extending ns

54
1 Extending ns Padma Haldar USC/ISI

Upload: yogiinmood

Post on 29-Jun-2015

40 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Extending ns

1

Extending ns

Padma Haldar

USC/ISI

Page 2: Extending ns

2

Outline

Extending nsIn OTclIn C++

Debugging

Page 3: Extending ns

3

ns Directory Structure

TK8.3 OTcl tclclTcl8.3 ns-2 nam-1

tcl

ex test lib

...

...

examples validation tests

C++ code

OTcl code

ns-allinone

mcast

Page 4: Extending ns

4

Extending ns in OTcl

If you don’t want to compilesource your changes in your sim

scripts Otherwise

Modifying code; recompileAdding new files

• Change Makefile (NS_TCL_LIB), tcl/lib/ns-lib.tcl

• Recompile

Page 5: Extending ns

5

Example: Agent/Message

n0 n1

n4

n5

n2

n3

128Kb, 50ms

10Mb, 1ms 10Mb, 1ms

C Ccrosstraffic

S R

msg agent

Page 6: Extending ns

6

Agent/Message

A UDP agent (without UDP header) Up to 64 bytes user message Good for fast prototyping a simple idea Usage requires extending ns functionality

SS RR

pkt: 64 bytesof arbitrary string

Receiver-sideprocessing

Page 7: Extending ns

7

Agent/Message: Step 1

Define senderclass Sender –superclass Agent/Messageclass Sender –superclass Agent/Message

# Message format: “Addr Op SeqNo”# Message format: “Addr Op SeqNo”

Sender instproc send-next {} {Sender instproc send-next {} {

$self instvar seq_ agent_addr_$self instvar seq_ agent_addr_

$self send “$agent_addr_ send $seq_”$self send “$agent_addr_ send $seq_”

incr seq_incr seq_

global nsglobal ns

$ns at [expr [$ns now]+0.1] "$self send-$ns at [expr [$ns now]+0.1] "$self send-next"next"

}}

Page 8: Extending ns

8

Agent/Message: Step 2

Define sender packet processing

Sender instproc Sender instproc recvrecv msg { msg {

$self instvar agent_addr_$self instvar agent_addr_

set sdr [lindex $msg 0]set sdr [lindex $msg 0]

set seq [lindex $msg 2]set seq [lindex $msg 2]

puts "Sender gets ack $seq from $sdr"puts "Sender gets ack $seq from $sdr"

}}

Page 9: Extending ns

9

Agent/Message: Step 3

Define receiver packet processing

Class Receiver –superclass Agent/MessageClass Receiver –superclass Agent/Message

Receiver instproc Receiver instproc recvrecv msg { msg {

$self instvar agent_addr_$self instvar agent_addr_

set sdr [lindex $msg 0]set sdr [lindex $msg 0]

set seq [lindex $msg 2]set seq [lindex $msg 2]

puts “Receiver gets seq $seq from puts “Receiver gets seq $seq from $sdr”$sdr”

$self send “$addr_ ack $seq”$self send “$addr_ ack $seq”

}}

Page 10: Extending ns

10

Agent/Message: Step 4

Scheduler and tracing

# Create scheduler# Create scheduler

set ns [new Simulator]set ns [new Simulator]

# Turn on Tracing# Turn on Tracing

set fd [new “message.tr” w]set fd [new “message.tr” w]

$ns trace-all $fd$ns trace-all $fd

Page 11: Extending ns

11

Agent/Message: Step 5

Topologyfor {set i 0} {$i < 6} {incr i} {for {set i 0} {$i < 6} {incr i} {

set n($i) [$ns node]set n($i) [$ns node]}}$ns duplex-link $n(0) $n(1) 128kb 50ms DropTail$ns duplex-link $n(0) $n(1) 128kb 50ms DropTail$ns duplex-link $n(1) $n(4) 10Mb 1ms DropTail$ns duplex-link $n(1) $n(4) 10Mb 1ms DropTail$ns duplex-link $n(1) $n(5) 10Mb 1ms DropTail$ns duplex-link $n(1) $n(5) 10Mb 1ms DropTail$ns duplex-link $n(0) $n(2) 10Mb 1ms DropTail$ns duplex-link $n(0) $n(2) 10Mb 1ms DropTail$ns duplex-link $n(0) $n(3) 10Mb 1ms DropTail$ns duplex-link $n(0) $n(3) 10Mb 1ms DropTail

