| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- package hysteria2
- import (
- "net"
- "github.com/sagernet/sing/common"
- "github.com/sagernet/sing/common/buf"
- "github.com/sagernet/sing/common/bufio"
- E "github.com/sagernet/sing/common/exceptions"
- M "github.com/sagernet/sing/common/metadata"
- N "github.com/sagernet/sing/common/network"
- "golang.org/x/crypto/blake2b"
- )
- const salamanderSaltLen = 8
- const ObfsTypeSalamander = "salamander"
- type Salamander struct {
- net.PacketConn
- password []byte
- }
- func NewSalamanderConn(conn net.PacketConn, password []byte) net.PacketConn {
- writer, isVectorised := bufio.CreateVectorisedPacketWriter(conn)
- if isVectorised {
- return &VectorisedSalamander{
- Salamander: Salamander{
- PacketConn: conn,
- password: password,
- },
- writer: writer,
- }
- } else {
- return &Salamander{
- PacketConn: conn,
- password: password,
- }
- }
- }
- func (s *Salamander) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
- n, addr, err = s.PacketConn.ReadFrom(p)
- if err != nil {
- return
- }
- if n <= salamanderSaltLen {
- return 0, nil, E.New("salamander: packet too short")
- }
- key := blake2b.Sum256(append(s.password, p[:salamanderSaltLen]...))
- for index, c := range p[salamanderSaltLen:n] {
- p[index] = c ^ key[index%blake2b.Size256]
- }
- return n - salamanderSaltLen, addr, nil
- }
- func (s *Salamander) WriteTo(p []byte, addr net.Addr) (n int, err error) {
- buffer := buf.NewSize(len(p) + salamanderSaltLen)
- defer buffer.Release()
- buffer.WriteRandom(salamanderSaltLen)
- key := blake2b.Sum256(append(s.password, buffer.Bytes()...))
- for index, c := range p {
- common.Must(buffer.WriteByte(c ^ key[index%blake2b.Size256]))
- }
- _, err = s.PacketConn.WriteTo(buffer.Bytes(), addr)
- if err != nil {
- return
- }
- return len(p), nil
- }
- type VectorisedSalamander struct {
- Salamander
- writer N.VectorisedPacketWriter
- }
- func (s *VectorisedSalamander) WriteTo(p []byte, addr net.Addr) (n int, err error) {
- buffer := buf.NewSize(salamanderSaltLen)
- buffer.WriteRandom(salamanderSaltLen)
- key := blake2b.Sum256(append(s.password, buffer.Bytes()...))
- for i := range p {
- p[i] ^= key[i%blake2b.Size256]
- }
- err = s.writer.WriteVectorisedPacket([]*buf.Buffer{buffer, buf.As(p)}, M.SocksaddrFromNet(addr))
- if err != nil {
- return
- }
- return len(p), nil
- }
- func (s *VectorisedSalamander) WriteVectorisedPacket(buffers []*buf.Buffer, destination M.Socksaddr) error {
- header := buf.NewSize(salamanderSaltLen)
- defer header.Release()
- header.WriteRandom(salamanderSaltLen)
- key := blake2b.Sum256(append(s.password, header.Bytes()...))
- var bufferIndex int
- for _, buffer := range buffers {
- content := buffer.Bytes()
- for index, c := range content {
- content[bufferIndex+index] = c ^ key[bufferIndex+index%blake2b.Size256]
- }
- bufferIndex += len(content)
- }
- return s.writer.WriteVectorisedPacket(append([]*buf.Buffer{header}, buffers...), destination)
- }
|