yggdrasil-go/src/yggdrasil/api.go

114 lines
2.5 KiB
Go
Raw Normal View History

2019-04-18 18:38:24 +03:00
package yggdrasil
import (
"encoding/hex"
"errors"
"time"
"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
)
func (c *Core) Dial(network, address string) (Conn, error) {
var nodeID *crypto.NodeID
var nodeMask *crypto.NodeID
// Process
switch network {
case "nodeid":
// A node ID was provided - we don't need to do anything special with it
dest, err := hex.DecodeString(address)
if err != nil {
return Conn{}, err
}
copy(nodeID[:], dest)
var m crypto.NodeID
for i := range dest {
m[i] = 0xFF
}
copy(nodeMask[:], m[:])
default:
// An unexpected address type was given, so give up
return Conn{}, errors.New("unexpected address type")
}
// Try and search for the node on the network
doSearch := func() {
sinfo, isIn := c.searches.searches[*nodeID]
if !isIn {
sinfo = c.searches.newIterSearch(nodeID, nodeMask)
}
c.searches.continueSearch(sinfo)
}
var sinfo *sessionInfo
var isIn bool
switch {
case !isIn || !sinfo.init:
// No or unintiialized session, so we need to search first
doSearch()
case time.Since(sinfo.time) > 6*time.Second:
if sinfo.time.Before(sinfo.pingTime) && time.Since(sinfo.pingTime) > 6*time.Second {
// We haven't heard from the dest in a while
// We tried pinging but didn't get a response
// They may have changed coords
// Try searching to discover new coords
// Note that search spam is throttled internally
doSearch()
} else {
// We haven't heard about the dest in a while
now := time.Now()
if !sinfo.time.Before(sinfo.pingTime) {
// Update pingTime to start the clock for searches (above)
sinfo.pingTime = now
}
if time.Since(sinfo.pingSend) > time.Second {
// Send at most 1 ping per second
sinfo.pingSend = now
c.sessions.sendPingPong(sinfo, false)
}
}
}
return Conn{
session: sinfo,
}, nil
}
type Conn struct {
session *sessionInfo
readDeadline time.Time
writeDeadline time.Time
}
func (c *Conn) Read(b []byte) (int, error) {
return 0, nil
}
func (c *Conn) Write(b []byte) (int, error) {
return 0, nil
}
func (c *Conn) Close() error {
return nil
}
func (c *Conn) LocalAddr() crypto.NodeID {
return *crypto.GetNodeID(&c.session.core.boxPub)
}
func (c *Conn) RemoteAddr() crypto.NodeID {
return *crypto.GetNodeID(&c.session.theirPermPub)
}
func (c *Conn) SetDeadline(t time.Time) error {
c.SetReadDeadline(t)
c.SetWriteDeadline(t)
return nil
}
func (c *Conn) SetReadDeadline(t time.Time) error {
c.readDeadline = t
return nil
}
func (c *Conn) SetWriteDeadline(t time.Time) error {
c.writeDeadline = t
return nil
}