udp service stability improvements, prep for kcp-over-i2p tunnels and easy VPN tunnels

This commit is contained in:
idk
2019-06-12 09:16:13 -04:00
parent 3c99520aa7
commit 0cd844cbd8
9 changed files with 162 additions and 109 deletions

View File

@ -40,25 +40,31 @@ test: test-keys test-ntcp test-ssu test-config test-manager
long-test: test-serve test
full-test: test-serve test
full-test: test test-serve
test-serve:
cd serve_test && go test
cd serve_test && go test -v -tags netgo \
-ldflags '-w -extldflags "-static"'
test-ntcp:
go test
cd tcp && go test -v -tags netgo \
-ldflags '-w -extldflags "-static"'
test-ssu:
cd udp && go test
cd udp && go test -v -tags netgo \
-ldflags '-w -extldflags "-static"'
test-config:
cd config && go test
cd config && go test -v -tags netgo \
-ldflags '-w -extldflags "-static"'
test-manager:
cd manager && go test
cd manager && go test -v -tags netgo \
-ldflags '-w -extldflags "-static"'
test-keys:
cd i2pkeys && go test
cd i2pkeys && go test -v -tags netgo \
-ldflags '-w -extldflags "-static"'
refresh:

View File

@ -86,14 +86,6 @@ relevant i2cp and tunnel options, which I'm keeping track of
I need to just change how the configuration is done entirely. I want it to work
with the configuration formats used by each I2P router.
Example tools built using this are being broken off into their own repos. Use
the other repos where appropriate, so I can leave the examples un-messed with.
It would be really awesome if I could make this run on Android. So I'll make
that happen eventually. I started a daemon for managing multiple tunnels and I
figure I give it a web interface to configure stuff with. I'll probably put that
in a different repo though. This is looking a little cluttered.
TLS configuration is experimental.
## Stuff that's using it:

View File

