X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gdhcp%2Fclient.c;h=5c5b42635cd40d16912e9be34bd4d1e545b9075d;hb=8a657ffc22119c65ee32c3c1f17c23950cf6c04e;hp=322639263f510d34a929cef741420d5b7d7261a5;hpb=03524ce74873a0df201894e6ae5f77a711d78849;p=framework%2Fconnectivity%2Fconnman.git diff --git a/gdhcp/client.c b/gdhcp/client.c index 3226392..5c5b426 100644 --- a/gdhcp/client.c +++ b/gdhcp/client.c @@ -33,7 +33,6 @@ #include #include -#include #include #include @@ -44,10 +43,10 @@ #include "common.h" #define DISCOVER_TIMEOUT 3 -#define DISCOVER_RETRIES 3 +#define DISCOVER_RETRIES 10 #define REQUEST_TIMEOUT 3 -#define REQUEST_RETRIES 3 +#define REQUEST_RETRIES 5 typedef enum _listen_mode { L_NONE, @@ -99,7 +98,21 @@ struct _GDHCPClient { gpointer debug_data; }; -static GTimer *timer = NULL; +static inline void debug(GDHCPClient *client, const char *format, ...) +{ + char str[256]; + va_list ap; + + if (client->debug_func == NULL) + return; + + va_start(ap, format); + + if (vsnprintf(str, sizeof(str), format, ap) > 0) + client->debug_func(str, client->debug_data); + + va_end(ap); +} /* Initialize the packet with the proper defaults */ static void init_packet(GDHCPClient *dhcp_client, @@ -151,6 +164,8 @@ static int send_discover(GDHCPClient *dhcp_client, uint32_t requested) { struct dhcp_packet packet; + debug(dhcp_client, "sending DHCP discover request"); + init_packet(dhcp_client, &packet, DHCPDISCOVER); packet.xid = dhcp_client->xid; @@ -176,6 +191,8 @@ static int send_select(GDHCPClient *dhcp_client) struct dhcp_packet packet; struct in_addr addr; + debug(dhcp_client, "sending DHCP select request"); + init_packet(dhcp_client, &packet, DHCPREQUEST); packet.xid = dhcp_client->xid; @@ -199,6 +216,8 @@ static int send_renew(GDHCPClient *dhcp_client) { struct dhcp_packet packet; + debug(dhcp_client, "sending DHCP renew request"); + init_packet(dhcp_client , &packet, DHCPREQUEST); packet.xid = dhcp_client->xid; packet.ciaddr = dhcp_client->requested_ip; @@ -216,6 +235,8 @@ static int send_rebound(GDHCPClient *dhcp_client) { struct dhcp_packet packet; + debug(dhcp_client, "sending DHCP rebound request"); + init_packet(dhcp_client , &packet, DHCPREQUEST); packet.xid = dhcp_client->xid; packet.ciaddr = dhcp_client->requested_ip; @@ -234,6 +255,8 @@ static int send_release(GDHCPClient *dhcp_client, { struct dhcp_packet packet; + debug(dhcp_client, "sending DHCP release request"); + init_packet(dhcp_client, &packet, DHCPRELEASE); packet.xid = rand(); packet.ciaddr = ciaddr; @@ -244,70 +267,7 @@ static int send_release(GDHCPClient *dhcp_client, server, SERVER_PORT); } -static gboolean interface_is_up(int index) -{ - int sk, err; - struct ifreq ifr; - gboolean ret = FALSE; - - sk = socket(PF_INET, SOCK_DGRAM, 0); - if (sk < 0) { - perror("Open socket error"); - return FALSE; - } - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_ifindex = index; - - err = ioctl(sk, SIOCGIFNAME, &ifr); - if (err < 0) { - perror("Get interface name error"); - goto done; - } - - err = ioctl(sk, SIOCGIFFLAGS, &ifr); - if (err < 0) { - perror("Get interface flags error"); - goto done; - } - - if (ifr.ifr_flags & IFF_UP) - ret = TRUE; - -done: - close(sk); - - return ret; -} - -static char *get_interface_name(int index) -{ - struct ifreq ifr; - int sk, err; - - if (index < 0) - return NULL; - - sk = socket(PF_INET, SOCK_DGRAM, 0); - if (sk < 0) { - perror("Open socket error"); - return NULL; - } - - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_ifindex = index; - - err = ioctl(sk, SIOCGIFNAME, &ifr); - if (err < 0) { - perror("Get interface name error"); - close(sk); - return NULL; - } - - close(sk); - - return g_strdup(ifr.ifr_name); -} static void get_interface_mac_address(int index, uint8_t *mac_address) { @@ -576,6 +536,9 @@ static gboolean request_timeout(gpointer user_data) { GDHCPClient *dhcp_client = user_data; + debug(dhcp_client, "request timeout (retries %d)", + dhcp_client->retry_times); + dhcp_client->retry_times++; start_request(dhcp_client); @@ -592,6 +555,9 @@ static int switch_listening_mode(GDHCPClient *dhcp_client, GIOChannel *listener_channel; int listener_sockfd; + debug(dhcp_client, "switch listening mode (%d ==> %d)", + dhcp_client->listen_mode, listen_mode); + if (dhcp_client->listen_mode == listen_mode) return 0; @@ -641,6 +607,9 @@ static int switch_listening_mode(GDHCPClient *dhcp_client, static void start_request(GDHCPClient *dhcp_client) { + debug(dhcp_client, "start request (retries %d)", + dhcp_client->retry_times); + if (dhcp_client->retry_times == REQUEST_RETRIES) { dhcp_client->state = INIT_SELECTING; @@ -686,6 +655,8 @@ static uint32_t get_lease(struct dhcp_packet *packet) static void restart_dhcp(GDHCPClient *dhcp_client, int retry_times) { + debug(dhcp_client, "restart DHCP (retries %d)", retry_times); + if (dhcp_client->timeout > 0) { g_source_remove(dhcp_client->timeout); dhcp_client->timeout = 0; @@ -702,6 +673,8 @@ static gboolean start_rebound_timeout(gpointer user_data) { GDHCPClient *dhcp_client = user_data; + debug(dhcp_client, "start rebound timeout"); + switch_listening_mode(dhcp_client, L2); dhcp_client->lease_seconds >>= 1; @@ -731,6 +704,8 @@ static gboolean start_rebound_timeout(gpointer user_data) static void start_rebound(GDHCPClient *dhcp_client) { + debug(dhcp_client, "start rebound"); + dhcp_client->state = REBINDING; dhcp_client->timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH, @@ -743,12 +718,8 @@ static void start_rebound(GDHCPClient *dhcp_client) static gboolean start_renew_timeout(gpointer user_data) { GDHCPClient *dhcp_client = user_data; - gdouble elapse; - gulong microseconds; - - elapse = g_timer_elapsed(timer, µseconds); - g_timer_start(timer); + debug(dhcp_client, "start renew timeout"); dhcp_client->state = RENEWING; @@ -773,13 +744,11 @@ static gboolean start_renew_timeout(gpointer user_data) static void start_bound(GDHCPClient *dhcp_client) { - dhcp_client->state = BOUND; + debug(dhcp_client, "start bound"); - if (timer == NULL) - timer = g_timer_new(); + dhcp_client->state = BOUND; - dhcp_client->timeout = - g_timeout_add_seconds_full(G_PRIORITY_HIGH, + dhcp_client->timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH, dhcp_client->lease_seconds >> 1, start_renew_timeout, dhcp_client, NULL); @@ -789,6 +758,8 @@ static gboolean restart_dhcp_timeout(gpointer user_data) { GDHCPClient *dhcp_client = user_data; + debug(dhcp_client, "restart DHCP timeout"); + dhcp_client->ack_retry_times++; restart_dhcp(dhcp_client, dhcp_client->ack_retry_times); @@ -829,9 +800,13 @@ static char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type) len = option[OPT_LEN - OPT_DATA]; type &= OPTION_TYPE_MASK; optlen = dhcp_option_lengths[type]; + if (optlen == 0) + return NULL; upper_length = len_of_option_as_string[type] * ((unsigned)len / (unsigned)optlen); dest = ret = malloc(upper_length + 1); + if (ret == NULL) + return NULL; while (len >= optlen) { switch (type) { @@ -874,15 +849,18 @@ static GList *get_option_value_list(char *value) char *pos = value; GList *list = NULL; + if (pos == NULL) + return NULL; + while ((pos = strchr(pos, ' ')) != NULL) { *pos = '\0'; - list = g_list_append(list, g_strdup(value)); + list = g_list_append(list, g_strdup(value)); value = ++pos; } - list = g_list_append(list, g_strdup(value)); + list = g_list_append(list, g_strdup(value)); return list; } @@ -908,6 +886,9 @@ static void get_request(GDHCPClient *dhcp_client, struct dhcp_packet *packet) type = dhcp_get_code_type(code); option_value = malloc_option_value_string(option, type); + if (option_value == NULL) + g_hash_table_remove(dhcp_client->code_value_hash, + GINT_TO_POINTER((int) code)); value_list = get_option_value_list(option_value); @@ -956,6 +937,9 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, /* No message type option, ignore pakcage */ return TRUE; + debug(dhcp_client, "received DHCP packet (current state %d)", + dhcp_client->state); + switch (dhcp_client->state) { case INIT_SELECTING: if (*message_type != DHCPOFFER) @@ -1018,6 +1002,9 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, break; } + debug(dhcp_client, "processed DHCP packet (new state %d)", + dhcp_client->state); + return TRUE; } @@ -1163,32 +1150,15 @@ static uint8_t *alloc_dhcp_option(int code, const char *str, int extra) return storage; } -static const char *get_hostname(const char *host) -{ - char local_host_name[HOST_NAME_MAX + 1]; - - if (g_strcmp0("", host) != 0) - return g_strdup(host); - - if (gethostname(local_host_name, HOST_NAME_MAX) != 0) - return NULL; - - local_host_name[HOST_NAME_MAX] = 0; - - return g_strdup(local_host_name); -} - /* Now only support send hostname */ GDHCPClientError g_dhcp_client_set_send(GDHCPClient *dhcp_client, unsigned char option_code, const char *option_value) { uint8_t *binary_option; - const char *hostname; - if (option_code == DHCP_HOST_NAME) { - hostname = get_hostname(option_value); - - binary_option = alloc_dhcp_option(option_code, hostname, 0); + if (option_code == G_DHCP_HOST_NAME && option_value != NULL) { + binary_option = alloc_dhcp_option(option_code, + option_value, 0); g_hash_table_insert(dhcp_client->send_value_hash, GINT_TO_POINTER((int) option_code), binary_option); @@ -1197,13 +1167,21 @@ GDHCPClientError g_dhcp_client_set_send(GDHCPClient *dhcp_client, return G_DHCP_CLIENT_ERROR_NONE; } -void g_dhcp_client_ref(GDHCPClient *dhcp_client) +GDHCPClient *g_dhcp_client_ref(GDHCPClient *dhcp_client) { + if (dhcp_client == NULL) + return NULL; + g_atomic_int_inc(&dhcp_client->ref_count); + + return dhcp_client; } void g_dhcp_client_unref(GDHCPClient *dhcp_client) { + if (dhcp_client == NULL) + return; + if (g_atomic_int_dec_and_test(&dhcp_client->ref_count) == FALSE) return; @@ -1222,8 +1200,11 @@ void g_dhcp_client_unref(GDHCPClient *dhcp_client) } void g_dhcp_client_set_debug(GDHCPClient *dhcp_client, - GDHCPDebugFunc func, gpointer data) + GDHCPDebugFunc func, gpointer user_data) { + if (dhcp_client == NULL) + return; + dhcp_client->debug_func = func; - dhcp_client->debug_data = data; + dhcp_client->debug_data = user_data; }