libcli/nbt: fix wack timeout handling
[kai/samba-autobuild/.git] / libcli / nbt / nbtsocket.c
index 083cef96e812a873af80a8ad1d88411cc9675a48..68c5d89db673a0aba20c34b48ea619f5692d57ea 100644 (file)
@@ -234,6 +234,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock)
        /* if this is a WACK response, this we need to go back to waiting,
           but perhaps increase the timeout */
        if ((packet->operation & NBT_OPCODE) == NBT_OPCODE_WACK) {
+               uint32_t ttl;
                if (req->received_wack || packet->ancount < 1) {
                        nbt_name_request_destructor(req);
                        req->status = NT_STATUS_INVALID_NETWORK_RESPONSE;
@@ -245,9 +246,23 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock)
                   has received our request */
                req->num_retries   = 0;
                req->received_wack = true;
-               /* although there can be a timeout in the packet, w2k3 screws it up,
-                  so better to set it ourselves */
-               req->timeout = lp_parm_int(global_loadparm, NULL, "nbt", "wack_timeout", 30);
+               /*
+                * there is a timeout in the packet,
+                * it is 5 + 4 * num_old_addresses
+                *
+                * although w2k3 screws it up
+                * and uses num_old_addresses = 0
+                *
+                * so we better fallback to the maximum
+                * of num_old_addresses = 25 if we got
+                * a timeout of less than 9s (5 + 4*1)
+                * or more than 105s (5 + 4*25).
+                */
+               ttl = packet->answers[0].ttl;
+               if ((ttl < (5 + 4*1)) || (ttl > (5 + 4*25))) {
+                       ttl = 5 + 4*25;
+               }
+               req->timeout = ttl;
                req->te = event_add_timed(req->nbtsock->event_ctx, req,
                                          timeval_current_ofs(req->timeout, 0),
                                          nbt_name_socket_timeout, req);