client.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. package proxy
  2. import (
  3. "context"
  4. "errors"
  5. "log"
  6. "net"
  7. "net/url"
  8. "strconv"
  9. "time"
  10. "github.com/miekg/dns"
  11. "github.com/pion/transport/v2"
  12. "github.com/txthinking/socks5"
  13. )
  14. func NewSocks5UDPClient(addr *url.URL) SocksClient {
  15. return SocksClient{addr: addr}
  16. }
  17. type SocksClient struct {
  18. addr *url.URL
  19. }
  20. type SocksConn struct {
  21. net.Conn
  22. socks5Client *socks5.Client
  23. }
  24. func (s SocksConn) SetReadBuffer(bytes int) error {
  25. return nil
  26. }
  27. func (s SocksConn) SetWriteBuffer(bytes int) error {
  28. return nil
  29. }
  30. func (s SocksConn) ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) {
  31. var buf [2000]byte
  32. n, err = s.Conn.Read(buf[:])
  33. if err != nil {
  34. return 0, nil, err
  35. }
  36. Datagram, err := socks5.NewDatagramFromBytes(buf[:n])
  37. if err != nil {
  38. return 0, nil, err
  39. }
  40. addr, err = net.ResolveUDPAddr("udp", Datagram.Address())
  41. if err != nil {
  42. return 0, nil, err
  43. }
  44. n = copy(b, Datagram.Data)
  45. if n < len(Datagram.Data) {
  46. return 0, nil, errors.New("short buffer")
  47. }
  48. return len(Datagram.Data), addr, nil
  49. }
  50. func (s SocksConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error) {
  51. panic("unimplemented")
  52. }
  53. func (s SocksConn) WriteToUDP(b []byte, addr *net.UDPAddr) (int, error) {
  54. a, addrb, portb, err := socks5.ParseAddress(addr.String())
  55. if err != nil {
  56. return 0, err
  57. }
  58. packet := socks5.NewDatagram(a, addrb, portb, b)
  59. _, err = s.Conn.Write(packet.Bytes())
  60. if err != nil {
  61. return 0, err
  62. }
  63. return len(b), nil
  64. }
  65. func (s SocksConn) WriteMsgUDP(b, oob []byte, addr *net.UDPAddr) (n, oobn int, err error) {
  66. panic("unimplemented")
  67. }
  68. func (sc *SocksClient) ListenPacket(network string, locAddr *net.UDPAddr) (transport.UDPConn, error) {
  69. conn, err := sc.listenPacket()
  70. if err != nil {
  71. log.Println("[SOCKS5 Client Error] cannot listen packet", err)
  72. }
  73. return conn, err
  74. }
  75. func (sc *SocksClient) listenPacket() (transport.UDPConn, error) {
  76. var username, password string
  77. if sc.addr.User != nil {
  78. username = sc.addr.User.Username()
  79. password, _ = sc.addr.User.Password()
  80. }
  81. client, err := socks5.NewClient(
  82. sc.addr.Host,
  83. username, password, 300, 300)
  84. if err != nil {
  85. return nil, err
  86. }
  87. err = client.Negotiate(nil)
  88. if err != nil {
  89. return nil, err
  90. }
  91. udpRequest := socks5.NewRequest(socks5.CmdUDP, socks5.ATYPIPv4, []byte{0x00, 0x00, 0x00, 0x00}, []byte{0x00, 0x00})
  92. reply, err := client.Request(udpRequest)
  93. if err != nil {
  94. return nil, err
  95. }
  96. udpServerAddr := socks5.ToAddress(reply.Atyp, reply.BndAddr, reply.BndPort)
  97. conn, err := net.Dial("udp", udpServerAddr)
  98. if err != nil {
  99. return nil, err
  100. }
  101. return &SocksConn{conn, client}, nil
  102. }
  103. func (s SocksConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
  104. return s.WriteToUDP(p, addr.(*net.UDPAddr))
  105. }
  106. func (s SocksConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
  107. return s.ReadFromUDP(p)
  108. }
  109. func (s SocksConn) Read(b []byte) (int, error) {
  110. panic("implement me")
  111. }
  112. func (s SocksConn) RemoteAddr() net.Addr {
  113. panic("implement me")
  114. }
  115. func (s SocksConn) Write(b []byte) (int, error) {
  116. panic("implement me")
  117. }
  118. func (sc *SocksClient) ResolveUDPAddr(network string, address string) (*net.UDPAddr, error) {
  119. dnsServer, err := net.ResolveUDPAddr("udp", "1.1.1.1:53")
  120. if err != nil {
  121. return nil, err
  122. }
  123. proxiedResolver := newDnsResolver(sc, dnsServer)
  124. ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
  125. defer cancel()
  126. host, port, err := net.SplitHostPort(address)
  127. if err != nil {
  128. return nil, err
  129. }
  130. ip, err := proxiedResolver.lookupIPAddr(ctx, host, network == "udp6")
  131. if err != nil {
  132. return nil, err
  133. }
  134. if len(ip) <= 0 {
  135. return nil, errors.New("cannot resolve hostname: NXDOMAIN")
  136. }
  137. switch network {
  138. case "udp4":
  139. var v4IPAddr []net.IPAddr
  140. for _, v := range ip {
  141. if v.IP.To4() != nil {
  142. v4IPAddr = append(v4IPAddr, v)
  143. }
  144. }
  145. ip = v4IPAddr
  146. case "udp6":
  147. var v6IPAddr []net.IPAddr
  148. for _, v := range ip {
  149. if v.IP.To4() == nil {
  150. v6IPAddr = append(v6IPAddr, v)
  151. }
  152. }
  153. ip = v6IPAddr
  154. case "udp":
  155. default:
  156. return nil, errors.New("unknown network")
  157. }
  158. if len(ip) <= 0 {
  159. return nil, errors.New("cannot resolve hostname: so suitable address")
  160. }
  161. portInInt, err := strconv.ParseInt(port, 10, 32)
  162. return &net.UDPAddr{
  163. IP: ip[0].IP,
  164. Port: int(portInInt),
  165. Zone: "",
  166. }, nil
  167. }
  168. func newDnsResolver(sc *SocksClient,
  169. serverAddress net.Addr) *dnsResolver {
  170. return &dnsResolver{sc: sc, serverAddress: serverAddress}
  171. }
  172. type dnsResolver struct {
  173. sc *SocksClient
  174. serverAddress net.Addr
  175. }
  176. func (r *dnsResolver) lookupIPAddr(ctx context.Context, host string, ipv6 bool) ([]net.IPAddr, error) {
  177. packetConn, err := r.sc.listenPacket()
  178. if err != nil {
  179. return nil, err
  180. }
  181. msg := new(dns.Msg)
  182. if !ipv6 {
  183. msg.SetQuestion(dns.Fqdn(host), dns.TypeA)
  184. } else {
  185. msg.SetQuestion(dns.Fqdn(host), dns.TypeAAAA)
  186. }
  187. encodedMsg, err := msg.Pack()
  188. if err != nil {
  189. log.Println(err.Error())
  190. }
  191. for i := 2; i >= 0; i-- {
  192. _, err := packetConn.WriteTo(encodedMsg, r.serverAddress)
  193. if err != nil {
  194. log.Println(err.Error())
  195. }
  196. }
  197. ctx, cancel := context.WithTimeout(ctx, time.Second)
  198. defer cancel()
  199. go func() {
  200. <-ctx.Done()
  201. packetConn.Close()
  202. }()
  203. var dataBuf [1600]byte
  204. n, _, err := packetConn.ReadFrom(dataBuf[:])
  205. if err != nil {
  206. return nil, err
  207. }
  208. err = msg.Unpack(dataBuf[:n])
  209. if err != nil {
  210. return nil, err
  211. }
  212. var returnedIPs []net.IPAddr
  213. for _, resp := range msg.Answer {
  214. switch respTyped := resp.(type) {
  215. case *dns.A:
  216. returnedIPs = append(returnedIPs, net.IPAddr{IP: respTyped.A})
  217. case *dns.AAAA:
  218. returnedIPs = append(returnedIPs, net.IPAddr{IP: respTyped.AAAA})
  219. }
  220. }
  221. return returnedIPs, nil
  222. }
  223. func NewTransportWrapper(sc *SocksClient, innerNet transport.Net) transport.Net {
  224. return &transportWrapper{sc: sc, Net: innerNet}
  225. }
  226. type transportWrapper struct {
  227. transport.Net
  228. sc *SocksClient
  229. }
  230. func (t *transportWrapper) ListenUDP(network string, locAddr *net.UDPAddr) (transport.UDPConn, error) {
  231. return t.sc.ListenPacket(network, nil)
  232. }
  233. func (t *transportWrapper) ListenPacket(network string, address string) (net.PacketConn, error) {
  234. return t.sc.ListenPacket(network, nil)
  235. }
  236. func (t *transportWrapper) ResolveUDPAddr(network string, address string) (*net.UDPAddr, error) {
  237. return t.sc.ResolveUDPAddr(network, address)
  238. }