Documentation ¶
Index ¶
- Constants
- Variables
- func PackAuthHeader(elems *AuthHeaderElems) []byte
- func PackChallenge(elems *ChallengeElems) []byte
- type AuthHeaderElems
- type ChallengeElems
- type ConnectionAcceptor
- type ConnectionInitiator
- type HTTPRequestHandler
- type HTTPServerConfig
- type HttpServer
- type ReadItem
- type WSConnectionWrapper
- type WebSocketClient
- type WebSocketClientConfig
- type WebSocketServer
- type WebSocketServerConfig
Constants ¶
View Source
const ( WsServerHandshakeAuthHeaderName string = "Authorization" WsServerHandshakeChallengeHeaderName string = "Challenge" HandshakeTimestampLen int = 4 HandshakeDonIdLen int = 64 HandshakeGatewayURLLen int = 128 HandshakeSignatureLen int = 65 HandshakeAuthHeaderLen int = HandshakeTimestampLen + HandshakeDonIdLen + HandshakeGatewayURLLen + HandshakeSignatureLen HandshakeEncodedAuthHeaderMaxLen int = 512 HandshakeChallengeMinLen int = HandshakeTimestampLen + HandshakeGatewayURLLen + 1 )
View Source
const ( HealthCheckPath = "/health" HealthCheckResponse = "OK" )
Variables ¶
View Source
var ( ErrAuthHeaderParse = errors.New("unable to parse auth header") ErrAuthInvalidDonId = errors.New("invalid DON ID") ErrAuthInvalidNode = errors.New("unexpected node address") ErrAuthInvalidGateway = errors.New("invalid gateway ID") ErrAuthInvalidTimestamp = errors.New("timestamp outside of tolerance range") ErrChallengeTooShort = errors.New("challenge too short") ErrChallengeAttemptNotFound = errors.New("attempt not found") ErrChallengeInvalidSignature = errors.New("invalid challenge signature") )
View Source
var ( ErrNoActiveConnection = errors.New("no active connection") ErrWrapperShutdown = errors.New("wrapper shutting down") )
Functions ¶
func PackAuthHeader ¶ added in v2.4.0
func PackAuthHeader(elems *AuthHeaderElems) []byte
func PackChallenge ¶ added in v2.4.0
func PackChallenge(elems *ChallengeElems) []byte
Types ¶
type AuthHeaderElems ¶ added in v2.3.0
Components going into the auth header, excluding the signature.
func UnpackSignedAuthHeader ¶ added in v2.4.0
func UnpackSignedAuthHeader(data []byte) (elems *AuthHeaderElems, signer []byte, err error)
type ChallengeElems ¶ added in v2.4.0
func UnpackChallenge ¶ added in v2.4.0
func UnpackChallenge(data []byte) (*ChallengeElems, 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(url *url.URL, challenge []byte) ([]byte, error) }
The handshake works as follows:
Client (Initiator) Server (Acceptor) NewAuthHeader() -------auth header--------> StartHandshake() <-------challenge---------- ChallengeResponse() ---------response---------> FinalizeHandshake()
type HTTPRequestHandler ¶
type HTTPServerConfig ¶
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 WSConnectionWrapper ¶
type WSConnectionWrapper interface { job.ServiceCtx services.HealthReporter // Update underlying connection object. Return a channel that gets an error on connection close. // Cannot be called after Close(). Reset(newConn *websocket.Conn) <-chan error Write(ctx context.Context, msgType int, data []byte) error ReadChannel() <-chan ReadItem }
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 Reset() 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(lggr logger.Logger) 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 }
Source Files ¶
Click to show internal directories.
Click to hide internal directories.