Send dummy byte fix

Hi Wiznet,

I am using the w5300 in an application where it is not acceptable to send a “dummy” byte to overcome the zero window size problem (FTP data connection - the server just closes the connection). I see from Wiznet’s socket.c that the original fix attempt seems to have been to send a zero-length data packet to update the window size to the server. This works as a fix in my lab but I am wondering if there is a real-world situation where this will not work. Would it be possible to have details of the original problem report that resulted in fix M_15052008 so that I can make that judgement please?

Many thanks,

Bruce.

This is the part of socket.c I am refering to:

/*

  • \warning send a packet for updating window size. This code block must be only used when W5300 do only receiving data.
    */
    // ------------------------
    // WARNING CODE BLOCK START

// M_15052008 : Replace Sn_CR_SEND with Sn_CR_SEND_KEEP.
//if(!(getSn_IR(s) & Sn_IR_SENDOK))
//{
// setSn_TX_WRSR(s,0); // size = 0
// setSn_CR(s,Sn_CR_SEND); // send
// while(!(getSn_IR(s) & Sn_IR_SENDOK)); // wait SEND command completion
// setSn_IR(s,Sn_IR_SENDOK); // clear Sn_IR_SENDOK bit
//}

// M_04072008 : Replace Sn_CR_SEND_KEP with Sn_CR_SEND.
//if(getSn_RX_RSR(s) == 0) // send the window-update packet when the window size is full
//{
// uint8 keep_time = 0;
// if((keep_time=getSn_KPALVTR(s)) != 0x00) setSn_KPALVTR(s,0x00); // disables the auto-keep-alive-process
// setSn_CR(s,Sn_CR_SEND_KEEP); // send a keep-alive packet by command
// setSn_KPALVTR(s,keep_time); // restore the previous keep-alive-timer value
//}
#if 0
if(getSn_RX_RSR(s) == 0) // check if the window size is full or not
{ /* Sn_RX_RSR can be compared with another value instead of ¡®0¡¯,
according to the host performance of receiving data */
setSn_TX_WRSR(s,1); // size : 1 byte dummy size
IINCHIP_WRITE(Sn_TX_FIFOR(s),0x0000); // write dummy data into tx memory
setSn_CR(s,Sn_CR_SEND); // send
while(!(getSn_IR(s) & Sn_IR_SENDOK)); // wait SEND command completion
setSn_IR(s,Sn_IR_SENDOK); // clear Sn_IR_SENDOK bit
}
#endif
// WARNING CODE BLOCK END
// ----------------------

Hi, BruceTanner

At the result, if your W5300 running as only receiver and server can not accept dummy byte, there is no way for zero window size problem…

In case of W5300, if it sends packet, there is no problem with window size.

but if it is running only receiver(no sending packet), the only way to notice window size to server is sending dummy byte or any acceptable packet data with window size.

And w5300 can not send zero window size packet.

// M_15052008 : Replace Sn_CR_SEND with Sn_CR_SEND_KEEP. //if(!(getSn_IR(s) & Sn_IR_SENDOK)) //{ // setSn_TX_WRSR(s,0); // size = 0 // setSn_CR(s,Sn_CR_SEND); // send // while(!(getSn_IR(s) & Sn_IR_SENDOK)); // wait SEND command completion // setSn_IR(s,Sn_IR_SENDOK); // clear Sn_IR_SENDOK bit //}

I wonder how it works in your lab…

So, If you keep using W5300 as only receiver in this case, find a server which can accept dummy packet data or there is no way…

In this case, I recommend w5500 or w5200… because it is ok to send zero window size but before that please compare the spec with w5300.

I hope it will be helpful.

Thank you.

lawrence

Hi Lawrence,

Thank you for your reply. Can I show you two packet captures from Wireshark please? The first is the known problem: the window size reaches 0 at packet 251 and the server then pauses for 5 seconds. This what we would expect with the known w5300 problem.

