mirror of
https://github.com/yggdrasil-network/yggdrasil-go
synced 2024-11-10 07:20:39 +03:00
add version metadata to key exchange at the start of connections
This commit is contained in:
parent
f5c850f098
commit
8733099516
@ -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…
Reference in New Issue
Block a user