kcp

package module
v5.6.61 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 30, 2025 License: MIT Imports: 36 Imported by: 267

README

kcp-go

GoDoc Powered MIT licensed Build Status Go Report Card Coverage Status Sourcegraph

English | 中文

Table of Contents

Introduction

kcp-go is a Reliable-UDP library for golang.

This library provides smooth, resilient, ordered, error-checked, and anonymous stream delivery over UDP packets. Battle-tested with the open-source project kcptun, millions of devices—from low-end MIPS routers to high-end servers—have deployed kcp-go-powered programs across various applications, including online games, live broadcasting, file synchronization, and network acceleration.

Latest Release

Features

  1. Designed for latency-sensitive scenarios.
  2. Cache-friendly and memory-optimized design, offering an extremely high-performance core.
  3. Handles >5K concurrent connections on a single commodity server.
  4. Compatible with net.Conn and net.Listener, serving as a drop-in replacement for net.TCPConn.
  5. FEC (Forward Error Correction) support using Reed-Solomon Codes.
  6. Packet-level encryption support for AES, TEA, 3DES, Blowfish, Cast5, Salsa20, etc., in CFB mode, generating completely anonymous packets.
  7. AEAD packet encryption support.
  8. Only a fixed number of goroutines are created for the entire server application, with context switching costs between goroutines taken into consideration.
  9. Compatible with skywind3000's C version, with various improvements.
  10. Platform-specific optimizations: sendmmsg and recvmmsg for Linux.

Documentation

For complete documentation, see the associated Godoc.

Layer-Model of KCP-GO

layer-model

Key Design Considerations

1. Slice vs. Container/List

kcp.flush() loops through the send queue for retransmission checking every 20 ms.

I wrote a benchmark comparing sequential loops through a slice and a container/list here:

BenchmarkLoopSlice-4   	2000000000	         0.39 ns/op
BenchmarkLoopList-4    	100000000	        54.6 ns/op

The list structure introduces heavy cache misses compared to the slice, which offers better locality. For 5,000 connections with a 32-window size and a 20 ms interval, using a slice costs 6 μs (0.03% CPU) per kcp.flush(), whereas using a list costs 8.7 ms (43.5% CPU).

2. Timing Accuracy vs. Syscall clock_gettime

Timing is critical for the RTT estimator. Inaccurate timing leads to false retransmissions in KCP, but calling time.Now() costs 42 cycles (10.5 ns on a 4 GHz CPU, 15.6 ns on my MacBook Pro 2.7 GHz).

The benchmark for time.Now() is here:

BenchmarkNow-4         	100000000	        15.6 ns/op

In kcp-go, after each kcp.output() function call, the current clock time is updated upon return. For a single kcp.flush() operation, the current time is queried from the system once. For 5,000 connections, this costs 5000 × 15.6 ns = 78 μs (a fixed cost when no packets need to be sent). For 10 MB/s data transfer with a 1400 MTU, kcp.output() is called approximately 7,500 times, costing 117 μs for time.Now() per second.

3. Memory Management

Primary memory allocation is performed from a global buffer pool, xmit.Buf. In kcp-go, when bytes need to be allocated, they are obtained from this pool, which returns a fixed-capacity 1500 bytes (mtuLimit). The rx queue, tx queue, and FEC queue all receive bytes from this pool and return them after use to prevent unnecessary zeroing of bytes. The pool mechanism maintains a high watermark for slice objects, allowing these in-flight objects to survive periodic garbage collection while also being able to return memory to the runtime when idle.

4. Information Security

kcp-go ships with built-in packet encryption powered by various block encryption algorithms and operates in Cipher Feedback Mode. For each packet to be sent, the encryption process begins by encrypting a nonce from the system entropy, ensuring that encryption of the same plaintext never produces the same ciphertext.

The contents of packets are completely anonymous with encryption, including the headers (FEC, KCP), checksums, and payload. Note that regardless of which encryption method you choose at the upper layer, if you disable encryption, the transmission will be insecure because the header is plaintext and susceptible to tampering, such as jamming the sliding window size, round-trip time, FEC properties, and checksums. AES-128 is recommended for minimal encryption, as modern CPUs feature AES-NI instructions and perform better than salsa20 (see the table above).

Other possible attacks on kcp-go include:

  • Traffic analysis: Data flow on specific websites may exhibit patterns during data exchange. This type of eavesdropping has been mitigated by adopting smux to mix data streams and introduce noise. While a perfect solution has not yet emerged, theoretically, shuffling/mixing messages on a larger-scale network may mitigate this problem.
  • Replay attack: Since asymmetric encryption has not been introduced into kcp-go, capturing packets and replaying them on a different machine is possible. Note that hijacking the session and decrypting the contents is still impossible. Upper layers should use an asymmetric encryption system to guarantee the authenticity of each message (to process each message exactly once), such as HTTPS/OpenSSL/LibreSSL. Signing requests with private keys can eliminate this type of attack.

5. Packet Clocking

  1. Immediate FastACK: Send immediately after fastack is triggered, without waiting for the fixed interval.
  2. Immediate ACK: Send immediately after accumulating ACKs that fill a full MTU packet, also without waiting for the interval. In high-speed networks, this acts as a higher-frequency "clock signal," potentially boosting unidirectional transmission speed by approximately 6x. For instance, if a batch takes only 1.5ms to process on a high-speed link but still adheres to a fixed 10ms transmission cycle, the actual throughput would be limited to 1/6 of the potential.
  3. Pacing Mechanism: Introduced a pacing clock to prevent burst congestion where data piles up in the kernel when snd_wnd is large, causing the kernel to drop packets. While difficult to implement in user space, a usable version has been achieved, allowing user-space echo to stabilize above 100MB/s.
  4. Data Structure Optimization: Optimized data structures (e.g., snd_buf ringbuffer) to ensure good cache coherency. Queues must not be too long; otherwise, traversal costs introduce extra latency. In high-speed networks, the buffer corresponding to BDP should be kept smaller to minimize latency from data structures. Note that the current KCP structure has O(n) complexity for RTO; changing it to O(1) would require significant refactoring.

Ultimately, nothing is more critical in a transmission system than the clock (real-time performance).

6. FEC Design Characteristics

  • Reed-Solomon based encoder/decoder lives in the postProcess/packetInput path, so parity shards are generated and consumed without extra goroutines or lock contention.
  • Data/parity ratios are configurable per session, letting operators trade ~20–30% bandwidth overhead for lower tail latency on lossy or long-haul links.
  • Parity shards are produced from buffer-pool-backed slices, which avoids repeated allocations and keeps GC pressure flat even during multi-Gbps transfers.
  • Decoding favors single-pass recovery: as soon as enough shards arrive, the original packets are reconstructed and pushed into KCP.Input, minimizing reordering and retransmission storms.
  • When combined with encryption, FEC headers stay protected, preventing traffic shapers from inferring recovery patterns or downgrading throughput.

Specification

Frame Format
NONCE:
  16bytes cryptographically secure random number, nonce changes for every packet.
  
CRC32:
  CRC-32 checksum of data using the IEEE polynomial
 
FEC TYPE:
  typeData = 0xF1
  typeParity = 0xF2
  
FEC SEQID:
  monotonically increasing in range: [0, (0xffffffff/shardSize) * shardSize - 1]
  
SIZE:
  The size of KCP frame plus 2

KCP Header
+------------------------------+
|           conv (u32)         |
+-------+-------+--------------+
|  cmd  |  frag |     wnd      |
|  u8   |  u8   |     u16      |
+------------------------------+
|           ts   (u32)         |
+------------------------------+
|           sn   (u32)         |
+------------------------------+
|           una  (u32)         |
+------------------------------+
|           data (bytes)       |
+------------------------------+

Performance

2025/11/26 11:12:51 beginning tests, encryption:salsa20, fec:10/3
goos: linux
goarch: amd64
pkg: github.com/xtaci/kcp-go/v5
cpu: AMD Ryzen 9 5950X 16-Core Processor
BenchmarkSM4
BenchmarkSM4-32                            56077             21672 ns/op         138.43 MB/s           0 B/op          0 allocs/op
BenchmarkAES128
BenchmarkAES128-32                        525854              2228 ns/op        1346.69 MB/s           0 B/op          0 allocs/op
BenchmarkAES192
BenchmarkAES192-32                        473692              2429 ns/op        1234.95 MB/s           0 B/op          0 allocs/op
BenchmarkAES256
BenchmarkAES256-32                        427497              2725 ns/op        1101.06 MB/s           0 B/op          0 allocs/op
BenchmarkTEA
BenchmarkTEA-32                           149976              8085 ns/op         371.06 MB/s           0 B/op          0 allocs/op
BenchmarkXOR
BenchmarkXOR-32                         12333190                92.35 ns/op     32485.16 MB/s          0 B/op          0 allocs/op
BenchmarkBlowfish
BenchmarkBlowfish-32                       70762             16983 ns/op         176.65 MB/s           0 B/op          0 allocs/op
BenchmarkNone
BenchmarkNone-32                        47325206                24.49 ns/op     122482.39 MB/s         0 B/op          0 allocs/op
BenchmarkCast5
BenchmarkCast5-32                          66837             18035 ns/op         166.35 MB/s           0 B/op          0 allocs/op
Benchmark3DES
Benchmark3DES-32                           18402             64349 ns/op          46.62 MB/s           0 B/op          0 allocs/op
BenchmarkTwofish
BenchmarkTwofish-32                        56440             21380 ns/op         140.32 MB/s           0 B/op          0 allocs/op
BenchmarkXTEA
BenchmarkXTEA-32                           45616             26124 ns/op         114.84 MB/s           0 B/op          0 allocs/op
BenchmarkSalsa20
BenchmarkSalsa20-32                       525685              2199 ns/op        1363.97 MB/s           0 B/op          0 allocs/op
BenchmarkCRC32
BenchmarkCRC32-32                       19418395                59.05 ns/op     17341.83 MB/s
BenchmarkCsprngSystem
BenchmarkCsprngSystem-32                 2912889               404.3 ns/op        39.58 MB/s
BenchmarkCsprngMD5
BenchmarkCsprngMD5-32                   15063580                79.23 ns/op      201.95 MB/s
BenchmarkCsprngSHA1
BenchmarkCsprngSHA1-32                  20186407                60.04 ns/op      333.08 MB/s
BenchmarkCsprngNonceMD5
BenchmarkCsprngNonceMD5-32              13863704                85.11 ns/op      187.98 MB/s
BenchmarkCsprngNonceAES128
BenchmarkCsprngNonceAES128-32           97239751                12.56 ns/op     1274.09 MB/s
BenchmarkFECDecode
BenchmarkFECDecode-32                    1808791               679.1 ns/op      2208.94 MB/s        1641 B/op          3 allocs/op
BenchmarkFECEncode
BenchmarkFECEncode-32                    6671982               181.4 ns/op      8270.76 MB/s           2 B/op          0 allocs/op
BenchmarkFlush
BenchmarkFlush-32                         322982              3809 ns/op               0 B/op          0 allocs/op
BenchmarkDebugLog
BenchmarkDebugLog-32                    1000000000               0.2146 ns/op
BenchmarkEchoSpeed4K
BenchmarkEchoSpeed4K-32                    35583             32875 ns/op         124.59 MB/s       18223 B/op        148 allocs/op
BenchmarkEchoSpeed64K
BenchmarkEchoSpeed64K-32                    1995            510301 ns/op         128.43 MB/s      284233 B/op       2297 allocs/op
BenchmarkEchoSpeed512K
BenchmarkEchoSpeed512K-32                    259           4058131 ns/op         129.19 MB/s     2243058 B/op      18148 allocs/op
BenchmarkEchoSpeed1M
BenchmarkEchoSpeed1M-32                      145           8561996 ns/op         122.47 MB/s     4464227 B/op      36009 allocs/op
BenchmarkSinkSpeed4K
BenchmarkSinkSpeed4K-32                   194648             42136 ns/op          97.21 MB/s        2073 B/op         50 allocs/op
BenchmarkSinkSpeed64K
BenchmarkSinkSpeed64K-32                   10000            113038 ns/op         579.77 MB/s       29242 B/op        741 allocs/op
BenchmarkSinkSpeed256K
BenchmarkSinkSpeed256K-32                   1555            843724 ns/op         621.40 MB/s      229558 B/op       5850 allocs/op
BenchmarkSinkSpeed1M
BenchmarkSinkSpeed1M-32                      667           1783214 ns/op         588.03 MB/s      462691 B/op      11694 allocs/op
PASS
ok      github.com/xtaci/kcp-go/v5      49.978s
===
Model Name:	MacBook Pro
Model Identifier:	MacBookPro14,1
Processor Name:	Intel Core i5
Processor Speed:	3.1 GHz
Number of Processors:	1
Total Number of Cores:	2
L2 Cache (per Core):	256 KB
L3 Cache:	4 MB
Memory:	8 GB
===

$ go test -v -run=^$ -bench .
beginning tests, encryption:salsa20, fec:10/3
goos: darwin
goarch: amd64
pkg: github.com/xtaci/kcp-go
BenchmarkSM4-4                 	   50000	     32180 ns/op	  93.23 MB/s	       0 B/op	       0 allocs/op
BenchmarkAES128-4              	  500000	      3285 ns/op	 913.21 MB/s	       0 B/op	       0 allocs/op
BenchmarkAES192-4              	  300000	      3623 ns/op	 827.85 MB/s	       0 B/op	       0 allocs/op
BenchmarkAES256-4              	  300000	      3874 ns/op	 774.20 MB/s	       0 B/op	       0 allocs/op
BenchmarkTEA-4                 	  100000	     15384 ns/op	 195.00 MB/s	       0 B/op	       0 allocs/op
BenchmarkXOR-4                 	20000000	        89.9 ns/op	33372.00 MB/s	       0 B/op	       0 allocs/op
BenchmarkBlowfish-4            	   50000	     26927 ns/op	 111.41 MB/s	       0 B/op	       0 allocs/op
BenchmarkNone-4                	30000000	        45.7 ns/op	65597.94 MB/s	       0 B/op	       0 allocs/op
BenchmarkCast5-4               	   50000	     34258 ns/op	  87.57 MB/s	       0 B/op	       0 allocs/op
Benchmark3DES-4                	   10000	    117149 ns/op	  25.61 MB/s	       0 B/op	       0 allocs/op
BenchmarkTwofish-4             	   50000	     33538 ns/op	  89.45 MB/s	       0 B/op	       0 allocs/op
BenchmarkXTEA-4                	   30000	     45666 ns/op	  65.69 MB/s	       0 B/op	       0 allocs/op
BenchmarkSalsa20-4             	  500000	      3308 ns/op	 906.76 MB/s	       0 B/op	       0 allocs/op
BenchmarkCRC32-4               	20000000	        65.2 ns/op	15712.43 MB/s
BenchmarkCsprngSystem-4        	 1000000	      1150 ns/op	  13.91 MB/s
BenchmarkCsprngMD5-4           	10000000	       145 ns/op	 110.26 MB/s
BenchmarkCsprngSHA1-4          	10000000	       158 ns/op	 126.54 MB/s
BenchmarkCsprngNonceMD5-4      	10000000	       153 ns/op	 104.22 MB/s
BenchmarkCsprngNonceAES128-4   	100000000	        19.1 ns/op	 837.81 MB/s
BenchmarkFECDecode-4           	 1000000	      1119 ns/op	1339.61 MB/s	    1606 B/op	       2 allocs/op
BenchmarkFECEncode-4           	 2000000	       832 ns/op	1801.83 MB/s	      17 B/op	       0 allocs/op
BenchmarkFlush-4               	 5000000	       272 ns/op	       0 B/op	       0 allocs/op
BenchmarkEchoSpeed4K-4         	    5000	    259617 ns/op	  15.78 MB/s	    5451 B/op	     149 allocs/op
BenchmarkEchoSpeed64K-4        	    1000	   1706084 ns/op	  38.41 MB/s	   56002 B/op	    1604 allocs/op
BenchmarkEchoSpeed512K-4       	     100	  14345505 ns/op	  36.55 MB/s	  482597 B/op	   13045 allocs/op
BenchmarkEchoSpeed1M-4         	      30	  34859104 ns/op	  30.08 MB/s	 1143773 B/op	   27186 allocs/op
BenchmarkSinkSpeed4K-4         	   50000	     31369 ns/op	 130.57 MB/s	    1566 B/op	      30 allocs/op
BenchmarkSinkSpeed64K-4        	    5000	    329065 ns/op	 199.16 MB/s	   21529 B/op	     453 allocs/op
BenchmarkSinkSpeed256K-4       	     500	   2373354 ns/op	 220.91 MB/s	  166332 B/op	    3554 allocs/op
BenchmarkSinkSpeed1M-4         	     300	   5117927 ns/op	 204.88 MB/s	  310378 B/op	    6988 allocs/op
PASS
ok  	github.com/xtaci/kcp-go	50.349s
=== Raspberry Pi 4 ===

➜  kcp-go git:(master) cat /proc/cpuinfo
processor	: 0
model name	: ARMv7 Processor rev 3 (v7l)
BogoMIPS	: 108.00
Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x0
CPU part	: 0xd08
CPU revision	: 3

