[PATCH] fixed noisy error Cannot read /proc/net/pnp Failed to open file
by Vasyl Vavrychuk
This error happend on every boot.
---
src/inet.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/inet.c b/src/inet.c
index dcd1ab24..80d96737 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -3233,6 +3233,9 @@ char **__connman_inet_get_pnp_nameservers(const char *pnp_file)
if (!pnp_file)
pnp_file = "/proc/net/pnp";
+ if (!g_file_test(pnp_file, G_FILE_TEST_EXISTS))
+ goto out;
+
if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
connman_error("%s: Cannot read %s %s\n", __func__,
pnp_file, error->message);
--
2.11.0
2 years, 5 months
[PATCH] inet: Invoke rtnl callback on errors too
by Slava Monich
Not invoking the callback results in memory leaks like this one:
==6817== 30 (8 direct, 22 indirect) bytes in 1 blocks are definitely lost in loss record 1,600 of 3,200
==6817== at 0x483F3EC: malloc (vg_replace_malloc.c)
==6817== by 0x8DC1B: __connman_inet_get_route (inet.c)
==6817== by 0x5E2E7: set_vpn_routes (connection.c)
==6817== by 0x5FD77: __connman_connection_gateway_add (connection.c)
==6817== by 0x837F7: __connman_ipconfig_gateway_add (ipconfig.c)
==6817== by 0x7DFA7: set_connected (provider.c)
==6817== by 0x7E0CB: connman_provider_set_state (provider.c)
==6817== by 0x499C3: set_provider_state (vpn.c)
==6817== by 0x4D95F: property_changed (vpn.c)
==6817== by 0xD7D4B: signal_filter (watch.c)
==6817== by 0xD8323: message_filter (watch.c)
==6817== by 0x4A1E02F: dbus_connection_dispatch (dbus-connection.c)
---
src/inet.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/inet.c b/src/inet.c
index dd13623..01c0c9c 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -2370,6 +2370,7 @@ static gboolean inet_rtnl_event(GIOChannel *chan, GIOCondition cond,
return TRUE;
cleanup:
+ rtnl_data->callback(NULL, rtnl_data->user_data);
inet_rtnl_cleanup(rtnl_data);
return TRUE;
}
--
1.9.1
2 years, 5 months
[PATCH] vpn: Removed unnecessary goto
by Slava Monich
---
plugins/vpn.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/plugins/vpn.c b/plugins/vpn.c
index c2a332b..b888e5e 100644
--- a/plugins/vpn.c
+++ b/plugins/vpn.c
@@ -484,19 +484,19 @@ static void connect_reply(DBusPendingCall *call, void *user_data)
if (dbus_set_error_from_message(&error, reply)) {
int err = errorstr2val(error.name);
+
if (err != -EINPROGRESS) {
connman_error("Connect reply: %s (%s)", error.message,
error.name);
- dbus_error_free(&error);
-
DBG("data %p cb_data %p", data, cb_data);
+
if (cb_data) {
cb_data->callback(cb_data->message, err, NULL);
free_config_cb_data(cb_data);
data->cb_data = NULL;
}
- goto done;
}
+
dbus_error_free(&error);
}
@@ -506,7 +506,6 @@ static void connect_reply(DBusPendingCall *call, void *user_data)
* state.
*/
-done:
dbus_message_unref(reply);
dbus_pending_call_unref(call);
--
1.9.1
2 years, 5 months
[PATCH] vpn: Fix memory leak
by Slava Monich
==10939== 20 bytes in 4 blocks are definitely lost in loss record 199 of 429
==10939== at 0x483F3EC: malloc (vg_replace_malloc.c)
==10939== by 0x4C7E35F: g_malloc (gmem.c)
==10939== by 0x4C962BD: g_strdup (gstrfuncs.c)
==10939== by 0x1945B: vpn_create_tun (vpn.c)
==10939== by 0x19C83: vpn_connect (vpn.c)
==10939== by 0x292DF: __vpn_provider_connect (vpn-provider.c)
==10939== by 0x27797: do_connect (vpn-provider.c)
==10939== by 0x46853: process_message (object.c)
==10939== by 0x486AB: generic_message (object.c)
==10939== by 0x49BDFE1: _dbus_object_tree_dispatch_and_unlock (dbus-object-tree.c)
==10939== by 0x49B4071: dbus_connection_dispatch (dbus-connection.c)
==10939== by 0x43A8B: message_dispatch (mainloop.c)
---
vpn/plugins/vpn.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/vpn/plugins/vpn.c b/vpn/plugins/vpn.c
index 10548aa..a26bcc6 100644
--- a/vpn/plugins/vpn.c
+++ b/vpn/plugins/vpn.c
@@ -378,6 +378,7 @@ static int vpn_create_tun(struct vpn_provider *provider, int flags)
}
data->tun_flags = flags;
+ g_free(data->if_name);
data->if_name = (char *)g_strdup(ifr.ifr_name);
if (!data->if_name) {
connman_error("Failed to allocate memory");
--
1.9.1
2 years, 5 months
[Patch] Bug fix when switching happens from Auto to Manual
by Rahul Jain
Author: Rahul Jain <rahul.jain(a)samsung.com>
Date: Fri Jul 27 14:32:51 2018 +0530
When a device having auto IP configurations, is connected
to router in which DHCP is not running, device will go for
IPv4All configuration and will get IP(like 169.254.xxx.xxx).
Inside connman/src/dhcp.c:dhcpipv4ll_available_cb(), dhcp ipconfig set to AUTO.
Now if user tries to configure manual IP, it fails.
As per current code, dhcp stop function (__connman_dhcp_stop) will not be called for IPv5.
Signed-off-by: Rahul Jain <rahul.jain(a)samsung.com>
diff --git a/src/network.c b/src/network.c
index c3a7cbf..c910afd 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1872,12 +1872,15 @@ int __connman_network_clear_ipconfig(struct connman_network *network,
case CONNMAN_IPCONFIG_METHOD_OFF:
case CONNMAN_IPCONFIG_METHOD_FIXED:
return -EINVAL;
- case CONNMAN_IPCONFIG_METHOD_AUTO:
- release_dhcpv6(network);
- break;
case CONNMAN_IPCONFIG_METHOD_MANUAL:
__connman_ipconfig_address_remove(ipconfig);
break;
+ case CONNMAN_IPCONFIG_METHOD_AUTO:
+ release_dhcpv6(network);
+ if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
+ break;
+ // incase ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4
+ /* fall through */
case CONNMAN_IPCONFIG_METHOD_DHCP:
remove_dhcp_timeout(network);
__connman_dhcp_stop(ipconfig_ipv4);
2 years, 5 months
[PATCH] inet: Treat NULL and any address gateways as the same
by Jussi Laakkonen
This fixes an issue of treating an any address (IPv4 or IPv6) as gateway
address when adding routes, which causes RTF_GATEWAY flag being set and
adding of such route to fail. RTF_GATEWAY should be set only when the
address is an real IP address.
In addition, when adding a IPv6 route the return value of inet_pton() is
utilized in order to check for the address validity before enabling
RTF_GATEWAY flag.
Added a helper function (__connman_inet_is_any_addr()) to check if an
IPv4 or IPv6 address is an any address. For convenience and future use
function prototype is added to src/connman.h.
---
src/connman.h | 2 ++
src/inet.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 57 insertions(+), 4 deletions(-)
diff --git a/src/connman.h b/src/connman.h
index 706ab98..34fdcb1 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -163,6 +163,8 @@ int __connman_inet_get_interface_address(int index, int family, void *address);
int __connman_inet_get_interface_ll_address(int index, int family, void *address);
int __connman_inet_get_interface_mac_address(int index, uint8_t *mac_address);
+bool __connman_inet_is_any_addr(const char *address, int family);
+
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
diff --git a/src/inet.c b/src/inet.c
index 0992ed4..5ffc132 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -190,6 +190,40 @@ done:
return err;
}
+bool __connman_inet_is_any_addr(const char *address, int family)
+{
+ bool rval = false;
+ struct addrinfo hints;
+ struct addrinfo *result = NULL;
+ struct sockaddr_in6 *in6 = NULL;
+ struct sockaddr_in *in4 = NULL;
+
+ if (!address || !*address)
+ goto out;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+
+ hints.ai_family = family;
+
+ if (getaddrinfo(address, NULL, &hints, &result))
+ goto out;
+
+ if (result) {
+ if (result->ai_family == AF_INET6) {
+ in6 = (struct sockaddr_in6*)result->ai_addr;
+ rval = IN6_IS_ADDR_UNSPECIFIED(&in6->sin6_addr);
+ } else if (result->ai_family == AF_INET) {
+ in4 = (struct sockaddr_in*)result->ai_addr;
+ rval = in4->sin_addr.s_addr == INADDR_ANY;
+ }
+
+ freeaddrinfo(result);
+ }
+
+out:
+ return rval;
+}
+
int connman_inet_ifindex(const char *name)
{
struct ifreq ifr;
@@ -512,7 +546,17 @@ int connman_inet_add_network_route(int index, const char *host,
memset(&rt, 0, sizeof(rt));
rt.rt_flags = RTF_UP;
- if (gateway)
+
+ /*
+ * Set RTF_GATEWAY only when gateway is set and the gateway IP address
+ * is not IPv4 any address (0.0.0.0). If the given gateway IP address is
+ * any address adding of route will fail when RTF_GATEWAY set. Passing
+ * gateway as NULL or INADDR_ANY should have the same effect. Setting
+ * the gateway address later to the struct is not affected by this,
+ * since given IPv4 any address (0.0.0.0) equals the value set with
+ * INADDR_ANY.
+ */
+ if (gateway && !__connman_inet_is_any_addr(gateway, AF_INET))
rt.rt_flags |= RTF_GATEWAY;
if (!netmask)
rt.rt_flags |= RTF_HOST;
@@ -675,10 +719,17 @@ int connman_inet_add_ipv6_network_route(int index, const char *host,
rt.rtmsg_flags = RTF_UP | RTF_HOST;
- if (gateway) {
+ /*
+ * Set RTF_GATEWAY only when gateway is set, the gateway IP address is
+ * not IPv6 any address (e.g., ::) and the address is valid (conversion
+ * succeeds). If the given gateway IP address is any address then
+ * adding of route will fail when RTF_GATEWAY set. Passing gateway as
+ * NULL or IPv6 any address should have the same effect.
+ */
+
+ if (gateway && !__connman_inet_is_any_addr(gateway, AF_INET6) &&
+ inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) > 0)
rt.rtmsg_flags |= RTF_GATEWAY;
- inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
- }
rt.rtmsg_metric = 1;
rt.rtmsg_ifindex = index;
--
2.7.4
2 years, 5 months
[PATCH] dhcp: Prefer to reuse broadcast flag from DHCPDISCOVER
by Slava Monich
Some (broken?) DHCP servers are picky about the BROADCAST flag.
They may respond with an IP broadcast, but ignore requests with
the BROADCAST flag set. IP unicast received from the server, on
the other hand, should guarantee that the server is ok with the
BROADCAST bit cleared.
---
gdhcp/client.c | 41 +++++++++++++++++++++++++++++++++--------
1 file changed, 33 insertions(+), 8 deletions(-)
diff --git a/gdhcp/client.c b/gdhcp/client.c
index d8a18d6..eb234b6 100644
--- a/gdhcp/client.c
+++ b/gdhcp/client.c
@@ -111,6 +111,7 @@ struct _GDHCPClient {
GList *request_list;
GHashTable *code_value_hash;
GHashTable *send_value_hash;
+ GHashTable *secs_bcast_hash;
GDHCPClientEventFunc lease_available_cb;
gpointer lease_available_data;
GDHCPClientEventFunc ipv4ll_available_cb;
@@ -466,10 +467,16 @@ static int send_discover(GDHCPClient *dhcp_client, uint32_t requested)
* versa. In the receiving side we then find out what kind of packet
* the server can send.
*/
+ dhcp_client->request_bcast = dhcp_client->retry_times % 2;
+
+ if (dhcp_client->request_bcast)
+ g_hash_table_add(dhcp_client->secs_bcast_hash,
+ GINT_TO_POINTER(packet.secs));
+
return dhcp_send_raw_packet(&packet, INADDR_ANY, CLIENT_PORT,
INADDR_BROADCAST, SERVER_PORT,
MAC_BCAST_ADDR, dhcp_client->ifindex,
- dhcp_client->retry_times % 2);
+ dhcp_client->request_bcast);
}
int g_dhcp_client_decline(GDHCPClient *dhcp_client, uint32_t requested)
@@ -1192,6 +1199,8 @@ GDHCPClient *g_dhcp_client_new(GDHCPType type,
g_direct_equal, NULL, remove_option_value);
dhcp_client->send_value_hash = g_hash_table_new_full(g_direct_hash,
g_direct_equal, NULL, g_free);
+ dhcp_client->secs_bcast_hash = g_hash_table_new(g_direct_hash,
+ g_direct_equal);
dhcp_client->request_list = NULL;
dhcp_client->require_list = NULL;
dhcp_client->duid = NULL;
@@ -2370,14 +2379,28 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
dhcp_client->state = REQUESTING;
- if (dst_addr.sin_addr.s_addr == INADDR_BROADCAST)
- dhcp_client->request_bcast = true;
- else
- dhcp_client->request_bcast = false;
+ /*
+ * RFC2131:
+ *
+ * If unicasting is not possible, the message MAY be
+ * sent as an IP broadcast using an IP broadcast address
+ * (preferably 0xffffffff) as the IP destination address
+ * and the link-layer broadcast address as the link-layer
+ * destination address.
+ *
+ * For interoperability reasons, if the response is an IP
+ * broadcast, let's reuse broadcast flag from DHCPDISCOVER
+ * to which the server has responded. Some servers are picky
+ * about this flag.
+ */
+ dhcp_client->request_bcast =
+ dst_addr.sin_addr.s_addr == INADDR_BROADCAST &&
+ g_hash_table_contains(dhcp_client->secs_bcast_hash,
+ GINT_TO_POINTER(packet.secs));
- debug(dhcp_client, "init ip %s -> %sadding broadcast flag",
- inet_ntoa(dst_addr.sin_addr),
- dhcp_client->request_bcast ? "" : "not ");
+ debug(dhcp_client, "init ip %s secs %hu -> broadcast flag %s",
+ inet_ntoa(dst_addr.sin_addr), packet.secs,
+ dhcp_client->request_bcast ? "on" : "off");
start_request(dhcp_client);
@@ -2827,6 +2850,7 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address)
__connman_util_get_random(&rand);
dhcp_client->xid = rand;
dhcp_client->start = time(NULL);
+ g_hash_table_remove_all(dhcp_client->secs_bcast_hash);
}
if (!last_address || oldstate == DECLINED) {
@@ -3227,6 +3251,7 @@ void g_dhcp_client_unref(GDHCPClient *dhcp_client)
g_hash_table_destroy(dhcp_client->code_value_hash);
g_hash_table_destroy(dhcp_client->send_value_hash);
+ g_hash_table_destroy(dhcp_client->secs_bcast_hash);
g_free(dhcp_client);
}
--
1.9.1
2 years, 5 months