udhcp源码详解(二)--转
定义的数据结构对于C程序的重要性,不言而喻。面向对象设计的程序是一个个对象的集合,而面向过程语言设计的程序则是数据结构与算法的集合。
下面来分析的是dhcp server中的定义结构体:
1)、在packet.h文件里定义了DHCP报文的格式:
struct dhcpMessage报文的字段虽然都有注释,但还是有必要讲下options字段。
options在大多文档中的说法是可选字段,大小不定,对于这个字段的重要性没有太多的强调。其实在DHCP交互过程,客户得到IP的配置过程,这个options字段有着很重要的作用,传递个很多不可或缺的信息。
例如Server与Client交互时,数据包的类型,是通过该字段的指示的。还有Client要成功连接到互联网,不只是需要IP,还需要其他的配置信息,如Dns、Router、Subnet等信息,Server就是通过options字段把这些信息传递给Client。(查看options支持哪些选项信息可以查看文档RFC2132)
问题来啦!!
这么多信息都放到一个字段,怎么合理的组织在一起呢,怎么能让交互双方准确的从这个字段取到相应的信息呢?
options字段才用“CLV“方式组织数据信息,OPT_CODE:标识号,唯一标识后面的信息内容;占1byte;OPT_LEN:长度,表示后面信息内容的长度,占1byte;value(OPT_DATA):信息内容,其长度由OPT_LEN所指定,以byte为单位(RFC2132文档给出所有支持选项的OPT_CODE,和可以确定长度的OPT_LEN的值)
CLV 的数据组织方式:
0 1 2 +Length
Code
Length
DATA
这是一种很漂亮的把多种数据信息组织在一个字段的方式,后面会看到对options字段相应的操作函数,这些函数就是根据CLV的方式对数据进行提取或者组织的。
另外options字段存储的信息分为三大类:
① DHCP_PADDING 填充字节 //读取的信息时候注意跳过
② DHCP_END 结束标志 //标志options字段的结束
③ CLV组织的有价值信息 //real value for us
options字段还有个让人纠结的情况——选项过载,其实也没什么,在后面遇再说吧!
2)、在dhcpd.h里定义里一个贯穿整个Server端程序的结构体struct server_config_t
上面的注释是源文件上的,本来的打算翻译下的,看了下注释很直白,没什么好翻译的,只是讲下其中的专业术语(好像是这么说的)。
network order 网络字节序, host order 主机字节序 相信大家了解她们的区别吧。
(定义类型是 uint32_t … ,说明变量是以network order存储的
常用数据类型 int long … ,说明变量是以host order存储的)
下面讲解下其中一些重要的成员:
① start,end可分配地址空间,每个客户的请求获得的IP都在这个内。IP地址池。
② struct option_set结构体的定义也在dhcpd.h里
Option set翻译过来:选项集合,就是的该结构的意义。上面分析struct dhcpMessage报文里有个选项字段options,她的值就是根据该集合(Option List)填写赋值的。
集合(Option List)里每个结点是一个选项信息,数据CLV的组织方式的。
与报文中options字段的区别是,报文里用一个options字段存储了所有的选项信息,options_set而是把一个一个的选项信息用链表链接起来。
③ 下面的几个是与租赁期限有关的成员变量
unsigned long lease client请求的租赁期限最大值,>lease,就以lease为租赁期限;client请求未指明租赁期限,lease作为其租赁期限(静态租赁的默认租期)。
unsigned long decline_time server的DHCPOFFER报文提供一个IP给client,client检测IP已经被其他主机使用,发送DHCPDECLINE报文给server,server接到该报文后,把IP添加到动态租赁数组里,租赁租期就是decline_time,对应的MAC为blank_chaddr(黑户,很形象^-^,实际值是全0)
unsigned long confict_time server在IP地址池找个a free IP时,检测到IP已被网络中的主机所使用,会把IP添加到动态租赁数组里,租赁期限就是confict_time,MAC:blank_chaddr。
unsigned long offer_time server发送DHCPOFFER报文时,即向client提供了IP地址,server会把IP和对应得MAC添加的动态租赁表里,但这个IP不一定会被client使用,所以添加到动态租赁表里的租赁期限要短,offer_time就是这个租赁期限(default : 60s)。(当server接收到DHCPREQUEST的时候会把租赁期限修改成请求的租赁期限)。
unsigned long min_lease client端的请求租赁期限不能小于min_lease。
④ 与保存租赁信息有关的两个成员变量:
char remaining 摘自dhcpd.conf里的注释(以及翻译和注解):
# If remaining is true (default), udhcpd will store the time
# remaining for each lease in the udhcpd leases file. This is
# for embedded systems that cannot keep time between reboots.
# If you set remaining to no, the absolute time that the lease
# expires at will be stored in the dhcpd.leases file.
# 如果剩下的就是true(默认),udhcpd将存储时间文件中
# 的每个udhcpd租赁租赁剩余。
# 这对于嵌入式系统,不能保持在重新启动的时间。
# (即重新启动就不算入租赁时间里)
# 如果您设置其余为NO,绝对时间,
# 租赁期满时将被储存在dhcpd.leases文件档案。
# 绝对时间,例: starts 0 2000/01/30 08:02:54;
# ends 5 2000/02/04 08:02:54;
# 而嵌入式存储的是租赁剩余时间
# 即 leases[i].expires - time(0) 的值
unsigne long auto_time how long should udhcpd wait before writing a config file.
if this is zero, it will only write one on SIGUSR1
多长时间把动态租赁表里的信息写入文件(dhcpd.leases)里。
Auto_time = 0的,只有等到SIGUSR1信号的时候才写。
⑤ struct static_lease *static_lease
/* dhcpd.h */
struct static_lease{
uint8_t *mac;
uint32_t *ip;
struct static_lease *next;
};
因为DHCP允许手动为client端配置IP,server端管理这些手动配置的IP就是使用该结构。
在dhcpd.c文件里声明定义一个struct server_config_t的全局变量server_config,server对于client的响应交互都必须有这个变量的参与。
3)、server端对于租赁出去的IP的管理基于以下这个结构体:
uint8_t chaddr[16]; 客户机的 MAC地址;
uint32_t yiaddr; 客户机租赁的IP地址;
uint32_t expires; 客户机租赁IP的到期时间
(是未来的一个时间点,是从1970.1.1午夜开始到租赁到期时刻的秒数)
这里有些奇怪,使用uint32_t声明的expires存储方式用的是host order, 这是因为server在把租赁记录保存到dhcpd.leases文件时使用的是network order方式保存的。(个人认为声明为unsigned long类型更为合适)
在dhcpd.c文件里声明定义一个 指向struct dhcpOferedAddr类型数组的全局指针变量leases。leases指向的数组大小由IP地址池大小决定的。
Server端主要的结构体就是这些,他们是整个server端程序跑起来的基础。还有一些其他结构体的设计是为了某些函数特别定制的,在分析具体函数再做讲解。
udhcp源码详解(二)--转的更多相关文章
- udhcp源码详解(五) 之DHCP包--options字段
中间有很长一段时间没有更新udhcp源码详解的博客,主要是源码里的函数太多,不知道要不要一个一个讲下去,要知道讲DHCP的实现理论的话一篇博文也就可以大致的讲完,但实现的源码却要关心很多的问题,比如说 ...
- udhcp源码详解(四) 之租赁IP的管理
Server端对于租赁出去的IP的管理是基于结构体dhcpOfferedAddr的,该结构体的定义是在leases.c文件里:(结构体的成员介绍说明见详解之数据结构) 1: struct dhcpOf ...
- udhcp源码详解(三) 下 之配置信息的读取
上节讲解了read_config函数,读取配置信息到server_config的相应成员变量里,但read_config函数只负责把配置信息重文件里读出来,具体怎么把信息填写到指定的地址内,是调用ke ...
- udhcp源码详解(三)上 之配置信息的读取
上节介绍了存储管理配置信息的结构体struct server_config_t,该结构体贯穿整个server端程序的运行. 在dhcpd.c里的用该结构体定义个一个全局的变量: struct serv ...
- udhcp源码详解(一)之文件组织结构(dhcp server) --转
udhcp目录下有十几个源文件,一个源文件相对应一个模块,完成一系列相关的功能,例如在static_leases.c主要针对static_lease链表增删查找等操作. dhcpd.c—— 整个d ...
- OkHttp3源码详解(二) 整体流程
1.简单使用 同步: @Override public Response execute() throws IOException { synchronized (this) { if (execut ...
- vue 源码详解(二): 组件生命周期初始化、事件系统初始化
vue 源码详解(二): 组件生命周期初始化.事件系统初始化 上一篇文章 生成 Vue 实例前的准备工作 讲解了实例化前的准备工作, 接下来我们继续看, 我们调用 new Vue() 的时候, 其内部 ...
- spring事务详解(三)源码详解
系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...
- Shiro 登录认证源码详解
Shiro 登录认证源码详解 Apache Shiro 是一个强大且灵活的 Java 开源安全框架,拥有登录认证.授权管理.企业级会话管理和加密等功能,相比 Spring Security 来说要更加 ...
随机推荐
- STL源码分析-iterator(迭代器)
1. GOF 迭代器设计模式 前面一篇文章有写到stl_list的实现,也实现了一下相应的iterator,但是后面觉得,实现具体容器之前有必要介绍一下iterator(迭代器) .那么迭代器是什么呢 ...
- find指令使用手册
find 目录 条件 选项 find . –print find . –print0 .指明在当前目录中查找 -print 打印匹配文件的文件名,使用‘\n’作为分隔文件的定位符 -print0 打印 ...
- webpack 之 plugin
loader和plugins的区别是:前者处理单个文件,而后者作用于整个打包过程 内置插件:BannerPlugin 可以在打包后的文件上方添加备注信息,如版权说明等 // webpack.confi ...
- python基础 : 1.计算机基础 2.注释 3.变量 4.标识符 5.输出 6.格式化输出 7.输入 8.算数运算符 9.字符串操作
- viva correction statements
* List of amendments| No. | Location | Amendments ...
- 分享下找到的Github上大神的EmpireofCode进攻策略:反正我是用了没反应,改了代码后单位不进攻,蠢站在那里,我自己的策略调调能打败不少人,这个日后慢慢研究吧,Github上暂时找到的唯一策略
from queue import PriorityQueue from enum import Enum from battle import commander from battle impor ...
- JavaEE JDBC 了解数据库连接池
了解数据库连接池 @author ixenos 数据库连接是有限的资源,如果用户需要离开应用一段时间,那么他占用的连接就不应该保持开放状态: 另一方面,每次查询都获取连接并在随后关闭它的代价也很高. ...
- POJ 1236 学校网络间的强连通
题目大意: N个学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输.问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件.问题2:至少需要添加几条 ...
- IPython的常见用法
IPython :交互式的Python命令行 安装: pip install ipython 使用(命令行中启动): ipython # 与Python解释器的使用方法一致 IPython高级功能: ...
- POJ1256 Anagram
Time Limit: 1000MS Memory Limit: 10000KB 64bit IO Format: %lld & %llu Submit Status Descript ...