diff options
Diffstat (limited to 'src')
-rwxr-xr-x[-rw-r--r--] | src/6to4.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/agent-connman.c | 44 | ||||
-rwxr-xr-x[-rw-r--r--] | src/agent.c | 13 | ||||
-rwxr-xr-x[-rw-r--r--] | src/bridge.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/clock.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/config.c | 6 | ||||
-rwxr-xr-x[-rw-r--r--] | src/connection.c | 12 | ||||
-rwxr-xr-x[-rw-r--r--] | src/connman-dbus.conf | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/connman-polkit.conf | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/connman.h | 20 | ||||
-rwxr-xr-x[-rw-r--r--] | src/connman.service.in | 7 | ||||
-rw-r--r-- | src/connman_tv.service.in | 12 | ||||
-rwxr-xr-x[-rw-r--r--] | src/counter.c | 5 | ||||
-rwxr-xr-x[-rw-r--r--] | src/dbus.c | 4 | ||||
-rwxr-xr-x[-rw-r--r--] | src/detect.c | 7 | ||||
-rwxr-xr-x[-rw-r--r--] | src/device.c | 8 | ||||
-rwxr-xr-x[-rw-r--r--] | src/dhcp.c | 16 | ||||
-rwxr-xr-x[-rw-r--r--] | src/dhcpv6.c | 77 | ||||
-rwxr-xr-x[-rw-r--r--] | src/dnsproxy.c | 156 | ||||
-rwxr-xr-x[-rw-r--r--] | src/eduroam.config | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/error.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/firewall.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/inet.c | 60 | ||||
-rwxr-xr-x[-rw-r--r--] | src/inotify.c | 30 | ||||
-rwxr-xr-x[-rw-r--r--] | src/ipaddress.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/ipconfig.c | 112 | ||||
-rwxr-xr-x[-rw-r--r--] | src/ippool.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/iptables.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/ipv6pd.c | 6 | ||||
-rwxr-xr-x[-rw-r--r--] | src/log.c | 124 | ||||
-rwxr-xr-x[-rw-r--r--] | src/machine.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/main.c | 55 | ||||
-rwxr-xr-x[-rw-r--r--] | src/main.conf | 15 | ||||
-rwxr-xr-x[-rw-r--r--] | src/manager.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/nat.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/net.connman.service.in | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | src/network.c | 340 | ||||
-rwxr-xr-x[-rw-r--r--] | src/notifier.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/ntp.c | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | src/peer.c | 99 | ||||
-rwxr-xr-x[-rw-r--r--] | src/peer_service.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/plugin.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/provider.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/proxy.c | 8 | ||||
-rwxr-xr-x[-rw-r--r--] | src/resolver.c | 34 | ||||
-rwxr-xr-x[-rw-r--r--] | src/rfkill.c | 30 | ||||
-rwxr-xr-x[-rw-r--r--] | src/rtnl.c | 123 | ||||
-rwxr-xr-x[-rw-r--r--] | src/service.c | 693 | ||||
-rwxr-xr-x[-rw-r--r--] | src/session.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/shared/netlink.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/shared/netlink.h | 0 | ||||
-rw-r--r-- | src/shared/sha1.c | 189 | ||||
-rw-r--r-- | src/shared/sha1.h | 33 | ||||
-rwxr-xr-x[-rw-r--r--] | src/shared/util.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/shared/util.h | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/stats.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/storage.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/task.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/technology.c | 47 | ||||
-rwxr-xr-x[-rw-r--r--] | src/tethering.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/timeserver.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/timezone.c | 0 | ||||
-rwxr-xr-x | src/util.c | 88 | ||||
-rwxr-xr-x[-rw-r--r--] | src/utsname.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/wispr.c | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | src/wpad.c | 0 |
66 files changed, 1579 insertions, 900 deletions
diff --git a/src/6to4.c b/src/6to4.c index 0e3a7a15..0e3a7a15 100644..100755 --- a/src/6to4.c +++ b/src/6to4.c diff --git a/src/agent-connman.c b/src/agent-connman.c index b2049a3d..d9502a7a 100644..100755 --- a/src/agent-connman.c +++ b/src/agent-connman.c @@ -79,8 +79,10 @@ static void request_input_passphrase_reply(DBusMessage *reply, void *user_data) int name_len = 0; DBusMessageIter iter, dict; - if (!reply) - goto out; + if (!reply) { + error = CONNMAN_ERROR_INTERFACE ".OperationAborted"; + goto done; + } if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { error = dbus_message_get_error_name(reply); @@ -138,10 +140,24 @@ static void request_input_passphrase_reply(DBusMessage *reply, void *user_data) dbus_message_iter_get_basic(&value, &name); name_len = strlen(name); } else if (g_str_equal(key, "SSID")) { +#if defined TIZEN_EXT + DBusMessageIter array; +#endif dbus_message_iter_next(&entry); if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT) break; +#if defined TIZEN_EXT + dbus_message_iter_recurse(&entry, &array); + if (dbus_message_iter_get_arg_type(&array) + != DBUS_TYPE_ARRAY) + break; + dbus_message_iter_recurse(&array, &value); + if (dbus_message_iter_get_arg_type(&value) + != DBUS_TYPE_BYTE) + break; +#else + dbus_message_iter_recurse(&entry, &value); if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_VARIANT) @@ -149,6 +165,7 @@ static void request_input_passphrase_reply(DBusMessage *reply, void *user_data) if (dbus_message_iter_get_element_type(&value) != DBUS_TYPE_VARIANT) break; +#endif dbus_message_iter_get_fixed_array(&value, &name, &name_len); } @@ -160,7 +177,7 @@ done: values_received, name, name_len, identity, passphrase, wps, wpspin, error, passphrase_reply->user_data); -out: + g_free(passphrase_reply); } @@ -365,8 +382,10 @@ static void request_input_login_reply(DBusMessage *reply, void *user_data) char *key; DBusMessageIter iter, dict; - if (!reply) - goto out; + if (!reply) { + error = CONNMAN_ERROR_INTERFACE ".OperationAborted"; + goto done; + } if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { error = dbus_message_get_error_name(reply); @@ -414,7 +433,7 @@ done: username_password_reply->service, values_received, NULL, 0, username, password, FALSE, NULL, error, username_password_reply->user_data); -out: + g_free(username_password_reply); } @@ -582,6 +601,11 @@ static void request_browser_reply(DBusMessage *reply, void *user_data) bool result = false; const char *error = NULL; + if (!reply) { + error = CONNMAN_ERROR_INTERFACE ".OperationAborted"; + goto done; + } + if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { error = dbus_message_get_error_name(reply); goto done; @@ -674,8 +698,10 @@ static void request_peer_authorization_reply(DBusMessage *reply, char *wpspin = NULL; char *key; - if (!reply) - goto out; + if (!reply) { + error = CONNMAN_ERROR_INTERFACE ".OperationAborted"; + goto done; + } if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { error = dbus_message_get_error_name(reply); @@ -716,7 +742,7 @@ static void request_peer_authorization_reply(DBusMessage *reply, done: auth_reply->peer_callback(auth_reply->peer, choice_done, wpspin, error, auth_reply->user_data); -out: + g_free(auth_reply); } diff --git a/src/agent.c b/src/agent.c index a3400262..bdeb0e71 100644..100755 --- a/src/agent.c +++ b/src/agent.c @@ -502,7 +502,7 @@ void connman_agent_cancel(void *user_context) g_hash_table_iter_init(&iter, agent_hash); while (g_hash_table_iter_next(&iter, &key, &value)) { - GList *list; + GList *list, *next; struct connman_agent *agent = value; /* @@ -512,6 +512,8 @@ void connman_agent_cancel(void *user_context) while (list) { struct connman_agent_request *request = list->data; + next = list->next; + if (request && request->user_context && request->user_context == user_context) { @@ -521,10 +523,11 @@ void connman_agent_cancel(void *user_context) agent_request_free(request); - agent->queue = list->next; - list = g_list_delete_link(list, list); - } else - list = list->next; + agent->queue = g_list_delete_link(agent->queue, + list); + } + + list = next; } /* diff --git a/src/bridge.c b/src/bridge.c index ba200969..ba200969 100644..100755 --- a/src/bridge.c +++ b/src/bridge.c diff --git a/src/clock.c b/src/clock.c index 0fde2c34..0fde2c34 100644..100755 --- a/src/clock.c +++ b/src/clock.c diff --git a/src/config.c b/src/config.c index 61cf8aeb..8ae1764d 100644..100755 --- a/src/config.c +++ b/src/config.c @@ -891,7 +891,7 @@ static void config_notify_handler(struct inotify_event *event, return; } - if (event->mask & IN_CREATE) + if (event->mask & IN_CREATE || event->mask & IN_MOVED_TO) create_config(ident); if (event->mask & IN_MODIFY) { @@ -1430,12 +1430,14 @@ static void generate_random_string(char *str, int length) { uint8_t val; int i; + uint64_t rand; memset(str, '\0', length); for (i = 0; i < length-1; i++) { do { - val = (uint8_t)(random() % 122); + __connman_util_get_random(&rand); + val = (uint8_t)(rand % 122); if (val < 48) val += 48; } while((val > 57 && val < 65) || (val > 90 && val < 97)); diff --git a/src/connection.c b/src/connection.c index 8fe97258..aa4e1c05 100644..100755 --- a/src/connection.c +++ b/src/connection.c @@ -401,13 +401,9 @@ static struct gateway_data *add_gateway(struct connman_service *service, data->ipv4_gateway = old->ipv4_gateway; old->ipv4_gateway = NULL; } - } else { - /* - * Only take a ref if we are adding new stuff to hash. - */ - connman_service_ref(service); } + connman_service_ref(data->service); g_hash_table_replace(gateway_hash, service, data); return data; @@ -708,6 +704,8 @@ static void remove_gateway(gpointer user_data) g_free(data->ipv6_gateway); } + connman_service_unref(data->service); + g_free(data); } @@ -999,9 +997,7 @@ void __connman_connection_gateway_remove(struct connman_service *service, (data->ipv4_gateway && !data->ipv6_gateway && do_ipv4) || (data->ipv6_gateway && !data->ipv4_gateway - && do_ipv6) - ) { - connman_service_unref(service); + && do_ipv6)) { g_hash_table_remove(gateway_hash, service); } else DBG("Not yet removing gw ipv4 %p/%d ipv6 %p/%d", diff --git a/src/connman-dbus.conf b/src/connman-dbus.conf index 98a773ea..98a773ea 100644..100755 --- a/src/connman-dbus.conf +++ b/src/connman-dbus.conf diff --git a/src/connman-polkit.conf b/src/connman-polkit.conf index b13d339b..b13d339b 100644..100755 --- a/src/connman-polkit.conf +++ b/src/connman-polkit.conf diff --git a/src/connman.h b/src/connman.h index 9c621163..c39210b4 100644..100755 --- a/src/connman.h +++ b/src/connman.h @@ -338,7 +338,7 @@ void __connman_ipconfig_newlink(int index, unsigned short type, unsigned short mtu, struct rtnl_link_stats *stats); void __connman_ipconfig_dellink(int index, struct rtnl_link_stats *stats); -void __connman_ipconfig_newaddr(int index, int family, const char *label, +int __connman_ipconfig_newaddr(int index, int family, const char *label, unsigned char prefixlen, const char *address); void __connman_ipconfig_deladdr(int index, int family, const char *label, unsigned char prefixlen, const char *address); @@ -459,6 +459,7 @@ typedef void (* dhcpv6_cb) (struct connman_network *network, typedef void (* dhcp_cb) (struct connman_ipconfig *ipconfig, struct connman_network *opt_network, bool success, gpointer data); +char *__connman_dhcp_get_server_address(struct connman_ipconfig *ipconfig); int __connman_dhcp_start(struct connman_ipconfig *ipconfig, struct connman_network *network, dhcp_cb callback, gpointer user_data); @@ -582,6 +583,11 @@ int __connman_rfkill_init(void); void __connman_rfkill_cleanup(void); int __connman_rfkill_block(enum connman_service_type type, bool block); +#if defined TIZEN_EXT +char *index2ident(int index, const char *prefix); +char *index2addr(int index); +#endif + #include <connman/network.h> int __connman_network_init(void); @@ -594,9 +600,8 @@ int __connman_network_connect(struct connman_network *network); int __connman_network_disconnect(struct connman_network *network); int __connman_network_clear_ipconfig(struct connman_network *network, struct connman_ipconfig *ipconfig); -int __connman_network_set_ipconfig(struct connman_network *network, - struct connman_ipconfig *ipconfig_ipv4, - struct connman_ipconfig *ipconfig_ipv6); +int __connman_network_enable_ipconfig(struct connman_network *network, + struct connman_ipconfig *ipconfig); const char *__connman_network_get_type(struct connman_network *network); const char *__connman_network_get_group(struct connman_network *network); @@ -707,8 +712,6 @@ int __connman_service_set_ignore(struct connman_service *service, bool ignore); void __connman_service_set_search_domains(struct connman_service *service, char **domains); -void __connman_service_update_search_domains(struct connman_service *service, - char **domains); void __connman_service_set_string(struct connman_service *service, const char *key, const char *value); @@ -953,7 +956,6 @@ int __connman_dnsproxy_add_listener(int index); void __connman_dnsproxy_remove_listener(int index); int __connman_dnsproxy_append(int index, const char *domain, const char *server); int __connman_dnsproxy_remove(int index, const char *domain, const char *server); -void __connman_dnsproxy_flush(void); int __connman_6to4_probe(struct connman_service *service); void __connman_6to4_remove(struct connman_ipconfig *ipconfig); @@ -1058,3 +1060,7 @@ void __connman_nfacct_cleanup(void); int __connman_machine_init(void); void __connman_machine_cleanup(void); + +int __connman_util_get_random(uint64_t *val); +int __connman_util_init(void); +void __connman_util_cleanup(void); diff --git a/src/connman.service.in b/src/connman.service.in index 67d051d7..c079054c 100644..100755 --- a/src/connman.service.in +++ b/src/connman.service.in @@ -1,15 +1,12 @@ [Unit] Description=Connection service -Requires=dbus.socket -After=dbus.socket -Before=remote-fs.target +After=tizen-system.target shutdown.target [Service] -EnvironmentFile=-/etc/sysconfig/connman Type=dbus BusName=net.connman Restart=on-failure -ExecStart=@prefix@/sbin/connmand -n $OPTIONS +ExecStart=@sbindir@/connmand -n StandardOutput=null [Install] diff --git a/src/connman_tv.service.in b/src/connman_tv.service.in new file mode 100644 index 00000000..43dea2ce --- /dev/null +++ b/src/connman_tv.service.in @@ -0,0 +1,12 @@ +[Unit] +Description=Connection service + +[Service] +Type=dbus +BusName=net.connman +RemainAfterExit=yes +ExecStartPre=/usr/bin/dbus-send --system --dest=net.netconfig / net.netconfig.auto.activate +ExecStart=/usr/sbin/connmand + +[Install] +WantedBy=multi-user.target diff --git a/src/counter.c b/src/counter.c index 06e5daff..8ea6205b 100644..100755 --- a/src/counter.c +++ b/src/counter.c @@ -133,8 +133,11 @@ void __connman_counter_send_usage(const char *path, struct connman_counter *counter; counter = g_hash_table_lookup(counter_table, path); - if (!counter) + if (!counter) { + if (message) + dbus_message_unref(message); return; + } dbus_message_set_destination(message, counter->owner); dbus_message_set_path(message, counter->path); diff --git a/src/dbus.c b/src/dbus.c index 260cec69..71728300 100644..100755 --- a/src/dbus.c +++ b/src/dbus.c @@ -528,6 +528,9 @@ int connman_dbus_get_connection_unix_user_sync(DBusConnection *connection, const char *bus_name, unsigned int *user_id) { +#if defined TIZEN_EXT + *user_id = 0; +#else unsigned long uid; DBusError err; @@ -545,6 +548,7 @@ int connman_dbus_get_connection_unix_user_sync(DBusConnection *connection, } *user_id = (unsigned int)uid; +#endif return 0; } diff --git a/src/detect.c b/src/detect.c index 6c039206..7f20870c 100644..100755 --- a/src/detect.c +++ b/src/detect.c @@ -67,8 +67,15 @@ static void detect_newlink(unsigned short type, int index, } device = find_device(index); +#if defined TIZEN_EXT + if (device) { + connman_inet_update_device_ident(device); + return; + } +#else if (device) return; +#endif device = connman_device_create_from_index(index); if (!device) diff --git a/src/device.c b/src/device.c index c0683abd..4d2d5403 100644..100755 --- a/src/device.c +++ b/src/device.c @@ -1143,7 +1143,11 @@ int __connman_device_request_hidden_scan(struct connman_device *device, passphrase, security, user_data); } +#if defined TIZEN_EXT +char *index2ident(int index, const char *prefix) +#else static char *index2ident(int index, const char *prefix) +#endif { struct ifreq ifr; struct ether_addr eth; @@ -1189,7 +1193,11 @@ static char *index2ident(int index, const char *prefix) return str; } +#if defined TIZEN_EXT +char *index2addr(int index) +#else static char *index2addr(int index) +#endif { struct ifreq ifr; struct ether_addr eth; diff --git a/src/dhcp.c b/src/dhcp.c index 505d9f06..9a743626 100644..100755 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -399,7 +399,8 @@ static bool apply_lease_available_on_network(GDHCPClient *dhcp_client, dhcp->pac); } - __connman_6to4_probe(service); + if (connman_setting_get_bool("Enable6to4")) + __connman_6to4_probe(service); return true; } @@ -582,6 +583,17 @@ static int dhcp_release(struct connman_dhcp *dhcp) return 0; } +char *__connman_dhcp_get_server_address(struct connman_ipconfig *ipconfig) +{ + struct connman_dhcp *dhcp; + + dhcp = g_hash_table_lookup(ipconfig_table, ipconfig); + if (!dhcp) + return NULL; + + return g_dhcp_client_get_server_address(dhcp->dhcp_client); +} + int __connman_dhcp_start(struct connman_ipconfig *ipconfig, struct connman_network *network, dhcp_cb callback, gpointer user_data) @@ -672,4 +684,6 @@ void __connman_dhcp_cleanup(void) g_hash_table_destroy(ipconfig_table); ipconfig_table = NULL; + + dhcp_cleanup_random(); } diff --git a/src/dhcpv6.c b/src/dhcpv6.c index 5f8029f1..db9feb60 100644..100755 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -105,25 +105,37 @@ static void clear_timer(struct connman_dhcpv6 *dhcp) } } -static inline float get_random(void) +static inline guint get_random(void) { - return (rand() % 200 - 100) / 1000.0; + uint64_t val; + + __connman_util_get_random(&val); + + /* Make sure the value is always positive so strip MSB */ + return ((uint32_t)val) >> 1; +} + +static guint compute_random(guint val) +{ + return val - val / 10 + + (get_random() % (2 * 1000)) * val / 10 / 1000; } /* Calculate a random delay, RFC 3315 chapter 14 */ /* RT and MRT are milliseconds */ static guint calc_delay(guint RT, guint MRT) { - float delay = get_random(); - float rt = RT * (2 + delay); + if (MRT && (RT > MRT / 2)) + RT = compute_random(MRT); + else + RT += compute_random(RT); - if (rt > MRT) - rt = MRT * (1 + delay); - - if (rt < 0) - rt = MRT; + return RT; +} - return (guint)rt; +static guint initial_rt(guint timeout) +{ + return compute_random(timeout); } static void free_prefix(gpointer data) @@ -493,7 +505,7 @@ static int set_other_addresses(GDHCPClient *dhcp_client, for (i = 0, list = option; list; list = list->next, i++) domains[i] = g_strdup(list->data); - __connman_service_update_search_domains(service, domains); + __connman_service_set_search_domains(service, domains); g_strfreev(domains); } } @@ -1095,7 +1107,7 @@ static void re_cb(enum request_type req_type, GDHCPClient *dhcp_client, if (!option) { switch (req_type) { case REQ_REQUEST: - dhcpv6_request(dhcp, true); + do_resend_request(dhcp); break; case REQ_REBIND: dhcpv6_rebind(dhcp); @@ -1220,7 +1232,7 @@ static gboolean start_rebind(gpointer user_data) if (check_restart(dhcp) < 0) return FALSE; - dhcp->RT = REB_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(REB_TIMEOUT); DBG("rebind initial RT timeout %d msec", dhcp->RT); @@ -1387,7 +1399,7 @@ static gboolean start_renew(gpointer user_data) { struct connman_dhcpv6 *dhcp = user_data; - dhcp->RT = REN_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(REN_TIMEOUT); DBG("renew initial RT timeout %d msec", dhcp->RT); @@ -1585,7 +1597,7 @@ static gboolean start_info_req(gpointer user_data) struct connman_dhcpv6 *dhcp = user_data; /* Set the retransmission timeout, RFC 3315 chapter 14 */ - dhcp->RT = INF_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(INF_TIMEOUT); DBG("info initial RT timeout %d msec", dhcp->RT); @@ -1601,6 +1613,7 @@ int __connman_dhcpv6_start_info(struct connman_network *network, { struct connman_dhcpv6 *dhcp; int delay; + uint64_t rand; DBG(""); @@ -1626,7 +1639,8 @@ int __connman_dhcpv6_start_info(struct connman_network *network, g_hash_table_replace(network_table, network, dhcp); /* Initial timeout, RFC 3315, 18.1.5 */ - delay = rand() % 1000; + __connman_util_get_random(&rand); + delay = rand % 1000; dhcp->timeout = g_timeout_add(delay, start_info_req, dhcp); @@ -1650,7 +1664,7 @@ static void advertise_cb(GDHCPClient *dhcp_client, gpointer user_data) return; } - dhcp->RT = REQ_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(REQ_TIMEOUT); DBG("request initial RT timeout %d msec", dhcp->RT); dhcp->timeout = g_timeout_add(dhcp->RT, timeout_request, dhcp); @@ -1668,9 +1682,16 @@ static void solicitation_cb(GDHCPClient *dhcp_client, gpointer user_data) clear_timer(dhcp); - do_dad(dhcp_client, dhcp); - g_dhcpv6_client_clear_retransmit(dhcp_client); + + if (g_dhcpv6_client_get_status(dhcp_client) != 0) { + if (dhcp->callback) + dhcp->callback(dhcp->network, + CONNMAN_DHCPV6_STATUS_FAIL, NULL); + return; + } + + do_dad(dhcp_client, dhcp); } static gboolean timeout_solicitation(gpointer user_data) @@ -1761,7 +1782,7 @@ static gboolean start_solicitation(gpointer user_data) struct connman_dhcpv6 *dhcp = user_data; /* Set the retransmission timeout, RFC 3315 chapter 14 */ - dhcp->RT = SOL_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(SOL_TIMEOUT); DBG("solicit initial RT timeout %d msec", dhcp->RT); @@ -1778,6 +1799,7 @@ int __connman_dhcpv6_start(struct connman_network *network, struct connman_service *service; struct connman_dhcpv6 *dhcp; int delay; + uint64_t rand; DBG(""); @@ -1807,7 +1829,8 @@ int __connman_dhcpv6_start(struct connman_network *network, g_hash_table_replace(network_table, network, dhcp); /* Initial timeout, RFC 3315, 17.1.2 */ - delay = rand() % 1000; + __connman_util_get_random(&rand); + delay = rand % 1000; /* * Start from scratch. @@ -2171,7 +2194,7 @@ static gboolean start_pd_rebind(gpointer user_data) if (check_pd_restart(dhcp) < 0) return FALSE; - dhcp->RT = REB_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(REB_TIMEOUT); DBG("rebind initial RT timeout %d msec", dhcp->RT); @@ -2223,7 +2246,7 @@ static gboolean start_pd_rebind_with_confirm(gpointer user_data) { struct connman_dhcpv6 *dhcp = user_data; - dhcp->RT = CNF_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(CNF_TIMEOUT); DBG("rebind with confirm initial RT timeout %d msec", dhcp->RT); @@ -2260,7 +2283,7 @@ static gboolean start_pd_renew(gpointer user_data) { struct connman_dhcpv6 *dhcp = user_data; - dhcp->RT = REN_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(REN_TIMEOUT); DBG("renew initial RT timeout %d msec", dhcp->RT); @@ -2476,7 +2499,7 @@ static void advertise_pd_cb(GDHCPClient *dhcp_client, gpointer user_data) return; } - dhcp->RT = REQ_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(REQ_TIMEOUT); DBG("request initial RT timeout %d msec", dhcp->RT); dhcp->timeout = g_timeout_add(dhcp->RT, timeout_pd_request, dhcp); @@ -2531,7 +2554,7 @@ static gboolean start_pd_solicitation(gpointer user_data) struct connman_dhcpv6 *dhcp = user_data; /* Set the retransmission timeout, RFC 3315 chapter 14 */ - dhcp->RT = SOL_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(SOL_TIMEOUT); DBG("solicit initial RT timeout %d msec", dhcp->RT); @@ -2640,8 +2663,6 @@ int __connman_dhcpv6_init(void) { DBG(""); - srand(time(NULL)); - network_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, remove_network); diff --git a/src/dnsproxy.c b/src/dnsproxy.c index d1752a7c..185d6f17 100644..100755 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -41,6 +41,10 @@ #include "connman.h" +#if defined TIZEN_EXT +#include <sys/smack.h> +#endif + #if __BYTE_ORDER == __LITTLE_ENDIAN struct domain_hdr { uint16_t id; @@ -233,7 +237,11 @@ static struct server_data *create_server_sec(int index, static guint16 get_id(void) { - return random(); + uint64_t rand; + + __connman_util_get_random(&rand); + + return rand; } static int protocol_offset(int protocol) @@ -541,6 +549,8 @@ static void destroy_request_data(struct request_data *req) static gboolean request_timeout(gpointer user_data) { struct request_data *req = user_data; + struct sockaddr *sa; + int sk; if (!req) return FALSE; @@ -548,47 +558,38 @@ static gboolean request_timeout(gpointer user_data) DBG("id 0x%04x", req->srcid); request_list = g_slist_remove(request_list, req); - req->numserv--; - if (req->resplen > 0 && req->resp) { - int sk, err; + if (req->protocol == IPPROTO_UDP) { + sk = get_req_udp_socket(req); + sa = &req->sa; + } else if (req->protocol == IPPROTO_TCP) { + sk = req->client_sk; + sa = NULL; + } else + goto out; - if (req->protocol == IPPROTO_UDP) { - sk = get_req_udp_socket(req); - if (sk < 0) - return FALSE; + if (req->resplen > 0 && req->resp) { + /* + * Here we have received at least one reply (probably telling + * "not found" result), so send that back to client instead + * of more fatal server failed error. + */ + if (sk >= 0) + sendto(sk, req->resp, req->resplen, MSG_NOSIGNAL, + sa, req->sa_len); - err = sendto(sk, req->resp, req->resplen, MSG_NOSIGNAL, - &req->sa, req->sa_len); - } else { - sk = req->client_sk; - err = send(sk, req->resp, req->resplen, MSG_NOSIGNAL); - if (err < 0) - close(sk); - } - if (err < 0) - return FALSE; - } else if (req->request && req->numserv == 0) { + } else if (req->request) { + /* + * There was not reply from server at all. + */ struct domain_hdr *hdr; - if (req->protocol == IPPROTO_TCP) { - hdr = (void *) (req->request + 2); - hdr->id = req->srcid; - send_response(req->client_sk, req->request, - req->request_len, NULL, 0, IPPROTO_TCP); - - } else if (req->protocol == IPPROTO_UDP) { - int sk; - - hdr = (void *) (req->request); - hdr->id = req->srcid; + hdr = (void *)(req->request + protocol_offset(req->protocol)); + hdr->id = req->srcid; - sk = get_req_udp_socket(req); - if (sk >= 0) - send_response(sk, req->request, - req->request_len, &req->sa, - req->sa_len, IPPROTO_UDP); - } + if (sk >= 0) + send_response(sk, req->request, req->request_len, + sa, req->sa_len, req->protocol); } /* @@ -601,6 +602,7 @@ static gboolean request_timeout(gpointer user_data) GINT_TO_POINTER(req->client_sk)); } +out: req->timeout = 0; destroy_request_data(req); @@ -779,6 +781,8 @@ static void cache_element_destroy(gpointer value) static gboolean try_remove_cache(gpointer user_data) { + cache_timer = 0; + if (__sync_fetch_and_sub(&cache_refcount, 1) == 1) { DBG("No cache users, removing it."); @@ -2244,8 +2248,8 @@ static void destroy_server(struct server_data *server) * without any good reason. The small delay allows the new RDNSS to * create a new DNS server instance and the refcount does not go to 0. */ - if (cache) - g_timeout_add_seconds(3, try_remove_cache, NULL); + if (cache && !cache_timer) + cache_timer = g_timeout_add_seconds(3, try_remove_cache, NULL); g_free(server); } @@ -2902,6 +2906,34 @@ static void append_domain(int index, const char *domain) } } +static void flush_requests(struct server_data *server) +{ + GSList *list; + + list = request_list; + while (list) { + struct request_data *req = list->data; + + list = list->next; + + if (ns_resolv(server, req, req->request, req->name)) { + /* + * A cached result was sent, + * so the request can be released + */ + request_list = + g_slist_remove(request_list, req); + destroy_request_data(req); + continue; + } + + if (req->timeout > 0) + g_source_remove(req->timeout); + + req->timeout = g_timeout_add_seconds(5, request_timeout, req); + } +} + int __connman_dnsproxy_append(int index, const char *domain, const char *server) { @@ -2934,6 +2966,8 @@ int __connman_dnsproxy_append(int index, const char *domain, if (!data) return -EIO; + flush_requests(data); + return 0; } @@ -2973,33 +3007,6 @@ int __connman_dnsproxy_remove(int index, const char *domain, return 0; } -void __connman_dnsproxy_flush(void) -{ - GSList *list; - - list = request_list; - while (list) { - struct request_data *req = list->data; - - list = list->next; - - if (resolv(req, req->request, req->name)) { - /* - * A cached result was sent, - * so the request can be released - */ - request_list = - g_slist_remove(request_list, req); - destroy_request_data(req); - continue; - } - - if (req->timeout > 0) - g_source_remove(req->timeout); - req->timeout = g_timeout_add_seconds(5, request_timeout, req); - } -} - static void dnsproxy_offline_mode(bool enabled) { GSList *list; @@ -3911,6 +3918,13 @@ static GIOChannel *get_listener(int family, int protocol, int index) } #if defined TIZEN_EXT + if (smack_fsetlabel(sk, "system::use_internet", SMACK_LABEL_IPOUT) != 0) + connman_error("Failed to label system::use_internet"); + + if (smack_fsetlabel(sk, "system::use_internet", SMACK_LABEL_IPIN) != 0) + connman_error("Failed to label system::use_internet"); +#endif +#if defined TIZEN_EXT /* When ConnMan crashed, * probably DNS listener cannot bind existing address */ option = 1; @@ -4200,8 +4214,6 @@ int __connman_dnsproxy_init(void) DBG(""); - srandom(time(NULL)); - listener_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); @@ -4233,6 +4245,16 @@ void __connman_dnsproxy_cleanup(void) { DBG(""); + if (cache_timer) { + g_source_remove(cache_timer); + cache_timer = 0; + } + + if (cache) { + g_hash_table_destroy(cache); + cache = NULL; + } + connman_notifier_unregister(&dnsproxy_notifier); g_hash_table_foreach(listener_table, remove_listener, NULL); diff --git a/src/eduroam.config b/src/eduroam.config index 768b7b40..768b7b40 100644..100755 --- a/src/eduroam.config +++ b/src/eduroam.config diff --git a/src/error.c b/src/error.c index 4f24ae25..4f24ae25 100644..100755 --- a/src/error.c +++ b/src/error.c diff --git a/src/firewall.c b/src/firewall.c index 90c3d3c1..90c3d3c1 100644..100755 --- a/src/firewall.c +++ b/src/firewall.c diff --git a/src/inet.c b/src/inet.c index cd220ffc..bfad01cb 100644..100755 --- a/src/inet.c +++ b/src/inet.c @@ -330,6 +330,62 @@ done: return err; } +#if defined TIZEN_EXT +void connman_inet_update_device_ident(struct connman_device *device) +{ + int index; + enum connman_device_type type; + char *ident = NULL, *addr = NULL; + + index = connman_device_get_index(device); + type = connman_device_get_type(device); + + switch (type) { + case CONNMAN_DEVICE_TYPE_UNKNOWN: + return; + case CONNMAN_DEVICE_TYPE_ETHERNET: + case CONNMAN_DEVICE_TYPE_GADGET: + case CONNMAN_DEVICE_TYPE_WIFI: + addr = index2addr(index); + break; + case CONNMAN_DEVICE_TYPE_BLUETOOTH: + case CONNMAN_DEVICE_TYPE_CELLULAR: + case CONNMAN_DEVICE_TYPE_GPS: + case CONNMAN_DEVICE_TYPE_VENDOR: + break; + } + + switch (type) { + case CONNMAN_DEVICE_TYPE_UNKNOWN: + case CONNMAN_DEVICE_TYPE_VENDOR: + case CONNMAN_DEVICE_TYPE_GPS: + break; + case CONNMAN_DEVICE_TYPE_ETHERNET: + case CONNMAN_DEVICE_TYPE_GADGET: + ident = index2ident(index, NULL); + break; + case CONNMAN_DEVICE_TYPE_WIFI: + ident = index2ident(index, NULL); + break; + case CONNMAN_DEVICE_TYPE_BLUETOOTH: + break; + case CONNMAN_DEVICE_TYPE_CELLULAR: + ident = index2ident(index, NULL); + break; + } + + if (ident != NULL) { + connman_device_set_ident(device, ident); + g_free(ident); + } + + if (addr != NULL) { + connman_device_set_string(device, "Address", addr); + g_free(addr); + } +} +#endif + struct in6_ifreq { struct in6_addr ifr6_addr; __u32 ifr6_prefixlen; @@ -2229,10 +2285,8 @@ static int inet_rtnl_recv(GIOChannel *chan, gpointer user_data) h = ptr; - if (!NLMSG_OK(h, len)) { + if (!NLMSG_OK(h, len)) return -1; - break; - } if (h->nlmsg_seq != rth->seq) { /* Skip this msg */ diff --git a/src/inotify.c b/src/inotify.c index 1ab3807c..c251c6ff 100644..100755 --- a/src/inotify.c +++ b/src/inotify.c @@ -35,6 +35,8 @@ #include "connman.h" struct connman_inotify { + unsigned int refcount; + GIOChannel *channel; uint watch; int wd; @@ -42,13 +44,30 @@ struct connman_inotify { GSList *list; }; +static void cleanup_inotify(gpointer user_data); + +static void connman_inotify_ref(struct connman_inotify *i) +{ + __sync_fetch_and_add(&i->refcount, 1); +} + +static void connman_inotify_unref(gpointer data) +{ + struct connman_inotify *i = data; + + if (__sync_fetch_and_sub(&i->refcount, 1) != 1) + return; + + cleanup_inotify(data); +} + static GHashTable *inotify_hash; static gboolean inotify_data(GIOChannel *channel, GIOCondition cond, gpointer user_data) { struct connman_inotify *inotify = user_data; - char buffer[256]; + char buffer[sizeof(struct inotify_event) + NAME_MAX + 1]; char *next_event; gsize bytes_read; GIOStatus status; @@ -60,7 +79,7 @@ static gboolean inotify_data(GIOChannel *channel, GIOCondition cond, } status = g_io_channel_read_chars(channel, buffer, - sizeof(buffer) -1, &bytes_read, NULL); + sizeof(buffer), &bytes_read, NULL); switch (status) { case G_IO_STATUS_NORMAL: @@ -75,6 +94,8 @@ static gboolean inotify_data(GIOChannel *channel, GIOCondition cond, next_event = buffer; + connman_inotify_ref(inotify); + while (bytes_read > 0) { struct inotify_event *event; gchar *ident; @@ -102,6 +123,8 @@ static gboolean inotify_data(GIOChannel *channel, GIOCondition cond, } } + connman_inotify_unref(inotify); + return TRUE; } @@ -179,6 +202,7 @@ int connman_inotify_register(const char *path, inotify_event_cb callback) if (!inotify) return -ENOMEM; + inotify->refcount = 1; inotify->wd = -1; err = create_watch(path, inotify); @@ -225,7 +249,7 @@ int __connman_inotify_init(void) DBG(""); inotify_hash = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, cleanup_inotify); + g_free, connman_inotify_unref); return 0; } diff --git a/src/ipaddress.c b/src/ipaddress.c index d63d95c3..d63d95c3 100644..100755 --- a/src/ipaddress.c +++ b/src/ipaddress.c diff --git a/src/ipconfig.c b/src/ipconfig.c index 29c5a3de..5d6da915 100644..100755 --- a/src/ipconfig.c +++ b/src/ipconfig.c @@ -45,8 +45,6 @@ struct connman_ipconfig { int index; enum connman_ipconfig_type type; - struct connman_ipconfig *origin; - const struct connman_ipconfig_ops *ops; void *ops_data; @@ -135,6 +133,7 @@ const char *__connman_ipconfig_type2string(enum connman_ipconfig_type type) { switch (type) { case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + case CONNMAN_IPCONFIG_TYPE_ALL: return "unknown"; case CONNMAN_IPCONFIG_TYPE_IPV4: return "IPv4"; @@ -445,12 +444,9 @@ static void update_stats(struct connman_ipdevice *ipdevice, if (!ipdevice->config_ipv4 && !ipdevice->config_ipv6) return; - if (ipdevice->config_ipv4) - service = __connman_ipconfig_get_data(ipdevice->config_ipv4); - else if (ipdevice->config_ipv6) - service = __connman_ipconfig_get_data(ipdevice->config_ipv6); - else - return; + service = __connman_service_lookup_from_index(ipdevice->index); + + DBG("service %p", service); if (!service) return; @@ -512,6 +508,16 @@ void __connman_ipconfig_newlink(int index, unsigned short type, index, type, type2str(type)); update: +#if defined TIZEN_EXT + if (g_strcmp0(ipdevice->address, address) != 0) { + /* If an original address is built-in physical device, + * it's hardly get an address at a initial creation + */ + g_free(ipdevice->address); + ipdevice->address = g_strdup(address); + } +#endif + ipdevice->mtu = mtu; update_stats(ipdevice, ifname, stats); @@ -642,7 +648,7 @@ static inline gint check_duplicate_address(gconstpointer a, gconstpointer b) return g_strcmp0(addr1->local, addr2->local); } -void __connman_ipconfig_newaddr(int index, int family, const char *label, +int __connman_ipconfig_newaddr(int index, int family, const char *label, unsigned char prefixlen, const char *address) { struct connman_ipdevice *ipdevice; @@ -655,11 +661,11 @@ void __connman_ipconfig_newaddr(int index, int family, const char *label, ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index)); if (!ipdevice) - return; + return -ENXIO; ipaddress = connman_ipaddress_alloc(family); if (!ipaddress) - return; + return -ENOMEM; ipaddress->prefixlen = prefixlen; ipaddress->local = g_strdup(address); @@ -667,7 +673,7 @@ void __connman_ipconfig_newaddr(int index, int family, const char *label, if (g_slist_find_custom(ipdevice->address_list, ipaddress, check_duplicate_address)) { connman_ipaddress_free(ipaddress); - return; + return -EALREADY; } if (family == AF_INET) @@ -675,7 +681,7 @@ void __connman_ipconfig_newaddr(int index, int family, const char *label, else if (family == AF_INET6) type = CONNMAN_IPCONFIG_TYPE_IPV6; else - return; + return -EINVAL; ipdevice->address_list = g_slist_prepend(ipdevice->address_list, ipaddress); @@ -698,7 +704,7 @@ void __connman_ipconfig_newaddr(int index, int family, const char *label, goto out; if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) != (IFF_RUNNING | IFF_LOWER_UP)) - return; + goto out; for (list = g_list_first(ipconfig_list); list; list = g_list_next(list)) { @@ -719,6 +725,7 @@ void __connman_ipconfig_newaddr(int index, int family, const char *label, out: g_free(ifname); + return 0; } void __connman_ipconfig_deladdr(int index, int family, const char *label, @@ -1261,11 +1268,6 @@ void __connman_ipconfig_unref_debug(struct connman_ipconfig *ipconfig, __connman_ipconfig_set_ops(ipconfig, NULL); - if (ipconfig->origin && ipconfig->origin != ipconfig) { - __connman_ipconfig_unref(ipconfig->origin); - ipconfig->origin = NULL; - } - connman_ipaddress_free(ipconfig->system); connman_ipaddress_free(ipconfig->address); g_free(ipconfig->last_dhcp_address); @@ -1310,9 +1312,6 @@ int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig) if (!ipconfig) return -1; - if (ipconfig->origin) - return ipconfig->origin->index; - return ipconfig->index; } @@ -2136,6 +2135,7 @@ int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig, type = AF_INET6; break; case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + case CONNMAN_IPCONFIG_TYPE_ALL: type = -1; break; } @@ -2225,6 +2225,7 @@ int __connman_ipconfig_load(struct connman_ipconfig *ipconfig, ipconfig->method = CONNMAN_IPCONFIG_METHOD_AUTO; break; case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + case CONNMAN_IPCONFIG_TYPE_ALL: ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF; break; } @@ -2264,42 +2265,59 @@ int __connman_ipconfig_load(struct connman_ipconfig *ipconfig, g_free(method); g_free(key); - key = g_strdup_printf("%snetmask_prefixlen", prefix); - ipconfig->address->prefixlen = g_key_file_get_integer( + switch (ipconfig->method) { + case CONNMAN_IPCONFIG_METHOD_UNKNOWN: + case CONNMAN_IPCONFIG_METHOD_OFF: + break; + + case CONNMAN_IPCONFIG_METHOD_FIXED: + case CONNMAN_IPCONFIG_METHOD_MANUAL: + + key = g_strdup_printf("%snetmask_prefixlen", prefix); + ipconfig->address->prefixlen = g_key_file_get_integer( keyfile, identifier, key, NULL); - g_free(key); + g_free(key); - key = g_strdup_printf("%slocal_address", prefix); - g_free(ipconfig->address->local); - ipconfig->address->local = g_key_file_get_string( + key = g_strdup_printf("%slocal_address", prefix); + g_free(ipconfig->address->local); + ipconfig->address->local = g_key_file_get_string( keyfile, identifier, key, NULL); - g_free(key); + g_free(key); - key = g_strdup_printf("%speer_address", prefix); - g_free(ipconfig->address->peer); - ipconfig->address->peer = g_key_file_get_string( + key = g_strdup_printf("%speer_address", prefix); + g_free(ipconfig->address->peer); + ipconfig->address->peer = g_key_file_get_string( keyfile, identifier, key, NULL); - g_free(key); + g_free(key); - key = g_strdup_printf("%sbroadcast_address", prefix); - g_free(ipconfig->address->broadcast); - ipconfig->address->broadcast = g_key_file_get_string( + key = g_strdup_printf("%sbroadcast_address", prefix); + g_free(ipconfig->address->broadcast); + ipconfig->address->broadcast = g_key_file_get_string( keyfile, identifier, key, NULL); - g_free(key); + g_free(key); - key = g_strdup_printf("%sgateway", prefix); - g_free(ipconfig->address->gateway); - ipconfig->address->gateway = g_key_file_get_string( + key = g_strdup_printf("%sgateway", prefix); + g_free(ipconfig->address->gateway); + ipconfig->address->gateway = g_key_file_get_string( keyfile, identifier, key, NULL); - g_free(key); + g_free(key); + break; - key = g_strdup_printf("%sDHCP.LastAddress", prefix); - str = g_key_file_get_string(keyfile, identifier, key, NULL); - if (str) { - g_free(ipconfig->last_dhcp_address); - ipconfig->last_dhcp_address = str; + case CONNMAN_IPCONFIG_METHOD_DHCP: + + key = g_strdup_printf("%sDHCP.LastAddress", prefix); + str = g_key_file_get_string(keyfile, identifier, key, NULL); + if (str) { + g_free(ipconfig->last_dhcp_address); + ipconfig->last_dhcp_address = str; + } + g_free(key); + + break; + + case CONNMAN_IPCONFIG_METHOD_AUTO: + break; } - g_free(key); return 0; } diff --git a/src/ippool.c b/src/ippool.c index bb8568d9..bb8568d9 100644..100755 --- a/src/ippool.c +++ b/src/ippool.c diff --git a/src/iptables.c b/src/iptables.c index 8d583eae..8d583eae 100644..100755 --- a/src/iptables.c +++ b/src/iptables.c diff --git a/src/ipv6pd.c b/src/ipv6pd.c index 5ecda389..0d221f07 100644..100755 --- a/src/ipv6pd.c +++ b/src/ipv6pd.c @@ -165,8 +165,10 @@ static void cleanup(void) timer_uplink = 0; } - g_hash_table_destroy(timer_hash); - timer_hash = NULL; + if (timer_hash) { + g_hash_table_destroy(timer_hash); + timer_hash = NULL; + } if (prefixes) { g_slist_free_full(prefixes, g_free); diff --git a/src/log.c b/src/log.c index a693bd00..ead9b2e8 100644..100755 --- a/src/log.c +++ b/src/log.c @@ -38,6 +38,130 @@ static const char *program_exec; static const char *program_path; +#if defined TIZEN_EXT +#include <sys/stat.h> + +#define LOG_FILE_PATH "/opt/usr/data/network/connman.log" +#define MAX_LOG_SIZE 1 * 1024 * 1024 +#define MAX_LOG_COUNT 3 + +#define openlog __connman_log_open +#define closelog __connman_log_close +#define vsyslog __connman_log +#define syslog __connman_log_s + +static FILE *log_file = NULL; + +void __connman_log_open(const char *ident, int option, int facility) +{ + if (!log_file) + log_file = (FILE *)fopen(LOG_FILE_PATH, "a+"); +} + +void __connman_log_close(void) +{ + fclose(log_file); + log_file = NULL; +} + +static void __connman_log_update_file_revision(int rev) +{ + int next_log_rev = 0; + char *log_file = NULL; + char *next_log_file = NULL; + + next_log_rev = rev + 1; + + log_file = g_strdup_printf("%s.%d", LOG_FILE_PATH, rev); + next_log_file = g_strdup_printf("%s.%d", LOG_FILE_PATH, next_log_rev); + + if (next_log_rev >= MAX_LOG_COUNT) + remove(next_log_file); + + if (access(next_log_file, F_OK) == 0) + __connman_log_update_file_revision(next_log_rev); + + if (rename(log_file, next_log_file) != 0) + remove(log_file); + + g_free(log_file); + g_free(next_log_file); +} + +static void __connman_log_make_backup(void) +{ + const int rev = 0; + char *backup = NULL; + + backup = g_strdup_printf("%s.%d", LOG_FILE_PATH, rev); + + if (access(backup, F_OK) == 0) + __connman_log_update_file_revision(rev); + + if (rename(LOG_FILE_PATH, backup) != 0) + remove(LOG_FILE_PATH); + + g_free(backup); +} + +static void __connman_log_get_local_time(char *strtime, const int size) +{ + time_t buf; + struct tm *local_ptm; + + time(&buf); + buf = time(NULL); + local_ptm = localtime(&buf); + + strftime(strtime, size, "%m/%d %H:%M:%S", local_ptm); +} + +void __connman_log(const int log_priority, const char *format, va_list ap) +{ + int log_size = 0; + struct stat buf; + char str[256]; + char strtime[40]; + + if (!log_file) + log_file = (FILE *)fopen(LOG_FILE_PATH, "a+"); + + if (!log_file) + return; + + fstat(fileno(log_file), &buf); + log_size = buf.st_size; + + if (log_size >= MAX_LOG_SIZE) { + fclose(log_file); + log_file = NULL; + + __connman_log_make_backup(); + + log_file = (FILE *)fopen(LOG_FILE_PATH, "a+"); + + if (!log_file) + return; + } + + __connman_log_get_local_time(strtime, sizeof(strtime)); + + if (vsnprintf(str, sizeof(str), format, ap) > 0) + fprintf(log_file, "%s %s\n", strtime, str); +} + +void __connman_log_s(int log_priority, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + + vsyslog(LOG_DEBUG, format, ap); + + va_end(ap); +} +#endif + /** * connman_info: * @format: format string diff --git a/src/machine.c b/src/machine.c index 14ea3667..14ea3667 100644..100755 --- a/src/machine.c +++ b/src/machine.c diff --git a/src/main.c b/src/main.c index 21d1e06f..c594adb2 100644..100755 --- a/src/main.c +++ b/src/main.c @@ -73,6 +73,10 @@ static struct { bool single_tech; char **tethering_technologies; bool persistent_tethering_mode; + bool enable_6to4; +#if defined TIZEN_EXT + char **cellular_interfaces; +#endif } connman_settings = { .bg_scan = true, .pref_timeservers = NULL, @@ -86,6 +90,10 @@ static struct { .single_tech = false, .tethering_technologies = NULL, .persistent_tethering_mode = false, + .enable_6to4 = false, +#if defined TIZEN_EXT + .cellular_interfaces = NULL, +#endif }; #define CONF_BG_SCAN "BackgroundScanning" @@ -100,6 +108,10 @@ static struct { #define CONF_SINGLE_TECH "SingleConnectedTechnology" #define CONF_TETHERING_TECHNOLOGIES "TetheringTechnologies" #define CONF_PERSISTENT_TETHERING_MODE "PersistentTetheringMode" +#define CONF_ENABLE_6TO4 "Enable6to4" +#if defined TIZEN_EXT +#define CONF_CELLULAR_INTERFACE "NetworkCellularInterfaceList" +#endif static const char *supported_options[] = { CONF_BG_SCAN, @@ -114,6 +126,10 @@ static const char *supported_options[] = { CONF_SINGLE_TECH, CONF_TETHERING_TECHNOLOGIES, CONF_PERSISTENT_TETHERING_MODE, + CONF_ENABLE_6TO4, +#if defined TIZEN_EXT + CONF_CELLULAR_INTERFACE, +#endif NULL }; @@ -228,6 +244,23 @@ static void check_config(GKeyFile *config) g_strfreev(keys); } +#if defined TIZEN_EXT +static void check_Tizen_configuration(GKeyFile *config) +{ + GError *error = NULL; + char **cellular_interfaces; + gsize len; + + cellular_interfaces = g_key_file_get_string_list(config, "General", + CONF_CELLULAR_INTERFACE, &len, &error); + + if (error == NULL) + connman_settings.cellular_interfaces = cellular_interfaces; + + g_clear_error(&error); +} +#endif + static void parse_config(GKeyFile *config) { GError *error = NULL; @@ -354,6 +387,17 @@ static void parse_config(GKeyFile *config) connman_settings.persistent_tethering_mode = boolean; g_clear_error(&error); + + boolean = __connman_config_get_bool(config, "General", + CONF_ENABLE_6TO4, &error); + if (!error) + connman_settings.enable_6to4 = boolean; + + g_clear_error(&error); + +#if defined TIZEN_EXT + check_Tizen_configuration(config); +#endif } static int config_init(const char *file) @@ -528,6 +572,9 @@ bool connman_setting_get_bool(const char *key) if (g_str_equal(key, CONF_PERSISTENT_TETHERING_MODE)) return connman_settings.persistent_tethering_mode; + if (g_str_equal(key, CONF_ENABLE_6TO4)) + return connman_settings.enable_6to4; + return false; } @@ -545,6 +592,11 @@ char **connman_setting_get_string_list(const char *key) if (g_str_equal(key, CONF_TETHERING_TECHNOLOGIES)) return connman_settings.tethering_technologies; +#if defined TIZEN_EXT + if (g_str_equal(key, CONF_CELLULAR_INTERFACE)) + return connman_settings.cellular_interfaces; +#endif + return NULL; } @@ -639,6 +691,7 @@ int main(int argc, char *argv[]) else config_init(option_config); + __connman_util_init(); __connman_inotify_init(); __connman_technology_init(); __connman_notifier_init(); @@ -729,6 +782,7 @@ int main(int argc, char *argv[]) __connman_technology_cleanup(); __connman_inotify_cleanup(); + __connman_util_cleanup(); __connman_dbus_cleanup(); __connman_log_cleanup(option_backtrace); @@ -747,6 +801,7 @@ int main(int argc, char *argv[]) g_strfreev(connman_settings.tethering_technologies); g_free(option_debug); + g_free(option_wifi); return 0; } diff --git a/src/main.conf b/src/main.conf index c9795534..d0edbdf7 100644..100755 --- a/src/main.conf +++ b/src/main.conf @@ -27,7 +27,7 @@ BackgroundScanning = false # These can contain mixed combination of fully qualified # domain names, IPv4 and IPv6 addresses. # FallbackTimeservers = -FallbackTimeservers = pool.ntp.org +#FallbackTimeservers = pool.ntp.org # List of fallback nameservers separated by "," used if no # nameservers are otherwise provided by the service. The @@ -54,7 +54,7 @@ FallbackTimeservers = pool.ntp.org # the default route when compared to either a non-preferred # type or a preferred type further down in the list. # PreferredTechnologies = -PreferredTechnologies = ethernet,wifi +PreferredTechnologies = wifi, ethernet # List of blacklisted network interfaces separated by ",". # Found interfaces will be compared to the list and will @@ -62,7 +62,7 @@ PreferredTechnologies = ethernet,wifi # match any of the list entries. Default value is # vmnet,vboxnet,virbr,ifb. # NetworkInterfaceBlacklist = vmnet,vboxnet,virbr,ifb -NetworkInterfaceBlacklist = vmnet,vboxnet,virbr +NetworkInterfaceBlacklist = veth, vmnet,vboxnet,virbr,usb,rndis,rmnet,rev_rmnet,dummy,seth_td,seth_w # Allow connman to change the system hostname. This can # happen for example if we receive DHCP hostname option. @@ -80,6 +80,7 @@ NetworkInterfaceBlacklist = vmnet,vboxnet,virbr # setting enabled applications will notice more network breaks than # normal. Default value is false. # SingleConnectedTechnology = false +SingleConnectedTechnology = true # List of technologies for which tethering is allowed separated by ",". # The default value is wifi,bluetooth,gadget. Only those technologies @@ -99,3 +100,11 @@ NetworkInterfaceBlacklist = vmnet,vboxnet,virbr # re-enabling a technology, and after restarts and reboots. # Default value is false. # PersistentTetheringMode = false + +# Automatically enable Anycast 6to4 if possible. This is not recommended, as +# the use of 6to4 will generally lead to a severe degradation of connection +# quality. See RFC6343. Default value is false (as recommended by RFC6343 +# section 4.1). +# Enable6to4 = false + +NetworkCellularInterfaceList = pdp,rmnet,seth_td,seth_w diff --git a/src/manager.c b/src/manager.c index bd52f39a..bd52f39a 100644..100755 --- a/src/manager.c +++ b/src/manager.c diff --git a/src/nat.c b/src/nat.c index 063f0851..063f0851 100644..100755 --- a/src/nat.c +++ b/src/nat.c diff --git a/src/net.connman.service.in b/src/net.connman.service.in index e76969bc..f7f6a7c0 100644..100755 --- a/src/net.connman.service.in +++ b/src/net.connman.service.in @@ -1,5 +1,5 @@ [D-BUS Service] Name=net.connman -Exec=@prefix@/sbin/connmand -n +Exec=@sbindir@/connmand -n User=root SystemdService=connman.service diff --git a/src/network.c b/src/network.c index 4047e177..f928b6af 100644..100755 --- a/src/network.c +++ b/src/network.c @@ -96,6 +96,7 @@ struct connman_network { char encryption_mode[WIFI_ENCYPTION_MODE_LEN_MAX]; unsigned char bssid[WIFI_BSSID_LEN_MAX]; unsigned int maxrate; + unsigned int isHS20AP; #endif } wifi; @@ -168,10 +169,6 @@ static void dhcp_success(struct connman_network *network) if (!service) goto err; - connman_network_set_associating(network, false); - - network->connecting = false; - ipconfig_ipv4 = __connman_service_get_ip4config(service); DBG("lease acquired for ipconfig %p", ipconfig_ipv4); @@ -207,9 +204,6 @@ static void dhcp_failure(struct connman_network *network) if (!service) return; - connman_network_set_associating(network, false); - network->connecting = false; - ipconfig_ipv4 = __connman_service_get_ip4config(service); DBG("lease lost for ipconfig %p", ipconfig_ipv4); @@ -225,60 +219,24 @@ static void dhcp_callback(struct connman_ipconfig *ipconfig, struct connman_network *network, bool success, gpointer data) { + network->connecting = false; + if (success) dhcp_success(network); else dhcp_failure(network); } -static int set_connected_fixed(struct connman_network *network) -{ - struct connman_service *service; - struct connman_ipconfig *ipconfig_ipv4; - int err; - - DBG(""); - - service = connman_service_lookup_from_network(network); - - ipconfig_ipv4 = __connman_service_get_ip4config(service); - - set_configuration(network, CONNMAN_IPCONFIG_TYPE_IPV4); - - network->connecting = false; - - connman_network_set_associating(network, false); - - err = __connman_ipconfig_address_add(ipconfig_ipv4); - if (err < 0) - goto err; - -#if defined TIZEN_EXT - err = __connman_ipconfig_gateway_add(ipconfig_ipv4, service); -#else - err = __connman_ipconfig_gateway_add(ipconfig_ipv4); -#endif - - if (err < 0) - goto err; - - return 0; - -err: - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); - - return err; -} - -static void set_connected_manual(struct connman_network *network) +static int set_connected_manual(struct connman_network *network) { + int err = 0; struct connman_service *service; struct connman_ipconfig *ipconfig; - int err; DBG("network %p", network); + network->connecting = false; + service = connman_service_lookup_from_network(network); ipconfig = __connman_service_get_ip4config(service); @@ -286,8 +244,6 @@ static void set_connected_manual(struct connman_network *network) if (!__connman_ipconfig_get_local(ipconfig)) __connman_service_read_ip4config(service); - set_configuration(network, CONNMAN_IPCONFIG_TYPE_IPV4); - err = __connman_ipconfig_address_add(ipconfig); if (err < 0) goto err; @@ -300,16 +256,8 @@ static void set_connected_manual(struct connman_network *network) if (err < 0) goto err; - network->connecting = false; - - connman_network_set_associating(network, false); - - return; - err: - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); - return; + return err; } static int set_connected_dhcp(struct connman_network *network) @@ -320,8 +268,6 @@ static int set_connected_dhcp(struct connman_network *network) DBG("network %p", network); - set_configuration(network, CONNMAN_IPCONFIG_TYPE_IPV4); - service = connman_service_lookup_from_network(network); ipconfig_ipv4 = __connman_service_get_ip4config(service); @@ -374,6 +320,8 @@ static int manual_ipv6_set(struct connman_network *network, connman_device_set_disconnected(network->device, false); + connman_network_set_associating(network, false); + network->connecting = false; return 0; @@ -381,6 +329,8 @@ static int manual_ipv6_set(struct connman_network *network, static void stop_dhcpv6(struct connman_network *network) { + network->connecting = false; + __connman_dhcpv6_stop(network); } @@ -418,8 +368,6 @@ static int dhcpv6_set_addresses(struct connman_network *network) if (!service) goto err; - connman_network_set_associating(network, false); - network->connecting = false; ipconfig_ipv6 = __connman_service_get_ip6config(service); @@ -427,14 +375,6 @@ static int dhcpv6_set_addresses(struct connman_network *network) if (err < 0) goto err; -#if defined TIZEN_EXT - err = __connman_ipconfig_gateway_add(ipconfig_ipv6, service); -#else - err = __connman_ipconfig_gateway_add(ipconfig_ipv6); -#endif - if (err < 0) - goto err; - return 0; err: @@ -547,6 +487,8 @@ static void check_dhcpv6(struct nd_router_advert *reply, if (service) { connman_service_create_ip6config(service, network->index); + connman_network_set_associating(network, false); + __connman_service_ipconfig_indicate_state(service, CONNMAN_SERVICE_STATE_CONFIGURATION, CONNMAN_IPCONFIG_TYPE_IPV6); @@ -555,10 +497,16 @@ static void check_dhcpv6(struct nd_router_advert *reply, /* * We do stateful/stateless DHCPv6 if router advertisement says so. */ - if (reply->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) + if (reply->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) { __connman_dhcpv6_start(network, prefixes, dhcpv6_callback); - else if (reply->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) - __connman_dhcpv6_start_info(network, dhcpv6_info_callback); + } else { + if (reply->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) + __connman_dhcpv6_start_info(network, + dhcpv6_info_callback); + + g_slist_free_full(prefixes, g_free); + network->connecting = false; + } connman_network_unref(network); } @@ -638,11 +586,9 @@ static void autoconf_ipv6_set(struct connman_network *network) connman_device_set_disconnected(network->device, false); - network->connecting = false; - #if defined TIZEN_EXT - if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR) - return; + if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR) + return; #endif service = connman_service_lookup_from_network(network); @@ -653,6 +599,8 @@ static void autoconf_ipv6_set(struct connman_network *network) if (!ipconfig) return; + __connman_ipconfig_enable_ipv6(ipconfig); + __connman_ipconfig_address_remove(ipconfig); index = __connman_ipconfig_get_index(ipconfig); @@ -667,13 +615,13 @@ static void autoconf_ipv6_set(struct connman_network *network) static void set_connected(struct connman_network *network) { struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6; - enum connman_ipconfig_method ipv4_method, ipv6_method; struct connman_service *service; - int ret; if (network->connected) return; + connman_network_set_associating(network, false); + network->connected = true; service = connman_service_lookup_from_network(network); @@ -684,62 +632,8 @@ static void set_connected(struct connman_network *network) DBG("service %p ipv4 %p ipv6 %p", service, ipconfig_ipv4, ipconfig_ipv6); - ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4); - ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6); - - DBG("method ipv4 %d ipv6 %d", ipv4_method, ipv6_method); - - switch (ipv6_method) { - case CONNMAN_IPCONFIG_METHOD_UNKNOWN: - case CONNMAN_IPCONFIG_METHOD_OFF: - break; - case CONNMAN_IPCONFIG_METHOD_DHCP: - case CONNMAN_IPCONFIG_METHOD_AUTO: -#if defined TIZEN_EXT - if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR) - __connman_service_ipconfig_indicate_state(service, - CONNMAN_SERVICE_STATE_CONFIGURATION, - CONNMAN_IPCONFIG_TYPE_IPV6); -#endif - autoconf_ipv6_set(network); - break; - case CONNMAN_IPCONFIG_METHOD_FIXED: - case CONNMAN_IPCONFIG_METHOD_MANUAL: - ret = manual_ipv6_set(network, ipconfig_ipv6); - if (ret != 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); - return; - } - break; - } - - switch (ipv4_method) { - case CONNMAN_IPCONFIG_METHOD_UNKNOWN: - case CONNMAN_IPCONFIG_METHOD_OFF: - case CONNMAN_IPCONFIG_METHOD_AUTO: - return; - case CONNMAN_IPCONFIG_METHOD_FIXED: - if (set_connected_fixed(network) < 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); - return; - } - return; - case CONNMAN_IPCONFIG_METHOD_MANUAL: - set_connected_manual(network); - return; - case CONNMAN_IPCONFIG_METHOD_DHCP: - if (set_connected_dhcp(network) < 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); - return; - } - } - - network->connecting = false; - - connman_network_set_associating(network, false); + __connman_network_enable_ipconfig(network, ipconfig_ipv4); + __connman_network_enable_ipconfig(network, ipconfig_ipv6); } static void set_disconnected(struct connman_network *network) @@ -1196,14 +1090,21 @@ void connman_network_set_index(struct connman_network *network, int index) goto done; ipconfig = __connman_service_get_ip4config(service); - if (!ipconfig) - goto done; + if (ipconfig) { + __connman_ipconfig_set_index(ipconfig, index); + + DBG("index %d service %p ip4config %p", network->index, + service, ipconfig); + } + + ipconfig = __connman_service_get_ip6config(service); + if (ipconfig) { + __connman_ipconfig_set_index(ipconfig, index); - /* If index changed, the index of ipconfig must be reset. */ - __connman_ipconfig_set_index(ipconfig, index); + DBG("index %d service %p ip6config %p", network->index, + service, ipconfig); + } - DBG("index %d service %p ip4config %p", network->index, - service, ipconfig); done: network->index = index; } @@ -1314,7 +1215,9 @@ bool connman_network_get_connecting(struct connman_network *network) int connman_network_set_available(struct connman_network *network, bool available) { +#if !defined TIZEN_EXT DBG("network %p available %d", network, available); +#endif if (network->available == available) return -EALREADY; @@ -1451,6 +1354,13 @@ int connman_network_set_associating(struct connman_network *network, CONNMAN_IPCONFIG_TYPE_IPV6); } +#if defined TIZEN_EXT + if (associating == FALSE) + g_timeout_add_seconds(1, + __connman_network_clear_associating_delayed, + network); +#endif + return 0; } @@ -1744,30 +1654,6 @@ int __connman_network_disconnect(struct connman_network *network) return err; } -static int manual_ipv4_set(struct connman_network *network, - struct connman_ipconfig *ipconfig) -{ - struct connman_service *service; - int err; - - service = connman_service_lookup_from_network(network); - if (!service) - return -EINVAL; - - err = __connman_ipconfig_address_add(ipconfig); - if (err < 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); - return err; - } - -#if defined TIZEN_EXT - return __connman_ipconfig_gateway_add(ipconfig, service); -#else - return __connman_ipconfig_gateway_add(ipconfig); -#endif -} - int __connman_network_clear_ipconfig(struct connman_network *network, struct connman_ipconfig *ipconfig) { @@ -1812,58 +1698,99 @@ int __connman_network_clear_ipconfig(struct connman_network *network, return 0; } -int __connman_network_set_ipconfig(struct connman_network *network, - struct connman_ipconfig *ipconfig_ipv4, - struct connman_ipconfig *ipconfig_ipv6) +int __connman_network_enable_ipconfig(struct connman_network *network, + struct connman_ipconfig *ipconfig) { + int r = 0; + enum connman_ipconfig_type type; enum connman_ipconfig_method method; - int ret; +#if defined TIZEN_EXT + struct connman_service *service; +#endif - if (!network) + if (!network || !ipconfig) return -EINVAL; - if (ipconfig_ipv6) { - method = __connman_ipconfig_get_method(ipconfig_ipv6); + type = __connman_ipconfig_get_config_type(ipconfig); + + switch (type) { + case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + case CONNMAN_IPCONFIG_TYPE_ALL: + return -ENOSYS; + + case CONNMAN_IPCONFIG_TYPE_IPV6: + set_configuration(network, type); + + method = __connman_ipconfig_get_method(ipconfig); + + DBG("ipv6 ipconfig method %d", method); switch (method) { case CONNMAN_IPCONFIG_METHOD_UNKNOWN: + break; + case CONNMAN_IPCONFIG_METHOD_OFF: + __connman_ipconfig_disable_ipv6(ipconfig); break; + case CONNMAN_IPCONFIG_METHOD_AUTO: +#if defined TIZEN_EXT + service = connman_service_lookup_from_network(network); + + if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR) + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_CONFIGURATION, + CONNMAN_IPCONFIG_TYPE_IPV6); +#endif autoconf_ipv6_set(network); break; + case CONNMAN_IPCONFIG_METHOD_FIXED: case CONNMAN_IPCONFIG_METHOD_MANUAL: - ret = manual_ipv6_set(network, ipconfig_ipv6); - if (ret != 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); - return ret; - } + r = manual_ipv6_set(network, ipconfig); break; + case CONNMAN_IPCONFIG_METHOD_DHCP: + r = -ENOSYS; break; } - } - if (ipconfig_ipv4) { - method = __connman_ipconfig_get_method(ipconfig_ipv4); + break; + + case CONNMAN_IPCONFIG_TYPE_IPV4: + set_configuration(network, type); + + method = __connman_ipconfig_get_method(ipconfig); + + DBG("ipv4 ipconfig method %d", method); switch (method) { case CONNMAN_IPCONFIG_METHOD_UNKNOWN: case CONNMAN_IPCONFIG_METHOD_OFF: - case CONNMAN_IPCONFIG_METHOD_FIXED: + break; + case CONNMAN_IPCONFIG_METHOD_AUTO: - return -EINVAL; + r = -ENOSYS; + break; + + case CONNMAN_IPCONFIG_METHOD_FIXED: case CONNMAN_IPCONFIG_METHOD_MANUAL: - return manual_ipv4_set(network, ipconfig_ipv4); + r = set_connected_manual(network); + break; + case CONNMAN_IPCONFIG_METHOD_DHCP: - return __connman_dhcp_start(ipconfig_ipv4, - network, dhcp_callback, NULL); + r = set_connected_dhcp(network); + break; } + + break; } - return 0; + if (r < 0) + connman_network_set_error(network, + CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); + + return r; } int connman_network_set_ipaddress(struct connman_network *network, @@ -1921,7 +1848,9 @@ unsigned char *connman_network_get_bssid(struct connman_network *network) int connman_network_set_maxrate(struct connman_network *network, unsigned int maxrate) { +#if !defined TIZEN_EXT DBG("network %p maxrate %d", network, maxrate); +#endif network->wifi.maxrate = maxrate; @@ -1970,6 +1899,25 @@ int connman_network_set_proxy(struct connman_network *network, return 0; } + +int connman_network_set_is_hs20AP(struct connman_network *network, + unsigned int isHS20AP) +{ + if (!network) + return 0; + + network->wifi.isHS20AP = isHS20AP; + + return 0; +} + +unsigned int connman_network_get_is_hs20AP(struct connman_network *network) +{ + if (!network) + return 0; + + return network->wifi.isHS20AP; +} #endif int connman_network_set_nameservers(struct connman_network *network, @@ -2047,7 +1995,9 @@ int connman_network_set_name(struct connman_network *network, int connman_network_set_strength(struct connman_network *network, uint8_t strength) { +#if !defined TIZEN_EXT DBG("network %p strengh %d", network, strength); +#endif network->strength = strength; @@ -2062,7 +2012,9 @@ uint8_t connman_network_get_strength(struct connman_network *network) int connman_network_set_frequency(struct connman_network *network, uint16_t frequency) { +#if !defined TIZEN_EXT DBG("network %p frequency %d", network, frequency); +#endif network->frequency = frequency; @@ -2100,7 +2052,9 @@ uint16_t connman_network_get_wifi_channel(struct connman_network *network) int connman_network_set_string(struct connman_network *network, const char *key, const char *value) { +#if !defined TIZEN_EXT DBG("network %p key %s value %s", network, key, value); +#endif if (g_strcmp0(key, "Name") == 0) return connman_network_set_name(network, value); @@ -2164,7 +2118,9 @@ int connman_network_set_string(struct connman_network *network, const char *connman_network_get_string(struct connman_network *network, const char *key) { +#if !defined TIZEN_EXT DBG("network %p key %s", network, key); +#endif if (g_str_equal(key, "Path")) return network->path; @@ -2211,7 +2167,9 @@ const char *connman_network_get_string(struct connman_network *network, int connman_network_set_bool(struct connman_network *network, const char *key, bool value) { +#if !defined TIZEN_EXT DBG("network %p key %s value %d", network, key, value); +#endif if (g_strcmp0(key, "Roaming") == 0) network->roaming = value; @@ -2237,7 +2195,9 @@ int connman_network_set_bool(struct connman_network *network, bool connman_network_get_bool(struct connman_network *network, const char *key) { +#if !defined TIZEN_EXT DBG("network %p key %s", network, key); +#endif if (g_str_equal(key, "Roaming")) return network->roaming; @@ -2265,7 +2225,9 @@ bool connman_network_get_bool(struct connman_network *network, int connman_network_set_blob(struct connman_network *network, const char *key, const void *data, unsigned int size) { +#if !defined TIZEN_EXT DBG("network %p key %s size %d", network, key, size); +#endif if (g_str_equal(key, "WiFi.SSID")) { g_free(network->wifi.ssid); diff --git a/src/notifier.c b/src/notifier.c index 5ba53242..5ba53242 100644..100755 --- a/src/notifier.c +++ b/src/notifier.c diff --git a/src/ntp.c b/src/ntp.c index b4fe63aa..abb2caa2 100644..100755 --- a/src/ntp.c +++ b/src/ntp.c @@ -208,6 +208,8 @@ static void send_packet(int fd, const char *server, uint32_t timeout) static gboolean next_poll(gpointer user_data) { + poll_id = 0; + if (!timeserver || transmit_fd == 0) return FALSE; diff --git a/src/peer.c b/src/peer.c index caff70c8..206b799b 100644..100755 --- a/src/peer.c +++ b/src/peer.c @@ -27,6 +27,7 @@ #include <ctype.h> #include <gdbus.h> #include <gdhcp/gdhcp.h> +#include <netinet/if_ether.h> #include <connman/agent.h> @@ -54,6 +55,7 @@ struct connman_peer { int refcount; struct connman_device *device; struct connman_device *sub_device; + unsigned char *iface_address[ETH_ALEN]; char *identifier; char *name; char *path; @@ -64,9 +66,12 @@ struct connman_peer { bool connection_master; struct connman_ippool *ip_pool; GDHCPServer *dhcp_server; + uint32_t lease_ip; GSList *services; }; +static void settings_changed(struct connman_peer *peer); + static void stop_dhcp_server(struct connman_peer *peer) { DBG(""); @@ -79,6 +84,7 @@ static void stop_dhcp_server(struct connman_peer *peer) if (peer->ip_pool) __connman_ippool_unref(peer->ip_pool); peer->ip_pool = NULL; + peer->lease_ip = 0; } static void dhcp_server_debug(const char *str, void *data) @@ -86,6 +92,24 @@ static void dhcp_server_debug(const char *str, void *data) connman_info("%s: %s\n", (const char *) data, str); } +static void lease_added(unsigned char *mac, uint32_t ip) +{ + GList *list, *start; + + start = list = g_hash_table_get_values(peers_table); + for (; list; list = list->next) { + struct connman_peer *temp = list->data; + + if (!memcmp(temp->iface_address, mac, ETH_ALEN)) { + temp->lease_ip = ip; + settings_changed(temp); + break; + } + } + + g_list_free(start); +} + static gboolean dhcp_server_started(gpointer data) { struct connman_peer *peer = data; @@ -146,6 +170,8 @@ static int start_dhcp_server(struct connman_peer *peer) g_dhcp_server_set_option(peer->dhcp_server, G_DHCP_DNS_SERVER, NULL); g_dhcp_server_set_ip_range(peer->dhcp_server, start_ip, end_ip); + g_dhcp_server_set_lease_added_cb(peer->dhcp_server, lease_added); + err = g_dhcp_server_start(peer->dhcp_server); if (err < 0) goto error; @@ -253,39 +279,43 @@ static bool allow_property_changed(struct connman_peer *peer) return true; } -static void append_dhcp_server_ipv4(DBusMessageIter *iter, void *user_data) +static void append_ipv4(DBusMessageIter *iter, void *user_data) { struct connman_peer *peer = user_data; - const char *str = "dhcp"; - const char *gateway; - const char *subnet; + char trans[INET_ADDRSTRLEN+1] = {}; + const char *local = ""; + const char *remote = ""; + char *dhcp = NULL; - if (!peer->ip_pool) + if (!is_connected(peer)) return; - gateway = __connman_ippool_get_gateway(peer->ip_pool); - subnet = __connman_ippool_get_subnet_mask(peer->ip_pool); + if (peer->connection_master) { + struct in_addr addr; - connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str); - connman_dbus_dict_append_basic(iter, "Address", - DBUS_TYPE_STRING, &gateway); - connman_dbus_dict_append_basic(iter, "Netmask", - DBUS_TYPE_STRING, &subnet); - connman_dbus_dict_append_basic(iter, "Gateway", - DBUS_TYPE_STRING, &gateway); -} + addr.s_addr = peer->lease_ip; + inet_ntop(AF_INET, &addr, trans, INET_ADDRSTRLEN); -static void append_ipv4(DBusMessageIter *iter, void *user_data) -{ - struct connman_peer *peer = user_data; + local = __connman_ippool_get_gateway(peer->ip_pool); + remote = trans; + } else if (peer->ipconfig) { + local = __connman_ipconfig_get_local(peer->ipconfig); - if (!is_connected(peer)) - return; + remote = __connman_ipconfig_get_gateway(peer->ipconfig); + if (!remote) { + remote = dhcp = __connman_dhcp_get_server_address( + peer->ipconfig); + if (!dhcp) + remote = ""; + } + } - if (peer->connection_master) - append_dhcp_server_ipv4(iter, peer); - else if (peer->ipconfig) - __connman_ipconfig_append_ipv4(peer->ipconfig, iter); + connman_dbus_dict_append_basic(iter, "Local", + DBUS_TYPE_STRING, &local); + connman_dbus_dict_append_basic(iter, "Remote", + DBUS_TYPE_STRING, &remote); + if (dhcp) + g_free(dhcp); } static void append_peer_service(DBusMessageIter *iter, @@ -725,6 +755,13 @@ void connman_peer_set_name(struct connman_peer *peer, const char *name) peer->name = g_strdup(name); } +void connman_peer_set_iface_address(struct connman_peer *peer, + const unsigned char *iface_address) +{ + memset(peer->iface_address, 0, ETH_ALEN); + memcpy(peer->iface_address, iface_address, ETH_ALEN); +} + void connman_peer_set_device(struct connman_peer *peer, struct connman_device *device) { @@ -885,6 +922,10 @@ int connman_peer_set_state(struct connman_peer *peer, peer->state = new_state; state_changed(peer); + if (peer->state == CONNMAN_PEER_STATE_READY || + peer->state == CONNMAN_PEER_STATE_DISCONNECT) + settings_changed(peer); + return 0; } @@ -976,7 +1017,8 @@ static void peer_ip_bound(struct connman_ipconfig *ipconfig, DBG("%s ip bound", ifname); - settings_changed(peer); + if (peer->state == CONNMAN_PEER_STATE_READY) + settings_changed(peer); connman_peer_set_state(peer, CONNMAN_PEER_STATE_READY); } @@ -987,7 +1029,8 @@ static void peer_ip_release(struct connman_ipconfig *ipconfig, DBG("%s ip release", ifname); - settings_changed(peer); + if (peer->state == CONNMAN_PEER_STATE_READY) + settings_changed(peer); } static const struct connman_ipconfig_ops peer_ip_ops = { @@ -1151,6 +1194,10 @@ void __connman_peer_cleanup(void) { DBG(""); + g_hash_table_destroy(peers_notify->remove); + g_hash_table_destroy(peers_notify->add); + g_free(peers_notify); + g_hash_table_destroy(peers_table); peers_table = NULL; dbus_connection_unref(connection); diff --git a/src/peer_service.c b/src/peer_service.c index 053672af..053672af 100644..100755 --- a/src/peer_service.c +++ b/src/peer_service.c diff --git a/src/plugin.c b/src/plugin.c index 7d730582..7d730582 100644..100755 --- a/src/plugin.c +++ b/src/plugin.c diff --git a/src/provider.c b/src/provider.c index 22ff08ae..22ff08ae 100644..100755 --- a/src/provider.c +++ b/src/provider.c diff --git a/src/proxy.c b/src/proxy.c index 0d1a25ab..f331de92 100644..100755 --- a/src/proxy.c +++ b/src/proxy.c @@ -44,6 +44,9 @@ struct proxy_lookup { static void remove_lookup(struct proxy_lookup *lookup) { + if (lookup->watch > 0) + g_source_remove(lookup->watch); + lookup_list = g_slist_remove(lookup_list, lookup); connman_service_unref(lookup->service); @@ -150,11 +153,6 @@ void connman_proxy_lookup_cancel(unsigned int token) } if (lookup) { - if (lookup->watch > 0) { - g_source_remove(lookup->watch); - lookup->watch = 0; - } - if (lookup->proxy && lookup->proxy->cancel_lookup) lookup->proxy->cancel_lookup(lookup->service, diff --git a/src/resolver.c b/src/resolver.c index f6fd0632..6a649388 100644..100755 --- a/src/resolver.c +++ b/src/resolver.c @@ -37,10 +37,6 @@ #define RESOLVER_FLAG_PUBLIC (1 << 0) -#if defined TIZEN_EXT -#include <sys/smack.h> -#endif - /* * Threshold for RDNSS lifetime. Will be used to trigger RS * before RDNSS entries actually expire @@ -141,11 +137,6 @@ static int resolvfile_export(void) goto done; } -#if defined TIZEN_EXT - if (smack_fsetlabel(fd, "_", SMACK_LABEL_ACCESS) != 0) - DBG("Failed to label _"); -#endif - if (ftruncate(fd, 0) < 0) { err = -errno; goto failed; @@ -292,6 +283,8 @@ static void remove_entries(GSList *entries) } g_slist_free(entries); + + append_fallback_nameservers(); } static gboolean resolver_expire_cb(gpointer user_data) @@ -571,21 +564,6 @@ int connman_resolver_remove_all(int index) return 0; } -/** - * connman_resolver_flush: - * - * Flush pending resolver requests - */ -void connman_resolver_flush(void) -{ - append_fallback_nameservers(); - - if (dnsproxy_enabled) - __connman_dnsproxy_flush(); - - return; -} - int __connman_resolver_redo_servers(int index) { GSList *list; @@ -617,14 +595,6 @@ int __connman_resolver_redo_servers(int index) */ __connman_dnsproxy_remove(entry->index, entry->domain, entry->server); - /* - * Remove also the resolver timer for the old server entry. - * A new timer will be set for the new server entry - * when the next Router Advertisement message arrives - * with RDNSS/DNSSL settings. - */ - g_source_remove(entry->timeout); - entry->timeout = 0; __connman_dnsproxy_append(entry->index, entry->domain, entry->server); diff --git a/src/rfkill.c b/src/rfkill.c index 43be17e8..20908d71 100644..100755 --- a/src/rfkill.c +++ b/src/rfkill.c @@ -155,7 +155,7 @@ static gboolean rfkill_event(GIOChannel *chan, GIOCondition cond, gpointer data) return TRUE; } -static GIOChannel *channel = NULL; +static guint watch = 0; int __connman_rfkill_block(enum connman_service_type type, bool block) { @@ -179,7 +179,7 @@ int __connman_rfkill_block(enum connman_service_type type, bool block) fd = open("/dev/rfkill", O_RDWR | O_CLOEXEC); if (fd < 0) - return fd; + return -errno; memset(&event, 0, sizeof(event)); event.op = RFKILL_OP_CHANGE_ALL; @@ -188,10 +188,9 @@ int __connman_rfkill_block(enum connman_service_type type, bool block) len = write(fd, &event, sizeof(event)); if (len < 0) { + err = -errno; connman_error("Failed to change RFKILL state"); - err = len; - } else - err = 0; + } close(fd); @@ -201,6 +200,7 @@ int __connman_rfkill_block(enum connman_service_type type, bool block) int __connman_rfkill_init(void) { + GIOChannel *channel; GIOFlags flags; int fd; @@ -225,21 +225,21 @@ int __connman_rfkill_init(void) /* Process current RFKILL events sent on device open */ while (rfkill_process(channel) == G_IO_STATUS_NORMAL); - g_io_add_watch(channel, G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR, - rfkill_event, NULL); + watch = g_io_add_watch(channel, + G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR, + rfkill_event, NULL); - return 0; + g_io_channel_unref(channel); + + return watch ? 0 : -EIO; } void __connman_rfkill_cleanup(void) { DBG(""); - if (!channel) - return; - - g_io_channel_shutdown(channel, TRUE, NULL); - g_io_channel_unref(channel); - - channel = NULL; + if (watch) { + g_source_remove(watch); + watch = 0; + } } diff --git a/src/rtnl.c b/src/rtnl.c index a46aa284..dc15b331 100644..100755 --- a/src/rtnl.c +++ b/src/rtnl.c @@ -46,6 +46,12 @@ #define ARPHDR_PHONET_PIPE (821) #endif +#if defined TIZEN_EXT +#ifndef ARPHDR_RMNET +#define ARPHDR_RMNET (530) +#endif +#endif + #define print(arg...) do { if (0) connman_info(arg); } while (0) //#define print(arg...) connman_info(arg) @@ -116,6 +122,29 @@ static bool wext_interface(char *ifname) return true; } +#if defined TIZEN_EXT +static bool __connman_rtnl_is_cellular_device(const char *name) +{ + char **pattern; + char **cellular_interfaces; + + cellular_interfaces = + connman_setting_get_string_list( + "NetworkCellularInterfaceList"); + if (!cellular_interfaces) + return false; + + for (pattern = cellular_interfaces; *pattern; pattern++) { + if (g_str_has_prefix(name, *pattern)) { + DBG("Cellular interface: %s", name); + return true; + } + } + + return false; +} +#endif + static void read_uevent(struct interface_data *interface) { char *filename, *name, line[128]; @@ -124,6 +153,14 @@ static void read_uevent(struct interface_data *interface) name = connman_inet_ifname(interface->index); +#if defined TIZEN_EXT + if (__connman_rtnl_is_cellular_device(name)) { + interface->service_type = CONNMAN_SERVICE_TYPE_CELLULAR; + interface->device_type = CONNMAN_DEVICE_TYPE_CELLULAR; + return; + } +#endif + if (ether_blacklisted(name)) { interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN; interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN; @@ -170,6 +207,9 @@ static void read_uevent(struct interface_data *interface) } else if (strcmp(line + 8, "gadget") == 0) { interface->service_type = CONNMAN_SERVICE_TYPE_GADGET; interface->device_type = CONNMAN_DEVICE_TYPE_GADGET; + } else if (strcmp(line + 8, "vlan") == 0) { + interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET; + interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET; } else { interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN; @@ -414,6 +454,14 @@ static void process_newlink(unsigned short type, int index, unsigned flags, if (!extract_link(msg, bytes, &address, &ifname, &mtu, &operstate, &stats)) return; +#if defined TIZEN_EXT + /* Do not accept Wi-Fi P2P interface */ + if (g_strrstr(ifname, "p2p") != NULL) { + DBG("Newlink event for Wi-Fi P2P interface ignored"); + return; + } +#endif + snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x", address.ether_addr_octet[0], address.ether_addr_octet[1], @@ -436,12 +484,25 @@ static void process_newlink(unsigned short type, int index, unsigned flags, return; } +#if defined TIZEN_TV_EXT + if (g_strcmp0(ident, "eeeeeeeeeeee") == 0) { + DBG("Newlink event with Dummy MAC. Ignored!"); + return; + } +#endif + switch (type) { case ARPHRD_ETHER: case ARPHRD_LOOPBACK: case ARPHDR_PHONET_PIPE: case ARPHRD_PPP: case ARPHRD_NONE: +#if defined TIZEN_EXT +/* + * Description: ARPHDR_RMNET for QC modem using QMI + */ + case ARPHDR_RMNET: +#endif __connman_ipconfig_newlink(index, type, flags, str, mtu, &stats); break; @@ -466,6 +527,25 @@ static void process_newlink(unsigned short type, int index, unsigned flags, if (type == ARPHRD_ETHER) read_uevent(interface); +#if defined TIZEN_EXT + if (type == ARPHRD_PPP || type == ARPHDR_RMNET) + read_uevent(interface); + + } else if (g_strcmp0(interface->ident, ident) != 0) { + /* If an original address is built-in physical device, + * it's hardly get an address at a initial creation + */ + __connman_technology_remove_interface(interface->service_type, + interface->index, interface->ident); + + g_free(interface->ident); + interface->ident = g_strdup(ident); + + __connman_technology_add_interface(interface->service_type, + interface->index, interface->ident); + + interface = NULL; +#endif } else interface = NULL; @@ -527,6 +607,13 @@ static void process_dellink(unsigned short type, int index, unsigned flags, case ARPHDR_PHONET_PIPE: case ARPHRD_PPP: case ARPHRD_NONE: +#if defined TIZEN_EXT + /* + * Description: SLP requires ARPHRD_PPP for PPP type device + * ARPHDR_RMNET for QC modem using QMI + */ + case ARPHDR_RMNET: +#endif __connman_ipconfig_dellink(index, &stats); break; } @@ -612,17 +699,18 @@ static void process_newaddr(unsigned char family, unsigned char prefixlen, if (!inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN)) return; - __connman_ipconfig_newaddr(index, family, label, - prefixlen, ip_string); - - if (family == AF_INET6) { - /* - * Re-create RDNSS configured servers if there are any - * for this interface. This is done because we might - * have now properly configured interface with proper - * autoconfigured address. - */ - __connman_resolver_redo_servers(index); + if (__connman_ipconfig_newaddr(index, family, label, + prefixlen, ip_string) >= 0) { + if (family == AF_INET6) { + /* + * Re-create RDNSS configured servers if there + * are any for this interface. This is done + * because we might have now properly + * configured interface with proper + * autoconfigured address. + */ + __connman_resolver_redo_servers(index); + } } } @@ -1083,6 +1171,8 @@ static void rtnl_route(struct nlmsghdr *hdr) static bool is_route_rtmsg(struct rtmsg *msg) { + if (msg->rtm_flags & RTM_F_CLONED) + return false; if (msg->rtm_table != RT_TABLE_MAIN) return false; @@ -1291,6 +1381,7 @@ static const char *type2string(uint16_t type) } static GIOChannel *channel = NULL; +static guint channel_watch = 0; struct rtnl_request { struct nlmsghdr hdr; @@ -1621,8 +1712,9 @@ int __connman_rtnl_init(void) g_io_channel_set_encoding(channel, NULL, NULL); g_io_channel_set_buffered(channel, FALSE); - g_io_add_watch(channel, G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR, - netlink_event, NULL); + channel_watch = g_io_add_watch(channel, + G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR, + netlink_event, NULL); return 0; } @@ -1672,6 +1764,11 @@ void __connman_rtnl_cleanup(void) g_slist_free(request_list); request_list = NULL; + if (channel_watch) { + g_source_remove(channel_watch); + channel_watch = 0; + } + g_io_channel_shutdown(channel, TRUE, NULL); g_io_channel_unref(channel); diff --git a/src/service.c b/src/service.c index 1eec7cac..320e7cc9 100644..100755 --- a/src/service.c +++ b/src/service.c @@ -77,6 +77,14 @@ struct connman_service_user { uid_t current_user; }; +#if defined TIZEN_TV_EXT +enum connman_dnsconfig_method { + CONNMAN_DNSCONFIG_METHOD_UNKNOWN = 0, + CONNMAN_DNSCONFIG_METHOD_MANUAL = 1, + CONNMAN_DNSCONFIG_METHOD_DHCP = 2, +}; +#endif + struct connman_service { int refcount; char *identifier; @@ -149,6 +157,9 @@ struct connman_service { */ int user_pdn_connection_refcount; #endif +#if defined TIZEN_TV_EXT + enum connman_dnsconfig_method dns_config_method; +#endif }; static bool allow_property_changed(struct connman_service *service); @@ -416,6 +427,33 @@ static enum connman_service_proxy_method string2proxymethod(const char *method) return CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN; } +#if defined TIZEN_TV_EXT +static const char *__connman_dnsconfig_method2string(enum connman_dnsconfig_method method) +{ + switch (method) { + case CONNMAN_DNSCONFIG_METHOD_UNKNOWN: + return "unknown"; + case CONNMAN_DNSCONFIG_METHOD_MANUAL: + return "manual"; + case CONNMAN_DNSCONFIG_METHOD_DHCP: + return "dhcp"; + } + + return NULL; +} + +static enum connman_dnsconfig_method __connman_dnsconfig_string2method( + const char *method) +{ + if (g_strcmp0(method, "manual") == 0) + return CONNMAN_DNSCONFIG_METHOD_MANUAL; + else if (g_strcmp0(method, "dhcp") == 0) + return CONNMAN_DNSCONFIG_METHOD_DHCP; + else + return CONNMAN_DNSCONFIG_METHOD_UNKNOWN; +} +#endif + static bool connman_service_is_user_allowed(struct connman_service *service, uid_t uid) { @@ -688,6 +726,13 @@ static int service_load(struct connman_service *service) service->nameservers_config = NULL; } +#if defined TIZEN_TV_EXT + char *dns_method; + dns_method = g_key_file_get_string(keyfile, service->identifier, + "Nameservers.method", NULL); + service->dns_config_method = __connman_dnsconfig_string2method(dns_method); +#endif + service->timeservers_config = g_key_file_get_string_list(keyfile, service->identifier, "Timeservers", &length, NULL); if (service->timeservers_config && length == 0) { @@ -733,6 +778,60 @@ static int service_load(struct connman_service *service) service->hidden_service = g_key_file_get_boolean(keyfile, service->identifier, "Hidden", NULL); +#if defined TIZEN_EXT + if (service->type == CONNMAN_SERVICE_TYPE_WIFI && + service->security == CONNMAN_SERVICE_SECURITY_8021X) { + str = g_key_file_get_string(keyfile, + service->identifier, "EAP", NULL); + if (str != NULL) { + g_free(service->eap); + service->eap = str; + } + + str = g_key_file_get_string(keyfile, + service->identifier, "Phase2", NULL); + if (str != NULL) { + g_free(service->phase2); + service->phase2 = str; + } + + str = g_key_file_get_string(keyfile, + service->identifier, "Identity", NULL); + if (str != NULL) { + g_free(service->identity); + service->identity = str; + } + + str = g_key_file_get_string(keyfile, + service->identifier, "CACertFile", NULL); + if (str != NULL) { + g_free(service->ca_cert_file); + service->ca_cert_file = str; + } + + str = g_key_file_get_string(keyfile, + service->identifier, "ClientCertFile", NULL); + if (str != NULL) { + g_free(service->client_cert_file); + service->client_cert_file = str; + } + + str = g_key_file_get_string(keyfile, + service->identifier, "PrivateKeyFile", NULL); + if (str != NULL) { + g_free(service->private_key_file); + service->private_key_file = str; + } + + str = g_key_file_get_string(keyfile, + service->identifier, "PrivateKeyPassphrase", NULL); + if (str != NULL) { + g_free(service->private_key_passphrase); + service->private_key_passphrase = str; + } + } +#endif + if (g_key_file_has_key(keyfile, service->identifier, "UID", NULL)) service->user.favorite_user = g_key_file_get_integer(keyfile, service->identifier, "UID", NULL); @@ -870,6 +969,18 @@ static int service_save(struct connman_service *service) g_key_file_remove_key(keyfile, service->identifier, "Nameservers", NULL); +#if defined TIZEN_TV_EXT + if(service->dns_config_method != 0) { + const char *method; + method = __connman_dnsconfig_method2string( + service->dns_config_method); + g_key_file_set_string(keyfile, service->identifier, + "Nameservers.method", method); + } else + g_key_file_remove_key(keyfile, service->identifier, + "Nameservers.method", NULL); +#endif + if (service->timeservers_config) { guint len = g_strv_length(service->timeservers_config); @@ -935,6 +1046,60 @@ static int service_save(struct connman_service *service) g_key_file_set_string(keyfile, service->identifier, "Config.ident", service->config_entry); +#if defined TIZEN_EXT + if (service->type == CONNMAN_SERVICE_TYPE_WIFI && + service->security == CONNMAN_SERVICE_SECURITY_8021X) { + if (service->eap != NULL && strlen(service->eap) > 0) + g_key_file_set_string(keyfile, service->identifier, + "EAP", service->eap); + else + g_key_file_remove_key(keyfile, service->identifier, + "EAP", NULL); + + if (service->phase2 != NULL && strlen(service->phase2) > 0) + g_key_file_set_string(keyfile, service->identifier, + "Phase2", service->phase2); + else + g_key_file_remove_key(keyfile, service->identifier, + "Phase2", NULL); + + if (service->identity != NULL && strlen(service->identity) > 0) + g_key_file_set_string(keyfile, service->identifier, + "Identity", service->identity); + else + g_key_file_remove_key(keyfile, service->identifier, + "Identity", NULL); + + if (service->ca_cert_file != NULL && strlen(service->ca_cert_file) > 0) + g_key_file_set_string(keyfile, service->identifier, + "CACertFile", service->ca_cert_file); + else + g_key_file_remove_key(keyfile, service->identifier, + "CACertFile", NULL); + + if (service->client_cert_file != NULL && strlen(service->client_cert_file) > 0) + g_key_file_set_string(keyfile, service->identifier, + "ClientCertFile", service->client_cert_file); + else + g_key_file_remove_key(keyfile, service->identifier, + "ClientCertFile", NULL); + + if (service->private_key_file != NULL && strlen(service->private_key_file) > 0) + g_key_file_set_string(keyfile, service->identifier, + "PrivateKeyFile", service->private_key_file); + else + g_key_file_remove_key(keyfile, service->identifier, + "PrivateKeyFile", NULL); + + if (service->private_key_passphrase != NULL && strlen(service->private_key_passphrase) > 0) + g_key_file_set_string(keyfile, service->identifier, + "PrivateKeyPassphrase", service->private_key_passphrase); + else + g_key_file_remove_key(keyfile, service->identifier, + "PrivateKeyPassphrase", NULL); + } +#endif + done: __connman_storage_save_service(keyfile, service->identifier); @@ -1107,146 +1272,155 @@ static bool is_connected(struct connman_service *service) return is_connected_state(service, service->state); } -static int nameserver_get_index(struct connman_service *service) +static bool nameserver_available(struct connman_service *service, + const char *ns) { - switch (combine_state(service->state_ipv4, service->state_ipv6)) { - case CONNMAN_SERVICE_STATE_UNKNOWN: - case CONNMAN_SERVICE_STATE_IDLE: - case CONNMAN_SERVICE_STATE_ASSOCIATION: - case CONNMAN_SERVICE_STATE_CONFIGURATION: - case CONNMAN_SERVICE_STATE_FAILURE: - case CONNMAN_SERVICE_STATE_DISCONNECT: - return -1; - case CONNMAN_SERVICE_STATE_READY: - case CONNMAN_SERVICE_STATE_ONLINE: - break; - } + int family; + + family = connman_inet_check_ipaddress(ns); - return __connman_service_get_index(service); + if (family == AF_INET) + return is_connected_state(service, service->state_ipv4); + + if (family == AF_INET6) + return is_connected_state(service, service->state_ipv6); + + return false; } -static void remove_nameservers(struct connman_service *service, - int index, char **ns) +static int nameserver_add(struct connman_service *service, + const char *nameserver) { - int i; - - if (!ns) - return; + int index; - if (index < 0) - index = nameserver_get_index(service); + if (!nameserver_available(service, nameserver)) + return 0; + index = __connman_service_get_index(service); if (index < 0) - return; + return -ENXIO; - for (i = 0; ns[i]; i++) - connman_resolver_remove(index, NULL, ns[i]); + return connman_resolver_append(index, NULL, nameserver); } -static void remove_searchdomains(struct connman_service *service, - int index, char **sd) +static int nameserver_add_all(struct connman_service *service) { - int i; + int i = 0; - if (!sd) - return; + if (service->nameservers_config) { + while (service->nameservers_config[i]) { + nameserver_add(service, service->nameservers_config[i]); + i++; + } - if (index < 0) - index = nameserver_get_index(service); + return 0; + } - if (index < 0) - return; + if (service->nameservers) { + while (service->nameservers[i]) { + nameserver_add(service, service->nameservers[i]); + i++; + } + } - for (i = 0; sd[i]; i++) - connman_resolver_remove(index, sd[i], NULL); + return 0; } -static bool nameserver_available(struct connman_service *service, char *ns) +static int nameserver_remove(struct connman_service *service, + const char *nameserver) { - int family; - - family = connman_inet_check_ipaddress(ns); + int index; - if (family == AF_INET) - return is_connected_state(service, service->state_ipv4); + if (!nameserver_available(service, nameserver)) + return 0; - if (family == AF_INET6) - return is_connected_state(service, service->state_ipv6); + index = __connman_service_get_index(service); + if (index < 0) + return -ENXIO; - return false; + return connman_resolver_remove(index, NULL, nameserver); } -static void update_nameservers(struct connman_service *service) +static int nameserver_remove_all(struct connman_service *service) { - int index; - char *ns; +#if defined TIZEN_EXT + /** + * Skip this function if there is any connected profiles + * that use same interface + */ + if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR && + __connman_service_get_connected_count_of_iface(service) > 0) + return 0; +#endif + int index, i = 0; index = __connman_service_get_index(service); if (index < 0) - return; + return -ENXIO; - switch (combine_state(service->state_ipv4, service->state_ipv6)) { - case CONNMAN_SERVICE_STATE_UNKNOWN: - case CONNMAN_SERVICE_STATE_IDLE: - case CONNMAN_SERVICE_STATE_ASSOCIATION: - case CONNMAN_SERVICE_STATE_CONFIGURATION: - return; - case CONNMAN_SERVICE_STATE_FAILURE: - case CONNMAN_SERVICE_STATE_DISCONNECT: - connman_resolver_remove_all(index); - return; - case CONNMAN_SERVICE_STATE_READY: - case CONNMAN_SERVICE_STATE_ONLINE: - break; + while (service->nameservers_config && service->nameservers_config[i]) { + + nameserver_remove(service, service->nameservers_config[i]); + i++; } - if (service->nameservers_config) { - int i; + i = 0; + while (service->nameservers && service->nameservers[i]) { + nameserver_remove(service, service->nameservers[i]); + i++; + } - remove_nameservers(service, index, service->nameservers); + return 0; +} + +static int searchdomain_add_all(struct connman_service *service) +{ + int index, i = 0; - i = g_strv_length(service->nameservers_config); - while (i != 0) { - i--; + if (!is_connected(service)) + return -ENOTCONN; - ns = service->nameservers_config[i]; + index = __connman_service_get_index(service); + if (index < 0) + return -ENXIO; - if (nameserver_available(service, ns)) - connman_resolver_append(index, NULL, ns); + if (service->domains) { + while (service->domains[i]) { + connman_resolver_append(index, service->domains[i], + NULL); + i++; } - } else if (service->nameservers) { - int i; - remove_nameservers(service, index, service->nameservers); + return 0; + } - i = g_strv_length(service->nameservers); - while (i != 0) { - i--; + if (service->domainname) + connman_resolver_append(index, service->domainname, NULL); - ns = service->nameservers[i]; + return 0; - if (nameserver_available(service, ns)) - connman_resolver_append(index, NULL, ns); - } - } +} - if (service->domains) { - char *searchdomains[2] = {NULL, NULL}; - int i; +static int searchdomain_remove_all(struct connman_service *service) +{ + int index, i = 0; - searchdomains[0] = service->domainname; - remove_searchdomains(service, index, searchdomains); + if (!is_connected(service)) + return -ENOTCONN; - i = g_strv_length(service->domains); - while (i != 0) { - i--; - connman_resolver_append(index, service->domains[i], - NULL); - } - } else if (service->domainname) - connman_resolver_append(index, service->domainname, NULL); + index = __connman_service_get_index(service); + if (index < 0) + return -ENXIO; + + while (service->domains && service->domains[i]) { + connman_resolver_remove(index, service->domains[i], NULL); + i++; + } - connman_resolver_flush(); + if (service->domainname) + connman_resolver_remove(index, service->domainname, NULL); + + return 0; } /* @@ -1291,11 +1465,16 @@ int __connman_service_nameserver_append(struct connman_service *service, nameservers[len + 1] = NULL; +#if defined TIZEN_TV_EXT + if(service->dns_config_method == CONNMAN_DNSCONFIG_METHOD_UNKNOWN) + service->dns_config_method = CONNMAN_DNSCONFIG_METHOD_DHCP; +#endif + if (is_auto) { service->nameservers_auto = nameservers; } else { service->nameservers = nameservers; - update_nameservers(service); + nameserver_add(service, nameserver); } return 0; @@ -1333,13 +1512,8 @@ int __connman_service_nameserver_remove(struct connman_service *service, len = g_strv_length(nameservers); if (len == 1) { - g_strfreev(nameservers); - if (is_auto) - service->nameservers_auto = NULL; - else - service->nameservers = NULL; - - return 0; + servers = NULL; + goto set_servers; } servers = g_try_new0(char *, len); @@ -1347,15 +1521,17 @@ int __connman_service_nameserver_remove(struct connman_service *service, return -ENOMEM; for (i = 0, j = 0; i < len; i++) { - if (g_strcmp0(nameservers[i], nameserver) != 0) { - servers[j] = g_strdup(nameservers[i]); - if (!servers[j]) - return -ENOMEM; + if (g_strcmp0(nameservers[i], nameserver)) { + servers[j] = nameservers[i]; j++; - } + } else + g_free(nameservers[i]); + + nameservers[i] = NULL; } servers[len - 1] = NULL; +set_servers: g_strfreev(nameservers); nameservers = servers; @@ -1363,7 +1539,7 @@ int __connman_service_nameserver_remove(struct connman_service *service, service->nameservers_auto = nameservers; } else { service->nameservers = nameservers; - update_nameservers(service); + nameserver_remove(service, nameserver); } return 0; @@ -1371,10 +1547,12 @@ int __connman_service_nameserver_remove(struct connman_service *service, void __connman_service_nameserver_clear(struct connman_service *service) { + nameserver_remove_all(service); + g_strfreev(service->nameservers); service->nameservers = NULL; - update_nameservers(service); + nameserver_add_all(service); } static void add_nameserver_route(int family, int index, char *nameserver, @@ -1402,14 +1580,18 @@ static void add_nameserver_route(int family, int index, char *nameserver, static void nameserver_add_routes(int index, char **nameservers, const char *gw) { - int i, family; + int i, ns_family, gw_family; + + gw_family = connman_inet_check_ipaddress(gw); + if (gw_family < 0) + return; for (i = 0; nameservers[i]; i++) { - family = connman_inet_check_ipaddress(nameservers[i]); - if (family < 0) + ns_family = connman_inet_check_ipaddress(nameservers[i]); + if (ns_family < 0 || ns_family != gw_family) continue; - add_nameserver_route(family, index, nameservers[i], gw); + add_nameserver_route(ns_family, index, nameservers[i], gw); } } @@ -1674,9 +1856,15 @@ static void default_changed(void) current_default ? current_default->identifier : ""); DBG("new default %p %s", service, service ? service->identifier : ""); +#if defined TIZEN_EXT + current_default = service; + + __connman_service_timeserver_changed(service, NULL); +#else __connman_service_timeserver_changed(current_default, NULL); current_default = service; +#endif if (service) { if (service->hostname && @@ -1896,6 +2084,15 @@ static void append_dns(DBusMessageIter *iter, void *user_data) if (!is_connected(service)) return; +#if defined TIZEN_TV_EXT + /* Append DNS Config Type */ + const char *str; + str = __connman_dnsconfig_method2string(service->dns_config_method); + if(str != NULL) + dbus_message_iter_append_basic(iter, + DBUS_TYPE_STRING, &str); +#endif + if (service->nameservers_config) { append_nameservers(iter, service, service->nameservers_config); return; @@ -1924,6 +2121,15 @@ static void append_dnsconfig(DBusMessageIter *iter, void *user_data) { struct connman_service *service = user_data; +#if defined TIZEN_TV_EXT + /* Append DNS Config Type */ + const char *str; + str = __connman_dnsconfig_method2string(service->dns_config_method); + if(str != NULL) + dbus_message_iter_append_basic(iter, + DBUS_TYPE_STRING, &str); +#endif + if (!service->nameservers_config) return; @@ -2543,6 +2749,13 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited, connman_dbus_dict_append_basic(dict, "State", DBUS_TYPE_STRING, &str); +#if defined TIZEN_TV_EXT + str = state2string(service->state_ipv6); + if (str != NULL) + connman_dbus_dict_append_basic(dict, "StateIPv6", + DBUS_TYPE_STRING, &str); +#endif + str = error2string(service->error); if (str) connman_dbus_dict_append_basic(dict, "Error", @@ -3213,7 +3426,6 @@ int __connman_service_set_passphrase(struct connman_service *service, if (service->network) connman_network_set_string(service->network, "WiFi.Passphrase", service->passphrase); - service_save(service); return 0; } @@ -3226,16 +3438,6 @@ const char *__connman_service_get_passphrase(struct connman_service *service) return service->passphrase; } -static void clear_passphrase(struct connman_service *service) -{ - g_free(service->passphrase); - service->passphrase = NULL; - - if (service->network) - connman_network_set_string(service->network, "WiFi.Passphrase", - service->passphrase); -} - static DBusMessage *get_properties(DBusConnection *conn, DBusMessage *msg, void *user_data) { @@ -3598,6 +3800,18 @@ static DBusMessage *set_property(DBusConnection *conn, const char *val; dbus_message_iter_get_basic(&entry, &val); dbus_message_iter_next(&entry); +#if defined TIZEN_TV_EXT + /* First unpack the DNS Config Method */ + if(g_strcmp0(val, "manual") == 0) { + service->dns_config_method = + CONNMAN_DNSCONFIG_METHOD_MANUAL; + continue; + } else if(g_strcmp0(val, "dhcp") == 0) { + service->dns_config_method = + CONNMAN_DNSCONFIG_METHOD_DHCP; + continue; + } +#endif if (connman_inet_check_ipaddress(val) > 0) { if (str->len > 0) g_string_append_printf(str, " %s", val); @@ -3606,7 +3820,7 @@ static DBusMessage *set_property(DBusConnection *conn, } } - remove_nameservers(service, -1, service->nameservers_config); + nameserver_remove_all(service); g_strfreev(service->nameservers_config); if (str->len > 0) { @@ -3621,7 +3835,7 @@ static DBusMessage *set_property(DBusConnection *conn, if (gw && strlen(gw)) __connman_service_nameserver_add_routes(service, gw); - update_nameservers(service); + nameserver_add_all(service); dns_configuration_changed(service); if (__connman_service_is_connected_state(service, @@ -3708,7 +3922,7 @@ static DBusMessage *set_property(DBusConnection *conn, g_string_append(str, val); } - remove_searchdomains(service, -1, service->domains); + searchdomain_remove_all(service); g_strfreev(service->domains); if (str->len > 0) @@ -3718,7 +3932,7 @@ static DBusMessage *set_property(DBusConnection *conn, g_string_free(str, TRUE); - update_nameservers(service); + searchdomain_add_all(service); domain_configuration_changed(service); domain_changed(service); @@ -3771,10 +3985,13 @@ static DBusMessage *set_property(DBusConnection *conn, if (err < 0) { if (is_connected_state(service, state) || - is_connecting_state(service, state)) - __connman_network_set_ipconfig(service->network, - service->ipconfig_ipv4, - service->ipconfig_ipv6); + is_connecting_state(service, state)) { + __connman_network_enable_ipconfig(service->network, + service->ipconfig_ipv4); + __connman_network_enable_ipconfig(service->network, + service->ipconfig_ipv6); + } + return __connman_error_failed(msg, -err); } @@ -3783,10 +4000,12 @@ static DBusMessage *set_property(DBusConnection *conn, else ipv6_configuration_changed(service); - if (is_connecting(service) || is_connected(service)) - __connman_network_set_ipconfig(service->network, - service->ipconfig_ipv4, - service->ipconfig_ipv6); + if (is_connecting(service) || is_connected(service)) { + __connman_network_enable_ipconfig(service->network, + service->ipconfig_ipv4); + __connman_network_enable_ipconfig(service->network, + service->ipconfig_ipv6); + } service_save(service); } else @@ -3808,14 +4027,14 @@ static void set_error(struct connman_service *service, if (!service->path) return; + if (!allow_property_changed(service)) + return; + str = error2string(service->error); if (!str) str = ""; - if (!allow_property_changed(service)) - return; - connman_dbus_property_changed_basic(service->path, CONNMAN_SERVICE_INTERFACE, "Error", DBUS_TYPE_STRING, &str); @@ -4027,6 +4246,20 @@ static bool auto_connect_service(GList *services, continue; } +#if defined TIZEN_EXT + DBG("service %p %s %s %s, favorite(%d), ignore(%d), hidden(%d, %d)", + service, service->name, + state2string(service->state), + __connman_service_type2string(service->type), + service->favorite, is_ignore(service), + service->hidden, service->hidden_service); + + /* Tizen takes Wi-Fi as the highest priority into consideration. */ + if (service->type != CONNMAN_SERVICE_TYPE_WIFI) + if (is_connecting(service) == TRUE || is_connected(service) == TRUE) + continue; +#endif + if (service->pending || is_connecting(service) || is_connected(service)) { @@ -4492,10 +4725,12 @@ static DBusMessage *remove_service(DBusConnection *conn, return __connman_error_permission_denied(msg); } +#if !defined TIZEN_EXT if (!connman_service_is_user_allowed(service, uid)) { DBG("Not allow this user to remove this wifi service now!"); return __connman_error_permission_denied(msg); } +#endif } if (!__connman_service_remove(service)) @@ -5334,6 +5569,11 @@ bool __connman_service_is_connected_state(struct connman_service *service, return is_connected_state(service, service->state_ipv4); case CONNMAN_IPCONFIG_TYPE_IPV6: return is_connected_state(service, service->state_ipv6); + case CONNMAN_IPCONFIG_TYPE_ALL: + return is_connected_state(service, + CONNMAN_IPCONFIG_TYPE_IPV4) && + is_connected_state(service, + CONNMAN_IPCONFIG_TYPE_IPV6); } return false; @@ -5531,32 +5771,14 @@ void __connman_service_set_string(struct connman_service *service, void __connman_service_set_search_domains(struct connman_service *service, char **domains) { - int index; - - index = __connman_service_get_index(service); - if (index < 0) - return; + searchdomain_remove_all(service); - if (service->domains) { - remove_searchdomains(service, index, service->domains); + if (service->domains) g_strfreev(service->domains); - service->domains = g_strdupv(domains); - - update_nameservers(service); - } -} - -/* - * This variant is used when domain search list is updated via - * dhcp and in that case the service is not yet fully connected so - * we cannot do same things as what the set() variant is doing. - */ -void __connman_service_update_search_domains(struct connman_service *service, - char **domains) -{ - g_strfreev(service->domains); service->domains = g_strdupv(domains); + + searchdomain_add_all(service); } #if defined TIZEN_EXT @@ -5635,6 +5857,34 @@ static int check_wpspin(struct connman_service *service, const char *wpspin) return 0; } +#if defined TIZEN_EXT +static int __connman_service_connect_hidden(struct connman_service *service, + const char *name, int name_len, + const char *identity, const char *passphrase, void *user_data) +{ + GList *list; + + for (list = service_list; list; list = list->next) { + struct connman_service *target = list->data; + const char *target_ssid = NULL; + unsigned int target_ssid_len = 0; + + if (service->network != NULL && + service->security == target->security) { + target_ssid = connman_network_get_blob(service->network, + "WiFi.SSID", &target_ssid_len); + if (target_ssid_len == name_len && + memcmp(target_ssid, name, name_len) == 0) { + return connman_network_connect_hidden(service->network, + (char *)identity, (char *)passphrase, user_data); + } + } + } + + return -ENOENT; +} +#endif + static void request_input_cb(struct connman_service *service, bool values_received, const char *name, int name_len, @@ -5667,6 +5917,14 @@ static void request_input_cb(struct connman_service *service, } if (service->hidden && name_len > 0 && name_len <= 32) { +#if defined TIZEN_EXT + /* TIZEN already has Wi-Fi hidden scan before this hidden connection */ + err = __connman_service_connect_hidden(service, name, name_len, + identity, passphrase, user_data); + if (err == 0 || err == -EALREADY || err == -EINPROGRESS) + return; +#endif + device = connman_network_get_device(service->network); security = connman_network_get_string(service->network, "WiFi.Security"); @@ -5978,6 +6236,10 @@ static int service_indicate_state(struct connman_service *service) if (old_state == CONNMAN_SERVICE_STATE_ONLINE) __connman_notifier_leave_online(service->type); + if (is_connected_state(service, old_state) && + !is_connected_state(service, new_state)) + searchdomain_remove_all(service); + service->state = new_state; state_changed(service); @@ -6012,6 +6274,8 @@ static int service_indicate_state(struct connman_service *service) break; case CONNMAN_SERVICE_STATE_READY: + set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN); + if (service->new_service && __connman_stats_service_register(service) == 0) { /* @@ -6040,6 +6304,7 @@ static int service_indicate_state(struct connman_service *service) g_get_current_time(&service->modified); service_save(service); + searchdomain_add_all(service); dns_changed(service); domain_changed(service); proxy_changed(service); @@ -6078,6 +6343,7 @@ static int service_indicate_state(struct connman_service *service) break; case CONNMAN_SERVICE_STATE_DISCONNECT: + set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN); reply_pending(service, ECONNABORTED); @@ -6134,9 +6400,6 @@ static int service_indicate_state(struct connman_service *service) break; } - if (new_state != CONNMAN_SERVICE_STATE_FAILURE) - set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN); - service_list_sort(); #if defined TIZEN_EXT @@ -6182,17 +6445,10 @@ int __connman_service_indicate_error(struct connman_service *service, if (!service) return -EINVAL; - set_error(service, error); - - /* - * Supplicant does not always return invalid key error for - * WPA-EAP so clear the credentials always. - */ - if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY || - service->security == CONNMAN_SERVICE_SECURITY_8021X) - clear_passphrase(service); + if (service->state == CONNMAN_SERVICE_STATE_FAILURE) + return -EALREADY; - __connman_service_set_agent_identity(service, NULL); + set_error(service, error); __connman_service_ipconfig_indicate_state(service, CONNMAN_SERVICE_STATE_FAILURE, @@ -6396,7 +6652,7 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, enum connman_ipconfig_type type) { struct connman_ipconfig *ipconfig = NULL; - enum connman_service_state *old_state; + enum connman_service_state old_state; enum connman_ipconfig_method method; if (!service) @@ -6404,16 +6660,17 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, switch (type) { case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + case CONNMAN_IPCONFIG_TYPE_ALL: return -EINVAL; case CONNMAN_IPCONFIG_TYPE_IPV4: - old_state = &service->state_ipv4; + old_state = service->state_ipv4; ipconfig = service->ipconfig_ipv4; break; case CONNMAN_IPCONFIG_TYPE_IPV6: - old_state = &service->state_ipv6; + old_state = service->state_ipv6; ipconfig = service->ipconfig_ipv6; break; @@ -6423,7 +6680,7 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, return -EINVAL; /* Any change? */ - if (*old_state == new_state) + if (old_state == new_state) return -EALREADY; #if defined TIZEN_EXT @@ -6440,7 +6697,7 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, DBG("service %p (%s) old state %d (%s) new state %d (%s) type %d (%s)", service, service ? service->identifier : NULL, - *old_state, state2string(*old_state), + old_state, state2string(old_state), new_state, state2string(new_state), type, __connman_ipconfig_type2string(type)); @@ -6496,16 +6753,25 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, break; case CONNMAN_IPCONFIG_METHOD_FIXED: - case CONNMAN_IPCONFIG_METHOD_MANUAL: - case CONNMAN_IPCONFIG_METHOD_DHCP: - case CONNMAN_IPCONFIG_METHOD_AUTO: + case CONNMAN_IPCONFIG_METHOD_MANUAL: + case CONNMAN_IPCONFIG_METHOD_DHCP: + case CONNMAN_IPCONFIG_METHOD_AUTO: break; } - *old_state = new_state; + if (is_connected_state(service, old_state) && + !is_connected_state(service, new_state)) + nameserver_remove_all(service); - update_nameservers(service); + if (type == CONNMAN_IPCONFIG_TYPE_IPV4) + service->state_ipv4 = new_state; + else + service->state_ipv6 = new_state; + + if (!is_connected_state(service, old_state) && + is_connected_state(service, new_state)) + nameserver_add_all(service); return service_indicate_state(service); } @@ -6603,6 +6869,9 @@ static int service_connect(struct connman_service *service) case CONNMAN_SERVICE_SECURITY_PSK: case CONNMAN_SERVICE_SECURITY_WPA: case CONNMAN_SERVICE_SECURITY_RSN: + if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY) + return -ENOKEY; + if (service->request_passphrase_input) { DBG("Now try to connect other user's favorite service"); service->request_passphrase_input = false; @@ -6644,9 +6913,10 @@ static int service_connect(struct connman_service *service) * missing. Agent provided credentials can be used as * fallback if needed. */ - if ((!service->identity && + if (((!service->identity && !service->agent_identity) || - !service->passphrase) + !service->passphrase) || + service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY) return -ENOKEY; break; @@ -6741,16 +7011,14 @@ int __connman_service_connect(struct connman_service *service, err = service_connect(service); service->connect_reason = reason; - if (err >= 0) { - set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN); + if (err >= 0) return 0; - } if (err == -EINPROGRESS) { if (service->timeout == 0) service->timeout = g_timeout_add_seconds( CONNECT_TIMEOUT, connect_timeout, service); - set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN); + return -EINPROGRESS; } @@ -7541,8 +7809,45 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne if (service->favorite) { device = connman_network_get_device(service->network); - if (device && !connman_device_get_scanning(device)) - __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO); + if (device && !connman_device_get_scanning(device)) { + + switch (service->type) { + case CONNMAN_SERVICE_TYPE_UNKNOWN: + case CONNMAN_SERVICE_TYPE_SYSTEM: + case CONNMAN_SERVICE_TYPE_P2P: + break; + + case CONNMAN_SERVICE_TYPE_GADGET: + case CONNMAN_SERVICE_TYPE_ETHERNET: + if (service->autoconnect) { + __connman_service_connect(service, + CONNMAN_SERVICE_CONNECT_REASON_AUTO); + break; + } + + /* fall through */ + case CONNMAN_SERVICE_TYPE_BLUETOOTH: + case CONNMAN_SERVICE_TYPE_GPS: + case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_WIFI: + case CONNMAN_SERVICE_TYPE_CELLULAR: + __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO); + break; + } + } + +#if defined TIZEN_EXT + /* TIZEN synchronizes below information when the service creates */ + if (service->eap != NULL) + connman_network_set_string(service->network, "WiFi.EAP", + service->eap); + if (service->identity != NULL) + connman_network_set_string(service->network, "WiFi.Identity", + service->identity); + if (service->phase2 != NULL) + connman_network_set_string(service->network, "WiFi.Phase2", + service->phase2); +#endif } __connman_notifier_service_add(service, service->name); diff --git a/src/session.c b/src/session.c index 08facc1d..08facc1d 100644..100755 --- a/src/session.c +++ b/src/session.c diff --git a/src/shared/netlink.c b/src/shared/netlink.c index b32ab854..b32ab854 100644..100755 --- a/src/shared/netlink.c +++ b/src/shared/netlink.c diff --git a/src/shared/netlink.h b/src/shared/netlink.h index 62bb3e01..62bb3e01 100644..100755 --- a/src/shared/netlink.h +++ b/src/shared/netlink.h diff --git a/src/shared/sha1.c b/src/shared/sha1.c deleted file mode 100644 index e67b020d..00000000 --- a/src/shared/sha1.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * - * Connection Manager - * - * Copyright (C) 2012 Intel Corporation. All rights reserved. - * - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <glib.h> - -#include "src/shared/sha1.h" - -#define SHA1_MAC_LEN 20 - -static void __hmac_sha1(GChecksum *checksum, const void *key, size_t key_len, - const void *data, size_t data_len, void *output) -{ - unsigned char ipad[64]; - unsigned char opad[64]; - unsigned char digest[SHA1_MAC_LEN]; - size_t length; - int i; - - /* if key is longer than 64 bytes reset it to key=SHA1(key) */ - if (key_len > 64) { - g_checksum_update(checksum, key, key_len); - length = sizeof(digest); - g_checksum_get_digest(checksum, digest, &length); - - g_checksum_reset(checksum); - - key = digest; - key_len = SHA1_MAC_LEN; - } - - /* start out by storing key in pads */ - memset(ipad, 0, sizeof(ipad)); - memset(opad, 0, sizeof(opad)); - memcpy(ipad, key, key_len); - memcpy(opad, key, key_len); - - /* XOR key with ipad and opad values */ - for (i = 0; i < 64; i++) { - ipad[i] ^= 0x36; - opad[i] ^= 0x5c; - } - - /* perform inner SHA1 */ - g_checksum_update(checksum, ipad, sizeof(ipad)); - g_checksum_update(checksum, data, data_len); - length = sizeof(digest); - g_checksum_get_digest(checksum, digest, &length); - - g_checksum_reset(checksum); - - /* perform outer SHA1 */ - g_checksum_update(checksum, opad, sizeof(opad)); - g_checksum_update(checksum, digest, length); - length = sizeof(digest); - g_checksum_get_digest(checksum, output, &length); - - g_checksum_reset(checksum); -} - -int hmac_sha1(const void *key, size_t key_len, - const void *data, size_t data_len, void *output, size_t size) -{ - GChecksum *checksum; - - checksum = g_checksum_new(G_CHECKSUM_SHA1); - - __hmac_sha1(checksum, key, key_len, data, data_len, output); - - g_checksum_free(checksum); - - return 0; -} - -static void F(GChecksum *checksum, const char *password, size_t password_len, - const char *salt, size_t salt_len, - unsigned int iterations, unsigned int count, - unsigned char *digest) -{ - unsigned char tmp1[SHA1_MAC_LEN]; - unsigned char tmp2[SHA1_MAC_LEN]; - unsigned char buf[36]; - unsigned int i, j; - - memcpy(buf, salt, salt_len); - buf[salt_len + 0] = (count >> 24) & 0xff; - buf[salt_len + 1] = (count >> 16) & 0xff; - buf[salt_len + 2] = (count >> 8) & 0xff; - buf[salt_len + 3] = count & 0xff; - - __hmac_sha1(checksum, password, password_len, - buf, salt_len + 4, tmp1); - memcpy(digest, tmp1, SHA1_MAC_LEN); - - for (i = 1; i < iterations; i++) { - __hmac_sha1(checksum, password, password_len, - tmp1, SHA1_MAC_LEN, tmp2); - memcpy(tmp1, tmp2, SHA1_MAC_LEN); - - for (j = 0; j < SHA1_MAC_LEN; j++) - digest[j] ^= tmp2[j]; - } -} - -int pbkdf2_sha1(const void *password, size_t password_len, - const void *salt, size_t salt_len, - unsigned int iterations, void *output, size_t size) -{ - GChecksum *checksum; - unsigned char *ptr = output; - unsigned char digest[SHA1_MAC_LEN]; - unsigned int i; - - checksum = g_checksum_new(G_CHECKSUM_SHA1); - - for (i = 1; size > 0; i++) { - size_t len; - - F(checksum, password, password_len, salt, salt_len, - iterations, i, digest); - - len = size > SHA1_MAC_LEN ? SHA1_MAC_LEN : size; - memcpy(ptr, digest, len); - - ptr += len; - size -= len; - } - - g_checksum_free(checksum); - - return 0; -} - -int prf_sha1(const void *key, size_t key_len, - const void *prefix, size_t prefix_len, - const void *data, size_t data_len, void *output, size_t size) -{ - GChecksum *checksum; - unsigned char input[1024]; - size_t input_len; - unsigned int i, offset = 0; - - checksum = g_checksum_new(G_CHECKSUM_SHA1); - - memcpy(input, prefix, prefix_len); - input[prefix_len] = 0; - - memcpy(input + prefix_len + 1, data, data_len); - input[prefix_len + 1 + data_len] = 0; - - input_len = prefix_len + 1 + data_len + 1; - - for (i = 0; i < (size + 19) / 20; i++) { - __hmac_sha1(checksum, key, key_len, input, input_len, - output + offset); - - offset += 20; - input[input_len - 1]++; - } - - g_checksum_free(checksum); - - return 0; -} diff --git a/src/shared/sha1.h b/src/shared/sha1.h deleted file mode 100644 index 0c0c6d19..00000000 --- a/src/shared/sha1.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * Connection Manager - * - * Copyright (C) 2012 Intel Corporation. All rights reserved. - * - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -int hmac_sha1(const void *key, size_t key_len, - const void *data, size_t data_len, void *output, size_t size); - -int pbkdf2_sha1(const void *password, size_t password_len, - const void *salt, size_t salt_len, - unsigned int iterations, void *output, size_t size); - -int prf_sha1(const void *key, size_t key_len, - const void *prefix, size_t prefix_len, - const void *data, size_t data_len, void *output, size_t size); diff --git a/src/shared/util.c b/src/shared/util.c index df045c5b..df045c5b 100644..100755 --- a/src/shared/util.c +++ b/src/shared/util.c diff --git a/src/shared/util.h b/src/shared/util.h index 293fb3a4..293fb3a4 100644..100755 --- a/src/shared/util.h +++ b/src/shared/util.h diff --git a/src/stats.c b/src/stats.c index 26343b13..26343b13 100644..100755 --- a/src/stats.c +++ b/src/stats.c diff --git a/src/storage.c b/src/storage.c index 7d031303..7d031303 100644..100755 --- a/src/storage.c +++ b/src/storage.c diff --git a/src/task.c b/src/task.c index 8b9e1d93..8b9e1d93 100644..100755 --- a/src/task.c +++ b/src/task.c diff --git a/src/technology.c b/src/technology.c index 15bb395d..9e00a293 100644..100755 --- a/src/technology.c +++ b/src/technology.c @@ -85,6 +85,9 @@ struct connman_technology { static GSList *driver_list = NULL; +static int technology_enabled(struct connman_technology *technology); +static int technology_disabled(struct connman_technology *technology); + static gint compare_priority(gconstpointer a, gconstpointer b) { const struct connman_technology_driver *driver1 = a; @@ -625,19 +628,27 @@ static gboolean technology_pending_reply(gpointer user_data) static int technology_affect_devices(struct connman_technology *technology, bool enable_device) { + int err = 0, err_dev; GSList *list; - int err = -ENXIO; - if (technology->type == CONNMAN_SERVICE_TYPE_P2P) + if (technology->type == CONNMAN_SERVICE_TYPE_P2P) { + if (enable_device) + __connman_technology_enabled(technology->type); + else + __connman_technology_disabled(technology->type); return 0; + } for (list = technology->device_list; list; list = list->next) { struct connman_device *device = list->data; if (enable_device) - err = __connman_device_enable(device); + err_dev = __connman_device_enable(device); else - err = __connman_device_disable(device); + err_dev = __connman_device_disable(device); + + if (err_dev < 0 && err_dev != -EALREADY) + err = err_dev; } return err; @@ -1252,13 +1263,6 @@ static struct connman_technology *technology_get(enum connman_service_type type) technology->tethering_hidden = FALSE; technology->path = g_strdup_printf("%s/technology/%s", CONNMAN_PATH, str); - if (type == CONNMAN_SERVICE_TYPE_P2P) { - struct connman_technology *wifi; - - wifi = technology_find(CONNMAN_SERVICE_TYPE_WIFI); - if (wifi) - technology->enabled = wifi->enabled; - } technology_load(technology); technology_list = g_slist_prepend(technology_list, technology); @@ -1277,7 +1281,20 @@ static struct connman_technology *technology_get(enum connman_service_type type) return NULL; } - DBG("technology %p", technology); + if (type == CONNMAN_SERVICE_TYPE_P2P) { + struct connman_technology *wifi; + bool enable; + + enable = technology->enable_persistent; + + wifi = technology_find(CONNMAN_SERVICE_TYPE_WIFI); + if (enable && wifi) + enable = wifi->enabled; + + technology_affect_devices(technology, enable); + } + + DBG("technology %p %s", technology, get_name(technology->type)); return technology; } @@ -1865,6 +1882,12 @@ void __connman_technology_cleanup(void) { DBG(""); + while (technology_list) { + struct connman_technology *technology = technology_list->data; + technology_list = g_slist_remove(technology_list, technology); + technology_put(technology); + } + g_hash_table_destroy(rfkill_list); dbus_connection_unref(connection); diff --git a/src/tethering.c b/src/tethering.c index c0c97431..c0c97431 100644..100755 --- a/src/tethering.c +++ b/src/tethering.c diff --git a/src/timeserver.c b/src/timeserver.c index f0d33e5e..f0d33e5e 100644..100755 --- a/src/timeserver.c +++ b/src/timeserver.c diff --git a/src/timezone.c b/src/timezone.c index e346b11a..e346b11a 100644..100755 --- a/src/timezone.c +++ b/src/timezone.c diff --git a/src/util.c b/src/util.c new file mode 100755 index 00000000..da32cc55 --- /dev/null +++ b/src/util.c @@ -0,0 +1,88 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2014 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <inttypes.h> +#include <stdint.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> + +#include "connman.h" + +#define URANDOM "/dev/urandom" + +int f = -1; + +int __connman_util_get_random(uint64_t *val) +{ + int r = 0; + + if (!val) + return -EINVAL; + + if (read(f, val, sizeof(uint64_t)) < 0) { + r = -errno; + connman_warn_once("Could not read from "URANDOM); + *val = random(); + } + + return r; +} + +int __connman_util_init(void) +{ + int r = 0; + + if (f > 0) + return 0; + + f = open(URANDOM, O_RDONLY); + if (f < 0) { + r = -errno; + connman_warn("Could not open "URANDOM); + srandom(time(NULL)); + } else { + uint64_t val; + + r = __connman_util_get_random(&val); + if (r < 0) + srandom(time(NULL)); + else + srandom(val); + } + + return r; +} + +void __connman_util_cleanup(void) +{ + if (f > 0) + close(f); + + f = -1; +} diff --git a/src/utsname.c b/src/utsname.c index 1dd5e0f2..1dd5e0f2 100644..100755 --- a/src/utsname.c +++ b/src/utsname.c diff --git a/src/wispr.c b/src/wispr.c index c4fcd60b..ef4bdaba 100644..100755 --- a/src/wispr.c +++ b/src/wispr.c @@ -143,6 +143,7 @@ static void free_wispr_routes(struct connman_wispr_portal_context *wp_context) route->address); break; case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + case CONNMAN_IPCONFIG_TYPE_ALL: break; } @@ -487,6 +488,7 @@ static bool wispr_route_request(const char *address, int ai_family, gateway); break; case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + case CONNMAN_IPCONFIG_TYPE_ALL: break; } diff --git a/src/wpad.c b/src/wpad.c index d40959be..d40959be 100644..100755 --- a/src/wpad.c +++ b/src/wpad.c |