tcp-full.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:88k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (c) Intel Corporation 2001. All rights reserved.
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *   http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. /*
  17.  * Copyright (c) 1997, 1998 The Regents of the University of California.
  18.  * All rights reserved.
  19.  * 
  20.  * Redistribution and use in source and binary forms, with or without
  21.  * modification, are permitted provided that the following conditions
  22.  * are met:
  23.  * 1. Redistributions of source code must retain the above copyright
  24.  *    notice, this list of conditions and the following disclaimer.
  25.  * 2. Redistributions in binary form must reproduce the above copyright
  26.  *    notice, this list of conditions and the following disclaimer in the
  27.  *    documentation and/or other materials provided with the distribution.
  28.  * 3. All advertising materials mentioning features or use of this software
  29.  *    must display the following acknowledgement:
  30.  *  This product includes software developed by the Network Research
  31.  *  Group at Lawrence Berkeley National Laboratory.
  32.  * 4. Neither the name of the University nor of the Laboratory may be used
  33.  *    to endorse or promote products derived from this software without
  34.  *    specific prior written permission.
  35.  * 
  36.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  37.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  38.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  39.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  40.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  41.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  42.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  44.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  45.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  */
  48. /*
  49.  * Full-TCP : A two-way TCP very similar to the 4.4BSD version of Reno TCP.
  50.  * This version also includes variants Tahoe, NewReno, and SACK.
  51.  *
  52.  * This code below has received a fairly major restructuring (Aug. 2001).
  53.  * The ReassemblyQueue structure is now removed to a separate module and
  54.  * entirely re-written.
  55.  * Also, the SACK functionality has been re-written (almost) entirely.
  56.  * -KF [kfall@intel.com]
  57.  *
  58.  * This code below was motivated in part by code contributed by
  59.  * Kathie Nichols (nichols@baynetworks.com).  The code below is based primarily
  60.  * on the 4.4BSD TCP implementation. -KF [kfall@ee.lbl.gov]
  61.  *
  62.  * Kathie Nichols and Van Jacobson have contributed significant bug fixes,
  63.  * especially with respect to the the handling of sequence numbers during
  64.  * connection establishment/clearin.  Additional fixes have followed
  65.  * theirs.
  66.  *
  67.  * Fixes for gensack() and ReassemblyQueue::add() contributed by Richard 
  68.  * Mortier <Richard.Mortier@cl.cam.ac.uk>
  69.  *
  70.  * Some warnings and comments:
  71.  * this version of TCP will not work correctly if the sequence number
  72.  * goes above 2147483648 due to sequence number wrap
  73.  *
  74.  * this version of TCP by default sends data at the beginning of a
  75.  * connection in the "typical" way... That is,
  76.  * A   ------> SYN ------> B
  77.  * A   <----- SYN+ACK ---- B
  78.  * A   ------> ACK ------> B
  79.  * A   ------> data -----> B
  80.  *
  81.  * there is no dynamic receiver's advertised window.   The advertised
  82.  * window is simulated by simply telling the sender a bound on the window
  83.  * size (wnd_).
  84.  *
  85.  * in real TCP, a user process performing a read (via PRU_RCVD)
  86.  * calls tcp_output each time to (possibly) send a window
  87.  * update.  Here we don't have a user process, so we simulate
  88.  * a user process always ready to consume all the receive buffer
  89.  *
  90.  * Notes:
  91.  * wnd_, wnd_init_, cwnd_, ssthresh_ are in segment units
  92.  * sequence and ack numbers are in byte units
  93.  *
  94.  * Futures:
  95.  *      there are different existing TCPs with respect to how
  96.  *      ack's are handled on connection startup.  Some delay
  97.  *      the ack for the first segment, which can cause connections
  98.  *      to take longer to start up than if we be sure to ack it quickly.
  99.  *
  100.  *      some TCPs arrange for immediate ACK generation if the incoming segment
  101.  *      contains the PUSH bit
  102.  *
  103.  *
  104.  */
  105. #ifndef lint
  106. static const char rcsid[] =
  107.     "@(#) $Header: /cvsroot/nsnam/ns-2/tcp/tcp-full.cc,v 1.124 2007/09/16 20:30:44 sallyfloyd Exp $ (LBL)";
  108. #endif
  109. #include "ip.h"
  110. #include "tcp-full.h"
  111. #include "flags.h"
  112. #include "random.h"
  113. #include "template.h"
  114. #ifndef TRUE
  115. #define TRUE  1
  116. #endif
  117. #ifndef FALSE
  118. #define FALSE  0
  119. #endif
  120. /*
  121.  * Tcl Linkage for the following:
  122.  * Agent/TCP/FullTcp, Agent/TCP/FullTcp/Tahoe,
  123.  * Agent/TCP/FullTcp/Newreno, Agent/TCP/FullTcp/Sack
  124.  *
  125.  * See tcl/lib/ns-default.tcl for init methods for
  126.  * Tahoe, Newreno, and Sack
  127.  */
  128. static class FullTcpClass : public TclClass { 
  129. public:
  130. FullTcpClass() : TclClass("Agent/TCP/FullTcp") {}
  131. TclObject* create(int, const char*const*) { 
  132. return (new FullTcpAgent());
  133. }
  134. } class_full;
  135. static class TahoeFullTcpClass : public TclClass { 
  136. public:
  137. TahoeFullTcpClass() : TclClass("Agent/TCP/FullTcp/Tahoe") {}
  138. TclObject* create(int, const char*const*) { 
  139. // ns-default sets reno_fastrecov_ to false
  140. return (new TahoeFullTcpAgent());
  141. }
  142. } class_tahoe_full;
  143. static class NewRenoFullTcpClass : public TclClass { 
  144. public:
  145. NewRenoFullTcpClass() : TclClass("Agent/TCP/FullTcp/Newreno") {}
  146. TclObject* create(int, const char*const*) { 
  147. // ns-default sets open_cwnd_on_pack_ to false
  148. return (new NewRenoFullTcpAgent());
  149. }
  150. } class_newreno_full;
  151. static class SackFullTcpClass : public TclClass { 
  152. public:
  153. SackFullTcpClass() : TclClass("Agent/TCP/FullTcp/Sack") {}
  154. TclObject* create(int, const char*const*) { 
  155. // ns-default sets reno_fastrecov_ to false
  156. // ns-default sets open_cwnd_on_pack_ to false
  157. return (new SackFullTcpAgent());
  158. }
  159. } class_sack_full;
  160. /*
  161.  * Delayed-binding variable linkage
  162.  */
  163. void
  164. FullTcpAgent::delay_bind_init_all()
  165. {
  166.         delay_bind_init_one("segsperack_");
  167.         delay_bind_init_one("segsize_");
  168.         delay_bind_init_one("tcprexmtthresh_");
  169.         delay_bind_init_one("iss_");
  170.         delay_bind_init_one("nodelay_");
  171.         delay_bind_init_one("data_on_syn_");
  172.         delay_bind_init_one("dupseg_fix_");
  173.         delay_bind_init_one("dupack_reset_");
  174.         delay_bind_init_one("close_on_empty_");
  175.         delay_bind_init_one("signal_on_empty_");
  176.         delay_bind_init_one("interval_");
  177.         delay_bind_init_one("ts_option_size_");
  178.         delay_bind_init_one("reno_fastrecov_");
  179.         delay_bind_init_one("pipectrl_");
  180.         delay_bind_init_one("open_cwnd_on_pack_");
  181.         delay_bind_init_one("halfclose_");
  182.         delay_bind_init_one("nopredict_");
  183.         delay_bind_init_one("ecn_syn_");
  184.         delay_bind_init_one("ecn_syn_wait_");
  185.         delay_bind_init_one("debug_");
  186.         delay_bind_init_one("spa_thresh_");
  187. TcpAgent::delay_bind_init_all();
  188.        
  189.        reset();
  190. }
  191. int
  192. FullTcpAgent::delay_bind_dispatch(const char *varName, const char *localName, TclObject *tracer)
  193. {
  194.         if (delay_bind(varName, localName, "segsperack_", &segs_per_ack_, tracer)) return TCL_OK;
  195.         if (delay_bind(varName, localName, "segsize_", &maxseg_, tracer)) return TCL_OK;
  196.         if (delay_bind(varName, localName, "tcprexmtthresh_", &tcprexmtthresh_, tracer)) return TCL_OK;
  197.         if (delay_bind(varName, localName, "iss_", &iss_, tracer)) return TCL_OK;
  198.         if (delay_bind(varName, localName, "spa_thresh_", &spa_thresh_, tracer)) return TCL_OK;
  199.         if (delay_bind_bool(varName, localName, "nodelay_", &nodelay_, tracer)) return TCL_OK;
  200.         if (delay_bind_bool(varName, localName, "data_on_syn_", &data_on_syn_, tracer)) return TCL_OK;
  201.         if (delay_bind_bool(varName, localName, "dupseg_fix_", &dupseg_fix_, tracer)) return TCL_OK;
  202.         if (delay_bind_bool(varName, localName, "dupack_reset_", &dupack_reset_, tracer)) return TCL_OK;
  203.         if (delay_bind_bool(varName, localName, "close_on_empty_", &close_on_empty_, tracer)) return TCL_OK;
  204.         if (delay_bind_bool(varName, localName, "signal_on_empty_", &signal_on_empty_, tracer)) return TCL_OK;
  205.         if (delay_bind_time(varName, localName, "interval_", &delack_interval_, tracer)) return TCL_OK;
  206.         if (delay_bind(varName, localName, "ts_option_size_", &ts_option_size_, tracer)) return TCL_OK;
  207.         if (delay_bind_bool(varName, localName, "reno_fastrecov_", &reno_fastrecov_, tracer)) return TCL_OK;
  208.         if (delay_bind_bool(varName, localName, "pipectrl_", &pipectrl_, tracer)) return TCL_OK;
  209.         if (delay_bind_bool(varName, localName, "open_cwnd_on_pack_", &open_cwnd_on_pack_, tracer)) return TCL_OK;
  210.         if (delay_bind_bool(varName, localName, "halfclose_", &halfclose_, tracer)) return TCL_OK;
  211.         if (delay_bind_bool(varName, localName, "nopredict_", &nopredict_, tracer)) return TCL_OK;
  212.         if (delay_bind_bool(varName, localName, "ecn_syn_", &ecn_syn_, tracer)) return TCL_OK;
  213.         if (delay_bind_bool(varName, localName, "ecn_syn_wait_", &ecn_syn_wait_, tracer)) return TCL_OK;
  214.         if (delay_bind_bool(varName, localName, "debug_", &debug_, tracer)) return TCL_OK;
  215.         return TcpAgent::delay_bind_dispatch(varName, localName, tracer);
  216. }
  217. void
  218. SackFullTcpAgent::delay_bind_init_all()
  219. {
  220.         delay_bind_init_one("clear_on_timeout_");
  221.         delay_bind_init_one("sack_rtx_cthresh_");
  222.         delay_bind_init_one("sack_rtx_bthresh_");
  223.         delay_bind_init_one("sack_block_size_");
  224.         delay_bind_init_one("sack_option_size_");
  225.         delay_bind_init_one("max_sack_blocks_");
  226.         delay_bind_init_one("sack_rtx_threshmode_");
  227. FullTcpAgent::delay_bind_init_all();
  228. }
  229. int
  230. SackFullTcpAgent::delay_bind_dispatch(const char *varName, const char *localName, TclObject *tracer)
  231. {
  232.         if (delay_bind_bool(varName, localName, "clear_on_timeout_", &clear_on_timeout_, tracer)) return TCL_OK;
  233.         if (delay_bind(varName, localName, "sack_rtx_cthresh_", &sack_rtx_cthresh_, tracer)) return TCL_OK;
  234.         if (delay_bind(varName, localName, "sack_rtx_bthresh_", &sack_rtx_bthresh_, tracer)) return TCL_OK;
  235.         if (delay_bind(varName, localName, "sack_rtx_threshmode_", &sack_rtx_threshmode_, tracer)) return TCL_OK;
  236.         if (delay_bind(varName, localName, "sack_block_size_", &sack_block_size_, tracer)) return TCL_OK;
  237.         if (delay_bind(varName, localName, "sack_option_size_", &sack_option_size_, tracer)) return TCL_OK;
  238.         if (delay_bind(varName, localName, "max_sack_blocks_", &max_sack_blocks_, tracer)) return TCL_OK;
  239.         return FullTcpAgent::delay_bind_dispatch(varName, localName, tracer);
  240. }
  241. int
  242. FullTcpAgent::command(int argc, const char*const* argv)
  243. {
  244. // would like to have some "connect" primitive
  245. // here, but the problem is that we get called before
  246. // the simulation is running and we want to send a SYN.
  247. // Because no routing exists yet, this fails.
  248. // Instead, see code in advance().
  249. //
  250. // listen can happen any time because it just changes state_
  251. //
  252. // close is designed to happen at some point after the
  253. // simulation is running (using an ns 'at' command)
  254. if (argc == 2) {
  255. if (strcmp(argv[1], "listen") == 0) {
  256. // just a state transition
  257. listen();
  258. return (TCL_OK);
  259. }
  260. if (strcmp(argv[1], "close") == 0) {
  261. usrclosed();
  262. return (TCL_OK);
  263. }
  264. }
  265. if (argc == 3) {
  266. if (strcmp(argv[1], "advance") == 0) {
  267. advanceby(atoi(argv[2]));
  268. return (TCL_OK);
  269. }
  270. if (strcmp(argv[1], "advanceby") == 0) {
  271. advanceby(atoi(argv[2]));
  272. return (TCL_OK);
  273. }
  274. if (strcmp(argv[1], "advance-bytes") == 0) {
  275. advance_bytes(atoi(argv[2]));
  276. return (TCL_OK);
  277. }
  278. }
  279. if (argc == 4) {
  280. if (strcmp(argv[1], "sendmsg") == 0) {
  281. sendmsg(atoi(argv[2]), argv[3]);
  282. return (TCL_OK);
  283. }
  284. }
  285. return (TcpAgent::command(argc, argv));
  286. }
  287. /*
  288.  * "User Interface" Functions for Full TCP
  289.  * advanceby(number of packets)
  290.  * advance_bytes(number of bytes)
  291.  * sendmsg(int bytes, char* buf)
  292.  * listen
  293.  * close
  294.  */
  295. /*
  296.  * the 'advance' interface to the regular tcp is in packet
  297.  * units.  Here we scale this to bytes for full tcp.
  298.  *
  299.  * 'advance' is normally called by an "application" (i.e. data source)
  300.  * to signal that there is something to send
  301.  *
  302.  * 'curseq_' is the sequence number of the last byte provided
  303.  * by the application.  In the case where no data has been supplied
  304.  * by the application, curseq_ is the iss_.
  305.  */
  306. void
  307. FullTcpAgent::advanceby(int np)
  308. {
  309. // XXX hack:
  310. // because np is in packets and a data source
  311. // may pass a *huge* number as a way to tell us
  312. // to go forever, just look for the huge number
  313. // and if it's there, pre-divide it
  314. if (np >= 0x10000000)
  315. np /= maxseg_;
  316. advance_bytes(np * maxseg_);
  317. return;
  318. }
  319. /*
  320.  * the byte-oriented interface: advance_bytes(int nbytes)
  321.  */
  322. void
  323. FullTcpAgent::advance_bytes(int nb)
  324. {
  325. //
  326. // state-specific operations:
  327. // if CLOSED or LISTEN, reset and try a new active open/connect
  328. // if ESTABLISHED, queue and try to send more
  329. // if SYN_SENT or SYN_RCVD, just queue
  330. // if above ESTABLISHED, we are closing, so don't allow
  331. //
  332. switch (state_) {
  333. case TCPS_CLOSED:
  334. case TCPS_LISTEN:
  335.                 reset();
  336.                 curseq_ = iss_ + nb;
  337.                 connect();              // initiate new connection
  338. break;
  339. case TCPS_ESTABLISHED:
  340. case TCPS_SYN_SENT:
  341. case TCPS_SYN_RECEIVED:
  342.                 if (curseq_ < iss_) 
  343.                         curseq_ = iss_; 
  344.                 curseq_ += nb;
  345. break;
  346. default:
  347.             if (debug_) 
  348.             fprintf(stderr, "%f: FullTcpAgent::advance(%s): cannot advance while in state %sn",
  349.          now(), name(), statestr(state_));
  350. }
  351. if (state_ == TCPS_ESTABLISHED)
  352. send_much(0, REASON_NORMAL, maxburst_);
  353.    return;
  354. }
  355. /*
  356.  * If MSG_EOF is set, by setting close_on_empty_ to TRUE, we ensure that
  357.  * a FIN will be sent when the send buffer emptys.
  358.  * If DAT_EOF is set, the callback function done_data is called
  359.  * when the send buffer empty
  360.  * 
  361.  * When (in the future?) FullTcpAgent implements T/TCP, avoidance of 3-way 
  362.  * handshake can be handled in this function.
  363.  */
  364. void
  365. FullTcpAgent::sendmsg(int nbytes, const char *flags)
  366. {
  367. if (flags && strcmp(flags, "MSG_EOF") == 0) 
  368. close_on_empty_ = TRUE;
  369. if (flags && strcmp(flags, "DAT_EOF") == 0) 
  370. signal_on_empty_ = TRUE;
  371. if (nbytes == -1) {
  372. infinite_send_ = TRUE;
  373. advance_bytes(0);
  374. } else
  375. advance_bytes(nbytes);
  376. }
  377. /*
  378.  * do an active open
  379.  * (in real TCP, see tcp_usrreq, case PRU_CONNECT)
  380.  */
  381. void
  382. FullTcpAgent::connect()
  383. {
  384. newstate(TCPS_SYN_SENT); // sending a SYN now
  385. sent(iss_, foutput(iss_, REASON_NORMAL));
  386. return;
  387. }
  388. /*
  389.  * be a passive opener
  390.  * (in real TCP, see tcp_usrreq, case PRU_LISTEN)
  391.  * (for simulation, make this peer's ptype ACKs)
  392.  */
  393. void
  394. FullTcpAgent::listen()
  395. {
  396. newstate(TCPS_LISTEN);
  397. type_ = PT_ACK; // instead of PT_TCP
  398. }
  399. /*
  400. * This function is invoked when the sender buffer is empty. It in turn
  401. * invokes the Tcl done_data procedure that was registered with TCP.
  402. */
  403.  
  404. void
  405. FullTcpAgent::bufferempty()
  406. {
  407.     signal_on_empty_=FALSE;
  408. Tcl::instance().evalf("%s done_data", this->name());
  409. }
  410. /*
  411.  * called when user/application performs 'close'
  412.  */
  413. void
  414. FullTcpAgent::usrclosed()
  415. {
  416. curseq_ = maxseq_ - 1; // now, no more data
  417. infinite_send_ = FALSE; // stop infinite send
  418. switch (state_) {
  419. case TCPS_CLOSED:
  420. case TCPS_LISTEN:
  421. cancel_timers();
  422. newstate(TCPS_CLOSED);
  423. finish();
  424. break;
  425. case TCPS_SYN_SENT:
  426. newstate(TCPS_CLOSED);
  427. /* fall through */
  428. case TCPS_LAST_ACK:
  429. flags_ |= TF_NEEDFIN;
  430. send_much(1, REASON_NORMAL, maxburst_);
  431. break;
  432. case TCPS_SYN_RECEIVED:
  433. case TCPS_ESTABLISHED:
  434. newstate(TCPS_FIN_WAIT_1);
  435. flags_ |= TF_NEEDFIN;
  436. send_much(1, REASON_NORMAL, maxburst_);
  437. break;
  438. case TCPS_CLOSE_WAIT:
  439. newstate(TCPS_LAST_ACK);
  440. flags_ |= TF_NEEDFIN;
  441. send_much(1, REASON_NORMAL, maxburst_);
  442. break;
  443. case TCPS_FIN_WAIT_1:
  444. case TCPS_FIN_WAIT_2:
  445. case TCPS_CLOSING:
  446. /* usr asked for a close more than once [?] */
  447.                 if (debug_)
  448.          fprintf(stderr,
  449.            "%f FullTcpAgent(%s): app close in bad state %sn",
  450.            now(), name(), statestr(state_));
  451. break;
  452. default:
  453.                 if (debug_)
  454.         fprintf(stderr,
  455.         "%f FullTcpAgent(%s): app close in unknown state %sn",
  456.         now(), name(), statestr(state_));
  457. }
  458. return;
  459. }
  460. /*
  461.  * Utility type functions
  462.  */
  463. void
  464. FullTcpAgent::cancel_timers()
  465. {
  466. // cancel: rtx, burstsend, delsnd
  467. TcpAgent::cancel_timers();      
  468. // cancel: delack
  469. delack_timer_.force_cancel();
  470. }
  471. void
  472. FullTcpAgent::newstate(int state)
  473. {
  474. //printf("%f(%s): state changed from %s to %sn",
  475. //now(), name(), statestr(state_), statestr(state));
  476. state_ = state;
  477. }
  478. void
  479. FullTcpAgent::prpkt(Packet *pkt)
  480. {
  481. hdr_tcp *tcph = hdr_tcp::access(pkt); // TCP header
  482. hdr_cmn *th = hdr_cmn::access(pkt); // common header (size, etc)
  483. //hdr_flags *fh = hdr_flags::access(pkt); // flags (CWR, CE, bits)
  484. hdr_ip* iph = hdr_ip::access(pkt);
  485. int datalen = th->size() - tcph->hlen(); // # payload bytes
  486. fprintf(stdout, " [%d:%d.%d>%d.%d] (hlen:%d, dlen:%d, seq:%d, ack:%d, flags:0x%x (%s), salen:%d, reason:0x%x)n",
  487. th->uid(),
  488. iph->saddr(), iph->sport(),
  489. iph->daddr(), iph->dport(),
  490. tcph->hlen(),
  491. datalen,
  492. tcph->seqno(),
  493. tcph->ackno(),
  494. tcph->flags(), flagstr(tcph->flags()),
  495. tcph->sa_length(),
  496. tcph->reason());
  497. }
  498. char *
  499. FullTcpAgent::flagstr(int hflags)
  500. {
  501. // update this if tcp header flags change
  502. static char *flagstrs[28] = {
  503. "<null>", "<FIN>", "<SYN>", "<SYN,FIN>", // 0-3
  504. "<?>", "<?,FIN>", "<?,SYN>", "<?,SYN,FIN>", // 4-7
  505. "<PSH>", "<PSH,FIN>", "<PSH,SYN>", "<PSH,SYN,FIN>", // 0x08-0x0b
  506. /* do not use <??, in next line because that's an ANSI trigraph */
  507. "<?>", "<?,FIN>", "<?,SYN>", "<?,SYN,FIN>",     // 0x0c-0x0f
  508. "<ACK>", "<ACK,FIN>", "<ACK,SYN>", "<ACK,SYN,FIN>", // 0x10-0x13
  509. "<ACK>", "<ACK,FIN>", "<ACK,SYN>", "<ACK,SYN,FIN>", // 0x14-0x17
  510. "<PSH,ACK>", "<PSH,ACK,FIN>", "<PSH,ACK,SYN>", "<PSH,ACK,SYN,FIN>", // 0x18-0x1b
  511. };
  512. if (hflags < 0 || (hflags > 28)) {
  513. /* Added strings for CWR and ECE  -M. Weigle 6/27/02 */
  514. if (hflags == 72) 
  515.   return ("<ECE,PSH>");
  516.   else if (hflags == 80)
  517.   return ("<ECE,ACK>");
  518.   else if (hflags == 88) 
  519.   return ("<ECE,PSH,ACK>");
  520.   else if (hflags == 152) 
  521.   return ("<CWR,PSH,ACK>");
  522. else if (hflags == 153)
  523. return ("<CWR,PSH,ACK,FIN>");
  524. else
  525. return ("<invalid>");
  526. }
  527. return (flagstrs[hflags]);
  528. }
  529. char *
  530. FullTcpAgent::statestr(int state)
  531. {
  532. static char *statestrs[TCP_NSTATES] = {
  533. "CLOSED", "LISTEN", "SYN_SENT", "SYN_RCVD",
  534. "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1", "CLOSING",
  535. "LAST_ACK", "FIN_WAIT_2"
  536. };
  537. if (state < 0 || (state >= TCP_NSTATES))
  538. return ("INVALID");
  539. return (statestrs[state]);
  540. }
  541. void
  542. DelAckTimer::expire(Event *) {
  543.         a_->timeout(TCP_TIMER_DELACK);
  544. }
  545. /*
  546.  * reset to starting point, don't set state_ here,
  547.  * because our starting point might be LISTEN rather
  548.  * than CLOSED if we're a passive opener
  549.  */
  550. void
  551. FullTcpAgent::reset()
  552. {
  553. cancel_timers(); // cancel timers first
  554.        TcpAgent::reset(); // resets most variables
  555. rq_.clear(); // clear reassembly queue
  556. rtt_init(); // zero rtt, srtt, backoff
  557. last_ack_sent_ = -1;
  558. rcv_nxt_ = -1;
  559. pipe_ = 0;
  560. rtxbytes_ = 0;
  561. flags_ = 0;
  562. t_seqno_ = iss_;
  563. maxseq_ = -1;
  564. irs_ = -1;
  565. last_send_time_ = -1.0;
  566. if (ts_option_)
  567. recent_ = recent_age_ = 0.0;
  568. else
  569. recent_ = recent_age_ = -1.0;
  570. fastrecov_ = FALSE;
  571. closed_ = 0;
  572. close_on_empty_ = FALSE;
  573. }
  574. /*
  575.  * This function is invoked when the connection is done. It in turn
  576.  * invokes the Tcl finish procedure that was registered with TCP.
  577.  * This function mimics tcp_close()
  578.  */
  579. void
  580. FullTcpAgent::finish()
  581. {
  582. Tcl::instance().evalf("%s done", this->name());
  583. }
  584. /*
  585.  * headersize:
  586.  * how big is an IP+TCP header in bytes; include options such as ts
  587.  * this function should be virtual so others (e.g. SACK) can override
  588.  */
  589. int
  590. FullTcpAgent::headersize()
  591. {
  592. int total = tcpip_base_hdr_size_;
  593. if (total < 1) {
  594. fprintf(stderr,
  595.     "%f: FullTcpAgent(%s): warning: tcpip hdr size is only %d bytesn",
  596. now(), name(), tcpip_base_hdr_size_);
  597. }
  598. if (ts_option_)
  599. total += ts_option_size_;
  600. return (total);
  601. }
  602. /*
  603.  * flags that are completely dependent on the tcp state
  604.  * these are used for the next outgoing packet in foutput()
  605.  * (in real TCP, see tcp_fsm.h, the "tcp_outflags" array)
  606.  */
  607. int
  608. FullTcpAgent::outflags()
  609. {
  610. // in real TCP an RST is added in the CLOSED state
  611. static int tcp_outflags[TCP_NSTATES] = {
  612. TH_ACK,           /* 0, CLOSED */  
  613. 0,                      /* 1, LISTEN */ 
  614. TH_SYN,                 /* 2, SYN_SENT */
  615. TH_SYN|TH_ACK,          /* 3, SYN_RECEIVED */
  616. TH_ACK,                 /* 4, ESTABLISHED */
  617. TH_ACK,                 /* 5, CLOSE_WAIT */
  618. TH_FIN|TH_ACK,          /* 6, FIN_WAIT_1 */
  619. TH_FIN|TH_ACK,          /* 7, CLOSING */
  620. TH_FIN|TH_ACK,          /* 8, LAST_ACK */
  621. TH_ACK,                 /* 9, FIN_WAIT_2 */
  622. /* 10, TIME_WAIT --- not used in simulator */
  623. };
  624. if (state_ < 0 || (state_ >= TCP_NSTATES)) {
  625. fprintf(stderr, "%f FullTcpAgent(%s): invalid state %dn",
  626. now(), name(), state_);
  627. return (0x0);
  628. }
  629. return (tcp_outflags[state_]);
  630. }
  631. /*
  632.  * reaass() -- extract the appropriate fields from the packet
  633.  * and pass this info the ReassemblyQueue add routine
  634.  *
  635.  * returns the TCP header flags representing the "or" of
  636.  * the flags contained in the adjacent sequence # blocks
  637.  */
  638. int
  639. FullTcpAgent::reass(Packet* pkt)
  640. {  
  641.         hdr_tcp *tcph =  hdr_tcp::access(pkt);
  642.         hdr_cmn *th = hdr_cmn::access(pkt);
  643.    
  644.         int start = tcph->seqno();
  645.         int end = start + th->size() - tcph->hlen();
  646.         int tiflags = tcph->flags();
  647. int fillshole = (start == rcv_nxt_);
  648. int flags;
  649.    
  650. // end contains the seq of the last byte of
  651. // in the packet plus one
  652. if (start == end && (tiflags & TH_FIN) == 0) {
  653. fprintf(stderr, "%f: FullTcpAgent(%s)::reass() -- bad condition - adding non-FIN zero-len segn",
  654. now(), name());
  655. abort();
  656. }
  657. flags = rq_.add(start, end, tiflags, 0);
  658. //present:
  659. //
  660. // If we've never received a SYN (unlikely)
  661. // or this is an out of order addition, no reason to coalesce
  662. //
  663. if (TCPS_HAVERCVDSYN(state_) == 0 || !fillshole) {
  664.   return (0x00);
  665. }
  666. //
  667. // If we get some data in SYN_RECVD, no need to present to user yet
  668. //
  669. if (state_ == TCPS_SYN_RECEIVED && (end > start))
  670. return (0x00);
  671. // clear out data that has been passed, up to rcv_nxt_,
  672. // collects flags
  673. flags |= rq_.cleartonxt();
  674.         return (flags);
  675. }
  676. /*
  677.  * utility function to set rcv_next_ during inital exchange of seq #s
  678.  */
  679. int
  680. FullTcpAgent::rcvseqinit(int seq, int dlen)
  681. {
  682. return (seq + dlen + 1);
  683. }
  684. /*
  685.  * build a header with the timestamp option if asked
  686.  */
  687. int
  688. FullTcpAgent::build_options(hdr_tcp* tcph)
  689. {
  690. int total = 0;
  691. if (ts_option_) {
  692. tcph->ts() = now();
  693. tcph->ts_echo() = recent_;
  694. total += ts_option_size_;
  695. } else {
  696. tcph->ts() = tcph->ts_echo() = -1.0;
  697. }
  698. return (total);
  699. }
  700. /*
  701.  * pack() -- is the ACK a partial ACK? (not past recover_)
  702.  */
  703. int
  704. FullTcpAgent::pack(Packet *pkt)
  705. {
  706. hdr_tcp *tcph = hdr_tcp::access(pkt);
  707. /* Added check for fast recovery.  -M. Weigle 5/2/02 */
  708. return (fastrecov_ && tcph->ackno() >= highest_ack_ &&
  709. tcph->ackno() < recover_);
  710. }
  711. /*
  712.  * baseline reno TCP exists fast recovery on a partial ACK
  713.  */
  714. void
  715. FullTcpAgent::pack_action(Packet*)
  716. {
  717. if (reno_fastrecov_ && fastrecov_ && cwnd_ > double(ssthresh_)) {
  718. cwnd_ = double(ssthresh_); // retract window if inflated
  719. }
  720. fastrecov_ = FALSE;
  721. //printf("%f: EXITED FAST RECOVERYn", now());
  722. dupacks_ = 0;
  723. }
  724. /*
  725.  * ack_action -- same as partial ACK action for base Reno TCP
  726.  */
  727. void
  728. FullTcpAgent::ack_action(Packet* p)
  729. {
  730. FullTcpAgent::pack_action(p);
  731. }
  732. /*
  733.  * sendpacket: 
  734.  * allocate a packet, fill in header fields, and send
  735.  * also keeps stats on # of data pkts, acks, re-xmits, etc
  736.  *
  737.  * fill in packet fields.  Agent::allocpkt() fills
  738.  * in most of the network layer fields for us.
  739.  * So fill in tcp hdr and adjust the packet size.
  740.  *
  741.  * Also, set the size of the tcp header.
  742.  */
  743. void
  744. FullTcpAgent::sendpacket(int seqno, int ackno, int pflags, int datalen, int reason, Packet *p)
  745. {
  746.         if (!p) p = allocpkt();
  747.         hdr_tcp *tcph = hdr_tcp::access(p);
  748. hdr_flags *fh = hdr_flags::access(p);
  749. /* build basic header w/options */
  750.         tcph->seqno() = seqno;
  751.         tcph->ackno() = ackno;
  752.         tcph->flags() = pflags;
  753.         tcph->reason() |= reason; // make tcph->reason look like ns1 pkt->flags?
  754. tcph->sa_length() = 0;    // may be increased by build_options()
  755.         tcph->hlen() = tcpip_base_hdr_size_;
  756. tcph->hlen() += build_options(tcph);
  757. /*
  758.  * Explicit Congestion Notification (ECN) related:
  759.  * Bits in header:
  760.  *  ECT (EC Capable Transport),
  761.  *  ECNECHO (ECHO of ECN Notification generated at router),
  762.  *  CWR (Congestion Window Reduced from RFC 2481)
  763.  * States in TCP:
  764.  * ecn_: I am supposed to do ECN if my peer does
  765.  * ect_: I am doing ECN (ecn_ should be T and peer does ECN)
  766.  */
  767. if (datalen > 0 && ecn_ ){
  768.         // set ect on data packets 
  769. fh->ect() = ect_; // on after mutual agreement on ECT
  770.         } else if (ecn_ && ecn_syn_ && (pflags & TH_SYN) && (pflags & TH_ACK)) {
  771.                 // set ect on syn/ack packet, if syn packet was negotiating ECT
  772.                 fh->ect() = ect_;
  773. } else {
  774. /* Set ect() to 0.  -M. Weigle 1/19/05 */
  775. fh->ect() = 0;
  776. }
  777. if (ecn_ && ect_ && recent_ce_ ) { 
  778. // This is needed here for the ACK in a SYN, SYN/ACK, ACK
  779. // sequence.
  780. pflags |= TH_ECE;
  781. }
  782.         // fill in CWR and ECE bits which don't actually sit in
  783.         // the tcp_flags but in hdr_flags
  784.         if ( pflags & TH_ECE) {
  785.                 fh->ecnecho() = 1;
  786.         } else {
  787.                 fh->ecnecho() = 0;
  788.         }
  789.         if ( pflags & TH_CWR ) {
  790.                 fh->cong_action() = 1;
  791.         }
  792. else {
  793. /* Set cong_action() to 0  -M. Weigle 1/19/05 */
  794. fh->cong_action() = 0;
  795. }
  796. /* actual size is data length plus header length */
  797.         hdr_cmn *ch = hdr_cmn::access(p);
  798.         ch->size() = datalen + tcph->hlen();
  799.         if (datalen <= 0)
  800.                 ++nackpack_;
  801.         else {
  802.                 ++ndatapack_;
  803.                 ndatabytes_ += datalen;
  804. last_send_time_ = now(); // time of last data
  805.         }
  806.         if (reason == REASON_TIMEOUT || reason == REASON_DUPACK || reason == REASON_SACK) {
  807.                 ++nrexmitpack_;
  808.                 nrexmitbytes_ += datalen;
  809.         }
  810. last_ack_sent_ = ackno;
  811. //if (state_ != TCPS_ESTABLISHED) {
  812. //printf("%f(%s)[state:%s]: sending pkt ", now(), name(), statestr(state_));
  813. //prpkt(p);
  814. //}
  815. send(p, 0);
  816. return;
  817. }
  818. //
  819. // reset_rtx_timer: called during a retransmission timeout
  820. // to perform exponential backoff.  Also, note that because
  821. // we have performed a retransmission, our rtt timer is now
  822. // invalidated (indicate this by setting rtt_active_ false)
  823. //
  824. void
  825. FullTcpAgent::reset_rtx_timer(int /* mild */)
  826. {
  827. // cancel old timer, set a new one
  828. /* if there is no outstanding data, don't back off rtx timer *
  829.  * (Fix from T. Kelly.) */
  830. if (!(highest_ack_ == maxseq_ && restart_bugfix_)) {
  831.          rtt_backoff(); // double current timeout
  832. }
  833.         set_rtx_timer(); // set new timer
  834.         rtt_active_ = FALSE; // no timing during this window
  835. }
  836. /*
  837.  * see if we should send a segment, and if so, send it
  838.  *  (may be ACK or data)
  839.  * return the number of data bytes sent (count a SYN or FIN as 1 each)
  840.  *
  841.  * simulator var, desc (name in real TCP)
  842.  * --------------------------------------
  843.  * maxseq_, largest seq# we've sent plus one (snd_max)
  844.  * flags_, flags regarding our internal state (t_state)
  845.  * pflags, a local used to build up the tcp header flags (flags)
  846.  * curseq_, is the highest sequence number given to us by "application"
  847.  * highest_ack_, the highest ACK we've seen for our data (snd_una-1)
  848.  * seqno, the next seq# we're going to send (snd_nxt)
  849.  */
  850. int
  851. FullTcpAgent::foutput(int seqno, int reason)
  852. {
  853. // if maxseg_ not set, set it appropriately
  854. // Q: how can this happen?
  855. if (maxseg_ == 0) 
  856.     maxseg_ = size_ - headersize();
  857. else
  858. size_ =  maxseg_ + headersize();
  859. int is_retransmit = (seqno < maxseq_);
  860. int quiet = (highest_ack_ == maxseq_);
  861. int pflags = outflags();
  862. int syn = (seqno == iss_);
  863. int emptying_buffer = FALSE;
  864. int buffered_bytes = (infinite_send_) ? TCP_MAXSEQ :
  865. curseq_ - highest_ack_ + 1;
  866. int win = window() * maxseg_; // window (in bytes)
  867. int off = seqno - highest_ack_; // offset of seg in window
  868. int datalen;
  869. //int amtsent = 0;
  870. // be careful if we have not received any ACK yet
  871. if (highest_ack_ < 0) {
  872. if (!infinite_send_)
  873. buffered_bytes = curseq_ - iss_;;
  874. off = seqno - iss_;
  875. }
  876. if (syn && !data_on_syn_)
  877. datalen = 0;
  878. else if (pipectrl_)
  879. datalen = buffered_bytes - off;
  880. else
  881. datalen = min(buffered_bytes, win) - off;
  882.         if ((signal_on_empty_) && (!buffered_bytes) && (!syn))
  883.                 bufferempty();
  884. //
  885. // in real TCP datalen (len) could be < 0 if there was window
  886. // shrinkage, or if a FIN has been sent and neither ACKd nor
  887. // retransmitted.  Only this 2nd case concerns us here...
  888. //
  889. if (datalen < 0) {
  890. datalen = 0;
  891. } else if (datalen > maxseg_) {
  892. datalen = maxseg_;
  893. }
  894. //
  895. // this is an option that causes us to slow-start if we've
  896. // been idle for a "long" time, where long means a rto or longer
  897. // the slow-start is a sort that does not set ssthresh
  898. //
  899. if (slow_start_restart_ && quiet && datalen > 0) {
  900. if (idle_restart()) {
  901. slowdown(CLOSE_CWND_INIT);
  902. }
  903. }
  904. //
  905. // see if sending this packet will empty the send buffer
  906. // a dataless SYN packet counts also
  907. //
  908. if (!infinite_send_ && ((seqno + datalen) > curseq_ || 
  909.     (syn && datalen == 0))) {
  910. emptying_buffer = TRUE;
  911. //
  912. // if not a retransmission, notify application that 
  913. // everything has been sent out at least once.
  914. //
  915. if (!syn) {
  916. idle();
  917. if (close_on_empty_ && quiet) {
  918. flags_ |= TF_NEEDCLOSE;
  919. }
  920. }
  921. pflags |= TH_PUSH;
  922. //
  923. // if close_on_empty set, we are finished
  924. // with this connection; close it
  925. //
  926. } else  {
  927. /* not emptying buffer, so can't be FIN */
  928. pflags &= ~TH_FIN;
  929. }
  930. if (infinite_send_ && (syn && datalen == 0))
  931. pflags |= TH_PUSH;  // set PUSH for dataless SYN
  932. /* sender SWS avoidance (Nagle) */
  933. if (datalen > 0) {
  934. // if full-sized segment, ok
  935. if (datalen == maxseg_)
  936. goto send;
  937. // if Nagle disabled and buffer clearing, ok
  938. if ((quiet || nodelay_)  && emptying_buffer)
  939. goto send;
  940. // if a retransmission
  941. if (is_retransmit)
  942. goto send;
  943. // if big "enough", ok...
  944. // (this is not a likely case, and would
  945. // only happen for tiny windows)
  946. if (datalen >= ((wnd_ * maxseg_) / 2.0))
  947. goto send;
  948. }
  949. if (need_send())
  950. goto send;
  951. /*
  952.  * send now if a control packet or we owe peer an ACK
  953.  * TF_ACKNOW can be set during connection establishment and
  954.  * to generate acks for out-of-order data
  955.  */
  956. if ((flags_ & (TF_ACKNOW|TF_NEEDCLOSE)) ||
  957.     (pflags & (TH_SYN|TH_FIN))) {
  958. goto send;
  959. }
  960.         /*      
  961.          * No reason to send a segment, just return.
  962.          */      
  963. return 0;
  964. send:
  965. // is a syn or fin?
  966. syn = (pflags & TH_SYN) ? 1 : 0;
  967. int fin = (pflags & TH_FIN) ? 1 : 0;
  968.         /* setup ECN syn and ECN SYN+ACK packet headers */
  969.         if (ecn_ && syn && !(pflags & TH_ACK)){
  970.                 pflags |= TH_ECE;
  971.                 pflags |= TH_CWR;
  972.         }
  973.         if (ecn_ && syn && (pflags & TH_ACK)){
  974.                 pflags |= TH_ECE;
  975.                 pflags &= ~TH_CWR;
  976.         }
  977. else if (ecn_ && ect_ && cong_action_ && 
  978.              (!is_retransmit || SetCWRonRetransmit_)) 
  979. /* 
  980.  * Don't set CWR for a retranmitted SYN+ACK (has ecn_ 
  981.  * and cong_action_ set) or on any retransmits.
  982.  * -M. Weigle 6/19/02
  983.  */
  984. /* set CWR if necessary */
  985. pflags |= TH_CWR;
  986. /* moved from sendpacket()  -M. Weigle 6/19/02 */
  987. //
  988. // although CWR bit is ordinarily associated with ECN,
  989. // it has utility within the simulator for traces. Thus, set
  990. // it even if we aren't doing ECN
  991. //
  992. if (datalen > 0 && cong_action_ && !is_retransmit) {
  993. pflags |= TH_CWR;
  994. }
  995.   
  996.         /* set ECE if necessary */
  997.         if (ecn_ && ect_ && recent_ce_ ) {
  998. pflags |= TH_ECE;
  999. }
  1000.         /* 
  1001.          * Tack on the FIN flag to the data segment if close_on_empty_
  1002.          * was previously set-- avoids sending a separate FIN
  1003.          */ 
  1004.         if (flags_ & TF_NEEDCLOSE) {
  1005.                 flags_ &= ~TF_NEEDCLOSE;
  1006.                 if (state_ <= TCPS_ESTABLISHED && state_ != TCPS_CLOSED)
  1007.                 {
  1008.                     pflags |=TH_FIN;
  1009.                     fin = 1;  /* FIN consumes sequence number */
  1010.                     newstate(TCPS_FIN_WAIT_1);
  1011.                 }
  1012.         }
  1013. sendpacket(seqno, rcv_nxt_, pflags, datalen, reason);
  1014.         /*      
  1015.          * Data sent (as far as we can tell).
  1016.          * Any pending ACK has now been sent.
  1017.          */      
  1018. flags_ &= ~(TF_ACKNOW|TF_DELACK);
  1019. /*
  1020.  * if we have reacted to congestion recently, the
  1021.  * slowdown() procedure will have set cong_action_ and
  1022.  * sendpacket will have copied that to the outgoing pkt
  1023.  * CWR field. If that packet contains data, then
  1024.  * it will be reliably delivered, so we are free to turn off the
  1025.  * cong_action_ state now  If only a pure ACK, we keep the state
  1026.  * around until we actually send a segment
  1027.  */
  1028. int reliable = datalen + syn + fin; // seq #'s reliably sent
  1029. /* 
  1030.  * Don't reset cong_action_ until we send new data.
  1031.  * -M. Weigle 6/19/02
  1032.  */
  1033. if (cong_action_ && reliable > 0 && !is_retransmit)
  1034. cong_action_ = FALSE;
  1035. // highest: greatest sequence number sent + 1
  1036. // and adjusted for SYNs and FINs which use up one number
  1037. int highest = seqno + reliable;
  1038. if (highest > maxseq_) {
  1039. maxseq_ = highest;
  1040. //
  1041. // if we are using conventional RTT estimation,
  1042. // establish timing on this segment
  1043. //
  1044. if (!ts_option_ && rtt_active_ == FALSE) {
  1045. rtt_active_ = TRUE; // set timer
  1046. rtt_seq_ = seqno;  // timed seq #
  1047. rtt_ts_ = now(); // when set
  1048. }
  1049. }
  1050. /*
  1051.  * Set retransmit timer if not currently set,
  1052.  * and not doing an ack or a keep-alive probe.
  1053.  * Initial value for retransmit timer is smoothed
  1054.  * round-trip time + 2 * round-trip time variance.
  1055.  * Future values are rtt + 4 * rttvar.
  1056.  */
  1057. if (rtx_timer_.status() != TIMER_PENDING && reliable) {
  1058. set_rtx_timer();  // no timer pending, schedule one
  1059. }
  1060. return (reliable);
  1061. }
  1062. /*
  1063.  *
  1064.  * send_much: send as much data as we are allowed to.  This is
  1065.  * controlled by the "pipectrl_" variable.  If pipectrl_ is set
  1066.  * to FALSE, then we are working as a normal window-based TCP and
  1067.  * we are allowed to send whatever the window allows.
  1068.  * If pipectrl_ is set to TRUE, then we are allowed to send whatever
  1069.  * pipe_ allows us to send.  One tricky part is to make sure we
  1070.  * do not overshoot the receiver's advertised window if we are
  1071.  * in (pipectrl_ == TRUE) mode.
  1072.  */
  1073.   
  1074. void
  1075. FullTcpAgent::send_much(int force, int reason, int maxburst)
  1076. {
  1077. int npackets = 0; // sent so far
  1078. //if ((int(t_seqno_)) > 1)
  1079. //printf("%f: send_much(f:%d, win:%d, pipectrl:%d, pipe:%d, t_seqno:%d, topwin:%d, maxseq_:%dn",
  1080. //now(), force, win, pipectrl_, pipe_, int(t_seqno_), topwin, int(maxseq_));
  1081. if (!force && (delsnd_timer_.status() == TIMER_PENDING))
  1082. return;
  1083. while (1) {
  1084. /*
  1085.  * note that if output decides to not actually send
  1086.  * (e.g. because of Nagle), then if we don't break out
  1087.  * of this loop, we can loop forever at the same
  1088.  * simulated time instant
  1089.  */
  1090. int amt;
  1091. int seq = nxt_tseq();
  1092. if (!force && !send_allowed(seq))
  1093. break;
  1094. // Q: does this need to be here too?
  1095. if (!force && overhead_ != 0 &&
  1096.     (delsnd_timer_.status() != TIMER_PENDING)) {
  1097. delsnd_timer_.resched(Random::uniform(overhead_));
  1098. return;
  1099. }
  1100. if ((amt = foutput(seq, reason)) <= 0)
  1101. break;
  1102. if ((outflags() & TH_FIN))
  1103. --amt; // don't count FINs
  1104. sent(seq, amt);
  1105. force = 0;
  1106. if ((outflags() & (TH_SYN|TH_FIN)) ||
  1107.     (maxburst && ++npackets >= maxburst))
  1108. break;
  1109. }
  1110. return;
  1111. }
  1112. /*
  1113.  * base TCP: we are allowed to send a sequence number if it
  1114.  * is in the window
  1115.  */
  1116. int
  1117. FullTcpAgent::send_allowed(int seq)
  1118. {
  1119.         int win = window() * maxseg_;
  1120.         int topwin = curseq_; // 1 seq number past the last byte we can send
  1121.         if ((topwin > highest_ack_ + win) || infinite_send_)
  1122.                 topwin = highest_ack_ + win; 
  1123. return (seq < topwin);
  1124. }
  1125. /*
  1126.  * Process an ACK
  1127.  * this version of the routine doesn't necessarily
  1128.  * require the ack to be one which advances the ack number
  1129.  *
  1130.  * if this ACKs a rtt estimate
  1131.  * indicate we are not timing
  1132.  * reset the exponential timer backoff (gamma)
  1133.  * update rtt estimate
  1134.  * cancel retrans timer if everything is sent and ACK'd, else set it
  1135.  * advance the ack number if appropriate
  1136.  * update segment to send next if appropriate
  1137.  */
  1138. void
  1139. FullTcpAgent::newack(Packet* pkt)
  1140. {
  1141. hdr_tcp *tcph = hdr_tcp::access(pkt);
  1142. register int ackno = tcph->ackno();
  1143. int progress = (ackno > highest_ack_);
  1144. if (ackno == maxseq_) {
  1145. cancel_rtx_timer(); // all data ACKd
  1146. } else if (progress) {
  1147. set_rtx_timer();
  1148. }
  1149. // advance the ack number if this is for new data
  1150. if (progress)
  1151. highest_ack_ = ackno;
  1152. // if we have suffered a retransmit timeout, t_seqno_
  1153. // will have been reset to highest_ ack.  If the
  1154. // receiver has cached some data above t_seqno_, the
  1155. // new-ack value could (should) jump forward.  We must
  1156. // update t_seqno_ here, otherwise we would be doing
  1157. // go-back-n.
  1158. if (t_seqno_ < highest_ack_)
  1159. t_seqno_ = highest_ack_; // seq# to send next
  1160.         /*
  1161.          * Update RTT only if it's OK to do so from info in the flags header.
  1162.          * This is needed for protocols in which intermediate agents
  1163.          * in the network intersperse acks (e.g., ack-reconstructors) for
  1164.          * various reasons (without violating e2e semantics).
  1165.          */
  1166.         hdr_flags *fh = hdr_flags::access(pkt);
  1167. if (!fh->no_ts_) {
  1168.                 if (ts_option_) {
  1169. recent_age_ = now();
  1170. recent_ = tcph->ts();
  1171. rtt_update(now() - tcph->ts_echo());
  1172. if (ts_resetRTO_ && (!ect_ || !ecn_backoff_ ||
  1173.            !hdr_flags::access(pkt)->ecnecho())) { 
  1174. // From Andrei Gurtov
  1175. //
  1176.                           // Don't end backoff if still in ECN-Echo with
  1177.                           // a congestion window of 1 packet.
  1178. t_backoff_ = 1;
  1179. }
  1180. } else if (rtt_active_ && ackno > rtt_seq_) {
  1181. // got an RTT sample, record it
  1182. // "t_backoff_ = 1;" deleted by T. Kelly.
  1183. rtt_active_ = FALSE;
  1184. rtt_update(now() - rtt_ts_);
  1185.                 }
  1186. if (!ect_ || !ecn_backoff_ ||
  1187.     !hdr_flags::access(pkt)->ecnecho()) {
  1188. /*
  1189.  * Don't end backoff if still in ECN-Echo with
  1190.  * a congestion window of 1 packet.
  1191.  * Fix from T. Kelly.
  1192.  */
  1193. t_backoff_ = 1;
  1194. ecn_backoff_ = 0;
  1195. }
  1196.         }
  1197. return;
  1198. }
  1199. /*
  1200.  * this is the simulated form of the header prediction
  1201.  * predicate.  While not really necessary for a simulation, it
  1202.  * follows the code base more closely and can sometimes help to reveal
  1203.  * odd behavior caused by the implementation structure..
  1204.  *
  1205.  * Here's the comment from the real TCP:
  1206.  *
  1207.  * Header prediction: check for the two common cases
  1208.  * of a uni-directional data xfer.  If the packet has
  1209.  * no control flags, is in-sequence, the window didn't
  1210.  * change and we're not retransmitting, it's a
  1211.  * candidate.  If the length is zero and the ack moved
  1212.  * forward, we're the sender side of the xfer.  Just
  1213.  * free the data acked & wake any higher level process
  1214.  * that was blocked waiting for space.  If the length
  1215.  * is non-zero and the ack didn't move, we're the
  1216.  * receiver side.  If we're getting packets in-order
  1217.  * (the reassembly queue is empty), add the data to
  1218.  * the socket buffer and note that we need a delayed ack.
  1219.  * Make sure that the hidden state-flags are also off.
  1220.  * Since we check for TCPS_ESTABLISHED above, it can only
  1221.  * be TF_NEEDSYN.
  1222.  */
  1223. int
  1224. FullTcpAgent::predict_ok(Packet* pkt)
  1225. {
  1226. hdr_tcp *tcph = hdr_tcp::access(pkt);
  1227.         hdr_flags *fh = hdr_flags::access(pkt);
  1228. /* not the fastest way to do this, but perhaps clearest */
  1229. int p1 = (state_ == TCPS_ESTABLISHED); // ready
  1230. int p2 = ((tcph->flags() & (TH_SYN|TH_FIN|TH_ACK)) == TH_ACK); // ACK
  1231. int p3 = ((flags_ & TF_NEEDFIN) == 0); // don't need fin
  1232. int p4 = (!ts_option_ || fh->no_ts_ || (tcph->ts() >= recent_)); // tsok
  1233. int p5 = (tcph->seqno() == rcv_nxt_); // in-order data
  1234. int p6 = (t_seqno_ == maxseq_); // not re-xmit
  1235. int p7 = (!ecn_ || fh->ecnecho() == 0); // no ECN
  1236. int p8 = (tcph->sa_length() == 0); // no SACK info
  1237. return (p1 && p2 && p3 && p4 && p5 && p6 && p7 && p8);
  1238. }
  1239. /*
  1240.  * fast_retransmit using the given seqno
  1241.  * perform fast RTX, set recover_, set last_cwnd_action
  1242.  */
  1243. int
  1244. FullTcpAgent::fast_retransmit(int seq)
  1245. {
  1246. // we are now going to fast-retransmit and willtrace that event
  1247. trace_event("FAST_RETX");
  1248. recover_ = maxseq_; // recovery target
  1249. last_cwnd_action_ = CWND_ACTION_DUPACK;
  1250. return(foutput(seq, REASON_DUPACK)); // send one pkt
  1251. }
  1252. /*
  1253.  * real tcp determines if the remote
  1254.  * side should receive a window update/ACK from us, and often
  1255.  * results in sending an update every 2 segments, thereby
  1256.  * giving the familiar 2-packets-per-ack behavior of TCP.
  1257.  * Here, we don't advertise any windows, so we just see if
  1258.  * there's at least 'segs_per_ack_' pkts not yet acked
  1259.  *
  1260.  * also, provide for a segs-per-ack "threshold" where
  1261.  * we generate 1-ack-per-seg until enough stuff
  1262.  * (spa_thresh_ bytes) has been received from the other side
  1263.  * This idea came from vj/kmn in BayTcp.  Added 8/21/01.
  1264.  */
  1265. int
  1266. FullTcpAgent::need_send()
  1267. {
  1268. if (flags_ & TF_ACKNOW)
  1269. return TRUE;
  1270. int spa = (spa_thresh_ > 0 && ((rcv_nxt_ - irs_)  < spa_thresh_)) ?
  1271. 1 : segs_per_ack_;
  1272. return ((rcv_nxt_ - last_ack_sent_) >= (spa * maxseg_));
  1273. }
  1274. /*
  1275.  * determine whether enough time has elapsed in order to
  1276.  * conclude a "restart" is necessary (e.g. a slow-start)
  1277.  *
  1278.  * for now, keep track of this similarly to how rtt_update() does
  1279.  */
  1280. int
  1281. FullTcpAgent::idle_restart()
  1282. {
  1283. if (last_send_time_ < 0.0) {
  1284. // last_send_time_ isn't set up yet, we shouldn't
  1285. // do the idle_restart
  1286. return (0);
  1287. }
  1288. double tao = now() - last_send_time_;
  1289. if (!ts_option_) {
  1290.                 double tickoff = fmod(last_send_time_ + boot_time_,
  1291. tcp_tick_);
  1292.                 tao = int((tao + tickoff) / tcp_tick_) * tcp_tick_;
  1293. }
  1294. return (tao > t_rtxcur_);  // verify this CHECKME
  1295. }
  1296. /*
  1297.  * tcp-full's version of set_initial_window()... over-rides
  1298.  * the one in tcp.cc
  1299.  */
  1300. void
  1301. FullTcpAgent::set_initial_window()
  1302. {
  1303. syn_ = TRUE; // full-tcp always models SYN exchange
  1304. TcpAgent::set_initial_window();
  1305. }       
  1306. /*
  1307.  * main reception path - 
  1308.  * called from the agent that handles the data path below in its muxing mode
  1309.  * advance() is called when connection is established with size sent from
  1310.  * user/application agent
  1311.  *
  1312.  * This is a fairly complex function.  It operates generally as follows:
  1313.  * do header prediction for simple cases (pure ACKS or data)
  1314.  * if in LISTEN and we get a SYN, begin initializing connection
  1315.  * if in SYN_SENT and we get an ACK, complete connection init
  1316.  * trim any redundant data from received dataful segment
  1317.  * deal with ACKS:
  1318.  * if in SYN_RCVD, complete connection init then go on
  1319.  * see if ACK is old or at the current highest_ack
  1320.  * if at current high, is the threshold reached or not
  1321.  * if so, maybe do fast rtx... otherwise drop or inflate win
  1322.  * deal with incoming data
  1323.  * deal with FIN bit on in arriving packet
  1324.  */
  1325. void
  1326. FullTcpAgent::recv(Packet *pkt, Handler*)
  1327. {
  1328. hdr_tcp *tcph = hdr_tcp::access(pkt); // TCP header
  1329. hdr_cmn *th = hdr_cmn::access(pkt); // common header (size, etc)
  1330. hdr_flags *fh = hdr_flags::access(pkt); // flags (CWR, CE, bits)
  1331. int needoutput = FALSE;
  1332. int ourfinisacked = FALSE;
  1333. int dupseg = FALSE; // recv'd dup data segment
  1334. int todrop = 0; // duplicate DATA cnt in seg
  1335. last_state_ = state_;
  1336. int datalen = th->size() - tcph->hlen(); // # payload bytes
  1337. int ackno = tcph->ackno();  // ack # from packet
  1338. int tiflags = tcph->flags() ;   // tcp flags from packet
  1339. //if (state_ != TCPS_ESTABLISHED || (tiflags&(TH_SYN|TH_FIN))) {
  1340. //fprintf(stdout, "%f(%s)in state %s recv'd this packet: ", now(), name(), statestr(state_));
  1341. //prpkt(pkt);
  1342. //}
  1343. /* 
  1344.  * Acknowledge FIN from passive closer even in TCPS_CLOSED state
  1345.  * (since we lack TIME_WAIT state and RST packets,
  1346.  * the loss of the FIN packet from the passive closer will make that
  1347.  * endpoint retransmit the FIN forever)
  1348.  * -F. Hernandez-Campos 8/6/00
  1349.  */
  1350. if ( (state_ == TCPS_CLOSED) && (tiflags & TH_FIN) ) {
  1351. goto dropafterack;
  1352. }
  1353. /*
  1354.  * Don't expect to see anything while closed
  1355.  */
  1356. if (state_ == TCPS_CLOSED) {
  1357.                 if (debug_) {
  1358.         fprintf(stderr, "%f: FullTcp(%s): recv'd pkt in CLOSED state: ",
  1359.     now(), name());
  1360.         prpkt(pkt);
  1361.                 }
  1362. goto drop;
  1363. }
  1364.         /*
  1365.          * Process options if not in LISTEN state,
  1366.          * else do it below
  1367.          */
  1368. if (state_ != TCPS_LISTEN)
  1369. dooptions(pkt);
  1370. /*
  1371.  * if we are using delayed-ACK timers and
  1372.  * no delayed-ACK timer is set, set one.
  1373.  * They are set to fire every 'interval_' secs, starting
  1374.  * at time t0 = (0.0 + k * interval_) for some k such
  1375.  * that t0 > now
  1376.  */
  1377. if (delack_interval_ > 0.0 &&
  1378.     (delack_timer_.status() != TIMER_PENDING)) {
  1379. int last = int(now() / delack_interval_);
  1380. delack_timer_.resched(delack_interval_ * (last + 1.0) - now());
  1381. }
  1382. /*
  1383.  * Try header prediction: in seq data or in seq pure ACK
  1384.  * with no funny business
  1385.  */
  1386. if (!nopredict_ && predict_ok(pkt)) {
  1387.                 /*
  1388.                  * If last ACK falls within this segment's sequence numbers,
  1389.                  * record the timestamp.
  1390.  * See RFC1323 (now RFC1323 bis)
  1391.                  */
  1392.                 if (ts_option_ && !fh->no_ts_ &&
  1393.     tcph->seqno() <= last_ack_sent_) {
  1394. /*
  1395.  * this is the case where the ts value is newer than
  1396.  * the last one we've seen, and the seq # is the one
  1397.  * we expect [seqno == last_ack_sent_] or older
  1398.  */
  1399. recent_age_ = now();
  1400. recent_ = tcph->ts();
  1401.                 }
  1402. //
  1403. // generate a stream of ecnecho bits until we see a true
  1404. // cong_action bit
  1405. //
  1406.      if (ecn_) {
  1407.      if (fh->ce() && fh->ect()) {
  1408.      // no CWR from peer yet... arrange to
  1409.      // keep sending ECNECHO
  1410.      recent_ce_ = TRUE;
  1411.      } else if (fh->cwr()) {
  1412.      // got CWR response from peer.. stop
  1413.      // sending ECNECHO bits
  1414.      recent_ce_ = FALSE;
  1415.      }
  1416.      }
  1417. // Header predication basically looks to see
  1418. // if the incoming packet is an expected pure ACK
  1419. // or an expected data segment
  1420. if (datalen == 0) {
  1421. // check for a received pure ACK in the correct range..
  1422. // also checks to see if we are wnd_ limited
  1423. // (we don't change cwnd at all below), plus
  1424. // not being in fast recovery and not a partial ack.
  1425. // If we are in fast
  1426. // recovery, go below so we can remember to deflate
  1427. // the window if we need to
  1428. if (ackno > highest_ack_ && ackno < maxseq_ &&
  1429.     cwnd_ >= wnd_ && !fastrecov_) {
  1430. newack(pkt); // update timers,  highest_ack_
  1431. send_much(0, REASON_NORMAL, maxburst_);
  1432. Packet::free(pkt);
  1433. return;
  1434. }
  1435. } else if (ackno == highest_ack_ && rq_.empty()) {
  1436. // check for pure incoming segment
  1437. // the next data segment we're awaiting, and
  1438. // that there's nothing sitting in the reassem-
  1439. // bly queue
  1440. //  give to "application" here
  1441. // note: DELACK is inspected only by
  1442. // tcp_fasttimo() in real tcp.  Every 200 ms
  1443. // this routine scans all tcpcb's looking for
  1444. // DELACK segments and when it finds them
  1445. // changes DELACK to ACKNOW and calls tcp_output()
  1446. rcv_nxt_ += datalen;
  1447. flags_ |= TF_DELACK;
  1448. recvBytes(datalen); // notify application of "delivery"
  1449. //
  1450. // special code here to simulate the operation
  1451. // of a receiver who always consumes data,
  1452. // resulting in a call to tcp_output
  1453. Packet::free(pkt);
  1454. if (need_send())
  1455. send_much(1, REASON_NORMAL, maxburst_);
  1456. return;
  1457. }
  1458. } /* header prediction */
  1459. //
  1460. // header prediction failed
  1461. // (e.g. pure ACK out of valid range, SACK present, etc)...
  1462. // do slow path processing
  1463. //
  1464. // the following switch does special things for these states:
  1465. // TCPS_LISTEN, TCPS_SYN_SENT
  1466. //
  1467. switch (state_) {
  1468.         /*
  1469.          * If the segment contains an ACK then it is bad and do reset.
  1470.          * If it does not contain a SYN then it is not interesting; drop it.
  1471.          * Otherwise initialize tp->rcv_nxt, and tp->irs, iss is already
  1472.  * selected, and send a segment:
  1473.          *     <SEQ=ISS><ACK=RCV_NXT><CTL=SYN,ACK>
  1474.          * Initialize tp->snd_nxt to tp->iss.
  1475.          * Enter SYN_RECEIVED state, and process any other fields of this
  1476.          * segment in this state.
  1477.          */
  1478. case TCPS_LISTEN: /* awaiting peer's SYN */
  1479. if (tiflags & TH_ACK) {
  1480.                         if (debug_) {
  1481.              fprintf(stderr,
  1482.      "%f: FullTcpAgent(%s): warning: recv'd ACK while in LISTEN: ",
  1483.     now(), name());
  1484.         prpkt(pkt);
  1485.                         }
  1486. // don't want ACKs in LISTEN
  1487. goto dropwithreset;
  1488. }
  1489. if ((tiflags & TH_SYN) == 0) {
  1490.                         if (debug_) {
  1491.              fprintf(stderr, "%f: FullTcpAgent(%s): warning: recv'd NON-SYN while in LISTENn",
  1492. now(), name());
  1493.         prpkt(pkt);
  1494.                         }
  1495. // any non-SYN is discarded
  1496. goto drop;
  1497. }
  1498. /*
  1499.  * must by a SYN (no ACK) at this point...
  1500.  * in real tcp we would bump the iss counter here also
  1501.  */
  1502. dooptions(pkt);
  1503. irs_ = tcph->seqno();
  1504. t_seqno_ = iss_; /* tcp_sendseqinit() macro in real tcp */
  1505. rcv_nxt_ = rcvseqinit(irs_, datalen);
  1506. flags_ |= TF_ACKNOW;
  1507. // check for a ECN-SYN with ECE|CWR
  1508. if (ecn_ && fh->ecnecho() && fh->cong_action()) {
  1509. ect_ = TRUE;
  1510. }
  1511. if (fid_ == 0) {
  1512. // XXX: sort of hack... If we do not
  1513. // have a special flow ID, pick up that
  1514. // of the sender (active opener)
  1515. hdr_ip* iph = hdr_ip::access(pkt);
  1516. fid_ = iph->flowid();
  1517. }
  1518. newstate(TCPS_SYN_RECEIVED);
  1519. goto trimthenstep6;
  1520.         /*
  1521.          * If the state is SYN_SENT:
  1522.          *      if seg contains an ACK, but not for our SYN, drop the input.
  1523.          *      if seg does not contain SYN, then drop it.
  1524.          * Otherwise this is an acceptable SYN segment
  1525.          *      initialize tp->rcv_nxt and tp->irs
  1526.          *      if seg contains ack then advance tp->snd_una
  1527.          *      if SYN has been acked change to ESTABLISHED else SYN_RCVD state
  1528.          *      arrange for segment to be acked (eventually)
  1529.          *      continue processing rest of data/controls, beginning with URG
  1530.          */
  1531. case TCPS_SYN_SENT: /* we sent SYN, expecting SYN+ACK (or SYN) */
  1532. /* drop if it's a SYN+ACK and the ack field is bad */
  1533. if ((tiflags & TH_ACK) &&
  1534. ((ackno <= iss_) || (ackno > maxseq_))) {
  1535. // not an ACK for our SYN, discard
  1536.                         if (debug_) {
  1537.        fprintf(stderr, "%f: FullTcpAgent::recv(%s): bad ACK for our SYN: ",
  1538.         now(), name());
  1539.         prpkt(pkt);
  1540.                         }
  1541. goto dropwithreset;
  1542. }
  1543. if ((tiflags & TH_SYN) == 0) {
  1544.                         if (debug_) {
  1545.         fprintf(stderr, "%f: FullTcpAgent::recv(%s): no SYN for our SYN: ",
  1546.         now(), name());
  1547.         prpkt(pkt);
  1548.                         }
  1549. goto drop;
  1550. }
  1551. /* looks like an ok SYN or SYN+ACK */
  1552. #ifdef notdef
  1553. cancel_rtx_timer(); // cancel timer on our 1st SYN [does this belong!?]
  1554. #endif
  1555. irs_ = tcph->seqno(); // get initial recv'd seq #
  1556. rcv_nxt_ = rcvseqinit(irs_, datalen);
  1557. if (tiflags & TH_ACK) {
  1558. // SYN+ACK (our SYN was acked)
  1559.                         if (ecn_ && fh->ecnecho() && !fh->cong_action()) {
  1560.                                 ect_ = TRUE;
  1561.              if ( fh->ce() ) 
  1562.      recent_ce_ = TRUE;
  1563.      }
  1564. highest_ack_ = ackno;
  1565. cwnd_ = initial_window();
  1566. #ifdef notdef
  1567. /*
  1568.  * if we didn't have to retransmit the SYN,
  1569.  * use its rtt as our initial srtt & rtt var.
  1570.  */
  1571. if (t_rtt_) {
  1572. double tao = now() - tcph->ts();
  1573. rtt_update(tao);
  1574. }
  1575. #endif
  1576. /*
  1577.  * if there's data, delay ACK; if there's also a FIN
  1578.  * ACKNOW will be turned on later.
  1579.  */
  1580. if (datalen > 0) {
  1581. flags_ |= TF_DELACK; // data there: wait
  1582. } else {
  1583. flags_ |= TF_ACKNOW; // ACK peer's SYN
  1584. }
  1585.                         /*
  1586.                          * Received <SYN,ACK> in SYN_SENT[*] state.
  1587.                          * Transitions:
  1588.                          *      SYN_SENT  --> ESTABLISHED
  1589.                          *      SYN_SENT* --> FIN_WAIT_1
  1590.                          */
  1591. if (flags_ & TF_NEEDFIN) {
  1592. newstate(TCPS_FIN_WAIT_1);
  1593. flags_ &= ~TF_NEEDFIN;
  1594. tiflags &= ~TH_SYN;
  1595. } else {
  1596. newstate(TCPS_ESTABLISHED);
  1597. }
  1598. // special to ns:
  1599. //  generate pure ACK here.
  1600. //  this simulates the ordinary connection establishment
  1601. //  where the ACK of the peer's SYN+ACK contains
  1602. //  no data.  This is typically caused by the way
  1603. //  the connect() socket call works in which the
  1604. //  entire 3-way handshake occurs prior to the app
  1605. //  being able to issue a write() [which actually
  1606. //  causes the segment to be sent].
  1607. sendpacket(t_seqno_, rcv_nxt_, TH_ACK, 0, 0);
  1608. } else {
  1609. // Check ECN-SYN packet
  1610.                         if (ecn_ && fh->ecnecho() && fh->cong_action())
  1611.                                 ect_ = TRUE;
  1612. // SYN (no ACK) (simultaneous active opens)
  1613. flags_ |= TF_ACKNOW;
  1614. cancel_rtx_timer();
  1615. newstate(TCPS_SYN_RECEIVED);
  1616. /*
  1617.  * decrement t_seqno_: we are sending a
  1618.  * 2nd SYN (this time in the form of a
  1619.  * SYN+ACK, so t_seqno_ will have been
  1620.  * advanced to 2... reduce this
  1621.  */
  1622. t_seqno_--; // CHECKME
  1623. }
  1624. trimthenstep6:
  1625. /*
  1626.  * advance the seq# to correspond to first data byte
  1627.  */
  1628. tcph->seqno()++;
  1629. if (tiflags & TH_ACK)
  1630. goto process_ACK;
  1631. goto step6;
  1632. case TCPS_LAST_ACK:
  1633. /* 
  1634.  * The only way we're in LAST_ACK is if we've already
  1635.  * received a FIN, so ignore all retranmitted FINS.
  1636.  * -M. Weigle 7/23/02
  1637.  */
  1638. if (tiflags & TH_FIN) {
  1639. goto drop;
  1640. }
  1641. break;
  1642. case TCPS_CLOSING:
  1643. break;
  1644. } /* end switch(state_) */
  1645.         /*
  1646.          * States other than LISTEN or SYN_SENT.
  1647.          * First check timestamp, if present.
  1648.          * Then check that at least some bytes of segment are within
  1649.          * receive window.  If segment begins before rcv_nxt,
  1650.          * drop leading data (and SYN); if nothing left, just ack.
  1651.          *
  1652.          * RFC 1323 PAWS: If we have a timestamp reply on this segment
  1653.          * and it's less than ts_recent, drop it.
  1654.          */
  1655. if (ts_option_ && !fh->no_ts_ && recent_ && tcph->ts() < recent_) {
  1656. if ((now() - recent_age_) > TCP_PAWS_IDLE) {
  1657. /*
  1658.  * this is basically impossible in the simulator,
  1659.  * but here it is...
  1660.  */
  1661.                         /*
  1662.                          * Invalidate ts_recent.  If this segment updates
  1663.                          * ts_recent, the age will be reset later and ts_recent
  1664.                          * will get a valid value.  If it does not, setting
  1665.                          * ts_recent to zero will at least satisfy the
  1666.                          * requirement that zero be placed in the timestamp
  1667.                          * echo reply when ts_recent isn't valid.  The
  1668.                          * age isn't reset until we get a valid ts_recent
  1669.                          * because we don't want out-of-order segments to be
  1670.                          * dropped when ts_recent is old.
  1671.                          */
  1672. recent_ = 0.0;
  1673. } else {
  1674. fprintf(stderr, "%f: FullTcpAgent(%s): dropped pkt due to bad tsn",
  1675. now(), name());
  1676. goto dropafterack;
  1677. }
  1678. }
  1679. // check for redundant data at head/tail of segment
  1680. // note that the 4.4bsd [Net/3] code has
  1681. // a bug here which can cause us to ignore the
  1682. // perfectly good ACKs on duplicate segments.  The
  1683. // fix is described in (Stevens, Vol2, p. 959-960).
  1684. // This code is based on that correction.
  1685. //
  1686. // In addition, it has a modification so that duplicate segments
  1687. // with dup acks don't trigger a fast retransmit when dupseg_fix_
  1688. // is enabled.
  1689. //
  1690. // Yet one more modification: make sure that if the received
  1691. // segment had datalen=0 and wasn't a SYN or FIN that
  1692. // we don't turn on the ACKNOW status bit.  If we were to
  1693. // allow ACKNOW to be turned on, normal pure ACKs that happen
  1694. // to have seq #s below rcv_nxt can trigger an ACK war by
  1695. // forcing us to ACK the pure ACKs
  1696. //
  1697. // Update: if we have a dataless FIN, don't really want to
  1698. // do anything with it.  In particular, would like to
  1699. // avoid ACKing an incoming FIN+ACK while in CLOSING
  1700. //
  1701. todrop = rcv_nxt_ - tcph->seqno();  // how much overlap?
  1702. if (todrop > 0 && ((tiflags & (TH_SYN)) || datalen > 0)) {
  1703. //printf("%f(%s): trim 1..todrop:%d, dlen:%dn",now(), name(), todrop, datalen);
  1704. if (tiflags & TH_SYN) {
  1705. tiflags &= ~TH_SYN;
  1706. tcph->seqno()++;
  1707. th->size()--; // XXX Must decrease packet size too!!
  1708. // Q: Why?.. this is only a SYN
  1709. todrop--;
  1710. }
  1711. //
  1712. // see Stevens, vol 2, p. 960 for this check;
  1713. // this check is to see if we are dropping
  1714. // more than this segment (i.e. the whole pkt + a FIN),
  1715. // or just the whole packet (no FIN)
  1716. //
  1717. if ((todrop > datalen) ||
  1718.     (todrop == datalen && ((tiflags & TH_FIN) == 0))) {
  1719. //printf("%f(%s): trim 2..todrop:%d, dlen:%dn",now(), name(), todrop, datalen);
  1720.                         /*
  1721.                          * Any valid FIN must be to the left of the window.
  1722.                          * At this point the FIN must be a duplicate or out
  1723.                          * of sequence; drop it.
  1724.                          */
  1725. tiflags &= ~TH_FIN;
  1726. /*
  1727.  * Send an ACK to resynchronize and drop any data.
  1728.  * But keep on processing for RST or ACK.
  1729.  */
  1730. flags_ |= TF_ACKNOW;
  1731. todrop = datalen;
  1732. dupseg = TRUE; // *completely* duplicate
  1733. }
  1734. /*
  1735.  * Trim duplicate data from the front of the packet
  1736.  */
  1737. tcph->seqno() += todrop;
  1738. th->size() -= todrop; // XXX Must decrease size too!!
  1739. // why? [kf]..prob when put in RQ
  1740. datalen -= todrop;
  1741. } /* data trim */
  1742. /*
  1743.  * If we are doing timstamps and this packet has one, and
  1744.  * If last ACK falls within this segment's sequence numbers,
  1745.  * record the timestamp.
  1746.  * See RFC1323 (now RFC1323 bis)
  1747.  */
  1748. if (ts_option_ && !fh->no_ts_ && tcph->seqno() <= last_ack_sent_) {
  1749. /*
  1750.  * this is the case where the ts value is newer than
  1751.  * the last one we've seen, and the seq # is the one we expect
  1752.  * [seqno == last_ack_sent_] or older
  1753.  */
  1754. recent_age_ = now();
  1755. recent_ = tcph->ts();
  1756. }
  1757. if (tiflags & TH_SYN) {
  1758.                 if (debug_) {
  1759.         fprintf(stderr, "%f: FullTcpAgent::recv(%s) received unexpected SYN (state:%d): ",
  1760.         now(), name(), state_);
  1761.         prpkt(pkt);
  1762.                 }
  1763. goto dropwithreset;
  1764. }
  1765. if ((tiflags & TH_ACK) == 0) {
  1766. /*
  1767.  * Added check for state != SYN_RECEIVED.  We will receive a 
  1768.  * duplicate SYN in SYN_RECEIVED when our SYN/ACK was dropped.
  1769.  * We should just ignore the duplicate SYN (our timeout for 
  1770.  * resending the SYN/ACK is about the same as the client's 
  1771.  * timeout for resending the SYN), but give no error message. 
  1772.  * -M. Weigle 07/24/01
  1773.  */
  1774. if (state_ != TCPS_SYN_RECEIVED) {
  1775.                         if (debug_) {
  1776.         fprintf(stderr, "%f: FullTcpAgent::recv(%s) got packet lacking ACK (state:%d): ",
  1777. now(), name(), state_);
  1778.         prpkt(pkt);
  1779.                         }
  1780. }
  1781. goto drop;
  1782. }
  1783. /*
  1784.  * Ack processing.
  1785.  */
  1786. switch (state_) {
  1787. case TCPS_SYN_RECEIVED: /* want ACK for our SYN+ACK */
  1788. if (ackno < highest_ack_ || ackno > maxseq_) {
  1789. // not in useful range
  1790.                         if (debug_) {
  1791.              fprintf(stderr, "%f: FullTcpAgent(%s): ack(%d) not in range while in SYN_RECEIVED: ",
  1792.   now(), name(), ackno);
  1793.         prpkt(pkt);
  1794.                         }
  1795. goto dropwithreset;
  1796. }
  1797.                 /*
  1798.                  * Make transitions:
  1799.                  *      SYN-RECEIVED  -> ESTABLISHED
  1800.                  *      SYN-RECEIVED* -> FIN-WAIT-1
  1801.                  */
  1802.                 if (flags_ & TF_NEEDFIN) {
  1803. newstate(TCPS_FIN_WAIT_1);
  1804.                         flags_ &= ~TF_NEEDFIN;
  1805.                 } else {
  1806.                         newstate(TCPS_ESTABLISHED);
  1807.                 }
  1808. if (ecn_ && ect_ && ecn_syn_ && fh->ecnecho() )
  1809. // The SYN/ACK packet was ECN-marked.
  1810. if (ecn_syn_wait_) {
  1811. // A timer will be called in ecn().
  1812. cwnd_ = 1;
  1813. use_rtt_ = 1;
  1814. } else
  1815.         // Congestion window will be halved in ecn().
  1816. cwnd_ = 2;
  1817. else 
  1818. cwnd_ = initial_window();
  1819. /* fall into ... */
  1820.         /*
  1821.          * In ESTABLISHED state: drop duplicate ACKs; ACK out of range
  1822.          * ACKs.  If the ack is in the range
  1823.          *      tp->snd_una < ti->ti_ack <= tp->snd_max
  1824.          * then advance tp->snd_una to ti->ti_ack and drop
  1825.          * data from the retransmission queue.
  1826.  *
  1827.  * note that state TIME_WAIT isn't used
  1828.  * in the simulator
  1829.          */
  1830.         case TCPS_ESTABLISHED:
  1831.         case TCPS_FIN_WAIT_1:
  1832.         case TCPS_FIN_WAIT_2:
  1833. case TCPS_CLOSE_WAIT:
  1834.         case TCPS_CLOSING:
  1835.         case TCPS_LAST_ACK:
  1836. //
  1837. // look for ECNs in ACKs, react as necessary
  1838. //
  1839. if (fh->ecnecho() && (!ecn_ || !ect_)) {
  1840. fprintf(stderr,
  1841.     "%f: FullTcp(%s): warning, recvd ecnecho but I am not ECN capable!n",
  1842. now(), name());
  1843. }
  1844.                 //
  1845.                 // generate a stream of ecnecho bits until we see a true
  1846.                 // cong_action bit
  1847.                 // 
  1848.                 if (ecn_) {
  1849.                         if (fh->ce() && fh->ect())
  1850.                                 recent_ce_ = TRUE;
  1851.                         else if (fh->cwr())
  1852.                                 recent_ce_ = FALSE;
  1853.                 }
  1854. //
  1855. // If ESTABLISHED or starting to close, process SACKS
  1856. //
  1857. if (state_ >= TCPS_ESTABLISHED && tcph->sa_length() > 0) {
  1858. process_sack(tcph);
  1859. }
  1860. //
  1861. // ACK indicates packet left the network
  1862. // try not to be fooled by data
  1863. //
  1864. if (fastrecov_ && (datalen == 0 || ackno > highest_ack_))
  1865. pipe_ -= maxseg_;
  1866. // look for dup ACKs (dup ack numbers, no data)
  1867. //
  1868. // do fast retransmit/recovery if at/past thresh
  1869. if (ackno <= highest_ack_) {
  1870. // a pure ACK which doesn't advance highest_ack_
  1871. if (datalen == 0 && (!dupseg_fix_ || !dupseg)) {
  1872.                                 /*
  1873.                                  * If we have outstanding data
  1874.                                  * this is a completely
  1875.                                  * duplicate ack,
  1876.                                  * the ack is the biggest we've
  1877.                                  * seen and we've seen exactly our rexmt
  1878.                                  * threshhold of them, assume a packet
  1879.                                  * has been dropped and retransmit it.
  1880.                                  *
  1881.                                  * We know we're losing at the current
  1882.                                  * window size so do congestion avoidance.
  1883.                                  *
  1884.                                  * Dup acks mean that packets have left the
  1885.                                  * network (they're now cached at the receiver)
  1886.                                  * so bump cwnd by the amount in the receiver
  1887.                                  * to keep a constant cwnd packets in the
  1888.                                  * network.
  1889.                                  */
  1890. if ((rtx_timer_.status() != TIMER_PENDING) ||
  1891.     ackno < highest_ack_) {
  1892. // Q: significance of timer not pending?
  1893. // ACK below highest_ack_
  1894. oldack();
  1895. } else if (++dupacks_ == tcprexmtthresh_) {
  1896. // ACK at highest_ack_ AND meets threshold
  1897. //trace_event("FAST_RECOVERY");
  1898. dupack_action(); // maybe fast rexmt
  1899. goto drop;
  1900. } else if (dupacks_ > tcprexmtthresh_) {
  1901. // ACK at highest_ack_ AND above threshole
  1902. //trace_event("FAST_RECOVERY");
  1903. extra_ack();
  1904. // send whatever window allows
  1905. send_much(0, REASON_DUPACK, maxburst_);
  1906. goto drop;
  1907. }
  1908. } else {
  1909. // non zero-length [dataful] segment
  1910. // with a dup ack (normal for dataful segs)
  1911. // (or window changed in real TCP).
  1912. if (dupack_reset_) {
  1913. dupacks_ = 0;
  1914. fastrecov_ = FALSE;
  1915. }
  1916. }
  1917. break; /* take us to "step6" */
  1918. } /* end of dup/old acks */
  1919. /*
  1920.  * we've finished the fast retransmit/recovery period
  1921.  * (i.e. received an ACK which advances highest_ack_)
  1922.  * The ACK may be "good" or "partial"
  1923.  */
  1924. process_ACK:
  1925. if (ackno > maxseq_) {
  1926. // ack more than we sent(!?)
  1927.                         if (debug_) {
  1928.         fprintf(stderr, "%f: FullTcpAgent::recv(%s) too-big ACK (maxseq:%d): ",
  1929. now(), name(), int(maxseq_));
  1930.         prpkt(pkt);
  1931.                         }
  1932. goto dropafterack;
  1933. }
  1934.                 /*
  1935.                  * If we have a timestamp reply, update smoothed
  1936.                  * round trip time.  If no timestamp is present but
  1937.                  * transmit timer is running and timed sequence
  1938.                  * number was acked, update smoothed round trip time.
  1939.                  * Since we now have an rtt measurement, cancel the
  1940.                  * timer backoff (cf., Phil Karn's retransmit alg.).
  1941.                  * Recompute the initial retransmit timer.
  1942.  *
  1943.                  * If all outstanding data is acked, stop retransmit
  1944.                  * If there is more data to be acked, restart retransmit
  1945.                  * timer, using current (possibly backed-off) value.
  1946.                  */
  1947. newack(pkt); // handle timers, update highest_ack_
  1948. /*
  1949.  * if this is a partial ACK, invoke whatever we should
  1950.  * note that newack() must be called before the action
  1951.  * functions, as some of them depend on side-effects
  1952.  * of newack()
  1953.  */
  1954. int partial = pack(pkt);
  1955. if (partial)
  1956. pack_action(pkt);
  1957. else
  1958. ack_action(pkt);
  1959. /*
  1960.  * if this is an ACK with an ECN indication, handle this
  1961.  * but not if it is a syn packet
  1962.  */
  1963. if (fh->ecnecho() && !(tiflags&TH_SYN) )
  1964. if (fh->ecnecho()) {
  1965. // Note from Sally: In one-way TCP,
  1966. // ecn() is called before newack()...
  1967. ecn(highest_ack_);  // updated by newack(), above
  1968. // "set_rtx_timer();" from T. Kelly.
  1969. if (cwnd_ < 1)
  1970.   set_rtx_timer();
  1971. }
  1972. // CHECKME: handling of rtx timer
  1973. if (ackno == maxseq_) {
  1974. needoutput = TRUE;
  1975. }
  1976. /*
  1977.  * If no data (only SYN) was ACK'd,
  1978.  *    skip rest of ACK processing.
  1979.  */
  1980. if (ackno == (highest_ack_ + 1))
  1981. goto step6;
  1982. // if we are delaying initial cwnd growth (probably due to
  1983. // large initial windows), then only open cwnd if data has
  1984. // been received
  1985. // Q: check when this happens
  1986.                 /*
  1987.                  * When new data is acked, open the congestion window.
  1988.                  * If the window gives us less than ssthresh packets
  1989.                  * in flight, open exponentially (maxseg per packet).
  1990.                  * Otherwise open about linearly: maxseg per window
  1991.                  * (maxseg^2 / cwnd per packet).
  1992.                  */
  1993. if ((!delay_growth_ || (rcv_nxt_ > 0)) &&
  1994.     last_state_ == TCPS_ESTABLISHED) {
  1995. if (!partial || open_cwnd_on_pack_)
  1996.   if (!ect_ || !hdr_flags::access(pkt)->ecnecho())
  1997. opencwnd();
  1998. }
  1999. if ((state_ >= TCPS_FIN_WAIT_1) && (ackno == maxseq_)) {
  2000. ourfinisacked = TRUE;
  2001. }
  2002. //
  2003. // special additional processing when our state
  2004. // is one of the closing states:
  2005. // FIN_WAIT_1, CLOSING, LAST_ACK
  2006. switch (state_) {
  2007.                 /*
  2008.                  * In FIN_WAIT_1 STATE in addition to the processing
  2009.                  * for the ESTABLISHED state if our FIN is now acknowledged
  2010.                  * then enter FIN_WAIT_2.
  2011.                  */
  2012. case TCPS_FIN_WAIT_1: /* doing active close */
  2013. if (ourfinisacked) {
  2014. // got the ACK, now await incoming FIN
  2015. newstate(TCPS_FIN_WAIT_2);
  2016. cancel_timers();
  2017. needoutput = FALSE;
  2018. }
  2019. break;
  2020.                 /*
  2021.                  * In CLOSING STATE in addition to the processing for
  2022.                  * the ESTABLISHED state if the ACK acknowledges our FIN
  2023.                  * then enter the TIME-WAIT state, otherwise ignore
  2024.                  * the segment.
  2025.                  */
  2026. case TCPS_CLOSING: /* simultaneous active close */;
  2027. if (ourfinisacked) {
  2028. newstate(TCPS_CLOSED);
  2029. cancel_timers();
  2030. }
  2031. break;
  2032.                 /*
  2033.                  * In LAST_ACK, we may still be waiting for data to drain
  2034.                  * and/or to be acked, as well as for the ack of our FIN.
  2035.                  * If our FIN is now acknowledged,
  2036.                  * enter the closed state and return.
  2037.                  */
  2038. case TCPS_LAST_ACK: /* passive close */
  2039. // K: added state change here
  2040. if (ourfinisacked) {
  2041. newstate(TCPS_CLOSED);
  2042. finish(); // cancels timers, erc
  2043. reset(); // for connection re-use (bug fix from ns-users list)
  2044. goto drop;
  2045. } else {
  2046. // should be a FIN we've seen
  2047.                                 if (debug_) {
  2048.                                         fprintf(stderr, "%f: FullTcpAgent(%s)::received non-ACK (state:%d): ",
  2049.                                         now(), name(), state_);
  2050.         prpkt(pkt);
  2051.                                 }
  2052.                         }
  2053. break;
  2054. /* no case for TIME_WAIT in simulator */
  2055. }  // inner state_ switch (closing states)
  2056. } // outer state_ switch (ack processing)
  2057. step6:
  2058. /*
  2059.  * Processing of incoming DATAful segments.
  2060.  *  Code above has already trimmed redundant data.
  2061.  *
  2062.  * real TCP handles window updates and URG data here also
  2063.  */
  2064. /* dodata: this label is in the "real" code.. here only for reference */
  2065. if ((datalen > 0 || (tiflags & TH_FIN)) &&
  2066.     TCPS_HAVERCVDFIN(state_) == 0) {
  2067. //
  2068. // the following 'if' implements the "real" TCP
  2069. // TCP_REASS macro
  2070. //
  2071. if (tcph->seqno() == rcv_nxt_ && rq_.empty()) {
  2072. // got the in-order packet we were looking
  2073. // for, nobody is in the reassembly queue,
  2074. // so this is the common case...
  2075. // note: in "real" TCP we must also be in
  2076. // ESTABLISHED state to come here, because
  2077. // data arriving before ESTABLISHED is
  2078. // queued in the reassembly queue.  Since we
  2079. // don't really have a process anyhow, just
  2080. // accept the data here as-is (i.e. don't
  2081. // require being in ESTABLISHED state)
  2082. flags_ |= TF_DELACK;
  2083. rcv_nxt_ += datalen;
  2084. tiflags = tcph->flags() & TH_FIN;
  2085. // give to "application" here
  2086. // in "real" TCP, this is sbappend() + sorwakeup()
  2087. if (datalen)
  2088. recvBytes(datalen); // notify app. of "delivery"
  2089. needoutput = need_send();
  2090. } else {
  2091. // see the "tcp_reass" function:
  2092. // not the one we want next (or it
  2093. // is but there's stuff on the reass queue);
  2094. // do whatever we need to do for out-of-order
  2095. // segments or hole-fills.  Also,
  2096. // send an ACK (or SACK) to the other side right now.
  2097. // Note that we may have just a FIN here (datalen = 0)
  2098. int rcv_nxt_old_ = rcv_nxt_; // notify app. if changes
  2099. tiflags = reass(pkt);
  2100. if (rcv_nxt_ > rcv_nxt_old_) {
  2101. // if rcv_nxt_ has advanced, must have
  2102. // been a hole fill.  In this case, there
  2103. // is something to give to application
  2104. recvBytes(rcv_nxt_ - rcv_nxt_old_);
  2105. }
  2106. flags_ |= TF_ACKNOW;
  2107. if (tiflags & TH_PUSH) {
  2108. //
  2109. // ???: does this belong here
  2110. // K: APPLICATION recv
  2111. needoutput = need_send();
  2112. }
  2113. }
  2114. } else {
  2115. /*
  2116.  * we're closing down or this is a pure ACK that
  2117.  * wasn't handled by the header prediction part above
  2118.  * (e.g. because cwnd < wnd)
  2119.  */
  2120. // K: this is deleted
  2121. tiflags &= ~TH_FIN;
  2122. }
  2123. /*
  2124.  * if FIN is received, ACK the FIN
  2125.  * (let user know if we could do so)
  2126.  */
  2127. if (tiflags & TH_FIN) {
  2128. if (TCPS_HAVERCVDFIN(state_) == 0) {
  2129. flags_ |= TF_ACKNOW;
  2130.   rcv_nxt_++;
  2131. }
  2132. switch (state_) {
  2133.                 /*
  2134.                  * In SYN_RECEIVED and ESTABLISHED STATES
  2135.                  * enter the CLOSE_WAIT state.
  2136.  * (passive close)
  2137.                  */
  2138.                 case TCPS_SYN_RECEIVED:
  2139.                 case TCPS_ESTABLISHED:
  2140. newstate(TCPS_CLOSE_WAIT);
  2141.                         break;
  2142.                 /*
  2143.                  * If still in FIN_WAIT_1 STATE FIN has not been acked so
  2144.                  * enter the CLOSING state.
  2145.  * (simultaneous close)
  2146.                  */
  2147.                 case TCPS_FIN_WAIT_1:
  2148. newstate(TCPS_CLOSING);
  2149.                         break;
  2150.                 /*
  2151.                  * In FIN_WAIT_2 state enter the TIME_WAIT state,
  2152.                  * starting the time-wait timer, turning off the other
  2153.                  * standard timers.
  2154.  * (in the simulator, just go to CLOSED)
  2155.  * (completion of active close)
  2156.                  */
  2157.                 case TCPS_FIN_WAIT_2:
  2158.                         newstate(TCPS_CLOSED);
  2159. cancel_timers();
  2160.                         break;
  2161. }
  2162. } /* end of if FIN bit on */
  2163. if (needoutput || (flags_ & TF_ACKNOW))
  2164. send_much(1, REASON_NORMAL, maxburst_);
  2165. else if (curseq_ >= highest_ack_ || infinite_send_)
  2166. send_much(0, REASON_NORMAL, maxburst_);
  2167. // K: which state to return to when nothing left?
  2168. if (!halfclose_ && state_ == TCPS_CLOSE_WAIT && highest_ack_ == maxseq_)
  2169. usrclosed();
  2170. Packet::free(pkt);
  2171. // haoboy: Is here the place for done{} of active close? 
  2172. // It cannot be put in the switch above because we might need to do
  2173. // send_much() (an ACK)
  2174. if (state_ == TCPS_CLOSED) 
  2175. Tcl::instance().evalf("%s done", this->name());
  2176. return;
  2177. //
  2178. // various ways of dropping (some also ACK, some also RST)
  2179. //
  2180. dropafterack:
  2181. flags_ |= TF_ACKNOW;
  2182. send_much(1, REASON_NORMAL, maxburst_);
  2183. goto drop;
  2184. dropwithreset:
  2185. /* we should be sending an RST here, but can't in simulator */
  2186. if (tiflags & TH_ACK) {
  2187. sendpacket(ackno, 0, 0x0, 0, REASON_NORMAL);
  2188. } else {
  2189. int ack = tcph->seqno() + datalen;
  2190. if (tiflags & TH_SYN)
  2191. ack--;
  2192. sendpacket(0, ack, TH_ACK, 0, REASON_NORMAL);
  2193. }
  2194. drop:
  2195.     Packet::free(pkt);
  2196. return;
  2197. }
  2198. /*  
  2199.  * Dupack-action: what to do on a DUP ACK.  After the initial check
  2200.  * of 'recover' below, this function implements the following truth
  2201.  * table:
  2202.  *  
  2203.  *      bugfix  ecn     last-cwnd == ecn        action  
  2204.  *  
  2205.  *      0       0       0                       full_reno_action
  2206.  *      0       0       1                       full_reno_action [impossible]
  2207.  *      0       1       0                       full_reno_action
  2208.  *      0       1       1                       1/2 window, return 
  2209.  *      1       0       0                       nothing 
  2210.  *      1       0       1                       nothing         [impossible]
  2211.  *      1       1       0                       nothing 
  2212.  *      1       1       1                       1/2 window, return
  2213.  */ 
  2214.     
  2215. void
  2216. FullTcpAgent::dupack_action()
  2217. {   
  2218.         int recovered = (highest_ack_ > recover_);
  2219. fastrecov_ = TRUE;
  2220. rtxbytes_ = 0;
  2221.         if (recovered || (!bug_fix_ && !ecn_) 
  2222.             || (last_cwnd_action_ == CWND_ACTION_DUPACK)
  2223.             || ( highest_ack_ == 0)) {
  2224.                 goto full_reno_action;
  2225.         }       
  2226.     
  2227.         if (ecn_ && last_cwnd_action_ == CWND_ACTION_ECN) {
  2228.                 slowdown(CLOSE_CWND_HALF);
  2229. cancel_rtx_timer();
  2230. rtt_active_ = FALSE;
  2231. (void)fast_retransmit(highest_ack_);
  2232.                 return; 
  2233.         }      
  2234.     
  2235.         if (bug_fix_) {
  2236.                 /*
  2237.                  * The line below, for "bug_fix_" true, avoids
  2238.                  * problems with multiple fast retransmits in one
  2239.                  * window of data.
  2240.                  */      
  2241.                 return;  
  2242.         }
  2243.     
  2244. full_reno_action:    
  2245.         slowdown(CLOSE_SSTHRESH_HALF|CLOSE_CWND_HALF);
  2246. cancel_rtx_timer();
  2247. rtt_active_ = FALSE;
  2248. recover_ = maxseq_;
  2249. (void)fast_retransmit(highest_ack_);
  2250. // we measure cwnd in packets,
  2251. // so don't scale by maxseg_
  2252. // as real TCP does
  2253. cwnd_ = double(ssthresh_) + double(dupacks_);
  2254.         return;
  2255. }
  2256. void
  2257. FullTcpAgent::timeout_action()
  2258. {
  2259. recover_ = maxseq_;
  2260. if (cwnd_ < 1.0) {
  2261.                 if (debug_) {
  2262.             fprintf(stderr, "%f: FullTcpAgent(%s):: resetting cwnd from %f to 1n",
  2263.     now(), name(), double(cwnd_));
  2264.                 }
  2265. cwnd_ = 1.0;
  2266. }
  2267. if (last_cwnd_action_ == CWND_ACTION_ECN) {
  2268. slowdown(CLOSE_CWND_ONE);
  2269. } else {
  2270. slowdown(CLOSE_SSTHRESH_HALF|CLOSE_CWND_RESTART);
  2271. last_cwnd_action_ = CWND_ACTION_TIMEOUT;
  2272. }
  2273. reset_rtx_timer(1);
  2274. t_seqno_ = (highest_ack_ < 0) ? iss_ : int(highest_ack_);
  2275. fastrecov_ = FALSE;
  2276. dupacks_ = 0;
  2277. }
  2278. /*
  2279.  * deal with timers going off.
  2280.  * 2 types for now:
  2281.  * retransmission timer (rtx_timer_)
  2282.  *  delayed ack timer (delack_timer_)
  2283.  * delayed send (randomization) timer (delsnd_timer_)
  2284.  *
  2285.  * real TCP initializes the RTO as 6 sec
  2286.  * (A + 2D, where A=0, D=3), [Stevens p. 305]
  2287.  * and thereafter uses
  2288.  * (A + 4D, where A and D are dynamic estimates)
  2289.  *
  2290.  * note that in the simulator t_srtt_, t_rttvar_ and t_rtt_
  2291.  * are all measured in 'tcp_tick_'-second units
  2292.  */
  2293. void
  2294. FullTcpAgent::timeout(int tno)
  2295. {
  2296. /*
  2297.  * Due to F. Hernandez-Campos' fix in recv(), we may send an ACK
  2298.  * while in the CLOSED state.  -M. Weigle 7/24/01
  2299.  */
  2300. if (state_ == TCPS_LISTEN) {
  2301.   // shouldn't be getting timeouts here
  2302.                 if (debug_) {
  2303.         fprintf(stderr, "%f: FullTcpAgent(%s): unexpected timeout %d in state %sn",
  2304. now(), name(), tno, statestr(state_));
  2305.                 }
  2306. return;
  2307. }
  2308. switch (tno) {
  2309. case TCP_TIMER_RTX:
  2310.                 /* retransmit timer */
  2311.                 ++nrexmit_;
  2312.                 timeout_action();
  2313. /* fall thru */
  2314. case TCP_TIMER_DELSND:
  2315. /* for phase effects */
  2316.                 send_much(1, PF_TIMEOUT, maxburst_);
  2317. break;
  2318. case TCP_TIMER_DELACK:
  2319.                 if (flags_ & TF_DELACK) {
  2320.                         flags_ &= ~TF_DELACK;
  2321.                         flags_ |= TF_ACKNOW;
  2322.                         send_much(1, REASON_NORMAL, 0);
  2323.                 }
  2324.                 delack_timer_.resched(delack_interval_);
  2325. break;
  2326. default:
  2327. fprintf(stderr, "%f: FullTcpAgent(%s) Unknown Timeout type %dn",
  2328. now(), name(), tno);
  2329. }
  2330. return;
  2331. }
  2332. void
  2333. FullTcpAgent::dooptions(Packet* pkt)
  2334. {
  2335. // interesting options: timestamps (here),
  2336. // CC, CCNEW, CCECHO (future work perhaps?)
  2337.         hdr_flags *fh = hdr_flags::access(pkt);
  2338. hdr_tcp *tcph = hdr_tcp::access(pkt);
  2339. if (ts_option_ && !fh->no_ts_) {
  2340. if (tcph->ts() < 0.0) {
  2341. fprintf(stderr,
  2342.     "%f: FullTcpAgent(%s) warning: ts_option enabled in this TCP, but appears to be disabled in peern",
  2343. now(), name());
  2344. } else if (tcph->flags() & TH_SYN) {
  2345. flags_ |= TF_RCVD_TSTMP;
  2346. recent_ = tcph->ts();
  2347. recent_age_ = now();
  2348. }
  2349. }
  2350. return;
  2351. }
  2352. //
  2353. // this shouldn't ever happen
  2354. //
  2355. void
  2356. FullTcpAgent::process_sack(hdr_tcp*)
  2357. {
  2358. fprintf(stderr, "%f: FullTcpAgent(%s) Non-SACK capable FullTcpAgent received a SACKn",
  2359. now(), name());
  2360. return;
  2361. }
  2362. /*
  2363.  * ****** Tahoe ******
  2364.  *
  2365.  * for TCP Tahoe, we force a slow-start as the dup ack
  2366.  * action.  Also, no window inflation due to multiple dup
  2367.  * acks.  The latter is arranged by setting reno_fastrecov_
  2368.  * false [which is performed by the Tcl init function for Tahoe in
  2369.  * ns-default.tcl].
  2370.  */
  2371. /* 
  2372.  * Tahoe
  2373.  * Dupack-action: what to do on a DUP ACK.  After the initial check
  2374.  * of 'recover' below, this function implements the following truth
  2375.  * table:
  2376.  * 
  2377.  *      bugfix  ecn     last-cwnd == ecn        action  
  2378.  * 
  2379.  *      0       0       0                       full_tahoe_action
  2380.  *      0       0       1                       full_tahoe_action [impossible]
  2381.  *      0       1       0                       full_tahoe_action
  2382.  *      0       1       1                       1/2 window, return
  2383.  *      1       0       0                       nothing 
  2384.  *      1       0       1                       nothing         [impossible]
  2385.  *      1       1       0                       nothing 
  2386.  *      1       1       1                       1/2 window, return
  2387.  */
  2388. void
  2389. TahoeFullTcpAgent::dupack_action()
  2390. {  
  2391.         int recovered = (highest_ack_ > recover_);
  2392. fastrecov_ = TRUE;
  2393. rtxbytes_ = 0;
  2394.         if (recovered || (!bug_fix_ && !ecn_) || highest_ack_ == 0) {
  2395.                 goto full_tahoe_action;
  2396.         }
  2397.    
  2398.         if (ecn_ && last_cwnd_action_ == CWND_ACTION_ECN) {
  2399. // slow start on ECN
  2400. last_cwnd_action_ = CWND_ACTION_DUPACK;
  2401.                 slowdown(CLOSE_CWND_ONE);
  2402. set_rtx_timer();
  2403.                 rtt_active_ = FALSE;
  2404. t_seqno_ = highest_ack_;
  2405.                 return; 
  2406.         }
  2407.    
  2408.         if (bug_fix_) {
  2409.                 /*
  2410.                  * The line below, for "bug_fix_" true, avoids
  2411.                  * problems with multiple fast retransmits in one
  2412.                  * window of data.
  2413.                  */      
  2414.                 return;  
  2415.         }
  2416.    
  2417. full_tahoe_action:
  2418. // slow-start and reset ssthresh
  2419. trace_event("FAST_RETX");
  2420. recover_ = maxseq_;
  2421. last_cwnd_action_ = CWND_ACTION_DUPACK;
  2422.         slowdown(CLOSE_SSTHRESH_HALF|CLOSE_CWND_ONE); // cwnd->1
  2423. set_rtx_timer();
  2424.         rtt_active_ = FALSE;
  2425. t_seqno_ = highest_ack_;
  2426. send_much(0, REASON_NORMAL, 0);
  2427.         return; 
  2428. }  
  2429. /*
  2430.  * ****** Newreno ******
  2431.  *
  2432.  * for NewReno, a partial ACK does not exit fast recovery,
  2433.  * and does not reset the dup ACK counter (which might trigger fast
  2434.  * retransmits we don't want).  In addition, the number of packets
  2435.  * sent in response to an ACK is limited to recov_maxburst_ during
  2436.  * recovery periods.
  2437.  */
  2438. NewRenoFullTcpAgent::NewRenoFullTcpAgent() : save_maxburst_(-1)
  2439. {
  2440. bind("recov_maxburst_", &recov_maxburst_);
  2441. }
  2442. void
  2443. NewRenoFullTcpAgent::pack_action(Packet*)
  2444. {
  2445. (void)fast_retransmit(highest_ack_);
  2446. cwnd_ = double(ssthresh_);
  2447. if (save_maxburst_ < 0) {
  2448. save_maxburst_ = maxburst_;
  2449. maxburst_ = recov_maxburst_;
  2450. }
  2451. return;
  2452. }
  2453. void
  2454. NewRenoFullTcpAgent::ack_action(Packet* p)
  2455. {
  2456. if (save_maxburst_ >= 0) {
  2457. maxburst_ = save_maxburst_;
  2458. save_maxburst_ = -1;
  2459. }
  2460. FullTcpAgent::ack_action(p);
  2461. return;
  2462. }
  2463. /*
  2464.  *
  2465.  * ****** SACK ******
  2466.  *
  2467.  * for Sack, receiver part must report SACK data
  2468.  * sender part maintains a 'scoreboard' (sq_) that
  2469.  * records what it hears from receiver
  2470.  * sender fills holes during recovery and obeys
  2471.  * "pipe" style control until recovery is complete
  2472.  */
  2473. void
  2474. SackFullTcpAgent::reset()
  2475. {
  2476. sq_.clear(); // no SACK blocks
  2477. /* Fixed typo.  -M. Weigle 6/17/02 */
  2478. sack_min_ = h_seqno_ = -1; // no left edge of SACK blocks
  2479. FullTcpAgent::reset();
  2480. }
  2481. int
  2482. SackFullTcpAgent::hdrsize(int nsackblocks)
  2483. {
  2484. int total = FullTcpAgent::headersize();
  2485. // use base header size plus SACK option size
  2486.         if (nsackblocks > 0) {
  2487.                 total += ((nsackblocks * sack_block_size_)
  2488.                         + sack_option_size_);
  2489. }
  2490. return (total);
  2491. }
  2492. void
  2493. SackFullTcpAgent::dupack_action()
  2494. {
  2495.         int recovered = (highest_ack_ > recover_);
  2496. fastrecov_ = TRUE;
  2497. rtxbytes_ = 0;
  2498. pipe_ = maxseq_ - highest_ack_ - sq_.total();
  2499. //printf("%f: SACK DUPACK-ACTION:pipe_:%d, sq-total:%d, bugfix:%d, cwnd:%d, highest_ack:%d, recover_:%dn",
  2500. //now(), pipe_, sq_.total(), bug_fix_, int(cwnd_), int(highest_ack_), recover_);
  2501.         if (recovered || (!bug_fix_ && !ecn_)) {
  2502.                 goto full_sack_action;
  2503.         }           
  2504.         if (ecn_ && last_cwnd_action_ == CWND_ACTION_ECN) {
  2505. /* 
  2506.  * Received ECN notification and 3 DUPACKs in same 
  2507.  * window. Don't cut cwnd again, but retransmit lost
  2508.  * packet.   -M. Weigle  6/19/02
  2509.  */
  2510. last_cwnd_action_ = CWND_ACTION_DUPACK;
  2511. cancel_rtx_timer();
  2512. rtt_active_ = FALSE;
  2513. int amt = fast_retransmit(highest_ack_);
  2514. pipectrl_ = TRUE;
  2515. h_seqno_ = highest_ack_ + amt;
  2516. send_much(0, REASON_DUPACK, maxburst_);
  2517. return; 
  2518. }
  2519.    
  2520.         if (bug_fix_) {
  2521.                 /*                              
  2522.                  * The line below, for "bug_fix_" true, avoids
  2523.                  * problems with multiple fast retransmits in one
  2524.                  * window of data.
  2525.                  */      
  2526. //printf("%f: SACK DUPACK-ACTION BUGFIX RETURN:pipe_:%d, sq-total:%d, bugfix:%d, cwnd:%dn",
  2527. //now(), pipe_, sq_.total(), bug_fix_, int(cwnd_));
  2528.                 return;  
  2529.         }
  2530.    
  2531. full_sack_action:                               
  2532. trace_event("FAST_RECOVERY");
  2533.         slowdown(CLOSE_SSTHRESH_HALF|CLOSE_CWND_HALF);
  2534.         cancel_rtx_timer();
  2535.         rtt_active_ = FALSE;
  2536. // these initiate SACK-style "pipe" recovery
  2537. pipectrl_ = TRUE;
  2538. recover_ = maxseq_; // where I am when recovery starts
  2539. int amt = fast_retransmit(highest_ack_);
  2540. h_seqno_ = highest_ack_ + amt;
  2541. //printf("%f: FAST-RTX seq:%d, h_seqno_ is now:%d, pipe:%d, cwnd:%d, recover:%dn",
  2542. //now(), int(highest_ack_), h_seqno_, pipe_, int(cwnd_), recover_);
  2543. send_much(0, REASON_DUPACK, maxburst_);
  2544.         return;
  2545. }
  2546. void
  2547. SackFullTcpAgent::pack_action(Packet* p)
  2548. {
  2549. if (!sq_.empty() && sack_min_ < highest_ack_) {
  2550. sack_min_ = highest_ack_;
  2551. sq_.cleartonxt();
  2552. }
  2553. pipe_ -= maxseg_; // see comment in tcp-sack1.cc
  2554. if (h_seqno_ < highest_ack_)
  2555. h_seqno_ = highest_ack_;
  2556. }
  2557. void
  2558. SackFullTcpAgent::ack_action(Packet* p)
  2559. {
  2560. //printf("%f: EXITING fast recovery, recover:%dn",
  2561. //now(), recover_);
  2562. fastrecov_ = pipectrl_ = FALSE;
  2563.         if (!sq_.empty() && sack_min_ < highest_ack_) {
  2564.                 sack_min_ = highest_ack_;
  2565.                 sq_.cleartonxt();
  2566.         }
  2567. dupacks_ = 0;
  2568. /* 
  2569.  * Update h_seqno_ on new ACK (same as for partial ACKS)
  2570.  * -M. Weigle 6/3/05
  2571.  */
  2572. if (h_seqno_ < highest_ack_)
  2573. h_seqno_ = highest_ack_;
  2574. }
  2575. //
  2576. // receiver side: if there are things in the reassembly queue,
  2577. // build the appropriate SACK blocks to carry in the SACK
  2578. //
  2579. int
  2580. SackFullTcpAgent::build_options(hdr_tcp* tcph)
  2581. {
  2582. int total = FullTcpAgent::build_options(tcph);
  2583.         if (!rq_.empty()) {
  2584.                 int nblk = rq_.gensack(&tcph->sa_left(0), max_sack_blocks_);
  2585.                 tcph->sa_length() = nblk;
  2586. total += (nblk * sack_block_size_) + sack_option_size_;
  2587.         } else {
  2588.                 tcph->sa_length() = 0;
  2589.         }
  2590. return (total);
  2591. }
  2592. void
  2593. SackFullTcpAgent::timeout_action()
  2594. {
  2595. FullTcpAgent::timeout_action();
  2596. //
  2597. // original SACK spec says the sender is
  2598. // supposed to clear out its knowledge of what
  2599. // the receiver has in the case of a timeout
  2600. // (on the chance the receiver has renig'd).
  2601. // Here, this happens when clear_on_timeout_ is
  2602. // enabled.
  2603. //
  2604. if (clear_on_timeout_) {
  2605. sq_.clear();
  2606. sack_min_ = highest_ack_;
  2607. }
  2608. return;
  2609. }
  2610. void
  2611. SackFullTcpAgent::process_sack(hdr_tcp* tcph)
  2612. {
  2613. //
  2614. // Figure out how many sack blocks are
  2615. // in the pkt.  Insert each block range
  2616. // into the scoreboard
  2617. //
  2618. if (max_sack_blocks_ <= 0) {
  2619. fprintf(stderr,
  2620.     "%f: FullTcpAgent(%s) warning: received SACK block but I am not SACK enabledn",
  2621. now(), name());
  2622. return;
  2623. }
  2624. int slen = tcph->sa_length(), i;
  2625. for (i = 0; i < slen; ++i) {
  2626. /* Added check for FIN   -M. Weigle 5/21/02 */
  2627. if ((tcph->flags() & TH_FIN == 0) && 
  2628.     tcph->sa_left(i) >= tcph->sa_right(i)) {
  2629. fprintf(stderr,
  2630.     "%f: FullTcpAgent(%s) warning: received illegal SACK block [%d,%d]n",
  2631. now(), name(), tcph->sa_left(i), tcph->sa_right(i));
  2632. continue;
  2633. }
  2634. sq_.add(tcph->sa_left(i), tcph->sa_right(i), 0);  
  2635. }
  2636. return;
  2637. }
  2638. int
  2639. SackFullTcpAgent::send_allowed(int seq)
  2640. {
  2641. // not in pipe control, so use regular control
  2642. if (!pipectrl_)
  2643. return (FullTcpAgent::send_allowed(seq));
  2644. // don't overshoot receiver's advertised window
  2645. int topawin = highest_ack_ + int(wnd_) * maxseg_;
  2646. if (seq >= topawin) {
  2647. //printf("%f: SEND(%d) NOT ALLOWED DUE TO AWIN:%d, pipe:%d, cwnd:%dn",
  2648. //now(), seq, topawin, pipe_, int(cwnd_));
  2649. return FALSE;
  2650. }
  2651. /*
  2652.  * If not in ESTABLISHED, don't send anything we don't have
  2653.  *   -M. Weigle 7/18/02
  2654.  */
  2655. if (state_ != TCPS_ESTABLISHED && seq > curseq_)
  2656. return FALSE;
  2657. // don't overshoot cwnd_
  2658. int cwin = int(cwnd_) * maxseg_;
  2659. return (pipe_ < cwin);
  2660. }
  2661. //
  2662. // Calculate the next seq# to send by send_much.  If we are recovering and
  2663. // we have learned about data cached at the receiver via a SACK,
  2664. // we may want something other than new data (t_seqno)
  2665. //
  2666. int
  2667. SackFullTcpAgent::nxt_tseq()
  2668. {
  2669. int in_recovery = (highest_ack_ < recover_);
  2670. int seq = h_seqno_;
  2671. if (!in_recovery) {
  2672. //if (int(t_seqno_) > 1)
  2673. //printf("%f: non-recovery nxt_tseq called w/t_seqno:%dn",
  2674. //now(), int(t_seqno_));
  2675. //sq_.dumplist();
  2676. return (t_seqno_);
  2677. }
  2678. int fcnt; // following count-- the
  2679. // count field in the block
  2680. // after the seq# we are about
  2681. // to send
  2682. int fbytes; // fcnt in bytes
  2683. //if (int(t_seqno_) > 1)
  2684. //printf("%f: recovery nxt_tseq called w/t_seqno:%d, seq:%d, mode:%dn",
  2685. //now(), int(t_seqno_), seq, sack_rtx_threshmode_);
  2686. //sq_.dumplist();
  2687. while ((seq = sq_.nexthole(seq, fcnt, fbytes)) > 0) {
  2688. // if we have a following block
  2689. // with a large enough count
  2690. // we should use the seq# we get
  2691. // from nexthole()
  2692. if (sack_rtx_threshmode_ == 0 ||
  2693.     (sack_rtx_threshmode_ == 1 && fcnt >= sack_rtx_cthresh_) ||
  2694.     (sack_rtx_threshmode_ == 2 && fbytes >= sack_rtx_bthresh_) ||
  2695.     (sack_rtx_threshmode_ == 3 && (fcnt >= sack_rtx_cthresh_ || fbytes >= sack_rtx_bthresh_)) ||
  2696.     (sack_rtx_threshmode_ == 4 && (fcnt >= sack_rtx_cthresh_ && fbytes >= sack_rtx_bthresh_))) {
  2697. //if (int(t_seqno_) > 1)
  2698. //printf("%f: nxt_tseq<hole> returning %dn",
  2699. //now(), int(seq));
  2700. // adjust h_seqno, as we may have
  2701. // been "jumped ahead" by learning
  2702. // about a filled hole
  2703. if (seq > h_seqno_)
  2704. h_seqno_ = seq;
  2705. return (seq);
  2706. } else if (fcnt <= 0)
  2707. break;
  2708. else {
  2709. seq += maxseg_;
  2710. }
  2711. }
  2712. //if (int(t_seqno_) > 1)
  2713. //printf("%f: nxt_tseq<top> returning %dn",
  2714. //now(), int(t_seqno_));
  2715. return (t_seqno_);
  2716. }