⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rttable.c

📁 igmp proxy 实现源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    }    // Send join message upstream, if the route has no joined flag...    if(croute->upstrState != ROUTESTATE_JOINED) {        // Send Join request upstream        sendJoinLeaveUpstream(croute, 1);    }    IF_DEBUG logRouteTable("Insert Route");    return 1;}/***   Activates a passive group. If the group is already*   activated, it's reinstalled in the kernel. If*   the route is activated, no originAddr is needed.*/int activateRoute(uint32 group, uint32 originAddr) {    struct RouteTable*  croute;    int result = 0;    // Find the requested route.    croute = findRoute(group);    if(croute == NULL) {        IF_DEBUG log(LOG_DEBUG, 0, "No table entry for %s [From: %s]. Inserting route.",            inetFmt(group, s1),inetFmt(originAddr, s2));        // Insert route, but no interfaces have yet requested it downstream.        insertRoute(group, -1);        // Retrieve the route from table...        croute = findRoute(group);    }    if(croute != NULL) {        // If the origin address is set, update the route data.        if(originAddr > 0) {            if(croute->originAddr > 0 && croute->originAddr!=originAddr) {                log(LOG_WARNING, 0, "The origin for route %s changed from %s to %s",                    inetFmt(croute->group, s1),                    inetFmt(croute->originAddr, s2),                    inetFmt(originAddr, s3));            }            croute->originAddr = originAddr;        }        // Only update kernel table if there are listeners !        if(croute->vifBits > 0) {            result = internUpdateKernelRoute(croute, 1);        }    }    IF_DEBUG logRouteTable("Activate Route");    return result;}/***   This function loops through all routes, and updates the age *   of any active routes.*/void ageActiveRoutes() {    struct RouteTable   *croute, *nroute;        IF_DEBUG log(LOG_DEBUG, 0, "Aging routes in table.");    // Scan all routes...    for( croute = routing_table; croute != NULL; croute = nroute ) {                // Keep the next route (since current route may be removed)...        nroute = croute->nextroute;        // Run the aging round algorithm.        if(croute->upstrState != ROUTESTATE_CHECK_LAST_MEMBER) {            // Only age routes if Last member probe is not active...            internAgeRoute(croute);        }    }    IF_DEBUG logRouteTable("Age active routes");}/***   Should be called when a leave message is recieved, to*   mark a route for the last member probe state.*/void setRouteLastMemberMode(uint32 group) {    struct Config       *conf = getCommonConfig();    struct RouteTable   *croute;    croute = findRoute(group);    if(croute!=NULL) {        // Check for fast leave mode...        if(croute->upstrState == ROUTESTATE_JOINED && conf->fastUpstreamLeave) {            // Send a leave message right away..            sendJoinLeaveUpstream(croute, 0);        }        // Set the routingstate to Last member check...        croute->upstrState = ROUTESTATE_CHECK_LAST_MEMBER;        // Set the count value for expiring... (-1 since first aging)        croute->ageValue = conf->lastMemberQueryCount;    }}/***   Ages groups in the last member check state. If the*   route is not found, or not in this state, 0 is returned.*/int lastMemberGroupAge(uint32 group) {    struct Config       *conf = getCommonConfig();    struct RouteTable   *croute;    croute = findRoute(group);    if(croute!=NULL) {        if(croute->upstrState == ROUTESTATE_CHECK_LAST_MEMBER) {            return !internAgeRoute(croute);        } else {            return 0;        }    }    return 0;}/***   Remove a specified route. Returns 1 on success,*   and 0 if route was not found.*/int removeRoute(struct RouteTable*  croute) {    struct Config       *conf = getCommonConfig();    int result = 1;        // If croute is null, no routes was found.    if(croute==NULL) {        return 0;    }    // Log the cleanup in debugmode...    IF_DEBUG log(LOG_DEBUG, 0, "Removed route entry for %s from table.",                 inetFmt(croute->group, s1));    //BIT_ZERO(croute->vifBits);    // Uninstall current route from kernel    if(!internUpdateKernelRoute(croute, 0)) {        log(LOG_WARNING, 0, "The removal from Kernel failed.");        result = 0;    }    // Send Leave request upstream if group is joined    if(croute->upstrState == ROUTESTATE_JOINED ||        (croute->upstrState == ROUTESTATE_CHECK_LAST_MEMBER && !conf->fastUpstreamLeave))     {        sendJoinLeaveUpstream(croute, 0);    }    // Update pointers...    if(croute->prevroute == NULL) {        // Topmost node...        if(croute->nextroute != NULL) {            croute->nextroute->prevroute = NULL;        }        routing_table = croute->nextroute;    } else {        croute->prevroute->nextroute = croute->nextroute;        if(croute->nextroute != NULL) {            croute->nextroute->prevroute = croute->prevroute;        }    }    // Free the memory, and set the route to NULL...    free(croute);    croute = NULL;    IF_DEBUG logRouteTable("Remove route");    return result;}/***   Ages a specific route*/int internAgeRoute(struct RouteTable*  croute) {    struct Config *conf = getCommonConfig();    int result = 0;    // Drop age by 1.    croute->ageValue--;    // Check if there has been any activity...    if( croute->ageVifBits > 0 && croute->ageActivity == 0 ) {        // There was some activity, check if all registered vifs responded.        if(croute->vifBits == croute->ageVifBits) {            // Everything is in perfect order, so we just update the route age.            croute->ageValue = conf->robustnessValue;            //croute->ageActivity = 0;        } else {            // One or more VIF has not gotten any response.            croute->ageActivity++;            // Update the actual bits for the route...            croute->vifBits = croute->ageVifBits;        }    }     // Check if there have been activity in aging process...    else if( croute->ageActivity > 0 ) {        // If the bits are different in this round, we must        if(croute->vifBits != croute->ageVifBits) {            // Or the bits together to insure we don't lose any listeners.            croute->vifBits |= croute->ageVifBits;            // Register changes in this round as well..            croute->ageActivity++;        }    }    // If the aging counter has reached zero, its time for updating...    if(croute->ageValue == 0) {        // Check for activity in the aging process,        if(croute->ageActivity>0) {                        IF_DEBUG log(LOG_DEBUG, 0, "Updating route after aging : %s",                         inetFmt(croute->group,s1));                        // Just update the routing settings in kernel...            internUpdateKernelRoute(croute, 1);                // We append the activity counter to the age, and continue...            croute->ageValue = croute->ageActivity;            croute->ageActivity = 0;        } else {            IF_DEBUG log(LOG_DEBUG, 0, "Removing group %s. Died of old age.",                         inetFmt(croute->group,s1));            // No activity was registered within the timelimit, so remove the route.            removeRoute(croute);        }        // Tell that the route was updated...        result = 1;    }    // The aging vif bits must be reset for each round...    BIT_ZERO(croute->ageVifBits);    return result;}/***   Updates the Kernel routing table. If activate is 1, the route*   is (re-)activated. If activate is false, the route is removed.*/int internUpdateKernelRoute(struct RouteTable *route, int activate) {    struct   MRouteDesc     mrDesc;    struct   IfDesc         *Dp;    unsigned                Ix;        if(route->originAddr>0) {        // Build route descriptor from table entry...        // Set the source address and group address...        mrDesc.McAdr.s_addr     = route->group;        mrDesc.OriginAdr.s_addr = route->originAddr;            // clear output interfaces         memset( mrDesc.TtlVc, 0, sizeof( mrDesc.TtlVc ) );            IF_DEBUG log(LOG_DEBUG, 0, "Vif bits : 0x%08x", route->vifBits);        // Set the TTL's for the route descriptor...        for ( Ix = 0; Dp = getIfByIx( Ix ); Ix++ ) {            if(Dp->state == IF_STATE_UPSTREAM) {                //IF_DEBUG log(LOG_DEBUG, 0, "Identified VIF #%d as upstream.", Dp->index);                mrDesc.InVif = Dp->index;            }            else if(BIT_TST(route->vifBits, Dp->index)) {                IF_DEBUG log(LOG_DEBUG, 0, "Setting TTL for Vif %d to %d", Dp->index, Dp->threshold);                mrDesc.TtlVc[ Dp->index ] = Dp->threshold;            }        }            // Do the actual Kernel route update...        if(activate) {            // Add route in kernel...            addMRoute( &mrDesc );            } else {            // Delete the route from Kernel...            delMRoute( &mrDesc );        }    } else {        log(LOG_NOTICE, 0, "Route is not active. No kernel updates done.");    }    return 1;}/***   Debug function that writes the routing table entries*   to the log.*/void logRouteTable(char *header) {    IF_DEBUG  {        struct RouteTable*  croute = routing_table;        unsigned            rcount = 0;            log(LOG_DEBUG, 0, "\nCurrent routing table (%s);\n-----------------------------------------------------\n", header);        if(croute==NULL) {            log(LOG_DEBUG, 0, "No routes in table...");        } else {            do {                /*                log(LOG_DEBUG, 0, "#%d: Src: %s, Dst: %s, Age:%d, St: %s, Prev: 0x%08x, T: 0x%08x, Next: 0x%08x",                    rcount, inetFmt(croute->originAddr, s1), inetFmt(croute->group, s2),                    croute->ageValue,(croute->originAddr>0?"A":"I"),                    croute->prevroute, croute, croute->nextroute);                */                log(LOG_DEBUG, 0, "#%d: Src: %s, Dst: %s, Age:%d, St: %s, OutVifs: 0x%08x",                    rcount, inetFmt(croute->originAddr, s1), inetFmt(croute->group, s2),                    croute->ageValue,(croute->originAddr>0?"A":"I"),                    croute->vifBits);                                  croute = croute->nextroute;                         rcount++;            } while ( croute != NULL );        }            log(LOG_DEBUG, 0, "\n-----------------------------------------------------\n");    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -