首页 > 其他分享 >ISC DHCP租约分析

ISC DHCP租约分析

时间:2023-02-17 17:45:07浏览次数:45  
标签:状态 表中 next 租约 ISC DHCP pool lease

租约状态转换

DHCP服务系统中的租约共有八种状态:空闲状态、预留状态、活跃状态、过期状态、释放状态、废弃状态、重置状态、备份状态。重置状态和备份状态为启动FAILOVER模块后,主从服务器通过通信设置,在此不做讨论,其它六种状态的转换如图3-6所示:

 

 图3-6 租约状态转移图

如图3-6所示,租约状态转换条件如下:

空闲状态变成预留状态:当服务器收到DHCPDISCOVER请求时,从空闲租约表中选择一个可用的空闲租约分配给客户端,设置该租约超时时间为2分钟,将该租约设置成预留状态,并放入预留租约表中,表示该租约暂时不能分配给其他客户端。

预留状态变成空闲状态:2分钟内未收到客户端的DHCPREQUEST请求,说明未收到客户端的租约确认消息,将该租约重新设置成空闲状态,并插入空闲租约表中。

预留状态变成活跃状态:2分钟内收到客户端的DHCPREQUEST请求,说明该客户端接收了服务器为其分配的租约,将该租约设置成活跃状态,并插入活跃租约表中,表示该租约正在被某个客户端使用。

活跃状态保持活跃状态:当收到客户端的续租请求,从活跃租约表中取出租约,更新租约过期时间,并按新的过期时间将租约插入活跃租期表相应位置,该租约仍然保持活跃状态。

活跃状态变成过期状态:活跃状态的租约会连成一个活跃租期表,且按租约到期的先后顺序排序,服务器每隔20s会检查活跃租期表中的第一个租期是否到期,若到期将该租约设置成过期状态,且放入过期租约表中。

过期状态变成活跃状态:当收到客户端DHCPREQUEST请求时,所请求的租约在过期租约表中,则将该租约从过期租约表中取出,更新租约状态为活跃状态,并将租约插入活跃租期表中。

活跃状态变成释放状态:当收到客户端的DHCPRELEASE请求时,将相应的活跃租期从活跃租期表取出,更新该租约为释放状态,并插入释放租约表中。

释放状态变成活跃状态:当收到客户端DHCPREQUEST请求时,所请求的租约在释放租约表中,则将该租约从释放租约表中取出,更新租约状态为活跃状态,并将租约插入活跃租期表中。

释放状态/过期状态变成空闲状态:当释放租约表/空闲租约表中的租约超过阈值时,将该租约表中一半的租约从该表中取出,将它们更新为空闲状态,并插入空闲租约表中。

空闲状态变成废弃状态:当将一个空闲租约分配给客户端前,服务器发送ping包检测该IP是否已被使用,若收到ping应答包,说明该租约已被使用,于是将该租约设置成废弃状态,并插入废弃租约表中。

废弃状态变成空闲状态:当空闲租约表的租约不够用时,服务器向废弃租约表中的每个IP发送ping包,若未收到某个IP地址的应答包,则说明该IP已未被使用,将该IP所对应的租约设置成空闲状态,并插入空闲租约表中。

维护地址池的租期代码分析

根据dhcp协议规定,默认情况下client需要在T1/T2这两个时间向server发送DHCPREQUEST来续租ip(T1 = 50% * 租期, T2 = 87.5% * 租期)。当然,client在T1时刻发送DHCPREQUEST后没有收到对应的DHCPACK,才会在T2时刻再次尝试发送DHCPREQUEST。对server来说,如果在整个租期内都没有收到client的DHCPREQUEST续租请求,则需要重置lease的状态,使其可以被分配给其他client。

   以下就根据isc-dhcp的代码,主要从两个方面来简单分析server端是如何维护地址池租期的。

(注:在lease结构体中关键的成员starts/ends/sort_time,分别表示lease的开始/结束/下次排序时间)

1. 续租成功,更新lease

   在server收到client发来的DHCPREQUEST报文后,构建DHCPACK回复时,同时更新对应lease的开始和结束时间。可以看看isc-dhcp中的代码:

  1.   /* At this point, we have a lease that we can offer the client.
  2.   Now we construct a lease structure that contains what we want,
  3.   and call supersede_lease to do the right thing with it. */
  4.   lt = (struct lease *)0;
  5.   result = lease_allocate (&lt, MDL);
  6.   if (result != ISC_R_SUCCESS) {
  7.   log_info ("%s: can't allocate temporary lease structure: %s",
  8.   msg, isc_result_totext (result));
  9.   free_lease_state (state, MDL);
  10.   if (host)
  11.   host_dereference (&host, MDL);
  12.   return;
  13.   }
  14.    
  15.   /* Use the ip address of the lease that we finally found in
  16.   the database. */
  17.   lt -> ip_addr = lease -> ip_addr;
  18.   /* Start now. */
  19.   lt -> starts = cur_time;
  20.   /* Figure out how long a lease to assign. If this is a
  21.   dynamic BOOTP lease, its duration must be infinite. */
  22.   if (offer) {
  23.   ……
  24.   } else {
  25.   lt->flags |= BOOTP_LEASE;
  26.   ……
  27.   lt -> ends = state -> offered_expiry = cur_time + lease_time;
  28.   lt -> next_binding_state = FTS_ACTIVE;
  29.   }

2. 租约到期,释放lease

   定时器是个很好的工具,但此处不对isc的timer做介绍。主要阅读dhcp的定时更新地址池内leases的代码。

  1.   /* Timer called when a lease in a particular pool expires. */
  2.   void pool_timer (vpool)
  3.   void *vpool;
  4.   {
  5.   struct pool *pool;
  6.   struct lease *next = (struct lease *)0;
  7.   struct lease *lease = (struct lease *)0;
  8.   #define FREE_LEASES 0
  9.   #define ACTIVE_LEASES 1
  10.   #define EXPIRED_LEASES 2
  11.   #define ABANDONED_LEASES 3
  12.   #define BACKUP_LEASES 4
  13.   #define RESERVED_LEASES 5
  14.   struct lease **lptr[RESERVED_LEASES+1];
  15.   TIME next_expiry = MAX_TIME;
  16.   int i;
  17.   struct timeval tv; // 定时器时间间隔
  18.   pool = (struct pool *)vpool;
  19.   lptr [FREE_LEASES] = &pool -> free;
  20.   lptr [ACTIVE_LEASES] = &pool -> active;
  21.   lptr [EXPIRED_LEASES] = &pool -> expired;
  22.   lptr [ABANDONED_LEASES] = &pool -> abandoned;
  23.   lptr [BACKUP_LEASES] = &pool -> backup;
  24.   lptr[RESERVED_LEASES] = &pool->reserved;
  25.   /* 遍历所有状态下的lease */
  26.   for (i = FREE_LEASES; i <= RESERVED_LEASES; i++) {
  27.   /* If there's nothing on the queue, skip it. */
  28.   if (!*(lptr [i]))
  29.   continue;
  30.   #if defined (FAILOVER_PROTOCOL)
  31.   ……
  32.   #endif
  33.   lease_reference (&lease, *(lptr [i]), MDL);
  34.   while (lease) {
  35.   /* Remember the next lease in the list. */
  36.   if (next)
  37.   lease_dereference (&next, MDL);
  38.   if (lease -> next)
  39.   lease_reference (&next, lease -> next, MDL);
  40.   /* If we've run out of things to expire on this list, stop. */
  41.   /* 由于一开始就维护着链表按时间来排序,当sort_time
  42.   在cur_time之后,则可以终止本次遍历。因为接下来的
  43.   所有lease的sort_time均大于cur_time */
  44.   if (lease -> sort_time > cur_time) {
  45.   if (lease -> sort_time < next_expiry)
  46.   next_expiry = lease -> sort_time;
  47.   break;
  48.   }
  49.   /* If there is a pending state change, and
  50.   this lease has gotten to the time when the
  51.   state change should happen, just call
  52.   supersede_lease on it to make the change
  53.   happen. */
  54.   if (lease->next_binding_state != lease->binding_state)
  55.   {
  56.   #if defined(FAILOVER_PROTOCOL)
  57.   ……
  58.   #endif
  59.   /* 更改lease状态 */
  60.   supersede_lease(lease, NULL, 1, 1, 1);
  61.   }
  62.   lease_dereference (&lease, MDL);
  63.   if (next)
  64.   lease_reference (&lease, next, MDL);
  65.   }
  66.   if (next)
  67.   lease_dereference (&next, MDL);
  68.   if (lease)
  69.   lease_dereference (&lease, MDL);
  70.   }
  71.   if (next_expiry != MAX_TIME) {
  72.   pool -> next_event_time = next_expiry;
  73.   tv . tv_sec = pool -> next_event_time;
  74.   tv . tv_usec = 0;
  75.   /* 设置下次pool_timer执行时间 */
  76.   add_timeout (&tv, pool_timer, pool,
  77.   (tvref_t)pool_reference,
  78.   (tvunref_t)pool_dereference);
  79.   } else
  80.   pool -> next_event_time = MIN_TIME;
  81.   }

 

标签:状态,表中,next,租约,ISC,DHCP,pool,lease
From: https://www.cnblogs.com/dhcpclass/p/17131016.html

相关文章

  • CRUD-U,discuz,设置discuz帖子内上传的图片显示大小
    Discuz!  或者Discuz!x中默认帖内图片最大宽度是600px,当用户需要在发表的帖子内发表宽度大于600px的图片时,可以把图片显示宽度放大,防止图片被压缩导致失真。帖内......
  • Disconf实践指南:安装篇和使用篇【转】
    Disconf是百度开源出来的一款基于Zookeeper的分布式配置管理软件。目前很多公司都在使用,包括滴滴、百度、网易、顺丰等公司。通过简单的界面操作就可以动态修改配置属性,......
  • ctfshow---misc入门练习-----2023.2.14
    1,misc1打开就是flag2,misc2打开发现.png然后改后缀为.png即可得到flag3,misc3发现为.bpg的后缀,用bpgview.exe打开即可得到flag4,misc4下载了6个.txt文件,然后直接全......
  • python 安装redis,rediscluster
    首先看下pip版本,过低版本会出问题[root@testrpm]#pip-Vpip20.3.4from/usr/lib/python2.7/site-packages/pip(python2.7)再进行安装,包名要改成redis-py-cluste......
  • ubutu上配置iscsi
    参考https://www.a5idc.net/helpview_1091.htmlhttps://blog.51cto.com/cerana/5725318iSCSI代表Internet小型计算机系统接口是一种存储区域网络协议,可用于共享块设备......
  • springboot 配置redis集群 JedisCluster 3主3从 哈希槽模式
    packagecom.estate.util;importredis.clients.jedis.*;importjava.util.HashSet;importjava.util.Set;publicclassRedisClient{privatestaticJedis......
  • ipv6地名词:有状态(dhcpv6),无状态(slaac),前缀代理(pd)等解释
    ipv6地址获取有两种方式:路由器通告的前缀+自己编的后缀(无状态,stateless)DHCP给一个/128的地址(有状态,stateful)需要明确:无状态和有状态,仅仅指的是ipv6地址的获取方式。......
  • DHCP Message Type 53 Values
    RegistrationProcedure(s)IETFReviewReference[RFC2939]AvailableFormatsCSVValue MessageType Reference 1DHCPDISCOVER[RFC2132]2DHCPOFFER[RFC2......
  • 使用LNMP搭建discuz平台
    discuz官方网站:​​https://discuz.dismall.com/​​1.Nginx安装和配置#安装依赖包[root@Nginx~]#yum-yinstallgccpcrepcre-developenssl-devel#下载Nginx源码包,......
  • linux篇-centos7安装DHCP服务器
    1检查防火墙和selinux(关闭)关闭防火墙和selinux,这边不多说2检查DHCP状态3安装DHCP软件包4把系统默认的样例复制5修改配置文件optiondomain-name“example.org”;--DN......