char *ipv4_gateway;
char *ipv6_gateway;
- char *proxy;
char *pac;
struct connman_ipconfig *config;
free_address_list(ipdevice);
g_free(ipdevice->ipv4_gateway);
g_free(ipdevice->ipv6_gateway);
- g_free(ipdevice->proxy);
g_free(ipdevice->pac);
g_free(ipdevice->address);
return 0;
}
-void __connman_ipconfig_append_proxy(struct connman_ipconfig *ipconfig,
- DBusMessageIter *iter)
-{
- struct connman_ipdevice *ipdevice;
- const char *method = "direct";
-
- ipdevice = g_hash_table_lookup(ipdevice_hash,
- GINT_TO_POINTER(ipconfig->index));
- if (ipdevice == NULL)
- goto done;
-
- if (ipdevice->pac == NULL)
- goto done;
-
- method = "auto-config";
-
- connman_dbus_dict_append_basic(iter, "URL",
- DBUS_TYPE_STRING, &ipdevice->pac);
-
-done:
- connman_dbus_dict_append_basic(iter, "Method",
- DBUS_TYPE_STRING, &method);
-}
-
-void __connman_ipconfig_append_proxyconfig(struct connman_ipconfig *ipconfig,
- DBusMessageIter *iter)
-{
- struct connman_ipdevice *ipdevice;
- const char *method = "auto";
-
- ipdevice = g_hash_table_lookup(ipdevice_hash,
- GINT_TO_POINTER(ipconfig->index));
- if (ipdevice == NULL)
- goto done;
-
- if (ipdevice->proxy == NULL)
- goto done;
-
- method = ipdevice->proxy;
-
-done:
- connman_dbus_dict_append_basic(iter, "Method",
- DBUS_TYPE_STRING, &method);
-}
-
-int __connman_ipconfig_set_proxyconfig(struct connman_ipconfig *ipconfig,
- DBusMessageIter *array)
-{
- struct connman_ipdevice *ipdevice;
- DBusMessageIter dict;
- const char *method;
-
- DBG("ipconfig %p", ipconfig);
-
- ipdevice = g_hash_table_lookup(ipdevice_hash,
- GINT_TO_POINTER(ipconfig->index));
- if (ipdevice == NULL)
- return -ENXIO;
-
- if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
- return -EINVAL;
-
- dbus_message_iter_recurse(array, &dict);
-
- while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
- DBusMessageIter entry;
- const char *key;
- int type;
-
- dbus_message_iter_recurse(&dict, &entry);
-
- if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
- return -EINVAL;
-
- dbus_message_iter_get_basic(&entry, &key);
- dbus_message_iter_next(&entry);
-
- type = dbus_message_iter_get_arg_type(&entry);
-
- if (g_str_equal(key, "Method") == TRUE) {
- if (type != DBUS_TYPE_STRING)
- return -EINVAL;
-
- dbus_message_iter_get_basic(&entry, &method);
- if (strlen(method) == 0)
- method = NULL;
- }
-
- dbus_message_iter_next(&dict);
- }
-
- DBG("method %s", method);
-
- if (method == NULL)
- return -EINVAL;
-
- if (g_str_equal(method, "auto") == FALSE &&
- g_str_equal(method, "direct") == FALSE)
- return -EINVAL;
-
- g_free(ipdevice->proxy);
- ipdevice->proxy = g_strdup(method);
-
- return 0;
-}
-
void __connman_ipconfig_append_ethernet(struct connman_ipconfig *ipconfig,
DBusMessageIter *iter)
{
struct connman_stats stats;
struct connman_stats stats_roaming;
GHashTable *counter_table;
+ enum connman_service_proxy_method proxy;
+ char **proxies;
+ char **excludes;
+ char *pac;
};
static void append_path(gpointer value, gpointer user_data)
return CONNMAN_SERVICE_ERROR_UNKNOWN;
}
+static const char *proxymethod2string(enum connman_service_proxy_method method)
+{
+ switch (method) {
+ case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
+ return "direct";
+ case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
+ return "manual";
+ case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
+ return "auto";
+ case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
+ break;
+ }
+
+ return NULL;
+}
+
+static enum connman_service_proxy_method string2proxymethod(const char *method)
+{
+ if (g_strcmp0(method, "direct") == 0)
+ return CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
+ else if (g_strcmp0(method, "auto") == 0)
+ return CONNMAN_SERVICE_PROXY_METHOD_AUTO;
+ else if (g_strcmp0(method, "manual") == 0)
+ return CONNMAN_SERVICE_PROXY_METHOD_MANUAL;
+ else
+ return CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
+}
+
static connman_bool_t is_connecting(struct connman_service *service)
{
switch (service->state) {
DBUS_TYPE_STRING, &service->domains[i]);
}
+static void append_proxies(DBusMessageIter *iter, void *user_data)
+{
+ struct connman_service *service = user_data;
+ int i;
+
+ if (service->proxies == NULL)
+ return;
+
+ for (i = 0; service->proxies[i]; i++)
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &service->proxies[i]);
+}
+
+static void append_excludes(DBusMessageIter *iter, void *user_data)
+{
+ struct connman_service *service = user_data;
+ int i;
+
+ if (service->excludes == NULL)
+ return;
+
+ for (i = 0; service->excludes[i]; i++)
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &service->excludes[i]);
+}
+
static void append_proxy(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
+ const char *pac = NULL;
+ const char *method = proxymethod2string(
+ CONNMAN_SERVICE_PROXY_METHOD_DIRECT);
+
+ DBG("");
if (is_connected(service) == FALSE)
return;
- if (service->ipconfig != NULL)
- __connman_ipconfig_append_proxy(service->ipconfig, iter);
+ switch (service->proxy) {
+ case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
+ service->proxy = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
+ /* fall through */
+ case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
+ goto done;
+ case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
+ connman_dbus_dict_append_array(iter, "Servers",
+ DBUS_TYPE_STRING, append_proxies,
+ service);
+
+ connman_dbus_dict_append_array(iter, "Excludes",
+ DBUS_TYPE_STRING, append_excludes,
+ service);
+ break;
+ case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
+ /* Maybe DHCP, or WPAD, has provided an url for a pac file */
+ if (service->ipconfig != NULL)
+ pac = __connman_ipconfig_get_proxy_autoconfig(
+ service->ipconfig);
+
+ if (service->pac == NULL && pac == NULL)
+ goto done;
+
+ if (service->pac != NULL)
+ pac = service->pac;
+
+ connman_dbus_dict_append_basic(iter, "URL",
+ DBUS_TYPE_STRING, &pac);
+ break;
+ }
+
+ method = proxymethod2string(service->proxy);
+
+done:
+ connman_dbus_dict_append_basic(iter, "Method",
+ DBUS_TYPE_STRING, &method);
}
static void append_proxyconfig(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
+ const char *method;
- if (service->ipconfig != NULL)
- __connman_ipconfig_append_proxyconfig(service->ipconfig, iter);
+ switch (service->proxy) {
+ case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
+ break;
+ case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
+ if (service->proxies != NULL)
+ connman_dbus_dict_append_array(iter, "Servers",
+ DBUS_TYPE_STRING,
+ append_proxies, service);
+
+ if (service->excludes != NULL)
+ connman_dbus_dict_append_array(iter, "Excludes",
+ DBUS_TYPE_STRING,
+ append_excludes, service);
+ break;
+ case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
+ if (service->pac != NULL)
+ connman_dbus_dict_append_basic(iter, "URL",
+ DBUS_TYPE_STRING, &service->pac);
+ break;
+ case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
+ service->proxy = CONNMAN_SERVICE_PROXY_METHOD_AUTO;
+ break;
+ }
+
+ method = proxymethod2string(service->proxy);
+
+ connman_dbus_dict_append_basic(iter, "Method",
+ DBUS_TYPE_STRING, &method);
}
static void append_provider(DBusMessageIter *iter, void *user_data)
return reply;
}
+static int update_proxy_configuration(struct connman_service *service,
+ DBusMessageIter *array)
+{
+ DBusMessageIter dict;
+ enum connman_service_proxy_method method;
+ GString *servers_str = NULL;
+ GString *excludes_str = NULL;
+ const char *url = NULL;
+
+ method = CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
+
+ dbus_message_iter_recurse(array, &dict);
+
+ while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter entry, variant;
+ const char *key;
+ int type;
+
+ dbus_message_iter_recurse(&dict, &entry);
+
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+ goto error;
+
+ dbus_message_iter_get_basic(&entry, &key);
+ dbus_message_iter_next(&entry);
+
+ if (dbus_message_iter_get_arg_type(&entry) !=
+ DBUS_TYPE_VARIANT)
+ goto error;
+
+ dbus_message_iter_recurse(&entry, &variant);
+ type = dbus_message_iter_get_arg_type(&variant);
+
+ if (g_str_equal(key, "Method") == TRUE) {
+ const char *val;
+
+ if (type != DBUS_TYPE_STRING)
+ goto error;
+
+ dbus_message_iter_get_basic(&variant, &val);
+ method = string2proxymethod(val);
+ } else if (g_str_equal(key, "URL") == TRUE) {
+ if (type != DBUS_TYPE_STRING)
+ goto error;
+
+ dbus_message_iter_get_basic(&variant, &url);
+ } else if (g_str_equal(key, "Servers") == TRUE) {
+ DBusMessageIter str_array;
+
+ if (type != DBUS_TYPE_ARRAY)
+ goto error;
+
+ servers_str = g_string_new(NULL);
+ if (servers_str == NULL)
+ goto error;
+
+ dbus_message_iter_recurse(&variant, &str_array);
+
+ while (dbus_message_iter_get_arg_type(&str_array) ==
+ DBUS_TYPE_STRING) {
+ char *val = NULL;
+
+ dbus_message_iter_get_basic(&str_array, &val);
+
+ if (servers_str->len > 0)
+ g_string_append_printf(servers_str,
+ " %s", val);
+ else
+ g_string_append(servers_str, val);
+
+ dbus_message_iter_next(&str_array);
+ }
+ } else if (g_str_equal(key, "Excludes") == TRUE) {
+ DBusMessageIter str_array;
+
+ if (type != DBUS_TYPE_ARRAY)
+ goto error;
+
+ excludes_str = g_string_new(NULL);
+ if (excludes_str == NULL)
+ goto error;
+
+ dbus_message_iter_recurse(&variant, &str_array);
+
+ while (dbus_message_iter_get_arg_type(&str_array) ==
+ DBUS_TYPE_STRING) {
+ char *val = NULL;
+
+ dbus_message_iter_get_basic(&str_array, &val);
+
+ if (excludes_str->len > 0)
+ g_string_append_printf(excludes_str,
+ " %s", val);
+ else
+ g_string_append(excludes_str, val);
+
+ dbus_message_iter_next(&str_array);
+ }
+ }
+
+ dbus_message_iter_next(&dict);
+ }
+
+ switch (method) {
+ case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
+ break;
+ case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
+ if (servers_str == NULL && service->proxies == NULL)
+ goto error;
+
+ if (servers_str != NULL) {
+ g_strfreev(service->proxies);
+
+ if (servers_str->len > 0)
+ service->proxies = g_strsplit_set(
+ servers_str->str, " ", 0);
+ else
+ service->proxies = NULL;
+ }
+
+ if (excludes_str != NULL) {
+ g_strfreev(service->excludes);
+
+ if (excludes_str->len > 0)
+ service->excludes = g_strsplit_set(
+ excludes_str->str, " ", 0);
+ else
+ service->excludes = NULL;
+ }
+
+ if (service->proxies == NULL)
+ method = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
+
+ break;
+ case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
+ g_free(service->pac);
+
+ if (url != NULL && strlen(url) > 0)
+ service->pac = g_strdup(url);
+ else
+ service->pac = NULL;
+
+ /* if we are connected:
+ - if service->pac == NULL
+ - if __connman_ipconfig_get_proxy_autoconfig(
+ service->ipconfig) == NULL
+ --> We should start WPAD */
+
+ break;
+ case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
+ goto error;
+ }
+
+ if (servers_str != NULL)
+ g_string_free(servers_str, TRUE);
+
+ if (excludes_str != NULL)
+ g_string_free(excludes_str, TRUE);
+
+ service->proxy = method;
+
+ return 0;
+
+error:
+ if (servers_str != NULL)
+ g_string_free(servers_str, TRUE);
+
+ if (excludes_str != NULL)
+ g_string_free(excludes_str, TRUE);
+
+ return -EINVAL;
+}
+
static DBusMessage *set_property(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
} else if (g_str_equal(name, "Proxy.Configuration") == TRUE) {
int err;
- if (service->ipconfig == NULL)
- return __connman_error_invalid_property(msg);
+ if (type != DBUS_TYPE_ARRAY)
+ return __connman_error_invalid_arguments(msg);
+
+ err = update_proxy_configuration(service, &value);
- err = __connman_ipconfig_set_proxyconfig(service->ipconfig,
- &value);
if (err < 0)
return __connman_error_failed(msg, -err);
g_strfreev(service->nameservers);
g_strfreev(service->domains);
+ g_strfreev(service->proxies);
+ g_strfreev(service->excludes);
g_free(service->nameserver);
g_free(service->domainname);
+ g_free(service->pac);
g_free(service->mcc);
g_free(service->mnc);
g_free(service->apn);
service->domains = NULL;
}
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "Proxy.Method", NULL);
+ service->proxy = string2proxymethod(str);
+
+ service->proxies = g_key_file_get_string_list(keyfile,
+ service->identifier, "Proxy.Servers", &length, NULL);
+ if (service->proxies != NULL && length == 0) {
+ g_strfreev(service->proxies);
+ service->proxies = NULL;
+ }
+
+ service->excludes = g_key_file_get_string_list(keyfile,
+ service->identifier, "Proxy.Excludes", &length, NULL);
+ if (service->excludes != NULL && length == 0) {
+ g_strfreev(service->excludes);
+ service->excludes = NULL;
+ }
+
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "Proxy.URL", NULL);
+ if (str != NULL) {
+ g_free(service->pac);
+ service->pac = str;
+ }
+
done:
g_key_file_free(keyfile);
gchar *pathname, *data = NULL;
gsize length;
gchar *str;
+ const char *cst_str = NULL;
int err = 0;
DBG("service %p", service);
g_key_file_remove_key(keyfile, service->identifier,
"Domains", NULL);
+ cst_str = proxymethod2string(service->proxy);
+ if (str != NULL)
+ g_key_file_set_string(keyfile, service->identifier,
+ "Proxy.Method", str);
+
+ if (service->proxies != NULL) {
+ guint len = g_strv_length(service->proxies);
+
+ g_key_file_set_string_list(keyfile, service->identifier,
+ "Proxy.Servers",
+ (const gchar **) service->proxies, len);
+ } else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "Proxy.Servers", NULL);
+
+ if (service->excludes != NULL) {
+ guint len = g_strv_length(service->excludes);
+
+ g_key_file_set_string_list(keyfile, service->identifier,
+ "Proxy.Excludes",
+ (const gchar **) service->excludes, len);
+ } else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "Proxy.Excludes", NULL);
+
+ if (service->pac != NULL && strlen(service->pac) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "Proxy.URL", service->pac);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "Proxy.URL", NULL);
+
data = g_key_file_to_data(keyfile, &length, NULL);
if (g_file_set_contents(pathname, data, length, NULL) == FALSE)