📄 olsr.cc
字号:
msg.msg_seq_num() = msg_seq(); msg.hello().reserved() = 0; msg.hello().htime() = OLSR::seconds_to_emf(hello_ival()); msg.hello().willingness() = willingness(); msg.hello().count = 0; map<u_int8_t, int> linkcodes_count; for (linkset_t::iterator it = linkset().begin(); it != linkset().end(); it++) { OLSR_link_tuple* link_tuple = *it; if (link_tuple->local_iface_addr() == ra_addr() && link_tuple->time() >= now) { u_int8_t link_type, nb_type, link_code; // Establishes link type if (use_mac() && link_tuple->lost_time() >= now) link_type = OLSR_LOST_LINK; else if (link_tuple->sym_time() >= now) link_type = OLSR_SYM_LINK; else if (link_tuple->asym_time() >= now) link_type = OLSR_ASYM_LINK; else link_type = OLSR_LOST_LINK; // Establishes neighbor type. if (state_.find_mpr_addr(get_main_addr(link_tuple->nb_iface_addr()))) nb_type = OLSR_MPR_NEIGH; else { bool ok = false; for (nbset_t::iterator nb_it = nbset().begin(); nb_it != nbset().end(); nb_it++) { OLSR_nb_tuple* nb_tuple = *nb_it; if (nb_tuple->nb_main_addr() == link_tuple->nb_iface_addr()) { if (nb_tuple->status() == OLSR_STATUS_SYM) nb_type = OLSR_SYM_NEIGH; else if (nb_tuple->status() == OLSR_STATUS_NOT_SYM) nb_type = OLSR_NOT_NEIGH; else { fprintf(stderr, "There is a neighbor tuple" " with an unknown status!\n"); exit(1); } ok = true; break; } } if (!ok) { fprintf(stderr, "Link tuple has no corresponding" " Neighbor tuple\n"); exit(1); } } int count = msg.hello().count; link_code = (link_type & 0x03) | ((nb_type << 2) & 0x0f); map<u_int8_t, int>::iterator pos = linkcodes_count.find(link_code); if (pos == linkcodes_count.end()) { linkcodes_count[link_code] = count; assert(count >= 0 && count < OLSR_MAX_HELLOS); msg.hello().hello_msg(count).count = 0; msg.hello().hello_msg(count).link_code() = link_code; msg.hello().hello_msg(count).reserved() = 0; msg.hello().count++; } else count = (*pos).second; int i = msg.hello().hello_msg(count).count; assert(count >= 0 && count < OLSR_MAX_HELLOS); assert(i >= 0 && i < OLSR_MAX_ADDRS); msg.hello().hello_msg(count).nb_iface_addr(i) = link_tuple->nb_iface_addr(); msg.hello().hello_msg(count).count++; msg.hello().hello_msg(count).link_msg_size() = msg.hello().hello_msg(count).size(); } } msg.msg_size() = msg.size(); enque_msg(msg, JITTER);}////// \brief Creates a new %OLSR TC message which is buffered to be sent later on.///voidOLSR::send_tc() { OLSR_msg msg; msg.msg_type() = OLSR_TC_MSG; msg.vtime() = OLSR::seconds_to_emf(OLSR_TOP_HOLD_TIME); msg.orig_addr() = ra_addr(); msg.ttl() = 255; msg.hop_count() = 0; msg.msg_seq_num() = msg_seq(); msg.tc().ansn() = ansn_; msg.tc().reserved() = 0; msg.tc().count = 0; for (mprselset_t::iterator it = mprselset().begin(); it != mprselset().end(); it++) { OLSR_mprsel_tuple* mprsel_tuple = *it; int count = msg.tc().count; assert(count >= 0 && count < OLSR_MAX_ADDRS); msg.tc().nb_main_addr(count) = mprsel_tuple->main_addr(); msg.tc().count++; } msg.msg_size() = msg.size(); enque_msg(msg, JITTER);}////// \brief Creates a new %OLSR MID message which is buffered to be sent later on./// \warning This message is never invoked because there is no support for multiple interfaces.///voidOLSR::send_mid() { OLSR_msg msg; msg.msg_type() = OLSR_MID_MSG; msg.vtime() = OLSR::seconds_to_emf(OLSR_MID_HOLD_TIME); msg.orig_addr() = ra_addr(); msg.ttl() = 255; msg.hop_count() = 0; msg.msg_seq_num() = msg_seq(); msg.mid().count = 0; //foreach iface in this_node do // msg.mid().iface_addr(i) = iface // msg.mid().count++ //done msg.msg_size() = msg.size(); enque_msg(msg, JITTER);}////// \brief Updates Link Set according to a new received HELLO message (following RFC 3626/// specification). Neighbor Set is also updated if needed.////// \param msg the OLSR message which contains the HELLO message./// \param receiver_iface the address of the interface where the message was received from./// \param sender_iface the address of the interface where the message was sent from.///voidOLSR::link_sensing(OLSR_msg& msg, nsaddr_t receiver_iface, nsaddr_t sender_iface) { OLSR_hello& hello = msg.hello(); double now = CURRENT_TIME; bool updated = false; bool created = false; OLSR_link_tuple* link_tuple = state_.find_link_tuple(sender_iface); if (link_tuple == NULL) { // We have to create a new tuple link_tuple = new OLSR_link_tuple; link_tuple->nb_iface_addr() = sender_iface; link_tuple->local_iface_addr() = receiver_iface; link_tuple->sym_time() = now - 1; link_tuple->lost_time() = 0.0; link_tuple->time() = now + OLSR::emf_to_seconds(msg.vtime()); add_link_tuple(link_tuple, hello.willingness()); created = true; } else updated = true; link_tuple->asym_time() = now + OLSR::emf_to_seconds(msg.vtime()); assert(hello.count >= 0 && hello.count <= OLSR_MAX_HELLOS); for (int i = 0; i < hello.count; i++) { OLSR_hello_msg& hello_msg = hello.hello_msg(i); int lt = hello_msg.link_code() & 0x03; int nt = hello_msg.link_code() >> 2; // We must not process invalid advertised links if ((lt == OLSR_SYM_LINK && nt == OLSR_NOT_NEIGH) || (nt != OLSR_SYM_NEIGH && nt != OLSR_MPR_NEIGH && nt != OLSR_NOT_NEIGH)) continue; assert(hello_msg.count >= 0 && hello_msg.count <= OLSR_MAX_ADDRS); for (int j = 0; j < hello_msg.count; j++) { if (hello_msg.nb_iface_addr(j) == receiver_iface) { if (lt == OLSR_LOST_LINK) { link_tuple->sym_time() = now - 1; updated = true; } else if (lt == OLSR_SYM_LINK || lt == OLSR_ASYM_LINK) { link_tuple->sym_time() = now + OLSR::emf_to_seconds(msg.vtime()); link_tuple->time() = link_tuple->sym_time() + OLSR_NEIGHB_HOLD_TIME; link_tuple->lost_time() = 0.0; updated = true; } break; } } } link_tuple->time() = MAX(link_tuple->time(), link_tuple->asym_time()); if (updated) updated_link_tuple(link_tuple); // Schedules link tuple deletion if (created && link_tuple != NULL) { OLSR_LinkTupleTimer* link_timer = new OLSR_LinkTupleTimer(this, link_tuple); link_timer->resched(DELAY(MIN(link_tuple->time(), link_tuple->sym_time()))); }}////// \brief Updates the Neighbor Set according to the information contained in a new received/// HELLO message (following RFC 3626).////// \param msg the %OLSR message which contains the HELLO message.///voidOLSR::populate_nbset(OLSR_msg& msg) { OLSR_hello& hello = msg.hello(); OLSR_nb_tuple* nb_tuple = state_.find_nb_tuple(msg.orig_addr()); if (nb_tuple != NULL) nb_tuple->willingness() = hello.willingness();}////// \brief Updates the 2-hop Neighbor Set according to the information contained in a new/// received HELLO message (following RFC 3626).////// \param msg the %OLSR message which contains the HELLO message.///voidOLSR::populate_nb2hopset(OLSR_msg& msg) { double now = CURRENT_TIME; OLSR_hello& hello = msg.hello(); for (linkset_t::iterator it_lt = linkset().begin(); it_lt != linkset().end(); it_lt++) { OLSR_link_tuple* link_tuple = *it_lt; if (get_main_addr(link_tuple->nb_iface_addr()) == msg.orig_addr()) { if (link_tuple->sym_time() >= now) { assert(hello.count >= 0 && hello.count <= OLSR_MAX_HELLOS); for (int i = 0; i < hello.count; i++) { OLSR_hello_msg& hello_msg = hello.hello_msg(i); int nt = hello_msg.link_code() >> 2; assert(hello_msg.count >= 0 && hello_msg.count <= OLSR_MAX_ADDRS); for (int j = 0; j < hello_msg.count; j++) { nsaddr_t nb2hop_addr = hello_msg.nb_iface_addr(j); if (nt == OLSR_SYM_NEIGH || nt == OLSR_MPR_NEIGH) { // if the main address of the 2-hop // neighbor address = main address of // the receiving node: silently // discard the 2-hop neighbor address if (nb2hop_addr != ra_addr()) { // Otherwise, a 2-hop tuple is created OLSR_nb2hop_tuple* nb2hop_tuple = state_.find_nb2hop_tuple(msg.orig_addr(), nb2hop_addr); if (nb2hop_tuple == NULL) { nb2hop_tuple = new OLSR_nb2hop_tuple; nb2hop_tuple->nb_main_addr() = msg.orig_addr(); nb2hop_tuple->nb2hop_addr() = nb2hop_addr; add_nb2hop_tuple(nb2hop_tuple); nb2hop_tuple->time() = now + OLSR::emf_to_seconds(msg.vtime()); // Schedules nb2hop tuple // deletion OLSR_Nb2hopTupleTimer* nb2hop_timer = new OLSR_Nb2hopTupleTimer(this, nb2hop_tuple); nb2hop_timer->resched(DELAY(nb2hop_tuple->time())); } else { nb2hop_tuple->time() = now + OLSR::emf_to_seconds(msg.vtime()); } } } else if (nt == OLSR_NOT_NEIGH) { // For each 2-hop node listed in the HELLO // message with Neighbor Type equal to // NOT_NEIGH all 2-hop tuples where: // N_neighbor_main_addr == Originator // Address AND N_2hop_addr == main address // of the 2-hop neighbor are deleted. state_.erase_nb2hop_tuples(msg.orig_addr(), nb2hop_addr); } } } } } }}////// \brief Updates the MPR Selector Set according to the information contained in a new/// received HELLO message (following RFC 3626).////// \param msg the %OLSR message which contains the HELLO message.///voidOLSR::populate_mprselset(OLSR_msg& msg) { double now = CURRENT_TIME; OLSR_hello& hello = msg.hello(); assert(hello.count >= 0 && hello.count <= OLSR_MAX_HELLOS); for (int i = 0; i < hello.count; i++) { OLSR_hello_msg& hello_msg = hello.hello_msg(i); int nt = hello_msg.link_code() >> 2; if (nt == OLSR_MPR_NEIGH) { assert(hello_msg.count >= 0 && hello_msg.count <= OLSR_MAX_ADDRS); for (int j = 0; j < hello_msg.count; j++) { if (hello_msg.nb_iface_addr(j) == ra_addr()) { // We must create a new entry into the mpr selector set OLSR_mprsel_tuple* mprsel_tuple = state_.find_mprsel_tuple(msg.orig_addr()); if (mprsel_tuple == NULL) { mprsel_tuple = new OLSR_mprsel_tuple; mprsel_tuple->main_addr() = msg.orig_addr(); mprsel_tuple->time() = now + OLSR::emf_to_seconds(msg.vtime()); add_mprsel_tuple(mprsel_tuple); // Schedules mpr selector tuple deletion OLSR_MprSelTupleTimer* mprsel_timer = new OLSR_MprSelTupleTimer(this, mprsel_tuple); mprsel_timer->resched(DELAY(mprsel_tuple->time())); } else mprsel_tuple->time() = now + OLSR::emf_to_seconds(msg.vtime()); } } } }}////// \brief Drops a given packet because it couldn't be delivered to the corresponding/// destination by the MAC layer. This may cause a neighbor loss, and appropiate/// actions are then taken.////// \param p the packet which couldn't be delivered by the MAC layer.///voidOLSR::mac_failed(Packet* p) { double now = CURRENT_TIME; struct hdr_ip* ih = HDR_IP(p); struct hdr_cmn* ch = HDR_CMN(p); debug("%f: Node %d MAC Layer detects a breakage on link to %d\n", now, OLSR::node_id(ra_addr()), OLSR::node_id(ch->next_hop())); if ((u_int32_t)ih->daddr() == IP_BROADCAST) { drop(p, DROP_RTR_MAC_CALLBACK); return; } OLSR_link_tuple* link_tuple = state_.find_link_tuple(ch->next_hop()); if (link_tuple != NULL) { link_tuple->lost_time() = now + OLSR_NEIGHB_HOLD_TIME; link_tuple->time() = now + OLSR_NEIGHB_HOLD_TIME; nb_loss(link_tuple); } drop(p, DROP_RTR_MAC_CALLBACK);}////// \brief Schedule the timer used for sending HELLO messages.///voidOLSR::set_hello_timer() { hello_timer_.resched((double)(hello_ival() - JITTER));}////// \brief Schedule the timer used for sending TC messages.///voidOLSR::set_tc_timer() { tc_timer_.resched((double)(tc_ival() - JITTER));}////// \brief Schedule the timer used for sending MID messages.///voidOLSR::set_mid_timer() { mid_timer_.resched((double)(mid_ival() - JITTER));}////// \brief Performs all actions needed when a neighbor loss occurs.////// Neighbor Set, 2-hop Neighbor Set, MPR Set and MPR Selector Set are updated.////// \param tuple link tuple with the information of the link to the neighbor which has been lost.///voidOLSR::nb_loss(OLSR_link_tuple* tuple) { debug("%f: Node %d detects neighbor %d loss\n", CURRENT_TIME,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -