main
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}