pidgin/pidgin

xmpp: Convert si xfer to gio socket server.

2020-05-12, Elliott Sales de Andrade
d85e4d3f17be
Parents 5529108bd66e
Children dc115c3b7694
xmpp: Convert si xfer to gio socket server.
--- a/libpurple/protocols/jabber/si.c Tue May 12 01:44:23 2020 -0400
+++ b/libpurple/protocols/jabber/si.c Tue May 12 03:01:37 2020 -0400
@@ -42,7 +42,7 @@
JabberStream *js;
PurpleProxyConnectData *connect_data;
- PurpleNetworkListenData *listen_data;
+ GSocketService *service;
guint connect_timeout;
gboolean accepted;
@@ -63,7 +63,7 @@
char *rxqueue;
size_t rxlen;
gsize rxmaxlen;
- int local_streamhost_fd;
+ GSocketConnection *local_streamhost_conn;
JabberIBBSession *ibb_session;
guint ibb_timeout_handle;
@@ -659,32 +659,30 @@
}
static void
-jabber_si_xfer_bytestreams_send_connected_cb(gpointer data, gint source,
- PurpleInputCondition cond)
+jabber_si_xfer_bytestreams_send_connected_cb(GSocketService *service,
+ GSocketConnection *connection,
+ GObject *source_object,
+ G_GNUC_UNUSED gpointer data)
{
- PurpleXfer *xfer = data;
+ PurpleXfer *xfer = PURPLE_XFER(source_object);
JabberSIXfer *jsx = JABBER_SI_XFER(xfer);
- int acceptfd;
+ GSocket *sock;
+ int fd;
purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_connected_cb\n");
- acceptfd = accept(source, NULL, 0);
- if(acceptfd == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
- return;
- else if(acceptfd == -1) {
- purple_debug_warning("jabber", "accept: %s\n", g_strerror(errno));
- /* Don't cancel the ft - allow it to fall to the next streamhost.*/
- return;
- }
+ jsx->local_streamhost_conn = g_object_ref(connection);
+ g_socket_service_stop(jsx->service);
+ g_clear_object(&jsx->service);
- purple_input_remove(purple_xfer_get_watcher(xfer));
- close(source);
- jsx->local_streamhost_fd = -1;
+ sock = g_socket_connection_get_socket(connection);
+ fd = g_socket_get_fd(sock);
+ _purple_network_set_common_socket_flags(fd);
- _purple_network_set_common_socket_flags(acceptfd);
-
- purple_xfer_set_watcher(xfer, purple_input_add(acceptfd, PURPLE_INPUT_READ,
- jabber_si_xfer_bytestreams_send_read_cb, xfer));
+ purple_xfer_set_watcher(
+ xfer,
+ purple_input_add(fd, PURPLE_INPUT_READ,
+ jabber_si_xfer_bytestreams_send_read_cb, xfer));
}
static void
@@ -793,13 +791,10 @@
}
/* Clean up the local streamhost - it isn't going to be used.*/
- if (purple_xfer_get_watcher(xfer) > 0) {
- purple_input_remove(purple_xfer_get_watcher(xfer));
- purple_xfer_set_watcher(xfer, 0);
- }
- if (jsx->local_streamhost_fd >= 0) {
- close(jsx->local_streamhost_fd);
- jsx->local_streamhost_fd = -1;
+ g_clear_object(&jsx->local_streamhost_conn);
+ if (jsx->service) {
+ g_socket_service_stop(jsx->service);
+ g_clear_object(&jsx->service);
}
jsx->streamhosts = g_list_remove_link(jsx->streamhosts, matched);
@@ -919,31 +914,42 @@
}
static void
-jabber_si_xfer_bytestreams_listen_cb(int sock, gpointer data)
+jabber_si_xfer_bytestreams_send_init(PurpleXfer *xfer)
{
- PurpleXfer *xfer = PURPLE_XFER(data);
JabberSIXfer *jsx = JABBER_SI_XFER(xfer);
+ PurpleProxyType proxy_type;
GList *local_ips = NULL;
- jsx->listen_data = NULL;
-
- /* I'm not sure under which conditions this can happen
- * (it seems like it shouldn't be possible */
- if (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL) {
- g_object_unref(xfer);
- return;
+ /* TODO: This should probably be done with an account option instead of
+ * piggy-backing on the TOR proxy type. */
+ proxy_type = purple_proxy_info_get_proxy_type(
+ purple_proxy_get_setup(purple_connection_get_account(jsx->js->gc)));
+ if (proxy_type == PURPLE_PROXY_TOR) {
+ purple_debug_info("jabber", "Skipping attempting local streamhost.\n");
+ jsx->service = NULL;
+ } else {
+ guint16 port = 0;
+ GError *error = NULL;
+ jsx->service = g_socket_service_new();
+ port = purple_socket_listener_add_any_inet_port(
+ G_SOCKET_LISTENER(jsx->service), G_OBJECT(xfer), &error);
+ if (port != 0) {
+ purple_xfer_set_local_port(xfer, port);
+ } else {
+ purple_debug_error("jabber",
+ "Unable to create streamhost socket listener: "
+ "%s. Trying proxy instead.",
+ error->message);
+ g_error_free(error);
+ g_clear_object(&jsx->service);
+ }
}
- /* If we successfully started listening locally */
- if (sock >= 0) {
+ if (jsx->service) {
GList *l = NULL;
gchar *public_ip;
gboolean has_public_ip = FALSE;
- jsx->local_streamhost_fd = sock;
-
- purple_xfer_set_local_port(xfer, purple_network_get_port_from_fd(sock));
-
public_ip = purple_network_get_my_ip_from_gio(
G_SOCKET_CONNECTION(jsx->js->stream));
@@ -961,44 +967,12 @@
local_ips = g_list_append(local_ips, public_ip);
}
- /* The listener for the local proxy */
- purple_xfer_set_watcher(
- xfer,
- purple_input_add(sock, PURPLE_INPUT_READ,
- jabber_si_xfer_bytestreams_send_connected_cb,
- xfer));
+ g_signal_connect(
+ G_OBJECT(jsx->service), "incoming",
+ G_CALLBACK(jabber_si_xfer_bytestreams_send_connected_cb), NULL);
}
jabber_si_xfer_bytestreams_send_local_info(xfer, local_ips);
-
- g_object_unref(xfer);
-}
-
-static void
-jabber_si_xfer_bytestreams_send_init(PurpleXfer *xfer)
-{
- JabberSIXfer *jsx;
- PurpleProxyType proxy_type;
-
- jsx = JABBER_SI_XFER(xfer);
-
- /* TODO: This should probably be done with an account option instead of
- * piggy-backing on the TOR proxy type. */
- proxy_type = purple_proxy_info_get_proxy_type(
- purple_proxy_get_setup(purple_connection_get_account(jsx->js->gc)));
- if (proxy_type == PURPLE_PROXY_TOR) {
- purple_debug_info("jabber", "Skipping attempting local streamhost.\n");
- jsx->listen_data = NULL;
- } else
- jsx->listen_data = purple_network_listen_range(
- 0, 0, AF_UNSPEC, SOCK_STREAM, TRUE,
- jabber_si_xfer_bytestreams_listen_cb, g_object_ref(xfer));
-
- if (jsx->listen_data == NULL) {
- /* We couldn't open a local port. Perhaps we can use a proxy. */
- jabber_si_xfer_bytestreams_send_local_info(xfer, NULL);
- }
-
}
static void
@@ -1749,7 +1723,6 @@
*****************************************************************************/
static void
jabber_si_xfer_init(JabberSIXfer *xfer) {
- xfer->local_streamhost_fd = -1;
xfer->ibb_session = NULL;
}
@@ -1764,18 +1737,16 @@
purple_proxy_connect_cancel(jsx->connect_data);
}
- if (jsx->listen_data != NULL) {
- purple_network_listen_cancel(jsx->listen_data);
+ g_clear_object(&jsx->local_streamhost_conn);
+ if (jsx->service) {
+ g_socket_service_stop(jsx->service);
}
+ g_clear_object(&jsx->service);
if (jsx->iq_id != NULL) {
jabber_iq_remove_callback_by_id(js, jsx->iq_id);
}
- if (jsx->local_streamhost_fd >= 0) {
- close(jsx->local_streamhost_fd);
- }
-
if (purple_xfer_get_xfer_type(PURPLE_XFER(jsx)) == PURPLE_XFER_TYPE_SEND && purple_xfer_get_fd(PURPLE_XFER(jsx)) >= 0) {
purple_debug_info("jabber", "remove port mapping\n");
purple_network_remove_port_mapping(purple_xfer_get_fd(PURPLE_XFER(jsx)));