Add: selector and proxys & rules router
This commit is contained in:
parent
39b45513af
commit
0eef9bbf5d
12 changed files with 390 additions and 47 deletions
|
@ -35,6 +35,10 @@ func (d *Direct) Name() string {
|
||||||
return "Direct"
|
return "Direct"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Direct) Type() C.AdapterType {
|
||||||
|
return C.Direct
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Direct) Generator(addr *C.Addr) (adapter C.ProxyAdapter, err error) {
|
func (d *Direct) Generator(addr *C.Addr) (adapter C.ProxyAdapter, err error) {
|
||||||
c, err := net.Dial("tcp", net.JoinHostPort(addr.String(), addr.Port))
|
c, err := net.Dial("tcp", net.JoinHostPort(addr.String(), addr.Port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -31,6 +31,10 @@ func (r *Reject) Name() string {
|
||||||
return "Reject"
|
return "Reject"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Reject) Type() C.AdapterType {
|
||||||
|
return C.Reject
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Reject) Generator(addr *C.Addr) (adapter C.ProxyAdapter, err error) {
|
func (r *Reject) Generator(addr *C.Addr) (adapter C.ProxyAdapter, err error) {
|
||||||
return &RejectAdapter{}, nil
|
return &RejectAdapter{}, nil
|
||||||
}
|
}
|
||||||
|
|
65
adapters/selector.go
Normal file
65
adapters/selector.go
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
package adapters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
C "github.com/Dreamacro/clash/constant"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Selector struct {
|
||||||
|
name string
|
||||||
|
selected C.Proxy
|
||||||
|
proxys map[string]C.Proxy
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Selector) Name() string {
|
||||||
|
return s.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Selector) Type() C.AdapterType {
|
||||||
|
return C.Selector
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Selector) Generator(addr *C.Addr) (adapter C.ProxyAdapter, err error) {
|
||||||
|
return s.selected.Generator(addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Selector) Now() string {
|
||||||
|
return s.selected.Name()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Selector) All() []string {
|
||||||
|
var all []string
|
||||||
|
for k, _ := range s.proxys {
|
||||||
|
all = append(all, k)
|
||||||
|
}
|
||||||
|
return all
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Selector) Set(name string) error {
|
||||||
|
proxy, exist := s.proxys[name]
|
||||||
|
if !exist {
|
||||||
|
return errors.New("Proxy does not exist")
|
||||||
|
}
|
||||||
|
s.selected = proxy
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSelector(name string, proxys map[string]C.Proxy) (*Selector, error) {
|
||||||
|
if len(proxys) == 0 {
|
||||||
|
return nil, errors.New("Provide at least one proxy")
|
||||||
|
}
|
||||||
|
|
||||||
|
mapping := make(map[string]C.Proxy)
|
||||||
|
var init string
|
||||||
|
for k, v := range proxys {
|
||||||
|
mapping[k] = v
|
||||||
|
init = k
|
||||||
|
}
|
||||||
|
s := &Selector{
|
||||||
|
name: name,
|
||||||
|
proxys: mapping,
|
||||||
|
selected: proxys[init],
|
||||||
|
}
|
||||||
|
return s, nil
|
||||||
|
}
|
|
@ -44,6 +44,10 @@ func (ss *ShadowSocks) Name() string {
|
||||||
return ss.name
|
return ss.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ss *ShadowSocks) Type() C.AdapterType {
|
||||||
|
return C.Shadowsocks
|
||||||
|
}
|
||||||
|
|
||||||
func (ss *ShadowSocks) Generator(addr *C.Addr) (adapter C.ProxyAdapter, err error) {
|
func (ss *ShadowSocks) Generator(addr *C.Addr) (adapter C.ProxyAdapter, err error) {
|
||||||
c, err := net.Dial("tcp", ss.server)
|
c, err := net.Dial("tcp", ss.server)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -26,6 +26,14 @@ func (u *URLTest) Name() string {
|
||||||
return u.name
|
return u.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *URLTest) Type() C.AdapterType {
|
||||||
|
return C.URLTest
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *URLTest) Now() string {
|
||||||
|
return u.fast.Name()
|
||||||
|
}
|
||||||
|
|
||||||
func (u *URLTest) Generator(addr *C.Addr) (adapter C.ProxyAdapter, err error) {
|
func (u *URLTest) Generator(addr *C.Addr) (adapter C.ProxyAdapter, err error) {
|
||||||
return u.fast.Generator(addr)
|
return u.fast.Generator(addr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,15 @@ import (
|
||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Adapter Type
|
||||||
|
const (
|
||||||
|
Direct AdapterType = iota
|
||||||
|
Reject
|
||||||
|
Selector
|
||||||
|
Shadowsocks
|
||||||
|
URLTest
|
||||||
|
)
|
||||||
|
|
||||||
type ProxyAdapter interface {
|
type ProxyAdapter interface {
|
||||||
ReadWriter() io.ReadWriter
|
ReadWriter() io.ReadWriter
|
||||||
Conn() net.Conn
|
Conn() net.Conn
|
||||||
|
@ -19,5 +28,26 @@ type ServerAdapter interface {
|
||||||
|
|
||||||
type Proxy interface {
|
type Proxy interface {
|
||||||
Name() string
|
Name() string
|
||||||
|
Type() AdapterType
|
||||||
Generator(addr *Addr) (ProxyAdapter, error)
|
Generator(addr *Addr) (ProxyAdapter, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AdapterType is enum of adapter type
|
||||||
|
type AdapterType int
|
||||||
|
|
||||||
|
func (at AdapterType) String() string {
|
||||||
|
switch at {
|
||||||
|
case Direct:
|
||||||
|
return "Direct"
|
||||||
|
case Reject:
|
||||||
|
return "Reject"
|
||||||
|
case Selector:
|
||||||
|
return "Selector"
|
||||||
|
case Shadowsocks:
|
||||||
|
return "Shadowsocks"
|
||||||
|
case URLTest:
|
||||||
|
return "URLTest"
|
||||||
|
default:
|
||||||
|
return "Unknow"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,65 +3,47 @@ package hub
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/Dreamacro/clash/tunnel"
|
||||||
|
|
||||||
"github.com/go-chi/chi"
|
"github.com/go-chi/chi"
|
||||||
"github.com/go-chi/render"
|
"github.com/go-chi/render"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Configs struct {
|
|
||||||
Proxys []Proxy `json:"proxys"`
|
|
||||||
Rules []Rule `json:"rules"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Proxy struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Rule struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Payload string `json:"type"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func configRouter() http.Handler {
|
func configRouter() http.Handler {
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
r.Get("/", getConfig)
|
|
||||||
r.Put("/", updateConfig)
|
r.Put("/", updateConfig)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func getConfig(w http.ResponseWriter, r *http.Request) {
|
type General struct {
|
||||||
rulesCfg, proxysCfg := tun.Config()
|
Mode string `json:mode`
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var modeMapping = map[string]tunnel.Mode{
|
||||||
rules []Rule
|
"global": tunnel.Global,
|
||||||
proxys []Proxy
|
"rule": tunnel.Rule,
|
||||||
)
|
"direct": tunnel.Direct,
|
||||||
|
|
||||||
for _, rule := range rulesCfg {
|
|
||||||
rules = append(rules, Rule{
|
|
||||||
Name: rule.RuleType().String(),
|
|
||||||
Payload: rule.Payload(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, proxy := range proxysCfg {
|
|
||||||
proxys = append(proxys, Proxy{Name: proxy.Name()})
|
|
||||||
}
|
|
||||||
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
render.JSON(w, r, Configs{
|
|
||||||
Rules: rules,
|
|
||||||
Proxys: proxys,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateConfig(w http.ResponseWriter, r *http.Request) {
|
func updateConfig(w http.ResponseWriter, r *http.Request) {
|
||||||
err := tun.UpdateConfig()
|
general := &General{}
|
||||||
|
err := render.DecodeJSON(r.Body, general)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
render.JSON(w, r, Error{
|
render.JSON(w, r, Error{
|
||||||
Error: err.Error(),
|
Error: "Format error",
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mode, ok := modeMapping[general.Mode]
|
||||||
|
if !ok {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
render.JSON(w, r, Error{
|
||||||
|
Error: "Mode error",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tun.SetMode(mode)
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
129
hub/proxys.go
Normal file
129
hub/proxys.go
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
package hub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
A "github.com/Dreamacro/clash/adapters"
|
||||||
|
C "github.com/Dreamacro/clash/constant"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi"
|
||||||
|
"github.com/go-chi/render"
|
||||||
|
)
|
||||||
|
|
||||||
|
func proxyRouter() http.Handler {
|
||||||
|
r := chi.NewRouter()
|
||||||
|
r.Get("/", getProxys)
|
||||||
|
r.Get("/{name}", getProxy)
|
||||||
|
r.Put("/{name}", updateProxy)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
type SampleProxy struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Selector struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Now string `json:"now"`
|
||||||
|
All []string `json:"all"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type URLTest struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Now string `json:"now"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func transformProxy(proxy C.Proxy) interface{} {
|
||||||
|
t := proxy.Type()
|
||||||
|
switch t {
|
||||||
|
case C.Selector:
|
||||||
|
selector := proxy.(*A.Selector)
|
||||||
|
return Selector{
|
||||||
|
Type: t.String(),
|
||||||
|
Now: selector.Now(),
|
||||||
|
All: selector.All(),
|
||||||
|
}
|
||||||
|
case C.URLTest:
|
||||||
|
return URLTest{
|
||||||
|
Type: t.String(),
|
||||||
|
Now: proxy.(*A.URLTest).Now(),
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return SampleProxy{
|
||||||
|
Type: proxy.Type().String(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetProxysResponse struct {
|
||||||
|
Proxys map[string]interface{} `json:"proxys"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProxys(w http.ResponseWriter, r *http.Request) {
|
||||||
|
_, rawProxys := tun.Config()
|
||||||
|
proxys := make(map[string]interface{})
|
||||||
|
for name, proxy := range rawProxys {
|
||||||
|
proxys[name] = transformProxy(proxy)
|
||||||
|
}
|
||||||
|
render.JSON(w, r, GetProxysResponse{Proxys: proxys})
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProxy(w http.ResponseWriter, r *http.Request) {
|
||||||
|
name := chi.URLParam(r, "name")
|
||||||
|
_, proxys := tun.Config()
|
||||||
|
proxy, exist := proxys[name]
|
||||||
|
if !exist {
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
render.JSON(w, r, Error{
|
||||||
|
Error: "Proxy not found",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
render.JSON(w, r, transformProxy(proxy))
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateProxyRequest struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateProxy(w http.ResponseWriter, r *http.Request) {
|
||||||
|
req := UpdateProxyRequest{}
|
||||||
|
if err := render.DecodeJSON(r.Body, &req); err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
render.JSON(w, r, Error{
|
||||||
|
Error: "Format error",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
name := chi.URLParam(r, "name")
|
||||||
|
_, proxys := tun.Config()
|
||||||
|
proxy, exist := proxys[name]
|
||||||
|
if !exist {
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
render.JSON(w, r, Error{
|
||||||
|
Error: "Proxy not found",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
selector, ok := proxy.(*A.Selector)
|
||||||
|
if !ok {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
render.JSON(w, r, Error{
|
||||||
|
Error: "Proxy can't update",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := selector.Set(req.Name); err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
render.JSON(w, r, Error{
|
||||||
|
Error: fmt.Sprintf("Selector update error: %s", err.Error()),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
}
|
53
hub/rules.go
Normal file
53
hub/rules.go
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
package hub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi"
|
||||||
|
"github.com/go-chi/render"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ruleRouter() http.Handler {
|
||||||
|
r := chi.NewRouter()
|
||||||
|
r.Get("/", getRules)
|
||||||
|
r.Put("/", updateRules)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
type Rule struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Payload string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetRulesResponse struct {
|
||||||
|
Rules []Rule `json:"rules"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRules(w http.ResponseWriter, r *http.Request) {
|
||||||
|
rulesCfg, _ := tun.Config()
|
||||||
|
|
||||||
|
var rules []Rule
|
||||||
|
for _, rule := range rulesCfg {
|
||||||
|
rules = append(rules, Rule{
|
||||||
|
Name: rule.RuleType().String(),
|
||||||
|
Payload: rule.Payload(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
render.JSON(w, r, GetRulesResponse{
|
||||||
|
Rules: rules,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateRules(w http.ResponseWriter, r *http.Request) {
|
||||||
|
err := tun.UpdateConfig()
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
render.JSON(w, r, Error{
|
||||||
|
Error: err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
}
|
|
@ -31,6 +31,8 @@ func NewHub(addr string) {
|
||||||
r.Get("/traffic", traffic)
|
r.Get("/traffic", traffic)
|
||||||
r.Get("/logs", getLogs)
|
r.Get("/logs", getLogs)
|
||||||
r.Mount("/configs", configRouter())
|
r.Mount("/configs", configRouter())
|
||||||
|
r.Mount("/proxys", proxyRouter())
|
||||||
|
r.Mount("/rules", ruleRouter())
|
||||||
|
|
||||||
err := http.ListenAndServe(addr, r)
|
err := http.ListenAndServe(addr, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
22
tunnel/mode.go
Normal file
22
tunnel/mode.go
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package tunnel
|
||||||
|
|
||||||
|
type Mode int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Global Mode = iota
|
||||||
|
Rule
|
||||||
|
Direct
|
||||||
|
)
|
||||||
|
|
||||||
|
func (m Mode) String() string {
|
||||||
|
switch m {
|
||||||
|
case Global:
|
||||||
|
return "Global"
|
||||||
|
case Rule:
|
||||||
|
return "Rule"
|
||||||
|
case Direct:
|
||||||
|
return "Direct"
|
||||||
|
default:
|
||||||
|
return "Unknow"
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,6 +28,8 @@ type Tunnel struct {
|
||||||
logCh chan interface{}
|
logCh chan interface{}
|
||||||
configLock *sync.RWMutex
|
configLock *sync.RWMutex
|
||||||
traffic *C.Traffic
|
traffic *C.Traffic
|
||||||
|
mode Mode
|
||||||
|
selector *adapters.Selector
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tunnel) Add(req C.ServerAdapter) {
|
func (t *Tunnel) Add(req C.ServerAdapter) {
|
||||||
|
@ -46,6 +48,10 @@ func (t *Tunnel) Log() *observable.Observable {
|
||||||
return t.observable
|
return t.observable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Tunnel) SetMode(mode Mode) {
|
||||||
|
t.mode = mode
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Tunnel) UpdateConfig() (err error) {
|
func (t *Tunnel) UpdateConfig() (err error) {
|
||||||
cfg, err := C.GetConfig()
|
cfg, err := C.GetConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -62,11 +68,10 @@ func (t *Tunnel) UpdateConfig() (err error) {
|
||||||
|
|
||||||
// parse proxy
|
// parse proxy
|
||||||
for _, key := range proxysConfig.Keys() {
|
for _, key := range proxysConfig.Keys() {
|
||||||
proxy := strings.Split(key.Value(), ",")
|
proxy := key.Strings(",")
|
||||||
if len(proxy) == 0 {
|
if len(proxy) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
proxy = trimArr(proxy)
|
|
||||||
switch proxy[0] {
|
switch proxy[0] {
|
||||||
// ss, server, port, cipter, password
|
// ss, server, port, cipter, password
|
||||||
case "ss":
|
case "ss":
|
||||||
|
@ -106,12 +111,12 @@ func (t *Tunnel) UpdateConfig() (err error) {
|
||||||
// parse proxy groups
|
// parse proxy groups
|
||||||
for _, key := range groupsConfig.Keys() {
|
for _, key := range groupsConfig.Keys() {
|
||||||
rule := strings.Split(key.Value(), ",")
|
rule := strings.Split(key.Value(), ",")
|
||||||
if len(rule) < 4 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
rule = trimArr(rule)
|
rule = trimArr(rule)
|
||||||
switch rule[0] {
|
switch rule[0] {
|
||||||
case "url-test":
|
case "url-test":
|
||||||
|
if len(rule) < 4 {
|
||||||
|
return fmt.Errorf("URLTest need more than 4 param")
|
||||||
|
}
|
||||||
proxyNames := rule[1 : len(rule)-2]
|
proxyNames := rule[1 : len(rule)-2]
|
||||||
delay, _ := strconv.Atoi(rule[len(rule)-1])
|
delay, _ := strconv.Atoi(rule[len(rule)-1])
|
||||||
url := rule[len(rule)-2]
|
url := rule[len(rule)-2]
|
||||||
|
@ -127,6 +132,24 @@ func (t *Tunnel) UpdateConfig() (err error) {
|
||||||
return fmt.Errorf("Config error: %s", err.Error())
|
return fmt.Errorf("Config error: %s", err.Error())
|
||||||
}
|
}
|
||||||
proxys[key.Name()] = adapter
|
proxys[key.Name()] = adapter
|
||||||
|
case "select":
|
||||||
|
if len(rule) < 3 {
|
||||||
|
return fmt.Errorf("Selector need more than 3 param")
|
||||||
|
}
|
||||||
|
proxyNames := rule[1:]
|
||||||
|
selectProxy := make(map[string]C.Proxy)
|
||||||
|
for _, name := range proxyNames {
|
||||||
|
proxy, exist := proxys[name]
|
||||||
|
if !exist {
|
||||||
|
return fmt.Errorf("Proxy %s not exist", name)
|
||||||
|
}
|
||||||
|
selectProxy[name] = proxy
|
||||||
|
}
|
||||||
|
selector, err := adapters.NewSelector(key.Name(), selectProxy)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Selector create error: %s", err.Error())
|
||||||
|
}
|
||||||
|
proxys[key.Name()] = selector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,8 +168,14 @@ func (t *Tunnel) UpdateConfig() (err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s, err := adapters.NewSelector("Proxy", proxys)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
t.proxys = proxys
|
t.proxys = proxys
|
||||||
t.rules = rules
|
t.rules = rules
|
||||||
|
t.selector = s
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -163,7 +192,17 @@ func (t *Tunnel) process() {
|
||||||
func (t *Tunnel) handleConn(localConn C.ServerAdapter) {
|
func (t *Tunnel) handleConn(localConn C.ServerAdapter) {
|
||||||
defer localConn.Close()
|
defer localConn.Close()
|
||||||
addr := localConn.Addr()
|
addr := localConn.Addr()
|
||||||
proxy := t.match(addr)
|
|
||||||
|
var proxy C.Proxy
|
||||||
|
switch t.mode {
|
||||||
|
case Direct:
|
||||||
|
proxy = t.proxys["DIRECT"]
|
||||||
|
case Global:
|
||||||
|
proxy = t.selector
|
||||||
|
// Rule
|
||||||
|
default:
|
||||||
|
proxy = t.match(addr)
|
||||||
|
}
|
||||||
remoConn, err := proxy.Generator(addr)
|
remoConn, err := proxy.Generator(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.logCh <- newLog(WARNING, "Proxy connect error: %s", err.Error())
|
t.logCh <- newLog(WARNING, "Proxy connect error: %s", err.Error())
|
||||||
|
@ -201,6 +240,7 @@ func newTunnel() *Tunnel {
|
||||||
logCh: logCh,
|
logCh: logCh,
|
||||||
configLock: &sync.RWMutex{},
|
configLock: &sync.RWMutex{},
|
||||||
traffic: C.NewTraffic(time.Second),
|
traffic: C.NewTraffic(time.Second),
|
||||||
|
mode: Rule,
|
||||||
}
|
}
|
||||||
go tunnel.process()
|
go tunnel.process()
|
||||||
go tunnel.subscribeLogs()
|
go tunnel.subscribeLogs()
|
||||||
|
|
Loading…
Reference in a new issue