Merge pull request #33 from asmogo/restructure_tcp_reverse

Refactor reverse TCP connection handling in socks5
This commit is contained in:
asmogo 2024-08-04 14:49:56 +02:00 committed by GitHub
commit 25a5486bf0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,10 +1,12 @@
package socks5 package socks5
import ( import (
"github.com/google/uuid" "fmt"
"github.com/puzpuzpuz/xsync/v3"
"log/slog" "log/slog"
"net" "net"
"github.com/google/uuid"
"github.com/puzpuzpuz/xsync/v3"
) )
type TCPListener struct { type TCPListener struct {
@ -12,10 +14,12 @@ type TCPListener struct {
connectChannels *xsync.MapOf[string, chan net.Conn] // todo -- use [16]byte for uuid instead of string connectChannels *xsync.MapOf[string, chan net.Conn] // todo -- use [16]byte for uuid instead of string
} }
const uuidLength = 36
func NewTCPListener(address string) (*TCPListener, error) { func NewTCPListener(address string) (*TCPListener, error) {
l, err := net.Listen("tcp", address) l, err := net.Listen("tcp", address)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("failed to create tcp listener: %w", err)
} }
return &TCPListener{ return &TCPListener{
listener: l, listener: l,
@ -39,26 +43,34 @@ func (l *TCPListener) Start() {
} }
// handleConnection handles the connection // handleConnection handles the connection
// It reads the uuid from the connection, checks if the uuid is in the map, and sends the connection to the channel
// It does not close the connection
func (l *TCPListener) handleConnection(conn net.Conn) { func (l *TCPListener) handleConnection(conn net.Conn) {
//defer conn.Close() response := []byte{1}
for { for {
// read uuid from the connection // read uuid from the connection
readbuffer := make([]byte, 36) readbuffer := make([]byte, uuidLength)
_, err := conn.Read(readbuffer) _, err := conn.Read(readbuffer)
if err != nil { if err != nil {
return return
} }
// check if uuid is in the map // check if uuid is in the map
ch, ok := l.connectChannels.Load(string(readbuffer)) connectionID := string(readbuffer)
connChannel, ok := l.connectChannels.Load(connectionID)
if !ok { if !ok {
slog.Error("uuid not found in map") slog.Error("uuid not found in map")
continue continue
} }
slog.Info("uuid found in map") slog.Info("uuid found in map")
conn.Write([]byte{1}) l.connectChannels.Delete(connectionID)
_, err = conn.Write(response)
if err != nil {
close(connChannel) // close the channel
slog.Error("failed to write response to connection", "err", err)
return
}
// send the connection to the channel // send the connection to the channel
ch <- conn connChannel <- conn
return return
} }
} }