connman: add various upstream patches, (not yet done), setup fallback nameserver for tethering, enable tethering on boot if it was enabled before

Signed-off-by: Stephan Raue <stephan@openelec.tv>
This commit is contained in:
Stephan Raue 2013-04-24 19:13:18 +02:00
parent d5ac322fb2
commit 3733c6e5eb
12 changed files with 947 additions and 1 deletions

View File

@ -32,7 +32,9 @@ mkdir -p $INSTALL/etc/connman
cp $PKG_BUILD/src/main.conf $INSTALL/etc/connman
sed -i $INSTALL/etc/connman/main.conf \
-e "s|^# BackgroundScanning.*|BackgroundScanning = true|g" \
-e "s|^# PreferredTechnologies.*|PreferredTechnologies = ethernet,wifi,cellular|g"
-e "s|^# FallbackNameservers.*|FallbackNameservers = 8.8.8.8,8.8.4.4|g" \
-e "s|^# PreferredTechnologies.*|PreferredTechnologies = ethernet,wifi,cellular|g" \
-e "s|^# PersistentTetheringMode.*|PersistentTetheringMode = true|g"
mkdir -p $INSTALL/etc/dbus-1/system.d
cp $PKG_BUILD/src/connman.conf $INSTALL/etc/dbus-1/system.d

View File

@ -0,0 +1,27 @@
From: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Subject: [PATCH 2/6] conf: Add description of AllowEthernetTethering
Date: Tue, 23 Apr 2013 15:17:37 +0300
---
src/main.conf | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/main.conf b/src/main.conf
index 2985613..a0608d4 100644
--- a/src/main.conf
+++ b/src/main.conf
@@ -76,3 +76,12 @@
# setting enabled applications will notice more network breaks than
# normal. Default value is false.
# SingleConnectedTechnology = false
+
+# Allow ethernet technology devices to be used when tethering.
+# If this is set to true and if ethernet tethering is activated,
+# a DHCP server is started to ethernet interface. The ethernet tethered
+# device should never be connected to corporate and home networks as
+# the device might confuse other network devices and services.
+# This is a dangerous setting so the default value is false.
+# Do not activate this unless you really know what you are doing.
+# AllowEthernetTethering = false
-- 1.7.11.7

View File

@ -0,0 +1,72 @@
From: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Subject: [PATCH 3/6] main: Add support for AllowEthernetTethering configuration variable
Date: Tue, 23 Apr 2013 15:17:38 +0300
---
rc/main.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/src/main.c b/src/main.c
index a76ec3b..016e52d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -70,6 +70,7 @@ static struct {
char **blacklisted_interfaces;
connman_bool_t allow_hostname_updates;
connman_bool_t single_tech;
+ connman_bool_t allow_ethernet_tethering;
} connman_settings = {
.bg_scan = TRUE,
.pref_timeservers = NULL,
@@ -81,6 +82,7 @@ static struct {
.blacklisted_interfaces = NULL,
.allow_hostname_updates = TRUE,
.single_tech = FALSE,
+ .allow_ethernet_tethering = FALSE,
};
#define CONF_BG_SCAN "BackgroundScanning"
@@ -93,6 +95,7 @@ static struct {
#define CONF_BLACKLISTED_INTERFACES "NetworkInterfaceBlacklist"
#define CONF_ALLOW_HOSTNAME_UPDATES "AllowHostnameUpdates"
#define CONF_SINGLE_TECH "SingleConnectedTechnology"
+#define CONF_ALLOW_ETHERNET_TETHERING "AllowEthernetTethering"
static const char *supported_options[] = {
CONF_BG_SCAN,
@@ -105,6 +108,7 @@ static const char *supported_options[] = {
CONF_BLACKLISTED_INTERFACES,
CONF_ALLOW_HOSTNAME_UPDATES,
CONF_SINGLE_TECH,
+ CONF_ALLOW_ETHERNET_TETHERING,
NULL
};
@@ -327,6 +331,14 @@ static void parse_config(GKeyFile *config)
connman_settings.single_tech = boolean;
g_clear_error(&error);
+
+ boolean = g_key_file_get_boolean(config, "General",
+ CONF_ALLOW_ETHERNET_TETHERING,
+ &error);
+ if (error == NULL)
+ connman_settings.allow_ethernet_tethering = boolean;
+
+ g_clear_error(&error);
}
static int config_init(const char *file)
@@ -498,6 +510,9 @@ connman_bool_t connman_setting_get_bool(const char *key)
if (g_str_equal(key, CONF_SINGLE_TECH) == TRUE)
return connman_settings.single_tech;
+ if (g_str_equal(key, CONF_ALLOW_ETHERNET_TETHERING) == TRUE)
+ return connman_settings.allow_ethernet_tethering;
+
return FALSE;
}
-- 1.7.11.7

View File

@ -0,0 +1,86 @@
From: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Subject: [PATCH 4/6] device: Add support functions needed by ethernet tethering
Date: Tue, 23 Apr 2013 15:17:39 +0300
---
include/device.h | 3 +++
src/device.c | 43 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/include/device.h b/include/device.h
index b372821..3382575 100644
--- a/include/device.h
+++ b/include/device.h
@@ -113,6 +113,9 @@ int connman_device_set_regdom(struct connman_device *device,
void connman_device_regdom_notify(struct connman_device *device,
int result, const char *alpha2);
struct connman_device *connman_device_create_from_index(int index);
+struct connman_device *connman_device_find_by_index(int index);
+int connman_device_disconnect_service(struct connman_device *device);
+int connman_device_reconnect_service(struct connman_device *device);
struct connman_device_driver {
const char *name;
diff --git a/src/device.c b/src/device.c
index 2e0dbdc..5feeee1 100644
--- a/src/device.c
+++ b/src/device.c
@@ -647,6 +647,36 @@ int __connman_device_disconnect(struct connman_device *device)
return 0;
}
+int connman_device_disconnect_service(struct connman_device *device)
+{
+ DBG("device %p", device);
+
+ device->reconnect = FALSE;
+
+ if (device->network) {
+ struct connman_service *service =
+ connman_service_lookup_from_network(device->network);
+
+ if (service != NULL)
+ __connman_service_disconnect(service);
+ else
+ connman_network_set_connected(device->network, FALSE);
+ }
+
+ return 0;
+}
+
+int connman_device_reconnect_service(struct connman_device *device)
+{
+ DBG("device %p", device);
+
+ device->reconnect = TRUE;
+
+ __connman_service_auto_connect();
+
+ return 0;
+}
+
static void mark_network_available(gpointer key, gpointer value,
gpointer user_data)
{
@@ -1035,6 +1065,19 @@ struct connman_device *__connman_device_find_device(
return NULL;
}
+struct connman_device *connman_device_find_by_index(int index)
+{
+ GSList *list;
+
+ for (list = device_list; list != NULL; list = list->next) {
+ struct connman_device *device = list->data;
+ if (device->index == index)
+ return device;
+ }
+
+ return NULL;
+}
+
/**
* connman_device_set_regdom
* @device: device structure
-- 1.7.11.7

View File

@ -0,0 +1,49 @@
The __connman_technology_add_interface() needs to be called
after we have created the technology which is done by rtnl->newlink()
callback. If this is done the old way, the ethernet devices
will not get their interfaces set properly.
---
src/rtnl.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/rtnl.c b/src/rtnl.c
index ef7f343..e5fab88 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -406,6 +406,7 @@ static void process_newlink(unsigned short type, int index, unsigned flags,
unsigned int mtu = 0;
char ident[13], str[18];
GSList *list;
+ connman_bool_t add_interface = FALSE;
memset(&stats, 0, sizeof(stats));
if (extract_link(msg, bytes, &address, &ifname, &mtu, &operstate,
@@ -461,8 +462,7 @@ static void process_newlink(unsigned short type, int index, unsigned flags,
if (type == ARPHRD_ETHER)
read_uevent(interface);
- __connman_technology_add_interface(interface->service_type,
- interface->index, interface->name, interface->ident);
+ add_interface = TRUE;
}
for (list = rtnl_list; list; list = list->next) {
@@ -472,6 +472,16 @@ static void process_newlink(unsigned short type, int index, unsigned flags,
rtnl->newlink(type, index, flags, change);
}
+ /*
+ * The interface needs to be added after the newlink call.
+ * The newlink will create the technology when needed and
+ * __connman_technology_add_interface() expects the
+ * technology to be there already.
+ */
+ if (add_interface == TRUE)
+ __connman_technology_add_interface(interface->service_type,
+ interface->index, interface->name, interface->ident);
+
for (list = watch_list; list; list = list->next) {
struct watch_data *watch = list->data;
-- 1.7.11.7

View File

@ -0,0 +1,140 @@
From: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Subject: [PATCH 5/6] ethernet: Add tethering support
Date: Tue, 23 Apr 2013 15:17:40 +0300
ns/ethernet.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 100 insertions(+), 1 deletion(-)
diff --git a/plugins/ethernet.c b/plugins/ethernet.c
index 6a20eb2..ac5033f 100644
--- a/plugins/ethernet.c
+++ b/plugins/ethernet.c
@@ -39,6 +39,9 @@
#include <connman/inet.h>
#include <connman/rtnl.h>
#include <connman/log.h>
+#include <connman/setting.h>
+
+static connman_bool_t eth_tethering = FALSE;
struct ethernet_data {
int index;
@@ -107,7 +110,13 @@ static void add_network(struct connman_device *device,
return;
}
- connman_network_set_group(network, "cable");
+ if (eth_tethering == FALSE)
+ /*
+ * Prevent service from starting the reconnect
+ * procedure as we do not want the DHCP client
+ * to run when tethering.
+ */
+ connman_network_set_group(network, "cable");
ethernet->network = network;
}
@@ -319,11 +328,101 @@ static void eth_remove(struct connman_technology *technology)
DBG("");
}
+static GList *eth_interface_list = NULL;
+
+static void eth_add_interface(struct connman_technology *technology,
+ int index, const char *name, const char *ident)
+{
+ DBG("index %d name %s ident %s", index, name, ident);
+
+ if (g_list_find(eth_interface_list,
+ GINT_TO_POINTER((int) index)) != NULL)
+ return;
+
+ eth_interface_list = g_list_prepend(eth_interface_list,
+ (GINT_TO_POINTER((int) index)));
+}
+
+static void eth_remove_interface(struct connman_technology *technology,
+ int index)
+{
+ DBG("index %d", index);
+
+ eth_interface_list = g_list_remove(eth_interface_list,
+ GINT_TO_POINTER((int) index));
+}
+
+static void eth_enable_tethering(struct connman_technology *technology,
+ const char *bridge)
+{
+ GList *list;
+
+ for (list = eth_interface_list; list; list = list->next) {
+ int index = GPOINTER_TO_INT(list->data);
+ struct connman_device *device =
+ connman_device_find_by_index(index);
+
+ if (device != NULL)
+ connman_device_disconnect_service(device);
+
+ connman_technology_tethering_notify(technology, TRUE);
+
+ connman_inet_ifup(index);
+
+ connman_inet_add_to_bridge(index, bridge);
+
+ eth_tethering = TRUE;
+ }
+}
+
+static void eth_disable_tethering(struct connman_technology *technology,
+ const char *bridge)
+{
+ GList *list;
+
+ for (list = eth_interface_list; list; list = list->next) {
+ int index = GPOINTER_TO_INT(list->data);
+ struct connman_device *device =
+ connman_device_find_by_index(index);
+
+ connman_inet_remove_from_bridge(index, bridge);
+
+ connman_inet_ifdown(index);
+
+ connman_technology_tethering_notify(technology, FALSE);
+
+ if (device != NULL)
+ connman_device_reconnect_service(device);
+
+ eth_tethering = FALSE;
+ }
+}
+
+static int eth_set_tethering(struct connman_technology *technology,
+ const char *identifier, const char *passphrase,
+ const char *bridge, connman_bool_t enabled)
+{
+ if (connman_setting_get_bool("AllowEthernetTethering") == FALSE)
+ return 0;
+
+ DBG("bridge %s enabled %d", bridge, enabled);
+
+ if (enabled)
+ eth_enable_tethering(technology, bridge);
+ else
+ eth_disable_tethering(technology, bridge);
+
+ return 0;
+}
+
static struct connman_technology_driver eth_driver = {
.name = "ethernet",
.type = CONNMAN_SERVICE_TYPE_ETHERNET,
.probe = eth_probe,
.remove = eth_remove,
+ .add_interface = eth_add_interface,
+ .remove_interface = eth_remove_interface,
+ .set_tethering = eth_set_tethering,
};
static int ethernet_init(void)
-- 1.7.11.7

View File

@ -0,0 +1,30 @@
From: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Subject: [PATCH 6/6] technology: Check if ethernet tethering is allowed
Date: Tue, 23 Apr 2013 15:17:41 +0300
Return EOPNOTSUPP if user tries to activate ethernet tethering
and AllowEthernetTethering variable is not set in main.conf
---
src/technology.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/technology.c b/src/technology.c
index f15fbd9..62950e7 100644
--- a/src/technology.c
+++ b/src/technology.c
@@ -787,6 +787,13 @@ static DBusMessage *set_property(DBusConnection *conn,
if (type != DBUS_TYPE_BOOLEAN)
return __connman_error_invalid_arguments(msg);
+ if (technology->type == CONNMAN_SERVICE_TYPE_ETHERNET &&
+ connman_setting_get_bool("AllowEthernetTethering")
+ == FALSE) {
+ DBG("Ethernet tethering not allowed by config file");
+ return __connman_error_not_supported(msg);
+ }
+
dbus_message_iter_get_basic(&value, &tethering);
if (technology->tethering == tethering) {
-- 1.7.11.7

View File

@ -0,0 +1,23 @@
From: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Subject: [PATCH v2 1/3] conf: Add description of StartTetheringAutomatically
Date: Tue, 23 Apr 2013 15:17:43 +0300
---
src/main.conf | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/main.conf b/src/main.conf
index a0608d4..7e509f7 100644
--- a/src/main.conf
+++ b/src/main.conf
@@ -85,3 +85,8 @@
# This is a dangerous setting so the default value is false.
# Do not activate this unless you really know what you are doing.
# AllowEthernetTethering = false
+
+# Restore earlier tethering status when returning from offline mode,
+# re-enabling a technology, and after restarts and reboots.
+# Default value is false.
+# PersistentTetheringMode = false
--
1.7.11.7

View File

@ -0,0 +1,71 @@
From: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Subject: [PATCH v2 2/3] main: Add support for StartTetheringAutomatically configuration variable
Date: Tue, 23 Apr 2013 15:17:44 +0300
---
src/main.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/src/main.c b/src/main.c
index 016e52d..5e738cf 100644
--- a/src/main.c
+++ b/src/main.c
@@ -71,6 +71,7 @@ static struct {
connman_bool_t allow_hostname_updates;
connman_bool_t single_tech;
connman_bool_t allow_ethernet_tethering;
+ connman_bool_t persistent_tethering_mode;
} connman_settings = {
.bg_scan = TRUE,
.pref_timeservers = NULL,
@@ -83,6 +84,7 @@ static struct {
.allow_hostname_updates = TRUE,
.single_tech = FALSE,
.allow_ethernet_tethering = FALSE,
+ .persistent_tethering_mode = FALSE,
};
#define CONF_BG_SCAN "BackgroundScanning"
@@ -96,6 +98,7 @@ static struct {
#define CONF_ALLOW_HOSTNAME_UPDATES "AllowHostnameUpdates"
#define CONF_SINGLE_TECH "SingleConnectedTechnology"
#define CONF_ALLOW_ETHERNET_TETHERING "AllowEthernetTethering"
+#define CONF_PERSISTENT_TETHERING_MODE "PersistentTetheringMode"
static const char *supported_options[] = {
CONF_BG_SCAN,
@@ -109,6 +112,7 @@ static const char *supported_options[] = {
CONF_ALLOW_HOSTNAME_UPDATES,
CONF_SINGLE_TECH,
CONF_ALLOW_ETHERNET_TETHERING,
+ CONF_PERSISTENT_TETHERING_MODE,
NULL
};
@@ -339,6 +343,14 @@ static void parse_config(GKeyFile *config)
connman_settings.allow_ethernet_tethering = boolean;
g_clear_error(&error);
+
+ boolean = g_key_file_get_boolean(config, "General",
+ CONF_PERSISTENT_TETHERING_MODE,
+ &error);
+ if (error == NULL)
+ connman_settings.persistent_tethering_mode = boolean;
+
+ g_clear_error(&error);
}
static int config_init(const char *file)
@@ -513,6 +525,9 @@ connman_bool_t connman_setting_get_bool(const char *key)
if (g_str_equal(key, CONF_ALLOW_ETHERNET_TETHERING) == TRUE)
return connman_settings.allow_ethernet_tethering;
+ if (g_str_equal(key, CONF_PERSISTENT_TETHERING_MODE) == TRUE)
+ return connman_settings.persistent_tethering_mode;
+
return FALSE;
}
-- 1.7.11.7

View File

@ -0,0 +1,300 @@
From: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Subject: [PATCH v2 3/3] technology: Auto start tethering if enabled and configured
Date: Tue, 23 Apr 2013 15:17:45 +0300
If the user has enabled tethering autostart in main.conf, then
start tethering when technology is enabled. Tethering is only
auto activated if it was active when ConnMan was stopped.
If the user has enabled persistent tethering mode in main.conf, then
try to activate tethering when technology is re-enabled, or we are
returning from offline mode, or after the device has rebooted.
---
src/technology.c | 185 +++++++++++++++++++++++++++++++++++--------------------
1 file changed, 119 insertions(+), 66 deletions(-)
diff --git a/src/technology.c b/src/technology.c
index a6efac1..c80a553 100644
--- a/src/technology.c
+++ b/src/technology.c
@@ -60,6 +60,10 @@ struct connman_technology {
connman_bool_t connected;
connman_bool_t tethering;
+ connman_bool_t tethering_persistent; /* Tells the save status, needed
+ * as offline mode might set
+ * tethering OFF.
+ */
char *tethering_ident;
char *tethering_passphrase;
@@ -180,6 +184,69 @@ void connman_technology_driver_unregister(struct connman_technology_driver *driv
driver_list = g_slist_remove(driver_list, driver);
}
+static const char *get_name(enum connman_service_type type)
+{
+ switch (type) {
+ case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_GPS:
+ case CONNMAN_SERVICE_TYPE_VPN:
+ case CONNMAN_SERVICE_TYPE_GADGET:
+ break;
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
+ return "Wired";
+ case CONNMAN_SERVICE_TYPE_WIFI:
+ return "WiFi";
+ case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ return "Bluetooth";
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+ return "Cellular";
+ }
+
+ return NULL;
+}
+
+static void technology_save(struct connman_technology *technology)
+{
+ GKeyFile *keyfile;
+ gchar *identifier;
+
+ DBG("technology %p", technology);
+
+ keyfile = __connman_storage_load_global();
+ if (keyfile == NULL)
+ keyfile = g_key_file_new();
+
+ identifier = g_strdup_printf("%s", get_name(technology->type));
+ if (identifier == NULL)
+ goto done;
+
+ g_key_file_set_boolean(keyfile, identifier, "Enable",
+ technology->enable_persistent);
+
+ g_key_file_set_boolean(keyfile, identifier, "Tethering",
+ technology->tethering_persistent);
+
+ if (technology->tethering_ident != NULL)
+ g_key_file_set_string(keyfile, identifier,
+ "Tethering.Identifier",
+ technology->tethering_ident);
+
+ if (technology->tethering_passphrase != NULL)
+ g_key_file_set_string(keyfile, identifier,
+ "Tethering.Passphrase",
+ technology->tethering_passphrase);
+
+done:
+ g_free(identifier);
+
+ __connman_storage_save_global(keyfile);
+
+ g_key_file_free(keyfile);
+
+ return;
+}
+
static void tethering_changed(struct connman_technology *technology)
{
connman_bool_t tethering = technology->tethering;
@@ -187,6 +254,8 @@ static void tethering_changed(struct connman_technology *technology)
connman_dbus_property_changed_basic(technology->path,
CONNMAN_TECHNOLOGY_INTERFACE, "Tethering",
DBUS_TYPE_BOOLEAN, &tethering);
+
+ technology_save(technology);
}
void connman_technology_tethering_notify(struct connman_technology *technology,
@@ -199,7 +268,7 @@ void connman_technology_tethering_notify(struct connman_technology *technology,
if (technology->tethering == enabled)
return;
- technology->tethering = enabled;
+ technology->tethering = enabled;
tethering_changed(technology);
@@ -361,72 +430,12 @@ static void free_rfkill(gpointer data)
g_free(rfkill);
}
-static const char *get_name(enum connman_service_type type)
-{
- switch (type) {
- case CONNMAN_SERVICE_TYPE_UNKNOWN:
- case CONNMAN_SERVICE_TYPE_SYSTEM:
- case CONNMAN_SERVICE_TYPE_GPS:
- case CONNMAN_SERVICE_TYPE_VPN:
- case CONNMAN_SERVICE_TYPE_GADGET:
- break;
- case CONNMAN_SERVICE_TYPE_ETHERNET:
- return "Wired";
- case CONNMAN_SERVICE_TYPE_WIFI:
- return "WiFi";
- case CONNMAN_SERVICE_TYPE_BLUETOOTH:
- return "Bluetooth";
- case CONNMAN_SERVICE_TYPE_CELLULAR:
- return "Cellular";
- }
-
- return NULL;
-}
-
-static void technology_save(struct connman_technology *technology)
-{
- GKeyFile *keyfile;
- gchar *identifier;
-
- DBG("technology %p", technology);
-
- keyfile = __connman_storage_load_global();
- if (keyfile == NULL)
- keyfile = g_key_file_new();
-
- identifier = g_strdup_printf("%s", get_name(technology->type));
- if (identifier == NULL)
- goto done;
-
- g_key_file_set_boolean(keyfile, identifier, "Enable",
- technology->enable_persistent);
-
- if (technology->tethering_ident != NULL)
- g_key_file_set_string(keyfile, identifier,
- "Tethering.Identifier",
- technology->tethering_ident);
-
- if (technology->tethering_passphrase != NULL)
- g_key_file_set_string(keyfile, identifier,
- "Tethering.Passphrase",
- technology->tethering_passphrase);
-
-done:
- g_free(identifier);
-
- __connman_storage_save_global(keyfile);
-
- g_key_file_free(keyfile);
-
- return;
-}
-
static void technology_load(struct connman_technology *technology)
{
GKeyFile *keyfile;
gchar *identifier;
GError *error = NULL;
- connman_bool_t enable;
+ connman_bool_t enable, need_saving = FALSE;
DBG("technology %p", technology);
@@ -454,10 +463,22 @@ static void technology_load(struct connman_technology *technology)
else
technology->enable_persistent = FALSE;
- technology_save(technology);
+ need_saving = TRUE;
g_clear_error(&error);
}
+ enable = g_key_file_get_boolean(keyfile, identifier,
+ "Tethering", &error);
+ if (error == NULL)
+ technology->tethering_persistent = enable;
+ else {
+ need_saving = TRUE;
+ g_clear_error(&error);
+ }
+
+ if (need_saving == TRUE)
+ technology_save(technology);
+
technology->tethering_ident = g_key_file_get_string(keyfile,
identifier, "Tethering.Identifier", NULL);
@@ -678,6 +699,10 @@ static int technology_enable(struct connman_technology *technology)
if (technology->pending_reply != NULL)
return -EBUSY;
+ if (connman_setting_get_bool("PersistentTetheringMode") == TRUE &&
+ technology->tethering == TRUE)
+ set_tethering(technology, TRUE);
+
if (technology->rfkill_driven == TRUE)
err = __connman_rfkill_block(technology->type, FALSE);
@@ -807,6 +832,10 @@ static DBusMessage *set_property(DBusConnection *conn,
if (err < 0)
return __connman_error_failed(msg, -err);
+ technology->tethering_persistent = tethering;
+
+ technology_save(technology);
+
} else if (g_str_equal(name, "TetheringIdentifier") == TRUE) {
const char *str;
@@ -1233,10 +1262,10 @@ int __connman_technology_add_device(struct connman_device *device)
struct connman_technology *technology;
enum connman_service_type type;
- DBG("device %p", device);
-
type = __connman_device_get_service_type(device);
+ DBG("device %p type %s", device, get_name(type));
+
technology = technology_get(type);
if (technology == NULL) {
/*
@@ -1341,6 +1370,20 @@ static void powered_changed(struct connman_technology *technology)
DBUS_TYPE_BOOLEAN, &technology->enabled);
}
+static void enable_tethering(struct connman_technology *technology)
+{
+ int ret;
+
+ if (connman_setting_get_bool("PersistentTetheringMode") != TRUE)
+ return;
+
+ ret = set_tethering(technology, TRUE);
+ if (ret < 0 && ret != -EALREADY)
+ DBG("Cannot enable tethering yet for %s (%d/%s)",
+ get_name(technology->type),
+ -ret, strerror(-ret));
+}
+
static int technology_enabled(struct connman_technology *technology)
{
__sync_synchronize();
@@ -1349,6 +1392,9 @@ static int technology_enabled(struct connman_technology *technology)
technology->enabled = TRUE;
+ if (technology->tethering_persistent == TRUE)
+ enable_tethering(technology);
+
powered_changed(technology);
return 0;
@@ -1362,8 +1408,15 @@ int __connman_technology_enabled(enum connman_service_type type)
if (technology == NULL)
return -ENXIO;
- if (technology->rfkill_driven == TRUE)
+ DBG("technology %p type %s rfkill %d enabled %d", technology,
+ get_name(type), technology->rfkill_driven,
+ technology->enabled);
+
+ if (technology->rfkill_driven == TRUE) {
+ if (technology->tethering_persistent == TRUE)
+ enable_tethering(technology);
return 0;
+ }
return technology_enabled(technology);
}
-- 1.7.11.7

View File

@ -0,0 +1,23 @@
The listener_table can be NULL if we have started connman with -r
option. Because we return <0 value to caller in this case,
the caller (like tethering code) has possibility to change how
its functionality (fall back to some other DNS servers).
---
src/dnsproxy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/dnsproxy.c b/src/dnsproxy.c
index 52d67d4..8ed34a7 100644
--- a/src/dnsproxy.c
+++ b/src/dnsproxy.c
@@ -3426,7 +3426,7 @@ int __connman_dnsproxy_add_listener(int index)
return -EINVAL;
if (listener_table == NULL)
- return 0;
+ return -ENOENT;
if (g_hash_table_lookup(listener_table, GINT_TO_POINTER(index)) != NULL)
return 0;
-- 1.7.11.7

View File

@ -0,0 +1,123 @@
If user has disabled dnsproxy with -r option, then fallback to
user specified nameservers instead of using the Google DNS.
---
src/tethering.c | 47 +++++++++++++++++++++++++++++++++++++----------
1 file changed, 37 insertions(+), 10 deletions(-)
diff --git a/src/tethering.c b/src/tethering.c
index bd79804..7042040 100644
--- a/src/tethering.c
+++ b/src/tethering.c
@@ -49,12 +49,11 @@
#endif
#define BRIDGE_NAME "tether"
-#define BRIDGE_DNS "8.8.8.8"
#define DEFAULT_MTU 1500
-#define PRIVATE_NETWORK_PRIMARY_DNS BRIDGE_DNS
-#define PRIVATE_NETWORK_SECONDARY_DNS "8.8.4.4"
+static char *private_network_primary_dns = NULL;
+static char *private_network_secondary_dns = NULL;
static volatile int tethering_enabled;
static GDHCPServer *tethering_dhcp_server = NULL;
@@ -73,8 +72,8 @@ struct connman_private_network {
int index;
guint iface_watch;
struct connman_ippool *pool;
- const char *primary_dns;
- const char *secondary_dns;
+ char *primary_dns;
+ char *secondary_dns;
};
const char *__connman_tethering_get_bridge(void)
@@ -192,6 +191,7 @@ void __connman_tethering_set_enabled(void)
const char *end_ip;
const char *dns;
unsigned char prefixlen;
+ char **ns;
DBG("enabled %d", tethering_enabled + 1);
@@ -228,11 +228,28 @@ void __connman_tethering_set_enabled(void)
return;
}
+ ns = connman_setting_get_string_list("FallbackNameservers");
+ if (ns != NULL) {
+ if (ns[0] != NULL) {
+ g_free(private_network_primary_dns);
+ private_network_primary_dns = g_strdup(ns[0]);
+ }
+ if (ns[1] != NULL) {
+ g_free(private_network_secondary_dns);
+ private_network_secondary_dns = g_strdup(ns[1]);
+ }
+
+ DBG("Fallback ns primary %s secondary %s",
+ private_network_primary_dns,
+ private_network_secondary_dns);
+ }
+
dns = gateway;
if (__connman_dnsproxy_add_listener(index) < 0) {
connman_error("Can't add listener %s to DNS proxy",
BRIDGE_NAME);
- dns = BRIDGE_DNS;
+ dns = private_network_primary_dns;
+ DBG("Serving %s nameserver to clients", dns);
}
tethering_dhcp_server = dhcp_server_start(BRIDGE_NAME,
@@ -278,6 +295,11 @@ void __connman_tethering_set_disabled(void)
__connman_bridge_remove(BRIDGE_NAME);
+ g_free(private_network_primary_dns);
+ private_network_primary_dns = NULL;
+ g_free(private_network_secondary_dns);
+ private_network_secondary_dns = NULL;
+
DBG("tethering stopped");
}
@@ -329,9 +351,12 @@ static void setup_tun_interface(unsigned int flags, unsigned change,
DBUS_TYPE_STRING, &server_ip);
connman_dbus_dict_append_basic(&dict, "PeerIPv4",
DBUS_TYPE_STRING, &peer_ip);
- connman_dbus_dict_append_basic(&dict, "PrimaryDNS",
+ if (pn->primary_dns != NULL)
+ connman_dbus_dict_append_basic(&dict, "PrimaryDNS",
DBUS_TYPE_STRING, &pn->primary_dns);
- connman_dbus_dict_append_basic(&dict, "SecondaryDNS",
+
+ if (pn->secondary_dns != NULL)
+ connman_dbus_dict_append_basic(&dict, "SecondaryDNS",
DBUS_TYPE_STRING, &pn->secondary_dns);
connman_dbus_dict_close(&array, &dict);
@@ -367,6 +392,8 @@ static void remove_private_network(gpointer user_data)
g_free(pn->interface);
g_free(pn->owner);
g_free(pn->path);
+ g_free(pn->primary_dns);
+ g_free(pn->secondary_dns);
g_free(pn);
}
@@ -447,8 +474,8 @@ int __connman_private_network_request(DBusMessage *msg, const char *owner)
goto error;
}
- pn->primary_dns = PRIVATE_NETWORK_PRIMARY_DNS;
- pn->secondary_dns = PRIVATE_NETWORK_SECONDARY_DNS;
+ pn->primary_dns = g_strdup(private_network_primary_dns);
+ pn->secondary_dns = g_strdup(private_network_secondary_dns);
pn->iface_watch = connman_rtnl_add_newlink_watch(index,
setup_tun_interface, pn);
-- 1.7.11.7