@@ -34,6 +34,7 @@ import (
3434 "tailscale.com/client/tailscale"
3535 "tailscale.com/hostinfo"
3636 "tailscale.com/ipn"
37+ "tailscale.com/ipn/ipnstate"
3738 "tailscale.com/tailcfg"
3839 "tailscale.com/tsnet"
3940)
4950 hostname = flag .String ("hostname" , defaultHostname , "service name" )
5051 resolveFromBackup = flag .String ("resolve-from-backup" , "" , "resolve a link from snapshot file and exit" )
5152 allowUnknownUsers = flag .Bool ("allow-unknown-users" , false , "allow unknown users to save links" )
53+ useTailscaled = flag .Bool ("use-tailscaled" , false , "use tailscaled instead of tsnet" )
5254)
5355
5456var stats struct {
@@ -154,6 +156,41 @@ func Run() error {
154156 log .Fatal (http .ListenAndServe (* dev , serveHandler ()))
155157 }
156158
159+ if * useTailscaled {
160+ localClient = & tailscale.LocalClient {}
161+ var st * ipnstate.Status
162+ for {
163+ ctx , cancel := context .WithTimeout (context .Background (), time .Second * 10 )
164+ st , err = localClient .StatusWithoutPeers (ctx )
165+ cancel ()
166+ if err != nil {
167+ return err
168+ }
169+ if st .BackendState == "Running" {
170+ break
171+ }
172+ log .Printf ("Waiting for backend to enter Running state; currently %s" , st .BackendState )
173+ time .Sleep (time .Second )
174+ }
175+
176+ anySuccess := false
177+ for _ , ip := range st .TailscaleIPs {
178+ l80 , err := net .Listen ("tcp" , net .JoinHostPort (ip .String (), "80" ))
179+ if err != nil {
180+ log .Printf ("Listen(%s): %v" , ip , err )
181+ continue
182+ }
183+ anySuccess = true
184+
185+ log .Printf ("Serving http://%s/ ..." , * hostname )
186+ go http .Serve (l80 , serveHandler ())
187+ }
188+ if ! anySuccess {
189+ return errors .New ("unable to listen on any Tailscale IP" )
190+ }
191+ select {}
192+ }
193+
157194 if * hostname == "" {
158195 return errors .New ("--hostname, if specified, cannot be empty" )
159196 }
0 commit comments