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
tcp/tcprecv.c@147:a6093b52e654, 2019-05-17 (annotated)
- Committer:
- andrewboyson
- Date:
- Fri May 17 15:01:32 2019 +0000
- Revision:
- 147:a6093b52e654
- Parent:
- 146:0fc66d610fd6
- Child:
- 156:be12b8fd5b21
Split HttpPollReply into HttpPoll and HttpReply to allow TSL to work
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 74:c3756bfa960e | 1 | #include <stdint.h> |
andrewboyson | 74:c3756bfa960e | 2 | #include <stdbool.h> |
andrewboyson | 75:603b10404183 | 3 | #include <stdarg.h> |
andrewboyson | 74:c3756bfa960e | 4 | |
andrewboyson | 74:c3756bfa960e | 5 | #include "log.h" |
andrewboyson | 74:c3756bfa960e | 6 | #include "net.h" |
andrewboyson | 74:c3756bfa960e | 7 | #include "action.h" |
andrewboyson | 74:c3756bfa960e | 8 | #include "tcp.h" |
andrewboyson | 74:c3756bfa960e | 9 | #include "tcphdr.h" |
andrewboyson | 74:c3756bfa960e | 10 | #include "tcpsend.h" |
andrewboyson | 74:c3756bfa960e | 11 | #include "tcb.h" |
andrewboyson | 74:c3756bfa960e | 12 | #include "ip4.h" |
andrewboyson | 74:c3756bfa960e | 13 | #include "dhcp.h" |
andrewboyson | 146:0fc66d610fd6 | 14 | #include "httpshim.h" |
andrewboyson | 74:c3756bfa960e | 15 | #include "led.h" |
andrewboyson | 93:580fc113d9e9 | 16 | #include "mstimer.h" |
andrewboyson | 142:a8c0890a58d1 | 17 | #include "restart.h" |
andrewboyson | 89:9b765a67699b | 18 | |
andrewboyson | 89:9b765a67699b | 19 | static void log(void (*traceback)(void), char* fmt, ...) |
andrewboyson | 74:c3756bfa960e | 20 | { |
andrewboyson | 78:9d8fc88df405 | 21 | if (TcpTrace) |
andrewboyson | 78:9d8fc88df405 | 22 | { |
andrewboyson | 78:9d8fc88df405 | 23 | if (NetTraceNewLine) Log("\r\n"); |
andrewboyson | 89:9b765a67699b | 24 | LogTimeF("TCP port %hu - ", TcpHdrSrcPort); |
andrewboyson | 75:603b10404183 | 25 | va_list argptr; |
andrewboyson | 75:603b10404183 | 26 | va_start(argptr, fmt); |
andrewboyson | 75:603b10404183 | 27 | LogV(fmt, argptr); |
andrewboyson | 75:603b10404183 | 28 | va_end(argptr); |
andrewboyson | 75:603b10404183 | 29 | Log("\r\n"); |
andrewboyson | 75:603b10404183 | 30 | if (NetTraceStack) traceback(); |
andrewboyson | 75:603b10404183 | 31 | } |
andrewboyson | 75:603b10404183 | 32 | } |
andrewboyson | 75:603b10404183 | 33 | |
andrewboyson | 88:1ba13e6062a3 | 34 | static void handleSyn(void *pPacket, int ipType, int remArIndex, int locMss, struct tcb* pTcb) |
andrewboyson | 74:c3756bfa960e | 35 | { |
andrewboyson | 74:c3756bfa960e | 36 | //Get the MSS to use for sends - it is the lower of the MSS advertised by the remote host and our local MSS |
andrewboyson | 74:c3756bfa960e | 37 | int remMss = TcpHdrMssGet(); |
andrewboyson | 74:c3756bfa960e | 38 | pTcb->remMss = remMss ? remMss : 536; //default MSS for IPv4 [576 - 20(TCP) - 20(IP)]; |
andrewboyson | 74:c3756bfa960e | 39 | if (pTcb->remMss > locMss) pTcb->remMss = locMss; |
andrewboyson | 74:c3756bfa960e | 40 | |
andrewboyson | 93:580fc113d9e9 | 41 | pTcb->timeSendsBeingAcked = MsTimerCount; |
andrewboyson | 82:20781198d26d | 42 | pTcb->countSendsNotAcked = 0; |
andrewboyson | 79:f50e02fb5c94 | 43 | pTcb->rcvdFin = false; |
andrewboyson | 79:f50e02fb5c94 | 44 | pTcb->sentFin = false; |
andrewboyson | 144:6bd5c54efc7d | 45 | pTcb->appStarted = false; |
andrewboyson | 144:6bd5c54efc7d | 46 | for (char* p = pTcb->appData; p < pTcb->appData + TCB_APP_STATE_BYTES; p++) *p = 0; |
andrewboyson | 147:a6093b52e654 | 47 | for (char* p = pTcb->tlsData; p < pTcb->tlsData + TCB_TLS_STATE_BYTES; p++) *p = 0; |
andrewboyson | 79:f50e02fb5c94 | 48 | pTcb->remIsn = TcpHdrSeqNum; |
andrewboyson | 79:f50e02fb5c94 | 49 | pTcb->locIsn = TcbGetIsn(); |
andrewboyson | 79:f50e02fb5c94 | 50 | pTcb->bytesRcvdFromRem = 0; |
andrewboyson | 79:f50e02fb5c94 | 51 | pTcb->bytesAckdByRem = 0; |
andrewboyson | 79:f50e02fb5c94 | 52 | pTcb->bytesAckdToRem = 0; |
andrewboyson | 79:f50e02fb5c94 | 53 | pTcb->bytesSentToRem = 0; |
andrewboyson | 74:c3756bfa960e | 54 | } |
andrewboyson | 88:1ba13e6062a3 | 55 | static void handleReceivedData(void* pPacket, int dataLength, uint32_t position, struct tcb* pTcb) |
andrewboyson | 74:c3756bfa960e | 56 | { |
andrewboyson | 74:c3756bfa960e | 57 | pTcb->window = TcpHdrWindow; |
andrewboyson | 74:c3756bfa960e | 58 | char* pData = (char*)pPacket + TcpHdrSizeGet(); |
andrewboyson | 74:c3756bfa960e | 59 | switch (pTcb->locPort) |
andrewboyson | 74:c3756bfa960e | 60 | { |
andrewboyson | 147:a6093b52e654 | 61 | case 80: HttpShimRequest(dataLength, pData, position, pTcb->appData, pTcb->tlsData, false); break; |
andrewboyson | 147:a6093b52e654 | 62 | case 443: HttpShimRequest(dataLength, pData, position, pTcb->appData, pTcb->tlsData, true ); break; |
andrewboyson | 147:a6093b52e654 | 63 | default: break; |
andrewboyson | 74:c3756bfa960e | 64 | } |
andrewboyson | 74:c3756bfa960e | 65 | } |
andrewboyson | 90:955f4c6e18a9 | 66 | static int sendResetFromPacket(int* pSizeTx, void* pPacketTx, int ipType, int remArIndex, int locIpScope, int seqLengthRcvd) |
andrewboyson | 89:9b765a67699b | 67 | { |
andrewboyson | 90:955f4c6e18a9 | 68 | /*RFC793 p36 If the connection does not exist (CLOSED) then a reset is sent |
andrewboyson | 90:955f4c6e18a9 | 69 | in response to any incoming segment except another reset. |
andrewboyson | 90:955f4c6e18a9 | 70 | If the incoming segment has an ACK field, the reset takes its sequence number from the ACK field of the segment, |
andrewboyson | 90:955f4c6e18a9 | 71 | otherwise the reset has sequence number zero |
andrewboyson | 90:955f4c6e18a9 | 72 | and |
andrewboyson | 90:955f4c6e18a9 | 73 | the ACK field is set to the sum of the sequence number and segment length of the incoming segment. |
andrewboyson | 90:955f4c6e18a9 | 74 | The connection remains in the CLOSED state. |
andrewboyson | 90:955f4c6e18a9 | 75 | In TcpSendReset TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn; //Set up the acknowledgement field ready to send |
andrewboyson | 90:955f4c6e18a9 | 76 | TcpHdrSeqNum = pTcb->bytesSentToRem + pTcb->locIsn; //Set up the start of the message before adding the bytes sent |
andrewboyson | 90:955f4c6e18a9 | 77 | */ |
andrewboyson | 90:955f4c6e18a9 | 78 | |
andrewboyson | 89:9b765a67699b | 79 | struct tcb tcb; |
andrewboyson | 89:9b765a67699b | 80 | struct tcb* pTcb = &tcb; |
andrewboyson | 93:580fc113d9e9 | 81 | pTcb->timeLastRcvd = MsTimerCount; |
andrewboyson | 89:9b765a67699b | 82 | pTcb->remArIndex = remArIndex; |
andrewboyson | 89:9b765a67699b | 83 | pTcb->ipType = ipType; |
andrewboyson | 89:9b765a67699b | 84 | pTcb->locIpScope = locIpScope; |
andrewboyson | 89:9b765a67699b | 85 | pTcb->remPort = TcpHdrSrcPort; |
andrewboyson | 89:9b765a67699b | 86 | pTcb->locPort = TcpHdrDstPort; |
andrewboyson | 89:9b765a67699b | 87 | pTcb->window = TcpHdrWindow; |
andrewboyson | 89:9b765a67699b | 88 | pTcb->state = TCB_EMPTY; |
andrewboyson | 89:9b765a67699b | 89 | |
andrewboyson | 93:580fc113d9e9 | 90 | pTcb->timeSendsBeingAcked = MsTimerCount; |
andrewboyson | 90:955f4c6e18a9 | 91 | pTcb->countSendsNotAcked = 0; |
andrewboyson | 90:955f4c6e18a9 | 92 | pTcb->rcvdFin = false; |
andrewboyson | 90:955f4c6e18a9 | 93 | pTcb->sentFin = false; |
andrewboyson | 144:6bd5c54efc7d | 94 | pTcb->appStarted = false; |
andrewboyson | 144:6bd5c54efc7d | 95 | for (char* p = pTcb->appData; p < pTcb->appData + TCB_APP_STATE_BYTES; p++) *p = 0; |
andrewboyson | 147:a6093b52e654 | 96 | for (char* p = pTcb->tlsData; p < pTcb->tlsData + TCB_TLS_STATE_BYTES; p++) *p = 0; |
andrewboyson | 90:955f4c6e18a9 | 97 | pTcb->remIsn = TcpHdrSeqNum + seqLengthRcvd; //Ack number |
andrewboyson | 90:955f4c6e18a9 | 98 | pTcb->locIsn = TcpHdrACK ? TcpHdrAckNum : 0; //Seq number |
andrewboyson | 90:955f4c6e18a9 | 99 | pTcb->bytesRcvdFromRem = 0; |
andrewboyson | 90:955f4c6e18a9 | 100 | pTcb->bytesAckdByRem = 0; |
andrewboyson | 90:955f4c6e18a9 | 101 | pTcb->bytesAckdToRem = 0; |
andrewboyson | 90:955f4c6e18a9 | 102 | pTcb->bytesSentToRem = 0; |
andrewboyson | 90:955f4c6e18a9 | 103 | |
andrewboyson | 89:9b765a67699b | 104 | return TcpSendReset(pSizeTx, pPacketTx, pTcb); |
andrewboyson | 89:9b765a67699b | 105 | } |
andrewboyson | 74:c3756bfa960e | 106 | |
andrewboyson | 80:4ef1500fca1d | 107 | int TcpHandleReceivedPacket(void (*traceback)(void), int sizeRx, void* pPacketRx, int* pSizeTx, void* pPacketTx, int ipType, int remArIndex, int locIpScope) |
andrewboyson | 74:c3756bfa960e | 108 | { |
andrewboyson | 142:a8c0890a58d1 | 109 | int lastRestartPoint = RestartPoint; |
andrewboyson | 142:a8c0890a58d1 | 110 | RestartPoint = FAULT_POINT_TcpHandleReceivedPacket; |
andrewboyson | 97:d91f7db00235 | 111 | |
andrewboyson | 90:955f4c6e18a9 | 112 | int action = DO_NOTHING; |
andrewboyson | 89:9b765a67699b | 113 | bool traceRequested = false; |
andrewboyson | 86:55bc5ddac16c | 114 | |
andrewboyson | 89:9b765a67699b | 115 | TcpHdrReadFromPacket(pPacketRx); |
andrewboyson | 89:9b765a67699b | 116 | |
andrewboyson | 78:9d8fc88df405 | 117 | if (remArIndex < 0) |
andrewboyson | 78:9d8fc88df405 | 118 | { |
andrewboyson | 89:9b765a67699b | 119 | log(traceback, "invalid remote AR index %d -> ignored packet", remArIndex); |
andrewboyson | 142:a8c0890a58d1 | 120 | RestartPoint = lastRestartPoint; |
andrewboyson | 78:9d8fc88df405 | 121 | return DO_NOTHING; |
andrewboyson | 78:9d8fc88df405 | 122 | } |
andrewboyson | 142:a8c0890a58d1 | 123 | RestartPoint += 100; |
andrewboyson | 78:9d8fc88df405 | 124 | |
andrewboyson | 74:c3756bfa960e | 125 | int dataLength = sizeRx - TcpHdrSizeGet(); |
andrewboyson | 74:c3756bfa960e | 126 | int locMss = *pSizeTx - TcpHdrSizeGet(); |
andrewboyson | 74:c3756bfa960e | 127 | |
andrewboyson | 90:955f4c6e18a9 | 128 | //Calculate the sequence length of the received packet |
andrewboyson | 90:955f4c6e18a9 | 129 | int seqLengthRcvd = 0; |
andrewboyson | 90:955f4c6e18a9 | 130 | if (TcpHdrSYN) seqLengthRcvd += 1; //Add one to acknowledge the SYN |
andrewboyson | 90:955f4c6e18a9 | 131 | seqLengthRcvd += dataLength; //Add the number of bytes received |
andrewboyson | 90:955f4c6e18a9 | 132 | if (TcpHdrFIN) seqLengthRcvd += 1; //Add one to acknowledge the FIN |
andrewboyson | 90:955f4c6e18a9 | 133 | |
andrewboyson | 74:c3756bfa960e | 134 | //Filter out unwanted links |
andrewboyson | 142:a8c0890a58d1 | 135 | RestartPoint++; |
andrewboyson | 74:c3756bfa960e | 136 | switch (TcpHdrDstPort) |
andrewboyson | 74:c3756bfa960e | 137 | { |
andrewboyson | 74:c3756bfa960e | 138 | case 80: |
andrewboyson | 146:0fc66d610fd6 | 139 | if (HttpShimGetTrace()) |
andrewboyson | 74:c3756bfa960e | 140 | { |
andrewboyson | 74:c3756bfa960e | 141 | if (NetTraceNewLine) Log("\r\n"); |
andrewboyson | 74:c3756bfa960e | 142 | LogTime("HTTP server request\r\n"); |
andrewboyson | 89:9b765a67699b | 143 | traceRequested = true; |
andrewboyson | 74:c3756bfa960e | 144 | } |
andrewboyson | 74:c3756bfa960e | 145 | break; |
andrewboyson | 74:c3756bfa960e | 146 | |
andrewboyson | 111:3600389d1add | 147 | case 443: |
andrewboyson | 146:0fc66d610fd6 | 148 | if (HttpShimGetTrace()) |
andrewboyson | 111:3600389d1add | 149 | { |
andrewboyson | 111:3600389d1add | 150 | if (NetTraceNewLine) Log("\r\n"); |
andrewboyson | 111:3600389d1add | 151 | LogTime("HTTPS server request\r\n"); |
andrewboyson | 111:3600389d1add | 152 | traceRequested = true; |
andrewboyson | 111:3600389d1add | 153 | } |
andrewboyson | 111:3600389d1add | 154 | break; |
andrewboyson | 111:3600389d1add | 155 | |
andrewboyson | 89:9b765a67699b | 156 | default: //Send reset if unknown port |
andrewboyson | 89:9b765a67699b | 157 | log(traceback, "unhandled local port %hu -> sent reset", TcpHdrDstPort); |
andrewboyson | 90:955f4c6e18a9 | 158 | action = sendResetFromPacket(pSizeTx, pPacketTx, ipType, remArIndex, locIpScope, seqLengthRcvd); |
andrewboyson | 142:a8c0890a58d1 | 159 | RestartPoint = lastRestartPoint; |
andrewboyson | 90:955f4c6e18a9 | 160 | return action; |
andrewboyson | 74:c3756bfa960e | 161 | } |
andrewboyson | 74:c3756bfa960e | 162 | |
andrewboyson | 76:17534bde28d3 | 163 | //Get the Transmission Control Block |
andrewboyson | 142:a8c0890a58d1 | 164 | RestartPoint++; |
andrewboyson | 88:1ba13e6062a3 | 165 | struct tcb* pTcb = TcbGetExisting(ipType, remArIndex, locIpScope, TcpHdrSrcPort, TcpHdrDstPort); |
andrewboyson | 76:17534bde28d3 | 166 | if (!pTcb) pTcb = TcbGetEmpty(); |
andrewboyson | 89:9b765a67699b | 167 | if (!pTcb) //send reset if no more tcbs are available |
andrewboyson | 76:17534bde28d3 | 168 | { |
andrewboyson | 89:9b765a67699b | 169 | log(traceback, "no more tcbs available -> sent reset"); |
andrewboyson | 90:955f4c6e18a9 | 170 | action = sendResetFromPacket(pSizeTx, pPacketTx, ipType, remArIndex, locIpScope, seqLengthRcvd); |
andrewboyson | 142:a8c0890a58d1 | 171 | RestartPoint = lastRestartPoint; |
andrewboyson | 90:955f4c6e18a9 | 172 | return action; |
andrewboyson | 76:17534bde28d3 | 173 | } |
andrewboyson | 93:580fc113d9e9 | 174 | pTcb->timeLastRcvd = MsTimerCount; |
andrewboyson | 76:17534bde28d3 | 175 | pTcb->remArIndex = remArIndex; |
andrewboyson | 76:17534bde28d3 | 176 | pTcb->ipType = ipType; |
andrewboyson | 81:50bfdd512f23 | 177 | pTcb->locIpScope = locIpScope; |
andrewboyson | 76:17534bde28d3 | 178 | pTcb->remPort = TcpHdrSrcPort; |
andrewboyson | 76:17534bde28d3 | 179 | pTcb->locPort = TcpHdrDstPort; |
andrewboyson | 76:17534bde28d3 | 180 | pTcb->window = TcpHdrWindow; |
andrewboyson | 75:603b10404183 | 181 | |
andrewboyson | 74:c3756bfa960e | 182 | //Handle request to reset |
andrewboyson | 142:a8c0890a58d1 | 183 | RestartPoint++; |
andrewboyson | 74:c3756bfa960e | 184 | if (TcpHdrRST) |
andrewboyson | 74:c3756bfa960e | 185 | { |
andrewboyson | 76:17534bde28d3 | 186 | if (pTcb->state) |
andrewboyson | 74:c3756bfa960e | 187 | { |
andrewboyson | 89:9b765a67699b | 188 | log(traceback, "received reset -> reaped TCB"); |
andrewboyson | 75:603b10404183 | 189 | pTcb->state = TCB_EMPTY; |
andrewboyson | 74:c3756bfa960e | 190 | } |
andrewboyson | 142:a8c0890a58d1 | 191 | RestartPoint = lastRestartPoint; |
andrewboyson | 74:c3756bfa960e | 192 | return DO_NOTHING; //Don't reply |
andrewboyson | 74:c3756bfa960e | 193 | } |
andrewboyson | 74:c3756bfa960e | 194 | |
andrewboyson | 74:c3756bfa960e | 195 | //Handle request to synchronise |
andrewboyson | 142:a8c0890a58d1 | 196 | RestartPoint++; |
andrewboyson | 74:c3756bfa960e | 197 | if (TcpHdrSYN) |
andrewboyson | 74:c3756bfa960e | 198 | { |
andrewboyson | 76:17534bde28d3 | 199 | if (pTcb->state) |
andrewboyson | 75:603b10404183 | 200 | { |
andrewboyson | 89:9b765a67699b | 201 | log(traceback, "received a SYN on an open connection -> sent reset"); |
andrewboyson | 75:603b10404183 | 202 | pTcb->state = TCB_EMPTY; |
andrewboyson | 90:955f4c6e18a9 | 203 | action = TcpSendReset(pSizeTx, pPacketTx, pTcb); |
andrewboyson | 142:a8c0890a58d1 | 204 | RestartPoint = lastRestartPoint; |
andrewboyson | 90:955f4c6e18a9 | 205 | return action; |
andrewboyson | 75:603b10404183 | 206 | } |
andrewboyson | 76:17534bde28d3 | 207 | else |
andrewboyson | 75:603b10404183 | 208 | { |
andrewboyson | 88:1ba13e6062a3 | 209 | handleSyn(pPacketRx, ipType, remArIndex, locMss, pTcb); |
andrewboyson | 75:603b10404183 | 210 | } |
andrewboyson | 74:c3756bfa960e | 211 | } |
andrewboyson | 74:c3756bfa960e | 212 | |
andrewboyson | 90:955f4c6e18a9 | 213 | //Handle non SYN packet on an empty connection |
andrewboyson | 142:a8c0890a58d1 | 214 | RestartPoint++; |
andrewboyson | 76:17534bde28d3 | 215 | if (!TcpHdrSYN && !pTcb->state) |
andrewboyson | 76:17534bde28d3 | 216 | { |
andrewboyson | 90:955f4c6e18a9 | 217 | |
andrewboyson | 89:9b765a67699b | 218 | log(traceback, "non SYN packet received on a closed connection -> sent reset"); |
andrewboyson | 78:9d8fc88df405 | 219 | pTcb->state = TCB_EMPTY; |
andrewboyson | 90:955f4c6e18a9 | 220 | action = sendResetFromPacket(pSizeTx, pPacketTx, ipType, remArIndex, locIpScope, seqLengthRcvd); |
andrewboyson | 142:a8c0890a58d1 | 221 | RestartPoint = lastRestartPoint; |
andrewboyson | 90:955f4c6e18a9 | 222 | return action; |
andrewboyson | 76:17534bde28d3 | 223 | } |
andrewboyson | 76:17534bde28d3 | 224 | |
andrewboyson | 79:f50e02fb5c94 | 225 | //Check if the acks of bytes sent has progressed and reset the timer |
andrewboyson | 142:a8c0890a58d1 | 226 | RestartPoint++; |
andrewboyson | 91:879545b19260 | 227 | uint32_t ackRcvdFromRem = TcpHdrACK ? TcpHdrAckNum - pTcb->locIsn : 0; |
andrewboyson | 82:20781198d26d | 228 | if (ackRcvdFromRem > pTcb->bytesAckdByRem) |
andrewboyson | 82:20781198d26d | 229 | { |
andrewboyson | 93:580fc113d9e9 | 230 | pTcb->timeSendsBeingAcked = MsTimerCount; |
andrewboyson | 82:20781198d26d | 231 | pTcb->countSendsNotAcked = 0; |
andrewboyson | 82:20781198d26d | 232 | } |
andrewboyson | 79:f50e02fb5c94 | 233 | |
andrewboyson | 79:f50e02fb5c94 | 234 | //Record the number of bytes acked by the remote host |
andrewboyson | 142:a8c0890a58d1 | 235 | RestartPoint++; |
andrewboyson | 79:f50e02fb5c94 | 236 | pTcb->bytesAckdByRem = ackRcvdFromRem; |
andrewboyson | 79:f50e02fb5c94 | 237 | |
andrewboyson | 76:17534bde28d3 | 238 | /* If the connection is in a synchronized state |
andrewboyson | 76:17534bde28d3 | 239 | any unacceptable segment (out of window sequence number or |
andrewboyson | 76:17534bde28d3 | 240 | unacceptible acknowledgment number) must elicit only an empty |
andrewboyson | 76:17534bde28d3 | 241 | acknowledgment segment containing the current send-sequence number |
andrewboyson | 76:17534bde28d3 | 242 | and an acknowledgment indicating the next sequence number expected |
andrewboyson | 76:17534bde28d3 | 243 | to be received, and the connection remains in the same state.*/ |
andrewboyson | 142:a8c0890a58d1 | 244 | RestartPoint++; |
andrewboyson | 74:c3756bfa960e | 245 | uint32_t seqRcvdFromRem = TcpHdrSeqNum - pTcb->remIsn; |
andrewboyson | 78:9d8fc88df405 | 246 | if (seqRcvdFromRem != pTcb->bytesAckdToRem) |
andrewboyson | 78:9d8fc88df405 | 247 | { |
andrewboyson | 79:f50e02fb5c94 | 248 | //Only warn non keep-alives |
andrewboyson | 79:f50e02fb5c94 | 249 | if (seqRcvdFromRem != 0 || pTcb->bytesAckdToRem != 1) |
andrewboyson | 79:f50e02fb5c94 | 250 | { |
andrewboyson | 89:9b765a67699b | 251 | log(traceback, "seq rcvd is %d and last seq ackd was %d -> resent last ACK", seqRcvdFromRem, pTcb->bytesAckdToRem); |
andrewboyson | 79:f50e02fb5c94 | 252 | } |
andrewboyson | 90:955f4c6e18a9 | 253 | action = TcpResendLastAck(pSizeTx, pPacketTx, pTcb); |
andrewboyson | 142:a8c0890a58d1 | 254 | RestartPoint = lastRestartPoint; |
andrewboyson | 90:955f4c6e18a9 | 255 | return action; |
andrewboyson | 78:9d8fc88df405 | 256 | } |
andrewboyson | 90:955f4c6e18a9 | 257 | //Ignore data before established |
andrewboyson | 142:a8c0890a58d1 | 258 | RestartPoint++; |
andrewboyson | 90:955f4c6e18a9 | 259 | if (pTcb->state != TCB_ESTABLISHED && dataLength) |
andrewboyson | 90:955f4c6e18a9 | 260 | { |
andrewboyson | 90:955f4c6e18a9 | 261 | log(traceback, "data received before connection established -> sent reset"); |
andrewboyson | 90:955f4c6e18a9 | 262 | pTcb->state = TCB_EMPTY; |
andrewboyson | 90:955f4c6e18a9 | 263 | action = TcpSendReset(pSizeTx, pPacketTx, pTcb); |
andrewboyson | 142:a8c0890a58d1 | 264 | RestartPoint = lastRestartPoint; |
andrewboyson | 90:955f4c6e18a9 | 265 | return action; |
andrewboyson | 90:955f4c6e18a9 | 266 | } |
andrewboyson | 90:955f4c6e18a9 | 267 | |
andrewboyson | 74:c3756bfa960e | 268 | //Handle FIN |
andrewboyson | 142:a8c0890a58d1 | 269 | RestartPoint++; |
andrewboyson | 74:c3756bfa960e | 270 | if (TcpHdrFIN) pTcb->rcvdFin = true; //When reply is all sent only a passive close is needed |
andrewboyson | 90:955f4c6e18a9 | 271 | |
andrewboyson | 90:955f4c6e18a9 | 272 | //From now on there are no errors so display traceback if requested |
andrewboyson | 142:a8c0890a58d1 | 273 | RestartPoint++; |
andrewboyson | 90:955f4c6e18a9 | 274 | if (traceRequested && NetTraceStack) traceback(); |
andrewboyson | 74:c3756bfa960e | 275 | |
andrewboyson | 75:603b10404183 | 276 | //Record the number of bytes received from the remote host |
andrewboyson | 142:a8c0890a58d1 | 277 | RestartPoint++; |
andrewboyson | 76:17534bde28d3 | 278 | pTcb->bytesRcvdFromRem += seqLengthRcvd; |
andrewboyson | 74:c3756bfa960e | 279 | |
andrewboyson | 76:17534bde28d3 | 280 | switch (pTcb->state) //This is the state of the connection BEFORE this packet arrived |
andrewboyson | 74:c3756bfa960e | 281 | { |
andrewboyson | 74:c3756bfa960e | 282 | case TCB_EMPTY: |
andrewboyson | 74:c3756bfa960e | 283 | pTcb->state = TCB_SYN_RECEIVED; |
andrewboyson | 74:c3756bfa960e | 284 | break; |
andrewboyson | 74:c3756bfa960e | 285 | |
andrewboyson | 74:c3756bfa960e | 286 | case TCB_SYN_RECEIVED: |
andrewboyson | 74:c3756bfa960e | 287 | pTcb->state = TCB_ESTABLISHED; |
andrewboyson | 74:c3756bfa960e | 288 | break; |
andrewboyson | 74:c3756bfa960e | 289 | |
andrewboyson | 74:c3756bfa960e | 290 | case TCB_ESTABLISHED: |
andrewboyson | 144:6bd5c54efc7d | 291 | if (dataLength) |
andrewboyson | 144:6bd5c54efc7d | 292 | { |
andrewboyson | 144:6bd5c54efc7d | 293 | handleReceivedData(pPacketRx, dataLength, seqRcvdFromRem - 1, pTcb); |
andrewboyson | 144:6bd5c54efc7d | 294 | pTcb->appStarted = true; |
andrewboyson | 144:6bd5c54efc7d | 295 | } |
andrewboyson | 74:c3756bfa960e | 296 | if (pTcb->sentFin) |
andrewboyson | 74:c3756bfa960e | 297 | { |
andrewboyson | 77:6cb7d92c37f3 | 298 | pTcb->state = pTcb->rcvdFin ? TCB_EMPTY : TCB_CLOSE_FIN_WAIT; |
andrewboyson | 74:c3756bfa960e | 299 | } |
andrewboyson | 74:c3756bfa960e | 300 | break; |
andrewboyson | 74:c3756bfa960e | 301 | |
andrewboyson | 74:c3756bfa960e | 302 | case TCB_CLOSE_FIN_WAIT: //End of active close |
andrewboyson | 74:c3756bfa960e | 303 | if (TcpHdrFIN) |
andrewboyson | 74:c3756bfa960e | 304 | { |
andrewboyson | 74:c3756bfa960e | 305 | pTcb->state = TCB_EMPTY;//Ignore ACK to our FIN. Wait for FIN then close. |
andrewboyson | 74:c3756bfa960e | 306 | } |
andrewboyson | 74:c3756bfa960e | 307 | break; |
andrewboyson | 74:c3756bfa960e | 308 | |
andrewboyson | 74:c3756bfa960e | 309 | } |
andrewboyson | 74:c3756bfa960e | 310 | |
andrewboyson | 142:a8c0890a58d1 | 311 | RestartPoint++; |
andrewboyson | 90:955f4c6e18a9 | 312 | action = TcpSend(pSizeTx, pPacketTx, pTcb); |
andrewboyson | 86:55bc5ddac16c | 313 | |
andrewboyson | 142:a8c0890a58d1 | 314 | RestartPoint = lastRestartPoint; |
andrewboyson | 90:955f4c6e18a9 | 315 | return action; |
andrewboyson | 74:c3756bfa960e | 316 | } |