libpurple/protocols/jabber/jabber.c

changeset 40105
54f0cc747958
parent 40104
59ea07d727db
child 40106
52dc2d315d73
equal deleted inserted replaced
40104:59ea07d727db 40105:54f0cc747958
33 #include "notify.h" 33 #include "notify.h"
34 #include "pluginpref.h" 34 #include "pluginpref.h"
35 #include "proxy.h" 35 #include "proxy.h"
36 #include "protocol.h" 36 #include "protocol.h"
37 #include "purpleaccountoption.h" 37 #include "purpleaccountoption.h"
38 #include "purple-gio.h"
38 #include "request.h" 39 #include "request.h"
39 #include "server.h" 40 #include "server.h"
40 #include "status.h" 41 #include "status.h"
41 #include "util.h" 42 #include "util.h"
42 #include "version.h" 43 #include "version.h"
853 854
854 jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING); 855 jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING);
855 js->inpa = purple_input_add(js->fd, PURPLE_INPUT_READ, jabber_recv_cb, gc); 856 js->inpa = purple_input_add(js->fd, PURPLE_INPUT_READ, jabber_recv_cb, gc);
856 } 857 }
857 858
859 /* Grabbed duplicate_fd() from GLib's testcases (gio/tests/socket.c).
860 * Can be dropped once this prpl has been fully converted to Gio.
861 */
862 static int
863 duplicate_fd(int fd)
864 {
865 #ifdef G_OS_WIN32
866 HANDLE newfd;
867
868 if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)fd, GetCurrentProcess(),
869 &newfd, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
870 return -1;
871 }
872
873 return (int)newfd;
874 #else
875 return dup(fd);
876 #endif
877 }
878 /* End function grabbed from GLib */
879
880 static void
881 jabber_login_callback_async(GObject *source_object, GAsyncResult *res,
882 gpointer data)
883 {
884 GSocketClient *client = G_SOCKET_CLIENT(source_object);
885 JabberStream *js = data;
886 GSocketConnection *conn;
887 GSocket *socket;
888 GError *error = NULL;
889
890 conn = g_socket_client_connect_to_host_finish(client, res, &error);
891 if (conn == NULL) {
892 GResolver *resolver;
893 gchar *name;
894
895 if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
896 g_error_free(error);
897 return;
898 }
899 g_error_free(error);
900
901 name = g_strdup_printf("_xmppconnect.%s", js->user->domain);
902 purple_debug_info("jabber",
903 "Couldn't connect directly to %s. Trying to find "
904 "alternative connection methods, like BOSH.\n",
905 js->user->domain);
906
907 resolver = g_resolver_get_default();
908 g_resolver_lookup_records_async(resolver, name, G_RESOLVER_RECORD_TXT,
909 js->cancellable, txt_resolved_cb, js);
910 g_free(name);
911 g_object_unref(resolver);
912
913 return;
914 }
915
916 socket = g_socket_connection_get_socket(conn);
917 g_assert(socket != NULL);
918
919 /* Duplicate the file descriptor, and then free the connection.
920 * libpurple's proxy code doesn't keep an object around for the
921 * lifetime of the connection. Therefore, in order to not leak
922 * memory, the GSocketConnection must be freed here. In order
923 * to avoid the double close/free of the file descriptor, the
924 * file descriptor is duplicated.
925 */
926 js->fd = duplicate_fd(g_socket_get_fd(socket));
927 g_object_unref(conn);
928
929 if (js->state == JABBER_STREAM_CONNECTING) {
930 jabber_send_raw(js, "<?xml version='1.0' ?>", -1);
931 }
932
933 jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING);
934 js->inpa =
935 purple_input_add(js->fd, PURPLE_INPUT_READ, jabber_recv_cb, js->gc);
936 }
937
858 static void 938 static void
859 jabber_ssl_connect_failure(PurpleSslConnection *gsc, PurpleSslErrorType error, 939 jabber_ssl_connect_failure(PurpleSslConnection *gsc, PurpleSslErrorType error,
860 gpointer data) 940 gpointer data)
861 { 941 {
862 PurpleConnection *gc = data; 942 PurpleConnection *gc = data;
1063 PurpleAccount *account = purple_connection_get_account(gc); 1143 PurpleAccount *account = purple_connection_get_account(gc);
1064 const char *connect_server = purple_account_get_string(account, 1144 const char *connect_server = purple_account_get_string(account,
1065 "connect_server", ""); 1145 "connect_server", "");
1066 const char *bosh_url = purple_account_get_string(account, 1146 const char *bosh_url = purple_account_get_string(account,
1067 "bosh_url", ""); 1147 "bosh_url", "");
1148 GError *error = NULL;
1068 1149
1069 jabber_stream_set_state(js, JABBER_STREAM_CONNECTING); 1150 jabber_stream_set_state(js, JABBER_STREAM_CONNECTING);
1070 1151
1071 /* If both BOSH and a Connect Server are specified, we prefer BOSH. I'm not 1152 /* If both BOSH and a Connect Server are specified, we prefer BOSH. I'm not
1072 * attached to that choice, though. 1153 * attached to that choice, though.
1080 } 1161 }
1081 1162
1082 return; 1163 return;
1083 } 1164 }
1084 1165
1166 js->client = purple_gio_socket_client_new(account, &error);
1167 if (js->client == NULL) {
1168 purple_connection_take_error(gc, error);
1169 return;
1170 }
1171
1085 js->certificate_CN = g_strdup(connect_server[0] ? connect_server : js->user->domain); 1172 js->certificate_CN = g_strdup(connect_server[0] ? connect_server : js->user->domain);
1086 1173
1087 /* if they've got old-ssl mode going, we probably want to ignore SRV lookups */ 1174 /* if they've got old-ssl mode going, we probably want to ignore SRV lookups */
1088 if (purple_strequal("old_ssl", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) { 1175 if (purple_strequal("old_ssl", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) {
1089 js->gsc = purple_ssl_connect(account, js->certificate_CN, 1176 js->gsc = purple_ssl_connect(account, js->certificate_CN,
1099 } 1186 }
1100 1187
1101 /* no old-ssl, so if they've specified a connect server, we'll use that, otherwise we'll 1188 /* no old-ssl, so if they've specified a connect server, we'll use that, otherwise we'll
1102 * invoke the magic of SRV lookups, to figure out host and port */ 1189 * invoke the magic of SRV lookups, to figure out host and port */
1103 if(connect_server[0]) { 1190 if(connect_server[0]) {
1104 jabber_login_connect(js, connect_server, 1191 g_socket_client_connect_to_host_async(
1105 purple_account_get_int(account, "port", 5222), 1192 js->client, connect_server,
1106 TRUE); 1193 purple_account_get_int(account, "port", 5222), js->cancellable,
1194 jabber_login_callback_async, js);
1107 } else { 1195 } else {
1108 GResolver *resolver = g_resolver_get_default(); 1196 GResolver *resolver = g_resolver_get_default();
1109 g_resolver_lookup_service_async(resolver, 1197 g_resolver_lookup_service_async(resolver,
1110 "xmpp-client", 1198 "xmpp-client",
1111 "tcp", 1199 "tcp",

mercurial