libcli/nbt: fix wack timeout handling
authorStefan Metzmacher <metze@samba.org>
Sat, 17 Jan 2009 17:14:29 +0000 (18:14 +0100)
committerStefan Metzmacher <metze@samba.org>
Mon, 19 Jan 2009 06:05:23 +0000 (07:05 +0100)
If the client gets a WACK response, the server
sends a timeout to the client. Possible
values are between 9 and 105 seconds.

Because w2k3 servers have a bug and always return
a value of 5 seconds, we need a workarround.

Always using a fixed value of 30 seconds is bad
as we could timeout to early.

Now we use the value from the server if it's in the
valid range and otherwise we use the upper limit
of the valid range (105s).

metze
(from samba4wins tree 40ef7739f4141598a6392c203e4a2d52d972fe06)

libcli/nbt/nbtsocket.c

index 083cef9..68c5d89 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);