@@ -502,8 +502,8 @@ dhcp_plugin_validateaddr(struct ctx *ctx, const struct in_addr *addr)
502502}
503503
504504static struct in_addr
505- dhcp_plugin_findaddr (struct ctx * ctx , char * hostname , const struct bootp * bootp ,
506- size_t len )
505+ dhcp_plugin_findaddr (struct ctx * ctx , char * hostname , uint32_t * ltime ,
506+ const struct bootp * bootp , size_t len )
507507{
508508 struct plugin * p ;
509509 struct sockaddr_in sin = {
@@ -517,6 +517,9 @@ dhcp_plugin_findaddr(struct ctx *ctx, char *hostname, const struct bootp *bootp,
517517 const char * hname = NULL ;
518518 size_t l ;
519519
520+ /* We might not get a least time so set to zero for a default. */
521+ * ltime = 0 ;
522+
520523 PLUGIN_FOREACH (ctx , p )
521524 {
522525 if (p -> p_lookup_hostname == NULL )
@@ -547,8 +550,8 @@ dhcp_plugin_findaddr(struct ctx *ctx, char *hostname, const struct bootp *bootp,
547550 {
548551 if (p -> p_lookup_addr == NULL )
549552 continue ;
550- err = p -> p_lookup_addr (p , (struct sockaddr * )& sin , hname , bootp ,
551- len );
553+ err = p -> p_lookup_addr (p , (struct sockaddr * )& sin , ltime , hname ,
554+ bootp , len );
552555 if (err == -1 ) {
553556 if (errno != ESRCH && errno != ENOSYS )
554557 logerr ("plugin %s" , p -> p_name );
@@ -787,10 +790,17 @@ dhcp_addoptions(struct bootp *bootp, uint8_t **p, const uint8_t *e,
787790 DHCP_PUT_B (p , e , DHO_MESSAGETYPE , type );
788791 DHCP_PUT_U32 (p , e , DHO_SERVERID , pool -> dp_addr .s_addr );
789792 if (type == DHCP_OFFER || type == DHCP_ACK ) {
790- uint32_t u32 , lease_time = ctx -> dhcp_lease_time ;
793+ uint32_t u32 , lease_time ;
791794 struct plugin * plug ;
792795 int n ;
793796
797+ if (pool -> dp_lease_time != 0 )
798+ lease_time = pool -> dp_lease_time ;
799+ else
800+ lease_time = ctx -> dhcp_lease_time ;
801+
802+ /* Allow the client to request a shorter leasetime
803+ * but not a longer one. */
794804 opt = dhcp_findoption (req , reqlen , DHO_LEASETIME );
795805 if (opt != NULL && opt [0 ] == sizeof (u32 )) {
796806 memcpy (& u32 , opt + 1 , sizeof (u32 ));
@@ -988,17 +998,23 @@ dhcp_set_expire_timeout(struct dhcp_ctx *ctx)
988998
989999static void
9901000dhcp_lease_settime (struct dhcp_ctx * ctx , struct dhcp_lease * lease ,
991- struct timespec * now , const struct bootp * bootp , size_t len )
1001+ struct timespec * now , uint32_t lease_time , const struct bootp * bootp ,
1002+ size_t len )
9921003{
9931004 const uint8_t * opt ;
994- uint32_t u32 , lease_time = ctx -> dhcp_lease_time ;
9951005
996- opt = dhcp_findoption (bootp , len , DHO_LEASETIME );
997- if (opt != NULL && opt [0 ] == sizeof (u32 )) {
998- memcpy (& u32 , opt + 1 , sizeof (u32 ));
999- u32 = ntohl (u32 );
1000- if (u32 < lease_time )
1001- lease_time = u32 ;
1006+ if (lease_time == 0 ) {
1007+ uint32_t u32 ;
1008+
1009+ lease_time = ctx -> dhcp_lease_time ;
1010+
1011+ opt = dhcp_findoption (bootp , len , DHO_LEASETIME );
1012+ if (opt != NULL && opt [0 ] == sizeof (u32 )) {
1013+ memcpy (& u32 , opt + 1 , sizeof (u32 ));
1014+ u32 = ntohl (u32 );
1015+ if (u32 < lease_time )
1016+ lease_time = u32 ;
1017+ }
10021018 }
10031019
10041020 if (lease -> dl_in_expire_tree ) {
@@ -1095,6 +1111,7 @@ dhcp_handlebootp(struct interface *ifp, struct bootp *bootp, size_t len,
10951111 uint8_t type , clientid [DHCP_CLIENTID_LEN + 1 ], fqdn_flags ;
10961112 struct in_addr addr = { .s_addr = INADDR_ANY };
10971113 char phostname [DHCP_HOSTNAME_LEN ] = { '\0' };
1114+ uint32_t pltime = 0 ;
10981115 struct in_addr paddr = { .s_addr = INADDR_ANY };
10991116 struct dhcp_lease * lease = NULL , * wanted = NULL ;
11001117 char clid_buf [sizeof (clientid ) * 3 ];
@@ -1153,8 +1170,10 @@ dhcp_handlebootp(struct interface *ifp, struct bootp *bootp, size_t len,
11531170 clientid [0 ] = bootp -> hlen + 1 ;
11541171 clientid [1 ] = bootp -> htype ;
11551172 memcpy (clientid + 2 , bootp -> chaddr , bootp -> hlen );
1156- } else
1173+ } else {
11571174 clientid [0 ] = '\0' ;
1175+ clientid [1 ] = '\0' ; /* silences maybe uninitialiased warning */
1176+ }
11581177
11591178 clid = hwaddr_ntoa (clientid + 1 , clientid [0 ], clid_buf ,
11601179 sizeof (clid_buf ));
@@ -1170,7 +1189,7 @@ dhcp_handlebootp(struct interface *ifp, struct bootp *bootp, size_t len,
11701189 return ;
11711190 if (lease -> dl_addr .s_addr == INADDR_ANY ) {
11721191 lease -> dl_addr = dhcp_plugin_findaddr (ifp -> if_ctx ,
1173- phostname , bootp , len );
1192+ phostname , & pltime , bootp , len );
11741193 if (lease -> dl_addr .s_addr != INADDR_ANY )
11751194 lease -> dl_flags |= DL_PLUGIN_ADDRESS ;
11761195 }
@@ -1260,8 +1279,8 @@ dhcp_handlebootp(struct interface *ifp, struct bootp *bootp, size_t len,
12601279 }
12611280 /* FALLTHROUGH */
12621281 case DHCP_REQUEST :
1263- paddr = dhcp_plugin_findaddr (ifp -> if_ctx , phostname , bootp ,
1264- len );
1282+ paddr = dhcp_plugin_findaddr (ifp -> if_ctx , phostname , & pltime ,
1283+ bootp , len );
12651284 if (paddr .s_addr == INADDR_ANY )
12661285 break ;
12671286 wanted = dhcp_lease_findaddr (ctx , & paddr );
@@ -1365,7 +1384,7 @@ dhcp_handlebootp(struct interface *ifp, struct bootp *bootp, size_t len,
13651384 expires = lease -> dl_expires ;
13661385 else
13671386 timespecclear (& expires );
1368- dhcp_lease_settime (ctx , lease , & now , bootp , len );
1387+ dhcp_lease_settime (ctx , lease , & now , pltime , bootp , len );
13691388 if (wanted != lease ) {
13701389 if (dhcp_lease_insertaddr (ctx , lease ) == -1 ) {
13711390 logerr ("%s: dhcp_lease_insertaddr" , __func__ );
@@ -1417,7 +1436,7 @@ dhcp_handlebootp(struct interface *ifp, struct bootp *bootp, size_t len,
14171436 lease -> dl_flags |= DL_PLUGIN_ADDRESS ;
14181437 else
14191438 lease -> dl_flags &= ~DL_PLUGIN_ADDRESS ;
1420- dhcp_lease_settime (ctx , lease , & now , bootp , len );
1439+ dhcp_lease_settime (ctx , lease , & now , pltime , bootp , len );
14211440 if (wanted != lease ) {
14221441 if (dhcp_lease_insertaddr (ctx , lease ) == -1 ) {
14231442 logerr ("%s: dhcp_lease_insertaddr" , __func__ );
@@ -1557,7 +1576,6 @@ dhcp_handlebootp(struct interface *ifp, struct bootp *bootp, size_t len,
15571576 if (lease -> dl_hostname [0 ] != '\0' )
15581577 lease -> dl_flags |= DL_HOSTNAME ;
15591578 }
1560- dhcp_commit_lease (ctx , lease , bootp , len );
15611579 break ;
15621580 }
15631581
@@ -1567,6 +1585,10 @@ dhcp_handlebootp(struct interface *ifp, struct bootp *bootp, size_t len,
15671585 case DHCP_ACK :
15681586 case DHCP_NAK :
15691587 dhcp_output (ifp , lease , type , msg , bootp , len );
1588+ /* Commit the lease after sending it as it might
1589+ * be a slow operation depending on what the plugins do. */
1590+ if (type != DHCP_NAK )
1591+ dhcp_commit_lease (ctx , lease , bootp , len );
15701592 break ;
15711593 }
15721594}
0 commit comments