$ns queue-limit $n(0) $n(1) 5$ns queue-limit $n(0) $n(1) 5$ns queue-limit $n(1) $n(0) 5$ns queue-limit $n(1) $n(0) 5

Page 12: Extending ns

12

Agent/Message: Step 6

Routing

# Packet loss produced by queueing# Packet loss produced by queueing

# Routing protocol: let’s run distance # Routing protocol: let’s run distance vectorvector

$ns rtproto DV$ns rtproto DV

Page 13: Extending ns

13

Agent/Message: Step 7

Cross trafficset udp0 [new Agent/UDP]set udp0 [new Agent/UDP]$ns attach-agent $n(2) $udp0$ns attach-agent $n(2) $udp0set null0 [new Agent/NULL]set null0 [new Agent/NULL]$ns attach-agent $n(4) $null0$ns attach-agent $n(4) $null0$ns connect $udp0 $null0$ns connect $udp0 $null0

set exp0 [new set exp0 [new Application/Traffic/Exponential]Application/Traffic/Exponential]$exp0 set rate_ 128k$exp0 set rate_ 128k$exp0 attach-agent $udp0$exp0 attach-agent $udp0$ns at 1.0 “$exp0 start”$ns at 1.0 “$exp0 start”

Page 14: Extending ns

14

Agent/Message: Step 8

Message agentsset sdr [new Sender]set sdr [new Sender]$sdr set seq_ 0$sdr set seq_ 0$sdr set packetSize_ 1000$sdr set packetSize_ 1000

set rcvr [new Receiver]set rcvr [new Receiver]$rcvr set packetSize_ 40$rcvr set packetSize_ 40

$ns attach-agent $n(3) $sdr$ns attach-agent $n(3) $sdr$ns attach-agent $n(5) $rcvr$ns attach-agent $n(5) $rcvr$ns connect $sdr $rcvr$ns connect $sdr $rcvr$ns at 1.1 “$sdr send-next”$ns at 1.1 “$sdr send-next”

Page 15: Extending ns

15

Agent/Message: Step 9

End-of-simulation wrapper (as usual)

$ns at 2.0 finish$ns at 2.0 finish

proc finish {} {proc finish {} {

global ns fdglobal ns fd

$ns flush-trace$ns flush-trace

close $fdclose $fd

exit 0exit 0

}}

$ns run$ns run

Page 16: Extending ns

16

Agent/Message: Result

Example output> ./ns msg.tcl> ./ns msg.tclReceiver gets seq 0 from 3Receiver gets seq 0 from 3Sender gets ack 0 from 5Sender gets ack 0 from 5Receiver gets seq 1 from 3Receiver gets seq 1 from 3Sender gets ack 1 from 5Sender gets ack 1 from 5Receiver gets seq 2 from 3Receiver gets seq 2 from 3Sender gets ack 2 from 5Sender gets ack 2 from 5Receiver gets seq 3 from 3Receiver gets seq 3 from 3Sender gets ack 3 from 5Sender gets ack 3 from 5Receiver gets seq 4 from 3Receiver gets seq 4 from 3Sender gets ack 4 from 5Sender gets ack 4 from 5Receiver gets seq 5 from 3Receiver gets seq 5 from 3

Page 17: Extending ns

17

Add Your Changes into ns

TK8.3 OTcl tclclTcl8.3 ns-2 nam-1

tcl

ex test lib

...

...

examples validation tests

C++ code

OTcl code

ns-allinone

mcastmysrc

msg.tcl

Page 18: Extending ns

18

Add Your Change into ns

tcl/lib/ns-lib.tclClass SimulatorClass Simulator……source ../mysrc/msg.tclsource ../mysrc/msg.tcl

MakefileNS_TCL_LIB = \NS_TCL_LIB = \tcl/mysrc/msg.tcl \tcl/mysrc/msg.tcl \……

