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
}