📄 diff_rate.cc
字号:
/****************************************************************//* diff_rate.cc : Chalermek Intanagonwiwat (USC/ISI) 05/18/99 *//****************************************************************/// Important Note: Work still in progress !extern "C" {#include <assert.h>#include <math.h>#include <stdio.h>#include <signal.h>#include <float.h>}#include <tcl.h>#include <stdlib.h>#include "diff_header.h"#include "agent.h"#include "tclcl.h"#include "ip.h"#include "config.h"#include "packet.h"#include "trace.h"#include "random.h"#include "classifier.h"#include "node.h"#include "diffusion.h"#include "iflist.h"#include "hash_table.h"#include "arp.h"#include "mac.h"#include "ll.h"#include "dsr/path.h"#include "god.h"#include "routing_table.h"#include "diff_rate.h"extern char *MsgStr[];static class DiffusionRateClass : public TclClass {public: DiffusionRateClass() : TclClass("Agent/Diffusion/RateGradient") {} TclObject* create(int argc, const char*const* argv) { return(new DiffusionRate()); }} class_diffusion_rate;void GradientTimer::expire(Event *e){ a_->GradientTimeOut();}void NegativeReinforceTimer::expire(Event *e){ a_->NegReinfTimeOut();}DiffusionRate::DiffusionRate() : DiffusionAgent(){ DUP_SUP_ = true; sub_type_ = BCAST_SUB; org_type_ = UNICAST_ORG; pos_type_ = POS_ALL; pos_node_type_ = INTM_POS; neg_win_type_ = NEG_TIMER; neg_thr_type_ = NEG_ABSOLUTE; neg_max_type_ = NEG_FIXED_MAX; num_not_send_bcast_data = 0; num_data_bcast_send = 0; num_data_bcast_rcv = 0; num_neg_bcast_send = 0; num_neg_bcast_rcv = 0;}void DiffusionRate::recv(Packet* packet, Handler*){ hdr_diff* dfh = HDR_DIFF(packet); // Packet Hash Table is used to keep info about experienced pkts. Pkt_Hash_Entry *hashPtr= PktTable.GetHash(dfh->sender_id, dfh->pk_num);#ifdef DEBUG_RATE printf("DF node %x recv %s (%x, %x, %d)\n", THIS_NODE, MsgStr[dfh->mess_type], (dfh->sender_id).addr_, (dfh->sender_id).port_, dfh->pk_num);#endif // Received this packet before ? if (hashPtr != NULL) { consider_old(packet); return; } // Never receive it before ? Put in hash table. PktTable.put_in_hash(dfh); // Take action for a new pkt. // Check for dupplicate data at application if (DUP_SUP_ == true) { if (dfh->mess_type == DATA) { if (DataTable.GetHash(dfh->attr) != NULL) { consider_old(packet); return; } else { DataTable.PutInHash(dfh->attr); } } } consider_new(packet); }void DiffusionRate::consider_old(Packet *pkt){ hdr_diff* dfh = HDR_DIFF(pkt); hdr_cmn* cmh = HDR_CMN(pkt); unsigned char msg_type = dfh->mess_type; unsigned int dtype = dfh->data_type; switch (msg_type) { case INTEREST : InterestHandle(pkt); return; case DATA: if (cmh->next_hop_ == (nsaddr_t)MAC_BROADCAST) { num_data_bcast_rcv++; } if (dfh->report_rate == ORIGINAL) { routing_table[dtype].CntOldOrg(dfh->forward_agent_id); } Packet::free(pkt); return; case NEG_REINFORCE: if (cmh->next_hop_ == (nsaddr_t)MAC_BROADCAST) { num_neg_bcast_rcv++; } break; default : Packet::free(pkt); break; }}void DiffusionRate::consider_new(Packet *pkt){ hdr_diff* dfh = HDR_DIFF(pkt); hdr_cmn * cmh = HDR_CMN(pkt); unsigned char msg_type = dfh->mess_type; unsigned int dtype = dfh->data_type; Agent_List *agentPtr; Packet *gen_pkt; hdr_diff *gen_dfh; switch (msg_type) { case INTEREST : InterestHandle(pkt); return; case POS_REINFORCE : if ( POS_REINF_ == false ) { printf("Hey, we are not in pos_reinf mode.\n"); Packet::free(pkt); exit(-1); } ProcessPosReinf(pkt); return; case NEG_REINFORCE : if (cmh->next_hop_ == (nsaddr_t)MAC_BROADCAST) { num_neg_bcast_rcv++; } else { routing_table[dtype].CntNeg(dfh->forward_agent_id); } if (NEG_REINF_ == false) { printf("Hey, we are not in neg_reinf mode.\n"); Packet::free(pkt); exit(-1); } ProcessNegReinf(pkt); return; case DATA_READY : // put source_agent in source list of routing table agentPtr = new Agent_List; AGT_ADDR(agentPtr) = dfh->sender_id; agentPtr->next = routing_table[dtype].source; routing_table[dtype].source = agentPtr; God::instance()->AddSource(dtype, (dfh->sender_id).addr_); /* printf("DF %d received DATA_READY (%d, %d, %d) at time %lf\n", THIS_NODE, dfh->sender_id.addr_, dfh->sender_id.port_, dfh->pk_num, NOW); */ if (routing_table[dtype].active != NULL || routing_table[dtype].sink != NULL) { gen_pkt = prepare_message(dtype, dfh->sender_id, DATA_REQUEST); gen_dfh = HDR_DIFF(gen_pkt); gen_dfh->report_rate = SUB_SAMPLED; send_to_dmux(gen_pkt, 0); /* printf("DF %d sent DATA_REQUEST (%d, %d, %d) at time %lf\n", THIS_NODE, gen_dfh->sender_id.addr_, gen_dfh->sender_id.port_, gen_dfh->pk_num, NOW); */ } Packet::free(pkt); return; case DATA : if (cmh->next_hop_ == (nsaddr_t)MAC_BROADCAST) { num_data_bcast_rcv++; } DataForSink(pkt); if (dfh->report_rate == SUB_SAMPLED) { routing_table[dtype].CntNewSub(dfh->forward_agent_id); FwdData(pkt); return; } if (dfh->report_rate == ORIGINAL) { routing_table[dtype].new_org_counter++; routing_table[dtype].CntNewOrg(dfh->forward_agent_id); FwdData(pkt); if (neg_win_type_ == NEG_COUNTER) { CheckNegCounter(dtype); return; } } return; default : Packet::free(pkt); break; }}void DiffusionRate::CheckNegCounter(int dtype){ if (neg_max_type_ == NEG_FIXED_MAX) { if (routing_table[dtype].new_org_counter >= MAX_NEG_COUNTER && NEG_REINF_ == true) { GenNeg(dtype); routing_table[dtype].new_org_counter = 0; routing_table[dtype].ClrAllNewOrg(); routing_table[dtype].ClrAllOldOrg(); } return; } if (neg_max_type_ == NEG_SCALE_MAX) { if (routing_table[dtype].new_org_counter >= PER_IIF * routing_table[dtype].num_iif && NEG_REINF_ == true) { GenNeg(dtype); routing_table[dtype].new_org_counter = 0; routing_table[dtype].ClrAllNewOrg(); routing_table[dtype].ClrAllOldOrg(); } return; }}void DiffusionRate::InterestHandle(Packet *pkt){ hdr_diff *dfh = HDR_DIFF(pkt); unsigned int dtype = dfh->data_type; Agent_List *agentPtr; nsaddr_t from_nodeID; PrvCurPtr RetVal; Out_List *OutPtr; if (dfh->ts_ + INTEREST_TIMEOUT < NOW) { Packet::free(pkt); return; } // Check if it comes from sink agent of this node // If so we have to keep it in sink list from_nodeID = (dfh->sender_id).addr_; if (THIS_NODE == from_nodeID) { // From sink agent on the same node. // It's from a sink on this node. // Is it already in list ? RetVal = INTF_FIND(routing_table[dtype].sink, dfh->sender_id); if (RetVal.cur == NULL) { // No, it's not. agentPtr = new Agent_List; AGT_ADDR(agentPtr) = dfh->sender_id; INTF_INSERT(routing_table[dtype].sink, agentPtr); God::instance()->AddSink(dtype, THIS_NODE); } } else { // From different node. // If we have gradient for the forwarder. RetVal = INTF_FIND(routing_table[dtype].active, dfh->forward_agent_id); if (RetVal.cur == NULL) { OutPtr = new Out_List; AGT_ADDR(OutPtr) = dfh->forward_agent_id; GRADIENT(OutPtr) = dfh->report_rate; GRAD_TMOUT(OutPtr) = dfh->ts_ + INTEREST_TIMEOUT; INTF_INSERT(routing_table[dtype].active, OutPtr); routing_table[dtype].num_active ++; } else { GRAD_TMOUT(RetVal.cur) = max(GRAD_TMOUT(RetVal.cur), dfh->ts_ + INTEREST_TIMEOUT); } } if (NOW > routing_table[dtype].last_fwd_time + INTEREST_PERIODIC) { if (routing_table[dtype].ExistOriginalGradient() == true) { DataReqAll(dtype, ORIGINAL); } else { DataReqAll(dtype, SUB_SAMPLED); } routing_table[dtype].last_fwd_time = NOW; MACprepare(pkt, MAC_BROADCAST, NS_AF_ILINK, 0); MACsend(pkt, JITTER*Random::uniform(1.0)); overhead++;#ifdef DEBUG_RATE hdr_cmn *cmh = HDR_CMN(pkt); printf("DF node %x will send %s (%x, %x, %d) to %x\n", THIS_NODE, MsgStr[dfh->mess_type], (dfh->sender_id).addr_, (dfh->sender_id).port_, dfh->pk_num, cmh->next_hop());#endif return; } Packet::free(pkt); return;}void DiffusionRate::NegReinfTimeOut(){ for (int i=0; i<MAX_DATA_TYPE; i++) { GenNeg(i); routing_table[i].new_org_counter = 0; routing_table[i].ClrAllNewOrg(); routing_table[i].ClrAllOldOrg(); } neg_reinf_timer->resched(NEG_CHECK);}void DiffusionRate::GradientTimeOut(){ int i; Agent_List *cur_out, **prv_out; for (i=0; i<MAX_DATA_TYPE; i++) { for (cur_out = routing_table[i].active, prv_out = (Agent_List **)&routing_table[i].active; cur_out != NULL; ) { if (NOW > GRAD_TMOUT(cur_out)) { INTF_REMOVE(prv_out, cur_out); routing_table[i].num_active -- ; cur_out = *prv_out; } else { prv_out = &(cur_out->next); cur_out = cur_out->next; } } } gradient_timer->resched(INTEREST_TIMEOUT);}bool DiffusionRate::FwdSubsample(Packet *pkt){ hdr_diff *dfh = HDR_DIFF(pkt); Out_List *cur_out; Packet *cur_pkt; hdr_diff *cur_dfh; hdr_ip *cur_iph; unsigned int dtype = dfh->data_type; if (routing_table[dtype].num_active <= 0) { // Won't forward num_not_send_bcast_data++; return false; } // Will forward num_data_bcast_send++; if (sub_type_ == BCAST_SUB) { MACprepare(pkt, MAC_BROADCAST, NS_AF_ILINK, 0); MACsend(pkt, JITTER*Random::uniform(1.0));#ifdef DEBUG_RATE hdr_cmn *cmh = HDR_CMN(pkt); printf("DF node %x will send %s (%x, %x, %d) to %x\n", THIS_NODE, MsgStr[dfh->mess_type], (dfh->sender_id).addr_, (dfh->sender_id).port_, dfh->pk_num, cmh->next_hop());#endif // DEBUG_RATE return true; } if (sub_type_ == UNICAST_SUB) { for (cur_out = routing_table[dtype].active; cur_out!= NULL; cur_out = OUT_NEXT(cur_out)) { cur_pkt = pkt->copy(); cur_iph = HDR_IP(cur_pkt); cur_iph->dst_ = AGT_ADDR(cur_out); cur_dfh = HDR_DIFF(cur_pkt); cur_dfh->forward_agent_id = here_; cur_dfh->num_next = 1; cur_dfh->next_nodes[0] = NODE_ADDR(cur_out); MACprepare(cur_pkt, NODE_ADDR(cur_out), NS_AF_INET, MAC_RETRY_); MACsend(cur_pkt, 0); #ifdef DEBUG_RATE cur_cmh = HDR_CMN(cur_pkt); printf("DF node %x will send %s (%x, %x, %d) to %x\n", THIS_NODE, MsgStr[cur_dfh->mess_type], (cur_dfh->sender_id).addr_, (cur_dfh->sender_id).port_, cur_dfh->pk_num, cur_cmh->next_hop());#endif // DEBUG_RATE } // endfor return true; } // endif unicast sub return false;}void DiffusionRate::TriggerPosReinf(Packet *pkt, ns_addr_t forward_agent){ hdr_diff *dfh = HDR_DIFF(pkt); unsigned int dtype = dfh->data_type; nsaddr_t forwarder_node = forward_agent.addr_; if (pos_node_type_ == INTM_POS) { if (routing_table[dtype].sink != NULL || routing_table[dtype].ExistOriginalGradient() == true) { DataReqAll(dtype, ORIGINAL); if (THIS_NODE != forwarder_node) { PosReinf(dtype, forwarder_node, dfh->sender_id, dfh->pk_num); routing_table[dtype].CntPosSend(forward_agent); routing_table[dtype].ClrNewSub(forward_agent); } } return; } if (pos_node_type_ == END_POS) { if (routing_table[dtype].sink != NULL) { DataReqAll(dtype, ORIGINAL); if (THIS_NODE != forwarder_node) { PosReinf(dtype, forwarder_node, dfh->sender_id, dfh->pk_num); routing_table[dtype].CntPosSend(forward_agent); routing_table[dtype].ClrNewSub(forward_agent); } } return; }}void DiffusionRate::FwdOriginal(Packet *pkt){ hdr_diff *dfh = HDR_DIFF(pkt); unsigned int dtype = dfh->data_type; Out_List *cur_out; Packet *cur_pkt; hdr_diff *cur_dfh; hdr_ip *cur_iph; if (org_type_ == BCAST_ORG) { MACprepare(pkt, MAC_BROADCAST, NS_AF_ILINK, 0); MACsend(pkt, JITTER*Random::uniform(1.0));#ifdef DEBUG_RATE hdr_cmn *cmh = HDR_CMN(pkt); printf("DF node %x will send %s (%x, %x, %d) to %x\n", THIS_NODE, MsgStr[dfh->mess_type], (dfh->sender_id).addr_, (dfh->sender_id).port_, dfh->pk_num, cmh->next_hop());#endif // DEBUG_RATE return; } if (org_type_ == UNICAST_ORG) { for (cur_out = routing_table[dtype].active; cur_out!= NULL; cur_out = OUT_NEXT(cur_out)) { if (GRADIENT(cur_out) == ORIGINAL) { cur_pkt = pkt->copy(); cur_iph = HDR_IP(cur_pkt); cur_iph->dst_ = AGT_ADDR(cur_out); cur_dfh = HDR_DIFF(cur_pkt); cur_dfh->forward_agent_id = here_; cur_dfh->num_next = 1; cur_dfh->next_nodes[0] = NODE_ADDR(cur_out); cur_out->num_data_send++; MACprepare(cur_pkt, NODE_ADDR(cur_out), NS_AF_INET, MAC_RETRY_); MACsend(cur_pkt, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -