mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-05 03:22:13 +00:00
add handshakeTimeout, bound chunkLength, comments
This commit is contained in:
parent
002d7c5475
commit
ba70bffa23
@ -1,5 +1,8 @@
|
|||||||
// Uses nacl's secret_box to encrypt a net.Conn.
|
// Uses nacl's secret_box to encrypt a net.Conn.
|
||||||
// It is (meant to be) an implementation of the STS protocol.
|
// It is (meant to be) an implementation of the STS protocol.
|
||||||
|
// Note we do not (yet) assume that a remote peer's pubkey
|
||||||
|
// is known ahead of time, and thus we are technically
|
||||||
|
// still vulnerable to MITM. (TODO!)
|
||||||
// See docs/sts-final.pdf for more info
|
// See docs/sts-final.pdf for more info
|
||||||
package p2p
|
package p2p
|
||||||
|
|
||||||
@ -11,7 +14,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/Godeps/_workspace/src/golang.org/x/crypto/nacl/box"
|
"github.com/tendermint/tendermint/Godeps/_workspace/src/golang.org/x/crypto/nacl/box"
|
||||||
@ -51,6 +53,8 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey acm.PrivKeyEd25519
|
|||||||
locEphPub, locEphPriv := genEphKeys()
|
locEphPub, locEphPriv := genEphKeys()
|
||||||
|
|
||||||
// Write local ephemeral pubkey and receive one too.
|
// Write local ephemeral pubkey and receive one too.
|
||||||
|
// NOTE: every 32-byte string is accepted as a Curve25519 public key
|
||||||
|
// (see DJB's Curve25519 paper: http://cr.yp.to/ecdh/curve25519-20060209.pdf)
|
||||||
remEphPub, err := shareEphPubKey(conn, locEphPub)
|
remEphPub, err := shareEphPubKey(conn, locEphPub)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -158,7 +162,10 @@ func (sc *SecretConnection) Read(data []byte) (n int, err error) {
|
|||||||
incr2Nonce(sc.recvNonce)
|
incr2Nonce(sc.recvNonce)
|
||||||
// end decryption
|
// end decryption
|
||||||
|
|
||||||
var chunkLength = binary.BigEndian.Uint16(frame)
|
var chunkLength = binary.BigEndian.Uint16(frame) // read the first two bytes
|
||||||
|
if chunkLength > dataMaxSize {
|
||||||
|
return 0, errors.New("chunkLength is greater than dataMaxSize")
|
||||||
|
}
|
||||||
var chunk = frame[dataLenSize : dataLenSize+chunkLength]
|
var chunk = frame[dataLenSize : dataLenSize+chunkLength]
|
||||||
|
|
||||||
n = copy(data, chunk)
|
n = copy(data, chunk)
|
||||||
@ -189,21 +196,17 @@ func genEphKeys() (ephPub, ephPriv *[32]byte) {
|
|||||||
|
|
||||||
func shareEphPubKey(conn io.ReadWriteCloser, locEphPub *[32]byte) (remEphPub *[32]byte, err error) {
|
func shareEphPubKey(conn io.ReadWriteCloser, locEphPub *[32]byte) (remEphPub *[32]byte, err error) {
|
||||||
var err1, err2 error
|
var err1, err2 error
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(2)
|
|
||||||
|
|
||||||
go func() {
|
Parallel(
|
||||||
defer wg.Done()
|
func() {
|
||||||
_, err1 = conn.Write(locEphPub[:])
|
_, err1 = conn.Write(locEphPub[:])
|
||||||
}()
|
},
|
||||||
|
func() {
|
||||||
|
remEphPub = new([32]byte)
|
||||||
|
_, err2 = io.ReadFull(conn, remEphPub[:])
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
remEphPub = new([32]byte)
|
|
||||||
_, err2 = io.ReadFull(conn, remEphPub[:])
|
|
||||||
}()
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
return nil, err1
|
return nil, err1
|
||||||
}
|
}
|
||||||
@ -271,6 +274,7 @@ func shareAuthSignature(sc *SecretConnection, pubKey acm.PubKeyEd25519, signatur
|
|||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
// NOTE relies on atomicity of small data.
|
// NOTE relies on atomicity of small data.
|
||||||
|
// XXX: isn't dataMaxSize twice the size of authSigMessage?
|
||||||
readBuffer := make([]byte, dataMaxSize)
|
readBuffer := make([]byte, dataMaxSize)
|
||||||
_, err2 = sc.Read(readBuffer)
|
_, err2 = sc.Read(readBuffer)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
|
@ -59,8 +59,9 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
peerDialTimeoutSeconds = 3 // TODO make this configurable
|
peerDialTimeoutSeconds = 3 // TODO make this configurable
|
||||||
maxNumPeers = 50 // TODO make this configurable
|
handshakeTimeoutSeconds = 5 // TODO make this configurable
|
||||||
|
maxNumPeers = 50 // TODO make this configurable
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewSwitch() *Switch {
|
func NewSwitch() *Switch {
|
||||||
@ -177,9 +178,13 @@ func (sw *Switch) Stop() {
|
|||||||
// NOTE: This performs a blocking handshake before the peer is added.
|
// NOTE: This performs a blocking handshake before the peer is added.
|
||||||
// CONTRACT: Iff error is returned, peer is nil, and conn is immediately closed.
|
// CONTRACT: Iff error is returned, peer is nil, and conn is immediately closed.
|
||||||
func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, error) {
|
func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, error) {
|
||||||
|
// Set deadline so we don't block forever on conn.ReadFull
|
||||||
|
conn.SetDeadline(time.Now().Add(handshakeTimeoutSeconds * time.Second))
|
||||||
|
|
||||||
// First, encrypt the connection.
|
// First, encrypt the connection.
|
||||||
sconn, err := MakeSecretConnection(conn, sw.nodePrivKey)
|
sconn, err := MakeSecretConnection(conn, sw.nodePrivKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
conn.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Then, perform node handshake
|
// Then, perform node handshake
|
||||||
@ -205,9 +210,8 @@ func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, er
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// The peerNodeInfo is not verified, so overwrite.
|
// The peerNodeInfo is not verified, so overwrite
|
||||||
// Overwrite the IP with that from the conn
|
// the IP, and the port too if we dialed out
|
||||||
// and if we dialed out, the port too
|
|
||||||
// Everything else we just have to trust
|
// Everything else we just have to trust
|
||||||
ip, port, _ := net.SplitHostPort(sconn.RemoteAddr().String())
|
ip, port, _ := net.SplitHostPort(sconn.RemoteAddr().String())
|
||||||
peerNodeInfo.Host = ip
|
peerNodeInfo.Host = ip
|
||||||
|
Loading…
x
Reference in New Issue
Block a user