Commit Graph

48 Commits

Author SHA1 Message Date
世界
df6e47f5f1 ocm: preserve websocket rate limit event fields 2026-03-15 18:48:44 +08:00
世界
1993da3735 ocm: rewrite codex.rate_limits WebSocket events for external users
The HTTP path rewrites utilization headers for external users via
rewriteResponseHeadersForExternalUser to show aggregated values.
The WebSocket upgrade headers were also rewritten, but in-band
codex.rate_limits events were forwarded unmodified, leaking
per-credential utilization to external users.
2026-03-15 18:48:43 +08:00
世界
22376472d0 ccm,ocm: fix passive usage update for WebSocket connections
WebSocket 101 upgrade responses do not include utilization headers
(confirmed via codex CLI source). Rate limit data is delivered
exclusively through in-band events (codex.rate_limits and error
events with status 429).

Previously, updateStateFromHeaders unconditionally bumped lastUpdated
even when no utilization headers were found, which suppressed polling
and left credential utilization permanently stale during WebSocket
sessions.

- Only bump lastUpdated when actual utilization data is parsed
- Parse in-band codex.rate_limits events to update credential state
- Detect in-band 429 error events to markRateLimited
- Fix WebSocket 429 retry to update old credential state before retry
2026-03-15 18:48:43 +08:00
世界
74bf20d349 ccm,ocm: fix reverse session shutdown race 2026-03-15 18:48:43 +08:00
世界
ff8585f7c6 ccm,ocm: block utilization decrease within same rate-limit window
updateStateFromHeaders unconditionally applied header utilization
values even when they were lower than the current state, causing
poll-sourced values to be overwritten by stale header values.

Parse reset timestamps before utilization and only allow decreases
when the reset timestamp changes (indicating a new rate-limit
window). Also add math.Ceil to CCM external credential for
consistency with default credential.
2026-03-15 18:48:42 +08:00
世界
4d5108fe7f ccm,ocm: fix connector-side bufio data loss in reverse proxy
connectorConnect() creates a bufio.NewReader to read the HTTP 101
upgrade response, but then passes the raw conn to yamux.Server().
If TCP coalesces the 101 response with initial yamux frames, the
bufio reader over-reads into its buffer and those bytes are lost
to yamux, causing session failure.

Wrap the bufio.Reader and raw conn into a bufferedConn so yamux
reads through the buffer first.
2026-03-15 18:48:42 +08:00
世界
3b177df05e ccm,ocm: fix data race on reverseContext/reverseCancel
InterfaceUpdated() writes reverseContext and reverseCancel without
synchronization while connectorLoop/connectorConnect goroutines
read them concurrently. close() also accesses reverseCancel without
a lock.

Fix by extending reverseAccess mutex to protect these fields:
- Add getReverseContext()/resetReverseContext() methods
- Pass context as parameter to connectorConnect
- Merge close() into a single lock acquisition
- Use resetReverseContext() in InterfaceUpdated()
2026-03-15 18:48:42 +08:00
世界
1824881719 ccm,ocm: reset connector backoff after successful connection
The consecutiveFailures counter in connectorLoop never resets,
causing backoff to permanently cap at 30-45s even after a
connection that served successfully for hours.

Reset the counter when connectorConnect ran for at least one
minute, indicating a successful session rather than a transient
dial/handshake failure.
2026-03-15 18:48:41 +08:00
世界
02a1409e9a ccm,ocm: unify HTTP request retry with fast retry and exponential backoff 2026-03-15 18:48:41 +08:00
世界
af94ea9089 Fix reverse external credential handling 2026-03-15 18:48:41 +08:00
世界
970951f369 ccm,ocm: add reverse proxy support for external credentials
Allow two CCM/OCM instances to share credentials when only one has a
public IP, using yamux-multiplexed reverse connections.

Three credential modes:
- Normal: URL set, reverse=false — standard HTTP proxy
- Receiver: URL empty — waits for incoming reverse connection
- Connector: URL set, reverse=true — dials out to establish connection

Extend InterfaceUpdated to services so network changes trigger
reverse connection reconnection.
2026-03-15 18:48:40 +08:00
世界
15f3619995 ccm,ocm: strip reverse proxy headers before forwarding to upstream 2026-03-15 18:48:40 +08:00
世界
b96ab4fef9 ccm,ocm,ssmapi: fix HTTP/2 over TLS with h2c handler
aTLS.NewListener returns *LazyConn, not *tls.Conn, so Go's
http.Server cannot detect TLS via type assertion and falls back
to HTTP/1.x. When ALPN negotiates h2, the client sends HTTP/2
frames that the server fails to parse, causing HTTP 520 errors
behind Cloudflare.

Wrap HTTP handlers with h2c.NewHandler to intercept the HTTP/2
client preface and dispatch to http2.Server.ServeConn, consistent
with DERP, v2rayhttp, naive, and v2raygrpclite services.
2026-03-15 18:48:40 +08:00
世界
6829f91a06 ccm,ocm: check credential file writability before token refresh
Refuse to refresh tokens when the credential file is not writable,
preventing server-side invalidation of the old refresh token that
would make the credential permanently unusable after restart.
2026-03-15 18:48:40 +08:00
世界
8e5811a8c7 ccm,ocm: watch credential_path and allow delayed credentials 2026-03-15 18:48:40 +08:00
世界
da8ff6f578 ccm/ocm: Add external credential support for cross-instance usage sharing
Extract credential interface from *defaultCredential to support both
default (OAuth) and external (remote proxy) credential types. External
credentials proxy requests to a remote ccm/ocm instance with bearer
token auth, poll a /status endpoint for utilization, and parse
aggregated rate limit headers from responses.