➜  kcp-go git:(master)  go test -run=^$ -bench .
2020/01/05 19:25:13 beginning tests, encryption:salsa20, fec:10/3
goos: linux
goarch: arm
pkg: github.com/xtaci/kcp-go/v5
BenchmarkSM4-4                     20000             86475 ns/op          34.69 MB/s           0 B/op          0 allocs/op
BenchmarkAES128-4                  20000             62254 ns/op          48.19 MB/s           0 B/op          0 allocs/op
BenchmarkAES192-4                  20000             71802 ns/op          41.78 MB/s           0 B/op          0 allocs/op
BenchmarkAES256-4                  20000             80570 ns/op          37.23 MB/s           0 B/op          0 allocs/op
BenchmarkTEA-4                     50000             37343 ns/op          80.34 MB/s           0 B/op          0 allocs/op
BenchmarkXOR-4                    100000             22266 ns/op         134.73 MB/s           0 B/op          0 allocs/op
BenchmarkBlowfish-4                20000             66123 ns/op          45.37 MB/s           0 B/op          0 allocs/op
BenchmarkNone-4                  3000000               518 ns/op        5786.77 MB/s           0 B/op          0 allocs/op
BenchmarkCast5-4                   20000             76705 ns/op          39.11 MB/s           0 B/op          0 allocs/op
Benchmark3DES-4                     5000            418868 ns/op           7.16 MB/s           0 B/op          0 allocs/op
BenchmarkTwofish-4                  5000            326896 ns/op           9.18 MB/s           0 B/op          0 allocs/op
BenchmarkXTEA-4                    10000            114418 ns/op          26.22 MB/s           0 B/op          0 allocs/op
BenchmarkSalsa20-4                 50000             36736 ns/op          81.66 MB/s           0 B/op          0 allocs/op
BenchmarkCRC32-4                 1000000              1735 ns/op         589.98 MB/s
BenchmarkCsprngSystem-4          1000000              2179 ns/op           7.34 MB/s
BenchmarkCsprngMD5-4             2000000               811 ns/op          19.71 MB/s
BenchmarkCsprngSHA1-4            2000000               862 ns/op          23.19 MB/s
BenchmarkCsprngNonceMD5-4        2000000               878 ns/op          18.22 MB/s
BenchmarkCsprngNonceAES128-4     5000000               326 ns/op          48.97 MB/s
BenchmarkFECDecode-4              200000              9081 ns/op         165.16 MB/s         140 B/op          1 allocs/op
BenchmarkFECEncode-4              100000             12039 ns/op         124.59 MB/s          11 B/op          0 allocs/op
BenchmarkFlush-4                  100000             21704 ns/op               0 B/op          0 allocs/op
BenchmarkEchoSpeed4K-4              2000            981182 ns/op           4.17 MB/s       12384 B/op        424 allocs/op
BenchmarkEchoSpeed64K-4              100          10503324 ns/op           6.24 MB/s      123616 B/op       3779 allocs/op
BenchmarkEchoSpeed512K-4              20         138633802 ns/op           3.78 MB/s     1606584 B/op      29233 allocs/op
BenchmarkEchoSpeed1M-4                 5         372903568 ns/op           2.81 MB/s     4080504 B/op      63600 allocs/op
BenchmarkSinkSpeed4K-4             10000            121239 ns/op          33.78 MB/s        4647 B/op        104 allocs/op
BenchmarkSinkSpeed64K-4             1000           1587906 ns/op          41.27 MB/s       50914 B/op       1115 allocs/op
BenchmarkSinkSpeed256K-4             100          16277830 ns/op          32.21 MB/s      453027 B/op       9296 allocs/op
BenchmarkSinkSpeed1M-4               100          31040703 ns/op          33.78 MB/s      898097 B/op      18932 allocs/op
PASS
ok      github.com/xtaci/kcp-go/v5      64.151s

Typical Flame Graph

Flame Graph in kcptun

Connection Termination

Control messages like SYN/FIN/RST in TCP are not defined in KCP. You need a keepalive/heartbeat mechanism at the application level. A practical example is to use a multiplexing protocol over the session, such as smux (which has an embedded keepalive mechanism). See kcptun for a reference implementation.

FAQ

Q: I'm handling >5K connections on my server, and the CPU utilization is very high.

A: A standalone agent or gate server for running kcp-go is recommended, not only to reduce CPU utilization but also to improve the precision of RTT measurements (timing), which indirectly affects retransmission. Increasing the update interval with SetNoDelay, such as conn.SetNoDelay(1, 40, 1, 1), will dramatically reduce system load but may lower performance.

Q: When should I enable FEC?

A: Forward error correction is critical for long-distance transmission because packet loss incurs a significant time penalty. In the complex packet routing networks of the modern world, round-trip time-based loss checks are not always efficient. The significant deviation of RTT samples over long distances typically leads to a larger RTO value in typical RTT estimators, which slows down transmission.

Q: Should I enable encryption?

A: Yes, for the security of the protocol, even if the upper layer has encryption.

Who is using this?

  1. https://github.com/xtaci/kcptun -- A Secure Tunnel Based on KCP over UDP.
  2. https://github.com/getlantern/lantern -- Lantern delivers fast access to the open Internet.
  3. https://github.com/smallnest/rpcx -- An RPC service framework based on net/rpc, similar to Alibaba Dubbo and Weibo Motan.
  4. https://github.com/gonet2/agent -- A gateway for games with stream multiplexing.
  5. https://github.com/syncthing/syncthing -- Open Source Continuous File Synchronization.

Looking for a C++ client?

  1. https://github.com/xtaci/libkcp -- FEC enhanced KCP session library for iOS/Android in C++

Examples

  1. simple examples
  2. kcptun client
  3. kcptun server
  1. https://github.com/xtaci/smux/ -- A Stream Multiplexing Library for golang with least memory
  2. https://github.com/xtaci/libkcp -- FEC enhanced KCP session library for iOS/Android in C++
  3. https://github.com/skywind3000/kcp -- A Fast and Reliable ARQ Protocol
  4. https://github.com/klauspost/reedsolomon -- Reed-Solomon Erasure Coding in Go

Documentation

Overview

if build tag debug is not set, then debugLog will ingore in compile time

Package kcp-go is a Reliable-UDP library for golang.

This library intents to provide a smooth, resilient, ordered, error-checked and anonymous delivery of streams over UDP packets.

The interfaces of this package aims to be compatible with net.Conn in standard library, but offers powerful features for advanced users.

Index

Constants

View Source
const (
	IKCP_RTO_NDL     = 30  // no delay min rto
	IKCP_RTO_MIN     = 100 // normal min rto
	IKCP_RTO_DEF     = 200
	IKCP_RTO_MAX     = 60000
	IKCP_CMD_PUSH    = 81 // cmd: push data
	IKCP_CMD_ACK     = 82 // cmd: ack
	IKCP_CMD_WASK    = 83 // cmd: window probe (ask)
	IKCP_CMD_WINS    = 84 // cmd: window size (tell)
	IKCP_ASK_SEND    = 1  // need to send IKCP_CMD_WASK
	IKCP_ASK_TELL    = 2  // need to send IKCP_CMD_WINS
	IKCP_WND_SND     = 32
	IKCP_WND_RCV     = 32
	IKCP_MTU_DEF     = 1400
	IKCP_ACK_FAST    = 3
	IKCP_INTERVAL    = 100
	IKCP_OVERHEAD    = 24
	IKCP_DEADLINK    = 20
	IKCP_THRESH_INIT = 2
	IKCP_THRESH_MIN  = 2
	IKCP_PROBE_INIT  = 500    // 500ms to probe window size
	IKCP_PROBE_LIMIT = 120000 // up to 120 secs to probe window
	IKCP_SN_OFFSET   = 12
)
View Source
const (
	RINGBUFFER_MIN = 8
	RINGBUFFER_EXP = 1024
)

