mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	Merge branch 'descriptive' into metadata
This commit is contained in:
		
						commit
						6200136fce
					
				
					 11 changed files with 219 additions and 50 deletions
				
			
		| 
						 | 
					@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue