Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Tue Oct 30 22:11:22 2018 +0000
Revision:
75:603b10404183
Parent:
74:c3756bfa960e
Child:
78:9d8fc88df405
A lot of tidying up and prevented requests other than the first packet from doing anything.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 74:c3756bfa960e 1 #include <stdint.h>
andrewboyson 74:c3756bfa960e 2 #include <stdbool.h>
andrewboyson 74:c3756bfa960e 3
andrewboyson 74:c3756bfa960e 4 #include "log.h"
andrewboyson 74:c3756bfa960e 5 #include "net.h"
andrewboyson 74:c3756bfa960e 6 #include "action.h"
andrewboyson 74:c3756bfa960e 7 #include "tcp.h"
andrewboyson 74:c3756bfa960e 8 #include "tcphdr.h"
andrewboyson 74:c3756bfa960e 9 #include "tcb.h"
andrewboyson 74:c3756bfa960e 10 #include "ip4.h"
andrewboyson 74:c3756bfa960e 11 #include "dhcp.h"
andrewboyson 74:c3756bfa960e 12 #include "http.h"
andrewboyson 74:c3756bfa960e 13 #include "led.h"
andrewboyson 74:c3756bfa960e 14 #include "tcpsend.h"
andrewboyson 74:c3756bfa960e 15
andrewboyson 75:603b10404183 16 #define RTO_TIME 2
andrewboyson 74:c3756bfa960e 17
andrewboyson 75:603b10404183 18 static int addApplicationData(void* pPacket, uint16_t port, int start, int mss, int todo)
andrewboyson 74:c3756bfa960e 19 {
andrewboyson 74:c3756bfa960e 20 int dataLength = 0;
andrewboyson 74:c3756bfa960e 21 char* pData = (char*)pPacket + TcpHdrSizeGet();
andrewboyson 75:603b10404183 22 switch (port)
andrewboyson 74:c3756bfa960e 23 {
andrewboyson 74:c3756bfa960e 24 case 80:
andrewboyson 75:603b10404183 25 HttpSendReply(&dataLength, pData, start, mss, todo);
andrewboyson 74:c3756bfa960e 26 break;
andrewboyson 74:c3756bfa960e 27 default:
andrewboyson 74:c3756bfa960e 28 break;
andrewboyson 74:c3756bfa960e 29 }
andrewboyson 75:603b10404183 30
andrewboyson 75:603b10404183 31 return dataLength;
andrewboyson 75:603b10404183 32 }
andrewboyson 75:603b10404183 33 static int preparePacket(void* pPacket, struct tcb* pTcb, int dataLength, int* pSize)
andrewboyson 75:603b10404183 34 {
andrewboyson 75:603b10404183 35 //Set the acknowledge flag
andrewboyson 75:603b10404183 36 TcpHdrACK = true;
andrewboyson 74:c3756bfa960e 37
andrewboyson 75:603b10404183 38 //Swap the ports for the reply
andrewboyson 75:603b10404183 39 TcpHdrSrcPort = pTcb->locPort;
andrewboyson 75:603b10404183 40 TcpHdrDstPort = pTcb->remPort;
andrewboyson 75:603b10404183 41
andrewboyson 75:603b10404183 42 //Specify the receive window size to not throttle
andrewboyson 75:603b10404183 43 TcpHdrWindow = 4000;
andrewboyson 75:603b10404183 44
andrewboyson 75:603b10404183 45 //Write the header
andrewboyson 75:603b10404183 46 TcpHdrWriteToPacket(pPacket);
andrewboyson 75:603b10404183 47
andrewboyson 75:603b10404183 48 //Calculate the size of the reply
andrewboyson 75:603b10404183 49 *pSize = TcpHdrSizeGet() + dataLength;
andrewboyson 75:603b10404183 50
andrewboyson 75:603b10404183 51 //Update the last send time
andrewboyson 74:c3756bfa960e 52 pTcb->lastSendTime = TcbElapsed;
andrewboyson 74:c3756bfa960e 53
andrewboyson 75:603b10404183 54 return ActionMakeFromDestAndTrace(UNICAST, TcpDoTrace && NetTraceStack);
andrewboyson 74:c3756bfa960e 55 }
andrewboyson 75:603b10404183 56 int TcpSend(int* pSize, void* pPacket, struct tcb* pTcb)
andrewboyson 74:c3756bfa960e 57 {
andrewboyson 74:c3756bfa960e 58 int dataLength = 0;
andrewboyson 74:c3756bfa960e 59 TcpHdrMakeEmpty();
andrewboyson 74:c3756bfa960e 60 int locMss = *pSize - TcpHdrSizeGet();
andrewboyson 74:c3756bfa960e 61 switch (pTcb->state)
andrewboyson 74:c3756bfa960e 62 {
andrewboyson 74:c3756bfa960e 63 case TCB_SYN_RECEIVED:
andrewboyson 74:c3756bfa960e 64 if (pTcb->bytesSentToRem == 0)
andrewboyson 74:c3756bfa960e 65 {
andrewboyson 74:c3756bfa960e 66 TcpHdrMssSet(locMss);
andrewboyson 74:c3756bfa960e 67 TcpHdrSYN = true;
andrewboyson 74:c3756bfa960e 68 }
andrewboyson 74:c3756bfa960e 69 break;
andrewboyson 74:c3756bfa960e 70
andrewboyson 74:c3756bfa960e 71 case TCB_ESTABLISHED:
andrewboyson 74:c3756bfa960e 72 if (!pTcb->sentFin)
andrewboyson 74:c3756bfa960e 73 {
andrewboyson 74:c3756bfa960e 74 if (pTcb->bytesSentToRem - pTcb->bytesAckdByRem < pTcb->window)
andrewboyson 74:c3756bfa960e 75 {
andrewboyson 74:c3756bfa960e 76 if (pTcb->todo)
andrewboyson 74:c3756bfa960e 77 {
andrewboyson 75:603b10404183 78 dataLength = addApplicationData(pPacket, pTcb->locPort, pTcb->bytesSentToRem - 1, pTcb->remMss, pTcb->todo);
andrewboyson 74:c3756bfa960e 79 if (dataLength < pTcb->remMss)
andrewboyson 74:c3756bfa960e 80 {
andrewboyson 74:c3756bfa960e 81 TcpHdrFIN = true;
andrewboyson 74:c3756bfa960e 82 pTcb->sentFin = true;
andrewboyson 74:c3756bfa960e 83 }
andrewboyson 74:c3756bfa960e 84 }
andrewboyson 74:c3756bfa960e 85 else
andrewboyson 74:c3756bfa960e 86 {
andrewboyson 74:c3756bfa960e 87 if (pTcb->rcvdFin)
andrewboyson 74:c3756bfa960e 88 {
andrewboyson 74:c3756bfa960e 89 TcpHdrFIN = true;
andrewboyson 74:c3756bfa960e 90 pTcb->sentFin = true;
andrewboyson 74:c3756bfa960e 91 }
andrewboyson 74:c3756bfa960e 92 }
andrewboyson 74:c3756bfa960e 93 }
andrewboyson 74:c3756bfa960e 94 }
andrewboyson 74:c3756bfa960e 95 break;
andrewboyson 74:c3756bfa960e 96 }
andrewboyson 74:c3756bfa960e 97
andrewboyson 74:c3756bfa960e 98 //See if have need to acknowledge received bytes
andrewboyson 74:c3756bfa960e 99 bool rcvdSeqHasAdvanced = pTcb->bytesRcvdFromRem > pTcb->bytesAckdToRem;
andrewboyson 74:c3756bfa960e 100
andrewboyson 74:c3756bfa960e 101 //Record the number of bytes acknowledged to the remote
andrewboyson 74:c3756bfa960e 102 pTcb->bytesAckdToRem = pTcb->bytesRcvdFromRem;
andrewboyson 74:c3756bfa960e 103
andrewboyson 74:c3756bfa960e 104 //Specify the start of the data being sent and acknowledge the data received
andrewboyson 74:c3756bfa960e 105 TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn; //Set up the acknowledgement field ready to send
andrewboyson 74:c3756bfa960e 106 TcpHdrSeqNum = pTcb->bytesSentToRem + pTcb->locIsn; //Set up the start of the message before adding the bytes sent
andrewboyson 74:c3756bfa960e 107
andrewboyson 74:c3756bfa960e 108 //Record the number of bytes sent
andrewboyson 74:c3756bfa960e 109 uint32_t bytesToSend = 0;
andrewboyson 74:c3756bfa960e 110 if (TcpHdrSYN) bytesToSend += 1; //Add one to acknowledge the SYN
andrewboyson 74:c3756bfa960e 111 bytesToSend += dataLength; //Add the number of bytes received
andrewboyson 74:c3756bfa960e 112 if (TcpHdrFIN) bytesToSend += 1; //Add one to acknowledge the FIN
andrewboyson 74:c3756bfa960e 113
andrewboyson 74:c3756bfa960e 114 pTcb->bytesSentToRem += bytesToSend;
andrewboyson 74:c3756bfa960e 115
andrewboyson 75:603b10404183 116 if (!rcvdSeqHasAdvanced && !bytesToSend) return DO_NOTHING;
andrewboyson 75:603b10404183 117
andrewboyson 75:603b10404183 118 return preparePacket(pPacket, pTcb, dataLength, pSize);
andrewboyson 75:603b10404183 119 }
andrewboyson 75:603b10404183 120 int TcpResendLastUnAcked(int* pSize, void *pPacket, struct tcb* pTcb)
andrewboyson 75:603b10404183 121 {
andrewboyson 75:603b10404183 122 int dataLength = 0;
andrewboyson 75:603b10404183 123 TcpHdrMakeEmpty();
andrewboyson 75:603b10404183 124 int locMss = *pSize - TcpHdrSizeGet();
andrewboyson 75:603b10404183 125 int seqNum = pTcb->bytesAckdByRem;
andrewboyson 75:603b10404183 126 switch (pTcb->state)
andrewboyson 74:c3756bfa960e 127 {
andrewboyson 75:603b10404183 128 case TCB_SYN_RECEIVED:
andrewboyson 75:603b10404183 129 TcpHdrMssSet(locMss);
andrewboyson 75:603b10404183 130 TcpHdrSYN = true;
andrewboyson 75:603b10404183 131 break;
andrewboyson 74:c3756bfa960e 132
andrewboyson 75:603b10404183 133 case TCB_ESTABLISHED:
andrewboyson 75:603b10404183 134 if (pTcb->todo)
andrewboyson 75:603b10404183 135 {
andrewboyson 75:603b10404183 136 dataLength = addApplicationData(pPacket, pTcb->locPort, seqNum, pTcb->remMss, pTcb->todo);
andrewboyson 75:603b10404183 137 if (dataLength < pTcb->remMss)
andrewboyson 75:603b10404183 138 {
andrewboyson 75:603b10404183 139 TcpHdrFIN = true;
andrewboyson 75:603b10404183 140 pTcb->sentFin = true;
andrewboyson 75:603b10404183 141 }
andrewboyson 75:603b10404183 142 }
andrewboyson 75:603b10404183 143 break;
andrewboyson 74:c3756bfa960e 144 }
andrewboyson 75:603b10404183 145
andrewboyson 75:603b10404183 146 TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn; //Set up the acknowledgement field ready to send
andrewboyson 75:603b10404183 147 TcpHdrSeqNum = seqNum + pTcb->locIsn; //Set up the start of the message before adding the bytes sent
andrewboyson 75:603b10404183 148
andrewboyson 75:603b10404183 149 return preparePacket(pPacket, pTcb, dataLength, pSize);
andrewboyson 75:603b10404183 150 }
andrewboyson 75:603b10404183 151 int TcpResendLastAck(int* pSize, void *pPacket, struct tcb* pTcb)
andrewboyson 75:603b10404183 152 {
andrewboyson 75:603b10404183 153 int dataLength = 0;
andrewboyson 75:603b10404183 154 TcpHdrMakeEmpty();
andrewboyson 75:603b10404183 155 TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn; //Set up the acknowledgement field ready to send
andrewboyson 75:603b10404183 156 TcpHdrSeqNum = pTcb->bytesSentToRem + pTcb->locIsn; //Set up the start of the message before adding the bytes sent
andrewboyson 75:603b10404183 157
andrewboyson 75:603b10404183 158 return preparePacket(pPacket, pTcb, dataLength, pSize);
andrewboyson 75:603b10404183 159 }
andrewboyson 75:603b10404183 160 int TcpSendReset(int* pSize, void *pPacket, struct tcb* pTcb)
andrewboyson 75:603b10404183 161 {
andrewboyson 75:603b10404183 162 int dataLength = 0;
andrewboyson 75:603b10404183 163 TcpHdrMakeEmpty();
andrewboyson 75:603b10404183 164 TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn; //Set up the acknowledgement field ready to send
andrewboyson 75:603b10404183 165 TcpHdrSeqNum = pTcb->bytesSentToRem + pTcb->locIsn; //Set up the start of the message before adding the bytes sent
andrewboyson 75:603b10404183 166
andrewboyson 75:603b10404183 167 TcpHdrRST = true;
andrewboyson 75:603b10404183 168
andrewboyson 75:603b10404183 169 return preparePacket(pPacket, pTcb, dataLength, pSize);
andrewboyson 74:c3756bfa960e 170 }
andrewboyson 74:c3756bfa960e 171 int TcpPollForPacketToSend(int* pSize, void* pPacket, int ipType, int* pRemArIndex)
andrewboyson 74:c3756bfa960e 172 {
andrewboyson 74:c3756bfa960e 173 struct tcb* pTcb = TcbGetNext(); //This loops around the TCBs
andrewboyson 74:c3756bfa960e 174 if (pTcb->ipType != ipType) return DO_NOTHING;
andrewboyson 74:c3756bfa960e 175 *pRemArIndex = pTcb->remArIndex;
andrewboyson 75:603b10404183 176
andrewboyson 75:603b10404183 177 //Check if have unacknowledged bytes longer than a time out
andrewboyson 75:603b10404183 178 if (TcbElapsed - pTcb->lastSendTime > RTO_TIME && pTcb->bytesSentToRem > pTcb->bytesAckdByRem)
andrewboyson 75:603b10404183 179 {
andrewboyson 75:603b10404183 180 return TcpResendLastUnAcked(pSize, pPacket, pTcb);
andrewboyson 75:603b10404183 181 }
andrewboyson 75:603b10404183 182 //Otherwise do a normal send
andrewboyson 75:603b10404183 183 else
andrewboyson 75:603b10404183 184 {
andrewboyson 75:603b10404183 185 return TcpSend(pSize, pPacket, pTcb);
andrewboyson 75:603b10404183 186 }
andrewboyson 74:c3756bfa960e 187 }
andrewboyson 74:c3756bfa960e 188