Extending ns Padma Haldar USC/ISI 1 Outline Extending ns In - - PowerPoint PPT Presentation

extending ns
SMART_READER_LITE
LIVE PREVIEW

Extending ns Padma Haldar USC/ISI 1 Outline Extending ns In - - PowerPoint PPT Presentation

Extending ns Padma Haldar USC/ISI 1 Outline Extending ns In OTcl In C++ Debugging 2 ns Directory Structure ns-allinone Tcl8.3 TK8.3 OTcl tclcl ns-2 nam-1 ... tcl C+ + code ex test mcast ... lib examples


slide-1
SLIDE 1

1

Extending ns

Padma Haldar USC/ISI

slide-2
SLIDE 2

2

Outline

Extending ns In OTcl In C++ Debugging

slide-3
SLIDE 3

3

ns Directory Structure

TK8.3 OTcl tclcl Tcl8.3 ns-2 nam-1 tcl ex test lib

... ...

examples validation tests C+ + code OTcl code

ns-allinone mcast

slide-4
SLIDE 4

4

Extending ns in OTcl

If you don’t want to compile source your changes in your sim

scripts

Otherwise Modifying code; recompile Adding new files

  • Change Makefile (NS_TCL_LIB),

tcl/lib/ns-lib.tcl

  • Recompile
slide-5
SLIDE 5

5

Example: Agent/Message

n0 n1 n4 n5 n2 n3

128Kb, 50ms 10Mb, 1ms 10Mb, 1ms

C C

cross traffic

S R

msg agent

slide-6
SLIDE 6

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

S S R R

pkt: 64 bytes

  • f arbitrary

string Receiver-side processing

slide-7
SLIDE 7

7

Agent/Message: Step 1

Define sender

class Sender class Sender – –superclass superclass Agent/Message Agent/Message

# Message format: “ # Message format: “Addr Addr Op Op SeqNo SeqNo” Sender Sender instproc instproc send send-next {} { next {} { $self $self instvar instvar seq seq_ _ agent_addr agent_addr_ $self send “$ $self send “$agent_addr agent_addr_ send $ _ send $seq seq_” _” incr incr seq seq_ global ns global ns $ns at [ $ns at [expr expr [$ns now]+0.1] "$self send [$ns now]+0.1] "$self send-next" next" }

slide-8
SLIDE 8

8

Agent/Message: Step 2

Define sender packet processing

Sender Sender instproc instproc recv recv msg msg { { $self $self instvar instvar agent_addr agent_addr_ _ set set sdr sdr [ [lindex lindex $ $msg msg 0] 0] set set seq seq [ [lindex lindex $ $msg msg 2] 2] puts "Sender gets puts "Sender gets ack ack $ $seq seq from $ from $sdr sdr" " } }

slide-9
SLIDE 9

9

Agent/Message: Step 3

Define receiver packet processing

Class Receiver Class Receiver – –superclass superclass Agent/Message Agent/Message Receiver Receiver instproc instproc recv recv msg msg { { $self $self instvar instvar agent_addr agent_addr_ _ set set sdr sdr [ [lindex lindex $ $msg msg 0] 0] set set seq seq [ [lindex lindex $ $msg msg 2] 2] puts “Receiver gets puts “Receiver gets seq seq $ $seq seq from $ from $sdr sdr” ” $self send “$ $self send “$addr addr_ _ ack ack $ $seq seq” ” } }

slide-10
SLIDE 10

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 set fd fd [new “ [new “message.tr message.tr” w] ” w] $ns trace $ns trace-

  • all $

all $fd fd

slide-11
SLIDE 11

11

Agent/Message: Step 5

Topology

