igmpproxy源代码学习——igmpProxyInit()

igmpproxy源代码学习——igmpProxyInit()函数详解,igmpproxy初始化

在运行igmpproxy的主程序igmpproxyRun()之前需要对igmpproxy进行一些配置,这些配置都是在igmpProxyInit()中完成的。

要进行的配置主要有:


信号处理配置

物理网络接口配置加载

配置文件的加载

虚拟网络设备初始化

路由向量表初始化

定时器初始化

信号处理配置

首先进行信号处理配置:

    sigemptyset(&sa.sa_mask);
    sigaction(SIGTERM, &sa, NULL);
    sigaction(SIGINT, &sa, NULL);

buildIfVc 物理网络接口配置加载

函数buildIfVc用于完成物理网络接口加载配置,将物理网络接口的配置保存在全局变量 IfDescVc[ MAX_IF ]中(这是目的)。

Sock = socket( AF_INET, SOCK_DGRAM, 0 )用于建立套接口,打开RAM

ioctl( Sock, SIOCGIFCONF, &IoCtlReq )用来获取所有网络接口列表(包含接口名字,IP地址)

然后进入一个循环体,该循环体会调用将前面获取的接口名字多次使用传入ioctl来分别获得子网掩码、索引号、Flags等信息。这些信息包括IP地址都将保存在IfDescVc[ MAX_IF ]中
关于IfDescVc的类型struct IfDesc 如下所示:

struct IfDesc {
    char                Name[ sizeof( ((struct ifreq *)NULL)->ifr_name ) ];
    struct in_addr      InAdr;          /* == 0 for non IP interfaces */
    short               Flags;
    short               state;        //状态:如upstream、downstream
    struct SubnetList*  allowednets; //一个子网链表
    unsigned int        robustness;
    unsigned char       threshold;   /* ttl limit */
    unsigned int        ratelimit;
    unsigned int        index;
};

configureVifs配置文件中信息的加载

在buildIfVc中,我们获取了物理网络接口的一些信息,但是要创建添加虚拟网路设备,仅有这些信息还不够,有些信息需要从配置文件中获取。在加载配置文件一文中,我们已经知道,配置文件中的有关虚拟网络设备的信息都被保存在vifconf中。

函数configuireVifs()的任务就是讲配置文件中关于虚拟网络设备的诸如robustness、allowednets、ratelimit等信息加载到IfDescVc[
MAX_IF ]中。

也就是说到这个函数完成这里,我们IfDescVc[ MAX_IF ]中保存了虚拟网络设备所需要的信息,这些信息由两部分组成,一个是物理网络接口的配置,一个是配置文件中关于虚拟网络设备的一些其他的描述

虚拟网络设备初始化AddVif

在创建虚拟网络设备之前需要执行   enableMRouter()完成对mrouter的初始化,创建套接口。具体如下:

    if ( (MRouterFD  = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP)) < 0 )//打开套接口MRouterFD
        log( LOG_ERR, errno, "IGMP socket open" );
    if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_INIT,(void *)&Va, sizeof( Va ) ) )//激活Linux内核模块mrouted服务
        return errno;

前面通过buildIfVc()和configureVifs()我们已经将要初始化的虚拟网络设备所需要的信息都保存在IfDescVc[
MAX_IF ]中了,接下来就是通过循环读取IfDescVc[ MAX_IF ]中的信息创建VIF虚拟网络设备。

AddVif()主要通过下面一行代码完成。

setsockopt( MRouterFD, IPPROTO_IP, MRT_ADD_VIF, (char *)&VifCtl, sizeof( VifCtl ) ) 

从上面代码我们看到参数VifCtl,该参数保存了虚拟网络设备的一些控制信息。VifCtl的类型struct
vifctl如下

struct vifctl {
	vifi_t	vifc_vifi;		/* Index of VIF */
	unsigned char vifc_flags;	/* VIFF_ flags */
	unsigned char vifc_threshold;	/* ttl limit */
	unsigned int vifc_rate_limit;	/* Rate limiter values (NI) */
	union {
		struct in_addr vifc_lcl_addr;     /* Local interface address */
		int            vifc_lcl_ifindex;  /* Local interface index   */
	};
	struct in_addr vifc_rmt_addr;	/* IPIP tunnel addr */
};

初始化igmp数据包 initIgmp();

初始化igmp数据包的报文格式,创建发送和接收数据包的缓冲区,为之后发送查询和接收报告做准备。

igmp数据包是实际上是在ip包首部中写入igmp相关信息,关于struct ip附上定义:

struct ip
  {
#if __BYTE_ORDER == __LITTLE_ENDIAN
    unsigned int ip_hl:4;               /* header length */
    unsigned int ip_v:4;                /* version */
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
    unsigned int ip_v:4;                /* version */
    unsigned int ip_hl:4;               /* header length */
#endif
    u_int8_t ip_tos;                    /* type of service */
    u_short ip_len;                     /* total length */
    u_short ip_id;                      /* identification */
    u_short ip_off;                     /* fragment offset field */
#define IP_RF 0x8000                    /* reserved fragment flag */
#define IP_DF 0x4000                    /* dont fragment flag */
#define IP_MF 0x2000                    /* more fragments flag */
#define IP_OFFMASK 0x1fff               /* mask for fragmenting bits */
    u_int8_t ip_ttl;                    /* time to live */
    u_int8_t ip_p;                      /* protocol */
    u_short ip_sum;                     /* checksum */
    struct in_addr ip_src, ip_dst;      /* source and dest address */
  };

