diff -ru --unidirectional-new-file ns-allinone-2.35/ns-2.35/Makefile.in ns-allinone-2.35-patched/ns-2.35/Makefile.in
--- ns-allinone-2.35/ns-2.35/Makefile.in	2011-10-23 09:29:54.000000000 -0700
+++ ns-allinone-2.35-patched/ns-2.35/Makefile.in	2012-05-07 07:46:30.000000000 -0700
@@ -217,7 +217,7 @@
 	tools/integrator.o tools/queue-monitor.o \
 	tools/flowmon.o tools/loss-monitor.o \
 	queue/queue.o queue/drop-tail.o \
-	adc/simple-intserv-sched.o queue/red.o \
+	adc/simple-intserv-sched.o queue/red.o queue/codel.o \
 	queue/semantic-packetqueue.o queue/semantic-red.o \
 	tcp/ack-recons.o \
 	queue/sfq.o queue/fq.o queue/drr.o queue/srr.o queue/cbq.o \
diff -ru --unidirectional-new-file ns-allinone-2.35/ns-2.35/codel.tcl ns-allinone-2.35-patched/ns-2.35/codel.tcl
--- ns-allinone-2.35/ns-2.35/codel.tcl	1969-12-31 16:00:00.000000000 -0800
+++ ns-allinone-2.35-patched/ns-2.35/codel.tcl	2012-05-13 22:02:39.000000000 -0700
@@ -0,0 +1,433 @@
+# Codel test script v120513
+
+# Run this to run CoDel AQM tests.
+# ns codel.tcl f w c {b}Mb s d r
+# where:
+#	f = # ftps
+#	w = # PackMime connections per second
+#	c = # CBRs
+#	b = bottleneck bandwidth in Mbps
+#	s = filesize for ftp, -1 for infinite
+#	d = dynamic bandwidth, if non-zero, changes (kind of kludgey)
+#		have to set the specific change ratios in this file (below)
+#	r = number of "reverse" ftps
+
+set stopTime 300
+set ns [new Simulator]
+
+# These are defaults if values not set on command line
+
+set num_ftps 1
+set web_rate 0
+set revftp 0
+set num_cbrs 0
+#rate and packetSize set in build_cbr
+set bottleneck 3Mb
+#for a 10MB ftp
+set filesize 10000000
+set dynamic_bw 0
+set greedy 0
+
+# Parse command line
+
+if {$argc >= 1} {
+    set num_ftps [lindex $argv 0]
+    if {$argc >= 2} {
+        set web_rate [lindex $argv 1]
+        if {$argc >= 3} {
+            set num_cbrs [lindex $argv 2]
+            if {$argc >= 4} {
+            	set bottleneck [lindex $argv 3]
+	    	if {$argc >= 5} {
+			set filesize [lindex $argv 4]
+	   	 	if {$argc >= 6} {
+				set dynamic_bw [lindex $argv 5]
+	   	 		if {$argc >= 7} {
+					set revftp [lindex $argv 6]
+	    			}
+	    		}
+        	}
+    	     }
+	}
+    }
+}
+
+set bw [bw_parse $bottleneck]
+if { $revftp >= 1} {
+	set num_revs $revftp
+} else {
+	set num_revs 0
+}
+puts "ftps $num_ftps webrate $web_rate cbrs $num_cbrs bw $bw filesize $filesize reverse $num_revs"
+
+# experiment settings
+set psize 1500
+if { $bw < 1000000} { set psize 500 }
+set nominal_rtt [delay_parse 100ms]
+set accessdly 20
+set bdelay 10 
+set realrtt [expr 2*(2*$accessdly + $bdelay)]
+puts "accessdly $accessdly bneckdly $bdelay realrtt $realrtt bneckbw $bw"
+
+# CoDel values
+# interval to keep min over
+set interval [delay_parse 100ms]
+# target in ms.
+set target [delay_parse 5ms]
+
+global defaultRNG
+$defaultRNG seed 0
+ns-random 0
+#$defaultRNG seed 54321
+#ns-random 23145
+
+# ------- config info is all above this line ----------
+
+#bdp in packets, based on the nominal rtt
+set bdp [expr round($bw*$nominal_rtt/(8*$psize))]
+
+Trace set show_tcphdr_ 1
+set startTime 0.0
+
+#TCP parameters - have to set both for FTPs and PackMime
+
+Agent/TCP set window_ [expr $bdp*16]
+Agent/TCP set segsize_ [expr $psize-40]
+Agent/TCP set packetSize_ [expr $psize-40]
+Agent/TCP set windowInit_ 4
+Agent/TCP set segsperack_ 1
+Agent/TCP set timestamps_ true
+set delack 0.4
+Agent/TCP set interval_ $delack
+
+Agent/TCP/FullTcp set window_ [expr $bdp*16]
+Agent/TCP/FullTcp set segsize_ [expr $psize-40]
+Agent/TCP/FullTcp set packetSize_ [expr $psize-40]
+Agent/TCP/FullTcp set windowInit_ 4
+Agent/TCP/FullTcp set segsperack_ 1
+Agent/TCP/FullTcp set timestamps_ true
+Agent/TCP/FullTcp set interval_ $delack
+
+
+Agent/TCP/Linux instproc done {} {
+	global ns filesize
+#this doesn't seem to work, had to hack tcp-linux.cc to do repeat ftps
+	$self set closed_ 0
+#needs to be delayed by at least .3sec to slow start
+	puts "[$ns now] TCP/Linux proc done called"
+	$ns at [expr [$ns now] + 0.3] "$self send $filesize"
+}
+
+# problem is that idle() in tcp.cc never seems to get called...
+Application/FTP instproc resume {} {
+puts "called resume"
+        global filesize
+        $self send $filesize
+#	$ns at [expr [$ns now] + 0.5] "[$self agent] reset"
+	$ns at [expr [$ns now] + 0.5] "[$self agent] send $filesize"
+}
+
+Application/FTP instproc fire {} {
+        global filesize
+        $self instvar maxpkts_
+        set maxpkts_ $filesize
+	[$self agent] set maxpkts_ $filesize
+        $self send $maxpkts_
+	puts "fire() FTP"
+}
+
+#buffersizes
+set buffersize [expr $bdp]
+set buffersize1 [expr $bdp*10]
+
+Queue/CoDel set target_ $target
+Queue/CoDel set interval_ $interval
+
+#set Flow_id 1
+
+proc build_topology { ns which } {
+    # nodes n0 and n1 are the server and client side gateways and
+    # the link between them is the congested slow link. n0 -> n1
+    # handles all the server to client traffic.
+    #
+    # if the web_rate is non-zero, node n2 will be the packmime server cloud
+    # and node n3 will be the client cloud.
+    #
+    # num_ftps server nodes and client nodes are created for the ftp sessions.
+    # the first client node is n{2+w} and the first server node is n{2+f+w}
+    # where 'f' is num_ftps and 'w' is 1 if web_rate>0 and 0 otherwise.
+    # servers will be even numbered nodes, clients odd
+    # Warning: the numbering here is ridiculously complicated
+
+    global bw bdelay accessdly buffersize buffersize1 filesize node_cnt
+    set node_cnt 2
+
+    # congested link
+    global n0 n1
+    set n0 [$ns node]
+    set n1 [$ns node]
+    $ns duplex-link $n0 $n1 $bw ${bdelay}ms CoDel
+    $ns duplex-link-op $n0 $n1 orient right
+    $ns duplex-link-op $n0 $n1 queuePos 0.5
+    $ns duplex-link-op $n1 $n0 queuePos 1.5
+    $ns queue-limit $n0 $n1 $buffersize
+    $ns queue-limit $n1 $n0 $buffersize
+    set node_cnt 2
+
+    #dynamic bandwidth
+    # these are the multipliers for changing bw, times initial set bw
+    # edit these values to get different patterns
+    global stopTime dynamic_bw
+    array names bw_changes
+    set bw_changes(1) 0.1
+    set bw_changes(2) 0.01
+    set bw_changes(3) 0.5
+    set bw_changes(4) 0.01
+    set bw_changes(5) 1.0
+
+    puts "bottleneck starts at [[[$ns link $n0 $n1] link] set bandwidth_]bps"
+    for {set k 1} {$k <= $dynamic_bw} {incr k 1} {
+	set changeTime [expr $k*$stopTime/($dynamic_bw+1)]
+	set f $bw_changes($k)
+	set newBW [expr $f*$bw]
+	puts "change at $changeTime to [expr $newBW/1000000.]Mbps"
+	$ns at $changeTime "[[$ns link $n0 $n1] link] set bandwidth_ $newBW"
+	$ns at $changeTime "[[$ns link $n1 $n0] link] set bandwidth_ $newBW"
+	$ns at $changeTime "puts $newBW"
+    }
+
+    set li_10 [[$ns link $n1 $n0] queue]
+    set li_01 [[$ns link $n0 $n1] queue]
+
+    set tchan_ [open /tmp/redqvar.tr w]
+    $li_01 trace curq_
+    $li_01 trace d_exp_
+    $li_01 attach $tchan_
+
+    global num_ftps web_rate num_cbrs greedy num_revs
+    set linkbw [expr $bw*10]
+
+    set w [expr $web_rate > 0]
+    if {$w} {
+        global n2 n3
+	#server
+        set n2 [$ns node]
+        $ns duplex-link $n2 $n0 $linkbw ${accessdly}ms DropTail
+        $ns queue-limit $n2 $n0 $buffersize1
+        $ns queue-limit $n0 $n2 $buffersize1
+
+	#client
+        set n3 [$ns node]
+        $ns duplex-link $n1 $n3 $linkbw ${accessdly}ms DropTail
+        $ns queue-limit $n1 $n3 $buffersize1
+        $ns queue-limit $n3 $n1 $buffersize1
+	set node_cnt 4
+    }
+#need to fix the angles if use nam
+    for {set k 0} {$k < $num_ftps} {incr k 1} {
+        # servers
+        set j $node_cnt
+        global n$j
+        set n$j [$ns node]
+	if {$greedy > 0 && $k == 0} {
+         $ns duplex-link [set n$j] $n0 $linkbw 1ms DropTail
+	} else {
+         $ns duplex-link [set n$j] $n0 $linkbw ${accessdly}ms DropTail
+	}
+        $ns queue-limit [set n$j] $n0 $buffersize1
+        $ns queue-limit $n0 [set n$j] $buffersize1
+        set angle [expr $num_ftps>1? 0.75+($k-1)*.5/($num_ftps-1) : 1]
+        $ns duplex-link-op $n0 [set n$j] orient $angle
+	incr node_cnt
+
+        # clients
+        set j $node_cnt
+        global n$j
+        set n$j [$ns node]
+        set dly [expr ${accessdly} +($k+1)]
+        $ns duplex-link $n1 [set n$j] $linkbw  ${dly}ms  DropTail
+        $ns queue-limit $n1 [set n$j] $buffersize1
+        $ns queue-limit [set n$j] $n1 $buffersize1
+        set angle [expr $num_ftps>1? fmod(2.25-($k-1)*.5/($num_ftps-1), 2) : 0]
+        $ns duplex-link-op $n1 [set n$j] orient $angle
+	incr node_cnt
+    }
+    for {set k 0} {$k < $num_cbrs} {incr k 1} {
+        # servers
+        set j $node_cnt
+        global n$j
+        set n$j [$ns node]
+        $ns duplex-link [set n$j] $n0 $linkbw ${accessdly}ms DropTail
+        $ns queue-limit [set n$j] $n0 $buffersize1
+        $ns queue-limit $n0 [set n$j] $buffersize1
+#        set angle [expr $num_cbrs>1? 0.75+($k-1)*.5/($num_cbrs-1) : 1]
+        $ns duplex-link-op $n0 [set n$j] orient $angle
+	incr node_cnt
+
+        # clients
+        set j $node_cnt
+        global n$j
+        set n$j [$ns node]
+        $ns duplex-link $n1 [set n$j] $linkbw  ${accessdly}ms  DropTail
+        $ns queue-limit $n1 [set n$j] $buffersize1
+        $ns queue-limit [set n$j] $n1 $buffersize1
+#        set angle [expr $num_cbrs>1? fmod(2.25-($k-1)*.5/($num_ftps-1), 2) : 0]
+        $ns duplex-link-op $n1 [set n$j] orient $angle
+	incr node_cnt
+    }
+#reverse direction ftps
+    for {set k 0} {$k < $num_revs} {incr k 1} {
+        # clients
+        set j $node_cnt
+        global n$j
+        set n$j [$ns node]
+        $ns duplex-link [set n$j] $n0 $linkbw ${accessdly}ms DropTail
+        $ns queue-limit [set n$j] $n0 $buffersize1
+        $ns queue-limit $n0 [set n$j] $buffersize1
+        set angle [expr $num_ftps>1? 0.75+($k-1)*.5/($num_ftps-1) : 1]
+        $ns duplex-link-op $n0 [set n$j] orient $angle
+	incr node_cnt
+
+        # servers
+        set j $node_cnt
+        global n$j
+        set n$j [$ns node]
+        set dly [expr ($accessdly)*1.1 +($k+1)]
+        $ns duplex-link $n1 [set n$j] $linkbw  ${dly}ms  DropTail
+        $ns queue-limit $n1 [set n$j] $buffersize1
+        $ns queue-limit [set n$j] $n1 $buffersize1
+        set angle [expr $num_ftps>1? fmod(2.25-($k-1)*.5/($num_ftps-1), 2) : 0]
+        $ns duplex-link-op $n1 [set n$j] orient $angle
+	incr node_cnt
+    }
+}
+
+proc build_cbr {cnd snd startTime timeToStop Flow_id} {
+    global ns
+    set udp [$ns create-connection UDP $snd LossMonitor $cnd $Flow_id]
+    set cbr [new Application/Traffic/CBR]
+    $cbr attach-agent $udp
+    # change these for different types of CBRs
+    $cbr set packetSize_ 100
+    $cbr set rate_ 0.064Mb
+    $ns at $startTime "$cbr start"
+    $ns at $timeToStop "$cbr stop"
+}
+
+# cnd is client node, snd is server node
+proc build_ftpclient {cnd snd startTime timeToStop Flow_id} {
+    
+    global ns filesize greedy revftp
+    set ctcp [$ns create-connection TCP/Linux $snd TCPSink/Sack1 $cnd $Flow_id]
+    $ctcp select_ca cubic
+    set ftp [$ctcp attach-app FTP]
+    $ftp set enableResume_ true
+    $ftp set type_ FTP 
+
+#set up a single infinite ftp with smallest RTT
+    if {$greedy > 0 || $filesize < 0} {
+     $ns at $startTime "$ftp start"
+     set greedy 0
+    } else {
+     $ns at $startTime "$ftp send $filesize"
+    }
+    $ns at $timeToStop "$ftp stop"
+}
+
+proc build_webs {cnd snd rate startTime timeToStop} {
+    set CLIENT 0
+    set SERVER 1
+
+    # SETUP PACKMIME
+    set pm [new PackMimeHTTP]
+    $pm set-TCP Sack
+    $pm set-client $cnd
+    $pm set-server $snd
+    $pm set-rate $rate;                    # new connections per second
+    $pm set-http-1.1;                      # use HTTP/1.1
+
+    # create RandomVariables
+    set flow_arrive [new RandomVariable/PackMimeHTTPFlowArrive $rate]
+    set req_size [new RandomVariable/PackMimeHTTPFileSize $rate $CLIENT]
+    set rsp_size [new RandomVariable/PackMimeHTTPFileSize $rate $SERVER]
+
+    # assign RNGs to RandomVariables
+    $flow_arrive use-rng [new RNG]
+    $req_size use-rng [new RNG]
+    $rsp_size use-rng [new RNG]
+
+    # set PackMime variables
+    $pm set-flow_arrive $flow_arrive
+    $pm set-req_size $req_size
+    $pm set-rsp_size $rsp_size
+
+    global ns
+    $ns at $startTime "$pm start"
+    $ns at $timeToStop "$pm stop"
+}
+
+proc uniform {a b} {
+	expr $a + (($b- $a) * ([ns-random]*1.0/0x7fffffff))
+}
+
+proc finish {} {
+        global ns
+	$ns halt
+        $ns flush-trace
+        exit 0
+}
+
+# $ns namtrace-all [open out.nam w]
+# $ns color 2 blue
+# $ns color 3 red
+# $ns color 4 yellow
+# $ns color 5 green
+
+build_topology $ns CoDel
+
+#$ns trace-queue $n0 $n1 [open out_n0ton1.tr w]
+#set fname f${num_ftps}w${web_rate}b${bottleneck}.tr
+set fname f.tr
+puts $fname
+$ns trace-queue $n0 $n1 [open /tmp/$fname w]
+#reverse direction
+#$ns trace-queue $n1 $n0 [open /tmp/$fname w]
+
+set node_cnt 2
+if {$web_rate > 0} {
+        build_webs $n3 $n2 $web_rate 0 $stopTime
+	set node_cnt 4
+}
+
+for {set k 1} {$k <= $num_ftps} {incr k 1} {
+    set j $node_cnt
+    incr node_cnt
+    set i $node_cnt
+    build_ftpclient [set n$i] [set n$j]  \
+ 		$startTime $stopTime $i
+# 		[expr 1.0*($k-1)] $stopTime $i
+# 		[expr $startTime+($k-1)*[uniform 0.0 2.0]] $stopTime $i
+    incr node_cnt
+}
+
+for {set k 1} {$k <= $num_cbrs} {incr k 1} {
+    set j $node_cnt
+    incr node_cnt
+    set i $node_cnt
+    build_cbr [set n$i] [set n$j]  \
+ 		[expr $startTime+($k-1)*[uniform 0.0 2.0]] $stopTime $i
+    incr node_cnt
+}
+
+#for reverse direction, give client smaller number
+for {set k 1} {$k <= $num_revs} {incr k 1} {
+    set j $node_cnt
+    incr node_cnt
+    set i $node_cnt
+    build_ftpclient [set n$j] [set n$i] $startTime $stopTime $j
+    incr node_cnt
+}
+
+$ns at [expr $stopTime ] "finish"
+$ns run
+exit 0
diff -ru --unidirectional-new-file ns-allinone-2.35/ns-2.35/queue/codel.cc ns-allinone-2.35-patched/ns-2.35/queue/codel.cc
--- ns-allinone-2.35/ns-2.35/queue/codel.cc	1969-12-31 16:00:00.000000000 -0800
+++ ns-allinone-2.35-patched/ns-2.35/queue/codel.cc	2012-05-13 22:02:23.000000000 -0700
@@ -0,0 +1,254 @@
+/*
+ * Codel - The Controlled-Delay Active Queue Management algorithm
+ * Copyright (C) 2011-2012 Kathleen Nichols <nichols@pollere.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The names of the authors may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <math.h>
+#include <sys/types.h>
+#include "config.h"
+#include "template.h"
+#include "random.h"
+#include "flags.h"
+#include "delay.h"
+#include "codel.h"
+
+static class CoDelClass : public TclClass {
+  public:
+    CoDelClass() : TclClass("Queue/CoDel") {}
+    TclObject* create(int, const char*const*) {
+        return (new CoDelQueue);
+    }
+} class_codel;
+
+CoDelQueue::CoDelQueue() : tchan_(0)
+{
+    bind("interval_", &interval_);
+    bind("target_", &target_);  // target min delay in clock ticks
+    bind("curq_", &curq_);      // current queue size in bytes
+    bind("d_exp_", &d_exp_);    // current delay experienced in clock ticks
+    q_ = new PacketQueue();     // underlying queue
+    pq_ = q_;
+    reset();
+}
+
+void CoDelQueue::reset()
+{
+    curq_ = 0;
+    d_exp_ = 0.;
+    dropping_ = 0;
+    first_above_time_ = -1;
+    maxpacket_ = 256;
+    count_ = 0;
+    Queue::reset();
+}
+
+// Add a new packet to the queue.  The packet is dropped if the maximum queue
+// size in pkts is exceeded. Otherwise just add a timestamp so dequeue can
+// compute the sojourn time (all the work is done in the deque).
+
+void CoDelQueue::enque(Packet* pkt)
+{
+    if(q_->length() >= qlim_) {
+        // tail drop
+        drop(pkt);
+    } else {
+        HDR_CMN(pkt)->ts_ = Scheduler::instance().clock();
+        q_->enque(pkt);
+    } 
+}
+
+// return the time of the next drop relative to 't'
+double CoDelQueue::control_law(double t)
+{
+    return t + interval_ / sqrt(count_);
+}
+
+// Internal routine to dequeue a packet. All the delay and min tracking
+// is done here to make sure it's done consistently on every dequeue.
+dodequeResult CoDelQueue::dodeque()
+{
+    double now = Scheduler::instance().clock();
+    dodequeResult r = { NULL, 0 };
+
+    r.p = q_->deque();
+    if (r.p == NULL) {
+        curq_ = 0;
+        first_above_time_ = 0;
+    } else {
+        // d_exp_ and curq_ are ns2 'traced variables' that allow the dynamic
+        // queue behavior that drives CoDel to be captured in a trace file for
+        // diagnostics and analysis.  d_exp_ is the sojourn time and curq_ is
+        // the current q size in bytes.
+        d_exp_ = now - HDR_CMN(r.p)->ts_;
+        curq_ = q_->byteLength();
+
+        if (maxpacket_ < HDR_CMN(r.p)->size_)
+            // keep track of the max packet size.
+            maxpacket_ = HDR_CMN(r.p)->size_;
+
+        // To span a large range of bandwidths, CoDel essentially runs two
+        // different AQMs in parallel. One is sojourn-time-based and takes
+        // effect when target_ is larger than the time it takes to send a
+        // TCP MSS packet. The 1st term of the "if" does this.
+        // The other is backlog-based and takes effect when the time to send an
+        // MSS packet is >= target_. The goal here is to keep the output link
+        // utilization high by never allowing the queue to get smaller than
+        // the amount that arrives in a typical interarrival time (one MSS-sized
+        // packet arriving spaced by the amount of time it takes to send such
+        // a packet on the bottleneck). The 2nd term of the "if" does this.
+        if (d_exp_ < target_ || curq_ <= maxpacket_) {
+            // went below - stay below for at least interval
+            first_above_time_ = 0;
+        } else {
+            if (first_above_time_ == 0) {
+                // just went above from below. if still above at first_above_time,
+                // will say it’s ok to drop
+                first_above_time_ = now + interval_;
+            } else if (now >= first_above_time_) {
+                r.ok_to_drop = 1;
+            }
+        }
+    }
+    return r;
+}
+
+// All of the work of CoDel is done here. There are two branches: In packet
+// dropping state (meaning that the queue sojourn time has gone above target
+// and hasn’t come down yet) check if it’s time to leave or if it’s time for
+// the next drop(s). If not in dropping state, decide if it’s time to enter it
+// and do the initial drop.
+
+Packet* CoDelQueue::deque()
+{
+    double now = Scheduler::instance().clock();;
+    dodequeResult r = dodeque();
+
+    if (dropping_) {
+        if (! r.ok_to_drop) {
+            // sojourn time below target - leave dropping state
+            dropping_ = 0;
+        }
+        // It’s time for the next drop. Drop the current packet and dequeue
+        // the next.  If the dequeue doesn't take us out of dropping state,
+        // schedule the next drop. A large backlog might result in drop
+        // rates so high that the next drop should happen now, hence the
+        // ‘while’ loop.
+        while (now >= drop_next_ && dropping_) {
+            drop(r.p);
+            ++count_;
+            r = dodeque();
+            if (! r.ok_to_drop) {
+                // leave dropping state
+                dropping_ = 0;
+            } else {
+                // schedule the next drop.
+                drop_next_ = control_law(drop_next_);
+            }
+        }
+
+    // If we get here we’re not in dropping state. 'ok_to_drop' means that the
+    // sojourn time has been above target for interval so enter dropping state.
+    } else if (r.ok_to_drop) {
+        drop(r.p);
+        r = dodeque();
+        dropping_ = 1;
+
+        // If min went above target close to when it last went below,
+        // assume that the drop rate that controlled the queue on the
+        // last cycle is a good starting point to control it now.
+        count_ = (count_ > 1 && now - drop_next_ < 16*interval_)? count_ - 1 : 1;
+        drop_next_ = control_law(now);
+    }
+    return (r.p);
+}
+
+int CoDelQueue::command(int argc, const char*const* argv)
+{
+    Tcl& tcl = Tcl::instance();
+    if (argc == 2) {
+        if (strcmp(argv[1], "reset") == 0) {
+            reset();
+            return (TCL_OK);
+        }
+    } else if (argc == 3) {
+        // attach a file for variable tracing
+        if (strcmp(argv[1], "attach") == 0) {
+            int mode;
+            const char* id = argv[2];
+            tchan_ = Tcl_GetChannel(tcl.interp(), (char*)id, &mode);
+            if (tchan_ == 0) {
+                tcl.resultf("CoDel trace: can't attach %s for writing", id);
+                return (TCL_ERROR);
+            }
+            return (TCL_OK);
+        }
+        // connect CoDel to the underlying queue
+        if (!strcmp(argv[1], "packetqueue-attach")) {
+            delete q_;
+            if (!(q_ = (PacketQueue*) TclObject::lookup(argv[2])))
+                return (TCL_ERROR);
+            else {
+                pq_ = q_;
+                return (TCL_OK);
+            }
+        }
+    }
+    return (Queue::command(argc, argv));
+}
+
+// Routine called by TracedVar facility when variables change values.
+// Note that the tracing of each var must be enabled in tcl to work.
+void
+CoDelQueue::trace(TracedVar* v)
+{
+    const char *p;
+
+    if (((p = strstr(v->name(), "curq")) == NULL) &&
+        ((p = strstr(v->name(), "d_exp")) == NULL) ) {
+        fprintf(stderr, "CoDel: unknown trace var %s\n", v->name());
+        return;
+    }
+    if (tchan_) {
+        char wrk[500];
+        double t = Scheduler::instance().clock();
+        if(*p == 'c') {
+            sprintf(wrk, "c %g %d", t, int(*((TracedInt*) v)));
+        } else if(*p == 'd') {
+            sprintf(wrk, "d %g %g %d %g", t, double(*((TracedDouble*) v)), count_,
+                    count_? control_law(0.)*1000.:0.);
+        }
+        int n = strlen(wrk);
+        wrk[n] = '\n'; 
+        wrk[n+1] = 0;
+        (void)Tcl_Write(tchan_, wrk, n+1);
+    }
+}
diff -ru --unidirectional-new-file ns-allinone-2.35/ns-2.35/queue/codel.h ns-allinone-2.35-patched/ns-2.35/queue/codel.h
--- ns-allinone-2.35/ns-2.35/queue/codel.h	1969-12-31 16:00:00.000000000 -0800
+++ ns-allinone-2.35-patched/ns-2.35/queue/codel.h	2012-05-13 22:02:27.000000000 -0700
@@ -0,0 +1,84 @@
+/*
+ * Codel - The Controlled-Delay Active Queue Management algorithm
+ * Copyright (C) 2011-2012 Kathleen Nichols <nichols@pollere.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The names of the authors may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ns_codel_h
+#define ns_codel_h
+
+#include "queue.h"
+#include <stdlib.h>
+#include "agent.h"
+#include "template.h"
+#include "trace.h"
+
+// we need a multi-valued return and C doesn't help
+struct dodequeResult { Packet* p; int ok_to_drop; };
+
+class CoDelQueue : public Queue {
+  public:   
+    CoDelQueue();
+  protected:
+    // Stuff specific to the CoDel algorithm
+    void enque(Packet* pkt);
+    Packet* deque();
+
+    // Static state (user supplied parameters)
+    double target_;         // target queue size (in time, same units as clock)
+    double interval_;       // width of moving time window over which to compute min
+
+    // Dynamic state used by algorithm
+    double first_above_time_; // when we went (or will go) continuously above
+                              // target for interval
+    double drop_next_;      // time to drop next packet (or when we dropped last)
+    int count_;             // how many drops we've done since the last time
+                            // we entered dropping state.
+    int dropping_;          // = 1 if in dropping state.
+    int maxpacket_;         // largest packet we've seen so far (this should be
+                            // the link's MTU but that's not available in NS)
+
+    // NS-specific junk
+    int command(int argc, const char*const* argv);
+    void reset();
+    void trace(TracedVar*); // routine to write trace records
+
+    PacketQueue *q_;        // underlying FIFO queue
+    Tcl_Channel tchan_;     // place to write trace records
+    TracedInt curq_;        // current qlen seen by arrivals
+    TracedDouble d_exp_;    // delay seen by most recently dequeued packet
+
+  private:
+    double control_law(double);
+    dodequeResult dodeque();
+};
+
+#endif
diff -ru --unidirectional-new-file ns-allinone-2.35/ns-2.35/tcl/lib/ns-default.tcl ns-allinone-2.35-patched/ns-2.35/tcl/lib/ns-default.tcl
--- ns-allinone-2.35/ns-2.35/tcl/lib/ns-default.tcl	2010-07-03 15:45:45.000000000 -0700
+++ ns-allinone-2.35-patched/ns-2.35/tcl/lib/ns-default.tcl	2012-05-07 07:46:30.000000000 -0700
@@ -248,6 +248,11 @@
 Queue/REM set markpkts_ false
 Queue/REM set qib_ false
 
+Queue/CoDel set curq_ 0.0
+Queue/CoDel set d_exp_ 0.0
+Queue/CoDel set interval_ 0.1
+Queue/CoDel set target_ .005
+
 Queue/GK set ecnlim_ 0.95
 Queue/GK set mean_pktsize_ 1000
 Queue/GK set curq_ 0
