999 Commits
Author SHA1 Message Date
xtaci f3f1bbd9b9 refine README 2026-05-15 14:23:25 +08:00
xtaci 78a2a3914a try to sched in 1 CPU system v5.6.72 2026-03-27 14:18:14 +08:00
xtaci 46408de74f fix(timedsched): ensure minimum 2 sched workers to prevent starvation on single-CPU machines 2026-03-27 14:08:49 +08:00
xtaci eeda96e338 remove conditional memory test for Parallel 2026-03-27 13:59:04 +08:00
xtaci 10a95b7d51 optimize mtu test 2026-03-26 20:55:45 +08:00
selfishblackberry177 8a84a05b1a Lower SetMtu minimum from 50 to IKCP_OVERHEAD+1 (25) (#337)
* Lower SetMtu minimum from 50 to IKCP_OVERHEAD+1 (25)

The hardcoded minimum of 50 bytes is an arbitrary safety margin.
The real minimum is IKCP_OVERHEAD (24 bytes for the KCP header)
plus at least 1 byte of payload data. This allows use of smaller
MTUs in transport scenarios where capacity is constrained.

* Address review: use mtu <= IKCP_OVERHEAD and update boundary tests

- Changed condition from mtu < IKCP_OVERHEAD+1 to mtu <= IKCP_OVERHEAD
  for readability.
- Updated TestSetMTU to verify the new boundary: MTU at or below
  IKCP_OVERHEAD is rejected, MTU just above total overhead is accepted.
2026-03-26 20:25:55 +08:00
Nhan (Nolan) Huynh 9781b44b33 perf: reuse timers in Read/WriteBuffers to reduce allocations (#335)
* perf: reuse timers in Read/WriteBuffers to reduce allocations

* fix: drain timer channel for pre-Go 1.23 compat and handle cleared deadlines
2026-03-22 18:04:15 +08:00
xtaci 812faf1a49 shrink the buffer in echo 2026-03-21 22:00:23 +08:00
xtaci 497beafe1d adjust to 8GB 2026-03-20 11:24:07 +08:00
xtaci 0a07e8eb67 skip the parallel test if total memory is less than 1GB 2026-03-19 19:55:13 +08:00
xtaci fd709b14a3 docs: fix typos and improve comments across secondary files
- pkg.go: fix grammar in package doc (intents→intends, aims→aim,
  golang→Go)
- snmp.go: fix typos (iput→input); clarify FECShardSet and
  FECShardMin field descriptions
- kcp_trace_off.go: fix typo (ingore→no-op)
- readloop_linux.go: improve readLoop doc comment; document batchSize
  constant
- tx_linux.go: improve tx() doc comment
- entropy.go: document reseedInterval constant

No code logic changes. Comments and documentation only.
v5.6.71
2026-03-13 17:09:45 +08:00
xtaci fec60d1ec6 docs: improve code readability with structured comments and section headers
- kcp.go: Group protocol constants by category (RTO, commands, probe flags,
  window/MTU defaults, protocol parameters) with descriptive comments.
  Document KCP struct fields with protocol semantics (RFC 6298/5681/6937).
  Add 6-phase description to flush() and annotate each phase.

- sess.go: Add section separators for session, packet input pipeline, listener,
  and public API. Document postProcess() 3-stage pipeline and kcpInput()
  packet demultiplexing logic.

- fec.go: Document FEC constants (header sizes, packet types, maxShardSets).
  Clarify fecDecoder's auto-tuning mechanism.

- crypt.go: Add section header for CFB-mode encryption. Document encrypt/decrypt
  dispatch and 8x loop unrolling optimization strategy.

- timedsched.go: Document two-stage pipeline architecture (prepend → sched)
  and explain why stages are separated.

- autotune.go: Expand FindPeriod() documentation with algorithm description
  and fix ASCII signal diagram alignment.

- ringbuffer.go: Document RINGBUFFER_MIN and RINGBUFFER_EXP constants.

- snmp.go: Fix typos (accmulated → accumulated, retransmited → retransmitted).

No code logic changes. All modifications are comments only.
2026-03-13 17:01:51 +08:00
xtaci 3f7d4c8b32 go fix ./... 2026-02-19 11:42:55 +08:00
xtaci 1b253ed16b set window to 1024 to align 2026-02-12 22:25:20 +08:00
xtaci ff25b1c9e0 remove unused code 2026-02-10 22:10:00 +08:00
xtaci 6d3de74039 fix(ringbuffer): fix off-by-one in Discard() causing index out of range panic
RingBuffer.Discard() used `end <= cap` to decide whether the discard
range is contiguous. When head + n equals exactly len(elements), this
incorrectly set head to len(elements) instead of wrapping it to 0.

A subsequent Peek() or Push() would then access elements[len(elements)],
triggering a runtime panic: "index out of range [64] with length 64".

The crash path in production:
  KCP.Input -> parse_una -> snd_buf.Discard(count) -> shrink_buf ->
  snd_buf.Peek() -> panic

Fix: change the boundary condition from `end <= cap` to `end < cap`,
so the exact-boundary case falls through to the wrap-around branch
which correctly computes head = end - cap = 0.

Add TestRingBufferDiscardBoundary to cover this edge case.
v5.6.70
2026-02-10 14:29:29 +08:00
xtaci 68987c794b chore: remove dead field and optimize RingBuffer.Discard
- Remove unused Listener.chSessionClosed field and its allocation;
  the channel was never read from or written to anywhere in the codebase.

- Optimize RingBuffer.Discard: replace per-element modulo loop with
  at most 2 clear() calls on contiguous ranges, eliminating N modulo
  operations for bulk discard.
v5.6.69
2026-02-10 14:20:44 +08:00
xtaci eecde5f5a5 refactor: use switch statement and struct literal in Input()
- Replace if-else if chain with switch statement for cmd dispatch
  in Input(), enabling potential jump table optimization by the compiler.

- Use struct literal to construct segment in IKCP_CMD_PUSH case,
  replacing 8 individual field assignments with a single expression.

- Move segmentHeader type definition from kcp.go to kcp_encoding.go,
  co-locating it with the encode/decode functions that use it.
2026-02-10 14:10:53 +08:00
xtaci d3eb83dd1e refactor: replace custom _imin_/_imax_/_ibound_ with built-in min/max
Remove the custom uint32 helper functions _imin_, _imax_, and _ibound_
in favor of Go's built-in min() and max() generics (available since
Go 1.21). The codebase already uses built-in min/max elsewhere.

- _imin_(a, b)          -> min(a, b)
- _imax_(a, b)          -> max(a, b)
- _ibound_(lo, mid, hi) -> min(max(lo, mid), hi)
2026-02-10 14:07:05 +08:00
xtaci e74c372f10 perf: inline segment header encode/decode with direct binary.LittleEndian calls
Benchmarks show that Go's encoding/binary PutUintXX/UintXX functions
(which compile down to bare MOV instructions on amd64/arm64) are 3-6%
faster than the encodeSegHeader/decodeSegHeader wrapper functions,
especially in multi-segment scenarios.

Replace the wrapper calls in segment.encode() and KCP.Input() with
direct binary.LittleEndian.PutUint32/PutUint16/Uint32/Uint16 calls,
using a single BCE (Bounds Check Elimination) hint per call site.

This eliminates the intermediate segmentHeader struct allocation in
encode and the pointer-receiver copy overhead in decode, letting the
compiler fully inline all field reads/writes.

Add bench_encode_test.go with BenchmarkSegmentEncode and
BenchmarkKCPInput for focused encode/decode benchmarking.
2026-02-10 14:03:35 +08:00
xtaci d44c1c7f15 perf: optimize segment header encode/decode with BCE hints
Introduce segmentHeader struct and dedicated encodeSegHeader/decodeSegHeader
functions to replace scattered inline binary.LittleEndian calls and remove
unused ikcp_encode/decode helper functions.

Key optimizations:
- BCE (Bounds Check Elimination) hint: a single `_ = data[IKCP_OVERHEAD-1]`
  eliminates all subsequent per-field bounds checks
- decodeSegHeader takes *segmentHeader pointer, writing fields directly to
  caller's struct and avoiding 24-byte struct copy overhead
- encodeSegHeader takes segmentHeader by value, allowing the compiler to
  keep fields in registers
- Compile-time size assertion via array type trick

Benchmark (8 runs, AMD Ryzen 9 5950X, Go 1.24, linux/amd64):

  Decode (single header):   2.257ns → 1.279ns  -43.3%  (p=0.000)
  EncodeLoop/1seg:          3.169ns → 2.544ns  -19.7%  (p=0.000)
  EncodeLoop/4segs:         11.42ns → 11.01ns   -3.6%  (p=0.000)
  EncodeLoop/16segs:        44.74ns → 43.84ns   -2.0%  (p=0.002)
  DecodeLoop/16segs:        40.03ns → 39.24ns   -2.0%  (p=0.038)
  DecodeLoop/64segs:        178.0ns → 175.5ns   -1.4%  (p=0.003)
  geomean:                  -3.03%
  0 allocs/op across all benchmarks.

Other changes:
- Remove 6 dead ikcp_encode8u/16u/32u and ikcp_decode8u/16u/32u functions
- Remove encoding/binary import from kcp.go
- Add round-trip and wire-format correctness tests
v5.6.68
2026-02-09 20:32:03 +08:00
xtaci c8a3a26370 perf: inline segment encode/decode to eliminate function call overhead
Replace chained ikcp_encode*/ikcp_decode* function calls with direct
binary.LittleEndian operations at fixed offsets in segment.encode()
and KCP.Input().

The original implementation used 6-7 sequential function calls that
each returned intermediate slices, adding unnecessary call overhead
and preventing compiler optimizations on the hot path.

Benchmark results (Apple M4 Pro, 6 samples, p=0.002):

  SegmentEncode:  3.192ns -> 2.895ns  (-9.32%)
  KCPInput:      12.11ns  -> 10.92ns  (-9.79%)

Zero change in allocations. All existing tests pass including race
detector.
v5.6.67
2026-02-09 16:26:03 +08:00
xtaci 56b1fffecd fix: add defensive checks to prevent panics and memory leaks
This commit addresses several potential issues found through code review:

kcp.go:
- Fix potential memory leak in segmentHeap.Pop() by clearing the last
  element reference before slice truncation, allowing GC to collect it

crypt.go:
- Add bounds check in salsa20BlockCrypt.Encrypt/Decrypt to prevent
  panic when input slice is shorter than 8 bytes (nonce size)
- Add empty slice check in simpleXORBlockCrypt.Encrypt/Decrypt to
  prevent index out of range panic
- Add empty slice check in noneBlockCrypt.Encrypt/Decrypt to prevent
  index out of range panic on dst[0] access

sess.go:
- Remove panic in postProcess rate limiter error handling; WaitN only
  returns errors for context cancellation or invalid burst size, both
  of which are non-critical in this context
2026-01-31 15:35:42 +08:00
xtaci 4ea3913eb4 Merge branch 'dev' v5.6.66 2026-01-29 12:27:34 +08:00
xtaci 2693fa8e71 perf: reduce heap allocations and fix memory leaks across multiple components
Optimizations:
- ringbuffer: optimize Len(), IsEmpty(), Discard(), Clear() methods with
  branchless arithmetic and simplified logic
- fec: fix memory leak in shardHeap.Pop() by setting element to nil before
  truncating slice, preventing GC from holding stale references
- timedsched: fix memory leak in timedFuncHeap.Pop() with same nil-before-truncate
  pattern; optimize prepend() using slice swap instead of append
- autotune: add sortCache field to Autotuner to reuse slice allocation in
  FindPeriod(), avoiding repeated allocations during period detection
- snmp: replace fmt.Sprint with strconv.FormatUint for better performance
  in Copy() and Reset() methods
- entropy: remove defer overhead in rngAES.Read() and rngChacha8.Read()
  hot paths for reduced function call cost
- bufferpool: pre-allocate ErrBufferPoolSizeExceeded error; reset slice
  length on Put() to allow proper reuse
- sess: remove defer overhead in 6 setter methods (SetWriteDelay,
  SetWindowSize, SetStreamMode, SetACKNoDelay, SetDUP, SetNoDelay)

These changes reduce memory allocations, fix potential memory leaks in
heap-based data structures, and eliminate defer overhead in frequently
called methods.
2026-01-29 12:22:33 +08:00
xtaci 5ed6c0ef1c Merge branch 'dev' v5.6.65 2026-01-28 14:22:34 +08:00
xtaci 41b30e042b keep kcp.buffer compatible with C version 2026-01-28 12:20:44 +08:00
hanselime cbd9d1a5d0 readme: add paqet to users list (#330) 2026-01-28 10:58:00 +08:00
xtaci 8fd6d90d50 perf(test): reduce 1GB echo allocations and random overhead
- Reuse buffers and use rng.Read to cut per-iteration allocations in random echo test
- Separate RNG for payload length to keep data stream deterministic
- Optimize UDP source validation by comparing UDPAddr directly to avoid per-packet String allocation
v5.6.64
2026-01-26 11:23:51 +08:00
xtaci b27887e8ce fix(fec): prevent permanent blocking in auto-tune when parameters unchanged
Fix shouldTune flag not being reset when auto-detected FEC parameters
match current parameters. This could cause the decoder to permanently
discard all incoming packets if a corrupted packet triggered shouldTune
but the actual FEC configuration hadn't changed.

Move `dec.shouldTune = false` outside the parameter-change check to
ensure the flag is always reset when valid parameters are detected.
2026-01-26 11:02:30 +08:00
xtaci ca00425149 add more tests to aututune 2026-01-26 10:54:37 +08:00
xtaci 9d77619765 perf(autotune): replace heap with fixed-size ring buffer to reduce allocations
Replace the heap-based pulseHeap implementation with a fixed-size ring
buffer array to avoid interface{} allocations from container/heap
Push/Pop operations.

Changes:
- Use fixed-size array [maxAutoTuneSamples]pulse instead of slice
- Track elements with head/tail/count instead of heap operations
- Copy elements from ring buffer in FindPeriod() for sorting
- Remove container/heap import dependency

Benchmark results (BenchmarkEchoSpeed4K):
- Before: 185 allocs/op
- After:  163 allocs/op (~12% reduction)

All existing tests pass with identical behavior.
v5.6.63
2026-01-25 23:35:07 +08:00
xtaci cbe05256b0 Merge branch 'master' into dev 2026-01-25 22:13:18 +08:00
xtaci ad2550932b crypt: optimize encryption routines with bitwise operations and lock improvements
- Replace division and modulo operations with bitwise equivalents:
  - len(src) / 8  -> len(src) >> 3
  - len(src) / 16 -> len(src) >> 4
  - n / 8  -> n >> 3
  - n % 8  -> n & 7

- Improve lock handling in blockCrypt:
  - Split single mutex into separate encMu/decMu for encrypt/decrypt
  - Remove defer for Lock/Unlock to reduce overhead
  - Cache blockSize in struct to avoid repeated method calls

- Optimize Salsa20 and None ciphers:
  - Skip unnecessary copy when dst and src point to same memory
  - Add //go:nosplit directive to hot path functions

All encryption tests pass. Benchmark results show no regression with
zero memory allocations maintained (0 B/op, 0 allocs/op).
2026-01-25 22:10:17 +08:00
xtaci 8cdb131af5 Squashed commit of the following:
commit e51740f7e6
Author: xtaci <imap@live.com>
Date:   Sat Jan 24 22:11:58 2026 +0800

    optimize crypto using subtle/XORBytes

commit 071dc4a69d
Author: xtaci <imap@live.com>
Date:   Sat Jan 24 21:55:49 2026 +0800

    1. Fix incorrect RepeatSegs counter in parse_data() function
       - Previously, the repeat flag was never set to true when duplicate packets
         were detected, causing incorrect statistics reporting
       - Added missing else branch to properly mark duplicate segments
       - Impact: Correct tracking of repeated packet statistics

    2. Fix memory leak in FEC decoder auto-tune functionality
       - When FEC parameters were adjusted dynamically, the old shardSet map
         was discarded without recycling its buffer pool entries
       - Added proper cleanup loop to return old shard packets to buffer pool
         before creating new shardSet
       - Impact: Prevents memory growth during long-lived connections with
         dynamic FEC parameter adjustments

    Files modified:
    - kcp.go: Added else branch in parse_data() to set repeat=true for duplicates
    - fec.go: Added buffer cleanup loop before shardSet recreation in decode()

    All existing tests pass, including FEC encoding/decoding and lossy connection tests.
v5.6.62
2026-01-24 22:13:21 +08:00
xtaci e51740f7e6 optimize crypto using subtle/XORBytes 2026-01-24 22:11:58 +08:00
xtaci 071dc4a69d 1. Fix incorrect RepeatSegs counter in parse_data() function
- Previously, the repeat flag was never set to true when duplicate packets
     were detected, causing incorrect statistics reporting
   - Added missing else branch to properly mark duplicate segments
   - Impact: Correct tracking of repeated packet statistics

2. Fix memory leak in FEC decoder auto-tune functionality
   - When FEC parameters were adjusted dynamically, the old shardSet map
     was discarded without recycling its buffer pool entries
   - Added proper cleanup loop to return old shard packets to buffer pool
     before creating new shardSet
   - Impact: Prevents memory growth during long-lived connections with
     dynamic FEC parameter adjustments

Files modified:
- kcp.go: Added else branch in parse_data() to set repeat=true for duplicates
- fec.go: Added buffer cleanup loop before shardSet recreation in decode()

All existing tests pass, including FEC encoding/decoding and lossy connection tests.
2026-01-24 21:55:49 +08:00
xtaci b38e76e5b0 add a test for variable length input in fec_test.go 2026-01-01 18:23:07 +08:00
xtaci d3d1f00432 update README for gists v5.6.61 2025-12-30 12:18:56 +08:00
xtaci 55536867fe refine toc 2025-12-29 11:48:59 +08:00
xtaci b893d5527e fix tests 2025-12-28 21:17:15 +08:00
xtaci 83866a3c41 Add files via upload 2025-12-28 18:29:39 +08:00
xtaci 73dc4141c1 update link 2025-12-28 12:12:38 +08:00
xtaci 2b4be79032 update link 2025-12-28 12:10:27 +08:00
xtaci e1d91f7e8d add TOC to README 2025-12-28 11:23:23 +08:00
xtaci 53c14d4570 refactor: unify and simplify OOB handler interface for UDPSession
- Replace atomic.Pointer[func([]byte)] with atomic.Value for OOB callback storage to improve compatibility.
- Rename SetCallbackForOOB to SetOOBHandler and GetMaxSizeForOOB to GetOOBMaxSize for clearer, consistent API naming.
- Add locking in SendOOB to ensure thread safety during OOB packet construction.
- Update related test cases in sess_test.go to use the new interface names.
- Revise comments and documentation for better clarity and maintainability.

user takes care of the nil handler

use 0xffffffff as the seqid of OOB

return error on nil handler

fix race in test

shorten test data size

add more test on OOB

enhance Error test

allow nil from sender side

add OOBPackets in snmp

use dummy handler instead of resetting the atomic.Value

add test for dummy handler

remove a comment

formalize callback function prototype

use const

rename to expose

Add comments to clarify KCP input and FEC decoding order for FEC packets.

fix test

comments

add TestOOB_OneSideHandler
v5.6.60
2025-12-27 23:25:03 +08:00
xtaci e51e7ce2bd Merge branch 'lonnywong-dev' into dev 2025-12-27 14:14:18 +08:00
Lonny Wong eb7d8ee32f Add out-of-band (OOB) data support 2025-12-27 10:12:56 +08:00
xtaci bca9b95082 refine struct to support oob 2025-12-24 20:40:47 +08:00
xtaci 6e5555659b Add files via upload 2025-12-22 15:49:25 +08:00