Variables

This section is empty.

Functions

func Dial

func Dial(raddr string) (net.Conn, error)

Dial connects to the remote address "raddr" on the network "udp" without encryption and FEC

func Listen

func Listen(laddr string) (net.Listener, error)

Listen listens for incoming KCP packets addressed to the local address laddr on the network "udp",

func NewEntropy added in v5.6.48

func NewEntropy() io.Reader

NewEntropy creates a new entropy source.

func NewEntropyAES added in v5.6.48

func NewEntropyAES() io.Reader

NewEntropyAES creates a new AES-based entropy source.

func NewEntropyChacha8 added in v5.6.48

func NewEntropyChacha8() io.Reader

NewEntropyChacha8 creates a new ChaCha8-based entropy source.

func SetEntropy added in v5.6.48

func SetEntropy(r io.Reader)

SetEntropy sets the global entropy source used by fillRand.

Types

type BlockCrypt

type BlockCrypt interface {
	// Encrypt encrypts the whole block in src into dst.
	// Dst and src may point at the same memory.
	Encrypt(dst, src []byte)

	// Decrypt decrypts the whole block in src into dst.
	// Dst and src may point at the same memory.
	Decrypt(dst, src []byte)
}

BlockCrypt defines encryption/decryption methods for a given byte slice. Notes on implementing: the data to be encrypted contains a builtin nonce at the first 16 bytes

func NewAEADCrypt added in v5.6.49

func NewAEADCrypt(aead cipher.AEAD) BlockCrypt

NewAEADCrypt creates an AEAD BlockCrypt instance from an existing cipher.AEAD

func NewAESGCMCrypt added in v5.6.49

func NewAESGCMCrypt(key []byte) (BlockCrypt, error)

NewAESGCMCrypt creates an AEAD BlockCrypt instance using AES-GCM key must be either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.

func NewBlowfishBlockCrypt

func NewBlowfishBlockCrypt(key []byte) (BlockCrypt, error)

NewBlowfishBlockCrypt https://en.wikipedia.org/wiki/Blowfish_(cipher)

func NewCast5BlockCrypt

func NewCast5BlockCrypt(key []byte) (BlockCrypt, error)

NewCast5BlockCrypt https://en.wikipedia.org/wiki/CAST-128

func NewNoneBlockCrypt

func NewNoneBlockCrypt(key []byte) (BlockCrypt, error)

NewNoneBlockCrypt does nothing but copying

func NewSM4BlockCrypt

func NewSM4BlockCrypt(key []byte) (BlockCrypt, error)

NewSM4BlockCrypt https://github.com/tjfoc/gmsm/tree/master/sm4

func NewSalsa20BlockCrypt

func NewSalsa20BlockCrypt(key []byte) (BlockCrypt, error)

NewSalsa20BlockCrypt https://en.wikipedia.org/wiki/Salsa20

func NewSimpleXORBlockCrypt

func NewSimpleXORBlockCrypt(key []byte) (BlockCrypt, error)

NewSimpleXORBlockCrypt simple xor with key expanding

func NewTripleDESBlockCrypt

func NewTripleDESBlockCrypt(key []byte) (BlockCrypt, error)

NewTripleDESBlockCrypt https://en.wikipedia.org/wiki/Triple_DES

func NewTwofishBlockCrypt

func NewTwofishBlockCrypt(key []byte) (BlockCrypt, error)

NewTwofishBlockCrypt https://en.wikipedia.org/wiki/Twofish

func NewXTEABlockCrypt

func NewXTEABlockCrypt(key []byte) (BlockCrypt, error)

NewXTEABlockCrypt https://en.wikipedia.org/wiki/XTEA

type FlushType added in v5.6.34

type FlushType int8
const (
	IKCP_FLUSH_ACKONLY FlushType = 1 << iota
	IKCP_FLUSH_FULL
)

type KCP

type KCP struct {
	// contains filtered or unexported fields
}

KCP defines a single KCP connection

func NewKCP

func NewKCP(conv uint32, output output_callback) *KCP

NewKCP create a new kcp state machine

'conv' must be equal in the connection peers, or else data will be silently rejected.

'output' function will be called whenever these is data to be sent on wire.

func (*KCP) Check

func (kcp *KCP) Check() uint32

(deprecated)

Check determines when should you invoke ikcp_update: returns when you should invoke ikcp_update in millisec, if there is no ikcp_input/_send calling. you can call ikcp_update in that time, instead of call update repeatly. Important to reduce unnacessary ikcp_update invoking. use it to schedule ikcp_update (eg. implementing an epoll-like mechanism, or optimize ikcp_update when handling massive kcp connections)

func (*KCP) Input

func (kcp *KCP) Input(data []byte, pktType PacketType, ackNoDelay bool) int

Input a packet into kcp state machine.

'regular' indicates it's a real data packet from remote, and it means it's not generated from ReedSolomon codecs.

'ackNoDelay' will trigger immediate ACK, but surely it will not be efficient in bandwidth

func (*KCP) NoDelay

func (kcp *KCP) NoDelay(nodelay, interval, resend, nc int) int

NoDelay options fastest: ikcp_nodelay(kcp, 1, 20, 2, 1) nodelay: 0:disable(default), 1:enable interval: internal update timer interval in millisec, default is 100ms resend: 0:disable fast resend(default), 1:enable fast resend nc: 0:normal congestion control(default), 1:disable congestion control

func (*KCP) PeekSize

func (kcp *KCP) PeekSize() (length int)

PeekSize checks the size of next message in the recv queue

func (*KCP) Recv

func (kcp *KCP) Recv(buffer []byte) (n int)

