2019-05-18 16:21:02 +00:00
|
|
|
package yggdrasil
|
|
|
|
|
|
|
|
import (
|
2021-05-15 19:50:56 +00:00
|
|
|
"crypto/ed25519"
|
2021-05-08 13:35:58 +00:00
|
|
|
//"encoding/hex"
|
2019-05-18 16:21:02 +00:00
|
|
|
"errors"
|
2021-05-08 13:35:58 +00:00
|
|
|
//"fmt"
|
2019-05-18 16:21:02 +00:00
|
|
|
"net"
|
2021-05-08 13:35:58 +00:00
|
|
|
//"sort"
|
2021-05-15 19:50:56 +00:00
|
|
|
//"time"
|
2019-05-18 16:21:02 +00:00
|
|
|
|
|
|
|
"github.com/gologme/log"
|
2021-05-08 13:35:58 +00:00
|
|
|
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
2021-05-15 19:50:56 +00:00
|
|
|
//"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
|
2021-05-08 13:35:58 +00:00
|
|
|
//"github.com/Arceliar/phony"
|
2019-05-18 16:21:02 +00:00
|
|
|
)
|
|
|
|
|
2021-05-15 19:50:56 +00:00
|
|
|
type Self struct {
|
|
|
|
Key ed25519.PublicKey
|
|
|
|
Root ed25519.PublicKey
|
|
|
|
Coords []uint64
|
2019-05-18 16:21:02 +00:00
|
|
|
}
|
|
|
|
|
2021-05-15 19:50:56 +00:00
|
|
|
type Peer struct {
|
|
|
|
Key ed25519.PublicKey
|
|
|
|
Root ed25519.PublicKey
|
|
|
|
Coords []uint64
|
|
|
|
Port uint64
|
2019-05-18 16:21:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type DHTEntry struct {
|
2021-05-15 19:50:56 +00:00
|
|
|
Key ed25519.PublicKey
|
|
|
|
Port uint64
|
2021-05-19 01:43:38 +00:00
|
|
|
Rest uint64
|
2019-05-18 16:21:02 +00:00
|
|
|
}
|
|
|
|
|
2021-05-15 19:50:56 +00:00
|
|
|
type PathEntry struct {
|
|
|
|
Key ed25519.PublicKey
|
|
|
|
Path []uint64
|
2019-05-20 18:51:44 +00:00
|
|
|
}
|
|
|
|
|
2021-05-15 19:50:56 +00:00
|
|
|
type Session struct {
|
|
|
|
Key ed25519.PublicKey
|
2019-05-19 15:29:04 +00:00
|
|
|
}
|
|
|
|
|
2021-05-15 19:50:56 +00:00
|
|
|
func (c *Core) GetSelf() Self {
|
|
|
|
var self Self
|
|
|
|
s := c.PacketConn.PacketConn.Debug.GetSelf()
|
|
|
|
self.Key = s.Key
|
|
|
|
self.Root = s.Root
|
|
|
|
self.Coords = s.Coords
|
|
|
|
return self
|
2019-05-19 15:29:04 +00:00
|
|
|
}
|
2019-05-18 16:21:02 +00:00
|
|
|
|
|
|
|
func (c *Core) GetPeers() []Peer {
|
|
|
|
var peers []Peer
|
2021-05-15 19:50:56 +00:00
|
|
|
ps := c.PacketConn.PacketConn.Debug.GetPeers()
|
|
|
|
for _, p := range ps {
|
2019-08-24 19:24:42 +00:00
|
|
|
var info Peer
|
2021-05-15 19:50:56 +00:00
|
|
|
info.Key = p.Key
|
|
|
|
info.Root = p.Root
|
|
|
|
info.Coords = p.Coords
|
|
|
|
info.Port = p.Port
|
2019-05-18 16:21:02 +00:00
|
|
|
peers = append(peers, info)
|
|
|
|
}
|
|
|
|
return peers
|
|
|
|
}
|
|
|
|
|
2021-05-15 19:50:56 +00:00
|
|
|
func (c *Core) GetDHT() []DHTEntry {
|
|
|
|
var dhts []DHTEntry
|
|
|
|
ds := c.PacketConn.PacketConn.Debug.GetDHT()
|
|
|
|
for _, d := range ds {
|
|
|
|
var info DHTEntry
|
|
|
|
info.Key = d.Key
|
|
|
|
info.Port = d.Port
|
2021-05-19 01:43:38 +00:00
|
|
|
info.Rest = d.Rest
|
2021-05-15 19:50:56 +00:00
|
|
|
dhts = append(dhts, info)
|
2019-05-18 16:21:02 +00:00
|
|
|
}
|
2021-05-15 19:50:56 +00:00
|
|
|
return dhts
|
2019-05-18 16:21:02 +00:00
|
|
|
}
|
|
|
|
|
2021-05-15 19:50:56 +00:00
|
|
|
func (c *Core) GetPaths() []PathEntry {
|
|
|
|
var paths []PathEntry
|
|
|
|
ps := c.PacketConn.PacketConn.Debug.GetPaths()
|
|
|
|
for _, p := range ps {
|
|
|
|
var info PathEntry
|
|
|
|
info.Key = p.Key
|
|
|
|
info.Path = p.Path
|
|
|
|
paths = append(paths, info)
|
2019-05-19 15:29:04 +00:00
|
|
|
}
|
2021-05-15 19:50:56 +00:00
|
|
|
return paths
|
2019-05-18 16:21:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Core) GetSessions() []Session {
|
2019-05-19 15:29:04 +00:00
|
|
|
var sessions []Session
|
2021-05-15 19:50:56 +00:00
|
|
|
ss := c.PacketConn.Debug.GetSessions()
|
|
|
|
for _, s := range ss {
|
|
|
|
var info Session
|
|
|
|
info.Key = s.Key
|
|
|
|
sessions = append(sessions, info)
|
2019-05-19 15:29:04 +00:00
|
|
|
}
|
|
|
|
return sessions
|
2019-05-18 16:21:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ListenTCP starts a new TCP listener. The input URI should match that of the
|
|
|
|
// "Listen" configuration item, e.g.
|
|
|
|
// tcp://a.b.c.d:e
|
|
|
|
func (c *Core) ListenTCP(uri string) (*TcpListener, error) {
|
2020-05-23 15:23:55 +00:00
|
|
|
return c.links.tcp.listen(uri, nil)
|
2019-10-23 16:26:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ListenTLS starts a new TLS listener. The input URI should match that of the
|
|
|
|
// "Listen" configuration item, e.g.
|
|
|
|
// tls://a.b.c.d:e
|
|
|
|
func (c *Core) ListenTLS(uri string) (*TcpListener, error) {
|
2020-05-23 15:23:55 +00:00
|
|
|
return c.links.tcp.listen(uri, c.links.tcp.tls.forListener)
|
2019-05-18 16:21:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Address gets the IPv6 address of the Yggdrasil node. This is always a /128
|
2019-09-01 22:47:47 +00:00
|
|
|
// address. The IPv6 address is only relevant when the node is operating as an
|
|
|
|
// IP router and often is meaningless when embedded into an application, unless
|
|
|
|
// that application also implements either VPN functionality or deals with IP
|
|
|
|
// packets specifically.
|
2019-07-28 10:30:24 +00:00
|
|
|
func (c *Core) Address() net.IP {
|
2021-05-08 13:35:58 +00:00
|
|
|
addr := net.IP(address.AddrForKey(c.public)[:])
|
|
|
|
return addr
|
2019-05-18 16:21:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Subnet gets the routed IPv6 subnet of the Yggdrasil node. This is always a
|
2019-09-01 22:47:47 +00:00
|
|
|
// /64 subnet. The IPv6 subnet is only relevant when the node is operating as an
|
|
|
|
// IP router and often is meaningless when embedded into an application, unless
|
|
|
|
// that application also implements either VPN functionality or deals with IP
|
|
|
|
// packets specifically.
|
2019-07-28 10:30:24 +00:00
|
|
|
func (c *Core) Subnet() net.IPNet {
|
2021-05-08 13:35:58 +00:00
|
|
|
subnet := address.SubnetForKey(c.public)[:]
|
|
|
|
subnet = append(subnet, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
|
|
return net.IPNet{IP: subnet, Mask: net.CIDRMask(64, 128)}
|
2019-05-18 16:21:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetLogger sets the output logger of the Yggdrasil node after startup. This
|
2019-09-01 22:47:47 +00:00
|
|
|
// may be useful if you want to redirect the output later. Note that this
|
|
|
|
// expects a Logger from the github.com/gologme/log package and not from Go's
|
|
|
|
// built-in log package.
|
2019-05-18 16:21:02 +00:00
|
|
|
func (c *Core) SetLogger(log *log.Logger) {
|
|
|
|
c.log = log
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddPeer adds a peer. This should be specified in the peer URI format, e.g.:
|
|
|
|
// tcp://a.b.c.d:e
|
|
|
|
// socks://a.b.c.d:e/f.g.h.i:j
|
|
|
|
// This adds the peer to the peer list, so that they will be called again if the
|
|
|
|
// connection drops.
|
|
|
|
func (c *Core) AddPeer(addr string, sintf string) error {
|
|
|
|
if err := c.CallPeer(addr, sintf); err != nil {
|
2019-09-19 07:55:55 +00:00
|
|
|
// TODO: We maybe want this to write the peer to the persistent
|
|
|
|
// configuration even if a connection attempt fails, but first we'll need to
|
|
|
|
// move the code to check the peer URI so that we don't deliberately save a
|
|
|
|
// peer with a known bad URI. Loading peers from config should really do the
|
|
|
|
// same thing too but I don't think that happens today
|
2019-05-18 16:21:02 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
c.config.Mutex.Lock()
|
2019-11-13 03:01:32 +00:00
|
|
|
defer c.config.Mutex.Unlock()
|
2019-05-18 16:21:02 +00:00
|
|
|
if sintf == "" {
|
2019-09-19 07:55:55 +00:00
|
|
|
for _, peer := range c.config.Current.Peers {
|
|
|
|
if peer == addr {
|
|
|
|
return errors.New("peer already added")
|
|
|
|
}
|
|
|
|
}
|
2019-05-18 16:21:02 +00:00
|
|
|
c.config.Current.Peers = append(c.config.Current.Peers, addr)
|
|
|
|
} else {
|
2019-09-19 07:55:55 +00:00
|
|
|
if _, ok := c.config.Current.InterfacePeers[sintf]; ok {
|
|
|
|
for _, peer := range c.config.Current.InterfacePeers[sintf] {
|
|
|
|
if peer == addr {
|
|
|
|
return errors.New("peer already added")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if _, ok := c.config.Current.InterfacePeers[sintf]; !ok {
|
|
|
|
c.config.Current.InterfacePeers[sintf] = []string{addr}
|
|
|
|
} else {
|
|
|
|
c.config.Current.InterfacePeers[sintf] = append(c.config.Current.InterfacePeers[sintf], addr)
|
|
|
|
}
|
2019-05-18 16:21:02 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-05-15 19:50:56 +00:00
|
|
|
/*
|
2019-05-20 18:51:44 +00:00
|
|
|
func (c *Core) RemovePeer(addr string, sintf string) error {
|
2020-07-06 13:14:34 +00:00
|
|
|
if sintf == "" {
|
|
|
|
for i, peer := range c.config.Current.Peers {
|
|
|
|
if peer == addr {
|
|
|
|
c.config.Current.Peers = append(c.config.Current.Peers[:i], c.config.Current.Peers[i+1:]...)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if _, ok := c.config.Current.InterfacePeers[sintf]; ok {
|
|
|
|
for i, peer := range c.config.Current.InterfacePeers[sintf] {
|
|
|
|
if peer == addr {
|
|
|
|
c.config.Current.InterfacePeers[sintf] = append(c.config.Current.InterfacePeers[sintf][:i], c.config.Current.InterfacePeers[sintf][i+1:]...)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-15 19:50:56 +00:00
|
|
|
panic("TODO") // Get the net.Conn to this peer (if any) and close it
|
2020-07-06 13:21:28 +00:00
|
|
|
c.peers.Act(nil, func() {
|
|
|
|
ports := c.peers.ports
|
|
|
|
for _, peer := range ports {
|
|
|
|
if addr == peer.intf.name() {
|
|
|
|
c.peers._removePeer(peer)
|
|
|
|
}
|
2020-07-06 13:14:34 +00:00
|
|
|
}
|
2020-07-06 13:21:28 +00:00
|
|
|
})
|
2020-07-06 13:14:34 +00:00
|
|
|
|
|
|
|
return nil
|
2019-05-20 18:51:44 +00:00
|
|
|
}
|
2021-05-15 19:50:56 +00:00
|
|
|
*/
|
2019-05-20 18:51:44 +00:00
|
|
|
|
2019-05-18 16:21:02 +00:00
|
|
|
// CallPeer calls a peer once. This should be specified in the peer URI format,
|
|
|
|
// e.g.:
|
|
|
|
// tcp://a.b.c.d:e
|
|
|
|
// socks://a.b.c.d:e/f.g.h.i:j
|
|
|
|
// This does not add the peer to the peer list, so if the connection drops, the
|
|
|
|
// peer will not be called again automatically.
|
|
|
|
func (c *Core) CallPeer(addr string, sintf string) error {
|
2020-05-23 15:23:55 +00:00
|
|
|
return c.links.call(addr, sintf)
|
2019-05-18 16:21:02 +00:00
|
|
|
}
|