diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index 14b76c34..8d3e00e8 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -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), diff --git a/src/address/address.go b/src/address/address.go index 0569af00..ff2d2120 100644 --- a/src/address/address.go +++ b/src/address/address.go @@ -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) -} diff --git a/src/admin/admin.go b/src/admin/admin.go index bdb7cd3a..dbf973e9 100644 --- a/src/admin/admin.go +++ b/src/admin/admin.go @@ -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 diff --git a/src/tuntap/iface.go b/src/tuntap/iface.go index 86c3f838..da6d8e24 100644 --- a/src/tuntap/iface.go +++ b/src/tuntap/iface.go @@ -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() } } } diff --git a/src/tuntap/tun.go b/src/tuntap/tun.go index 656ecca7..06f609ae 100644 --- a/src/tuntap/tun.go +++ b/src/tuntap/tun.go @@ -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] diff --git a/src/yggdrasil/api.go b/src/yggdrasil/api.go index c800cb0d..9d0634ce 100644 --- a/src/yggdrasil/api.go +++ b/src/yggdrasil/api.go @@ -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 diff --git a/src/yggdrasil/link.go b/src/yggdrasil/link.go index 2ee2f312..9ecc98ff 100644 --- a/src/yggdrasil/link.go +++ b/src/yggdrasil/link.go @@ -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", diff --git a/src/yggdrasil/router.go b/src/yggdrasil/router.go index db81068a..924d285a 100644 --- a/src/yggdrasil/router.go +++ b/src/yggdrasil/router.go @@ -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! diff --git a/src/yggdrasil/session.go b/src/yggdrasil/session.go index 8fd7cd5b..2d64cac4 100644 --- a/src/yggdrasil/session.go +++ b/src/yggdrasil/session.go @@ -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