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);
+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.
{
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);
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
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)
{
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;
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;
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. */
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;
*/
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.
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,