mirror of https://github.com/getdnsapi/getdns.git
Intermediate commit, after definition of the MDNS context
This commit is contained in:
parent
4c71d6239f
commit
93d6f2b18f
|
@ -98,6 +98,16 @@ static pthread_mutex_t ssl_init_lock = PTHREAD_MUTEX_INITIALIZER;
|
|||
#endif
|
||||
static bool ssl_init=false;
|
||||
|
||||
#ifdef HAVE_MDNS_SUPPORT
|
||||
/*
|
||||
* Forward declaration of MDNS context init and destroy function.
|
||||
* We do this here instead of including mdns.h, in order to
|
||||
* minimize dependencies.
|
||||
*/
|
||||
void _getdns_mdns_context_init(struct getdns_context *context);
|
||||
void _getdns_mdns_context_destroy(struct getdns_context *context);
|
||||
#endif
|
||||
|
||||
void *plain_mem_funcs_user_arg = MF_PLAIN;
|
||||
|
||||
typedef struct host_name_addrs {
|
||||
|
@ -1471,8 +1481,14 @@ getdns_context_create_with_extended_memory_functions(
|
|||
goto error;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_MDNS_SUPPORT
|
||||
_getdns_mdns_context_init(result);
|
||||
#endif
|
||||
|
||||
create_local_hosts(result);
|
||||
|
||||
|
||||
*context = result;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
error:
|
||||
|
@ -1552,6 +1568,13 @@ getdns_context_destroy(struct getdns_context *context)
|
|||
ub_ctx_delete(context->unbound_ctx);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MDNS_SUPPORT
|
||||
/*
|
||||
* Release all ressource allocated for MDNS.
|
||||
*/
|
||||
_getdns_mdns_context_destroy(context);
|
||||
#endif
|
||||
|
||||
if (context->namespaces)
|
||||
GETDNS_FREE(context->my_mf, context->namespaces);
|
||||
|
||||
|
|
|
@ -344,12 +344,14 @@ struct getdns_context {
|
|||
* or in full mode. If working in extended mode, two multicast sockets are
|
||||
* left open, for IPv4 and IPv6. Data can be received on either socket.
|
||||
* The context also keeps a list of open queries, characterized by a
|
||||
* name and an RR type.
|
||||
* name and an RR type, and a list of received answers, characterized
|
||||
* by name, RR type and data value.
|
||||
*/
|
||||
int mdns_extended_support;
|
||||
int fd_mdns_v4;
|
||||
int fd_mdns_v6;
|
||||
int mdns_extended_support; /* 0 = no support, 1 = supported, 2 = initialization needed */
|
||||
int mdns_fdv4;
|
||||
int mdns_fdv6;
|
||||
_getdns_rbtree_t mdns_continuous_queries_by_name_rrtype;
|
||||
_getdns_rbtree_t mdns_known_records_by_value;
|
||||
|
||||
#endif /* HAVE_MDNS_SUPPORT */
|
||||
}; /* getdns_context */
|
||||
|
|
|
@ -128,6 +128,7 @@
|
|||
|
||||
#define MDNS_DEBUG_ENTRY "-> MDNS ENTRY: "
|
||||
#define MDNS_DEBUG_READ "-- MDNS READ: "
|
||||
#define MDNS_DEBUG_MREAD "-- MDNS MREAD: "
|
||||
#define MDNS_DEBUG_WRITE "-- MDNS WRITE: "
|
||||
#define MDNS_DEBUG_CLEANUP "-- MDNS CLEANUP:"
|
||||
|
||||
|
|
260
src/mdns.c
260
src/mdns.c
|
@ -48,12 +48,10 @@ uint64_t _getdns_get_time_as_uintt64();
|
|||
#define MDNS_MCAST_IPV4_LONG 0xE00000FB /* 224.0.0.251 */
|
||||
#define MDNS_MCAST_PORT 5353
|
||||
|
||||
/*
|
||||
* TODO: When we start supporting IPv6 with MDNS, need to define this:
|
||||
* static uint8_t mdns_mcast_ipv6[] = {
|
||||
* 0xFF, 0x02, 0, 0, 0, 0, 0, 0,
|
||||
* 0, 0, 0, 0, 0, 0, 0, 0xFB };
|
||||
*/
|
||||
static uint8_t mdns_mcast_ipv6[] = {
|
||||
0xFF, 0x02, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0xFB
|
||||
};
|
||||
|
||||
static uint8_t mdns_suffix_dot_local[] = { 5, 'l', 'o', 'c', 'a', 'l', 0 };
|
||||
static uint8_t mdns_suffix_254_169_in_addr_arpa[] = {
|
||||
|
@ -63,19 +61,19 @@ static uint8_t mdns_suffix_254_169_in_addr_arpa[] = {
|
|||
4, 'a', 'r', 'p', 'a', 0 };
|
||||
static uint8_t mdns_suffix_8_e_f_ip6_arpa[] = {
|
||||
1, '8', 1, 'e', 1, 'f',
|
||||
7, 'i', 'p', 'v', '6',
|
||||
3, 'i', 'p', '6',
|
||||
4, 'a', 'r', 'p', 'a', 0 };
|
||||
static uint8_t mdns_suffix_9_e_f_ip6_arpa[] = {
|
||||
1, '9', 1, 'e', 1, 'f',
|
||||
7, 'i', 'p', 'v', '6',
|
||||
3, 'i', 'p', '6',
|
||||
4, 'a', 'r', 'p', 'a', 0 };
|
||||
static uint8_t mdns_suffix_a_e_f_ip6_arpa[] = {
|
||||
1, 'a', 1, 'e', 1, 'f',
|
||||
7, 'i', 'p', 'v', '6',
|
||||
3, 'i', 'p', '6',
|
||||
4, 'a', 'r', 'p', 'a', 0 };
|
||||
static uint8_t mdns_suffix_b_e_f_ip6_arpa[] = {
|
||||
1, 'b', 1, 'e', 1, 'f',
|
||||
7, 'i', 'p', 'v', '6',
|
||||
3, 'i', 'p', '6',
|
||||
4, 'a', 'r', 'p', 'a', 0 };
|
||||
|
||||
|
||||
|
@ -105,13 +103,25 @@ static int mdns_cmp_known_records(const void * nkr1, const void * nkr2)
|
|||
getdns_mdns_known_record * kr1 = (getdns_mdns_known_record *)nkr1;
|
||||
getdns_mdns_known_record * kr2 = (getdns_mdns_known_record *)nkr2;
|
||||
|
||||
if (kr1->record_length != kr2->record_length)
|
||||
if (kr1->request_class != kr2->request_class)
|
||||
{
|
||||
ret = (kr1->record_length < kr2->record_length) ? -1 : 1;
|
||||
ret = (kr1->request_class < kr2->request_class) ? -1 : 1;
|
||||
}
|
||||
else
|
||||
else if (kr1->request_type != kr2->request_type)
|
||||
{
|
||||
ret = memcmp((const void*)kr1->record_data, (const void*)kr2->record_data, kr1->record_length);
|
||||
ret = (kr1->request_type < kr2->request_type) ? -1 : 1;
|
||||
}
|
||||
else if (kr1->name_len != kr2->name_len)
|
||||
{
|
||||
ret = (kr1->name_len < kr2->name_len) ? -1 : 1;
|
||||
}
|
||||
else if (kr1->record_len != kr2->record_len)
|
||||
{
|
||||
ret = (kr1->record_len < kr2->record_len) ? -1 : 1;
|
||||
}
|
||||
else if ((ret = memcmp((void*)kr1->name, (void*)kr2->name, kr2->name_len)) == 0)
|
||||
{
|
||||
ret = memcmp((const void*)kr1->record_data, (const void*)kr2->record_data, kr1->record_len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -146,14 +156,181 @@ static int mdns_cmp_continuous_queries_by_name_rrtype(const void * nqnr1, const
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create the two required multicast sockets
|
||||
*/
|
||||
static int mdns_open_ipv4_multicast()
|
||||
{
|
||||
getdns_return_t ret = 0;
|
||||
SOCKET fd4 = -1;
|
||||
SOCKADDR_IN ipv4_dest;
|
||||
SOCKADDR_IN ipv4_port;
|
||||
uint8_t so_reuse_bool = 1;
|
||||
uint8_t ttl = 255;
|
||||
IP_MREQ mreq4;
|
||||
|
||||
memset(&ipv4_dest, 0, sizeof(ipv4_dest));
|
||||
memset(&ipv4_port, 0, sizeof(ipv4_dest));
|
||||
ipv4_dest.sin_family = AF_INET;
|
||||
ipv4_dest.sin_port = htons(MDNS_MCAST_PORT);
|
||||
ipv4_dest.sin_addr.S_un.S_addr = htonl(MDNS_MCAST_IPV4_LONG);
|
||||
ipv4_port.sin_family = AF_INET;
|
||||
ipv4_port.sin_port = htons(MDNS_MCAST_PORT);
|
||||
|
||||
|
||||
fd4 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
||||
if (fd4 != -1)
|
||||
{
|
||||
/*
|
||||
* No need to test the output of the so_reuse call,
|
||||
* since the only result that matters is that of bind.
|
||||
*/
|
||||
(void)setsockopt(fd4, SOL_SOCKET, SO_REUSEADDR
|
||||
, (const char*)&so_reuse_bool, (int) sizeof(BOOL));
|
||||
|
||||
if (bind(fd4, (SOCKADDR*)&ipv4_port, sizeof(ipv4_port)) != 0)
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mreq4.imr_multiaddr = ipv4_dest.sin_addr;
|
||||
mreq4.imr_interface = ipv4_port.sin_addr;
|
||||
|
||||
if (setsockopt(fd4, IPPROTO_IP, IP_ADD_MEMBERSHIP
|
||||
, (const char*)&mreq4, (int) sizeof(mreq4)) != 0)
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
else if (setsockopt(fd4, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) != 0)
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != 0 && fd4 != -1)
|
||||
{
|
||||
#ifdef USE_WINSOCK
|
||||
closesocket(fd4);
|
||||
#else
|
||||
close(fd4);
|
||||
#endif
|
||||
fd4 = -1;
|
||||
}
|
||||
|
||||
return fd4;
|
||||
}
|
||||
|
||||
static int mdns_open_ipv6_multicast()
|
||||
{
|
||||
getdns_return_t ret = 0;
|
||||
SOCKET fd6 = -1;
|
||||
SOCKADDR_IN6 ipv6_dest;
|
||||
SOCKADDR_IN6 ipv6_port;
|
||||
uint8_t so_reuse_bool = 1;
|
||||
uint8_t ttl = 255;
|
||||
IPV6_MREQ mreq6;
|
||||
|
||||
memset(&ipv6_dest, 0, sizeof(ipv6_dest));
|
||||
memset(&ipv6_port, 0, sizeof(ipv6_dest));
|
||||
ipv6_dest.sin6_family = AF_INET6;
|
||||
ipv6_dest.sin6_port = htons(MDNS_MCAST_PORT);
|
||||
ipv6_port.sin6_family = AF_INET6;
|
||||
ipv6_port.sin6_port = htons(MDNS_MCAST_PORT);
|
||||
memcpy(&ipv6_dest.sin6_addr
|
||||
, mdns_mcast_ipv6, sizeof(mdns_mcast_ipv6));
|
||||
|
||||
|
||||
fd6 = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
||||
if (fd6 != -1)
|
||||
{
|
||||
/*
|
||||
* No need to test the output of the so_reuse call,
|
||||
* since the only result that matters is that of bind.
|
||||
*/
|
||||
(void)setsockopt(fd6, SOL_SOCKET, SO_REUSEADDR
|
||||
, (const char*)&so_reuse_bool, (int) sizeof(BOOL));
|
||||
|
||||
if (bind(fd6, (SOCKADDR*)&ipv6_port, sizeof(ipv6_port)) != 0)
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&mreq6.ipv6mr_multiaddr
|
||||
, &ipv6_dest.sin6_addr, sizeof(mreq6.ipv6mr_multiaddr));
|
||||
memcpy(&mreq6.ipv6mr_interface
|
||||
, &ipv6_port.sin6_addr, sizeof(mreq6.ipv6mr_interface));
|
||||
|
||||
if (setsockopt(fd6, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP
|
||||
, (const char*)&mreq6, (int) sizeof(mreq6)) != 0)
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
else if (setsockopt(fd6, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl)) != 0)
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != 0 && fd6 != -1)
|
||||
{
|
||||
#ifdef USE_WINSOCK
|
||||
closesocket(fd6);
|
||||
#else
|
||||
close(fd6);
|
||||
#endif
|
||||
fd6 = -1;
|
||||
}
|
||||
|
||||
return fd6;
|
||||
}
|
||||
|
||||
/*
|
||||
* Delayed opening of the MDNS sockets, and launch of the MDNS listeners
|
||||
*/
|
||||
static getdns_return_t mdns_delayed_network_init(struct getdns_context *context)
|
||||
{
|
||||
getdns_return_t ret = 0;
|
||||
|
||||
if (context->mdns_extended_support == 2)
|
||||
{
|
||||
context->mdns_fdv4 = mdns_open_ipv4_multicast();
|
||||
context->mdns_fdv6 = mdns_open_ipv6_multicast();
|
||||
|
||||
if (context->mdns_fdv4 == -1 || context->mdns_fdv6 == -1)
|
||||
{
|
||||
if (context->mdns_fdv4 != -1)
|
||||
#ifdef USE_WINSOCK
|
||||
closesocket(context->mdns_fdv4);
|
||||
#else
|
||||
close(context->mdns_fdv4);
|
||||
#endif
|
||||
ret = GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO: launch the receive loops */
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a continuous query from netreq
|
||||
*/
|
||||
static int mdns_initialize_continuous_request(getdns_network_req *netreq)
|
||||
static getdns_return_t mdns_initialize_continuous_request(getdns_network_req *netreq)
|
||||
{
|
||||
int ret = 0;
|
||||
getdns_mdns_continuous_query temp_query, *continuous_query, *inserted_query;
|
||||
getdns_dns_req *dnsreq = netreq->owner;
|
||||
struct getdns_context *context = dnsreq->context;
|
||||
/*
|
||||
* Fill the target request, but only initialize name and request_type
|
||||
*/
|
||||
|
@ -168,27 +345,30 @@ static int mdns_initialize_continuous_request(getdns_network_req *netreq)
|
|||
* TODO: should lock the context object when doing that.
|
||||
*/
|
||||
continuous_query = (getdns_mdns_continuous_query *)
|
||||
_getdns_rbtree_search(&dnsreq->context->mdns_continuous_queries_by_name_rrtype, &temp_query);
|
||||
_getdns_rbtree_search(&context->mdns_continuous_queries_by_name_rrtype, &temp_query);
|
||||
if (continuous_query == NULL)
|
||||
{
|
||||
continuous_query = (getdns_mdns_continuous_query *)
|
||||
GETDNS_MALLOC(dnsreq->context->mf, getdns_mdns_continuous_query);
|
||||
GETDNS_MALLOC(context->mf, getdns_mdns_continuous_query);
|
||||
if (continuous_query != NULL)
|
||||
{
|
||||
continuous_query->node.parent = NULL;
|
||||
continuous_query->node.left = NULL;
|
||||
continuous_query->node.right = NULL;
|
||||
continuous_query->node.key = (void*)continuous_query;
|
||||
continuous_query->request_class = temp_query.request_class;
|
||||
continuous_query->request_type = temp_query.request_type;
|
||||
continuous_query->name_len = temp_query.name_len;
|
||||
memcpy(continuous_query->name, temp_query.name, temp_query.name_len);
|
||||
_getdns_rbtree_init(&continuous_query->known_records_by_value, mdns_cmp_known_records);
|
||||
/* Tracking of network requests on this socket */
|
||||
_getdns_rbtree_init(&continuous_query->netreq_by_query_id, mdns_cmp_netreq_by_query_id);
|
||||
continuous_query->netreq_first = NULL;
|
||||
/* Add the new continuous query to the context */
|
||||
inserted_query = _getdns_rbtree_insert(&dnsreq->context->mdns_continuous_queries_by_name_rrtype,
|
||||
continuous_query);
|
||||
inserted_query = (getdns_mdns_continuous_query *)
|
||||
_getdns_rbtree_insert(&context->mdns_continuous_queries_by_name_rrtype,
|
||||
&continuous_query->node);
|
||||
if (inserted_query == NULL)
|
||||
{
|
||||
/* Weird. This can only happen in a race condition */
|
||||
GETDNS_FREE(dnsreq->context->mf, continuous_query);
|
||||
GETDNS_FREE(context->mf, &continuous_query);
|
||||
ret = GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -197,12 +377,42 @@ static int mdns_initialize_continuous_request(getdns_network_req *netreq)
|
|||
ret = GETDNS_RETURN_MEMORY_ERROR;
|
||||
}
|
||||
}
|
||||
/* To do: insert netreq into query list */
|
||||
/* insert netreq into query list */
|
||||
netreq->mdns_netreq_next = continuous_query->netreq_first;
|
||||
continuous_query->netreq_first = netreq;
|
||||
|
||||
/* to do: queue message request to socket */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the MDNS part of the context structure.
|
||||
*/
|
||||
void _getdns_mdns_context_init(struct getdns_context *context)
|
||||
{
|
||||
|
||||
context->mdns_extended_support = 2; /* 0 = no support, 1 = supported, 2 = initialization needed */
|
||||
context->mdns_fdv4 = -1; /* invalid socket, i.e. not initialized */
|
||||
context->mdns_fdv6 = -1; /* invalid socket, i.e. not initialized */
|
||||
_getdns_rbtree_init(&context->mdns_continuous_queries_by_name_rrtype
|
||||
, mdns_cmp_continuous_queries_by_name_rrtype);
|
||||
_getdns_rbtree_init(&context->mdns_known_records_by_value
|
||||
, mdns_cmp_known_records);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete all the data allocated for MDNS in a context
|
||||
*/
|
||||
void _getdns_mdns_context_destroy(struct getdns_context *context)
|
||||
{
|
||||
/* Close the sockets */
|
||||
|
||||
/* Clear all the continuous queries */
|
||||
|
||||
/* Clear all the cached records */
|
||||
}
|
||||
|
||||
/* TODO: actualy delete what is required.. */
|
||||
static void
|
||||
mdns_cleanup(getdns_network_req *netreq)
|
||||
|
@ -212,8 +422,6 @@ mdns_cleanup(getdns_network_req *netreq)
|
|||
getdns_dns_req *dnsreq = netreq->owner;
|
||||
|
||||
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
|
||||
|
||||
GETDNS_NULL_FREE(dnsreq->context->mf, netreq->tcp.read_buf);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
20
src/mdns.h
20
src/mdns.h
|
@ -37,26 +37,36 @@ _getdns_mdns_namespace_check(getdns_dns_req *dnsreq);
|
|||
|
||||
typedef struct getdns_mdns_known_record
|
||||
{
|
||||
uint32_t ttl; /* todo: should this be an expiration date? */
|
||||
/* For storage in context->mdns_known_records_by_value */
|
||||
_getdns_rbnode_t node;
|
||||
uint64_t insertion_microsec;
|
||||
uint16_t request_type;
|
||||
uint16_t request_class;
|
||||
uint32_t ttl;
|
||||
int name_len;
|
||||
int record_len;
|
||||
uint8_t* name;
|
||||
uint8_t * record_data;
|
||||
int record_length;
|
||||
} getdns_mdns_known_record;
|
||||
|
||||
typedef struct getdns_mdns_continuous_query
|
||||
{
|
||||
/* For storage in context->mdns_continuous_queries_by_name_rrtype */
|
||||
_getdns_rbnode_t node;
|
||||
uint8_t name[256]; /* binary representation of name being queried */
|
||||
int name_len;
|
||||
uint16_t request_class;
|
||||
uint16_t request_type;
|
||||
/* list of known records */
|
||||
_getdns_rbtree_t known_records_by_value;
|
||||
/* list of user queries */
|
||||
_getdns_rbtree_t netreq_by_query_id;
|
||||
getdns_network_req *netreq_first;
|
||||
/* todo: do we need an expiration date, or a timer? */
|
||||
/* todo: do we need an update mark for showing last results? */
|
||||
} getdns_mdns_continuous_query;
|
||||
|
||||
|
||||
void _getdns_mdns_context_init(struct getdns_context *context);
|
||||
void _getdns_mdns_context_destroy(struct getdns_context *context);
|
||||
|
||||
#endif /* HAVE_MDNS_SUPPORT */
|
||||
|
||||
#endif /* MDNS_H */
|
||||
|
|
22
src/server.c
22
src/server.c
|
@ -135,7 +135,11 @@ static void tcp_connection_destroy(tcp_connection *conn)
|
|||
loop->vmt->clear(loop, &conn->event);
|
||||
|
||||
if (conn->fd >= 0)
|
||||
#ifdef USE_WINSOCK
|
||||
(void) closesocket(conn->fd);
|
||||
#else
|
||||
(void) close(conn->fd);
|
||||
#endif
|
||||
GETDNS_FREE(*mf, conn->read_buf);
|
||||
|
||||
for (cur = conn->to_write; cur; cur = next) {
|
||||
|
@ -185,8 +189,8 @@ static void tcp_write_cb(void *userarg)
|
|||
}
|
||||
to_write = conn->to_write;
|
||||
if (conn->fd == -1 ||
|
||||
(written = write(conn->fd, &to_write->write_buf[to_write->written],
|
||||
to_write->write_buf_len - to_write->written)) == -1) {
|
||||
(written = send(conn->fd, &to_write->write_buf[to_write->written],
|
||||
to_write->write_buf_len - to_write->written, 0)) == -1) {
|
||||
|
||||
/* IO error, close connection */
|
||||
conn->event.read_cb = conn->event.write_cb =
|
||||
|
@ -280,7 +284,11 @@ getdns_reply(
|
|||
(struct sockaddr *)&conn->remote_in, conn->addrlen) == -1) {
|
||||
/* IO error, cleanup this listener */
|
||||
loop->vmt->clear(loop, &conn->l->event);
|
||||
#ifdef USE_WINSOCK
|
||||
closesocket(conn->l->fd);
|
||||
#else
|
||||
close(conn->l->fd);
|
||||
#endif
|
||||
conn->l->fd = -1;
|
||||
}
|
||||
/* Unlink this connection */
|
||||
|
@ -359,7 +367,7 @@ static void tcp_read_cb(void *userarg)
|
|||
(void) loop->vmt->schedule(loop, conn->fd,
|
||||
DOWNSTREAM_IDLE_TIMEOUT, &conn->event);
|
||||
|
||||
if ((bytes_read = read(conn->fd, conn->read_pos, conn->to_read)) < 0) {
|
||||
if ((bytes_read = recv(conn->fd, conn->read_pos, conn->to_read, 0)) < 0) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
return; /* Come back to do the read later */
|
||||
|
||||
|
@ -473,7 +481,11 @@ static void tcp_accept_cb(void *userarg)
|
|||
&conn->super.remote_in, &conn->super.addrlen)) == -1) {
|
||||
/* IO error, cleanup this listener */
|
||||
loop->vmt->clear(loop, &l->event);
|
||||
#ifdef USE_WINSOCK
|
||||
closesocket(l->fd);
|
||||
#else
|
||||
close(l->fd);
|
||||
#endif
|
||||
l->fd = -1;
|
||||
GETDNS_FREE(*mf, conn);
|
||||
return;
|
||||
|
@ -543,7 +555,11 @@ static void udp_read_cb(void *userarg)
|
|||
(struct sockaddr *)&conn->remote_in, &conn->addrlen)) == -1) {
|
||||
/* IO error, cleanup this listener. */
|
||||
loop->vmt->clear(loop, &l->event);
|
||||
#ifdef USE_WINSOCK
|
||||
closesocket(l->fd);
|
||||
#else
|
||||
close(l->fd);
|
||||
#endif
|
||||
l->fd = -1;
|
||||
|
||||
#if 0 && defined(SERVER_DEBUG) && SERVER_DEBUG
|
||||
|
|
|
@ -183,7 +183,6 @@ typedef struct getdns_tcp_state {
|
|||
|
||||
} getdns_tcp_state;
|
||||
|
||||
|
||||
/**
|
||||
* Request data
|
||||
**/
|
||||
|
@ -191,6 +190,15 @@ typedef struct getdns_network_req
|
|||
{
|
||||
/* For storage in upstream->netreq_by_query_id */
|
||||
_getdns_rbnode_t node;
|
||||
#ifdef HAVE_MDNS_SUPPORT
|
||||
/*
|
||||
* for storage in continuous query context. We never
|
||||
* expect much more than one query per msdn context,
|
||||
* so no need for RB Tree.
|
||||
*/
|
||||
struct getdns_network_req * mdns_netreq_next;
|
||||
struct getdns_mdns_continuous_query * mdns_continuous_query;
|
||||
#endif /* HAVE_MDNS_SUPPORT */
|
||||
/* the async_id from unbound */
|
||||
int unbound_id;
|
||||
/* state var */
|
||||
|
|
Loading…
Reference in New Issue