tun.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. //go:build android
  2. package tun
  3. import "C"
  4. import (
  5. "context"
  6. "encoding/binary"
  7. "github.com/Kr328/tun2socket"
  8. "github.com/Kr328/tun2socket/nat"
  9. "github.com/metacubex/mihomo/adapter/inbound"
  10. "github.com/metacubex/mihomo/common/pool"
  11. "github.com/metacubex/mihomo/constant"
  12. "github.com/metacubex/mihomo/log"
  13. "github.com/metacubex/mihomo/transport/socks5"
  14. "github.com/metacubex/mihomo/tunnel"
  15. "golang.org/x/sync/semaphore"
  16. "io"
  17. "net"
  18. "os"
  19. "time"
  20. )
  21. type Tun struct {
  22. Closer io.Closer
  23. Closed bool
  24. Limit *semaphore.Weighted
  25. }
  26. func (t *Tun) Close() {
  27. _ = t.Limit.Acquire(context.TODO(), 4)
  28. defer t.Limit.Release(4)
  29. t.Closed = true
  30. if t.Closer != nil {
  31. _ = t.Closer.Close()
  32. }
  33. }
  34. var _, ipv4LoopBack, _ = net.ParseCIDR("127.0.0.0/8")
  35. func Start(fd int, gateway, portal, dns string) (io.Closer, error) {
  36. device := os.NewFile(uintptr(fd), "/dev/tun")
  37. ip, network, err := net.ParseCIDR(gateway)
  38. if err != nil {
  39. panic(err.Error())
  40. } else {
  41. network.IP = ip
  42. }
  43. stack, err := tun2socket.StartTun2Socket(device, network, net.ParseIP(portal))
  44. if err != nil {
  45. _ = device.Close()
  46. return nil, err
  47. }
  48. dnsAddr := net.ParseIP(dns)
  49. tcp := func() {
  50. defer func(tcp *nat.TCP) {
  51. _ = tcp.Close()
  52. }(stack.TCP())
  53. defer log.Debugln("TCP: closed")
  54. for stack.TCP().SetDeadline(time.Time{}) == nil {
  55. conn, err := stack.TCP().Accept()
  56. if err != nil {
  57. continue
  58. }
  59. lAddr := conn.LocalAddr().(*net.TCPAddr)
  60. rAddr := conn.RemoteAddr().(*net.TCPAddr)
  61. if ipv4LoopBack.Contains(rAddr.IP) {
  62. _ = conn.Close()
  63. continue
  64. }
  65. if shouldHijackDns(dnsAddr, rAddr.IP, rAddr.Port) {
  66. go func() {
  67. defer func(conn net.Conn) {
  68. _ = conn.Close()
  69. }(conn)
  70. buf := pool.Get(pool.UDPBufferSize)
  71. defer func(buf []byte) {
  72. _ = pool.Put(buf)
  73. }(buf)
  74. for {
  75. _ = conn.SetReadDeadline(time.Now().Add(constant.DefaultTCPTimeout))
  76. length := uint16(0)
  77. if err := binary.Read(conn, binary.BigEndian, &length); err != nil {
  78. return
  79. }
  80. if int(length) > len(buf) {
  81. return
  82. }
  83. n, err := conn.Read(buf[:length])
  84. if err != nil {
  85. return
  86. }
  87. msg, err := relayDns(buf[:n])
  88. if err != nil {
  89. return
  90. }
  91. _, _ = conn.Write(msg)
  92. }
  93. }()
  94. continue
  95. }
  96. go tunnel.Tunnel.HandleTCPConn(conn, createMetadata(lAddr, rAddr))
  97. }
  98. }
  99. udp := func() {
  100. defer func(udp *nat.UDP) {
  101. _ = udp.Close()
  102. }(stack.UDP())
  103. defer log.Debugln("UDP: closed")
  104. for {
  105. buf := pool.Get(pool.UDPBufferSize)
  106. n, lRAddr, rRAddr, err := stack.UDP().ReadFrom(buf)
  107. if err != nil {
  108. return
  109. }
  110. raw := buf[:n]
  111. lAddr := lRAddr.(*net.UDPAddr)
  112. rAddr := rRAddr.(*net.UDPAddr)
  113. if ipv4LoopBack.Contains(rAddr.IP) {
  114. _ = pool.Put(buf)
  115. continue
  116. }
  117. if shouldHijackDns(dnsAddr, rAddr.IP, rAddr.Port) {
  118. go func() {
  119. defer func(buf []byte) {
  120. _ = pool.Put(buf)
  121. }(buf)
  122. msg, err := relayDns(raw)
  123. if err != nil {
  124. return
  125. }
  126. _, _ = stack.UDP().WriteTo(msg, rAddr, lAddr)
  127. }()
  128. continue
  129. }
  130. pkt := &packet{
  131. local: lAddr,
  132. data: raw,
  133. writeBack: func(b []byte, addr net.Addr) (int, error) {
  134. return stack.UDP().WriteTo(b, addr, lAddr)
  135. },
  136. drop: func() {
  137. _ = pool.Put(buf)
  138. },
  139. }
  140. tunnel.Tunnel.HandleUDPPacket(inbound.NewPacket(socks5.ParseAddrToSocksAddr(rAddr), pkt, constant.SOCKS5))
  141. }
  142. }
  143. go tcp()
  144. go udp()
  145. return stack, nil
  146. }