Samba 3 socket status after [RST, ACK]

Alison Winters alisonw at sgi.com
Fri Dec 1 00:03:32 GMT 2006


FWIW we're currently working around this by only running Samba on port
139 (smb ports config option).  Running only on 445 makes browsing break.

I'd be very interested to see performance figures of running Samba only
on 139 vs both ports.  I'm guessing the connect will be faster because
445 will be dropped by the kernel straight away, but perhaps there is
significant transport overhead in NBT vs raw TCP?

I'm not sure there is a clever programmatic solution to this.  Perhaps
if you had a decent packet filter you could do something really evil
like blocking 139 requests that weren't browse requests iff a 445 wasn't
coming from the same client too?  Ick.

Alison


Petr Sumbera wrote:
> 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