@@ -10,6 +10,7 @@ import (
10
10
"net/http"
11
11
"net/http/cookiejar"
12
12
"net/netip"
13
+ "strconv"
13
14
"time"
14
15
15
16
"cloud.google.com/go/compute/metadata"
@@ -208,7 +209,42 @@ func (c *Client) WorkspaceAgentMetadata(ctx context.Context) (WorkspaceAgentMeta
208
209
return WorkspaceAgentMetadata {}, readBodyAsError (res )
209
210
}
210
211
var agentMetadata WorkspaceAgentMetadata
211
- return agentMetadata , json .NewDecoder (res .Body ).Decode (& agentMetadata )
212
+ err = json .NewDecoder (res .Body ).Decode (& agentMetadata )
213
+ if err != nil {
214
+ return WorkspaceAgentMetadata {}, err
215
+ }
216
+ accessingPort := c .URL .Port ()
217
+ if accessingPort == "" {
218
+ accessingPort = "80"
219
+ if c .URL .Scheme == "https" {
220
+ accessingPort = "443"
221
+ }
222
+ }
223
+ accessPort , err := strconv .Atoi (accessingPort )
224
+ if err != nil {
225
+ return WorkspaceAgentMetadata {}, xerrors .Errorf ("convert accessing port %q: %w" , accessingPort , err )
226
+ }
227
+ // Agents can provide an arbitrary access URL that may be different
228
+ // that the globally configured one. This breaks the built-in DERP,
229
+ // which would continue to reference the global access URL.
230
+ //
231
+ // This converts all built-in DERPs to use the access URL that the
232
+ // metadata request was performed with.
233
+ for _ , region := range agentMetadata .DERPMap .Regions {
234
+ if ! region .EmbeddedRelay {
235
+ continue
236
+ }
237
+
238
+ for _ , node := range region .Nodes {
239
+ if node .STUNOnly {
240
+ continue
241
+ }
242
+ node .HostName = c .URL .Hostname ()
243
+ node .DERPPort = accessPort
244
+ node .ForceHTTP = c .URL .Scheme == "http"
245
+ }
246
+ }
247
+ return agentMetadata , nil
212
248
}
213
249
214
250
func (c * Client ) ListenWorkspaceAgentTailnet (ctx context.Context ) (net.Conn , error ) {
0 commit comments