mirror of
https://github.com/v2fly/v2ray-core.git
synced 2026-06-19 01:09:55 -04:00
refine kcp header and security
This commit is contained in:
92
transport/internet/kcp/io.go
Normal file
92
transport/internet/kcp/io.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package kcp
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
|
||||
"v2ray.com/core/transport/internet"
|
||||
)
|
||||
|
||||
type PacketReader interface {
|
||||
Read([]byte) []Segment
|
||||
}
|
||||
|
||||
type PacketWriter interface {
|
||||
Overhead() int
|
||||
io.Writer
|
||||
}
|
||||
|
||||
type KCPPacketReader struct {
|
||||
Security cipher.AEAD
|
||||
Header internet.PacketHeader
|
||||
}
|
||||
|
||||
func (v *KCPPacketReader) Read(b []byte) []Segment {
|
||||
if v.Header != nil {
|
||||
b = b[v.Header.Size():]
|
||||
}
|
||||
if v.Security != nil {
|
||||
nonceSize := v.Security.NonceSize()
|
||||
out, err := v.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 {
|
||||
Header internet.PacketHeader
|
||||
Security cipher.AEAD
|
||||
Writer io.Writer
|
||||
|
||||
buffer [32 * 1024]byte
|
||||
}
|
||||
|
||||
func (v *KCPPacketWriter) Overhead() int {
|
||||
overhead := 0
|
||||
if v.Header != nil {
|
||||
overhead += v.Header.Size()
|
||||
}
|
||||
if v.Security != nil {
|
||||
overhead += v.Security.Overhead()
|
||||
}
|
||||
return overhead
|
||||
}
|
||||
|
||||
func (v *KCPPacketWriter) Write(b []byte) (int, error) {
|
||||
x := v.buffer[:]
|
||||
size := 0
|
||||
if v.Header != nil {
|
||||
nBytes := v.Header.Write(x)
|
||||
size += nBytes
|
||||
x = x[nBytes:]
|
||||
}
|
||||
if v.Security != nil {
|
||||
nonceSize := v.Security.NonceSize()
|
||||
var nonce []byte
|
||||
if nonceSize > 0 {
|
||||
nonce = x[:nonceSize]
|
||||
rand.Read(nonce)
|
||||
x = x[nonceSize:]
|
||||
}
|
||||
x = v.Security.Seal(x[:0], nonce, b, nil)
|
||||
size += nonceSize + len(x)
|
||||
} else {
|
||||
size += copy(x, b)
|
||||
}
|
||||
|
||||
_, err := v.Writer.Write(v.buffer[:size])
|
||||
return len(b), err
|
||||
}
|
||||
Reference in New Issue
Block a user