Fix IPv6 detection on XP.

Fix loop to service on quit when there are messages waiting.

git-svn-id: file:///svn/unbound/trunk@1624 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2009-05-27 08:24:19 +00:00
parent daf63c7e89
commit b86b9f7fdc
7 changed files with 44 additions and 2 deletions

View file

@ -1163,6 +1163,7 @@ worker_delete(struct worker* worker)
mesh_stats(worker->env.mesh, "mesh has");
worker_mem_report(worker, NULL);
}
outside_network_quit_prepare(worker->back);
mesh_delete(worker->env.mesh);
ldns_buffer_free(worker->env.scratch_buffer);
forwards_delete(worker->env.fwds);

View file

@ -1,3 +1,11 @@
27 May 2009: Wouter
- detect lack of IPv6 support on XP (with a different error code).
- Fixup a crash-on-exit which was triggered by a very long queue.
Unbound would try to re-use ports that came free, but this is
of course not really possible because everything is deleted.
Most easily triggered on XP (not Vista), maybe because of the
network stack encouraging large messages backlogs.
26 May 2009: Wouter
- Thanks again to Brett Carr, found an assertion that was not true.
Assertion checked if recursion parent query still existed.

View file

@ -72,6 +72,7 @@ libworker_delete(struct libworker* w)
{
if(!w) return;
if(w->env) {
outside_network_quit_prepare(w->back);
mesh_delete(w->env->mesh);
context_release_alloc(w->ctx, w->env->alloc,
!w->is_bg || w->is_bg_thread);

View file

@ -295,6 +295,12 @@ make_sock(int stype, const char* ifname, const char* port,
hints->ai_socktype = stype;
*noip6 = 0;
if((r=getaddrinfo(ifname, port, hints, &res)) != 0 || !res) {
#ifdef USE_WINSOCK
if(r == EAI_NONAME && hints->ai_family == AF_INET6){
*noip6 = 1; /* 'Host not found' for IP6 on winXP */
return -1;
}
#endif
log_err("node %s:%s getaddrinfo: %s %s",
ifname?ifname:"default", port, gai_strerror(r),
#ifdef EAI_SYSTEM

View file

@ -194,7 +194,8 @@ static void
use_free_buffer(struct outside_network* outnet)
{
struct waiting_tcp* w;
while(outnet->tcp_free && outnet->tcp_wait_first) {
while(outnet->tcp_free && outnet->tcp_wait_first
&& !outnet->want_to_quit) {
w = outnet->tcp_wait_first;
outnet->tcp_wait_first = w->next_waiting;
if(outnet->tcp_wait_last == w)
@ -276,7 +277,8 @@ outnet_send_wait_udp(struct outside_network* outnet)
{
struct pending* pend;
/* process waiting queries */
while(outnet->udp_wait_first && outnet->unused_fds) {
while(outnet->udp_wait_first && outnet->unused_fds
&& !outnet->want_to_quit) {
pend = outnet->udp_wait_first;
outnet->udp_wait_first = pend->next_waiting;
if(!pend->next_waiting) outnet->udp_wait_last = NULL;
@ -483,6 +485,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
outnet->infra = infra;
outnet->rnd = rnd;
outnet->svcd_overhead = 0;
outnet->want_to_quit = 0;
outnet->unwanted_threshold = unwanted_threshold;
outnet->unwanted_action = unwanted_action;
outnet->unwanted_param = unwanted_param;
@ -608,11 +611,21 @@ serviced_node_del(rbnode_t* node, void* ATTR_UNUSED(arg))
free(sq);
}
void
outside_network_quit_prepare(struct outside_network* outnet)
{
if(!outnet)
return;
/* prevent queued items from being sent */
outnet->want_to_quit = 1;
}
void
outside_network_delete(struct outside_network* outnet)
{
if(!outnet)
return;
outnet->want_to_quit = 1;
/* check every element, since we can be called on malloc error */
if(outnet->pending) {
/* free pending elements, but do no unlink from tree. */

View file

@ -75,6 +75,8 @@ struct outside_network {
size_t svcd_overhead;
/** use x20 bits to encode additional ID random bits */
int use_caps_for_id;
/** outside network wants to quit. Stop queued msgs from sent. */
int want_to_quit;
/** number of unwanted replies received (for statistics) */
size_t unwanted_replies;
@ -360,6 +362,12 @@ struct outside_network* outside_network_create(struct comm_base* base,
*/
void outside_network_delete(struct outside_network* outnet);
/**
* Prepare for quit. Sends no more queries, even if queued up.
* @param outnet: object to prepare for removal
*/
void outside_network_quit_prepare(struct outside_network* outnet);
/**
* Send UDP query, create pending answer.
* Changes the ID for the query to be random and unique for that destination.

View file

@ -749,6 +749,11 @@ outside_network_delete(struct outside_network* outnet)
free(outnet);
}
void
outside_network_quit_prepare(struct outside_network* ATTR_UNUSED(outnet))
{
}
struct pending*
pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,