9 #include "LibEndian.hpp"
10 #include "NetTcpSocket.hpp"
11 #include "NetChecksum.hpp"
13 LibLinkedList<NetTcpSocket> NetTcp::sSocketList;
16 void NetTcp::processFrame(NetDefs::FRAME& frame, NetDefs::TCP_HEADER& header,
int len) {
19 NetDefs::IP_PSEUDO_HEADER ipPseudoHeader;
20 ipPseudoHeader.srcAddr = frame.types.ip.ipHeader.srcAddr;
21 ipPseudoHeader.dstAddr = frame.types.ip.ipHeader.dstAddr;
22 ipPseudoHeader.zero = 0x0;
23 ipPseudoHeader.protocol = NetDefs::IP_PROTOCOL_TCP;
24 ipPseudoHeader.len = LibEndian::beToHw((uint16_t) len);
26 uint32_t checkSum = NetChecksum::calcPartialChecksum((uint8_t*) &ipPseudoHeader,
sizeof(ipPseudoHeader));
28 checkSum += NetChecksum::calcPartialChecksum((uint8_t*) &header, len);
30 checkSum = NetChecksum::finalizeCheckSum(checkSum);
33 Net::freeFrame(frame);
41 NetTcpSocket* s = findMatchingSocket(header, frame.types.ip.ipHeader.srcAddr);
45 Net::freeFrame(frame);
49 if (!onSegmentReceived(frame, header, *s, len)) {
50 Net::freeFrame(frame);
55 bool NetTcp::onSegmentReceived(NetDefs::FRAME& frame, NetDefs::TCP_HEADER& header, NetTcpSocket& s,
int len) {
58 if (header.flags.bits.ack) {
59 for (; s.mTxFirstSegment != 0;) {
60 uint32_t diff = header.ack - (s.mTxFirstSegment->hdr.seq + s.mTxFirstSegment->hdr.len);
61 if (diff < 0x80000000) {
62 NetTcpSocket::TX_SEGMENT* next = s.mTxFirstSegment->next;
63 Net::freeFrame((NetDefs::FRAME&) *s.mTxFirstSegment);
64 s.mTxFirstSegment = next;
72 if (header.flags.bits.rst) {
74 case NetTcpSocket::STATE_LISTEN:
76 case NetTcpSocket::STATE_SYN_SENT:
77 s.mState = NetTcpSocket::STATE_CLOSED;
80 case NetTcpSocket::STATE_SYN_RCVD:
81 s.mState = NetTcpSocket::STATE_LISTEN;
83 case NetTcpSocket::STATE_EST: {
84 s.discardAllRxSegments();
85 s.discardAllTxSegments();
86 if (s.mIsAutoListenAndAccept) {
87 s.mState = NetTcpSocket::STATE_LISTEN;
90 s.mState = NetTcpSocket::STATE_RESET;
91 NetTcpSocket::RX_SEGMENT* seg = 0;
92 s.mRxMsgBox.give(seg, 0);
97 s.discardAllTxSegments();
98 s.discardAllTxSegments();
99 if (s.mIsAutoListenAndAccept) {
100 s.mState = NetTcpSocket::STATE_LISTEN;
103 s.mState = NetTcpSocket::STATE_RESET;
111 case NetTcpSocket::STATE_LISTEN:
112 if (header.flags.bits.syn) {
113 s.mRemoteMacAddr = frame.types.mac.macHeader.srcAddr;
114 s.mRemoteIpAddr = frame.types.ip.ipHeader.srcAddr;
115 s.mRemotePort = header.srcPort;
117 s.mRecvCount = header.seq + 1;
119 s.mRetries = MAX_RETRIES_SYN_RCVD;
120 s.mTimer = TIMER_SYN_RCVD;
121 s.mState = NetTcpSocket::STATE_SYN_RCVD;
122 sendControlPacket(s, NetDefs::TCP_FLAG_SYN | NetDefs::TCP_FLAG_ACK);
126 case NetTcpSocket::STATE_SYN_SENT:
127 if (header.flags.bits.syn && header.flags.bits.ack && (header.ack == s.mSentCount)) {
128 s.mRecvCount = header.seq + 1;
129 sendControlPacket(s, NetDefs::TCP_FLAG_ACK);
130 s.mRetries = MAX_RETRIES_EST_KEEP_ALIVE;
131 s.mTimer = TIMER_EST_KEEP_ALIVE;
132 s.mState = NetTcpSocket::STATE_EST;
133 s.mSemaEvent.give(0);
136 case NetTcpSocket::STATE_SYN_RCVD:
137 if (header.flags.bits.ack) {
138 if (header.seq == s.mRecvCount) {
139 s.mRecvCount = header.seq;
140 s.mRetries = MAX_RETRIES_EST_KEEP_ALIVE;
141 s.mTimer = TIMER_EST_KEEP_ALIVE;
142 s.mState = NetTcpSocket::STATE_EST;
143 if (!s.mIsAutoListenAndAccept) {
144 s.mSemaEvent.give(0);
149 case NetTcpSocket::STATE_EST: {
150 if (header.seq != s.mRecvCount) {
153 sendControlPacket(s, NetDefs::TCP_FLAG_ACK);
156 if (header.flags.bits.fin) {
157 s.discardAllTxSegments();
159 s.mSentCount = header.ack;
160 sendControlPacket(s, NetDefs::TCP_FLAG_ACK);
161 if (s.mIsAutoListenAndAccept) {
162 sendControlPacket(s, NetDefs::TCP_FLAG_FIN | NetDefs::TCP_FLAG_ACK);
163 s.mState = NetTcpSocket::STATE_LAST_ACK;
164 s.mRetries = MAX_RETRIES_LAST_ACK;
165 s.mTimer = TIMER_LAST_ACK;
168 s.mState = NetTcpSocket::STATE_CLOSE_WAIT;
169 NetTcpSocket::RX_SEGMENT* seg = 0;
170 s.mRxMsgBox.give(seg, 0);
174 s.mRetries = MAX_RETRIES_EST_KEEP_ALIVE;
175 s.mTimer = TIMER_EST_KEEP_ALIVE;
178 int optionLen = (((int) header.offset.val) << 2) -
sizeof(NetDefs::TCP_HEADER);
179 int dataLen = len - (((int) header.offset.val) << 2);
182 if (dataLen <= s.mWindowSize) {
183 NetTcpSocket::RX_SEGMENT* seg = (NetTcpSocket::RX_SEGMENT*) Net::resizeFrameLeft(frame,
184 (((uint8_t*) &header +
sizeof(NetDefs::TCP_HEADER) + optionLen - (uint8_t*) &frame)) -
sizeof(NetTcpSocket::RX_SEGMENT_HEADER));
189 seg->hdr.dataLen = dataLen;
190 if (!s.mRxMsgBox.give(seg, 0)) {
191 Net::freeFrame((NetDefs::FRAME&) *seg);
194 s.mWindowSize -= dataLen;
195 s.mRecvCount += dataLen;
196 sendControlPacket(s, NetDefs::TCP_FLAG_ACK);
204 case NetTcpSocket::STATE_FIN_WAIT_1:
205 if ((header.seq == s.mRecvCount)) {
206 s.mRecvCount += len - (((int) header.offset.val) << 2);
208 if (header.flags.bits.fin && header.flags.bits.ack) {
210 sendControlPacket(s, NetDefs::TCP_FLAG_ACK);
212 s.mTimer = TIMER_TIME_WAIT;
213 s.mState = NetTcpSocket::STATE_TIME_WAIT;
215 else if (header.flags.bits.ack) {
216 s.mRetries = MAX_RETRIES_FIN_WAIT_2;
217 s.mTimer = TIMER_FIN_WAIT_2;
218 s.mState = NetTcpSocket::STATE_FIN_WAIT_2;
220 else if (header.flags.bits.fin) {
222 sendControlPacket(s, NetDefs::TCP_FLAG_ACK);
224 s.mRetries = MAX_RETRIES_CLOSING;
225 s.mTimer = TIMER_CLOSING;
226 s.mState = NetTcpSocket::STATE_CLOSING;
230 case NetTcpSocket::STATE_FIN_WAIT_2:
231 if (header.seq == s.mRecvCount) {
232 s.mRecvCount += len - (((int) header.offset.val) << 2);
233 if (header.flags.bits.fin) {
235 sendControlPacket(s, NetDefs::TCP_FLAG_ACK);
237 s.mTimer = TIMER_TIME_WAIT;
238 s.mState = NetTcpSocket::STATE_TIME_WAIT;
242 case NetTcpSocket::STATE_CLOSING:
243 if (header.seq == s.mRecvCount) {
244 s.mRecvCount += len - (((int) header.offset.val) << 2);
245 if (header.flags.bits.ack) {
246 s.mTimer = TIMER_TIME_WAIT;
247 s.mState = NetTcpSocket::STATE_TIME_WAIT;
251 case NetTcpSocket::STATE_TIME_WAIT:
252 if (header.seq == s.mRecvCount) {
253 sendControlPacket(s, NetDefs::TCP_FLAG_ACK);
256 case NetTcpSocket::STATE_LAST_ACK:
257 if (header.seq == s.mRecvCount) {
258 if (header.flags.bits.ack) {
259 s.discardAllTxSegments();
260 s.discardAllRxSegments();
261 if (s.mIsAutoListenAndAccept) {
262 s.mState = NetTcpSocket::STATE_LISTEN;
266 s.mState = NetTcpSocket::STATE_CLOSED;
277 void NetTcp::tick() {
280 for (NetTcpSocket* s = sSocketList.getFirst(); s != 0; s = s->getNext()) {
282 for (NetTcpSocket::TX_SEGMENT* segment = s->mTxFirstSegment; segment != 0; segment = segment->next) {
283 if (segment->hdr.timeout-- <= 0) {
284 if (segment->hdr.retries > 0) {
285 flushSegment(*s, *segment);
286 s->mRetries = MAX_RETRIES_EST_KEEP_ALIVE;
287 s->mTimer = TIMER_EST_KEEP_ALIVE;
291 s->mSentCount = s->mTxFirstSegment->hdr.seq;
292 s->discardAllTxSegments();
293 sendControlPacket(*s, NetDefs::TCP_FLAG_PSH | NetDefs::TCP_FLAG_RST);
294 if (s->mIsAutoListenAndAccept) {
295 s->discardAllRxSegments();
296 s->mState = NetTcpSocket::STATE_LISTEN;
299 s->mState = NetTcpSocket::STATE_CLOSE_WAIT;
305 if (s->mTimer-- > 0) {
310 case NetTcpSocket::STATE_SYN_SENT:
313 sendControlPacket(*s, NetDefs::TCP_FLAG_SYN);
315 s->mTimer = TIMER_SYN_RCVD;
318 s->mState = NetTcpSocket::STATE_CLOSED;
319 s->mSemaEvent.give(0);
322 case NetTcpSocket::STATE_SYN_RCVD:
325 sendControlPacket(*s, NetDefs::TCP_FLAG_SYN | NetDefs::TCP_FLAG_ACK);
327 s->mTimer = TIMER_SYN_RCVD;
330 sendControlPacket(*s, NetDefs::TCP_FLAG_PSH | NetDefs::TCP_FLAG_RST);
331 s->mState = NetTcpSocket::STATE_LISTEN;
334 case NetTcpSocket::STATE_EST:
335 if (s->mTxFirstSegment == 0) {
338 sendControlPacket(*s, NetDefs::TCP_FLAG_ACK);
340 s->mTimer = TIMER_EST_KEEP_ALIVE;
343 sendControlPacket(*s, NetDefs::TCP_FLAG_PSH | NetDefs::TCP_FLAG_RST);
344 if (s->mIsAutoListenAndAccept) {
345 s->discardAllRxSegments();
346 s->discardAllTxSegments();
347 s->mState = NetTcpSocket::STATE_LISTEN;
350 s->mState = NetTcpSocket::STATE_CLOSE_WAIT;
351 NetTcpSocket::RX_SEGMENT* seg = 0;
352 s->mRxMsgBox.give(seg, 0);
357 case NetTcpSocket::STATE_LAST_ACK:
360 sendControlPacket(*s, NetDefs::TCP_FLAG_PSH | NetDefs::TCP_FLAG_FIN | NetDefs::TCP_FLAG_ACK);
362 s->mTimer = TIMER_LAST_ACK;
367 sendControlPacket(*s, NetDefs::TCP_FLAG_PSH | NetDefs::TCP_FLAG_RST);
368 if (s->mIsAutoListenAndAccept) {
369 s->discardAllRxSegments();
370 s->discardAllTxSegments();
371 s->mState = NetTcpSocket::STATE_LISTEN;
374 s->mTimer = TIMER_TIME_WAIT;
375 s->mState = NetTcpSocket::STATE_TIME_WAIT;
379 case NetTcpSocket::STATE_FIN_WAIT_1:
382 sendControlPacket(*s, NetDefs::TCP_FLAG_PSH | NetDefs::TCP_FLAG_FIN | NetDefs::TCP_FLAG_ACK);
384 s->mTimer = TIMER_FIN_WAIT_1;
389 sendControlPacket(*s, NetDefs::TCP_FLAG_PSH | NetDefs::TCP_FLAG_RST);
390 s->mTimer = TIMER_TIME_WAIT;
391 s->mState = NetTcpSocket::STATE_TIME_WAIT;
394 case NetTcpSocket::STATE_FIN_WAIT_2:
395 sendControlPacket(*s, NetDefs::TCP_FLAG_PSH | NetDefs::TCP_FLAG_RST);
396 s->mTimer = TIMER_TIME_WAIT;
397 s->mState = NetTcpSocket::STATE_TIME_WAIT;
399 case NetTcpSocket::STATE_CLOSING:
400 sendControlPacket(*s, NetDefs::TCP_FLAG_PSH | NetDefs::TCP_FLAG_RST);
401 s->mTimer = TIMER_TIME_WAIT;
402 s->mState = NetTcpSocket::STATE_TIME_WAIT;
404 case NetTcpSocket::STATE_TIME_WAIT:
405 s->discardAllTxSegments();
407 s->mState = NetTcpSocket::STATE_CLOSED;
418 void NetTcp::sendControlPacket(NetTcpSocket& s, uint8_t flags) {
419 NetDefs::FRAME* frame;
420 int len =
sizeof(NetDefs::TCP_HEADER);
422 if (flags & NetDefs::TCP_FLAG_SYN) {
423 len +=
sizeof(NetDefs::TCP_HEADER_OPTIONS);
426 frame = Net::allocFrame(
sizeof(NetDefs::MAC_HEADER) +
sizeof(NetDefs::IP_HEADER) + len);
432 putHeader(*frame, s, s.mSentCount, 0, 0, flags);
433 NetIp::flush(*frame, len,
true);
436 void NetTcp::putHeader(NetDefs::FRAME& frame, NetTcpSocket& s, uint32_t seq, uint32_t checkSum,
int dataLen, uint8_t flags) {
438 frame.types.tcp.tcpHeader.srcPort = s.mLocalPort;
439 frame.types.tcp.tcpHeader.dstPort = s.mRemotePort;
440 frame.types.tcp.tcpHeader.ack = s.mRecvCount;
441 frame.types.tcp.tcpHeader.seq = seq;
442 frame.types.tcp.tcpHeader.offset.zero = 0;
443 frame.types.tcp.tcpHeader.flags.value = flags;
444 frame.types.tcp.tcpHeader.window = s.mWindowSize;
445 frame.types.tcp.tcpHeader.checkSum = 0;
446 frame.types.tcp.tcpHeader.urgentPointer = 0;
448 swapHeader(frame.types.tcp.tcpHeader);
450 if (flags & NetDefs::TCP_FLAG_SYN) {
451 frame.types.tcp_with_options.tcpOptions.type = OPTIONS_MAX_SEG_SIZE;
452 frame.types.tcp_with_options.tcpOptions.len = 0x04;
453 frame.types.tcp_with_options.tcpOptions.maxSegLen = frame.types.tcp.tcpHeader.window;
454 frame.types.tcp.tcpHeader.offset.val = (
sizeof(NetDefs::TCP_HEADER) +
sizeof(NetDefs::TCP_HEADER_OPTIONS)) >> 2;
455 checkSum += NetChecksum::calcPartialChecksum((uint8_t*) &frame.types.tcp_with_options.tcpOptions,
sizeof(NetDefs::TCP_HEADER_OPTIONS));
456 dataLen +=
sizeof(NetDefs::TCP_HEADER_OPTIONS);
459 frame.types.tcp.tcpHeader.offset.val =
sizeof(NetDefs::TCP_HEADER) >> 2;
463 NetDefs::IP_PSEUDO_HEADER pseudoHeader;
466 pseudoHeader.srcAddr.val = Net::sConfig.ipAddr.val;
467 pseudoHeader.dstAddr.val = s.mRemoteIpAddr.val;
468 pseudoHeader.zero = 0x0;
469 pseudoHeader.protocol = NetDefs::IP_PROTOCOL_TCP;
470 pseudoHeader.len = LibEndian::hwToBe((uint16_t) (
sizeof(NetDefs::TCP_HEADER) + dataLen));
472 checkSum += NetChecksum::calcPartialChecksum((uint8_t*) &pseudoHeader,
sizeof(NetDefs::IP_PSEUDO_HEADER));
473 checkSum += NetChecksum::calcPartialChecksum((uint8_t*) &frame.types.tcp.tcpHeader,
sizeof(NetDefs::TCP_HEADER));
477 frame.types.tcp.tcpHeader.checkSum = NetChecksum::finalizeCheckSum(checkSum);
479 NetIp::putHeader(frame, s.mRemoteMacAddr, s.mRemoteIpAddr,
sizeof(NetDefs::TCP_HEADER) + dataLen, NetDefs::IP_PROTOCOL_TCP);
482 NetTcpSocket* NetTcp::findMatchingSocket(NetDefs::TCP_HEADER& header, NetDefs::IP_ADDR& remoteIpAddr) {
483 NetTcpSocket* result = 0;
485 for (NetTcpSocket* s = sSocketList.getFirst(); s != 0; s = s->getNext()) {
486 if (s->mState > NetTcpSocket::STATE_CLOSED) {
487 if (s->mLocalPort == header.dstPort) {
488 if (s->mState == NetTcpSocket::STATE_LISTEN) {
491 else if ((s->mRemotePort == header.srcPort) && (s->mRemoteIpAddr == remoteIpAddr)) {
497 if (!header.flags.bits.syn) {
503 void NetTcp::lock() {
507 void NetTcp::unlock() {
511 void NetTcp::addSocket(NetTcpSocket& socket) {
512 sSocketList.insert(socket);
515 void NetTcp::removeSocket(NetTcpSocket& socket) {
516 sSocketList.remove(socket);
519 void NetTcp::flushSegment(NetTcpSocket& s, NetTcpSocket::TX_SEGMENT& segment) {
520 if (!segment.hdr.flushed) {
522 segment.hdr.dataChecksum = NetChecksum::calcPartialChecksum(segment.frame.types.tcp.data, segment.hdr.len);
523 segment.hdr.flushed =
true;
524 s.mSentCount += segment.hdr.len;
526 putHeader(segment.frame, s, segment.hdr.seq, segment.hdr.dataChecksum, segment.hdr.len, NetDefs::TCP_FLAG_PSH | NetDefs::TCP_FLAG_ACK);
527 NetIp::flush(segment.frame,
sizeof(NetDefs::TCP_HEADER) + segment.hdr.len,
false);
528 if (&segment == s.mTxCurrentSegment) {
529 s.mTxCurrentSegment = 0;
531 segment.hdr.timeout = TIMER_SEGMENT_RETRY;
532 segment.hdr.retries--;
535 int NetTcp::getTcpSocketList(SOCKET_INFO* buffer,
int count) {
538 for (NetTcpSocket* s = sSocketList.getFirst(); s != 0 && i < count; s = s->getNext(), buffer++) {
539 buffer->remoteIpAddr = s->mRemoteIpAddr;
540 buffer->localPort = s->mLocalPort;
541 buffer->remotePort = s->mRemotePort;
542 buffer->state = s->mState;
549 void NetTcp::swapHeader(NetDefs::TCP_HEADER& header) {
550 header.srcPort = LibEndian::hwToBe(header.srcPort);
551 header.dstPort = LibEndian::hwToBe(header.dstPort);
552 header.seq = LibEndian::hwToBe(header.seq);
553 header.ack = LibEndian::hwToBe(header.ack);
554 header.window = LibEndian::hwToBe(header.window);
555 header.checkSum = LibEndian::hwToBe(header.checkSum);
556 header.urgentPointer = LibEndian::hwToBe(header.urgentPointer);