vless.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. package outbound
  2. import (
  3. "context"
  4. "crypto/tls"
  5. "encoding/binary"
  6. "errors"
  7. "fmt"
  8. "io"
  9. "net"
  10. "net/http"
  11. "strconv"
  12. "sync"
  13. "github.com/metacubex/mihomo/common/convert"
  14. N "github.com/metacubex/mihomo/common/net"
  15. "github.com/metacubex/mihomo/common/utils"
  16. "github.com/metacubex/mihomo/component/ca"
  17. "github.com/metacubex/mihomo/component/dialer"
  18. "github.com/metacubex/mihomo/component/proxydialer"
  19. "github.com/metacubex/mihomo/component/resolver"
  20. tlsC "github.com/metacubex/mihomo/component/tls"
  21. C "github.com/metacubex/mihomo/constant"
  22. "github.com/metacubex/mihomo/log"
  23. "github.com/metacubex/mihomo/transport/gun"
  24. "github.com/metacubex/mihomo/transport/socks5"
  25. "github.com/metacubex/mihomo/transport/vless"
  26. "github.com/metacubex/mihomo/transport/vmess"
  27. vmessSing "github.com/metacubex/sing-vmess"
  28. "github.com/metacubex/sing-vmess/packetaddr"
  29. M "github.com/sagernet/sing/common/metadata"
  30. )
  31. const (
  32. // max packet length
  33. maxLength = 1024 << 3
  34. )
  35. type Vless struct {
  36. *Base
  37. client *vless.Client
  38. option *VlessOption
  39. // for gun mux
  40. gunTLSConfig *tls.Config
  41. gunConfig *gun.Config
  42. transport *gun.TransportWrap
  43. realityConfig *tlsC.RealityConfig
  44. }
  45. type VlessOption struct {
  46. BasicOption
  47. Name string `proxy:"name"`
  48. Server string `proxy:"server"`
  49. Port int `proxy:"port"`
  50. UUID string `proxy:"uuid"`
  51. Flow string `proxy:"flow,omitempty"`
  52. TLS bool `proxy:"tls,omitempty"`
  53. ALPN []string `proxy:"alpn,omitempty"`
  54. UDP bool `proxy:"udp,omitempty"`
  55. PacketAddr bool `proxy:"packet-addr,omitempty"`
  56. XUDP bool `proxy:"xudp,omitempty"`
  57. PacketEncoding string `proxy:"packet-encoding,omitempty"`
  58. Network string `proxy:"network,omitempty"`
  59. RealityOpts RealityOptions `proxy:"reality-opts,omitempty"`
  60. HTTPOpts HTTPOptions `proxy:"http-opts,omitempty"`
  61. HTTP2Opts HTTP2Options `proxy:"h2-opts,omitempty"`
  62. GrpcOpts GrpcOptions `proxy:"grpc-opts,omitempty"`
  63. WSOpts WSOptions `proxy:"ws-opts,omitempty"`
  64. WSPath string `proxy:"ws-path,omitempty"`
  65. WSHeaders map[string]string `proxy:"ws-headers,omitempty"`
  66. SkipCertVerify bool `proxy:"skip-cert-verify,omitempty"`
  67. Fingerprint string `proxy:"fingerprint,omitempty"`
  68. ServerName string `proxy:"servername,omitempty"`
  69. ClientFingerprint string `proxy:"client-fingerprint,omitempty"`
  70. }
  71. func (v *Vless) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.Metadata) (net.Conn, error) {
  72. var err error
  73. if tlsC.HaveGlobalFingerprint() && len(v.option.ClientFingerprint) == 0 {
  74. v.option.ClientFingerprint = tlsC.GetGlobalFingerprint()
  75. }
  76. switch v.option.Network {
  77. case "ws":
  78. host, port, _ := net.SplitHostPort(v.addr)
  79. wsOpts := &vmess.WebsocketConfig{
  80. Host: host,
  81. Port: port,
  82. Path: v.option.WSOpts.Path,
  83. MaxEarlyData: v.option.WSOpts.MaxEarlyData,
  84. EarlyDataHeaderName: v.option.WSOpts.EarlyDataHeaderName,
  85. V2rayHttpUpgrade: v.option.WSOpts.V2rayHttpUpgrade,
  86. V2rayHttpUpgradeFastOpen: v.option.WSOpts.V2rayHttpUpgradeFastOpen,
  87. ClientFingerprint: v.option.ClientFingerprint,
  88. Headers: http.Header{},
  89. }
  90. if len(v.option.WSOpts.Headers) != 0 {
  91. for key, value := range v.option.WSOpts.Headers {
  92. wsOpts.Headers.Add(key, value)
  93. }
  94. }
  95. if v.option.TLS {
  96. wsOpts.TLS = true
  97. tlsConfig := &tls.Config{
  98. MinVersion: tls.VersionTLS12,
  99. ServerName: host,
  100. InsecureSkipVerify: v.option.SkipCertVerify,
  101. NextProtos: []string{"http/1.1"},
  102. }
  103. wsOpts.TLSConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, v.option.Fingerprint)
  104. if err != nil {
  105. return nil, err
  106. }
  107. if v.option.ServerName != "" {
  108. wsOpts.TLSConfig.ServerName = v.option.ServerName
  109. } else if host := wsOpts.Headers.Get("Host"); host != "" {
  110. wsOpts.TLSConfig.ServerName = host
  111. }
  112. } else {
  113. if host := wsOpts.Headers.Get("Host"); host == "" {
  114. wsOpts.Headers.Set("Host", convert.RandHost())
  115. convert.SetUserAgent(wsOpts.Headers)
  116. }
  117. }
  118. c, err = vmess.StreamWebsocketConn(ctx, c, wsOpts)
  119. case "http":
  120. // readability first, so just copy default TLS logic
  121. c, err = v.streamTLSConn(ctx, c, false)
  122. if err != nil {
  123. return nil, err
  124. }
  125. host, _, _ := net.SplitHostPort(v.addr)
  126. httpOpts := &vmess.HTTPConfig{
  127. Host: host,
  128. Method: v.option.HTTPOpts.Method,
  129. Path: v.option.HTTPOpts.Path,
  130. Headers: v.option.HTTPOpts.Headers,
  131. }
  132. c = vmess.StreamHTTPConn(c, httpOpts)
  133. case "h2":
  134. c, err = v.streamTLSConn(ctx, c, true)
  135. if err != nil {
  136. return nil, err
  137. }
  138. h2Opts := &vmess.H2Config{
  139. Hosts: v.option.HTTP2Opts.Host,
  140. Path: v.option.HTTP2Opts.Path,
  141. }
  142. c, err = vmess.StreamH2Conn(c, h2Opts)
  143. case "grpc":
  144. c, err = gun.StreamGunWithConn(c, v.gunTLSConfig, v.gunConfig, v.realityConfig)
  145. default:
  146. // default tcp network
  147. // handle TLS
  148. c, err = v.streamTLSConn(ctx, c, false)
  149. }
  150. if err != nil {
  151. return nil, err
  152. }
  153. return v.streamConn(c, metadata)
  154. }
  155. func (v *Vless) streamConn(c net.Conn, metadata *C.Metadata) (conn net.Conn, err error) {
  156. if metadata.NetWork == C.UDP {
  157. if v.option.PacketAddr {
  158. metadata = &C.Metadata{
  159. NetWork: C.UDP,
  160. Host: packetaddr.SeqPacketMagicAddress,
  161. DstPort: 443,
  162. }
  163. } else {
  164. metadata = &C.Metadata{ // a clear metadata only contains ip
  165. NetWork: C.UDP,
  166. DstIP: metadata.DstIP,
  167. DstPort: metadata.DstPort,
  168. }
  169. }
  170. conn, err = v.client.StreamConn(c, parseVlessAddr(metadata, v.option.XUDP))
  171. if v.option.PacketAddr {
  172. conn = packetaddr.NewBindConn(conn)
  173. }
  174. } else {
  175. conn, err = v.client.StreamConn(c, parseVlessAddr(metadata, false))
  176. }
  177. if err != nil {
  178. conn = nil
  179. }
  180. return
  181. }
  182. func (v *Vless) streamTLSConn(ctx context.Context, conn net.Conn, isH2 bool) (net.Conn, error) {
  183. if v.option.TLS {
  184. host, _, _ := net.SplitHostPort(v.addr)
  185. tlsOpts := vmess.TLSConfig{
  186. Host: host,
  187. SkipCertVerify: v.option.SkipCertVerify,
  188. FingerPrint: v.option.Fingerprint,
  189. ClientFingerprint: v.option.ClientFingerprint,
  190. Reality: v.realityConfig,
  191. NextProtos: v.option.ALPN,
  192. }
  193. if isH2 {
  194. tlsOpts.NextProtos = []string{"h2"}
  195. }
  196. if v.option.ServerName != "" {
  197. tlsOpts.Host = v.option.ServerName
  198. }
  199. return vmess.StreamTLSConn(ctx, conn, &tlsOpts)
  200. }
  201. return conn, nil
  202. }
  203. // DialContext implements C.ProxyAdapter
  204. func (v *Vless) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (_ C.Conn, err error) {
  205. // gun transport
  206. if v.transport != nil && len(opts) == 0 {
  207. c, err := gun.StreamGunWithTransport(v.transport, v.gunConfig)
  208. if err != nil {
  209. return nil, err
  210. }
  211. defer func(c net.Conn) {
  212. safeConnClose(c, err)
  213. }(c)
  214. c, err = v.client.StreamConn(c, parseVlessAddr(metadata, v.option.XUDP))
  215. if err != nil {
  216. return nil, err
  217. }
  218. return NewConn(c, v), nil
  219. }
  220. return v.DialContextWithDialer(ctx, dialer.NewDialer(v.Base.DialOptions(opts...)...), metadata)
  221. }
  222. // DialContextWithDialer implements C.ProxyAdapter
  223. func (v *Vless) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.Conn, err error) {
  224. if len(v.option.DialerProxy) > 0 {
  225. dialer, err = proxydialer.NewByName(v.option.DialerProxy, dialer)
  226. if err != nil {
  227. return nil, err
  228. }
  229. }
  230. c, err := dialer.DialContext(ctx, "tcp", v.addr)
  231. if err != nil {
  232. return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error())
  233. }
  234. N.TCPKeepAlive(c)
  235. defer func(c net.Conn) {
  236. safeConnClose(c, err)
  237. }(c)
  238. c, err = v.StreamConnContext(ctx, c, metadata)
  239. if err != nil {
  240. return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error())
  241. }
  242. return NewConn(c, v), err
  243. }
  244. // ListenPacketContext implements C.ProxyAdapter
  245. func (v *Vless) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (_ C.PacketConn, err error) {
  246. // vless use stream-oriented udp with a special address, so we need a net.UDPAddr
  247. if !metadata.Resolved() {
  248. ip, err := resolver.ResolveIP(ctx, metadata.Host)
  249. if err != nil {
  250. return nil, errors.New("can't resolve ip")
  251. }
  252. metadata.DstIP = ip
  253. }
  254. var c net.Conn
  255. // gun transport
  256. if v.transport != nil && len(opts) == 0 {
  257. c, err = gun.StreamGunWithTransport(v.transport, v.gunConfig)
  258. if err != nil {
  259. return nil, err
  260. }
  261. defer func(c net.Conn) {
  262. safeConnClose(c, err)
  263. }(c)
  264. c, err = v.streamConn(c, metadata)
  265. if err != nil {
  266. return nil, fmt.Errorf("new vless client error: %v", err)
  267. }
  268. return v.ListenPacketOnStreamConn(ctx, c, metadata)
  269. }
  270. return v.ListenPacketWithDialer(ctx, dialer.NewDialer(v.Base.DialOptions(opts...)...), metadata)
  271. }
  272. // ListenPacketWithDialer implements C.ProxyAdapter
  273. func (v *Vless) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.PacketConn, err error) {
  274. if len(v.option.DialerProxy) > 0 {
  275. dialer, err = proxydialer.NewByName(v.option.DialerProxy, dialer)
  276. if err != nil {
  277. return nil, err
  278. }
  279. }
  280. // vless use stream-oriented udp with a special address, so we need a net.UDPAddr
  281. if !metadata.Resolved() {
  282. ip, err := resolver.ResolveIP(ctx, metadata.Host)
  283. if err != nil {
  284. return nil, errors.New("can't resolve ip")
  285. }
  286. metadata.DstIP = ip
  287. }
  288. c, err := dialer.DialContext(ctx, "tcp", v.addr)
  289. if err != nil {
  290. return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error())
  291. }
  292. N.TCPKeepAlive(c)
  293. defer func(c net.Conn) {
  294. safeConnClose(c, err)
  295. }(c)
  296. c, err = v.StreamConnContext(ctx, c, metadata)
  297. if err != nil {
  298. return nil, fmt.Errorf("new vless client error: %v", err)
  299. }
  300. return v.ListenPacketOnStreamConn(ctx, c, metadata)
  301. }
  302. // SupportWithDialer implements C.ProxyAdapter
  303. func (v *Vless) SupportWithDialer() C.NetWork {
  304. return C.ALLNet
  305. }
  306. // ListenPacketOnStreamConn implements C.ProxyAdapter
  307. func (v *Vless) ListenPacketOnStreamConn(ctx context.Context, c net.Conn, metadata *C.Metadata) (_ C.PacketConn, err error) {
  308. // vless use stream-oriented udp with a special address, so we need a net.UDPAddr
  309. if !metadata.Resolved() {
  310. ip, err := resolver.ResolveIP(ctx, metadata.Host)
  311. if err != nil {
  312. return nil, errors.New("can't resolve ip")
  313. }
  314. metadata.DstIP = ip
  315. }
  316. if v.option.XUDP {
  317. var globalID [8]byte
  318. if metadata.SourceValid() {
  319. globalID = utils.GlobalID(metadata.SourceAddress())
  320. }
  321. return newPacketConn(N.NewThreadSafePacketConn(
  322. vmessSing.NewXUDPConn(c,
  323. globalID,
  324. M.SocksaddrFromNet(metadata.UDPAddr())),
  325. ), v), nil
  326. } else if v.option.PacketAddr {
  327. return newPacketConn(N.NewThreadSafePacketConn(
  328. packetaddr.NewConn(&vlessPacketConn{
  329. Conn: c, rAddr: metadata.UDPAddr(),
  330. }, M.SocksaddrFromNet(metadata.UDPAddr())),
  331. ), v), nil
  332. }
  333. return newPacketConn(N.NewThreadSafePacketConn(&vlessPacketConn{Conn: c, rAddr: metadata.UDPAddr()}), v), nil
  334. }
  335. // SupportUOT implements C.ProxyAdapter
  336. func (v *Vless) SupportUOT() bool {
  337. return true
  338. }
  339. func parseVlessAddr(metadata *C.Metadata, xudp bool) *vless.DstAddr {
  340. var addrType byte
  341. var addr []byte
  342. switch metadata.AddrType() {
  343. case socks5.AtypIPv4:
  344. addrType = vless.AtypIPv4
  345. addr = make([]byte, net.IPv4len)
  346. copy(addr[:], metadata.DstIP.AsSlice())
  347. case socks5.AtypIPv6:
  348. addrType = vless.AtypIPv6
  349. addr = make([]byte, net.IPv6len)
  350. copy(addr[:], metadata.DstIP.AsSlice())
  351. case socks5.AtypDomainName:
  352. addrType = vless.AtypDomainName
  353. addr = make([]byte, len(metadata.Host)+1)
  354. addr[0] = byte(len(metadata.Host))
  355. copy(addr[1:], metadata.Host)
  356. }
  357. return &vless.DstAddr{
  358. UDP: metadata.NetWork == C.UDP,
  359. AddrType: addrType,
  360. Addr: addr,
  361. Port: metadata.DstPort,
  362. Mux: metadata.NetWork == C.UDP && xudp,
  363. }
  364. }
  365. type vlessPacketConn struct {
  366. net.Conn
  367. rAddr net.Addr
  368. remain int
  369. mux sync.Mutex
  370. cache [2]byte
  371. }
  372. func (c *vlessPacketConn) writePacket(payload []byte) (int, error) {
  373. binary.BigEndian.PutUint16(c.cache[:], uint16(len(payload)))
  374. if _, err := c.Conn.Write(c.cache[:]); err != nil {
  375. return 0, err
  376. }
  377. return c.Conn.Write(payload)
  378. }
  379. func (c *vlessPacketConn) WriteTo(b []byte, addr net.Addr) (int, error) {
  380. total := len(b)
  381. if total == 0 {
  382. return 0, nil
  383. }
  384. if total <= maxLength {
  385. return c.writePacket(b)
  386. }
  387. offset := 0
  388. for offset < total {
  389. cursor := offset + maxLength
  390. if cursor > total {
  391. cursor = total
  392. }
  393. n, err := c.writePacket(b[offset:cursor])
  394. if err != nil {
  395. return offset + n, err
  396. }
  397. offset = cursor
  398. if offset == total {
  399. break
  400. }
  401. }
  402. return total, nil
  403. }
  404. func (c *vlessPacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
  405. c.mux.Lock()
  406. defer c.mux.Unlock()
  407. if c.remain > 0 {
  408. length := len(b)
  409. if c.remain < length {
  410. length = c.remain
  411. }
  412. n, err := c.Conn.Read(b[:length])
  413. if err != nil {
  414. return 0, c.rAddr, err
  415. }
  416. c.remain -= n
  417. return n, c.rAddr, nil
  418. }
  419. if _, err := c.Conn.Read(b[:2]); err != nil {
  420. return 0, c.rAddr, err
  421. }
  422. total := int(binary.BigEndian.Uint16(b[:2]))
  423. if total == 0 {
  424. return 0, c.rAddr, nil
  425. }
  426. length := len(b)
  427. if length > total {
  428. length = total
  429. }
  430. if _, err := io.ReadFull(c.Conn, b[:length]); err != nil {
  431. return 0, c.rAddr, errors.New("read packet error")
  432. }
  433. c.remain = total - length
  434. return length, c.rAddr, nil
  435. }
  436. func NewVless(option VlessOption) (*Vless, error) {
  437. var addons *vless.Addons
  438. if option.Network != "ws" && len(option.Flow) >= 16 {
  439. option.Flow = option.Flow[:16]
  440. switch option.Flow {
  441. case vless.XRV:
  442. log.Warnln("To use %s, ensure your server is upgrade to Xray-core v1.8.0+", vless.XRV)
  443. addons = &vless.Addons{
  444. Flow: option.Flow,
  445. }
  446. case vless.XRO, vless.XRD, vless.XRS:
  447. log.Fatalln("Legacy XTLS protocol %s is deprecated and no longer supported", option.Flow)
  448. default:
  449. return nil, fmt.Errorf("unsupported xtls flow type: %s", option.Flow)
  450. }
  451. }
  452. switch option.PacketEncoding {
  453. case "packetaddr", "packet":
  454. option.PacketAddr = true
  455. option.XUDP = false
  456. default: // https://github.com/XTLS/Xray-core/pull/1567#issuecomment-1407305458
  457. if !option.PacketAddr {
  458. option.XUDP = true
  459. }
  460. }
  461. if option.XUDP {
  462. option.PacketAddr = false
  463. }
  464. client, err := vless.NewClient(option.UUID, addons)
  465. if err != nil {
  466. return nil, err
  467. }
  468. v := &Vless{
  469. Base: &Base{
  470. name: option.Name,
  471. addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)),
  472. tp: C.Vless,
  473. udp: option.UDP,
  474. xudp: option.XUDP,
  475. tfo: option.TFO,
  476. mpTcp: option.MPTCP,
  477. iface: option.Interface,
  478. rmark: option.RoutingMark,
  479. prefer: C.NewDNSPrefer(option.IPVersion),
  480. },
  481. client: client,
  482. option: &option,
  483. }
  484. v.realityConfig, err = v.option.RealityOpts.Parse()
  485. if err != nil {
  486. return nil, err
  487. }
  488. switch option.Network {
  489. case "h2":
  490. if len(option.HTTP2Opts.Host) == 0 {
  491. option.HTTP2Opts.Host = append(option.HTTP2Opts.Host, "www.example.com")
  492. }
  493. case "grpc":
  494. dialFn := func(network, addr string) (net.Conn, error) {
  495. var err error
  496. var cDialer C.Dialer = dialer.NewDialer(v.Base.DialOptions()...)
  497. if len(v.option.DialerProxy) > 0 {
  498. cDialer, err = proxydialer.NewByName(v.option.DialerProxy, cDialer)
  499. if err != nil {
  500. return nil, err
  501. }
  502. }
  503. c, err := cDialer.DialContext(context.Background(), "tcp", v.addr)
  504. if err != nil {
  505. return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error())
  506. }
  507. N.TCPKeepAlive(c)
  508. return c, nil
  509. }
  510. gunConfig := &gun.Config{
  511. ServiceName: v.option.GrpcOpts.GrpcServiceName,
  512. Host: v.option.ServerName,
  513. ClientFingerprint: v.option.ClientFingerprint,
  514. }
  515. if option.ServerName == "" {
  516. gunConfig.Host = v.addr
  517. }
  518. var tlsConfig *tls.Config
  519. if option.TLS {
  520. tlsConfig = ca.GetGlobalTLSConfig(&tls.Config{
  521. InsecureSkipVerify: v.option.SkipCertVerify,
  522. ServerName: v.option.ServerName,
  523. })
  524. if option.ServerName == "" {
  525. host, _, _ := net.SplitHostPort(v.addr)
  526. tlsConfig.ServerName = host
  527. }
  528. }
  529. v.gunTLSConfig = tlsConfig
  530. v.gunConfig = gunConfig
  531. v.transport = gun.NewHTTP2Client(dialFn, tlsConfig, v.option.ClientFingerprint, v.realityConfig)
  532. }
  533. return v, nil
  534. }