diff -up bind-9.3.6-P1/lib/dns/request.c.rh676242 bind-9.3.6-P1/lib/dns/request.c --- bind-9.3.6-P1/lib/dns/request.c.rh676242 2011-08-04 19:59:20.881352473 +0200 +++ bind-9.3.6-P1/lib/dns/request.c 2011-08-04 20:01:18.503344208 +0200 @@ -95,6 +95,7 @@ struct dns_request { synchronously canceled */ #define DNS_REQUEST_F_TIMEDOUT 0x0008 /* cancelled due to a timeout */ #define DNS_REQUEST_F_TCP 0x0010 /* This request used TCP */ +#define DNS_REQUEST_F_RESPONSE 0x0020 /*%< We got response */ #define DNS_REQUEST_CANCELED(r) \ (((r)->flags & DNS_REQUEST_F_CANCELED) != 0) #define DNS_REQUEST_CONNECTING(r) \ @@ -103,6 +104,8 @@ struct dns_request { (((r)->flags & DNS_REQUEST_F_SENDING) != 0) #define DNS_REQUEST_TIMEDOUT(r) \ (((r)->flags & DNS_REQUEST_F_TIMEDOUT) != 0) +#define DNS_REQUEST_RESPONSE(r) \ + (((r)->flags & DNS_REQUEST_F_RESPONSE) != 0) /*** @@ -1308,9 +1311,15 @@ req_senddone(isc_task_t *task, isc_event if (DNS_REQUEST_CANCELED(request)) { /* - * Send delayed event. + * Response can arrive before we proccess + * req_senddone which means we received cancellation + * request from req_response(). If we successfully + * fetched response, send success. Otherwise + * indicate failure. */ - if (DNS_REQUEST_TIMEDOUT(request)) + if (DNS_REQUEST_RESPONSE(request)) + send_if_done(request, ISC_R_SUCCESS); + else if (DNS_REQUEST_TIMEDOUT(request)) send_if_done(request, ISC_R_TIMEDOUT); else send_if_done(request, ISC_R_CANCELED); @@ -1363,6 +1372,8 @@ req_response(isc_task_t *task, isc_event /* * Send completion event. */ + if (result == ISC_R_SUCCESS) + request->flags |= DNS_REQUEST_F_RESPONSE; send_if_done(request, result); UNLOCK(&request->requestmgr->locks[request->hash]); }