在igmpproxy主程序运行之前需要先读取配置文件,igmpproxy的配置文件通常为/etc/igmpproxy.conf或者/var/igmpproxy.conf
其内容如下:
quickleave
mode 3
phyint ppp0 upstream ratelimit 0 threshold 1
phyint br0 downstream ratelimit 0 threshold 1

        igmpproxy加载配置文件信息由main函数中调用loadConfig()实现,加载配置文件的代码主要在config.c中。在分析loadConfig的具体实现之前,我们先了解config.c中的结构体struct
vifconfig。该结构体记录了关于igmpproxy端口等配置信息。
struct vifconfig {
char* name; //端口名称 如eth0
short state; //端口状态 0-无效端口 1
int ratelimit; //访问速率的限制值
int threshold; //TTl阈值
// Keep allowed nets for VIF.
struct SubnetList* allowednets; //关于子网IP地址及子网掩码的结构体 // Next config in list...
struct vifconfig* next; //下一个节点
};

        在config.c中,定义了struct
vifconfig的全局变量vifconf。这个全局变量保存了我们从配置文件中读取的配置信息。laodConfig()的主要作用就是讲配置文件中的信息记录了通过vifconf可以访问的链表中。然后main函数在调用igmpProxyInit(),该函数访问vifconf,进行相关配置。当然igmpProxyInit()还有其他作用。
    
    

loadConfig

    接下来我们进入loadConfig了解配置信息加载的主要流程。
void initCommonConfig()
    loadConfig首先调用initCommonConfig()函数,初始化一些公共常量
openConfigFile(configFile)
    打开配置文件,容易理解。除了打开配置文件外,这个函数还为全局指针变量iBuffer分配内存空间。iBuffer用于保存每次从配置文件中读取的512个字节的内容。igmpproxy的加载配置信息的实现是:每次从配置文件中至多读取512字节(实际上可能是一行一行读)的数据放在IBuffer中,然后再从iBuffer中解析出每一个token(关于iBuffer在nextConfigToken()会更详细的解释)。
nextConfigToken()
    顾名思义,nextConfigToken()的作用是从igmpproxy.conf中解析出一个一个token。但是它不是每一个token都去访问一次igmpproxy.conf的,而是一次性取出READ_BUFFER_SIZE大小的数据放在缓冲区iBuffer中,然后再从iBuffer中一个词一个词解析,这512字节解析完了遇到'\0'的时候,(bufPtr == readSize)为真,再fread出512字节的数据。

    如果igmpproxy.conf读完了,且读出来的数据都在nextConfigToken中解析完了,则(readSize < READ_BUFFER_SIZE && bufPtr == readSize)为真,这时返回NULL。
    因为nextConfigToken()使用了缓冲区iBuffer,它就不是每一次运行都去访问一次igmpproxy.conf。第一次运行nextConfigToken的时候我们必须执行fread从次igmpproxy.conf中读取512字节的数据,第二次执行nextConfigToken的时候,因为我们第一次读出来放在iBuffer中的数据还没有用完,就不需要在fread一次了。
loadConfig的核心流程  
        loadConfig()函数中,在第一次执行nextConfigToken获取一个token后,我们就进入了loadConfig的核心流程,也就是配置信息的解析以及将配置信息解析为结构体struct
vifconfig的成员变量保存在全局变量vifconf中(如端口信息,IP地址等等)。
    正确的配置文件可能包含三类信息(不一定三类都有),分别是phyint、quickleave和mode。loadConfig通过token与这三个词的匹配来判断要进行什么样的处理。(我下载的官方源码是不支持mode的,这可以通过自己修改源码实现,我们也可以再配置文件igmpproxy.conf中写入其他配置信息,然后再loadConfig增加处理方法)
    如果发现当前读取到的是有关phyint的信息,则调用parsePhyintToken()按照phyint的规则解析,将信息已结构体struct vifconfig的形式保存给指针tmpPtr,再通过currPtr串到vifconf中。关于parsePhyintToken后面有做说明。
        如果发现当前读取到的是quickleave,则写到公共配置中commonConfig.fastUpstreamLeave =
1;
parsePhyintToken
        首先看返回值,是一个struct
vifconfig 类型的结构体指针。
        在刚刚进入 parsePhyintToken时,token必须是网络接口的名字如(eth0,ppp0,br0),因此第一个token大小不能超过sizeof(
((struct ifreq *)NULL)->ifr_name)。接下来对结构体指针tmpPtr的成员变量进行初始化 。
    tmpPtr->next = NULL;    // Important to avoid seg fault...
