⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp-sock.cc

📁 升级版的p2p文件共享linux环境ns2仿真软件
💻 CC
📖 第 1 页 / 共 3 页
字号:
                /*                 * If we have a timestamp reply, update smoothed                 * round trip time.  If no timestamp is present but                 * transmit timer is running and timed sequence                 * number was acked, update smoothed round trip time.                 * Since we now have an rtt measurement, cancel the                 * timer backoff (cf., Phil Karn's retransmit alg.).                 * Recompute the initial retransmit timer.		 *                 * If all outstanding data is acked, stop retransmit                 * If there is more data to be acked, restart retransmit                 * timer, using current (possibly backed-off) value.                 */		newack(pkt);	// handle timers, update highest_ack_		--pipe_;		/*		 * if this is a partial ACK, invoke whatever we should		 */		int partial = pack(pkt);		if (partial)			pack_action(pkt);		else			ack_action(pkt);		/*		 * if this is an ACK with an ECN indication, handle this		 */		if (fh->ecnecho())			ecn(highest_ack_);  // updated by newack(), above		// CHECKME: handling of rtx timer		if (ackno == maxseq_) {			needoutput = TRUE;		}		/*		 * If no data (only SYN) was ACK'd,		 *    skip rest of ACK processing.		 */		if (ackno == (highest_ack_ + 1))			goto step6;		// if we are delaying initial cwnd growth (probably due to		// large initial windows), then only open cwnd if data has		// been received                /*                 * When new data is acked, open the congestion window.                 * If the window gives us less than ssthresh packets                 * in flight, open exponentially (maxseg per packet).                 * Otherwise open about linearly: maxseg per window                 * (maxseg^2 / cwnd per packet).                 */		if ((!delay_growth_ || (rcv_nxt_ > 0)) &&		    last_state_ == TCPS_ESTABLISHED) {			if (!partial || open_cwnd_on_pack_)				opencwnd();		}		// K: added state check in equal but diff way		if ((state_ >= TCPS_FIN_WAIT_1) && (ackno == maxseq_)) {			ourfinisacked = TRUE;		} else {			ourfinisacked = FALSE;		}		// additional processing when we're in special states		switch (state_) {                /*                 * In FIN_WAIT_1 STATE in addition to the processing                 * for the ESTABLISHED state if our FIN is now acknowledged                 * then enter FIN_WAIT_2.                 */		case TCPS_FIN_WAIT_1:	/* doing active close */			if (ourfinisacked) {				// got the ACK, now await incoming FIN				newstate(TCPS_FIN_WAIT_2);				cancel_timers();				needoutput = FALSE;			}			break;                /*                 * In CLOSING STATE in addition to the processing for                 * the ESTABLISHED state if the ACK acknowledges our FIN                 * then enter the TIME-WAIT state, otherwise ignore                 * the segment.                 */		case TCPS_CLOSING:	/* simultaneous active close */;			if (ourfinisacked) {				newstate(TCPS_CLOSED);				cancel_timers();			}			break;                /*                 * In LAST_ACK, we may still be waiting for data to drain                 * and/or to be acked, as well as for the ack of our FIN.                 * If our FIN is now acknowledged,                 * enter the closed state and return.                 */		case TCPS_LAST_ACK:	/* passive close */			// K: added state change here			if (ourfinisacked) {				newstate(TCPS_CLOSED);#ifdef notdefcancel_timers();	// DOES THIS BELONG HERE?, probably (see tcp_cose#endif				finish();				reset();				goto drop;			} else {				// should be a FIN we've seen				hdr_ip* iph = hdr_ip::access(pkt);                                fprintf(stderr,                                "%f: %d.%d>%d.%d FullTcpAgent::recv(%s) received non-ACK (state:%d)\n",                                        now(),                                        iph->saddr(), iph->sport(),                                        iph->daddr(), iph->dport(),                                        name(), state_);                        }			break;		/* no case for TIME_WAIT in simulator */		}  // inner switch	} // outer switchstep6:	/* real TCP handles window updates and URG data here *//* dodata: this label is in the "real" code.. here only for reference */	/*	 * DATA processing	 */	if ((datalen > 0 || (tiflags & TH_FIN)) &&	    TCPS_HAVERCVDFIN(state_) == 0) {		if (tcph->seqno() == rcv_nxt_ && rq_.empty()) {			// see the "TCP_REASS" macro for this code:			// got the in-order packet we were looking			// for, nobody is in the reassembly queue,			// so this is the common case...			// note: in "real" TCP we must also be in			// ESTABLISHED state to come here, because			// data arriving before ESTABLISHED is			// queued in the reassembly queue.  Since we			// don't really have a process anyhow, just			// accept the data here as-is (i.e. don't			// require being in ESTABLISHED state)			flags_ |= TF_DELACK;			PktDataEntry *pe = new PktDataEntry(rcv_nxt_, (PacketData *)pkt->userdata());			rcv_buf_.append(pe);			rcv_nxt_ += datalen;			rcv_wnd_ -= datalen;			if(pkt->userdata() && datalen) {			if(datalen==((PacketData *)pkt->userdata())->size())			  recvBytes(datalen); // notify app. of "delivery"			}			tiflags = tcph->flags() & TH_FIN;			needoutput = TRUE;		} else {			// see the "tcp_reass" function:			// not the one we want next (or it			// is but there's stuff on the reass queue);			// do whatever we need to do for out-of-order			// segments or hole-fills.  Also,			// send an ACK to the other side right now.			// K: some changes here, figure out			int rcv_nxt_old_ = rcv_nxt_; // notify app. if changes						tiflags = reass(pkt);			PktDataEntry *pe = new PktDataEntry(tcph->seqno(), (PacketData *)pkt->userdata());			insert(&rcv_buf_, pe);			if (rcv_nxt_ > rcv_nxt_old_)				recvBytes(rcv_nxt_ - rcv_nxt_old_);			if(datalen && app_)			  ((NSSocket *)app_)->upcall_recv((PacketData*)pkt->userdata());			if (tiflags & TH_PUSH) {				// K: APPLICATION recv				needoutput = need_send();			} else {				flags_ |= TF_ACKNOW;			}		}	} else {		/*		 * we're closing down or this is a pure ACK that		 * wasn't handled by the header prediction part above		 * (e.g. because cwnd < wnd)		 */		// K: this is deleted		tiflags &= ~TH_FIN;	}	/*	 * if FIN is received, ACK the FIN	 * (let user know if we could do so)	 */	if (tiflags & TH_FIN) {		if (TCPS_HAVERCVDFIN(state_) == 0) {			flags_ |= TF_ACKNOW;			rcv_nxt_++;		}		if(app_)		  app_->upcall_closing();		switch (state_) {                /*                 * In SYN_RECEIVED and ESTABLISHED STATES                 * enter the CLOSE_WAIT state.		 * (passive close)                 */                case TCPS_SYN_RECEIVED:                case TCPS_ESTABLISHED:			newstate(TCPS_CLOSE_WAIT);                        break;                /*                 * If still in FIN_WAIT_1 STATE FIN has not been acked so                 * enter the CLOSING state.		 * (simultaneous close)                 */                case TCPS_FIN_WAIT_1:			newstate(TCPS_CLOSING);                        break;                /*                 * In FIN_WAIT_2 state enter the TIME_WAIT state,                 * starting the time-wait timer, turning off the other                 * standard timers.		 * (in the simulator, just go to CLOSED)		 * (completion of active close)                 */                case TCPS_FIN_WAIT_2:                        newstate(TCPS_CLOSED);			cancel_timers();                        break;		}	} /* end of if FIN bit on */	if (needoutput || (flags_ & TF_ACKNOW))		send_much(1, REASON_NORMAL, maxburst_);	else if (curseq_ >= highest_ack_ || infinite_send_)		send_much(0, REASON_NORMAL, maxburst_);	// K: which state to return to when nothing left?	if (!halfclose_ && state_ == TCPS_CLOSE_WAIT && highest_ack_ == maxseq_)		usrclosed();	Packet::free(pkt);	// haoboy: Is here the place for done{} of active close? 	// It cannot be put in the switch above because we might need to do	// send_much() (an ACK)	if (state_ == TCPS_CLOSED) 		Tcl::instance().evalf("%s done", this->name());	return;dropafterack:	flags_ |= TF_ACKNOW;	send_much(1, REASON_NORMAL, maxburst_);	goto drop;dropwithreset:	/* we should be sending an RST here, but can't in simulator */	if (tiflags & TH_ACK) {		sendpacket(ackno, 0, 0x0, 0, NULL, REASON_NORMAL);	} else {		int ack = tcph->seqno() + datalen;		if (tiflags & TH_SYN)			ack--;		sendpacket(0, ack, TH_ACK, 0, NULL, REASON_NORMAL);	}drop:	Packet::free(pkt);	return;}voidSocketTcp::sendpacket(int seqno, int ackno, int pflags, int datalen, PacketData *data, int reason){        Packet* p = allocpkt(datalen);        hdr_tcp *tcph = hdr_tcp::access(p);	/* build basic header w/options */        tcph->seqno() = seqno;        tcph->ackno() = ackno;        tcph->flags() = pflags;        tcph->reason() |= reason; // make tcph->reason look like ns1 pkt->flags?	tcph->sa_length() = 0;    // may be increased by build_options()        tcph->hlen() = tcpip_base_hdr_size_;	tcph->hlen() += build_options(tcph);	tcph->advwin() = rcv_wnd_;	/* ECT, ECN, and congestion action */        hdr_flags *fh = hdr_flags::access(p);	fh->ect() = ect_;	// on after mutual agreement on ECT	if (ecn_ && !ect_)	// initializing; ect = 0, ecnecho = 1		fh->ecnecho() = 1;	else {		fh->ecnecho() = recent_ce_;	}	fh->cong_action() =  cong_action_;	/* actual size is data length plus header length */        hdr_cmn *ch = hdr_cmn::access(p);        ch->size() = datalen + tcph->hlen();        if (datalen <= 0)                ++nackpack_;        else {                ++ndatapack_;                ndatabytes_ += datalen;		last_send_time_ = now();	// time of last data		if(data) {		  p->setdata(data->copy());		}else {		  fprintf(stderr, "datalen>0 without data\n");		}		        }        if (reason == REASON_TIMEOUT || reason == REASON_DUPACK) {                ++nrexmitpack_;                nrexmitbytes_ += datalen;        }	last_ack_sent_ = ackno;	send(p, 0);}int SocketTcp::r_advance_bytes(int nb) {	int new_inc = nb, old_curseq = curseq_;        //        // state-specific operations:        //      if CLOSED, reset and try a new active open/connect        //      if ESTABLISHED, just try to send more        //      if above ESTABLISHED, we are closing, so don't allow        //      if anything else (establishing), do nothing here        //        if (state_ > TCPS_ESTABLISHED) {            fprintf(stderr,            "%f: SocketTcpAgent::advance(%s): cannot advance while in state %d\n",                 now(), name(), state_);            return 0;        } else if (state_ == TCPS_CLOSED) {                reset();                curseq_ = iss_ + nb;                connect();              // initiate new connection        } else if (state_ == TCPS_ESTABLISHED) {                closed_ = 0;                if (curseq_ < iss_)                        curseq_ = iss_;		curseq_ = curseq_ + nb > (highest_ack_ + snd_wnd_)? highest_ack_+ snd_wnd_: curseq_+nb;		new_inc = curseq_ - old_curseq;                 send_much (0, REASON_NORMAL, maxburst_);        }        return new_inc;	}int SocketTcp::r_advance_pkt(PacketData *p) {	int new_inc = 0, old_curseq = curseq_, nb;	if(p==NULL)	  return 0;	nb = p->size();        if (state_ > TCPS_ESTABLISHED) {            fprintf(stderr,            "%f: SocketTcpAgent::advance(%s %d): cannot advance while in state %d\n",                 now(), name(),  here_.addr_, state_);	    // socket is closed            return -1;        } else if (state_ == TCPS_CLOSED) {                reset();		PktDataEntry *pe = new PktDataEntry((int)curseq_+1, p);		curseq_ += nb;		snd_buf_.append(pe);                connect();              // initiate new connection	       	return 0;	} else if (state_ == TCPS_ESTABLISHED) {                 closed_ = 0;                if (curseq_ < iss_)                        curseq_ = iss_;		curseq_ = curseq_ + nb > (highest_ack_ + snd_wnd_)? (int)curseq_: curseq_ + nb;		new_inc = curseq_ - old_curseq; 		if(new_inc) {		  PktDataEntry *pe = new PktDataEntry(old_curseq + 1, p);		  apcnt++;		  snd_buf_.append(pe);		}                send_much(0, REASON_NORMAL, maxburst_);        }	if (new_inc && curseq_ + nb <= highest_ack_ + snd_wnd_)	  return 1;	if (new_inc && curseq_ + nb > highest_ack_ + snd_wnd_)	  return 0;	if(p!=NULL) {	  dropcnt++;	}	return -1;}void SocketTcp::listen(int max) {  FullTcpAgent::listen();  max_conn_ = max;  listen_only_ = TRUE;}void SocketTcp::ack_syn(Packet *synpkt) {  hdr_tcp *tcph = hdr_tcp::access(synpkt);  irs_ = tcph->seqno();  t_seqno_ = iss_; /* tcp_sendseqinit() macro in real tcp */  rcv_nxt_ = rcvseqinit(irs_, 0);  flags_ |= TF_ACKNOW;  newstate(TCPS_SYN_RECEIVED);  send_much(1, REASON_NORMAL, maxburst_);  return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -