2016-12-08 10:27:41 -05:00
|
|
|
package kcp
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/cipher"
|
|
|
|
"crypto/rand"
|
|
|
|
"io"
|
|
|
|
|
2021-02-16 15:31:50 -05:00
|
|
|
"github.com/v2fly/v2ray-core/v4/common"
|
|
|
|
"github.com/v2fly/v2ray-core/v4/common/buf"
|
|
|
|
"github.com/v2fly/v2ray-core/v4/transport/internet"
|
2016-12-08 10:27:41 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
type PacketReader interface {
|
|
|
|
Read([]byte) []Segment
|
|
|
|
}
|
|
|
|
|
|
|
|
type PacketWriter interface {
|
|
|
|
Overhead() int
|
|
|
|
io.Writer
|
|
|
|
}
|
|
|
|
|
2021-11-27 04:16:41 -05:00
|
|
|
type KCPPacketReader struct { // nolint: revive
|
2016-12-08 10:27:41 -05:00
|
|
|
Security cipher.AEAD
|
|
|
|
Header internet.PacketHeader
|
|
|
|
}
|
|
|
|
|
2017-04-13 16:17:58 -04:00
|
|
|
func (r *KCPPacketReader) Read(b []byte) []Segment {
|
|
|
|
if r.Header != nil {
|
2018-12-17 14:31:54 -05:00
|
|
|
if int32(len(b)) <= r.Header.Size() {
|
|
|
|
return nil
|
|
|
|
}
|
2017-04-13 16:17:58 -04:00
|
|
|
b = b[r.Header.Size():]
|
2016-12-08 10:27:41 -05:00
|
|
|
}
|
2017-04-13 16:17:58 -04:00
|
|
|
if r.Security != nil {
|
|
|
|
nonceSize := r.Security.NonceSize()
|
2018-08-07 18:26:01 -04:00
|
|
|
overhead := r.Security.Overhead()
|
|
|
|
if len(b) <= nonceSize+overhead {
|
|
|
|
return nil
|
|
|
|
}
|
2017-04-13 16:17:58 -04:00
|
|
|
out, err := r.Security.Open(b[nonceSize:nonceSize], b[:nonceSize], b[nonceSize:], nil)
|
2016-12-08 10:27:41 -05:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2021-11-27 04:16:41 -05:00
|
|
|
type KCPPacketWriter struct { // nolint: revive
|
2016-12-08 10:27:41 -05:00
|
|
|
Header internet.PacketHeader
|
|
|
|
Security cipher.AEAD
|
|
|
|
Writer io.Writer
|
|
|
|
}
|
|
|
|
|
2017-04-13 16:17:58 -04:00
|
|
|
func (w *KCPPacketWriter) Overhead() int {
|
2016-12-08 10:27:41 -05:00
|
|
|
overhead := 0
|
2017-04-13 16:17:58 -04:00
|
|
|
if w.Header != nil {
|
2018-04-02 14:00:50 -04:00
|
|
|
overhead += int(w.Header.Size())
|
2016-12-08 10:27:41 -05:00
|
|
|
}
|
2017-04-13 16:17:58 -04:00
|
|
|
if w.Security != nil {
|
|
|
|
overhead += w.Security.Overhead()
|
2016-12-08 10:27:41 -05:00
|
|
|
}
|
|
|
|
return overhead
|
|
|
|
}
|
|
|
|
|
2017-04-13 16:17:58 -04:00
|
|
|
func (w *KCPPacketWriter) Write(b []byte) (int, error) {
|
2018-11-15 15:32:27 -05:00
|
|
|
bb := buf.StackNew()
|
2018-04-02 16:12:51 -04:00
|
|
|
defer bb.Release()
|
|
|
|
|
2017-04-13 16:17:58 -04:00
|
|
|
if w.Header != nil {
|
2018-11-02 16:34:04 -04:00
|
|
|
w.Header.Serialize(bb.Extend(w.Header.Size()))
|
2016-12-08 10:27:41 -05:00
|
|
|
}
|
2017-04-13 16:17:58 -04:00
|
|
|
if w.Security != nil {
|
|
|
|
nonceSize := w.Security.NonceSize()
|
2018-11-02 16:34:04 -04:00
|
|
|
common.Must2(bb.ReadFullFrom(rand.Reader, int32(nonceSize)))
|
2018-04-02 16:12:51 -04:00
|
|
|
nonce := bb.BytesFrom(int32(-nonceSize))
|
2018-11-02 16:34:04 -04:00
|
|
|
|
|
|
|
encrypted := bb.Extend(int32(w.Security.Overhead() + len(b)))
|
|
|
|
w.Security.Seal(encrypted[:0], nonce, b, nil)
|
2016-12-08 10:27:41 -05:00
|
|
|
} else {
|
2018-04-19 16:56:55 -04:00
|
|
|
bb.Write(b)
|
2016-12-08 10:27:41 -05:00
|
|
|
}
|
|
|
|
|
2018-04-02 16:12:51 -04:00
|
|
|
_, err := w.Writer.Write(bb.Bytes())
|
2016-12-08 10:27:41 -05:00
|
|
|
return len(b), err
|
|
|
|
}
|