Update: add config route
This commit is contained in:
parent
0eef9bbf5d
commit
3cacfb8a7f
12 changed files with 319 additions and 77 deletions
|
@ -16,8 +16,8 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Name = "clash"
|
Name = "clash"
|
||||||
DefalutHTTPPort = "7890"
|
DefalutHTTPPort = 7890
|
||||||
DefalutSOCKSPort = "7891"
|
DefalutSOCKSPort = 7891
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -26,6 +26,13 @@ var (
|
||||||
MMDBPath string
|
MMDBPath string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type General struct {
|
||||||
|
Mode *string `json:"mode,omitempty"`
|
||||||
|
AllowLan *bool `json:"allow-lan,omitempty"`
|
||||||
|
Port *int `json:"port,omitempty"`
|
||||||
|
SocksPort *int `json:"socks-port,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
currentUser, err := user.Current()
|
currentUser, err := user.Current()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
7
constant/proxy.go
Normal file
7
constant/proxy.go
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package constant
|
||||||
|
|
||||||
|
// ProxySignal is used to handle graceful shutdown of proxy
|
||||||
|
type ProxySignal struct {
|
||||||
|
Done chan<- struct{}
|
||||||
|
Closed <-chan struct{}
|
||||||
|
}
|
31
hub/common.go
Normal file
31
hub/common.go
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package hub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Dreamacro/clash/proxy"
|
||||||
|
T "github.com/Dreamacro/clash/tunnel"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
tunnel = T.GetInstance()
|
||||||
|
listener = proxy.Instance()
|
||||||
|
)
|
||||||
|
|
||||||
|
type Error struct {
|
||||||
|
Error string `json:"error"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Errors struct {
|
||||||
|
Errors map[string]string `json:"errors"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatErrors(errorsMap map[string]error) (bool, Errors) {
|
||||||
|
errors := make(map[string]string)
|
||||||
|
hasError := false
|
||||||
|
for key, err := range errorsMap {
|
||||||
|
if err != nil {
|
||||||
|
errors[key] = err.Error()
|
||||||
|
hasError = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hasError, Errors{Errors: errors}
|
||||||
|
}
|
|
@ -1,9 +1,12 @@
|
||||||
package hub
|
package hub
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/tunnel"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
|
"github.com/Dreamacro/clash/proxy"
|
||||||
|
T "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"
|
||||||
|
@ -11,22 +14,26 @@ import (
|
||||||
|
|
||||||
func configRouter() http.Handler {
|
func configRouter() http.Handler {
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
r.Put("/", updateConfig)
|
r.Get("/", getConfigs)
|
||||||
|
r.Put("/", updateConfigs)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
type General struct {
|
var modeMapping = map[string]T.Mode{
|
||||||
Mode string `json:mode`
|
"Global": T.Global,
|
||||||
|
"Rule": T.Rule,
|
||||||
|
"Direct": T.Direct,
|
||||||
}
|
}
|
||||||
|
|
||||||
var modeMapping = map[string]tunnel.Mode{
|
func getConfigs(w http.ResponseWriter, r *http.Request) {
|
||||||
"global": tunnel.Global,
|
info := listener.Info()
|
||||||
"rule": tunnel.Rule,
|
mode := tunnel.GetMode().String()
|
||||||
"direct": tunnel.Direct,
|
info.Mode = &mode
|
||||||
|
render.JSON(w, r, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateConfig(w http.ResponseWriter, r *http.Request) {
|
func updateConfigs(w http.ResponseWriter, r *http.Request) {
|
||||||
general := &General{}
|
general := &C.General{}
|
||||||
err := render.DecodeJSON(r.Body, general)
|
err := render.DecodeJSON(r.Body, general)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
@ -36,14 +43,32 @@ func updateConfig(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mode, ok := modeMapping[general.Mode]
|
// update errors
|
||||||
if !ok {
|
var proxyErr, modeErr error
|
||||||
|
|
||||||
|
// update proxy
|
||||||
|
listener := proxy.Instance()
|
||||||
|
proxyErr = listener.Update(general.AllowLan, general.Port, general.SocksPort)
|
||||||
|
|
||||||
|
// update mode
|
||||||
|
if general.Mode != nil {
|
||||||
|
mode, ok := modeMapping[*general.Mode]
|
||||||
|
if !ok {
|
||||||
|
modeErr = fmt.Errorf("Mode error")
|
||||||
|
} else {
|
||||||
|
tunnel.SetMode(mode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hasError, errors := formatErrors(map[string]error{
|
||||||
|
"proxy": proxyErr,
|
||||||
|
"mode": modeErr,
|
||||||
|
})
|
||||||
|
|
||||||
|
if hasError {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
render.JSON(w, r, Error{
|
render.JSON(w, r, errors)
|
||||||
Error: "Mode error",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tun.SetMode(mode)
|
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ type GetProxysResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getProxys(w http.ResponseWriter, r *http.Request) {
|
func getProxys(w http.ResponseWriter, r *http.Request) {
|
||||||
_, rawProxys := tun.Config()
|
_, rawProxys := tunnel.Config()
|
||||||
proxys := make(map[string]interface{})
|
proxys := make(map[string]interface{})
|
||||||
for name, proxy := range rawProxys {
|
for name, proxy := range rawProxys {
|
||||||
proxys[name] = transformProxy(proxy)
|
proxys[name] = transformProxy(proxy)
|
||||||
|
@ -71,7 +71,7 @@ func getProxys(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
func getProxy(w http.ResponseWriter, r *http.Request) {
|
func getProxy(w http.ResponseWriter, r *http.Request) {
|
||||||
name := chi.URLParam(r, "name")
|
name := chi.URLParam(r, "name")
|
||||||
_, proxys := tun.Config()
|
_, proxys := tunnel.Config()
|
||||||
proxy, exist := proxys[name]
|
proxy, exist := proxys[name]
|
||||||
if !exist {
|
if !exist {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
@ -98,7 +98,7 @@ func updateProxy(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
name := chi.URLParam(r, "name")
|
name := chi.URLParam(r, "name")
|
||||||
_, proxys := tun.Config()
|
_, proxys := tunnel.Config()
|
||||||
proxy, exist := proxys[name]
|
proxy, exist := proxys[name]
|
||||||
if !exist {
|
if !exist {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
|
|
@ -24,7 +24,7 @@ type GetRulesResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRules(w http.ResponseWriter, r *http.Request) {
|
func getRules(w http.ResponseWriter, r *http.Request) {
|
||||||
rulesCfg, _ := tun.Config()
|
rulesCfg, _ := tunnel.Config()
|
||||||
|
|
||||||
var rules []Rule
|
var rules []Rule
|
||||||
for _, rule := range rulesCfg {
|
for _, rule := range rulesCfg {
|
||||||
|
@ -41,7 +41,7 @@ func getRules(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateRules(w http.ResponseWriter, r *http.Request) {
|
func updateRules(w http.ResponseWriter, r *http.Request) {
|
||||||
err := tun.UpdateConfig()
|
err := tunnel.UpdateConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
render.JSON(w, r, Error{
|
render.JSON(w, r, Error{
|
||||||
|
|
|
@ -5,26 +5,18 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/tunnel"
|
T "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"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
tun = tunnel.GetInstance()
|
|
||||||
)
|
|
||||||
|
|
||||||
type Traffic struct {
|
type Traffic struct {
|
||||||
Up int64 `json:"up"`
|
Up int64 `json:"up"`
|
||||||
Down int64 `json:"down"`
|
Down int64 `json:"down"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Error struct {
|
|
||||||
Error string `json:"error"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewHub(addr string) {
|
func NewHub(addr string) {
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
|
|
||||||
|
@ -44,7 +36,7 @@ func traffic(w http.ResponseWriter, r *http.Request) {
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
||||||
tick := time.NewTicker(time.Second)
|
tick := time.NewTicker(time.Second)
|
||||||
t := tun.Traffic()
|
t := tunnel.Traffic()
|
||||||
for range tick.C {
|
for range tick.C {
|
||||||
up, down := t.Now()
|
up, down := t.Now()
|
||||||
if err := json.NewEncoder(w).Encode(Traffic{
|
if err := json.NewEncoder(w).Encode(Traffic{
|
||||||
|
@ -73,11 +65,11 @@ func getLogs(w http.ResponseWriter, r *http.Request) {
|
||||||
req.Level = "info"
|
req.Level = "info"
|
||||||
}
|
}
|
||||||
|
|
||||||
mapping := map[string]tunnel.LogLevel{
|
mapping := map[string]T.LogLevel{
|
||||||
"info": tunnel.INFO,
|
"info": T.INFO,
|
||||||
"debug": tunnel.DEBUG,
|
"debug": T.DEBUG,
|
||||||
"error": tunnel.ERROR,
|
"error": T.ERROR,
|
||||||
"warning": tunnel.WARNING,
|
"warning": T.WARNING,
|
||||||
}
|
}
|
||||||
|
|
||||||
level, ok := mapping[req.Level]
|
level, ok := mapping[req.Level]
|
||||||
|
@ -89,7 +81,7 @@ func getLogs(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
src := tun.Log()
|
src := tunnel.Log()
|
||||||
sub, err := src.Subscribe()
|
sub, err := src.Subscribe()
|
||||||
defer src.UnSubscribe(sub)
|
defer src.UnSubscribe(sub)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -101,7 +93,7 @@ func getLogs(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
render.Status(r, http.StatusOK)
|
render.Status(r, http.StatusOK)
|
||||||
for elm := range sub {
|
for elm := range sub {
|
||||||
log := elm.(tunnel.Log)
|
log := elm.(T.Log)
|
||||||
if log.LogLevel > level {
|
if log.LogLevel > level {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
30
main.go
30
main.go
|
@ -7,38 +7,28 @@ import (
|
||||||
|
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
"github.com/Dreamacro/clash/hub"
|
"github.com/Dreamacro/clash/hub"
|
||||||
"github.com/Dreamacro/clash/proxy/http"
|
"github.com/Dreamacro/clash/proxy"
|
||||||
"github.com/Dreamacro/clash/proxy/socks"
|
|
||||||
"github.com/Dreamacro/clash/tunnel"
|
"github.com/Dreamacro/clash/tunnel"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
if err := tunnel.GetInstance().UpdateConfig(); err != nil {
|
||||||
|
log.Fatalf("Parse config error: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := proxy.Instance().Run(); err != nil {
|
||||||
|
log.Fatalf("Proxy listen error: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hub
|
||||||
cfg, err := C.GetConfig()
|
cfg, err := C.GetConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Read config error: %s", err.Error())
|
log.Fatalf("Read config error: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
port, socksPort := C.DefalutHTTPPort, C.DefalutSOCKSPort
|
|
||||||
section := cfg.Section("General")
|
section := cfg.Section("General")
|
||||||
if key, err := section.GetKey("port"); err == nil {
|
|
||||||
port = key.Value()
|
|
||||||
}
|
|
||||||
|
|
||||||
if key, err := section.GetKey("socks-port"); err == nil {
|
|
||||||
socksPort = key.Value()
|
|
||||||
}
|
|
||||||
|
|
||||||
err = tunnel.GetInstance().UpdateConfig()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Parse config error: %s", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
go http.NewHttpProxy(port)
|
|
||||||
go socks.NewSocksProxy(socksPort)
|
|
||||||
|
|
||||||
// Hub
|
|
||||||
if key, err := section.GetKey("external-controller"); err == nil {
|
if key, err := section.GetKey("external-controller"); err == nil {
|
||||||
go hub.NewHub(key.Value())
|
go hub.NewHub(key.Value())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -17,9 +17,20 @@ var (
|
||||||
tun = tunnel.GetInstance()
|
tun = tunnel.GetInstance()
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewHttpProxy(port string) {
|
func NewHttpProxy(addr string) (*C.ProxySignal, error) {
|
||||||
|
l, err := net.Listen("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
done := make(chan struct{})
|
||||||
|
closed := make(chan struct{})
|
||||||
|
signal := &C.ProxySignal{
|
||||||
|
Done: done,
|
||||||
|
Closed: closed,
|
||||||
|
}
|
||||||
|
|
||||||
server := &http.Server{
|
server := &http.Server{
|
||||||
Addr: fmt.Sprintf(":%s", port),
|
|
||||||
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method == http.MethodConnect {
|
if r.Method == http.MethodConnect {
|
||||||
handleTunneling(w, r)
|
handleTunneling(w, r)
|
||||||
|
@ -28,8 +39,20 @@ func NewHttpProxy(port string) {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
log.Infof("HTTP proxy :%s", port)
|
|
||||||
server.ListenAndServe()
|
go func() {
|
||||||
|
log.Infof("HTTP proxy listening at: %s", addr)
|
||||||
|
server.Serve(l)
|
||||||
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
<-done
|
||||||
|
server.Shutdown(context.Background())
|
||||||
|
l.Close()
|
||||||
|
closed <- struct{}{}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return signal, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleHTTP(w http.ResponseWriter, r *http.Request) {
|
func handleHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
143
proxy/listener.go
Normal file
143
proxy/listener.go
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
package proxy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
C "github.com/Dreamacro/clash/constant"
|
||||||
|
"github.com/Dreamacro/clash/proxy/http"
|
||||||
|
"github.com/Dreamacro/clash/proxy/socks"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
listener *Listener
|
||||||
|
once sync.Once
|
||||||
|
)
|
||||||
|
|
||||||
|
type Listener struct {
|
||||||
|
httpPort int
|
||||||
|
socksPort int
|
||||||
|
allowLan bool
|
||||||
|
|
||||||
|
// signal for update
|
||||||
|
httpSignal *C.ProxySignal
|
||||||
|
socksSignal *C.ProxySignal
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info returns the proxys's current configuration
|
||||||
|
func (l *Listener) Info() (info C.General) {
|
||||||
|
return C.General{
|
||||||
|
Port: &l.httpPort,
|
||||||
|
SocksPort: &l.socksPort,
|
||||||
|
AllowLan: &l.allowLan,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Listener) Update(allowLan *bool, httpPort *int, socksPort *int) error {
|
||||||
|
if allowLan != nil {
|
||||||
|
l.allowLan = *allowLan
|
||||||
|
}
|
||||||
|
|
||||||
|
var socksErr, httpErr error
|
||||||
|
if allowLan != nil || httpPort != nil {
|
||||||
|
newHTTPPort := l.httpPort
|
||||||
|
if httpPort != nil {
|
||||||
|
newHTTPPort = *httpPort
|
||||||
|
}
|
||||||
|
httpErr = l.updateHTTP(newHTTPPort)
|
||||||
|
}
|
||||||
|
|
||||||
|
if allowLan != nil || socksPort != nil {
|
||||||
|
newSocksPort := l.socksPort
|
||||||
|
if socksPort != nil {
|
||||||
|
newSocksPort = *socksPort
|
||||||
|
}
|
||||||
|
socksErr = l.updateSocks(newSocksPort)
|
||||||
|
}
|
||||||
|
|
||||||
|
if socksErr != nil && httpErr != nil {
|
||||||
|
return fmt.Errorf("%s\n%s", socksErr.Error(), httpErr.Error())
|
||||||
|
} else if socksErr != nil {
|
||||||
|
return socksErr
|
||||||
|
} else if httpErr != nil {
|
||||||
|
return httpErr
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Listener) updateHTTP(port int) error {
|
||||||
|
if l.httpSignal != nil {
|
||||||
|
signal := l.httpSignal
|
||||||
|
signal.Done <- struct{}{}
|
||||||
|
<-signal.Closed
|
||||||
|
l.httpSignal = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
signal, err := http.NewHttpProxy(l.genAddr(port))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
l.httpSignal = signal
|
||||||
|
l.httpPort = port
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Listener) updateSocks(port int) error {
|
||||||
|
if l.socksSignal != nil {
|
||||||
|
signal := l.socksSignal
|
||||||
|
signal.Done <- struct{}{}
|
||||||
|
<-signal.Closed
|
||||||
|
l.socksSignal = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
signal, err := socks.NewSocksProxy(l.genAddr(port))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
l.socksSignal = signal
|
||||||
|
l.socksPort = port
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Listener) genAddr(port int) string {
|
||||||
|
host := "127.0.0.1"
|
||||||
|
if l.allowLan {
|
||||||
|
host = ""
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s:%d", host, port)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Listener) Run() error {
|
||||||
|
return l.Update(&l.allowLan, &l.httpPort, &l.socksPort)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newListener() *Listener {
|
||||||
|
cfg, err := C.GetConfig()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Read config error: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
general := cfg.Section("General")
|
||||||
|
|
||||||
|
port := general.Key("port").RangeInt(C.DefalutHTTPPort, 1, 65535)
|
||||||
|
socksPort := general.Key("socks-port").RangeInt(C.DefalutSOCKSPort, 1, 65535)
|
||||||
|
allowLan := general.Key("allow-lan").MustBool()
|
||||||
|
|
||||||
|
return &Listener{
|
||||||
|
httpPort: port,
|
||||||
|
socksPort: socksPort,
|
||||||
|
allowLan: allowLan,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Instance() *Listener {
|
||||||
|
once.Do(func() {
|
||||||
|
listener = newListener()
|
||||||
|
})
|
||||||
|
return listener
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
package socks
|
package socks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -17,20 +16,41 @@ var (
|
||||||
tun = tunnel.GetInstance()
|
tun = tunnel.GetInstance()
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewSocksProxy(port string) {
|
func NewSocksProxy(addr string) (*C.ProxySignal, error) {
|
||||||
l, err := net.Listen("tcp", fmt.Sprintf(":%s", port))
|
l, err := net.Listen("tcp", addr)
|
||||||
defer l.Close()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
log.Infof("SOCKS proxy :%s", port)
|
|
||||||
for {
|
done := make(chan struct{})
|
||||||
c, err := l.Accept()
|
closed := make(chan struct{})
|
||||||
if err != nil {
|
signal := &C.ProxySignal{
|
||||||
continue
|
Done: done,
|
||||||
|
Closed: closed,
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
log.Infof("SOCKS proxy listening at: %s", addr)
|
||||||
|
for {
|
||||||
|
c, err := l.Accept()
|
||||||
|
if err != nil {
|
||||||
|
if _, open := <-done; !open {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
go handleSocks(c)
|
||||||
}
|
}
|
||||||
go handleSocks(c)
|
}()
|
||||||
}
|
|
||||||
|
go func() {
|
||||||
|
<-done
|
||||||
|
close(done)
|
||||||
|
l.Close()
|
||||||
|
closed <- struct{}{}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return signal, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleSocks(conn net.Conn) {
|
func handleSocks(conn net.Conn) {
|
||||||
|
|
|
@ -52,6 +52,10 @@ func (t *Tunnel) SetMode(mode Mode) {
|
||||||
t.mode = mode
|
t.mode = mode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Tunnel) GetMode() Mode {
|
||||||
|
return t.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 {
|
||||||
|
|
Loading…
Reference in a new issue