[PATCH 2/2] dhcpc: Allow to specify request-timeout during initial request transmission
Hans Dedecker
dedeckeh at gmail.com
Thu Feb 18 11:27:08 UTC 2016
RFC2131 paragraph 3.1 states the client should retransmit the DHCP
request message enough times to give adequate probability of contacting
the server without causing the client to wait overly to long before
giving up; as an example a total delay of 60 seconds is given.
The udhcp client implementation allows to tweak the number of request
messages via the -t option; however if -t option is set to 0 so the
the client keeps sending discover messages it will get stuck in the
requesting state after an offer if no DHCP ack or nack message is
received. The option -Q allows to specify the timeout in seconds
the client can send request messages before switching back to init
state. By default the initial_request_timeout is set to 0 to preserve
the old behavior
Signed-off-by: Hans Dedecker <dedeckeh at gmail.com>
---
networking/udhcp/dhcpc.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index 431f807..f5f2e80 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -68,6 +68,7 @@ static const char udhcpc_longopts[] ALIGN1 =
"foreground\0" No_argument "f"
"background\0" No_argument "b"
"broadcast\0" No_argument "B"
+ "request-timeout\0" Required_argument "Q"
IF_FEATURE_UDHCPC_ARPING("arping\0" Optional_argument "a")
IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P")
;
@@ -95,8 +96,9 @@ enum {
OPT_x = 1 << 18,
OPT_f = 1 << 19,
OPT_B = 1 << 20,
+ OPT_Q = 1 << 21,
/* The rest has variable bit positions, need to be clever */
- OPTBIT_B = 20,
+ OPTBIT_B = 21,
USE_FOR_MMU( OPTBIT_b,)
IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,)
IF_FEATURE_UDHCP_PORT( OPTBIT_P,)
@@ -1175,6 +1177,8 @@ static void client_background(void)
//usage: "\n -t,--retries N Send up to N discover packets (default 3)"
//usage: "\n -T,--timeout SEC Pause between packets (default 3)"
//usage: "\n -A,--tryagain SEC Wait if lease is not obtained (default 20)"
+//usage: "\n -Q,--request-timeout SEC Send initial request packets up to SEC seconds (default 0)"
+
//usage: "\n -n,--now Exit if lease is not obtained"
//usage: "\n -q,--quit Exit after obtaining lease"
//usage: "\n -R,--release Release IP on exit"
@@ -1212,6 +1216,7 @@ static void client_background(void)
//usage: "\n -t N Send up to N discover packets (default 3)"
//usage: "\n -T SEC Pause between packets (default 3)"
//usage: "\n -A SEC Wait if lease is not obtained (default 20)"
+//usage: "\n -Q SEC Send initial request packets up to SEC seconds (default 0)"
//usage: "\n -n Exit if lease is not obtained"
//usage: "\n -q Exit after obtaining lease"
//usage: "\n -R Release IP on exit"
@@ -1256,12 +1261,14 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
int tryagain_timeout = 20;
int discover_timeout = 3;
int discover_retries = 3;
+ int initial_request_timeout = 0;
uint32_t server_addr = server_addr; /* for compiler */
uint32_t requested_ip = 0;
uint32_t xid = xid; /* for compiler */
int packet_num;
int timeout; /* must be signed */
unsigned already_waited_sec;
+ unsigned first_request_sending;
unsigned opt;
IF_FEATURE_UDHCPC_ARPING(unsigned arpping_ms;)
int max_fd;
@@ -1276,10 +1283,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
str_V = "udhcp "BB_VER;
/* Parse command line */
- /* O,x: list; -T,-t,-A take numeric param */
- opt_complementary = "O::x::T+:t+:A+" IF_UDHCP_VERBOSE(":vv") ;
+ /* O,x: list; -T,-t,-A,-Q take numeric param */
+ opt_complementary = "O::x::T+:t+:A+:Q+" IF_UDHCP_VERBOSE(":vv") ;
IF_LONG_OPTS(applet_long_options = udhcpc_longopts;)
- opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB"
+ opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fBQ:"
USE_FOR_MMU("b")
IF_FEATURE_UDHCPC_ARPING("a::")
IF_FEATURE_UDHCP_PORT("P:")
@@ -1290,6 +1297,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
, &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */
, &list_O
, &list_x
+ , &initial_request_timeout /* Q */
IF_FEATURE_UDHCPC_ARPING(, &str_a)
IF_FEATURE_UDHCP_PORT(, &str_P)
IF_UDHCP_VERBOSE(, &dhcp_verbose)
@@ -1500,11 +1508,17 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
timeout = tryagain_timeout;
packet_num = 0;
continue;
- case REQUESTING:
- if (!discover_retries || packet_num < discover_retries) {
+ case REQUESTING: {
+ unsigned now = (unsigned)monotonic_sec();
+ if ((!discover_retries || packet_num < discover_retries) &&
+ (!initial_request_timeout || (initial_request_timeout > (now - first_request_sending)))) {
/* send broadcast select packet */
send_select(xid, server_addr, requested_ip);
timeout = discover_timeout;
+ /* Clamp the timeout to the maximum initial_request_timeout if specified */
+ if (initial_request_timeout && ((now + timeout - first_request_sending) > initial_request_timeout))
+ timeout = (first_request_sending + initial_request_timeout - now);
+
packet_num++;
continue;
}
@@ -1515,6 +1529,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
change_listen_mode(LISTEN_RAW);
state = INIT_SELECTING;
goto leasefail;
+ }
case BOUND:
/* 1/2 lease passed, enter renewing state */
state = RENEWING;
@@ -1700,6 +1715,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
timeout = 0;
packet_num = 0;
already_waited_sec = 0;
+ first_request_sending = (unsigned)monotonic_sec();
}
continue;
case REQUESTING:
--
1.9.1
More information about the busybox
mailing list