结构调整、kcp支持

This commit is contained in:
刘河
2019-02-09 17:07:47 +08:00
parent 2e8af6f120
commit 59d789d253
60 changed files with 11097 additions and 783 deletions

View File

@@ -3,7 +3,10 @@ package server
import (
"errors"
"github.com/cnlh/nps/bridge"
"github.com/cnlh/nps/lib"
"github.com/cnlh/nps/lib/common"
"github.com/cnlh/nps/lib/conn"
"github.com/cnlh/nps/lib/file"
"github.com/cnlh/nps/lib/pool"
"net"
"net/http"
"sync"
@@ -13,8 +16,8 @@ import (
type server struct {
id int
bridge *bridge.Bridge
task *lib.Tunnel
config *lib.Config
task *file.Tunnel
config *file.Config
errorContent []byte
sync.Mutex
}
@@ -26,7 +29,7 @@ func (s *server) FlowAdd(in, out int64) {
s.task.Flow.InletFlow += in
}
func (s *server) FlowAddHost(host *lib.Host, in, out int64) {
func (s *server) FlowAddHost(host *file.Host, in, out int64) {
s.Lock()
defer s.Unlock()
host.Flow.ExportFlow += out
@@ -36,7 +39,7 @@ func (s *server) FlowAddHost(host *lib.Host, in, out int64) {
//热更新配置
func (s *server) ResetConfig() bool {
//获取最新数据
task, err := lib.GetCsvDb().GetTask(s.task.Id)
task, err := file.GetCsvDb().GetTask(s.task.Id)
if err != nil {
return false
}
@@ -45,7 +48,7 @@ func (s *server) ResetConfig() bool {
}
s.task.UseClientCnf = task.UseClientCnf
//使用客户端配置
client, err := lib.GetCsvDb().GetClient(s.task.Client.Id)
client, err := file.GetCsvDb().GetClient(s.task.Client.Id)
if s.task.UseClientCnf {
if err == nil {
s.config.U = client.Cnf.U
@@ -62,11 +65,11 @@ func (s *server) ResetConfig() bool {
}
}
s.task.Client.Rate = client.Rate
s.config.CompressDecode, s.config.CompressEncode = lib.GetCompressType(s.config.Compress)
s.config.CompressDecode, s.config.CompressEncode = common.GetCompressType(s.config.Compress)
return true
}
func (s *server) linkCopy(link *lib.Link, c *lib.Conn, rb []byte, tunnel *lib.Conn, flow *lib.Flow) {
func (s *server) linkCopy(link *conn.Link, c *conn.Conn, rb []byte, tunnel *conn.Conn, flow *file.Flow) {
if rb != nil {
if _, err := tunnel.SendMsg(rb, link); err != nil {
c.Close()
@@ -74,32 +77,32 @@ func (s *server) linkCopy(link *lib.Link, c *lib.Conn, rb []byte, tunnel *lib.Co
}
flow.Add(len(rb), 0)
}
buf := pool.BufPoolCopy.Get().([]byte)
for {
buf := lib.BufPoolCopy.Get().([]byte)
if n, err := c.Read(buf); err != nil {
tunnel.SendMsg([]byte(lib.IO_EOF), link)
tunnel.SendMsg([]byte(common.IO_EOF), link)
break
} else {
if _, err := tunnel.SendMsg(buf[:n], link); err != nil {
lib.PutBufPoolCopy(buf)
c.Close()
break
}
lib.PutBufPoolCopy(buf)
flow.Add(n, 0)
}
}
pool.PutBufPoolCopy(buf)
}
func (s *server) writeConnFail(c net.Conn) {
c.Write([]byte(lib.ConnectionFailBytes))
c.Write([]byte(common.ConnectionFailBytes))
c.Write(s.errorContent)
}
//权限认证
func (s *server) auth(r *http.Request, c *lib.Conn, u, p string) error {
if u != "" && p != "" && !lib.CheckAuth(r, u, p) {
c.Write([]byte(lib.UnauthorizedBytes))
func (s *server) auth(r *http.Request, c *conn.Conn, u, p string) error {
if u != "" && p != "" && !common.CheckAuth(r, u, p) {
c.Write([]byte(common.UnauthorizedBytes))
c.Close()
return errors.New("401 Unauthorized")
}

View File

@@ -3,9 +3,13 @@ package server
import (
"bufio"
"crypto/tls"
"github.com/astaxie/beego"
"github.com/cnlh/nps/lib/beego"
"github.com/cnlh/nps/bridge"
"github.com/cnlh/nps/lib"
"github.com/cnlh/nps/lib/conn"
"github.com/cnlh/nps/lib/file"
"github.com/cnlh/nps/lib/lg"
"github.com/cnlh/nps/lib/common"
"log"
"net/http"
"net/http/httputil"
"path/filepath"
@@ -22,7 +26,7 @@ type httpServer struct {
stop chan bool
}
func NewHttp(bridge *bridge.Bridge, c *lib.Tunnel) *httpServer {
func NewHttp(bridge *bridge.Bridge, c *file.Tunnel) *httpServer {
httpPort, _ := beego.AppConfig.Int("httpProxyPort")
httpsPort, _ := beego.AppConfig.Int("httpsProxyPort")
pemPath := beego.AppConfig.String("pemPath")
@@ -44,33 +48,33 @@ func NewHttp(bridge *bridge.Bridge, c *lib.Tunnel) *httpServer {
func (s *httpServer) Start() error {
var err error
var http, https *http.Server
if s.errorContent, err = lib.ReadAllFromFile(filepath.Join(lib.GetRunPath(), "web", "static", "page", "error.html")); err != nil {
if s.errorContent, err = common.ReadAllFromFile(filepath.Join(common.GetRunPath(), "web", "static", "page", "error.html")); err != nil {
s.errorContent = []byte("easyProxy 404")
}
if s.httpPort > 0 {
http = s.NewServer(s.httpPort)
go func() {
lib.Println("启动http监听,端口为", s.httpPort)
lg.Println("启动http监听,端口为", s.httpPort)
err := http.ListenAndServe()
if err != nil {
lib.Fatalln(err)
lg.Fatalln(err)
}
}()
}
if s.httpsPort > 0 {
if !lib.FileExists(s.pemPath) {
lib.Fatalf("ssl certFile文件%s不存在", s.pemPath)
if !common.FileExists(s.pemPath) {
lg.Fatalf("ssl certFile文件%s不存在", s.pemPath)
}
if !lib.FileExists(s.keyPath) {
lib.Fatalf("ssl keyFile文件%s不存在", s.keyPath)
if !common.FileExists(s.keyPath) {
lg.Fatalf("ssl keyFile文件%s不存在", s.keyPath)
}
https = s.NewServer(s.httpsPort)
go func() {
lib.Println("启动https监听,端口为", s.httpsPort)
lg.Println("启动https监听,端口为", s.httpsPort)
err := https.ListenAndServeTLS(s.pemPath, s.keyPath)
if err != nil {
lib.Fatalln(err)
lg.Fatalln(err)
}
}()
}
@@ -96,40 +100,41 @@ func (s *httpServer) handleTunneling(w http.ResponseWriter, r *http.Request) {
http.Error(w, "Hijacking not supported", http.StatusInternalServerError)
return
}
conn, _, err := hijacker.Hijack()
c, _, err := hijacker.Hijack()
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
s.process(lib.NewConn(conn), r)
s.process(conn.NewConn(c), r)
}
func (s *httpServer) process(c *lib.Conn, r *http.Request) {
func (s *httpServer) process(c *conn.Conn, r *http.Request) {
//多客户端域名代理
var (
isConn = true
link *lib.Link
host *lib.Host
tunnel *lib.Conn
lk *conn.Link
host *file.Host
tunnel *conn.Conn
err error
)
for {
//首次获取conn
if isConn {
if host, err = GetInfoByHost(r.Host); err != nil {
lib.Printf("the host %s is not found !", r.Host)
lg.Printf("the host %s is not found !", r.Host)
break
}
//流量限制
if host.Client.Flow.FlowLimit > 0 && (host.Client.Flow.FlowLimit<<20) < (host.Client.Flow.ExportFlow+host.Client.Flow.InletFlow) {
break
}
host.Client.Cnf.CompressDecode, host.Client.Cnf.CompressEncode = lib.GetCompressType(host.Client.Cnf.Compress)
host.Client.Cnf.CompressDecode, host.Client.Cnf.CompressEncode = common.GetCompressType(host.Client.Cnf.Compress)
//权限控制
if err = s.auth(r, c, host.Client.Cnf.U, host.Client.Cnf.P); err != nil {
break
}
link = lib.NewLink(host.Client.GetId(), lib.CONN_TCP, host.GetRandomTarget(), host.Client.Cnf.CompressEncode, host.Client.Cnf.CompressDecode, host.Client.Cnf.Crypt, c, host.Flow, nil, host.Client.Rate, nil)
if tunnel, err = s.bridge.SendLinkInfo(host.Client.Id, link); err != nil {
lk = conn.NewLink(host.Client.GetId(), common.CONN_TCP, host.GetRandomTarget(), host.Client.Cnf.CompressEncode, host.Client.Cnf.CompressDecode, host.Client.Cnf.Crypt, c, host.Flow, nil, host.Client.Rate, nil)
if tunnel, err = s.bridge.SendLinkInfo(host.Client.Id, lk); err != nil {
log.Println(err)
break
}
isConn = false
@@ -140,13 +145,13 @@ func (s *httpServer) process(c *lib.Conn, r *http.Request) {
}
}
//根据设定修改header和host
lib.ChangeHostAndHeader(r, host.HostChange, host.HeaderChange, c.Conn.RemoteAddr().String())
common.ChangeHostAndHeader(r, host.HostChange, host.HeaderChange, c.Conn.RemoteAddr().String())
b, err := httputil.DumpRequest(r, true)
if err != nil {
break
}
host.Flow.Add(len(b), 0)
if _, err := tunnel.SendMsg(b, link); err != nil {
if _, err := tunnel.SendMsg(b, lk); err != nil {
c.Close()
break
}
@@ -155,7 +160,7 @@ func (s *httpServer) process(c *lib.Conn, r *http.Request) {
if isConn {
s.writeConnFail(c.Conn)
} else {
tunnel.SendMsg([]byte(lib.IO_EOF), link)
tunnel.SendMsg([]byte(common.IO_EOF), lk)
}
c.Close()

View File

@@ -3,7 +3,8 @@ package server
import (
"errors"
"github.com/cnlh/nps/bridge"
"github.com/cnlh/nps/lib"
"github.com/cnlh/nps/lib/file"
"github.com/cnlh/nps/lib/lg"
"reflect"
"strings"
)
@@ -11,44 +12,41 @@ import (
var (
Bridge *bridge.Bridge
RunList map[int]interface{} //运行中的任务
startFinish chan bool
)
func init() {
RunList = make(map[int]interface{})
startFinish = make(chan bool)
}
//从csv文件中恢复任务
func InitFromCsv() {
for _, v := range lib.GetCsvDb().Tasks {
for _, v := range file.GetCsvDb().Tasks {
if v.Status {
lib.Println("启动模式:", v.Mode, "监听端口:", v.TcpPort)
lg.Println("启动模式:", v.Mode, "监听端口:", v.TcpPort)
AddTask(v)
}
}
}
//start a new server
func StartNewServer(bridgePort int, cnf *lib.Tunnel) {
Bridge = bridge.NewTunnel(bridgePort, RunList)
func StartNewServer(bridgePort int, cnf *file.Tunnel, bridgeType string) {
Bridge = bridge.NewTunnel(bridgePort, RunList, bridgeType)
if err := Bridge.StartTunnel(); err != nil {
lib.Fatalln("服务端开启失败", err)
lg.Fatalln("服务端开启失败", err)
}
if svr := NewMode(Bridge, cnf); svr != nil {
RunList[cnf.Id] = svr
err := reflect.ValueOf(svr).MethodByName("Start").Call(nil)[0]
if err.Interface() != nil {
lib.Fatalln(err)
lg.Fatalln(err)
}
} else {
lib.Fatalln("启动模式不正确")
lg.Fatalln("启动模式不正确")
}
}
//new a server by mode name
func NewMode(Bridge *bridge.Bridge, c *lib.Tunnel) interface{} {
func NewMode(Bridge *bridge.Bridge, c *file.Tunnel) interface{} {
switch c.Mode {
case "tunnelServer":
return NewTunnelModeServer(ProcessTunnel, Bridge, c)
@@ -60,17 +58,15 @@ func NewMode(Bridge *bridge.Bridge, c *lib.Tunnel) interface{} {
return NewUdpModeServer(Bridge, c)
case "webServer":
InitFromCsv()
t := &lib.Tunnel{
t := &file.Tunnel{
TcpPort: 0,
Mode: "httpHostServer",
Target: "",
Config: &lib.Config{},
Config: &file.Config{},
Status: true,
}
AddTask(t)
return NewWebServer(Bridge)
case "hostServer":
return NewHostServer(c)
case "httpHostServer":
return NewHttp(Bridge, c)
}
@@ -81,11 +77,11 @@ func NewMode(Bridge *bridge.Bridge, c *lib.Tunnel) interface{} {
func StopServer(id int) error {
if v, ok := RunList[id]; ok {
reflect.ValueOf(v).MethodByName("Close").Call(nil)
if t, err := lib.GetCsvDb().GetTask(id); err != nil {
if t, err := file.GetCsvDb().GetTask(id); err != nil {
return err
} else {
t.Status = false
lib.GetCsvDb().UpdateTask(t)
file.GetCsvDb().UpdateTask(t)
}
return nil
}
@@ -93,13 +89,13 @@ func StopServer(id int) error {
}
//add task
func AddTask(t *lib.Tunnel) error {
func AddTask(t *file.Tunnel) error {
if svr := NewMode(Bridge, t); svr != nil {
RunList[t.Id] = svr
go func() {
err := reflect.ValueOf(svr).MethodByName("Start").Call(nil)[0]
if err.Interface() != nil {
lib.Fatalln("服务端", t.Id, "启动失败,错误:", err)
lg.Fatalln("客户端", t.Id, "启动失败,错误:", err)
delete(RunList, t.Id)
}
}()
@@ -111,12 +107,12 @@ func AddTask(t *lib.Tunnel) error {
//start task
func StartTask(id int) error {
if t, err := lib.GetCsvDb().GetTask(id); err != nil {
if t, err := file.GetCsvDb().GetTask(id); err != nil {
return err
} else {
AddTask(t)
t.Status = true
lib.GetCsvDb().UpdateTask(t)
file.GetCsvDb().UpdateTask(t)
}
return nil
}
@@ -126,12 +122,12 @@ func DelTask(id int) error {
if err := StopServer(id); err != nil {
return err
}
return lib.GetCsvDb().DelTask(id)
return file.GetCsvDb().DelTask(id)
}
//get key by host from x
func GetInfoByHost(host string) (h *lib.Host, err error) {
for _, v := range lib.GetCsvDb().Hosts {
func GetInfoByHost(host string) (h *file.Host, err error) {
for _, v := range file.GetCsvDb().Hosts {
s := strings.Split(host, ":")
if s[0] == v.Host {
h = v
@@ -143,10 +139,10 @@ func GetInfoByHost(host string) (h *lib.Host, err error) {
}
//get task list by page num
func GetTunnel(start, length int, typeVal string, clientId int) ([]*lib.Tunnel, int) {
list := make([]*lib.Tunnel, 0)
func GetTunnel(start, length int, typeVal string, clientId int) ([]*file.Tunnel, int) {
list := make([]*file.Tunnel, 0)
var cnt int
for _, v := range lib.GetCsvDb().Tasks {
for _, v := range file.GetCsvDb().Tasks {
if (typeVal != "" && v.Mode != typeVal) || (typeVal == "" && clientId != v.Client.Id) {
continue
}
@@ -171,13 +167,13 @@ func GetTunnel(start, length int, typeVal string, clientId int) ([]*lib.Tunnel,
}
//获取客户端列表
func GetClientList(start, length int) (list []*lib.Client, cnt int) {
list, cnt = lib.GetCsvDb().GetClientList(start, length)
func GetClientList(start, length int) (list []*file.Client, cnt int) {
list, cnt = file.GetCsvDb().GetClientList(start, length)
dealClientData(list)
return
}
func dealClientData(list []*lib.Client) {
func dealClientData(list []*file.Client) {
for _, v := range list {
if _, ok := Bridge.Client[v.Id]; ok {
v.IsConnect = true
@@ -186,13 +182,13 @@ func dealClientData(list []*lib.Client) {
}
v.Flow.InletFlow = 0
v.Flow.ExportFlow = 0
for _, h := range lib.GetCsvDb().Hosts {
for _, h := range file.GetCsvDb().Hosts {
if h.Client.Id == v.Id {
v.Flow.InletFlow += h.Flow.InletFlow
v.Flow.ExportFlow += h.Flow.ExportFlow
}
}
for _, t := range lib.GetCsvDb().Tasks {
for _, t := range file.GetCsvDb().Tasks {
if t.Client.Id == v.Id {
v.Flow.InletFlow += t.Flow.InletFlow
v.Flow.ExportFlow += t.Flow.ExportFlow
@@ -204,14 +200,14 @@ func dealClientData(list []*lib.Client) {
//根据客户端id删除其所属的所有隧道和域名
func DelTunnelAndHostByClientId(clientId int) {
for _, v := range lib.GetCsvDb().Tasks {
for _, v := range file.GetCsvDb().Tasks {
if v.Client.Id == clientId {
DelTask(v.Id)
}
}
for _, v := range lib.GetCsvDb().Hosts {
for _, v := range file.GetCsvDb().Hosts {
if v.Client.Id == clientId {
lib.GetCsvDb().DelHost(v.Host)
file.GetCsvDb().DelHost(v.Host)
}
}
}
@@ -223,9 +219,9 @@ func DelClientConnect(clientId int) {
func GetDashboardData() map[string]int {
data := make(map[string]int)
data["hostCount"] = len(lib.GetCsvDb().Hosts)
data["clientCount"] = len(lib.GetCsvDb().Clients)
list := lib.GetCsvDb().Clients
data["hostCount"] = len(file.GetCsvDb().Hosts)
data["clientCount"] = len(file.GetCsvDb().Clients)
list := file.GetCsvDb().Clients
dealClientData(list)
c := 0
var in, out int64
@@ -239,7 +235,7 @@ func GetDashboardData() map[string]int {
data["clientOnlineCount"] = c
data["inletFlowCount"] = int(in)
data["exportFlowCount"] = int(out)
for _, v := range lib.GetCsvDb().Tasks {
for _, v := range file.GetCsvDb().Tasks {
switch v.Mode {
case "tunnelServer":
data["tunnelServerCount"] += 1

View File

@@ -4,7 +4,10 @@ import (
"encoding/binary"
"errors"
"github.com/cnlh/nps/bridge"
"github.com/cnlh/nps/lib"
"github.com/cnlh/nps/lib/common"
"github.com/cnlh/nps/lib/conn"
"github.com/cnlh/nps/lib/file"
"github.com/cnlh/nps/lib/lg"
"io"
"net"
"strconv"
@@ -65,7 +68,7 @@ func (s *Sock5ModeServer) handleRequest(c net.Conn) {
_, err := io.ReadFull(c, header)
if err != nil {
lib.Println("illegal request", err)
lg.Println("illegal request", err)
c.Close()
return
}
@@ -135,18 +138,18 @@ func (s *Sock5ModeServer) doConnect(c net.Conn, command uint8) {
addr := net.JoinHostPort(host, strconv.Itoa(int(port)))
var ltype string
if command == associateMethod {
ltype = lib.CONN_UDP
ltype = common.CONN_UDP
} else {
ltype = lib.CONN_TCP
ltype = common.CONN_TCP
}
link := lib.NewLink(s.task.Client.GetId(), ltype, addr, s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, lib.NewConn(c), s.task.Flow, nil, s.task.Client.Rate, nil)
link := conn.NewLink(s.task.Client.GetId(), ltype, addr, s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, conn.NewConn(c), s.task.Flow, nil, s.task.Client.Rate, nil)
if tunnel, err := s.bridge.SendLinkInfo(s.task.Client.Id, link); err != nil {
c.Close()
return
} else {
s.sendReply(c, succeeded)
s.linkCopy(link, lib.NewConn(c), nil, tunnel, s.task.Flow)
s.linkCopy(link, conn.NewConn(c), nil, tunnel, s.task.Flow)
}
return
}
@@ -162,7 +165,7 @@ func (s *Sock5ModeServer) handleBind(c net.Conn) {
//udp
func (s *Sock5ModeServer) handleUDP(c net.Conn) {
lib.Println("UDP Associate")
lg.Println("UDP Associate")
/*
+----+------+------+----------+----------+----------+
|RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA |
@@ -175,7 +178,7 @@ func (s *Sock5ModeServer) handleUDP(c net.Conn) {
// relay udp datagram silently, without any notification to the requesting client
if buf[2] != 0 {
// does not support fragmentation, drop it
lib.Println("does not support fragmentation, drop")
lg.Println("does not support fragmentation, drop")
dummy := make([]byte, maxUDPPacketSize)
c.Read(dummy)
}
@@ -187,13 +190,13 @@ func (s *Sock5ModeServer) handleUDP(c net.Conn) {
func (s *Sock5ModeServer) handleConn(c net.Conn) {
buf := make([]byte, 2)
if _, err := io.ReadFull(c, buf); err != nil {
lib.Println("negotiation err", err)
lg.Println("negotiation err", err)
c.Close()
return
}
if version := buf[0]; version != 5 {
lib.Println("only support socks5, request from: ", c.RemoteAddr())
lg.Println("only support socks5, request from: ", c.RemoteAddr())
c.Close()
return
}
@@ -201,7 +204,7 @@ func (s *Sock5ModeServer) handleConn(c net.Conn) {
methods := make([]byte, nMethods)
if len, err := c.Read(methods); len != int(nMethods) || err != nil {
lib.Println("wrong method")
lg.Println("wrong method")
c.Close()
return
}
@@ -210,7 +213,7 @@ func (s *Sock5ModeServer) handleConn(c net.Conn) {
c.Write(buf)
if err := s.Auth(c); err != nil {
c.Close()
lib.Println("验证失败:", err)
lg.Println("验证失败:", err)
return
}
} else {
@@ -269,7 +272,7 @@ func (s *Sock5ModeServer) Start() error {
if strings.Contains(err.Error(), "use of closed network connection") {
break
}
lib.Fatalln("accept error: ", err)
lg.Fatalln("accept error: ", err)
}
if !s.ResetConfig() {
conn.Close()
@@ -286,11 +289,11 @@ func (s *Sock5ModeServer) Close() error {
}
//new
func NewSock5ModeServer(bridge *bridge.Bridge, task *lib.Tunnel) *Sock5ModeServer {
func NewSock5ModeServer(bridge *bridge.Bridge, task *file.Tunnel) *Sock5ModeServer {
s := new(Sock5ModeServer)
s.bridge = bridge
s.task = task
s.config = lib.DeepCopyConfig(task.Config)
s.config = file.DeepCopyConfig(task.Config)
if s.config.U != "" && s.config.P != "" {
s.isVerify = true
} else {

View File

@@ -2,9 +2,12 @@ package server
import (
"errors"
"github.com/astaxie/beego"
"github.com/cnlh/nps/lib/beego"
"github.com/cnlh/nps/bridge"
"github.com/cnlh/nps/lib"
"github.com/cnlh/nps/lib/common"
"github.com/cnlh/nps/lib/conn"
"github.com/cnlh/nps/lib/file"
"github.com/cnlh/nps/lib/lg"
"net"
"path/filepath"
"strings"
@@ -17,12 +20,12 @@ type TunnelModeServer struct {
}
//tcp|http|host
func NewTunnelModeServer(process process, bridge *bridge.Bridge, task *lib.Tunnel) *TunnelModeServer {
func NewTunnelModeServer(process process, bridge *bridge.Bridge, task *file.Tunnel) *TunnelModeServer {
s := new(TunnelModeServer)
s.bridge = bridge
s.process = process
s.task = task
s.config = lib.DeepCopyConfig(task.Config)
s.config = file.DeepCopyConfig(task.Config)
return s
}
@@ -34,22 +37,22 @@ func (s *TunnelModeServer) Start() error {
return err
}
for {
conn, err := s.listener.AcceptTCP()
c, err := s.listener.AcceptTCP()
if err != nil {
if strings.Contains(err.Error(), "use of closed network connection") {
break
}
lib.Println(err)
lg.Println(err)
continue
}
go s.process(lib.NewConn(conn), s)
go s.process(conn.NewConn(c), s)
}
return nil
}
//与客户端建立通道
func (s *TunnelModeServer) dealClient(c *lib.Conn, cnf *lib.Config, addr string, method string, rb []byte) error {
link := lib.NewLink(s.task.Client.GetId(), lib.CONN_TCP, addr, cnf.CompressEncode, cnf.CompressDecode, cnf.Crypt, c, s.task.Flow, nil, s.task.Client.Rate, nil)
func (s *TunnelModeServer) dealClient(c *conn.Conn, cnf *file.Config, addr string, method string, rb []byte) error {
link := conn.NewLink(s.task.Client.GetId(), common.CONN_TCP, addr, cnf.CompressEncode, cnf.CompressDecode, cnf.Crypt, c, s.task.Flow, nil, s.task.Client.Rate, nil)
if tunnel, err := s.bridge.SendLinkInfo(s.task.Client.Id, link); err != nil {
c.Close()
@@ -73,13 +76,13 @@ type WebServer struct {
//开始
func (s *WebServer) Start() error {
p, _ := beego.AppConfig.Int("httpport")
if !lib.TestTcpPort(p) {
lib.Fatalln("web管理端口", p, "被占用!")
if !common.TestTcpPort(p) {
lg.Fatalln("web管理端口", p, "被占用!")
}
beego.BConfig.WebConfig.Session.SessionOn = true
lib.Println("web管理启动访问端口为", beego.AppConfig.String("httpport"))
beego.SetStaticPath("/static", filepath.Join(lib.GetRunPath(), "web", "static"))
beego.SetViewsPath(filepath.Join(lib.GetRunPath(), "web", "views"))
lg.Println("web管理启动访问端口为", p)
beego.SetStaticPath("/static", filepath.Join(common.GetRunPath(), "web", "static"))
beego.SetViewsPath(filepath.Join(common.GetRunPath(), "web", "views"))
beego.Run()
return errors.New("web管理启动失败")
}
@@ -91,32 +94,10 @@ func NewWebServer(bridge *bridge.Bridge) *WebServer {
return s
}
//host
type HostServer struct {
server
}
//开始
func (s *HostServer) Start() error {
return nil
}
func NewHostServer(task *lib.Tunnel) *HostServer {
s := new(HostServer)
s.task = task
s.config = lib.DeepCopyConfig(task.Config)
return s
}
//close
func (s *HostServer) Close() error {
return nil
}
type process func(c *lib.Conn, s *TunnelModeServer) error
type process func(c *conn.Conn, s *TunnelModeServer) error
//tcp隧道模式
func ProcessTunnel(c *lib.Conn, s *TunnelModeServer) error {
func ProcessTunnel(c *conn.Conn, s *TunnelModeServer) error {
if !s.ResetConfig() {
c.Close()
return errors.New("流量超出")
@@ -125,7 +106,7 @@ func ProcessTunnel(c *lib.Conn, s *TunnelModeServer) error {
}
//http代理模式
func ProcessHttp(c *lib.Conn, s *TunnelModeServer) error {
func ProcessHttp(c *conn.Conn, s *TunnelModeServer) error {
if !s.ResetConfig() {
c.Close()
return errors.New("流量超出")

View File

@@ -1,54 +1,78 @@
package server
import (
"github.com/astaxie/beego"
"github.com/cnlh/nps/lib"
"github.com/cnlh/nps/lib/beego"
"github.com/cnlh/nps/lib/common"
"github.com/cnlh/nps/lib/file"
"log"
"strconv"
)
func TestServerConfig() {
var postArr []int
for _, v := range lib.GetCsvDb().Tasks {
isInArr(&postArr, v.TcpPort, v.Remark)
var postTcpArr []int
var postUdpArr []int
for _, v := range file.GetCsvDb().Tasks {
if v.Mode == "udpServer" {
isInArr(&postUdpArr, v.TcpPort, v.Remark, "udp")
} else {
isInArr(&postTcpArr, v.TcpPort, v.Remark, "tcp")
}
}
p, err := beego.AppConfig.Int("httpport")
if err != nil {
log.Fatalln("Getting web management port error :", err)
} else {
isInArr(&postArr, p, "WebmManagement port")
isInArr(&postTcpArr, p, "Web Management port", "tcp")
}
if p := beego.AppConfig.String("bridgePort"); p != "" {
if port, err := strconv.Atoi(p); err != nil {
log.Fatalln("get Server and client communication portserror:", err)
} else if beego.AppConfig.String("bridgeType") == "kcp" {
isInArr(&postUdpArr, port, "Server and client communication ports", "udp")
} else {
isInArr(&postTcpArr, port, "Server and client communication ports", "tcp")
}
}
if p := beego.AppConfig.String("httpProxyPort"); p != "" {
if port, err := strconv.Atoi(p); err != nil {
log.Fatalln("get http port error:", err)
} else {
isInArr(&postArr, port, "https port")
isInArr(&postTcpArr, port, "https port", "tcp")
}
}
if p := beego.AppConfig.String("httpsProxyPort"); p != "" {
if port, err := strconv.Atoi(p); err != nil {
log.Fatalln("get https port error", err)
} else {
if !lib.FileExists(beego.AppConfig.String("pemPath")) {
if !common.FileExists(beego.AppConfig.String("pemPath")) {
log.Fatalf("ssl certFile %s is not exist", beego.AppConfig.String("pemPath"))
}
if !lib.FileExists(beego.AppConfig.String("ketPath")) {
if !common.FileExists(beego.AppConfig.String("ketPath")) {
log.Fatalf("ssl keyFile %s is not exist", beego.AppConfig.String("pemPath"))
}
isInArr(&postArr, port, "http port")
isInArr(&postTcpArr, port, "http port", "tcp")
}
}
}
func isInArr(arr *[]int, val int, remark string) {
func isInArr(arr *[]int, val int, remark string, tp string) {
for _, v := range *arr {
if v == val {
log.Fatalf("the port %d is reused,remark: %s", val, remark)
}
}
if !lib.TestTcpPort(val) {
log.Fatalf("open the %d port error ,remark: %s", val, remark)
if tp == "tcp" {
if !common.TestTcpPort(val) {
log.Fatalf("open the %d port error ,remark: %s", val, remark)
}
} else {
if !common.TestUdpPort(val) {
log.Fatalf("open the %d port error ,remark: %s", val, remark)
}
}
*arr = append(*arr, val)
return
}

View File

@@ -2,7 +2,10 @@ package server
import (
"github.com/cnlh/nps/bridge"
"github.com/cnlh/nps/lib"
"github.com/cnlh/nps/lib/common"
"github.com/cnlh/nps/lib/conn"
"github.com/cnlh/nps/lib/file"
"github.com/cnlh/nps/lib/pool"
"net"
"strings"
)
@@ -10,15 +13,15 @@ import (
type UdpModeServer struct {
server
listener *net.UDPConn
udpMap map[string]*lib.Conn
udpMap map[string]*conn.Conn
}
func NewUdpModeServer(bridge *bridge.Bridge, task *lib.Tunnel) *UdpModeServer {
func NewUdpModeServer(bridge *bridge.Bridge, task *file.Tunnel) *UdpModeServer {
s := new(UdpModeServer)
s.bridge = bridge
s.udpMap = make(map[string]*lib.Conn)
s.udpMap = make(map[string]*conn.Conn)
s.task = task
s.config = lib.DeepCopyConfig(task.Config)
s.config = file.DeepCopyConfig(task.Config)
return s
}
@@ -29,7 +32,7 @@ func (s *UdpModeServer) Start() error {
if err != nil {
return err
}
buf := lib.BufPoolUdp.Get().([]byte)
buf := pool.BufPoolUdp.Get().([]byte)
for {
n, addr, err := s.listener.ReadFromUDP(buf)
if err != nil {
@@ -47,13 +50,14 @@ func (s *UdpModeServer) Start() error {
}
func (s *UdpModeServer) process(addr *net.UDPAddr, data []byte) {
link := lib.NewLink(s.task.Client.GetId(), lib.CONN_UDP, s.task.Target, s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, nil, s.task.Flow, s.listener, s.task.Client.Rate, addr)
link := conn.NewLink(s.task.Client.GetId(), common.CONN_UDP, s.task.Target, s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, nil, s.task.Flow, s.listener, s.task.Client.Rate, addr)
if tunnel, err := s.bridge.SendLinkInfo(s.task.Client.Id, link); err != nil {
return
} else {
s.task.Flow.Add(len(data), 0)
tunnel.SendMsg(data, link)
pool.PutBufPoolUdp(data)
}
}