github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/proxy/trojan/protocol.go (about) 1 package trojan 2 3 import ( 4 "encoding/binary" 5 "io" 6 7 "v2ray.com/core/common/buf" 8 "v2ray.com/core/common/net" 9 "v2ray.com/core/common/protocol" 10 ) 11 12 var ( 13 crlf = []byte{'\r', '\n'} 14 15 addrParser = protocol.NewAddressParser( 16 protocol.AddressFamilyByte(0x01, net.AddressFamilyIPv4), // nolint: gomnd 17 protocol.AddressFamilyByte(0x04, net.AddressFamilyIPv6), // nolint: gomnd 18 protocol.AddressFamilyByte(0x03, net.AddressFamilyDomain), // nolint: gomnd 19 ) 20 ) 21 22 const ( 23 maxLength = 8192 24 25 commandTCP byte = 1 26 commandUDP byte = 3 27 ) 28 29 // ConnWriter is TCP Connection Writer Wrapper for trojan protocol 30 type ConnWriter struct { 31 io.Writer 32 Target net.Destination 33 Account *MemoryAccount 34 headerSent bool 35 } 36 37 // Write implements io.Writer 38 func (c *ConnWriter) Write(p []byte) (n int, err error) { 39 if !c.headerSent { 40 if err := c.writeHeader(); err != nil { 41 return 0, newError("failed to write request header").Base(err) 42 } 43 } 44 45 return c.Writer.Write(p) 46 } 47 48 // WriteMultiBuffer implements buf.Writer 49 func (c *ConnWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { 50 defer buf.ReleaseMulti(mb) 51 52 for _, b := range mb { 53 if !b.IsEmpty() { 54 if _, err := c.Write(b.Bytes()); err != nil { 55 return err 56 } 57 } 58 } 59 60 return nil 61 } 62 63 func (c *ConnWriter) writeHeader() error { 64 buffer := buf.StackNew() 65 defer buffer.Release() 66 67 command := commandTCP 68 if c.Target.Network == net.Network_UDP { 69 command = commandUDP 70 } 71 72 if _, err := buffer.Write(c.Account.Key); err != nil { 73 return err 74 } 75 if _, err := buffer.Write(crlf); err != nil { 76 return err 77 } 78 if err := buffer.WriteByte(command); err != nil { 79 return err 80 } 81 if err := addrParser.WriteAddressPort(&buffer, c.Target.Address, c.Target.Port); err != nil { 82 return err 83 } 84 if _, err := buffer.Write(crlf); err != nil { 85 return err 86 } 87 88 _, err := c.Writer.Write(buffer.Bytes()) 89 if err == nil { 90 c.headerSent = true 91 } 92 93 return err 94 } 95 96 // PacketWriter UDP Connection Writer Wrapper for trojan protocol 97 type PacketWriter struct { 98 io.Writer 99 Target net.Destination 100 } 101 102 // WriteMultiBuffer implements buf.Writer 103 func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { 104 b := make([]byte, maxLength) 105 for !mb.IsEmpty() { 106 var length int 107 mb, length = buf.SplitBytes(mb, b) 108 if _, err := w.writePacket(b[:length], w.Target); err != nil { 109 buf.ReleaseMulti(mb) 110 return err 111 } 112 } 113 114 return nil 115 } 116 117 // WriteMultiBufferWithMetadata writes udp packet with destination specified 118 func (w *PacketWriter) WriteMultiBufferWithMetadata(mb buf.MultiBuffer, dest net.Destination) error { 119 b := make([]byte, maxLength) 120 for !mb.IsEmpty() { 121 var length int 122 mb, length = buf.SplitBytes(mb, b) 123 if _, err := w.writePacket(b[:length], dest); err != nil { 124 buf.ReleaseMulti(mb) 125 return err 126 } 127 } 128 129 return nil 130 } 131 132 func (w *PacketWriter) writePacket(payload []byte, dest net.Destination) (int, error) { // nolint: unparam 133 buffer := buf.StackNew() 134 defer buffer.Release() 135 136 length := len(payload) 137 lengthBuf := [2]byte{} 138 binary.BigEndian.PutUint16(lengthBuf[:], uint16(length)) 139 if err := addrParser.WriteAddressPort(&buffer, dest.Address, dest.Port); err != nil { 140 return 0, err 141 } 142 if _, err := buffer.Write(lengthBuf[:]); err != nil { 143 return 0, err 144 } 145 if _, err := buffer.Write(crlf); err != nil { 146 return 0, err 147 } 148 if _, err := buffer.Write(payload); err != nil { 149 return 0, err 150 } 151 _, err := w.Write(buffer.Bytes()) 152 if err != nil { 153 return 0, err 154 } 155 156 return length, nil 157 } 158 159 // ConnReader is TCP Connection Reader Wrapper for trojan protocol 160 type ConnReader struct { 161 io.Reader 162 Target net.Destination 163 headerParsed bool 164 } 165 166 // ParseHeader parses the trojan protocol header 167 func (c *ConnReader) ParseHeader() error { 168 var crlf [2]byte 169 var command [1]byte 170 var hash [56]byte 171 if _, err := io.ReadFull(c.Reader, hash[:]); err != nil { 172 return newError("failed to read user hash").Base(err) 173 } 174 175 if _, err := io.ReadFull(c.Reader, crlf[:]); err != nil { 176 return newError("failed to read crlf").Base(err) 177 } 178 179 if _, err := io.ReadFull(c.Reader, command[:]); err != nil { 180 return newError("failed to read command").Base(err) 181 } 182 183 network := net.Network_TCP 184 if command[0] == commandUDP { 185 network = net.Network_UDP 186 } 187 188 addr, port, err := addrParser.ReadAddressPort(nil, c.Reader) 189 if err != nil { 190 return newError("failed to read address and port").Base(err) 191 } 192 c.Target = net.Destination{Network: network, Address: addr, Port: port} 193 194 if _, err := io.ReadFull(c.Reader, crlf[:]); err != nil { 195 return newError("failed to read crlf").Base(err) 196 } 197 198 c.headerParsed = true 199 return nil 200 } 201 202 // Read implements io.Reader 203 func (c *ConnReader) Read(p []byte) (int, error) { 204 if !c.headerParsed { 205 if err := c.ParseHeader(); err != nil { 206 return 0, err 207 } 208 } 209 210 return c.Reader.Read(p) 211 } 212 213 // ReadMultiBuffer implements buf.Reader 214 func (c *ConnReader) ReadMultiBuffer() (buf.MultiBuffer, error) { 215 b := buf.New() 216 _, err := b.ReadFrom(c) 217 return buf.MultiBuffer{b}, err 218 } 219 220 // PacketPayload combines udp payload and destination 221 type PacketPayload struct { 222 Target net.Destination 223 Buffer buf.MultiBuffer 224 } 225 226 // PacketReader is UDP Connection Reader Wrapper for trojan protocol 227 type PacketReader struct { 228 io.Reader 229 } 230 231 // ReadMultiBuffer implements buf.Reader 232 func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) { 233 p, err := r.ReadMultiBufferWithMetadata() 234 if p != nil { 235 return p.Buffer, err 236 } 237 return nil, err 238 } 239 240 // ReadMultiBufferWithMetadata reads udp packet with destination 241 func (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) { 242 addr, port, err := addrParser.ReadAddressPort(nil, r) 243 if err != nil { 244 return nil, newError("failed to read address and port").Base(err) 245 } 246 247 var lengthBuf [2]byte 248 if _, err := io.ReadFull(r, lengthBuf[:]); err != nil { 249 return nil, newError("failed to read payload length").Base(err) 250 } 251 252 remain := int(binary.BigEndian.Uint16(lengthBuf[:])) 253 if remain > maxLength { 254 return nil, newError("oversize payload") 255 } 256 257 var crlf [2]byte 258 if _, err := io.ReadFull(r, crlf[:]); err != nil { 259 return nil, newError("failed to read crlf").Base(err) 260 } 261 262 dest := net.UDPDestination(addr, port) 263 var mb buf.MultiBuffer 264 for remain > 0 { 265 length := buf.Size 266 if remain < length { 267 length = remain 268 } 269 270 b := buf.New() 271 mb = append(mb, b) 272 n, err := b.ReadFullFrom(r, int32(length)) 273 if err != nil { 274 buf.ReleaseMulti(mb) 275 return nil, newError("failed to read payload").Base(err) 276 } 277 278 remain -= int(n) 279 } 280 281 return &PacketPayload{Target: dest, Buffer: mb}, nil 282 }