LjhAUMEM
2026-05-29 19:48:22 +08:00
committed by RPRX
parent 569459c54c
commit aba22722a6
38 changed files with 499 additions and 1484 deletions
@@ -0,0 +1,17 @@
package header
import (
"net"
)
func (c *Config) UDP() {}
func (c *Config) HeaderConn() {}
func (c *Config) WrapPacketConnClient(raw net.PacketConn, level int, levelCount int) (net.PacketConn, error) {
return NewConnClient(c, raw)
}
func (c *Config) WrapPacketConnServer(raw net.PacketConn, level int, levelCount int) (net.PacketConn, error) {
return NewConnServer(c, raw)
}
@@ -0,0 +1,132 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.11
// protoc v6.33.5
// source: transport/internet/finalmask/mkcp/header/config.proto
package header
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type Config struct {
state protoimpl.MessageState `protogen:"open.v1"`
ID int32 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
Domain string `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Config) Reset() {
*x = Config{}
mi := &file_transport_internet_finalmask_mkcp_header_config_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Config) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message {
mi := &file_transport_internet_finalmask_mkcp_header_config_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Config.ProtoReflect.Descriptor instead.
func (*Config) Descriptor() ([]byte, []int) {
return file_transport_internet_finalmask_mkcp_header_config_proto_rawDescGZIP(), []int{0}
}
func (x *Config) GetID() int32 {
if x != nil {
return x.ID
}
return 0
}
func (x *Config) GetDomain() string {
if x != nil {
return x.Domain
}
return ""
}
var File_transport_internet_finalmask_mkcp_header_config_proto protoreflect.FileDescriptor
const file_transport_internet_finalmask_mkcp_header_config_proto_rawDesc = "" +
"\n" +
"5transport/internet/finalmask/mkcp/header/config.proto\x12-xray.transport.internet.finalmask.mkcp.header\"0\n" +
"\x06Config\x12\x0e\n" +
"\x02ID\x18\x01 \x01(\x05R\x02ID\x12\x16\n" +
"\x06domain\x18\x02 \x01(\tR\x06domainB\xa9\x01\n" +
"1com.xray.transport.internet.finalmask.mkcp.headerP\x01ZBgithub.com/xtls/xray-core/transport/internet/finalmask/mkcp/header\xaa\x02-Xray.Transport.Internet.Finalmask.Mkcp.Headerb\x06proto3"
var (
file_transport_internet_finalmask_mkcp_header_config_proto_rawDescOnce sync.Once
file_transport_internet_finalmask_mkcp_header_config_proto_rawDescData []byte
)
func file_transport_internet_finalmask_mkcp_header_config_proto_rawDescGZIP() []byte {
file_transport_internet_finalmask_mkcp_header_config_proto_rawDescOnce.Do(func() {
file_transport_internet_finalmask_mkcp_header_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_finalmask_mkcp_header_config_proto_rawDesc), len(file_transport_internet_finalmask_mkcp_header_config_proto_rawDesc)))
})
return file_transport_internet_finalmask_mkcp_header_config_proto_rawDescData
}
var file_transport_internet_finalmask_mkcp_header_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_transport_internet_finalmask_mkcp_header_config_proto_goTypes = []any{
(*Config)(nil), // 0: xray.transport.internet.finalmask.mkcp.header.Config
}
var file_transport_internet_finalmask_mkcp_header_config_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_transport_internet_finalmask_mkcp_header_config_proto_init() }
func file_transport_internet_finalmask_mkcp_header_config_proto_init() {
if File_transport_internet_finalmask_mkcp_header_config_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_transport_internet_finalmask_mkcp_header_config_proto_rawDesc), len(file_transport_internet_finalmask_mkcp_header_config_proto_rawDesc)),
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_transport_internet_finalmask_mkcp_header_config_proto_goTypes,
DependencyIndexes: file_transport_internet_finalmask_mkcp_header_config_proto_depIdxs,
MessageInfos: file_transport_internet_finalmask_mkcp_header_config_proto_msgTypes,
}.Build()
File_transport_internet_finalmask_mkcp_header_config_proto = out.File
file_transport_internet_finalmask_mkcp_header_config_proto_goTypes = nil
file_transport_internet_finalmask_mkcp_header_config_proto_depIdxs = nil
}
@@ -0,0 +1,12 @@
syntax = "proto3";
package xray.transport.internet.finalmask.mkcp.header;
option csharp_namespace = "Xray.Transport.Internet.Finalmask.Mkcp.Header";
option go_package = "github.com/xtls/xray-core/transport/internet/finalmask/mkcp/header";
option java_package = "com.xray.transport.internet.finalmask.mkcp.header";
option java_multiple_files = true;
message Config {
int32 ID = 1;
string domain = 2;
}
@@ -0,0 +1,57 @@
package header
import (
"net"
"github.com/xtls/xray-core/common/errors"
)
type headerConn struct {
net.PacketConn
header Header
}
func NewConnClient(c *Config, raw net.PacketConn) (net.PacketConn, error) {
var header Header
switch HeaderID(c.ID) {
case DNS:
var err error
header, err = NewHeaderDNS(c.Domain)
if err != nil {
return nil, err
}
case DTLS:
header = &dtls{}
case SRTP:
header = &srtp{}
case UTP:
header = &utp{}
case WECHAT:
header = &wechat{}
case WIREGUARD:
header = &wireguard{}
default:
return nil, errors.New("invalid id ", c.ID)
}
return &headerConn{
PacketConn: raw,
header: header,
}, nil
}
func NewConnServer(c *Config, raw net.PacketConn) (net.PacketConn, error) {
return NewConnClient(c, raw)
}
func (c *headerConn) Size() int {
return c.header.Size()
}
func (c *headerConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
return len(p) - c.header.Size(), nil, nil
}
func (c *headerConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
c.header.Serialize(p)
return len(p), nil
}
@@ -0,0 +1,17 @@
package header
type Header interface {
Size() int
Serialize(b []byte)
}
type HeaderID int
const (
DNS HeaderID = iota
DTLS
SRTP
UTP
WECHAT
WIREGUARD
)
@@ -0,0 +1,106 @@
package header
import (
"encoding/binary"
"errors"
"github.com/xtls/xray-core/common/dice"
)
type dns struct {
header []byte
}
func (h *dns) Size() int {
return len(h.header)
}
func (h *dns) Serialize(b []byte) {
copy(b, h.header)
binary.BigEndian.PutUint16(b[0:], dice.RollUint16())
}
func NewHeaderDNS(domain string) (*dns, error) {
var header []byte
header = binary.BigEndian.AppendUint16(header, 0x0000) // Transaction ID
header = binary.BigEndian.AppendUint16(header, 0x0100) // Flags: Standard query
header = binary.BigEndian.AppendUint16(header, 0x0001) // Questions
header = binary.BigEndian.AppendUint16(header, 0x0000) // Answer RRs
header = binary.BigEndian.AppendUint16(header, 0x0000) // Authority RRs
header = binary.BigEndian.AppendUint16(header, 0x0000) // Additional RRs
buf := make([]byte, 0x100)
off1, err := packDomainName(domain+".", buf)
if err != nil {
return nil, err
}
header = append(header, buf[:off1]...)
header = binary.BigEndian.AppendUint16(header, 0x0001) // Type: A
header = binary.BigEndian.AppendUint16(header, 0x0001) // Class: IN
return &dns{header: header}, nil
}
func packDomainName(s string, msg []byte) (off1 int, err error) {
off := 0
ls := len(s)
// Each dot ends a segment of the name.
// We trade each dot byte for a length byte.
// Except for escaped dots (\.), which are normal dots.
// There is also a trailing zero.
// Emit sequence of counted strings, chopping at dots.
var (
begin int
bs []byte
)
for i := 0; i < ls; i++ {
var c byte
if bs == nil {
c = s[i]
} else {
c = bs[i]
}
switch c {
case '\\':
if off+1 > len(msg) {
return len(msg), errors.New("buffer size too small")
}
if bs == nil {
bs = []byte(s)
}
copy(bs[i:ls-1], bs[i+1:])
ls--
case '.':
labelLen := i - begin
if labelLen >= 1<<6 { // top two bits of length must be clear
return len(msg), errors.New("bad rdata")
}
// off can already (we're in a loop) be bigger than len(msg)
// this happens when a name isn't fully qualified
if off+1+labelLen > len(msg) {
return len(msg), errors.New("buffer size too small")
}
// The following is covered by the length check above.
msg[off] = byte(labelLen)
if bs == nil {
copy(msg[off+1:], s[begin:i])
} else {
copy(msg[off+1:], bs[begin:i])
}
off += 1 + labelLen
begin = i + 1
default:
}
}
if off < len(msg) {
msg[off] = 0
}
return off + 1, nil
}
@@ -0,0 +1,32 @@
package header
type dtls struct {
epoch uint16
length uint16
sequence uint32
}
func (*dtls) Size() int {
return 1 + 2 + 2 + 6 + 2
}
func (h *dtls) Serialize(b []byte) {
b[0] = 23
b[1] = 254
b[2] = 253
b[3] = byte(h.epoch >> 8)
b[4] = byte(h.epoch)
b[5] = 0
b[6] = 0
b[7] = byte(h.sequence >> 24)
b[8] = byte(h.sequence >> 16)
b[9] = byte(h.sequence >> 8)
b[10] = byte(h.sequence)
h.sequence++
b[11] = byte(h.length >> 8)
b[12] = byte(h.length)
h.length += 17
if h.length > 100 {
h.length -= 50
}
}
@@ -0,0 +1,18 @@
package header
import "encoding/binary"
type srtp struct {
header uint16
number uint16
}
func (*srtp) Size() int {
return 4
}
func (h *srtp) Serialize(b []byte) {
h.number++
binary.BigEndian.PutUint16(b, h.header)
binary.BigEndian.PutUint16(b[2:], h.number)
}
@@ -0,0 +1,19 @@
package header
import "encoding/binary"
type utp struct {
header byte
extension byte
connectionID uint16
}
func (*utp) Size() int {
return 4
}
func (h *utp) Serialize(b []byte) {
binary.BigEndian.PutUint16(b, h.connectionID)
b[2] = h.header
b[3] = h.extension
}
@@ -0,0 +1,25 @@
package header
import "encoding/binary"
type wechat struct {
sn uint32
}
func (*wechat) Size() int {
return 13
}
func (h *wechat) Serialize(b []byte) {
h.sn++
b[0] = 0xa1
b[1] = 0x08
binary.BigEndian.PutUint32(b[2:], h.sn)
b[6] = 0x00
b[7] = 0x10
b[8] = 0x11
b[9] = 0x18
b[10] = 0x30
b[11] = 0x22
b[12] = 0x30
}
@@ -0,0 +1,14 @@
package header
type wireguard struct{}
func (*wireguard) Size() int {
return 4
}
func (h *wireguard) Serialize(b []byte) {
b[0] = 0x04
b[1] = 0x00
b[2] = 0x00
b[3] = 0x00
}