diff --git a/apps/sam/doc/protocol-v3.txt b/apps/sam/doc/protocol-v3.txt deleted file mode 100644 index 9aacfa124..000000000 --- a/apps/sam/doc/protocol-v3.txt +++ /dev/null @@ -1,17 +0,0 @@ -telnet localhost 7656 -HELLO VERSION MIN=3.0 MAX=3.0 -SESSION CREATE STYLE=STREAM ID=essaiSamIn DESTINATION=tYhjbFlFL38WFuO5eCzTvE0UBr4RfaqWMKlekGeMoB-Ouz7nYaWfiS-9j3jMiZT7FH~pwdmoSREOs2ZbXK84sR59P~pPfeCMxnJrk57f3U9uKzXkesjkKWYco3YAGs-G8sw8Fu2FBx0Do57yBdA9~j8Zq6pMjmgPBXCLuXG3vo0Z8zUWCjApJyFY6OXYopHck9Fz9vKy7YhC6zXFHfEuNHVkAooduiLd~aCoGij0TW3lH2rTVU-lx-DUdi6edxQ5-RvDNkXfikvytoCpRkivbNVytjCJLk~7RNU4FpBD20wTZWNJmEG3OY3cjNjawJVFdNjtgczh9K7gZ7ad-NjVjZVhXEj1lU8mk~vAH-2QE5om8dstWUwWoNDwmVDlvIJNKzQmahG~VrpFexFHXO0n3fKIXcSgWGOHDExM8w9neCt7AxUjxPDtXXuYNW~bRwcfiL-C9~z4K9rmwiTPZX0lmsToSXTF28l7WAoj~TMT9kZAjQeFRRWU5oW5oxVuonVvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABngJSS8xMyF4t82otZmCDhrKjbm-QLMtOLoumwR28ebDHEd4clF6O7aRa3d3yRH7p - -telnet localhost 7656 -HELLO VERSION MIN=3.0 MAX=3.0 -STREAM ACCEPT ID=essaiSamIn - - -telnet localhost 7656 -HELLO VERSION MIN=3.0 MAX=3.0 -SESSION CREATE STYLE=STREAM ID=essaiSamOut DESTINATION=EYUpJFeW9tiubXR0aOjvCJ~ndj3xN0Wn-ljuGdbpOEttPg7nj0VCTOQDJ~FAolzn9FIDdmR3VjM0OFFDT46Q5HN4vShXFE2VNC8e3~GjzxJfaJhijRC2R9oIOzsNlzKtInD2o9lh0PxPioNMCigwmgWuqlQHs4tjWeaYRAtooHxbrtuoCIhIdGfyVV-nAcPiyYbouKq3leETXE~4kBXm-LfWfyPtrv6OuDk3GBVVcthv19GYBmnl2YI8HpJjc-G-TvNkgYishjzIJyEW-Xrpy43R4ZBXlyQqnheGLlbOEY8NLDbyNHLRMMOGbcr~67SVE3Iw3RqQ3Dhrkq2FCaQwcDucfIUCCbOfCZgu0hlnCkS42xsUvegQeiwMxbdI~h9v7vcR3yFFOrHX6WQvIZSbFLKNGArGJcfmOJVLqw1wTC4AgYXjk3csVDPd-QWbMXOuodyBgrg27Ds2BBYTsVXWskoo6ASsMIQZ6jMfL7PkY9dPLCRParIyzb9aPmf~MntNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABHNqwgkhJnBW4ymaRsdVmITAha-ff0UiALfKSlznqp5HcSewgMHbzQ0I01TQytFnW - -telnet localhost 7656 -HELLO VERSION MIN=3.0 MAX=3.0 -STREAM CONNECT ID=essaiSamOut DESTINATION=tYhjbFlFL38WFuO5eCzTvE0UBr4RfaqWMKlekGeMoB-Ouz7nYaWfiS-9j3jMiZT7FH~pwdmoSREOs2ZbXK84sR59P~pPfeCMxnJrk57f3U9uKzXkesjkKWYco3YAGs-G8sw8Fu2FBx0Do57yBdA9~j8Zq6pMjmgPBXCLuXG3vo0Z8zUWCjApJyFY6OXYopHck9Fz9vKy7YhC6zXFHfEuNHVkAooduiLd~aCoGij0TW3lH2rTVU-lx-DUdi6edxQ5-RvDNkXfikvytoCpRkivbNVytjCJLk~7RNU4FpBD20wTZWNJmEG3OY3cjNjawJVFdNjtgczh9K7gZ7ad-NjVjZVhXEj1lU8mk~vAH-2QE5om8dstWUwWoNDwmVDlvIJNKzQmahG~VrpFexFHXO0n3fKIXcSgWGOHDExM8w9neCt7AxUjxPDtXXuYNW~bRwcfiL-C9~z4K9rmwiTPZX0lmsToSXTF28l7WAoj~TMT9kZAjQeFRRWU5oW5oxVuonVvAAAA - diff --git a/apps/sam/doc/sam.3.0-protocol.txt b/apps/sam/doc/sam.3.0-protocol.txt new file mode 100644 index 000000000..c544068db --- /dev/null +++ b/apps/sam/doc/sam.3.0-protocol.txt @@ -0,0 +1,477 @@ +---------------------------------------------------------------------- +Simple Anonymous Messaging (SAM version 3.0) +---------------------------------------------------------------------- +Client application talks to SAM bridge, which deals with +all of the I2P functionality (using the ministreaming +lib for virtual streams, or I2CP directly for async messages). + +All client<-->SAM bridge communication is unencrypted and +unauthenticated. Access to the SAM +bridge should be protected through firewalls or other means +(perhaps the bridge may have ACLs on what IPs it accepts +connections from). + +All of these SAM messages are sent on a single line in plain ASCII, +terminated by the newline character (\n). The formatting shown +below is merely for readability, and while the first two words in +each message must stay in their specific order, the ordering of +the key=value pairs can change (e.g. "ONE TWO A=B C=D" or +"ONE TWO C=D A=B" are both perfectly valid constructions). In +addition, the protocol is case-sensitive. +In the following, message examples are preceded by "-> " for +messages sent by the client to the SAM bridge, and by "<- " for +messages sent by the SAM bridge to the client. + +I2P communications can take three distinct forms: +* Virtual streams +* Repliable datagrams (messages with a FROM field) +* Anonymous datagrams (raw anonymous messages) + +I2P communications are supported by I2P sessions, and each I2P +session is bound to an address (called destination). An I2P session +is associated with one of the three types above, and cannot carry +communications of another type. + + +---------------------------------------------------------------------- +SAM connection handshake +---------------------------------------------------------------------- +No SAM communication can occur until after the client and bridge have +agreed on a protocol version, which is done by the client sending +a HELLO and the bridge sending a HELLO REPLY: + +-> HELLO VERSION MIN=$min MAX=$max + +and + +<- HELLO REPLY RESULT=OK VERSION=3.0 + +*** In order to force protocol version 3.0, the values of $min and $max +*** must be "3.0". + +If the SAM bridge cannot find a suitable version, it replies with : + +<- HELLO REPLY RESULT=NOVERSION + +If some error occurred, such as a bad request format, it replies with : + +<- HELLO REPLY RESULT=I2P_ERROR MESSAGE={$message} + + +---------------------------------------------------------------------- +SAM sessions +---------------------------------------------------------------------- +A SAM session is created by a client opening a socket to the SAM +bridge, operating a handshake, and sending a SESSION CREATE message, +and the session terminates when the socket is disconnected. + +Each registered I2P Destination is uniquely associated with a session ID +(or nickname). + +Each session is uniquely associated with : + * the socket from which the client creates the session + * its ID (or nickname) + +The session creation message can only use one of these forms (messages +received through other forms are answered with an error message) : + +-> SESSION CREATE + STYLE={STREAM,DATAGRAM,RAW} + ID={$nickname} + DESTINATION={$private_destination_key,TRANSIENT} + [option=value]* + +DESTINATION specifies what destination should be used for +sending and receiving messages/streams. It has to be a suitable +private base64 destination key. If the destination is +specified as TRANSIENT, the SAM bridge creates a new destination. + +{$nickname} is the choice of the client. No whitespace is allowed. + +Additional options given are passed to the I2P session +configuration if not interpreted by the SAM bridge (e.g. +outbound.length=0). These options are documented below. + +The SAM bridge itself should already be configured with what router +it should communicate over I2P through (though if need be there may +be a way to provide an override, e.g. i2cp.tcp.host=localhost and +i2cp.tcp.port=7654). + +After receiving the session create message, the SAM bridge will reply +with a session status message, as follows: + +If the creation was successful : +<- SESSION STATUS RESULT=OK DESTINATION={$private_destination_key} + +If the nickname is already associated with a session : +<- SESSION STATUS RESULT=DUPLICATED_ID + +If the destination is already in use : +<- SESSION STATUS RESULT=DUPLICATED_DEST + +If the destination is not a valid private destination key : +<- SESSION STATUS RESULT=INVALID_KEY + +If some other error has occurred : +<- SESSION STATUS RESULT=I2P_ERROR MESSAGE={$message} + +If it's not OK, the MESSAGE should contain human-readable information +as to why the session could not be created. + + +SAM sessions live and die with the socket they are associated with. +When the socket is closed, the session dies, and all communications +using the session die at the same time. And the other way round, when +the session dies for any reason, the SAM bridge closes the socket. + + +---------------------------------------------------------------------- +SAM virtual streams +---------------------------------------------------------------------- +Virtual streams are guaranteed to be sent reliably and in order, with +failure and success notification as soon as it is available. + +Streams are bidirectional communication sockets between two I2P +destinations, but their opening has to be requested by one of them. +Hereafter, CONNECT commands are used by the SAM client for such a +request. FORWARD / ACCEPT commands are used by the SAM client when +it wants to listen to requests coming from other I2P destinations. + + +----------------------------- +SAM virtual streams : CONNECT +----------------------------- +A client asks for a connection by : + * opening a new socket with the SAM bridge + * passing the same HELLO handshake as above + * sending the connection command : + +-> STREAM CONNECT + ID={$nickname} + DESTINATION=$peer_public_base64_key + [SILENCE={true,false}] + +This establishes a new virtual connection from the local session +whose ID is {$nickname} to the specified peer. + +If SILENCE=true is passed, the SAM bridge won't issue any other message +on the socket : if the connection fails, the socket will be closed. +If the connection succeeds, all remaining data passing through the +current socket is forwarded from and to the connected I2P destination +peer. + +If SILENCE=false, which is the default value, the SAM bridge sends a +last message to its client before forwarding or shutting down the +socket : + +<- STREAM STATUS + RESULT=$result + [MESSAGE=...] + +The RESULT value may be one of: + + OK + CANT_REACH_PEER + I2P_ERROR + INVALID_KEY + INVALID_ID + TIMEOUT + +If the RESULT is OK, all remaining data passing through the +current socket is forwarded from and to the connected I2P destination +peer. If the connection was not possible (timeout, etc), +RESULT will contain the appropriate error value (accompanied by an +optional human-readable MESSAGE), and the SAM bridge closes the +socket. + +---------------------------- +SAM virtual streams : ACCEPT +---------------------------- + +A client waits for an incoming connection request by : + * opening a new socket with the SAM bridge + * passing the same HELLO handshake as above + * sending the accept command : + +-> STREAM ACCEPT + ID={$nickname} + [SILENCE={true,false}] + +This makes the session ${nickname} listen for one incoming +connection request from the I2P network. + +The SAM bridge answers with : + +<- STREAM STATUS + RESULT=$result + [MESSAGE=...] + +The RESULT value may be one of: + + OK + I2P_ERROR + INVALID_ID + +If the result is not OK, the socket is closed immediately by the SAM +bridge. If the result is OK, the SAM bridge starts waiting for an +incoming connection request from another I2P peer. When a request +arrives, the SAM bridge accepts it and : + + * If SILENCE=true was passed, the SAM bridge won't issue any other message +on the client socket : all remaining data passing through the +current socket is forwarded from and to the connected I2P destination +peer. + * If SILENCE=false was passed, which is the default value, the SAM bridge +sends the client a ASCII line containing the base64 public destination key +of the requesting peer. After this '\n' terminated line, all remaining data +passing through the current socket is forwarded from and to the connected +I2P destination peer, until one of the peer closes the socket. + +----------------------------- +SAM virtual streams : FORWARD +----------------------------- + +A client waits for an incoming connection request by : + * opening a new socket with the SAM bridge + * passing the same HELLO handshake as above + * sending the forward command : + +-> STREAM FORWARD + ID={$nickname} + PORT={$port} + [HOST={$host}] + [SILENCE={true,false}] + +This makes the session ${nickname} listen forever for incoming +connection requests from the I2P network. + +The SAM bridge answers with : + +<- STREAM STATUS + RESULT=$result + [MESSAGE=...] + +The RESULT value may be one of: + + OK + I2P_ERROR + INVALID_ID + +The socket is closed immediately after the message by the SAM +bridge. If the result is OK, the SAM bridge starts waiting for +incoming connection requests from other I2P peers. + + * {$host} is the hostname or IP address of the socket server to which +SAM will forward connection requests. If not given, SAM takes the IP +of the socket that issued the forward command. + + * {$port} is the port number of the socket server to which SAM will +forward connection requests. Is is mandatory. + +When a connexion request arrives from I2P, the SAM bridge requests a +socket connexion from {$host}:{$port}. If it is accepted after no more +than 3 seconds, SAM will accept the connexion from I2P, and then : + + * If SILENCE=true was passed, all data passing through the obtained +current socket is forwarded from and to the connected I2P destination +peer. + * If SILENCE=false was passed, which is the default value, the SAM bridge +sends on the obtained socket an ASCII line containing the base64 public +destination key of the requesting peer. After this '\n' terminated line, +all remaining data passing through the socket is forwarded from and to +the connected I2P destination peer, until one of the sides closes the +socket. + + + + +---------------------------------------------------------------------- +SAM repliable datagrams : sending a datagram +---------------------------------------------------------------------- +While I2P doesn't inherently contain a FROM address, for ease of use +an additional layer is provided as repliable datagrams - unordered +and unreliable messages of up to 31KB in size that include a FROM +address (leaving up to 1KB for header material). This FROM address +is authenticated internally by SAM (making use of the destination's +signing key to verify the source) and includes replay prevention. + +After establishing a SAM session with STYLE=DATAGRAM, the client can +send datagrams through SAM's UDP port (7655). + +The first line of a datagram sent through this port has to be in the +following format : + +3.0 {$nickname} {$base64_public_destination_key} + + * 3.0 is the version of SAM + * {$nickname} is the id of the DGRAM session that will be used + * {$base64_public_destination_key} is the destination of the + datagram + * this line is '\n' terminated. + +The first line will be discarded by SAM before sending the remaining +of the message to the specified destination. + +---------------------------------------------------------------------- +SAM repliable datagrams : receiving a datagram +---------------------------------------------------------------------- +Received datagrams are written by SAM on the socket from which the +datagram session was opened, unless specified otherwise by the CREATE +command. + +When a datagram arrives, the bridge delivers it to the client via the +message : + +<- DATAGRAM RECEIVED + DESTINATION=$base64key + SIZE=$numBytes\n[$numBytes of data] + +The SAM bridge never exposes to the client the authentication headers +or other fields, merely the data that the sender provided. This +continues until the session is closed (by the client dropping the +connection). + +---------------------------------------------------------------------- +SAM repliable datagrams : forwarding datagrams +---------------------------------------------------------------------- +When creating a datagram session, the client can ask SAM to forward +incoming messages to a specified ip:port. It does so by issuing the +CREATE command with PORT and HOST options : + +-> SESSION CREATE + STYLE=DATAGRAM + ID={$nickname} + DESTINATION={$private_destination_key,TRANSIENT} + PORT={$port} + [HOST={$host}] + [option=value]* + + * {$host} is the hostname or IP address of the datagram server to + which SAM will forward datagrams. If not given, SAM takes the + IP of the socket that issued the forward command. + + * {$port} is the port number of the datagram server to which SAM + will forward datagrams. + +When a datagram arrives, the bridge sends to the specified host:port +a message containing the following data : + +${sender_base64_destination_key}\n{$datagram_payload} + + +---------------------------------------------------------------------- +SAM anonymous datagrams +---------------------------------------------------------------------- +Squeezing the most out of I2P's bandwidth, SAM allows clients to send +and receive anonymous datagrams, leaving authentication and reply +information up to the client themselves. These datagrams are +unreliable and unordered, and may be up to 32KB in size. + +After establishing a SAM session with STYLE=RAW, the client can +send anonymous datagrams throug the SAM bridge exactly the same way +he sends non anonymous datagrams. + +Both ways of receiving datagrams are also available for anonymous +datagrams. + +When anonymous datagrams are to be written to the socket that created +the session,the bridge delivers it to the client via: + +<- RAW RECEIVED + SIZE=$numBytes\n[$numBytes of data] + +When anonymous datagrams are to be forwarded to some host:port, +the bridge sends to the specified host:port a message containing +the following data : + +{$datagram_payload} + + +---------------------------------------------------------------------- +SAM utility functionality +---------------------------------------------------------------------- +The following message can be used by the client to query the SAM +bridge for name resolution: + + NAMING LOOKUP + NAME=$name + +which is answered by + + NAMING REPLY + RESULT=$result + NAME=$name + [VALUE=$base64key] + [MESSAGE=$message] + + +The RESULT value may be one of: + + OK + INVALID_KEY + KEY_NOT_FOUND + +If NAME=ME, then the reply will contain the base64key used by the +current session (useful if you're using a TRANSIENT one). If $result +is not OK, MESSAGE may convey a descriptive message, such as "bad +format", etc. + +Public and private base64 keys can be generated using the following +message: + + DEST GENERATE + +which is answered by + + DEST REPLY + PUB=$pubkey + PRIV=$privkey + +---------------------------------------------------------------------- +RESULT values +---------------------------------------------------------------------- +These are the values that can be carried by the RESULT field, with +their meaning: + + OK Operation completed succesfully + CANT_REACH_PEER The peer exists, but cannot be reached + DUPLICATED_DEST The specified Destination is already in use + I2P_ERROR A generic I2P error (e.g. I2CP disconnection, etc.) + INVALID_KEY The specified key is not valid (bad format, etc.) + KEY_NOT_FOUND The naming system can't resolve the given name + PEER_NOT_FOUND The peer cannot be found on the network + TIMEOUT Timeout while waiting for an event (e.g. peer answer) + +---------------------------------------------------------------------- +Tunnel Pool Options +---------------------------------------------------------------------- + +These options can be passed in as name=value pairs at the end of a +SAM SESSION CREATE line. + + inbound.nickname - Name shows up in I2P router console. + inbound.quantity - Number of tunnels, default 2. + inbound.backupQuantity - Number of backup tunnels, default 0. + inbound.rebuildPeriod - Obsolete - ignored - the router controls rebuilding + inbound.duration - Tunnels last X ms, default 10*60*1000. + (change not recommended, will break anonymmity + if it works at all) + inbound.length - Depth of tunnels, default 2. + inbound.lengthVariance - If negative, randomly skews from + (length - variance) to + (length + variance). If positive, from + length to (length + var), inclusive. + Default -1. + inbound.allowZeroHop - Zero hop allowed? Default "true". + outbound.* - Same properties as inbound. + i2p.streaming.connectDelay - If 0, connect ASAP. If positive, wait + until X ms have passed or output stream + is flushed or buffer fills. Default 0. + i2p.streaming.maxWindowSize - Max window size, default 64. + +---------------------------------------------------------------------- +Client library implementations: +---------------------------------------------------------------------- + C/C++: libSAM: http://www.innographx.com/mpc/libsam/ or i2p/sam/c/ + Python: Python/I2P: http://dev.i2p.net/contrib/apps/sam/python/index.html + Others: See apps/sam/ in I2P CVS.