mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 11:15:07 +03:00 
			
		
		
		
	add version metadata to key exchange at the start of connections
This commit is contained in:
		
							parent
							
								
									f5c850f098
								
							
						
					
					
						commit
						8733099516
					
				
					 1 changed files with 30 additions and 12 deletions
				
			
		| 
						 | 
				
			
			@ -10,6 +10,10 @@ package yggdrasil
 | 
			
		|||
//  Could be used to DoS (connect, give someone else's keys, spew garbage)
 | 
			
		||||
//  I guess the "peer" part should watch for link packets, disconnect?
 | 
			
		||||
 | 
			
		||||
// TCP connections start with a metadata exchange.
 | 
			
		||||
//  It involves exchanging version numbers and crypto keys
 | 
			
		||||
//  See version.go for version metadata format
 | 
			
		||||
 | 
			
		||||
import "net"
 | 
			
		||||
import "time"
 | 
			
		||||
import "errors"
 | 
			
		||||
| 
						 | 
				
			
			@ -142,29 +146,43 @@ func (iface *tcpInterface) handler(sock net.Conn, incoming bool) {
 | 
			
		|||
	defer sock.Close()
 | 
			
		||||
	// Get our keys
 | 
			
		||||
	myLinkPub, myLinkPriv := newBoxKeys() // ephemeral link keys
 | 
			
		||||
	keys := []byte{}
 | 
			
		||||
	keys = append(keys, tcp_key[:]...)
 | 
			
		||||
	keys = append(keys, iface.core.boxPub[:]...)
 | 
			
		||||
	keys = append(keys, iface.core.sigPub[:]...)
 | 
			
		||||
	keys = append(keys, myLinkPub[:]...)
 | 
			
		||||
	_, err := sock.Write(keys)
 | 
			
		||||
	meta := version_getBaseMetadata()
 | 
			
		||||
	meta.box = iface.core.boxPub
 | 
			
		||||
	meta.sig = iface.core.sigPub
 | 
			
		||||
	meta.link = *myLinkPub
 | 
			
		||||
	metaBytes := meta.encode()
 | 
			
		||||
	_, err := sock.Write(metaBytes)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	timeout := time.Now().Add(6 * time.Second)
 | 
			
		||||
	sock.SetReadDeadline(timeout)
 | 
			
		||||
	n, err := sock.Read(keys)
 | 
			
		||||
	n, err := sock.Read(metaBytes)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if n < len(keys) { /*panic("Partial key packet?") ;*/
 | 
			
		||||
	if n != version_getMetaLength() {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	info := tcpInfo{} // used as a map key, so don't include ephemeral link eys
 | 
			
		||||
	var theirLinkPub boxPubKey
 | 
			
		||||
	if !tcp_chop_keys(&info.box, &info.sig, &theirLinkPub, &keys) { /*panic("Invalid key packet?") ;*/
 | 
			
		||||
	meta = version_metadata{} // Reset to zero value
 | 
			
		||||
	if !meta.decode(metaBytes) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if !meta.check() {
 | 
			
		||||
		base := version_getBaseMetadata()
 | 
			
		||||
		if meta.meta == base.meta {
 | 
			
		||||
			if meta.ver > base.ver {
 | 
			
		||||
				iface.core.log.Println("Failed to connect to node:", sock.RemoteAddr().String(), "version:", meta.ver)
 | 
			
		||||
			} else if meta.ver == base.ver && meta.minorVer > base.minorVer {
 | 
			
		||||
				iface.core.log.Println("Failed to connect to node:", sock.RemoteAddr().String(), "version:", fmt.Sprintf("%d.%d", meta.ver, meta.minorVer))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	info := tcpInfo{ // used as a map key, so don't include ephemeral link key
 | 
			
		||||
		box: meta.box,
 | 
			
		||||
		sig: meta.sig,
 | 
			
		||||
	}
 | 
			
		||||
	// Quit the parent call if this is a connection to ourself
 | 
			
		||||
	equiv := func(k1, k2 []byte) bool {
 | 
			
		||||
		for idx := range k1 {
 | 
			
		||||
| 
						 | 
				
			
			@ -210,7 +228,7 @@ func (iface *tcpInterface) handler(sock net.Conn, incoming bool) {
 | 
			
		|||
	}()
 | 
			
		||||
	// Note that multiple connections to the same node are allowed
 | 
			
		||||
	//  E.g. over different interfaces
 | 
			
		||||
	p := iface.core.peers.newPeer(&info.box, &info.sig, getSharedKey(myLinkPriv, &theirLinkPub))
 | 
			
		||||
	p := iface.core.peers.newPeer(&info.box, &info.sig, getSharedKey(myLinkPriv, &meta.link))
 | 
			
		||||
	p.linkOut = make(chan []byte, 1)
 | 
			
		||||
	in := func(bs []byte) {
 | 
			
		||||
		p.handlePacket(bs)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue