dashboard 备注 客户端管理优化 多客户端支持 流量显示支持 热更新支持 404错误页支持

This commit is contained in:
刘河
2019-01-25 12:10:12 +08:00
parent c533436c78
commit c34e5e1a7d
37 changed files with 5415 additions and 732 deletions

76
server/base.go Normal file
View File

@@ -0,0 +1,76 @@
package server
import (
"github.com/cnlh/easyProxy/bridge"
"github.com/cnlh/easyProxy/utils"
"sync"
)
//server base struct
type server struct {
bridge *bridge.Tunnel
config *utils.ServerConfig
sync.Mutex
}
func (s *server) GetTunnelAndWriteHost(connType string, cnf *utils.ServerConfig, addr string) (*utils.Conn, error) {
var err error
link, err := s.bridge.GetTunnel(cnf.ClientId, 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
}
func (s *server) FlowAdd(in, out int64) {
s.Lock()
defer s.Unlock()
if s.config.Flow == nil {
s.config.Flow = new(utils.Flow)
}
s.config.Flow.ExportFlow += out
s.config.Flow.InletFlow += in
}
func (s *server) FlowAddHost(host *utils.HostList, in, out int64) {
s.Lock()
defer s.Unlock()
if s.config.Flow == nil {
s.config.Flow = new(utils.Flow)
}
host.Flow.ExportFlow += out
host.Flow.InletFlow += in
}
//热更新配置
func (s *server) ResetConfig() {
task, err := CsvDb.GetTask(s.config.Id)
if err != nil {
return
}
s.config.UseClientCnf = task.UseClientCnf
if s.config.UseClientCnf {
client, err := CsvDb.GetClient(s.config.ClientId)
if err == nil {
s.config.U = client.Cnf.U
s.config.P = client.Cnf.P
s.config.Compress = client.Cnf.Compress
s.config.Mux = client.Cnf.Mux
s.config.Crypt = client.Cnf.Crypt
}
s.config.CompressDecode, s.config.CompressEncode = utils.GetCompressType(client.Cnf.Compress)
} else {
if err == nil {
s.config.U = task.U
s.config.P = task.P
s.config.Compress = task.Compress
s.config.Mux = task.Mux
s.config.Crypt = task.Crypt
}
s.config.CompressDecode, s.config.CompressEncode = utils.GetCompressType(task.Compress)
}
}

View File

@@ -1,271 +0,0 @@
package server
import (
"encoding/csv"
"errors"
"github.com/astaxie/beego"
"github.com/cnlh/easyProxy/utils"
"log"
"os"
"strconv"
)
type ServerConfig struct {
TcpPort int //服务端与客户端通信端口
Mode string //启动方式
Target string //目标
VerifyKey string //flag
U string //socks5验证用户名
P string //socks5验证密码
Compress string //压缩方式
Start int //是否开启
IsRun int //是否在运行
ClientStatus int //客s户端状态
Crypt bool //是否加密
Mux bool //是否加密
CompressEncode int //加密方式
CompressDecode int //解密方式
}
type HostList struct {
Vkey string //服务端与客户端通信端口
Host string //启动方式
Target string //目标
HeaderChange string //host修改
HostChange string //host修改
}
func NewCsv(runList map[string]interface{}) *Csv {
c := new(Csv)
c.RunList = runList
return c
}
type Csv struct {
Tasks []*ServerConfig
Path string
RunList map[string]interface{}
Hosts []*HostList //域名列表
}
func (s *Csv) Init() {
s.LoadTaskFromCsv()
s.LoadHostFromCsv()
}
func (s *Csv) StoreTasksToCsv() {
// 创建文件
csvFile, err := os.Create(beego.AppPath + "/conf/tasks.csv")
if err != nil {
log.Fatalf(err.Error())
}
defer csvFile.Close()
writer := csv.NewWriter(csvFile)
for _, task := range s.Tasks {
record := []string{
strconv.Itoa(task.TcpPort),
task.Mode,
task.Target,
task.VerifyKey,
task.U,
task.P,
task.Compress,
strconv.Itoa(task.Start),
utils.GetStrByBool(task.Crypt),
utils.GetStrByBool(task.Mux),
strconv.Itoa(task.CompressEncode),
strconv.Itoa(task.CompressDecode),
}
err := writer.Write(record)
if err != nil {
log.Fatalf(err.Error())
}
}
writer.Flush()
}
func (s *Csv) openFile(path string) ([][]string, error) {
// 打开文件
file, err := os.Open(path)
if err != nil {
panic(err)
}
defer file.Close()
// 获取csv的reader
reader := csv.NewReader(file)
// 设置FieldsPerRecord为-1
reader.FieldsPerRecord = -1
// 读取文件中所有行保存到slice中
return reader.ReadAll()
}
func (s *Csv) LoadTaskFromCsv() {
path := beego.AppPath + "/conf/tasks.csv"
records, err := s.openFile(path)
if err != nil {
log.Fatal("配置文件打开错误:", path)
}
var tasks []*ServerConfig
// 将每一行数据保存到内存slice中
for _, item := range records {
post := &ServerConfig{
TcpPort: utils.GetIntNoErrByStr(item[0]),
Mode: item[1],
Target: item[2],
VerifyKey: item[3],
U: item[4],
P: item[5],
Compress: item[6],
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]),
}
tasks = append(tasks, post)
}
s.Tasks = tasks
}
func (s *Csv) NewTask(t *ServerConfig) {
s.Tasks = append(s.Tasks, t)
s.StoreTasksToCsv()
}
func (s *Csv) UpdateTask(t *ServerConfig) error {
for k, v := range s.Tasks {
if v.VerifyKey == t.VerifyKey {
s.Tasks = append(s.Tasks[:k], s.Tasks[k+1:]...)
s.Tasks = append(s.Tasks, t)
s.StoreTasksToCsv()
return nil
}
}
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
}
func (s *Csv) DelRunList(vKey string) {
delete(s.RunList, vKey)
}
func (s *Csv) DelTask(vKey string) error {
for k, v := range s.Tasks {
if v.VerifyKey == vKey {
s.Tasks = append(s.Tasks[:k], s.Tasks[k+1:]...)
s.StoreTasksToCsv()
return nil
}
}
return errors.New("不存在")
}
func (s *Csv) GetTask(vKey string) (v *ServerConfig, err error) {
for _, v = range s.Tasks {
if v.VerifyKey == vKey {
return
}
}
err = errors.New("未找到")
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() {
path := beego.AppPath + "/conf/hosts.csv"
records, err := s.openFile(path)
if err != nil {
log.Fatal("配置文件打开错误:", path)
}
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 {
s.Hosts = append(s.Hosts[:k], s.Hosts[k+1:]...)
s.StoreHostToCsv()
return nil
}
}
return errors.New("不存在")
}
func (s *Csv) NewHost(t *HostList) {
s.Hosts = append(s.Hosts, t)
s.StoreHostToCsv()
}
func (s *Csv) GetHostList(start, length int, vKey string) ([]*HostList, int) {
list := make([]*HostList, 0)
var cnt int
for _, v := range s.Hosts {
if v.Vkey == vKey {
cnt++
if start--; start < 0 {
if length--; length > 0 {
list = append(list, v)
}
}
}
}
return list, cnt
}

View File

@@ -41,8 +41,8 @@ func ProcessHost(c *utils.Conn, s *TunnelModeServer) error {
var (
isConn = true
link *utils.Conn
cnf *ServerConfig
host *HostList
client *utils.Client
host *utils.HostList
wg sync.WaitGroup
)
for {
@@ -52,48 +52,56 @@ func ProcessHost(c *utils.Conn, s *TunnelModeServer) error {
}
//首次获取conn
if isConn {
isConn = false
if host, cnf, err = GetKeyByHost(r.Host); err != nil {
if host, client, 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 {
client.Cnf.ClientId = host.ClientId
client.Cnf.CompressDecode, client.Cnf.CompressEncode = utils.GetCompressType(client.Cnf.Compress)
if err = s.auth(r, c, client.Cnf.U, client.Cnf.P); err != nil {
break
}
if link, err = s.GetTunnelAndWriteHost(utils.CONN_TCP, cnf, host.Target); err != nil {
if link, err = s.GetTunnelAndWriteHost(utils.CONN_TCP, client.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)
out, _ := utils.Relay(c.Conn, link.Conn, client.Cnf.CompressDecode, client.Cnf.Crypt, client.Cnf.Mux)
wg.Done()
s.FlowAddHost(host, 0, out)
}()
}
isConn = false
}
utils.ChangeHostAndHeader(r, host.HostChange, host.HeaderChange, c.Conn.RemoteAddr().String())
b, err := httputil.DumpRequest(r, true)
s.FlowAddHost(host, int64(len(b)), 0)
if err != nil {
break
}
if _, err := link.WriteTo(b, cnf.CompressEncode, cnf.Crypt); err != nil {
if _, err := link.WriteTo(b, client.Cnf.CompressEncode, client.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))
if client != nil && client.Cnf != nil && client.Cnf.Mux && link != nil {
link.WriteTo([]byte(utils.IO_EOF), client.Cnf.CompressEncode, client.Cnf.Crypt)
s.bridge.ReturnTunnel(link, client.Id)
} else if link != nil {
link.Close()
}
if isConn {
s.writeConnFail(c.Conn)
}
c.Close()
return nil
}

View File

@@ -11,35 +11,43 @@ import (
"sync"
)
type RunServer struct {
flag int //标志
ExportFlow int64 //出口流量
InletFlow int64 //入口流量
service interface{}
sync.Mutex
}
var (
Bridge *bridge.Tunnel
RunList map[string]interface{} //运行中的任务
CsvDb *Csv
RunList map[int]interface{} //运行中的任务
CsvDb = utils.GetCsvDb()
VerifyKey string
)
func init() {
RunList = make(map[string]interface{})
RunList = make(map[int]interface{})
}
//从csv文件中恢复任务
func InitFromCsv() {
for _, v := range CsvDb.Tasks {
if v.Start == 1 {
log.Println("启动模式:", v.Mode, "监听端口:", v.TcpPort, "客户端令牌:", v.VerifyKey)
log.Println("启动模式:", v.Mode, "监听端口:", v.TcpPort)
AddTask(v)
}
}
}
//start a new server
func StartNewServer(bridgePort int, cnf *ServerConfig) {
func StartNewServer(bridgePort int, cnf *utils.ServerConfig) {
Bridge = bridge.NewTunnel(bridgePort, RunList)
if err := Bridge.StartTunnel(); err != nil {
log.Fatalln("服务端开启失败", err)
}
if svr := NewMode(Bridge, cnf); svr != nil {
RunList[cnf.VerifyKey] = svr
RunList[cnf.Id] = svr
err := reflect.ValueOf(svr).MethodByName("Start").Call(nil)[0]
if err.Interface() != nil {
log.Println(err)
@@ -50,7 +58,8 @@ func StartNewServer(bridgePort int, cnf *ServerConfig) {
}
//new a server by mode name
func NewMode(Bridge *bridge.Tunnel, config *ServerConfig) interface{} {
func NewMode(Bridge *bridge.Tunnel, c *utils.ServerConfig) interface{} {
config := utils.DeepCopyConfig(c)
switch config.Mode {
case "tunnelServer":
return NewTunnelModeServer(ProcessTunnel, Bridge, config)
@@ -61,14 +70,12 @@ func NewMode(Bridge *bridge.Tunnel, config *ServerConfig) interface{} {
case "udpServer":
return NewUdpModeServer(Bridge, config)
case "webServer":
InitCsvDb()
InitFromCsv()
p, _ := beego.AppConfig.Int("hostPort")
t := &ServerConfig{
t := &utils.ServerConfig{
TcpPort: p,
Mode: "httpHostServer",
Target: "",
VerifyKey: "",
U: "",
P: "",
Compress: "",
@@ -87,15 +94,10 @@ func NewMode(Bridge *bridge.Tunnel, config *ServerConfig) interface{} {
}
//stop server
func StopServer(cFlag string) error {
if v, ok := RunList[cFlag]; ok {
func StopServer(id int) error {
if v, ok := RunList[id]; ok {
reflect.ValueOf(v).MethodByName("Close").Call(nil)
delete(RunList, cFlag)
if VerifyKey == "" { //多客户端模式关闭相关隧道
Bridge.DelClientSignal(cFlag)
Bridge.DelClientTunnel(cFlag)
}
if t, err := CsvDb.GetTask(cFlag); err != nil {
if t, err := CsvDb.GetTask(id); err != nil {
return err
} else {
t.Start = 0
@@ -107,15 +109,14 @@ func StopServer(cFlag string) error {
}
//add task
func AddTask(t *ServerConfig) error {
t.CompressDecode, t.CompressEncode = utils.GetCompressType(t.Compress)
func AddTask(t *utils.ServerConfig) error {
if svr := NewMode(Bridge, t); svr != nil {
RunList[t.VerifyKey] = svr
RunList[t.Id] = svr
go func() {
err := reflect.ValueOf(svr).MethodByName("Start").Call(nil)[0]
if err.Interface() != nil {
log.Println("客户端", t.VerifyKey, "启动失败,错误:", err)
delete(RunList, t.VerifyKey)
log.Println("客户端", t.Id, "启动失败,错误:", err)
delete(RunList, t.Id)
}
}()
} else {
@@ -125,8 +126,8 @@ func AddTask(t *ServerConfig) error {
}
//start task
func StartTask(vKey string) error {
if t, err := CsvDb.GetTask(vKey); err != nil {
func StartTask(id int) error {
if t, err := CsvDb.GetTask(id); err != nil {
return err
} else {
AddTask(t)
@@ -137,35 +138,20 @@ func StartTask(vKey string) error {
}
//delete task
func DelTask(vKey string) error {
if err := StopServer(vKey); err != nil {
func DelTask(id int) error {
if err := StopServer(id); err != nil {
return err
}
for _, v := range CsvDb.Hosts {
if v.Vkey == vKey {
CsvDb.DelHost(v.Host)
}
}
return CsvDb.DelTask(vKey)
}
//init csv from file
func InitCsvDb() *Csv {
var once sync.Once
once.Do(func() {
CsvDb = NewCsv(RunList)
CsvDb.Init()
})
return CsvDb
return CsvDb.DelTask(id)
}
//get key by host from x
func GetKeyByHost(host string) (h *HostList, t *ServerConfig, err error) {
func GetKeyByHost(host string) (h *utils.HostList, t *utils.Client, err error) {
for _, v := range CsvDb.Hosts {
s := strings.Split(host, ":")
if s[0] == v.Host {
h = v
t, err = CsvDb.GetTask(v.Vkey)
t, err = CsvDb.GetClient(v.ClientId)
return
}
}
@@ -174,22 +160,32 @@ func GetKeyByHost(host string) (h *HostList, t *ServerConfig, err error) {
}
//get task list by page num
func GetServerConfig(start, length int, typeVal string) ([]*ServerConfig, int) {
list := make([]*ServerConfig, 0)
func GetServerConfig(start, length int, typeVal string, clientId int) ([]*utils.ServerConfig, int) {
list := make([]*utils.ServerConfig, 0)
var cnt int
for _, v := range CsvDb.Tasks {
if v.Mode != typeVal {
if (typeVal != "" && v.Mode != typeVal) || (typeVal == "" && clientId != v.ClientId) {
continue
}
if v.UseClientCnf {
v = utils.DeepCopyConfig(v)
if c, err := CsvDb.GetClient(v.ClientId); err == nil {
v.Compress = c.Cnf.Compress
v.Mux = c.Cnf.Mux
v.Crypt = c.Cnf.Crypt
v.U = c.Cnf.U
v.P = c.Cnf.P
}
}
cnt++
if start--; start < 0 {
if length--; length > 0 {
if _, ok := RunList[v.VerifyKey]; ok {
if _, ok := RunList[v.Id]; ok {
v.IsRun = 1
} else {
v.IsRun = 0
}
if s, ok := Bridge.SignalList[getverifyval(v.VerifyKey)]; ok {
if s, ok := Bridge.SignalList[v.ClientId]; ok {
if s.Len() > 0 {
v.ClientStatus = 1
} else {
@@ -201,16 +197,91 @@ func GetServerConfig(start, length int, typeVal string) ([]*ServerConfig, int) {
list = append(list, v)
}
}
}
return list, cnt
}
//get verify value
//when mode is webServer and vKey is not none
func getverifyval(vkey string) string {
if VerifyKey != "" {
return utils.Md5(VerifyKey)
}
return utils.Md5(vkey)
//获取客户端列表
func GetClientList(start, length int) (list []*utils.Client, cnt int) {
list, cnt = CsvDb.GetClientList(start, length)
dealClientData(list)
return
}
func dealClientData(list []*utils.Client) {
for _, v := range list {
if _, ok := Bridge.SignalList[v.Id]; ok {
v.IsConnect = true
} else {
v.IsConnect = false
}
v.Flow.InletFlow = 0
v.Flow.ExportFlow = 0
for _, h := range CsvDb.Hosts {
if h.ClientId == v.Id {
v.Flow.InletFlow += h.Flow.InletFlow
v.Flow.ExportFlow += h.Flow.ExportFlow
}
}
for _, t := range CsvDb.Tasks {
if t.ClientId == v.Id {
v.Flow.InletFlow += t.Flow.InletFlow
v.Flow.ExportFlow += t.Flow.ExportFlow
}
}
}
return
}
//根据客户端id删除其所属的所有隧道和域名
func DelTunnelAndHostByClientId(clientId int) {
for _, v := range CsvDb.Tasks {
if v.ClientId == clientId {
DelTask(v.Id)
}
}
for _, v := range CsvDb.Hosts {
if v.ClientId == clientId {
CsvDb.DelHost(v.Host)
}
}
}
//关闭客户端连接
func DelClientConnect(clientId int) {
Bridge.DelClientTunnel(clientId)
Bridge.DelClientSignal(clientId)
}
func GetDashboardData() map[string]int {
data := make(map[string]int)
data["hostCount"] = len(CsvDb.Hosts)
data["clientCount"] = len(CsvDb.Clients)
list := CsvDb.Clients
dealClientData(list)
c := 0
var in, out int64
for _, v := range list {
if v.IsConnect {
c += 1
}
in += v.Flow.InletFlow
out += v.Flow.ExportFlow
}
data["clientOnlineCount"] = c
data["inletFlowCount"] = int(in)
data["exportFlowCount"] = int(out)
for _, v := range CsvDb.Tasks {
switch v.Mode {
case "tunnelServer":
data["tunnelServerCount"] += 1
case "socks5Server":
data["socks5ServerCount"] += 1
case "httpProxyServer":
data["httpProxyServerCount"] += 1
case "udpServer":
data["udpServerCount"] += 1
}
}
return data
}

View File

@@ -160,13 +160,14 @@ func (s *Sock5ModeServer) handleConnect(c net.Conn) {
proxyConn, err := s.doConnect(c, connectMethod)
defer func() {
if s.config.Mux && proxyConn != nil {
s.bridge.ReturnTunnel(proxyConn, getverifyval(s.config.VerifyKey))
s.bridge.ReturnTunnel(proxyConn, s.config.ClientId)
}
}()
if err != nil {
c.Close()
} else {
utils.ReplayWaitGroup(proxyConn.Conn, c, s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
out, in := utils.ReplayWaitGroup(proxyConn.Conn, c, s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
s.FlowAdd(in, out)
}
}
@@ -197,13 +198,14 @@ func (s *Sock5ModeServer) handleUDP(c net.Conn) {
proxyConn, err := s.doConnect(c, associateMethod)
defer func() {
if s.config.Mux && proxyConn != nil {
s.bridge.ReturnTunnel(proxyConn, getverifyval(s.config.VerifyKey))
s.bridge.ReturnTunnel(proxyConn, s.config.ClientId)
}
}()
if err != nil {
c.Close()
} else {
utils.ReplayWaitGroup(proxyConn.Conn, c, s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
out, in := utils.ReplayWaitGroup(proxyConn.Conn, c, s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
s.FlowAdd(in, out)
}
}
@@ -295,6 +297,7 @@ func (s *Sock5ModeServer) Start() error {
}
log.Fatal("accept error: ", err)
}
s.ResetConfig()
go s.handleConn(conn)
}
return nil
@@ -306,7 +309,7 @@ func (s *Sock5ModeServer) Close() error {
}
//new
func NewSock5ModeServer(bridge *bridge.Tunnel, cnf *ServerConfig) *Sock5ModeServer {
func NewSock5ModeServer(bridge *bridge.Tunnel, cnf *utils.ServerConfig) *Sock5ModeServer {
s := new(Sock5ModeServer)
s.bridge = bridge
s.config = cnf

View File

@@ -12,33 +12,15 @@ import (
"strings"
)
//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
errorContent []byte
process process
listener *net.TCPListener
}
//tcp|http|host
func NewTunnelModeServer(process process, bridge *bridge.Tunnel, cnf *ServerConfig) *TunnelModeServer {
func NewTunnelModeServer(process process, bridge *bridge.Tunnel, cnf *utils.ServerConfig) *TunnelModeServer {
s := new(TunnelModeServer)
s.bridge = bridge
s.process = process
@@ -49,6 +31,9 @@ func NewTunnelModeServer(process process, bridge *bridge.Tunnel, cnf *ServerConf
//开始
func (s *TunnelModeServer) Start() error {
var err error
if s.errorContent, err = utils.ReadAllFromFile(beego.AppPath + "/web/static/page/error.html"); err != nil {
s.errorContent = []byte("easyProxy 404")
}
s.listener, err = net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), s.config.TcpPort, ""})
if err != nil {
return err
@@ -62,6 +47,7 @@ func (s *TunnelModeServer) Start() error {
log.Println(err)
continue
}
s.ResetConfig()
go s.process(utils.NewConn(conn), s)
}
return nil
@@ -70,20 +56,25 @@ func (s *TunnelModeServer) Start() error {
//权限认证
func (s *TunnelModeServer) auth(r *http.Request, c *utils.Conn, u, p string) error {
if u != "" && p != "" && !utils.CheckAuth(r, u, p) {
c.Write([]byte(utils.Unauthorized_BYTES))
c.Write([]byte(utils.UnauthorizedBytes))
c.Close()
return errors.New("401 Unauthorized")
}
return nil
}
func (s *TunnelModeServer) writeConnFail(c net.Conn) {
c.Write([]byte(utils.ConnectionFailBytes))
c.Write(s.errorContent)
}
//与客户端建立通道
func (s *TunnelModeServer) dealClient(c *utils.Conn, cnf *ServerConfig, addr string, method string, rb []byte) error {
func (s *TunnelModeServer) dealClient(c *utils.Conn, cnf *utils.ServerConfig, addr string, method string, rb []byte) error {
var link *utils.Conn
var err error
defer func() {
if cnf.Mux && link != nil {
s.bridge.ReturnTunnel(link, getverifyval(cnf.VerifyKey))
s.bridge.ReturnTunnel(link, cnf.ClientId)
}
}()
if link, err = s.GetTunnelAndWriteHost(utils.CONN_TCP, cnf, addr); err != nil {
@@ -97,7 +88,8 @@ func (s *TunnelModeServer) dealClient(c *utils.Conn, cnf *ServerConfig, addr str
} else if rb != nil {
link.WriteTo(rb, cnf.CompressEncode, cnf.Crypt)
}
utils.ReplayWaitGroup(link.Conn, c.Conn, cnf.CompressEncode, cnf.CompressDecode, cnf.Crypt, cnf.Mux)
out, in := utils.ReplayWaitGroup(link.Conn, c.Conn, cnf.CompressEncode, cnf.CompressDecode, cnf.Crypt, cnf.Mux)
s.FlowAdd(in, out)
}
}
return nil
@@ -139,7 +131,7 @@ func (s *HostServer) Start() error {
return nil
}
func NewHostServer(cnf *ServerConfig) *HostServer {
func NewHostServer(cnf *utils.ServerConfig) *HostServer {
s := new(HostServer)
s.config = cnf
return s

View File

@@ -10,13 +10,12 @@ import (
)
type UdpModeServer struct {
bridge *bridge.Tunnel
server
listener *net.UDPConn
udpMap map[string]*utils.Conn
config *ServerConfig
}
func NewUdpModeServer(bridge *bridge.Tunnel, cnf *ServerConfig) *UdpModeServer {
func NewUdpModeServer(bridge *bridge.Tunnel, cnf *utils.ServerConfig) *UdpModeServer {
s := new(UdpModeServer)
s.bridge = bridge
s.udpMap = make(map[string]*utils.Conn)
@@ -40,6 +39,7 @@ func (s *UdpModeServer) Start() error {
}
continue
}
s.ResetConfig()
go s.process(addr, data[:n])
}
return nil
@@ -47,7 +47,7 @@ func (s *UdpModeServer) Start() error {
//TODO:效率问题有待解决
func (s *UdpModeServer) process(addr *net.UDPAddr, data []byte) {
conn, err := s.bridge.GetTunnel(getverifyval(s.config.VerifyKey), s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
conn, err := s.bridge.GetTunnel(s.config.ClientId, s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
if err != nil {
log.Println(err)
return
@@ -60,21 +60,22 @@ func (s *UdpModeServer) process(addr *net.UDPAddr, data []byte) {
defer func() {
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))
s.bridge.ReturnTunnel(conn, s.config.ClientId)
} else {
conn.Close()
}
}()
if flag == utils.CONN_SUCCESS {
conn.WriteTo(data, s.config.CompressEncode, s.config.Crypt)
buf := make([]byte, 1024)
//conn.conn.SetReadDeadline(time.Now().Add(time.Duration(time.Second * 3)))
n, err := conn.ReadFrom(buf, s.config.CompressDecode, s.config.Crypt)
in, _ := conn.WriteTo(data, s.config.CompressEncode, s.config.Crypt)
buf := utils.BufPoolUdp.Get().([]byte)
out, err := conn.ReadFrom(buf, s.config.CompressDecode, s.config.Crypt)
if err != nil || err == io.EOF {
log.Println("revieve error:", err)
return
}
s.listener.WriteToUDP(buf[:n], addr)
s.listener.WriteToUDP(buf[:out], addr)
s.FlowAdd(int64(in), int64(out))
utils.BufPoolUdp.Put(buf)
}
}
}