Serge Bazanski | be74284 | 2022-04-04 13:18:50 +0200 | [diff] [blame^] | 1 | package main |
| 2 | |
| 3 | import ( |
| 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 |
| 13 | const SOCKSPort uint16 = 1080 |
| 14 | |
| 15 | // socksHandler implements a socksproxy.Handler which permits and logs |
| 16 | // connections to the nanoswitch network. |
| 17 | type socksHandler struct{} |
| 18 | |
| 19 | func (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. |
| 61 | func 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 | } |