Moved SAM and BOB pages to docs/api
This commit is contained in:
255
i2p2www/pages/site/docs/api/bob.html
Normal file
255
i2p2www/pages/site/docs/api/bob.html
Normal file
@ -0,0 +1,255 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}BOB{% endblock %}
|
||||
{% block content %}
|
||||
<pre>
|
||||
Technical differences from SAM (for the better?)
|
||||
|
||||
|
||||
BOB has separate command and data channels.
|
||||
One, an application command channel socket to router to configure.
|
||||
Two, the application data sockets to/from router that carry only data.
|
||||
The command channel is only needed for making or setting the initial
|
||||
destination key, and to set the destination key to port bindings.
|
||||
All connections run in parallel.
|
||||
|
||||
SAM One connection that does everything, and you need to parse every packet.
|
||||
|
||||
BOB does not hold keypair values, nor does the router.
|
||||
Your application holds the keypair values.
|
||||
This is to reduce any extra complexity in the router code, it also adds to
|
||||
your privacy.
|
||||
|
||||
SAM router stores every keypair you ever make.
|
||||
|
||||
Those are the important differences.
|
||||
|
||||
KEYS = keypair public+private, these are BASE64
|
||||
KEY = public key, also BASE64
|
||||
|
||||
ERROR as is implied returns the message "ERROR "+DESCRIPTION+"\n", where the DESCRIPTION is what went wrong.
|
||||
OK returns "OK", and if data is to be returned, it is on the same line. OK means the command is finished.
|
||||
DATA lines contain information that you requested. There may be multiple DATA lines per request.
|
||||
|
||||
NOTE: The help command is the ONLY command that has an exception to
|
||||
the rules... it can actually return nothing! This is intentional, since
|
||||
help is a HUMAN and not an APPLICATION command.
|
||||
|
||||
PLEASE NOTE:
|
||||
For CURRENT details on the commands PLEASE use the built-in help command.
|
||||
Just telnet to localhost 2827 and type help and you can get full documentation on each command.
|
||||
|
||||
Commands never get obsoleted or changed, however new commands do get added from time to time.
|
||||
|
||||
Here are the commands we have as of this writing (Aug 2010).
|
||||
|
||||
COMMAND OPERAND RETURNS
|
||||
help (optional command to get help on) NOTHING or OK and description of the command
|
||||
clear ERROR or OK
|
||||
getdest ERROR or OK and KEY
|
||||
getkeys ERROR or OK and KEYS
|
||||
getnick tunnelname ERROR or OK
|
||||
inhost hostname or IP address ERROR or OK
|
||||
inport port number ERROR or OK
|
||||
list ERROR or DATA lines and final OK
|
||||
newkeys ERROR or OK and KEY
|
||||
option ERROR or OK
|
||||
outhost hostname or IP address ERROR or OK
|
||||
outport port number ERROR or OK
|
||||
quiet ERROR or OK
|
||||
quit OK and terminates the command connection
|
||||
setkeys KEYS ERROR or OK
|
||||
setnick tunnel nickname ERROR or OK
|
||||
show ERROR or OK and information
|
||||
showprops ERROR or OK and information
|
||||
start ERROR or OK
|
||||
status tunnel nickname ERROR or OK and information
|
||||
stop ERROR or OK
|
||||
verify KEY ERROR or OK
|
||||
visit OK, and dumps BOB's threads to the wrapper.log
|
||||
zap nothing, quits BOB
|
||||
|
||||
Once set up, all TCP sockets can and will block as needed, and there is no need for any
|
||||
additional messages to/from the command channel. This allows the router to pace the
|
||||
stream without exploding with OOM like SAM does as it chokes on attempting to shove
|
||||
many streams in or out one socket -- that can't scale when you have alot of connections!
|
||||
|
||||
What is also nice about this particular interface is that writing anything to interface
|
||||
to it, is much much easier than SAM. There is no other processing to do after the set up.
|
||||
It's configuration is so simple, that very simple tools, such as nc (netcat) can be used
|
||||
to point to some application. The value there is that one could schedule up and down times
|
||||
for an application, and not have to change the application to do that, or to even have
|
||||
to stop that application. Instead, you can literally "unplug" the destination, and
|
||||
"plug it in" again. As long as the same IP/port addresses and destination keys are used
|
||||
when bringing the bridge up, the normal TCP application won't care, and won't notice.
|
||||
It will simply be fooled -- the destinations are not reachable, and that nothing is coming in.
|
||||
|
||||
For the following example, we'll setup a very simple local loopback connection,
|
||||
with two destinations. Destination "mouth" will be the CHARGEN service from
|
||||
the INET superserver daemon. Destination "ear" will be a local port that you
|
||||
can telnet into, and watch the pretty ASCII test puke forth.
|
||||
|
||||
EXAMPLE SESSION DIALOGUE -- simple telnet 127.0.0.1 2827 works
|
||||
A = Application
|
||||
C = BOB's Command response.
|
||||
|
||||
FROM TO DIALOGUE
|
||||
A C setnick mouth
|
||||
C A OK Nickname set to mouth
|
||||
A C newkeys
|
||||
C A OK ZMPz1zinTdy3~zGD~f3g9aikZTipujEvvXOEyYfq4Su-mNKerqG710hFbkR6P-xkouVyNQsqWLI8c6ngnkSwGdUfM7hGccqBYDjIubTrlr~0g2-l0vM7Y8nSqtFrSdMw~pyufXZ0Ys3NqUSb8NuZXpiH2lCCkFG21QPRVfKBGwvvyDVU~hPVfBHuR8vkd5x0teMXGGmiTzdB96DuNRWayM0y8vkP-1KJiPFxKjOXULjuXhLmINIOYn39bQprq~dAtNALoBgd-waZedYgFLvwHDCc9Gui8Cpp41EihlYGNW0cu0vhNFUN79N4DEpO7AtJyrSu5ZjFTAGjLw~lOvhyO2NwQ4RiC4UCKSuM70Fz0BFKTJquIjUNkQ8pBPBYvJRRlRG9HjAcSqAMckC3pvKKlcTJJBAE8GqexV7rdCCIsnasJXle-6DoWrDkY1s1KNbEVH6i1iUEtmFr2IHTpPeFCyWfZ581CAFNRbbUs-MmnZu1tXAYF7I2-oXTH2hXoxCGAAAA
|
||||
|
||||
MAKE NOTE OF THE ABOVE DESTINATION KEY, YOURS WILL BE DIFFERENT!
|
||||
|
||||
FROM TO DIALOGUE
|
||||
A C outhost 127.0.0.1
|
||||
C A OK outhost set
|
||||
A C outport 19
|
||||
C A OK outbound port set
|
||||
A C start
|
||||
C A OK tunnel starting
|
||||
|
||||
At this point, there was no error, a destination with a nickname of "mouth"
|
||||
is set up. When you contact the destination provided, you actually connect
|
||||
to the CHARGEN service on 19/TCP.
|
||||
|
||||
Now for the other half, so that we can actually contact this destination.
|
||||
|
||||
FROM TO DIALOGUE
|
||||
A C setnick ear
|
||||
C A OK Nickname set to ear
|
||||
A C newkeys
|
||||
C A OK 8SlWuZ6QNKHPZ8KLUlExLwtglhizZ7TG19T7VwN25AbLPsoxW0fgLY8drcH0r8Klg~3eXtL-7S-qU-wdP-6VF~ulWCWtDMn5UaPDCZytdGPni9pK9l1Oudqd2lGhLA4DeQ0QRKU9Z1ESqejAIFZ9rjKdij8UQ4amuLEyoI0GYs2J~flAvF4wrbF-LfVpMdg~tjtns6fA~EAAM1C4AFGId9RTGot6wwmbVmKKFUbbSmqdHgE6x8-xtqjeU80osyzeN7Jr7S7XO1bivxEDnhIjvMvR9sVNC81f1CsVGzW8AVNX5msEudLEggpbcjynoi-968tDLdvb-CtablzwkWBOhSwhHIXbbDEm0Zlw17qKZw4rzpsJzQg5zbGmGoPgrSD80FyMdTCG0-f~dzoRCapAGDDTTnvjXuLrZ-vN-orT~HIVYoHV7An6t6whgiSXNqeEFq9j52G95MhYIfXQ79pO9mcJtV3sfea6aGkMzqmCP3aikwf4G3y0RVbcPcNMQetDAAAA
|
||||
A C inhost 127.0.0.1
|
||||
C A OK inhost set
|
||||
A C inport 37337
|
||||
C A OK inbound port set
|
||||
A C start
|
||||
C A OK tunnel starting
|
||||
A C quit
|
||||
C A OK Bye!
|
||||
|
||||
Now all we need to do is telnet into 127.0.0.1, port 37337,
|
||||
send the destination key or host address from addressbook we want to contact.
|
||||
In this case, we want to contact "mouth", all we do is paste in the
|
||||
key and it goes.
|
||||
|
||||
NOTE: The "quit" command in the command channel does NOT disconnect the tunnels like SAM.
|
||||
|
||||
# telnet 127.0.0.1 37337
|
||||
Trying 127.0.0.1...
|
||||
Connected to 127.0.0.1.
|
||||
Escape character is '^]'.
|
||||
ZMPz1zinTdy3~zGD~f3g9aikZTipujEvvXOEyYfq4Su-mNKerqG710hFbkR6P-xkouVyNQsqWLI8c6ngnkSwGdUfM7hGccqBYDjIubTrlr~0g2-l0vM7Y8nSqtFrSdMw~pyufXZ0Ys3NqUSb8NuZXpiH2lCCkFG21QPRVfKBGwvvyDVU~hPVfBHuR8vkd5x0teMXGGmiTzdB96DuNRWayM0y8vkP-1KJiPFxKjOXULjuXhLmINIOYn39bQprq~dAtNALoBgd-waZedYgFLvwHDCc9Gui8Cpp41EihlYGNW0cu0vhNFUN79N4DEpO7AtJyrSu5ZjFTAGjLw~lOvhyO2NwQ4RiC4UCKSuM70Fz0BFKTJquIjUNkQ8pBPBYvJRRlRG9HjAcSqAMckC3pvKKlcTJJBAE8GqexV7rdCCIsnasJXle-6DoWrDkY1s1KNbEVH6i1iUEtmFr2IHTpPeFCyWfZ581CAFNRbbUs-MmnZu1tXAYF7I2-oXTH2hXoxCGAAAA
|
||||
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefg
|
||||
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefgh
|
||||
"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghi
|
||||
#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghij
|
||||
$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijk
|
||||
...
|
||||
After a few virtual miles of this spew, press Control-]
|
||||
...
|
||||
cdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJK
|
||||
defghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKL
|
||||
efghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=
|
||||
telnet> c
|
||||
Connection closed.
|
||||
|
||||
Here is what happened...
|
||||
telnet -> ear -> i2p -> mouth -> chargen -.
|
||||
telnet <- ear <- i2p <- mouth <-----------'
|
||||
|
||||
You can connect to EEPSITES too!
|
||||
|
||||
# telnet 127.0.0.1 37337
|
||||
Trying 127.0.0.1...
|
||||
Connected to 127.0.0.1.
|
||||
Escape character is '^]'.
|
||||
i2host.i2p
|
||||
GET / HTTP/1.1
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Date: Fri, 05 Dec 2008 14:20:28 GMT
|
||||
Connection: close
|
||||
Content-Type: text/html
|
||||
Content-Length: 3946
|
||||
Last-Modified: Fri, 05 Dec 2008 10:33:36 GMT
|
||||
Accept-Ranges: bytes
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>I2HOST</title>
|
||||
<link rel="shortcut icon" href="favicon.ico">
|
||||
</head>
|
||||
...
|
||||
<a href="http://sponge.i2p/">--Sponge.</a></pre>
|
||||
<img src="/counter.gif" alt="!@^7A76Z!#(*&amp;%"> visitors. </body>
|
||||
</html>
|
||||
Connection closed by foreign host.
|
||||
#
|
||||
|
||||
Pretty cool isn't it? Try some other well known EEPSITES if you like, nonexistent ones,
|
||||
etc, to get a feel for what kind of output to expect in different situations.
|
||||
For the most part, it is suggested that you ignore any of the error messages.
|
||||
They would be meaningless to the application, and are only presented for human debugging.
|
||||
|
||||
Let's put down our destinations now that we are all done with them.
|
||||
|
||||
First, lets see what destination nicknames we have.
|
||||
|
||||
FROM TO DIALOGUE
|
||||
A C list
|
||||
C A DATA NICKNAME: mouth STARTING: false RUNNING: true STOPPING: false KEYS: true QUIET: false INPORT: not_set INHOST: localhost OUTPORT: 19 OUTHOST: 127.0.0.1
|
||||
C A DATA NICKNAME: ear STARTING: false RUNNING: true STOPPING: false KEYS: true QUIET: false INPORT: 37337 INHOST: 127.0.0.1 OUTPORT: not_set OUTHOST: localhost
|
||||
C A OK Listing done
|
||||
|
||||
Alright, there they are. First, let's remove "mouth".
|
||||
|
||||
FROM TO DIALOGUE
|
||||
A C getnick mouth
|
||||
C A OK Nickname set to mouth
|
||||
A C stop
|
||||
C A OK tunnel stopping
|
||||
A C clear
|
||||
C A OK cleared
|
||||
|
||||
Now to remove "ear", note that this is what happens when you type too fast,
|
||||
and shows you what typical ERROR messages looks like.
|
||||
|
||||
FROM TO DIALOGUE
|
||||
A C getnick ear
|
||||
C A OK Nickname set to ear
|
||||
A C stop
|
||||
C A OK tunnel stopping
|
||||
A C clear
|
||||
C A ERROR tunnel is active
|
||||
A C clear
|
||||
C A OK cleared
|
||||
A C quit
|
||||
C A OK Bye!
|
||||
|
||||
I won't bother to show an example of the receiver end of a bridge
|
||||
because it is very simple. There are two possible settings for it, and
|
||||
it is toggled with the "quiet" command.
|
||||
The default is NOT quiet, and the first data to come into your
|
||||
listening socket is the destination that is making the contact. It is a
|
||||
single line consisting of the BASE64 address followed by a newline.
|
||||
Everything after that is for the application to actually consume.
|
||||
In quiet mode, think of it as a regular Internet connection. No
|
||||
extra data comes in at all. It's just as if you are plain connected to
|
||||
the regular Internet. This mode allows a form of transparency much like
|
||||
is available on the router console tunnel settings pages, so that you
|
||||
can use BOB to point a destination at a web server, for example, and
|
||||
you would not have to modify the web server at all.
|
||||
The advantage with using BOB for this is as discussed
|
||||
previously. You could schedule random uptimes for the application,
|
||||
redirect to a different machine, etc. One use of this may be something
|
||||
like wanting to try to goof up router-to-destination upness guessing.
|
||||
You could stop and start the destination with a totally different
|
||||
process to make random up and down times on services. That way you
|
||||
would only be stopping the ability to contact such a service, and not
|
||||
have to bother shutting it down and restarting it. You could redirect
|
||||
and point to a different machine on your LAN while you do updates, or
|
||||
point to a set of backup machines depending on what is running, etc,
|
||||
etc. Only your imagination limits what you could do with BOB.
|
||||
</pre>
|
||||
{% endblock %}
|
365
i2p2www/pages/site/docs/api/sam.html
Normal file
365
i2p2www/pages/site/docs/api/sam.html
Normal file
@ -0,0 +1,365 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}SAM V1 Specification{% endblock %}
|
||||
{% block content %}
|
||||
Updated August 2010 for release 0.8
|
||||
<p>Specified below is version 1 of a simple client protocol for interacting with
|
||||
I2P.
|
||||
Newer alternatives:
|
||||
<a href="{{ site_url('docs/api/samv2') }}">SAM V2</a>,
|
||||
<a href="{{ site_url('docs/api/samv3') }}">SAM V3</a>,
|
||||
<a href="{{ site_url('docs/api/bob') }}">BOB</a>.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
----------------------------------------------------------------------
|
||||
Simple Anonymous Messaging (SAM version 1.0) Specification
|
||||
----------------------------------------------------------------------
|
||||
Client application talks to SAM bridge, which deals with
|
||||
all of the I2P functionality (using the streaming
|
||||
lib for virtual streams, or I2CP directly for async messages).
|
||||
|
||||
All client<-->SAM bridge communication is unencrypted and
|
||||
unauthenticated over a single TCP socket. 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.
|
||||
|
||||
Communication can take three distinct forms:
|
||||
* <a href="streaming.html">Virtual streams</a>
|
||||
* <a href="datagrams.html#repliable">Repliable datagrams</a> (messages with a FROM field)
|
||||
* <a href="datagrams.html#raw">Anonymous datagrams</a> (raw anonymous messages)
|
||||
|
||||
----------------------------------------------------------------------
|
||||
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=$result VERSION=1.0
|
||||
|
||||
The current version for both must be "1.0".
|
||||
|
||||
The RESULT value may be one of:
|
||||
|
||||
OK
|
||||
NOVERSION
|
||||
|
||||
----------------------------------------------------------------------
|
||||
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 I2P Destination can only be used for one SAM session at a time,
|
||||
and can only use one of those forms (messages received through other
|
||||
forms are dropped).
|
||||
|
||||
The SESSION CREATE message sent by the client to the bridge is as
|
||||
follows:
|
||||
|
||||
SESSION CREATE
|
||||
STYLE={STREAM,DATAGRAM,RAW}
|
||||
DESTINATION={$name,TRANSIENT}
|
||||
[DIRECTION={BOTH,RECEIVE,CREATE}]
|
||||
[option=value]*
|
||||
|
||||
DESTINATION specifies what destination should be used for
|
||||
sending and receiving messages/streams. If a $name is given, the
|
||||
SAM bridge looks through its own local storage for an associated
|
||||
destination (and private key). If no association exists matching
|
||||
that name, it creates a new one. If the destination is specified
|
||||
as TRANSIENT, it always creates a new one.
|
||||
|
||||
The DIRECTION can be specified for STREAM sessions, instructing
|
||||
the bridge that the client will either be creating or receiving
|
||||
streams, or both. If this is not specified, BOTH will be assumed.
|
||||
Attempting to create an outbound stream when DIRECTION=RECEIVE
|
||||
should result in an error, and incoming streams when
|
||||
DIRECTION=CREATE should be ignored.
|
||||
|
||||
Additional options given should be fed into the I2P session
|
||||
configuration if not interpreted by the SAM bridge (e.g.
|
||||
"tunnels.depthInbound=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:
|
||||
|
||||
SESSION STATUS
|
||||
RESULT=$result
|
||||
DESTINATION={$name,TRANSIENT}
|
||||
[MESSAGE=...]
|
||||
|
||||
The RESULT value may be one of:
|
||||
|
||||
OK
|
||||
DUPLICATED_DEST
|
||||
I2P_ERROR
|
||||
INVALID_KEY
|
||||
|
||||
If it's not OK, the MESSAGE should contain human-readable information
|
||||
as to why the session could not be created.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
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.
|
||||
|
||||
After establishing the session with STYLE=STREAM, both the client
|
||||
and the SAM bridge may asynchronously send various messages back and
|
||||
forth to manage the streams, as listed below:
|
||||
|
||||
STREAM CONNECT
|
||||
ID=$id
|
||||
DESTINATION=$base64key
|
||||
|
||||
This establishes a new virtual connection from the local destination
|
||||
to the specified peer, marking it with the session-scoped unique ID.
|
||||
The unique ID is an ASCII base 10 integer from 1 through (2^31-1).
|
||||
The SAM bridge must reply to this with a stream status message:
|
||||
|
||||
STREAM STATUS
|
||||
RESULT=$result
|
||||
ID=$id
|
||||
[MESSAGE=...]
|
||||
|
||||
The RESULT value may be one of:
|
||||
|
||||
OK
|
||||
CANT_REACH_PEER
|
||||
I2P_ERROR
|
||||
INVALID_KEY
|
||||
TIMEOUT
|
||||
|
||||
If the RESULT is OK, the destination specified is up and authorized
|
||||
the connection; if the connection was not possible (timeout, etc),
|
||||
RESULT will contain the appropriate error value (accompanied by an
|
||||
optional human-readable MESSAGE).
|
||||
|
||||
On the receiving end, the SAM bridge simply notifies the client as
|
||||
follows:
|
||||
|
||||
STREAM CONNECTED
|
||||
DESTINATION=$base64key
|
||||
ID=$id
|
||||
|
||||
This tells the client that the given destination has created a virtual
|
||||
connection with them. The following data stream will be marked with
|
||||
the given unique ID, that is an ASCII base 10 integer from -1 through
|
||||
-(2^31-1).
|
||||
|
||||
When the client wants to send data on the virtual connection, they
|
||||
do so as follows:
|
||||
|
||||
STREAM SEND
|
||||
ID=$id
|
||||
SIZE=$numBytes\n[$numBytes of data]
|
||||
|
||||
This adds the specified data to the buffer being sent to the peer
|
||||
over the virtual connection. The send size $numBytes is how many
|
||||
8bit bytes are included after the newline, which may be 1 through
|
||||
32768 (32KB).
|
||||
|
||||
The SAM bridge will then do its best to deliver the message as
|
||||
quickly and efficiently as possible, perhaps buffering multiple SEND
|
||||
messages together. If there is an error delivering the data, or if
|
||||
the remote side closes the connection, the SAM bridge will tell the
|
||||
client:
|
||||
|
||||
STREAM CLOSED
|
||||
RESULT=$result
|
||||
ID=$id
|
||||
[MESSAGE=...]
|
||||
|
||||
The RESULT value may be one of:
|
||||
|
||||
OK
|
||||
CANT_REACH_PEER
|
||||
I2P_ERROR
|
||||
PEER_NOT_FOUND
|
||||
TIMEOUT
|
||||
|
||||
If the connection has been cleanly closed by the other peer, $result
|
||||
is set to OK. If $result is not OK, MESSAGE may convey a descriptive
|
||||
message, such as "peer unreachable", etc. Whenever a client would
|
||||
like to close the connection, they send the SAM bridge the close
|
||||
message:
|
||||
|
||||
STREAM CLOSE
|
||||
ID=$id
|
||||
|
||||
The bridge then cleans up what it needs to and discards that ID - no
|
||||
further messages can be sent or received on it.
|
||||
|
||||
For the other side of the communication, whenever the peer has sent
|
||||
some data and it is available for the client, the SAM bridge will
|
||||
promptly deliver it:
|
||||
|
||||
STREAM RECEIVED
|
||||
ID=$id
|
||||
SIZE=$numBytes\n[$numBytes of data]
|
||||
|
||||
All streams are implicitly closed by the connection between the SAM
|
||||
bridge and the client being dropped.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
SAM repliable datagrams
|
||||
----------------------------------------------------------------------
|
||||
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 the SAM bridge:
|
||||
|
||||
DATAGRAM SEND
|
||||
DESTINATION=$base64key
|
||||
SIZE=$numBytes\n[$numBytes of data]
|
||||
|
||||
When a datagram arrives, the bridge delivers it to the client via:
|
||||
|
||||
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 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 the SAM bridge:
|
||||
|
||||
RAW SEND
|
||||
DESTINATION=$base64key
|
||||
SIZE=$numBytes\n[$numBytes of data]
|
||||
|
||||
When a raw datagram arrives, the bridge delivers it to the client
|
||||
via:
|
||||
|
||||
RAW RECEIVED
|
||||
SIZE=$numBytes\n[$numBytes of data]
|
||||
|
||||
----------------------------------------------------------------------
|
||||
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 successfully
|
||||
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, I2CP, and Streaming Options
|
||||
----------------------------------------------------------------------
|
||||
|
||||
These options may be passed in as name=value pairs at the end of a
|
||||
SAM SESSION CREATE line.
|
||||
|
||||
All sessions may include <a href="i2cp.html#options">I2CP options such as tunnel lengths</a>.
|
||||
STREAM sessions may include <a href="streaming.html#options">Streaming lib options</a>.
|
||||
See those references for option names and defaults.
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
BASE 64 Notes
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Base 64 encoding must use the I2P standard Base 64 alphabet "A-Z, a-z, 0-9, -, ~".
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Client library implementations:
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Client libraries are available for C, C++, C#, Perl, and Python.
|
||||
These are in the apps/sam/ directory in the <a href="download.html">I2P Source Package</a>.
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Default SAM Setup
|
||||
----------------------------------------------------------------------
|
||||
|
||||
The default SAM port is 7656. SAM is not enabled by default in the I2P Router;
|
||||
it must be started manually, or configured to start automatically,
|
||||
on the configure clients page in the router console, or in the clients.config file.
|
||||
|
||||
</pre>
|
||||
{% endblock %}
|
432
i2p2www/pages/site/docs/api/samv2.html
Normal file
432
i2p2www/pages/site/docs/api/samv2.html
Normal file
@ -0,0 +1,432 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}SAM V2 Specification{% endblock %}
|
||||
{% block content %}
|
||||
Updated August 2010 for release 0.8
|
||||
<p>Specified below is a simple client protocol for interacting with I2P.
|
||||
</p>
|
||||
<p>
|
||||
SAM V2 was introduced in I2P release 0.6.1.31.
|
||||
Significant differences from SAM V1 are marked with "***".
|
||||
Alternatives:
|
||||
<a href="{{ site_url('docs/api/sam') }}">SAM V1</a>,
|
||||
<a href="{{ site_url('docs/api/samv3') }}">SAM V3</a>,
|
||||
<a href="{{ site_url('docs/api/bob') }}">BOB</a>.
|
||||
</p>
|
||||
|
||||
<p />
|
||||
<b>Version 2 Changes</b>
|
||||
Compared to version 1, SAM v2 provides a way to manage several sockets
|
||||
on the same I2P destination <i>in parallel</i>, i.e. the client does not
|
||||
have to wait for data being successfully sent on one socket before sending
|
||||
data on another socket. All data transits through the same
|
||||
client<-->SAM socket.
|
||||
For multiple sockets, see <a href="{{ site_url('docs/api/samv3') }}">SAM V3</a>.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
----------------------------------------------------------------------
|
||||
Simple Anonymous Messaging (SAM version 2.0) Specification
|
||||
----------------------------------------------------------------------
|
||||
Client application talks to SAM bridge, which deals with
|
||||
all of the I2P functionality (using the streaming
|
||||
lib for virtual streams, or I2CP directly for async messages).
|
||||
|
||||
All client<-->SAM bridge communication is unencrypted and
|
||||
unauthenticated over a single TCP socket. 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.
|
||||
|
||||
Communication can take three distinct forms:
|
||||
* <a href="streaming.html">Virtual streams</a>
|
||||
* <a href="datagrams.html#repliable">Repliable datagrams</a> (messages with a FROM field)
|
||||
* <a href="datagrams.html#raw">Anonymous datagrams</a> (raw anonymous messages)
|
||||
|
||||
----------------------------------------------------------------------
|
||||
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=$result VERSION=2.0
|
||||
|
||||
*** In order to force protocol version 2.0, the values of $min and $max
|
||||
*** must be "2.0".
|
||||
|
||||
The RESULT value may be one of:
|
||||
|
||||
OK
|
||||
NOVERSION
|
||||
|
||||
----------------------------------------------------------------------
|
||||
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 I2P Destination can only be used for one SAM session at a time,
|
||||
and can only use one of those forms (messages received through other
|
||||
forms are dropped).
|
||||
|
||||
The SESSION CREATE message sent by the client to the bridge is as
|
||||
follows:
|
||||
|
||||
SESSION CREATE
|
||||
STYLE={STREAM,DATAGRAM,RAW}
|
||||
DESTINATION={$name,TRANSIENT}
|
||||
[DIRECTION={BOTH,RECEIVE,CREATE}]
|
||||
[option=value]*
|
||||
|
||||
DESTINATION specifies what destination should be used for
|
||||
sending and receiving messages/streams. If a $name is given, the
|
||||
SAM bridge looks through its own local storage for an associated
|
||||
destination (and private key). If no association exists matching
|
||||
that name, it creates a new one. If the destination is specified
|
||||
as TRANSIENT, it always creates a new one.
|
||||
|
||||
The DIRECTION can be specified for STREAM sessions, instructing
|
||||
the bridge that the client will either be creating or receiving
|
||||
streams, or both. If this is not specified, BOTH will be assumed.
|
||||
Attempting to create an outbound stream when DIRECTION=RECEIVE
|
||||
should result in an error, and incoming streams when
|
||||
DIRECTION=CREATE should be ignored.
|
||||
|
||||
Additional options given should be fed into the I2P session
|
||||
configuration if not interpreted by the SAM bridge (e.g.
|
||||
"tunnels.depthInbound=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:
|
||||
|
||||
SESSION STATUS
|
||||
RESULT=$result
|
||||
DESTINATION={$name,TRANSIENT}
|
||||
[MESSAGE=...]
|
||||
|
||||
The RESULT value may be one of:
|
||||
|
||||
OK
|
||||
DUPLICATED_DEST
|
||||
I2P_ERROR
|
||||
INVALID_KEY
|
||||
|
||||
If it's not OK, the MESSAGE should contain human-readable information
|
||||
as to why the session could not be created.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
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.
|
||||
|
||||
After establishing the session with STYLE=STREAM, both the client
|
||||
and the SAM bridge may asynchronously send various messages back and
|
||||
forth to manage the streams, as listed below:
|
||||
|
||||
STREAM CONNECT
|
||||
ID=$id
|
||||
DESTINATION=$base64key
|
||||
|
||||
This establishes a new virtual connection from the local destination
|
||||
to the specified peer, marking it with the session-scoped unique ID.
|
||||
The unique ID is an ASCII base 10 integer from 1 through (2^31-1).
|
||||
The SAM bridge replies to this with a stream status message:
|
||||
|
||||
STREAM STATUS
|
||||
RESULT=$result
|
||||
ID=$id
|
||||
[MESSAGE=...]
|
||||
|
||||
The RESULT value may be one of:
|
||||
|
||||
OK
|
||||
CANT_REACH_PEER
|
||||
I2P_ERROR
|
||||
INVALID_KEY
|
||||
TIMEOUT
|
||||
|
||||
If the RESULT is OK, the destination specified is up and authorized
|
||||
the connection; if the connection was not possible (timeout, etc),
|
||||
RESULT will contain the appropriate error value (accompanied by an
|
||||
optional human-readable MESSAGE).
|
||||
|
||||
On the receiving end, the SAM bridge simply notifies the client as
|
||||
follows:
|
||||
|
||||
STREAM CONNECTED
|
||||
DESTINATION=$base64key
|
||||
ID=$id
|
||||
|
||||
This tells the client that the given destination has created a virtual
|
||||
connection with them. The following data stream will be marked with
|
||||
the given unique ID, that is an ASCII base 10 integer from -1 through
|
||||
-(2^31-1).
|
||||
|
||||
When the client wants to send data on the virtual connection, they
|
||||
do so as follows:
|
||||
|
||||
STREAM SEND
|
||||
ID=$id
|
||||
SIZE=$numBytes\n[$numBytes of data]
|
||||
|
||||
This asks the SAM bridge to add the specified data to the buffer
|
||||
being sent to the peer over the virtual connection. The send size
|
||||
$numBytes is how many 8bit bytes are included after the newline,
|
||||
which may be 1 through 32768 (32KB).
|
||||
|
||||
*** The SAM bridge immediately replies with:
|
||||
***
|
||||
*** STREAM SEND
|
||||
*** ID=$id
|
||||
*** RESULT=$result
|
||||
*** STATE=$bufferState
|
||||
***
|
||||
*** where $bufferState can be :
|
||||
*** - BUFFER_FULL : SAM's buffer has 32 or more KB of data
|
||||
*** to send, and subsequent SEND requests
|
||||
*** will fail ;
|
||||
*** - READY : SAM's buffer is not full, and the next SEND
|
||||
*** request is granted to be successful.
|
||||
***
|
||||
*** and $result is one of :
|
||||
*** - OK : the data has been buffered successfully
|
||||
*** - FAILED : the buffer was full, no data has been buffered
|
||||
***
|
||||
*** If the SAM bridge replied with BUFFER_FULL, it will send another
|
||||
*** message as soon as its buffer is available again :
|
||||
***
|
||||
*** STREAM READY_TO_SEND ID=$id
|
||||
***
|
||||
***
|
||||
***
|
||||
*** When the result is OK, the SAM bridge will then do its best to deliver
|
||||
*** the message as quickly and efficiently as possible, perhaps buffering
|
||||
*** multiple SEND messages together. If there is an error delivering the
|
||||
*** data, or if the remote side closes the connection, the SAM bridge will
|
||||
*** tell the client:
|
||||
|
||||
STREAM CLOSED
|
||||
RESULT=$result
|
||||
ID=$id
|
||||
[MESSAGE=...]
|
||||
|
||||
The RESULT value may be one of:
|
||||
|
||||
OK
|
||||
CANT_REACH_PEER
|
||||
I2P_ERROR
|
||||
PEER_NOT_FOUND
|
||||
TIMEOUT
|
||||
|
||||
If the connection has been cleanly closed by the other peer, $result
|
||||
is set to OK. If $result is not OK, MESSAGE may convey a descriptive
|
||||
message, such as "peer unreachable", etc. Whenever a client would
|
||||
like to close the connection, they send the SAM bridge the close
|
||||
message:
|
||||
|
||||
STREAM CLOSE
|
||||
ID=$id
|
||||
|
||||
The bridge then cleans up what it needs to and discards that ID - no
|
||||
further messages can be sent or received on it.
|
||||
|
||||
For the other side of the communication, whenever the peer has sent
|
||||
some data and it is available for the client, the SAM bridge will
|
||||
promptly deliver it:
|
||||
|
||||
STREAM RECEIVED
|
||||
ID=$id
|
||||
SIZE=$numBytes\n[$numBytes of data]
|
||||
|
||||
*** With SAM version 2.0, though, the client has first to tell the SAM
|
||||
*** bridge how much incoming data is allowed for the whole session, by
|
||||
*** sending a message :
|
||||
***
|
||||
*** STREAM RECEIVE
|
||||
*** ID=$id
|
||||
*** LIMIT=$limit\n
|
||||
***
|
||||
*** where $limit can be :
|
||||
***
|
||||
*** - NONE : the SAM bridge will keep on listening and deliver
|
||||
*** incoming data (same behavior as in version 1.0)
|
||||
***
|
||||
*** - an integer (less than 2^64) : the number of received bytes
|
||||
*** after which the SAM bridge will stop listening on
|
||||
*** the incoming stream.
|
||||
***
|
||||
*** Whenever the client is ready to accept more bytes
|
||||
*** from the stream, it has to send such a message again,
|
||||
*** with a greater $limit.
|
||||
***
|
||||
*** The client has to send such STREAM RECEIVE messages after the
|
||||
*** connection to the peer has been established, i.e. after the client
|
||||
*** has received a "STREAM CONNECTED" or a "STREAM STATUS RESULT=OK"
|
||||
*** from the SAM bridge.
|
||||
|
||||
|
||||
|
||||
All streams are implicitly closed by the connection between the SAM
|
||||
bridge and the client being dropped.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
SAM repliable datagrams
|
||||
----------------------------------------------------------------------
|
||||
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 the SAM bridge:
|
||||
|
||||
DATAGRAM SEND
|
||||
DESTINATION=$base64key
|
||||
SIZE=$numBytes\n[$numBytes of data]
|
||||
|
||||
When a datagram arrives, the bridge delivers it to the client via:
|
||||
|
||||
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 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 the SAM bridge:
|
||||
|
||||
RAW SEND
|
||||
DESTINATION=$base64key
|
||||
SIZE=$numBytes\n[$numBytes of data]
|
||||
|
||||
When a raw datagram arrives, the bridge delivers it to the client
|
||||
via:
|
||||
|
||||
RAW RECEIVED
|
||||
SIZE=$numBytes\n[$numBytes of data]
|
||||
|
||||
----------------------------------------------------------------------
|
||||
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 successfully
|
||||
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, I2CP, and Streaming Options
|
||||
----------------------------------------------------------------------
|
||||
|
||||
These options may be passed in as name=value pairs at the end of a
|
||||
SAM SESSION CREATE line.
|
||||
|
||||
All sessions may include <a href="i2cp.html#options">I2CP options such as tunnel lengths</a>.
|
||||
STREAM sessions may include <a href="streaming.html#options">Streaming lib options</a>.
|
||||
See those references for option names and defaults.
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
BASE 64 Notes
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Base 64 encoding must use the I2P standard Base 64 alphabet "A-Z, a-z, 0-9, -, ~".
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Client library implementations:
|
||||
----------------------------------------------------------------------
|
||||
Client libraries are available for C, C++, C#, Perl, and Python.
|
||||
These are in the apps/sam/ directory in the <a href="download.html">I2P Source Package</a>.
|
||||
Some may be older and have not been updated for SAMv2 support.
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Default SAM Setup
|
||||
----------------------------------------------------------------------
|
||||
|
||||
The default SAM port is 7656. SAM is not enabled by default in the I2P Router;
|
||||
it must be started manually, or configured to start automatically,
|
||||
on the configure clients page in the router console, or in the clients.config file.
|
||||
|
||||
</pre>
|
||||
{% endblock %}
|
519
i2p2www/pages/site/docs/api/samv3.html
Normal file
519
i2p2www/pages/site/docs/api/samv3.html
Normal file
@ -0,0 +1,519 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}SAM V3{% endblock %}
|
||||
{% block content %}
|
||||
Updated August 2010 for release 0.8
|
||||
<p>Specified below is a simple client protocol for interacting with I2P.
|
||||
</p>
|
||||
<p>SAM version 3
|
||||
was introduced in I2P release 0.7.3.
|
||||
Alternatives:
|
||||
<a href="{{ site_url('docs/api/sam') }}">SAM V1</a>,
|
||||
<a href="{{ site_url('docs/api/samv2') }}">SAM V2</a>,
|
||||
<a href="{{ site_url('docs/api/bob') }}">BOB</a>.
|
||||
</p>
|
||||
|
||||
<p />
|
||||
<b>Version 3 Changes</b>
|
||||
SAM v2 provided a way to manage several sockets
|
||||
on the same I2P destination <i>in parallel</i>, i.e. the client does not
|
||||
have to wait for data being successfully sent on one socket before sending
|
||||
data on another socket. But all data transited through the same
|
||||
client<-->SAM socket, which was quite complicated to manage for the client.
|
||||
<p />
|
||||
SAM v3 manages sockets in a different way: each <i>I2P socket</i>
|
||||
matches a unique client<-->SAM socket, which is much more simple to handle.
|
||||
This is similar to <a href="{{ site_url('docs/api/bob') }}">BOB</a>.
|
||||
<br />
|
||||
SAM v3 also offers a UDP port for sending datagrams through I2P, and
|
||||
can forward back I2P datagrams to the client's datagram server.
|
||||
<p />
|
||||
|
||||
<b>Version 3 Protocol</b>
|
||||
<pre>
|
||||
----------------------------------------------------------------------
|
||||
Simple Anonymous Messaging (SAM version 3.0) Specification
|
||||
----------------------------------------------------------------------
|
||||
Client application talks to SAM bridge, which deals with
|
||||
all of the I2P functionality (using the streaming
|
||||
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:
|
||||
* <a href="streaming.html">Virtual streams</a>
|
||||
* <a href="datagrams.html#repliable">Repliable datagrams</a> (messages with a FROM field)
|
||||
* <a href="datagrams.html#raw">Anonymous datagrams</a> (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
|
||||
he 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 can use a regular socket server and wait for connection requests
|
||||
coming from I2P. For that, the client has to :
|
||||
* open a new socket with the SAM bridge
|
||||
* pass the same HELLO handshake as above
|
||||
* send the forward command :
|
||||
|
||||
-> STREAM FORWARD
|
||||
ID={$nickname}
|
||||
PORT={$port}
|
||||
[HOST={$host}]
|
||||
[SILENCE={true,false}]
|
||||
|
||||
This makes the session ${nickname} listen 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
|
||||
|
||||
* {$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. It is mandatory.
|
||||
|
||||
When a connection request arrives from I2P, the SAM bridge requests a
|
||||
socket connection from {$host}:{$port}. If it is accepted after no more
|
||||
than 3 seconds, SAM will accept the connection 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.
|
||||
|
||||
|
||||
|
||||
The I2P router will stop listening to incoming connection requests as
|
||||
soon as the "forwarding" socket is closed.
|
||||
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
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 through 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 successfully
|
||||
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, I2CP, and Streaming Options
|
||||
----------------------------------------------------------------------
|
||||
|
||||
These options may be passed in as name=value pairs at the end of a
|
||||
SAM SESSION CREATE line.
|
||||
|
||||
All sessions may include <a href="i2cp.html#options">I2CP options such as tunnel lengths</a>.
|
||||
STREAM sessions may include <a href="streaming.html#options">Streaming lib options</a>.
|
||||
See those references for option names and defaults.
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
BASE 64 Notes
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Base 64 encoding must use the I2P standard Base 64 alphabet "A-Z, a-z, 0-9, -, ~".
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Client library implementations:
|
||||
----------------------------------------------------------------------
|
||||
Client libraries are available for C, C++, C#, Perl, and Python.
|
||||
These are in the apps/sam/ directory in the <a href="download.html">I2P Source Package</a>.
|
||||
Some may be older and have not been updated for SAMv3 support.
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Default SAM Setup
|
||||
----------------------------------------------------------------------
|
||||
|
||||
The default SAM port is 7656. SAM is not enabled by default in the I2P Router;
|
||||
it must be started manually, or configured to start automatically,
|
||||
on the configure clients page in the router console, or in the clients.config file.
|
||||
The default SAM UDP port is 7655, listening on 0.0.0.0.
|
||||
These may be changed by adding the arguments sam.udp.port=nnnnn and/or
|
||||
sam.udp.host=w.x.y.z to the invocation.
|
||||
|
||||
</pre>
|
||||
{% endblock %}
|
Reference in New Issue
Block a user