{% extends "global/layout.html" %} {% block title %}SAM V3{% endblock %} {% block lastupdated %}2023-10{% endblock %} {% block accuratefor %}API 0.9.59{% endblock %} {% block content %}

SAM is a simple client protocol for interacting with I2P. SAM is the recommended protocol for non-Java applications to connect to the I2P network, and is supported by multiple router implementations. Java applications should use the streaming or I2CP APIs directly.

SAM version 3 was introduced in I2P release 0.7.3 (May 2009) and is a stable and supported interface. 3.1 is also stable and supports the signature type option, which is strongly recommended. More recent 3.x versions support advanced features. Note that i2pd does not currently support most 3.2 and 3.3 features.

Alternatives: SOCKS, Streaming, I2CP, BOB (deprecated). Deprecated versions: SAM V1, SAM V2

Known SAM libraries

Warning: Some of these may be very old or unsupported. None are tested, reviewed, or maintained by the I2P project unless noted below. Do your own research.

{% trans %}Library Name{% endtrans %} {% trans %}Language{% endtrans %} {% trans %}Version{% endtrans %} {% trans %}STREAM{% endtrans %} {% trans %}DGRAM{% endtrans %} {% trans %}RAW{% endtrans %} {% trans %}Site{% endtrans %}
i2psam C++, C {% trans %}wrapper{% endtrans %} 3.1 yes yes no github.com/i2p/i2psam
gosam Go 3.2 yes no no github.com/eyedeekay/goSam
sam3 Go 3.3 yes yes yes bitbucket.org/eyedeekay/sam3
txi2p Python 3.1 yes no no github.com/str4d/txi2p
i2p.socket Python 3.2 yes yes yes github.com/majestrate/i2p.socket
i2plib Python 3.1 yes no no github.com/l-n-s/i2plib
i2plib-fork Python 3.1 yes no no codeberg.org/weko/i2plib-fork
Py2p Python 3.3 yes yes yes i2pgit.org/robin/Py2p
i2p-rs Rust 3.1 yes yes yes github.com/i2p/i2p-rs
libsam3 C 3.1 yes yes yes github.com/i2p/libsam3
(Maintained by the I2P project)
mooni2p Lua 3.1 yes yes yes notabug.org/l-n-s/mooni2p
haskell-network-anonymous-i2p Haskell 3.1 yes yes yes github.com/solatis/haskell-network-anonymous-i2p
i2p-sam Javascript 3.1 yes no yes codeberg.org/diva.exchange/i2p-sam
node-i2p Javascript 3.0 yes unk unk github.com/redhog/node-i2p
Jsam Java 3.1 yes no no github.com/eyedeekay/Jsam
I2PSharp .Net 3.3 yes no no github.com/MohA39/I2PSharp
i2pdotnet .Net 3.0 yes unk unk github.com/SamuelFisher/i2pdotnet
i2p.rb Ruby 3.0 yes no no github.com/dryruby/i2p.rb
solitude Rust 3.1 WIP WIP WIP github.com/syvita/solitude
i2pSAM-Qt C++ 3.1 yes yes yes notabug.org/acetone/i2pSAM-Qt
bitcoin C++ 3.1 yes no no source (not a library, but good reference code)

Quick Start

To implement a basic TCP-only, peer-to-peer application, the client must support the following commands.

General Guidance for Developers

SAM sessions (or inside I2P, tunnel pools or sets of tunnels) are designed to be long-lived. Most applications will only need one session, created at startup and closed on exit. I2P is different from Tor, where circuits may be rapidly created and discarded. Think carefully and consult with I2P developers before designing your application to use more than one or two simultaneous sessions, or to rapidly create and discard them. Most threat models will not require a unique session for every connection.

Also, please ensure your application settings (and guidance to users about router settings, or router defaults if you bundle a router) will result in your users contributing more resources to the network than they consume. I2P is a peer-to-peer network, and the network cannot survive if a popular application drives the network into permanent congestion.

The Java I2P and i2pd router implementations are independent and have minor differences in behavior, feature support, and defaults. Please test your application with the latest version of both routers.

i2pd SAM is enabled by default; Java I2P SAM is not. Provide instructions to your users on how to enable SAM in Java I2P (via /configclients in the router console), and/or provide a good error message to the user if the initial connect fails, e.g. "ensure that I2P is running and the SAM interface is enabled".

The Java I2P and i2pd routers have different defaults for tunnel quantities. The Java default is 2 and the i2pd default is 5. For most low- to medium-bandwidth and low- to medium-connection counts, 2 or 3 is sufficient. Please specify the tunnel quantity in the SESSION CREATE message to get consistent performance with the Java I2P and i2pd routers. See below.

For more guidance to developers on ensuring your application uses only the resources it needs, please see our guide to bundling I2P with your application.

Version 3 Changes

Version 3.0 Changes

Version 3.0 was introduced in I2P release 0.7.3. SAM v2 provided a way to manage several sockets on the same I2P destination in parallel, 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.

SAM v3 manages sockets in a different way: each I2P socket matches a unique client<-->SAM socket, which is much more simple to handle. This is similar to BOB.
SAM v3 also offers a UDP port for sending datagrams through I2P, and can forward back I2P datagrams to the client's datagram server.

