brontide/noise_test: test parallel handshakes
This commit is contained in:
parent
782a8088eb
commit
c22b46d462
@ -13,16 +13,16 @@ import (
|
|||||||
"github.com/roasbeef/btcd/btcec"
|
"github.com/roasbeef/btcd/btcec"
|
||||||
)
|
)
|
||||||
|
|
||||||
func establishTestConnection() (net.Conn, net.Conn, func(), error) {
|
type maybeNetConn struct {
|
||||||
// First, generate the long-term private keys both ends of the
|
conn net.Conn
|
||||||
// connection within our test.
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeListener() (*Listener, *lnwire.NetAddress, error) {
|
||||||
|
// First, generate the long-term private keys for the brontide listener.
|
||||||
localPriv, err := btcec.NewPrivateKey(btcec.S256())
|
localPriv, err := btcec.NewPrivateKey(btcec.S256())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, err
|
||||||
}
|
|
||||||
remotePriv, err := btcec.NewPrivateKey(btcec.S256())
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Having a port of ":0" means a random port, and interface will be
|
// Having a port of ":0" means a random port, and interface will be
|
||||||
@ -32,56 +32,62 @@ func establishTestConnection() (net.Conn, net.Conn, func(), error) {
|
|||||||
// Our listener will be local, and the connection remote.
|
// Our listener will be local, and the connection remote.
|
||||||
listener, err := NewListener(localPriv, addr)
|
listener, err := NewListener(localPriv, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
defer listener.Close()
|
|
||||||
|
|
||||||
netAddr := &lnwire.NetAddress{
|
netAddr := &lnwire.NetAddress{
|
||||||
IdentityKey: localPriv.PubKey(),
|
IdentityKey: localPriv.PubKey(),
|
||||||
Address: listener.Addr().(*net.TCPAddr),
|
Address: listener.Addr().(*net.TCPAddr),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return listener, netAddr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func establishTestConnection() (net.Conn, net.Conn, func(), error) {
|
||||||
|
listener, netAddr, err := makeListener()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
defer listener.Close()
|
||||||
|
|
||||||
|
// Nos, generate the long-term private keys remote end of the connection
|
||||||
|
// within our test.
|
||||||
|
remotePriv, err := btcec.NewPrivateKey(btcec.S256())
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// Initiate a connection with a separate goroutine, and listen with our
|
// Initiate a connection with a separate goroutine, and listen with our
|
||||||
// main one. If both errors are nil, then encryption+auth was
|
// main one. If both errors are nil, then encryption+auth was
|
||||||
// successful.
|
// successful.
|
||||||
conErrChan := make(chan error, 1)
|
remoteConnChan := make(chan maybeNetConn, 1)
|
||||||
connChan := make(chan net.Conn, 1)
|
|
||||||
go func() {
|
go func() {
|
||||||
conn, err := Dial(remotePriv, netAddr, net.Dial)
|
remoteConn, err := Dial(remotePriv, netAddr, net.Dial)
|
||||||
|
remoteConnChan <- maybeNetConn{remoteConn, err}
|
||||||
conErrChan <- err
|
|
||||||
connChan <- conn
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
lisErrChan := make(chan error, 1)
|
localConnChan := make(chan maybeNetConn, 1)
|
||||||
lisChan := make(chan net.Conn, 1)
|
|
||||||
go func() {
|
go func() {
|
||||||
localConn, listenErr := listener.Accept()
|
localConn, err := listener.Accept()
|
||||||
|
localConnChan <- maybeNetConn{localConn, err}
|
||||||
lisErrChan <- listenErr
|
|
||||||
lisChan <- localConn
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
remote := <-remoteConnChan
|
||||||
case err := <-conErrChan:
|
if remote.err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
case err := <-lisErrChan:
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
localConn := <-lisChan
|
local := <-localConnChan
|
||||||
remoteConn := <-connChan
|
if local.err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
cleanUp := func() {
|
cleanUp := func() {
|
||||||
localConn.Close()
|
local.conn.Close()
|
||||||
remoteConn.Close()
|
remote.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
return localConn, remoteConn, cleanUp, nil
|
return local.conn, remote.conn, cleanUp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnectionCorrectness(t *testing.T) {
|
func TestConnectionCorrectness(t *testing.T) {
|
||||||
@ -134,14 +140,84 @@ func TestConnectionCorrectness(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestConecurrentHandshakes verifies the listener's ability to not be blocked
|
||||||
|
// by other pending handshakes. This is tested by opening multiple tcp
|
||||||
|
// connections with the listener, without completing any of the brontide acts.
|
||||||
|
// The test passes if real brontide dialer connects while the others are
|
||||||
|
// stalled.
|
||||||
|
func TestConcurrentHandshakes(t *testing.T) {
|
||||||
|
listener, netAddr, err := makeListener()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to create listener connection: %v", err)
|
||||||
|
}
|
||||||
|
defer listener.Close()
|
||||||
|
|
||||||
|
const nblocking = 5
|
||||||
|
|
||||||
|
// Open a handful of tcp connections, that do not complete any steps of
|
||||||
|
// the brontide handshake.
|
||||||
|
connChan := make(chan maybeNetConn)
|
||||||
|
for i := 0; i < nblocking; i++ {
|
||||||
|
go func() {
|
||||||
|
conn, err := net.Dial("tcp", listener.Addr().String())
|
||||||
|
connChan <- maybeNetConn{conn, err}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive all connections/errors from our blocking tcp dials. We make a
|
||||||
|
// pass to gather all connections and errors to make sure we defer the
|
||||||
|
// calls to Close() on all successful connections.
|
||||||
|
tcpErrs := make([]error, 0, nblocking)
|
||||||
|
for i := 0; i < nblocking; i++ {
|
||||||
|
result := <-connChan
|
||||||
|
if result.conn != nil {
|
||||||
|
defer result.conn.Close()
|
||||||
|
}
|
||||||
|
if result.err != nil {
|
||||||
|
tcpErrs = append(tcpErrs, result.err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, tcpErr := range tcpErrs {
|
||||||
|
if tcpErr != nil {
|
||||||
|
t.Fatalf("unable to tcp dial listener: %v", tcpErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, construct a new private key and use the brontide dialer to
|
||||||
|
// connect to the listener.
|
||||||
|
remotePriv, err := btcec.NewPrivateKey(btcec.S256())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to generate private key: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
remoteConn, err := Dial(remotePriv, netAddr, net.Dial)
|
||||||
|
connChan <- maybeNetConn{remoteConn, err}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// This connection should be accepted without error, as the brontide
|
||||||
|
// connection should bypass stalled tcp connections.
|
||||||
|
conn, err := listener.Accept()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to accept dial: %v", err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
result := <-connChan
|
||||||
|
if result.err != nil {
|
||||||
|
t.Fatalf("unable to dial %v: %v", netAddr, result.err)
|
||||||
|
}
|
||||||
|
result.conn.Close()
|
||||||
|
}
|
||||||
|
|
||||||
func TestMaxPayloadLength(t *testing.T) {
|
func TestMaxPayloadLength(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
b := Machine{}
|
b := Machine{}
|
||||||
b.split()
|
b.split()
|
||||||
|
|
||||||
// Create a payload that's only *slightly* above the maximum allotted payload
|
// Create a payload that's only *slightly* above the maximum allotted
|
||||||
// length.
|
// payload length.
|
||||||
payloadToReject := make([]byte, math.MaxUint16+1)
|
payloadToReject := make([]byte, math.MaxUint16+1)
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
Loading…
Reference in New Issue
Block a user