Documentation ¶
Overview ¶
Library for I2Ps SAMv3 bridge (https://geti2p.com)
Index ¶
- Variables
- func Base32(anything string) string
- func StoreKeysIncompat(k I2PKeys, w io.Writer) (err error)
- type Config
- type DatagramSession
- func (s *DatagramSession) B32() string
- func (s *DatagramSession) Close() error
- func (s *DatagramSession) LocalAddr() net.Addr
- func (s *DatagramSession) LocalI2PAddr() I2PAddr
- func (s *DatagramSession) Lookup(name string) (a net.Addr, err error)
- func (s *DatagramSession) ReadFrom(b []byte) (n int, addr net.Addr, err error)
- func (s *DatagramSession) SetDeadline(t time.Time) error
- func (s *DatagramSession) SetReadDeadline(t time.Time) error
- func (s *DatagramSession) SetWriteDeadline(t time.Time) error
- func (s *DatagramSession) WriteTo(b []byte, addr net.Addr) (n int, err error)
- type I2PAddr
- type I2PDestHash
- type I2PKeys
- type Options
- type RawSession
- func (s *RawSession) Close() error
- func (s *RawSession) LocalAddr() I2PAddr
- func (s *RawSession) Read(b []byte) (n int, err error)
- func (s *RawSession) SetDeadline(t time.Time) error
- func (s *RawSession) SetReadDeadline(t time.Time) error
- func (s *RawSession) SetWriteDeadline(t time.Time) error
- func (s *RawSession) WriteTo(b []byte, addr I2PAddr) (n int, err error)
- type SAM
- func (sam *SAM) Close() error
- func (sam *SAM) EnsureKeyfile(fname string) (keys I2PKeys, err error)
- func (sam *SAM) Keys() (k *I2PKeys)
- func (sam *SAM) Lookup(name string) (I2PAddr, error)
- func (s *SAM) NewDatagramSession(id string, keys I2PKeys, options []string, udpPort int) (*DatagramSession, error)
- func (sam *SAM) NewKeys() (I2PKeys, error)
- func (s *SAM) NewRawSession(id string, keys I2PKeys, options []string, udpPort int) (*RawSession, error)
- func (sam *SAM) NewStreamSession(id string, keys I2PKeys, options []string) (*StreamSession, error)
- func (sam *SAM) ReadKeys(r io.Reader) (err error)
- type SAMConn
- func (sc *SAMConn) Close() error
- func (sc *SAMConn) LocalAddr() net.Addr
- func (sc *SAMConn) Read(buf []byte) (int, error)
- func (sc *SAMConn) RemoteAddr() net.Addr
- func (sc *SAMConn) SetDeadline(t time.Time) error
- func (sc *SAMConn) SetReadDeadline(t time.Time) error
- func (sc *SAMConn) SetWriteDeadline(t time.Time) error
- func (sc *SAMConn) Write(buf []byte) (int, error)
- type StreamListener
- type StreamSession
- func (ss StreamSession) Addr() I2PAddr
- func (ss *StreamSession) Close() error
- func (s *StreamSession) Dial(n, addr string) (c net.Conn, err error)
- func (s *StreamSession) DialI2P(addr I2PAddr) (*SAMConn, error)
- func (ss StreamSession) ID() string
- func (ss StreamSession) Keys() I2PKeys
- func (s *StreamSession) Listen() (*StreamListener, error)
- func (s *StreamSession) Lookup(name string) (I2PAddr, error)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // Suitable options if you are shuffling A LOT of traffic. If unused, this // will waste your resources. Options_Humongous = []string{"inbound.length=3", "outbound.length=3", "inbound.lengthVariance=1", "outbound.lengthVariance=1", "inbound.backupQuantity=3", "outbound.backupQuantity=3", "inbound.quantity=6", "outbound.quantity=6"} // Suitable for shuffling a lot of traffic. Options_Fat = []string{"inbound.length=3", "outbound.length=3", "inbound.lengthVariance=1", "outbound.lengthVariance=1", "inbound.backupQuantity=1", "outbound.backupQuantity=1", "inbound.quantity=4", "outbound.quantity=4"} // Suitable for shuffling medium amounts of traffic. Options_Medium = []string{"inbound.length=3", "outbound.length=3", "inbound.lengthVariance=1", "outbound.lengthVariance=1", "inbound.backupQuantity=0", "outbound.backupQuantity=0", "inbound.quantity=2", "outbound.quantity=2"} // Suitable only for small dataflows, and very short lasting connections: // You only have one tunnel in each direction, so if any of the nodes // through which any of your two tunnels pass through go offline, there will // be a complete halt in the dataflow, until a new tunnel is built. Options_Small = []string{"inbound.length=3", "outbound.length=3", "inbound.lengthVariance=1", "outbound.lengthVariance=1", "inbound.backupQuantity=0", "outbound.backupQuantity=0", "inbound.quantity=1", "outbound.quantity=1"} // Does not use any anonymization, you connect directly to others tunnel // endpoints, thus revealing your identity but not theirs. Use this only // if you don't care. Options_Warning_ZeroHop = []string{"inbound.length=0", "outbound.length=0", "inbound.lengthVariance=0", "outbound.lengthVariance=0", "inbound.backupQuantity=0", "outbound.backupQuantity=0", "inbound.quantity=2", "outbound.quantity=2"} )
Examples and suggestions for options when creating sessions.
Functions ¶
Types ¶
type Config ¶
Config is the config type for the sam connector api for i2p which allows applications to 'speak' with i2p
func (*Config) DatagramSession ¶
func (cfg *Config) DatagramSession() (session *DatagramSession, err error)
create new sam datagram session from config
func (*Config) StreamSession ¶
func (cfg *Config) StreamSession() (session *StreamSession, err error)
create new sam connector from config with a stream session
type DatagramSession ¶
type DatagramSession struct {
// contains filtered or unexported fields
}
The DatagramSession implements net.PacketConn. It works almost like ordinary UDP, except that datagrams may be at most 31kB large. These datagrams are also end-to-end encrypted, signed and includes replay-protection. And they are also built to be surveillance-resistant (yey!).
Example ¶
// Creates a new DatagramSession, which behaves just like a net.PacketConn. const samBridge = "127.0.0.1:7656" sam, err := NewSAM(samBridge) if err != nil { fmt.Println(err.Error()) return } keys, err := sam.NewKeys() if err != nil { fmt.Println(err.Error()) return } myself := keys.Addr() // See the example Option_* variables. dg, err := sam.NewDatagramSession("DGTUN", keys, Options_Small, 0) if err != nil { fmt.Println(err.Error()) return } someone, err := sam.Lookup("zzz.i2p") if err != nil { fmt.Println(err.Error()) return } dg.WriteTo([]byte("Hello stranger!"), someone) dg.WriteTo([]byte("Hello myself!"), myself) buf := make([]byte, 31*1024) n, _, err := dg.ReadFrom(buf) if err != nil { fmt.Println(err.Error()) return } fmt.Println("Got message: " + string(buf[:n])) return
Output: Got message: Hello myself!
func (*DatagramSession) B32 ¶
func (s *DatagramSession) B32() string
func (*DatagramSession) Close ¶
func (s *DatagramSession) Close() error
Closes the DatagramSession. Implements net.PacketConn
func (*DatagramSession) LocalAddr ¶
func (s *DatagramSession) LocalAddr() net.Addr
Implements net.PacketConn
func (*DatagramSession) LocalI2PAddr ¶
func (s *DatagramSession) LocalI2PAddr() I2PAddr
Returns the I2P destination of the DatagramSession.
func (*DatagramSession) Lookup ¶
func (s *DatagramSession) Lookup(name string) (a net.Addr, err error)
func (*DatagramSession) ReadFrom ¶
Reads one datagram sent to the destination of the DatagramSession. Returns the number of bytes read, from what address it was sent, or an error. implements net.PacketConn
func (*DatagramSession) SetDeadline ¶
func (s *DatagramSession) SetDeadline(t time.Time) error
Sets read and write deadlines for the DatagramSession. Implements net.PacketConn and does the same thing. Setting write deadlines for datagrams is seldom done.
func (*DatagramSession) SetReadDeadline ¶
func (s *DatagramSession) SetReadDeadline(t time.Time) error
Sets read deadline for the DatagramSession. Implements net.PacketConn
func (*DatagramSession) SetWriteDeadline ¶
func (s *DatagramSession) SetWriteDeadline(t time.Time) error
Sets the write deadline for the DatagramSession. Implements net.Packetconn.
type I2PAddr ¶
type I2PAddr string
I2PAddr represents an I2P destination, almost equivalent to an IP address. This is the humongously huge base64 representation of such an address, which really is just a pair of public keys and also maybe a certificate. (I2P hides the details of exactly what it is. Read the I2P specifications for more info.)
func NewI2PAddrFromBytes ¶
Creates a new I2P address from a byte array. The inverse of ToBytes().
func NewI2PAddrFromString ¶
Creates a new I2P address from a base64-encoded string. Checks if the address addr is in correct format. (If you know for sure it is, use I2PAddr(addr).)
func (I2PAddr) Base32 ¶
Returns the *.b32.i2p address of the I2P address. It is supposed to be a somewhat human-manageable 64 character long pseudo-domain name equivalent of the 516+ characters long default base64-address (the I2PAddr format). It is not possible to turn the base32-address back into a usable I2PAddr without performing a Lookup(). Lookup only works if you are using the I2PAddr from which the b32 address was generated.
func (I2PAddr) DestHash ¶
func (addr I2PAddr) DestHash() (h I2PDestHash)
type I2PDestHash ¶
type I2PDestHash [32]byte
an i2p destination hash, the .b32.i2p address if you will
func DestHashFromString ¶
func DestHashFromString(str string) (dhash I2PDestHash, err error)
create a desthash from a string b32.i2p address
func (I2PDestHash) String ¶
func (h I2PDestHash) String() string
get string representation of i2p dest hash
type I2PKeys ¶
type I2PKeys struct {
// contains filtered or unexported fields
}
The public and private keys associated with an I2P destination. I2P hides the details of exactly what this is, so treat them as blobs, but generally: One pair of DSA keys, one pair of ElGamal keys, and sometimes (almost never) also a certificate. String() returns you the full content of I2PKeys and Addr() returns the public keys.
func LoadKeysIncompat ¶
load keys from non standard format
type RawSession ¶
type RawSession struct {
// contains filtered or unexported fields
}
The RawSession provides no authentication of senders, and there is no sender address attached to datagrams, so all communication is anonymous. The messages send are however still endpoint-to-endpoint encrypted. You need to figure out a way to identify and authenticate clients yourself, iff that is needed. Raw datagrams may be at most 32 kB in size. There is no overhead of authentication, which is the reason to use this..
func (*RawSession) LocalAddr ¶
func (s *RawSession) LocalAddr() I2PAddr
Returns the local I2P destination of the RawSession.
func (*RawSession) Read ¶
func (s *RawSession) Read(b []byte) (n int, err error)
Reads one raw datagram sent to the destination of the DatagramSession. Returns the number of bytes read. Who sent the raw message can not be determined at this layer - you need to do it (in a secure way!).
func (*RawSession) SetDeadline ¶
func (s *RawSession) SetDeadline(t time.Time) error
func (*RawSession) SetReadDeadline ¶
func (s *RawSession) SetReadDeadline(t time.Time) error
func (*RawSession) SetWriteDeadline ¶
func (s *RawSession) SetWriteDeadline(t time.Time) error
type SAM ¶
type SAM struct {
// contains filtered or unexported fields
}
Used for controlling I2Ps SAMv3.
func (*SAM) EnsureKeyfile ¶
if keyfile fname does not exist
func (*SAM) Lookup ¶
Performs a lookup, probably this order: 1) routers known addresses, cached addresses, 3) by asking peers in the I2P network.
func (*SAM) NewDatagramSession ¶
func (s *SAM) NewDatagramSession(id string, keys I2PKeys, options []string, udpPort int) (*DatagramSession, error)
Creates a new datagram session. udpPort is the UDP port SAM is listening on, and if you set it to zero, it will use SAMs standard UDP port.
func (*SAM) NewKeys ¶
Creates the I2P-equivalent of an IP address, that is unique and only the one who has the private keys can send messages from. The public keys are the I2P desination (the address) that anyone can send messages to.
func (*SAM) NewRawSession ¶
func (s *SAM) NewRawSession(id string, keys I2PKeys, options []string, udpPort int) (*RawSession, error)
Creates a new raw session. udpPort is the UDP port SAM is listening on, and if you set it to zero, it will use SAMs standard UDP port.
func (*SAM) NewStreamSession ¶
Creates a new StreamSession with the I2CP- and streaminglib options as specified. See the I2P documentation for a full list of options.
type SAMConn ¶
type SAMConn struct {
// contains filtered or unexported fields
}
Implements net.Conn
func (*SAMConn) RemoteAddr ¶
func (*SAMConn) SetReadDeadline ¶
Implements net.Conn
func (*SAMConn) SetWriteDeadline ¶
Implements net.Conn
type StreamListener ¶
type StreamListener struct {
// contains filtered or unexported fields
}
Example ¶
// One server Accept()ing on a StreamListener, and one client that Dials // through I2P to the server. Server writes "Hello world!" through a SAMConn // (which implements net.Conn) and the client prints the message. const samBridge = "127.0.0.1:7656" sam, err := NewSAM(samBridge) if err != nil { fmt.Println(err.Error()) return } defer sam.Close() keys, err := sam.NewKeys() if err != nil { fmt.Println(err.Error()) return } quit := make(chan bool) // Client connecting to the server go func(server I2PAddr) { csam, err := NewSAM(samBridge) if err != nil { fmt.Println(err.Error()) return } defer csam.Close() keys, err := csam.NewKeys() if err != nil { fmt.Println(err.Error()) return } cs, err := csam.NewStreamSession("client_example", keys, Options_Small) if err != nil { fmt.Println(err.Error()) quit <- false return } conn, err := cs.DialI2P(server) if err != nil { fmt.Println(err.Error()) quit <- false return } buf := make([]byte, 256) n, err := conn.Read(buf) if err != nil { fmt.Println(err.Error()) quit <- false return } fmt.Println(string(buf[:n])) quit <- true }(keys.Addr()) // end of client ss, err := sam.NewStreamSession("server_example", keys, Options_Small) if err != nil { fmt.Println(err.Error()) return } l, err := ss.Listen() if err != nil { fmt.Println(err.Error()) return } conn, err := l.Accept() if err != nil { fmt.Println(err.Error()) return } conn.Write([]byte("Hello world!")) <-quit // waits for client to die, for example only
Output: Hello world!
func (*StreamListener) Accept ¶
func (l *StreamListener) Accept() (net.Conn, error)
implements net.Listener
func (*StreamListener) AcceptI2P ¶
func (l *StreamListener) AcceptI2P() (*SAMConn, error)
accept a new inbound connection
func (*StreamListener) Addr ¶
func (l *StreamListener) Addr() net.Addr
get our address implements net.Listener
type StreamSession ¶
type StreamSession struct {
// contains filtered or unexported fields
}
Represents a streaming session.
Example ¶
// Creates a new StreamingSession, dials to zzz.i2p and gets a SAMConn // which behaves just like a normal net.Conn. const samBridge = "127.0.0.1:7656" sam, err := NewSAM(samBridge) if err != nil { fmt.Println(err.Error()) return } defer sam.Close() keys, err := sam.NewKeys() if err != nil { fmt.Println(err.Error()) return } // See the example Option_* variables. ss, err := sam.NewStreamSession("stream_example", keys, Options_Small) if err != nil { fmt.Println(err.Error()) return } someone, err := sam.Lookup("zzz.i2p") if err != nil { fmt.Println(err.Error()) return } conn, err := ss.DialI2P(someone) if err != nil { fmt.Println(err.Error()) return } defer conn.Close() fmt.Println("Sending HTTP GET /") if _, err := conn.Write([]byte("GET /\n")); err != nil { fmt.Println(err.Error()) return } buf := make([]byte, 4096) n, err := conn.Read(buf) if !strings.Contains(strings.ToLower(string(buf[:n])), "http") && !strings.Contains(strings.ToLower(string(buf[:n])), "html") { fmt.Printf("Probably failed to StreamSession.DialI2P(zzz.i2p)? It replied %d bytes, but nothing that looked like http/html", n) } else { fmt.Println("Read HTTP/HTML from zzz.i2p") } return
Output: Sending HTTP GET / Read HTTP/HTML from zzz.i2p
func (StreamSession) Addr ¶
func (ss StreamSession) Addr() I2PAddr
Returns the I2P destination (the address) of the stream session
func (*StreamSession) Close ¶
func (ss *StreamSession) Close() error
func (*StreamSession) Dial ¶
func (s *StreamSession) Dial(n, addr string) (c net.Conn, err error)
implement net.Dialer
func (*StreamSession) DialI2P ¶
func (s *StreamSession) DialI2P(addr I2PAddr) (*SAMConn, error)
Dials to an I2P destination and returns a SAMConn, which implements a net.Conn.
func (StreamSession) ID ¶
func (ss StreamSession) ID() string
Returns the local tunnel name of the I2P tunnel used for the stream session
func (StreamSession) Keys ¶
func (ss StreamSession) Keys() I2PKeys
Returns the keys associated with the stream session
func (*StreamSession) Listen ¶
func (s *StreamSession) Listen() (*StreamListener, error)
create a new stream listener to accept inbound connections