mirror of
https://github.com/cmz0228/hysteria-dev.git
synced 2025-06-08 21:39:53 +00:00
feat(wip): test reworks (need to add back traffic logger tests)
This commit is contained in:
parent
dd836b4496
commit
6172f2ac53
@ -109,12 +109,12 @@ func (c *clientImpl) connect() error {
|
|||||||
_ = conn.CloseWithError(closeErrCodeProtocolError, "")
|
_ = conn.CloseWithError(closeErrCodeProtocolError, "")
|
||||||
}
|
}
|
||||||
_ = pktConn.Close()
|
_ = pktConn.Close()
|
||||||
return &coreErrs.ConnectError{Err: err}
|
return coreErrs.ConnectError{Err: err}
|
||||||
}
|
}
|
||||||
if resp.StatusCode != protocol.StatusAuthOK {
|
if resp.StatusCode != protocol.StatusAuthOK {
|
||||||
_ = conn.CloseWithError(closeErrCodeProtocolError, "")
|
_ = conn.CloseWithError(closeErrCodeProtocolError, "")
|
||||||
_ = pktConn.Close()
|
_ = pktConn.Close()
|
||||||
return &coreErrs.AuthError{StatusCode: resp.StatusCode}
|
return coreErrs.AuthError{StatusCode: resp.StatusCode}
|
||||||
}
|
}
|
||||||
// Auth OK
|
// Auth OK
|
||||||
udpEnabled, serverRx := protocol.AuthResponseDataFromHeader(resp.Header)
|
udpEnabled, serverRx := protocol.AuthResponseDataFromHeader(resp.Header)
|
||||||
|
@ -92,8 +92,8 @@ func TestClientServerTCPClose(t *testing.T) {
|
|||||||
_ = conn.Close()
|
_ = conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestServerUDPIdleTimeout tests whether the server's UDP idle timeout works correctly.
|
// TestClientServerUDPIdleTimeout tests whether the server's UDP idle timeout works correctly.
|
||||||
func TestServerUDPIdleTimeout(t *testing.T) {
|
func TestClientServerUDPIdleTimeout(t *testing.T) {
|
||||||
// Create server
|
// Create server
|
||||||
udpConn, udpAddr, err := serverConn()
|
udpConn, udpAddr, err := serverConn()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
|
|
||||||
// TestServerMasquerade is a test to ensure that the server behaves as a normal
|
// TestServerMasquerade is a test to ensure that the server behaves as a normal
|
||||||
// HTTP/3 server when dealing with an unauthenticated client. This is mainly to
|
// HTTP/3 server when dealing with an unauthenticated client. This is mainly to
|
||||||
// confirm that the server does not expose itself to active probers.
|
// confirm that the server does not expose itself to active probing.
|
||||||
func TestServerMasquerade(t *testing.T) {
|
func TestServerMasquerade(t *testing.T) {
|
||||||
// Create server
|
// Create server
|
||||||
udpConn, udpAddr, err := serverConn()
|
udpConn, udpAddr, err := serverConn()
|
||||||
|
@ -1,43 +1,30 @@
|
|||||||
package integration_tests
|
package integration_tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
|
|
||||||
"github.com/apernet/hysteria/core/client"
|
"github.com/apernet/hysteria/core/client"
|
||||||
coreErrs "github.com/apernet/hysteria/core/errors"
|
coreErrs "github.com/apernet/hysteria/core/errors"
|
||||||
|
"github.com/apernet/hysteria/core/internal/integration_tests/mocks"
|
||||||
"github.com/apernet/hysteria/core/server"
|
"github.com/apernet/hysteria/core/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Smoke tests that act as a sanity check for client & server to ensure they can talk to each other correctly.
|
// Smoke tests that act as a sanity check for client & server to ensure they can talk to each other correctly.
|
||||||
|
|
||||||
// TestClientNoServer tests how the client handles a server that doesn't exist.
|
// TestClientNoServer tests how the client handles a server address it cannot connect to.
|
||||||
// The client should still be able to be created, but TCP & UDP requests should fail.
|
// NewClient should return a ConnectError.
|
||||||
func TestClientNoServer(t *testing.T) {
|
func TestClientNoServer(t *testing.T) {
|
||||||
// Create client
|
|
||||||
c, err := client.NewClient(&client.Config{
|
c, err := client.NewClient(&client.Config{
|
||||||
ServerAddr: &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 14514},
|
ServerAddr: &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 55666},
|
||||||
})
|
})
|
||||||
if err != nil {
|
assert.Nil(t, c)
|
||||||
t.Fatal("error creating client:", err)
|
_, ok := err.(coreErrs.ConnectError)
|
||||||
}
|
assert.True(t, ok)
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
var cErr *coreErrs.ConnectError
|
|
||||||
|
|
||||||
// Try TCP
|
|
||||||
_, err = c.TCP("google.com:443")
|
|
||||||
if !errors.As(err, &cErr) {
|
|
||||||
t.Fatal("expected connect error from TCP")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try UDP
|
|
||||||
_, err = c.UDP()
|
|
||||||
if !errors.As(err, &cErr) {
|
|
||||||
t.Fatal("expected connect error from DialUDP")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestClientServerBadAuth tests two things:
|
// TestClientServerBadAuth tests two things:
|
||||||
@ -45,79 +32,82 @@ func TestClientNoServer(t *testing.T) {
|
|||||||
// - How the client handles failed authentication.
|
// - How the client handles failed authentication.
|
||||||
func TestClientServerBadAuth(t *testing.T) {
|
func TestClientServerBadAuth(t *testing.T) {
|
||||||
// Create server
|
// Create server
|
||||||
udpAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 14514}
|
udpConn, udpAddr, err := serverConn()
|
||||||
udpConn, err := net.ListenUDP("udp", udpAddr)
|
assert.NoError(t, err)
|
||||||
if err != nil {
|
auth := mocks.NewMockAuthenticator(t)
|
||||||
t.Fatal("error creating server:", err)
|
auth.EXPECT().Authenticate(mock.Anything, "badpassword", uint64(0)).Return(false, "").Once()
|
||||||
}
|
|
||||||
s, err := server.NewServer(&server.Config{
|
s, err := server.NewServer(&server.Config{
|
||||||
TLSConfig: serverTLSConfig(),
|
TLSConfig: serverTLSConfig(),
|
||||||
Conn: udpConn,
|
Conn: udpConn,
|
||||||
Authenticator: &pwAuthenticator{
|
Authenticator: auth,
|
||||||
Password: "correct password",
|
|
||||||
ID: "nobody",
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error creating server:", err)
|
|
||||||
}
|
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
go s.Serve()
|
go s.Serve()
|
||||||
|
|
||||||
// Create client
|
// Create client
|
||||||
c, err := client.NewClient(&client.Config{
|
c, err := client.NewClient(&client.Config{
|
||||||
ServerAddr: udpAddr,
|
ServerAddr: udpAddr,
|
||||||
Auth: "wrong password",
|
Auth: "badpassword",
|
||||||
TLSConfig: client.TLSConfig{InsecureSkipVerify: true},
|
TLSConfig: client.TLSConfig{InsecureSkipVerify: true},
|
||||||
})
|
})
|
||||||
if err != nil {
|
assert.Nil(t, c)
|
||||||
t.Fatal("error creating client:", err)
|
_, ok := err.(coreErrs.AuthError)
|
||||||
|
assert.True(t, ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestClientServerUDPDisabled tests how the client handles a server that does not support UDP.
|
||||||
|
// UDP should return a DialError.
|
||||||
|
func TestClientServerUDPDisabled(t *testing.T) {
|
||||||
|
// Create server
|
||||||
|
udpConn, udpAddr, err := serverConn()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
auth := mocks.NewMockAuthenticator(t)
|
||||||
|
auth.EXPECT().Authenticate(mock.Anything, mock.Anything, mock.Anything).Return(true, "nobody")
|
||||||
|
s, err := server.NewServer(&server.Config{
|
||||||
|
TLSConfig: serverTLSConfig(),
|
||||||
|
Conn: udpConn,
|
||||||
|
DisableUDP: true,
|
||||||
|
Authenticator: auth,
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer s.Close()
|
||||||
|
go s.Serve()
|
||||||
|
|
||||||
|
// Create client
|
||||||
|
c, err := client.NewClient(&client.Config{
|
||||||
|
ServerAddr: udpAddr,
|
||||||
|
TLSConfig: client.TLSConfig{InsecureSkipVerify: true},
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
|
|
||||||
var aErr *coreErrs.AuthError
|
conn, err := c.UDP()
|
||||||
|
assert.Nil(t, conn)
|
||||||
// Try TCP
|
_, ok := err.(coreErrs.DialError)
|
||||||
_, err = c.TCP("google.com:443")
|
assert.True(t, ok)
|
||||||
if !errors.As(err, &aErr) {
|
|
||||||
t.Fatal("expected auth error from TCP")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try UDP
|
|
||||||
_, err = c.UDP()
|
|
||||||
if !errors.As(err, &aErr) {
|
|
||||||
t.Fatal("expected auth error from DialUDP")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestClientServerTCPEcho tests TCP forwarding using a TCP echo server.
|
// TestClientServerTCPEcho tests TCP forwarding using a TCP echo server.
|
||||||
func TestClientServerTCPEcho(t *testing.T) {
|
func TestClientServerTCPEcho(t *testing.T) {
|
||||||
// Create server
|
// Create server
|
||||||
udpAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 14514}
|
udpConn, udpAddr, err := serverConn()
|
||||||
udpConn, err := net.ListenUDP("udp", udpAddr)
|
assert.NoError(t, err)
|
||||||
if err != nil {
|
auth := mocks.NewMockAuthenticator(t)
|
||||||
t.Fatal("error creating server:", err)
|
auth.EXPECT().Authenticate(mock.Anything, mock.Anything, mock.Anything).Return(true, "nobody")
|
||||||
}
|
|
||||||
s, err := server.NewServer(&server.Config{
|
s, err := server.NewServer(&server.Config{
|
||||||
TLSConfig: serverTLSConfig(),
|
TLSConfig: serverTLSConfig(),
|
||||||
Conn: udpConn,
|
Conn: udpConn,
|
||||||
Authenticator: &pwAuthenticator{
|
Authenticator: auth,
|
||||||
Password: "password",
|
|
||||||
ID: "nobody",
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error creating server:", err)
|
|
||||||
}
|
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
go s.Serve()
|
go s.Serve()
|
||||||
|
|
||||||
// Create TCP echo server
|
// Create TCP echo server
|
||||||
echoTCPAddr := &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 14515}
|
echoAddr := "127.0.0.1:22333"
|
||||||
echoListener, err := net.ListenTCP("tcp", echoTCPAddr)
|
echoListener, err := net.Listen("tcp", echoAddr)
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error creating TCP echo server:", err)
|
|
||||||
}
|
|
||||||
echoServer := &tcpEchoServer{Listener: echoListener}
|
echoServer := &tcpEchoServer{Listener: echoListener}
|
||||||
defer echoServer.Close()
|
defer echoServer.Close()
|
||||||
go echoServer.Serve()
|
go echoServer.Serve()
|
||||||
@ -125,65 +115,46 @@ func TestClientServerTCPEcho(t *testing.T) {
|
|||||||
// Create client
|
// Create client
|
||||||
c, err := client.NewClient(&client.Config{
|
c, err := client.NewClient(&client.Config{
|
||||||
ServerAddr: udpAddr,
|
ServerAddr: udpAddr,
|
||||||
Auth: "password",
|
|
||||||
TLSConfig: client.TLSConfig{InsecureSkipVerify: true},
|
TLSConfig: client.TLSConfig{InsecureSkipVerify: true},
|
||||||
})
|
})
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error creating client:", err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
|
|
||||||
// Dial TCP
|
// Dial TCP
|
||||||
conn, err := c.TCP(echoTCPAddr.String())
|
conn, err := c.TCP(echoAddr)
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error dialing TCP:", err)
|
|
||||||
}
|
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
// Send and receive data
|
// Send and receive data
|
||||||
sData := []byte("hello world")
|
sData := []byte("hello world")
|
||||||
_, err = conn.Write(sData)
|
_, err = conn.Write(sData)
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error writing to TCP:", err)
|
|
||||||
}
|
|
||||||
rData := make([]byte, len(sData))
|
rData := make([]byte, len(sData))
|
||||||
_, err = io.ReadFull(conn, rData)
|
_, err = io.ReadFull(conn, rData)
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error reading from TCP:", err)
|
assert.Equal(t, sData, rData)
|
||||||
}
|
|
||||||
if string(rData) != string(sData) {
|
|
||||||
t.Fatalf("expected %q, got %q", sData, rData)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestClientServerUDPEcho tests UDP forwarding using a UDP echo server.
|
// TestClientServerUDPEcho tests UDP forwarding using a UDP echo server.
|
||||||
func TestClientServerUDPEcho(t *testing.T) {
|
func TestClientServerUDPEcho(t *testing.T) {
|
||||||
// Create server
|
// Create server
|
||||||
udpAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 14514}
|
udpConn, udpAddr, err := serverConn()
|
||||||
udpConn, err := net.ListenUDP("udp", udpAddr)
|
assert.NoError(t, err)
|
||||||
if err != nil {
|
auth := mocks.NewMockAuthenticator(t)
|
||||||
t.Fatal("error creating server:", err)
|
auth.EXPECT().Authenticate(mock.Anything, mock.Anything, mock.Anything).Return(true, "nobody")
|
||||||
}
|
|
||||||
s, err := server.NewServer(&server.Config{
|
s, err := server.NewServer(&server.Config{
|
||||||
TLSConfig: serverTLSConfig(),
|
TLSConfig: serverTLSConfig(),
|
||||||
Conn: udpConn,
|
Conn: udpConn,
|
||||||
Authenticator: &pwAuthenticator{
|
Authenticator: auth,
|
||||||
Password: "password",
|
|
||||||
ID: "nobody",
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error creating server:", err)
|
|
||||||
}
|
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
go s.Serve()
|
go s.Serve()
|
||||||
|
|
||||||
// Create UDP echo server
|
// Create UDP echo server
|
||||||
echoUDPAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 55555}
|
echoAddr := "127.0.0.1:22333"
|
||||||
echoConn, err := net.ListenUDP("udp", echoUDPAddr)
|
echoConn, err := net.ListenPacket("udp", echoAddr)
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error creating UDP echo server:", err)
|
|
||||||
}
|
|
||||||
echoServer := &udpEchoServer{Conn: echoConn}
|
echoServer := &udpEchoServer{Conn: echoConn}
|
||||||
defer echoServer.Close()
|
defer echoServer.Close()
|
||||||
go echoServer.Serve()
|
go echoServer.Serve()
|
||||||
@ -191,35 +162,22 @@ func TestClientServerUDPEcho(t *testing.T) {
|
|||||||
// Create client
|
// Create client
|
||||||
c, err := client.NewClient(&client.Config{
|
c, err := client.NewClient(&client.Config{
|
||||||
ServerAddr: udpAddr,
|
ServerAddr: udpAddr,
|
||||||
Auth: "password",
|
|
||||||
TLSConfig: client.TLSConfig{InsecureSkipVerify: true},
|
TLSConfig: client.TLSConfig{InsecureSkipVerify: true},
|
||||||
})
|
})
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error creating client:", err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
|
|
||||||
// Listen UDP
|
// Listen UDP
|
||||||
conn, err := c.UDP()
|
conn, err := c.UDP()
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error listening UDP:", err)
|
|
||||||
}
|
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
// Send and receive data
|
// Send and receive data
|
||||||
sData := []byte("hello world")
|
sData := []byte("hello world")
|
||||||
err = conn.Send(sData, echoUDPAddr.String())
|
err = conn.Send(sData, echoAddr)
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error sending UDP:", err)
|
|
||||||
}
|
|
||||||
rData, rAddr, err := conn.Receive()
|
rData, rAddr, err := conn.Receive()
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error receiving UDP:", err)
|
assert.Equal(t, sData, rData)
|
||||||
}
|
assert.Equal(t, echoAddr, rAddr)
|
||||||
if string(rData) != string(sData) {
|
|
||||||
t.Fatalf("expected %q, got %q", sData, rData)
|
|
||||||
}
|
|
||||||
if rAddr != echoUDPAddr.String() {
|
|
||||||
t.Fatalf("expected %q, got %q", echoUDPAddr.String(), rAddr)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,12 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
"golang.org/x/time/rate"
|
"golang.org/x/time/rate"
|
||||||
|
|
||||||
"github.com/apernet/hysteria/core/client"
|
"github.com/apernet/hysteria/core/client"
|
||||||
|
"github.com/apernet/hysteria/core/internal/integration_tests/mocks"
|
||||||
"github.com/apernet/hysteria/core/server"
|
"github.com/apernet/hysteria/core/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,9 +29,7 @@ func (s *tcpStressor) Run(t *testing.T) {
|
|||||||
// Make some random data
|
// Make some random data
|
||||||
sData := make([]byte, s.Size)
|
sData := make([]byte, s.Size)
|
||||||
_, err := rand.Read(sData)
|
_, err := rand.Read(sData)
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error generating random data:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run iterations
|
// Run iterations
|
||||||
for i := 0; i < s.Iterations; i++ {
|
for i := 0; i < s.Iterations; i++ {
|
||||||
@ -57,9 +58,7 @@ func (s *tcpStressor) Run(t *testing.T) {
|
|||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
if len(errChan) > 0 {
|
assert.Empty(t, errChan)
|
||||||
t.Fatal("error reading from TCP:", <-errChan)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,9 +75,7 @@ func (s *udpStressor) Run(t *testing.T) {
|
|||||||
// Make some random data
|
// Make some random data
|
||||||
sData := make([]byte, s.Size)
|
sData := make([]byte, s.Size)
|
||||||
_, err := rand.Read(sData)
|
_, err := rand.Read(sData)
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error generating random data:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Due to UDP's unreliability, we need to limit the rate of sending
|
// Due to UDP's unreliability, we need to limit the rate of sending
|
||||||
// to reduce packet loss. This is hardcoded to 1 MiB/s for now.
|
// to reduce packet loss. This is hardcoded to 1 MiB/s for now.
|
||||||
@ -123,39 +120,29 @@ func (s *udpStressor) Run(t *testing.T) {
|
|||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
if len(errChan) > 0 {
|
assert.Empty(t, errChan)
|
||||||
t.Fatal("error reading from UDP:", <-errChan)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientServerTCPStress(t *testing.T) {
|
func TestClientServerTCPStress(t *testing.T) {
|
||||||
// Create server
|
// Create server
|
||||||
udpAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 14514}
|
udpConn, udpAddr, err := serverConn()
|
||||||
udpConn, err := net.ListenUDP("udp", udpAddr)
|
assert.NoError(t, err)
|
||||||
if err != nil {
|
auth := mocks.NewMockAuthenticator(t)
|
||||||
t.Fatal("error creating server:", err)
|
auth.EXPECT().Authenticate(mock.Anything, mock.Anything, mock.Anything).Return(true, "nobody")
|
||||||
}
|
|
||||||
s, err := server.NewServer(&server.Config{
|
s, err := server.NewServer(&server.Config{
|
||||||
TLSConfig: serverTLSConfig(),
|
TLSConfig: serverTLSConfig(),
|
||||||
Conn: udpConn,
|
Conn: udpConn,
|
||||||
Authenticator: &pwAuthenticator{
|
Authenticator: auth,
|
||||||
Password: "password",
|
|
||||||
ID: "nobody",
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error creating server:", err)
|
|
||||||
}
|
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
go s.Serve()
|
go s.Serve()
|
||||||
|
|
||||||
// Create TCP echo server
|
// Create TCP echo server
|
||||||
echoTCPAddr := &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 14515}
|
echoAddr := "127.0.0.1:22333"
|
||||||
echoListener, err := net.ListenTCP("tcp", echoTCPAddr)
|
echoListener, err := net.Listen("tcp", echoAddr)
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error creating TCP echo server:", err)
|
|
||||||
}
|
|
||||||
echoServer := &tcpEchoServer{Listener: echoListener}
|
echoServer := &tcpEchoServer{Listener: echoListener}
|
||||||
defer echoServer.Close()
|
defer echoServer.Close()
|
||||||
go echoServer.Serve()
|
go echoServer.Serve()
|
||||||
@ -163,16 +150,13 @@ func TestClientServerTCPStress(t *testing.T) {
|
|||||||
// Create client
|
// Create client
|
||||||
c, err := client.NewClient(&client.Config{
|
c, err := client.NewClient(&client.Config{
|
||||||
ServerAddr: udpAddr,
|
ServerAddr: udpAddr,
|
||||||
Auth: "password",
|
|
||||||
TLSConfig: client.TLSConfig{InsecureSkipVerify: true},
|
TLSConfig: client.TLSConfig{InsecureSkipVerify: true},
|
||||||
})
|
})
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error creating client:", err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
|
|
||||||
dialFunc := func() (net.Conn, error) {
|
dialFunc := func() (net.Conn, error) {
|
||||||
return c.TCP(echoTCPAddr.String())
|
return c.TCP(echoAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("Single 500m", (&tcpStressor{DialFunc: dialFunc, Size: 524288000, Parallel: 1, Iterations: 1}).Run)
|
t.Run("Single 500m", (&tcpStressor{DialFunc: dialFunc, Size: 524288000, Parallel: 1, Iterations: 1}).Run)
|
||||||
@ -186,49 +170,38 @@ func TestClientServerTCPStress(t *testing.T) {
|
|||||||
|
|
||||||
func TestClientServerUDPStress(t *testing.T) {
|
func TestClientServerUDPStress(t *testing.T) {
|
||||||
// Create server
|
// Create server
|
||||||
udpAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 14514}
|
udpConn, udpAddr, err := serverConn()
|
||||||
udpConn, err := net.ListenUDP("udp", udpAddr)
|
assert.NoError(t, err)
|
||||||
if err != nil {
|
auth := mocks.NewMockAuthenticator(t)
|
||||||
t.Fatal("error creating server:", err)
|
auth.EXPECT().Authenticate(mock.Anything, mock.Anything, mock.Anything).Return(true, "nobody")
|
||||||
}
|
|
||||||
s, err := server.NewServer(&server.Config{
|
s, err := server.NewServer(&server.Config{
|
||||||
TLSConfig: serverTLSConfig(),
|
TLSConfig: serverTLSConfig(),
|
||||||
Conn: udpConn,
|
Conn: udpConn,
|
||||||
Authenticator: &pwAuthenticator{
|
Authenticator: auth,
|
||||||
Password: "password",
|
|
||||||
ID: "nobody",
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error creating server:", err)
|
|
||||||
}
|
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
go s.Serve()
|
go s.Serve()
|
||||||
|
|
||||||
// Create UDP echo server
|
// Create UDP echo server
|
||||||
echoUDPAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 14515}
|
echoAddr := "127.0.0.1:22333"
|
||||||
echoListener, err := net.ListenUDP("udp", echoUDPAddr)
|
echoConn, err := net.ListenPacket("udp", echoAddr)
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error creating UDP echo server:", err)
|
echoServer := &udpEchoServer{Conn: echoConn}
|
||||||
}
|
|
||||||
echoServer := &udpEchoServer{Conn: echoListener}
|
|
||||||
defer echoServer.Close()
|
defer echoServer.Close()
|
||||||
go echoServer.Serve()
|
go echoServer.Serve()
|
||||||
|
|
||||||
// Create client
|
// Create client
|
||||||
c, err := client.NewClient(&client.Config{
|
c, err := client.NewClient(&client.Config{
|
||||||
ServerAddr: udpAddr,
|
ServerAddr: udpAddr,
|
||||||
Auth: "password",
|
|
||||||
TLSConfig: client.TLSConfig{InsecureSkipVerify: true},
|
TLSConfig: client.TLSConfig{InsecureSkipVerify: true},
|
||||||
})
|
})
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Fatal("error creating client:", err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
|
|
||||||
t.Run("Single 1000x100b", (&udpStressor{
|
t.Run("Single 1000x100b", (&udpStressor{
|
||||||
ListenFunc: c.UDP,
|
ListenFunc: c.UDP,
|
||||||
ServerAddr: echoUDPAddr.String(),
|
ServerAddr: echoAddr,
|
||||||
Size: 100,
|
Size: 100,
|
||||||
Count: 1000,
|
Count: 1000,
|
||||||
Parallel: 1,
|
Parallel: 1,
|
||||||
@ -236,7 +209,7 @@ func TestClientServerUDPStress(t *testing.T) {
|
|||||||
}).Run)
|
}).Run)
|
||||||
t.Run("Single 1000x3k", (&udpStressor{
|
t.Run("Single 1000x3k", (&udpStressor{
|
||||||
ListenFunc: c.UDP,
|
ListenFunc: c.UDP,
|
||||||
ServerAddr: echoUDPAddr.String(),
|
ServerAddr: echoAddr,
|
||||||
Size: 3000,
|
Size: 3000,
|
||||||
Count: 1000,
|
Count: 1000,
|
||||||
Parallel: 1,
|
Parallel: 1,
|
||||||
@ -245,7 +218,7 @@ func TestClientServerUDPStress(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("5 Sequential 1000x100b", (&udpStressor{
|
t.Run("5 Sequential 1000x100b", (&udpStressor{
|
||||||
ListenFunc: c.UDP,
|
ListenFunc: c.UDP,
|
||||||
ServerAddr: echoUDPAddr.String(),
|
ServerAddr: echoAddr,
|
||||||
Size: 100,
|
Size: 100,
|
||||||
Count: 1000,
|
Count: 1000,
|
||||||
Parallel: 1,
|
Parallel: 1,
|
||||||
@ -253,7 +226,7 @@ func TestClientServerUDPStress(t *testing.T) {
|
|||||||
}).Run)
|
}).Run)
|
||||||
t.Run("5 Sequential 200x3k", (&udpStressor{
|
t.Run("5 Sequential 200x3k", (&udpStressor{
|
||||||
ListenFunc: c.UDP,
|
ListenFunc: c.UDP,
|
||||||
ServerAddr: echoUDPAddr.String(),
|
ServerAddr: echoAddr,
|
||||||
Size: 3000,
|
Size: 3000,
|
||||||
Count: 200,
|
Count: 200,
|
||||||
Parallel: 1,
|
Parallel: 1,
|
||||||
@ -262,7 +235,7 @@ func TestClientServerUDPStress(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("2 Sequential 5 Parallel 1000x100b", (&udpStressor{
|
t.Run("2 Sequential 5 Parallel 1000x100b", (&udpStressor{
|
||||||
ListenFunc: c.UDP,
|
ListenFunc: c.UDP,
|
||||||
ServerAddr: echoUDPAddr.String(),
|
ServerAddr: echoAddr,
|
||||||
Size: 100,
|
Size: 100,
|
||||||
Count: 1000,
|
Count: 1000,
|
||||||
Parallel: 5,
|
Parallel: 5,
|
||||||
@ -271,19 +244,10 @@ func TestClientServerUDPStress(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("2 Sequential 5 Parallel 200x3k", (&udpStressor{
|
t.Run("2 Sequential 5 Parallel 200x3k", (&udpStressor{
|
||||||
ListenFunc: c.UDP,
|
ListenFunc: c.UDP,
|
||||||
ServerAddr: echoUDPAddr.String(),
|
ServerAddr: echoAddr,
|
||||||
Size: 3000,
|
Size: 3000,
|
||||||
Count: 200,
|
Count: 200,
|
||||||
Parallel: 5,
|
Parallel: 5,
|
||||||
Iterations: 2,
|
Iterations: 2,
|
||||||
}).Run)
|
}).Run)
|
||||||
|
|
||||||
t.Run("10 Sequential 5 Parallel 200x3k", (&udpStressor{
|
|
||||||
ListenFunc: c.UDP,
|
|
||||||
ServerAddr: echoUDPAddr.String(),
|
|
||||||
Size: 3000,
|
|
||||||
Count: 200,
|
|
||||||
Parallel: 5,
|
|
||||||
Iterations: 10,
|
|
||||||
}).Run)
|
|
||||||
}
|
}
|
||||||
|
@ -1,173 +0,0 @@
|
|||||||
package integration_tests
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"sync/atomic"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/apernet/hysteria/core/client"
|
|
||||||
"github.com/apernet/hysteria/core/server"
|
|
||||||
)
|
|
||||||
|
|
||||||
type testTrafficLogger struct {
|
|
||||||
Tx, Rx uint64
|
|
||||||
Block atomic.Bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *testTrafficLogger) Log(id string, tx, rx uint64) bool {
|
|
||||||
atomic.AddUint64(&l.Tx, tx)
|
|
||||||
atomic.AddUint64(&l.Rx, rx)
|
|
||||||
return !l.Block.Load()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *testTrafficLogger) Get() (tx, rx uint64) {
|
|
||||||
return atomic.LoadUint64(&l.Tx), atomic.LoadUint64(&l.Rx)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *testTrafficLogger) SetBlock(block bool) {
|
|
||||||
l.Block.Store(block)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *testTrafficLogger) Reset() {
|
|
||||||
atomic.StoreUint64(&l.Tx, 0)
|
|
||||||
atomic.StoreUint64(&l.Rx, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestServerTrafficLogger tests that the server's TrafficLogger interface is working correctly.
|
|
||||||
// More specifically, it tests that the server is correctly logging traffic in both directions,
|
|
||||||
// and that it is correctly disconnecting clients when the traffic logger returns false.
|
|
||||||
func TestServerTrafficLogger(t *testing.T) {
|
|
||||||
tl := &testTrafficLogger{}
|
|
||||||
|
|
||||||
// Create server
|
|
||||||
udpAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 14514}
|
|
||||||
udpConn, err := net.ListenUDP("udp", udpAddr)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("error creating server:", err)
|
|
||||||
}
|
|
||||||
s, err := server.NewServer(&server.Config{
|
|
||||||
TLSConfig: serverTLSConfig(),
|
|
||||||
Conn: udpConn,
|
|
||||||
Authenticator: &pwAuthenticator{
|
|
||||||
Password: "password",
|
|
||||||
ID: "nobody",
|
|
||||||
},
|
|
||||||
TrafficLogger: tl,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("error creating server:", err)
|
|
||||||
}
|
|
||||||
defer s.Close()
|
|
||||||
go s.Serve()
|
|
||||||
|
|
||||||
// Create TCP double echo server
|
|
||||||
// We use double echo to test that the traffic logger is correctly logging both directions.
|
|
||||||
echoTCPAddr := &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 14515}
|
|
||||||
echoListener, err := net.ListenTCP("tcp", echoTCPAddr)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("error creating TCP echo server:", err)
|
|
||||||
}
|
|
||||||
tEchoServer := &tcpDoubleEchoServer{Listener: echoListener}
|
|
||||||
defer tEchoServer.Close()
|
|
||||||
go tEchoServer.Serve()
|
|
||||||
|
|
||||||
// Create client
|
|
||||||
c, err := client.NewClient(&client.Config{
|
|
||||||
ServerAddr: udpAddr,
|
|
||||||
Auth: "password",
|
|
||||||
TLSConfig: client.TLSConfig{InsecureSkipVerify: true},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("error creating client:", err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
// Dial TCP
|
|
||||||
tConn, err := c.TCP(echoTCPAddr.String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("error dialing TCP:", err)
|
|
||||||
}
|
|
||||||
defer tConn.Close()
|
|
||||||
|
|
||||||
// Send and receive TCP data
|
|
||||||
sData := []byte("1234")
|
|
||||||
_, err = tConn.Write(sData)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("error writing to TCP:", err)
|
|
||||||
}
|
|
||||||
rData := make([]byte, len(sData)*2)
|
|
||||||
_, err = io.ReadFull(tConn, rData)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("error reading from TCP:", err)
|
|
||||||
}
|
|
||||||
expected := string(sData) + string(sData)
|
|
||||||
if string(rData) != expected {
|
|
||||||
t.Fatalf("expected %q, got %q", expected, string(rData))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check traffic logger
|
|
||||||
tx, rx := tl.Get()
|
|
||||||
if tx != uint64(len(sData)) || rx != uint64(len(rData)) {
|
|
||||||
t.Fatalf("expected TrafficLogger Tx=%d, Rx=%d, got Tx=%d, Rx=%d", len(sData), len(rData), tx, rx)
|
|
||||||
}
|
|
||||||
tl.Reset()
|
|
||||||
|
|
||||||
// Create UDP double echo server
|
|
||||||
echoUDPAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 55555}
|
|
||||||
echoConn, err := net.ListenUDP("udp", echoUDPAddr)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("error creating UDP echo server:", err)
|
|
||||||
}
|
|
||||||
uEchoServer := &udpDoubleEchoServer{Conn: echoConn}
|
|
||||||
defer uEchoServer.Close()
|
|
||||||
go uEchoServer.Serve()
|
|
||||||
|
|
||||||
// Listen UDP
|
|
||||||
uConn, err := c.UDP()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("error listening UDP:", err)
|
|
||||||
}
|
|
||||||
defer uConn.Close()
|
|
||||||
|
|
||||||
// Send and receive UDP data
|
|
||||||
sData = []byte("gucci gang")
|
|
||||||
err = uConn.Send(sData, echoUDPAddr.String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("error sending UDP:", err)
|
|
||||||
}
|
|
||||||
for i := 0; i < 2; i++ {
|
|
||||||
rData, rAddr, err := uConn.Receive()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("error receiving UDP:", err)
|
|
||||||
}
|
|
||||||
if string(rData) != string(sData) {
|
|
||||||
t.Fatalf("expected %q, got %q", string(sData), string(rData))
|
|
||||||
}
|
|
||||||
if rAddr != echoUDPAddr.String() {
|
|
||||||
t.Fatalf("expected %q, got %q", echoUDPAddr.String(), rAddr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check traffic logger
|
|
||||||
tx, rx = tl.Get()
|
|
||||||
if tx != uint64(len(sData)) || rx != uint64(len(sData)*2) {
|
|
||||||
t.Fatalf("expected TrafficLogger Tx=%d, Rx=%d, got Tx=%d, Rx=%d", len(sData), len(sData)*2, tx, rx)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the disconnect client functionality
|
|
||||||
tl.SetBlock(true)
|
|
||||||
|
|
||||||
// Send and receive TCP data again
|
|
||||||
sData = []byte("1234")
|
|
||||||
_, err = tConn.Write(sData)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("error writing to TCP:", err)
|
|
||||||
}
|
|
||||||
// This should fail instantly without reading any data
|
|
||||||
// io.Copy should return nil as EOF is treated as a non-error though
|
|
||||||
n, err := io.Copy(io.Discard, tConn)
|
|
||||||
if n != 0 || err != nil {
|
|
||||||
t.Fatal("expected 0 bytes read and nil error, got", n, err)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
package integration_tests
|
package integration_tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
@ -35,18 +34,6 @@ func serverConn() (net.PacketConn, net.Addr, error) {
|
|||||||
return udpConn, udpAddr, nil
|
return udpConn, udpAddr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type pwAuthenticator struct {
|
|
||||||
Password string
|
|
||||||
ID string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *pwAuthenticator) Authenticate(addr net.Addr, auth string, tx uint64) (ok bool, id string) {
|
|
||||||
if auth != a.Password {
|
|
||||||
return false, ""
|
|
||||||
}
|
|
||||||
return true, a.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
// tcpEchoServer is a TCP server that echoes what it reads from the connection.
|
// tcpEchoServer is a TCP server that echoes what it reads from the connection.
|
||||||
// It will never actively close the connection.
|
// It will never actively close the connection.
|
||||||
type tcpEchoServer struct {
|
type tcpEchoServer struct {
|
||||||
@ -70,92 +57,6 @@ func (s *tcpEchoServer) Close() error {
|
|||||||
return s.Listener.Close()
|
return s.Listener.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// tcpDoubleEchoServer is a TCP server that echoes twice what it reads from the connection.
|
|
||||||
// It will never actively close the connection.
|
|
||||||
type tcpDoubleEchoServer struct {
|
|
||||||
Listener net.Listener
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *tcpDoubleEchoServer) Serve() error {
|
|
||||||
for {
|
|
||||||
conn, err := s.Listener.Accept()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
go func() {
|
|
||||||
buf := make([]byte, 1024)
|
|
||||||
for {
|
|
||||||
n, err := conn.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
_ = conn.Close()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, _ = conn.Write(buf[:n])
|
|
||||||
_, _ = conn.Write(buf[:n])
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *tcpDoubleEchoServer) Close() error {
|
|
||||||
return s.Listener.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
type sinkEvent struct {
|
|
||||||
Data []byte
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
// tcpSinkServer is a TCP server that reads data from the connection,
|
|
||||||
// and sends what it read to the channel when the connection is closed.
|
|
||||||
type tcpSinkServer struct {
|
|
||||||
Listener net.Listener
|
|
||||||
Ch chan<- sinkEvent
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *tcpSinkServer) Serve() error {
|
|
||||||
for {
|
|
||||||
conn, err := s.Listener.Accept()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
go func() {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
_, err := io.Copy(&buf, conn)
|
|
||||||
_ = conn.Close()
|
|
||||||
s.Ch <- sinkEvent{Data: buf.Bytes(), Err: err}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *tcpSinkServer) Close() error {
|
|
||||||
return s.Listener.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// tcpSenderServer is a TCP server that sends data to the connection,
|
|
||||||
// and closes the connection when all data has been sent.
|
|
||||||
type tcpSenderServer struct {
|
|
||||||
Listener net.Listener
|
|
||||||
Data []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *tcpSenderServer) Serve() error {
|
|
||||||
for {
|
|
||||||
conn, err := s.Listener.Accept()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
go func() {
|
|
||||||
_, _ = conn.Write(s.Data)
|
|
||||||
_ = conn.Close()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *tcpSenderServer) Close() error {
|
|
||||||
return s.Listener.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// udpEchoServer is a UDP server that echoes what it reads from the connection.
|
// udpEchoServer is a UDP server that echoes what it reads from the connection.
|
||||||
// It will never actively close the connection.
|
// It will never actively close the connection.
|
||||||
type udpEchoServer struct {
|
type udpEchoServer struct {
|
||||||
@ -179,140 +80,3 @@ func (s *udpEchoServer) Serve() error {
|
|||||||
func (s *udpEchoServer) Close() error {
|
func (s *udpEchoServer) Close() error {
|
||||||
return s.Conn.Close()
|
return s.Conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// udpDoubleEchoServer is a UDP server that echoes twice what it reads from the connection.
|
|
||||||
// It will never actively close the connection.
|
|
||||||
type udpDoubleEchoServer struct {
|
|
||||||
Conn net.PacketConn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *udpDoubleEchoServer) Serve() error {
|
|
||||||
buf := make([]byte, 65536)
|
|
||||||
for {
|
|
||||||
n, addr, err := s.Conn.ReadFrom(buf)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = s.Conn.WriteTo(buf[:n], addr)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = s.Conn.WriteTo(buf[:n], addr)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *udpDoubleEchoServer) Close() error {
|
|
||||||
return s.Conn.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
type connectEvent struct {
|
|
||||||
Addr net.Addr
|
|
||||||
ID string
|
|
||||||
TX uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
type disconnectEvent struct {
|
|
||||||
Addr net.Addr
|
|
||||||
ID string
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
type tcpRequestEvent struct {
|
|
||||||
Addr net.Addr
|
|
||||||
ID string
|
|
||||||
ReqAddr string
|
|
||||||
}
|
|
||||||
|
|
||||||
type tcpErrorEvent struct {
|
|
||||||
Addr net.Addr
|
|
||||||
ID string
|
|
||||||
ReqAddr string
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
type udpRequestEvent struct {
|
|
||||||
Addr net.Addr
|
|
||||||
ID string
|
|
||||||
SessionID uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type udpErrorEvent struct {
|
|
||||||
Addr net.Addr
|
|
||||||
ID string
|
|
||||||
SessionID uint32
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
type channelEventLogger struct {
|
|
||||||
ConnectEventCh chan connectEvent
|
|
||||||
DisconnectEventCh chan disconnectEvent
|
|
||||||
TCPRequestEventCh chan tcpRequestEvent
|
|
||||||
TCPErrorEventCh chan tcpErrorEvent
|
|
||||||
UDPRequestEventCh chan udpRequestEvent
|
|
||||||
UDPErrorEventCh chan udpErrorEvent
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *channelEventLogger) Connect(addr net.Addr, id string, tx uint64) {
|
|
||||||
if l.ConnectEventCh != nil {
|
|
||||||
l.ConnectEventCh <- connectEvent{
|
|
||||||
Addr: addr,
|
|
||||||
ID: id,
|
|
||||||
TX: tx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *channelEventLogger) Disconnect(addr net.Addr, id string, err error) {
|
|
||||||
if l.DisconnectEventCh != nil {
|
|
||||||
l.DisconnectEventCh <- disconnectEvent{
|
|
||||||
Addr: addr,
|
|
||||||
ID: id,
|
|
||||||
Err: err,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *channelEventLogger) TCPRequest(addr net.Addr, id, reqAddr string) {
|
|
||||||
if l.TCPRequestEventCh != nil {
|
|
||||||
l.TCPRequestEventCh <- tcpRequestEvent{
|
|
||||||
Addr: addr,
|
|
||||||
ID: id,
|
|
||||||
ReqAddr: reqAddr,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *channelEventLogger) TCPError(addr net.Addr, id, reqAddr string, err error) {
|
|
||||||
if l.TCPErrorEventCh != nil {
|
|
||||||
l.TCPErrorEventCh <- tcpErrorEvent{
|
|
||||||
Addr: addr,
|
|
||||||
ID: id,
|
|
||||||
ReqAddr: reqAddr,
|
|
||||||
Err: err,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *channelEventLogger) UDPRequest(addr net.Addr, id string, sessionID uint32, reqAddr string) {
|
|
||||||
if l.UDPRequestEventCh != nil {
|
|
||||||
l.UDPRequestEventCh <- udpRequestEvent{
|
|
||||||
Addr: addr,
|
|
||||||
ID: id,
|
|
||||||
SessionID: sessionID,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *channelEventLogger) UDPError(addr net.Addr, id string, sessionID uint32, err error) {
|
|
||||||
if l.UDPErrorEventCh != nil {
|
|
||||||
l.UDPErrorEventCh <- udpErrorEvent{
|
|
||||||
Addr: addr,
|
|
||||||
ID: id,
|
|
||||||
SessionID: sessionID,
|
|
||||||
Err: err,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user