Mercurial > hg > sv-dependency-builds
comparison win64-msvc/include/capnp/rpc-twoparty.capnp @ 47:d93140aac40b
Current Capnp libs and headers from git
author | Chris Cannam |
---|---|
date | Thu, 20 Oct 2016 18:15:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
46:efe5b9f38b13 | 47:d93140aac40b |
---|---|
1 # Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors | |
2 # Licensed under the MIT License: | |
3 # | |
4 # Permission is hereby granted, free of charge, to any person obtaining a copy | |
5 # of this software and associated documentation files (the "Software"), to deal | |
6 # in the Software without restriction, including without limitation the rights | |
7 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
8 # copies of the Software, and to permit persons to whom the Software is | |
9 # furnished to do so, subject to the following conditions: | |
10 # | |
11 # The above copyright notice and this permission notice shall be included in | |
12 # all copies or substantial portions of the Software. | |
13 # | |
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
17 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
20 # THE SOFTWARE. | |
21 | |
22 @0xa184c7885cdaf2a1; | |
23 # This file defines the "network-specific parameters" in rpc.capnp to support a network consisting | |
24 # of two vats. Each of these vats may in fact be in communication with other vats, but any | |
25 # capabilities they forward must be proxied. Thus, to each end of the connection, all capabilities | |
26 # received from the other end appear to live in a single vat. | |
27 # | |
28 # Two notable use cases for this model include: | |
29 # - Regular client-server communications, where a remote client machine (perhaps living on an end | |
30 # user's personal device) connects to a server. The server may be part of a cluster, and may | |
31 # call on other servers in the cluster to help service the user's request. It may even obtain | |
32 # capabilities from these other servers which it passes on to the user. To simplify network | |
33 # common traversal problems (e.g. if the user is behind a firewall), it is probably desirable to | |
34 # multiplex all communications between the server cluster and the client over the original | |
35 # connection rather than form new ones. This connection should use the two-party protocol, as | |
36 # the client has no interest in knowing about additional servers. | |
37 # - Applications running in a sandbox. A supervisor process may execute a confined application | |
38 # such that all of the confined app's communications with the outside world must pass through | |
39 # the supervisor. In this case, the connection between the confined app and the supervisor might | |
40 # as well use the two-party protocol, because the confined app is intentionally prevented from | |
41 # talking to any other vat anyway. Any external resources will be proxied through the supervisor, | |
42 # and so to the contained app will appear as if they were hosted by the supervisor itself. | |
43 # | |
44 # Since there are only two vats in this network, there is never a need for three-way introductions, | |
45 # so level 3 is free. Moreover, because it is never necessary to form new connections, the | |
46 # two-party protocol can be used easily anywhere where a two-way byte stream exists, without regard | |
47 # to where that byte stream goes or how it was initiated. This makes the two-party runtime library | |
48 # highly reusable. | |
49 # | |
50 # Joins (level 4) _could_ be needed in cases where one or both vats are participating in other | |
51 # networks that use joins. For instance, if Alice and Bob are speaking through the two-party | |
52 # protocol, and Bob is also participating on another network, Bob may send Alice two or more | |
53 # proxied capabilities which, unbeknownst to Bob at the time, are in fact pointing at the same | |
54 # remote object. Alice may then request to join these capabilities, at which point Bob will have | |
55 # to forward the join to the other network. Note, however, that if Alice is _not_ participating on | |
56 # any other network, then Alice will never need to _receive_ a Join, because Alice would always | |
57 # know when two locally-hosted capabilities are the same and would never export a redundant alias | |
58 # to Bob. So, Alice can respond to all incoming joins with an error, and only needs to implement | |
59 # outgoing joins if she herself desires to use this feature. Also, outgoing joins are relatively | |
60 # easy to implement in this scenario. | |
61 # | |
62 # What all this means is that a level 4 implementation of the confined network is barely more | |
63 # complicated than a level 2 implementation. However, such an implementation allows the "client" | |
64 # or "confined" app to access the server's/supervisor's network with equal functionality to any | |
65 # native participant. In other words, an application which implements only the two-party protocol | |
66 # can be paired with a proxy app in order to participate in any network. | |
67 # | |
68 # So, when implementing Cap'n Proto in a new language, it makes sense to implement only the | |
69 # two-party protocol initially, and then pair applications with an appropriate proxy written in | |
70 # C++, rather than implement other parameterizations of the RPC protocol directly. | |
71 | |
72 using Cxx = import "/capnp/c++.capnp"; | |
73 $Cxx.namespace("capnp::rpc::twoparty"); | |
74 | |
75 # Note: SturdyRef is not specified here. It is up to the application to define semantics of | |
76 # SturdyRefs if desired. | |
77 | |
78 enum Side { | |
79 server @0; | |
80 # The object lives on the "server" or "supervisor" end of the connection. Only the | |
81 # server/supervisor knows how to interpret the ref; to the client, it is opaque. | |
82 # | |
83 # Note that containers intending to implement strong confinement should rewrite SturdyRefs | |
84 # received from the external network before passing them on to the confined app. The confined | |
85 # app thus does not ever receive the raw bits of the SturdyRef (which it could perhaps | |
86 # maliciously leak), but instead receives only a thing that it can pass back to the container | |
87 # later to restore the ref. See: | |
88 # http://www.erights.org/elib/capability/dist-confine.html | |
89 | |
90 client @1; | |
91 # The object lives on the "client" or "confined app" end of the connection. Only the client | |
92 # knows how to interpret the ref; to the server/supervisor, it is opaque. Most clients do not | |
93 # actually know how to persist capabilities at all, so use of this is unusual. | |
94 } | |
95 | |
96 struct VatId { | |
97 side @0 :Side; | |
98 } | |
99 | |
100 struct ProvisionId { | |
101 # Only used for joins, since three-way introductions never happen on a two-party network. | |
102 | |
103 joinId @0 :UInt32; | |
104 # The ID from `JoinKeyPart`. | |
105 } | |
106 | |
107 struct RecipientId {} | |
108 # Never used, because there are only two parties. | |
109 | |
110 struct ThirdPartyCapId {} | |
111 # Never used, because there is no third party. | |
112 | |
113 struct JoinKeyPart { | |
114 # Joins in the two-party case are simplified by a few observations. | |
115 # | |
116 # First, on a two-party network, a Join only ever makes sense if the receiving end is also | |
117 # connected to other networks. A vat which is not connected to any other network can safely | |
118 # reject all joins. | |
119 # | |
120 # Second, since a two-party connection bisects the network -- there can be no other connections | |
121 # between the networks at either end of the connection -- if one part of a join crosses the | |
122 # connection, then _all_ parts must cross it. Therefore, a vat which is receiving a Join request | |
123 # off some other network which needs to be forwarded across the two-party connection can | |
124 # collect all the parts on its end and only forward them across the two-party connection when all | |
125 # have been received. | |
126 # | |
127 # For example, imagine that Alice and Bob are vats connected over a two-party connection, and | |
128 # each is also connected to other networks. At some point, Alice receives one part of a Join | |
129 # request off her network. The request is addressed to a capability that Alice received from | |
130 # Bob and is proxying to her other network. Alice goes ahead and responds to the Join part as | |
131 # if she hosted the capability locally (this is important so that if not all the Join parts end | |
132 # up at Alice, the original sender can detect the failed Join without hanging). As other parts | |
133 # trickle in, Alice verifies that each part is addressed to a capability from Bob and continues | |
134 # to respond to each one. Once the complete set of join parts is received, Alice checks if they | |
135 # were all for the exact same capability. If so, she doesn't need to send anything to Bob at | |
136 # all. Otherwise, she collects the set of capabilities (from Bob) to which the join parts were | |
137 # addressed and essentially initiates a _new_ Join request on those capabilities to Bob. Alice | |
138 # does not forward the Join parts she received herself, but essentially forwards the Join as a | |
139 # whole. | |
140 # | |
141 # On Bob's end, since he knows that Alice will always send all parts of a Join together, he | |
142 # simply waits until he's received them all, then performs a join on the respective capabilities | |
143 # as if it had been requested locally. | |
144 | |
145 joinId @0 :UInt32; | |
146 # A number identifying this join, chosen by the sender. May be reused once `Finish` messages are | |
147 # sent corresponding to all of the `Join` messages. | |
148 | |
149 partCount @1 :UInt16; | |
150 # The number of capabilities to be joined. | |
151 | |
152 partNum @2 :UInt16; | |
153 # Which part this request targets -- a number in the range [0, partCount). | |
154 } | |
155 | |
156 struct JoinResult { | |
157 joinId @0 :UInt32; | |
158 # Matches `JoinKeyPart`. | |
159 | |
160 succeeded @1 :Bool; | |
161 # All JoinResults in the set will have the same value for `succeeded`. The receiver actually | |
162 # implements the join by waiting for all the `JoinKeyParts` and then performing its own join on | |
163 # them, then going back and answering all the join requests afterwards. | |
164 | |
165 cap @2 :AnyPointer; | |
166 # One of the JoinResults will have a non-null `cap` which is the joined capability. | |
167 # | |
168 # TODO(cleanup): Change `AnyPointer` to `Capability` when that is supported. | |
169 } |