--- a/libpurple/protocols/simple/simple.c Tue May 19 10:29:23 2020 +0000
+++ b/libpurple/protocols/simple/simple.c Thu May 21 04:45:24 2020 +0000
@@ -210,8 +210,12 @@
-static struct sip_connection *connection_create(struct simple_account_data *sip, int fd) {
+static struct sip_connection * +connection_create(struct simple_account_data *sip, GSocketConnection *sockconn, struct sip_connection *ret = g_new0(struct sip_connection, 1);
+ ret->sockconn = sockconn; sip->openconns = g_slist_append(sip->openconns, ret);
@@ -224,6 +228,7 @@
purple_input_remove(conn->inputhandler);
g_clear_pointer(&conn->inbuf, g_free);
+ g_clear_object(&conn->sockconn); @@ -505,22 +510,34 @@
static void simple_input_cb(gpointer data, gint source, PurpleInputCondition cond);
-static void send_later_cb(gpointer data, gint source, const gchar *error_message) {
+send_later_cb(GObject *sender, GAsyncResult *res, gpointer data) PurpleConnection *gc = data;
struct simple_account_data *sip;
struct sip_connection *conn;
+ GSocketConnection *sockconn;
- gchar *tmp = g_strdup_printf(_("Unable to connect: %s"),
- purple_connection_error(gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+ sockconn = g_socket_client_connect_to_host_finish(G_SOCKET_CLIENT(sender), + if (sockconn == NULL) { + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + purple_connection_take_error(gc, error); + socket = g_socket_connection_get_socket(sockconn); + g_assert(socket != NULL); + fd = g_socket_get_fd(socket); sip = purple_connection_get_protocol_data(gc);
simple_canwrite_cb(gc, sip->fd, PURPLE_INPUT_WRITE);
@@ -530,19 +547,30 @@
sip->tx_handler = purple_input_add(sip->fd, PURPLE_INPUT_WRITE,
- conn = connection_create(sip, source);
+ conn = connection_create(sip, sockconn, fd); conn->inputhandler = purple_input_add(sip->fd, PURPLE_INPUT_READ, simple_input_cb, gc);
static void sendlater(PurpleConnection *gc, const char *buf) {
struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
- purple_debug_info("simple", "connecting to %s port %d\n", sip->realhostname ? sip->realhostname : "{NULL}", sip->realport);
- if (purple_proxy_connect(gc, sip->account, sip->realhostname, sip->realport, send_later_cb, gc) == NULL) {
- purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect"));
+ GSocketClient *client = NULL; + client = purple_gio_socket_client_new(sip->account, &error); + purple_connection_take_error(sip->gc, error); + purple_debug_info("simple", "connecting to %s port %d", + sip->realhostname ? sip->realhostname : "{NULL}", + g_socket_client_connect_to_host_async(client, sip->realhostname, + sip->realport, sip->cancellable, + g_object_unref(client); @@ -1760,40 +1788,59 @@
/* Callback for new connections on incoming TCP port */
-static void simple_newconn_cb(gpointer data, gint source, PurpleInputCondition cond) {
- PurpleConnection *gc = data;
+simple_newconn_cb(G_GNUC_UNUSED GSocketService *service, + GSocketConnection *connection, GObject *source_object, + G_GNUC_UNUSED gpointer data) + PurpleConnection *gc = PURPLE_CONNECTION(source_object); struct simple_account_data *sip = purple_connection_get_protocol_data(gc);
struct sip_connection *conn;
- newfd = accept(source, NULL, NULL);
- g_return_if_fail(newfd >= 0);
+ socket = g_socket_connection_get_socket(connection); + g_assert(socket != NULL); + fd = g_socket_get_fd(socket); - _purple_network_set_common_socket_flags(newfd);
+ _purple_network_set_common_socket_flags(fd); - conn = connection_create(sip, newfd);
+ conn = connection_create(sip, g_object_ref(connection), fd); - conn->inputhandler = purple_input_add(newfd, PURPLE_INPUT_READ, simple_input_cb, gc);
+ purple_input_add(fd, PURPLE_INPUT_READ, simple_input_cb, gc); -static void login_cb(gpointer data, gint source, const gchar *error_message) {
+login_cb(GObject *sender, GAsyncResult *res, gpointer data) PurpleConnection *gc = data;
struct simple_account_data *sip;
struct sip_connection *conn;
+ GSocketConnection *sockconn;
- gchar *tmp = g_strdup_printf(_("Unable to connect: %s"),
- purple_connection_error(gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
+ sockconn = g_socket_client_connect_to_host_finish(G_SOCKET_CLIENT(sender), + if (sockconn == NULL) { + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + purple_connection_take_error(gc, error); + socket = g_socket_connection_get_socket(sockconn); + g_assert(socket != NULL); + fd = g_socket_get_fd(socket); sip = purple_connection_get_protocol_data(gc);
- conn = connection_create(sip, source);
+ conn = connection_create(sip, sockconn, fd); sip->registertimeout = g_timeout_add_seconds(
g_random_int_range(10, 100), (GSourceFunc)subscribe_timeout, sip);
@@ -1893,35 +1940,6 @@
-simple_tcp_connect_listen_cb(int listenfd, gpointer data) {
- struct simple_account_data *sip = (struct simple_account_data*) data;
- sip->listen_data = NULL;
- sip->listenfd = listenfd;
- if(sip->listenfd == -1) {
- purple_connection_error(sip->gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Unable to create listen socket"));
- purple_debug_info("simple", "listenfd: %d\n", sip->listenfd);
- sip->listenport = purple_network_get_port_from_fd(sip->listenfd);
- sip->listenpa = purple_input_add(sip->listenfd, PURPLE_INPUT_READ,
- simple_newconn_cb, sip->gc);
- purple_debug_info("simple", "connecting to %s port %d\n",
- sip->realhostname, sip->realport);
- /* open tcp connection to the server */
- if (purple_proxy_connect(sip->gc, sip->account, sip->realhostname,
- sip->realport, login_cb, sip->gc) == NULL) {
- purple_connection_error(sip->gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Unable to connect"));
srvresolved(GObject *sender, GAsyncResult *result, gpointer data) {
@@ -1963,15 +1981,32 @@
- /* create socket for incoming connections */
- sip->listen_data = purple_network_listen_range(5060, 5160, AF_UNSPEC, SOCK_STREAM, TRUE,
- simple_tcp_connect_listen_cb, sip);
- if (sip->listen_data == NULL) {
- purple_connection_error(sip->gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Unable to create listen socket"));
+ /* create service for incoming connections */ + sip->service = g_socket_service_new(); + sip->listenport = purple_socket_listener_add_any_inet_port( + G_SOCKET_LISTENER(sip->service), G_OBJECT(sip->gc), &error); + if (sip->listenport == 0) { + purple_connection_take_error(sip->gc, error); + g_signal_connect(sip->service, "incoming", + G_CALLBACK(simple_newconn_cb), NULL); + purple_debug_info("simple", "connecting to %s port %d", + sip->realhostname, sip->realport); + client = purple_gio_socket_client_new(sip->account, &error); + purple_connection_take_error(sip->gc, error); + /* open tcp connection to the server */ + g_socket_client_connect_to_host_async(client, sip->realhostname, + sip->realport, sip->cancellable, + g_object_unref(client); GResolver *resolver = g_resolver_get_default();
@@ -2010,7 +2045,6 @@
purple_connection_set_protocol_data(gc, sip);
sip->registerexpire = 900;
sip->udp = purple_account_get_bool(account, "udp", FALSE);
@@ -2090,13 +2124,16 @@
g_cancellable_cancel(sip->cancellable);
g_object_unref(G_OBJECT(sip->cancellable));
+ g_socket_service_stop(sip->service); + g_clear_object(&sip->service); if (sip->listen_data != NULL)
purple_network_listen_cancel(sip->listen_data);
- if (sip->listenfd >= 0)
--- a/libpurple/protocols/simple/simple.h Tue May 19 10:29:23 2020 +0000
+++ b/libpurple/protocols/simple/simple.h Thu May 21 04:45:24 2020 +0000
@@ -94,6 +94,7 @@
GCancellable *cancellable;
+ GSocketService *service; PurpleNetworkListenData *listen_data;
@@ -102,7 +103,6 @@
int registerstatus; /* 0 nothing, 1 first registration send, 2 auth received, 3 registered */
struct sip_auth registrar;
@@ -126,6 +126,7 @@
+ GSocketConnection *sockconn;