📄 rsvp.cc
字号:
temp->psb_list = temp->psb_list->next; clear_psb(p); delete p; num_psb_--; } delete temp; if ((t_list_ != NULL) && (!t_list_->ref_flag)) { t_list_->ref_flag = 1; Tcl& tcl = Tcl::instance(); tcl.evalf("[Simulator instance] at %f \"%s refresh\"", minref(t_list_), name()); }}/* Remove session from timer list and from the session list (unless it is a 'local' session. The difference between release_session and remove_session is that remove_session does not remove local sessions. */void RSVPAgent::remove_session(session *s) { session *search; if (t_list_ == s) { t_list_ = t_list_->t_next; } else { search = t_list_; while (search->t_next != s) { search = search->t_next; } search->t_next = search->t_next->t_next; } if (!s->local) { release_session(s); } if ((t_list_ != NULL) && (!t_list_->ref_flag)) { t_list_->ref_flag = 1; Tcl& tcl = Tcl::instance(); tcl.evalf("[Simulator instance] at %f \"%s refresh\"", minref(t_list_), name()); }}/* Reschedule a session */void RSVPAgent::reschedule_session(session *s) { session *search; s->ref_flag = 0; if (t_list_ == NULL) { t_list_ = s; } else { if (t_list_ == s) { t_list_ = t_list_->t_next; } else { search = t_list_; /* A doubly linked list would make the following code faster, but probably not simpler. However, that feature can be added when it turns out that the simulations run too slow. */ while ((search->t_next != NULL) && (search->t_next != s)) { search = search->t_next; } if (search->t_next == s) { search->t_next = search->t_next->t_next; } } if (t_list_ == NULL) { t_list_ = s; } else { if (minref(s) < minref(t_list_)) { s->t_next = t_list_; t_list_ = s; } else { search = t_list_; while ((search->t_next != NULL) && (minref(search->t_next) < minref(s))) { search = search->t_next; } s->t_next = search->t_next; search->t_next = s; } } } /* If the first element in the timer list hasn't been scheduled for refreshing yet, call Tcl to schedule it. In the ideal case, only the first element of the timer list is scheduled. The worst case, that the scheduler has one entry for each session in each RSVP agent should be avoided. */ if (!t_list_->ref_flag) { t_list_->ref_flag = 1; Tcl& tcl = Tcl::instance(); tcl.evalf("[Simulator instance] at %f \"%s refresh\"", minref(t_list_), name()); }}/* 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() != addr_ >> Address::instance().NodeShift_[1]) && if ((s->s->get_dest() != here_.addr_ ) && // SM (p->ttl >= 1)) { if (is_mcast(s->s->get_dest())) { dst_.addr_ = s->s->get_dest(); } else { // dst_ = s->s->get_dest() << Address::instance().NodeShift_[1]; dst_.addr_ = s->s->get_dest() ; } 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 RSVP_HOP(addr_ >> Address::instance().NodeShift_[1], 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; } fid_ = 46; Packet *pkt = allocpkt(); //hdr_cmn* hdr = (hdr_cmn*)pkt->access(off_cmn_); 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*)pkt->access(off_ip_); hdr_ip *ip_hdr = hdr_ip::access(pkt) ; //ip_hdr->src_ = p->sender->get_addr() << Address::instance().NodeShift_[1]; ip_hdr->saddr() = p->sender->get_addr() ; //SM p->check->give(pkt); } else { send(pkt, 0); } delete msg; }}/* 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() != addr_ >> Address::instance().NodeShift_[1]) || 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())) { if (s->s->get_dest() >= 1 << Address::instance().McastShift_) { dst_.addr_ = s->s->get_dest(); } else { // dst_ = s->s->get_dest() << Address::instance().NodeShift_[1]; dst_.addr_ = s->s->get_dest() ; } 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(addr_ >> Address::instance().NodeShift_[1], 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*)pkt->access(off_cmn_); 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*)pkt->access(off_ip_); hdr_ip *ip_hdr = hdr_ip::access(pkt) ; // ip_hdr->src_ = p->sender->get_addr() << Address::instance().NodeShift_[1]; ip_hdr->saddr() = p->sender->get_addr() ; //SM p->check->give(pkt); } else { send(pkt, 0); } delete msg; } }}/* Create and send a resv confirm message. */void RSVPAgent::send_resv_conf_message(session *s, rsb *r) { if (nam_) { type_ = PT_RESV_CONF; } RSVPmessage *msg = new RSVPmessage(RESVCONF, 32); msg->add_object(new SESSION(s->s->get_contents())); msg->add_object(new STYLE(r->st->get_contents())); msg->add_object(new FILTER_SPEC(r->sender->get_addr(), ip6_)); // msg->add_object(new ERROR_SPEC(addr_ >> Address::instance().NodeShift_[1], msg->add_object(new ERROR_SPEC(here_.addr_ , 0, 0, 0, ip6_)); msg->add_object(new RESV_CONFIRM(r->confirm->get_contents())); if (ip6_) { size_ = msg->get_length() + 40; // Size for standard IPv6 header } else { size_ = msg->get_length() + 24; } Tcl& tcl = Tcl::instance(); tcl.evalf("[Simulator instance] connect-rsvp-agents %d %d", // addr_ >> Address::instance().NodeShift_[1], here_.addr_ , r->confirm->get_addr()); fid_ = 46; Packet *pkt = allocpkt(); pkt->allocdata(msg->get_conlength()); memcpy(pkt->accessdata(), msg->get_contents(), msg->get_conlength()); send(pkt, 0); delete msg;}/* Create and send a resv message based on a reservation message that was received. */void RSVPAgent::send_resv_err_message(RSVPmessage *resvmsg, int code) { if (nam_) { type_ = PT_RESV_ERR; } RSVPmessage *msg = new RSVPmessage(RESVERR, 32); msg->add_object(new SESSION(((SESSION *)resvmsg->get_first(1))->get_contents())); // msg->add_object(new RSVP_HOP(addr_ >> Address::instance().NodeShift_[1], msg->add_object(new RSVP_HOP(here_.addr_ , ip6_)); msg->add_object(new STYLE(((STYLE *)resvmsg->get_first(8))->get_contents())); FILTER_SPEC *sender; sender = (FILTER_SPEC *)resvmsg->get_first(10); while (sender != NULL) { msg->add_object(new FILTER_SPEC(sender->get_contents())); resvmsg->delete_first(10); sender = (FILTER_SPEC *)resvmsg->get_first(10); } // msg->add_object(new ERROR_SPEC(addr_ >> Address::instance().NodeShift_[1], msg->add_object(new ERROR_SPEC(here_.addr_ , 0, code, 0, ip6_)); if (ip6_) { size_ = msg->get_length() + 40; // Size for standard IPv6 header } else { size_ = msg->get_length() + 24; } // dst_ = ((RSVP_HOP *)resvmsg->get_first(3))->get_hop() << Address::instance().NodeShift_[1]; dst_.addr_ = ((RSVP_HOP *)resvmsg->get_first(3))->get_hop() ; fid_ = 46; Packet *pkt = allocpkt(); pkt->allocdata(msg->get_conlength()); memcpy(pkt->accessdata(), msg->get_contents(), msg->get_conlength()); send(pkt, 0); delete msg;}/* Create and send a resv err message (an admission control error, to be exact) for an RSB. */void RSVPAgent::send_resv_err_message(session *s, rsb *r) { if (nam_) { type_ = PT_RESV_ERR; } RSVPmessage *msg = new RSVPmessage(RESVERR, 32); msg->add_object(new SESSION(s->s->get_contents())); // msg->add_object(new RSVP_HOP(addr_ >> Address::instance().NodeShift_[1], msg->add_object(new RSVP_HOP(here_.addr_ , ip6_)); msg->add_object(new STYLE(r->st->get_contents())); msg->add_object(new FILTER_SPEC(r->sender->get_addr(), ip6_)); // msg->add_object(new ERROR_SPEC(addr_ >> Address::instance().NodeShift_[1], msg->add_object(new ERROR_SPEC(here_.addr_ , 0, 1, 0, ip6_)); if (ip6_) { size_ = msg->get_length() + 40; // Size for standard IPv6 header } else { size_ = msg->get_length() + 24; } // dst_ = r->nhop->get_hop() << Address::instance().NodeShift_[1]; dst_.addr_ = r->nhop->get_hop() ; fid_ = 46; Packet *pkt = allocpkt(); pkt->allocdata(msg->get_conlength()); memcpy(pkt->accessdata(), msg->get_contents(), msg->get_conlength()); send(pkt, 0); delete msg;}/* Create and send a resv err message for all RSBs with the same PHOP in their corresponding PSBs. */void RSVPAgent::send_resv_err_message(session *s, RSVPmessage *resvmsg, rsb *r) { if (nam_) { type_ = PT_RESV_ERR; } if (r->nhop->get_hop() != -1) { RSVPmessage *msg = new RSVPmessage(RESVERR, 32); msg->add_object(new SESSION(((SESSION *)resvmsg->get_first(1))->get_contents())); // msg->add_object(new RSVP_HOP(addr_ >> Address::instance().NodeShift_[1], msg->add_object(new RSVP_HOP(here_.addr_ , ip6_)); msg->add_object(new STYLE(((STYLE *)resvmsg->get_first(8))->get_contents())); rsb *rsearch = r; while (rsearch != NULL) { if (rsearch->processed && (rsearch->nhop->get_hop() == r->nhop->get_hop())) { rsearch->processed = 0; msg->add_object(new FILTER_SPEC(rsearch->sender->get_addr(), ip6_)); } rsearch = rsearch->next; } msg->add_object(new ERROR_SPEC(((ERROR_SPEC *)resvmsg->get_first(6))->get_contents())); if (ip6_) { size_ = msg->get_length() + 40; // Size for standard IPv6 header } else { size_ = msg->get_length() + 24; } // dst_ = r->nhop->get_hop() << Address::instance().NodeShift_[1]; dst_.addr_ = r->nhop->get_hop() ; fid_ = 46; Packet *pkt = allocpkt(); pkt->allocdata(msg->get_conlength()); memcpy(pkt->accessdata(), msg->get_contents(), msg->get_conlength()); send(pkt, 0); delete msg; }}/* Create and send a resv message for all RSBs with the same PHOP in their corresponding PSBs. */int RSVPAgent::send_resv_message(session *s, rsb *r, char forced) { if (nam_) { type_ = PT_RSVP_RESV; } char snd = 0; if (r->p->phop->get_hop() != -1) { RSVPmessage *msg = new RSVPmessage(RESV, 32); msg->add_object(new SESSION(s->s->get_contents())); msg->add_object(new TIME_VALUES(s->resv_tv->get_contents())); // msg->add_object(new RSVP_HOP(addr_ >> Address::instance().NodeShift_[1], msg->add_object(new RSVP_HOP(here_.addr_ , ip6_)); msg->add_object(new STYLE(r->st->get_contents())); if (s->confirm) { // msg->add_object(new RESV_CONFIRM(addr_ >> Address::instance().NodeShift_[1], ip6_)); msg->add_object(new RESV_CONFIRM(here_.addr_ , ip6_)); s->confirm = 0; } rsb *rsearch = s->rsb_list; nsaddr_t phop = r->p->phop->get_hop(); nsaddr_t sender; double lub_rate; long lub_size; rsb *rsearch2, *rsearch3; char merged; tcsb *t; while (rsearch != NULL) { if (!rsearch->processed && (rsearch->p->phop->get_hop() == phop)) { /* Calculate the LUB for all RSBs that match 'sender'. */ lub_rate = 0; lub_size = 0; sender = rsearch->sender->get_addr(); rsearch2 = rsearch; while (rsearch2 != NULL) { if (rsearch2->confirm != NULL) { merged = 0; rsearch3 = s->rsb_list; while (!merged && (rsearch3 != NULL)) { if ((rsearch3->p->phop->get_hop() == phop) && (rsearch3 != rsearch2) && (rsearch2->fspec->get_rate() <= rsearch3->fspec->get_rate()) && (rsearch2->fspec->get_size() <= rsearch3->fspec->get_rate())) { merged = 1; } rsearch3 = rsearch3->next; } if (merged) { send_resv_conf_message(s, rsearch2); } else { msg->add_object(new RESV_CONFIRM(rsearch2->confirm->get_contents())); } delete rsearch2->confirm; rsearch2->confirm = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -