else if(ctrl_hdr->_type == MAB_CTRL_END) { // TODO: works bad if END is lost, or if explore traffic is received after
if(_debug_explore)
_verb_debug=false;
DEBUG_CHATTER("[Order %s] MAB control END message %d, id %d, remove routes from source %s, has received %d packets, sent %d (%d timeout, %d error)...",
createPacketTimer(src,packet_seq,_saved_packets*_diff_route_delays[src]); // packet expire after difference between routes; TODO: check expiration time
createPacketTimer(src,packet_seq,Timestamp(0,_packet_lifetime_ms*Timestamp::subsec_per_msec)); // packet expire after _packet_lifetime_ms
}
// instead of having timeouts for out-of-order packets we run the following procedure
bool should_forward = true;
if (_newsrcTable.get(src))
should_forward = false;
// check if some packets should be forwarded, by observing the last sequence seen "last_seq" from all routes.
// if last_seq > cur_seq +1 for all routes, it means we have lost all the packets with sequence from cur_seq +1 up to the minimum of "last_seq" from all routes.
for(HashTable<uint16_t, Packet*>::iterator it = _ptable->begin();it.live();it++)
it.value()->kill();
}
_pktTables.clear();
_SeqFormRouteTables.clear();
_SeqFormRouteTablesTemp.clear();
_timersTable.clear();
_newsrcTable.clear();
_froute2ts.clear();
// for (HashTable<IPAddress, HashTable<FormatedRoute, Timestamp> >::iterator iter = _froute2delta.begin(); iter.live(); iter++) {
// iter.value().clear();
// }
// _froute2delta.clear();
// for (HashTable<IPAddress, HashTable<FormatedRoute, uint32_t> >::iterator iter = _froute2rate.begin(); iter.live(); iter++) {
// iter.value().clear();
// }
// _froute2rate.clear();
// _waiting_time.clear();
// _expiration_time.clear();
_src2ts.clear();
_packet_1period_ago.clear();
_packet_2period_ago.clear();
_nack_timer.unschedule();
_missed_packets.clear();
_missed_packets_int=0;
}
void Order::run_timer(Timer *t) {
VERB_DEBUG_CHATTER("[Order %s] Run timer %p", Timestamp::now().unparse().c_str(), t);
if(t == &_active_timer) {
reset();
}
if(t == &_expire_timer_s) {
if(_active && _seqTable.size() > 0) {
if(_dropped > 0) {
DEBUG_CHATTER("[Order %s] Has dropped %d packets during the last %d ms", Timestamp::now().unparse().c_str(), _dropped, mymin(_print_stats_freq,1000*_source_lifetime_s));
_dropped = 0;
}
else
VERB_DEBUG_CHATTER("[Order %s] No dropped packet during the last %d ms", Timestamp::now().unparse().c_str(), mymin(_print_stats_freq,1000*_source_lifetime_s));
// this timer is used to remove sources that are inactive more than 5 seconds
VERB_DEBUG_CHATTER("[Order] timer expired");
for (HashTable<IPAddress, uint16_t>::iterator iter = _seqTableTimer.begin(); iter.live(); iter++) {
click_chatter("[Order %s] Removing src %s, since it is inactive for %u sec", Timestamp::now().unparse().c_str(), iter.key().unparse().c_str(), _source_lifetime_s);
for(HashTable<uint16_t, Packet*>::iterator it = _ptable->begin();it.live();it++)
DEBUG_CHATTER("[Order %s] Adding new src %s, route %s with packet of type %d, id %d (seq %u)", Timestamp::now().unparse().c_str(), src.unparse().c_str(),
DEBUG_CHATTER("[Order %s] New route %s, source %s with packet of type %d, id %d (seq %u)", Timestamp::now().unparse().c_str(), froute.unparse().c_str(), src.unparse().c_str(),
hdr->_type, hdr->_id_rate_mab, seq);
}
}
// remove old routes if they exceed the number of max. routes
if (_seqformroutetable->size() > _max_num_routes) {
uint16_t cur_seq = getCurrentSeqNum(src, seq);
uint16_t minimum = MAX_SEQ;
uint16_t min_distance = MAX_SEQ;
uint16_t distance;
FormatedRoute toremove;
DEBUG_CHATTER("[Order] Source %s has %u routes, should remove 1 route (current seq %u)...", src.unparse().c_str(), _seqformroutetable->size(), cur_seq);
for (HashTable<FormatedRoute, uint16_t>::iterator iter = _seqformroutetable->begin(); iter.live(); iter++) {
// Christina: the following should work, unless we miss more than MAX_SEQ/2 packets, noticed it can happen if we use infinite source (acne-offline script) with non-blocking queues
DEBUG_CHATTER("[Order %s] Removing formatted route %s, since it is inactive for %d msec", now.unparse().c_str(), iter.key().unparse().c_str(), _route_lifetime_ms);