blob: 1230903fb73e939673416e599e2b894e33bc352f [file] [log] [blame]
Serge Bazanskibe742842022-04-04 13:18:50 +02001package main
2
3import (
4 "context"
5 "fmt"
6 "net"
7
Tim Windelschmidt9f21f532024-05-07 15:14:20 +02008 "source.monogon.dev/osbase/socksproxy"
9 "source.monogon.dev/osbase/supervisor"
Serge Bazanskibe742842022-04-04 13:18:50 +020010)
11
Tim Windelschmidta3cd52c2024-04-18 23:21:16 +020012// SOCKSPort is the port at which nanoswitch listens for SOCKS conenctions.
13//
Tim Windelschmidt9f21f532024-05-07 15:14:20 +020014// ONCHANGE(//metropolis/test/launch:cluster.go): port must be kept in sync
Serge Bazanskibe742842022-04-04 13:18:50 +020015const 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 {
Tim Windelschmidtadcf5d72024-05-21 13:46:25 +020067 return fmt.Errorf("failed to listen on :%d : %w", SOCKSPort, err)
Serge Bazanskibe742842022-04-04 13:18:50 +020068 }
69
70 h := &socksHandler{}
71 supervisor.Signal(ctx, supervisor.SignalHealthy)
72 return socksproxy.Serve(ctx, h, lis)
73}