main
Raw Download raw file
 1package main
 2
 3import (
 4	"fmt"
 5	"log/slog"
 6	"net"
 7	"time"
 8)
 9
10// TODO:
11//  - [x] parsing socks5 bytes into functions
12//  - [ ] report results and cobine in send+recv results
13//    - connection id
14//  - [] seralization of replies into functions ->
15//  - [] better goroutine mgmt
16//  - [] signal handlers
17//  - [] split server and client with abstract reader/writers and messages
18//  - (?) avoid structs, [id, len, data] for established connections
19//  - (?) server-to-server Reply ATYP=05 id
20
21// TODO: options
22
23const (
24	timeout = time.Second * 30
25	bufSize = 128 * 1024
26)
27
28func NewServer() (*net.TCPListener, error) {
29	network := "tcp4"
30	address := "127.0.0.1"
31	port := 9000
32	slog.Info("starting socks server",
33		slog.String("network", network),
34		slog.String("address", address),
35		slog.Int("port", port),
36	)
37	addr := fmt.Sprintf("%s:%d", address, port)
38	lAddr, err := net.ResolveTCPAddr("tcp", addr)
39	if err != nil {
40		return nil, fmt.Errorf("failed to parse addr=%q: %w", addr, err)
41	}
42	l, err := net.ListenTCP(network, lAddr)
43	if err != nil {
44		return nil, fmt.Errorf("failed to start server: %w", err)
45	}
46	return l, nil
47}
48
49func main() {
50
51	l, err := NewServer()
52	if err != nil {
53		fmt.Println(err)
54		return
55	}
56	defer l.Close()
57
58	for {
59		sconn, err := l.AcceptTCP()
60		if err != nil {
61			slog.Error("failed to accept conenction",
62				slog.String("error", err.Error()))
63			return
64		}
65
66		go func() {
67			conn, err := NewConnection(sconn)
68			if err != nil {
69				slog.Error("failed to setup proxy",
70					slog.String("error", err.Error()))
71				return
72			}
73
74			err = conn.Proxy()
75			if err != nil {
76				slog.Error("failed to proxy connection",
77					slog.String("error", err.Error()))
78				return
79			}
80		}()
81	}
82}