mirror of
https://github.com/BotChain-Robots/rpc.git
synced 2026-07-08 08:57:21 +02:00
More macos connection fixes
This commit is contained in:
@@ -29,10 +29,10 @@ typedef int socket_t;
|
||||
class UDPClient final : public ICommunicationClient {
|
||||
|
||||
public:
|
||||
UDPClient(std::string /* ip */,
|
||||
UDPClient(std::string ip,
|
||||
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_rx_queue(rx_queue) {
|
||||
m_remote_ip(std::move(ip)), m_rx_queue(rx_queue) {
|
||||
}
|
||||
~UDPClient() override;
|
||||
int init() override;
|
||||
@@ -47,6 +47,7 @@ class UDPClient final : public ICommunicationClient {
|
||||
bool m_initialized = false;
|
||||
std::atomic<bool> m_stop_flag;
|
||||
std::thread m_thread;
|
||||
std::string m_remote_ip;
|
||||
std::shared_ptr<BlockingQueue<std::unique_ptr<std::vector<uint8_t>>>> m_rx_queue;
|
||||
};
|
||||
|
||||
|
||||
@@ -8,6 +8,48 @@
|
||||
#include <vector>
|
||||
|
||||
#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 "util/log.h"
|
||||
|
||||
@@ -84,7 +126,12 @@ int UDPClient::init() {
|
||||
|
||||
ip_mreq mreq{};
|
||||
mreq.imr_multiaddr.s_addr = inet_addr(RECV_MCAST.c_str());
|
||||
#ifdef _WIN32
|
||||
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
|
||||
// Get hostname, resolve to primary IPv4
|
||||
@@ -132,7 +179,7 @@ int UDPClient::init() {
|
||||
}
|
||||
|
||||
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) {
|
||||
spdlog::error("[UDP] Failed to set multicast TX interface");
|
||||
print_errno();
|
||||
|
||||
Reference in New Issue
Block a user