Plumbing for local interface addresses -- GitHub issue #180

This commit is contained in:
Adam Ierymenko 2015-07-06 15:51:04 -07:00
parent 79e9a8bcc2
commit 235f4762b7
5 changed files with 84 additions and 18 deletions

View file

@ -628,6 +628,15 @@ typedef struct
unsigned long peerCount; unsigned long peerCount;
} ZT1_PeerList; } ZT1_PeerList;
/**
* Local interface trust levels
*/
typedef enum {
ZT1_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL = 0,
ZT1_LOCAL_INTERFACE_ADDRESS_TRUST_PRIVACY = 1,
ZT1_LOCAL_INTERFACE_ADDRESS_TRUST_ULTIMATE = 2
} ZT1_LocalInterfaceAddressTrust;
/** /**
* An instance of a ZeroTier One node (opaque) * An instance of a ZeroTier One node (opaque)
*/ */
@ -958,6 +967,29 @@ ZT1_VirtualNetworkList *ZT1_Node_networks(ZT1_Node *node);
*/ */
void ZT1_Node_freeQueryResult(ZT1_Node *node,void *qr); void ZT1_Node_freeQueryResult(ZT1_Node *node,void *qr);
/**
* Add a local interface address
*
* Local interface addresses may be added if you want remote peers
* with whom you have a trust relatinship (e.g. common network membership)
* to receive information about these endpoints as potential endpoints for
* direct communication.
*
* Take care that these are never ZeroTier interface addresses, otherwise
* strange things might happen or they simply won't work.
*
* @param addr Local interface address
* @param metric Local interface metric
* @param trust How much do you trust the local network under this interface?
* @param reliable If nonzero, this interface doesn't link to anything behind a NAT or stateful firewall
*/
void ZT1_Node_addLocalInterfaceAddress(ZT1_Node *node,const struct sockaddr_storage *addr,int metric,ZT1_LocalInterfaceAddressTrust trust,int reliable);
/**
* Clear local interface addresses
*/
void ZT1_Node_clearLocalInterfaceAddresses(ZT1_Node *node);
/** /**
* Set a network configuration master instance for this node * Set a network configuration master instance for this node
* *

View file

@ -426,6 +426,20 @@ void Node::freeQueryResult(void *qr)
::free(qr); ::free(qr);
} }
void Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr,int metric,ZT1_LocalInterfaceAddressTrust trust,int reliable)
{
Mutex::Lock _l(_directPaths_m);
_directPaths.push_back(Path(*(reinterpret_cast<const InetAddress *>(addr)),metric,(Path::Trust)trust,reliable != 0));
std::sort(_directPaths.begin(),_directPaths.end());
_directPaths.erase(std::unique(_directPaths.begin(),_directPaths.end()),_directPaths.end());
}
void Node::clearLocalInterfaceAddresses()
{
Mutex::Lock _l(_directPaths_m);
_directPaths.clear();
}
void Node::setNetconfMaster(void *networkControllerInstance) void Node::setNetconfMaster(void *networkControllerInstance)
{ {
RR->localNetworkController = reinterpret_cast<NetworkController *>(networkControllerInstance); RR->localNetworkController = reinterpret_cast<NetworkController *>(networkControllerInstance);
@ -679,6 +693,20 @@ void ZT1_Node_setNetconfMaster(ZT1_Node *node,void *networkControllerInstance)
} catch ( ... ) {} } catch ( ... ) {}
} }
void ZT1_Node_addLocalInterfaceAddress(ZT1_Node *node,const struct sockaddr_storage *addr,int metric,ZT1_LocalInterfaceAddressTrust trust,int reliable)
{
try {
reinterpret_cast<ZeroTier::Node *>(node)->addLocalInterfaceAddress(addr,metric,trust,reliable);
} catch ( ... ) {}
}
void ZT1_Node_clearLocalInterfaceAddresses(ZT1_Node *node)
{
try {
reinterpret_cast<ZeroTier::Node *>(node)->clearLocalInterfaceAddresses();
} catch ( ... ) {}
}
void ZT1_version(int *major,int *minor,int *revision,unsigned long *featureFlags) void ZT1_version(int *major,int *minor,int *revision,unsigned long *featureFlags)
{ {
if (major) *major = ZEROTIER_ONE_VERSION_MAJOR; if (major) *major = ZEROTIER_ONE_VERSION_MAJOR;

View file

@ -104,6 +104,8 @@ public:
ZT1_VirtualNetworkConfig *networkConfig(uint64_t nwid) const; ZT1_VirtualNetworkConfig *networkConfig(uint64_t nwid) const;
ZT1_VirtualNetworkList *networks() const; ZT1_VirtualNetworkList *networks() const;
void freeQueryResult(void *qr); void freeQueryResult(void *qr);
void addLocalInterfaceAddress(const struct sockaddr_storage *addr,int metric,ZT1_LocalInterfaceAddressTrust trust,int reliable);
void clearLocalInterfaceAddresses();
void setNetconfMaster(void *networkControllerInstance); void setNetconfMaster(void *networkControllerInstance);
// Internal functions ------------------------------------------------------ // Internal functions ------------------------------------------------------
@ -172,6 +174,9 @@ public:
return nw; return nw;
} }
/**
* @return Potential direct paths to me a.k.a. local interface addresses
*/
inline std::vector<Path> directPaths() const inline std::vector<Path> directPaths() const
{ {
Mutex::Lock _l(_directPaths_m); Mutex::Lock _l(_directPaths_m);

View file

@ -37,28 +37,27 @@ namespace ZeroTier {
class Path class Path
{ {
public: public:
// Must be the same values as ZT1_LocalInterfaceAddressTrust in ZeroTierOne.h
enum Trust enum Trust
{ {
TRUST_NORMAL, TRUST_NORMAL = 0,
TRUST_PRIVACY, TRUST_PRIVACY = 1,
TRUST_ULTIMATE TRUST_ULTIMATE = 2
}; };
Path() : Path() :
_addr(), _addr(),
_metric(0), _metric(0),
_trust(TRUST_NORMAL), _trust(TRUST_NORMAL),
_reliable(false), _reliable(false)
_fixed(false)
{ {
} }
Path(const InetAddress &addr,int metric,Trust trust,bool reliable,bool fixed) : Path(const InetAddress &addr,int metric,Trust trust,bool reliable) :
_addr(addr), _addr(addr),
_metric(metric), _metric(metric),
_trust(trust), _trust(trust),
_reliable(reliable), _reliable(reliable)
_fixed(fixed)
{ {
} }
@ -82,11 +81,6 @@ public:
*/ */
inline bool reliable() const throw() { return _reliable; } inline bool reliable() const throw() { return _reliable; }
/**
* @return Is this a fixed path?
*/
inline bool fixed() const throw() { return _fixed; }
/** /**
* @return True if address is non-NULL * @return True if address is non-NULL
*/ */
@ -105,7 +99,6 @@ protected:
int _metric; // negative == blacklisted int _metric; // negative == blacklisted
Trust _trust; Trust _trust;
bool _reliable; bool _reliable;
bool _fixed;
}; };
} // namespace ZeroTier } // namespace ZeroTier

View file

@ -52,18 +52,25 @@ public:
RemotePath() : RemotePath() :
Path(), Path(),
_lastSend(0), _lastSend(0),
_lastReceived(0) {} _lastReceived(0),
_fixed(false) {}
RemotePath(const InetAddress &addr,bool fixed) : RemotePath(const InetAddress &addr,bool fixed) :
Path(addr,0,TRUST_NORMAL,false,fixed), Path(addr,0,TRUST_NORMAL,false),
_lastSend(0), _lastSend(0),
_lastReceived(0) {} _lastReceived(0),
_fixed(fixed) {}
inline uint64_t lastSend() const throw() { return _lastSend; } inline uint64_t lastSend() const throw() { return _lastSend; }
inline uint64_t lastReceived() const throw() { return _lastReceived; } inline uint64_t lastReceived() const throw() { return _lastReceived; }
/** /**
* @param f New value of parent 'fixed' field * @return Is this a fixed path?
*/
inline bool fixed() const throw() { return _fixed; }
/**
* @param f New value of fixed flag
*/ */
inline void setFixed(const bool f) inline void setFixed(const bool f)
throw() throw()
@ -127,6 +134,7 @@ public:
private: private:
uint64_t _lastSend; uint64_t _lastSend;
uint64_t _lastReceived; uint64_t _lastReceived;
bool _fixed;
}; };
} // namespace ZeroTier } // namespace ZeroTier