Samba 3 socket status after [RST, ACK]

Petr Sumbera Petr.Sumbera at Sun.COM
Thu Nov 30 14:51:21 GMT 2006


Hi All,

I would like ask you for your opinion on the following issue with Samba 
3 (tested with 3.0.21b on Solaris and 3.0.20 on Linux).

When running samba against Windows (WinXP) client, there appears at some 
point some strange TCP communication (ending with [RST,ACK]):

No. Time   Src   Dst   Pro. Info
================================
67 .430902 WinXP Samba TCP  2321 > netbios-ssn [SYN] Seq=0 Len=0 MSS=1460
68 .431162 Samba WinXP TCP  netbios-ssn > 2321 [SYN, ACK] Seq=0 Ack=1 
Win=5840
Len=0 MSS=1460
69 .431623 WinXP Samba NBSS Session request, to TEST-DESKTOP<20> from 
TEST-87E22893BE<00>
70 .431912 Samba WinXP TCP  netbios-ssn > 2321 [ACK] Seq=1 Ack=73 
Win=5840 Len=0
78 .447703 WinXP Samba TCP  2321 > netbios-ssn [RST, ACK] Seq=73 Ack=1 
Win=0 Len=0
(above TCP stream was edited to better fit into email)

The best way how to run into this is following procedure on Windows client:

 > net use t: \\s10-pc\public
  --- Wait some time (something like 5 minutes but it's not clear)
 > net use t: /delete
  --- after issuing following command, error messages will appear
 > net use t: \\s10-pc\public

As result of this you will see in log.smbd following:

Linux:

[2006/11/30 11:44:07, 0] lib/util_sock.c:get_peer_addr(1225)
   getpeername failed. Error was Transport endpoint is not connected
[2006/11/30 11:44:07, 0] lib/util_sock.c:get_peer_addr(1225)

Solaris:

[2006/09/15 10:06:11, 0] lib/util_sock.c:(1229)
   getpeername failed. Error was Invalid argument
[2006/09/15 10:06:11, 0] lib/util_sock.c:(261)
   Failed to set socket option SO_KEEPALIVE (Error Invalid argument)
[2006/09/15 10:06:11, 0] lib/util_sock.c:(261)
   Failed to set socket option TCP_NODELAY (Error Invalid argument)
[2006/09/15 10:06:11, 0] lib/util_sock.c:(1229)
   getpeername failed. Error was Invalid argument

These messages comes from following piece of code in 
samba-3.0.21b/source/smbd/server.c:

     388 			smbd_set_server_fd(accept(s,&addr,&in_addrlen));

---> inside smbd_set_server_fd() getpeername system call is issued and 
it returns with Solaris error "getpeername failed. Error was Invalid 
argument"

     389
     390 			if (smbd_server_fd() == -1 && errno == EINTR)
     391 				continue;
     392
     393 			if (smbd_server_fd() == -1) {
     394 				DEBUG(0,("open_sockets_smbd: accept: %s\n",
     395 					 strerror(errno)));
     396 				continue;
     397 			}
     398
     399 			/* Ensure child is set to blocking mode */
     400 			set_blocking(smbd_server_fd(),True);
     401
     402 			if (smbd_server_fd() != -1 && interactive)
     403 				return True;
     404
     405 			if (allowable_number_of_smbd_processes() && smbd_server_fd() 
!= -1 && sys_fork()==0) {
     406 				/* Child code ... */
     407
     408 				/* close the listening socket(s) */
     409 				for(i = 0; i < num_sockets; i++)
     410 					close(fd_listenset[i]);
     411
     412 				/* close our standard file
     413 				   descriptors */
     414 				close_low_fds(False);
     415 				am_parent = 0;
     416
     417 				set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");

---> error message "Failed to set socket option SO_KEEPALIVE (Error 
Invalid argument)" is issued
     418 				set_socket_options(smbd_server_fd(),user_socket_options);

---> error message "Failed to set socket option TCP_NODELAY (Error 
Invalid argument)"  is issued

Notes:
======

- Not sure where the second getpeername() error comes from but it's not 
important.

- It seems that setsockopt() error appears only on Solaris (I think I 
saw somewhere on internet that it can be seen also on HP Unix)

Where I see the problem:
========================

Don't know why Windows is reseting TCP connection. But it seems that 
there are usually in such a case two attempts to connect to samba server 
(windows is trying to connect twice to ports 139 or to port 139 and 445) 
at the same time.

Samba is not functionally affected in any way. There are only several 
messages in log and samba is once forked more. But if there is many 
Windows clients, there is many messages. And in that case it can be a 
problem (messages and performance)...

How to avoid it?
================

I think we should add into samba after accept() is returned some check 
for socket sanity. If we find that socket is in some wrong state we 
shouldn't even do fork (just a close socket and continue in main loop).

But I see there some possible race condition. I believe [RST, ACK] can 
arrive little bit later (after we returned from accept() and maybe even 
after we are forked).

So, probably the best idea is to check return values from all socket 
calls and behave according them (even for getpeername() and setsockopt()).

---

Any comments are welcomed... :-)

Petr



More information about the samba-technical mailing list