embOS/IP's support for TCP window scaling is incomplete and I think there may be a bug in the code that prevents proper support.
Window scaling allows a host to specify receive/send windows that are larger than 65535 bytes by specifying an optional scaling factor during the connection (SYN) phase. This is useful in cases where the receiver has a lot of memory (say a PC) and the sender has a lot of data to send quickly. Of course, the sender needs a fair amount of memory too in order to hold the TCP packets that are waiting for ACKs. However, many of today's MCUs have external memory controllers that can access many megabytes of RAM (e.g., NXP LPC246).
According to pages 864 - 866 of "TCP/IP Illustrated - Volume 2: The Implementation" by Wright & Stevens, a client (connecting) host can request window scaling by specifying a 3-byte option in the TCP options portion of the header. In order for the option to be accepted, however, the server host must respond with the window scaling option in its SYN packet. embOS/IP includes some fo the code necessary for supporting this capability, but it's incomplete. The changes I believe are necessary (there may be more) to get embOS/IP to respond properly are
1) IP_socket.c, sosetopt() function
Add an additional SO_WINSCALE case to the switch statement (line 16). Also, after creating a socket, your code must call setsockopt( sock, SOL_SOCKET, SO_WINSCALE, NULL, 0 ); to enable window scaling support.
Display All
2) IP_TCP_in.c, _HandleOptions() function
Fix what I think is a bug by changing this (line 6)
Display All
to this (line 6)
Display All
3) If window scaling is going to be supported generally, then the SO_WINSCALE option should be documented in the user manual.
I have tested changes (1) & (2) with a Windows XP PC as a client requesting 8x window scaling and observed the results in WireShark. The window scaling options do appear in the SYN packets as expected. Also, using a debugger, I have observed that the embOS/IP TCP control block field "snd_wnd" is expanded by the scaling factor as requested by the PC. Further testing, however, is required to ensure that TCP packets are sent, ACKed and disposed of properly.
Window scaling allows a host to specify receive/send windows that are larger than 65535 bytes by specifying an optional scaling factor during the connection (SYN) phase. This is useful in cases where the receiver has a lot of memory (say a PC) and the sender has a lot of data to send quickly. Of course, the sender needs a fair amount of memory too in order to hold the TCP packets that are waiting for ACKs. However, many of today's MCUs have external memory controllers that can access many megabytes of RAM (e.g., NXP LPC246).
According to pages 864 - 866 of "TCP/IP Illustrated - Volume 2: The Implementation" by Wright & Stevens, a client (connecting) host can request window scaling by specifying a 3-byte option in the TCP options portion of the header. In order for the option to be accepted, however, the server host must respond with the window scaling option in its SYN packet. embOS/IP includes some fo the code necessary for supporting this capability, but it's incomplete. The changes I believe are necessary (there may be more) to get embOS/IP to respond properly are
1) IP_socket.c, sosetopt() function
Add an additional SO_WINSCALE case to the switch statement (line 16). Also, after creating a socket, your code must call setsockopt( sock, SOL_SOCKET, SO_WINSCALE, NULL, 0 ); to enable window scaling support.
C Source Code
- switch (optname) {
- case SO_LINGER:
- so->so_linger = (short) ((struct linger *)arg)->l_linger;
- arg = &((struct linger *)arg)->l_onoff;
- // Fall through
- case SO_KEEPALIVE:
- case SO_DONTROUTE:
- case SO_BROADCAST:
- case SO_REUSEADDR:
- case SO_OOBINLINE:
- case SO_TCPSACK:
- case SO_NOSLOWSTART:
- #ifdef SUPPORT_SO_FULLMSS
- case SO_FULLMSS:
- #endif
- case SO_WINSCALE:
- if (*(int *)arg) {
- so->so_options |= optname;
- } else {
- so->so_options &= ~optname;
- }
- break;
2) IP_TCP_in.c, _HandleOptions() function
Fix what I think is a bug by changing this (line 6)
C Source Code
to this (line 6)
C Source Code
3) If window scaling is going to be supported generally, then the SO_WINSCALE option should be documented in the user manual.
I have tested changes (1) & (2) with a Windows XP PC as a client requesting 8x window scaling and observed the results in WireShark. The window scaling options do appear in the SYN packets as expected. Also, using a debugger, I have observed that the embOS/IP TCP control block field "snd_wnd" is expanded by the scaling factor as requested by the PC. Further testing, however, is required to ensure that TCP packets are sent, ACKed and disposed of properly.