summaryrefslogtreecommitdiffhomepage
path: root/util/deephash
AgeCommit message (Collapse)AuthorFilesLines
2026-04-05cmd/vet: add subtestnames analyzer; fix all existing violationsBrad Fitzpatrick1-4/+4
Add a new vet analyzer that checks t.Run subtest names don't contain characters requiring quoting when re-running via "go test -run". This enforces the style guide rule: don't use spaces or punctuation in subtest names. The analyzer flags: - Direct t.Run calls with string literal names containing spaces, regex metacharacters, quotes, or other problematic characters - Table-driven t.Run(tt.name, ...) calls where tt ranges over a slice/map literal with bad name field values Also fix all 978 existing violations across 81 test files, replacing spaces with hyphens and shortening long sentence-like names to concise hyphenated forms. Updates #19242 Change-Id: Ib0ad96a111bd8e764582d1d4902fe2599454ab65 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-05types/ptr: deprecate ptr.To, use Go 1.26 newBrad Fitzpatrick1-5/+4
Updates #18682 Change-Id: I62f6aa0de2a15ef8c1435032c6aa74a181c25f8f Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-01-23all: remove AUTHORS file and references to itWill Norris10-10/+10
This file was never truly necessary and has never actually been used in the history of Tailscale's open source releases. A Brief History of AUTHORS files --- The AUTHORS file was a pattern developed at Google, originally for Chromium, then adopted by Go and a bunch of other projects. The problem was that Chromium originally had a copyright line only recognizing Google as the copyright holder. Because Google (and most open source projects) do not require copyright assignemnt for contributions, each contributor maintains their copyright. Some large corporate contributors then tried to add their own name to the copyright line in the LICENSE file or in file headers. This quickly becomes unwieldy, and puts a tremendous burden on anyone building on top of Chromium, since the license requires that they keep all copyright lines intact. The compromise was to create an AUTHORS file that would list all of the copyright holders. The LICENSE file and source file headers would then include that list by reference, listing the copyright holder as "The Chromium Authors". This also become cumbersome to simply keep the file up to date with a high rate of new contributors. Plus it's not always obvious who the copyright holder is. Sometimes it is the individual making the contribution, but many times it may be their employer. There is no way for the proejct maintainer to know. Eventually, Google changed their policy to no longer recommend trying to keep the AUTHORS file up to date proactively, and instead to only add to it when requested: https://opensource.google/docs/releasing/authors. They are also clear that: > Adding contributors to the AUTHORS file is entirely within the > project's discretion and has no implications for copyright ownership. It was primarily added to appease a small number of large contributors that insisted that they be recognized as copyright holders (which was entirely their right to do). But it's not truly necessary, and not even the most accurate way of identifying contributors and/or copyright holders. In practice, we've never added anyone to our AUTHORS file. It only lists Tailscale, so it's not really serving any purpose. It also causes confusion because Tailscalars put the "Tailscale Inc & AUTHORS" header in other open source repos which don't actually have an AUTHORS file, so it's ambiguous what that means. Instead, we just acknowledge that the contributors to Tailscale (whoever they are) are copyright holders for their individual contributions. We also have the benefit of using the DCO (developercertificate.org) which provides some additional certification of their right to make the contribution. The source file changes were purely mechanical with: git ls-files | xargs sed -i -e 's/\(Tailscale Inc &\) AUTHORS/\1 contributors/g' Updates #cleanup Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d Signed-off-by: Will Norris <will@tailscale.com>
2025-11-12wgengine/wgcfg: remove two unused Config fieldsBrad Fitzpatrick1-1/+0
They distracted me in some refactoring. They're set but never used. Updates #17858 Change-Id: I6ec7d6841ab684a55bccca7b7cbf7da9c782694f Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-05-08util/deephash: move tests that depend on other tailscale packages to ↵Nick Khyl2-156/+177
deephash_test This is done to prevent import cycles in tests. Fixes #15923 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2024-06-19util/deephash: fix test regression on 32-bitBrad Fitzpatrick1-1/+1
Fix regression from bd93c3067e4adf where I didn't notice the 32-bit test failure was real and not its usual slowness-related regression. Yay failure blindness. Updates #12526 Change-Id: I00e33bba697e2cdb61a0d76a71b62406f6c2eeb9 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-06-18tailcfg, wgengine/filter: remove most FilterRule.SrcBits codeBrad Fitzpatrick1-4/+3
The control plane hasn't sent it to clients in ages. Updates tailscale/corp#20965 Change-Id: I1d71a4b6dd3f75010a05c544ee39827837c30772 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-06-18wgengine/filter/filtertype: make Match.IPProto a viewBrad Fitzpatrick1-1/+2
I noticed we were allocating these every time when they could just share the same memory. Rather than document ownership, just lock it down with a view. I was considering doing all of the fields but decided to just do this one first as test to see how infectious it became. Conclusion: not very. Updates #cleanup (while working towards tailscale/corp#20514) Change-Id: I8ce08519de0c9a53f20292adfbecd970fe362de0 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-04-16all: use Go 1.22 range-over-intBrad Fitzpatrick2-15/+15
Updates #11058 Change-Id: I35e7ef9b90e83cac04ca93fd964ad00ed5b48430 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-02-08all: use reflect.TypeFor now available in Go 1.22 (#11078)Joe Tsai3-9/+7
Updates #cleanup Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2024-02-08util/deephash: cleanup TODO in TestHash (#11080)Joe Tsai1-7/+1
Updates #cleanup Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2024-02-01util/deephash: tighten up SelfHasher API (#11012)Joe Tsai4-36/+85
Providing a hash.Block512 is an implementation detail of how deephash works today, but providing an opaque type with mostly equivalent API (i.e., HashUint8, HashBytes, etc. methods) is still sensible. Thus, define a public Hasher type that exposes exactly the API that an implementation of SelfHasher would want to call. This gives us freedom to change the hashing algorithm of deephash at some point in the future. Also, this type is likely going to be called by types that are going to memoize their own hash results, we additionally add a HashSum method to simplify this use case. Add documentation to SelfHasher on how a type might implement it. Updates: corp#16409 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2024-02-01util/deephash: document pathological deephash behavior (#11010)Joe Tsai1-0/+43
Updates #cleanup Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2024-02-01util/deephash: implement SelfHasher to allow types to hash themselvesTom DNetto4-2/+62
Updates: corp#16409 Signed-off-by: Tom DNetto <tom@tailscale.com>
2023-12-20all: cleanup unused code, part 1 (#10661)Andrew Lytvynov2-5/+4
Run `staticcheck` with `U1000` to find unused code. This cleans up about a half of it. I'll do the other half separately to keep PRs manageable. Updates #cleanup Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2023-08-27util/deephash: add IncludeFields, ExcludeFields HasherForType OptionsBrad Fitzpatrick2-7/+138
Updates tailscale/corp#6198 Change-Id: Iafc18c5b947522cf07a42a56f35c0319cc7b1c94 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-08-19util/deephash: relax an annoyingly needy testBrad Fitzpatrick1-3/+3
I'd added a test case of deephash against a tailcfg.Node to make sure it worked at all more than anything. We don't care what the exact bytes are in this test, just that it doesn't fail. So adjust for that. Then when we make changes to tailcfg.Node and types under it, we don't need to keep adjusting this test. Updates #cleanup Change-Id: Ibf4fa42820aeab8f5292fe65f9f92ffdb0b4407b Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-08-08all: require Go 1.21Brad Fitzpatrick1-6/+2
Updates #8419 Change-Id: I809b6a4d59d92a2ab6ec587ccbb9053376bf02c2 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-07-25tailcfg,ipn/ipnlocal,wgengine: add values to PeerCapabilitiesMaisem Ali1-1/+1
Define PeerCapabilty and PeerCapMap as the new way of sending down inter-peer capability information. Previously, this was unstructured and you could only send down strings which got too limiting for certain usecases. Instead add the ability to send down raw JSON messages that are opaque to Tailscale but provide the applications to define them however they wish. Also update accessors to use the new values. Updates #4217 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-07-08tailcfg,etc: remove unused tailcfg.Node.KeepAlive fieldBrad Fitzpatrick1-2/+2
The server hasn't sent it in ages. Updates #cleanup Change-Id: I9695ab0f074ec6fb006e11faf3cdfc5ca049fbf8 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-06-25.github: actually run tests in CIMaisem Ali1-3/+13
Updates #cleanup Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-04-13tailcfg: make SelfNodeV4MasqAddrForThisPeer a pointerMaisem Ali1-2/+2
This makes `omitempty` actually work, and saves bytes in each map response. Updates tailscale/corp#8020 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-04-08tailcfg,wgengine: add initial support for WireGuard only peersCharlotte Brandhorst-Satzkorn1-2/+2
A peer can have IsWireGuardOnly, which means it will not support DERP or Disco, and it must have Endpoints filled in order to be usable. In the present implementation only the first Endpoint will be used as the bestAddr. Updates tailscale/corp#10351 Co-authored-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com> Co-authored-by: James Tucker <james@tailscale.com> Signed-off-by: James Tucker <james@tailscale.com>
2023-03-23tailcfg: add Node.SelfNodeV4MasqAddrForThisPeerMaisem Ali1-2/+2
This only adds the field, to be used in a future commit. Updates tailscale/corp#8020 Co-authored-by: Melanie Warrick <warrick@tailscale.com> Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-02-01all: update to Go 1.20, use strings.CutPrefix/Suffix instead of our forkBrad Fitzpatrick1-2/+2
Updates #7123 Updates #5309 Change-Id: I90bcd87a2fb85a91834a0dd4be6e03db08438672 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-01-27all: update copyright and license headersWill Norris9-27/+18
This updates all source files to use a new standard header for copyright and license declaration. Notably, copyright no longer includes a date, and we now use the standard SPDX-License-Identifier header. This commit was done almost entirely mechanically with perl, and then some minimal manual fixes. Updates #6865 Signed-off-by: Will Norris <will@tailscale.com>
2023-01-19all: start groundwork for using capver for localapi & peerapiBrad Fitzpatrick1-3/+4
Updates #7015 Change-Id: I3d4c11b42a727a62eaac3262a879f29bb4ce82dd Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-01-11control/controlclient, tailcfg: add Node.Expired field, set for expired nodesAndrew Dunham1-1/+1
Nodes that are expired, taking into account the time delta calculated from MapResponse.ControlTime have the newly-added Expired boolean set. For additional defense-in-depth, also replicate what control does and clear the Endpoints and DERP fields, and additionally set the node key to a bogus value. Updates #6932 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: Ia2bd6b56064416feee28aef5699ca7090940662a
2022-11-30types/ptr: move all the ptrTo funcs to one new package's ptr.ToBrad Fitzpatrick1-6/+5
Change-Id: Ia0b820ffe7aa72897515f19bd415204b6fe743c7 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2022-11-02tailcfg: add Node.UnsignedPeerAPIOnly to let server mark node as peerapi-onlyBrad Fitzpatrick1-1/+1
capver 48 Change-Id: I20b2fa81d61ef8cc8a84e5f2afeefb68832bd904 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2022-09-29all: fix spelling mistakesJosh Soref3-8/+8
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2022-09-27util/deephash: add AppendSum method (#5768)Andrew Dunham2-0/+33
This method can be used to obtain the hex-formatted deephash.Sum instance without allocations. Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
2022-09-22tailcfg, util/deephash: add DataPlaneAuditLogID to Node and ↵Aaron Klotz1-1/+1
DomainDataPlaneAuditLogID to MapResponse We're adding two log IDs to facilitate data-plane audit logging: a node-specific log ID, and a domain-specific log ID. Updated util/deephash/deephash_test.go with revised expectations for tailcfg.Node. Updates https://github.com/tailscale/corp/issues/6991 Signed-off-by: Aaron Klotz <aaron@tailscale.com>
2022-08-30util/deephash: handle slice edge-cases (#5471)Joe Tsai2-6/+84
It is unclear whether the lack of checking nil-ness of slices was an oversight or a deliberate feature. Lacking a comment, the assumption is that this was an oversight. Also, expand the logic to perform cycle detection for recursive slices. We do this on a per-element basis since a slice is semantically equivalent to a list of pointers. Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2022-08-27util/deephash: remove getTypeInfo (#5469)Joe Tsai2-93/+32
Add a new lookupTypeHasher function that is just a cached front-end around the makeTypeHasher function. We do not need to worry about the recursive type cycle issue that made getTypeInfo more complicated since makeTypeHasher is not directly recursive. All calls to itself happen lazily through a sync.Once upon first use. Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2022-08-27util/deephash: require pointer in API (#5467)Joe Tsai2-122/+97
The entry logic of Hash has extra complexity to make sure we always have an addressable value on hand. If not, we heap allocate the input. For this reason we document that there are performance benefits to always providing a pointer. Rather than documenting this, just enforce it through generics. Also, delete the unused HasherForType function. It's an interesting use of generics, but not well tested. We can resurrect it from code history if there's a need for it. Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2022-08-27util/deephash: move pointer and interface logic to separate function (#5465)Joe Tsai1-35/+49
This helps pprof better identify which Go kinds take the most time since the kind is always in the function name. Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2022-08-27util/deephash: move map logic to separate function (#5464)Joe Tsai2-57/+64
This helps pprof better identify which Go kinds take the most time since the kind is always in the function name. There is a minor adjustment where we hash the length of the map to be more on the cautious side. Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2022-08-27util/deephash: coalesce struct logic (#5466)Joe Tsai1-64/+48
Rather than having two copies []fieldInfo, just maintain one and perform merging in the same pass. Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2022-08-27util/deephash: move array and slice logic to separate function (#5463)Joe Tsai1-41/+39
This helps pprof better identify which Go kinds take the most time since the kind is always in the function name. Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2022-08-27util/deephash: use unsafe.Pointer instead of reflect.Value (#5459)Joe Tsai5-162/+408
Use of reflect.Value.SetXXX panics if the provided argument was obtained from an unexported struct field. Instead, pass an unsafe.Pointer around and convert to a reflect.Value when necessary (i.e., for maps and interfaces). Converting from unsafe.Pointer to reflect.Value guarantees that none of the read-only bits will be populated. When running in race mode, we attach type information to the pointer so that we can type check every pointer operation. This also type-checks that direct memory hashing is within the valid range of a struct value. We add test cases that previously caused deephash to panic, but now pass. Performance: name old time/op new time/op delta Hash 14.1µs ± 1% 14.1µs ± 1% ~ (p=0.590 n=10+9) HashPacketFilter 2.53µs ± 2% 2.44µs ± 1% -3.79% (p=0.000 n=9+10) TailcfgNode 1.45µs ± 1% 1.43µs ± 0% -1.36% (p=0.000 n=9+9) HashArray 318ns ± 2% 318ns ± 2% ~ (p=0.541 n=10+10) HashMapAcyclic 32.9µs ± 1% 31.6µs ± 1% -4.16% (p=0.000 n=10+9) There is a slight performance gain due to the use of unsafe.Pointer over reflect.Value methods. Also, passing an unsafe.Pointer (1 word) on the stack is cheaper than passing a reflect.Value (3 words). Performance gains are diminishing since SHA-256 hashing now dominates the runtime. Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2022-08-27util/deephash: add debug printer (#5460)Joe Tsai1-0/+38
When built with "deephash_debug", print the set of HashXXX methods. Example usage: $ go test -run=GetTypeHasher/string_slice -tags=deephash_debug U64(2)+U64(3)+S("foo")+U64(3)+S("bar")+FIN Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2022-08-26util/deephash: rely on direct memory hashing for primitive kinds (#5457)Joe Tsai2-97/+31
Rather than separate functions to hash each kind, just rely on the fact that these are direct memory hashable, thus simplifying the code. Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2022-08-26util/deephash: delete slow path (#5423)Joe Tsai2-229/+49
Every implementation of typeHasherFunc always returns true, which implies that the slow path is no longer executed. Delete it. h.hashValueWithType(v, ti, ...) is deleted as it is equivalent to: ti.hasher()(h, v) h.hashValue(v, ...) is deleted as it is equivalent to: ti := getTypeInfo(v.Type()) ti.hasher()(h, v) Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2022-08-24util/deephash: expand fast-path capabilities (#5404)Joe Tsai1-28/+56
Add support for maps and interfaces to the fast path. Add cycle-detection to the pointer handling logic. This logic is mostly copied from the slow path. A future commit will delete the slow path once the fast path never falls back to the slow path. Performance: name old time/op new time/op delta Hash-24 18.5µs ± 1% 14.9µs ± 2% -19.52% (p=0.000 n=10+10) HashPacketFilter-24 2.54µs ± 1% 2.60µs ± 1% +2.19% (p=0.000 n=10+10) HashMapAcyclic-24 31.6µs ± 1% 30.5µs ± 1% -3.42% (p=0.000 n=9+8) TailcfgNode-24 1.44µs ± 2% 1.43µs ± 1% ~ (p=0.171 n=10+10) HashArray-24 324ns ± 1% 324ns ± 2% ~ (p=0.425 n=9+9) The additional cycle detection logic doesn't incur much slow down since it only activates if a type is recursive, which does not apply for any of the types that we care about. There is a notable performance boost since we switch from the fath path to the slow path less often. Most notably, a struct with a field that could not be handled by the fast path would previously cause the entire struct to go through the slow path. Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2022-08-22control/controlclient,tailcfg: [capver 40] create KeySignature field in ↵Tom DNetto1-1/+1
tailcfg.Node We calve out a space to put the node-key signature (used on tailnets where network lock is enabled). Signed-off-by: Tom DNetto <tom@tailscale.com>
2022-08-18util/deephash: specialize for netip.Addr and drop AppendTo support (#5402)Joe Tsai3-54/+140
There are 5 types that we care about that implement AppendTo: key.DiscoPublic key.NodePublic netip.Prefix netipx.IPRange netip.Addr The key types are thin wrappers around [32]byte and are memory hashable. The netip.Prefix and netipx.IPRange types are thin wrappers over netip.Addr and are hashable by default if netip.Addr is hashable. The netip.Addr type is the only one with a complex structure where the default behavior of deephash does not hash it correctly due to the presence of the intern.Value type. Drop support for AppendTo and instead add specialized hashing for netip.Addr that would be semantically equivalent to == on the netip.Addr values. The AppendTo support was already broken prior to this change. It was fully removed (intentionally or not) in #4870. It was partially restored in #4858 for the fast path, but still broken in the slow path. Just drop support for it altogether. This does mean we lack any ability for types to self-hash themselves. In the future we can add support for types that implement: interface { DeepHash() Sum } Test and fuzz cases were added for the relevant types that used to rely on the AppendTo method. FuzzAddr has been executed on 1 billion samples without issues. Signed-off-by: Joe Tsai joetsai@digital-static.net
2022-08-16util/hashx: move from sha256x (#5388)Joe Tsai1-1/+1
2022-08-16util/sha256x: rename Hash as Block512 (#5351)Joe Tsai2-6/+13
Rename Hash as Block512 to indicate that this is a general-purpose hash.Hash for any algorithm that operates on 512-bit block sizes. While we rename the package as hashx in this commit, a subsequent commit will move the sha256x package to hashx. This is done separately to avoid confusing git. Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2022-08-16util/deephash: move typeIsRecursive and canMemHash to types.go (#5386)Joe Tsai4-188/+206
Also, rename canMemHash to typeIsMemHashable to be consistent. There are zero changes to the semantics. Signed-off-by: Joe Tsai <joetsai@digital-static.net>