for {set i 0} {$i < 6} { for {set i 0} {$i < 6} {incr incr i} { i} { set set n($i n($i) [$ns node] ) [$ns node] } $ns duplex $ns duplex-link $n(0) $n(1) 128kb 50ms link $n(0) $n(1) 128kb 50ms DropTail DropTail $ns duplex $ns duplex-link $n(1) $n(4) 10Mb 1ms link $n(1) $n(4) 10Mb 1ms DropTail DropTail $ns duplex $ns duplex-link $n(1) $n(5) 10Mb 1ms link $n(1) $n(5) 10Mb 1ms DropTail DropTail $ns duplex $ns duplex-link $n(0) $n(2) 10Mb 1ms link $n(0) $n(2) 10Mb 1ms DropTail DropTail $ns duplex $ns duplex-link $n(0) $n(3) 10Mb 1ms link $n(0) $n(3) 10Mb 1ms DropTail DropTail $ns queue $ns queue-limit $n(0) $n(1) 5 limit $n(0) $n(1) 5 $ns queue $ns queue-limit $n(1) $n(0) 5 limit $n(1) $n(0) 5

slide-12
SLIDE 12

12

Agent/Message: Step 6

Routing

# Packet loss produced by # Packet loss produced by queueing queueing # Routing protocol: let’s run distance # Routing protocol: let’s run distance vector vector $ns $ns rtproto rtproto DV DV

slide-13
SLIDE 13

13

Agent/Message: Step 7

Cross traffic

set udp0 [new Agent/UDP] set udp0 [new Agent/UDP] $ns attach $ns attach-

  • agent $n(2) $udp0

agent $n(2) $udp0 set null0 [new Agent/NULL] set null0 [new Agent/NULL] $ns attach $ns attach-

  • agent $n(4) $null0

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 $exp0 attach-

  • agent $udp0

agent $udp0 $ns at 1.0 “$exp0 start” $ns at 1.0 “$exp0 start”

slide-14
SLIDE 14

14

Agent/Message: Step 8

Message agents set set sdr sdr [new Sender] [new Sender] $ $sdr sdr set set seq seq_ 0 _ 0 $ $sdr sdr set set packetSize packetSize_ 1000 _ 1000 set set rcvr rcvr [new Receiver] [new Receiver] $ $rcvr rcvr set set packetSize packetSize_ 40 _ 40 $ns attach $ns attach-

  • agent $n(3) $

agent $n(3) $sdr sdr $ns attach $ns attach-

  • agent $n(5) $

agent $n(5) $rcvr rcvr $ns connect $ $ns connect $sdr sdr $ $rcvr rcvr $ns at 1.1 “$ $ns at 1.1 “$sdr sdr send send-

  • next”

next”

slide-15
SLIDE 15

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 global ns fd fd $ns flush $ns flush-

  • trace

trace close $ close $fd fd exit 0 exit 0 } } $ns run $ns run

slide-16
SLIDE 16

16

Agent/Message: Result

Example output

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

slide-17
SLIDE 17

17

Add Your Changes into ns

TK8.3 OTcl tclcl Tcl8.3 ns-2 nam-1 tcl ex test lib

... ...

examples validation tests C+ + code OTcl code

ns-allinone mcast mysrc msg.tcl

slide-18
SLIDE 18

18

Add Your Change into ns

tcl/lib/ns-lib.tcl

Class Simulator Class Simulator … … source ../ source ../mysrc/msg.tcl mysrc/msg.tcl

Makefile

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

Or: change Makefile.in, make

make distclean distclean,

then ./configure

./configure --

  • -enable

enable-

  • debug ,

debug , make depend make depend and

and make

make

slide-19
SLIDE 19

19

Outline

Extending ns In OTcl In C++

  • New components
slide-20
SLIDE 20

20

Extending ns in C++

Modifying code make depend Recompile Adding code in new files Change Makefile make depend recompile

slide-21
SLIDE 21

21

Creating New Components

Guidelines Two styles New agent based on existing packet

headers

Add new packet header

slide-22
SLIDE 22

22

Guidelines

Decide position in class hierarchy I.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)

slide-23
SLIDE 23

23

New Agent, Old Header

TCP jump start Wide-open transmission window at

the beginning

From cwnd

cwnd_ += 1 _ += 1 To cwnd cwnd_ = _ = MAXWIN_ MAXWIN_

slide-24
SLIDE 24

24

TCP Jump Start – Step 1

TclObject NsObject Connector Classifier Delay AddrClassifier Agent McastClasifier Queue Trace DropTail RED TCP Enq Deq Drop Reno SACK

JS

Handler

slide-25
SLIDE 25

25

TCP Jump Start – Step 2

New file: tcp-js.h class class JSTCPAgent JSTCPAgent : public : public TcpAgent TcpAgent { { public: public: virtual void virtual void set_initial_window set_initial_window() { () { cwnd cwnd_ = MAXWIN_; _ = MAXWIN_; } } private: private: int int MAXWIN_; MAXWIN_; }; };

slide-26
SLIDE 26

26

TCP Jump Start – Step 3

New file: tcp-js.cc

static JSTcpClass : public TclClass { public: JSTcpClass() : TclClass("Agent/TCP/JS") {} TclObject* create(int, const char*const*) { return (new JSTcpAgent()); } }; JSTcpAgent::JSTcpAgent() { bind(“MAXWIN_”, MAXWIN_); }

