DHCP 服务器,客户端代码都采用了统一的事件轮询(event loop),包含了任务处理消息,定时器消息,socke收发消息等等。

 static struct {
isc_appmethods_t methods; /*%
* The following are defined just for avoiding unused static functions.
*/
#ifndef BIND9
void *run, *shutdown, *start, *onrun, *reload, *finish,
*block, *unblock;
#endif
} appmethods = {
{
isc__appctx_destroy,
isc__app_ctxstart,
isc__app_ctxrun,
isc__app_ctxsuspend,
isc__app_ctxshutdown,
isc__app_ctxfinish,
isc__appctx_settaskmgr,
isc__appctx_setsocketmgr,
isc__appctx_settimermgr
}
#ifndef BIND9
,
(void *)isc__app_run, (void *)isc__app_shutdown,
(void *)isc__app_start, (void *)isc__app_onrun, (void *)isc__app_reload,
(void *)isc__app_finish, (void *)isc__app_block,
(void *)isc__app_unblock
#endif
};
(void)isc__taskmgr_dispatch(ctx->taskmgr); result = evloop(ctx);
if (result != ISC_R_SUCCESS)
return (result);

网卡接口对象的收包处理函数注册:

 for (tmp = interfaces; tmp; tmp = tmp -> next) {
/* not if it's been registered before */
if (tmp -> flags & INTERFACE_RUNNING)
continue;
if (tmp -> rfdesc == -)
continue;
switch (local_family) {
#ifdef DHCPv6
case AF_INET6:
status = omapi_register_io_object((omapi_object_t *)tmp,
if_readsocket,
, got_one_v6, , );
break;
#endif /* DHCPv6 */
case AF_INET:
default:
status = omapi_register_io_object((omapi_object_t *)tmp,
if_readsocket,
, got_one, , );
break;
} if (status != ISC_R_SUCCESS)
log_fatal ("Can't register I/O handle for %s: %s",
tmp -> name, isc_result_totext (status)); #if defined(DHCPv6)
/* Only register the first interface for V6, since they all
* use the same socket. XXX: This has some messy side
* effects if we start dynamically adding and removing
* interfaces, but we're well beyond that point in terms of
* mess.
*/
if (local_family == AF_INET6)
break;
#endif
} /* for (tmp = interfaces; ... */

omapi_register_io_object函数将收包处理函数got_one与对应的接口对象指针关联:

 status = omapi_object_reference (&obj -> inner, h, MDL);
if (status != ISC_R_SUCCESS) {
omapi_io_dereference (&obj, MDL);
return status;
} status = omapi_object_reference (&h -> outer,
(omapi_object_t *)obj, MDL);
if (status != ISC_R_SUCCESS) {
omapi_io_dereference (&obj, MDL);
return status;
} ...
obj -> reader = reader;

reader 就是指向 got_one 函数的函数指针参数,这样就可以从主流程main函数入口进入到收包处理流程了。

 isc_result_t got_one (h)
omapi_object_t *h; {
....
if (bootp_packet_handler) {
ifrom.len = ;
memcpy (ifrom.iabuf, &from.sin_addr, ifrom.len); (*bootp_packet_handler) (ip, &u.packet, (unsigned)result,
from.sin_port, ifrom, &hfrom);
}
....
}

bootp_packet_handler 即是 main函数设置的包处理函数:

 /* Set up various hooks. */
dhcp_interface_setup_hook = dhcpd_interface_setup_hook;
bootp_packet_handler = do_packet;
#ifdef DHCPv6
dhcpv6_packet_handler = do_packet6;
#endif /* DHCPv6 */

