|
63 | 63 | (.isSiteLocalAddress (InetAddress/getByName ip)) |
64 | 64 | (catch Exception _ false))) |
65 | 65 |
|
66 | | -(defn ^:private try-start-jetty |
67 | | - "Attempts to start Jetty on the given port. Returns the Server on success, |
68 | | - nil when the port is already in use (BindException or Jetty's wrapping IOException)." |
| 66 | +(def ^:private bind-hosts |
| 67 | + "Ordered list of bind addresses to try per port. |
| 68 | + 0.0.0.0 gives full connectivity; 127.0.0.1 is the fallback when another |
| 69 | + service (e.g. Tailscale) already holds the port on a specific interface." |
| 70 | + ["0.0.0.0" "127.0.0.1"]) |
| 71 | + |
| 72 | +(defn ^:private try-start-jetty-any-host |
| 73 | + "Tries to start Jetty on the given port, attempting each bind address in |
| 74 | + bind-hosts order. Returns the Server on success, nil if all fail." |
69 | 75 | ^Server [handler port] |
70 | | - (try |
71 | | - (jetty/run-jetty handler {:port port :host "0.0.0.0" :join? false}) |
72 | | - (catch BindException _ nil) |
73 | | - (catch IOException _ nil))) |
| 76 | + (reduce (fn [_ bind-host] |
| 77 | + (try |
| 78 | + (let [server (jetty/run-jetty handler {:port port :host bind-host :join? false})] |
| 79 | + (logger/debug logger-tag (str "Bound to " bind-host ":" port)) |
| 80 | + (reduced server)) |
| 81 | + (catch BindException _ nil) |
| 82 | + (catch IOException _ nil))) |
| 83 | + nil |
| 84 | + bind-hosts)) |
74 | 85 |
|
75 | 86 | (defn ^:private start-with-retry |
76 | 87 | "Tries sequential ports starting from base-port up to max-port-attempts. |
| 88 | + For each port, tries all bind-hosts before moving to the next port. |
77 | 89 | Returns [server actual-port] on success, nil if all attempts fail." |
78 | 90 | [handler base-port] |
79 | 91 | (loop [port base-port |
80 | 92 | attempts 0] |
81 | 93 | (when (< attempts max-port-attempts) |
82 | | - (if-let [server (try-start-jetty handler port)] |
| 94 | + (if-let [server (try-start-jetty-any-host handler port)] |
83 | 95 | [server (.getLocalPort ^NetworkConnector (first (.getConnectors ^Server server)))] |
84 | 96 | (do (logger/debug logger-tag (str "Port " port " in use, trying " (inc port) "...")) |
85 | 97 | (recur (inc port) (inc attempts))))))) |
|
106 | 118 | (try |
107 | 119 | (if-let [[^Server jetty-server actual-port] |
108 | 120 | (if user-port |
109 | | - ;; User-specified port: single attempt, no retry |
110 | | - (if-let [server (try-start-jetty handler user-port)] |
| 121 | + ;; User-specified port: single attempt, try all bind hosts |
| 122 | + (if-let [server (try-start-jetty-any-host handler user-port)] |
111 | 123 | [server (.getLocalPort ^NetworkConnector (first (.getConnectors ^Server server)))] |
112 | 124 | (do (logger/warn logger-tag "Port" user-port "is already in use." |
113 | 125 | "Remote server will not start.") |
|
0 commit comments