{"record":{"id":"08da0367e7d39355","repo":"XTLS/Xray-core","slug":"lru-size-is-bigger-than-subnet-size","errorCode":null,"errorMessage":"LRU size is bigger than subnet size","messagePattern":"LRU size is bigger than subnet size","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/dns/fakedns/fake.go","lineNumber":89,"sourceCode":"\treturn &Holder{config: conf}, nil\n}\n\nfunc (fkdns *Holder) initializeFromConfig() error {\n\treturn fkdns.initialize(fkdns.config.IpPool, int(fkdns.config.LruSize))\n}\n\nfunc (fkdns *Holder) initialize(ipPoolCidr string, lruSize int) error {\n\tvar ipRange *net.IPNet\n\tvar err error\n\n\tif _, ipRange, err = net.ParseCIDR(ipPoolCidr); err != nil {\n\t\treturn errors.New(\"Unable to parse CIDR for Fake DNS IP assignment\").Base(err).AtError()\n\t}\n\n\tones, bits := ipRange.Mask.Size()\n\trooms := bits - ones\n\tif math.Log2(float64(lruSize)) >= float64(rooms) {\n\t\treturn errors.New(\"LRU size is bigger than subnet size\").AtError()\n\t}\n\tfkdns.domainToIP = cache.NewLru(lruSize)\n\tfkdns.ipRange = ipRange\n\treturn nil\n}\n\n// GetFakeIPForDomain checks and generates a fake IP for a domain name\nfunc (fkdns *Holder) GetFakeIPForDomain(domain string) []net.Address {\n\tfkdns.mu.Lock()\n\tdefer fkdns.mu.Unlock()\n\tif v, ok := fkdns.domainToIP.Get(domain); ok {\n\t\treturn []net.Address{v.(net.Address)}\n\t}\n\tcurrentTimeMillis := uint64(time.Now().UnixMilli())\n\tones, bits := fkdns.ipRange.Mask.Size()\n\trooms := bits - ones\n\tif rooms < 64 {\n\t\tcurrentTimeMillis %= (uint64(1) << rooms)","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/app/dns/fakedns/fake.go#L71-L107","documentation":"writeFull(w, buffer[:chunkLength]) failed while emitting chunk i of a padding turn. This is the pass-through of an underlying transport write error: closed/reset connection, TLS write failure, buffer-overrun timeouts, or a writer whose context was cancelled. The padding layer adds no error of its own here beyond identifying the chunk index.","triggerScenarios":"Peer disconnects or RSTs mid-handshake while padding turns are being written; write deadline exceeded on the underlying conn; writer wrapped by a component that returns an error (e.g. closed pipe in tests).","commonSituations":"Client aborts during the padded handshake; proxy/LB idle timeout shorter than the sum of configured padding delays; mobile network切换; test harnesses closing the write side early.","solutions":["Inspect the wrapped error (errors.Unwrap / errors.Is io.ErrClosedPipe, os.ErrDeadlineExceeded) to classify the transport failure","Close and re-establish the connection; padding turns are not resumable","If deadlines hit, align conn write timeouts with the maximum total padding delay the schedule can inject"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := runPaddingSchedule(reader, writer, isClient, prefix, schedule); err != nil {\n    var chunkErr error\n    if errors.As(err, &chunkErr) && strings.Contains(err.Error(), \"write padding chunk\") {\n        // transport-level failure: close conn, count the failure, reconnect with backoff\n        conn.Close()\n        return retryWithBackoff()\n    }\n    return err\n}","preventionTips":["Set write deadlines larger than the schedule's maximum injected delay","Detect peer closure early (context cancellation) instead of relying on write failure","Do not retry a partially written turn on the same connection"],"tags":["padding","network","io","write","xmc"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}