mux.go 3.37 KB
Newer Older
tavit ohanian's avatar
tavit ohanian committed
1
// Package mux provides stream multiplexing interfaces for p2p.
2
//
tavit ohanian's avatar
tavit ohanian committed
3 4
// For a conceptual overview of stream multiplexing in p2p, see
// https://docs.p2p.io/concepts/stream-multiplexing/
5 6 7
package mux

import (
8
	"context"
9 10 11 12 13 14 15 16 17 18 19 20 21 22
	"errors"
	"io"
	"net"
	"time"
)

// ErrReset is returned when reading or writing on a reset stream.
var ErrReset = errors.New("stream reset")

// Stream is a bidirectional io pipe within a connection.
type MuxedStream interface {
	io.Reader
	io.Writer

23 24 25 26 27 28 29 30
	// Close closes the stream.
	//
	// * Any buffered data for writing will be flushed.
	// * Future reads will fail.
	// * Any in-progress reads/writes will be interrupted.
	//
	// Close may be asynchronous and _does not_ guarantee receipt of the
	// data.
Aarsh Shah's avatar
Aarsh Shah committed
31 32 33 34 35 36 37
	//
	// Close closes the stream for both reading and writing.
	// Close is equivalent to calling `CloseRead` and `CloseWrite`. Importantly, Close will not wait for any form of acknowledgment.
	// If acknowledgment is required, the caller must call `CloseWrite`, then wait on the stream for a response (or an EOF),
	// then call Close() to free the stream object.
	//
	// When done with a stream, the user must call either Close() or `Reset()` to discard the stream, even after calling `CloseRead` and/or `CloseWrite`.
38 39
	io.Closer

40 41 42 43 44 45 46
	// CloseWrite closes the stream for writing but leaves it open for
	// reading.
	//
	// CloseWrite does not free the stream, users must still call Close or
	// Reset.
	CloseWrite() error

Aarsh Shah's avatar
Aarsh Shah committed
47 48
	// CloseRead closes the stream for reading but leaves it open for
	// writing.
49
	//
Aarsh Shah's avatar
Aarsh Shah committed
50 51 52 53 54
	// When CloseRead is called, all in-progress Read calls are interrupted with a non-EOF error and
	// no further calls to Read will succeed.
	//
	// The handling of new incoming data on the stream after calling this function is implementation defined.
	//
55 56 57 58
	// CloseRead does not free the stream, users must still call Close or
	// Reset.
	CloseRead() error

59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
	// Reset closes both ends of the stream. Use this to tell the remote
	// side to hang up and go away.
	Reset() error

	SetDeadline(time.Time) error
	SetReadDeadline(time.Time) error
	SetWriteDeadline(time.Time) error
}

// NoopHandler do nothing. Resets streams as soon as they are opened.
var NoopHandler = func(s MuxedStream) { s.Reset() }

// MuxedConn represents a connection to a remote peer that has been
// extended to support stream multiplexing.
//
// A MuxedConn allows a single net.Conn connection to carry many logically
// independent bidirectional streams of binary data.
//
// Together with network.ConnSecurity, MuxedConn is a component of the
// transport.CapableConn interface, which represents a "raw" network
tavit ohanian's avatar
tavit ohanian committed
79
// connection that has been "upgraded" to support the p2p capabilities
80 81 82 83 84 85 86 87 88 89
// of secure communication and stream multiplexing.
type MuxedConn interface {
	// Close closes the stream muxer and the the underlying net.Conn.
	io.Closer

	// IsClosed returns whether a connection is fully closed, so it can
	// be garbage collected.
	IsClosed() bool

	// OpenStream creates a new stream.
90
	OpenStream(context.Context) (MuxedStream, error)
91 92 93 94 95 96 97 98 99 100 101 102 103

	// AcceptStream accepts a stream opened by the other side.
	AcceptStream() (MuxedStream, error)
}

// Multiplexer wraps a net.Conn with a stream multiplexing
// implementation and returns a MuxedConn that supports opening
// multiple streams over the underlying net.Conn
type Multiplexer interface {

	// NewConn constructs a new connection
	NewConn(c net.Conn, isServer bool) (MuxedConn, error)
}