network

package
v2.2.1-mercury-20230627 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 28, 2023 License: MIT Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const (
	WsServerHandshakeAuthHeaderName      string = "Authorization"
	WsServerHandshakeChallengeHeaderName string = "Challenge"

	HandshakeTimestampLen            int = 4
	HandshakeDonIdLen                int = 64
	HandshakeGatewayURLMinLen        int = 10
	HandshakeSignatureLen            int = 65
	HandshakeAuthHeaderMinLen        int = HandshakeTimestampLen + HandshakeDonIdLen + HandshakeGatewayURLMinLen + HandshakeSignatureLen
	HandshakeEncodedAuthHeaderMaxLen int = 512
)

Variables

View Source
var (
	ErrNoActiveConnection = errors.New("no active connection")
	ErrWrapperShutdown    = errors.New("wrapper shutting down")
)

Functions

func Pack added in v2.3.0

func Pack(elems *AuthHeaderElems) []byte

Types

type AuthHeaderElems added in v2.3.0

type AuthHeaderElems struct {
	Timestamp  uint32
	DonId      string
	GatewayURL string
}

Components going into the auth header, excluding the signature.

func Unpack added in v2.3.0

func Unpack(data []byte) (*AuthHeaderElems, error)

type ConnectionAcceptor

type ConnectionAcceptor interface {
	// Verify auth header, save state of the attempt and generate a challenge for the node.
	StartHandshake(authHeader []byte) (attemptId string, challenge []byte, err error)

	// Verify signed challenge and update connection, if successful.
	FinalizeHandshake(attemptId string, response []byte, conn *websocket.Conn) error

	// Clear attempt's state.
	AbortHandshake(attemptId string)
}

type ConnectionInitiator

type ConnectionInitiator interface {
	// Generate authentication header value specific to node and gateway
	NewAuthHeader(url *url.URL) ([]byte, error)

	// Sign challenge to prove identity.
	ChallengeResponse(challenge []byte) ([]byte, error)
}

The handshake works as follows:

  Client (Initiator)                  Server (Acceptor)

 NewAuthHeader()
             -------auth header-------->
                                       StartHandshake()
             <-------challenge----------
ChallengeResponse()
             ---------response--------->
                                     FinalizeHandshake()

type HTTPRequestHandler

type HTTPRequestHandler interface {
	ProcessRequest(ctx context.Context, rawRequest []byte) (rawResponse []byte, httpStatusCode int)
}

type HTTPServerConfig

type HTTPServerConfig struct {
	Host                 string
	Port                 uint16
	TLSEnabled           bool
	TLSCertPath          string
	TLSKeyPath           string
	Path                 string
	ContentTypeHeader    string
	ReadTimeoutMillis    uint32
	WriteTimeoutMillis   uint32
	RequestTimeoutMillis uint32
	MaxRequestBytes      int64
}

type HttpServer

type HttpServer interface {
	job.ServiceCtx

	// Not thread-safe. Should be called once, before Start() is called.
	SetHTTPRequestHandler(handler HTTPRequestHandler)

	// Not thread-safe. Can be called after Start() returns.
	GetPort() int
}

func NewHttpServer

func NewHttpServer(config *HTTPServerConfig, lggr logger.Logger) HttpServer

type ReadItem

type ReadItem struct {
	MsgType int
	Data    []byte
}

type WSConnectionWrapper

type WSConnectionWrapper interface {
	// Update underlying connection object. Return a channel that gets an error on connection close.
	// Cannot be called after Close().
	Restart(newConn *websocket.Conn) <-chan error

	Write(ctx context.Context, msgType int, data []byte) error

	ReadChannel() <-chan ReadItem

	Close()
}

WSConnectionWrapper is a websocket connection abstraction that supports re-connects. I/O is separated from connection management:

  • component doing writes can use the thread-safe Write() method
  • component doing reads can listen on the ReadChannel()
  • component managing connections can listen to connection-closed channels and call Restart() to swap the underlying connection object

The Wrapper can be used by a server expecting long-lived connections from a given client, as well as a client maintaining such long-lived connection with a given server. This fits the Gateway very well as servers accept connections only from a fixed set of nodes and conversely, nodes only connect to a fixed set of servers (Gateways).

The concept of "pumps" is borrowed from https://github.com/smartcontractkit/wsrpc All methods are thread-safe.

func NewWSConnectionWrapper

func NewWSConnectionWrapper() WSConnectionWrapper

type WebSocketClient

type WebSocketClient interface {
	Connect(ctx context.Context, url *url.URL) (*websocket.Conn, error)
}

func NewWebSocketClient

func NewWebSocketClient(config WebSocketClientConfig, initiator ConnectionInitiator, lggr logger.Logger) WebSocketClient

type WebSocketClientConfig

type WebSocketClientConfig struct {
	HandshakeTimeoutMillis uint32
}

type WebSocketServer

type WebSocketServer interface {
	job.ServiceCtx

	// Not thread-safe. Can be called after Start() returns.
	GetPort() int
}

func NewWebSocketServer

func NewWebSocketServer(config *WebSocketServerConfig, acceptor ConnectionAcceptor, lggr logger.Logger) WebSocketServer

type WebSocketServerConfig

type WebSocketServerConfig struct {
	HTTPServerConfig
	HandshakeTimeoutMillis uint32
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL