Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
tcp/tcpsend.c@164:84b20bcd0941, 2020-03-31 (annotated)
- Committer:
- andrewboyson
- Date:
- Tue Mar 31 10:52:21 2020 +0000
- Revision:
- 164:84b20bcd0941
- Parent:
- 163:f063e374cf2a
- Child:
- 165:29a9e5f2eaef
Corrected a bug whereby a TCP connection which was closed by the client (FIN) without ever being used was not closed (FIN) and so the client would keep it alive until we ran out of TCP connections.
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 | 90:955f4c6e18a9 | 3 | #include <stdarg.h> |
| andrewboyson | 74:c3756bfa960e | 4 | |
| andrewboyson | 93:580fc113d9e9 | 5 | #include "log.h" |
| andrewboyson | 93:580fc113d9e9 | 6 | #include "net.h" |
| andrewboyson | 93:580fc113d9e9 | 7 | #include "action.h" |
| andrewboyson | 93:580fc113d9e9 | 8 | #include "tcp.h" |
| andrewboyson | 93:580fc113d9e9 | 9 | #include "tcphdr.h" |
| andrewboyson | 93:580fc113d9e9 | 10 | #include "tcb.h" |
| andrewboyson | 93:580fc113d9e9 | 11 | #include "ip4.h" |
| andrewboyson | 93:580fc113d9e9 | 12 | #include "dhcp.h" |
| andrewboyson | 159:3ebef2d02f7f | 13 | #include "http.h" |
| andrewboyson | 159:3ebef2d02f7f | 14 | #include "https.h" |
| andrewboyson | 93:580fc113d9e9 | 15 | #include "led.h" |
| andrewboyson | 74:c3756bfa960e | 16 | #include "tcpsend.h" |
| andrewboyson | 93:580fc113d9e9 | 17 | #include "mstimer.h" |
| andrewboyson | 74:c3756bfa960e | 18 | |
| andrewboyson | 120:05b6d67a0cec | 19 | #define TIMEOUT_RETRANSMISSION_MS 700 |
| andrewboyson | 120:05b6d67a0cec | 20 | #define MAX_RETRANSMISSIONS 5 |
| andrewboyson | 120:05b6d67a0cec | 21 | #define TIMEOUT_BROKEN_LINK_MS 600000 |
| andrewboyson | 74:c3756bfa960e | 22 | |
| andrewboyson | 164:84b20bcd0941 | 23 | |
| andrewboyson | 164:84b20bcd0941 | 24 | static void led(int number) |
| andrewboyson | 164:84b20bcd0941 | 25 | { |
| andrewboyson | 164:84b20bcd0941 | 26 | switch (number) |
| andrewboyson | 164:84b20bcd0941 | 27 | { |
| andrewboyson | 164:84b20bcd0941 | 28 | case 0: Led1Set(0); Led2Set(0); Led3Set(0); break; |
| andrewboyson | 164:84b20bcd0941 | 29 | case 1: Led1Set(1); Led2Set(0); Led3Set(0); break; |
| andrewboyson | 164:84b20bcd0941 | 30 | case 2: Led1Set(0); Led2Set(1); Led3Set(0); break; |
| andrewboyson | 164:84b20bcd0941 | 31 | case 3: Led1Set(1); Led2Set(1); Led3Set(0); break; |
| andrewboyson | 164:84b20bcd0941 | 32 | case 4: Led1Set(0); Led2Set(0); Led3Set(1); break; |
| andrewboyson | 164:84b20bcd0941 | 33 | case 5: Led1Set(1); Led2Set(0); Led3Set(1); break; |
| andrewboyson | 164:84b20bcd0941 | 34 | case 6: Led1Set(0); Led2Set(1); Led3Set(1); break; |
| andrewboyson | 164:84b20bcd0941 | 35 | case 7: Led1Set(1); Led2Set(1); Led3Set(1); break; |
| andrewboyson | 164:84b20bcd0941 | 36 | } |
| andrewboyson | 164:84b20bcd0941 | 37 | } |
| andrewboyson | 164:84b20bcd0941 | 38 | |
| andrewboyson | 90:955f4c6e18a9 | 39 | static void log(uint16_t remPort, char* fmt, ...) |
| andrewboyson | 90:955f4c6e18a9 | 40 | { |
| andrewboyson | 90:955f4c6e18a9 | 41 | if (TcpTrace) |
| andrewboyson | 90:955f4c6e18a9 | 42 | { |
| andrewboyson | 90:955f4c6e18a9 | 43 | if (NetTraceNewLine) Log("\r\n"); |
| andrewboyson | 90:955f4c6e18a9 | 44 | LogTimeF("TCP port %hu - ", remPort); |
| andrewboyson | 90:955f4c6e18a9 | 45 | va_list argptr; |
| andrewboyson | 90:955f4c6e18a9 | 46 | va_start(argptr, fmt); |
| andrewboyson | 90:955f4c6e18a9 | 47 | LogV(fmt, argptr); |
| andrewboyson | 90:955f4c6e18a9 | 48 | va_end(argptr); |
| andrewboyson | 90:955f4c6e18a9 | 49 | Log("\r\n"); |
| andrewboyson | 90:955f4c6e18a9 | 50 | } |
| andrewboyson | 90:955f4c6e18a9 | 51 | } |
| andrewboyson | 90:955f4c6e18a9 | 52 | |
| andrewboyson | 88:1ba13e6062a3 | 53 | static bool doTrace(uint16_t port) |
| andrewboyson | 88:1ba13e6062a3 | 54 | { |
| andrewboyson | 88:1ba13e6062a3 | 55 | switch (port) |
| andrewboyson | 88:1ba13e6062a3 | 56 | { |
| andrewboyson | 159:3ebef2d02f7f | 57 | case 80: return HttpGetTrace(); |
| andrewboyson | 159:3ebef2d02f7f | 58 | case 443: return HttpsGetTrace(); |
| andrewboyson | 146:0fc66d610fd6 | 59 | default: return false; |
| andrewboyson | 88:1ba13e6062a3 | 60 | } |
| andrewboyson | 88:1ba13e6062a3 | 61 | } |
| andrewboyson | 147:a6093b52e654 | 62 | |
| andrewboyson | 159:3ebef2d02f7f | 63 | static bool addAppData(int *pDataLength, void* pPacket, int connection, uint16_t port, uint32_t windowPositionInStream, int windowSize, bool clientFinished) |
| andrewboyson | 147:a6093b52e654 | 64 | { |
| andrewboyson | 159:3ebef2d02f7f | 65 | uint8_t* pWindow = (uint8_t*)pPacket + TcpHdrSizeGet(); |
| andrewboyson | 145:206bf0d073c7 | 66 | bool finished = false; |
| andrewboyson | 159:3ebef2d02f7f | 67 | *pDataLength = windowSize; |
| andrewboyson | 75:603b10404183 | 68 | switch (port) |
| andrewboyson | 74:c3756bfa960e | 69 | { |
| andrewboyson | 159:3ebef2d02f7f | 70 | case 80: finished = HttpResponse(connection, clientFinished, pDataLength, (char*)pWindow, windowPositionInStream); break; |
| andrewboyson | 159:3ebef2d02f7f | 71 | case 443: finished = HttpsResponse(connection, clientFinished, pDataLength, pWindow, windowPositionInStream); break; |
| andrewboyson | 144:6bd5c54efc7d | 72 | } |
| andrewboyson | 145:206bf0d073c7 | 73 | return finished; |
| andrewboyson | 75:603b10404183 | 74 | } |
| andrewboyson | 89:9b765a67699b | 75 | static int preparePacket(void* pPacket, struct tcb* pTcb, int dataLength, int* pSize) |
| andrewboyson | 75:603b10404183 | 76 | { |
| andrewboyson | 75:603b10404183 | 77 | //Set the acknowledge flag |
| andrewboyson | 75:603b10404183 | 78 | TcpHdrACK = true; |
| andrewboyson | 74:c3756bfa960e | 79 | |
| andrewboyson | 75:603b10404183 | 80 | //Swap the ports for the reply |
| andrewboyson | 89:9b765a67699b | 81 | TcpHdrSrcPort = pTcb->locPort; |
| andrewboyson | 89:9b765a67699b | 82 | TcpHdrDstPort = pTcb->remPort; |
| andrewboyson | 75:603b10404183 | 83 | |
| andrewboyson | 75:603b10404183 | 84 | //Specify the receive window size to not throttle |
| andrewboyson | 75:603b10404183 | 85 | TcpHdrWindow = 4000; |
| andrewboyson | 75:603b10404183 | 86 | |
| andrewboyson | 75:603b10404183 | 87 | //Write the header |
| andrewboyson | 75:603b10404183 | 88 | TcpHdrWriteToPacket(pPacket); |
| andrewboyson | 75:603b10404183 | 89 | |
| andrewboyson | 75:603b10404183 | 90 | //Calculate the size of the reply |
| andrewboyson | 75:603b10404183 | 91 | *pSize = TcpHdrSizeGet() + dataLength; |
| andrewboyson | 75:603b10404183 | 92 | |
| andrewboyson | 89:9b765a67699b | 93 | return ActionMakeFromDestAndTrace(UNICAST, doTrace(pTcb->locPort) && NetTraceStack); |
| andrewboyson | 74:c3756bfa960e | 94 | } |
| andrewboyson | 75:603b10404183 | 95 | int TcpSend(int* pSize, void* pPacket, struct tcb* pTcb) |
| andrewboyson | 74:c3756bfa960e | 96 | { |
| andrewboyson | 74:c3756bfa960e | 97 | int dataLength = 0; |
| andrewboyson | 74:c3756bfa960e | 98 | TcpHdrMakeEmpty(); |
| andrewboyson | 74:c3756bfa960e | 99 | int locMss = *pSize - TcpHdrSizeGet(); |
| andrewboyson | 74:c3756bfa960e | 100 | switch (pTcb->state) |
| andrewboyson | 74:c3756bfa960e | 101 | { |
| andrewboyson | 74:c3756bfa960e | 102 | case TCB_SYN_RECEIVED: |
| andrewboyson | 74:c3756bfa960e | 103 | if (pTcb->bytesSentToRem == 0) |
| andrewboyson | 74:c3756bfa960e | 104 | { |
| andrewboyson | 74:c3756bfa960e | 105 | TcpHdrMssSet(locMss); |
| andrewboyson | 74:c3756bfa960e | 106 | TcpHdrSYN = true; |
| andrewboyson | 74:c3756bfa960e | 107 | } |
| andrewboyson | 74:c3756bfa960e | 108 | break; |
| andrewboyson | 74:c3756bfa960e | 109 | |
| andrewboyson | 74:c3756bfa960e | 110 | case TCB_ESTABLISHED: |
| andrewboyson | 74:c3756bfa960e | 111 | if (!pTcb->sentFin) |
| andrewboyson | 74:c3756bfa960e | 112 | { |
| andrewboyson | 74:c3756bfa960e | 113 | if (pTcb->bytesSentToRem - pTcb->bytesAckdByRem < pTcb->window) |
| andrewboyson | 74:c3756bfa960e | 114 | { |
| andrewboyson | 156:be12b8fd5b21 | 115 | bool finished = addAppData(&dataLength, pPacket, TcbGetId(pTcb), pTcb->locPort, pTcb->bytesSentToRem - 1, pTcb->remMss, pTcb->rcvdFin); |
| andrewboyson | 145:206bf0d073c7 | 116 | if (finished) |
| andrewboyson | 74:c3756bfa960e | 117 | { |
| andrewboyson | 144:6bd5c54efc7d | 118 | TcpHdrFIN = true; |
| andrewboyson | 144:6bd5c54efc7d | 119 | pTcb->sentFin = true; |
| andrewboyson | 74:c3756bfa960e | 120 | } |
| andrewboyson | 74:c3756bfa960e | 121 | } |
| andrewboyson | 74:c3756bfa960e | 122 | } |
| andrewboyson | 74:c3756bfa960e | 123 | break; |
| andrewboyson | 74:c3756bfa960e | 124 | } |
| andrewboyson | 74:c3756bfa960e | 125 | |
| andrewboyson | 79:f50e02fb5c94 | 126 | //Handle the acknowledgement of received bytes |
| andrewboyson | 74:c3756bfa960e | 127 | bool rcvdSeqHasAdvanced = pTcb->bytesRcvdFromRem > pTcb->bytesAckdToRem; |
| andrewboyson | 74:c3756bfa960e | 128 | pTcb->bytesAckdToRem = pTcb->bytesRcvdFromRem; |
| andrewboyson | 79:f50e02fb5c94 | 129 | TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn; //Set up the acknowledgement field ready to send |
| andrewboyson | 74:c3756bfa960e | 130 | |
| andrewboyson | 79:f50e02fb5c94 | 131 | //Specify the start of the data being sent |
| andrewboyson | 79:f50e02fb5c94 | 132 | uint32_t seqToSend = pTcb->bytesSentToRem; |
| andrewboyson | 79:f50e02fb5c94 | 133 | TcpHdrSeqNum = seqToSend + pTcb->locIsn; //Set up the start of the message before adding the bytes sent |
| andrewboyson | 74:c3756bfa960e | 134 | |
| andrewboyson | 74:c3756bfa960e | 135 | //Record the number of bytes sent |
| andrewboyson | 74:c3756bfa960e | 136 | uint32_t bytesToSend = 0; |
| andrewboyson | 74:c3756bfa960e | 137 | if (TcpHdrSYN) bytesToSend += 1; //Add one to acknowledge the SYN |
| andrewboyson | 74:c3756bfa960e | 138 | bytesToSend += dataLength; //Add the number of bytes received |
| andrewboyson | 74:c3756bfa960e | 139 | if (TcpHdrFIN) bytesToSend += 1; //Add one to acknowledge the FIN |
| andrewboyson | 74:c3756bfa960e | 140 | |
| andrewboyson | 74:c3756bfa960e | 141 | pTcb->bytesSentToRem += bytesToSend; |
| andrewboyson | 74:c3756bfa960e | 142 | |
| andrewboyson | 79:f50e02fb5c94 | 143 | //Only send a packet if have bytes or an acknowledgement to send |
| andrewboyson | 75:603b10404183 | 144 | if (!rcvdSeqHasAdvanced && !bytesToSend) return DO_NOTHING; |
| andrewboyson | 79:f50e02fb5c94 | 145 | |
| andrewboyson | 89:9b765a67699b | 146 | return preparePacket(pPacket, pTcb, dataLength, pSize); |
| andrewboyson | 75:603b10404183 | 147 | } |
| andrewboyson | 75:603b10404183 | 148 | int TcpResendLastUnAcked(int* pSize, void *pPacket, struct tcb* pTcb) |
| andrewboyson | 75:603b10404183 | 149 | { |
| andrewboyson | 75:603b10404183 | 150 | int dataLength = 0; |
| andrewboyson | 75:603b10404183 | 151 | TcpHdrMakeEmpty(); |
| andrewboyson | 75:603b10404183 | 152 | int locMss = *pSize - TcpHdrSizeGet(); |
| andrewboyson | 79:f50e02fb5c94 | 153 | uint32_t seqNum = pTcb->bytesAckdByRem; |
| andrewboyson | 75:603b10404183 | 154 | switch (pTcb->state) |
| andrewboyson | 74:c3756bfa960e | 155 | { |
| andrewboyson | 75:603b10404183 | 156 | case TCB_SYN_RECEIVED: |
| andrewboyson | 75:603b10404183 | 157 | TcpHdrMssSet(locMss); |
| andrewboyson | 75:603b10404183 | 158 | TcpHdrSYN = true; |
| andrewboyson | 75:603b10404183 | 159 | break; |
| andrewboyson | 74:c3756bfa960e | 160 | |
| andrewboyson | 75:603b10404183 | 161 | case TCB_ESTABLISHED: |
| andrewboyson | 79:f50e02fb5c94 | 162 | case TCB_CLOSE_FIN_WAIT: |
| andrewboyson | 75:603b10404183 | 163 | { |
| andrewboyson | 156:be12b8fd5b21 | 164 | bool finished = addAppData(&dataLength, pPacket, TcbGetId(pTcb), pTcb->locPort, seqNum - 1, pTcb->remMss, pTcb->rcvdFin); |
| andrewboyson | 145:206bf0d073c7 | 165 | if (finished) |
| andrewboyson | 75:603b10404183 | 166 | { |
| andrewboyson | 75:603b10404183 | 167 | TcpHdrFIN = true; |
| andrewboyson | 75:603b10404183 | 168 | pTcb->sentFin = true; |
| andrewboyson | 75:603b10404183 | 169 | } |
| andrewboyson | 145:206bf0d073c7 | 170 | break; |
| andrewboyson | 75:603b10404183 | 171 | } |
| andrewboyson | 74:c3756bfa960e | 172 | } |
| andrewboyson | 75:603b10404183 | 173 | |
| andrewboyson | 75:603b10404183 | 174 | TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn; //Set up the acknowledgement field ready to send |
| andrewboyson | 75:603b10404183 | 175 | TcpHdrSeqNum = seqNum + pTcb->locIsn; //Set up the start of the message before adding the bytes sent |
| andrewboyson | 79:f50e02fb5c94 | 176 | |
| andrewboyson | 89:9b765a67699b | 177 | return preparePacket(pPacket, pTcb, dataLength, pSize); |
| andrewboyson | 75:603b10404183 | 178 | } |
| andrewboyson | 75:603b10404183 | 179 | int TcpResendLastAck(int* pSize, void *pPacket, struct tcb* pTcb) |
| andrewboyson | 75:603b10404183 | 180 | { |
| andrewboyson | 75:603b10404183 | 181 | int dataLength = 0; |
| andrewboyson | 75:603b10404183 | 182 | TcpHdrMakeEmpty(); |
| andrewboyson | 75:603b10404183 | 183 | TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn; //Set up the acknowledgement field ready to send |
| andrewboyson | 75:603b10404183 | 184 | TcpHdrSeqNum = pTcb->bytesSentToRem + pTcb->locIsn; //Set up the start of the message before adding the bytes sent |
| andrewboyson | 75:603b10404183 | 185 | |
| andrewboyson | 89:9b765a67699b | 186 | return preparePacket(pPacket, pTcb, dataLength, pSize); |
| andrewboyson | 75:603b10404183 | 187 | } |
| andrewboyson | 75:603b10404183 | 188 | int TcpSendReset(int* pSize, void *pPacket, struct tcb* pTcb) |
| andrewboyson | 75:603b10404183 | 189 | { |
| andrewboyson | 75:603b10404183 | 190 | int dataLength = 0; |
| andrewboyson | 75:603b10404183 | 191 | TcpHdrMakeEmpty(); |
| andrewboyson | 75:603b10404183 | 192 | TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn; //Set up the acknowledgement field ready to send |
| andrewboyson | 75:603b10404183 | 193 | TcpHdrSeqNum = pTcb->bytesSentToRem + pTcb->locIsn; //Set up the start of the message before adding the bytes sent |
| andrewboyson | 75:603b10404183 | 194 | |
| andrewboyson | 75:603b10404183 | 195 | TcpHdrRST = true; |
| andrewboyson | 75:603b10404183 | 196 | |
| andrewboyson | 89:9b765a67699b | 197 | return preparePacket(pPacket, pTcb, dataLength, pSize); |
| andrewboyson | 74:c3756bfa960e | 198 | } |
| andrewboyson | 79:f50e02fb5c94 | 199 | int TcpSendClose(int* pSize, void *pPacket, struct tcb* pTcb) |
| andrewboyson | 79:f50e02fb5c94 | 200 | { |
| andrewboyson | 79:f50e02fb5c94 | 201 | int dataLength = 0; |
| andrewboyson | 79:f50e02fb5c94 | 202 | TcpHdrMakeEmpty(); |
| andrewboyson | 79:f50e02fb5c94 | 203 | TcpHdrFIN = true; |
| andrewboyson | 79:f50e02fb5c94 | 204 | pTcb->sentFin = true; |
| andrewboyson | 79:f50e02fb5c94 | 205 | pTcb->bytesSentToRem += 1; //For the FIN |
| andrewboyson | 79:f50e02fb5c94 | 206 | TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn; //Set up the acknowledgement field ready to send |
| andrewboyson | 79:f50e02fb5c94 | 207 | TcpHdrSeqNum = pTcb->bytesSentToRem + pTcb->locIsn; //Set up the start of the message before adding the bytes sent |
| andrewboyson | 79:f50e02fb5c94 | 208 | |
| andrewboyson | 89:9b765a67699b | 209 | return preparePacket(pPacket, pTcb, dataLength, pSize); |
| andrewboyson | 79:f50e02fb5c94 | 210 | } |
| andrewboyson | 79:f50e02fb5c94 | 211 | |
| andrewboyson | 80:4ef1500fca1d | 212 | int TcpPollForPacketToSend(int* pSize, void* pPacket, int ipType, int* pRemArIndex, int* pLocIpScope) |
| andrewboyson | 74:c3756bfa960e | 213 | { |
| andrewboyson | 83:08c983006a6e | 214 | //Loops around the TCBs, moving on if empty but staying if not the right type |
| andrewboyson | 79:f50e02fb5c94 | 215 | static struct tcb* pTcb = NULL; //Passing a pointer containing NULL to TcbGetNext causes it to return the first TCB |
| andrewboyson | 79:f50e02fb5c94 | 216 | static bool stay = false; |
| andrewboyson | 83:08c983006a6e | 217 | if (!stay) pTcb = TcbGetNext(pTcb); |
| andrewboyson | 79:f50e02fb5c94 | 218 | stay = false; |
| andrewboyson | 78:9d8fc88df405 | 219 | if (!pTcb->state) return DO_NOTHING; |
| andrewboyson | 79:f50e02fb5c94 | 220 | if (pTcb->ipType != ipType) |
| andrewboyson | 79:f50e02fb5c94 | 221 | { |
| andrewboyson | 79:f50e02fb5c94 | 222 | stay = true; |
| andrewboyson | 79:f50e02fb5c94 | 223 | return DO_NOTHING; |
| andrewboyson | 79:f50e02fb5c94 | 224 | } |
| andrewboyson | 79:f50e02fb5c94 | 225 | |
| andrewboyson | 163:f063e374cf2a | 226 | //Return the remote AR index and the local IP scope |
| andrewboyson | 163:f063e374cf2a | 227 | if (pRemArIndex) *pRemArIndex = pTcb->remArIndex; |
| andrewboyson | 80:4ef1500fca1d | 228 | if (pLocIpScope) *pLocIpScope = pTcb->locIpScope; |
| andrewboyson | 87:40d46a979cdb | 229 | |
| andrewboyson | 163:f063e374cf2a | 230 | //Reap broken links |
| andrewboyson | 133:a37eb35a03f1 | 231 | if (MsTimerRelative(pTcb->timeLastRcvd, TIMEOUT_BROKEN_LINK_MS)) |
| andrewboyson | 79:f50e02fb5c94 | 232 | { |
| andrewboyson | 90:955f4c6e18a9 | 233 | log(pTcb->remPort, "broken link -> reaping TCB"); |
| andrewboyson | 79:f50e02fb5c94 | 234 | pTcb->state = TCB_EMPTY; |
| andrewboyson | 79:f50e02fb5c94 | 235 | return DO_NOTHING; |
| andrewboyson | 79:f50e02fb5c94 | 236 | } |
| andrewboyson | 78:9d8fc88df405 | 237 | |
| andrewboyson | 79:f50e02fb5c94 | 238 | //Reset the RTO if all bytes are acknowledged |
| andrewboyson | 79:f50e02fb5c94 | 239 | if (pTcb->bytesSentToRem == pTcb->bytesAckdByRem) |
| andrewboyson | 79:f50e02fb5c94 | 240 | { |
| andrewboyson | 93:580fc113d9e9 | 241 | pTcb->timeSendsBeingAcked = MsTimerCount; |
| andrewboyson | 82:20781198d26d | 242 | pTcb->countSendsNotAcked = 0; |
| andrewboyson | 79:f50e02fb5c94 | 243 | } |
| andrewboyson | 75:603b10404183 | 244 | |
| andrewboyson | 79:f50e02fb5c94 | 245 | //Check if have unacknowledged send bytes after the RTO |
| andrewboyson | 133:a37eb35a03f1 | 246 | if (MsTimerRelative(pTcb->timeSendsBeingAcked, TIMEOUT_RETRANSMISSION_MS)) |
| andrewboyson | 75:603b10404183 | 247 | { |
| andrewboyson | 82:20781198d26d | 248 | pTcb->countSendsNotAcked++; |
| andrewboyson | 82:20781198d26d | 249 | if (pTcb->countSendsNotAcked > MAX_RETRANSMISSIONS) |
| andrewboyson | 82:20781198d26d | 250 | { |
| andrewboyson | 164:84b20bcd0941 | 251 | log(pTcb->remPort, "reached maximum retransmissions -> reaping TCB"); |
| andrewboyson | 90:955f4c6e18a9 | 252 | pTcb->state = TCB_EMPTY; |
| andrewboyson | 164:84b20bcd0941 | 253 | return DO_NOTHING; |
| andrewboyson | 82:20781198d26d | 254 | } |
| andrewboyson | 90:955f4c6e18a9 | 255 | else |
| andrewboyson | 79:f50e02fb5c94 | 256 | { |
| andrewboyson | 90:955f4c6e18a9 | 257 | log(pTcb->remPort, "only had ack of %lu while sent %lu -> resending", pTcb->bytesAckdByRem, pTcb->bytesSentToRem); |
| andrewboyson | 93:580fc113d9e9 | 258 | pTcb->timeSendsBeingAcked = MsTimerCount; |
| andrewboyson | 90:955f4c6e18a9 | 259 | return TcpResendLastUnAcked(pSize, pPacket, pTcb); |
| andrewboyson | 79:f50e02fb5c94 | 260 | } |
| andrewboyson | 75:603b10404183 | 261 | } |
| andrewboyson | 90:955f4c6e18a9 | 262 | else |
| andrewboyson | 90:955f4c6e18a9 | 263 | { |
| andrewboyson | 90:955f4c6e18a9 | 264 | //If haven't had to do anything else then do a normal send |
| andrewboyson | 90:955f4c6e18a9 | 265 | return TcpSend(pSize, pPacket, pTcb); |
| andrewboyson | 90:955f4c6e18a9 | 266 | } |
| andrewboyson | 74:c3756bfa960e | 267 | } |
| andrewboyson | 74:c3756bfa960e | 268 |