Rooting around

This commit is contained in:
Adam Ierymenko 2019-09-21 22:54:58 -07:00
parent bcb9df9cdf
commit 3341c4a670
No known key found for this signature in database
GPG Key ID: C8877CF2D7A5D7F3
2 changed files with 164 additions and 23 deletions

View File

@ -58,8 +58,8 @@ const (
// CoreVersionBuild is the build version of the ZeroTier core
CoreVersionBuild int = C.ZEROTIER_ONE_VERSION_BUILD
afInet int = C.AF_INET
afInet6 int = C.AF_INET6
afInet = C.AF_INET
afInet6 = C.AF_INET6
)
var (
@ -67,6 +67,67 @@ var (
nodesByUserPtrLock sync.RWMutex
)
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
}
func sockaddrStorageToUDPAddr(ss *C.struct_sockaddr_storage) *net.UDPAddr {
var a net.UDPAddr
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.Port = int(binary.BigEndian.Uint16(((*[2]byte)(unsafe.Pointer(&sa4.sin_port)))[:]))
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.Port = int(binary.BigEndian.Uint16(((*[2]byte)(unsafe.Pointer(&sa6.sin6_port)))[:]))
return &a
}
return nil
}
func makeSockaddrStorage(ip net.IP, port int, ss *C.struct_sockaddr_storage) bool {
C.memset(unsafe.Pointer(ss), 0, C.sizeof_struct_sockaddr_storage)
if len(ip) == 4 {
sa4 := (*C.struct_sockaddr_in)(unsafe.Pointer(ss))
sa4.sin_family = afInet
copy(((*[4]byte)(unsafe.Pointer(&sa4.sin_addr)))[:], ip)
binary.BigEndian.PutUint16(((*[2]byte)(unsafe.Pointer(&sa4.sin_port)))[:], uint16(port))
return true
}
if len(ip) == 16 {
sa6 := (*C.struct_sockaddr_in6)(unsafe.Pointer(ss))
sa6.sin6_family = afInet6
copy(((*[16]byte)(unsafe.Pointer(&sa6.sin6_addr)))[:], ip)
binary.BigEndian.PutUint16(((*[2]byte)(unsafe.Pointer(&sa6.sin6_port)))[:], uint16(port))
return true
}
return false
}
//////////////////////////////////////////////////////////////////////////////
// Node represents an instance of the ZeroTier core node and related C++ I/O code
@ -160,6 +221,82 @@ func (n *Node) Leave(nwid uint64) error {
return nil
}
// AddStaticRoot adds a statically defined root server to this node.
// If a static root with the given identity already exists this will update its IP and port information.
func (n *Node) AddStaticRoot(id *Identity, addrs []net.Addr) {
var saddrs []*C.struct_sockaddr_storage
for _, a := range addrs {
aa, _ := a.(*net.UDPAddr)
if aa != nil {
ss := new(C.struct_sockaddr_storage)
if makeSockaddrStorage(aa.IP, aa.Port, ss) {
saddrs = append(saddrs, ss)
}
}
}
if len(saddrs) > 0 {
ids := C.CString(id.String())
C.ZT_Node_setStaticRoot(n.zn, ids, &saddrs[0], C.uint(len(saddrs)))
C.free(unsafe.Pointer(ids))
}
}
// RemoveStaticRoot removes a statically defined root server from this node.
func (n *Node) RemoveStaticRoot(id *Identity) {
ids := C.CString(id.String())
C.ZT_Node_removeStaticRoot(n.zn, ids)
C.free(unsafe.Pointer(ids))
}
// AddDynamicRoot adds a dynamic root to this node.
// If the locator parameter is non-empty it can contain a binary serialized locator
// to use if (or until) one can be fetched via DNS.
func (n *Node) AddDynamicRoot(dnsName string, locator []byte) {
dn := C.CString(dnsName)
if len(locator) > 0 {
C.ZT_Node_setDynamicRoot(n.zn, dn, unsafe.Pointer(&locator[0]), C.uint(len(locator)))
} else {
C.ZT_Node_setDynamicRoot(n.zn, dn, nil, 0)
}
C.free(unsafe.Pointer(dn))
}
// RemoveDynamicRoot removes a dynamic root from this node.
func (n *Node) RemoveDynamicRoot(dnsName string) {
dn := C.CString(dnsName)
C.ZT_Node_removeDynamicRoot(n.zn, dn)
C.free(unsafe.Pointer(dn))
}
// ListRoots retrieves a list of root servers on this node and their preferred and online status.
func (n *Node) ListRoots() []Root {
var roots []Root
rl := C.ZT_Node_listRoots(n.zn, C.int64_t(TimeMs()))
if rl != nil {
for i := 0; i < int(rl.count); i++ {
id, err := NewIdentityFromString(C.GoString(rl.roots[i].identity))
if err == nil {
var addrs []net.Addr
for j := 0; j < int(rl.roots[i].addressCount); j++ {
a := sockaddrStorageToUDPAddr(&rl.roots[i].addresses[j])
if a != nil {
addrs = append(addrs, a)
}
}
roots = append(roots, Root{
DNSName: C.GoString(rl.roots[i].dnsName),
Identity: id,
Addresses: addrs,
Preferred: (rl.roots[i].preferred != 0),
Online: (rl.roots[i].online != 0),
})
}
}
defer C.ZT_Node_freeQueryResult(n.zn, unsafe.Pointer(rl))
}
return roots
}
//////////////////////////////////////////////////////////////////////////////
func (n *Node) pathCheck(ztAddress uint64, af int, ip net.IP, port int) bool {
@ -345,27 +482,6 @@ 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) {
go func() {

25
go/pkg/zerotier/root.go Normal file
View File

@ -0,0 +1,25 @@
/*
* Copyright (c)2019 ZeroTier, Inc.
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file in the project's root directory.
*
* Change Date: 2023-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2.0 of the Apache License.
*/
/****/
package zerotier
import "net"
// Root describes a root server used to find and establish communication with other nodes.
type Root struct {
DNSName string
Identity *Identity
Addresses []net.Addr
Preferred bool
Online bool
}