signalling.proto 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. syntax = "proto2";
  2. // TODO: We're using proto2 because it's the default on Ubuntu 16.04.
  3. // At some point we will want to migrate to proto3, but we are not
  4. // using any proto3 features yet.
  5. package tapdance;
  6. enum KeyType {
  7. AES_GCM_128 = 90;
  8. AES_GCM_256 = 91; // not supported atm
  9. }
  10. message PubKey {
  11. // A public key, as used by the station.
  12. optional bytes key = 1;
  13. optional KeyType type = 2;
  14. }
  15. message TLSDecoySpec {
  16. // The hostname/SNI to use for this host
  17. //
  18. // The hostname is the only required field, although other
  19. // fields are expected to be present in most cases.
  20. optional string hostname = 1;
  21. // The 32-bit ipv4 address, in network byte order
  22. //
  23. // If the IPv4 address is absent, then it may be resolved via
  24. // DNS by the client, or the client may discard this decoy spec
  25. // if local DNS is untrusted, or the service may be multihomed.
  26. optional fixed32 ipv4addr = 2;
  27. // The 128-bit ipv6 address, in network byte order
  28. optional bytes ipv6addr = 6;
  29. // The Tapdance station public key to use when contacting this
  30. // decoy
  31. //
  32. // If omitted, the default station public key (if any) is used.
  33. optional PubKey pubkey = 3;
  34. // The maximum duration, in milliseconds, to maintain an open
  35. // connection to this decoy (because the decoy may close the
  36. // connection itself after this length of time)
  37. //
  38. // If omitted, a default of 30,000 milliseconds is assumed.
  39. optional uint32 timeout = 4;
  40. // The maximum TCP window size to attempt to use for this decoy.
  41. //
  42. // If omitted, a default of 15360 is assumed.
  43. //
  44. // TODO: the default is based on the current heuristic of only
  45. // using decoys that permit windows of 15KB or larger. If this
  46. // heuristic changes, then this default doesn't make sense.
  47. optional uint32 tcpwin = 5;
  48. }
  49. // In version 1, the request is very simple: when
  50. // the client sends a MSG_PROTO to the station, if the
  51. // generation number is present, then this request includes
  52. // (in addition to whatever other operations are part of the
  53. // request) a request for the station to send a copy of
  54. // the current decoy set that has a generation number greater
  55. // than the generation number in its request.
  56. //
  57. // If the response contains a DecoyListUpdate with a generation number equal
  58. // to that which the client sent, then the client is "caught up" with
  59. // the station and the response contains no new information
  60. // (and all other fields may be omitted or empty). Otherwise,
  61. // the station will send the latest configuration information,
  62. // along with its generation number.
  63. //
  64. // The station can also send ClientConf messages
  65. // (as part of Station2Client messages) whenever it wants.
  66. // The client is expected to react as if it had requested
  67. // such messages -- possibly by ignoring them, if the client
  68. // is already up-to-date according to the generation number.
  69. message ClientConf {
  70. optional DecoyList decoy_list = 1;
  71. optional uint32 generation = 2;
  72. optional PubKey default_pubkey = 3;
  73. optional PhantomSubnetsList phantom_subnets_list = 4;
  74. optional PubKey conjure_pubkey = 5;
  75. }
  76. message DecoyList {
  77. repeated TLSDecoySpec tls_decoys = 1;
  78. }
  79. message PhantomSubnetsList{
  80. repeated PhantomSubnets weighted_subnets = 1;
  81. }
  82. message PhantomSubnets{
  83. optional uint32 weight = 1;
  84. repeated string subnets = 2;
  85. }
  86. // State transitions of the client
  87. enum C2S_Transition {
  88. C2S_NO_CHANGE = 0;
  89. C2S_SESSION_INIT = 1; // connect me to squid
  90. C2S_SESSION_COVERT_INIT = 11; // connect me to provided covert
  91. C2S_EXPECT_RECONNECT = 2;
  92. C2S_SESSION_CLOSE = 3;
  93. C2S_YIELD_UPLOAD = 4;
  94. C2S_ACQUIRE_UPLOAD = 5;
  95. C2S_EXPECT_UPLOADONLY_RECONN = 6;
  96. C2S_ERROR = 255;
  97. }
  98. // State transitions of the server
  99. enum S2C_Transition {
  100. S2C_NO_CHANGE = 0;
  101. S2C_SESSION_INIT = 1; // connected to squid
  102. S2C_SESSION_COVERT_INIT = 11; // connected to covert host
  103. S2C_CONFIRM_RECONNECT = 2;
  104. S2C_SESSION_CLOSE = 3;
  105. // TODO should probably also allow EXPECT_RECONNECT here, for DittoTap
  106. S2C_ERROR = 255;
  107. }
  108. // Should accompany all S2C_ERROR messages.
  109. enum ErrorReasonS2C {
  110. NO_ERROR = 0;
  111. COVERT_STREAM = 1; // Squid TCP connection broke
  112. CLIENT_REPORTED = 2; // You told me something was wrong, client
  113. CLIENT_PROTOCOL = 3; // You messed up, client (e.g. sent a bad protobuf)
  114. STATION_INTERNAL = 4; // I broke
  115. DECOY_OVERLOAD = 5; // Everything's fine, but don't use this decoy right now
  116. CLIENT_STREAM = 100; // My stream to you broke. (This is impossible to send)
  117. CLIENT_TIMEOUT = 101; // You never came back. (This is impossible to send)
  118. }
  119. enum TransportType {
  120. Null = 0;
  121. Min = 1; // Send a 32-byte HMAC id to let the station distinguish registrations to same host
  122. Obfs4 = 2; // Not implemented yet?
  123. Webrtc = 99; // UDP transport: WebRTC DataChannel
  124. }
  125. // Deflated ICE Candidate by seed2sdp package
  126. message WebRTCICECandidate {
  127. // IP is represented in its 16-byte form
  128. required uint64 ip_upper = 1;
  129. required uint64 ip_lower = 2;
  130. // Composed info includes port, tcptype (unset if not tcp), candidate type (host, srflx, prflx), protocol (TCP/UDP), and component (RTP/RTCP)
  131. required uint32 composed_info = 3;
  132. }
  133. // Deflated SDP for WebRTC by seed2sdp package
  134. message WebRTCSDP {
  135. required uint32 type = 1;
  136. repeated WebRTCICECandidate candidates = 2; // there could be multiple candidates
  137. }
  138. // WebRTCSignal includes a deflated SDP and a seed
  139. message WebRTCSignal {
  140. required string seed = 1;
  141. required WebRTCSDP sdp = 2;
  142. }
  143. message StationToClient {
  144. // Should accompany (at least) SESSION_INIT and CONFIRM_RECONNECT.
  145. optional uint32 protocol_version = 1;
  146. // There might be a state transition. May be absent; absence should be
  147. // treated identically to NO_CHANGE.
  148. optional S2C_Transition state_transition = 2;
  149. // The station can send client config info piggybacked
  150. // on any message, as it sees fit
  151. optional ClientConf config_info = 3;
  152. // If state_transition == S2C_ERROR, this field is the explanation.
  153. optional ErrorReasonS2C err_reason = 4;
  154. // Signals client to stop connecting for following amount of seconds
  155. optional uint32 tmp_backoff = 5;
  156. // Sent in SESSION_INIT, identifies the station that picked up
  157. optional string station_id = 6;
  158. // Random-sized junk to defeat packet size fingerprinting.
  159. optional bytes padding = 100;
  160. }
  161. message RegistrationFlags {
  162. optional bool upload_only = 1;
  163. optional bool dark_decoy = 2;
  164. optional bool proxy_header = 3;
  165. optional bool use_TIL = 4;
  166. optional bool prescanned = 5;
  167. }
  168. message ClientToStation {
  169. optional uint32 protocol_version = 1;
  170. // The client reports its decoy list's version number here, which the
  171. // station can use to decide whether to send an updated one. The station
  172. // should always send a list if this field is set to 0.
  173. optional uint32 decoy_list_generation = 2;
  174. optional C2S_Transition state_transition = 3;
  175. // The position in the overall session's upload sequence where the current
  176. // YIELD=>ACQUIRE switchover is happening.
  177. optional uint64 upload_sync = 4;
  178. // List of decoys that client have unsuccessfully tried in current session.
  179. // Could be sent in chunks
  180. repeated string failed_decoys = 10;
  181. optional SessionStats stats = 11;
  182. // NullTransport, MinTransport, Obfs4Transport, etc. Transport type we want from phantom proxy
  183. optional TransportType transport = 12;
  184. // Station is only required to check this variable during session initialization.
  185. // If set, station must facilitate connection to said target by itself, i.e. write into squid
  186. // socket an HTTP/SOCKS/any other connection request.
  187. // covert_address must have exactly one ':' colon, that separates host (literal IP address or
  188. // resolvable hostname) and port
  189. // TODO: make it required for initialization, and stop connecting any client straight to squid?
  190. optional string covert_address = 20;
  191. // Used in dark decoys to signal which dark decoy it will connect to.
  192. optional string masked_decoy_server_name = 21;
  193. // Used to indicate to server if client is registering v4, v6 or both
  194. optional bool v6_support = 22;
  195. optional bool v4_support = 23;
  196. // A collection of optional flags for the registration.
  197. optional RegistrationFlags flags = 24;
  198. // Transport Extensions
  199. optional WebRTCSignal webrtc_signal = 31;
  200. // Random-sized junk to defeat packet size fingerprinting.
  201. optional bytes padding = 100;
  202. }
  203. enum RegistrationSource {
  204. Unspecified = 0;
  205. Detector = 1;
  206. API = 2;
  207. DetectorPrescan = 3;
  208. BidirectionalAPI = 4;
  209. }
  210. message C2SWrapper {
  211. optional bytes shared_secret = 1;
  212. optional ClientToStation registration_payload = 3;
  213. optional RegistrationSource registration_source = 4;
  214. // client source address when receiving a registration
  215. optional bytes registration_address = 6;
  216. // Decoy address used when registering over Decoy registrar
  217. optional bytes decoy_address = 7;
  218. optional RegistrationResponse registration_response = 8;
  219. }
  220. message SessionStats {
  221. optional uint32 failed_decoys_amount = 20; // how many decoys were tried before success
  222. // Timings below are in milliseconds
  223. // Applicable to whole session:
  224. optional uint32 total_time_to_connect = 31; // includes failed attempts
  225. // Last (i.e. successful) decoy:
  226. optional uint32 rtt_to_station = 33; // measured during initial handshake
  227. optional uint32 tls_to_decoy = 38; // includes tcp to decoy
  228. optional uint32 tcp_to_decoy = 39; // measured when establishing tcp connection to decot
  229. }
  230. message StationToDetector {
  231. optional string phantom_ip = 1;
  232. optional string client_ip = 2;
  233. optional uint64 timeout_ns = 3;
  234. }
  235. // Adding message response from Station to Client for birdirectional API
  236. message RegistrationResponse {
  237. optional fixed32 ipv4addr = 1;
  238. // The 128-bit ipv6 address, in network byte order
  239. optional bytes ipv6addr = 2;
  240. // Respond with randomized port
  241. optional uint32 port = 3;
  242. // Future: station provides client with secret, want chanel present
  243. // Leave null for now
  244. optional bytes serverRandom = 4;
  245. // If registration wrong, populate this error string
  246. optional string error = 5;
  247. // ClientConf field (optional)
  248. optional ClientConf clientConf = 6;
  249. }