mirror of
https://github.com/tailscale/tailscale.git
synced 2026-03-26 02:03:42 -04:00
net/porttrack: change magic listen address format for Go 1.26
Go 1.26's url.Parser is stricter and made our tests elsewhere fail with this scheme because when these listen addresses get shoved into a URL, it can't parse back out. I verified this makes tests elsewhere pass with Go 1.26. Updates #18682 Change-Id: I04dd3cee591aa85a9417a0bbae2b6f699d8302fa Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
committed by
Brad Fitzpatrick
parent
d58bfb8a1b
commit
87bf76de89
@@ -9,9 +9,9 @@
|
||||
//
|
||||
// The magic address format is:
|
||||
//
|
||||
// testport-report:HOST:PORT/LABEL
|
||||
// testport-report-LABEL:PORT
|
||||
//
|
||||
// where HOST:PORT is the collector's TCP address and LABEL identifies
|
||||
// where localhost:PORT is the collector's TCP address and LABEL identifies
|
||||
// which listener this is (e.g. "main", "plaintext").
|
||||
//
|
||||
// When [Listen] is called with a non-magic address, it falls through to
|
||||
@@ -31,17 +31,18 @@
|
||||
"tailscale.com/util/testenv"
|
||||
)
|
||||
|
||||
const magicPrefix = "testport-report:"
|
||||
const magicPrefix = "testport-report-"
|
||||
|
||||
// Collector is the parent/test side of the porttrack protocol. It
|
||||
// listens for port reports from child processes that used [Listen]
|
||||
// with a magic address obtained from [Collector.Addr].
|
||||
type Collector struct {
|
||||
ln net.Listener
|
||||
mu sync.Mutex
|
||||
cond *sync.Cond
|
||||
ports map[string]int
|
||||
err error // non-nil if a context passed to Port was cancelled
|
||||
ln net.Listener
|
||||
lnPort int
|
||||
mu sync.Mutex
|
||||
cond *sync.Cond
|
||||
ports map[string]int
|
||||
err error // non-nil if a context passed to Port was cancelled
|
||||
}
|
||||
|
||||
// NewCollector creates a new Collector. The collector's TCP listener is
|
||||
@@ -53,8 +54,9 @@ func NewCollector(t testenv.TB) *Collector {
|
||||
t.Fatalf("porttrack.NewCollector: %v", err)
|
||||
}
|
||||
c := &Collector{
|
||||
ln: ln,
|
||||
ports: make(map[string]int),
|
||||
ln: ln,
|
||||
lnPort: ln.Addr().(*net.TCPAddr).Port,
|
||||
ports: make(map[string]int),
|
||||
}
|
||||
c.cond = sync.NewCond(&c.mu)
|
||||
go c.accept(t)
|
||||
@@ -100,7 +102,14 @@ func (c *Collector) handleConn(t testenv.TB, conn net.Conn) {
|
||||
// causes the child to bind to localhost:0 and report its actual port
|
||||
// back to this collector under the given label.
|
||||
func (c *Collector) Addr(label string) string {
|
||||
return magicPrefix + c.ln.Addr().String() + "/" + label
|
||||
for _, c := range label {
|
||||
switch {
|
||||
case 'a' <= c && c <= 'z', 'A' <= c && c <= 'Z', '0' <= c && c <= '9', c == '-':
|
||||
default:
|
||||
panic(fmt.Sprintf("invalid label %q: only letters, digits, and hyphens are allowed", label))
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("%s%s:%d", magicPrefix, label, c.lnPort)
|
||||
}
|
||||
|
||||
// Port blocks until the child process has reported the port for the
|
||||
@@ -145,13 +154,11 @@ func Listen(network, address string) (net.Listener, error) {
|
||||
return net.Listen(network, address)
|
||||
}
|
||||
|
||||
// rest is "HOST:PORT/LABEL"
|
||||
slashIdx := strings.LastIndex(rest, "/")
|
||||
if slashIdx < 0 {
|
||||
return nil, fmt.Errorf("porttrack: malformed magic address %q: missing /LABEL", address)
|
||||
// rest is LABEL:PORT.
|
||||
label, collectorPort, ok := strings.Cut(rest, ":")
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("porttrack: malformed magic address %q: missing :PORT", address)
|
||||
}
|
||||
collectorAddr := rest[:slashIdx]
|
||||
label := rest[slashIdx+1:]
|
||||
|
||||
ln, err := net.Listen(network, "localhost:0")
|
||||
if err != nil {
|
||||
@@ -160,6 +167,7 @@ func Listen(network, address string) (net.Listener, error) {
|
||||
|
||||
port := ln.Addr().(*net.TCPAddr).Port
|
||||
|
||||
collectorAddr := net.JoinHostPort("localhost", collectorPort)
|
||||
conn, err := net.Dial("tcp", collectorAddr)
|
||||
if err != nil {
|
||||
ln.Close()
|
||||
|
||||
Reference in New Issue
Block a user