Appendice A
Riportiamo in questa appendice due script di esempio, uno del modulo RSVP/ns ed uno del modulo MNS.
Partiamo dallo script di RSVP/ns:
$defaultRNG seed 1 set ns [new Simulator]
$ns color 0 red
$ns color 1 blue
$ns color 2 green
$ns color 46 purple
set f0 [open out0.tr w]
set f1 [open out1.tr w]
set f2 [open out2.tr w]
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]
set n4 [$ns node]
# Keep nam trace generation off for now set nf [open out.nam w]
$ns duplex-rsvp-link $n0 $n2 1Mb 1s 0.5 200 5000 Param Null
$ns duplex-rsvp-link $n1 $n2 1Mb 1s 0.5 200 5000 Param Null
$ns duplex-rsvp-link $n2 $n3 1Mb 1s 0.5 200 5000 Param Null
$ns duplex-rsvp-link $n2 $n4 1Mb 1s 0.5 200 5000 Param Null
# Enable upcalls on all nodes Agent/RSVP set noisy_ 255
set rsvp0 [$n0 add-rsvp-agent]
set rsvp1 [$n1 add-rsvp-agent]
set rsvp2 [$n2 add-rsvp-agent]
set rsvp3 [$n3 add-rsvp-agent]
set rsvp4 [$n4 add-rsvp-agent]
# Create three traffic sources set udp1 [new Agent/UDP]
$ns attach-agent $n1 $udp1
$udp1 set packetSize_ 500
$udp1 set fid_ 1
set cbr1 [new Application/Traffic/CBR]
$cbr1 set rate_ 500k
$cbr1 set random_ 1
$cbr1 set packetSize_ 500
$cbr1 attach-agent $udp1
set udp3 [new Agent/UDP]
$ns attach-agent $n3 $udp3
$udp3 set packetSize_ 500
$udp3 set fid_ 2
set cbr3 [new Application/Traffic/CBR]
$cbr3 set rate_ 500k
$cbr3 set random_ 1
$cbr3 set packetSize_ 500
$cbr3 attach-agent $udp3
set udp4 [new Agent/UDP]
$ns attach-agent $n4 $udp4
$udp4 set packetSize_ 500
$udp4 set fid_ 3
set cbr4 [new Application/Traffic/CBR]
$cbr4 set packetSize_ 500
$cbr4 set rate_ 500k
$cbr4 set random_ 1
$cbr4 attach-agent $udp4
set sink1 [new Agent/LossMonitor]
$ns attach-agent $n0 $sink1
set sink3 [new Agent/LossMonitor]
$ns attach-agent $n0 $sink3
set sink4 [new Agent/LossMonitor]
$ns attach-agent $n0 $sink4
$ns connect $udp1 $sink1
$ns connect $udp3 $sink3
$ns connect $udp4 $sink4
# Create the session on sender nodes
$rsvp1 session $n0 1
$rsvp3 session $n0 2
$rsvp4 session $n0 3
set counter 0
$ns at 1.0 "$rsvp1 sender 0 +500000 5000 32"
$ns at 3.0 "$rsvp3 sender 0 +500000 5000 32"
$ns at 5.0 "$rsvp4 sender 0 +500000 5000 32"
$ns at 300 "$rsvp0 reserve 0 ff +100000 100000 $n1"
$ns at 400 "$rsvp0 reserve 0 ff +500000 100000 $n3"
$ns at 500 "$rsvp0 reserve 0 ff +400000 100000 $n3"
$ns at 600 "$rsvp0 reserve 0 ff +100000 100000 $n3"
$ns at 700 "$rsvp0 reserve 0 ff +300000 100000 $n4"
$ns at 10.0 "$cbr1 start"
$ns at 2000.0 "$cbr1 stop"
$ns at 10.0 "$cbr3 start"
$ns at 2000.0 "$cbr3 stop"
$ns at 10.0 "$cbr4 start"
$ns at 2000.0 "$cbr4 stop"
$ns at 2100.0 "finish"
proc finish {}
{
global ns nf $ns flush-trace close $nf
puts "Done"
exit 0 }
$ns run
3
2
1
0 4
3
Passiamo ora allo script d’esempio del modulo MNS:
set ns [new Simulator]
set na [open test-lsp.tr w]
$ns trace-all $na
set nf [open test-lsp.nam w]
$ns namtrace-all $nf
proc finish {} {
global ns na nf $ns flush-trace close $na
close $nf
exec nam test-lsp.nam &
exit 0 }
# make nodes & MPLSnodes set Node0 [$ns node]
set Node1 [$ns node]
set LSR2 [$ns mpls-node]
set LSR3 [$ns mpls-node]
set LSR4 [$ns mpls-node]
set LSR5 [$ns mpls-node]
set LSR6 [$ns mpls-node]
set LSR7 [$ns mpls-node]
set LSR8 [$ns mpls-node]
set Node9 [$ns node]
set Node10 [$ns node]
# make links
$ns duplex-link $Node0 $LSR2 1Mb 10ms DropTail
$ns duplex-link $Node1 $LSR2 1Mb 10ms DropTail
$ns duplex-link $LSR2 $LSR3 1Mb 10ms DropTail
$ns duplex-link $LSR3 $LSR4 1Mb 10ms DropTail
$ns duplex-link $LSR4 $LSR8 1Mb 10ms DropTail
$ns duplex-link $LSR2 $LSR5 1Mb 10ms DropTail
$ns duplex-link $LSR5 $LSR6 1Mb 10ms DropTail
$ns duplex-link $LSR5 $LSR4 1Mb 10ms DropTail
$ns duplex-link $LSR6 $LSR7 1Mb 10ms DropTail
$ns duplex-link $LSR6 $LSR8 1Mb 10ms DropTail
$ns duplex-link $LSR7 $LSR8 1Mb 10ms DropTail
$ns duplex-link $LSR7 $Node9 1Mb 10ms DropTail
$ns duplex-link $LSR8 $Node10 1Mb 10ms DropTail
# configure ldp agents on all mpls nodes
$ns configure-ldp-on-all-mpls-nodes
# set ldp-message colors
$ns ldp-request-color blue
$ns ldp-mapping-color red
$ns ldp-withdraw-color magenta
$ns ldp-release-color orange
$ns ldp-notification-color yellow
# set ldp events
$ns enable-control-driven
# configure-cbq-for-SBTS {qlim cbq_qtype okborrow
# bw maxidle extradelay}
$ns cfg-cbq-for-SBTS 10 DropTail 1 0.1 auto 0
$ns cfg-cbq-for-HBTS 10 DropTail 1 0.05 auto 0
$ns cfg-cbq-for-RTS 10 DropTail 0 0.8 auto 0
$ns cfg-cbq-for-STS 10 DropTail 1 0.05 auto 0
$ns bind-flowid-to-SBTS 100
$ns bind-flowid-to-SBTS 200
$ns bind-flowid-to-SBTS 300
$ns bind-flowid-to-SBTS 400
$ns bind-ldp-to-STS
proc attach-expoo-traffic {node sink size burst idle rate } {
global ns
set source [new Agent/CBR/UDP]
$ns attach-agent $node $source set traffic [new Traffic/Expoo]
$traffic set packet-size $size $traffic set burst-time $burst $traffic set idle-time $idle $traffic set rate $rate
$source attach-traffic $traffic
$ns connect $source $sink return $source
}
set SBTsink [new Agent/LossMonitor]
$ns attach-agent $Node9 $SBTsink
$SBTsink clear
set HBTsink [new Agent/LossMonitor]
$ns attach-agent $Node10 $HBTsink
$HBTsink clear
set RT1sink [new Agent/LossMonitor]
$ns attach-agent $Node9 $RT1sink
$RT1sink clear
set RT2sink [new Agent/LossMonitor]
$ns attach-agent $Node10 $RT2sink
$RT2sink clear
#Create a traffic source
set SBT [attach-expoo-traffic $Node0 $SBTsink 200 0 0 250k]
$SBT set fid_ 100
$ns color 100 red
set HBT [attach-expoo-traffic $Node1 $HBTsink 200 0 0 250k]
$HBT set fid_ 200
$ns color 200 blue
set RT1 [attach-expoo-traffic $Node0 $RT1sink 200 0 0 350k]
$RT1 set fid_ 300
$ns color 300 yellow
set RT2 [attach-expoo-traffic $Node1 $RT2sink 200 0 0 450k]
$RT2 set fid_ 400
$ns color 400 black
proc notify-erlsp-setup {node lspid} { set ns [Simulator instance]
set module [$node get-module "MPLS"]
if {[$node id] == 1} { switch $lspid { 1000 {
$module bind-flow-erlsp 9 100 $lspid }
1100 {
$module bind-flow-erlsp 10 200 $lspid $module set-flow-prio 10 200 1
} 1200 {
$module bind-flow-erlsp 9 300 $lspid }
1300 {
$module bind-flow-erlsp 10 400 $lspid }
default { puts "error"
exit 1 } } } }
# set MPLS modules
for {set i 2} {$i < 9} {incr i} { set a LSR$i
set m [eval $$a get-module "MPLS"]
eval set LSRmpls$i $m }
#event list
$ns at 0 "$LSRmpls2 setup-erlsp 3 2_3_4_5_6_7 1000"
$ns at 0 "$LSRmpls2 setup-erlsp 3 2_3_4_8_7 1100"
# RtModule/MPLS instproc setup-crlsp {fec er lspid
# TRate BSize PSize SPrio HPrio}
$ns at 0.1 "$LSRmpls2 setup-crlsp 8 2_5_4_8 1200 350K 400B 200B 7 3"
$ns at 1.0 "$SBT start"
$ns at 1.0 "$HBT start"
$ns at 1.0 "$RT1 start"
$ns at 10.0 "$LSRmpls2 setup-crlsp 7 2_5_4_8_6_7 1300 450K 400B 200B 7 3"
$ns at 11.0 "$RT2 start"
$ns at 30.0 "$RT2 stop"
$ns at 31.0 "$LSRmpls2 send-crldp-release-msg 1300"
$ns at 40.0 "$SBT stop"
$ns at 40.0 "$HBT stop"
$ns at 40.0 "$RT1 stop"
$ns at 43.0 "finish"
$ns run
3 7
2 6
1
5
9 10
0
4
8
APPENDICE B
In questa appendice sono riportati i principali file sorgente di RSVP-TE\ns, e in particolar modo tutte le parti da noi aggiunte o modificate nel nostro lavoro di implementazione.
FILE RSVP.H
In questo file abbiamo modificato le struct di psb e rsb
struct psb {
psb() : next(0) {};
SENDER_TEMPLATE *sender;
SENDER_TSPEC *s_tspec;
RSVP_HOP *phop;
EXPLICIT_ROUTE_TE *ero;
RECORD_ROUTE_TE *rro;
SESSION_ATTRIBUTE_TE *sess;
CLASSTYPE *classtype;
//DIFFSERV_OBJECT *diff;
LABEL_REQUEST_TE *labreq;
char ttl;
double timeout;
int iif;
int penultimate;
int ingress;
int LIB;
int tid;
RSVPChecker *check;
psb *next;
int flag;
};
struct rsb {
rsb() : confirm(0), modified(0), is_new(0), processed(0), next(0) {};
RSVP_HOP *nhop;
FILTER_SPEC *sender;
FLOWSPEC *fspec;
STYLE *st;
RESV_CONFIRM *confirm;
RSVP_LABEL_TE *label;
psb *p;
nsaddr_t oifhop;
double timeout;
char modified;
char is_new;
char processed;
rsb *old;
rsb *next;
};
FILE RSVP.CC
In questo file abbiamo modificato o aggiunto diverse funzioni:
int RSVPAgent::command(int argc, const char*const*
argv) {
Tcl& tcl = Tcl::instance();
………
//AGGIUNTA
/*failure nodo1 nodo2*/
if (strcmp(argv[1], "failure") == 0) { nsaddr_t prox;
for (int k =100; k>=0; k--) {
session* s= find_session_sid (k);
if (s != NULL) {
elem *pl0 = s->psb_list->ero-
>get_ero();
if (s->psb_list->sender->get_addr() ==
here_.addr_ && pl0 != NULL)
prox = pl0->nodo;
else{
if (pl0 != NULL){
while(pl0->nodo != here_.addr_ &&
pl0->pun!=NULL){
pl0 = pl0->pun; }
if (pl0->pun != NULL){
pl0 = pl0->pun;
prox = pl0->nodo;
} else {
prox = s->s->get_dest() ;
}} else {
prox = s->s->get_dest() ;
}
}
if (prox == atoi(argv[3])) {
send_path_err_msg_after_break (s);
} }}
return (TCL_OK);
}
// AGGIUNTA
/*fail nodo2 nodo1*/
if (strcmp(argv[1], "fail") == 0) { nsaddr_t prec=here_.addr_;
for (int k =100; k>=0; k--) {
session* s= find_session_sid (k);
if (s != NULL) {
if (s->psb_list->sender-
>get_addr() == here_.addr_) { } else {
prec = s->psb_list->phop->get_hop() }
if (prec == atoi(argv[2]))
send_resv_err_message (s, s->rsb_list);
}}
return (TCL_OK); }
………
// MODIFICATA
/* sender session-id rate bucket-size ttl */
if (strcmp(argv[1], "sender") == 0) { if (argc != 10) {
return (TCL_ERROR);
}
elem *pl0 = NULL;
if (atoi(argv[8]) != 0){
int vect[atoi(argv[8])];
int L = strlen(argv[9]);
int a = 0;
string er = argv [9];
int j = 0;
for (int i = 0; i < L; i++){
if (er[i]!='_'){
a = er[i] -48 + (a * 10);
}
else {
vect[j] = a;
a = 0;
j++;
} }
elem *pl;
elem *q;
q=pl0;
for (int i=1; i <= atoi(argv[8]); i++){
pl = new elem;
pl->nodo = vect[i-1];
pl->pun = NULL;
if (q!=NULL) { q->pun=pl;
} else { pl0=pl;
}
q=pl;
} }
………
//MODIFICATA
void RSVPAgent::give(Packet *p, RSVPChecker *ret) { //hdr_rsvp* rsvp_hdr = (hdr_rsvp*)p-
>access(off_rsvp_);
hdr_rsvp* rsvp_hdr = hdr_rsvp::access(p);
//hdr_cmn* cmn_hdr = (hdr_cmn*)p- >access(off_cmn_);
hdr_cmn *cmn_hdr = hdr_cmn::access(p);
RSVPmessage *msg = new RSVPmessage(p- >accessdata());
switch (msg->get_type()) {
case PATH: process_path_message(msg, cmn_hdr- >iface_, ret); break;
case PATHTEAR: process_path_tear_message(msg, cmn_hdr->iface_, ret); break;
case RESV: process_resv_message(msg, rsvp_hdr- >fromhop); break;
case RESVTEAR: process_resv_tear_message(msg);
break;
case RESVERR: process_resv_err_message(msg);
break;
case RESVCONF: process_resv_conf_message(msg);
break;
case PATHERR: process_path_err_message (msg);
break;
}
delete msg;
Packet::free(p);
}
// MODIFICATA
/* Create a new PSB for a given session, add it to the session's PSB list,reschedule the session for refreshing.*/
void RSVPAgent::new_psb(session *s, double rate, long bucket, char ttl, nsaddr_t sender, nsaddr_t phop, double refresh,int iface, RSVPChecker *check,
int tid, int l3, elem *list_e, int n,int ingr, int penult) {
psb *p = new psb();
p->sender = new SENDER_TEMPLATE(sender, ip6_, tid);
p->s_tspec = new SENDER_TSPEC(rate, bucket);
p->phop = new RSVP_HOP(phop, ip6_);
p->labreq = new LABEL_REQUEST_TE(l3);
p->ero= new EXPLICIT_ROUTE_TE(list_e, n);
//p->diff = new DIFFSERV_OBJECT();
//p->classtype = new CLASSTYPE(ct) //p->rro = new RECORD_ROUTE_TE(list_r);
//p->sess = new SESSION_ATTRIBUTE(arg vari);
p->ttl = ttl;
p->iif = iface;
p->tid = tid;
p->penultimate = penult;
p->ingress = ingr;
p->check = check;
if (phop > -1) { // Call came from API
p->timeout = (lifetime_factor_ + 0.5) * 1.5 * refresh + Scheduler::instance().clock();
}
if ((s->psb_list == NULL) || (s->psb_list-
>sender->get_addr() > sender)) { p->next = s->psb_list;
s->psb_list = p;
} else {
psb *search = s->psb_list;
while ((search->next != NULL) &&
(search->next->sender->get_addr() < sender)) { search = search->next;
}
p->next = search->next;
search->next = p;
}
send_path_message(s, p);
/* Reschedule the session if this is the first PSB. Send a path message for this PSB. */
if (s->path_ref == -1) {
s->path_ref = Scheduler::instance().clock() + s->path_tv->get_r();
reschedule_session(s);
}
/* Make an upcall to the API if necessary */
if ((noisy_ & UPC_PATH) && (phop > -1)) { Tcl& tcl = Tcl::instance();
tcl.evalf("%s upcall-path %d %f %d %d", name(), s->sid, rate, bucket, sender);
} }
// MODIFICATA
/* Create a new RSB for a given session and add it to the session's RSB list. */
rsb *RSVPAgent::new_rsb(session *s, psb *p,
nsaddr_t sender, FLOWSPEC *fl, const char *style, nsaddr_t nhop, double refresh, nsaddr_t fromhop, int label) {
rsb *r = new rsb();
r->nhop = new RSVP_HOP(nhop, ip6_);
r->sender = new FILTER_SPEC(sender, ip6_,s->s- >get_tid());
r->fspec = new FLOWSPEC(fl->get_contents());
r->label = new RSVP_LABEL_TE(label);
r->p = p;
r->oifhop = fromhop;
r->modified = 1;
r->is_new = 1;
/* Only valid values for 'style' should arrive here */
if (strcasecmp(style, "FF") == 0) { r->st = new STYLE(STYLE_FF);
}
if (nhop > -1) { // Call came from API
r->timeout = (lifetime_factor_ + 0.5) * 1.5 * refresh + Scheduler::instance().clock();
}
if ((s->rsb_list == NULL) || (s->rsb_list- >sender->get_addr() > sender)) {
s->rsb_list = r;
} else {
rsb *search = s->rsb_list;
while ((search->next != NULL) &&
(search->next->sender->get_addr() < sender)) {search = search->next;
}
r->next = search->next;
search->next = r;
}
return r;
}
// MODIFICATA
void RSVPAgent::process_ff_request(session *s, int argc, const char*const* argv) {
Tcl &tcl = Tcl::instance();
int i = 4;
rsb *r;
psb *p;
nsaddr_t sender;
char modified = 0;
int label;
FLOWSPEC *fl;
/* The following code parses a flow descriptor list which matches the following Backus-Naur form: <flow descriptor list> ::= <FLOWSPEC>
<FILTER_SPEC> |<flow descriptor list><FF flow descriptor>
<FF flow descriptor> ::= [ <FLOWSPEC> ] <FILTER_SPEC>
This conforms with the description in RFC 2205 and means that there can be any number of FILTER_SPEC objects for a FLOWSPEC object. */
while (i < argc) { if (i + 1 >= argc) {
tcl.evalf("%s RSVP: FLOWSPEC incomplete", name());
}
fl=new FLOWSPEC(atoi(argv[i]),atoi(argv[i+1]));
i += 2;
if ((i >= argc) || (argv[i][0] == '+')) {
tcl.evalf("%s RSVP: FILTER_SPEC missing", name());
}
while ((i < argc) && (argv[i][0] != '+')) { if (argv[i][0] == '_') { // if (confirm-
>get_addr() == addr_Address::instance().
NodeShift_[1]) {
tcl.evalf("%s id", argv[i]);
sender = atoi(tcl.result());
} else { // if (confirm->get_addr() == addr_
>> Address::instance().NodeShift_[1]) { sender = atoi(argv[i]);
}
if (((p = find_psb(s, sender)) == NULL) &&
(noisy_ & UPC_RESVERR)) {
tcl.evalf("%s upcall-resv-error %s 4 0
%d %d", name(), argv[2], here_.addr_ , sender);
}
if (p->labreq->get_l3pid() != 0){
label = labe_;
labe_++;
} else {
label = -1;
}
if ((r = find_rsb(s, sender, -1)) == NULL) { new_rsb(s, p, sender, fl, "FF", -1, refresh_, -1, label);
num_rsb_++;
} else {
update_rsb(s, r, p, sender, fl, "FF", - 1, refresh_, -1, label);
} i++;
}
delete fl;
}
rsb *rsearch = s->rsb_list;
while (rsearch != NULL) {
if (rsearch->modified || rsearch->is_new) { modified = 1;
rsearch->modified = 0;
rsearch->is_new = 0;
}
rsearch = rsearch->next;
}
refresh_resv(s, 0);
}
//MODIFICATA
void RSVPAgent::process_path_message(RSVPmessage
*msg, int iface, RSVPChecker *check) {
SESSION *se = (SESSION *)msg->get_first(1);
session *s;
if ((s = find_session_dst(se->get_dest(), se- >get_fid())) == NULL) {
s = new_session_p(se->get_dest(), se- >get_fid(), 0,se->get_tid());
};
psb *p;
SENDER_TEMPLATE *sender = (SENDER_TEMPLATE *)msg- >get_first(11);
TIME_VALUES *tv=(TIME_VALUES *)msg->get_first(5);
SENDER_TSPEC *s_tspec = (SENDER_TSPEC *)msg- >get_first(12);
RSVP_HOP *hop = (RSVP_HOP *)msg->get_first(3);
EXPLICIT_ROUTE_TE *ero = (EXPLICIT_ROUTE_TE *)msg->get_first(20);
//DIFFSERV_OBJECT *diff = (DIFFSERV_OBJECT *)msg->get_first(65);
//CLASSTYPE *classtype = (CLASSTYPE *)msg- >get_first(TBD);
// RECORD_ROUTE_TE *rro = (RECORD_ROUTE_TE *)msg->get_first(21);
// SESSION_ATTRIBUTE_TE *sess =
(SESSION_ATTRIBUTE_TE *)msg->get_first(207);
LABEL_REQUEST_TE *labreq = (LABEL_REQUEST_TE *)msg->get_first(19);
int dst = se ->get_dest();
int rate = s_tspec->get_rate();
int buck = s_tspec->get_size();
int sid = s->sid;
int src = sender->get_addr();
elem *pl0 = ero->get_ero();
int i =ero->get_num();
elem *pll = pl0;
int penult;
int ingr;
if (pll != NULL) {
if (pll->nodo == here_.addr_){
ingr = 1;
} else {
ingr = 0;
} }
for (int x = 1; x < (i-1); x++){
pll = pll->pun;
}
if (pll->nodo == here_.addr_){
penult = 1;
} else {
penult = 0;
}
if((p=find_psb(s, sender->get_addr())) == NULL) { new_psb(s,s_tspec->get_rate(),s_tspec->
get_size(), msg->get_ttl(), sender->get_addr(), hop->get_hop(), tv->get_r(), iface, check, se- >get_tid(), labreq->get_l3pid(), pl0, i,
ingr, penult);
num_psb_++;
} else {
update_psb(s, p, s_tspec->get_rate(), s_tspec->get_size(),msg->get_ttl(), sender-
>get_addr(), hop->get_hop(),tv->get_r(), iface, check, se->get_tid(), labreq-
>get_l3pid(), pl0, i, ingr, penult); } if (here_.addr_ == dst){
Tcl& tcl = Tcl::instance();
tcl.evalf ("%s send-resv %d %d %d %d", name(), sid, rate, buck, src);
} }
//MODIFICATA
void RSVPAgent::process_resv_err_message (RSVPmessage *msg) {
SESSION *se = (SESSION *)msg->get_first(1);
session *s;
rsb *r;
Tcl& tcl = Tcl::instance();
if ((s = find_session_dst(se->get_dest(), se- >get_fid())) == NULL) {
} else {
RSVP_HOP *nhop=(RSVP_HOP *)msg->get_first(3);
FILTER_SPEC *sender = (FILTER_SPEC *)msg- >get_first(10);
ERROR_SPEC *err = (ERROR_SPEC *)msg- >get_first(6);
/* First mark all RSBs which route to the
outgoing interface where the ResvErr message came from. */
while (sender != NULL) { r = s->rsb_list;
while (r != NULL) {
if ((r->p->phop->get_hop()==nhop- >get_hop()) && (r->sender->get_addr() == sender->get_addr())) {
r->processed = 1;
}
r = r->next;
}
msg->delete_first(10);
sender = (FILTER_SPEC *)msg->get_first(10);
}
/* Now send ResvErr messages to each nhop that appears in the marked RSBs. */
r = s->rsb_list;
rsb *c = r;
while (r != NULL) { if (r->processed) {
send_resv_err_message(s, msg, r);
}
r->processed = 0;
r = r->next;
}
if (noisy_ & UPC_RESVERR) {
tcl.evalf("%s upcall-resv-error %d %d %d %d", name(), s->sid, err->get_errcode(), err-
>get_errvalue(), err->get_errnode()); } int x = 0;
elem *pl0 = s->psb_list->ero->get_ero();
while (pl0 != NULL) {
if (pl0->nodo == here_.addr_) { x++;
}
pl0 = pl0->pun;
}
if (x == 0){
} } }
// MODIFICATA
void RSVPAgent::process_resv_message(RSVPmessage
*msg, nsaddr_t fromhop) {
SESSION *se = (SESSION *)msg->get_first(1);
session *s;
char modified = 0;
if ((s = find_session_dst(se->get_dest(), se- >get_fid())) == NULL) {
send_resv_err_message(msg, 3);
} else {
RSVP_HOP *nhop = (RSVP_HOP *)msg->get_first(3);
TIME_VALUES *tv=(TIME_VALUES*)msg>get_first(5);
RSVP_LABEL_TE *lab = (RSVP_LABEL_TE *)msg- >get_first(16);
rsb *r;
psb *p;
FLOWSPEC *fl;
FILTER_SPEC *sender;
long senderaddr ; // SM
fl = (FLOWSPEC *)msg->get_first(9);
while (fl != NULL) {
sender = (FILTER_SPEC *)msg->get_first(10);
// There was a problem here - the sender is // deleted below with the delete_first
// method, but is still assumed to contain // valid data in the while loop below. To //overcome this, I create a new variable - //senderaddr - this is used below - SM senderaddr = sender->get_addr() ;
if((p=find_psb(s,sender->get_addr()))==NULL) { send_resv_err_message(msg, 4);
}
elem *pl0;
elem *prc;
pl0 = p->ero->get_ero();
int f =p->ero->get_num();
int tid = p->tid;
nsaddr_t dest;
dest = se->get_dest();
int label;
int Olab;
if (pl0 !=NULL){
prc = pl0;
for (int i = 0 ; i < (f-1); i++){
prc=prc->pun;
}
nsaddr_t egress;
nsaddr_t prec;
nsaddr_t next;
nsaddr_t previous;
egress = prc->nodo;
if (pl0->nodo == here_.addr_){
previous = -1;
pl0=pl0->pun;
next =pl0->nodo;
} else {
while (pl0->pun !=NULL) { prec = pl0->nodo;
pl0 = pl0->pun;
if (pl0->nodo == here_.addr_ ){
previous = prec;
if (pl0->pun != NULL){
pl0 = pl0->pun;
next = pl0->nodo;
} } } }
int egre = egress;
int nhop = next;
int phop = previous;
int dst = dest;
int out_lab;
out_lab = lab->get_label();
int Oiface;
int Iiface;
int Out;
int r = 0;
if (out_lab >= 0) {
if (p->ingress == 1){
Olab = out_lab;
Iiface = -1;
Oiface =nhop;
Tcl& tcl = Tcl::instance();
tcl.evalf("%s label-create-ing %d %d %d %d %d %d", name(), egre, tid, -1, -1, Oiface, Olab);
r = 1;
}
if(p->penultimate ==1){
label = out_lab;
Out = 0;
Iiface = phop;
Oiface =nhop;
Tcl& tcl = Tcl::instance();
tcl.evalf("%s label-create-pen %d %d %d
%d %d %d", name(), egre, tid, Iiface, label, Oiface, 0) ;
r = 1;
}
if (here_.addr_==egress){//Egress node
label = out_lab;
Olab = -1;
r =1;
}
if (here_.addr_ == senderaddr) {
}
else {
if (r == 0){
label = out_lab;
Olab = out_lab;
Iiface = phop;
Oiface = nhop;
Tcl& tcl = Tcl::instance();
tcl.evalf("%s label-create %d %d
%d %d %d %d", name(), egre, tid, Iiface, label, Oiface, Olab);}
} }
if (out_lab < 0){
label = out_lab;
} }
if ((r = find_rsb(s, sender->get_addr(), nhop->get_hop())) == NULL) {
r = new_rsb(s, p, sender->get_addr(), fl, "FF", nhop->get_hop(), tv->get_r(), fromhop, label);
num_rsb_++;
} else {
update_rsb(s, r, p, sender->get_addr(), fl, "FF", nhop->get_hop(), tv->get_r(), fromhop, label);
}
RESV_CONFIRM *confirm = (RESV_CONFIRM *)msg-
>get_first(15);
if (confirm != NULL) {
r->confirm = new RESV_CONFIRM(confirm-
>get_contents());
}
modified += update_traffic_control(s, r);
msg->delete_first(9);
msg->delete_first(10);
fl = (FLOWSPEC *)msg->get_first(9); } rsb *rsearch = s->rsb_list;
while (rsearch != NULL) {
if (rsearch->modified || rsearch->is_new) { rsearch->modified = 0;
rsearch->is_new = 0;
/* Make an upcall to the API if necessary.
One upcall is made for each new RSB, and resv upcalls are not only made on leaf nodes. */
if (noisy_ & UPC_RESV) { Tcl& tcl = Tcl::instance();
tcl.evalf("%s upcall-resv %d %f %d %d", name(), s->sid, r->fspec->get_rate(), r- >fspec->get_size(), senderaddr); // SM }
}
rsearch = rsearch->next;
}
refresh_resv(s, 0);
} }
// MODIFICATA
/* Create and send a path message for a PSB in a session */
void RSVPAgent::send_path_message(session *s, psb
*p) {
if (nam_) {
type_ = PT_RSVP_PATH;
}
if ((s->s->get_dest() != here_.addr_ ) && // SM (p->ttl >= 1)) {
RSVPmessage *msg = new RSVPmessage(PATH, p- >ttl-1);
msg->add_object(new SESSION(s->s- >get_contents()));
msg->add_object(new TIME_VALUES(s->path_tv- >get_contents()));
msg->add_object(new SENDER_TEMPLATE(p->sender- >get_contents()));
msg->add_object(new SENDER_TSPEC(p->s_tspec- >get_contents()));
msg->add_object(new LABEL_REQUEST_TE(p->labreq- >get_contents()));
msg->add_object(new EXPLICIT_ROUTE_TE(p->ero-
>get_contents()));
// msg->add_object(new DIFFSERV_OBJECT(p->diff- >get_contents()));
// msg->add_object(new CLASSTYPE(p->classtype- >get_contents()));
// msg->add_object(new RECORD_ROUTE_TE(p->rro- >get_contents()));
// msg->add_object(new SESSION_ATTRINUTE(p->sess- >get_contents()));
msg->add_object(new RSVP_HOP(here_.addr_ , ip6_));
if (ip6_) {
size_ = msg->get_length() + 40; // Size for //standard IPv6 header } else {
size_ = msg->get_length() + 24;
}
elem *pl0 = p->ero->get_ero(); //punta al //primo elemento della lista ero if (p->sender->get_addr() == here_.addr_ && pl0 != NULL)
dst_.addr_ = pl0->nodo;
else{
if (pl0 != NULL){
while(pl0->nodo != here_.addr_ && pl0- >pun!=NULL){
pl0 = pl0->pun;
}
if (pl0->pun != NULL){
pl0 = pl0->pun;
dst_.addr_ = pl0->nodo;
} else {
dst_.addr_ = s->s->get_dest() ; }
} else {
dst_.addr_ = s->s->get_dest() ;
}
} fid_ = 46;
Packet *pkt = allocpkt();
hdr_cmn* hdr = hdr_cmn::access(pkt);
pkt->allocdata(msg->get_conlength());
memcpy(pkt->accessdata(), msg->get_contents(), msg->get_conlength());
if (p->phop->get_hop() != -1) { hdr->iface_ = p->iif;
hdr_ip *ip_hdr = hdr_ip::access(pkt);
ip_hdr->saddr() = p->sender->get_addr();
p->check->give(pkt);
} else {
send(pkt, 0);
}
delete msg;
} }
// MODIFICATA
/* Create and send a path tear message for a PSB in a session */
void RSVPAgent::send_path_tear_message(session *s, psb *p) {
if (nam_) {
type_ = PT_PATH_TEAR;
}
if (((s->s->get_dest() != here_.addr_ ) ||
(s->s->get_dest() >= 1 << Address::instance().
McastShift_)) && (p->ttl > 1)) { if (!is_mcast(s->s->get_dest()) ||
!is_leaf(p->sender->get_addr(), s->s- >get_dest())) {
elem *pl0 = p->ero->get_ero();
if (p->sender->get_addr() == here_.addr_ &&
pl0 != NULL)
dst_.addr_ = pl0->nodo;
else{
if (pl0 != NULL){
while(pl0->nodo != here_.addr_ &&
pl0->pun!=NULL){
pl0 = pl0->pun;
}
if (pl0->pun != NULL){
pl0 = pl0->pun;
dst_.addr_ = pl0->nodo;
} } }
RSVPmessage *msg = new RSVPmessage(PATHTEAR, p->ttl-1);
msg->add_object(new SESSION(s->s- >get_contents()));
msg->add_object(new SENDER_TEMPLATE(p- >sender->get_contents()));
msg->add_object(new RSVP_HOP(here_.addr_, ip6_));
/* A SENDER_TSPEC object may be added to the message here. RFC 2205 is unclear about that though. At one point it says that a SENDER_TSPEC is an obligatory part of a sender descriptor,later it says that it may be ommited in a PathTear message and will be ignored. */
size_ = msg->get_length();
if (ip6_) {
size_ = msg->get_length() + 40; //Size for //standard IPv6 header } else {
size_ = msg->get_length() + 24;
}
fid_ = 46;
Packet *pkt = allocpkt();
hdr_cmn* hdr = hdr_cmn::access(pkt) ; pkt->allocdata(msg->get_conlength());
memcpy(pkt->accessdata(), msg-
>get_contents(), msg->get_conlength());
if (p->phop->get_hop() != -1) { hdr->iface_ = p->iif;
hdr_ip *ip_hdr = hdr_ip::access(pkt) ; ip_hdr->saddr() = p->sender-
>get_addr(); //SM
p->check->give(pkt);
} else {
send(pkt, 0);
}
delete msg; } } }
// AGGIUNTA
void RSVPAgent::send_path_err_msg_after_break (session *s) {
if (nam_ ) {
type_ = PT_PATH_TEAR;
}
psb* p = s->psb_list;
if (p!=NULL){
psb* p0=p;
while (p0!=NULL) {
nsaddr_t phop = p0->phop->get_hop();
if (phop!=-1) {
RSVPmessage*msg=new RSVPmessage(PATHERR,32);
msg->add_object(new SESSION(s->s- >get_contents()));
if (ip6_) {
size_ = msg->get_length() + 40;
} else {
size_ = msg->get_length() + 24;
}
dst_.addr_ = phop;
fid_ = 50;
Packet *pkt = allocpkt();
pkt->allocdata(msg->get_conlength());
memcpy(pkt->accessdata(), msg- >get_contents(), msg-
>get_conlength());
send(pkt, 0);
delete msg;
}
if ((p0->sender->get_addr())==
here_.addr_) {
release_session(s);
}
if ((p0->ingress) == 1) {
int lab = -1;
int iiface = -1;
Tcl& tcl = Tcl::instance();
tcl.evalf("%s lookup %d
%d", name(), iiface, lab);
}
p0=p0->next; //mi sposto al psb //successivo
} } }
// AGGIUNTA
void RSVPAgent::process_path_err_message (RSVPmessage *msg) {
Tcl& tcl = Tcl::instance();
SESSION *se = (SESSION *)msg->get_first(1);
session *s = find_session_dst(se->get_dest(), se- >get_fid()); //ricavo il puntatore alla giusta
//session
send_path_err_msg_after_break (s);
}
// MODIFICATA
/* Update an existing PSB with new values. */
void RSVPAgent::update_psb(session *s, psb *p, double rate, long bucket, char ttl, nsaddr_t sender, nsaddr_t phop, double refresh, int iface, RSVPChecker *check, int tid, int l3, elem *list_e, int n, int ingr, int penult) {
/*The following is slightly different from what the RSVP Processing Rules suggest for updated PSBs */
char diff = ((p->sender->get_addr() != sender) ||
(p->s_tspec->get_rate() != rate) ||
(s->s->get_tid() != tid)||
(p->s_tspec->get_size() != bucket) ||
(p->ttl != ttl));
clear_psb(p);
p->sender=new SENDER_TEMPLATE(sender, ip6_, tid);
p->s_tspec = new SENDER_TSPEC(rate, bucket);
p->phop = new RSVP_HOP(phop, ip6_);
p->labreq = new LABEL_REQUEST_TE(l3);
p->ero= new EXPLICIT_ROUTE_TE(list_e, n);
//p->rro = new RECORD_ROUTE_TE(list_r);
//p->sess = new SESSION_ATTRINUTE(arg vari);
p->ttl = ttl;
p->iif = iface;
p->tid = tid;
p->ingress = ingr;
p->penultimate = penult;
p->check = check;
if (phop > -1) {
p->timeout = (lifetime_factor_ + 0.5) * 1.5 * refresh + Scheduler::instance().clock();
}
/* Send a path message for this PSB to inform downstream nodes of the updated path state. */
if ((diff) || ((is_mcast (s->s->get_dest())) &&
(is_leaf(p->sender->get_addr(), s->s- >get_dest())))) {
send_path_message(s, p);
s->path_ref = Scheduler::instance() .clock() + s->path_tv->get_r();
reschedule_session(s);
}
/* Make an upcall to the API if necessary */
if ((noisy_ & UPC_PATH) && (diff)) { Tcl& tcl = Tcl::instance();
tcl.evalf("%s upcall-path %d %f %d %d", name(), s->sid, rate, bucket, sender);
}}}
// MODIFICATA
/* Update an existing RSB with new values. */
void RSVPAgent::update_rsb(session *s, rsb *r, psb
*p, nsaddr_t sender, FLOWSPEC *fl, const char
*style, nsaddr_t nhop, double refresh, nsaddr_t fromhop, int label) {
long nstyle;
if (strcasecmp(style, "FF") == 0) { nstyle = STYLE_FF;
}
r->modified = ((r->fspec->get_rate() != fl- >get_rate()) || (r->fspec->get_size() != fl- >get_size()) || (r->st->get_style() != nstyle) ||
(r->p != p) || (r->oifhop != fromhop));
if (nhop > -1) {
r->timeout = (lifetime_factor_ + 0.5) * 1.5 * refresh + Scheduler::instance().clock();
}
/* Store the old values, so in case the
reservation is rejected by admission control, it can be restored. */
r->old = new rsb();
r->old->nhop = r->nhop;
r->old->sender = r->sender;
r->old->fspec = r->fspec;
r->old->st = r->st;
r->old->oifhop = r->oifhop;
r->old->p = r->p;
r->old->label = r->label;
if (r->modified) {
r->nhop = new RSVP_HOP(nhop, ip6_);
r->sender = new FILTER_SPEC(sender, ip6_,s->s- >get_tid());
r->fspec = new FLOWSPEC(fl->get_contents());
r->st = new STYLE(nstyle);
r->label = new RSVP_LABEL_TE(label);
r->oifhop = fromhop;
r->p = p;
} }
FILE RSVP-OBJECT.H
Anche per questo file, così come per tutti quelli successivi, vengono riportate soltanto le porzioni aggiunte o modificate:
class SESSION : public RSVPobject { public:
SESSION(nsaddr_t dst, char fl, int f, char ip6,int t);
SESSION(unsigned char *cont);
virtual ~SESSION() {};
inline nsaddr_t get_dest() { return con->dest; };
inline int get_fid() { return con->fid; };
inline int get_tid() { return con->tid; };
void dump_object();
private:
struct construct { nsaddr_t dest;
int fid;
int tid;
};
struct construct *con;
};
class FILTER_SPEC : public RSVPobject { public:
FILTER_SPEC(nsaddr_t src, char ip6, int t);
FILTER_SPEC(unsigned char *cont);
virtual ~FILTER_SPEC() {};
inline long get_addr() { return con->addr; };
inline int get_tid() { return con->tid; };
void dump_object();
private:
struct construct { long addr;
int tid;
};
struct construct *con;
};
class SENDER_TEMPLATE : public RSVPobject { public:
SENDER_TEMPLATE(nsaddr_t src, char ip6, int t);
SENDER_TEMPLATE(unsigned char *cont);
virtual ~SENDER_TEMPLATE() {};
inline long get_addr() { return con->addr; };
inline int get_tid() { return con->tid; };
void dump_object();
private:
struct construct { long addr;
int tid;
};
struct construct *con;
};
class RSVP_LABEL_TE : public RSVPobject { public:
RSVP_LABEL_TE(long lab);
RSVP_LABEL_TE(unsigned char *cont);
virtual ~RSVP_LABEL_TE() {};
inline long get_label() { return con->label; };
void dump_object();
private:
struct construct { long label;
};
struct construct *con;
};
class LABEL_REQUEST_TE : public RSVPobject { public:
LABEL_REQUEST_TE(int l3);
LABEL_REQUEST_TE(unsigned char *cont);
virtual ~LABEL_REQUEST_TE() {};
inline int get_l3pid() { return con->l3pid; };
void dump_object();
private:
struct construct { int l3pid;
};
struct construct *con;
};
class EXPLICIT_ROUTE_TE : public RSVPobject { private:
struct construct { elem *com;
int num;
};
struct construct *con;
public:
EXPLICIT_ROUTE_TE(elem* list, int n );
EXPLICIT_ROUTE_TE(unsigned char *cont);
virtual ~EXPLICIT_ROUTE_TE() {};
inline elem* get_ero(){return con->com;};
inline int get_num(){return con->num;};
void dump_object();
};
/*SI CONSIDERA SOLO IL SUBOBJECT RELATIVO A INDIRIZZI IPv4 */
class RECORD_ROUTE_TE : public RSVPobject { private:
struct construct { nsaddr_t *com;
};
struct construct *con;
public:
RECORD_ROUTE_TE(elem* list, int n );
RECORD_ROUTE_TE(unsigned char *cont);
virtual ~RECORD_ROUTE_TE() {};
inline nsaddr_t* get_rro(){return con->com;};
void dump_object();
};
class SESSION_ATTRIBUTE_TE : public RSVPobject { public:
SESSION_ATTRIBUTE_TE(int excl, int inclany, int inclall, int set, int hold, int fl, int l );
SESSION_ATTRIBUTE_TE(unsigned char *cont);
virtual ~SESSION_ATTRIBUTE_TE() {};
inline int get_Excl_any(){return con- >Excl_any;};
inline int get_Incl_any(){return con- >Incl_any;};
inline int get_Incl_all(){return con-
>Incl_all;};
inline int get_SetPrio(){return con->SetPrio;};
inline int get_HoldPrio(){return con- >HoldPrio;};
inline int get_Flags(){return con->Flags;};
inline int get_length(){return con->length;};
void dump_object();
private:
struct construct { int Excl_any;
int Incl_any;
int Incl_all;
int SetPrio;
int HoldPrio;
int Flags;
int length;
};
struct construct *con;
};
class DIFFSERV_OBJECT : public RSVPobject { public:
DIFFSERV_OBJECT(int psc);
DIFFSERV_OBJECT(int e1, int P1,int e2, int P2,int e3, int P3,int e4, int P4,int e5, int P5,int e6, int P6,int e7, int P7,int e8, int P8);
DIFFSERV_OBJECT(unsigned char *cont);
virtual ~DIFFSERV_OBJECT(){};
inline int get_PSC(){return con->PSC;}
inline int get_exp1(){return con->exp1;};
inline int get_PHBid1(){return con->PHBid1;};
inline int get_exp2(){return con->exp2;};
inline int get_PHBid2(){return con->PHBid2;};
inline int get_exp3(){return con->exp3;};
inline int get_PHBid3(){return con->PHBid3;};
inline int get_exp4(){return con->exp4;};
inline int get_PHBid4(){return con->PHBid4;};
inline int get_exp5(){return con->exp5;};
inline int get_PHBid5(){return con->PHBid5;};
inline int get_exp6(){return con->exp6;};
inline int get_PHBid6(){return con->PHBid6;};
inline int get_exp7(){return con->exp7;};
inline int get_PHBid7(){return con->PHBid7;};
inline int get_exp8(){return con->exp8;};
inline int get_PHBid8(){return con->PHBid8;};
void dump_object();
private:
struct construct{
int PSC;
int exp1;
int PHBid1;
int exp2;
int PHBid2;
int exp3;
int PHBid3;
int exp4;
int PHBid4;
int exp5;
int PHBid5;
int exp6;
int PHBid6;
int exp7;
int PHBid7;
int exp8;
int PHBid8;
} ;
struct construct *con;
};
class CLASSTYPE : public RSVPobject { public:
CLASSTYPE(int CT);
CLASSTYPE(unsigned char *cont);
virtual ~CLASSTYPE() {};
inline int get_CT() { return con->CT; };
void dump_object();
private:
struct construct { int CT;
};
struct construct *con;
};