5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-12-22 22:15:46 +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 {
case *getaddr:
if nodeid := getNodeID(); nodeid != nil {
addr := *address.AddrForNodeID(nodeid)
panic("TODO")
addr := new(address.Address) //*address.AddrForNodeID(nodeid)
ip := net.IP(addr[:])
fmt.Println(ip.String())
}
return
case *getsnet:
if nodeid := getNodeID(); nodeid != nil {
snet := *address.SubnetForNodeID(nodeid)
panic("TODO")
snet := new(address.Address) //*address.SubnetForNodeID(nodeid)
ipnet := net.IPNet{
IP: append(snet[:], 0, 0, 0, 0, 0, 0, 0, 0),
Mask: net.CIDRMask(len(snet)*8, 128),

View File

@ -3,9 +3,7 @@
package address
import (
"fmt"
"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
"crypto/ed25519"
)
// 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
}
// 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.
// The following 8 bits are set to the number of leading 1 bits in the NodeID.
// 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.
func AddrForNodeID(nid *crypto.NodeID) *Address {
// The following 8 bits are set to the number of leading 1 bits in the bitwise inverse of the public key.
// 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 AddrForKey(publicKey ed25519.PublicKey) *Address {
// 128 bit address
// Begins with prefix
// Next bit is a 0
// 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
// 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 temp []byte
done := false
ones := byte(0)
bits := byte(0)
nBits := 0
for idx := 0; idx < 8*len(nid); idx++ {
bit := (nid[idx/8] & (0x80 >> byte(idx%8))) >> byte(7-(idx%8))
for idx := 0; idx < 8*len(buf); idx++ {
bit := (buf[idx/8] & (0x80 >> byte(idx%8))) >> byte(7-(idx%8))
if !done && bit != 0 {
ones++
continue
@ -86,91 +93,22 @@ func AddrForNodeID(nid *crypto.NodeID) *Address {
return &addr
}
// SubnetForNodeID takes a *NodeID as an argument and returns an *Address.
// This subnet begins with the address prefix, with the last bit set to 1 to indicate a prefix.
// The following 8 bits are set to the number of leading 1 bits in the NodeID.
// 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.
func SubnetForNodeID(nid *crypto.NodeID) *Subnet {
// SubnetForKey takes an ed25519.PublicKey as an argument and returns a *Subnet.
// This function returns nil if the key length is not ed25519.PublicKeySize.
// The subnet begins with the address prefix, with the last bit set to 1 to indicate a prefix.
// The following 8 bits are set to the number of leading 1 bits in the bitwise inverse of the key.
// 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:
// 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
addr := *AddrForNodeID(nid)
addr := AddrForKey(publicKey)
if addr == nil {
return nil
}
var snet Subnet
copy(snet[:], addr[:])
prefix := GetPrefix()
snet[len(prefix)-1] |= 0x01
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) {
peers := make(Info)
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()
peers[so] = Info{
"port": p.Port,
@ -117,7 +118,8 @@ func (a *AdminSocket) SetupAdminHandlers(na *AdminSocket) {
a.AddHandler("getSwitchPeers", []string{}, func(in Info) (Info, error) {
switchpeers := make(Info)
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)
switchpeers[so] = Info{
"ip": net.IP(addr[:]).String(),
@ -141,7 +143,8 @@ func (a *AdminSocket) SetupAdminHandlers(na *AdminSocket) {
a.AddHandler("getDHT", []string{}, func(in Info) (Info, error) {
dht := make(Info)
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()
dht[so] = Info{
"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) {
sessions := make(Info)
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()
sessions[so] = Info{
"coords": fmt.Sprintf("%v", s.Coords),
@ -293,7 +297,8 @@ func (a *AdminSocket) SetupAdminHandlers(na *AdminSocket) {
"box_pub_key": hex.EncodeToString(dinfo.PublicKey[:]),
"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
}
return Info{"nodes": infos}, nil

View File

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

View File

@ -154,9 +154,10 @@ func (tun *TunAdapter) _start() error {
return err
}
copy(boxPub[:], boxPubHex)
nodeID := crypto.GetNodeID(&boxPub)
tun.addr = *address.AddrForNodeID(nodeID)
tun.subnet = *address.SubnetForNodeID(nodeID)
panic("TODO")
//nodeID := crypto.GetNodeID(&boxPub)
//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)
if current.IfName == "none" || current.IfName == "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
// Get the remote address and subnet of the other side
remotePubKey := conn.RemoteAddr().(*crypto.BoxPubKey)
remoteNodeID := crypto.GetNodeID(remotePubKey)
s.addr = *address.AddrForNodeID(remoteNodeID)
s.snet = *address.SubnetForNodeID(remoteNodeID)
panic("TODO")
//remotePubKey := conn.RemoteAddr().(*crypto.BoxPubKey)
//remoteNodeID := crypto.GetNodeID(remotePubKey)
//s.addr = *address.AddrForNodeID(remoteNodeID)
//s.snet = *address.SubnetForNodeID(remoteNodeID)
// Work out if this is already a destination we already know about
atc, aok := tun.addrToConn[s.addr]
stc, sok := tun.subnetToConn[s.snet]

View File

@ -9,7 +9,7 @@ import (
"time"
"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/Arceliar/phony"
@ -314,8 +314,10 @@ func (c *Core) Coords() []uint64 {
// that application also implements either VPN functionality or deals with IP
// packets specifically.
func (c *Core) Address() net.IP {
address := net.IP(address.AddrForNodeID(c.NodeID())[:])
return address
panic("TODO")
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
@ -324,9 +326,11 @@ func (c *Core) Address() net.IP {
// that application also implements either VPN functionality or deals with IP
// packets specifically.
func (c *Core) Subnet() net.IPNet {
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)}
panic("TODO")
return net.IPNet{}
//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

View File

@ -13,7 +13,7 @@ import (
//"sync/atomic"
"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/util"
"golang.org/x/net/proxy"
@ -287,7 +287,7 @@ func (intf *link) handler() (chan struct{}, error) {
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()
themString := fmt.Sprintf("%s@%s", themAddrString, intf.info.remote)
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.
func (r *router) init(core *Core) {
r.core = core
r.addr = *address.AddrForNodeID(&r.dht.nodeID)
r.subnet = *address.SubnetForNodeID(&r.dht.nodeID)
// TODO r.addr = *address.AddrForNodeID(&r.dht.nodeID)
// TODO r.subnet = *address.SubnetForNodeID(&r.dht.nodeID)
r.intf.router = r
phony.Block(&r.core.peers, func() {
// 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.myHandle = *crypto.NewHandle()
sinfo.theirAddr = *address.AddrForNodeID(crypto.GetNodeID(&sinfo.theirPermPub))
sinfo.theirSubnet = *address.SubnetForNodeID(crypto.GetNodeID(&sinfo.theirPermPub))
// TODO sinfo.theirAddr = *address.AddrForNodeID(crypto.GetNodeID(&sinfo.theirPermPub))
// TODO sinfo.theirSubnet = *address.SubnetForNodeID(crypto.GetNodeID(&sinfo.theirPermPub))
sinfo.table = ss.router.table
ss.sinfos[sinfo.myHandle] = &sinfo
ss.byTheirPerm[sinfo.theirPermPub] = &sinfo.myHandle