Or: change Makefile.in, make distcleanmake distclean, then ./configure --enable-debug ,./configure --enable-debug ,

make depend make depend andand make make

Page 19: Extending ns

19

Outline

Extending nsIn OTclIn C++

• New components

Page 20: Extending ns

20

Extending ns in C++

Modifying codemake dependRecompile

Adding code in new filesChange Makefilemake dependrecompile

Page 21: Extending ns

21

Creating New Components

Guidelines Two styles

New agent based on existing packet headers

Add new packet header

Page 22: Extending ns

22

Guidelines

Decide position in class hierarchyI.e., which class to derive from?

Create new packet header (if necessary)

Create C++ class, fill in methods Define OTcl linkage (if any) Write OTcl code (if any) Build (and debug)

Page 23: Extending ns

23

New Agent, Old Header

TCP jump startWide-open transmission window at

the beginningFrom cwnd_ += 1cwnd_ += 1 To cwnd_ = cwnd_ = MAXWIN_MAXWIN_

Page 24: Extending ns

24

TCP Jump Start – Step 1

TclObject

NsObject

Connector Classifier

Delay AddrClassifierAgent McastClasifierQueue Trace

DropTail RED TCP Enq Deq Drop

Reno SACK JS

Handler

Page 25: Extending ns

25

TCP Jump Start – Step 2

New file: tcp-js.h

class JSTCPAgent : public TcpAgent {class JSTCPAgent : public TcpAgent {

public:public:

virtual void set_initial_window() {virtual void set_initial_window() {

cwnd_ = MAXWIN_;cwnd_ = MAXWIN_;

}}

private:private:

int MAXWIN_;int MAXWIN_;

};};

Page 26: Extending ns

26

TCP Jump Start – Step 3

New file: tcp-js.ccstatic JSTcpClass : public TclClass {public:

JSTcpClass() : TclClass("Agent/TCP/JS") {}

TclObject* create(int, const char*const*) {

return (new JSTcpAgent());}

};JSTcpAgent::JSTcpAgent() {

bind(“MAXWIN_”, MAXWIN_);}

Page 27: Extending ns

27

TCP Jump Start – Step 4

Create an instance of jump-start TCP in your tcl script tcp-js.tcl

Set MAXWIN_ value in tcl Add tcp-js.o in Makefile.in Re-configure, make depend and

recompile Run yr tcl script tcp-js.tcl

Page 28: Extending ns

28

Packet Format

header

data

ip header

tcp header

rtp header

trace header

cmn header

...

ts_

ptype_

uid_

size_

iface_

Page 29: Extending ns

29

New Packet Header

Create new header structure Enable tracing support of new header Create static class for OTcl linkage

(packet.h) Enable new header in OTcl (tcl/lib/ns-

packet.tcl) This does not apply when you add a

new field into an existing header!

Page 30: Extending ns

30

How Packet Header Works

Packet

next_

hdrlen_

bits_ size determinedat compile time

size determinedat compile time

size determinedat compile time

……

hdr_cmn

hdr_ip

hdr_tcp

size determinedat simulatorstartup time

(PacketHeaderManager)

PacketHeader/Common

PacketHeader/IP

PacketHeader/TCP

Page 31: Extending ns

31

Example: Agent/Message

New packet header for 64-byte message

New transport agent to process this new header

Page 32: Extending ns

32

New Packet Header – Step 1 Create header structure

struct hdr_msg {struct hdr_msg {char msg_[64];char msg_[64];static int offset_;static int offset_;inline static int& offset() { return inline static int& offset() { return offset_; }offset_; }inline static hdr_msg* access(Packet* p) {inline static hdr_msg* access(Packet* p) {

return (hdr_msg*) p->access(offset_);return (hdr_msg*) p->access(offset_);}}/* per-field member functions *//* per-field member functions */char* msg() { return (msg_); }char* msg() { return (msg_); }int maxmsg() { return (sizeof(msg_)); }int maxmsg() { return (sizeof(msg_)); }

};};

Page 33: Extending ns

33

New Packet Header – Step 2 PacketHeader/Message

