⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rsvp.cc

📁 rsvp and wfq patch for Netowrk Simulator 2
💻 CC
📖 第 1 页 / 共 5 页
字号:
	  Tcl& tcl = Tcl::instance();	  tcl.evalf("%s upcall-path-tear %d %d", name(), s->sid, 		    sender->get_addr());	}	/* The necessary actions for deleting the path state would	   be fairly complicated. The PSB  and all corresponding RSBs	   have to be deleted and the session has to be removed if this 	   PSB was the last state block. To make this short, a 'trick' 	   will be used. The timeout for this PSB will be set to -1, and 	   then a check_path will be performed, which will definitely 	   remove this PSB (and perhaps even clean up some other PSBs 	   which are due for removal in the process). */	p->timeout = -1;	if (!check_path(s)) {	  reschedule_session(s);	}      }    }  }}void RSVPAgent::process_resv_conf_message(RSVPmessage *msg) {  RESV_CONFIRM *confirm = (RESV_CONFIRM *)msg->get_first(15);  // if (confirm->get_addr() == addr_ >> Address::instance().NodeShift_[1]) {  if (confirm->get_addr() == here_.addr_ ) {    SESSION *se = (SESSION *)msg->get_first(1);    session *s;    if ((s = find_session_dst(se->get_dest(), se->get_fid())) != NULL) {      FILTER_SPEC *sender = (FILTER_SPEC *)msg->get_first(10);      ERROR_SPEC *err = (ERROR_SPEC *)msg->get_first(6);      if (noisy_ & UPC_RESVCONF) {	Tcl& tcl = Tcl::instance();	tcl.evalf("%s upcall-resv-confirm %d %d %d", name(), s->s->get_fid(),		  sender->get_addr(), err->get_errnode());      }    }  } else {    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_ ,	      confirm->get_addr());    Packet *pkt = allocpkt();    pkt->allocdata(msg->get_conlength());    memcpy(pkt->accessdata(), msg->get_contents(), msg->get_conlength());    send(pkt, 0);  }}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;    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());    }  }}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);    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);      }      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);	num_rsb_++;      } else {	update_rsb(s, r, p, sender->get_addr(), fl, "FF", nhop->get_hop(), 		   tv->get_r(), fromhop);      }      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(), 		    //sender->get_addr());                    senderaddr) ; // SM	}      }      rsearch = rsearch->next;    }    refresh_resv(s, 0);  }}void RSVPAgent::process_resv_tear_message(RSVPmessage *msg) {  SESSION *se = (SESSION *)msg->get_first(1);  session *s;  // Tcl& tcl = Tcl::instance(); - unused  rsb *r, *r_list, *temp;  /* Check if a session exists for this ResvTear message, otherwise     drop the message silently. */  if ((s = find_session_dst(se->get_dest(), se->get_fid())) != NULL) {    FILTER_SPEC *sender;    RSVP_HOP *nhop = (RSVP_HOP *)msg->get_first(3);    r_list = 0;    sender = (FILTER_SPEC *)msg->get_first(10);    /* Read each FILTER_SPEC from the message and delete the corresponding       RSBs from the rsb_list, putting them in a different list for further       processing. */    while (sender != NULL) {      while ((s->rsb_list != NULL) && 	     (s->rsb_list->sender->get_addr() == sender->get_addr()) &&	     (s->rsb_list->nhop->get_hop() == nhop->get_hop())) {	temp = s->rsb_list;	s->rsb_list = temp->next;	temp->next = r_list;	r_list = temp;	update_traffic_control(s, temp);	if ((noisy_ & UPC_RESVTEAR) && (temp->timeout != -1)) {	  Tcl& tcl = Tcl::instance();	  tcl.evalf("%s upcall-resv-tear %d %d", name(),  s->sid, 		    temp->sender->get_addr());	}      }      if (s->rsb_list != NULL) {	r = s->rsb_list;	while (r != NULL) {	  if ((r->next != NULL) &&	      (r->next->sender->get_addr() == sender->get_addr()) &&	      (r->next->nhop->get_hop() == nhop->get_hop())) {	    temp = r->next;	    r->next = temp->next;	    temp->next = r_list;	    r_list = temp;	    num_rsb_--;	    update_traffic_control(s, temp);	    if ((noisy_ & UPC_RESVTEAR) && (temp->timeout != -1)) {	      Tcl& tcl = Tcl::instance();	      tcl.evalf("%s upcall-resv-tear %d %d", name(),  s->sid, 			temp->sender->get_addr());	    }	  }	  r = r->next;	}      }      msg->delete_first(10);      sender = (FILTER_SPEC *)msg->get_first(10);         }  }  if (r_list != NULL) {    refresh_resv(s, 0);    while ((r_list != NULL) && (find_rsb_for_psb(s, r_list->p))) {      temp = r_list;      r_list = r_list->next;      clear_rsb(temp);      delete temp;    }    if (r_list != NULL) {      r = r_list;      while (r->next != NULL) {	if (find_rsb_for_psb(s, r->p)) {	  temp = r->next;	  r->next = temp->next;	  clear_rsb(temp);	  delete temp;	}      }    }    if (r_list != NULL) {      send_resv_tear_messages(s, r_list);    }    while (r_list != NULL) {      temp = r_list;      r_list = r_list->next;      clear_rsb(temp);      delete temp;    }  }}void RSVPAgent::recv(Packet* p, Handler* h) {  /* All packets are already being processed by the 'give' function,     so get rid of this packet. */  Packet::free(p);}/* Refresh the path/reservation state for all sessions that need to be   refreshed (usually that should only be the first session in the    timer list).   */void RSVPAgent::refresh() {  double now = Scheduler::instance().clock();  /* PSB and RSB timeouts are checked with every refresh for this     session and not when the actual timeout occurs. That means that     path and reservation state might time out a bit slower in the     simulation than in a real system (though no refresh messages from     these states will be sent after the timeout), but this behaviour     is not incorrect, since RFC 2205 states that L (a state's lifetime)     should be equal *or greater* than (K + 0.5) * 1.5 * R. */  if ((t_list_ != NULL) && in_range(minref(t_list_), now)) {    check_path(t_list_);    if (t_list_ != NULL) {      check_resv(t_list_);    }    if (t_list_ != NULL) {      if (in_range(minref(t_list_), now)) {	if (minref(t_list_) == t_list_->path_ref) {	  refresh_path(t_list_);	} else {	  /* Force a reservation refresh */	  refresh_resv(t_list_, 1);	}      } else {	reschedule_session(t_list_);      }    }  }}/* Create and send path messages for this session, then reschedule   the session. */void RSVPAgent::refresh_path(session *s) {  psb *p = s->psb_list;  while (p != NULL) {    if (!is_mcast(s->s->get_dest()) ||	!is_leaf(p->sender->get_addr(), s->s->get_dest())) {      send_path_message(s, p);    }    p = p->next;  }  s->path_ref = Scheduler::instance().clock() + s->path_tv->get_r();  reschedule_session(s);}/* Create and send resv messages for this session, then reschedule   the session. If the 'forced' flag is off, this function merely checks   if a refresh is necessary (for example after a new RSB was added).   If it finds a reservation state that has to be updated, it performs a   normal refresh. */void RSVPAgent::refresh_resv(session *s, char forced) {  rsb *rsearch = s->rsb_list;  rsb *rsearch2;  while (rsearch != NULL) {    if (!rsearch->processed) {      /* Send a reservation message for all RSBs with the same PHOP	 in their corresponding PSBs as rsearch. */      if (send_resv_message(s, rsearch, forced) && !forced) {	/* A reservation has changed and had to be forwarded. Force	   a refresh for the whole reservation state. */	forced = 1;	rsearch2 = s->rsb_list;	while (rsearch2 != NULL) {	  rsearch2->processed = 0;	  rsearch2 = rsearch2->next;	}	rsearch2 = s->rsb_list;	while (rsearch2 != rsearch) {	  if (rsearch->processed) {	    send_resv_message(s, rsearch2, forced);	  }	  rsearch2 = rsearch2->next;	}      }    }    rsearch = rsearch->next;  }  rsearch = s->rsb_list;  while (rsearch != NULL) {    rsearch->processed = 0;    rsearch = rsearch->next;  }  if (forced) {    /* Only set a new refresh timeout if any messages were actually sent. */    s->resv_ref = Scheduler::instance().clock() + s->resv_tv->get_r();    reschedule_session(s);  }}/* Release a session. Remove it from the timer list and from the   session list, and send appropriate teardown messages for all path   and reservation states. */void RSVPAgent::release_session(session *s) {  session *search, *temp;  // Tcl& tcl = Tcl::instance(); - unused  /* First remove the session from the timer list */  if (t_list_ != NULL) {    if (t_list_ == s) {      t_list_ = t_list_->t_next;    } else {      search = t_list_;      while ((search->t_next != s) && (search->t_next != NULL)) {	search = search->t_next;      }      if (search->t_next != NULL) {	search->t_next = search->t_next->t_next;      }    }  }  /* Now remove the session from the session list and send teardown     messages for all existing path and reservation states. */  if (s_list_ == s) {    s_list_ = s_list_->next;    temp = s;  } else {    search = s_list_;    while ((search->next != s) && (search->next != NULL)) {      search = search->next;    }    temp = search->next;    search->next = search->next->next;  }  psb *p;   rsb *r;  /* Tear down all reservation states */  send_resv_tear_messages(s, s->rsb_list);  while ((r = temp->rsb_list) != NULL) {    temp->rsb_list = temp->rsb_list->next;    update_traffic_control(temp, r);    clear_rsb(r);    delete r;    num_rsb_--;  }  /* Tear down all path states */  while ((p = temp->psb_list) != NULL) {    send_path_tear_message(s, p);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -