A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.

Dependents:   oldheating gps motorhome heating

Revision:
79:f50e02fb5c94
Parent:
78:9d8fc88df405
Child:
80:4ef1500fca1d
--- a/tcp/tcprecv.c	Mon Nov 05 19:27:19 2018 +0000
+++ b/tcp/tcprecv.c	Sun Nov 11 15:44:23 2018 +0000
@@ -22,9 +22,9 @@
     if (TcpTrace)
     {
         if (NetTraceNewLine) Log("\r\n");
+        LogTime("TCP sent RST - ");
         va_list argptr;
         va_start(argptr, fmt);
-        LogTime("TCP sent RST - ");
         LogV(fmt, argptr);
         Log("\r\n");
         va_end(argptr);
@@ -45,23 +45,23 @@
     }
 }
 
-static void startConnection(void *pPacket, int ipType, int remArIndex, int locMss)
+static void handleSyn(void *pPacket, int ipType, int remArIndex, int locMss)
 {
     //Get the MSS to use for sends - it is the lower of the MSS advertised by the remote host and our local MSS
     int remMss = TcpHdrMssGet();
     pTcb->remMss = remMss ? remMss : 536; //default MSS for IPv4 [576 - 20(TCP) - 20(IP)];
     if (pTcb->remMss > locMss) pTcb->remMss = locMss;
     
-    pTcb->lastSendTime     = TcbElapsed;
-    pTcb->rcvdFin          = false;
-    pTcb->sentFin          = false;
-    pTcb->todo             = 0;
-    pTcb->remIsn           = TcpHdrSeqNum;
-    pTcb->locIsn           = TcbGetIsn();
-    pTcb->bytesRcvdFromRem = 0;
-    pTcb->bytesAckdByRem   = 0;
-    pTcb->bytesAckdToRem   = 0;
-    pTcb->bytesSentToRem   = 0;
+    pTcb->timeSendsBeingAcked = TcbElapsed;
+    pTcb->rcvdFin             = false;
+    pTcb->sentFin             = false;
+    pTcb->todo                = 0;
+    pTcb->remIsn              = TcpHdrSeqNum;
+    pTcb->locIsn              = TcbGetIsn();
+    pTcb->bytesRcvdFromRem    = 0;
+    pTcb->bytesAckdByRem      = 0;
+    pTcb->bytesAckdToRem      = 0;
+    pTcb->bytesSentToRem      = 0;
 }
 static void handleReceivedData(void* pPacket, int dataLength, uint32_t position)
 {
@@ -105,7 +105,7 @@
             break;
             
         default:
-            logTraceBack(traceback, "TCP - unknown port %d\r\n", TcpHdrDstPort);
+            logTraceBack(traceback, "TCP - unknown port %d", TcpHdrDstPort);
             return DO_NOTHING; //Ignore unknown ports
     }
     
@@ -114,9 +114,10 @@
     if (!pTcb) pTcb = TcbGetEmpty();
     if (!pTcb) //Bomb out if no more tcbs are available
     {
-        logTraceBack(traceback, "TCP - no more tcbs are available\r\n");
+        logTraceBack(traceback, "TCP - no more tcbs are available");
         return DO_NOTHING;
     }
+    pTcb->timeLastRcvd     = TcbElapsed;
     pTcb->remArIndex       = remArIndex;
     pTcb->ipType           = ipType;
     pTcb->remPort          = TcpHdrSrcPort;
@@ -128,7 +129,7 @@
     {
         if (pTcb->state)
         {
-            logTraceBack(traceback, "TCP - received reset - resetting TCB\r\n");
+            logTraceBack(traceback, "TCP - received reset - resetting TCB");
             pTcb->state = TCB_EMPTY;
         }
         return DO_NOTHING;        //Don't reply
@@ -145,7 +146,7 @@
         }
         else
         {
-            startConnection(pPacketRx, ipType, remArIndex, locMss);
+            handleSyn(pPacketRx, ipType, remArIndex, locMss);
         }
     }
     
@@ -179,6 +180,13 @@
         return TcpSendReset(pSizeTx, pPacketTx, pTcb);
     }
     
+    //Check if the acks of bytes sent has progressed and reset the timer
+    uint32_t ackRcvdFromRem = TcpHdrAckNum - pTcb->locIsn;
+    if (ackRcvdFromRem > pTcb->bytesAckdByRem) pTcb->timeSendsBeingAcked = TcbElapsed;
+
+    //Record the number of bytes acked by the remote host
+    pTcb->bytesAckdByRem = ackRcvdFromRem;
+
     /* If the connection is in a synchronized state
     any unacceptable segment (out of window sequence number or
     unacceptible acknowledgment number) must elicit only an empty
@@ -188,13 +196,14 @@
     uint32_t seqRcvdFromRem = TcpHdrSeqNum - pTcb->remIsn;
     if (seqRcvdFromRem != pTcb->bytesAckdToRem)
     {
-        logTraceBack(traceback, "TCP - resending last ACK on port %d as seq rcvd is %d and seq last was %d\r\n", TcpHdrSrcPort, seqRcvdFromRem, pTcb->bytesAckdToRem);
+        //Only warn non keep-alives
+        if (seqRcvdFromRem != 0 || pTcb->bytesAckdToRem != 1)
+        {
+            logTraceBack(traceback, "TCP - resending last ACK on port %d as seq rcvd is %d and last seq ackd was %d", TcpHdrSrcPort, seqRcvdFromRem, pTcb->bytesAckdToRem);
+        }
         return TcpResendLastAck(pSizeTx, pPacketTx, pTcb);
     }
     
-    //Record the number of bytes acked by the remote host
-    pTcb->bytesAckdByRem = TcpHdrAckNum - pTcb->locIsn;
-    
     //Handle FIN
     if (TcpHdrFIN) pTcb->rcvdFin = true; //When reply is all sent only a passive close is needed
         
@@ -223,7 +232,6 @@
             if (dataLength) handleReceivedData (pPacketRx, dataLength, seqRcvdFromRem - 1);
             if (pTcb->sentFin)
             {
-                //pTcb->state = pTcb->rcvdFin ? TCB_CLOSE_ACK_WAIT : TCB_CLOSE_FIN_WAIT;
                 pTcb->state = pTcb->rcvdFin ? TCB_EMPTY : TCB_CLOSE_FIN_WAIT;
             }
             break;
@@ -235,9 +243,6 @@
             }
             break;
             
-        case TCB_CLOSE_ACK_WAIT: //End of passive close
-            pTcb->state = TCB_EMPTY;
-            break;
     }
     
     return TcpSend(pSizeTx, pPacketTx, pTcb);