mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-16 09:23:45 +02:00
Clean up zerotier.h to by proxy clean up Rust bindings, and implement inetaddress in Rust.
This commit is contained in:
parent
ce40a1df8a
commit
07b99a982d
19 changed files with 598 additions and 194 deletions
|
@ -100,7 +100,7 @@ enum ZT_ResultCode ZT_Node_processWirePacket(
|
|||
void *tptr,
|
||||
int64_t now,
|
||||
int64_t localSocket,
|
||||
const struct sockaddr_storage *remoteAddress,
|
||||
const ZT_InetAddress *remoteAddress,
|
||||
const void *packetData,
|
||||
unsigned int packetLength,
|
||||
int isZtBuffer,
|
||||
|
@ -108,7 +108,7 @@ enum ZT_ResultCode ZT_Node_processWirePacket(
|
|||
{
|
||||
try {
|
||||
ZeroTier::SharedPtr< ZeroTier::Buf > buf((isZtBuffer) ? ZT_PTRTOBUF(packetData) : new ZeroTier::Buf(packetData, packetLength & ZT_BUF_MEM_MASK));
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->processWirePacket(tptr, now, localSocket, remoteAddress, buf, packetLength, nextBackgroundTaskDeadline);
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->processWirePacket(tptr, now, localSocket, ZT_InetAddress_ptr_cast_const_sockaddr_storage_ptr(remoteAddress), buf, packetLength, nextBackgroundTaskDeadline);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
|
@ -755,4 +755,79 @@ int ZT_Fingerprint_fromString(ZT_Fingerprint *fp, const char *s)
|
|||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
void ZT_InetAddress_clear(ZT_InetAddress *ia)
|
||||
{
|
||||
if (likely(ia != nullptr))
|
||||
ZeroTier::Utils::zero<sizeof(ZT_InetAddress)>(ia);
|
||||
}
|
||||
|
||||
char *ZT_InetAddress_toString(const ZT_InetAddress *ia, char *buf, unsigned int cap)
|
||||
{
|
||||
if (likely((cap > 0)&&(buf != nullptr))) {
|
||||
if (likely((ia != nullptr)&&(cap >= ZT_INETADDRESS_STRING_SIZE_MAX))) {
|
||||
reinterpret_cast<const ZeroTier::InetAddress *>(ia)->toString(buf);
|
||||
} else {
|
||||
buf[0] = 0;
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
int ZT_InetAddress_fromString(ZT_InetAddress *ia, const char *str)
|
||||
{
|
||||
if (likely((ia != nullptr)&&(str != nullptr))) {
|
||||
return (int)reinterpret_cast<ZeroTier::InetAddress *>(ia)->fromString(str);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ZT_InetAddress_set(ZT_InetAddress *ia, const void *saddr)
|
||||
{
|
||||
if (likely(ia != nullptr))
|
||||
(*reinterpret_cast<ZeroTier::InetAddress *>(ia)) = reinterpret_cast<const struct sockaddr *>(saddr);
|
||||
}
|
||||
|
||||
void ZT_InetAddress_setIpBytes(ZT_InetAddress *ia, const void *ipBytes, unsigned int ipLen, unsigned int port)
|
||||
{
|
||||
if (likely(ia != nullptr))
|
||||
reinterpret_cast<ZeroTier::InetAddress *>(ia)->set(ipBytes, ipLen, port);
|
||||
}
|
||||
|
||||
void ZT_InetAddress_setPort(ZT_InetAddress *ia, unsigned int port)
|
||||
{
|
||||
if (likely(ia != nullptr))
|
||||
reinterpret_cast<ZeroTier::InetAddress *>(ia)->setPort(port);
|
||||
}
|
||||
|
||||
unsigned int ZT_InetAddress_port(const ZT_InetAddress *ia)
|
||||
{
|
||||
if (likely(ia != nullptr))
|
||||
return reinterpret_cast<const ZeroTier::InetAddress *>(ia)->port();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ZT_InetAddress_isNil(const ZT_InetAddress *ia)
|
||||
{
|
||||
return (int)( (ia == nullptr) || ((reinterpret_cast<const sockaddr_storage *>(ia))->ss_family == 0) );
|
||||
}
|
||||
|
||||
int ZT_InetAddress_isV4(const ZT_InetAddress *ia)
|
||||
{
|
||||
return (int)( (ia != nullptr) && ((reinterpret_cast<const sockaddr_storage *>(ia))->ss_family == AF_INET) );
|
||||
}
|
||||
|
||||
int ZT_InetAddress_isV6(const ZT_InetAddress *ia)
|
||||
{
|
||||
return (int)( (ia != nullptr) && ((reinterpret_cast<const sockaddr_storage *>(ia))->ss_family == AF_INET6) );
|
||||
}
|
||||
|
||||
enum ZT_InetAddress_IpScope ZT_InetAddress_ipScope(const ZT_InetAddress *ia)
|
||||
{
|
||||
if (likely(ia != nullptr))
|
||||
return reinterpret_cast<const ZeroTier::InetAddress *>(ia)->ipScope();
|
||||
return ZT_IP_SCOPE_NONE;
|
||||
}
|
||||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
@ -14,9 +14,13 @@
|
|||
#ifndef ZT_CONSTANTS_HPP
|
||||
#define ZT_CONSTANTS_HPP
|
||||
|
||||
#include "zerotier.h"
|
||||
#include "OS.hpp"
|
||||
/**
|
||||
* Indicates to some parts of zerotier.h that we are building the core
|
||||
*/
|
||||
#define ZT_CORE 1
|
||||
|
||||
#include "OS.hpp"
|
||||
#include "zerotier.h"
|
||||
#include "version.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
|
||||
namespace ZeroTier {
|
||||
|
||||
static_assert(ZT_SOCKADDR_STORAGE_SIZE == sizeof(sockaddr_storage), "ZT_SOCKADDR_STORAGE_SIZE is incorrect on this platform, must be size of sockaddr_storage");
|
||||
static_assert(ZT_SOCKADDR_STORAGE_SIZE == sizeof(InetAddress), "ZT_SOCKADDR_STORAGE_SIZE should equal InetAddress, which should equal size of sockaddr_storage");
|
||||
static_assert(ZT_SOCKADDR_STORAGE_SIZE == sizeof(ZT_InetAddress), "ZT_SOCKADDR_STORAGE_SIZE should equal ZT_InetAddress, which should equal size of sockaddr_storage");
|
||||
|
||||
const InetAddress InetAddress::LO4((const void *) ("\x7f\x00\x00\x01"), 4, 0);
|
||||
const InetAddress InetAddress::LO6((const void *) ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"), 16, 0);
|
||||
const InetAddress InetAddress::NIL;
|
||||
|
@ -31,11 +35,11 @@ InetAddress::IpScope InetAddress::ipScope() const noexcept
|
|||
const uint32_t ip = Utils::ntoh((uint32_t)as.sa_in.sin_addr.s_addr);
|
||||
switch (ip >> 24U) {
|
||||
case 0x00:
|
||||
return IP_SCOPE_NONE; // 0.0.0.0/8 (reserved, never used)
|
||||
return ZT_IP_SCOPE_NONE; // 0.0.0.0/8 (reserved, never used)
|
||||
case 0x06:
|
||||
return IP_SCOPE_PSEUDOPRIVATE; // 6.0.0.0/8 (US Army)
|
||||
return ZT_IP_SCOPE_PSEUDOPRIVATE; // 6.0.0.0/8 (US Army)
|
||||
case 0x0a:
|
||||
return IP_SCOPE_PRIVATE; // 10.0.0.0/8
|
||||
return ZT_IP_SCOPE_PRIVATE; // 10.0.0.0/8
|
||||
case 0x0b: //return IP_SCOPE_PSEUDOPRIVATE; // 11.0.0.0/8 (US DoD)
|
||||
case 0x15: //return IP_SCOPE_PSEUDOPRIVATE; // 21.0.0.0/8 (US DDN-RVN)
|
||||
case 0x16: //return IP_SCOPE_PSEUDOPRIVATE; // 22.0.0.0/8 (US DISA)
|
||||
|
@ -47,65 +51,65 @@ InetAddress::IpScope InetAddress::ipScope() const noexcept
|
|||
case 0x33: //return IP_SCOPE_PSEUDOPRIVATE; // 51.0.0.0/8 (UK Department of Social Security)
|
||||
case 0x37: //return IP_SCOPE_PSEUDOPRIVATE; // 55.0.0.0/8 (US DoD)
|
||||
case 0x38: // 56.0.0.0/8 (US Postal Service)
|
||||
return IP_SCOPE_PSEUDOPRIVATE;
|
||||
return ZT_IP_SCOPE_PSEUDOPRIVATE;
|
||||
case 0x64:
|
||||
if ((ip & 0xffc00000) == 0x64400000) return IP_SCOPE_PRIVATE; // 100.64.0.0/10
|
||||
if ((ip & 0xffc00000) == 0x64400000) return ZT_IP_SCOPE_PRIVATE; // 100.64.0.0/10
|
||||
break;
|
||||
case 0x7f:
|
||||
return IP_SCOPE_LOOPBACK; // 127.0.0.0/8
|
||||
return ZT_IP_SCOPE_LOOPBACK; // 127.0.0.0/8
|
||||
case 0xa9:
|
||||
if ((ip & 0xffff0000) == 0xa9fe0000) return IP_SCOPE_LINK_LOCAL; // 169.254.0.0/16
|
||||
if ((ip & 0xffff0000) == 0xa9fe0000) return ZT_IP_SCOPE_LINK_LOCAL; // 169.254.0.0/16
|
||||
break;
|
||||
case 0xac:
|
||||
if ((ip & 0xfff00000) == 0xac100000) return IP_SCOPE_PRIVATE; // 172.16.0.0/12
|
||||
if ((ip & 0xfff00000) == 0xac100000) return ZT_IP_SCOPE_PRIVATE; // 172.16.0.0/12
|
||||
break;
|
||||
case 0xc0:
|
||||
if ((ip & 0xffff0000) == 0xc0a80000) return IP_SCOPE_PRIVATE; // 192.168.0.0/16
|
||||
if ((ip & 0xffffff00) == 0xc0000200) return IP_SCOPE_PRIVATE; // 192.0.2.0/24
|
||||
if ((ip & 0xffff0000) == 0xc0a80000) return ZT_IP_SCOPE_PRIVATE; // 192.168.0.0/16
|
||||
if ((ip & 0xffffff00) == 0xc0000200) return ZT_IP_SCOPE_PRIVATE; // 192.0.2.0/24
|
||||
break;
|
||||
case 0xc6:
|
||||
if ((ip & 0xfffe0000) == 0xc6120000) return IP_SCOPE_PRIVATE; // 198.18.0.0/15
|
||||
if ((ip & 0xffffff00) == 0xc6336400) return IP_SCOPE_PRIVATE; // 198.51.100.0/24
|
||||
if ((ip & 0xfffe0000) == 0xc6120000) return ZT_IP_SCOPE_PRIVATE; // 198.18.0.0/15
|
||||
if ((ip & 0xffffff00) == 0xc6336400) return ZT_IP_SCOPE_PRIVATE; // 198.51.100.0/24
|
||||
break;
|
||||
case 0xcb:
|
||||
if ((ip & 0xffffff00) == 0xcb007100) return IP_SCOPE_PRIVATE; // 203.0.113.0/24
|
||||
if ((ip & 0xffffff00) == 0xcb007100) return ZT_IP_SCOPE_PRIVATE; // 203.0.113.0/24
|
||||
break;
|
||||
case 0xff:
|
||||
return IP_SCOPE_NONE; // 255.0.0.0/8 (broadcast, or unused/unusable)
|
||||
return ZT_IP_SCOPE_NONE; // 255.0.0.0/8 (broadcast, or unused/unusable)
|
||||
}
|
||||
switch (ip >> 28U) {
|
||||
case 0xe:
|
||||
return IP_SCOPE_MULTICAST; // 224.0.0.0/4
|
||||
return ZT_IP_SCOPE_MULTICAST; // 224.0.0.0/4
|
||||
case 0xf:
|
||||
return IP_SCOPE_PSEUDOPRIVATE; // 240.0.0.0/4 ("reserved," usually unusable)
|
||||
return ZT_IP_SCOPE_PSEUDOPRIVATE; // 240.0.0.0/4 ("reserved," usually unusable)
|
||||
}
|
||||
return IP_SCOPE_GLOBAL;
|
||||
return ZT_IP_SCOPE_GLOBAL;
|
||||
}
|
||||
|
||||
case AF_INET6: {
|
||||
const uint8_t *const ip = as.sa_in6.sin6_addr.s6_addr;
|
||||
if ((ip[0] & 0xf0U) == 0xf0) {
|
||||
if (ip[0] == 0xff) return IP_SCOPE_MULTICAST; // ff00::/8
|
||||
if (ip[0] == 0xff) return ZT_IP_SCOPE_MULTICAST; // ff00::/8
|
||||
if ((ip[0] == 0xfe) && ((ip[1] & 0xc0U) == 0x80)) {
|
||||
unsigned int k = 2;
|
||||
while ((!ip[k]) && (k < 15)) ++k;
|
||||
if ((k == 15) && (ip[15] == 0x01))
|
||||
return IP_SCOPE_LOOPBACK; // fe80::1/128
|
||||
else return IP_SCOPE_LINK_LOCAL; // fe80::/10
|
||||
return ZT_IP_SCOPE_LOOPBACK; // fe80::1/128
|
||||
else return ZT_IP_SCOPE_LINK_LOCAL; // fe80::/10
|
||||
}
|
||||
if ((ip[0] & 0xfeU) == 0xfc) return IP_SCOPE_PRIVATE; // fc00::/7
|
||||
if ((ip[0] & 0xfeU) == 0xfc) return ZT_IP_SCOPE_PRIVATE; // fc00::/7
|
||||
}
|
||||
unsigned int k = 0;
|
||||
while ((!ip[k]) && (k < 15)) ++k;
|
||||
if (k == 15) { // all 0's except last byte
|
||||
if (ip[15] == 0x01) return IP_SCOPE_LOOPBACK; // ::1/128
|
||||
if (ip[15] == 0x00) return IP_SCOPE_NONE; // ::/128
|
||||
if (ip[15] == 0x01) return ZT_IP_SCOPE_LOOPBACK; // ::1/128
|
||||
if (ip[15] == 0x00) return ZT_IP_SCOPE_NONE; // ::/128
|
||||
}
|
||||
return IP_SCOPE_GLOBAL;
|
||||
return ZT_IP_SCOPE_GLOBAL;
|
||||
}
|
||||
|
||||
}
|
||||
return IP_SCOPE_NONE;
|
||||
return ZT_IP_SCOPE_NONE;
|
||||
}
|
||||
|
||||
void InetAddress::set(const void *ipBytes, unsigned int ipLen, unsigned int port) noexcept
|
||||
|
|
|
@ -59,17 +59,7 @@ public:
|
|||
* MUST remain that way or Path must be changed to reflect. Also be sure
|
||||
* to change ZT_INETADDRESS_MAX_SCOPE if the max changes.
|
||||
*/
|
||||
enum IpScope
|
||||
{
|
||||
IP_SCOPE_NONE = 0, // NULL or not an IP address
|
||||
IP_SCOPE_MULTICAST = 1, // 224.0.0.0 and other V4/V6 multicast IPs
|
||||
IP_SCOPE_LOOPBACK = 2, // 127.0.0.1, ::1, etc.
|
||||
IP_SCOPE_PSEUDOPRIVATE = 3, // 28.x.x.x, etc. -- unofficially unrouted IPv4 blocks often "bogarted"
|
||||
IP_SCOPE_GLOBAL = 4, // globally routable IP address (all others)
|
||||
IP_SCOPE_LINK_LOCAL = 5, // 169.254.x.x, IPv6 LL
|
||||
IP_SCOPE_SHARED = 6, // currently unused, formerly used for carrier-grade NAT ranges
|
||||
IP_SCOPE_PRIVATE = 7 // 10.x.x.x, 192.168.x.x, etc.
|
||||
};
|
||||
typedef ZT_InetAddress_IpScope IpScope;
|
||||
|
||||
// Hasher for unordered sets and maps in C++11
|
||||
struct Hasher
|
||||
|
@ -130,52 +120,52 @@ public:
|
|||
|
||||
ZT_INLINE InetAddress &operator=(const sockaddr_in &sa) noexcept
|
||||
{
|
||||
memoryZero(this);
|
||||
as.sa_in = sa;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ZT_INLINE InetAddress &operator=(const sockaddr_in *sa) noexcept
|
||||
{
|
||||
memoryZero(this);
|
||||
if (sa)
|
||||
as.sa_in = *sa;
|
||||
else memoryZero(this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ZT_INLINE InetAddress &operator=(const sockaddr_in6 &sa) noexcept
|
||||
{
|
||||
memoryZero(this);
|
||||
as.sa_in6 = sa;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ZT_INLINE InetAddress &operator=(const sockaddr_in6 *sa) noexcept
|
||||
{
|
||||
memoryZero(this);
|
||||
if (sa)
|
||||
as.sa_in6 = *sa;
|
||||
else memoryZero(this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ZT_INLINE InetAddress &operator=(const sockaddr &sa) noexcept
|
||||
{
|
||||
memoryZero(this);
|
||||
if (sa.sa_family == AF_INET)
|
||||
as.sa_in = *reinterpret_cast<const sockaddr_in *>(&sa);
|
||||
else if (sa.sa_family == AF_INET6)
|
||||
as.sa_in6 = *reinterpret_cast<const sockaddr_in6 *>(&sa);
|
||||
else memoryZero(this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ZT_INLINE InetAddress &operator=(const sockaddr *sa) noexcept
|
||||
{
|
||||
memoryZero(this);
|
||||
if (sa) {
|
||||
if (sa->sa_family == AF_INET)
|
||||
as.sa_in = *reinterpret_cast<const sockaddr_in *>(sa);
|
||||
else if (sa->sa_family == AF_INET6)
|
||||
as.sa_in6 = *reinterpret_cast<const sockaddr_in6 *>(sa);
|
||||
else memoryZero(this);
|
||||
} else {
|
||||
memoryZero(this);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -625,6 +615,9 @@ static ZT_INLINE InetAddress *asInetAddress(sockaddr *const p) noexcept
|
|||
static ZT_INLINE InetAddress *asInetAddress(sockaddr_storage *const p) noexcept
|
||||
{ return reinterpret_cast<InetAddress *>(p); }
|
||||
|
||||
static ZT_INLINE InetAddress *asInetAddress(ZT_InetAddress *const p) noexcept
|
||||
{ return reinterpret_cast<InetAddress *>(p); }
|
||||
|
||||
static ZT_INLINE const InetAddress *asInetAddress(const sockaddr_in *const p) noexcept
|
||||
{ return reinterpret_cast<const InetAddress *>(p); }
|
||||
|
||||
|
@ -637,6 +630,9 @@ static ZT_INLINE const InetAddress *asInetAddress(const sockaddr *const p) noexc
|
|||
static ZT_INLINE const InetAddress *asInetAddress(const sockaddr_storage *const p) noexcept
|
||||
{ return reinterpret_cast<const InetAddress *>(p); }
|
||||
|
||||
static ZT_INLINE const InetAddress *asInetAddress(const ZT_InetAddress *const p) noexcept
|
||||
{ return reinterpret_cast<const InetAddress *>(p); }
|
||||
|
||||
static ZT_INLINE InetAddress &asInetAddress(sockaddr_in &p) noexcept
|
||||
{ return *reinterpret_cast<InetAddress *>(&p); }
|
||||
|
||||
|
@ -649,6 +645,9 @@ static ZT_INLINE InetAddress &asInetAddress(sockaddr &p) noexcept
|
|||
static ZT_INLINE InetAddress &asInetAddress(sockaddr_storage &p) noexcept
|
||||
{ return *reinterpret_cast<InetAddress *>(&p); }
|
||||
|
||||
static ZT_INLINE InetAddress &asInetAddress(ZT_InetAddress &p) noexcept
|
||||
{ return *reinterpret_cast<InetAddress *>(&p); }
|
||||
|
||||
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_in &p) noexcept
|
||||
{ return *reinterpret_cast<const InetAddress *>(&p); }
|
||||
|
||||
|
@ -661,6 +660,9 @@ static ZT_INLINE const InetAddress &asInetAddress(const sockaddr &p) noexcept
|
|||
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_storage &p) noexcept
|
||||
{ return *reinterpret_cast<const InetAddress *>(&p); }
|
||||
|
||||
static ZT_INLINE const InetAddress &asInetAddress(const ZT_InetAddress &p) noexcept
|
||||
{ return *reinterpret_cast<const InetAddress *>(&p); }
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
||||
|
|
|
@ -703,7 +703,7 @@ bool Node::shouldUsePathForZeroTierTraffic(void *tPtr, const Identity &id, const
|
|||
id.address().toInt(),
|
||||
(const ZT_Identity *)&id,
|
||||
localSocket,
|
||||
reinterpret_cast<const struct sockaddr_storage *>(&remoteAddress)) != 0);
|
||||
reinterpret_cast<const ZT_InetAddress *>(&remoteAddress)) != 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -719,7 +719,7 @@ bool Node::externalPathLookup(void *tPtr, const Identity &id, int family, InetAd
|
|||
id.address().toInt(),
|
||||
reinterpret_cast<const ZT_Identity *>(&id),
|
||||
family,
|
||||
reinterpret_cast<sockaddr_storage *>(&addr)) == ZT_RESULT_OK);
|
||||
reinterpret_cast<ZT_InetAddress *>(&addr)) == ZT_RESULT_OK);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -178,7 +178,7 @@ public:
|
|||
m_uPtr,
|
||||
tPtr,
|
||||
localSocket,
|
||||
&addr.as.ss,
|
||||
reinterpret_cast<const ZT_InetAddress *>(&addr.as.ss),
|
||||
data,
|
||||
len,
|
||||
ttl) == 0);
|
||||
|
|
|
@ -58,6 +58,13 @@
|
|||
|
||||
#endif /* Microsoft Windows */
|
||||
|
||||
#ifndef __WINDOWS__
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#endif /* NOT Microsoft Windows */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -53,7 +53,7 @@ void SelfAwareness::iam(void *tPtr, const Identity &reporter, const int64_t rece
|
|||
{
|
||||
const InetAddress::IpScope scope = myPhysicalAddress.ipScope();
|
||||
|
||||
if ((scope != reporterPhysicalAddress.ipScope()) || (scope == InetAddress::IP_SCOPE_NONE) || (scope == InetAddress::IP_SCOPE_LOOPBACK) || (scope == InetAddress::IP_SCOPE_MULTICAST))
|
||||
if ((scope != reporterPhysicalAddress.ipScope()) || (scope == ZT_IP_SCOPE_NONE) || (scope == ZT_IP_SCOPE_LOOPBACK) || (scope == ZT_IP_SCOPE_MULTICAST))
|
||||
return;
|
||||
|
||||
Mutex::Lock l(m_phy_l);
|
||||
|
|
126
core/zerotier.h
126
core/zerotier.h
|
@ -18,19 +18,6 @@
|
|||
#ifndef ZT_ZEROTIER_API_H
|
||||
#define ZT_ZEROTIER_API_H
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
#include <Windows.h>
|
||||
#else
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -281,6 +268,34 @@ typedef void ZT_Identity;
|
|||
*/
|
||||
typedef void ZT_Locator;
|
||||
|
||||
#define ZT_SOCKADDR_STORAGE_SIZE 128
|
||||
|
||||
/**
|
||||
* InetAddress holds a socket address
|
||||
*
|
||||
* This is a sized placeholder for InetAddress in the C++ code or the
|
||||
* sockaddr_storage structure. Its size is checked at compile time in
|
||||
* InetAddress.cpp against sizeof(sockaddr_storage) to ensure that it
|
||||
* is correct for the platform. If it's not correct, a platform ifdef
|
||||
* will be needed.
|
||||
*/
|
||||
typedef struct { uint64_t bits[ZT_SOCKADDR_STORAGE_SIZE / 8]; } ZT_InetAddress;
|
||||
|
||||
/**
|
||||
* IP scope types as identified by InetAddress.
|
||||
*/
|
||||
enum ZT_InetAddress_IpScope
|
||||
{
|
||||
ZT_IP_SCOPE_NONE = 0, // NULL or not an IP address
|
||||
ZT_IP_SCOPE_MULTICAST = 1, // 224.0.0.0 and other V4/V6 multicast IPs
|
||||
ZT_IP_SCOPE_LOOPBACK = 2, // 127.0.0.1, ::1, etc.
|
||||
ZT_IP_SCOPE_PSEUDOPRIVATE = 3, // 28.x.x.x, etc. -- unofficially unrouted IPv4 blocks often "bogarted"
|
||||
ZT_IP_SCOPE_GLOBAL = 4, // globally routable IP address (all others)
|
||||
ZT_IP_SCOPE_LINK_LOCAL = 5, // 169.254.x.x, IPv6 LL
|
||||
ZT_IP_SCOPE_SHARED = 6, // currently unused, formerly used for carrier-grade NAT ranges
|
||||
ZT_IP_SCOPE_PRIVATE = 7 // 10.x.x.x, 192.168.x.x, etc.
|
||||
};
|
||||
|
||||
/**
|
||||
* Full identity fingerprint with address and 384-bit hash of public key(s)
|
||||
*/
|
||||
|
@ -1311,12 +1326,12 @@ typedef struct
|
|||
/**
|
||||
* Target network / netmask bits (in port field) or NULL or 0.0.0.0/0 for default
|
||||
*/
|
||||
struct sockaddr_storage target;
|
||||
ZT_InetAddress target;
|
||||
|
||||
/**
|
||||
* Gateway IP address (port ignored) or NULL (family == 0) for LAN-local (no gateway)
|
||||
*/
|
||||
struct sockaddr_storage via;
|
||||
ZT_InetAddress via;
|
||||
|
||||
/**
|
||||
* Route flags
|
||||
|
@ -1439,7 +1454,7 @@ typedef struct
|
|||
* This is only used for ZeroTier-managed address assignments sent by the
|
||||
* virtual network's configuration master.
|
||||
*/
|
||||
struct sockaddr_storage assignedAddresses[ZT_MAX_ZT_ASSIGNED_ADDRESSES];
|
||||
ZT_InetAddress assignedAddresses[ZT_MAX_ZT_ASSIGNED_ADDRESSES];
|
||||
|
||||
/**
|
||||
* Number of ZT-pushed routes
|
||||
|
@ -1471,7 +1486,7 @@ typedef struct
|
|||
/**
|
||||
* IP and port as would be reachable by external nodes
|
||||
*/
|
||||
struct sockaddr_storage address;
|
||||
ZT_InetAddress address;
|
||||
|
||||
/**
|
||||
* If nonzero this address is static and can be incorporated into this node's Locator
|
||||
|
@ -1491,6 +1506,15 @@ typedef struct
|
|||
|
||||
union
|
||||
{
|
||||
/**
|
||||
* ZT_InetAddress, which is identically sized to sockaddr_storage.
|
||||
*
|
||||
* The ZT_InetAddress conversion macros can be used to get this in the
|
||||
* form of a sockaddr, sockaddr_in, etc.
|
||||
*/
|
||||
ZT_InetAddress ia;
|
||||
|
||||
#ifdef ZT_CORE
|
||||
/**
|
||||
* Socket address generic buffer
|
||||
*/
|
||||
|
@ -1510,6 +1534,7 @@ typedef struct
|
|||
* IPv6 address, for all ZT_ENDPOINT_TYPE_IP types if family is AF_INET6
|
||||
*/
|
||||
struct sockaddr_in6 sa_in6;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* MAC address (least significant 48 bites) for ZT_ENDPOINT_TYPE_ETHERNET and other MAC addressed types
|
||||
|
@ -1875,7 +1900,7 @@ typedef int (*ZT_WirePacketSendFunction)(
|
|||
void *, /* User ptr */
|
||||
void *, /* Thread ptr */
|
||||
int64_t, /* Local socket */
|
||||
const struct sockaddr_storage *, /* Remote address */
|
||||
const ZT_InetAddress *, /* Remote address */
|
||||
const void *, /* Packet data */
|
||||
unsigned int, /* Packet length */
|
||||
unsigned int); /* TTL or 0 to use default */
|
||||
|
@ -1909,7 +1934,7 @@ typedef int (*ZT_PathCheckFunction)(
|
|||
uint64_t, /* ZeroTier address */
|
||||
const ZT_Identity *, /* Full identity of node */
|
||||
int64_t, /* Local socket or -1 if unknown */
|
||||
const struct sockaddr_storage *); /* Remote address */
|
||||
const ZT_InetAddress *); /* Remote address */
|
||||
|
||||
/**
|
||||
* Function to get physical addresses for ZeroTier peers
|
||||
|
@ -1934,7 +1959,7 @@ typedef int (*ZT_PathLookupFunction)(
|
|||
uint64_t, /* ZeroTier address (40 bits) */
|
||||
const ZT_Identity *, /* Full identity of node */
|
||||
int, /* Desired ss_family or -1 for any */
|
||||
struct sockaddr_storage *); /* Result buffer */
|
||||
ZT_InetAddress *); /* Result buffer */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------------------- */
|
||||
|
||||
|
@ -2071,7 +2096,7 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_processWirePacket(
|
|||
void *tptr,
|
||||
int64_t now,
|
||||
int64_t localSocket,
|
||||
const struct sockaddr_storage *remoteAddress,
|
||||
const ZT_InetAddress *remoteAddress,
|
||||
const void *packetData,
|
||||
unsigned int packetLength,
|
||||
int isZtBuffer,
|
||||
|
@ -2892,6 +2917,65 @@ ZT_SDK_API int ZT_Fingerprint_fromString(ZT_Fingerprint *fp, const char *s);
|
|||
|
||||
/* ---------------------------------------------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* InetAddress casting macros depend on the relevant struct being defined.
|
||||
* System headers with sockaddr, sockaddr_in, etc. must have already been
|
||||
* included.
|
||||
*/
|
||||
|
||||
#define ZT_InetAddress_ptr_cast_sockaddr_ptr(a) ((struct sockaddr *)(a))
|
||||
#define ZT_InetAddress_ptr_cast_sockaddr_in_ptr(a) ((struct sockaddr_in *)(a))
|
||||
#define ZT_InetAddress_ptr_cast_sockaddr_in6_ptr(a) ((struct sockaddr_in6 *)(a))
|
||||
#define ZT_InetAddress_ptr_cast_sockaddr_storage_ptr(a) ((struct sockaddr_storage *)(a))
|
||||
|
||||
#define ZT_InetAddress_ptr_cast_const_sockaddr_ptr(a) ((const struct sockaddr *)(a))
|
||||
#define ZT_InetAddress_ptr_cast_const_sockaddr_in_ptr(a) ((const struct sockaddr_in *)(a))
|
||||
#define ZT_InetAddress_ptr_cast_const_sockaddr_in6_ptr(a) ((const struct sockaddr_in6 *)(a))
|
||||
#define ZT_InetAddress_ptr_cast_const_sockaddr_storage_ptr(a) ((const struct sockaddr_storage *)(a))
|
||||
|
||||
#define ZT_InetAddress_cast_sockaddr_ptr(a) ((struct sockaddr *)(&(a)))
|
||||
#define ZT_InetAddress_cast_sockaddr_in_ptr(a) ((struct sockaddr_in *)(&(a)))
|
||||
#define ZT_InetAddress_cast_sockaddr_in6_ptr(a) ((struct sockaddr_in6 *)(&(a)))
|
||||
#define ZT_InetAddress_cast_sockaddr_storage_ptr(a) ((struct sockaddr_storage *)(&(a)))
|
||||
|
||||
#define ZT_InetAddress_cast_const_sockaddr_ptr(a) ((const struct sockaddr *)(&(a)))
|
||||
#define ZT_InetAddress_cast_const_sockaddr_in_ptr(a) ((const struct sockaddr_in *)(&(a)))
|
||||
#define ZT_InetAddress_cast_const_sockaddr_in6_ptr(a) ((const struct sockaddr_in6 *)(&(a)))
|
||||
#define ZT_InetAddress_cast_const_sockaddr_storage_ptr(a) ((const struct sockaddr_storage *)(&(a)))
|
||||
|
||||
ZT_SDK_API void ZT_InetAddress_clear(ZT_InetAddress *ia);
|
||||
|
||||
/**
|
||||
* Convert an IP/port pair to a string
|
||||
*
|
||||
* @param ia InetAddress to convert
|
||||
* @param buf Buffer to store result
|
||||
* @param cap Size of buffer, must be at least 64 bytes
|
||||
* @return 'buf' is returned
|
||||
*/
|
||||
ZT_SDK_API char *ZT_InetAddress_toString(const ZT_InetAddress *ia, char *buf, unsigned int cap);
|
||||
|
||||
ZT_SDK_API int ZT_InetAddress_fromString(ZT_InetAddress *ia, const char *str);
|
||||
|
||||
ZT_SDK_API void ZT_InetAddress_set(ZT_InetAddress *ia, const void *saddr);
|
||||
|
||||
ZT_SDK_API void ZT_InetAddress_setIpBytes(ZT_InetAddress *ia, const void *ipBytes, unsigned int ipLen, unsigned int port);
|
||||
|
||||
ZT_SDK_API void ZT_InetAddress_setPort(ZT_InetAddress *ia, unsigned int port);
|
||||
|
||||
ZT_SDK_API unsigned int ZT_InetAddress_port(const ZT_InetAddress *ia);
|
||||
|
||||
ZT_SDK_API int ZT_InetAddress_isNil(const ZT_InetAddress *ia);
|
||||
|
||||
ZT_SDK_API int ZT_InetAddress_isV4(const ZT_InetAddress *ia);
|
||||
|
||||
ZT_SDK_API int ZT_InetAddress_isV6(const ZT_InetAddress *ia);
|
||||
|
||||
ZT_SDK_API enum ZT_InetAddress_IpScope ZT_InetAddress_ipScope(const ZT_InetAddress *ia);
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
46
rust-zerotier-core/Cargo.lock
generated
46
rust-zerotier-core/Cargo.lock
generated
|
@ -6,12 +6,6 @@ version = "1.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.2"
|
||||
|
@ -24,12 +18,6 @@ version = "0.4.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
version = "0.3.3"
|
||||
|
@ -77,7 +65,6 @@ dependencies = [
|
|||
"num-traits",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"socket2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -117,17 +104,6 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97e0e9fd577458a4f61fb91fcb559ea2afecc54c934119421f9f5d3d5b1a1057"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.54"
|
||||
|
@ -144,25 +120,3 @@ name = "unicode-xid"
|
|||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
|
|
@ -4,12 +4,9 @@ version = "0.1.0"
|
|||
authors = ["Adam Ierymenko <adam.ierymenko@zerotier.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
num-traits = "0.2.14"
|
||||
num-derive = "0.3.3"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
hex = "0.4.2"
|
||||
socket2 = "0.3.18"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::ffi::CStr;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::mem::MaybeUninit;
|
||||
use std::os::raw::{c_char, c_int};
|
||||
use std::os::raw::{c_char, c_int, c_void};
|
||||
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
use num_traits::FromPrimitive;
|
||||
|
@ -35,9 +35,14 @@ impl Endpoint {
|
|||
}
|
||||
|
||||
pub fn new_from_string(s: &str) -> Result<Endpoint, ResultCode> {
|
||||
let cs = CString::new(s);
|
||||
if cs.is_err() {
|
||||
return Err(ResultCode::ErrorBadParameter);
|
||||
}
|
||||
let cs = cs.unwrap();
|
||||
unsafe {
|
||||
let mut cep: MaybeUninit<ztcore::ZT_Endpoint> = MaybeUninit::uninit();
|
||||
let ec = ztcore::ZT_Endpoint_fromString(cep.as_mut_ptr(), s.as_ptr() as *const c_char) as i32;
|
||||
let ec = ztcore::ZT_Endpoint_fromString(cep.as_mut_ptr(), cs.as_ptr()) as i32;
|
||||
if ec == 0 {
|
||||
let epi = cep.assume_init();
|
||||
return Ok(Endpoint{
|
||||
|
@ -48,6 +53,18 @@ impl Endpoint {
|
|||
return Err(ResultCode::from_i32(ec).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a reference to the InetAddress in this endpoint or None if this is not of a relevant type.
|
||||
pub fn as_inetaddress(&self) -> Option<&InetAddress> {
|
||||
match self.type_ {
|
||||
EndpointType::Ip | EndpointType::IpUdp | EndpointType::IpTcp | EndpointType::IpHttp => {
|
||||
unsafe {
|
||||
Some(InetAddress::transmute_capi(&self.capi.value.ia))
|
||||
}
|
||||
},
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for Endpoint {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::*;
|
||||
use crate::bindings::capi as ztcore;
|
||||
use std::os::raw::{c_char, c_int};
|
||||
use std::ffi::CStr;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
pub struct Fingerprint {
|
||||
|
@ -19,9 +19,14 @@ impl Fingerprint {
|
|||
}
|
||||
|
||||
pub fn new_from_string(s: &str) -> Result<Fingerprint, ResultCode> {
|
||||
let cs = CString::new(s);
|
||||
if cs.is_err() {
|
||||
return Err(ResultCode::ErrorBadParameter);
|
||||
}
|
||||
let cs = cs.unwrap();
|
||||
let mut cfp: MaybeUninit<ztcore::ZT_Fingerprint> = MaybeUninit::uninit();
|
||||
unsafe {
|
||||
let mut cfp: MaybeUninit<ztcore::ZT_Fingerprint> = MaybeUninit::uninit();
|
||||
if ztcore::ZT_Fingerprint_fromString(cfp.as_mut_ptr(), s.as_ptr() as *const c_char) != 0 {
|
||||
if ztcore::ZT_Fingerprint_fromString(cfp.as_mut_ptr(), cs.as_ptr()) != 0 {
|
||||
let fp = cfp.assume_init();
|
||||
return Ok(Fingerprint{
|
||||
address: Address(fp.address),
|
||||
|
@ -43,7 +48,7 @@ impl ToString for Fingerprint {
|
|||
}, buf.as_mut_ptr() as *mut c_char, buf.len() as c_int).is_null() {
|
||||
return String::from("(invalid)");
|
||||
}
|
||||
return String::from(CStr::from_bytes_with_nul(buf.as_ref()).unwrap().to_str().unwrap());
|
||||
return cstr_to_string(buf.as_ptr() as *const c_char, 256);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::ffi::CStr;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::mem::MaybeUninit;
|
||||
use std::os::raw::*;
|
||||
|
||||
|
@ -49,7 +49,12 @@ impl Identity {
|
|||
/// Construct from a string representation of this identity.
|
||||
pub fn new_from_string(s: &str) -> Result<Identity, ResultCode> {
|
||||
unsafe {
|
||||
let id = ztcore::ZT_Identity_fromString(s.as_ptr() as *const c_char);
|
||||
let cs = CString::new(s);
|
||||
if cs.is_err() {
|
||||
return Err(ResultCode::ErrorBadParameter);
|
||||
}
|
||||
let cs = cs.unwrap();
|
||||
let id = ztcore::ZT_Identity_fromString(cs.as_ptr());
|
||||
if id.is_null() {
|
||||
return Err(ResultCode::ErrorBadParameter);
|
||||
}
|
||||
|
|
140
rust-zerotier-core/src/inetaddress.rs
Normal file
140
rust-zerotier-core/src/inetaddress.rs
Normal file
|
@ -0,0 +1,140 @@
|
|||
use std::ffi::CString;
|
||||
use std::mem::{MaybeUninit, transmute, size_of};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::*;
|
||||
use crate::bindings::capi as ztcore;
|
||||
|
||||
/// Opaque structure that can hold an IPv4 or IPv6 address.
|
||||
pub struct InetAddress {
|
||||
// This must be the same size as ZT_InetAddress in zerotier.h. This is
|
||||
// checked in tests.
|
||||
bits: [u64; (ztcore::ZT_SOCKADDR_STORAGE_SIZE / 8) as usize]
|
||||
}
|
||||
|
||||
impl InetAddress {
|
||||
#[inline(always)]
|
||||
pub fn new() -> InetAddress {
|
||||
InetAddress {
|
||||
bits: [0; (ztcore::ZT_SOCKADDR_STORAGE_SIZE / 8) as usize]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_from_string(s: &str) -> Option<InetAddress> {
|
||||
let mut a = InetAddress::new();
|
||||
let cs = CString::new(s);
|
||||
if cs.is_ok() {
|
||||
let cs = cs.unwrap();
|
||||
unsafe {
|
||||
if ztcore::ZT_InetAddress_fromString(a.as_mut_ptr(), cs.as_ptr()) == 0 {
|
||||
return None
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(a)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) unsafe fn transmute_capi(a: &ztcore::ZT_InetAddress) -> &InetAddress {
|
||||
unsafe {
|
||||
transmute(a)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn new_from_capi(a: ztcore::ZT_InetAddress) -> Option<InetAddress> {
|
||||
if a.bits[0] != 0 {
|
||||
Some(InetAddress {
|
||||
bits: a.bits
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
for i in self.bits.iter_mut() {
|
||||
*i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_nil(&self) -> bool {
|
||||
self.bits[0] == 0 // if ss_family != 0, this will not be zero
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn as_ptr(&self) -> *const ztcore::ZT_InetAddress {
|
||||
unsafe {
|
||||
transmute(self as *const InetAddress)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn as_mut_ptr(&mut self) -> *mut ztcore::ZT_InetAddress {
|
||||
unsafe {
|
||||
transmute(self as *mut InetAddress)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for InetAddress {
|
||||
fn to_string(&self) -> String {
|
||||
let mut buf: MaybeUninit<[c_char; 128]> = MaybeUninit::uninit();
|
||||
unsafe {
|
||||
return cstr_to_string(ztcore::ZT_InetAddress_toString(self.as_ptr(), (*buf.as_mut_ptr()).as_mut_ptr(), 128), 128);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for InetAddress {
|
||||
fn from(s: &str) -> InetAddress {
|
||||
let a = InetAddress::new_from_string(s);
|
||||
if a.is_none() {
|
||||
return InetAddress::new();
|
||||
}
|
||||
a.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::Serialize for InetAddress {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
||||
serializer.serialize_str(self.to_string().as_str())
|
||||
}
|
||||
}
|
||||
|
||||
struct InetAddressVisitor;
|
||||
|
||||
impl<'de> serde::de::Visitor<'de> for InetAddressVisitor {
|
||||
type Value = InetAddress;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("InetAddress value in string form")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||
let id = InetAddress::new_from_string(s);
|
||||
if id.is_none() {
|
||||
return Err(serde::de::Error::invalid_value(serde::de::Unexpected::Str(s), &self));
|
||||
}
|
||||
return Ok(id.unwrap() as Self::Value);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::Deserialize<'de> for InetAddress {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
|
||||
deserializer.deserialize_str(InetAddressVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::mem::{size_of, zeroed};
|
||||
|
||||
use crate::*;
|
||||
|
||||
#[test]
|
||||
fn type_sizes() {
|
||||
assert_eq!(size_of::<ztcore::ZT_InetAddress>(), size_of::<InetAddress>());
|
||||
}
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
#[link(name = ":../../build/core/libzt_core.a")]
|
||||
|
||||
use std::os::raw::{c_char, c_int};
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
|
||||
|
@ -9,6 +11,7 @@ mod fingerprint;
|
|||
mod endpoint;
|
||||
mod certificate;
|
||||
mod networkid;
|
||||
mod inetaddress;
|
||||
mod locator;
|
||||
mod path;
|
||||
mod peer;
|
||||
|
@ -26,6 +29,7 @@ pub use fingerprint::Fingerprint;
|
|||
pub use endpoint::*;
|
||||
pub use certificate::*;
|
||||
pub use networkid::NetworkId;
|
||||
pub use inetaddress::*;
|
||||
pub use locator::*;
|
||||
pub use path::Path;
|
||||
pub use peer::Peer;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::*;
|
||||
use crate::bindings::capi as ztcore;
|
||||
use std::os::raw::{c_char, c_int, c_uint};
|
||||
use std::ffi::CStr;
|
||||
use std::ffi::CString;
|
||||
|
||||
pub struct Locator {
|
||||
pub(crate) capi: *const ztcore::ZT_Locator,
|
||||
|
@ -19,7 +19,12 @@ impl Locator {
|
|||
|
||||
pub fn new_from_string(s: &str) -> Result<Locator, ResultCode> {
|
||||
unsafe {
|
||||
let l = ztcore::ZT_Locator_fromString(s.as_ptr() as *const c_char);
|
||||
let cs = CString::new(s);
|
||||
if cs.is_err() {
|
||||
return Err(ResultCode::ErrorBadParameter);
|
||||
}
|
||||
let cs = cs.unwrap();
|
||||
let l = ztcore::ZT_Locator_fromString(cs.as_ptr());
|
||||
if l.is_null() {
|
||||
return Err(ResultCode::ErrorBadParameter);
|
||||
}
|
||||
|
@ -72,7 +77,7 @@ impl ToString for Locator {
|
|||
if ztcore::ZT_Locator_toString(self.capi, buf.as_mut_ptr() as *mut c_char, buf.len() as c_int).is_null() {
|
||||
return String::from("(invalid)");
|
||||
}
|
||||
return String::from(CStr::from_bytes_with_nul(buf.as_ref()).unwrap().to_str().unwrap());
|
||||
return cstr_to_string(buf.as_ptr() as *const c_char, 4096);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,15 +8,16 @@ use std::sync::*;
|
|||
use std::sync::atomic::*;
|
||||
use std::time::Duration;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use num_traits::FromPrimitive;
|
||||
use socket2::SockAddr;
|
||||
|
||||
use crate::*;
|
||||
use crate::bindings::capi as ztcore;
|
||||
use crate::inetaddress::InetAddress;
|
||||
|
||||
const NODE_BACKGROUND_MIN_DELAY: i64 = 250;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct NodeStatus {
|
||||
pub address: Address,
|
||||
pub identity: Identity,
|
||||
|
@ -110,7 +111,7 @@ extern "C" fn zt_wire_packet_send_function(
|
|||
uptr: *mut c_void,
|
||||
tptr: *mut c_void,
|
||||
local_socket: i64,
|
||||
sock_addr: *const ztcore::sockaddr_storage,
|
||||
sock_addr: *const ztcore::ZT_InetAddress,
|
||||
data: *const c_void,
|
||||
data_size: c_uint,
|
||||
packet_ttl: c_uint
|
||||
|
@ -124,7 +125,7 @@ extern "C" fn zt_path_check_function(
|
|||
address: u64,
|
||||
identity: *const ztcore::ZT_Identity,
|
||||
local_socket: i64,
|
||||
sock_addr: *const ztcore::sockaddr_storage
|
||||
sock_addr: *const ztcore::ZT_InetAddress
|
||||
) {}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -135,7 +136,7 @@ extern "C" fn zt_path_lookup_function(
|
|||
address: u64,
|
||||
identity: *const ztcore::ZT_Identity,
|
||||
sock_family: c_int,
|
||||
sock_addr: *mut ztcore::sockaddr_storage
|
||||
sock_addr: *mut ztcore::ZT_InetAddress
|
||||
) {}
|
||||
|
||||
impl Node {
|
||||
|
@ -248,11 +249,11 @@ impl Node {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn process_wire_packet(&self, local_socket: i64, remote_address: &SockAddr, data: &mut Buffer) -> ResultCode {
|
||||
pub fn process_wire_packet<A>(&self, local_socket: i64, remote_address: &InetAddress, data: &mut Buffer) -> ResultCode {
|
||||
let current_time = self.now.get();
|
||||
let mut next_task_deadline: i64 = current_time;
|
||||
unsafe {
|
||||
return ResultCode::from_u32(ztcore::ZT_Node_processWirePacket(self.capi.get(), null_mut(), current_time, local_socket, remote_address.as_ptr() as *const ztcore::sockaddr_storage, data.zt_core_buf as *const c_void, data.data_size as u32, 1, &mut next_task_deadline as *mut i64) as u32).unwrap_or(ResultCode::ErrorInternalNonFatal);
|
||||
return ResultCode::from_u32(ztcore::ZT_Node_processWirePacket(self.capi.get(), null_mut(), current_time, local_socket, remote_address.as_ptr() as *const ztcore::ZT_InetAddress, data.zt_core_buf as *const c_void, data.data_size as u32, 1, &mut next_task_deadline as *mut i64) as u32).unwrap_or(ResultCode::ErrorInternalNonFatal);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,20 +1,75 @@
|
|||
use std::ffi::CStr;
|
||||
use std::mem::{size_of, transmute, zeroed};
|
||||
use std::os::raw::{c_void, c_char};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
use num_traits::FromPrimitive;
|
||||
use socket2::SockAddr;
|
||||
|
||||
use crate::*;
|
||||
use crate::bindings::capi as ztcore;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(FromPrimitive,ToPrimitive)]
|
||||
pub enum VirtualNetworkType {
|
||||
Private = ztcore::ZT_VirtualNetworkType_ZT_NETWORK_TYPE_PRIVATE as isize,
|
||||
Public = ztcore::ZT_VirtualNetworkType_ZT_NETWORK_TYPE_PUBLIC as isize
|
||||
}
|
||||
|
||||
impl VirtualNetworkType {
|
||||
pub fn to_str(&self) -> &str {
|
||||
match *self {
|
||||
//VirtualNetworkType::Private => "PRIVATE",
|
||||
VirtualNetworkType::Public => "PUBLIC",
|
||||
_ => "PRIVATE"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for VirtualNetworkType {
|
||||
fn from(s: &str) -> VirtualNetworkType {
|
||||
match s.to_ascii_lowercase().as_str() {
|
||||
//"requesting_configuration" | "requestingconfiguration" => VirtualNetworkStatus::RequestingConfiguration,
|
||||
"public" => VirtualNetworkType::Public,
|
||||
_ => VirtualNetworkType::Private
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for VirtualNetworkType {
|
||||
#[inline(always)]
|
||||
fn to_string(&self) -> String {
|
||||
String::from(self.to_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::Serialize for VirtualNetworkType {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
||||
serializer.serialize_str(self.to_str())
|
||||
}
|
||||
}
|
||||
|
||||
struct VirtualNetworkTypeVisitor;
|
||||
|
||||
impl<'de> serde::de::Visitor<'de> for VirtualNetworkTypeVisitor {
|
||||
type Value = VirtualNetworkType;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("VirtualNetworkType value in string form")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||
Ok(VirtualNetworkType::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::Deserialize<'de> for VirtualNetworkType {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
|
||||
deserializer.deserialize_str(VirtualNetworkTypeVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(FromPrimitive,ToPrimitive)]
|
||||
pub enum VirtualNetworkRuleType {
|
||||
ActionDrop = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_ACTION_DROP as isize,
|
||||
|
@ -54,6 +109,8 @@ pub enum VirtualNetworkRuleType {
|
|||
MatchIntegerRange = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_INTEGER_RANGE as isize
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(FromPrimitive,ToPrimitive)]
|
||||
pub enum VirtualNetworkConfigOperation {
|
||||
Up = ztcore::ZT_VirtualNetworkConfigOperation_ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP as isize,
|
||||
|
@ -62,6 +119,8 @@ pub enum VirtualNetworkConfigOperation {
|
|||
Destroy = ztcore::ZT_VirtualNetworkConfigOperation_ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY as isize
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(FromPrimitive,ToPrimitive)]
|
||||
pub enum VirtualNetworkStatus {
|
||||
RequestingConfiguration = ztcore::ZT_VirtualNetworkStatus_ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION as isize,
|
||||
|
@ -70,14 +129,73 @@ pub enum VirtualNetworkStatus {
|
|||
NotFound = ztcore::ZT_VirtualNetworkStatus_ZT_NETWORK_STATUS_NOT_FOUND as isize
|
||||
}
|
||||
|
||||
impl VirtualNetworkStatus {
|
||||
pub fn to_str(&self) -> &str {
|
||||
match *self {
|
||||
VirtualNetworkStatus::RequestingConfiguration => "REQUESTING_CONFIGURATION",
|
||||
VirtualNetworkStatus::Ok => "OK",
|
||||
VirtualNetworkStatus::AccessDenied => "ACCESS_DENIED",
|
||||
VirtualNetworkStatus::NotFound => "NOT_FOUND"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for VirtualNetworkStatus {
|
||||
fn from(s: &str) -> VirtualNetworkStatus {
|
||||
match s.to_ascii_lowercase().as_str() {
|
||||
//"requesting_configuration" | "requestingconfiguration" => VirtualNetworkStatus::RequestingConfiguration,
|
||||
"ok" => VirtualNetworkStatus::Ok,
|
||||
"access_denied" | "accessdenied" => VirtualNetworkStatus::AccessDenied,
|
||||
"not_found" | "notfound" => VirtualNetworkStatus::NotFound,
|
||||
_ => VirtualNetworkStatus::RequestingConfiguration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for VirtualNetworkStatus {
|
||||
#[inline(always)]
|
||||
fn to_string(&self) -> String {
|
||||
String::from(self.to_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::Serialize for VirtualNetworkStatus {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
||||
serializer.serialize_str(self.to_str())
|
||||
}
|
||||
}
|
||||
|
||||
struct VirtualNetworkStatusVisitor;
|
||||
|
||||
impl<'de> serde::de::Visitor<'de> for VirtualNetworkStatusVisitor {
|
||||
type Value = VirtualNetworkStatus;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("VirtualNetworkStatus value in string form")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||
Ok(VirtualNetworkStatus::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::Deserialize<'de> for VirtualNetworkStatus {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
|
||||
deserializer.deserialize_str(VirtualNetworkStatusVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct VirtualNetworkRoute {
|
||||
pub target: Option<SockAddr>,
|
||||
pub via: Option<SockAddr>,
|
||||
pub target: Option<InetAddress>,
|
||||
pub via: Option<InetAddress>,
|
||||
pub flags: u16,
|
||||
pub metric: u16
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct VirtualNetworkConfig {
|
||||
pub nwid: NetworkId,
|
||||
pub mac: MAC,
|
||||
|
@ -92,63 +210,45 @@ pub struct VirtualNetworkConfig {
|
|||
#[serde(rename = "netconfRevision")]
|
||||
pub netconf_revision: u64,
|
||||
#[serde(rename = "assignedAddresses")]
|
||||
pub assigned_addresses: Vec<SockAddr>,
|
||||
pub assigned_addresses: Vec<InetAddress>,
|
||||
pub routes: Vec<VirtualNetworkRoute>
|
||||
}
|
||||
|
||||
const SIZEOF_SOCKADDR_IN: ztcore::socklen_t = size_of::<ztcore::sockaddr_in>() as ztcore::socklen_t;
|
||||
const SIZEOF_SOCKADDR_IN6: ztcore::socklen_t = size_of::<ztcore::sockaddr_in6>() as ztcore::socklen_t;
|
||||
|
||||
/// Obtain a socket2::SockAddr from a C struct sockaddr_storage as used in the ZeroTier core.
|
||||
pub(crate) fn sockaddr_from_capi(ss: &ztcore::sockaddr_storage) -> Option<SockAddr> {
|
||||
// The transmute() calls in here are to work around the fact that socket2
|
||||
// uses sockaddr_storage from the libc crate, while ztcore uses it as
|
||||
// generated from bindgen from the system headers. It's the same thing but
|
||||
// Rust's type system doesn't know that.
|
||||
match ss.ss_family as u32 {
|
||||
ztcore::AF_INET => { unsafe { Some(SockAddr::from_raw_parts(transmute(ss as *const ztcore::sockaddr_storage), transmute(SIZEOF_SOCKADDR_IN))) } },
|
||||
ztcore::AF_INET6 => { unsafe { Some(SockAddr::from_raw_parts(transmute(ss as *const ztcore::sockaddr_storage), transmute(SIZEOF_SOCKADDR_IN6))) } },
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtualNetworkConfig {
|
||||
pub(crate) fn new_from_capi(vnc: &ztcore::ZT_VirtualNetworkConfig) -> VirtualNetworkConfig {
|
||||
unsafe {
|
||||
let mut aa: Vec<SockAddr> = Vec::new();
|
||||
let saptr = vnc.assignedAddresses.as_ptr();
|
||||
for i in 0..vnc.assignedAddressCount as isize {
|
||||
let sa = sockaddr_from_capi(&*saptr.offset(i));
|
||||
if sa.is_some() {
|
||||
aa.push(sa.unwrap());
|
||||
}
|
||||
let mut aa: Vec<InetAddress> = Vec::new();
|
||||
let saptr = vnc.assignedAddresses.as_ptr();
|
||||
for i in 0..vnc.assignedAddressCount as isize {
|
||||
let a = InetAddress::new_from_capi(unsafe { *saptr.offset(i) });
|
||||
if a.is_some() {
|
||||
aa.push(a.unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
let mut rts: Vec<VirtualNetworkRoute> = Vec::new();
|
||||
let rtptr = vnc.routes.as_ptr();
|
||||
for i in 0..vnc.routeCount as isize {
|
||||
let r = *rtptr.offset(i);
|
||||
rts.push(VirtualNetworkRoute{
|
||||
target: sockaddr_from_capi(&r.target),
|
||||
via: sockaddr_from_capi(&r.via),
|
||||
flags: r.flags,
|
||||
metric: r.metric
|
||||
})
|
||||
}
|
||||
let mut rts: Vec<VirtualNetworkRoute> = Vec::new();
|
||||
let rtptr = vnc.routes.as_ptr();
|
||||
for i in 0..vnc.routeCount as isize {
|
||||
let r = unsafe { *rtptr.offset(i) };
|
||||
rts.push(VirtualNetworkRoute{
|
||||
target: InetAddress::new_from_capi(r.target),
|
||||
via: InetAddress::new_from_capi(r.via),
|
||||
flags: r.flags,
|
||||
metric: r.metric
|
||||
})
|
||||
}
|
||||
|
||||
return VirtualNetworkConfig{
|
||||
nwid: NetworkId(vnc.nwid),
|
||||
mac: MAC(vnc.mac),
|
||||
name: String::from(CStr::from_ptr(vnc.name.as_ptr() as *const c_char).to_str().unwrap_or("")),
|
||||
status: FromPrimitive::from_u32(vnc.status as u32).unwrap(),
|
||||
type_: FromPrimitive::from_u32(vnc.type_ as u32).unwrap(),
|
||||
mtu: vnc.mtu as u32,
|
||||
bridge: vnc.bridge != 0,
|
||||
broadcast_enabled: vnc.broadcastEnabled != 0,
|
||||
netconf_revision: vnc.netconfRevision as u64,
|
||||
assigned_addresses: aa,
|
||||
routes: rts
|
||||
}
|
||||
return VirtualNetworkConfig{
|
||||
nwid: NetworkId(vnc.nwid),
|
||||
mac: MAC(vnc.mac),
|
||||
name: unsafe { cstr_to_string(vnc.name.as_ptr(), vnc.name.len() as isize) },
|
||||
status: FromPrimitive::from_u32(vnc.status as u32).unwrap(),
|
||||
type_: FromPrimitive::from_u32(vnc.type_ as u32).unwrap(),
|
||||
mtu: vnc.mtu as u32,
|
||||
bridge: vnc.bridge != 0,
|
||||
broadcast_enabled: vnc.broadcastEnabled != 0,
|
||||
netconf_revision: vnc.netconfRevision as u64,
|
||||
assigned_addresses: aa,
|
||||
routes: rts
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue