mirror of
https://github.com/yggdrasil-network/yggdrasil-go
synced 2024-11-10 15:30:34 +03:00
Merge branch 'descriptive' into metadata
This commit is contained in:
commit
6200136fce
@ -256,6 +256,13 @@ func main() {
|
|||||||
if buildversion, ok := v.(map[string]interface{})["build_version"].(string); ok && buildversion != "unknown" {
|
if buildversion, ok := v.(map[string]interface{})["build_version"].(string); ok && buildversion != "unknown" {
|
||||||
fmt.Println("Build version:", buildversion)
|
fmt.Println("Build version:", buildversion)
|
||||||
}
|
}
|
||||||
|
if friendlyname, ok := v.(map[string]interface{})["friendly_name"].(string); ok {
|
||||||
|
if friendlyname == "" {
|
||||||
|
fmt.Println("Friendly name: (none)")
|
||||||
|
} else {
|
||||||
|
fmt.Println("Friendly name:", friendlyname)
|
||||||
|
}
|
||||||
|
}
|
||||||
fmt.Println("IPv6 address:", k)
|
fmt.Println("IPv6 address:", k)
|
||||||
if subnet, ok := v.(map[string]interface{})["subnet"].(string); ok {
|
if subnet, ok := v.(map[string]interface{})["subnet"].(string); ok {
|
||||||
fmt.Println("IPv6 subnet:", subnet)
|
fmt.Println("IPv6 subnet:", subnet)
|
||||||
|
@ -2,6 +2,7 @@ package config
|
|||||||
|
|
||||||
// NodeConfig defines all configuration values needed to run a signle yggdrasil node
|
// NodeConfig defines all configuration values needed to run a signle yggdrasil node
|
||||||
type NodeConfig struct {
|
type NodeConfig struct {
|
||||||
|
Metadata Metadata `comment:"Optional node metadata. Entirely optional but visible to all\npeers and nodes with open sessions."`
|
||||||
Listen string `comment:"Listen address for peer connections. Default is to listen for all\nTCP connections over IPv4 and IPv6 with a random port."`
|
Listen string `comment:"Listen address for peer connections. Default is to listen for all\nTCP connections over IPv4 and IPv6 with a random port."`
|
||||||
AdminListen string `comment:"Listen address for admin connections. Default is to listen for local\nconnections either on TCP/9001 or a UNIX socket depending on your\nplatform. Use this value for yggdrasilctl -endpoint=X. To disable\nthe admin socket, use the value \"none\" instead."`
|
AdminListen string `comment:"Listen address for admin connections. Default is to listen for local\nconnections either on TCP/9001 or a UNIX socket depending on your\nplatform. Use this value for yggdrasilctl -endpoint=X. To disable\nthe admin socket, use the value \"none\" instead."`
|
||||||
Peers []string `comment:"List of connection strings for static peers in URI format, e.g.\ntcp://a.b.c.d:e or socks://a.b.c.d:e/f.g.h.i:j."`
|
Peers []string `comment:"List of connection strings for static peers in URI format, e.g.\ntcp://a.b.c.d:e or socks://a.b.c.d:e/f.g.h.i:j."`
|
||||||
@ -51,3 +52,10 @@ type TunnelRouting struct {
|
|||||||
type SwitchOptions struct {
|
type SwitchOptions struct {
|
||||||
MaxTotalQueueSize uint64 `comment:"Maximum size of all switch queues combined (in bytes)."`
|
MaxTotalQueueSize uint64 `comment:"Maximum size of all switch queues combined (in bytes)."`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Optional metadata - format subject to change
|
||||||
|
type Metadata struct {
|
||||||
|
Name string
|
||||||
|
Location string
|
||||||
|
Contact string
|
||||||
|
}
|
||||||
|
@ -574,6 +574,9 @@ func (a *admin) getData_getSelf() *admin_nodeInfo {
|
|||||||
{"ip", a.core.GetAddress().String()},
|
{"ip", a.core.GetAddress().String()},
|
||||||
{"subnet", a.core.GetSubnet().String()},
|
{"subnet", a.core.GetSubnet().String()},
|
||||||
{"coords", fmt.Sprint(coords)},
|
{"coords", fmt.Sprint(coords)},
|
||||||
|
{"name", a.core.metadata.name},
|
||||||
|
{"location", a.core.metadata.location},
|
||||||
|
{"contact", a.core.metadata.contact},
|
||||||
}
|
}
|
||||||
if name := GetBuildName(); name != "unknown" {
|
if name := GetBuildName(); name != "unknown" {
|
||||||
self = append(self, admin_pair{"build_name", name})
|
self = append(self, admin_pair{"build_name", name})
|
||||||
|
@ -23,6 +23,7 @@ type Core struct {
|
|||||||
boxPriv boxPrivKey
|
boxPriv boxPrivKey
|
||||||
sigPub sigPubKey
|
sigPub sigPubKey
|
||||||
sigPriv sigPrivKey
|
sigPriv sigPrivKey
|
||||||
|
metadata metadata
|
||||||
switchTable switchTable
|
switchTable switchTable
|
||||||
peers peers
|
peers peers
|
||||||
sessions sessions
|
sessions sessions
|
||||||
@ -40,7 +41,8 @@ type Core struct {
|
|||||||
func (c *Core) init(bpub *boxPubKey,
|
func (c *Core) init(bpub *boxPubKey,
|
||||||
bpriv *boxPrivKey,
|
bpriv *boxPrivKey,
|
||||||
spub *sigPubKey,
|
spub *sigPubKey,
|
||||||
spriv *sigPrivKey) {
|
spriv *sigPrivKey,
|
||||||
|
metadata metadata) {
|
||||||
// TODO separate init and start functions
|
// TODO separate init and start functions
|
||||||
// Init sets up structs
|
// Init sets up structs
|
||||||
// Start launches goroutines that depend on structs being set up
|
// Start launches goroutines that depend on structs being set up
|
||||||
@ -51,6 +53,7 @@ func (c *Core) init(bpub *boxPubKey,
|
|||||||
}
|
}
|
||||||
c.boxPub, c.boxPriv = *bpub, *bpriv
|
c.boxPub, c.boxPriv = *bpub, *bpriv
|
||||||
c.sigPub, c.sigPriv = *spub, *spriv
|
c.sigPub, c.sigPriv = *spub, *spriv
|
||||||
|
c.metadata = metadata
|
||||||
c.admin.core = c
|
c.admin.core = c
|
||||||
c.searches.init(c)
|
c.searches.init(c)
|
||||||
c.dht.init(c)
|
c.dht.init(c)
|
||||||
@ -80,6 +83,11 @@ func GetBuildVersion() string {
|
|||||||
return buildVersion
|
return buildVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gets the friendly name of this node, as specified in the NodeConfig.
|
||||||
|
func (c *Core) GetMeta() metadata {
|
||||||
|
return c.metadata
|
||||||
|
}
|
||||||
|
|
||||||
// Starts up Yggdrasil using the provided NodeConfig, and outputs debug logging
|
// Starts up Yggdrasil using the provided NodeConfig, and outputs debug logging
|
||||||
// through the provided log.Logger. The started stack will include TCP and UDP
|
// through the provided log.Logger. The started stack will include TCP and UDP
|
||||||
// sockets, a multicast discovery socket, an admin socket, router, switch and
|
// sockets, a multicast discovery socket, an admin socket, router, switch and
|
||||||
@ -121,7 +129,13 @@ func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error {
|
|||||||
copy(sigPub[:], sigPubHex)
|
copy(sigPub[:], sigPubHex)
|
||||||
copy(sigPriv[:], sigPrivHex)
|
copy(sigPriv[:], sigPrivHex)
|
||||||
|
|
||||||
c.init(&boxPub, &boxPriv, &sigPub, &sigPriv)
|
meta := metadata{
|
||||||
|
name: nc.Metadata.Name,
|
||||||
|
location: nc.Metadata.Location,
|
||||||
|
contact: nc.Metadata.Contact,
|
||||||
|
}
|
||||||
|
|
||||||
|
c.init(&boxPub, &boxPriv, &sigPub, &sigPriv, meta)
|
||||||
c.admin.init(c, nc.AdminListen)
|
c.admin.init(c, nc.AdminListen)
|
||||||
|
|
||||||
if err := c.tcp.init(c, nc.Listen, nc.ReadTimeout); err != nil {
|
if err := c.tcp.init(c, nc.Listen, nc.ReadTimeout); err != nil {
|
||||||
|
@ -50,7 +50,7 @@ func StartProfiler(log *log.Logger) error {
|
|||||||
func (c *Core) Init() {
|
func (c *Core) Init() {
|
||||||
bpub, bpriv := newBoxKeys()
|
bpub, bpriv := newBoxKeys()
|
||||||
spub, spriv := newSigKeys()
|
spub, spriv := newSigKeys()
|
||||||
c.init(bpub, bpriv, spub, spriv)
|
c.init(bpub, bpriv, spub, spriv, metadata{})
|
||||||
c.switchTable.start()
|
c.switchTable.start()
|
||||||
c.router.start()
|
c.router.start()
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ func (c *Core) DEBUG_getPeers() *peers {
|
|||||||
func (ps *peers) DEBUG_newPeer(box boxPubKey, sig sigPubKey, link boxSharedKey) *peer {
|
func (ps *peers) DEBUG_newPeer(box boxPubKey, sig sigPubKey, link boxSharedKey) *peer {
|
||||||
//in <-chan []byte,
|
//in <-chan []byte,
|
||||||
//out chan<- []byte) *peer {
|
//out chan<- []byte) *peer {
|
||||||
return ps.newPeer(&box, &sig, &link, "(simulator)") //, in, out)
|
return ps.newPeer(&box, &sig, &link, "(simulator)", metadata{}) //, in, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -356,7 +356,7 @@ func (c *Core) DEBUG_init(bpub []byte,
|
|||||||
copy(boxPriv[:], bpriv)
|
copy(boxPriv[:], bpriv)
|
||||||
copy(sigPub[:], spub)
|
copy(sigPub[:], spub)
|
||||||
copy(sigPriv[:], spriv)
|
copy(sigPriv[:], spriv)
|
||||||
c.init(&boxPub, &boxPriv, &sigPub, &sigPriv)
|
c.init(&boxPub, &boxPriv, &sigPub, &sigPriv, metadata{})
|
||||||
|
|
||||||
if err := c.router.start(); err != nil {
|
if err := c.router.start(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
7
src/yggdrasil/metadata.go
Normal file
7
src/yggdrasil/metadata.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package yggdrasil
|
||||||
|
|
||||||
|
type metadata struct {
|
||||||
|
name string
|
||||||
|
location string
|
||||||
|
contact string
|
||||||
|
}
|
@ -79,30 +79,31 @@ type peer struct {
|
|||||||
bytesSent uint64 // To track bandwidth usage for getPeers
|
bytesSent uint64 // To track bandwidth usage for getPeers
|
||||||
bytesRecvd uint64 // To track bandwidth usage for getPeers
|
bytesRecvd uint64 // To track bandwidth usage for getPeers
|
||||||
// BUG: sync/atomic, 32 bit platforms need the above to be the first element
|
// BUG: sync/atomic, 32 bit platforms need the above to be the first element
|
||||||
core *Core
|
core *Core
|
||||||
port switchPort
|
port switchPort
|
||||||
box boxPubKey
|
box boxPubKey
|
||||||
sig sigPubKey
|
sig sigPubKey
|
||||||
shared boxSharedKey
|
shared boxSharedKey
|
||||||
linkShared boxSharedKey
|
linkShared boxSharedKey
|
||||||
endpoint string
|
endpoint string
|
||||||
friendlyName string
|
metadata metadata
|
||||||
firstSeen time.Time // To track uptime for getPeers
|
firstSeen time.Time // To track uptime for getPeers
|
||||||
linkOut (chan []byte) // used for protocol traffic (to bypass queues)
|
linkOut (chan []byte) // used for protocol traffic (to bypass queues)
|
||||||
doSend (chan struct{}) // tell the linkLoop to send a switchMsg
|
doSend (chan struct{}) // tell the linkLoop to send a switchMsg
|
||||||
dinfo *dhtInfo // used to keep the DHT working
|
dinfo *dhtInfo // used to keep the DHT working
|
||||||
out func([]byte) // Set up by whatever created the peers struct, used to send packets to other nodes
|
out func([]byte) // Set up by whatever created the peers struct, used to send packets to other nodes
|
||||||
close func() // Called when a peer is removed, to close the underlying connection, or via admin api
|
close func() // Called when a peer is removed, to close the underlying connection, or via admin api
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new peer with the specified box, sig, and linkShared keys, using the lowest unocupied port number.
|
// Creates a new peer with the specified box, sig, and linkShared keys, using the lowest unocupied port number.
|
||||||
func (ps *peers) newPeer(box *boxPubKey, sig *sigPubKey, linkShared *boxSharedKey, endpoint string) *peer {
|
func (ps *peers) newPeer(box *boxPubKey, sig *sigPubKey, linkShared *boxSharedKey, endpoint string, metadata metadata) *peer {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
p := peer{box: *box,
|
p := peer{box: *box,
|
||||||
sig: *sig,
|
sig: *sig,
|
||||||
shared: *getSharedKey(&ps.core.boxPriv, box),
|
shared: *getSharedKey(&ps.core.boxPriv, box),
|
||||||
linkShared: *linkShared,
|
linkShared: *linkShared,
|
||||||
endpoint: endpoint,
|
endpoint: endpoint,
|
||||||
|
metadata: metadata,
|
||||||
firstSeen: now,
|
firstSeen: now,
|
||||||
doSend: make(chan struct{}, 1),
|
doSend: make(chan struct{}, 1),
|
||||||
core: ps.core}
|
core: ps.core}
|
||||||
|
@ -58,7 +58,7 @@ func (r *router) init(core *Core) {
|
|||||||
r.addr = *address_addrForNodeID(&r.core.dht.nodeID)
|
r.addr = *address_addrForNodeID(&r.core.dht.nodeID)
|
||||||
r.subnet = *address_subnetForNodeID(&r.core.dht.nodeID)
|
r.subnet = *address_subnetForNodeID(&r.core.dht.nodeID)
|
||||||
in := make(chan []byte, 32) // TODO something better than this...
|
in := make(chan []byte, 32) // TODO something better than this...
|
||||||
p := r.core.peers.newPeer(&r.core.boxPub, &r.core.sigPub, &boxSharedKey{}, "(self)")
|
p := r.core.peers.newPeer(&r.core.boxPub, &r.core.sigPub, &boxSharedKey{}, "(self)", r.core.metadata)
|
||||||
p.out = func(packet []byte) {
|
p.out = func(packet []byte) {
|
||||||
// This is to make very sure it never blocks
|
// This is to make very sure it never blocks
|
||||||
select {
|
select {
|
||||||
@ -428,6 +428,10 @@ func (r *router) handleProto(packet []byte) {
|
|||||||
r.handlePing(bs, &p.FromKey)
|
r.handlePing(bs, &p.FromKey)
|
||||||
case wire_SessionPong:
|
case wire_SessionPong:
|
||||||
r.handlePong(bs, &p.FromKey)
|
r.handlePong(bs, &p.FromKey)
|
||||||
|
case wire_SessionMetaRequest:
|
||||||
|
fallthrough
|
||||||
|
case wire_SessionMetaResponse:
|
||||||
|
r.handleMeta(bs, &p.FromKey)
|
||||||
case wire_DHTLookupRequest:
|
case wire_DHTLookupRequest:
|
||||||
r.handleDHTReq(bs, &p.FromKey)
|
r.handleDHTReq(bs, &p.FromKey)
|
||||||
case wire_DHTLookupResponse:
|
case wire_DHTLookupResponse:
|
||||||
@ -472,6 +476,17 @@ func (r *router) handleDHTRes(bs []byte, fromKey *boxPubKey) {
|
|||||||
r.core.dht.handleRes(&res)
|
r.core.dht.handleRes(&res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decodes meta request
|
||||||
|
func (r *router) handleMeta(bs []byte, fromKey *boxPubKey) {
|
||||||
|
req := sessionMeta{}
|
||||||
|
if !req.decode(bs) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.SendPermPub = *fromKey
|
||||||
|
r.core.log.Printf("handleMeta: %+v\n", req)
|
||||||
|
r.core.sessions.handleMeta(&req)
|
||||||
|
}
|
||||||
|
|
||||||
// Passed a function to call.
|
// Passed a function to call.
|
||||||
// This will send the function to r.admin and block until it finishes.
|
// This will send the function to r.admin and block until it finishes.
|
||||||
// It's used by the admin socket to ask the router mainLoop goroutine about information in the session or dht structs, which cannot be read safely from outside that goroutine.
|
// It's used by the admin socket to ask the router mainLoop goroutine about information in the session or dht structs, which cannot be read safely from outside that goroutine.
|
||||||
|
@ -13,34 +13,37 @@ import (
|
|||||||
// All the information we know about an active session.
|
// All the information we know about an active session.
|
||||||
// This includes coords, permanent and ephemeral keys, handles and nonces, various sorts of timing information for timeout and maintenance, and some metadata for the admin API.
|
// This includes coords, permanent and ephemeral keys, handles and nonces, various sorts of timing information for timeout and maintenance, and some metadata for the admin API.
|
||||||
type sessionInfo struct {
|
type sessionInfo struct {
|
||||||
core *Core
|
core *Core
|
||||||
theirAddr address
|
theirAddr address
|
||||||
theirSubnet subnet
|
theirSubnet subnet
|
||||||
theirPermPub boxPubKey
|
theirPermPub boxPubKey
|
||||||
theirSesPub boxPubKey
|
theirSesPub boxPubKey
|
||||||
mySesPub boxPubKey
|
mySesPub boxPubKey
|
||||||
mySesPriv boxPrivKey
|
mySesPriv boxPrivKey
|
||||||
sharedSesKey boxSharedKey // derived from session keys
|
sharedSesKey boxSharedKey // derived from session keys
|
||||||
theirHandle handle
|
theirHandle handle
|
||||||
myHandle handle
|
myHandle handle
|
||||||
theirNonce boxNonce
|
theirNonce boxNonce
|
||||||
myNonce boxNonce
|
myNonce boxNonce
|
||||||
theirMTU uint16
|
metaReqTime time.Time
|
||||||
myMTU uint16
|
metaResTime time.Time
|
||||||
wasMTUFixed bool // Was the MTU fixed by a receive error?
|
theirMetadata metadata
|
||||||
time time.Time // Time we last received a packet
|
theirMTU uint16
|
||||||
coords []byte // coords of destination
|
myMTU uint16
|
||||||
packet []byte // a buffered packet, sent immediately on ping/pong
|
wasMTUFixed bool // Was the MTU fixed by a receive error?
|
||||||
init bool // Reset if coords change
|
time time.Time // Time we last received a packet
|
||||||
send chan []byte
|
coords []byte // coords of destination
|
||||||
recv chan *wire_trafficPacket
|
packet []byte // a buffered packet, sent immediately on ping/pong
|
||||||
nonceMask uint64
|
init bool // Reset if coords change
|
||||||
tstamp int64 // tstamp from their last session ping, replay attack mitigation
|
send chan []byte
|
||||||
mtuTime time.Time // time myMTU was last changed
|
recv chan *wire_trafficPacket
|
||||||
pingTime time.Time // time the first ping was sent since the last received packet
|
nonceMask uint64
|
||||||
pingSend time.Time // time the last ping was sent
|
tstamp int64 // tstamp from their last session ping, replay attack mitigation
|
||||||
bytesSent uint64 // Bytes of real traffic sent in this session
|
mtuTime time.Time // time myMTU was last changed
|
||||||
bytesRecvd uint64 // Bytes of real traffic received in this session
|
pingTime time.Time // time the first ping was sent since the last received packet
|
||||||
|
pingSend time.Time // time the last ping was sent
|
||||||
|
bytesSent uint64 // Bytes of real traffic sent in this session
|
||||||
|
bytesRecvd uint64 // Bytes of real traffic received in this session
|
||||||
}
|
}
|
||||||
|
|
||||||
// Represents a session ping/pong packet, andincludes information like public keys, a session handle, coords, a timestamp to prevent replays, and the tun/tap MTU.
|
// Represents a session ping/pong packet, andincludes information like public keys, a session handle, coords, a timestamp to prevent replays, and the tun/tap MTU.
|
||||||
@ -54,6 +57,13 @@ type sessionPing struct {
|
|||||||
MTU uint16
|
MTU uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Represents a session metadata packet.
|
||||||
|
type sessionMeta struct {
|
||||||
|
SendPermPub boxPubKey // Sender's permanent key
|
||||||
|
IsResponse bool
|
||||||
|
Metadata metadata
|
||||||
|
}
|
||||||
|
|
||||||
// Updates session info in response to a ping, after checking that the ping is OK.
|
// Updates session info in response to a ping, after checking that the ping is OK.
|
||||||
// Returns true if the session was updated, or false otherwise.
|
// Returns true if the session was updated, or false otherwise.
|
||||||
func (s *sessionInfo) update(p *sessionPing) bool {
|
func (s *sessionInfo) update(p *sessionPing) bool {
|
||||||
@ -466,6 +476,66 @@ func (ss *sessions) handlePing(ping *sessionPing) {
|
|||||||
bs, sinfo.packet = sinfo.packet, nil
|
bs, sinfo.packet = sinfo.packet, nil
|
||||||
ss.core.router.sendPacket(bs)
|
ss.core.router.sendPacket(bs)
|
||||||
}
|
}
|
||||||
|
if time.Since(sinfo.metaResTime).Minutes() > 15 {
|
||||||
|
if time.Since(sinfo.metaReqTime).Minutes() > 1 {
|
||||||
|
ss.sendMeta(sinfo, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ss *sessions) sendMeta(sinfo *sessionInfo, isResponse bool) {
|
||||||
|
meta := sessionMeta{
|
||||||
|
IsResponse: isResponse,
|
||||||
|
Metadata: metadata{
|
||||||
|
name: "some.name.com", //[]byte(ss.core.friendlyName)[0:len(ss.core.friendlyName):32],
|
||||||
|
location: "Some Place",
|
||||||
|
contact: "someone@somewhere.com",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
bs := meta.encode()
|
||||||
|
shared := ss.getSharedKey(&ss.core.boxPriv, &sinfo.theirPermPub)
|
||||||
|
payload, nonce := boxSeal(shared, bs, nil)
|
||||||
|
p := wire_protoTrafficPacket{
|
||||||
|
Coords: sinfo.coords,
|
||||||
|
ToKey: sinfo.theirPermPub,
|
||||||
|
FromKey: ss.core.boxPub,
|
||||||
|
Nonce: *nonce,
|
||||||
|
Payload: payload,
|
||||||
|
}
|
||||||
|
packet := p.encode()
|
||||||
|
ss.core.router.out(packet)
|
||||||
|
if isResponse {
|
||||||
|
ss.core.log.Println("Sent meta response to", sinfo.theirAddr)
|
||||||
|
} else {
|
||||||
|
ss.core.log.Println("Sent meta request to", sinfo.theirAddr)
|
||||||
|
sinfo.metaReqTime = time.Now()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles a meta request/response.
|
||||||
|
func (ss *sessions) handleMeta(meta *sessionMeta) {
|
||||||
|
// Get the corresponding session (or create a new session)
|
||||||
|
sinfo, isIn := ss.getByTheirPerm(&meta.SendPermPub)
|
||||||
|
// Check the session firewall
|
||||||
|
if !isIn && ss.sessionFirewallEnabled {
|
||||||
|
if !ss.isSessionAllowed(&meta.SendPermPub, false) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !isIn || sinfo.timedout() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if meta.IsResponse {
|
||||||
|
ss.core.log.Println("Received meta response", string(meta.Metadata.name), "from", sinfo.theirAddr)
|
||||||
|
sinfo.theirMetadata = meta.Metadata
|
||||||
|
sinfo.metaResTime = time.Now()
|
||||||
|
ss.core.log.Println("- name:", meta.Metadata.name)
|
||||||
|
ss.core.log.Println("- contact:", meta.Metadata.contact)
|
||||||
|
ss.core.log.Println("- location:", meta.Metadata.location)
|
||||||
|
} else {
|
||||||
|
ss.core.log.Println("Received meta request", string(meta.Metadata.name), "from", sinfo.theirAddr)
|
||||||
|
ss.sendMeta(sinfo, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to subtract one nonce from another, staying in the range +- 64.
|
// Used to subtract one nonce from another, staying in the range +- 64.
|
||||||
|
@ -287,7 +287,7 @@ func (iface *tcpInterface) handler(sock net.Conn, incoming bool) {
|
|||||||
}()
|
}()
|
||||||
// Note that multiple connections to the same node are allowed
|
// Note that multiple connections to the same node are allowed
|
||||||
// E.g. over different interfaces
|
// E.g. over different interfaces
|
||||||
p := iface.core.peers.newPeer(&info.box, &info.sig, getSharedKey(myLinkPriv, &meta.link), sock.RemoteAddr().String())
|
p := iface.core.peers.newPeer(&info.box, &info.sig, getSharedKey(myLinkPriv, &meta.link), sock.RemoteAddr().String(), metadata{})
|
||||||
p.linkOut = make(chan []byte, 1)
|
p.linkOut = make(chan []byte, 1)
|
||||||
in := func(bs []byte) {
|
in := func(bs []byte) {
|
||||||
p.handlePacket(bs)
|
p.handlePacket(bs)
|
||||||
|
@ -16,6 +16,8 @@ const (
|
|||||||
wire_SessionPong // inside protocol traffic header
|
wire_SessionPong // inside protocol traffic header
|
||||||
wire_DHTLookupRequest // inside protocol traffic header
|
wire_DHTLookupRequest // inside protocol traffic header
|
||||||
wire_DHTLookupResponse // inside protocol traffic header
|
wire_DHTLookupResponse // inside protocol traffic header
|
||||||
|
wire_SessionMetaRequest // inside protocol traffic header
|
||||||
|
wire_SessionMetaResponse // inside protocol traffic header
|
||||||
)
|
)
|
||||||
|
|
||||||
// Calls wire_put_uint64 on a nil slice.
|
// Calls wire_put_uint64 on a nil slice.
|
||||||
@ -353,6 +355,48 @@ func (p *sessionPing) decode(bs []byte) bool {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Encodes a sessionPing into its wire format.
|
||||||
|
func (p *sessionMeta) encode() []byte {
|
||||||
|
var pTypeVal uint64
|
||||||
|
if p.IsResponse {
|
||||||
|
pTypeVal = wire_SessionMetaResponse
|
||||||
|
} else {
|
||||||
|
pTypeVal = wire_SessionMetaRequest
|
||||||
|
}
|
||||||
|
bs := wire_encode_uint64(pTypeVal)
|
||||||
|
if p.IsResponse {
|
||||||
|
bs = append(bs, p.Metadata.name...)
|
||||||
|
bs = append(bs, p.Metadata.location...)
|
||||||
|
bs = append(bs, p.Metadata.contact...)
|
||||||
|
}
|
||||||
|
return bs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decodes an encoded sessionPing into the struct, returning true if successful.
|
||||||
|
func (p *sessionMeta) decode(bs []byte) bool {
|
||||||
|
var pType uint64
|
||||||
|
switch {
|
||||||
|
case !wire_chop_uint64(&pType, &bs):
|
||||||
|
return false
|
||||||
|
case pType != wire_SessionMetaRequest && pType != wire_SessionMetaResponse:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
p.IsResponse = pType == wire_SessionMetaResponse
|
||||||
|
if p.IsResponse {
|
||||||
|
switch {
|
||||||
|
case !wire_chop_slice([]byte(p.Metadata.name), &bs):
|
||||||
|
return false
|
||||||
|
case !wire_chop_slice([]byte(p.Metadata.location), &bs):
|
||||||
|
return false
|
||||||
|
case !wire_chop_slice([]byte(p.Metadata.contact), &bs):
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Encodes a dhtReq into its wire format.
|
// Encodes a dhtReq into its wire format.
|
||||||
func (r *dhtReq) encode() []byte {
|
func (r *dhtReq) encode() []byte {
|
||||||
coords := wire_encode_coords(r.Coords)
|
coords := wire_encode_coords(r.Coords)
|
||||||
|
Loading…
Reference in New Issue
Block a user