| 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", |