tmpPtr->ratelimit = 0;
tmpPtr->threshold = 1;
tmpPtr->state = IF_STATE_DOWNSTREAM;
tmpPtr->allowednets = NULL

        初始化完成后,将token(此时为接口名称)拷贝给tmpPtr->name
 strcpy(tmpPtr->name, token);
        然后使用altnet、upstream等关键词逐个匹配后面的token。匹配到altnet是需要使用parseSubnetAddress进一步解析:
  *anetPtr = parseSubnetAddress(token);

        匹配到upstream、downstream、disabled、ratelimit、threshold时直接对tmpPtr的成员变量进行设置。如:
      else if(strcmp("upstream", token)==0) {
// Upstream
IF_DEBUG log(LOG_DEBUG, 0, "Config: IF: Got upstream token.");
tmpPtr->state = IF_STATE_UPSTREAM;

parseSubnetAddress
       将 a.b.c.d/n格式的子网IP解析为结构体struct
SubnetList
struct SubnetList {
uint32 subnet_addr;
uint32 subnet_mask;
struct SubnetList* next;
}

getCurrentConfigToken
    判断token是否合法,没什么好解释的。


总结:

    loadConfig主循环。
nextConfigToken()
while(){
phyint:
parsePhyintToken()
quickleave/mode:
直接修改公共配置
}

parsePhyintToken 将phyint的信息通过一个链表保存在vifconf中。 












igmpproxy源代码学习——配置信息加载 loadConfig的更多相关文章

  1. igmpproxy源代码学习——igmpProxyInit()

    igmpproxy源代码学习--igmpProxyInit()函数详解,igmpproxy初始化 在运行igmpproxy的主程序igmpproxyRun()之前需要对igmpproxy进行一些配置, ...

  2. Crystal框架配置参数加载机制详解?

    前言 定义 配置参数定义的形式 配置参数文件定义在哪里? 配置参数加载的优先级 如何使用配置参数? 最佳实践 Jar项目中如何定义配置参数? War项目中如何定义或重载Jar包中的配置参数? 开发人员 ...

  3. flutter 入口文件配置路由+加载页面

    入口文件配置路由 1.路由信息 -- 加载页面 ,通常用于显示新的内容或者广告,加载完成之后进入主页面 -- 主页面 /app 2.配置页面  main.dart main.dart // main ...

  4. 【Java Web开发学习】Spring加载外部properties配置文件

    [Java Web开发学习]Spring加载外部properties配置文件 转载:https://www.cnblogs.com/yangchongxing/p/9136505.html 1.声明属 ...

  5. Spring源码阅读 之 配置的加载(希望有喜欢源码的朋友一起交流)

    想写Spring的源码方面的东西想了好久了,之前花了一段时间学习了SpringCloud,现在总算对SpringCloud有了一个大概的了解,从今天开始好好读一篇Spring的源码,结合书本跟网上的一 ...

  6. SpringBoot 配置的加载

    SpringBoot 配置的加载 SpringBoot配置及环境变量的加载提供许多便利的方式,接下来一起来学习一下吧! 本章内容的源码按实战过程采用小步提交,可以按提交的节点一步一步来学习,仓库地址: ...

  7. 深入java虚拟机学习 -- 类的加载机制(续)

    昨晚写 深入java虚拟机学习 -- 类的加载机制 都到1点半了,由于第二天还要工作,没有将上篇文章中的demo讲解写出来,今天抽时间补上昨晚的例子讲解. 这里我先把昨天的两份代码贴过来,重新看下: ...

  8. Spring Boot自定义配置与加载

    Spring Boot自定义配置与加载 application.properties主要用来配置数据库连接.日志相关配置等.除了这些配置内容之外,还可以自定义一些配置项,如: my.config.ms ...

  9. Aspnetcore下面服务器热更新与配置热加载

    原文:Aspnetcore下面服务器热更新与配置热加载 Asp.net的热更新方案Appdomain在aspnetcore中不被支持了 新的方案如下: 配置文件更新选项 reloadOnChange ...

随机推荐

  1. javaee加密部署,tomcat使用自己的classloader解密

    http://www.2cto.com/kf/201312/264455.html [起因] 公司需要对一个web项目进行加密之后出售, 大家都知道的,class很好反编译, 所以需要对class文件 ...

  2. opencv2 学习第8天 提取分离前景和背景

    http://blog.csdn.net/zhouzhouzf/article/details/9281327 GrabCut 代码来自于http://www.cnblogs.com/tornadom ...

  3. GRUB2 分析 (一)

    GRUB是目前较流行启动引导程序.其第二版被主流Linux发行版所包括.本文将探索和分析GRUB的设计和实现机制. boot.S是第一个研究对象,因为boot.S将被编译成boot.img(512字节 ...

  4. WCF用户名密码验证方式

    WCF使用用户名密码验证 服务契约 namespace WCFUserNameConstract { [ServiceContract] public interface IWcfContract { ...

  5. AD9361

    AD9361框图   1. Fir滤波器的阶数为64或128 而内插或抽取因子为:1.2或4. HB1和HB2的内插或抽取因子为1或2而HB3的因子为1.2或3 BB_LPF为:三阶巴特沃斯低通滤波器 ...

  6. chrome调试工具

    Chrome调试面板 Chrome 开发者工具是一套内置在Google Chrome中Web开发和调试工具.使用开发者工具来重演,调试和剖析您的网站.其中常用的有Elements(元素面板).Cons ...

  7. bat(续五)-获取批处理文件所在路径

    获取批处理文件所在路径        在开发时,经常需要使用批处理运行一些程序,java程序 犹其是这样,往往需要运行时根路径.Hardcode一个路径总是令自己觉得不自在,例如一个java程序从一台 ...

  8. scala(一)方法&函数

    写在前面 众所周知,scala一向宣称自己是面向函数的编程,(java表示不服,我是面向bean的编程!)那什么是函数? 在接触java的时候,有时候用函数来称呼某个method(实在找不出词了),有 ...

  9. 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Sum

    2017-09-16 12:13:44 writer:pprp 特判 #include <iostream> using namespace std; int main() { int c ...

  10. [异常记录(二)] 验证视图状态 MAC 失败。如果此应用程序由网络场或群集承载,请确保 <machineKey> 配置指定了相同的 validationKey 和验证算法。不能在群集中使用 AutoGenerate。

    错误提示: 验证视图状态 MAC 失败.如果此应用程序由网络场或群集承载,请确保 <machineKey> 配置指定了相同的 validationKey 和验证算法.不能在群集中使用 Au ...