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
Diff: tcp/tcprecv.c
- 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); }