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
