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

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (c) 1997 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  * This product includes software developed by the Daedalus Research
  17.  * Group at the University of California Berkeley.
  18.  * 4. Neither the name of the University nor of the Laboratory may be used
  19.  *    to endorse or promote products derived from this software without
  20.  *    specific prior written permission.
  21.  *
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32.  * SUCH DAMAGE.
  33.  *
  34.  * Contributed by the Daedalus Research Group, U.C.Berkeley
  35.  * http://daedalus.cs.berkeley.edu
  36.  *
  37.  * @(#) $Header:
  38.  */
  39. /*
  40.  * tcp-asym includes modifications to several flavors of TCP to enhance
  41.  * performance over asymmetric networks, where the ack channel is
  42.  * constrained.  Types of asymmetry we have studied and used these mods
  43.  * include bandwidth asymmetry and latency asymmetry (where  variable 
  44.  * latencies cause problems to TCP, e.g., in packet radio networks.
  45.  * The sender-side modifications in this file are structured as helper 
  46.  * functions that are invoked from various points in the TCP code. The main
  47.  * additional functionality is (a) the sender increases its congestion window
  48.  * in proportion to the amount of data acked rather than the number of acks
  49.  * received, (b) it breaks up potentially large bursts into smaller ones 
  50.  * when acks are few and far between by rate-based pacing, and 
  51.  * (c) it copies the ecn_to_echo_ bit from acks into subsequent data packets, 
  52.  * using which the sink can perform ack congestion control (tcp-asym-sink.cc). 
  53.  * The tcp-asym source is usually used in conjunction with a tcp-asym sink, or
  54.  * with a router/end-host implementing ack filtering (semantic-packetqueue.cc).
  55.  * 
  56.  * For questions/comments, please contact:
  57.  *   Venkata N. Padmanabhan (padmanab@cs.berkeley.edu)
  58.  *   http://www.cs.berkeley.edu/~padmanab
  59.  */ 
  60. #ifndef lint
  61. static const char rcsid[] =
  62.     "@(#) $Header: /cvsroot/nsnam/ns-2/tcp/tcp-asym.cc,v 1.17 1999/09/09 03:22:50 salehi Exp $ (UCB)";
  63. #endif
  64. #include "tcp-asym.h"
  65. int hdr_tcpasym::offset_;
  66. static class TCPAHeaderClass : public PacketHeaderClass {
  67. public:
  68.         TCPAHeaderClass() : PacketHeaderClass("PacketHeader/TCPA",
  69.      sizeof(hdr_tcpasym)) {
  70. bind_offset(&hdr_tcpasym::offset_);
  71. }
  72. } class_tcpahdr;
  73. static class TcpAsymClass : public TclClass {
  74. public:
  75. TcpAsymClass() : TclClass("Agent/TCP/Asym") {}
  76. TclObject* create(int, const char*const*) {
  77. return (new TcpAsymAgent());
  78. } class_tcpasym;
  79. TcpAsymAgent::TcpAsymAgent() : TcpAgent(), ecn_to_echo_(0), t_exact_srtt_(0)
  80. {
  81. /* bind("exact_srtt_", &t_exact_srtt_);*/
  82. bind("g_", &g_);
  83. /* bind("avg_win_", &avg_win_);*/
  84. /* bind("damp_", &damp_);*/
  85. }
  86. static class TcpRenoAsymClass : public TclClass {
  87. public:
  88. TcpRenoAsymClass() : TclClass("Agent/TCP/Reno/Asym") {}
  89. TclObject* create(int, const char*const*) {
  90. return (new TcpRenoAsymAgent());
  91. } class_tcprenoasym;
  92. static class NewRenoTcpAsymClass : public TclClass {
  93. public:
  94. NewRenoTcpAsymClass() : TclClass("Agent/TCP/Newreno/Asym") {}
  95. TclObject* create(int, const char*const*) {
  96. return (new NewRenoTcpAsymAgent());
  97. } class_newrenotcpasym;
  98. /* The helper functions */
  99. /* fill in the TCP asym header before packet is sent out */
  100. void TcpAsymAgent::output_helper(Packet* p) 
  101. {
  102. hdr_tcpasym *tcpha = hdr_tcpasym::access(p);
  103. hdr_flags *flagsh = hdr_flags::access(p);
  104. tcpha->win() = min(highest_ack_+window(), curseq_) - t_seqno_;
  105. tcpha->highest_ack() = highest_ack_;
  106. tcpha->max_left_to_send() = curseq_ - highest_ack_; /* XXXX not needed? */
  107. flagsh->ecnecho() = ecn_to_echo_;
  108. ecn_to_echo_ = 0;
  109. }
  110. /* schedule the next burst of data (of size at most maxburst) */
  111. void TcpAsymAgent::send_helper(int maxburst) 
  112. {
  113. /* 
  114.  * If there is still data to be sent and there is space in the
  115.  * window, set a timer to schedule the next burst. Note that
  116.  * we wouldn't get here if TCP_TIMER_BURSTSEND were pending,
  117.  * so we do not need an explicit check here.
  118.  */
  119. if (t_seqno_ <= highest_ack_ + window() && t_seqno_ < curseq_) {
  120. burstsnd_timer_.resched(t_exact_srtt_*maxburst/window());
  121. }
  122. }
  123. /* check if the received ack has an ECN that needs to be echoed back to the sink */
  124. void TcpAsymAgent::recv_helper(Packet *pkt) 
  125. {
  126. if (hdr_flags::access(pkt)->ce())
  127. ecn_to_echo_ = 1;
  128. }
  129. /* open cwnd in proportion to the amount of data acked */
  130. void TcpAsymAgent::recv_newack_helper(Packet *pkt) 
  131. {
  132. int i;
  133. hdr_tcp *tcph = hdr_tcp::access(pkt);
  134. int ackcount = tcph->seqno() - last_ack_;
  135. double tao = Scheduler::instance().clock() - tcph->ts_echo();
  136. newack(pkt);
  137. /* update our fine-grained estimate of the smoothed RTT */
  138. if (t_exact_srtt_ != 0) 
  139. t_exact_srtt_ = g_*tao + (1-g_)*t_exact_srtt_;
  140. else
  141. t_exact_srtt_ = tao;
  142. /* avg_win_ = g_*window() + (1-g_)*avg_win_;*/
  143. /* grow cwnd */
  144. for (i=0; i<ackcount; i++)
  145. opencwnd();
  146. /* if the connection is done, call finish() */
  147. if ((highest_ack_ >= curseq_-1) && !closed_) {
  148. closed_ = 1;
  149. finish();
  150. }
  151. }
  152. /* Print out if tcp-asym-specific variables have been modified */
  153. void TcpAsymAgent::traceVar(TracedVar* v) {
  154. Scheduler& s = Scheduler::instance();
  155. char wrk[500];
  156. double curtime = &s ? s.clock() : 0;
  157. if (!strcmp(v->name(), "exact_srtt_"))
  158. sprintf(wrk,"%-8.5f %-2d %-2d %-2d %-2d %s %-6.3f", 
  159. curtime, addr(), port(), daddr(), dport(),
  160. v->name(), double(*((TracedDouble*) v)));
  161. else if (!strcmp(v->name(), "avg_win_"))
  162. sprintf(wrk,"%-8.5f %-2d %-2d %-2d %-2d %s %-6.3f", 
  163. curtime, addr(), port(), daddr(), dport(), 
  164. v->name(), double(*((TracedDouble*) v)));
  165. else {
  166. TcpAgent::traceVar(v);
  167. return;
  168. }
  169. int n = strlen(wrk);
  170. wrk[n] = 'n';
  171. wrk[n+1] = 0;
  172. if (channel_)
  173. (void)Tcl_Write(channel_, wrk, n+1);
  174. wrk[n] = 0;
  175. return;
  176. }
  177. /* Print out all the traced variables whenever any one is changed */
  178. void
  179. TcpAsymAgent::traceAll() {
  180. double curtime;
  181. Scheduler& s = Scheduler::instance();
  182. char wrk[500];
  183. int n;
  184. TcpAgent::traceAll();
  185. curtime = &s ? s.clock() : 0;
  186. sprintf(wrk, "time: %-8.5f saddr: %-2d sport: %-2d daddr: %-2d dport:"
  187. " %-2d exact_srtt %d", curtime, addr(), port(),
  188. daddr(), dport(), (int(t_exact_srtt_)));
  189. n = strlen(wrk);
  190. wrk[n] = 'n';
  191. wrk[n+1] = 0;
  192. if (channel_)
  193. (void)Tcl_Write(channel_, wrk, n+1);
  194. wrk[n] = 0;
  195. return;
  196. }