proxy.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823
  1. // Package proxy contains all proxies used by Xray.
  2. //
  3. // To implement an inbound or outbound proxy, one needs to do the following:
  4. // 1. Implement the interface(s) below.
  5. // 2. Register a config creator through common.RegisterConfig.
  6. package proxy
  7. import (
  8. "bytes"
  9. "context"
  10. "crypto/rand"
  11. "io"
  12. "math/big"
  13. "runtime"
  14. "strconv"
  15. "strings"
  16. "time"
  17. "github.com/pires/go-proxyproto"
  18. "github.com/xtls/xray-core/app/dispatcher"
  19. "github.com/xtls/xray-core/common/buf"
  20. "github.com/xtls/xray-core/common/errors"
  21. "github.com/xtls/xray-core/common/net"
  22. "github.com/xtls/xray-core/common/protocol"
  23. "github.com/xtls/xray-core/common/session"
  24. "github.com/xtls/xray-core/common/signal"
  25. "github.com/xtls/xray-core/features/routing"
  26. "github.com/xtls/xray-core/features/stats"
  27. "github.com/xtls/xray-core/proxy/vless/encryption"
  28. "github.com/xtls/xray-core/transport"
  29. "github.com/xtls/xray-core/transport/internet"
  30. "github.com/xtls/xray-core/transport/internet/reality"
  31. "github.com/xtls/xray-core/transport/internet/stat"
  32. "github.com/xtls/xray-core/transport/internet/tls"
  33. )
  34. var (
  35. Tls13SupportedVersions = []byte{0x00, 0x2b, 0x00, 0x02, 0x03, 0x04}
  36. TlsClientHandShakeStart = []byte{0x16, 0x03}
  37. TlsServerHandShakeStart = []byte{0x16, 0x03, 0x03}
  38. TlsApplicationDataStart = []byte{0x17, 0x03, 0x03}
  39. Tls13CipherSuiteDic = map[uint16]string{
  40. 0x1301: "TLS_AES_128_GCM_SHA256",
  41. 0x1302: "TLS_AES_256_GCM_SHA384",
  42. 0x1303: "TLS_CHACHA20_POLY1305_SHA256",
  43. 0x1304: "TLS_AES_128_CCM_SHA256",
  44. 0x1305: "TLS_AES_128_CCM_8_SHA256",
  45. }
  46. )
  47. const (
  48. TlsHandshakeTypeClientHello byte = 0x01
  49. TlsHandshakeTypeServerHello byte = 0x02
  50. CommandPaddingContinue byte = 0x00
  51. CommandPaddingEnd byte = 0x01
  52. CommandPaddingDirect byte = 0x02
  53. )
  54. // An Inbound processes inbound connections.
  55. type Inbound interface {
  56. // Network returns a list of networks that this inbound supports. Connections with not-supported networks will not be passed into Process().
  57. Network() []net.Network
  58. // Process processes a connection of given network. If necessary, the Inbound can dispatch the connection to an Outbound.
  59. Process(context.Context, net.Network, stat.Connection, routing.Dispatcher) error
  60. }
  61. // An Outbound process outbound connections.
  62. type Outbound interface {
  63. // Process processes the given connection. The given dialer may be used to dial a system outbound connection.
  64. Process(context.Context, *transport.Link, internet.Dialer) error
  65. }
  66. // UserManager is the interface for Inbounds and Outbounds that can manage their users.
  67. type UserManager interface {
  68. // AddUser adds a new user.
  69. AddUser(context.Context, *protocol.MemoryUser) error
  70. // RemoveUser removes a user by email.
  71. RemoveUser(context.Context, string) error
  72. // Get user by email.
  73. GetUser(context.Context, string) *protocol.MemoryUser
  74. // Get all users.
  75. GetUsers(context.Context) []*protocol.MemoryUser
  76. // Get users count.
  77. GetUsersCount(context.Context) int64
  78. }
  79. type GetInbound interface {
  80. GetInbound() Inbound
  81. }
  82. type GetOutbound interface {
  83. GetOutbound() Outbound
  84. }
  85. // TrafficState is used to track uplink and downlink of one connection
  86. // It is used by XTLS to determine if switch to raw copy mode, It is used by Vision to calculate padding
  87. type TrafficState struct {
  88. UserUUID []byte
  89. StartTime time.Time
  90. ByteSent int64
  91. ByteReceived int64
  92. NumberOfPacketSent int
  93. NumberOfPacketReceived int
  94. NumberOfPacketToFilter int
  95. EnableXtls bool
  96. IsTLS12orAbove bool
  97. IsTLS bool
  98. Cipher uint16
  99. RemainingServerHello int32
  100. Inbound InboundState
  101. Outbound OutboundState
  102. }
  103. type InboundState struct {
  104. // reader link state
  105. WithinPaddingBuffers bool
  106. UplinkReaderDirectCopy bool
  107. RemainingCommand int32
  108. RemainingContent int32
  109. RemainingPadding int32
  110. CurrentCommand int
  111. // write link state
  112. IsPadding bool
  113. DownlinkWriterDirectCopy bool
  114. }
  115. type OutboundState struct {
  116. // reader link state
  117. WithinPaddingBuffers bool
  118. DownlinkReaderDirectCopy bool
  119. RemainingCommand int32
  120. RemainingContent int32
  121. RemainingPadding int32
  122. CurrentCommand int
  123. // write link state
  124. IsPadding bool
  125. UplinkWriterDirectCopy bool
  126. }
  127. func NewTrafficState(userUUID []byte, flow string) *TrafficState {
  128. var state = TrafficState{
  129. UserUUID: userUUID,
  130. StartTime: time.Time{},
  131. ByteSent: 0,
  132. ByteReceived: 0,
  133. NumberOfPacketSent: 0,
  134. NumberOfPacketReceived: 0,
  135. NumberOfPacketToFilter: 8,
  136. EnableXtls: false,
  137. IsTLS12orAbove: false,
  138. IsTLS: false,
  139. Cipher: 0,
  140. RemainingServerHello: -1,
  141. Inbound: InboundState{
  142. UplinkReaderDirectCopy: false,
  143. RemainingCommand: -1,
  144. RemainingContent: -1,
  145. RemainingPadding: -1,
  146. CurrentCommand: 0,
  147. DownlinkWriterDirectCopy: false,
  148. IsPadding: true,
  149. },
  150. Outbound: OutboundState{
  151. DownlinkReaderDirectCopy: false,
  152. RemainingCommand: -1,
  153. RemainingContent: -1,
  154. RemainingPadding: -1,
  155. CurrentCommand: 0,
  156. UplinkWriterDirectCopy: false,
  157. IsPadding: true,
  158. },
  159. }
  160. if len(flow) > 0 {
  161. state.Inbound.WithinPaddingBuffers = true;
  162. state.Outbound.WithinPaddingBuffers = true;
  163. }
  164. return &state
  165. }
  166. // VisionReader is used to read seed protocol
  167. // Note Vision probably only make sense as the inner most layer of reader, since it need assess traffic state from origin proxy traffic
  168. type VisionReader struct {
  169. buf.Reader
  170. addons *Addons
  171. trafficState *TrafficState
  172. ctx context.Context
  173. isUplink bool
  174. conn net.Conn
  175. input *bytes.Reader
  176. rawInput *bytes.Buffer
  177. ob *session.Outbound
  178. // internal
  179. directReadCounter stats.Counter
  180. }
  181. func NewVisionReader(reader buf.Reader, addon *Addons, trafficState *TrafficState, isUplink bool, ctx context.Context, conn net.Conn, input *bytes.Reader, rawInput *bytes.Buffer, ob *session.Outbound) *VisionReader {
  182. return &VisionReader{
  183. Reader: reader,
  184. addons: addon,
  185. trafficState: trafficState,
  186. ctx: ctx,
  187. isUplink: isUplink,
  188. conn: conn,
  189. input: input,
  190. rawInput: rawInput,
  191. ob: ob,
  192. }
  193. }
  194. func (w *VisionReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
  195. buffer, err := w.Reader.ReadMultiBuffer()
  196. if buffer.IsEmpty() {
  197. return buffer, err
  198. }
  199. if w.trafficState.StartTime.IsZero() {
  200. w.trafficState.StartTime = time.Now()
  201. }
  202. w.trafficState.ByteReceived += int64(buffer.Len())
  203. var withinPaddingBuffers *bool
  204. var remainingContent *int32
  205. var remainingPadding *int32
  206. var currentCommand *int
  207. var switchToDirectCopy *bool
  208. if w.isUplink {
  209. withinPaddingBuffers = &w.trafficState.Inbound.WithinPaddingBuffers
  210. remainingContent = &w.trafficState.Inbound.RemainingContent
  211. remainingPadding = &w.trafficState.Inbound.RemainingPadding
  212. currentCommand = &w.trafficState.Inbound.CurrentCommand
  213. switchToDirectCopy = &w.trafficState.Inbound.UplinkReaderDirectCopy
  214. } else {
  215. withinPaddingBuffers = &w.trafficState.Outbound.WithinPaddingBuffers
  216. remainingContent = &w.trafficState.Outbound.RemainingContent
  217. remainingPadding = &w.trafficState.Outbound.RemainingPadding
  218. currentCommand = &w.trafficState.Outbound.CurrentCommand
  219. switchToDirectCopy = &w.trafficState.Outbound.DownlinkReaderDirectCopy
  220. }
  221. if *switchToDirectCopy {
  222. if w.directReadCounter != nil {
  223. w.directReadCounter.Add(int64(buffer.Len()))
  224. }
  225. return buffer, err
  226. }
  227. if *withinPaddingBuffers || w.trafficState.NumberOfPacketReceived <= 8 || !ShouldStopSeed(w.addons, w.trafficState) {
  228. mb2 := make(buf.MultiBuffer, 0, len(buffer))
  229. for _, b := range buffer {
  230. newbuffer := XtlsUnpadding(b, w.trafficState, w.isUplink, w.ctx)
  231. if newbuffer.Len() > 0 {
  232. mb2 = append(mb2, newbuffer)
  233. }
  234. }
  235. buffer = mb2
  236. if *remainingContent > 0 || *remainingPadding > 0 || *currentCommand == 0 {
  237. *withinPaddingBuffers = true
  238. } else if *currentCommand == 1 {
  239. *withinPaddingBuffers = false
  240. } else if *currentCommand == 2 {
  241. *withinPaddingBuffers = false
  242. *switchToDirectCopy = true
  243. } else {
  244. errors.LogInfo(w.ctx, "XtlsRead unknown command ", *currentCommand, buffer.Len())
  245. }
  246. }
  247. w.trafficState.NumberOfPacketReceived += len(buffer)
  248. if w.trafficState.NumberOfPacketToFilter > 0 {
  249. XtlsFilterTls(buffer, w.trafficState, w.ctx)
  250. }
  251. if *switchToDirectCopy {
  252. // XTLS Vision processes TLS-like conn's input and rawInput
  253. if inputBuffer, err := buf.ReadFrom(w.input); err == nil && !inputBuffer.IsEmpty() {
  254. buffer, _ = buf.MergeMulti(buffer, inputBuffer)
  255. }
  256. if rawInputBuffer, err := buf.ReadFrom(w.rawInput); err == nil && !rawInputBuffer.IsEmpty() {
  257. buffer, _ = buf.MergeMulti(buffer, rawInputBuffer)
  258. }
  259. *w.input = bytes.Reader{} // release memory
  260. w.input = nil
  261. *w.rawInput = bytes.Buffer{} // release memory
  262. w.rawInput = nil
  263. if inbound := session.InboundFromContext(w.ctx); inbound != nil && inbound.Conn != nil {
  264. if w.isUplink && inbound.CanSpliceCopy == 2 {
  265. inbound.CanSpliceCopy = 1
  266. }
  267. if !w.isUplink && w.ob != nil && w.ob.CanSpliceCopy == 2 { // ob need to be passed in due to context can have more than one ob
  268. w.ob.CanSpliceCopy = 1
  269. }
  270. }
  271. readerConn, readCounter, _ := UnwrapRawConn(w.conn)
  272. w.directReadCounter = readCounter
  273. w.Reader = buf.NewReader(readerConn)
  274. }
  275. return buffer, err
  276. }
  277. // VisionWriter is used to write seed protocol
  278. // Note Vision probably only make sense as the inner most layer of writer, since it need assess traffic state from origin proxy traffic
  279. type VisionWriter struct {
  280. buf.Writer
  281. addons *Addons
  282. trafficState *TrafficState
  283. ctx context.Context
  284. isUplink bool
  285. conn net.Conn
  286. ob *session.Outbound
  287. // internal
  288. writeOnceUserUUID *[]byte
  289. directWriteCounter stats.Counter
  290. scheduler *Scheduler
  291. }
  292. func NewVisionWriter(writer buf.Writer, addon *Addons, trafficState *TrafficState, isUplink bool, ctx context.Context, conn net.Conn, ob *session.Outbound) *VisionWriter {
  293. w := make([]byte, len(trafficState.UserUUID))
  294. copy(w, trafficState.UserUUID)
  295. return &VisionWriter{
  296. Writer: writer,
  297. addons: addon,
  298. trafficState: trafficState,
  299. ctx: ctx,
  300. writeOnceUserUUID: &w,
  301. isUplink: isUplink,
  302. conn: conn,
  303. ob: ob,
  304. scheduler: NewScheduler(writer, addon, trafficState, &w, ctx),
  305. }
  306. }
  307. func (w *VisionWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
  308. var isPadding *bool
  309. var switchToDirectCopy *bool
  310. if w.isUplink {
  311. isPadding = &w.trafficState.Outbound.IsPadding
  312. switchToDirectCopy = &w.trafficState.Outbound.UplinkWriterDirectCopy
  313. } else {
  314. isPadding = &w.trafficState.Inbound.IsPadding
  315. switchToDirectCopy = &w.trafficState.Inbound.DownlinkWriterDirectCopy
  316. }
  317. if *switchToDirectCopy {
  318. if inbound := session.InboundFromContext(w.ctx); inbound != nil {
  319. if !w.isUplink && inbound.CanSpliceCopy == 2 {
  320. inbound.CanSpliceCopy = 1
  321. }
  322. if w.isUplink && w.ob != nil && w.ob.CanSpliceCopy == 2 {
  323. w.ob.CanSpliceCopy = 1
  324. }
  325. }
  326. rawConn, _, writerCounter := UnwrapRawConn(w.conn)
  327. w.Writer = buf.NewWriter(rawConn)
  328. w.directWriteCounter = writerCounter
  329. *switchToDirectCopy = false
  330. }
  331. if !mb.IsEmpty() && w.directWriteCounter != nil {
  332. w.directWriteCounter.Add(int64(mb.Len()))
  333. }
  334. w.trafficState.NumberOfPacketSent += len(mb)
  335. if w.trafficState.NumberOfPacketToFilter > 0 {
  336. XtlsFilterTls(mb, w.trafficState, w.ctx)
  337. }
  338. if *isPadding && ShouldStartSeed(w.addons, w.trafficState) {
  339. if len(mb) == 1 && mb[0] == nil {
  340. mb[0] = XtlsPadding(nil, CommandPaddingContinue, w.writeOnceUserUUID, true, w.addons, w.ctx) // we do a long padding to hide vless header
  341. } else {
  342. mb = ReshapeMultiBuffer(w.ctx, mb)
  343. longPadding := w.trafficState.IsTLS
  344. for i, b := range mb {
  345. if w.trafficState.IsTLS && b.Len() >= 6 && bytes.Equal(TlsApplicationDataStart, b.BytesTo(3)) {
  346. if w.trafficState.EnableXtls {
  347. *switchToDirectCopy = true
  348. }
  349. var command byte = CommandPaddingContinue
  350. if i == len(mb) - 1 {
  351. if w.trafficState.EnableXtls {
  352. command = CommandPaddingDirect
  353. *isPadding = false
  354. } else if ShouldStopSeed(w.addons, w.trafficState) {
  355. command = CommandPaddingEnd
  356. *isPadding = false
  357. }
  358. }
  359. mb[i] = XtlsPadding(b, command, w.writeOnceUserUUID, true, w.addons, w.ctx)
  360. longPadding = false
  361. continue
  362. } else if !w.trafficState.IsTLS12orAbove && ShouldStopSeed(w.addons, w.trafficState) {
  363. *isPadding = false
  364. mb[i] = XtlsPadding(b, CommandPaddingEnd, w.writeOnceUserUUID, longPadding, w.addons, w.ctx)
  365. break
  366. }
  367. var command byte = CommandPaddingContinue
  368. if i == len(mb)-1 && !*isPadding {
  369. command = CommandPaddingEnd
  370. if w.trafficState.EnableXtls {
  371. command = CommandPaddingDirect
  372. }
  373. }
  374. mb[i] = XtlsPadding(b, command, w.writeOnceUserUUID, longPadding, w.addons, w.ctx)
  375. }
  376. }
  377. }
  378. w.trafficState.ByteSent += int64(mb.Len())
  379. if w.trafficState.StartTime.IsZero() {
  380. w.trafficState.StartTime = time.Now()
  381. }
  382. w.scheduler.Buffer <- mb
  383. if w.addons.Scheduler == nil {
  384. w.scheduler.Trigger <- -1 // send all buffers
  385. }
  386. if len(w.scheduler.Error) > 0 {
  387. return <-w.scheduler.Error
  388. }
  389. return nil
  390. }
  391. // ReshapeMultiBuffer prepare multi buffer for padding structure (max 21 bytes)
  392. func ReshapeMultiBuffer(ctx context.Context, buffer buf.MultiBuffer) buf.MultiBuffer {
  393. needReshape := 0
  394. for _, b := range buffer {
  395. if b.Len() >= buf.Size-21 {
  396. needReshape += 1
  397. }
  398. }
  399. if needReshape == 0 {
  400. return buffer
  401. }
  402. mb2 := make(buf.MultiBuffer, 0, len(buffer)+needReshape)
  403. toPrint := ""
  404. for i, buffer1 := range buffer {
  405. if buffer1.Len() >= buf.Size-21 {
  406. index := int32(bytes.LastIndex(buffer1.Bytes(), TlsApplicationDataStart))
  407. if index < 21 || index > buf.Size-21 {
  408. index = buf.Size / 2
  409. }
  410. buffer2 := buf.New()
  411. buffer2.Write(buffer1.BytesFrom(index))
  412. buffer1.Resize(0, index)
  413. mb2 = append(mb2, buffer1, buffer2)
  414. toPrint += " " + strconv.Itoa(int(buffer1.Len())) + " " + strconv.Itoa(int(buffer2.Len()))
  415. } else {
  416. mb2 = append(mb2, buffer1)
  417. toPrint += " " + strconv.Itoa(int(buffer1.Len()))
  418. }
  419. buffer[i] = nil
  420. }
  421. buffer = buffer[:0]
  422. errors.LogInfo(ctx, "ReshapeMultiBuffer ", toPrint)
  423. return mb2
  424. }
  425. // XtlsPadding add padding to eliminate length signature during tls handshake
  426. func XtlsPadding(b *buf.Buffer, command byte, userUUID *[]byte, longPadding bool, addons *Addons, ctx context.Context) *buf.Buffer {
  427. var contentLen int32 = 0
  428. var paddingLen int32 = 0
  429. if b != nil {
  430. contentLen = b.Len()
  431. }
  432. if contentLen < int32(addons.Padding.LongMin) && longPadding {
  433. l, err := rand.Int(rand.Reader, big.NewInt(int64(addons.Padding.LongMax - addons.Padding.LongMin)))
  434. if err != nil {
  435. errors.LogDebugInner(ctx, err, "failed to generate padding")
  436. }
  437. paddingLen = int32(l.Int64()) + int32(addons.Padding.LongMin) - contentLen
  438. } else {
  439. l, err := rand.Int(rand.Reader, big.NewInt(int64(addons.Padding.RegularMax - addons.Padding.RegularMin)))
  440. if err != nil {
  441. errors.LogDebugInner(ctx, err, "failed to generate padding")
  442. }
  443. paddingLen = int32(l.Int64()) + int32(addons.Padding.RegularMin)
  444. }
  445. if paddingLen > buf.Size-21-contentLen {
  446. paddingLen = buf.Size - 21 - contentLen
  447. }
  448. newbuffer := buf.New()
  449. if userUUID != nil {
  450. newbuffer.Write(*userUUID)
  451. *userUUID = nil
  452. }
  453. newbuffer.Write([]byte{command, byte(contentLen >> 8), byte(contentLen), byte(paddingLen >> 8), byte(paddingLen)})
  454. if b != nil {
  455. newbuffer.Write(b.Bytes())
  456. b.Release()
  457. b = nil
  458. }
  459. newbuffer.Extend(paddingLen)
  460. errors.LogInfo(ctx, "XtlsPadding ", contentLen, " ", paddingLen, " ", command)
  461. return newbuffer
  462. }
  463. // XtlsUnpadding remove padding and parse command
  464. func XtlsUnpadding(b *buf.Buffer, s *TrafficState, isUplink bool, ctx context.Context) *buf.Buffer {
  465. var remainingCommand *int32
  466. var remainingContent *int32
  467. var remainingPadding *int32
  468. var currentCommand *int
  469. if isUplink {
  470. remainingCommand = &s.Inbound.RemainingCommand
  471. remainingContent = &s.Inbound.RemainingContent
  472. remainingPadding = &s.Inbound.RemainingPadding
  473. currentCommand = &s.Inbound.CurrentCommand
  474. } else {
  475. remainingCommand = &s.Outbound.RemainingCommand
  476. remainingContent = &s.Outbound.RemainingContent
  477. remainingPadding = &s.Outbound.RemainingPadding
  478. currentCommand = &s.Outbound.CurrentCommand
  479. }
  480. if *remainingCommand == -1 && *remainingContent == -1 && *remainingPadding == -1 { // initial state
  481. if b.Len() >= 21 && bytes.Equal(s.UserUUID, b.BytesTo(16)) {
  482. b.Advance(16)
  483. *remainingCommand = 5
  484. } else {
  485. return b
  486. }
  487. }
  488. newbuffer := buf.New()
  489. for b.Len() > 0 {
  490. if *remainingCommand > 0 {
  491. data, err := b.ReadByte()
  492. if err != nil {
  493. return newbuffer
  494. }
  495. switch *remainingCommand {
  496. case 5:
  497. *currentCommand = int(data)
  498. case 4:
  499. *remainingContent = int32(data) << 8
  500. case 3:
  501. *remainingContent = *remainingContent | int32(data)
  502. case 2:
  503. *remainingPadding = int32(data) << 8
  504. case 1:
  505. *remainingPadding = *remainingPadding | int32(data)
  506. errors.LogInfo(ctx, "Xtls Unpadding new block, content ", *remainingContent, " padding ", *remainingPadding, " command ", *currentCommand)
  507. }
  508. *remainingCommand--
  509. } else if *remainingContent > 0 {
  510. len := *remainingContent
  511. if b.Len() < len {
  512. len = b.Len()
  513. }
  514. data, err := b.ReadBytes(len)
  515. if err != nil {
  516. return newbuffer
  517. }
  518. newbuffer.Write(data)
  519. *remainingContent -= len
  520. } else { // remainingPadding > 0
  521. len := *remainingPadding
  522. if b.Len() < len {
  523. len = b.Len()
  524. }
  525. b.Advance(len)
  526. *remainingPadding -= len
  527. }
  528. if *remainingCommand <= 0 && *remainingContent <= 0 && *remainingPadding <= 0 { // this block done
  529. if *currentCommand == 0 {
  530. *remainingCommand = 5
  531. } else {
  532. *remainingCommand = -1 // set to initial state
  533. *remainingContent = -1
  534. *remainingPadding = -1
  535. if b.Len() > 0 { // shouldn't happen
  536. newbuffer.Write(b.Bytes())
  537. }
  538. break
  539. }
  540. }
  541. }
  542. b.Release()
  543. b = nil
  544. return newbuffer
  545. }
  546. // XtlsFilterTls filter and recognize tls 1.3 and other info
  547. func XtlsFilterTls(buffer buf.MultiBuffer, trafficState *TrafficState, ctx context.Context) {
  548. for _, b := range buffer {
  549. if b == nil {
  550. continue
  551. }
  552. trafficState.NumberOfPacketToFilter--
  553. if b.Len() >= 6 {
  554. startsBytes := b.BytesTo(6)
  555. if bytes.Equal(TlsServerHandShakeStart, startsBytes[:3]) && startsBytes[5] == TlsHandshakeTypeServerHello {
  556. trafficState.RemainingServerHello = (int32(startsBytes[3])<<8 | int32(startsBytes[4])) + 5
  557. trafficState.IsTLS12orAbove = true
  558. trafficState.IsTLS = true
  559. if b.Len() >= 79 && trafficState.RemainingServerHello >= 79 {
  560. sessionIdLen := int32(b.Byte(43))
  561. cipherSuite := b.BytesRange(43+sessionIdLen+1, 43+sessionIdLen+3)
  562. trafficState.Cipher = uint16(cipherSuite[0])<<8 | uint16(cipherSuite[1])
  563. } else {
  564. errors.LogInfo(ctx, "XtlsFilterTls short server hello, tls 1.2 or older? ", b.Len(), " ", trafficState.RemainingServerHello)
  565. }
  566. } else if bytes.Equal(TlsClientHandShakeStart, startsBytes[:2]) && startsBytes[5] == TlsHandshakeTypeClientHello {
  567. trafficState.IsTLS = true
  568. errors.LogInfo(ctx, "XtlsFilterTls found tls client hello! ", buffer.Len())
  569. }
  570. }
  571. if trafficState.RemainingServerHello > 0 {
  572. end := trafficState.RemainingServerHello
  573. if end > b.Len() {
  574. end = b.Len()
  575. }
  576. trafficState.RemainingServerHello -= b.Len()
  577. if bytes.Contains(b.BytesTo(end), Tls13SupportedVersions) {
  578. v, ok := Tls13CipherSuiteDic[trafficState.Cipher]
  579. if !ok {
  580. v = "Old cipher: " + strconv.FormatUint(uint64(trafficState.Cipher), 16)
  581. } else if v != "TLS_AES_128_CCM_8_SHA256" {
  582. trafficState.EnableXtls = true
  583. }
  584. errors.LogInfo(ctx, "XtlsFilterTls found tls 1.3! ", b.Len(), " ", v)
  585. trafficState.NumberOfPacketToFilter = 0
  586. return
  587. } else if trafficState.RemainingServerHello <= 0 {
  588. errors.LogInfo(ctx, "XtlsFilterTls found tls 1.2! ", b.Len())
  589. trafficState.NumberOfPacketToFilter = 0
  590. return
  591. }
  592. errors.LogInfo(ctx, "XtlsFilterTls inconclusive server hello ", b.Len(), " ", trafficState.RemainingServerHello)
  593. }
  594. if trafficState.NumberOfPacketToFilter <= 0 {
  595. errors.LogInfo(ctx, "XtlsFilterTls stop filtering", buffer.Len())
  596. }
  597. }
  598. }
  599. // UnwrapRawConn support unwrap encryption, stats, tls, utls, reality, proxyproto, uds-wrapper conn and get raw tcp/uds conn from it
  600. func UnwrapRawConn(conn net.Conn) (net.Conn, stats.Counter, stats.Counter) {
  601. var readCounter, writerCounter stats.Counter
  602. if conn != nil {
  603. isEncryption := false
  604. if commonConn, ok := conn.(*encryption.CommonConn); ok {
  605. conn = commonConn.Conn
  606. isEncryption = true
  607. }
  608. if xorConn, ok := conn.(*encryption.XorConn); ok {
  609. return xorConn, nil, nil // full-random xorConn should not be penetrated
  610. }
  611. if statConn, ok := conn.(*stat.CounterConnection); ok {
  612. conn = statConn.Connection
  613. readCounter = statConn.ReadCounter
  614. writerCounter = statConn.WriteCounter
  615. }
  616. if !isEncryption { // avoids double penetration
  617. if xc, ok := conn.(*tls.Conn); ok {
  618. conn = xc.NetConn()
  619. } else if utlsConn, ok := conn.(*tls.UConn); ok {
  620. conn = utlsConn.NetConn()
  621. } else if realityConn, ok := conn.(*reality.Conn); ok {
  622. conn = realityConn.NetConn()
  623. } else if realityUConn, ok := conn.(*reality.UConn); ok {
  624. conn = realityUConn.NetConn()
  625. }
  626. }
  627. if pc, ok := conn.(*proxyproto.Conn); ok {
  628. conn = pc.Raw()
  629. // 8192 > 4096, there is no need to process pc's bufReader
  630. }
  631. if uc, ok := conn.(*internet.UnixConnWrapper); ok {
  632. conn = uc.UnixConn
  633. }
  634. }
  635. return conn, readCounter, writerCounter
  636. }
  637. // CopyRawConnIfExist use the most efficient copy method.
  638. // - If caller don't want to turn on splice, do not pass in both reader conn and writer conn
  639. // - writer are from *transport.Link
  640. func CopyRawConnIfExist(ctx context.Context, readerConn net.Conn, writerConn net.Conn, writer buf.Writer, timer *signal.ActivityTimer, inTimer *signal.ActivityTimer) error {
  641. readerConn, readCounter, _ := UnwrapRawConn(readerConn)
  642. writerConn, _, writeCounter := UnwrapRawConn(writerConn)
  643. reader := buf.NewReader(readerConn)
  644. if runtime.GOOS != "linux" && runtime.GOOS != "android" {
  645. return readV(ctx, reader, writer, timer, readCounter)
  646. }
  647. tc, ok := writerConn.(*net.TCPConn)
  648. if !ok || readerConn == nil || writerConn == nil {
  649. return readV(ctx, reader, writer, timer, readCounter)
  650. }
  651. inbound := session.InboundFromContext(ctx)
  652. if inbound == nil || inbound.CanSpliceCopy == 3 {
  653. return readV(ctx, reader, writer, timer, readCounter)
  654. }
  655. outbounds := session.OutboundsFromContext(ctx)
  656. if len(outbounds) == 0 {
  657. return readV(ctx, reader, writer, timer, readCounter)
  658. }
  659. for _, ob := range outbounds {
  660. if ob.CanSpliceCopy == 3 {
  661. return readV(ctx, reader, writer, timer, readCounter)
  662. }
  663. }
  664. for {
  665. inbound := session.InboundFromContext(ctx)
  666. outbounds := session.OutboundsFromContext(ctx)
  667. var splice = inbound.CanSpliceCopy == 1
  668. for _, ob := range outbounds {
  669. if ob.CanSpliceCopy != 1 {
  670. splice = false
  671. }
  672. }
  673. if splice {
  674. errors.LogInfo(ctx, "CopyRawConn splice")
  675. statWriter, _ := writer.(*dispatcher.SizeStatWriter)
  676. //runtime.Gosched() // necessary
  677. time.Sleep(time.Millisecond) // without this, there will be a rare ssl error for freedom splice
  678. timer.SetTimeout(8 * time.Hour) // prevent leak, just in case
  679. if inTimer != nil {
  680. inTimer.SetTimeout(8 * time.Hour)
  681. }
  682. w, err := tc.ReadFrom(readerConn)
  683. if readCounter != nil {
  684. readCounter.Add(w) // outbound stats
  685. }
  686. if writeCounter != nil {
  687. writeCounter.Add(w) // inbound stats
  688. }
  689. if statWriter != nil {
  690. statWriter.Counter.Add(w) // user stats
  691. }
  692. if err != nil && errors.Cause(err) != io.EOF {
  693. return err
  694. }
  695. return nil
  696. }
  697. buffer, err := reader.ReadMultiBuffer()
  698. if !buffer.IsEmpty() {
  699. if readCounter != nil {
  700. readCounter.Add(int64(buffer.Len()))
  701. }
  702. timer.Update()
  703. if werr := writer.WriteMultiBuffer(buffer); werr != nil {
  704. return werr
  705. }
  706. }
  707. if err != nil {
  708. if errors.Cause(err) == io.EOF {
  709. return nil
  710. }
  711. return err
  712. }
  713. }
  714. }
  715. func readV(ctx context.Context, reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, readCounter stats.Counter) error {
  716. errors.LogInfo(ctx, "CopyRawConn (maybe) readv")
  717. if err := buf.Copy(reader, writer, buf.UpdateActivity(timer), buf.AddToStatCounter(readCounter)); err != nil {
  718. return errors.New("failed to process response").Base(err)
  719. }
  720. return nil
  721. }
  722. func IsRAWTransportWithoutSecurity(conn stat.Connection) bool {
  723. iConn := conn
  724. if statConn, ok := iConn.(*stat.CounterConnection); ok {
  725. iConn = statConn.Connection
  726. }
  727. _, ok1 := iConn.(*proxyproto.Conn)
  728. _, ok2 := iConn.(*net.TCPConn)
  729. _, ok3 := iConn.(*internet.UnixConnWrapper)
  730. return ok1 || ok2 || ok3
  731. }
  732. func ShouldStartSeed(addons *Addons, trafficState *TrafficState) bool {
  733. if len(addons.Duration) == 0 || len(strings.Split(addons.Duration, "-")) < 2 {
  734. return false
  735. }
  736. start := strings.ToLower(strings.Split(addons.Duration, "-")[0])
  737. if len(start) == 0 {
  738. return true
  739. }
  740. if strings.Contains(start, "b") {
  741. start = strings.TrimRight(start, "b")
  742. i, err := strconv.Atoi(start)
  743. if err == nil && i <= int(trafficState.ByteSent + trafficState.ByteSent) {
  744. return true
  745. }
  746. } else {
  747. i, err := strconv.Atoi(start)
  748. if err == nil && i <= trafficState.NumberOfPacketSent + trafficState.NumberOfPacketReceived {
  749. return true
  750. }
  751. }
  752. return false
  753. }
  754. func ShouldStopSeed(addons *Addons, trafficState *TrafficState) bool {
  755. if len(addons.Duration) == 0 || len(strings.Split(addons.Duration, "-")) < 2 {
  756. return true
  757. }
  758. start := strings.ToLower(strings.Split(addons.Duration, "-")[1])
  759. if len(start) == 0 { // infinite
  760. return false
  761. }
  762. if strings.Contains(start, "b") {
  763. start = strings.TrimRight(start, "b")
  764. i, err := strconv.Atoi(start)
  765. if err == nil && i > int(trafficState.ByteSent + trafficState.ByteSent) {
  766. return false
  767. }
  768. } else {
  769. i, err := strconv.Atoi(start)
  770. if err == nil && i > trafficState.NumberOfPacketSent + trafficState.NumberOfPacketReceived {
  771. return false
  772. }
  773. }
  774. return true
  775. }