multiple changes

pull/265/head
ffdfgdfg 2019-10-12 22:56:37 +08:00
parent 4c8d7b0738
commit 1f8e441090
14 changed files with 176 additions and 33 deletions

View File

@ -197,6 +197,9 @@ nps是一款轻量级、高性能、功能强大的**内网穿透**代理服务
- 在刚才创建的客户端隧道管理中添加一条socks5代理填写监听的端口8003保存。 - 在刚才创建的客户端隧道管理中添加一条socks5代理填写监听的端口8003保存。
- 在外网环境的本机配置socks5代理(例如使用proxifier进行全局代理)ip为公网服务器ip1.1.1.1),端口为填写的监听端口(8003),即可畅享内网了 - 在外网环境的本机配置socks5代理(例如使用proxifier进行全局代理)ip为公网服务器ip1.1.1.1),端口为填写的监听端口(8003),即可畅享内网了
**注意**
经过socks5代理当收到socks5数据包时socket已经是accept状态。表现是扫描端口全open建立连接后短时间关闭。若想同内网表现一致建议远程连接一台设备。
### http正向代理 ### http正向代理
**适用范围:** 在外网环境下使用http正向代理访问内网站点 **适用范围:** 在外网环境下使用http正向代理访问内网站点
@ -375,7 +378,13 @@ server {
``` ```
(./nps|nps.exe) install (./nps|nps.exe) install
``` ```
安装成功后对于linuxdarwin将会把配置文件和静态文件放置于/etc/nps/并将可执行文件nps复制到/usr/bin/nps或者/usr/local/bin/nps安装成功后可在任何位置执行 安装成功后对于linuxdarwin将会把配置文件和静态文件放置于/etc/nps/并将可执行文件nps复制到/usr/bin/nps或者/usr/local/bin/nps安装成功后可在任何位置执行同时也会添加systemd配置。
```
sudo systemctl enable|disable|start|stop|restart|status nps
```
systemd带有开机自启自动重启配置当进程结束后15秒会启动日志输出至/var/log/nps/nps.log。
建议采用此方式启动能够捕获panic信息便于排查问题。
``` ```
nps test|start|stop|restart|status nps test|start|stop|restart|status

View File

@ -49,6 +49,11 @@ retry:
time.Sleep(time.Second * 5) time.Sleep(time.Second * 5)
goto retry goto retry
} }
if c == nil {
logs.Error("Error data from server, and will be reconnected in five seconds")
time.Sleep(time.Second * 5)
goto retry
}
logs.Info("Successful connection with server %s", s.svrAddr) logs.Info("Successful connection with server %s", s.svrAddr)
//monitor the connection //monitor the connection
go s.ping() go s.ping()

View File

