Samba 3 socket status after [RST, ACK]

Petr Sumbera Petr.Sumbera at Sun.COM
Fri Dec 1 16:52:54 GMT 2006


Hi Alison,

Alison Winters wrote:
> 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.

Thanks, it really avoids those messages.

> 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?

Yes, it would be interesting to see some benchmarks. I will check 
whether we are capable of doing anything with it.

Don't you know whether there is any other limitation when using port 139 
only?

> 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.

I think that something like that would be really wild (if not impossible 
if we don't know what Windows client really wants). And also it would be 
very platform specific :-)

Petr

> 
> 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