[PATCH v4] NTP implementation for IPv6 timeserver
From: nasingh Current NTP code is written with an assumption that timeserver is always an IPv4 address. If there is an IPv6 timeserver then the socket operation would fail with error as Permission denied (13). This change in ntp.c ensures that code works fine with both IPv4 and IPv6 address. --- src/ntp.c | 131 ++ 1 file changed, 98 insertions(+), 33 deletions(-) diff --git a/src/ntp.c b/src/ntp.c index 2c313a4..9e7192d 100644 --- a/src/ntp.c +++ b/src/ntp.c @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ - #ifdef HAVE_CONFIG_H #include #endif @@ -34,6 +33,7 @@ #include #include #include +#include #include @@ -117,12 +117,12 @@ static struct timespec mtx_time; static int transmit_fd = 0; static char *timeserver = NULL; -static struct sockaddr_in timeserver_addr; +static struct sockaddr_in6 timeserver_addr; static gint poll_id = 0; static gint timeout_id = 0; static guint retries = 0; -static void send_packet(int fd, const char *server, uint32_t timeout); +static void send_packet(int fd, struct sockaddr *server, uint32_t timeout); static void next_server(void) { @@ -143,17 +143,19 @@ static gboolean send_timeout(gpointer user_data) if (retries++ == NTP_SEND_RETRIES) next_server(); else - send_packet(transmit_fd, timeserver, timeout << 1); + send_packet(transmit_fd, (struct sockaddr *)×erver_addr, timeout << 1); return FALSE; } -static void send_packet(int fd, const char *server, uint32_t timeout) +static void send_packet(int fd, struct sockaddr *server, uint32_t timeout) { struct ntp_msg msg; - struct sockaddr_in addr; struct timeval transmit_timeval; ssize_t len; + void * addr; + int size; + char ipaddrstring[INET6_ADDRSTRLEN + 1]; /* * At some point, we could specify the actual system precision with: @@ -168,10 +170,16 @@ static void send_packet(int fd, const char *server, uint32_t timeout) msg.poll = 10; // max msg.precision = NTP_PRECISION_S; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(123); - addr.sin_addr.s_addr = inet_addr(server); + if (server->sa_family == AF_INET) { + size = sizeof(struct sockaddr_in); + addr = (void *)&(((struct sockaddr_in *)×erver_addr)->sin_addr); + } else if (server->sa_family == AF_INET6) { + size = sizeof(struct sockaddr_in6); + addr = (void *)×erver_addr.sin6_addr; + } else { + connman_error("Family is neither ipv4 nor ipv6"); + return; + } gettimeofday(&transmit_timeval, NULL); clock_gettime(CLOCK_MONOTONIC, &mtx_time); @@ -180,10 +188,12 @@ static void send_packet(int fd, const char *server, uint32_t timeout) msg.xmttime.fraction = htonl(transmit_timeval.tv_usec * 1000); len = sendto(fd, &msg, sizeof(msg), MSG_DONTWAIT, - &addr, sizeof(addr)); + server, size); + if (len < 0) { connman_error("Time request for server %s failed (%d/%s)", - server, errno, strerror(errno)); + inet_ntop(server->sa_family, addr, ipaddrstring, sizeof(ipaddrstring)), + errno, strerror(errno)); if (errno == ENETUNREACH) __connman_timeserver_sync_next(); @@ -192,7 +202,8 @@ static void send_packet(int fd, const char *server, uint32_t timeout) } if (len != sizeof(msg)) { - connman_error("Broken time request for server %s", server); + connman_error("Broken time request for server %s", + inet_ntop(server->sa_family, addr, ipaddrstring, sizeof(ipaddrstring))); return; } @@ -213,7 +224,7 @@ static gboolean next_poll(gpointer user_data) if (!timeserver || transmit_fd == 0) return FALSE; - send_packet(transmit_fd, timeserver, NTP_SEND_TIMEOUT); + send_packet(transmit_fd, (struct sockaddr *)×erver_addr, NTP_SEND_TIMEOUT); return FALSE; } @@ -363,7 +374,7 @@ static gboolean received_data(GIOChannel *channel, GIOCondition condition, gpointer user_data) { unsigned char buf[128]; - struct sockaddr_in sender_addr; + struct sockaddr_in6 sender_addr; struct msghdr msg; struct iovec iov; struct cmsghdr *cmsg; @@ -372,6 +383,9 @@ static gboolean received_data(GIOChannel *channel, GIOCondition condition, char aux[128]; ssize_t len; int fd; + int size; + void * addr_ptr; + void * src_ptr;
Wi-Fi service won't auto-connect when Ethernet is already present
I'm using ConnMan v1.30 on a BeagleBone Black based system. I've got a USB Wi-Fi device, as well as Ethernet. Is it possible to configure ConnMan so that it will auto-connect Wi-Fi even if it's got an Ethernet connection? Ethernet would still be "preferred" in the sense of having the default route. But I want Wi-Fi to always connect if an auto-connect service is available, even while Ethernet is present. If Wi-Fi connects while Ethernet is unplugged, then later Ethernet is plugged in, then they can both be connected at the same time, which is good. But if Ethernet connects first, and the USB Wi-Fi device is plugged in later, then it won't auto-connect to the configured Wi-Fi service, and I wish it would. I've read the "Preferred Technologies" section of the ConnMan web site documentation page. It sounds as though there are twists indeed. Can the "Preferred Technologies" feature be disabled? I tried putting in my /etc/connman/main.conf: PreferredTechnologies = But that didn't seem to make a difference. -- Craig McQueen ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
ConnMan doesn't clear rfkill softblock when Wi-Fi plugged in after start-up
Consider this pre-condition: * ConnMan is configured for Wi-Fi enabled and tethered. * USB Wi-Fi device is not plugged in. * Linux rfkill softblock is enabled for wlan. Now, consider this scenario: * ConnMan was not running. * USB Wi-Fi device is plugged in. * ConnMan is started. In that scenario, ConnMan detects the Wi-Fi technology, enables it, turns off the rfkill softblock for wlan, and starts tethering. Good! Now consider this alternative scenario: * ConnMan is running. * USB Wi-Fi device is plugged in. In this scenario, ConnMan detects the Wi-Fi technology, but doesn't enable it because of the rfkill softblock for wlan. In this second scenario, I would wish for ConnMan to turn off the rfkill softblock for wlan (since it is configured for Wi-Fi enabled and tethered), and start tethering. What code change would be needed to achieve that? -- Craig McQueen ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: searchdns does not work in connman 1.30
On 27.10.2015 15:49, Pasi Sjöholm wrote: > On 27.10.2015 15:00, SpiderX wrote: >> This was fixed once (see commit >> http://git.kernel.org/cgit/network/connman/connman.git/commit/src/dnsproxy.c?h=1.30&id=0439194ed0c5a90f61dbef86d9a51307764da2d7), >> but then was refactored in later commits Technically that commit is still working but the thing is that the uncompress() and forward_dns_reply() are not able to handle few special cases. > I'm able to reproduce the issue. However it seems that connman's > dnsproxy properly caches the response, so if I do "host -v -t a bz" > immediately after the first query there will be a proper response. Ok, it's not ConnMan's cache from where the response comes correctly on the next time. The issue is: 1) Some upstream DNS-servers add details in the Authority and additional sections of the reply when being queried. Eg. dnsmasq does this on this on replies not coming from it's cache but for ones coming from the cache it replies only the asked records. First query: host -t a -v bz.siirappi.com --cut-- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31498 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 3 ;; QUESTION SECTION: ;bz.siirappi.com. IN A ;; ANSWER SECTION: bz.siirappi.com.60 IN A 1.2.3.4 ;; AUTHORITY SECTION: siirappi.com. 3367IN NS ns2.afraid.org. siirappi.com. 3367IN NS ns1.siirappi.com. ;; ADDITIONAL SECTION:http://git.kernel.org/cgit/network/connman/connman.git/tree/src/dnsproxy.c#n2056 ns1.siirappi.com. 60 IN 2001:41d0:8:196a::2 ns2.afraid.org. 67 IN A 208.43.71.243 ns2.afraid.org. 67 IN 2607:f0d0:3001:92::2 --cut-- Second query (from cache): --cut-- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53006 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;bz.siirappi.com. IN A ;; ANSWER SECTION: bz.siirappi.com.53 IN A 1.2.3.4 --cut-- 2) As a workaround Google's public DNS-servers seem not to have any authority / additional sections in their replies. Those should work ok. 3) For me the uncompress() returns null when being asked to uncompress nscount from the replies and that's enough for it to bail out. (http://git.kernel.org/cgit/network/connman/connman.git/tree/src/dnsproxy.c#n2056) --cut-- connmand[10470]: src/dnsproxy.c:forward_dns_reply() req 0x18c02b0 dstid 0x8fe0 altid 0x0865 rcode 0 connmand[10470]: src/dnsproxy.c:uncompress() count 1 ptr 0xbe9d2575 end 0xbe9d260b uptr 0xbe9d2128 connmand[10470]: src/dnsproxy.c:uncompress() pos 2 ulen 16 left 1017 name bsiirappicom connmand[10470]: src/dnsproxy.c:uncompress() count 2 ptr 0xbe9d2585 end 0xbe9d260b uptr 0xbe9d2147 connmand[10470]: src/dnsproxy.c:uncompress() pos 2 ulen 13 left 986 namesiirappicom connmand[10470]: src/dnsproxy.c:uncompress() pos 6 ulen 17 left 962 name nssiirappicom connmand[10470]: src/dnsproxy.c:uncompress() failed dns_class != ns_c_in --cut-- So I guess the bug itself is in the uncompress()-function. JukkaR: can you please help me with this one as you know how the uncompress() should work? Br, Pasi ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: connmanctl quitting before multiple return functions called
Hi, On Thu, 2015-10-15 at 15:41 +1100, Craig McQueen wrote: > I agree, it would be best if connmanctl exits after all the method > calls have completed. I'd be happy to do a patch in principle, however > I'm new to this D-Bus stuff and unfamiliar with the connman codebase, > so at this point I'm not sure what is an architecturally elegant way > to fix this. E.g., would it a counter which increments for each method > call, and decrements when its response is received Yes, that should work. > (and if so, does it need locks to be thread safe)? This is entirely single threaded using a main loop. No locking structures needed. > Or, is there some existing D-Bus code that already provides such > functionality, e.g. returning true when there are no method calls > waiting for a response? Currently not. Looks like the 'config' command has the same problem here. But that is a different "bug"... Cheers, Patrik ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: [PATCH] connmanctl: Implement clock API with new clock commands
Hi, On Thu, 2015-10-15 at 15:07 +1100, Craig McQueen wrote: > --- > > I'm not sure if you would like this use of commands. I'm interested not > only in _setting_ clock settings, but also in reading them conveniently. > The precedent in connmanctl is that there is one command to configure a > service ('config'), and a separate command to see its properties > ('services'). So for net.connman.Clock, the analagous commands are > 'configclock' to configure, and 'clock' to read. But 'clock' also takes > parameters which allow individual properties to be read. Here I'd go for the simpler option of just having a 'clock' command that shows all Clock properties. This way it is similar to 'technologies' and 'state' commands. > My earlier e-mail-- > "connmanctl quitting before multiple return functions called" -- > can be seen with the 'clock' command, reading multiple items. E.g.: > > connmanctl clock time timeupdates timezone > > which on my ARM embedded Linux based system, sometimes gets all three > responses, but often only two. > > client/commands.c | 273 > ++ > client/dbus_helpers.c | 6 ++ > 2 files changed, 279 insertions(+) > > diff --git a/client/commands.c b/client/commands.c > index 3bfdfd7..8b56965 100644 > --- a/client/commands.c > +++ b/client/commands.c > @@ -291,6 +291,75 @@ static int peers_list(DBusMessageIter *iter, > return 0; > } > > +static int one_object_properties(DBusMessageIter *iter, > + const char *error, void *user_data) > +{ > + DBusMessageIter dict; > + > + if (!error) { > + dbus_message_iter_recurse(iter, &dict); > + __connmanctl_dbus_print(&dict, "", " = ", "\n"); > + > + fprintf(stdout, "\n"); > + > + } else { > + fprintf(stderr, "Error: %s\n", error); > + } > + > + return 0; > +} > + > +static int one_object_one_property(DBusMessageIter *iter, > + const char *error, void *user_data) > +{ > + char *property = user_data; > + int arg_type; > + DBusMessageIter dict; > + DBusMessageIter entry; > + DBusMessageIter iter2; > + char *str; > + > + if (error) { > + fprintf(stderr, "Error: %s\n", error); > + return 0; > + } > + > + dbus_message_iter_recurse(iter, &dict); > + while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) { > + dbus_message_iter_recurse(&dict, &entry); > + arg_type = dbus_message_iter_get_arg_type(&entry); > + if (arg_type == DBUS_TYPE_STRING) { > + dbus_message_iter_get_basic(&entry, &str); > + } else { > + str = ""; > + } > + if (g_strcmp0(str, property) == 0) { > + dbus_message_iter_next(&entry); > + while (dbus_message_iter_get_arg_type(&entry) == > DBUS_TYPE_VARIANT) { > + dbus_message_iter_recurse(&entry, &iter2); > + entry = iter2; > + } > + switch (dbus_message_iter_get_arg_type(&entry)) { > + case DBUS_TYPE_STRUCT: > + case DBUS_TYPE_ARRAY: > + case DBUS_TYPE_DICT_ENTRY: > + dbus_message_iter_recurse(&entry, &iter2); > + __connmanctl_dbus_print(&iter2, "", "=", " "); > + break; > + default: > + __connmanctl_dbus_print(&entry, "", " = ", " = > "); > + break; > + } > + break; > + } > + dbus_message_iter_next(&dict); > + } > + > + fprintf(stdout, "\n"); > + > + return 0; > +} > + > static int object_properties(DBusMessageIter *iter, > const char *error, void *user_data) > { > @@ -1188,6 +1257,189 @@ static int cmd_config(char *args[], int num, struct > connman_option *options) > return result; > } > > +static int configclock_return(DBusMessageIter *iter, const char *error, > + void *user_data) > +{ > + char *property = user_data; > + > + if (error) > + fprintf(stderr, "Error %s: %s\n", property, error); > + > + g_free(user_data); > + > + return 0; > +} > + > +static int cmd_clock(char *args[], int num, struct connman_option *options) > +{ > + int result = 0, res = 0, index = 1, oldindex = 0; > + int c; > + char *path; > + char **opt_start; > + struct config_append append; > + > + if (num == 1) { > + return __connmanctl_dbus_method_call(connection, > CONNMAN_SERVICE, "/", > + "net.connman.Clock", "GetProperties", > + one_object_properties, NULL
Re: Re: [PATCH] Set exit value in connmanctl
> > + if (!strncmp("Already ",error,8)) > > + ret = -2; > > + else > > + ret = -1; > > I don't think one can rely on the string here. It's a semi-descriptive > one that may be used for logging or other purposes, but not much else. Yes. A better way would be to look at DBusError.name, but that is not available without changing connmanctl_dbus_method_return_func_t > The code is looking for -EINPROGRESS in dbus_method_reply(), so "proper" > values from errno*.h shall be used. What if this just sets the return > value to -EOPNOTSUPP? Ok, I'll make another patch some day. ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman