blob: a85e9a34b5468be5c1f3dc9e4d4ca4fa4518fed7 [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
Tim Windelschmidta3cd52c2024-04-18 23:21:16 +020012// SOCKSPort is the port at which nanoswitch listens for SOCKS conenctions.
13//
Serge Bazanskibe742842022-04-04 13:18:50 +020014// ONCHANGE(//metropolis/test/launch/cluster:cluster.go): port must be kept in sync
15const SOCKSPort uint16 = 1080
16
17// socksHandler implements a socksproxy.Handler which permits and logs
18// connections to the nanoswitch network.
19type socksHandler struct{}
20
21func (s *socksHandler) Connect(ctx context.Context, req *socksproxy.ConnectRequest) *socksproxy.ConnectResponse {
22 logger := supervisor.Logger(ctx)
23 target := net.JoinHostPort(req.Address.String(), fmt.Sprintf("%d", req.Port))
24
25 if len(req.Address) != 4 {
26 logger.Warningf("Connect %s: wrong address type", target)
27 return &socksproxy.ConnectResponse{
28 Error: socksproxy.ReplyAddressTypeNotSupported,
29 }
30 }
31
32 addr := req.Address
33 switchCIDR := net.IPNet{
34 IP: switchIP.Mask(switchSubnetMask),
35 Mask: switchSubnetMask,
36 }
37 if !switchCIDR.Contains(addr) || switchCIDR.IP.Equal(addr) {
38 logger.Warningf("Connect %s: not in switch network", target)
39 return &socksproxy.ConnectResponse{
40 Error: socksproxy.ReplyNetworkUnreachable,
41 }
42 }
43
44 con, err := net.Dial("tcp", target)
45 if err != nil {
46 logger.Warningf("Connect %s: dial failed: %v", target, err)
47 return &socksproxy.ConnectResponse{
48 Error: socksproxy.ReplyHostUnreachable,
49 }
50 }
51 res, err := socksproxy.ConnectResponseFromConn(con)
52 if err != nil {
53 logger.Warningf("Connect %s: could not make SOCKS response: %v", target, err)
Serge Bazanski1ec1fe92023-03-22 18:29:28 +010054 con.Close()
Serge Bazanskibe742842022-04-04 13:18:50 +020055 return &socksproxy.ConnectResponse{
56 Error: socksproxy.ReplyGeneralFailure,
57 }
58 }
59 logger.Infof("Connect %s: established", target)
60 return res
61}
62
63// runSOCKSProxy starts a SOCKS proxy to the nanoswitchnetwork at SOCKSPort.
64func runSOCKSProxy(ctx context.Context) error {
65 lis, err := net.Listen("tcp", fmt.Sprintf(":%d", SOCKSPort))
66 if err != nil {
67 return fmt.Errorf("failed to listen on :%d : %v", SOCKSPort, err)
68 }
69
70 h := &socksHandler{}
71 supervisor.Signal(ctx, supervisor.SignalHealthy)
72 return socksproxy.Serve(ctx, h, lis)
73}