Browse Source

Introduce function to determine if ZT comms channel to peer is relayed

pull/6458/head
staphen 3 years ago committed by Anders Jenbo
parent
commit
663c33475b
  1. 2
      3rdParty/libzt/CMakeLists.txt
  2. 22
      Source/dvlnet/protocol_zt.cpp
  3. 1
      Source/dvlnet/protocol_zt.h
  4. 65
      Source/dvlnet/zerotier_native.cpp
  5. 4
      Source/dvlnet/zerotier_native.h

2
3rdParty/libzt/CMakeLists.txt vendored

@ -5,7 +5,7 @@ set(BUILD_HOST_SELFTEST OFF)
include(FetchContent)
FetchContent_Declare(libzt
GIT_REPOSITORY https://github.com/diasurgical/libzt.git
GIT_TAG d6c6a069a5041a3e89594c447ced3f15d77618b8)
GIT_TAG def49803307920da0ab5b9e9b70b399fdc2943dc)
FetchContent_MakeAvailableExcludeFromAll(libzt)
if(NOT ANDROID)

22
Source/dvlnet/protocol_zt.cpp

@ -12,6 +12,7 @@
#include <lwip/igmp.h>
#include <lwip/mld6.h>
#include <lwip/nd6.h>
#include <lwip/sockets.h>
#include <lwip/tcpip.h>
@ -312,6 +313,27 @@ bool protocol_zt::is_peer_connected(endpoint &peer)
return peer_list.count(peer) != 0 && peer_list[peer].fd != -1;
}
bool protocol_zt::is_peer_relayed(const endpoint &peer) const
{
ip6_addr_t address = {};
IP6_ADDR_PART(&address, 0, peer.addr[0], peer.addr[1], peer.addr[2], peer.addr[3]);
IP6_ADDR_PART(&address, 1, peer.addr[4], peer.addr[5], peer.addr[6], peer.addr[7]);
IP6_ADDR_PART(&address, 2, peer.addr[8], peer.addr[9], peer.addr[10], peer.addr[11]);
IP6_ADDR_PART(&address, 3, peer.addr[12], peer.addr[13], peer.addr[14], peer.addr[15]);
const u8_t *hwaddr;
if (nd6_get_next_hop_addr_or_queue(netif_default, nullptr, &address, &hwaddr) != ERR_OK)
return true;
uint64_t mac = hwaddr[0];
mac = (mac << 8) | hwaddr[1];
mac = (mac << 8) | hwaddr[2];
mac = (mac << 8) | hwaddr[3];
mac = (mac << 8) | hwaddr[4];
mac = (mac << 8) | hwaddr[5];
return zerotier_is_relayed(mac);
}
std::string protocol_zt::make_default_gamename()
{
std::string ret;

1
Source/dvlnet/protocol_zt.h

@ -75,6 +75,7 @@ public:
bool get_disconnected(endpoint &peer);
bool network_online();
bool is_peer_connected(endpoint &peer);
bool is_peer_relayed(const endpoint &peer) const;
static std::string make_default_gamename();
private:

65
Source/dvlnet/zerotier_native.cpp

@ -2,6 +2,7 @@
#include <SDL.h>
#include <atomic>
#include <unordered_map>
#ifdef USE_SDL1
#include "utils/sdl2_to_1_2_backports.h"
@ -38,6 +39,15 @@ namespace net {
namespace {
// static constexpr uint64_t zt_earth = 0x8056c2e21c000001;
constexpr uint64_t ZtNetwork = 0xa84ac5c10a7ebb5f;
std::atomic_bool zt_network_ready(false);
std::atomic_bool zt_node_online(false);
std::atomic_bool zt_joined(false);
std::unordered_map<uint64_t, zts_event_t> ztPeerEvents;
#ifdef DVL_ZT_SYMLINK
bool HasMultiByteChars(string_view path)
{
@ -107,38 +117,48 @@ std::string ToZTCompliantPath(string_view configPath)
}
#endif
} // namespace
// static constexpr uint64_t zt_earth = 0x8056c2e21c000001;
static constexpr uint64_t ZtNetwork = 0xa84ac5c10a7ebb5f;
static std::atomic_bool zt_network_ready(false);
static std::atomic_bool zt_node_online(false);
static std::atomic_bool zt_joined(false);
static void Callback(void *ptr)
void Callback(void *ptr)
{
zts_event_msg_t *msg = reinterpret_cast<zts_event_msg_t *>(ptr);
// printf("callback %i\n", msg->eventCode);
if (msg->event_code == ZTS_EVENT_NODE_ONLINE) {
switch (msg->event_code) {
case ZTS_EVENT_NODE_ONLINE:
Log("ZeroTier: ZTS_EVENT_NODE_ONLINE, nodeId={:x}", (unsigned long long)msg->node->node_id);
zt_node_online = true;
if (!zt_joined) {
zts_net_join(ZtNetwork);
zt_joined = true;
}
} else if (msg->event_code == ZTS_EVENT_NODE_OFFLINE) {
break;
case ZTS_EVENT_NODE_OFFLINE:
Log("ZeroTier: ZTS_EVENT_NODE_OFFLINE");
zt_node_online = false;
} else if (msg->event_code == ZTS_EVENT_NETWORK_READY_IP6) {
break;
case ZTS_EVENT_NETWORK_READY_IP6:
Log("ZeroTier: ZTS_EVENT_NETWORK_READY_IP6, networkId={:x}", (unsigned long long)msg->network->net_id);
zt_ip6setup();
zt_network_ready = true;
} else if (msg->event_code == ZTS_EVENT_ADDR_ADDED_IP6) {
break;
case ZTS_EVENT_ADDR_ADDED_IP6:
print_ip6_addr(&(msg->addr->addr));
break;
case ZTS_EVENT_PEER_DIRECT:
case ZTS_EVENT_PEER_RELAY:
ztPeerEvents[msg->peer->peer_id] = static_cast<zts_event_t>(msg->event_code);
break;
case ZTS_EVENT_PEER_PATH_DEAD:
ztPeerEvents.erase(msg->peer->peer_id);
break;
}
}
} // namespace
bool zerotier_network_ready()
{
return zt_network_ready && zt_node_online;
@ -156,5 +176,20 @@ void zerotier_network_start()
zts_node_start();
}
bool zerotier_is_relayed(uint64_t mac)
{
bool isRelayed = true;
if (zts_core_lock_obtain() != ZTS_ERR_OK)
return isRelayed;
zts_peer_info_t peerInfo;
if (zts_core_query_peer_info(ZtNetwork, mac, &peerInfo) == ZTS_ERR_OK) {
auto peerEvent = ztPeerEvents.find(peerInfo.peer_id);
if (peerEvent != ztPeerEvents.end())
isRelayed = (peerEvent->second == ZTS_EVENT_PEER_RELAY);
}
zts_core_lock_release();
return isRelayed;
}
} // namespace net
} // namespace devilution

4
Source/dvlnet/zerotier_native.h

@ -1,11 +1,13 @@
#pragma once
#include <cstdint>
namespace devilution {
namespace net {
bool zerotier_network_ready();
void zerotier_network_start();
void zerotier_network_stop();
bool zerotier_is_relayed(uint64_t mac);
// NOTE: We have patched our libzt to have the corresponding multicast
// MAC hardcoded, since libzt is still missing the proper handling.

Loading…
Cancel
Save