Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b9e4186119 | ||
![]() |
3f57ff4eaf | ||
![]() |
4c6e2f5d88 |
@@ -1,6 +1,7 @@
|
|||||||
package sam
|
package sam
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
@@ -24,7 +25,7 @@ func I2PListener(name, samaddr, keyspath string) (*sam3.StreamListener, error) {
|
|||||||
if keyspath != "" {
|
if keyspath != "" {
|
||||||
err = ioutil.WriteFile(keyspath+".i2p.public.txt", []byte(listener.Keys().Addr().Base32()), 0644)
|
err = ioutil.WriteFile(keyspath+".i2p.public.txt", []byte(listener.Keys().Addr().Base32()), 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("error storing I2P base32 address in adjacent text file, %s", err)
|
return nil, fmt.Errorf("error storing I2P base32 address in adjacent text file, %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return listener.Listen() //, err
|
return listener.Listen() //, err
|
||||||
@@ -37,32 +38,38 @@ func I2PStreamSession(name, samaddr, keyspath string) (*sam3.StreamSession, erro
|
|||||||
log.Printf("Starting and registering I2P session...")
|
log.Printf("Starting and registering I2P session...")
|
||||||
sam, err := sam3.NewSAM(samaddr)
|
sam, err := sam3.NewSAM(samaddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("error connecting to SAM to %s: %s", samaddr, err)
|
return nil, fmt.Errorf("error connecting to SAM to %s: %s", samaddr, err)
|
||||||
}
|
}
|
||||||
var keys *i2pkeys.I2PKeys
|
var keys *i2pkeys.I2PKeys
|
||||||
if keyspath != "" {
|
if keyspath != "" {
|
||||||
if _, err := os.Stat(keyspath + ".i2p.private"); os.IsNotExist(err) {
|
if _, err := os.Stat(keyspath + ".i2p.private"); os.IsNotExist(err) {
|
||||||
f, err := os.Create(keyspath + ".i2p.private")
|
f, err := os.Create(keyspath + ".i2p.private")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to open I2P keyfile for writing: %s", err)
|
return nil, fmt.Errorf("unable to open I2P keyfile for writing: %s", err)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
tkeys, err := sam.NewKeys()
|
tkeys, err := sam.NewKeys()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to generate I2P Keys, %s", err)
|
return nil, fmt.Errorf("unable to generate I2P Keys, %s", err)
|
||||||
}
|
}
|
||||||
keys = &tkeys
|
keys = &tkeys
|
||||||
err = i2pkeys.StoreKeysIncompat(*keys, f)
|
err = i2pkeys.StoreKeysIncompat(*keys, f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to save newly generated I2P Keys, %s", err)
|
return nil, fmt.Errorf("unable to save newly generated I2P Keys, %s", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tkeys, err := i2pkeys.LoadKeys(keyspath + ".i2p.private")
|
tkeys, err := i2pkeys.LoadKeys(keyspath + ".i2p.private")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to load I2P Keys: %e", err)
|
return nil, fmt.Errorf("unable to load I2P Keys: %e", err)
|
||||||
}
|
}
|
||||||
keys = &tkeys
|
keys = &tkeys
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
tkeys, err := sam.NewKeys()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to generate I2P Keys, %s", err)
|
||||||
|
}
|
||||||
|
keys = &tkeys
|
||||||
}
|
}
|
||||||
stream, err := sam.NewStreamSession(name, *keys, sam3.Options_Medium)
|
stream, err := sam.NewStreamSession(name, *keys, sam3.Options_Medium)
|
||||||
return stream, err
|
return stream, err
|
||||||
@@ -74,32 +81,38 @@ func I2PDatagramSession(name, samaddr, keyspath string) (*sam3.DatagramSession,
|
|||||||
log.Printf("Starting and registering I2P session...")
|
log.Printf("Starting and registering I2P session...")
|
||||||
sam, err := sam3.NewSAM(samaddr)
|
sam, err := sam3.NewSAM(samaddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("error connecting to SAM to %s: %s", samaddr, err)
|
return nil, fmt.Errorf("error connecting to SAM to %s: %s", samaddr, err)
|
||||||
}
|
}
|
||||||
var keys *i2pkeys.I2PKeys
|
var keys *i2pkeys.I2PKeys
|
||||||
if keyspath != "" {
|
if keyspath != "" {
|
||||||
if _, err := os.Stat(keyspath + ".i2p.private"); os.IsNotExist(err) {
|
if _, err := os.Stat(keyspath + ".i2p.private"); os.IsNotExist(err) {
|
||||||
f, err := os.Create(keyspath + ".i2p.private")
|
f, err := os.Create(keyspath + ".i2p.private")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to open I2P keyfile for writing: %s", err)
|
return nil, fmt.Errorf("unable to open I2P keyfile for writing: %s", err)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
tkeys, err := sam.NewKeys()
|
tkeys, err := sam.NewKeys()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to generate I2P Keys, %s", err)
|
return nil, fmt.Errorf("unable to generate I2P Keys, %s", err)
|
||||||
}
|
}
|
||||||
keys = &tkeys
|
keys = &tkeys
|
||||||
err = i2pkeys.StoreKeysIncompat(*keys, f)
|
err = i2pkeys.StoreKeysIncompat(*keys, f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to save newly generated I2P Keys, %s", err)
|
return nil, fmt.Errorf("unable to save newly generated I2P Keys, %s", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tkeys, err := i2pkeys.LoadKeys(keyspath + ".i2p.private")
|
tkeys, err := i2pkeys.LoadKeys(keyspath + ".i2p.private")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to load I2P Keys: %e", err)
|
return nil, fmt.Errorf("unable to load I2P Keys: %e", err)
|
||||||
}
|
}
|
||||||
keys = &tkeys
|
keys = &tkeys
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
tkeys, err := sam.NewKeys()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to generate I2P Keys, %s", err)
|
||||||
|
}
|
||||||
|
keys = &tkeys
|
||||||
}
|
}
|
||||||
gram, err := sam.NewDatagramSession(name, *keys, sam3.Options_Medium, 0)
|
gram, err := sam.NewDatagramSession(name, *keys, sam3.Options_Medium, 0)
|
||||||
return gram, err
|
return gram, err
|
||||||
@@ -111,32 +124,38 @@ func I2PPrimarySession(name, samaddr, keyspath string) (*sam3.PrimarySession, er
|
|||||||
log.Printf("Starting and registering I2P session...")
|
log.Printf("Starting and registering I2P session...")
|
||||||
sam, err := sam3.NewSAM(samaddr)
|
sam, err := sam3.NewSAM(samaddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("error connecting to SAM to %s: %s", samaddr, err)
|
return nil, fmt.Errorf("error connecting to SAM to %s: %s", samaddr, err)
|
||||||
}
|
}
|
||||||
var keys *i2pkeys.I2PKeys
|
var keys *i2pkeys.I2PKeys
|
||||||
if keyspath != "" {
|
if keyspath != "" {
|
||||||
if _, err := os.Stat(keyspath + ".i2p.private"); os.IsNotExist(err) {
|
if _, err := os.Stat(keyspath + ".i2p.private"); os.IsNotExist(err) {
|
||||||
f, err := os.Create(keyspath + ".i2p.private")
|
f, err := os.Create(keyspath + ".i2p.private")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to open I2P keyfile for writing: %s", err)
|
return nil, fmt.Errorf("unable to open I2P keyfile for writing: %s", err)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
tkeys, err := sam.NewKeys()
|
tkeys, err := sam.NewKeys()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to generate I2P Keys, %s", err)
|
return nil, fmt.Errorf("unable to generate I2P Keys, %s", err)
|
||||||
}
|
}
|
||||||
keys = &tkeys
|
keys = &tkeys
|
||||||
err = i2pkeys.StoreKeysIncompat(*keys, f)
|
err = i2pkeys.StoreKeysIncompat(*keys, f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to save newly generated I2P Keys, %s", err)
|
return nil, fmt.Errorf("unable to save newly generated I2P Keys, %s", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tkeys, err := i2pkeys.LoadKeys(keyspath + ".i2p.private")
|
tkeys, err := i2pkeys.LoadKeys(keyspath + ".i2p.private")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to load I2P Keys: %e", err)
|
return nil, fmt.Errorf("unable to load I2P Keys: %e", err)
|
||||||
}
|
}
|
||||||
keys = &tkeys
|
keys = &tkeys
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
tkeys, err := sam.NewKeys()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to generate I2P Keys, %s", err)
|
||||||
|
}
|
||||||
|
keys = &tkeys
|
||||||
}
|
}
|
||||||
gram, err := sam.NewPrimarySession(name, *keys, sam3.Options_Medium)
|
gram, err := sam.NewPrimarySession(name, *keys, sam3.Options_Medium)
|
||||||
return gram, err
|
return gram, err
|
||||||
|
@@ -21,6 +21,8 @@ var (
|
|||||||
i2pB32enc *base32.Encoding = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567")
|
i2pB32enc *base32.Encoding = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var FakePort = false
|
||||||
|
|
||||||
// The public and private keys associated with an I2P destination. I2P hides the
|
// 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
|
// 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
|
// pair of DSA keys, one pair of ElGamal keys, and sometimes (almost never) also
|
||||||
@@ -279,7 +281,14 @@ func (addr I2PAddr) Bytes() []byte {
|
|||||||
// performing a Lookup(). Lookup only works if you are using the I2PAddr from
|
// performing a Lookup(). Lookup only works if you are using the I2PAddr from
|
||||||
// which the b32 address was generated.
|
// which the b32 address was generated.
|
||||||
func (addr I2PAddr) Base32() (str string) {
|
func (addr I2PAddr) Base32() (str string) {
|
||||||
return addr.DestHash().String()
|
return addr.DestHash().String() + addr.Port()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (addr I2PAddr) Port() (str string) {
|
||||||
|
if FakePort {
|
||||||
|
return ":8080"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (addr I2PAddr) DestHash() (h I2PDestHash) {
|
func (addr I2PAddr) DestHash() (h I2PDestHash) {
|
||||||
|
71
primary.go
71
primary.go
@@ -33,8 +33,8 @@ type PrimarySession struct {
|
|||||||
Deadline time.Time
|
Deadline time.Time
|
||||||
sigType string
|
sigType string
|
||||||
Config SAMEmit
|
Config SAMEmit
|
||||||
stsess map[string]*StreamSession
|
stsess *StreamSession
|
||||||
dgsess map[string]*DatagramSession
|
dgsess *DatagramSession
|
||||||
// from string
|
// from string
|
||||||
// to string
|
// to string
|
||||||
}
|
}
|
||||||
@@ -62,10 +62,12 @@ func (ss *PrimarySession) Close() error {
|
|||||||
|
|
||||||
// Returns the I2P destination (the address) of the stream session
|
// Returns the I2P destination (the address) of the stream session
|
||||||
func (ss *PrimarySession) Addr() i2pkeys.I2PAddr {
|
func (ss *PrimarySession) Addr() i2pkeys.I2PAddr {
|
||||||
|
// fmt.Println("LOCAL ADDR")
|
||||||
return ss.keys.Addr()
|
return ss.keys.Addr()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *PrimarySession) LocalAddr() net.Addr {
|
func (ss *PrimarySession) LocalAddr() net.Addr {
|
||||||
|
// fmt.Println("LOCAL ADDR")
|
||||||
aa := ss.keys.Addr()
|
aa := ss.keys.Addr()
|
||||||
return &aa
|
return &aa
|
||||||
}
|
}
|
||||||
@@ -87,58 +89,58 @@ func (sam *PrimarySession) Dial(network, addr string) (net.Conn, error) {
|
|||||||
|
|
||||||
// DialTCP implements x/dialer
|
// DialTCP implements x/dialer
|
||||||
func (sam *PrimarySession) DialTCP(network string, laddr, raddr net.Addr) (net.Conn, error) {
|
func (sam *PrimarySession) DialTCP(network string, laddr, raddr net.Addr) (net.Conn, error) {
|
||||||
_, ok := sam.stsess[network+raddr.String()[0:4]]
|
var err error
|
||||||
if !ok {
|
if sam.stsess == nil {
|
||||||
stsess, err := sam.NewUniqueStreamSubSession(network + raddr.String()[0:4])
|
sam.stsess, err = sam.NewUniqueStreamSubSession(network + RandString())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sam.stsess[network+raddr.String()[0:4]] = stsess
|
|
||||||
}
|
}
|
||||||
return sam.stsess[network+raddr.String()[0:4]].Dial(network, raddr.String())
|
return sam.stsess.Dial(network, raddr.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sam *PrimarySession) DialTCPI2P(network string, laddr, raddr string) (net.Conn, error) {
|
func (sam *PrimarySession) DialTCPI2P(network string, laddr, raddr string) (*SAMConn, error) {
|
||||||
_, ok := sam.stsess[network+raddr[0:4]]
|
var err error
|
||||||
if !ok {
|
if sam.stsess == nil {
|
||||||
stsess, err := sam.NewUniqueStreamSubSession(network + laddr)
|
sam.stsess, err = sam.NewUniqueStreamSubSession(network + RandString())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sam.stsess[network+raddr[0:4]] = stsess
|
|
||||||
}
|
}
|
||||||
return sam.stsess[network+raddr[0:4]].Dial(network, raddr)
|
c, err := sam.stsess.Dial(network, raddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c.(*SAMConn), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialUDP implements x/dialer
|
// DialUDP implements x/dialer
|
||||||
func (sam *PrimarySession) DialUDP(network string, laddr, raddr net.Addr) (net.PacketConn, error) {
|
func (sam *PrimarySession) DialUDP(network string, laddr, raddr net.Addr) (net.PacketConn, error) {
|
||||||
_, ok := sam.dgsess[network+raddr.String()[0:4]]
|
var err error
|
||||||
if !ok {
|
if sam.dgsess == nil {
|
||||||
dgsess, err := sam.NewDatagramSubSession(network+raddr.String()[0:4], 0)
|
sam.dgsess, err = sam.NewDatagramSubSession(network+raddr.String()[0:4], 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sam.dgsess[network+raddr.String()[0:4]] = dgsess
|
|
||||||
}
|
}
|
||||||
return sam.dgsess[network+raddr.String()[0:4]].Dial(network, raddr.String())
|
return sam.dgsess.Dial(network, raddr.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sam *PrimarySession) DialUDPI2P(network, laddr, raddr string) (*DatagramSession, error) {
|
func (sam *PrimarySession) DialUDPI2P(network, laddr, raddr string) (*DatagramSession, error) {
|
||||||
_, ok := sam.dgsess[network+raddr[0:4]]
|
var err error
|
||||||
if !ok {
|
if sam.dgsess == nil {
|
||||||
dgsess, err := sam.NewDatagramSubSession(network+laddr, 0)
|
sam.dgsess, err = sam.NewDatagramSubSession(network+raddr[0:4], 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sam.dgsess[network+raddr[0:4]] = dgsess
|
|
||||||
}
|
}
|
||||||
return sam.dgsess[network+raddr[0:4]].Dial(network, raddr)
|
return sam.dgsess.Dial(network, raddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PrimarySession) Lookup(name string) (a net.Addr, err error) {
|
func (s *PrimarySession) Lookup(name string) (a net.Addr, err error) {
|
||||||
var sam *SAM
|
var sam *SAM
|
||||||
if len(strings.Split(name, ":")) <= 1 {
|
if len(strings.Split(name, ":")) <= 1 {
|
||||||
name += ":0"
|
name += ":80"
|
||||||
}
|
}
|
||||||
sam, err = NewSAM(s.samAddr)
|
sam, err = NewSAM(s.samAddr)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -149,14 +151,17 @@ func (s *PrimarySession) Lookup(name string) (a net.Addr, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sam *PrimarySession) Resolve(network, addr string) (net.Addr, error) {
|
func (sam *PrimarySession) Resolve(network, addr string) (net.Addr, error) {
|
||||||
|
fmt.Println("LOGGING RESOLUTION", network, addr)
|
||||||
return sam.Lookup(addr)
|
return sam.Lookup(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sam *PrimarySession) ResolveTCPAddr(network, dest string) (net.Addr, error) {
|
func (sam *PrimarySession) ResolveTCPAddr(network, dest string) (net.Addr, error) {
|
||||||
|
fmt.Println("LOGGING RESOLUTION", network, dest)
|
||||||
return sam.Lookup(dest)
|
return sam.Lookup(dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sam *PrimarySession) ResolveUDPAddr(network, dest string) (net.Addr, error) {
|
func (sam *PrimarySession) ResolveUDPAddr(network, dest string) (net.Addr, error) {
|
||||||
|
fmt.Println("LOGGING RESOLUTION", network, dest)
|
||||||
return sam.Lookup(dest)
|
return sam.Lookup(dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,9 +172,7 @@ func (sam *SAM) NewPrimarySession(id string, keys i2pkeys.I2PKeys, options []str
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ssesss := make(map[string]*StreamSession)
|
return &PrimarySession{sam.Config.I2PConfig.Sam(), id, conn, keys, time.Duration(600 * time.Second), time.Now(), Sig_NONE, sam.Config, nil, nil}, nil
|
||||||
dsesss := make(map[string]*DatagramSession)
|
|
||||||
return &PrimarySession{sam.Config.I2PConfig.Sam(), id, conn, keys, time.Duration(600 * time.Second), time.Now(), Sig_NONE, sam.Config, ssesss, dsesss}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new PrimarySession with the I2CP- and PRIMARYinglib options as
|
// Creates a new PrimarySession with the I2CP- and PRIMARYinglib options as
|
||||||
@@ -179,9 +182,7 @@ func (sam *SAM) NewPrimarySessionWithSignature(id string, keys i2pkeys.I2PKeys,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ssesss := make(map[string]*StreamSession)
|
return &PrimarySession{sam.Config.I2PConfig.Sam(), id, conn, keys, time.Duration(600 * time.Second), time.Now(), sigType, sam.Config, nil, nil}, nil
|
||||||
dsesss := make(map[string]*DatagramSession)
|
|
||||||
return &PrimarySession{sam.Config.I2PConfig.Sam(), id, conn, keys, time.Duration(600 * time.Second), time.Now(), sigType, sam.Config, ssesss, dsesss}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new session with the style of either "STREAM", "DATAGRAM" or "RAW",
|
// Creates a new session with the style of either "STREAM", "DATAGRAM" or "RAW",
|
||||||
@@ -260,21 +261,23 @@ func (sam *PrimarySession) newGenericSubSessionWithSignatureAndPorts(style, id,
|
|||||||
// Creates a new StreamSession with the I2CP- and streaminglib options as
|
// Creates a new StreamSession with the I2CP- and streaminglib options as
|
||||||
// specified. See the I2P documentation for a full list of options.
|
// specified. See the I2P documentation for a full list of options.
|
||||||
func (sam *PrimarySession) NewStreamSubSession(id string) (*StreamSession, error) {
|
func (sam *PrimarySession) NewStreamSubSession(id string) (*StreamSession, error) {
|
||||||
conn, err := sam.newGenericSubSession("STREAM", id, []string{})
|
s := RandString()
|
||||||
|
conn, err := sam.newGenericSubSession("STREAM", id+s, []string{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &StreamSession{sam.Config.I2PConfig.Sam(), id, conn, sam.keys, time.Duration(600 * time.Second), time.Now(), Sig_NONE, "0", "0"}, nil
|
return &StreamSession{sam.Config.I2PConfig.Sam(), id + s, 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
|
// Creates a new StreamSession with the I2CP- and streaminglib options as
|
||||||
// specified. See the I2P documentation for a full list of options.
|
// specified. See the I2P documentation for a full list of options.
|
||||||
func (sam *PrimarySession) NewUniqueStreamSubSession(id string) (*StreamSession, error) {
|
func (sam *PrimarySession) NewUniqueStreamSubSession(id string) (*StreamSession, error) {
|
||||||
conn, err := sam.newGenericSubSession("STREAM", id, []string{})
|
s := RandString()
|
||||||
|
conn, err := sam.newGenericSubSession("STREAM", id+s, []string{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &StreamSession{sam.Config.I2PConfig.Sam(), id, conn, sam.keys, time.Duration(600 * time.Second), time.Now(), Sig_NONE, randport(), "0"}, nil
|
return &StreamSession{sam.Config.I2PConfig.Sam(), id + s, conn, sam.keys, time.Duration(600 * time.Second), time.Now(), Sig_NONE, randport(), "0"}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new StreamSession with the I2CP- and streaminglib options as
|
// Creates a new StreamSession with the I2CP- and streaminglib options as
|
||||||
|
Reference in New Issue
Block a user