server: upstream trains, observed TTL/DSCP/ECN, rate limits, action ids
Types 0x03/0x04/0x05 land with a bounded columnar train buffer (head kept, truncation declared) and grant-free multi-part reports - a report row is smaller than the packet it answers, so $3.4 holds without a grant. The read loop now collects TTL/TOS cmsgs on Linux, replacing the 0xFF stubs in the observation block with what the kernel saw; downtrain gained a dscp parameter, so DSCP survival is measurable in both directions. Rate limiting ($2.5) exists now: per-credential AND per-source buckets, 429 on the control plane, silent drop on the data plane after the HMAC gate and before the replay window. UDP ceilings default above the largest legitimate run - a limit that clips a real measurement produces a confidently wrong number. Every granted packet carries its action_id at payload[8:16]; overlapping actions were unattributable before. Canary DNS logs now honor the stated 24h privacy default. /admin/enroll-tokens answers the spec's JSON shape. protocol_version 1.0.1 (additive). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
f6849f8e6a
commit
8118e213ae
@@ -0,0 +1,55 @@
|
||||
// SPDX-FileCopyrightText: 2026 Echolot contributors
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
//go:build linux
|
||||
|
||||
package dataplane
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// withTOS runs fn with the socket's TOS/traffic class set to dscp<<2 (ECN bits left zero — the
|
||||
// test is about DSCP survival, and claiming ECN capability we do not use would pollute it), then
|
||||
// restores what was there before.
|
||||
//
|
||||
// Same borrow discipline as withDF: the socket is shared by every session on that family, so the
|
||||
// caller must hold Server.dfMu for the whole window or a concurrent burst rides along with — or
|
||||
// clears — someone else's marking.
|
||||
func withTOS(conn *net.UDPConn, dscp int, fn func() error) error {
|
||||
raw, err := conn.SyscallConn()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v4 := conn.LocalAddr().(*net.UDPAddr).IP.To4() != nil
|
||||
level, opt := syscall.IPPROTO_IPV6, syscall.IPV6_TCLASS
|
||||
if v4 {
|
||||
level, opt = syscall.IPPROTO_IP, syscall.IP_TOS
|
||||
}
|
||||
|
||||
var setErr error
|
||||
prev := 0
|
||||
if err := raw.Control(func(fd uintptr) {
|
||||
if p, e := syscall.GetsockoptInt(int(fd), level, opt); e == nil {
|
||||
prev = p
|
||||
}
|
||||
setErr = syscall.SetsockoptInt(int(fd), level, opt, dscp<<2)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if setErr != nil {
|
||||
return setErr
|
||||
}
|
||||
defer func() {
|
||||
_ = raw.Control(func(fd uintptr) {
|
||||
_ = syscall.SetsockoptInt(int(fd), level, opt, prev)
|
||||
})
|
||||
}()
|
||||
return fn()
|
||||
}
|
||||
|
||||
// TOSSupported reports whether withTOS can actually mark packets here. Exported so the control
|
||||
// plane can tell the client up front that its dscp request will not be honored, instead of the
|
||||
// client measuring an unmarked burst and concluding the network stripped the marking.
|
||||
const TOSSupported = true
|
||||
Reference in New Issue
Block a user