Add allow_external_usage user flag to control whether balancer/fallback
providers may select external credentials. Add status endpoint
(/ccm/v1/status, /ocm/v1/status) returning averaged utilization across
eligible credentials. Rewrite response rate limit headers for external
users with aggregated values.
2026-03-15 18:48:39 +08:00
世界
2801bce815 ccm/ocm: Add multi-credential support with balancer and fallback strategies 2026-03-15 18:48:39 +08:00
世界
49c450d942 ccm/ocm: Fix missing metering for 1M context and /fast mode
CCM: Fix 1M context detection - use prefix match for versioned
beta strings (e.g. "context-1m-2025-08-07") and include cache
tokens in the 200K threshold check per Anthropic billing docs.

OCM: Add GPT-5.4 family pricing (standard/priority/flex) with
extended context (>272K) premium pricing support. Add context
window tracking to usage combinations, mirroring CCM's pattern.
Update normalizeGPT5Model defaults to latest known models.
2026-03-11 20:41:29 +08:00
世界
67621ee6ba Fix OCM websocket proxy lifecycle and headers 2026-03-10 22:04:11 +08:00
世界
a09ffe6a0f ccm/ocm: Add by_user_and_week cost summary 2026-03-10 22:04:11 +08:00
世界
e0be8743f6 ocm: Add Responses WebSocket API proxy and fix client config docs
Support the OpenAI Responses WebSocket API (`wss://.../v1/responses`)
for bidirectional frame proxying with usage tracking.
Fix Codex CLI client config examples to use profiles and correct flags.

Update openai-go v3.24.0 → v3.26.0.
2026-03-10 22:04:11 +08:00
世界
df0bf927e4 Fix missing with_gvisor build tag for tailscale 2026-03-09 20:18:28 +08:00
Oleg Artyomov
1d388547ee service/ccm: strip Accept-Encoding before forwarding to avoid untracked usage
When clients (e.g. Node.js Anthropic SDK) explicitly set Accept-Encoding: gzip,
Go's http.Transport does not transparently decompress the response body, because
it only does so when it added the header itself. This causes CCM's json.Unmarshal
to receive raw gzip bytes, silently failing to parse usage data and leaving the
usage counter unchanged.

Fix: remove Accept-Encoding from the outgoing proxy request. Transport adds it
automatically and transparently decompresses response.Body before CCM reads it.

Wire compression (CCM→Anthropic) is preserved — Transport still negotiates gzip.
Only CCM→localhost path is affected; compression on loopback has no practical
benefit.
2026-03-09 20:06:34 +08:00
世界
65150f5cc3 platform: Improve OOM killer for iOS 2026-02-27 14:58:06 +08:00
世界
cf4791f1ad platform: Improve iOS OOM killer 2026-02-26 14:13:32 +08:00
世界
0bc66e5a56 service/ccm,ocm: Fixes and improvements 2026-02-26 13:36:46 +08:00
世界
aa8dd6e44f Fix DNS transports 2026-01-17 05:48:41 +08:00
世界
511d1bb3fa Update tailscale to v1.92.4 2026-01-17 05:48:28 +08:00
世界
b2d90b7d86 Fix missing RootPoolFromContext and TimeFuncFromContext in HTTP clients 2026-01-17 05:48:16 +08:00
世界
e8620587dd Add OpenAI Codex Multiplexer service 2026-01-17 05:47:42 +08:00
世界
a89680fa2d Update pricing for CCM service 2026-01-17 05:47:42 +08:00
世界
5bc0dfa9dd platform: Refactoring libbox to use gRPC-based protocol 2026-01-17 05:47:32 +08:00
世界
1c4614318e Fix read credentials for ccm service 2026-01-17 05:46:24 +08:00
世界
0f5cda4169 Add claude code multiplexer service 2026-01-17 05:46:23 +08:00
世界
7f3ea8dbd8 Update WireGuard and Tailscale 2026-01-17 05:46:02 +08:00
世界
107f92381b Add support for kTLS
Reference: https://gitlab.com/go-extension/tls
2026-01-17 05:44:42 +08:00
世界
68448de7d0 Fix missing RootPoolFromContext and TimeFuncFromContext in HTTP clients 2025-12-22 13:50:57 +08:00
世界
5841d410a1 ssm-api: Fix save cache 2025-11-04 11:00:43 +08:00
世界
031f25c1c1 Deprecate common/atomic 2025-08-25 19:49:12 +08:00
世界
354ece2bdf Fix resolved service 2025-08-16 00:09:29 +08:00
世界
de10bb00a9 Fix ssm-api 2025-08-15 15:05:37 +08:00
世界
378e39f70c Update golangci-lint to v2 2025-08-13 23:37:40 +08:00
世界
3388efe65a Fix ssm-api 2025-07-28 08:01:52 +08:00
世界
407ee08d8a Add cache support for ssm-api 2025-07-08 13:14:44 +08:00
世界
d339f85087 Fix missing home for derp service 2025-07-08 13:14:43 +08:00
世界
0146fbfc40 Add SSM API service 2025-07-08 13:14:42 +08:00
世界
6ee3117755 Add resolved service and DNS server 2025-07-08 13:14:41 +08:00
世界
e2440a569e Add DERP service 2025-07-08 13:14:41 +08:00