FullTcpAgent::sendpacket():
*** 837,842 ****
--- 851,860 ----
if ( datalen > 0 && ecn_ ){
fh->ect() = ect_; // on after mutual agreement on ECT
}
+ else {
+ /* Set ect() to 0. -M. Weigle 1/19/05 */
+ fh->ect() = 0;
+ }
// fill in CWR and ECE bits which don't actually sit in
// the tcp_flags but in hdr_flags
***************
*** 848,861 ****
if ( pflags & TH_CWR ) {
fh->cong_action() = 1;
}
!
! //
! // although CWR bit is ordinarily associated with ECN,
! // it utility within the simulator for traces. Thus, set
! // it even if we aren't doing ECN
! //
! if ( datalen > 0 )
! fh->cwr() = cong_action_;
/* actual size is data length plus header length */
--- 866,875 ----
if ( pflags & TH_CWR ) {
fh->cong_action() = 1;
}
! else {
! /* Set cong_action() to 0 -M. Weigle 1/19/05 */
! fh->cong_action() = 0;
! }
/* actual size is data length plus header length */
FullTcpAgent::flagstr():
*** 558,565 ****
"<ACK>", "<ACK,FIN>", "<ACK,SYN>", "<ACK,SYN,FIN>", // 0x14-0x17
"<PSH,ACK>", "<PSH,ACK,FIN>", "<PSH,ACK,SYN>", "<PSH,ACK,SYN,FIN>", // 0x18-0x1b
};
! if (hflags < 0 || (hflags > 28))
! return ("<invalid>");
return (flagstrs[hflags]);
}
--- 558,578 ----
"<ACK>", "<ACK,FIN>", "<ACK,SYN>", "<ACK,SYN,FIN>", // 0x14-0x17
"<PSH,ACK>", "<PSH,ACK,FIN>", "<PSH,ACK,SYN>", "<PSH,ACK,SYN,FIN>", // 0x18-0x1b
};
! if (hflags < 0 || (hflags > 28)) {
! /* Added strings for CWR and ECE -M. Weigle 6/27/02 */
! if (hflags == 72)
! return ("<ECE,PSH>");
! else if (hflags == 80)
! return ("<ECE,ACK>");
! else if (hflags == 88)
! return ("<ECE,PSH,ACK>");
! else if (hflags == 152)
! return ("<CWR,PSH,ACK>");
! else if (hflags == 153)
! return ("<CWR,PSH,ACK,FIN>");
! else
! return ("<invalid>");
! }
return (flagstrs[hflags]);
}
(The code for this fix is included in the fix for the next bug.)
June 12, 2002
Symptom: "recvd ecnecho but I am not ECN capable!" error messages
Problem: ECN is not being used even though both sides requested it.
When a ECN-enabled SYN is received, the receiver sets ect_. If the
ECN-enabled SYN+ACK is dropped and a timeout occurs, cong_action_ is set.
Then, when the SYN+ACK is retranmitted, it has the CWR bit set, which is not
a valid ECN SYN+ACK.
Example: ns tcp-full-bugs.tcl ecn-drop-synack (Results)
Fix: Don't set CWR if the packet is a SYN+ACK. Move setting CWR from sendpacket() to foutput() so this is done correctly.
(See email sent to ns-users mailing list)
(The code below shows fixes for both of these bugs)
FullTcpAgent::sendpacket():
- // - // although CWR bit is ordinarily associated with ECN, - // it utility within the simulator for traces. Thus, set - // it even if we aren't doing ECN - // - if ( datalen > 0 ) - fh->cwr() = cong_action_; ----
FullTcpAgent::foutput():
*** 1068,1076 ****
pflags |= TH_ECE;
pflags &= ~TH_CWR;
}
!
! /* set CWR if necessary */
! if (ecn_ && ect_ && cong_action_) pflags |= TH_CWR;
/* set ECE if necessary */
if (ecn_ && ect_ && recent_ce_ ) pflags |= TH_ECE;
--- 1082,1105 ----
pflags |= TH_ECE;
pflags &= ~TH_CWR;
}
! else if (ecn_ && ect_ && cong_action_ && !is_retransmit)
! /*
! * Don't set CWR for a retranmitted SYN+ACK (has ecn_
! * and cong_action_ set) or on any retransmits.
! * -M. Weigle 6/19/02
! */
! /* set CWR if necessary */
! pflags |= TH_CWR;
!
! /* moved from sendpacket() -M. Weigle 6/19/02 */
! //
! // although CWR bit is ordinarily associated with ECN,
! // it has utility within the simulator for traces. Thus, set
! // it even if we aren't doing ECN
! //
! if (datalen > 0 && cong_action_ && !is_retransmit) {
! pflags |= TH_CWR;
! }
/* set ECE if necessary */
if (ecn_ && ect_ && recent_ce_ ) pflags |= TH_ECE;
FullTcpAgent::foutput():
*** 1107,1113 **** */ int reliable = datalen + syn + fin; // seq #'s reliably sent ! if (cong_action_ && reliable > 0) cong_action_ = FALSE; // highest: greatest sequence number sent + 1 --- 1136,1146 ---- */ int reliable = datalen + syn + fin; // seq #'s reliably sent ! /* ! * Don't reset cong_action_ until we send new data. ! * -M. Weigle 6/19/02 ! */ ! if (cong_action_ && reliable > 0 && !is_retransmit) cong_action_ = FALSE; // highest: greatest sequence number sent + 1
FullTcpAgent definition in tcp/tcp-full.h
*** 119,125 ****
closed_(0), pipe_(-1), rtxbytes_(0), fastrecov_(FALSE),
last_send_time_(-1.0), infinite_send_(FALSE), irs_(-1),
delack_timer_(this), flags_(0),
! state_(TCPS_CLOSED), ect_(FALSE), recent_ce_(FALSE),
last_state_(TCPS_CLOSED), rq_(rcv_nxt_), last_ack_sent_(-1) { }
~FullTcpAgent() { cancel_timers(); rq_.clear(); }
--- 119,125 ----
closed_(0), pipe_(-1), rtxbytes_(0), fastrecov_(FALSE),
last_send_time_(-1.0), infinite_send_(FALSE), irs_(-1),
delack_timer_(this), flags_(0),
! state_(TCPS_CLOSED), recent_ce_(FALSE),
last_state_(TCPS_CLOSED), rq_(rcv_nxt_), last_ack_sent_(-1) { }
~FullTcpAgent() { cancel_timers(); rq_.clear(); }
***************
*** 225,231 ****
int maxseg_; /* MSS */
int flags_; /* controls next output() call */
int state_; /* enumerated type: FSM state */
- int ect_; /* turn on ect bit now? */
int recent_ce_; /* last ce bit we saw */
int last_state_; /* FSM state at last pkt recv */
int rcv_nxt_; /* next sequence number expected */