diff options
author | hyunuktak <hyunuk.tak@samsung.com> | 2015-08-07 17:11:34 +0900 |
---|---|---|
committer | hyunuktak <hyunuk.tak@samsung.com> | 2015-08-07 17:11:56 +0900 |
commit | 6aa4055ef0544ae85457c25c510fe3db04949c43 (patch) | |
tree | 94018be3cef92c33b60650c488dc15536c8f978a /gdhcp | |
parent | bc55a3df0d4d2d97964ce2fadc9fe3ffc4953f4e (diff) | |
download | connman-6aa4055ef0544ae85457c25c510fe3db04949c43.tar.gz connman-6aa4055ef0544ae85457c25c510fe3db04949c43.tar.bz2 connman-6aa4055ef0544ae85457c25c510fe3db04949c43.zip |
Base Code merged to SPIN 2.4submit/tizen/20150810.034432
Signed-off-by: hyunuktak <hyunuk.tak@samsung.com>
Change-Id: I84a42375b5c59739e4caca1f726699ea7647ef17
Diffstat (limited to 'gdhcp')
-rwxr-xr-x[-rw-r--r--] | gdhcp/client.c | 43 | ||||
-rwxr-xr-x[-rw-r--r--] | gdhcp/common.c | 61 | ||||
-rwxr-xr-x[-rw-r--r--] | gdhcp/common.h | 8 | ||||
-rwxr-xr-x[-rw-r--r--] | gdhcp/gdhcp.h | 10 | ||||
-rwxr-xr-x[-rw-r--r--] | gdhcp/ipv4ll.c | 23 | ||||
-rwxr-xr-x[-rw-r--r--] | gdhcp/ipv4ll.h | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | gdhcp/server.c | 20 |
7 files changed, 130 insertions, 37 deletions
diff --git a/gdhcp/client.c b/gdhcp/client.c index a72efb41..b4b3e7ee 100644..100755 --- a/gdhcp/client.c +++ b/gdhcp/client.c @@ -514,11 +514,13 @@ static int send_release(GDHCPClient *dhcp_client, uint32_t server, uint32_t ciaddr) { struct dhcp_packet packet; + uint64_t rand; debug(dhcp_client, "sending DHCP release request"); init_packet(dhcp_client, &packet, DHCPRELEASE); - packet.xid = rand(); + dhcp_get_random(&rand); + packet.xid = rand; packet.ciaddr = htonl(ciaddr); dhcp_add_option_uint32(&packet, DHCP_SERVER_ID, server); @@ -540,7 +542,7 @@ static gboolean send_probe_packet(gpointer dhcp_data) /* if requested_ip is not valid, pick a new address*/ if (dhcp_client->requested_ip == 0) { debug(dhcp_client, "pick a new random address"); - dhcp_client->requested_ip = ipv4ll_random_ip(0); + dhcp_client->requested_ip = ipv4ll_random_ip(); } debug(dhcp_client, "sending IPV4LL probe request"); @@ -1361,7 +1363,6 @@ static int dhcp_recv_l2_packet(struct dhcp_packet *dhcp_pkt, int fd, static void ipv4ll_start(GDHCPClient *dhcp_client) { guint timeout; - int seed; remove_timeouts(dhcp_client); @@ -1369,9 +1370,7 @@ static void ipv4ll_start(GDHCPClient *dhcp_client) dhcp_client->retry_times = 0; dhcp_client->requested_ip = 0; - /*try to start with a based mac address ip*/ - seed = (dhcp_client->mac_address[4] << 8 | dhcp_client->mac_address[4]); - dhcp_client->requested_ip = ipv4ll_random_ip(seed); + dhcp_client->requested_ip = ipv4ll_random_ip(); /*first wait a random delay to avoid storm of arp request on boot*/ timeout = ipv4ll_random_delay_ms(PROBE_WAIT); @@ -1670,6 +1669,7 @@ static gboolean start_expire(gpointer user_data) static gboolean continue_rebound(gpointer user_data) { GDHCPClient *dhcp_client = user_data; + uint64_t rand; switch_listening_mode(dhcp_client, L2); send_request(dhcp_client); @@ -1680,9 +1680,10 @@ static gboolean continue_rebound(gpointer user_data) /*recalculate remaining rebind time*/ dhcp_client->T2 >>= 1; if (dhcp_client->T2 > 60) { + dhcp_get_random(&rand); dhcp_client->t2_timeout = g_timeout_add_full(G_PRIORITY_HIGH, - dhcp_client->T2 * 1000 + (rand() % 2000) - 1000, + dhcp_client->T2 * 1000 + (rand % 2000) - 1000, continue_rebound, dhcp_client, NULL); @@ -1714,6 +1715,7 @@ static gboolean start_rebound(gpointer user_data) static gboolean continue_renew (gpointer user_data) { GDHCPClient *dhcp_client = user_data; + uint64_t rand; switch_listening_mode(dhcp_client, L3); send_request(dhcp_client); @@ -1721,11 +1723,14 @@ static gboolean continue_renew (gpointer user_data) if (dhcp_client->t1_timeout > 0) g_source_remove(dhcp_client->t1_timeout); + dhcp_client->t1_timeout = 0; + dhcp_client->T1 >>= 1; if (dhcp_client->T1 > 60) { + dhcp_get_random(&rand); dhcp_client->t1_timeout = g_timeout_add_full(G_PRIORITY_HIGH, - dhcp_client->T1 * 1000 + (rand() % 2000) - 1000, + dhcp_client->T1 * 1000 + (rand % 2000) - 1000, continue_renew, dhcp_client, NULL); @@ -2396,7 +2401,7 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, rapid_commit = dhcpv6_get_option(packet6, pkt_len, G_DHCPV6_RAPID_COMMIT, &option_len, &count); - if (!rapid_commit || option_len == 0 || + if (!rapid_commit || option_len != 0 || count != 1) /* RFC 3315, 17.1.4 */ return TRUE; @@ -2594,6 +2599,11 @@ static gboolean ipv4ll_announce_timeout(gpointer dhcp_data) GDHCPClient *dhcp_client = dhcp_data; uint32_t ip; +#if defined TIZEN_EXT + if (!dhcp_client) + return FALSE; +#endif + debug(dhcp_client, "request timeout (retries %d)", dhcp_client->retry_times); @@ -2642,6 +2652,7 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address) { int re; uint32_t addr; + uint64_t rand; if (dhcp_client->type == G_DHCP_IPV6) { if (dhcp_client->information_req_cb) { @@ -2750,7 +2761,8 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address) if (re != 0) return re; - dhcp_client->xid = rand(); + dhcp_get_random(&rand); + dhcp_client->xid = rand; dhcp_client->start = time(NULL); } @@ -2919,6 +2931,14 @@ int g_dhcp_client_get_index(GDHCPClient *dhcp_client) return dhcp_client->ifindex; } +char *g_dhcp_client_get_server_address(GDHCPClient *dhcp_client) +{ + if (!dhcp_client) + return NULL; + + return get_ip(dhcp_client->server_ip); +} + char *g_dhcp_client_get_address(GDHCPClient *dhcp_client) { return g_strdup(dhcp_client->assigned_ip); @@ -3143,6 +3163,9 @@ void g_dhcp_client_unref(GDHCPClient *dhcp_client) g_hash_table_destroy(dhcp_client->send_value_hash); g_free(dhcp_client); +#if defined TIZEN_EXT + dhcp_client = NULL; +#endif } void g_dhcp_client_set_debug(GDHCPClient *dhcp_client, diff --git a/gdhcp/common.c b/gdhcp/common.c index ac6b1250..6d457ac5 100644..100755 --- a/gdhcp/common.c +++ b/gdhcp/common.c @@ -35,6 +35,7 @@ #include <netpacket/packet.h> #include <net/ethernet.h> #include <arpa/inet.h> +#include <fcntl.h> #include "gdhcp.h" #include "common.h" @@ -58,6 +59,42 @@ static const DHCPOption client_options[] = { { OPTION_UNKNOWN, 0x00 }, }; +#define URANDOM "/dev/urandom" +static int random_fd = -1; + +int dhcp_get_random(uint64_t *val) +{ + int r; + + if (random_fd < 0) { + random_fd = open(URANDOM, O_RDONLY); + if (random_fd < 0) { + r = -errno; + *val = random(); + + return r; + } + } + + if (read(random_fd, val, sizeof(uint64_t)) < 0) { + r = -errno; + *val = random(); + + return r; + } + + return 0; +} + +void dhcp_cleanup_random(void) +{ + if (random_fd < 0) + return; + + close(random_fd); + random_fd = -1; +} + GDHCPOptionType dhcp_get_code_type(uint8_t code) { int i; @@ -421,12 +458,14 @@ void dhcp_init_header(struct dhcp_packet *packet, char type) void dhcpv6_init_header(struct dhcpv6_packet *packet, uint8_t type) { int id; + uint64_t rand; memset(packet, 0, sizeof(*packet)); packet->message = type; - id = random(); + dhcp_get_random(&rand); + id = rand; packet->transaction_id[0] = (id >> 16) & 0xff; packet->transaction_id[1] = (id >> 8) & 0xff; @@ -499,19 +538,14 @@ uint16_t dhcp_checksum(void *addr, int count) static const struct in6_addr in6addr_all_dhcp_relay_agents_and_servers_mc = IN6ADDR_ALL_DHCP_RELAY_AGENTS_AND_SERVERS_MC_INIT; -/* from netinet/in.h */ -struct in6_pktinfo { - struct in6_addr ipi6_addr; /* src/dst IPv6 address */ - unsigned int ipi6_ifindex; /* send/recv interface index */ -}; - int dhcpv6_send_packet(int index, struct dhcpv6_packet *dhcp_pkt, int len) { struct msghdr m; struct iovec v; struct in6_pktinfo *pktinfo; struct cmsghdr *cmsg; - int fd, ret; + int fd, ret, opt = 1; + struct sockaddr_in6 src; struct sockaddr_in6 dst; void *control_buf; size_t control_buf_len; @@ -520,6 +554,17 @@ int dhcpv6_send_packet(int index, struct dhcpv6_packet *dhcp_pkt, int len) if (fd < 0) return -errno; + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + memset(&src, 0, sizeof(src)); + src.sin6_family = AF_INET6; + src.sin6_port = htons(DHCPV6_CLIENT_PORT); + + if (bind(fd, (struct sockaddr *) &src, sizeof(src)) <0) { + close(fd); + return -errno; + } + memset(&dst, 0, sizeof(dst)); dst.sin6_family = AF_INET6; dst.sin6_port = htons(DHCPV6_SERVER_PORT); diff --git a/gdhcp/common.h b/gdhcp/common.h index 1ab9a7cd..7da13135 100644..100755 --- a/gdhcp/common.h +++ b/gdhcp/common.h @@ -170,6 +170,14 @@ static const uint8_t dhcp_option_lengths[] = { [OPTION_U32] = 4, }; +/* already defined within netinet/in.h if using GNU compiler */ +#ifndef __USE_GNU +struct in6_pktinfo { + struct in6_addr ipi6_addr; /* src/dst IPv6 address */ + unsigned int ipi6_ifindex; /* send/recv interface index */ +}; +#endif + char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type); uint8_t *dhcp_get_option(struct dhcp_packet *packet, int code); uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len, diff --git a/gdhcp/gdhcp.h b/gdhcp/gdhcp.h index f4ef2922..22fa9f4b 100644..100755 --- a/gdhcp/gdhcp.h +++ b/gdhcp/gdhcp.h @@ -150,6 +150,7 @@ GDHCPClientError g_dhcp_client_set_send(GDHCPClient *client, unsigned char option_code, const char *option_value); +char *g_dhcp_client_get_server_address(GDHCPClient *client); char *g_dhcp_client_get_address(GDHCPClient *client); char *g_dhcp_client_get_netmask(GDHCPClient *client); GList *g_dhcp_client_get_option(GDHCPClient *client, @@ -201,6 +202,9 @@ typedef enum { typedef void (*GDHCPSaveLeaseFunc) (unsigned char *mac, unsigned int nip, unsigned int expire); + +typedef void (*GDHCPLeaseAddedCb) (unsigned char *mac, uint32_t ip); + struct _GDHCPServer; typedef struct _GDHCPServer GDHCPServer; @@ -226,8 +230,14 @@ void g_dhcp_server_set_lease_time(GDHCPServer *dhcp_server, unsigned int lease_time); void g_dhcp_server_set_save_lease(GDHCPServer *dhcp_server, GDHCPSaveLeaseFunc func, gpointer user_data); +void g_dhcp_server_set_lease_added_cb(GDHCPServer *dhcp_server, + GDHCPLeaseAddedCb cb); void g_dhcp_server_set_save_ack_lease(GDHCPServer *dhcp_server, GDHCPSaveACKLeaseFunc func, gpointer user_data); + +int dhcp_get_random(uint64_t *val); +void dhcp_cleanup_random(void); + #ifdef __cplusplus } #endif diff --git a/gdhcp/ipv4ll.c b/gdhcp/ipv4ll.c index 9bf52b0a..c43971f0 100644..100755 --- a/gdhcp/ipv4ll.c +++ b/gdhcp/ipv4ll.c @@ -34,23 +34,19 @@ #include <glib.h> #include "ipv4ll.h" +#include "common.h" /** * Return a random link local IP (in host byte order) */ -uint32_t ipv4ll_random_ip(int seed) +uint32_t ipv4ll_random_ip(void) { unsigned tmp; + uint64_t rand; - if (seed) - srand(seed); - else { - struct timeval tv; - gettimeofday(&tv, NULL); - srand(tv.tv_usec); - } do { - tmp = rand(); + dhcp_get_random(&rand); + tmp = rand; tmp = tmp & IN_CLASSB_HOST; } while (tmp > (IN_CLASSB_HOST - 0x0200)); return ((LINKLOCAL_ADDR + 0x0100) + tmp); @@ -61,13 +57,10 @@ uint32_t ipv4ll_random_ip(int seed) */ guint ipv4ll_random_delay_ms(guint secs) { - struct timeval tv; - guint tmp; + uint64_t rand; - gettimeofday(&tv, NULL); - srand(tv.tv_usec); - tmp = rand(); - return tmp % (secs * 1000); + dhcp_get_random(&rand); + return rand % (secs * 1000); } int ipv4ll_send_arp_packet(uint8_t* source_eth, uint32_t source_ip, diff --git a/gdhcp/ipv4ll.h b/gdhcp/ipv4ll.h index aaac33ed..bee8138a 100644..100755 --- a/gdhcp/ipv4ll.h +++ b/gdhcp/ipv4ll.h @@ -43,7 +43,7 @@ extern "C" { #define RATE_LIMIT_INTERVAL 60 #define DEFEND_INTERVAL 10 -uint32_t ipv4ll_random_ip(int seed); +uint32_t ipv4ll_random_ip(void); guint ipv4ll_random_delay_ms(guint secs); int ipv4ll_send_arp_packet(uint8_t* source_eth, uint32_t source_ip, uint32_t target_ip, int ifindex); diff --git a/gdhcp/server.c b/gdhcp/server.c index 0171b5f4..83132a71 100644..100755 --- a/gdhcp/server.c +++ b/gdhcp/server.c @@ -56,7 +56,7 @@ struct _GDHCPServer { char *interface; uint32_t start_ip; uint32_t end_ip; - uint32_t server_nip; + uint32_t server_nip; /* our address in network byte order */ uint32_t lease_seconds; int listener_sockfd; guint listener_watch; @@ -65,6 +65,7 @@ struct _GDHCPServer { GHashTable *nip_lease_hash; GHashTable *option_hash; /* Options send to client */ GDHCPSaveLeaseFunc save_lease_func; + GDHCPLeaseAddedCb lease_added_cb; GDHCPSaveACKLeaseFunc save_ack_lease_func; GDHCPDebugFunc debug_func; gpointer debug_data; @@ -214,6 +215,9 @@ static struct dhcp_lease *add_lease(GDHCPServer *dhcp_server, uint32_t expire, g_hash_table_insert(dhcp_server->nip_lease_hash, GINT_TO_POINTER((int) lease->lease_nip), lease); + if (dhcp_server->lease_added_cb) + dhcp_server->lease_added_cb(lease->lease_mac, yiaddr); + return lease; } @@ -452,7 +456,7 @@ static void init_packet(GDHCPServer *dhcp_server, struct dhcp_packet *packet, packet->gateway_nip = client_packet->gateway_nip; packet->ciaddr = client_packet->ciaddr; dhcp_add_option_uint32(packet, DHCP_SERVER_ID, - dhcp_server->server_nip); + ntohl(dhcp_server->server_nip)); } static void add_option(gpointer key, gpointer value, gpointer user_data) @@ -669,7 +673,8 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, server_id_option = dhcp_get_option(&packet, DHCP_SERVER_ID); if (server_id_option) { - uint32_t server_nid = get_be32(server_id_option); + uint32_t server_nid = + get_unaligned((const uint32_t *) server_id_option); if (server_nid != dhcp_server->server_nip) return TRUE; @@ -832,6 +837,15 @@ void g_dhcp_server_set_save_lease(GDHCPServer *dhcp_server, dhcp_server->save_lease_func = func; } +void g_dhcp_server_set_lease_added_cb(GDHCPServer *dhcp_server, + GDHCPLeaseAddedCb cb) +{ + if (!dhcp_server) + return; + + dhcp_server->lease_added_cb = cb; +} + void g_dhcp_server_set_save_ack_lease(GDHCPServer *dhcp_server, GDHCPSaveACKLeaseFunc func, gpointer user_data) { |