mirror of
https://github.com/hackdiaz-dev/free-turn-proxy.git
synced 2026-10-12 09:41:53 +02:00
perf: убрать аллокации на горячем пути, TCP DPI-split и KCP FEC
- Атомарный счётчик nonce вместо per-packet rand.Read (syscall getrandom); wire-формат не изменён, сервер декодирует без правок - wrapInto: TX-путь без аллокаций с заранее выделенным буфером; wrapPacket оставлен для тестов и control-путей - Кеш указателя при приёме WG исключает аллокацию addr.String() на пакет (быстрый путь — сравнение указателей, медленный — строк) - Атомики статистики throughput спрятаны за isDebug — снижает трафик cache-line по N стримам в production-сборках - splitFirstWriteConn разбивает первую TCP-запись на байте 6 + задержка 20ms, ломая STUN magic cookie между сегментами против поверхностного DPI - VK_TURN_KCP_FEC=data:parity включает Reed-Solomon FEC поверх KCP; обе стороны должны совпадать; по умолчанию 0:0 (выключено) - Исправлен WaitGroup: wg.Add(1) → wg.Add(2) для двух горутин в oneDtlsConnection; раньше wg.Wait() возвращался слишком рано
This commit is contained in:
committed by
antongospod
parent
334a17f1af
commit
7a0f98f730
+6
-4
@@ -180,15 +180,17 @@ type throughputStats struct {
|
||||
}
|
||||
|
||||
func (s *throughputStats) addTx(n int) {
|
||||
if n > 0 {
|
||||
s.tx.Add(uint64(n))
|
||||
if !isDebug || n <= 0 {
|
||||
return
|
||||
}
|
||||
s.tx.Add(uint64(n))
|
||||
}
|
||||
|
||||
func (s *throughputStats) addRx(n int) {
|
||||
if n > 0 {
|
||||
s.rx.Add(uint64(n))
|
||||
if !isDebug || n <= 0 {
|
||||
return
|
||||
}
|
||||
s.rx.Add(uint64(n))
|
||||
}
|
||||
|
||||
func (s *throughputStats) logEvery(ctx context.Context, label, txName, rxName string) {
|
||||
|
||||
+22
-3
@@ -4,9 +4,11 @@ package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
dtlsnet "github.com/pion/dtls/v3/pkg/net"
|
||||
@@ -19,6 +21,25 @@ const (
|
||||
wrapKeyLen = 32
|
||||
)
|
||||
|
||||
// Nonce layout matches the client: [4B session prefix | 8B atomic counter].
|
||||
// Replaces a per-packet crypto/rand syscall (getrandom on Linux) with a
|
||||
// monotonic counter; (key, nonce) uniqueness preserved within the process.
|
||||
// Wire format unchanged.
|
||||
var (
|
||||
nonceSessionPrefix [4]byte
|
||||
nonceCounter atomic.Uint64
|
||||
)
|
||||
|
||||
func init() {
|
||||
_, _ = rand.Read(nonceSessionPrefix[:])
|
||||
}
|
||||
|
||||
func fillWrapNonce(dst []byte) {
|
||||
_ = dst[wrapNonceLen-1]
|
||||
copy(dst[:4], nonceSessionPrefix[:])
|
||||
binary.BigEndian.PutUint64(dst[4:wrapNonceLen], nonceCounter.Add(1))
|
||||
}
|
||||
|
||||
func listenWrapped(addr *net.UDPAddr, key []byte) (dtlsnet.PacketListener, error) {
|
||||
if len(key) != wrapKeyLen {
|
||||
return nil, fmt.Errorf("wrap: key must be %d bytes (got %d)", wrapKeyLen, len(key))
|
||||
@@ -78,9 +99,7 @@ func (c *wrapPacketConn) ReadFrom(p []byte) (int, net.Addr, error) {
|
||||
|
||||
func (c *wrapPacketConn) WriteTo(p []byte, addr net.Addr) (int, error) {
|
||||
out := make([]byte, wrapNonceLen+len(p))
|
||||
if _, err := rand.Read(out[:wrapNonceLen]); err != nil {
|
||||
return 0, fmt.Errorf("wrap: nonce gen: %w", err)
|
||||
}
|
||||
fillWrapNonce(out[:wrapNonceLen])
|
||||
cipher, err := chacha20.NewUnauthenticatedCipher(c.key, out[:wrapNonceLen])
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("wrap: cipher init: %w", err)
|
||||
|
||||
Reference in New Issue
Block a user