@ -223,8 +223,13 @@ func NewConn(tp string, vkey string, server string, connType string, proxyUrl st
if _, err := c.Write([]byte(crypt.Md5(version.GetVersion()))); err != nil { if _, err := c.Write([]byte(crypt.Md5(version.GetVersion()))); err != nil {
return nil, err return nil, err
} }
if b, err := c.GetShortContent(32); err != nil || crypt.Md5(version.GetVersion()) != string(b) { b, err := c.GetShortContent(32)
logs.Error("The client does not match the server version. The current version of the client is", version.GetVersion()) if err != nil {
logs.Error(err)
return nil, err
}
if crypt.Md5(version.GetVersion()) != string(b) {
logs.Error("The client does not match the server version. The current core version of the client is", version.GetVersion())
return nil, err return nil, err
} }
if _, err := c.Write([]byte(common.Getverifyval(vkey))); err != nil { if _, err := c.Write([]byte(common.Getverifyval(vkey))); err != nil {

View File

@ -61,7 +61,7 @@ func main() {
logs.Error("Getting bridge_port error", err) logs.Error("Getting bridge_port error", err)
os.Exit(0) os.Exit(0)
} }
logs.Info("the version of server is %s ,allow client version to be %s", version.VERSION, version.GetVersion()) logs.Info("the version of server is %s ,allow client core version to be %s", version.VERSION, version.GetVersion())
connection.InitConnectionService() connection.InitConnectionService()
crypt.InitTls(filepath.Join(common.GetRunPath(), "conf", "server.pem"), filepath.Join(common.GetRunPath(), "conf", "server.key")) crypt.InitTls(filepath.Join(common.GetRunPath(), "conf", "server.pem"), filepath.Join(common.GetRunPath(), "conf", "server.key"))
tool.InitAllowPort() tool.InitAllowPort()

View File

@ -49,4 +49,5 @@ const (
MUX_PING_RETURN MUX_PING_RETURN
MUX_PING int32 = -1 MUX_PING int32 = -1
MAXIMUM_SEGMENT_SIZE = PoolSizeWindow MAXIMUM_SEGMENT_SIZE = PoolSizeWindow
MAXIMUM_WINDOW_SIZE = 1<<31 - 1
) )

View File

@ -158,8 +158,10 @@ func (Self *MuxPackager) NewPac(flag uint8, id int32, content ...interface{}) (e
Self.Flag = flag Self.Flag = flag
Self.Id = id Self.Id = id
switch flag { switch flag {
case MUX_NEW_MSG, MUX_NEW_MSG_PART, MUX_PING_FLAG, MUX_PING_RETURN: case MUX_PING_FLAG, MUX_PING_RETURN, MUX_NEW_MSG, MUX_NEW_MSG_PART:
Self.Content = WindowBuff.Get()
err = Self.BasePackager.NewPac(content...) err = Self.BasePackager.NewPac(content...)
//logs.Warn(Self.Length, string(Self.Content))
case MUX_MSG_SEND_OK: case MUX_MSG_SEND_OK:
// MUX_MSG_SEND_OK contains two data // MUX_MSG_SEND_OK contains two data
switch content[0].(type) { switch content[0].(type) {
@ -190,6 +192,7 @@ func (Self *MuxPackager) Pack(writer io.Writer) (err error) {
switch Self.Flag { switch Self.Flag {
case MUX_NEW_MSG, MUX_NEW_MSG_PART, MUX_PING_FLAG, MUX_PING_RETURN: case MUX_NEW_MSG, MUX_NEW_MSG_PART, MUX_PING_FLAG, MUX_PING_RETURN:
err = Self.BasePackager.Pack(writer) err = Self.BasePackager.Pack(writer)
WindowBuff.Put(Self.Content)
case MUX_MSG_SEND_OK: case MUX_MSG_SEND_OK:
err = binary.Write(writer, binary.LittleEndian, Self.Window) err = binary.Write(writer, binary.LittleEndian, Self.Window)
if err != nil { if err != nil {
@ -201,7 +204,6 @@ func (Self *MuxPackager) Pack(writer io.Writer) (err error) {
} }
func (Self *MuxPackager) UnPack(reader io.Reader) (err error) { func (Self *MuxPackager) UnPack(reader io.Reader) (err error) {
Self.BasePackager.clean() // also clean the content
err = binary.Read(reader, binary.LittleEndian, &Self.Flag) err = binary.Read(reader, binary.LittleEndian, &Self.Flag)
if err != nil { if err != nil {
return return
@ -212,7 +214,10 @@ func (Self *MuxPackager) UnPack(reader io.Reader) (err error) {
} }
switch Self.Flag { switch Self.Flag {
case MUX_NEW_MSG, MUX_NEW_MSG_PART, MUX_PING_FLAG, MUX_PING_RETURN: case MUX_NEW_MSG, MUX_NEW_MSG_PART, MUX_PING_FLAG, MUX_PING_RETURN:
Self.Content = WindowBuff.Get() // need get a window buf from pool
Self.BasePackager.clean() // also clean the content
err = Self.BasePackager.UnPack(reader) err = Self.BasePackager.UnPack(reader)
//logs.Warn("unpack", Self.Length, string(Self.Content))
case MUX_MSG_SEND_OK: case MUX_MSG_SEND_OK:
err = binary.Read(reader, binary.LittleEndian, &Self.Window) err = binary.Read(reader, binary.LittleEndian, &Self.Window)
if err != nil { if err != nil {

View File

@ -104,11 +104,7 @@ func (Self *windowBufferPool) Get() (buf []byte) {
} }
func (Self *windowBufferPool) Put(x []byte) { func (Self *windowBufferPool) Put(x []byte) {
if len(x) == PoolSizeWindow {
Self.pool.Put(x[:PoolSizeWindow]) // make buf to full Self.pool.Put(x[:PoolSizeWindow]) // make buf to full
} else {
x = nil
}
} }
type bufferPool struct { type bufferPool struct {
@ -146,13 +142,10 @@ func (Self *muxPackagerPool) New() {
} }
func (Self *muxPackagerPool) Get() *MuxPackager { func (Self *muxPackagerPool) Get() *MuxPackager {
pack := Self.pool.Get().(*MuxPackager) return Self.pool.Get().(*MuxPackager)
pack.Content = WindowBuff.Get()
return pack
} }
func (Self *muxPackagerPool) Put(pack *MuxPackager) { func (Self *muxPackagerPool) Put(pack *MuxPackager) {
WindowBuff.Put(pack.Content)
Self.pool.Put(pack) Self.pool.Put(pack)
} }

View File

@ -268,6 +268,9 @@ func CopyBuffer(dst io.Writer, src io.Reader) (written int64, err error) {
defer CopyBuff.Put(buf) defer CopyBuff.Put(buf)
for { for {
nr, er := src.Read(buf) nr, er := src.Read(buf)
//if len(pr)>0 && pr[0] && nr > 50 {
// logs.Warn(string(buf[:50]))
//}
if nr > 0 { if nr > 0 {
nw, ew := dst.Write(buf[0:nr]) nw, ew := dst.Write(buf[0:nr])
if nw > 0 { if nw > 0 {

View File

@ -4,6 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
@ -13,6 +14,23 @@ import (
) )
func InstallNps() { func InstallNps() {
unit := `[Unit]
Description=nps - convenient proxy server
Documentation=https://github.com/cnlh/nps/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target`
service := `[Service]
Type=simple
KillMode=process
Restart=always
RestartSec=15s
StandardOutput=append:/var/log/nps/nps.log
ExecStartPre=/bin/echo 'Starting nps'
ExecStopPost=/bin/echo 'Stopping nps'
ExecStart=`
install := `[Install]
WantedBy=multi-user.target`
path := common.GetInstallPath() path := common.GetInstallPath()
if common.FileExists(path) { if common.FileExists(path) {
log.Fatalf("the path %s has exist, does not support install", path) log.Fatalf("the path %s has exist, does not support install", path)
@ -35,21 +53,35 @@ func InstallNps() {
log.Fatalln(err) log.Fatalln(err)
} else { } else {
os.Chmod("/usr/local/bin/nps", 0755) os.Chmod("/usr/local/bin/nps", 0755)
service += "/usr/local/bin/nps"
log.Println("Executable files have been copied to", "/usr/local/bin/nps") log.Println("Executable files have been copied to", "/usr/local/bin/nps")
} }
} else { } else {
os.Chmod("/usr/bin/nps", 0755) os.Chmod("/usr/bin/nps", 0755)
service += "/usr/bin/nps"
log.Println("Executable files have been copied to", "/usr/bin/nps") log.Println("Executable files have been copied to", "/usr/bin/nps")
} }
systemd := unit + "\n\n" + service + "\n\n" + install
_ = os.Remove("/usr/lib/systemd/system/nps.service")
err := ioutil.WriteFile("/usr/lib/systemd/system/nps.service", []byte(systemd), 0644)
if err != nil {
log.Println("Write systemd service err ", err)
}
_ = os.Mkdir("/var/log/nps", 644)
} }
log.Println("install ok!") log.Println("install ok!")
log.Println("Static files and configuration files in the current directory will be useless") log.Println("Static files and configuration files in the current directory will be useless")
log.Println("The new configuration file is located in", path, "you can edit them") log.Println("The new configuration file is located in", path, "you can edit them")
if !common.IsWindows() { if !common.IsWindows() {
log.Println("You can start with nps test|start|stop|restart|status anywhere") log.Println(`You can start with:
sudo systemctl enable|disable|start|stop|restart|status nps
or:
nps test|start|stop|restart|status
anywhere!`)
} else { } else {
log.Println("You can copy executable files to any directory and start working with nps.exe test|start|stop|restart|status") log.Println(`You can copy executable files to any directory and start working with:
nps.exe test|start|stop|restart|status
now!`)
} }
} }
func MkidrDirAll(path string, v ...string) { func MkidrDirAll(path string, v ...string) {

View File

@ -183,6 +183,10 @@ func (Self *ReceiveWindow) CalcSize() {
n = Self.bufQueue.Len() n = Self.bufQueue.Len()
} }
// set the minimal size // set the minimal size
if n > common.MAXIMUM_WINDOW_SIZE {
n = common.MAXIMUM_WINDOW_SIZE
}
// set the maximum size
//logs.Warn("n", n) //logs.Warn("n", n)
Self.maxSize = n Self.maxSize = n
Self.count = -5 Self.count = -5
@ -248,6 +252,10 @@ copyData:
l = 0 l = 0
Self.bw.EndRead() Self.bw.EndRead()
Self.sendStatus(id) Self.sendStatus(id)
if Self.off == uint32(Self.element.l) {
//logs.Warn("put the element end ", string(Self.element.buf[:15]))
common.WindowBuff.Put(Self.element.buf)
}
if pOff < len(p) && Self.element.part { if pOff < len(p) && Self.element.part {
// element is a part of the segments, trying to fill up buf p // element is a part of the segments, trying to fill up buf p
goto copyData goto copyData

View File

@ -25,6 +25,7 @@ type Mux struct {
pingOk int pingOk int
latency float64 latency float64
pingCh chan []byte pingCh chan []byte
pingTimer *time.Timer
connType string connType string
writeQueue PriorityQueue writeQueue PriorityQueue
bufCh chan *bytes.Buffer bufCh chan *bytes.Buffer
@ -42,6 +43,7 @@ func NewMux(c net.Conn, connType string) *Mux {
connType: connType, connType: connType,
bufCh: make(chan *bytes.Buffer), bufCh: make(chan *bytes.Buffer),
pingCh: make(chan []byte), pingCh: make(chan []byte),
pingTimer: time.NewTimer(15 * time.Second),
} }
m.writeQueue.New() m.writeQueue.New()
//read session by flag //read session by flag
@ -119,6 +121,7 @@ func (s *Mux) packBuf() {
common.BuffPool.Put(buffer) common.BuffPool.Put(buffer)
break break
} }
//logs.Warn(buffer.String())
select { select {
case s.bufCh <- buffer: case s.bufCh <- buffer:
case <-s.closeChan: case <-s.closeChan:
@ -153,7 +156,7 @@ func (s *Mux) ping() {
now, _ := time.Now().UTC().MarshalText() now, _ := time.Now().UTC().MarshalText()
s.sendInfo(common.MUX_PING_FLAG, common.MUX_PING, now) s.sendInfo(common.MUX_PING_FLAG, common.MUX_PING, now)
// send the ping flag and get the latency first // send the ping flag and get the latency first
ticker := time.NewTicker(time.Second * 15) ticker := time.NewTicker(time.Second * 5)
for { for {
if s.IsClose { if s.IsClose {
ticker.Stop() ticker.Stop()
@ -168,6 +171,10 @@ func (s *Mux) ping() {
} }
now, _ := time.Now().UTC().MarshalText() now, _ := time.Now().UTC().MarshalText()
s.sendInfo(common.MUX_PING_FLAG, common.MUX_PING, now) s.sendInfo(common.MUX_PING_FLAG, common.MUX_PING, now)
if !s.pingTimer.Stop() {
<-s.pingTimer.C
}
s.pingTimer.Reset(15 * time.Second)
if s.pingOk > 10 && s.connType == "kcp" { if s.pingOk > 10 && s.connType == "kcp" {
s.Close() s.Close()
break break
@ -186,10 +193,15 @@ func (s *Mux) pingReturn() {
case data = <-s.pingCh: case data = <-s.pingCh:
case <-s.closeChan: case <-s.closeChan:
break break
case <-s.pingTimer.C:
logs.Error("mux: ping time out")
s.Close()
break
} }
_ = now.UnmarshalText(data) _ = now.UnmarshalText(data)
s.latency = time.Now().UTC().Sub(now).Seconds() / 2 s.latency = time.Now().UTC().Sub(now).Seconds() / 2
//logs.Warn("latency", s.latency) logs.Warn("latency", s.latency)
common.WindowBuff.Put(data)
if s.latency <= 0 { if s.latency <= 0 {
logs.Warn("latency err", s.latency) logs.Warn("latency err", s.latency)
} }
@ -218,6 +230,7 @@ func (s *Mux) readSession() {
continue continue
case common.MUX_PING_FLAG: //ping case common.MUX_PING_FLAG: //ping
s.sendInfo(common.MUX_PING_RETURN, common.MUX_PING, pack.Content) s.sendInfo(common.MUX_PING_RETURN, common.MUX_PING, pack.Content)
common.WindowBuff.Put(pack.Content)
continue continue
case common.MUX_PING_RETURN: case common.MUX_PING_RETURN:
s.pingCh <- pack.Content s.pingCh <- pack.Content

View File

@ -1,8 +1,11 @@
package mux package mux
import ( import (
"bufio"
"fmt"
"net" "net"
"net/http" "net/http"
"net/http/httputil"
_ "net/http/pprof" _ "net/http/pprof"
"sync" "sync"
"testing" "testing"
@ -37,6 +40,7 @@ func TestNewMux(t *testing.T) {
c2, err := net.Dial("tcp", "127.0.0.1:80") c2, err := net.Dial("tcp", "127.0.0.1:80")
if err != nil { if err != nil {
logs.Warn(err) logs.Warn(err)
c.Close()
continue continue
} }
go func(c2 net.Conn, c net.Conn) { go func(c2 net.Conn, c net.Conn) {
@ -107,6 +111,9 @@ func TestNewMux(t *testing.T) {
} }
}() }()
time.Sleep(time.Second * 5)
//go test_request()
for { for {
time.Sleep(time.Second * 5) time.Sleep(time.Second * 5)
} }
@ -135,6 +142,51 @@ func client() {
} }
} }
func test_request() {
conn, _ := net.Dial("tcp", "127.0.0.1:7777")
for {
conn.Write([]byte(`GET /videojs5/video.js HTTP/1.1
Host: 127.0.0.1:7777
Connection: keep-alive
`))
r, err := http.ReadResponse(bufio.NewReader(conn), nil)
if err != nil {
logs.Warn("close by read response err", err)
break
}
logs.Warn("read response success", r)
b, err := httputil.DumpResponse(r, true)
if err != nil {
logs.Warn("close by dump response err", err)
break
}
fmt.Println(string(b[:20]), err)
time.Sleep(time.Second)
}
}
func test_raw() {
conn, _ := net.Dial("tcp", "127.0.0.1:7777")
for {
conn.Write([]byte(`GET /videojs5/test HTTP/1.1
Host: 127.0.0.1:7777
Connection: keep-alive
`))
buf := make([]byte, 1000000)
n, err := conn.Read(buf)
if err != nil {
logs.Warn("close by read response err", err)
break
}
logs.Warn(n, string(buf[:50]), "\n--------------\n", string(buf[n-50:n]))
time.Sleep(time.Second)
}
}
func TestNewConn(t *testing.T) { func TestNewConn(t *testing.T) {
buf := common.GetBufPoolCopy() buf := common.GetBufPoolCopy()
logs.Warn(len(buf), cap(buf)) logs.Warn(len(buf), cap(buf))

View File

@ -51,15 +51,23 @@ func (Self *PriorityQueue) New() {
func (Self *PriorityQueue) Push(packager *common.MuxPackager) { func (Self *PriorityQueue) Push(packager *common.MuxPackager) {
Self.mutex.Lock() Self.mutex.Lock()
if Self.popWait { switch packager.Flag {
defer Self.allowPop() case common.MUX_PING_FLAG, common.MUX_PING_RETURN:
} Self.list.PushFront(packager)
if packager.Flag == common.MUX_CONN_CLOSE { // the ping package need highest priority
Self.insert(packager) // the close package may need priority, // prevent ping calculation error
// prevent wait too long to close case common.MUX_CONN_CLOSE:
} else { Self.insert(packager)
// the close package may need priority too, set second
// prevent wait too long to close conn
default:
Self.list.PushBack(packager) Self.list.PushBack(packager)
} }
if Self.popWait {
Self.mutex.Unlock()
Self.allowPop()
return
}
Self.mutex.Unlock() Self.mutex.Unlock()
return return
} }
@ -68,7 +76,14 @@ func (Self *PriorityQueue) insert(packager *common.MuxPackager) {
element := Self.list.Back() element := Self.list.Back()
for { for {
if element == nil { // PriorityQueue dose not have any of msg package with this close package id if element == nil { // PriorityQueue dose not have any of msg package with this close package id
Self.list.PushFront(packager) // insert close package to first element = Self.list.Front()
if element != nil {
Self.list.InsertAfter(packager, element)
// insert close package to second
} else {
Self.list.PushFront(packager)
// list is empty, push to front
}
break break
} }
if element.Value.(*common.MuxPackager).Flag == common.MUX_NEW_MSG && if element.Value.(*common.MuxPackager).Flag == common.MUX_NEW_MSG &&
@ -136,11 +151,13 @@ func (Self *FIFOQueue) New() {
func (Self *FIFOQueue) Push(element *ListElement) { func (Self *FIFOQueue) Push(element *ListElement) {
Self.mutex.Lock() Self.mutex.Lock()
if Self.popWait {
defer Self.allowPop()
}
Self.list = append(Self.list, element) Self.list = append(Self.list, element)
Self.length += uint32(element.l) Self.length += uint32(element.l)
if Self.popWait {
Self.mutex.Unlock()
Self.allowPop()
return
}
Self.mutex.Unlock() Self.mutex.Unlock()
return return
} }

View File

@ -1,8 +1,8 @@
package version package version
const VERSION = "0.23.2" const VERSION = "0.23.3"
// Compulsory minimum version, Minimum downward compatibility to this version // Compulsory minimum version, Minimum downward compatibility to this version
func GetVersion() string { func GetVersion() string {
return "0.21.0" return "0.22.0"
} }