slide-27
SLIDE 27

27

Packet Format

header data ip header tcp header rtp header trace header cmn header ... ts_ ptype_ uid_ size_ iface_

slide-28
SLIDE 28

28

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!

slide-29
SLIDE 29

29

How Packet Header Works

Packet next_ hdrlen_ bits_

size determined at compile time size determined at compile time size determined at compile time …… hdr_cmn hdr_ip hdr_tcp size determined at simulator startup time

(PacketHeaderManager) PacketHeader/ Common PacketHeader/ I P PacketHeader/ TCP

slide-30
SLIDE 30

30

Example: Agent/Message

New packet header for 64-byte

message

New transport agent to process this

new header

slide-31
SLIDE 31

31

New Packet Header – Step 1

Create header structure

struct struct hdr_msg hdr_msg { { char msg_[64]; char msg_[64]; static static int int offset_;

  • ffset_;

inline static inline static int int& offset() { return & offset() { return

  • ffset_; }
  • ffset_; }

inline static inline static hdr_msg hdr_msg* * access(Packet access(Packet* p) { * p) { return ( return (hdr_msg hdr_msg*) p *) p-

  • >

>access(offset access(offset_); _); } } /* per /* per-

  • field member functions */

field member functions */ char* char* msg msg() { return ( () { return (msg msg_); } _); } int int maxmsg maxmsg() { return ( () { return (sizeof(msg sizeof(msg_)); } _)); } }; };

slide-32
SLIDE 32

32

New Packet Header – Step 2

PacketHeader/Message static class static class MessageHeaderClass MessageHeaderClass : : public public PacketHeaderClass PacketHeaderClass { { public: public: MessageHeaderClass MessageHeaderClass() : () : PacketHeaderClass("PacketHeader PacketHeaderClass("PacketHeader/Message /Message ", ", sizeof(hdr_msg sizeof(hdr_msg)) { )) { bind_offset(&hdr_msg::offset bind_offset(&hdr_msg::offset_); _); } } } } class_msghdr class_msghdr; ;

slide-33
SLIDE 33

33

New Packet Header – Step 3

