Experiment with new API

This commit is contained in:
Neil Alexander 2019-04-18 16:38:24 +01:00
parent 24fa8355f1
commit eef2a02d0a
No known key found for this signature in database
GPG Key ID: A02A2019A2BB0944
2 changed files with 122 additions and 0 deletions

View File

@ -13,6 +13,7 @@ It also defines NodeID and TreeID as hashes of keys, and wraps hash functions
import ( import (
"crypto/rand" "crypto/rand"
"crypto/sha512" "crypto/sha512"
"encoding/hex"
"golang.org/x/crypto/ed25519" "golang.org/x/crypto/ed25519"
"golang.org/x/crypto/nacl/box" "golang.org/x/crypto/nacl/box"
@ -32,6 +33,14 @@ type NodeID [NodeIDLen]byte
type TreeID [TreeIDLen]byte type TreeID [TreeIDLen]byte
type Handle [handleLen]byte type Handle [handleLen]byte
func (n *NodeID) String() string {
return hex.EncodeToString(n[:])
}
func (n *NodeID) Network() string {
return "nodeid"
}
func GetNodeID(pub *BoxPubKey) *NodeID { func GetNodeID(pub *BoxPubKey) *NodeID {
h := sha512.Sum512(pub[:]) h := sha512.Sum512(pub[:])
return (*NodeID)(&h) return (*NodeID)(&h)

113
src/yggdrasil/api.go Normal file
View File

@ -0,0 +1,113 @@
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
}