h2transport

package module
v0.0.0-...-77015f9 Latest Latest
Warning

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

Go to latest
Published: Dec 14, 2020 License: Apache-2.0 Imports: 33 Imported by: 0

README

go-libp2p-h2-transport

HTTP/2 based transport, using libp2p interfaces.

The primary goal is compatibility with standards and existing infrastructure, including external load balancers. The transport can listen on 'https', using real or self-signed certificates. The server may be started in the calling app - the transport will only act as a POST handler.

It is also possible to start in plain text mode, with an external proxy handling TLS or mTLS.

In either case, the transport will get a HTTP/2 POST request, creating a binary stream that is upgraded with a normal TLS+H2. This is 'http/2 over http/2' - with the external http/2 not trusted, used only to create a stream.

  • TODO: if the infrastructure doesn't support H2 POST, fallback to http/2-over-websocket.

  • TODO: support CONNECT as well (Istio-like)

  • TODO: if the HTTP/2 connection is using the node identity (cert) and is authenticated with mTLS (or JWT in future), a H2 MUX will be configured.

In the 'ideal' case, the host will use the identity with mTLS or JWT on the outer HTTP/2, avoiding the second http/2. This is only posible if the transport is directly accepting - regular HTTP/2 does not allow 'reverse' connections.

The code violates (or extends) to the HTTP/2 standard, which only allow server-originated PUSH without a client strea - instead is using the same model as QUIC and libp2p where both sides can start streams. The docker/spdystream library is used - x/net doesn't seem to allow this.

Documentation

Index

Constants

View Source
const PROTO_H2 = "/h2/1.0"
View Source
const StreamQueueLen = 10

StreamQueueLen is the length of the stream queue.

Variables

View Source
var GracefulCloseTimeout = 100 * time.Millisecond

GracefulCloseTimeout is the time to wait trying to gracefully close a connection before simply cutting it.

WsFmt is multiaddr formatter for WsProtocol

Functions

func GetSAN

func GetSAN(c *x509.Certificate) ([]string, error)

func PubKeyFromCertChain

func PubKeyFromCertChain(chain []*x509.Certificate) (ic.PubKey, error)

PubKeyFromCertChain verifies the certificate chain and extract the remote's public key.

Types

type Conn

type Conn struct {
	*ws.Conn
	DefaultMessageType int
	// contains filtered or unexported fields
}

Conn implements net.Conn interface for gorilla/websocket.

func NewConn

func NewConn(raw *ws.Conn) *Conn

NewConn creates a Conn given a regular gorilla/websocket Conn.

func (*Conn) Close

func (c *Conn) Close() error

Close closes the connection. Only the first call to Close will receive the close error, subsequent and concurrent calls will return nil. This method is thread-safe.

func (*Conn) LocalAddr

func (c *Conn) LocalAddr() net.Addr

func (*Conn) Read

func (c *Conn) Read(b []byte) (int, error)

func (*Conn) RemoteAddr

func (c *Conn) RemoteAddr() net.Addr

func (*Conn) SetDeadline

func (c *Conn) SetDeadline(t time.Time) error

func (*Conn) SetReadDeadline

func (c *Conn) SetReadDeadline(t time.Time) error

func (*Conn) SetWriteDeadline

func (c *Conn) SetWriteDeadline(t time.Time) error

func (*Conn) Write

func (c *Conn) Write(b []byte) (n int, err error)

type H2Transport

type H2Transport struct {
	Prefix string
	Mux    *http.ServeMux

	Gater connmgr.ConnectionGater
	Psk   pnet.PSK
	Key   ic.PrivKey
	// contains filtered or unexported fields
}

H2Transport implements libp2p Transport. It also implements http.Handler, and can be registered with a HTTP/2 or HTTP/1 server. For HTTP/1 it will use websocket, with standard TLS and SPDY for crypto or mux. For HTTP/2 it will the normal connection if mTLS was negotiated. Otherwise will do a TLS+SPDY handshake for the POST method.

func NewH2Transport

func NewH2Transport(key ic.PrivKey, psk pnet.PSK, gater connmgr.ConnectionGater) (*H2Transport, error)

func (*H2Transport) CanDial

func (t *H2Transport) CanDial(a ma.Multiaddr) bool

func (*H2Transport) ConfigForAny

func (i *H2Transport) ConfigForAny() (*tls.Config, <-chan ic.PubKey)

ConfigForAny is a short-hand for ConfigForPeer("").

func (*H2Transport) ConfigForPeer

func (i *H2Transport) ConfigForPeer(remote peer.ID) (*tls.Config, <-chan ic.PubKey)

ConfigForPeer creates a new single-use tls.Config that verifies the peer's certificate chain and returns the peer's public key via the channel. If the peer ID is empty, the returned config will accept any peer.

It should be used to create a new tls.Config before securing either an incoming or outgoing connection.

func (*H2Transport) Dial

Dial creates a secure multiplexed CapableConn to the peer identified by a public key, using an address. The ID is derived from the proto-representation of the key - either SHA256 or the actual key if len <= 42

func (*H2Transport) Listen

func (t *H2Transport) Listen(a ma.Multiaddr) (transport.Listener, error)

func (*H2Transport) NewCapableConn

func (t *H2Transport) NewCapableConn(ctx context.Context, unsec net.Conn, isServer bool, p peer.ID) (*SPDYConn, error)

func (*H2Transport) Protocols

func (t *H2Transport) Protocols() []int

Returns the list of protocol codes handled by this transport, using the int code from the registry.

func (*H2Transport) Proxy

func (t *H2Transport) Proxy() bool

True for relay - currently not implemented.

func (*H2Transport) SecureInbound

func (t *H2Transport) SecureInbound(ctx context.Context, c *SPDYConn, insecure net.Conn) (*tls.Conn, error)

SecureInbound runs the TLS handshake as a server.

type PortListeners

type PortListeners struct {
	// contains filtered or unexported fields
}

type SPDYConn

type SPDYConn struct {
	LastSeen    time.Time
	ConnectTime time.Time
	// contains filtered or unexported fields
}

Conn is a connection to a remote peer, implements CapableConn ( MuxedConn, network.ConnSecurity, network.ConnMultiaddrs Transport())

implements MuxedConn (OpenStream/AcceptStream, Close/IsClosed)

func (*SPDYConn) AcceptStream

func (c *SPDYConn) AcceptStream() (mux.MuxedStream, error)

AcceptStream accepts a stream opened by the other side.

func (*SPDYConn) Close

func (c *SPDYConn) Close() error

func (*SPDYConn) GetStreams

func (c *SPDYConn) GetStreams() []network.Stream

func (*SPDYConn) ID

func (c *SPDYConn) ID() string

func (*SPDYConn) IsClosed

func (c *SPDYConn) IsClosed() bool

func (*SPDYConn) LocalMultiaddr

func (c *SPDYConn) LocalMultiaddr() ma.Multiaddr

func (*SPDYConn) LocalPeer

func (c *SPDYConn) LocalPeer() peer.ID

func (*SPDYConn) LocalPrivateKey

func (c *SPDYConn) LocalPrivateKey() ic.PrivKey

func (*SPDYConn) NewStream

func (c *SPDYConn) NewStream() (network.Stream, error)

Replaces/uses OpenStream used in transport MuxedStream.

func (*SPDYConn) OpenStream

func (c *SPDYConn) OpenStream() (mux.MuxedStream, error)

OpenStream creates a new stream.

func (*SPDYConn) RemoteMultiaddr

func (c *SPDYConn) RemoteMultiaddr() ma.Multiaddr

func (*SPDYConn) RemotePeer

func (c *SPDYConn) RemotePeer() peer.ID

func (*SPDYConn) RemotePublicKey

func (c *SPDYConn) RemotePublicKey() ic.PubKey

func (*SPDYConn) SecureOutbound

func (t *SPDYConn) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (*tls.Conn, error)

SecureOutbound runs the TLS handshake as a client. Note that SecureOutbound will not return an error if the server doesn't accept the certificate. This is due to the fact that in TLS 1.3, the client sends its certificate and the ClientFinished in the same flight, and can send application data immediately afterwards. If the handshake fails, the server will close the connection. The client will notice this after 1 RTT when calling Read.

func (*SPDYConn) Stat

func (c *SPDYConn) Stat() network.Stat

Return Stat directly - for metadata.

func (*SPDYConn) Transport

func (c *SPDYConn) Transport() transport.Transport

Jump to

Keyboard shortcuts

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