mirror of https://github.com/ehang-io/nps
pull/1219/head
parent
cc90bcf4e9
commit
c533436c78
|
@ -84,9 +84,9 @@ func (s *Csv) StoreTasksToCsv() {
|
|||
writer.Flush()
|
||||
}
|
||||
|
||||
func (s *Csv) LoadTaskFromCsv() {
|
||||
func (s *Csv) openFile(path string) ([][]string, error) {
|
||||
// 打开文件
|
||||
file, err := os.Open(beego.AppPath + "/conf/tasks.csv")
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -99,28 +99,31 @@ func (s *Csv) LoadTaskFromCsv() {
|
|||
reader.FieldsPerRecord = -1
|
||||
|
||||
// 读取文件中所有行保存到slice中
|
||||
records, err := reader.ReadAll()
|
||||
return reader.ReadAll()
|
||||
}
|
||||
|
||||
func (s *Csv) LoadTaskFromCsv() {
|
||||
path := beego.AppPath + "/conf/tasks.csv"
|
||||
records, err := s.openFile(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
log.Fatal("配置文件打开错误:", path)
|
||||
}
|
||||
var tasks []*ServerConfig
|
||||
// 将每一行数据保存到内存slice中
|
||||
for _, item := range records {
|
||||
tcpPort, _ := strconv.Atoi(item[0])
|
||||
Start, _ := strconv.Atoi(item[7])
|
||||
post := &ServerConfig{
|
||||
TcpPort: tcpPort,
|
||||
TcpPort: utils.GetIntNoErrByStr(item[0]),
|
||||
Mode: item[1],
|
||||
Target: item[2],
|
||||
VerifyKey: item[3],
|
||||
U: item[4],
|
||||
P: item[5],
|
||||
Compress: item[6],
|
||||
Start: Start,
|
||||
Start: utils.GetIntNoErrByStr(item[7]),
|
||||
Crypt: utils.GetBoolByStr(item[8]),
|
||||
Mux: utils.GetBoolByStr(item[9]),
|
||||
CompressEncode: utils.GetIntNoerrByStr(item[10]),
|
||||
CompressDecode: utils.GetIntNoerrByStr(item[11]),
|
||||
CompressEncode: utils.GetIntNoErrByStr(item[10]),
|
||||
CompressDecode: utils.GetIntNoErrByStr(item[11]),
|
||||
}
|
||||
tasks = append(tasks, post)
|
||||
}
|
||||
|
@ -214,23 +217,10 @@ func (s *Csv) StoreHostToCsv() {
|
|||
}
|
||||
|
||||
func (s *Csv) LoadHostFromCsv() {
|
||||
// 打开文件
|
||||
file, err := os.Open(beego.AppPath + "/conf/hosts.csv")
|
||||
path := beego.AppPath + "/conf/hosts.csv"
|
||||
records, err := s.openFile(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 获取csv的reader
|
||||
reader := csv.NewReader(file)
|
||||
|
||||
// 设置FieldsPerRecord为-1
|
||||
reader.FieldsPerRecord = -1
|
||||
|
||||
// 读取文件中所有行保存到slice中
|
||||
records, err := reader.ReadAll()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
log.Fatal("配置文件打开错误:", path)
|
||||
}
|
||||
var hosts []*HostList
|
||||
// 将每一行数据保存到内存slice中
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"github.com/cnlh/easyProxy/utils"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type process func(c *utils.Conn, s *TunnelModeServer) error
|
||||
|
||||
//tcp隧道模式
|
||||
func ProcessTunnel(c *utils.Conn, s *TunnelModeServer) error {
|
||||
_, _, rb, err, r := c.GetHost()
|
||||
if err == nil {
|
||||
if err := s.auth(r, c, s.config.U, s.config.P); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return s.dealClient(c, s.config, s.config.Target, "", rb)
|
||||
}
|
||||
|
||||
//http代理模式
|
||||
func ProcessHttp(c *utils.Conn, s *TunnelModeServer) error {
|
||||
method, addr, rb, err, r := c.GetHost()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
c.Close()
|
||||
return err
|
||||
}
|
||||
if err := s.auth(r, c, s.config.U, s.config.P); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.dealClient(c, s.config, addr, method, rb)
|
||||
}
|
||||
|
||||
//多客户端域名代理
|
||||
func ProcessHost(c *utils.Conn, s *TunnelModeServer) error {
|
||||
var (
|
||||
isConn = true
|
||||
link *utils.Conn
|
||||
cnf *ServerConfig
|
||||
host *HostList
|
||||
wg sync.WaitGroup
|
||||
)
|
||||
for {
|
||||
r, err := http.ReadRequest(bufio.NewReader(c))
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
//首次获取conn
|
||||
if isConn {
|
||||
isConn = false
|
||||
if host, cnf, err = GetKeyByHost(r.Host); err != nil {
|
||||
log.Printf("the host %s is not found !", r.Host)
|
||||
break
|
||||
}
|
||||
|
||||
if err = s.auth(r, c, cnf.U, cnf.P); err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
if link, err = s.GetTunnelAndWriteHost(utils.CONN_TCP, cnf, host.Target); err != nil {
|
||||
log.Println("get bridge tunnel error: ", err)
|
||||
break
|
||||
}
|
||||
|
||||
if flag, err := link.ReadFlag(); err != nil || flag == utils.CONN_ERROR {
|
||||
log.Printf("the host %s connection to %s error", r.Host, host.Target)
|
||||
break
|
||||
} else {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
utils.Relay(c.Conn, link.Conn, cnf.CompressDecode, cnf.Crypt, cnf.Mux)
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
}
|
||||
utils.ChangeHostAndHeader(r, host.HostChange, host.HeaderChange, c.Conn.RemoteAddr().String())
|
||||
b, err := httputil.DumpRequest(r, true)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
if _, err := link.WriteTo(b, cnf.CompressEncode, cnf.Crypt); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
if cnf != nil && cnf.Mux && link != nil {
|
||||
link.WriteTo([]byte(utils.IO_EOF), cnf.CompressEncode, cnf.Crypt)
|
||||
s.bridge.ReturnTunnel(link, getverifyval(cnf.VerifyKey))
|
||||
} else if link != nil {
|
||||
link.Close()
|
||||
}
|
||||
c.Close()
|
||||
return nil
|
||||
}
|
|
@ -46,10 +46,9 @@ const (
|
|||
)
|
||||
|
||||
type Sock5ModeServer struct {
|
||||
bridge *bridge.Tunnel
|
||||
server
|
||||
isVerify bool
|
||||
listener net.Listener
|
||||
config *ServerConfig
|
||||
}
|
||||
|
||||
//req
|
||||
|
@ -136,26 +135,24 @@ func (s *Sock5ModeServer) doConnect(c net.Conn, command uint8) (proxyConn *utils
|
|||
binary.Read(c, binary.BigEndian, &port)
|
||||
// connect to host
|
||||
addr := net.JoinHostPort(host, strconv.Itoa(int(port)))
|
||||
client, err := s.bridge.GetTunnel(getverifyval(s.config.VerifyKey), s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
s.sendReply(c, succeeded)
|
||||
var ltype string
|
||||
if command == associateMethod {
|
||||
ltype = utils.CONN_UDP
|
||||
} else {
|
||||
ltype = utils.CONN_TCP
|
||||
}
|
||||
_, err = client.WriteHost(ltype, addr)
|
||||
if proxyConn, err = s.GetTunnelAndWriteHost(ltype, s.config, addr); err != nil {
|
||||
log.Println("get bridge tunnel error: ", err)
|
||||
return
|
||||
}
|
||||
s.sendReply(c, succeeded)
|
||||
var flag string
|
||||
if flag, err = client.ReadFlag(); err == nil {
|
||||
if flag, err = proxyConn.ReadFlag(); err == nil {
|
||||
if flag != utils.CONN_SUCCESS {
|
||||
err = errors.New("conn failed")
|
||||
}
|
||||
}
|
||||
return client, err
|
||||
return
|
||||
}
|
||||
|
||||
//conn
|
||||
|
|
137
server/tcp.go
137
server/tcp.go
|
@ -1,7 +1,6 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/astaxie/beego"
|
||||
|
@ -10,17 +9,31 @@ import (
|
|||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type process func(c *utils.Conn, s *TunnelModeServer) error
|
||||
|
||||
type TunnelModeServer struct {
|
||||
process process
|
||||
//server base struct
|
||||
type server struct {
|
||||
bridge *bridge.Tunnel
|
||||
config *ServerConfig
|
||||
}
|
||||
|
||||
func (s *server) GetTunnelAndWriteHost(connType string, cnf *ServerConfig, addr string) (*utils.Conn, error) {
|
||||
var err error
|
||||
link, err := s.bridge.GetTunnel(getverifyval(cnf.VerifyKey), cnf.CompressEncode, cnf.CompressDecode, cnf.Crypt, cnf.Mux)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err = link.WriteHost(connType, addr); err != nil {
|
||||
link.Close()
|
||||
return nil, err
|
||||
}
|
||||
return link, nil
|
||||
}
|
||||
|
||||
type TunnelModeServer struct {
|
||||
server
|
||||
process process
|
||||
listener *net.TCPListener
|
||||
}
|
||||
|
||||
|
@ -64,10 +77,6 @@ func (s *TunnelModeServer) auth(r *http.Request, c *utils.Conn, u, p string) err
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *TunnelModeServer) dealClient2(c *utils.Conn, cnf *ServerConfig, addr string, method string, rb []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
//与客户端建立通道
|
||||
func (s *TunnelModeServer) dealClient(c *utils.Conn, cnf *ServerConfig, addr string, method string, rb []byte) error {
|
||||
var link *utils.Conn
|
||||
|
@ -77,7 +86,7 @@ func (s *TunnelModeServer) dealClient(c *utils.Conn, cnf *ServerConfig, addr str
|
|||
s.bridge.ReturnTunnel(link, getverifyval(cnf.VerifyKey))
|
||||
}
|
||||
}()
|
||||
if link, err = s.GetTunnelAndWriteHost(c, cnf, addr); err != nil {
|
||||
if link, err = s.GetTunnelAndWriteHost(utils.CONN_TCP, cnf, addr); err != nil {
|
||||
log.Println("get bridge tunnel error: ", err)
|
||||
return err
|
||||
}
|
||||
|
@ -99,109 +108,9 @@ func (s *TunnelModeServer) Close() error {
|
|||
return s.listener.Close()
|
||||
}
|
||||
|
||||
func (s *TunnelModeServer) GetTunnelAndWriteHost(c *utils.Conn, cnf *ServerConfig, addr string) (*utils.Conn, error) {
|
||||
var err error
|
||||
link, err := s.bridge.GetTunnel(getverifyval(cnf.VerifyKey), cnf.CompressEncode, cnf.CompressDecode, cnf.Crypt, cnf.Mux)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err = link.WriteHost(utils.CONN_TCP, addr); err != nil {
|
||||
link.Close()
|
||||
return nil, err
|
||||
}
|
||||
return link, nil
|
||||
}
|
||||
|
||||
//tcp隧道模式
|
||||
func ProcessTunnel(c *utils.Conn, s *TunnelModeServer) error {
|
||||
_, _, rb, err, r := c.GetHost()
|
||||
if err == nil {
|
||||
if err := s.auth(r, c, s.config.U, s.config.P); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return s.dealClient(c, s.config, s.config.Target, "", rb)
|
||||
}
|
||||
|
||||
//http代理模式
|
||||
func ProcessHttp(c *utils.Conn, s *TunnelModeServer) error {
|
||||
method, addr, rb, err, r := c.GetHost()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
c.Close()
|
||||
return err
|
||||
}
|
||||
if err := s.auth(r, c, s.config.U, s.config.P); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.dealClient(c, s.config, addr, method, rb)
|
||||
}
|
||||
|
||||
//多客户端域名代理
|
||||
func ProcessHost(c *utils.Conn, s *TunnelModeServer) error {
|
||||
var (
|
||||
isConn = true
|
||||
link *utils.Conn
|
||||
cnf *ServerConfig
|
||||
host *HostList
|
||||
wg sync.WaitGroup
|
||||
)
|
||||
for {
|
||||
r, err := http.ReadRequest(bufio.NewReader(c))
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
//首次获取conn
|
||||
if isConn {
|
||||
isConn = false
|
||||
if host, cnf, err = GetKeyByHost(r.Host); err != nil {
|
||||
log.Printf("the host %s is not found !", r.Host)
|
||||
break
|
||||
}
|
||||
|
||||
if err = s.auth(r, c, cnf.U, cnf.P); err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
if link, err = s.GetTunnelAndWriteHost(c, cnf, host.Target); err != nil {
|
||||
log.Println("get bridge tunnel error: ", err)
|
||||
break
|
||||
}
|
||||
|
||||
if flag, err := link.ReadFlag(); err != nil || flag == utils.CONN_ERROR {
|
||||
log.Printf("the host %s connection to %s error", r.Host, host.Target)
|
||||
break
|
||||
} else {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
utils.Relay(c.Conn, link.Conn, cnf.CompressDecode, cnf.Crypt, cnf.Mux)
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
}
|
||||
utils.ChangeHostAndHeader(r, host.HostChange, host.HeaderChange, c.Conn.RemoteAddr().String())
|
||||
b, err := httputil.DumpRequest(r, true)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
if _, err := link.WriteTo(b, cnf.CompressEncode, cnf.Crypt); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
if cnf != nil && cnf.Mux && link != nil {
|
||||
link.WriteTo([]byte(utils.IO_EOF), cnf.CompressEncode, cnf.Crypt)
|
||||
s.bridge.ReturnTunnel(link, getverifyval(cnf.VerifyKey))
|
||||
} else if link != nil {
|
||||
link.Close()
|
||||
}
|
||||
c.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
//web管理方式
|
||||
type WebServer struct {
|
||||
bridge *bridge.Tunnel
|
||||
server
|
||||
}
|
||||
|
||||
//开始
|
||||
|
@ -222,7 +131,7 @@ func NewWebServer(bridge *bridge.Tunnel) *WebServer {
|
|||
|
||||
//host
|
||||
type HostServer struct {
|
||||
config *ServerConfig
|
||||
server
|
||||
}
|
||||
|
||||
//开始
|
||||
|
|
|
@ -76,7 +76,7 @@ func GetCompressType(compress string) (int, int) {
|
|||
}
|
||||
|
||||
//通过host获取对应的ip地址
|
||||
func Gethostbyname(hostname string) string {
|
||||
func GetHostByName(hostname string) string {
|
||||
if !DomainCheck(hostname) {
|
||||
return hostname
|
||||
}
|
||||
|
@ -140,16 +140,17 @@ func GetStrByBool(b bool) string {
|
|||
}
|
||||
|
||||
//int
|
||||
func GetIntNoerrByStr(str string) int {
|
||||
func GetIntNoErrByStr(str string) int {
|
||||
i, _ := strconv.Atoi(str)
|
||||
return i
|
||||
}
|
||||
|
||||
|
||||
// io.copy的优化版,读取buffer长度原为32*1024,与snappy不同,导致读取出的内容存在差异,不利于解密,特此修改
|
||||
// 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 {
|
||||
|
|
|
@ -34,7 +34,7 @@ func (s *BaseController) display(tpl ...string) {
|
|||
}
|
||||
s.Data["menu"] = s.actionName
|
||||
ip := s.Ctx.Request.Host
|
||||
s.Data["ip"] = utils.Gethostbyname(ip[0:strings.LastIndex(ip, ":")])
|
||||
s.Data["ip"] = utils.GetHostByName(ip[0:strings.LastIndex(ip, ":")])
|
||||
s.Data["p"] = server.Bridge.TunnelPort
|
||||
s.Data["proxyPort"] = beego.AppConfig.String("hostPort")
|
||||
s.Layout = "public/layout.html"
|
||||
|
|
Loading…
Reference in New Issue