wstransport

package module
v0.0.0-...-89bfd3f Latest Latest
Warning

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

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

README

go-ws-ssh-transport

Libp2p and IPFS compatible transport using SSH-over-websocket for security and multiplexing.

This is backward compatible with the "ws" transport: client and server will negotiate using the standards ws headers, and if SSH is available on both ends it will be used.

The libp2p transport interface is relatively nice and the higher level infrastructure and protocols are interesting. Like many others attempting to reinvent the internet - the protocol is also repeating many mistakes, in particular creating new security and protocol negotiation schemes, and failing to interoperate with well established standards.

The Libp2p QUIC transport is a good start in fixing this, by reusing a well defined standard, TLS + QUIC, and avoiding the round trips for mux and security negotiation.

This package provides a similar 'combined' transport, using SSH for multiplexing and security and Websocket for low-level communication.

The choice of WS is needed for interop with JS in browsers. There are few SSH implementations in javascript as well.

Another option would be TLS+SPDY over Websocket - the multiplexing provided by SPDY is very similar with SSH. I might add this as an option, using the built-in WS negotiation instead of the one invented by Libp2p.

Notes on libp2p interfaces

  • lower layer: 'transport.Transport' creates transport.CapableConn (Mux + Security), which creates MuxedStream. No metadata except public key of the pair.

  • network is a higher level - implemented by 'swarm' package. It defines Stream as an extension to MuxedStream, having an ID and a protocol. It also has metadata, open time, direction and link to the Conn to get the security.

  • host is the next layer - basic_host and ipfs host implement it. Adds a local ID, a peerstore (database of peers), a Mux (protocol.Switch). Has Connect() and SetStreamHandler, NewStream(peer, protocolID...) Also has a ConnManager and EventBus. High leve introspection as well.

Helper interfaces

  • protocol.Switch - implemented by 'multiformats' package - handles negotiation at high level. This seems inefficient and ignores the standard capabilities of the protocols. Seems the weakest part of the package.

  • PeerStore

  • ConnManager: policy to close/keep alive ( Decay ), Gater, tags for peers. BasicConnMgr implementation using high watermark.

  • crypto - custom representation as a PB, base58. Also supports the PEM and raw format.

  • RoutedHost - Routing FindPeer(ID)->AddrInfo

  • EventBus

TODO

JS

Documentation

Index

Constants

View Source
const PROTO_SSH = "/ssh/1.0"

Variables

View Source
var GracefulCloseTimeout = 100 * time.Millisecond

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

View Source
var WsCodec = &manet.NetCodec{
	NetAddrNetworks:  []string{"ws"},
	ProtocolName:     "ws",
	ConvertMultiaddr: ConvertWebsocketMultiaddrToNetAddr,
	ParseNetAddr:     ParseWebsocketNetAddr,
}

WsCodec is the multiaddr-net codec definition for the websocket transport

WsFmt is multiaddr formatter for WsProtocol

Functions

func ConvertWebsocketMultiaddrToNetAddr

func ConvertWebsocketMultiaddrToNetAddr(maddr ma.Multiaddr) (net.Addr, error)

func ParseWebsocketNetAddr

func ParseWebsocketNetAddr(a net.Addr) (ma.Multiaddr, error)

func PrivKey2SSH

func PrivKey2SSH(key ic.PrivKey) (ssh.Signer, error)

Types

type Addr

type Addr struct {
	*url.URL
}

Addr is an implementation of net.Addr for WebSocket.

func NewAddr

func NewAddr(host string) *Addr

NewAddr creates a new Addr using the given host string

func (*Addr) Network

func (addr *Addr) Network() string

Network returns the network type for a WebSocket, "websocket".

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 SSHConn

type SSHConn 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 (*SSHConn) AcceptStream

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

AcceptStream accepts a stream opened by the other side.

func (*SSHConn) Close

func (c *SSHConn) Close() error

func (*SSHConn) GetStreams

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

func (*SSHConn) ID

func (c *SSHConn) ID() string

func (*SSHConn) IsClosed

func (c *SSHConn) IsClosed() bool

func (*SSHConn) LocalMultiaddr

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

func (*SSHConn) LocalPeer

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

func (*SSHConn) LocalPrivateKey

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

func (*SSHConn) NewStream

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

Replaces/uses OpenStream used in transport MuxedStream.

func (*SSHConn) OpenStream

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

OpenStream creates a new stream. This uses the same channel in both directions.

func (*SSHConn) RemoteMultiaddr

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

func (*SSHConn) RemotePeer

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

func (*SSHConn) RemotePublicKey

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

func (*SSHConn) Stat

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

Return Stat directly - for metadata.

func (*SSHConn) Transport

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

type SSHTransport

type SSHTransport struct {
	Prefix string
	Mux    *http.ServeMux

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

SSHTransport is the actual go-libp2p transport

func NewSSHTransport

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

NewWsSshTransport creates a new transport using Websocket and SSH Based on QUIC transport.

func (*SSHTransport) CanDial

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

func (*SSHTransport) 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 (*SSHTransport) Listen

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

func (*SSHTransport) NewCapableConn

func (t *SSHTransport) NewCapableConn(nc net.Conn, isServer bool) (transport.CapableConn, error)

NewConn wraps a net.Conn using SSH for MUX and security.

func (*SSHTransport) NewConn

func (t *SSHTransport) NewConn(nc net.Conn, isServer bool) (mux.MuxedConn, error)

SSH transport implements the Multiplexer interface, can be used with other transports. The result is also a CapableConn, so no need for the extra security.

func (*SSHTransport) Protocols

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

func (*SSHTransport) Proxy

func (t *SSHTransport) Proxy() bool

Jump to

Keyboard shortcuts

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