00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <string.h>
00021 #include "TCP.h"
00022 #include "TCPConnection.h"
00023 #include "TCPSegment.h"
00024 #include "TCPCommand_m.h"
00025 #include "TCPSendQueue.h"
00026 #include "TCPSACKRexmitQueue.h"
00027 #include "TCPReceiveQueue.h"
00028 #include "TCPAlgorithm.h"
00029
00030 bool TCPConnection::tryFastRoute(TCPSegment *tcpseg)
00031 {
00032
00033 return false;
00034 }
00035
00036
00037 void TCPConnection::segmentArrivalWhileClosed(TCPSegment *tcpseg, IPvXAddress srcAddr, IPvXAddress destAddr)
00038 {
00039 tcpEV << "Seg arrived: ";
00040 printSegmentBrief(tcpseg);
00041
00042
00043
00044 ASSERT(state==NULL);
00045 tcpEV << "Segment doesn't belong to any existing connection\n";
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 if (tcpseg->getRstBit())
00065 {
00066 tcpEV << "RST bit set: dropping segment\n";
00067 return;
00068 }
00069
00070 if (!tcpseg->getAckBit())
00071 {
00072 tcpEV << "ACK bit not set: sending RST+ACK\n";
00073 uint32 ackNo = tcpseg->getSequenceNo() + (uint32)tcpseg->getPayloadLength();
00074 sendRstAck(0,ackNo,destAddr,srcAddr,tcpseg->getDestPort(),tcpseg->getSrcPort());
00075 }
00076 else
00077 {
00078 tcpEV << "ACK bit set: sending RST\n";
00079 sendRst(tcpseg->getAckNo(),destAddr,srcAddr,tcpseg->getDestPort(),tcpseg->getSrcPort());
00080 }
00081 }
00082
00083 TCPEventCode TCPConnection::process_RCV_SEGMENT(TCPSegment *tcpseg, IPvXAddress src, IPvXAddress dest)
00084 {
00085 tcpEV << "Seg arrived: ";
00086 printSegmentBrief(tcpseg);
00087 tcpEV << "TCB: " << state->info() << "\n";
00088
00089 if (rcvSeqVector) rcvSeqVector->record(tcpseg->getSequenceNo());
00090 if (rcvAckVector) rcvAckVector->record(tcpseg->getAckNo());
00091
00092
00093
00094
00095
00096 TCPEventCode event;
00097 if (fsm.getState()==TCP_S_LISTEN)
00098 {
00099 event = processSegmentInListen(tcpseg, src, dest);
00100 }
00101 else if (fsm.getState()==TCP_S_SYN_SENT)
00102 {
00103 event = processSegmentInSynSent(tcpseg, src, dest);
00104 }
00105 else
00106 {
00107
00108 event = processSegment1stThru8th(tcpseg);
00109 }
00110 delete tcpseg;
00111 return event;
00112 }
00113
00114 TCPEventCode TCPConnection::processSegment1stThru8th(TCPSegment *tcpseg)
00115 {
00116
00117
00118
00119
00120 bool acceptable = true;
00121
00122 if (tcpseg->getHeaderLength() > TCP_HEADER_OCTETS)
00123 {
00124
00125 if (state->ts_enabled)
00126 {
00127 uint32 tsval = getTSval(tcpseg);
00128
00129 if (tsval != 0 && seqLess(tsval, state->ts_recent) &&
00130 (simTime() - state->time_last_data_sent) > PAWS_IDLE_TIME_THRESH)
00131 {
00132 tcpEV << "PAWS: Segment is not acceptable, TSval=" << tsval << " in " <<
00133 stateName(fsm.getState()) << " state received: dropping segment\n";
00134 acceptable = false;
00135 }
00136 }
00137 readHeaderOptions(tcpseg);
00138 }
00139
00140 if (acceptable)
00141 acceptable = isSegmentAcceptable(tcpseg);
00142
00143 if (!acceptable)
00144 {
00145
00146
00147
00148
00149
00150
00151
00152 if (tcpseg->getRstBit())
00153 {
00154 tcpEV << "RST with unacceptable seqNum: dropping\n";
00155 }
00156 else
00157 {
00158 if (tcpseg->getSynBit())
00159 {
00160 tcpEV << "SYN with unacceptable seqNum in " << stateName(fsm.getState()) << " state received (SYN duplicat?)\n";
00161 }
00162 else if (state->sack_enabled && seqLess((tcpseg->getSequenceNo()+tcpseg->getPayloadLength()), state->rcv_nxt))
00163 {
00164 state->start_seqno = tcpseg->getSequenceNo();
00165 state->end_seqno = tcpseg->getSequenceNo() + tcpseg->getPayloadLength();
00166 state->snd_dsack = true;
00167 tcpEV << "SND_D-SACK SET (dupseg rcvd)\n";
00168 }
00169
00170 tcpEV << "Segment seqNum not acceptable, sending ACK with current receive seq\n";
00171
00172
00173
00174
00175
00176
00177 sendAck();
00178 }
00179 return TCP_E_IGNORE;
00180 }
00181
00182
00183
00184
00185 if (tcpseg->getRstBit())
00186 {
00187
00188 switch (fsm.getState())
00189 {
00190 case TCP_S_SYN_RCVD:
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 return processRstInSynReceived(tcpseg);
00203
00204 case TCP_S_ESTABLISHED:
00205 case TCP_S_FIN_WAIT_1:
00206 case TCP_S_FIN_WAIT_2:
00207 case TCP_S_CLOSE_WAIT:
00208
00209
00210
00211
00212
00213
00214
00215
00216 tcpEV << "RST: performing connection reset, closing connection\n";
00217 sendIndicationToApp(TCP_I_CONNECTION_RESET);
00218 return TCP_E_RCV_RST;
00219
00220 case TCP_S_CLOSING:
00221 case TCP_S_LAST_ACK:
00222 case TCP_S_TIME_WAIT:
00223
00224
00225
00226 tcpEV << "RST: closing connection\n";
00227 if (fsm.getState()!=TCP_S_TIME_WAIT)
00228 sendIndicationToApp(TCP_I_CLOSED);
00229 return TCP_E_RCV_RST;
00230
00231 default: ASSERT(0);
00232 }
00233 }
00234
00235
00236
00237
00238
00239
00240
00241 if (tcpseg->getSynBit())
00242 {
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 ASSERT(isSegmentAcceptable(tcpseg));
00256 tcpEV << "SYN is in the window: performing connection reset, closing connection\n";
00257 sendIndicationToApp(TCP_I_CONNECTION_RESET);
00258 return TCP_E_RCV_UNEXP_SYN;
00259 }
00260
00261
00262
00263
00264 if (!tcpseg->getAckBit())
00265 {
00266
00267 tcpEV << "ACK not set, dropping segment\n";
00268 return TCP_E_IGNORE;
00269 }
00270
00271 uint32 old_snd_una = state->snd_una;
00272
00273 TCPEventCode event = TCP_E_IGNORE;
00274
00275 if (fsm.getState()==TCP_S_SYN_RCVD)
00276 {
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 if (!seqLE(state->snd_una,tcpseg->getAckNo()) || !seqLE(tcpseg->getAckNo(),state->snd_nxt))
00289 {
00290 sendRst(tcpseg->getAckNo());
00291 return TCP_E_IGNORE;
00292 }
00293
00294
00295 tcpAlgorithm->established(false);
00296 sendEstabIndicationToApp();
00297
00298
00299
00300 event = TCP_E_RCV_ACK;
00301 }
00302
00303 uint32 old_snd_nxt = state->snd_nxt;
00304
00305
00306
00307
00308
00309
00310 if (fsm.getState()==TCP_S_SYN_RCVD || fsm.getState()==TCP_S_ESTABLISHED ||
00311 fsm.getState()==TCP_S_FIN_WAIT_1 || fsm.getState()==TCP_S_FIN_WAIT_2 ||
00312 fsm.getState()==TCP_S_CLOSE_WAIT || fsm.getState()==TCP_S_CLOSING || fsm.getState()==TCP_S_LAST_ACK)
00313 {
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 bool ok = processAckInEstabEtc(tcpseg);
00339 if (!ok)
00340 return TCP_E_IGNORE;
00341 }
00342
00343 if ((fsm.getState()==TCP_S_FIN_WAIT_1 && state->fin_ack_rcvd))
00344 {
00345
00346
00347
00348
00349
00350
00351 event = TCP_E_RCV_ACK;
00352 }
00353
00354 if (fsm.getState()==TCP_S_FIN_WAIT_2)
00355 {
00356
00357
00358
00359
00360
00361
00362
00363
00364 }
00365
00366 if (fsm.getState()==TCP_S_CLOSING)
00367 {
00368
00369
00370
00371
00372
00373 if (state->fin_ack_rcvd)
00374 {
00375 tcpEV << "Our FIN acked -- can go to TIME_WAIT now\n";
00376 event = TCP_E_RCV_ACK;
00377 scheduleTimeout(the2MSLTimer, TCP_TIMEOUT_2MSL);
00378
00379
00380
00381 sendIndicationToApp(TCP_I_CLOSED);
00382 }
00383 }
00384
00385 if (fsm.getState()==TCP_S_LAST_ACK)
00386 {
00387
00388
00389
00390
00391
00392 if (state->send_fin && tcpseg->getAckNo()==state->snd_fin_seq+1)
00393 {
00394 tcpEV << "Last ACK arrived\n";
00395 sendIndicationToApp(TCP_I_CLOSED);
00396 return TCP_E_RCV_ACK;
00397 }
00398 }
00399
00400 if (fsm.getState()==TCP_S_TIME_WAIT)
00401 {
00402
00403
00404
00405
00406
00407
00408
00409 sendAck();
00410 cancelEvent(the2MSLTimer);
00411 scheduleTimeout(the2MSLTimer, TCP_TIMEOUT_2MSL);
00412 }
00413
00414
00415
00416
00417 if (tcpseg->getUrgBit() && (fsm.getState()==TCP_S_ESTABLISHED ||
00418 fsm.getState()==TCP_S_FIN_WAIT_1 || fsm.getState()==TCP_S_FIN_WAIT_2))
00419 {
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 }
00431
00432
00433
00434
00435 uint32 old_rcv_nxt = state->rcv_nxt;
00436 if (fsm.getState()==TCP_S_SYN_RCVD || fsm.getState()==TCP_S_ESTABLISHED ||
00437 fsm.getState()==TCP_S_FIN_WAIT_1 || fsm.getState()==TCP_S_FIN_WAIT_2)
00438 {
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 tcpseg->truncateSegment(state->rcv_nxt, state->rcv_nxt + state->rcv_wnd);
00466
00467 if (tcpseg->getPayloadLength()>0)
00468 {
00469
00470 if (tcpseg->getPayloadLength() == state->snd_mss || tcpseg->getPayloadLength() + tcpseg->getHeaderLength() - TCP_HEADER_OCTETS == state->snd_mss)
00471 state->full_sized_segment_counter++;
00472
00473 if (tcpseg->getPayloadLength() == 1)
00474 state->ack_now = true;
00475
00476 updateRcvQueueVars();
00477 if (state->freeRcvBuffer >= tcpseg->getPayloadLength())
00478 {
00479 tcpEV2 << "Processing segment text in a data transfer state\n";
00480
00481
00482
00483
00484
00485
00486
00487 uint32 old_usedRcvBuffer = state->usedRcvBuffer;
00488 state->rcv_nxt = receiveQueue->insertBytesFromSegment(tcpseg);
00489
00490 if (seqGreater(state->snd_una, old_snd_una))
00491 {
00492
00493 tcpAlgorithm->receivedDataAck(old_snd_una);
00494
00495
00496 state->dupacks = 0;
00497 if (dupAcksVector)
00498 dupAcksVector->record(state->dupacks);
00499 }
00500
00501
00502 if (old_rcv_nxt==state->rcv_nxt)
00503 {
00504 state->rcv_oooseg++;
00505 if (rcvOooSegVector)
00506 rcvOooSegVector->record(state->rcv_oooseg);
00507
00508
00509
00510
00511
00512 if (state->sack_enabled)
00513 {
00514
00515 state->start_seqno = tcpseg->getSequenceNo();
00516 state->end_seqno = tcpseg->getSequenceNo() + tcpseg->getPayloadLength();
00517
00518 if (old_usedRcvBuffer == receiveQueue->getAmountOfBufferedBytes())
00519 {
00520 state->snd_dsack = true;
00521 tcpEV << "SND_D-SACK SET (old_rcv_nxt==rcv_nxt duplicated oooseg rcvd)\n";
00522 }
00523 else
00524 {
00525 state->snd_sack = true;
00526 tcpEV << "SND_SACK SET (old_rcv_nxt==rcv_nxt oooseg rcvd)\n";
00527 }
00528 }
00529 tcpAlgorithm->receivedOutOfOrderSegment();
00530 }
00531 else
00532 {
00533
00534
00535
00536
00537
00538
00539
00540
00541 cPacket *msg;
00542 while ((msg=receiveQueue->extractBytesUpTo(state->rcv_nxt))!=NULL)
00543 {
00544 msg->setKind(TCP_I_DATA);
00545 TCPCommand *cmd = new TCPCommand();
00546 cmd->setConnId(connId);
00547 msg->setControlInfo(cmd);
00548 sendToApp(msg);
00549 }
00550
00551
00552
00553
00554 if (state->fin_rcvd && state->rcv_nxt==state->rcv_fin_seq)
00555 {
00556 state->ack_now = true;
00557 tcpEV << "All segments arrived up to the FIN segment, advancing rcv_nxt over the FIN\n";
00558 state->rcv_nxt = state->rcv_fin_seq+1;
00559
00560
00561 event = TCP_E_RCV_FIN;
00562 switch (fsm.getState())
00563 {
00564 case TCP_S_FIN_WAIT_1:
00565 if (state->fin_ack_rcvd)
00566 {
00567 event = TCP_E_RCV_FIN_ACK;
00568
00569 cancelEvent(finWait2Timer);
00570 scheduleTimeout(the2MSLTimer, TCP_TIMEOUT_2MSL);
00571
00572
00573
00574 sendIndicationToApp(TCP_I_CLOSED);
00575 }
00576 break;
00577 case TCP_S_FIN_WAIT_2:
00578
00579 cancelEvent(finWait2Timer);
00580 scheduleTimeout(the2MSLTimer, TCP_TIMEOUT_2MSL);
00581
00582
00583
00584 sendIndicationToApp(TCP_I_CLOSED);
00585 break;
00586 case TCP_S_TIME_WAIT:
00587
00588 cancelEvent(the2MSLTimer);
00589 scheduleTimeout(the2MSLTimer, TCP_TIMEOUT_2MSL);
00590 break;
00591 }
00592 sendIndicationToApp(TCP_I_PEER_CLOSED);
00593 }
00594 }
00595 }
00596 else
00597 {
00598 state->tcpRcvQueueDrops++;
00599 if (tcpRcvQueueDropsVector)
00600 tcpRcvQueueDropsVector->record(state->tcpRcvQueueDrops);
00601
00602
00603 tcpEV << "RcvQueueBuffer has run out, dropping segment\n";
00604 return TCP_E_IGNORE;
00605 }
00606 }
00607 }
00608
00609
00610
00611
00612 if (tcpseg->getFinBit())
00613 {
00614 state->ack_now = true;
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628 uint32 fin_seq = (uint32)tcpseg->getSequenceNo() + (uint32)tcpseg->getPayloadLength();
00629 if (state->rcv_nxt==fin_seq)
00630 {
00631
00632 tcpEV << "FIN arrived, advancing rcv_nxt over the FIN\n";
00633 state->rcv_nxt++;
00634
00635
00636 event = TCP_E_RCV_FIN;
00637 switch (fsm.getState())
00638 {
00639 case TCP_S_FIN_WAIT_1:
00640 if (state->fin_ack_rcvd)
00641 {
00642 event = TCP_E_RCV_FIN_ACK;
00643
00644 cancelEvent(finWait2Timer);
00645 scheduleTimeout(the2MSLTimer, TCP_TIMEOUT_2MSL);
00646
00647
00648
00649 sendIndicationToApp(TCP_I_CLOSED);
00650 }
00651 break;
00652 case TCP_S_FIN_WAIT_2:
00653
00654 cancelEvent(finWait2Timer);
00655 scheduleTimeout(the2MSLTimer, TCP_TIMEOUT_2MSL);
00656
00657
00658
00659 sendIndicationToApp(TCP_I_CLOSED);
00660 break;
00661 case TCP_S_TIME_WAIT:
00662
00663 cancelEvent(the2MSLTimer);
00664 scheduleTimeout(the2MSLTimer, TCP_TIMEOUT_2MSL);
00665 break;
00666 }
00667 sendIndicationToApp(TCP_I_PEER_CLOSED);
00668 }
00669 else
00670 {
00671
00672 tcpEV << "FIN segment above sequence, storing sequence number of FIN\n";
00673 state->fin_rcvd = true;
00674 state->rcv_fin_seq = fin_seq;
00675 }
00676
00677
00678 }
00679
00680 if (old_rcv_nxt!=state->rcv_nxt)
00681 {
00682
00683
00684
00685
00686 if (state->sack_enabled)
00687 {
00688 if (receiveQueue->getQueueLength()!=0)
00689 {
00690
00691
00692
00693 state->start_seqno = tcpseg->getSequenceNo();
00694 state->end_seqno = tcpseg->getSequenceNo() + tcpseg->getPayloadLength();
00695 state->snd_sack = true;
00696 tcpEV << "SND_SACK SET (rcv_nxt changed, but rexmitQ is not empty)\n";
00697 state->ack_now = true;
00698 }
00699 }
00700
00701
00702 tcpAlgorithm->receiveSeqChanged();
00703 }
00704
00705 if ((fsm.getState()==TCP_S_ESTABLISHED || fsm.getState()==TCP_S_SYN_RCVD) &&
00706 state->send_fin && state->snd_nxt==state->snd_fin_seq+1)
00707 {
00708
00709
00710
00711
00712 tcpEV << "Now we can do the CLOSE which was deferred a while ago\n";
00713 event = TCP_E_CLOSE;
00714 }
00715
00716 if (fsm.getState()==TCP_S_CLOSE_WAIT && state->send_fin &&
00717 state->snd_nxt==state->snd_fin_seq+1 && old_snd_nxt!=state->snd_nxt)
00718 {
00719
00720
00721
00722
00723 tcpEV << "Now we can do the CLOSE which was deferred a while ago\n";
00724 event = TCP_E_CLOSE;
00725 }
00726
00727 return event;
00728 }
00729
00730
00731
00732 TCPEventCode TCPConnection::processSegmentInListen(TCPSegment *tcpseg, IPvXAddress srcAddr, IPvXAddress destAddr)
00733 {
00734 tcpEV2 << "Processing segment in LISTEN\n";
00735
00736
00737
00738
00739
00740 if (tcpseg->getRstBit())
00741 {
00742 tcpEV << "RST bit set: dropping segment\n";
00743 return TCP_E_IGNORE;
00744 }
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757 if (tcpseg->getAckBit())
00758 {
00759 tcpEV << "ACK bit set: dropping segment and sending RST\n";
00760 sendRst(tcpseg->getAckNo(),destAddr,srcAddr,tcpseg->getDestPort(),tcpseg->getSrcPort());
00761 return TCP_E_IGNORE;
00762 }
00763
00764
00765
00766
00767 if (tcpseg->getSynBit())
00768 {
00769 if (tcpseg->getFinBit())
00770 {
00771
00772
00773
00774 tcpEV << "SYN+FIN received: ignoring FIN\n";
00775 }
00776
00777 tcpEV << "SYN bit set: filling in foreign socket and sending SYN+ACK\n";
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787 if (state->fork)
00788 {
00789 TCPConnection *conn = cloneListeningConnection();
00790 tcpMain->addForkedConnection(this, conn, destAddr, srcAddr, tcpseg->getDestPort(), tcpseg->getSrcPort());
00791 tcpEV << "Connection forked: this connection got new connId=" << connId << ", "
00792 "spinoff keeps LISTENing with connId=" << conn->connId << "\n";
00793 }
00794 else
00795 {
00796 tcpMain->updateSockPair(this, destAddr, srcAddr, tcpseg->getDestPort(), tcpseg->getSrcPort());
00797 }
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809 state->rcv_nxt = tcpseg->getSequenceNo()+1;
00810 state->rcv_adv = state->rcv_nxt + state->rcv_wnd;
00811 if (rcvAdvVector) rcvAdvVector->record(state->rcv_adv);
00812 state->irs = tcpseg->getSequenceNo();
00813 receiveQueue->init(state->rcv_nxt);
00814 selectInitialSeqNum();
00815
00816
00817
00818 updateWndInfo(tcpseg, true);
00819
00820 if (tcpseg->getHeaderLength() > TCP_HEADER_OCTETS)
00821 readHeaderOptions(tcpseg);
00822
00823 state->ack_now = true;
00824 sendSynAck();
00825 startSynRexmitTimer();
00826 if (!connEstabTimer->isScheduled())
00827 scheduleTimeout(connEstabTimer, TCP_TIMEOUT_CONN_ESTAB);
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838 if (tcpseg->getPayloadLength()>0)
00839 {
00840 updateRcvQueueVars();
00841 if (state->freeRcvBuffer >= tcpseg->getPayloadLength())
00842 {
00843 receiveQueue->insertBytesFromSegment(tcpseg);
00844 }
00845 else
00846 {
00847 state->tcpRcvQueueDrops++;
00848 if (tcpRcvQueueDropsVector)
00849 tcpRcvQueueDropsVector->record(state->tcpRcvQueueDrops);
00850
00851 tcpEV << "RcvQueueBuffer has run out, dropping segment\n";
00852 return TCP_E_IGNORE;
00853 }
00854 }
00855 if (tcpseg->getUrgBit() || tcpseg->getPshBit())
00856 tcpEV << "Ignoring URG and PSH bits in SYN\n";
00857
00858 return TCP_E_RCV_SYN;
00859 }
00860
00861
00862
00863
00864
00865 tcpEV << "Unexpected segment: dropping it\n";
00866 return TCP_E_IGNORE;
00867 }
00868
00869 TCPEventCode TCPConnection::processSegmentInSynSent(TCPSegment *tcpseg, IPvXAddress srcAddr, IPvXAddress destAddr)
00870 {
00871 tcpEV2 << "Processing segment in SYN_SENT\n";
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887 if (tcpseg->getAckBit())
00888 {
00889 if (seqLE(tcpseg->getAckNo(),state->iss) || seqGreater(tcpseg->getAckNo(),state->snd_nxt))
00890 {
00891 tcpEV << "ACK bit set but wrong AckNo, sending RST\n";
00892 sendRst(tcpseg->getAckNo(),destAddr,srcAddr,tcpseg->getDestPort(),tcpseg->getSrcPort());
00893 return TCP_E_IGNORE;
00894 }
00895 tcpEV << "ACK bit set, AckNo acceptable\n";
00896 }
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908 if (tcpseg->getRstBit())
00909 {
00910 if (tcpseg->getAckBit())
00911 {
00912 tcpEV << "RST+ACK: performing connection reset\n";
00913 sendIndicationToApp(TCP_I_CONNECTION_RESET);
00914 return TCP_E_RCV_RST;
00915 }
00916 else
00917 {
00918 tcpEV << "RST without ACK: dropping segment\n";
00919 return TCP_E_IGNORE;
00920 }
00921 }
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934 if (tcpseg->getSynBit())
00935 {
00936
00937
00938
00939
00940
00941
00942 state->rcv_nxt = tcpseg->getSequenceNo()+1;
00943 state->rcv_adv = state->rcv_nxt + state->rcv_wnd;
00944 if (rcvAdvVector) rcvAdvVector->record(state->rcv_adv);
00945 state->irs = tcpseg->getSequenceNo();
00946 receiveQueue->init(state->rcv_nxt);
00947
00948 if (tcpseg->getAckBit())
00949 {
00950 state->snd_una = tcpseg->getAckNo();
00951 sendQueue->discardUpTo(state->snd_una);
00952 if (state->sack_enabled)
00953 rexmitQueue->discardUpTo(state->snd_una);
00954
00955
00956
00957 updateWndInfo(tcpseg, true);
00958 }
00959
00960
00961
00962 tcpMain->updateSockPair(this, destAddr, srcAddr, tcpseg->getDestPort(), tcpseg->getSrcPort());
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975 if (seqGreater(state->snd_una, state->iss))
00976 {
00977 tcpEV << "SYN+ACK bits set, connection established.\n";
00978
00979
00980
00981
00982
00983
00984
00985 if (tcpseg->getFinBit())
00986 tcpEV << "SYN+ACK+FIN received: ignoring FIN\n";
00987 if (tcpseg->getPayloadLength()>0)
00988 {
00989 updateRcvQueueVars();
00990 if (state->freeRcvBuffer >= tcpseg->getPayloadLength())
00991 {
00992 receiveQueue->insertBytesFromSegment(tcpseg);
00993 }
00994 else
00995 {
00996 state->tcpRcvQueueDrops++;
00997 if (tcpRcvQueueDropsVector)
00998 tcpRcvQueueDropsVector->record(state->tcpRcvQueueDrops);
00999
01000 tcpEV << "RcvQueueBuffer has run out, dropping segment\n";
01001 return TCP_E_IGNORE;
01002 }
01003 }
01004 if (tcpseg->getUrgBit() || tcpseg->getPshBit())
01005 tcpEV << "Ignoring URG and PSH bits in SYN+ACK\n";
01006
01007 if (tcpseg->getHeaderLength() > TCP_HEADER_OCTETS)
01008 readHeaderOptions(tcpseg);
01009
01010
01011 state->ack_now = true;
01012 tcpAlgorithm->established(true);
01013 sendEstabIndicationToApp();
01014
01015
01016
01017 return TCP_E_RCV_SYN_ACK;
01018 }
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029 tcpEV << "SYN bit set: sending SYN+ACK\n";
01030 state->snd_max = state->snd_nxt = state->iss;
01031 sendSynAck();
01032 startSynRexmitTimer();
01033
01034
01035
01036
01037 if (tcpseg->getFinBit())
01038 tcpEV << "SYN+FIN received: ignoring FIN\n";
01039
01040
01041
01042
01043 if (tcpseg->getPayloadLength()>0)
01044 {
01045 updateRcvQueueVars();
01046 if (state->freeRcvBuffer >= tcpseg->getPayloadLength())
01047 {
01048 receiveQueue->insertBytesFromSegment(tcpseg);
01049 }
01050 else
01051 {
01052 state->tcpRcvQueueDrops++;
01053 if (tcpRcvQueueDropsVector)
01054 tcpRcvQueueDropsVector->record(state->tcpRcvQueueDrops);
01055
01056 tcpEV << "RcvQueueBuffer has run out, dropping segment\n";
01057 return TCP_E_IGNORE;
01058 }
01059 }
01060 if (tcpseg->getUrgBit() || tcpseg->getPshBit())
01061 tcpEV << "Ignoring URG and PSH bits in SYN\n";
01062
01063 return TCP_E_RCV_SYN;
01064 }
01065
01066
01067
01068
01069
01070 return TCP_E_IGNORE;
01071 }
01072
01073 TCPEventCode TCPConnection::processRstInSynReceived(TCPSegment *tcpseg)
01074 {
01075 tcpEV2 << "Processing RST in SYN_RCVD\n";
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089 sendQueue->discardUpTo(sendQueue->getBufferEndSeq());
01090 if (state->sack_enabled)
01091 rexmitQueue->discardUpTo(rexmitQueue->getBufferEndSeq());
01092
01093 if (state->active)
01094 {
01095
01096 sendIndicationToApp(TCP_I_CONNECTION_REFUSED);
01097 }
01098
01099
01100
01101 return TCP_E_RCV_RST;
01102 }
01103
01104 bool TCPConnection::processAckInEstabEtc(TCPSegment *tcpseg)
01105 {
01106 tcpEV2 << "Processing ACK in a data transfer state\n";
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133 if (seqGE(state->snd_una, tcpseg->getAckNo()))
01134 {
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146 if (state->snd_una==tcpseg->getAckNo() && tcpseg->getPayloadLength()==0 && state->snd_una!=state->snd_max)
01147 {
01148 state->dupacks++;
01149 if (dupAcksVector)
01150 dupAcksVector->record(state->dupacks);
01151
01152
01153
01154 updateWndInfo(tcpseg);
01155
01156 tcpAlgorithm->receivedDuplicateAck();
01157 }
01158 else
01159 {
01160
01161 if (tcpseg->getPayloadLength()==0)
01162 {
01163 if (state->snd_una!=tcpseg->getAckNo())
01164 tcpEV << "Old ACK: ackNo<snd_una\n";
01165 else if (state->snd_una==state->snd_max)
01166 tcpEV << "ACK looks duplicate but we have currently no unacked data (snd_una==snd_max)\n";
01167 }
01168
01169
01170 state->dupacks = 0;
01171 if (dupAcksVector)
01172 dupAcksVector->record(state->dupacks);
01173 }
01174 }
01175 else if (seqLE(tcpseg->getAckNo(), state->snd_max))
01176 {
01177
01178 uint32 old_snd_una = state->snd_una;
01179 state->snd_una = tcpseg->getAckNo();
01180 if (unackedVector) unackedVector->record(state->snd_max - state->snd_una);
01181
01182
01183 if (seqLess(state->snd_nxt, state->snd_una))
01184 state->snd_nxt = state->snd_una;
01185
01186
01187
01188
01189
01190
01191
01192
01193 if (state->ts_enabled)
01194 tcpAlgorithm->rttMeasurementCompleteUsingTS(getTSecr(tcpseg));
01195
01196
01197 uint32 discardUpToSeq = state->snd_una;
01198
01199
01200 if (state->send_fin && tcpseg->getAckNo()==state->snd_fin_seq+1)
01201 {
01202
01203 tcpEV << "ACK acks our FIN\n";
01204 state->fin_ack_rcvd = true;
01205 discardUpToSeq--;
01206 }
01207
01208
01209 sendQueue->discardUpTo(discardUpToSeq);
01210
01211 if (state->sack_enabled)
01212 rexmitQueue->discardUpTo(discardUpToSeq);
01213
01214 updateWndInfo(tcpseg);
01215
01216
01217
01218 if (tcpseg->getPayloadLength() == 0 && fsm.getState()!=TCP_S_SYN_RCVD)
01219 {
01220
01221 tcpAlgorithm->receivedDataAck(old_snd_una);
01222
01223
01224 state->dupacks = 0;
01225 if (dupAcksVector)
01226 dupAcksVector->record(state->dupacks);
01227 }
01228 }
01229 else
01230 {
01231 ASSERT(seqGreater(tcpseg->getAckNo(), state->snd_max));
01232
01233
01234 tcpAlgorithm->receivedAckForDataNotYetSent(tcpseg->getAckNo());
01235 state->dupacks = 0;
01236 if (dupAcksVector)
01237 dupAcksVector->record(state->dupacks);
01238 return false;
01239 }
01240
01241 return true;
01242 }
01243
01244
01245
01246 void TCPConnection::process_TIMEOUT_CONN_ESTAB()
01247 {
01248 switch(fsm.getState())
01249 {
01250 case TCP_S_SYN_RCVD:
01251 case TCP_S_SYN_SENT:
01252
01253
01254 if (state->active)
01255 {
01256
01257 sendIndicationToApp(TCP_I_TIMED_OUT);
01258 }
01259 break;
01260 default:
01261
01262 opp_error("Internal error: received CONN_ESTAB timeout in state %s", stateName(fsm.getState()));
01263 }
01264 }
01265
01266 void TCPConnection::process_TIMEOUT_2MSL()
01267 {
01268
01269
01270
01271
01272 switch(fsm.getState())
01273 {
01274 case TCP_S_TIME_WAIT:
01275
01276
01277
01278
01279 break;
01280 default:
01281
01282 opp_error("Internal error: received time-wait (2MSL) timeout in state %s", stateName(fsm.getState()));
01283 }
01284 }
01285
01286 void TCPConnection::process_TIMEOUT_FIN_WAIT_2()
01287 {
01288 switch(fsm.getState())
01289 {
01290 case TCP_S_FIN_WAIT_2:
01291
01292
01293 sendIndicationToApp(TCP_I_CLOSED);
01294 break;
01295 default:
01296
01297 opp_error("Internal error: received FIN_WAIT_2 timeout in state %s", stateName(fsm.getState()));
01298 }
01299 }
01300
01301 void TCPConnection::startSynRexmitTimer()
01302 {
01303 state->syn_rexmit_count = 0;
01304 state->syn_rexmit_timeout = TCP_TIMEOUT_SYN_REXMIT;
01305
01306 if (synRexmitTimer->isScheduled())
01307 cancelEvent(synRexmitTimer);
01308 scheduleTimeout(synRexmitTimer, state->syn_rexmit_timeout);
01309 }
01310
01311 void TCPConnection::process_TIMEOUT_SYN_REXMIT(TCPEventCode& event)
01312 {
01313 if (++state->syn_rexmit_count>MAX_SYN_REXMIT_COUNT)
01314 {
01315 tcpEV << "Retransmission count during connection setup exceeds " << MAX_SYN_REXMIT_COUNT << ", giving up\n";
01316
01317 event = TCP_E_ABORT;
01318 return;
01319 }
01320
01321 tcpEV << "Performing retransmission #" << state->syn_rexmit_count << "\n";
01322
01323
01324 switch(fsm.getState())
01325 {
01326 case TCP_S_SYN_SENT: sendSyn(); break;
01327 case TCP_S_SYN_RCVD: sendSynAck(); break;
01328 default: opp_error("Internal error: SYN-REXMIT timer expired while in state %s", stateName(fsm.getState()));
01329 }
01330
01331
01332 state->syn_rexmit_timeout *= 2;
01333
01334 if (state->syn_rexmit_timeout > TCP_TIMEOUT_SYN_REXMIT_MAX)
01335 state->syn_rexmit_timeout = TCP_TIMEOUT_SYN_REXMIT_MAX;
01336 scheduleTimeout(synRexmitTimer, state->syn_rexmit_timeout);
01337 }
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349