Add a basic test of a Primary session by making the datagramm session test fire off a datagram subsession

This commit is contained in:
idk
2021-02-21 00:07:06 -05:00
parent 0b4982e1fe
commit 6b90389d7f
2 changed files with 218 additions and 35 deletions

View File

@@ -15,6 +15,10 @@ import (
"github.com/eyedeekay/sam3/i2pkeys"
)
const (
session_ADDOK = "SESSION STATUS RESULT=OK"
)
// Represents a primary session.
type PrimarySession struct {
samAddr string // address to the sam bridge (ipv4:port)
@@ -85,12 +89,12 @@ func (sam *SAM) NewPrimarySessionWithSignature(id string, keys i2pkeys.I2PKeys,
// 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 *PrimarySession) newGenericSubSession(style, id string, keys i2pkeys.I2PKeys, options []string, extras []string) (net.Conn, error) {
return sam.newGenericSubSessionWithSignature(style, id, keys, Sig_NONE, options, extras)
func (sam *PrimarySession) newGenericSubSession(style, id string, extras []string) (net.Conn, error) {
return sam.newGenericSubSessionWithSignature(style, id, extras)
}
func (sam *PrimarySession) newGenericSubSessionWithSignature(style, id string, keys i2pkeys.I2PKeys, sigType string, options []string, extras []string) (net.Conn, error) {
return sam.newGenericSubSessionWithSignatureAndPorts(style, id, "0", "0", keys, sigType, options, extras)
func (sam *PrimarySession) newGenericSubSessionWithSignature(style, id string, extras []string) (net.Conn, error) {
return sam.newGenericSubSessionWithSignatureAndPorts(style, id, "0", "0", extras)
}
// Creates a new session with the style of either "STREAM", "DATAGRAM" or "RAW",
@@ -98,12 +102,7 @@ func (sam *PrimarySession) newGenericSubSessionWithSignature(style, id string, k
// 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 *PrimarySession) newGenericSubSessionWithSignatureAndPorts(style, id, from, to string, keys i2pkeys.I2PKeys, sigType string, options []string, extras []string) (net.Conn, error) {
optStr := ""
for _, opt := range options {
optStr += opt + " "
}
func (sam *PrimarySession) newGenericSubSessionWithSignatureAndPorts(style, id, from, to string, extras []string) (net.Conn, error) {
conn := sam.conn
fp := ""
@@ -114,7 +113,7 @@ func (sam *PrimarySession) newGenericSubSessionWithSignatureAndPorts(style, id,
if to != "0" {
tp = " TO_PORT=" + to
}
scmsg := []byte("SESSION ADD STYLE=" + style + fp + tp + " ID=" + id + " " + optStr + strings.Join(extras, " ") + "\n")
scmsg := []byte("SESSION ADD STYLE=" + style + fp + tp + " ID=" + id + " " + strings.Join(extras, " ") + "\n")
for m, i := 0, 0; m != len(scmsg); i++ {
if i == 15 {
conn.Close()
@@ -134,8 +133,8 @@ func (sam *PrimarySession) newGenericSubSessionWithSignatureAndPorts(style, id,
return nil, err
}
text := string(buf[:n])
if strings.HasPrefix(text, session_OK) {
if keys.String() != text[len(session_OK):len(text)-1] {
if strings.HasPrefix(text, session_ADDOK) {
if sam.keys.String() != text[len(session_ADDOK):len(text)-1] {
conn.Close()
return nil, errors.New("SAMv3 created a tunnel with keys other than the ones we asked it for")
}
@@ -160,37 +159,27 @@ func (sam *PrimarySession) newGenericSubSessionWithSignatureAndPorts(style, id,
// Creates a new StreamSession with the I2CP- and streaminglib options as
// specified. See the I2P documentation for a full list of options.
func (sam *PrimarySession) NewStreamSession(id string, keys i2pkeys.I2PKeys, options []string) (*StreamSession, error) {
conn, err := sam.newGenericSubSession("STREAM", id, keys, options, []string{})
func (sam *PrimarySession) NewStreamSubSession(id string) (*StreamSession, error) {
conn, err := sam.newGenericSubSession("STREAM", id, []string{})
if err != nil {
return nil, err
}
return &StreamSession{sam.Config.I2PConfig.Sam(), id, conn, keys, time.Duration(600 * time.Second), time.Now(), Sig_NONE, "0", "0"}, nil
return &StreamSession{sam.Config.I2PConfig.Sam(), id, conn, sam.keys, time.Duration(600 * time.Second), time.Now(), Sig_NONE, "0", "0"}, nil
}
// Creates a new StreamSession with the I2CP- and streaminglib options as
// specified. See the I2P documentation for a full list of options.
func (sam *PrimarySession) NewStreamSessionWithSignature(id string, keys i2pkeys.I2PKeys, options []string, sigType string) (*StreamSession, error) {
conn, err := sam.newGenericSubSessionWithSignature("STREAM", id, keys, sigType, options, []string{})
func (sam *PrimarySession) NewStreamSessionWithPorts(id, from, to string) (*StreamSession, error) {
conn, err := sam.newGenericSubSessionWithSignatureAndPorts("STREAM", id, from, to, []string{})
if err != nil {
return nil, err
}
return &StreamSession{sam.Config.I2PConfig.Sam(), id, conn, keys, time.Duration(600 * time.Second), time.Now(), sigType, "0", "0"}, nil
}
// Creates a new StreamSession with the I2CP- and streaminglib options as
// specified. See the I2P documentation for a full list of options.
func (sam *PrimarySession) NewStreamSessionWithSignatureAndPorts(id, from, to string, keys i2pkeys.I2PKeys, options []string, sigType string) (*StreamSession, error) {
conn, err := sam.newGenericSubSessionWithSignatureAndPorts("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, from, to}, nil
return &StreamSession{sam.Config.I2PConfig.Sam(), id, conn, sam.keys, time.Duration(600 * time.Second), time.Now(), Sig_NONE, from, to}, nil
}
// 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 *PrimarySession) NewDatagramSession(id string, keys i2pkeys.I2PKeys, options []string, udpPort int) (*DatagramSession, error) {
func (s *PrimarySession) NewDatagramSubSession(id string, udpPort int) (*DatagramSession, error) {
if udpPort > 65335 || udpPort < 0 {
return nil, errors.New("udpPort needs to be in the intervall 0-65335")
}
@@ -220,16 +209,16 @@ func (s *PrimarySession) NewDatagramSession(id string, keys i2pkeys.I2PKeys, opt
return nil, err
}
_, lport, err := net.SplitHostPort(udpconn.LocalAddr().String())
conn, err := s.newGenericSubSession("DATAGRAM", id, keys, options, []string{"PORT=" + lport})
conn, err := s.newGenericSubSession("DATAGRAM", id, []string{"PORT=" + lport})
if err != nil {
return nil, err
}
return &DatagramSession{s.Config.I2PConfig.Sam(), id, conn, udpconn, keys, rUDPAddr, nil}, nil
return &DatagramSession{s.Config.I2PConfig.Sam(), id, conn, udpconn, s.keys, rUDPAddr, nil}, nil
}
// 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 *PrimarySession) NewRawSession(id string, keys i2pkeys.I2PKeys, options []string, udpPort int) (*RawSession, error) {
func (s *PrimarySession) NewRawSubSession(id string, udpPort int) (*RawSession, error) {
if udpPort > 65335 || udpPort < 0 {
return nil, errors.New("udpPort needs to be in the intervall 0-65335")
}
@@ -259,9 +248,10 @@ func (s *PrimarySession) NewRawSession(id string, keys i2pkeys.I2PKeys, options
return nil, err
}
_, lport, err := net.SplitHostPort(udpconn.LocalAddr().String())
conn, err := s.newGenericSubSession("RAW", id, keys, options, []string{"PORT=" + lport})
// conn, err := s.newGenericSubSession("RAW", id, s.keys, options, []string{"PORT=" + lport})
conn, err := s.newGenericSubSession("RAW", id, []string{"PORT=" + lport})
if err != nil {
return nil, err
}
return &RawSession{s.Config.I2PConfig.Sam(), id, conn, udpconn, keys, rUDPAddr}, nil
return &RawSession{s.Config.I2PConfig.Sam(), id, conn, udpconn, s.keys, rUDPAddr}, nil
}

View File

@@ -1 +1,194 @@
// +build nettest
package sam3
import (
"fmt"
// "log"
"testing"
"time"
)
func Test_PrimaryServerClient(t *testing.T) {
if testing.Short() {
return
}
fmt.Println("Test_DatagramServerClient")
earlysam, err := NewSAM(yoursam)
if err != nil {
t.Fail()
return
}
defer earlysam.Close()
keys, err := earlysam.NewKeys()
if err != nil {
t.Fail()
return
}
sam, err := earlysam.NewPrimarySession("PrimaryTunnel", keys, []string{"inbound.length=0", "outbound.length=0", "inbound.lengthVariance=0", "outbound.lengthVariance=0", "inbound.quantity=1", "outbound.quantity=1"})
if err != nil {
t.Fail()
return
}
defer sam.Close()
// fmt.Println("\tServer: My address: " + keys.Addr().Base32())
fmt.Println("\tServer: Creating tunnel")
ds, err := sam.NewDatagramSubSession("PrimaryTunnel-3", 0)
if err != nil {
fmt.Println("Server: Failed to create tunnel: " + err.Error())
t.Fail()
return
}
defer ds.Close()
c, w := make(chan bool), make(chan bool)
go func(c, w chan (bool)) {
sam2, err := NewSAM(yoursam)
if err != nil {
c <- false
return
}
defer sam2.Close()
keys, err := sam2.NewKeys()
if err != nil {
c <- false
return
}
fmt.Println("\tClient: Creating tunnel")
ds2, err := sam2.NewDatagramSession("PRIMARYClientTunnel", 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.LocalAddr().Base32())
// fmt.Println("\tClient: Clients address: " + ds2.LocalAddr().Base32())
fmt.Println("\tClient: Tries to send primary to server")
for {
select {
default:
_, err = ds2.WriteTo([]byte("Hello primary-world! <3 <3 <3 <3 <3 <3"), ds.LocalAddr())
if err != nil {
fmt.Println("\tClient: Failed to send primary: " + err.Error())
c <- false
return
}
time.Sleep(5 * time.Second)
case <-w:
fmt.Println("\tClient: Sent primary, quitting.")
return
}
}
c <- true
}(c, w)
buf := make([]byte, 512)
fmt.Println("\tServer: ReadFrom() waiting...")
n, _, err := ds.ReadFrom(buf)
w <- true
if err != nil {
fmt.Println("\tServer: Failed to ReadFrom(): " + err.Error())
t.Fail()
return
}
fmt.Println("\tServer: Received primary: " + string(buf[:n]))
// fmt.Println("\tServer: Senders address was: " + saddr.Base32())
}
/*
func ExamplePrimarySession() {
// 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
}
log.Println("Got message: '" + string(buf[:n]) + "'")
fmt.Println("Got message: " + string(buf[:n]))
return
// Output:
//Got message: Hello myself!
}
func ExampleMiniPrimarySession() {
// 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
// Output:
//Got message: Hello myself!
}*/