21.3 XCP example script

Let's walk through a simple xcp script that is similar to ~ns/tcl/ex/xcp/xcp_test.tcl The example uses a small dumbbell topology having 3 xcp sources running over a bottleneck link.

The topology is setup using the node and link creation APIs. The bottleneck is a duplex link that has a xcp router in both directions. For details on creating nodes, links etc in ns see Marc Greis' NS tutorial at http://www.isi.edu/nsnam/ns/tutorial.

The bottleneck link having a XCP queue is created as follows:

    set R0 [\$ns node]       ;# create Bottleneck between nodes R0 and R1 
    set R1 [\$ns node]
    \$ns duplex-link \$R0 \$R1 \<BW\>Mb \<delay\>ms XCP

The side links connecting source nodes to the bottleneck link have XCP queues as well. The API queue-limit allows users to set the buffer size in the queue.

The xcp source and sink is created as follows (very similar to tcp):

    set xcp [new Agent/TCP/Reno/XCP]
    \$ns attach-agent \$src\_node \$xcp
    set xcp\_sink [new Agent/TCPSink/XCPSink]
    \$ns attach-agent \$rcvr\_node \$xcp\_sink
    \$ns connect \$xcp \$xcp\_sink
    ...
    ...

There is a tcl class GeneralSender used in the example script that sets up xcp agents in the source nodes and then connects them to the xcp receiver in the destination node. An FTP source is used in all the 3 sources.

Note that once the topology is set up the link bandwidth information needs to be propagated to the xcp queue as this is used by the xcp router for feedback calculation. So for every xcp queue use the following tcl command:

$xcp_queue set-link-capacity bandwidth_in_bits_per_sec Next we need to trace variables in the xcp router and xcp sources. The GeneralSender class procedure trace-xcp sets up tracing for xcp sources using variable-tracing in ns.

    GeneralSender instproc trace-xcp parameters {
      $self instvar tcp_ id_ tcpTrace_
      global ftracetcp$id_ 
      set ftracetcp$id_ [open  xcp$id_.tr  w]
      set tcpTrace_ [set ftracetcp$id_]
      $tcp_ attach-trace [set ftracetcp$id_]
      if { -1 \< [lsearch $parameters cwnd]  } { $tcp_ tracevar cwnd_ }
      if { -1 \< [lsearch $parameters seqno] } { $tcp_ tracevar t_seqno_ }
      }

For tracing xcp queue it is required to attach a file descriptor to the xcp queue.

 
    $xcpq attach \<file-descriptor\>

This is an example of how the trace at an xcp source looks like:

    0.00000  2  0  1  0  cwnd_ 1.000 
    0.00000  2  0  1  0  t_seqno_ 0
    0.079 x x x x throughput 0.1
    0.07900  2  0  1  0  t_seqno_ 1
    0.119064 x x x x reverse_feedback_ 0
    0.119064 x x x x controlling_hop_ 0
    0.119064 x x x x newcwnd 1
    0.11906  2  0  1  0  cwnd_ 2.000 
    0.119064 x x x x throughput 50000
    0.11906  2  0  1  0  t_seqno_ 2
    0.119064 x x x x throughput 50000
    0.11906  2  0  1  0  t_seqno_ 3

The first field gives the timestamp; the next 4 fields give the source id (node/port) and destination id (node/port) for the xcp flow. The next field gives the name of the variable being traced followed by the value of the variable. Note that variables like cwnd_, t_seqno_ are using variable tracing which is a function supported by the OTcl lib. While variables like throughput, reverse_feedback use the XCPAgent class function trace_var defined in xcp-end-sys.cc. For more on variable tracing in ns please read section 3.4.3 in the ns manual at http://www.isi.edu/nsnam/ns/doc/index.html

And example of trace output at a xcp bottleneck router looks like below:

    Tq_ 0.0472859 0.025
    queue_bytes_ 0.0472859 0
    routerId_ 0.0472859 0
    pos_fbk 0.053544 0
    neg_fbk 0.053544 0
    delta_throughput 0.053544 0
    Thruput2 0.053544 60000
    pos_fbk 0.054024 0
    neg_fbk 0.054024 0
    delta_throughput 0.054024 0
    Thruput2 0.054024 60000
    residue_pos_fbk_not_allocated 0.0638023 0
    residue_neg_fbk_not_allocated 0.0638023 0
    input_traffic_bytes_ 0.0638023 2480
    avg_rtt_ 0.0638023 0.04

Here the first field describes the name of the variable, the second field gives the timestamp and the third field gives the value of the variable. The XCPQueue class function trace_var() is used to trace variables in the xcp queue.

Additionally packet traces may be created in ns using the following tcl APIs:

    set f\_all [open out.tr w]
    \$ns trace-all \$f\_all

First open a file and then attach the file descriptor to the ns trace object such that a trace of each packet as it travels through the network is logged and dumped into the output file.

An example of such a file would look like:

    + 0.003 4 0 xcp 40 ------- 2 4.0 1.2 0 0
    - 0.003 4 0 xcp 40 ------- 2 4.0 1.2 0 0
    r 0.013016 4 0 xcp 40 ------- 2 4.0 1.2 0 0
    + 0.013016 0 1 xcp 40 ------- 2 4.0 1.2 0 0
    - 0.013016 0 1 xcp 40 ------- 2 4.0 1.2 0 0
    r 0.023032 0 1 xcp 40 ------- 2 4.0 1.2 0 0
    + 0.023032 1 0 ack 40 ------- 2 1.2 4.0 0 1
    - 0.023032 1 0 ack 40 ------- 2 1.2 4.0 0 1
    r 0.033048 1 0 ack 40 ------- 2 1.2 4.0 0 1
    + 0.033048 0 4 ack 40 ------- 2 1.2 4.0 0 1
    - 0.033048 0 4 ack 40 ------- 2 1.2 4.0 0 1
    r 0.043064 0 4 ack 40 ------- 2 1.2 4.0 0 1
    + 0.043064 4 0 xcp 1200 ------- 2 4.0 1.2 1 2
    - 0.043064 4 0 xcp 1200 ------- 2 4.0 1.2 1 2
    + 0.043064 4 0 xcp 1200 ------- 2 4.0 1.2 2 3
    - 0.043544 4 0 xcp 1200 ------- 2 4.0 1.2 2 3

Lets try to read the first line:

+ 0.003 4 0 xcp 40 ---- 2 4.0 1.2 0 0

+ means a packet is enqueued in the queue (in node 4) as it hopped between node 4 to node 0. You'll find traces showing packets enqued (+) and then dequed (-) at the queue, after which it is transmitted over the link to be received by the next node. packet type is xcp and it is of size 40 bytes. The xcp flow has an id of 2 and the packet header has a source node/port id of 4.0 and dest node/port id of 1.2 and the unique packet id is 0.

Tom Henderson 2011-11-05