diff --git a/docs/webapi.md b/docs/webapi.md new file mode 100644 index 0000000..836358b --- /dev/null +++ b/docs/webapi.md @@ -0,0 +1,233 @@ +获取客户端列表 + +``` +POST /client/list/ +``` + + +| 参数 | 含义 | +| --- | --- | +| search | 搜索 | +| order | 排序asc 正序 desc倒序 | +| offset | 分页(第几页) | +| limit | 条数(分页显示的条数) | + +*** +获取单个客户端 + +``` +POST /client/getclient/ +``` + + +| 参数 | 含义 | +| --- | --- | +| id | 客户端id | + +*** +添加客户端 + +``` +POST /client/add/ +``` + +| 参数 | 含义 | +| --- | --- | +| remark | 备注 | +| u | basic权限认证用户名 | +| p | basic权限认证密码 | +| limit | 条数(分页显示的条数) | +| vkey | 客户端验证密钥 | +| config\_conn\_allow | 是否允许客户端以配置文件模式连接 1允许 0不允许 | +| compress | 压缩1允许 0不允许 | +| crypt | 是否加密(1或者0)1允许 0不允许 | +| rate\_limit | 带宽限制 单位KB/S 空则为不限制 | +| flow\_limit | 流量限制 单位M 空则为不限制 | +| max\_conn | 客户端最大连接数量 空则为不限制 | +| max\_tunnel | 客户端最大隧道数量 空则为不限制 | + +*** +修改客户端(25.4版本有问题暂时不能用) + +``` +POST /client/edit/ +``` + +| 参数 | 含义 | +| --- | --- | +| remark | 备注 | +| u | basic权限认证用户名 | +| p | basic权限认证密码 | +| limit | 条数(分页显示的条数) | +| vkey | 客户端验证密钥 | +| config\_conn\_allow | 是否允许客户端以配置文件模式连接 1允许 0不允许 | +| compress | 压缩1允许 0不允许 | +| crypt | 是否加密(1或者0)1允许 0不允许 | +| rate\_limit | 带宽限制 单位KB/S 空则为不限制 | +| flow\_limit | 流量限制 单位M 空则为不限制 | +| max\_conn | 客户端最大连接数量 空则为不限制 | +| max\_tunnel | 客户端最大隧道数量 空则为不限制 | +| id | 要修改的客户端id | + +*** +删除客户端 + +``` +POST /client/del/ +``` + +| 参数 | 含义 | +| --- | --- | +| id | 要删除的客户端id | + +*** +获取域名解析列表 + +``` +POST /index/hostlist/ +``` + +| 参数 | 含义 | +| --- | --- | +| search | 搜索(可以搜域名/备注什么的) | +| offset | 分页(第几页) | +| limit | 条数(分页显示的条数) | + +*** +添加域名解析 + +``` +POST /index/addhost/ +``` + + +| 参数 | 含义 | +| --- | --- | +| remark | 备注 | +| host | 域名 | +| scheme | 协议类型(三种 all http https) | +| location | url路由 空则为不限制 | +| client\_id | 客户端id | +| target | 内网目标(ip:端口) | +| header | request header 请求头 | +| hostchange | request host 请求主机 | + +*** +修改域名解析 + +``` +POST /index/edithost/ +``` + +| 参数 | 含义 | +| --- | --- | +| remark | 备注 | +| host | 域名 | +| scheme | 协议类型(三种 all http https) | +| location | url路由 空则为不限制 | +| client\_id | 客户端id | +| target | 内网目标(ip:端口) | +| header | request header 请求头 | +| hostchange | request host 请求主机 | +| id | 需要修改的域名解析id | + +*** +删除域名解析 + +``` +POST /index/delhost/ +``` + +| 参数 | 含义 | +| --- | --- | +| id | 需要删除的域名解析id | + +*** +获取单条隧道信息 + +``` +POST /index/getonetunnel/ +``` + +| 参数 | 含义 | +| --- | --- | +| id | 隧道的id | + +*** +获取隧道列表 + +``` +POST /index/gettunnel/ +``` + +| 参数 | 含义 | +| --- | --- | +| client\_id | 穿透隧道的客户端id | +| type | 类型tcp udp httpProx socks5 secret p2p | +| search | 搜索 | +| offset | 分页(第几页) | +| limit | 条数(分页显示的条数) | + +*** +添加隧道 + +``` +POST /index/add/ +``` + +| 参数 | 含义 | +| --- | --- | +| type | 类型tcp udp httpProx socks5 secret p2p | +| remark | 备注 | +| port | 服务端端口 | +| target | 目标(ip:端口) | +| client\_id | 客户端id | + +*** +修改隧道 + +``` +POST /index/edit/ +``` + +| 参数 | 含义 | +| --- | --- | +| type | 类型tcp udp httpProx socks5 secret p2p | +| remark | 备注 | +| port | 服务端端口 | +| target | 目标(ip:端口) | +| client\_id | 客户端id | +| id | 隧道id | + +*** +删除隧道 + +``` +POST /index/del/ +``` + +| 参数 | 含义 | +| --- | --- | +| id | 隧道id | + +*** +隧道停止工作 + +``` +POST /index/stop/ +``` + +| 参数 | 含义 | +| --- | --- | +| id | 隧道id | + +*** +隧道开始工作 + +``` +POST /index/start/ +``` + +| 参数 | 含义 | +| --- | --- | +| id | 隧道id | diff --git a/image/work_flow.svg b/image/work_flow.svg new file mode 100644 index 0000000..5b3794b --- /dev/null +++ b/image/work_flow.svg @@ -0,0 +1,821 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + 页-1 + + + + + + + + + + + + + + + + + + + + + + + + 防火墙 + NAT + + 工作表.2 + + + + 工作表.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NAT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 服务器 + Application2 10.0.0.4:PORT + + 工作表.5 + + + + 工作表.6 + + + + 工作表.7 + + + + + + + + + + Application210.0.0.4:PORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 服务器.8 + Application1 10.0.0.3:PORT + + 工作表.9 + + + + 工作表.10 + + + + 工作表.11 + + + + + + + + + + Application110.0.0.3:PORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 服务器.12 + Application3 10.0.0.5:PORT + + 工作表.13 + + + + 工作表.14 + + + + 工作表.15 + + + + + + + + + + Application310.0.0.5:PORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 主机 + NPC Client 10.0.0.2 Dial To: ->10.0.0.3:PORT ->10.0.0.4:PORT ... + + 工作表.17 + + + + + + 工作表.18 + + + + + + + + 工作表.19 + + + + + + NPCClient10.0.0.2Dial To:->10.0.0.3:PORT->10.0.0.4:PORT->10.0.0.5:PORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 主机.20 + NPS Server 1.1.1.1 Listen On: 8003->10.0.0.3:PORT 8004->10.0.... + + 工作表.21 + + + + + + 工作表.22 + + + + + + + + 工作表.23 + + + + + + NPSServer1.1.1.1Listen On:8003->10.0.0.3:PORT8004->10.0.0.4:PORT8005->10.0.0.5:PORT + + + + + + + + + + + + + + + + + + 用户 + User1 Wants:APP1 + + 工作表.25 + + + + + + User1Wants:APP1 + + + + + + + + + + + + + + + + + + 用户.26 + User2 Wants:APP2 + + 工作表.27 + + + + + + User2Wants:APP2 + + + + + + + + + + + + + + + + + + 用户.28 + User3 Wants:APP3 + + 工作表.29 + + + + + + User3Wants:APP3 + + + 动态连接线.1003 + ->8003 Multi Conn + + + + + + + + ->8003Multi Conn + + 动态连接线.1004 + ->8004 Multi Conn + + + + + + + + ->8004Multi Conn + + 动态连接线.1005 + ->8005 Multi Conn + + + + + + + + ->8005Multi Conn + + 动态连接线.1006 + NPS & NPC Multiplexing Connection TCP or KCP Only One Conn Pe... + + + + + + + + NPS & NPCMultiplexingConnectionTCP or KCPOnly OneConn PeerNPC + + 动态连接线.1007 + ->PORT Multi Conn + + + + + + + + ->PORTMulti Conn + + 动态连接线.1008 + ->PORT Multi Conn + + + + + + + + ->PORTMulti Conn + + 动态连接线.1009 + ->PORT Multi Conn + + + + + + + + ->PORTMulti Conn + + 动态连接线.1010 + NPS & NPC + + + + + + + + NPS&NPC + + 工作表.1011 + + + + 工作表.1012 + + + + 工作表.1013 + Internet + + + + Internet + + 工作表.1014 + Intranet + + + + Intranet + + diff --git a/lib/mux/conn.go b/lib/mux/conn.go index 6d65f7c..85ba1ef 100644 --- a/lib/mux/conn.go +++ b/lib/mux/conn.go @@ -202,7 +202,7 @@ type ReceiveWindow struct { bufQueue ReceiveWindowQueue element *common.ListElement count int8 - bw *bandwidth + bw *writeBandwidth once sync.Once // receive window send the current max size and read size to send window // means done size actually store the size receive window has read @@ -215,7 +215,7 @@ func (Self *ReceiveWindow) New(mux *Mux) { Self.maxSizeDone = Self.pack(common.MAXIMUM_SEGMENT_SIZE*30, 0, false) Self.mux = mux Self.window.New() - Self.bw = NewBandwidth(nil) + Self.bw = NewWriteBandwidth() } func (Self *ReceiveWindow) remainingSize(maxSize uint32, delta uint16) (n uint32) { @@ -232,9 +232,15 @@ func (Self *ReceiveWindow) calcSize() { // calculating maximum receive window size if Self.count == 0 { //logs.Warn("ping, bw", Self.mux.latency, Self.bw.Get()) - conns := Self.mux.connMap.Size() - n := uint32(math.Float64frombits(atomic.LoadUint64(&Self.mux.latency)) * - (Self.mux.bw.Get() + Self.bw.Get())) + //conns := Self.mux.connMap.Size() + muxBw := Self.mux.bw.Get() + connBw := Self.bw.Get() + //logs.Warn("muxbw connbw", muxBw, connBw) + var n uint32 + if connBw > 0 && muxBw > 0 { + n = uint32(math.Float64frombits(atomic.LoadUint64(&Self.mux.latency)) * + (muxBw + connBw)) + } //logs.Warn(n) if n < common.MAXIMUM_SEGMENT_SIZE*30 { //logs.Warn("window small", n, Self.mux.bw.Get(), Self.bw.Get()) @@ -252,9 +258,12 @@ func (Self *ReceiveWindow) calcSize() { n = 2 * size // twice grow } - if n > (common.MAXIMUM_WINDOW_SIZE / uint32(conns)) { - logs.Warn("window too large, calculated:", n, "limit:", common.MAXIMUM_WINDOW_SIZE/uint32(conns)) - n = common.MAXIMUM_WINDOW_SIZE / uint32(conns) + if connBw > 0 && muxBw > 0 { + limit := uint32(common.MAXIMUM_WINDOW_SIZE * (connBw / (muxBw + connBw))) + if n > limit { + logs.Warn("window too large, calculated:", n, "limit:", limit, connBw, muxBw) + n = limit + } } // set the maximum size //logs.Warn("n", n) @@ -664,3 +673,50 @@ func (Self *SendWindow) SetTimeOut(t time.Time) { // waiting for receive a receive window size Self.timeout = t } + +type writeBandwidth struct { + writeBW uint64 // store in bits, but it's float64 + readEnd time.Time + duration float64 + bufLength uint32 +} + +const writeCalcThreshold uint32 = 5 * 1024 * 1024 + +func NewWriteBandwidth() *writeBandwidth { + return &writeBandwidth{} +} + +func (Self *writeBandwidth) StartRead() { + if Self.readEnd.IsZero() { + Self.readEnd = time.Now() + } + Self.duration += time.Now().Sub(Self.readEnd).Seconds() + if Self.bufLength >= writeCalcThreshold { + Self.calcBandWidth() + } +} + +func (Self *writeBandwidth) SetCopySize(n uint16) { + Self.bufLength += uint32(n) + Self.endRead() +} + +func (Self *writeBandwidth) endRead() { + Self.readEnd = time.Now() +} + +func (Self *writeBandwidth) calcBandWidth() { + atomic.StoreUint64(&Self.writeBW, math.Float64bits(float64(Self.bufLength)/Self.duration)) + Self.bufLength = 0 + Self.duration = 0 +} + +func (Self *writeBandwidth) Get() (bw float64) { + // The zero value, 0 for numeric types + bw = math.Float64frombits(atomic.LoadUint64(&Self.writeBW)) + if bw <= 0 { + bw = 0 + } + return +} diff --git a/lib/mux/mux.go b/lib/mux/mux.go index f89bbc4..52bd81c 100644 --- a/lib/mux/mux.go +++ b/lib/mux/mux.go @@ -443,7 +443,7 @@ func (Self *bandwidth) Get() (bw float64) { // The zero value, 0 for numeric types bw = math.Float64frombits(atomic.LoadUint64(&Self.readBandwidth)) if bw <= 0 { - bw = 100 + bw = 0 } //logs.Warn(bw) return