Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0a2d58418f | ||
![]() |
ca1a4f7f54 | ||
![]() |
6406efd277 | ||
![]() |
a12f9ba498 | ||
![]() |
4a24538cd5 | ||
![]() |
f617388473 | ||
![]() |
c2b2b39c74 | ||
![]() |
0067d37ca3 | ||
![]() |
f8d54526ea | ||
![]() |
e9868b791e | ||
![]() |
a810f009bd | ||
![]() |
99ad6522eb | ||
![]() |
6f6be01fb2 | ||
![]() |
7438f855cd | ||
![]() |
eabe42f33f | ||
![]() |
0e9665027e | ||
![]() |
79b526d69c | ||
![]() |
5b1dcc54aa | ||
![]() |
6b863d7514 | ||
![]() |
9ee74a89d3 | ||
![]() |
6029d7dd6e | ||
![]() |
265e8b21b4 | ||
![]() |
9d24d56c28 | ||
![]() |
d622765b79 |
10
Makefile
Normal file
10
Makefile
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
USER_GH=eyedeekay
|
||||
VERSION=0.32.1
|
||||
|
||||
echo:
|
||||
@echo "type make version to do release $(VERSION)"
|
||||
|
||||
version:
|
||||
gothub release -s $(GITHUB_TOKEN) -u $(USER_GH) -r sam3 -t v$(VERSION) -d "version $(VERSION)"
|
||||
|
@@ -78,7 +78,7 @@ Error handling was omitted in the above code for readability.
|
||||
|
||||
## Testing ##
|
||||
|
||||
* `go test` runs the whole suite (takes 90+ sec to perform!)
|
||||
* `go test -tags=nettest` runs the whole suite (takes 90+ sec to perform!)
|
||||
* `go test -short` runs the shorter variant, does not connect to anything
|
||||
|
||||
## License ##
|
||||
@@ -88,4 +88,4 @@ Public domain.
|
||||
## Author ##
|
||||
|
||||
* Kalle Vedin `kalle.vedin@fripost.org`
|
||||
* Unknown Name (majestrate)
|
||||
* Unknown Name (majestrate)
|
||||
|
12
SAMConn.go
12
SAMConn.go
@@ -1,18 +1,20 @@
|
||||
package sam3
|
||||
|
||||
import (
|
||||
"github.com/eyedeekay/sam3/i2pkeys"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
/*
|
||||
import (
|
||||
. "github.com/eyedeekay/sam3/i2pkeys"
|
||||
)
|
||||
|
||||
*/
|
||||
// Implements net.Conn
|
||||
type SAMConn struct {
|
||||
laddr I2PAddr
|
||||
raddr I2PAddr
|
||||
laddr i2pkeys.I2PAddr
|
||||
raddr i2pkeys.I2PAddr
|
||||
conn net.Conn
|
||||
}
|
||||
|
||||
@@ -38,7 +40,7 @@ func (sc *SAMConn) LocalAddr() net.Addr {
|
||||
}
|
||||
|
||||
// Implements net.Conn
|
||||
func (sc *SAMConn) localAddr() I2PAddr {
|
||||
func (sc *SAMConn) localAddr() i2pkeys.I2PAddr {
|
||||
return sc.laddr
|
||||
}
|
||||
|
||||
@@ -47,7 +49,7 @@ func (sc *SAMConn) RemoteAddr() net.Addr {
|
||||
}
|
||||
|
||||
// Implements net.Conn
|
||||
func (sc *SAMConn) remoteAddr() I2PAddr {
|
||||
func (sc *SAMConn) remoteAddr() i2pkeys.I2PAddr {
|
||||
return sc.raddr
|
||||
}
|
||||
|
||||
|
@@ -4,10 +4,8 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
import (
|
||||
. "github.com/eyedeekay/sam3/i2pkeys"
|
||||
"github.com/eyedeekay/sam3/i2pkeys"
|
||||
)
|
||||
|
||||
// sam config
|
||||
@@ -38,7 +36,7 @@ func (cfg *Config) StreamSession() (session *StreamSession, err error) {
|
||||
s, err = NewSAM(cfg.Addr)
|
||||
if err == nil {
|
||||
// ensure keys exist
|
||||
var keys I2PKeys
|
||||
var keys i2pkeys.I2PKeys
|
||||
keys, err = s.EnsureKeyfile(cfg.Keyfile)
|
||||
if err == nil {
|
||||
// create session
|
||||
@@ -55,7 +53,7 @@ func (cfg *Config) DatagramSession() (session *DatagramSession, err error) {
|
||||
s, err = NewSAM(cfg.Addr)
|
||||
if err == nil {
|
||||
// ensure keys exist
|
||||
var keys I2PKeys
|
||||
var keys i2pkeys.I2PKeys
|
||||
keys, err = s.EnsureKeyfile(cfg.Keyfile)
|
||||
if err == nil {
|
||||
// determine udp port
|
||||
|
56
datagram.go
56
datagram.go
@@ -6,10 +6,8 @@ import (
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
import (
|
||||
. "github.com/eyedeekay/sam3/i2pkeys"
|
||||
"github.com/eyedeekay/sam3/i2pkeys"
|
||||
)
|
||||
|
||||
// The DatagramSession implements net.PacketConn. It works almost like ordinary
|
||||
@@ -17,24 +15,25 @@ import (
|
||||
// also end-to-end encrypted, signed and includes replay-protection. And they
|
||||
// are also built to be surveillance-resistant (yey!).
|
||||
type DatagramSession struct {
|
||||
samAddr string // address to the sam bridge (ipv4:port)
|
||||
id string // tunnel name
|
||||
conn net.Conn // connection to sam bridge
|
||||
udpconn *net.UDPConn // used to deliver datagrams
|
||||
keys I2PKeys // i2p destination keys
|
||||
rUDPAddr *net.UDPAddr // the SAM bridge UDP-port
|
||||
samAddr string // address to the sam bridge (ipv4:port)
|
||||
id string // tunnel name
|
||||
conn net.Conn // connection to sam bridge
|
||||
udpconn *net.UDPConn // used to deliver datagrams
|
||||
keys i2pkeys.I2PKeys // i2p destination keys
|
||||
rUDPAddr *net.UDPAddr // the SAM bridge UDP-port
|
||||
remoteAddr *i2pkeys.I2PAddr // optional remote I2P address
|
||||
}
|
||||
|
||||
// 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 (s *SAM) NewDatagramSession(id string, keys I2PKeys, options []string, udpPort int) (*DatagramSession, error) {
|
||||
func (s *SAM) NewDatagramSession(id string, keys i2pkeys.I2PKeys, options []string, udpPort int) (*DatagramSession, error) {
|
||||
if udpPort > 65335 || udpPort < 0 {
|
||||
return nil, errors.New("udpPort needs to be in the intervall 0-65335")
|
||||
}
|
||||
if udpPort == 0 {
|
||||
udpPort = 7655
|
||||
}
|
||||
lhost, _, err := net.SplitHostPort(s.Conn.LocalAddr().String())
|
||||
lhost, _, err := net.SplitHostPort(s.conn.LocalAddr().String())
|
||||
if err != nil {
|
||||
s.Close()
|
||||
return nil, err
|
||||
@@ -47,7 +46,7 @@ func (s *SAM) NewDatagramSession(id string, keys I2PKeys, options []string, udpP
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rhost, _, err := net.SplitHostPort(s.Conn.RemoteAddr().String())
|
||||
rhost, _, err := net.SplitHostPort(s.conn.RemoteAddr().String())
|
||||
if err != nil {
|
||||
s.Close()
|
||||
return nil, err
|
||||
@@ -61,13 +60,17 @@ func (s *SAM) NewDatagramSession(id string, keys I2PKeys, options []string, udpP
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &DatagramSession{s.Config.I2PConfig.Sam(), id, conn, udpconn, keys, rUDPAddr}, nil
|
||||
return &DatagramSession{s.address, id, conn, udpconn, keys, rUDPAddr, nil}, nil
|
||||
}
|
||||
|
||||
func (s *DatagramSession) B32() string {
|
||||
return s.keys.Addr().Base32()
|
||||
}
|
||||
|
||||
func (s *DatagramSession) RemoteAddr() net.Addr {
|
||||
return s.remoteAddr
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -80,20 +83,20 @@ func (s *DatagramSession) ReadFrom(b []byte) (n int, addr net.Addr, err error) {
|
||||
var saddr *net.UDPAddr
|
||||
n, saddr, err = s.udpconn.ReadFromUDP(buf)
|
||||
if err != nil {
|
||||
return 0, I2PAddr(""), err
|
||||
return 0, i2pkeys.I2PAddr(""), err
|
||||
}
|
||||
if bytes.Equal(saddr.IP, s.rUDPAddr.IP) {
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
i := bytes.IndexByte(buf, byte(' '))
|
||||
i := bytes.IndexByte(buf, byte('\n'))
|
||||
if i > 4096 || i > n {
|
||||
return 0, I2PAddr(""), errors.New("Could not parse incomming message remote address.")
|
||||
return 0, i2pkeys.I2PAddr(""), errors.New("Could not parse incomming message remote address.")
|
||||
}
|
||||
raddr, err := NewI2PAddrFromString(string(buf[:i]))
|
||||
raddr, err := i2pkeys.NewI2PAddrFromString(string(buf[:i]))
|
||||
if err != nil {
|
||||
return 0, I2PAddr(""), errors.New("Could not parse incomming message remote address: " + string(buf[:i]) + err.Error())
|
||||
return 0, i2pkeys.I2PAddr(""), errors.New("Could not parse incomming message remote address: " + err.Error())
|
||||
}
|
||||
// shift out the incomming address to contain only the data received
|
||||
if (n - i + 1) > len(b) {
|
||||
@@ -105,16 +108,25 @@ func (s *DatagramSession) ReadFrom(b []byte) (n int, addr net.Addr, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DatagramSession) Read(b []byte) (n int, err error) {
|
||||
rint, _, rerr := s.ReadFrom(b)
|
||||
return rint, rerr
|
||||
}
|
||||
|
||||
// Sends one signed datagram to the destination specified. At the time of
|
||||
// writing, maximum size is 31 kilobyte, but this may change in the future.
|
||||
// Implements net.PacketConn.
|
||||
func (s *DatagramSession) WriteTo(b []byte, addr net.Addr) (n int, err error) {
|
||||
header := []byte("3.0 " + s.id + " " + addr.String() + "\n")
|
||||
header := []byte("3.1 " + s.id + " " + addr.String() + "\n")
|
||||
msg := append(header, b...)
|
||||
n, err = s.udpconn.WriteToUDP(msg, s.rUDPAddr)
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (s *DatagramSession) Write(b []byte) (int, error) {
|
||||
return s.WriteTo(b, s.remoteAddr)
|
||||
}
|
||||
|
||||
// Closes the DatagramSession. Implements net.PacketConn
|
||||
func (s *DatagramSession) Close() error {
|
||||
err := s.conn.Close()
|
||||
@@ -126,7 +138,7 @@ func (s *DatagramSession) Close() error {
|
||||
}
|
||||
|
||||
// Returns the I2P destination of the DatagramSession.
|
||||
func (s *DatagramSession) LocalI2PAddr() I2PAddr {
|
||||
func (s *DatagramSession) LocalI2PAddr() i2pkeys.I2PAddr {
|
||||
return s.keys.Addr()
|
||||
}
|
||||
|
||||
@@ -161,3 +173,7 @@ func (s *DatagramSession) SetReadDeadline(t time.Time) error {
|
||||
func (s *DatagramSession) SetWriteDeadline(t time.Time) error {
|
||||
return s.udpconn.SetWriteDeadline(t)
|
||||
}
|
||||
|
||||
func (s *DatagramSession) SetWriteBuffer(bytes int) error {
|
||||
return s.udpconn.SetWriteBuffer(bytes)
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ package sam3
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -27,7 +28,7 @@ func Test_DatagramServerClient(t *testing.T) {
|
||||
}
|
||||
// fmt.Println("\tServer: My address: " + keys.Addr().Base32())
|
||||
fmt.Println("\tServer: Creating tunnel")
|
||||
ds, err := sam.NewDatagramSession("DGserverTun", keys, []string{"inbound.length=1", "outbound.length=1", "inbound.lengthVariance=0", "outbound.lengthVariance=0", "inbound.quantity=1", "outbound.quantity=1"}, 0)
|
||||
ds, err := sam.NewDatagramSession("DGserverTun", keys, []string{"inbound.length=0", "outbound.length=0", "inbound.lengthVariance=0", "outbound.lengthVariance=0", "inbound.quantity=1", "outbound.quantity=1"}, 0)
|
||||
if err != nil {
|
||||
fmt.Println("Server: Failed to create tunnel: " + err.Error())
|
||||
t.Fail()
|
||||
@@ -47,14 +48,14 @@ func Test_DatagramServerClient(t *testing.T) {
|
||||
return
|
||||
}
|
||||
fmt.Println("\tClient: Creating tunnel")
|
||||
ds2, err := sam2.NewDatagramSession("DGclientTun", keys, []string{"inbound.length=1", "outbound.length=1", "inbound.lengthVariance=0", "outbound.lengthVariance=0", "inbound.quantity=1", "outbound.quantity=1"}, 0)
|
||||
ds2, err := sam2.NewDatagramSession("DGclientTun", keys, []string{"inbound.length=0", "outbound.length=0", "inbound.lengthVariance=0", "outbound.lengthVariance=0", "inbound.quantity=1", "outbound.quantity=1"}, 0)
|
||||
if err != nil {
|
||||
c <- false
|
||||
return
|
||||
}
|
||||
defer ds2.Close()
|
||||
fmt.Println("\tClient: Servers address: " + ds.B32())
|
||||
fmt.Println("\tClient: Clients address: " + ds2.B32())
|
||||
// fmt.Println("\tClient: Servers address: " + ds.LocalAddr().Base32())
|
||||
// fmt.Println("\tClient: Clients address: " + ds2.LocalAddr().Base32())
|
||||
fmt.Println("\tClient: Tries to send datagram to server")
|
||||
for {
|
||||
select {
|
||||
@@ -124,6 +125,58 @@ func ExampleDatagramSession() {
|
||||
fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
log.Println("Got message: '" + string(buf[:n]) + "'")
|
||||
fmt.Println("Got message: " + string(buf[:n]))
|
||||
|
||||
return
|
||||
// Output:
|
||||
//Got message: Hello myself!
|
||||
}
|
||||
|
||||
func ExampleMiniDatagramSession() {
|
||||
// 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("MINIDGTUN", 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
|
||||
}
|
||||
err = dg.SetWriteBuffer(14 * 1024)
|
||||
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
|
||||
}
|
||||
log.Println("Got message: '" + string(buf[:n]) + "'")
|
||||
fmt.Println("Got message: " + string(buf[:n]))
|
||||
|
||||
return
|
||||
|
23
debian/changelog
vendored
23
debian/changelog
vendored
@@ -1,3 +1,26 @@
|
||||
golang-github-eyedeekay-sam3 (0.3.2.1) bionic; urgency=medium
|
||||
|
||||
[ idk ]
|
||||
* Add support for 44-character destination hashes.
|
||||
|
||||
-- idk <hankhill19580@gmail.com> Sat, 7 Dec 2019 17:30:30 -0500
|
||||
|
||||
|
||||
golang-github-eyedeekay-sam3 (0.3.2.01) bionic; urgency=medium
|
||||
|
||||
[ idk ]
|
||||
* completely remove the old i2pkeys version and replace it with the new one.
|
||||
|
||||
-- idk <hankhill19580@gmail.com> Sat, 25 May 2019 14:38:11 -0500
|
||||
|
||||
golang-github-eyedeekay-sam3 (0.3.2.0) bionic; urgency=medium
|
||||
|
||||
[ idk ]
|
||||
* Bug fixes, create stable branch
|
||||
* Move i2pkeys
|
||||
|
||||
-- idk <hankhill19580@gmail.com> Sat, 18 May 2019 18:32:51 -0500
|
||||
|
||||
golang-github-eyedeekay-sam3 (0.0~git20190223.af5a3f3) bionic; urgency=medium
|
||||
|
||||
[ idk ]
|
||||
|
3
debian/control
vendored
3
debian/control
vendored
@@ -15,7 +15,8 @@ Testsuite: autopkgtest-pkg-go
|
||||
|
||||
Package: golang-github-eyedeekay-sam3-dev
|
||||
Architecture: all
|
||||
Depends: ${misc:Depends}, (i2p | i2pd)
|
||||
Depends: ${misc:Depends},
|
||||
i2p | i2pd
|
||||
Description: Go library for the I2P SAMv3.0 bridge,
|
||||
used to build anonymous/pseudonymous end-to-end encrypted sockets.
|
||||
README go library for the I2P SAMv3.0
|
||||
|
1
debian/files
vendored
Normal file
1
debian/files
vendored
Normal file
@@ -0,0 +1 @@
|
||||
golang-github-eyedeekay-sam3_0.3.2.01_source.buildinfo devel optional
|
5
go.mod
Normal file
5
go.mod
Normal file
@@ -0,0 +1,5 @@
|
||||
module github.com/eyedeekay/sam3
|
||||
|
||||
go 1.12
|
||||
|
||||
require github.com/eyedeekay/ramp v0.0.0-20190429201811-305b382042ab
|
2
go.sum
Normal file
2
go.sum
Normal file
@@ -0,0 +1,2 @@
|
||||
github.com/eyedeekay/ramp v0.0.0-20190429201811-305b382042ab h1:EfTRHxGSbiaEyxNzvKRBWVIDw3mD8xXGxj4gvwFzY7Q=
|
||||
github.com/eyedeekay/ramp v0.0.0-20190429201811-305b382042ab/go.mod h1:h7mvUAMgZ/rtRDUOkvKTK+8LnDMeUhJSoa5EPdB51fc=
|
@@ -21,8 +21,8 @@ var (
|
||||
// a certificate. String() returns you the full content of I2PKeys and Addr()
|
||||
// returns the public keys.
|
||||
type I2PKeys struct {
|
||||
addr I2PAddr // only the public key
|
||||
both string // both public and private keys
|
||||
Address I2PAddr // only the public key
|
||||
Both string // both public and private keys
|
||||
}
|
||||
|
||||
// Creates I2PKeys from an I2PAddr and a public/private keypair string (as
|
||||
@@ -44,19 +44,19 @@ func LoadKeysIncompat(r io.Reader) (k I2PKeys, err error) {
|
||||
|
||||
// store keys in non standard format
|
||||
func StoreKeysIncompat(k I2PKeys, w io.Writer) (err error) {
|
||||
_, err = io.WriteString(w, k.addr.Base64()+"\n"+k.both)
|
||||
_, err = io.WriteString(w, k.Address.Base64()+"\n"+k.Both)
|
||||
return
|
||||
}
|
||||
|
||||
// Returns the public keys of the I2PKeys.
|
||||
func (k I2PKeys) Addr() I2PAddr {
|
||||
return k.addr
|
||||
return k.Address
|
||||
}
|
||||
|
||||
// Returns the keys (both public and private), in I2Ps base64 format. Use this
|
||||
// when you create sessions.
|
||||
func (k I2PKeys) String() string {
|
||||
return k.both
|
||||
return k.Both
|
||||
}
|
||||
|
||||
// I2PAddr represents an I2P destination, almost equivalent to an IP address.
|
||||
@@ -80,13 +80,23 @@ func DestHashFromString(str string) (dhash I2PDestHash, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// get string representation of i2p dest hash
|
||||
// get string representation of i2p dest hash(base32 version)
|
||||
func (h I2PDestHash) String() string {
|
||||
b32addr := make([]byte, 56)
|
||||
i2pB32enc.Encode(b32addr, h[:])
|
||||
return string(b32addr[:52]) + ".b32.i2p"
|
||||
}
|
||||
|
||||
// get base64 representation of i2p dest sha256 hash(the 44-character one)
|
||||
func (h I2PDestHash) Hash() string {
|
||||
hash := sha256.New()
|
||||
hash.Write(h[:])
|
||||
digest := hash.Sum(nil)
|
||||
buf := make([]byte, 44)
|
||||
i2pB64enc.Encode(buf, digest)
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
// Returns "I2P"
|
||||
func (h *I2PDestHash) Network() string {
|
||||
return "I2P"
|
||||
|
26
raw.go
26
raw.go
@@ -6,10 +6,8 @@ import (
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
import (
|
||||
. "github.com/eyedeekay/sam3/i2pkeys"
|
||||
"github.com/eyedeekay/sam3/i2pkeys"
|
||||
)
|
||||
|
||||
// The RawSession provides no authentication of senders, and there is no sender
|
||||
@@ -19,24 +17,24 @@ import (
|
||||
// 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..
|
||||
type RawSession struct {
|
||||
samAddr string // address to the sam bridge (ipv4:port)
|
||||
id string // tunnel name
|
||||
conn net.Conn // connection to sam bridge
|
||||
udpconn *net.UDPConn // used to deliver datagrams
|
||||
keys I2PKeys // i2p destination keys
|
||||
rUDPAddr *net.UDPAddr // the SAM bridge UDP-port
|
||||
samAddr string // address to the sam bridge (ipv4:port)
|
||||
id string // tunnel name
|
||||
conn net.Conn // connection to sam bridge
|
||||
udpconn *net.UDPConn // used to deliver datagrams
|
||||
keys i2pkeys.I2PKeys // i2p destination keys
|
||||
rUDPAddr *net.UDPAddr // the SAM bridge UDP-port
|
||||
}
|
||||
|
||||
// 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 (s *SAM) NewRawSession(id string, keys I2PKeys, options []string, udpPort int) (*RawSession, error) {
|
||||
func (s *SAM) NewRawSession(id string, keys i2pkeys.I2PKeys, options []string, udpPort int) (*RawSession, error) {
|
||||
if udpPort > 65335 || udpPort < 0 {
|
||||
return nil, errors.New("udpPort needs to be in the intervall 0-65335")
|
||||
}
|
||||
if udpPort == 0 {
|
||||
udpPort = 7655
|
||||
}
|
||||
lhost, _, err := net.SplitHostPort(s.Conn.LocalAddr().String())
|
||||
lhost, _, err := net.SplitHostPort(s.conn.LocalAddr().String())
|
||||
if err != nil {
|
||||
s.Close()
|
||||
return nil, err
|
||||
@@ -49,7 +47,7 @@ func (s *SAM) NewRawSession(id string, keys I2PKeys, options []string, udpPort i
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rhost, _, err := net.SplitHostPort(s.Conn.RemoteAddr().String())
|
||||
rhost, _, err := net.SplitHostPort(s.conn.RemoteAddr().String())
|
||||
if err != nil {
|
||||
s.Close()
|
||||
return nil, err
|
||||
@@ -87,7 +85,7 @@ func (s *RawSession) Read(b []byte) (n int, err error) {
|
||||
|
||||
// Sends one raw datagram to the destination specified. At the time of writing,
|
||||
// maximum size is 32 kilobyte, but this may change in the future.
|
||||
func (s *RawSession) WriteTo(b []byte, addr I2PAddr) (n int, err error) {
|
||||
func (s *RawSession) WriteTo(b []byte, addr i2pkeys.I2PAddr) (n int, err error) {
|
||||
header := []byte("3.0 " + s.id + " " + addr.String() + "\n")
|
||||
msg := append(header, b...)
|
||||
n, err = s.udpconn.WriteToUDP(msg, s.rUDPAddr)
|
||||
@@ -105,7 +103,7 @@ func (s *RawSession) Close() error {
|
||||
}
|
||||
|
||||
// Returns the local I2P destination of the RawSession.
|
||||
func (s *RawSession) LocalAddr() I2PAddr {
|
||||
func (s *RawSession) LocalAddr() i2pkeys.I2PAddr {
|
||||
return s.keys.Addr()
|
||||
}
|
||||
|
||||
|
21
resolver.go
21
resolver.go
@@ -5,10 +5,8 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
import (
|
||||
. "github.com/eyedeekay/sam3/i2pkeys"
|
||||
"github.com/eyedeekay/sam3/i2pkeys"
|
||||
)
|
||||
|
||||
type SAMResolver struct {
|
||||
@@ -33,19 +31,19 @@ func NewFullSAMResolver(address string) (*SAMResolver, error) {
|
||||
|
||||
// Performs a lookup, probably this order: 1) routers known addresses, cached
|
||||
// addresses, 3) by asking peers in the I2P network.
|
||||
func (sam *SAMResolver) Resolve(name string) (I2PAddr, error) {
|
||||
if _, err := sam.Conn.Write([]byte("NAMING LOOKUP NAME=" + name + "\n")); err != nil {
|
||||
func (sam *SAMResolver) Resolve(name string) (i2pkeys.I2PAddr, error) {
|
||||
if _, err := sam.conn.Write([]byte("NAMING LOOKUP NAME=" + name + "\r\n")); err != nil {
|
||||
sam.Close()
|
||||
return I2PAddr(""), err
|
||||
return i2pkeys.I2PAddr(""), err
|
||||
}
|
||||
buf := make([]byte, 4096)
|
||||
n, err := sam.Conn.Read(buf)
|
||||
n, err := sam.conn.Read(buf)
|
||||
if err != nil {
|
||||
sam.Close()
|
||||
return I2PAddr(""), err
|
||||
return i2pkeys.I2PAddr(""), err
|
||||
}
|
||||
if n <= 13 || !strings.HasPrefix(string(buf[:n]), "NAMING REPLY ") {
|
||||
return I2PAddr(""), errors.New("Failed to parse.")
|
||||
return i2pkeys.I2PAddr(""), errors.New("Failed to parse.")
|
||||
}
|
||||
s := bufio.NewScanner(bytes.NewReader(buf[13:n]))
|
||||
s.Split(bufio.ScanWords)
|
||||
@@ -53,6 +51,7 @@ func (sam *SAMResolver) Resolve(name string) (I2PAddr, error) {
|
||||
errStr := ""
|
||||
for s.Scan() {
|
||||
text := s.Text()
|
||||
//log.Println("SAM3", text)
|
||||
if text == "RESULT=OK" {
|
||||
continue
|
||||
} else if text == "RESULT=INVALID_KEY" {
|
||||
@@ -62,12 +61,12 @@ func (sam *SAMResolver) Resolve(name string) (I2PAddr, error) {
|
||||
} else if text == "NAME="+name {
|
||||
continue
|
||||
} else if strings.HasPrefix(text, "VALUE=") {
|
||||
return I2PAddr(text[6:]), nil
|
||||
return i2pkeys.I2PAddr(text[6:]), nil
|
||||
} else if strings.HasPrefix(text, "MESSAGE=") {
|
||||
errStr += " " + text[8:]
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return I2PAddr(""), errors.New(errStr)
|
||||
return i2pkeys.I2PAddr(""), errors.New(errStr)
|
||||
}
|
||||
|
73
sam3.go
73
sam3.go
@@ -9,20 +9,23 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/eyedeekay/sam3/i2pkeys"
|
||||
)
|
||||
|
||||
import (
|
||||
"github.com/eyedeekay/ramp/config"
|
||||
. "github.com/eyedeekay/ramp/emit"
|
||||
. "github.com/eyedeekay/sam3/i2pkeys"
|
||||
)
|
||||
|
||||
// Used for controlling I2Ps SAMv3.
|
||||
type SAM struct {
|
||||
//address string
|
||||
Conn net.Conn
|
||||
Resolver *SAMResolver
|
||||
address string
|
||||
conn net.Conn
|
||||
resolver *SAMResolver
|
||||
Config SAMEmit
|
||||
keys *i2pkeys.I2PKeys
|
||||
sigType int
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -46,9 +49,7 @@ const (
|
||||
func NewSAM(address string) (*SAM, error) {
|
||||
var s SAM
|
||||
// TODO: clean this up
|
||||
s.Config.I2PConfig.SetSAMAddress(address)
|
||||
s.Config.SamMax = "3.2"
|
||||
conn, err := net.Dial("tcp", s.Config.I2PConfig.Sam())
|
||||
conn, err := net.Dial("tcp", address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -63,9 +64,10 @@ func NewSAM(address string) (*SAM, error) {
|
||||
return nil, err
|
||||
}
|
||||
if strings.Contains(string(buf[:n]), "HELLO REPLY RESULT=OK") {
|
||||
s.Conn = conn
|
||||
s.Config.I2PConfig.SetSAMAddress(address)
|
||||
s.conn = conn
|
||||
//s.Config.I2PConfig.DestinationKeys = nil
|
||||
s.Resolver, err = NewSAMResolver(&s)
|
||||
s.resolver, err = NewSAMResolver(&s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -80,7 +82,7 @@ func NewSAM(address string) (*SAM, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (sam *SAM) Keys() (k *I2PKeys) {
|
||||
func (sam *SAM) Keys() (k *i2pkeys.I2PKeys) {
|
||||
//TODO: copy them?
|
||||
k = &sam.Config.I2PConfig.DestinationKeys
|
||||
return
|
||||
@@ -88,8 +90,8 @@ func (sam *SAM) Keys() (k *I2PKeys) {
|
||||
|
||||
// read public/private keys from an io.Reader
|
||||
func (sam *SAM) ReadKeys(r io.Reader) (err error) {
|
||||
var keys I2PKeys
|
||||
keys, err = LoadKeysIncompat(r)
|
||||
var keys i2pkeys.I2PKeys
|
||||
keys, err = i2pkeys.LoadKeysIncompat(r)
|
||||
if err == nil {
|
||||
sam.Config.I2PConfig.DestinationKeys = keys
|
||||
}
|
||||
@@ -97,7 +99,7 @@ func (sam *SAM) ReadKeys(r io.Reader) (err error) {
|
||||
}
|
||||
|
||||
// if keyfile fname does not exist
|
||||
func (sam *SAM) EnsureKeyfile(fname string) (keys I2PKeys, err error) {
|
||||
func (sam *SAM) EnsureKeyfile(fname string) (keys i2pkeys.I2PKeys, err error) {
|
||||
if fname == "" {
|
||||
// transient
|
||||
keys, err = sam.NewKeys()
|
||||
@@ -116,7 +118,7 @@ func (sam *SAM) EnsureKeyfile(fname string) (keys I2PKeys, err error) {
|
||||
var f io.WriteCloser
|
||||
f, err = os.OpenFile(fname, os.O_WRONLY|os.O_CREATE, 0600)
|
||||
if err == nil {
|
||||
err = StoreKeysIncompat(keys, f)
|
||||
err = i2pkeys.StoreKeysIncompat(keys, f)
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
@@ -125,7 +127,7 @@ func (sam *SAM) EnsureKeyfile(fname string) (keys I2PKeys, err error) {
|
||||
var f *os.File
|
||||
f, err = os.Open(fname)
|
||||
if err == nil {
|
||||
keys, err = LoadKeysIncompat(f)
|
||||
keys, err = i2pkeys.LoadKeysIncompat(f)
|
||||
if err == nil {
|
||||
sam.Config.I2PConfig.DestinationKeys = keys
|
||||
}
|
||||
@@ -138,18 +140,18 @@ func (sam *SAM) EnsureKeyfile(fname string) (keys I2PKeys, err error) {
|
||||
// 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 *SAM) NewKeys(sigType ...string) (I2PKeys, error) {
|
||||
func (sam *SAM) NewKeys(sigType ...string) (i2pkeys.I2PKeys, error) {
|
||||
sigtmp := ""
|
||||
if len(sigType) > 0 {
|
||||
sigtmp = sigType[0]
|
||||
}
|
||||
if _, err := sam.Conn.Write([]byte("DEST GENERATE " + sigtmp + "\n")); err != nil {
|
||||
return I2PKeys{}, err
|
||||
if _, err := sam.conn.Write([]byte("DEST GENERATE " + sigtmp + "\n")); err != nil {
|
||||
return i2pkeys.I2PKeys{}, err
|
||||
}
|
||||
buf := make([]byte, 8192)
|
||||
n, err := sam.Conn.Read(buf)
|
||||
n, err := sam.conn.Read(buf)
|
||||
if err != nil {
|
||||
return I2PKeys{}, err
|
||||
return i2pkeys.I2PKeys{}, err
|
||||
}
|
||||
s := bufio.NewScanner(bytes.NewReader(buf[:n]))
|
||||
s.Split(bufio.ScanWords)
|
||||
@@ -166,7 +168,7 @@ func (sam *SAM) NewKeys(sigType ...string) (I2PKeys, error) {
|
||||
} else if strings.HasPrefix(text, "PRIV=") {
|
||||
priv = text[5:]
|
||||
} else {
|
||||
return I2PKeys{}, errors.New("Failed to parse keys.")
|
||||
return i2pkeys.I2PKeys{}, errors.New("Failed to parse keys.")
|
||||
}
|
||||
}
|
||||
return NewKeys(I2PAddr(pub), priv), nil
|
||||
@@ -174,8 +176,8 @@ func (sam *SAM) NewKeys(sigType ...string) (I2PKeys, error) {
|
||||
|
||||
// Performs a lookup, probably this order: 1) routers known addresses, cached
|
||||
// addresses, 3) by asking peers in the I2P network.
|
||||
func (sam *SAM) Lookup(name string) (I2PAddr, error) {
|
||||
return sam.Resolver.Resolve(name)
|
||||
func (sam *SAM) Lookup(name string) (i2pkeys.I2PAddr, error) {
|
||||
return sam.resolver.Resolve(name)
|
||||
}
|
||||
|
||||
// Creates a new session with the style of either "STREAM", "DATAGRAM" or "RAW",
|
||||
@@ -183,25 +185,28 @@ func (sam *SAM) Lookup(name string) (I2PAddr, error) {
|
||||
// I2CP/streaminglib-options as specified. Extra arguments can be specified by
|
||||
// setting extra to something else than []string{}.
|
||||
// This sam3 instance is now a session
|
||||
func (sam *SAM) newGenericSession(style, id string, keys I2PKeys, options []string, extras []string) (net.Conn, error) {
|
||||
func (sam *SAM) newGenericSession(style, id string, keys i2pkeys.I2PKeys, options []string, extras []string) (net.Conn, error) {
|
||||
return sam.newGenericSessionWithSignature(style, id, keys, Sig_NONE, options, extras)
|
||||
}
|
||||
|
||||
func (sam *SAM) newGenericSessionWithSignature(style, id string, keys i2pkeys.I2PKeys, sigType string, options []string, extras []string) (net.Conn, error) {
|
||||
return sam.newGenericSessionWithSignatureAndPorts(style, id, "0", "0", keys, sigType, options, extras)
|
||||
}
|
||||
|
||||
// Creates a new session with the style of either "STREAM", "DATAGRAM" or "RAW",
|
||||
// for a new I2P tunnel with name id, using the cypher keys specified, with the
|
||||
// I2CP/streaminglib-options as specified. Extra arguments can be specified by
|
||||
// setting extra to something else than []string{}.
|
||||
// This sam3 instance is now a session
|
||||
func (sam *SAM) newGenericSessionWithSignature(style, id string, keys I2PKeys, sigType string, options []string, extras []string) (net.Conn, error) {
|
||||
conf, _ := i2pconfig.ConstructEqualsConfig(append(options))
|
||||
sam.Config.I2PConfig = *conf
|
||||
sam.Config.SigType = sigType
|
||||
sam.Config.Style = style
|
||||
sam.Config.DestinationKeys = keys
|
||||
sam.Config.TunName = id
|
||||
func (sam *SAM) newGenericSessionWithSignatureAndPorts(style, id, from, to string, keys i2pkeys.I2PKeys, sigType string, options []string, extras []string) (net.Conn, error) {
|
||||
|
||||
conn := sam.Conn
|
||||
scmsg := []byte("SESSION CREATE " + sam.Config.SessionStyle() + sam.Config.ID() + sam.Config.DestinationKey() + sam.Config.SignatureType() + sam.Config.FromPort() + sam.Config.ToPort() + sam.Config.OptStr() + strings.Join(extras, " ") + "\n")
|
||||
optStr := ""
|
||||
for _, opt := range options {
|
||||
optStr += opt + " "
|
||||
}
|
||||
|
||||
conn := sam.conn
|
||||
scmsg := []byte("SESSION CREATE STYLE=" + style + " FROM_PORT=" + from + " TO_PORT=" + to + " ID=" + id + " DESTINATION=" + keys.String() + " " + sigType + " " + optStr + strings.Join(extras, " ") + "\n")
|
||||
for m, i := 0, 0; m != len(scmsg); i++ {
|
||||
if i == 15 {
|
||||
conn.Close()
|
||||
@@ -247,5 +252,5 @@ func (sam *SAM) newGenericSessionWithSignature(style, id string, keys I2PKeys, s
|
||||
|
||||
// close this sam session
|
||||
func (sam *SAM) Close() error {
|
||||
return sam.Conn.Close()
|
||||
return sam.conn.Close()
|
||||
}
|
||||
|
53
stream.go
53
stream.go
@@ -11,18 +11,16 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
import (
|
||||
. "github.com/eyedeekay/sam3/i2pkeys"
|
||||
"github.com/eyedeekay/sam3/i2pkeys"
|
||||
)
|
||||
|
||||
// Represents a streaming session.
|
||||
type StreamSession struct {
|
||||
samAddr string // address to the sam bridge (ipv4:port)
|
||||
id string // tunnel name
|
||||
conn net.Conn // connection to sam
|
||||
keys I2PKeys // i2p destination keys
|
||||
samAddr string // address to the sam bridge (ipv4:port)
|
||||
id string // tunnel name
|
||||
conn net.Conn // connection to sam
|
||||
keys i2pkeys.I2PKeys // i2p destination keys
|
||||
Timeout time.Duration
|
||||
Deadline time.Time
|
||||
sigType string
|
||||
@@ -52,18 +50,18 @@ func (ss *StreamSession) Close() error {
|
||||
}
|
||||
|
||||
// Returns the I2P destination (the address) of the stream session
|
||||
func (ss *StreamSession) Addr() I2PAddr {
|
||||
func (ss *StreamSession) Addr() i2pkeys.I2PAddr {
|
||||
return ss.keys.Addr()
|
||||
}
|
||||
|
||||
// Returns the keys associated with the stream session
|
||||
func (ss *StreamSession) Keys() I2PKeys {
|
||||
func (ss *StreamSession) Keys() i2pkeys.I2PKeys {
|
||||
return ss.keys
|
||||
}
|
||||
|
||||
// Creates a new StreamSession with the I2CP- and streaminglib options as
|
||||
// specified. See the I2P documentation for a full list of options.
|
||||
func (sam *SAM) NewStreamSession(id string, keys I2PKeys, options []string) (*StreamSession, error) {
|
||||
func (sam *SAM) NewStreamSession(id string, keys i2pkeys.I2PKeys, options []string) (*StreamSession, error) {
|
||||
conn, err := sam.newGenericSession("STREAM", id, keys, options, []string{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -73,7 +71,7 @@ func (sam *SAM) NewStreamSession(id string, keys I2PKeys, options []string) (*St
|
||||
|
||||
// Creates a new StreamSession with the I2CP- and streaminglib options as
|
||||
// specified. See the I2P documentation for a full list of options.
|
||||
func (sam *SAM) NewStreamSessionWithSignature(id string, keys I2PKeys, options []string, sigType string) (*StreamSession, error) {
|
||||
func (sam *SAM) NewStreamSessionWithSignature(id string, keys i2pkeys.I2PKeys, options []string, sigType string) (*StreamSession, error) {
|
||||
conn, err := sam.newGenericSessionWithSignature("STREAM", id, keys, sigType, options, []string{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -83,23 +81,23 @@ func (sam *SAM) NewStreamSessionWithSignature(id string, keys I2PKeys, options [
|
||||
|
||||
// Creates a new StreamSession with the I2CP- and streaminglib options as
|
||||
// specified. See the I2P documentation for a full list of options.
|
||||
func (sam *SAM) NewStreamSessionWithSignatureAndPorts(id string, keys I2PKeys, options []string, sigType string) (*StreamSession, error) {
|
||||
conn, err := sam.newGenericSessionWithSignature("STREAM", id, keys, sigType, options, []string{})
|
||||
func (sam *SAM) NewStreamSessionWithSignatureAndPorts(id, from, to string, keys i2pkeys.I2PKeys, options []string, sigType string) (*StreamSession, error) {
|
||||
conn, err := sam.newGenericSessionWithSignatureAndPorts("STREAM", id, from, to, keys, sigType, options, []string{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &StreamSession{sam.Config.I2PConfig.Sam(), id, conn, keys, time.Duration(600 * time.Second), time.Now(), sigType, sam.Config.Fromport, sam.Config.Toport}, nil
|
||||
return &StreamSession{sam.Config.I2PConfig.Sam(), id, conn, keys, time.Duration(600 * time.Second), time.Now(), sigType, from, to}, nil
|
||||
}
|
||||
|
||||
// lookup name, convienence function
|
||||
func (s *StreamSession) Lookup(name string) (I2PAddr, error) {
|
||||
func (s *StreamSession) Lookup(name string) (i2pkeys.I2PAddr, error) {
|
||||
sam, err := NewSAM(s.samAddr)
|
||||
if err == nil {
|
||||
addr, err := sam.Lookup(name)
|
||||
sam.Close()
|
||||
return addr, err
|
||||
}
|
||||
return I2PAddr(""), err
|
||||
return i2pkeys.I2PAddr(""), err
|
||||
}
|
||||
|
||||
// context-aware dialer, eventually...
|
||||
@@ -121,7 +119,7 @@ func (s *StreamSession) DialContextI2P(ctx context.Context, n, addr string) (*SA
|
||||
}
|
||||
}
|
||||
|
||||
i2paddr, err := NewI2PAddrFromString(addr)
|
||||
i2paddr, err := i2pkeys.NewI2PAddrFromString(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -163,7 +161,7 @@ func (s *StreamSession) deadline(ctx context.Context, now time.Time) (earliest t
|
||||
// implement net.Dialer
|
||||
func (s *StreamSession) Dial(n, addr string) (c net.Conn, err error) {
|
||||
|
||||
var i2paddr I2PAddr
|
||||
var i2paddr i2pkeys.I2PAddr
|
||||
var host string
|
||||
host, _, err = net.SplitHostPort(addr)
|
||||
if err == nil {
|
||||
@@ -173,7 +171,7 @@ func (s *StreamSession) Dial(n, addr string) (c net.Conn, err error) {
|
||||
i2paddr, err = s.Lookup(host)
|
||||
} else {
|
||||
// probably a destination
|
||||
i2paddr = I2PAddr(host)
|
||||
i2paddr = i2pkeys.I2PAddr(host)
|
||||
}
|
||||
if err == nil {
|
||||
return s.DialI2P(i2paddr)
|
||||
@@ -183,14 +181,13 @@ func (s *StreamSession) Dial(n, addr string) (c net.Conn, err error) {
|
||||
}
|
||||
|
||||
// Dials to an I2P destination and returns a SAMConn, which implements a net.Conn.
|
||||
func (s *StreamSession) DialI2P(addr I2PAddr) (*SAMConn, error) {
|
||||
func (s *StreamSession) DialI2P(addr i2pkeys.I2PAddr) (*SAMConn, error) {
|
||||
sam, err := NewSAM(s.samAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conn := sam.Conn
|
||||
// + sam.Config.ID()
|
||||
_, err = conn.Write([]byte("STREAM CONNECT ID=" + s.id + sam.Config.FromPort() + sam.Config.ToPort() + " DESTINATION=" + addr.Base64() + " SILENT=false\n"))
|
||||
conn := sam.conn
|
||||
_, err = conn.Write([]byte("STREAM CONNECT ID=" + s.id + " FROM_PORT=" + s.from + " TO_PORT=" + s.to + " DESTINATION=" + addr.Base64() + " SILENT=false\n"))
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
return nil, err
|
||||
@@ -249,7 +246,7 @@ type StreamListener struct {
|
||||
// our session id
|
||||
id string
|
||||
// our local address for this sam socket
|
||||
laddr I2PAddr
|
||||
laddr i2pkeys.I2PAddr
|
||||
}
|
||||
|
||||
func (l *StreamListener) From() string {
|
||||
@@ -307,9 +304,9 @@ func (l *StreamListener) AcceptI2P() (*SAMConn, error) {
|
||||
if err == nil {
|
||||
// we connected to sam
|
||||
// send accept() command
|
||||
_, err = io.WriteString(s.Conn, "STREAM ACCEPT ID="+l.id+" SILENT=false\n")
|
||||
_, err = io.WriteString(s.conn, "STREAM ACCEPT ID="+l.id+" SILENT=false\n")
|
||||
// read reply
|
||||
rd := bufio.NewReader(s.Conn)
|
||||
rd := bufio.NewReader(s.conn)
|
||||
// read first line
|
||||
line, err := rd.ReadString(10)
|
||||
log.Println(line)
|
||||
@@ -326,8 +323,8 @@ func (l *StreamListener) AcceptI2P() (*SAMConn, error) {
|
||||
dest = strings.Trim(dest, "\n")
|
||||
return &SAMConn{
|
||||
laddr: l.laddr,
|
||||
raddr: I2PAddr(dest),
|
||||
conn: s.Conn,
|
||||
raddr: i2pkeys.I2PAddr(dest),
|
||||
conn: s.conn,
|
||||
}, nil
|
||||
} else {
|
||||
s.Close()
|
||||
|
@@ -4,12 +4,11 @@ package sam3
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
import (
|
||||
. "github.com/eyedeekay/sam3/i2pkeys"
|
||||
"github.com/eyedeekay/sam3/i2pkeys"
|
||||
)
|
||||
|
||||
func Test_StreamingDial(t *testing.T) {
|
||||
@@ -31,7 +30,7 @@ func Test_StreamingDial(t *testing.T) {
|
||||
return
|
||||
}
|
||||
fmt.Println("\tBuilding tunnel")
|
||||
ss, err := sam.NewStreamSession("streamTun", keys, []string{"inbound.length=0", "outbound.length=0", "inbound.lengthVariance=0", "outbound.lengthVariance=0", "inbound.quantity=1", "outbound.quantity=1"})
|
||||
ss, err := sam.NewStreamSession("streamTun", keys, []string{"inbound.length=1", "outbound.length=1", "inbound.lengthVariance=0", "outbound.lengthVariance=0", "inbound.quantity=1", "outbound.quantity=1"})
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
t.Fail()
|
||||
@@ -45,7 +44,7 @@ func Test_StreamingDial(t *testing.T) {
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
fmt.Println("\tDialing i2p-projekt.i2p")
|
||||
fmt.Println("\tDialing i2p-projekt.i2p(", forumAddr.Base32(), forumAddr.DestHash().Hash(), ")")
|
||||
conn, err := ss.DialI2P(forumAddr)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
@@ -194,8 +193,10 @@ func ExampleStreamSession() {
|
||||
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)
|
||||
log.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")
|
||||
log.Println("Read HTTP/HTML from zzz.i2p")
|
||||
}
|
||||
return
|
||||
|
||||
@@ -226,7 +227,7 @@ func ExampleStreamListener() {
|
||||
quit := make(chan bool)
|
||||
|
||||
// Client connecting to the server
|
||||
go func(server I2PAddr) {
|
||||
go func(server i2pkeys.I2PAddr) {
|
||||
csam, err := NewSAM(samBridge)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
|
Reference in New Issue
Block a user