dctcp-ns2-patch
1 diff -crbB ns-allinone-2.35/ns-2.35/queue/red.cc ns-2.35/queue/red.cc 2 *** ns-allinone-2.35/ns-2.35/queue/red.cc 2011-10-02 15:32:34.000000000 -0700 3 --- ns-2.35/queue/red.cc 2012-03-19 02:40:10.827778003 -0700 4 *************** 5 *** 559,565 **** 6 edv_.count_bytes = 0; 7 hdr_flags* hf = hdr_flags::access(pickPacketForECN(pkt)); 8 if (edp_.setbit && hf->ect() && 9 ! (!edp_.use_mark_p || edv_.v_prob1 < edp_.mark_p)) { 10 hf->ce() = 1; // mark Congestion Experienced bit 11 // Tell the queue monitor here - call emark(pkt) 12 return (0); // no drop 13 --- 559,565 ---- 14 edv_.count_bytes = 0; 15 hdr_flags* hf = hdr_flags::access(pickPacketForECN(pkt)); 16 if (edp_.setbit && hf->ect() && 17 ! (!edp_.use_mark_p || edv_.v_prob1 <= edp_.mark_p)) { // For DCTCP: '<' is changed to '<=' here 18 hf->ce() = 1; // mark Congestion Experienced bit 19 // Tell the queue monitor here - call emark(pkt) 20 return (0); // no drop 21 Only in ns-2.35/queue: red.cc~ 22 diff -crbB ns-allinone-2.35/ns-2.35/tcl/lib/ns-default.tcl ns-2.35/tcl/lib/ns-default.tcl 23 *** ns-allinone-2.35/ns-2.35/tcl/lib/ns-default.tcl 2010-07-03 15:45:45.000000000 -0700 24 --- ns-2.35/tcl/lib/ns-default.tcl 2012-03-19 02:40:08.415778003 -0700 25 *************** 26 *** 1026,1031 **** 27 --- 1026,1035 ---- 28 29 Agent/TCP set SetCWRonRetransmit_ true ; # added on 2005/06/19. 30 # default changed on 2008/06/05. 31 + # DCTCP 32 + Agent/TCP set dctcp_ false; 33 + Agent/TCP set dctcp_alpha_ 0.0; 34 + Agent/TCP set dctcp_g_ 0.0625; 35 36 # XXX Generate nam trace or plain old text trace for variables. 37 # When it's true, generate nam trace. 38 Only in ns-2.35/tcl/lib: ns-default.tcl~ 39 Only in ns-2.35/tcp: .swp 40 diff -crbB ns-allinone-2.35/ns-2.35/tcp/tcp.cc ns-2.35/tcp/tcp.cc 41 *** ns-allinone-2.35/ns-2.35/tcp/tcp.cc 2011-06-19 21:51:46.000000000 -0700 42 --- ns-2.35/tcp/tcp.cc 2012-03-19 02:40:09.966778001 -0700 43 *************** 44 *** 101,106 **** 45 --- 101,109 ---- 46 bind("necnresponses_", &necnresponses_); 47 bind("ncwndcuts_", &ncwndcuts_); 48 bind("ncwndcuts1_", &ncwndcuts1_); 49 + bind("dctcp_", &dctcp_); 50 + bind("dctcp_alpha_", &dctcp_alpha_); 51 + bind("dctcp_g_", &dctcp_g_); 52 #endif /* TCP_DELAY_BIND_ALL */ 53 54 } 55 *************** 56 *** 123,128 **** 57 --- 126,136 ---- 58 delay_bind_init_one("overhead_"); 59 delay_bind_init_one("tcpTick_"); 60 delay_bind_init_one("ecn_"); 61 + // DCTCP 62 + delay_bind_init_one("dctcp_"); 63 + delay_bind_init_one("dctcp_alpha_"); 64 + delay_bind_init_one("dctcp_g_"); 65 + 66 delay_bind_init_one("SetCWRonRetransmit_"); 67 delay_bind_init_one("old_ecn_"); 68 delay_bind_init_one("bugfix_ss_"); 69 *************** 70 *** 234,239 **** 71 --- 242,251 ---- 72 if (delay_bind(varName, localName, "overhead_", &overhead_, tracer)) return TCL_OK; 73 if (delay_bind(varName, localName, "tcpTick_", &tcp_tick_, tracer)) return TCL_OK; 74 if (delay_bind_bool(varName, localName, "ecn_", &ecn_, tracer)) return TCL_OK; 75 + // Mohammad 76 + if (delay_bind_bool(varName, localName, "dctcp_", &dctcp_, tracer)) return TCL_OK; 77 + if (delay_bind(varName, localName, "dctcp_alpha_", &dctcp_alpha_ , tracer)) return TCL_OK; 78 + if (delay_bind(varName, localName, "dctcp_g_", &dctcp_g_ , tracer)) return TCL_OK; 79 if (delay_bind_bool(varName, localName, "SetCWRonRetransmit_", &SetCWRonRetransmit_, tracer)) return TCL_OK; 80 if (delay_bind_bool(varName, localName, "old_ecn_", &old_ecn_ , tracer)) return TCL_OK; 81 if (delay_bind_bool(varName, localName, "bugfix_ss_", &bugfix_ss_ , tracer)) return TCL_OK; 82 *************** 83 *** 1297,1302 **** 84 --- 1309,1316 ---- 85 } else { 86 ssthresh_ = (int) decreasewin; 87 } 88 + else if (how & CLOSE_SSTHRESH_DCTCP) 89 + ssthresh_ = (int) ((1 - dctcp_alpha_/2.0) * windowd()); 90 else if (how & THREE_QUARTER_SSTHRESH) 91 if (ssthresh_ < 3*cwnd_/4) 92 ssthresh_ = (int)(3*cwnd_/4); 93 *************** 94 *** 1306,1311 **** 95 --- 1321,1328 ---- 96 if (first_decrease_ == 1 || slowstart || decrease_num_ == 0.5) { 97 cwnd_ = halfwin; 98 } else cwnd_ = decreasewin; 99 + else if (how & CLOSE_CWND_DCTCP) 100 + cwnd_ = (1 - dctcp_alpha_/2.0) * windowd(); 101 else if (how & CWND_HALF_WITH_MIN) { 102 // We have not thought about how non-standard TCPs, with 103 // non-standard values of decrease_num_, should respond 104 *************** 105 *** 1328,1334 **** 106 } 107 if (ssthresh_ < 2) 108 ssthresh_ = 2; 109 ! if (how & (CLOSE_CWND_HALF|CLOSE_CWND_RESTART|CLOSE_CWND_INIT|CLOSE_CWND_ONE)) 110 cong_action_ = TRUE; 111 112 fcnt_ = count_ = 0; 113 --- 1345,1353 ---- 114 } 115 if (ssthresh_ < 2) 116 ssthresh_ = 2; 117 ! if (cwnd_ < 1) 118 ! cwnd_ = 1; 119 ! if (how & (CLOSE_CWND_HALF|CLOSE_CWND_RESTART|CLOSE_CWND_INIT|CLOSE_CWND_ONE|CLOSE_CWND_DCTCP)) 120 cong_action_ = TRUE; 121 122 fcnt_ = count_ = 0; 123 *************** 124 *** 1429,1434 **** 125 --- 1448,1456 ---- 126 rtt_backoff(); 127 else ecn_backoff_ = 1; 128 } else ecn_backoff_ = 0; 129 + if (dctcp_) 130 + slowdown(CLOSE_CWND_DCTCP|CLOSE_SSTHRESH_DCTCP); 131 + else 132 slowdown(CLOSE_CWND_HALF|CLOSE_SSTHRESH_HALF); 133 ++necnresponses_ ; 134 // added by sylvia to count number of ecn responses 135 Only in ns-2.35/tcp: tcp.cc~ 136 diff -crbB ns-allinone-2.35/ns-2.35/tcp/tcp-full.cc ns-2.35/tcp/tcp-full.cc 137 *** ns-allinone-2.35/ns-2.35/tcp/tcp-full.cc 2010-03-07 21:54:54.000000000 -0800 138 --- ns-2.35/tcp/tcp-full.cc 2012-03-19 02:40:10.049778005 -0700 139 *************** 140 *** 871,876 **** 141 --- 871,881 ---- 142 /* Set ect() to 0. -M. Weigle 1/19/05 */ 143 fh->ect() = 0; 144 } 145 + 146 + // For DCTCP, ect should be set on all packets 147 + if (dctcp_) 148 + fh->ect() = ect_; 149 + 150 if (ecn_ && ect_ && recent_ce_ ) { 151 // This is needed here for the ACK in a SYN, SYN/ACK, ACK 152 // sequence. 153 *************** 154 *** 960,968 **** 155 // Q: how can this happen? 156 157 if (maxseg_ == 0) 158 ! maxseg_ = size_ - headersize(); 159 else 160 size_ = maxseg_ + headersize(); 161 162 int is_retransmit = (seqno < maxseq_); 163 int quiet = (highest_ack_ == maxseq_); 164 --- 965,976 ---- 165 // Q: how can this happen? 166 167 if (maxseg_ == 0) 168 ! maxseg_ = size_; // Mohammad: changed from size_ - headersize(); 169 ! /* Mohammad: This else condition is unnecessary and conflates 170 ! * with tcp.cc 171 else 172 size_ = maxseg_ + headersize(); 173 + */ 174 175 int is_retransmit = (seqno < maxseq_); 176 int quiet = (highest_ack_ == maxseq_); 177 *************** 178 *** 1156,1161 **** 179 --- 1164,1171 ---- 180 */ 181 flags_ &= ~(TF_ACKNOW|TF_DELACK); 182 183 + delack_timer_.force_cancel(); 184 + 185 /* 186 * if we have reacted to congestion recently, the 187 * slowdown() procedure will have set cong_action_ and 188 *************** 189 *** 1178,1183 **** 190 --- 1188,1195 ---- 191 // and adjusted for SYNs and FINs which use up one number 192 193 int highest = seqno + reliable; 194 + if (highest > dctcp_maxseq) 195 + dctcp_maxseq = highest; 196 if (highest > maxseq_) { 197 maxseq_ = highest; 198 // 199 *************** 200 *** 1415,1421 **** 201 { 202 // we are now going to fast-retransmit and willtrace that event 203 trace_event("FAST_RETX"); 204 - 205 recover_ = maxseq_; // recovery target 206 last_cwnd_action_ = CWND_ACTION_DUPACK; 207 return(foutput(seq, REASON_DUPACK)); // send one pkt 208 --- 1427,1432 ---- 209 *************** 210 *** 1564,1574 **** 211 --- 1576,1594 ---- 212 * at time t0 = (0.0 + k * interval_) for some k such 213 * that t0 > now 214 */ 215 + /* 216 + * Mohammad: commented this out for more efficient 217 + * delayed ack generation. 218 + * 219 if (delack_interval_ > 0.0 && 220 (delack_timer_.status() != TIMER_PENDING)) { 221 int last = int(now() / delack_interval_); 222 delack_timer_.resched(delack_interval_ * (last + 1.0) - now()); 223 } 224 + */ 225 + 226 + if (dctcp_) 227 + update_dctcp_alpha(pkt); 228 229 /* 230 * Try header prediction: in seq data or in seq pure ACK 231 *************** 232 *** 1597,1602 **** 233 --- 1617,1641 ---- 234 // 235 236 if (ecn_) { 237 + if (dctcp_) { // DCTCP 238 + if (fh->ce() && fh->ect()) { 239 + // no CWR from peer yet... arrange to 240 + // keep sending ECNECHO 241 + if (recent_ce_ == FALSE) { 242 + ce_transition = 1; 243 + recent_ce_ = TRUE; 244 + } else { 245 + ce_transition = 0; 246 + } 247 + } else if (datalen > 0 && !fh->ce() && fh->ect()){ 248 + if (recent_ce_ == TRUE) { 249 + ce_transition = 1; 250 + recent_ce_ = FALSE; 251 + } else { 252 + ce_transition = 0; 253 + } 254 + } 255 + } else { 256 if (fh->ce() && fh->ect()) { 257 // no CWR from peer yet... arrange to 258 // keep sending ECNECHO 259 *************** 260 *** 1607,1612 **** 261 --- 1646,1652 ---- 262 recent_ce_ = FALSE; 263 } 264 } 265 + } 266 267 // Header predication basically looks to see 268 // if the incoming packet is an expected pure ACK 269 *************** 270 *** 1638,1645 **** 271 --- 1678,1698 ---- 272 // this routine scans all tcpcb's looking for 273 // DELACK segments and when it finds them 274 // changes DELACK to ACKNOW and calls tcp_output() 275 + 276 + /* DCTCP receiver state machine */ 277 + if (dctcp_ && ce_transition && ((rcv_nxt_ - last_ack_sent_) > 0)) { 278 + // Must send an immediate ACK with with previous ECN state 279 + // before transitioning to new state 280 + flags_ |= TF_ACKNOW; 281 + recent_ce_ = !recent_ce_; 282 + send_much(1, REASON_NORMAL, maxburst_); 283 + recent_ce_ = !recent_ce_; 284 + } 285 + 286 rcv_nxt_ += datalen; 287 flags_ |= TF_DELACK; 288 + // Mohammad 289 + delack_timer_.resched(delack_interval_); 290 recvBytes(datalen); // notify application of "delivery" 291 // 292 // special code here to simulate the operation 293 *************** 294 *** 1816,1821 **** 295 --- 1869,1876 ---- 296 */ 297 if (datalen > 0) { 298 flags_ |= TF_DELACK; // data there: wait 299 + // Mohammad 300 + delack_timer_.resched(delack_interval_); 301 } else { 302 flags_ |= TF_ACKNOW; // ACK peer's SYN 303 } 304 *************** 305 *** 2131,2140 **** 306 // cong_action bit 307 // 308 if (ecn_) { 309 ! if (fh->ce() && fh->ect()) 310 recent_ce_ = TRUE; 311 ! else if (fh->cwr()) 312 recent_ce_ = FALSE; 313 } 314 315 // 316 --- 2186,2216 ---- 317 // cong_action bit 318 // 319 if (ecn_) { 320 ! if (dctcp_) { // Mohammad 321 ! if (fh->ce() && fh->ect()) { 322 ! // no CWR from peer yet... arrange to 323 ! // keep sending ECNECHO 324 ! if (recent_ce_ == FALSE) { 325 ! ce_transition = 1; 326 recent_ce_ = TRUE; 327 ! } else { 328 ! ce_transition = 0; 329 ! } 330 ! } else if (datalen > 0 && !fh->ce() && fh->ect()){ 331 ! if (recent_ce_ == TRUE) { 332 ! ce_transition = 1; 333 recent_ce_ = FALSE; 334 + } else { 335 + ce_transition = 0; 336 + } 337 + } 338 + } else { 339 + if (fh->ce() && fh->ect()) { 340 + recent_ce_ = TRUE; 341 + } else if (fh->cwr()) { 342 + recent_ce_ = FALSE; 343 + } 344 + } 345 } 346 347 // 348 *************** 349 *** 2297,2307 **** 350 if ((!delay_growth_ || (rcv_nxt_ > 0)) && 351 last_state_ == TCPS_ESTABLISHED) { 352 if (!partial || open_cwnd_on_pack_) { 353 ! if (!ect_ || !hdr_flags::access(pkt)->ecnecho()) 354 opencwnd(); 355 } 356 } 357 358 if ((state_ >= TCPS_FIN_WAIT_1) && (ackno == maxseq_)) { 359 ourfinisacked = TRUE; 360 } 361 --- 2373,2391 ---- 362 if ((!delay_growth_ || (rcv_nxt_ > 0)) && 363 last_state_ == TCPS_ESTABLISHED) { 364 if (!partial || open_cwnd_on_pack_) { 365 ! if (!ect_ || !hdr_flags::access(pkt)->ecnecho() || ecn_burst_) 366 opencwnd(); 367 } 368 } 369 370 + // Mohammad: Detect bursts of ECN marks 371 + if (ect_) { 372 + if (!ecn_burst_ && hdr_flags::access(pkt)->ecnecho()) 373 + ecn_burst_ = TRUE; 374 + else if (ecn_burst_ && ! hdr_flags::access(pkt)->ecnecho()) 375 + ecn_burst_ = FALSE; 376 + } 377 + 378 if ((state_ >= TCPS_FIN_WAIT_1) && (ackno == maxseq_)) { 379 ourfinisacked = TRUE; 380 } 381 *************** 382 *** 2395,2401 **** 383 --- 2479,2499 ---- 384 // don't really have a process anyhow, just 385 // accept the data here as-is (i.e. don't 386 // require being in ESTABLISHED state) 387 + 388 + /* Mohammad: For DCTCP state machine */ 389 + if (dctcp_ && ce_transition && ((rcv_nxt_ - last_ack_sent_) > 0)) { 390 + // Must send an immediate ACK with with previous ECN state 391 + // before transitioning to new state 392 + flags_ |= TF_ACKNOW; 393 + recent_ce_ = !recent_ce_; 394 + send_much(1, REASON_NORMAL, maxburst_); 395 + recent_ce_ = !recent_ce_; 396 + } 397 + 398 flags_ |= TF_DELACK; 399 + // Mohammad 400 + delack_timer_.resched(delack_interval_); 401 + 402 rcv_nxt_ += datalen; 403 tiflags = tcph->flags() & TH_FIN; 404 405 *************** 406 *** 2412,2417 **** 407 --- 2510,2519 ---- 408 // segments or hole-fills. Also, 409 // send an ACK (or SACK) to the other side right now. 410 // Note that we may have just a FIN here (datalen = 0) 411 + 412 + /* Note: The DCTCP receiver conveys the ECN-CE 413 + received on each out-of-order data packet */ 414 + 415 int rcv_nxt_old_ = rcv_nxt_; // notify app. if changes 416 tiflags = reass(pkt); 417 if (rcv_nxt_ > rcv_nxt_old_) { 418 *************** 419 *** 2608,2616 **** 420 --- 2710,2756 ---- 421 } 422 reset_rtx_timer(1); 423 t_seqno_ = (highest_ack_ < 0) ? iss_ : int(highest_ack_); 424 + dctcp_alpha_update_seq = t_seqno_; 425 + dctcp_maxseq = dctcp_alpha_update_seq; 426 fastrecov_ = FALSE; 427 dupacks_ = 0; 428 } 429 + 430 + /* 431 + * Update dctcp alpha based on the ecn bit in the received packet. 432 + * This procedure is called only when dctcp_ is 1. 433 + */ 434 + void FullTcpAgent::update_dctcp_alpha(Packet *pkt) 435 + { 436 + int ecnbit = hdr_flags::access(pkt)->ecnecho(); 437 + int ackno = hdr_tcp::access(pkt)->ackno(); 438 + int acked_bytes = ackno - highest_ack_; 439 + 440 + if (acked_bytes <= 0) 441 + acked_bytes = size_; 442 + dctcp_total += acked_bytes; 443 + if (ecnbit) { 444 + dctcp_marked += acked_bytes; 445 + } 446 + 447 + /* Check for barrier indicating its time to recalculate alpha. 448 + * This code basically updated alpha roughly once per RTT. 449 + */ 450 + if (ackno > dctcp_alpha_update_seq) { 451 + double temp_alpha; 452 + dctcp_alpha_update_seq = dctcp_maxseq; 453 + if (dctcp_total > 0) 454 + temp_alpha = ((double) dctcp_marked) / dctcp_total; 455 + else 456 + temp_alpha = 0.0; 457 + 458 + dctcp_alpha_ = (1 - dctcp_g_) * dctcp_alpha_ + dctcp_g_ * temp_alpha; 459 + dctcp_marked = 0; 460 + dctcp_total = 0; 461 + } 462 + } 463 + 464 + 465 /* 466 * deal with timers going off. 467 * 2 types for now: 468 *************** 469 *** 2662,2668 **** 470 flags_ |= TF_ACKNOW; 471 send_much(1, REASON_NORMAL, 0); 472 } 473 ! delack_timer_.resched(delack_interval_); 474 break; 475 default: 476 fprintf(stderr, "%f: FullTcpAgent(%s) Unknown Timeout type %d\n", 477 --- 2802,2809 ---- 478 flags_ |= TF_ACKNOW; 479 send_much(1, REASON_NORMAL, 0); 480 } 481 ! // Mohammad 482 ! // delack_timer_.resched(delack_interval_); 483 break; 484 default: 485 fprintf(stderr, "%f: FullTcpAgent(%s) Unknown Timeout type %d\n", 486 *************** 487 *** 2874,2879 **** 488 --- 3015,3023 ---- 489 * packet. -M. Weigle 6/19/02 490 */ 491 last_cwnd_action_ = CWND_ACTION_DUPACK; 492 + /* Mohammad: cut window by half when we have 3 dup ack */ 493 + if (dctcp_) 494 + slowdown(CLOSE_SSTHRESH_HALF|CLOSE_CWND_HALF); 495 cancel_rtx_timer(); 496 rtt_active_ = FALSE; 497 int amt = fast_retransmit(highest_ack_); 498 Only in ns-2.35/tcp: tcp-full.cc~ 499 diff -crbB ns-allinone-2.35/ns-2.35/tcp/tcp-full.h ns-2.35/tcp/tcp-full.h 500 *** ns-allinone-2.35/ns-2.35/tcp/tcp-full.h 2008-10-14 10:42:52.000000000 -0700 501 --- ns-2.35/tcp/tcp-full.h 2012-03-19 02:40:10.052777998 -0700 502 *************** 503 *** 120,126 **** 504 last_send_time_(-1.0), infinite_send_(FALSE), irs_(-1), 505 delack_timer_(this), flags_(0), 506 state_(TCPS_CLOSED), recent_ce_(FALSE), 507 ! last_state_(TCPS_CLOSED), rq_(rcv_nxt_), last_ack_sent_(-1) { } 508 509 ~FullTcpAgent() { cancel_timers(); rq_.clear(); } 510 virtual void recv(Packet *pkt, Handler*); 511 --- 120,128 ---- 512 last_send_time_(-1.0), infinite_send_(FALSE), irs_(-1), 513 delack_timer_(this), flags_(0), 514 state_(TCPS_CLOSED), recent_ce_(FALSE), 515 ! last_state_(TCPS_CLOSED), rq_(rcv_nxt_), last_ack_sent_(-1), 516 ! dctcp_total(0), dctcp_marked(0), dctcp_alpha_update_seq(0), 517 ! dctcp_maxseq(0), ce_transition(0) { } 518 519 ~FullTcpAgent() { cancel_timers(); rq_.clear(); } 520 virtual void recv(Packet *pkt, Handler*); 521 *************** 522 *** 183,188 **** 523 --- 185,192 ---- 524 void finish(); 525 void reset_rtx_timer(int); // adjust the rtx timer 526 527 + void update_dctcp_alpha(Packet*); // DCTCP alpha update 528 + 529 virtual void timeout_action(); // what to do on rtx timeout 530 virtual void dupack_action(); // what to do on dup acks 531 virtual void pack_action(Packet*); // action on partial acks 532 *************** 533 *** 236,241 **** 534 --- 240,255 ---- 535 int last_state_; /* FSM state at last pkt recv */ 536 int rcv_nxt_; /* next sequence number expected */ 537 ReassemblyQueue rq_; /* TCP reassembly queue */ 538 + 539 + /* 540 + * variables for DCTCP 541 + */ 542 + int dctcp_total; 543 + int dctcp_marked; 544 + int dctcp_alpha_update_seq; 545 + int dctcp_maxseq; 546 + int ce_transition; 547 + 548 /* 549 * the following are part of a tcpcb in "real" RFC1323 TCP 550 */ 551 Only in ns-2.35/tcp: tcp-full.h~ 552 diff -crbB ns-allinone-2.35/ns-2.35/tcp/tcp.h ns-2.35/tcp/tcp.h 553 *** ns-allinone-2.35/ns-2.35/tcp/tcp.h 2011-08-26 12:29:57.000000000 -0700 554 --- ns-2.35/tcp/tcp.h 2012-03-19 02:40:10.049778005 -0700 555 *************** 556 *** 104,110 **** 557 #define CWND_HALF_WITH_MIN 0x00000200 558 #define TCP_IDLE 0x00000400 559 #define NO_OUTSTANDING_DATA 0x00000800 560 ! 561 /* 562 * tcp_tick_: 563 * default 0.1, 564 --- 104,111 ---- 565 #define CWND_HALF_WITH_MIN 0x00000200 566 #define TCP_IDLE 0x00000400 567 #define NO_OUTSTANDING_DATA 0x00000800 568 ! #define CLOSE_SSTHRESH_DCTCP 0x00001000 569 ! #define CLOSE_CWND_DCTCP 0x00002000 570 /* 571 * tcp_tick_: 572 * default 0.1, 573 *************** 574 *** 432,437 **** 575 --- 433,444 ---- 576 577 /* Used for ECN */ 578 int ecn_; /* Explicit Congestion Notification */ 579 + 580 + /* Use for DCTCP */ 581 + int dctcp_; 582 + double dctcp_alpha_; 583 + double dctcp_g_; 584 + 585 int cong_action_; /* Congestion Action. True to indicate 586 that the sender responded to congestion. */ 587 int ecn_burst_; /* True when the previous ACK packet 588 Only in ns-2.35/tcp: tcp.h~