Commit d381eef
authored
fix(mcp): pin outbound connections to IPv4 to avoid unreachable-IPv6 hangs (#5798)
* fix(mcp): pin outbound connections to IPv4 to avoid unreachable-IPv6 hangs
Root cause of the MCP 'connecting forever' / tool-discovery timeouts in
production: SSRF pinning forces each outbound connection to a single resolved
IP, which strips Happy Eyeballs' IPv4 fallback. dns.lookup(verbatim) returns the
IPv6 address first for Cloudflare-fronted dual-stack hosts (Gauge, api.exa.ai),
so the connection was pinned to IPv6 — but the production app subnets have no
IPv6 egress (AWS NAT gateways are IPv4-only), so the pinned IPv6 connection
connects into a void and hangs until the 30s timeout. Intermittent because the
resolver rotates A/AAAA order; works on retry when it happens to pick IPv4.
This is why h1.1 (#5797) did not fix it (protocol-independent) and why it never
reproduced locally (dev machines have IPv6 egress). Empirically verified: pinning
only the IPv6 address times out; preferring the IPv4 address connects in ~600ms.
Fix: at both pinned-resolution sites (validateMcpServerSsrf and validateUrlWithDNS)
resolve all addresses and prefer an IPv4 one; IPv6-only hosts still pin their sole
address. No signature/threading changes; SSRF validation of the pinned IP is
unchanged.
* chore(mcp): trim inline comments on the IPv4-preference fix1 parent 48103e9 commit d381eef
3 files changed
Lines changed: 36 additions & 12 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
105 | 105 | | |
106 | 106 | | |
107 | 107 | | |
108 | | - | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
109 | 112 | | |
110 | 113 | | |
111 | 114 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
364 | 364 | | |
365 | 365 | | |
366 | 366 | | |
367 | | - | |
| 367 | + | |
368 | 368 | | |
369 | 369 | | |
370 | 370 | | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
371 | 390 | | |
372 | | - | |
| 391 | + | |
373 | 392 | | |
374 | 393 | | |
375 | 394 | | |
| |||
405 | 424 | | |
406 | 425 | | |
407 | 426 | | |
408 | | - | |
| 427 | + | |
409 | 428 | | |
410 | 429 | | |
411 | 430 | | |
412 | 431 | | |
413 | | - | |
| 432 | + | |
414 | 433 | | |
415 | 434 | | |
416 | 435 | | |
| |||
424 | 443 | | |
425 | 444 | | |
426 | 445 | | |
427 | | - | |
| 446 | + | |
428 | 447 | | |
429 | 448 | | |
430 | 449 | | |
| |||
450 | 469 | | |
451 | 470 | | |
452 | 471 | | |
453 | | - | |
| 472 | + | |
454 | 473 | | |
455 | 474 | | |
456 | 475 | | |
457 | 476 | | |
458 | 477 | | |
459 | 478 | | |
460 | | - | |
| 479 | + | |
461 | 480 | | |
462 | 481 | | |
463 | 482 | | |
| |||
483 | 502 | | |
484 | 503 | | |
485 | 504 | | |
486 | | - | |
| 505 | + | |
487 | 506 | | |
488 | 507 | | |
489 | 508 | | |
| |||
508 | 527 | | |
509 | 528 | | |
510 | 529 | | |
511 | | - | |
| 530 | + | |
512 | 531 | | |
513 | 532 | | |
514 | 533 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
185 | 185 | | |
186 | 186 | | |
187 | 187 | | |
188 | | - | |
189 | | - | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
190 | 192 | | |
191 | 193 | | |
192 | 194 | | |
| |||
0 commit comments