zoukankan      html  css  js  c++  java
  • DHCP源码分析--主流程

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

     1 static struct {
     2     isc_appmethods_t methods;
     3 
     4     /*%
     5      * The following are defined just for avoiding unused static functions.
     6      */
     7 #ifndef BIND9
     8     void *run, *shutdown, *start, *onrun, *reload, *finish,
     9         *block, *unblock;
    10 #endif
    11 } appmethods = {
    12     {
    13         isc__appctx_destroy,
    14         isc__app_ctxstart,
    15         isc__app_ctxrun,
    16         isc__app_ctxsuspend,
    17         isc__app_ctxshutdown,
    18         isc__app_ctxfinish,
    19         isc__appctx_settaskmgr,
    20         isc__appctx_setsocketmgr,
    21         isc__appctx_settimermgr
    22     }
    23 #ifndef BIND9
    24     ,
    25     (void *)isc__app_run, (void *)isc__app_shutdown,
    26     (void *)isc__app_start, (void *)isc__app_onrun, (void *)isc__app_reload,
    27     (void *)isc__app_finish, (void *)isc__app_block,
    28     (void *)isc__app_unblock
    29 #endif
    30 };
    31         (void)isc__taskmgr_dispatch(ctx->taskmgr);
    32 
    33     result = evloop(ctx);
    34     if (result != ISC_R_SUCCESS)
    35         return (result);
    
    

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

     1 for (tmp = interfaces; tmp; tmp = tmp -> next) {
     2         /* not if it's been registered before */
     3         if (tmp -> flags & INTERFACE_RUNNING)
     4             continue;
     5         if (tmp -> rfdesc == -1)
     6             continue;
     7         switch (local_family) {
     8 #ifdef DHCPv6 
     9         case AF_INET6:
    10             status = omapi_register_io_object((omapi_object_t *)tmp,
    11                               if_readsocket, 
    12                               0, got_one_v6, 0, 0);
    13             break;
    14 #endif /* DHCPv6 */
    15         case AF_INET:
    16         default:
    17             status = omapi_register_io_object((omapi_object_t *)tmp,
    18                               if_readsocket, 
    19                               0, got_one, 0, 0);
    20             break;
    21         }
    22 
    23         if (status != ISC_R_SUCCESS)
    24             log_fatal ("Can't register I/O handle for %s: %s",
    25                    tmp -> name, isc_result_totext (status));
    26 
    27 #if defined(DHCPv6)
    28         /* Only register the first interface for V6, since they all
    29          * use the same socket.  XXX: This has some messy side
    30          * effects if we start dynamically adding and removing
    31          * interfaces, but we're well beyond that point in terms of
    32          * mess.
    33          */
    34         if (local_family == AF_INET6)
    35             break;
    36 #endif
    37     } /* for (tmp = interfaces; ... */

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

     1 status = omapi_object_reference (&obj -> inner, h, MDL);
     2     if (status != ISC_R_SUCCESS) {
     3         omapi_io_dereference (&obj, MDL);
     4         return status;
     5     }
     6 
     7     status = omapi_object_reference (&h -> outer,
     8                      (omapi_object_t *)obj, MDL);
     9     if (status != ISC_R_SUCCESS) {
    10         omapi_io_dereference (&obj, MDL);
    11         return status;
    12     }
    13 
    14         ...
    15         obj -> reader = reader;

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

     1 isc_result_t got_one (h)
     2     omapi_object_t *h; {
     3     ....
     4     if (bootp_packet_handler) {
     5         ifrom.len = 4;
     6         memcpy (ifrom.iabuf, &from.sin_addr, ifrom.len);
     7 
     8         (*bootp_packet_handler) (ip, &u.packet, (unsigned)result,
     9                      from.sin_port, ifrom, &hfrom);
    10     }
    11     ....
    12 }

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

    1 /* Set up various hooks. */
    2     dhcp_interface_setup_hook = dhcpd_interface_setup_hook;
    3     bootp_packet_handler = do_packet;
    4 #ifdef DHCPv6
    5     dhcpv6_packet_handler = do_packet6;
    6 #endif /* DHCPv6 */
  • 相关阅读:
    第四章:初识CSS3
    第三章:表单
    第二章:列表、表格与媒体元素
    人机猜拳
    类的无参方法
    javadoc
    类与对象
    vuex笔记
    vi 编辑器常用快捷键
    知识点笔记(二维数组排序、统计数组重复个数、)
  • 原文地址:https://www.cnblogs.com/danxi/p/5799507.html
Copyright © 2011-2022 走看看