nps/lib/tcp.go

317 lines
6.9 KiB
Go
Raw Normal View History

2018-12-11 08:37:12 +00:00
package lib
import (
"errors"
"fmt"
"github.com/astaxie/beego"
2018-12-30 14:36:15 +00:00
"github.com/astaxie/beego/session"
2018-12-11 08:37:12 +00:00
"io/ioutil"
"log"
"net"
"net/http"
"strings"
)
2018-12-30 14:36:15 +00:00
var GlobalHostSessions *session.Manager
2018-12-11 08:37:12 +00:00
const (
2018-12-30 14:36:15 +00:00
VERIFY_EER = "vkey"
WORK_MAIN = "main"
WORK_CHAN = "chan"
RES_SIGN = "sign"
RES_MSG = "msg0"
TEST_FLAG = "tst"
CONN_TCP = "tcp"
CONN_UDP = "udp"
Unauthorized_BYTES = `HTTP/1.1 401 Unauthorized
Content-Type: text/plain; charset=utf-8
WWW-Authenticate: Basic realm="easyProxy"
401 Unauthorized`
2018-12-11 08:37:12 +00:00
)
2019-01-03 16:21:23 +00:00
type process func(c *Conn, s *TunnelModeServer) error
2018-12-11 08:37:12 +00:00
type HttpModeServer struct {
2019-01-05 19:16:46 +00:00
bridge *Tunnel
config *ServerConfig
2018-12-11 08:37:12 +00:00
}
2019-01-03 16:21:23 +00:00
//http
2019-01-05 19:16:46 +00:00
func NewHttpModeServer(bridge *Tunnel, cnf *ServerConfig) *HttpModeServer {
2018-12-11 08:37:12 +00:00
s := new(HttpModeServer)
s.bridge = bridge
2019-01-05 19:16:46 +00:00
s.config = cnf
2018-12-11 08:37:12 +00:00
return s
}
//开始
func (s *HttpModeServer) Start() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
retry:
2018-12-30 14:36:15 +00:00
u := beego.AppConfig.String("basic.user")
p := beego.AppConfig.String("basic.password")
if u != "" && p != "" && !checkAuth(r, u, p) {
w.Header().Set("WWW-Authenticate", `Basic realm="easyProxy""`)
w.WriteHeader(401)
w.Write([]byte("401 Unauthorized\n"))
return
}
2019-01-05 19:16:46 +00:00
err, conn := s.bridge.GetSignal(getverifyval(s.config.VerifyKey))
2018-12-11 08:37:12 +00:00
if err != nil {
BadRequest(w)
2018-12-30 14:36:15 +00:00
return
2018-12-11 08:37:12 +00:00
}
if err := s.writeRequest(r, conn); err != nil {
2018-12-30 14:36:15 +00:00
log.Println("write request to client error:", err)
2018-12-11 08:37:12 +00:00
conn.Close()
goto retry
return
}
err = s.writeResponse(w, conn)
if err != nil {
2018-12-30 14:36:15 +00:00
log.Println("write response error:", err)
2018-12-11 08:37:12 +00:00
conn.Close()
goto retry
return
}
2019-01-05 19:16:46 +00:00
s.bridge.ReturnSignal(conn, getverifyval(s.config.VerifyKey))
2018-12-11 08:37:12 +00:00
})
2019-01-05 19:16:46 +00:00
log.Fatalln(http.ListenAndServe(fmt.Sprintf(":%d", s.config.TcpPort), nil))
2018-12-11 08:37:12 +00:00
}
//req转为bytes发送给client端
func (s *HttpModeServer) writeRequest(r *http.Request, conn *Conn) error {
raw, err := EncodeRequest(r)
if err != nil {
return err
}
conn.wSign()
2019-01-05 19:16:46 +00:00
conn.WriteConnInfo(s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
c, err := conn.WriteTo(raw, s.config.CompressEncode, s.config.Crypt)
2018-12-11 08:37:12 +00:00
if err != nil {
return err
}
if c != len(raw) {
return errors.New("写出长度与字节长度不一致。")
}
return nil
}
//从client读取出Response
func (s *HttpModeServer) writeResponse(w http.ResponseWriter, c *Conn) error {
flags, err := c.ReadFlag()
if err != nil {
return err
}
switch flags {
case RES_SIGN:
2018-12-30 14:36:15 +00:00
buf := make([]byte, 1024*1024*32)
2019-01-05 19:16:46 +00:00
n, err := c.ReadFrom(buf, s.config.CompressDecode, s.config.Crypt)
2018-12-11 08:37:12 +00:00
if err != nil {
return err
}
resp, err := DecodeResponse(buf[:n])
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)
case RES_MSG:
BadRequest(w)
return errors.New("客户端请求出错")
default:
BadRequest(w)
return errors.New("无法解析此错误")
}
return nil
}
type TunnelModeServer struct {
2019-01-05 19:16:46 +00:00
process process
bridge *Tunnel
config *ServerConfig
listener *net.TCPListener
2018-12-11 08:37:12 +00:00
}
2019-01-03 16:21:23 +00:00
//tcp|http|host
2019-01-05 19:16:46 +00:00
func NewTunnelModeServer(process process, bridge *Tunnel, cnf *ServerConfig) *TunnelModeServer {
2018-12-11 08:37:12 +00:00
s := new(TunnelModeServer)
s.bridge = bridge
s.process = process
2019-01-05 19:16:46 +00:00
s.config = cnf
2018-12-11 08:37:12 +00:00
return s
}
//开始
func (s *TunnelModeServer) Start() error {
2019-01-05 19:16:46 +00:00
s.listener, err = net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), s.config.TcpPort, ""})
2018-12-11 08:37:12 +00:00
if err != nil {
return err
}
for {
conn, err := s.listener.AcceptTCP()
if err != nil {
if strings.Contains(err.Error(), "use of closed network connection") {
break
}
log.Println(err)
continue
}
go s.process(NewConn(conn), s)
}
return nil
}
2019-01-03 16:21:23 +00:00
//权限认证
2019-01-04 12:23:33 +00:00
func (s *TunnelModeServer) auth(r *http.Request, c *Conn, u, p string) error {
if u != "" && p != "" && !checkAuth(r, u, p) {
2018-12-30 14:36:15 +00:00
c.Write([]byte(Unauthorized_BYTES))
c.Close()
return errors.New("401 Unauthorized")
}
return nil
}
2018-12-11 08:37:12 +00:00
2019-01-03 16:21:23 +00:00
//与客户端建立通道
2019-01-05 19:16:46 +00:00
func (s *TunnelModeServer) dealClient(c *Conn, cnf *ServerConfig, addr string, method string, rb []byte) error {
link, err := s.bridge.GetTunnel(getverifyval(cnf.VerifyKey), cnf.CompressEncode, cnf.CompressDecode, cnf.Crypt, cnf.Mux)
defer func() {
if cnf.Mux {
s.bridge.ReturnTunnel(link, getverifyval(cnf.VerifyKey))
}
}()
2018-12-30 14:36:15 +00:00
if err != nil {
log.Println(err)
c.Close()
return err
}
2019-01-05 19:16:46 +00:00
if _, err := link.WriteHost(CONN_TCP, addr); err != nil {
2018-12-11 08:37:12 +00:00
c.Close()
2019-01-03 16:21:23 +00:00
link.Close()
2018-12-11 08:37:12 +00:00
log.Println(err)
return err
}
2019-01-03 16:21:23 +00:00
if method == "CONNECT" {
fmt.Fprint(c, "HTTP/1.1 200 Connection established\r\n")
} else {
2019-01-05 19:16:46 +00:00
link.WriteTo(rb, cnf.CompressEncode, cnf.Crypt)
2019-01-03 16:21:23 +00:00
}
2019-01-05 19:16:46 +00:00
go relay(link, c, cnf.CompressEncode, cnf.Crypt, cnf.Mux)
relay(c, link, cnf.CompressDecode, cnf.Crypt, cnf.Mux)
2018-12-11 08:37:12 +00:00
return nil
}
2019-01-03 16:21:23 +00:00
//close
func (s *TunnelModeServer) Close() error {
return s.listener.Close()
}
//tcp隧道模式
func ProcessTunnel(c *Conn, s *TunnelModeServer) error {
method, _, rb, err, r := c.GetHost()
if err == nil {
2019-01-05 19:16:46 +00:00
if err := s.auth(r, c, s.config.U, s.config.P); err != nil {
2019-01-03 16:21:23 +00:00
return err
}
}
2019-01-05 19:16:46 +00:00
return s.dealClient(c, s.config, s.config.Target, method, rb)
2019-01-03 16:21:23 +00:00
}
2018-12-11 08:37:12 +00:00
//http代理模式
func ProcessHttp(c *Conn, s *TunnelModeServer) error {
2018-12-30 14:36:15 +00:00
method, addr, rb, err, r := c.GetHost()
2018-12-11 08:37:12 +00:00
if err != nil {
c.Close()
return err
}
2019-01-05 19:16:46 +00:00
if err := s.auth(r, c, s.config.U, s.config.P); err != nil {
2018-12-30 14:36:15 +00:00
return err
}
2019-01-05 19:16:46 +00:00
//TODO效率问题
return s.dealClient(c, s.config, addr, method, rb)
2018-12-11 08:37:12 +00:00
}
//多客户端域名代理
func ProcessHost(c *Conn, s *TunnelModeServer) error {
2018-12-30 14:36:15 +00:00
method, addr, rb, err, r := c.GetHost()
2018-12-11 08:37:12 +00:00
if err != nil {
c.Close()
return err
}
2019-01-04 12:23:33 +00:00
host, task, err := getKeyByHost(addr)
if err := s.auth(r, c, task.U, task.P); err != nil {
2018-12-30 14:36:15 +00:00
return err
}
2018-12-11 08:37:12 +00:00
if err != nil {
c.Close()
return err
}
2019-01-05 19:16:46 +00:00
return s.dealClient(c, task, host.Target, method, rb)
2018-12-11 08:37:12 +00:00
}
//web管理方式
type WebServer struct {
bridge *Tunnel
}
//开始
func (s *WebServer) Start() {
InitFromCsv()
p, _ := beego.AppConfig.Int("hostPort")
2019-01-05 19:16:46 +00:00
t := &ServerConfig{
2018-12-11 08:37:12 +00:00
TcpPort: p,
Mode: "httpHostServer",
Target: "",
VerifyKey: "",
U: "",
P: "",
Compress: "",
Start: 1,
IsRun: 0,
ClientStatus: 0,
}
AddTask(t)
beego.BConfig.WebConfig.Session.SessionOn = true
2018-12-30 14:36:15 +00:00
log.Println("web管理启动访问端口为", beego.AppConfig.String("httpport"))
2018-12-11 08:37:12 +00:00
beego.Run()
}
2019-01-03 16:21:23 +00:00
//new
2018-12-11 08:37:12 +00:00
func NewWebServer(bridge *Tunnel) *WebServer {
s := new(WebServer)
s.bridge = bridge
return s
}
//host
type HostServer struct {
2019-01-05 19:16:46 +00:00
config *ServerConfig
2018-12-11 08:37:12 +00:00
}
//开始
func (s *HostServer) Start() error {
return nil
}
2018-12-30 14:36:15 +00:00
2019-01-02 17:44:45 +00:00
//TODOhost模式的客户端无需指定和监听端口等
2019-01-05 19:16:46 +00:00
func NewHostServer(cnf *ServerConfig) *HostServer {
2018-12-11 08:37:12 +00:00
s := new(HostServer)
2019-01-05 19:16:46 +00:00
s.config = cnf
2018-12-11 08:37:12 +00:00
return s
}
2019-01-03 16:21:23 +00:00
//close
2018-12-11 08:37:12 +00:00
func (s *HostServer) Close() error {
return nil
}