2023-05-25 20:24:24 -07:00

230 lines
5.7 KiB
Go

package integration_tests
import (
"errors"
"io"
"net"
"testing"
"github.com/apernet/hysteria/core/client"
coreErrs "github.com/apernet/hysteria/core/errors"
"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.
// TestClientNoServer tests how the client handles a server that doesn't exist.
// The client should still be able to be created, but TCP & UDP requests should fail.
func TestClientNoServer(t *testing.T) {
// Create client
c, err := client.NewClient(&client.Config{
ServerAddr: &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 14514},
ServerName: "not_a_real_server",
})
if err != nil {
t.Fatal("error creating client:", err)
}
defer c.Close()
var cErr *coreErrs.ConnectError
// Try TCP
_, err = c.DialTCP("google.com:443")
if !errors.As(err, &cErr) {
t.Fatal("expected connect error from DialTCP")
}
// Try UDP
_, err = c.ListenUDP()
if !errors.As(err, &cErr) {
t.Fatal("expected connect error from ListenUDP")
}
}
// TestClientServerBadAuth tests two things:
// - The server uses Authenticator when a client connects.
// - How the client handles failed authentication.
func TestClientServerBadAuth(t *testing.T) {
// 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: "correct password",
ID: "nobody",
},
})
if err != nil {
t.Fatal("error creating server:", err)
}
defer s.Close()
go s.Serve()
// Create client
c, err := client.NewClient(&client.Config{
ServerAddr: udpAddr,
ServerName: udpAddr.String(),
Auth: "wrong password",
TLSConfig: client.TLSConfig{InsecureSkipVerify: true},
})
if err != nil {
t.Fatal("error creating client:", err)
}
defer c.Close()
var aErr *coreErrs.AuthError
// Try TCP
_, err = c.DialTCP("google.com:443")
if !errors.As(err, &aErr) {
t.Fatal("expected auth error from DialTCP")
}
// Try UDP
_, err = c.ListenUDP()
if !errors.As(err, &aErr) {
t.Fatal("expected auth error from ListenUDP")
}
}
// TestClientServerTCPEcho tests TCP forwarding using a TCP echo server.
func TestClientServerTCPEcho(t *testing.T) {
// 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",
},
})
if err != nil {
t.Fatal("error creating server:", err)
}
defer s.Close()
go s.Serve()
// Create TCP echo server
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)
}
echoServer := &tcpEchoServer{Listener: echoListener}
defer echoServer.Close()
go echoServer.Serve()
// Create client
c, err := client.NewClient(&client.Config{
ServerAddr: udpAddr,
ServerName: udpAddr.String(),
Auth: "password",
TLSConfig: client.TLSConfig{InsecureSkipVerify: true},
})
if err != nil {
t.Fatal("error creating client:", err)
}
defer c.Close()
// Dial TCP
conn, err := c.DialTCP(echoTCPAddr.String())
if err != nil {
t.Fatal("error dialing TCP:", err)
}
defer conn.Close()
// Send and receive data
sData := []byte("hello world")
_, err = conn.Write(sData)
if err != nil {
t.Fatal("error writing to TCP:", err)
}
rData := make([]byte, len(sData))
_, err = io.ReadFull(conn, rData)
if err != nil {
t.Fatal("error reading from TCP:", err)
}
if string(rData) != string(sData) {
t.Fatalf("expected %q, got %q", sData, rData)
}
}
// TestClientServerUDPEcho tests UDP forwarding using a UDP echo server.
func TestClientServerUDPEcho(t *testing.T) {
// 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",
},
})
if err != nil {
t.Fatal("error creating server:", err)
}
defer s.Close()
go s.Serve()
// Create UDP 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)
}
echoServer := &udpEchoServer{Conn: echoConn}
defer echoServer.Close()
go echoServer.Serve()
// Create client
c, err := client.NewClient(&client.Config{
ServerAddr: udpAddr,
ServerName: udpAddr.String(),
Auth: "password",
TLSConfig: client.TLSConfig{InsecureSkipVerify: true},
})
if err != nil {
t.Fatal("error creating client:", err)
}
defer c.Close()
// Listen UDP
conn, err := c.ListenUDP()
if err != nil {
t.Fatal("error listening UDP:", err)
}
defer conn.Close()
// Send and receive data
sData := []byte("hello world")
err = conn.Send(sData, echoUDPAddr.String())
if err != nil {
t.Fatal("error sending UDP:", err)
}
rData, rAddr, err := conn.Receive()
if err != nil {
t.Fatal("error receiving UDP:", err)
}
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)
}
}