mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 19:15:34 +00:00
all: gofmt for Go 1.19
Updates #5210 Change-Id: Ib02cd5e43d0a8db60c1f09755a8ac7b140b670be Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
a029989aff
commit
116f55ff66
@ -14,14 +14,14 @@
|
|||||||
//
|
//
|
||||||
// Use this Grafana configuration to enable the auth proxy:
|
// Use this Grafana configuration to enable the auth proxy:
|
||||||
//
|
//
|
||||||
// [auth.proxy]
|
// [auth.proxy]
|
||||||
// enabled = true
|
// enabled = true
|
||||||
// header_name = X-WEBAUTH-USER
|
// header_name = X-WEBAUTH-USER
|
||||||
// header_property = username
|
// header_property = username
|
||||||
// auto_sign_up = true
|
// auto_sign_up = true
|
||||||
// whitelist = 127.0.0.1
|
// whitelist = 127.0.0.1
|
||||||
// headers = Name:X-WEBAUTH-NAME
|
// headers = Name:X-WEBAUTH-NAME
|
||||||
// enable_login_token = true
|
// enable_login_token = true
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -178,15 +178,16 @@ func (a upArgsT) getAuthKey() (string, error) {
|
|||||||
// JSON block will be output. The AuthURL and QR fields will not be present, the
|
// JSON block will be output. The AuthURL and QR fields will not be present, the
|
||||||
// BackendState and Error fields will give the result of the authentication.
|
// BackendState and Error fields will give the result of the authentication.
|
||||||
// Ex:
|
// Ex:
|
||||||
// {
|
|
||||||
// "AuthURL": "https://login.tailscale.com/a/0123456789abcdef",
|
|
||||||
// "QR": "data:image/png;base64,0123...cdef"
|
|
||||||
// "BackendState": "NeedsLogin"
|
|
||||||
// }
|
|
||||||
// {
|
|
||||||
// "BackendState": "Running"
|
|
||||||
// }
|
|
||||||
//
|
//
|
||||||
|
// {
|
||||||
|
// "AuthURL": "https://login.tailscale.com/a/0123456789abcdef",
|
||||||
|
// "QR": "data:image/png;base64,0123...cdef"
|
||||||
|
// "BackendState": "NeedsLogin"
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// "BackendState": "Running"
|
||||||
|
// }
|
||||||
type upOutputJSON struct {
|
type upOutputJSON struct {
|
||||||
AuthURL string `json:",omitempty"` // Authentication URL of the form https://login.tailscale.com/a/0123456789
|
AuthURL string `json:",omitempty"` // Authentication URL of the form https://login.tailscale.com/a/0123456789
|
||||||
QR string `json:",omitempty"` // a DataURL (base64) PNG of a QR code AuthURL
|
QR string `json:",omitempty"` // a DataURL (base64) PNG of a QR code AuthURL
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
// The tsconnect command builds and serves the static site that is generated for
|
// The tsconnect command builds and serves the static site that is generated for
|
||||||
// the Tailscale Connect JS/WASM client. Can be run in 3 modes:
|
// the Tailscale Connect JS/WASM client. Can be run in 3 modes:
|
||||||
// - dev: builds the site and serves it. JS and CSS changes can be picked up
|
// - dev: builds the site and serves it. JS and CSS changes can be picked up
|
||||||
// with a reload.
|
// with a reload.
|
||||||
// - build: builds the site and writes it to dist/
|
// - build: builds the site and writes it to dist/
|
||||||
// - serve: serves the site from dist/ (embedded in the binary)
|
// - serve: serves the site from dist/ (embedded in the binary)
|
||||||
package main // import "tailscale.com/cmd/tsconnect"
|
package main // import "tailscale.com/cmd/tsconnect"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -342,8 +342,7 @@ func main() {
|
|||||||
it := codegen.NewImportTracker(pkg.Types)
|
it := codegen.NewImportTracker(pkg.Types)
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
fmt.Fprintf(buf, `//go:generate go run tailscale.com/cmd/cloner %s`, strings.Join(flagArgs, " "))
|
fmt.Fprintf(buf, "//go:generate go run tailscale.com/cmd/cloner %s\n\n", strings.Join(flagArgs, " "))
|
||||||
fmt.Fprintln(buf)
|
|
||||||
runCloner := false
|
runCloner := false
|
||||||
for _, typeName := range typeNames {
|
for _, typeName := range typeNames {
|
||||||
typ, ok := namedTypes[typeName]
|
typ, ok := namedTypes[typeName]
|
||||||
|
@ -40,8 +40,8 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
// ProtocolVersion is bumped whenever there's a wire-incompatible change.
|
// ProtocolVersion is bumped whenever there's a wire-incompatible change.
|
||||||
// * version 1 (zero on wire): consistent box headers, in use by employee dev nodes a bit
|
// - version 1 (zero on wire): consistent box headers, in use by employee dev nodes a bit
|
||||||
// * version 2: received packets have src addrs in frameRecvPacket at beginning
|
// - version 2: received packets have src addrs in frameRecvPacket at beginning
|
||||||
const ProtocolVersion = 2
|
const ProtocolVersion = 2
|
||||||
|
|
||||||
// frameType is the one byte frame type at the beginning of the frame
|
// frameType is the one byte frame type at the beginning of the frame
|
||||||
|
@ -7,16 +7,17 @@
|
|||||||
// A discovery message is:
|
// A discovery message is:
|
||||||
//
|
//
|
||||||
// Header:
|
// Header:
|
||||||
// magic [6]byte // “TS💬” (0x54 53 f0 9f 92 ac)
|
//
|
||||||
// senderDiscoPub [32]byte // nacl public key
|
// magic [6]byte // “TS💬” (0x54 53 f0 9f 92 ac)
|
||||||
// nonce [24]byte
|
// senderDiscoPub [32]byte // nacl public key
|
||||||
|
// nonce [24]byte
|
||||||
//
|
//
|
||||||
// The recipient then decrypts the bytes following (the nacl secretbox)
|
// The recipient then decrypts the bytes following (the nacl secretbox)
|
||||||
// and then the inner payload structure is:
|
// and then the inner payload structure is:
|
||||||
//
|
//
|
||||||
// messageType byte (the MessageType constants below)
|
// messageType byte (the MessageType constants below)
|
||||||
// messageVersion byte (0 for now; but always ignore bytes at the end)
|
// messageVersion byte (0 for now; but always ignore bytes at the end)
|
||||||
// message-paylod [...]byte
|
// message-paylod [...]byte
|
||||||
package disco
|
package disco
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -162,12 +162,12 @@ type PartialFile struct {
|
|||||||
//
|
//
|
||||||
// Various platforms currently set StateKey in different ways:
|
// Various platforms currently set StateKey in different ways:
|
||||||
//
|
//
|
||||||
// * the macOS/iOS GUI apps set it to "ipn-go-bridge"
|
// - the macOS/iOS GUI apps set it to "ipn-go-bridge"
|
||||||
// * the Android app sets it to "ipn-android"
|
// - the Android app sets it to "ipn-android"
|
||||||
// * on Windows, it's the empty string (in client mode) or, via
|
// - on Windows, it's the empty string (in client mode) or, via
|
||||||
// LocalBackend.userID, a string like "user-$USER_ID" (used in
|
// LocalBackend.userID, a string like "user-$USER_ID" (used in
|
||||||
// server mode).
|
// server mode).
|
||||||
// * on Linux/etc, it's always "_daemon" (ipn.GlobalDaemonStateKey)
|
// - on Linux/etc, it's always "_daemon" (ipn.GlobalDaemonStateKey)
|
||||||
type StateKey string
|
type StateKey string
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
|
@ -883,11 +883,11 @@ func (b *LocalBackend) getNewControlClientFunc() clientGen {
|
|||||||
// startIsNoopLocked reports whether a Start call on this LocalBackend
|
// startIsNoopLocked reports whether a Start call on this LocalBackend
|
||||||
// with the provided Start Options would be a useless no-op.
|
// with the provided Start Options would be a useless no-op.
|
||||||
//
|
//
|
||||||
// TODO(apenwarr): we shouldn't need this.
|
// TODO(apenwarr): we shouldn't need this. The state machine is now
|
||||||
// The state machine is now nearly clean enough where it can accept a new
|
// nearly clean enough where it can accept a new connection while in
|
||||||
// connection while in any state, not just Running, and on any platform.
|
// any state, not just Running, and on any platform. We'd want to add
|
||||||
// We'd want to add a few more tests to state_test.go to ensure this continues
|
// a few more tests to state_test.go to ensure this continues to work
|
||||||
// to work as expected.
|
// as expected.
|
||||||
//
|
//
|
||||||
// b.mu must be held.
|
// b.mu must be held.
|
||||||
func (b *LocalBackend) startIsNoopLocked(opts ipn.Options) bool {
|
func (b *LocalBackend) startIsNoopLocked(opts ipn.Options) bool {
|
||||||
@ -2926,7 +2926,7 @@ func (b *LocalBackend) RequestEngineStatus() {
|
|||||||
// feed events into LocalBackend.
|
// feed events into LocalBackend.
|
||||||
//
|
//
|
||||||
// TODO(apenwarr): use a channel or something to prevent re-entrancy?
|
// TODO(apenwarr): use a channel or something to prevent re-entrancy?
|
||||||
// Or maybe just call the state machine from fewer places.
|
// Or maybe just call the state machine from fewer places.
|
||||||
func (b *LocalBackend) stateMachine() {
|
func (b *LocalBackend) stateMachine() {
|
||||||
b.enterState(b.nextState())
|
b.enterState(b.nextState())
|
||||||
}
|
}
|
||||||
|
@ -545,7 +545,7 @@ func (h *Handler) serveFileTargets(w http.ResponseWriter, r *http.Request) {
|
|||||||
//
|
//
|
||||||
// URL format:
|
// URL format:
|
||||||
//
|
//
|
||||||
// * PUT /localapi/v0/file-put/:stableID/:escaped-filename
|
// - PUT /localapi/v0/file-put/:stableID/:escaped-filename
|
||||||
func (h *Handler) serveFilePut(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) serveFilePut(w http.ResponseWriter, r *http.Request) {
|
||||||
if !h.PermitWrite {
|
if !h.PermitWrite {
|
||||||
http.Error(w, "file access denied", http.StatusForbidden)
|
http.Error(w, "file access denied", http.StatusForbidden)
|
||||||
|
@ -305,8 +305,8 @@ func (bc *BackendClient) RequestStatus() {
|
|||||||
// MaxMessageSize is the maximum message size, in bytes.
|
// MaxMessageSize is the maximum message size, in bytes.
|
||||||
const MaxMessageSize = 10 << 20
|
const MaxMessageSize = 10 << 20
|
||||||
|
|
||||||
// TODO(apenwarr): incremental json decode?
|
// TODO(apenwarr): incremental json decode? That would let us avoid
|
||||||
// That would let us avoid storing the whole byte array uselessly in RAM.
|
// storing the whole byte array uselessly in RAM.
|
||||||
func ReadMsg(r io.Reader) ([]byte, error) {
|
func ReadMsg(r io.Reader) ([]byte, error) {
|
||||||
cb := make([]byte, 4)
|
cb := make([]byte, 4)
|
||||||
_, err := io.ReadFull(r, cb)
|
_, err := io.ReadFull(r, cb)
|
||||||
@ -328,10 +328,11 @@ func ReadMsg(r io.Reader) ([]byte, error) {
|
|||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(apenwarr): incremental json encode?
|
|
||||||
// That would save RAM, at the expense of having to encode once so that
|
|
||||||
// we can produce the initial byte count.
|
|
||||||
func WriteMsg(w io.Writer, b []byte) error {
|
func WriteMsg(w io.Writer, b []byte) error {
|
||||||
|
// TODO(apenwarr): incremental json encode? That would save RAM, at the
|
||||||
|
// expense of having to encode once so that we can produce the initial byte
|
||||||
|
// count.
|
||||||
|
|
||||||
// TODO(bradfitz): this does two writes to w, which likely
|
// TODO(bradfitz): this does two writes to w, which likely
|
||||||
// does two writes on the wire, two frame generations, etc. We
|
// does two writes on the wire, two frame generations, etc. We
|
||||||
// should take a concrete buffered type, or use a sync.Pool to
|
// should take a concrete buffered type, or use a sync.Pool to
|
||||||
|
@ -49,13 +49,13 @@ func registerDefaultStores() {
|
|||||||
//
|
//
|
||||||
// By default the following stores are registered:
|
// By default the following stores are registered:
|
||||||
//
|
//
|
||||||
// * if the string begins with "mem:", the suffix
|
// - if the string begins with "mem:", the suffix
|
||||||
// is ignored and an in-memory store is used.
|
// is ignored and an in-memory store is used.
|
||||||
// * (Linux-only) if the string begins with "arn:",
|
// - (Linux-only) if the string begins with "arn:",
|
||||||
// the suffix an AWS ARN for an SSM.
|
// the suffix an AWS ARN for an SSM.
|
||||||
// * (Linux-only) if the string begins with "kube:",
|
// - (Linux-only) if the string begins with "kube:",
|
||||||
// the suffix is a Kubernetes secret name
|
// the suffix is a Kubernetes secret name
|
||||||
// * In all other cases, the path is treated as a filepath.
|
// - In all other cases, the path is treated as a filepath.
|
||||||
func New(logf logger.Logf, path string) (ipn.StateStore, error) {
|
func New(logf logger.Logf, path string) (ipn.StateStore, error) {
|
||||||
regOnce.Do(registerDefaultStores)
|
regOnce.Do(registerDefaultStores)
|
||||||
for prefix, sf := range knownStores {
|
for prefix, sf := range knownStores {
|
||||||
|
@ -31,7 +31,9 @@
|
|||||||
// In other cases, resolved may be managing the system DNS configuration directly.
|
// In other cases, resolved may be managing the system DNS configuration directly.
|
||||||
// Then the nameserver list will be a concatenation of those for all
|
// Then the nameserver list will be a concatenation of those for all
|
||||||
// the interfaces that register their interest in being a default resolver with
|
// the interfaces that register their interest in being a default resolver with
|
||||||
// SetLinkDomains([]{{"~.", true}, ...})
|
//
|
||||||
|
// SetLinkDomains([]{{"~.", true}, ...})
|
||||||
|
//
|
||||||
// which includes at least the interface with the default route, i.e. not us.
|
// which includes at least the interface with the default route, i.e. not us.
|
||||||
// This does not work for us: there is a possibility of getting NXDOMAIN
|
// This does not work for us: there is a possibility of getting NXDOMAIN
|
||||||
// from the other nameservers before we are asked or get a chance to respond.
|
// from the other nameservers before we are asked or get a chance to respond.
|
||||||
|
@ -1025,11 +1025,11 @@ func marshalResponse(resp *response) ([]byte, error) {
|
|||||||
// https://tools.ietf.org/html/rfc6763 lists
|
// https://tools.ietf.org/html/rfc6763 lists
|
||||||
// "five special RR names" for Bonjour service discovery:
|
// "five special RR names" for Bonjour service discovery:
|
||||||
//
|
//
|
||||||
// b._dns-sd._udp.<domain>.
|
// b._dns-sd._udp.<domain>.
|
||||||
// db._dns-sd._udp.<domain>.
|
// db._dns-sd._udp.<domain>.
|
||||||
// r._dns-sd._udp.<domain>.
|
// r._dns-sd._udp.<domain>.
|
||||||
// dr._dns-sd._udp.<domain>.
|
// dr._dns-sd._udp.<domain>.
|
||||||
// lb._dns-sd._udp.<domain>.
|
// lb._dns-sd._udp.<domain>.
|
||||||
func hasRDNSBonjourPrefix(name dnsname.FQDN) bool {
|
func hasRDNSBonjourPrefix(name dnsname.FQDN) bool {
|
||||||
s := name.WithTrailingDot()
|
s := name.WithTrailingDot()
|
||||||
base, rest, ok := strings.Cut(s, ".")
|
base, rest, ok := strings.Cut(s, ".")
|
||||||
@ -1063,9 +1063,12 @@ func rawNameToLower(name []byte) string {
|
|||||||
// ptrNameToIPv4 transforms a PTR name representing an IPv4 address to said address.
|
// ptrNameToIPv4 transforms a PTR name representing an IPv4 address to said address.
|
||||||
// Such names are IPv4 labels in reverse order followed by .in-addr.arpa.
|
// Such names are IPv4 labels in reverse order followed by .in-addr.arpa.
|
||||||
// For example,
|
// For example,
|
||||||
// 4.3.2.1.in-addr.arpa
|
//
|
||||||
|
// 4.3.2.1.in-addr.arpa
|
||||||
|
//
|
||||||
// is transformed to
|
// is transformed to
|
||||||
// 1.2.3.4
|
//
|
||||||
|
// 1.2.3.4
|
||||||
func rdnsNameToIPv4(name dnsname.FQDN) (ip netip.Addr, ok bool) {
|
func rdnsNameToIPv4(name dnsname.FQDN) (ip netip.Addr, ok bool) {
|
||||||
s := strings.TrimSuffix(name.WithTrailingDot(), rdnsv4Suffix)
|
s := strings.TrimSuffix(name.WithTrailingDot(), rdnsv4Suffix)
|
||||||
ip, err := netip.ParseAddr(s)
|
ip, err := netip.ParseAddr(s)
|
||||||
@ -1082,9 +1085,12 @@ func rdnsNameToIPv4(name dnsname.FQDN) (ip netip.Addr, ok bool) {
|
|||||||
// ptrNameToIPv6 transforms a PTR name representing an IPv6 address to said address.
|
// ptrNameToIPv6 transforms a PTR name representing an IPv6 address to said address.
|
||||||
// Such names are dot-separated nibbles in reverse order followed by .ip6.arpa.
|
// Such names are dot-separated nibbles in reverse order followed by .ip6.arpa.
|
||||||
// For example,
|
// For example,
|
||||||
// b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
|
//
|
||||||
|
// b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
|
||||||
|
//
|
||||||
// is transformed to
|
// is transformed to
|
||||||
// 2001:db8::567:89ab
|
//
|
||||||
|
// 2001:db8::567:89ab
|
||||||
func rdnsNameToIPv6(name dnsname.FQDN) (ip netip.Addr, ok bool) {
|
func rdnsNameToIPv6(name dnsname.FQDN) (ip netip.Addr, ok bool) {
|
||||||
var b [32]byte
|
var b [32]byte
|
||||||
var ipb [16]byte
|
var ipb [16]byte
|
||||||
|
@ -39,7 +39,6 @@ func TestLikelyHomeRouterIPSyscallExec(t *testing.T) {
|
|||||||
10/16 link#4 UCS en0 !
|
10/16 link#4 UCS en0 !
|
||||||
10.0.0.1/32 link#4 UCS en0 !
|
10.0.0.1/32 link#4 UCS en0 !
|
||||||
...
|
...
|
||||||
|
|
||||||
*/
|
*/
|
||||||
func likelyHomeRouterIPDarwinExec() (ret netip.Addr, ok bool) {
|
func likelyHomeRouterIPDarwinExec() (ret netip.Addr, ok bool) {
|
||||||
if version.IsMobile() {
|
if version.IsMobile() {
|
||||||
|
@ -25,13 +25,13 @@
|
|||||||
// TCP RST, this includes a reason.
|
// TCP RST, this includes a reason.
|
||||||
//
|
//
|
||||||
// On the wire, after the IP header, it's currently 7 or 8 bytes:
|
// On the wire, after the IP header, it's currently 7 or 8 bytes:
|
||||||
// * '!'
|
// - '!'
|
||||||
// * IPProto byte (IANA protocol number: TCP or UDP)
|
// - IPProto byte (IANA protocol number: TCP or UDP)
|
||||||
// * 'A' or 'S' (RejectedDueToACLs, RejectedDueToShieldsUp)
|
// - 'A' or 'S' (RejectedDueToACLs, RejectedDueToShieldsUp)
|
||||||
// * srcPort big endian uint16
|
// - srcPort big endian uint16
|
||||||
// * dstPort big endian uint16
|
// - dstPort big endian uint16
|
||||||
// * [optional] byte of flag bits:
|
// - [optional] byte of flag bits:
|
||||||
// lowest bit (0x1): MaybeBroken
|
// lowest bit (0x1): MaybeBroken
|
||||||
//
|
//
|
||||||
// In the future it might also accept 16 byte IP flow src/dst IPs
|
// In the future it might also accept 16 byte IP flow src/dst IPs
|
||||||
// after the header, if they're different than the IP-level ones.
|
// after the header, if they're different than the IP-level ones.
|
||||||
@ -205,8 +205,8 @@ func (pp *Parsed) AsTailscaleRejectedHeader() (h TailscaleRejectedHeader, ok boo
|
|||||||
// TSMPPingRequest is a TSMP message that's like an ICMP ping request.
|
// TSMPPingRequest is a TSMP message that's like an ICMP ping request.
|
||||||
//
|
//
|
||||||
// On the wire, after the IP header, it's currently 9 bytes:
|
// On the wire, after the IP header, it's currently 9 bytes:
|
||||||
// * 'p' (TSMPTypePing)
|
// - 'p' (TSMPTypePing)
|
||||||
// * 8 opaque ping bytes to copy back in the response
|
// - 8 opaque ping bytes to copy back in the response
|
||||||
type TSMPPingRequest struct {
|
type TSMPPingRequest struct {
|
||||||
Data [8]byte
|
Data [8]byte
|
||||||
}
|
}
|
||||||
|
@ -164,19 +164,20 @@ func SetConfigExpectedCert(c *tls.Config, certDNSName string) {
|
|||||||
letsEncryptX1 is the LetsEncrypt X1 root:
|
letsEncryptX1 is the LetsEncrypt X1 root:
|
||||||
|
|
||||||
Certificate:
|
Certificate:
|
||||||
Data:
|
|
||||||
Version: 3 (0x2)
|
Data:
|
||||||
Serial Number:
|
Version: 3 (0x2)
|
||||||
82:10:cf:b0:d2:40:e3:59:44:63:e0:bb:63:82:8b:00
|
Serial Number:
|
||||||
Signature Algorithm: sha256WithRSAEncryption
|
82:10:cf:b0:d2:40:e3:59:44:63:e0:bb:63:82:8b:00
|
||||||
Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X1
|
Signature Algorithm: sha256WithRSAEncryption
|
||||||
Validity
|
Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X1
|
||||||
Not Before: Jun 4 11:04:38 2015 GMT
|
Validity
|
||||||
Not After : Jun 4 11:04:38 2035 GMT
|
Not Before: Jun 4 11:04:38 2015 GMT
|
||||||
Subject: C = US, O = Internet Security Research Group, CN = ISRG Root X1
|
Not After : Jun 4 11:04:38 2035 GMT
|
||||||
Subject Public Key Info:
|
Subject: C = US, O = Internet Security Research Group, CN = ISRG Root X1
|
||||||
Public Key Algorithm: rsaEncryption
|
Subject Public Key Info:
|
||||||
RSA Public-Key: (4096 bit)
|
Public Key Algorithm: rsaEncryption
|
||||||
|
RSA Public-Key: (4096 bit)
|
||||||
|
|
||||||
We bake it into the binary as a fallback verification root,
|
We bake it into the binary as a fallback verification root,
|
||||||
in case the system we're running on doesn't have it.
|
in case the system we're running on doesn't have it.
|
||||||
@ -189,7 +190,6 @@ func SetConfigExpectedCert(c *tls.Config, certDNSName string) {
|
|||||||
|
|
||||||
Then restart tailscaled. To also test dnsfallback's use of it, nuke
|
Then restart tailscaled. To also test dnsfallback's use of it, nuke
|
||||||
your /etc/resolv.conf and it should still start & run fine.
|
your /etc/resolv.conf and it should still start & run fine.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
const letsEncryptX1 = `
|
const letsEncryptX1 = `
|
||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
|
@ -13,11 +13,11 @@
|
|||||||
|
|
||||||
// TryConfigFileMigration carefully copies the contents of oldFile to
|
// TryConfigFileMigration carefully copies the contents of oldFile to
|
||||||
// newFile, returning the path which should be used to read the config.
|
// newFile, returning the path which should be used to read the config.
|
||||||
// - if newFile already exists, don't modify it just return its path
|
// - if newFile already exists, don't modify it just return its path
|
||||||
// - if neither oldFile nor newFile exist, return newFile for a fresh
|
// - if neither oldFile nor newFile exist, return newFile for a fresh
|
||||||
// default config to be written to.
|
// default config to be written to.
|
||||||
// - if oldFile exists but copying to newFile fails, return oldFile so
|
// - if oldFile exists but copying to newFile fails, return oldFile so
|
||||||
// there will at least be some config to work with.
|
// there will at least be some config to work with.
|
||||||
func TryConfigFileMigration(logf logger.Logf, oldFile, newFile string) string {
|
func TryConfigFileMigration(logf logger.Logf, oldFile, newFile string) string {
|
||||||
_, err := os.Stat(newFile)
|
_, err := os.Stat(newFile)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -18,12 +18,15 @@
|
|||||||
// Owner: The user for the current process;
|
// Owner: The user for the current process;
|
||||||
// Primary Group: The primary group for the current process;
|
// Primary Group: The primary group for the current process;
|
||||||
// DACL: Full control to the current user and to the Administrators group.
|
// DACL: Full control to the current user and to the Administrators group.
|
||||||
// (We include Administrators so that admin users may still access logs;
|
//
|
||||||
// granting access exclusively to LocalSystem would require admins to use
|
// (We include Administrators so that admin users may still access logs;
|
||||||
// special tools to access the Log directory)
|
// granting access exclusively to LocalSystem would require admins to use
|
||||||
|
// special tools to access the Log directory)
|
||||||
|
//
|
||||||
// Inheritance: The directory does not inherit the ACL from its parent.
|
// Inheritance: The directory does not inherit the ACL from its parent.
|
||||||
// However, any directories and/or files created within this
|
//
|
||||||
// directory *do* inherit the ACL that we are setting.
|
// However, any directories and/or files created within this
|
||||||
|
// directory *do* inherit the ACL that we are setting.
|
||||||
func ensureStateDirPerms(dirPath string) error {
|
func ensureStateDirPerms(dirPath string) error {
|
||||||
fi, err := os.Stat(dirPath)
|
fi, err := os.Stat(dirPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -239,13 +239,13 @@ func (v varExporter) String() string {
|
|||||||
// WritePrometheus writes the the state of all probes to w.
|
// WritePrometheus writes the the state of all probes to w.
|
||||||
//
|
//
|
||||||
// For each probe, WritePrometheus exports 5 variables:
|
// For each probe, WritePrometheus exports 5 variables:
|
||||||
// - <prefix>_interval_secs, how frequently the probe runs.
|
// - <prefix>_interval_secs, how frequently the probe runs.
|
||||||
// - <prefix>_start_secs, when the probe last started running, in seconds since epoch.
|
// - <prefix>_start_secs, when the probe last started running, in seconds since epoch.
|
||||||
// - <prefix>_end_secs, when the probe last finished running, in seconds since epoch.
|
// - <prefix>_end_secs, when the probe last finished running, in seconds since epoch.
|
||||||
// - <prefix>_latency_millis, how long the last probe cycle took, in
|
// - <prefix>_latency_millis, how long the last probe cycle took, in
|
||||||
// milliseconds. This is just (end_secs-start_secs) in an easier to
|
// milliseconds. This is just (end_secs-start_secs) in an easier to
|
||||||
// graph form.
|
// graph form.
|
||||||
// - <prefix>_result, 1 if the last probe succeeded, 0 if it failed.
|
// - <prefix>_result, 1 if the last probe succeeded, 0 if it failed.
|
||||||
//
|
//
|
||||||
// Each probe has a set of static key/value labels (defined once at
|
// Each probe has a set of static key/value labels (defined once at
|
||||||
// probe creation), which are added as Prometheus metric labels to
|
// probe creation), which are added as Prometheus metric labels to
|
||||||
|
@ -27,11 +27,12 @@ func setFlags(network, address string, c syscall.RawConn) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(apenwarr): use named pipes instead of sockets?
|
// TODO(apenwarr): use named pipes instead of sockets?
|
||||||
// I tried to use winio.ListenPipe() here, but that code is a disaster,
|
//
|
||||||
// built on top of an API that's a disaster. So for now we'll hack it by
|
// I tried to use winio.ListenPipe() here, but that code is a disaster,
|
||||||
// just always using a TCP session on a fixed port on localhost. As a
|
// built on top of an API that's a disaster. So for now we'll hack it by
|
||||||
// result, on Windows we ignore the vendor and name strings.
|
// just always using a TCP session on a fixed port on localhost. As a
|
||||||
// NOTE(bradfitz): Jason did a new pipe package: https://go-review.googlesource.com/c/sys/+/299009
|
// result, on Windows we ignore the vendor and name strings.
|
||||||
|
// NOTE(bradfitz): Jason did a new pipe package: https://go-review.googlesource.com/c/sys/+/299009
|
||||||
func listen(path string, port uint16) (_ net.Listener, gotPort uint16, _ error) {
|
func listen(path string, port uint16) (_ net.Listener, gotPort uint16, _ error) {
|
||||||
lc := net.ListenConfig{
|
lc := net.ListenConfig{
|
||||||
Control: setFlags,
|
Control: setFlags,
|
||||||
|
@ -26,8 +26,9 @@ func init() {
|
|||||||
// from /Library/Tailscale.
|
// from /Library/Tailscale.
|
||||||
//
|
//
|
||||||
// In that case the files are:
|
// In that case the files are:
|
||||||
// /Library/Tailscale/ipnport => $port (symlink with localhost port number target)
|
//
|
||||||
// /Library/Tailscale/sameuserproof-$port is a file with auth
|
// /Library/Tailscale/ipnport => $port (symlink with localhost port number target)
|
||||||
|
// /Library/Tailscale/sameuserproof-$port is a file with auth
|
||||||
func localTCPPortAndTokenMacsys() (port int, token string, err error) {
|
func localTCPPortAndTokenMacsys() (port int, token string, err error) {
|
||||||
|
|
||||||
const dir = "/Library/Tailscale"
|
const dir = "/Library/Tailscale"
|
||||||
|
@ -118,11 +118,11 @@ func socketPermissionsForOS() os.FileMode {
|
|||||||
// homebrew or go install). This little dance to connect a regular user binary
|
// homebrew or go install). This little dance to connect a regular user binary
|
||||||
// to the sandboxed network extension is:
|
// to the sandboxed network extension is:
|
||||||
//
|
//
|
||||||
// * the sandboxed IPNExtension picks a random localhost:0 TCP port
|
// - the sandboxed IPNExtension picks a random localhost:0 TCP port
|
||||||
// to listen on
|
// to listen on
|
||||||
// * it also picks a random hex string that acts as an auth token
|
// - it also picks a random hex string that acts as an auth token
|
||||||
// * the CLI looks on disk for that TCP port + auth token (see localTCPPortAndTokenDarwin)
|
// - the CLI looks on disk for that TCP port + auth token (see localTCPPortAndTokenDarwin)
|
||||||
// * we send it upon TCP connect to prove to the Tailscale daemon that
|
// - we send it upon TCP connect to prove to the Tailscale daemon that
|
||||||
// we're a suitably privileged user to have access the files on disk
|
// we're a suitably privileged user to have access the files on disk
|
||||||
// which the Network/App Extension wrote.
|
// which the Network/App Extension wrote.
|
||||||
func connectMacOSAppSandbox() (net.Conn, error) {
|
func connectMacOSAppSandbox() (net.Conn, error) {
|
||||||
|
@ -20,7 +20,7 @@ type DERPMap struct {
|
|||||||
OmitDefaultRegions bool `json:"omitDefaultRegions,omitempty"`
|
OmitDefaultRegions bool `json:"omitDefaultRegions,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
/// RegionIDs returns the sorted region IDs.
|
// / RegionIDs returns the sorted region IDs.
|
||||||
func (m *DERPMap) RegionIDs() []int {
|
func (m *DERPMap) RegionIDs() []int {
|
||||||
ret := make([]int, 0, len(m.Regions))
|
ret := make([]int, 0, len(m.Regions))
|
||||||
for rid := range m.Regions {
|
for rid := range m.Regions {
|
||||||
|
@ -37,37 +37,38 @@
|
|||||||
// CurrentCapabilityVersion is the current capability version of the codebase.
|
// CurrentCapabilityVersion is the current capability version of the codebase.
|
||||||
//
|
//
|
||||||
// History of versions:
|
// History of versions:
|
||||||
// 3: implicit compression, keep-alives
|
//
|
||||||
// 4: opt-in keep-alives via KeepAlive field, opt-in compression via Compress
|
// 3: implicit compression, keep-alives
|
||||||
// 5: 2020-10-19, implies IncludeIPv6, delta Peers/UserProfiles, supports MagicDNS
|
// 4: opt-in keep-alives via KeepAlive field, opt-in compression via Compress
|
||||||
// 6: 2020-12-07: means MapResponse.PacketFilter nil means unchanged
|
// 5: 2020-10-19, implies IncludeIPv6, delta Peers/UserProfiles, supports MagicDNS
|
||||||
// 7: 2020-12-15: FilterRule.SrcIPs accepts CIDRs+ranges, doesn't warn about 0.0.0.0/::
|
// 6: 2020-12-07: means MapResponse.PacketFilter nil means unchanged
|
||||||
// 8: 2020-12-19: client can buggily receive IPv6 addresses and routes if beta enabled server-side
|
// 7: 2020-12-15: FilterRule.SrcIPs accepts CIDRs+ranges, doesn't warn about 0.0.0.0/::
|
||||||
// 9: 2020-12-30: client doesn't auto-add implicit search domains from peers; only DNSConfig.Domains
|
// 8: 2020-12-19: client can buggily receive IPv6 addresses and routes if beta enabled server-side
|
||||||
// 10: 2021-01-17: client understands MapResponse.PeerSeenChange
|
// 9: 2020-12-30: client doesn't auto-add implicit search domains from peers; only DNSConfig.Domains
|
||||||
// 11: 2021-03-03: client understands IPv6, multiple default routes, and goroutine dumping
|
// 10: 2021-01-17: client understands MapResponse.PeerSeenChange
|
||||||
// 12: 2021-03-04: client understands PingRequest
|
// 11: 2021-03-03: client understands IPv6, multiple default routes, and goroutine dumping
|
||||||
// 13: 2021-03-19: client understands FilterRule.IPProto
|
// 12: 2021-03-04: client understands PingRequest
|
||||||
// 14: 2021-04-07: client understands DNSConfig.Routes and DNSConfig.Resolvers
|
// 13: 2021-03-19: client understands FilterRule.IPProto
|
||||||
// 15: 2021-04-12: client treats nil MapResponse.DNSConfig as meaning unchanged
|
// 14: 2021-04-07: client understands DNSConfig.Routes and DNSConfig.Resolvers
|
||||||
// 16: 2021-04-15: client understands Node.Online, MapResponse.OnlineChange
|
// 15: 2021-04-12: client treats nil MapResponse.DNSConfig as meaning unchanged
|
||||||
// 17: 2021-04-18: MapResponse.Domain empty means unchanged
|
// 16: 2021-04-15: client understands Node.Online, MapResponse.OnlineChange
|
||||||
// 18: 2021-04-19: MapResponse.Node nil means unchanged (all fields now omitempty)
|
// 17: 2021-04-18: MapResponse.Domain empty means unchanged
|
||||||
// 19: 2021-04-21: MapResponse.Debug.SleepSeconds
|
// 18: 2021-04-19: MapResponse.Node nil means unchanged (all fields now omitempty)
|
||||||
// 20: 2021-06-11: MapResponse.LastSeen used even less (https://github.com/tailscale/tailscale/issues/2107)
|
// 19: 2021-04-21: MapResponse.Debug.SleepSeconds
|
||||||
// 21: 2021-06-15: added MapResponse.DNSConfig.CertDomains
|
// 20: 2021-06-11: MapResponse.LastSeen used even less (https://github.com/tailscale/tailscale/issues/2107)
|
||||||
// 22: 2021-06-16: added MapResponse.DNSConfig.ExtraRecords
|
// 21: 2021-06-15: added MapResponse.DNSConfig.CertDomains
|
||||||
// 23: 2021-08-25: DNSConfig.Routes values may be empty (for ExtraRecords support in 1.14.1+)
|
// 22: 2021-06-16: added MapResponse.DNSConfig.ExtraRecords
|
||||||
// 24: 2021-09-18: MapResponse.Health from control to node; node shows in "tailscale status"
|
// 23: 2021-08-25: DNSConfig.Routes values may be empty (for ExtraRecords support in 1.14.1+)
|
||||||
// 25: 2021-11-01: MapResponse.Debug.Exit
|
// 24: 2021-09-18: MapResponse.Health from control to node; node shows in "tailscale status"
|
||||||
// 26: 2022-01-12: (nothing, just bumping for 1.20.0)
|
// 25: 2021-11-01: MapResponse.Debug.Exit
|
||||||
// 27: 2022-02-18: start of SSHPolicy being respected
|
// 26: 2022-01-12: (nothing, just bumping for 1.20.0)
|
||||||
// 28: 2022-03-09: client can communicate over Noise.
|
// 27: 2022-02-18: start of SSHPolicy being respected
|
||||||
// 29: 2022-03-21: MapResponse.PopBrowserURL
|
// 28: 2022-03-09: client can communicate over Noise.
|
||||||
// 30: 2022-03-22: client can request id tokens.
|
// 29: 2022-03-21: MapResponse.PopBrowserURL
|
||||||
// 31: 2022-04-15: PingRequest & PingResponse TSMP & disco support
|
// 30: 2022-03-22: client can request id tokens.
|
||||||
// 32: 2022-04-17: client knows FilterRule.CapMatch
|
// 31: 2022-04-15: PingRequest & PingResponse TSMP & disco support
|
||||||
// 33: 2022-07-20: added MapResponse.PeersChangedPatch (DERPRegion + Endpoints)
|
// 32: 2022-04-17: client knows FilterRule.CapMatch
|
||||||
|
// 33: 2022-07-20: added MapResponse.PeersChangedPatch (DERPRegion + Endpoints)
|
||||||
const CurrentCapabilityVersion CapabilityVersion = 33
|
const CurrentCapabilityVersion CapabilityVersion = 33
|
||||||
|
|
||||||
type StableID string
|
type StableID string
|
||||||
@ -746,6 +747,7 @@ func (st SignatureType) String() string {
|
|||||||
// RegisterRequest is sent by a client to register the key for a node.
|
// RegisterRequest is sent by a client to register the key for a node.
|
||||||
// It is encoded to JSON, encrypted with golang.org/x/crypto/nacl/box,
|
// It is encoded to JSON, encrypted with golang.org/x/crypto/nacl/box,
|
||||||
// using the local machine key, and sent to:
|
// using the local machine key, and sent to:
|
||||||
|
//
|
||||||
// https://login.tailscale.com/machine/<mkey hex>
|
// https://login.tailscale.com/machine/<mkey hex>
|
||||||
type RegisterRequest struct {
|
type RegisterRequest struct {
|
||||||
_ structs.Incomparable
|
_ structs.Incomparable
|
||||||
@ -864,6 +866,7 @@ type Endpoint struct {
|
|||||||
//
|
//
|
||||||
// The request is encoded to JSON, encrypted with golang.org/x/crypto/nacl/box,
|
// The request is encoded to JSON, encrypted with golang.org/x/crypto/nacl/box,
|
||||||
// using the local machine key, and sent to:
|
// using the local machine key, and sent to:
|
||||||
|
//
|
||||||
// https://login.tailscale.com/machine/<mkey hex>/map
|
// https://login.tailscale.com/machine/<mkey hex>/map
|
||||||
type MapRequest struct {
|
type MapRequest struct {
|
||||||
// Version is incremented whenever the client code changes enough that
|
// Version is incremented whenever the client code changes enough that
|
||||||
@ -1514,6 +1517,7 @@ type Oauth2Token struct {
|
|||||||
//
|
//
|
||||||
// The request is encoded to JSON, encrypted with golang.org/x/crypto/nacl/box,
|
// The request is encoded to JSON, encrypted with golang.org/x/crypto/nacl/box,
|
||||||
// using the local machine key, and sent to:
|
// using the local machine key, and sent to:
|
||||||
|
//
|
||||||
// https://login.tailscale.com/machine/<mkey hex>/set-dns
|
// https://login.tailscale.com/machine/<mkey hex>/set-dns
|
||||||
type SetDNSRequest struct {
|
type SetDNSRequest struct {
|
||||||
// Version is the client's capabilities
|
// Version is the client's capabilities
|
||||||
|
@ -10,29 +10,29 @@
|
|||||||
ListenAndServe starts an SSH server with a given address, handler, and options. The
|
ListenAndServe starts an SSH server with a given address, handler, and options. The
|
||||||
handler is usually nil, which means to use DefaultHandler. Handle sets DefaultHandler:
|
handler is usually nil, which means to use DefaultHandler. Handle sets DefaultHandler:
|
||||||
|
|
||||||
ssh.Handle(func(s ssh.Session) {
|
ssh.Handle(func(s ssh.Session) {
|
||||||
io.WriteString(s, "Hello world\n")
|
io.WriteString(s, "Hello world\n")
|
||||||
})
|
})
|
||||||
|
|
||||||
log.Fatal(ssh.ListenAndServe(":2222", nil))
|
log.Fatal(ssh.ListenAndServe(":2222", nil))
|
||||||
|
|
||||||
If you don't specify a host key, it will generate one every time. This is convenient
|
If you don't specify a host key, it will generate one every time. This is convenient
|
||||||
except you'll have to deal with clients being confused that the host key is different.
|
except you'll have to deal with clients being confused that the host key is different.
|
||||||
It's a better idea to generate or point to an existing key on your system:
|
It's a better idea to generate or point to an existing key on your system:
|
||||||
|
|
||||||
log.Fatal(ssh.ListenAndServe(":2222", nil, ssh.HostKeyFile("/Users/progrium/.ssh/id_rsa")))
|
log.Fatal(ssh.ListenAndServe(":2222", nil, ssh.HostKeyFile("/Users/progrium/.ssh/id_rsa")))
|
||||||
|
|
||||||
Although all options have functional option helpers, another way to control the
|
Although all options have functional option helpers, another way to control the
|
||||||
server's behavior is by creating a custom Server:
|
server's behavior is by creating a custom Server:
|
||||||
|
|
||||||
s := &ssh.Server{
|
s := &ssh.Server{
|
||||||
Addr: ":2222",
|
Addr: ":2222",
|
||||||
Handler: sessionHandler,
|
Handler: sessionHandler,
|
||||||
PublicKeyHandler: authHandler,
|
PublicKeyHandler: authHandler,
|
||||||
}
|
}
|
||||||
s.AddHostKey(hostKeySigner)
|
s.AddHostKey(hostKeySigner)
|
||||||
|
|
||||||
log.Fatal(s.ListenAndServe())
|
log.Fatal(s.ListenAndServe())
|
||||||
|
|
||||||
This package automatically handles basic SSH requests like setting environment
|
This package automatically handles basic SSH requests like setting environment
|
||||||
variables, requesting PTY, and changing window size. These requests are
|
variables, requesting PTY, and changing window size. These requests are
|
||||||
|
@ -582,17 +582,17 @@ funcRet = fmt.Sprintf(" returning %T", v)
|
|||||||
// VarzHandler is an HTTP handler to write expvar values into the
|
// VarzHandler is an HTTP handler to write expvar values into the
|
||||||
// prometheus export format:
|
// prometheus export format:
|
||||||
//
|
//
|
||||||
// https://github.com/prometheus/docs/blob/master/content/docs/instrumenting/exposition_formats.md
|
// https://github.com/prometheus/docs/blob/master/content/docs/instrumenting/exposition_formats.md
|
||||||
//
|
//
|
||||||
// It makes the following assumptions:
|
// It makes the following assumptions:
|
||||||
//
|
//
|
||||||
// * *expvar.Int are counters (unless marked as a gauge_; see below)
|
// - *expvar.Int are counters (unless marked as a gauge_; see below)
|
||||||
// * a *tailscale/metrics.Set is descended into, joining keys with
|
// - a *tailscale/metrics.Set is descended into, joining keys with
|
||||||
// underscores. So use underscores as your metric names.
|
// underscores. So use underscores as your metric names.
|
||||||
// * an expvar named starting with "gauge_" or "counter_" is of that
|
// - an expvar named starting with "gauge_" or "counter_" is of that
|
||||||
// Prometheus type, and has that prefix stripped.
|
// Prometheus type, and has that prefix stripped.
|
||||||
// * anything else is untyped and thus not exported.
|
// - anything else is untyped and thus not exported.
|
||||||
// * expvar.Func can return an int or int64 (for now) and anything else
|
// - expvar.Func can return an int or int64 (for now) and anything else
|
||||||
// is not exported.
|
// is not exported.
|
||||||
//
|
//
|
||||||
// This will evolve over time, or perhaps be replaced.
|
// This will evolve over time, or perhaps be replaced.
|
||||||
|
@ -12,10 +12,11 @@
|
|||||||
|
|
||||||
// It's similar in function to golang.org/x/time/rate.Limiter, which we
|
// It's similar in function to golang.org/x/time/rate.Limiter, which we
|
||||||
// can't use because:
|
// can't use because:
|
||||||
// - It doesn't give access to the number of accumulated tokens, which we
|
// - It doesn't give access to the number of accumulated tokens, which we
|
||||||
// need for implementing hysteresis;
|
// need for implementing hysteresis;
|
||||||
// - It doesn't let us provide our own time function, which we need for
|
// - It doesn't let us provide our own time function, which we need for
|
||||||
// implementing proper unit tests.
|
// implementing proper unit tests.
|
||||||
|
//
|
||||||
// rate.Limiter is also much more complex than necessary, but that wouldn't
|
// rate.Limiter is also much more complex than necessary, but that wouldn't
|
||||||
// be enough to disqualify it on its own.
|
// be enough to disqualify it on its own.
|
||||||
//
|
//
|
||||||
|
@ -216,11 +216,11 @@ func WritePrometheusExpositionFormat(w io.Writer) {
|
|||||||
// without further escaping.
|
// without further escaping.
|
||||||
//
|
//
|
||||||
// The current encoding is:
|
// The current encoding is:
|
||||||
// * name immediately following metric:
|
// - name immediately following metric:
|
||||||
// 'N' + hex(varint(len(name))) + name
|
// 'N' + hex(varint(len(name))) + name
|
||||||
// * set value of a metric:
|
// - set value of a metric:
|
||||||
// 'S' + hex(varint(wireid)) + hex(varint(value))
|
// 'S' + hex(varint(wireid)) + hex(varint(value))
|
||||||
// * increment a metric: (decrements if negative)
|
// - increment a metric: (decrements if negative)
|
||||||
// 'I' + hex(varint(wireid)) + hex(varint(value))
|
// 'I' + hex(varint(wireid)) + hex(varint(value))
|
||||||
func EncodeLogTailMetricsDelta() string {
|
func EncodeLogTailMetricsDelta() string {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
|
@ -9,11 +9,11 @@
|
|||||||
// Hash(x) == Hash(y) is an appropriate replacement for x == y.
|
// Hash(x) == Hash(y) is an appropriate replacement for x == y.
|
||||||
//
|
//
|
||||||
// The definition of equality is identical to reflect.DeepEqual except:
|
// The definition of equality is identical to reflect.DeepEqual except:
|
||||||
// * Floating-point values are compared based on the raw bits,
|
// - Floating-point values are compared based on the raw bits,
|
||||||
// which means that NaNs (with the same bit pattern) are treated as equal.
|
// which means that NaNs (with the same bit pattern) are treated as equal.
|
||||||
// * Types which implement interface { AppendTo([]byte) []byte } use
|
// - Types which implement interface { AppendTo([]byte) []byte } use
|
||||||
// the AppendTo method to produce a textual representation of the value.
|
// the AppendTo method to produce a textual representation of the value.
|
||||||
// Thus, two values are equal if AppendTo produces the same bytes.
|
// Thus, two values are equal if AppendTo produces the same bytes.
|
||||||
//
|
//
|
||||||
// WARNING: This package, like most of the tailscale.com Go module,
|
// WARNING: This package, like most of the tailscale.com Go module,
|
||||||
// should be considered Tailscale-internal; we make no API promises.
|
// should be considered Tailscale-internal; we make no API promises.
|
||||||
|
@ -34,8 +34,9 @@ func (e Error) Errors() []error {
|
|||||||
|
|
||||||
// New returns an error composed from errs.
|
// New returns an error composed from errs.
|
||||||
// Some errors in errs get special treatment:
|
// Some errors in errs get special treatment:
|
||||||
// * nil errors are discarded
|
// - nil errors are discarded
|
||||||
// * errors of type Error are expanded into the top level
|
// - errors of type Error are expanded into the top level
|
||||||
|
//
|
||||||
// If the resulting slice has length 0, New returns nil.
|
// If the resulting slice has length 0, New returns nil.
|
||||||
// If the resulting slice has length 1, New returns that error.
|
// If the resulting slice has length 1, New returns that error.
|
||||||
// If the resulting slice has length > 1, New returns that slice as an Error.
|
// If the resulting slice has length > 1, New returns that slice as an Error.
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
// This is a Tailscale fork of Go's singleflight package which has had several
|
// This is a Tailscale fork of Go's singleflight package which has had several
|
||||||
// homes in the past:
|
// homes in the past:
|
||||||
//
|
//
|
||||||
// * https://github.com/golang/go/commit/61d3b2db6292581fc07a3767ec23ec94ad6100d1
|
// - https://github.com/golang/go/commit/61d3b2db6292581fc07a3767ec23ec94ad6100d1
|
||||||
// * https://github.com/golang/groupcache/tree/master/singleflight
|
// - https://github.com/golang/groupcache/tree/master/singleflight
|
||||||
// * https://pkg.go.dev/golang.org/x/sync/singleflight
|
// - https://pkg.go.dev/golang.org/x/sync/singleflight
|
||||||
//
|
//
|
||||||
// This fork adds generics.
|
// This fork adds generics.
|
||||||
package singleflight // import "tailscale.com/util/singleflight"
|
package singleflight // import "tailscale.com/util/singleflight"
|
||||||
|
@ -59,18 +59,18 @@ func Ready() {
|
|||||||
// Status sends a single line status update to systemd so that information shows up
|
// Status sends a single line status update to systemd so that information shows up
|
||||||
// in systemctl output. For example:
|
// in systemctl output. For example:
|
||||||
//
|
//
|
||||||
// $ systemctl status tailscale
|
// $ systemctl status tailscale
|
||||||
// ● tailscale.service - Tailscale client daemon
|
// ● tailscale.service - Tailscale client daemon
|
||||||
// Loaded: loaded (/nix/store/qc312qcy907wz80fqrgbbm8a9djafmlg-unit-tailscale.service/tailscale.service; enabled; vendor preset: enabled)
|
// Loaded: loaded (/nix/store/qc312qcy907wz80fqrgbbm8a9djafmlg-unit-tailscale.service/tailscale.service; enabled; vendor preset: enabled)
|
||||||
// Active: active (running) since Tue 2020-11-24 17:54:07 EST; 13h ago
|
// Active: active (running) since Tue 2020-11-24 17:54:07 EST; 13h ago
|
||||||
// Main PID: 26741 (.tailscaled-wra)
|
// Main PID: 26741 (.tailscaled-wra)
|
||||||
// Status: "Connected; user@host.domain.tld; 100.101.102.103"
|
// Status: "Connected; user@host.domain.tld; 100.101.102.103"
|
||||||
// IP: 0B in, 0B out
|
// IP: 0B in, 0B out
|
||||||
// Tasks: 22 (limit: 4915)
|
// Tasks: 22 (limit: 4915)
|
||||||
// Memory: 30.9M
|
// Memory: 30.9M
|
||||||
// CPU: 2min 38.469s
|
// CPU: 2min 38.469s
|
||||||
// CGroup: /system.slice/tailscale.service
|
// CGroup: /system.slice/tailscale.service
|
||||||
// └─26741 /nix/store/sv6cj4mw2jajm9xkbwj07k29dj30lh0n-tailscale-date.20200727/bin/tailscaled --port 41641
|
// └─26741 /nix/store/sv6cj4mw2jajm9xkbwj07k29dj30lh0n-tailscale-date.20200727/bin/tailscaled --port 41641
|
||||||
func Status(format string, args ...any) {
|
func Status(format string, args ...any) {
|
||||||
err := notifier().Notify(sdnotify.Statusf(format, args...))
|
err := notifier().Notify(sdnotify.Statusf(format, args...))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -245,17 +245,17 @@ func maybeHexdump(flag RunFlags, b []byte) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(apenwarr): use a bigger bucket for specifically TCP SYN accept logging?
|
// TODO(apenwarr): use a bigger bucket for specifically TCP SYN accept logging?
|
||||||
// Logging is a quick way to record every newly opened TCP connection, but
|
// Logging is a quick way to record every newly opened TCP connection, but
|
||||||
// we have to be cautious about flooding the logs vs letting people use
|
// we have to be cautious about flooding the logs vs letting people use
|
||||||
// flood protection to hide their traffic. We could use a rate limiter in
|
// flood protection to hide their traffic. We could use a rate limiter in
|
||||||
// the actual *filter* for SYN accepts, perhaps.
|
// the actual *filter* for SYN accepts, perhaps.
|
||||||
var acceptBucket = rate.NewLimiter(rate.Every(10*time.Second), 3)
|
var acceptBucket = rate.NewLimiter(rate.Every(10*time.Second), 3)
|
||||||
var dropBucket = rate.NewLimiter(rate.Every(5*time.Second), 10)
|
var dropBucket = rate.NewLimiter(rate.Every(5*time.Second), 10)
|
||||||
|
|
||||||
// NOTE(Xe): This func init is used to detect
|
// NOTE(Xe): This func init is used to detect
|
||||||
// TS_DEBUG_FILTER_RATE_LIMIT_LOGS=all, and if it matches, to
|
// TS_DEBUG_FILTER_RATE_LIMIT_LOGS=all, and if it matches, to
|
||||||
// effectively disable the limits on the log rate by setting the limit
|
// effectively disable the limits on the log rate by setting the limit
|
||||||
// to 1 millisecond. This should capture everything.
|
// to 1 millisecond. This should capture everything.
|
||||||
func init() {
|
func init() {
|
||||||
if envknob.String("TS_DEBUG_FILTER_RATE_LIMIT_LOGS") != "all" {
|
if envknob.String("TS_DEBUG_FILTER_RATE_LIMIT_LOGS") != "all" {
|
||||||
return
|
return
|
||||||
|
@ -102,10 +102,10 @@ func MatchesFromFilterRules(pf []tailcfg.FilterRule) ([]Match, error) {
|
|||||||
|
|
||||||
// parseIPSet parses arg as one:
|
// parseIPSet parses arg as one:
|
||||||
//
|
//
|
||||||
// * an IP address (IPv4 or IPv6)
|
// - an IP address (IPv4 or IPv6)
|
||||||
// * the string "*" to match everything (both IPv4 & IPv6)
|
// - the string "*" to match everything (both IPv4 & IPv6)
|
||||||
// * a CIDR (e.g. "192.168.0.0/16")
|
// - a CIDR (e.g. "192.168.0.0/16")
|
||||||
// * a range of two IPs, inclusive, separated by hyphen ("2eff::1-2eff::0800")
|
// - a range of two IPs, inclusive, separated by hyphen ("2eff::1-2eff::0800")
|
||||||
//
|
//
|
||||||
// bits, if non-nil, is the legacy SrcBits CIDR length to make a IP
|
// bits, if non-nil, is the legacy SrcBits CIDR length to make a IP
|
||||||
// address (without a slash) treated as a CIDR of *bits length.
|
// address (without a slash) treated as a CIDR of *bits length.
|
||||||
|
@ -1833,10 +1833,10 @@ func (c *Conn) sendDiscoMessage(dst netip.AddrPort, dstKey key.NodePublic, dstDi
|
|||||||
//
|
//
|
||||||
// A discovery message has the form:
|
// A discovery message has the form:
|
||||||
//
|
//
|
||||||
// * magic [6]byte
|
// - magic [6]byte
|
||||||
// * senderDiscoPubKey [32]byte
|
// - senderDiscoPubKey [32]byte
|
||||||
// * nonce [24]byte
|
// - nonce [24]byte
|
||||||
// * naclbox of payload (see tailscale.com/disco package for inner payload format)
|
// - naclbox of payload (see tailscale.com/disco package for inner payload format)
|
||||||
//
|
//
|
||||||
// For messages received over DERP, the src.Addr() will be derpMagicIP (with
|
// For messages received over DERP, the src.Addr() will be derpMagicIP (with
|
||||||
// src.Port() being the region ID) and the derpNodeSrc will be the node key
|
// src.Port() being the region ID) and the derpNodeSrc will be the node key
|
||||||
|
@ -517,8 +517,8 @@ func (e *userspaceEngine) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper)
|
|||||||
|
|
||||||
// pollResolver reads packets from the DNS resolver and injects them inbound.
|
// pollResolver reads packets from the DNS resolver and injects them inbound.
|
||||||
//
|
//
|
||||||
// TODO(tom): Remove this fallback path (via NextPacket()) once
|
// TODO(tom): Remove this fallback path (via NextPacket()) once all
|
||||||
// all platforms use netstack.
|
// platforms use netstack.
|
||||||
func (e *userspaceEngine) pollResolver() {
|
func (e *userspaceEngine) pollResolver() {
|
||||||
for {
|
for {
|
||||||
bs, err := e.dns.NextPacket()
|
bs, err := e.dns.NextPacket()
|
||||||
@ -1503,7 +1503,6 @@ func (e *userspaceEngine) WhoIsIPPort(ipport netip.AddrPort) (tsIP netip.Addr, o
|
|||||||
// If none is found in the wireguard config but one is found in
|
// If none is found in the wireguard config but one is found in
|
||||||
// the netmap, it's described in an error.
|
// the netmap, it's described in an error.
|
||||||
//
|
//
|
||||||
//
|
|
||||||
// peerForIP acquires both e.mu and e.wgLock, but neither at the same
|
// peerForIP acquires both e.mu and e.wgLock, but neither at the same
|
||||||
// time.
|
// time.
|
||||||
func (e *userspaceEngine) PeerForIP(ip netip.Addr) (ret PeerForIP, ok bool) {
|
func (e *userspaceEngine) PeerForIP(ip netip.Addr) (ret PeerForIP, ok bool) {
|
||||||
|
Loading…
Reference in New Issue
Block a user