From 7d10e58d08a39339c0b4e11e079768ce56bbdf88 Mon Sep 17 00:00:00 2001 From: MrMelon54 Date: Tue, 18 Apr 2023 01:45:42 +0100 Subject: [PATCH] Finish adding testing to tcp/udp forwarding --- go.mod | 4 +- go.sum | 7 ++- tcp/manager.go | 3 ++ tcp/manager_test.go | 43 ++++++++++++++++++ tcp/proxy_test.go | 12 +++-- udp/manager.go | 3 ++ udp/manager_test.go | 106 ++++++++++++++++++++++++++++++++++++++++++++ udp/proxy.go | 2 +- udp/proxy_test.go | 4 +- 9 files changed, 172 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 9176aa6..5cba35e 100644 --- a/go.mod +++ b/go.mod @@ -7,11 +7,11 @@ require ( github.com/gorilla/mux v1.8.0 github.com/mrmelon54/mjwt v0.0.1 github.com/stretchr/testify v1.8.2 + golang.org/x/net v0.9.0 xorm.io/xorm v1.3.2 ) require ( - code.mrmelon54.com/melon/summer v0.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-sql-driver/mysql v1.7.0 // indirect github.com/goccy/go-json v0.8.1 // indirect @@ -25,6 +25,8 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/syndtr/goleveldb v1.0.0 // indirect golang.org/x/crypto v0.8.0 // indirect + golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57 // indirect + golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 // indirect ) diff --git a/go.sum b/go.sum index 9717cba..75f6038 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,5 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -code.mrmelon54.com/melon/summer v0.0.2 h1:8VGzgS5BKULvbONwtLE3k2EiYJzMtyBqEHwUz9EaLec= -code.mrmelon54.com/melon/summer v0.0.2/go.mod h1:8RztDnjYO+04/+o6pWnyv74sGH8ZkaVMrF6wAt6H9D0= -code.mrmelon54.com/melon/summer-utils v0.0.1 h1:nuM7Bshl244F3HbzBH9KDRJ2GSV86+TyQZroof4bv1A= -code.mrmelon54.com/melon/summer-utils v0.0.1/go.mod h1:rDuABxgoMOhz3KgNqoCvVXIGixf7Xq76E/36Q1f5hCI= code.mrmelon54.com/melon/summer-utils v0.0.3 h1:Bz4o5BBOqWCNGpKkxUum4rwMn/DIdyMCKGQ/D6SXD6Q= code.mrmelon54.com/melon/summer-utils v0.0.3/go.mod h1:Gh/baXSzkf1ZhHonpPP8oQkyhhmFZcC2yTMlrwclDUw= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= @@ -407,6 +403,7 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57 h1:LQmS1nU0twXLA96Kt7U9qtHJEbBk3z6Q0V4UXjZkpr4= +golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -426,6 +423,7 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -491,6 +489,7 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023 h1:0c3L82FDQ5rt1bjTBlchS8t6RQ6299/+5bWMnRLh+uI= +golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/tcp/manager.go b/tcp/manager.go index 7492be4..3dde8d0 100644 --- a/tcp/manager.go +++ b/tcp/manager.go @@ -29,6 +29,9 @@ func NewTcpManager(db *xorm.Engine) *Manager { func (m *Manager) Compile() { m.empty() + if m.db == nil { + return + } var a []web.TcpRedirect err := m.db.Where("enabled = ?", true).Find(&a) if err != nil { diff --git a/tcp/manager_test.go b/tcp/manager_test.go index 4ae52b7..f004c91 100644 --- a/tcp/manager_test.go +++ b/tcp/manager_test.go @@ -1 +1,44 @@ package tcp + +import ( + "code.mrmelon54.com/melon/summer-utils/tables/web" + "code.mrmelon54.com/melon/summer-utils/utils" + "github.com/stretchr/testify/assert" + "net" + "testing" +) + +func TestNewTcpManager(t *testing.T) { + m := NewTcpManager(nil) + m.Add(web.TcpRedirect{Id: 1, Port: 1238, Target: "127.0.0.1:1234", Enabled: utils.PBool(true)}) + m.Add(web.TcpRedirect{Id: 2, Port: 1239, Target: "127.0.0.1:1234", Enabled: utils.PBool(true)}) + + dial, err := net.Dial("tcp", "127.0.0.1:1238") + assert.NoError(t, err) + //goland:noinspection GoUnhandledErrorResult + defer dial.Close() + + dial, err = net.Dial("tcp", "127.0.0.1:1239") + assert.NoError(t, err) + //goland:noinspection GoUnhandledErrorResult + defer dial.Close() + + // port 1237 closes + m.Close(2) + + dial, err = net.Dial("tcp", "127.0.0.1:1238") + assert.NoError(t, err) + //goland:noinspection GoUnhandledErrorResult + defer dial.Close() + + _, err = net.Dial("tcp", "127.0.0.1:1239") + assert.Error(t, err) + + // all ports close + m.Destroy() + + _, err = net.Dial("tcp", "127.0.0.1:1238") + assert.Error(t, err) + _, err = net.Dial("tcp", "127.0.0.1:1239") + assert.Error(t, err) +} diff --git a/tcp/proxy_test.go b/tcp/proxy_test.go index 5dc6247..19a664a 100644 --- a/tcp/proxy_test.go +++ b/tcp/proxy_test.go @@ -5,6 +5,7 @@ import ( "github.com/stretchr/testify/assert" "net" "testing" + "time" ) func TestNewTcpProxy(t *testing.T) { @@ -20,11 +21,11 @@ func TestNewTcpProxy(t *testing.T) { defer listenTCP.Close() go func() { - tcp, err := listenTCP.AcceptTCP() + accept, err := listenTCP.AcceptTCP() assert.NoError(t, err) b := make([]byte, 2) - n, err := tcp.Read(b) + n, err := accept.Read(b) assert.NoError(t, err) assert.Equal(t, 2, n) @@ -46,8 +47,11 @@ func TestNewTcpProxy(t *testing.T) { proxy.Quit() assert.False(t, proxy.done.Running()) + time.Sleep(2 * time.Second) + // Open connections prevent the proxy from quitting - n, err := tcp.Write([]byte{0x32, 0x32}) + _, err = tcp.Write([]byte{0x32, 0x32}) + assert.NoError(t, err) + _, err = tcp.Read(nil) assert.NoError(t, err) - assert.Equal(t, 2, n) } diff --git a/udp/manager.go b/udp/manager.go index ac33552..218cf85 100644 --- a/udp/manager.go +++ b/udp/manager.go @@ -29,6 +29,9 @@ func NewUdpManager(db *xorm.Engine) *Manager { func (m *Manager) Compile() { m.empty() + if m.db == nil { + return + } var a []web.UdpRedirect err := m.db.Where("enabled = ?", true).Find(&a) if err != nil { diff --git a/udp/manager_test.go b/udp/manager_test.go index 0213f41..12ad099 100644 --- a/udp/manager_test.go +++ b/udp/manager_test.go @@ -1 +1,107 @@ package udp + +import ( + "bytes" + "code.mrmelon54.com/melon/summer-utils/tables/web" + "code.mrmelon54.com/melon/summer-utils/utils" + "github.com/stretchr/testify/assert" + "net" + "testing" +) + +func TestNewUdpManager(t *testing.T) { + m := NewUdpManager(nil) + m.Add(web.UdpRedirect{Id: 1, Port: 1240, Target: "127.0.0.1:1234", Enabled: utils.PBool(true)}) + m.Add(web.UdpRedirect{Id: 2, Port: 1241, Target: "127.0.0.1:1234", Enabled: utils.PBool(true)}) + + packet, err := net.ListenPacket("udp", "127.0.0.1:1234") + assert.NoError(t, err) + + done := utils.NewDoneChan() + + go func() { + for { + select { + case <-done.C: + return + default: + b := make([]byte, 2) + n, a, err := packet.ReadFrom(b) + assert.NoError(t, err) + assert.Equal(t, 2, n) + n, err = packet.WriteTo([]byte{b[0] + 1, b[1] + 1}, a) + assert.NoError(t, err) + assert.Equal(t, 2, n) + } + } + }() + + dial, err := net.Dial("udp", "127.0.0.1:1240") + assert.NoError(t, err) + //goland:noinspection GoUnhandledErrorResult + defer dial.Close() + + dial2, err := net.Dial("udp", "127.0.0.1:1241") + assert.NoError(t, err) + //goland:noinspection GoUnhandledErrorResult + defer dial2.Close() + + n, err := dial.Write([]byte{0x01, 0x15}) + assert.NoError(t, err) + assert.Equal(t, 2, n) + b := make([]byte, 2) + n, err = dial.Read(b) + assert.NoError(t, err) + assert.Equal(t, 2, n) + assert.Equal(t, 0, bytes.Compare(b, []byte{0x02, 0x16})) + + n, err = dial2.Write([]byte{0x03, 0x17}) + assert.NoError(t, err) + assert.Equal(t, 2, n) + b = make([]byte, 2) + n, err = dial2.Read(b) + assert.NoError(t, err) + assert.Equal(t, 2, n) + assert.Equal(t, 0, bytes.Compare(b, []byte{0x04, 0x18})) + + // port 1237 closes + m.Close(2) + + n, err = dial.Write([]byte{0x05, 0x19}) + assert.NoError(t, err) + assert.Equal(t, 2, n) + b = make([]byte, 2) + n, err = dial.Read(b) + assert.NoError(t, err) + assert.Equal(t, 2, n) + assert.Equal(t, 0, bytes.Compare(b, []byte{0x06, 0x1a})) + + n, err = dial2.Write([]byte{0x07, 0x1b}) + assert.NoError(t, err) + assert.Equal(t, 2, n) + b = make([]byte, 2) + n, err = dial2.Read(b) + assert.Error(t, err) + assert.Equal(t, 0, n) + + // all ports close + m.Destroy() + + n, err = dial2.Write([]byte{0x09, 0x1d}) + assert.NoError(t, err) + assert.Equal(t, 2, n) + b = make([]byte, 2) + n, err = dial2.Read(b) + assert.Error(t, err) + assert.Equal(t, 0, n) + + n, err = dial2.Write([]byte{0x11, 0x25}) + assert.NoError(t, err) + assert.Equal(t, 2, n) + b = make([]byte, 2) + n, err = dial2.Read(b) + assert.Error(t, err) + assert.Equal(t, 0, n) + + done.Close() +} diff --git a/udp/proxy.go b/udp/proxy.go index df96c5a..48da78e 100644 --- a/udp/proxy.go +++ b/udp/proxy.go @@ -52,7 +52,7 @@ outer: i, addr, err := p.l.ReadFromUDP(buf) if err != nil { log.Printf("[WARN %s @ %s] Read failed '%s'\n", addr, p.lAddr, err) - continue outer + break outer } data := buf[:i] diff --git a/udp/proxy_test.go b/udp/proxy_test.go index fbec35c..97236f5 100644 --- a/udp/proxy_test.go +++ b/udp/proxy_test.go @@ -8,10 +8,10 @@ import ( ) func TestNewUdpProxy(t *testing.T) { - addr, err := net.ResolveUDPAddr("udp", "127.0.0.1:1234") + addr, err := net.ResolveUDPAddr("udp", "127.0.0.1:1236") assert.NoError(t, err) - addr2, err := net.ResolveUDPAddr("udp", "127.0.0.1:1235") + addr2, err := net.ResolveUDPAddr("udp", "127.0.0.1:1237") assert.NoError(t, err) listenUDP, err := net.ListenUDP("udp", addr2)