merged with fixes
This commit is contained in:
parent
a9e758b712
commit
2f1818d656
176 changed files with 9000 additions and 907 deletions
|
|
@ -330,27 +330,21 @@ type Options struct {
|
|||
// 阻断连接维持消息。可靠响应无法 tracking 时终止该连接,durable best-effort update
|
||||
// 则只丢在线加速并由 difference 恢复。
|
||||
OutboundTrackedGlobalMaxBytes int64
|
||||
// OutboundCriticalGlobalMaxBytes is an independent retained-body reserve for
|
||||
// bootstrap/convergence RPC results. Bulk traffic cannot consume it.
|
||||
OutboundCriticalGlobalMaxBytes int64
|
||||
// OutboundWriteGlobalMaxBytes bounds concurrent encrypted wire/codec/obfuscation scratch.
|
||||
// Scratch is shared and pooled across connections; default 512 MiB.
|
||||
OutboundWriteGlobalMaxBytes int64
|
||||
|
||||
// DC 是本 server 的 DC ID。默认 2。
|
||||
DC int
|
||||
// StrictDC turns on exact DC-ID validation for the permanent-key exchange
|
||||
// (default off = lenient). telesrv is always a single physical backend —
|
||||
// there is no real multi-DC federation behind it — but the OwpenGram
|
||||
// client forks intentionally run in "single-server backend" mode, where
|
||||
// dc_id 1..5 all alias to this one server (see owpengram_servers.cpp /
|
||||
// ApplyServerToDcOptions in the desktop client) so that any old data
|
||||
// referencing a specific dc_id still resolves correctly. When tdesktop
|
||||
// adds a new local account it picks its own starting dc_id (its usual
|
||||
// multi-DC load-spreading behavior, unrelated to which physical server
|
||||
// it's actually talking to) — that choice is not guaranteed to equal our
|
||||
// configured DC. Strict validation would reject those accounts with
|
||||
// "-444 wrong dc_id" even though they are connecting to the right (and
|
||||
// only) server; dc_id is a client-side routing label here, not part of
|
||||
// key derivation, so accepting the mismatch does not weaken the exchange.
|
||||
// The switch exists for a hypothetical future real multi-DC deployment.
|
||||
// StrictDC enables DC-label validation during key exchange. It is false by
|
||||
// default: this single physical backend accepts every wire int32 label for
|
||||
// permanent and temporary keys, and the label never changes auth-key
|
||||
// persistence, session identity, or business state. When enabled,
|
||||
// permanent labels must equal DC and temporary labels may equal +/-DC.
|
||||
// This diagnostic switch does not itself provide multi-DC isolation.
|
||||
StrictDC bool
|
||||
// RSAKey 是 server RSA 私钥,用于密钥交换。nil 时无法完成握手。
|
||||
RSAKey *rsa.PrivateKey
|
||||
|
|
@ -458,6 +452,9 @@ func (o *Options) setDefaults() {
|
|||
if o.OutboundTrackedGlobalMaxBytes <= 0 {
|
||||
o.OutboundTrackedGlobalMaxBytes = defaultOutboundTrackedMaxBytes
|
||||
}
|
||||
if o.OutboundCriticalGlobalMaxBytes <= 0 {
|
||||
o.OutboundCriticalGlobalMaxBytes = defaultOutboundCriticalMaxBytes
|
||||
}
|
||||
if o.OutboundWriteGlobalMaxBytes <= 0 {
|
||||
o.OutboundWriteGlobalMaxBytes = defaultOutboundWriteMaxBytes
|
||||
}
|
||||
|
|
@ -518,13 +515,17 @@ type Server struct {
|
|||
rpcQueueSize int
|
||||
rpcTimeout time.Duration
|
||||
rpcScheduler *inboundRPCScheduler
|
||||
bulkRPCScheduler *bulkRPCScheduler
|
||||
rpcDeliveryHooks *rpcDeliveryHookExecutor
|
||||
frameBudget *inboundFrameBudget
|
||||
outboundQueueSize int
|
||||
outboundControlQueueSize int
|
||||
outboundTrackedBudget *outboundTrackedBudget
|
||||
outboundControlBudget *outboundTrackedBudget
|
||||
outboundCriticalBudget *outboundTrackedBudget
|
||||
outboundScratchPool *outboundScratchPool
|
||||
outboundOpPool *outboundOpPool
|
||||
outboundReplayBodyPool *outboundReplayBodyPool
|
||||
|
||||
dc int
|
||||
strictDC bool
|
||||
|
|
@ -581,17 +582,20 @@ func New(opts Options) *Server {
|
|||
rpcQueueSize: opts.RPCQueueSize,
|
||||
rpcTimeout: opts.RPCTimeout,
|
||||
rpcScheduler: newInboundRPCScheduler(opts.RPCGlobalWorkers, opts.RPCGlobalMaxTasks, opts.RPCGlobalMaxBytes),
|
||||
bulkRPCScheduler: newBulkRPCScheduler(max(1, opts.RPCGlobalWorkers/2)),
|
||||
rpcDeliveryHooks: newRPCDeliveryHookExecutor(opts.RPCDeliveryHookWorkers, opts.RPCDeliveryHookMaxPending),
|
||||
frameBudget: newInboundFrameBudget(opts.InboundFrameGlobalMaxBytes),
|
||||
outboundQueueSize: opts.OutboundQueueSize,
|
||||
outboundControlQueueSize: opts.OutboundControlQueueSize,
|
||||
outboundTrackedBudget: newOutboundTrackedBudget(opts.OutboundTrackedGlobalMaxBytes),
|
||||
outboundControlBudget: newOutboundTrackedBudget(defaultOutboundControlMaxBytes),
|
||||
outboundCriticalBudget: newOutboundTrackedBudget(opts.OutboundCriticalGlobalMaxBytes),
|
||||
outboundScratchPool: newOutboundScratchPool(opts.OutboundWriteGlobalMaxBytes),
|
||||
outboundOpPool: newOutboundOpPool(defaultOutboundOpPoolSize),
|
||||
outboundReplayBodyPool: newOutboundReplayBodyPool(defaultOutboundReplayBodyClasses),
|
||||
dc: opts.DC,
|
||||
strictDC: opts.StrictDC,
|
||||
key: exchange.PrivateKey{RSA: opts.RSAKey},
|
||||
pubKeyPEM: rsaPublicKeyPEM(opts.RSAKey),
|
||||
authKeys: opts.AuthKeys,
|
||||
conns: conns,
|
||||
rpc: opts.legacyRPC,
|
||||
|
|
@ -612,6 +616,7 @@ func New(opts Options) *Server {
|
|||
}),
|
||||
rpcRewrap: newRPCRewrapRegistry(opts.RPCGlobalMaxTasks),
|
||||
admission: newAdmissionController(opts.MaxConnections, opts.MaxConnectionsPerIP, opts.MaxConcurrentHandshakes),
|
||||
pubKeyPEM: rsaPublicKeyPEM(opts.RSAKey),
|
||||
}
|
||||
if opts.IdentityDir != "" {
|
||||
server.identityStore = identity.NewStore(opts.IdentityDir)
|
||||
|
|
@ -662,26 +667,29 @@ func (s *Server) newConnWithLease(lease *physicalTransportLease, key crypto.Auth
|
|||
|
||||
func (s *Server) buildConn(tc transport.Conn, lease *physicalTransportLease, key crypto.AuthKey, sessionID, salt int64) *Conn {
|
||||
c := &Conn{
|
||||
transport: tc,
|
||||
transportLease: lease,
|
||||
writer: tc,
|
||||
cipher: s.cipher,
|
||||
msgID: proto.NewMessageIDGen(s.clock.Now),
|
||||
writeTimeout: s.writeTimeout,
|
||||
metrics: s.metrics,
|
||||
now: s.clock.Now,
|
||||
authKeyID: key.ID,
|
||||
authKeyHex: hex.EncodeToString(key.ID[:]),
|
||||
sessionID: sessionID,
|
||||
salt: salt,
|
||||
key: key,
|
||||
createdAt: s.clock.Now(),
|
||||
outboundQueueSize: s.outboundQueueSize,
|
||||
outboundControlQueueSize: s.outboundControlQueueSize,
|
||||
outboundTrackedBudget: s.outboundTrackedBudget,
|
||||
outboundControlTrackedBudget: s.outboundControlBudget,
|
||||
outboundScratchPool: s.outboundScratchPool,
|
||||
rpcDeliveryHooks: s.rpcDeliveryHooks,
|
||||
transport: tc,
|
||||
transportLease: lease,
|
||||
writer: tc,
|
||||
cipher: s.cipher,
|
||||
msgID: proto.NewMessageIDGen(s.clock.Now),
|
||||
writeTimeout: s.writeTimeout,
|
||||
metrics: s.metrics,
|
||||
now: s.clock.Now,
|
||||
authKeyID: key.ID,
|
||||
authKeyHex: hex.EncodeToString(key.ID[:]),
|
||||
sessionID: sessionID,
|
||||
salt: salt,
|
||||
key: key,
|
||||
createdAt: s.clock.Now(),
|
||||
outboundQueueSize: s.outboundQueueSize,
|
||||
outboundControlQueueSize: s.outboundControlQueueSize,
|
||||
outboundTrackedBudget: s.outboundTrackedBudget,
|
||||
outboundControlTrackedBudget: s.outboundControlBudget,
|
||||
outboundCriticalTrackedBudget: s.outboundCriticalBudget,
|
||||
outboundScratchPool: s.outboundScratchPool,
|
||||
outboundOpPool: s.outboundOpPool,
|
||||
outboundReplayBodyPool: s.outboundReplayBodyPool,
|
||||
rpcDeliveryHooks: s.rpcDeliveryHooks,
|
||||
rpcResultAcked: func(conn *Conn, reqMsgID int64) {
|
||||
// The sole outbound actor invokes this only after resolving a client
|
||||
// msgs_ack server msg_id through its tracked resend frame. The actor has
|
||||
|
|
@ -708,6 +716,7 @@ func (s *Server) Serve(ctx context.Context, ln net.Listener) error {
|
|||
defer s.rpcDeliveryHooks.stop(rpcCloseWaitTimeout)
|
||||
defer s.conns.releaseAllLogicalSessions()
|
||||
defer s.rpcScheduler.stop(rpcCloseWaitTimeout)
|
||||
defer s.bulkRPCScheduler.close()
|
||||
// 只在最外层 listener 包一次,确保 same-port mux 的 sniff/HTTP upgrade 也计入
|
||||
// raw admission,而不是等连接已经分流后才计数。
|
||||
ln = s.observeRawAccepts(s.admission.wrapListener(ln))
|
||||
|
|
@ -1147,7 +1156,7 @@ func (s *Server) serveConn(ctx context.Context, raw transport.Conn, remote, loca
|
|||
fetchedKey = &d
|
||||
}
|
||||
|
||||
current, err = s.handleEncrypted(ctx, conn, cs, current, fetchedKey, &b, &plain)
|
||||
current, err = s.handleEncrypted(ctx, conn, cs, current, remote, fetchedKey, &b, &plain)
|
||||
if errors.Is(err, errActivationAuthKeyRejected) {
|
||||
// handleEncrypted writes -404 while its activation claim still owns the
|
||||
// physical writer, then its deferred abort removes/closes the claim.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue