Intermediate commit, after definition of the MDNS context

This commit is contained in:
Christian Huitema 2017-02-06 18:23:35 -10:00
parent 4c71d6239f
commit 93d6f2b18f
7 changed files with 307 additions and 39 deletions

View File

@ -98,6 +98,16 @@ static pthread_mutex_t ssl_init_lock = PTHREAD_MUTEX_INITIALIZER;
#endif #endif
static bool ssl_init=false; 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; void *plain_mem_funcs_user_arg = MF_PLAIN;
typedef struct host_name_addrs { typedef struct host_name_addrs {
@ -1471,8 +1481,14 @@ getdns_context_create_with_extended_memory_functions(
goto error; goto error;
#endif #endif
#ifdef HAVE_MDNS_SUPPORT
_getdns_mdns_context_init(result);
#endif
create_local_hosts(result); create_local_hosts(result);
*context = result; *context = result;
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
error: error:
@ -1552,6 +1568,13 @@ getdns_context_destroy(struct getdns_context *context)
ub_ctx_delete(context->unbound_ctx); ub_ctx_delete(context->unbound_ctx);
#endif #endif
#ifdef HAVE_MDNS_SUPPORT
/*
* Release all ressource allocated for MDNS.
*/
_getdns_mdns_context_destroy(context);
#endif
if (context->namespaces) if (context->namespaces)
GETDNS_FREE(context->my_mf, context->namespaces); GETDNS_FREE(context->my_mf, context->namespaces);

View File

@ -344,12 +344,14 @@ struct getdns_context {
* or in full mode. If working in extended mode, two multicast sockets are * 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. * 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 * 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 mdns_extended_support; /* 0 = no support, 1 = supported, 2 = initialization needed */
int fd_mdns_v4; int mdns_fdv4;
int fd_mdns_v6; int mdns_fdv6;
_getdns_rbtree_t mdns_continuous_queries_by_name_rrtype; _getdns_rbtree_t mdns_continuous_queries_by_name_rrtype;
_getdns_rbtree_t mdns_known_records_by_value;
#endif /* HAVE_MDNS_SUPPORT */ #endif /* HAVE_MDNS_SUPPORT */
}; /* getdns_context */ }; /* getdns_context */

View File

@ -128,6 +128,7 @@
#define MDNS_DEBUG_ENTRY "-> MDNS ENTRY: " #define MDNS_DEBUG_ENTRY "-> MDNS ENTRY: "
#define MDNS_DEBUG_READ "-- MDNS READ: " #define MDNS_DEBUG_READ "-- MDNS READ: "
#define MDNS_DEBUG_MREAD "-- MDNS MREAD: "
#define MDNS_DEBUG_WRITE "-- MDNS WRITE: " #define MDNS_DEBUG_WRITE "-- MDNS WRITE: "
#define MDNS_DEBUG_CLEANUP "-- MDNS CLEANUP:" #define MDNS_DEBUG_CLEANUP "-- MDNS CLEANUP:"

View File

@ -48,12 +48,10 @@ uint64_t _getdns_get_time_as_uintt64();
#define MDNS_MCAST_IPV4_LONG 0xE00000FB /* 224.0.0.251 */ #define MDNS_MCAST_IPV4_LONG 0xE00000FB /* 224.0.0.251 */
#define MDNS_MCAST_PORT 5353 #define MDNS_MCAST_PORT 5353
/* static uint8_t mdns_mcast_ipv6[] = {
* TODO: When we start supporting IPv6 with MDNS, need to define this: 0xFF, 0x02, 0, 0, 0, 0, 0, 0,
* static uint8_t mdns_mcast_ipv6[] = { 0, 0, 0, 0, 0, 0, 0, 0xFB
* 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_dot_local[] = { 5, 'l', 'o', 'c', 'a', 'l', 0 };
static uint8_t mdns_suffix_254_169_in_addr_arpa[] = { 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 }; 4, 'a', 'r', 'p', 'a', 0 };
static uint8_t mdns_suffix_8_e_f_ip6_arpa[] = { static uint8_t mdns_suffix_8_e_f_ip6_arpa[] = {
1, '8', 1, 'e', 1, 'f', 1, '8', 1, 'e', 1, 'f',
7, 'i', 'p', 'v', '6', 3, 'i', 'p', '6',
4, 'a', 'r', 'p', 'a', 0 }; 4, 'a', 'r', 'p', 'a', 0 };
static uint8_t mdns_suffix_9_e_f_ip6_arpa[] = { static uint8_t mdns_suffix_9_e_f_ip6_arpa[] = {
1, '9', 1, 'e', 1, 'f', 1, '9', 1, 'e', 1, 'f',
7, 'i', 'p', 'v', '6', 3, 'i', 'p', '6',
4, 'a', 'r', 'p', 'a', 0 }; 4, 'a', 'r', 'p', 'a', 0 };
static uint8_t mdns_suffix_a_e_f_ip6_arpa[] = { static uint8_t mdns_suffix_a_e_f_ip6_arpa[] = {
1, 'a', 1, 'e', 1, 'f', 1, 'a', 1, 'e', 1, 'f',
7, 'i', 'p', 'v', '6', 3, 'i', 'p', '6',
4, 'a', 'r', 'p', 'a', 0 }; 4, 'a', 'r', 'p', 'a', 0 };
static uint8_t mdns_suffix_b_e_f_ip6_arpa[] = { static uint8_t mdns_suffix_b_e_f_ip6_arpa[] = {
1, 'b', 1, 'e', 1, 'f', 1, 'b', 1, 'e', 1, 'f',
7, 'i', 'p', 'v', '6', 3, 'i', 'p', '6',
4, 'a', 'r', 'p', 'a', 0 }; 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 * kr1 = (getdns_mdns_known_record *)nkr1;
getdns_mdns_known_record * kr2 = (getdns_mdns_known_record *)nkr2; 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; return ret;
@ -146,14 +156,181 @@ static int mdns_cmp_continuous_queries_by_name_rrtype(const void * nqnr1, const
return ret; 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 * 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; int ret = 0;
getdns_mdns_continuous_query temp_query, *continuous_query, *inserted_query; getdns_mdns_continuous_query temp_query, *continuous_query, *inserted_query;
getdns_dns_req *dnsreq = netreq->owner; getdns_dns_req *dnsreq = netreq->owner;
struct getdns_context *context = dnsreq->context;
/* /*
* Fill the target request, but only initialize name and request_type * 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. * TODO: should lock the context object when doing that.
*/ */
continuous_query = (getdns_mdns_continuous_query *) 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) if (continuous_query == NULL)
{ {
continuous_query = (getdns_mdns_continuous_query *) 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) 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_class = temp_query.request_class;
continuous_query->request_type = temp_query.request_type; continuous_query->request_type = temp_query.request_type;
continuous_query->name_len = temp_query.name_len; continuous_query->name_len = temp_query.name_len;
memcpy(continuous_query->name, temp_query.name, 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); continuous_query->netreq_first = NULL;
/* Tracking of network requests on this socket */
_getdns_rbtree_init(&continuous_query->netreq_by_query_id, mdns_cmp_netreq_by_query_id);
/* Add the new continuous query to the context */ /* Add the new continuous query to the context */
inserted_query = _getdns_rbtree_insert(&dnsreq->context->mdns_continuous_queries_by_name_rrtype, inserted_query = (getdns_mdns_continuous_query *)
continuous_query); _getdns_rbtree_insert(&context->mdns_continuous_queries_by_name_rrtype,
&continuous_query->node);
if (inserted_query == NULL) if (inserted_query == NULL)
{ {
/* Weird. This can only happen in a race condition */ /* 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; ret = GETDNS_RETURN_GENERIC_ERROR;
} }
} }
@ -197,12 +377,42 @@ static int mdns_initialize_continuous_request(getdns_network_req *netreq)
ret = GETDNS_RETURN_MEMORY_ERROR; 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 */ /* to do: queue message request to socket */
return ret; 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.. */ /* TODO: actualy delete what is required.. */
static void static void
mdns_cleanup(getdns_network_req *netreq) mdns_cleanup(getdns_network_req *netreq)
@ -212,8 +422,6 @@ mdns_cleanup(getdns_network_req *netreq)
getdns_dns_req *dnsreq = netreq->owner; getdns_dns_req *dnsreq = netreq->owner;
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event); GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
GETDNS_NULL_FREE(dnsreq->context->mf, netreq->tcp.read_buf);
} }
void void

View File

@ -37,26 +37,36 @@ _getdns_mdns_namespace_check(getdns_dns_req *dnsreq);
typedef struct getdns_mdns_known_record 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; uint8_t * record_data;
int record_length;
} getdns_mdns_known_record; } getdns_mdns_known_record;
typedef struct getdns_mdns_continuous_query 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 */ uint8_t name[256]; /* binary representation of name being queried */
int name_len; int name_len;
uint16_t request_class; uint16_t request_class;
uint16_t request_type; uint16_t request_type;
/* list of known records */
_getdns_rbtree_t known_records_by_value;
/* list of user queries */ /* 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 expiration date, or a timer? */
/* todo: do we need an update mark for showing last results? */ /* todo: do we need an update mark for showing last results? */
} getdns_mdns_continuous_query; } 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 /* HAVE_MDNS_SUPPORT */
#endif /* MDNS_H */ #endif /* MDNS_H */