No.     Time           Source                Destination           Protocol Length Info
    188 *REF*          192.168.1.66          192.168.1.64          FTP      60     Request: PASV
    189 0.000808000    192.168.1.64          192.168.1.66          FTP      104    Response: 227 Entering Passive Mode (192,168,1,64,239,171)
    190 0.000891000    192.168.1.66          192.168.1.64          TCP      60     22→21 [ACK] Seq=44 Ack=246 Win=8138 Len=0
    193 0.006190000    192.168.1.66          192.168.1.64          TCP      60     16962→61355 [SYN] Seq=0 Win=8190 Len=0 MSS=1460
    194 0.006428000    192.168.1.64          192.168.1.66          TCP      58     61355→16962 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1460
    195 0.006492000    192.168.1.66          192.168.1.64          TCP      60     16962→61355 [ACK] Seq=1 Ack=1 Win=8190 Len=0
    196 0.007544000    192.168.1.66          192.168.1.64          FTP      65     Request: RETR TEST
    197 0.009260000    192.168.1.64          192.168.1.66          FTP      121    Response: 150 Opening data channel for file download from server of "/TEST"
    198 0.009369000    192.168.1.66          192.168.1.64          TCP      60     22→21 [ACK] Seq=55 Ack=313 Win=8120 Len=0
    199 0.010023000    192.168.1.64          192.168.1.66          FTP-DATA 2974   FTP Data: 2920 bytes
    200 0.010332000    192.168.1.66          192.168.1.64          TCP      60     16962→61355 [ACK] Seq=1 Ack=1461 Win=6728 Len=0
    201 0.010365000    192.168.1.64          192.168.1.66          FTP-DATA 2974   FTP Data: 2920 bytes
    202 0.010487000    192.168.1.66          192.168.1.64          TCP      60     16962→61355 [ACK] Seq=1 Ack=2921 Win=5266 Len=0
    203 0.010523000    192.168.1.64          192.168.1.66          FTP-DATA 1514   FTP Data: 1460 bytes
    204 0.010698000    192.168.1.66          192.168.1.64          TCP      60     16962→61355 [ACK] Seq=1 Ack=4381 Win=3804 Len=0
    205 0.010893000    192.168.1.66          192.168.1.64          TCP      60     16962→61355 [ACK] Seq=1 Ack=5841 Win=2342 Len=0
    206 0.011005000    192.168.1.64          192.168.1.66          FTP      92     Response: 226 Successfully transferred "/TEST"
    207 0.011038000    192.168.1.66          192.168.1.64          TCP      60     16962→61355 [ACK] Seq=1 Ack=7301 Win=880 Len=0
    208 0.011100000    192.168.1.66          192.168.1.64          TCP      60     22→21 [ACK] Seq=55 Ack=351 Win=8150 Len=0
    251 5.005901000    192.168.1.64          192.168.1.66          FTP-DATA 934    [TCP Window Full] FTP Data: 880 bytes
    252 5.006148000    192.168.1.66          192.168.1.64          TCP      60     16962→61355 [ACK] Seq=1 Ack=8181 Win=7308 Len=0
    253 5.006215000    192.168.1.64          192.168.1.66          FTP-DATA 7354   FTP Data: 7300 bytes
    254 5.006559000    192.168.1.66          192.168.1.64          TCP      60     16962→61355 [ACK] Seq=1 Ack=9641 Win=5846 Len=0
    255 5.006764000    192.168.1.66          192.168.1.64          TCP      60     16962→61355 [ACK] Seq=1 Ack=11101 Win=4384 Len=0
    256 5.006973000    192.168.1.66          192.168.1.64          TCP      60     16962→61355 [ACK] Seq=1 Ack=12561 Win=2922 Len=0
    257 5.006975000    192.168.1.66          192.168.1.64          TCP      60     16962→61355 [ACK] Seq=1 Ack=14021 Win=1460 Len=0
    258 5.007174000    192.168.1.66          192.168.1.64          TCP      60     [TCP ZeroWindow] 16962→61355 [ACK] Seq=1 Ack=15481 Win=0 Len=0
    259 5.305846000    192.168.1.64          192.168.1.66          FTP-DATA 55     [TCP ZeroWindowProbe] FTP Data: 1 bytes
    260 5.305910000    192.168.1.66          192.168.1.64          TCP      60     [TCP ACKed unseen segment] 16962→61355 [ACK] Seq=1 Ack=15482 Win=8186 Len=0
    261 5.305929000    192.168.1.64          192.168.1.66          FTP-DATA 1698   [TCP Previous segment not captured] FTP Data: 1644 bytes
    262 5.306239000    192.168.1.66          192.168.1.64          TCP      60     [TCP ACKed unseen segment] 16962→61355 [ACK] Seq=1 Ack=16942 Win=6724 Len=0
    263 5.306441000    192.168.1.66          192.168.1.64          TCP      60     16962→61355 [ACK] Seq=1 Ack=17127 Win=6538 Len=0

The second capture is with a zero-length send at packet 73, sent when the receiver has no packets to read, and which Wireshark helpfully decodes as “TCP window update”! (And again at 82). This fixes the problem: there is no server pause.

