bool igmp_sender::create_mc_query(msg_type type, unsigned char* buf,const addr_storage* g_addr){ HC_LOG_TRACE(""); if(m_version == 2){ struct igmp* igmp_Hdr = (struct igmp*)(buf); igmp_Hdr->igmp_type = IGMP_MEMBERSHIP_QUERY; igmp_Hdr->igmp_cksum = 0; if(type==GENERAL_QUERY){ igmp_Hdr->igmp_code = MC_TV_QUERY_RESPONSE_INTERVAL*MC_TV_MAX_RESPONSE_TIME_UNIT; igmp_Hdr->igmp_group = addr_storage(m_addr_family).get_in_addr(); //0.0.0.0 }else if(type== GROUP_SPECIFIC_QUERY){ if(!g_addr){ HC_LOG_ERROR("g_addr is NULL"); return false; } igmp_Hdr->igmp_code = MC_TV_LAST_MEMBER_QUERY_INTEVAL*MC_TV_MAX_RESPONSE_TIME_UNIT; igmp_Hdr->igmp_group = g_addr->get_in_addr(); }else{ HC_LOG_ERROR("wrong type: " << type); return false; } igmp_Hdr->igmp_cksum = m_sock.calc_checksum((unsigned char*)igmp_Hdr,sizeof(struct igmp)); return true; }else{ HC_LOG_ERROR("wrong verson: "<< m_version); return false; } }
addr_storage parser::get_addr(group_mem_protocol gmp) { HC_LOG_TRACE(""); std::ostringstream s; while (true) { if (m_current_token.get_type() == TT_STRING) { s << m_current_token.get_string(); } else if (m_current_token.get_type() == TT_DOT) { s << "."; } else if (m_current_token.get_type() == TT_DOUBLE_DOT) { s << ":"; } else { break; } get_next_token(); } addr_storage result(s.str()); if (result.is_valid()) { if (result.get_addr_family() == get_addr_family(gmp)) { return result; } else { HC_LOG_ERROR("failed to parse line " << m_current_line << " ip address: " << s.str() << " has a wrong IP version"); throw "failed to parse config file"; } } else { HC_LOG_ERROR("failed to parse line " << m_current_line << " ip address: " << s.str() << " is invalid"); throw "failed to parse config file"; } }
bool mld_sender::create_mc_query(msg_type type, unsigned char* buf, const addr_storage* g_addr){ HC_LOG_TRACE(""); if(m_version == 1){ struct mld_hdr* mld_Hdr = (struct mld_hdr*)buf; mld_Hdr->mld_type = MLD_LISTENER_QUERY; mld_Hdr->mld_code = 0; mld_Hdr->mld_cksum = MC_MASSAGES_AUTO_FILL; mld_Hdr->mld_reserved = 0; if(type==GENERAL_QUERY){ mld_Hdr->mld_maxdelay = htons(MC_TV_QUERY_RESPONSE_INTERVAL * MC_TV_MAX_RESPONSE_DELAY_UNIT); mld_Hdr->mld_addr = addr_storage(m_addr_family).get_in6_addr(); //0.0.0.0 }else if(type== MC_ADDR_SPECIFIC_QUERY){ if(!g_addr){ HC_LOG_ERROR("g_addr is NULL"); return false; } mld_Hdr->mld_maxdelay = htons(MC_TV_LAST_LISTENER_QUERY_INTERVAL * MC_TV_MAX_RESPONSE_DELAY_UNIT); mld_Hdr->mld_addr = g_addr->get_in6_addr(); }else{ HC_LOG_ERROR("wrong type: " << type); return false; } return true; }else{ HC_LOG_ERROR("wrong verson: "<< m_version); return false; } }
void querier::timer_triggerd(const std::shared_ptr<proxy_msg>& msg) { HC_LOG_TRACE(""); gaddr_map::iterator db_info_it; std::shared_ptr<timer_msg> tm; if (!msg.unique()) { switch (msg->get_type()) { case proxy_msg::FILTER_TIMER_MSG: case proxy_msg::SOURCE_TIMER_MSG: case proxy_msg::RET_GROUP_TIMER_MSG: case proxy_msg::RET_SOURCE_TIMER_MSG: case proxy_msg::OLDER_HOST_PRESENT_TIMER_MSG: { tm = std::static_pointer_cast<timer_msg>(msg); db_info_it = m_db.group_info.find(tm->get_gaddr()); if (db_info_it == end(m_db.group_info)) { HC_LOG_ERROR("filter_timer message is still in use but cannot found"); return; } } break; case proxy_msg::GENERAL_QUERY_TIMER_MSG: tm = std::static_pointer_cast<timer_msg>(msg); break; default: HC_LOG_ERROR("unknown timer message format"); return; } } else { HC_LOG_DEBUG("filter_timer is outdate"); return; } switch (msg->get_type()) { case proxy_msg::FILTER_TIMER_MSG: timer_triggerd_filter_timer(db_info_it, tm); break; case proxy_msg::SOURCE_TIMER_MSG: timer_triggerd_source_timer(db_info_it, tm); break; case proxy_msg::RET_GROUP_TIMER_MSG: timer_triggerd_ret_group_timer(db_info_it, tm); break; case proxy_msg::RET_SOURCE_TIMER_MSG: timer_triggerd_ret_source_timer(db_info_it, tm); break; case proxy_msg::GENERAL_QUERY_TIMER_MSG: timer_triggerd_general_query_timer(tm); break; case proxy_msg::OLDER_HOST_PRESENT_TIMER_MSG: timer_triggerd_older_host_present_timer(db_info_it, tm); break; default: HC_LOG_ERROR("unknown timer message format"); return; } }
void querier::receive_record(const std::shared_ptr<proxy_msg>& msg) { HC_LOG_TRACE(""); if (msg->get_type() != proxy_msg::GROUP_RECORD_MSG) { HC_LOG_ERROR("wrong proxy message, it musst be be a GROUP_RECORD_MS"); return; } auto gr = std::static_pointer_cast<group_record_msg>(msg); auto db_info_it = m_db.group_info.find(gr->get_gaddr()); if (db_info_it == end(m_db.group_info)) { //add an empty neutral record to membership database HC_LOG_DEBUG("gaddr not found"); db_info_it = m_db.group_info.insert(gaddr_pair(gr->get_gaddr(), gaddr_info(m_db.querier_version_mode))).first; } //backwards compatibility coordination if (!is_newest_version(gr->get_grp_mem_proto()) && is_older_or_equal_version(gr->get_grp_mem_proto(), m_db.querier_version_mode) ) { db_info_it->second.compatibility_mode_variable = gr->get_grp_mem_proto(); auto ohpt = std::make_shared<older_host_present_timer_msg>(m_if_index, db_info_it->first, m_timers_values.get_older_host_present_interval()); db_info_it->second.older_host_present_timer = ohpt; m_timing->add_time(m_timers_values.get_older_host_present_interval(), m_msg_worker, ohpt); } //section 8.3.2. In the Presence of MLDv1 Multicast Address Listeners //MLDv2 BLOCK messages are ignored, as are source-lists in TO_EX() //messages (i.e., any TO_EX() message is treated as TO_EX( {} )). if (db_info_it->second.is_in_backward_compatibility_mode()) { if (gr->get_record_type() == CHANGE_TO_EXCLUDE_MODE) { gr->get_slist() = {}; } else if (gr->get_record_type() == BLOCK_OLD_SOURCES){ return; } } switch (db_info_it->second.filter_mode) { case INCLUDE_MODE: receive_record_in_include_mode(gr->get_record_type(), gr->get_gaddr(), gr->get_slist(), db_info_it->second); //if the new created group is not used delete it if (db_info_it->second.filter_mode == INCLUDE_MODE && db_info_it->second.include_requested_list.empty()) { m_db.group_info.erase(db_info_it); } break; case EXCLUDE_MODE: receive_record_in_exclude_mode(gr->get_record_type(), gr->get_gaddr(), gr->get_slist(), db_info_it->second); break; default : HC_LOG_ERROR("wrong filter mode: " << db_info_it->second.filter_mode); break; } }
std::unique_ptr<table> parser::parse_table(const std::shared_ptr<const global_table_set>& gts, group_mem_protocol gmp, bool inside_rule_box) { HC_LOG_TRACE(""); std::string table_name; std::list<std::unique_ptr<rule_box>> rule_box_list; if (get_parser_type() == PT_TABLE) { get_next_token(); if ((!inside_rule_box && m_scanner.get_next_token(true, 0).get_type() == TT_NIL) || (inside_rule_box && m_scanner.get_next_token(true, 0).get_type() == TT_RIGHT_BRACKET )) { //table reference if (m_current_token.get_type() == TT_STRING) { table_name = m_current_token.get_string(); if (gts->get_table(table_name) != nullptr) { get_next_token(); auto rb = std::unique_ptr<rule_box>(new rule_table_ref(table_name, gts)); rule_box_list.push_back(std::move(rb)); return std::unique_ptr<table>(new table(std::string(), std::move(rule_box_list))); } else { HC_LOG_ERROR("failed to parse line " << m_current_line << " table " << table_name << " not found"); throw "failed to parse config file"; } } } else if (m_current_token.get_type() == TT_STRING || m_current_token.get_type() == TT_LEFT_BRACE) { if (m_current_token.get_type() == TT_STRING) { table_name = m_current_token.get_string(); get_next_token(); if (m_current_token.get_type() != TT_LEFT_BRACE) { HC_LOG_ERROR("failed to parse line " << m_current_line << " unknown token " << get_token_type_name(m_current_token.get_type()) << " with value " << m_current_token.get_string() << " in this context"); throw "failed to parse config file"; } } get_next_token(); auto tmp_rule = parse_rule(gts, gmp); while (tmp_rule != nullptr) { rule_box_list.push_back(std::move(tmp_rule)); get_next_token(); tmp_rule = parse_rule(gts, gmp); } if (m_current_token.get_type() == TT_RIGHT_BRACE) { get_next_token(); if ((!inside_rule_box && m_current_token.get_type() == TT_NIL) || (inside_rule_box && m_current_token.get_type() == TT_RIGHT_BRACKET)) { return std::unique_ptr<table>(new table(table_name, std::move(rule_box_list))); } } } } HC_LOG_ERROR("failed to parse line " << m_current_line << " unknown token " << get_token_type_name(m_current_token.get_type()) << " with value " << m_current_token.get_string() << " in this context"); throw "failed to parse config file"; }
bool proxy_instance::split_traffic(int if_index, const addr_storage& g_addr, const addr_storage& src_addr){ HC_LOG_TRACE(""); proxy_msg msg; std::list<int> vif_list; vif_map::iterator it_vif_map = m_vif_map.find(if_index); if(it_vif_map == m_vif_map.end()){ HC_LOG_ERROR("cant find vif to if_index:" << if_index); return false; } int vif = it_vif_map->second; //cout << "vif vom source interface: " << vif << endl; //find all downstream interaces who join this group and if if_index is not a upstream add upstream vif add_all_group_vifs_to_list(&vif_list, if_index, g_addr); //cout << "split_traffic: haben wieviele vifs gefunden: " << vif_list.size() << endl; if(vif_list.size() == 0) return false; //if nobody join this group ignore m_routing.add_route(vif, g_addr, src_addr, vif_list); //set source to flag CACHED_SRC if(if_index == m_upstream){ //upstream source upstream_src_state_map::iterator it_gss = m_upstream_state.find(g_addr); if(it_gss == m_upstream_state.end()){ HC_LOG_ERROR("CACHE_MISS refresh routing: failed to find upstream g_addr:" << g_addr); return false; } src_state_map::iterator iter_src = it_gss->second.find(src_addr); if(iter_src == it_gss->second.end()){ HC_LOG_ERROR("CACHE_MISS refresh routing: failed to find to g_addr:" << g_addr << " the source:" << src_addr); return false; } iter_src->second.flag = src_state::CACHED_SRC; }else{ //downstream source state_table_map::iterator iter_table =m_state_table.find(if_index); if(iter_table == m_state_table.end()) return false; g_state_map::iterator iter_state = iter_table->second.find(g_addr); if(iter_state == iter_table->second.end()) { HC_LOG_ERROR("CACHE_MISS refresh routing: failed to find downstream g_addr:" << g_addr); return false; } src_group_state_pair* sgs_pair = &iter_state->second; src_state_map::iterator iter_src = sgs_pair->first.find(src_addr); if(iter_state == iter_table->second.end()) { HC_LOG_ERROR("CACHE_MISS refresh routing: failed to find to g_addr:" << g_addr << " the source:" << src_addr); return false; } iter_src->second.flag = src_state::CACHED_SRC; } return true; }
void proxy_instance::unregistrate_if(int if_index){ HC_LOG_TRACE(""); vif_map::iterator it_vif_map; if((it_vif_map = m_vif_map.find(if_index))== m_vif_map.end()){ HC_LOG_ERROR("failed to find vif from if_index:" << if_index); return; } int vif = it_vif_map->second; //##-- routing --## m_routing.del_vif(if_index, vif); //##-- receiver --## m_receiver->del_interface(if_index, vif); //##-- timing --## //remove all running times //m_timing->stop_all_time(this); if(if_index != m_upstream){ //##-- sender --## //leave all router addr at all downstreams if(m_addr_family == AF_INET){ addr_storage mc_router_addr(IPV4_ALL_IGMP_ROUTERS_ADDR); if(!m_sender->send_leave(if_index, mc_router_addr )){ HC_LOG_ERROR("failed to leave: ==> " << mc_router_addr); } }else if(m_addr_family == AF_INET6){ addr_storage mc_router_addr(IPV6_ALL_LINK_LOCAL_ROUTER); if(!m_sender->send_leave(if_index, mc_router_addr )){ HC_LOG_ERROR("failed to leave: ==> " << mc_router_addr); } mc_router_addr=IPV6_ALL_SITE_LOCAL_ROUTER; if(!m_sender->send_leave(if_index, mc_router_addr )){ HC_LOG_ERROR("failed to leave: ==> " << mc_router_addr); } }else{ HC_LOG_ERROR("wrong addr_family: " << m_addr_family); return; } } }
bool querier::router_groups_function(bool subscribe) const { HC_LOG_TRACE(""); //MLDv1 RFC 2710: Section 8. link-scope all-routers (FF02::2), link-scope all-routers (FF05::2)| IANA: site local scope all-routers //MLDv2 RFC 3810: Section 7. all MLDv2-capable routers (FF02::16) //IGMPv1 //IGMPv2 RFC 2236: Section 9. ALL-ROUTERS (224.0.0.2) //IGMPv3 IANA: IGMP (224.0.0.22) mc_filter mf; if (subscribe) { mf = EXCLUDE_MODE; } else { mf = INCLUDE_MODE; } bool rc = true; if (is_IPv4(m_db.querier_version_mode)) { rc = rc && m_sender->send_record(m_if_index, mf, addr_storage(IPV4_ALL_IGMP_ROUTERS_ADDR), source_list<source>()); rc = rc && m_sender->send_record(m_if_index, mf, addr_storage(IPV4_IGMPV3_ADDR), source_list<source>()); } else if (is_IPv6(m_db.querier_version_mode)) { rc = rc && m_sender->send_record(m_if_index, mf, addr_storage(IPV6_ALL_NODE_LOCAL_ROUTER), source_list<source>()); rc = rc && m_sender->send_record(m_if_index, mf, addr_storage(IPV6_ALL_SITE_LOCAL_ROUTER), source_list<source>()); rc = rc && m_sender->send_record(m_if_index, mf, addr_storage(IPV6_ALL_MLDv2_CAPABLE_ROUTERS), source_list<source>()); } else { HC_LOG_ERROR("unknown ip version"); return false; } return rc; }
void querier::timer_triggerd_source_timer(gaddr_map::iterator db_info_it, const std::shared_ptr<timer_msg>& msg) { HC_LOG_TRACE(""); gaddr_info& ginfo = db_info_it->second; switch (ginfo.filter_mode) { //7.2.3. Definition of Source Timers //If the timer of a //source from the Include List expires, the source is deleted from the //Include List. If there are no more source records left, the //multicast address record is deleted from the router. case INCLUDE_MODE: { addr_storage notify_gaddr = db_info_it->first; for (auto it = std::begin(ginfo.include_requested_list); it != std::end(ginfo.include_requested_list);) { if (it->shared_source_timer.get() == msg.get()) { it = ginfo.include_requested_list.erase(it); continue; } ++it; } if (ginfo.include_requested_list.empty()) { m_db.group_info.erase(db_info_it); } state_change_notification(notify_gaddr); //only A break; } //7.2.3. Definition of Source Timers //If the timer //of a source from the Requested List expires, the source is moved to //the Exclude List. case EXCLUDE_MODE: { addr_storage notify_gaddr = db_info_it->first; for (auto it = std::begin(ginfo.include_requested_list); it != std::end(ginfo.include_requested_list);) { if (it->shared_source_timer.get() == msg.get()) { it->shared_source_timer.reset(); ginfo.exclude_list.insert(*it); it = ginfo.include_requested_list.erase(it); continue; } ++it; } state_change_notification(notify_gaddr); //only A break; } default: HC_LOG_ERROR("unknown filter mode"); } }
group_mem_protocol parser::parse_group_mem_proto() { HC_LOG_TRACE(""); //protocol = "protocol" potocol_type; //protocol_type = "MLDv1" | "MLDv2" | "IGMPv1" | "IGMPv2" | "IGMPv3"; group_mem_protocol result; if (get_parser_type() == PT_PROTOCOL) { get_next_token(); switch (m_current_token.get_type()) { case TT_MLDV1: result = MLDv1; break; case TT_MLDV2: result = MLDv2; break; case TT_IGMPV1: result = IGMPv1; break; case TT_IGMPV2: result = IGMPv2; break; case TT_IGMPV3: result = IGMPv3; break; default: HC_LOG_ERROR("failed to parse line " << m_current_line << " unknown token " << get_token_type_name(m_current_token.get_type()) << " with value " << m_current_token.get_string() << ", expected \"MLDV1\" or \"MLDv2\" or \"IGMPv1\" or \"IGMPv2\" or \"IGMPv3\""); throw "failed to parse config file"; break; } }else{ HC_LOG_ERROR("failed to parse line " << m_current_line << " unknown token " << get_token_type_name(m_current_token.get_type()) << " with value " << m_current_token.get_string() << ", expected \"protocol\""); throw "failed to parse config file"; } get_next_token(); if (m_current_token.get_type() == TT_NIL) { return result; } else { HC_LOG_ERROR("failed to parse line " << m_current_line << " unknown token " << get_token_type_name(m_current_token.get_type()) << " with value " << m_current_token.get_string()); throw "failed to parse config file"; } }
int igmp_sender::get_msg_min_size(){ HC_LOG_TRACE(""); if(m_version == 2){ return sizeof(struct igmp); }else{ HC_LOG_ERROR("IPv4 version: " << m_version << " not supported"); return -1; } }
const if_prop_map* if_prop::get_if_props() const{ HC_LOG_TRACE(""); if (!is_getaddrs_valid()) { HC_LOG_ERROR("data invalid"); return NULL; } return &m_if_map; }
int mld_sender::get_msg_min_size(){ HC_LOG_TRACE(""); if(m_version == 1){ return sizeof(struct mld_hdr); }else{ HC_LOG_ERROR("IPv6 version: " << m_version << " not supported"); return -1; } }
void querier::timer_triggerd_general_query_timer(const std::shared_ptr<timer_msg>& msg) { HC_LOG_TRACE(""); if (m_db.general_query_timer.get() == msg.get()) { send_general_query(); } else { HC_LOG_ERROR("general query timer not found"); } }
void proxy_instance::add_all_group_vifs_to_list(std::list<int>* vif_list, int without_if_index, addr_storage g_addr){ vif_map::iterator it_vif_map; state_table_map::iterator iter_table; g_state_map::iterator iter_state; src_group_state_pair* sgs_pair = 0; //all downstream traffic musst be forward to upstream if(without_if_index != m_upstream){ it_vif_map = m_vif_map.find(m_upstream); if(it_vif_map == m_vif_map.end()){ HC_LOG_ERROR("cant find vif to if_index:" << m_upstream); return; } vif_list->push_back(it_vif_map->second); //cout << "add_all_group_vifs_to_list: upstream gefunden und gesetzt. if_index: " << m_upstream << " vif: " << it_vif_map->second << endl; } //all downstream and upstream traffic musste be forward to the downstream who joined the same group for(iter_table = m_state_table.begin(); iter_table != m_state_table.end(); iter_table++){ if(without_if_index != iter_table->first){ iter_state = iter_table->second.find(g_addr); if(iter_state != iter_table->second.end()){ sgs_pair = &iter_state->second; //if the groupe is in use if(sgs_pair->second.flag == src_state::RUNNING || sgs_pair->second.flag == src_state::RESPONSE_STATE || sgs_pair->second.flag == src_state::WAIT_FOR_DEL){ it_vif_map = m_vif_map.find(iter_table->first); if(it_vif_map == m_vif_map.end()){ HC_LOG_ERROR("cant find vif to if_index:" << iter_table->first); return; } vif_list->push_back(it_vif_map->second); } } } } }
void if_prop::print_if_info() const{ HC_LOG_TRACE(""); if (!is_getaddrs_valid()) { HC_LOG_ERROR("data invalid"); return; } const if_prop_map* prop = get_if_props(); if(prop == NULL){ HC_LOG_ERROR("data struct not found"); return; } const struct ifaddrs* if_p; const list<const struct ifaddrs*>* if_p_list; cout << "##-- IPv4 [count:" << prop->size() << "]--##" << endl; for(if_prop_map::const_iterator iter = prop->begin(); iter != prop->end(); iter++){ if_p = get_ip4_if(iter->first); if(if_p == NULL){ HC_LOG_ERROR("interface name not found: " << iter->first); continue; } print_if_addr(if_p); } cout << "##-- IPv6 [count:" << prop->size() << "]--##" << endl; for(if_prop_map::const_iterator iter = prop->begin(); iter != prop->end(); iter++){ if_p_list = get_ip6_if(iter->first); if(if_p_list == NULL){ HC_LOG_ERROR("interface name not found: " << iter->first); continue; } for(list<const struct ifaddrs*>::const_iterator itera = if_p_list->begin(); itera != if_p_list->end(); itera++){ print_if_addr(*itera); } } }
void test_log() { hc_set_default_log_fun(HC_LOG_TRACE_LVL); HC_LOG_TRACE(""); HC_LOG_DEBUG("HC_LOG_DEBUG"); HC_LOG_INFO("HC_LOG_INFO"); HC_LOG_WARN("HC_LOG_WARN"); HC_LOG_ERROR("HC_LOG_ERROR"); HC_LOG_FATAL("HC_LOG_FATAL"); }
bool if_prop::refresh_network_interfaces(){ HC_LOG_TRACE(""); //clean if(is_getaddrs_valid()){ freeifaddrs(m_if_addrs); } m_if_map.clear(); //create if(getifaddrs(&m_if_addrs) < 0){ HC_LOG_ERROR("getifaddrs failed! Error: " << strerror(errno) ); return false; } struct ifaddrs* ifEntry=NULL; for(ifEntry=m_if_addrs; ifEntry!=NULL; ifEntry=ifEntry->ifa_next) { if(ifEntry->ifa_addr->sa_data == NULL) { continue; } if(ifEntry->ifa_addr->sa_family==AF_INET) { if_prop_map::iterator iter = m_if_map.find(ifEntry->ifa_name); if(iter != m_if_map.end()){ //existing interface if(iter->second.ip4_addr != NULL){ HC_LOG_WARN("more than one ipv4 address for one interface configurated! used:" << addr_storage(*(iter->second.ip4_addr->ifa_addr)) << "; don't used:" << addr_storage(*(ifEntry->ifa_addr)) << ";"); //return false; }else{ iter->second.ip4_addr = ifEntry; } }else{ //new interface m_if_map.insert(if_prop_pair(ifEntry->ifa_name, ipv4_6_pair(ifEntry,list<const struct ifaddrs*>()))); } } else if(ifEntry->ifa_addr->sa_family==AF_INET6) { if_prop_map::iterator iter = m_if_map.find(ifEntry->ifa_name); if(iter != m_if_map.end()){ //existing interface list<const struct ifaddrs*>* l = &iter->second.ip6_addr; l->push_back(ifEntry); }else{ //new interface list<const struct ifaddrs*> l; l.push_back(ifEntry); m_if_map.insert(if_prop_pair(ifEntry->ifa_name, ipv4_6_pair(NULL,l))); } } else { //It isn't IPv4 or IPv6 continue; } } return true; }
void querier::timer_triggerd_ret_source_timer(gaddr_map::iterator db_info_it, const std::shared_ptr<timer_msg>& msg) { HC_LOG_TRACE(""); gaddr_info& ginfo = db_info_it->second; if (ginfo.source_retransmission_timer.get() == msg.get()) { //msg is an retransmit filter timer message send_Q(msg->get_gaddr(), ginfo, ginfo.include_requested_list , source_list<source>(), true); } else { //msg is an retransmit source timer message HC_LOG_ERROR("retransmission timer not found"); } }
const list<const struct ifaddrs*>* if_prop::get_ip6_if(const string &if_name) const{ HC_LOG_TRACE(""); if (!is_getaddrs_valid()) { HC_LOG_ERROR("data invalid"); return NULL; } if_prop_map::const_iterator if_prop_iter = m_if_map.find(if_name); if(if_prop_iter == m_if_map.end()) return NULL; return &(if_prop_iter->second.ip6_addr); }
querier::querier(worker* msg_worker, group_mem_protocol querier_version_mode, int if_index, const std::shared_ptr<const sender>& sender, const std::shared_ptr<timing>& timing, const timers_values& tv, callback_querier_state_change cb_state_change) : m_msg_worker(msg_worker) , m_if_index(if_index) , m_db(querier_version_mode) , m_timers_values(tv) , m_cb_state_change(cb_state_change) , m_sender(sender) , m_timing(timing) { HC_LOG_TRACE(""); //join all router groups if (!router_groups_function(true)) { HC_LOG_ERROR("failed to subscribe multicast router groups"); throw "failed to subscribe multicast router groups"; } if (!send_general_query()) { HC_LOG_ERROR("failed to initialise query startup"); throw "failed to initialise query startup"; } }
bool proxy_instance::del_route(int if_index, const addr_storage& g_addr, const addr_storage& src_addr){ HC_LOG_TRACE(""); vif_map::iterator it_vif_map = m_vif_map.find(if_index); if(it_vif_map == m_vif_map.end()){ HC_LOG_ERROR("cant find vif to if_index:" << if_index); return false; } int vif = it_vif_map->second; m_routing.del_route(vif, g_addr, src_addr); return true; }
parser_type parser::get_parser_type() { if (m_current_token.get_type() == TT_PROTOCOL) { return PT_PROTOCOL; } else if (m_current_token.get_type() == TT_TABLE) { return PT_TABLE; } else if (m_current_token.get_type() == TT_PINSTANCE) { auto cmp_token = m_scanner.get_next_token(true, 1); if (cmp_token.get_type() == TT_DOUBLE_DOT || cmp_token.get_type() == TT_LEFT_BRACKET) { return PT_INSTANCE_DEFINITION; } else if (cmp_token.get_type() == TT_UPSTREAM || cmp_token.get_type() == TT_DOWNSTREAM) { return PT_INTERFACE_RULE_BINDING; } else { HC_LOG_ERROR("failed to parse line " << m_current_line << " unknown token " << get_token_type_name(cmp_token.get_type()) << " with value " << cmp_token.get_string() << ", expected \":\" or \"upstream\" or \"downstream\""); throw "failed to parse config file"; } } else if(m_current_token.get_type() == TT_DISABLE) { throw "mcproxy is disabled"; } else { HC_LOG_ERROR("failed to parse line " << m_current_line << " unknown token " << get_token_type_name(m_current_token.get_type()) << " with value " << m_current_token.get_string()); throw "failed to parse config file"; } }
void receiver::worker_thread() { HC_LOG_TRACE(""); int info_size = 0; //######################## //create msg //iov std::unique_ptr<unsigned char[]> iov_buf { new unsigned char[get_iov_min_size()] }; //unsigned char iov_buf[r->get_iov_min_size()]; struct iovec iov; iov.iov_base = iov_buf.get(); iov.iov_len = get_iov_min_size(); //sizeof(iov_buf); //control std::unique_ptr<unsigned char[]> ctrl { new unsigned char[get_ctrl_min_size()] }; //unsigned char ctrl[r->get_ctrl_min_size()]; //create msghdr struct msghdr msg; msg.msg_name = nullptr; msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = ctrl.get(); msg.msg_controllen = get_ctrl_min_size(); //sizeof(ctrl); msg.msg_flags = 0; //######################## while (m_running) { if (!m_mrt_sock->receive_msg(&msg, info_size)) { HC_LOG_ERROR("received failed"); sleep(1); continue; } if (info_size == 0) { continue; //on timeout } m_data_lock.lock(); analyse_packet(&msg, info_size); m_data_lock.unlock(); } }
bool proxy_instance::send_gq_to_all(){ HC_LOG_TRACE(""); HC_LOG_DEBUG("send general query to all"); bool correct= true; state_table_map::iterator it_state_table; for(it_state_table= m_state_table.begin(); it_state_table != m_state_table.end(); it_state_table++){ if(!m_sender->send_general_query(it_state_table->first)){ HC_LOG_ERROR("failed to send general to if_index: " << it_state_table->first); correct = false; } } return correct; }
bool proxy_instance::init_sender(){ HC_LOG_TRACE(""); if(m_addr_family == AF_INET){ m_sender = new igmp_sender; }else if(m_addr_family == AF_INET6){ m_sender = new mld_sender; }else{ HC_LOG_ERROR("wrong addr_family: " << m_addr_family); return false; } if(!m_sender->init(m_addr_family,m_version)) return false; return true; }
bool proxy_instance::init_receiver(){ HC_LOG_TRACE(""); if(m_addr_family == AF_INET){ m_receiver = new igmp_receiver(); }else if(m_addr_family == AF_INET6){ m_receiver = new mld_receiver(); }else{ HC_LOG_ERROR("wrong address family"); return false; } if(!m_receiver->init(m_addr_family,m_version, &m_mrt_sock)) return false; m_receiver->start(); return true; }
//interface_filter_fun is very useless, please overwork ??????????????? void querier::suggest_to_forward_traffic(const addr_storage& gaddr, std::list<std::pair<source, std::list<unsigned int>>>& rt_slist, std::function<bool(const addr_storage&)> interface_filter_fun) const { HC_LOG_TRACE(""); if (m_db.is_querier == true) { auto db_info_it = m_db.group_info.find(gaddr); if (db_info_it != std::end(m_db.group_info)) { if (db_info_it->second.is_under_bakcward_compatibility_effects()) { //accept all sources for (auto & e : rt_slist) { if (interface_filter_fun(e.first.saddr)) { e.second.push_back(m_if_index); } } } else { if (db_info_it->second.filter_mode == INCLUDE_MODE) { for (auto & e : rt_slist) { auto irl_it = db_info_it->second.include_requested_list.find(e.first); if (irl_it != std::end(db_info_it->second.include_requested_list) ) { if (interface_filter_fun(e.first.saddr)) { e.second.push_back(m_if_index); } } } } else if (db_info_it->second.filter_mode == EXCLUDE_MODE) { for (auto & e : rt_slist) { auto el_it = db_info_it->second.exclude_list.find(e.first); if (el_it == std::end(db_info_it->second.exclude_list) ) { if (interface_filter_fun(e.first.saddr)) { e.second.push_back(m_if_index); } } } } else { HC_LOG_ERROR("unknown filter mode"); } } } } }
bool reverse_path_filter::get_rp_filter(const std::string& if_name) const { HC_LOG_TRACE(""); std::stringstream path; bool state; path << REVERSE_PATH_FILTER_PATH << if_name << "/rp_filter"; std::ifstream is(path.str().c_str(), std::ios::binary | std::ios::in); if (!is) { HC_LOG_ERROR("failed to open file:" << path.str()); return false; } else { state = is.get(); } is.close(); return state; }