diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2014-02-07 12:34:07 +0000 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2014-02-07 12:34:07 +0000 |
commit | 81b93ba358cb6d50e19a09369e426d81590e22f5 (patch) | |
tree | 68325f78557cc3545f8eeba098a3519ff91acda5 | |
parent | 13bca976aef7a8bb13b92eb1d83f1ad77f7dcb2f (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.c | 9 | ||||
-rw-r--r-- | lib/gibber/gibber-sockets.h | 2 | ||||
-rw-r--r-- | lib/gibber/gibber-tcp-transport.c | 101 | ||||
-rw-r--r-- | lib/gibber/gibber-tcp-transport.h | 2 | ||||
-rw-r--r-- | lib/gibber/tests/check-gibber-listener.c | 5 | ||||
-rw-r--r-- | salut/src/tube-stream.c | 5 |
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 { |