Receive data from kcp state machine

Return number of bytes read.

Return -1 when there is no readable data.

Return -2 if len(buffer) is smaller than kcp.PeekSize().

func (*KCP) Send

func (kcp *KCP) Send(buffer []byte) int

Send is user/upper level send, returns below zero for error

func (*KCP) SetLogger added in v5.6.39

func (kcp *KCP) SetLogger(mask KCPLogType, logger logoutput_callback)

SetLogger configures the trace logger

func (*KCP) SetMtu

func (kcp *KCP) SetMtu(mtu int) int

SetMtu changes MTU size, default is 1400

func (*KCP) Update

func (kcp *KCP) Update()

(deprecated)

Update updates state (call it repeatedly, every 10ms-100ms), or you can ask ikcp_check when to call it again (without ikcp_input/_send calling). 'current' - current timestamp in millisec.

func (*KCP) WaitSnd

func (kcp *KCP) WaitSnd() int

WaitSnd gets how many packet is waiting to be sent

func (*KCP) WndSize

func (kcp *KCP) WndSize(sndwnd, rcvwnd int) int

WndSize sets maximum window size: sndwnd=32, rcvwnd=32 by default

type KCPLogType added in v5.6.39

type KCPLogType int32
const (
	IKCP_LOG_OUTPUT KCPLogType = 1 << iota
	IKCP_LOG_INPUT
	IKCP_LOG_SEND
	IKCP_LOG_RECV
	IKCP_LOG_OUT_ACK
	IKCP_LOG_OUT_PUSH
	IKCP_LOG_OUT_WASK
	IKCP_LOG_OUT_WINS
	IKCP_LOG_IN_ACK
	IKCP_LOG_IN_PUSH
	IKCP_LOG_IN_WASK
	IKCP_LOG_IN_WINS
)

type Listener

type Listener struct {
	// contains filtered or unexported fields
}

Listener defines a server which will be waiting to accept incoming connections

func ListenWithOptions

func ListenWithOptions(laddr string, block BlockCrypt, dataShards, parityShards int) (*Listener, error)

ListenWithOptions listens for incoming KCP packets addressed to the local address laddr on the network "udp" with packet encryption.

'block' is the block encryption algorithm to encrypt packets.

'dataShards', 'parityShards' specify how many parity packets will be generated following the data packets.

Check https://github.com/klauspost/reedsolomon for details

func ServeConn

func ServeConn(block BlockCrypt, dataShards, parityShards int, conn net.PacketConn) (*Listener, error)

ServeConn serves KCP protocol for a single packet connection.

func (*Listener) Accept

func (l *Listener) Accept() (net.Conn, error)

Accept implements the Accept method in the Listener interface; it waits for the next call and returns a generic Conn.

func (*Listener) AcceptKCP

func (l *Listener) AcceptKCP() (*UDPSession, error)

AcceptKCP accepts a KCP connection

func (*Listener) Addr

func (l *Listener) Addr() net.Addr

Addr returns the listener's network address, The Addr returned is shared by all invocations of Addr, so do not modify it.

func (*Listener) Close

func (l *Listener) Close() error

Close stops listening on the UDP address, and closes the socket

func (*Listener) Control added in v5.6.15

func (l *Listener) Control(f func(conn net.PacketConn) error) error

Control applys a procedure to the underly socket fd. CAUTION: BE VERY CAREFUL TO USE THIS FUNCTION, YOU MAY BREAK THE PROTOCOL.

func (*Listener) SetDSCP

func (l *Listener) SetDSCP(dscp int) error

SetDSCP sets the 6bit DSCP field in IPv4 header, or 8bit Traffic Class in IPv6 header.

if the underlying connection has implemented `func SetDSCP(int) error`, SetDSCP() will invoke this function instead.

func (*Listener) SetDeadline

func (l *Listener) SetDeadline(t time.Time) error

SetDeadline sets the deadline associated with the listener. A zero time value disables the deadline.

func (*Listener) SetReadBuffer

func (l *Listener) SetReadBuffer(bytes int) error

SetReadBuffer sets the socket read buffer for the Listener

func (*Listener) SetReadDeadline

func (l *Listener) SetReadDeadline(t time.Time) error

SetReadDeadline implements the Conn SetReadDeadline method.

func (*Listener) SetWriteBuffer

func (l *Listener) SetWriteBuffer(bytes int) error

SetWriteBuffer sets the socket write buffer for the Listener

func (*Listener) SetWriteDeadline

func (l *Listener) SetWriteDeadline(t time.Time) error

SetWriteDeadline implements the Conn SetWriteDeadline method.

type OOBCallBackType added in v5.6.60

type OOBCallBackType func([]byte)

OOB callback function

type PacketType added in v5.6.40

type PacketType int8
const (
	IKCP_PACKET_REGULAR PacketType = iota
	IKCP_PACKET_FEC
)

type RingBuffer added in v5.6.22

type RingBuffer[T any] struct {
	// contains filtered or unexported fields
}

RingBuffer is a generic ring (circular) buffer that supports dynamic resizing. It provides efficient FIFO queue behavior with amortized constant time operations.

func NewRingBuffer added in v5.6.22

func NewRingBuffer[T any](size int) *RingBuffer[T]

NewRingBuffer creates a new Ring with a specified initial capacity. If the provided size is <= 8, it defaults to 8.

func (*RingBuffer[T]) Clear added in v5.6.22

func (r *RingBuffer[T]) Clear()

Clear resets the ring to an empty state and reinitializes the buffer.

func (*RingBuffer[T]) Discard added in v5.6.22

func (r *RingBuffer[T]) Discard(n int) int

Discard discards the first N elements from the ring buffer. Returns the number of elements that are actually discarded (<= n).

func (*RingBuffer[T]) ForEach added in v5.6.22

func (r *RingBuffer[T]) ForEach(fn func(*T) bool)

ForEach iterates over each element in the ring buffer, applying the provided function. If the function returns false, iteration stops early.

func (*RingBuffer[T]) ForEachReverse added in v5.6.22

func (r *RingBuffer[T]) ForEachReverse(fn func(*T) bool)

ForEachReverse iterates over each element in the ring buffer in reverse order, applying the provided function. If the function returns false, iteration stops early.

