forked from yinqiwen/gsnova
-
Notifications
You must be signed in to change notification settings - Fork 0
/
proxy.go
136 lines (122 loc) · 3.01 KB
/
proxy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package proxy
import (
"encoding/json"
"fmt"
"io"
"log"
"reflect"
"strings"
"github.com/yinqiwen/gsnova/common/event"
"github.com/yinqiwen/gsnova/common/helper"
"github.com/yinqiwen/gsnova/common/logger"
"github.com/yinqiwen/gsnova/local"
"github.com/yinqiwen/gsnova/local/hosts"
)
var proxyHome string
var cnIPRange *IPRangeHolder
type InternalEventMonitor func(code int, desc string) error
type Feature struct {
MaxRequestBody int
}
type Proxy interface {
Init(conf ProxyChannelConfig) error
//Type() string
Config() *ProxyChannelConfig
Destory() error
Features() Feature
PrintStat(w io.Writer)
Serve(session *ProxySession, ev event.Event) error
}
func init() {
proxyHome = "."
}
var proxyTable = make(map[string]Proxy)
var proxyTypeTable map[string]reflect.Type = make(map[string]reflect.Type)
func RegisterProxyType(str string, p Proxy) error {
rt := reflect.TypeOf(p)
if rt.Kind() == reflect.Ptr {
rt = rt.Elem()
}
proxyTypeTable[str] = rt
//proxyTable[p.Name()] = p
return nil
}
func getProxyByName(name string) Proxy {
p, exist := proxyTable[name]
if exist {
return p
}
return nil
}
func Start(home string, monitor InternalEventMonitor) error {
clientConf := home + "/client.json"
hostsConf := home + "/hosts.json"
confdata, err := helper.ReadWithoutComment(clientConf, "//")
if nil != err {
//log.Println(err)
return err
}
err = json.Unmarshal(confdata, &GConf)
if nil != err {
fmt.Printf("Failed to unmarshal json:%s to config for reason:%v", string(confdata), err)
return err
}
iprangeFile := home + "/apnic_cn.txt"
cnIPRange, err = parseApnicIPFile(iprangeFile)
if nil != err {
fmt.Printf("Failed to parse iprange file:%s for reason:%v", iprangeFile, err)
return err
}
err = hosts.Init(hostsConf)
if nil != err {
log.Printf("Failed to init local hosts with reason:%v.", err)
}
event.SetDefaultSecretKey(GConf.Encrypt.Method, GConf.Encrypt.Key)
GConf.init()
for _, conf := range GConf.Channel {
conf.Type = strings.ToUpper(conf.Type)
if t, ok := proxyTypeTable[conf.Type]; !ok {
log.Printf("[ERROR]No registe proxy channel type for %s", conf.Type)
continue
} else {
v := reflect.New(t)
p := v.Interface().(Proxy)
if !conf.Enable {
continue
}
if 0 == conf.ConnsPerServer {
conf.ConnsPerServer = 1
}
err = p.Init(conf)
if nil != err {
log.Printf("Proxy channel(%s):%s init failed with reason:%v", conf.Type, conf.Name, err)
} else {
log.Printf("Proxy channel(%s):%s init success", conf.Type, conf.Name)
proxyTable[conf.Name] = p
}
}
}
proxyHome = home
logger.InitLogger(GConf.Log)
log.Printf("Starting GSnova %s.", local.Version)
go initDNS()
go startAdminServer()
startLocalServers()
return nil
}
func Stop() error {
stopLocalServers()
for name, p := range proxyTable {
err := p.Destory()
if nil != err {
log.Printf("Failed to destroy proxy:%s with error:%v", name, err)
} else {
log.Printf("Proxy:%s destroy success.", name)
}
}
hosts.Clear()
if nil != cnIPRange {
cnIPRange.Clear()
}
return nil
}