server: DF-mode big_send + uploaded-run storage with an operator policy
big_send now forces the Don't-Fragment bit for the whole burst by default, so the largest size that arrives IS the downstream path MTU rather than "fragments got through" — two different measurements the schema already separates. Sizes above our own egress MTU (from the startup self-test) are refused up front and reported as max_df_bytes, because absence caused by our kernel must not be read as a limit of the client's path. Uploads: one JSON file per run under the state dir, with the policy the operator actually cares about — who may upload (off / anonymous / account), how large, how long to keep, and the least anonymization accepted. The profile advertises all of it so the app can present the switch honestly instead of discovering the rules by failing. `account` refuses today rather than falling back to anonymous: picking the strict setting before OIDC lands must not silently mean the loose one. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
7e1015c211
commit
2521d39989
@@ -45,6 +45,10 @@ type Server struct {
|
||||
|
||||
mu sync.Mutex
|
||||
conns []*net.UDPConn
|
||||
|
||||
// dfMu serialises DF windows: the listening socket is shared by every session on that
|
||||
// family, so two concurrent big_sends must not overlap their DF on/off transitions.
|
||||
dfMu sync.Mutex
|
||||
}
|
||||
|
||||
// Serve runs the read loop for one socket; call once per bound address.
|
||||
@@ -203,6 +207,13 @@ func (s *Server) timesyncResp(conn *net.UDPConn, raddr netip.AddrPort, sess *ses
|
||||
}
|
||||
|
||||
func (s *Server) send(conn *net.UDPConn, raddr netip.AddrPort, sess *session.Session, typ byte, seq uint32, payload []byte) {
|
||||
_ = s.sendErr(conn, raddr, sess, typ, seq, payload)
|
||||
}
|
||||
|
||||
// sendErr is send with the write error surfaced. Only the DF-mode big_send cares: there an
|
||||
// EMSGSIZE means our own egress MTU refused the datagram, which is a different fact from the
|
||||
// client not receiving it.
|
||||
func (s *Server) sendErr(conn *net.UDPConn, raddr netip.AddrPort, sess *session.Session, typ byte, seq uint32, payload []byte) error {
|
||||
pkt := make([]byte, HeaderSize+len(payload))
|
||||
copy(pkt[0:4], Magic)
|
||||
pkt[4] = typ
|
||||
@@ -218,7 +229,8 @@ func (s *Server) send(conn *net.UDPConn, raddr netip.AddrPort, sess *session.Ses
|
||||
mac.Write(pkt[0:28])
|
||||
mac.Write(payload)
|
||||
copy(pkt[28:32], mac.Sum(nil)[:4])
|
||||
_, _ = conn.WriteToUDPAddrPort(pkt, raddr)
|
||||
_, err := conn.WriteToUDPAddrPort(pkt, raddr)
|
||||
return err
|
||||
}
|
||||
|
||||
func hexByte(hi, lo byte) byte {
|
||||
|
||||
Reference in New Issue
Block a user