1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

a cleanup of the receive_smb() usage, adding timeouts in some places

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 8e9dce34d5)
This commit is contained in:
Andrew Tridgell 1996-06-10 05:16:19 +00:00
parent 7e3b4a1c0d
commit a521fe8a27
7 changed files with 43 additions and 24 deletions

View File

@ -99,6 +99,9 @@ typedef unsigned int uint32;
#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)

View File

@ -2079,7 +2079,7 @@ int read_smb_length(int fd,char *inbuf,int timeout)
if (msg_type == 0x85)
{
DEBUG(5,( "Got keepalive packet\n"));
DEBUG(5,("Got keepalive packet\n"));
ok = False;
}
}
@ -2097,8 +2097,7 @@ The timeout is in milli seconds
****************************************************************************/
BOOL receive_smb(int fd,char *buffer,int timeout)
{
int len;
BOOL ok;
int len,ret;
bzero(buffer,smb_size + 100);
@ -2107,18 +2106,16 @@ BOOL receive_smb(int fd,char *buffer,int timeout)
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);
}
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);
}

View File

@ -2790,12 +2790,9 @@ int reply_trans(char *inbuf,char *outbuf)
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);
@ -2803,6 +2800,8 @@ int reply_trans(char *inbuf,char *outbuf)
if (setup) free(setup);
return(ERROR(ERRSRV,ERRerror));
}
show_msg(inbuf);
tpscnt = SVAL(inbuf,smb_vwv0);
tdscnt = SVAL(inbuf,smb_vwv1);

View File

@ -1318,9 +1318,10 @@ BOOL server_cryptkey(char *buf)
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);

View 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 */
if(read_smb_length(Client,inbuf,0) == -1) {
if (read_smb_length(Client,inbuf,SMB_SECONDARY_WAIT) == -1) {
exit_server("secondary writebraw failed");
}

View File

@ -3445,6 +3445,27 @@ static void process(void)
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();

View 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)
{
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"));