| 37 | } |
| 38 | |
| 39 | func (s *Server) Start(ctx context.Context) error { |
| 40 | var err error |
| 41 | if s.ln, err = new(net.ListenConfig).Listen(ctx, "tcp", s.Addr); err != nil { |
| 42 | return err |
| 43 | } |
| 44 | s.Addr = s.ln.Addr().String() |
| 45 | |
| 46 | s.proxy = &tcpproxy.Proxy{ |
| 47 | ListenFunc: func(string, string) (net.Listener, error) { |
| 48 | return s.ln, nil |
| 49 | }, |
| 50 | } |
| 51 | |
| 52 | lnTLS := &tcpproxy.TargetListener{ |
| 53 | Address: s.Addr, |
| 54 | } |
| 55 | |
| 56 | s.proxy.AddSNIRouteFunc(s.Addr, func(context.Context, string) (tcpproxy.Target, bool) { |
| 57 | return lnTLS, true |
| 58 | }) |
| 59 | |
| 60 | lnHTTP := &tcpproxy.TargetListener{ |
| 61 | Address: s.Addr, |
| 62 | } |
| 63 | |
| 64 | s.proxy.AddRoute(s.Addr, lnHTTP) |
| 65 | |
| 66 | s.server = &http.Server{ |
| 67 | Addr: s.Addr, |
| 68 | |
| 69 | Handler: http.HandlerFunc(s.serveHTTP), |
| 70 | |
| 71 | BaseContext: func(net.Listener) context.Context { return ctx }, |
| 72 | ErrorLog: discardLogger, |
| 73 | } |
| 74 | |
| 75 | s.errg.Go(func() error { |
| 76 | return s.server.Serve(lnHTTP) |
| 77 | }) |
| 78 | s.errg.Go(func() error { |
| 79 | return s.server.Serve(tls.NewListener(lnTLS, &tls.Config{ |
| 80 | NextProtos: []string{"h2", "http/1.1"}, |
| 81 | GetCertificate: s.getCertificate, |
| 82 | })) |
| 83 | }) |
| 84 | |
| 85 | s.tlsc = make(chan struct{}) |
| 86 | return s.proxy.Start() |
| 87 | } |
| 88 | |
| 89 | func (s *Server) EnableTLS() { |
| 90 | s.tlso.Do(func() { close(s.tlsc) }) |