2018-11-04 15:19:22 +00:00
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"io/ioutil"
|
|
|
|
|
"log"
|
|
|
|
|
"net"
|
|
|
|
|
"net/http"
|
|
|
|
|
)
|
|
|
|
|
|
2018-11-29 11:55:24 +00:00
|
|
|
|
const (
|
|
|
|
|
VERIFY_EER = "vkey"
|
|
|
|
|
WORK_MAIN = "main"
|
|
|
|
|
WORK_CHAN = "chan"
|
|
|
|
|
RES_SIGN = "sign"
|
|
|
|
|
RES_MSG = "msg0"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type HttpModeServer struct {
|
|
|
|
|
Tunnel
|
2018-11-04 15:19:22 +00:00
|
|
|
|
httpPort int
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-29 11:55:24 +00:00
|
|
|
|
func NewHttpModeServer(tcpPort, httpPort int) *HttpModeServer {
|
|
|
|
|
s := new(HttpModeServer)
|
|
|
|
|
s.tunnelPort = tcpPort
|
2018-11-04 15:19:22 +00:00
|
|
|
|
s.httpPort = httpPort
|
2018-11-29 11:55:24 +00:00
|
|
|
|
s.signalList = make(chan *Conn, 1000)
|
2018-11-04 15:19:22 +00:00
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-29 11:55:24 +00:00
|
|
|
|
//开始
|
|
|
|
|
func (s *HttpModeServer) Start() (error) {
|
|
|
|
|
err := s.StartTunnel()
|
2018-11-04 15:19:22 +00:00
|
|
|
|
if err != nil {
|
2018-11-29 11:55:24 +00:00
|
|
|
|
log.Fatalln("开启客户端失败!", err)
|
2018-11-04 15:19:22 +00:00
|
|
|
|
return err
|
|
|
|
|
}
|
2018-11-29 11:55:24 +00:00
|
|
|
|
s.startHttpServer()
|
|
|
|
|
return nil
|
2018-11-04 15:19:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-11-29 11:55:24 +00:00
|
|
|
|
//开启http端口监听
|
|
|
|
|
func (s *HttpModeServer) startHttpServer() {
|
2018-11-04 15:19:22 +00:00
|
|
|
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
retry:
|
2018-11-29 11:55:24 +00:00
|
|
|
|
if len(s.signalList) == 0 {
|
|
|
|
|
BadRequest(w)
|
2018-11-04 15:19:22 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
2018-11-29 11:55:24 +00:00
|
|
|
|
conn := <-s.signalList
|
|
|
|
|
if err := s.writeRequest(r, conn); err != nil {
|
2018-11-04 15:19:22 +00:00
|
|
|
|
log.Println(err)
|
|
|
|
|
conn.Close()
|
|
|
|
|
goto retry
|
|
|
|
|
return
|
|
|
|
|
}
|
2018-11-29 11:55:24 +00:00
|
|
|
|
err = s.writeResponse(w, conn)
|
2018-11-04 15:19:22 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
log.Println(err)
|
|
|
|
|
conn.Close()
|
|
|
|
|
goto retry
|
|
|
|
|
return
|
|
|
|
|
}
|
2018-11-29 11:55:24 +00:00
|
|
|
|
s.signalList <- conn
|
2018-11-04 15:19:22 +00:00
|
|
|
|
})
|
|
|
|
|
log.Fatalln(http.ListenAndServe(fmt.Sprintf(":%d", s.httpPort), nil))
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-29 11:55:24 +00:00
|
|
|
|
//req转为bytes发送给client端
|
|
|
|
|
func (s *HttpModeServer) writeRequest(r *http.Request, conn *Conn) error {
|
2018-11-04 15:19:22 +00:00
|
|
|
|
raw, err := EncodeRequest(r)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2018-12-03 15:03:25 +00:00
|
|
|
|
conn.wSign()
|
|
|
|
|
c, err := conn.WriteCompress(raw, DataEncode)
|
2018-11-04 15:19:22 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if c != len(raw) {
|
|
|
|
|
return errors.New("写出长度与字节长度不一致。")
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-29 11:55:24 +00:00
|
|
|
|
//从client读取出Response
|
|
|
|
|
func (s *HttpModeServer) writeResponse(w http.ResponseWriter, c *Conn) error {
|
|
|
|
|
flags, err := c.ReadFlag()
|
2018-11-04 15:19:22 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
switch flags {
|
2018-11-29 11:55:24 +00:00
|
|
|
|
case RES_SIGN:
|
2018-12-03 15:03:25 +00:00
|
|
|
|
buf := make([]byte, 1024*32)
|
|
|
|
|
n, err := c.ReadFromCompress(buf, DataDecode)
|
2018-11-04 15:19:22 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2018-12-03 15:03:25 +00:00
|
|
|
|
resp, err := DecodeResponse(buf[:n])
|
2018-11-04 15:19:22 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
bodyBytes, err := ioutil.ReadAll(resp.Body)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
for k, v := range resp.Header {
|
|
|
|
|
for _, v2 := range v {
|
|
|
|
|
w.Header().Set(k, v2)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
w.WriteHeader(resp.StatusCode)
|
|
|
|
|
w.Write(bodyBytes)
|
2018-11-29 11:55:24 +00:00
|
|
|
|
case RES_MSG:
|
|
|
|
|
BadRequest(w)
|
|
|
|
|
return errors.New("客户端请求出错")
|
2018-11-04 15:19:22 +00:00
|
|
|
|
default:
|
2018-11-29 11:55:24 +00:00
|
|
|
|
BadRequest(w)
|
|
|
|
|
return errors.New("无法解析此错误")
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-30 18:38:29 +00:00
|
|
|
|
type process func(c *Conn, s *TunnelModeServer) error
|
2018-11-29 11:55:24 +00:00
|
|
|
|
type TunnelModeServer struct {
|
|
|
|
|
Tunnel
|
|
|
|
|
httpPort int
|
|
|
|
|
tunnelTarget string
|
2018-11-30 18:38:29 +00:00
|
|
|
|
process process
|
2018-11-29 11:55:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-11-30 18:38:29 +00:00
|
|
|
|
func NewTunnelModeServer(tcpPort, httpPort int, tunnelTarget string, process process) *TunnelModeServer {
|
2018-11-29 11:55:24 +00:00
|
|
|
|
s := new(TunnelModeServer)
|
|
|
|
|
s.tunnelPort = tcpPort
|
|
|
|
|
s.httpPort = httpPort
|
|
|
|
|
s.tunnelTarget = tunnelTarget
|
|
|
|
|
s.tunnelList = make(chan *Conn, 1000)
|
|
|
|
|
s.signalList = make(chan *Conn, 10)
|
2018-11-30 18:38:29 +00:00
|
|
|
|
s.process = process
|
2018-11-29 11:55:24 +00:00
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//开始
|
|
|
|
|
func (s *TunnelModeServer) Start() (error) {
|
|
|
|
|
err := s.StartTunnel()
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Fatalln("开启客户端失败!", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
s.startTunnelServer()
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//隧道模式server
|
|
|
|
|
func (s *TunnelModeServer) startTunnelServer() {
|
|
|
|
|
listener, err := net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), s.httpPort, ""})
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Fatalln(err)
|
|
|
|
|
}
|
|
|
|
|
for {
|
|
|
|
|
conn, err := listener.AcceptTCP()
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Println(err)
|
|
|
|
|
continue
|
|
|
|
|
}
|
2018-11-30 18:38:29 +00:00
|
|
|
|
go s.process(NewConn(conn), s)
|
2018-11-29 11:55:24 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-30 18:38:29 +00:00
|
|
|
|
//TODO:这种实现方式……
|
|
|
|
|
//tcp隧道模式
|
|
|
|
|
func ProcessTunnel(c *Conn, s *TunnelModeServer) error {
|
2018-11-29 11:55:24 +00:00
|
|
|
|
retry:
|
2018-11-30 18:38:29 +00:00
|
|
|
|
link := s.GetTunnel()
|
2018-12-03 15:03:25 +00:00
|
|
|
|
if _, err := link.WriteHost("tcp", s.tunnelTarget); err != nil {
|
2018-11-30 18:38:29 +00:00
|
|
|
|
link.Close()
|
2018-11-29 11:55:24 +00:00
|
|
|
|
goto retry
|
2018-11-04 15:19:22 +00:00
|
|
|
|
}
|
2018-12-03 15:03:25 +00:00
|
|
|
|
go relay(link, c, DataEncode)
|
|
|
|
|
relay(c, link, DataDecode)
|
2018-11-04 15:19:22 +00:00
|
|
|
|
return nil
|
|
|
|
|
}
|
2018-11-30 18:38:29 +00:00
|
|
|
|
|
|
|
|
|
//http代理模式
|
|
|
|
|
func ProcessHttp(c *Conn, s *TunnelModeServer) error {
|
|
|
|
|
method, addr, rb, err := c.GetHost()
|
|
|
|
|
if err != nil {
|
|
|
|
|
c.Close()
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
retry:
|
|
|
|
|
link := s.GetTunnel()
|
2018-12-03 15:03:25 +00:00
|
|
|
|
if _, err := link.WriteHost("tcp", addr); err != nil {
|
2018-11-30 18:38:29 +00:00
|
|
|
|
link.Close()
|
|
|
|
|
goto retry
|
|
|
|
|
}
|
|
|
|
|
if method == "CONNECT" {
|
|
|
|
|
fmt.Fprint(c, "HTTP/1.1 200 Connection established\r\n")
|
|
|
|
|
} else {
|
2018-12-03 15:03:25 +00:00
|
|
|
|
link.WriteCompress(rb, DataEncode)
|
2018-11-30 18:38:29 +00:00
|
|
|
|
}
|
2018-12-03 15:03:25 +00:00
|
|
|
|
go relay(link, c, DataEncode)
|
|
|
|
|
relay(c, link, DataDecode)
|
2018-11-30 18:38:29 +00:00
|
|
|
|
return nil
|
|
|
|
|
}
|