Hunter0x7c7
2022-08-11 b8230139fb40edea387617b6accd8371e37eda58
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package kcp
 
import (
    "crypto/cipher"
    "crypto/rand"
    "io"
 
    "github.com/v2fly/v2ray-core/v5/common"
    "github.com/v2fly/v2ray-core/v5/common/buf"
    "github.com/v2fly/v2ray-core/v5/transport/internet"
)
 
type PacketReader interface {
    Read([]byte) []Segment
}
 
type PacketWriter interface {
    Overhead() int
    io.Writer
}
 
type KCPPacketReader struct { // nolint: revive
    Security cipher.AEAD
    Header   internet.PacketHeader
}
 
func (r *KCPPacketReader) Read(b []byte) []Segment {
    if r.Header != nil {
        if int32(len(b)) <= r.Header.Size() {
            return nil
        }
        b = b[r.Header.Size():]
    }
    if r.Security != nil {
        nonceSize := r.Security.NonceSize()
        overhead := r.Security.Overhead()
        if len(b) <= nonceSize+overhead {
            return nil
        }
        out, err := r.Security.Open(b[nonceSize:nonceSize], b[:nonceSize], b[nonceSize:], nil)
        if err != nil {
            return nil
        }
        b = out
    }
    var result []Segment
    for len(b) > 0 {
        seg, x := ReadSegment(b)
        if seg == nil {
            break
        }
        result = append(result, seg)
        b = x
    }
    return result
}
 
type KCPPacketWriter struct { // nolint: revive
    Header   internet.PacketHeader
    Security cipher.AEAD
    Writer   io.Writer
}
 
func (w *KCPPacketWriter) Overhead() int {
    overhead := 0
    if w.Header != nil {
        overhead += int(w.Header.Size())
    }
    if w.Security != nil {
        overhead += w.Security.Overhead()
    }
    return overhead
}
 
func (w *KCPPacketWriter) Write(b []byte) (int, error) {
    bb := buf.StackNew()
    defer bb.Release()
 
    if w.Header != nil {
        w.Header.Serialize(bb.Extend(w.Header.Size()))
    }
    if w.Security != nil {
        nonceSize := w.Security.NonceSize()
        common.Must2(bb.ReadFullFrom(rand.Reader, int32(nonceSize)))
        nonce := bb.BytesFrom(int32(-nonceSize))
 
        encrypted := bb.Extend(int32(w.Security.Overhead() + len(b)))
        w.Security.Seal(encrypted[:0], nonce, b, nil)
    } else {
        bb.Write(b)
    }
 
    _, err := w.Writer.Write(bb.Bytes())
    return len(b), err
}