关于用到的全局变量的组播地址:

allhosts_group   = htonl(INADDR_ALLHOSTS_GROUP); //224.0.0.1 在本子网上的所有参加多播的主机和路由器
allrouters_group = htonl(INADDR_ALLRTRS_GROUP);  //224.0.0.2 在本子网上的所有参加多播的路由器

这两个地址在后面会用到

初始化路由表  initRouteTable();

初始化路由表,为每个下行接口加入多播组allrouters_group

joinMcGroup( getMcGroupSock(), Dp, allrouters_group );

joinMcGroup中会调用

joinleave( int Cmd, int UdpSock, struct IfDesc *IfDp, uint32 mcastaddr )

因为传入的cmd为j,表示加入组(如果传入不是j,表示离开组)

joinleave最主要的代码是:

setsockopt( UdpSock, IPPROTO_IP,
          Cmd == 'j' ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP,
          (void *)&CtlReq, sizeof( CtlReq ) )

初始化时间表callout_init();

void callout_init() {
    queue = NULL;
}

初始化询问超时,queue=NULL

时间: 2024-11-07 18:19:40

igmpproxy源代码学习——igmpProxyInit()的相关文章

igmpproxy源代码学习——配置信息加载

在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()实现,加载配置文件的

nginx源代码学习资源(不断更新)

nginx源代码学习是一个痛苦又快乐的过程,以下列出了一些nginx的学习资源. 首先要做的当然是下载一份nginx源代码,能够从nginx官方站点下载一份最新的. 看了nginx源代码,发现这是一份全然没有凝视,全然没有配置文档的代码. 如今你最希望要的是一份凝视版的nginx源代码,能够从以下的链接中下载一份: https://github.com/jianfengye/nginx-1.0.14_comment 这份凝视版源代码会不断进行更新的 好了,第一个问题, nginx的main函数在

tablib源代码学习

tablib简介 ----------- Tablib is a format-agnostic tabular dataset library, written in Python. Tablib 是一个格式未知的表格操作库,使用python编写,目前(2014-06-11)支持如下格式:Excel .JSON .YAML .HTML.TSV .CSV的导入/导出,及修改操作.实现方法是使用各种数据格式的python支持库(大多是各种格式的有明支持库)导入数据成list(列表,python 内

struts2源代码学习之初始化(一)

看struts2源代码已有一段时日,从今天開始,就做一个总结吧. 首先,先看看怎么调试struts2源代码吧,主要是下面步骤: 使用Myeclipse创建一个webproject 导入struts2须要的jar包 如图: 让jar包关联源文件 在上图中的jar包右键,选择properties->java source attach,假设关联成功,双击jar包下的某个class文件就会显示java源码了. 双击.class文件,在源码关键地方设置断点 部署project到Tomcat Tomcat

[Java] LinkedList / Queue - 源代码学习笔记

简单地画了下 LinkedList 的继承关系,如下图.只是画了关注的部分,并不是完整的关系图.本博文涉及的是 Queue, Deque, LinkedList 的源代码阅读笔记.关于 List 接口的笔记,可以参考上一篇博文 List / ArrayList - 源代码学习笔记 Queue 1. 继承 Collection 接口,并提供了额外的插入.提取和查看元素的方法.新增的方法都有两种形式:当操作失败时,抛出异常或者返回一个特殊值.特殊值可以是 null 或者 false ,这取决于方法本

JDK源代码学习系列04----ArrayList

                                                                         JDK源代码学习系列04----ArrayList 1.ArrayList简单介绍 ArrayList是基于Object[] 数组的,也就是我们常说的动态数组.它能非常方便的实现数组的添加删除等操作. public class ArrayList<E> extends AbstractList<E> implements List<

lucene源代码学习之LZ4压缩算法在lucene中应用

LZ4算法又称为Realtime Compression Algorithm,在操作系统(linux/freeBSD).文件系统(OpenZFS).大数据(Hadoop).搜索引擎(Lucene/solr).数据库(Hbase)--都可以看到它的身影,可以说是一个非常通用的算法.LZ4最突出的地方在于它的压缩/解压速度. 基础知识 理解Lucene中LZ4算法的实现,需要有以下两点基础知识: 1. 理解Lucene里面的packedInts. 关于PacedInts,可以参考http://sbp

PetaPoco源代码学习--0.目录贴

2017年3季度后,以人力外包的形式派驻到甲方单位进行项目救急时,接触到了甲方单位的ASP.NET MVC项目的ORM框架,它以PetaPoco(2012年的老版本)进行改造升级的,当初就想学习一下这个小型的ORM框架,但是一直没有机会切入,目前,项目不是太紧张,想起此框架,因此,决定以此为目标,对该框架进行深入学习,希望能够坚持下来,学习框架里的编程思想来提高自己. 将该贴作为系列博文的索引页,同时也算是对自己的一个监督. 注:该源代码学习计划可能比较杂乱,没有系统性,关键是坚持,并理解其编程

jQuery源代码学习之六——jQuery数据缓存Data

一.jQuery数据缓存基本原理 jQuery数据缓存就两个全局Data对象,data_user以及data_priv; 这两个对象分别用于缓存用户自定义数据和内部数据: 以data_user为例,所有用户自定义数据都被保存在这个对象的cache属性下,cache在此姑且称之为自定义数据缓存: 自定义数据缓存和DOM元素/javascript对象通过id建立关联,id的查找通过DOM元素/javascript元素下挂载的expando属性获得 话不多说,直接上代码.相关思路在代码注释中都有讲解