Enable tracing (packet.h): enum enum packet_t packet_t { { PT_TCP, PT_TCP, …, …, PT_MESSAGE, PT_MESSAGE, PT_NTYPE // This MUST be the LAST one PT_NTYPE // This MUST be the LAST one }; }; class class p_info p_info { { …… …… name_[PT_MESSAGE name_[PT_MESSAGE] = “message”; ] = “message”; name_[PT_NTYPE name_[PT_NTYPE]= "undefined"; ]= "undefined"; …… …… }; };

slide-34
SLIDE 34

34

New Packet Header – Step 4

Register new header (tcl/lib/ns-

packet.tcl)

foreach foreach pair { pair { { Common { Common off_cmn

  • ff_cmn_ }

_ } … … { Message { Message off_msg

  • ff_msg_ }

_ } } }

slide-35
SLIDE 35

35

Packet Header: Caution

Some old code, e.g.:

RtpAgent::RtpAgent RtpAgent::RtpAgent() { () { …… …… bind(“off_rtp bind(“off_rtp_”, & _”, &off_rtp

  • ff_rtp);

); } } …… …… hdr_rtp hdr_rtp* * rh rh = ( = (hdr_rtp hdr_rtp*)p *)p-

  • >

>access(off_rtp access(off_rtp_); _);

Don’t follow this example!

slide-36
SLIDE 36

36

Agent/Message – Step 1

TclObject NsObject Connector Classifier Delay AddrClassifier Agent McastClasifier Queue Trace DropTail RED TCP Enq Deq Drop Reno SACK

Message

slide-37
SLIDE 37

37

Agent/Message – Step 2

C++ class definition

// Standard split object declaration // Standard split object declaration static … static … class class MessageAgent MessageAgent : public Agent { : public Agent { public: public: MessageAgent MessageAgent() : () : Agent( Agent(PT_MESSAGE PT_MESSAGE) {} ) {} virtual virtual int int command(int command(int argc argc, const char*const* , const char*const* argv argv); ); virtual void virtual void recv(Packet recv(Packet*, Handler*); *, Handler*); }; };

slide-38
SLIDE 38

38

Agent/Message – Step 3

Packet processing: send

int int MessageAgent::command(int MessageAgent::command(int, const char*const* , const char*const* argv argv) { Tcl Tcl& & tcl tcl = = Tcl::instance Tcl::instance(); (); if (strcmp(argv[1], "send") == 0) { if (strcmp(argv[1], "send") == 0) { Packet* Packet* pkt pkt = = allocpkt allocpkt(); (); hdr_msg hdr_msg* * mh mh = = hdr_msg::access(pkt hdr_msg::access(pkt); ); // We ignore message size check... // We ignore message size check... strcpy(mh strcpy(mh->msg msg(), argv[2]); (), argv[2]); send(pkt send(pkt, 0); , 0); return (TCL_OK); return (TCL_OK); } return ( return (Agent::command(argc Agent::command(argc, , argv argv)); )); }

slide-39
SLIDE 39

39

Agent/Message – Step 4

Packet processing: receive void void MessageAgent::recv(Packet MessageAgent::recv(Packet* * pkt pkt, Handler*) , Handler*) { { hdr_msg hdr_msg* * mh mh = = hdr_msg::access(pkt hdr_msg::access(pkt); ); // // OTcl OTcl callback callback char wrk[128]; char wrk[128]; sprintf(wrk sprintf(wrk, "%s , "%s recv recv {%s}", name(), {%s}", name(), mh mh-

  • >

>msg msg()); ()); Tcl Tcl& & tcl tcl = = Tcl::instance Tcl::instance(); (); tcl.eval(wrk tcl.eval(wrk); ); Packet::free(pkt Packet::free(pkt); ); } }

slide-40
SLIDE 40

40

Outline

Extending ns In OTcl In C++ Debugging: OTcl/C++, memory Pitfalls

slide-41
SLIDE 41

41

Debugging C++ in ns

C++/OTcl debugging Memory debugging purify dmalloc

slide-42
SLIDE 42

42

C++/OTcl Debugging

Usual technique Break inside command() Cannot examine states inside OTcl! Solution Execute tcl-debug inside gdb

slide-43
SLIDE 43

43

C++/OTcl Debugging

( (gdb gdb) ) call call Tcl::instance().eval(“debug Tcl::instance().eval(“debug 1”) 1”) 15: 15: lappend lappend auto_path auto_path $ $dbg_library dbg_library dbg15.3> w dbg15.3> w *0: application *0: application 15: 15: lappend lappend auto_path auto_path $ $dbg_library dbg_library dbg15.4> Simulator info instances dbg15.4> Simulator info instances _o1 _o1 dbg15.5> _o1 now dbg15.5> _o1 now dbg15.6> # and other fun stuff dbg15.6> # and other fun stuff dbg15.7> dbg15.7> c c ( (gdb gdb) where ) where #0 0x102218 in write() #0 0x102218 in write() ...... ......

slide-44
SLIDE 44

44

Memory Debugging in ns

Purify Set PURIFY macro in ns Makefile Usually, put -colloctor=<ld_path> Gray Watson’s dmalloc library http://www.dmalloc.com make distclean ./configure --with-dmalloc=<dmalloc_path> Analyze results: dmalloc_summarize

slide-45
SLIDE 45

45

dmalloc: Usage

Turn on dmalloc alias dmalloc ’eval ‘\dmalloc –C \!*`’ dmalloc -l log low dmalloc_summarize ns < logfile ns must be in current directory Itemize how much memory is

allocated in each function

slide-46
SLIDE 46

46

Pitfalls

Scalability vs flexibility Or, how to write scalable simulation? Memory conservation tips Memory leaks

slide-47
SLIDE 47

47

Scalability vs Flexibility

It’s tempting to write all-OTcl

simulation

Benefit: quick prototyping Cost: memory + runtime Solution Control the granularity of your split

  • bject by migrating methods from

OTcl to C++

slide-48
SLIDE 48

48

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

slide-49
SLIDE 49

49

Object Granularity Tips

Functionality Per-packet processing C++ Hooks, frequently changing code

OTcl

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

OTcl

slide-50
SLIDE 50

50

Memory Conservation Tips

Remove unused packet headers Avoid trace

trace-

  • all

all

Use arrays for a sequence of variables Instead of n$i

n$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

slide-51
SLIDE 51

51

Memory Leaks

Purify or dmalloc, but be careful about split

  • bjects:

for {set i 0} {$i < 500} { for {set i 0} {$i < 500} {incr incr i} { i} { set a [new set a [new RandomVariable RandomVariable/Constant] /Constant] } }

It leaks memory, but can’t be detected! Solution Explicitly delete EVERY split object that was

new-ed

slide-52
SLIDE 52

52

Final Word

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

  • Check your command()

Otherwise, check the otcl script

pointed by the error message