From 05ab653103f689ad0cca6f8d70fff980fc5c9519 Mon Sep 17 00:00:00 2001 From: Dreamacro <305009791@qq.com> Date: Wed, 20 Jun 2018 22:41:02 +0800 Subject: [PATCH] Add: config hub route --- constant/rule.go | 18 +++++++++++ hub/configs.go | 67 +++++++++++++++++++++++++++++++++++++++++ hub/server.go | 6 ++-- rules/domain_keyword.go | 4 +++ rules/domain_suffix.go | 4 +++ rules/final.go | 4 +++ rules/geoip.go | 4 +++ rules/ipcidr.go | 8 +++-- tunnel/tunnel.go | 4 +++ 9 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 hub/configs.go diff --git a/constant/rule.go b/constant/rule.go index 6a65febc6..0acdcc391 100644 --- a/constant/rule.go +++ b/constant/rule.go @@ -11,8 +11,26 @@ const ( type RuleType int +func (rt RuleType) String() string { + switch rt { + case DomainSuffix: + return "DomainSuffix" + case DomainKeyword: + return "DomainKeyword" + case GEOIP: + return "GEOIP" + case IPCIDR: + return "IPCIDR" + case FINAL: + return "FINAL" + default: + return "Unknow" + } +} + type Rule interface { RuleType() RuleType IsMatch(addr *Addr) bool Adapter() string + Payload() string } diff --git a/hub/configs.go b/hub/configs.go new file mode 100644 index 000000000..3cc46a320 --- /dev/null +++ b/hub/configs.go @@ -0,0 +1,67 @@ +package hub + +import ( + "net/http" + + "github.com/go-chi/chi" + "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 { + r := chi.NewRouter() + r.Get("/", getConfig) + r.Put("/", updateConfig) + return r +} + +func getConfig(w http.ResponseWriter, r *http.Request) { + rulesCfg, proxysCfg := tun.Config() + + var ( + rules []Rule + proxys []Proxy + ) + + 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) { + err := tun.UpdateConfig() + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + render.JSON(w, r, Error{ + Error: err.Error(), + }) + return + } + w.WriteHeader(http.StatusNoContent) +} diff --git a/hub/server.go b/hub/server.go index 1caad82af..cea853b80 100644 --- a/hub/server.go +++ b/hub/server.go @@ -35,6 +35,7 @@ func NewHub(addr string) { r.Get("/traffic", traffic) r.Get("/logs", getLogs) + r.Mount("/configs", configRouter()) err := http.ListenAndServe(addr, r) if err != nil { @@ -43,7 +44,7 @@ func NewHub(addr string) { } func traffic(w http.ResponseWriter, r *http.Request) { - render.Status(r, http.StatusOK) + w.WriteHeader(http.StatusOK) tick := time.NewTicker(time.Second) t := tun.Traffic() @@ -64,10 +65,11 @@ func getLogs(w http.ResponseWriter, r *http.Request) { sub, err := src.Subscribe() defer src.UnSubscribe(sub) if err != nil { - render.Status(r, http.StatusInternalServerError) + w.WriteHeader(http.StatusInternalServerError) render.JSON(w, r, Error{ Error: err.Error(), }) + return } render.Status(r, http.StatusOK) for elm := range sub { diff --git a/rules/domain_keyword.go b/rules/domain_keyword.go index a235dc7aa..19ca2e224 100644 --- a/rules/domain_keyword.go +++ b/rules/domain_keyword.go @@ -27,6 +27,10 @@ func (dk *DomainKeyword) Adapter() string { return dk.adapter } +func (dk *DomainKeyword) Payload() string { + return dk.keyword +} + func NewDomainKeyword(keyword string, adapter string) *DomainKeyword { return &DomainKeyword{ keyword: keyword, diff --git a/rules/domain_suffix.go b/rules/domain_suffix.go index 42f4fc8be..d6dd9f970 100644 --- a/rules/domain_suffix.go +++ b/rules/domain_suffix.go @@ -27,6 +27,10 @@ func (ds *DomainSuffix) Adapter() string { return ds.adapter } +func (ds *DomainSuffix) Payload() string { + return ds.suffix +} + func NewDomainSuffix(suffix string, adapter string) *DomainSuffix { return &DomainSuffix{ suffix: suffix, diff --git a/rules/final.go b/rules/final.go index c82768c4f..f07fbab16 100644 --- a/rules/final.go +++ b/rules/final.go @@ -20,6 +20,10 @@ func (f *Final) Adapter() string { return f.adapter } +func (f *Final) Payload() string { + return "" +} + func NewFinal(adapter string) *Final { return &Final{ adapter: adapter, diff --git a/rules/geoip.go b/rules/geoip.go index 9d981b9fd..9ee8691e0 100644 --- a/rules/geoip.go +++ b/rules/geoip.go @@ -38,6 +38,10 @@ func (g *GEOIP) Adapter() string { return g.adapter } +func (g *GEOIP) Payload() string { + return g.country +} + func NewGEOIP(country string, adapter string) *GEOIP { return &GEOIP{ country: country, diff --git a/rules/ipcidr.go b/rules/ipcidr.go index 57d08f502..baf447579 100644 --- a/rules/ipcidr.go +++ b/rules/ipcidr.go @@ -23,8 +23,12 @@ func (i *IPCIDR) IsMatch(addr *C.Addr) bool { return i.ipnet.Contains(*addr.IP) } -func (g *IPCIDR) Adapter() string { - return g.adapter +func (i *IPCIDR) Adapter() string { + return i.adapter +} + +func (i *IPCIDR) Payload() string { + return i.ipnet.String() } func NewIPCIDR(s string, adapter string) *IPCIDR { diff --git a/tunnel/tunnel.go b/tunnel/tunnel.go index 8b7b696ea..e02a9b5db 100644 --- a/tunnel/tunnel.go +++ b/tunnel/tunnel.go @@ -38,6 +38,10 @@ func (t *Tunnel) Traffic() *C.Traffic { return t.traffic } +func (t *Tunnel) Config() ([]C.Rule, map[string]C.Proxy) { + return t.rules, t.proxys +} + func (t *Tunnel) Log() *observable.Observable { return t.observable }