I just proposed. Wait for being approved.

> -----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

Reply via email to