static class MessageHeaderClass : static class MessageHeaderClass : public PacketHeaderClass {public PacketHeaderClass {

public:public:MessageHeaderClass() : MessageHeaderClass() : PacketHeaderClass("PacketHeader/MessagePacketHeaderClass("PacketHeader/Message",",

sizeof(hdr_msg)) {sizeof(hdr_msg)) {

bind_offset(&hdr_msg::offset_);bind_offset(&hdr_msg::offset_);}}

} class_msghdr;} class_msghdr;

Page 34: Extending ns

34

New Packet Header – Step 3 Enable tracing (packet.h):

enum packet_t {enum packet_t {PT_TCP,PT_TCP,……,,PT_MESSAGE,PT_MESSAGE,PT_NTYPE // This MUST be the LAST onePT_NTYPE // This MUST be the LAST one

};};class p_info {class p_info {

…………name_[PT_MESSAGE] = “message”;name_[PT_MESSAGE] = “message”;name_[PT_NTYPE]= "undefined";name_[PT_NTYPE]= "undefined";

…………};};

Page 35: Extending ns

35

New Packet Header – Step 4

Register new header (tcl/lib/ns-packet.tcl)

foreach prot {foreach prot {

{ Common off_cmn_ }{ Common off_cmn_ }

……

{ Message off_msg_ }{ Message off_msg_ }

}}

add-packet-header $protadd-packet-header $prot

Page 36: Extending ns

36

Packet Header: Caution

Some old code, e.g.:RtpAgent::RtpAgent() {RtpAgent::RtpAgent() {

…… ……

bind(“off_rtp_”, &off_rtp);bind(“off_rtp_”, &off_rtp);

}}

…………

hdr_rtp* rh = (hdr_rtp*)p-hdr_rtp* rh = (hdr_rtp*)p->access(off_rtp_);>access(off_rtp_);

Don’t follow this example!

Page 37: Extending ns

37

Agent/Message – Step 1

TclObject

NsObject

Connector Classifier

Delay AddrClassifierAgent McastClasifierQueue Trace

DropTail RED TCP Enq Deq Drop

Reno SACK

Message

Page 38: Extending ns

38

Agent/Message – Step 2

C++ class definition// Standard split object declaration// Standard split object declaration

static …static …

class MessageAgent : public Agent {class MessageAgent : public Agent {

public:public:

MessageAgent() : Agent(MessageAgent() : Agent(PT_MESSAGEPT_MESSAGE) {}) {}

virtual int command(int argc, const char*const* virtual int command(int argc, const char*const* argv);argv);

virtual void recv(Packet*, Handler*);virtual void recv(Packet*, Handler*);

};};

Page 39: Extending ns

39

Agent/Message – Step 3

Packet processing: sendint MessageAgent::command(int, const char*const* int MessageAgent::command(int, const char*const*

argv)argv){{

Tcl& tcl = Tcl::instance();Tcl& tcl = Tcl::instance();if (strcmp(argv[1], "send") == 0) {if (strcmp(argv[1], "send") == 0) {

Packet* pkt = allocpkt();Packet* pkt = allocpkt();hdr_msg* mh = hdr_msg::access(pkt);hdr_msg* mh = hdr_msg::access(pkt);// We ignore message size check...// We ignore message size check...strcpy(mh->msg(), argv[2]);strcpy(mh->msg(), argv[2]);send(pkt, 0);send(pkt, 0);return (TCL_OK);return (TCL_OK);

}}return (Agent::command(argc, argv));return (Agent::command(argc, argv));

}}

Page 40: Extending ns

40

Agent/Message – Step 4

Packet processing: receivevoid MessageAgent::recv(Packet* pkt, Handler*)void MessageAgent::recv(Packet* pkt, Handler*){{

hdr_msg* mh = hdr_msg::access(pkt);hdr_msg* mh = hdr_msg::access(pkt);

// OTcl callback// OTcl callbackchar wrk[128];char wrk[128];sprintf(wrk, "%s recv {%s}", name(), mh-sprintf(wrk, "%s recv {%s}", name(), mh->msg());>msg());Tcl& tcl = Tcl::instance();Tcl& tcl = Tcl::instance();tcl.eval(wrk);tcl.eval(wrk);

Packet::free(pkt);Packet::free(pkt);}}