func (*RingBuffer[T]) IsEmpty added in v5.6.22

func (r *RingBuffer[T]) IsEmpty() bool

IsEmpty returns true if the ring has no elements.

func (*RingBuffer[T]) IsFull added in v5.6.22

func (r *RingBuffer[T]) IsFull() bool

IsFull returns true if the ring buffer is full (tail + 1 == head).

func (*RingBuffer[T]) Len added in v5.6.22

func (r *RingBuffer[T]) Len() int

Len returns the number of elements currently in the ring.

func (*RingBuffer[T]) MaxLen added in v5.6.22

func (r *RingBuffer[T]) MaxLen() int

MaxLen returns the maximum capacity of the ring buffer.

func (*RingBuffer[T]) Peek added in v5.6.22

func (r *RingBuffer[T]) Peek() (*T, bool)

Peek returns the element at the head of the ring without removing it. It returns the zero value and false if the ring is empty.

func (*RingBuffer[T]) Pop added in v5.6.22

func (r *RingBuffer[T]) Pop() (T, bool)

Pop removes and returns the element from the head of the ring. It returns the zero value and false if the ring is empty.

func (*RingBuffer[T]) Push added in v5.6.22

func (r *RingBuffer[T]) Push(v T)

Push adds an element to the tail of the ring. If the ring is full, it will grow automatically.

type Snmp

type Snmp struct {
	BytesSent           uint64 // bytes sent from upper level
	BytesReceived       uint64 // bytes received to upper level
	MaxConn             uint64 // max number of connections ever reached
	ActiveOpens         uint64 // accumulated active open connections
	PassiveOpens        uint64 // accumulated passive open connections
	CurrEstab           uint64 // current number of established connections
	InErrs              uint64 // UDP read errors reported from net.PacketConn
	InCsumErrors        uint64 // checksum errors from CRC32
	KCPInErrors         uint64 // packet iput errors reported from KCP
	InPkts              uint64 // incoming packets count
	OutPkts             uint64 // outgoing packets count
	InSegs              uint64 // incoming KCP segments
	OutSegs             uint64 // outgoing KCP segments
	InBytes             uint64 // UDP bytes received
	OutBytes            uint64 // UDP bytes sent
	RetransSegs         uint64 // accmulated retransmited segments
	FastRetransSegs     uint64 // accmulated fast retransmitted segments
	EarlyRetransSegs    uint64 // accmulated early retransmitted segments
	LostSegs            uint64 // number of segs inferred as lost
	RepeatSegs          uint64 // number of segs duplicated
	FECFullShardSet     uint64 // number of FEC segments that are full
	FECRecovered        uint64 // correct packets recovered from FEC
	FECErrs             uint64 // incorrect packets recovered from FEC
	FECParityShards     uint64 // FEC segments received
	FECShardSet         uint64 // number of parity shards that are not yet received
	FECShardMin         uint64 // the minimum ID of FEC shards
	RingBufferSndQueue  uint64 // Len of segments in send queue ring buffer
	RingBufferRcvQueue  uint64 // Len of segments in receive queue ring buffer
	RingBufferSndBuffer uint64 // Len of segments in send buffer ring buffer
	OOBPackets          uint64 // number of OOB packets received
}

Snmp defines network statistics indicator

var DefaultSnmp *Snmp

DefaultSnmp is the global KCP connection statistics collector

func (*Snmp) Copy

func (s *Snmp) Copy() *Snmp

Copy make a copy of current snmp snapshot

func (*Snmp) Header

func (s *Snmp) Header() []string

Header returns all field names

func (*Snmp) Reset

func (s *Snmp) Reset()

Reset values to zero

func (*Snmp) ToSlice

func (s *Snmp) ToSlice() []string

ToSlice returns current snmp info as slice

type TimedSched added in v5.5.0

type TimedSched struct {
	// contains filtered or unexported fields
}

TimedSched represents the control struct for timed parallel scheduler

var SystemTimedSched *TimedSched = NewTimedSched(runtime.NumCPU())

SystemTimedSched is the library level timed-scheduler

func NewTimedSched added in v5.5.0

func NewTimedSched(parallel int) *TimedSched

NewTimedSched creates a parallel-scheduler with given parallelization

func (*TimedSched) Close added in v5.5.0

func (ts *TimedSched) Close()

Close terminates this scheduler

func (*TimedSched) Put added in v5.5.0

func (ts *TimedSched) Put(f func(), deadline time.Time)

Put a function 'f' awaiting to be executed at 'deadline'

type UDPSession

type UDPSession struct {
	// contains filtered or unexported fields
}

UDPSession defines a KCP session implemented by UDP

func DialWithOptions

func DialWithOptions(raddr string, block BlockCrypt, dataShards, parityShards int) (*UDPSession, error)

DialWithOptions connects to the remote address "raddr" on the network "udp" with packet encryption

'block' is the block encryption algorithm to encrypt packets.

'dataShards', 'parityShards' specify how many parity packets will be generated following the data packets.

Check https://github.com/klauspost/reedsolomon for details

func NewConn

func NewConn(raddr string, block BlockCrypt, dataShards, parityShards int, conn net.PacketConn) (*UDPSession, error)

NewConn establishes a session and talks KCP protocol over a packet connection.

func NewConn2

func NewConn2(raddr net.Addr, block BlockCrypt, dataShards, parityShards int, conn net.PacketConn) (*UDPSession, error)

NewConn2 establishes a session and talks KCP protocol over a packet connection.

func NewConn3

func NewConn3(convid uint32, raddr net.Addr, block BlockCrypt, dataShards, parityShards int, conn net.PacketConn) (*UDPSession, error)

NewConn3 establishes a session and talks KCP protocol over a packet connection.

func NewConn4 added in v5.6.14

func NewConn4(convid uint32, raddr net.Addr, block BlockCrypt, dataShards, parityShards int, ownConn bool, conn net.PacketConn) (*UDPSession, error)

NewConn4 establishes a session and talks KCP protocol over a packet connection.

func (*UDPSession) Close

func (s *UDPSession) Close() error

Close closes the connection.

func (*UDPSession) Control added in v5.6.15

func (s *UDPSession) Control(f func(conn net.PacketConn) error) error

Control applys a procedure to the underly socket fd. CAUTION: BE VERY CAREFUL TO USE THIS FUNCTION, YOU MAY BREAK THE PROTOCOL.

func (*UDPSession) GetConv

func (s *UDPSession) GetConv() uint32

GetConv gets conversation id of a session

func (*UDPSession) GetOOBMaxSize added in v5.6.60

func (s *UDPSession) GetOOBMaxSize() int

GetOOBMaxSize returns the maximum payload size for an OOB packet.

The returned value is the maximum number of bytes that can be carried as OOB data in a single packet, based on the current MTU and protocol layout.

If FEC is not enabled, OOB is unsupported and this function returns 0.

func (*UDPSession) GetRTO added in v5.5.13

func (s *UDPSession) GetRTO() uint32

GetRTO gets current rto of the session

func (*UDPSession) GetSRTT added in v5.5.15

func (s *UDPSession) GetSRTT() int32

GetSRTT gets current srtt of the session

func (*UDPSession) GetSRTTVar added in v5.5.15

func (s *UDPSession) GetSRTTVar() int32

GetRTTVar gets current rtt variance of the session

func (*UDPSession) LocalAddr

func (s *UDPSession) LocalAddr() net.Addr

LocalAddr returns the local network address. The Addr returned is shared by all invocations of LocalAddr, so do not modify it.

func (*UDPSession) Read

func (s *UDPSession) Read(b []byte) (n int, err error)

Read implements net.Conn

func (*UDPSession) RemoteAddr

func (s *UDPSession) RemoteAddr() net.Addr

RemoteAddr returns the remote network address. The Addr returned is shared by all invocations of RemoteAddr, so do not modify it.

func (*UDPSession) SendOOB added in v5.6.60

func (s *UDPSession) SendOOB(data []byte) error

SendOOB sends an out-of-band (OOB) data packet.

OOB packets:

  • Are unreliable: they are NOT retransmitted if lost.
  • Are unordered: delivery order is not guaranteed.
  • Are unacknowledged: no ACKs are generated.
  • Bypass the KCP reliable data path.
  • Reuse the FEC header layout for demultiplexing, but are NOT protected by FEC.

The OOB payload MUST fit into a single packet. If the payload is too large, an error is returned.

If the internal send queue is full, the OOB packet is dropped silently.

func (*UDPSession) SetACKNoDelay

func (s *UDPSession) SetACKNoDelay(nodelay bool)

SetACKNoDelay changes ack flush option, set true to flush ack immediately,

func (*UDPSession) SetDSCP

func (s *UDPSession) SetDSCP(dscp int) error

SetDSCP sets the 6bit DSCP field in IPv4 header, or 8bit Traffic Class in IPv6 header.

if the underlying connection has implemented `func SetDSCP(int) error`, SetDSCP() will invoke this function instead.

It has no effect if it's accepted from Listener.

func (*UDPSession) SetDUP

func (s *UDPSession) SetDUP(dup int)

(deprecated)

SetDUP duplicates udp packets for kcp output.

func (*UDPSession) SetDeadline

func (s *UDPSession) SetDeadline(t time.Time) error

SetDeadline sets the deadline associated with the listener. A zero time value disables the deadline.

func (*UDPSession) SetLogger added in v5.6.39

func (s *UDPSession) SetLogger(mask KCPLogType, logger logoutput_callback)

SetLogger configures the kcp trace logger

func (*UDPSession) SetMtu

func (s *UDPSession) SetMtu(mtu int) bool

SetMtu sets the maximum transmission unit(not including UDP header)

func (*UDPSession) SetNoDelay

func (s *UDPSession) SetNoDelay(nodelay, interval, resend, nc int)

SetNoDelay calls nodelay() of kcp https://github.com/skywind3000/kcp/blob/master/README.en.md#protocol-configuration

func (*UDPSession) SetOOBHandler added in v5.6.60

func (s *UDPSession) SetOOBHandler(callback OOBCallBackType) error

SetOOBHandler registers a callback for receiving out-of-band (OOB) data.

OOB data is delivered unreliably and bypasses the KCP reliable data path. The callback is invoked synchronously from the KCP input processing path.

The callback MUST return quickly and MUST NOT perform any blocking operations. Blocking inside the callback will stall processing of all other KCP packets.

Passing a nil callback unregisters the current OOB callback.

OOB support requires FEC to be enabled, as the OOB packet format reuses the FEC header layout for demultiplexing.

func (*UDPSession) SetRateLimit added in v5.6.35

func (s *UDPSession) SetRateLimit(bytesPerSecond uint32)

SetRateLimit sets the rate limit for this session in bytes per second, by setting to 0 will disable rate limiting.

func (*UDPSession) SetReadBuffer

func (s *UDPSession) SetReadBuffer(bytes int) error

SetReadBuffer sets the socket read buffer, no effect if it's accepted from Listener

func (*UDPSession) SetReadDeadline

func (s *UDPSession) SetReadDeadline(t time.Time) error

SetReadDeadline implements the Conn SetReadDeadline method.

func (*UDPSession) SetStreamMode deprecated

func (s *UDPSession) SetStreamMode(enable bool)

Deprecated: toggles the stream mode on/off

func (*UDPSession) SetWindowSize

func (s *UDPSession) SetWindowSize(sndwnd, rcvwnd int)

SetWindowSize set maximum window size

func (*UDPSession) SetWriteBuffer

func (s *UDPSession) SetWriteBuffer(bytes int) error

SetWriteBuffer sets the socket write buffer, no effect if it's accepted from Listener

func (*UDPSession) SetWriteDeadline

func (s *UDPSession) SetWriteDeadline(t time.Time) error

SetWriteDeadline implements the Conn SetWriteDeadline method.

func (*UDPSession) SetWriteDelay

func (s *UDPSession) SetWriteDelay(delay bool)

SetWriteDelay delays write for bulk transfer until the next update interval

func (*UDPSession) Write

func (s *UDPSession) Write(b []byte) (n int, err error)

Write implements net.Conn

func (*UDPSession) WriteBuffers

func (s *UDPSession) WriteBuffers(v [][]byte) (n int, err error)

WriteBuffers write a vector of byte slices to the underlying connection

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL