mirror of
https://github.com/ehang-io/nps.git
synced 2025-09-02 11:56:53 +00:00
https 、客户端与服务端连接优化
This commit is contained in:
312
utils/conn.go
312
utils/conn.go
@@ -13,6 +13,7 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -52,12 +53,6 @@ func (s *CryptConn) Write(b []byte) (n int, err error) {
|
||||
|
||||
//解密读
|
||||
func (s *CryptConn) Read(b []byte) (n int, err error) {
|
||||
defer func() {
|
||||
if err == nil && n == len(IO_EOF) && string(b[:n]) == IO_EOF {
|
||||
err = io.EOF
|
||||
n = 0
|
||||
}
|
||||
}()
|
||||
var lens int
|
||||
var buf []byte
|
||||
var rb []byte
|
||||
@@ -122,14 +117,8 @@ func (s *SnappyConn) Write(b []byte) (n int, err error) {
|
||||
|
||||
//snappy压缩读 包含解密
|
||||
func (s *SnappyConn) Read(b []byte) (n int, err error) {
|
||||
buf := bufPool.Get().([]byte)
|
||||
defer func() {
|
||||
if err == nil && n == len(IO_EOF) && string(b[:n]) == IO_EOF {
|
||||
err = io.EOF
|
||||
n = 0
|
||||
}
|
||||
bufPool.Put(buf)
|
||||
}()
|
||||
buf := BufPool.Get().([]byte)
|
||||
defer BufPool.Put(buf)
|
||||
if n, err = s.r.Read(buf); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -152,6 +141,7 @@ func (s *SnappyConn) Read(b []byte) (n int, err error) {
|
||||
|
||||
type Conn struct {
|
||||
Conn net.Conn
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
//new conn
|
||||
@@ -161,101 +151,7 @@ func NewConn(conn net.Conn) *Conn {
|
||||
return c
|
||||
}
|
||||
|
||||
//读取指定长度内容
|
||||
func (s *Conn) ReadLen(cLen int) ([]byte, error) {
|
||||
if cLen > poolSize {
|
||||
return nil, errors.New("长度错误" + strconv.Itoa(cLen))
|
||||
}
|
||||
var buf []byte
|
||||
if cLen <= poolSizeSmall {
|
||||
buf = bufPoolSmall.Get().([]byte)[:cLen]
|
||||
defer bufPoolSmall.Put(buf)
|
||||
} else {
|
||||
buf = bufPoolMax.Get().([]byte)[:cLen]
|
||||
defer bufPoolMax.Put(buf)
|
||||
}
|
||||
if n, err := io.ReadFull(s, buf); err != nil || n != cLen {
|
||||
return buf, errors.New("读取指定长度错误" + err.Error())
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
//获取长度
|
||||
func (s *Conn) GetLen() (int, error) {
|
||||
val, err := s.ReadLen(4)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return GetLenByBytes(val)
|
||||
}
|
||||
|
||||
//写入长度+内容 粘包
|
||||
func (s *Conn) WriteLen(buf []byte) (int, error) {
|
||||
var b []byte
|
||||
var err error
|
||||
if b, err = GetLenBytes(buf); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return s.Write(b)
|
||||
}
|
||||
|
||||
//读取flag
|
||||
func (s *Conn) ReadFlag() (string, error) {
|
||||
val, err := s.ReadLen(4)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(val), err
|
||||
}
|
||||
|
||||
//读取host 连接地址 压缩类型
|
||||
func (s *Conn) GetHostFromConn() (typeStr string, host string, en, de int, crypt, mux bool, err error) {
|
||||
retry:
|
||||
lType, err := s.ReadLen(3)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if typeStr = string(lType); typeStr == TEST_FLAG {
|
||||
en, de, crypt, mux = s.GetConnInfoFromConn()
|
||||
goto retry
|
||||
} else if typeStr != CONN_TCP && typeStr != CONN_UDP {
|
||||
err = errors.New("unknown conn type")
|
||||
return
|
||||
}
|
||||
cLen, err := s.GetLen()
|
||||
if err != nil || cLen > poolSize {
|
||||
return
|
||||
}
|
||||
hostByte, err := s.ReadLen(cLen)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
host = string(hostByte)
|
||||
return
|
||||
}
|
||||
|
||||
//写连接类型 和 host地址
|
||||
func (s *Conn) WriteHost(ltype string, host string) (int, error) {
|
||||
raw := bytes.NewBuffer([]byte{})
|
||||
binary.Write(raw, binary.LittleEndian, []byte(ltype))
|
||||
binary.Write(raw, binary.LittleEndian, int32(len([]byte(host))))
|
||||
binary.Write(raw, binary.LittleEndian, []byte(host))
|
||||
return s.Write(raw.Bytes())
|
||||
}
|
||||
|
||||
//设置连接为长连接
|
||||
func (s *Conn) SetAlive() {
|
||||
conn := s.Conn.(*net.TCPConn)
|
||||
conn.SetReadDeadline(time.Time{})
|
||||
conn.SetKeepAlive(true)
|
||||
conn.SetKeepAlivePeriod(time.Duration(2 * time.Second))
|
||||
}
|
||||
|
||||
func (s *Conn) SetReadDeadline(t time.Duration) {
|
||||
s.Conn.(*net.TCPConn).SetReadDeadline(time.Now().Add(time.Duration(t) * time.Second))
|
||||
}
|
||||
|
||||
//从tcp报文中解析出host,连接类型等 TODO 多种情况
|
||||
//从tcp报文中解析出host,连接类型等
|
||||
func (s *Conn) GetHost() (method, address string, rb []byte, err error, r *http.Request) {
|
||||
var b [32 * 1024]byte
|
||||
var n int
|
||||
@@ -285,6 +181,71 @@ func (s *Conn) GetHost() (method, address string, rb []byte, err error, r *http.
|
||||
return
|
||||
}
|
||||
|
||||
//读取指定长度内容
|
||||
func (s *Conn) ReadLen(cLen int) ([]byte, error) {
|
||||
if cLen > poolSize {
|
||||
return nil, errors.New("长度错误" + strconv.Itoa(cLen))
|
||||
}
|
||||
var buf []byte
|
||||
if cLen <= poolSizeSmall {
|
||||
buf = BufPoolSmall.Get().([]byte)[:cLen]
|
||||
defer BufPoolSmall.Put(buf)
|
||||
} else {
|
||||
buf = BufPoolMax.Get().([]byte)[:cLen]
|
||||
defer BufPoolMax.Put(buf)
|
||||
}
|
||||
if n, err := io.ReadFull(s, buf); err != nil || n != cLen {
|
||||
return buf, errors.New("读取指定长度错误" + err.Error())
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
//read length or id (content length=4)
|
||||
func (s *Conn) GetLen() (int, error) {
|
||||
val, err := s.ReadLen(4)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return GetLenByBytes(val)
|
||||
}
|
||||
|
||||
//read flag
|
||||
func (s *Conn) ReadFlag() (string, error) {
|
||||
val, err := s.ReadLen(4)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(val), err
|
||||
}
|
||||
|
||||
//read connect status
|
||||
func (s *Conn) GetConnStatus() (id int, status bool, err error) {
|
||||
id, err = s.GetLen()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var b []byte
|
||||
if b, err = s.ReadLen(1); err != nil {
|
||||
return
|
||||
} else {
|
||||
status = GetBoolByStr(string(b[0]))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//设置连接为长连接
|
||||
func (s *Conn) SetAlive() {
|
||||
conn := s.Conn.(*net.TCPConn)
|
||||
conn.SetReadDeadline(time.Time{})
|
||||
conn.SetKeepAlive(true)
|
||||
conn.SetKeepAlivePeriod(time.Duration(2 * time.Second))
|
||||
}
|
||||
|
||||
//set read dead time
|
||||
func (s *Conn) SetReadDeadline(t time.Duration) {
|
||||
s.Conn.(*net.TCPConn).SetReadDeadline(time.Now().Add(time.Duration(t) * time.Second))
|
||||
}
|
||||
|
||||
//单独读(加密|压缩)
|
||||
func (s *Conn) ReadFrom(b []byte, compress int, crypt bool, rate *Rate) (int, error) {
|
||||
if COMPRESS_SNAPY_DECODE == compress {
|
||||
@@ -301,24 +262,112 @@ func (s *Conn) WriteTo(b []byte, compress int, crypt bool, rate *Rate) (n int, e
|
||||
return NewCryptConn(s.Conn, crypt, rate).Write(b)
|
||||
}
|
||||
|
||||
//写压缩方式,加密
|
||||
func (s *Conn) WriteConnInfo(en, de int, crypt, mux bool) {
|
||||
s.Write([]byte(strconv.Itoa(en) + strconv.Itoa(de) + GetStrByBool(crypt) + GetStrByBool(mux)))
|
||||
}
|
||||
|
||||
//获取压缩方式,是否加密
|
||||
func (s *Conn) GetConnInfoFromConn() (en, de int, crypt, mux bool) {
|
||||
buf, err := s.ReadLen(4)
|
||||
if err != nil {
|
||||
//send msg
|
||||
func (s *Conn) SendMsg(content []byte, link *Link) (n int, err error) {
|
||||
/*
|
||||
The msg info is formed as follows:
|
||||
+----+--------+
|
||||
|id | content |
|
||||
+----+--------+
|
||||
| 4 | ... |
|
||||
+----+--------+
|
||||
*/
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
raw := bytes.NewBuffer([]byte{})
|
||||
binary.Write(raw, binary.LittleEndian, int32(link.Id))
|
||||
if n, err = s.Write(raw.Bytes()); err != nil {
|
||||
return
|
||||
}
|
||||
en, _ = strconv.Atoi(string(buf[0]))
|
||||
de, _ = strconv.Atoi(string(buf[1]))
|
||||
crypt = GetBoolByStr(string(buf[2]))
|
||||
mux = GetBoolByStr(string(buf[3]))
|
||||
raw.Reset()
|
||||
binary.Write(raw, binary.LittleEndian, content)
|
||||
n, err = s.WriteTo(raw.Bytes(), link.En, link.Crypt, link.Rate)
|
||||
return
|
||||
}
|
||||
|
||||
//get msg content from conn
|
||||
func (s *Conn) GetMsgContent(link *Link) (content []byte, err error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
buf := BufPoolCopy.Get().([]byte)
|
||||
if n, err := s.ReadFrom(buf, link.De, link.Crypt, link.Rate); err == nil && n > 4 {
|
||||
content = buf[:n]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//send info for link
|
||||
func (s *Conn) SendLinkInfo(link *Link) (int, error) {
|
||||
/*
|
||||
The link info is formed as follows:
|
||||
+----------+------+----------+------+----------+-----+
|
||||
| id | len | type | hostlen | host | en | de |crypt |
|
||||
+----------+------+----------+------+---------+------+
|
||||
| 4 | 4 | 3 | 4 | host | 1 | 1 | 1 |
|
||||
+----------+------+----------+------+----+----+------+
|
||||
*/
|
||||
raw := bytes.NewBuffer([]byte{})
|
||||
binary.Write(raw, binary.LittleEndian, []byte(NEW_CONN))
|
||||
binary.Write(raw, binary.LittleEndian, int32(14+len(link.Host)))
|
||||
binary.Write(raw, binary.LittleEndian, int32(link.Id))
|
||||
binary.Write(raw, binary.LittleEndian, []byte(link.ConnType))
|
||||
binary.Write(raw, binary.LittleEndian, int32(len(link.Host)))
|
||||
binary.Write(raw, binary.LittleEndian, []byte(link.Host))
|
||||
binary.Write(raw, binary.LittleEndian, []byte(strconv.Itoa(link.En)))
|
||||
binary.Write(raw, binary.LittleEndian, []byte(strconv.Itoa(link.De)))
|
||||
binary.Write(raw, binary.LittleEndian, []byte(GetStrByBool(link.Crypt)))
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
return s.Write(raw.Bytes())
|
||||
}
|
||||
|
||||
func (s *Conn) GetLinkInfo() (link *Link, err error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
var hostLen, n int
|
||||
var buf []byte
|
||||
if n, err = s.GetLen(); err != nil {
|
||||
return
|
||||
}
|
||||
link = new(Link)
|
||||
if buf, err = s.ReadLen(n); err != nil {
|
||||
return
|
||||
}
|
||||
if link.Id, err = GetLenByBytes(buf[:4]); err != nil {
|
||||
return
|
||||
}
|
||||
link.ConnType = string(buf[4:7])
|
||||
if hostLen, err = GetLenByBytes(buf[7:11]); err != nil {
|
||||
return
|
||||
} else {
|
||||
link.Host = string(buf[11 : 11+hostLen])
|
||||
link.En = GetIntNoErrByStr(string(buf[11+hostLen]))
|
||||
link.De = GetIntNoErrByStr(string(buf[12+hostLen]))
|
||||
link.Crypt = GetBoolByStr(string(buf[13+hostLen]))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//write connect success
|
||||
func (s *Conn) WriteSuccess(id int) (int, error) {
|
||||
raw := bytes.NewBuffer([]byte{})
|
||||
binary.Write(raw, binary.LittleEndian, int32(id))
|
||||
binary.Write(raw, binary.LittleEndian, []byte("1"))
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
return s.Write(raw.Bytes())
|
||||
}
|
||||
|
||||
//write connect fail
|
||||
func (s *Conn) WriteFail(id int) (int, error) {
|
||||
raw := bytes.NewBuffer([]byte{})
|
||||
binary.Write(raw, binary.LittleEndian, int32(id))
|
||||
binary.Write(raw, binary.LittleEndian, []byte("0"))
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
return s.Write(raw.Bytes())
|
||||
}
|
||||
|
||||
//close
|
||||
func (s *Conn) Close() error {
|
||||
return s.Conn.Close()
|
||||
@@ -351,29 +400,18 @@ func (s *Conn) WriteClose() (int, error) {
|
||||
|
||||
//write main
|
||||
func (s *Conn) WriteMain() (int, error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
return s.Write([]byte(WORK_MAIN))
|
||||
}
|
||||
|
||||
//write chan
|
||||
func (s *Conn) WriteChan() (int, error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
return s.Write([]byte(WORK_CHAN))
|
||||
}
|
||||
|
||||
//write test
|
||||
func (s *Conn) WriteTest() (int, error) {
|
||||
return s.Write([]byte(TEST_FLAG))
|
||||
}
|
||||
|
||||
//write test
|
||||
func (s *Conn) WriteSuccess() (int, error) {
|
||||
return s.Write([]byte(CONN_SUCCESS))
|
||||
}
|
||||
|
||||
//write test
|
||||
func (s *Conn) WriteFail() (int, error) {
|
||||
return s.Write([]byte(CONN_ERROR))
|
||||
}
|
||||
|
||||
//获取长度+内容
|
||||
func GetLenBytes(buf []byte) (b []byte, err error) {
|
||||
raw := bytes.NewBuffer([]byte{})
|
||||
|
@@ -17,61 +17,8 @@ var (
|
||||
once sync.Once
|
||||
)
|
||||
|
||||
type Flow struct {
|
||||
ExportFlow int64 //出口流量
|
||||
InletFlow int64 //入口流量
|
||||
FlowLimit int64 //流量限制,出口+入口 /M
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
Cnf *Config
|
||||
Id int //id
|
||||
VerifyKey string //验证密钥
|
||||
Addr string //客户端ip地址
|
||||
Remark string //备注
|
||||
Status bool //是否开启
|
||||
IsConnect bool //是否连接
|
||||
RateLimit int //速度限制 /kb
|
||||
Flow *Flow //流量
|
||||
Rate *Rate //速度控制
|
||||
}
|
||||
|
||||
type Tunnel struct {
|
||||
Id int //Id
|
||||
TcpPort int //服务端与客户端通信端口
|
||||
Mode string //启动方式
|
||||
Target string //目标
|
||||
Status bool //是否开启
|
||||
Client *Client //所属客户端id
|
||||
Flow *Flow
|
||||
Config *Config
|
||||
UseClientCnf bool //是否继承客户端配置
|
||||
Remark string //备注
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
U string //socks5验证用户名
|
||||
P string //socks5验证密码
|
||||
Compress string //压缩方式
|
||||
Crypt bool //是否加密
|
||||
Mux bool //是否加密
|
||||
CompressEncode int //加密方式
|
||||
CompressDecode int //解密方式
|
||||
}
|
||||
|
||||
type Host struct {
|
||||
Host string //启动方式
|
||||
Target string //目标
|
||||
HeaderChange string //host修改
|
||||
HostChange string //host修改
|
||||
Flow *Flow
|
||||
Client *Client
|
||||
Remark string //备注
|
||||
}
|
||||
|
||||
func NewCsv() *Csv {
|
||||
c := new(Csv)
|
||||
return c
|
||||
return new(Csv)
|
||||
}
|
||||
|
||||
type Csv struct {
|
||||
@@ -108,7 +55,6 @@ func (s *Csv) StoreTasksToCsv() {
|
||||
task.Config.Compress,
|
||||
utils.GetStrByBool(task.Status),
|
||||
GetStrByBool(task.Config.Crypt),
|
||||
GetStrByBool(task.Config.Mux),
|
||||
strconv.Itoa(task.Config.CompressEncode),
|
||||
strconv.Itoa(task.Config.CompressDecode),
|
||||
strconv.Itoa(task.Id),
|
||||
@@ -160,17 +106,16 @@ func (s *Csv) LoadTaskFromCsv() {
|
||||
P: item[4],
|
||||
Compress: item[5],
|
||||
Crypt: GetBoolByStr(item[7]),
|
||||
Mux: GetBoolByStr(item[8]),
|
||||
CompressEncode: GetIntNoErrByStr(item[9]),
|
||||
CompressDecode: GetIntNoErrByStr(item[10]),
|
||||
CompressEncode: GetIntNoErrByStr(item[8]),
|
||||
CompressDecode: GetIntNoErrByStr(item[9]),
|
||||
},
|
||||
Status: utils.GetBoolByStr(item[6]),
|
||||
Id: GetIntNoErrByStr(item[11]),
|
||||
UseClientCnf: GetBoolByStr(item[13]),
|
||||
Remark: item[14],
|
||||
Id: GetIntNoErrByStr(item[10]),
|
||||
UseClientCnf: GetBoolByStr(item[12]),
|
||||
Remark: item[13],
|
||||
}
|
||||
post.Flow = new(Flow)
|
||||
if post.Client, err = s.GetClient(GetIntNoErrByStr(item[12])); err != nil {
|
||||
if post.Client, err = s.GetClient(GetIntNoErrByStr(item[11])); err != nil {
|
||||
continue
|
||||
}
|
||||
tasks = append(tasks, post)
|
||||
@@ -284,13 +229,12 @@ func (s *Csv) LoadClientFromCsv() {
|
||||
VerifyKey: item[1],
|
||||
Remark: item[2],
|
||||
Status: GetBoolByStr(item[3]),
|
||||
RateLimit: GetIntNoErrByStr(item[9]),
|
||||
RateLimit: GetIntNoErrByStr(item[8]),
|
||||
Cnf: &Config{
|
||||
U: item[4],
|
||||
P: item[5],
|
||||
Crypt: GetBoolByStr(item[6]),
|
||||
Mux: GetBoolByStr(item[7]),
|
||||
Compress: item[8],
|
||||
Compress: item[7],
|
||||
},
|
||||
}
|
||||
if post.Id > s.ClientIncreaseId {
|
||||
@@ -301,7 +245,7 @@ func (s *Csv) LoadClientFromCsv() {
|
||||
post.Rate.Start()
|
||||
}
|
||||
post.Flow = new(Flow)
|
||||
post.Flow.FlowLimit = int64(utils.GetIntNoerrByStr(item[10]))
|
||||
post.Flow.FlowLimit = int64(utils.GetIntNoerrByStr(item[9]))
|
||||
clients = append(clients, post)
|
||||
}
|
||||
s.Clients = clients
|
||||
@@ -407,10 +351,14 @@ func (s *Csv) GetClientId() int {
|
||||
func (s *Csv) UpdateClient(t *Client) error {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
for k, v := range s.Clients {
|
||||
for _, v := range s.Clients {
|
||||
if v.Id == t.Id {
|
||||
s.Clients = append(s.Clients[:k], s.Clients[k+1:]...)
|
||||
s.Clients = append(s.Clients, t)
|
||||
v.Cnf = t.Cnf
|
||||
v.VerifyKey = t.VerifyKey
|
||||
v.Remark = t.Remark
|
||||
v.RateLimit = t.RateLimit
|
||||
v.Flow = t.Flow
|
||||
v.Rate = t.Rate
|
||||
s.StoreClientsToCsv()
|
||||
return nil
|
||||
}
|
||||
@@ -458,7 +406,6 @@ func (s *Csv) StoreClientsToCsv() {
|
||||
client.Cnf.U,
|
||||
client.Cnf.P,
|
||||
utils.GetStrByBool(client.Cnf.Crypt),
|
||||
utils.GetStrByBool(client.Cnf.Mux),
|
||||
client.Cnf.Compress,
|
||||
strconv.Itoa(client.RateLimit),
|
||||
strconv.Itoa(int(client.Flow.FlowLimit)),
|
||||
@@ -480,15 +427,3 @@ func GetCsvDb() *Csv {
|
||||
return CsvDb
|
||||
}
|
||||
|
||||
//深拷贝Tunnel
|
||||
func DeepCopyConfig(c *Config) *Config {
|
||||
return &Config{
|
||||
U: c.U,
|
||||
P: c.P,
|
||||
Compress: c.Compress,
|
||||
Crypt: c.Crypt,
|
||||
Mux: c.Mux,
|
||||
CompressEncode: c.CompressEncode,
|
||||
CompressDecode: c.CompressDecode,
|
||||
}
|
||||
}
|
||||
|
116
utils/link.go
Normal file
116
utils/link.go
Normal file
@@ -0,0 +1,116 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"net"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Link struct {
|
||||
Id int //id
|
||||
ConnType string //连接类型
|
||||
Host string //目标
|
||||
En int //加密
|
||||
De int //解密
|
||||
Crypt bool //加密
|
||||
Conn *Conn
|
||||
Flow *Flow
|
||||
UdpListener *net.UDPConn
|
||||
Rate *Rate
|
||||
UdpRemoteAddr *net.UDPAddr
|
||||
}
|
||||
|
||||
func NewLink(id int, connType string, host string, en, de int, crypt bool, conn *Conn, flow *Flow, udpListener *net.UDPConn, rate *Rate, UdpRemoteAddr *net.UDPAddr) *Link {
|
||||
return &Link{
|
||||
Id: id,
|
||||
ConnType: connType,
|
||||
Host: host,
|
||||
En: en,
|
||||
De: de,
|
||||
Crypt: crypt,
|
||||
Conn: conn,
|
||||
Flow: flow,
|
||||
UdpListener: udpListener,
|
||||
Rate: rate,
|
||||
UdpRemoteAddr: UdpRemoteAddr,
|
||||
}
|
||||
}
|
||||
|
||||
type Flow struct {
|
||||
ExportFlow int64 //出口流量
|
||||
InletFlow int64 //入口流量
|
||||
FlowLimit int64 //流量限制,出口+入口 /M
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func (s *Flow) Add(in, out int) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
s.InletFlow += int64(in)
|
||||
s.ExportFlow += int64(out)
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
Cnf *Config
|
||||
Id int //id
|
||||
VerifyKey string //验证密钥
|
||||
Addr string //客户端ip地址
|
||||
Remark string //备注
|
||||
Status bool //是否开启
|
||||
IsConnect bool //是否连接
|
||||
RateLimit int //速度限制 /kb
|
||||
Flow *Flow //流量
|
||||
Rate *Rate //速度控制
|
||||
id int
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func (s *Client) GetId() int {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
s.id++
|
||||
return s.id
|
||||
}
|
||||
|
||||
type Tunnel struct {
|
||||
Id int //Id
|
||||
TcpPort int //服务端与客户端通信端口
|
||||
Mode string //启动方式
|
||||
Target string //目标
|
||||
Status bool //是否开启
|
||||
Client *Client //所属客户端id
|
||||
Flow *Flow
|
||||
Config *Config
|
||||
UseClientCnf bool //是否继承客户端配置
|
||||
Remark string //备注
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
U string //socks5验证用户名
|
||||
P string //socks5验证密码
|
||||
Compress string //压缩方式
|
||||
Crypt bool //是否加密
|
||||
CompressEncode int //加密方式
|
||||
CompressDecode int //解密方式
|
||||
}
|
||||
|
||||
type Host struct {
|
||||
Host string //启动方式
|
||||
Target string //目标
|
||||
HeaderChange string //host修改
|
||||
HostChange string //host修改
|
||||
Flow *Flow
|
||||
Client *Client
|
||||
Remark string //备注
|
||||
}
|
||||
|
||||
//深拷贝Config
|
||||
func DeepCopyConfig(c *Config) *Config {
|
||||
return &Config{
|
||||
U: c.U,
|
||||
P: c.P,
|
||||
Compress: c.Compress,
|
||||
Crypt: c.Crypt,
|
||||
CompressEncode: c.CompressEncode,
|
||||
CompressDecode: c.CompressDecode,
|
||||
}
|
||||
}
|
@@ -1,13 +1,15 @@
|
||||
package utils
|
||||
|
||||
import "sync"
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
const poolSize = 64 * 1024
|
||||
const poolSizeSmall = 100
|
||||
const poolSizeUdp = 1472
|
||||
const poolSizeCopy = 32 * 1024
|
||||
|
||||
var bufPool = sync.Pool{
|
||||
var BufPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return make([]byte, poolSize)
|
||||
},
|
||||
@@ -18,18 +20,24 @@ var BufPoolUdp = sync.Pool{
|
||||
return make([]byte, poolSizeUdp)
|
||||
},
|
||||
}
|
||||
var bufPoolMax = sync.Pool{
|
||||
var BufPoolMax = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return make([]byte, poolSize)
|
||||
},
|
||||
}
|
||||
var bufPoolSmall = sync.Pool{
|
||||
var BufPoolSmall = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return make([]byte, poolSizeSmall)
|
||||
},
|
||||
}
|
||||
var bufPoolCopy = sync.Pool{
|
||||
var BufPoolCopy = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return make([]byte, poolSizeCopy)
|
||||
},
|
||||
}
|
||||
|
||||
func PutBufPoolCopy(buf []byte) {
|
||||
if cap(buf) == poolSizeCopy {
|
||||
BufPoolCopy.Put(buf[:poolSizeCopy])
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,6 @@ package utils
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
@@ -11,8 +10,6 @@ import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -26,9 +23,8 @@ const (
|
||||
RES_SIGN = "sign"
|
||||
RES_MSG = "msg0"
|
||||
RES_CLOSE = "clse"
|
||||
NEW_CONN = "conn" //新连接标志
|
||||
CONN_SUCCESS = "sucs"
|
||||
CONN_ERROR = "fail"
|
||||
TEST_FLAG = "tst"
|
||||
CONN_TCP = "tcp"
|
||||
CONN_UDP = "udp"
|
||||
UnauthorizedBytes = `HTTP/1.1 401 Unauthorized
|
||||
@@ -42,32 +38,6 @@ WWW-Authenticate: Basic realm="easyProxy"
|
||||
`
|
||||
)
|
||||
|
||||
//copy
|
||||
func Relay(in, out net.Conn, compressType int, crypt, mux bool, rate *Rate) (n int64, err error) {
|
||||
switch compressType {
|
||||
case COMPRESS_SNAPY_ENCODE:
|
||||
n, err = copyBuffer(NewSnappyConn(in, crypt, rate), out)
|
||||
out.Close()
|
||||
NewSnappyConn(in, crypt, rate).Write([]byte(IO_EOF))
|
||||
case COMPRESS_SNAPY_DECODE:
|
||||
n, err = copyBuffer(in, NewSnappyConn(out, crypt, rate))
|
||||
in.Close()
|
||||
if !mux {
|
||||
out.Close()
|
||||
}
|
||||
case COMPRESS_NONE_ENCODE:
|
||||
n, err = copyBuffer(NewCryptConn(in, crypt, rate), out)
|
||||
out.Close()
|
||||
NewCryptConn(in, crypt, rate).Write([]byte(IO_EOF))
|
||||
case COMPRESS_NONE_DECODE:
|
||||
n, err = copyBuffer(in, NewCryptConn(out, crypt, rate))
|
||||
in.Close()
|
||||
if !mux {
|
||||
out.Close()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//判断压缩方式
|
||||
func GetCompressType(compress string) (int, int) {
|
||||
@@ -152,71 +122,11 @@ func GetIntNoErrByStr(str string) int {
|
||||
return i
|
||||
}
|
||||
|
||||
// io.copy的优化版,读取buffer长度原为32*1024,与snappy不同,导致读取出的内容存在差异,不利于解密
|
||||
//内存优化 用到pool,快速回收
|
||||
func copyBuffer(dst io.Writer, src io.Reader) (written int64, err error) {
|
||||
for {
|
||||
//放在里面是为了加快回收和重利用
|
||||
buf := bufPoolCopy.Get().([]byte)
|
||||
nr, er := src.Read(buf)
|
||||
if nr > 0 {
|
||||
nw, ew := dst.Write(buf[0:nr])
|
||||
bufPoolCopy.Put(buf)
|
||||
if nw > 0 {
|
||||
written += int64(nw)
|
||||
}
|
||||
if ew != nil {
|
||||
err = ew
|
||||
break
|
||||
}
|
||||
if nr != nw {
|
||||
err = io.ErrShortWrite
|
||||
break
|
||||
}
|
||||
} else {
|
||||
bufPoolCopy.Put(buf)
|
||||
}
|
||||
if er != nil {
|
||||
if er != io.EOF {
|
||||
err = er
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return written, err
|
||||
}
|
||||
|
||||
//连接重置 清空缓存区
|
||||
func FlushConn(c net.Conn) {
|
||||
c.SetReadDeadline(time.Now().Add(time.Second * 3))
|
||||
buf := bufPool.Get().([]byte)
|
||||
defer bufPool.Put(buf)
|
||||
for {
|
||||
if _, err := c.Read(buf); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
c.SetReadDeadline(time.Time{})
|
||||
}
|
||||
|
||||
//简单的一个校验值
|
||||
func Getverifyval(vkey string) string {
|
||||
return Md5(vkey)
|
||||
}
|
||||
|
||||
//wait replay group
|
||||
//conn1 网桥 conn2
|
||||
func ReplayWaitGroup(conn1 net.Conn, conn2 net.Conn, compressEncode, compressDecode int, crypt, mux bool, rate *Rate) (out int64, in int64) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
in, _ = Relay(conn1, conn2, compressEncode, crypt, mux, rate)
|
||||
wg.Done()
|
||||
}()
|
||||
out, _ = Relay(conn2, conn1, compressDecode, crypt, mux, rate)
|
||||
wg.Wait()
|
||||
return
|
||||
}
|
||||
|
||||
func ChangeHostAndHeader(r *http.Request, host string, header string, addr string) {
|
||||
if host != "" {
|
||||
@@ -236,8 +146,8 @@ func ChangeHostAndHeader(r *http.Request, host string, header string, addr strin
|
||||
r.Header.Set("X-Real-IP", addr)
|
||||
}
|
||||
|
||||
func ReadAllFromFile(filePth string) ([]byte, error) {
|
||||
f, err := os.Open(filePth)
|
||||
func ReadAllFromFile(filePath string) ([]byte, error) {
|
||||
f, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Reference in New Issue
Block a user