[PATCH v2] peer: Add memory allocation controls
by Jose Blanquicet
Add control where pointer may be NULL and use g_try_new0 instead of g_malloc0 in
order to avoid potential abortion on failure.
---
plugins/wifi.c | 3 +++
src/peer.c | 19 ++++++++++++++++---
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/plugins/wifi.c b/plugins/wifi.c
index 70cec77..2af41de 100644
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -2853,6 +2853,9 @@ static void peer_found(GSupplicantPeer *peer)
return;
connman_peer = connman_peer_create(identifier);
+ if (!connman_peer)
+ return;
+
connman_peer_set_name(connman_peer, name);
connman_peer_set_device(connman_peer, wifi->device);
apply_peer_services(peer, connman_peer);
diff --git a/src/peer.c b/src/peer.c
index ad4e445..6b712aa 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -706,7 +706,10 @@ struct connman_peer *connman_peer_create(const char *identifier)
{
struct connman_peer *peer;
- peer = g_malloc0(sizeof(struct connman_peer));
+ peer = g_try_new0(struct connman_peer, 1);
+ if (!peer)
+ return NULL;
+
peer->identifier = g_strdup(identifier);
peer->state = CONNMAN_PEER_STATE_IDLE;
@@ -978,7 +981,10 @@ void connman_peer_add_service(struct connman_peer *peer,
if (!peer || !data || type == CONNMAN_PEER_SERVICE_UNKNOWN)
return;
- service = g_malloc0(sizeof(struct _peer_service));
+ service = g_try_new0(struct _peer_service, 1);
+ if (!service)
+ return;
+
service->type = type;
service->data = g_memdup(data, data_length * sizeof(unsigned char));
service->length = data_length;
@@ -1017,6 +1023,8 @@ static void peer_ip_bound(struct connman_ipconfig *ipconfig,
const char *ifname)
{
struct connman_peer *peer = __connman_ipconfig_get_data(ipconfig);
+ if (!peer)
+ return;
DBG("%s ip bound", ifname);
@@ -1029,6 +1037,8 @@ static void peer_ip_release(struct connman_ipconfig *ipconfig,
const char *ifname)
{
struct connman_peer *peer = __connman_ipconfig_get_data(ipconfig);
+ if (!peer)
+ return;
DBG("%s ip release", ifname);
@@ -1186,7 +1196,10 @@ int __connman_peer_init(void)
peers_table = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL, peer_free);
- peers_notify = g_new0(struct _peers_notify, 1);
+ peers_notify = g_try_new0(struct _peers_notify, 1);
+ if (!peers_notify)
+ return -ENOMEM;
+
peers_notify->add = g_hash_table_new(g_str_hash, g_str_equal);
peers_notify->remove = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, NULL);
--
1.9.1
4 years, 1 month
[PATCH 0/2] DHCPv6 infinite expiry times
by Patrik Flykt
Hi,
This patch set is heavily influenced by the patch set from
wangfe(a)nestlabs.com. The difference is that T1, T2 and expiry
timeouts are all set to 0xffffffff (infinite) when the expiry
time is infinite. With this it is believed any further changes
will be much smaller, as the code already checks for T1 and
T2 being unequal to 0xffffffff.
Wang Feng, does this work with your setup?
Cheers,
Patrik
Patrik Flykt (2):
dhcpv6: Return -EISCONN when the expiry time is inifinite
gdhcp: Set T1 and T2 to infinite if expiry time is infinite
gdhcp/client.c | 9 ++++++---
src/dhcpv6.c | 5 +++++
2 files changed, 11 insertions(+), 3 deletions(-)
--
2.8.1
4 years, 1 month
[PATCH] stats: Don't handle TEMP_FAILURE_RETRY on close()
by Daniel Wagner
From: Daniel Wagner <daniel.wagner(a)bmw-carit.de>
If close return EINTR the filedescriptor is already invalid. This is
Linux specific behavoir.
http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
https://bugzilla.gnome.org/show_bug.cgi?id=682819
http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
https://sites.google.com/site/michaelsafyan/software-engineering/checkfor...
Pointed out by Tom Gundersen.
*/
---
src/stats.c | 10 +++++-----
tools/stats-tool.c | 4 ++--
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/stats.c b/src/stats.c
index eed6e8a1c09b..663bc3827efc 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -227,7 +227,7 @@ static void stats_free(gpointer user_data)
munmap(file->addr, file->len);
file->addr = NULL;
- TFR(close(file->fd));
+ close(file->fd);
file->fd = -1;
g_free(file->history_name);
@@ -373,7 +373,7 @@ static int stats_file_setup(struct stats_file *file)
connman_error("fstat error %s for %s\n",
strerror(errno), file->name);
- TFR(close(file->fd));
+ close(file->fd);
file->fd = -1;
g_free(file->name);
file->name = NULL;
@@ -389,7 +389,7 @@ static int stats_file_setup(struct stats_file *file)
err = stats_file_remap(file, size);
if (err < 0) {
- TFR(close(file->fd));
+ close(file->fd);
file->fd = -1;
g_free(file->name);
file->name = NULL;
@@ -619,7 +619,7 @@ static int stats_file_close_swap(struct stats_file *history_file,
stats_file_unmap(history_file);
stats_file_unmap(temp_file);
- TFR(close(temp_file->fd));
+ close(temp_file->fd);
unlink(history_file->name);
@@ -627,7 +627,7 @@ static int stats_file_close_swap(struct stats_file *history_file,
unlink(temp_file->name);
- TFR(close(history_file->fd));
+ close(history_file->fd);
stats_file_cleanup(history_file);
stats_file_cleanup(temp_file);
diff --git a/tools/stats-tool.c b/tools/stats-tool.c
index b076478a4bcf..efa39de27274 100644
--- a/tools/stats-tool.c
+++ b/tools/stats-tool.c
@@ -794,7 +794,7 @@ static void swap_and_close_files(struct stats_file *history_file,
munmap(history_file->addr, history_file->len);
munmap(temp_file->addr, temp_file->len);
- TFR(close(temp_file->fd));
+ close(temp_file->fd);
unlink(history_file->name);
@@ -802,7 +802,7 @@ static void swap_and_close_files(struct stats_file *history_file,
return;
unlink(temp_file->name);
- TFR(close(history_file->fd));
+ close(history_file->fd);
}
static void history_file_update(struct stats_file *data_file,
--
2.7.4
4 years, 1 month
RE: Issue in setting nameserver and default route
by Priyaranjan Singh
Hello,
We have got Telephony device connected to usb0 interface with my Linux embedded system. This Telephony device doesn't have DHCP Server.
Using connman API, we are setting static route and nameserver information.
With the logs we can very well verify that connman accepted this new values but reverting this value soon.
Note: Telephony device has been given highest priority in the connman service order list. Also using log I cannot see service order changing is happening.
Basic steps: My application is setting below properties. Listening for the change from connman. In case connman is reverting this change, application is setting back to static values.
For "nameserver" we are setting " Nameservers.Configuration" property
For "route" we are setting " IPv4.Configuration" property (Method, Address, Netmask, Gateway)
Result:
1) When application is setting "nameserver", for entire lifecycle connman is clearing the value and My application is setting it back. This is going in loop.
-If application is writing static nameserver to "resolv.conf" file directly. We are not observing any issues.
- What will be side effect in case application is directly writing to resolv.conf
2) When application is reading " IPv4" property, if "method" is not "manual" then setting " IPv4.Configuration". Application is checking this on SERVICESCHANGED and PROPERTYCHANGED signal from connman
-usb0 interface is getting added and removed by connman continuously ==> connman Log " usb0 {add} route" & " usb0 {del} route" is continuously coming
- This is causing state change to "configuration" -> "idle" -> "ready"
Do you know reason for this issue? Are we consuming connman APIs in wrong way?
Thanks in advance.
Best Regards,
PriyaranjanS
This message contains information that may be privileged or confidential and is the property of the KPIT Technologies Ltd. It is intended only for the person to whom it is addressed. If you are not the intended recipient, you are not authorized to read, print, retain copy, disseminate, distribute, or use this message or any part thereof. If you receive this message in error, please notify the sender immediately and delete all copies of this message. KPIT Technologies Ltd. does not accept any liability for virus infected mails.
4 years, 1 month
[PATCH] rootnfs: Working rootnfs using connman
by Pantelis Antoniou
Until now for root NFS you either had to manually blacklist
the interface or disable connman all together
This patch automatically blacklists the interface the NFS server
is reachable from and populates the resolver entries that the
DHCP server provided on startup.
It is now possible to use a vanilla rootfs tarball without
having to manually edit connman configuration entries.
---
src/connman.h | 3 +
src/device.c | 5 +
src/inet.c | 294 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/resolver.c | 8 ++
4 files changed, 310 insertions(+)
diff --git a/src/connman.h b/src/connman.h
index ce3ef8d..f85d243 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -244,6 +244,9 @@ int __connman_inet_del_default_from_table(uint32_t table_id, int ifindex, const
int __connman_inet_get_address_netmask(int ifindex,
struct sockaddr_in *address, struct sockaddr_in *netmask);
+bool __connman_inet_isrootnfs_device(const char *devname);
+char **__connman_inet_get_pnp_nameservers(const char *pnp_file);
+
#include <connman/resolver.h>
int __connman_resolver_init(gboolean dnsproxy);
diff --git a/src/device.c b/src/device.c
index 742b3c4..2e1a3cd 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1321,6 +1321,11 @@ nodevice:
}
list:
+ if (__connman_inet_isrootnfs_device(devname)) {
+ DBG("ignoring device %s (rootnfs)", devname);
+ return true;
+ }
+
blacklisted_interfaces =
connman_setting_get_string_list("NetworkInterfaceBlacklist");
if (!blacklisted_interfaces)
diff --git a/src/inet.c b/src/inet.c
index 803f0e6..0f2151c 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -2964,3 +2964,297 @@ out:
close(sk);
return ret;
}
+
+static int get_nfs_server_ip(const char *cmdline_file, const char *pnp_file,
+ struct in_addr *addr)
+{
+ char *s, *nfsargs;
+ int len;
+ char addrstr[INET_ADDRSTRLEN];
+ struct in_addr taddr;
+ GError *error = NULL;
+ char *cmdline = NULL;
+ char *pnp = NULL;
+ char **args = NULL;
+ char **pnpent = NULL;
+ char **pp = NULL;
+ int err = -1;
+
+ if (!cmdline_file)
+ cmdline_file = "/proc/cmdline";
+ if (!pnp_file)
+ pnp_file = "/proc/net/pnp";
+ if (!addr)
+ addr = &taddr;
+ addr->s_addr = INADDR_NONE;
+
+ if (!g_file_get_contents(cmdline_file, &cmdline, NULL, &error)) {
+ connman_error("%s: Cannot read %s %s\n", __func__,
+ cmdline_file, error->message);
+ 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);
+ goto out;
+ }
+
+ len = strlen(cmdline);
+ if (len <= 1) {
+ /* too short */
+ goto out;
+ }
+ /* remove newline */
+ if (cmdline[len - 1] == '\n')
+ cmdline[--len] = '\0';
+
+ /* split in arguments (seperated by space) */
+ args = g_strsplit(cmdline, " ", 0);
+ if (!args) {
+ connman_error("%s: Cannot split cmdline \"%s\"\n", __func__,
+ cmdline);
+ goto out;
+ }
+
+ /* split in entries (by newlines) */
+ pnpent = g_strsplit(pnp, "\n", 0);
+ if (!pnpent) {
+ connman_error("%s: Cannot split pnp at file \"%s\"\n", __func__,
+ pnp_file);
+ goto out;
+ }
+
+ /* first find root argument */
+ for (pp = args; *pp; pp++) {
+ if (!strcmp(*pp, "root=/dev/nfs"))
+ break;
+ }
+ /* no rootnfs found */
+ if (!*pp)
+ goto out;
+
+ /* locate nfsroot argument */
+ for (pp = args; *pp; pp++) {
+ if (!strncmp(*pp, "nfsroot=", strlen("nfsroot=")))
+ break;
+ }
+ /* no nfsroot argument found */
+ if (!*pp)
+ goto out;
+
+ /* determine if nfsroot server is provided */
+ nfsargs = strchr(*pp, '=');
+ if (!nfsargs)
+ goto out;
+ nfsargs++;
+
+ /* find whether serverip is present */
+ s = strchr(nfsargs, ':');
+ if (s) {
+ len = s - nfsargs;
+ s = nfsargs;
+ } else {
+ /* no serverip, use bootserver */
+ for (pp = pnpent; *pp; pp++) {
+ if (!strncmp(*pp, "bootserver ", strlen("bootserver ")))
+ break;
+ }
+ /* no bootserver found */
+ if (!*pp)
+ goto out;
+ s = *pp + strlen("bootserver ");
+ len = strlen(s);
+ }
+
+ /* copy to addr string buffer */
+ if (len >= sizeof(addrstr)) {
+ connman_error("%s: Bad server\n", __func__);
+ goto out;
+ }
+ memcpy(addrstr, s, len);
+ addrstr[len] = '\0';
+
+ err = inet_pton(AF_INET, addrstr, addr);
+ if (err <= 0) {
+ connman_error("%s: Cannot convert to numeric addr \"%s\"\n",
+ __func__, addrstr);
+ err = -1;
+ goto out;
+ }
+
+ /* all done */
+ err = 0;
+out:
+ g_strfreev(pnpent);
+ g_strfreev(args);
+ if (error)
+ g_error_free(error);
+ g_free(pnp);
+ g_free(cmdline);
+
+ return err;
+}
+
+/* get interface out of which peer is reachable (IPv4 only) */
+static int get_peer_iface(struct in_addr *addr, char *ifname)
+{
+ struct ifaddrs *ifaddr, *ifa;
+ struct sockaddr_in saddr, *ifsaddr;
+ socklen_t socklen;
+ int s;
+ int err = -1;
+
+ /* Obtain address(es) matching host/port */
+ err = getifaddrs(&ifaddr);
+ if (err < 0) {
+ connman_error("%s: getifaddrs() failed %d (%s)\n",
+ __func__, errno, strerror(errno));
+ return -1;
+ }
+
+ s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (s < 0) {
+ connman_error("%s: socket() failed %d (%s)\n",
+ __func__, errno, strerror(errno));
+ return -1;
+ }
+
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.sin_family = AF_INET;
+ saddr.sin_port = 0; /* any port */
+ saddr.sin_addr = *addr;
+
+ /* no need to bind, connect will select iface */
+ err = connect(s, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
+ if (err < 0) {
+ connman_error("%s: connect() failed: %d (%s)\n",
+ __func__, errno, strerror(errno));
+ goto out;
+ }
+
+ socklen = sizeof(saddr);
+ err = getsockname(s, (struct sockaddr *)&saddr, &socklen);
+ if (err < 0) {
+ connman_error("%s: getsockname() failed: %d (%s)\n",
+ __func__, errno, strerror(errno));
+ goto out;
+ }
+
+ err = -1;
+ for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
+ if (!ifa->ifa_addr)
+ continue;
+
+ /* only IPv4 address */
+ if (ifa->ifa_addr->sa_family != AF_INET)
+ continue;
+
+ ifsaddr = (struct sockaddr_in *)ifa->ifa_addr;
+
+ /* match address? */
+ if (ifsaddr->sin_addr.s_addr == saddr.sin_addr.s_addr)
+ break;
+ }
+
+ if (ifa) {
+ err = 0;
+ if (ifname)
+ strcpy(ifname, ifa->ifa_name);
+ }
+
+out:
+ close(s);
+
+ freeifaddrs(ifaddr);
+
+ return err;
+}
+
+bool __connman_inet_isrootnfs_device(const char *devname)
+{
+ struct in_addr addr;
+ char ifname[IFNAMSIZ];
+
+ return get_nfs_server_ip(NULL, NULL, &addr) == 0 &&
+ get_peer_iface(&addr, ifname) == 0 &&
+ strcmp(devname, ifname) == 0;
+}
+
+char **__connman_inet_get_pnp_nameservers(const char *pnp_file)
+{
+ char **pp;
+ char *s;
+ int pass, count;
+ GError *error = NULL;
+ char *pnp = NULL;
+ char **pnpent = NULL;
+ char **nameservers = NULL;
+
+ if (!pnp_file)
+ pnp_file = "/proc/net/pnp";
+
+ if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
+ connman_error("%s: Cannot read %s %s\n", __func__,
+ pnp_file, error->message);
+ goto out;
+ }
+
+ /* split in entries (by newlines) */
+ pnpent = g_strsplit(pnp, "\n", 0);
+ if (!pnpent) {
+ connman_error("%s: Cannot split pnp \"%s\"\n", __func__,
+ pnp_file);
+ goto out;
+ }
+
+ /*
+ * Perform two passes to retreive a char ** array of
+ * nameservers that are not 0.0.0.0
+ *
+ * The first pass counts them, the second fills in the
+ * array.
+ */
+ count = 0;
+ nameservers = NULL;
+ for (pass = 1; pass <= 2; pass++) {
+
+ /* at the start of the second pass allocate */
+ if (pass == 2)
+ nameservers = g_new(char *, count + 1);
+
+ count = 0;
+ for (pp = pnpent; *pp; pp++) {
+ /* match 'nameserver ' at the start of each line */
+ if (strncmp(*pp, "nameserver ", strlen("nameserver ")))
+ continue;
+
+ /* compare it against 0.0.0.0 */
+ s = *pp + strlen("nameserver ");
+ if (!strcmp(s, "0.0.0.0"))
+ continue;
+
+ /* on second pass fill in array */
+ if (pass == 2)
+ nameservers[count] = g_strdup(s);
+ count++;
+ }
+
+ /* no nameservers? */
+ if (count == 0)
+ goto out;
+
+ /* and terminate char ** array with NULL */
+ if (pass == 2)
+ nameservers[count] = NULL;
+
+ }
+
+out:
+ g_strfreev(pnpent);
+ g_free(pnp);
+ if (error)
+ g_error_free(error);
+
+ return nameservers;
+}
diff --git a/src/resolver.c b/src/resolver.c
index c4adbc6..75ea5ba 100644
--- a/src/resolver.c
+++ b/src/resolver.c
@@ -659,6 +659,14 @@ int __connman_resolver_init(gboolean dnsproxy)
DBG("dnsproxy %d", dnsproxy);
+ /* get autoip nameservers */
+ ns = __connman_inet_get_pnp_nameservers(NULL);
+ for (i = 0; ns && ns[i]; i += 1) {
+ DBG("pnp server %s", ns[i]);
+ append_resolver(i, NULL, ns[i], 86400, 0);
+ }
+ g_strfreev(ns);
+
if (!dnsproxy)
return 0;
--
2.1.4
4 years, 1 month