" + strconv.Itoa(i+1) + ":" + vv + "
" - } - } - w.Write([]byte(s)) -} diff --git a/lib/mux/web_test.go b/lib/mux/web_test.go deleted file mode 100644 index 91a0430..0000000 --- a/lib/mux/web_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package mux - -import "testing" - -func TestWeb(t *testing.T) { - NewLogServer() -} diff --git a/lib/mux/pconn.go b/lib/pmux/pconn.go similarity index 99% rename from lib/mux/pconn.go rename to lib/pmux/pconn.go index 35af3cc..d4330ef 100644 --- a/lib/mux/pconn.go +++ b/lib/pmux/pconn.go @@ -1,4 +1,4 @@ -package mux +package pmux import ( "net" diff --git a/lib/mux/plistener.go b/lib/pmux/plistener.go similarity index 98% rename from lib/mux/plistener.go rename to lib/pmux/plistener.go index 9bdaabc..deef001 100644 --- a/lib/mux/plistener.go +++ b/lib/pmux/plistener.go @@ -1,4 +1,4 @@ -package mux +package pmux import ( "errors" diff --git a/lib/mux/pmux.go b/lib/pmux/pmux.go similarity index 98% rename from lib/mux/pmux.go rename to lib/pmux/pmux.go index b8de236..0dffb3e 100644 --- a/lib/mux/pmux.go +++ b/lib/pmux/pmux.go @@ -1,6 +1,6 @@ // This module is used for port reuse // Distinguish client, web manager , HTTP and HTTPS according to the difference of protocol -package mux +package pmux import ( "bufio" @@ -139,7 +139,7 @@ func (pMux *PortMux) process(conn net.Conn) { func (pMux *PortMux) Close() error { if pMux.isClose { - return errors.New("the port mux has closed") + return errors.New("the port pmux has closed") } pMux.isClose = true close(pMux.clientConn) diff --git a/lib/mux/pmux_test.go b/lib/pmux/pmux_test.go similarity index 98% rename from lib/mux/pmux_test.go rename to lib/pmux/pmux_test.go index 4c8e44e..6a17ddd 100644 --- a/lib/mux/pmux_test.go +++ b/lib/pmux/pmux_test.go @@ -1,4 +1,4 @@ -package mux +package pmux import ( "testing" diff --git a/lib/version/version.go b/lib/version/version.go index 6a4c8ab..4f59412 100644 --- a/lib/version/version.go +++ b/lib/version/version.go @@ -1,6 +1,6 @@ package version -const VERSION = "0.26.0" +const VERSION = "0.26.1" // Compulsory minimum version, Minimum downward compatibility to this version func GetVersion() string { diff --git a/server/connection/connection.go b/server/connection/connection.go index aac1c34..f614622 100644 --- a/server/connection/connection.go +++ b/server/connection/connection.go @@ -5,12 +5,12 @@ import ( "os" "strconv" - "ehang.io/nps/lib/mux" + "ehang.io/nps/lib/pmux" "github.com/astaxie/beego" "github.com/astaxie/beego/logs" ) -var pMux *mux.PortMux +var pMux *pmux.PortMux var bridgePort string var httpsPort string var httpPort string @@ -28,7 +28,7 @@ func InitConnectionService() { logs.Error(err) os.Exit(0) } - pMux = mux.NewPortMux(port, beego.AppConfig.String("web_host")) + pMux = pmux.NewPortMux(port, beego.AppConfig.String("web_host")) } } diff --git a/server/proxy/http.go b/server/proxy/http.go index 1470c3c..73507ee 100644 --- a/server/proxy/http.go +++ b/server/proxy/http.go @@ -30,11 +30,12 @@ type httpServer struct { httpsServer *http.Server httpsListener net.Listener useCache bool + addOrigin bool cache *cache.Cache cacheLen int } -func NewHttp(bridge *bridge.Bridge, c *file.Tunnel, httpPort, httpsPort int, useCache bool, cacheLen int) *httpServer { +func NewHttp(bridge *bridge.Bridge, c *file.Tunnel, httpPort, httpsPort int, useCache bool, cacheLen int, addOrigin bool) *httpServer { httpServer := &httpServer{ BaseServer: BaseServer{ task: c, @@ -45,6 +46,7 @@ func NewHttp(bridge *bridge.Bridge, c *file.Tunnel, httpPort, httpsPort int, use httpsPort: httpsPort, useCache: useCache, cacheLen: cacheLen, + addOrigin: addOrigin, } if useCache { httpServer.cache = cache.New(cacheLen) @@ -55,7 +57,7 @@ func NewHttp(bridge *bridge.Bridge, c *file.Tunnel, httpPort, httpsPort int, use func (s *httpServer) Start() error { var err error if s.errorContent, err = common.ReadAllFromFile(filepath.Join(common.GetRunPath(), "web", "static", "page", "error.html")); err != nil { - s.errorContent = []byte("easyProxy 404") + s.errorContent = []byte("nps 404") } if s.httpPort > 0 { s.httpServer = s.NewServer(s.httpPort, "http") @@ -116,7 +118,6 @@ func (s *httpServer) handleHttp(c *conn.Conn, r *http.Request) { var ( host *file.Host target net.Conn - lastHost *file.Host err error connClient io.ReadWriteCloser scheme = r.URL.Scheme @@ -133,6 +134,10 @@ func (s *httpServer) handleHttp(c *conn.Conn, r *http.Request) { } c.Close() }() +reset: + if isReset { + host.Client.AddConn() + } if host, err = file.GetDb().GetInfoByHost(r.Host, r); err != nil { logs.Notice("the url %s %s %s can't be parsed!", r.URL.Scheme, r.Host, r.RequestURI) return @@ -141,12 +146,13 @@ func (s *httpServer) handleHttp(c *conn.Conn, r *http.Request) { logs.Warn("client id %d, host id %d, error %s, when https connection", host.Client.Id, host.Id, err.Error()) return } - defer host.Client.AddConn() + if !isReset { + defer host.Client.AddConn() + } if err = s.auth(r, c, host.Client.Cnf.U, host.Client.Cnf.P); err != nil { logs.Warn("auth error", err, r.RemoteAddr) return } -reset: if targetAddr, err = host.Target.GetRandomTarget(); err != nil { logs.Warn(err.Error()) return @@ -157,7 +163,6 @@ reset: return } connClient = conn.GetConn(target, lk.Crypt, lk.Compress, host.Client.Rate, true) - lastHost = host //read from inc-client go func() { @@ -214,7 +219,7 @@ reset: } //change the host and header and set proxy setting - common.ChangeHostAndHeader(r, host.HostChange, host.HeaderChange, c.Conn.RemoteAddr().String()) + common.ChangeHostAndHeader(r, host.HostChange, host.HeaderChange, c.Conn.RemoteAddr().String(), s.addOrigin) logs.Trace("%s request, method %s, host %s, url %s, remote address %s, target %s", r.URL.Scheme, r.Method, r.Host, r.URL.Path, c.RemoteAddr().String(), lk.Host) //write lenConn = conn.NewLenConn(connClient) @@ -235,9 +240,8 @@ reset: if hostTmp, err := file.GetDb().GetInfoByHost(r.Host, r); err != nil { logs.Notice("the url %s %s %s can't be parsed!", r.URL.Scheme, r.Host, r.RequestURI) break - } else if host != lastHost { + } else if host != hostTmp { host = hostTmp - lastHost = host isReset = true connClient.Close() goto reset diff --git a/server/proxy/udp.go b/server/proxy/udp.go index abe2c7f..fa3d0be 100755 --- a/server/proxy/udp.go +++ b/server/proxy/udp.go @@ -55,9 +55,11 @@ func (s *UdpModeServer) process(addr *net.UDPAddr, data []byte) { } defer s.task.Client.AddConn() link := conn.NewLink(common.CONN_UDP, s.task.Target.TargetStr, s.task.Client.Cnf.Crypt, s.task.Client.Cnf.Compress, addr.String(), s.task.Target.LocalProxy) - if target, err := s.bridge.SendLinkInfo(s.task.Client.Id, link, s.task); err != nil { + if clientConn, err := s.bridge.SendLinkInfo(s.task.Client.Id, link, s.task); err != nil { return } else { + target := conn.GetConn(clientConn, s.task.Client.Cnf.Crypt, s.task.Client.Cnf.Compress, nil, true) + defer target.Close() s.task.Flow.Add(int64(len(data)), 0) buf := common.BufPoolUdp.Get().([]byte) defer common.BufPoolUdp.Put(buf) diff --git a/server/server.go b/server/server.go index b1de97e..bae6439 100644 --- a/server/server.go +++ b/server/server.go @@ -7,6 +7,7 @@ import ( "os" "strconv" "strings" + "sync" "time" "ehang.io/nps/bridge" @@ -24,11 +25,11 @@ import ( var ( Bridge *bridge.Bridge - RunList map[int]interface{} + RunList sync.Map //map[int]interface{} ) func init() { - RunList = make(map[int]interface{}) + RunList = sync.Map{} } //init task from db @@ -37,7 +38,8 @@ func InitFromCsv() { if vkey := beego.AppConfig.String("public_vkey"); vkey != "" { c := file.NewClient(vkey, true, true) file.GetDb().NewClient(c) - RunList[c.Id] = nil + RunList.Store(c.Id, nil) + //RunList[c.Id] = nil } //Initialize services in server-side files file.GetDb().JsonDb.Tasks.Range(func(key, value interface{}) bool { @@ -102,7 +104,8 @@ func StartNewServer(bridgePort int, cnf *file.Tunnel, bridgeType string) { if err := svr.Start(); err != nil { logs.Error(err) } - RunList[cnf.Id] = svr + RunList.Store(cnf.Id, svr) + //RunList[cnf.Id] = svr } else { logs.Error("Incorrect startup mode %s", cnf.Mode) } @@ -147,14 +150,16 @@ func NewMode(Bridge *bridge.Bridge, c *file.Tunnel) proxy.Service { httpsPort, _ := beego.AppConfig.Int("https_proxy_port") useCache, _ := beego.AppConfig.Bool("http_cache") cacheLen, _ := beego.AppConfig.Int("http_cache_length") - service = proxy.NewHttp(Bridge, c, httpPort, httpsPort, useCache, cacheLen) + addOrigin, _ := beego.AppConfig.Bool("http_add_origin_header") + service = proxy.NewHttp(Bridge, c, httpPort, httpsPort, useCache, cacheLen, addOrigin) } return service } //stop server func StopServer(id int) error { - if v, ok := RunList[id]; ok { + //if v, ok := RunList[id]; ok { + if v, ok := RunList.Load(id); ok { if svr, ok := v.(proxy.Service); ok { if err := svr.Close(); err != nil { return err @@ -169,7 +174,8 @@ func StopServer(id int) error { t.Status = false file.GetDb().UpdateTask(t) } - delete(RunList, id) + //delete(RunList, id) + RunList.Delete(id) return nil } return errors.New("task is not running") @@ -179,7 +185,8 @@ func StopServer(id int) error { func AddTask(t *file.Tunnel) error { if t.Mode == "secret" || t.Mode == "p2p" { logs.Info("secret task %s start ", t.Remark) - RunList[t.Id] = nil + //RunList[t.Id] = nil + RunList.Store(t.Id, nil) return nil } if b := tool.TestServerPort(t.Port, t.Mode); !b && t.Mode != "httpHostServer" { @@ -191,11 +198,13 @@ func AddTask(t *file.Tunnel) error { } if svr := NewMode(Bridge, t); svr != nil { logs.Info("tunnel task %s start mode:%s port %d", t.Remark, t.Mode, t.Port) - RunList[t.Id] = svr + //RunList[t.Id] = svr + RunList.Store(t.Id, svr) go func() { if err := svr.Start(); err != nil { logs.Error("clientId %d taskId %d start error %s", t.Client.Id, t.Id, err) - delete(RunList, t.Id) + //delete(RunList, t.Id) + RunList.Delete(t.Id) return } }() @@ -219,7 +228,8 @@ func StartTask(id int) error { //delete task func DelTask(id int) error { - if _, ok := RunList[id]; ok { + //if _, ok := RunList[id]; ok { + if _, ok := RunList.Load(id); ok { if err := StopServer(id); err != nil { return err } @@ -249,7 +259,8 @@ func GetTunnel(start, length int, typeVal string, clientId int, search string) ( } if start--; start < 0 { if length--; length >= 0 { - if _, ok := RunList[v.Id]; ok { + //if _, ok := RunList[v.Id]; ok { + if _, ok := RunList.Load(v.Id); ok { v.RunStatus = true } else { v.RunStatus = false diff --git a/web/controllers/base.go b/web/controllers/base.go index 426692f..cf4da6a 100755 --- a/web/controllers/base.go +++ b/web/controllers/base.go @@ -33,10 +33,13 @@ func (s *BaseController) Prepare() { timestamp := s.GetIntNoErr("timestamp") configKey := beego.AppConfig.String("auth_key") timeNowUnix := time.Now().Unix() - if !((math.Abs(float64(timeNowUnix-int64(timestamp))) <= 20) && (crypt.Md5(configKey+strconv.Itoa(timestamp)) == md5Key)) { + if !(md5Key!="" && (math.Abs(float64(timeNowUnix-int64(timestamp))) <= 20) && (crypt.Md5(configKey+strconv.Itoa(timestamp)) == md5Key)) { if s.GetSession("auth") != true { s.Redirect(beego.AppConfig.String("web_base_url")+"/login/index", 302) } + }else { + s.SetSession("isAdmin",true) + s.Data["isAdmin"] = true } if s.GetSession("isAdmin") != nil && !s.GetSession("isAdmin").(bool) { s.Ctx.Input.SetData("client_id", s.GetSession("clientId").(int))