├── LICENSE_ns-allinone-2.34.qjump.patch ├── LICENSE_ns-allinone-2.34.ubuntu.patch ├── LICENSE_pfabric.patch ├── README.md ├── drive_all.sh ├── drive_qjump.sh ├── learning_CDF.tcl ├── ns-allinone-2.34.qjump.patch ├── ns-allinone-2.34.ubuntu.patch ├── pfabric.patch ├── qjump.tcl ├── run_baseline.sh ├── run_dctcp.sh ├── run_pfabric.sh ├── run_qjump.sh ├── search_CDF.tcl └── tcp-common-opt.tcl /LICENSE_ns-allinone-2.34.qjump.patch: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Ionel Gog. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | * Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | * Neither the name of copyright holder nor the names of the contributors may 14 | be used to endorse or promote products derived from this software without 15 | specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | -------------------------------------------------------------------------------- /LICENSE_ns-allinone-2.34.ubuntu.patch: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Matthew P. Grosvenor. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | * Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | * Neither the name of copyright holder nor the names of the contributors may 14 | be used to endorse or promote products derived from this software without 15 | specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | -------------------------------------------------------------------------------- /LICENSE_pfabric.patch: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, The Board of Trustees of The Leland Stanford Junior 2 | University. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of copyright holder nor the names of the contributors may 15 | be used to endorse or promote products derived from this software without 16 | specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | NS2 DCTCP and pFabric Patches 2 | ============================= 3 | 4 | Patches to NS2 to add DCTCP and pFabric functionality. 5 | 6 | Thanks go to Mohammad Alizadeh,Shuang Yang, Nick McKeown and the pFabric and DCTCP authors for providing these. 7 | 8 | Full instructions for how to apply, build and run the patches can be found here: http://www.cl.cam.ac.uk/research/srg/netos/qjump/nsdi2015/figure9.html 9 | 10 | See LICENSE for more details. 11 | 12 | -------------------------------------------------------------------------------- /drive_all.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # Copyright (c) 2015, Matthew P. Grosvenor 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 are met: 8 | # 9 | # * Redistributions of source code must retain the above copyright notice, this 10 | # list of conditions and the following disclaimer. 11 | # 12 | # * Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 16 | # * Neither the name of the project, the name of copyright holder nor the names 17 | # of its contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | #set -x 32 | CDF="learning" 33 | CDF="search" 34 | 35 | 36 | #for CDF in "learning"; do 37 | for CDF in "search" "learning"; do 38 | if [ "$CDF" == "search" ]; then MEAN_FLOW_SIZE=1661480; fi #1138 packets * 1460B 39 | if [ "$CDF" == "learning" ]; then MEAN_FLOW_SIZE=7470820; fi #5117 packets * 1460B 40 | 41 | #for type in "qjump" ; do 42 | for type in "baseline" "pfabric" "dctcp"; do 43 | if [ "$type" == "baseline" ]; then con_per_pair=8; fi 44 | if [ "$type" == "dctcp" ]; then con_per_pair=8; fi 45 | if [ "$type" == "pfabric" ]; then con_per_pair=1; fi 46 | if [ "$type" == "qjump" ]; then con_per_pair=10; fi 47 | 48 | pids="" 49 | #for i in "0.95" "0.99" "0.999"; do 50 | #for i in "0.8" ; do 51 | for i in "0.8" "0.7" "0.6" "0.5" "0.4" "0.3" "0.2" "0.1"; do 52 | name=${type}_${CDF}_$i 53 | mkdir -p $name 54 | cp *.tcl *.sh $name 55 | cd $name 56 | cmd="time ./run_${type}.sh 100000 $i $con_per_pair ${CDF}_CDF.tcl $MEAN_FLOW_SIZE &> $name.log &" 57 | echo $cmd 58 | eval $cmd 59 | pids="$pids $!" 60 | cd - 61 | done 62 | 63 | for pid in $pids; do 64 | echo "Waiting for $pid" 65 | wait $pid 66 | done 67 | 68 | done 69 | done 70 | -------------------------------------------------------------------------------- /drive_qjump.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # Copyright (c) 2015, Matthew P. Grosvenor 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 are met: 8 | # 9 | # * Redistributions of source code must retain the above copyright notice, this 10 | # list of conditions and the following disclaimer. 11 | # 12 | # * Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 16 | # * Neither the name of the project, the name of copyright holder nor the names 17 | # of its contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | #set -x 32 | CDF="learning" 33 | CDF="search" 34 | 35 | 36 | #for CDF in "learning"; do 37 | for CDF in "search" "learning"; do 38 | if [ "$CDF" == "search" ]; then MEAN_FLOW_SIZE=1661480; fi #1138 packets * 1460B 39 | if [ "$CDF" == "learning" ]; then MEAN_FLOW_SIZE=7470820; fi #5117 packets * 1460B 40 | 41 | for type in "qjump" ; do 42 | #for type in "baseline" "pfabric" "dctcp"; do 43 | if [ "$type" == "baseline" ]; then con_per_pair=8; fi 44 | if [ "$type" == "dctcp" ]; then con_per_pair=8; fi 45 | if [ "$type" == "pfabric" ]; then con_per_pair=1; fi 46 | if [ "$type" == "qjump" ]; then con_per_pair=10; fi 47 | 48 | pids="" 49 | #for i in "0.95" "0.99" "0.999"; do 50 | #for i in "0.8" ; do 51 | for i in "0.8" "0.7" "0.6" "0.5" "0.4" "0.3" "0.2" "0.1"; do 52 | name=${type}_${CDF}_$i 53 | mkdir -p $name 54 | cp *.tcl *.sh $name 55 | cd $name 56 | cmd="time ./run_${type}.sh 100000 $i $con_per_pair ${CDF}_CDF.tcl $MEAN_FLOW_SIZE &> $name.log &" 57 | echo $cmd 58 | eval $cmd 59 | pids="$pids $!" 60 | cd - 61 | done 62 | 63 | for pid in $pids; do 64 | echo "Waiting for $pid" 65 | wait $pid 66 | done 67 | 68 | done 69 | done 70 | -------------------------------------------------------------------------------- /learning_CDF.tcl: -------------------------------------------------------------------------------- 1 | 1 1 0 2 | 1 1 0.5 3 | 2 1 0.6 4 | 3 1 0.7 5 | 7 1 0.8 6 | 267 1 0.9 7 | 2107 1 0.95 8 | 66667 1 0.99 9 | 666667 1 1 10 | -------------------------------------------------------------------------------- /ns-allinone-2.34.ubuntu.patch: -------------------------------------------------------------------------------- 1 | diff -rupN ns-allinone-2.34/ns-2.34/linkstate/ls.h ns-allinone-2.34-ubutnu/ns-2.34/linkstate/ls.h 2 | --- ns-allinone-2.34/ns-2.34/linkstate/ls.h 2009-06-14 18:35:43.000000000 +0100 3 | +++ ns-allinone-2.34-ubutnu/ns-2.34/linkstate/ls.h 2015-03-04 16:42:18.618790250 +0000 4 | @@ -134,7 +134,7 @@ public: 5 | return ib.second ? ib.first : baseMap::end(); 6 | } 7 | 8 | - void eraseAll() { erase(baseMap::begin(), baseMap::end()); } 9 | + void eraseAll() { this->erase(baseMap::begin(), baseMap::end()); } 10 | T* findPtr(Key key) { 11 | iterator it = baseMap::find(key); 12 | return (it == baseMap::end()) ? (T *)NULL : &((*it).second); 13 | diff -rupN ns-allinone-2.34/ns-2.34/mac/mac-802_11Ext.h ns-allinone-2.34-ubutnu/ns-2.34/mac/mac-802_11Ext.h 14 | --- ns-allinone-2.34/ns-2.34/mac/mac-802_11Ext.h 2009-06-14 18:35:44.000000000 +0100 15 | +++ ns-allinone-2.34-ubutnu/ns-2.34/mac/mac-802_11Ext.h 2015-03-04 15:52:13.150820258 +0000 16 | @@ -62,6 +62,7 @@ 17 | #define GET_ETHER_TYPE(x) GET2BYTE((x)) 18 | #define SET_ETHER_TYPE(x,y) {u_int16_t t = (y); STORE2BYTE(x,&t);} 19 | #include "wireless-phyExt.h" 20 | +#include 21 | 22 | /* ====================================================================== 23 | Frame Formats 24 | diff -rupN ns-allinone-2.34/ns-2.34/mobile/nakagami.cc ns-allinone-2.34-ubutnu/ns-2.34/mobile/nakagami.cc 25 | --- ns-allinone-2.34/ns-2.34/mobile/nakagami.cc 2009-06-14 18:35:45.000000000 +0100 26 | +++ ns-allinone-2.34-ubutnu/ns-2.34/mobile/nakagami.cc 2015-03-04 15:51:09.326820895 +0000 27 | @@ -180,9 +180,9 @@ double Nakagami::Pr(PacketStamp *t, Pack 28 | double resultPower; 29 | 30 | if (int_m == m) { 31 | - resultPower = ErlangRandomVariable::ErlangRandomVariable(Pr/m, int_m).value(); 32 | + resultPower = ErlangRandomVariable(Pr/m, int_m).value(); 33 | } else { 34 | - resultPower = GammaRandomVariable::GammaRandomVariable(m, Pr/m).value(); 35 | + resultPower = GammaRandomVariable(m, Pr/m).value(); 36 | } 37 | return resultPower; 38 | } 39 | diff -rupN ns-allinone-2.34/ns-2.34/tools/ranvar.cc ns-allinone-2.34-ubutnu/ns-2.34/tools/ranvar.cc 40 | --- ns-allinone-2.34/ns-2.34/tools/ranvar.cc 2009-06-14 18:35:44.000000000 +0100 41 | +++ ns-allinone-2.34-ubutnu/ns-2.34/tools/ranvar.cc 2015-03-04 15:50:02.174821565 +0000 42 | @@ -216,7 +216,7 @@ double GammaRandomVariable::value() 43 | // ACM Transactions on mathematical software, Vol. 26, No. 3, Sept. 2000 44 | if (alpha_ < 1) { 45 | double u = rng_->uniform(1.0); 46 | - return GammaRandomVariable::GammaRandomVariable(1.0 + alpha_, beta_).value() * pow (u, 1.0 / alpha_); 47 | + return GammaRandomVariable(1.0 + alpha_, beta_).value() * pow (u, 1.0 / alpha_); 48 | } 49 | 50 | double x, v, u; 51 | diff -rupN ns-allinone-2.34/otcl-1.13/configure ns-allinone-2.34-ubutnu/otcl-1.13/configure 52 | --- ns-allinone-2.34/otcl-1.13/configure 2009-06-14 18:35:49.000000000 +0100 53 | +++ ns-allinone-2.34-ubutnu/otcl-1.13/configure 2015-03-04 16:45:12.590788513 +0000 54 | @@ -6301,7 +6301,7 @@ case $system in 55 | ;; 56 | Linux*) 57 | SHLIB_CFLAGS="-fpic" 58 | - SHLIB_LD="ld -shared" 59 | + SHLIB_LD=”gcc -shared” 60 | SHLIB_SUFFIX=".so" 61 | DL_LIBS="-ldl" 62 | SHLD_FLAGS="" 63 | @@ -7477,7 +7477,8 @@ $debug || 64 | if test -n "$CONFIG_FILES"; then 65 | 66 | 67 | -ac_cr=' ' 68 | +ac_cr=' 69 | +' 70 | ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` 71 | if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then 72 | ac_cs_awk_cr='\\r' 73 | -------------------------------------------------------------------------------- /pfabric.patch: -------------------------------------------------------------------------------- 1 | From cb67dd736e69ae2384b96f790514b3a21ffe6188 Mon Sep 17 00:00:00 2001 2 | From: Mohammad Alizadeh 3 | Date: Sat, 19 Jul 2014 18:53:02 -0700 4 | Subject: [PATCH 1/2] changes in ns-code.zip applied 5 | 6 | --- 7 | classifier/classifier-mpath.cc | 94 ++++- 8 | common/ip.h | 10 + 9 | queue/drop-tail.cc | 164 +++++++- 10 | queue/drop-tail.h | 48 ++- 11 | tcl/lib/ns-default.tcl | 124 +++++- 12 | tcl/lib/ns-node.tcl | 17 +- 13 | tcp/tcp-full.cc | 972 +++++++++++++++++++++++++++++++++------- 14 | tcp/tcp-full.h | 112 +++-- 15 | tcp/tcp-newreno.cc | 12 +- 16 | tcp/tcp-sink.cc | 16 +- 17 | tcp/tcp-sink.h | 2 +- 18 | tcp/tcp.cc | 193 ++++++-- 19 | tcp/tcp.h | 67 ++-- 20 | tools/queue-monitor.cc | 51 ++- 21 | tools/queue-monitor.h | 27 +- 22 | 15 files changed, 1598 insertions(+), 311 deletions(-) 23 | 24 | diff --git a/classifier/classifier-mpath.cc b/classifier/classifier-mpath.cc 25 | index f41e77f..88ea545 100644 26 | --- a/classifier/classifier-mpath.cc 27 | +++ b/classifier/classifier-mpath.cc 28 | @@ -1,4 +1,5 @@ 29 | -/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ 30 | +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t 31 | + -*- */ 32 | 33 | /* 34 | * Copyright (C) 1997 by the University of Southern California 35 | @@ -50,21 +51,106 @@ static const char rcsid[] = 36 | #endif 37 | 38 | #include "classifier.h" 39 | +#include "ip.h" 40 | 41 | class MultiPathForwarder : public Classifier { 42 | public: 43 | - MultiPathForwarder() : ns_(0) {} 44 | - virtual int classify(Packet*) { 45 | - int cl; 46 | + MultiPathForwarder() : ns_(0), nodeid_(0), nodetype_(0), perflow_(0), checkpathid_(0) { 47 | + bind("nodeid_", &nodeid_); 48 | + bind("nodetype_", &nodetype_); 49 | + bind("perflow_", &perflow_); 50 | + bind("checkpathid_", &checkpathid_); 51 | + } 52 | + virtual int classify(Packet* p) { 53 | + int cl; 54 | + hdr_ip* h = hdr_ip::access(p); 55 | + // Mohammad: multipath support 56 | + // fprintf(stdout, "perflow_ = %d, rcv packet in classifier\n", perflow_); 57 | + if (perflow_ || checkpathid_) { 58 | + /*if (h->flowid() >= 10000000) { 59 | + int fail = ns_; 60 | + do { 61 | + cl = ns_++; 62 | + ns_ %= (maxslot_ + 1); 63 | + } while (slot_[cl] == 0 && ns_ != fail); 64 | + return cl; 65 | + }*/ 66 | + 67 | + struct hkey { 68 | + int nodeid; 69 | + nsaddr_t src, dst; 70 | + int fid; 71 | + }; 72 | + struct hkey buf_; 73 | + buf_.nodeid = nodeid_; 74 | + buf_.src = mshift(h->saddr()); 75 | + buf_.dst = mshift(h->daddr()); 76 | + buf_.fid = h->flowid(); 77 | + /*if (checkpathid_) 78 | + buf_.prio = h->prio(); 79 | + else 80 | + buf_.prio = 0;*/ 81 | + char* bufString = (char*) &buf_; 82 | + int length = sizeof(hkey); 83 | + 84 | + unsigned int ms_ = (unsigned int) HashString(bufString, length); 85 | + if (checkpathid_) { 86 | + int pathNum = h->prio(); 87 | + int pathDig; 88 | + for (int i = 0; i < nodetype_; i++) { 89 | + pathDig = pathNum % 8; 90 | + pathNum /= 8; 91 | + } 92 | + //printf("%d: %d->%d\n", nodetype_, h->prio(), pathDig); 93 | + ms_ += h->prio(); //pathDig; 94 | + } 95 | + ms_ %= (maxslot_ + 1); 96 | + //printf("nodeid = %d, pri = %d, ms = %d\n", nodeid_, buf_.prio, ms_); 97 | + int fail = ms_; 98 | + do { 99 | + cl = ms_++; 100 | + ms_ %= (maxslot_ + 1); 101 | + } while (slot_[cl] == 0 && ms_ != fail); 102 | + //printf("nodeid = %d, pri = %d, cl = %d\n", nodeid_, h->prio(), cl); 103 | + } 104 | + 105 | + else { 106 | + //hdr_ip* h = hdr_ip::access(p); 107 | + //if (h->flowid() == 45) { 108 | + //cl = h->prio() % (maxslot_ + 1); 109 | + //} 110 | + //else { 111 | int fail = ns_; 112 | do { 113 | cl = ns_++; 114 | ns_ %= (maxslot_ + 1); 115 | } while (slot_[cl] == 0 && ns_ != fail); 116 | + } 117 | + //} 118 | + 119 | + 120 | return cl; 121 | } 122 | private: 123 | int ns_; 124 | + // Mohamamd: adding support for perflow multipath 125 | + int nodeid_; 126 | + int nodetype_; 127 | + int perflow_; 128 | + int checkpathid_; 129 | + 130 | + static unsigned int 131 | + HashString(register const char *bytes,int length) 132 | + { 133 | + register unsigned int result; 134 | + register int i; 135 | + 136 | + result = 0; 137 | + for (i = 0; i < length; i++) { 138 | + result += (result<<3) + *bytes++; 139 | + } 140 | + return result; 141 | + } 142 | }; 143 | 144 | static class MultiPathClass : public TclClass { 145 | diff --git a/common/ip.h b/common/ip.h 146 | index 8e3f153..13fc354 100644 147 | --- a/common/ip.h 148 | +++ b/common/ip.h 149 | @@ -61,6 +61,14 @@ struct hdr_ip { 150 | ns_addr_t dst_; 151 | int ttl_; 152 | 153 | + /* Mohammad: flag to indicate 154 | + * the last TCP ack for this flow 155 | + * had EcnEcho set. This is used by 156 | + * TBF to determin if flow should be 157 | + *paced. */ 158 | + int gotecnecho; 159 | + //abd 160 | + 161 | /* Monarch extn */ 162 | // u_int16_t sport_; 163 | // u_int16_t dport_; 164 | @@ -68,6 +76,7 @@ struct hdr_ip { 165 | /* IPv6 */ 166 | int fid_; /* flow id */ 167 | int prio_; 168 | + int prio_type_; //Shuang 169 | 170 | static int offset_; 171 | inline static int& offset() { return offset_; } 172 | @@ -87,6 +96,7 @@ struct hdr_ip { 173 | /* ipv6 fields */ 174 | int& flowid() { return (fid_); } 175 | int& prio() { return (prio_); } 176 | + int& prio_type() {return (prio_type_); } 177 | }; 178 | 179 | #endif 180 | diff --git a/queue/drop-tail.cc b/queue/drop-tail.cc 181 | index d1a3ed6..4e5b9ac 100644 182 | --- a/queue/drop-tail.cc 183 | +++ b/queue/drop-tail.cc 184 | @@ -87,7 +87,7 @@ void DropTail::enque(Packet* p) 185 | if (summarystats) { 186 | Queue::updateStats(qib_?q_->byteLength():q_->length()); 187 | } 188 | - 189 | + //printf("qlim_ = %d, qib_ = %d, mean_pktsize_ = %d\n", qlim_, qib_, mean_pktsize_); 190 | int qlimBytes = qlim_ * mean_pktsize_; 191 | if ((!qib_ && (q_->length() + 1) >= qlim_) || 192 | (qib_ && (q_->byteLength() + hdr_cmn::access(p)->size()) >= qlimBytes)){ 193 | @@ -96,6 +96,77 @@ void DropTail::enque(Packet* p) 194 | q_->enque(p); 195 | Packet *pp = q_->deque(); 196 | drop(pp); 197 | + } 198 | + else if (drop_prio_) { 199 | + Packet *max_pp = p; 200 | + int max_prio = 0; 201 | + 202 | + q_->enque(p); 203 | + q_->resetIterator(); 204 | + for (Packet *pp = q_->getNext(); pp != 0; pp = q_->getNext()) { 205 | + if (!qib_ || ( q_->byteLength() - hdr_cmn::access(pp)->size() < qlimBytes)) { 206 | + hdr_ip* h = hdr_ip::access(pp); 207 | + int prio = h->prio(); 208 | + if (prio >= max_prio) { 209 | + max_pp = pp; 210 | + max_prio = prio; 211 | + } 212 | + } 213 | + } 214 | + q_->remove(max_pp); 215 | + drop(max_pp); 216 | + } 217 | + else if (drop_smart_) { 218 | + Packet *max_pp = p; 219 | + int max_count = 0; 220 | + 221 | + q_->enque(p); 222 | + q_->resetIterator(); 223 | + for (Packet *pp = q_->getNext(); pp != 0; pp = q_->getNext()) { 224 | + hdr_ip* h = hdr_ip::access(pp); 225 | + FlowKey fkey; 226 | + fkey.src = h->saddr(); 227 | + fkey.dst = h->daddr(); 228 | + fkey.fid = h->flowid(); 229 | + 230 | + char* fkey_buf = (char*) &fkey; 231 | + int length = sizeof(fkey); 232 | + string fkey_string(fkey_buf, length); 233 | + 234 | + std::tr1::hash string_hasher; 235 | + size_t signature = string_hasher(fkey_string); 236 | + 237 | + if (sq_counts_.find(signature) != sq_counts_.end()) { 238 | + int count = sq_counts_[signature]; 239 | + if (count > max_count) { 240 | + max_count = count; 241 | + max_pp = pp; 242 | + } 243 | + } 244 | + } 245 | + q_->remove(max_pp); 246 | + /*hdr_ip* h = hdr_ip::access(p); 247 | + FlowKey fkey; 248 | + fkey.src = h->saddr(); 249 | + fkey.dst = h->daddr(); 250 | + fkey.fid = h->flowid(); 251 | + 252 | + char* fkey_buf = (char*) &fkey; 253 | + int length = sizeof(fkey); 254 | + string fkey_string(fkey_buf, length); 255 | + 256 | + std::tr1::hash string_hasher; 257 | + size_t p_sig = string_hasher(fkey_string); 258 | + h = hdr_ip::access(max_pp); 259 | + fkey.src = h->saddr(); 260 | + fkey.dst = h->daddr(); 261 | + fkey.fid = h->flowid(); 262 | + 263 | + string fkey_string2(fkey_buf, length); 264 | + size_t maxpp_sig = string_hasher(fkey_string2); 265 | + 266 | + printf("%s, enqueued %d, dropped %d instead\n", this->name(), p_sig, maxpp_sig);*/ 267 | + drop(max_pp); 268 | } else { 269 | drop(p); 270 | } 271 | @@ -130,7 +201,96 @@ Packet* DropTail::deque() 272 | if (summarystats && &Scheduler::instance() != NULL) { 273 | Queue::updateStats(qib_?q_->byteLength():q_->length()); 274 | } 275 | - return q_->deque(); 276 | + //printf("drop_smart_ = %d, sq_limit = %d \n", drop_smart_, sq_limit_); 277 | + 278 | + /*Shuang: deque the packet with the highest priority */ 279 | + if (deque_prio_) { 280 | + q_->resetIterator(); 281 | + Packet *p = q_->getNext(); 282 | + int highest_prio_; 283 | + if (p != 0) 284 | + highest_prio_ = hdr_ip::access(p)->prio(); 285 | + else 286 | + return 0; 287 | + for (Packet *pp = q_->getNext(); pp != 0; pp = q_->getNext()) { 288 | + hdr_ip* h = hdr_ip::access(pp); 289 | + int prio = h->prio(); 290 | + //deque from the head 291 | + if (prio < highest_prio_) { 292 | + p = pp; 293 | + highest_prio_ = prio; 294 | + } 295 | + } 296 | + if (keep_order_) { 297 | + q_->resetIterator(); 298 | + hdr_ip* hp = hdr_ip::access(p); 299 | + for (Packet *pp = q_->getNext(); pp != p; pp = q_->getNext()) { 300 | + hdr_ip* h = hdr_ip::access(pp); 301 | + if (h->saddr() == hp->saddr() 302 | + && h->daddr() == hp->daddr() 303 | + && h->flowid() == hp->flowid()) { 304 | + p = pp; 305 | + break; 306 | + } 307 | + } 308 | + } 309 | + 310 | + //if (hdr_ip::access(p)->flowid() == 1) { 311 | + // q_->resetIterator(); 312 | + // printf("DEQUE: flow %d queue_length %d\n", hdr_ip::access(p)->flowid(), q_->byteLength()); 313 | + // for (Packet *pp = q_->getNext(); pp != 0; pp = q_->getNext()) { 314 | + // hdr_ip* h = hdr_ip::access(pp); 315 | + // printf("( %d %d )", h->flowid(), h->prio()); 316 | + // } 317 | + // printf("\n"); 318 | + // fflush(stdout); 319 | + //} 320 | + 321 | + q_->remove(p); 322 | + return p; 323 | + } else 324 | + if (drop_smart_) { 325 | + Packet *p = q_->deque(); 326 | + if (p) { 327 | + hdr_ip* h = hdr_ip::access(p); 328 | + FlowKey fkey; 329 | + fkey.src = h->saddr(); 330 | + fkey.dst = h->daddr(); 331 | + fkey.fid = h->flowid(); 332 | + 333 | + char* fkey_buf = (char*) &fkey; 334 | + int length = sizeof(fkey); 335 | + string fkey_string(fkey_buf, length); 336 | + 337 | + std::tr1::hash string_hasher; 338 | + size_t signature = string_hasher(fkey_string); 339 | + sq_queue_.push(signature); 340 | + 341 | + if (sq_counts_.find(signature) != sq_counts_.end()) { 342 | + sq_counts_[signature]++; 343 | + //printf("%s packet with signature %d, count = %d, qsize = %d\n", this->name(), signature, sq_counts_[signature], sq_queue_.size()); 344 | + } 345 | + else { 346 | + sq_counts_[signature] = 1; 347 | + //printf("%s first packet with signature %d, count = %d, qsize = %d\n", this->name(), signature, sq_counts_[signature], sq_queue_.size()); 348 | + } 349 | + 350 | + if (sq_queue_.size() > sq_limit_) { 351 | + //printf("%s we are full %d %d\n", this->name(), sq_counts_.size(), sq_queue_.size()); 352 | + size_t temp = sq_queue_.front(); sq_queue_.pop(); 353 | + sq_counts_[temp]--; 354 | + if (sq_counts_[temp] == 0) 355 | + sq_counts_.erase(temp); 356 | + 357 | + //printf("%s removed front sig = %d, no longer full %d %d\n", this->name(), temp, sq_counts_.size(), sq_queue_.size()); 358 | + 359 | + } 360 | + } 361 | + return p; 362 | + 363 | + } else { 364 | + return q_->deque(); 365 | + } 366 | } 367 | 368 | void DropTail::print_summarystats() 369 | diff --git a/queue/drop-tail.h b/queue/drop-tail.h 370 | index a16399e..b82f7e5 100644 371 | --- a/queue/drop-tail.h 372 | +++ b/queue/drop-tail.h 373 | @@ -37,10 +37,35 @@ 374 | #ifndef ns_drop_tail_h 375 | #define ns_drop_tail_h 376 | 377 | -#include 378 | +/*#ifdef __GNUC__ 379 | +#include 380 | +#else 381 | +#include 382 | +#endif 383 | + 384 | + 385 | +namespace std 386 | +{ 387 | + using namespace __gnu_cxx; 388 | +} 389 | +*/ 390 | +#include 391 | +#include 392 | +#include 393 | + 394 | +using std::queue; 395 | +using std::tr1::unordered_map; 396 | +//using std::tr1::functional; 397 | + 398 | +#include 399 | #include "queue.h" 400 | #include "config.h" 401 | 402 | +typedef struct flowkey { 403 | + nsaddr_t src, dst; 404 | + int fid; 405 | +} FlowKey; 406 | + 407 | /* 408 | * A bounded, drop-tail queue 409 | */ 410 | @@ -50,27 +75,44 @@ class DropTail : public Queue { 411 | q_ = new PacketQueue; 412 | pq_ = q_; 413 | bind_bool("drop_front_", &drop_front_); 414 | + bind_bool("drop_smart_", &drop_smart_); 415 | + bind_bool("drop_prio_", &drop_prio_); 416 | + bind_bool("deque_prio_", &deque_prio_); 417 | + bind_bool("keep_order_", &keep_order_); 418 | bind_bool("summarystats_", &summarystats); 419 | bind_bool("queue_in_bytes_", &qib_); // boolean: q in bytes? 420 | bind("mean_pktsize_", &mean_pktsize_); 421 | + bind("sq_limit_", &sq_limit_); 422 | // _RENAMED("drop-front_", "drop_front_"); 423 | } 424 | ~DropTail() { 425 | delete q_; 426 | } 427 | - protected: 428 | void reset(); 429 | int command(int argc, const char*const* argv); 430 | void enque(Packet*); 431 | Packet* deque(); 432 | + protected: 433 | void shrink_queue(); // To shrink queue and drop excessive packets. 434 | 435 | PacketQueue *q_; /* underlying FIFO queue */ 436 | - int drop_front_; /* drop-from-front (rather than from tail) */ 437 | + int drop_front_; /* drop-from-front (rather than from tail) */ 438 | int summarystats; 439 | void print_summarystats(); 440 | int qib_; /* bool: queue measured in bytes? */ 441 | int mean_pktsize_; /* configured mean packet size in bytes */ 442 | + // Mohammad: for smart dropping 443 | + int drop_smart_; 444 | + // Shuang: for priority dropping 445 | + int drop_prio_; 446 | + int deque_prio_; 447 | + int keep_order_; 448 | + 449 | + 450 | + unsigned int sq_limit_; 451 | + unordered_map sq_counts_; 452 | + std::queue sq_queue_; 453 | + 454 | }; 455 | 456 | #endif 457 | diff --git a/tcl/lib/ns-default.tcl b/tcl/lib/ns-default.tcl 458 | index 4e4e2f7..c907f04 100644 459 | --- a/tcl/lib/ns-default.tcl 460 | +++ b/tcl/lib/ns-default.tcl 461 | @@ -103,9 +103,17 @@ Queue/DropTail set drop_front_ false 462 | Queue/DropTail set summarystats_ false 463 | Queue/DropTail set queue_in_bytes_ false 464 | Queue/DropTail set mean_pktsize_ 500 465 | +# Mohammad: Smart drop 466 | +Queue/DropTail set drop_smart_ false 467 | +Queue/DropTail set sq_limit_ 10 468 | 469 | Queue/DropTail/PriQueue set Prefer_Routing_Protocols 1 470 | 471 | +# Shuang: Priority drop 472 | +Queue/DropTail set drop_prio_ false 473 | +Queue/DropTail set deque_prio_ false 474 | +Queue/DropTail set keep_order_ false 475 | + 476 | # special cmu implemented priority queue used by DSR 477 | CMUPriQueue set qlen_logthresh_ 10 478 | CMUPriQueue set fw_logthresh_ 25 479 | @@ -119,6 +127,24 @@ Queue/dsRED set ecn_ 0 480 | # support only xcp flows; set to 1 when supporting both tcp and xcp flows; temporary fix for allocating link BW between xcp and tcp queues until dynamic queue weights come into effect. This fix should then go away 481 | Queue/XCP set tcp_xcp_on_ 0 ; 482 | 483 | +# Drop Tail Variant 484 | +# Queue/DropTailVariant set drop_front_ false 485 | +# Queue/DropTailVariant set summarystats_ false 486 | +# Queue/DropTailVariant set queue_in_bytes_ false 487 | +# Queue/DropTailVariant set mean_pktsize_ 500 488 | +# Queue/DropTailVariant set tcp_queue_limit_pkts_ 1000 489 | + 490 | +# Queue/DropTailVariant/RCP set alpha_ 0.4 491 | +# Queue/DropTailVariant/RCP set beta_ 0.4 492 | +# Queue/DropTailVariant/RCP set gamma_ 1 493 | +# Queue/DropTailVariant/RCP set min_pprtt_ 0.01 494 | +# Queue/DropTailVariant/RCP set init_rate_fact_ 0.05 495 | +# Queue/DropTailVariant/RCP set print_status_ 1 496 | +# Queue/DropTailVariant/RCP set rate_fact_mode_ 0 497 | +# Queue/DropTailVariant/RCP set fixed_rate_fact_ 0.05 ;# effecitve only if rate_fact_mode = 1 498 | +# Queue/DropTailVariant/RCP set propag_rtt_ 1.0 ;# effecitve only if rate_fact_mode = 3 499 | +# Queue/DropTailVariant/RCP set upd_timeslot_ 0.01 ;# rate update interval (sec). 500 | + 501 | Queue/RED set bytes_ true ; # default changed on 10/11/2004. 502 | Queue/RED set queue_in_bytes_ true ; # default changed on 10/11/2004. 503 | # Queue/RED set thresh_ 5 504 | @@ -168,6 +194,15 @@ Queue/RED set bottom_ 0 505 | ### for automatic configuration. 506 | Queue/RED set cautious_ 0 507 | Queue/RED set feng_adaptive_ 0 508 | +# Mohammad: Phantom Queue extensions 509 | +Queue/RED set pq_enable_ 0 510 | +Queue/RED set pq_mode_ 0 511 | +Queue/RED set pq_drainrate_ 0 ; # need to set this when PQ is enabled 512 | + # always in bps 513 | +Queue/RED set pq_thresh_ 0 514 | +# Shuang: priority dropping/deque extensions 515 | +Queue/RED set drop_prio_ 0 516 | +Queue/RED set deque_prio_ 0 517 | 518 | Queue/RED/RIO set bytes_ false 519 | Queue/RED/RIO set queue_in_bytes_ false 520 | @@ -235,6 +270,9 @@ Queue/Vq set mean_pktsize_ 1000 521 | Queue/Vq set curq_ 0 522 | Queue/Vq set drop_front_ 0 523 | Queue/Vq set markfront_ 0 524 | +# Mohammad 525 | +Queue/Vq set ctilde_ 0 526 | +Queue/Vq set vq_len_ 0 527 | 528 | Queue/REM set gamma_ 0.001 529 | Queue/REM set phi_ 1.001 530 | @@ -298,6 +336,20 @@ QueueMonitor set pdrops_ 0 531 | QueueMonitor set pmarks_ 0 532 | QueueMonitor set bdrops_ 0 533 | 534 | +#added for count dropping from small flow - Shuang 535 | +QueueMonitor set num_monitor_ 50 536 | +for {set k 0} {$k < 50} {incr k} { 537 | + set tmp kdrops$k 538 | + QueueMonitor set $tmp 0 539 | + set tmp karrivals$k 540 | + QueueMonitor set $tmp 0 541 | +} 542 | + 543 | +QueueMonitor set ack_arrivals_ 0 544 | +QueueMonitor set ack_drops_ 0 545 | +QueueMonitor set ack_departures_ 0 546 | + 547 | + 548 | QueueMonitor set qs_pkts_ 0 549 | QueueMonitor set qs_bytes_ 0 550 | QueueMonitor set qs_drops_ 0 551 | @@ -360,8 +412,7 @@ DelayLink set bandwidth_ 1.5Mb 552 | DelayLink set delay_ 100ms 553 | DelayLink set debug_ false 554 | DelayLink set avoidReordering_ false ; # Added 3/27/2003. 555 | - # Set to true to avoid reordering when 556 | - # changing link bandwidth or delay. 557 | + # Set to true to avoid reordering when 558 | DynamicLink set status_ 1 559 | DynamicLink set debug_ false 560 | 561 | @@ -389,6 +440,11 @@ Classifier/Addr/MPLS set reroute_option_ 0 562 | Classifier/Addr/MPLS set control_driven_ 0 563 | Classifier/Addr/MPLS set data_driven_ 0 564 | 565 | +# Mohammad 566 | +Classifier/MultiPath set nodeid_ 0 567 | +Classifier/MultiPath set nodetype_ 0 568 | +Classifier/MultiPath set perflow_ 0 569 | +Classifier/MultiPath set checkpathid_ 0 570 | # 571 | # FEC models 572 | # 573 | @@ -634,7 +690,16 @@ NetworkInterface set debug_ false 574 | TBF set rate_ 64k 575 | TBF set bucket_ 1024 576 | TBF set qlen_ 0 577 | - 578 | +# Mohammad: Pacer variables 579 | +TBF set pacer_enable_ 0 580 | +TBF set assoc_timeout_ 0.01 581 | +TBF set assoc_prob_ 0.125 582 | +TBF set maxrate_ 1000000000 583 | +TBF set minrate_ 10000000 584 | +TBF set qlength_factor_ 122; 585 | +TBF set rate_ave_factor_ 0.125 586 | +TBF set rate_update_interval_ 0.000064 587 | +TBF set debug_ 0 588 | # 589 | # mobile Ip 590 | # 591 | @@ -1022,6 +1087,18 @@ Agent/TCP set control_increase_ 0 592 | 593 | Agent/TCP set SetCWRonRetransmit_ true ; # added on 2005/06/19. 594 | # default changed on 2008/06/05. 595 | +# Mohammad 596 | +Agent/TCP set ecnhat_ false; 597 | +Agent/TCP set ecnhat_smooth_alpha_ true; 598 | +Agent/TCP set ecnhat_alpha_ 0.0; 599 | +Agent/TCP set ecnhat_g_ 0.125; 600 | +Agent/TCP set ecnhat_enable_beta_ false; 601 | +Agent/TCP set ecnhat_beta_ 0.0; 602 | +Agent/TCP set ecnhat_quadratic_beta_ false; 603 | +Agent/TCP set ecnhat_tcp_friendly_ false; 604 | +Agent/TCP set perPacketMP_ false; 605 | +Agent/TCP set pathAwareMP_ false; 606 | +Agent/TCP set num_paths_ 1 607 | 608 | # XXX Generate nam trace or plain old text trace for variables. 609 | # When it's true, generate nam trace. 610 | @@ -1057,6 +1134,7 @@ Agent/TCPSink set qs_enabled_ false 611 | Agent/TCPSink set RFC2581_immediate_ack_ true 612 | Agent/TCPSink set bytes_ 0 613 | Agent/TCPSink set ecn_syn_ false ; # Added 2005/11/21 for SYN/ACK pkts. 614 | +Agent/TCPSink set ecnhat_ false; 615 | 616 | Agent/TCPSink/DelAck set interval_ 100ms 617 | catch { 618 | @@ -1229,6 +1307,20 @@ if [TclObject is-class Agent/TCP/FullTcp] { 619 | Agent/TCP/FullTcp set ecn_syn_ false; # Make SYN/ACK packet ECN-Capable? 620 | Agent/TCP/FullTcp set ecn_syn_wait_ 0; # Wait after marked SYN/ACK? 621 | Agent/TCP/FullTcp set debug_ false; # Added Sept. 16, 2007. 622 | + Agent/TCP/FullTcp set flow_remaining_ -1; #Mohammad: added for robust FCT measurement 623 | + Agent/TCP/FullTcp set dynamic_dupack_ 0; # Mohammad: if non-zero, set dupack threshold to max(3, dynamic_dupack_ * cwnd_) 624 | + Agent/TCP/FullTcp set prio_scheme_ 2; #Shuang: priority scheme 625 | + Agent/TCP/FullTcp set prio_num_ 0; #Shuang: number of priority 626 | + Agent/TCP/FullTcp set prio_cap0 6*1460+15; 627 | + Agent/TCP/FullTcp set prio_cap1 16*1460+15; 628 | + Agent/TCP/FullTcp set prio_cap2 30*1460+15; 629 | + Agent/TCP/FullTcp set prio_cap3 49*1460+15; 630 | + Agent/TCP/FullTcp set prio_cap4 266*1460+15; 631 | + Agent/TCP/FullTcp set prio_cap5 1001*1460+15; 632 | + Agent/TCP/FullTcp set prio_cap6 2825*1460+15; 633 | + Agent/TCP/FullTcp set prob_cap_ 0; #Shuang: prob mode 634 | + Agent/TCP/FullTcp set deadline 0; #Shuang: deadline 635 | + Agent/TCP/FullTcp set early_terminated_ 0; #Shuang 636 | 637 | Agent/TCP/FullTcp/Newreno set recov_maxburst_ 2; # max burst dur recov 638 | 639 | @@ -1259,6 +1351,14 @@ if [TclObject is-class Agent/TCP/FullTcp] { 640 | set open_cwnd_on_pack_ false 641 | } 642 | 643 | + Agent/TCP/FullTcp/Sack/MinTCP instproc init {} { 644 | + $self next 645 | + } 646 | + 647 | + Agent/TCP/FullTcp/Sack/DDTCP instproc init {} { 648 | + $self next 649 | + } 650 | + 651 | } 652 | 653 | if [TclObject is-class Agent/TCP/BayFullTcp] { 654 | @@ -1451,6 +1551,24 @@ Queue set util_records_ 5 ; # Changed from 0 to 5, 2/25/05. 655 | 656 | Delayer set debug_ false 657 | 658 | +# # Nandita: Following is for Video traffic. Taken from Xiaoqing Zhu 659 | +# Application/Traffic/VideoCBR set rate_ 0 660 | +# Application/Traffic/VideoCBR set pktsize_ 1500 661 | +# Application/Traffic/VideoCBR set fps_ 30 662 | +# Application/Traffic/VideoCBR set gop_ 15 663 | +# Application/Traffic/VideoCBR set fix_interval_ 0 664 | +# Application/Traffic/VideoCBR set init_delay_ 0.5 665 | +# Application/Traffic/VideoCBR set debug_ 0 666 | +# Application/Traffic/VideoCBR set random_ 0 667 | + 668 | +# Application/Traffic/VideoTrace set init_delay_ 0.5 669 | +# Application/Traffic/VideoTrace set quality_ 0 670 | +# Application/Traffic/VideoTrace set fps_ 30 671 | +# Application/Traffic/VideoTrace set advance_per_gop_ 1 672 | +# Application/Traffic/VideoTrace set debug_ 0 673 | +# Application/Traffic/VideoTrace set random_ 0 674 | +# Application/Traffic/VideoTrace set loop_ 0 675 | + 676 | Agent/TCP/Linux set rtxcur_init_ 3 677 | Agent/TCP/Linux set maxrto_ 120 678 | Agent/TCP/Linux set minrto_ 0.2 679 | diff --git a/tcl/lib/ns-node.tcl b/tcl/lib/ns-node.tcl 680 | index 045b45d..18b5163 100644 681 | --- a/tcl/lib/ns-node.tcl 682 | +++ b/tcl/lib/ns-node.tcl 683 | @@ -88,9 +88,9 @@ Node instproc init args { 684 | set nodetype_ [$ns_ get-nodetype] 685 | 686 | $self mk-default-classifier 687 | - 688 | # XXX Eventually these two should also be converted to modules 689 | set multiPath_ [$class set multiPath_] 690 | + 691 | } 692 | 693 | # XXX This instproc is backward compatibility; when satellite node, mobile 694 | @@ -350,8 +350,21 @@ Node instproc add-routes {id ifs} { 695 | # 1. get new MultiPathClassifier, 696 | # 2. migrate existing routes to that mclassifier 697 | # 3. install the mclassifier in the node classifier_ 698 | - # 699 | + # 700 | set mpathClsfr_($id) [new Classifier/MultiPath] 701 | + $mpathClsfr_($id) set nodeid_ [$self id] 702 | + set nodecolor_ [$self get-attribute "COLOR"] 703 | + set nodetype_ 0 704 | + if {$nodecolor_ == "green"} { 705 | + set nodetype_ 1 706 | + } 707 | + if {$nodecolor_ == "blue"} { 708 | + set nodetype_ 2 709 | + } 710 | + if {$nodecolor_ == "red"} { 711 | + set nodetype_ 3 712 | + } 713 | + $mpathClsfr_($id) set nodetype_ $nodetype_ 714 | if {$routes_($id) > 0} { 715 | assert "$routes_($id) == 1" 716 | $mpathClsfr_($id) installNext \ 717 | diff --git a/tcp/tcp-full.cc b/tcp/tcp-full.cc 718 | index f2cd360..b8b7fd7 100644 719 | --- a/tcp/tcp-full.cc 720 | +++ b/tcp/tcp-full.cc 721 | @@ -1,75 +1,4 @@ 722 | -/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ 723 | - 724 | -/* 725 | - * Copyright (c) Intel Corporation 2001. All rights reserved. 726 | - * 727 | - * Licensed under the Apache License, Version 2.0 (the "License"); 728 | - * you may not use this file except in compliance with the License. 729 | - * You may obtain a copy of the License at 730 | - * http://www.apache.org/licenses/LICENSE-2.0 731 | - * 732 | - * Unless required by applicable law or agreed to in writing, software 733 | - * distributed under the License is distributed on an "AS IS" BASIS, 734 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 735 | - * See the License for the specific language governing permissions and 736 | - * limitations under the License. 737 | - */ 738 | - 739 | -/* 740 | - * Copyright (c) 1997, 1998 The Regents of the University of California. 741 | - * All rights reserved. 742 | - * 743 | - * Redistribution and use in source and binary forms, with or without 744 | - * modification, are permitted provided that the following conditions 745 | - * are met: 746 | - * 1. Redistributions of source code must retain the above copyright 747 | - * notice, this list of conditions and the following disclaimer. 748 | - * 2. Redistributions in binary form must reproduce the above copyright 749 | - * notice, this list of conditions and the following disclaimer in the 750 | - * documentation and/or other materials provided with the distribution. 751 | - * 3. All advertising materials mentioning features or use of this software 752 | - * must display the following acknowledgement: 753 | - * This product includes software developed by the Network Research 754 | - * Group at Lawrence Berkeley National Laboratory. 755 | - * 4. Neither the name of the University nor of the Laboratory may be used 756 | - * to endorse or promote products derived from this software without 757 | - * specific prior written permission. 758 | - * 759 | - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 760 | - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 761 | - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 762 | - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 763 | - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 764 | - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 765 | - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 766 | - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 767 | - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 768 | - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 769 | - * SUCH DAMAGE. 770 | - */ 771 | - 772 | -/* 773 | - * 774 | - * Full-TCP : A two-way TCP very similar to the 4.4BSD version of Reno TCP. 775 | - * This version also includes variants Tahoe, NewReno, and SACK. 776 | - * 777 | - * This code below has received a fairly major restructuring (Aug. 2001). 778 | - * The ReassemblyQueue structure is now removed to a separate module and 779 | - * entirely re-written. 780 | - * Also, the SACK functionality has been re-written (almost) entirely. 781 | - * -KF [kfall@intel.com] 782 | - * 783 | - * This code below was motivated in part by code contributed by 784 | - * Kathie Nichols (nichols@baynetworks.com). The code below is based primarily 785 | - * on the 4.4BSD TCP implementation. -KF [kfall@ee.lbl.gov] 786 | - * 787 | - * Kathie Nichols and Van Jacobson have contributed significant bug fixes, 788 | - * especially with respect to the the handling of sequence numbers during 789 | - * connection establishment/clearin. Additional fixes have followed 790 | - * theirs. 791 | - * 792 | - * Fixes for gensack() and ReassemblyQueue::add() contributed by Richard 793 | - * Mortier 794 | + /* Mortier 795 | * 796 | * Some warnings and comments: 797 | * this version of TCP will not work correctly if the sequence number 798 | @@ -117,6 +46,7 @@ static const char rcsid[] = 799 | #include "flags.h" 800 | #include "random.h" 801 | #include "template.h" 802 | +#include "math.h" 803 | 804 | #ifndef TRUE 805 | #define TRUE 1 806 | @@ -171,6 +101,22 @@ public: 807 | } 808 | } class_sack_full; 809 | 810 | +static class MinTcpClass : public TclClass { 811 | +public: 812 | + MinTcpClass() : TclClass("Agent/TCP/FullTcp/Sack/MinTCP") {} 813 | + TclObject* create(int, const char*const*) { 814 | + return (new MinTcpAgent()); 815 | + } 816 | +} class_min_full; 817 | + 818 | +static class DDTcpClass : public TclClass { 819 | +public: 820 | + DDTcpClass() : TclClass("Agent/TCP/FullTcp/Sack/DDTCP") {} 821 | + TclObject* create(int, const char*const*) { 822 | + return (new DDTcpAgent()); 823 | + } 824 | +} class_dd_full; 825 | + 826 | /* 827 | * Delayed-binding variable linkage 828 | */ 829 | @@ -199,6 +145,21 @@ FullTcpAgent::delay_bind_init_all() 830 | delay_bind_init_one("ecn_syn_wait_"); 831 | delay_bind_init_one("debug_"); 832 | delay_bind_init_one("spa_thresh_"); 833 | + 834 | + delay_bind_init_one("flow_remaining_"); //Mohammad 835 | + delay_bind_init_one("dynamic_dupack_"); 836 | + 837 | + delay_bind_init_one("prio_scheme_"); // Shuang 838 | + delay_bind_init_one("prio_num_"); //Shuang 839 | + delay_bind_init_one("prio_cap0"); //Shuang 840 | + delay_bind_init_one("prio_cap1"); //Shuang 841 | + delay_bind_init_one("prio_cap2"); //Shuang 842 | + delay_bind_init_one("prio_cap3"); //Shuang 843 | + delay_bind_init_one("prio_cap4"); //Shuang 844 | + delay_bind_init_one("prio_cap5"); //Shuang 845 | + delay_bind_init_one("prio_cap6"); //Shuang 846 | + delay_bind_init_one("deadline"); //Shuang 847 | + delay_bind_init_one("early_terminated_"); //Shuang 848 | 849 | TcpAgent::delay_bind_init_all(); 850 | 851 | @@ -229,7 +190,20 @@ FullTcpAgent::delay_bind_dispatch(const char *varName, const char *localName, Tc 852 | if (delay_bind_bool(varName, localName, "ecn_syn_", &ecn_syn_, tracer)) return TCL_OK; 853 | if (delay_bind(varName, localName, "ecn_syn_wait_", &ecn_syn_wait_, tracer)) return TCL_OK; 854 | if (delay_bind_bool(varName, localName, "debug_", &debug_, tracer)) return TCL_OK; 855 | - 856 | + if (delay_bind(varName, localName, "flow_remaining_", &flow_remaining_, tracer)) return TCL_OK; // Mohammad 857 | + if (delay_bind(varName, localName, "dynamic_dupack_", &dynamic_dupack_, tracer)) return TCL_OK; // Mohammad 858 | + if (delay_bind(varName, localName, "prio_scheme_", &prio_scheme_, tracer)) return TCL_OK; // Shuang 859 | + if (delay_bind(varName, localName, "prio_num_", &prio_num_, tracer)) return TCL_OK; //Shuang 860 | + if (delay_bind(varName, localName, "prio_cap0", &prio_cap_[0], tracer)) return TCL_OK; 861 | + if (delay_bind(varName, localName, "prio_cap1", &prio_cap_[1], tracer)) return TCL_OK; 862 | + if (delay_bind(varName, localName, "prio_cap2", &prio_cap_[2], tracer)) return TCL_OK; 863 | + if (delay_bind(varName, localName, "prio_cap3", &prio_cap_[3], tracer)) return TCL_OK; 864 | + if (delay_bind(varName, localName, "prio_cap4", &prio_cap_[4], tracer)) return TCL_OK; 865 | + if (delay_bind(varName, localName, "prio_cap5", &prio_cap_[5], tracer)) return TCL_OK; 866 | + if (delay_bind(varName, localName, "prio_cap6", &prio_cap_[6], tracer)) return TCL_OK; 867 | + if (delay_bind(varName, localName, "prob_cap_", &prob_cap_, tracer)) return TCL_OK; //Shuang 868 | + if (delay_bind(varName, localName, "deadline", &deadline, tracer)) return TCL_OK; //Shuang 869 | + if (delay_bind(varName, localName, "early_terminated_", &early_terminated_, tracer)) return TCL_OK; //Shuang 870 | return TcpAgent::delay_bind_dispatch(varName, localName, tracer); 871 | } 872 | 873 | @@ -297,6 +271,11 @@ FullTcpAgent::command(int argc, const char*const* argv) 874 | advance_bytes(atoi(argv[2])); 875 | return (TCL_OK); 876 | } 877 | + //Mohammad 878 | + if (strcmp(argv[1], "get-flow") == 0) { 879 | + flow_remaining_ = atoi(argv[2]); 880 | + return(TCL_OK); 881 | + } 882 | } 883 | if (argc == 4) { 884 | if (strcmp(argv[1], "sendmsg") == 0) { 885 | @@ -330,10 +309,11 @@ FullTcpAgent::command(int argc, const char*const* argv) 886 | void 887 | FullTcpAgent::advanceby(int np) 888 | { 889 | - // XXX hack: 890 | + 891 | + 892 | +// XXX hack: 893 | // because np is in packets and a data source 894 | // may pass a *huge* number as a way to tell us 895 | - // to go forever, just look for the huge number 896 | // and if it's there, pre-divide it 897 | if (np >= 0x10000000) 898 | np /= maxseg_; 899 | @@ -350,6 +330,10 @@ void 900 | FullTcpAgent::advance_bytes(int nb) 901 | { 902 | 903 | +////Shuang: hardcode 904 | + cwnd_ = initial_window(); 905 | +// //ssthresh_ = cwnd_; 906 | + 907 | // 908 | // state-specific operations: 909 | // if CLOSED or LISTEN, reset and try a new active open/connect 910 | @@ -357,21 +341,26 @@ FullTcpAgent::advance_bytes(int nb) 911 | // if SYN_SENT or SYN_RCVD, just queue 912 | // if above ESTABLISHED, we are closing, so don't allow 913 | // 914 | - 915 | - switch (state_) { 916 | + start_time = now(); 917 | + early_terminated_ = 0; 918 | + switch (state_) { 919 | 920 | case TCPS_CLOSED: 921 | case TCPS_LISTEN: 922 | reset(); 923 | + startseq_ = iss_; 924 | curseq_ = iss_ + nb; 925 | - connect(); // initiate new connection 926 | + seq_bound_ = -1; 927 | + connect(); // initiate new connection 928 | break; 929 | 930 | case TCPS_ESTABLISHED: 931 | case TCPS_SYN_SENT: 932 | case TCPS_SYN_RECEIVED: 933 | if (curseq_ < iss_) 934 | - curseq_ = iss_; 935 | + curseq_ = iss_; 936 | + startseq_ = curseq_; 937 | + seq_bound_ = -1; 938 | curseq_ += nb; 939 | break; 940 | 941 | @@ -400,11 +389,15 @@ FullTcpAgent::advance_bytes(int nb) 942 | void 943 | FullTcpAgent::sendmsg(int nbytes, const char *flags) 944 | { 945 | - if (flags && strcmp(flags, "MSG_EOF") == 0) 946 | + if (flags && strcmp(flags, "MSG_EOF") == 0){ 947 | close_on_empty_ = TRUE; 948 | - if (flags && strcmp(flags, "DAT_EOF") == 0) 949 | - signal_on_empty_ = TRUE; 950 | +printf("setting 2 closeonempty to true for fid= %d\n",fid_); 951 | + } 952 | 953 | + if (flags && strcmp(flags, "DAT_EOF") == 0){ 954 | + signal_on_empty_ = TRUE; 955 | + printf("setting signalonempty to true for fid= %d\n",fid_); 956 | + } 957 | if (nbytes == -1) { 958 | infinite_send_ = TRUE; 959 | advance_bytes(0); 960 | @@ -446,6 +439,7 @@ void 961 | FullTcpAgent::bufferempty() 962 | { 963 | signal_on_empty_=FALSE; 964 | + //printf("flow fid= %d is done\n",fid_); 965 | Tcl::instance().evalf("%s done_data", this->name()); 966 | } 967 | 968 | @@ -459,7 +453,6 @@ FullTcpAgent::usrclosed() 969 | { 970 | curseq_ = maxseq_ - 1; // now, no more data 971 | infinite_send_ = FALSE; // stop infinite send 972 | - 973 | switch (state_) { 974 | case TCPS_CLOSED: 975 | case TCPS_LISTEN: 976 | @@ -610,9 +603,9 @@ FullTcpAgent::reset() 977 | cancel_timers(); // cancel timers first 978 | TcpAgent::reset(); // resets most variables 979 | rq_.clear(); // clear reassembly queue 980 | - rtt_init(); // zero rtt, srtt, backoff 981 | - 982 | + rtt_init(); // zero rtt, srtt, backoff 983 | last_ack_sent_ = -1; 984 | + flow_remaining_ = -1; // Mohammad 985 | rcv_nxt_ = -1; 986 | pipe_ = 0; 987 | rtxbytes_ = 0; 988 | @@ -635,7 +628,12 @@ FullTcpAgent::reset() 989 | ecn_syn_next_ = 1; 990 | else 991 | ecn_syn_next_ = 0; 992 | - 993 | + //Shuang 994 | + prob_mode_ = false; 995 | + prob_count_ = 0; 996 | + last_sqtotal_ = 0; 997 | + deadline = 0; 998 | + early_terminated_ = 0; 999 | } 1000 | 1001 | /* 1002 | @@ -764,6 +762,7 @@ int 1003 | FullTcpAgent::rcvseqinit(int seq, int dlen) 1004 | { 1005 | return (seq + dlen + 1); 1006 | +//printf("newww3 fid= %d, rcv_nxt_= %d diff= %d, highest_ack= %d, last_ack_sent= %d diff= %d\n",fid_,(int)rcv_nxt_,((int)rcv_nxt_)-oldrcvnxt,(int)highest_ack_,last_ack_sent_,((int)last_ack_sent_)-oldlastacksent); 1007 | } 1008 | 1009 | /* 1010 | @@ -821,6 +820,45 @@ FullTcpAgent::ack_action(Packet* p) 1011 | FullTcpAgent::pack_action(p); 1012 | } 1013 | 1014 | +int 1015 | +FullTcpAgent::set_prio(int seq, int maxseq) { 1016 | + int max = 100 * 1460; 1017 | + int prio; 1018 | + if (prio_scheme_ == 0) { 1019 | + if ( seq - startseq_ > max) 1020 | + prio = max; 1021 | + else 1022 | + prio = seq - startseq_; 1023 | + } 1024 | + if (prio_scheme_ == 1) 1025 | + prio = maxseq - startseq_; 1026 | + if (prio_scheme_ == 2) 1027 | + prio = maxseq - seq; 1028 | + if (prio_scheme_ == 3) 1029 | + prio = seq - startseq_; 1030 | + 1031 | + if (prio_num_ == 0) 1032 | + return prio; 1033 | + else 1034 | + return calPrio(prio); 1035 | +} 1036 | + 1037 | +int 1038 | +FullTcpAgent::calPrio(int prio) { 1039 | + if (prio_num_ != 2 && prio_num_ != 4 && prio_num_ != 8) { 1040 | + fprintf(stderr, "wrong number or priority class %d\n", prio_num_); 1041 | + return 0; 1042 | + } 1043 | + for (int i = 1; i < prio_num_; i++) 1044 | + if (prio <= prio_cap_[i * 8 / prio_num_ - 1]) 1045 | + { 1046 | + //printf("prio %d cap %d ans %d\n", prio, prio_cap_[i*8/prio_num_ - 1], i - 1); 1047 | + return i - 1; 1048 | + } 1049 | + 1050 | + //printf("prio %d cap %d ans %d\n", prio, prio_cap_[8/prio_num_ - 1], prio_num_ - 1); 1051 | + return prio_num_ - 1; 1052 | +} 1053 | 1054 | /* 1055 | * sendpacket: 1056 | @@ -839,6 +877,7 @@ FullTcpAgent::sendpacket(int seqno, int ackno, int pflags, int datalen, int reas 1057 | if (!p) p = allocpkt(); 1058 | hdr_tcp *tcph = hdr_tcp::access(p); 1059 | hdr_flags *fh = hdr_flags::access(p); 1060 | + hdr_ip* iph = hdr_ip::access(p); 1061 | 1062 | /* build basic header w/options */ 1063 | 1064 | @@ -849,7 +888,10 @@ FullTcpAgent::sendpacket(int seqno, int ackno, int pflags, int datalen, int reas 1065 | tcph->sa_length() = 0; // may be increased by build_options() 1066 | tcph->hlen() = tcpip_base_hdr_size_; 1067 | tcph->hlen() += build_options(tcph); 1068 | + //Shuang: reduce header length 1069 | + //tcph->hlen() = 1; 1070 | 1071 | + //iph->prio() = curseq_ - seqno + 10; 1072 | /* 1073 | * Explicit Congestion Notification (ECN) related: 1074 | * Bits in header: 1075 | @@ -871,10 +913,16 @@ FullTcpAgent::sendpacket(int seqno, int ackno, int pflags, int datalen, int reas 1076 | /* Set ect() to 0. -M. Weigle 1/19/05 */ 1077 | fh->ect() = 0; 1078 | } 1079 | + 1080 | + // Mohammad: for DCTCP, ect should be set on all packets 1081 | + if (ecnhat_) 1082 | + fh->ect() = ect_; 1083 | + 1084 | if (ecn_ && ect_ && recent_ce_ ) { 1085 | // This is needed here for the ACK in a SYN, SYN/ACK, ACK 1086 | // sequence. 1087 | - pflags |= TH_ECE; 1088 | + pflags |= TH_ECE; 1089 | + 1090 | } 1091 | // fill in CWR and ECE bits which don't actually sit in 1092 | // the tcp_flags but in hdr_flags 1093 | @@ -883,6 +931,8 @@ FullTcpAgent::sendpacket(int seqno, int ackno, int pflags, int datalen, int reas 1094 | } else { 1095 | fh->ecnecho() = 0; 1096 | } 1097 | + 1098 | + 1099 | if ( pflags & TH_CWR ) { 1100 | fh->cong_action() = 1; 1101 | } 1102 | @@ -896,8 +946,11 @@ FullTcpAgent::sendpacket(int seqno, int ackno, int pflags, int datalen, int reas 1103 | hdr_cmn *ch = hdr_cmn::access(p); 1104 | ch->size() = datalen + tcph->hlen(); 1105 | 1106 | - if (datalen <= 0) 1107 | + if (datalen <= 0) { 1108 | ++nackpack_; 1109 | + //Shuang: artifically reduce ack size 1110 | + //ch->size() = 1; 1111 | + } 1112 | else { 1113 | ++ndatapack_; 1114 | ndatabytes_ += datalen; 1115 | @@ -907,14 +960,54 @@ FullTcpAgent::sendpacket(int seqno, int ackno, int pflags, int datalen, int reas 1116 | ++nrexmitpack_; 1117 | nrexmitbytes_ += datalen; 1118 | } 1119 | - 1120 | last_ack_sent_ = ackno; 1121 | 1122 | //if (state_ != TCPS_ESTABLISHED) { 1123 | //printf("%f(%s)[state:%s]: sending pkt ", now(), name(), statestr(state_)); 1124 | //prpkt(p); 1125 | //} 1126 | - 1127 | + if (deadline > 0) 1128 | + iph->prio_type() = 1; 1129 | + if (datalen > 0) { 1130 | + //iph->prio_type() = 0; 1131 | + //iph->prio() = set_prio(seqno, curseq_); 1132 | + /* Shuang: prio dropping */ 1133 | + if (deadline == 0) { 1134 | + iph->prio() = set_prio(seqno, curseq_); 1135 | + iph->prio_type() = 0; 1136 | + } else { 1137 | + int tleft = deadline - int((now() - start_time) * 1e6); 1138 | + iph->prio_type() = 1; 1139 | + iph->prio() = deadline + int(start_time * 1e6); 1140 | + if (tleft < 0 || byterm() * 8 / 1e4 > tleft) { 1141 | + iph->prio_type() = 0; 1142 | + iph->prio() = (1 << 30); 1143 | + } else { 1144 | +// iph->prio() = iph->prio() / 40 * 1000 + set_prio(seqno, curseq_) / 1460; 1145 | + } 1146 | + } 1147 | + 1148 | + /* Mohammad: this is deprecated 1149 | + * it was for path-aware multipath 1150 | + * congestion control experiments */ 1151 | + //Shuang: delete it 1152 | + //iph->prio() = fid_; 1153 | + 1154 | + /* Mohammad: inform pacer (TBF) that 1155 | + * this connection received an EcnEcho. 1156 | + * this is a bit hacky, but necessary 1157 | + * for now since the TBF class doesn't see the 1158 | + * ACKS. */ 1159 | + 1160 | + if (informpacer) 1161 | + iph->gotecnecho = 1; 1162 | + else 1163 | + iph->gotecnecho = 0; 1164 | + 1165 | + informpacer = 0; 1166 | + //abd 1167 | + } 1168 | + 1169 | send(p, 0); 1170 | 1171 | return; 1172 | @@ -960,9 +1053,12 @@ FullTcpAgent::foutput(int seqno, int reason) 1173 | // Q: how can this happen? 1174 | 1175 | if (maxseg_ == 0) 1176 | - maxseg_ = size_ - headersize(); 1177 | - else 1178 | - size_ = maxseg_ + headersize(); 1179 | + maxseg_ = size_;// Mohammad: changed from size_ - headersize(); 1180 | + // Mohamad: commented the else condition 1181 | + // which is unnecessary and conflates with 1182 | + // tcp.cc 1183 | + //else 1184 | + // size_ = maxseg_ + headersize(); 1185 | 1186 | int is_retransmit = (seqno < maxseq_); 1187 | int quiet = (highest_ack_ == maxseq_); 1188 | @@ -971,8 +1067,11 @@ FullTcpAgent::foutput(int seqno, int reason) 1189 | int emptying_buffer = FALSE; 1190 | int buffered_bytes = (infinite_send_) ? TCP_MAXSEQ : 1191 | curseq_ - highest_ack_ + 1; 1192 | - 1193 | +//printf("buffered bytes= %d now= %lf fid= %d cwnd= %d\n", buffered_bytes,now(),fid_,(int)cwnd_); 1194 | int win = window() * maxseg_; // window (in bytes) 1195 | + if (prob_mode_ && win > 1) 1196 | + win = 1; 1197 | + 1198 | int off = seqno - highest_ack_; // offset of seg in window 1199 | int datalen; 1200 | //int amtsent = 0; 1201 | @@ -990,10 +1089,28 @@ FullTcpAgent::foutput(int seqno, int reason) 1202 | datalen = buffered_bytes - off; 1203 | else 1204 | datalen = min(buffered_bytes, win) - off; 1205 | - 1206 | - if ((signal_on_empty_) && (!buffered_bytes) && (!syn)) 1207 | + 1208 | +// if (fid_ == 13 || fid_ == 14) { 1209 | +// int tmp = 0; 1210 | +// if (prob_mode_) 1211 | +// tmp = 1; 1212 | +// int tmph = highest_ack_; 1213 | +// printf("%.5lf: FLOW%d: win %d probe: %d buffered bytes %d off %d seqno %d, highestack %d, datalen %d\n", now(), fid_, win, tmp, buffered_bytes, off, seqno, tmph, datalen); 1214 | +// fflush(stdout); 1215 | +// } 1216 | + 1217 | +// if (deadline != 0 && !syn) { 1218 | +// double tleft = deadline/1e6 - (now() - start_time); 1219 | +// if (tleft < 0) { 1220 | +// printf("early termination now %.8lf start %.8lf deadline %d\n", now(), start_time, deadline); 1221 | +// fflush(stdout); 1222 | +// buffered_bytes = 0; 1223 | +// datalen = 0; 1224 | +// } 1225 | +// } 1226 | + if ((signal_on_empty_) && (!buffered_bytes) && (!syn)) { 1227 | bufferempty(); 1228 | - 1229 | + } 1230 | // 1231 | // in real TCP datalen (len) could be < 0 if there was window 1232 | // shrinkage, or if a FIN has been sent and neither ACKd nor 1233 | @@ -1004,6 +1121,7 @@ FullTcpAgent::foutput(int seqno, int reason) 1234 | } else if (datalen > maxseg_) { 1235 | datalen = maxseg_; 1236 | } 1237 | + 1238 | 1239 | // 1240 | // this is an option that causes us to slow-start if we've 1241 | @@ -1014,9 +1132,11 @@ FullTcpAgent::foutput(int seqno, int reason) 1242 | if (slow_start_restart_ && quiet && datalen > 0) { 1243 | if (idle_restart()) { 1244 | slowdown(CLOSE_CWND_INIT); 1245 | - } 1246 | + } 1247 | } 1248 | 1249 | + //printf("%f %d %d\n", Scheduler::instance().clock(), (int) highest_ack_, (int) maxseq_); 1250 | + 1251 | // 1252 | // see if sending this packet will empty the send buffer 1253 | // a dataless SYN packet counts also 1254 | @@ -1064,10 +1184,15 @@ FullTcpAgent::foutput(int seqno, int reason) 1255 | // only happen for tiny windows) 1256 | if (datalen >= ((wnd_ * maxseg_) / 2.0)) 1257 | goto send; 1258 | + //Shuang 1259 | + if (datalen == 1 && prob_mode_) 1260 | + goto send; 1261 | } 1262 | 1263 | - if (need_send()) 1264 | + if (need_send()){ 1265 | +// if(fid_==2352) printf("before need_send fid= %d, rcv_nxt_= %d highest_ack= %d, last_ack_sent= %d\n",fid_,(int)rcv_nxt_,(int)highest_ack_,last_ack_sent_); 1266 | goto send; 1267 | + } 1268 | 1269 | /* 1270 | * send now if a control packet or we owe peer an ACK 1271 | @@ -1088,10 +1213,11 @@ FullTcpAgent::foutput(int seqno, int reason) 1272 | send: 1273 | 1274 | // is a syn or fin? 1275 | - 1276 | + //printf("made it to send\n"); 1277 | syn = (pflags & TH_SYN) ? 1 : 0; 1278 | + 1279 | int fin = (pflags & TH_FIN) ? 1 : 0; 1280 | - 1281 | + 1282 | /* setup ECN syn and ECN SYN+ACK packet headers */ 1283 | if (ecn_ && syn && !(pflags & TH_ACK)){ 1284 | pflags |= TH_ECE; 1285 | @@ -1155,6 +1281,13 @@ send: 1286 | * Any pending ACK has now been sent. 1287 | */ 1288 | flags_ &= ~(TF_ACKNOW|TF_DELACK); 1289 | + 1290 | + // Mohammad 1291 | + delack_timer_.force_cancel(); 1292 | + /* 1293 | + if (datalen == 0) 1294 | + printf("%f -- %s sent ACK for %d, canceled delack\n", this->name(), Scheduler::instance().clock(), rcv_nxt_); 1295 | + */ 1296 | 1297 | /* 1298 | * if we have reacted to congestion recently, the 1299 | @@ -1178,6 +1311,8 @@ send: 1300 | // and adjusted for SYNs and FINs which use up one number 1301 | 1302 | int highest = seqno + reliable; 1303 | + if (highest > ecnhat_maxseq) 1304 | + ecnhat_maxseq = highest; 1305 | if (highest > maxseq_) { 1306 | maxseq_ = highest; 1307 | // 1308 | @@ -1222,10 +1357,10 @@ FullTcpAgent::send_much(int force, int reason, int maxburst) 1309 | { 1310 | int npackets = 0; // sent so far 1311 | 1312 | -//if ((int(t_seqno_)) > 1) 1313 | -//printf("%f: send_much(f:%d, win:%d, pipectrl:%d, pipe:%d, t_seqno:%d, topwin:%d, maxseq_:%d\n", 1314 | -//now(), force, win, pipectrl_, pipe_, int(t_seqno_), topwin, int(maxseq_)); 1315 | - 1316 | + //if ((int(t_seqno_)) > 1) 1317 | + //printf("%f: send_much(f:%d, win:%d, pipectrl:%d, pipe:%d, t_seqno:%d, topwin:%d, maxseq_:%d\n", 1318 | + //now(), force, win, pipectrl_, pipe_, int(t_seqno_), topwin, int(maxseq_)); 1319 | + 1320 | if (!force && (delsnd_timer_.status() == TIMER_PENDING)) 1321 | return; 1322 | 1323 | @@ -1239,6 +1374,8 @@ FullTcpAgent::send_much(int force, int reason, int maxburst) 1324 | */ 1325 | int amt; 1326 | int seq = nxt_tseq(); 1327 | + 1328 | + 1329 | if (!force && !send_allowed(seq)) 1330 | break; 1331 | // Q: does this need to be here too? 1332 | @@ -1247,8 +1384,10 @@ FullTcpAgent::send_much(int force, int reason, int maxburst) 1333 | delsnd_timer_.resched(Random::uniform(overhead_)); 1334 | return; 1335 | } 1336 | - if ((amt = foutput(seq, reason)) <= 0) 1337 | - break; 1338 | + if ((amt = foutput(seq, reason)) <= 0) { 1339 | + //printf("made call to foutput: returned %d\n", amt); 1340 | + break; 1341 | + } 1342 | if ((outflags() & TH_FIN)) 1343 | --amt; // don't count FINs 1344 | sent(seq, amt); 1345 | @@ -1269,11 +1408,18 @@ int 1346 | FullTcpAgent::send_allowed(int seq) 1347 | { 1348 | int win = window() * maxseg_; 1349 | + //Shuang: probe_mode 1350 | + if (prob_mode_ && win > 1) 1351 | + win = 1; 1352 | int topwin = curseq_; // 1 seq number past the last byte we can send 1353 | 1354 | if ((topwin > highest_ack_ + win) || infinite_send_) 1355 | - topwin = highest_ack_ + win; 1356 | - 1357 | + topwin = highest_ack_ + win; 1358 | + 1359 | +// if (seq >= topwin) { 1360 | +// printf("%.5lf: fid %d send not allowed\n", now(), fid_); 1361 | +// fflush(stdout); 1362 | +// } 1363 | return (seq < topwin); 1364 | } 1365 | /* 1366 | @@ -1292,11 +1438,17 @@ FullTcpAgent::send_allowed(int seq) 1367 | void 1368 | FullTcpAgent::newack(Packet* pkt) 1369 | { 1370 | + 1371 | + //Shuang: cancel prob_mode_ when receiving an ack 1372 | + prob_mode_ = false; 1373 | + prob_count_ = 0; 1374 | + 1375 | hdr_tcp *tcph = hdr_tcp::access(pkt); 1376 | 1377 | register int ackno = tcph->ackno(); 1378 | int progress = (ackno > highest_ack_); 1379 | - 1380 | + 1381 | + //printf("NEWACK cur %d last %d ackno %d highest %d\n", cur_sqtotal_, last_sqtotal_,int(ackno), int(highest_ack_)); 1382 | if (ackno == maxseq_) { 1383 | cancel_rtx_timer(); // all data ACKd 1384 | } else if (progress) { 1385 | @@ -1304,8 +1456,9 @@ FullTcpAgent::newack(Packet* pkt) 1386 | } 1387 | 1388 | // advance the ack number if this is for new data 1389 | - if (progress) 1390 | + if (progress) { 1391 | highest_ack_ = ackno; 1392 | + } 1393 | 1394 | // if we have suffered a retransmit timeout, t_seqno_ 1395 | // will have been reset to highest_ ack. If the 1396 | @@ -1360,6 +1513,8 @@ FullTcpAgent::newack(Packet* pkt) 1397 | return; 1398 | } 1399 | 1400 | + 1401 | + 1402 | /* 1403 | * this is the simulated form of the header prediction 1404 | * predicate. While not really necessary for a simulation, it 1405 | @@ -1415,7 +1570,7 @@ FullTcpAgent::fast_retransmit(int seq) 1406 | { 1407 | // we are now going to fast-retransmit and willtrace that event 1408 | trace_event("FAST_RETX"); 1409 | - 1410 | + printf("%f: fid %d did a fast retransmit - dupacks = %d\n", now(), fid_, (int)dupacks_); 1411 | recover_ = maxseq_; // recovery target 1412 | last_cwnd_action_ = CWND_ACTION_DUPACK; 1413 | return(foutput(seq, REASON_DUPACK)); // send one pkt 1414 | @@ -1443,8 +1598,10 @@ FullTcpAgent::need_send() 1415 | 1416 | int spa = (spa_thresh_ > 0 && ((rcv_nxt_ - irs_) < spa_thresh_)) ? 1417 | 1 : segs_per_ack_; 1418 | - 1419 | - return ((rcv_nxt_ - last_ack_sent_) >= (spa * maxseg_)); 1420 | + //Shuang 1421 | + return ((rcv_nxt_ - last_ack_sent_) > 0); 1422 | + //return ((rcv_nxt_ - last_ack_sent_) >= spa * maxseg_); 1423 | + 1424 | } 1425 | 1426 | /* 1427 | @@ -1471,6 +1628,8 @@ FullTcpAgent::idle_restart() 1428 | } 1429 | 1430 | return (tao > t_rtxcur_); // verify this CHECKME 1431 | + //return (tao > (int(t_srtt_) >> T_SRTT_BITS)*tcp_tick_); //Mohammad 1432 | + 1433 | } 1434 | 1435 | /* 1436 | @@ -1506,6 +1665,10 @@ FullTcpAgent::set_initial_window() 1437 | void 1438 | FullTcpAgent::recv(Packet *pkt, Handler*) 1439 | { 1440 | + //Shuang: cancel probe mode 1441 | + prob_mode_ = false; 1442 | + prob_count_ = 0; 1443 | + 1444 | hdr_tcp *tcph = hdr_tcp::access(pkt); // TCP header 1445 | hdr_cmn *th = hdr_cmn::access(pkt); // common header (size, etc) 1446 | hdr_flags *fh = hdr_flags::access(pkt); // flags (CWR, CE, bits) 1447 | @@ -1518,6 +1681,7 @@ FullTcpAgent::recv(Packet *pkt, Handler*) 1448 | last_state_ = state_; 1449 | 1450 | int datalen = th->size() - tcph->hlen(); // # payload bytes 1451 | +//printf("fid2= %d datalen= %d\n",fid_,datalen); 1452 | int ackno = tcph->ackno(); // ack # from packet 1453 | int tiflags = tcph->flags() ; // tcp flags from packet 1454 | 1455 | @@ -1525,7 +1689,6 @@ FullTcpAgent::recv(Packet *pkt, Handler*) 1456 | //fprintf(stdout, "%f(%s)in state %s recv'd this packet: ", now(), name(), statestr(state_)); 1457 | //prpkt(pkt); 1458 | //} 1459 | - 1460 | /* 1461 | * Acknowledge FIN from passive closer even in TCPS_CLOSED state 1462 | * (since we lack TIME_WAIT state and RST packets, 1463 | @@ -1550,6 +1713,14 @@ FullTcpAgent::recv(Packet *pkt, Handler*) 1464 | goto drop; 1465 | } 1466 | 1467 | + /* 1468 | + * Shuang: if fid does not match, drop packets 1469 | + */ 1470 | + if (fid_ != hdr_ip::access(pkt)->fid_) { 1471 | + //printf("extra!%d %d\n", fid_, hdr_ip::access(pkt)->fid_); 1472 | + goto drop; 1473 | + } 1474 | + 1475 | /* 1476 | * Process options if not in LISTEN state, 1477 | * else do it below 1478 | @@ -1563,12 +1734,33 @@ FullTcpAgent::recv(Packet *pkt, Handler*) 1479 | * They are set to fire every 'interval_' secs, starting 1480 | * at time t0 = (0.0 + k * interval_) for some k such 1481 | * that t0 > now 1482 | + */ 1483 | + /* 1484 | + *Mohammad: commented this out for more efficient 1485 | + * delayed ack generation 1486 | */ 1487 | - if (delack_interval_ > 0.0 && 1488 | + /*if (delack_interval_ > 0.0 && 1489 | (delack_timer_.status() != TIMER_PENDING)) { 1490 | int last = int(now() / delack_interval_); 1491 | delack_timer_.resched(delack_interval_ * (last + 1.0) - now()); 1492 | - } 1493 | + }*/ 1494 | + 1495 | + 1496 | + // Mohammad 1497 | + if (ecnhat_) 1498 | + update_ecnhat_alpha(pkt); 1499 | + 1500 | + /* Mohammad: check if we need to inform 1501 | + * pacer of ecnecho. 1502 | + */ 1503 | + if (!(tiflags & TH_SYN) && fh->ecnecho()) 1504 | + informpacer = 1; 1505 | + 1506 | + /*if (datalen > 0) 1507 | + printf("received data: datalen = %d seqno = %d, ackno = %d, ce = %d, ecn-echo = %d\n", datalen, tcph->seqno(), ackno, fh->ce(), fh->ecnecho()); 1508 | + else 1509 | + printf("received ack : datalen = %d seqno = %d, ackno = %d, ce = %d, ecn-echo = %d\n", datalen, tcph->seqno(), ackno, fh->ce(), fh->ecnecho()); 1510 | + */ 1511 | 1512 | /* 1513 | * Try header prediction: in seq data or in seq pure ACK 1514 | @@ -1596,16 +1788,36 @@ FullTcpAgent::recv(Packet *pkt, Handler*) 1515 | // cong_action bit 1516 | // 1517 | 1518 | - if (ecn_) { 1519 | + if (ecn_) { 1520 | + if (ecnhat_) { // Mohammad 1521 | if (fh->ce() && fh->ect()) { 1522 | // no CWR from peer yet... arrange to 1523 | // keep sending ECNECHO 1524 | + if (recent_ce_ == FALSE) { 1525 | + ce_transition_ = 1; 1526 | + recent_ce_ = TRUE; 1527 | + } else { 1528 | + ce_transition_ = 0; 1529 | + } 1530 | + } else if (datalen > 0 && !fh->ce() && fh->ect()){ 1531 | + if (recent_ce_ == TRUE) { 1532 | + ce_transition_ = 1; 1533 | + recent_ce_ = FALSE; 1534 | + } else { 1535 | + ce_transition_ = 0; 1536 | + } 1537 | + } 1538 | + } else { 1539 | + if (fh->ce() && fh->ect()) { 1540 | + // no CWR from peer yet... arrange to 1541 | + // keep sending ECNECHO 1542 | recent_ce_ = TRUE; 1543 | - } else if (fh->cwr()) { 1544 | - // got CWR response from peer.. stop 1545 | + } else if (fh->cwr()) { 1546 | + // got CWR response from peer.. stop 1547 | // sending ECNECHO bits 1548 | - recent_ce_ = FALSE; 1549 | - } 1550 | + recent_ce_ = FALSE; 1551 | + } 1552 | + } 1553 | } 1554 | 1555 | // Header predication basically looks to see 1556 | @@ -1638,16 +1850,47 @@ FullTcpAgent::recv(Packet *pkt, Handler*) 1557 | // this routine scans all tcpcb's looking for 1558 | // DELACK segments and when it finds them 1559 | // changes DELACK to ACKNOW and calls tcp_output() 1560 | - rcv_nxt_ += datalen; 1561 | + 1562 | + /* Mohammad: For DCTCP state machine */ 1563 | + if (ecnhat_ && ce_transition_ && ((rcv_nxt_ - last_ack_sent_) > 0)) { 1564 | + // Must send an immediate ACK with with previous ECN state 1565 | + // before transitioning to new state 1566 | + flags_ |= TF_ACKNOW; 1567 | + recent_ce_ = !recent_ce_; 1568 | + // printf("should be acking %d with recent_ce_ = %d\n", rcv_nxt_, recent_ce_); 1569 | + send_much(1, REASON_NORMAL, maxburst_); 1570 | + recent_ce_ = !recent_ce_; 1571 | + } 1572 | + 1573 | + rcv_nxt_ += datalen; 1574 | + 1575 | flags_ |= TF_DELACK; 1576 | + // Mohammad 1577 | + delack_timer_.resched(delack_interval_); 1578 | + 1579 | + // printf("%f: receving data %d, rescheduling delayed ack\n", Scheduler::instance().clock(), rcv_nxt_); 1580 | + 1581 | recvBytes(datalen); // notify application of "delivery" 1582 | + 1583 | + //printf("flow_remaining before dec = %d\n" , flow_remaining_); 1584 | + if (flow_remaining_ > 0) 1585 | + flow_remaining_ -= datalen; // Mohammad 1586 | + 1587 | + if (flow_remaining_ == 0) { 1588 | + flags_ |= TF_ACKNOW; 1589 | + flow_remaining_ = -1; 1590 | + } 1591 | + //printf("flow_remaining after dec = %d\n" , flow_remaining_); 1592 | + 1593 | // 1594 | // special code here to simulate the operation 1595 | // of a receiver who always consumes data, 1596 | // resulting in a call to tcp_output 1597 | Packet::free(pkt); 1598 | - if (need_send()) 1599 | + if (need_send()){ 1600 | send_much(1, REASON_NORMAL, maxburst_); 1601 | +// if(fid_==2352) printf("before2 need_send fid= %d, rcv_nxt_= %d highest_ack= %d, last_ack_sent= %d\n",fid_,(int)rcv_nxt_,(int)highest_ack_,last_ack_sent_); 1602 | + } 1603 | return; 1604 | } 1605 | } /* header prediction */ 1606 | @@ -1707,7 +1950,6 @@ FullTcpAgent::recv(Packet *pkt, Handler*) 1607 | t_seqno_ = iss_; /* tcp_sendseqinit() macro in real tcp */ 1608 | rcv_nxt_ = rcvseqinit(irs_, datalen); 1609 | flags_ |= TF_ACKNOW; 1610 | - 1611 | // check for a ECN-SYN with ECE|CWR 1612 | if (ecn_ && fh->ecnecho() && fh->cong_action()) { 1613 | ect_ = TRUE; 1614 | @@ -1816,6 +2058,8 @@ if (t_rtt_) { 1615 | */ 1616 | if (datalen > 0) { 1617 | flags_ |= TF_DELACK; // data there: wait 1618 | + // Mohammad 1619 | + delack_timer_.resched(delack_interval_); 1620 | } else { 1621 | flags_ |= TF_ACKNOW; // ACK peer's SYN 1622 | } 1623 | @@ -2122,21 +2366,49 @@ trimthenstep6: 1624 | 1625 | if (fh->ecnecho() && (!ecn_ || !ect_)) { 1626 | fprintf(stderr, 1627 | - "%f: FullTcp(%s): warning, recvd ecnecho but I am not ECN capable!\n", 1628 | - now(), name()); 1629 | + "%f: FullTcp(%s): warning, recvd ecnecho but I am not ECN capable! %d %d\n", 1630 | + now(), name(), ecn_); 1631 | } 1632 | 1633 | - // 1634 | - // generate a stream of ecnecho bits until we see a true 1635 | - // cong_action bit 1636 | - // 1637 | - if (ecn_) { 1638 | - if (fh->ce() && fh->ect()) 1639 | - recent_ce_ = TRUE; 1640 | - else if (fh->cwr()) 1641 | - recent_ce_ = FALSE; 1642 | - } 1643 | + // 1644 | + // generate a stream of ecnecho bits until we see a true 1645 | + // cong_action bit 1646 | + // 1647 | + 1648 | + if (ecn_) { 1649 | + if (ecnhat_) { // Mohammad 1650 | + if (fh->ce() && fh->ect()) { 1651 | + // no CWR from peer yet... arrange to 1652 | + // keep sending ECNECHO 1653 | + if (recent_ce_ == FALSE) { 1654 | + ce_transition_ = 1; 1655 | + recent_ce_ = TRUE; 1656 | + } else { 1657 | + ce_transition_ = 0; 1658 | + } 1659 | + } else if (datalen > 0 && !fh->ce() && fh->ect()){ 1660 | + if (recent_ce_ == TRUE) { 1661 | + ce_transition_ = 1; 1662 | + recent_ce_ = FALSE; 1663 | + } else { 1664 | + ce_transition_ = 0; 1665 | + } 1666 | + } 1667 | + 1668 | + } else { 1669 | + if (fh->ce() && fh->ect()) { 1670 | + // no CWR from peer yet... arrange to 1671 | + // keep sending ECNECHO 1672 | + recent_ce_ = TRUE; 1673 | + } else if (fh->cwr()) { 1674 | + // got CWR response from peer.. stop 1675 | + // sending ECNECHO bits 1676 | + recent_ce_ = FALSE; 1677 | + } 1678 | + } 1679 | + } 1680 | 1681 | + 1682 | // 1683 | // If ESTABLISHED or starting to close, process SACKS 1684 | // 1685 | @@ -2156,11 +2428,22 @@ trimthenstep6: 1686 | // look for dup ACKs (dup ack numbers, no data) 1687 | // 1688 | // do fast retransmit/recovery if at/past thresh 1689 | +//if (ackno <= highest_ack_) printf("dupi= %d\n",(int)dupacks_); 1690 | +//else printf("in fully\n"); 1691 | + //Shuang: 1692 | +// if (ackno <= highest_ack_ && cur_sqtotal_ <= last_sqtotal_) { 1693 | if (ackno <= highest_ack_) { 1694 | // a pure ACK which doesn't advance highest_ack_ 1695 | +//printf("dupi= %d\n",dupacks_); 1696 | if (datalen == 0 && (!dupseg_fix_ || !dupseg)) { 1697 | 1698 | - /* 1699 | + //Mohammad: check for dynamic dupack mode. 1700 | + if (dynamic_dupack_ > 0.0) { 1701 | + tcprexmtthresh_ = int(dynamic_dupack_ * window()); 1702 | + if (tcprexmtthresh_ < 3) 1703 | + tcprexmtthresh_ = 3; 1704 | + } 1705 | + /* 1706 | * If we have outstanding data 1707 | * this is a completely 1708 | * duplicate ack, 1709 | @@ -2187,6 +2470,7 @@ trimthenstep6: 1710 | } else if (++dupacks_ == tcprexmtthresh_) { 1711 | // ACK at highest_ack_ AND meets threshold 1712 | //trace_event("FAST_RECOVERY"); 1713 | + //Shuang: dupack_action 1714 | dupack_action(); // maybe fast rexmt 1715 | goto drop; 1716 | 1717 | @@ -2263,14 +2547,22 @@ process_ACK: 1718 | * but not if it is a syn packet 1719 | */ 1720 | if (fh->ecnecho() && !(tiflags&TH_SYN) ) 1721 | - if (fh->ecnecho()) { 1722 | + if (fh->ecnecho()) { 1723 | // Note from Sally: In one-way TCP, 1724 | // ecn() is called before newack()... 1725 | ecn(highest_ack_); // updated by newack(), above 1726 | // "set_rtx_timer();" from T. Kelly. 1727 | if (cwnd_ < 1) 1728 | set_rtx_timer(); 1729 | - } 1730 | + } 1731 | + 1732 | + // Mohammad 1733 | + /*if (Random::uniform(1) < ecnhat_alpha_ && !(tiflags&TH_SYN) ) { 1734 | + ecn(highest_ack_); 1735 | + if (cwnd_ < 1) 1736 | + set_rtx_timer(); 1737 | + }*/ 1738 | + 1739 | // CHECKME: handling of rtx timer 1740 | if (ackno == maxseq_) { 1741 | needoutput = TRUE; 1742 | @@ -2297,11 +2589,19 @@ process_ACK: 1743 | if ((!delay_growth_ || (rcv_nxt_ > 0)) && 1744 | last_state_ == TCPS_ESTABLISHED) { 1745 | if (!partial || open_cwnd_on_pack_) { 1746 | - if (!ect_ || !hdr_flags::access(pkt)->ecnecho()) 1747 | - opencwnd(); 1748 | + if (!ect_ || !hdr_flags::access(pkt)->ecnecho() || ecn_burst_) 1749 | + opencwnd(); 1750 | } 1751 | } 1752 | 1753 | + // Mohammad 1754 | + if (ect_) { 1755 | + if (!ecn_burst_ && hdr_flags::access(pkt)->ecnecho()) 1756 | + ecn_burst_ = TRUE; 1757 | + else if (ecn_burst_ && ! hdr_flags::access(pkt)->ecnecho()) 1758 | + ecn_burst_ = FALSE; 1759 | + } 1760 | + 1761 | if ((state_ >= TCPS_FIN_WAIT_1) && (ackno == maxseq_)) { 1762 | ourfinisacked = TRUE; 1763 | } 1764 | @@ -2395,14 +2695,42 @@ step6: 1765 | // don't really have a process anyhow, just 1766 | // accept the data here as-is (i.e. don't 1767 | // require being in ESTABLISHED state) 1768 | - flags_ |= TF_DELACK; 1769 | + 1770 | + /* Mohammad: For DCTCP state machine */ 1771 | + if (ecnhat_ && ce_transition_ && ((rcv_nxt_ - last_ack_sent_) > 0)) { 1772 | + // Must send an immediate ACK with with previous ECN state 1773 | + // before transitioning to new state 1774 | + flags_ |= TF_ACKNOW; 1775 | + recent_ce_ = !recent_ce_; 1776 | + //printf("should be acking %d with recent_ce_ = %d\n", rcv_nxt_, recent_ce_); 1777 | + send_much(1, REASON_NORMAL, maxburst_); 1778 | + recent_ce_ = !recent_ce_; 1779 | + } 1780 | + 1781 | + flags_ |= TF_DELACK; 1782 | + // Mohammad 1783 | + delack_timer_.resched(delack_interval_); 1784 | rcv_nxt_ += datalen; 1785 | + 1786 | + // printf("%f: receving data %d, rescheduling delayed ack\n", Scheduler::instance().clock(), rcv_nxt_); 1787 | + 1788 | tiflags = tcph->flags() & TH_FIN; 1789 | 1790 | // give to "application" here 1791 | // in "real" TCP, this is sbappend() + sorwakeup() 1792 | - if (datalen) 1793 | + if (datalen) { 1794 | recvBytes(datalen); // notify app. of "delivery" 1795 | + 1796 | + //printf("flow_remaining before dec = %d\n" , flow_remaining_); 1797 | + if (flow_remaining_ > 0) 1798 | + flow_remaining_ -= datalen; // Mohammad 1799 | + if (flow_remaining_ == 0) { 1800 | + flags_ |= TF_ACKNOW; 1801 | + flow_remaining_ = -1; 1802 | + } 1803 | + //printf("flow_remaining after dec = %d\n" , flow_remaining_); 1804 | + } 1805 | + 1806 | needoutput = need_send(); 1807 | } else { 1808 | // see the "tcp_reass" function: 1809 | @@ -2412,13 +2740,29 @@ step6: 1810 | // segments or hole-fills. Also, 1811 | // send an ACK (or SACK) to the other side right now. 1812 | // Note that we may have just a FIN here (datalen = 0) 1813 | - int rcv_nxt_old_ = rcv_nxt_; // notify app. if changes 1814 | + 1815 | + /* Mohammad: the DCTCP receiver conveys the ECN-CE 1816 | + received on each out-of-order data packet */ 1817 | + 1818 | + int rcv_nxt_old_ = rcv_nxt_; // notify app. if changes 1819 | tiflags = reass(pkt); 1820 | if (rcv_nxt_ > rcv_nxt_old_) { 1821 | // if rcv_nxt_ has advanced, must have 1822 | // been a hole fill. In this case, there 1823 | - // is something to give to application 1824 | - recvBytes(rcv_nxt_ - rcv_nxt_old_); 1825 | + // is something to give to application 1826 | + recvBytes(rcv_nxt_ - rcv_nxt_old_); 1827 | + 1828 | + //printf("flow_remaining before dec = %d\n" , flow_remaining_); 1829 | + if (flow_remaining_ > 0) 1830 | + flow_remaining_ -= datalen; // Mohammad 1831 | + 1832 | + if (flow_remaining_ == 0) { 1833 | + flags_ |= TF_ACKNOW; 1834 | + flow_remaining_ = -1; 1835 | + } 1836 | + 1837 | + //printf("flow_remaining after dec = %d\n" , flow_remaining_); 1838 | + 1839 | } 1840 | flags_ |= TF_ACKNOW; 1841 | 1842 | @@ -2562,15 +2906,13 @@ FullTcpAgent::dupack_action() 1843 | cancel_rtx_timer(); 1844 | rtt_active_ = FALSE; 1845 | (void)fast_retransmit(highest_ack_); 1846 | - return; 1847 | + return; 1848 | } 1849 | 1850 | if (bug_fix_) { 1851 | - /* 1852 | - * The line below, for "bug_fix_" true, avoids 1853 | - * problems with multiple fast retransmits in one 1854 | - * window of data. 1855 | - */ 1856 | + // The line below, for "bug_fix_" true, avoids 1857 | + // problems with multiple fast retransmits in one 1858 | + // window of data. 1859 | return; 1860 | } 1861 | 1862 | @@ -2584,7 +2926,8 @@ full_reno_action: 1863 | // so don't scale by maxseg_ 1864 | // as real TCP does 1865 | cwnd_ = double(ssthresh_) + double(dupacks_); 1866 | - return; 1867 | + return; 1868 | + 1869 | } 1870 | 1871 | void 1872 | @@ -2592,6 +2935,8 @@ FullTcpAgent::timeout_action() 1873 | { 1874 | recover_ = maxseq_; 1875 | 1876 | +// cwnd_ = 0.5 * cwnd_; 1877 | +//Shuang: comment all below 1878 | if (cwnd_ < 1.0) { 1879 | if (debug_) { 1880 | fprintf(stderr, "%f: FullTcpAgent(%s):: resetting cwnd from %f to 1\n", 1881 | @@ -2606,8 +2951,16 @@ FullTcpAgent::timeout_action() 1882 | slowdown(CLOSE_SSTHRESH_HALF|CLOSE_CWND_RESTART); 1883 | last_cwnd_action_ = CWND_ACTION_TIMEOUT; 1884 | } 1885 | + 1886 | + //cwnd_ = initial_window(); 1887 | +// ssthresh_ = cwnd_; 1888 | + 1889 | reset_rtx_timer(1); 1890 | t_seqno_ = (highest_ack_ < 0) ? iss_ : int(highest_ack_); 1891 | + ecnhat_recalc_seq = t_seqno_; 1892 | + ecnhat_maxseq = ecnhat_recalc_seq; 1893 | + 1894 | + //printf("%f, fid %d took timeout, cwnd_ = %f\n", now(), fid_, (double)cwnd_); 1895 | fastrecov_ = FALSE; 1896 | dupacks_ = 0; 1897 | } 1898 | @@ -2662,7 +3015,8 @@ FullTcpAgent::timeout(int tno) 1899 | flags_ |= TF_ACKNOW; 1900 | send_much(1, REASON_NORMAL, 0); 1901 | } 1902 | - delack_timer_.resched(delack_interval_); 1903 | + // Mohammad 1904 | + //delack_timer_.resched(delack_interval_); 1905 | break; 1906 | default: 1907 | fprintf(stderr, "%f: FullTcpAgent(%s) Unknown Timeout type %d\n", 1908 | @@ -2706,6 +3060,11 @@ FullTcpAgent::process_sack(hdr_tcp*) 1909 | return; 1910 | } 1911 | 1912 | +int 1913 | +FullTcpAgent::byterm() { 1914 | + return curseq_ - int(highest_ack_) - window() * maxseg_; 1915 | +} 1916 | + 1917 | 1918 | /* 1919 | * ****** Tahoe ****** 1920 | @@ -2828,6 +3187,51 @@ NewRenoFullTcpAgent::ack_action(Packet* p) 1921 | * "pipe" style control until recovery is complete 1922 | */ 1923 | 1924 | +int 1925 | +SackFullTcpAgent::set_prio(int seq, int maxseq) { 1926 | + int max = 100 * 1460; 1927 | + int prio; 1928 | + if (prio_scheme_ == 0) { 1929 | + if ( seq - startseq_ > max) 1930 | + prio = max; 1931 | + else 1932 | + prio = seq - startseq_; 1933 | + } 1934 | + if (prio_scheme_ == 1) 1935 | + prio = maxseq - startseq_; 1936 | + if (prio_scheme_ == 2) { 1937 | + //printf("%d %d\n", maxseq, int(highest_ack_)); 1938 | + //printf("%d %d %d %d\n", maxseq, int(highest_ack_), sq_.total(), maxseq - int(highest_ack_) - sq_.total() + 10); 1939 | + //fflush(stdout); 1940 | + if (maxseq - int(highest_ack_) - sq_.total() + 10 < 0) 1941 | + prio = 0; 1942 | + else 1943 | + prio = maxseq - int(highest_ack_) - sq_.total() + 10; 1944 | + //return maxseq - seq; 1945 | + } 1946 | + if (prio_scheme_ == 3) { 1947 | + //printf("3??\n"); 1948 | + prio = seq - startseq_; 1949 | + } 1950 | + if (prio_scheme_ == 4) { //in batch 1951 | + if (int(highest_ack_) >= seq_bound_) { 1952 | + seq_bound_ = maxseq_; 1953 | + if (maxseq - int(highest_ack_) - sq_.total() + 10 < 0) 1954 | + last_prio_ = 0; 1955 | + else 1956 | + last_prio_ = maxseq - int(highest_ack_) - sq_.total() + 10; 1957 | + } 1958 | + //printf("prio scheme 4: highest ack %d maxseq_ %d seq %d prio %d\n", int(highest_ack_), int(maxseq_), seq, last_prio_); 1959 | + prio = last_prio_; 1960 | + } 1961 | + 1962 | + if (prio_num_ == 0) 1963 | + return prio; 1964 | + else 1965 | + return calPrio(prio); 1966 | +} 1967 | + 1968 | + 1969 | void 1970 | SackFullTcpAgent::reset() 1971 | { 1972 | @@ -2874,6 +3278,9 @@ SackFullTcpAgent::dupack_action() 1973 | * packet. -M. Weigle 6/19/02 1974 | */ 1975 | last_cwnd_action_ = CWND_ACTION_DUPACK; 1976 | + /* Mohammad: cut window by half when we have 3 dup ack */ 1977 | + if (ecnhat_) 1978 | + slowdown(CLOSE_SSTHRESH_HALF|CLOSE_CWND_HALF); 1979 | cancel_rtx_timer(); 1980 | rtt_active_ = FALSE; 1981 | int amt = fast_retransmit(highest_ack_); 1982 | @@ -2933,7 +3340,10 @@ SackFullTcpAgent::ack_action(Packet* p) 1983 | { 1984 | //printf("%f: EXITING fast recovery, recover:%d\n", 1985 | //now(), recover_); 1986 | + 1987 | + //Shuang: not set pipectrol_ = false 1988 | fastrecov_ = pipectrl_ = FALSE; 1989 | + fastrecov_ = FALSE; 1990 | if (!sq_.empty() && sack_min_ < highest_ack_) { 1991 | sack_min_ = highest_ack_; 1992 | sq_.cleartonxt(); 1993 | @@ -2964,6 +3374,8 @@ SackFullTcpAgent::build_options(hdr_tcp* tcph) 1994 | } else { 1995 | tcph->sa_length() = 0; 1996 | } 1997 | + //Shuang: reduce ack size 1998 | + //return 0; 1999 | return (total); 2000 | } 2001 | 2002 | @@ -2972,6 +3384,23 @@ SackFullTcpAgent::timeout_action() 2003 | { 2004 | FullTcpAgent::timeout_action(); 2005 | 2006 | + /*recover_ = maxseq_; 2007 | + 2008 | + int progress = curseq_ - int(highest_ack_) - sq_.total(); 2009 | + cwnd_ = min((last_timeout_progress_ - progress) / 1460 + 1, maxcwnd_); 2010 | + ssthresh_ = cwnd_; 2011 | + printf("%d %d", progress/1460, last_timeout_progress_ / 1460); 2012 | + last_timeout_progress_ = progress; 2013 | + 2014 | + reset_rtx_timer(1); 2015 | + t_seqno_ = (highest_ack_ < 0) ? iss_ : int(highest_ack_); 2016 | + ecnhat_recalc_seq = t_seqno_; 2017 | + ecnhat_maxseq = ecnhat_recalc_seq; 2018 | + 2019 | + printf("%f, fid %d took timeout, cwnd_ = %f\n", now(), fid_, (double)cwnd_); 2020 | + fastrecov_ = FALSE; 2021 | + dupacks_ = 0;*/ 2022 | + 2023 | // 2024 | // original SACK spec says the sender is 2025 | // supposed to clear out its knowledge of what 2026 | @@ -2981,7 +3410,7 @@ SackFullTcpAgent::timeout_action() 2027 | // enabled. 2028 | // 2029 | 2030 | - if (clear_on_timeout_) { 2031 | + if (clear_on_timeout_ ) { 2032 | sq_.clear(); 2033 | sack_min_ = highest_ack_; 2034 | } 2035 | @@ -2997,6 +3426,7 @@ SackFullTcpAgent::process_sack(hdr_tcp* tcph) 2036 | // in the pkt. Insert each block range 2037 | // into the scoreboard 2038 | // 2039 | + last_sqtotal_ = sq_.total(); 2040 | 2041 | if (max_sack_blocks_ <= 0) { 2042 | fprintf(stderr, 2043 | @@ -3017,22 +3447,28 @@ SackFullTcpAgent::process_sack(hdr_tcp* tcph) 2044 | } 2045 | sq_.add(tcph->sa_left(i), tcph->sa_right(i), 0); 2046 | } 2047 | - 2048 | + 2049 | + cur_sqtotal_ = sq_.total(); 2050 | return; 2051 | } 2052 | 2053 | int 2054 | SackFullTcpAgent::send_allowed(int seq) 2055 | { 2056 | + //Shuang: always pipe control and simple pipe function 2057 | + //pipectrl_ = true; 2058 | + //pipe_ = maxseq_ - highest_ack_ - sq_.total(); 2059 | + 2060 | // not in pipe control, so use regular control 2061 | if (!pipectrl_) 2062 | return (FullTcpAgent::send_allowed(seq)); 2063 | 2064 | // don't overshoot receiver's advertised window 2065 | int topawin = highest_ack_ + int(wnd_) * maxseg_; 2066 | +// printf("%f: PIPECTRL: SEND(%d) AWIN:%d, pipe:%d, cwnd:%d highest_ack:%d sqtotal:%d\n", 2067 | + //now(), seq, topawin, pipe_, int(cwnd_), int(highest_ack_), sq_.total()); 2068 | + 2069 | if (seq >= topawin) { 2070 | -//printf("%f: SEND(%d) NOT ALLOWED DUE TO AWIN:%d, pipe:%d, cwnd:%d\n", 2071 | -//now(), seq, topawin, pipe_, int(cwnd_)); 2072 | return FALSE; 2073 | } 2074 | 2075 | @@ -3104,6 +3540,10 @@ SackFullTcpAgent::nxt_tseq() 2076 | } else if (fcnt <= 0) 2077 | break; 2078 | else { 2079 | + //Shuang; probe 2080 | + if (prob_cap_ != 0) { 2081 | + seq ++; 2082 | + } else 2083 | seq += maxseg_; 2084 | } 2085 | } 2086 | @@ -3112,3 +3552,217 @@ SackFullTcpAgent::nxt_tseq() 2087 | //now(), int(t_seqno_)); 2088 | return (t_seqno_); 2089 | } 2090 | + 2091 | +int 2092 | +SackFullTcpAgent::byterm() { 2093 | + return curseq_ - int(highest_ack_) - sq_.total() - window() * maxseg_; 2094 | +} 2095 | +void 2096 | +MinTcpAgent::timeout_action() { 2097 | +//Shuang: prob count when cwnd=1 2098 | + if (prob_cap_ != 0) { 2099 | + prob_count_ ++; 2100 | + if (prob_count_ == prob_cap_) { 2101 | + prob_mode_ = true; 2102 | + } 2103 | + //Shuang: h_seqno_? 2104 | + h_seqno_ = highest_ack_; 2105 | + } 2106 | + 2107 | + 2108 | + SackFullTcpAgent::timeout_action(); 2109 | +} 2110 | + 2111 | +double 2112 | +MinTcpAgent::rtt_timeout() { 2113 | + return minrto_; 2114 | +} 2115 | + 2116 | +//void 2117 | +//MinTcpAgent::advance_bytes(int nb) 2118 | +// SackFullTcpAgent::advance_bytes(); 2119 | +//} 2120 | + 2121 | +void 2122 | +DDTcpAgent::slowdown(int how) { 2123 | + 2124 | + double decrease; /* added for highspeed - sylvia */ 2125 | + double win, halfwin, decreasewin; 2126 | + int slowstart = 0; 2127 | + ++ncwndcuts_; 2128 | + if (!(how & TCP_IDLE) && !(how & NO_OUTSTANDING_DATA)){ 2129 | + ++ncwndcuts1_; 2130 | + } 2131 | + 2132 | + //Shuang: deadline-aware 2133 | + double penalty = ecnhat_alpha_; 2134 | + if (deadline != 0) { 2135 | + double tleft = deadline/1e6 - (now() - start_time); 2136 | + 2137 | + //if (tleft < 0 && now() < 3) { 2138 | + // cwnd_ = 1; 2139 | + // printf("early termination now %.8lf start %.8lf deadline %d\n", now(), start_time, deadline); 2140 | + // fflush(stdout); 2141 | + // if (signal_on_empty_); 2142 | + // bufferempty(); 2143 | + // return; 2144 | + //} else 2145 | + if (tleft < 0) { 2146 | + tleft = 1e10; 2147 | + } 2148 | + double rtt = int(t_srtt_ >> T_SRTT_BITS) * tcp_tick_; 2149 | + double Tc = byterm() / (0.75 * cwnd_ * maxseg_) * rtt; 2150 | + double d = Tc/tleft; 2151 | + if (d > 2) d = 2; 2152 | + if (d < 0.5) d = 0.5; 2153 | + if (d >= 0) 2154 | + penalty = pow(penalty, d); 2155 | + //printf("deadline left %.6lf d-factor %f Tc %f start %f rm %d cwnd %f\n", tleft, Tc/tleft, Tc, start_time, byterm(), double(cwnd_)); 2156 | + //fflush(stdout); 2157 | + } else if (penalty > 0) { 2158 | + //non-deadline->TCP 2159 | + penalty = 1; 2160 | + } 2161 | + 2162 | + //ecnhat_alpha_ = 0.07; 2163 | + // we are in slowstart for sure if cwnd < ssthresh 2164 | + if (cwnd_ < ssthresh_) 2165 | + slowstart = 1; 2166 | + if (precision_reduce_) { 2167 | + halfwin = windowd() / 2; 2168 | + if (wnd_option_ == 6) { 2169 | + /* binomial controls */ 2170 | + decreasewin = windowd() - (1.0-decrease_num_)*pow(windowd(),l_parameter_); 2171 | + } else if (wnd_option_ == 8 && (cwnd_ > low_window_)) { 2172 | + /* experimental highspeed TCP */ 2173 | + decrease = decrease_param(); 2174 | + //if (decrease < 0.1) 2175 | + // decrease = 0.1; 2176 | + decrease_num_ = decrease; 2177 | + decreasewin = windowd() - (decrease * windowd()); 2178 | + } else { 2179 | + decreasewin = decrease_num_ * windowd(); 2180 | + } 2181 | + win = windowd(); 2182 | + //printf("decrease param = %f window = %f decwin = %f\n", decrease_num_, win, decreasewin); 2183 | + } else { 2184 | + int temp; 2185 | + temp = (int)(window() / 2); 2186 | + halfwin = (double) temp; 2187 | + if (wnd_option_ == 6) { 2188 | + /* binomial controls */ 2189 | + temp = (int)(window() - (1.0-decrease_num_)*pow(window(),l_parameter_)); 2190 | + } else if ((wnd_option_ == 8) && (cwnd_ > low_window_)) { 2191 | + /* experimental highspeed TCP */ 2192 | + decrease = decrease_param(); 2193 | + //if (decrease < 0.1) 2194 | + // decrease = 0.1; 2195 | + decrease_num_ = decrease; 2196 | + temp = (int)(windowd() - (decrease * windowd())); 2197 | + } else { 2198 | + temp = (int)(decrease_num_ * window()); 2199 | + } 2200 | + decreasewin = (double) temp; 2201 | + win = (double) window(); 2202 | + } 2203 | + if (how & CLOSE_SSTHRESH_HALF) 2204 | + // For the first decrease, decrease by half 2205 | + // even for non-standard values of decrease_num_. 2206 | + if (first_decrease_ == 1 || slowstart || 2207 | + last_cwnd_action_ == CWND_ACTION_TIMEOUT) { 2208 | + // Do we really want halfwin instead of decreasewin 2209 | + // after a timeout? 2210 | + ssthresh_ = (int) halfwin; 2211 | + } else { 2212 | + ssthresh_ = (int) decreasewin; 2213 | + } 2214 | + else if (how & CLOSE_SSTHRESH_ECNHAT) 2215 | + ssthresh_ = (int) ((1 - penalty/2.0) * windowd()); 2216 | + //ssthresh_ = (int) (windowd() - sqrt(2*windowd())/2.0); 2217 | + else if (how & THREE_QUARTER_SSTHRESH) 2218 | + if (ssthresh_ < 3*cwnd_/4) 2219 | + ssthresh_ = (int)(3*cwnd_/4); 2220 | + if (how & CLOSE_CWND_HALF) 2221 | + // For the first decrease, decrease by half 2222 | + // even for non-standard values of decrease_num_. 2223 | + if (first_decrease_ == 1 || slowstart || decrease_num_ == 0.5) { 2224 | + cwnd_ = halfwin; 2225 | + } else cwnd_ = decreasewin; 2226 | + else if (how & CLOSE_CWND_ECNHAT) { 2227 | + cwnd_ = (1 - penalty/2.0) * windowd(); 2228 | + if (cwnd_ < 1) 2229 | + cwnd_ = 1; 2230 | + } 2231 | + //cwnd_ = windowd() - sqrt(2*windowd())/2.0; 2232 | + else if (how & CWND_HALF_WITH_MIN) { 2233 | + // We have not thought about how non-standard TCPs, with 2234 | + // non-standard values of decrease_num_, should respond 2235 | + // after quiescent periods. 2236 | + cwnd_ = decreasewin; 2237 | + if (cwnd_ < 1) 2238 | + cwnd_ = 1; 2239 | + } 2240 | + else if (how & CLOSE_CWND_RESTART) 2241 | + cwnd_ = int(wnd_restart_); 2242 | + else if (how & CLOSE_CWND_INIT) 2243 | + cwnd_ = int(wnd_init_); 2244 | + else if (how & CLOSE_CWND_ONE) 2245 | + cwnd_ = 1; 2246 | + else if (how & CLOSE_CWND_HALF_WAY) { 2247 | + // cwnd_ = win - (win - W_used)/2 ; 2248 | + cwnd_ = W_used + decrease_num_ * (win - W_used); 2249 | + if (cwnd_ < 1) 2250 | + cwnd_ = 1; 2251 | + } 2252 | + if (ssthresh_ < 2) 2253 | + ssthresh_ = 2; 2254 | + if (cwnd_ < 1) 2255 | + cwnd_ = 1; // Added by Mohammad 2256 | + if (how & (CLOSE_CWND_HALF|CLOSE_CWND_RESTART|CLOSE_CWND_INIT|CLOSE_CWND_ONE|CLOSE_CWND_ECNHAT)) 2257 | + cong_action_ = TRUE; 2258 | + 2259 | + fcnt_ = count_ = 0; 2260 | + if (first_decrease_ == 1) 2261 | + first_decrease_ = 0; 2262 | + // for event tracing slow start 2263 | + if (cwnd_ == 1 || slowstart) 2264 | + // Not sure if this is best way to capture slow_start 2265 | + // This is probably tracing a superset of slowdowns of 2266 | + // which all may not be slow_start's --Padma, 07/'01. 2267 | + trace_event("SLOW_START"); 2268 | +} 2269 | + 2270 | +int 2271 | +DDTcpAgent::byterm() { 2272 | + return curseq_ - int(highest_ack_) - sq_.total(); 2273 | +} 2274 | + 2275 | +int 2276 | +DDTcpAgent::foutput(int seqno, int reason) { 2277 | + if (deadline != 0) { 2278 | +// double tleft = double(deadline)/1e6 - (now() - start_time) - byterm()*8/1e10; 2279 | + double tleft = deadline/1e6 - (now() - start_time) - (curseq_ - int(maxseq_)) * 8/1e10; 2280 | + if (tleft < 0 && signal_on_empty_) { 2281 | + early_terminated_ = 1; 2282 | + bufferempty(); 2283 | + printf("early termination V2 now %.8lf start %.8lf deadline %d byterm %d tleft %.8f\n", now(), start_time, deadline, curseq_ - int(maxseq_), tleft); 2284 | + fflush(stdout); 2285 | + return 0; 2286 | + } else if (tleft < 0) { 2287 | + return 0; 2288 | + } 2289 | + //printf("test foutput\n"); 2290 | + } 2291 | + return SackFullTcpAgent::foutput(seqno, reason); 2292 | +} 2293 | + 2294 | +int 2295 | +DDTcpAgent::need_send() { 2296 | + if (deadline != 0) { 2297 | + double tleft1 = deadline/1e6 - (now() - start_time); 2298 | + if (tleft1 < 0) 2299 | + return 0; 2300 | + //printf("test need send\n"); 2301 | + } 2302 | + return SackFullTcpAgent::need_send(); 2303 | +} 2304 | diff --git a/tcp/tcp-full.h b/tcp/tcp-full.h 2305 | index 36e714c..7c69543 100644 2306 | --- a/tcp/tcp-full.h 2307 | +++ b/tcp/tcp-full.h 2308 | @@ -1,38 +1,3 @@ 2309 | -/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ 2310 | -/* 2311 | - * Copyright (c) 1997, 2001 The Regents of the University of California. 2312 | - * All rights reserved. 2313 | - * 2314 | - * Redistribution and use in source and binary forms, with or without 2315 | - * modification, are permitted provided that the following conditions 2316 | - * are met: 2317 | - * 1. Redistributions of source code must retain the above copyright 2318 | - * notice, this list of conditions and the following disclaimer. 2319 | - * 2. Redistributions in binary form must reproduce the above copyright 2320 | - * notice, this list of conditions and the following disclaimer in the 2321 | - * documentation and/or other materials provided with the distribution. 2322 | - * 3. All advertising materials mentioning features or use of this software 2323 | - * must display the following acknowledgement: 2324 | - * This product includes software developed by the Network Research 2325 | - * Group at Lawrence Berkeley National Laboratory. 2326 | - * 4. Neither the name of the University nor of the Laboratory may be used 2327 | - * to endorse or promote products derived from this software without 2328 | - * specific prior written permission. 2329 | - * 2330 | - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2331 | - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2332 | - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2333 | - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2334 | - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2335 | - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2336 | - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2337 | - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2338 | - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2339 | - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2340 | - * SUCH DAMAGE. 2341 | - * 2342 | - * @(#) $Header: /cvsroot/nsnam/ns-2/tcp/tcp-full.h,v 1.60 2008/10/14 17:42:52 sallyfloyd Exp $ (LBL) 2343 | - */ 2344 | 2345 | #ifndef ns_tcp_full_h 2346 | #define ns_tcp_full_h 2347 | @@ -116,18 +81,21 @@ protected: 2348 | class FullTcpAgent : public TcpAgent { 2349 | public: 2350 | FullTcpAgent() : 2351 | + prio_scheme_(0), prio_num_(0), startseq_(0), last_prio_(0), seq_bound_(0), 2352 | closed_(0), pipe_(-1), rtxbytes_(0), fastrecov_(FALSE), 2353 | last_send_time_(-1.0), infinite_send_(FALSE), irs_(-1), 2354 | delack_timer_(this), flags_(0), 2355 | state_(TCPS_CLOSED), recent_ce_(FALSE), 2356 | - last_state_(TCPS_CLOSED), rq_(rcv_nxt_), last_ack_sent_(-1) { } 2357 | + last_state_(TCPS_CLOSED), rq_(rcv_nxt_), last_ack_sent_(-1), 2358 | + informpacer(0) { } 2359 | + // Mohammad: added informpacer 2360 | 2361 | ~FullTcpAgent() { cancel_timers(); rq_.clear(); } 2362 | virtual void recv(Packet *pkt, Handler*); 2363 | virtual void timeout(int tno); // tcp_timers() in real code 2364 | virtual void close() { usrclosed(); } 2365 | void advanceby(int); // over-rides tcp base version 2366 | - void advance_bytes(int); // unique to full-tcp 2367 | + virtual void advance_bytes(int); // unique to full-tcp 2368 | virtual void sendmsg(int nbytes, const char *flags = 0); 2369 | virtual int& size() { return maxseg_; } //FullTcp uses maxseg_ for size_ 2370 | virtual int command(int argc, const char*const* argv); 2371 | @@ -135,6 +103,25 @@ public: 2372 | protected: 2373 | virtual void delay_bind_init_all(); 2374 | virtual int delay_bind_dispatch(const char *varName, const char *localName, TclObject *tracer); 2375 | + /* Shuang: priority dropping */ 2376 | + virtual int set_prio(int seq, int maxseq); 2377 | + virtual int calPrio(int prio); 2378 | + virtual int byterm(); 2379 | + int prio_scheme_; 2380 | + int prio_num_; //number of priorities; 0: unlimited 2381 | + int prio_cap_[7]; 2382 | + int startseq_; 2383 | + int last_prio_; 2384 | + int seq_bound_; 2385 | + int prob_cap_; //change to prob mode after #prob_cap_ timeout 2386 | + int prob_count_; //current #timeouts 2387 | + bool prob_mode_; 2388 | + int last_sqtotal_; 2389 | + int cur_sqtotal_; 2390 | + int deadline; // time remain in us at the beginning 2391 | + double start_time; //start time 2392 | + int early_terminated_; //early terminated 2393 | + 2394 | int closed_; 2395 | int ts_option_size_; // header bytes in a ts option 2396 | int pipe_; // estimate of pipe occupancy (for Sack) 2397 | @@ -148,6 +135,26 @@ protected: 2398 | int deflate_on_pack_; // deflate on partial acks (reno:yes) 2399 | int data_on_syn_; // send data on initial SYN? 2400 | double last_send_time_; // time of last send 2401 | + 2402 | + 2403 | + /* Mohammad: state-variable for robust 2404 | + FCT measurement. 2405 | + */ 2406 | + int flow_remaining_; /* Number of bytes yet to be received from 2407 | + the current flow (at the receiver). This is 2408 | + set by TCL when starting a flow. Receiver will 2409 | + set immediate ACKs when nothing remains to 2410 | + notify sender of flow completion. */ 2411 | + 2412 | + /* Mohammad: state-variable to inform 2413 | + * pacer (TBF) of receiving ecnecho for the flow 2414 | + */ 2415 | + int informpacer; 2416 | + //abd 2417 | + 2418 | + // Mohammad: if non-zero, set dupack threshold to max(3, dynamic_dupack_ * cwnd)_ 2419 | + double dynamic_dupack_; 2420 | + 2421 | int close_on_empty_; // close conn when buffer empty 2422 | int signal_on_empty_; // signal when buffer is empty 2423 | int reno_fastrecov_; // do reno-style fast recovery? 2424 | @@ -215,8 +222,8 @@ protected: 2425 | void connect(); // do active open 2426 | void listen(); // do passive open 2427 | void usrclosed(); // user requested a close 2428 | - int need_send(); // send ACK/win-update now? 2429 | - int foutput(int seqno, int reason = 0); // output 1 packet 2430 | + virtual int need_send(); // send ACK/win-update now? 2431 | + virtual int foutput(int seqno, int reason = 0); // output 1 packet 2432 | void newack(Packet* pkt); // process an ACK 2433 | int pack(Packet* pkt); // is this a partial ack? 2434 | void dooptions(Packet*); // process option(s) 2435 | @@ -225,7 +232,8 @@ protected: 2436 | void prpkt(Packet*); // print packet (debugging helper) 2437 | char *flagstr(int); // print header flags as symbols 2438 | char *statestr(int); // print states as symbols 2439 | - 2440 | + 2441 | + 2442 | /* 2443 | * the following are part of a tcpcb in "real" RFC793 TCP 2444 | */ 2445 | @@ -233,13 +241,18 @@ protected: 2446 | int flags_; /* controls next output() call */ 2447 | int state_; /* enumerated type: FSM state */ 2448 | int recent_ce_; /* last ce bit we saw */ 2449 | + int ce_transition_; /* Mohammad: was there a transition in 2450 | + recent_ce by last ACK. for DCTCP receiver 2451 | + state machine. */ 2452 | int last_state_; /* FSM state at last pkt recv */ 2453 | int rcv_nxt_; /* next sequence number expected */ 2454 | + 2455 | ReassemblyQueue rq_; /* TCP reassembly queue */ 2456 | /* 2457 | * the following are part of a tcpcb in "real" RFC1323 TCP 2458 | */ 2459 | int last_ack_sent_; /* ackno field from last segment we sent */ 2460 | + 2461 | double recent_; // ts on SYN written by peer 2462 | double recent_age_; // my time when recent_ was set 2463 | 2464 | @@ -272,7 +285,6 @@ public: 2465 | sq_(sack_min_), sack_min_(-1), h_seqno_(-1) { } 2466 | ~SackFullTcpAgent() { rq_.clear(); } 2467 | protected: 2468 | - 2469 | virtual void delay_bind_init_all(); 2470 | virtual int delay_bind_dispatch(const char *varName, const char *localName, TclObject *tracer); 2471 | 2472 | @@ -281,6 +293,7 @@ protected: 2473 | virtual void dupack_action(); 2474 | virtual void process_sack(hdr_tcp*); 2475 | virtual void timeout_action(); 2476 | + virtual int set_prio(int seq, int maxseq); 2477 | virtual int nxt_tseq(); 2478 | virtual int hdrsize(int nblks); 2479 | virtual int send_allowed(int); 2480 | @@ -289,6 +302,7 @@ protected: 2481 | h_seqno_ += amt; 2482 | FullTcpAgent::sent(seq, amt); 2483 | } 2484 | + virtual int byterm(); 2485 | 2486 | int build_options(hdr_tcp*); // insert opts, return len 2487 | int clear_on_timeout_; // clear sender's SACK queue on RTX timeout? 2488 | @@ -309,4 +323,20 @@ protected: 2489 | int h_seqno_; // next seq# to hole-fill 2490 | }; 2491 | 2492 | +class MinTcpAgent : public SackFullTcpAgent { 2493 | +public: 2494 | + virtual void timeout_action(); 2495 | + virtual double rtt_timeout(); 2496 | +// virtual void advance_bytes(int nb); 2497 | +}; 2498 | + 2499 | +class DDTcpAgent : public SackFullTcpAgent { 2500 | + 2501 | + virtual void slowdown(int how); /* reduce cwnd/ssthresh */ 2502 | + virtual int byterm(); 2503 | + virtual int foutput(int seqno, int reason = 0); // output 1 packet 2504 | + virtual int need_send(); // send ACK/win-update now? 2505 | + 2506 | +}; 2507 | + 2508 | #endif 2509 | diff --git a/tcp/tcp-newreno.cc b/tcp/tcp-newreno.cc 2510 | index 48afd64..0c60841 100644 2511 | --- a/tcp/tcp-newreno.cc 2512 | +++ b/tcp/tcp-newreno.cc 2513 | @@ -144,7 +144,10 @@ NewRenoTcpAgent::dupack_action() 2514 | * all unnecessary Fast Retransmits. 2515 | */ 2516 | reset_rtx_timer(1,0); 2517 | - output(last_ack_ + 1, TCP_REASON_DUPACK); 2518 | + /* Mohammad: cut window by half when we have 3 dup ack */ 2519 | + if (ecnhat_) 2520 | + slowdown(CLOSE_SSTHRESH_HALF|CLOSE_CWND_HALF); 2521 | + output(last_ack_ + 1, TCP_REASON_DUPACK); 2522 | dupwnd_ = numdupacks_; 2523 | return; 2524 | } 2525 | @@ -218,9 +221,14 @@ void NewRenoTcpAgent::recv(Packet *pkt, Handler*) 2526 | } 2527 | ++nackpack_; 2528 | ts_peer_ = tcph->ts(); 2529 | - 2530 | + 2531 | + 2532 | + if (ecnhat_) 2533 | + update_ecnhat_alpha(pkt); 2534 | + 2535 | if (hdr_flags::access(pkt)->ecnecho() && ecn_) 2536 | ecn(tcph->seqno()); 2537 | + 2538 | recv_helper(pkt); 2539 | recv_frto_helper(pkt); 2540 | if (tcph->seqno() > last_ack_) { 2541 | diff --git a/tcp/tcp-sink.cc b/tcp/tcp-sink.cc 2542 | index 558f4fb..591155b 100644 2543 | --- a/tcp/tcp-sink.cc 2544 | +++ b/tcp/tcp-sink.cc 2545 | @@ -189,6 +189,7 @@ TcpSink::TcpSink(Acker* acker) : Agent(PT_ACK), acker_(acker), save_(NULL), 2546 | #if defined(TCP_DELAY_BIND_ALL) && 0 2547 | #else /* ! TCP_DELAY_BIND_ALL */ 2548 | bind("maxSackBlocks_", &max_sack_blocks_); // used only by sack 2549 | + bind("ecnhat_", &ecnhat_); 2550 | #endif /* TCP_DELAY_BIND_ALL */ 2551 | } 2552 | 2553 | @@ -203,6 +204,7 @@ TcpSink::delay_bind_init_all() 2554 | delay_bind_init_one("qs_enabled_"); 2555 | delay_bind_init_one("RFC2581_immediate_ack_"); 2556 | delay_bind_init_one("ecn_syn_"); 2557 | + delay_bind_init_one("ecnhat_"); 2558 | #if defined(TCP_DELAY_BIND_ALL) && 0 2559 | delay_bind_init_one("maxSackBlocks_"); 2560 | #endif /* TCP_DELAY_BIND_ALL */ 2561 | @@ -220,6 +222,7 @@ TcpSink::delay_bind_dispatch(const char *varName, const char *localName, TclObje 2562 | if (delay_bind_bool(varName, localName, "qs_enabled_", &qs_enabled_, tracer)) return TCL_OK; 2563 | if (delay_bind_bool(varName, localName, "RFC2581_immediate_ack_", &RFC2581_immediate_ack_, tracer)) return TCL_OK; 2564 | if (delay_bind_bool(varName, localName, "ecn_syn_", &ecn_syn_ ,tracer)) return TCL_OK; 2565 | + if (delay_bind_bool(varName, localName, "ecnhat_", &ecnhat_ ,tracer)) return TCL_OK; 2566 | #if defined(TCP_DELAY_BIND_ALL) && 0 2567 | if (delay_bind(varName, localName, "maxSackBlocks_", &max_sack_blocks_, tracer)) return TCL_OK; 2568 | #endif /* TCP_DELAY_BIND_ALL */ 2569 | @@ -321,9 +324,16 @@ void TcpSink::ack(Packet* opkt) 2570 | (of->ect() && of->ce()) ) 2571 | // New report of congestion. 2572 | acker_->update_ecn_unacked(1); 2573 | - if ( (sf != 0 && sf->ect()) || of->ect() ) 2574 | - // Set EcnEcho bit. 2575 | - nf->ecnecho() = acker_->ecn_unacked(); 2576 | + if ( (sf != 0 && sf->ect()) || of->ect() ) { 2577 | + // Set EcnEcho bit. 2578 | + if (ecnhat_) { 2579 | + if ( (sf != 0 && sf->ect() && sf->ce()) || 2580 | + (of->ect() && of->ce()) ) 2581 | + nf->ecnecho() = 1; 2582 | + else 2583 | + nf->ecnecho() = 0; 2584 | + } else nf->ecnecho() = acker_->ecn_unacked(); 2585 | + } 2586 | if (!of->ect() && of->ecnecho() || 2587 | (sf != 0 && !sf->ect() && sf->ecnecho()) ) { 2588 | // This is the negotiation for ECN-capability. 2589 | diff --git a/tcp/tcp-sink.h b/tcp/tcp-sink.h 2590 | index 13f205f..050e3d9 100644 2591 | --- a/tcp/tcp-sink.h 2592 | +++ b/tcp/tcp-sink.h 2593 | @@ -128,7 +128,7 @@ protected: 2594 | double lastreset_; /* W.N. used for detecting packets */ 2595 | /* from previous incarnations */ 2596 | int ecn_syn_; /* allow SYN/ACK packets to be ECN-capable */ 2597 | - 2598 | + int ecnhat_; /* Mohammad: added to enable ECNHAT receiver behavior */ 2599 | }; 2600 | 2601 | class DelAckSink; 2602 | diff --git a/tcp/tcp.cc b/tcp/tcp.cc 2603 | index 8891f89..867d7cb 100644 2604 | --- a/tcp/tcp.cc 2605 | +++ b/tcp/tcp.cc 2606 | @@ -1,36 +1,3 @@ 2607 | -/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ 2608 | -/* 2609 | - * Copyright (c) 1991-1997 Regents of the University of California. 2610 | - * All rights reserved. 2611 | - * 2612 | - * Redistribution and use in source and binary forms, with or without 2613 | - * modification, are permitted provided that the following conditions 2614 | - * are met: 2615 | - * 1. Redistributions of source code must retain the above copyright 2616 | - * notice, this list of conditions and the following disclaimer. 2617 | - * 2. Redistributions in binary form must reproduce the above copyright 2618 | - * notice, this list of conditions and the following disclaimer in the 2619 | - * documentation and/or other materials provided with the distribution. 2620 | - * 3. All advertising materials mentioning features or use of this software 2621 | - * must display the following acknowledgement: 2622 | - * This product includes software developed by the Computer Systems 2623 | - * Engineering Group at Lawrence Berkeley Laboratory. 2624 | - * 4. Neither the name of the University nor of the Laboratory may be used 2625 | - * to endorse or promote products derived from this software without 2626 | - * specific prior written permission. 2627 | - * 2628 | - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2629 | - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2630 | - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2631 | - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2632 | - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2633 | - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2634 | - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2635 | - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2636 | - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2637 | - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2638 | - * SUCH DAMAGE. 2639 | - */ 2640 | 2641 | #ifndef lint 2642 | static const char rcsid[] = 2643 | @@ -76,7 +43,8 @@ TcpAgent::TcpAgent() 2644 | first_decrease_(1), fcnt_(0), nrexmit_(0), restart_bugfix_(1), 2645 | cong_action_(0), ecn_burst_(0), ecn_backoff_(0), ect_(0), 2646 | use_rtt_(0), qs_requested_(0), qs_approved_(0), 2647 | - qs_window_(0), qs_cwnd_(0), frto_(0) 2648 | + qs_window_(0), qs_cwnd_(0), frto_(0), ecnhat_recalc_seq(0), ecnhat_num_marked(0),ecnhat_total(0), 2649 | + ecnhat_maxseq(0), ecnhat_not_marked(0), ecnhat_mark_period(0), target_wnd(0) , ecnhat_tcp_friendly_increase_(1.0) 2650 | { 2651 | #ifdef TCP_DELAY_BIND_ALL 2652 | // defined since Dec 1999. 2653 | @@ -101,6 +69,15 @@ TcpAgent::TcpAgent() 2654 | bind("necnresponses_", &necnresponses_); 2655 | bind("ncwndcuts_", &ncwndcuts_); 2656 | bind("ncwndcuts1_", &ncwndcuts1_); 2657 | + // Mohammad 2658 | + bind("ecnhat_", &ecnhat_); 2659 | + bind("ecnhat_smooth_alpha_", &ecnhat_smooth_alpha_); 2660 | + bind("ecnhat_alpha_", &ecnhat_alpha_); 2661 | + bind("ecnhat_g_", &ecnhat_g_); 2662 | + bind("ecnhat_enable_beta_", &ecnhat_enable_beta_); 2663 | + bind("ecnhat_beta_", &ecnhat_beta_); 2664 | + bind("ecnhat_quadratic_beta_", &ecnhat_quadratic_beta_); 2665 | + bind("ecnhat_tcp_friendly_", &ecnhat_tcp_friendly_); 2666 | #endif /* TCP_DELAY_BIND_ALL */ 2667 | 2668 | } 2669 | @@ -123,6 +100,16 @@ TcpAgent::delay_bind_init_all() 2670 | delay_bind_init_one("overhead_"); 2671 | delay_bind_init_one("tcpTick_"); 2672 | delay_bind_init_one("ecn_"); 2673 | + // Mohammad 2674 | + delay_bind_init_one("ecnhat_"); 2675 | + delay_bind_init_one("ecnhat_smooth_alpha_"); 2676 | + delay_bind_init_one("ecnhat_alpha_"); 2677 | + delay_bind_init_one("ecnhat_g_"); 2678 | + delay_bind_init_one("ecnhat_beta_"); 2679 | + delay_bind_init_one("ecnhat_enable_beta_"); 2680 | + delay_bind_init_one("ecnhat_quadratic_beta_"); 2681 | + delay_bind_init_one("ecnhat_tcp_friendly_"); 2682 | + 2683 | delay_bind_init_one("SetCWRonRetransmit_"); 2684 | delay_bind_init_one("old_ecn_"); 2685 | delay_bind_init_one("bugfix_ss_"); 2686 | @@ -234,7 +221,17 @@ TcpAgent::delay_bind_dispatch(const char *varName, const char *localName, TclObj 2687 | if (delay_bind(varName, localName, "overhead_", &overhead_, tracer)) return TCL_OK; 2688 | if (delay_bind(varName, localName, "tcpTick_", &tcp_tick_, tracer)) return TCL_OK; 2689 | if (delay_bind_bool(varName, localName, "ecn_", &ecn_, tracer)) return TCL_OK; 2690 | - if (delay_bind_bool(varName, localName, "SetCWRonRetransmit_", &SetCWRonRetransmit_, tracer)) return TCL_OK; 2691 | + // Mohammad 2692 | + if (delay_bind_bool(varName, localName, "ecnhat_", &ecnhat_, tracer)) return TCL_OK; 2693 | + if (delay_bind_bool(varName, localName, "ecnhat_smooth_alpha_", &ecnhat_smooth_alpha_, tracer)) return TCL_OK; 2694 | + if (delay_bind(varName, localName, "ecnhat_alpha_", &ecnhat_alpha_ , tracer)) return TCL_OK; 2695 | + if (delay_bind(varName, localName, "ecnhat_g_", &ecnhat_g_ , tracer)) return TCL_OK; 2696 | + if (delay_bind_bool(varName, localName, "ecnhat_enable_beta_", &ecnhat_enable_beta_ , tracer)) return TCL_OK; 2697 | + if (delay_bind(varName, localName, "ecnhat_beta_", &ecnhat_beta_ , tracer)) return TCL_OK; 2698 | + if (delay_bind_bool(varName, localName, "ecnhat_quadratic_beta_", &ecnhat_quadratic_beta_ , tracer)) return TCL_OK; 2699 | + if (delay_bind_bool(varName, localName, "ecnhat_tcp_friendly_", &ecnhat_tcp_friendly_, tracer)) return TCL_OK; 2700 | + 2701 | + if (delay_bind_bool(varName, localName, "SetCWRonRetransmit_", &SetCWRonRetransmit_, tracer)) return TCL_OK; 2702 | if (delay_bind_bool(varName, localName, "old_ecn_", &old_ecn_ , tracer)) return TCL_OK; 2703 | if (delay_bind_bool(varName, localName, "bugfix_ss_", &bugfix_ss_ , tracer)) return TCL_OK; 2704 | if (delay_bind(varName, localName, "eln_", &eln_ , tracer)) return TCL_OK; 2705 | @@ -546,10 +543,12 @@ double TcpAgent::rtt_timeout() 2706 | if (timeout > maxrto_) 2707 | timeout = maxrto_; 2708 | 2709 | - if (timeout < 2.0 * tcp_tick_) { 2710 | + if (timeout < 2.0 * tcp_tick_) { 2711 | if (timeout < 0) { 2712 | fprintf(stderr, "TcpAgent: negative RTO! (%f)\n", 2713 | timeout); 2714 | + fflush(stdout); 2715 | + fflush(stderr); 2716 | exit(1); 2717 | } else if (use_rtt_ && timeout < tcp_tick_) 2718 | timeout = tcp_tick_; 2719 | @@ -565,6 +564,7 @@ double TcpAgent::rtt_timeout() 2720 | void TcpAgent::rtt_update(double tao) 2721 | { 2722 | double now = Scheduler::instance().clock(); 2723 | + //printf("%f\n", tao); 2724 | if (ts_option_) 2725 | t_rtt_ = int(tao /tcp_tick_ + 0.5); 2726 | else { 2727 | @@ -610,7 +610,8 @@ void TcpAgent::rtt_update(double tao) 2728 | 2729 | void TcpAgent::rtt_backoff() 2730 | { 2731 | - if (t_backoff_ < 64 || rfc2988_) 2732 | + //if (t_backoff_ < 64 || rfc2988_) 2733 | + if (t_backoff_ < 64 || (rfc2988_ && rtt_timeout() < maxrto_)) 2734 | t_backoff_ <<= 1; 2735 | // RFC2988 allows a maximum for the backed-off RTO of 60 seconds. 2736 | // This is applied by maxrto_. 2737 | @@ -665,14 +666,17 @@ void TcpAgent::output(int seqno, int reason) 2738 | // (A real TCP would use scoreboard for this.) 2739 | if (bugfix_ts_ && tss==NULL) { 2740 | tss = (double*) calloc(tss_size_, sizeof(double)); 2741 | - if (tss==NULL) exit(1); 2742 | + if (tss==NULL) { 2743 | + fflush(stdout); 2744 | + exit(1); 2745 | + } 2746 | } 2747 | //dynamically grow the timestamp array if it's getting full 2748 | if (bugfix_ts_ && ((seqno - highest_ack_) > tss_size_* 0.9)) { 2749 | double *ntss; 2750 | ntss = (double*) calloc(tss_size_*2, sizeof(double)); 2751 | printf("%p resizing timestamp table\n", this); 2752 | - if (ntss == NULL) exit(1); 2753 | + if (ntss == NULL) { fflush(stdout); exit(1);} 2754 | for (int i=0; i> T_SRTT_BITS)*tcp_tick_ / 0.0004);// * ((int(t_srtt_) >> T_SRTT_BITS)*tcp_tick_ / 0.0004); 2780 | + //printf("increase_factor = %f, s_rtt = %f\n", ecnhat_tcp_friendly_increase_, (int(t_srtt_) >> T_SRTT_BITS)*tcp_tick_); 2781 | + increment = ecnhat_tcp_friendly_increase_ / cwnd_; 2782 | + //increment = increase_num_ / cwnd_; 2783 | + } 2784 | + else 2785 | + increment = increase_num_ / cwnd_; 2786 | + 2787 | if ((last_cwnd_action_ == 0 || 2788 | last_cwnd_action_ == CWND_ACTION_TIMEOUT) 2789 | && max_ssthresh_ > 0) { 2790 | increment = limited_slow_start(cwnd_, 2791 | max_ssthresh_, increment); 2792 | } 2793 | + //printf("%f: target = %f cwnd = %f\n", Scheduler::instance().clock(), target_wnd, (double) cwnd_); 2794 | + /*if (1) { 2795 | + target_wnd += increment; 2796 | + cwnd_ += (target_wnd - cwnd_)/2.0/cwnd_; 2797 | + } else*/ 2798 | cwnd_ += increment; 2799 | + 2800 | break; 2801 | 2802 | case 2: 2803 | @@ -1245,6 +1270,8 @@ TcpAgent::slowdown(int how) 2804 | if (!(how & TCP_IDLE) && !(how & NO_OUTSTANDING_DATA)){ 2805 | ++ncwndcuts1_; 2806 | } 2807 | + 2808 | + //ecnhat_alpha_ = 0.07; 2809 | // we are in slowstart for sure if cwnd < ssthresh 2810 | if (cwnd_ < ssthresh_) 2811 | slowstart = 1; 2812 | @@ -1264,6 +1291,7 @@ TcpAgent::slowdown(int how) 2813 | decreasewin = decrease_num_ * windowd(); 2814 | } 2815 | win = windowd(); 2816 | + //printf("decrease param = %f window = %f decwin = %f\n", decrease_num_, win, decreasewin); 2817 | } else { 2818 | int temp; 2819 | temp = (int)(window() / 2); 2820 | @@ -1295,6 +1323,9 @@ TcpAgent::slowdown(int how) 2821 | } else { 2822 | ssthresh_ = (int) decreasewin; 2823 | } 2824 | + else if (how & CLOSE_SSTHRESH_ECNHAT) 2825 | + ssthresh_ = (int) ((1 - ecnhat_alpha_/2.0) * windowd()); 2826 | + //ssthresh_ = (int) (windowd() - sqrt(2*windowd())/2.0); 2827 | else if (how & THREE_QUARTER_SSTHRESH) 2828 | if (ssthresh_ < 3*cwnd_/4) 2829 | ssthresh_ = (int)(3*cwnd_/4); 2830 | @@ -1304,7 +1335,10 @@ TcpAgent::slowdown(int how) 2831 | if (first_decrease_ == 1 || slowstart || decrease_num_ == 0.5) { 2832 | cwnd_ = halfwin; 2833 | } else cwnd_ = decreasewin; 2834 | - else if (how & CWND_HALF_WITH_MIN) { 2835 | + else if (how & CLOSE_CWND_ECNHAT) 2836 | + cwnd_ = (1 - ecnhat_alpha_/2.0) * windowd(); 2837 | + //cwnd_ = windowd() - sqrt(2*windowd())/2.0; 2838 | + else if (how & CWND_HALF_WITH_MIN) { 2839 | // We have not thought about how non-standard TCPs, with 2840 | // non-standard values of decrease_num_, should respond 2841 | // after quiescent periods. 2842 | @@ -1314,8 +1348,8 @@ TcpAgent::slowdown(int how) 2843 | } 2844 | else if (how & CLOSE_CWND_RESTART) 2845 | cwnd_ = int(wnd_restart_); 2846 | - else if (how & CLOSE_CWND_INIT) 2847 | - cwnd_ = int(wnd_init_); 2848 | + else if (how & CLOSE_CWND_INIT) 2849 | + cwnd_ = int(wnd_init_); 2850 | else if (how & CLOSE_CWND_ONE) 2851 | cwnd_ = 1; 2852 | else if (how & CLOSE_CWND_HALF_WAY) { 2853 | @@ -1326,7 +1360,9 @@ TcpAgent::slowdown(int how) 2854 | } 2855 | if (ssthresh_ < 2) 2856 | ssthresh_ = 2; 2857 | - if (how & (CLOSE_CWND_HALF|CLOSE_CWND_RESTART|CLOSE_CWND_INIT|CLOSE_CWND_ONE)) 2858 | + if (cwnd_ < 1) 2859 | + cwnd_ = 1; // Added by Mohammad 2860 | + if (how & (CLOSE_CWND_HALF|CLOSE_CWND_RESTART|CLOSE_CWND_INIT|CLOSE_CWND_ONE|CLOSE_CWND_ECNHAT)) 2861 | cong_action_ = TRUE; 2862 | 2863 | fcnt_ = count_ = 0; 2864 | @@ -1418,20 +1454,73 @@ void TcpAgent::newack(Packet* pkt) 2865 | */ 2866 | void TcpAgent::ecn(int seqno) 2867 | { 2868 | - if (seqno > recover_ || 2869 | - last_cwnd_action_ == CWND_ACTION_TIMEOUT) { 2870 | + if (seqno > recover_ || 2871 | + last_cwnd_action_ == CWND_ACTION_TIMEOUT) { 2872 | recover_ = maxseq_; 2873 | last_cwnd_action_ = CWND_ACTION_ECN; 2874 | if (cwnd_ <= 1.0) { 2875 | if (ecn_backoff_) 2876 | rtt_backoff(); 2877 | else ecn_backoff_ = 1; 2878 | - } else ecn_backoff_ = 0; 2879 | - slowdown(CLOSE_CWND_HALF|CLOSE_SSTHRESH_HALF); 2880 | + } else ecn_backoff_ = 0; 2881 | + if (ecnhat_) { 2882 | + if (ecnhat_tcp_friendly_) { 2883 | + target_wnd = cwnd_; 2884 | + //printf("changed target wnd = %f\n", target_wnd); 2885 | + ecnhat_tcp_friendly_increase_ = 1.5/(2.0/ecnhat_alpha_ - 0.5); 2886 | + } 2887 | + slowdown(CLOSE_CWND_ECNHAT|CLOSE_SSTHRESH_ECNHAT); 2888 | + 2889 | + } 2890 | + 2891 | + else 2892 | + slowdown(CLOSE_CWND_HALF|CLOSE_SSTHRESH_HALF); 2893 | ++necnresponses_ ; 2894 | // added by sylvia to count number of ecn responses 2895 | + } 2896 | +} 2897 | + 2898 | +/* 2899 | + * Mohammad: Update ecnhat alpha based on the ecn bit in the received packet. 2900 | + * 2901 | + * This procedure is called only when ecnhat_ is 1. 2902 | + */ 2903 | +void TcpAgent::update_ecnhat_alpha(Packet *pkt) 2904 | +{ 2905 | + int ecnbit = hdr_flags::access(pkt)->ecnecho(); 2906 | + int ackno = hdr_tcp::access(pkt)->ackno(); 2907 | + 2908 | + if (!ecnhat_smooth_alpha_) 2909 | + ecnhat_alpha_ = (1 - ecnhat_g_) * ecnhat_alpha_ + ecnhat_g_ * ecnbit; 2910 | + else { 2911 | + int acked_bytes = ackno - highest_ack_; 2912 | + if (acked_bytes <= 0) 2913 | + acked_bytes = size_; 2914 | + //printf("size_ = %d, acked_bytes = %d\n",size_, acked_bytes); 2915 | + //ecnhat_total++; 2916 | + ecnhat_total += acked_bytes; 2917 | + if (ecnbit) { 2918 | + //ecnhat_num_marked++; 2919 | + ecnhat_num_marked += acked_bytes; 2920 | + ecnhat_beta_ = 1; 2921 | + } 2922 | + if (ackno > ecnhat_recalc_seq) { 2923 | + double temp_alpha; 2924 | + ecnhat_recalc_seq = ecnhat_maxseq; 2925 | + if (ecnhat_total > 0) { 2926 | + temp_alpha = ((double) ecnhat_num_marked) / ecnhat_total; 2927 | + } else temp_alpha = 0.0; 2928 | + 2929 | + 2930 | + //printf("%f %f %f %f\n", Scheduler::instance().clock(), (double) cwnd_, temp_alpha, ecnhat_alpha_); 2931 | + ecnhat_alpha_ = (1 - ecnhat_g_) * ecnhat_alpha_ + ecnhat_g_ * temp_alpha; 2932 | + ecnhat_num_marked = 0; 2933 | + ecnhat_total = 0; 2934 | + } 2935 | } 2936 | + 2937 | } 2938 | + 2939 | 2940 | /* 2941 | * Is the connection limited by the network (instead of by a lack 2942 | @@ -1453,6 +1542,7 @@ void TcpAgent::recv_newack_helper(Packet *pkt) { 2943 | // We can exit the Quick-Start phase. 2944 | qs_window_ = 0; 2945 | } 2946 | + 2947 | if (!ect_ || !hdr_flags::access(pkt)->ecnecho() || 2948 | (old_ecn_ && ecn_burst_)) { 2949 | /* If "old_ecn", this is not the first ACK carrying ECN-Echo 2950 | @@ -1797,8 +1887,10 @@ void TcpAgent::recv(Packet *pkt, Handler*) 2951 | ++nackpack_; 2952 | ts_peer_ = tcph->ts(); 2953 | int ecnecho = hdr_flags::access(pkt)->ecnecho(); 2954 | - if (ecnecho && ecn_) 2955 | + 2956 | + if (ecnecho && ecn_) 2957 | ecn(tcph->seqno()); 2958 | + 2959 | recv_helper(pkt); 2960 | recv_frto_helper(pkt); 2961 | /* grow cwnd and check if the connection is done */ 2962 | @@ -1812,6 +1904,7 @@ void TcpAgent::recv(Packet *pkt, Handler*) 2963 | tcp_eln(pkt); 2964 | return; 2965 | } 2966 | +printf("dupacks= %d\n",dupacks_+1); 2967 | if (++dupacks_ == numdupacks_ && !noFastRetrans_) { 2968 | dupack_action(); 2969 | } else if (dupacks_ < numdupacks_ && singledup_ ) { 2970 | diff --git a/tcp/tcp.h b/tcp/tcp.h 2971 | index 13dce25..1edb56d 100644 2972 | --- a/tcp/tcp.h 2973 | +++ b/tcp/tcp.h 2974 | @@ -1,37 +1,3 @@ 2975 | -/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ /* 2976 | - * Copyright (c) 1991-1997 Regents of the University of California. 2977 | - * All rights reserved. 2978 | - * 2979 | - * Redistribution and use in source and binary forms, with or without 2980 | - * modification, are permitted provided that the following conditions 2981 | - * are met: 2982 | - * 1. Redistributions of source code must retain the above copyright 2983 | - * notice, this list of conditions and the following disclaimer. 2984 | - * 2. Redistributions in binary form must reproduce the above copyright 2985 | - * notice, this list of conditions and the following disclaimer in the 2986 | - * documentation and/or other materials provided with the distribution. 2987 | - * 3. All advertising materials mentioning features or use of this software 2988 | - * must display the following acknowledgement: 2989 | - * This product includes software developed by the Computer Systems 2990 | - * Engineering Group at Lawrence Berkeley Laboratory. 2991 | - * 4. Neither the name of the University nor of the Laboratory may be used 2992 | - * to endorse or promote products derived from this software without 2993 | - * specific prior written permission. 2994 | - * 2995 | - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2996 | - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2997 | - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2998 | - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2999 | - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3000 | - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3001 | - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3002 | - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3003 | - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3004 | - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3005 | - * SUCH DAMAGE. 3006 | - * 3007 | - * @(#) $Header: /cvsroot/nsnam/ns-2/tcp/tcp.h,v 1.130 2007/09/29 01:07:22 sallyfloyd Exp $ (LBL) 3008 | - */ 3009 | #ifndef ns_tcp_h 3010 | #define ns_tcp_h 3011 | 3012 | @@ -104,6 +70,9 @@ struct hdr_tcp { 3013 | #define CWND_HALF_WITH_MIN 0x00000200 3014 | #define TCP_IDLE 0x00000400 3015 | #define NO_OUTSTANDING_DATA 0x00000800 3016 | +#define CLOSE_SSTHRESH_ECNHAT 0x00001000 3017 | +#define CLOSE_CWND_ECNHAT 0x00002000 3018 | + 3019 | 3020 | /* 3021 | * tcp_tick_: 3022 | @@ -194,7 +163,7 @@ protected: 3023 | 3024 | virtual void delay_bind_init_all(); 3025 | virtual int delay_bind_dispatch(const char *varName, const char *localName, TclObject *tracer); 3026 | - 3027 | + 3028 | double boot_time_; /* where between 'ticks' this sytem came up */ 3029 | double overhead_; 3030 | double wnd_; 3031 | @@ -215,14 +184,14 @@ protected: 3032 | /* windows */ 3033 | 3034 | /* connection and packet dynamics */ 3035 | - virtual void output(int seqno, int reason = 0); 3036 | +virtual void output(int seqno, int reason = 0); 3037 | virtual void send_much(int force, int reason, int maxburst = 0); 3038 | virtual void newtimer(Packet*); 3039 | virtual void dupack_action(); /* do this on dupacks */ 3040 | virtual void send_one(); /* do this on 1-2 dupacks */ 3041 | virtual void opencwnd(); 3042 | 3043 | - void slowdown(int how); /* reduce cwnd/ssthresh */ 3044 | + virtual void slowdown(int how); /* reduce cwnd/ssthresh */ 3045 | void ecn(int seqno); /* react to quench */ 3046 | virtual void set_initial_window(); /* set IW */ 3047 | double initial_window(); /* what is IW? */ 3048 | @@ -316,7 +285,7 @@ protected: 3049 | void spurious_timeout(); 3050 | 3051 | /* Timers */ 3052 | - RtxTimer rtx_timer_; 3053 | + RtxTimer rtx_timer_; 3054 | DelSndTimer delsnd_timer_; 3055 | BurstSndTimer burstsnd_timer_; 3056 | virtual void cancel_timers() { 3057 | @@ -427,6 +396,28 @@ protected: 3058 | 3059 | /* Used for ECN */ 3060 | int ecn_; /* Explicit Congestion Notification */ 3061 | + 3062 | + /* Mohammad: added for Ecn-Hat */ 3063 | + int ecnhat_; 3064 | + int ecnhat_smooth_alpha_; 3065 | + double ecnhat_g_; 3066 | + double ecnhat_alpha_; 3067 | + int ecnhat_recalc_seq; 3068 | + int ecnhat_maxseq; 3069 | + int ecnhat_num_marked; 3070 | + int ecnhat_total; 3071 | + int ecnhat_enable_beta_; 3072 | + double ecnhat_beta_; 3073 | + int ecnhat_quadratic_beta_; 3074 | + int ecnhat_tcp_friendly_; 3075 | + double ecnhat_tcp_friendly_increase_; 3076 | + int ecnhat_not_marked; 3077 | + double ecnhat_mark_period; 3078 | + int dctcp_enable_ap; 3079 | + double target_wnd; 3080 | + 3081 | + void update_ecnhat_alpha(Packet *pkt); /* updates the ecnhat alpha value */ 3082 | + 3083 | int cong_action_; /* Congestion Action. True to indicate 3084 | that the sender responded to congestion. */ 3085 | int ecn_burst_; /* True when the previous ACK packet 3086 | diff --git a/tools/queue-monitor.cc b/tools/queue-monitor.cc 3087 | index 3ca513b..bd512ba 100644 3088 | --- a/tools/queue-monitor.cc 3089 | +++ b/tools/queue-monitor.cc 3090 | @@ -41,6 +41,8 @@ static const char rcsid[] = 3091 | #include "trace.h" 3092 | #include 3093 | 3094 | +#include "ip.h" 3095 | + 3096 | int QueueMonitor::command(int argc, const char*const* argv) 3097 | { 3098 | Tcl& tcl = Tcl::instance(); 3099 | @@ -245,6 +247,20 @@ void QueueMonitor::in(Packet* p) 3100 | prevTime_ = now; 3101 | } 3102 | 3103 | + //Shuang: count small flow arrivals 3104 | + hdr_ip* iph = hdr_ip::access(p); 3105 | + int prio = iph->prio() / 1460; 3106 | + if (prio < 100000 && pktsz > 100) { 3107 | + karrivals_[calc_prio(prio)] ++; 3108 | + } 3109 | + 3110 | + //Shuang: count ack arrivals 3111 | + //hdr_rcp* rh = hdr_rcp::access(p); 3112 | + //if (rh->RCP_pkt_type() == RCP_ACK) { 3113 | + // ack_arrivals_++; 3114 | + //} 3115 | + 3116 | + 3117 | barrivals_ += pktsz; 3118 | parrivals_++; 3119 | size_ += pktsz; 3120 | @@ -273,6 +289,13 @@ void QueueMonitor::out(Packet* p) 3121 | pkts_--; 3122 | bdepartures_ += pktsz; 3123 | pdepartures_++; 3124 | + 3125 | + //Shuang: count ack departure 3126 | + //hdr_rcp* rh = hdr_rcp::access(p); 3127 | + //if (rh->RCP_pkt_type() == RCP_ACK) { 3128 | + // ack_departures_++; 3129 | + //} 3130 | + 3131 | if (bytesInt_) 3132 | bytesInt_->newPoint(now, double(size_)); 3133 | if (pktsInt_) 3134 | @@ -302,6 +325,19 @@ void QueueMonitor::drop(Packet* p) 3135 | bdrops_ += pktsz; 3136 | pdrops_++; 3137 | 3138 | + //Shuang: count small flow dropping 3139 | + hdr_ip* iph = hdr_ip::access(p); 3140 | + int prio = iph->prio() / 1460; 3141 | + if (prio < 100000 && pktsz > 100) { 3142 | + kdrops_[calc_prio(prio)] ++; 3143 | + } 3144 | + //Shuang: count ack dropping 3145 | + //hdr_rcp* rh = hdr_rcp::access(p); 3146 | + //if (rh->RCP_pkt_type() == RCP_ACK) { 3147 | + // ack_drops_++; 3148 | + //} 3149 | + 3150 | + 3151 | if (pf->qs()) 3152 | qs_drops_++; 3153 | 3154 | @@ -313,6 +349,20 @@ void QueueMonitor::drop(Packet* p) 3155 | printStats(); 3156 | } 3157 | 3158 | +int QueueMonitor::calc_prio(int prio) 3159 | +{ 3160 | + if (prio <= 10) 3161 | + return prio; 3162 | + if (prio <= 100) 3163 | + return 10 + prio / 10; 3164 | + if (prio <= 1000) 3165 | + return 20 + prio / 100; 3166 | + if (prio <= 10000) 3167 | + return 30 + prio / 1000; 3168 | + if (prio <= 100000) 3169 | + return 40 + prio / 10000; 3170 | +} 3171 | + 3172 | // The procedure to estimate the rate of the incoming traffic 3173 | void QueueMonitor::estimateRate(Packet *pkt) { 3174 | 3175 | @@ -448,7 +498,6 @@ public: 3176 | * ############################################################ 3177 | */ 3178 | 3179 | -#include "ip.h" 3180 | QueueMonitorCompat::QueueMonitorCompat() 3181 | { 3182 | memset(pkts_, 0, sizeof(pkts_)); 3183 | diff --git a/tools/queue-monitor.h b/tools/queue-monitor.h 3184 | index 789c8db..bd8fb1c 100644 3185 | --- a/tools/queue-monitor.h 3186 | +++ b/tools/queue-monitor.h 3187 | @@ -49,7 +49,8 @@ public: 3188 | size_(0), pkts_(0), 3189 | parrivals_(0), barrivals_(0), 3190 | pdepartures_(0), bdepartures_(0), 3191 | - pdrops_(0), pmarks_(0), bdrops_(0), 3192 | + pdrops_(0), pmarks_(0), bdrops_(0), num_monitor_(50), 3193 | + ack_arrivals_(0), ack_drops_(0), ack_departures_(0), 3194 | qs_pkts_(0), qs_bytes_(0), qs_drops_(0), 3195 | keepRTTstats_(0), maxRTT_(1), numRTTs_(0), binsPerSec_(10), 3196 | keepSeqnoStats_(0), maxSeqno_(1000), 3197 | @@ -59,7 +60,22 @@ public: 3198 | k_(0.1), 3199 | estRate_(0.0), 3200 | temp_size_(0) { 3201 | - 3202 | + 3203 | + //Shuang: monitor the kth drop 3204 | + for (int i = 0; i < num_monitor_; i++) { 3205 | + char buf[20]; 3206 | + memset(buf, 0, sizeof(buf)); 3207 | + sprintf(buf, "kdrops%d", i); 3208 | + bind(buf, &kdrops_[i]); 3209 | + memset(buf, 0, sizeof(buf)); 3210 | + sprintf(buf, "karrivals%d", i); 3211 | + bind(buf, &karrivals_[i]); 3212 | + } 3213 | + bind("num_monitor_", &num_monitor_); 3214 | + bind("ack_arrivals_", &ack_arrivals_); 3215 | + bind("ack_drops_", &ack_drops_); 3216 | + bind("ack_departures_", &ack_departures_); 3217 | + 3218 | bind("size_", &size_); 3219 | bind("pkts_", &pkts_); 3220 | bind("parrivals_", &parrivals_); 3221 | @@ -150,6 +166,12 @@ protected: 3222 | int pdrops_; 3223 | int pmarks_; 3224 | int bdrops_; 3225 | + int kdrops_[50]; //Shuang: count the num of kth drop 3226 | + int karrivals_[50]; //Shuang: count the num of kth arrival 3227 | + int num_monitor_; //Shuang: maximum of k to monitor 3228 | + int ack_arrivals_; //Shuang: number of ack pkts arrival 3229 | + int ack_drops_; //Shuang: number of ack pkts dropped 3230 | + int ack_departures_; //Shuang: number of ack pkts departured 3231 | 3232 | int qs_pkts_; /* Number of Quick-Start packets */ 3233 | int qs_bytes_; /* Number of Quick-Start bytes */ 3234 | @@ -192,6 +214,7 @@ protected: 3235 | void estimateRate(Packet *p); 3236 | void keepRTTstats(Packet *p); 3237 | void keepSeqnoStats(Packet *p); 3238 | + int calc_prio(int prio); 3239 | }; 3240 | 3241 | class SnoopQueue : public Connector { 3242 | -- 3243 | 1.7.7.6 3244 | 3245 | 3246 | From 0b821f32f4b95c7acfa1fcfc7f2edd558aab132b Mon Sep 17 00:00:00 2001 3247 | From: Mohammad Alizadeh 3248 | Date: Sun, 20 Jul 2014 22:47:28 -0700 3249 | Subject: [PATCH 2/2] Fixed a nasty bug which breaks ECN marking for DCTCP. 3250 | 3251 | --- 3252 | queue/red.cc | 2 +- 3253 | 1 files changed, 1 insertions(+), 1 deletions(-) 3254 | 3255 | diff --git a/queue/red.cc b/queue/red.cc 3256 | index 5a9c292..2cfe743 100644 3257 | --- a/queue/red.cc 3258 | +++ b/queue/red.cc 3259 | @@ -560,7 +560,7 @@ REDQueue::drop_early(Packet* pkt) 3260 | edv_.count_bytes = 0; 3261 | hdr_flags* hf = hdr_flags::access(pickPacketForECN(pkt)); 3262 | if (edp_.setbit && hf->ect() && 3263 | - (!edp_.use_mark_p || edv_.v_prob1 < edp_.mark_p)) { 3264 | + (!edp_.use_mark_p || edv_.v_prob1 <= edp_.mark_p)) { // Mohammad: I changed < to <= 3265 | hf->ce() = 1; // mark Congestion Experienced bit 3266 | // Tell the queue monitor here - call emark(pkt) 3267 | return (0); // no drop 3268 | -- 3269 | 1.7.7.6 3270 | 3271 | -------------------------------------------------------------------------------- /qjump.tcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015, The Board of Trustees of The Leland Stanford Junior 2 | # University. All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # * Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # * Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # * Neither the name of copyright holder nor the names of the contributors may 15 | # be used to endorse or promote products derived from this software without 16 | # specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | source "tcp-common-opt.tcl" 30 | 31 | #add/remove packet headers as required 32 | #this must be done before create simulator, i.e., [new Simulator] 33 | #remove-all-packet-headers ;# removes all except common 34 | #add-packet-header Flags IP RCP ;#hdrs reqd for RCP traffic 35 | 36 | set ns [new Simulator] 37 | puts "Date: [clock format [clock seconds]]" 38 | set sim_start [clock seconds] 39 | puts "Host: [exec uname -a]" 40 | 41 | #set trace_file [open qjump.tr w] 42 | #$ns trace-all $trace_file 43 | 44 | if {$argc != 43} { 45 | puts "wrong number of arguments, expected 43, got $argc" 46 | exit 0 47 | } 48 | 49 | set sim_end [lindex $argv 0] 50 | set link_rate [lindex $argv 1] 51 | set mean_link_delay [lindex $argv 2] 52 | set host_delay [lindex $argv 3] 53 | set queueSize [lindex $argv 4] 54 | set load [lindex $argv 5] 55 | set connections_per_pair [lindex $argv 6] 56 | set meanFlowSize [lindex $argv 7] 57 | set paretoShape [lindex $argv 8] 58 | #### Multipath 59 | set enableMultiPath [lindex $argv 9] 60 | set perflowMP [lindex $argv 10] 61 | #### Transport settings options 62 | set sourceAlg [lindex $argv 11] ; # Sack or DCTCP-Sack 63 | set ackRatio [lindex $argv 12] 64 | set enableHRTimer 0 65 | set slowstartrestart [lindex $argv 13] 66 | set DCTCP_g [lindex $argv 14] ; # DCTCP alpha estimation gain 67 | #### Switch side options 68 | set switchAlg [lindex $argv 15] 69 | set DCTCP_K [lindex $argv 16] 70 | # Phantom Queue settings 71 | set enablePQ [lindex $argv 17] 72 | set PQ_mode [lindex $argv 18] 73 | set PQ_gamma [lindex $argv 19] 74 | set PQ_thresh [lindex $argv 20] 75 | ### Pacer settings 76 | set enablePacer [lindex $argv 21] 77 | set TBFsPerServer [lindex $argv 22] 78 | set Pacer_qlength_factor [lindex $argv 23] 79 | set Pacer_rate_ave_factor [lindex $argv 24] 80 | set Pacer_rate_update_interval [lindex $argv 25] 81 | set Pacer_assoc_prob [lindex $argv 26] 82 | set Pacer_assoc_timeout [lindex $argv 27] 83 | #### topology 84 | set topology_spt [lindex $argv 28] 85 | set topology_tors [lindex $argv 29] 86 | set topology_spines [lindex $argv 30] 87 | set topology_x [lindex $argv 31] 88 | #### NAM 89 | set enableNAM [lindex $argv 32] 90 | set min_rto [lindex $argv 33] 91 | set drop_prio_ [lindex $argv 34] 92 | set prio_scheme_ [lindex $argv 35] 93 | set deque_prio_ [lindex $argv 36] 94 | set prob_cap_ [lindex $argv 37] 95 | set keep_order_ [lindex $argv 38] 96 | set enable_dctcp [lindex $argv 39] 97 | set enable_pfabric [lindex $argv 40] 98 | set enable_qjump [lindex $argv 41] 99 | set FLOW_CDF [lindex $argv 42] 100 | 101 | #### Packet size is in bytes. 102 | set pktSize 1460 103 | #### trace frequency 104 | set queueSamplingInterval 0.0001 105 | #set queueSamplingInterval 1 106 | 107 | puts "Simulation input:" 108 | puts "Dynamic Flow - Pareto" 109 | puts "topology: spines server per rack = $topology_spt, x = $topology_x" 110 | puts "sim_end $sim_end" 111 | puts "link_rate $link_rate Gbps" 112 | puts "link_delay $mean_link_delay sec" 113 | puts "RTT [expr $mean_link_delay * 2.0 * 6] sec" 114 | puts "host_delay $host_delay sec" 115 | puts "queue size $queueSize pkts" 116 | puts "load $load" 117 | puts "connections_per_pair $connections_per_pair" 118 | puts "enableMultiPath=$enableMultiPath, perflowMP=$perflowMP" 119 | puts "source algorithm: $sourceAlg" 120 | puts "ackRatio $ackRatio" 121 | puts "DCTCP_g $DCTCP_g" 122 | puts "HR-Timer $enableHRTimer" 123 | puts "slow-start Restart $slowstartrestart" 124 | puts "switch algorithm $switchAlg" 125 | puts "DCTCP_K_ $DCTCP_K" 126 | puts "enablePQ $enablePQ" 127 | puts "PQ_mode $PQ_mode" 128 | puts "PQ_gamma $PQ_gamma" 129 | puts "PQ_thresh $PQ_thresh" 130 | puts "enablePacer $enablePacer" 131 | puts "TBFsPerServer $TBFsPerServer" 132 | puts "Pacer_qlength_factor $Pacer_qlength_factor" 133 | puts "Pacer_rate_ave_factor $Pacer_rate_ave_factor" 134 | puts "Pacer_rate_update_interval $Pacer_rate_update_interval" 135 | puts "Pacer_assoc_prob $Pacer_assoc_prob" 136 | puts "Pacer_assoc_timeout $Pacer_assoc_timeout" 137 | puts "pktSize(payload) $pktSize Bytes" 138 | puts "pktSize(include header) [expr $pktSize + 40] Bytes" 139 | 140 | puts "enableNAM $enableNAM" 141 | puts " " 142 | 143 | ################# Transport Options #################### 144 | 145 | Agent/TCP set ecn_ 1 146 | Agent/TCP set old_ecn_ 1 147 | Agent/TCP set packetSize_ $pktSize 148 | Agent/TCP/FullTcp set segsize_ $pktSize 149 | Agent/TCP/FullTcp set spa_thresh_ 0 150 | Agent/TCP set window_ 64 151 | Agent/TCP set windowInit_ 2 152 | Agent/TCP set slow_start_restart_ $slowstartrestart 153 | Agent/TCP set windowOption_ 0 154 | Agent/TCP set tcpTick_ 0.000001 155 | Agent/TCP set minrto_ $min_rto 156 | Agent/TCP set maxrto_ 2 157 | 158 | Agent/TCP/FullTcp set nodelay_ true; # disable Nagle 159 | Agent/TCP/FullTcp set segsperack_ $ackRatio; 160 | Agent/TCP/FullTcp set interval_ 0.000006 161 | if {$perflowMP == 0} { 162 | Agent/TCP/FullTcp set dynamic_dupack_ 0.75 163 | } 164 | if {$ackRatio > 2} { 165 | Agent/TCP/FullTcp set spa_thresh_ [expr ($ackRatio - 1) * $pktSize] 166 | } 167 | if {$enableHRTimer != 0} { 168 | Agent/TCP set minrto_ 0.00100 ; # 1ms 169 | Agent/TCP set tcpTick_ 0.000001 170 | } 171 | if {[string compare $sourceAlg "DCTCP-Sack"] == 0} { 172 | Agent/TCP set ecnhat_ true 173 | Agent/TCPSink set ecnhat_ true 174 | Agent/TCP set ecnhat_g_ $DCTCP_g; 175 | } 176 | #Shuang 177 | Agent/TCP/FullTcp set prio_scheme_ $prio_scheme_; 178 | Agent/TCP/FullTcp set dynamic_dupack_ 1000000; #disable dupack 179 | Agent/TCP set window_ 1000000 180 | Agent/TCP set windowInit_ 12 181 | Agent/TCP set rtxcur_init_ $min_rto; 182 | Agent/TCP/FullTcp/Sack set clear_on_timeout_ false; 183 | #Agent/TCP/FullTcp set pipectrl_ true; 184 | Agent/TCP/FullTcp/Sack set sack_rtx_threshmode_ 2; 185 | if {$queueSize > 12} { 186 | Agent/TCP set maxcwnd_ [expr $queueSize - 1]; 187 | } else { 188 | Agent/TCP set maxcwnd_ 12; 189 | } 190 | Agent/TCP/FullTcp set prob_cap_ $prob_cap_; 191 | if {$enable_dctcp != 0} { 192 | set myAgent "Agent/TCP/FullTcp/Sack"; 193 | } else { 194 | if {$enable_pfabric != 0} { 195 | set myAgent "Agent/TCP/FullTcp/Sack/MinTCP"; 196 | } else { 197 | if {$enable_qjump != 0} { 198 | set myAgent "Agent/TCP/FullTcp/Sack"; 199 | } else { 200 | set myAgent "Agent/TCP/FullTcp/Sack"; 201 | } 202 | } 203 | } 204 | 205 | ################# Switch Options ###################### 206 | 207 | Queue set limit_ $queueSize 208 | 209 | Queue/DropTail set queue_in_bytes_ true 210 | Queue/DropTail set mean_pktsize_ [expr $pktSize+40] 211 | Queue/DropTail set drop_prio_ $drop_prio_ 212 | Queue/DropTail set deque_prio_ $deque_prio_ 213 | Queue/DropTail set keep_order_ $keep_order_ 214 | 215 | Queue/RED set bytes_ false 216 | Queue/RED set queue_in_bytes_ true 217 | Queue/RED set mean_pktsize_ $pktSize 218 | Queue/RED set setbit_ true 219 | Queue/RED set gentle_ false 220 | Queue/RED set q_weight_ 1.0 221 | Queue/RED set mark_p_ 1.0 222 | Queue/RED set thresh_ $DCTCP_K 223 | Queue/RED set maxthresh_ $DCTCP_K 224 | Queue/RED set drop_prio_ $drop_prio_ 225 | Queue/RED set deque_prio_ $deque_prio_ 226 | 227 | #DelayLink set avoidReordering_ true 228 | 229 | if {$enablePQ == 1} { 230 | Queue/RED set pq_enable_ 1 231 | Queue/RED set pq_mode_ $PQ_mode ; # 0 = Series, 1 = Parallel 232 | Queue/RED set pq_drainrate_ [expr $PQ_gamma * $link_rate * 1000000000] 233 | Queue/RED set pq_thresh_ $PQ_thresh 234 | #Queue/RED set thresh_ 100000 235 | #Queue/RED set maxthresh_ 100000 236 | } 237 | 238 | ################ Pacer Options ####################### 239 | if {$enablePacer == 1} { 240 | TBF set bucket_ [expr 3100 * 8] 241 | TBF set qlen_ 10000 242 | TBF set pacer_enable_ 1 243 | TBF set assoc_timeout_ $Pacer_assoc_timeout 244 | TBF set assoc_prob_ $Pacer_assoc_prob 245 | TBF set maxrate_ [expr $link_rate * 1000000000] 246 | TBF set minrate_ [expr 0.01 * $link_rate * 1000000000] 247 | TBF set rate_ [expr $link_rate * 1000000000] 248 | TBF set qlength_factor_ $Pacer_qlength_factor 249 | TBF set rate_ave_factor_ $Pacer_rate_ave_factor 250 | TBF set rate_update_interval_ $Pacer_rate_update_interval 251 | } 252 | ############### NAM ########################### 253 | if {$enableNAM != 0} { 254 | set namfile [open out.nam w] 255 | $ns namtrace-all $namfile 256 | } 257 | 258 | ############## Multipathing ########################### 259 | 260 | if {$enableMultiPath == 1} { 261 | $ns rtproto DV 262 | Agent/rtProto/DV set advertInterval [expr 2*$sim_end] 263 | Node set multiPath_ 1 264 | if {$perflowMP != 0} { 265 | Classifier/MultiPath set perflow_ 1 266 | } 267 | } 268 | 269 | ############# Topoplgy ######################### 270 | $ns color 0 Red 271 | $ns color 1 Orange 272 | $ns color 2 Yellow 273 | $ns color 3 Green 274 | $ns color 4 Blue 275 | $ns color 5 Violet 276 | $ns color 6 Brown 277 | $ns color 7 Black 278 | 279 | set S [expr $topology_spt * $topology_tors] ; #number of servers 280 | set UCap [expr $link_rate * $topology_spt / $topology_spines / $topology_x] ; #uplink rate 281 | 282 | puts "UCap: $UCap" 283 | 284 | for {set i 0} {$i < $S} {incr i} { 285 | set s($i) [$ns node] 286 | } 287 | 288 | for {set i 0} {$i < $topology_tors} {incr i} { 289 | set n($i) [$ns node] 290 | $n($i) shape box 291 | $n($i) color green 292 | } 293 | 294 | for {set i 0} {$i < $topology_spines} {incr i} { 295 | set a($i) [$ns node] 296 | $a($i) color blue 297 | $a($i) shape box 298 | } 299 | 300 | for {set i 0} {$i < $S} {incr i} { 301 | set j [expr $i/$topology_spt] 302 | $ns simplex-link $s($i) $n($j) [set link_rate]Gb [expr $host_delay + $mean_link_delay] $switchAlg 303 | $ns simplex-link $n($j) $s($i) [set link_rate]Gb [expr $host_delay + $mean_link_delay] $switchAlg 304 | $ns duplex-link-op $s($i) $n($j) queuePos -0.5 305 | set qfile(s$i,n$j) [$ns monitor-queue $s($i) $n($j) [open queue_s$i\_n$j.tr w] $queueSamplingInterval] 306 | set qfile(n$j,s$i) [$ns monitor-queue $n($j) $s($i) [open queue_n$j\_s$i.tr w] $queueSamplingInterval] 307 | } 308 | 309 | for {set i 0} {$i < $topology_tors} {incr i} { 310 | for {set j 0} {$j < $topology_spines} {incr j} { 311 | $ns duplex-link $n($i) $a($j) [set UCap]Gb $mean_link_delay $switchAlg 312 | $ns duplex-link-op $n($i) $a($j) queuePos 0.25 313 | set qfile(n$i,a$j) [$ns monitor-queue $n($i) $a($j) [open queue_n$i\_a$j.tr w] $queueSamplingInterval] 314 | set qfile(a$j,n$i) [$ns monitor-queue $a($j) $n($i) [open queue_a$j\_n$i.tr w] $queueSamplingInterval] 315 | } 316 | } 317 | 318 | ############## Tocken Buckets for Pacer ######### 319 | if {$enablePacer == 1} { 320 | for { set i 0 } { $i < $S } { incr i } { 321 | for { set j 0 } { $j < $TBFsPerServer} { incr j } { 322 | set tbf($s($i),$j) [new TBF] 323 | } 324 | } 325 | } else { 326 | set tbf 0 327 | } 328 | 329 | ############# Agents ######################### 330 | set lambda [expr ($link_rate*$load*1000000000)/($meanFlowSize*8.0/1460*1500)] 331 | #set lambda [expr ($link_rate*$load*1000000000)/($mean_npkts*($pktSize+40)*8.0)] 332 | puts "Arrival: Poisson with inter-arrival [expr 1/$lambda * 1000] ms" 333 | puts "FlowSize: Pareto with mean = $meanFlowSize, shape = $paretoShape" 334 | 335 | puts "Setting up connections ..."; flush stdout 336 | 337 | set flow_gen 0 338 | set flow_fin 0 339 | 340 | set flowlog [open flow.tr w] 341 | set init_fid 0 342 | for {set j 0} {$j < $S } {incr j} { 343 | for {set i 0} {$i < $S } {incr i} { 344 | if {$i != $j} { 345 | set agtagr($i,$j) [new Agent_Aggr_pair] 346 | $agtagr($i,$j) setup $s($i) $s($j) [array get tbf] [expr $j % $TBFsPerServer] "$i $j" $connections_per_pair $init_fid "TCP_pair" $enable_qjump 347 | $agtagr($i,$j) attach-logfile $flowlog 348 | 349 | #puts -nonewline "($i,$j) " 350 | #For Poisson/Pareto 351 | $agtagr($i,$j) set_PCarrival_process [expr $lambda/($S - 1)] $FLOW_CDF [expr 17*$i+1244*$j] [expr 33*$i+4369*$j] 352 | 353 | $ns at 0.1 "$agtagr($i,$j) warmup 0.5 5" 354 | $ns at 1 "$agtagr($i,$j) init_schedule" 355 | 356 | set init_fid [expr $init_fid + $connections_per_pair]; 357 | } 358 | } 359 | } 360 | 361 | puts "Initial agent creation done";flush stdout 362 | puts "Simulation started!" 363 | 364 | 365 | ############# Queue Monitor ######################### 366 | #set qf [open queue.tr w] 367 | #set qm [$ns monitor-queue $n0 $n1 $qf 0.1] 368 | #$bnecklink queue-sample-timeout 369 | 370 | set qstonfile [open qston.tr w] 371 | set qntosfile [open qntos.tr w] 372 | 373 | set qlossfile [open qloss.tr w] 374 | set tlossfile [open tloss.tr w] 375 | 376 | proc queueTrace {} { 377 | global ns queueSamplingInterval qfile S topology_spt topology_tors topology_spines 378 | global qstonfile qntosfile qlossfile tlossfile 379 | 380 | set now [$ns now] 381 | 382 | puts -nonewline $qstonfile "$now " 383 | puts -nonewline $qntosfile "$now " 384 | 385 | for {set k 0} {$k < 20} {incr k} { 386 | set kdrop_sn($k) 0 387 | set kdrop_ns($k) 0 388 | set karrival_sn($k) 0 389 | set karrival_ns($k) 0 390 | } 391 | 392 | set ston_drop 0 393 | set ston_arr 0 394 | set ston_depart 0 395 | set ntos_drop 0 396 | set ntos_arr 0 397 | set ntos_depart 0 398 | 399 | set bston_drop 0 400 | set bston_arr 0 401 | set bston_depart 0 402 | set bntos_drop 0 403 | set bntos_arr 0 404 | set bntos_depart 0 405 | 406 | for {set i 0} {$i < $S} {incr i} { 407 | set j [expr $i/$topology_spt] 408 | 409 | $qfile(s$i,n$j) instvar barrivals_ bdepartures_ bdrops_ pdrops_ parrivals_ pdepartures_ 410 | puts -nonewline $qstonfile "$barrivals_ $bdepartures_ $bdrops_ " 411 | incr ston_drop $pdrops_ 412 | incr ston_arr $parrivals_ 413 | incr ston_depart $pdepartures_ 414 | incr bston_drop $bdrops_ 415 | incr bston_arr $barrivals_ 416 | incr bston_depart $bdepartures_ 417 | 418 | $qfile(n$j,s$i) instvar barrivals_ bdepartures_ bdrops_ pdrops_ parrivals_ pdepartures_ 419 | puts -nonewline $qntosfile "$barrivals_ $bdepartures_ $bdrops_ " 420 | incr ntos_drop $pdrops_ 421 | incr ntos_arr $parrivals_ 422 | incr ntos_depart $pdepartures_ 423 | incr bntos_drop $bdrops_ 424 | incr bntos_arr $barrivals_ 425 | incr bntos_depart $bdepartures_ 426 | 427 | for {set k 0} {$k < 20} {incr k} { 428 | set tmp kdrops$k 429 | set tmp1 karrivals$k 430 | $qfile(s$i,n$j) instvar $tmp $tmp1 431 | if {[set $tmp1] != 0} { 432 | incr kdrop_sn($k) [set $tmp] 433 | incr karrival_sn($k) [set $tmp1] 434 | } 435 | $qfile(n$j,s$i) instvar $tmp $tmp1 436 | if {[set $tmp1] != 0} { 437 | incr kdrop_ns($k) [set $tmp] 438 | incr karrival_ns($k) [set $tmp1] 439 | } 440 | } 441 | } 442 | 443 | for {set k 0} {$k < 20} {incr k} { 444 | puts $qlossfile "$k $kdrop_sn($k) $karrival_sn($k) $kdrop_ns($k) $karrival_ns($k)" 445 | } 446 | 447 | set ntoa_drop 0 448 | set aton_drop 0 449 | set bntoa_drop 0 450 | set baton_drop 0 451 | for {set i 0} {$i < $topology_tors} {incr i} { 452 | for {set j 0} {$j < $topology_spines} {incr j} { 453 | $qfile(n$i,a$j) instvar pdrops_ bdrops_ 454 | incr ntoa_drop $pdrops_ 455 | incr bntoa_drop $bdrops_ 456 | $qfile(a$j,n$i) instvar pdrops_ bdrops_ 457 | incr aton_drop $pdrops_ 458 | incr baton_drop $bdrops_ 459 | } 460 | } 461 | 462 | 463 | puts $tlossfile "$ston_drop $ntoa_drop $aton_drop $ntos_drop" 464 | puts $tlossfile "$ston_drop $ston_arr $ston_depart $ntos_drop $ntos_arr $ntos_depart" 465 | 466 | puts $tlossfile "$bston_drop $bntoa_drop $baton_drop $bntos_drop" 467 | puts $tlossfile "$bston_drop $bston_arr $bston_depart $bntos_drop $bntos_arr $bntos_depart" 468 | 469 | puts $qstonfile " " 470 | puts $qntosfile " " 471 | 472 | } 473 | 474 | 475 | $ns run 476 | -------------------------------------------------------------------------------- /run_baseline.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # Copyright (c) 2015, Ionel Gog 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 are met: 8 | # 9 | # * Redistributions of source code must retain the above copyright notice, this 10 | # list of conditions and the following disclaimer. 11 | # 12 | # * Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 16 | # * Neither the name of the project, the name of copyright holder nor the names 17 | # of its contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | #!/bin/bash 32 | if [ $# -lt 3 ] ; then 33 | echo "Not enough paramters\n usage: " 34 | fi 35 | 36 | SIM_END=$1 37 | LOAD=$2 38 | CONNECTIONS_PER_PAIR=$3 39 | CDF=$4 40 | MEAN_FLOW_SIZE=$5 41 | #MEAN_FLOW_SIZE=1661480 42 | 43 | ENABLE_DCTCP=0 44 | ENABLE_PFABRIC=0 45 | ENABLE_QJUMP=0 46 | 47 | # Changeable 48 | ENABLE_MULTI_PATH=1 49 | PER_FLOW_MP=0 50 | SOURCE_ALG=DCTCP-Sack 51 | MIN_RTO=0.000200 52 | DROP_PRIO=false 53 | DEQUE_PRIO=false 54 | DCTCP_K=10000 # set this to very large value to get TCPDroptail/mu 55 | QUEUE_SIZE=150 56 | 57 | # Common 58 | LINK_RATE=10 59 | MEAN_LINK_DELAY=0.0000002 60 | HOST_DELAY=0.0000025 61 | PARETO_SHAPE=1.05 62 | ACK_RATIO=1 63 | SLOW_START_RESTART=true 64 | DCTCP_G=0.0625 65 | SWITCH_ALG=RED 66 | ENABLE_PQ=0 67 | PQ_MODE=0 68 | PQ_GAMMA=0 69 | PQ_THRESH=0 70 | ENABLE_PACER=0 71 | TBFS_PER_SERVER=1 72 | PACER_QLENGTH_FACTOR=3000 73 | PACER_RATE_AVE_FACTOR=0.125 74 | PACER_RATE_UPDATE_INTERVAL=0.0000072 75 | PACER_ASSOC_PROB=0.125 76 | PACER_ASSOC_TIMEOUT=0.001 77 | TOPOLOGY_SPT=16 78 | TOPOLOGY_TORS=9 79 | TOPOLOGY_SPINES=4 80 | TOPOLOGY_X=1 81 | ENABLE_NAM=0 82 | PRIO_SCHEME=2 83 | PROB_CAP=5 84 | KEEP_ORDER=false 85 | 86 | cmd="ns qjump.tcl $SIM_END $LINK_RATE $MEAN_LINK_DELAY $HOST_DELAY $QUEUE_SIZE $LOAD $CONNECTIONS_PER_PAIR $MEAN_FLOW_SIZE $PARETO_SHAPE $ENABLE_MULTI_PATH $PER_FLOW_MP $SOURCE_ALG $ACK_RATIO $SLOW_START_RESTART $DCTCP_G $SWITCH_ALG $DCTCP_K $ENABLE_PQ $PQ_MODE $PQ_GAMMA $PQ_THRESH $ENABLE_PACER $TBFS_PER_SERVER $PACER_QLENGTH_FACTOR $PACER_RATE_AVE_FACTOR $PACER_RATE_UPDATE_INTERVAL $PACER_ASSOC_PROB $PACER_ASSOC_TIMEOUT $TOPOLOGY_SPT $TOPOLOGY_TORS $TOPOLOGY_SPINES $TOPOLOGY_X $ENABLE_NAM $MIN_RTO $DROP_PRIO $PRIO_SCHEME $DEQUE_PRIO $PROB_CAP $KEEP_ORDER $ENABLE_DCTCP $ENABLE_PFABRIC $ENABLE_QJUMP $CDF" 87 | 88 | echo $cmd 89 | 90 | eval $cmd # ns ../qjump.tcl $SIM_END $LINK_RATE $MEAN_LINK_DELAY $HOST_DELAY $QUEUE_SIZE $LOAD $CONNECTIONS_PER_PAIR $MEAN_FLOW_SIZE $PARETO_SHAPE $ENABLE_MULTI_PATH $PER_FLOW_MP $SOURCE_ALG $ACK_RATIO $SLOW_START_RESTART $DCTCP_G $SWITCH_ALG $DCTCP_K $ENABLE_PQ $PQ_MODE $PQ_GAMMA $PQ_THRESH $ENABLE_PACER $TBFS_PER_SERVER $PACER_QLENGTH_FACTOR $PACER_RATE_AVE_FACTOR $PACER_RATE_UPDATE_INTERVAL $PACER_ASSOC_PROB $PACER_ASSOC_TIMEOUT $TOPOLOGY_SPT $TOPOLOGY_TORS $TOPOLOGY_SPINES $TOPOLOGY_X $ENABLE_NAM $MIN_RTO $DROP_PRIO $PRIO_SCHEME $DEQUE_PRIO $PROB_CAP $KEEP_ORDER $ENABLE_DCTCP $ENABLE_PFABRIC $ENABLE_QJUMP 91 | -------------------------------------------------------------------------------- /run_dctcp.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015, Ionel Gog 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # * Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # * Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # * Neither the name of the project, the name of copyright holder nor the names 15 | # of its contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #!/bin/bash 30 | SIM_END=$1 31 | LOAD=$2 32 | CONNECTIONS_PER_PAIR=$3 33 | CDF=$4 34 | MEAN_FLOW_SIZE=$5 35 | 36 | ENABLE_DCTCP=1 37 | ENABLE_PFABRIC=0 38 | ENABLE_QJUMP=0 39 | 40 | # Changeable 41 | ENABLE_MULTI_PATH=1 42 | PER_FLOW_MP=0 43 | SOURCE_ALG=DCTCP-Sack 44 | MIN_RTO=0.000200 45 | DROP_PRIO=false 46 | DEQUE_PRIO=false 47 | DCTCP_K=15 48 | QUEUE_SIZE=150 49 | 50 | # Common 51 | LINK_RATE=10 52 | MEAN_LINK_DELAY=0.0000002 53 | HOST_DELAY=0.0000025 54 | PARETO_SHAPE=1.05 55 | ACK_RATIO=1 56 | SLOW_START_RESTART=true 57 | DCTCP_G=0.0625 58 | SWITCH_ALG=RED 59 | ENABLE_PQ=0 60 | PQ_MODE=0 61 | PQ_GAMMA=0 62 | PQ_THRESH=0 63 | ENABLE_PACER=0 64 | TBFS_PER_SERVER=1 65 | PACER_QLENGTH_FACTOR=3000 66 | PACER_RATE_AVE_FACTOR=0.125 67 | PACER_RATE_UPDATE_INTERVAL=0.0000072 68 | PACER_ASSOC_PROB=0.125 69 | PACER_ASSOC_TIMEOUT=0.001 70 | TOPOLOGY_SPT=16 71 | TOPOLOGY_TORS=9 72 | TOPOLOGY_SPINES=4 73 | TOPOLOGY_X=1 74 | ENABLE_NAM=0 75 | PRIO_SCHEME=2 76 | PROB_CAP=5 77 | KEEP_ORDER=false 78 | 79 | echo "ns qjump.tcl $SIM_END $LINK_RATE $MEAN_LINK_DELAY $HOST_DELAY $QUEUE_SIZE $LOAD $CONNECTIONS_PER_PAIR $MEAN_FLOW_SIZE $PARETO_SHAPE $ENABLE_MULTI_PATH $PER_FLOW_MP $SOURCE_ALG $ACK_RATIO $SLOW_START_RESTART $DCTCP_G $SWITCH_ALG $DCTCP_K $ENABLE_PQ $PQ_MODE $PQ_GAMMA $PQ_THRESH $ENABLE_PACER $TBFS_PER_SERVER $PACER_QLENGTH_FACTOR $PACER_RATE_AVE_FACTOR $PACER_RATE_UPDATE_INTERVAL $PACER_ASSOC_PROB $PACER_ASSOC_TIMEOUT $TOPOLOGY_SPT $TOPOLOGY_TORS $TOPOLOGY_SPINES $TOPOLOGY_X $ENABLE_NAM $MIN_RTO $DROP_PRIO $PRIO_SCHEME $DEQUE_PRIO $PROB_CAP $KEEP_ORDER $ENABLE_DCTCP $ENABLE_PFABRIC $ENABLE_QJUMP" 80 | 81 | ns qjump.tcl $SIM_END $LINK_RATE $MEAN_LINK_DELAY $HOST_DELAY $QUEUE_SIZE $LOAD $CONNECTIONS_PER_PAIR $MEAN_FLOW_SIZE $PARETO_SHAPE $ENABLE_MULTI_PATH $PER_FLOW_MP $SOURCE_ALG $ACK_RATIO $SLOW_START_RESTART $DCTCP_G $SWITCH_ALG $DCTCP_K $ENABLE_PQ $PQ_MODE $PQ_GAMMA $PQ_THRESH $ENABLE_PACER $TBFS_PER_SERVER $PACER_QLENGTH_FACTOR $PACER_RATE_AVE_FACTOR $PACER_RATE_UPDATE_INTERVAL $PACER_ASSOC_PROB $PACER_ASSOC_TIMEOUT $TOPOLOGY_SPT $TOPOLOGY_TORS $TOPOLOGY_SPINES $TOPOLOGY_X $ENABLE_NAM $MIN_RTO $DROP_PRIO $PRIO_SCHEME $DEQUE_PRIO $PROB_CAP $KEEP_ORDER $ENABLE_DCTCP $ENABLE_PFABRIC $ENABLE_QJUMP $CDF 82 | -------------------------------------------------------------------------------- /run_pfabric.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015, Ionel Gog 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # * Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # * Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # * Neither the name of the project, the name of copyright holder nor the names 15 | # of its contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #!/bin/bash 30 | SIM_END=$1 31 | LOAD=$2 32 | CONNECTIONS_PER_PAIR=$3 33 | CDF=$4 34 | MEAN_FLOW_SIZE=$5 35 | 36 | ENABLE_DCTCP=0 37 | ENABLE_PFABRIC=1 38 | ENABLE_QJUMP=0 39 | 40 | # Changeable 41 | ENABLE_MULTI_PATH=1 42 | PER_FLOW_MP=0 43 | SOURCE_ALG=DCTCP-Sack 44 | MIN_RTO=0.000045 45 | DROP_PRIO=true 46 | DEQUE_PRIO=true 47 | DCTCP_K=10000 48 | QUEUE_SIZE=24 49 | 50 | # Common 51 | LINK_RATE=10 52 | MEAN_LINK_DELAY=0.0000002 53 | HOST_DELAY=0.0000025 54 | PARETO_SHAPE=1.05 55 | ACK_RATIO=1 56 | SLOW_START_RESTART=true 57 | DCTCP_G=0.0625 58 | SWITCH_ALG=DropTail 59 | ENABLE_PQ=0 60 | PQ_MODE=0 61 | PQ_GAMMA=0 62 | PQ_THRESH=0 63 | ENABLE_PACER=0 64 | TBFS_PER_SERVER=1 65 | PACER_QLENGTH_FACTOR=3000 66 | PACER_RATE_AVE_FACTOR=0.125 67 | PACER_RATE_UPDATE_INTERVAL=0.0000072 68 | PACER_ASSOC_PROB=0.125 69 | PACER_ASSOC_TIMEOUT=0.001 70 | TOPOLOGY_SPT=16 71 | TOPOLOGY_TORS=9 72 | TOPOLOGY_SPINES=4 73 | TOPOLOGY_X=1 74 | ENABLE_NAM=0 75 | PRIO_SCHEME=2 76 | PROB_CAP=5 77 | KEEP_ORDER=true 78 | 79 | echo "ns qjump.tcl $SIM_END $LINK_RATE $MEAN_LINK_DELAY $HOST_DELAY $QUEUE_SIZE $LOAD $CONNECTIONS_PER_PAIR $MEAN_FLOW_SIZE $PARETO_SHAPE $ENABLE_MULTI_PATH $PER_FLOW_MP $SOURCE_ALG $ACK_RATIO $SLOW_START_RESTART $DCTCP_G $SWITCH_ALG $DCTCP_K $ENABLE_PQ $PQ_MODE $PQ_GAMMA $PQ_THRESH $ENABLE_PACER $TBFS_PER_SERVER $PACER_QLENGTH_FACTOR $PACER_RATE_AVE_FACTOR $PACER_RATE_UPDATE_INTERVAL $PACER_ASSOC_PROB $PACER_ASSOC_TIMEOUT $TOPOLOGY_SPT $TOPOLOGY_TORS $TOPOLOGY_SPINES $TOPOLOGY_X $ENABLE_NAM $MIN_RTO $DROP_PRIO $PRIO_SCHEME $DEQUE_PRIO $PROB_CAP $KEEP_ORDER $ENABLE_DCTCP $ENABLE_PFABRIC $ENABLE_QJUMP" 80 | 81 | ns qjump.tcl $SIM_END $LINK_RATE $MEAN_LINK_DELAY $HOST_DELAY $QUEUE_SIZE $LOAD $CONNECTIONS_PER_PAIR $MEAN_FLOW_SIZE $PARETO_SHAPE $ENABLE_MULTI_PATH $PER_FLOW_MP $SOURCE_ALG $ACK_RATIO $SLOW_START_RESTART $DCTCP_G $SWITCH_ALG $DCTCP_K $ENABLE_PQ $PQ_MODE $PQ_GAMMA $PQ_THRESH $ENABLE_PACER $TBFS_PER_SERVER $PACER_QLENGTH_FACTOR $PACER_RATE_AVE_FACTOR $PACER_RATE_UPDATE_INTERVAL $PACER_ASSOC_PROB $PACER_ASSOC_TIMEOUT $TOPOLOGY_SPT $TOPOLOGY_TORS $TOPOLOGY_SPINES $TOPOLOGY_X $ENABLE_NAM $MIN_RTO $DROP_PRIO $PRIO_SCHEME $DEQUE_PRIO $PROB_CAP $KEEP_ORDER $ENABLE_DCTCP $ENABLE_PFABRIC $ENABLE_QJUMP $CDF 82 | -------------------------------------------------------------------------------- /run_qjump.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015, Ionel Gog 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # * Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # * Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # * Neither the name of the project, the name of copyright holder nor the names 15 | # of its contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #!/bin/bash 30 | SIM_END=$1 31 | LOAD=$2 32 | CONNECTIONS_PER_PAIR=$3 33 | CDF=$4 34 | MEAN_FLOW_SIZE=$5 35 | 36 | ENABLE_DCTCP=0 37 | ENABLE_PFABRIC=0 38 | ENABLE_QJUMP=1 39 | 40 | # Changeable 41 | ENABLE_MULTI_PATH=1 42 | PER_FLOW_MP=0 43 | SOURCE_ALG=Sack 44 | MIN_RTO=0.000200 45 | DROP_PRIO=true 46 | DEQUE_PRIO=true 47 | DCTCP_K=10000 48 | QUEUE_SIZE=153 49 | 50 | # Common 51 | LINK_RATE=10 52 | MEAN_LINK_DELAY=0.0000002 53 | HOST_DELAY=0.0000025 54 | PARETO_SHAPE=1.05 55 | ACK_RATIO=1 56 | SLOW_START_RESTART=true 57 | DCTCP_G=0.0625 58 | SWITCH_ALG=DropTail 59 | ENABLE_PQ=0 60 | PQ_MODE=0 61 | PQ_GAMMA=0 62 | PQ_THRESH=0 63 | ENABLE_PACER=0 64 | TBFS_PER_SERVER=1 65 | PACER_QLENGTH_FACTOR=3000 66 | PACER_RATE_AVE_FACTOR=0.125 67 | PACER_RATE_UPDATE_INTERVAL=0.0000072 68 | PACER_ASSOC_PROB=0.125 69 | PACER_ASSOC_TIMEOUT=0.001 70 | TOPOLOGY_SPT=16 71 | TOPOLOGY_TORS=9 72 | TOPOLOGY_SPINES=4 73 | TOPOLOGY_X=1 74 | ENABLE_NAM=0 75 | PRIO_SCHEME=2 76 | PROB_CAP=5 77 | KEEP_ORDER=true 78 | 79 | echo "ns qjump.tcl $SIM_END $LINK_RATE $MEAN_LINK_DELAY $HOST_DELAY $QUEUE_SIZE $LOAD $CONNECTIONS_PER_PAIR $MEAN_FLOW_SIZE $PARETO_SHAPE $ENABLE_MULTI_PATH $PER_FLOW_MP $SOURCE_ALG $ACK_RATIO $SLOW_START_RESTART $DCTCP_G $SWITCH_ALG $DCTCP_K $ENABLE_PQ $PQ_MODE $PQ_GAMMA $PQ_THRESH $ENABLE_PACER $TBFS_PER_SERVER $PACER_QLENGTH_FACTOR $PACER_RATE_AVE_FACTOR $PACER_RATE_UPDATE_INTERVAL $PACER_ASSOC_PROB $PACER_ASSOC_TIMEOUT $TOPOLOGY_SPT $TOPOLOGY_TORS $TOPOLOGY_SPINES $TOPOLOGY_X $ENABLE_NAM $MIN_RTO $DROP_PRIO $PRIO_SCHEME $DEQUE_PRIO $PROB_CAP $KEEP_ORDER $ENABLE_DCTCP $ENABLE_PFABRIC $ENABLE_QJUMP $CDF" 80 | 81 | ns qjump.tcl $SIM_END $LINK_RATE $MEAN_LINK_DELAY $HOST_DELAY $QUEUE_SIZE $LOAD $CONNECTIONS_PER_PAIR $MEAN_FLOW_SIZE $PARETO_SHAPE $ENABLE_MULTI_PATH $PER_FLOW_MP $SOURCE_ALG $ACK_RATIO $SLOW_START_RESTART $DCTCP_G $SWITCH_ALG $DCTCP_K $ENABLE_PQ $PQ_MODE $PQ_GAMMA $PQ_THRESH $ENABLE_PACER $TBFS_PER_SERVER $PACER_QLENGTH_FACTOR $PACER_RATE_AVE_FACTOR $PACER_RATE_UPDATE_INTERVAL $PACER_ASSOC_PROB $PACER_ASSOC_TIMEOUT $TOPOLOGY_SPT $TOPOLOGY_TORS $TOPOLOGY_SPINES $TOPOLOGY_X $ENABLE_NAM $MIN_RTO $DROP_PRIO $PRIO_SCHEME $DEQUE_PRIO $PROB_CAP $KEEP_ORDER $ENABLE_DCTCP $ENABLE_PFABRIC $ENABLE_QJUMP $CDF 82 | -------------------------------------------------------------------------------- /search_CDF.tcl: -------------------------------------------------------------------------------- 1 | 6 1 0 2 | 6 1 0.15 3 | 13 1 0.2 4 | 19 1 0.3 5 | 33 1 0.4 6 | 53 1 0.53 7 | 133 1 0.6 8 | 667 1 0.7 9 | 1333 1 0.8 10 | 3333 1 0.9 11 | 6667 1 0.97 12 | 20000 1 1 13 | 14 | -------------------------------------------------------------------------------- /tcp-common-opt.tcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015, The Board of Trustees of The Leland Stanford Junior 2 | # University. All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # * Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # * Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # * Neither the name of copyright holder nor the names of the contributors may 15 | # be used to endorse or promote products derived from this software without 16 | # specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | # TCP pair's have 30 | # - group_id = "src->dst" 31 | # - pair_id = index of connection among the group 32 | # - fid = unique flow identifier for this connection (group_id, pair_id) 33 | set next_fid 0 34 | 35 | Class TCP_pair 36 | #Variables: 37 | #tcps tcpr: Sender TCP, Receiver TCP 38 | #sn dn : source/dest node which TCP sender/receiver exist 39 | #: (only for setup_wnode) 40 | #delay : delay between sn and san (dn and dan) 41 | #: (only for setup_wnode) 42 | #san dan : nodes to which sn/dn are attached 43 | #aggr_ctrl: Agent_Aggr_pair for callback 44 | #start_cbfunc: callback at start 45 | #fin_cbfunc: callback at start 46 | #group_id : group id 47 | #pair_id : group id 48 | #fid : flow id 49 | #Public Functions: 50 | #setup{snode dnode} <- either of them 51 | #setgid {gid} <- if applicable (default 0) 52 | #setpairid {pid} <- if applicable (default 0) 53 | #setfid {fid} <- if applicable (default 0) 54 | #start { nr_bytes } ;# let start sending nr_bytes 55 | #setcallback { controller } #; only Agent_Aggr_pair uses to 56 | ##; registor itself 57 | #fin_notify {} #; Callback .. this is called by agent when it finished 58 | #Private Function 59 | #flow_finished {} { 60 | 61 | TCP_pair instproc init {args} { 62 | $self instvar pair_id group_id id debug_mode rttimes 63 | $self instvar tcps tcpr;# Sender TCP, Receiver TCP 64 | global myAgent 65 | eval $self next $args 66 | 67 | $self set tcps [new $myAgent] ;# Sender TCP 68 | $self set tcpr [new $myAgent] ;# Receiver TCP 69 | $tcps set_callback $self 70 | #$tcpr set_callback $self 71 | $self set pair_id 0 72 | $self set group_id 0 73 | $self set id 0 74 | $self set debug_mode 0 75 | $self set rttimes 0 76 | } 77 | 78 | TCP_pair instproc setup {snode dnode arg_enable_qjump} { 79 | #Directly connect agents to snode, dnode. For faster simulation. 80 | #puts "TCP_pair setup $snode $dnode" 81 | global ns link_rate 82 | $self instvar tcps tcpr;# Sender TCP, Receiver TCP 83 | $self instvar san dan ;# memorize dumbell node (to attach) 84 | $self instvar tbf; 85 | $self instvar qjump; 86 | $self instvar enable_qjump; 87 | 88 | $self set san $snode 89 | $self set dan $dnode 90 | $self set enable_qjump $arg_enable_qjump 91 | $ns attach-agent $snode $tcps; 92 | $ns attach-agent $dnode $tcpr; 93 | $tcpr listen 94 | 95 | # $self set tbf [new TBF] 96 | # $ns attach-tbf-agent $snode $tcps $tbf 97 | if {$enable_qjump != 0} { 98 | $self set qjump [new QJUMP] 99 | $ns attach-qjump-agent $snode $tcps $qjump 100 | } 101 | 102 | $ns connect $tcps $tcpr 103 | } 104 | 105 | TCP_pair instproc set_fincallback { controller func} { 106 | $self instvar aggr_ctrl fin_cbfunc 107 | $self set aggr_ctrl $controller 108 | $self set fin_cbfunc $func 109 | } 110 | 111 | TCP_pair instproc set_startcallback { controller func} { 112 | $self instvar aggr_ctrl start_cbfunc 113 | $self set aggr_ctrl $controller 114 | $self set start_cbfunc $func 115 | } 116 | 117 | TCP_pair instproc setgid { gid } { 118 | $self instvar group_id 119 | $self set group_id $gid 120 | } 121 | 122 | TCP_pair instproc setpairid { pid } { 123 | $self instvar pair_id 124 | $self set pair_id $pid 125 | } 126 | 127 | TCP_pair instproc setfid { fid } { 128 | $self instvar tcps tcpr 129 | $self instvar id 130 | $self set id $fid 131 | $tcps set fid_ $fid; 132 | $tcpr set fid_ $fid; 133 | } 134 | 135 | TCP_pair instproc settbf { tbf } { 136 | global ns 137 | $self instvar tcps tcpr 138 | $self instvar san 139 | $self instvar tbfs 140 | $self set tbfs $tbf 141 | $ns attach-tbf-agent $san $tcps $tbf 142 | } 143 | 144 | TCP_pair instproc start { nr_bytes } { 145 | global ns sim_end flow_gen 146 | $self instvar tcps tcpr id group_id 147 | $self instvar start_time bytes 148 | $self instvar aggr_ctrl start_cbfunc 149 | $self instvar debug_mode 150 | $self instvar tbf; 151 | $self instvar qjump; 152 | $self instvar id; 153 | $self instvar enable_qjump; 154 | 155 | $self set start_time [$ns now] ;# memorize 156 | $self set bytes $nr_bytes ;# memorize 157 | 158 | if {$flow_gen >= $sim_end} { 159 | return 160 | } 161 | if {$start_time >= 0.2} { 162 | set flow_gen [expr $flow_gen + 1] 163 | } 164 | if { $debug_mode == 1 } { 165 | puts "stats: [$ns now] start grp $group_id fid $id $nr_bytes bytes" 166 | } 167 | if { [info exists aggr_ctrl] } { 168 | $aggr_ctrl $start_cbfunc 169 | } 170 | $tcpr set flow_remaining_ [expr $nr_bytes] 171 | $tcps set signal_on_empty_ TRUE 172 | puts "Starting flow: $flow_gen of size $nr_bytes $id" 173 | # fid rate bucket qlen 174 | if {$enable_qjump != 0} { 175 | if {$nr_bytes <= 8760} { 176 | # Priority 7 177 | $qjump activate-fid $id 72000 1050000 0 0 178 | } else { 179 | if {$nr_bytes <= 18980} { 180 | # Priority 6 181 | $qjump activate-fid $id 156000 1050000 0 1 182 | } else { 183 | if {$nr_bytes <= 27740} { 184 | # Priority 5 185 | $qjump activate-fid $id 228000 1050000 0 2 186 | } else { 187 | if {$nr_bytes <= 48180} { 188 | # Priority 4 189 | $qjump activate-fid $id 396000 1050000 0 3 190 | } else { 191 | if {$nr_bytes <= 77380} { 192 | # Priority 3 193 | $qjump activate-fid $id 636000 1050000 0 4 194 | } else { 195 | if {$nr_bytes <= 194180} { 196 | # Priority 2 197 | $qjump activate-fid $id 1596000 1050000 0 5 198 | } else { 199 | if {$nr_bytes <= 973820} { 200 | # Priority 1 201 | $qjump activate-fid $id 8004000 1050000 0 6 202 | } else { 203 | # Priority 0 204 | $qjump activate-fid $id 10500000 1050000 0 7 205 | } 206 | } 207 | } 208 | } 209 | } 210 | } 211 | } 212 | } 213 | $tcps advance-bytes $nr_bytes 214 | # set test_cbr [new Application/Traffic/CBR] 215 | # $test_cbr attach-agent $tcps 216 | # $test_cbr set interval_ 0.0000015 217 | # $test_cbr set packetSize_ 1460 218 | # $test_cbr set maxpkts_ [expr $nr_bytes / 1460] 219 | # $ns at [expr [$ns now]] "$test_cbr start" 220 | } 221 | 222 | TCP_pair instproc warmup { nr_pkts } { 223 | global ns 224 | $self instvar tcps id group_id 225 | $self instvar debug_mode 226 | 227 | set pktsize [$tcps set packetSize_] 228 | if { $debug_mode == 1 } { 229 | puts "warm-up: [$ns now] start grp $group_id fid $id $nr_pkts pkts ($pktsize +40)" 230 | } 231 | $tcps advanceby $nr_pkts 232 | } 233 | 234 | TCP_pair instproc stop {} { 235 | $self instvar tcps tcpr 236 | 237 | $tcps reset 238 | $tcpr reset 239 | } 240 | 241 | TCP_pair instproc fin_notify {} { 242 | global ns 243 | $self instvar sn dn san dan rttimes 244 | $self instvar tcps tcpr 245 | $self instvar aggr_ctrl fin_cbfunc 246 | $self instvar pair_id 247 | $self instvar bytes 248 | $self instvar dt 249 | $self instvar bps 250 | $self flow_finished 251 | 252 | #Shuang 253 | set old_rttimes $rttimes 254 | $self set rttimes [$tcps set nrexmit_] 255 | # 256 | # Mohammad commenting these 257 | # for persistent connections 258 | # 259 | #$tcps reset 260 | #$tcpr reset 261 | if { [info exists aggr_ctrl] } { 262 | $aggr_ctrl $fin_cbfunc $pair_id $bytes $dt $bps [expr $rttimes - $old_rttimes] 263 | } 264 | } 265 | 266 | TCP_pair instproc flow_finished {} { 267 | global ns 268 | $self instvar start_time bytes id group_id 269 | $self instvar dt bps 270 | $self instvar debug_mode 271 | 272 | set ct [$ns now] 273 | #Shuang commenting these 274 | # puts "Flow times (start, end): ($start_time, $ct)" 275 | $self set dt [expr $ct - $start_time] 276 | if { $dt == 0 } { 277 | puts "dt = 0" 278 | flush stdout 279 | } 280 | $self set bps [expr $bytes * 8.0 / $dt ] 281 | if { $debug_mode == 1 } { 282 | puts "stats: $ct fin grp $group_id fid $id fldur $dt sec $bps bps" 283 | } 284 | } 285 | 286 | Agent/TCP/FullTcp instproc set_callback {tcp_pair} { 287 | $self instvar ctrl 288 | $self set ctrl $tcp_pair 289 | } 290 | 291 | Agent/TCP/FullTcp instproc done_data {} { 292 | global ns sink 293 | $self instvar ctrl 294 | #puts "[$ns now] $self fin-ack received"; 295 | if { [info exists ctrl] } { 296 | $ctrl fin_notify 297 | } 298 | } 299 | 300 | Class Agent_Aggr_pair 301 | #Note: 302 | #Contoller and placeholder of Agent_pairs 303 | #Let Agent_pairs to arrives according to 304 | #random process. 305 | #Currently, the following two processes are defined 306 | #- PParrival: 307 | #flow arrival is poissson and 308 | #each flow contains pareto 309 | #distributed number of packets. 310 | #- PEarrival 311 | #flow arrival is poissson and 312 | #each flow contains pareto 313 | #distributed number of packets. 314 | #- PBarrival 315 | #flow arrival is poissson and 316 | #each flow contains bimodal 317 | #distributed number of packets. 318 | 319 | #Variables:# 320 | #apair: array of Agent_pair 321 | #nr_pairs: the number of pairs 322 | #rv_flow_intval: (r.v.) flow interval 323 | #rv_nbytes: (r.v.) the number of bytes within a flow 324 | #last_arrival_time: the last flow starting time 325 | #logfile: log file (should have been opend) 326 | #stat_nr_finflow ;# statistics nr of finished flows 327 | #stat_sum_fldur ;# statistics sum of finished flow durations 328 | #last_arrival_time ;# last flow arrival time 329 | #actfl ;# nr of current active flow 330 | 331 | #Public functions: 332 | #attach-logfile {logf} <- call if want logfile 333 | #setup {snode dnode gid nr} <- must 334 | #set_PParrival_process {lambda mean_nbytes shape rands1 rands2} <- call either 335 | #set_PEarrival_process {lambda mean_nbytes rands1 rands2} <- 336 | #set_PBarrival_process {lambda mean_nbytes S1 S2 rands1 rands2} <- of them 337 | #init_schedule {} <- must 338 | 339 | #fin_notify { pid bytes fldur bps } ;# Callback 340 | #start_notify {} ;# Callback 341 | 342 | #Private functions: 343 | #init {args} 344 | #resetvars {} 345 | 346 | Agent_Aggr_pair instproc init {args} { 347 | eval $self next $args 348 | } 349 | 350 | Agent_Aggr_pair instproc attach-logfile { logf } { 351 | #Public 352 | $self instvar logfile 353 | $self set logfile $logf 354 | } 355 | 356 | Agent_Aggr_pair instproc setup {snode dnode tbflist tbfindex gid nr init_fid agent_pair_type enable_qjump} { 357 | #Public 358 | #Note: 359 | #Create nr pairs of Agent_pair and connect them to snode-dnode bottleneck. 360 | #We may refer this pair by group_id gid. All Agent_pairs have the same gid, 361 | #and each of them has its own flow id: init_fid + [0 .. nr-1] global next_fid 362 | $self instvar apair ;# array of Agent_pair 363 | $self instvar group_id ;# group id of this group (given) 364 | $self instvar nr_pairs ;# nr of pairs in this group (given) 365 | $self instvar s_node d_node apair_type ; 366 | 367 | $self set group_id $gid 368 | $self set nr_pairs $nr 369 | $self set s_node $snode 370 | $self set d_node $dnode 371 | $self set apair_type $agent_pair_type 372 | 373 | array set tbf $tbflist 374 | 375 | set arrsize [array size tbf] 376 | 377 | for {set i 0} {$i < $nr_pairs} {incr i} { 378 | $self set apair($i) [new $agent_pair_type] 379 | $apair($i) setup $snode $dnode $enable_qjump 380 | $apair($i) setgid $group_id ;# let each pair know our group id 381 | $apair($i) setpairid $i ;# let each pair know his pair id 382 | $apair($i) setfid $init_fid ;# Mohammad: assign next fid 383 | if {$arrsize != 0} { ;# Mohammad: install TBF for this pair 384 | puts "installing tbf $tbfindex for gid $group_id fid $init_fid" 385 | $apair($i) settbf $tbf($snode,$tbfindex) ;#FIXME: needs to assign proper tbf 386 | } 387 | incr init_fid 388 | } 389 | $self resetvars ;# other initialization 390 | } 391 | 392 | set warmupRNG [new RNG] 393 | $warmupRNG seed 5251 394 | 395 | Agent_Aggr_pair instproc warmup {jitter_period npkts} { 396 | global ns warmupRNG 397 | $self instvar nr_pairs apair 398 | 399 | for {set i 0} {$i < $nr_pairs} {incr i} { 400 | $ns at [expr [$ns now] + [$warmupRNG uniform 0.0 $jitter_period]] "$apair($i) warmup $npkts" 401 | } 402 | } 403 | 404 | Agent_Aggr_pair instproc init_schedule {} { 405 | #Public 406 | #Note: 407 | #Initially schedule flows for all pairs according to the arrival process. 408 | global ns 409 | $self instvar nr_pairs apair 410 | 411 | # Mohammad: initializing last_arrival_time 412 | #$self instvar last_arrival_time 413 | #$self set last_arrival_time [$ns now] 414 | $self instvar tnext rv_flow_intval 415 | 416 | set dt [$rv_flow_intval value] 417 | 418 | $self set tnext [expr [$ns now] + $dt] 419 | 420 | for {set i 0} {$i < $nr_pairs} {incr i} { 421 | #### Callback Setting ######################## 422 | $apair($i) set_fincallback $self fin_notify 423 | $apair($i) set_startcallback $self start_notify 424 | ############################################### 425 | $self schedule $i 426 | } 427 | } 428 | 429 | Agent_Aggr_pair instproc set_PCarrival_process {lambda cdffile rands1 rands2} { 430 | #public 431 | ##setup random variable rv_flow_intval and rv_npkts. 432 | # 433 | #- PCarrival: 434 | #flow arrival: poisson with rate $lambda 435 | #flow length: custom defined expirical cdf 436 | $self instvar rv_flow_intval rv_nbytes 437 | 438 | set rng1 [new RNG] 439 | $rng1 seed $rands1 440 | $self set rv_flow_intval [new RandomVariable/Exponential] 441 | $rv_flow_intval use-rng $rng1 442 | $rv_flow_intval set avg_ [expr 1.0/$lambda] 443 | 444 | set rng2 [new RNG] 445 | $rng2 seed $rands2 446 | $self set rv_nbytes [new RandomVariable/Empirical] 447 | $rv_nbytes use-rng $rng2 448 | $rv_nbytes set interpolation_ 2 449 | $rv_nbytes loadCDF $cdffile 450 | } 451 | 452 | Agent_Aggr_pair instproc set_PBarrival_process {lambda mean_nbytes S1 S2 rands1 rands2} { 453 | #Public 454 | #setup random variable rv_flow_intval and rv_nbytes. 455 | #To get the r.v. call "value" function. ex) $rv_flow_intval value 456 | #- PParrival: 457 | #flow arrival: poissson with rate $lambda 458 | #flow length : pareto with mean $mean_nbytes bytes and shape parameter $shape. 459 | $self instvar rv_flow_intval rv_nbytes 460 | 461 | set rng1 [new RNG] 462 | $rng1 seed $rands1 463 | $self set rv_flow_intval [new RandomVariable/Exponential] 464 | $rv_flow_intval use-rng $rng1 465 | $rv_flow_intval set avg_ [expr 1.0/$lambda] 466 | 467 | set rng2 [new RNG] 468 | $rng2 seed $rands2 469 | $self set rv_nbytes [new RandomVariable/Binomial] 470 | $rv_nbytes use-rng $rng2 471 | 472 | $rv_nbytes set p1_ [expr (1.0*$mean_nbytes - $S2)/($S1-$S2)] 473 | $rv_nbytes set s1_ $S1 474 | $rv_nbytes set s2_ $S2 475 | 476 | set p [expr (1.0*$mean_nbytes - $S2)/($S1-$S2)] 477 | if { $p < 0 } { 478 | puts "In PBarrival, prob for bimodal p_ is negative %p_ exiting.. " 479 | flush stdout 480 | exit 0 481 | } 482 | } 483 | 484 | Agent_Aggr_pair instproc resetvars {} { 485 | # $self instvar fid ;# current flow id of this group 486 | $self instvar tnext ;# last flow arrival time 487 | $self instvar actfl ;# nr of current active flow 488 | 489 | $self set tnext 0.0 490 | # $self set fid 0 ;# flow id starts from 0 491 | $self set actfl 0 492 | } 493 | 494 | Agent_Aggr_pair instproc schedule { pid } { 495 | #Private 496 | #Schedule pair (having pid) next flow time according to the flow arrival process. 497 | global ns flow_gen sim_end 498 | $self instvar apair 499 | # $self instvar fid 500 | $self instvar tnext 501 | $self instvar rv_flow_intval rv_nbytes 502 | 503 | if {$flow_gen >= $sim_end} { 504 | return 505 | } 506 | 507 | set t [$ns now] 508 | 509 | if { $t > $tnext } { 510 | puts "Error, Not enough flows ! Aborting! pair id $pid" 511 | flush stdout 512 | exit 513 | } 514 | 515 | # Mohammad: persistent connection.. don't 516 | # need to set fid each time 517 | #$apair($pid) setfid $fid 518 | # incr fid 519 | 520 | set tmp_ [expr ceil ([$rv_nbytes value])] 521 | set tmp_ [expr $tmp_ * 1460] 522 | $ns at $tnext "$apair($pid) start $tmp_" 523 | 524 | set dt [$rv_flow_intval value] 525 | $self set tnext [expr $tnext + $dt] 526 | $ns at [expr $tnext - 0.0000001] "$self check_if_behind" 527 | } 528 | 529 | Agent_Aggr_pair instproc check_if_behind {} { 530 | global ns 531 | global flow_gen sim_end 532 | $self instvar apair 533 | $self instvar nr_pairs 534 | $self instvar apair_type s_node d_node group_id 535 | $self instvar tnext 536 | #$self instvar enable_qjump 537 | 538 | set t [$ns now] 539 | if { $flow_gen < $sim_end && $tnext < [expr $t + 0.0000002] } { #create new flow 540 | puts "[$ns now]: creating new connection $nr_pairs $s_node -> $d_node" 541 | flush stdout 542 | $self set apair($nr_pairs) [new $apair_type] 543 | $apair($nr_pairs) setup $s_node $d_node 0 544 | $apair($nr_pairs) setgid $group_id ; 545 | $apair($nr_pairs) setpairid $nr_pairs ; 546 | 547 | #### Callback Setting ################# 548 | $apair($nr_pairs) set_fincallback $self fin_notify 549 | $apair($nr_pairs) set_startcallback $self start_notify 550 | ####################################### 551 | $self schedule $nr_pairs 552 | incr nr_pairs 553 | } 554 | 555 | } 556 | 557 | Agent_Aggr_pair instproc fin_notify { pid bytes fldur bps rttimes } { 558 | # puts "Agent_Aggr_pair fin_notify $pid $bytes $fldur $bps $rttimes" 559 | #Callback Function 560 | #pid : pair_id 561 | #bytes : nr of bytes of the flow which has just finished 562 | #fldur: duration of the flow which has just finished 563 | #bps : avg bits/sec of the flow which has just finished 564 | #Note: 565 | #If we registor $self as "setcallback" of 566 | #$apair($id), $apair($i) will callback this 567 | #function with argument id when the flow between the pair finishes. 568 | #i.e. 569 | #If we set: "$apair(13) setcallback $self" somewhere, 570 | #"fin_notify 13 $bytes $fldur $bps" is called when the $apair(13)'s flow is finished. 571 | # 572 | global ns flow_gen flow_fin sim_end 573 | $self instvar logfile 574 | $self instvar group_id 575 | $self instvar actfl 576 | $self instvar apair 577 | 578 | #Here, we re-schedule $apair($pid). 579 | #according to the arrival process. 580 | 581 | $self set actfl [expr $actfl - 1] 582 | 583 | set fin_fid [$apair($pid) set id] 584 | 585 | ###### OUPUT STATISTICS ################# 586 | if { [info exists logfile] } { 587 | #puts $logfile "flow_stats: [$ns now] gid $group_id pid $pid fid $fin_fid bytes $bytes fldur $fldur actfl $actfl bps $bps" 588 | set tmp_pkts [expr $bytes / 1460] 589 | 590 | #puts $logfile "$tmp_pkts $fldur $rttimes" 591 | puts $logfile "$tmp_pkts $fldur $rttimes $group_id" 592 | flush stdout 593 | } 594 | set flow_fin [expr $flow_fin + 1] 595 | if {$flow_fin >= $sim_end} { 596 | finish 597 | } 598 | if {$flow_gen < $sim_end} { 599 | $self schedule $pid ;# re-schedule a pair having pair_id $pid. 600 | } 601 | } 602 | 603 | Agent_Aggr_pair instproc start_notify {} { 604 | #Callback Function 605 | #Note: 606 | #If we registor $self as "setcallback" of 607 | #$apair($id), $apair($i) will callback this 608 | #function with argument id when the flow between the pair finishes. 609 | #i.e. If we set: "$apair(13) setcallback $self" somewhere, 610 | #"start_notyf 13" is called when the $apair(13)'s flow is started. 611 | $self instvar actfl; 612 | incr actfl; 613 | } 614 | 615 | proc finish {} { 616 | global ns flowlog 617 | global sim_start 618 | global enableNAM namfile 619 | 620 | queueTrace 621 | 622 | $ns flush-trace 623 | close $flowlog 624 | 625 | set t [clock seconds] 626 | puts "Simulation Finished!" 627 | puts "Time [expr $t - $sim_start] sec" 628 | #puts "Date [clock format [clock seconds]]" 629 | # if {$enableNAM != 0} { 630 | # close $namfile 631 | # exec nam out.nam & 632 | # } 633 | exit 0 634 | } 635 | 636 | 637 | --------------------------------------------------------------------------------