mirror of https://github.com/getdnsapi/getdns.git
Bug fix in get_os_defaults, clean up code in winsock_event, add code to handle event handling differences in Winsock2
This commit is contained in:
parent
2d58ed465c
commit
22a8550caa
|
@ -803,10 +803,9 @@ set_os_defaults_windows(struct getdns_context *context)
|
||||||
hints.ai_addr = NULL;
|
hints.ai_addr = NULL;
|
||||||
hints.ai_next = NULL;
|
hints.ai_next = NULL;
|
||||||
|
|
||||||
//g
|
|
||||||
FIXED_INFO *info;
|
FIXED_INFO *info;
|
||||||
ULONG buflen = sizeof(*info);
|
ULONG buflen = sizeof(*info);
|
||||||
IP_ADDR_STRING *ptr;
|
IP_ADDR_STRING *ptr = 0;
|
||||||
|
|
||||||
info = (FIXED_INFO *)malloc(sizeof(FIXED_INFO));
|
info = (FIXED_INFO *)malloc(sizeof(FIXED_INFO));
|
||||||
if (info == NULL)
|
if (info == NULL)
|
||||||
|
@ -821,7 +820,7 @@ set_os_defaults_windows(struct getdns_context *context)
|
||||||
|
|
||||||
if (GetNetworkParams(info, &buflen) == NO_ERROR) {
|
if (GetNetworkParams(info, &buflen) == NO_ERROR) {
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
ptr = &(info->DnsServerList);
|
ptr = info->DnsServerList.Next;
|
||||||
*domain = 0;
|
*domain = 0;
|
||||||
while (ptr) {
|
while (ptr) {
|
||||||
for (size_t i = 0; i < GETDNS_UPSTREAM_TRANSPORTS; i++) {
|
for (size_t i = 0; i < GETDNS_UPSTREAM_TRANSPORTS; i++) {
|
||||||
|
@ -843,7 +842,6 @@ set_os_defaults_windows(struct getdns_context *context)
|
||||||
free(info);
|
free(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
(void)getdns_list_get_length(context->suffix, &length);
|
(void)getdns_list_get_length(context->suffix, &length);
|
||||||
if (length == 0 && *domain != 0) {
|
if (length == 0 && *domain != 0) {
|
||||||
bindata.data = (uint8_t *)domain;
|
bindata.data = (uint8_t *)domain;
|
||||||
|
@ -994,7 +992,7 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
result->fchg_resolvconf = NULL;
|
result->fchg_resolvconf = NULL;
|
||||||
result->fchg_hosts = NULL;
|
result->fchg_hosts = NULL;
|
||||||
|
|
||||||
//g resolv.conf does not exist on Windows, handle differently
|
// resolv.conf does not exist on Windows, handle differently
|
||||||
#ifndef USE_WINSOCK
|
#ifndef USE_WINSOCK
|
||||||
if (set_from_os && (r = set_os_defaults(result)))
|
if (set_from_os && (r = set_os_defaults(result)))
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -2358,18 +2356,24 @@ _getdns_context_prepare_for_resolution(struct getdns_context *context,
|
||||||
/* Create client context, use TLS v1.2 only for now */
|
/* Create client context, use TLS v1.2 only for now */
|
||||||
context->tls_ctx = SSL_CTX_new(TLSv1_2_client_method());
|
context->tls_ctx = SSL_CTX_new(TLSv1_2_client_method());
|
||||||
if (context->tls_ctx == NULL)
|
if (context->tls_ctx == NULL)
|
||||||
printf("ERROR! Bad TLS context!");
|
#ifndef USE_WINSOCK
|
||||||
//g return GETDNS_RETURN_BAD_CONTEXT;
|
return GETDNS_RETURN_BAD_CONTEXT;
|
||||||
|
#else
|
||||||
|
printf("Warning! Bad TLS context, check openssl version on Windows!\n");;
|
||||||
|
#endif
|
||||||
/* Be strict and only use the cipher suites recommended in RFC7525
|
/* Be strict and only use the cipher suites recommended in RFC7525
|
||||||
Unless we later fallback to opportunistic. */
|
Unless we later fallback to opportunistic. */
|
||||||
const char* const PREFERRED_CIPHERS = "EECDH+aRSA+AESGCM:EECDH+aECDSA+AESGCM:EDH+aRSA+AESGCM";
|
const char* const PREFERRED_CIPHERS = "EECDH+aRSA+AESGCM:EECDH+aECDSA+AESGCM:EDH+aRSA+AESGCM";
|
||||||
if (!SSL_CTX_set_cipher_list(context->tls_ctx, PREFERRED_CIPHERS))
|
if (!SSL_CTX_set_cipher_list(context->tls_ctx, PREFERRED_CIPHERS)) {
|
||||||
return GETDNS_RETURN_BAD_CONTEXT;
|
return GETDNS_RETURN_BAD_CONTEXT;
|
||||||
if (!SSL_CTX_set_default_verify_paths(context->tls_ctx))
|
}
|
||||||
|
if (!SSL_CTX_set_default_verify_paths(context->tls_ctx)) {
|
||||||
return GETDNS_RETURN_BAD_CONTEXT;
|
return GETDNS_RETURN_BAD_CONTEXT;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
if (tls_only_is_in_transports_list(context) == 1)
|
if (tls_only_is_in_transports_list(context) == 1) {
|
||||||
return GETDNS_RETURN_BAD_CONTEXT;
|
return GETDNS_RETURN_BAD_CONTEXT;
|
||||||
|
}
|
||||||
/* A null tls_ctx will make TLS fail and fallback to the other
|
/* A null tls_ctx will make TLS fail and fallback to the other
|
||||||
transports will kick-in.*/
|
transports will kick-in.*/
|
||||||
#endif
|
#endif
|
||||||
|
|
47
src/stub.c
47
src/stub.c
|
@ -50,6 +50,7 @@
|
||||||
#define EINPROGRESS 112
|
#define EINPROGRESS 112
|
||||||
#define EWOULDBLOCK 140
|
#define EWOULDBLOCK 140
|
||||||
typedef u_short sa_family_t;
|
typedef u_short sa_family_t;
|
||||||
|
#include "util/winsock_event.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define STUB_OUT_OF_OPTIONS -5 /* upstream options exceeded MAXIMUM_UPSTREAM_OPTION_SPACE */
|
#define STUB_OUT_OF_OPTIONS -5 /* upstream options exceeded MAXIMUM_UPSTREAM_OPTION_SPACE */
|
||||||
|
@ -623,7 +624,7 @@ stub_tls_timeout_cb(void *userarg)
|
||||||
/****************************/
|
/****************************/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
stub_tcp_read(int fd, getdns_tcp_state *tcp, struct mem_funcs *mf)
|
stub_tcp_read(int fd, getdns_tcp_state *tcp, struct mem_funcs *mf, getdns_eventloop_event* event)
|
||||||
{
|
{
|
||||||
ssize_t read;
|
ssize_t read;
|
||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
|
@ -640,10 +641,24 @@ stub_tcp_read(int fd, getdns_tcp_state *tcp, struct mem_funcs *mf)
|
||||||
}
|
}
|
||||||
read = recv(fd, tcp->read_pos, tcp->to_read, 0);
|
read = recv(fd, tcp->read_pos, tcp->to_read, 0);
|
||||||
if (read == -1) {
|
if (read == -1) {
|
||||||
|
#ifdef USE_WINSOCK
|
||||||
|
printf("read (in tcp ) %s\n",
|
||||||
|
wsa_strerror(WSAGetLastError()));
|
||||||
|
if (WSAGetLastError() == WSAECONNRESET)
|
||||||
|
return STUB_TCP_AGAIN;
|
||||||
|
if (WSAGetLastError() == WSAEINPROGRESS)
|
||||||
|
return STUB_TCP_AGAIN;
|
||||||
|
if (WSAGetLastError() == WSAEWOULDBLOCK) {
|
||||||
|
winsock_tcp_wouldblock(event, EV_READ);
|
||||||
|
return STUB_TCP_AGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||||
return STUB_TCP_AGAIN;
|
return STUB_TCP_AGAIN;
|
||||||
else
|
else
|
||||||
return STUB_TCP_ERROR;
|
return STUB_TCP_ERROR;
|
||||||
|
#endif
|
||||||
} else if (read == 0) {
|
} else if (read == 0) {
|
||||||
/* Remote end closed the socket */
|
/* Remote end closed the socket */
|
||||||
/* TODO: Try to reconnect */
|
/* TODO: Try to reconnect */
|
||||||
|
@ -747,19 +762,19 @@ stub_tcp_write(int fd, getdns_tcp_state *tcp, getdns_network_req *netreq)
|
||||||
upstream). We must let the handshake complete since non-blocking. */
|
upstream). We must let the handshake complete since non-blocking. */
|
||||||
errno == EINPROGRESS)) ||
|
errno == EINPROGRESS)) ||
|
||||||
written < pkt_len + 2) {
|
written < pkt_len + 2) {
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef USE_WINSOCK
|
#ifdef USE_WINSOCK
|
||||||
written = sendto(fd, netreq->query - 2, pkt_len + 2,
|
written = sendto(fd, netreq->query - 2, pkt_len + 2,
|
||||||
0, (struct sockaddr *)&(netreq->upstream->addr),
|
0, (struct sockaddr *)&(netreq->upstream->addr),
|
||||||
netreq->upstream->addr_len);
|
netreq->upstream->addr_len);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
written = write(fd, netreq->query - 2, pkt_len + 2);
|
written = write(fd, netreq->query - 2, pkt_len + 2);
|
||||||
#endif
|
#endif
|
||||||
if ((written == -1 && (errno == EAGAIN ||
|
if ((written == -1 && (errno == EAGAIN ||
|
||||||
errno == EWOULDBLOCK)) ||
|
errno == EWOULDBLOCK)) ||
|
||||||
written < pkt_len + 2) {
|
written < pkt_len + 2) {
|
||||||
#endif
|
#endif
|
||||||
/* We couldn't write the whole packet.
|
/* We couldn't write the whole packet.
|
||||||
* We have to return with STUB_TCP_AGAIN.
|
* We have to return with STUB_TCP_AGAIN.
|
||||||
|
@ -1359,7 +1374,7 @@ stub_tcp_read_cb(void *userarg)
|
||||||
int q;
|
int q;
|
||||||
|
|
||||||
switch ((q = stub_tcp_read(netreq->fd, &netreq->tcp,
|
switch ((q = stub_tcp_read(netreq->fd, &netreq->tcp,
|
||||||
&dnsreq->context->mf))) {
|
&dnsreq->context->mf, &netreq->event))) {
|
||||||
|
|
||||||
case STUB_TCP_AGAIN:
|
case STUB_TCP_AGAIN:
|
||||||
return;
|
return;
|
||||||
|
@ -1437,7 +1452,7 @@ upstream_read_cb(void *userarg)
|
||||||
&upstream->upstreams->mf);
|
&upstream->upstreams->mf);
|
||||||
else
|
else
|
||||||
q = stub_tcp_read(upstream->fd, &upstream->tcp,
|
q = stub_tcp_read(upstream->fd, &upstream->tcp,
|
||||||
&upstream->upstreams->mf);
|
&upstream->upstreams->mf, &netreq->event);
|
||||||
|
|
||||||
switch (q) {
|
switch (q) {
|
||||||
case STUB_TCP_AGAIN:
|
case STUB_TCP_AGAIN:
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -40,6 +40,7 @@
|
||||||
* This file contains interface functions with the WinSock2 API on Windows.
|
* This file contains interface functions with the WinSock2 API on Windows.
|
||||||
* It uses the winsock WSAWaitForMultipleEvents interface on a number of
|
* It uses the winsock WSAWaitForMultipleEvents interface on a number of
|
||||||
* sockets.
|
* sockets.
|
||||||
|
* Code is originally from the Unbound source for Windows.
|
||||||
*
|
*
|
||||||
* Note that windows can only wait for max 64 events at one time.
|
* Note that windows can only wait for max 64 events at one time.
|
||||||
*
|
*
|
||||||
|
@ -133,92 +134,92 @@
|
||||||
*/
|
*/
|
||||||
struct _getdns_event_base
|
struct _getdns_event_base
|
||||||
{
|
{
|
||||||
/** sorted by timeout (absolute), ptr */
|
/** sorted by timeout (absolute), ptr */
|
||||||
_getdns_rbtree_t* times;
|
_getdns_rbtree_t* times;
|
||||||
/** array (first part in use) of handles to work on */
|
/** array (first part in use) of handles to work on */
|
||||||
struct _getdns_event** items;
|
struct _getdns_event** items;
|
||||||
/** number of items in use in array */
|
/** number of items in use in array */
|
||||||
int max;
|
int max;
|
||||||
/** capacity of array, size of array in items */
|
/** capacity of array, size of array in items */
|
||||||
int cap;
|
int cap;
|
||||||
/** array of 0 - maxsig of ptr to event for it */
|
/** array of 0 - maxsig of ptr to event for it */
|
||||||
struct _getdns_event** signals;
|
struct _getdns_event** signals;
|
||||||
/** if we need to exit */
|
/** if we need to exit */
|
||||||
int need_to_exit;
|
int need_to_exit;
|
||||||
/** where to store time in seconds */
|
/** where to store time in seconds */
|
||||||
time_t* time_secs;
|
time_t* time_secs;
|
||||||
/** where to store time in microseconds */
|
/** where to store time in microseconds */
|
||||||
struct timeval* time_tv;
|
struct timeval* time_tv;
|
||||||
/**
|
/**
|
||||||
* TCP streams have sticky events to them, these are not
|
* TCP streams have sticky events to them, these are not
|
||||||
* reported by the windows event system anymore, we have to
|
* reported by the windows event system anymore, we have to
|
||||||
* keep reporting those events as present until wouldblock() is
|
* keep reporting those events as present until wouldblock() is
|
||||||
* signalled by the handler back to use.
|
* signalled by the handler back to use.
|
||||||
*/
|
*/
|
||||||
int tcp_stickies;
|
int tcp_stickies;
|
||||||
/**
|
/**
|
||||||
* should next cycle process reinvigorated stickies,
|
* should next cycle process reinvigorated stickies,
|
||||||
* these are stickies that have been stored, but due to a new
|
* these are stickies that have been stored, but due to a new
|
||||||
* event_add a sudden interest in the event has incepted.
|
* event_add a sudden interest in the event has incepted.
|
||||||
*/
|
*/
|
||||||
int tcp_reinvigorated;
|
int tcp_reinvigorated;
|
||||||
/** The list of events that is currently being processed. */
|
/** The list of events that is currently being processed. */
|
||||||
WSAEVENT waitfor[WSK_MAX_ITEMS];
|
WSAEVENT waitfor[WSK_MAX_ITEMS];
|
||||||
|
|
||||||
/* fdset for read write, for fds ready, and added */
|
/* fdset for read write, for fds ready, and added */
|
||||||
fd_set
|
fd_set
|
||||||
/** fds for reading */
|
/** fds for reading */
|
||||||
reads,
|
reads,
|
||||||
/** fds for writing */
|
/** fds for writing */
|
||||||
writes,
|
writes,
|
||||||
/** fds determined ready for use */
|
/** fds determined ready for use */
|
||||||
ready,
|
ready,
|
||||||
/** ready plus newly added events. */
|
/** ready plus newly added events. */
|
||||||
content;
|
content;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event structure. Has some of the event elements.
|
* Event structure. Has some of the event elements.
|
||||||
*/
|
*/
|
||||||
struct _getdns_event {
|
struct _getdns_event {
|
||||||
/** node in timeout rbtree */
|
/** node in timeout rbtree */
|
||||||
_getdns_rbnode_t node;
|
_getdns_rbnode_t node;
|
||||||
/** is event already added */
|
/** is event already added */
|
||||||
int added;
|
int added;
|
||||||
|
|
||||||
/** event base it belongs to */
|
/** event base it belongs to */
|
||||||
struct _getdns_event_base *ev_base;
|
struct _getdns_event_base *ev_base;
|
||||||
/** fd to poll or -1 for timeouts. signal number for sigs. */
|
/** fd to poll or -1 for timeouts. signal number for sigs. */
|
||||||
int ev_fd;
|
int ev_fd;
|
||||||
/** what events this event is interested in, see EV_.. above. */
|
/** what events this event is interested in, see EV_.. above. */
|
||||||
short ev_events;
|
short ev_events;
|
||||||
/** timeout value */
|
/** timeout value */
|
||||||
struct timeval ev_timeout;
|
struct timeval ev_timeout;
|
||||||
|
|
||||||
/** callback to call: fd, eventbits, userarg */
|
/** callback to call: fd, eventbits, userarg */
|
||||||
void (*ev_callback)(int, short, void *);
|
void (*ev_callback)(int, short, void *);
|
||||||
/** callback user arg */
|
/** callback user arg */
|
||||||
void *ev_arg;
|
void *ev_arg;
|
||||||
|
|
||||||
/* ----- nonpublic part, for winsock_event only ----- */
|
/* ----- nonpublic part, for winsock_event only ----- */
|
||||||
/** index of this event in the items array (if added) */
|
/** index of this event in the items array (if added) */
|
||||||
int idx;
|
int idx;
|
||||||
/** the event handle to wait for new events to become ready */
|
/** the event handle to wait for new events to become ready */
|
||||||
WSAEVENT hEvent;
|
WSAEVENT hEvent;
|
||||||
/** true if this filedes is a TCP socket and needs special attention */
|
/** true if this filedes is a TCP socket and needs special attention */
|
||||||
int is_tcp;
|
int is_tcp;
|
||||||
/** remembered EV_ values */
|
/** remembered EV_ values */
|
||||||
short old_events;
|
short old_events;
|
||||||
/** should remembered EV_ values be used for TCP streams.
|
/** should remembered EV_ values be used for TCP streams.
|
||||||
* Reset after WOULDBLOCK is signaled using the function. */
|
* Reset after WOULDBLOCK is signaled using the function. */
|
||||||
int stick_events;
|
int stick_events;
|
||||||
|
|
||||||
/** true if this event is a signaling WSAEvent by the user.
|
/** true if this event is a signaling WSAEvent by the user.
|
||||||
* User created and user closed WSAEvent. Only signaled/unsigneled,
|
* User created and user closed WSAEvent. Only signaled/unsigneled,
|
||||||
* no read/write/distinctions needed. */
|
* no read/write/distinctions needed. */
|
||||||
int is_signal;
|
int is_signal;
|
||||||
/** used during callbacks to see which events were just checked */
|
/** used during callbacks to see which events were just checked */
|
||||||
int just_checked;
|
int just_checked;
|
||||||
};
|
};
|
||||||
|
|
||||||
char* wsa_strerror(DWORD err);
|
char* wsa_strerror(DWORD err);
|
||||||
|
@ -267,7 +268,7 @@ int getdns_mini_ev_cmp(const void* a, const void* b);
|
||||||
* retesting the event.
|
* retesting the event.
|
||||||
* Pass if EV_READ or EV_WRITE gave wouldblock.
|
* Pass if EV_READ or EV_WRITE gave wouldblock.
|
||||||
*/
|
*/
|
||||||
static void winsock_tcp_wouldblock(struct _getdns_event* ev, int eventbit);
|
void winsock_tcp_wouldblock(struct _getdns_event* ev, int eventbit);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Routine for windows only. where you pass a signal WSAEvent that
|
* Routine for windows only. where you pass a signal WSAEvent that
|
||||||
|
@ -275,14 +276,14 @@ static void winsock_tcp_wouldblock(struct _getdns_event* ev, int eventbit);
|
||||||
* The callback has to WSAResetEvent to disable the signal.
|
* The callback has to WSAResetEvent to disable the signal.
|
||||||
* @param base: the event base.
|
* @param base: the event base.
|
||||||
* @param ev: the event structure for data storage
|
* @param ev: the event structure for data storage
|
||||||
* can be passed uninitialised.
|
* can be passed uninitialised.
|
||||||
* @param wsaevent: the WSAEvent that gets signaled.
|
* @param wsaevent: the WSAEvent that gets signaled.
|
||||||
* @param cb: callback routine.
|
* @param cb: callback routine.
|
||||||
* @param arg: user argument to callback routine.
|
* @param arg: user argument to callback routine.
|
||||||
* @return false on error.
|
* @return false on error.
|
||||||
*/
|
*/
|
||||||
static int winsock_register_wsaevent(struct _getdns_event_base* base, struct _getdns_event* ev,
|
static int winsock_register_wsaevent(struct _getdns_event_base* base, struct _getdns_event* ev,
|
||||||
WSAEVENT wsaevent, void (*cb)(int, short, void*), void* arg);
|
WSAEVENT wsaevent, void (*cb)(int, short, void*), void* arg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregister a wsaevent. User has to close the WSAEVENT itself.
|
* Unregister a wsaevent. User has to close the WSAEVENT itself.
|
||||||
|
|
Loading…
Reference in New Issue