DHCP源码分析--主流程的更多相关文章

  1. Android应用层View绘制流程与源码分析

    1  背景 还记得前面<Android应用setContentView与LayoutInflater加载解析机制源码分析>这篇文章吗?我们有分析到Activity中界面加载显示的基本流程原 ...

  2. Nmap源码分析(脚本引擎)

    Nmap提供了强大的脚本引擎(NSE),以支持通过Lua编程来扩展Nmap的功能.目前脚本库已经包含300多个常用的Lua脚本,辅助完成Nmap的主机发现.端口扫描.服务侦测.操作系统侦测四个基本功能 ...

  3. Android Small插件化框架源码分析

    Android Small插件化框架源码分析 目录 概述 Small如何使用 插件加载流程 待改进的地方 一.概述 Small是一个写得非常简洁的插件化框架,工程源码位置:https://github ...

  4. SURF算法与源码分析、下

    上一篇文章 SURF算法与源码分析.上 中主要分析的是SURF特征点定位的算法原理与相关OpenCV中的源码分析,这篇文章接着上篇文章对已经定位到的SURF特征点进行特征描述.这一步至关重要,这是SU ...

  5. Tomcat源码分析--转

    一.架构 下面谈谈我对Tomcat架构的理解 总体架构: 1.面向组件架构 2.基于JMX 3.事件侦听 1)面向组件架构 tomcat代码看似很庞大,但从结构上看却很清晰和简单,它主要由一堆组件组成 ...

  6. 【Spring源码分析】非懒加载的单例Bean初始化过程(上篇)

    代码入口 上文[Spring源码分析]Bean加载流程概览,比较详细地分析了Spring上下文加载的代码入口,并且在AbstractApplicationContext的refresh方法中,点出了f ...

  7. 【Spring源码分析】非懒加载的单例Bean初始化过程(下篇)

    doCreateBean方法 上文[Spring源码分析]非懒加载的单例Bean初始化过程(上篇),分析了单例的Bean初始化流程,并跟踪代码进入了主流程,看到了Bean是如何被实例化出来的.先贴一下 ...

  8. Spring源码分析:Spring IOC容器初始化

    概述: Spring 对于Java 开发来说,以及算得上非常基础并且核心的框架了,在有一定开发经验后,阅读源码能更好的提高我们的编码能力并且让我们对其更加理解.俗话说知己知彼,百战不殆.当你对Spri ...

  9. Hessian源码分析--HessianSkeleton

    HessianSkeleton是Hessian的服务端的核心,简单总结来说:HessianSkeleton根据客户端请求的链接,获取到需要执行的接口及实现类,对客户端发送过来的二进制数据进行反序列化, ...

随机推荐

  1. C#接口总结

    C#接口总结 浅析C#接口特点及实例应用 C#接口(interface)的掌握对我们开发有什么作用呢?C#接口的使用能够使我们的程序有什么改进?那么我们首先我们来看看C#接口特点以及具体的实例使用分析 ...

  2. [原]使用MachOView辅助破解AppStore应用

    在破解iOS应用的过程中,需要经常使用 otool 开获取程序本身的信息(比如:是否启用了PIE),获取加密信息, 但是CLI的程序在直观性上还是不如GUI的, 下面描述使用MachOView来查看到 ...

  3. 对linux高级用户有用的20个命令

    41.命令:ifconfig ifconfig命令用于配置网络接口信息.如配置网络接口的ip地址,默认网关地址等,以便机器能够联通互联网. 显示当前网络接口信息 viidiot@ubuntu:~$ i ...

  4. IOS学习之路十六(UItableView 通过Prepare for segue 页面传值)

    当你点击一个UITableView 的section 或者cell的时候希望把值传到另一个页面(页面是通过segue跳转的),可以通过prepareforsegure 方法传值 (我的UITableV ...

  5. MongoDB学习3

    MongoDB学习(翻译3)   支持的where字句(比较多,今天先写一部分) 本节介绍支持的where字句 正如前面提到的,不是所有的C#表达式都支持where子句.您可以以此文为指导,或者你可以 ...

  6. Apple的通知

    Apple的通知 1. 本地通知 //取消原来的通知,可设可不设 [[UIApplication sharedApplication]cancelAllLocalNotifications]; //初 ...

  7. TCP通讯处理粘包详解

    TCP通讯处理粘包详解 一般所谓的TCP粘包是在一次接收数据不能完全地体现一个完整的消息数据.TCP通讯为何存在粘包呢?主要原因是TCP是以流的方式来处理数据,再加上网络上MTU的往往小于在应用处理的 ...

  8. iOS多线程的初步研究1

    iOS多线程的初步研究(一) 对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NS ...

  9. Lucene.net入门学习系列(1)

    Lucene.net入门学习系列(1)   Lucene.net入门学习系列(1)-分词 Lucene.net入门学习系列(2)-创建索引 Lucene.net入门学习系列(3)-全文检索 这几天在公 ...

  10. C语言栈与调用惯例

    C语言栈与调用惯例 1.前言 最近在再看<程序员的自我修养>这本书,对程序的链接.装载与库有了更深入的认识.关于这本书的评价可以去豆瓣看看http://book.douban.com/su ...