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:
89:9b765a67699b
Parent:
88:1ba13e6062a3
Child:
90:955f4c6e18a9
--- a/tcp/tcprecv.c	Tue Nov 20 17:21:38 2018 +0000
+++ b/tcp/tcprecv.c	Wed Nov 21 17:13:04 2018 +0000
@@ -14,25 +14,13 @@
 #include    "http.h"
 #include     "led.h"
 
-static void logReset(char* fmt, ...)
+
+static void log(void (*traceback)(void), char* fmt, ...)
 {
     if (TcpTrace)
     {
         if (NetTraceNewLine) Log("\r\n");
-        LogTime("TCP sent RST - ");
-        va_list argptr;
-        va_start(argptr, fmt);
-        LogV(fmt, argptr);
-        Log("\r\n");
-        va_end(argptr);
-    }
-}
-
-static void logTraceBack(void (*traceback)(void), char* fmt, ...)
-{
-    if (TcpTrace)
-    {
-        if (NetTraceNewLine) Log("\r\n");
+        LogTimeF("TCP port %hu - ", TcpHdrSrcPort);
         va_list argptr;
         va_start(argptr, fmt);
         LogV(fmt, argptr);
@@ -74,22 +62,38 @@
             break;
     }
 }
+static int sendResetFromPacket(int* pSizeTx, void* pPacketTx, int ipType, int remArIndex, int locIpScope)
+{
+    struct tcb tcb;
+    struct tcb* pTcb = &tcb;
+    pTcb->timeLastRcvd     = TcbElapsed;
+    pTcb->remArIndex       = remArIndex;
+    pTcb->ipType           = ipType;
+    pTcb->locIpScope       = locIpScope;
+    pTcb->remPort          = TcpHdrSrcPort;
+    pTcb->locPort          = TcpHdrDstPort;
+    pTcb->window           = TcpHdrWindow;
+    pTcb->state            = TCB_EMPTY;
+
+    return TcpSendReset(pSizeTx, pPacketTx, pTcb);
+}
 
 int TcpHandleReceivedPacket(void (*traceback)(void), int sizeRx, void* pPacketRx, int* pSizeTx, void* pPacketTx, int ipType, int remArIndex, int locIpScope)
 {
-    int action = DO_NOTHING;
-    bool doTrace = false;
+    int dest = DO_NOTHING;
+    bool traceRequested = false;
     
     Led1Set(true);
+    
+    TcpHdrReadFromPacket(pPacketRx);
+    
     if (remArIndex < 0)
     {
-        LogTimeF("Invalid remote AR index %d", remArIndex);
+        log(traceback, "invalid remote AR index %d -> ignored packet", remArIndex);
         Led1Set(false);
         return DO_NOTHING;
     }
     
-    TcpHdrReadFromPacket(pPacketRx);
-    
     int dataLength =   sizeRx - TcpHdrSizeGet();
     int locMss     = *pSizeTx - TcpHdrSizeGet();
     
@@ -101,24 +105,26 @@
             {
                 if (NetTraceNewLine) Log("\r\n");
                 LogTime("HTTP server request\r\n");
-                doTrace = true;
+                traceRequested = true;
             }
             break;
             
-        default:
-            logTraceBack(traceback, "TCP - unknown port %d", TcpHdrDstPort);
+        default: //Send reset if unknown port
+            log(traceback, "unhandled local port %hu -> sent reset", TcpHdrDstPort);
+            dest = sendResetFromPacket(pSizeTx, pPacketTx, ipType, remArIndex, locIpScope);
             Led1Set(false);
-            return DO_NOTHING; //Ignore unknown ports
+            return ActionMakeFromDestAndTrace(dest, traceRequested && NetTraceStack);
     }
     
     //Get the Transmission Control Block
     struct tcb* pTcb = TcbGetExisting(ipType, remArIndex, locIpScope, TcpHdrSrcPort, TcpHdrDstPort);
     if (!pTcb) pTcb = TcbGetEmpty();
-    if (!pTcb) //Bomb out if no more tcbs are available
+    if (!pTcb) //send reset if no more tcbs are available
     {
-        logTraceBack(traceback, "TCP - no more tcbs are available");
+        log(traceback, "no more tcbs available -> sent reset");
+        dest = sendResetFromPacket(pSizeTx, pPacketTx, ipType, remArIndex, locIpScope);
         Led1Set(false);
-        return DO_NOTHING;
+        return ActionMakeFromDestAndTrace(dest, traceRequested && NetTraceStack);
     }
     pTcb->timeLastRcvd     = TcbElapsed;
     pTcb->remArIndex       = remArIndex;
@@ -133,7 +139,7 @@
     {
         if (pTcb->state)
         {
-            logTraceBack(traceback, "TCP - received reset - resetting TCB");
+            log(traceback, "received reset -> reaped TCB");
             pTcb->state = TCB_EMPTY;
         }
         Led1Set(false);
@@ -145,11 +151,11 @@
     {
         if (pTcb->state)
         {
-            logReset("received a SYN on port %d when connection open", TcpHdrSrcPort);
+            log(traceback, "received a SYN on an open connection -> sent reset");
             pTcb->state = TCB_EMPTY;
-            action = TcpSendReset(pSizeTx, pPacketTx, pTcb);
+            dest = TcpSendReset(pSizeTx, pPacketTx, pTcb);
             Led1Set(false);
-            return action;
+            ActionMakeFromDestAndTrace(dest, traceRequested && NetTraceStack);
         }
         else
         {
@@ -182,11 +188,11 @@
         
         pTcb->bytesSentToRem   = TcpHdrACK ? TcpHdrAckNum : 0; //Seq number
         pTcb->bytesAckdToRem   = TcpHdrSeqNum + seqLengthRcvd; //Ack number
-        logReset("non SYN packet received on a closed connection");
+        log(traceback, "non SYN packet received on a closed connection -> sent reset");
         pTcb->state = TCB_EMPTY;
-        action = TcpSendReset(pSizeTx, pPacketTx, pTcb);
+        dest = TcpSendReset(pSizeTx, pPacketTx, pTcb);
         Led1Set(false);
-        return action;
+        return ActionMakeFromDestAndTrace(dest, traceRequested && NetTraceStack);
     }
     
     //Check if the acks of bytes sent has progressed and reset the timer
@@ -212,17 +218,17 @@
         //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);
+            log(traceback, "seq rcvd is %d and last seq ackd was %d -> resent last ACK", seqRcvdFromRem, pTcb->bytesAckdToRem);
         }
-        action = TcpResendLastAck(pSizeTx, pPacketTx, pTcb);
+        dest = TcpResendLastAck(pSizeTx, pPacketTx, pTcb);
         Led1Set(false);
-        return action;
+        return ActionMakeFromDestAndTrace(dest, traceRequested && NetTraceStack);
     }
     Led2Set(true);
     //Handle FIN
     if (TcpHdrFIN) pTcb->rcvdFin = true; //When reply is all sent only a passive close is needed
         
-    if (doTrace && NetTraceStack) traceback(); //This will already include the TCP header
+    if (traceRequested && NetTraceStack) traceback(); //This will already include the TCP header
     
     //Record the number of bytes received from the remote host
     pTcb->bytesRcvdFromRem += seqLengthRcvd;
@@ -236,12 +242,12 @@
         case TCB_SYN_RECEIVED:
             if (dataLength)
             {
-                logReset("data received before connection established");
+                log(traceback, "data received before connection established -> sent reset");
                 pTcb->state = TCB_EMPTY;
-                action = TcpSendReset(pSizeTx, pPacketTx, pTcb);
+                dest = TcpSendReset(pSizeTx, pPacketTx, pTcb);
                 Led1Set(false);
                 Led2Set(false);
-                return action;
+                return ActionMakeFromDestAndTrace(dest, traceRequested && NetTraceStack);
             }
             pTcb->state = TCB_ESTABLISHED;
             break;
@@ -263,9 +269,9 @@
             
     }
     
-    action = TcpSend(pSizeTx, pPacketTx, pTcb);
+    dest = TcpSend(pSizeTx, pPacketTx, pTcb);
     Led1Set(false);
     Led2Set(false);
 
-    return action;
+    return ActionMakeFromDestAndTrace(dest, traceRequested && NetTraceStack);
 }