pull/1219/head
刘河 2019-01-15 20:59:50 +08:00
parent cc90bcf4e9
commit c533436c78
6 changed files with 150 additions and 154 deletions

View File

@ -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中

99
server/process.go Normal file
View File

@ -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
}

View File

@ -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

View File

@ -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
//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
bridge *bridge.Tunnel
config *ServerConfig
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
}
//开始

View File

@ -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 {

View File

@ -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"