Commit e5f2ef8e authored by Kenton Varda's avatar Kenton Varda

More RPC doc tweaks.

parent 0b4a459c
...@@ -94,12 +94,12 @@ struct JoinKeyPart { ...@@ -94,12 +94,12 @@ struct JoinKeyPart {
# Which part this request targets -- a number in the range [0, partCount). # Which part this request targets -- a number in the range [0, partCount).
} }
struct JoinHostId { struct JoinAnswer {
joinId @0 :UInt32; joinId @0 :UInt32;
# Matches `JoinKeyPart`. # Matches `JoinKeyPart`.
succeeded @1 :Bool; succeeded @1 :Bool;
# All JoinHostIds in the set will have the same value for `succeeded`. The container actually # All JoinAnswers in the set will have the same value for `succeeded`. The container actually
# implements the join by waiting for all the `JoinKeyParts` and then performing its own join on # implements the join by waiting for all the `JoinKeyParts` and then performing its own join on
# them, then going back and answering all the join requests afterwards. # them, then going back and answering all the join requests afterwards.
} }
...@@ -51,8 +51,8 @@ ...@@ -51,8 +51,8 @@
# to the intended vat as well as to encrypt transmitted data for privacy and integrity. See the # to the intended vat as well as to encrypt transmitted data for privacy and integrity. See the
# `VatNetwork` example interface near the end of this file. # `VatNetwork` example interface near the end of this file.
# #
# Once a connection is formed, nothing interesting can happen until one side sends a Restore frame # Once a connection is formed, nothing interesting can happen until one side sends a Restore
# to obtain a persistent capability. # message to obtain a persistent capability.
# #
# Unless otherwise specified, messages must be delivered to the receiving application in the same # Unless otherwise specified, messages must be delivered to the receiving application in the same
# order in which they were initiated by the sending application, just like in E: # order in which they were initiated by the sending application, just like in E:
...@@ -117,6 +117,12 @@ $Cxx.namespace("capnp::rpc"); ...@@ -117,6 +117,12 @@ $Cxx.namespace("capnp::rpc");
# messages using the ID could be traveling in both directions simultaneously, we must define the # messages using the ID could be traveling in both directions simultaneously, we must define the
# end of life of each ID _in each direction_. The ID is only safe to reuse once it has been # end of life of each ID _in each direction_. The ID is only safe to reuse once it has been
# released by both sides. # released by both sides.
#
# When a Cap'n Proto connection is lost, everything on the four tables is lost. All questions are
# canceled and throw exceptions. All imports become broken (all methods throw exceptions). All
# exports and answers are implicitly released. The only things not lost are persistent
# capabilities (`SturdyRef`s). The application must plan for this and should respond by
# establishing a new connection and restoring from these persistent capabilities.
using QuestionId = UInt32; using QuestionId = UInt32;
# Identifies a question in the questions/answers table. The questioner (caller) chooses an ID # Identifies a question in the questions/answers table. The questioner (caller) chooses an ID
...@@ -128,7 +134,7 @@ using ExportId = UInt32; ...@@ -128,7 +134,7 @@ using ExportId = UInt32;
# an ID before sending a capability over the wire. If the capability is already in the table, the # an ID before sending a capability over the wire. If the capability is already in the table, the
# exporter should reuse the same ID. If the ID is a promise (as opposed to a settled capability), # exporter should reuse the same ID. If the ID is a promise (as opposed to a settled capability),
# this must be indicated at the time the ID is introduced; in this case, the importer shall expect # this must be indicated at the time the ID is introduced; in this case, the importer shall expect
# a later Resolve frame which replaces the promise. # a later Resolve message which replaces the promise.
# #
# ExportIds are subject to reference counting. When an `ExportId` is received embedded in an # ExportIds are subject to reference counting. When an `ExportId` is received embedded in an
# question or answer, the export has an implicit reference until that question or answer is # question or answer, the export has an implicit reference until that question or answer is
...@@ -142,22 +148,21 @@ using ExportId = UInt32; ...@@ -142,22 +148,21 @@ using ExportId = UInt32;
# that the `Release` message is sent, so it is necessary for the exporter to keep track of the # that the `Release` message is sent, so it is necessary for the exporter to keep track of the
# reference count on its end as well to avoid race conditions. # reference count on its end as well to avoid race conditions.
# #
# When an `ExportId` is received as part of a Frame but not embedded in a question or answer, its # When an `ExportId` is received as part of a exporter -> importer message but not embedded in a
# reference count is automatically incremented unless otherwise specified. # question or answer, its reference count must be incremented unless otherwise specified.
# #
# An `ExportId` remains valid in importer -> exporter messages until its reference count reaches # An `ExportId` remains valid in importer -> exporter messages until its reference count reaches
# zero and a `Release` message has been sent to release it. # zero and a `Release` message has been sent to release it.
#
# When a connection is lost, all exports are implicitly released. It is not possible to restore
# a connection state (or, restoration should be implemented at the transport layer without the RPC
# layer knowing that anything happened).
# ======================================================================================== # ========================================================================================
# Frames # Messages
struct Frame { struct Message {
# An RPC connection is a bi-directional stream of Frames. # An RPC connection is a bi-directional stream of Messages.
#
# When the RPC system wants to send a Frame, it instructs the transport layer to keep trying to
# send the frame until the transport can guarantee that one of the following is true:
# 1) The Frame was received.
# 2) The sessing is broken, and no further Frames can be sent.
union { union {
# Level 1 features ----------------------------------------------- # Level 1 features -----------------------------------------------
...@@ -183,15 +188,17 @@ struct Frame { ...@@ -183,15 +188,17 @@ struct Frame {
} }
struct Call { struct Call {
# Frame type initiating a method call on a capability. # Message type initiating a method call on a capability.
questionId @0 :QuestionId; questionId @0 :QuestionId;
# A number, chosen by the caller, which identifies this call in future messages. This number # A number, chosen by the caller, which identifies this call in future messages. This number
# must be different from all other calls originating from the same end of the connection (but # must be different from all other calls originating from the same end of the connection (but
# may overlap with call IDs originating from the opposite end). A fine strategy is to use # may overlap with question IDs originating from the opposite end). A fine strategy is to use
# sequential call IDs, but the recipient should not assume this. # sequential question IDs, but the recipient should not assume this.
# #
# TODO: Decide if it is safe to reuse a call ID. If not, extend to 64 bits. # A question ID can be reused once both:
# - A matching Return has been received from the callee.
# - A matching ReleaseAnswer has been sent from the caller.
target :union { target :union {
exportedCap @1 :ExportId; exportedCap @1 :ExportId;
...@@ -212,11 +219,11 @@ struct Call { ...@@ -212,11 +219,11 @@ struct Call {
# The request struct. The fields of this struct correspond to the parameters of the method. # The request struct. The fields of this struct correspond to the parameters of the method.
# #
# The request may contain capabilities. These capabilities are automatically released when the # The request may contain capabilities. These capabilities are automatically released when the
# call returns *unless* the Return frame explicitly indicates that they are being retained. # call returns *unless* the Return message explicitly indicates that they are being retained.
} }
struct Return { struct Return {
# Frame type sent from callee to caller indicating that the call has completed. # Message type sent from callee to caller indicating that the call has completed.
questionId @0 :QuestionId; questionId @0 :QuestionId;
# Question ID which is being answered, as specified in the corresponding Call. # Question ID which is being answered, as specified in the corresponding Call.
...@@ -232,8 +239,10 @@ struct Return { ...@@ -232,8 +239,10 @@ struct Return {
# (This implies that an method's return type can be upgraded from a non-struct to a struct # (This implies that an method's return type can be upgraded from a non-struct to a struct
# without breaking wire compatibility.) # without breaking wire compatibility.)
# #
# If the response contains any capabilities, the caller is expected to send a Release frame for # For a `Return` in response to an `Accept`, `answer` is a capability pointer (and therefore
# each one when done with them. # points to a `CapDescriptor`, but is tagged as a capability rather than a struct). A
# `ReleaseAnswer` is still required in this case, and the capability must still be listed in
# `retainedCaps` if it is to be retained.
exception @3 :Exception; exception @3 :Exception;
# Indicates that the call failed and explains why. # Indicates that the call failed and explains why.
...@@ -245,7 +254,7 @@ struct Return { ...@@ -245,7 +254,7 @@ struct Return {
} }
struct Resolve { struct Resolve {
# Frame type sent to indicate that a previously-sent promise has now been resolved to some other # Message type sent to indicate that a previously-sent promise has now been resolved to some other
# object (possibly another promise) -- or broken, or canceled. # object (possibly another promise) -- or broken, or canceled.
promiseId @0 :ExportId; promiseId @0 :ExportId;
...@@ -290,22 +299,19 @@ struct Resolve { ...@@ -290,22 +299,19 @@ struct Resolve {
} }
struct Release { struct Release {
# Frame type sent to indicate that the sender is done with the given capability and the receiver # Message type sent to indicate that the sender is done with the given capability and the receiver
# can free resources allocated to it. # can free resources allocated to it.
id @0 :ExportId; id @0 :ExportId;
# What to release. # What to release.
referenceCount @1 :UInt32; referenceCount @1 :UInt32;
# The number of times this ID has been received by the importer. The object is only truly # The amount by which to decrement the reference count. The export is only actually released
# released when the referenceCount from all Release messages for the ID adds up to the number of # when the reference count reaches zero.
# times the exporter has actually sent the object to the importer. This avoids a race condition
# where the exporter happens to send another copy of the same ID at the same time as the importer
# is sending a Release message for it.
} }
struct ReleaseAnswer { struct ReleaseAnswer {
# Frame type sent from the caller to the callee to indicate: # Message type sent from the caller to the callee to indicate:
# 1) The questionId will no longer be used in any messages sent by the callee (no further # 1) The questionId will no longer be used in any messages sent by the callee (no further
# pipelined requests). # pipelined requests).
# 2) Any capabilities in the answer other than the ones listed below should be implicitly # 2) Any capabilities in the answer other than the ones listed below should be implicitly
...@@ -324,7 +330,7 @@ struct ReleaseAnswer { ...@@ -324,7 +330,7 @@ struct ReleaseAnswer {
} }
struct Restore { struct Restore {
# Frame type sent to restore a persistent capability obtained during a previous connection, or # Message type sent to restore a persistent capability obtained during a previous connection, or
# through other means. # through other means.
questionId @0 :QuestionId; questionId @0 :QuestionId;
...@@ -332,13 +338,13 @@ struct Restore { ...@@ -332,13 +338,13 @@ struct Restore {
# message containing the restored capability. # message containing the restored capability.
ref @1 :SturdyRef; ref @1 :SturdyRef;
# An object designating the capability to restore. # Designates the capability to restore.
} }
struct Provide { struct Provide {
# **Level 2 feature** # **Level 2 feature**
# #
# Frame type sent to indicate that the sender wishes to make a particular capability implemented # Message type sent to indicate that the sender wishes to make a particular capability implemented
# by the receiver available to a third party for direct access (without the need for the third # by the receiver available to a third party for direct access (without the need for the third
# party to proxy through the sender). # party to proxy through the sender).
# #
...@@ -368,7 +374,7 @@ struct Provide { ...@@ -368,7 +374,7 @@ struct Provide {
struct Accept { struct Accept {
# **Level 2 feature** # **Level 2 feature**
# #
# Frame type sent to pick up a capability hosted by the receiving vat and provided by a third # Message type sent to pick up a capability hosted by the receiving vat and provided by a third
# party. The third party previously designated the capability using `Provide`. # party. The third party previously designated the capability using `Provide`.
questionId @0 :QuestionId; questionId @0 :QuestionId;
...@@ -382,10 +388,10 @@ struct Accept { ...@@ -382,10 +388,10 @@ struct Accept {
struct Join { struct Join {
# **Level 3 feature** # **Level 3 feature**
# #
# Frame type sent to implement E.join(), which, given a number of capabilities which are expected # Message type sent to implement E.join(), which, given a number of capabilities which are
# to be equivalent, finds the underlying object upon which they all agree and forms a direct # expected to be equivalent, finds the underlying object upon which they all agree and forms a
# connection to it, skipping any proxies which may have been constructed by other vats while # direct connection to it, skipping any proxies which may have been constructed by other vats
# transmitting the capability. See: # while transmitting the capability. See:
# http://erights.org/elib/equality/index.html # http://erights.org/elib/equality/index.html
# #
# Note that this should only serve to bypass fully-transparent proxies -- proxies that were # Note that this should only serve to bypass fully-transparent proxies -- proxies that were
...@@ -406,7 +412,7 @@ struct Join { ...@@ -406,7 +412,7 @@ struct Join {
# - Dana receives Carol's request and notes that she now has both parts of a JoinKey. She # - Dana receives Carol's request and notes that she now has both parts of a JoinKey. She
# combines them in order to form information needed to form a secure connection to Bob. She # combines them in order to form information needed to form a secure connection to Bob. She
# also responds with another JoinAnswer. # also responds with another JoinAnswer.
# - Bob receives the responses from Alice and Carol. He uses the returned JoinHostIds to # - Bob receives the responses from Alice and Carol. He uses the returned JoinAnswers to
# determine how to connect to Dana and attempts to form the connection. Since Bob and Dana now # determine how to connect to Dana and attempts to form the connection. Since Bob and Dana now
# agree on a secret key which neither Alice nor Carol ever saw, this connection can be made # agree on a secret key which neither Alice nor Carol ever saw, this connection can be made
# securely even if Alice or Carol is conspiring against the other. (If Alice and Carol are # securely even if Alice or Carol is conspiring against the other. (If Alice and Carol are
...@@ -422,6 +428,18 @@ struct Join { ...@@ -422,6 +428,18 @@ struct Join {
# Question ID used to respond to this Join. (Note that this ID only identifies one part of the # Question ID used to respond to this Join. (Note that this ID only identifies one part of the
# request for one hop; each part has a different ID and relayed copies of the request have # request for one hop; each part has a different ID and relayed copies of the request have
# (probably) different IDs still.) # (probably) different IDs still.)
#
# The receiver will reply with a `Return` whose `answer` is a JoinAnswer. This `JoinAnswer`
# is relayed from the joined object's host, possibly with transformation applied as needed
# by the network.
#
# Like any answer, the answer must be released using a `ReleaseAnswer`. However, this release
# should not occur until the joiner has either successfully connected to the joined object.
# Vats relaying a `Join` message similarly must not release the answer they receive until the
# answer they relayed back towards the joiner has itself been released. This allows the
# joined object's host to detect when the Join operation is canceled before completing -- if
# it receives a `ReleaseAnswer` for one of the join answers before the joiner successfully
# connects. It can then free any resources it had allocated as part of the join.
capId @1 :ExportId; capId @1 :ExportId;
# The capability to join. # The capability to join.
...@@ -429,23 +447,10 @@ struct Join { ...@@ -429,23 +447,10 @@ struct Join {
keyPart @2 :JoinKeyPart; keyPart @2 :JoinKeyPart;
# A part of the join key. These combine to form the complete join key which is used to establish # A part of the join key. These combine to form the complete join key which is used to establish
# a direct connection. # a direct connection.
struct Answer {
# The answer to a `Join` frame (sent in a `Return` frame).
hostId @0 :JoinHostId;
# Information indicating where to connect to complete the join. Also used to verify that all
# the joins actually reached the same object.
vineId @1 :ExportId;
# A new capability in the sender's export table which must be released once the join is
# complete. This capability has no methods. This allows the joined capability's host to
# detect when a Join has failed and release the associated resources on its end.
}
} }
# ======================================================================================== # ========================================================================================
# Common structures used in frames # Common structures used in messages
struct CapDescriptor { struct CapDescriptor {
# When an application-defined type contains an interface pointer, that pointer's encoding is the # When an application-defined type contains an interface pointer, that pointer's encoding is the
...@@ -489,17 +494,23 @@ struct CapDescriptor { ...@@ -489,17 +494,23 @@ struct CapDescriptor {
sturdyRef @6 :SturdyRef; sturdyRef @6 :SturdyRef;
# If non-null, this is a SturdyRef that can be used to store this capability persistently and # If non-null, this is a SturdyRef that can be used to store this capability persistently and
# restore access to in in the future (using a `Restore` frame). If null, this capability will be # restore access to in in the future (using a `Restore` message). If null, this capability will
# lost if the connection dies. Generally, application interfaces should define when a client can # be lost if the connection dies. Generally, application interfaces should define when a client
# expect a capability to be persistent (and therefore have a SturdyRef attached). However, # can expect a capability to be persistent (and therefore have a SturdyRef attached). However,
# application protocols should never embed SturdyRefs directly, as various infrastructure like # application protocols should never embed SturdyRefs directly, as various infrastructure like
# transports, gateways, and sandboxes may need to be aware of SturdyRefs being passed over the # transports, gateways, and sandboxes may need to be aware of SturdyRefs being passed over the
# wire in order to transform them into different namespaces. # wire in order to transform them into different namespaces.
} }
struct PromisedAnswer { struct PromisedAnswer {
# Specifies how to derive a promise from an unanswered question, by specifying the path of fields
# to follow from the root of the eventual answer struct to get to the desired capability. Used
# to address method calls to a not-yet-returned capability or to pass such a capability as an
# input to some other method call.
questionId @0 :QuestionId; questionId @0 :QuestionId;
# ID of the question whose answer is expected to contain the capability. # ID of the question (in the sender's question table / receiver's answer table) whose answer is
# expected to contain the capability.
path @1 :List(UInt16); path @1 :List(UInt16);
# Path to the capability in the response. This is a list of indexes into the pointer # Path to the capability in the response. This is a list of indexes into the pointer
...@@ -507,8 +518,13 @@ struct PromisedAnswer { ...@@ -507,8 +518,13 @@ struct PromisedAnswer {
# pointer except for the last one must point to another struct -- it is an error if one ends # pointer except for the last one must point to another struct -- it is an error if one ends
# up pointing to a list or something else. # up pointing to a list or something else.
# #
# If the question refers to an `Accept` (or anything other than a `Call`), this list must be
# empty.
#
# TODO(someday): Would it make sense to support lists in the path, and say that the method # TODO(someday): Would it make sense to support lists in the path, and say that the method
# should be executed on every element of the list? # should be executed on every element of the list? Of course, if we wanted to get arbitrarily
# complicated, the ideal would be for the caller to be able to upload a script to run that
# derives the capability given the former answer, but that's probably unreasonable.
} }
struct ThirdPartyCapDescriptor { struct ThirdPartyCapDescriptor {
...@@ -610,7 +626,7 @@ struct Exception { ...@@ -610,7 +626,7 @@ struct Exception {
# #
# **Level 3 feature** # **Level 3 feature**
# #
# The `Join` frame type and corresponding operation arranges for a direct connection to be formed # The `Join` message type and corresponding operation arranges for a direct connection to be formed
# between the joiner and the host of the joined object, and this connection must be authenticated. # between the joiner and the host of the joined object, and this connection must be authenticated.
# Thus, the details are network-dependent. # Thus, the details are network-dependent.
# #
...@@ -624,7 +640,7 @@ struct Exception { ...@@ -624,7 +640,7 @@ struct Exception {
using SturdyRef = Object; using SturdyRef = Object;
# Identifies a long-lived capability which can be obtained again in a future connection by sending # Identifies a long-lived capability which can be obtained again in a future connection by sending
# a `Restore` frame. The base RPC protocol does not specify under what conditions a SturdyRef can # a `Restore` message. The base RPC protocol does not specify under what conditions a SturdyRef can
# be restored. For example: # be restored. For example:
# - Do you have to connect to a specific vat to restore the reference? # - Do you have to connect to a specific vat to restore the reference?
# - Is just any vat allowed to restore the SturdyRef, or is it tied to a specific vat requiring # - Is just any vat allowed to restore the SturdyRef, or is it tied to a specific vat requiring
...@@ -633,16 +649,16 @@ using SturdyRef = Object; ...@@ -633,16 +649,16 @@ using SturdyRef = Object;
using ProvisionId = Object; using ProvisionId = Object;
# **Level 2 feature** # **Level 2 feature**
# #
# The information which must be sent in an `Accept` frame to identify the object being accepted. # The information which 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 # 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 the questionId used in the `Provide` frame sent from # fingerprint of the provider vat along with the questionId used in the `Provide` message sent from
# that provider. # that provider.
using RecipientId = Object; using RecipientId = Object;
# **Level 2 feature** # **Level 2 feature**
# #
# The information which must be sent in a `Provide` frame to identify the recipient of the # The information which must be sent in a `Provide` message to identify the recipient of the
# capability. # capability.
# #
# In a network where each vat has a public/private key pair, this could simply be the public key # In a network where each vat has a public/private key pair, this could simply be the public key
...@@ -655,13 +671,13 @@ using ThirdPartyCapId = Object; ...@@ -655,13 +671,13 @@ using ThirdPartyCapId = Object;
# #
# In a network where each vat has a public/private key pair, this could be a combination of the # 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 # third party's public key fingerprint, hints on how to connect to the third party (e.g. an IP
# address), and the question ID used in the corresponding `Provide` frame sent to that third party # address), and the question ID used in the corresponding `Provide` mesasge sent to that third party
# (used to identify which capability to pick up). # (used to identify which capability to pick up).
using JoinKeyPart = Object; using JoinKeyPart = Object;
# A piece of a secret key. One piece is sent along each path that is expected to lead to the same # A piece of a secret key. One piece is sent along each path that is expected to lead to the same
# place. Once the pieces are combined, a direct connection may be formed between the sender and # place. Once the pieces are combined, a direct connection may be formed between the sender and
# the receiver, bypassing any men-in-the-middle along the paths. See the "Join" frame type. # the receiver, bypassing any men-in-the-middle along the paths. See the `Join` message type.
# #
# The motivation for Joins is discussed under "Supporting Equality" in the "Unibus" protocol # The motivation for Joins is discussed under "Supporting Equality" in the "Unibus" protocol
# sketch: http://www.erights.org/elib/distrib/captp/unibus.html # sketch: http://www.erights.org/elib/distrib/captp/unibus.html
...@@ -680,16 +696,16 @@ using JoinKeyPart = Object; ...@@ -680,16 +696,16 @@ using JoinKeyPart = Object;
# the joiner and the joined object's host. Each JoinKeyPart should also include an indication of # the joiner and the joined object's host. Each JoinKeyPart should also include an indication of
# how many parts to expect and a hash of the shared secret (used to match up parts). # how many parts to expect and a hash of the shared secret (used to match up parts).
using JoinHostId = Object; using JoinAnswer = Object;
# Information needed by the joiner in order to form a direct connection to a joined object. One # Information returned in the answer to a `Join` message, needed by the joiner in order to form a
# of these is returned in response to each `Join` frame. This might simply be the address of the # direct connection to a joined object. This might simply be the address of the joined object's
# joined object's host vat, since the `JoinKey` has already been communicated so the two vats # host vat, since the `JoinKey` has already been communicated so the two vats already have a shared
# already have a shared secret to use to authenticate each other. # secret to use to authenticate each other.
# #
# The `JoinHostId` should also contain information that can be used to detect when the Join # The `JoinAnswer` should also contain information that can be used to detect when the Join
# requests ended up reaching different objects, so that this situation can be detected easily. # requests ended up reaching different objects, so that this situation can be detected easily.
# This could be a simple matter of including a sequence number -- if the joiner receives two # This could be a simple matter of including a sequence number -- if the joiner receives two
# `JoinHostId`s with sequence number 0, then they must have come from different objects and the # `JoinAnswer`s with sequence number 0, then they must have come from different objects and the
# whole join is a failure. # whole join is a failure.
# ======================================================================================== # ========================================================================================
...@@ -717,13 +733,13 @@ using JoinHostId = Object; ...@@ -717,13 +733,13 @@ using JoinHostId = Object;
# # sends them encrypted such that only the authentic vat would be able to decrypt them. The # # sends them encrypted such that only the authentic vat would be able to decrypt them. The
# # latter approach avoids a round trip for authentication. # # latter approach avoids a round trip for authentication.
# # # #
# # Once connected, the caller should start by sending a `Restore` frame. # # Once connected, the caller should start by sending a `Restore` message.
# #
# acceptConnectionAsRefHost() :Connection; # acceptConnectionAsRefHost() :Connection;
# # Wait for the next incoming connection and return it. Only connections formed by # # Wait for the next incoming connection and return it. Only connections formed by
# # connectToHostOf() are returned by this method. # # connectToHostOf() are returned by this method.
# # # #
# # Once connected, the first received frame will usually be a `Restore`. # # Once connected, the first received message will usually be a `Restore`.
# #
# # Level 3 features ----------------------------------------------- # # Level 3 features -----------------------------------------------
# #
...@@ -733,45 +749,45 @@ using JoinHostId = Object; ...@@ -733,45 +749,45 @@ using JoinHostId = Object;
# #
# struct NewJoinerResponse { # struct NewJoinerResponse {
# joinKeyParts :List(JoinKeyPart); # joinKeyParts :List(JoinKeyPart);
# # Key parts to send in Join frames to each capability. # # Key parts to send in Join messages to each capability.
# #
# joiner :Joiner; # joiner :Joiner;
# # Used to establish the final connection. # # Used to establish the final connection.
# } # }
# #
# interface Joiner { # interface Joiner {
# addHostId(hostId :JoinHostId) :Void; # addJoinAnswer(answer :JoinAnswer) :Void;
# # Add a host ID at which the host might live. All `JoinHostId`s returned from all paths # # Add a JoinAnswer received in response to one of the `Join` messages. All `JoinAnswer`s
# # must be added before trying to connect. # # returned from all paths must be added before trying to connect.
# #
# connect() :ConnectionAndProvisionId; # connect() :ConnectionAndProvisionId;
# # Try to form a connection to the joined capability's host, verifying that it has received # # Try to form a connection to the joined capability's host, verifying that it has received
# # all of the JoinKeyParts. Once the connection is formed, the caller should send an `Accept` # # all of the JoinKeyParts. Once the connection is formed, the caller should send an `Accept`
# # frame on it with the specified `ProvisionId` in order to receive the final capability. # # message on it with the specified `ProvisionId` in order to receive the final capability.
# } # }
# #
# acceptConnectionFromJoiner(parts: List(JoinKeyPart), paths :List(VatPath)) # acceptConnectionFromJoiner(parts: List(JoinKeyPart), paths :List(VatPath))
# :ConnectionAndProvisionId; # :ConnectionAndProvisionId;
# # Called on a joined capability's host to receive the connection from the joiner, once all # # Called on a joined capability's host to receive the connection from the joiner, once all
# # key parts have arrived. The caller should expect to receive an `Accept` frame over the # # key parts have arrived. The caller should expect to receive an `Accept` message over the
# # connection with the given ProvisionId. # # connection with the given ProvisionId.
# } # }
# #
# interface Connection { # interface Connection {
# # Level 1 features ----------------------------------------------- # # Level 1 features -----------------------------------------------
# #
# send(frame :Frame) :Void; # send(message :Message) :Void;
# # Send the frame. Returns successfully when the frame (and all preceding frames) has been # # Send the message. Returns successfully when the message (and all preceding messages) has
# # acknowledged by the recipient. # # been acknowledged by the recipient.
# #
# receive() :Frame; # receive() :Message;
# # Receive the next frame, and acknowledges receipt to the sender. Frames are received in the # # Receive the next message, and acknowledges receipt to the sender. Messages are received in
# # order in which they are sent. # # the order in which they are sent.
# #
# # Level 2 features ----------------------------------------------- # # Level 2 features -----------------------------------------------
# #
# introduceTo(recipient :Connection) :IntroductionInfo; # introduceTo(recipient :Connection) :IntroductionInfo;
# # Call before starting a three-way introduction, assuming a `Provide` frame is to be sent on # # Call before starting a three-way introduction, assuming a `Provide` message is to be sent on
# # this connection and a `ThirdPartyCapId` is to be sent to `recipient`. # # this connection and a `ThirdPartyCapId` is to be sent to `recipient`.
# #
# struct IntroductionInfo { # struct IntroductionInfo {
...@@ -781,18 +797,18 @@ using JoinHostId = Object; ...@@ -781,18 +797,18 @@ using JoinHostId = Object;
# #
# connectToIntroduced(capId: ThirdPartyCapId) :ConnectionAndProvisionId; # connectToIntroduced(capId: ThirdPartyCapId) :ConnectionAndProvisionId;
# # Given a ThirdPartyCapId received over this connection, connect to the third party. The # # Given a ThirdPartyCapId received over this connection, connect to the third party. The
# # caller should then send an `Accept` frame over the new connection. # # caller should then send an `Accept` message over the new connection.
# #
# acceptIntroducedConnection(recipientId: RecipientId): Connection # acceptIntroducedConnection(recipientId: RecipientId): Connection
# # Given a RecipientId received in a `Provide` frame on this `Connection`, wait for the # # Given a RecipientId received in a `Provide` message on this `Connection`, wait for the
# # recipient to connect, and return the connection formed. Usually, the first frame received # # recipient to connect, and return the connection formed. Usually, the first message received
# # on the new connection will be an `Accept` frame. # # on the new connection will be an `Accept` message.
# } # }
# #
# sturct ConnectionAndProvisionId { # sturct ConnectionAndProvisionId {
# connection :Connection; # connection :Connection;
# # Connection on which to issue `Accept` frame. # # Connection on which to issue `Accept` message.
# #
# provision :ProvisionId; # provision :ProvisionId;
# # `ProvisionId` to send in the `Accept` frame. # # `ProvisionId` to send in the `Accept` message.
# } # }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment