X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fdhcpv6.c;h=4c07c769be86d6a0f931ba906322ac7a518341b6;hb=7ef7e96fc2f3eb620fffb6f277339214efe83747;hp=db9feb60da4fb1364243a708a55bf5f1e1001e2e;hpb=9c99015013fcf0abde65abaf2203dde64c07a962;p=platform%2Fupstream%2Fconnman.git diff --git a/src/dhcpv6.c b/src/dhcpv6.c index db9feb6..4c07c76 100755 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -105,20 +105,14 @@ static void clear_timer(struct connman_dhcpv6 *dhcp) } } -static inline guint get_random(void) +static guint compute_random(guint val) { - uint64_t val; - - __connman_util_get_random(&val); + uint64_t rand; - /* Make sure the value is always positive so strip MSB */ - return ((uint32_t)val) >> 1; -} + __connman_util_get_random(&rand); -static guint compute_random(guint val) -{ return val - val / 10 + - (get_random() % (2 * 1000)) * val / 10 / 1000; + ((guint) rand % (2 * 1000)) * val / 10 / 1000; } /* Calculate a random delay, RFC 3315 chapter 14 */ @@ -202,11 +196,24 @@ static int set_duid(struct connman_service *service, unsigned char *duid; int duid_len; - ident = __connman_service_get_ident(service); + ident = connman_service_get_identifier(service); +#if defined TIZEN_EXT + if(ident != NULL) + DBG("ident : %s", ident); +#endif keyfile = connman_storage_load_service(ident); + +#if defined TIZEN_EXT + if (!keyfile) { + keyfile = g_key_file_new(); + if (!keyfile) + return -EIO; + } +#else if (!keyfile) return -EINVAL; +#endif hex_duid = g_key_file_get_string(keyfile, ident, "IPv6.DHCP.DUID", NULL); @@ -240,6 +247,7 @@ static int set_duid(struct connman_service *service, hex_duid = convert_to_hex(duid, duid_len); if (!hex_duid) { + g_free(duid); g_key_file_free(keyfile); return -ENOMEM; } @@ -327,9 +335,19 @@ static void info_req_cb(GDHCPClient *dhcp_client, gpointer user_data) if (!compare_string_arrays(nameservers, dhcp->nameservers)) { if (dhcp->nameservers) { for (i = 0; dhcp->nameservers[i]; i++) +#if defined TIZEN_EXT + { + __connman_service_nameserver_remove(service, + dhcp->nameservers[i], false, + CONNMAN_IPCONFIG_TYPE_IPV6); +#else __connman_service_nameserver_remove(service, dhcp->nameservers[i], false); +#endif +#if defined TIZEN_EXT + } +#endif g_strfreev(dhcp->nameservers); } @@ -337,9 +355,19 @@ static void info_req_cb(GDHCPClient *dhcp_client, gpointer user_data) for (i = 0; dhcp->nameservers && dhcp->nameservers[i]; i++) +#if defined TIZEN_EXT + { + __connman_service_nameserver_append(service, + dhcp->nameservers[i], false, + CONNMAN_IPCONFIG_TYPE_IPV6); +#else __connman_service_nameserver_append(service, dhcp->nameservers[i], false); +#endif +#if defined TIZEN_EXT + } +#endif } else g_strfreev(nameservers); @@ -397,7 +425,9 @@ static int dhcpv6_info_request(struct connman_dhcpv6 *dhcp) return -EINVAL; } +#if !defined TIZEN_EXT if (getenv("CONNMAN_DHCPV6_DEBUG")) +#endif g_dhcp_client_set_debug(dhcp_client, dhcpv6_debug, "DHCPv6"); service = connman_service_lookup_from_network(dhcp->network); @@ -446,7 +476,6 @@ static int check_ipv6_addr_prefix(GSList *prefixes, char *address) if (!slash) continue; - prefix = g_strndup(prefix, slash - prefix); len = strtol(slash + 1, NULL, 10); if (len < 3 || len > 128) break; @@ -457,6 +486,7 @@ static int check_ipv6_addr_prefix(GSList *prefixes, char *address) left = plen % 8; i = 16 - count; + prefix = g_strndup(prefix, slash - prefix); inet_pton(AF_INET6, prefix, &addr_prefix); inet_pton(AF_INET6, address, &addr); @@ -522,9 +552,19 @@ static int set_other_addresses(GDHCPClient *dhcp_client, if (!compare_string_arrays(nameservers, dhcp->nameservers)) { if (dhcp->nameservers) { for (i = 0; dhcp->nameservers[i]; i++) +#if defined TIZEN_EXT + { + __connman_service_nameserver_remove(service, + dhcp->nameservers[i], + false, CONNMAN_IPCONFIG_TYPE_IPV6); +#else __connman_service_nameserver_remove(service, dhcp->nameservers[i], false); +#endif +#if defined TIZEN_EXT + } +#endif g_strfreev(dhcp->nameservers); } @@ -532,9 +572,19 @@ static int set_other_addresses(GDHCPClient *dhcp_client, for (i = 0; dhcp->nameservers && dhcp->nameservers[i]; i++) +#if defined TIZEN_EXT + { + __connman_service_nameserver_append(service, + dhcp->nameservers[i], + false, CONNMAN_IPCONFIG_TYPE_IPV6); +#else __connman_service_nameserver_append(service, dhcp->nameservers[i], false); +#endif +#if defined TIZEN_EXT + } +#endif } else g_strfreev(nameservers); @@ -643,6 +693,9 @@ static void set_address(int ifindex, struct connman_ipconfig *ipconfig, /* Is this prefix part of the subnet we are suppose to use? */ prefix_len = check_ipv6_addr_prefix(prefixes, address); +#if defined TIZEN_EXT + char *gateway = g_strdup(__connman_ipconfig_get_gateway(ipconfig)); +#endif __connman_ipconfig_address_remove(ipconfig); __connman_ipconfig_set_local(ipconfig, address); __connman_ipconfig_set_prefixlen(ipconfig, prefix_len); @@ -650,6 +703,11 @@ static void set_address(int ifindex, struct connman_ipconfig *ipconfig, DBG("new address %s/%d", address, prefix_len); __connman_ipconfig_set_dhcp_address(ipconfig, address); +#if defined TIZEN_EXT + DBG("Set gateway %s", gateway); + __connman_ipconfig_set_gateway(ipconfig, gateway); + g_free(gateway); +#endif __connman_service_save( __connman_service_lookup_from_index(ifindex)); } @@ -1192,12 +1250,17 @@ static int check_restart(struct connman_dhcpv6 *dhcp) g_dhcpv6_client_get_timeouts(dhcp->dhcp_client, NULL, NULL, NULL, &expired); + + /* infinite lifetime for an DHCPv6 address */ + if (expired == 0xffffffff) + return -EISCONN; + current = time(NULL); if (current >= expired) { DBG("expired by %d secs", (int)(current - expired)); - g_timeout_add(0, dhcpv6_restart, dhcp); + g_idle_add(dhcpv6_restart, dhcp); return -ETIMEDOUT; } @@ -1456,8 +1519,7 @@ int __connman_dhcpv6_start_renew(struct connman_network *network, /* RFC 3315, chapter 18.1.3, start rebind */ DBG("start rebind immediately"); - dhcp->timeout = g_timeout_add_seconds(0, start_rebind, - dhcp); + dhcp->timeout = g_idle_add(start_rebind, dhcp); } else if ((unsigned)current < (unsigned)started + T1) { delta = started + T1 - current; @@ -1714,7 +1776,9 @@ static gboolean timeout_solicitation(gpointer user_data) static int dhcpv6_solicitation(struct connman_dhcpv6 *dhcp) { struct connman_service *service; +#if !defined TIZEN_EXT struct connman_ipconfig *ipconfig_ipv6; +#endif GDHCPClient *dhcp_client; GDHCPClientError error; int index, ret; @@ -1729,7 +1793,9 @@ static int dhcpv6_solicitation(struct connman_dhcpv6 *dhcp) return -EINVAL; } +#if !defined TIZEN_EXT if (getenv("CONNMAN_DHCPV6_DEBUG")) +#endif g_dhcp_client_set_debug(dhcp_client, dhcpv6_debug, "DHCPv6"); service = connman_service_lookup_from_network(dhcp->network); @@ -1755,8 +1821,20 @@ static int dhcpv6_solicitation(struct connman_dhcpv6 *dhcp) g_dhcpv6_client_set_oro(dhcp_client, 3, G_DHCPV6_DNS_SERVERS, G_DHCPV6_DOMAIN_LIST, G_DHCPV6_SNTP_SERVERS); +#if defined TIZEN_EXT + /** + When privacy extension is enabled then connman requests + OPTION_IA_TA (4) from DHCPv6 server. This option is used to request + temporary IPv6 address from DHCPv6 server but we found that DHCPv6 + server never provided temporary IPv6 address and connman resend dhcpv6 + requests. So always set OPTION_IA_NA in dhcpv6 request to get IPv6 + address from DHCPv6 server. + */ + dhcp->use_ta = FALSE; +#else ipconfig_ipv6 = __connman_service_get_ip6config(service); dhcp->use_ta = __connman_ipconfig_ipv6_privacy_enabled(ipconfig_ipv6); +#endif g_dhcpv6_client_set_ia(dhcp_client, index, dhcp->use_ta ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA, @@ -2046,7 +2124,9 @@ static GDHCPClient *create_pd_client(struct connman_dhcpv6 *dhcp, int *err) return NULL; } +#if !defined TIZEN_EXT if (getenv("CONNMAN_DHCPV6_DEBUG")) +#endif g_dhcp_client_set_debug(dhcp_client, dhcpv6_debug, "DHCPv6:PD"); service = connman_service_lookup_from_network(dhcp->network); @@ -2159,7 +2239,7 @@ static int check_pd_restart(struct connman_dhcpv6 *dhcp) if (current > expired) { DBG("expired by %d secs", (int)(current - expired)); - g_timeout_add(0, dhcpv6_restart, dhcp); + g_idle_add(dhcpv6_restart, dhcp); return -ETIMEDOUT; }