nps/server.go

208 lines
4.1 KiB
Go
Raw Normal View History

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
}
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:
buf := make([]byte, 1024*32)
n, err := c.ReadFromCompress(buf, DataDecode)
2018-11-04 15:19:22 +00:00
if err != nil {
return err
}
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()
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
}
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()
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 {
link.WriteCompress(rb, DataEncode)
2018-11-30 18:38:29 +00:00
}
go relay(link, c, DataEncode)
relay(c, link, DataDecode)
2018-11-30 18:38:29 +00:00
return nil
}