mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-12-23 16:55:40 +00: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
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 (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
|
||||||
"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/config"
|
"github.com/yggdrasil-network/yggdrasil-go/src/config"
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
|
"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
|
// Start starts up Yggdrasil using the provided config.NodeConfig, and outputs
|
||||||
// debug logging through the provided log.Logger. The started stack will include
|
// debug logging through the provided log.Logger. The started stack will include
|
||||||
// TCP and UDP sockets, a multicast discovery socket, an admin socket, router,
|
// 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.log.Infoln("Stopping...")
|
||||||
c.admin.close()
|
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…
Reference in New Issue
Block a user