[linux-cifs-client] Re: strange tcp peek behavior confuses cifs demultiplexing

Steve French smfrench at austin.rr.com
Tue Dec 14 16:21:22 GMT 2004


Ok - this seems straightforward problem (although one I did not believe 
could happen with Linux TCP/IP stack) and the approach I tried isn't 
going to work without a slightly different change.

Background:
cifs has a kernel thread which reads data from each server we have a 
mount to (one thread per server socket).
This "demultiplex thread" basically does:

while(not shutting down/unmounting) {
    Peek to see if it is an SMB response
    If valid RFC1001 frame but not SMB   
        continue
    If SMB is not valid {
       /* assume something bad happened to server */
       kill session
       reconnect session
       continue
    }
    while(data left in SMB to read off socket)
        Read SMB from socket

    find which task is waiting for this smb
    wake up the task waiting on this smb
}
   

The problem here is that I need at least 4 bytes returned from the peek 
to be able to determine the length and RFC1001 frame type.  So I have to 
get 4 bytes (but since I can't imagine the tcp stack returning fewer 
than that on the peek since at a minimum the servers send 
sizeof(smb_header) in one tcp send, this has never been a problem).  
Here though the stack is returning only 3 bytes of the SMB header on the 
peek!  Originally I had been assuming that the peek would always return 
what the server sent which would be either a 4 byte keep alive or 
sizeof(smb header) bytes (followed by a second send of the data) or a 
full SMB - obviously the stack does not always return on peek the 
corresponding size to the servers tcp sendmsg - so then I relaxed that 
to assume that if we did not get 14 bytes (enough to read the smb flags 
and tell if this was an smb response) - don't check the SMB flags (they 
get checked later anyway) - but we still need at least 4 bytes off the 
peek (otherwise I don't have the full length field and I can't tell how 
much to read off the socket).   Sounds like on the 3 byte peek I need to 
sleep for perhaps a millisecond, then try again until I get that 4th 
byte.  Note that I am expecting an error if the socket really is dead - 
I am not expecting a tiny peek.   Getting the 3 byte peek confused the 
next read which started 3 bytes off and did not parse as an SMB.

The fix on the peek less than 4 bytes is presumably to not read it off 
the socket, but to sleep a short time and continue retrying the peek.


Gorazd Golob wrote:

>Hi!
>
>Here is reproduces the problem reproduced with this new patch.. I guess
>something else went wrong. Below are two things as usual .. snip from
>dmesg (with cifsFYI on) and kernel oops with ksymoops. Hope it helps.
>
>--- dmesg ---
>
>Dec 14 08:40:59 delovc10 kernel:  fs/cifs/connect.c: Peek length rcvd:
>0x24 beginning 0x1044)
>Dec 14 08:40:59 delovc10 kernel:  fs/cifs/transport.c: For smb_command 46
>Dec 14 08:40:59 delovc10 kernel:  fs/cifs/transport.c: Sending smb of
>length 59
>Dec 14 08:40:59 delovc10 kernel:  fs/cifs/connect.c:  Mid 0xe667 matched -
>waking up
>Dec 14 08:40:59 delovc10 kernel:  fs/cifs/connect.c: Peek length rcvd:
>0x24 beginning 0x1044)
>Dec 14 08:40:59 delovc10 kernel:  fs/cifs/transport.c: For smb_command 46
>Dec 14 08:40:59 delovc10 kernel:  fs/cifs/transport.c: Sending smb of
>length 59
>Dec 14 08:40:59 delovc10 kernel:  fs/cifs/connect.c:  Mid 0xe668 matched -
>waking up
>Dec 14 08:40:59 delovc10 kernel:  fs/cifs/connect.c: Peek length rcvd: 0x3
>beginning 0x1004)
>Dec 14 08:40:59 delovc10 kernel:  fs/cifs/connect.c:  with junk  0x100000
>in it
>Dec 14 08:40:59 delovc10 kernel:  fs/cifs/transport.c: For smb_command 46
>Dec 14 08:40:59 delovc10 kernel:  fs/cifs/transport.c: Sending smb of
>length 59
>Dec 14 08:40:59 delovc10 kernel:  fs/cifs/connect.c: Peek length rcvd:
>0x24 beginning 0x40ff5351)
>Dec 14 08:40:59 delovc10 kernel:  CIFS VFS: Unknown RFC 1002 frame
>Dec 14 08:40:59 delovc10 kernel:  Received Data: : dump of 36 bytes of
>data at 0xe95007a0
>Dec 14 08:40:59 delovc10 kernel:
>Dec 14 08:41:00 delovc10 kernel:  4d53ff40 00002e42 01800000 000000c0 @ ÿ
>S M B . . . . . . . À . . .
>Dec 14 08:41:00 delovc10 kernel:  00000000 00000000 76080000 69080009 . .
>. . . . . . . . . v . . . i
>Dec 14 08:41:00 delovc10 kernel:  00ff0ce6 æ . ÿ .
>Dec 14 08:41:00 delovc10 kernel:  fs/cifs/connect.c: Reconnecting tcp
>session
>  
>




More information about the linux-cifs-client mailing list