View File

@ -135,7 +135,11 @@ static void tcp_connection_destroy(tcp_connection *conn)
loop->vmt->clear(loop, &conn->event); loop->vmt->clear(loop, &conn->event);
if (conn->fd >= 0) if (conn->fd >= 0)
#ifdef USE_WINSOCK
(void) closesocket(conn->fd);
#else
(void) close(conn->fd); (void) close(conn->fd);
#endif
GETDNS_FREE(*mf, conn->read_buf); GETDNS_FREE(*mf, conn->read_buf);
for (cur = conn->to_write; cur; cur = next) { for (cur = conn->to_write; cur; cur = next) {
@ -185,8 +189,8 @@ static void tcp_write_cb(void *userarg)
} }
to_write = conn->to_write; to_write = conn->to_write;
if (conn->fd == -1 || if (conn->fd == -1 ||
(written = write(conn->fd, &to_write->write_buf[to_write->written], (written = send(conn->fd, &to_write->write_buf[to_write->written],
to_write->write_buf_len - to_write->written)) == -1) { to_write->write_buf_len - to_write->written, 0)) == -1) {
/* IO error, close connection */ /* IO error, close connection */
conn->event.read_cb = conn->event.write_cb = conn->event.read_cb = conn->event.write_cb =
@ -280,7 +284,11 @@ getdns_reply(
(struct sockaddr *)&conn->remote_in, conn->addrlen) == -1) { (struct sockaddr *)&conn->remote_in, conn->addrlen) == -1) {
/* IO error, cleanup this listener */ /* IO error, cleanup this listener */
loop->vmt->clear(loop, &conn->l->event); loop->vmt->clear(loop, &conn->l->event);
#ifdef USE_WINSOCK
closesocket(conn->l->fd);
#else
close(conn->l->fd); close(conn->l->fd);
#endif
conn->l->fd = -1; conn->l->fd = -1;
} }
/* Unlink this connection */ /* Unlink this connection */
@ -359,7 +367,7 @@ static void tcp_read_cb(void *userarg)
(void) loop->vmt->schedule(loop, conn->fd, (void) loop->vmt->schedule(loop, conn->fd,
DOWNSTREAM_IDLE_TIMEOUT, &conn->event); 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) if (errno == EAGAIN || errno == EWOULDBLOCK)
return; /* Come back to do the read later */ 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) { &conn->super.remote_in, &conn->super.addrlen)) == -1) {
/* IO error, cleanup this listener */ /* IO error, cleanup this listener */
loop->vmt->clear(loop, &l->event); loop->vmt->clear(loop, &l->event);
#ifdef USE_WINSOCK
closesocket(l->fd);
#else
close(l->fd); close(l->fd);
#endif
l->fd = -1; l->fd = -1;
GETDNS_FREE(*mf, conn); GETDNS_FREE(*mf, conn);
return; return;
@ -543,7 +555,11 @@ static void udp_read_cb(void *userarg)
(struct sockaddr *)&conn->remote_in, &conn->addrlen)) == -1) { (struct sockaddr *)&conn->remote_in, &conn->addrlen)) == -1) {
/* IO error, cleanup this listener. */ /* IO error, cleanup this listener. */
loop->vmt->clear(loop, &l->event); loop->vmt->clear(loop, &l->event);
#ifdef USE_WINSOCK
closesocket(l->fd);
#else
close(l->fd); close(l->fd);
#endif
l->fd = -1; l->fd = -1;
#if 0 && defined(SERVER_DEBUG) && SERVER_DEBUG #if 0 && defined(SERVER_DEBUG) && SERVER_DEBUG

View File

@ -183,7 +183,6 @@ typedef struct getdns_tcp_state {
} getdns_tcp_state; } getdns_tcp_state;
/** /**
* Request data * Request data
**/ **/
@ -191,6 +190,15 @@ typedef struct getdns_network_req
{ {
/* For storage in upstream->netreq_by_query_id */ /* For storage in upstream->netreq_by_query_id */
_getdns_rbnode_t node; _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 */ /* the async_id from unbound */
int unbound_id; int unbound_id;
/* state var */ /* state var */