📄 rsvp.cc~
字号:
/* * Copyright (c) 1998 The University of Bonn * All rights reserved. * * Permission to use and copy this software in source and binary forms * is hereby granted, provided that the above copyright notice, this * paragraph and the following disclaimer are retained in any copies * of any part of this software and that the University of Bonn is * acknowledged in all documentation pertaining to any such copy * or derivative work. The name of the University of Bonn may not * be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL * THE UNIVERSITY OF BONN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */#include "rsvp.h"#include "rsvp-objects.h"#include "rsvp-messages.h"#include "rng.h"int hdr_rsvp::offset_ ;static class RSVPHeaderClass : public PacketHeaderClass {public: RSVPHeaderClass() : PacketHeaderClass("PacketHeader/RSVP", sizeof(hdr_rsvp)) { bind_offset (&hdr_rsvp::offset_); } } class_RSVPhdr;static class RSVPClass : public TclClass {public: RSVPClass() : TclClass("Agent/RSVP") {} TclObject* create(int, const char*const*) { return (new RSVPAgent()); }} class_RSVP;RSVPAgent::RSVPAgent() : Agent(PT_RSVP), noisy_(0), next_sid_(0), ip6_(0), s_list_(0), t_list_(0) { //bind("off_rsvp_", &off_rsvp_); bind_bool("noisy_", &noisy_); bind("refresh_", &refresh_); bind("lifetime_factor_", &lifetime_factor_); bind("ip6_", &ip6_); bind("num_flows_", &num_flows_); bind("num_rsb_", &num_rsb_); bind("num_psb_", &num_psb_); bind_bool("nam_", &nam_); /* At the moment, drand48 is used as random generator. This should be changed at some point to use the ns random generators. */ //srand48(gethrtime()); // changed to use the default rng - Sean Murphy 4/12/99}/* Check if any path states have timed out and should be removed. This function returns a '1' if the session was removed in the process (because no state blocks were left), otherwise it returns 0. */char RSVPAgent::check_path(session *s) { psb *temp, *search; double now = Scheduler::instance().clock(); while ((s->psb_list != NULL) && (s->psb_list->phop->get_hop() != -1) && (now > s->psb_list->timeout)) { temp = s->psb_list; s->psb_list = s->psb_list->next; send_path_tear_message(s, temp); if ((noisy_ & UPC_PATHTO) && (temp->timeout != -1)) { Tcl& tcl = Tcl::instance(); tcl.evalf("%s upcall-path-timeout %d %d", name(), s->sid, temp->sender->get_addr()); } delete_rsbs(s, temp); /* (see below) */ clear_psb(temp); delete temp; num_psb_--; } if (s->psb_list != NULL) { search = s->psb_list; while (search->next != NULL) { if ((search->next->phop->get_hop() != -1) && (search->next->timeout < now)) { temp = search->next; search->next = temp->next; if ((noisy_ & UPC_PATHTO) && (temp->timeout != -1)) { Tcl& tcl = Tcl::instance(); tcl.evalf("%s upcall-path-timeout %d %d", name(), s->sid, temp->sender->get_addr()); } send_path_tear_message(s, temp); /* Find all RSBs for this PSB and tear them down and update traffic control accordingly. Important note: No ResvTear messages will be sent as a result of this. RFC 2205 states that ResvTear messages should be sent by end systems or as a result of *reservation* timeouts. However, here we are dealing with a *path* timeout. RFC 2209 does not mention anything about this, and the ISI RSVP demon does not seem to send any ResvTear messages either when a path state expires. */ delete_rsbs(s, temp); clear_psb(temp); delete temp; num_psb_--; } else { search = search->next; } } } if (s->psb_list == NULL) { s->path_ref = -1; } if ((s->resv_ref == -1) && (s->path_ref == -1)) { remove_session(s); return 1; } return 0;}/* Check if any resv states have timed out and should be removed. This function returns 1 if the session was removed in the process, otherwise it returns 0. */char RSVPAgent::check_resv(session *s) { rsb *temp, *search, *r_list; // Tcl& tcl = Tcl::instance(); - unused double now = Scheduler::instance().clock(); r_list = 0; while ((s->rsb_list != NULL) && (s->rsb_list->nhop->get_hop() != -1) && (s->rsb_list->timeout < now)) { temp = s->rsb_list; s->rsb_list = s->rsb_list->next; update_traffic_control(s, temp); if ((noisy_ & UPC_RESVTO) && (temp->timeout != -1) && (temp->nhop->get_hop() != -1)) { Tcl& tcl = Tcl::instance(); tcl.evalf("%s upcall-resv-timeout %d %d", name(), s->sid, temp->sender->get_addr()); } temp->next = r_list; r_list = temp; num_rsb_--; } if (s->rsb_list != NULL) { search = s->rsb_list; while (search->next != NULL) { if ((search->next->nhop->get_hop() != -1) && (search->next->timeout < now)) { temp = search->next; search->next = temp->next; clear_rsb(temp); update_traffic_control(s, temp); if ((noisy_ & UPC_RESVTO) && (temp->timeout != -1) && (temp->nhop->get_hop() != -1)) { Tcl& tcl = Tcl::instance(); tcl.evalf("%s upcall-resv-timeout %d %d", name(), s->sid, temp->sender->get_addr()); } temp->next = r_list; r_list = temp; num_rsb_--; } else { search = search->next; } } } send_resv_tear_messages(s, r_list); refresh_resv(s, 0); while (r_list != NULL) { temp = r_list; r_list = r_list->next; clear_rsb(temp); delete temp; } if (s->rsb_list == NULL) { s->resv_ref = -1; } if ((s->resv_ref == -1) && (s->path_ref == -1)) { remove_session(s); return 1; } return 0;}/* Make sure that all sub-objects of a PSB are deleted */void RSVPAgent::clear_psb(psb *p) { delete p->sender; delete p->s_tspec; delete p->phop;}/* Make sure that all sub-objects of an RSB are deleted */void RSVPAgent::clear_rsb(rsb *r) { delete r->nhop; delete r->fspec; delete r->sender; delete r->st; r->p = NULL;}int RSVPAgent::command(int argc, const char*const* argv) { Tcl& tcl = Tcl::instance(); /* session dest fid */ if (strcmp(argv[1], "session") == 0) { if (argc != 4) { return (TCL_ERROR); } if (argv[2][0] == '_') { tcl.evalf("%s id", argv[2]); tcl.resultf("%d", new_session_sid(atoi(tcl.result()), atoi(argv[3]), 1)); } else { tcl.resultf("%d", new_session_sid(strtol(argv[2], NULL, 0), atoi(argv[3]), 1)); } return (TCL_OK); } /* confirm session-id */ if (strcmp(argv[1], "confirm") == 0) { if (argc != 3) { return (TCL_ERROR); } session *s = find_session_sid(atoi(argv[2])); if (s == NULL) { tcl.resultf("%s RSVP: unknown session ID %s", name(), argv[2]); return(TCL_ERROR); } s->confirm = 1; return (TCL_OK); } /* sender session-id rate bucket-size ttl */ if (strcmp(argv[1], "sender") == 0) { if (argc != 6) { return (TCL_ERROR); } session *s = find_session_sid(atoi(argv[2])); if (s == NULL) { tcl.resultf("%s RSVP: unknown session ID %s", name(), argv[2]); return(TCL_ERROR); } psb *p; // if ((p = find_psb(s, addr_ >> Address::instance().NodeShift_[1])) if ((p = find_psb(s, here_.addr_ )) // SM == NULL) { new_psb(s, atof(argv[3]), atoi(argv[4]), atoi(argv[5]), // addr_ >> Address::instance().NodeShift_[1], -1, here_.addr_ , -1, // SM refresh_, 0, NULL); num_psb_++; } else { update_psb(s, p, atof(argv[3]), atoi(argv[4]), atoi(argv[5]), // addr_ >> Address::instance().NodeShift_[1], -1, here_.addr_ , -1, // SM refresh_, 0, NULL); } return (TCL_OK); } /* reserve session-id style <flow descriptor list> */ if (strcmp(argv[1], "reserve") == 0) { if (argc < 6) { return (TCL_ERROR); } session *s = find_session_sid(atoi(argv[2])); if (s == NULL) { if (noisy_ & UPC_RESVERR) { tcl.evalf("%s upcall-resv-error %s 4 0 %d", name(), argv[2], // addr_ >> Address::instance().NodeShift_[1]); here_.addr_ ); } } else { /* Are there any PSBs for this session? */ if (s->psb_list == NULL) { if (noisy_ & UPC_RESVERR) { tcl.evalf("%s upcall-resv-error %s 3 0 %d", name(), argv[2], // addr_ >> Address::instance().NodeShift_[1]); here_.addr_ ); } } else { if (strcasecmp(argv[3], "ff") != 0) { if (noisy_ & UPC_RESVERR) { tcl.evalf("%s upcall-resv-error %s 6 0 %d", name(), argv[2], // addr_ >> Address::instance().NodeShift_[1]); here_.addr_ ); } } else { process_ff_request(s, argc, argv); } } } return (TCL_OK); } /* release session-id */ if (strcmp(argv[1], "release") == 0) { if (argc != 3) { return (TCL_ERROR); } session *s = find_session_sid(atoi(argv[2])); if (s == NULL) { tcl.evalf("puts \"%s RSVP: unknown session ID %s\"", name(), argv[2]); } else { release_session(s); } return (TCL_OK); } if (strcmp(argv[1], "refresh") == 0) { refresh(); return (TCL_OK); } /* sessions */ if (strcmp(argv[1], "sessions") == 0) { if (argc != 2) { return (TCL_ERROR); } char buf[200]; list_sessions(buf, 200); tcl.resultf("%s", buf); return (TCL_OK); } /* set-status session-id value */ if (strcmp(argv[1], "set-status") == 0) { if (argc != 4) { return (TCL_ERROR); } session *s = find_session_sid(atoi(argv[2])); if (s != NULL) { s->status = atoi(argv[3]); } return (TCL_OK); } /* get-status session-id */ if (strcmp(argv[1], "get-status") == 0) { if (argc != 3) { return (TCL_ERROR); } session *s = find_session_sid(atoi(argv[2])); if (s != NULL) { tcl.resultf("%d", s->status); } return (TCL_OK); } /* set-handle session-id object */ if (strcmp(argv[1], "set-handle") == 0) { if (argc != 4) { return (TCL_ERROR); } session *s = find_session_sid(atoi(argv[2])); if (s != NULL) { strcpy(s->handle, argv[3]); } return (TCL_OK); } /* get-handle session-id */ if (strcmp(argv[1], "get-handle") == 0) { if (argc != 3) { return (TCL_ERROR); } session *s = find_session_sid(atoi(argv[2])); if (s != NULL) { tcl.resultf("%s", s->handle); } return (TCL_OK); } return (Agent::command(argc, argv));}/* Delete all RSBs for the PSB 'p'. */void RSVPAgent::delete_rsbs(session *s, psb *p) { rsb *r, *temp; // Tcl& tcl = Tcl::instance(); - unused while ((s->rsb_list != NULL) && (s->rsb_list->p == p)) { temp = s->rsb_list; s->rsb_list = temp->next; update_traffic_control(s, temp); clear_rsb(temp); delete temp; num_rsb_--; } if (s->rsb_list != NULL) { r = s->rsb_list; while (r->next != NULL) { if (r->next->p == p) { temp = r->next; r->next = temp->next; update_traffic_control(s, temp); clear_rsb(temp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -