remove unnecessary configs

Kim committed Oct 21, 2025 at 18:43 UTC 2c91f7c321641fe4dbe5e5ffaefdbac467ec935c
8 files changed +193 -179
Makefile
+6 -12
@@ -17,15 +17,10 @@ server-build:
17 # ---------- Client (local go) ----------
18 # Default flags (override via `make VAR=value`)
19 SERVER_URL ?= http://localhost:8080
20 -BACKEND_HTTP ?= :8081
21 -# Optional repeated flags: BOOTSTRAPS="/dnsaddr/example/p2p/12D3... /ip4/1.2.3.4/tcp/4001/p2p/12D3..."
22 -BOOTSTRAPS ?=
23 -CLIENT_BOOTSTRAPS_FLAGS := $(foreach b,$(BOOTSTRAPS),--bootstrap $(b))
24 -
20 +BACKEND_PORT ?= 8081
21 CLIENT_FLAGS := \
22 --server-url $(SERVER_URL) \
27 - --backend-http $(BACKEND_HTTP) \
28 - $(CLIENT_BOOTSTRAPS_FLAGS)
23 + --port $(BACKEND_PORT)
24
25 client-run:
26 go run ./cmd/example_http_client $(CLIENT_FLAGS)
@@ -34,14 +29,13 @@ client-build:
29 go build -trimpath -o bin/relaydns-client ./cmd/example_http_client
30
31 # ---------- Chat (local go) ----------
37 -CHAT_ADDR ?= :8091
32 +CHAT_PORT ?= 8091
33 CHAT_NAME ?= demo-chat
34
35 CHAT_FLAGS := \
36 --server-url $(SERVER_URL) \
42 - --addr $(CHAT_ADDR) \
43 - --name $(CHAT_NAME) \
44 - $(CLIENT_BOOTSTRAPS_FLAGS)
37 + --port $(CHAT_PORT) \
38 + --name $(CHAT_NAME)
39
40 chat-run:
41 go run ./cmd/example_chat $(CHAT_FLAGS)
@@ -66,4 +60,4 @@ help:
60 @echo " make chat-run # run example_chat locally (WS UI + advertiser)"
61 @echo " make chat-build # build example_chat to ./bin/relaydns-chat"
62 @echo "\nFlags (override with make VAR=value):"
69 - @echo " SERVER_URL BACKEND_HTTP BOOTSTRAPS CHAT_ADDR CHAT_NAME"
63 + @echo " SERVER_URL BACKEND_PORT CHAT_PORT CHAT_NAME"
README.md
+6 -10
@@ -45,16 +45,14 @@ Clients are NOT required to run the server. They are provided for testing/demo.
45 ```bash
46 make client-run
47 # Optional overrides:
48 - # make client-run BACKEND_HTTP=:8081 SERVER_URL=http://localhost:8080 \
49 - # BOOTSTRAPS="/dnsaddr/your.bootstrap/p2p/12D3Koo..."
48 + # make client-run BACKEND_PORT=8081 SERVER_URL=http://localhost:8080
49 ```
50
51 - Chat client (optional): WebSocket chat UI (local) + advertiser (libp2p). Uses coder/websocket.
52 ```bash
53 make chat-run
54 # Optional overrides:
56 - # make chat-run CHAT_ADDR=:8091 CHAT_NAME=demo-chat SERVER_URL=http://localhost:8080 \
57 - # BOOTSTRAPS="/ip4/1.2.3.4/tcp/4001/p2p/12D3Koo..."
55 + # make chat-run CHAT_PORT=8091 CHAT_NAME=demo-chat SERVER_URL=http://localhost:8080
56 ```
57
58 If you run the chat client:
@@ -101,20 +99,18 @@ Server flags (see `docker-compose.yml`):
99
100 HTTP client flags (see `make client-run`):
101 - `--server-url` Admin base URL to fetch `/health` (default `http://localhost:8080`)
104 -- `--bootstrap` Repeatable multiaddr with `/p2p/`
105 -- `--backend-http` Local backend HTTP listen address (default `:8081`)
102 +- `--port` Local backend HTTP port (default `8081`)
103
104 Chat client flags (see `make chat-run`):
105 - `--server-url` Admin base URL to fetch `/health` (default `http://localhost:8080`)
109 -- `--bootstrap` Repeatable multiaddr with `/p2p/`
110 -- `--addr` Local chat HTTP listen address (default `:8091`)
106 +- `--port` Local chat HTTP port (default `8091`)
107 - `--name` Display name (shown on server UI)
108
109 ## Deploying the Server (public)
110
111 - Expose ports:
116 - - `8080/tcp` Admin UI + HTTP/WS proxy (`/peer/<peerID>/`)
117 - - `4001/tcp` and `4001/udp` libp2p (GossipSub/streams)
112 + - `8080/tcp` Admin UI + HTTP/WS proxy (`/peer/<peerID>/`) — flag: `--http-port`
113 + - `4001/tcp` and `4001/udp` libp2p (GossipSub/streams) — flag: `--p2p-port`
114 - Cloudflare DNS:
115 - Web UI/proxy (8080): can be proxied (orange cloud) if using HTTP/HTTPS
116 - libp2p (4001 tcp/udp): must be DNS only (gray cloud). Cloudflare proxy doesn’t support arbitrary TCP/UDP ports.
cmd/example_chat/main.go
+10 -21
@@ -22,22 +22,16 @@ var rootCmd = &cobra.Command{
22 }
23
24 var (
25 - flagServerURL string
26 - flagBootstraps []string
27 - flagAddr string
28 - flagName string
29 - flagProtocol string
30 - flagTopic string
25 + flagServerURL string
26 + flagPort int
27 + flagName string
28 )
29
30 func init() {
31 flags := rootCmd.PersistentFlags()
32 flags.StringVar(&flagServerURL, "server-url", "http://localhost:8080", "relayserver base URL to auto-fetch multiaddrs from /health")
36 - flags.StringSliceVar(&flagBootstraps, "bootstrap", nil, "multiaddrs with /p2p/ (supports /dnsaddr/ that resolves to /p2p/)")
37 - flags.StringVar(&flagAddr, "addr", ":8091", "local chat HTTP listen address")
33 + flags.IntVar(&flagPort, "port", 8091, "local chat HTTP port")
34 flags.StringVar(&flagName, "name", "demo-chat", "backend display name")
39 - flags.StringVar(&flagProtocol, "protocol", "/relaydns/http/1.0", "libp2p protocol id for streams (must match server)")
40 - flags.StringVar(&flagTopic, "topic", "relaydns.backends", "pubsub topic for backend adverts")
35 }
36
37 func main() {
@@ -51,7 +45,7 @@ func runChat(cmd *cobra.Command, args []string) error {
45 defer cancel()
46
47 // 1) start local chat HTTP backend
54 - ln, err := net.Listen("tcp", flagAddr)
48 + ln, err := net.Listen("tcp", fmt.Sprintf(":%d", flagPort))
49 if err != nil {
50 return fmt.Errorf("listen chat: %w", err)
51 }
@@ -70,17 +64,12 @@ func runChat(cmd *cobra.Command, args []string) error {
64
65 // 2) advertise over RelayDNS (HTTP tunneled via server /peer route)
66 client, err := relaydns.NewClient(ctx, relaydns.ClientConfig{
73 - Protocol: flagProtocol,
74 - Topic: flagTopic,
75 - AdvertiseEvery: 3 * time.Second,
76 - Name: flagName,
77 - TargetTCP: relaydns.AddrToTarget(flagAddr),
67 + Name: flagName,
68 + TargetTCP: relaydns.AddrToTarget(fmt.Sprintf(":%d", flagPort)),
69 + ServerURL: flagServerURL,
70
79 - ServerURL: flagServerURL,
80 - Bootstraps: flagBootstraps,
81 - HTTPTimeout: 5 * time.Second,
82 - PreferQUIC: true,
83 - PreferLocal: true,
71 + Protocol: relaydns.DefaultProtocol,
72 + Topic: relaydns.DefaultTopic,
73 })
74 if err != nil {
75 return fmt.Errorf("new client: %w", err)
cmd/example_http_client/main.go
+14 -25
@@ -22,22 +22,16 @@ var rootCmd = &cobra.Command{
22 }
23
24 var (
25 - flagServerURL string
26 - flagBootstraps []string
27 - flagAddr string
28 - flagClientName string
29 - flagProtocol string
30 - flagTopic string
25 + flagServerURL string
26 + flagPort int
27 + flagName string
28 )
29
30 func init() {
31 flags := rootCmd.PersistentFlags()
32 flags.StringVar(&flagServerURL, "server-url", "http://localhost:8080", "relayserver admin base URL to auto-fetch multiaddrs from /health")
36 - flags.StringSliceVar(&flagBootstraps, "bootstrap", nil, "multiaddrs with /p2p/ (supports /dnsaddr/ that resolves to /p2p/)")
37 - flags.StringVar(&flagAddr, "addr", ":8081", "local backend HTTP listen address")
38 - flags.StringVar(&flagClientName, "name", "", "backend display name shown on server UI")
39 - flags.StringVar(&flagProtocol, "protocol", "/relaydns/http/1.0", "libp2p protocol id for streams (must match server)")
40 - flags.StringVar(&flagTopic, "topic", "relaydns.backends", "pubsub topic for backend adverts")
33 + flags.IntVar(&flagPort, "port", 8081, "local backend HTTP port")
34 + flags.StringVar(&flagName, "name", "", "backend display name shown on server UI")
35 }
36
37 func main() {
@@ -50,24 +44,24 @@ func runClient(cmd *cobra.Command, args []string) error {
44 ctx, cancel := context.WithCancel(context.Background())
45 defer cancel()
46
53 - if flagClientName == "" {
47 + if flagName == "" {
48 hn, err := os.Hostname()
49 if err != nil {
50 hn = "unknown-" + rand.Text()
51 }
58 - flagClientName = hn
52 + flagName = hn
53 }
54
55 // 1) HTTP backend
56 var clientRef *relaydns.RelayClient
63 - ln, err := net.Listen("tcp", flagAddr)
57 + ln, err := net.Listen("tcp", fmt.Sprintf(":%d", flagPort))
58 if err != nil {
59 log.Fatal().Err(err).Msg("failed to listen")
60 }
61 log.Info().Msgf("[client] local backend http listening on %s", ln.Addr().String())
62
63 // Serve local backend view in a goroutine
70 - go serveClientHTTP(ctx, ln, flagClientName, func() string {
64 + go serveClientHTTP(ctx, ln, flagName, func() string {
65 if clientRef == nil {
66 return "Starting..."
67 }
@@ -76,17 +70,12 @@ func runClient(cmd *cobra.Command, args []string) error {
70
71 // 2) libp2p host
72 client, err := relaydns.NewClient(ctx, relaydns.ClientConfig{
79 - Protocol: flagProtocol,
80 - Topic: flagTopic,
81 - AdvertiseEvery: 3 * time.Second,
82 - Name: flagClientName,
83 - TargetTCP: relaydns.AddrToTarget(flagAddr),
73 + Name: flagName,
74 + TargetTCP: relaydns.AddrToTarget(fmt.Sprintf(":%d", flagPort)),
75 + ServerURL: flagServerURL,
76
85 - ServerURL: flagServerURL,
86 - Bootstraps: flagBootstraps,
87 - HTTPTimeout: 5 * time.Second,
88 - PreferQUIC: true,
89 - PreferLocal: true,
77 + Protocol: relaydns.DefaultProtocol,
78 + Topic: relaydns.DefaultTopic,
79 })
80 if err != nil {
81 return fmt.Errorf("new client: %w", err)
cmd/server/main.go
+12 -20
@@ -2,6 +2,7 @@ package main
2
3 import (
4 "context"
5 + "fmt"
6 "net"
7 "os"
8 "os/signal"
@@ -20,22 +21,16 @@ var rootCmd = &cobra.Command{
21 }
22
23 var (
23 - flagBootstraps []string
24 -
25 - httpAddr string // unified admin + HTTP proxy (e.g. :8080)
26 - protocol string
27 - topic string
28 - tcpAddr string // optional raw TCP ingress (e.g. :2222 for SSH)
24 + flagP2pPort int // libp2p outbound TCP/UDP port (e.g. 4001)
25 + flagHttpPort int // admin UI + HTTP proxy port (e.g. 8080)
26 + flagTcpPort int // optional raw TCP ingress port (0 to disable)
27 )
28
29 func init() {
30 flags := rootCmd.PersistentFlags()
33 - flags.StringSliceVar(&flagBootstraps, "bootstrap", nil, "multiaddrs with /p2p/ (supports /dnsaddr/ that resolves to /p2p/)")
34 -
35 - flags.StringVar(&httpAddr, "http", ":8080", "Unified admin UI and HTTP proxy listen address")
36 - flags.StringVar(&protocol, "protocol", "/relaydns/http/1.0", "libp2p protocol id for streams (must match clients)")
37 - flags.StringVar(&topic, "topic", "relaydns.backends", "pubsub topic for backend adverts")
38 - flags.StringVar(&tcpAddr, "tcp", "", "Optional raw TCP ingress (e.g. :2222 for SSH). Empty to disable")
31 + flags.IntVar(&flagHttpPort, "http-port", 8080, "admin UI and HTTP proxy port")
32 + flags.IntVar(&flagP2pPort, "p2p-port", 4001, "libp2p outbound TCP/UDP port")
33 + flags.IntVar(&flagTcpPort, "tcp-port", 0, "optional raw TCP ingress port (0 to disable)")
34 }
35
36 func main() {
@@ -48,24 +43,21 @@ func runServer(cmd *cobra.Command, args []string) error {
43 ctx, cancel := context.WithCancel(context.Background())
44 defer cancel()
45
51 - const outBoundPort = 4001
52 - h, err := relaydns.MakeHost(ctx, outBoundPort, true)
46 + h, err := relaydns.MakeHost(ctx, flagP2pPort, true)
47 if err != nil {
48 return err
49 }
56 - relaydns.ConnectBootstraps(ctx, h, flagBootstraps)
57 -
58 - d, err := relaydns.NewRelayServer(ctx, h, protocol, topic)
50 + d, err := relaydns.NewRelayServer(ctx, h, relaydns.DefaultProtocol, relaydns.DefaultTopic)
51 if err != nil {
52 return err
53 }
54
55 // Admin UI + per-peer HTTP proxy served here
64 - go serveHTTP(ctx, httpAddr, d, h, cancel)
56 + go serveHTTP(ctx, fmt.Sprintf(":%d", flagHttpPort), d, h, cancel)
57
58 // Optional raw TCP ingress (e.g., SSH)
67 - if tcpAddr != "" {
68 - go serveTCPIngress(ctx, tcpAddr, d)
59 + if flagTcpPort > 0 {
60 + go serveTCPIngress(ctx, fmt.Sprintf(":%d", flagTcpPort), d)
61 }
62
63 // graceful shutdown
docker-compose.yml
+4 -5
@@ -7,11 +7,10 @@ services:
7 dockerfile: Dockerfile
8 image: dreamcacao/relaydns:latest
9 command:
10 - - "--http"
11 - - ":8080"
12 - # To add bootstraps, add more lines like below (repeatable):
13 - # - "--bootstrap"
14 - # - "/dnsaddr/bootstrap.example/p2p/12D3Koo..."
10 + - "--http-port"
11 + - "8080"
12 + - "--p2p-port"
13 + - "4001"
14 ports:
15 - "8080:8080" # Admin UI + HTTP proxy
16 - "4001:4001/tcp" # libp2p tcp
relaydns/client.go
+130 -81
@@ -58,27 +58,43 @@ type RelayClient struct {
58 serverHealthy bool
59 }
60
61 -// NewClient constructs a client with defaults applied and an initialized libp2p host.
62 -// It does not start networking. Call Start(ctx) to begin handlers, pubsub, and advertising.
63 -func NewClient(ctx context.Context, cfg ClientConfig) (*RelayClient, error) {
61 +// sensible defaults for optional client config
62 +const (
63 + defaultAdvertiseEvery = 5 * time.Second
64 + defaultHTTPTimeout = 3 * time.Second
65 + defaultRefreshBootstraps = 20 * time.Second
66 +)
67 +
68 +// applyDefaults fills zero-values in cfg with sane defaults.
69 +func applyDefaults(cfg ClientConfig) ClientConfig {
70 if cfg.AdvertiseEvery <= 0 {
65 - cfg.AdvertiseEvery = 5 * time.Second
71 + cfg.AdvertiseEvery = defaultAdvertiseEvery
72 }
73 if cfg.AdvertiseTTL <= 0 {
74 cfg.AdvertiseTTL = 10 * cfg.AdvertiseEvery
75 }
76 if cfg.HTTPTimeout <= 0 {
71 - cfg.HTTPTimeout = 3 * time.Second
72 - }
73 - if cfg.RefreshBootstrapsEvery <= 0 {
74 - cfg.RefreshBootstrapsEvery = 20 * time.Second
75 - }
76 - if cfg.Protocol == "" {
77 - cfg.Protocol = "/relaydns/http/1.0"
77 + cfg.HTTPTimeout = defaultHTTPTimeout
78 }
79 + if cfg.RefreshBootstrapsEvery <= 0 {
80 + cfg.RefreshBootstrapsEvery = defaultRefreshBootstraps
81 + }
82 + // Always prefer QUIC and local addresses for better performance and locality.
83 + cfg.PreferQUIC = true
84 + cfg.PreferLocal = true
85 + if cfg.Protocol == "" {
86 + cfg.Protocol = DefaultProtocol
87 + }
88 if cfg.Topic == "" {
80 - cfg.Topic = "relaydns.backends"
89 + cfg.Topic = DefaultTopic
90 }
91 + return cfg
92 +}
93 +
94 +// NewClient constructs a client with defaults applied and an initialized libp2p host.
95 +// It does not start networking. Call Start(ctx) to begin handlers, pubsub, and advertising.
96 +func NewClient(ctx context.Context, cfg ClientConfig) (*RelayClient, error) {
97 + cfg = applyDefaults(cfg)
98
99 h, err := MakeHost(ctx, 0, true)
100 if err != nil {
@@ -97,7 +113,68 @@ func (b *RelayClient) Start(ctx context.Context) error {
113 if b.stop != nil {
114 return fmt.Errorf("client already started")
115 }
100 - // resolve bootstraps (from flags and optional server health)
116 + // 1) resolve bootstraps (flags + optional server health)
117 + boot := b.resolveBootstraps()
118 + if len(boot) > 0 {
119 + ConnectBootstraps(ctx, b.h, boot)
120 + } else {
121 + log.Warn().Msg("relaydns: no bootstrap sources provided (Bootstraps/ServerURL); discovery may fail")
122 + }
123 +
124 + // 2) stream handler for inbound libp2p streams
125 + if err := b.setupStreamHandler(); err != nil {
126 + return err
127 + }
128 +
129 + // 3) pubsub join (for adverts)
130 + if err := b.joinPubSub(ctx); err != nil {
131 + return err
132 + }
133 +
134 + // 4) advertiser loop
135 + advCtx, cancel := context.WithCancel(ctx)
136 + b.stop = cancel
137 + b.wg.Add(1)
138 + b.startAdvertiser(advCtx)
139 +
140 + // 5) background: periodically re-fetch bootstraps from server and reconnect
141 + if b.cfg.ServerURL != "" {
142 + b.startRefreshLoop(advCtx)
143 + }
144 +
145 + if addrs := BuildAddrs(b.Host()); len(addrs) > 0 {
146 + for _, s := range addrs {
147 + log.Info().Msgf("[client] host addr: %s", s)
148 + }
149 + } else {
150 + log.Info().Msgf("[client] host peer: %s (no listen addrs yet)", b.Host().ID().String())
151 + }
152 +
153 + return nil
154 +}
155 +
156 +func (b *RelayClient) Host() host.Host {
157 + return b.h
158 +}
159 +
160 +func (b *RelayClient) Close() error {
161 + if b.stop != nil {
162 + b.stop()
163 + }
164 + b.wg.Wait()
165 + // leaving topic is optional; libp2p will clean up on host close
166 + return nil
167 +}
168 +
169 +func (b *RelayClient) setServerHealthy(ok bool) {
170 + b.statusMu.Lock()
171 + b.serverHealthy = ok
172 + b.statusMu.Unlock()
173 +}
174 +
175 +// resolveBootstraps merges configured bootstraps with optional server-provided
176 +// multiaddrs from /health. It updates serverHealthy accordingly.
177 +func (b *RelayClient) resolveBootstraps() []string {
178 boot := make([]string, 0, len(b.cfg.Bootstraps)+4)
179 if len(b.cfg.Bootstraps) > 0 {
180 boot = append(boot, b.cfg.Bootstraps...)
@@ -112,14 +189,11 @@ func (b *RelayClient) Start(ctx context.Context) error {
189 boot = append(boot, addrs...)
190 }
191 }
115 - boot = uniq(boot)
116 - if len(boot) > 0 {
117 - ConnectBootstraps(ctx, b.h, boot)
118 - } else {
119 - log.Warn().Msg("relaydns: no bootstrap sources provided (Bootstraps/ServerURL); discovery may fail")
120 - }
192 + return uniq(boot)
193 +}
194
122 - // stream handler
195 +// setupStreamHandler installs the appropriate libp2p stream handler.
196 +func (b *RelayClient) setupStreamHandler() error {
197 switch {
198 case b.cfg.Handler != nil:
199 b.h.SetStreamHandler(b.protoID, b.cfg.Handler)
@@ -139,8 +213,11 @@ func (b *RelayClient) Start(ctx context.Context) error {
213 default:
214 return fmt.Errorf("relaydns: either Handler or TargetTCP must be set")
215 }
216 + return nil
217 +}
218
143 - // pubsub join
219 +// joinPubSub creates a GossipSub instance and joins the advert topic.
220 +func (b *RelayClient) joinPubSub(ctx context.Context) error {
221 ps, err := pubsub.NewGossipSub(ctx, b.h, pubsub.WithMessageSigning(true))
222 if err != nil {
223 return err
@@ -150,10 +227,11 @@ func (b *RelayClient) Start(ctx context.Context) error {
227 return err
228 }
229 b.ps, b.t = ps, t
230 + return nil
231 +}
232
154 - // advertiser loop
155 - advCtx, cancel := context.WithCancel(ctx)
156 - b.stop = cancel
233 +// startAdvertiser periodically publishes Advertise messages with host addrs.
234 +func (b *RelayClient) startAdvertiser(ctx context.Context) {
235 b.wg.Add(1)
236 go func() {
237 defer b.wg.Done()
@@ -161,7 +239,7 @@ func (b *RelayClient) Start(ctx context.Context) error {
239 defer ticker.Stop()
240 for {
241 select {
164 - case <-advCtx.Done():
242 + case <-ctx.Done():
243 return
244 case <-ticker.C:
245 enc := BuildAddrs(b.h)
@@ -177,69 +255,40 @@ func (b *RelayClient) Start(ctx context.Context) error {
255 Proto: string(b.protoID),
256 }
257 payload, _ := json.Marshal(ad)
180 - _ = b.t.Publish(advCtx, payload)
258 + _ = b.t.Publish(ctx, payload)
259 }
260 }
261 }()
262 +}
263
185 - // background: periodically re-fetch bootstraps from server and reconnect
186 - if b.cfg.ServerURL != "" {
187 - b.wg.Add(1)
188 - go func() {
189 - defer b.wg.Done()
190 - t := time.NewTicker(b.cfg.RefreshBootstrapsEvery)
191 - defer t.Stop()
192 - for {
193 - select {
194 - case <-advCtx.Done():
195 - return
196 - case <-t.C:
197 - addrs, err := fetchMultiaddrsFromHealth(b.cfg.ServerURL, b.cfg.HTTPTimeout)
198 - if err != nil {
199 - b.setServerHealthy(false)
200 - log.Warn().Err(err).Msgf("refresh /health from %s failed", b.cfg.ServerURL)
201 - continue
202 - }
203 - b.setServerHealthy(true)
204 - sortMultiaddrs(addrs, b.cfg.PreferQUIC, b.cfg.PreferLocal)
205 - addrs = uniq(addrs)
206 - if len(addrs) > 0 {
207 - // Always attempt (re)connect; ConnectBootstraps handles dedupe and quiet logging
208 - ConnectBootstraps(ctx, b.h, addrs)
209 - }
264 +// startRefreshLoop periodically fetches /health and attempts (re)connects.
265 +func (b *RelayClient) startRefreshLoop(ctx context.Context) {
266 + b.wg.Add(1)
267 + go func() {
268 + defer b.wg.Done()
269 + t := time.NewTicker(b.cfg.RefreshBootstrapsEvery)
270 + defer t.Stop()
271 + for {
272 + select {
273 + case <-ctx.Done():
274 + return
275 + case <-t.C:
276 + addrs, err := fetchMultiaddrsFromHealth(b.cfg.ServerURL, b.cfg.HTTPTimeout)
277 + if err != nil {
278 + b.setServerHealthy(false)
279 + log.Warn().Err(err).Msgf("refresh /health from %s failed", b.cfg.ServerURL)
280 + continue
281 + }
282 + b.setServerHealthy(true)
283 + sortMultiaddrs(addrs, b.cfg.PreferQUIC, b.cfg.PreferLocal)
284 + addrs = uniq(addrs)
285 + if len(addrs) > 0 {
286 + // Always attempt (re)connect; ConnectBootstraps handles dedupe and quiet logging
287 + ConnectBootstraps(ctx, b.h, addrs)
288 }
289 }
212 - }()
213 - }
214 -
215 - if addrs := BuildAddrs(b.Host()); len(addrs) > 0 {
216 - for _, s := range addrs {
217 - log.Info().Msgf("[client] host addr: %s", s)
290 }
219 - } else {
220 - log.Info().Msgf("[client] host peer: %s (no listen addrs yet)", b.Host().ID().String())
221 - }
222 -
223 - return nil
224 -}
225 -
226 -func (b *RelayClient) Host() host.Host {
227 - return b.h
228 -}
229 -
230 -func (b *RelayClient) Close() error {
231 - if b.stop != nil {
232 - b.stop()
233 - }
234 - b.wg.Wait()
235 - // leaving topic is optional; libp2p will clean up on host close
236 - return nil
237 -}
238 -
239 -func (b *RelayClient) setServerHealthy(ok bool) {
240 - b.statusMu.Lock()
241 - b.serverHealthy = ok
242 - b.statusMu.Unlock()
291 + }()
292 }
293
294 // ServerStatus returns a human-friendly status regarding connection to ServerURL.
relaydns/types.go
+11 -5
@@ -1,15 +1,21 @@
1 package relaydns
2
3 import (
4 - "time"
4 + "time"
5
6 - "github.com/libp2p/go-libp2p/core/peer"
6 + "github.com/libp2p/go-libp2p/core/peer"
7 +)
8 +
9 +// Defaults shared by server and client.
10 +const (
11 + DefaultProtocol = "/relaydns/http/1.0"
12 + DefaultTopic = "relaydns.backends"
13 )
14
15 type Advertise struct {
10 - Peer string `json:"peer"`
11 - Name string `json:"name,omitempty"`
12 - DNS string `json:"dns,omitempty"`
16 + Peer string `json:"peer"`
17 + Name string `json:"name,omitempty"`
18 + DNS string `json:"dns,omitempty"`
19 Addrs []string `json:"addrs"`
20 Ready bool `json:"ready"`
21 Load float64 `json:"load"`