main.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. package yu_tcp
  2. import (
  3. yu_base64 "gogs.qqck.cn/s/tools/base64"
  4. yu_fast "gogs.qqck.cn/s/tools/fast"
  5. yu_proxy "gogs.qqck.cn/s/tools/proxy"
  6. yu_strconv "gogs.qqck.cn/s/tools/strconv"
  7. "net"
  8. "net/netip"
  9. )
  10. type Tcp struct {
  11. host string // IP 或 域名
  12. port int // 端口号
  13. proxy *yu_proxy.Info
  14. sec int32 // 超时时间,单位:秒
  15. usec int32 // 超时时间,单位:微妙
  16. fd uintptr // socket 句柄
  17. }
  18. // New
  19. //
  20. // @Description: 创建 Tcp 对象
  21. func New() (t *Tcp) {
  22. t = &Tcp{}
  23. t.SetSec(30)
  24. t.SetUsec(0)
  25. t.init()
  26. return
  27. }
  28. func (t *Tcp) SetHost(value string) *Tcp {
  29. t.host = value
  30. return t
  31. }
  32. func (t *Tcp) GetHost() string {
  33. return t.host
  34. }
  35. func (t *Tcp) SetPort(value int) *Tcp {
  36. t.port = value
  37. return t
  38. }
  39. func (t *Tcp) GetPort() int {
  40. return t.port
  41. }
  42. func (t *Tcp) SetProxy(value *yu_proxy.Info) *Tcp {
  43. t.proxy = value
  44. return t
  45. }
  46. func (t *Tcp) GetProxy() *yu_proxy.Info {
  47. return t.proxy
  48. }
  49. // SetSec
  50. //
  51. // @Description: 设置超时时间,单位:秒,默认:30 ,最终的超时时间是 sec 和 usec 的总和
  52. func (t *Tcp) SetSec(value int32) *Tcp {
  53. t.sec = value
  54. return t
  55. }
  56. func (t *Tcp) GetSec() int32 {
  57. return t.sec
  58. }
  59. // SetUsec
  60. //
  61. // @Description: 设置超时时间,单位:微秒,默认:0,最终的超时时间是 sec 和 usec 的总和
  62. func (t *Tcp) SetUsec(value int32) *Tcp {
  63. t.usec = value
  64. return t
  65. }
  66. func (t *Tcp) GetUsec() int32 {
  67. return t.usec
  68. }
  69. func (t *Tcp) Connect() bool {
  70. if t.proxy != nil && t.proxy.IsValid() {
  71. return t.content_proxy()
  72. }
  73. return t.connect(t.host, t.port)
  74. }
  75. func (t *Tcp) content_proxy() bool {
  76. if t.proxy.IsTimeout() {
  77. return false
  78. }
  79. if !t.connect(t.proxy.Host, t.proxy.Port) {
  80. return false
  81. }
  82. var j_addr netip.Addr
  83. var j_err error
  84. var j_doamin bool
  85. if j_addr, j_err = netip.ParseAddr(t.host); j_err != nil {
  86. j_addrs, j_err := net.LookupHost(t.host)
  87. if j_err != nil || len(j_addrs) == 0 {
  88. t.Close()
  89. return false
  90. }
  91. if j_addr, j_err = netip.ParseAddr(j_addrs[0]); j_err != nil {
  92. t.Close()
  93. return false
  94. }
  95. j_doamin = true
  96. }
  97. if t.proxy.IsHttp() {
  98. j_buf := make([]byte, 0, 256)
  99. j_buf = append(j_buf, "CONNECT "...)
  100. if t.proxy.Domain {
  101. j_buf = append(j_buf, t.host...)
  102. } else if j_addr.IsValid() {
  103. if j_addr.Is4() {
  104. j_buf = append(j_buf, j_addr.String()...)
  105. } else if j_addr.Is6() {
  106. j_buf = append(j_buf, '[')
  107. j_buf = append(j_buf, j_addr.String()...)
  108. j_buf = append(j_buf, ']')
  109. } else {
  110. t.Close()
  111. return false
  112. }
  113. } else {
  114. t.Close()
  115. return false
  116. }
  117. j_buf = append(j_buf, ':')
  118. j_buf = append(j_buf, yu_strconv.FormatInt(t.port)...)
  119. j_buf = append(j_buf, " HTTP/1.1\r\n"...)
  120. j_buf = append(j_buf, "Proxy-Connection: Keep-Alive"...)
  121. j_buf = append(j_buf, 13, 10)
  122. if t.proxy.IsAuthorization() {
  123. j_buf = append(j_buf, "Proxy-Authorization: Basic "...)
  124. j_buf = append(j_buf, yu_base64.Std.EncodeS2S(t.proxy.User+":"+t.proxy.Pass)...)
  125. j_buf = append(j_buf, 13, 10)
  126. }
  127. j_buf = append(j_buf, 13, 10)
  128. if !t.send(t.fd, j_buf) {
  129. t.Close()
  130. return false
  131. }
  132. if j_buf = t.recv(t.fd, 1024); len(j_buf) == 0 {
  133. t.Close()
  134. return false
  135. }
  136. // "HTTP/1.1 200 Connection Established"、"HTTP/1.1 200 Connection established"
  137. // HTTP/1.0 200 OK
  138. if len(j_buf) < 36 || yu_fast.B2S(j_buf[9:12]) != "200" {
  139. t.Close()
  140. return false
  141. }
  142. switch yu_fast.B2S(j_buf[13:35]) {
  143. case "Connection Established", "Connection established", "connection Established", "connection established":
  144. default:
  145. t.Close()
  146. return false
  147. }
  148. return true
  149. }
  150. if t.proxy.IsSocks5() {
  151. // https://zhuanlan.zhihu.com/p/458173597?utm_id=0
  152. // https://www.jianshu.com/p/97873541510f
  153. j_buf := make([]byte, 0, 256)
  154. j_buf = append(j_buf, 5) // VER 协议版本号
  155. j_buf = append(j_buf, 1) // NMETHODS 客户端支持的认证方法数量
  156. // X'00' 不需要身份验证(NO AUTHENTICATION REQUIRED)
  157. // X'01' GSSAPI
  158. // X'02' 用户密码认证(USERNAME/PASSWORD)
  159. // X'03' to X'7F' IANA ASSIGNED
  160. // X'80' to X'FE' RESERVED FOR PRIVATE METHODS
  161. if t.proxy.IsAuthorization() {
  162. j_buf = append(j_buf, 0x02) // METHODS:认证方法
  163. } else {
  164. j_buf = append(j_buf, 0x00) // METHODS:认证方法
  165. }
  166. if !t.send(t.fd, j_buf) {
  167. t.Close()
  168. return false
  169. }
  170. if j_buf = t.recv(t.fd, 1024); len(j_buf) == 0 {
  171. t.Close()
  172. return false
  173. }
  174. if len(j_buf) != 2 || j_buf[0] != 5 {
  175. t.Close()
  176. return false
  177. }
  178. if j_buf[1] == 0x02 {
  179. j_buf = append(j_buf[0:0], 1) // VERSION 认证子协商版本(与SOCKS协议版本的0x05无关系)
  180. j_buf = append(j_buf, byte(len(t.proxy.User)))
  181. j_buf = append(j_buf, t.proxy.User...)
  182. j_buf = append(j_buf, byte(len(t.proxy.Pass)))
  183. j_buf = append(j_buf, t.proxy.Pass...)
  184. if !t.send(t.fd, j_buf) {
  185. t.Close()
  186. return false
  187. }
  188. if j_buf = t.recv(t.fd, 1024); len(j_buf) == 0 {
  189. t.Close()
  190. return false
  191. }
  192. if len(j_buf) != 2 || (j_buf[0] != 1 && j_buf[0] != 5) || j_buf[1] != 0 {
  193. t.Close()
  194. return false
  195. }
  196. } else if j_buf[1] != 0x00 {
  197. t.Close()
  198. return false
  199. }
  200. j_buf = append(j_buf[0:0], 5) // VER 协议版本号
  201. j_buf = append(j_buf, 0x01) // 0x01 CONNECT 连接目标服务器
  202. j_buf = append(j_buf, 0) // RSV 保留字段
  203. if t.proxy.Domain && j_doamin {
  204. j_buf = append(j_buf, 0x03) // 0x03 域名地址(没有打错,就是没有0x02),域名地址的第1个字节为域名长度,剩下字节为域名名称字节数组
  205. j_buf = append(j_buf, byte(len(t.host)))
  206. j_buf = append(j_buf, t.host...)
  207. } else if j_addr.IsValid() {
  208. if j_addr.Is4() {
  209. j_buf = append(j_buf, 0x01) // 0x01 IP V4地址
  210. } else if j_addr.Is6() {
  211. j_buf = append(j_buf, 0x04) // 0x04 IP V6地址
  212. } else {
  213. t.Close()
  214. return false
  215. }
  216. j_buf = append(j_buf, j_addr.AsSlice()...)
  217. } else {
  218. t.Close()
  219. return false
  220. }
  221. j_buf = append(j_buf, byte(t.port>>8), byte(t.port))
  222. if !t.send(t.fd, j_buf) {
  223. t.Close()
  224. return false
  225. }
  226. if j_buf = t.recv(t.fd, 1024); len(j_buf) == 0 {
  227. t.Close()
  228. return false
  229. }
  230. if len(j_buf) < 10 || j_buf[0] != 5 || j_buf[1] != 0 || j_buf[2] != 0 {
  231. t.Close()
  232. return false
  233. }
  234. return true
  235. }
  236. return true
  237. }
  238. func (t *Tcp) Send(buf []byte) bool {
  239. return t.send(t.fd, buf)
  240. }
  241. func (t *Tcp) Recv(size int) []byte {
  242. return t.recv(t.fd, size)
  243. }
  244. type Pack byte
  245. const (
  246. // PackV1 头四字节包含长度信息(包含长度信息自身的四字节),长度信息为高位字序,如: 00 00 00 09 11 22 33 44 55
  247. PackV1 Pack = iota
  248. )
  249. func (t *Tcp) SendPack(v Pack, buf []byte) bool {
  250. switch v {
  251. case PackV1:
  252. j_buf := make([]byte, len(buf)+4)
  253. j_buf[0] = byte(len(j_buf) >> 24)
  254. j_buf[1] = byte(len(j_buf) >> 16)
  255. j_buf[2] = byte(len(j_buf) >> 8)
  256. j_buf[3] = byte(len(j_buf))
  257. copy(j_buf[4:], buf)
  258. return t.send(t.fd, j_buf)
  259. default:
  260. return false
  261. }
  262. }
  263. // RecvPack
  264. //
  265. // @Description: 如果接收失败返回 nil ,如果接收成功但数据包体长度为 0 返回 make([]byte, 0)
  266. func (t *Tcp) RecvPack(v Pack) []byte {
  267. switch v {
  268. case PackV1:
  269. var j_buf = make([]byte, 0, 4)
  270. for len(j_buf) != cap(j_buf) {
  271. j_tmp := t.recv(t.fd, cap(j_buf)-len(j_buf))
  272. if len(j_tmp) == 0 {
  273. return nil
  274. }
  275. j_buf = append(j_buf, j_tmp...)
  276. }
  277. j_size := int(int32(j_buf[3]) | int32(j_buf[2])<<8 | int32(j_buf[1])<<16 | int32(j_buf[0])<<24)
  278. j_size -= 4
  279. if j_size < 0 {
  280. return nil
  281. }
  282. j_buf = make([]byte, 0, j_size)
  283. for len(j_buf) != cap(j_buf) {
  284. j_tmp := t.recv(t.fd, cap(j_buf)-len(j_buf))
  285. if len(j_tmp) == 0 {
  286. return nil
  287. }
  288. j_buf = append(j_buf, j_tmp...)
  289. }
  290. return j_buf
  291. default:
  292. return nil
  293. }
  294. }
  295. func (t *Tcp) Close() *Tcp {
  296. t.close()
  297. return t
  298. }