mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 11:15:07 +03:00 
			
		
		
		
	Implement GetPeers and GetSwitchPeers API functions in Core, in preparation for breaking out the admin socket into a separate module
This commit is contained in:
		
							parent
							
								
									ce60609906
								
							
						
					
					
						commit
						8a6f6f3b2b
					
				
					 2 changed files with 341 additions and 155 deletions
				
			
		
							
								
								
									
										341
									
								
								src/yggdrasil/api.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										341
									
								
								src/yggdrasil/api.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,341 @@
 | 
			
		|||
package yggdrasil
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/hex"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"net"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/gologme/log"
 | 
			
		||||
	"github.com/yggdrasil-network/yggdrasil-go/src/address"
 | 
			
		||||
	"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Peer represents a single peer object. This contains information from the
 | 
			
		||||
// preferred switch port for this peer, although there may be more than one in
 | 
			
		||||
// reality.
 | 
			
		||||
type Peer struct {
 | 
			
		||||
	PublicKey  crypto.BoxPubKey
 | 
			
		||||
	Endpoint   string
 | 
			
		||||
	BytesSent  uint64
 | 
			
		||||
	BytesRecvd uint64
 | 
			
		||||
	Protocol   string
 | 
			
		||||
	Port       uint64
 | 
			
		||||
	Uptime     time.Duration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SwitchPeer represents a switch connection to a peer. Note that there may be
 | 
			
		||||
// multiple switch peers per actual peer, e.g. if there are multiple connections
 | 
			
		||||
// to a given node.
 | 
			
		||||
type SwitchPeer struct {
 | 
			
		||||
	PublicKey  crypto.BoxPubKey
 | 
			
		||||
	Coords     []byte
 | 
			
		||||
	BytesSent  uint64
 | 
			
		||||
	BytesRecvd uint64
 | 
			
		||||
	Port       uint64
 | 
			
		||||
	Protocol   string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type DHTEntry struct {
 | 
			
		||||
	PublicKey crypto.BoxPubKey
 | 
			
		||||
	Coords    []byte
 | 
			
		||||
	LastSeen  time.Duration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type SwitchQueue struct{}
 | 
			
		||||
type Session struct{}
 | 
			
		||||
 | 
			
		||||
// GetPeers returns one or more Peer objects containing information about active
 | 
			
		||||
// peerings with other Yggdrasil nodes, where one of the responses always
 | 
			
		||||
// includes information about the current node (with a port number of 0). If
 | 
			
		||||
// there is exactly one entry then this node is not connected to any other nodes
 | 
			
		||||
// and is therefore isolated.
 | 
			
		||||
func (c *Core) GetPeers() []Peer {
 | 
			
		||||
	ports := c.peers.ports.Load().(map[switchPort]*peer)
 | 
			
		||||
	var peers []Peer
 | 
			
		||||
	var ps []switchPort
 | 
			
		||||
	for port := range ports {
 | 
			
		||||
		ps = append(ps, port)
 | 
			
		||||
	}
 | 
			
		||||
	sort.Slice(ps, func(i, j int) bool { return ps[i] < ps[j] })
 | 
			
		||||
	for _, port := range ps {
 | 
			
		||||
		p := ports[port]
 | 
			
		||||
		info := Peer{
 | 
			
		||||
			Endpoint:   p.intf.name,
 | 
			
		||||
			BytesSent:  atomic.LoadUint64(&p.bytesSent),
 | 
			
		||||
			BytesRecvd: atomic.LoadUint64(&p.bytesRecvd),
 | 
			
		||||
			Protocol:   p.intf.info.linkType,
 | 
			
		||||
			Port:       uint64(port),
 | 
			
		||||
			Uptime:     time.Since(p.firstSeen),
 | 
			
		||||
		}
 | 
			
		||||
		copy(info.PublicKey[:], p.box[:])
 | 
			
		||||
		peers = append(peers, info)
 | 
			
		||||
	}
 | 
			
		||||
	return peers
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetSwitchPeers returns zero or more SwitchPeer objects containing information
 | 
			
		||||
// about switch port connections with other Yggdrasil nodes. Note that, unlike
 | 
			
		||||
// GetPeers, GetSwitchPeers does not include information about the current node,
 | 
			
		||||
// therefore it is possible for this to return zero elements if the node is
 | 
			
		||||
// isolated or not connected to any peers.
 | 
			
		||||
func (c *Core) GetSwitchPeers() []SwitchPeer {
 | 
			
		||||
	var switchpeers []SwitchPeer
 | 
			
		||||
	table := c.switchTable.table.Load().(lookupTable)
 | 
			
		||||
	peers := c.peers.ports.Load().(map[switchPort]*peer)
 | 
			
		||||
	for _, elem := range table.elems {
 | 
			
		||||
		peer, isIn := peers[elem.port]
 | 
			
		||||
		if !isIn {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		coords := elem.locator.getCoords()
 | 
			
		||||
		info := SwitchPeer{
 | 
			
		||||
			Coords:     coords,
 | 
			
		||||
			BytesSent:  atomic.LoadUint64(&peer.bytesSent),
 | 
			
		||||
			BytesRecvd: atomic.LoadUint64(&peer.bytesRecvd),
 | 
			
		||||
			Port:       uint64(elem.port),
 | 
			
		||||
			Protocol:   peer.intf.info.linkType,
 | 
			
		||||
		}
 | 
			
		||||
		copy(info.PublicKey[:], peer.box[:])
 | 
			
		||||
		switchpeers = append(switchpeers, info)
 | 
			
		||||
	}
 | 
			
		||||
	return switchpeers
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Core) GetDHT() []DHTEntry {
 | 
			
		||||
	/*
 | 
			
		||||
	  var infos []admin_nodeInfo
 | 
			
		||||
	  getDHT := func() {
 | 
			
		||||
	    now := time.Now()
 | 
			
		||||
	    var dhtInfos []*dhtInfo
 | 
			
		||||
	    for _, v := range a.core.dht.table {
 | 
			
		||||
	      dhtInfos = append(dhtInfos, v)
 | 
			
		||||
	    }
 | 
			
		||||
	    sort.SliceStable(dhtInfos, func(i, j int) bool {
 | 
			
		||||
	      return dht_ordered(&a.core.dht.nodeID, dhtInfos[i].getNodeID(), dhtInfos[j].getNodeID())
 | 
			
		||||
	    })
 | 
			
		||||
	    for _, v := range dhtInfos {
 | 
			
		||||
	      addr := *address.AddrForNodeID(v.getNodeID())
 | 
			
		||||
	      info := admin_nodeInfo{
 | 
			
		||||
	        {"ip", net.IP(addr[:]).String()},
 | 
			
		||||
	        {"coords", fmt.Sprint(v.coords)},
 | 
			
		||||
	        {"last_seen", int(now.Sub(v.recv).Seconds())},
 | 
			
		||||
	        {"box_pub_key", hex.EncodeToString(v.key[:])},
 | 
			
		||||
	      }
 | 
			
		||||
	      infos = append(infos, info)
 | 
			
		||||
	    }
 | 
			
		||||
	  }
 | 
			
		||||
	  a.core.router.doAdmin(getDHT)
 | 
			
		||||
	  return infos
 | 
			
		||||
	*/
 | 
			
		||||
	return []DHTEntry{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Core) GetSwitchQueues() []SwitchQueue {
 | 
			
		||||
	/*
 | 
			
		||||
	  var peerInfos admin_nodeInfo
 | 
			
		||||
	  switchTable := &a.core.switchTable
 | 
			
		||||
	  getSwitchQueues := func() {
 | 
			
		||||
	    queues := make([]map[string]interface{}, 0)
 | 
			
		||||
	    for k, v := range switchTable.queues.bufs {
 | 
			
		||||
	      nexthop := switchTable.bestPortForCoords([]byte(k))
 | 
			
		||||
	      queue := map[string]interface{}{
 | 
			
		||||
	        "queue_id":      k,
 | 
			
		||||
	        "queue_size":    v.size,
 | 
			
		||||
	        "queue_packets": len(v.packets),
 | 
			
		||||
	        "queue_port":    nexthop,
 | 
			
		||||
	      }
 | 
			
		||||
	      queues = append(queues, queue)
 | 
			
		||||
	    }
 | 
			
		||||
	    peerInfos = admin_nodeInfo{
 | 
			
		||||
	      {"queues", queues},
 | 
			
		||||
	      {"queues_count", len(switchTable.queues.bufs)},
 | 
			
		||||
	      {"queues_size", switchTable.queues.size},
 | 
			
		||||
	      {"highest_queues_count", switchTable.queues.maxbufs},
 | 
			
		||||
	      {"highest_queues_size", switchTable.queues.maxsize},
 | 
			
		||||
	      {"maximum_queues_size", switchTable.queueTotalMaxSize},
 | 
			
		||||
	    }
 | 
			
		||||
	  }
 | 
			
		||||
	  a.core.switchTable.doAdmin(getSwitchQueues)
 | 
			
		||||
	  return peerInfos
 | 
			
		||||
	*/
 | 
			
		||||
	return []SwitchQueue{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Core) GetSessions() []Session {
 | 
			
		||||
	/*
 | 
			
		||||
	  var infos []admin_nodeInfo
 | 
			
		||||
	  getSessions := func() {
 | 
			
		||||
	    for _, sinfo := range a.core.sessions.sinfos {
 | 
			
		||||
	      // TODO? skipped known but timed out sessions?
 | 
			
		||||
	      info := admin_nodeInfo{
 | 
			
		||||
	        {"ip", net.IP(sinfo.theirAddr[:]).String()},
 | 
			
		||||
	        {"coords", fmt.Sprint(sinfo.coords)},
 | 
			
		||||
	        {"mtu", sinfo.getMTU()},
 | 
			
		||||
	        {"was_mtu_fixed", sinfo.wasMTUFixed},
 | 
			
		||||
	        {"bytes_sent", sinfo.bytesSent},
 | 
			
		||||
	        {"bytes_recvd", sinfo.bytesRecvd},
 | 
			
		||||
	        {"box_pub_key", hex.EncodeToString(sinfo.theirPermPub[:])},
 | 
			
		||||
	      }
 | 
			
		||||
	      infos = append(infos, info)
 | 
			
		||||
	    }
 | 
			
		||||
	  }
 | 
			
		||||
	  a.core.router.doAdmin(getSessions)
 | 
			
		||||
	  return infos
 | 
			
		||||
	*/
 | 
			
		||||
	return []Session{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BuildName gets the current build name. This is usually injected if built
 | 
			
		||||
// from git, or returns "unknown" otherwise.
 | 
			
		||||
func BuildName() string {
 | 
			
		||||
	if buildName == "" {
 | 
			
		||||
		return "unknown"
 | 
			
		||||
	}
 | 
			
		||||
	return buildName
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BuildVersion gets the current build version. This is usually injected if
 | 
			
		||||
// built from git, or returns "unknown" otherwise.
 | 
			
		||||
func BuildVersion() string {
 | 
			
		||||
	if buildVersion == "" {
 | 
			
		||||
		return "unknown"
 | 
			
		||||
	}
 | 
			
		||||
	return buildVersion
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ListenConn returns a listener for Yggdrasil session connections.
 | 
			
		||||
func (c *Core) ConnListen() (*Listener, error) {
 | 
			
		||||
	c.sessions.listenerMutex.Lock()
 | 
			
		||||
	defer c.sessions.listenerMutex.Unlock()
 | 
			
		||||
	if c.sessions.listener != nil {
 | 
			
		||||
		return nil, errors.New("a listener already exists")
 | 
			
		||||
	}
 | 
			
		||||
	c.sessions.listener = &Listener{
 | 
			
		||||
		core:  c,
 | 
			
		||||
		conn:  make(chan *Conn),
 | 
			
		||||
		close: make(chan interface{}),
 | 
			
		||||
	}
 | 
			
		||||
	return c.sessions.listener, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ConnDialer returns a dialer for Yggdrasil session connections.
 | 
			
		||||
func (c *Core) ConnDialer() (*Dialer, error) {
 | 
			
		||||
	return &Dialer{
 | 
			
		||||
		core: c,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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) {
 | 
			
		||||
	return c.link.tcp.listen(uri)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewEncryptionKeys generates a new encryption keypair. The encryption keys are
 | 
			
		||||
// used to encrypt traffic and to derive the IPv6 address/subnet of the node.
 | 
			
		||||
func (c *Core) NewEncryptionKeys() (*crypto.BoxPubKey, *crypto.BoxPrivKey) {
 | 
			
		||||
	return crypto.NewBoxKeys()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSigningKeys generates a new signing keypair. The signing keys are used to
 | 
			
		||||
// derive the structure of the spanning tree.
 | 
			
		||||
func (c *Core) NewSigningKeys() (*crypto.SigPubKey, *crypto.SigPrivKey) {
 | 
			
		||||
	return crypto.NewSigKeys()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NodeID gets the node ID.
 | 
			
		||||
func (c *Core) NodeID() *crypto.NodeID {
 | 
			
		||||
	return crypto.GetNodeID(&c.boxPub)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TreeID gets the tree ID.
 | 
			
		||||
func (c *Core) TreeID() *crypto.TreeID {
 | 
			
		||||
	return crypto.GetTreeID(&c.sigPub)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SigPubKey gets the node's signing public key.
 | 
			
		||||
func (c *Core) SigPubKey() string {
 | 
			
		||||
	return hex.EncodeToString(c.sigPub[:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BoxPubKey gets the node's encryption public key.
 | 
			
		||||
func (c *Core) BoxPubKey() string {
 | 
			
		||||
	return hex.EncodeToString(c.boxPub[:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Address gets the IPv6 address of the Yggdrasil node. This is always a /128
 | 
			
		||||
// address.
 | 
			
		||||
func (c *Core) Address() *net.IP {
 | 
			
		||||
	address := net.IP(address.AddrForNodeID(c.NodeID())[:])
 | 
			
		||||
	return &address
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Subnet gets the routed IPv6 subnet of the Yggdrasil node. This is always a
 | 
			
		||||
// /64 subnet.
 | 
			
		||||
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)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RouterAddresses returns the raw address and subnet types as used by the
 | 
			
		||||
// router
 | 
			
		||||
func (c *Core) RouterAddresses() (address.Address, address.Subnet) {
 | 
			
		||||
	return c.router.addr, c.router.subnet
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NodeInfo gets the currently configured nodeinfo.
 | 
			
		||||
func (c *Core) NodeInfo() nodeinfoPayload {
 | 
			
		||||
	return c.router.nodeinfo.getNodeInfo()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetNodeInfo the lcal nodeinfo. Note that nodeinfo can be any value or struct,
 | 
			
		||||
// it will be serialised into JSON automatically.
 | 
			
		||||
func (c *Core) SetNodeInfo(nodeinfo interface{}, nodeinfoprivacy bool) {
 | 
			
		||||
	c.router.nodeinfo.setNodeInfo(nodeinfo, nodeinfoprivacy)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetLogger sets the output logger of the Yggdrasil node after startup. This
 | 
			
		||||
// may be useful if you want to redirect the output later.
 | 
			
		||||
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 {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	c.config.Mutex.Lock()
 | 
			
		||||
	if sintf == "" {
 | 
			
		||||
		c.config.Current.Peers = append(c.config.Current.Peers, addr)
 | 
			
		||||
	} else {
 | 
			
		||||
		c.config.Current.InterfacePeers[sintf] = append(c.config.Current.InterfacePeers[sintf], addr)
 | 
			
		||||
	}
 | 
			
		||||
	c.config.Mutex.Unlock()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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 {
 | 
			
		||||
	return c.link.call(addr, sintf)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddAllowedEncryptionPublicKey adds an allowed public key. This allow peerings
 | 
			
		||||
// to be restricted only to keys that you have selected.
 | 
			
		||||
func (c *Core) AddAllowedEncryptionPublicKey(boxStr string) error {
 | 
			
		||||
	return c.admin.addAllowedEncryptionPublicKey(boxStr)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,14 +2,11 @@ package yggdrasil
 | 
			
		|||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/hex"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/gologme/log"
 | 
			
		||||
 | 
			
		||||
	"github.com/yggdrasil-network/yggdrasil-go/src/address"
 | 
			
		||||
	"github.com/yggdrasil-network/yggdrasil-go/src/config"
 | 
			
		||||
	"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -147,24 +144,6 @@ func (c *Core) UpdateConfig(config *config.NodeConfig) {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BuildName gets the current build name. This is usually injected if built
 | 
			
		||||
// from git, or returns "unknown" otherwise.
 | 
			
		||||
func BuildName() string {
 | 
			
		||||
	if buildName == "" {
 | 
			
		||||
		return "unknown"
 | 
			
		||||
	}
 | 
			
		||||
	return buildName
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BuildVersion gets the current build version. This is usually injected if
 | 
			
		||||
// built from git, or returns "unknown" otherwise.
 | 
			
		||||
func BuildVersion() string {
 | 
			
		||||
	if buildVersion == "" {
 | 
			
		||||
		return "unknown"
 | 
			
		||||
	}
 | 
			
		||||
	return buildVersion
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Start starts up Yggdrasil using the provided config.NodeConfig, and outputs
 | 
			
		||||
// debug logging through the provided log.Logger. The started stack will include
 | 
			
		||||
// TCP and UDP sockets, a multicast discovery socket, an admin socket, router,
 | 
			
		||||
| 
						 | 
				
			
			@ -226,137 +205,3 @@ func (c *Core) Stop() {
 | 
			
		|||
	c.log.Infoln("Stopping...")
 | 
			
		||||
	c.admin.close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ListenConn returns a listener for Yggdrasil session connections.
 | 
			
		||||
func (c *Core) ConnListen() (*Listener, error) {
 | 
			
		||||
	c.sessions.listenerMutex.Lock()
 | 
			
		||||
	defer c.sessions.listenerMutex.Unlock()
 | 
			
		||||
	if c.sessions.listener != nil {
 | 
			
		||||
		return nil, errors.New("a listener already exists")
 | 
			
		||||
	}
 | 
			
		||||
	c.sessions.listener = &Listener{
 | 
			
		||||
		core:  c,
 | 
			
		||||
		conn:  make(chan *Conn),
 | 
			
		||||
		close: make(chan interface{}),
 | 
			
		||||
	}
 | 
			
		||||
	return c.sessions.listener, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ConnDialer returns a dialer for Yggdrasil session connections.
 | 
			
		||||
func (c *Core) ConnDialer() (*Dialer, error) {
 | 
			
		||||
	return &Dialer{
 | 
			
		||||
		core: c,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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) {
 | 
			
		||||
	return c.link.tcp.listen(uri)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewEncryptionKeys generates a new encryption keypair. The encryption keys are
 | 
			
		||||
// used to encrypt traffic and to derive the IPv6 address/subnet of the node.
 | 
			
		||||
func (c *Core) NewEncryptionKeys() (*crypto.BoxPubKey, *crypto.BoxPrivKey) {
 | 
			
		||||
	return crypto.NewBoxKeys()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSigningKeys generates a new signing keypair. The signing keys are used to
 | 
			
		||||
// derive the structure of the spanning tree.
 | 
			
		||||
func (c *Core) NewSigningKeys() (*crypto.SigPubKey, *crypto.SigPrivKey) {
 | 
			
		||||
	return crypto.NewSigKeys()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NodeID gets the node ID.
 | 
			
		||||
func (c *Core) NodeID() *crypto.NodeID {
 | 
			
		||||
	return crypto.GetNodeID(&c.boxPub)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TreeID gets the tree ID.
 | 
			
		||||
func (c *Core) TreeID() *crypto.TreeID {
 | 
			
		||||
	return crypto.GetTreeID(&c.sigPub)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SigPubKey gets the node's signing public key.
 | 
			
		||||
func (c *Core) SigPubKey() string {
 | 
			
		||||
	return hex.EncodeToString(c.sigPub[:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BoxPubKey gets the node's encryption public key.
 | 
			
		||||
func (c *Core) BoxPubKey() string {
 | 
			
		||||
	return hex.EncodeToString(c.boxPub[:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Address gets the IPv6 address of the Yggdrasil node. This is always a /128
 | 
			
		||||
// address.
 | 
			
		||||
func (c *Core) Address() *net.IP {
 | 
			
		||||
	address := net.IP(address.AddrForNodeID(c.NodeID())[:])
 | 
			
		||||
	return &address
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Subnet gets the routed IPv6 subnet of the Yggdrasil node. This is always a
 | 
			
		||||
// /64 subnet.
 | 
			
		||||
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)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RouterAddresses returns the raw address and subnet types as used by the
 | 
			
		||||
// router
 | 
			
		||||
func (c *Core) RouterAddresses() (address.Address, address.Subnet) {
 | 
			
		||||
	return c.router.addr, c.router.subnet
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NodeInfo gets the currently configured nodeinfo.
 | 
			
		||||
func (c *Core) NodeInfo() nodeinfoPayload {
 | 
			
		||||
	return c.router.nodeinfo.getNodeInfo()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetNodeInfo the lcal nodeinfo. Note that nodeinfo can be any value or struct,
 | 
			
		||||
// it will be serialised into JSON automatically.
 | 
			
		||||
func (c *Core) SetNodeInfo(nodeinfo interface{}, nodeinfoprivacy bool) {
 | 
			
		||||
	c.router.nodeinfo.setNodeInfo(nodeinfo, nodeinfoprivacy)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetLogger sets the output logger of the Yggdrasil node after startup. This
 | 
			
		||||
// may be useful if you want to redirect the output later.
 | 
			
		||||
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 {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	c.config.Mutex.Lock()
 | 
			
		||||
	if sintf == "" {
 | 
			
		||||
		c.config.Current.Peers = append(c.config.Current.Peers, addr)
 | 
			
		||||
	} else {
 | 
			
		||||
		c.config.Current.InterfacePeers[sintf] = append(c.config.Current.InterfacePeers[sintf], addr)
 | 
			
		||||
	}
 | 
			
		||||
	c.config.Mutex.Unlock()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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 {
 | 
			
		||||
	return c.link.call(addr, sintf)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddAllowedEncryptionPublicKey adds an allowed public key. This allow peerings
 | 
			
		||||
// to be restricted only to keys that you have selected.
 | 
			
		||||
func (c *Core) AddAllowedEncryptionPublicKey(boxStr string) error {
 | 
			
		||||
	return c.admin.addAllowedEncryptionPublicKey(boxStr)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue