基于go手动写个转发代理服务的代码实现

2020-01-28 13:45:36于丽

代码实现:


type Socks5Resolution struct {
  VER uint8
  CMD uint8
  RSV uint8
  ATYP uint8
  DSTADDR []byte
  DSTPORT uint16
  DSTDOMAIN string
  RAWADDR *net.TCPAddr
}

func (s *Socks5Resolution) lstRequest(conn net.Conn) error {
  b := make([]byte, 128)
  n, err := conn.Read(b)
  if err != nil || n < 7 {
    log.Println(err)
    return errors.New("请求协议错误")
  }
  s.VER = b[0]
  if s.VER != 5 {
    return errors.New("该协议不是socks5协议")
  }

  s.CMD = b[1]
  if s.CMD != 1 { 
    return errors.New("客户端请求类型不为代理连接, 其他功能暂时不支持.")
  }
  s.RSV = b[2] //RSV保留字端,值长度为1个字节

  s.ATYP = b[3]

  switch s.ATYP {
  case 1:
    // IP V4 address: X'01'
    s.DSTADDR = b[4 : 4+net.IPv4len]
  case 3:
    // DOMAINNAME: X'03'
    s.DSTDOMAIN = string(b[5:n-2])
    ipAddr, err := net.ResolveIPAddr("ip", s.DSTDOMAIN)
 if err != nil {
  return err
 }
    s.DSTADDR = ipAddr.IP
  case 4:
    // IP V6 address: X'04'
    s.DSTADDR = b[4 : 4+net.IPv6len]
 default:
 return errors.New("IP地址错误")
  }

  s.DSTPORT = binary.BigEndian.Uint16(b[n-2:n])
  // DSTADDR全部换成IP地址,可以防止DNS污染和封杀
  s.RAWADDR = &net.TCPAddr{
 IP:  s.DSTADDR,
 Port: int(s.DSTPORT),
  }
  
  /**
  回应客户端,响应客户端连接成功
    +----+-----+-------+------+----------+----------+
    |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
    +----+-----+-------+------+----------+----------+
    | 1 | 1 | X'00' | 1  | Variable |  2   |
    +----+-----+-------+------+----------+----------+
  */
 resp := []byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
  conn.Write(resp) 

  return nil
}

(4)最后将信息进行转发即可

代码实现:


  wg := new(sync.WaitGroup)
  wg.Add(2)

  go func() {
 defer wg.Done()
 defer dstServer.Close()
    io.Copy(dstServer, client)
  }()

  go func() {
 defer wg.Done()
    defer client.Close()
    io.Copy(client, dstServer)
  }()

  wg.Wait()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易采站长站。