encoding.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. package encoding
  2. //go:generate go run github.com/xtls/xray-core/common/errors/errorgen
  3. import (
  4. "bytes"
  5. "context"
  6. "crypto/rand"
  7. "fmt"
  8. "io"
  9. "math/big"
  10. "runtime"
  11. "strconv"
  12. "syscall"
  13. "time"
  14. "github.com/xtls/xray-core/common/buf"
  15. "github.com/xtls/xray-core/common/errors"
  16. "github.com/xtls/xray-core/common/net"
  17. "github.com/xtls/xray-core/common/protocol"
  18. "github.com/xtls/xray-core/common/session"
  19. "github.com/xtls/xray-core/common/signal"
  20. "github.com/xtls/xray-core/features/stats"
  21. "github.com/xtls/xray-core/proxy/vless"
  22. "github.com/xtls/xray-core/transport/internet/stat"
  23. "github.com/xtls/xray-core/transport/internet/tls"
  24. "github.com/xtls/xray-core/transport/internet/xtls"
  25. )
  26. const (
  27. Version = byte(0)
  28. )
  29. var (
  30. tls13SupportedVersions = []byte{0x00, 0x2b, 0x00, 0x02, 0x03, 0x04}
  31. tlsClientHandShakeStart = []byte{0x16, 0x03}
  32. tlsServerHandShakeStart = []byte{0x16, 0x03, 0x03}
  33. tlsApplicationDataStart = []byte{0x17, 0x03, 0x03}
  34. Tls13CipherSuiteDic = map[uint16]string{
  35. 0x1301: "TLS_AES_128_GCM_SHA256",
  36. 0x1302: "TLS_AES_256_GCM_SHA384",
  37. 0x1303: "TLS_CHACHA20_POLY1305_SHA256",
  38. 0x1304: "TLS_AES_128_CCM_SHA256",
  39. 0x1305: "TLS_AES_128_CCM_8_SHA256",
  40. }
  41. )
  42. const (
  43. tlsHandshakeTypeClientHello byte = 0x01
  44. tlsHandshakeTypeServerHello byte = 0x02
  45. CommandPaddingContinue byte = 0x00
  46. CommandPaddingEnd byte = 0x01
  47. CommandPaddingDirect byte = 0x02
  48. )
  49. var addrParser = protocol.NewAddressParser(
  50. protocol.AddressFamilyByte(byte(protocol.AddressTypeIPv4), net.AddressFamilyIPv4),
  51. protocol.AddressFamilyByte(byte(protocol.AddressTypeDomain), net.AddressFamilyDomain),
  52. protocol.AddressFamilyByte(byte(protocol.AddressTypeIPv6), net.AddressFamilyIPv6),
  53. protocol.PortThenAddress(),
  54. )
  55. // EncodeRequestHeader writes encoded request header into the given writer.
  56. func EncodeRequestHeader(writer io.Writer, request *protocol.RequestHeader, requestAddons *Addons) error {
  57. buffer := buf.StackNew()
  58. defer buffer.Release()
  59. if err := buffer.WriteByte(request.Version); err != nil {
  60. return newError("failed to write request version").Base(err)
  61. }
  62. if _, err := buffer.Write(request.User.Account.(*vless.MemoryAccount).ID.Bytes()); err != nil {
  63. return newError("failed to write request user id").Base(err)
  64. }
  65. if err := EncodeHeaderAddons(&buffer, requestAddons); err != nil {
  66. return newError("failed to encode request header addons").Base(err)
  67. }
  68. if err := buffer.WriteByte(byte(request.Command)); err != nil {
  69. return newError("failed to write request command").Base(err)
  70. }
  71. if request.Command != protocol.RequestCommandMux {
  72. if err := addrParser.WriteAddressPort(&buffer, request.Address, request.Port); err != nil {
  73. return newError("failed to write request address and port").Base(err)
  74. }
  75. }
  76. if _, err := writer.Write(buffer.Bytes()); err != nil {
  77. return newError("failed to write request header").Base(err)
  78. }
  79. return nil
  80. }
  81. // DecodeRequestHeader decodes and returns (if successful) a RequestHeader from an input stream.
  82. func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validator *vless.Validator) (*protocol.RequestHeader, *Addons, bool, error) {
  83. buffer := buf.StackNew()
  84. defer buffer.Release()
  85. request := new(protocol.RequestHeader)
  86. if isfb {
  87. request.Version = first.Byte(0)
  88. } else {
  89. if _, err := buffer.ReadFullFrom(reader, 1); err != nil {
  90. return nil, nil, false, newError("failed to read request version").Base(err)
  91. }
  92. request.Version = buffer.Byte(0)
  93. }
  94. switch request.Version {
  95. case 0:
  96. var id [16]byte
  97. if isfb {
  98. copy(id[:], first.BytesRange(1, 17))
  99. } else {
  100. buffer.Clear()
  101. if _, err := buffer.ReadFullFrom(reader, 16); err != nil {
  102. return nil, nil, false, newError("failed to read request user id").Base(err)
  103. }
  104. copy(id[:], buffer.Bytes())
  105. }
  106. if request.User = validator.Get(id); request.User == nil {
  107. return nil, nil, isfb, newError("invalid request user id")
  108. }
  109. if isfb {
  110. first.Advance(17)
  111. }
  112. requestAddons, err := DecodeHeaderAddons(&buffer, reader)
  113. if err != nil {
  114. return nil, nil, false, newError("failed to decode request header addons").Base(err)
  115. }
  116. buffer.Clear()
  117. if _, err := buffer.ReadFullFrom(reader, 1); err != nil {
  118. return nil, nil, false, newError("failed to read request command").Base(err)
  119. }
  120. request.Command = protocol.RequestCommand(buffer.Byte(0))
  121. switch request.Command {
  122. case protocol.RequestCommandMux:
  123. request.Address = net.DomainAddress("v1.mux.cool")
  124. request.Port = 0
  125. case protocol.RequestCommandTCP, protocol.RequestCommandUDP:
  126. if addr, port, err := addrParser.ReadAddressPort(&buffer, reader); err == nil {
  127. request.Address = addr
  128. request.Port = port
  129. }
  130. }
  131. if request.Address == nil {
  132. return nil, nil, false, newError("invalid request address")
  133. }
  134. return request, requestAddons, false, nil
  135. default:
  136. return nil, nil, isfb, newError("invalid request version")
  137. }
  138. }
  139. // EncodeResponseHeader writes encoded response header into the given writer.
  140. func EncodeResponseHeader(writer io.Writer, request *protocol.RequestHeader, responseAddons *Addons) error {
  141. buffer := buf.StackNew()
  142. defer buffer.Release()
  143. if err := buffer.WriteByte(request.Version); err != nil {
  144. return newError("failed to write response version").Base(err)
  145. }
  146. if err := EncodeHeaderAddons(&buffer, responseAddons); err != nil {
  147. return newError("failed to encode response header addons").Base(err)
  148. }
  149. if _, err := writer.Write(buffer.Bytes()); err != nil {
  150. return newError("failed to write response header").Base(err)
  151. }
  152. return nil
  153. }
  154. // DecodeResponseHeader decodes and returns (if successful) a ResponseHeader from an input stream.
  155. func DecodeResponseHeader(reader io.Reader, request *protocol.RequestHeader) (*Addons, error) {
  156. buffer := buf.StackNew()
  157. defer buffer.Release()
  158. if _, err := buffer.ReadFullFrom(reader, 1); err != nil {
  159. return nil, newError("failed to read response version").Base(err)
  160. }
  161. if buffer.Byte(0) != request.Version {
  162. return nil, newError("unexpected response version. Expecting ", int(request.Version), " but actually ", int(buffer.Byte(0)))
  163. }
  164. responseAddons, err := DecodeHeaderAddons(&buffer, reader)
  165. if err != nil {
  166. return nil, newError("failed to decode response header addons").Base(err)
  167. }
  168. return responseAddons, nil
  169. }
  170. func ReadV(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn *xtls.Conn, rawConn syscall.RawConn, counter stats.Counter, ctx context.Context) error {
  171. err := func() error {
  172. var ct stats.Counter
  173. for {
  174. if conn.DirectIn {
  175. conn.DirectIn = false
  176. if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil {
  177. iConn := inbound.Conn
  178. statConn, ok := iConn.(*stat.CounterConnection)
  179. if ok {
  180. iConn = statConn.Connection
  181. }
  182. if xc, ok := iConn.(*xtls.Conn); ok {
  183. iConn = xc.NetConn()
  184. }
  185. if tc, ok := iConn.(*net.TCPConn); ok {
  186. if conn.SHOW {
  187. fmt.Println(conn.MARK, "Splice")
  188. }
  189. runtime.Gosched() // necessary
  190. w, err := tc.ReadFrom(conn.NetConn())
  191. if counter != nil {
  192. counter.Add(w)
  193. }
  194. if statConn != nil && statConn.WriteCounter != nil {
  195. statConn.WriteCounter.Add(w)
  196. }
  197. return err
  198. } else {
  199. panic("XTLS Splice: not TCP inbound")
  200. }
  201. }
  202. reader = buf.NewReadVReader(conn.NetConn(), rawConn, nil)
  203. ct = counter
  204. if conn.SHOW {
  205. fmt.Println(conn.MARK, "ReadV")
  206. }
  207. }
  208. buffer, err := reader.ReadMultiBuffer()
  209. if !buffer.IsEmpty() {
  210. if ct != nil {
  211. ct.Add(int64(buffer.Len()))
  212. }
  213. timer.Update()
  214. if werr := writer.WriteMultiBuffer(buffer); werr != nil {
  215. return werr
  216. }
  217. }
  218. if err != nil {
  219. return err
  220. }
  221. }
  222. }()
  223. if err != nil && errors.Cause(err) != io.EOF {
  224. return err
  225. }
  226. return nil
  227. }
  228. // XtlsRead filter and read xtls protocol
  229. func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, rawConn syscall.RawConn,
  230. input *bytes.Reader, rawInput *bytes.Buffer,
  231. counter stats.Counter, ctx context.Context, userUUID []byte, numberOfPacketToFilter *int, enableXtls *bool,
  232. isTLS12orAbove *bool, isTLS *bool, cipher *uint16, remainingServerHello *int32,
  233. ) error {
  234. err := func() error {
  235. var ct stats.Counter
  236. withinPaddingBuffers := true
  237. shouldSwitchToDirectCopy := false
  238. var remainingContent int32 = -1
  239. var remainingPadding int32 = -1
  240. currentCommand := 0
  241. for {
  242. if shouldSwitchToDirectCopy {
  243. shouldSwitchToDirectCopy = false
  244. if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil && (runtime.GOOS == "linux" || runtime.GOOS == "android") {
  245. if _, ok := inbound.User.Account.(*vless.MemoryAccount); inbound.User.Account == nil || ok {
  246. iConn := inbound.Conn
  247. statConn, ok := iConn.(*stat.CounterConnection)
  248. if ok {
  249. iConn = statConn.Connection
  250. }
  251. if xc, ok := iConn.(*tls.Conn); ok {
  252. iConn = xc.NetConn()
  253. }
  254. if tc, ok := iConn.(*net.TCPConn); ok {
  255. newError("XtlsRead splice").WriteToLog(session.ExportIDToError(ctx))
  256. runtime.Gosched() // necessary
  257. w, err := tc.ReadFrom(conn)
  258. if counter != nil {
  259. counter.Add(w)
  260. }
  261. if statConn != nil && statConn.WriteCounter != nil {
  262. statConn.WriteCounter.Add(w)
  263. }
  264. return err
  265. }
  266. }
  267. }
  268. reader = buf.NewReadVReader(conn, rawConn, nil)
  269. ct = counter
  270. newError("XtlsRead readV").WriteToLog(session.ExportIDToError(ctx))
  271. }
  272. buffer, err := reader.ReadMultiBuffer()
  273. if !buffer.IsEmpty() {
  274. if withinPaddingBuffers || *numberOfPacketToFilter > 0 {
  275. buffer = XtlsUnpadding(ctx, buffer, userUUID, &remainingContent, &remainingPadding, &currentCommand)
  276. if remainingContent == 0 && remainingPadding == 0 {
  277. if currentCommand == 1 {
  278. withinPaddingBuffers = false
  279. remainingContent = -1
  280. remainingPadding = -1 // set to initial state to parse the next padding
  281. } else if currentCommand == 2 {
  282. withinPaddingBuffers = false
  283. shouldSwitchToDirectCopy = true
  284. // XTLS Vision processes struct TLS Conn's input and rawInput
  285. if inputBuffer, err := buf.ReadFrom(input); err == nil {
  286. if !inputBuffer.IsEmpty() {
  287. buffer, _ = buf.MergeMulti(buffer, inputBuffer)
  288. }
  289. }
  290. if rawInputBuffer, err := buf.ReadFrom(rawInput); err == nil {
  291. if !rawInputBuffer.IsEmpty() {
  292. buffer, _ = buf.MergeMulti(buffer, rawInputBuffer)
  293. }
  294. }
  295. } else if currentCommand == 0 {
  296. withinPaddingBuffers = true
  297. } else {
  298. newError("XtlsRead unknown command ", currentCommand, buffer.Len()).WriteToLog(session.ExportIDToError(ctx))
  299. }
  300. } else if remainingContent > 0 || remainingPadding > 0 {
  301. withinPaddingBuffers = true
  302. } else {
  303. withinPaddingBuffers = false
  304. }
  305. }
  306. if *numberOfPacketToFilter > 0 {
  307. XtlsFilterTls(buffer, numberOfPacketToFilter, enableXtls, isTLS12orAbove, isTLS, cipher, remainingServerHello, ctx)
  308. }
  309. if ct != nil {
  310. ct.Add(int64(buffer.Len()))
  311. }
  312. timer.Update()
  313. if werr := writer.WriteMultiBuffer(buffer); werr != nil {
  314. return werr
  315. }
  316. }
  317. if err != nil {
  318. return err
  319. }
  320. }
  321. }()
  322. if err != nil && errors.Cause(err) != io.EOF {
  323. return err
  324. }
  325. return nil
  326. }
  327. // XtlsWrite filter and write xtls protocol
  328. func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, counter stats.Counter,
  329. ctx context.Context, numberOfPacketToFilter *int, enableXtls *bool, isTLS12orAbove *bool, isTLS *bool,
  330. cipher *uint16, remainingServerHello *int32,
  331. ) error {
  332. err := func() error {
  333. var ct stats.Counter
  334. isPadding := true
  335. shouldSwitchToDirectCopy := false
  336. for {
  337. buffer, err := reader.ReadMultiBuffer()
  338. if !buffer.IsEmpty() {
  339. if *numberOfPacketToFilter > 0 {
  340. XtlsFilterTls(buffer, numberOfPacketToFilter, enableXtls, isTLS12orAbove, isTLS, cipher, remainingServerHello, ctx)
  341. }
  342. if isPadding {
  343. buffer = ReshapeMultiBuffer(ctx, buffer)
  344. var xtlsSpecIndex int
  345. for i, b := range buffer {
  346. if *isTLS && b.Len() >= 6 && bytes.Equal(tlsApplicationDataStart, b.BytesTo(3)) {
  347. var command byte = CommandPaddingEnd
  348. if *enableXtls {
  349. shouldSwitchToDirectCopy = true
  350. xtlsSpecIndex = i
  351. command = CommandPaddingDirect
  352. }
  353. isPadding = false
  354. buffer[i] = XtlsPadding(b, command, nil, *isTLS, ctx)
  355. break
  356. } else if !*isTLS12orAbove && *numberOfPacketToFilter <= 1 { // For compatibility with earlier vision receiver, we finish padding 1 packet early
  357. isPadding = false
  358. buffer[i] = XtlsPadding(b, CommandPaddingEnd, nil, *isTLS, ctx)
  359. break
  360. }
  361. buffer[i] = XtlsPadding(b, CommandPaddingContinue, nil, *isTLS, ctx)
  362. }
  363. if shouldSwitchToDirectCopy {
  364. encryptBuffer, directBuffer := buf.SplitMulti(buffer, xtlsSpecIndex+1)
  365. length := encryptBuffer.Len()
  366. if !encryptBuffer.IsEmpty() {
  367. timer.Update()
  368. if werr := writer.WriteMultiBuffer(encryptBuffer); werr != nil {
  369. return werr
  370. }
  371. }
  372. buffer = directBuffer
  373. writer = buf.NewWriter(conn)
  374. ct = counter
  375. newError("XtlsWrite writeV ", xtlsSpecIndex, " ", length, " ", buffer.Len()).WriteToLog(session.ExportIDToError(ctx))
  376. time.Sleep(5 * time.Millisecond) // for some device, the first xtls direct packet fails without this delay
  377. }
  378. }
  379. if !buffer.IsEmpty() {
  380. if ct != nil {
  381. ct.Add(int64(buffer.Len()))
  382. }
  383. timer.Update()
  384. if werr := writer.WriteMultiBuffer(buffer); werr != nil {
  385. return werr
  386. }
  387. }
  388. }
  389. if err != nil {
  390. return err
  391. }
  392. }
  393. }()
  394. if err != nil && errors.Cause(err) != io.EOF {
  395. return err
  396. }
  397. return nil
  398. }
  399. // XtlsFilterTls filter and recognize tls 1.3 and other info
  400. func XtlsFilterTls(buffer buf.MultiBuffer, numberOfPacketToFilter *int, enableXtls *bool, isTLS12orAbove *bool, isTLS *bool,
  401. cipher *uint16, remainingServerHello *int32, ctx context.Context,
  402. ) {
  403. for _, b := range buffer {
  404. *numberOfPacketToFilter--
  405. if b.Len() >= 6 {
  406. startsBytes := b.BytesTo(6)
  407. if bytes.Equal(tlsServerHandShakeStart, startsBytes[:3]) && startsBytes[5] == tlsHandshakeTypeServerHello {
  408. *remainingServerHello = (int32(startsBytes[3])<<8 | int32(startsBytes[4])) + 5
  409. *isTLS12orAbove = true
  410. *isTLS = true
  411. if b.Len() >= 79 && *remainingServerHello >= 79 {
  412. sessionIdLen := int32(b.Byte(43))
  413. cipherSuite := b.BytesRange(43+sessionIdLen+1, 43+sessionIdLen+3)
  414. *cipher = uint16(cipherSuite[0])<<8 | uint16(cipherSuite[1])
  415. } else {
  416. newError("XtlsFilterTls short server hello, tls 1.2 or older? ", b.Len(), " ", *remainingServerHello).WriteToLog(session.ExportIDToError(ctx))
  417. }
  418. } else if bytes.Equal(tlsClientHandShakeStart, startsBytes[:2]) && startsBytes[5] == tlsHandshakeTypeClientHello {
  419. *isTLS = true
  420. newError("XtlsFilterTls found tls client hello! ", buffer.Len()).WriteToLog(session.ExportIDToError(ctx))
  421. }
  422. }
  423. if *remainingServerHello > 0 {
  424. end := *remainingServerHello
  425. if end > b.Len() {
  426. end = b.Len()
  427. }
  428. *remainingServerHello -= b.Len()
  429. if bytes.Contains(b.BytesTo(end), tls13SupportedVersions) {
  430. v, ok := Tls13CipherSuiteDic[*cipher]
  431. if !ok {
  432. v = "Old cipher: " + strconv.FormatUint(uint64(*cipher), 16)
  433. } else if v != "TLS_AES_128_CCM_8_SHA256" {
  434. *enableXtls = true
  435. }
  436. newError("XtlsFilterTls found tls 1.3! ", b.Len(), " ", v).WriteToLog(session.ExportIDToError(ctx))
  437. *numberOfPacketToFilter = 0
  438. return
  439. } else if *remainingServerHello <= 0 {
  440. newError("XtlsFilterTls found tls 1.2! ", b.Len()).WriteToLog(session.ExportIDToError(ctx))
  441. *numberOfPacketToFilter = 0
  442. return
  443. }
  444. newError("XtlsFilterTls inconclusive server hello ", b.Len(), " ", *remainingServerHello).WriteToLog(session.ExportIDToError(ctx))
  445. }
  446. if *numberOfPacketToFilter <= 0 {
  447. newError("XtlsFilterTls stop filtering", buffer.Len()).WriteToLog(session.ExportIDToError(ctx))
  448. }
  449. }
  450. }
  451. // ReshapeMultiBuffer prepare multi buffer for padding stucture (max 21 bytes)
  452. func ReshapeMultiBuffer(ctx context.Context, buffer buf.MultiBuffer) buf.MultiBuffer {
  453. needReshape := 0
  454. for _, b := range buffer {
  455. if b.Len() >= buf.Size-21 {
  456. needReshape += 1
  457. }
  458. }
  459. if needReshape == 0 {
  460. return buffer
  461. }
  462. mb2 := make(buf.MultiBuffer, 0, len(buffer)+needReshape)
  463. toPrint := ""
  464. for i, buffer1 := range buffer {
  465. if buffer1.Len() >= buf.Size-21 {
  466. index := int32(bytes.LastIndex(buffer1.Bytes(), tlsApplicationDataStart))
  467. if index <= 0 || index > buf.Size-21 {
  468. index = buf.Size / 2
  469. }
  470. buffer2 := buf.New()
  471. buffer2.Write(buffer1.BytesFrom(index))
  472. buffer1.Resize(0, index)
  473. mb2 = append(mb2, buffer1, buffer2)
  474. toPrint += " " + strconv.Itoa(int(buffer1.Len())) + " " + strconv.Itoa(int(buffer2.Len()))
  475. } else {
  476. mb2 = append(mb2, buffer1)
  477. toPrint += " " + strconv.Itoa(int(buffer1.Len()))
  478. }
  479. buffer[i] = nil
  480. }
  481. buffer = buffer[:0]
  482. newError("ReshapeMultiBuffer ", toPrint).WriteToLog(session.ExportIDToError(ctx))
  483. return mb2
  484. }
  485. // XtlsPadding add padding to eliminate length siganature during tls handshake
  486. func XtlsPadding(b *buf.Buffer, command byte, userUUID *[]byte, longPadding bool, ctx context.Context) *buf.Buffer {
  487. var contantLen int32 = 0
  488. var paddingLen int32 = 0
  489. if b != nil {
  490. contantLen = b.Len()
  491. }
  492. if contantLen < 900 && longPadding {
  493. l, err := rand.Int(rand.Reader, big.NewInt(500))
  494. if err != nil {
  495. newError("failed to generate padding").Base(err).WriteToLog(session.ExportIDToError(ctx))
  496. }
  497. paddingLen = int32(l.Int64()) + 900 - contantLen
  498. } else {
  499. l, err := rand.Int(rand.Reader, big.NewInt(256))
  500. if err != nil {
  501. newError("failed to generate padding").Base(err).WriteToLog(session.ExportIDToError(ctx))
  502. }
  503. paddingLen = int32(l.Int64())
  504. }
  505. newbuffer := buf.New()
  506. if userUUID != nil {
  507. newbuffer.Write(*userUUID)
  508. }
  509. newbuffer.Write([]byte{command, byte(contantLen >> 8), byte(contantLen), byte(paddingLen >> 8), byte(paddingLen)})
  510. if b != nil {
  511. newbuffer.Write(b.Bytes())
  512. b.Release()
  513. b = nil
  514. }
  515. newbuffer.Extend(paddingLen)
  516. newError("XtlsPadding ", contantLen, " ", paddingLen, " ", command).WriteToLog(session.ExportIDToError(ctx))
  517. return newbuffer
  518. }
  519. // XtlsUnpadding remove padding and parse command
  520. func XtlsUnpadding(ctx context.Context, buffer buf.MultiBuffer, userUUID []byte, remainingContent *int32, remainingPadding *int32, currentCommand *int) buf.MultiBuffer {
  521. posindex := 0
  522. var posByte int32 = 0
  523. if *remainingContent == -1 && *remainingPadding == -1 {
  524. for i, b := range buffer {
  525. if b.Len() >= 21 && bytes.Equal(userUUID, b.BytesTo(16)) {
  526. posindex = i
  527. posByte = 16
  528. *remainingContent = 0
  529. *remainingPadding = 0
  530. *currentCommand = 0
  531. break
  532. }
  533. }
  534. }
  535. if *remainingContent == -1 && *remainingPadding == -1 {
  536. return buffer
  537. }
  538. mb2 := make(buf.MultiBuffer, 0, len(buffer))
  539. for i := 0; i < posindex; i++ {
  540. newbuffer := buf.New()
  541. newbuffer.Write(buffer[i].Bytes())
  542. mb2 = append(mb2, newbuffer)
  543. }
  544. for i := posindex; i < len(buffer); i++ {
  545. b := buffer[i]
  546. for posByte < b.Len() {
  547. if *remainingContent <= 0 && *remainingPadding <= 0 {
  548. if *currentCommand == 1 { // possible buffer after padding, no need to worry about xtls (command 2)
  549. len := b.Len() - posByte
  550. newbuffer := buf.New()
  551. newbuffer.Write(b.BytesRange(posByte, posByte+len))
  552. mb2 = append(mb2, newbuffer)
  553. posByte += len
  554. } else {
  555. paddingInfo := b.BytesRange(posByte, posByte+5)
  556. *currentCommand = int(paddingInfo[0])
  557. *remainingContent = int32(paddingInfo[1])<<8 | int32(paddingInfo[2])
  558. *remainingPadding = int32(paddingInfo[3])<<8 | int32(paddingInfo[4])
  559. newError("Xtls Unpadding new block", i, " ", posByte, " content ", *remainingContent, " padding ", *remainingPadding, " ", paddingInfo[0]).WriteToLog(session.ExportIDToError(ctx))
  560. posByte += 5
  561. }
  562. } else if *remainingContent > 0 {
  563. len := *remainingContent
  564. if b.Len() < posByte+*remainingContent {
  565. len = b.Len() - posByte
  566. }
  567. newbuffer := buf.New()
  568. newbuffer.Write(b.BytesRange(posByte, posByte+len))
  569. mb2 = append(mb2, newbuffer)
  570. *remainingContent -= len
  571. posByte += len
  572. } else { // remainingPadding > 0
  573. len := *remainingPadding
  574. if b.Len() < posByte+*remainingPadding {
  575. len = b.Len() - posByte
  576. }
  577. *remainingPadding -= len
  578. posByte += len
  579. }
  580. if posByte == b.Len() {
  581. posByte = 0
  582. break
  583. }
  584. }
  585. }
  586. buf.ReleaseMulti(buffer)
  587. return mb2
  588. }