@ -26,6 +26,25 @@ func (c *Conf) GetType(argc, argu, argh bool, def string, label ...string) strin
typ += "server"
}
}
if def == "kcpclient" {
typ = "kcpclient"
}
if def == "kcpserver" {
typ = "kcpserver"
}
if typ != def {
return typ
}
if c.Config == nil {
return typ
}
if x, o := c.Get("type", label...); o {
return x
}
return def
}
func (c *Conf) GetOtherType(typ, def string, label ...string) string {
if typ != def {
return typ
}
@ -44,7 +63,7 @@ func (c *Conf) SetType(label ...string) {
if strings.Contains(v, "client") {
c.Client = true
}
if c.Type == "server" || c.Type == "http" || c.Type == "client" || c.Type == "httpclient" || c.Type == "udpserver" || c.Type == "udpclient" {
if c.Type == "server" || c.Type == "http" || c.Type == "client" || c.Type == "httpclient" || c.Type == "udpserver" || c.Type == "udpclient" || c.Type == "kcpclient" || c.Type == "kcpserver" {
c.Type = v
}
} else {

View File

@ -2,4 +2,25 @@ Implementing the sam-forwarder interface
========================================
The sam-forwrder interface(used int the Go sense of the word interface) is used
to create custom types of tunnels.
to create custom types of tunnels. It's kind of big, and maybe too complex, so
subject to change.
``` go
type SAMTunnel interface {
GetType() string
Cleanup()
Print() string
Props() map[string]string
Search(search string) string
Target() string
ID() string
//Destination() string
Base32() string
Base64() string
Keys() i2pkeys.I2PKeys
Serve() error
Close() error
Up() bool
Load() (SAMTunnel, error)
}
```

View File

@ -18,9 +18,9 @@ import (
var (
port = "8100"
cport = "8101"
uport = "8102"
ucport = "8103"
ssuport = "8104"
UDPServerPort = "8102"
UDPClientPort = "8103"
SSUServerPort = "8104"
udpserveraddr *net.UDPAddr
udplocaladdr *net.UDPAddr
ssulocaladdr *net.UDPAddr
@ -75,12 +75,12 @@ func client() {
}
func echo() {
/* Lets prepare a address at any address at port 10001*/
udpserveraddr, err = net.ResolveUDPAddr("udp", "127.0.0.1:"+uport)
/* Lets prepare a address at any address at port UDPServerPort */
udpserveraddr, err = net.ResolveUDPAddr("udp", "127.0.0.1:"+UDPServerPort)
if err != nil {
log.Fatal(err)
}
fmt.Println("listening on :", uport)
fmt.Println("starting UDP echo server listening on :", UDPServerPort)
/* Now listen at selected port */
udpserverconn, err = net.ListenUDP("udp", udpserveraddr)
@ -102,12 +102,18 @@ func echo() {
}
}
func serveudp() {
flag.Parse()
func echoclient() {
udpclientaddr, e := net.Dial("udp", "127.0.0.1:"+UDPServerPort)
if e != nil {
log.Fatal(e)
}
udpclientaddr.Write([]byte("test"))
}
func serveudp() {
ssuforwarder, err = samforwarderudp.NewSAMSSUForwarderFromOptions(
samforwarderudp.SetHost("127.0.0.1"),
samforwarderudp.SetPort(uport),
samforwarderudp.SetPort(UDPServerPort),
samforwarderudp.SetSAMHost("127.0.0.1"),
samforwarderudp.SetSAMPort("7656"),
samforwarderudp.SetName("testudpserver"),
@ -115,16 +121,18 @@ func serveudp() {
if err != nil {
log.Fatal(err.Error())
}
go ssuforwarder.Serve()
log.Printf("Serving on UDP port: %s and on %s\n", uport, ssuforwarder.Base32())
f, e := ssuforwarder.Load()
if e != nil {
log.Fatal(e.Error())
}
go f.Serve()
log.Printf("Serving on UDP port: %s and on %s\n", UDPServerPort, ssuforwarder.Base32())
}
func clientudp() {
flag.Parse()
ssuforwarderclient, err = samforwarderudp.NewSAMSSUClientForwarderFromOptions(
samforwarderudp.SetClientHost("127.0.0.1"),
samforwarderudp.SetClientPort(ssuport),
samforwarderudp.SetClientPort(UDPClientPort),
samforwarderudp.SetClientSAMHost("127.0.0.1"),
samforwarderudp.SetClientSAMPort("7656"),
samforwarderudp.SetClientName("testudpclient"),
@ -133,17 +141,22 @@ func clientudp() {
if err != nil {
log.Fatal(err.Error())
}
go ssuforwarderclient.Serve()
log.Printf("Connecting UDP port: %s to %s\n", ssuport, ssuforwarder.Base32())
f, e := ssuforwarderclient.Load()
if e != nil {
log.Fatal(e.Error())
}
go f.Serve()
log.Printf("Connecting UDP port: %s to %s\n", SSUServerPort, ssuforwarder.Base32())
}
func setupudp() {
ssulocaladdr, err = net.ResolveUDPAddr("udp", "127.0.0.1:"+ssuport)
ssulocaladdr, err = net.ResolveUDPAddr("udp", "127.0.0.1:"+SSUServerPort)
if err != nil {
log.Fatal(err)
}
udplocaladdr, err = net.ResolveUDPAddr("udp", "127.0.0.1:"+ucport)
udplocaladdr, err = net.ResolveUDPAddr("udp", "127.0.0.1:"+UDPClientPort)
if err != nil {
log.Fatal(err)
}

View File

@ -8,21 +8,21 @@ import (
"time"
)
var longcount = 60
func countdown(i int) {
for i > 0 {
time.Sleep(1 * time.Second)
i--
log.Println("waiting", i, "more seconds.")
if i%10 == 0 {
log.Println("Waiting", i, "more seconds.")
}
}
}
func TestTCP(t *testing.T) {
go serve()
countdown(longcount)
countdown(61)
go client()
countdown(longcount)
countdown(61)
resp, err := http.Get("http://127.0.0.1:" + cport + "/test.html")
log.Println("requesting http://127.0.0.1:" + cport + "/test.html")
if err != nil {
@ -33,37 +33,23 @@ func TestTCP(t *testing.T) {
func TestUDP(t *testing.T) {
go echo()
countdown(3)
countdown(11)
echoclient()
countdown(11)
go serveudp()
countdown(longcount)
countdown(61)
go clientudp()
countdown(longcount)
countdown(61)
setupudp()
conn, err := net.DialUDP("udp", udplocaladdr, ssulocaladdr)
if err != nil {
t.Fatal(err)
}
message := []byte("Hello SSU")
message := []byte("Hello UDP")
_, err = conn.Write(message)
if err != nil {
t.Fatal("SSU error", err)
t.Fatal("UDP error", err)
}
log.Println(string(message))
}
/*
func TestUDPeasy(t *testing.T) {
go echo()
time.Sleep(time.Duration(1 * time.Second))
conn, err := net.DialUDP("udp", udplocaladdr, udpserveraddr)
//defer conn.Close()
if err != nil {
t.Fatal(err)
}
_, err = conn.Write([]byte("Hello SSU"))
if err != nil {
t.Fatal("SSU error", err)
}
}
*/

View File

@ -224,18 +224,9 @@ func (f *SAMSSUClientForwarder) Base64() string {
}
func (f *SAMSSUClientForwarder) forward(conn net.PacketConn) {
var err error
//p, _ := strconv.Atoi(f.TargetPort)
sp, _ := strconv.Atoi(f.SamPort)
if f.connectStream, err = f.samConn.NewDatagramSession(f.TunName, f.SamKeys,
f.print(), sp); err != nil {
log.Fatal("Stream Creation error:", err.Error())
}
log.Println("SAM stream session established.")
log.Printf("Connected to localhost %v\n", f.publishConnection)
go func() {
defer f.connectStream.Close()
defer f.publishConnection.Close()
// defer f.connectStream.Close()
// defer f.publishConnection.Close()
buffer := make([]byte, 1024)
if size, _, readerr := f.publishConnection.ReadFrom(buffer); readerr == nil {
if size2, writeerr := f.connectStream.WriteTo(buffer, f.addr); writeerr == nil {
@ -245,8 +236,8 @@ func (f *SAMSSUClientForwarder) forward(conn net.PacketConn) {
}
}()
go func() {
defer f.connectStream.Close()
defer f.publishConnection.Close()
// defer f.connectStream.Close()
// defer f.publishConnection.Close()
buffer := make([]byte, 1024)
if size, _, readerr := f.connectStream.ReadFrom(buffer); readerr == nil {
if size2, writeerr := f.publishConnection.WriteTo(buffer, f.addr); writeerr == nil {
@ -261,28 +252,44 @@ func (f *SAMSSUClientForwarder) Up() bool {
return f.up
}
func (f *SAMSSUClientForwarder) errSleep(err error) bool {
if err != nil {
log.Printf("Dial failed: %v, waiting 5 minutes to try again\n", err)
time.Sleep(5 * time.Minute)
return false
} else {
return true
}
}
//Serve starts the SAM connection and and forwards the local host:port to i2p
func (f *SAMSSUClientForwarder) Serve() error {
if f.addr, err = f.samConn.Lookup(f.dest); err != nil {
return err
}
var err error
//p, _ := strconv.Atoi(f.TargetPort)
sp, _ := strconv.Atoi(f.SamPort)
f.connectStream, err = f.samConn.NewDatagramSession(
f.TunName,
f.SamKeys,
f.print(),
sp-1,
)
if err != nil {
log.Fatal("Stream Creation error:", err.Error())
}
log.Println("SAM datagram session established.")
log.Printf("Connected to localhost %v\n", f.publishConnection)
Close := false
for !Close {
p, _ := strconv.Atoi(f.TargetPort)
f.publishConnection, err = net.DialUDP("udp", &net.UDPAddr{
Port: p,
IP: net.ParseIP(f.TargetHost),
}, nil)
if err != nil {
//return err
log.Printf("Dial failed: %v, waiting 5 minutes to try again\n", err)
time.Sleep(5 * time.Minute)
} else {
Close = true
}
log.Println("Forwarding client to i2p address:", f.addr.Base32())
//f.forward(f.publishConnection)
addr, err := net.ResolveUDPAddr("udp", f.Target())
Close = f.errSleep(err)
f.publishConnection, err = net.DialUDP("udp", nil, addr)
Close = f.errSleep(err)
log.Printf("Forwarding client to i2p address: %v\n", f.publishConnection)
}
for {
f.forward(f.publishConnection)
@ -291,7 +298,7 @@ func (f *SAMSSUClientForwarder) Serve() error {
}
func (s *SAMSSUClientForwarder) Load() (samtunnel.SAMTunnel, error) {
if s.publishConnection, err = net.ListenPacket("udp", s.TargetHost+":"+s.TargetPort); err != nil {
if s.publishConnection, err = net.ListenPacket("udp", s.Target()); err != nil {
return nil, err
}
if s.samConn, err = sam3.NewSAM(s.sam()); err != nil {

View File

@ -208,8 +208,8 @@ func (f *SAMSSUForwarder) sam() string {
//func (f *SAMSSUForwarder) forward(conn net.Conn) {
func (f *SAMSSUForwarder) forward() {
go func() {
defer f.clientConnection.Close()
defer f.publishConnection.Close()
// defer f.clientConnection.Close()
// defer f.publishConnection.Close()
buffer := make([]byte, 1024)
if size, addr, readerr := f.clientConnection.ReadFrom(buffer); readerr == nil {
if size2, writeerr := f.publishConnection.WriteTo(buffer, addr); writeerr == nil {
@ -219,8 +219,8 @@ func (f *SAMSSUForwarder) forward() {
}
}()
go func() {
defer f.clientConnection.Close()
defer f.publishConnection.Close()
// defer f.clientConnection.Close()
// defer f.publishConnection.Close()
buffer := make([]byte, 1024)
if size, addr, readerr := f.publishConnection.ReadFrom(buffer); readerr == nil {
if size2, writeerr := f.clientConnection.WriteTo(buffer, addr); writeerr == nil {
@ -241,12 +241,27 @@ func (f *SAMSSUForwarder) Base64() string {
return f.SamKeys.Addr().Base64()
}
func (f *SAMSSUForwarder) errSleep(err error) bool {
if err != nil {
log.Printf("Dial failed: %v, waiting 5 minutes to try again\n", err)
time.Sleep(5 * time.Minute)
return false
} else {
return true
}
}
//Serve starts the SAM connection and and forwards the local host:port to i2p
func (f *SAMSSUForwarder) Serve() error {
var err error
sp, _ := strconv.Atoi(f.SamPort)
f.publishConnection, err = f.samConn.NewDatagramSession(f.TunName, f.SamKeys, f.print(), sp)
f.publishConnection, err = f.samConn.NewDatagramSession(
f.TunName,
f.SamKeys,
f.print(),
sp-1,
)
if err != nil {
log.Println("Session Creation error:", err.Error())
return err
@ -256,20 +271,12 @@ func (f *SAMSSUForwarder) Serve() error {
b := string(f.SamKeys.Addr().Base32())
log.Println("SAM Keys loaded,", b)
p, _ := strconv.Atoi(f.TargetPort)
Close := false
for !Close {
f.clientConnection, err = net.DialUDP("udp", nil, &net.UDPAddr{
Port: p,
IP: net.ParseIP(f.TargetHost),
})
if err != nil {
log.Printf("Dial failed: %v, waiting 5 minutes to try again\n", err)
time.Sleep(5 * time.Minute)
} else {
Close = true
}
addr, err := net.ResolveUDPAddr("udp", f.Target())
Close = f.errSleep(err)
f.clientConnection, err = net.DialUDP("udp", nil, addr)
Close = f.errSleep(err)
log.Printf("Connected to localhost %v\n", f.publishConnection)
}
for {
@ -278,7 +285,8 @@ func (f *SAMSSUForwarder) Serve() error {
}
func (s *SAMSSUForwarder) Load() (samtunnel.SAMTunnel, error) {
if s.samConn, err = sam3.NewSAM(s.sam()); err != nil {
s.samConn, err = sam3.NewSAM(s.sam())
if err != nil {
return nil, err
}
log.Println("SAM Bridge connection established.")
@ -298,6 +306,7 @@ func (s *SAMSSUForwarder) Load() (samtunnel.SAMTunnel, error) {
s.up = true
return s, nil
}
func (f *SAMSSUForwarder) Up() bool {
return f.up
}