More macos connection fixes

This commit is contained in:
2026-03-31 21:31:45 -04:00
parent ae6bf34952
commit 25b971cacc
2 changed files with 51 additions and 3 deletions

View File

@@ -29,10 +29,10 @@ typedef int socket_t;
class UDPClient final : public ICommunicationClient { class UDPClient final : public ICommunicationClient {
public: public:
UDPClient(std::string /* ip */, UDPClient(std::string ip,
const std::shared_ptr<BlockingQueue<std::unique_ptr<std::vector<uint8_t>>>> &rx_queue) const std::shared_ptr<BlockingQueue<std::unique_ptr<std::vector<uint8_t>>>> &rx_queue)
: m_stop_flag(false), m_thread(std::thread(&UDPClient::rx_thread, this)), : m_stop_flag(false), m_thread(std::thread(&UDPClient::rx_thread, this)),
m_rx_queue(rx_queue) { m_remote_ip(std::move(ip)), m_rx_queue(rx_queue) {
} }
~UDPClient() override; ~UDPClient() override;
int init() override; int init() override;
@@ -47,6 +47,7 @@ class UDPClient final : public ICommunicationClient {
bool m_initialized = false; bool m_initialized = false;
std::atomic<bool> m_stop_flag; std::atomic<bool> m_stop_flag;
std::thread m_thread; std::thread m_thread;
std::string m_remote_ip;
std::shared_ptr<BlockingQueue<std::unique_ptr<std::vector<uint8_t>>>> m_rx_queue; std::shared_ptr<BlockingQueue<std::unique_ptr<std::vector<uint8_t>>>> m_rx_queue;
}; };

View File

@@ -8,6 +8,48 @@
#include <vector> #include <vector>
#include "UDPClient.h" #include "UDPClient.h"
#ifndef _WIN32
#include <ifaddrs.h>
#include <net/if.h>
static in_addr find_local_interface(const std::string &remote_ip) {
in_addr result{};
result.s_addr = htonl(INADDR_ANY);
in_addr remote{};
if (inet_pton(AF_INET, remote_ip.c_str(), &remote) != 1) {
return result;
}
ifaddrs *ifap = nullptr;
if (getifaddrs(&ifap) != 0) {
return result;
}
for (const ifaddrs *ifa = ifap; ifa != nullptr; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == nullptr || ifa->ifa_addr->sa_family != AF_INET) {
continue;
}
if (!(ifa->ifa_flags & IFF_UP) || (ifa->ifa_flags & IFF_LOOPBACK)) {
continue;
}
if (ifa->ifa_netmask == nullptr) {
continue;
}
const auto *sin = reinterpret_cast<const sockaddr_in *>(ifa->ifa_addr);
const auto *mask = reinterpret_cast<const sockaddr_in *>(ifa->ifa_netmask);
if ((sin->sin_addr.s_addr & mask->sin_addr.s_addr) ==
(remote.s_addr & mask->sin_addr.s_addr)) {
result = sin->sin_addr;
break;
}
}
freeifaddrs(ifap);
return result;
}
#endif
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
#include "util/log.h" #include "util/log.h"
@@ -84,7 +126,12 @@ int UDPClient::init() {
ip_mreq mreq{}; ip_mreq mreq{};
mreq.imr_multiaddr.s_addr = inet_addr(RECV_MCAST.c_str()); mreq.imr_multiaddr.s_addr = inet_addr(RECV_MCAST.c_str());
#ifdef _WIN32
mreq.imr_interface.s_addr = INADDR_ANY; mreq.imr_interface.s_addr = INADDR_ANY;
#else
mreq.imr_interface = find_local_interface(this->m_remote_ip);
spdlog::info("[UDP] Using interface {} for multicast", inet_ntoa(mreq.imr_interface));
#endif
#ifdef _WIN32 #ifdef _WIN32
// Get hostname, resolve to primary IPv4 // Get hostname, resolve to primary IPv4
@@ -132,7 +179,7 @@ int UDPClient::init() {
} }
in_addr tx_iface{}; in_addr tx_iface{};
tx_iface.s_addr = mreq.imr_interface.s_addr; // INADDR_ANY lets the OS pick tx_iface.s_addr = mreq.imr_interface.s_addr;
if (setsockopt(m_tx_socket, IPPROTO_IP, IP_MULTICAST_IF, &tx_iface, sizeof(tx_iface)) < 0) { if (setsockopt(m_tx_socket, IPPROTO_IP, IP_MULTICAST_IF, &tx_iface, sizeof(tx_iface)) < 0) {
spdlog::error("[UDP] Failed to set multicast TX interface"); spdlog::error("[UDP] Failed to set multicast TX interface");
print_errno(); print_errno();