mirror of https://github.com/ehang-io/nps
				
				
				
			P2p first version
							parent
							
								
									204c53ddd3
								
							
						
					
					
						commit
						534d428c6d
					
				| 
						 | 
				
			
			@ -11,6 +11,7 @@ import (
 | 
			
		|||
	"github.com/cnlh/nps/lib/pool"
 | 
			
		||||
	"github.com/cnlh/nps/lib/version"
 | 
			
		||||
	"github.com/cnlh/nps/server/tool"
 | 
			
		||||
	"github.com/cnlh/nps/vender/github.com/astaxie/beego"
 | 
			
		||||
	"github.com/cnlh/nps/vender/github.com/astaxie/beego/logs"
 | 
			
		||||
	"github.com/cnlh/nps/vender/github.com/xtaci/kcp"
 | 
			
		||||
	"net"
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +72,6 @@ func NewTunnel(tunnelPort int, tunnelType string, ipVerify bool, runList map[int
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (s *Bridge) StartTunnel() error {
 | 
			
		||||
	go s.linkCleanSession()
 | 
			
		||||
	var err error
 | 
			
		||||
	if s.tunnelType == "kcp" {
 | 
			
		||||
		s.kcpListener, err = kcp.ListenWithOptions(":"+strconv.Itoa(s.TunnelPort), nil, 150, 3)
 | 
			
		||||
| 
						 | 
				
			
			@ -209,10 +209,35 @@ func (s *Bridge) typeDeal(typeVal string, c *conn.Conn, id int) {
 | 
			
		|||
		go s.GetConfig(c)
 | 
			
		||||
	case common.WORK_REGISTER:
 | 
			
		||||
		go s.register(c)
 | 
			
		||||
	case common.WORD_SECRET:
 | 
			
		||||
	case common.WORK_SECRET:
 | 
			
		||||
		if b, err := c.ReadLen(32); err == nil {
 | 
			
		||||
			s.SecretChan <- conn.NewSecret(string(b), c)
 | 
			
		||||
		}
 | 
			
		||||
	case common.WORK_P2P:
 | 
			
		||||
		//读取md5密钥
 | 
			
		||||
		if b, err := c.ReadLen(32); err != nil {
 | 
			
		||||
			return
 | 
			
		||||
		} else if t := file.GetCsvDb().GetTaskByMd5Password(string(b)); t == nil {
 | 
			
		||||
			return
 | 
			
		||||
		} else {
 | 
			
		||||
			s.clientLock.Lock()
 | 
			
		||||
			if v, ok := s.Client[t.Client.Id]; !ok {
 | 
			
		||||
				logs.Error("未获取到对应客户端")
 | 
			
		||||
				s.clientLock.Unlock()
 | 
			
		||||
				return
 | 
			
		||||
			} else {
 | 
			
		||||
				logs.Warn("获取到对应客户端")
 | 
			
		||||
				s.clientLock.Unlock()
 | 
			
		||||
				//向密钥对应的客户端发送与服务端udp建立连接信息,地址,密钥
 | 
			
		||||
				logs.Warn(v.signal.Write([]byte(common.NEW_UDP_CONN)))
 | 
			
		||||
				svrAddr := beego.AppConfig.String("serverIp") + ":" + beego.AppConfig.String("p2pPort")
 | 
			
		||||
				logs.Warn(svrAddr)
 | 
			
		||||
				logs.Warn(v.signal.WriteLenContent([]byte(svrAddr)))
 | 
			
		||||
				logs.Warn(string(b), v.signal.WriteLenContent(b))
 | 
			
		||||
				//向该请求者发送建立连接请求,服务器地址
 | 
			
		||||
				c.WriteLenContent([]byte(svrAddr))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	case common.WORK_SEND_STATUS:
 | 
			
		||||
		s.clientLock.Lock()
 | 
			
		||||
		if v, ok := s.Client[id]; ok {
 | 
			
		||||
| 
						 | 
				
			
			@ -511,6 +536,7 @@ func (s *Bridge) clientCopy(clientId int) {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//TODO 清除有一个未知bug待处理
 | 
			
		||||
func (s *Bridge) linkCleanSession() {
 | 
			
		||||
	ticker := time.NewTicker(time.Minute * 5)
 | 
			
		||||
	for {
 | 
			
		||||
| 
						 | 
				
			
			@ -526,7 +552,7 @@ func (s *Bridge) linkCleanSession() {
 | 
			
		|||
				}
 | 
			
		||||
				v.Unlock()
 | 
			
		||||
			}
 | 
			
		||||
			s.clientLock.RUnlock()
 | 
			
		||||
			s.clientLock.Unlock()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										133
									
								
								client/client.go
								
								
								
								
							
							
						
						
									
										133
									
								
								client/client.go
								
								
								
								
							| 
						 | 
				
			
			@ -5,6 +5,7 @@ import (
 | 
			
		|||
	"github.com/cnlh/nps/lib/conn"
 | 
			
		||||
	"github.com/cnlh/nps/lib/pool"
 | 
			
		||||
	"github.com/cnlh/nps/vender/github.com/astaxie/beego/logs"
 | 
			
		||||
	"github.com/cnlh/nps/vender/github.com/xtaci/kcp"
 | 
			
		||||
	"net"
 | 
			
		||||
	"os"
 | 
			
		||||
	"sync"
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +39,6 @@ func NewRPClient(svraddr string, vKey string, bridgeConnType string, proxyUrl st
 | 
			
		|||
 | 
			
		||||
//start
 | 
			
		||||
func (s *TRPClient) Start() {
 | 
			
		||||
	go s.linkCleanSession()
 | 
			
		||||
retry:
 | 
			
		||||
	c, err := NewConn(s.bridgeConnType, s.vKey, s.svrAddr, common.WORK_MAIN, s.proxyUrl)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -82,8 +82,8 @@ func (s *TRPClient) processor(c *conn.Conn) {
 | 
			
		|||
				s.linkMap[link.Id] = link
 | 
			
		||||
				s.Unlock()
 | 
			
		||||
				link.MsgConn = s.msgTunnel
 | 
			
		||||
				go s.linkProcess(link, c)
 | 
			
		||||
				link.Run(false)
 | 
			
		||||
				go linkProcess(link, c, s.tunnel)
 | 
			
		||||
				link.RunWrite()
 | 
			
		||||
			}
 | 
			
		||||
		case common.RES_CLOSE:
 | 
			
		||||
			logs.Error("The authentication key is connected by another client or the server closes the client.")
 | 
			
		||||
| 
						 | 
				
			
			@ -91,6 +91,14 @@ func (s *TRPClient) processor(c *conn.Conn) {
 | 
			
		|||
		case common.RES_MSG:
 | 
			
		||||
			logs.Error("Server-side return error")
 | 
			
		||||
			break
 | 
			
		||||
		case common.NEW_UDP_CONN:
 | 
			
		||||
			//读取服务端地址、密钥 继续做处理
 | 
			
		||||
			if lAddr, err := c.GetLenContent(); err != nil {
 | 
			
		||||
				return
 | 
			
		||||
			} else if pwd, err := c.GetLenContent(); err == nil {
 | 
			
		||||
				logs.Warn(string(lAddr), string(pwd))
 | 
			
		||||
				go s.newUdpConn(string(lAddr), string(pwd))
 | 
			
		||||
			}
 | 
			
		||||
		default:
 | 
			
		||||
			logs.Warn("The error could not be resolved")
 | 
			
		||||
			break
 | 
			
		||||
| 
						 | 
				
			
			@ -100,37 +108,112 @@ func (s *TRPClient) processor(c *conn.Conn) {
 | 
			
		|||
	s.Close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *TRPClient) linkProcess(link *conn.Link, c *conn.Conn) {
 | 
			
		||||
func (s *TRPClient) newUdpConn(rAddr string, md5Password string) {
 | 
			
		||||
	tmpConn, err := net.Dial("udp", "114.114.114.114:53")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logs.Warn(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	tmpConn.Close()
 | 
			
		||||
	//与服务端建立udp连接
 | 
			
		||||
	localAddr, _ := net.ResolveUDPAddr("udp", tmpConn.LocalAddr().String())
 | 
			
		||||
	localConn, err := net.ListenUDP("udp", localAddr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logs.Warn(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	localKcpConn, err := kcp.NewConn(rAddr, nil, 150, 3, localConn)
 | 
			
		||||
	logs.Warn(localConn.RemoteAddr(), rAddr)
 | 
			
		||||
	conn.SetUdpSession(localKcpConn)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logs.Warn(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	localToolConn := conn.NewConn(localKcpConn)
 | 
			
		||||
	//写入密钥、provider身份
 | 
			
		||||
	if _, err := localToolConn.Write([]byte(md5Password)); err != nil {
 | 
			
		||||
		logs.Warn(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if _, err := localToolConn.Write([]byte(common.WORK_P2P_PROVIDER)); err != nil {
 | 
			
		||||
		logs.Warn(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	//接收服务端传的visitor地址
 | 
			
		||||
	if b, err := localToolConn.GetLenContent(); err != nil {
 | 
			
		||||
		logs.Warn(err)
 | 
			
		||||
		return
 | 
			
		||||
	} else {
 | 
			
		||||
		logs.Warn("收到服务端回传地址", string(b))
 | 
			
		||||
		//向visitor地址发送测试消息
 | 
			
		||||
		visitorAddr, err := net.ResolveUDPAddr("udp", string(b))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logs.Warn(err)
 | 
			
		||||
		}
 | 
			
		||||
		logs.Warn(visitorAddr.String())
 | 
			
		||||
		if n, err := localConn.WriteTo([]byte("test"), visitorAddr); err != nil {
 | 
			
		||||
			logs.Warn(err)
 | 
			
		||||
		} else {
 | 
			
		||||
			logs.Warn("write", n)
 | 
			
		||||
		}
 | 
			
		||||
		//给服务端发反馈
 | 
			
		||||
		if _, err := localToolConn.Write([]byte(common.VERIFY_SUCCESS)); err != nil {
 | 
			
		||||
			logs.Warn(err)
 | 
			
		||||
		}
 | 
			
		||||
		//关闭与服务端的连接
 | 
			
		||||
		localConn.Close()
 | 
			
		||||
		//关闭与服务端udp conn,建立新的监听
 | 
			
		||||
		localConn, err = net.ListenUDP("udp", localAddr)
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logs.Warn(err)
 | 
			
		||||
		}
 | 
			
		||||
		l, err := kcp.ServeConn(nil, 150, 3, localConn)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logs.Warn(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		for {
 | 
			
		||||
			//接收新的监听,得到conn,
 | 
			
		||||
			udpTunnel, err := l.AcceptKCP()
 | 
			
		||||
			logs.Warn(udpTunnel.RemoteAddr(), udpTunnel.LocalAddr())
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				logs.Warn(err)
 | 
			
		||||
				l.Close()
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			conn.SetUdpSession(udpTunnel)
 | 
			
		||||
			if udpTunnel.RemoteAddr().String() == string(b) {
 | 
			
		||||
				//读取link,设置msgCh 设置msgConn消息回传响应机制
 | 
			
		||||
				c, e := net.Dial("tcp", "123.206.77.88:22")
 | 
			
		||||
				if e != nil {
 | 
			
		||||
					logs.Warn(e)
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				go common.CopyBuffer(c, udpTunnel)
 | 
			
		||||
				common.CopyBuffer(udpTunnel, c)
 | 
			
		||||
				//读取flag ping/new/msg/msgConn//分别对于不同的做法
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func linkProcess(link *conn.Link, statusConn, msgConn *conn.Conn) {
 | 
			
		||||
	link.Host = common.FormatAddress(link.Host)
 | 
			
		||||
	//与目标建立连接
 | 
			
		||||
	server, err := net.DialTimeout(link.ConnType, link.Host, time.Second*3)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		c.WriteFail(link.Id)
 | 
			
		||||
		statusConn.WriteFail(link.Id)
 | 
			
		||||
		logs.Warn("connect to ", link.Host, "error:", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	c.WriteSuccess(link.Id)
 | 
			
		||||
	statusConn.WriteSuccess(link.Id)
 | 
			
		||||
	link.Conn = conn.NewConn(server)
 | 
			
		||||
	buf := pool.BufPoolCopy.Get().([]byte)
 | 
			
		||||
	for {
 | 
			
		||||
		if n, err := server.Read(buf); err != nil {
 | 
			
		||||
			s.tunnel.SendMsg([]byte(common.IO_EOF), link)
 | 
			
		||||
			break
 | 
			
		||||
		} else {
 | 
			
		||||
			if _, err := s.tunnel.SendMsg(buf[:n], link); err != nil {
 | 
			
		||||
				c.Close()
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			if link.ConnType == common.CONN_UDP {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		<-link.StatusCh
 | 
			
		||||
	}
 | 
			
		||||
	pool.PutBufPoolCopy(buf)
 | 
			
		||||
	s.Lock()
 | 
			
		||||
	s.Unlock()
 | 
			
		||||
	link.RunRead(msgConn)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *TRPClient) getMsgStatus() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,8 +3,10 @@ package client
 | 
			
		|||
import (
 | 
			
		||||
	"github.com/cnlh/nps/lib/common"
 | 
			
		||||
	"github.com/cnlh/nps/lib/config"
 | 
			
		||||
	"github.com/cnlh/nps/lib/conn"
 | 
			
		||||
	"github.com/cnlh/nps/lib/crypt"
 | 
			
		||||
	"github.com/cnlh/nps/vender/github.com/astaxie/beego/logs"
 | 
			
		||||
	"github.com/cnlh/nps/vender/github.com/xtaci/kcp"
 | 
			
		||||
	"net"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -39,16 +41,81 @@ func StartLocalServer(l *config.LocalServer, config *config.CommonConfig) error
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func process(conn net.Conn, config *config.CommonConfig, l *config.LocalServer) {
 | 
			
		||||
	c, err := NewConn(config.Tp, config.VKey, config.Server, common.WORD_SECRET, config.ProxyUrl)
 | 
			
		||||
func process(localTcpConn net.Conn, config *config.CommonConfig, l *config.LocalServer) {
 | 
			
		||||
	var workType string
 | 
			
		||||
	if l.Type == "secret" {
 | 
			
		||||
		workType = common.WORK_SECRET
 | 
			
		||||
	} else {
 | 
			
		||||
		workType = common.WORK_P2P
 | 
			
		||||
	}
 | 
			
		||||
	remoteConn, err := NewConn(config.Tp, config.VKey, config.Server, workType, config.ProxyUrl)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logs.Error("Local connection server failed ", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	if _, err := c.Write([]byte(crypt.Md5(l.Password))); err != nil {
 | 
			
		||||
	if _, err := remoteConn.Write([]byte(crypt.Md5(l.Password))); err != nil {
 | 
			
		||||
		logs.Error("Local connection server failed ", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	go common.CopyBuffer(c, conn)
 | 
			
		||||
	common.CopyBuffer(conn, c)
 | 
			
		||||
	c.Close()
 | 
			
		||||
	conn.Close()
 | 
			
		||||
	if l.Type == "secret" {
 | 
			
		||||
		go common.CopyBuffer(remoteConn, localTcpConn)
 | 
			
		||||
		common.CopyBuffer(localTcpConn, remoteConn)
 | 
			
		||||
		remoteConn.Close()
 | 
			
		||||
		localTcpConn.Close()
 | 
			
		||||
	} else {
 | 
			
		||||
		//读取服务端地址、密钥 继续做处理
 | 
			
		||||
		logs.Warn(111)
 | 
			
		||||
		if rAddr, err := remoteConn.GetLenContent(); err != nil {
 | 
			
		||||
			return
 | 
			
		||||
		} else {
 | 
			
		||||
			logs.Warn(222)
 | 
			
		||||
			//与服务端udp建立连接
 | 
			
		||||
			tmpConn, err := net.Dial("udp", "114.114.114.114:53")
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				logs.Warn(err)
 | 
			
		||||
			}
 | 
			
		||||
			tmpConn.Close()
 | 
			
		||||
			//与服务端建立udp连接
 | 
			
		||||
			localAddr, _ := net.ResolveUDPAddr("udp", tmpConn.LocalAddr().String())
 | 
			
		||||
			localConn, err := net.ListenUDP("udp", localAddr)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			logs.Warn(333)
 | 
			
		||||
			localKcpConn, err := kcp.NewConn(string(rAddr), nil, 150, 3, localConn)
 | 
			
		||||
			conn.SetUdpSession(localKcpConn)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				logs.Warn(err)
 | 
			
		||||
			}
 | 
			
		||||
			localToolConn := conn.NewConn(localKcpConn)
 | 
			
		||||
			//写入密钥、provider身份
 | 
			
		||||
			if _, err := localToolConn.Write([]byte(crypt.Md5(l.Password))); err != nil {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			if _, err := localToolConn.Write([]byte(common.WORK_P2P_VISITOR)); err != nil {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			logs.Warn(444)
 | 
			
		||||
			//接收服务端传的visitor地址
 | 
			
		||||
			if b, err := localToolConn.GetLenContent(); err != nil {
 | 
			
		||||
				logs.Warn(err)
 | 
			
		||||
				return
 | 
			
		||||
			} else {
 | 
			
		||||
				logs.Warn("收到服务回传地址", string(b))
 | 
			
		||||
				//关闭与服务端连接
 | 
			
		||||
				localConn.Close()
 | 
			
		||||
				//建立新的连接
 | 
			
		||||
				localConn, err = net.ListenUDP("udp", localAddr)
 | 
			
		||||
				udpTunnel, err := kcp.NewConn(string(b), nil, 150, 3, localConn)
 | 
			
		||||
				if err != nil || udpTunnel == nil {
 | 
			
		||||
					logs.Warn(err)
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				conn.SetUdpSession(udpTunnel)
 | 
			
		||||
				logs.Warn(udpTunnel.RemoteAddr(), string(b), udpTunnel.LocalAddr())
 | 
			
		||||
 | 
			
		||||
				go common.CopyBuffer(udpTunnel, localTcpConn)
 | 
			
		||||
				common.CopyBuffer(localTcpConn, udpTunnel)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
[common]
 | 
			
		||||
server=127.0.0.1:8284
 | 
			
		||||
server=123.206.77.88:8284
 | 
			
		||||
tp=tcp
 | 
			
		||||
vkey=123
 | 
			
		||||
auto_reconnection=true
 | 
			
		||||
| 
						 | 
				
			
			@ -16,10 +16,6 @@ host_change=www.proxy.com
 | 
			
		|||
target=127.0.0.1:8080
 | 
			
		||||
location=/cdn
 | 
			
		||||
 | 
			
		||||
[ssh_1118]
 | 
			
		||||
mode=secretServer
 | 
			
		||||
password=1111
 | 
			
		||||
target=123.206.77.88:22
 | 
			
		||||
 | 
			
		||||
[tcp]
 | 
			
		||||
mode=tcpServer
 | 
			
		||||
| 
						 | 
				
			
			@ -37,4 +33,8 @@ port=9004
 | 
			
		|||
[udp]
 | 
			
		||||
mode=udpServer
 | 
			
		||||
port=9003
 | 
			
		||||
target=114.114.114.53
 | 
			
		||||
target=114.114.114.53
 | 
			
		||||
 | 
			
		||||
[p2p_ssh]
 | 
			
		||||
port=2000
 | 
			
		||||
password=p2pssh
 | 
			
		||||
| 
						 | 
				
			
			@ -13,12 +13,16 @@ const (
 | 
			
		|||
	WORK_SEND_STATUS  = "sdst"
 | 
			
		||||
	WORK_CONFIG       = "conf"
 | 
			
		||||
	WORK_REGISTER     = "rgst"
 | 
			
		||||
	WORD_SECRET       = "sert"
 | 
			
		||||
	WORK_SECRET       = "sert"
 | 
			
		||||
	WORK_P2P          = "p2pm"
 | 
			
		||||
	WORK_P2P_VISITOR  = "p2pv"
 | 
			
		||||
	WORK_P2P_PROVIDER = "p2pp"
 | 
			
		||||
	WORK_STATUS       = "stus"
 | 
			
		||||
	RES_SIGN          = "sign"
 | 
			
		||||
	RES_MSG           = "msg0"
 | 
			
		||||
	RES_CLOSE         = "clse"
 | 
			
		||||
	NEW_CONN          = "conn" //新连接标志
 | 
			
		||||
	NEW_UDP_CONN      = "udpc" //p2p udp conn
 | 
			
		||||
	NEW_TASK          = "task" //新连接标志
 | 
			
		||||
	NEW_CONF          = "conf" //新连接标志
 | 
			
		||||
	NEW_HOST          = "host" //新连接标志
 | 
			
		||||
| 
						 | 
				
			
			@ -33,4 +37,5 @@ WWW-Authenticate: Basic realm="easyProxy"
 | 
			
		|||
	ConnectionFailBytes = `HTTP/1.1 404 Not Found
 | 
			
		||||
 | 
			
		||||
`
 | 
			
		||||
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -251,7 +251,29 @@ func GetIpByAddr(addr string) string {
 | 
			
		|||
 | 
			
		||||
func CopyBuffer(dst io.Writer, src io.Reader) (written int64, err error) {
 | 
			
		||||
	buf := pool.BufPoolCopy.Get().([]byte)
 | 
			
		||||
	io.CopyBuffer(dst, src, buf)
 | 
			
		||||
	pool.PutBufPoolCopy(buf)
 | 
			
		||||
	for {
 | 
			
		||||
		nr, er := src.Read(buf)
 | 
			
		||||
		if nr > 0 {
 | 
			
		||||
			nw, ew := dst.Write(buf[0:nr])
 | 
			
		||||
			if nw > 0 {
 | 
			
		||||
				written += int64(nw)
 | 
			
		||||
			}
 | 
			
		||||
			if ew != nil {
 | 
			
		||||
				err = ew
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			if nr != nw {
 | 
			
		||||
				err = io.ErrShortWrite
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if er != nil {
 | 
			
		||||
			if er != io.EOF {
 | 
			
		||||
				err = er
 | 
			
		||||
			}
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	defer pool.PutBufPoolCopy(buf)
 | 
			
		||||
	return written, err
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@ type CommonConfig struct {
 | 
			
		|||
	Client           *file.Client
 | 
			
		||||
}
 | 
			
		||||
type LocalServer struct {
 | 
			
		||||
	Type     string
 | 
			
		||||
	Port     int
 | 
			
		||||
	Password string
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +54,15 @@ func NewConfig(path string) (c *Config, err error) {
 | 
			
		|||
			nowContent = c.content[nowIndex:nextIndex]
 | 
			
		||||
 | 
			
		||||
			if strings.Index(getTitleContent(c.title[i]), "secret") == 0 {
 | 
			
		||||
				c.LocalServer = append(c.LocalServer, delLocalService(nowContent))
 | 
			
		||||
				local := delLocalService(nowContent)
 | 
			
		||||
				local.Type = "secret"
 | 
			
		||||
				c.LocalServer = append(c.LocalServer, local)
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			if strings.Index(getTitleContent(c.title[i]), "p2p") == 0 {
 | 
			
		||||
				local := delLocalService(nowContent)
 | 
			
		||||
				local.Type = "p2p"
 | 
			
		||||
				c.LocalServer = append(c.LocalServer, local)
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			switch c.title[i] {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,6 +69,15 @@ func (s *Conn) GetHost() (method, address string, rb []byte, err error, r *http.
 | 
			
		|||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Conn) GetLenContent() (b []byte, err error) {
 | 
			
		||||
	var l int
 | 
			
		||||
	if l, err = s.GetLen(); err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	b, err = s.ReadLen(l)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//读取指定长度内容
 | 
			
		||||
func (s *Conn) ReadLen(cLen int) ([]byte, error) {
 | 
			
		||||
	if cLen > pool.PoolSize {
 | 
			
		||||
| 
						 | 
				
			
			@ -77,10 +86,11 @@ func (s *Conn) ReadLen(cLen int) ([]byte, error) {
 | 
			
		|||
	var buf []byte
 | 
			
		||||
	if cLen < pool.PoolSizeSmall {
 | 
			
		||||
		buf = pool.BufPoolSmall.Get().([]byte)[:cLen]
 | 
			
		||||
		defer pool.PutBufPoolSmall(buf)
 | 
			
		||||
		//TODO 回收
 | 
			
		||||
		//defer pool.PutBufPoolSmall(buf)
 | 
			
		||||
	} else {
 | 
			
		||||
		buf = pool.BufPoolMax.Get().([]byte)[:cLen]
 | 
			
		||||
		defer pool.PutBufPoolMax(buf)
 | 
			
		||||
		//defer pool.PutBufPoolMax(buf)
 | 
			
		||||
	}
 | 
			
		||||
	if n, err := io.ReadFull(s, buf); err != nil || n != cLen {
 | 
			
		||||
		return buf, errors.New("Error reading specified length " + err.Error())
 | 
			
		||||
| 
						 | 
				
			
			@ -95,6 +105,14 @@ func (s *Conn) GetLen() (int, error) {
 | 
			
		|||
	return int(l), err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Conn) WriteLenContent(buf []byte) (err error) {
 | 
			
		||||
	var b []byte
 | 
			
		||||
	if b, err = GetLenBytes(buf); err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	return binary.Write(s.Conn, binary.LittleEndian, b)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//read flag
 | 
			
		||||
func (s *Conn) ReadFlag() (string, error) {
 | 
			
		||||
	val, err := s.ReadLen(4)
 | 
			
		||||
| 
						 | 
				
			
			@ -477,7 +495,6 @@ func (s *Conn) WriteChan() (int, error) {
 | 
			
		|||
	defer s.Unlock()
 | 
			
		||||
	return s.Write([]byte(common.WORK_CHAN))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//获取长度+内容
 | 
			
		||||
func GetLenBytes(buf []byte) (b []byte, err error) {
 | 
			
		||||
	raw := bytes.NewBuffer([]byte{})
 | 
			
		||||
| 
						 | 
				
			
			@ -491,6 +508,7 @@ func GetLenBytes(buf []byte) (b []byte, err error) {
 | 
			
		|||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//解析出长度
 | 
			
		||||
func GetLenByBytes(buf []byte) (int, error) {
 | 
			
		||||
	nlen := binary.LittleEndian.Uint32(buf)
 | 
			
		||||
| 
						 | 
				
			
			@ -508,4 +526,5 @@ func SetUdpSession(sess *kcp.UDPSession) {
 | 
			
		|||
	sess.SetNoDelay(1, 10, 2, 1)
 | 
			
		||||
	sess.SetMtu(1600)
 | 
			
		||||
	sess.SetACKNoDelay(true)
 | 
			
		||||
	sess.SetWriteDelay(false)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,7 +56,7 @@ func NewLink(id int, connType string, host string, en, de int, crypt bool, c *Co
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Link) Run(flow bool) {
 | 
			
		||||
func (s *Link) RunWrite() {
 | 
			
		||||
	go func() {
 | 
			
		||||
		for {
 | 
			
		||||
			select {
 | 
			
		||||
| 
						 | 
				
			
			@ -76,7 +76,7 @@ func (s *Link) Run(flow bool) {
 | 
			
		|||
					} else {
 | 
			
		||||
						s.Conn.Write(content)
 | 
			
		||||
					}
 | 
			
		||||
					if flow {
 | 
			
		||||
					if s.Flow != nil {
 | 
			
		||||
						s.Flow.Add(0, len(content))
 | 
			
		||||
					}
 | 
			
		||||
					if s.ConnType == common.CONN_UDP {
 | 
			
		||||
| 
						 | 
				
			
			@ -89,3 +89,25 @@ func (s *Link) Run(flow bool) {
 | 
			
		|||
		}
 | 
			
		||||
	}()
 | 
			
		||||
}
 | 
			
		||||
func (s *Link) RunRead(msgConn *Conn) {
 | 
			
		||||
	buf := pool.BufPoolCopy.Get().([]byte)
 | 
			
		||||
	for {
 | 
			
		||||
		if n, err := s.Conn.Read(buf); err != nil {
 | 
			
		||||
			msgConn.SendMsg([]byte(common.IO_EOF), s)
 | 
			
		||||
			break
 | 
			
		||||
		} else {
 | 
			
		||||
			if _, err := msgConn.SendMsg(buf[:n], s); err != nil {
 | 
			
		||||
				msgConn.Close()
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			if s.ConnType == common.CONN_UDP {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			if s.Flow != nil {
 | 
			
		||||
				s.Flow.Add(n, 0)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		<-s.StatusCh
 | 
			
		||||
	}
 | 
			
		||||
	pool.PutBufPoolCopy(buf)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -181,7 +181,7 @@ func (s *Csv) DelTask(id int) error {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
//md5 password
 | 
			
		||||
func (s *Csv) GetSecretTask(p string) *Tunnel {
 | 
			
		||||
func (s *Csv) GetTaskByMd5Password(p string) *Tunnel {
 | 
			
		||||
	for _, v := range s.Tasks {
 | 
			
		||||
		if crypt.Md5(v.Password) == p {
 | 
			
		||||
			return v
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,7 +53,6 @@ func NewClient(vKey string, noStore bool, noDisplay bool) *Client {
 | 
			
		|||
		Flow:      new(Flow),
 | 
			
		||||
		Rate:      nil,
 | 
			
		||||
		NoStore:   noStore,
 | 
			
		||||
		id:        GetCsvDb().GetClientId(),
 | 
			
		||||
		RWMutex:   sync.RWMutex{},
 | 
			
		||||
		NoDisplay: noDisplay,
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
package mux
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"io"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//write bytes with int32 length
 | 
			
		||||
func WriteLenBytes(buf []byte, w io.Writer) (int, error) {
 | 
			
		||||
	raw := bytes.NewBuffer([]byte{})
 | 
			
		||||
	if err := binary.Write(raw, binary.LittleEndian, int32(len(buf))); err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	if err := binary.Write(raw, binary.LittleEndian, buf); err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	return w.Write(raw.Bytes())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//read bytes by length
 | 
			
		||||
func ReadLenBytes(buf []byte, r io.Reader) (int, error) {
 | 
			
		||||
	var l int32
 | 
			
		||||
	var err error
 | 
			
		||||
	if binary.Read(r, binary.LittleEndian, &l) != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	if _, err = io.ReadFull(r, buf[:l]); err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	return int(l), nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,148 @@
 | 
			
		|||
package mux
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"github.com/cnlh/nps/lib/pool"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type conn struct {
 | 
			
		||||
	net.Conn
 | 
			
		||||
	readMsgCh        chan []byte
 | 
			
		||||
	getStatusCh      chan struct{}
 | 
			
		||||
	connStatusOkCh   chan struct{}
 | 
			
		||||
	connStatusFailCh chan struct{}
 | 
			
		||||
	readTimeOut      time.Time
 | 
			
		||||
	writeTimeOut     time.Time
 | 
			
		||||
	sendMsgCh        chan *msg  //mux
 | 
			
		||||
	sendStatusCh     chan int32 //mux
 | 
			
		||||
	connId           int32
 | 
			
		||||
	isClose          bool
 | 
			
		||||
	mux              *Mux
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type msg struct {
 | 
			
		||||
	connId  int32
 | 
			
		||||
	content []byte
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewMsg(connId int32, content []byte) *msg {
 | 
			
		||||
	return &msg{
 | 
			
		||||
		connId:  connId,
 | 
			
		||||
		content: content,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewConn(connId int32, mux *Mux, sendMsgCh chan *msg, sendStatusCh chan int32) *conn {
 | 
			
		||||
	return &conn{
 | 
			
		||||
		readMsgCh:        make(chan []byte),
 | 
			
		||||
		getStatusCh:      make(chan struct{}),
 | 
			
		||||
		connStatusOkCh:   make(chan struct{}),
 | 
			
		||||
		connStatusFailCh: make(chan struct{}),
 | 
			
		||||
		readTimeOut:      time.Time{},
 | 
			
		||||
		writeTimeOut:     time.Time{},
 | 
			
		||||
		sendMsgCh:        sendMsgCh,
 | 
			
		||||
		sendStatusCh:     sendStatusCh,
 | 
			
		||||
		connId:           connId,
 | 
			
		||||
		isClose:          false,
 | 
			
		||||
		mux:              mux,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *conn) Read(buf []byte) (int, error) {
 | 
			
		||||
	if s.isClose {
 | 
			
		||||
		return 0, errors.New("the conn has closed")
 | 
			
		||||
	}
 | 
			
		||||
	var b []byte
 | 
			
		||||
	if t := s.readTimeOut.Sub(time.Now()); t > 0 {
 | 
			
		||||
		timer := time.NewTimer(t)
 | 
			
		||||
		select {
 | 
			
		||||
		case <-timer.C:
 | 
			
		||||
			s.Close()
 | 
			
		||||
			return 0, errors.New("read timeout")
 | 
			
		||||
		case b = <-s.readMsgCh:
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		b = <-s.readMsgCh
 | 
			
		||||
	}
 | 
			
		||||
	defer pool.PutBufPoolCopy(b)
 | 
			
		||||
	if s.isClose {
 | 
			
		||||
		return 0, io.EOF
 | 
			
		||||
	}
 | 
			
		||||
	s.sendStatusCh <- s.connId
 | 
			
		||||
	return copy(buf, b), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *conn) Write(buf []byte) (int, error) {
 | 
			
		||||
	if s.isClose {
 | 
			
		||||
		return 0, errors.New("the conn has closed")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if t := s.writeTimeOut.Sub(time.Now()); t > 0 {
 | 
			
		||||
		timer := time.NewTimer(t)
 | 
			
		||||
		select {
 | 
			
		||||
		case <-timer.C:
 | 
			
		||||
			s.Close()
 | 
			
		||||
			return 0, errors.New("write timeout")
 | 
			
		||||
		case s.sendMsgCh <- NewMsg(s.connId, buf):
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		s.sendMsgCh <- NewMsg(s.connId, buf)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if t := s.writeTimeOut.Sub(time.Now()); t > 0 {
 | 
			
		||||
		timer := time.NewTimer(t)
 | 
			
		||||
		select {
 | 
			
		||||
		case <-timer.C:
 | 
			
		||||
			s.Close()
 | 
			
		||||
			return 0, errors.New("write timeout")
 | 
			
		||||
		case <-s.getStatusCh:
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		<-s.getStatusCh
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if s.isClose {
 | 
			
		||||
		return 0, io.EOF
 | 
			
		||||
	}
 | 
			
		||||
	return len(buf), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *conn) Close() error {
 | 
			
		||||
	if s.isClose {
 | 
			
		||||
		return errors.New("the conn has closed")
 | 
			
		||||
	}
 | 
			
		||||
	s.isClose = true
 | 
			
		||||
	close(s.getStatusCh)
 | 
			
		||||
	close(s.readMsgCh)
 | 
			
		||||
	close(s.connStatusOkCh)
 | 
			
		||||
	close(s.connStatusFailCh)
 | 
			
		||||
	s.sendMsgCh <- NewMsg(s.connId, nil)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *conn) LocalAddr() net.Addr {
 | 
			
		||||
	return s.mux.conn.LocalAddr()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *conn) RemoteAddr() net.Addr {
 | 
			
		||||
	return s.mux.conn.RemoteAddr()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *conn) SetDeadline(t time.Time) error {
 | 
			
		||||
	s.readTimeOut = t
 | 
			
		||||
	s.writeTimeOut = t
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *conn) SetReadDeadline(t time.Time) error {
 | 
			
		||||
	s.readTimeOut = t
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *conn) SetWriteDeadline(t time.Time) error {
 | 
			
		||||
	s.writeTimeOut = t
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
package mux
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type connMap struct {
 | 
			
		||||
	connMap map[int32]*conn
 | 
			
		||||
	closeCh chan struct{}
 | 
			
		||||
	sync.RWMutex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewConnMap() *connMap {
 | 
			
		||||
	connMap := &connMap{
 | 
			
		||||
		connMap: make(map[int32]*conn),
 | 
			
		||||
		closeCh: make(chan struct{}),
 | 
			
		||||
	}
 | 
			
		||||
	go connMap.clean()
 | 
			
		||||
	return connMap
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *connMap) Get(id int32) (*conn, bool) {
 | 
			
		||||
	s.Lock()
 | 
			
		||||
	defer s.Unlock()
 | 
			
		||||
	if v, ok := s.connMap[id]; ok {
 | 
			
		||||
		return v, true
 | 
			
		||||
	}
 | 
			
		||||
	return nil, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *connMap) Set(id int32, v *conn) {
 | 
			
		||||
	s.Lock()
 | 
			
		||||
	defer s.Unlock()
 | 
			
		||||
	s.connMap[id] = v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *connMap) Close() {
 | 
			
		||||
	s.Lock()
 | 
			
		||||
	defer s.Unlock()
 | 
			
		||||
	for _, v := range s.connMap {
 | 
			
		||||
		v.isClose = true
 | 
			
		||||
	}
 | 
			
		||||
	s.closeCh <- struct{}{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *connMap) clean() {
 | 
			
		||||
	ticker := time.NewTimer(time.Minute * 1)
 | 
			
		||||
	for {
 | 
			
		||||
		select {
 | 
			
		||||
		case <-ticker.C:
 | 
			
		||||
			s.Lock()
 | 
			
		||||
			for _, v := range s.connMap {
 | 
			
		||||
				if v.isClose {
 | 
			
		||||
					delete(s.connMap, v.connId)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			s.Unlock()
 | 
			
		||||
		case <-s.closeCh:
 | 
			
		||||
			ticker.Stop()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,226 @@
 | 
			
		|||
package mux
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"github.com/cnlh/nps/lib/pool"
 | 
			
		||||
	"math"
 | 
			
		||||
	"net"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	MUX_PING_FLAG int32 = iota
 | 
			
		||||
	MUX_NEW_CONN_OK
 | 
			
		||||
	MUX_NEW_CONN_Fail
 | 
			
		||||
	MUX_NEW_MSG
 | 
			
		||||
	MUX_MSG_SEND_OK
 | 
			
		||||
	MUX_NEW_CONN
 | 
			
		||||
	MUX_PING
 | 
			
		||||
	MUX_CONN_CLOSE
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Mux struct {
 | 
			
		||||
	net.Listener
 | 
			
		||||
	conn         net.Conn
 | 
			
		||||
	connMap      *connMap
 | 
			
		||||
	sendMsgCh    chan *msg  //write msg chan
 | 
			
		||||
	sendStatusCh chan int32 //write read ok chan
 | 
			
		||||
	newConnCh    chan *conn
 | 
			
		||||
	id           int32
 | 
			
		||||
	closeChan    chan struct{}
 | 
			
		||||
	isClose      bool
 | 
			
		||||
	sync.Mutex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewMux(c net.Conn) *Mux {
 | 
			
		||||
	m := &Mux{
 | 
			
		||||
		conn:         c,
 | 
			
		||||
		connMap:      NewConnMap(),
 | 
			
		||||
		sendMsgCh:    make(chan *msg),
 | 
			
		||||
		sendStatusCh: make(chan int32),
 | 
			
		||||
		id:           0,
 | 
			
		||||
		closeChan:    make(chan struct{}),
 | 
			
		||||
		newConnCh:    make(chan *conn),
 | 
			
		||||
		isClose:      false,
 | 
			
		||||
	}
 | 
			
		||||
	//read session by flag
 | 
			
		||||
	go m.readSession()
 | 
			
		||||
	//write session
 | 
			
		||||
	go m.writeSession()
 | 
			
		||||
	//ping
 | 
			
		||||
	go m.ping()
 | 
			
		||||
	return m
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Mux) NewConn() (*conn, error) {
 | 
			
		||||
	if s.isClose {
 | 
			
		||||
		return nil, errors.New("the mux has closed")
 | 
			
		||||
	}
 | 
			
		||||
	conn := NewConn(s.getId(), s, s.sendMsgCh, s.sendStatusCh)
 | 
			
		||||
	raw := bytes.NewBuffer([]byte{})
 | 
			
		||||
	if err := binary.Write(raw, binary.LittleEndian, MUX_NEW_CONN); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if err := binary.Write(raw, binary.LittleEndian, conn.connId); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	//it must be set before send
 | 
			
		||||
	s.connMap.Set(conn.connId, conn)
 | 
			
		||||
	if _, err := s.conn.Write(raw.Bytes()); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	select {
 | 
			
		||||
	case <-conn.connStatusOkCh:
 | 
			
		||||
		return conn, nil
 | 
			
		||||
	case <-conn.connStatusFailCh:
 | 
			
		||||
	}
 | 
			
		||||
	return nil, errors.New("create connection fail,the server refused the connection")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Mux) Accept() (net.Conn, error) {
 | 
			
		||||
	if s.isClose {
 | 
			
		||||
		return nil, errors.New("accpet error,the conn has closed")
 | 
			
		||||
	}
 | 
			
		||||
	return <-s.newConnCh, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Mux) Addr() net.Addr {
 | 
			
		||||
	return s.conn.LocalAddr()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Mux) ping() {
 | 
			
		||||
	go func() {
 | 
			
		||||
		ticker := time.NewTicker(time.Second * 5)
 | 
			
		||||
		raw := bytes.NewBuffer([]byte{})
 | 
			
		||||
		for {
 | 
			
		||||
			select {
 | 
			
		||||
			case <-ticker.C:
 | 
			
		||||
			}
 | 
			
		||||
			//Avoid going beyond the scope
 | 
			
		||||
			if (math.MaxInt32 - s.id) < 10000 {
 | 
			
		||||
				s.id = 0
 | 
			
		||||
			}
 | 
			
		||||
			raw.Reset()
 | 
			
		||||
			binary.Write(raw, binary.LittleEndian, MUX_PING_FLAG)
 | 
			
		||||
			binary.Write(raw, binary.LittleEndian, MUX_PING)
 | 
			
		||||
			if _, err := s.conn.Write(raw.Bytes()); err != nil {
 | 
			
		||||
				s.Close()
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	select {
 | 
			
		||||
	case <-s.closeChan:
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Mux) writeSession() {
 | 
			
		||||
	go func() {
 | 
			
		||||
		raw := bytes.NewBuffer([]byte{})
 | 
			
		||||
		for {
 | 
			
		||||
			raw.Reset()
 | 
			
		||||
			select {
 | 
			
		||||
			case msg := <-s.sendMsgCh:
 | 
			
		||||
				if msg.content == nil { //close
 | 
			
		||||
					binary.Write(raw, binary.LittleEndian, MUX_CONN_CLOSE)
 | 
			
		||||
					binary.Write(raw, binary.LittleEndian, msg.connId)
 | 
			
		||||
					break
 | 
			
		||||
				}
 | 
			
		||||
				binary.Write(raw, binary.LittleEndian, MUX_NEW_MSG)
 | 
			
		||||
				binary.Write(raw, binary.LittleEndian, msg.connId)
 | 
			
		||||
				binary.Write(raw, binary.LittleEndian, int32(len(msg.content)))
 | 
			
		||||
				binary.Write(raw, binary.LittleEndian, msg.content)
 | 
			
		||||
			case connId := <-s.sendStatusCh:
 | 
			
		||||
				binary.Write(raw, binary.LittleEndian, MUX_MSG_SEND_OK)
 | 
			
		||||
				binary.Write(raw, binary.LittleEndian, connId)
 | 
			
		||||
			}
 | 
			
		||||
			if _, err := s.conn.Write(raw.Bytes()); err != nil {
 | 
			
		||||
				s.Close()
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	select {
 | 
			
		||||
	case <-s.closeChan:
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Mux) readSession() {
 | 
			
		||||
	go func() {
 | 
			
		||||
		raw := bytes.NewBuffer([]byte{})
 | 
			
		||||
		for {
 | 
			
		||||
			var flag, i int32
 | 
			
		||||
			if binary.Read(s.conn, binary.LittleEndian, &flag) == nil {
 | 
			
		||||
				if binary.Read(s.conn, binary.LittleEndian, &i) != nil {
 | 
			
		||||
					break
 | 
			
		||||
				}
 | 
			
		||||
				switch flag {
 | 
			
		||||
				case MUX_NEW_CONN: //new conn
 | 
			
		||||
					conn := NewConn(i, s, s.sendMsgCh, s.sendStatusCh)
 | 
			
		||||
					s.connMap.Set(i, conn) //it has been set before send ok
 | 
			
		||||
					s.newConnCh <- conn
 | 
			
		||||
					raw.Reset()
 | 
			
		||||
					binary.Write(raw, binary.LittleEndian, MUX_NEW_CONN_OK)
 | 
			
		||||
					binary.Write(raw, binary.LittleEndian, i)
 | 
			
		||||
					s.conn.Write(raw.Bytes())
 | 
			
		||||
					continue
 | 
			
		||||
				case MUX_PING_FLAG: //ping
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				if conn, ok := s.connMap.Get(i); ok {
 | 
			
		||||
					switch flag {
 | 
			
		||||
					case MUX_NEW_MSG: //new msg from remote conn
 | 
			
		||||
						buf := pool.BufPoolCopy.Get().([]byte)
 | 
			
		||||
						if n, err := ReadLenBytes(buf, s.conn); err == nil {
 | 
			
		||||
							if !conn.isClose {
 | 
			
		||||
								conn.readMsgCh <- buf[:n]
 | 
			
		||||
							} else {
 | 
			
		||||
								pool.PutBufPoolCopy(buf)
 | 
			
		||||
							}
 | 
			
		||||
						} else { //read len bytes error,the mux has broken
 | 
			
		||||
							break
 | 
			
		||||
						}
 | 
			
		||||
					case MUX_MSG_SEND_OK: //the remote has read
 | 
			
		||||
						conn.getStatusCh <- struct{}{}
 | 
			
		||||
					case MUX_NEW_CONN_OK: //conn ok
 | 
			
		||||
						conn.connStatusOkCh <- struct{}{}
 | 
			
		||||
					case MUX_NEW_CONN_Fail:
 | 
			
		||||
						conn.connStatusFailCh <- struct{}{}
 | 
			
		||||
					case MUX_CONN_CLOSE: //close the connection
 | 
			
		||||
						conn.Close()
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		s.Close()
 | 
			
		||||
	}()
 | 
			
		||||
	select {
 | 
			
		||||
	case <-s.closeChan:
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Mux) Close() error {
 | 
			
		||||
	if s.isClose {
 | 
			
		||||
		return errors.New("the mux has closed")
 | 
			
		||||
	}
 | 
			
		||||
	s.isClose = true
 | 
			
		||||
	s.connMap.Close()
 | 
			
		||||
	s.closeChan <- struct{}{}
 | 
			
		||||
	s.closeChan <- struct{}{}
 | 
			
		||||
	s.closeChan <- struct{}{}
 | 
			
		||||
	close(s.closeChan)
 | 
			
		||||
	close(s.sendMsgCh)
 | 
			
		||||
	close(s.sendStatusCh)
 | 
			
		||||
	return s.conn.Close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//get new connId as unique flag
 | 
			
		||||
func (s *Mux) getId() int32 {
 | 
			
		||||
	return atomic.AddInt32(&s.id, 1)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,96 @@
 | 
			
		|||
package mux
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/cnlh/nps/lib/common"
 | 
			
		||||
	"github.com/cnlh/nps/vender/github.com/astaxie/beego/logs"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	_ "net/http/pprof"
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var conn1 net.Conn
 | 
			
		||||
var conn2 net.Conn
 | 
			
		||||
 | 
			
		||||
func TestNewMux(t *testing.T) {
 | 
			
		||||
	go func() {
 | 
			
		||||
		http.ListenAndServe("0.0.0.0:8899", nil)
 | 
			
		||||
	}()
 | 
			
		||||
	logs.EnableFuncCallDepth(true)
 | 
			
		||||
	logs.SetLogFuncCallDepth(3)
 | 
			
		||||
	server()
 | 
			
		||||
	client()
 | 
			
		||||
	time.Sleep(time.Second * 3)
 | 
			
		||||
	go func() {
 | 
			
		||||
		m2 := NewMux(conn2)
 | 
			
		||||
		for {
 | 
			
		||||
			c, err := m2.Accept()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Fatalln(err)
 | 
			
		||||
			}
 | 
			
		||||
			go func(c net.Conn) {
 | 
			
		||||
				c2, err := net.Dial("tcp", "127.0.0.1:8080")
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					log.Fatalln(err)
 | 
			
		||||
				}
 | 
			
		||||
				go common.CopyBuffer(c2, c)
 | 
			
		||||
				common.CopyBuffer(c, c2)
 | 
			
		||||
				c.Close()
 | 
			
		||||
				c2.Close()
 | 
			
		||||
			}(c)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	go func() {
 | 
			
		||||
		m1 := NewMux(conn1)
 | 
			
		||||
		l, err := net.Listen("tcp", "127.0.0.1:7777")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Fatalln(err)
 | 
			
		||||
		}
 | 
			
		||||
		for {
 | 
			
		||||
			conn, err := l.Accept()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Fatalln(err)
 | 
			
		||||
			}
 | 
			
		||||
			go func(conn net.Conn) {
 | 
			
		||||
				tmpCpnn, err := m1.NewConn()
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					log.Fatalln(err)
 | 
			
		||||
				}
 | 
			
		||||
				go common.CopyBuffer(tmpCpnn, conn)
 | 
			
		||||
				common.CopyBuffer(conn, tmpCpnn)
 | 
			
		||||
				conn.Close()
 | 
			
		||||
				tmpCpnn.Close()
 | 
			
		||||
			}(conn)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		time.Sleep(time.Second * 5)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func server() {
 | 
			
		||||
	var err error
 | 
			
		||||
	l, err := net.Listen("tcp", "127.0.0.1:9999")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalln(err)
 | 
			
		||||
	}
 | 
			
		||||
	go func() {
 | 
			
		||||
		conn1, err = l.Accept()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Fatalln(err)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func client() {
 | 
			
		||||
	var err error
 | 
			
		||||
	conn2, err = net.Dial("tcp", "127.0.0.1:9999")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalln(err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -42,6 +42,7 @@ func PutBufPoolUdp(buf []byte) {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func PutBufPoolCopy(buf []byte) {
 | 
			
		||||
	if cap(buf) == PoolSizeCopy {
 | 
			
		||||
		BufPoolCopy.Put(buf[:PoolSizeCopy])
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,6 @@ import (
 | 
			
		|||
	"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"
 | 
			
		||||
| 
						 | 
				
			
			@ -58,27 +57,11 @@ func (s *BaseServer) linkCopy(link *conn.Link, c *conn.Conn, rb []byte, tunnel *
 | 
			
		|||
		flow.Add(len(rb), 0)
 | 
			
		||||
		<-link.StatusCh
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	buf := pool.BufPoolCopy.Get().([]byte)
 | 
			
		||||
	for {
 | 
			
		||||
		if err := s.checkFlow(); err != nil {
 | 
			
		||||
			c.Close()
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		if n, err := c.Read(buf); err != nil {
 | 
			
		||||
			tunnel.SendMsg([]byte(common.IO_EOF), link)
 | 
			
		||||
			break
 | 
			
		||||
		} else {
 | 
			
		||||
			if _, err := tunnel.SendMsg(buf[:n], link); err != nil {
 | 
			
		||||
				c.Close()
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			flow.Add(n, 0)
 | 
			
		||||
		}
 | 
			
		||||
		<-link.StatusCh
 | 
			
		||||
	if err := s.checkFlow(); err != nil {
 | 
			
		||||
		c.Close()
 | 
			
		||||
	}
 | 
			
		||||
	link.RunRead(tunnel)
 | 
			
		||||
	s.task.Client.AddConn()
 | 
			
		||||
	pool.PutBufPoolCopy(buf)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *BaseServer) writeConnFail(c net.Conn) {
 | 
			
		||||
| 
						 | 
				
			
			@ -111,7 +94,7 @@ func (s *BaseServer) DealClient(c *conn.Conn, addr string, rb []byte) error {
 | 
			
		|||
		c.Close()
 | 
			
		||||
		return err
 | 
			
		||||
	} else {
 | 
			
		||||
		link.Run(true)
 | 
			
		||||
		link.RunWrite()
 | 
			
		||||
		s.linkCopy(link, c, rb, tunnel, s.task.Flow)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -150,7 +150,7 @@ func (s *httpServer) process(c *conn.Conn, r *http.Request) {
 | 
			
		|||
				logs.Notice(err)
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			lk.Run(true)
 | 
			
		||||
			lk.RunWrite()
 | 
			
		||||
			isConn = false
 | 
			
		||||
		} else {
 | 
			
		||||
			r, err = http.ReadRequest(bufio.NewReader(c))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,104 @@
 | 
			
		|||
package proxy
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/cnlh/nps/lib/common"
 | 
			
		||||
	"github.com/cnlh/nps/lib/conn"
 | 
			
		||||
	"github.com/cnlh/nps/vender/github.com/astaxie/beego/logs"
 | 
			
		||||
	"github.com/cnlh/nps/vender/github.com/xtaci/kcp"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type P2PServer struct {
 | 
			
		||||
	BaseServer
 | 
			
		||||
	p2pPort int
 | 
			
		||||
	p2p     map[string]*p2p
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type p2p struct {
 | 
			
		||||
	provider     *conn.Conn
 | 
			
		||||
	visitor      *conn.Conn
 | 
			
		||||
	visitorAddr  string
 | 
			
		||||
	providerAddr string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewP2PServer(p2pPort int) *P2PServer {
 | 
			
		||||
	return &P2PServer{
 | 
			
		||||
		p2pPort: p2pPort,
 | 
			
		||||
		p2p:     make(map[string]*p2p),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *P2PServer) Start() error {
 | 
			
		||||
	kcpListener, err := kcp.ListenWithOptions(":"+strconv.Itoa(s.p2pPort), nil, 150, 3)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logs.Error(err)
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	for {
 | 
			
		||||
		c, err := kcpListener.AcceptKCP()
 | 
			
		||||
		conn.SetUdpSession(c)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logs.Warn(err)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		go s.p2pProcess(conn.NewConn(c))
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *P2PServer) p2pProcess(c *conn.Conn) {
 | 
			
		||||
	logs.Warn("new link", c.Conn.RemoteAddr())
 | 
			
		||||
	//获取密钥
 | 
			
		||||
	var (
 | 
			
		||||
		f   string
 | 
			
		||||
		b   []byte
 | 
			
		||||
		err error
 | 
			
		||||
		v   *p2p
 | 
			
		||||
		ok  bool
 | 
			
		||||
	)
 | 
			
		||||
	if b, err = c.ReadLen(32); err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	//获取角色
 | 
			
		||||
	if f, err = c.ReadFlag(); err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	logs.Warn("收到", string(b), f)
 | 
			
		||||
	if v, ok = s.p2p[string(b)]; !ok {
 | 
			
		||||
		v = new(p2p)
 | 
			
		||||
		s.p2p[string(b)] = v
 | 
			
		||||
	}
 | 
			
		||||
	logs.Warn(f, c.Conn.RemoteAddr().String())
 | 
			
		||||
	//存储
 | 
			
		||||
	if f == common.WORK_P2P_VISITOR {
 | 
			
		||||
		v.visitorAddr = c.Conn.RemoteAddr().String()
 | 
			
		||||
		v.visitor = c
 | 
			
		||||
		for {
 | 
			
		||||
			time.Sleep(time.Second)
 | 
			
		||||
			if v.provider != nil {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		logs.Warn("等待确认")
 | 
			
		||||
		if _, err := v.provider.ReadFlag(); err == nil {
 | 
			
		||||
			v.visitor.WriteLenContent([]byte(v.providerAddr))
 | 
			
		||||
			logs.Warn("收到确认")
 | 
			
		||||
			delete(s.p2p, string(b))
 | 
			
		||||
		} else {
 | 
			
		||||
			logs.Warn("收到确认失败", err)
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		v.providerAddr = c.Conn.RemoteAddr().String()
 | 
			
		||||
		v.provider = c
 | 
			
		||||
		for {
 | 
			
		||||
			time.Sleep(time.Second)
 | 
			
		||||
			if v.visitor != nil {
 | 
			
		||||
				v.provider.WriteLenContent([]byte(v.visitorAddr))
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	//假设是连接者、等待对应的被连接者连上后,发送被连接者信息
 | 
			
		||||
	//假设是被连接者,等待对应的连接者脸上后,发送连接者信息
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +148,7 @@ func (s *Sock5ModeServer) doConnect(c net.Conn, command uint8) {
 | 
			
		|||
		return
 | 
			
		||||
	} else {
 | 
			
		||||
		s.sendReply(c, succeeded)
 | 
			
		||||
		link.Run(true)
 | 
			
		||||
		link.RunWrite()
 | 
			
		||||
		s.linkCopy(link, conn.NewConn(c), nil, tunnel, s.task.Flow)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,7 +58,7 @@ func (s *UdpModeServer) process(addr *net.UDPAddr, data []byte) {
 | 
			
		|||
		s.task.Flow.Add(len(data), 0)
 | 
			
		||||
		tunnel.SendMsg(data, link)
 | 
			
		||||
		pool.PutBufPoolUdp(data)
 | 
			
		||||
		link.Run(true)
 | 
			
		||||
		link.RunWrite()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,7 +48,7 @@ func DealBridgeTask() {
 | 
			
		|||
			file.GetCsvDb().DelClient(id)
 | 
			
		||||
		case s := <-Bridge.SecretChan:
 | 
			
		||||
			logs.Trace("New secret connection, addr", s.Conn.Conn.RemoteAddr())
 | 
			
		||||
			if t := file.GetCsvDb().GetSecretTask(s.Password); t != nil {
 | 
			
		||||
			if t := file.GetCsvDb().GetTaskByMd5Password(s.Password); t != nil {
 | 
			
		||||
				if !t.Client.GetConn() {
 | 
			
		||||
					logs.Info("Connections exceed the current client %d limit", t.Client.Id)
 | 
			
		||||
					s.Conn.Close()
 | 
			
		||||
| 
						 | 
				
			
			@ -75,6 +75,9 @@ func StartNewServer(bridgePort int, cnf *file.Tunnel, bridgeType string) {
 | 
			
		|||
	} else {
 | 
			
		||||
		logs.Info("Server startup, the bridge type is %s, the bridge port is %d", bridgeType, bridgePort)
 | 
			
		||||
	}
 | 
			
		||||
	if p, err := beego.AppConfig.Int("p2pPort"); err == nil {
 | 
			
		||||
		go proxy.NewP2PServer(p).Start()
 | 
			
		||||
	}
 | 
			
		||||
	go DealBridgeTask()
 | 
			
		||||
	if svr := NewMode(Bridge, cnf); svr != nil {
 | 
			
		||||
		if err := svr.Start(); err != nil {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue