blob: 3ca8e3466d40e66acf95119fb294a4e2b60cd07f [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)
Serge Bazanski1ec1fe92023-03-22 18:29:28 +010052 con.Close()
Serge Bazanskibe742842022-04-04 13:18:50 +020053 return &socksproxy.ConnectResponse{
54 Error: socksproxy.ReplyGeneralFailure,
55 }
56 }
57 logger.Infof("Connect %s: established", target)
58 return res
59}
60
61// runSOCKSProxy starts a SOCKS proxy to the nanoswitchnetwork at SOCKSPort.
62func runSOCKSProxy(ctx context.Context) error {
63 lis, err := net.Listen("tcp", fmt.Sprintf(":%d", SOCKSPort))
64 if err != nil {
65 return fmt.Errorf("failed to listen on :%d : %v", SOCKSPort, err)
66 }
67
68 h := &socksHandler{}
69 supervisor.Signal(ctx, supervisor.SignalHealthy)
70 return socksproxy.Serve(ctx, h, lis)
71}