mirror of
https://github.com/ZeroTier/ZeroTierOne
synced 2025-08-14 10:37:33 -07:00
Gogogogogogogo
This commit is contained in:
parent
b44bd19c53
commit
b6175bd408
12 changed files with 583 additions and 150 deletions
123
go/pkg/zerotier/inetaddress.go
Normal file
123
go/pkg/zerotier/inetaddress.go
Normal file
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* 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 (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// InetAddress implements net.Addr but has a ZeroTier-like string representation
|
||||
type InetAddress struct {
|
||||
IP net.IP
|
||||
Port int
|
||||
}
|
||||
|
||||
// Less returns true if this IP/port is lexicographically less than another
|
||||
func (i *InetAddress) Less(i2 *InetAddress) bool {
|
||||
c := bytes.Compare(i.IP, i2.IP)
|
||||
if c < 0 {
|
||||
return true
|
||||
}
|
||||
if c == 0 {
|
||||
return i.Port < i2.Port
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// NewInetAddressFromString parses an IP[/port] format address
|
||||
func NewInetAddressFromString(s string) *InetAddress {
|
||||
i := new(InetAddress)
|
||||
ss := strings.Split(s, "/")
|
||||
if len(ss) > 0 {
|
||||
i.IP = net.ParseIP(ss[0])
|
||||
i4 := i.IP.To4()
|
||||
if len(i4) == 4 { // down-convert IPv4-in-6 IPs to native IPv4 as this is what all our code expects
|
||||
i.IP = i4
|
||||
}
|
||||
if len(ss) > 1 {
|
||||
p64, _ := strconv.ParseUint(s, 10, 64)
|
||||
i.Port = int(p64 & 0xffff)
|
||||
}
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
// NewInetAddressFromSockaddr parses a sockaddr_in or sockaddr_in6 C structure (may crash if given something other than these!)
|
||||
// This is a convenience wrapper around the CGO functions in node.go.
|
||||
func NewInetAddressFromSockaddr(sa unsafe.Pointer) *InetAddress {
|
||||
i := new(InetAddress)
|
||||
if uintptr(sa) != 0 {
|
||||
ua := sockaddrStorageToUDPAddr2(sa)
|
||||
if ua != nil {
|
||||
i.IP = ua.IP
|
||||
i.Port = ua.Port
|
||||
}
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
// Network returns "udp" to implement net.Addr
|
||||
func (i *InetAddress) Network() string {
|
||||
return "udp"
|
||||
}
|
||||
|
||||
// String returns this address in ZeroTier-canonical IP/port format
|
||||
func (i *InetAddress) String() string {
|
||||
return i.IP.String() + "/" + strconv.FormatInt(int64(i.Port), 10)
|
||||
}
|
||||
|
||||
// Family returns the address family (AFInet etc.) or 0 if none
|
||||
func (i *InetAddress) Family() int {
|
||||
switch len(i.IP) {
|
||||
case 4:
|
||||
return AFInet
|
||||
case 16:
|
||||
return AFInet6
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Valid returns true if both the IP and port have valid values
|
||||
func (i *InetAddress) Valid() bool {
|
||||
return (len(i.IP) == 4 || len(i.IP) == 16) && (i.Port > 0 && i.Port < 65536)
|
||||
}
|
||||
|
||||
// MarshalJSON marshals this MAC as a string
|
||||
func (i *InetAddress) MarshalJSON() ([]byte, error) {
|
||||
s := i.String()
|
||||
return json.Marshal(&s)
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals this MAC from a string
|
||||
func (i *InetAddress) UnmarshalJSON(j []byte) error {
|
||||
var s string
|
||||
err := json.Unmarshal(j, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*i = *NewInetAddressFromString(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
// key returns a short array suitable for use as a map[] key for this IP
|
||||
func (i *InetAddress) key() (k [3]uint64) {
|
||||
copy(((*[16]byte)(unsafe.Pointer(&k[0])))[:], i.IP)
|
||||
k[2] = uint64(i.Port)
|
||||
return
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue