예제 #1
0
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;
    }
}
예제 #2
0
파일: parser.cpp 프로젝트: Tilka/mcproxy
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";
    }
}
예제 #3
0
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;
     }
}
예제 #4
0
파일: querier.cpp 프로젝트: Tilka/mcproxy
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;
    }
}
예제 #5
0
파일: querier.cpp 프로젝트: Tilka/mcproxy
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;
    }

}
예제 #6
0
파일: parser.cpp 프로젝트: Tilka/mcproxy
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";
}
예제 #7
0
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;
}
예제 #8
0
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;
        }


    }

}
예제 #9
0
파일: querier.cpp 프로젝트: Tilka/mcproxy
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;
}
예제 #10
0
파일: querier.cpp 프로젝트: Tilka/mcproxy
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");
    }
}
예제 #11
0
파일: parser.cpp 프로젝트: Tilka/mcproxy
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";
    }
}
예제 #12
0
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;
    }
}
예제 #13
0
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;
}
예제 #14
0
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;
     }
}
예제 #15
0
파일: querier.cpp 프로젝트: Tilka/mcproxy
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");
    }
}
예제 #16
0
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);
                }
            }

        }
    }
}
예제 #17
0
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);
          }
     }
}
예제 #18
0
파일: main.cpp 프로젝트: ViToni/mcproxy
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");
}
예제 #19
0
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;
}
예제 #20
0
파일: querier.cpp 프로젝트: Tilka/mcproxy
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");
    }
}
예제 #21
0
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);
}
예제 #22
0
파일: querier.cpp 프로젝트: Tilka/mcproxy
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";
    }
}
예제 #23
0
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;
}
예제 #24
0
파일: parser.cpp 프로젝트: Tilka/mcproxy
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";
    }
}
예제 #25
0
파일: receiver.cpp 프로젝트: ViToni/mcproxy
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();
    }
}
예제 #26
0
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;
}
예제 #27
0
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;
}
예제 #28
0
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;
}
예제 #29
0
파일: querier.cpp 프로젝트: Tilka/mcproxy
//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");
                }

            }
        }
    }

}
예제 #30
0
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;
}