新功能+bug修复

This commit is contained in:
刘河
2019-01-13 00:09:12 +08:00
parent bb882f348a
commit 851241a0c7
17 changed files with 394 additions and 178 deletions

View File

@@ -23,14 +23,16 @@ type ServerConfig struct {
ClientStatus int //客s户端状态
Crypt bool //是否加密
Mux bool //是否加密
CompressEncode int
CompressDecode int
CompressEncode int //加密方式
CompressDecode int //解密方式
}
type HostList struct {
Vkey string //服务端与客户端通信端口
Host string //启动方式
Target string //目标
Vkey string //服务端与客户端通信端口
Host string //启动方式
Target string //目标
HeaderChange string //host修改
HostChange string //host修改
}
func NewCsv(runList map[string]interface{}) *Csv {
@@ -125,64 +127,6 @@ func (s *Csv) LoadTaskFromCsv() {
s.Tasks = tasks
}
func (s *Csv) StoreHostToCsv() {
// 创建文件
csvFile, err := os.Create(beego.AppPath + "/conf/hosts.csv")
if err != nil {
panic(err)
}
defer csvFile.Close()
// 获取csv的Writer
writer := csv.NewWriter(csvFile)
// 将map中的Post转换成slice因为csv的Write需要slice参数
// 并写入csv文件
for _, host := range s.Hosts {
record := []string{
host.Host,
host.Target,
host.Vkey,
}
err1 := writer.Write(record)
if err1 != nil {
panic(err1)
}
}
// 确保所有内存数据刷到csv文件
writer.Flush()
}
func (s *Csv) LoadHostFromCsv() {
// 打开文件
file, err := os.Open(beego.AppPath + "/conf/hosts.csv")
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)
}
var hosts []*HostList
// 将每一行数据保存到内存slice中
for _, item := range records {
post := &HostList{
Vkey: item[2],
Host: item[0],
Target: item[1],
}
hosts = append(hosts, post)
}
s.Hosts = hosts
}
func (s *Csv) NewTask(t *ServerConfig) {
s.Tasks = append(s.Tasks, t)
s.StoreTasksToCsv()
@@ -200,6 +144,18 @@ func (s *Csv) UpdateTask(t *ServerConfig) error {
return errors.New("不存在")
}
func (s *Csv) UpdateHost(t *HostList) error {
for k, v := range s.Hosts {
if v.Host == t.Host {
s.Hosts = append(s.Hosts[:k], s.Hosts[k+1:]...)
s.Hosts = append(s.Hosts, t)
s.StoreHostToCsv()
return nil
}
}
return errors.New("不存在")
}
func (s *Csv) AddRunList(vKey string, svr interface{}) {
s.RunList[vKey] = svr
}
@@ -229,6 +185,68 @@ func (s *Csv) GetTask(vKey string) (v *ServerConfig, err error) {
return
}
func (s *Csv) StoreHostToCsv() {
// 创建文件
csvFile, err := os.Create(beego.AppPath + "/conf/hosts.csv")
if err != nil {
panic(err)
}
defer csvFile.Close()
// 获取csv的Writer
writer := csv.NewWriter(csvFile)
// 将map中的Post转换成slice因为csv的Write需要slice参数
// 并写入csv文件
for _, host := range s.Hosts {
record := []string{
host.Host,
host.Target,
host.Vkey,
host.HeaderChange,
host.HostChange,
}
err1 := writer.Write(record)
if err1 != nil {
panic(err1)
}
}
// 确保所有内存数据刷到csv文件
writer.Flush()
}
func (s *Csv) LoadHostFromCsv() {
// 打开文件
file, err := os.Open(beego.AppPath + "/conf/hosts.csv")
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)
}
var hosts []*HostList
// 将每一行数据保存到内存slice中
for _, item := range records {
post := &HostList{
Vkey: item[2],
Host: item[0],
Target: item[1],
HeaderChange: item[3],
HostChange: item[4],
}
hosts = append(hosts, post)
}
s.Hosts = hosts
}
func (s *Csv) DelHost(host string) error {
for k, v := range s.Hosts {
if v.Host == host {

View File

@@ -162,15 +162,14 @@ func (s *Sock5ModeServer) doConnect(c net.Conn, command uint8) (proxyConn *utils
func (s *Sock5ModeServer) handleConnect(c net.Conn) {
proxyConn, err := s.doConnect(c, connectMethod)
defer func() {
if s.config.Mux {
if s.config.Mux && proxyConn != nil {
s.bridge.ReturnTunnel(proxyConn, getverifyval(s.config.VerifyKey))
}
}()
if err != nil {
c.Close()
} else {
go utils.Relay(proxyConn.Conn, c, s.config.CompressEncode, s.config.Crypt, s.config.Mux)
utils.Relay(c, proxyConn.Conn, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
utils.ReplayWaitGroup(proxyConn.Conn, c, s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
}
}
@@ -200,15 +199,14 @@ func (s *Sock5ModeServer) handleUDP(c net.Conn) {
proxyConn, err := s.doConnect(c, associateMethod)
defer func() {
if s.config.Mux {
if s.config.Mux && proxyConn != nil {
s.bridge.ReturnTunnel(proxyConn, getverifyval(s.config.VerifyKey))
}
}()
if err != nil {
c.Close()
} else {
go utils.Relay(proxyConn.Conn, c, s.config.CompressEncode, s.config.Crypt, s.config.Mux)
utils.Relay(c, proxyConn.Conn, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
utils.ReplayWaitGroup(proxyConn.Conn, c, s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
}
}

View File

@@ -1,6 +1,7 @@
package server
import (
"bufio"
"errors"
"fmt"
"github.com/astaxie/beego"
@@ -9,7 +10,9 @@ import (
"log"
"net"
"net/http"
"net/http/httputil"
"strings"
"sync"
)
type process func(c *utils.Conn, s *TunnelModeServer) error
@@ -61,28 +64,23 @@ 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 {
reGet:
link, err := s.bridge.GetTunnel(getverifyval(cnf.VerifyKey), cnf.CompressEncode, cnf.CompressDecode, cnf.Crypt, cnf.Mux)
var link *utils.Conn
var err error
defer func() {
if cnf.Mux {
if cnf.Mux && link != nil {
s.bridge.ReturnTunnel(link, getverifyval(cnf.VerifyKey))
} else {
c.Close()
}
}()
if err != nil {
log.Println("conn to client error:", err)
c.Close()
if link, err = s.GetTunnelAndWriteHost(c, cnf, addr); err != nil {
log.Println("get bridge tunnel error: ", err)
return err
}
if _, err := link.WriteHost(utils.CONN_TCP, addr); err != nil {
c.Close()
link.Close()
log.Println(err)
goto reGet
}
if flag, err := link.ReadFlag(); err == nil {
if flag == utils.CONN_SUCCESS {
if method == "CONNECT" {
@@ -90,8 +88,7 @@ reGet:
} else if rb != nil {
link.WriteTo(rb, cnf.CompressEncode, cnf.Crypt)
}
go utils.Relay(link.Conn, c.Conn, cnf.CompressEncode, cnf.Crypt, cnf.Mux)
utils.Relay(c.Conn, link.Conn, cnf.CompressDecode, cnf.Crypt, cnf.Mux)
utils.ReplayWaitGroup(link.Conn, c.Conn, cnf.CompressEncode, cnf.CompressDecode, cnf.Crypt, cnf.Mux)
}
}
return nil
@@ -102,6 +99,19 @@ 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()
@@ -124,29 +134,69 @@ func ProcessHttp(c *utils.Conn, s *TunnelModeServer) error {
if err := s.auth(r, c, s.config.U, s.config.P); err != nil {
return err
}
//TODO 效率问题
return s.dealClient(c, s.config, addr, method, rb)
}
//多客户端域名代理
func ProcessHost(c *utils.Conn, s *TunnelModeServer) error {
method, addr, rb, err, r := c.GetHost()
if err != nil {
c.Close()
return err
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
}
}
host, task, err := GetKeyByHost(addr)
if err != nil {
return err
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()
}
if err := s.auth(r, c, task.U, task.P); err != nil {
return err
}
if err != nil {
c.Close()
return err
}
return s.dealClient(c, task, host.Target, method, rb)
c.Close()
return nil
}
//web管理方式

View File

@@ -58,7 +58,7 @@ func (s *UdpModeServer) process(addr *net.UDPAddr, data []byte) {
}
if flag, err := conn.ReadFlag(); err == nil {
defer func() {
if s.config.Mux {
if conn != nil && s.config.Mux {
conn.WriteTo([]byte(utils.IO_EOF), s.config.CompressEncode, s.config.Crypt)
s.bridge.ReturnTunnel(conn, getverifyval(s.config.VerifyKey))
} else {