# HG changeset patch # User Samuel Tesla # Date 1232263385 0 # Node ID 757d716a8f8a37786ca983ab5a17f7124f4e93b1 # Parent 0f0cb6b6d6e07c5d99ce1ba47d1f443b5ba4437e Applied ksmith's DNS patch. * Use SRV records when available. * Fallback to A records. * Use port specified in SRV record, else default. diff -r 0f0cb6b6d6e0 -r 757d716a8f8a loudmouth/lm-blocking-resolver.c --- a/loudmouth/lm-blocking-resolver.c Tue Jan 13 19:09:54 2009 +0000 +++ b/loudmouth/lm-blocking-resolver.c Sun Jan 18 07:23:05 2009 +0000 @@ -62,8 +62,8 @@ resolver_class->lookup = blocking_resolver_lookup; resolver_class->cancel = blocking_resolver_cancel; - - g_type_class_add_private (object_class, + + g_type_class_add_private (object_class, sizeof (LmBlockingResolverPriv)); } @@ -88,13 +88,14 @@ (G_OBJECT_CLASS (lm_blocking_resolver_parent_class)->finalize) (object); } -static void +static gboolean blocking_resolver_lookup_host (LmBlockingResolver *resolver) { gchar *host; struct addrinfo req; struct addrinfo *ans; int err; + gboolean retval = TRUE; g_object_get (resolver, "host", &host, NULL); @@ -105,37 +106,27 @@ req.ai_socktype = SOCK_STREAM; req.ai_protocol = IPPROTO_TCP; -g_print ("blocking_resolver_lookup_host; looking up: %s\n",host); - err = getaddrinfo (host, NULL, &req, &ans); if (err != 0) { - /* FIXME: Report error */ - g_print ("blocking_resolver_lookup_host ERROR: %d in %s\n", err, G_STRFUNC); - _lm_resolver_set_result (LM_RESOLVER (resolver), LM_RESOLVER_RESULT_FAILED, NULL); - - return; + + retval = FALSE; } if (ans == NULL) { /* Couldn't find any results */ - /* FIXME: Report no results */ - g_print ("No results in %s\n", G_STRFUNC); - _lm_resolver_set_result (LM_RESOLVER (resolver), LM_RESOLVER_RESULT_FAILED, NULL); - return; + retval = FALSE; } /* FIXME: How to set and iterate the results */ /*priv->results = ans; priv->cur_result = ans; */ - g_print ("Found result for %s\n", host); - g_object_ref (resolver); _lm_resolver_set_result (LM_RESOLVER (resolver), LM_RESOLVER_RESULT_OK, @@ -144,9 +135,11 @@ g_object_unref (resolver); g_free (host); + + return retval; } -static void +static gboolean blocking_resolver_lookup_service (LmBlockingResolver *resolver) { gchar *domain; @@ -158,6 +151,7 @@ gboolean result; unsigned char srv_ans[SRV_LEN]; int len; + gboolean retval = TRUE; g_object_get (resolver, "domain", &domain, @@ -167,21 +161,17 @@ srv = _lm_resolver_create_srv_string (domain, service, protocol); -g_print ("blocking_resolver_lookup_service: %s\n",srv); - res_init (); len = res_query (srv, C_IN, T_SRV, srv_ans, SRV_LEN); - result = _lm_resolver_parse_srv_response (srv_ans, len, + result = _lm_resolver_parse_srv_response (srv_ans, len, &new_server, &new_port); if (result == FALSE) { - g_print ("Error while parsing srv response in %s\n", - G_STRFUNC); - /* FIXME: Report error */ + retval = FALSE; } - g_object_set (resolver, + g_object_set (resolver, "host", new_server, "port", new_port, NULL); @@ -198,10 +188,12 @@ g_free (domain); g_free (service); g_free (protocol); + + return retval; } static gboolean -blocking_resolver_idle_lookup (LmBlockingResolver *resolver) +blocking_resolver_idle_lookup (LmBlockingResolver *resolver) { LmBlockingResolverPriv *priv = GET_PRIV (resolver); gint type; @@ -237,7 +229,7 @@ g_object_get (resolver, "context", &context, NULL); - priv->idle_source = lm_misc_add_idle (context, + priv->idle_source = lm_misc_add_idle (context, (GSourceFunc) blocking_resolver_idle_lookup, resolver); } diff -r 0f0cb6b6d6e0 -r 757d716a8f8a loudmouth/lm-old-socket.c --- a/loudmouth/lm-old-socket.c Tue Jan 13 19:09:54 2009 +0000 +++ b/loudmouth/lm-old-socket.c Sun Jan 18 07:23:05 2009 +0000 @@ -74,7 +74,7 @@ GSource *watch_connect; gboolean cancel_open; - + GSource *watch_out; GString *out_buf; @@ -88,11 +88,11 @@ guint ref_count; LmResolver *resolver; -}; +}; static void socket_free (LmOldSocket *socket); static gboolean socket_do_connect (LmConnectData *connect_data); -static gboolean socket_connect_cb (GIOChannel *source, +static gboolean socket_connect_cb (GIOChannel *source, GIOCondition condition, LmConnectData *connect_data); static gboolean socket_in_event (GIOChannel *source, @@ -104,7 +104,7 @@ static gboolean socket_error_event (GIOChannel *source, GIOCondition condition, LmOldSocket *socket); -static gboolean socket_buffered_write_cb (GIOChannel *source, +static gboolean socket_buffered_write_cb (GIOChannel *source, GIOCondition condition, LmOldSocket *socket); static void socket_close_io_channel (GIOChannel *io_channel); @@ -128,7 +128,7 @@ if (socket->proxy) { lm_proxy_unref (socket->proxy); } - + if (socket->out_buf) { g_string_free (socket->out_buf, TRUE); } @@ -152,8 +152,8 @@ gsize bytes_written; while (io_status == G_IO_STATUS_AGAIN) { - io_status = g_io_channel_write_chars (socket->io_channel, - buf, len, + io_status = g_io_channel_write_chars (socket->io_channel, + buf, len, &bytes_written, NULL); } @@ -185,7 +185,7 @@ len - b_written); return len; } - + return b_written; } @@ -202,7 +202,7 @@ *hangup = FALSE; if (socket->ssl_started) { - status = _lm_ssl_read (socket->ssl, + status = _lm_ssl_read (socket->ssl, buf, buf_size - 1, bytes_read); } else { status = g_io_channel_read_chars (socket->io_channel, @@ -229,7 +229,7 @@ /* Notify connection_in_event that we hangup the connection */ *hangup = TRUE; - + return FALSE; } @@ -254,17 +254,17 @@ return FALSE; } - while (socket_read_incoming (socket, buf, IN_BUFFER_SIZE, + while (socket_read_incoming (socket, buf, IN_BUFFER_SIZE, &bytes_read, &hangup, &reason)) { - - g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "\nRECV [%d]:\n", + + g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "\nRECV [%d]:\n", (int)bytes_read); - g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, + g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "-----------------------------------\n"); g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "'%s'\n", buf); - g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, + g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "-----------------------------------\n"); - + lm_verbose ("Read: %d chars\n", (int)bytes_read); (socket->data_func) (socket, buf, socket->user_data); @@ -281,22 +281,22 @@ return TRUE; } - + static gboolean socket_hup_event (GIOChannel *source, GIOCondition condition, LmOldSocket *socket) { - lm_verbose ("HUP event: %d->'%s'\n", + lm_verbose ("HUP event: %d->'%s'\n", condition, lm_misc_io_condition_to_str (condition)); if (!socket->io_channel) { return FALSE; } - (socket->closed_func) (socket, LM_DISCONNECT_REASON_HUP, + (socket->closed_func) (socket, LM_DISCONNECT_REASON_HUP, socket->user_data); - + return TRUE; } @@ -305,16 +305,16 @@ GIOCondition condition, LmOldSocket *socket) { - lm_verbose ("ERROR event: %d->'%s'\n", + lm_verbose ("ERROR event: %d->'%s'\n", condition, lm_misc_io_condition_to_str (condition)); if (!socket->io_channel) { return FALSE; } - (socket->closed_func) (socket, LM_DISCONNECT_REASON_ERROR, + (socket->closed_func) (socket, LM_DISCONNECT_REASON_ERROR, socket->user_data); - + return TRUE; } @@ -340,7 +340,7 @@ ssl_verify_domain = socket->domain; else ssl_verify_domain = socket->server; - + if (!_lm_ssl_begin (socket->ssl, socket->fd, ssl_verify_domain, &error)) { lm_verbose ("Could not begin SSL\n"); @@ -356,12 +356,12 @@ if (!delayed && socket->connect_func) { (socket->connect_func) (socket, FALSE, socket->user_data); } - + return FALSE; } #ifdef HAVE_GNUTLS - _lm_sock_set_blocking (socket->fd, FALSE); + _lm_sock_set_blocking (socket->fd, FALSE); #endif socket->ssl_started = TRUE; @@ -383,7 +383,7 @@ _lm_old_socket_succeeded (LmConnectData *connect_data) { LmOldSocket *socket; - + socket = connect_data->socket; if (socket->watch_connect) { @@ -399,7 +399,7 @@ } return; } - + socket->fd = connect_data->fd; socket->io_channel = connect_data->io_channel; @@ -416,7 +416,7 @@ } } - socket->watch_in = + socket->watch_in = lm_misc_add_io_watch (socket->context, socket->io_channel, G_IO_IN, @@ -428,13 +428,13 @@ * windows handles watches, see bug #331214. */ #ifndef G_OS_WIN32 - socket->watch_err = + socket->watch_err = lm_misc_add_io_watch (socket->context, socket->io_channel, G_IO_ERR, (GIOFunc) socket_error_event, socket); - + socket->watch_hup = lm_misc_add_io_watch (socket->context, socket->io_channel, @@ -448,19 +448,19 @@ } } -gboolean -_lm_old_socket_failed_with_error (LmConnectData *connect_data, int error) +gboolean +_lm_old_socket_failed_with_error (LmConnectData *connect_data, int error) { LmOldSocket *socket; - + g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "Connection failed: %s (error %d)\n", _lm_sock_get_error_str (error), error); - + socket = lm_old_socket_ref (connect_data->socket); connect_data->current_addr = lm_resolver_results_get_next (socket->resolver); - + if (socket->watch_connect) { g_source_destroy (socket->watch_connect); socket->watch_connect = NULL; @@ -469,12 +469,12 @@ if (connect_data->io_channel != NULL) { socket_close_io_channel (connect_data->io_channel); } - + if (connect_data->current_addr == NULL) { if (socket->connect_func) { (socket->connect_func) (socket, FALSE, socket->user_data); } - + /* if the user callback called connection_close(), this is already freed */ if (socket->connect_data != NULL) { if (socket->resolver) { @@ -494,17 +494,17 @@ return FALSE; } -gboolean +gboolean _lm_old_socket_failed (LmConnectData *connect_data) { return _lm_old_socket_failed_with_error (connect_data, _lm_sock_get_last_error()); } -static gboolean -socket_connect_cb (GIOChannel *source, +static gboolean +socket_connect_cb (GIOChannel *source, GIOCondition condition, - LmConnectData *connect_data) + LmConnectData *connect_data) { LmOldSocket *socket; struct addrinfo *addr; @@ -539,7 +539,7 @@ fd = g_io_channel_unix_get_fd (source); - res = _lm_sock_connect (fd, addr->ai_addr, (int)addr->ai_addrlen); + res = _lm_sock_connect (fd, addr->ai_addr, (int)addr->ai_addrlen); if (res < 0) { err = _lm_sock_get_last_error (); if (_lm_sock_is_blocking_success (err)) { @@ -547,10 +547,10 @@ g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "Connection success (1).\n"); - + _lm_old_socket_succeeded (connect_data); } - + if (_lm_connection_async_connect_waiting (socket->connection) && !_lm_sock_is_blocking_error (err)) { g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, @@ -562,14 +562,14 @@ socket->watch_connect = NULL; goto out; } - } + } } else { #endif - { + { /* for blocking sockets, G_IO_OUT means we are connected */ g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "Connection success (2).\n"); - + _lm_old_socket_succeeded (connect_data); } @@ -577,12 +577,12 @@ out: lm_old_socket_unref(socket); - - return result; + + return result; } static gboolean -socket_do_connect (LmConnectData *connect_data) +socket_do_connect (LmConnectData *connect_data) { LmOldSocket *socket; LmOldSocketT fd; @@ -591,16 +591,20 @@ char name[NI_MAXHOST]; char portname[NI_MAXSERV]; struct addrinfo *addr; - + socket = connect_data->socket; addr = connect_data->current_addr; - + + if (socket->port == 0) { + socket->port = 5222; + } + if (socket->proxy) { port = htons (lm_proxy_get_port (socket->proxy)); } else { port = htons (socket->port); } - + ((struct sockaddr_in *) addr->ai_addr)->sin_port = port; res = getnameinfo (addr->ai_addr, @@ -608,20 +612,21 @@ name, sizeof (name), portname, sizeof (portname), NI_NUMERICHOST | NI_NUMERICSERV); - + if (res < 0) { return _lm_old_socket_failed (connect_data); } g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "Trying %s port %s...\n", name, portname); - + fd = _lm_sock_makesocket (addr->ai_family, - addr->ai_socktype, + addr->ai_socktype, addr->ai_protocol); - + if (!_LM_SOCK_VALID (fd)) { - g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, + g_print("invalid fd\n"); + g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "Failed making socket, error:%d...\n", _lm_sock_get_last_error ()); @@ -634,18 +639,18 @@ */ connect_data->fd = fd; connect_data->io_channel = g_io_channel_unix_new (fd); - + g_io_channel_set_encoding (connect_data->io_channel, NULL, NULL); g_io_channel_set_buffered (connect_data->io_channel, FALSE); - + _lm_sock_set_blocking (connect_data->fd, FALSE); - + if (socket->proxy) { socket->watch_connect = lm_misc_add_io_watch (socket->context, connect_data->io_channel, G_IO_OUT|G_IO_ERR, - (GIOFunc) _lm_proxy_connect_cb, + (GIOFunc) _lm_proxy_connect_cb, connect_data); } else { socket->watch_connect = @@ -656,12 +661,13 @@ connect_data); } - res = _lm_sock_connect (connect_data->fd, - addr->ai_addr, (int)addr->ai_addrlen); + res = _lm_sock_connect (connect_data->fd, + addr->ai_addr, (int)addr->ai_addrlen); if (res < 0) { err = _lm_sock_get_last_error (); if (!_lm_sock_is_blocking_error (err)) { _lm_sock_close (connect_data->fd); + g_print("unable to connect\n"); return _lm_old_socket_failed_with_error (connect_data, err); } } @@ -699,7 +705,7 @@ } static gboolean -socket_buffered_write_cb (GIOChannel *source, +socket_buffered_write_cb (GIOChannel *source, GIOCondition condition, LmOldSocket *socket) { @@ -715,7 +721,7 @@ b_written = old_socket_do_write (socket, out_buf->str, out_buf->len); if (b_written < 0) { - (socket->closed_func) (socket, LM_DISCONNECT_REASON_ERROR, + (socket->closed_func) (socket, LM_DISCONNECT_REASON_ERROR, socket->user_data); return FALSE; } @@ -742,7 +748,7 @@ { gint fd; - g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, + g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "Freeing up IOChannel and file descriptor\n"); fd = g_io_channel_unix_get_fd (io_channel); @@ -774,16 +780,16 @@ return; } - socket->connect_data->current_addr = + socket->connect_data->current_addr = lm_resolver_results_get_next (resolver); socket_do_connect (socket->connect_data); } -/* FIXME: Need to have a way to only get srv reply and then decide if the - * resolver should continue to look the host up. +/* FIXME: Need to have a way to only get srv reply and then decide if the + * resolver should continue to look the host up. * - * This is needed for the case when we do a SRV lookup to lookup the + * This is needed for the case when we do a SRV lookup to lookup the * real host of the service and then connect to it through a proxy. */ static void @@ -793,7 +799,7 @@ { LmOldSocket *socket = (LmOldSocket *) user_data; const gchar *remote_addr; - + lm_verbose ("LmOldSocket::srv_cb (result=%d)\n", result); if (result != LM_RESOLVER_RESULT_OK) { @@ -806,17 +812,20 @@ if (socket->proxy) { remote_addr = lm_proxy_get_server (socket->proxy); - } else { + } else if (socket->server) { remote_addr = socket->server; } - + else { + remote_addr = socket->domain; + } + g_object_unref (socket->resolver); - - socket->resolver = + + socket->resolver = lm_resolver_new_for_host (remote_addr, old_socket_resolver_host_cb, socket); - + lm_resolver_lookup (socket->resolver); } @@ -829,7 +838,7 @@ LmConnection *connection, const gchar *server, const gchar *domain, - guint port, + guint port, LmSSL *ssl, LmProxy *proxy, GError **error) @@ -874,10 +883,10 @@ socket->resolver = lm_resolver_new_for_service (socket->domain, "xmpp-client", "tcp", - old_socket_resolver_srv_cb, + old_socket_resolver_srv_cb, socket); } else { - socket->resolver = + socket->resolver = lm_resolver_new_for_host (socket->server ? socket->server : socket->domain, old_socket_resolver_host_cb, socket); @@ -890,25 +899,10 @@ socket->data_func = data_func; socket->closed_func = closed_func; socket->connect_func = connect_func; - socket->user_data = user_data; - + socket->user_data = user_data; + lm_resolver_lookup (socket->resolver); -#if 0 - if (socket->connect_data == NULL) { - /* Open failed synchronously, probably a DNS lookup problem */ - lm_old_socket_unref(socket); - - g_set_error (error, - LM_ERROR, - LM_ERROR_CONNECTION_FAILED, - "Failed to resolve server"); - - return NULL; - } - -#endif - return socket; } @@ -932,7 +926,7 @@ g_source_destroy (socket->watch_connect); socket->watch_connect = NULL; } - + data = socket->connect_data; if (data) { socket->connect_data = NULL; @@ -1043,6 +1037,3 @@ return lm_ssl_get_require_starttls (socket->ssl); } - - - diff -r 0f0cb6b6d6e0 -r 757d716a8f8a loudmouth/lm-sock.c --- a/loudmouth/lm-sock.c Tue Jan 13 19:09:54 2009 +0000 +++ b/loudmouth/lm-sock.c Sun Jan 18 07:23:05 2009 +0000 @@ -67,34 +67,34 @@ WSADATA data; int error; #endif /* G_OS_WIN32 */ - + if (initialised) { return TRUE; } lm_verbose ("Socket library initialising...\n"); - + #ifdef G_OS_WIN32 lm_verbose ("Checking for winsock 2.0 or above...\n"); - + version = MAKEWORD (2, 0); - + error = WSAStartup (version, &data); if (error != 0) { g_printerr ("WSAStartup() failed, error:%d\n", error); return FALSE; } - + /* Confirm that the WinSock DLL supports 2.0. - * Note that if the DLL supports versions greater - * than 2.0 in addition to 2.0, it will still return - * 2.0 in wVersion since that is the version we - * requested. + * Note that if the DLL supports versions greater + * than 2.0 in addition to 2.0, it will still return + * 2.0 in wVersion since that is the version we + * requested. */ if (LOBYTE (data.wVersion) != 2 || HIBYTE (data.wVersion) != 0) { /* Tell the user that we could not find a usable - * WinSock DLL. + * WinSock DLL. */ g_printerr ("Socket library version is not sufficient!\n"); WSACleanup (); @@ -103,7 +103,7 @@ #endif /* G_OS_WIN32 */ initialised = TRUE; - + return TRUE; } @@ -124,7 +124,7 @@ } void -_lm_sock_set_blocking (LmOldSocketT sock, +_lm_sock_set_blocking (LmOldSocketT sock, gboolean block) { int res; @@ -161,16 +161,16 @@ LmOldSocketT _lm_sock_makesocket (int af, - int type, + int type, int protocol) { return (LmOldSocketT)socket (af, type, protocol); } -int -_lm_sock_connect (LmOldSocketT sock, - const struct sockaddr *name, - int namelen) +int +_lm_sock_connect (LmOldSocketT sock, + const struct sockaddr *name, + int namelen) { return connect (sock, name, namelen); } @@ -181,8 +181,8 @@ #ifndef G_OS_WIN32 return (err == _LM_SOCK_EINPROGRESS); #else /* G_OS_WIN32 */ - return (err == _LM_SOCK_EINPROGRESS || - err == _LM_SOCK_EWOULDBLOCK || + return (err == _LM_SOCK_EINPROGRESS || + err == _LM_SOCK_EWOULDBLOCK || err == _LM_SOCK_EINVAL); #endif /* G_OS_WIN32 */ } @@ -193,7 +193,7 @@ return (err == _LM_SOCK_EALREADY || err == _LM_SOCK_EISCONN); } -int +int _lm_sock_get_last_error (void) { #ifndef G_OS_WIN32 @@ -203,9 +203,9 @@ #endif /* G_OS_WIN32 */ } -void -_lm_sock_get_error (LmOldSocketT sock, - void *error, +void +_lm_sock_get_error (LmOldSocketT sock, + void *error, socklen_t *len) { getsockopt (sock, SOL_SOCKET, SO_ERROR, (void*) error, len); @@ -219,7 +219,7 @@ #else /* G_OS_WIN32 */ switch (err) { case WSAEINTR: return _("Connect interrupted and canceled"); - case WSAEACCES: return _("Permission denied"); + case WSAEACCES: return _("Permission denied"); case WSAEFAULT: return _("Bad address"); case WSAEINVAL: return _("Invalid argument"); case WSAEMFILE: return _("Too many open sockets"); @@ -270,7 +270,7 @@ /* os dependent */ case WSASYSCALLFAILURE: return _("System call failure"); } - + return _("Unknown"); #endif /* G_OS_WIN32 */ } @@ -279,23 +279,23 @@ _lm_sock_addrinfo_get_error_str (int err) { switch (err) { - case EAI_AGAIN: + case EAI_AGAIN: return _("The nameserver failed to return an " "address, try again later"); - case EAI_BADFLAGS: + case EAI_BADFLAGS: return _("Internal error trying to obtain remote address"); - case EAI_FAIL: + case EAI_FAIL: return _("The nameserver encountered errors " "looking up this address"); /* EAI_NODATA is apparently missing on FreeBSD. On recent GNU libc, * it requires _GNU_SOURCE to be defined; in the unlikely case that * that GNU libc returns this value we'll return the default message */ #ifdef EAI_NODATA - case EAI_NODATA: + case EAI_NODATA: return _("The remote host exists but no address " "is available"); #endif - case EAI_NONAME: + case EAI_NONAME: return _("The remote address is unknown"); case EAI_FAMILY: case EAI_SERVICE: @@ -330,7 +330,7 @@ return FALSE; } - opt = delay; + opt = delay; if (setsockopt (sock, IPPROTO_TCP, TCP_KEEPINTVL, &opt, sizeof (opt)) < 0) { return FALSE; } @@ -354,8 +354,8 @@ } switch (addr_info.sa_family) { - case AF_INET: - + case AF_INET: + sock_addr = & (((struct sockaddr_in *) &addr_info)->sin_addr); break; case AF_INET6: @@ -372,4 +372,3 @@ return g_strdup (host); } -