Skip to content

Commit c50775e

Browse files
committed
start on a wrapper for sam3
1 parent 6587c5c commit c50775e

22 files changed

+2313
-13
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
review.md
22
SAMv3.md
3+
testplan.md
4+
err

SAMConn.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package sam3
2+
3+
import (
4+
"github.com/go-i2p/go-sam-go/stream"
5+
)
6+
7+
// Implements net.Conn
8+
type SAMConn struct {
9+
*stream.StreamConn
10+
}

common/emitter_test.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package common
2+
3+
import (
4+
"bytes"
5+
"testing"
6+
)
7+
8+
var (
9+
from = RandPort()
10+
to = RandPort()
11+
)
12+
13+
func setupTestEmit() *SAMEmit {
14+
return &SAMEmit{
15+
I2PConfig: I2PConfig{
16+
SamHost: "127.0.0.1",
17+
SamPort: 7656,
18+
SamMin: "3.0",
19+
SamMax: "3.1",
20+
Style: "STREAM",
21+
TunName: "testid",
22+
Fromport: from,
23+
Toport: to,
24+
SigType: "ED25519",
25+
},
26+
}
27+
}
28+
29+
func TestSAMEmit_Hello(t *testing.T) {
30+
emit := setupTestEmit()
31+
want := "HELLO VERSION MIN=3.0 MAX=3.1 \n"
32+
33+
t.Run("string output", func(t *testing.T) {
34+
if got := emit.Hello(); got != want {
35+
t.Errorf("Hello() = %v, want %v", got, want)
36+
}
37+
})
38+
39+
t.Run("byte output", func(t *testing.T) {
40+
if got := emit.HelloBytes(); !bytes.Equal(got, []byte(want)) {
41+
t.Errorf("HelloBytes() = %v, want %v", got, []byte(want))
42+
}
43+
})
44+
}
45+
46+
func TestSAMEmit_GenerateDestination(t *testing.T) {
47+
emit := setupTestEmit()
48+
want := "DEST GENERATE ED25519 \n"
49+
50+
t.Run("string output", func(t *testing.T) {
51+
if got := emit.GenerateDestination(); got != want {
52+
t.Errorf("GenerateDestination() = %v, want %v", got, want)
53+
}
54+
})
55+
56+
t.Run("byte output", func(t *testing.T) {
57+
if got := emit.GenerateDestinationBytes(); !bytes.Equal(got, []byte(want)) {
58+
t.Errorf("GenerateDestinationBytes() = %v, want %v", got, []byte(want))
59+
}
60+
})
61+
}
62+
63+
func TestSAMEmit_Lookup(t *testing.T) {
64+
tests := []struct {
65+
name string
66+
lookup string
67+
want string
68+
}{
69+
{"basic lookup", "test.i2p", "NAMING LOOKUP NAME=test.i2p \n"},
70+
{"empty lookup", "", "NAMING LOOKUP NAME= \n"},
71+
}
72+
73+
emit := setupTestEmit()
74+
for _, tt := range tests {
75+
t.Run(tt.name, func(t *testing.T) {
76+
if got := emit.Lookup(tt.lookup); got != tt.want {
77+
t.Errorf("Lookup() = %v, want %v", got, tt.want)
78+
}
79+
if got := emit.LookupBytes(tt.lookup); !bytes.Equal(got, []byte(tt.want)) {
80+
t.Errorf("LookupBytes() = %v, want %v", got, []byte(tt.want))
81+
}
82+
})
83+
}
84+
}
85+
86+
func TestSAMEmit_Connect(t *testing.T) {
87+
tests := []struct {
88+
name string
89+
dest string
90+
want string
91+
}{
92+
{
93+
"basic connect",
94+
"destination123",
95+
"STREAM CONNECT ID=testid " + from + " " + to + " DESTINATION=destination123 \n",
96+
},
97+
{
98+
"empty destination",
99+
"",
100+
"STREAM CONNECT ID=testid " + from + " " + to + " DESTINATION= \n",
101+
},
102+
}
103+
104+
emit := setupTestEmit()
105+
for _, tt := range tests {
106+
t.Run(tt.name, func(t *testing.T) {
107+
if got := emit.Connect(tt.dest); got != tt.want {
108+
t.Errorf("Connect() = %v, want %v", got, tt.want)
109+
}
110+
if got := emit.ConnectBytes(tt.dest); !bytes.Equal(got, []byte(tt.want)) {
111+
t.Errorf("ConnectBytes() = %v, want %v", got, []byte(tt.want))
112+
}
113+
})
114+
}
115+
}
116+
117+
func TestSAMEmit_Accept(t *testing.T) {
118+
emit := setupTestEmit()
119+
want := "STREAM ACCEPT ID=testid " + from + " " + to + ""
120+
121+
t.Run("string output", func(t *testing.T) {
122+
if got := emit.Accept(); got != want {
123+
t.Errorf("Accept() = %v, want %v", got, want)
124+
}
125+
})
126+
127+
t.Run("byte output", func(t *testing.T) {
128+
if got := emit.AcceptBytes(); !bytes.Equal(got, []byte(want)) {
129+
t.Errorf("AcceptBytes() = %v, want %v", got, []byte(want))
130+
}
131+
})
132+
}

