-
Notifications
You must be signed in to change notification settings - Fork 8
/
socks.go
73 lines (63 loc) · 2.09 KB
/
socks.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package main
import (
"context"
"fmt"
"net"
"source.monogon.dev/metropolis/pkg/socksproxy"
"source.monogon.dev/metropolis/pkg/supervisor"
)
// SOCKSPort is the port at which nanoswitch listens for SOCKS conenctions.
//
// ONCHANGE(//metropolis/test/launch/cluster:cluster.go): port must be kept in sync
const SOCKSPort uint16 = 1080
// socksHandler implements a socksproxy.Handler which permits and logs
// connections to the nanoswitch network.
type socksHandler struct{}
func (s *socksHandler) Connect(ctx context.Context, req *socksproxy.ConnectRequest) *socksproxy.ConnectResponse {
logger := supervisor.Logger(ctx)
target := net.JoinHostPort(req.Address.String(), fmt.Sprintf("%d", req.Port))
if len(req.Address) != 4 {
logger.Warningf("Connect %s: wrong address type", target)
return &socksproxy.ConnectResponse{
Error: socksproxy.ReplyAddressTypeNotSupported,
}
}
addr := req.Address
switchCIDR := net.IPNet{
IP: switchIP.Mask(switchSubnetMask),
Mask: switchSubnetMask,
}
if !switchCIDR.Contains(addr) || switchCIDR.IP.Equal(addr) {
logger.Warningf("Connect %s: not in switch network", target)
return &socksproxy.ConnectResponse{
Error: socksproxy.ReplyNetworkUnreachable,
}
}
con, err := net.Dial("tcp", target)
if err != nil {
logger.Warningf("Connect %s: dial failed: %v", target, err)
return &socksproxy.ConnectResponse{
Error: socksproxy.ReplyHostUnreachable,
}
}
res, err := socksproxy.ConnectResponseFromConn(con)
if err != nil {
logger.Warningf("Connect %s: could not make SOCKS response: %v", target, err)
con.Close()
return &socksproxy.ConnectResponse{
Error: socksproxy.ReplyGeneralFailure,
}
}
logger.Infof("Connect %s: established", target)
return res
}
// runSOCKSProxy starts a SOCKS proxy to the nanoswitchnetwork at SOCKSPort.
func runSOCKSProxy(ctx context.Context) error {
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", SOCKSPort))
if err != nil {
return fmt.Errorf("failed to listen on :%d : %w", SOCKSPort, err)
}
h := &socksHandler{}
supervisor.Signal(ctx, supervisor.SignalHealthy)
return socksproxy.Serve(ctx, h, lis)
}