Version 3.1 Changes

Version 3.1 was introduced in Java I2P release 0.9.14 (July 2014). SAM 3.1 is the recommended minimum SAM implementation because of its support for better signature types than SAM 3.0. i2pd also supports most 3.1 features.

Version 3.2 Changes

Version 3.2 was introduced in Java I2P release 0.9.24 (January 2016). Note that i2pd does not currently support most 3.2 features.

I2CP Port and Protocol Support

SSL and Authentication

Multithreading

Command Line Parsing and Keepalive

Version 3.3 Changes

Version 3.3 was introduced in Java I2P release 0.9.25 (March 2016). Note that i2pd does not currently support most 3.3 features.

Version 3 Protocol

Simple Anonymous Messaging (SAM) Version 3.3 Specification Overview

The client application talks to the SAM bridge, which deals with all of the I2P functionality (using the streaming library for virtual streams, or I2CP directly for datagrams).

By default, the client<-->SAM bridge communication is unencrypted and unauthenticated. The SAM bridge may support SSL/TLS connections; configuration and implementation details are outside the scope of this specification. As of SAM 3.2, optional authentication user/password parameters are supported in the initial handshake and may be required by the bridge.

I2P communications can take three distinct forms:

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, unless using PRIMARY sessions.

Encoding and Escaping

All of these SAM messages are sent on a single line, terminated by the newline character (\n). Prior to SAM 3.2, only 7-bit ASCII was supported. As of SAM 3.2, the encoding must be UTF-8. Any UTF8-encoded keys or values should work.

The formatting shown in this specification 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.

The basic command or response line takes one of the following forms:

     COMMAND SUBCOMMAND [key=value] [key=value] ...
     COMMAND                                           # As of SAM 3.2
     PING[ arbitrary text]                             # As of SAM 3.2
     PONG[ arbitrary text]                             # As of SAM 3.2
COMMAND without a SUBCOMMAND is supported for some new commands in SAM 3.2 only.

Key=value pairs must be separated by a single space. (As of SAM 3.2, multiple spaces are allowed) Values must be enclosed in double quotes if they contain spaces, e.g. key="long value text". (Prior to SAM 3.2, this did not work reliably in some implementations)

Prior to SAM 3.2, there was no escaping mechanism. As of SAM 3.2, double quotes may be escaped with a backslash '\' and a backslash may be represented as two backslashes '\\'.

Empty values

As of SAM 3.2, empty option values such as KEY, KEY=, or KEY="" may be allowed, implementation dependent.

Case Sensitivity

The protocol, as specified, is case-sensitive. It is recommended but not required that the server map commands to upper case, for ease in testing via telnet. This would allow, for example, "hello version" to work. This is implementation-dependent. Do not map keys or values to upper case, as this would corrupt I2CP options.

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]            # Optional as of SAM 3.1, required for 3.0 and earlier
          [MAX=$max]            # Optional as of SAM 3.1, required for 3.0 and earlier
          [USER="xxx"]          # As of SAM 3.2, required if authentication is enabled, see below
          [PASSWORD="yyy"]      # As of SAM 3.2, required if authentication is enabled, see below
and
<-  HELLO REPLY RESULT=OK VERSION=3.1

As of version 3.1 (I2P 0.9.14), the MIN and MAX parameters are optional. SAM will always return the highest version possible given the MIN and MAX constraints, or the current server version if no constraints are given. 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"

SSL

The server's control socket may optionally offer SSL/TLS support, as configured on the server and client. Implementations may offer other transport layers as well; this is outside the scope of the protocol definition.

Authorization

For authorization, client adds USER="xxx" PASSWORD="yyy" to the HELLO parameters. Double quotes for user and password are recommended but not required. A double quote inside a user or password must be escaped with a backslash. On failure the server will reply with an I2P_ERROR and a message. It is recommended that SSL be enabled on any SAM servers where authorization is required.

Timeouts

Servers may implement timeouts for the HELLO or subsequent commands, implementation dependent. Clients should promptly send the HELLO and the next command after connecting.

If a timeout occurs before the HELLO is received, the bridge replies with:

<- HELLO REPLY RESULT=I2P_ERROR MESSAGE="$message"
and then disconnects.

If a timeout occurs after the HELLO is received but before the next command, the bridge replies with:

<- SESSION STATUS RESULT=I2P_ERROR MESSAGE="$message"
and then disconnects.

I2CP Ports and Protocol

As of SAM 3.2, the I2CP ports and protocol may be specified by the SAM client sender to be passed through to I2CP, and the SAM bridge will pass the received I2CP port and protocol information to the SAM client.

For FROM_PORT and TO_PORT, the valid range is 0-65535, and the default is 0.

For PROTOCOL, which may be specified only for RAW, the valid range is 0-255, and the default is 18.

For SESSION commands, the specified ports and protocol are the defaults for that session. For individual streams or datagrams, the specified ports and protocol override the session defaults. For received streams or datagrams, the indicated ports and protocol are as received from I2CP.

Important Differences from Standard IP

I2CP ports are for I2P sockets and datagrams. They are unrelated to your local sockets connecting to SAM.