common/util.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ func ExtractDest(input string) string {
7171
return strings.Split(input, " ")[0]
7272
}
7373

74-
var randSource = rand.NewSource(time.Now().UnixNano())
75-
var randGen = rand.New(randSource)
74+
var (
75+
randSource = rand.NewSource(time.Now().UnixNano())
76+
randGen = rand.New(randSource)
77+
)
7678

7779
func RandPort() string {
7880
for {

config.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package sam3
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/go-i2p/go-sam-go/common"
7+
)
8+
9+
// I2PConfig is a struct which manages I2P configuration options
10+
type I2PConfig struct {
11+
common.I2PConfig
12+
}
13+
14+
func NewConfig(opts ...func(*I2PConfig) error) (*I2PConfig, error) {
15+
var config I2PConfig
16+
config.SamHost = "127.0.0.1"
17+
config.SamPort = 7656
18+
config.SamMin = "3.0"
19+
config.SamMax = "3.2"
20+
config.TunName = ""
21+
config.TunType = "server"
22+
config.Style = "STREAM"
23+
config.InLength = 3
24+
config.OutLength = 3
25+
config.InQuantity = 2
26+
config.OutQuantity = 2
27+
config.InVariance = 1
28+
config.OutVariance = 1
29+
config.InBackupQuantity = 3
30+
config.OutBackupQuantity = 3
31+
config.InAllowZeroHop = false
32+
config.OutAllowZeroHop = false
33+
config.EncryptLeaseSet = false
34+
config.LeaseSetKey = ""
35+
config.LeaseSetPrivateKey = ""
36+
config.LeaseSetPrivateSigningKey = ""
37+
config.FastRecieve = false
38+
config.UseCompression = true
39+
config.ReduceIdle = false
40+
config.ReduceIdleTime = 15
41+
config.ReduceIdleQuantity = 4
42+
config.CloseIdle = false
43+
config.CloseIdleTime = 300000
44+
config.MessageReliability = "none"
45+
for _, o := range opts {
46+
if err := o(&config); err != nil {
47+
return nil, err
48+
}
49+
}
50+
return &config, nil
51+
}
52+
53+
// options map
54+
type Options map[string]string
55+
56+
// obtain sam options as list of strings
57+
func (opts Options) AsList() (ls []string) {
58+
for k, v := range opts {
59+
ls = append(ls, fmt.Sprintf("%s=%s", k, v))
60+
}
61+
return
62+
}

datagram.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package sam3
2+
3+
import (
4+
"github.com/go-i2p/go-sam-go/datagram"
5+
)
6+
7+
// The DatagramSession implements net.PacketConn. It works almost like ordinary
8+
// UDP, except that datagrams may be at most 31kB large. These datagrams are
9+
// also end-to-end encrypted, signed and includes replay-protection. And they
10+
// are also built to be surveillance-resistant (yey!).
11+
type DatagramSession struct {
12+
datagram.DatagramSession
13+
}

0 commit comments

Comments
 (0)