refact: remove RelayID

Kim committed Apr 1, 2026 at 18:31 UTC bbe7a6bdc57234cec43712a4cb66d1fbb84c8ea3
11 files changed +19 -35
Dockerfile
+3 -5
@@ -39,13 +39,11 @@ FROM gcr.io/distroless/static-debian12:nonroot
39
40 COPY --from=go-builder /src/bin/relay-server /usr/bin/relay-server
41
42 -WORKDIR /tmp
43 -
42 ENV PORTAL_URL=https://localhost:4017
45 -ENV IDENTITY_PATH=/tmp/.portal-certs/identity.json
43 +ENV IDENTITY_PATH=/portal-certs/identity.json
44 ENV ADMIN_SECRET_KEY=
47 -ENV SNI_PORT=:443
48 -ENV KEYLESS_DIR=/tmp/.portal-certs
45 +ENV SNI_PORT=443
46 +ENV KEYLESS_DIR=/portal-certs
47 ENV CLOUDFLARE_TOKEN=
48 ENV TZ=UTC
49
portal/api_server.go
-1
@@ -149,7 +149,6 @@ func (s *Server) handleRelayDiscovery(w http.ResponseWriter, r *http.Request) {
149
150 self, err := discovery.NormalizeDescriptor(types.RelayDescriptor{
151 Identity: s.identity.Copy(),
152 - RelayID: s.cfg.PortalURL,
152 Sequence: uint64(now.UnixMilli()),
153 Version: 1,
154 IssuedAt: now,
portal/discovery/discovery.go
-7
@@ -19,7 +19,6 @@ const defaultRequestTimeout = 15 * time.Second
19 func NormalizeDescriptor(desc types.RelayDescriptor) (types.RelayDescriptor, error) {
20 desc.Name = utils.NormalizeHostname(desc.Name)
21 desc.Address = strings.TrimSpace(desc.Address)
22 - desc.RelayID = strings.TrimSpace(desc.RelayID)
22 desc.APIHTTPSAddr = strings.TrimSpace(desc.APIHTTPSAddr)
23 desc.WireGuardPublicKey = strings.TrimSpace(desc.WireGuardPublicKey)
24 desc.WireGuardEndpoint = strings.TrimSpace(desc.WireGuardEndpoint)
@@ -37,9 +36,6 @@ func NormalizeDescriptor(desc types.RelayDescriptor) (types.RelayDescriptor, err
36 return types.RelayDescriptor{}, fmt.Errorf("normalize api https addr: %w", err)
37 }
38 desc.APIHTTPSAddr = normalized
40 - if desc.RelayID == "" {
41 - desc.RelayID = normalized
42 - }
39 }
40 if desc.Address != "" {
41 normalized, err := utils.NormalizeEVMAddress(desc.Address)
@@ -77,8 +73,6 @@ func ValidateDescriptor(desc types.RelayDescriptor, now time.Time) (types.RelayD
73 switch {
74 case normalized.Name == "":
75 return types.RelayDescriptor{}, errors.New("identity.name is required")
80 - case normalized.RelayID == "":
81 - return types.RelayDescriptor{}, errors.New("relay_id is required")
76 case normalized.APIHTTPSAddr == "":
77 return types.RelayDescriptor{}, errors.New("api_https_addr is required")
78 case normalized.Sequence == 0:
@@ -224,7 +218,6 @@ func SeedDescriptor(apiURL string) (types.RelayDescriptor, error) {
218 Identity: types.Identity{
219 Name: utils.PortalRootHost(normalized),
220 },
227 - RelayID: normalized,
221 APIHTTPSAddr: normalized,
222 Version: 1,
223 }, nil
portal/discovery/relayset.go
-1
@@ -246,7 +246,6 @@ func (s *RelaySet) BootstrapDescriptors() []types.RelayDescriptor {
246 Identity: types.Identity{
247 Name: utils.PortalRootHost(relayURL),
248 },
249 - RelayID: relayURL,
249 APIHTTPSAddr: relayURL,
250 Version: 1,
251 })
portal/server.go
+4 -4
@@ -519,7 +519,7 @@ func (s *Server) startOverlay() error {
519 return fmt.Errorf("start wireguard overlay: %w", err)
520 }
521
522 - if err := overlay.Sync(s.cfg.PortalURL, s.relaySet.Snapshot()); err != nil {
522 + if err := overlay.Sync(s.identity.Key(), s.relaySet.Snapshot()); err != nil {
523 _ = overlay.Shutdown(context.Background())
524 return fmt.Errorf("sync wireguard peers: %w", err)
525 }
@@ -550,7 +550,7 @@ func (s *Server) runRelayDiscoveryLoop(ctx context.Context) error {
550 var warnErr error
551 _, relaySetChanged, _, warnErr, err = s.relaySet.ApplyRelayDiscoveryResponse(bootstrap.Identity, bootstrap.APIHTTPSAddr, resp, now)
552 if relaySetChanged && s.overlay != nil {
553 - if syncErr := s.overlay.Sync(s.cfg.PortalURL, s.relaySet.Snapshot()); syncErr != nil {
553 + if syncErr := s.overlay.Sync(s.identity.Key(), s.relaySet.Snapshot()); syncErr != nil {
554 if warnErr == nil {
555 warnErr = syncErr
556 }
@@ -601,7 +601,7 @@ func (s *Server) runRelayDiscoveryLoop(ctx context.Context) error {
601 _, relaySetChanged, _, warnErr, err = s.relaySet.ApplyOverlayRelayDiscoveryResponse(relay.Identity, relay.APIHTTPSAddr, resp, now)
602 if relaySetChanged {
603 snapshot = s.relaySet.Snapshot()
604 - if syncErr := s.overlay.Sync(s.cfg.PortalURL, snapshot); syncErr != nil {
604 + if syncErr := s.overlay.Sync(s.identity.Key(), snapshot); syncErr != nil {
605 if warnErr == nil {
606 warnErr = syncErr
607 }
@@ -624,7 +624,7 @@ func (s *Server) runRelayDiscoveryLoop(ctx context.Context) error {
624 }
625 expired, expireReason, consecutiveFailures := s.relaySet.RecordDiscoveryFailure(relay.Identity, relay.APIHTTPSAddr, failureErr, defaultWGRecoveryFailures, time.Now().UTC())
626 if expired {
627 - if syncErr := s.overlay.Sync(s.cfg.PortalURL, s.relaySet.Snapshot()); syncErr != nil && failureErr == nil {
627 + if syncErr := s.overlay.Sync(s.identity.Key(), s.relaySet.Snapshot()); syncErr != nil && failureErr == nil {
628 failureErr = syncErr
629 }
630 }
portal/server_test.go
-1
@@ -40,7 +40,6 @@ func mustRelayDescriptor(t *testing.T, relayURL string) types.RelayDescriptor {
40 Identity: types.Identity{
41 Name: utils.PortalRootHost(relayURL),
42 },
43 - RelayID: relayURL,
43 Sequence: uint64(now.UnixMilli()),
44 Version: 1,
45 IssuedAt: now,
portal/wireguard/overlay.go
+5 -6
@@ -154,21 +154,21 @@ func (o *Overlay) Client() *http.Client {
154 }
155 }
156
157 -func (o *Overlay) Sync(selfRelayID string, snapshot map[string]types.RelayState) error {
157 +func (o *Overlay) Sync(selfIdentityKey string, snapshot map[string]types.RelayState) error {
158 if o == nil || o.stack == nil {
159 return nil
160 }
161 - return o.stack.ApplyPeers(peersForSnapshot(selfRelayID, snapshot))
161 + return o.stack.ApplyPeers(peersForSnapshot(selfIdentityKey, snapshot))
162 }
163
164 -func peersForSnapshot(selfRelayID string, snapshot map[string]types.RelayState) []types.DesiredPeer {
164 +func peersForSnapshot(selfIdentityKey string, snapshot map[string]types.RelayState) []types.DesiredPeer {
165 peers := make([]types.DesiredPeer, 0, len(snapshot))
166 for _, state := range snapshot {
167 if state.Expired {
168 continue
169 }
170 desc := state.Descriptor
171 - if desc.RelayID == selfRelayID || !desc.SupportsOverlayPeer {
171 + if desc.Key() == selfIdentityKey || !desc.SupportsOverlayPeer {
172 continue
173 }
174 if desc.WireGuardPublicKey == "" || desc.WireGuardEndpoint == "" || desc.OverlayIPv4 == "" {
@@ -178,14 +178,13 @@ func peersForSnapshot(selfRelayID string, snapshot map[string]types.RelayState)
178 allowedIPs := []string{desc.OverlayIPv4 + "/32"}
179 allowedIPs = append(allowedIPs, desc.OverlayCIDRs...)
180 peers = append(peers, types.DesiredPeer{
181 - RelayID: desc.RelayID,
181 WireGuardPublicKey: desc.WireGuardPublicKey,
182 WireGuardEndpoint: desc.WireGuardEndpoint,
183 AllowedIPs: allowedIPs,
184 })
185 }
186 sort.Slice(peers, func(i, j int) bool {
188 - return peers[i].RelayID < peers[j].RelayID
187 + return peers[i].WireGuardPublicKey < peers[j].WireGuardPublicKey
188 })
189 return peers
190 }
portal/wireguard/stack.go
+4 -3
@@ -132,9 +132,10 @@ func (s *stack) ApplyPeers(peers []types.DesiredPeer) error {
132 nextPeerEndpoints := map[string]string{}
133
134 for _, peer := range peers {
135 + peerKey := strings.TrimSpace(peer.WireGuardPublicKey)
136 publicKeyHex, err := utils.WireGuardKeyHex(peer.WireGuardPublicKey)
137 if err != nil {
137 - return fmt.Errorf("normalize peer %q public key: %w", peer.RelayID, err)
138 + return fmt.Errorf("normalize peer %q public key: %w", peerKey, err)
139 }
140
141 resolvedEndpoint := ""
@@ -145,10 +146,10 @@ func (s *stack) ApplyPeers(peers []types.DesiredPeer) error {
146 currentEndpoint := s.peerEndpoints[publicKeyHex]
147 s.mu.Unlock()
148 if currentEndpoint != "" {
148 - warnErr = errors.Join(warnErr, fmt.Errorf("resolve peer %q endpoint: %w; using current endpoint %q", peer.RelayID, err, currentEndpoint))
149 + warnErr = errors.Join(warnErr, fmt.Errorf("resolve peer %q endpoint: %w; using current endpoint %q", peerKey, err, currentEndpoint))
150 resolvedEndpoint = currentEndpoint
151 } else {
151 - warnErr = errors.Join(warnErr, fmt.Errorf("resolve peer %q endpoint: %w", peer.RelayID, err))
152 + warnErr = errors.Join(warnErr, fmt.Errorf("resolve peer %q endpoint: %w", peerKey, err))
153 continue
154 }
155 }
portal/wireguard/stack_test.go
-1
@@ -135,7 +135,6 @@ func TestApplyPeersKeepsCurrentEndpointOnResolveFailure(t *testing.T) {
135 }
136
137 peer := types.DesiredPeer{
138 - RelayID: "https://peer.example.com",
138 WireGuardPublicKey: peerPublicKey,
139 WireGuardEndpoint: "127.0.0.1:51820",
140 AllowedIPs: []string{"10.77.0.2/32"},
sdk/expose_test.go
+3 -4
@@ -9,15 +9,14 @@ import (
9 "github.com/gosuda/portal/v2/types"
10 )
11
12 -func mustRelayDescriptor(t *testing.T, relayID, relayURL string) types.RelayDescriptor {
12 +func mustRelayDescriptor(t *testing.T, relayName, relayURL string) types.RelayDescriptor {
13 t.Helper()
14
15 now := time.Now().UTC()
16 desc, err := discovery.NormalizeDescriptor(types.RelayDescriptor{
17 Identity: types.Identity{
18 - Name: relayID,
18 + Name: relayName,
19 },
20 - RelayID: relayID,
20 Sequence: uint64(now.UnixMilli()),
21 Version: 1,
22 IssuedAt: now,
@@ -171,7 +170,7 @@ func TestExposurePinDiscoveredDescriptorAllowsURLChangeForSameIdentity(t *testin
170 t.Fatalf("ApplyRelayDiscoveryResponse() error = %v", err)
171 }
172
174 - changedURL := mustRelayDescriptor(t, desc.RelayID, "https://relay-b.example")
173 + changedURL := mustRelayDescriptor(t, desc.Name, "https://relay-b.example")
174 _, _, _, _, err := exposure.relaySet.ApplyRelayDiscoveryResponse(desc.Identity, "", types.DiscoveryResponse{ProtocolVersion: types.ProtocolVersion, Self: changedURL}, time.Now().UTC())
175 if err != nil {
176 t.Fatalf("ApplyRelayDiscoveryResponse() error = %v, want nil for same relay identity", err)
types/identity.go
-2
@@ -70,7 +70,6 @@ func (m LeaseMetadata) Copy() LeaseMetadata {
70
71 type RelayDescriptor struct {
72 Identity
73 - RelayID string `json:"relay_id"`
73
74 Sequence uint64 `json:"sequence"`
75 Version uint32 `json:"version"`
@@ -103,7 +102,6 @@ type RelayState struct {
102 }
103
104 type DesiredPeer struct {
106 - RelayID string `json:"relay_id"`
105 WireGuardPublicKey string `json:"wireguard_public_key"`
106 WireGuardEndpoint string `json:"wireguard_endpoint"`
107 AllowedIPs []string `json:"allowed_ips,omitempty"`