source: apps/sam/doc/sam.3.0-protocol.txt @ 1bc4cb3

Last change on this file since 1bc4cb3 was 1bc4cb3, checked in by mkvore-commit <mkvore-commit@…>, 12 years ago

SAMv3 : protocol better specified, and small changes in the code reflecting the new protocol

  • Property mode set to 100644
File size: 17.3 KB
Line 
1----------------------------------------------------------------------
2Simple Anonymous Messaging (SAM version 3.0)
3----------------------------------------------------------------------
4Client application talks to SAM bridge, which deals with
5all of the I2P functionality (using the ministreaming
6lib for virtual streams, or I2CP directly for async messages).
7
8All client<-->SAM bridge communication is unencrypted and
9unauthenticated.  Access to the SAM
10bridge should be protected through firewalls or other means
11(perhaps the bridge may have ACLs on what IPs it accepts
12connections from).
13
14All of these SAM messages are sent on a single line in plain ASCII,
15terminated by the newline character (\n).  The formatting shown
16below is merely for readability, and while the first two words in
17each message must stay in their specific order, the ordering of
18the key=value pairs can change (e.g. "ONE TWO A=B C=D" or
19"ONE TWO C=D A=B" are both perfectly valid constructions).  In
20addition, the protocol is case-sensitive.
21In the following, message examples are preceded by "-> " for
22messages sent by the client to the SAM bridge, and by "<- " for
23messages sent by the SAM bridge to the client.
24
25I2P communications can take three distinct forms:
26* Virtual streams
27* Repliable datagrams (messages with a FROM field)
28* Anonymous datagrams (raw anonymous messages)
29
30I2P communications are supported by I2P sessions, and each I2P
31session is bound to an address (called destination). An I2P session
32is associated with one of the three types above, and cannot carry
33communications of another type.
34
35 
36----------------------------------------------------------------------
37SAM connection handshake
38----------------------------------------------------------------------
39No SAM communication can occur until after the client and bridge have
40agreed on a protocol version, which is done by the client sending
41a HELLO and the bridge sending a HELLO REPLY:
42
43->  HELLO VERSION MIN=$min MAX=$max
44
45and
46
47<-  HELLO REPLY RESULT=OK VERSION=3.0
48
49*** In order to force protocol version 3.0, the values of $min and $max
50*** must be "3.0".
51
52If the SAM bridge cannot find a suitable version, it replies with :
53
54<- HELLO REPLY RESULT=NOVERSION
55
56If some error occurred, such as a bad request format, it replies with :
57
58<- HELLO REPLY RESULT=I2P_ERROR MESSAGE={$message}
59
60
61----------------------------------------------------------------------
62SAM sessions
63----------------------------------------------------------------------
64A SAM session is created by a client opening a socket to the SAM
65bridge, operating a handshake, and sending a SESSION CREATE message,
66and the session terminates when the socket is disconnected.
67
68Each registered I2P Destination is uniquely associated with a session ID
69(or nickname).
70
71Each session is uniquely associated with :
72 * the socket from which the client creates the session
73 * its ID (or nickname)
74
75The session creation message can only use one of these forms (messages
76received through other forms are answered with an error message) :
77
78->  SESSION CREATE
79          STYLE={STREAM,DATAGRAM,RAW}
80          ID={$nickname}
81          DESTINATION={$private_destination_key,TRANSIENT}
82          [option=value]*
83
84DESTINATION specifies what destination should be used for
85sending and receiving messages/streams.  It has to be a suitable
86private base64 destination key. If the destination is
87specified as TRANSIENT, the SAM bridge creates a new destination.
88
89{$nickname} is the choice of the client. No whitespace is allowed.
90
91Additional options given are passed to the I2P session
92configuration if not interpreted by the SAM bridge (e.g.
93outbound.length=0). These options are documented below.
94
95The SAM bridge itself should already be configured with what router
96it should communicate over I2P through (though if need be there may
97be a way to provide an override, e.g. i2cp.tcp.host=localhost and
98i2cp.tcp.port=7654).
99
100After receiving the session create message, the SAM bridge will reply
101with a session status message, as follows:
102
103If the creation was successful :
104<-  SESSION STATUS RESULT=OK DESTINATION={$private_destination_key}
105
106If the nickname is already associated with a session :
107<-  SESSION STATUS RESULT=DUPLICATED_ID
108
109If the destination is already in use :
110<-  SESSION STATUS RESULT=DUPLICATED_DEST
111
112If the destination is not a valid private destination key :
113<-  SESSION STATUS RESULT=INVALID_KEY
114
115If some other error has occurred :
116<-  SESSION STATUS RESULT=I2P_ERROR MESSAGE={$message}
117
118If it's not OK, the MESSAGE should contain human-readable information
119as to why the session could not be created.
120
121
122SAM sessions live and die with the socket they are associated with.
123When the socket is closed, the session dies, and all communications
124using the session die at the same time. And the other way round, when
125the session dies for any reason, the SAM bridge closes the socket.
126
127
128----------------------------------------------------------------------
129SAM virtual streams
130----------------------------------------------------------------------
131Virtual streams are guaranteed to be sent reliably and in order, with
132failure and success notification as soon as it is available.
133
134Streams are bidirectional communication sockets between two I2P
135destinations, but their opening has to be requested by one of them.
136Hereafter, CONNECT commands are used by the SAM client for such a
137request. FORWARD / ACCEPT commands are used by the SAM client when
138it wants to listen to requests coming from other I2P destinations.
139
140
141-----------------------------
142SAM virtual streams : CONNECT
143-----------------------------
144A client asks for a connection by :
145 * opening a new socket with the SAM bridge
146 * passing the same HELLO handshake as above
147 * sending the connection command : 
148
149-> STREAM CONNECT
150         ID={$nickname}
151         DESTINATION=$peer_public_base64_key
152         [SILENCE={true,false}]
153
154This establishes a new virtual connection from the local session
155whose ID is {$nickname} to the specified peer.
156
157If SILENCE=true is passed, the SAM bridge won't issue any other message
158on the socket : if the connection fails, the socket will be closed.
159If the connection succeeds, all remaining data passing through the
160current socket is forwarded from and to the connected I2P destination
161peer.
162
163If SILENCE=false, which is the default value, the SAM bridge sends a
164last message to its client before forwarding or shutting down the
165socket :
166
167<-  STREAM STATUS
168         RESULT=$result
169         [MESSAGE=...]
170
171The RESULT value may be one of:
172
173    OK
174    CANT_REACH_PEER
175    I2P_ERROR
176    INVALID_KEY
177    INVALID_ID
178    TIMEOUT
179
180If the RESULT is OK, all remaining data passing through the
181current socket is forwarded from and to the connected I2P destination
182peer. If the connection was not possible (timeout, etc),
183RESULT will contain the appropriate error value (accompanied by an
184optional human-readable MESSAGE), and the SAM bridge closes the
185socket.
186
187----------------------------
188SAM virtual streams : ACCEPT
189----------------------------
190
191A client waits for an incoming connection request by :
192 * opening a new socket with the SAM bridge
193 * passing the same HELLO handshake as above
194 * sending the accept command : 
195
196-> STREAM ACCEPT
197         ID={$nickname}
198         [SILENCE={true,false}]
199
200This makes the session ${nickname} listen for one incoming
201connection request from the I2P network.
202
203The SAM bridge answers with :
204
205<-  STREAM STATUS
206         RESULT=$result
207         [MESSAGE=...]
208
209The RESULT value may be one of:
210
211    OK
212    I2P_ERROR
213    INVALID_ID
214
215If the result is not OK, the socket is closed immediately by the SAM
216bridge. If the result is OK, the SAM bridge starts waiting for an
217incoming connection request from another I2P peer. When a request
218arrives, the SAM bridge accepts it and :
219
220 * If SILENCE=true was passed, the SAM bridge won't issue any other message
221on the client socket : all remaining data passing through the
222current socket is forwarded from and to the connected I2P destination
223peer.
224 * If SILENCE=false was passed, which is the default value, the SAM bridge
225sends the client a ASCII line containing the base64 public destination key
226of the requesting peer. After this '\n' terminated line, all remaining data
227passing through the current socket is forwarded from and to the connected
228I2P destination peer, until one of the peer closes the socket.
229
230-----------------------------
231SAM virtual streams : FORWARD
232-----------------------------
233
234A client waits for an incoming connection request by :
235 * opening a new socket with the SAM bridge
236 * passing the same HELLO handshake as above
237 * sending the forward command : 
238
239-> STREAM FORWARD
240         ID={$nickname}
241         PORT={$port}
242         [HOST={$host}]
243         [SILENCE={true,false}]
244
245This makes the session ${nickname} listen forever for incoming
246connection requests from the I2P network.
247
248The SAM bridge answers with :
249
250<-  STREAM STATUS
251         RESULT=$result
252         [MESSAGE=...]
253
254The RESULT value may be one of:
255
256    OK
257    I2P_ERROR
258    INVALID_ID
259
260The socket is closed immediately after the message by the SAM
261bridge. If the result is OK, the SAM bridge starts waiting for
262incoming connection requests from other I2P peers.
263
264 * {$host} is the hostname or IP address of the socket server to which
265SAM will forward connection requests. If not given, SAM takes the IP
266of the socket that issued the forward command.
267
268 * {$port} is the port number of the socket server to which SAM will
269forward connection requests. Is is mandatory.
270
271When a connexion request arrives from I2P, the SAM bridge requests a
272socket connexion from {$host}:{$port}. If it is accepted after no more
273than 3 seconds, SAM will accept the connexion from I2P, and then :
274
275 * If SILENCE=true was passed, all data passing through the obtained
276current socket is forwarded from and to the connected I2P destination
277peer.
278 * If SILENCE=false was passed, which is the default value, the SAM bridge
279sends on the obtained socket an ASCII line containing the base64 public
280destination key of the requesting peer. After this '\n' terminated line,
281all remaining data passing through the socket is forwarded from and to
282the connected I2P destination peer, until one of the sides closes the
283socket.
284
285
286
287
288----------------------------------------------------------------------
289SAM repliable datagrams : sending a datagram
290----------------------------------------------------------------------
291While I2P doesn't inherently contain a FROM address, for ease of use
292an additional layer is provided as repliable datagrams - unordered
293and unreliable messages of up to 31KB in size that include a FROM
294address (leaving up to 1KB for header material).  This FROM address
295is authenticated internally by SAM (making use of the destination's
296signing key to verify the source) and includes replay prevention.
297
298After establishing a SAM session with STYLE=DATAGRAM, the client can
299send datagrams through SAM's UDP port (7655).
300
301The first line of a datagram sent through this port has to be in the
302following format :
303
3043.0 {$nickname} {$base64_public_destination_key}
305
306 * 3.0 is the version of SAM
307 * {$nickname} is the id of the DGRAM session that will be used
308 * {$base64_public_destination_key} is the destination of the
309    datagram
310 * this line is '\n' terminated.
311
312The first line will be discarded by SAM before sending the remaining
313of the message to the specified destination.
314
315----------------------------------------------------------------------
316SAM repliable datagrams : receiving a datagram
317----------------------------------------------------------------------
318Received datagrams are written by SAM on the socket from which the
319datagram session was opened, unless specified otherwise by the CREATE
320command.
321
322When a datagram arrives, the bridge delivers it to the client via the
323message :
324
325<-  DATAGRAM RECEIVED
326           DESTINATION=$base64key
327           SIZE=$numBytes\n[$numBytes of data]
328
329The SAM bridge never exposes to the client the authentication headers
330or other fields, merely the data that the sender provided.  This
331continues until the session is closed (by the client dropping the
332connection).
333
334----------------------------------------------------------------------
335SAM repliable datagrams : forwarding datagrams
336----------------------------------------------------------------------
337When creating a datagram session, the client can ask SAM to forward
338incoming messages to a specified ip:port. It does so by issuing the
339CREATE command with PORT and HOST options :
340
341-> SESSION CREATE
342          STYLE=DATAGRAM
343          ID={$nickname}
344          DESTINATION={$private_destination_key,TRANSIENT}
345          PORT={$port}
346          [HOST={$host}]
347          [option=value]*
348
349 * {$host} is the hostname or IP address of the datagram server to
350     which SAM will forward datagrams. If not given, SAM takes the
351     IP of the socket that issued the forward command.
352
353 * {$port} is the port number of the datagram server to which SAM
354     will forward datagrams.
355
356When a datagram arrives, the bridge sends to the specified host:port
357a message containing the following data :
358
359${sender_base64_destination_key}\n{$datagram_payload}
360
361
362----------------------------------------------------------------------
363SAM anonymous datagrams
364----------------------------------------------------------------------
365Squeezing the most out of I2P's bandwidth, SAM allows clients to send
366and receive anonymous datagrams, leaving authentication and reply
367information up to the client themselves.  These datagrams are
368unreliable and unordered, and may be up to 32KB in size.
369
370After establishing a SAM session with STYLE=RAW, the client can
371send anonymous datagrams throug the SAM bridge exactly the same way
372he sends non anonymous datagrams.
373
374Both ways of receiving datagrams are also available for anonymous
375datagrams.
376
377When anonymous datagrams are to be written to the socket that created
378the session,the bridge delivers it to the client via:
379
380<- RAW RECEIVED
381      SIZE=$numBytes\n[$numBytes of data]
382
383When anonymous datagrams are to be forwarded to some host:port,
384the bridge sends to the specified host:port a message containing
385the following data :
386
387{$datagram_payload}
388
389
390----------------------------------------------------------------------
391SAM utility functionality
392----------------------------------------------------------------------
393The following message can be used by the client to query the SAM
394bridge for name resolution:
395
396 NAMING LOOKUP
397        NAME=$name
398
399which is answered by
400
401 NAMING REPLY
402        RESULT=$result
403        NAME=$name
404        [VALUE=$base64key]
405        [MESSAGE=$message]
406
407
408The RESULT value may be one of:
409
410    OK
411    INVALID_KEY
412    KEY_NOT_FOUND
413
414If NAME=ME, then the reply will contain the base64key used by the
415current session (useful if you're using a TRANSIENT one).  If $result
416is not OK, MESSAGE may convey a descriptive message, such as "bad
417format", etc.
418
419Public and private base64 keys can be generated using the following
420message:
421
422 DEST GENERATE
423
424which is answered by
425
426 DEST REPLY
427      PUB=$pubkey
428      PRIV=$privkey
429
430----------------------------------------------------------------------
431RESULT values
432----------------------------------------------------------------------
433These are the values that can be carried by the RESULT field, with
434their meaning:
435
436 OK              Operation completed succesfully
437 CANT_REACH_PEER The peer exists, but cannot be reached
438 DUPLICATED_DEST The specified Destination is already in use
439 I2P_ERROR       A generic I2P error (e.g. I2CP disconnection, etc.)
440 INVALID_KEY     The specified key is not valid (bad format, etc.)
441 KEY_NOT_FOUND   The naming system can't resolve the given name
442 PEER_NOT_FOUND  The peer cannot be found on the network
443 TIMEOUT         Timeout while waiting for an event (e.g. peer answer)
444
445----------------------------------------------------------------------
446Tunnel Pool Options
447----------------------------------------------------------------------
448
449These options can be passed in as name=value pairs at the end of a
450SAM SESSION CREATE line.
451
452 inbound.nickname            - Name shows up in I2P router console.
453 inbound.quantity            - Number of tunnels, default 2.
454 inbound.backupQuantity      - Number of backup tunnels, default 0.
455 inbound.rebuildPeriod       - Obsolete - ignored - the router controls rebuilding
456 inbound.duration            - Tunnels last X ms, default 10*60*1000.
457                               (change not recommended, will break anonymmity
458                                if it works at all)
459 inbound.length              - Depth of tunnels, default 2.
460 inbound.lengthVariance      - If negative, randomly skews from
461                               (length - variance) to
462                               (length + variance).  If positive, from
463                               length to (length + var), inclusive.
464                               Default -1.
465 inbound.allowZeroHop        - Zero hop allowed?  Default "true".
466 outbound.*                  - Same properties as inbound.
467 i2p.streaming.connectDelay  - If 0, connect ASAP.  If positive, wait
468                               until X ms have passed or output stream
469                               is flushed or buffer fills.  Default 0.
470 i2p.streaming.maxWindowSize - Max window size, default 64.
471
472----------------------------------------------------------------------
473Client library implementations:
474----------------------------------------------------------------------
475 C/C++:  libSAM: http://www.innographx.com/mpc/libsam/ or i2p/sam/c/
476 Python: Python/I2P: http://dev.i2p.net/contrib/apps/sam/python/index.html
477 Others: See apps/sam/ in I2P CVS.
Note: See TracBrowser for help on using the repository browser.