summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2014-02-07 12:34:07 +0000
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2014-02-07 12:34:07 +0000
commit81b93ba358cb6d50e19a09369e426d81590e22f5 (patch)
tree68325f78557cc3545f8eeba098a3519ff91acda5
parent13bca976aef7a8bb13b92eb1d83f1ad77f7dcb2f (diff)
gibber-tcp-transport, gibber-sockets: sync from Gabble
This changes the API for gibber_tcp_transport_connect(): correct for that in check-gibber-listener and tube-stream.
-rw-r--r--lib/gibber/gibber-sockets.c9
-rw-r--r--lib/gibber/gibber-sockets.h2
-rw-r--r--lib/gibber/gibber-tcp-transport.c101
-rw-r--r--lib/gibber/gibber-tcp-transport.h2
-rw-r--r--lib/gibber/tests/check-gibber-listener.c5
-rw-r--r--salut/src/tube-stream.c5
6 files changed, 71 insertions, 53 deletions
diff --git a/lib/gibber/gibber-sockets.c b/lib/gibber/gibber-sockets.c
index bcedeb53..b926f902 100644
--- a/lib/gibber/gibber-sockets.c
+++ b/lib/gibber/gibber-sockets.c
@@ -27,14 +27,13 @@
#include "gibber-debug.h"
gboolean
-gibber_connect_errno_requires_retry (void)
+gibber_connect_errno_requires_retry (int err)
{
#ifdef G_OS_WIN32
- int err = WSAGetLastError ();
-
- return (err == WSAEINPROGRESS || err == WSAEALREADY);
+ return (err == WSAEINPROGRESS || err == WSAEALREADY ||
+ err == WSAEWOULDBLOCK || err == WSAEINVAL);
#else
- return (errno == EINPROGRESS || errno == EALREADY);
+ return (err == EINPROGRESS || err == EALREADY);
#endif
}
diff --git a/lib/gibber/gibber-sockets.h b/lib/gibber/gibber-sockets.h
index 5cfb3c8b..48ec4342 100644
--- a/lib/gibber/gibber-sockets.h
+++ b/lib/gibber/gibber-sockets.h
@@ -32,7 +32,7 @@
G_BEGIN_DECLS
-gboolean gibber_connect_errno_requires_retry (void);
+gboolean gibber_connect_errno_requires_retry (int err);
gboolean gibber_socket_errno_is_eafnosupport (void);
gboolean gibber_socket_errno_is_eaddrinuse (void);
void gibber_socket_set_error (GError **error, const gchar *context,
diff --git a/lib/gibber/gibber-tcp-transport.c b/lib/gibber/gibber-tcp-transport.c
index 58a74ae2..68d82963 100644
--- a/lib/gibber/gibber-tcp-transport.c
+++ b/lib/gibber/gibber-tcp-transport.c
@@ -36,6 +36,8 @@
#define DEBUG_FLAG DEBUG_NET
#include "gibber-debug.h"
+#include <gio/gio.h>
+
#include "errno.h"
G_DEFINE_TYPE(GibberTCPTransport, gibber_tcp_transport,
@@ -47,8 +49,8 @@ typedef struct _GibberTCPTransportPrivate GibberTCPTransportPrivate;
struct _GibberTCPTransportPrivate
{
GIOChannel *channel;
- struct addrinfo *ans;
- struct addrinfo *tmpaddr;
+ GList *addresses;
+ guint16 port;
guint watch_in;
gboolean dispose_has_run;
@@ -110,13 +112,8 @@ clean_all_connect_attempts (GibberTCPTransport *self)
clean_connect_attempt (self);
- if (priv->ans != NULL)
- {
- freeaddrinfo (priv->ans);
- priv->ans = NULL;
- }
-
- priv->tmpaddr = NULL;
+ g_resolver_free_addresses (priv->addresses);
+ priv->addresses = NULL;
}
void
@@ -163,15 +160,41 @@ try_to_connect (GibberTCPTransport *self)
{
GibberTCPTransportPrivate *priv = GIBBER_TCP_TRANSPORT_GET_PRIVATE (
self);
+ GSocketAddress *gaddr;
+ struct sockaddr_storage addr;
+ gssize native_size;
gint fd;
int ret;
+ int err;
+ gboolean connected = FALSE;
g_assert (priv->channel != NULL);
fd = g_io_channel_unix_get_fd (priv->channel);
- ret = connect (fd, priv->tmpaddr->ai_addr, priv->tmpaddr->ai_addrlen);
- if (ret == 0)
+ gaddr = g_inet_socket_address_new (G_INET_ADDRESS (priv->addresses->data),
+ priv->port);
+
+ native_size = g_socket_address_get_native_size (gaddr);
+ /* _get_native_size() really shouldn't fail... */
+ g_return_val_if_fail (native_size > 0, FALSE);
+ /* ...and if sockaddr_storage isn't big enough, we're basically screwed. */
+ g_return_val_if_fail ((gsize) native_size <= sizeof (addr), FALSE);
+
+ g_socket_address_to_native (gaddr, &addr, sizeof (addr), NULL);
+ ret = connect (fd, (struct sockaddr *)&addr, (gsize) native_size);
+
+#ifdef G_OS_WIN32
+ err = WSAGetLastError ();
+ connected = (ret == 0 || err == WSAEISCONN);
+#else
+ err = errno;
+ connected = (ret == 0);
+#endif
+
+ g_object_unref (gaddr);
+
+ if (connected)
{
DEBUG ("connect succeeded");
@@ -180,15 +203,17 @@ try_to_connect (GibberTCPTransport *self)
return FALSE;
}
- if (gibber_connect_errno_requires_retry ())
+ if (gibber_connect_errno_requires_retry (err))
{
/* We have to wait longer */
return TRUE;
}
clean_connect_attempt (self);
- priv->tmpaddr = priv->tmpaddr->ai_next;
+ g_object_unref (priv->addresses->data);
+ priv->addresses = g_list_remove_link (priv->addresses, priv->addresses);
new_connect_attempt (self);
+
return FALSE;
}
@@ -208,23 +233,24 @@ new_connect_attempt (GibberTCPTransport *self)
GibberTCPTransportPrivate *priv = GIBBER_TCP_TRANSPORT_GET_PRIVATE (
self);
int fd;
- char name[NI_MAXHOST], portname[NI_MAXSERV];
+ GSocketAddress *gaddr;
+ gchar *tmpstr;
- if (priv->tmpaddr == NULL)
+ if (priv->addresses == NULL)
{
/* no more candidate to try */
DEBUG ("connection failed");
goto failed;
}
- getnameinfo (priv->tmpaddr->ai_addr, priv->tmpaddr->ai_addrlen,
- name, sizeof (name), portname, sizeof (portname),
- NI_NUMERICHOST | NI_NUMERICSERV);
-
- DEBUG ("Trying %s port %s...", name, portname);
+ tmpstr = g_inet_address_to_string (G_INET_ADDRESS (priv->addresses->data));
+ DEBUG ("Trying %s port %d...", tmpstr, priv->port);
+ g_free (tmpstr);
- fd = socket (priv->tmpaddr->ai_family, priv->tmpaddr->ai_socktype,
- priv->tmpaddr->ai_protocol);
+ gaddr = g_inet_socket_address_new (G_INET_ADDRESS (priv->addresses->data),
+ priv->port);
+ fd = socket (g_socket_address_get_family (gaddr), SOCK_STREAM, IPPROTO_TCP);
+ g_object_unref (gaddr);
if (fd < 0)
{
@@ -254,37 +280,36 @@ failed:
void
gibber_tcp_transport_connect (GibberTCPTransport *tcp_transport,
- const gchar *host, const gchar *port)
+ const gchar *host, guint16 port)
{
GibberTCPTransportPrivate *priv = GIBBER_TCP_TRANSPORT_GET_PRIVATE (
tcp_transport);
- int ret = -1;
- struct addrinfo req;
+ GResolver *resolver = g_resolver_get_default ();
+ GError *error = NULL;
gibber_transport_set_state (GIBBER_TRANSPORT (tcp_transport),
GIBBER_TRANSPORT_CONNECTING);
- memset (&req, 0, sizeof (req));
- req.ai_flags = 0;
- req.ai_family = AF_UNSPEC;
- req.ai_socktype = SOCK_STREAM;
- req.ai_protocol = IPPROTO_TCP;
+ priv->port = port;
- g_assert (priv->ans == NULL);
- g_assert (priv->tmpaddr == NULL);
+ g_assert (priv->addresses == NULL);
g_assert (priv->channel == NULL);
- ret = getaddrinfo (host, port, &req, &priv->ans);
- if (ret != 0)
+ priv->addresses = g_resolver_lookup_by_name (resolver, host, NULL, &error);
+
+ if (priv->addresses == NULL)
{
- DEBUG("getaddrinfo failed: %s", gai_strerror (ret));
+ DEBUG("Address lookup failed: %s", error->message);
gibber_transport_set_state (GIBBER_TRANSPORT (tcp_transport),
GIBBER_TRANSPORT_DISCONNECTED);
- return;
- }
- priv->tmpaddr = priv->ans;
+ g_error_free (error);
+ goto out;
+ }
new_connect_attempt (tcp_transport);
+
+out:
+ g_object_unref (resolver);
}
diff --git a/lib/gibber/gibber-tcp-transport.h b/lib/gibber/gibber-tcp-transport.h
index 642fdcdc..4a6bdc4c 100644
--- a/lib/gibber/gibber-tcp-transport.h
+++ b/lib/gibber/gibber-tcp-transport.h
@@ -60,7 +60,7 @@ GibberTCPTransport *
gibber_tcp_transport_new (void);
void gibber_tcp_transport_connect (GibberTCPTransport *tcp_transport,
- const gchar *host, const gchar *port);
+ const gchar *host, guint16 port);
G_END_DECLS
diff --git a/lib/gibber/tests/check-gibber-listener.c b/lib/gibber/tests/check-gibber-listener.c
index 8f991ba6..ca84d6ca 100644
--- a/lib/gibber/tests/check-gibber-listener.c
+++ b/lib/gibber/tests/check-gibber-listener.c
@@ -62,15 +62,12 @@ static GibberTransport *
connect_to_port (int port, GMainLoop *loop)
{
GibberTCPTransport *transport;
- gchar sport[16];
-
- g_snprintf (sport, 16, "%d", port);
transport = gibber_tcp_transport_new ();
g_signal_connect (transport, "disconnected",
G_CALLBACK (disconnected_cb), loop);
- gibber_tcp_transport_connect (transport, "127.0.0.1", sport);
+ gibber_tcp_transport_connect (transport, "127.0.0.1", port);
return GIBBER_TRANSPORT (transport);
}
diff --git a/salut/src/tube-stream.c b/salut/src/tube-stream.c
index cbed76c8..3201d54f 100644
--- a/salut/src/tube-stream.c
+++ b/salut/src/tube-stream.c
@@ -767,21 +767,18 @@ new_connection_to_socket (SalutTubeStream *self,
priv->address_type == TP_SOCKET_ADDRESS_TYPE_IPV6)
{
gchar *ip;
- gchar *port_str;
guint port;
dbus_g_type_struct_get (priv->address,
0, &ip,
1, &port,
G_MAXUINT);
- port_str = g_strdup_printf ("%d", port);
transport = GIBBER_TRANSPORT (gibber_tcp_transport_new ());
gibber_tcp_transport_connect (GIBBER_TCP_TRANSPORT (transport), ip,
- port_str);
+ port);
g_free (ip);
- g_free (port_str);
}
else
{