Fix bug with nmbd running wild due to recursion in retransmit_or_expire_response_reco...
authorJeremy Allison <jra@samba.org>
Thu, 17 Dec 1998 21:41:28 +0000 (21:41 +0000)
committerJeremy Allison <jra@samba.org>
Thu, 17 Dec 1998 21:41:28 +0000 (21:41 +0000)
Jeremy.

source/include/nameserv.h
source/nmbd/nmbd_packets.c
source/nmbd/nmbd_responserecordsdb.c

index e3a1d740a744f80f09218e81b09e97b6e6956a1b..995a47b2fa0bb58e03fbbdca48df3ae6d2f8c30c 100644 (file)
@@ -369,6 +369,9 @@ struct response_record
   time_t repeat_time;
   time_t repeat_interval;
   int    repeat_count;
+
+  /* Recursion protection. */
+  BOOL in_expiration_processing;
 };
 
 /* A subnet structure. It contains a list of workgroups and netbios names. */
index ce785b40a457713090ff0668dd2889d85a6bdf4b..7f277533522e119114b3051c92b6a9cd00cb6ae1 100644 (file)
@@ -1633,16 +1633,31 @@ to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip),
 on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), 
                  subrec->subnet_name));
 
-          /* Call the timeout function. This will deal with removing the
-             timed out packet. */
-          if(rrec->timeout_fn)
-            (*rrec->timeout_fn)(subrec, rrec);
-          else
+          /*
+           * Check the flag in this record to prevent recursion if we end
+           * up in this function again via the timeout function call.
+           */
+
+          if(!rrec->in_expiration_processing)
           {
-            /* We must remove the record ourself if there is
-               no timeout function. */
-            remove_response_record(subrec, rrec);
-          }
+
+            /*
+             * Set the recursion protection flag in this record.
+             */
+
+            rrec->in_expiration_processing = True;
+
+            /* Call the timeout function. This will deal with removing the
+               timed out packet. */
+            if(rrec->timeout_fn)
+              (*rrec->timeout_fn)(subrec, rrec);
+            else
+            {
+              /* We must remove the record ourself if there is
+                 no timeout function. */
+              remove_response_record(subrec, rrec);
+            }
+          } /* !rrec->in_expitation_processing */
         } /* rrec->repeat_count > 0 */
       } /* rrec->repeat_time <= t */
     } /* end for rrec */
index 3edca699812f34b7ebddc32965f7489a3c2d8226..0c698760bb6670b938a8912d5e347c91115176eb 100644 (file)
@@ -172,6 +172,9 @@ struct response_record *make_response_record( struct subnet_record *subrec,
   rrec->repeat_count = 3; /* 3 retries */
   rrec->repeat_time = time(NULL) + rrec->repeat_interval; /* initial retry time */
 
+  /* This packet is not being processed. */
+  rrec->in_expiration_processing = False;
+
   /* Lock the packet so we won't lose it while it's on the list. */
   p->locked = True;