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