Interniche, MCF52235, lots of ACK's and window size zero

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Interniche, MCF52235, lots of ACK's and window size zero

3,016 Views
Petter_fupp
Contributor I
I have been struggeling with the Interniche TCP/IP stack on the MCF52235 (GNU compiler, superloop mode). In frustration, I post a lot of details in hope for solutions. Has anyone fixed similar stuff in the stack code? Any help or suggestions would be greatly appreciated.

Observations from network traffic:
- There seems to be a lot of ACK's in here.
- Window size ends up equal to zero when we are in a big pile of sh...

A few of my constants, in case they matter:
NUMBIGBUFS = 4
NUMLILBUFS = 6
NUM_RXBDS = 2
NUM_TXBDS = 2
bigbufsiz = 1536
lilbufsiz = 120
TCP_MSS = 1456
MAX_ETH_PKT = 1520

Some information about "my network":
IP 10.10.12.245 is a PC.
IP 10.10.12.252 is a server with Interniche stack
IP 10.10.12.254 is a client with Interniche stack
IP 10.10.12.248 is a gdb box for debugging (connected to the server in these dumps)

Wireshark dumps:

servpwrup-pc-clipwrup.txt
-------------------------
[Powered up server]
Frame 1-4: The server is powered up
Frame 5: UDP broadcast message from server (identifying itself to the network)
[Started a connection from the PC to the server]
Frame 6-7: ARP request and response
Frame 8-11: Connect from PC to server
Frame 12-14: A hello world message from server to PC
[Typed a command on the PC]
Frame 16-20: The command from PC to server
Frame 21-23: The reply from server to PC
[Closed the connection on the PC]
Frame 24-27: Disconnect
[Powered up client]
Frame 28-29: ARP request and response
Frame 30-33: Connect from client to server
Frame 34-38: A hello world message from server to client
Frame 39: UDP broadcast message from client (identifying itself to the network)
Frame 40-42: ping from client to server
Frame 43-49: pong (reply to ping) from server to client
Frame 50-53: ping from client to server
Frame 54-59: pong (reply to ping) from server to client
[the client will continue to send ping periodically]

window-zero.txt
---------------
[Client and server doing ping-pong]
[PC connected to server]
[PC connected to client]
Frame 219-236: ping-pong
[Button pressed on client, resulting in data transfer]
Frame 237-261: Data from all over the place
Frame 262-263: Info from gdb box to PC telling me the server watchdog kicked

A few of the interesting frames:
237: Command from client to server
238: Status from client to PC
242: ?? (where did this come from? did the stack make it?)
243: First frame with window size = 0

window-zero-no-wd.txt
---------------------
Similar to window-zero.txt, but with watchdog disabled:
[Client-server doing ping-pong and PC connected to both]
[Button pressed before frame 36]
[Client window size 0 in frame 42, seems to be fixed with TCP window update]
[Server window size 0 from frame 50 to end of file]
Labels (1)
0 Kudos
3 Replies

458 Views
Petter_fupp
Contributor I
Here is some details on half of our solution to window size equal to zero, and more related questions:

Closed sockects seems to not always clean up buffers. This seems to appear only when Interniche units are talking to each other (not when a PC is talking to a Interniche unit).

Observation:
- tcpcb->t_state TCPS_FIN_WAIT_2
- PACKET->inuse true
- Data in PACKET: received from other end
- M_SOCK->state bit SS_NOFDREF set

In the above condition, buffers may be not released properly. Buffers can be locking up the system like this, and after a while the unit can become uncapable of replying even ARP requests.

Could this be "fixed" by setting SS_CANTRCVMORE somewhere? Our (temporary?) fix for this problem is to set M_SOCK->linger equal to zero (by calling the m_ioctl() function).

I'm asking because debugging the function tcp_rcv() seems a bit complex. More specifically, I'm wandering if something can be improved. Possibly close to these lines:

Code:
   /*    * If the state is CLOSED (i.e., TCB does not exist) then    * all data in the incoming segment is discarded.    * If the TCB exists but is in CLOSED state, it is embryonic,    * but should either do a listen or a connect soon.    */   tp = so->tp;   if (tp == NULL)      GOTO_DROPWITHRESET;   if (tp->t_state == TCPS_CLOSED)      GOTO_DROP;

Any help, feedback or point-of-views would be appreciated.

Cheers,
Petter
0 Kudos

458 Views
Petter_fupp
Contributor I
Here are some more details which seems to remove duplicate ack and window size zero problems. If anyone has better or other solutions, please tell us here.

Initialise two variables e.g somewhere close after init of bigbufsiz (if you want to avoid window update ack's all the time):
Code:
mt_defrxwin = bigbufsiz * (NUMBIGBUFS-NUM_RXBDS-1);mt_deftxwin = mt_defrxwin;

To send even less ACK packets, enable delayed ACK's (add "#define DO_DELAY_ACKS 1" in e.g. ipport.h) and fix the resulting compile error. To make this work, make sure processing of incoming packets completes and puts output packets back into the stack (at least most of the time) before calling tcp_fasttimo().

Cheers,
Petter


Message Edited by Petter_ on 2007-09-11 06:32 PM
0 Kudos

458 Views
Petter_fupp
Contributor I
Here is a suggestion on how to delay the call of the tcp_fasttimo() function (added stuff in red):
Code:
unsigned long nextslow = 0L;     /* next slow tcp timer time */
#ifdef DO_DELAY_ACKS
unsigned long nextfast = 0L;     /* next fast tcp timer time */
#endif
static int in_tcptick = 0;       /* reentry gaurd */

void
tcp_tick()
{
   /* guard against re-entry */
   if (in_tcptick)
      return;
   in_tcptick++;

   LOCK_NET_RESOURCE(NET_RESID);

   if (cticks >= nextslow) /* time to do it again */
   {
      tcp_slowtimo();      /* call routine in BSD tcp_timr.c */
      nextslow = cticks + (TPS/2);  /* another 500 ms */
   }

#ifdef DO_DELAY_ACKS
   if (cticks >= nextfast) /* time to do it again */
   {
      tcp_fasttimo();
      nextfast = cticks + 2;
   }
#endif   /* DO_DELAY_ACKS */

   UNLOCK_NET_RESOURCE(NET_RESID);

   in_tcptick--;
}


Message Edited by Petter_ on 2007-09-13 03:43 PM
0 Kudos