@@ -2,13 +2,19 @@ package main
22
33import (
44 "bytes"
5+ "errors"
56 "flag"
67 "fmt"
78 "io/ioutil"
89 "log"
10+ "net"
911 "net/http"
1012 "net/http/httputil"
13+ "os"
1114 "path"
15+ "runtime"
16+ "strconv"
17+ "syscall"
1218
1319 "github.com/projectdiscovery/gologger"
1420)
@@ -55,13 +61,29 @@ func main() {
5561 if opts .Upload {
5662 gologger .Print ().Msgf ("Upload enabled" )
5763 }
64+ retry_listen:
65+ var err error
5866 if opts .HTTPS {
5967 if opts .Certificate == "" || opts .Key == "" {
6068 gologger .Fatal ().Msgf ("Certificate or Key file not specified" )
6169 }
62- gologger .Print ().Msgf ("%s\n " , http .ListenAndServeTLS (opts .ListenAddress , opts .Certificate , opts .Key , layers ))
70+ err = http .ListenAndServeTLS (opts .ListenAddress , opts .Certificate , opts .Key , layers )
71+
6372 } else {
64- gologger .Print ().Msgf ("%s\n " , http .ListenAndServe (opts .ListenAddress , layers ))
73+ err = http .ListenAndServe (opts .ListenAddress , layers )
74+ gologger .Print ().Msgf ("%s\n " )
75+ }
76+ if err != nil {
77+ if isErrorAddressAlreadyInUse (err ) {
78+ gologger .Warning ().Msgf ("Can't listen on %s: %s - retrying with another port\n " , opts .ListenAddress , err )
79+ newListenAddress , err := incPort (opts .ListenAddress )
80+ if err != nil {
81+ gologger .Fatal ().Msgf ("%s\n " , err )
82+ }
83+ opts .ListenAddress = newListenAddress
84+ goto retry_listen
85+ }
86+ gologger .Warning ().Msgf ("%s\n " , err )
6587 }
6688}
6789
@@ -133,3 +155,39 @@ func (lrw *loggingResponseWriter) WriteHeader(code int) {
133155func handleUpload (file string , data []byte ) error {
134156 return ioutil .WriteFile (file , data , 0655 )
135157}
158+
159+ func isErrorAddressAlreadyInUse (err error ) bool {
160+ var eOsSyscall * os.SyscallError
161+ if ! errors .As (err , & eOsSyscall ) {
162+ return false
163+ }
164+ var errErrno syscall.Errno // doesn't need a "*" (ptr) because it's already a ptr (uintptr)
165+ if ! errors .As (eOsSyscall , & errErrno ) {
166+ return false
167+ }
168+ if errErrno == syscall .EADDRINUSE {
169+ return true
170+ }
171+ const WSAEADDRINUSE = 10048
172+ if runtime .GOOS == "windows" && errErrno == WSAEADDRINUSE {
173+ return true
174+ }
175+ return false
176+ }
177+
178+ func incPort (address string ) (string , error ) {
179+ addrOrig , portOrig , err := net .SplitHostPort (address )
180+ if err != nil {
181+ return address , err
182+ }
183+
184+ // increment port
185+ portNumber , err := strconv .Atoi (portOrig )
186+ if err != nil {
187+ return address , err
188+ }
189+ portNumber ++
190+ newPort := strconv .FormatInt (int64 (portNumber ), 10 )
191+
192+ return net .JoinHostPort (addrOrig , newPort ), nil
193+ }
0 commit comments