mirror of
https://github.com/ehang-io/nps.git
synced 2025-09-02 03:16:53 +00:00
结构调整、kcp支持
This commit is contained in:
@@ -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")
|
||||
}
|
||||
|
@@ -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()
|
||||
|
@@ -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
|
||||
|
@@ -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 {
|
||||
|
@@ -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("流量超出")
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user