fix client

Kim committed Oct 21, 2025 at 11:49 UTC d64af3432359a8b61d5a5d9e570c0bd3c217c63d
2 files changed +64 -66
cmd/example_client/main.go
+18 -14
@@ -31,6 +31,9 @@ var (
31 flagAdvertiseEvery time.Duration
32 flagName string
33 flagDNS string
34 + flagPreferQUIC bool
35 + flagPreferLocal bool
36 + flagHTTPTimeout time.Duration
37 )
38
39 func init() {
@@ -44,6 +47,9 @@ func init() {
47 flags.DurationVar(&flagAdvertiseEvery, "advertise-every", 3*time.Second, "interval for backend adverts")
48 flags.StringVar(&flagName, "name", "demo-http", "backend display name")
49 flags.StringVar(&flagDNS, "dns", "demo-http.example", "backend DNS metadata (optional)")
50 + flags.BoolVar(&flagPreferQUIC, "prefer-quic", true, "prefer QUIC multiaddrs when available")
51 + flags.BoolVar(&flagPreferLocal, "prefer-local", true, "prefer loopback/local multiaddrs when available")
52 + flags.DurationVar(&flagHTTPTimeout, "http-timeout", 3*time.Second, "timeout for server /health fetch")
53 }
54
55 func main() {
@@ -56,7 +62,7 @@ func runClient(cmd *cobra.Command, args []string) error {
62 ctx, cancel := context.WithCancel(context.Background())
63 defer cancel()
64
59 - // 1) 로컬 HTTP 백엔드
65 + // 1) HTTP backend
66 go func() {
67 mux := http.NewServeMux()
68 mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
@@ -90,25 +96,24 @@ func runClient(cmd *cobra.Command, args []string) error {
96 }
97
98 client, err := relaydns.NewClient(ctx, h, relaydns.ClientConfig{
93 - Protocol: "/relaydns/http/1.0",
94 - Topic: "relaydns.backends",
95 - AdvertiseEvery: 3 * time.Second,
96 - Name: "demo-http",
97 - DNS: "demo-http.example",
98 - TargetTCP: "127.0.0.1:8081",
99 -
100 - // 편의성 업!
99 + Protocol: flagProtocol,
100 + Topic: flagTopic,
101 + AdvertiseEvery: flagAdvertiseEvery,
102 + Name: flagName,
103 + DNS: flagDNS,
104 + TargetTCP: addrToTarget(flagBackendHTTP),
105 +
106 ServerURL: flagServerURL,
107 Bootstraps: flagBootstraps,
103 - PreferQUIC: true,
104 - PreferLocal: true,
108 + HTTPTimeout: flagHTTPTimeout,
109 + PreferQUIC: flagPreferQUIC,
110 + PreferLocal: flagPreferLocal,
111 })
112 if err != nil {
113 return fmt.Errorf("new client: %w", err)
114 }
115 defer client.Close()
116
111 - // 자기 주소/피어ID 로그로 찍어서 디버깅 편하게
117 if addrs := h.Addrs(); len(addrs) > 0 {
118 for _, a := range addrs {
119 log.Info().Msgf("[client] host addr: %s/p2p/%s", a.String(), h.ID().String())
@@ -117,7 +122,7 @@ func runClient(cmd *cobra.Command, args []string) error {
122 log.Info().Msgf("[client] host peer: %s (no listen addrs yet)", h.ID().String())
123 }
124
120 - // 종료 대기
125 + // wait for termination
126 sig := make(chan os.Signal, 1)
127 signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
128 <-sig
@@ -127,7 +132,6 @@ func runClient(cmd *cobra.Command, args []string) error {
132 }
133
134 func addrToTarget(listen string) string {
130 - // ":8081" 같은 형식을 TargetTCP에 맞게 127.0.0.1로 보정
135 if len(listen) > 0 && listen[0] == ':' {
136 return "127.0.0.1" + listen
137 }
relaydns/client.go
+46 -52
@@ -1,25 +1,25 @@
1 package relaydns
2
3 -import (
4 - "context"
5 - "encoding/json"
6 - "errors"
7 - "fmt"
8 - "io"
9 - "net"
10 - "net/http"
11 - "net/url"
12 - "sort"
13 - "strings"
14 - "sync"
15 - "time"
16 -
17 - pubsub "github.com/libp2p/go-libp2p-pubsub"
18 - "github.com/libp2p/go-libp2p/core/host"
19 - "github.com/libp2p/go-libp2p/core/network"
20 - "github.com/libp2p/go-libp2p/core/protocol"
21 - "github.com/rs/zerolog/log"
22 -)
3 +import (
4 + "context"
5 + "encoding/json"
6 + "errors"
7 + "fmt"
8 + "io"
9 + "net"
10 + "net/http"
11 + "net/url"
12 + "sort"
13 + "strings"
14 + "sync"
15 + "time"
16 +
17 + pubsub "github.com/libp2p/go-libp2p-pubsub"
18 + "github.com/libp2p/go-libp2p/core/host"
19 + "github.com/libp2p/go-libp2p/core/network"
20 + "github.com/libp2p/go-libp2p/core/protocol"
21 + "github.com/rs/zerolog/log"
22 +)
23
24 type ClientConfig struct {
25 ServerURL string
@@ -60,12 +60,6 @@ type RelayClient struct {
60 // It registers a stream handler and starts an advertiser loop.
61 // Call Close() to stop.
62 func NewClient(ctx context.Context, h host.Host, cfg ClientConfig) (*RelayClient, error) {
63 - if cfg.Protocol == "" {
64 - cfg.Protocol = "/relaydns/ssh/1.0"
65 - }
66 - if cfg.Topic == "" {
67 - cfg.Topic = "relaydns.backends"
68 - }
63 if cfg.AdvertiseEvery <= 0 {
64 cfg.AdvertiseEvery = 5 * time.Second
65 }
@@ -82,38 +76,38 @@ func NewClient(ctx context.Context, h host.Host, cfg ClientConfig) (*RelayClient
76 if len(cfg.Bootstraps) > 0 {
77 boot = append(boot, cfg.Bootstraps...)
78 }
85 - if cfg.ServerURL != "" {
86 - if addrs, err := fetchMultiaddrsFromHealth(cfg.ServerURL, cfg.HTTPTimeout); err != nil {
87 - log.Warn().Err(err).Msgf("relaydns: fetch /health from %s failed", cfg.ServerURL)
88 - } else {
89 - sortMultiaddrs(addrs, cfg.PreferQUIC, cfg.PreferLocal)
90 - boot = append(boot, addrs...)
91 - }
92 - }
93 - boot = uniq(boot)
94 - if len(boot) > 0 {
95 - ConnectBootstraps(ctx, h, boot)
96 - } else {
97 - log.Warn().Msg("relaydns: no bootstrap sources provided (Bootstraps/ServerURL); discovery may fail")
98 - }
79 + if cfg.ServerURL != "" {
80 + if addrs, err := fetchMultiaddrsFromHealth(cfg.ServerURL, cfg.HTTPTimeout); err != nil {
81 + log.Warn().Err(err).Msgf("relaydns: fetch /health from %s failed", cfg.ServerURL)
82 + } else {
83 + sortMultiaddrs(addrs, cfg.PreferQUIC, cfg.PreferLocal)
84 + boot = append(boot, addrs...)
85 + }
86 + }
87 + boot = uniq(boot)
88 + if len(boot) > 0 {
89 + ConnectBootstraps(ctx, h, boot)
90 + } else {
91 + log.Warn().Msg("relaydns: no bootstrap sources provided (Bootstraps/ServerURL); discovery may fail")
92 + }
93
94 // 1) stream handler
95 switch {
96 case cfg.Handler != nil:
97 h.SetStreamHandler(b.protoID, cfg.Handler)
98 case cfg.TargetTCP != "":
105 - h.SetStreamHandler(b.protoID, func(s network.Stream) {
106 - defer s.Close()
107 - c, err := net.Dial("tcp", cfg.TargetTCP)
108 - if err != nil {
109 - log.Error().Err(err).Msgf("relaydns: dial %s", cfg.TargetTCP)
110 - return
111 - }
112 - defer c.Close()
113 - // raw byte pipe
114 - go io.Copy(c, s)
115 - io.Copy(s, c)
116 - })
99 + h.SetStreamHandler(b.protoID, func(s network.Stream) {
100 + defer s.Close()
101 + c, err := net.Dial("tcp", cfg.TargetTCP)
102 + if err != nil {
103 + log.Error().Err(err).Msgf("relaydns: dial %s", cfg.TargetTCP)
104 + return
105 + }
106 + defer c.Close()
107 + // raw byte pipe
108 + go io.Copy(c, s)
109 + io.Copy(s, c)
110 + })
111 default:
112 return nil, fmt.Errorf("relaydns: either Handler or TargetTCP must be set")
113 }