mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-20 17:00:49 +00:00
getting there...
This commit is contained in:
parent
5e35346f17
commit
2eef9d22e6
@ -1458,20 +1458,6 @@ public:
|
||||
const InetAddress *const target = reinterpret_cast<const InetAddress *>(&(n.config.routes[i].target));
|
||||
const InetAddress *const via = reinterpret_cast<const InetAddress *>(&(n.config.routes[i].via));
|
||||
|
||||
const InetAddress *src = NULL;
|
||||
for (unsigned int j=0; j<n.config.assignedAddressCount; ++j) {
|
||||
const InetAddress *const tmp = reinterpret_cast<const InetAddress *>(&(n.config.assignedAddresses[j]));
|
||||
if (target->isV4() && tmp->isV4()) {
|
||||
src = reinterpret_cast<InetAddress *>(&(n.config.assignedAddresses[j]));
|
||||
break;
|
||||
} else if (target->isV6() && tmp->isV6()) {
|
||||
src = reinterpret_cast<InetAddress *>(&(n.config.assignedAddresses[j]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!src)
|
||||
src = &InetAddress::NIL;
|
||||
|
||||
if ( (!checkIfManagedIsAllowed(n,*target)) || ((via->ss_family == target->ss_family)&&(matchIpOnly(myIps,*via))) )
|
||||
continue;
|
||||
|
||||
@ -1501,7 +1487,7 @@ public:
|
||||
continue;
|
||||
|
||||
// Add and apply new routes
|
||||
n.managedRoutes.push_back(SharedPtr<ManagedRoute>(new ManagedRoute(*target,*via,*src,tapdev)));
|
||||
n.managedRoutes.push_back(SharedPtr<ManagedRoute>(new ManagedRoute(*target,*via,tapdev)));
|
||||
if (!n.managedRoutes.back()->sync())
|
||||
n.managedRoutes.pop_back();
|
||||
#endif
|
||||
|
@ -661,3 +661,52 @@ extern "C" void ZT_GoTap_setMtu(ZT_GoTap *tap,unsigned int mtu)
|
||||
{
|
||||
reinterpret_cast<EthernetTap *>(tap)->setMtu(mtu);
|
||||
}
|
||||
|
||||
extern "C" int ZT_GoTap_addRoute(ZT_GoTap *tap,int targetAf,const void *targetIp,int targetNetmaskBits,int viaAf,const void *viaIp,unsigned int metric)
|
||||
{
|
||||
InetAddress target,via;
|
||||
switch(targetAf) {
|
||||
case AF_INET:
|
||||
target.set(targetIp,4,(unsigned int)targetNetmaskBits);
|
||||
break;
|
||||
case AF_INET6:
|
||||
target.set(targetIp,16,(unsigned int)targetNetmaskBits);
|
||||
break;
|
||||
}
|
||||
switch(viaAf) {
|
||||
case AF_INET:
|
||||
via.set(viaIp,4,0);
|
||||
break;
|
||||
case AF_INET6:
|
||||
via.set(viaIp,16,0);
|
||||
break;
|
||||
}
|
||||
return reinterpret_cast<EthernetTap *>(tap)->addRoute(target,via,metric);
|
||||
}
|
||||
|
||||
extern "C" int ZT_GoTap_removeRoute(ZT_GoTap *tap,int targetAf,const void *targetIp,int targetNetmaskBits,int viaAf,const void *viaIp,unsigned int metric)
|
||||
{
|
||||
InetAddress target,via;
|
||||
switch(targetAf) {
|
||||
case AF_INET:
|
||||
target.set(targetIp,4,(unsigned int)targetNetmaskBits);
|
||||
break;
|
||||
case AF_INET6:
|
||||
target.set(targetIp,16,(unsigned int)targetNetmaskBits);
|
||||
break;
|
||||
}
|
||||
switch(viaAf) {
|
||||
case AF_INET:
|
||||
via.set(viaIp,4,0);
|
||||
break;
|
||||
case AF_INET6:
|
||||
via.set(viaIp,16,0);
|
||||
break;
|
||||
}
|
||||
return reinterpret_cast<EthernetTap *>(tap)->removeRoute(target,via,metric);
|
||||
}
|
||||
|
||||
extern "C" int ZT_GoTap_syncRoutes(ZT_GoTap *tap)
|
||||
{
|
||||
return reinterpret_cast<EthernetTap *>(tap)->syncRoutes();
|
||||
}
|
||||
|
@ -91,6 +91,12 @@ void ZT_GoTap_setFriendlyName(ZT_GoTap *tap,const char *friendlyName);
|
||||
|
||||
void ZT_GoTap_setMtu(ZT_GoTap *tap,unsigned int mtu);
|
||||
|
||||
int ZT_GoTap_addRoute(ZT_GoTap *tap,int targetAf,const void *targetIp,int targetNetmaskBits,int viaAf,const void *viaIp,unsigned int metric);
|
||||
|
||||
int ZT_GoTap_removeRoute(ZT_GoTap *tap,int targetAf,const void *targetIp,int targetNetmaskBits,int viaAf,const void *viaIp,unsigned int metric);
|
||||
|
||||
int ZT_GoTap_syncRoutes(ZT_GoTap *tap);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -15,10 +15,22 @@ package zerotier
|
||||
|
||||
import (
|
||||
"encoding/base32"
|
||||
"net"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var base32StdLowerCase = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567")
|
||||
|
||||
// TimeMs returns the time in milliseconds since epoch.
|
||||
func TimeMs() int64 { return int64(time.Now().UnixNano()) / int64(1000000) }
|
||||
|
||||
// ipNetToKey creates a key that can be used in a map[] from a net.IPNet
|
||||
func ipNetToKey(ipn *net.IPNet) (k [3]uint64) {
|
||||
if len(ipn.IP) > 0 {
|
||||
copy(((*[16]byte)(unsafe.Pointer(&k[0])))[:], ipn.IP)
|
||||
}
|
||||
ones, bits := ipn.Mask.Size()
|
||||
k[2] = (uint64(ones) << 32) | uint64(bits)
|
||||
return
|
||||
}
|
||||
|
@ -116,3 +116,36 @@ func (n *Network) Tap() Tap {
|
||||
defer n.tapLock.RUnlock()
|
||||
return n.tap
|
||||
}
|
||||
|
||||
func (n *Network) handleNetworkConfigUpdate(nc *NetworkConfig) {
|
||||
n.tapLock.RLock()
|
||||
n.configLock.Lock()
|
||||
defer n.configLock.Unlock()
|
||||
defer n.tapLock.RUnlock()
|
||||
|
||||
if n.tap == nil { // sanity check
|
||||
return
|
||||
}
|
||||
|
||||
// Add IPs to tap that are newly assigned in this config update,
|
||||
// and remove any IPs from the tap that were assigned that are no
|
||||
// longer wanted. IPs assigned to the tap externally (e.g. by an
|
||||
// "ifconfig" command) are left alone.
|
||||
haveAssignedIPs := make(map[[3]uint64]*net.IPNet)
|
||||
for _, ip := range n.config.AssignedAddresses {
|
||||
haveAssignedIPs[ipNetToKey(&ip)] = &ip
|
||||
}
|
||||
wantAssignedIPs := make(map[[3]uint64]bool)
|
||||
for _, ip := range nc.AssignedAddresses {
|
||||
k := ipNetToKey(&ip)
|
||||
wantAssignedIPs[k] = true
|
||||
if _, have := haveAssignedIPs[k]; !have {
|
||||
n.tap.AddIP(&ip)
|
||||
}
|
||||
}
|
||||
for k, ip := range haveAssignedIPs {
|
||||
if _, want := wantAssignedIPs[k]; !want {
|
||||
n.tap.RemoveIP(ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ package zerotier
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@ -28,7 +29,6 @@ import (
|
||||
"path"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
acl "github.com/hectane/go-acl"
|
||||
@ -139,10 +139,8 @@ func (n *Node) Join(nwid uint64, tap Tap) (*Network, error) {
|
||||
nw := &Network{
|
||||
id: NetworkID(nwid),
|
||||
config: NetworkConfig{
|
||||
ID: NetworkID(nwid),
|
||||
Status: NetworkStatusRequestConfiguration,
|
||||
LastUpdated: time.Now(),
|
||||
Enabled: true,
|
||||
ID: NetworkID(nwid),
|
||||
Status: NetworkStatusRequestConfiguration,
|
||||
},
|
||||
tap: &nativeTap{tap: unsafe.Pointer(ntap), enabled: 1},
|
||||
}
|
||||
@ -347,20 +345,74 @@ func goDNSResolverFunc(gn unsafe.Pointer, dnsRecordTypes unsafe.Pointer, numDNSR
|
||||
}()
|
||||
}
|
||||
|
||||
func sockaddrStorageToIPNet(ss *C.struct_sockaddr_storage) *net.IPNet {
|
||||
var a net.IPNet
|
||||
switch ss.ss_family {
|
||||
case afInet:
|
||||
sa4 := (*C.struct_sockaddr_in)(unsafe.Pointer(ss))
|
||||
var ip4 [4]byte
|
||||
copy(ip4[:], (*[4]byte)(unsafe.Pointer(&sa4.sin_addr))[:])
|
||||
a.IP = net.IP(ip4[:])
|
||||
a.Mask = net.CIDRMask(int(binary.BigEndian.Uint16(((*[2]byte)(unsafe.Pointer(&sa4.sin_port)))[:])), 32)
|
||||
return &a
|
||||
case afInet6:
|
||||
sa6 := (*C.struct_sockaddr_in6)(unsafe.Pointer(ss))
|
||||
var ip6 [16]byte
|
||||
copy(ip6[:], (*[16]byte)(unsafe.Pointer(&sa6.sin6_addr))[:])
|
||||
a.IP = net.IP(ip6[:])
|
||||
a.Mask = net.CIDRMask(int(binary.BigEndian.Uint16(((*[2]byte)(unsafe.Pointer(&sa6.sin6_port)))[:])), 128)
|
||||
return &a
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//export goVirtualNetworkConfigFunc
|
||||
func goVirtualNetworkConfigFunc(gn, tapP unsafe.Pointer, nwid C.uint64_t, op C.int, conf unsafe.Pointer) {
|
||||
nodesByUserPtrLock.RLock()
|
||||
node := nodesByUserPtr[uintptr(gn)]
|
||||
nodesByUserPtrLock.RUnlock()
|
||||
if node == nil {
|
||||
return 255
|
||||
return
|
||||
}
|
||||
node.networksLock.RLock()
|
||||
network := node.networks[uint64(nwid)]
|
||||
node.networksLock.RUnlock()
|
||||
if network != nil {
|
||||
ncc := (*C.ZT_VirtualNetworkConfig)(conf)
|
||||
var nc NetworkConfig
|
||||
nc.ID = uint64(ncc.nwid)
|
||||
nc.MAC = MAC(ncc.mac)
|
||||
nc.Name = C.GoString(ncc.name)
|
||||
nc.Status = int(ncc.status)
|
||||
nc.Type = int(ncc._type)
|
||||
nc.MTU = int(ncc.mtu)
|
||||
nc.Bridge = (ncc.bridge != 0)
|
||||
nc.BroadcastEnabled = (ncc.broadcastEnabled != 0)
|
||||
nc.NetconfRevision = uint64(ncc.netconfRevision)
|
||||
for i := 0; i < int(ncc.assignedAddressCount); i++ {
|
||||
a := sockaddrStorageToIPNet(&ncc.assignedAddresses[i])
|
||||
if a != nil {
|
||||
nc.AssignedAddresses = append(nc.AssignedAddresses, *a)
|
||||
}
|
||||
}
|
||||
for i := 0; i < int(ncc.routeCount); i++ {
|
||||
tgt := sockaddrStorageToIPNet(&ncc.routes[i].target)
|
||||
viaN := sockaddrStorageToIPNet(&ncc.routes[i].via)
|
||||
var via net.IP
|
||||
if viaN != nil {
|
||||
via = viaN.IP
|
||||
}
|
||||
if tgt != nil {
|
||||
nc.Routes = append(nc.Routes, Route{
|
||||
Target: *tgt,
|
||||
Via: via,
|
||||
Flags: uint16(ncc.routes[i].flags),
|
||||
Metric: uint16(ncc.routes[i].metric),
|
||||
})
|
||||
}
|
||||
}
|
||||
network.handleNetworkConfigUpdate(&nc)
|
||||
}
|
||||
//return C.int(node.handleNetworkConfigUpdate(uint64(nwid), int(op), (*C.ZT_VirtualNetworkConfig)(conf)))
|
||||
}
|
||||
|
||||
//export goZtEvent
|
||||
@ -461,7 +513,7 @@ func (t *nativeTap) Enabled() bool {
|
||||
}
|
||||
|
||||
// AddIP adds an IP address (with netmask) to this tap
|
||||
func (t *nativeTap) AddIP(ip net.IPNet) error {
|
||||
func (t *nativeTap) AddIP(ip *net.IPNet) error {
|
||||
bits, _ := ip.Mask.Size()
|
||||
if len(ip.IP) == 16 {
|
||||
if bits > 128 || bits < 0 {
|
||||
@ -478,7 +530,7 @@ func (t *nativeTap) AddIP(ip net.IPNet) error {
|
||||
}
|
||||
|
||||
// RemoveIP removes this IP address (with netmask) from this tap
|
||||
func (t *nativeTap) RemoveIP(ip net.IPNet) error {
|
||||
func (t *nativeTap) RemoveIP(ip *net.IPNet) error {
|
||||
bits, _ := ip.Mask.Size()
|
||||
if len(ip.IP) == 16 {
|
||||
if bits > 128 || bits < 0 {
|
||||
@ -553,3 +605,61 @@ func (t *nativeTap) AddMulticastGroupChangeHandler(handler func(bool, *Multicast
|
||||
t.multicastGroupHandlers = append(t.multicastGroupHandlers, handler)
|
||||
t.multicastGroupHandlersLock.Unlock()
|
||||
}
|
||||
|
||||
// AddRoute adds or updates a managed route on this tap's interface
|
||||
func (t *nativeTap) AddRoute(r *Route) error {
|
||||
rc := 0
|
||||
if r != nil {
|
||||
if len(r.Target.IP) == 4 {
|
||||
mask, _ := r.Target.Mask.Size()
|
||||
if len(r.Via) == 4 {
|
||||
rc = int(C.ZT_GoTap_addRoute(t.tap, afInet, unsafe.Pointer(&r.Target.IP[0]), C.int(mask), afInet, unsafe.Pointer(&r.Via[0]), C.int(r.Metric)))
|
||||
} else {
|
||||
rc = int(C.ZT_GoTap_addRoute(t.tap, afInet, unsafe.Pointer(&r.Target.IP[0]), C.int(mask), 0, nil, C.int(r.Metric)))
|
||||
}
|
||||
} else if len(r.Target.IP) == 16 {
|
||||
mask, _ := r.Target.Mask.Size()
|
||||
if len(r.Via) == 4 {
|
||||
rc = int(C.ZT_GoTap_addRoute(t.tap, afInet6, unsafe.Pointer(&r.Target.IP[0]), C.int(mask), afInet6, unsafe.Pointer(&r.Via[0]), C.int(r.Metric)))
|
||||
} else {
|
||||
rc = int(C.ZT_GoTap_addRoute(t.tap, afInet6, unsafe.Pointer(&r.Target.IP[0]), C.int(mask), 0, nil, C.int(r.Metric)))
|
||||
}
|
||||
}
|
||||
}
|
||||
if rc != 0 {
|
||||
return fmt.Errorf("tap device error adding route: %d", rc)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveRoute removes a managed route on this tap's interface
|
||||
func (t *nativeTap) RemoveRoute(r *Route) error {
|
||||
rc := 0
|
||||
if r != nil {
|
||||
if len(r.Target.IP) == 4 {
|
||||
mask, _ := r.Target.Mask.Size()
|
||||
if len(r.Via) == 4 {
|
||||
rc = int(C.ZT_GoTap_removeRoute(t.tap, afInet, unsafe.Pointer(&r.Target.IP[0]), C.int(mask), afInet, unsafe.Pointer(&r.Via[0]), C.int(r.Metric)))
|
||||
} else {
|
||||
rc = int(C.ZT_GoTap_removeRoute(t.tap, afInet, unsafe.Pointer(&r.Target.IP[0]), C.int(mask), 0, nil, C.int(r.Metric)))
|
||||
}
|
||||
} else if len(r.Target.IP) == 16 {
|
||||
mask, _ := r.Target.Mask.Size()
|
||||
if len(r.Via) == 4 {
|
||||
rc = int(C.ZT_GoTap_removeRoute(t.tap, afInet6, unsafe.Pointer(&r.Target.IP[0]), C.int(mask), afInet6, unsafe.Pointer(&r.Via[0]), C.int(r.Metric)))
|
||||
} else {
|
||||
rc = int(C.ZT_GoTap_removeRoute(t.tap, afInet6, unsafe.Pointer(&r.Target.IP[0]), C.int(mask), 0, nil, C.int(r.Metric)))
|
||||
}
|
||||
}
|
||||
}
|
||||
if rc != 0 {
|
||||
return fmt.Errorf("tap device error removing route: %d", rc)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SyncRoutes synchronizes managed routes
|
||||
func (t *nativeTap) SyncRoutes() error {
|
||||
C.ZT_GoTap_syncRoutes(t.tap)
|
||||
return nil
|
||||
}
|
||||
|
@ -23,6 +23,9 @@ type Route struct {
|
||||
// Via is how to reach this target (null/empty if the target IP range is local to this virtual LAN)
|
||||
Via net.IP
|
||||
|
||||
// Route flags (currently unused, always 0)
|
||||
Flags uint16
|
||||
|
||||
// Metric is an interface metric that can affect route priority (behavior can be OS-specific)
|
||||
Metric int
|
||||
Metric uint16
|
||||
}
|
||||
|
@ -21,9 +21,12 @@ type Tap interface {
|
||||
Error() (int, string)
|
||||
SetEnabled(enabled bool)
|
||||
Enabled() bool
|
||||
AddIP(ip net.IPNet) error
|
||||
RemoveIP(ip net.IPNet) error
|
||||
AddIP(ip *net.IPNet) error
|
||||
RemoveIP(ip *net.IPNet) error
|
||||
IPs() ([]net.IPNet, error)
|
||||
DeviceName() string
|
||||
AddMulticastGroupChangeHandler(func(bool, *MulticastGroup))
|
||||
AddRoute(r *Route) error
|
||||
RemoveRoute(r *Route) error
|
||||
SyncRoutes() error
|
||||
}
|
||||
|
@ -128,4 +128,15 @@ bool EthernetTap::addIps(std::vector<InetAddress> ips)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string EthernetTap::routingDeviceName() const
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
char tapdev[64];
|
||||
OSUtils::ztsnprintf(tapdev,sizeof(tapdev),"%.16llx",(unsigned long long)(((const WindowsEthernetTap *)(this))->luid().Value));
|
||||
return std::string(tapdev);
|
||||
#else
|
||||
return this->deviceName();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
@ -18,10 +18,13 @@
|
||||
#include "../node/MAC.hpp"
|
||||
#include "../node/InetAddress.hpp"
|
||||
#include "../node/MulticastGroup.hpp"
|
||||
#include "ManagedRoute.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <map>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
@ -50,9 +53,37 @@ public:
|
||||
virtual std::vector<InetAddress> ips() const = 0;
|
||||
virtual void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) = 0;
|
||||
virtual std::string deviceName() const = 0;
|
||||
virtual std::string routingDeviceName() const;
|
||||
virtual void setFriendlyName(const char *friendlyName) = 0;
|
||||
virtual void scanMulticastGroups(std::vector<MulticastGroup> &added,std::vector<MulticastGroup> &removed) = 0;
|
||||
virtual void setMtu(unsigned int mtu) = 0;
|
||||
|
||||
ZT_ALWAYS_INLINE int addRoute(const InetAddress &target,const InetAddress &via,const unsigned int metric)
|
||||
{
|
||||
const std::string dn(this->routingDeviceName());
|
||||
const char *const dnp = (dn.length() > 0) ? dn.c_str() : (const char *)0;
|
||||
std::lock_guard<std::mutex> l(_managedRoutes_l);
|
||||
_managedRoutes[std::pair<InetAddress,unsigned int>(target,metric)] = std::shared_ptr<ManagedRoute>(new ManagedRoute(target,via,dnp));
|
||||
}
|
||||
|
||||
ZT_ALWAYS_INLINE int removeRoute(const InetAddress &target,const InetAddress &via,const unsigned int metric)
|
||||
{
|
||||
std::lock_guard<std::mutex> l(_managedRoutes_l);
|
||||
_managedRoutes.erase(std::pair<InetAddress,unsigned int>(target,metric));
|
||||
}
|
||||
|
||||
ZT_ALWAYS_INLINE int syncRoutes()
|
||||
{
|
||||
std::lock_guard<std::mutex> l(_managedRoutes_l);
|
||||
for(auto r=_managedRoutes.begin();r!=_managedRoutes.end();++r) {
|
||||
r->second->sync();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
std::map< std::pair<InetAddress,unsigned int>,std::shared_ptr<ManagedRoute> > _managedRoutes;
|
||||
std::mutex _managedRoutes_l;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
@ -36,28 +36,19 @@ class ManagedRoute
|
||||
friend class SharedPtr<ManagedRoute>;
|
||||
|
||||
public:
|
||||
ManagedRoute(const InetAddress &target,const InetAddress &via,const InetAddress &src,const char *device)
|
||||
ZT_ALWAYS_INLINE ManagedRoute(const InetAddress &target,const InetAddress &via,const char *device)
|
||||
{
|
||||
_target = target;
|
||||
_via = via;
|
||||
_src = src;
|
||||
if (via.ss_family == AF_INET)
|
||||
_via.setPort(32);
|
||||
else if (via.ss_family == AF_INET6)
|
||||
_via.setPort(128);
|
||||
if (src.ss_family == AF_INET) {
|
||||
_src.setPort(32);
|
||||
} else if (src.ss_family == AF_INET6) {
|
||||
_src.setPort(128);
|
||||
}
|
||||
Utils::scopy(_device,sizeof(_device),device);
|
||||
_systemDevice[0] = (char)0;
|
||||
}
|
||||
|
||||
~ManagedRoute()
|
||||
{
|
||||
this->remove();
|
||||
}
|
||||
ZT_ALWAYS_INLINE ~ManagedRoute() { this->remove(); }
|
||||
|
||||
/**
|
||||
* Set or update currently set route
|
||||
@ -78,18 +69,16 @@ public:
|
||||
*/
|
||||
void remove();
|
||||
|
||||
inline const InetAddress &target() const { return _target; }
|
||||
inline const InetAddress &via() const { return _via; }
|
||||
inline const InetAddress &src() const { return _src; }
|
||||
inline const char *device() const { return _device; }
|
||||
ZT_ALWAYS_INLINE const InetAddress &target() const { return _target; }
|
||||
ZT_ALWAYS_INLINE const InetAddress &via() const { return _via; }
|
||||
ZT_ALWAYS_INLINE const char *device() const { return _device; }
|
||||
|
||||
private:
|
||||
ManagedRoute(const ManagedRoute &) {}
|
||||
inline ManagedRoute &operator=(const ManagedRoute &) { return *this; }
|
||||
ZT_ALWAYS_INLINE ManagedRoute(const ManagedRoute &) {}
|
||||
ZT_ALWAYS_INLINE ManagedRoute &operator=(const ManagedRoute &) { return *this; }
|
||||
|
||||
InetAddress _target;
|
||||
InetAddress _via;
|
||||
InetAddress _src;
|
||||
InetAddress _systemVia; // for route overrides
|
||||
std::map<InetAddress,bool> _applied; // routes currently applied
|
||||
char _device[128];
|
||||
|
Loading…
x
Reference in New Issue
Block a user