Skip to content
File

Blob: cmd/client/listen.go

go68 lines
1package client
2 
3import (
4 "context"
5 "fmt"
6 "net"
7 "os"
8 "os/signal"
9 "syscall"
10 
11 "go.miragespace.co/specter/tun/client/connector"
12 "go.miragespace.co/specter/tun/client/dialer"
13 
14 "github.com/urfave/cli/v3"
15 "go.uber.org/zap"
16)
17 
18func cmdListen(ctx context.Context, cmd *cli.Command) error {
19 logger := cmd.Root().Metadata["logger"].(*zap.Logger)
20 
21 hostname := cmd.Args().First()
22 if hostname == "" {
23 return fmt.Errorf("missing hostname in argument")
24 }
25 
26 var (
27 remote net.Addr
28 dial dialer.TransportDialer
29 err error
30 )
31 
32 parsed, err := dialer.ParseApex(hostname)
33 if err != nil {
34 return fmt.Errorf("error parsing hostname: %w", err)
35 }
36 
37 if cmd.IsSet("tcp") {
38 remote, dial, err = tlsDialer(ctx, cmd, logger, parsed, false)
39 } else {
40 remote, dial, err = quicDialer(ctx, cmd, logger, parsed, false)
41 }
42 if err != nil {
43 return fmt.Errorf("error dialing specter gateway: %w", err)
44 }
45 
46 listener, err := net.Listen("tcp", cmd.String("listen"))
47 if err != nil {
48 return err
49 }
50 defer listener.Close()
51 
52 logger.Info("listening for local connections", zap.String("listen", listener.Addr().String()), zap.String("via", remote.String()))
53 
54 go connector.HandleConnections(logger, listener, dial)
55 
56 sigs := make(chan os.Signal, 1)
57 signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
58 
59 select {
60 case sig := <-sigs:
61 logger.Info("received signal to stop", zap.String("signal", sig.String()))
62 case <-ctx.Done():
63 logger.Info("context done", zap.Error(ctx.Err()))
64 }
65 
66 return nil
67}