One limit on git pack generation across SSH, smart HTTP, git:// and web archives.
internal/packlimit: a global cap, a per-principal cap and a bounded queue with a wait. One limiter is built inserveand shared by every transport.[limits] pack_concurrency(3),pack_per_principal(2),pack_queue(32),pack_queue_wait("60s"); 0 takes the default, a negative value turns that bound off.- Principals:
user:<id>for SSH and for a tokened or signed-in HTTP request; the client address for anonymous HTTP and git://, an IPv6 client by its /64. Anonymous clients together hold at mostpack_concurrency− 1 slots, so an account can take the last one when it is free. - upload-pack, upload-archive and web archives take a slot after every access check; pushes and ls-refs never do. A clone is killed when its client leaves (SSH), its key is revoked, or nothing has been written to the client for two minutes; upload-pack runs with
uploadpack.keepAlive=5. The slot is released only after git has exited. - Busy: SSH prints that the server is at its clone limit and exits 1; HTTP answers 503 with
Retry-After: 30; git:// sends an ERR packet. Refusals are logged at most once a minute per transport, without addresses. - Hook-side refusals are audited: a hook request without a valid push token or from another uid as
refused hook, policy denials in pre-receive asrefused push(#275). deploy/clonebench.sh; Admin, Performance, Threat-Model, Architecture 09/10; CHANGELOG.ssh.mode = "system"has no limiter (Known-Gaps).
Stacked on !505 (builds-badge-org).
Closes #262