mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-10-31 09:15:07 +03:00 
			
		
		
		
	Searches called from api.go, various other tweaks, searches now have a callback for success/failure, node ID now reported by admin socket
This commit is contained in:
		
							parent
							
								
									eef2a02d0a
								
							
						
					
					
						commit
						160e01e84f
					
				
					 7 changed files with 177 additions and 81 deletions
				
			
		|  | @ -6,11 +6,13 @@ import ( | |||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/yggdrasil-network/yggdrasil-go/src/crypto" | ||||
| 	"github.com/yggdrasil-network/yggdrasil-go/src/util" | ||||
| ) | ||||
| 
 | ||||
| func (c *Core) Dial(network, address string) (Conn, error) { | ||||
| 	var nodeID *crypto.NodeID | ||||
| 	var nodeMask *crypto.NodeID | ||||
| 	conn := Conn{} | ||||
| 	nodeID := crypto.NodeID{} | ||||
| 	nodeMask := crypto.NodeID{} | ||||
| 	// Process | ||||
| 	switch network { | ||||
| 	case "nodeid": | ||||
|  | @ -20,22 +22,51 @@ func (c *Core) Dial(network, address string) (Conn, error) { | |||
| 			return Conn{}, err | ||||
| 		} | ||||
| 		copy(nodeID[:], dest) | ||||
| 		var m crypto.NodeID | ||||
| 		for i := range dest { | ||||
| 			m[i] = 0xFF | ||||
| 		for i := range nodeMask { | ||||
| 			nodeMask[i] = 0xFF | ||||
| 		} | ||||
| 		copy(nodeMask[:], m[:]) | ||||
| 	default: | ||||
| 		// An unexpected address type was given, so give up | ||||
| 		return Conn{}, errors.New("unexpected address type") | ||||
| 	} | ||||
| 	conn.core = c | ||||
| 	conn.nodeID = &nodeID | ||||
| 	conn.nodeMask = &nodeMask | ||||
| 	conn.core.router.doAdmin(func() { | ||||
| 		conn.startSearch() | ||||
| 	}) | ||||
| 	return conn, nil | ||||
| } | ||||
| 
 | ||||
| type Conn struct { | ||||
| 	core          *Core | ||||
| 	nodeID        *crypto.NodeID | ||||
| 	nodeMask      *crypto.NodeID | ||||
| 	session       *sessionInfo | ||||
| 	readDeadline  time.Time | ||||
| 	writeDeadline time.Time | ||||
| } | ||||
| 
 | ||||
| // This method should only be called from the router goroutine | ||||
| func (c *Conn) startSearch() { | ||||
| 	searchCompleted := func(sinfo *sessionInfo, err error) { | ||||
| 		if err != nil { | ||||
| 			c.core.log.Debugln("DHT search failed:", err) | ||||
| 			return | ||||
| 		} | ||||
| 		if sinfo != nil { | ||||
| 			c.session = sinfo | ||||
| 			c.core.log.Println("Search from API found", hex.EncodeToString(sinfo.theirPermPub[:])) | ||||
| 		} | ||||
| 	} | ||||
| 	// Try and search for the node on the network | ||||
| 	doSearch := func() { | ||||
| 		sinfo, isIn := c.searches.searches[*nodeID] | ||||
| 		sinfo, isIn := c.core.searches.searches[*c.nodeID] | ||||
| 		if !isIn { | ||||
| 			sinfo = c.searches.newIterSearch(nodeID, nodeMask) | ||||
| 			c.core.log.Debugln("Starting search for", hex.EncodeToString(c.nodeID[:])) | ||||
| 			sinfo = c.core.searches.newIterSearch(c.nodeID, c.nodeMask, searchCompleted) | ||||
| 		} | ||||
| 		c.searches.continueSearch(sinfo) | ||||
| 		c.core.searches.continueSearch(sinfo) | ||||
| 	} | ||||
| 	var sinfo *sessionInfo | ||||
| 	var isIn bool | ||||
|  | @ -61,27 +92,62 @@ func (c *Core) Dial(network, address string) (Conn, error) { | |||
| 			if time.Since(sinfo.pingSend) > time.Second { | ||||
| 				// Send at most 1 ping per second | ||||
| 				sinfo.pingSend = now | ||||
| 				c.sessions.sendPingPong(sinfo, false) | ||||
| 				c.core.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 | ||||
| 	if c.session == nil { | ||||
| 		return 0, errors.New("invalid session") | ||||
| 	} | ||||
| 	p := <-c.session.recv | ||||
| 	defer util.PutBytes(p.Payload) | ||||
| 	if !c.session.nonceIsOK(&p.Nonce) { | ||||
| 		return 0, errors.New("invalid nonce") | ||||
| 	} | ||||
| 	bs, isOK := crypto.BoxOpen(&c.session.sharedSesKey, p.Payload, &p.Nonce) | ||||
| 	if !isOK { | ||||
| 		util.PutBytes(bs) | ||||
| 		return 0, errors.New("failed to decrypt") | ||||
| 	} | ||||
| 	b = b[:0] | ||||
| 	b = append(b, bs...) | ||||
| 	c.session.updateNonce(&p.Nonce) | ||||
| 	c.session.time = time.Now() | ||||
| 	c.session.bytesRecvd += uint64(len(bs)) | ||||
| 	return len(b), nil | ||||
| } | ||||
| 
 | ||||
| func (c *Conn) Write(b []byte) (int, error) { | ||||
| 	return 0, nil | ||||
| 	if c.session == nil { | ||||
| 		c.core.router.doAdmin(func() { | ||||
| 			c.startSearch() | ||||
| 		}) | ||||
| 		return 0, errors.New("invalid session") | ||||
| 	} | ||||
| 	defer util.PutBytes(b) | ||||
| 	if !c.session.init { | ||||
| 		// To prevent using empty session keys | ||||
| 		return 0, errors.New("session not initialised") | ||||
| 	} | ||||
| 	// code isn't multithreaded so appending to this is safe | ||||
| 	coords := c.session.coords | ||||
| 	// Prepare the payload | ||||
| 	payload, nonce := crypto.BoxSeal(&c.session.sharedSesKey, b, &c.session.myNonce) | ||||
| 	defer util.PutBytes(payload) | ||||
| 	p := wire_trafficPacket{ | ||||
| 		Coords:  coords, | ||||
| 		Handle:  c.session.theirHandle, | ||||
| 		Nonce:   *nonce, | ||||
| 		Payload: payload, | ||||
| 	} | ||||
| 	packet := p.encode() | ||||
| 	c.session.bytesSent += uint64(len(b)) | ||||
| 	c.session.send <- packet | ||||
| 	//c.session.core.router.out(packet) | ||||
| 	return len(b), nil | ||||
| } | ||||
| 
 | ||||
| func (c *Conn) Close() error { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Neil Alexander
						Neil Alexander