@@ -10,6 +10,7 @@ import (
1010 "os"
1111 "path"
1212 "strings"
13+ "sync/atomic"
1314
1415 "github.com/caddyserver/caddy/v2"
1516 "github.com/caddyserver/caddy/v2/caddyconfig"
@@ -22,6 +23,7 @@ import (
2223
2324var (
2425 servers = caddy .NewUsagePool ()
26+ tsapp = atomic.Pointer [TSApp ]{}
2527)
2628
2729func init () {
@@ -47,7 +49,10 @@ func getPlainListener(_ context.Context, _ string, addr string, _ net.ListenConf
4749 network = "tcp"
4850 }
4951
50- return s .Listen (network , ":" + port )
52+ ln := & tsnetServerDestructor {
53+ Server : s .Server ,
54+ }
55+ return ln .Listen (network , ":" + port )
5156}
5257
5358func getTLSListener (_ context.Context , _ string , addr string , _ net.ListenConfig ) (any , error ) {
@@ -105,11 +110,9 @@ func getServer(_, addr string) (*tsnetServerDestructor, error) {
105110 }
106111
107112 if host != "" {
108- // Set authkey to "TS_AUTHKEY_<HOST>". If empty,
109- // fall back to "TS_AUTHKEY".
110- s .AuthKey = os .Getenv ("TS_AUTHKEY_" + strings .ToUpper (host ))
111- if s .AuthKey == "" {
112- s .AuthKey = os .Getenv ("TS_AUTHKEY" )
113+ if app := tsapp .Load (); app != nil {
114+ s .AuthKey = getAuthKey (host , app )
115+ s .Ephemeral = getEphemeral (host , app )
113116 }
114117
115118 // Set config directory for tsnet. By default, tsnet will use the name of the
@@ -136,6 +139,39 @@ func getServer(_, addr string) (*tsnetServerDestructor, error) {
136139 return s .(* tsnetServerDestructor ), nil
137140}
138141
142+ func getAuthKey (host string , app * TSApp ) string {
143+ if app == nil {
144+ return ""
145+ }
146+ svr := app .Servers [host ]
147+ if svr .AuthKey != "" {
148+ return svr .AuthKey
149+ }
150+
151+ if app .DefaultAuthKey != "" {
152+ return app .DefaultAuthKey
153+ }
154+
155+ // Set authkey to "TS_AUTHKEY_<HOST>". If empty,
156+ // fall back to "TS_AUTHKEY".
157+ authKey := os .Getenv ("TS_AUTHKEY_" + strings .ToUpper (host ))
158+ if authKey == "" {
159+ authKey = os .Getenv ("TS_AUTHKEY" )
160+ }
161+ return authKey
162+ }
163+
164+ func getEphemeral (host string , app * TSApp ) bool {
165+ if app == nil {
166+ return false
167+ }
168+ if svr , ok := app .Servers [host ]; ok {
169+ return svr .Ephemeral
170+ }
171+
172+ return app .Ephemeral
173+ }
174+
139175type TailscaleAuth struct {
140176 localclient * tailscale.LocalClient
141177}
@@ -234,3 +270,31 @@ type tsnetServerDestructor struct {
234270func (t tsnetServerDestructor ) Destruct () error {
235271 return t .Close ()
236272}
273+
274+ func (t * tsnetServerDestructor ) Listen (network string , addr string ) (net.Listener , error ) {
275+ ln , err := t .Server .Listen (network , addr )
276+ if err != nil {
277+ return nil , err
278+ }
279+ serverListener := & tsnetServerListener {
280+ hostname : t .Hostname ,
281+ Listener : ln ,
282+ }
283+ return serverListener , nil
284+ }
285+
286+ type tsnetServerListener struct {
287+ hostname string
288+ net.Listener
289+ }
290+
291+ func (t * tsnetServerListener ) Close () error {
292+ if err := t .Listener .Close (); err != nil {
293+ return err
294+ }
295+
296+ // Decrement usage count of server for this hostname.
297+ // If usage reaches zero, then the server is actually shutdown.
298+ _ , err := servers .Delete (t .hostname )
299+ return err
300+ }
0 commit comments