Hi Jukka,

> Some routers/AP handle the DHCP broadcast flag incorrectly.
> This means that some AP discard the DHCP packet if broadcast
> flag is present and some discard it if broadcast flag is missing.
> 
> The workaround is to send two DISCOVER packets in INIT state and
> two REQUEST packets in REBOOTING state. The first packet does not
> set the broadcast flag and the latter one sets it. When response
> is received, we check what kind of destination address (unicast or
> broadcast) the server used and start to send packets to it having
> either broadcast flag set or not.
> ---
> gdhcp/client.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
> gdhcp/common.c |  8 ++++---
> gdhcp/common.h |  3 ++-
> gdhcp/server.c |  4 ++--
> 4 files changed, 74 insertions(+), 13 deletions(-)
> 
> diff --git a/gdhcp/client.c b/gdhcp/client.c
> index 16fe080..238a301 100644
> --- a/gdhcp/client.c
> +++ b/gdhcp/client.c
> @@ -155,6 +155,7 @@ struct _GDHCPClient {
>       uint32_t expire;
>       bool retransmit;
>       struct timeval start_time;
> +     bool request_bcast;
> };
> 
> static inline void debug(GDHCPClient *client, const char *format, ...)
> @@ -436,6 +437,7 @@ static uint16_t dhcp_attempt_secs(GDHCPClient 
> *dhcp_client)
> static int send_discover(GDHCPClient *dhcp_client, uint32_t requested)
> {
>       struct dhcp_packet packet;
> +     int ret;
> 
>       debug(dhcp_client, "sending DHCP discover request");
> 
> @@ -455,15 +457,30 @@ static int send_discover(GDHCPClient *dhcp_client, 
> uint32_t requested)
> 
>       add_send_options(dhcp_client, &packet);
> 
> +     /*
> +      * We send discover packet twice, first without broadcast flag and
> +      * then with broadcast flag. Reason is various buggy routers/ap that
> +      * either eat the other or vice versa. In the receiving side we then
> +      * find out what kind of packet the server can send.
> +      */
> +     ret = dhcp_send_raw_packet(&packet, INADDR_ANY, CLIENT_PORT,
> +                             INADDR_BROADCAST, SERVER_PORT,
> +                             MAC_BCAST_ADDR, dhcp_client->ifindex, false);
> +     if (ret < 0)
> +             return ret;
> +
>       return dhcp_send_raw_packet(&packet, INADDR_ANY, CLIENT_PORT,
> -                                     INADDR_BROADCAST, SERVER_PORT,
> -                                     MAC_BCAST_ADDR, dhcp_client->ifindex);
> +                             INADDR_BROADCAST, SERVER_PORT,
> +                             MAC_BCAST_ADDR, dhcp_client->ifindex, true);
> }

I actually do not like the idea to send both at the same time. Has it been 
measured on what impact that might has on DHCP lease time. I rather have it 
send one first (maybe starting out with unicast) is safer here and have a 
timeout. If no response comes, we try the other type.

Once we know which ones work and which ones doesn't. We store that internally 
for that service. And next we start with that type first. However same applies, 
if the type we start with timeouts, then we try the other one. That seems like 
a smarter logic that allows us to adapt to different network cases while only 
eating the penalty once.

Regards

Marcel

_______________________________________________
connman mailing list
connman@connman.net
https://lists.connman.net/mailman/listinfo/connman

Reply via email to