📄 request.c
字号:
/*** igmpproxy - IGMP proxy based multicast router ** Copyright (C) 2005 Johnny Egeland <johnny@rlo.org>**** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA****----------------------------------------------------------------------------**** This software is derived work from the following software. The original** source code has been modified from it's original state by the author** of igmpproxy.**** smcroute 0.92 - Copyright (C) 2001 Carsten Schill <carsten@cschill.de>** - Licensed under the GNU General Public License, version 2** ** mrouted 3.9-beta3 - COPYRIGHT 1989 by The Board of Trustees of ** Leland Stanford Junior University.** - Original license can be found in the "doc/mrouted-LINCESE" file.***//*** request.c ** Functions for recieveing and processing IGMP requests.**/#include "defs.h"// Prototypes...void sendGroupSpecificMemberQuery(void *argument); typedef struct { uint32 group; uint32 vifAddr; short started;} GroupVifDesc;/*** Handles incoming membership reports, and* appends them to the routing table.*/void acceptGroupReport(uint32 src, uint32 group, uint8 type) { struct IfDesc *sourceVif; // Sanitycheck the group adress... if(!IN_MULTICAST( ntohl(group) )) { log(LOG_WARNING, 0, "The group address %s is not a valid Multicast group.", inetFmt(group, s1)); return; } // Find the interface on which the report was recieved. sourceVif = getIfByAddress( src ); if(sourceVif == NULL) { log(LOG_WARNING, 0, "No interfaces found for source %s", inetFmt(src,s1)); return; } if(sourceVif->InAdr.s_addr == src) { log(LOG_NOTICE, 0, "The IGMP message was from myself. Ignoring."); return; } // We have a IF so check that it's an downstream IF. if(sourceVif->state == IF_STATE_DOWNSTREAM) { IF_DEBUG log(LOG_DEBUG, 0, "Should insert group %s (from: %s) to route table. Vif Ix : %d", inetFmt(group,s1), inetFmt(src,s2), sourceVif->index); // The membership report was OK... Insert it into the route table.. insertRoute(group, sourceVif->index); } else { // Log the state of the interface the report was recieved on. log(LOG_INFO, 0, "Mebership report was recieved on %s. Ignoring.", sourceVif->state==IF_STATE_UPSTREAM?"the upstream interface":"a disabled interface"); }}/*** Recieves and handles a group leave message.*/void acceptLeaveMessage(uint32 src, uint32 group) { struct IfDesc *sourceVif; IF_DEBUG log(LOG_DEBUG, 0, "Got leave message from %s to %s. Starting last member detection.", inetFmt(src, s1), inetFmt(group, s2)); // Sanitycheck the group adress... if(!IN_MULTICAST( ntohl(group) )) { log(LOG_WARNING, 0, "The group address %s is not a valid Multicast group.", inetFmt(group, s1)); return; } // Find the interface on which the report was recieved. sourceVif = getIfByAddress( src ); if(sourceVif == NULL) { log(LOG_WARNING, 0, "No interfaces found for source %s", inetFmt(src,s1)); return; } // We have a IF so check that it's an downstream IF. if(sourceVif->state == IF_STATE_DOWNSTREAM) { GroupVifDesc *gvDesc; gvDesc = (GroupVifDesc*) malloc(sizeof(GroupVifDesc)); // Tell the route table that we are checking for remaining members... setRouteLastMemberMode(group); // Call the group spesific membership querier... gvDesc->group = group; gvDesc->vifAddr = sourceVif->InAdr.s_addr; gvDesc->started = 0; sendGroupSpecificMemberQuery(gvDesc); } else { // just ignore the leave request... IF_DEBUG log(LOG_DEBUG, 0, "The found if for %s was not downstream. Ignoring leave request."); }}/*** Sends a group specific member report query until the * group times out...*/void sendGroupSpecificMemberQuery(void *argument) { struct Config *conf = getCommonConfig(); // Cast argument to correct type... GroupVifDesc *gvDesc = (GroupVifDesc*) argument; if(gvDesc->started) { // If aging returns false, we don't do any further action... if(!lastMemberGroupAge(gvDesc->group)) { return; } } else { gvDesc->started = 1; } // Send a group specific membership query... sendIgmp(gvDesc->vifAddr, gvDesc->group, IGMP_MEMBERSHIP_QUERY, conf->lastMemberQueryInterval * IGMP_TIMER_SCALE, gvDesc->group, 0); IF_DEBUG log(LOG_DEBUG, 0, "Sent membership query from %s to %s. Delay: %d", inetFmt(gvDesc->vifAddr,s1), inetFmt(gvDesc->group,s2), conf->lastMemberQueryInterval); // Set timeout for next round... timer_setTimer(conf->lastMemberQueryInterval, sendGroupSpecificMemberQuery, gvDesc);}/*** Sends a general membership query on downstream VIFs*/void sendGeneralMembershipQuery() { struct Config *conf = getCommonConfig(); struct IfDesc *Dp; int Ix; // Loop through all downstream vifs... for ( Ix = 0; Dp = getIfByIx( Ix ); Ix++ ) { if ( Dp->InAdr.s_addr && ! (Dp->Flags & IFF_LOOPBACK) ) { if(Dp->state == IF_STATE_DOWNSTREAM) { // Send the membership query... sendIgmp(Dp->InAdr.s_addr, allhosts_group, IGMP_MEMBERSHIP_QUERY, conf->queryResponseInterval * IGMP_TIMER_SCALE, 0, 0); IF_DEBUG log(LOG_DEBUG, 0, "Sent membership query from %s to %s. Delay: %d", inetFmt(Dp->InAdr.s_addr,s1), inetFmt(allhosts_group,s2), conf->queryResponseInterval); } } } // Install timer for aging active routes. timer_setTimer(conf->queryResponseInterval, ageActiveRoutes, NULL); // Install timer for next general query... if(conf->startupQueryCount>0) { // Use quick timer... timer_setTimer(conf->startupQueryInterval, sendGeneralMembershipQuery, NULL); // Decrease startup counter... conf->startupQueryCount--; } else { // Use slow timer... timer_setTimer(conf->queryInterval, sendGeneralMembershipQuery, NULL); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -