mirror of
https://github.com/SagerNet/sing.git
synced 2025-04-04 20:37:40 +03:00
75 lines
1.7 KiB
Go
75 lines
1.7 KiB
Go
package uot
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"io"
|
|
|
|
"github.com/sagernet/sing/common"
|
|
"github.com/sagernet/sing/common/buf"
|
|
M "github.com/sagernet/sing/common/metadata"
|
|
)
|
|
|
|
const (
|
|
Version = 2
|
|
LegacyVersion = 1
|
|
MagicAddress = "sp.v2.udp-over-tcp.arpa"
|
|
LegacyMagicAddress = "sp.udp-over-tcp.arpa"
|
|
)
|
|
|
|
var AddrParser = M.NewSerializer(
|
|
M.AddressFamilyByte(0x00, M.AddressFamilyIPv4),
|
|
M.AddressFamilyByte(0x01, M.AddressFamilyIPv6),
|
|
M.AddressFamilyByte(0x02, M.AddressFamilyFqdn),
|
|
)
|
|
|
|
func RequestDestination(version uint8) M.Socksaddr {
|
|
switch version {
|
|
case 0, Version:
|
|
return M.Socksaddr{Fqdn: MagicAddress}
|
|
default:
|
|
fallthrough
|
|
case LegacyVersion:
|
|
return M.Socksaddr{Fqdn: LegacyMagicAddress}
|
|
}
|
|
}
|
|
|
|
type Request struct {
|
|
IsConnect bool
|
|
Destination M.Socksaddr
|
|
}
|
|
|
|
func ReadRequest(reader io.Reader) (*Request, error) {
|
|
var request Request
|
|
err := binary.Read(reader, binary.BigEndian, &request.IsConnect)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
request.Destination, err = M.SocksaddrSerializer.ReadAddrPort(reader)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &request, nil
|
|
}
|
|
|
|
func EncodeRequest(request Request) (*buf.Buffer, error) {
|
|
var bufferLen int
|
|
bufferLen += 1 // isConnect
|
|
bufferLen += M.SocksaddrSerializer.AddrPortLen(request.Destination)
|
|
buffer := buf.NewSize(bufferLen)
|
|
common.Must(binary.Write(buffer, binary.BigEndian, request.IsConnect))
|
|
err := M.SocksaddrSerializer.WriteAddrPort(buffer, request.Destination)
|
|
if err != nil {
|
|
buffer.Release()
|
|
return nil, err
|
|
}
|
|
return buffer, nil
|
|
}
|
|
|
|
func WriteRequest(writer io.Writer, request Request) error {
|
|
buffer, err := EncodeRequest(request)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer buffer.Release()
|
|
return common.Error(writer.Write(buffer.Bytes()))
|
|
}
|