a cleanup of the receive_smb() usage, adding timeouts in some places
authorAndrew Tridgell <tridge@samba.org>
Mon, 10 Jun 1996 05:16:19 +0000 (05:16 +0000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 10 Jun 1996 05:16:19 +0000 (05:16 +0000)
also added paranoid code in the main process() loop of smbd to detect
when smbd is looping uselessly. This should stop the "smbd is chewing
lots of cpu" reports
(This used to be commit 8e9dce34d50d673cb50531f0c4c7672ce2522cef)

source3/include/smb.h
source3/lib/util.c
source3/smbd/ipc.c
source3/smbd/password.c
source3/smbd/reply.c
source3/smbd/server.c
source3/smbd/trans2.c

index 5fd2e0846bbdebad1be7508e8326413d22131973..b9dd13a802b8387162c1af883330bdbb44ca4ecd 100644 (file)
@@ -99,6 +99,9 @@ typedef unsigned int uint32;
 #define DEFAULT_PIPE_TIMEOUT 10000000 /* Ten seconds */
 #endif
 
 #define DEFAULT_PIPE_TIMEOUT 10000000 /* Ten seconds */
 #endif
 
+/* how long to wait for secondary SMB packets (seconds) */
+#define SMB_SECONDARY_WAIT 30
+
 /* debugging code */
 #ifndef SYSLOG
 #define DEBUG(level,body) ((DEBUGLEVEL>=(level))?(Debug1 body):0)
 /* debugging code */
 #ifndef SYSLOG
 #define DEBUG(level,body) ((DEBUGLEVEL>=(level))?(Debug1 body):0)
index fc47313b57b1d5f3a2ed00f5564ab859581d9622..ee4fca3ed37eb6e75cdfca3715b889d92ac41199 100644 (file)
@@ -2079,7 +2079,7 @@ int read_smb_length(int fd,char *inbuf,int timeout)
 
       if (msg_type == 0x85) 
        {
 
       if (msg_type == 0x85) 
        {
-         DEBUG(5,( "Got keepalive packet\n"));
+         DEBUG(5,("Got keepalive packet\n"));
          ok = False;
        }
     }
          ok = False;
        }
     }
@@ -2097,8 +2097,7 @@ The timeout is in milli seconds
 ****************************************************************************/
 BOOL receive_smb(int fd,char *buffer,int timeout)
 {
 ****************************************************************************/
 BOOL receive_smb(int fd,char *buffer,int timeout)
 {
-  int len;
-  BOOL ok;
+  int len,ret;
 
   bzero(buffer,smb_size + 100);
 
 
   bzero(buffer,smb_size + 100);
 
@@ -2107,18 +2106,16 @@ BOOL receive_smb(int fd,char *buffer,int timeout)
     return(False);
 
   if (len > BUFFER_SIZE) {
     return(False);
 
   if (len > BUFFER_SIZE) {
-    DEBUG(0,("Invalid packet length! (%d bytes)\n",len));
+    DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
     if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
       exit(1);
   }
 
     if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
       exit(1);
   }
 
-  ok = (read_data(fd,buffer+4,len) == len);
-
-  if (!ok)
-    {
-      close_sockets();
-      exit(1);
-    }
+  ret = read_data(fd,buffer+4,len);
+  if (ret != len) {
+    DEBUG(0,("ERROR: Invalid SMB length. Expected %d got %d\n",len,ret));
+    return False;
+  }
 
   return(True);
 }
 
   return(True);
 }
index 594e067ddd4bbf2890ea405f66fb8fa401f34409..415c939bf38c2b72a4e1fa3e0fda6c516ab29f40 100644 (file)
@@ -2790,12 +2790,9 @@ int reply_trans(char *inbuf,char *outbuf)
   while (pscnt < tpscnt || dscnt < tdscnt)
     {
       int pcnt,poff,dcnt,doff,pdisp,ddisp;
   while (pscnt < tpscnt || dscnt < tdscnt)
     {
       int pcnt,poff,dcnt,doff,pdisp,ddisp;
-
-      receive_smb(Client,inbuf, 0);
-      show_msg(inbuf);
-         
-      /* Ensure this is still a trans packet (sanity check) */
-      if(CVAL(inbuf, smb_com) != SMBtrans)
+      
+      if (!receive_smb(Client,inbuf, SMB_SECONDARY_WAIT*1000) ||
+         CVAL(inbuf, smb_com) != SMBtrans)
        {
          DEBUG(2,("Invalid secondary trans2 packet\n"));
          if (params) free(params);
        {
          DEBUG(2,("Invalid secondary trans2 packet\n"));
          if (params) free(params);
@@ -2803,6 +2800,8 @@ int reply_trans(char *inbuf,char *outbuf)
          if (setup) free(setup);
          return(ERROR(ERRSRV,ERRerror));
        }
          if (setup) free(setup);
          return(ERROR(ERRSRV,ERRerror));
        }
+
+      show_msg(inbuf);
       
       tpscnt = SVAL(inbuf,smb_vwv0);
       tdscnt = SVAL(inbuf,smb_vwv1);
       
       tpscnt = SVAL(inbuf,smb_vwv0);
       tdscnt = SVAL(inbuf,smb_vwv1);
index ae548b826693ac0bb8aa6c5dd4b2f239e46a4dbd..a5f597682f646cbb815789895809c9f1eab19ca7 100644 (file)
@@ -1318,9 +1318,10 @@ BOOL server_cryptkey(char *buf)
   CVAL(outbuf,0) = 0x81;
 
   send_smb(password_client,outbuf);
   CVAL(outbuf,0) = 0x81;
 
   send_smb(password_client,outbuf);
-  receive_smb(password_client,inbuf,5000);
+  
  
  
-  if (CVAL(inbuf,0) != 0x82) {
+  if (!receive_smb(password_client,inbuf,5000) ||
+      CVAL(inbuf,0) != 0x82) {
     DEBUG(1,("%s rejected the session\n",pserver));
     close(password_client); password_client = -1;
     return(False);
     DEBUG(1,("%s rejected the session\n",pserver));
     close(password_client); password_client = -1;
     return(False);
index 43703982ec94e5dde146e2aaf0e85caeafdb722f..4cfa001ec2144b3567e4fe833f7ca7dec62b8902 100644 (file)
@@ -1590,7 +1590,7 @@ int reply_writebraw(char *inbuf,char *outbuf)
   send_smb(Client,outbuf);
   
   /* Now read the raw data into the buffer and write it */
   send_smb(Client,outbuf);
   
   /* Now read the raw data into the buffer and write it */
-  if(read_smb_length(Client,inbuf,0) == -1) {
+  if (read_smb_length(Client,inbuf,SMB_SECONDARY_WAIT) == -1) {
     exit_server("secondary writebraw failed");
   }
   
     exit_server("secondary writebraw failed");
   }
   
index ecc8e4ce9c57d18b197973bb6e4447ab7b7e767d..3ececed393a6a6bada83eb4955b3e6cc834529fd 100644 (file)
@@ -3445,6 +3445,27 @@ static void process(void)
 
          t = time(NULL);
 
 
          t = time(NULL);
 
+         {
+           /* the following bit of code was added to combat smbd
+               looping chewing lots of CPU time. It should never
+               actually be needed, but it seems that some systems
+               don't set error correctly, which is used to distinguish
+               a select() timeout from a read error 
+              
+              we exit if receive_smb() returns false 3 times in one second. 
+              */
+           static int error_count=0;
+           static time_t error_time=0;
+           if (error_count==0) {
+             error_time = t;
+           } else if (error_time != t) {
+             error_count = 0;
+           } else if (error_count++ > 2) {
+             exit_server("looping in process()\n");
+           }
+         }
+
+
          /* become root again if waiting */
          unbecome_user();
 
          /* become root again if waiting */
          unbecome_user();
 
index 0b113a2ed0eec45e56b34cfa940bacd517817156..321dabc72cf280b976ad31b7aa39e7c99c817969 100644 (file)
@@ -1554,10 +1554,8 @@ int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize)
 
       while( num_data_sofar < total_data || num_params_sofar < total_params)
        {
 
       while( num_data_sofar < total_data || num_params_sofar < total_params)
        {
-         receive_smb(Client,inbuf, 0);
-         
-         /* Ensure this is still a trans2 packet (sanity check) */
-         if(CVAL(inbuf, smb_com) != SMBtranss2)
+         if(!receive_smb(Client,inbuf, SMB_SECONDARY_WAIT*1000) ||
+            CVAL(inbuf, smb_com) != SMBtranss2)
            {
              outsize = set_message(outbuf,0,0,True);
              DEBUG(2,("Invalid secondary trans2 packet\n"));
            {
              outsize = set_message(outbuf,0,0,True);
              DEBUG(2,("Invalid secondary trans2 packet\n"));