No.     Time           Source                Destination           Protocol Length Info
     50 *REF*          192.168.1.66          192.168.1.64          FTP      60     Request: PASV
     51 0.000848000    192.168.1.64          192.168.1.66          FTP      104    Response: 227 Entering Passive Mode (192,168,1,64,198,254)
     52 0.000931000    192.168.1.66          192.168.1.64          TCP      60     22→21 [ACK] Seq=44 Ack=246 Win=8138 Len=0
     55 0.011771000    192.168.1.66          192.168.1.64          TCP      60     16962→50942 [SYN] Seq=0 Win=8190 Len=0 MSS=1460
     56 0.011891000    192.168.1.64          192.168.1.66          TCP      58     50942→16962 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1460
     57 0.011969000    192.168.1.66          192.168.1.64          TCP      60     16962→50942 [ACK] Seq=1 Ack=1 Win=8190 Len=0
     58 0.013054000    192.168.1.66          192.168.1.64          FTP      65     Request: RETR TEST
     59 0.013650000    192.168.1.64          192.168.1.66          FTP      121    Response: 150 Opening data channel for file download from server of "/TEST"
     60 0.013717000    192.168.1.66          192.168.1.64          TCP      60     22→21 [ACK] Seq=55 Ack=313 Win=8120 Len=0
     61 0.013967000    192.168.1.64          192.168.1.66          FTP-DATA 2974   FTP Data: 2920 bytes
     62 0.014271000    192.168.1.66          192.168.1.64          TCP      60     16962→50942 [ACK] Seq=1 Ack=1461 Win=6728 Len=0
     63 0.014304000    192.168.1.64          192.168.1.66          FTP-DATA 2974   FTP Data: 2920 bytes
     64 0.014436000    192.168.1.64          192.168.1.66          FTP      92     Response: 226 Successfully transferred "/TEST"
     65 0.014467000    192.168.1.66          192.168.1.64          TCP      60     16962→50942 [ACK] Seq=1 Ack=2921 Win=5266 Len=0
     66 0.014479000    192.168.1.64          192.168.1.66          FTP-DATA 1514   FTP Data: 1460 bytes
     67 0.014674000    192.168.1.66          192.168.1.64          TCP      60     16962→50942 [ACK] Seq=1 Ack=4381 Win=3804 Len=0
     68 0.014884000    192.168.1.66          192.168.1.64          TCP      60     16962→50942 [ACK] Seq=1 Ack=5841 Win=2342 Len=0
     69 0.014885000    192.168.1.66          192.168.1.64          TCP      60     22→21 [ACK] Seq=55 Ack=351 Win=8150 Len=0
     70 0.014886000    192.168.1.66          192.168.1.64          TCP      60     16962→50942 [ACK] Seq=1 Ack=7301 Win=880 Len=0
     73 0.295139000    192.168.1.66          192.168.1.64          TCP      60     [TCP Window Update] 16962→50942 [PSH, ACK] Seq=1 Ack=7301 Win=8190 Len=0
     74 0.295176000    192.168.1.64          192.168.1.66          FTP-DATA 7354   FTP Data: 7300 bytes
     75 0.295500000    192.168.1.66          192.168.1.64          TCP      60     16962→50942 [ACK] Seq=1 Ack=8761 Win=6728 Len=0
     76 0.295699000    192.168.1.66          192.168.1.64          TCP      60     16962→50942 [ACK] Seq=1 Ack=10221 Win=5266 Len=0
     77 0.295910000    192.168.1.66          192.168.1.64          TCP      60     16962→50942 [ACK] Seq=1 Ack=11681 Win=3804 Len=0
     78 0.295911000    192.168.1.66          192.168.1.64          TCP      60     16962→50942 [ACK] Seq=1 Ack=13141 Win=2342 Len=0
     79 0.296109000    192.168.1.66          192.168.1.64          TCP      60     16962→50942 [ACK] Seq=1 Ack=14601 Win=880 Len=0
     82 0.519700000    192.168.1.66          192.168.1.64          TCP      60     [TCP Window Update] 16962→50942 [PSH, ACK] Seq=1 Ack=14601 Win=8190 Len=0
     83 0.519755000    192.168.1.64          192.168.1.66          FTP-DATA 2579   FTP Data: 2525 bytes
     84 0.520099000    192.168.1.66          192.168.1.64          TCP      60     16962→50942 [ACK] Seq=1 Ack=16061 Win=6728 Len=0
     85 0.520288000    192.168.1.66          192.168.1.64          TCP      60     16962→50942 [ACK] Seq=1 Ack=17127 Win=5660 Len=0

(Please note there are two sockets active here: the data and the control. So ignore anything between ports 20 and 21 - these are the control socket packets),

So a zero length send fixes the problem in this situation. Looking at WIZnet’s socket.c, it looks like that was WIZnet’s first fix too, but then it was changed to a fix involving Keep Alives, and then changed again to actually sending one byte.

So my question is: what were the circumstances where WIZnet’s original zero-length-send fix did not work? It would be useful to know the details so that I know when my own zero-length send fix might not work.

I’m curious if this worked for you long-term? I tried sending zero-byte packets when Sn_RX_RSR reaches zero like in the code snippet, and this seems to work for a while. Eventually, though, sends stop working because the SENDOK flag never gets set.

It worked “well enough” for a while, not a high-traffic application, but long term…I designed a pin-compatible module using an ESP8266 and Xylinx CPLD that has 5V compatible i/o! It works properly, protocol code is stored in updatable FLASH, wifi, simpler host interface. Quicker to re-write your own code (and you always do it better the second time) than constantly tripping up on other people’s unfixed bugs and trying to work around them!