diff options
author | Gary Kramlich <grim@reaperworld.com> | 2023-03-04 06:37:53 -0600 |
---|---|---|
committer | Gary Kramlich <grim@reaperworld.com> | 2023-03-04 06:37:53 -0600 |
commit | bef0352bc9a8636a84ec98a1c7c76a7ae99b15d5 (patch) | |
tree | ac97ebc78604354b365ff508b3daaf6ab075ac3f /libpurple | |
parent | f9b41b220e65711fcb3bdaeab1aa31eedb02ba47 (diff) | |
download | pidgin-bef0352bc9a8636a84ec98a1c7c76a7ae99b15d5.tar.gz |
Remove our stun code
I left in the preferences widgets for now as these will be wired to traversity
at some point.
Testing Done:
Opened the preferences dialog and made sure it worked as expected.
Reviewed at https://reviews.imfreedom.org/r/2309/
Diffstat (limited to 'libpurple')
-rw-r--r-- | libpurple/core.c | 2 | ||||
-rw-r--r-- | libpurple/meson.build | 2 | ||||
-rw-r--r-- | libpurple/network.c | 85 | ||||
-rw-r--r-- | libpurple/stun.c | 429 | ||||
-rw-r--r-- | libpurple/stun.h | 93 |
5 files changed, 3 insertions, 608 deletions
diff --git a/libpurple/core.c b/libpurple/core.c index 1c68c8e1de..5354a21c29 100644 --- a/libpurple/core.c +++ b/libpurple/core.c @@ -49,7 +49,6 @@ #include "savedstatuses.h" #include "signals.h" #include "status.h" -#include "stun.h" #include "util.h" #ifdef _WIN32 #include "win32/win32dep.h" @@ -182,7 +181,6 @@ purple_core_init(PurpleUi *ui, G_GNUC_UNUSED GError **error) { purple_history_manager_startup(); purple_network_init(); purple_proxy_init(); - purple_stun_init(); purple_xfers_init(); purple_idle_init(); diff --git a/libpurple/meson.build b/libpurple/meson.build index 46bb7cd7fb..aa7559f73b 100644 --- a/libpurple/meson.build +++ b/libpurple/meson.build @@ -101,7 +101,6 @@ purple_coresources = [ 'server.c', 'signals.c', 'status.c', - 'stun.c', 'util.c', 'version.c', 'xfer.c', @@ -210,7 +209,6 @@ purple_coreheaders = [ 'server.h', 'signals.h', 'status.h', - 'stun.h', 'tests.h', 'util.h', 'xfer.h', diff --git a/libpurple/network.c b/libpurple/network.c index 45cfe4a63f..6fadd412bb 100644 --- a/libpurple/network.c +++ b/libpurple/network.c @@ -44,13 +44,9 @@ #include "account.h" #include "network.h" #include "prefs.h" -#include "stun.h" static gboolean force_online = FALSE; -/* Cached IP addresses for STUN and TURN servers (set globally in prefs) */ -static gchar *stun_ip = NULL; - void purple_network_set_public_ip(const char *ip) { @@ -114,7 +110,6 @@ void purple_network_discover_my_ip(void) { const char *ip = NULL; - PurpleStunNatDiscovery *stun; /* Check if the user specified an IP manually */ if (!purple_prefs_get_bool("/purple/network/auto_ip")) { @@ -124,33 +119,21 @@ purple_network_discover_my_ip(void) return; } } - - /* Check if STUN discovery was already done */ - stun = purple_stun_discover(NULL); - if (stun != NULL && stun->status == PURPLE_STUN_STATUS_DISCOVERED) { - return; - } } gchar * purple_network_get_my_ip_from_gio(GSocketConnection *sockconn) { - const gchar *ip = NULL; - PurpleStunNatDiscovery *stun; - /* Check if the user specified an IP manually */ if (!purple_prefs_get_bool("/purple/network/auto_ip")) { + const gchar *ip = NULL; + ip = purple_network_get_public_ip(); + /* Make sure the IP address entered by the user is valid */ if ((ip != NULL) && (purple_network_is_ipv4(ip))) { return g_strdup(ip); } - } else { - /* Check if STUN discovery was already done */ - stun = purple_stun_discover(NULL); - if ((stun != NULL) && (stun->status == PURPLE_STUN_STATUS_DISCOVERED)) { - return g_strdup(stun->publicip); - } } /* Just fetch the IP of the local system */ @@ -173,58 +156,6 @@ purple_network_force_online(void) force_online = TRUE; } -static void -purple_network_ip_lookup_cb(GObject *sender, GAsyncResult *result, gpointer data) { - GError *error = NULL; - GList *addresses = NULL; - GInetAddress *address = NULL; - const gchar **ip_address = (const gchar **)data; - - addresses = g_resolver_lookup_by_name_finish(G_RESOLVER(sender), - result, &error); - if(error) { - purple_debug_info("network", "lookup of IP address failed: %s\n", error->message); - - g_error_free(error); - - return; - } - - address = G_INET_ADDRESS(addresses->data); - - *ip_address = g_inet_address_to_string(address); - - g_resolver_free_addresses(addresses); -} - -void -purple_network_set_stun_server(const gchar *stun_server) -{ - if (stun_server && stun_server[0] != '\0') { - if (purple_network_is_available()) { - GResolver *resolver = g_resolver_get_default(); - g_resolver_lookup_by_name_async(resolver, - stun_server, - NULL, - purple_network_ip_lookup_cb, - &stun_ip); - g_object_unref(resolver); - } else { - purple_debug_info("network", - "network is unavailable, don't try to update STUN IP"); - } - } else { - g_free(stun_ip); - stun_ip = NULL; - } -} - -const gchar * -purple_network_get_stun_ip(void) -{ - return stun_ip; -} - gboolean _purple_network_set_common_socket_flags(int fd) { @@ -256,25 +187,15 @@ void purple_network_init(void) { purple_prefs_add_none ("/purple/network"); - purple_prefs_add_string("/purple/network/stun_server", ""); - purple_prefs_add_string("/purple/network/turn_server", ""); - purple_prefs_add_int ("/purple/network/turn_port", 3478); - purple_prefs_add_int ("/purple/network/turn_port_tcp", 3478); - purple_prefs_add_string("/purple/network/turn_username", ""); - purple_prefs_add_string("/purple/network/turn_password", ""); purple_prefs_add_bool ("/purple/network/auto_ip", TRUE); purple_prefs_add_string("/purple/network/public_ip", ""); purple_prefs_add_bool ("/purple/network/map_ports", TRUE); purple_prefs_add_bool ("/purple/network/ports_range_use", FALSE); purple_prefs_add_int ("/purple/network/ports_range_start", 1024); purple_prefs_add_int ("/purple/network/ports_range_end", 2048); - - purple_network_set_stun_server( - purple_prefs_get_string("/purple/network/stun_server")); } void purple_network_uninit(void) { - g_free(stun_ip); } diff --git a/libpurple/stun.c b/libpurple/stun.c deleted file mode 100644 index c5479a675f..0000000000 --- a/libpurple/stun.c +++ /dev/null @@ -1,429 +0,0 @@ -/* purple - * - * STUN implementation inspired by jstun [http://jstun.javawi.de/] - * - * Purple is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - * - */ - -#include "internal.h" - -#ifndef _WIN32 -#include <net/if.h> -#endif - -#include <gio/gio.h> - -#include "glibcompat.h" - -#include "debug.h" -#include "account.h" -#include "network.h" -#include "proxy.h" -#include "stun.h" -#include "prefs.h" - -#define MSGTYPE_BINDINGREQUEST 0x0001 -#define MSGTYPE_BINDINGRESPONSE 0x0101 - -#define ATTRIB_MAPPEDADDRESS 0x0001 - -struct stun_header { - guint16 type; - guint16 len; - guint32 transid[4]; -}; - -struct stun_attrib { - guint16 type; - guint16 len; -}; - -struct stun_conn { - GSocket *sock; - GSocketAddress *addr; - int retry; - guint incb; - guint timeout; - struct stun_header *packet; - gsize packetsize; -}; - -static PurpleStunNatDiscovery nattype = { - PURPLE_STUN_STATUS_UNDISCOVERED, - "\0", NULL, 0}; - -static GSList *callbacks = NULL; - -static void close_stun_conn(struct stun_conn *sc) { - g_clear_object(&sc->sock); - g_clear_object(&sc->addr); - - if (sc->incb) { - g_source_remove(sc->incb); - } - - if (sc->timeout) { - g_source_remove(sc->timeout); - } - - g_clear_pointer(&sc->packet, g_free); - g_free(sc); -} - -static void do_callbacks(void) { - while (callbacks) { - PurpleStunCallback cb = callbacks->data; - if (cb) - cb(&nattype); - callbacks = g_slist_delete_link(callbacks, callbacks); - } -} - -static gboolean timeoutfunc(gpointer data) { - struct stun_conn *sc = data; - GError *error = NULL; - - if(sc->retry >= 2) { - guint id; - - purple_debug_warning("stun", "request timed out, giving up.\n"); - - /* set unknown */ - nattype.status = PURPLE_STUN_STATUS_UNKNOWN; - - nattype.lookup_time = g_get_monotonic_time(); - - /* callbacks */ - do_callbacks(); - - /* we don't need to remove the timeout (returning FALSE), but - * we do need to remove the read callback, which will free the - * whole stun_conn. */ - id = sc->incb; - sc->timeout = 0; - sc->incb = 0; - g_source_remove(id); - - return FALSE; - } - purple_debug_info("stun", "request timed out, retrying.\n"); - sc->retry++; - if (g_socket_send_to(sc->sock, sc->addr, (const gchar *)sc->packet, - sc->packetsize, NULL, - &error) != (gssize)sc->packetsize) { - purple_debug_warning("stun", "sendto failed: %s", error->message); - g_clear_error(&error); - return FALSE; - } - return TRUE; -} - -static gboolean -reply_cb(GSocket *socket, G_GNUC_UNUSED GIOCondition condition, gpointer data) -{ - struct stun_conn *sc = data; - gchar buffer[65536]; - gchar *it; - gssize len; - struct stun_attrib attrib; - struct stun_header hdr; - GError *error = NULL; - - len = g_socket_receive(socket, buffer, sizeof(buffer) - 1, NULL, &error); - if (len <= 0) { - purple_debug_warning("stun", "unable to read stun response: %s", - error->message); - g_clear_error(&error); - sc->incb = 0; - return FALSE; - } - buffer[len] = '\0'; - - if ((gsize)len < sizeof(struct stun_header)) { - purple_debug_warning("stun", "got invalid response\n"); - sc->incb = 0; - return FALSE; - } - - memcpy(&hdr, buffer, sizeof(hdr)); - if ((gsize)len != (g_ntohs(hdr.len) + sizeof(struct stun_header))) { - purple_debug_warning("stun", "got incomplete response\n"); - sc->incb = 0; - return FALSE; - } - - /* wrong transaction */ - if(hdr.transid[0] != sc->packet->transid[0] - || hdr.transid[1] != sc->packet->transid[1] - || hdr.transid[2] != sc->packet->transid[2] - || hdr.transid[3] != sc->packet->transid[3]) { - purple_debug_warning("stun", "got wrong transid\n"); - sc->incb = 0; - return FALSE; - } - - if (hdr.type != MSGTYPE_BINDINGRESPONSE) { - purple_debug_warning("stun", "Expected Binding Response, got %d", - hdr.type); - sc->incb = 0; - return FALSE; - } - - it = buffer + sizeof(struct stun_header); - while ((buffer + len) > (it + sizeof(struct stun_attrib))) { - memcpy(&attrib, it, sizeof(attrib)); - it += sizeof(struct stun_attrib); - - if (!((buffer + len) > (it + g_ntohs(attrib.len)))) { - break; - } - - if (attrib.type == g_htons(ATTRIB_MAPPEDADDRESS) && - g_ntohs(attrib.len) == 8) { - GInetAddress *inet_addr = NULL; - /* Skip the first unused byte, - * the family(1 byte), and the port(2 bytes); - * then read the 4 byte IPv4 address */ - inet_addr = g_inet_address_new_from_bytes((const guint8 *)it + 4, - G_SOCKET_FAMILY_IPV4); - if (inet_addr) { - gchar *ip = g_inet_address_to_string(inet_addr); - g_strlcpy(nattype.publicip, ip, sizeof(nattype.publicip)); - g_free(ip); - g_object_unref(inet_addr); - } - } - - it += g_ntohs(attrib.len); - } - purple_debug_info("stun", "got public ip %s\n", nattype.publicip); - nattype.status = PURPLE_STUN_STATUS_DISCOVERED; - nattype.lookup_time = g_get_monotonic_time(); - - do_callbacks(); - - /* sc will be freed by the GSource destruction. */ - sc->incb = 0; - return FALSE; -} - -static void -hbn_cb(GObject *sender, GAsyncResult *res, gpointer data) -{ - struct stun_conn *sc = NULL; - GList *addresses = NULL; - GSocketAddress *local_addr = NULL; - GInetAddress *remote_addr = NULL; - struct stun_header *hdr_data = NULL; - GSource *read_source = NULL; - GError *error = NULL; - - addresses = - g_resolver_lookup_by_name_finish(G_RESOLVER(sender), res, &error); - if (error != NULL) { - nattype.status = PURPLE_STUN_STATUS_UNDISCOVERED; - nattype.lookup_time = g_get_monotonic_time(); - - do_callbacks(); - - g_clear_error(&error); - return; - } - - sc = g_new0(struct stun_conn, 1); - sc->sock = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, - G_SOCKET_PROTOCOL_DEFAULT, &error); - if (sc->sock == NULL) { - purple_debug_error( - "stun", "Unable to create socket to connect to STUN server: %s", - error->message); - nattype.status = PURPLE_STUN_STATUS_UNKNOWN; - nattype.lookup_time = g_get_monotonic_time(); - - do_callbacks(); - - close_stun_conn(sc); - g_resolver_free_addresses(addresses); - g_clear_error(&error); - return; - } - - local_addr = g_inet_socket_address_new_from_string("0.0.0.0", 0); - remote_addr = G_INET_ADDRESS(addresses->data); - sc->addr = g_inet_socket_address_new(remote_addr, GPOINTER_TO_INT(data)); - g_resolver_free_addresses(addresses); - - g_socket_set_blocking(sc->sock, FALSE); - if (!g_socket_bind(sc->sock, local_addr, TRUE, &error)) { - purple_debug_error( - "stun", "Unable to bind socket to connect to STUN server: %s", - error->message); - nattype.status = PURPLE_STUN_STATUS_UNKNOWN; - nattype.lookup_time = g_get_monotonic_time(); - - do_callbacks(); - - g_object_unref(local_addr); - close_stun_conn(sc); - g_clear_error(&error); - return; - } - - g_object_unref(local_addr); - - read_source = g_socket_create_source(sc->sock, G_IO_IN, NULL); - g_source_set_callback(read_source, G_SOURCE_FUNC(reply_cb), sc, - (GDestroyNotify)close_stun_conn); - sc->incb = g_source_attach(read_source, NULL); - g_source_unref(read_source); - - hdr_data = g_new0(struct stun_header, 1); - hdr_data->type = g_htons(MSGTYPE_BINDINGREQUEST); - hdr_data->len = 0; - hdr_data->transid[0] = g_random_int(); - hdr_data->transid[1] = g_ntohl(((int)'g' << 24) + ((int)'a' << 16) + - ((int)'i' << 8) + (int)'m'); - hdr_data->transid[2] = g_random_int(); - hdr_data->transid[3] = g_random_int(); - sc->packet = hdr_data; - sc->packetsize = sizeof(struct stun_header); - - if (g_socket_send_to(sc->sock, sc->addr, (const gchar *)sc->packet, - sc->packetsize, NULL, - &error) < (gssize)sc->packetsize) { - purple_debug_warning("stun", "sendto failed: %s", error->message); - nattype.status = PURPLE_STUN_STATUS_UNKNOWN; - nattype.lookup_time = g_get_monotonic_time(); - do_callbacks(); - close_stun_conn(sc); - return; - } - - sc->timeout = g_timeout_add(500, (GSourceFunc)timeoutfunc, sc); -} - -static void -do_test1(GObject *sender, GAsyncResult *res, gpointer data) { - GList *services = NULL; - GError *error = NULL; - GResolver *resolver; - const char *servername = data; - int port = 3478; - - services = g_resolver_lookup_service_finish(G_RESOLVER(sender), - res, &error); - if(error != NULL) { - purple_debug_info("stun", "Failed to look up srv record : %s\n", error->message); - - g_error_free(error); - } else { - servername = g_srv_target_get_hostname((GSrvTarget *)services->data); - port = g_srv_target_get_port((GSrvTarget *)services->data); - } - - purple_debug_info("stun", "connecting to %s:%d\n", servername, port); - - resolver = g_resolver_get_default(); - g_resolver_lookup_by_name_async(resolver, - servername, - NULL, - hbn_cb, - GINT_TO_POINTER(port)); - g_object_unref(resolver); - - g_resolver_free_targets(services); -} - -static gboolean call_callback(gpointer data) { - PurpleStunCallback cb = data; - cb(&nattype); - return FALSE; -} - -PurpleStunNatDiscovery *purple_stun_discover(PurpleStunCallback cb) { - const char *servername = purple_prefs_get_string("/purple/network/stun_server"); - GResolver *resolver; - - purple_debug_info("stun", "using server %s\n", servername); - - if(nattype.status == PURPLE_STUN_STATUS_DISCOVERING) { - if(cb) - callbacks = g_slist_append(callbacks, cb); - return &nattype; - } - - if(nattype.status != PURPLE_STUN_STATUS_UNDISCOVERED) { - gboolean use_cached_result = TRUE; - - /* Deal with the server name having changed since we did the - lookup */ - if (servername && strlen(servername) > 1 - && !purple_strequal(servername, nattype.servername)) { - use_cached_result = FALSE; - } - - /* If we don't have a successful status and it has been 5 - minutes since we last did a lookup, redo the lookup */ - if (nattype.status != PURPLE_STUN_STATUS_DISCOVERED && - (g_get_monotonic_time() - nattype.lookup_time) > - 300 * G_USEC_PER_SEC) { - use_cached_result = FALSE; - } - - if (use_cached_result) { - if(cb) - g_timeout_add(10, call_callback, cb); - return &nattype; - } - } - - if(!servername || (strlen(servername) < 2)) { - nattype.status = PURPLE_STUN_STATUS_UNKNOWN; - nattype.lookup_time = g_get_monotonic_time(); - if(cb) - g_timeout_add(10, call_callback, cb); - return &nattype; - } - - nattype.status = PURPLE_STUN_STATUS_DISCOVERING; - nattype.publicip[0] = '\0'; - g_free(nattype.servername); - nattype.servername = g_strdup(servername); - - callbacks = g_slist_append(callbacks, cb); - - resolver = g_resolver_get_default(); - g_resolver_lookup_service_async(resolver, - "stun", - "udp", - servername, - NULL, - do_test1, - (gpointer)servername); - g_object_unref(resolver); - - return &nattype; -} - -void -purple_stun_init(void) -{ - purple_prefs_add_string("/purple/network/stun_server", ""); -} diff --git a/libpurple/stun.h b/libpurple/stun.h deleted file mode 100644 index 423048190b..0000000000 --- a/libpurple/stun.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Purple - Internet Messaging Library - * Copyright (C) Pidgin Developers <devel@pidgin.im> - * - * Purple is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <https://www.gnu.org/licenses/>. - */ - -#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION) -# error "only <purple.h> may be included directly" -#endif - -#ifndef PURPLE_STUN_H -#define PURPLE_STUN_H - -typedef struct _PurpleStunNatDiscovery PurpleStunNatDiscovery; - -/** - * PurpleStunStatus: - * @PURPLE_STUN_STATUS_UNDISCOVERED: No request has been published - * @PURPLE_STUN_STATUS_UNKNOWN: No STUN server reachable - * @PURPLE_STUN_STATUS_DISCOVERING: The request has been sent to the server - * @PURPLE_STUN_STATUS_DISCOVERED: The server has responded - * - * The status of a #PurpleStunNatDiscovery - */ -typedef enum { - PURPLE_STUN_STATUS_UNDISCOVERED = -1, - PURPLE_STUN_STATUS_UNKNOWN, - PURPLE_STUN_STATUS_DISCOVERING, - PURPLE_STUN_STATUS_DISCOVERED -} PurpleStunStatus; - -/** - * PurpleStunNatDiscovery: - * @status: The #PurpleStunStatus - * @publicip: The public ip - * @servername: The name of the stun server - * @lookup_time: The time when the lookup occurred - * - * A data type representing a STUN lookup. - */ -struct _PurpleStunNatDiscovery { - PurpleStunStatus status; - char publicip[16]; - char *servername; - gint64 lookup_time; -}; - -typedef void (*PurpleStunCallback) (PurpleStunNatDiscovery *discovery); - -G_BEGIN_DECLS - -/** - * purple_stun_discover: - * @cb: (scope async): The callback to call when the STUN discovery is finished - * if the discovery would block. If the discovery is done, this is NOT - * called. - * - * Starts a NAT discovery. It returns a PurpleStunNatDiscovery if the discovery - * is already done. Otherwise the callback is called when the discovery is over - * and NULL is returned. - * - * Returns: (transfer none): a #PurpleStunNatDiscovery which includes the public IP and the type - * of NAT or NULL if discovery would block - */ -PurpleStunNatDiscovery *purple_stun_discover(PurpleStunCallback cb); - -/** - * purple_stun_init: - * - * Initializes the STUN API. This is called by libpurple and you should not be - * calling it yourself. - */ -void purple_stun_init(void); - -G_END_DECLS - -#endif /* PURPLE_STUN_H */ |