X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fdhcp-client.c;h=460fedf90f8f12812081efab1b6ae40217e7e9f4;hb=6b617bac12401ffad57c47ec9815860b87fa4152;hp=70f4e60fc312e65e0cdcae69b23314e741b87cbb;hpb=c5e61793e9e1f5e4cd24d6abd444e521408c8ee7;p=sliver-openvswitch.git diff --git a/lib/dhcp-client.c b/lib/dhcp-client.c index 70f4e60fc..460fedf90 100644 --- a/lib/dhcp-client.c +++ b/lib/dhcp-client.c @@ -103,6 +103,7 @@ struct dhclient { bool changed; unsigned int retransmit, delay; /* Used by send_reliably(). */ + unsigned int max_timeout; unsigned int init_delay; /* Used by S_INIT. */ @@ -199,6 +200,7 @@ dhclient_create(const char *netdev_name, cli->ipaddr = 0; cli->server_ip = 0; cli->retransmit = cli->delay = 0; + cli->max_timeout = 64; cli->min_timeout = 1; ds_init(&cli->s); cli->changed = true; @@ -206,6 +208,36 @@ dhclient_create(const char *netdev_name, return 0; } +/* Sets the maximum amount of timeout that 'cli' will wait for a reply from + * the DHCP server before retransmitting, in seconds, to 'max_timeout'. The + * default is 64 seconds. */ +void +dhclient_set_max_timeout(struct dhclient *cli, unsigned int max_timeout) +{ + cli->max_timeout = MAX(2, max_timeout); +} + +/* Destroys 'cli' and frees all related resources. */ +void +dhclient_destroy(struct dhclient *cli) +{ + if (cli) { + dhcp_msg_uninit(cli->binding); + free(cli->binding); + netdev_close(cli->netdev); + ds_destroy(&cli->s); + free(cli); + } +} + +/* Returns the network device in use by 'cli'. The caller must not destroy + * the returned device. */ +struct netdev * +dhclient_get_netdev(struct dhclient *cli) +{ + return cli->netdev; +} + /* Forces 'cli' into a (re)initialization state, in which no address is bound * but the client is advertising to obtain one. If 'requested_ip' is nonzero, * then the client will attempt to re-bind to that IP address; otherwise, it @@ -779,7 +811,13 @@ void dhclient_wait(struct dhclient *cli) { if (cli->min_timeout != UINT_MAX) { - poll_timer_wait(sat_mul(cli->min_timeout, 1000)); + time_t now = time_now(); + unsigned int wake = sat_add(cli->state_entered, cli->min_timeout); + if (wake <= now) { + poll_immediate_wake(); + } else { + poll_timer_wait(sat_mul(sat_sub(wake, now), 1000)); + } } /* Reset timeout to 1 second. This will have no effect ordinarily, because * dhclient_run() will typically set it back to a higher value. If, @@ -840,7 +878,7 @@ send_reliably(struct dhclient *cli, cli->modify_request(&msg, cli->aux); } do_send_msg(cli, &msg); - cli->delay = MIN(64, MAX(4, cli->delay * 2)); + cli->delay = MIN(cli->max_timeout, MAX(4, cli->delay * 2)); cli->retransmit += fuzz(cli->delay, 1); timeout(cli, cli->retransmit); dhcp_msg_uninit(&msg); @@ -916,8 +954,12 @@ do_receive_msg(struct dhclient *cli, struct dhcp_msg *msg) ofpbuf_pull(&b, (char *)b.l7 - (char*)b.data); error = dhcp_parse(msg, &b); if (!error) { - VLOG_DBG_RL(&rl, "received %s", - dhcp_msg_to_string(msg, false, &cli->s)); + if (VLOG_IS_DBG_ENABLED()) { + VLOG_DBG_RL(&rl, "received %s", + dhcp_msg_to_string(msg, false, &cli->s)); + } else { + VLOG_WARN_RL(&rl, "received %s", dhcp_type_name(msg->type)); + } ofpbuf_uninit(&b); return true; } @@ -992,7 +1034,11 @@ do_send_msg(struct dhclient *cli, const struct dhcp_msg *msg) * frame to have to be discarded or fragmented if it travels over a regular * Ethernet at some point. 1500 bytes should be enough for anyone. */ if (b.size <= ETH_TOTAL_MAX) { - VLOG_DBG("sending %s", dhcp_msg_to_string(msg, false, &cli->s)); + if (VLOG_IS_DBG_ENABLED()) { + VLOG_DBG("sending %s", dhcp_msg_to_string(msg, false, &cli->s)); + } else { + VLOG_WARN("sending %s", dhcp_type_name(msg->type)); + } error = netdev_send(cli->netdev, &b); if (error) { VLOG_ERR("send failed on %s: %s",