From 27206418062bee3d3b342574f1425a1683f83f3a Mon Sep 17 00:00:00 2001 From: Brian Hackel Date: Wed, 30 Aug 2023 14:48:51 -0700 Subject: [PATCH 1/6] include both binding strategies --- src/arvgvdevice.c | 48 ++++++++++++++++++++++++++++++++++++++++---- src/arvgvinterface.c | 32 ++++++++++++++++++++++++++--- 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/src/arvgvdevice.c b/src/arvgvdevice.c index 4d94bcc1f..948a13dab 100644 --- a/src/arvgvdevice.c +++ b/src/arvgvdevice.c @@ -1966,11 +1966,18 @@ arv_gv_device_constructed (GObject *object) char *address_string; guint32 capabilities; guint32 device_mode; + GSocketAddress *any_socket_address; + GInetAddress *any_address; + int socket_fd; + struct ifaddrs *addrs, *iap; + struct sockaddr_in *sa; + char buf[32]; + char interface_name[32]; - G_OBJECT_CLASS (arv_gv_device_parent_class)->constructed (object); + G_OBJECT_CLASS (arv_gv_device_parent_class)->constructed (object); if (!G_IS_INET_ADDRESS (priv->interface_address) || - !G_IS_INET_ADDRESS (priv->device_address)) { + !G_IS_INET_ADDRESS (priv->device_address)) { arv_device_take_init_error (ARV_DEVICE (object), g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_ERROR_INVALID_PARAMETER, "Invalid interface or device address")); return; @@ -1994,14 +2001,47 @@ arv_gv_device_constructed (GObject *object) io_data->socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); - if (!g_socket_bind (io_data->socket, io_data->interface_address, FALSE, &local_error)) { + + any_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); + any_socket_address = g_inet_socket_address_new (any_address, 0); + + if (!g_socket_bind (io_data->socket, any_socket_address, FALSE, &local_error)) { if (local_error == NULL) local_error = g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_ERROR_UNKNOWN, - "Unknown error trying to bind device interface"); + "Unknown error trying to bind device interface"); arv_device_take_init_error (ARV_DEVICE (gv_device), local_error); return; } + g_object_unref (any_socket_address); + g_object_unref (any_address); + + // we have to grab the interface name + if (getifaddrs (&addrs) <0) { + arv_device_take_init_error (ARV_DEVICE (object), + g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_ERROR_NOT_CONNECTED, + "Couldn't get available interfaces")); + return; + } + + for (iap = addrs; iap != NULL; iap = iap->ifa_next) { + if ((iap->ifa_flags & IFF_UP) != 0 && + (iap->ifa_flags & IFF_POINTOPOINT) == 0 && + (iap->ifa_addr != NULL) && + (iap->ifa_addr->sa_family == AF_INET)) { + + sa = (struct sockaddr_in *)(iap->ifa_addr); + inet_ntop(iap->ifa_addr->sa_family, (void *)&(sa->sin_addr), buf, sizeof(buf)); + if (!strcmp(g_inet_address_to_string (priv->interface_address), buf)) { + sprintf(interface_name, "%s", iap->ifa_name); + } + } + } + + freeifaddrs (addrs); + + socket_fd = g_socket_get_fd(io_data->socket); + setsockopt (socket_fd, SOL_SOCKET, SO_BINDTODEVICE, interface_name, strlen (interface_name)); io_data->buffer = g_malloc (ARV_GV_DEVICE_BUFFER_SIZE); io_data->gvcp_n_retries = ARV_GV_DEVICE_GVCP_N_RETRIES_DEFAULT; diff --git a/src/arvgvinterface.c b/src/arvgvinterface.c index c8eb24790..44fd30193 100644 --- a/src/arvgvinterface.c +++ b/src/arvgvinterface.c @@ -83,39 +83,65 @@ arv_gv_discover_socket_list_new (void) return socket_list; for (iface_iter = ifaces; iface_iter != NULL; iface_iter = iface_iter->next) { + ArvGvDiscoverSocket *discover_socket_bind_any = g_new0 (ArvGvDiscoverSocket, 1); ArvGvDiscoverSocket *discover_socket = g_new0 (ArvGvDiscoverSocket, 1); GSocketAddress *socket_address; GSocketAddress *socket_broadcast; + GSocketAddress *any_socket_address; + GInetAddress *any_address; GInetAddress *inet_address; GInetAddress *inet_broadcast; char *inet_address_string; char *inet_broadcast_string; GError *error = NULL; gint buffer_size = ARV_GV_INTERFACE_DISCOVERY_SOCKET_BUFFER_SIZE; + int socket_fd; + const char *interface_name; + socket_address = g_socket_address_new_from_native (arv_network_interface_get_addr(iface_iter->data), sizeof (struct sockaddr)); socket_broadcast = g_socket_address_new_from_native (arv_network_interface_get_broadaddr(iface_iter->data), sizeof (struct sockaddr)); inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (socket_address)); - inet_broadcast = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (socket_broadcast)); + inet_broadcast = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (socket_broadcast)); inet_address_string = g_inet_address_to_string (inet_address); inet_broadcast_string = g_inet_address_to_string (inet_broadcast); arv_info_interface ("[GvDiscoverSocket::new] Add interface %s (%s)", inet_address_string, inet_broadcast_string); g_free (inet_address_string); g_free (inet_broadcast_string); + discover_socket_bind_any->interface_address = g_inet_socket_address_new (inet_address, 0); + discover_socket_bind_any->broadcast_address = g_inet_socket_address_new (inet_broadcast, ARV_GVCP_PORT); discover_socket->interface_address = g_inet_socket_address_new (inet_address, 0); discover_socket->broadcast_address = g_inet_socket_address_new (inet_broadcast, ARV_GVCP_PORT); + g_object_unref (socket_address); g_object_unref (socket_broadcast); + discover_socket_bind_any->socket = g_socket_new (g_inet_address_get_family (inet_address), + G_SOCKET_TYPE_DATAGRAM, + G_SOCKET_PROTOCOL_UDP, NULL); discover_socket->socket = g_socket_new (g_inet_address_get_family (inet_address), G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); + arv_socket_set_recv_buffer_size (g_socket_get_fd (discover_socket_bind_any->socket), buffer_size); arv_socket_set_recv_buffer_size (g_socket_get_fd (discover_socket->socket), buffer_size); - g_socket_bind (discover_socket->socket, discover_socket->interface_address, FALSE, &error); + + any_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); + any_socket_address = g_inet_socket_address_new (any_address, 0); + g_socket_bind (discover_socket->socket, discover_socket->interface_address, FALSE, &error); socket_list->sockets = g_slist_prepend (socket_list->sockets, discover_socket); socket_list->n_sockets++; + g_socket_bind (discover_socket_bind_any->socket, any_socket_address, FALSE, &error); + g_object_unref (any_socket_address); + g_object_unref (any_address); + + interface_name = arv_network_interface_get_name (iface_iter->data); + socket_fd = g_socket_get_fd(discover_socket_bind_any->socket); + setsockopt (socket_fd, SOL_SOCKET, SO_BINDTODEVICE, interface_name, strlen (interface_name)); + + socket_list->sockets = g_slist_prepend (socket_list->sockets, discover_socket_bind_any); + socket_list->n_sockets++; } g_list_free_full (ifaces, (GDestroyNotify) arv_network_interface_free); @@ -802,4 +828,4 @@ arv_gv_interface_class_init (ArvGvInterfaceClass *gv_interface_class) interface_class->open_device = arv_gv_interface_open_device; interface_class->protocol = "GigEVision"; -} +} \ No newline at end of file From 6b2153d77d5c6296fbbcd7c7d02b010f680cd6b0 Mon Sep 17 00:00:00 2001 From: Brian Hackel Date: Fri, 8 Sep 2023 13:08:55 -0700 Subject: [PATCH 2/6] Update arvgvinterface.c --- src/arvgvinterface.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/arvgvinterface.c b/src/arvgvinterface.c index 44fd30193..b1386e185 100644 --- a/src/arvgvinterface.c +++ b/src/arvgvinterface.c @@ -83,7 +83,6 @@ arv_gv_discover_socket_list_new (void) return socket_list; for (iface_iter = ifaces; iface_iter != NULL; iface_iter = iface_iter->next) { - ArvGvDiscoverSocket *discover_socket_bind_any = g_new0 (ArvGvDiscoverSocket, 1); ArvGvDiscoverSocket *discover_socket = g_new0 (ArvGvDiscoverSocket, 1); GSocketAddress *socket_address; GSocketAddress *socket_broadcast; @@ -109,38 +108,27 @@ arv_gv_discover_socket_list_new (void) arv_info_interface ("[GvDiscoverSocket::new] Add interface %s (%s)", inet_address_string, inet_broadcast_string); g_free (inet_address_string); g_free (inet_broadcast_string); - discover_socket_bind_any->interface_address = g_inet_socket_address_new (inet_address, 0); - discover_socket_bind_any->broadcast_address = g_inet_socket_address_new (inet_broadcast, ARV_GVCP_PORT); discover_socket->interface_address = g_inet_socket_address_new (inet_address, 0); discover_socket->broadcast_address = g_inet_socket_address_new (inet_broadcast, ARV_GVCP_PORT); - g_object_unref (socket_address); g_object_unref (socket_broadcast); - discover_socket_bind_any->socket = g_socket_new (g_inet_address_get_family (inet_address), - G_SOCKET_TYPE_DATAGRAM, - G_SOCKET_PROTOCOL_UDP, NULL); discover_socket->socket = g_socket_new (g_inet_address_get_family (inet_address), G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); - arv_socket_set_recv_buffer_size (g_socket_get_fd (discover_socket_bind_any->socket), buffer_size); arv_socket_set_recv_buffer_size (g_socket_get_fd (discover_socket->socket), buffer_size); - any_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); any_socket_address = g_inet_socket_address_new (any_address, 0); - g_socket_bind (discover_socket->socket, discover_socket->interface_address, FALSE, &error); - socket_list->sockets = g_slist_prepend (socket_list->sockets, discover_socket); - socket_list->n_sockets++; - g_socket_bind (discover_socket_bind_any->socket, any_socket_address, FALSE, &error); + g_socket_bind (discover_socket->socket, any_socket_address, FALSE, &error); g_object_unref (any_socket_address); g_object_unref (any_address); interface_name = arv_network_interface_get_name (iface_iter->data); - socket_fd = g_socket_get_fd(discover_socket_bind_any->socket); + socket_fd = g_socket_get_fd(discover_socket->socket); setsockopt (socket_fd, SOL_SOCKET, SO_BINDTODEVICE, interface_name, strlen (interface_name)); - socket_list->sockets = g_slist_prepend (socket_list->sockets, discover_socket_bind_any); + socket_list->sockets = g_slist_prepend (socket_list->sockets, discover_socket); socket_list->n_sockets++; } g_list_free_full (ifaces, (GDestroyNotify) arv_network_interface_free); From a2f905fb5383de317c8df46f04422340b4277877 Mon Sep 17 00:00:00 2001 From: Brian Hackel Date: Fri, 8 Sep 2023 14:06:20 -0700 Subject: [PATCH 3/6] updates --- src/arvgvdevice.c | 36 ++++++++++++++++++++---------------- src/arvgvinterface.c | 16 +++++++++------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/arvgvdevice.c b/src/arvgvdevice.c index 948a13dab..21341764c 100644 --- a/src/arvgvdevice.c +++ b/src/arvgvdevice.c @@ -1966,7 +1966,7 @@ arv_gv_device_constructed (GObject *object) char *address_string; guint32 capabilities; guint32 device_mode; - GSocketAddress *any_socket_address; + GSocketAddress *socket_address; GInetAddress *any_address; int socket_fd; struct ifaddrs *addrs, *iap; @@ -2002,20 +2002,6 @@ arv_gv_device_constructed (GObject *object) G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); - any_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); - any_socket_address = g_inet_socket_address_new (any_address, 0); - - if (!g_socket_bind (io_data->socket, any_socket_address, FALSE, &local_error)) { - if (local_error == NULL) - local_error = g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_ERROR_UNKNOWN, - "Unknown error trying to bind device interface"); - arv_device_take_init_error (ARV_DEVICE (gv_device), local_error); - - return; - } - g_object_unref (any_socket_address); - g_object_unref (any_address); - // we have to grab the interface name if (getifaddrs (&addrs) <0) { arv_device_take_init_error (ARV_DEVICE (object), @@ -2041,7 +2027,25 @@ arv_gv_device_constructed (GObject *object) freeifaddrs (addrs); socket_fd = g_socket_get_fd(io_data->socket); - setsockopt (socket_fd, SOL_SOCKET, SO_BINDTODEVICE, interface_name, strlen (interface_name)); + if (setsockopt (socket_fd, SOL_SOCKET, SO_BINDTODEVICE, interface_name, strlen (interface_name)) == 0) { + any_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); + socket_address = g_inet_socket_address_new (any_address, 0); + g_object_unref (any_address); + } else { + socket_address = g_inet_socket_address_new (priv->interface_address, 0); + } + + if (!g_socket_bind (io_data->socket, socket_address, FALSE, &local_error)) { + if (local_error == NULL) + local_error = g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_ERROR_UNKNOWN, + "Unknown error trying to bind device interface"); + arv_device_take_init_error (ARV_DEVICE (gv_device), local_error); + g_object_unref (socket_address); + + return; + } + g_object_unref (socket_address); + io_data->buffer = g_malloc (ARV_GV_DEVICE_BUFFER_SIZE); io_data->gvcp_n_retries = ARV_GV_DEVICE_GVCP_N_RETRIES_DEFAULT; diff --git a/src/arvgvinterface.c b/src/arvgvinterface.c index b1386e185..b9fe809d8 100644 --- a/src/arvgvinterface.c +++ b/src/arvgvinterface.c @@ -118,15 +118,17 @@ arv_gv_discover_socket_list_new (void) G_SOCKET_PROTOCOL_UDP, NULL); arv_socket_set_recv_buffer_size (g_socket_get_fd (discover_socket->socket), buffer_size); - any_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); - any_socket_address = g_inet_socket_address_new (any_address, 0); - g_socket_bind (discover_socket->socket, any_socket_address, FALSE, &error); - g_object_unref (any_socket_address); - g_object_unref (any_address); - interface_name = arv_network_interface_get_name (iface_iter->data); socket_fd = g_socket_get_fd(discover_socket->socket); - setsockopt (socket_fd, SOL_SOCKET, SO_BINDTODEVICE, interface_name, strlen (interface_name)); + if (setsockopt (socket_fd, SOL_SOCKET, SO_BINDTODEVICE, interface_name, strlen (interface_name)) == 0) { + any_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); + any_socket_address = g_inet_socket_address_new (any_address, 0); + g_socket_bind (discover_socket->socket, any_socket_address, FALSE, &error); + g_object_unref (any_socket_address); + g_object_unref (any_address); + } else { + g_socket_bind (discover_socket->socket, discover_socket->interface_address, FALSE, &error); + } socket_list->sockets = g_slist_prepend (socket_list->sockets, discover_socket); socket_list->n_sockets++; From eca2fb999cd8eac16232c643ea65b7107cd09ea4 Mon Sep 17 00:00:00 2001 From: Brian Hackel Date: Tue, 27 Aug 2024 17:15:59 -0700 Subject: [PATCH 4/6] fix missing curly brace --- src/arvgvinterface.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/arvgvinterface.c b/src/arvgvinterface.c index 0e68a4b9a..464946245 100644 --- a/src/arvgvinterface.c +++ b/src/arvgvinterface.c @@ -133,22 +133,23 @@ arv_gv_discover_socket_list_new (void) g_object_unref (any_socket_address); g_object_unref (any_address); } else { - discover_socket->interface_address = arv_socket_bind_with_range (discover_socket->socket, inet_address, - 0, FALSE, &error); + discover_socket->interface_address = arv_socket_bind_with_range (discover_socket->socket, inet_address, + 0, FALSE, &error); g_object_unref (socket_address); g_object_unref (socket_broadcast); if (G_IS_INET_SOCKET_ADDRESS (discover_socket->interface_address)) { - socket_list->sockets = g_slist_prepend (socket_list->sockets, discover_socket); - socket_list->n_sockets++; - } else { - arv_warning_interface ("Failed to bind discovery socket: %s", - error != NULL ? error->message : "Unknown reason"); - arv_gv_discover_socket_free (discover_socket); - } - } - g_list_free_full (ifaces, (GDestroyNotify) arv_network_interface_free); + socket_list->sockets = g_slist_prepend (socket_list->sockets, discover_socket); + socket_list->n_sockets++; + } else { + arv_warning_interface ("Failed to bind discovery socket: %s", + error != NULL ? error->message : "Unknown reason"); + arv_gv_discover_socket_free (discover_socket); + } + } + } + g_list_free_full (ifaces, (GDestroyNotify) arv_network_interface_free); socket_list->poll_fds = g_new (GPollFD, socket_list->n_sockets); for (i = 0, iter = socket_list->sockets; iter != NULL; i++, iter = iter->next) { From f549f843f94980df68fb7e90510104e6781129d2 Mon Sep 17 00:00:00 2001 From: Brian Hackel Date: Tue, 27 Aug 2024 17:25:56 -0700 Subject: [PATCH 5/6] fixing some test failures and build warnings --- src/arvgvinterface.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/arvgvinterface.c b/src/arvgvinterface.c index 464946245..69aa69759 100644 --- a/src/arvgvinterface.c +++ b/src/arvgvinterface.c @@ -95,7 +95,6 @@ arv_gv_discover_socket_list_new (void) ArvGvDiscoverSocket *discover_socket = g_new0 (ArvGvDiscoverSocket, 1); GSocketAddress *socket_address; GSocketAddress *socket_broadcast; - GSocketAddress *any_socket_address; GInetAddress *any_address; GInetAddress *inet_address; GInetAddress *inet_broadcast; @@ -127,10 +126,8 @@ arv_gv_discover_socket_list_new (void) socket_fd = g_socket_get_fd(discover_socket->socket); if (setsockopt (socket_fd, SOL_SOCKET, SO_BINDTODEVICE, interface_name, strlen (interface_name)) == 0) { any_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); - any_socket_address = g_inet_socket_address_new (any_address, 0); - discover_socket->interface_address = arv_socket_bind_with_range (discover_socket->socket, any_socket_address, + discover_socket->interface_address = arv_socket_bind_with_range (discover_socket->socket, any_address, 0, FALSE, &error); - g_object_unref (any_socket_address); g_object_unref (any_address); } else { discover_socket->interface_address = arv_socket_bind_with_range (discover_socket->socket, inet_address, From 8340141eec8cfb3ce1a9006d8801eb5186623053 Mon Sep 17 00:00:00 2001 From: Brian Hackel Date: Tue, 27 Aug 2024 17:28:13 -0700 Subject: [PATCH 6/6] fixing test failures and build warnings --- src/arvgvdevice.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/arvgvdevice.c b/src/arvgvdevice.c index 8c6a7a302..2f3a66670 100644 --- a/src/arvgvdevice.c +++ b/src/arvgvdevice.c @@ -1983,7 +1983,6 @@ arv_gv_device_constructed (GObject *object) char *address_string; guint32 capabilities; guint32 device_mode; - GSocketAddress *socket_address; GInetAddress *any_address; int socket_fd; struct ifaddrs *addrs, *iap; @@ -2044,24 +2043,22 @@ arv_gv_device_constructed (GObject *object) socket_fd = g_socket_get_fd(io_data->socket); if (setsockopt (socket_fd, SOL_SOCKET, SO_BINDTODEVICE, interface_name, strlen (interface_name)) == 0) { any_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); - socket_address = g_inet_socket_address_new (any_address, 0); + io_data->interface_address = arv_socket_bind_with_range (io_data->socket, any_address, 0, + FALSE, &local_error); g_object_unref (any_address); } else { - socket_address = g_inet_socket_address_new (priv->interface_address, 0); + io_data->interface_address = arv_socket_bind_with_range (io_data->socket, priv->interface_address, 0, + FALSE, &local_error); } - io_data->interface_address = arv_socket_bind_with_range (io_data->socket, socket_address, 0, - FALSE, &local_error); + if (io_data->interface_address == NULL) { if (local_error == NULL) local_error = g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_ERROR_UNKNOWN, "Unknown error trying to bind device interface"); arv_device_take_init_error (ARV_DEVICE (gv_device), local_error); - g_object_unref (socket_address); - return; } - g_object_unref (socket_address); io_data->buffer = g_malloc (ARV_GV_DEVICE_BUFFER_SIZE);