Page 41: Extending ns

41

Outline

Extending nsIn OTclIn C++Debugging: OTcl/C++, memoryPitfalls

Page 42: Extending ns

42

Debugging C++ in ns

C++/OTcl debugging

Memory debuggingpurifydmalloc

Page 43: Extending ns

43

C++/OTcl Debugging

Usual techniqueBreak inside command()Cannot examine states inside OTcl!

SolutionExecute tcl-debug inside gdb

Page 44: Extending ns

44

C++/OTcl Debugging

(gdb) (gdb) call Tcl::instance().eval(“debug 1”)call Tcl::instance().eval(“debug 1”)15: lappend auto_path $dbg_library15: lappend auto_path $dbg_librarydbg15.3> wdbg15.3> w*0: application*0: application 15: lappend auto_path $dbg_library15: lappend auto_path $dbg_librarydbg15.4> Simulator info instancesdbg15.4> Simulator info instances_o1_o1dbg15.5> _o1 nowdbg15.5> _o1 now00dbg15.6> # and other fun stuffdbg15.6> # and other fun stuffdbg15.7> dbg15.7> cc(gdb) where(gdb) where#0 0x102218 in write()#0 0x102218 in write()............

Page 45: Extending ns

45

Memory Debugging in ns

PurifySet PURIFY macro in ns MakefileUsually, put -colloctor=<ld_path>

Gray Watson’s dmalloc libraryhttp://www.dmalloc.com make distclean./configure --with-dmalloc=<dmalloc_path>Analyze results: dmalloc_summarize

Page 46: Extending ns

46

dmalloc: Usage

Turn on dmallocalias dmalloc ’eval ‘\dmalloc –C \!*`’dmalloc -l log low

dmalloc_summarize ns < logfilens must be in current directoryItemize how much memory is

allocated in each function

Page 47: Extending ns

47

Pitfalls

Scalability vs flexibilityOr, how to write scalable simulation?

Memory conservation tips Memory leaks

Page 48: Extending ns

48

Scalability vs Flexibility

It’s tempting to write all-OTcl simulationBenefit: quick prototypingCost: memory + runtime

SolutionControl the granularity of your split

object by migrating methods from OTcl to C++

Page 49: Extending ns

49

THE Merit of OTcl

Program size, complexity

C/C++ OTcl

Smoothly adjust the granularity of scripting to balance extensibility and performance

With complete compatibility with existing simulation scripts

high low

split objects

Page 50: Extending ns

50

Object Granularity Tips

FunctionalityPer-packet processing C++Hooks, frequently changing code

OTcl Data management

Complex/large data structure C++One-time configuration variables

OTcl

Page 51: Extending ns

51

Memory Conservation Tips

Remove unused packet headers Avoid trace-alltrace-all Use arrays for a sequence of variables

Instead of n$in$i, say n($i)n($i) Avoid OTcl temporary variables Use dynamic binding

delay_bind()delay_bind() instead of bind()bind() See object.{h,cc}

See tips for running large sim in ns at www.isi.edu/ns/nsnam/ns-largesim.html

Page 52: Extending ns

52

Memory Conservation Tips

Remove unused packet headers Avoid trace-alltrace-all Use arrays for a sequence of variables

Instead of n$in$i, say n($i)n($i) Avoid OTcl temporary variables Use dynamic binding

delay_bind()delay_bind() instead of bind()bind() See object.{h,cc}

See tips for running large sim in ns at www.isi.edu/ns/nsnam/ns-largesim.html

Page 53: Extending ns

53

Memory Leaks

Purify or dmalloc, but be careful about split objects:for {set i 0} {$i < 500} {incr i} {for {set i 0} {$i < 500} {incr i} {

set a [new set a [new RandomVariable/Constant]RandomVariable/Constant]

}}

It leaks memory, but can’t be detected! Solution

Explicitly delete EVERY split object that was new-ed

Page 54: Extending ns

54

Final Word

My extended ns dumps OTcl scripts!Find the last 10-20 lines of the dumpIs the error related to “_o*** cmd …” ?

• Check your command()

Otherwise, check the otcl script pointed by the error message