123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- package yu_tcp
- import (
- yu_base64 "gogs.qqck.cn/s/tools/base64"
- yu_fast "gogs.qqck.cn/s/tools/fast"
- yu_proxy "gogs.qqck.cn/s/tools/proxy"
- yu_strconv "gogs.qqck.cn/s/tools/strconv"
- "net"
- "net/netip"
- )
- type Tcp struct {
- host string // IP 或 域名
- port int // 端口号
- proxy *yu_proxy.Info
- sec int32 // 超时时间,单位:秒
- usec int32 // 超时时间,单位:微妙
- fd uintptr // socket 句柄
- }
- // New
- //
- // @Description: 创建 Tcp 对象
- func New() (t *Tcp) {
- t = &Tcp{}
- t.SetSec(30)
- t.SetUsec(0)
- t.init()
- return
- }
- func (t *Tcp) SetHost(value string) *Tcp {
- t.host = value
- return t
- }
- func (t *Tcp) GetHost() string {
- return t.host
- }
- func (t *Tcp) SetPort(value int) *Tcp {
- t.port = value
- return t
- }
- func (t *Tcp) GetPort() int {
- return t.port
- }
- func (t *Tcp) SetProxy(value *yu_proxy.Info) *Tcp {
- t.proxy = value
- return t
- }
- func (t *Tcp) GetProxy() *yu_proxy.Info {
- return t.proxy
- }
- // SetSec
- //
- // @Description: 设置超时时间,单位:秒,默认:30 ,最终的超时时间是 sec 和 usec 的总和
- func (t *Tcp) SetSec(value int32) *Tcp {
- t.sec = value
- return t
- }
- func (t *Tcp) GetSec() int32 {
- return t.sec
- }
- // SetUsec
- //
- // @Description: 设置超时时间,单位:微秒,默认:0,最终的超时时间是 sec 和 usec 的总和
- func (t *Tcp) SetUsec(value int32) *Tcp {
- t.usec = value
- return t
- }
- func (t *Tcp) GetUsec() int32 {
- return t.usec
- }
- func (t *Tcp) Connect() bool {
- if t.proxy != nil && t.proxy.IsValid() {
- return t.content_proxy()
- }
- return t.connect(t.host, t.port)
- }
- func (t *Tcp) content_proxy() bool {
- if t.proxy.IsTimeout() {
- return false
- }
- if !t.connect(t.proxy.Host, t.proxy.Port) {
- return false
- }
- var j_addr netip.Addr
- var j_err error
- var j_doamin bool
- if j_addr, j_err = netip.ParseAddr(t.host); j_err != nil {
- j_addrs, j_err := net.LookupHost(t.host)
- if j_err != nil || len(j_addrs) == 0 {
- t.Close()
- return false
- }
- if j_addr, j_err = netip.ParseAddr(j_addrs[0]); j_err != nil {
- t.Close()
- return false
- }
- j_doamin = true
- }
- if t.proxy.IsHttp() {
- j_buf := make([]byte, 0, 256)
- j_buf = append(j_buf, "CONNECT "...)
- if t.proxy.Domain {
- j_buf = append(j_buf, t.host...)
- } else if j_addr.IsValid() {
- if j_addr.Is4() {
- j_buf = append(j_buf, j_addr.String()...)
- } else if j_addr.Is6() {
- j_buf = append(j_buf, '[')
- j_buf = append(j_buf, j_addr.String()...)
- j_buf = append(j_buf, ']')
- } else {
- t.Close()
- return false
- }
- } else {
- t.Close()
- return false
- }
- j_buf = append(j_buf, ':')
- j_buf = append(j_buf, yu_strconv.FormatInt(t.port)...)
- j_buf = append(j_buf, " HTTP/1.1\r\n"...)
- j_buf = append(j_buf, "Proxy-Connection: Keep-Alive"...)
- j_buf = append(j_buf, 13, 10)
- if t.proxy.IsAuthorization() {
- j_buf = append(j_buf, "Proxy-Authorization: Basic "...)
- j_buf = append(j_buf, yu_base64.Std.EncodeS2S(t.proxy.User+":"+t.proxy.Pass)...)
- j_buf = append(j_buf, 13, 10)
- }
- j_buf = append(j_buf, 13, 10)
- if !t.send(t.fd, j_buf) {
- t.Close()
- return false
- }
- if j_buf = t.recv(t.fd, 1024); len(j_buf) == 0 {
- t.Close()
- return false
- }
- // "HTTP/1.1 200 Connection Established"、"HTTP/1.1 200 Connection established"
- // HTTP/1.0 200 OK
- if len(j_buf) < 36 || yu_fast.B2S(j_buf[9:12]) != "200" {
- t.Close()
- return false
- }
- switch yu_fast.B2S(j_buf[13:35]) {
- case "Connection Established", "Connection established", "connection Established", "connection established":
- default:
- t.Close()
- return false
- }
- return true
- }
- if t.proxy.IsSocks5() {
- // https://zhuanlan.zhihu.com/p/458173597?utm_id=0
- // https://www.jianshu.com/p/97873541510f
- j_buf := make([]byte, 0, 256)
- j_buf = append(j_buf, 5) // VER 协议版本号
- j_buf = append(j_buf, 1) // NMETHODS 客户端支持的认证方法数量
- // X'00' 不需要身份验证(NO AUTHENTICATION REQUIRED)
- // X'01' GSSAPI
- // X'02' 用户密码认证(USERNAME/PASSWORD)
- // X'03' to X'7F' IANA ASSIGNED
- // X'80' to X'FE' RESERVED FOR PRIVATE METHODS
- if t.proxy.IsAuthorization() {
- j_buf = append(j_buf, 0x02) // METHODS:认证方法
- } else {
- j_buf = append(j_buf, 0x00) // METHODS:认证方法
- }
- if !t.send(t.fd, j_buf) {
- t.Close()
- return false
- }
- if j_buf = t.recv(t.fd, 1024); len(j_buf) == 0 {
- t.Close()
- return false
- }
- if len(j_buf) != 2 || j_buf[0] != 5 {
- t.Close()
- return false
- }
- if j_buf[1] == 0x02 {
- j_buf = append(j_buf[0:0], 1) // VERSION 认证子协商版本(与SOCKS协议版本的0x05无关系)
- j_buf = append(j_buf, byte(len(t.proxy.User)))
- j_buf = append(j_buf, t.proxy.User...)
- j_buf = append(j_buf, byte(len(t.proxy.Pass)))
- j_buf = append(j_buf, t.proxy.Pass...)
- if !t.send(t.fd, j_buf) {
- t.Close()
- return false
- }
- if j_buf = t.recv(t.fd, 1024); len(j_buf) == 0 {
- t.Close()
- return false
- }
- if len(j_buf) != 2 || (j_buf[0] != 1 && j_buf[0] != 5) || j_buf[1] != 0 {
- t.Close()
- return false
- }
- } else if j_buf[1] != 0x00 {
- t.Close()
- return false
- }
- j_buf = append(j_buf[0:0], 5) // VER 协议版本号
- j_buf = append(j_buf, 0x01) // 0x01 CONNECT 连接目标服务器
- j_buf = append(j_buf, 0) // RSV 保留字段
- if t.proxy.Domain && j_doamin {
- j_buf = append(j_buf, 0x03) // 0x03 域名地址(没有打错,就是没有0x02),域名地址的第1个字节为域名长度,剩下字节为域名名称字节数组
- j_buf = append(j_buf, byte(len(t.host)))
- j_buf = append(j_buf, t.host...)
- } else if j_addr.IsValid() {
- if j_addr.Is4() {
- j_buf = append(j_buf, 0x01) // 0x01 IP V4地址
- } else if j_addr.Is6() {
- j_buf = append(j_buf, 0x04) // 0x04 IP V6地址
- } else {
- t.Close()
- return false
- }
- j_buf = append(j_buf, j_addr.AsSlice()...)
- } else {
- t.Close()
- return false
- }
- j_buf = append(j_buf, byte(t.port>>8), byte(t.port))
- if !t.send(t.fd, j_buf) {
- t.Close()
- return false
- }
- if j_buf = t.recv(t.fd, 1024); len(j_buf) == 0 {
- t.Close()
- return false
- }
- if len(j_buf) < 10 || j_buf[0] != 5 || j_buf[1] != 0 || j_buf[2] != 0 {
- t.Close()
- return false
- }
- return true
- }
- return true
- }
- func (t *Tcp) Send(buf []byte) bool {
- return t.send(t.fd, buf)
- }
- func (t *Tcp) Recv(size int) []byte {
- return t.recv(t.fd, size)
- }
- type Pack byte
- const (
- // PackV1 头四字节包含长度信息(包含长度信息自身的四字节),长度信息为高位字序,如: 00 00 00 09 11 22 33 44 55
- PackV1 Pack = iota
- )
- func (t *Tcp) SendPack(v Pack, buf []byte) bool {
- switch v {
- case PackV1:
- j_buf := make([]byte, len(buf)+4)
- j_buf[0] = byte(len(j_buf) >> 24)
- j_buf[1] = byte(len(j_buf) >> 16)
- j_buf[2] = byte(len(j_buf) >> 8)
- j_buf[3] = byte(len(j_buf))
- copy(j_buf[4:], buf)
- return t.send(t.fd, j_buf)
- default:
- return false
- }
- }
- // RecvPack
- //
- // @Description: 如果接收失败返回 nil ,如果接收成功但数据包体长度为 0 返回 make([]byte, 0)
- func (t *Tcp) RecvPack(v Pack) []byte {
- switch v {
- case PackV1:
- var j_buf = make([]byte, 0, 4)
- for len(j_buf) != cap(j_buf) {
- j_tmp := t.recv(t.fd, cap(j_buf)-len(j_buf))
- if len(j_tmp) == 0 {
- return nil
- }
- j_buf = append(j_buf, j_tmp...)
- }
- j_size := int(int32(j_buf[3]) | int32(j_buf[2])<<8 | int32(j_buf[1])<<16 | int32(j_buf[0])<<24)
- j_size -= 4
- if j_size < 0 {
- return nil
- }
- j_buf = make([]byte, 0, j_size)
- for len(j_buf) != cap(j_buf) {
- j_tmp := t.recv(t.fd, cap(j_buf)-len(j_buf))
- if len(j_tmp) == 0 {
- return nil
- }
- j_buf = append(j_buf, j_tmp...)
- }
- return j_buf
- default:
- return nil
- }
- }
- func (t *Tcp) Close() *Tcp {
- t.close()
- return t
- }
|