mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 06:42:16 +00:00
* Adds a random suffix to temporary Unix sockets during testing * Adds Unix domain socket tests for client (FAILING) This adds Unix domain socket tests for the privval client. Right now, one of the tests (TestRemoteSignerRetry) fails, probably because the Unix domain socket state is known instantaneously on both sides by the OS. Committing this to collaborate on the error. * Removes extraneous logging * Completes testing of Unix sockets client version This completes the testing of the client connecting via Unix sockets. There are two specific tests (TestSocketPVDeadline and TestRemoteSignerRetryTCPOnly) that are only relevant to TCP connections. * Renames test to show TCP-specificity * Adds testing into closures for consistency (forgot previously) * Moves test specific to RemoteSigner into own file As per discussion on #3132, `TestRemoteSignerRetryTCPOnly` doesn't really belong with the client tests. This moves it into its own file related to the `RemoteSigner` class.
185 lines
5.0 KiB
Go
185 lines
5.0 KiB
Go
package privval
|
|
|
|
import (
|
|
"net"
|
|
"time"
|
|
|
|
"github.com/tendermint/tendermint/crypto/ed25519"
|
|
p2pconn "github.com/tendermint/tendermint/p2p/conn"
|
|
)
|
|
|
|
const (
|
|
defaultAcceptDeadlineSeconds = 3
|
|
defaultConnDeadlineSeconds = 3
|
|
)
|
|
|
|
// timeoutError can be used to check if an error returned from the netp package
|
|
// was due to a timeout.
|
|
type timeoutError interface {
|
|
Timeout() bool
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
// TCP Listener
|
|
|
|
// TCPListenerOption sets an optional parameter on the tcpListener.
|
|
type TCPListenerOption func(*tcpListener)
|
|
|
|
// TCPListenerAcceptDeadline sets the deadline for the listener.
|
|
// A zero time value disables the deadline.
|
|
func TCPListenerAcceptDeadline(deadline time.Duration) TCPListenerOption {
|
|
return func(tl *tcpListener) { tl.acceptDeadline = deadline }
|
|
}
|
|
|
|
// TCPListenerConnDeadline sets the read and write deadline for connections
|
|
// from external signing processes.
|
|
func TCPListenerConnDeadline(deadline time.Duration) TCPListenerOption {
|
|
return func(tl *tcpListener) { tl.connDeadline = deadline }
|
|
}
|
|
|
|
// tcpListener implements net.Listener.
|
|
var _ net.Listener = (*tcpListener)(nil)
|
|
|
|
// tcpListener wraps a *net.TCPListener to standardise protocol timeouts
|
|
// and potentially other tuning parameters. It also returns encrypted connections.
|
|
type tcpListener struct {
|
|
*net.TCPListener
|
|
|
|
secretConnKey ed25519.PrivKeyEd25519
|
|
|
|
acceptDeadline time.Duration
|
|
connDeadline time.Duration
|
|
}
|
|
|
|
// NewTCPListener returns a listener that accepts authenticated encrypted connections
|
|
// using the given secretConnKey and the default timeout values.
|
|
func NewTCPListener(ln net.Listener, secretConnKey ed25519.PrivKeyEd25519) *tcpListener {
|
|
return &tcpListener{
|
|
TCPListener: ln.(*net.TCPListener),
|
|
secretConnKey: secretConnKey,
|
|
acceptDeadline: time.Second * defaultAcceptDeadlineSeconds,
|
|
connDeadline: time.Second * defaultConnDeadlineSeconds,
|
|
}
|
|
}
|
|
|
|
// Accept implements net.Listener.
|
|
func (ln *tcpListener) Accept() (net.Conn, error) {
|
|
err := ln.SetDeadline(time.Now().Add(ln.acceptDeadline))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
tc, err := ln.AcceptTCP()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Wrap the conn in our timeout and encryption wrappers
|
|
timeoutConn := newTimeoutConn(tc, ln.connDeadline)
|
|
secretConn, err := p2pconn.MakeSecretConnection(timeoutConn, ln.secretConnKey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return secretConn, nil
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
// Unix Listener
|
|
|
|
// unixListener implements net.Listener.
|
|
var _ net.Listener = (*unixListener)(nil)
|
|
|
|
type UnixListenerOption func(*unixListener)
|
|
|
|
// UnixListenerAcceptDeadline sets the deadline for the listener.
|
|
// A zero time value disables the deadline.
|
|
func UnixListenerAcceptDeadline(deadline time.Duration) UnixListenerOption {
|
|
return func(ul *unixListener) { ul.acceptDeadline = deadline }
|
|
}
|
|
|
|
// UnixListenerConnDeadline sets the read and write deadline for connections
|
|
// from external signing processes.
|
|
func UnixListenerConnDeadline(deadline time.Duration) UnixListenerOption {
|
|
return func(ul *unixListener) { ul.connDeadline = deadline }
|
|
}
|
|
|
|
// unixListener wraps a *net.UnixListener to standardise protocol timeouts
|
|
// and potentially other tuning parameters. It returns unencrypted connections.
|
|
type unixListener struct {
|
|
*net.UnixListener
|
|
|
|
acceptDeadline time.Duration
|
|
connDeadline time.Duration
|
|
}
|
|
|
|
// NewUnixListener returns a listener that accepts unencrypted connections
|
|
// using the default timeout values.
|
|
func NewUnixListener(ln net.Listener) *unixListener {
|
|
return &unixListener{
|
|
UnixListener: ln.(*net.UnixListener),
|
|
acceptDeadline: time.Second * defaultAcceptDeadlineSeconds,
|
|
connDeadline: time.Second * defaultConnDeadlineSeconds,
|
|
}
|
|
}
|
|
|
|
// Accept implements net.Listener.
|
|
func (ln *unixListener) Accept() (net.Conn, error) {
|
|
err := ln.SetDeadline(time.Now().Add(ln.acceptDeadline))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
tc, err := ln.AcceptUnix()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Wrap the conn in our timeout wrapper
|
|
conn := newTimeoutConn(tc, ln.connDeadline)
|
|
|
|
// TODO: wrap in something that authenticates
|
|
// with a MAC - https://github.com/tendermint/tendermint/issues/3099
|
|
|
|
return conn, nil
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
// Connection
|
|
|
|
// timeoutConn implements net.Conn.
|
|
var _ net.Conn = (*timeoutConn)(nil)
|
|
|
|
// timeoutConn wraps a net.Conn to standardise protocol timeouts / deadline resets.
|
|
type timeoutConn struct {
|
|
net.Conn
|
|
|
|
connDeadline time.Duration
|
|
}
|
|
|
|
// newTimeoutConn returns an instance of timeoutConn.
|
|
func newTimeoutConn(
|
|
conn net.Conn,
|
|
connDeadline time.Duration) *timeoutConn {
|
|
return &timeoutConn{
|
|
conn,
|
|
connDeadline,
|
|
}
|
|
}
|
|
|
|
// Read implements net.Conn.
|
|
func (c timeoutConn) Read(b []byte) (n int, err error) {
|
|
// Reset deadline
|
|
c.Conn.SetReadDeadline(time.Now().Add(c.connDeadline))
|
|
|
|
return c.Conn.Read(b)
|
|
}
|
|
|
|
// Write implements net.Conn.
|
|
func (c timeoutConn) Write(b []byte) (n int, err error) {
|
|
// Reset deadline
|
|
c.Conn.SetWriteDeadline(time.Now().Add(c.connDeadline))
|
|
|
|
return c.Conn.Write(b)
|
|
}
|