On Sun, 2010-10-10 at 23:13 -0700, Xu, Martin wrote: > I just proposed. Wait for being approved.
This looks like a big patch, and we are three days from the last image. It looks like it changes some behavior, and it may very well break the connectivity UX that is on top of it. This isn't even an approved blocker. Reject, please! > > -----Original Message----- > > From: Zhu, Peter J > > Sent: Monday, October 11, 2010 2:10 PM > > To: Anas Nashif; [email protected] (announcement list); Xu, > > Martin > > Subject: RE: [meego-packaging] [meego-commits] 8278: Changes to > > MeeGo:1.1:Core:Testing/connman > > > > And more, BMC#7497 is not proposed as 1.1 release blocker yet not saying > > approval. > > > > Peter > > > > > -----Original Message----- > > > From: [email protected] > > > [mailto:[email protected]] On Behalf Of Anas Nashif > > > Sent: Monday, October 11, 2010 1:41 PM > > > To: [email protected] (announcement list); Xu, Martin > > > Cc: [email protected] > > > Subject: Re: [meego-packaging] [meego-commits] 8278: Changes to > > > MeeGo:1.1:Core:Testing/connman > > > > > > > > > On 2010-10-10, at 9:58 PM, Martin Xu wrote: > > > > > > > Hi, > > > > I have made the following changes to connman in project > > > MeeGo:1.1:Core:Testing. Please review and accept ASAP. > > > > > > > > Thank You, > > > > Martin Xu > > > > > > > > [This message was auto-generated] > > > > > > > > --- > > > > > > > > Request #8278: > > > > > > > > submit: > > > home:martin:branches:MeeGo:1.1:Core:Testing/connman(r2)(cleanup) -> > > > MeeGo:1.1:Core:Testing/connman > > > > > > > > > > > > Message: > > > > fix BMC #7497 > > > > > > > > State: new 2010-10-10T21:58:15 martin > > > > Comment: None > > > > > > > > > > > > > > > > changes files: > > > > -------------- > > > > --- connman.changes > > > > +++ connman.changes > > > > @@ -0,0 +1,3 @@ > > > > +* Sat Oct 09 2010 Martin Xu <[email protected]> - 0.60.5 > > > > +- upgrade to 0.60.5 to fix BMC #7497 > > > > + > > > > > > In the change log in the tarball there are many other bugs not mentioned > > here, > > > and that bug (7497) is not mentioned at all? What is going on here? Why > > > those > > > other bugs are not mentioned in the package changelog? > > > > > > > > > > > > +ver 0.60.5 > > > + Remove EDNS0 option (Fixes BMC #4818) > > > + Implement DNS over TCP for dnsproxy > > > + > > > +ver 0.60.4 > > > + Do not remove wifi network upon disconnection (Fixes BMC #7730, #7734) > > > + Set WiFi task scanning flag when receiving a Scanning event > > > + Implement WiFi network driver remove hook > > > + RemoveProvider argument is an object path > > > + Remove providers based on their VPN service path > > > + > > > > > > > > > > > > > > > > > > > > > > > > > > old: > > > > ---- > > > > connman-0.60.3.tar.bz2 > > > > > > > > new: > > > > ---- > > > > connman-0.60.5.tar.bz2 > > > > > > > > spec files: > > > > ----------- > > > > --- connman.spec > > > > +++ connman.spec > > > > @@ -7,7 +7,7 @@ > > > > > > > > Name: connman > > > > Summary: Connection Manager > > > > -Version: 0.60.3 > > > > +Version: 0.60.5 > > > > Release: 1 > > > > Group: System/Networking > > > > License: GPLv2 > > > > > > > > other changes: > > > > -------------- > > > > > > > > ++++++ connman-0.60.3.tar.bz2 -> connman-0.60.5.tar.bz2 > > > > --- ChangeLog > > > > +++ ChangeLog > > > > @@ -1,3 +1,14 @@ > > > > +ver 0.60.5 > > > > + Remove EDNS0 option (Fixes BMC #4818) > > > > + Implement DNS over TCP for dnsproxy > > > > + > > > > +ver 0.60.4 > > > > + Do not remove wifi network upon disconnection (Fixes BMC #7730, > > #7734) > > > > + Set WiFi task scanning flag when receiving a Scanning event > > > > + Implement WiFi network driver remove hook > > > > + RemoveProvider argument is an object path > > > > + Remove providers based on their VPN service path > > > > + > > > > ver 0.60.3 > > > > Fix bug to remove vpn services if offline mode is on (Fixes BMC # > > > > 6591) > > > > Schedule delayed scan if disconnected from an AP (Fixes BMC #6831) > > > > --- configure > > > > +++ configure > > > > @@ -1,6 +1,6 @@ > > > > #! /bin/sh > > > > # Guess values for system-dependent variables and create Makefiles. > > > > -# Generated by GNU Autoconf 2.64 for connman 0.60.3. > > > > +# Generated by GNU Autoconf 2.64 for connman 0.60.5. > > > > # > > > > # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, > > > > # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software > > > > @@ -695,8 +695,8 @@ > > > > # Identity of this package. > > > > PACKAGE_NAME='connman' > > > > PACKAGE_TARNAME='connman' > > > > -PACKAGE_VERSION='0.60.3' > > > > -PACKAGE_STRING='connman 0.60.3' > > > > +PACKAGE_VERSION='0.60.5' > > > > +PACKAGE_STRING='connman 0.60.5' > > > > PACKAGE_BUGREPORT='' > > > > PACKAGE_URL='' > > > > > > > > @@ -1573,7 +1573,7 @@ > > > > # Omit some internal or obsolete options to make the list less > > > > imposing. > > > > # This message is too long to be a string in the A/UX 3.1 sh. > > > > cat <<_ACEOF > > > > -\`configure' configures connman 0.60.3 to adapt to many kinds of > > > > systems. > > > > +\`configure' configures connman 0.60.5 to adapt to many kinds of > > > > systems. > > > > > > > > Usage: $0 [OPTION]... [VAR=VALUE]... > > > > > > > > @@ -1643,7 +1643,7 @@ > > > > > > > > if test -n "$ac_init_help"; then > > > > case $ac_init_help in > > > > - short | recursive ) echo "Configuration of connman 0.60.3:";; > > > > + short | recursive ) echo "Configuration of connman 0.60.5:";; > > > > esac > > > > cat <<\_ACEOF > > > > > > > > @@ -1808,7 +1808,7 @@ > > > > test -n "$ac_init_help" && exit $ac_status > > > > if $ac_init_version; then > > > > cat <<\_ACEOF > > > > -connman configure 0.60.3 > > > > +connman configure 0.60.5 > > > > generated by GNU Autoconf 2.64 > > > > > > > > Copyright (C) 2009 Free Software Foundation, Inc. > > > > @@ -2266,7 +2266,7 @@ > > > > This file contains any messages produced by compilers while > > > > running configure, to aid debugging if configure makes a mistake. > > > > > > > > -It was created by connman $as_me 0.60.3, which was > > > > +It was created by connman $as_me 0.60.5, which was > > > > generated by GNU Autoconf 2.64. Invocation command line was > > > > > > > > $ $0 $@ > > > > @@ -3075,7 +3075,7 @@ > > > > > > > > # Define the identity of the package. > > > > PACKAGE='connman' > > > > - VERSION='0.60.3' > > > > + VERSION='0.60.5' > > > > > > > > > > > > cat >>confdefs.h <<_ACEOF > > > > @@ -13740,7 +13740,7 @@ > > > > # report actual input values of CONFIG_FILES etc. instead of their > > > > # values after options handling. > > > > ac_log=" > > > > -This file was extended by connman $as_me 0.60.3, which was > > > > +This file was extended by connman $as_me 0.60.5, which was > > > > generated by GNU Autoconf 2.64. Invocation command line was > > > > > > > > CONFIG_FILES = $CONFIG_FILES > > > > @@ -13804,7 +13804,7 @@ > > > > _ACEOF > > > > cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 > > > > ac_cs_version="\\ > > > > -connman config.status 0.60.3 > > > > +connman config.status 0.60.5 > > > > configured by $0, generated by GNU Autoconf 2.64, > > > > with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; > > > s/[\\""\`\$]/\\\\&/g'`\\" > > > > > > > > --- configure.ac > > > > +++ configure.ac > > > > @@ -1,5 +1,5 @@ > > > > AC_PREREQ(2.60) > > > > -AC_INIT(connman, 0.60.3) > > > > +AC_INIT(connman, 0.60.5) > > > > > > > > AM_INIT_AUTOMAKE([foreign subdir-objects]) > > > > AM_CONFIG_HEADER(config.h) > > > > --- plugins/dnsproxy.c > > > > +++ plugins/dnsproxy.c > > > > @@ -79,18 +79,24 @@ > > > > char *interface; > > > > char *domain; > > > > char *server; > > > > + int protocol; > > > > GIOChannel *channel; > > > > guint watch; > > > > + guint timeout; > > > > gboolean enabled; > > > > + gboolean connected; > > > > }; > > > > > > > > struct request_data { > > > > struct sockaddr_in sin; > > > > + int client_sk; > > > > + int protocol; > > > > socklen_t len; > > > > guint16 srcid; > > > > guint16 dstid; > > > > guint16 altid; > > > > guint timeout; > > > > + guint watch; > > > > guint numserv; > > > > guint numresp; > > > > gpointer request; > > > > @@ -105,8 +111,25 @@ > > > > static GSList *request_pending_list = NULL; > > > > static guint16 request_id = 0x0000; > > > > > > > > -static GIOChannel *listener_channel = NULL; > > > > -static guint listener_watch = 0; > > > > +static GIOChannel *udp_listener_channel = NULL; > > > > +static guint udp_listener_watch = 0; > > > > +static GIOChannel *tcp_listener_channel = NULL; > > > > +static guint tcp_listener_watch = 0; > > > > + > > > > +static int protocol_offset(int protocol) > > > > +{ > > > > + switch (protocol) { > > > > + case IPPROTO_UDP: > > > > + return 0; > > > > + > > > > + case IPPROTO_TCP: > > > > + return 2; > > > > + > > > > + default: > > > > + return -EINVAL; > > > > + } > > > > + > > > > +} > > > > > > > > static struct request_data *find_request(guint16 id) > > > > { > > > > @@ -123,7 +146,8 @@ > > > > } > > > > > > > > static struct server_data *find_server(const char *interface, > > > > - const char *domain, const char > > > > *server) > > > > + const char *domain, const char > > > > *server, > > > > + int protocol) > > > > { > > > > GSList *list; > > > > > > > > @@ -136,7 +160,8 @@ > > > > continue; > > > > > > > > if (g_str_equal(data->interface, interface) == TRUE && > > > > - g_str_equal(data->server, server) == TRUE) { > > > > + g_str_equal(data->server, server) == TRUE && > > > > + data->protocol == protocol) { > > > > if (domain == NULL) { > > > > if (data->domain == NULL) > > > > return data; > > > > @@ -151,155 +176,80 @@ > > > > return NULL; > > > > } > > > > > > > > -static gboolean server_event(GIOChannel *channel, GIOCondition > > condition, > > > > - gpointer user_data) > > > > + > > > > +static void send_response(int sk, unsigned char *buf, int len, > > > > + const struct sockaddr *to, socklen_t tolen, > > > > + int protocol) > > > > { > > > > - struct server_data *data = user_data; > > > > - struct request_data *req; > > > > - unsigned char buf[4096]; > > > > - struct domain_hdr *hdr = (void *) &buf; > > > > - int sk, err, len; > > > > + struct domain_hdr *hdr; > > > > + int err, offset = protocol_offset(protocol); > > > > > > > > - if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { > > > > - connman_error("Error with server channel"); > > > > - data->watch = 0; > > > > - return FALSE; > > > > - } > > > > + DBG(""); > > > > > > > > - sk = g_io_channel_unix_get_fd(channel); > > > > + if (offset < 0) > > > > + return; > > > > > > > > - len = recv(sk, buf, sizeof(buf), 0); > > > > if (len < 12) > > > > - return TRUE; > > > > - > > > > - DBG("Received %d bytes (id 0x%04x)", len, buf[0] | buf[1] << 8); > > > > - > > > > - req = find_request(buf[0] | buf[1] << 8); > > > > - if (req == NULL) > > > > - return TRUE; > > > > - > > > > - DBG("id 0x%04x rcode %d", hdr->id, hdr->rcode); > > > > - > > > > - buf[0] = req->srcid & 0xff; > > > > - buf[1] = req->srcid >> 8; > > > > - > > > > - req->numresp++; > > > > - > > > > - if (hdr->rcode == 0 || req->resp == NULL) { > > > > - g_free(req->resp); > > > > - req->resplen = 0; > > > > - > > > > - req->resp = g_try_malloc(len); > > > > - if (req->resp == NULL) > > > > - return TRUE; > > > > - > > > > - memcpy(req->resp, buf, len); > > > > - req->resplen = len; > > > > - } > > > > - > > > > - if (hdr->rcode > 0 && req->numresp < req->numserv) > > > > - return TRUE; > > > > - > > > > - if (req->timeout > 0) > > > > - g_source_remove(req->timeout); > > > > + return; > > > > > > > > - request_list = g_slist_remove(request_list, req); > > > > + hdr = (void*) (buf + offset); > > > > > > > > - sk = g_io_channel_unix_get_fd(listener_channel); > > > > + DBG("id 0x%04x qr %d opcode %d", hdr->id, hdr->qr, hdr->opcode); > > > > > > > > - err = sendto(sk, req->resp, req->resplen, 0, > > > > - (struct sockaddr *) &req->sin, req->len); > > > > + hdr->qr = 1; > > > > + hdr->rcode = 2; > > > > > > > > - g_free(req->resp); > > > > - g_free(req); > > > > + hdr->ancount = 0; > > > > + hdr->nscount = 0; > > > > + hdr->arcount = 0; > > > > > > > > - return TRUE; > > > > + err = sendto(sk, buf, len, 0, to, tolen); > > > > } > > > > > > > > -static struct server_data *create_server(const char *interface, > > > > - const char *domain, const char > > > > *server) > > > > +static gboolean request_timeout(gpointer user_data) > > > > { > > > > - struct server_data *data; > > > > - struct sockaddr_in sin; > > > > - int sk; > > > > + struct request_data *req = user_data; > > > > > > > > - DBG("interface %s server %s", interface, server); > > > > + DBG("id 0x%04x", req->srcid); > > > > > > > > - sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); > > > > - if (sk < 0) { > > > > - connman_error("Failed to create server %s socket", server); > > > > - return NULL; > > > > - } > > > > + if (req == NULL) > > > > + return FALSE; > > > > > > > > - if (interface != NULL) { > > > > - if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE, > > > > - interface, strlen(interface) + 1) < 0) { > > > > - connman_error("Failed to bind server %s " > > > > - "to interface %s", > > > > - server, interface); > > > > - close(sk); > > > > - return NULL; > > > > - } > > > > - } > > > > + request_list = g_slist_remove(request_list, req); > > > > + req->numserv--; > > > > > > > > - memset(&sin, 0, sizeof(sin)); > > > > - sin.sin_family = AF_INET; > > > > - sin.sin_port = htons(53); > > > > - sin.sin_addr.s_addr = inet_addr(server); > > > > + if (req->resplen > 0 && req->resp != NULL) { > > > > + int sk, err; > > > > > > > > - if (connect(sk, (struct sockaddr *) &sin, sizeof(sin)) < 0) { > > > > - connman_error("Failed to connect server %s", server); > > > > - close(sk); > > > > - return NULL; > > > > - } > > > > + sk = g_io_channel_unix_get_fd(udp_listener_channel); > > > > > > > > - data = g_try_new0(struct server_data, 1); > > > > - if (data == NULL) { > > > > - connman_error("Failed to allocate server %s data", server); > > > > - close(sk); > > > > - return NULL; > > > > - } > > > > + err = sendto(sk, req->resp, req->resplen, 0, > > > > + (struct sockaddr *) &req->sin, req->len); > > > > + } else if (req->request && req->numserv == 0) { > > > > + struct domain_hdr *hdr; > > > > > > > > - data->channel = g_io_channel_unix_new(sk); > > > > - if (data->channel == NULL) { > > > > - connman_error("Failed to create server %s channel", server); > > > > - close(sk); > > > > - g_free(data); > > > > - return NULL; > > > > + if (req->protocol == IPPROTO_TCP) { > > > > + hdr = (void *) (req->request + 2); > > > > + hdr->id = req->srcid; > > > > + send_response(req->client_sk, req->request, > > > > + req->request_len, NULL, 0, > > > > IPPROTO_TCP); > > > > + > > > > + } else if (req->protocol == IPPROTO_UDP) { > > > > + int sk; > > > > + > > > > + hdr = (void *) (req->request); > > > > + hdr->id = req->srcid; > > > > + sk = g_io_channel_unix_get_fd(udp_listener_channel); > > > > + send_response(sk, req->request, req->request_len, > > > > + (struct sockaddr *)&req->sin, > > > > + sizeof(req->sin), > > > > IPPROTO_UDP); > > > > + } > > > > } > > > > > > > > - g_io_channel_set_close_on_unref(data->channel, TRUE); > > > > - > > > > - data->watch = g_io_add_watch(data->channel, G_IO_IN, > > > > - server_event, data); > > > > - > > > > - data->interface = g_strdup(interface); > > > > - data->domain = g_strdup(domain); > > > > - data->server = g_strdup(server); > > > > - > > > > - /* Enable new servers by default */ > > > > - data->enabled = TRUE; > > > > - > > > > - connman_info("Adding DNS server %s", data->server); > > > > - > > > > - return data; > > > > -} > > > > - > > > > -static void destroy_server(struct server_data *data) > > > > -{ > > > > - DBG("interface %s server %s", data->interface, data->server); > > > > - > > > > - if (data->watch > 0) > > > > - g_source_remove(data->watch); > > > > - > > > > - g_io_channel_unref(data->channel); > > > > - > > > > - connman_info("Removing DNS server %s", data->server); > > > > + g_free(req->resp); > > > > + g_free(req); > > > > > > > > - g_free(data->server); > > > > - g_free(data->domain); > > > > - g_free(data->interface); > > > > - g_free(data); > > > > + return FALSE; > > > > } > > > > > > > > static int append_query(unsigned char *buf, unsigned int size, > > > > @@ -357,84 +307,427 @@ > > > > return ptr - buf; > > > > } > > > > > > > > -static gboolean request_timeout(gpointer user_data) > > > > +static int ns_resolv(struct server_data *server, struct request_data > > > > *req, > > > > + gpointer request, gpointer name) > > > > { > > > > - struct request_data *req = user_data; > > > > + int sk, err; > > > > > > > > - DBG("id 0x%04x", req->srcid); > > > > + sk = g_io_channel_unix_get_fd(server->channel); > > > > > > > > - request_list = g_slist_remove(request_list, req); > > > > + err = send(sk, request, req->request_len, 0); > > > > > > > > - if (req->resplen > 0 && req->resp != NULL) { > > > > - int sk, err; > > > > + req->numserv++; > > > > + > > > > + if (server->domain != NULL) { > > > > + unsigned char alt[1024]; > > > > + struct domain_hdr *hdr = (void *) &alt; > > > > + int altlen, domlen, offset; > > > > + > > > > + offset = protocol_offset(server->protocol); > > > > + if (offset < 0) > > > > + return offset; > > > > + > > > > + domlen = strlen(server->domain) + 1; > > > > + if (domlen < 5) > > > > + return -EINVAL; > > > > + > > > > + alt[offset] = req->altid & 0xff; > > > > + alt[offset + 1] = req->altid >> 8; > > > > + > > > > + memcpy(alt + offset + 2, request + offset + 2, 10); > > > > + hdr->qdcount = htons(1); > > > > + > > > > + altlen = append_query(alt + offset + 12, sizeof(alt) - 12, > > > > + name, server->domain); > > > > + if (altlen < 0) > > > > + return -EINVAL; > > > > + > > > > + altlen += 12; > > > > + > > > > + memcpy(alt + offset + altlen, > > > > + request + offset + altlen - domlen, > > > > + req->request_len - altlen + domlen); > > > > + > > > > + if (server->protocol == IPPROTO_TCP) { > > > > + int req_len = req->request_len + domlen - 1; > > > > + > > > > + alt[0] = (req_len >> 8) & 0xff; > > > > + alt[1] = req_len & 0xff; > > > > + } > > > > + > > > > + err = send(sk, alt, req->request_len + domlen + 1, 0); > > > > + > > > > + req->numserv++; > > > > + } > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int forward_dns_reply(unsigned char *reply, int reply_len, int > > > protocol) > > > > +{ > > > > + struct domain_hdr *hdr; > > > > + struct request_data *req; > > > > + int dns_id, sk, err, offset = protocol_offset(protocol); > > > > + > > > > + if (offset < 0) > > > > + return offset; > > > > + > > > > + hdr = (void *)(reply + offset); > > > > + dns_id = reply[offset] | reply[offset + 1] << 8; > > > > + > > > > + DBG("Received %d bytes (id 0x%04x)", reply_len, dns_id); > > > > + > > > > + req = find_request(dns_id); > > > > + if (req == NULL) > > > > + return -EINVAL; > > > > + > > > > + DBG("id 0x%04x rcode %d", hdr->id, hdr->rcode); > > > > + > > > > + reply[offset] = req->srcid & 0xff; > > > > + reply[offset + 1] = req->srcid >> 8; > > > > + > > > > + req->numresp++; > > > > + > > > > + if (hdr->rcode == 0 || req->resp == NULL) { > > > > + g_free(req->resp); > > > > + req->resplen = 0; > > > > + > > > > + req->resp = g_try_malloc(reply_len); > > > > + if (req->resp == NULL) > > > > + return -ENOMEM; > > > > + > > > > + memcpy(req->resp, reply, reply_len); > > > > + req->resplen = reply_len; > > > > + } > > > > + > > > > + if (hdr->rcode > 0 && req->numresp < req->numserv) > > > > + return -EINVAL; > > > > > > > > - sk = g_io_channel_unix_get_fd(listener_channel); > > > > + if (req->timeout > 0) > > > > + g_source_remove(req->timeout); > > > > + > > > > + request_list = g_slist_remove(request_list, req); > > > > > > > > + if (protocol == IPPROTO_UDP) { > > > > + sk = g_io_channel_unix_get_fd(udp_listener_channel); > > > > err = sendto(sk, req->resp, req->resplen, 0, > > > > (struct sockaddr *) &req->sin, req->len); > > > > + } else { > > > > + sk = req->client_sk; > > > > + err = send(sk, req->resp, req->resplen, 0); > > > > + close(sk); > > > > } > > > > > > > > g_free(req->resp); > > > > g_free(req); > > > > > > > > - return FALSE; > > > > + return err; > > > > } > > > > > > > > -static gboolean resolv(struct request_data *req, > > > > - gpointer request, gpointer name) > > > > +static void destroy_server(struct server_data *server) > > > > { > > > > - int sk, err; > > > > - GSList *list; > > > > + DBG("interface %s server %s", server->interface, server->server); > > > > > > > > - request_list = g_slist_append(request_list, req); > > > > + server_list = g_slist_remove(server_list, server); > > > > > > > > - req->numserv = 0; > > > > - req->timeout = g_timeout_add_seconds(5, request_timeout, req); > > > > + if (server->watch > 0) > > > > + g_source_remove(server->watch); > > > > > > > > - for (list = server_list; list; list = list->next) { > > > > - struct server_data *data = list->data; > > > > + if (server->timeout > 0) > > > > + g_source_remove(server->timeout); > > > > > > > > - DBG("server %s domain %s enabled %d", > > > > - data->server, data->domain, data->enabled); > > > > + g_io_channel_unref(server->channel); > > > > > > > > - if (data->enabled == FALSE) > > > > - continue; > > > > + if (server->protocol == IPPROTO_UDP) > > > > + connman_info("Removing DNS server %s", server->server); > > > > > > > > - sk = g_io_channel_unix_get_fd(data->channel); > > > > + g_free(server->server); > > > > + g_free(server->domain); > > > > + g_free(server->interface); > > > > + g_free(server); > > > > +} > > > > > > > > - err = send(sk, request, req->request_len, 0); > > > > +static gboolean udp_server_event(GIOChannel *channel, GIOCondition > > > condition, > > > > + gpointer user_data) > > > > +{ > > > > + struct server_data *data = user_data; > > > > + unsigned char buf[4096]; > > > > + int sk, err, len; > > > > > > > > - req->numserv++; > > > > + if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { > > > > + connman_error("Error with server channel"); > > > > + data->watch = 0; > > > > + return FALSE; > > > > + } > > > > > > > > - if (data->domain != NULL) { > > > > - unsigned char alt[1024]; > > > > - struct domain_hdr *hdr = (void *) &alt; > > > > - int altlen, domlen; > > > > + sk = g_io_channel_unix_get_fd(channel); > > > > + > > > > + len = recv(sk, buf, sizeof(buf), 0); > > > > + if (len < 12) > > > > + return TRUE; > > > > + > > > > + err = forward_dns_reply(buf, len, IPPROTO_UDP); > > > > + > > > > + return TRUE; > > > > +} > > > > + > > > > +static gboolean tcp_server_event(GIOChannel *channel, GIOCondition > > > condition, > > > > + gpointer user_data) > > > > +{ > > > > + int sk; > > > > + struct server_data *server = user_data; > > > > + > > > > + sk = g_io_channel_unix_get_fd(channel); > > > > + if (sk == 0) > > > > + return FALSE; > > > > + > > > > + if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { > > > > + GSList *list; > > > > + > > > > + DBG("TCP server channel closed"); > > > > > > > > - domlen = strlen(data->domain) + 1; > > > > - if (domlen < 5) > > > > + for (list = request_list; list; list = list->next) { > > > > + struct request_data *req = list->data; > > > > + struct domain_hdr *hdr; > > > > + > > > > + if (req->protocol == IPPROTO_UDP) > > > > + continue; > > > > + > > > > + if (req->request == NULL) > > > > continue; > > > > > > > > - alt[0] = req->altid & 0xff; > > > > - alt[1] = req->altid >> 8; > > > > + /* > > > > + * If we're not waiting for any further response > > > > + * from another name server, then we send an error > > > > + * response to the client. > > > > + */ > > > > + if (req->numserv && --(req->numserv)) > > > > + continue; > > > > + > > > > + hdr = (void *) (req->request + 2); > > > > + hdr->id = req->srcid; > > > > + send_response(req->client_sk, req->request, > > > > + req->request_len, NULL, 0, > > > > IPPROTO_TCP); > > > > + > > > > + request_list = g_slist_remove(request_list, req); > > > > + } > > > > + > > > > + destroy_server(server); > > > > + > > > > + return FALSE; > > > > + } > > > > + > > > > + if ((condition & G_IO_OUT) && !server->connected) { > > > > + GSList *list; > > > > + > > > > + server->connected = TRUE; > > > > + server_list = g_slist_append(server_list, server); > > > > + > > > > + if (server->timeout > 0) { > > > > + g_source_remove(server->timeout); > > > > + server->timeout = 0; > > > > + } > > > > > > > > - memcpy(alt + 2, request + 2, 10); > > > > - hdr->qdcount = htons(1); > > > > + for (list = request_list; list; list = list->next) { > > > > + struct request_data *req = list->data; > > > > > > > > - altlen = append_query(alt + 12, sizeof(alt) - 12, > > > > - name, data->domain); > > > > - if (altlen < 0) > > > > + if (req->protocol == IPPROTO_UDP) > > > > continue; > > > > > > > > - altlen += 12; > > > > + DBG("Sending req %s over TCP", (char *)req->name); > > > > + > > > > + if (req->timeout > 0) > > > > + g_source_remove(req->timeout); > > > > + > > > > + req->timeout = g_timeout_add_seconds(30, > > > > + request_timeout, req); > > > > + ns_resolv(server, req, req->request, req->name); > > > > + } > > > > + > > > > + } else if (condition & G_IO_IN) { > > > > + int len, bytes_recv, total_bytes_recv; > > > > + unsigned char reply_len_buf[2]; > > > > + uint16_t reply_len; > > > > + unsigned char *reply; > > > > > > > > - memcpy(alt + altlen, request + altlen - domlen, > > > > - req->request_len - altlen + domlen); > > > > + len = recv(sk, reply_len_buf, 2, 0); > > > > + if (len < 2) > > > > + return TRUE; > > > > + > > > > + reply_len = reply_len_buf[1] | reply_len_buf[0] << 8; > > > > + > > > > + DBG("TCP reply %d bytes", reply_len); > > > > + > > > > + reply = g_try_malloc(reply_len + 2); > > > > + if (reply == NULL) > > > > + return TRUE; > > > > + > > > > + reply[0] = reply_len_buf[0]; > > > > + reply[1] = reply_len_buf[1]; > > > > > > > > - err = send(sk, alt, req->request_len + domlen + 1, 0); > > > > + total_bytes_recv = bytes_recv = 0; > > > > + while (total_bytes_recv < reply_len) { > > > > + bytes_recv = recv(sk, reply + 2, reply_len, 0); > > > > + if (bytes_recv < 0) > > > > + break; > > > > > > > > - req->numserv++; > > > > + total_bytes_recv += bytes_recv; > > > > } > > > > + > > > > + forward_dns_reply(reply, reply_len + 2, IPPROTO_TCP); > > > > + > > > > + g_free(reply); > > > > + > > > > + destroy_server(server); > > > > + > > > > + return FALSE; > > > > + } > > > > + > > > > + return TRUE; > > > > +} > > > > + > > > > +static gboolean tcp_idle_timeout(gpointer user_data) > > > > +{ > > > > + struct server_data *server = user_data; > > > > + > > > > + DBG(""); > > > > + > > > > + if (server == NULL) > > > > + return FALSE; > > > > + > > > > + destroy_server(server); > > > > + > > > > + return FALSE; > > > > +} > > > > + > > > > +static struct server_data *create_server(const char *interface, > > > > + const char *domain, const char > > > > *server, > > > > + int protocol) > > > > +{ > > > > + struct server_data *data; > > > > + struct sockaddr_in sin; > > > > + int sk, type, ret; > > > > + > > > > + DBG("interface %s server %s", interface, server); > > > > + > > > > + switch (protocol) { > > > > + case IPPROTO_UDP: > > > > + type = SOCK_DGRAM; > > > > + break; > > > > + > > > > + case IPPROTO_TCP: > > > > + type = SOCK_STREAM; > > > > + break; > > > > + > > > > + default: > > > > + return NULL; > > > > + } > > > > + > > > > + data = find_server(interface, domain, server, protocol); > > > > + if (data) { > > > > + if (data->watch > 0) > > > > + g_source_remove(data->watch); > > > > + data->watch = g_io_add_watch(data->channel, > > > > + G_IO_OUT | G_IO_IN | G_IO_HUP | G_IO_NVAL | > > G_IO_ERR, > > > > + tcp_server_event, data); > > > > + return data; > > > > + } > > > > + > > > > + sk = socket(AF_INET, type, protocol); > > > > + if (sk < 0) { > > > > + connman_error("Failed to create server %s socket", server); > > > > + return NULL; > > > > + } > > > > + > > > > + if (interface != NULL) { > > > > + if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE, > > > > + interface, strlen(interface) + 1) < 0) { > > > > + connman_error("Failed to bind server %s " > > > > + "to interface %s", > > > > + server, interface); > > > > + close(sk); > > > > + return NULL; > > > > + } > > > > + } > > > > + > > > > + data = g_try_new0(struct server_data, 1); > > > > + if (data == NULL) { > > > > + connman_error("Failed to allocate server %s data", server); > > > > + close(sk); > > > > + return NULL; > > > > + } > > > > + > > > > + data->channel = g_io_channel_unix_new(sk); > > > > + if (data->channel == NULL) { > > > > + connman_error("Failed to create server %s channel", server); > > > > + close(sk); > > > > + g_free(data); > > > > + return NULL; > > > > + } > > > > + > > > > + g_io_channel_set_close_on_unref(data->channel, TRUE); > > > > + > > > > + if (protocol == IPPROTO_TCP) { > > > > + g_io_channel_set_flags(data->channel, G_IO_FLAG_NONBLOCK, > > > NULL); > > > > + data->watch = g_io_add_watch(data->channel, > > > > + G_IO_OUT | G_IO_IN | G_IO_HUP | G_IO_NVAL | > > G_IO_ERR, > > > > + tcp_server_event, data); > > > > + data->timeout = g_timeout_add_seconds(30, tcp_idle_timeout, > > > > + data); > > > > + } else > > > > + data->watch = g_io_add_watch(data->channel, G_IO_IN, > > > > + udp_server_event, data); > > > > + > > > > + data->interface = g_strdup(interface); > > > > + data->domain = g_strdup(domain); > > > > + data->server = g_strdup(server); > > > > + data->protocol = protocol; > > > > + > > > > + memset(&sin, 0, sizeof(sin)); > > > > + sin.sin_family = AF_INET; > > > > + sin.sin_port = htons(53); > > > > + sin.sin_addr.s_addr = inet_addr(server); > > > > + > > > > + ret = connect(sk, (struct sockaddr *) &sin, sizeof(sin)); > > > > + if (ret < 0) { > > > > + if ((protocol == IPPROTO_TCP && errno != EINPROGRESS) || > > > > + protocol == IPPROTO_UDP) { > > > > + connman_error("Failed to connect to server %s", > > > > server); > > > > + close(sk); > > > > + g_free(data); > > > > + return NULL; > > > > + } > > > > + } > > > > + > > > > + if (protocol == IPPROTO_UDP) { > > > > + /* Enable new servers by default */ > > > > + data->enabled = TRUE; > > > > + connman_info("Adding DNS server %s", data->server); > > > > + > > > > + server_list = g_slist_append(server_list, data); > > > > + > > > > + return data; > > > > + } > > > > + > > > > + return NULL; > > > > +} > > > > + > > > > +static gboolean resolv(struct request_data *req, > > > > + gpointer request, gpointer name) > > > > +{ > > > > + GSList *list; > > > > + > > > > + for (list = server_list; list; list = list->next) { > > > > + struct server_data *data = list->data; > > > > + > > > > + DBG("server %s domain %s enabled %d", > > > > + data->server, data->domain, data->enabled); > > > > + > > > > + if (data->enabled == FALSE) > > > > + continue; > > > > + > > > > + if (ns_resolv(data, req, request, name) < 0) > > > > + continue; > > > > } > > > > > > > > return TRUE; > > > > @@ -450,32 +743,35 @@ > > > > if (g_str_equal(server, "127.0.0.1") == TRUE) > > > > return -ENODEV; > > > > > > > > - data = create_server(interface, domain, server); > > > > + data = create_server(interface, domain, server, IPPROTO_UDP); > > > > if (data == NULL) > > > > return -EIO; > > > > > > > > - server_list = g_slist_append(server_list, data); > > > > - > > > > return 0; > > > > } > > > > > > > > -static int dnsproxy_remove(const char *interface, const char *domain, > > > > - const char *server) > > > > +static void remove_server(const char *interface, const char *domain, > > > > + const char *server, int protocol) > > > > { > > > > struct server_data *data; > > > > > > > > + data = find_server(interface, domain, server, protocol); > > > > + if (data == NULL) > > > > + return; > > > > + > > > > + destroy_server(data); > > > > +} > > > > + > > > > +static int dnsproxy_remove(const char *interface, const char *domain, > > > > + const char *server) > > > > +{ > > > > DBG("interface %s server %s", interface, server); > > > > > > > > if (g_str_equal(server, "127.0.0.1") == TRUE) > > > > return -ENODEV; > > > > > > > > - data = find_server(interface, domain, server); > > > > - if (data == NULL) > > > > - return 0; > > > > - > > > > - server_list = g_slist_remove(server_list, data); > > > > - > > > > - destroy_server(data); > > > > + remove_server(interface, domain, server, IPPROTO_UDP); > > > > + remove_server(interface, domain, server, IPPROTO_TCP); > > > > > > > > return 0; > > > > } > > > > @@ -637,28 +933,121 @@ > > > > return 0; > > > > } > > > > > > > > -static void send_response(int sk, unsigned char *buf, int len, > > > > - const struct sockaddr *to, socklen_t tolen) > > > > +static gboolean tcp_listener_event(GIOChannel *channel, GIOCondition > > > condition, > > > > + gpointer user_data) > > > > { > > > > - struct domain_hdr *hdr = (void *) buf; > > > > - int err; > > > > + unsigned char buf[768]; > > > > + char query[512]; > > > > + struct request_data *req; > > > > + struct server_data *server; > > > > + int sk, client_sk, len, err; > > > > + struct sockaddr client_addr; > > > > + socklen_t client_addr_len; > > > > + GSList *list; > > > > > > > > - if (len < 12) > > > > - return; > > > > + DBG("condition 0x%x", condition); > > > > > > > > - DBG("id 0x%04x qr %d opcode %d", hdr->id, hdr->qr, hdr->opcode); > > > > + if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { > > > > + if (tcp_listener_watch > 0) > > > > + g_source_remove(tcp_listener_watch); > > > > + tcp_listener_watch = 0; > > > > > > > > - hdr->qr = 1; > > > > - hdr->rcode = 2; > > > > + connman_error("Error with TCP listener channel"); > > > > > > > > - hdr->ancount = 0; > > > > - hdr->nscount = 0; > > > > - hdr->arcount = 0; > > > > + return FALSE; > > > > + } > > > > > > > > - err = sendto(sk, buf, len, 0, to, tolen); > > > > + sk = g_io_channel_unix_get_fd(channel); > > > > + > > > > + client_addr_len = sizeof(struct sockaddr); > > > > + client_sk = accept(sk, &client_addr, &client_addr_len); > > > > + if (client_sk < 0) { > > > > + connman_error("Accept failure on TCP listener"); > > > > + tcp_listener_watch = 0; > > > > + return FALSE; > > > > + } > > > > + > > > > + len = recv(client_sk, buf, sizeof(buf), 0); > > > > + if (len < 2) > > > > + return TRUE; > > > > + > > > > + DBG("Received %d bytes (id 0x%04x)", len, buf[2] | buf[3] << 8); > > > > + > > > > + err = parse_request(buf + 2, len - 2, query, sizeof(query)); > > > > + if (err < 0 || (g_slist_length(server_list) == 0 && > > > > + connman_ondemand_connected())) { > > > > + send_response(client_sk, buf, len, NULL, 0, IPPROTO_TCP); > > > > + return TRUE; > > > > + } > > > > + > > > > + req = g_try_new0(struct request_data, 1); > > > > + if (req == NULL) > > > > + return TRUE; > > > > + > > > > + memcpy(&req->sin, (struct sockaddr_in *)&client_addr, > > sizeof(req->sin)); > > > > + req->client_sk = client_sk; > > > > + req->protocol = IPPROTO_TCP; > > > > + req->len = client_addr_len; > > > > + > > > > + request_id += 2; > > > > + if (request_id == 0x0000 || request_id == 0xffff) > > > > + request_id += 2; > > > > + > > > > + req->srcid = buf[2] | (buf[3] << 8); > > > > + req->dstid = request_id; > > > > + req->altid = request_id + 1; > > > > + req->request_len = len; > > > > + > > > > + buf[2] = req->dstid & 0xff; > > > > + buf[3] = req->dstid >> 8; > > > > + > > > > + req->numserv = 0; > > > > + request_list = g_slist_append(request_list, req); > > > > + > > > > + for (list = server_list; list; list = list->next) { > > > > + struct server_data *data = list->data; > > > > + > > > > + if (data->protocol != IPPROTO_UDP || data->enabled == FALSE) > > > > + continue; > > > > + > > > > + server = create_server(data->interface, data->domain, > > > > + data->server, IPPROTO_TCP); > > > > + > > > > + /* > > > > + * If server is NULL, we're not connected yet. > > > > + * Copy the relevant buffers and continue with > > > > + * the next nameserver. > > > > + * The request will actually be sent once we're > > > > + * properly connected over TCP to this nameserver. > > > > + */ > > > > + if (server == NULL) { > > > > + req->request = g_try_malloc0(req->request_len); > > > > + if (req->request == NULL) > > > > + return TRUE; > > > > + > > > > + memcpy(req->request, buf, req->request_len); > > > > + > > > > + req->name = g_try_malloc0(sizeof(query)); > > > > + if (req->name == NULL) { > > > > + g_free(req->request); > > > > + return TRUE; > > > > + } > > > > + memcpy(req->name, query, sizeof(query)); > > > > + > > > > + continue; > > > > + } > > > > + > > > > + if (req->timeout > 0) > > > > + g_source_remove(req->timeout); > > > > + > > > > + req->timeout = g_timeout_add_seconds(30, request_timeout, > > req); > > > > + ns_resolv(server, req, buf, query); > > > > + } > > > > + > > > > + return TRUE; > > > > } > > > > > > > > -static gboolean listener_event(GIOChannel *channel, GIOCondition > > > condition, > > > > +static gboolean udp_listener_event(GIOChannel *channel, GIOCondition > > > condition, > > > > gpointer user_data) > > > > { > > > > unsigned char buf[768]; > > > > @@ -669,8 +1058,8 @@ > > > > int sk, err, len; > > > > > > > > if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { > > > > - connman_error("Error with listener channel"); > > > > - listener_watch = 0; > > > > + connman_error("Error with UDP listener channel"); > > > > + udp_listener_watch = 0; > > > > return FALSE; > > > > } > > > > > > > > @@ -687,7 +1076,8 @@ > > > > err = parse_request(buf, len, query, sizeof(query)); > > > > if (err < 0 || (g_slist_length(server_list) == 0 && > > > > connman_ondemand_connected())) { > > > > - send_response(sk, buf, len, (struct sockaddr *) &sin, size); > > > > + send_response(sk, buf, len, (struct sockaddr *) &sin, size, > > > > + IPPROTO_UDP); > > > > return TRUE; > > > > } > > > > > > > > @@ -696,6 +1086,8 @@ > > > > return TRUE; > > > > > > > > memcpy(&req->sin, &sin, sizeof(sin)); > > > > + req->client_sk = 0; > > > > + req->protocol = IPPROTO_UDP; > > > > req->len = size; > > > > > > > > request_id += 2; > > > > @@ -737,29 +1129,47 @@ > > > > return TRUE; > > > > } > > > > > > > > + > > > > + req->numserv = 0; > > > > + req->timeout = g_timeout_add_seconds(5, request_timeout, req); > > > > + request_list = g_slist_append(request_list, req); > > > > + > > > > return resolv(req, buf, query); > > > > } > > > > > > > > -static int create_listener(void) > > > > +static int create_dns_listener(int protocol) > > > > { > > > > - const char *ifname = "lo"; > > > > + GIOChannel *channel; > > > > + const char *ifname = "lo", *proto; > > > > struct sockaddr_in sin; > > > > - int sk; > > > > + int sk, type; > > > > > > > > DBG(""); > > > > > > > > - sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); > > > > + switch (protocol) { > > > > + case IPPROTO_UDP: > > > > + proto = "UDP"; > > > > + type = SOCK_DGRAM; > > > > + break; > > > > + > > > > + case IPPROTO_TCP: > > > > + proto = "TCP"; > > > > + type = SOCK_STREAM; > > > > + break; > > > > + > > > > + default: > > > > + return -EINVAL; > > > > + } > > > > + > > > > + sk = socket(AF_INET, type, protocol); > > > > if (sk < 0) { > > > > - connman_error("Failed to create listener socket"); > > > > + connman_error("Failed to create %s listener socket", proto); > > > > return -EIO; > > > > } > > > > > > > > - //setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); > > > > - //setsockopt(sk, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)); > > > > - > > > > if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE, > > > > ifname, strlen(ifname) + 1) < 0) { > > > > - connman_error("Failed to bind listener interface"); > > > > + connman_error("Failed to bind %s listener interface", proto); > > > > close(sk); > > > > return -EIO; > > > > } > > > > @@ -768,25 +1178,75 @@ > > > > sin.sin_family = AF_INET; > > > > sin.sin_port = htons(53); > > > > sin.sin_addr.s_addr = inet_addr("127.0.0.1"); > > > > - //sin.sin_addr.s_addr = INADDR_ANY; > > > > + sin.sin_addr.s_addr = htonl(INADDR_ANY); > > > > > > > > if (bind(sk, (struct sockaddr *) &sin, sizeof(sin)) < 0) { > > > > - connman_error("Failed to bind listener socket"); > > > > + connman_error("Failed to bind %s listener socket", proto); > > > > + close(sk); > > > > + return -EIO; > > > > + } > > > > + > > > > + if (protocol == IPPROTO_TCP && listen(sk, 10) < 0) { > > > > + connman_error("Failed to listen on TCP socket"); > > > > close(sk); > > > > return -EIO; > > > > } > > > > > > > > - listener_channel = g_io_channel_unix_new(sk); > > > > - if (listener_channel == NULL) { > > > > - connman_error("Failed to create listener channel"); > > > > + channel = g_io_channel_unix_new(sk); > > > > + if (channel == NULL) { > > > > + connman_error("Failed to create %s listener channel", proto); > > > > close(sk); > > > > return -EIO; > > > > } > > > > > > > > - g_io_channel_set_close_on_unref(listener_channel, TRUE); > > > > + g_io_channel_set_close_on_unref(channel, TRUE); > > > > + > > > > + if (protocol == IPPROTO_TCP) { > > > > + tcp_listener_channel = channel; > > > > + tcp_listener_watch = g_io_add_watch(channel, > > > > + G_IO_IN, tcp_listener_event, NULL); > > > > + } else { > > > > + udp_listener_channel = channel; > > > > + udp_listener_watch = g_io_add_watch(channel, > > > > + G_IO_IN, udp_listener_event, NULL); > > > > + } > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static void destroy_udp_listener(void) > > > > +{ > > > > + DBG(""); > > > > + > > > > + if (udp_listener_watch > 0) > > > > + g_source_remove(udp_listener_watch); > > > > + > > > > + g_io_channel_unref(udp_listener_channel); > > > > +} > > > > + > > > > +static void destroy_tcp_listener(void) > > > > +{ > > > > + DBG(""); > > > > > > > > - listener_watch = g_io_add_watch(listener_channel, G_IO_IN, > > > > - listener_event, NULL); > > > > + if (tcp_listener_watch > 0) > > > > + g_source_remove(tcp_listener_watch); > > > > + > > > > + g_io_channel_unref(tcp_listener_channel); > > > > +} > > > > + > > > > +static int create_listener(void) > > > > +{ > > > > + int err; > > > > + > > > > + err = create_dns_listener(IPPROTO_UDP); > > > > + if (err < 0) > > > > + return err; > > > > + > > > > + err = create_dns_listener(IPPROTO_TCP); > > > > + if (err < 0) { > > > > + destroy_udp_listener(); > > > > + return err; > > > > + } > > > > > > > > connman_resolver_append("lo", NULL, "127.0.0.1"); > > > > > > > > @@ -797,13 +1257,8 @@ > > > > { > > > > GSList *list; > > > > > > > > - DBG(""); > > > > - > > > > connman_resolver_remove_all("lo"); > > > > > > > > - if (listener_watch > 0) > > > > - g_source_remove(listener_watch); > > > > - > > > > for (list = request_pending_list; list; list = list->next) { > > > > struct request_data *req = list->data; > > > > > > > > @@ -836,7 +1291,8 @@ > > > > g_slist_free(request_list); > > > > request_list = NULL; > > > > > > > > - g_io_channel_unref(listener_channel); > > > > + destroy_tcp_listener(); > > > > + destroy_udp_listener(); > > > > } > > > > > > > > static int dnsproxy_init(void) > > > > --- plugins/supplicant.c > > > > +++ plugins/supplicant.c > > > > @@ -2189,15 +2189,9 @@ > > > > > > > > connman_info("%s scanning %s", task->ifname, > > > > scanning == TRUE ? "started" : "finished"); > > > > -} > > > > - > > > > -static gboolean delayed_scan(gpointer user_data) > > > > -{ > > > > - struct supplicant_task *task = user_data; > > > > > > > > - supplicant_scan(task->device); > > > > - > > > > - return FALSE; > > > > + if (scanning == TRUE) > > > > + task->scanning = TRUE; > > > > } > > > > > > > > static void state_change(struct supplicant_task *task, DBusMessage *msg) > > > > @@ -2293,13 +2287,7 @@ > > > > task_connect(task); > > > > } else > > > > task->network = NULL; > > > > - } else { > > > > - if (task->state == WPA_DISCONNECTED) > > > > - g_timeout_add_seconds(10, delayed_scan, task); > > > > - > > > > - remove_network(task); > > > > } > > > > - > > > > break; > > > > > > > > default: > > > > @@ -2522,6 +2510,25 @@ > > > > return 0; > > > > } > > > > > > > > +void supplicant_remove_network(struct connman_network *network) > > > > +{ > > > > + struct supplicant_task *task; > > > > + int index; > > > > + > > > > + DBG("network %p", network); > > > > + > > > > + index = connman_network_get_index(network); > > > > + > > > > + task = find_task_by_index(index); > > > > + if (task == NULL) > > > > + return; > > > > + > > > > + if (task->network != network) > > > > + return; > > > > + > > > > + remove_network(task); > > > > +} > > > > + > > > > static void supplicant_activate(DBusConnection *conn) > > > > { > > > > DBusMessage *message; > > > > --- plugins/supplicant.h > > > > +++ plugins/supplicant.h > > > > @@ -37,3 +37,5 @@ > > > > > > > > int supplicant_connect(struct connman_network *network); > > > > int supplicant_disconnect(struct connman_network *network); > > > > + > > > > +void supplicant_remove_network(struct connman_network *network); > > > > --- plugins/wifi.c > > > > +++ plugins/wifi.c > > > > @@ -62,6 +62,8 @@ > > > > static void network_remove(struct connman_network *network) > > > > { > > > > DBG("network %p", network); > > > > + > > > > + supplicant_remove_network(network); > > > > } > > > > > > > > static int network_connect(struct connman_network *network) > > > > --- src/inet.c > > > > +++ src/inet.c > > > > @@ -420,7 +420,7 @@ > > > > { > > > > enum connman_device_mode mode = > > > CONNMAN_DEVICE_MODE_UNKNOWN; > > > > enum connman_device_type type; > > > > - struct connman_device *device; > > > > + struct connman_device *device = NULL; > > > > char *devname, *ident = NULL; > > > > char *addr = NULL, *name = NULL, *node = NULL; > > > > > > > > @@ -459,6 +459,11 @@ > > > > break; > > > > } > > > > > > > > + if (g_strcmp0(addr, "00:00:00:00:00:00") == 0) { > > > > + connman_info("Wrong address ignoring interface %s ", > > devname); > > > > + goto done; > > > > + } > > > > + > > > > device = connman_device_create(name, type); > > > > if (device == NULL) > > > > goto done; > > > > --- src/manager.c > > > > +++ src/manager.c > > > > @@ -224,8 +224,8 @@ > > > > > > > > DBG("conn %p", conn); > > > > > > > > - dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &path, > > > > - DBUS_TYPE_INVALID); > > > > + dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, > > &path, > > > > + DBUS_TYPE_INVALID); > > > > > > > > if (__connman_security_check_privilege(msg, > > > > CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0) > > > > @@ -657,7 +657,7 @@ > > > > { "GetState", "", "s", get_state }, > > > > { "CreateProfile", "s", "o", create_profile }, > > > > { "RemoveProfile", "o", "", remove_profile }, > > > > - { "RemoveProvider", "s", "", remove_provider }, > > > > + { "RemoveProvider", "o", "", remove_provider }, > > > > { "RequestScan", "s", "", request_scan }, > > > > { "EnableTechnology", "s", "", enable_technology, > > > > G_DBUS_METHOD_FLAG_ASYNC }, > > > > --- src/provider.c > > > > +++ src/provider.c > > > > @@ -216,18 +216,30 @@ > > > > int __connman_provider_remove(const char *path) > > > > { > > > > struct connman_provider *provider; > > > > + GHashTableIter iter; > > > > + gpointer value, key; > > > > > > > > DBG("path %s", path); > > > > > > > > - provider = g_hash_table_lookup(provider_hash, path); > > > > - if (provider == NULL) { > > > > - DBG("patch %s not found", path); > > > > - return -ENXIO; > > > > - } > > > > + g_hash_table_iter_init(&iter, provider_hash); > > > > + while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) { > > > > + const char *srv_path; > > > > + provider = value; > > > > + > > > > + if (provider->vpn_service == NULL) > > > > + continue; > > > > > > > > - g_hash_table_remove(provider_hash, path); > > > > + srv_path = > > __connman_service_get_path(provider->vpn_service); > > > > + > > > > + if (g_strcmp0(srv_path, path) == 0) { > > > > + DBG("Removing VPN %s", provider->identifier); > > > > + g_hash_table_remove(provider_hash, > > > > + provider->identifier); > > > > + return 0; > > > > + } > > > > + } > > > > > > > > - return 0; > > > > + return -ENXIO; > > > > } > > > > > > > > static int set_connected(struct connman_provider *provider, > > > > --- src/resolver.c > > > > +++ src/resolver.c > > > > @@ -389,8 +389,7 @@ > > > > unsigned int count; > > > > mode_t old_umask; > > > > > > > > - content = g_string_new("# Generated by Connection Manager\n" > > > > - "options edns0\n"); > > > > + content = g_string_new("# Generated by Connection Manager\n"); > > > > > > > > /* > > > > * Nameservers are added in reverse so that the most recently > > > > --- test/disconnect-vpn > > > > +++ test/disconnect-vpn > > > > @@ -4,7 +4,7 @@ > > > > import dbus > > > > > > > > if (len(sys.argv) < 2): > > > > - print "Usage: %s <provider name> " % (sys.argv[0]) > > > > + print "Usage: %s <VPN service path> " % (sys.argv[0]) > > > > sys.exit(1) > > > > > > > > bus = dbus.SystemBus() > > > > @@ -18,5 +18,4 @@ > > > > > > > > manager.RemoveProvider(sys.argv[1]) > > > > > > > > -print "remove path is %s" %(path) > > > > > > > > > > > > ++++++ connman.yaml > > > > --- connman.yaml > > > > +++ connman.yaml > > > > @@ -1,6 +1,6 @@ > > > > Name: connman > > > > Summary: Connection Manager > > > > -Version: 0.60.3 > > > > +Version: 0.60.5 > > > > Release: 1 > > > > Group: System/Networking > > > > License: GPLv2 > > > > > > > > _______________________________________________ > > > > Meego-commits mailing list > > > > [email protected] > > > > http://lists.meego.com/listinfo/meego-commits > > > > > > _______________________________________________ > > > MeeGo-packaging mailing list > > > [email protected] > > > http://lists.meego.com/listinfo/meego-packaging > _______________________________________________ > MeeGo-packaging mailing list > [email protected] > http://lists.meego.com/listinfo/meego-packaging -- Michael Leibowitz <[email protected]> _______________________________________________ MeeGo-packaging mailing list [email protected] http://lists.meego.com/listinfo/meego-packaging
