00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <string.h>
00020 #include "TCP_old.h"
00021 #include "TCPConnection_old.h"
00022 #include "TCPSegment.h"
00023 #include "TCPCommand_m.h"
00024 #include "TCPSendQueue_old.h"
00025 #include "TCPReceiveQueue_old.h"
00026 #include "TCPAlgorithm_old.h"
00027
00028 using namespace tcp_old;
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 bool acceptable = isSegmentAcceptable(tcpseg);
00120 if (!acceptable)
00121 {
00122
00123
00124
00125
00126
00127
00128
00129 if (tcpseg->getRstBit())
00130 {
00131 tcpEV << "RST with unacceptable seqNum: dropping\n";
00132 }
00133 else
00134 {
00135 tcpEV << "Segment seqNum not acceptable, sending ACK with current receive seq\n";
00136 sendAck();
00137 }
00138 return TCP_E_IGNORE;
00139 }
00140
00141
00142
00143
00144 if (tcpseg->getRstBit())
00145 {
00146
00147 switch (fsm.getState())
00148 {
00149 case TCP_S_SYN_RCVD:
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 return processRstInSynReceived(tcpseg);
00162
00163 case TCP_S_ESTABLISHED:
00164 case TCP_S_FIN_WAIT_1:
00165 case TCP_S_FIN_WAIT_2:
00166 case TCP_S_CLOSE_WAIT:
00167
00168
00169
00170
00171
00172
00173
00174
00175 tcpEV << "RST: performing connection reset, closing connection\n";
00176 sendIndicationToApp(TCP_I_CONNECTION_RESET);
00177 return TCP_E_RCV_RST;
00178
00179 case TCP_S_CLOSING:
00180 case TCP_S_LAST_ACK:
00181 case TCP_S_TIME_WAIT:
00182
00183
00184
00185 tcpEV << "RST: closing connection\n";
00186 if (fsm.getState()!=TCP_S_TIME_WAIT)
00187 sendIndicationToApp(TCP_I_CLOSED);
00188 return TCP_E_RCV_RST;
00189
00190 default: ASSERT(0);
00191 }
00192 }
00193
00194
00195
00196
00197
00198
00199
00200 if (tcpseg->getSynBit())
00201 {
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 ASSERT(isSegmentAcceptable(tcpseg));
00215 tcpEV << "SYN is in the window: performing connection reset, closing connection\n";
00216 sendIndicationToApp(TCP_I_CONNECTION_RESET);
00217 return TCP_E_RCV_UNEXP_SYN;
00218 }
00219
00220
00221
00222
00223 if (!tcpseg->getAckBit())
00224 {
00225
00226 tcpEV << "ACK not set, dropping segment\n";
00227 return TCP_E_IGNORE;
00228 }
00229
00230 uint32 old_snd_una = state->snd_una;
00231
00232 TCPEventCode event = TCP_E_IGNORE;
00233
00234 if (fsm.getState()==TCP_S_SYN_RCVD)
00235 {
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 if (!seqLE(state->snd_una,tcpseg->getAckNo()) || !seqLE(tcpseg->getAckNo(),state->snd_nxt))
00248 {
00249 sendRst(tcpseg->getAckNo());
00250 return TCP_E_IGNORE;
00251 }
00252
00253
00254 tcpAlgorithm->established(false);
00255 sendEstabIndicationToApp();
00256
00257
00258
00259 event = TCP_E_RCV_ACK;
00260 }
00261
00262 uint32 old_snd_nxt = state->snd_nxt;
00263
00264
00265
00266
00267
00268
00269 if (fsm.getState()==TCP_S_SYN_RCVD || fsm.getState()==TCP_S_ESTABLISHED ||
00270 fsm.getState()==TCP_S_FIN_WAIT_1 || fsm.getState()==TCP_S_FIN_WAIT_2 ||
00271 fsm.getState()==TCP_S_CLOSE_WAIT || fsm.getState()==TCP_S_CLOSING || fsm.getState()==TCP_S_LAST_ACK)
00272 {
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 bool ok = processAckInEstabEtc(tcpseg);
00298 if (!ok)
00299 return TCP_E_IGNORE;
00300 }
00301
00302 if ((fsm.getState()==TCP_S_FIN_WAIT_1 && state->fin_ack_rcvd))
00303 {
00304
00305
00306
00307
00308
00309
00310 event = TCP_E_RCV_ACK;
00311 }
00312
00313 if (fsm.getState()==TCP_S_FIN_WAIT_2)
00314 {
00315
00316
00317
00318
00319
00320
00321
00322
00323 }
00324
00325 if (fsm.getState()==TCP_S_CLOSING)
00326 {
00327
00328
00329
00330
00331
00332 if (state->fin_ack_rcvd)
00333 {
00334 tcpEV << "Our FIN acked -- can go to TIME_WAIT now\n";
00335 event = TCP_E_RCV_ACK;
00336 scheduleTimeout(the2MSLTimer, TCP_TIMEOUT_2MSL);
00337
00338
00339
00340 sendIndicationToApp(TCP_I_CLOSED);
00341 }
00342 }
00343
00344 if (fsm.getState()==TCP_S_LAST_ACK)
00345 {
00346
00347
00348
00349
00350
00351 if (state->send_fin && tcpseg->getAckNo()==state->snd_fin_seq+1)
00352 {
00353 tcpEV << "Last ACK arrived\n";
00354 sendIndicationToApp(TCP_I_CLOSED);
00355 return TCP_E_RCV_ACK;
00356 }
00357 }
00358
00359 if (fsm.getState()==TCP_S_TIME_WAIT)
00360 {
00361
00362
00363
00364
00365
00366
00367
00368 sendAck();
00369 cancelEvent(the2MSLTimer);
00370 scheduleTimeout(the2MSLTimer, TCP_TIMEOUT_2MSL);
00371 }
00372
00373
00374
00375
00376 if (tcpseg->getUrgBit() && (fsm.getState()==TCP_S_ESTABLISHED || fsm.getState()==TCP_S_FIN_WAIT_1 ||
00377 fsm.getState()==TCP_S_FIN_WAIT_2))
00378 {
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 }
00390
00391
00392
00393
00394 uint32 old_rcv_nxt = state->rcv_nxt;
00395 if (fsm.getState()==TCP_S_SYN_RCVD || fsm.getState()==TCP_S_ESTABLISHED || fsm.getState()==TCP_S_FIN_WAIT_1 || fsm.getState()==TCP_S_FIN_WAIT_2)
00396 {
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 if (tcpseg->getPayloadLength()>0)
00423 {
00424 tcpEV2 << "Processing segment text in a data transfer state\n";
00425
00426
00427
00428
00429
00430
00431 uint32 old_rcv_nxt = state->rcv_nxt;
00432 state->rcv_nxt = receiveQueue->insertBytesFromSegment(tcpseg);
00433
00434 if (seqGreater(state->snd_una, old_snd_una))
00435 {
00436
00437 tcpAlgorithm->receivedDataAck(old_snd_una);
00438
00439
00440 state->dupacks = 0;
00441 }
00442
00443
00444 if (old_rcv_nxt==state->rcv_nxt)
00445 {
00446
00447 tcpAlgorithm->receivedOutOfOrderSegment();
00448 }
00449 else
00450 {
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 cPacket *msg;
00461 while ((msg=receiveQueue->extractBytesUpTo(state->rcv_nxt))!=NULL)
00462 {
00463 msg->setKind(TCP_I_DATA);
00464 TCPCommand *cmd = new TCPCommand();
00465 cmd->setConnId(connId);
00466 msg->setControlInfo(cmd);
00467 sendToApp(msg);
00468 }
00469
00470
00471
00472
00473 if (state->fin_rcvd && state->rcv_nxt==state->rcv_fin_seq)
00474 {
00475 tcpEV << "All segments arrived up to the FIN segment, advancing rcv_nxt over the FIN\n";
00476 state->rcv_nxt = state->rcv_fin_seq+1;
00477
00478
00479 event = TCP_E_RCV_FIN;
00480 switch (fsm.getState())
00481 {
00482 case TCP_S_FIN_WAIT_1:
00483 if (state->fin_ack_rcvd)
00484 {
00485 event = TCP_E_RCV_FIN_ACK;
00486
00487 cancelEvent(finWait2Timer);
00488 scheduleTimeout(the2MSLTimer, TCP_TIMEOUT_2MSL);
00489
00490
00491
00492 sendIndicationToApp(TCP_I_CLOSED);
00493 }
00494 break;
00495 case TCP_S_FIN_WAIT_2:
00496
00497 cancelEvent(finWait2Timer);
00498 scheduleTimeout(the2MSLTimer, TCP_TIMEOUT_2MSL);
00499
00500
00501
00502 sendIndicationToApp(TCP_I_CLOSED);
00503 break;
00504 case TCP_S_TIME_WAIT:
00505
00506 cancelEvent(the2MSLTimer);
00507 scheduleTimeout(the2MSLTimer, TCP_TIMEOUT_2MSL);
00508 break;
00509 }
00510 sendIndicationToApp(TCP_I_PEER_CLOSED);
00511 }
00512 }
00513 }
00514 }
00515
00516
00517
00518
00519 if (tcpseg->getFinBit())
00520 {
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 uint32 fin_seq = (uint32)tcpseg->getSequenceNo() + (uint32)tcpseg->getPayloadLength();
00534 if (state->rcv_nxt==fin_seq)
00535 {
00536
00537 tcpEV << "FIN arrived, advancing rcv_nxt over the FIN\n";
00538 state->rcv_nxt++;
00539
00540
00541 event = TCP_E_RCV_FIN;
00542 switch (fsm.getState())
00543 {
00544 case TCP_S_FIN_WAIT_1:
00545 if (state->fin_ack_rcvd)
00546 {
00547 event = TCP_E_RCV_FIN_ACK;
00548
00549 cancelEvent(finWait2Timer);
00550 scheduleTimeout(the2MSLTimer, TCP_TIMEOUT_2MSL);
00551
00552
00553
00554 sendIndicationToApp(TCP_I_CLOSED);
00555 }
00556 break;
00557 case TCP_S_FIN_WAIT_2:
00558
00559 cancelEvent(finWait2Timer);
00560 scheduleTimeout(the2MSLTimer, TCP_TIMEOUT_2MSL);
00561
00562
00563
00564 sendIndicationToApp(TCP_I_CLOSED);
00565 break;
00566 case TCP_S_TIME_WAIT:
00567
00568 cancelEvent(the2MSLTimer);
00569 scheduleTimeout(the2MSLTimer, TCP_TIMEOUT_2MSL);
00570 break;
00571 }
00572 sendIndicationToApp(TCP_I_PEER_CLOSED);
00573 }
00574 else
00575 {
00576
00577 tcpEV << "FIN segment above sequence, storing sequence number of FIN\n";
00578 state->fin_rcvd = true;
00579 state->rcv_fin_seq = fin_seq;
00580 }
00581
00582
00583 }
00584
00585 if (old_rcv_nxt!=state->rcv_nxt)
00586 {
00587
00588
00589
00590
00591
00592 tcpAlgorithm->receiveSeqChanged();
00593 }
00594
00595 if ((fsm.getState()==TCP_S_ESTABLISHED || fsm.getState()==TCP_S_SYN_RCVD) &&
00596 state->send_fin && state->snd_nxt==state->snd_fin_seq+1)
00597 {
00598
00599
00600
00601
00602 tcpEV << "Now we can do the CLOSE which was deferred a while ago\n";
00603 event = TCP_E_CLOSE;
00604 }
00605
00606 if (fsm.getState()==TCP_S_CLOSE_WAIT && state->send_fin &&
00607 state->snd_nxt==state->snd_fin_seq+1 && old_snd_nxt!=state->snd_nxt)
00608 {
00609
00610
00611
00612
00613 tcpEV << "Now we can do the CLOSE which was deferred a while ago\n";
00614 event = TCP_E_CLOSE;
00615 }
00616
00617 return event;
00618 }
00619
00620
00621
00622 TCPEventCode TCPConnection::processSegmentInListen(TCPSegment *tcpseg, IPvXAddress srcAddr, IPvXAddress destAddr)
00623 {
00624 tcpEV2 << "Processing segment in LISTEN\n";
00625
00626
00627
00628
00629
00630 if (tcpseg->getRstBit())
00631 {
00632 tcpEV << "RST bit set: dropping segment\n";
00633 return TCP_E_IGNORE;
00634 }
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647 if (tcpseg->getAckBit())
00648 {
00649 tcpEV << "ACK bit set: dropping segment and sending RST\n";
00650 sendRst(tcpseg->getAckNo(),destAddr,srcAddr,tcpseg->getDestPort(),tcpseg->getSrcPort());
00651 return TCP_E_IGNORE;
00652 }
00653
00654
00655
00656
00657 if (tcpseg->getSynBit())
00658 {
00659 if (tcpseg->getFinBit())
00660 {
00661
00662
00663
00664 tcpEV << "SYN+FIN received: ignoring FIN\n";
00665 }
00666
00667 tcpEV << "SYN bit set: filling in foreign socket and sending SYN+ACK\n";
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677 if (state->fork)
00678 {
00679 TCPConnection *conn = cloneListeningConnection();
00680 tcpMain->addForkedConnection(this, conn, destAddr, srcAddr, tcpseg->getDestPort(), tcpseg->getSrcPort());
00681 tcpEV << "Connection forked: this connection got new connId=" << connId << ", "
00682 "spinoff keeps LISTENing with connId=" << conn->connId << "\n";
00683 }
00684 else
00685 {
00686 tcpMain->updateSockPair(this, destAddr, srcAddr, tcpseg->getDestPort(), tcpseg->getSrcPort());
00687 }
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 state->rcv_nxt = tcpseg->getSequenceNo()+1;
00700 state->irs = tcpseg->getSequenceNo();
00701 receiveQueue->init(state->rcv_nxt);
00702 selectInitialSeqNum();
00703
00704
00705
00706 state->snd_wnd = tcpseg->getWindow();
00707 state->snd_wl1 = tcpseg->getSequenceNo();
00708 state->snd_wl2 = state->iss;
00709 if (sndWndVector) sndWndVector->record(state->snd_wnd);
00710
00711 sendSynAck();
00712 startSynRexmitTimer();
00713 if (!connEstabTimer->isScheduled())
00714 scheduleTimeout(connEstabTimer, TCP_TIMEOUT_CONN_ESTAB);
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725 if (tcpseg->getPayloadLength()>0)
00726 receiveQueue->insertBytesFromSegment(tcpseg);
00727 if (tcpseg->getUrgBit() || tcpseg->getPshBit())
00728 tcpEV << "Ignoring URG and PSH bits in SYN\n";
00729
00730 return TCP_E_RCV_SYN;
00731 }
00732
00733
00734
00735
00736
00737 tcpEV << "Unexpected segment: dropping it\n";
00738 return TCP_E_IGNORE;
00739 }
00740
00741 TCPEventCode TCPConnection::processSegmentInSynSent(TCPSegment *tcpseg, IPvXAddress srcAddr, IPvXAddress destAddr)
00742 {
00743 tcpEV2 << "Processing segment in SYN_SENT\n";
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759 if (tcpseg->getAckBit())
00760 {
00761 if (seqLE(tcpseg->getAckNo(),state->iss) || seqGreater(tcpseg->getAckNo(),state->snd_nxt))
00762 {
00763 tcpEV << "ACK bit set but wrong AckNo, sending RST\n";
00764 sendRst(tcpseg->getAckNo(),destAddr,srcAddr,tcpseg->getDestPort(),tcpseg->getSrcPort());
00765 return TCP_E_IGNORE;
00766 }
00767 tcpEV << "ACK bit set, AckNo acceptable\n";
00768 }
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780 if (tcpseg->getRstBit())
00781 {
00782 if (tcpseg->getAckBit())
00783 {
00784 tcpEV << "RST+ACK: performing connection reset\n";
00785 sendIndicationToApp(TCP_I_CONNECTION_RESET);
00786 return TCP_E_RCV_RST;
00787 }
00788 else
00789 {
00790 tcpEV << "RST without ACK: dropping segment\n";
00791 return TCP_E_IGNORE;
00792 }
00793 }
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806 if (tcpseg->getSynBit())
00807 {
00808
00809
00810
00811
00812
00813
00814 state->rcv_nxt = tcpseg->getSequenceNo()+1;
00815 state->irs = tcpseg->getSequenceNo();
00816 receiveQueue->init(state->rcv_nxt);
00817
00818 if (tcpseg->getAckBit())
00819 {
00820 state->snd_una = tcpseg->getAckNo();
00821 sendQueue->discardUpTo(state->snd_una);
00822
00823
00824
00825 state->snd_wnd = tcpseg->getWindow();
00826 state->snd_wl1 = tcpseg->getSequenceNo();
00827 state->snd_wl2 = tcpseg->getAckNo();
00828 if (sndWndVector) sndWndVector->record(state->snd_wnd);
00829 }
00830
00831
00832
00833 tcpMain->updateSockPair(this, destAddr, srcAddr, tcpseg->getDestPort(), tcpseg->getSrcPort());
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846 if (seqGreater(state->snd_una, state->iss))
00847 {
00848 tcpEV << "SYN+ACK bits set, connection established.\n";
00849
00850
00851
00852
00853
00854
00855
00856 if (tcpseg->getFinBit())
00857 tcpEV << "SYN+ACK+FIN received: ignoring FIN\n";
00858 if (tcpseg->getPayloadLength()>0)
00859 state->rcv_nxt = receiveQueue->insertBytesFromSegment(tcpseg);
00860 if (tcpseg->getUrgBit() || tcpseg->getPshBit())
00861 tcpEV << "Ignoring URG and PSH bits in SYN+ACK\n";
00862
00863
00864 tcpAlgorithm->established(true);
00865 sendEstabIndicationToApp();
00866
00867
00868
00869 return TCP_E_RCV_SYN_ACK;
00870 }
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881 tcpEV << "SYN bit set: sending SYN+ACK\n";
00882 state->snd_max = state->snd_nxt = state->iss;
00883 sendSynAck();
00884 startSynRexmitTimer();
00885
00886
00887
00888
00889 if (tcpseg->getFinBit())
00890 tcpEV << "SYN+FIN received: ignoring FIN\n";
00891
00892
00893
00894
00895 if (tcpseg->getPayloadLength()>0)
00896 receiveQueue->insertBytesFromSegment(tcpseg);
00897 if (tcpseg->getUrgBit() || tcpseg->getPshBit())
00898 tcpEV << "Ignoring URG and PSH bits in SYN\n";
00899 return TCP_E_RCV_SYN;
00900 }
00901
00902
00903
00904
00905
00906 return TCP_E_IGNORE;
00907 }
00908
00909 TCPEventCode TCPConnection::processRstInSynReceived(TCPSegment *tcpseg)
00910 {
00911 tcpEV2 << "Processing RST in SYN_RCVD\n";
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 sendQueue->discardUpTo(sendQueue->getBufferEndSeq());
00926
00927 if (state->active)
00928 {
00929
00930 sendIndicationToApp(TCP_I_CONNECTION_REFUSED);
00931 }
00932
00933
00934 return TCP_E_RCV_RST;
00935 }
00936
00937 bool TCPConnection::processAckInEstabEtc(TCPSegment *tcpseg)
00938 {
00939 tcpEV2 << "Processing ACK in a data transfer state\n";
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966 if (seqGE(state->snd_una, tcpseg->getAckNo()))
00967 {
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979 if (state->snd_una==tcpseg->getAckNo() && tcpseg->getPayloadLength()==0 &&
00980 state->snd_una!=state->snd_max)
00981 {
00982 state->dupacks++;
00983 tcpAlgorithm->receivedDuplicateAck();
00984 }
00985 else
00986 {
00987
00988 if (tcpseg->getPayloadLength()==0)
00989 {
00990 if (state->snd_una!=tcpseg->getAckNo())
00991 tcpEV << "Old ACK: ackNo<snd_una\n";
00992 else if (state->snd_una==state->snd_max)
00993 tcpEV << "ACK looks duplicate but we have currently no unacked data (snd_una==snd_max)\n";
00994 }
00995
00996
00997 state->dupacks = 0;
00998 }
00999 }
01000 else if (seqLE(tcpseg->getAckNo(), state->snd_max))
01001 {
01002
01003 uint32 old_snd_una = state->snd_una;
01004 state->snd_una = tcpseg->getAckNo();
01005 if (unackedVector) unackedVector->record(state->snd_max - state->snd_una);
01006
01007
01008 if (seqLess(state->snd_nxt, state->snd_una))
01009 state->snd_nxt = state->snd_una;
01010
01011 uint32 discardUpToSeq = state->snd_una;
01012
01013
01014 if (state->send_fin && tcpseg->getAckNo()==state->snd_fin_seq+1)
01015 {
01016
01017 tcpEV << "ACK acks our FIN\n";
01018 state->fin_ack_rcvd = true;
01019 discardUpToSeq--;
01020 }
01021
01022
01023 sendQueue->discardUpTo(discardUpToSeq);
01024
01025 if (seqLess(state->snd_wl1, tcpseg->getSequenceNo()) ||
01026 (state->snd_wl1==tcpseg->getSequenceNo() && seqLE(state->snd_wl2, tcpseg->getAckNo())))
01027 {
01028
01029 tcpEV << "Updating send window from segment: new wnd=" << tcpseg->getWindow() << "\n";
01030 state->snd_wnd = tcpseg->getWindow();
01031 state->snd_wl1 = tcpseg->getSequenceNo();
01032 state->snd_wl2 = tcpseg->getAckNo();
01033 if (sndWndVector) sndWndVector->record(state->snd_wnd);
01034 }
01035
01036 if (tcpseg->getPayloadLength() == 0 && fsm.getState()!=TCP_S_SYN_RCVD)
01037 {
01038
01039 tcpAlgorithm->receivedDataAck(old_snd_una);
01040
01041
01042 state->dupacks = 0;
01043 }
01044 }
01045 else
01046 {
01047 ASSERT(seqGreater(tcpseg->getAckNo(), state->snd_max));
01048
01049
01050 tcpAlgorithm->receivedAckForDataNotYetSent(tcpseg->getAckNo());
01051 state->dupacks = 0;
01052 return false;
01053 }
01054 return true;
01055 }
01056
01057
01058
01059 void TCPConnection::process_TIMEOUT_CONN_ESTAB()
01060 {
01061 switch(fsm.getState())
01062 {
01063 case TCP_S_SYN_RCVD:
01064 case TCP_S_SYN_SENT:
01065
01066
01067 if (state->active)
01068 {
01069
01070 sendIndicationToApp(TCP_I_TIMED_OUT);
01071 }
01072 break;
01073 default:
01074
01075 opp_error("Internal error: received CONN_ESTAB timeout in state %s", stateName(fsm.getState()));
01076 }
01077 }
01078
01079 void TCPConnection::process_TIMEOUT_2MSL()
01080 {
01081
01082
01083
01084
01085 switch(fsm.getState())
01086 {
01087 case TCP_S_TIME_WAIT:
01088
01089
01090
01091
01092 break;
01093 default:
01094
01095 opp_error("Internal error: received time-wait (2MSL) timeout in state %s", stateName(fsm.getState()));
01096 }
01097
01098 }
01099
01100 void TCPConnection::process_TIMEOUT_FIN_WAIT_2()
01101 {
01102 switch(fsm.getState())
01103 {
01104 case TCP_S_FIN_WAIT_2:
01105
01106
01107 sendIndicationToApp(TCP_I_CLOSED);
01108 break;
01109 default:
01110
01111 opp_error("Internal error: received FIN_WAIT_2 timeout in state %s", stateName(fsm.getState()));
01112 }
01113 }
01114
01115 void TCPConnection::startSynRexmitTimer()
01116 {
01117 state->syn_rexmit_count = 0;
01118 state->syn_rexmit_timeout = TCP_TIMEOUT_SYN_REXMIT;
01119
01120 if (synRexmitTimer->isScheduled())
01121 cancelEvent(synRexmitTimer);
01122 scheduleTimeout(synRexmitTimer, state->syn_rexmit_timeout);
01123 }
01124
01125 void TCPConnection::process_TIMEOUT_SYN_REXMIT(TCPEventCode& event)
01126 {
01127 if (++state->syn_rexmit_count>MAX_SYN_REXMIT_COUNT)
01128 {
01129 tcpEV << "Retransmission count during connection setup exceeds " << MAX_SYN_REXMIT_COUNT << ", giving up\n";
01130
01131 event = TCP_E_ABORT;
01132 return;
01133 }
01134
01135 tcpEV << "Performing retransmission #" << state->syn_rexmit_count << "\n";
01136
01137
01138 switch(fsm.getState())
01139 {
01140 case TCP_S_SYN_SENT: sendSyn(); break;
01141 case TCP_S_SYN_RCVD: sendSynAck(); break;
01142 default: opp_error("Internal error: SYN-REXMIT timer expired while in state %s", stateName(fsm.getState()));
01143 }
01144
01145
01146 state->syn_rexmit_timeout *= 2;
01147
01148 if (state->syn_rexmit_timeout > TCP_TIMEOUT_SYN_REXMIT_MAX)
01149 state->syn_rexmit_timeout = TCP_TIMEOUT_SYN_REXMIT_MAX;
01150 scheduleTimeout(synRexmitTimer, state->syn_rexmit_timeout);
01151 }
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164