mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-09 04:04:13 +00:00
Whole heap more cleanup and refactoring...
This commit is contained in:
parent
647ce82b86
commit
36eab4f1a9
@ -35,21 +35,33 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef ZT_SOCKADDR_STORAGE
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
#include <Windows.h>
|
||||
#else /* not Windows */
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#endif /* Windows or not */
|
||||
#define ZT_SOCKADDR_STORAGE struct sockaddr_storage
|
||||
#endif /* !ZT_SOCKADDR_STORAGE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/* Core constants */
|
||||
/****************************************************************************/
|
||||
|
||||
/**
|
||||
* Maximum frame MTU
|
||||
*/
|
||||
#define ZT1_MAX_MTU 2800
|
||||
|
||||
/**
|
||||
* Maximum length of a wire message packet in bytes
|
||||
*/
|
||||
#define ZT1_MAX_WIRE_MESSAGE_LENGTH 1500
|
||||
|
||||
/****************************************************************************/
|
||||
/* Structures and other types */
|
||||
/****************************************************************************/
|
||||
@ -149,9 +161,9 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* Remote socket address
|
||||
* Socket address
|
||||
*/
|
||||
ZT_SOCKADDR_STORAGE remoteAddress;
|
||||
struct sockaddr_storage address;
|
||||
|
||||
/**
|
||||
* Link desperation -- higher equals "worse" or "slower"
|
||||
@ -191,7 +203,7 @@ typedef struct
|
||||
/**
|
||||
* Packet data
|
||||
*/
|
||||
const void *packetData;
|
||||
const char packetData[ZT1_MAX_WIRE_MESSAGE_LENGTH];
|
||||
|
||||
/**
|
||||
* Length of packet
|
||||
@ -207,7 +219,7 @@ typedef struct
|
||||
/**
|
||||
* ZeroTier network ID of virtual LAN port
|
||||
*/
|
||||
uint64_t networkId;
|
||||
uint64_t nwid;
|
||||
|
||||
/**
|
||||
* Source MAC address
|
||||
@ -232,7 +244,7 @@ typedef struct
|
||||
/**
|
||||
* Ethernet frame data
|
||||
*/
|
||||
const void *frameData;
|
||||
const char frameData[ZT1_MAX_MTU];
|
||||
|
||||
/**
|
||||
* Ethernet frame length
|
||||
@ -290,7 +302,7 @@ typedef struct
|
||||
/**
|
||||
* 64-bit ZeroTier network ID
|
||||
*/
|
||||
uint64_t networkId;
|
||||
uint64_t nwid;
|
||||
|
||||
/**
|
||||
* Ethernet MAC (40 bits) that should be assigned to port
|
||||
@ -346,7 +358,7 @@ typedef struct
|
||||
* This is only used for ZeroTier-managed address assignments sent by the
|
||||
* virtual network's configuration master.
|
||||
*/
|
||||
const ZT_SOCKADDR_STORAGE *assignedAddresses;
|
||||
const struct sockaddr_storage *assignedAddresses;
|
||||
|
||||
/**
|
||||
* Number of assigned addresses
|
||||
@ -376,7 +388,7 @@ typedef struct
|
||||
/**
|
||||
* Address of endpoint
|
||||
*/
|
||||
ZT_SOCKADDR_STORAGE address;
|
||||
struct sockaddr_storage address;
|
||||
|
||||
/**
|
||||
* Time since last send in milliseconds or -1 for never
|
||||
@ -466,7 +478,7 @@ typedef struct
|
||||
/**
|
||||
* Array of network paths to peer
|
||||
*/
|
||||
struct ZT1_PeerPhysicalPath *paths;
|
||||
ZT1_PeerPhysicalPath *paths;
|
||||
|
||||
/**
|
||||
* Number of paths (size of paths[])
|
||||
@ -561,7 +573,7 @@ typedef int (*ZT1_DataStorePutFunction)(ZT1_Node *,const char *,const void *,uns
|
||||
* @param node Result: pointer is set to new node instance on success
|
||||
* @param dataStoreGetFunction Function called to get objects from persistent storage
|
||||
* @param dataStorePutFunction Function called to put objects in persistent storage
|
||||
* @param portConfigCallback Function to be called when virtual LANs are created, deleted, or their config parameters change
|
||||
* @param networkConfigCallback Function to be called when virtual LANs are created, deleted, or their config parameters change
|
||||
* @param statusCallback Function to receive status updates and non-fatal error notices
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
@ -569,7 +581,7 @@ enum ZT1_ResultCode ZT1_Node_new(
|
||||
ZT1_Node **node,
|
||||
ZT1_DataStoreGetFunction *dataStoreGetFunction,
|
||||
ZT1_DataStorePutFunction *dataStorePutFunction,
|
||||
ZT1_VirtualPortConfigCallback *portConfigCallback,
|
||||
ZT1_VirtualNetworkConfigCallback *networkConfigCallback,
|
||||
ZT1_StatusCallback *statusCallback);
|
||||
|
||||
/**
|
||||
@ -609,11 +621,11 @@ enum ZT1_ResultCode ZT1_Node_run(
|
||||
uint64_t now,
|
||||
const ZT1_WireMessage *inputWireMessages,
|
||||
unsigned int inputWireMessageCount,
|
||||
const ZT1_VirtualLanFrame *inputLanFrames,
|
||||
unsigned int inputLanFrameCount,
|
||||
const ZT1_VirtualNetworkFrame *inputFrames,
|
||||
unsigned int inputFrameCount,
|
||||
const ZT1_WireMessage **outputWireMessages,
|
||||
unsigned int *outputWireMessageCount,
|
||||
const ZT1_VirtualLanFrame **outputLanFrames,
|
||||
const ZT1_VirtualNetworkFrame **outputFrames,
|
||||
unsigned int *outputLanFrameCount,
|
||||
unsigned long *maxNextInterval);
|
||||
|
||||
@ -624,10 +636,10 @@ enum ZT1_ResultCode ZT1_Node_run(
|
||||
* or these may be deffered if a netconf is not available yet.
|
||||
*
|
||||
* @param node Node instance
|
||||
* @param networkId 64-bit ZeroTIer network ID
|
||||
* @param nwid 64-bit ZeroTIer network ID
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
enum ZT1_ResultCode ZT1_Node_join(ZT1_Node *node,uint64_t networkId);
|
||||
enum ZT1_ResultCode ZT1_Node_join(ZT1_Node *node,uint64_t nwid);
|
||||
|
||||
/**
|
||||
* Leave a network
|
||||
@ -637,19 +649,18 @@ enum ZT1_ResultCode ZT1_Node_join(ZT1_Node *node,uint64_t networkId);
|
||||
* the port is now deleted.
|
||||
*
|
||||
* @param node Node instance
|
||||
* @param networkId 64-bit network ID
|
||||
* @param nwid 64-bit network ID
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
enum ZT1_ResultCode ZT1_Node_leave(ZT1_Node *node,uint64_t networkId);
|
||||
enum ZT1_ResultCode ZT1_Node_leave(ZT1_Node *node,uint64_t nwid);
|
||||
|
||||
/**
|
||||
* Get the status of this node
|
||||
*
|
||||
* @param node Node instance
|
||||
* @param status Buffer to fill with current node status
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
enum ZT1_ResultCode ZT1_Node_status(ZT1_Node *node,ZT1_NodeStatus *status);
|
||||
void ZT1_Node_status(ZT1_Node *node,ZT1_NodeStatus *status);
|
||||
|
||||
/**
|
||||
* Get a list of known peer nodes
|
||||
@ -710,6 +721,15 @@ enum ZT1_ResultCode ZT1_Node_setNetconfMaster(
|
||||
ZT1_Node *node,
|
||||
void *networkConfigMasterInstance);
|
||||
|
||||
/**
|
||||
* Get ZeroTier One version
|
||||
*
|
||||
* @param major Result: major version
|
||||
* @param minor Result: minor version
|
||||
* @param revision Result: revision
|
||||
*/
|
||||
void ZT1_version(int *major,int *minor,int *revision);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -299,16 +299,21 @@
|
||||
*/
|
||||
#define ZT_STARTUP_AGGRO (ZT_PING_UNANSWERED_AFTER * 2)
|
||||
|
||||
/**
|
||||
* How long since last message from an authoritative upstream peer before we increment our desperation level?
|
||||
*/
|
||||
#define ZT_DESPERATION_INCREMENT (ZT_STARTUP_AGGRO * 2)
|
||||
|
||||
/**
|
||||
* "Spam" packets to lower desperation links every Nth packet
|
||||
*/
|
||||
#define ZT_DESPERATION_SPAM_EVERY 10
|
||||
|
||||
/**
|
||||
* Maximum delay between runs of the main loop in Node.cpp
|
||||
*/
|
||||
#define ZT_MAX_SERVICE_LOOP_INTERVAL ZT_STARTUP_AGGRO
|
||||
|
||||
/**
|
||||
* Try TCP tunnels if nothing received for this long
|
||||
*/
|
||||
#define ZT_TCP_TUNNEL_FAILOVER_TIMEOUT (ZT_STARTUP_AGGRO * 5)
|
||||
|
||||
/**
|
||||
* Timeout for overall peer activity (measured from last receive)
|
||||
*/
|
||||
@ -319,11 +324,6 @@
|
||||
*/
|
||||
#define ZT_PEER_PATH_ACTIVITY_TIMEOUT ZT_PEER_ACTIVITY_TIMEOUT
|
||||
|
||||
/**
|
||||
* Close TCP sockets if unused for this long (SocketManager)
|
||||
*/
|
||||
#define ZT_TCP_TUNNEL_ACTIVITY_TIMEOUT ZT_PEER_ACTIVITY_TIMEOUT
|
||||
|
||||
/**
|
||||
* Stop relaying via peers that have not responded to direct sends
|
||||
*
|
||||
@ -374,28 +374,6 @@
|
||||
*/
|
||||
#define ZT_MIN_BEACON_RESPONSE_INTERVAL (ZT_BEACON_INTERVAL / 32)
|
||||
|
||||
/**
|
||||
* Minimum interval between attempts to do a software update
|
||||
*/
|
||||
#define ZT_UPDATE_MIN_INTERVAL 120000
|
||||
|
||||
/**
|
||||
* Maximum interval between checks for new versions
|
||||
*/
|
||||
#define ZT_UPDATE_MAX_INTERVAL 7200000
|
||||
|
||||
/**
|
||||
* Software update HTTP timeout in seconds
|
||||
*/
|
||||
#define ZT_UPDATE_HTTP_TIMEOUT 120
|
||||
|
||||
/**
|
||||
* Delay between fetches of the root topology update URL
|
||||
*
|
||||
* 86400000 = check once every 24 hours (this doesn't change often)
|
||||
*/
|
||||
#define ZT_UPDATE_ROOT_TOPOLOGY_CHECK_INTERVAL 86400000
|
||||
|
||||
/**
|
||||
* Sanity limit on maximum bridge routes
|
||||
*
|
||||
|
@ -45,24 +45,29 @@ const InetAddress InetAddress::DEFAULT6((const void *)0,16,0);
|
||||
void InetAddress::set(const std::string &ip,unsigned int port)
|
||||
throw()
|
||||
{
|
||||
memset(&_sa,0,sizeof(_sa));
|
||||
if (ip.find(':') != std::string::npos) {
|
||||
_sa.sin6.sin6_family = AF_INET6;
|
||||
_sa.sin6.sin6_port = Utils::hton((uint16_t)port);
|
||||
if (inet_pton(AF_INET6,ip.c_str(),(void *)&(_sa.sin6.sin6_addr.s6_addr)) <= 0)
|
||||
_sa.saddr.sa_family = 0;
|
||||
struct sockaddr_in6 sin6;
|
||||
memset(&sin6,0,sizeof(sin6));
|
||||
sin6.sin6_family = AF_INET6;
|
||||
sin6.sin6_port = Utils::hton((uint16_t)port);
|
||||
if (inet_pton(AF_INET6,ip.c_str(),(void *)&(sin6.sin6_addr.s6_addr)) <= 0)
|
||||
memset(this,0,sizeof(InetAddress));
|
||||
else *this = sin6;
|
||||
} else {
|
||||
_sa.sin.sin_family = AF_INET;
|
||||
_sa.sin.sin_port = Utils::hton((uint16_t)port);
|
||||
if (inet_pton(AF_INET,ip.c_str(),(void *)&(_sa.sin.sin_addr.s_addr)) <= 0)
|
||||
_sa.saddr.sa_family = 0;
|
||||
struct sockaddr_in sin;
|
||||
memset(&sin,0,sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = Utils::hton((uint16_t)port);
|
||||
if (inet_pton(AF_INET,ip.c_str(),(void *)&(sin.sin_addr.s_addr)) <= 0)
|
||||
memset(this,0,sizeof(InetAddress));
|
||||
else *this = sin;
|
||||
}
|
||||
}
|
||||
|
||||
void InetAddress::set(const void *ipBytes,unsigned int ipLen,unsigned int port)
|
||||
throw()
|
||||
{
|
||||
memset(&_sa,0,sizeof(_sa));
|
||||
memset(this,0,sizeof(InetAddress));
|
||||
if (ipLen == 4) {
|
||||
setV4();
|
||||
if (ipBytes)
|
||||
@ -79,59 +84,87 @@ void InetAddress::set(const void *ipBytes,unsigned int ipLen,unsigned int port)
|
||||
bool InetAddress::isLinkLocal() const
|
||||
throw()
|
||||
{
|
||||
if (_sa.saddr.sa_family == AF_INET)
|
||||
return ((Utils::ntoh((uint32_t)_sa.sin.sin_addr.s_addr) & 0xffff0000) == 0xa9fe0000);
|
||||
else if (_sa.saddr.sa_family == AF_INET6) {
|
||||
if (_sa.sin6.sin6_addr.s6_addr[0] != 0xfe) return false;
|
||||
if (_sa.sin6.sin6_addr.s6_addr[1] != 0x80) return false;
|
||||
if (_sa.sin6.sin6_addr.s6_addr[2] != 0x00) return false;
|
||||
if (_sa.sin6.sin6_addr.s6_addr[3] != 0x00) return false;
|
||||
if (_sa.sin6.sin6_addr.s6_addr[4] != 0x00) return false;
|
||||
if (_sa.sin6.sin6_addr.s6_addr[5] != 0x00) return false;
|
||||
if (_sa.sin6.sin6_addr.s6_addr[6] != 0x00) return false;
|
||||
if (_sa.sin6.sin6_addr.s6_addr[7] != 0x00) return false;
|
||||
return true;
|
||||
static const unsigned char v6llPrefix[8] = { 0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||
switch(ss_family) {
|
||||
case AF_INET:
|
||||
return ((Utils::ntoh((uint32_t)reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr) & 0xffff0000) == 0xa9fe0000);
|
||||
case AF_INET6:
|
||||
return (memcmp(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr,v6llPrefix,8) == 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InetAddress::isDefaultRoute() const
|
||||
throw()
|
||||
{
|
||||
if (_sa.saddr.sa_family == AF_INET)
|
||||
return ((_sa.sin.sin_addr.s_addr == 0)&&(_sa.sin.sin_port == 0));
|
||||
else if (_sa.saddr.sa_family == AF_INET6)
|
||||
return ((Utils::isZero(_sa.sin6.sin6_addr.s6_addr,16))&&(_sa.sin6.sin6_port == 0));
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string InetAddress::toString() const
|
||||
{
|
||||
char buf[128],buf2[128];
|
||||
|
||||
switch(_sa.saddr.sa_family) {
|
||||
char buf[128];
|
||||
switch(ss_family) {
|
||||
case AF_INET:
|
||||
#ifdef __WINDOWS__
|
||||
if (inet_ntop(AF_INET,(PVOID)&(_sa.sin.sin_addr.s_addr),buf,sizeof(buf))) {
|
||||
#else
|
||||
if (inet_ntop(AF_INET,(const void *)&(_sa.sin.sin_addr.s_addr),buf,sizeof(buf))) {
|
||||
#endif
|
||||
Utils::snprintf(buf2,sizeof(buf2),"%s/%u",buf,(unsigned int)ntohs(_sa.sin.sin_port));
|
||||
return std::string(buf2);
|
||||
}
|
||||
break;
|
||||
Utils::snprintf(buf,sizeof(buf),"%d.%d.%d.%d/%d",
|
||||
(int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[0],
|
||||
(int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[1],
|
||||
(int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[2],
|
||||
(int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[3],
|
||||
(int)Utils::ntoh((uint16_t)(reinterpret_cast<const struct sockaddr_in *>(this)->sin_port))
|
||||
);
|
||||
return std::string(buf);
|
||||
case AF_INET6:
|
||||
#ifdef __WINDOWS__
|
||||
if (inet_ntop(AF_INET6,(PVOID)&(_sa.sin6.sin6_addr.s6_addr),buf,sizeof(buf))) {
|
||||
#else
|
||||
if (inet_ntop(AF_INET6,(const void *)&(_sa.sin6.sin6_addr.s6_addr),buf,sizeof(buf))) {
|
||||
#endif
|
||||
Utils::snprintf(buf2,sizeof(buf2),"%s/%u",buf,(unsigned int)ntohs(_sa.sin6.sin6_port));
|
||||
return std::string(buf2);
|
||||
}
|
||||
break;
|
||||
Utils::snprintf(buf,sizeof(buf),"%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x/%d",
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[0]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[1]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[2]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[3]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[4]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[5]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[6]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[7]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[8]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[9]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[10]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[11]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[12]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[13]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[14]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[15]),
|
||||
(int)Utils::ntoh((uint16_t)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_port))
|
||||
);
|
||||
return std::string(buf);
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string InetAddress::toIpString() const
|
||||
{
|
||||
char buf[128];
|
||||
switch(ss_family) {
|
||||
case AF_INET:
|
||||
Utils::snprintf(buf,sizeof(buf),"%d.%d.%d.%d",
|
||||
(int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[0],
|
||||
(int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[1],
|
||||
(int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[2],
|
||||
(int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[3]
|
||||
);
|
||||
return std::string(buf);
|
||||
case AF_INET6:
|
||||
Utils::snprintf(buf,sizeof(buf),"%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x",
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[0]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[1]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[2]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[3]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[4]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[5]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[6]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[7]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[8]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[9]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[10]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[11]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[12]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[13]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[14]),
|
||||
(int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[15])
|
||||
);
|
||||
return std::string(buf);
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
@ -148,64 +181,16 @@ void InetAddress::fromString(const std::string &ipSlashPort)
|
||||
}
|
||||
}
|
||||
|
||||
std::string InetAddress::toIpString() const
|
||||
{
|
||||
char buf[128];
|
||||
switch(_sa.saddr.sa_family) {
|
||||
case AF_INET:
|
||||
#ifdef __WINDOWS__
|
||||
if (inet_ntop(AF_INET,(PVOID)&(_sa.sin.sin_addr.s_addr),buf,sizeof(buf)))
|
||||
return std::string(buf);
|
||||
#else
|
||||
if (inet_ntop(AF_INET,(const void *)&(_sa.sin.sin_addr.s_addr),buf,sizeof(buf)))
|
||||
return std::string(buf);
|
||||
#endif
|
||||
break;
|
||||
case AF_INET6:
|
||||
#ifdef __WINDOWS__
|
||||
if (inet_ntop(AF_INET6,(PVOID)&(_sa.sin6.sin6_addr.s6_addr),buf,sizeof(buf)))
|
||||
return std::string(buf);
|
||||
#else
|
||||
if (inet_ntop(AF_INET6,(const void *)&(_sa.sin6.sin6_addr.s6_addr),buf,sizeof(buf)))
|
||||
return std::string(buf);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
InetAddress InetAddress::netmask() const
|
||||
throw()
|
||||
{
|
||||
InetAddress r(*this);
|
||||
switch(_sa.saddr.sa_family) {
|
||||
switch(r.ss_family) {
|
||||
case AF_INET:
|
||||
r._sa.sin.sin_addr.s_addr = Utils::hton((uint32_t)(0xffffffff << (32 - netmaskBits())));
|
||||
reinterpret_cast<struct sockaddr_in *>(&r)->sin_addr.s_addr = Utils::hton((uint32_t)(0xffffffff << (32 - netmaskBits())));
|
||||
break;
|
||||
case AF_INET6: {
|
||||
unsigned char *bf = (unsigned char *)r._sa.sin6.sin6_addr.s6_addr;
|
||||
signed int bitsLeft = (signed int)netmaskBits();
|
||||
for(unsigned int i=0;i<16;++i) {
|
||||
if (bitsLeft > 0) {
|
||||
bf[i] = (unsigned char)((bitsLeft >= 8) ? 0xff : (0xff << (8 - bitsLeft)));
|
||||
bitsLeft -= 8;
|
||||
} else bf[i] = (unsigned char)0;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
InetAddress InetAddress::broadcast() const
|
||||
throw()
|
||||
{
|
||||
InetAddress r(*this);
|
||||
switch(_sa.saddr.sa_family) {
|
||||
case AF_INET:
|
||||
r._sa.sin.sin_addr.s_addr |= Utils::hton((uint32_t)(0xffffffff >> netmaskBits()));
|
||||
break;
|
||||
case AF_INET6: {
|
||||
unsigned char *bf = (unsigned char *)r._sa.sin6.sin6_addr.s6_addr;
|
||||
unsigned char *bf = reinterpret_cast<unsigned char *>(reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr);
|
||||
signed int bitsLeft = (signed int)netmaskBits();
|
||||
for(unsigned int i=0;i<16;++i) {
|
||||
if (bitsLeft > 0) {
|
||||
@ -218,130 +203,51 @@ InetAddress InetAddress::broadcast() const
|
||||
return r;
|
||||
}
|
||||
|
||||
bool InetAddress::sameNetworkAs(const InetAddress &ipnet) const
|
||||
InetAddress InetAddress::broadcast() const
|
||||
throw()
|
||||
{
|
||||
if (_sa.saddr.sa_family != ipnet._sa.saddr.sa_family)
|
||||
return false;
|
||||
|
||||
unsigned int bits = netmaskBits();
|
||||
if (bits != ipnet.netmaskBits())
|
||||
return false;
|
||||
if (!bits)
|
||||
return true;
|
||||
switch(_sa.saddr.sa_family) {
|
||||
InetAddress r(*this);
|
||||
switch(r.ss_family) {
|
||||
case AF_INET:
|
||||
if (bits >= 32) bits = 32;
|
||||
reinterpret_cast<struct sockaddr_in *>(&r)->sin_addr.s_addr |= Utils::hton((uint32_t)(0xffffffff >> netmaskBits()));
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (bits >= 128) bits = 128;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
case AF_INET6: {
|
||||
unsigned char *bf = reinterpret_cast<unsigned char *>(reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr);
|
||||
signed int bitsLeft = (signed int)netmaskBits();
|
||||
for(unsigned int i=0;i<16;++i) {
|
||||
if (bitsLeft > 0) {
|
||||
bf[i] |= (unsigned char)((bitsLeft >= 8) ? 0x00 : (0xff >> bitsLeft));
|
||||
bitsLeft -= 8;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
const uint8_t *a = (const uint8_t *)rawIpData();
|
||||
const uint8_t *b = (const uint8_t *)ipnet.rawIpData();
|
||||
while (bits >= 8) {
|
||||
if (*(a++) != *(b++))
|
||||
return false;
|
||||
bits -= 8;
|
||||
}
|
||||
bits = 8 - bits;
|
||||
return ((*a >> bits) == (*b >> bits));
|
||||
}
|
||||
|
||||
bool InetAddress::within(const InetAddress &ipnet) const
|
||||
throw()
|
||||
{
|
||||
if (_sa.saddr.sa_family != ipnet._sa.saddr.sa_family)
|
||||
return false;
|
||||
|
||||
unsigned int bits = ipnet.netmaskBits();
|
||||
switch(_sa.saddr.sa_family) {
|
||||
case AF_INET:
|
||||
if (bits > 32) return false;
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (bits > 128) return false;
|
||||
break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
const uint8_t *a = (const uint8_t *)rawIpData();
|
||||
const uint8_t *b = (const uint8_t *)ipnet.rawIpData();
|
||||
while (bits >= 8) {
|
||||
if (*(a++) != *(b++))
|
||||
return false;
|
||||
bits -= 8;
|
||||
}
|
||||
if (bits) {
|
||||
uint8_t mask = ((0xff << (8 - bits)) & 0xff);
|
||||
return ((*a & mask) == (*b & mask));
|
||||
} else return true;
|
||||
}
|
||||
|
||||
bool InetAddress::operator==(const InetAddress &a) const
|
||||
throw()
|
||||
{
|
||||
if (_sa.saddr.sa_family == AF_INET) {
|
||||
if (a._sa.saddr.sa_family == AF_INET)
|
||||
return ((_sa.sin.sin_addr.s_addr == a._sa.sin.sin_addr.s_addr)&&(_sa.sin.sin_port == a._sa.sin.sin_port));
|
||||
return false;
|
||||
} else if (_sa.saddr.sa_family == AF_INET6) {
|
||||
if (a._sa.saddr.sa_family == AF_INET6) {
|
||||
if (_sa.sin6.sin6_port == a._sa.sin6.sin6_port)
|
||||
return (!memcmp(_sa.sin6.sin6_addr.s6_addr,a._sa.sin6.sin6_addr.s6_addr,sizeof(_sa.sin6.sin6_addr.s6_addr)));
|
||||
}
|
||||
return false;
|
||||
} else return (memcmp(&_sa,&a._sa,sizeof(_sa)) == 0);
|
||||
}
|
||||
|
||||
bool InetAddress::operator<(const InetAddress &a) const
|
||||
throw()
|
||||
{
|
||||
if (_sa.saddr.sa_family < a._sa.saddr.sa_family)
|
||||
return true;
|
||||
else if (_sa.saddr.sa_family == a._sa.saddr.sa_family) {
|
||||
if (_sa.saddr.sa_family == AF_INET) {
|
||||
unsigned long x = Utils::ntoh((uint32_t)_sa.sin.sin_addr.s_addr);
|
||||
unsigned long y = Utils::ntoh((uint32_t)a._sa.sin.sin_addr.s_addr);
|
||||
if (x == y)
|
||||
return (Utils::ntoh((uint16_t)_sa.sin.sin_port) < Utils::ntoh((uint16_t)a._sa.sin.sin_port));
|
||||
else return (x < y);
|
||||
} else if (_sa.saddr.sa_family == AF_INET6) {
|
||||
int cmp = (int)memcmp(_sa.sin6.sin6_addr.s6_addr,a._sa.sin6.sin6_addr.s6_addr,16);
|
||||
if (cmp == 0)
|
||||
return (Utils::ntoh((uint16_t)_sa.sin6.sin6_port) < Utils::ntoh((uint16_t)a._sa.sin6.sin6_port));
|
||||
else return (cmp < 0);
|
||||
} else return (memcmp(&_sa,&a._sa,sizeof(_sa)) < 0);
|
||||
}
|
||||
return false;
|
||||
return r;
|
||||
}
|
||||
|
||||
InetAddress InetAddress::makeIpv6LinkLocal(const MAC &mac)
|
||||
throw()
|
||||
{
|
||||
InetAddress ip;
|
||||
ip._sa.saddr.sa_family = AF_INET6;
|
||||
ip._sa.sin6.sin6_addr.s6_addr[0] = 0xfe;
|
||||
ip._sa.sin6.sin6_addr.s6_addr[1] = 0x80;
|
||||
ip._sa.sin6.sin6_addr.s6_addr[2] = 0x00;
|
||||
ip._sa.sin6.sin6_addr.s6_addr[3] = 0x00;
|
||||
ip._sa.sin6.sin6_addr.s6_addr[4] = 0x00;
|
||||
ip._sa.sin6.sin6_addr.s6_addr[5] = 0x00;
|
||||
ip._sa.sin6.sin6_addr.s6_addr[6] = 0x00;
|
||||
ip._sa.sin6.sin6_addr.s6_addr[7] = 0x00;
|
||||
ip._sa.sin6.sin6_addr.s6_addr[8] = mac[0] & 0xfd;
|
||||
ip._sa.sin6.sin6_addr.s6_addr[9] = mac[1];
|
||||
ip._sa.sin6.sin6_addr.s6_addr[10] = mac[2];
|
||||
ip._sa.sin6.sin6_addr.s6_addr[11] = 0xff;
|
||||
ip._sa.sin6.sin6_addr.s6_addr[12] = 0xfe;
|
||||
ip._sa.sin6.sin6_addr.s6_addr[13] = mac[3];
|
||||
ip._sa.sin6.sin6_addr.s6_addr[14] = mac[4];
|
||||
ip._sa.sin6.sin6_addr.s6_addr[15] = mac[5];
|
||||
ip._sa.sin6.sin6_port = Utils::hton((uint16_t)64);
|
||||
return ip;
|
||||
struct sockaddr_in6 sin6;
|
||||
sin6.sin6_family = AF_INET6;
|
||||
sin6.sin6_addr.s6_addr[0] = 0xfe;
|
||||
sin6.sin6_addr.s6_addr[1] = 0x80;
|
||||
sin6.sin6_addr.s6_addr[2] = 0x00;
|
||||
sin6.sin6_addr.s6_addr[3] = 0x00;
|
||||
sin6.sin6_addr.s6_addr[4] = 0x00;
|
||||
sin6.sin6_addr.s6_addr[5] = 0x00;
|
||||
sin6.sin6_addr.s6_addr[6] = 0x00;
|
||||
sin6.sin6_addr.s6_addr[7] = 0x00;
|
||||
sin6.sin6_addr.s6_addr[8] = mac[0] & 0xfd;
|
||||
sin6.sin6_addr.s6_addr[9] = mac[1];
|
||||
sin6.sin6_addr.s6_addr[10] = mac[2];
|
||||
sin6.sin6_addr.s6_addr[11] = 0xff;
|
||||
sin6.sin6_addr.s6_addr[12] = 0xfe;
|
||||
sin6.sin6_addr.s6_addr[13] = mac[3];
|
||||
sin6.sin6_addr.s6_addr[14] = mac[4];
|
||||
sin6.sin6_addr.s6_addr[15] = mac[5];
|
||||
sin6.sin6_port = Utils::hton((uint16_t)64);
|
||||
return InetAddress(sin6);
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
@ -35,39 +35,20 @@
|
||||
#include <string>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "../include/ZeroTierOne.h"
|
||||
#include "Utils.hpp"
|
||||
#include "MAC.hpp"
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* Wrapper for sockaddr structures for IPV4 and IPV6
|
||||
* Extends sockaddr_storage with friendly C++ methods
|
||||
*
|
||||
* Note: this class is raw memcpy'able, which is used in a couple places.
|
||||
* This adds no new fields, so it can be memcpy'd and assigned to/from
|
||||
* raw sockaddr_storage structures. This is used in a few places.
|
||||
*/
|
||||
class InetAddress
|
||||
struct InetAddress : public sockaddr_storage
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Address type
|
||||
*/
|
||||
enum AddressType
|
||||
{
|
||||
TYPE_NULL = 0,
|
||||
TYPE_IPV4 = AF_INET,
|
||||
TYPE_IPV6 = AF_INET6
|
||||
};
|
||||
|
||||
/**
|
||||
* Loopback IPv4 address (no port)
|
||||
*/
|
||||
@ -88,9 +69,16 @@ public:
|
||||
*/
|
||||
static const InetAddress DEFAULT6;
|
||||
|
||||
InetAddress() throw() { memset(&_sa,0,sizeof(_sa)); }
|
||||
InetAddress(const InetAddress &a) throw() { memcpy(&_sa,&a._sa,sizeof(_sa)); }
|
||||
InetAddress(const struct sockaddr *sa) throw() { this->set(sa); }
|
||||
InetAddress() throw() { memset(this,0,sizeof(InetAddress)); }
|
||||
InetAddress(const InetAddress &a) throw() { memcpy(this,&a,sizeof(InetAddress)); }
|
||||
InetAddress(const struct sockaddr_storage &ss) throw() { *this = ss; }
|
||||
InetAddress(const struct sockaddr_storage *ss) throw() { *this = ss; }
|
||||
InetAddress(const struct sockaddr &sa) throw() { *this = sa; }
|
||||
InetAddress(const struct sockaddr *sa) throw() { *this = sa; }
|
||||
InetAddress(const struct sockaddr_in &sa) throw() { *this = sa; }
|
||||
InetAddress(const struct sockaddr_in *sa) throw() { *this = sa; }
|
||||
InetAddress(const struct sockaddr_in6 &sa) throw() { *this = sa; }
|
||||
InetAddress(const struct sockaddr_in6 *sa) throw() { *this = sa; }
|
||||
InetAddress(const void *ipBytes,unsigned int ipLen,unsigned int port) throw() { this->set(ipBytes,ipLen,port); }
|
||||
InetAddress(const uint32_t ipv4,unsigned int port) throw() { this->set(&ipv4,4,port); }
|
||||
InetAddress(const std::string &ip,unsigned int port) throw() { this->set(ip,port); }
|
||||
@ -100,23 +88,84 @@ public:
|
||||
inline InetAddress &operator=(const InetAddress &a)
|
||||
throw()
|
||||
{
|
||||
memcpy(&_sa,&a._sa,sizeof(_sa));
|
||||
memcpy(this,&a,sizeof(InetAddress));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set from an OS-level sockaddr structure
|
||||
*
|
||||
* @param sa Socket address (V4 or V6)
|
||||
*/
|
||||
inline void set(const struct sockaddr *sa)
|
||||
inline InetAddress &operator=(const struct sockaddr_storage &ss)
|
||||
throw()
|
||||
{
|
||||
switch(sa->sa_family) {
|
||||
case AF_INET: memcpy(&_sa.sin,sa,sizeof(struct sockaddr_in)); break;
|
||||
case AF_INET6: memcpy(&_sa.sin6,sa,sizeof(struct sockaddr_in6)); break;
|
||||
default: memset(&_sa,0,sizeof(_sa)); break;
|
||||
memcpy(this,&ss,sizeof(InetAddress));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline InetAddress &operator=(const struct sockaddr_storage *ss)
|
||||
throw()
|
||||
{
|
||||
memcpy(this,ss,sizeof(InetAddress));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline InetAddress &operator=(const struct sockaddr_in &sa)
|
||||
throw()
|
||||
{
|
||||
memset(this,0,sizeof(InetAddress));
|
||||
memcpy(this,&sa,sizeof(struct sockaddr_in));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline InetAddress &operator=(const struct sockaddr_in *sa)
|
||||
throw()
|
||||
{
|
||||
memset(this,0,sizeof(InetAddress));
|
||||
memcpy(this,sa,sizeof(struct sockaddr_in));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline InetAddress &operator=(const struct sockaddr_in6 &sa)
|
||||
throw()
|
||||
{
|
||||
memset(this,0,sizeof(InetAddress));
|
||||
memcpy(this,&sa,sizeof(struct sockaddr_in6));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline InetAddress &operator=(const struct sockaddr_in6 *sa)
|
||||
throw()
|
||||
{
|
||||
memset(this,0,sizeof(InetAddress));
|
||||
memcpy(this,sa,sizeof(struct sockaddr_in6));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline InetAddress &operator=(const struct sockaddr &sa)
|
||||
throw()
|
||||
{
|
||||
memset(this,0,sizeof(InetAddress));
|
||||
switch(sa.sa_family) {
|
||||
case AF_INET:
|
||||
memcpy(this,&sa,sizeof(struct sockaddr_in));
|
||||
break;
|
||||
case AF_INET6:
|
||||
memcpy(this,&sa,sizeof(struct sockaddr_in6));
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline InetAddress &operator=(const struct sockaddr *sa)
|
||||
throw()
|
||||
{
|
||||
memset(this,0,sizeof(InetAddress));
|
||||
switch(sa->sa_family) {
|
||||
case AF_INET:
|
||||
memcpy(this,sa,sizeof(struct sockaddr_in));
|
||||
break;
|
||||
case AF_INET6:
|
||||
memcpy(this,sa,sizeof(struct sockaddr_in6));
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -146,10 +195,14 @@ public:
|
||||
inline void setPort(unsigned int port)
|
||||
throw()
|
||||
{
|
||||
if (_sa.saddr.sa_family == AF_INET)
|
||||
_sa.sin.sin_port = Utils::hton((uint16_t)port);
|
||||
else if (_sa.saddr.sa_family == AF_INET6)
|
||||
_sa.sin6.sin6_port = Utils::hton((uint16_t)port);
|
||||
switch(ss_family) {
|
||||
case AF_INET:
|
||||
reinterpret_cast<struct sockaddr_in *>(this)->sin_port = Utils::hton((uint16_t)port);
|
||||
break;
|
||||
case AF_INET6:
|
||||
reinterpret_cast<struct sockaddr_in6 *>(this)->sin6_port = Utils::hton((uint16_t)port);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -158,45 +211,35 @@ public:
|
||||
bool isLinkLocal() const
|
||||
throw();
|
||||
|
||||
/**
|
||||
* @return True if this ip/netmask would represent a default route (e.g. 0.0.0.0/0)
|
||||
*/
|
||||
bool isDefaultRoute() const
|
||||
throw();
|
||||
|
||||
/**
|
||||
* @return True if this is a loopback address
|
||||
*/
|
||||
inline bool isLoopback() const
|
||||
throw()
|
||||
{
|
||||
return ((*this == LO4)||(*this == LO6));
|
||||
}
|
||||
inline bool isLoopback() const throw() { return ((*this == LO4)||(*this == LO6)); }
|
||||
|
||||
/**
|
||||
* @return ASCII IP/port format representation
|
||||
*/
|
||||
std::string toString() const;
|
||||
|
||||
/**
|
||||
* @param ipSlashPort ASCII IP/port format notation
|
||||
*/
|
||||
void fromString(const std::string &ipSlashPort);
|
||||
|
||||
/**
|
||||
* @return IP portion only, in ASCII string format
|
||||
*/
|
||||
std::string toIpString() const;
|
||||
|
||||
/**
|
||||
* @param ipSlashPort ASCII IP/port format notation
|
||||
*/
|
||||
void fromString(const std::string &ipSlashPort);
|
||||
|
||||
/**
|
||||
* @return Port or 0 if no port component defined
|
||||
*/
|
||||
inline unsigned int port() const
|
||||
throw()
|
||||
{
|
||||
switch(_sa.saddr.sa_family) {
|
||||
case AF_INET: return Utils::ntoh((uint16_t)_sa.sin.sin_port);
|
||||
case AF_INET6: return Utils::ntoh((uint16_t)_sa.sin6.sin6_port);
|
||||
switch(ss_family) {
|
||||
case AF_INET: return Utils::ntoh((uint16_t)(reinterpret_cast<const struct sockaddr_in *>(this)->sin_port));
|
||||
case AF_INET6: return Utils::ntoh((uint16_t)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_port));
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
@ -229,33 +272,22 @@ public:
|
||||
/**
|
||||
* @return True if this is an IPv4 address
|
||||
*/
|
||||
inline bool isV4() const throw() { return (_sa.saddr.sa_family == AF_INET); }
|
||||
inline bool isV4() const throw() { return (ss_family == AF_INET); }
|
||||
|
||||
/**
|
||||
* @return True if this is an IPv6 address
|
||||
*/
|
||||
inline bool isV6() const throw() { return (_sa.saddr.sa_family == AF_INET6); }
|
||||
|
||||
/**
|
||||
* @return Address type or TYPE_NULL if not defined
|
||||
*/
|
||||
inline AddressType type() const throw() { return (AddressType)_sa.saddr.sa_family; }
|
||||
inline bool isV6() const throw() { return (ss_family == AF_INET6); }
|
||||
|
||||
/**
|
||||
* Force type to IPv4
|
||||
*/
|
||||
inline void setV4() throw() { _sa.saddr.sa_family = AF_INET; }
|
||||
inline void setV4() throw() { ss_family = AF_INET; }
|
||||
|
||||
/**
|
||||
* Force type to IPv6
|
||||
*/
|
||||
inline void setV6() throw() { _sa.saddr.sa_family = AF_INET6; }
|
||||
|
||||
/**
|
||||
* @return Raw sockaddr structure
|
||||
*/
|
||||
inline struct sockaddr *saddr() throw() { return &(_sa.saddr); }
|
||||
inline const struct sockaddr *saddr() const throw() { return &(_sa.saddr); }
|
||||
inline void setV6() throw() { ss_family = AF_INET6; }
|
||||
|
||||
/**
|
||||
* @return Length of sockaddr_in if IPv4, sockaddr_in6 if IPv6
|
||||
@ -263,99 +295,62 @@ public:
|
||||
inline unsigned int saddrLen() const
|
||||
throw()
|
||||
{
|
||||
switch(_sa.saddr.sa_family) {
|
||||
switch(ss_family) {
|
||||
case AF_INET: return sizeof(struct sockaddr_in);
|
||||
case AF_INET6: return sizeof(struct sockaddr_in6);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Checksum of this address (not portable, so don't use for long-term storage purposes)
|
||||
*/
|
||||
inline uint64_t hashCode() const
|
||||
{
|
||||
switch(_sa.saddr.sa_family) {
|
||||
case AF_INET:
|
||||
return ((uint64_t)_sa.sin.sin_port + (uint64_t)(_sa.sin.sin_addr.s_addr));
|
||||
case AF_INET6:
|
||||
return ((uint64_t)_sa.sin6.sin6_port + ( ((const uint64_t *)_sa.sin6.sin6_addr.s6_addr)[0] ^ ((const uint64_t *)_sa.sin6.sin6_addr.s6_addr)[1] ));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Combined length of internal structure, room for either V4 or V6
|
||||
*/
|
||||
inline unsigned int saddrSpaceLen() const throw() { return sizeof(_sa); }
|
||||
|
||||
/**
|
||||
* @return Raw sockaddr_in structure (valid if IPv4)
|
||||
*/
|
||||
inline const struct sockaddr_in *saddr4() const throw() { return &(_sa.sin); }
|
||||
inline const struct sockaddr_in *saddr4() const throw() { return reinterpret_cast<const struct sockaddr_in *>(this); }
|
||||
|
||||
/**
|
||||
* @return Raw sockaddr_in6 structure (valid if IPv6)
|
||||
*/
|
||||
inline const struct sockaddr_in6 *saddr6() const throw() { return &(_sa.sin6); }
|
||||
inline const struct sockaddr_in6 *saddr6() const throw() { return reinterpret_cast<const struct sockaddr_in6 *>(this); }
|
||||
|
||||
/**
|
||||
* @return Raw IP address (4 bytes for IPv4, 16 bytes for IPv6)
|
||||
* @return pointer to raw IP address bytes
|
||||
*/
|
||||
inline void *rawIpData() throw() { return ((_sa.saddr.sa_family == AF_INET) ? (void *)(&(_sa.sin.sin_addr.s_addr)) : (void *)_sa.sin6.sin6_addr.s6_addr); }
|
||||
inline const void *rawIpData() const throw() { return ((_sa.saddr.sa_family == AF_INET) ? (void *)(&(_sa.sin.sin_addr.s_addr)) : (void *)_sa.sin6.sin6_addr.s6_addr); }
|
||||
|
||||
/**
|
||||
* Compare only the IP portions of addresses, ignoring port/netmask
|
||||
*
|
||||
* @param a Address to compare
|
||||
* @return True if both addresses are of the same (valid) type and their IPs match
|
||||
*/
|
||||
inline bool ipsEqual(const InetAddress &a) const
|
||||
inline const void *rawIpData() const
|
||||
throw()
|
||||
{
|
||||
if (_sa.saddr.sa_family == a._sa.saddr.sa_family) {
|
||||
switch(_sa.saddr.sa_family) {
|
||||
case AF_INET:
|
||||
return (_sa.sin.sin_addr.s_addr == a._sa.sin.sin_addr.s_addr);
|
||||
case AF_INET6:
|
||||
return (!memcmp(_sa.sin6.sin6_addr.s6_addr,a._sa.sin6.sin6_addr.s6_addr,16));
|
||||
}
|
||||
switch(ss_family) {
|
||||
case AF_INET: return (const void *)&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr);
|
||||
case AF_INET6: return (const void *)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr);
|
||||
default: return 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare IP/netmask with another IP/netmask
|
||||
*
|
||||
* @param ipnet IP/netmask to compare with
|
||||
* @return True if [netmask] bits match
|
||||
* @return pointer to raw IP address bytes
|
||||
*/
|
||||
bool sameNetworkAs(const InetAddress &ipnet) const
|
||||
throw();
|
||||
|
||||
/**
|
||||
* Determine whether this address is within an ip/netmask
|
||||
*
|
||||
* @param ipnet IP/netmask
|
||||
* @return True if this address is within this network
|
||||
*/
|
||||
bool within(const InetAddress &ipnet) const
|
||||
throw();
|
||||
inline void *rawIpData()
|
||||
throw()
|
||||
{
|
||||
switch(ss_family) {
|
||||
case AF_INET: return (void *)&(reinterpret_cast<struct sockaddr_in *>(this)->sin_addr.s_addr);
|
||||
case AF_INET6: return (void *)(reinterpret_cast<struct sockaddr_in6 *>(this)->sin6_addr.s6_addr);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to null/zero
|
||||
*/
|
||||
inline void zero() throw() { memset(&_sa,0,sizeof(_sa)); }
|
||||
inline void zero() throw() { memset(this,0,sizeof(InetAddress)); }
|
||||
|
||||
/**
|
||||
* @return True if address family is non-zero
|
||||
*/
|
||||
inline operator bool() const throw() { return ((_sa.saddr.sa_family == AF_INET)||(_sa.saddr.sa_family == AF_INET6)); }
|
||||
inline operator bool() const throw() { return (ss_family != 0); }
|
||||
|
||||
bool operator==(const InetAddress &a) const throw();
|
||||
inline bool operator==(const InetAddress &a) const throw() { return (memcmp(this,&a,sizeof(InetAddress)) == 0); }
|
||||
inline bool operator!=(const InetAddress &a) const throw() { return !(*this == a); }
|
||||
bool operator<(const InetAddress &a) const throw();
|
||||
inline bool operator<(const InetAddress &a) const throw() { return (memcmp(this,&a,sizeof(InetAddress)) < 0); }
|
||||
inline bool operator>(const InetAddress &a) const throw() { return (a < *this); }
|
||||
inline bool operator<=(const InetAddress &a) const throw() { return !(a < *this); }
|
||||
inline bool operator>=(const InetAddress &a) const throw() { return !(*this < a); }
|
||||
@ -366,13 +361,6 @@ public:
|
||||
*/
|
||||
static InetAddress makeIpv6LinkLocal(const MAC &mac)
|
||||
throw();
|
||||
|
||||
private:
|
||||
union {
|
||||
struct sockaddr saddr;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_in6 sin6;
|
||||
} _sa;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
@ -71,6 +71,13 @@ public:
|
||||
|
||||
MAC(const Address &ztaddr,uint64_t nwid) throw() { fromAddress(ztaddr,nwid); }
|
||||
|
||||
MAC(const uint64_t m) throw() : _m(m & 0xffffffffffffULL) {}
|
||||
|
||||
/**
|
||||
* @return MAC in 64-bit integer
|
||||
*/
|
||||
inline uint64_t toInt() const throw() { return _m; }
|
||||
|
||||
/**
|
||||
* Set MAC to zero
|
||||
*/
|
||||
|
30
node/Node.cpp
Normal file
30
node/Node.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
||||
*
|
||||
* If you would like to embed ZeroTier into a commercial application or
|
||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
||||
* LLC. Start here: http://www.zerotier.com/
|
||||
*/
|
||||
|
||||
#include "Node.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
|
206
node/Node.hpp
Normal file
206
node/Node.hpp
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
||||
*
|
||||
* If you would like to embed ZeroTier into a commercial application or
|
||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
||||
* LLC. Start here: http://www.zerotier.com/
|
||||
*/
|
||||
|
||||
#ifndef ZT_NODE_HPP
|
||||
#define ZT_NODE_HPP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "Constants.hpp"
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
|
||||
#include "InetAddress.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "MAC.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class RuntimeEnvironment;
|
||||
|
||||
/**
|
||||
* Implementation of Node object as defined in CAPI
|
||||
*
|
||||
* The pointer returned by ZT1_Node_new() is an instance of this class.
|
||||
*/
|
||||
class Node
|
||||
{
|
||||
public:
|
||||
Node(
|
||||
ZT1_DataStoreGetFunction *dataStoreGetFunction,
|
||||
ZT1_DataStorePutFunction *dataStorePutFunction,
|
||||
ZT1_VirtualNetworkConfigCallback *networkConfigCallback,
|
||||
ZT1_StatusCallback *statusCallback);
|
||||
|
||||
~Node();
|
||||
|
||||
// Public API Functions ----------------------------------------------------
|
||||
|
||||
ZT1_ResultCode run(
|
||||
uint64_t now,
|
||||
const ZT1_WireMessage *inputWireMessages,
|
||||
unsigned int inputWireMessageCount,
|
||||
const ZT1_VirtualLanFrame *inputLanFrames,
|
||||
unsigned int inputLanFrameCount,
|
||||
const ZT1_WireMessage **outputWireMessages,
|
||||
unsigned int *outputWireMessageCount,
|
||||
const ZT1_VirtualNetworkFrame **outputFrames,
|
||||
unsigned int *outputLanFrameCount,
|
||||
unsigned long *maxNextInterval);
|
||||
|
||||
ZT1_ResultCode join(uint64_t nwid);
|
||||
|
||||
ZT1_ResultCode leave(uint64_t nwid);
|
||||
|
||||
void status(ZT1_NodeStatus *status);
|
||||
|
||||
ZT1_PeerList *peers();
|
||||
|
||||
ZT1_VirtualNetworkConfig *networkConfig(uint64_t nwid);
|
||||
|
||||
ZT1_VirtualNetworkList *listNetworks();
|
||||
|
||||
void freeQueryResult(void *qr);
|
||||
|
||||
ZT1_ResultCode setNetconfMaster(
|
||||
ZT1_Node *node,
|
||||
void *networkConfigMasterInstance);
|
||||
|
||||
// Internal functions ------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @return Time as of last call to run()
|
||||
*/
|
||||
inline uint64_t now() const throw() { return _now; }
|
||||
|
||||
/**
|
||||
* @return Current level of desperation
|
||||
*/
|
||||
inline int desperation() const throw() { return (int)((_now - _timeOfLastPrivilgedPacket) / ZT_DESPERATION_INCREMENT); }
|
||||
|
||||
/**
|
||||
* Enqueue a ZeroTier message to be sent
|
||||
*
|
||||
* @param addr Destination address
|
||||
* @param data Packet data
|
||||
* @param len Packet length
|
||||
*/
|
||||
inline void putPacket(const InetAddress &addr,const void *data,unsigned int len)
|
||||
{
|
||||
Mutex::Lock _l(_outputWireMessages_m);
|
||||
if (_outputWireMessageCount >= _outputWireMessageCapacity) {
|
||||
ZT1_WireMessage *old = _outputWireMessages;
|
||||
_outputWireMessages = new ZT1_WireMessage[_outputWireMessageCapacity *= 2];
|
||||
memcpy(_outputWireMessages,old,sizeof(ZT1_WireMessage) * _outputWireMessageCount);
|
||||
delete [] old;
|
||||
}
|
||||
ZT1_WireMessage &wm = _outputWireMessages[_outputWireMessageCount++];
|
||||
memcpy(&(wm.address),&addr,sizeof(ZT_SOCKADDR_STORAGE));
|
||||
wm.desperation = this->desperation();
|
||||
wm.spam = (int)((++_spamCounter % ZT_DESPERATION_SPAM_EVERY) == 0);
|
||||
memcpy(wm.packetData,data,len);
|
||||
wm.packetLength = len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue a frame to be injected into a tap device (port)
|
||||
*
|
||||
* @param nwid Network ID
|
||||
* @param source Source MAC
|
||||
* @param dest Destination MAC
|
||||
* @param etherType 16-bit ethernet type
|
||||
* @param vlanId VLAN ID or 0 if none
|
||||
* @param data Frame data
|
||||
* @param len Frame length
|
||||
*/
|
||||
inline void putFrame(uint64_t nwid,const MAC &source,const MAC &dest,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
|
||||
{
|
||||
Mutex::Lock _l(_outputFrames_m);
|
||||
if (_outputFrameCount >= _outputFrameCapacity) {
|
||||
ZT1_VirtualNetworkFrame *old = _outputFrames;
|
||||
_outputFrames = new ZT1_VirtualNetworkFrame[_outputFrameCapacity *= 2];
|
||||
memcpy(_outputFrames,old,sizeof(ZT1_VirtualNetworkFrame) * _outputFrameCount);
|
||||
delete [] old;
|
||||
}
|
||||
ZT1_VirtualNetworkFrame &f = _outputFrames[_outputFrameCount++];
|
||||
f.nwid = nwid;
|
||||
f.sourceMac = source.toInt();
|
||||
f.destMac = dest.toInt();
|
||||
f.etherType = etherType;
|
||||
f.vlanId = vlanId;
|
||||
memcpy(f.frameData,data,len);
|
||||
f.frameLength = len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nwid Network ID
|
||||
* @return Network instance
|
||||
*/
|
||||
inline SharedPtr<Network> network(uint64_t nwid)
|
||||
{
|
||||
Mutex::Lock _l(_networks_m);
|
||||
std::map< uint64_t,Network >::iterator nw(_networks.find(nwid));
|
||||
return ((nw == _networks.end()) ? SharedPtr<Network>() : nw->second);
|
||||
}
|
||||
|
||||
private:
|
||||
RuntimeEnvironment *RR;
|
||||
|
||||
ZT1_WireMessage *_outputWireMessages;
|
||||
unsigned long _outputWireMessageCount;
|
||||
unsigned long _outputWireMessageCapacity;
|
||||
Mutex _outputWireMessages_m;
|
||||
|
||||
ZT1_VirtualNetworkFrame *_outputFrames;
|
||||
unsigned long _outputFrameCount;
|
||||
unsigned long _outputFrameCapacity;
|
||||
Mutex _outputFrames_m;
|
||||
|
||||
ZT1_DataStoreGetFunction *_dataStoreGetFunction,
|
||||
ZT1_DataStorePutFunction *_dataStorePutFunction,
|
||||
ZT1_VirtualPortConfigCallback *_portConfigCallback,
|
||||
ZT1_StatusCallback *_statusCallback);
|
||||
|
||||
//Dictionary _localConfig; // persisted as local.conf
|
||||
//Mutex _localConfig_m;
|
||||
|
||||
std::map< uint64_t,SharedPtr<Network> > _networks;
|
||||
Mutex _networks_m;
|
||||
|
||||
uint64_t _now; // time of last run()
|
||||
uint64_t _timeOfLastPacketReceived;
|
||||
uint64_t _timeOfLastPrivilgedPacket;
|
||||
unsigned int _spamCounter; // used to "spam" every Nth packet
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
@ -1,137 +0,0 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
||||
*
|
||||
* If you would like to embed ZeroTier into a commercial application or
|
||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
||||
* LLC. Start here: http://www.zerotier.com/
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include "Constants.hpp"
|
||||
|
||||
#include "NodeConfig.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Defaults.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Logger.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "SoftwareUpdater.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
NodeConfig::NodeConfig(const RuntimeEnvironment *renv) :
|
||||
RR(renv)
|
||||
{
|
||||
{
|
||||
Mutex::Lock _l(_localConfig_m);
|
||||
_readLocalConfig();
|
||||
}
|
||||
|
||||
std::string networksFolder(RR->homePath + ZT_PATH_SEPARATOR_S + "networks.d");
|
||||
std::map<std::string,bool> networksDotD(Utils::listDirectory(networksFolder.c_str()));
|
||||
std::vector<uint64_t> configuredNets;
|
||||
for(std::map<std::string,bool>::iterator d(networksDotD.begin());d!=networksDotD.end();++d) {
|
||||
if (!d->second) {
|
||||
std::string::size_type dot = d->first.rfind(".conf");
|
||||
if (dot != std::string::npos) {
|
||||
uint64_t nwid = Utils::hexStrToU64(d->first.substr(0,dot).c_str());
|
||||
if ((nwid > 0)&&(std::find(configuredNets.begin(),configuredNets.end(),nwid) == configuredNets.end()))
|
||||
configuredNets.push_back(nwid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(std::vector<uint64_t>::iterator n(configuredNets.begin());n!=configuredNets.end();++n) {
|
||||
try {
|
||||
_networks[*n] = Network::newInstance(RR,this,*n);
|
||||
} catch (std::exception &exc) {
|
||||
LOG("unable to create network %.16llx: %s",(unsigned long long)*n,exc.what());
|
||||
} catch ( ... ) {
|
||||
LOG("unable to create network %.16llx: (unknown exception)",(unsigned long long)*n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NodeConfig::~NodeConfig()
|
||||
{
|
||||
_writeLocalConfig();
|
||||
}
|
||||
|
||||
void NodeConfig::putLocalConfig(const std::string &key,const char *value)
|
||||
{
|
||||
Mutex::Lock _l(_localConfig_m);
|
||||
_localConfig[key] = value;
|
||||
_writeLocalConfig();
|
||||
}
|
||||
|
||||
void NodeConfig::putLocalConfig(const std::string &key,const std::string &value)
|
||||
{
|
||||
Mutex::Lock _l(_localConfig_m);
|
||||
_localConfig[key] = value;
|
||||
_writeLocalConfig();
|
||||
}
|
||||
|
||||
std::string NodeConfig::getLocalConfig(const std::string &key) const
|
||||
{
|
||||
Mutex::Lock _l(_localConfig_m);
|
||||
Dictionary::const_iterator i(_localConfig.find(key));
|
||||
if (i == _localConfig.end())
|
||||
return std::string();
|
||||
return i->second;
|
||||
}
|
||||
|
||||
void NodeConfig::clean()
|
||||
{
|
||||
Mutex::Lock _l(_networks_m);
|
||||
for(std::map< uint64_t,SharedPtr<Network> >::const_iterator n(_networks.begin());n!=_networks.end();++n)
|
||||
n->second->clean();
|
||||
}
|
||||
|
||||
void NodeConfig::_readLocalConfig()
|
||||
{
|
||||
// assumes _localConfig_m is locked
|
||||
std::string localDotConf(RR->homePath + ZT_PATH_SEPARATOR_S + "local.conf");
|
||||
std::string buf;
|
||||
if (Utils::readFile(localDotConf.c_str(),buf))
|
||||
_localConfig.fromString(buf.c_str());
|
||||
}
|
||||
|
||||
void NodeConfig::_writeLocalConfig()
|
||||
{
|
||||
// assumes _localConfig_m is locked
|
||||
Utils::writeFile(((RR->homePath + ZT_PATH_SEPARATOR_S + "local.conf")).c_str(),_localConfig.toString());
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
@ -1,181 +0,0 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere
|
||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
||||
*
|
||||
* If you would like to embed ZeroTier into a commercial application or
|
||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
||||
* LLC. Start here: http://www.zerotier.com/
|
||||
*/
|
||||
|
||||
#ifndef ZT_NODECONFIG_HPP
|
||||
#define ZT_NODECONFIG_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "SharedPtr.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Dictionary.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class RuntimeEnvironment;
|
||||
|
||||
/**
|
||||
* Node configuration endpoint
|
||||
*/
|
||||
class NodeConfig
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param renv Runtime environment
|
||||
* @throws std::runtime_error Unable to initialize or listen for IPC connections
|
||||
*/
|
||||
NodeConfig(const RuntimeEnvironment *renv);
|
||||
|
||||
~NodeConfig();
|
||||
|
||||
/**
|
||||
* Store something in local configuration cache
|
||||
*
|
||||
* By convention, keys starting with _ will not be shown in the command bus
|
||||
* local config functions.
|
||||
*
|
||||
* @param key Configuration key
|
||||
* @param value Configuration value
|
||||
*/
|
||||
void putLocalConfig(const std::string &key,const char *value);
|
||||
void putLocalConfig(const std::string &key,const std::string &value);
|
||||
|
||||
/**
|
||||
* @param key Configuration key
|
||||
* @return Value or empty string if not found
|
||||
*/
|
||||
std::string getLocalConfig(const std::string &key) const;
|
||||
|
||||
/**
|
||||
* @param nwid Network ID
|
||||
* @return Network or NULL if no network for that ID
|
||||
*/
|
||||
inline SharedPtr<Network> network(uint64_t nwid) const
|
||||
{
|
||||
Mutex::Lock _l(_networks_m);
|
||||
std::map< uint64_t,SharedPtr<Network> >::const_iterator n(_networks.find(nwid));
|
||||
return ((n == _networks.end()) ? SharedPtr<Network>() : n->second);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Vector containing all networks
|
||||
*/
|
||||
inline std::vector< SharedPtr<Network> > networks() const
|
||||
{
|
||||
std::vector< SharedPtr<Network> > nwlist;
|
||||
Mutex::Lock _l(_networks_m);
|
||||
for(std::map< uint64_t,SharedPtr<Network> >::const_iterator n(_networks.begin());n!=_networks.end();++n)
|
||||
nwlist.push_back(n->second);
|
||||
return nwlist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a network or return existing network if already joined
|
||||
*
|
||||
* @param nwid Network ID to join
|
||||
* @return New network instance
|
||||
*/
|
||||
inline SharedPtr<Network> join(uint64_t nwid)
|
||||
{
|
||||
Mutex::Lock _l(_networks_m);
|
||||
SharedPtr<Network> &nw = _networks[nwid];
|
||||
if (nw)
|
||||
return nw;
|
||||
else return (nw = Network::newInstance(RR,this,nwid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Leave a network
|
||||
*
|
||||
* @param nwid Network ID
|
||||
* @return True if network was left, false if we were not a member of this network
|
||||
*/
|
||||
inline bool leave(uint64_t nwid)
|
||||
{
|
||||
Mutex::Lock _l(_networks_m);
|
||||
std::map< uint64_t,SharedPtr<Network> >::iterator n(_networks.find(nwid));
|
||||
if (n != _networks.end()) {
|
||||
n->second->destroy();
|
||||
_networks.erase(n);
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform cleanup and possibly persist saved state
|
||||
*/
|
||||
void clean();
|
||||
|
||||
/**
|
||||
* @param nwid Network ID
|
||||
* @return True if this network exists
|
||||
*/
|
||||
inline bool hasNetwork(uint64_t nwid)
|
||||
{
|
||||
Mutex::Lock _l(_networks_m);
|
||||
return (_networks.find(nwid) != _networks.end());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Sorted vector of network tap device names from our virtual networks (not other taps on system)
|
||||
*/
|
||||
inline std::vector<std::string> networkTapDeviceNames() const
|
||||
{
|
||||
std::vector<std::string> tapDevs;
|
||||
Mutex::Lock _l(_networks_m);
|
||||
for(std::map< uint64_t,SharedPtr<Network> >::const_iterator n(_networks.begin());n!=_networks.end();++n) {
|
||||
std::string dn(n->second->tapDeviceName());
|
||||
if (dn.length())
|
||||
tapDevs.push_back(dn);
|
||||
}
|
||||
return tapDevs;
|
||||
}
|
||||
|
||||
private:
|
||||
void _readLocalConfig();
|
||||
void _writeLocalConfig();
|
||||
|
||||
const RuntimeEnvironment *RR;
|
||||
|
||||
Dictionary _localConfig; // persisted as local.conf
|
||||
Mutex _localConfig_m;
|
||||
|
||||
std::map< uint64_t,SharedPtr<Network> > _networks; // persisted in networks.d/
|
||||
Mutex _networks_m;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
@ -41,12 +41,8 @@ class Switch;
|
||||
class Topology;
|
||||
class CMWC4096;
|
||||
class Node;
|
||||
class SoftwareUpdater;
|
||||
class SocketManager;
|
||||
class Multicaster;
|
||||
class AntiRecursion;
|
||||
class EthernetTapFactory;
|
||||
class HttpClient;
|
||||
class NetworkConfigMaster;
|
||||
|
||||
/**
|
||||
@ -65,50 +61,23 @@ class RuntimeEnvironment
|
||||
{
|
||||
public:
|
||||
RuntimeEnvironment() :
|
||||
homePath(),
|
||||
identity(),
|
||||
initialized(false),
|
||||
tcpTunnelingEnabled(false),
|
||||
timeOfLastResynchronize(0),
|
||||
timeOfLastPacketReceived(0),
|
||||
tapFactory((EthernetTapFactory *)0),
|
||||
sm((SocketManager *)0),
|
||||
netconfMaster((NetworkConfigMaster *)0),
|
||||
log((Logger *)0),
|
||||
prng((CMWC4096 *)0),
|
||||
http((HttpClient *)0),
|
||||
sw((Switch *)0),
|
||||
mc((Multicaster *)0),
|
||||
antiRec((AntiRecursion *)0),
|
||||
topology((Topology *)0),
|
||||
nc((NodeConfig *)0),
|
||||
node((Node *)0),
|
||||
updater((SoftwareUpdater *)0)
|
||||
node((Node *)0)
|
||||
{
|
||||
}
|
||||
|
||||
// Full path to home folder
|
||||
std::string homePath;
|
||||
|
||||
// This node's identity
|
||||
Identity identity;
|
||||
|
||||
// Are we initialized?
|
||||
volatile bool initialized;
|
||||
|
||||
// Are we in outgoing TCP failover mode?
|
||||
volatile bool tcpTunnelingEnabled;
|
||||
|
||||
// Time network environment (e.g. fingerprint) last changed -- used to determine online-ness
|
||||
volatile uint64_t timeOfLastResynchronize;
|
||||
|
||||
// Time last packet was received -- from anywhere. This is updated in Peer::receive()
|
||||
// via an ugly const_cast<>.
|
||||
volatile uint64_t timeOfLastPacketReceived;
|
||||
|
||||
// These are passed in from outside and are not created or deleted by the ZeroTier node core
|
||||
EthernetTapFactory *tapFactory;
|
||||
SocketManager *sm;
|
||||
// This is set externally to an instance of this base class if netconf functionality is enabled
|
||||
NetworkConfigMaster *netconfMaster;
|
||||
|
||||
/*
|
||||
@ -121,14 +90,12 @@ public:
|
||||
|
||||
Logger *log; // null if logging is disabled
|
||||
CMWC4096 *prng;
|
||||
HttpClient *http;
|
||||
Switch *sw;
|
||||
Multicaster *mc;
|
||||
AntiRecursion *antiRec;
|
||||
Topology *topology;
|
||||
NodeConfig *nc;
|
||||
Node *node;
|
||||
SoftwareUpdater *updater; // null if software updates are not enabled
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
@ -15,7 +15,6 @@ OBJS=\
|
||||
node/Network.o \
|
||||
node/NetworkConfig.o \
|
||||
node/Node.o \
|
||||
node/NodeConfig.o \
|
||||
node/OutboundMulticast.o \
|
||||
node/Packet.o \
|
||||
node/Peer.o \
|
||||
|
@ -38,6 +38,28 @@
|
||||
#include "Defaults.hpp"
|
||||
#include "Address.hpp"
|
||||
|
||||
/**
|
||||
* Delay between fetches of the root topology update URL
|
||||
*
|
||||
* 86400000 = check once every 24 hours (this doesn't change often)
|
||||
*/
|
||||
#define ZT_UPDATE_ROOT_TOPOLOGY_CHECK_INTERVAL 86400000
|
||||
|
||||
/**
|
||||
* Minimum interval between attempts to do a software update
|
||||
*/
|
||||
#define ZT_UPDATE_MIN_INTERVAL 120000
|
||||
|
||||
/**
|
||||
* Maximum interval between checks for new versions
|
||||
*/
|
||||
#define ZT_UPDATE_MAX_INTERVAL 7200000
|
||||
|
||||
/**
|
||||
* Software update HTTP timeout in seconds
|
||||
*/
|
||||
#define ZT_UPDATE_HTTP_TIMEOUT 120
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class RuntimeEnvironment;
|
||||
|
Loading…
x
Reference in New Issue
Block a user