mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05: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)
 | 
					//  Could be used to DoS (connect, give someone else's keys, spew garbage)
 | 
				
			||||||
//  I guess the "peer" part should watch for link packets, disconnect?
 | 
					//  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 "net"
 | 
				
			||||||
import "time"
 | 
					import "time"
 | 
				
			||||||
import "errors"
 | 
					import "errors"
 | 
				
			||||||
| 
						 | 
					@ -142,29 +146,43 @@ func (iface *tcpInterface) handler(sock net.Conn, incoming bool) {
 | 
				
			||||||
	defer sock.Close()
 | 
						defer sock.Close()
 | 
				
			||||||
	// Get our keys
 | 
						// Get our keys
 | 
				
			||||||
	myLinkPub, myLinkPriv := newBoxKeys() // ephemeral link keys
 | 
						myLinkPub, myLinkPriv := newBoxKeys() // ephemeral link keys
 | 
				
			||||||
	keys := []byte{}
 | 
						meta := version_getBaseMetadata()
 | 
				
			||||||
	keys = append(keys, tcp_key[:]...)
 | 
						meta.box = iface.core.boxPub
 | 
				
			||||||
	keys = append(keys, iface.core.boxPub[:]...)
 | 
						meta.sig = iface.core.sigPub
 | 
				
			||||||
	keys = append(keys, iface.core.sigPub[:]...)
 | 
						meta.link = *myLinkPub
 | 
				
			||||||
	keys = append(keys, myLinkPub[:]...)
 | 
						metaBytes := meta.encode()
 | 
				
			||||||
	_, err := sock.Write(keys)
 | 
						_, err := sock.Write(metaBytes)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	timeout := time.Now().Add(6 * time.Second)
 | 
						timeout := time.Now().Add(6 * time.Second)
 | 
				
			||||||
	sock.SetReadDeadline(timeout)
 | 
						sock.SetReadDeadline(timeout)
 | 
				
			||||||
	n, err := sock.Read(keys)
 | 
						n, err := sock.Read(metaBytes)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if n < len(keys) { /*panic("Partial key packet?") ;*/
 | 
						if n != version_getMetaLength() {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	info := tcpInfo{} // used as a map key, so don't include ephemeral link eys
 | 
						meta = version_metadata{} // Reset to zero value
 | 
				
			||||||
	var theirLinkPub boxPubKey
 | 
						if !meta.decode(metaBytes) {
 | 
				
			||||||
	if !tcp_chop_keys(&info.box, &info.sig, &theirLinkPub, &keys) { /*panic("Invalid key packet?") ;*/
 | 
					 | 
				
			||||||
		return
 | 
							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
 | 
						// Quit the parent call if this is a connection to ourself
 | 
				
			||||||
	equiv := func(k1, k2 []byte) bool {
 | 
						equiv := func(k1, k2 []byte) bool {
 | 
				
			||||||
		for idx := range k1 {
 | 
							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
 | 
						// 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, &theirLinkPub))
 | 
						p := iface.core.peers.newPeer(&info.box, &info.sig, getSharedKey(myLinkPriv, &meta.link))
 | 
				
			||||||
	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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue