@@ -13,6 +13,7 @@ import (
1313 "flag"
1414 "fmt"
1515 "io"
16+ "io/fs"
1617 "log"
1718 "net"
1819 "net/http"
@@ -22,6 +23,7 @@ import (
2223 "os/signal"
2324 "path/filepath"
2425 "runtime"
26+ "strconv"
2527 "strings"
2628 "syscall"
2729 "time"
@@ -160,6 +162,25 @@ func (a *hexArg) Value() []byte {
160162 return a .value
161163}
162164
165+ type modeArg fs.FileMode
166+
167+ func (a * modeArg ) String () string {
168+ return fmt .Sprintf ("%#o" , uint32 (* a ))
169+ }
170+
171+ func (a * modeArg ) Set (s string ) error {
172+ p , err := strconv .ParseUint (s , 8 , 32 )
173+ if err != nil {
174+ return err
175+ }
176+ * a = modeArg (p )
177+ return nil
178+ }
179+
180+ func (a * modeArg ) Value () fs.FileMode {
181+ return fs .FileMode (* a )
182+ }
183+
163184type cacheKind int
164185
165186const (
@@ -175,11 +196,17 @@ type autocertCache struct {
175196
176197const envCacheEncKey = "DUMBPROXY_CACHE_ENC_KEY"
177198
199+ type bindSpec struct {
200+ af string
201+ address string
202+ }
203+
178204type CLIArgs struct {
179- bindAddress string
180- bindUnixSocket string
205+ bind bindSpec
181206 bindReusePort bool
182- bindPprof string
207+ bindPprof bindSpec
208+ unixSockUnlink bool
209+ unixSockMode modeArg
183210 auth string
184211 verbosity int
185212 cert , key , cafile string
@@ -244,20 +271,35 @@ func parse_args() CLIArgs {
244271 kind : cacheKindDir ,
245272 value : filepath .Join (home , ".dumbproxy" , "autocert" ),
246273 },
274+ bind : bindSpec {
275+ address : ":8080" ,
276+ af : "tcp" ,
277+ },
247278 }
248279 args .autocertCacheEncKey .Set (os .Getenv (envCacheEncKey ))
249- flag .Func ("bind-address" , "HTTP proxy listen address. Set empty value to use systemd socket activation." , func (p string ) error {
250- args .bindAddress = p
251- args .bindUnixSocket = ""
280+ flag .Func ("bind-address" , "HTTP proxy listen address. Set empty value to use systemd socket activation. (default \" :8080 \" ) " , func (p string ) error {
281+ args .bind . address = p
282+ args .bind . af = "tcp "
252283 return nil
253284 })
254285 flag .Func ("bind-unix-socket" , "Unix domain socket to listen to, overrides bind-address if set." , func (p string ) error {
255- args .bindAddress = ""
256- args .bindUnixSocket = p
286+ args .bind . address = p
287+ args .bind . af = "unix"
257288 return nil
258289 })
259290 flag .BoolVar (& args .bindReusePort , "bind-reuseport" , false , "allow multiple server instances on the same port" )
260- flag .StringVar (& args .bindPprof , "bind-pprof" , "" , "enables pprof debug endpoints" )
291+ flag .Func ("bind-pprof" , "enables pprof debug endpoints" , func (p string ) error {
292+ args .bindPprof .address = p
293+ args .bindPprof .af = "tcp"
294+ return nil
295+ })
296+ flag .Func ("bind-pprof-unix-socket" , "enables pprof debug endpoints listening on Unix domain socket" , func (p string ) error {
297+ args .bindPprof .address = p
298+ args .bindPprof .af = "unix"
299+ return nil
300+ })
301+ flag .BoolVar (& args .unixSockUnlink , "unix-sock-unlink" , true , "delete file object located at Unix domain socket bind path before binding" )
302+ flag .Var (& args .unixSockMode , "unix-sock-mode" , "set file mode for bound unix socket" )
261303 flag .StringVar (& args .auth , "auth" , "none://" , "auth parameters" )
262304 flag .IntVar (& args .verbosity , "verbosity" , 20 , "logging verbosity " +
263305 "(10 - debug, 20 - info, 30 - warning, 40 - error, 50 - critical)" )
@@ -496,7 +538,6 @@ func run() int {
496538
497539 stopContext , _ := signal .NotifyContext (context .Background (), os .Interrupt , syscall .SIGTERM )
498540 server := http.Server {
499- Addr : args .bindAddress ,
500541 Handler : handler .NewProxyHandler (& handler.Config {
501542 Dialer : dialerRoot ,
502543 Auth : auth ,
@@ -526,17 +567,38 @@ func run() int {
526567 }
527568
528569 mainLogger .Info ("Starting proxy server..." )
529- var listener net.Listener
530- if args .bindUnixSocket != "" {
531- newListener , err := net .Listen ("unix" , args .bindUnixSocket )
532570
533- if err != nil {
534- mainLogger .Critical ("listen failed: %v" , err )
535- return 3
571+ listenerFactory := net .Listen
572+ if args .bindReusePort {
573+ if reuseport .Available () {
574+ listenerFactory = reuseport .Listen
575+ } else {
576+ mainLogger .Warning ("reuseport was requested but not available!" )
536577 }
578+ }
579+ if args .unixSockUnlink {
580+ listenerFactory = func (orig func (string , string ) (net.Listener , error )) func (string , string ) (net.Listener , error ) {
581+ return func (network , address string ) (net.Listener , error ) {
582+ if (network == "unix" || network == "unixdgram" ) && len (address ) > 0 && address [0 ] != '@' {
583+ os .Remove (address )
584+ }
585+ return orig (network , address )
586+ }
587+ }(listenerFactory )
588+ }
589+ if args .unixSockMode != 0 {
590+ listenerFactory = func (orig func (string , string ) (net.Listener , error )) func (string , string ) (net.Listener , error ) {
591+ return func (network , address string ) (net.Listener , error ) {
592+ if (network == "unix" || network == "unixdgram" ) && len (address ) > 0 && address [0 ] != '@' {
593+ defer os .Chmod (address , args .unixSockMode .Value ())
594+ }
595+ return orig (network , address )
596+ }
597+ }(listenerFactory )
598+ }
537599
538- listener = newListener
539- } else if args .bindAddress == "" {
600+ var listener net. Listener
601+ if args .bind . address == "" {
540602 // socket activation
541603 listeners , err := activation .Listeners ()
542604 if err != nil {
@@ -554,15 +616,7 @@ func run() int {
554616 }
555617 listener = listeners [0 ]
556618 } else {
557- listenerFactory := net .Listen
558- if args .bindReusePort {
559- if reuseport .Available () {
560- listenerFactory = reuseport .Listen
561- } else {
562- mainLogger .Warning ("reuseport was requested but not available!" )
563- }
564- }
565- newListener , err := listenerFactory ("tcp" , args .bindAddress )
619+ newListener , err := listenerFactory (args .bind .af , args .bind .address )
566620 if err != nil {
567621 mainLogger .Critical ("listen failed: %v" , err )
568622 return 3
@@ -648,14 +702,17 @@ func run() int {
648702 defer listener .Close ()
649703
650704 // debug endpoints setup
651- if args .bindPprof != "" {
705+ if args .bindPprof . address != "" {
652706 mux := http .NewServeMux ()
653707 mux .HandleFunc ("/debug/pprof/" , pprof .Index )
654708 mux .HandleFunc ("/debug/pprof/cmdline" , pprof .Cmdline )
655709 mux .HandleFunc ("/debug/pprof/profile" , pprof .Profile )
656710 mux .HandleFunc ("/debug/pprof/symbol" , pprof .Symbol )
657711 mux .HandleFunc ("/debug/pprof/trace" , pprof .Trace )
658- go func () { log .Fatal (http .ListenAndServe (args .bindPprof , mux )) }()
712+ pprofListener , err := listenerFactory (args .bindPprof .af , args .bindPprof .address )
713+ if err == nil {
714+ go func () { log .Fatal (http .Serve (pprofListener , mux )) }()
715+ }
659716 }
660717
661718 mainLogger .Info ("Proxy server started." )
0 commit comments