5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-11-22 14:10:28 +00:00

(broken state) WIP address migration

This commit is contained in:
Arceliar 2021-05-08 07:25:53 -05:00
parent ae96148008
commit ace7b43b6d
9 changed files with 73 additions and 120 deletions

View File

@ -230,14 +230,16 @@ func main() {
switch { switch {
case *getaddr: case *getaddr:
if nodeid := getNodeID(); nodeid != nil { if nodeid := getNodeID(); nodeid != nil {
addr := *address.AddrForNodeID(nodeid) panic("TODO")
addr := new(address.Address) //*address.AddrForNodeID(nodeid)
ip := net.IP(addr[:]) ip := net.IP(addr[:])
fmt.Println(ip.String()) fmt.Println(ip.String())
} }
return return
case *getsnet: case *getsnet:
if nodeid := getNodeID(); nodeid != nil { if nodeid := getNodeID(); nodeid != nil {
snet := *address.SubnetForNodeID(nodeid) panic("TODO")
snet := new(address.Address) //*address.SubnetForNodeID(nodeid)
ipnet := net.IPNet{ ipnet := net.IPNet{
IP: append(snet[:], 0, 0, 0, 0, 0, 0, 0, 0), IP: append(snet[:], 0, 0, 0, 0, 0, 0, 0, 0),
Mask: net.CIDRMask(len(snet)*8, 128), Mask: net.CIDRMask(len(snet)*8, 128),

View File

@ -3,9 +3,7 @@
package address package address
import ( import (
"fmt" "crypto/ed25519"
"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
) )
// Address represents an IPv6 address in the yggdrasil address range. // Address represents an IPv6 address in the yggdrasil address range.
@ -45,25 +43,34 @@ func (s *Subnet) IsValid() bool {
return (*s)[l-1] == prefix[l-1]|0x01 return (*s)[l-1] == prefix[l-1]|0x01
} }
// AddrForNodeID takes a *NodeID as an argument and returns an *Address. // AddrForKey takes an ed25519.PublicKey as an argument and returns an *Address.
// This function returns nil if the key length is not ed25519.PublicKeySize.
// This address begins with the contents of GetPrefix(), with the last bit set to 0 to indicate an address. // This address begins with the contents of GetPrefix(), with the last bit set to 0 to indicate an address.
// The following 8 bits are set to the number of leading 1 bits in the NodeID. // The following 8 bits are set to the number of leading 1 bits in the bitwise inverse of the public key.
// The NodeID, excluding the leading 1 bits and the first leading 0 bit, is truncated to the appropriate length and makes up the remainder of the address. // The bitwise inverse of the key, excluding the leading 1 bits and the first leading 0 bit, is truncated to the appropriate length and makes up the remainder of the address.
func AddrForNodeID(nid *crypto.NodeID) *Address { func AddrForKey(publicKey ed25519.PublicKey) *Address {
// 128 bit address // 128 bit address
// Begins with prefix // Begins with prefix
// Next bit is a 0 // Next bit is a 0
// Next 7 bits, interpreted as a uint, are # of leading 1s in the NodeID // Next 7 bits, interpreted as a uint, are # of leading 1s in the NodeID
// Leading 1s and first leading 0 of the NodeID are truncated off // Leading 1s and first leading 0 of the NodeID are truncated off
// The rest is appended to the IPv6 address (truncated to 128 bits total) // The rest is appended to the IPv6 address (truncated to 128 bits total)
if len(publicKey) != ed25519.PublicKeySize {
return nil
}
var buf [ed25519.PublicKeySize]byte
copy(buf[:], publicKey)
for idx := range buf {
buf[idx] = ^buf[idx]
}
var addr Address var addr Address
var temp []byte var temp []byte
done := false done := false
ones := byte(0) ones := byte(0)
bits := byte(0) bits := byte(0)
nBits := 0 nBits := 0
for idx := 0; idx < 8*len(nid); idx++ { for idx := 0; idx < 8*len(buf); idx++ {
bit := (nid[idx/8] & (0x80 >> byte(idx%8))) >> byte(7-(idx%8)) bit := (buf[idx/8] & (0x80 >> byte(idx%8))) >> byte(7-(idx%8))
if !done && bit != 0 { if !done && bit != 0 {
ones++ ones++
continue continue
@ -86,91 +93,22 @@ func AddrForNodeID(nid *crypto.NodeID) *Address {
return &addr return &addr
} }
// SubnetForNodeID takes a *NodeID as an argument and returns an *Address. // SubnetForKey takes an ed25519.PublicKey as an argument and returns a *Subnet.
// This subnet begins with the address prefix, with the last bit set to 1 to indicate a prefix. // This function returns nil if the key length is not ed25519.PublicKeySize.
// The following 8 bits are set to the number of leading 1 bits in the NodeID. // The subnet begins with the address prefix, with the last bit set to 1 to indicate a prefix.
// The NodeID, excluding the leading 1 bits and the first leading 0 bit, is truncated to the appropriate length and makes up the remainder of the subnet. // The following 8 bits are set to the number of leading 1 bits in the bitwise inverse of the key.
func SubnetForNodeID(nid *crypto.NodeID) *Subnet { // The bitwise inverse of the key, excluding the leading 1 bits and the first leading 0 bit, is truncated to the appropriate length and makes up the remainder of the subnet.
func SubnetForKey(publicKey ed25519.PublicKey) *Subnet {
// Exactly as the address version, with two exceptions: // Exactly as the address version, with two exceptions:
// 1) The first bit after the fixed prefix is a 1 instead of a 0 // 1) The first bit after the fixed prefix is a 1 instead of a 0
// 2) It's truncated to a subnet prefix length instead of 128 bits // 2) It's truncated to a subnet prefix length instead of 128 bits
addr := *AddrForNodeID(nid) addr := AddrForKey(publicKey)
if addr == nil {
return nil
}
var snet Subnet var snet Subnet
copy(snet[:], addr[:]) copy(snet[:], addr[:])
prefix := GetPrefix() prefix := GetPrefix()
snet[len(prefix)-1] |= 0x01 snet[len(prefix)-1] |= 0x01
return &snet return &snet
} }
// GetNodeIDandMask returns two *NodeID.
// The first is a NodeID with all the bits known from the Address set to their correct values.
// The second is a bitmask with 1 bit set for each bit that was known from the Address.
// This is used to look up NodeIDs in the DHT and tell if they match an Address.
func (a *Address) GetNodeIDandMask() (*crypto.NodeID, *crypto.NodeID) {
// Mask is a bitmask to mark the bits visible from the address
// This means truncated leading 1s, first leading 0, and visible part of addr
var nid crypto.NodeID
var mask crypto.NodeID
prefix := GetPrefix()
ones := int(a[len(prefix)])
for idx := 0; idx < ones; idx++ {
nid[idx/8] |= 0x80 >> byte(idx%8)
}
nidOffset := ones + 1
addrOffset := 8*len(prefix) + 8
for idx := addrOffset; idx < 8*len(a); idx++ {
bits := a[idx/8] & (0x80 >> byte(idx%8))
bits <<= byte(idx % 8)
nidIdx := nidOffset + (idx - addrOffset)
bits >>= byte(nidIdx % 8)
nid[nidIdx/8] |= bits
}
maxMask := 8*(len(a)-len(prefix)-1) + ones + 1
for idx := 0; idx < maxMask; idx++ {
mask[idx/8] |= 0x80 >> byte(idx%8)
}
return &nid, &mask
}
// GetNodeIDLengthString returns a string representation of the known bits of the NodeID, along with the number of known bits, for use with yggdrasil.Dialer's Dial and DialContext functions.
func (a *Address) GetNodeIDLengthString() string {
nid, mask := a.GetNodeIDandMask()
l := mask.PrefixLength()
return fmt.Sprintf("%s/%d", nid.String(), l)
}
// GetNodeIDandMask returns two *NodeID.
// The first is a NodeID with all the bits known from the Subnet set to their correct values.
// The second is a bitmask with 1 bit set for each bit that was known from the Subnet.
// This is used to look up NodeIDs in the DHT and tell if they match a Subnet.
func (s *Subnet) GetNodeIDandMask() (*crypto.NodeID, *crypto.NodeID) {
// As with the address version, but visible parts of the subnet prefix instead
var nid crypto.NodeID
var mask crypto.NodeID
prefix := GetPrefix()
ones := int(s[len(prefix)])
for idx := 0; idx < ones; idx++ {
nid[idx/8] |= 0x80 >> byte(idx%8)
}
nidOffset := ones + 1
addrOffset := 8*len(prefix) + 8
for idx := addrOffset; idx < 8*len(s); idx++ {
bits := s[idx/8] & (0x80 >> byte(idx%8))
bits <<= byte(idx % 8)
nidIdx := nidOffset + (idx - addrOffset)
bits >>= byte(nidIdx % 8)
nid[nidIdx/8] |= bits
}
maxMask := 8*(len(s)-len(prefix)-1) + ones + 1
for idx := 0; idx < maxMask; idx++ {
mask[idx/8] |= 0x80 >> byte(idx%8)
}
return &nid, &mask
}
// GetNodeIDLengthString returns a string representation of the known bits of the NodeID, along with the number of known bits, for use with yggdrasil.Dialer's Dial and DialContext functions.
func (s *Subnet) GetNodeIDLengthString() string {
nid, mask := s.GetNodeIDandMask()
l := mask.PrefixLength()
return fmt.Sprintf("%s/%d", nid.String(), l)
}

View File

@ -100,7 +100,8 @@ func (a *AdminSocket) SetupAdminHandlers(na *AdminSocket) {
a.AddHandler("getPeers", []string{}, func(in Info) (Info, error) { a.AddHandler("getPeers", []string{}, func(in Info) (Info, error) {
peers := make(Info) peers := make(Info)
for _, p := range a.core.GetPeers() { for _, p := range a.core.GetPeers() {
addr := *address.AddrForNodeID(crypto.GetNodeID(&p.PublicKey)) panic("TODO")
addr := new(address.Address) // TODO *address.AddrForNodeID(crypto.GetNodeID(&p.PublicKey))
so := net.IP(addr[:]).String() so := net.IP(addr[:]).String()
peers[so] = Info{ peers[so] = Info{
"port": p.Port, "port": p.Port,
@ -117,7 +118,8 @@ func (a *AdminSocket) SetupAdminHandlers(na *AdminSocket) {
a.AddHandler("getSwitchPeers", []string{}, func(in Info) (Info, error) { a.AddHandler("getSwitchPeers", []string{}, func(in Info) (Info, error) {
switchpeers := make(Info) switchpeers := make(Info)
for _, s := range a.core.GetSwitchPeers() { for _, s := range a.core.GetSwitchPeers() {
addr := *address.AddrForNodeID(crypto.GetNodeID(&s.PublicKey)) panic("TODO")
addr := new(address.Address) // TODO *address.AddrForNodeID(crypto.GetNodeID(&s.PublicKey))
so := fmt.Sprint(s.Port) so := fmt.Sprint(s.Port)
switchpeers[so] = Info{ switchpeers[so] = Info{
"ip": net.IP(addr[:]).String(), "ip": net.IP(addr[:]).String(),
@ -141,7 +143,8 @@ func (a *AdminSocket) SetupAdminHandlers(na *AdminSocket) {
a.AddHandler("getDHT", []string{}, func(in Info) (Info, error) { a.AddHandler("getDHT", []string{}, func(in Info) (Info, error) {
dht := make(Info) dht := make(Info)
for _, d := range a.core.GetDHT() { for _, d := range a.core.GetDHT() {
addr := *address.AddrForNodeID(crypto.GetNodeID(&d.PublicKey)) panic("TODO")
addr := new(address.Address) // TODO *address.AddrForNodeID(crypto.GetNodeID(&d.PublicKey))
so := net.IP(addr[:]).String() so := net.IP(addr[:]).String()
dht[so] = Info{ dht[so] = Info{
"coords": fmt.Sprintf("%v", d.Coords), "coords": fmt.Sprintf("%v", d.Coords),
@ -154,7 +157,8 @@ func (a *AdminSocket) SetupAdminHandlers(na *AdminSocket) {
a.AddHandler("getSessions", []string{}, func(in Info) (Info, error) { a.AddHandler("getSessions", []string{}, func(in Info) (Info, error) {
sessions := make(Info) sessions := make(Info)
for _, s := range a.core.GetSessions() { for _, s := range a.core.GetSessions() {
addr := *address.AddrForNodeID(crypto.GetNodeID(&s.PublicKey)) panic("TODO")
addr := new(address.Address) //*address.AddrForNodeID(crypto.GetNodeID(&s.PublicKey))
so := net.IP(addr[:]).String() so := net.IP(addr[:]).String()
sessions[so] = Info{ sessions[so] = Info{
"coords": fmt.Sprintf("%v", s.Coords), "coords": fmt.Sprintf("%v", s.Coords),
@ -293,7 +297,8 @@ func (a *AdminSocket) SetupAdminHandlers(na *AdminSocket) {
"box_pub_key": hex.EncodeToString(dinfo.PublicKey[:]), "box_pub_key": hex.EncodeToString(dinfo.PublicKey[:]),
"coords": fmt.Sprintf("%v", dinfo.Coords), "coords": fmt.Sprintf("%v", dinfo.Coords),
} }
addr := net.IP(address.AddrForNodeID(crypto.GetNodeID(&dinfo.PublicKey))[:]).String() panic("TODO")
addr := "" //net.IP(address.AddrForNodeID(crypto.GetNodeID(&dinfo.PublicKey))[:]).String()
infos[addr] = info infos[addr] = info
} }
return Info{"nodes": infos}, nil return Info{"nodes": infos}, nil

View File

@ -139,11 +139,12 @@ func (tun *TunAdapter) _handlePacket(recvd []byte, err error) {
} }
if tun.ckr.isEnabled() { if tun.ckr.isEnabled() {
if addrlen != 16 || (!dstAddr.IsValid() && !dstSnet.IsValid()) { if addrlen != 16 || (!dstAddr.IsValid() && !dstSnet.IsValid()) {
if key, err := tun.ckr.getPublicKeyForAddress(dstAddr, addrlen); err == nil { if /*key*/ _, err := tun.ckr.getPublicKeyForAddress(dstAddr, addrlen); err == nil {
// A public key was found, get the node ID for the search // A public key was found, get the node ID for the search
dstNodeID := crypto.GetNodeID(&key) panic("TODO")
dstAddr = *address.AddrForNodeID(dstNodeID) //dstNodeID := crypto.GetNodeID(&key)
dstSnet = *address.SubnetForNodeID(dstNodeID) //dstAddr = *address.AddrForNodeID(dstNodeID)
//dstSnet = *address.SubnetForNodeID(dstNodeID)
addrlen = 16 addrlen = 16
} }
} }
@ -170,10 +171,11 @@ func (tun *TunAdapter) _handlePacket(recvd []byte, err error) {
if !isIn || session == nil { if !isIn || session == nil {
// Neither an address nor a subnet mapping matched, therefore populate // Neither an address nor a subnet mapping matched, therefore populate
// the node ID and mask to commence a search // the node ID and mask to commence a search
panic("TODO")
if dstAddr.IsValid() { if dstAddr.IsValid() {
dstString = dstAddr.GetNodeIDLengthString() //dstString = dstAddr.GetNodeIDLengthString()
} else { } else {
dstString = dstSnet.GetNodeIDLengthString() //dstString = dstSnet.GetNodeIDLengthString()
} }
} }
} }

View File

@ -154,9 +154,10 @@ func (tun *TunAdapter) _start() error {
return err return err
} }
copy(boxPub[:], boxPubHex) copy(boxPub[:], boxPubHex)
nodeID := crypto.GetNodeID(&boxPub) panic("TODO")
tun.addr = *address.AddrForNodeID(nodeID) //nodeID := crypto.GetNodeID(&boxPub)
tun.subnet = *address.SubnetForNodeID(nodeID) //tun.addr = *address.AddrForNodeID(nodeID)
//tun.subnet = *address.SubnetForNodeID(nodeID)
addr := fmt.Sprintf("%s/%d", net.IP(tun.addr[:]).String(), 8*len(address.GetPrefix())-1) addr := fmt.Sprintf("%s/%d", net.IP(tun.addr[:]).String(), 8*len(address.GetPrefix())-1)
if current.IfName == "none" || current.IfName == "dummy" { if current.IfName == "none" || current.IfName == "dummy" {
tun.log.Debugln("Not starting TUN as ifname is none or dummy") tun.log.Debugln("Not starting TUN as ifname is none or dummy")
@ -251,10 +252,11 @@ func (tun *TunAdapter) _wrap(conn *yggdrasil.Conn) (c *tunConn, err error) {
} }
c = &s c = &s
// Get the remote address and subnet of the other side // Get the remote address and subnet of the other side
remotePubKey := conn.RemoteAddr().(*crypto.BoxPubKey) panic("TODO")
remoteNodeID := crypto.GetNodeID(remotePubKey) //remotePubKey := conn.RemoteAddr().(*crypto.BoxPubKey)
s.addr = *address.AddrForNodeID(remoteNodeID) //remoteNodeID := crypto.GetNodeID(remotePubKey)
s.snet = *address.SubnetForNodeID(remoteNodeID) //s.addr = *address.AddrForNodeID(remoteNodeID)
//s.snet = *address.SubnetForNodeID(remoteNodeID)
// Work out if this is already a destination we already know about // Work out if this is already a destination we already know about
atc, aok := tun.addrToConn[s.addr] atc, aok := tun.addrToConn[s.addr]
stc, sok := tun.subnetToConn[s.snet] stc, sok := tun.subnetToConn[s.snet]

View File

@ -9,7 +9,7 @@ import (
"time" "time"
"github.com/gologme/log" "github.com/gologme/log"
"github.com/yggdrasil-network/yggdrasil-go/src/address" //"github.com/yggdrasil-network/yggdrasil-go/src/address"
"github.com/yggdrasil-network/yggdrasil-go/src/crypto" "github.com/yggdrasil-network/yggdrasil-go/src/crypto"
"github.com/Arceliar/phony" "github.com/Arceliar/phony"
@ -314,8 +314,10 @@ func (c *Core) Coords() []uint64 {
// that application also implements either VPN functionality or deals with IP // that application also implements either VPN functionality or deals with IP
// packets specifically. // packets specifically.
func (c *Core) Address() net.IP { func (c *Core) Address() net.IP {
address := net.IP(address.AddrForNodeID(c.NodeID())[:]) panic("TODO")
return address return nil
//address := net.IP(address.AddrForNodeID(c.NodeID())[:])
//return address
} }
// Subnet gets the routed IPv6 subnet of the Yggdrasil node. This is always a // Subnet gets the routed IPv6 subnet of the Yggdrasil node. This is always a
@ -324,9 +326,11 @@ func (c *Core) Address() net.IP {
// that application also implements either VPN functionality or deals with IP // that application also implements either VPN functionality or deals with IP
// packets specifically. // packets specifically.
func (c *Core) Subnet() net.IPNet { func (c *Core) Subnet() net.IPNet {
subnet := address.SubnetForNodeID(c.NodeID())[:] panic("TODO")
subnet = append(subnet, 0, 0, 0, 0, 0, 0, 0, 0) return net.IPNet{}
return net.IPNet{IP: subnet, Mask: net.CIDRMask(64, 128)} //subnet := address.SubnetForNodeID(c.NodeID())[:]
//subnet = append(subnet, 0, 0, 0, 0, 0, 0, 0, 0)
//return net.IPNet{IP: subnet, Mask: net.CIDRMask(64, 128)}
} }
// MyNodeInfo gets the currently configured nodeinfo. NodeInfo is typically // MyNodeInfo gets the currently configured nodeinfo. NodeInfo is typically

View File

@ -13,7 +13,7 @@ import (
//"sync/atomic" //"sync/atomic"
"time" "time"
"github.com/yggdrasil-network/yggdrasil-go/src/address" //"github.com/yggdrasil-network/yggdrasil-go/src/address"
"github.com/yggdrasil-network/yggdrasil-go/src/crypto" "github.com/yggdrasil-network/yggdrasil-go/src/crypto"
"github.com/yggdrasil-network/yggdrasil-go/src/util" "github.com/yggdrasil-network/yggdrasil-go/src/util"
"golang.org/x/net/proxy" "golang.org/x/net/proxy"
@ -287,7 +287,7 @@ func (intf *link) handler() (chan struct{}, error) {
intf.peer.Act(intf, intf.peer._removeSelf) intf.peer.Act(intf, intf.peer._removeSelf)
}) })
}() }()
themAddr := address.AddrForNodeID(crypto.GetNodeID(&intf.info.box)) themAddr := make([]byte, 16) // TODO address.AddrForNodeID(crypto.GetNodeID(&intf.info.box))
themAddrString := net.IP(themAddr[:]).String() themAddrString := net.IP(themAddr[:]).String()
themString := fmt.Sprintf("%s@%s", themAddrString, intf.info.remote) themString := fmt.Sprintf("%s@%s", themAddrString, intf.info.remote)
intf.links.core.log.Infof("Connected %s: %s, source %s", intf.links.core.log.Infof("Connected %s: %s, source %s",

View File

@ -53,8 +53,8 @@ type router struct {
// Initializes the router struct, which includes setting up channels to/from the adapter. // Initializes the router struct, which includes setting up channels to/from the adapter.
func (r *router) init(core *Core) { func (r *router) init(core *Core) {
r.core = core r.core = core
r.addr = *address.AddrForNodeID(&r.dht.nodeID) // TODO r.addr = *address.AddrForNodeID(&r.dht.nodeID)
r.subnet = *address.SubnetForNodeID(&r.dht.nodeID) // TODO r.subnet = *address.SubnetForNodeID(&r.dht.nodeID)
r.intf.router = r r.intf.router = r
phony.Block(&r.core.peers, func() { phony.Block(&r.core.peers, func() {
// FIXME don't block here! // FIXME don't block here!

View File

@ -221,8 +221,8 @@ func (ss *sessions) createSession(theirPermKey *crypto.BoxPubKey) *sessionInfo {
sinfo.myNonce[len(sinfo.myNonce)-1] &= 0xfe sinfo.myNonce[len(sinfo.myNonce)-1] &= 0xfe
} }
sinfo.myHandle = *crypto.NewHandle() sinfo.myHandle = *crypto.NewHandle()
sinfo.theirAddr = *address.AddrForNodeID(crypto.GetNodeID(&sinfo.theirPermPub)) // TODO sinfo.theirAddr = *address.AddrForNodeID(crypto.GetNodeID(&sinfo.theirPermPub))
sinfo.theirSubnet = *address.SubnetForNodeID(crypto.GetNodeID(&sinfo.theirPermPub)) // TODO sinfo.theirSubnet = *address.SubnetForNodeID(crypto.GetNodeID(&sinfo.theirPermPub))
sinfo.table = ss.router.table sinfo.table = ss.router.table
ss.sinfos[sinfo.myHandle] = &sinfo ss.sinfos[sinfo.myHandle] = &sinfo
ss.byTheirPerm[sinfo.theirPermPub] = &sinfo.myHandle ss.byTheirPerm[sinfo.theirPermPub] = &sinfo.myHandle