tailscale/portlist/portlist.go
Marwan Sulaiman e32e5c0d0c portlist: add Poller.IncludeLocalhost option
This PR parameterizes receiving loopback updates from the portlist package.
Callers can now include services bound to localhost if they want.
Note that this option is off by default still.

Fixes #8171

Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
2023-05-24 13:26:16 -04:00

81 lines
1.6 KiB
Go

// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// This file is just the types. The bulk of the code is in poller.go.
// The portlist package contains code that checks what ports are open and
// listening on the current machine.
package portlist
import (
"fmt"
"sort"
"strings"
)
// Port is a listening port on the machine.
type Port struct {
Proto string // "tcp" or "udp"
Port uint16 // port number
Process string // optional process name, if found
Pid int // process id, if known
}
// List is a list of Ports.
type List []Port
func (a *Port) lessThan(b *Port) bool {
if a.Port != b.Port {
return a.Port < b.Port
}
if a.Proto != b.Proto {
return a.Proto < b.Proto
}
return a.Process < b.Process
}
func (a *Port) equal(b *Port) bool {
return a.Port == b.Port &&
a.Proto == b.Proto &&
a.Process == b.Process
}
func (a List) equal(b List) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if !a[i].equal(&b[i]) {
return false
}
}
return true
}
func (pl List) String() string {
var sb strings.Builder
for _, v := range pl {
fmt.Fprintf(&sb, "%-3s %5d %#v\n",
v.Proto, v.Port, v.Process)
}
return strings.TrimRight(sb.String(), "\n")
}
// sortAndDedup sorts ps in place (by Port.lessThan) and then returns
// a subset of it with duplicate (Proto, Port) removed.
func sortAndDedup(ps List) List {
sort.Slice(ps, func(i, j int) bool {
return (&ps[i]).lessThan(&ps[j])
})
out := ps[:0]
var last Port
for _, p := range ps {
if last.Proto == p.Proto && last.Port == p.Port {
continue
}
out = append(out, p)
last = p
}
return out
}