Documentation
¶
Overview ¶
Package rpc implements the Cap'n Proto RPC protocol.
Index ¶
- Variables
- func ListenAndServe(ctx context.Context, network, addr string, bootstrapClient capnp.Client, ...) error
- func Serve(lis net.Listener, boot capnp.Client, opts ...ServeOption) error
- type Codec
- type Conn
- type IntroductionInfo
- type Logger
- type Network
- type Network3PH
- type NewTransportFunc
- type Options
- type PeerID
- type ServeOption
- type ThirdPartyCompletion
- type ThirdPartyToAwait
- type ThirdPartyToContact
- type Transport
Constants ¶
This section is empty.
Variables ¶
var ( // Base errors ErrConnClosed = errors.New("connection closed") ErrNotACapability = errors.New("not a capability") ErrCapTablePopulated = errors.New("capability table already populated") // RPC exceptions ExcClosed = rpcerr.Disconnected(ErrConnClosed) )
Functions ¶
func ListenAndServe ¶
func ListenAndServe(ctx context.Context, network, addr string, bootstrapClient capnp.Client, opts ...ServeOption) error
ListenAndServe opens a listener on the given address and serves a Cap'n Proto RPC to incoming connections
network and address are passed to net.Listen. Use network "unix" for Unix Domain Sockets and "tcp" for regular TCP IP4 or IP6 connections.
ListenAndServe will take ownership of bootstrapClient and release it on exit.
func Serve ¶
func Serve(lis net.Listener, boot capnp.Client, opts ...ServeOption) error
Serve serves a Cap'n Proto RPC to incoming connections.
Serve will take ownership of bootstrapClient and release it after the listener closes.
Serve exits with the listener error if the listener is closed by the owner.
Types ¶
type Conn ¶
type Conn struct {
// contains filtered or unexported fields
}
A Conn is a connection to another Cap'n Proto vat. It is safe to use from multiple goroutines.
func NewConn ¶
NewConn creates a new connection that communicates on a given transport.
Closing the connection will close the transport and release the bootstrap client provided in opts.
If opts == nil, sensible defaults are used. See Options for more info.
Once a connection is created, it will immediately start receiving requests from the transport.
func (*Conn) Bootstrap ¶
Bootstrap returns the remote vat's bootstrap interface. This creates a new client that the caller is responsible for releasing.
func (*Conn) Done ¶
func (c *Conn) Done() <-chan struct{}
Done returns a channel that is closed after the connection is shut down.
func (*Conn) RemotePeerID ¶
Return the peer ID for the remote side of the connection. Returns the zero value if this connection was set up with NewConn instead of via a Network.
type IntroductionInfo ¶
type IntroductionInfo struct { SendToProvider ThirdPartyToAwait SendToRecipient ThirdPartyToContact }
Data needed to perform a third-party handoff.
type Logger ¶
type Logger interface { Debug(message string, args ...any) Info(message string, args ...any) Warn(message string, args ...any) Error(message string, args ...any) }
Logger is used for logging by the RPC system. Each method logs messages at a different level, but otherwise has the same semantics:
- Message is a human-readable description of the log event.
- Args is a sequenece of key, value pairs, where the keys must be strings and the values may be any type.
- The methods may not block for long periods of time.
This interface is designed such that it is satisfied by *slog.Logger.
type Network ¶
type Network interface { // Return the identifier for caller on this network. LocalID() PeerID // Connect to another peer by ID. Re-uses any existing connection // to the peer. Dial(PeerID) (*Conn, error) // Accept and handle incoming connections on the network until // the context is canceled. Serve(context.Context) error }
A Network is a reference to a multi-party (generally >= 3) network of Cap'n Proto peers. Use this instead of NewConn when establishing connections outside a point-to-point setting.
In addition to satisfying the method set, a correct implementation of Network must be comparable.
type Network3PH ¶
type Network3PH interface { // Introduces both connections for a three-party handoff. After this, // the `ThirdPartyToAwait` will be sent to the `provider` and the // `ThirdPartyToContact` will be sent to the `recipient`. // // An error indicates introduction is not possible between the two `Conn`s. Introduce(provider *Conn, recipient *Conn) (IntroductionInfo, error) // Attempts forwarding of a `ThirdPartyToContact` received from `from` to // `destination`, with both vats being in this Network. This method // return a `ThirdPartyToContact` to send to `destination`. // // An error indicates forwarding is not possible. Forward(from *Conn, destination *Conn, info ThirdPartyToContact) (ThirdPartyToContact, error) // Completes a three-party handoff. // // The provided `completion` has been received from `conn` in an `Accept`. // // This method blocks until there is a matching `AwaitThirdParty`, if there is // none currently, and returns the `value` passed to it. // // An error indicates that this completion can never succeed, for example due // to a `completion` that is malformed. The error will be sent in response to the // `Accept`. CompleteThirdParty(ctx context.Context, conn *Conn, completion ThirdPartyCompletion) (any, error) // Awaits for completion of a three-party handoff. // // The provided `await` has been received from `conn`. // // While the context is valid, any `CompleteThirdParty` calls that match // the provided `await` should return `value`. // // After the context is canceled, future calls to `CompleteThirdParty` are // not required to return the provided `value`. // // This method SHOULD not block. AwaitThirdParty(ctx context.Context, conn *Conn, await ThirdPartyToAwait, value any) }
A Network3PH is a Network which supports three-party handoff of capabilities. TODO(before merge): could this interface be named better?
type NewTransportFunc ¶
type NewTransportFunc func(io.ReadWriteCloser) Transport
type Options ¶
type Options struct { // BootstrapClient is the capability that will be returned to the // remote peer when receiving a Bootstrap message. NewConn "steals" // this reference: it will release the client when the connection is // closed. BootstrapClient capnp.Client // Logger is used for logging by the RPC system, including errors that // occur while the Conn is receiving messages from the remote vat. Logger Logger // AbortTimeout specifies how long to block on sending an abort message // before closing the transport. If zero, then a reasonably short // timeout is used. AbortTimeout time.Duration // RemotePeerID is the PeerID of the remote side of the connection. Can // be left as the zero value for point to point connections. For >= 3 // party use, this should be filled in by the Network on Accept or Dial. // Application code should not set this. RemotePeerID PeerID // A reference to the Network that this connection is a part of. Can be // left nil for point to point connections. Otherwise, this must be set // by Dial or Accept on the Network itself; application code should not // set this. Network Network // BaseContext is an optional function that returns a base context // for any incoming connection. If ommitted, the context.Background() // will be used instead. BaseContext func() context.Context }
Options specifies optional parameters for creating a Conn.
type PeerID ¶
type PeerID struct { // Network specific value identifying the peer. Value any }
A PeerID identifies a peer on a Cap'n Proto network. The exact format of this is network specific.
type ServeOption ¶
type ServeOption func(*serveOpts)
func WithBasicStreamingTransport ¶
func WithBasicStreamingTransport() ServeOption
WithBasicStreamingTransport enables the streaming transport with basic encoding.
func WithPackedStreamingTransport ¶
func WithPackedStreamingTransport() ServeOption
WithPackedStreamingTransport enables the streaming transport with packed encoding.
type ThirdPartyCompletion ¶
The information that must be sent in an `Accept` message to identify the object being accepted.
In a network where each vat has a public/private key pair, this could simply be the public key fingerprint of the provider vat along with a nonce matching the one in the `RecipientId` used in the `Provide` message sent from that provider.
type ThirdPartyToAwait ¶
The information that must be sent in a `Provide` message to identify the recipient of the capability.
In a network where each vat has a public/private key pair, this could simply be the public key fingerprint of the recipient along with a nonce matching the one in the `ProvisionId`.
As another example, when communicating between processes on the same machine over Unix sockets, RecipientId could simply refer to a file descriptor attached to the message via SCM_RIGHTS. This file descriptor would be one end of a newly-created socketpair, with the other end having been sent to the capability's recipient in ThirdPartyCapId.
type ThirdPartyToContact ¶
The information needed to connect to a third party and accept a capability from it.
In a network where each vat has a public/private key pair, this could be a combination of the third party's public key fingerprint, hints on how to connect to the third party (e.g. an IP address), and the nonce used in the corresponding `Provide` message's `RecipientId` as sent to that third party (used to identify which capability to pick up).
As another example, when communicating between processes on the same machine over Unix sockets, ThirdPartyCapId could simply refer to a file descriptor attached to the message via SCM_RIGHTS. This file descriptor would be one end of a newly-created socketpair, with the other end having been sent to the process hosting the capability in RecipientId.
Some networks, as an optimization, may permit ThirdPartyToContact to be forwarded across multiple vats. For example, imagine Alice sends a capability to Bob, who passes it along to Carol, who further pass it to Dave. Bob will send a `Provide` message to Alice telling her to expect the capability to be picked up by Carol, and then will pass Carol a `ThirdPartyToContact` pointing to Alice. If `ThirdPartyToContact` is non-forwardable, then Carol must form a connection to Alice, send an `Accept` to receive the capability, and then immediately send a `Provide` to provide it to Dave, before then being able to give a `ThirdPartyToContact` to Dave which points to Alice. This is a bit of a waste. If `ThirdPartyToContact` is forwardable, then Carol can simply pass it along to Dave without making any connection to Alice. Some VatNetwork implementations may require that Carol add a signature to the `ThirdPartyToContact` authenticating that she really did forward it to Dave, which Dave will then present back to Alice. Other implementations may simply pass along an unguessable token and instruct Alice that whoever presents the token should receive the capability. A VatNetwork may choose not to allow forwarding if it doesn't want its security to be dependent on secret bearer tokens nor cryptographic signatures.
type Transport ¶
func NewPackedStreamTransport ¶
func NewPackedStreamTransport(rwc io.ReadWriteCloser) Transport
NewPackedStreamTransport is an alias for as transport.NewPackedStream
func NewStreamTransport ¶
func NewStreamTransport(rwc io.ReadWriteCloser) Transport
NewStreamTransport is an alias for as transport.NewStream
func NewTransport ¶
NewTransport is an alias for as transport.New
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
internal
|
|
testnetwork
Package testnetwork provides an in-memory implementation of rpc.Network for testing purposes.
|
Package testnetwork provides an in-memory implementation of rpc.Network for testing purposes. |
Package transport defines an interface for sending and receiving rpc messages.
|
Package transport defines an interface for sending and receiving rpc messages. |