client_windows_extend.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. //go:build windows
  2. package yu_hpsocket
  3. import (
  4. yu_base64 "gogs.qqck.cn/s/tools/base64"
  5. yu_fast "gogs.qqck.cn/s/tools/fast"
  6. yu_proxy "gogs.qqck.cn/s/tools/proxy"
  7. yu_strconv "gogs.qqck.cn/s/tools/strconv"
  8. yu_sys "gogs.qqck.cn/s/tools/sys"
  9. "net"
  10. "net/netip"
  11. )
  12. // SetProxy
  13. //
  14. // @Description: 设置代理
  15. func (t *Client[T]) SetProxy(info *yu_proxy.Info) {
  16. t.proxy_info = info
  17. return
  18. }
  19. // DelProxy
  20. //
  21. // @Description: 清除代理
  22. func (t *Client[T]) DelProxy() {
  23. t.proxy_info.Host = ""
  24. t.proxy_info.User = ""
  25. t.proxy_info.Pass = ""
  26. t.proxy_info.Type = 0
  27. t.proxy_info.Timeout = 0
  28. return
  29. }
  30. func (t *Client[T]) connect_proxy() bool {
  31. var j_addr netip.Addr
  32. var j_err error
  33. var j_doamin bool
  34. if j_addr, j_err = netip.ParseAddr(t._RemoteAddress); j_err != nil {
  35. j_addrs, j_err := net.LookupHost(t._RemoteAddress)
  36. if j_err != nil || len(j_addrs) == 0 {
  37. t.Stop()
  38. return false
  39. }
  40. if j_addr, j_err = netip.ParseAddr(j_addrs[0]); j_err != nil {
  41. t.Stop()
  42. return false
  43. }
  44. j_doamin = true
  45. }
  46. if t.proxy_info.IsHttp() {
  47. j_buf := make([]byte, 0, 256)
  48. j_buf = append(j_buf, "CONNECT "...)
  49. if t.proxy_info.Domain {
  50. j_buf = append(j_buf, t._RemoteAddress...)
  51. } else if j_addr.IsValid() {
  52. if j_addr.Is4() {
  53. j_buf = append(j_buf, j_addr.String()...)
  54. } else if j_addr.Is6() {
  55. j_buf = append(j_buf, '[')
  56. j_buf = append(j_buf, j_addr.String()...)
  57. j_buf = append(j_buf, ']')
  58. } else {
  59. t.Stop()
  60. return false
  61. }
  62. } else {
  63. t.Stop()
  64. return false
  65. }
  66. j_buf = append(j_buf, ':')
  67. j_buf = append(j_buf, yu_strconv.FormatInt(t._Port)...)
  68. j_buf = append(j_buf, " HTTP/1.1\r\n"...)
  69. j_buf = append(j_buf, "Proxy-Connection: Keep-Alive"...)
  70. j_buf = append(j_buf, 13, 10)
  71. if t.proxy_info.IsAuthorization() {
  72. j_buf = append(j_buf, "Proxy-Authorization: Basic "...)
  73. j_buf = append(j_buf, yu_base64.Std.EncodeS2S(t.proxy_info.User+":"+t.proxy_info.Pass)...)
  74. j_buf = append(j_buf, 13, 10)
  75. }
  76. j_buf = append(j_buf, 13, 10)
  77. if !yu_sys.Socket_write_tcp(t.socket, j_buf, 30, 0) {
  78. t.Stop()
  79. return false
  80. }
  81. if j_buf = yu_sys.Socket_read_tcp(t.socket, 1024, 30, 0); len(j_buf) == 0 {
  82. t.Stop()
  83. return false
  84. }
  85. // "HTTP/1.1 200 Connection Established"、"HTTP/1.1 200 Connection established"
  86. // HTTP/1.0 200 OK
  87. if len(j_buf) < 36 || yu_fast.B2S(j_buf[9:12]) != "200" {
  88. t.Stop()
  89. return false
  90. }
  91. switch yu_fast.B2S(j_buf[13:35]) {
  92. case "Connection Established", "Connection established", "connection Established", "connection established":
  93. default:
  94. t.Stop()
  95. return false
  96. }
  97. return true
  98. }
  99. if t.proxy_info.IsSocks5() {
  100. // https://zhuanlan.zhihu.com/p/458173597?utm_id=0
  101. // https://www.jianshu.com/p/97873541510f
  102. j_buf := make([]byte, 0, 256)
  103. j_buf = append(j_buf, 5) // VER 协议版本号
  104. j_buf = append(j_buf, 1) // NMETHODS 客户端支持的认证方法数量
  105. // X'00' 不需要身份验证(NO AUTHENTICATION REQUIRED)
  106. // X'01' GSSAPI
  107. // X'02' 用户密码认证(USERNAME/PASSWORD)
  108. // X'03' to X'7F' IANA ASSIGNED
  109. // X'80' to X'FE' RESERVED FOR PRIVATE METHODS
  110. if t.proxy_info.IsAuthorization() {
  111. j_buf = append(j_buf, 0x02) // METHODS:认证方法
  112. } else {
  113. j_buf = append(j_buf, 0x00) // METHODS:认证方法
  114. }
  115. if !yu_sys.Socket_write_tcp(t.socket, j_buf, 30, 0) {
  116. t.Stop()
  117. return false
  118. }
  119. if j_buf = yu_sys.Socket_read_tcp(t.socket, 1024, 30, 0); len(j_buf) == 0 {
  120. t.Stop()
  121. return false
  122. }
  123. if len(j_buf) != 2 || j_buf[0] != 5 {
  124. t.Stop()
  125. return false
  126. }
  127. if j_buf[1] == 0x02 {
  128. j_buf = append(j_buf[0:0], 1) // VERSION 认证子协商版本(与SOCKS协议版本的0x05无关系)
  129. j_buf = append(j_buf, byte(len(t.proxy_info.User)))
  130. j_buf = append(j_buf, t.proxy_info.User...)
  131. j_buf = append(j_buf, byte(len(t.proxy_info.Pass)))
  132. j_buf = append(j_buf, t.proxy_info.Pass...)
  133. if !yu_sys.Socket_write_tcp(t.socket, j_buf, 30, 0) {
  134. t.Stop()
  135. return false
  136. }
  137. if j_buf = yu_sys.Socket_read_tcp(t.socket, 1024, 30, 0); len(j_buf) == 0 {
  138. t.Stop()
  139. return false
  140. }
  141. if len(j_buf) != 2 || (j_buf[0] != 1 && j_buf[0] != 5) || j_buf[1] != 0 {
  142. t.Stop()
  143. return false
  144. }
  145. } else if j_buf[1] != 0x00 {
  146. t.Stop()
  147. return false
  148. }
  149. j_buf = append(j_buf[0:0], 5) // VER 协议版本号
  150. j_buf = append(j_buf, 0x01) // 0x01 CONNECT 连接目标服务器
  151. j_buf = append(j_buf, 0) // RSV 保留字段
  152. if t.proxy_info.Domain && j_doamin {
  153. j_buf = append(j_buf, 0x03) // 0x03 域名地址(没有打错,就是没有0x02),域名地址的第1个字节为域名长度,剩下字节为域名名称字节数组
  154. j_buf = append(j_buf, byte(len(t._RemoteAddress)))
  155. j_buf = append(j_buf, t._RemoteAddress...)
  156. } else if j_addr.IsValid() {
  157. if j_addr.Is4() {
  158. j_buf = append(j_buf, 0x01) // 0x01 IP V4地址
  159. } else if j_addr.Is6() {
  160. j_buf = append(j_buf, 0x04) // 0x04 IP V6地址
  161. } else {
  162. t.Stop()
  163. return false
  164. }
  165. j_buf = append(j_buf, j_addr.AsSlice()...)
  166. } else {
  167. t.Stop()
  168. return false
  169. }
  170. j_buf = append(j_buf, byte(t._Port>>8), byte(t._Port))
  171. if !yu_sys.Socket_write_tcp(t.socket, j_buf, 30, 0) {
  172. t.Stop()
  173. return false
  174. }
  175. if j_buf = yu_sys.Socket_read_tcp(t.socket, 1024, 30, 0); len(j_buf) == 0 {
  176. t.Stop()
  177. return false
  178. }
  179. if len(j_buf) < 10 || j_buf[0] != 5 || j_buf[1] != 0 || j_buf[2] != 0 {
  180. t.Stop()
  181. return false
  182. }
  183. return true
  184. }
  185. t.Stop()
  186. return false
  187. }