From 408b2fa63444fc5489dee0eb26b1938635e80833 Mon Sep 17 00:00:00 2001 From: Doug Nazar Date: Mon, 19 Apr 2021 15:48:18 -0400 Subject: [PATCH] tcp: Add helper functions to lookup hostnames and create sockets. Lookup will now maintain the full list of possible IP address(es). We can now iterate over all available addresses in case certain address families (IPv6) are disabled or try connecting to additional addresses for the clients. Part-of: --- gst/tcp/gsttcpelements.c | 73 ++++++++++++++++++++++++++++++++++++++++ gst/tcp/gsttcpelements.h | 6 ++++ 2 files changed, 79 insertions(+) diff --git a/gst/tcp/gsttcpelements.c b/gst/tcp/gsttcpelements.c index 6d0ebb2d5..f695ead29 100644 --- a/gst/tcp/gsttcpelements.c +++ b/gst/tcp/gsttcpelements.c @@ -26,6 +26,7 @@ #include "gsttcpelements.h" GST_DEBUG_CATEGORY (tcp_debug); +#define GST_CAT_DEFAULT tcp_debug void tcp_element_init (GstPlugin * plugin) @@ -36,3 +37,75 @@ tcp_element_init (GstPlugin * plugin) g_once_init_leave (&res, TRUE); } } + +GList * +tcp_get_addresses (GstElement * obj, const char *host, + GCancellable * cancellable, GError ** err) +{ + GList *addrs = NULL; + GInetAddress *addr; + + g_return_val_if_fail (GST_IS_ELEMENT (obj), NULL); + g_return_val_if_fail (host != NULL, NULL); + g_return_val_if_fail (err == NULL || *err == NULL, NULL); + + /* look up name if we need to */ + addr = g_inet_address_new_from_string (host); + if (addr) { + addrs = g_list_append (addrs, addr); + } else { + GResolver *resolver = g_resolver_get_default (); + + GST_DEBUG_OBJECT (obj, "Looking up IP address(es) for host '%s'", host); + addrs = g_resolver_lookup_by_name (resolver, host, cancellable, err); + g_object_unref (resolver); + } + + return addrs; +} + +/* + * Loops over available addresses until successfully creates a socket + * + * iter: updated to contain current list position or NULL if finished + * saddr: contains current address is successful + */ +GSocket * +tcp_create_socket (GstElement * obj, GList ** iter, guint16 port, + GSocketAddress ** saddr, GError ** err) +{ + GSocket *sock = NULL; + + g_return_val_if_fail (GST_IS_ELEMENT (obj), NULL); + g_return_val_if_fail (iter != NULL, NULL); + g_return_val_if_fail (saddr != NULL, NULL); + g_return_val_if_fail (err == NULL || *err == NULL, NULL); + + *saddr = NULL; + while (*iter) { + GInetAddress *addr = G_INET_ADDRESS ((*iter)->data); + +#ifndef GST_DISABLE_GST_DEBUG + { + gchar *ip = g_inet_address_to_string (addr); + GST_DEBUG_OBJECT (obj, "Trying IP address %s", ip); + g_free (ip); + } +#endif + /* update iter in case we get called again */ + *iter = (*iter)->next; + g_clear_error (err); + + *saddr = g_inet_socket_address_new (addr, port); + sock = + g_socket_new (g_socket_address_get_family (*saddr), + G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, err); + if (sock) + break; + + /* release and try next... */ + g_clear_object (saddr); + } + + return sock; +} diff --git a/gst/tcp/gsttcpelements.h b/gst/tcp/gsttcpelements.h index df3b6e1ab..4466083e4 100644 --- a/gst/tcp/gsttcpelements.h +++ b/gst/tcp/gsttcpelements.h @@ -21,6 +21,7 @@ #define __GST_TCP_ELEMENTS_H__ #include +#include #define TCP_HIGHEST_PORT 65535 #define TCP_DEFAULT_HOST "localhost" @@ -38,6 +39,11 @@ GST_ELEMENT_REGISTER_DECLARE (tcpserversrc); GST_ELEMENT_REGISTER_DECLARE (multifdsink); GST_ELEMENT_REGISTER_DECLARE (multisocketsink); +G_GNUC_INTERNAL GList * tcp_get_addresses (GstElement * obj, const char *host, + GCancellable * cancellable, GError ** err); +G_GNUC_INTERNAL GSocket * tcp_create_socket (GstElement * obj, GList ** iter, + guint16 port, GSocketAddress ** saddr, GError ** err); + G_END_DECLS #endif /* __GST_TCP_ELEMENTS_H__ */