mirror of
https://github.com/luscis/openlan.git
synced 2025-10-07 01:22:51 +08:00
fea: merge http and socks5 proxy.
This commit is contained in:
33
Makefile
33
Makefile
@@ -78,11 +78,9 @@ builder:
|
||||
# tar xvf libreswan_4.10.orig.tar.gz
|
||||
# cd libreswan-4.10 && make deb
|
||||
|
||||
|
||||
docker-bin: ## binary by Docker
|
||||
docker exec openlan_builder bash -c "cd /opt/openlan && make linux-bin"
|
||||
|
||||
|
||||
docker-test: ## test by Docker
|
||||
docker exec openlan_builder bash -c "cd /opt/openlan && make test"
|
||||
|
||||
@@ -92,6 +90,9 @@ docker-darwin: ## binary for MacOS by Docker
|
||||
docker-windows: ## binary for Windows by Docker
|
||||
docker exec openlan_builder bash -c "cd /opt/openlan && make windows-gzip"
|
||||
|
||||
docker-ceci: ## binary for ceci by Docker
|
||||
docker exec openlan_builder bash -c "cd /opt/openlan && make ceci"
|
||||
|
||||
docker-rhel: docker-bin ## build image for redhat
|
||||
cp -rf $(SD)/docker/centos $(BD)
|
||||
cd $(BD) && \
|
||||
@@ -118,13 +119,19 @@ docker-compose: ## create a compose files
|
||||
echo "$ cd /tmp/openlan.c" && \
|
||||
echo "$ docker-compose up -d"
|
||||
|
||||
linux: env ## build linux binary
|
||||
ceci: linux-ceci darwin-ceci windows-ceci ## build all platform ceci
|
||||
|
||||
linux: env linux-ceci linux-proxy ## build linux binary
|
||||
go build -mod=vendor -ldflags "$(LDFLAGS)" -o $(BD)/openlan ./cmd/main.go
|
||||
go build -mod=vendor -ldflags "$(LDFLAGS)" -o $(BD)/openlan-proxy ./cmd/proxy
|
||||
go build -mod=vendor -ldflags "$(LDFLAGS)" -o $(BD)/openlan-ceci ./cmd/ceci
|
||||
go build -mod=vendor -ldflags "$(LDFLAGS)" -o $(BD)/openlan-point ./cmd/point
|
||||
go build -mod=vendor -ldflags "$(LDFLAGS)" -o $(BD)/openlan-switch ./cmd/switch
|
||||
|
||||
linux-ceci:
|
||||
go build -mod=vendor -ldflags "$(LDFLAGS)" -o $(BD)/openlan-ceci ./cmd/ceci
|
||||
|
||||
linux-proxy:
|
||||
go build -mod=vendor -ldflags "$(LDFLAGS)" -o $(BD)/openlan-proxy ./cmd/proxy
|
||||
|
||||
linux-gzip: install ## build linux packages
|
||||
@rm -rf $(LIN_DIR).tar.gz
|
||||
tar -cf $(LIN_DIR).tar $(LIN_DIR) && mv $(LIN_DIR).tar $(BD)
|
||||
@@ -152,8 +159,12 @@ install: env linux ## install packages
|
||||
@echo "Installed to $(LIN_DIR)"
|
||||
|
||||
## cross build for windows
|
||||
windows: ## build windows binary
|
||||
windows: env windows-ceci windows-proxy ## build windows binary
|
||||
|
||||
windows-proxy:
|
||||
GOOS=windows GOARCH=amd64 go build -mod=vendor -ldflags "$(LDFLAGS)" -o $(BD)/openlan-proxy.exe ./cmd/proxy
|
||||
|
||||
windows-ceci:
|
||||
GOOS=windows GOARCH=amd64 go build -mod=vendor -ldflags "$(LDFLAGS)" -o $(BD)/openlan-ceci.exe ./cmd/ceci
|
||||
|
||||
windows-gzip: env windows ## build windows packages
|
||||
@@ -166,12 +177,16 @@ windows-gzip: env windows ## build windows packages
|
||||
## cross build for osx
|
||||
osx: darwin
|
||||
|
||||
darwin: env ## build darwin binary
|
||||
GOOS=darwin GOARCH=amd64 go build -mod=vendor -ldflags "$(LDFLAGS)" -o $(BD)/openlan-proxy.dar ./cmd/proxy
|
||||
GOOS=darwin GOARCH=arm64 go build -mod=vendor -ldflags "$(LDFLAGS)" -o $(BD)/openlan-proxy.arm64.dar ./cmd/proxy
|
||||
darwin: env darwin-ceci darwin-proxy ## build darwin binary
|
||||
|
||||
darwin-ceci:
|
||||
GOOS=darwin GOARCH=amd64 go build -mod=vendor -ldflags "$(LDFLAGS)" -o $(BD)/openlan-ceci.dar ./cmd/ceci
|
||||
GOOS=darwin GOARCH=arm64 go build -mod=vendor -ldflags "$(LDFLAGS)" -o $(BD)/openlan-ceci.arm64.dar ./cmd/ceci
|
||||
|
||||
darwin-proxy:
|
||||
GOOS=darwin GOARCH=amd64 go build -mod=vendor -ldflags "$(LDFLAGS)" -o $(BD)/openlan-proxy.dar ./cmd/proxy
|
||||
GOOS=darwin GOARCH=arm64 go build -mod=vendor -ldflags "$(LDFLAGS)" -o $(BD)/openlan-proxy.arm64.dar ./cmd/proxy
|
||||
|
||||
darwin-gzip: env darwin ## build darwin packages
|
||||
@rm -rf $(MAC_DIR) && mkdir -p $(MAC_DIR)
|
||||
@cp -rf $(SD)/dist/rootfs/etc/openlan/proxy.json.local $(MAC_DIR)/proxy.json
|
||||
|
91
cmd/api/v5/ceci.go
Executable file
91
cmd/api/v5/ceci.go
Executable file
@@ -0,0 +1,91 @@
|
||||
package v5
|
||||
|
||||
import (
|
||||
"github.com/luscis/openlan/cmd/api"
|
||||
"github.com/luscis/openlan/pkg/schema"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
type Ceci struct {
|
||||
Cmd
|
||||
}
|
||||
|
||||
func (u Ceci) Url(prefix, name string) string {
|
||||
return prefix + "/api/interface/" + name + "/ceci"
|
||||
}
|
||||
|
||||
func (u Ceci) Tmpl() string {
|
||||
return `# total {{ len . }}
|
||||
{{ps -16 "Name"}} {{ps -8 "Configure"}}
|
||||
{{- range . }}
|
||||
{{ps -16 .Name}} {{pi .Configure}}
|
||||
{{- end }}
|
||||
`
|
||||
}
|
||||
|
||||
func (u Ceci) List(c *cli.Context) error {
|
||||
url := u.Url(c.String("url"), "")
|
||||
clt := u.NewHttp(c.String("token"))
|
||||
var items []schema.Ceci
|
||||
if err := clt.GetJSON(url, &items); err != nil {
|
||||
return err
|
||||
}
|
||||
return u.Out(items, c.String("format"), u.Tmpl())
|
||||
}
|
||||
|
||||
func (u Ceci) Add(c *cli.Context) error {
|
||||
name := c.String("name")
|
||||
rate := &schema.Ceci{
|
||||
Name: name,
|
||||
}
|
||||
url := u.Url(c.String("url"), name)
|
||||
clt := u.NewHttp(c.String("token"))
|
||||
if err := clt.PostJSON(url, rate, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u Ceci) Remove(c *cli.Context) error {
|
||||
name := c.String("name")
|
||||
|
||||
url := u.Url(c.String("url"), name)
|
||||
clt := u.NewHttp(c.String("token"))
|
||||
if err := clt.DeleteJSON(url, nil, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u Ceci) Commands(app *api.App) {
|
||||
app.Command(&cli.Command{
|
||||
Name: "ceci",
|
||||
Usage: "Ceci proxy",
|
||||
Subcommands: []*cli.Command{
|
||||
{
|
||||
Name: "list",
|
||||
Usage: "Display all ceci proxy",
|
||||
Aliases: []string{"ls"},
|
||||
Action: u.List,
|
||||
},
|
||||
{
|
||||
Name: "add",
|
||||
Usage: "Add a ceci proxy",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "name", Required: true},
|
||||
&cli.StringFlag{Name: "file", Required: true},
|
||||
},
|
||||
Action: u.Add,
|
||||
},
|
||||
{
|
||||
Name: "remove",
|
||||
Usage: "Remove a ceci proxy",
|
||||
Aliases: []string{"rm"},
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "name", Required: true},
|
||||
},
|
||||
Action: u.Remove,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
@@ -40,4 +40,5 @@ func Commands(app *api.App) {
|
||||
Log{}.Commands(app)
|
||||
ZTrust{}.Commands(app)
|
||||
Rate{}.Commands(app)
|
||||
Ceci{}.Commands(app)
|
||||
}
|
||||
|
12
dist/rootfs/etc/openlan/switch/ceci/https.yaml.example
vendored
Normal file
12
dist/rootfs/etc/openlan/switch/ceci/https.yaml.example
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
listen: 127.0.0.1:1080
|
||||
socks:
|
||||
listen: 127.0.0.1:1081
|
||||
cacert: ca.crt
|
||||
backends:
|
||||
- protocol: ssl
|
||||
server: <s1>:18000
|
||||
socks:
|
||||
server: <s2:18001>
|
||||
match:
|
||||
- a.b.com
|
@@ -2,8 +2,10 @@ package config
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
|
||||
"github.com/luscis/openlan/pkg/libol"
|
||||
)
|
||||
@@ -18,11 +20,69 @@ type ShadowProxy struct {
|
||||
Protocol string `json:"protocol,omitempty"`
|
||||
}
|
||||
|
||||
type ForwardSocks struct {
|
||||
Server string `json:"server,omitempty"`
|
||||
}
|
||||
|
||||
type HttpForward struct {
|
||||
Protocol string `json:"protocol,omitempty" yaml:"protocol,omitempty"`
|
||||
Server string `json:"server,omitempty" yaml:"server,omitempty"`
|
||||
Insecure bool `json:"insecure,omitempty" yaml:"insecure,omitempty"`
|
||||
Match []string `json:"match,omitempty" yaml:"match,omitempty"`
|
||||
Secret string `json:"secret,omitempty" yaml:"secret,omitempty"`
|
||||
Socks ForwardSocks `json:"socks,omitempty" yaml:"socks,omitempty"`
|
||||
}
|
||||
|
||||
func (f *HttpForward) SocksAddr() string {
|
||||
if f.Socks.Server != "" {
|
||||
return f.Socks.Server
|
||||
}
|
||||
return f.Server
|
||||
}
|
||||
|
||||
type HttpBackends []*HttpForward
|
||||
|
||||
func (h HttpBackends) isMatch(value string, rules []string) bool {
|
||||
if len(rules) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, rule := range rules {
|
||||
pattern := fmt.Sprintf(`(^|\.)%s(:\d+)?$`, regexp.QuoteMeta(rule))
|
||||
re := regexp.MustCompile(pattern)
|
||||
if re.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (h HttpBackends) FindBackend(host string) *HttpForward {
|
||||
for _, via := range h {
|
||||
if via == nil {
|
||||
continue
|
||||
}
|
||||
if via.Server == "" && via.Socks.Server == "" {
|
||||
continue
|
||||
}
|
||||
if h.isMatch(host, via.Match) {
|
||||
return via
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type FindBackend interface {
|
||||
FindBackend(host string) *HttpForward
|
||||
}
|
||||
|
||||
type SocksProxy struct {
|
||||
Conf string `json:"-" yaml:"-"`
|
||||
Listen string `json:"listen,omitempty" yaml:"listen,omitempty"`
|
||||
Auth *Password `json:"auth,omitempty" yaml:"auth,omitempty"`
|
||||
Backends []*HttpForward `json:"backends,omitempty" yaml:"backends,omitempty"`
|
||||
Backends HttpBackends `json:"backends,omitempty" yaml:"backends,omitempty"`
|
||||
}
|
||||
|
||||
func (s *SocksProxy) Initialize() error {
|
||||
@@ -41,12 +101,8 @@ func (s *SocksProxy) Load() error {
|
||||
return libol.UnmarshalLoad(s, s.Conf)
|
||||
}
|
||||
|
||||
type HttpForward struct {
|
||||
Protocol string `json:"protocol,omitempty" yaml:"protocol,omitempty"`
|
||||
Server string `json:"server,omitempty" yaml:"server,omitempty"`
|
||||
Insecure bool `json:"insecure,omitempty" yaml:"insecure,omitempty"`
|
||||
Match []string `json:"match,omitempty" yaml:"match,omitempty"`
|
||||
Secret string `json:"secret,omitempty" yaml:"secret,omitempty"`
|
||||
type HttpSocks struct {
|
||||
Listen string `json:"listen,omitempty"`
|
||||
}
|
||||
|
||||
type HttpProxy struct {
|
||||
@@ -57,8 +113,9 @@ type HttpProxy struct {
|
||||
Cert *Cert `json:"cert,omitempty" yaml:"cert,omitempty"`
|
||||
Password string `json:"password,omitempty" yaml:"password,omitempty"`
|
||||
CaCert string `json:"cacert,omitempty" yaml:"cacert,omitempty"`
|
||||
Forward *HttpForward `json:"forward,omitempty" yaml:"forward,omitempty"`
|
||||
Backends []*HttpForward `json:"backends,omitempty" yaml:"backends,omitempty"`
|
||||
Backends HttpBackends `json:"backends,omitempty" yaml:"backends,omitempty"`
|
||||
Socks *HttpSocks `json:"socks,omitempty" yaml:"socks,omitempty"`
|
||||
SocksProxy *SocksProxy `json:"-" yaml:"-"`
|
||||
}
|
||||
|
||||
func (h *HttpProxy) Initialize() error {
|
||||
@@ -93,6 +150,11 @@ func (h *HttpProxy) Correct() {
|
||||
h.CaCert = "ca.crt"
|
||||
}
|
||||
h.CaCert = path.Join(h.ConfDir, h.CaCert)
|
||||
if h.Socks != nil {
|
||||
h.SocksProxy = &SocksProxy{
|
||||
Listen: h.Socks.Listen,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *HttpProxy) FindMatch(domain string, to *HttpForward) int {
|
||||
@@ -105,9 +167,6 @@ func (h *HttpProxy) FindMatch(domain string, to *HttpForward) int {
|
||||
}
|
||||
|
||||
func (h *HttpProxy) FindBackend(remote string) *HttpForward {
|
||||
if remote == "" || remote == "null" {
|
||||
return h.Forward
|
||||
}
|
||||
for _, to := range h.Backends {
|
||||
if to.Server == remote {
|
||||
return to
|
||||
|
@@ -13,7 +13,6 @@ import (
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -57,6 +56,7 @@ type HttpProxy struct {
|
||||
startat time.Time
|
||||
requests map[string]*HttpRecord
|
||||
lock sync.RWMutex
|
||||
socks *SocksProxy
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -134,7 +134,10 @@ func NewHttpProxy(cfg *co.HttpProxy, px Proxyer) *HttpProxy {
|
||||
if auth != nil && auth.Username != "" {
|
||||
h.pass[auth.Username] = auth.Password
|
||||
}
|
||||
|
||||
if cfg.SocksProxy != nil {
|
||||
h.socks = NewSocksProxy(cfg.SocksProxy)
|
||||
h.socks.server.SetBackends(h)
|
||||
}
|
||||
h.loadUrl()
|
||||
h.loadPass()
|
||||
|
||||
@@ -271,7 +274,7 @@ func (t *HttpProxy) toTunnel(w http.ResponseWriter, conn net.Conn, update func(b
|
||||
}
|
||||
|
||||
func (t *HttpProxy) openConn(protocol, remote string, insecure bool) (net.Conn, error) {
|
||||
if protocol == "https" {
|
||||
if protocol == "https" || protocol == "tls" {
|
||||
conf := &tls.Config{
|
||||
InsecureSkipVerify: insecure,
|
||||
}
|
||||
@@ -294,6 +297,12 @@ func (t *HttpProxy) openConn(protocol, remote string, insecure bool) (net.Conn,
|
||||
return net.DialTimeout("tcp", remote, 10*time.Second)
|
||||
}
|
||||
|
||||
func (h *HttpProxy) FindBackend(host string) *co.HttpForward {
|
||||
h.lock.RLock()
|
||||
defer h.lock.RUnlock()
|
||||
return h.cfg.Backends.FindBackend(host)
|
||||
}
|
||||
|
||||
func (t *HttpProxy) cloneRequest(r *http.Request, secret string) ([]byte, error) {
|
||||
var err error
|
||||
var b bytes.Buffer
|
||||
@@ -344,36 +353,6 @@ func (t *HttpProxy) cloneRequest(r *http.Request, secret string) ([]byte, error)
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func (t *HttpProxy) isMatch(value string, rules []string) bool {
|
||||
if len(rules) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, rule := range rules {
|
||||
pattern := fmt.Sprintf(`(^|\.)%s(:\d+)?$`, regexp.QuoteMeta(rule))
|
||||
re := regexp.MustCompile(pattern)
|
||||
if re.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *HttpProxy) findForward(r *http.Request) *co.HttpForward {
|
||||
t.lock.RLock()
|
||||
defer t.lock.RUnlock()
|
||||
|
||||
via := t.cfg.Forward
|
||||
if via != nil && t.isMatch(r.URL.Host, via.Match) {
|
||||
return via
|
||||
}
|
||||
for _, via := range t.cfg.Backends {
|
||||
if via != nil && t.isMatch(r.URL.Host, via.Match) {
|
||||
return via
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *HttpProxy) doRecord(r *http.Request, bytes int64) {
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
@@ -401,7 +380,7 @@ func (t *HttpProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
t.doRecord(r, 0)
|
||||
via := t.findForward(r)
|
||||
via := t.FindBackend(r.URL.Host)
|
||||
if via != nil {
|
||||
t.out.Info("HttpProxy.ServeHTTP %s %s -> %s via %s", r.Method, r.RemoteAddr, r.URL.Host, via.Server)
|
||||
conn, err := t.openConn(via.Protocol, via.Server, via.Insecure)
|
||||
@@ -450,6 +429,11 @@ func (t *HttpProxy) Start() {
|
||||
if t.server == nil || t.cfg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if t.socks != nil {
|
||||
t.socks.Start()
|
||||
}
|
||||
|
||||
crt := t.cfg.Cert
|
||||
if crt == nil || crt.KeyFile == "" {
|
||||
t.out.Info("HttpProxy.start http://%s", t.server.Addr)
|
||||
|
@@ -50,7 +50,7 @@ func (s *SocksProxy) Start() {
|
||||
return
|
||||
}
|
||||
addr := s.cfg.Listen
|
||||
s.out.Info("SocksProxy.Start: %s", s.cfg.Listen)
|
||||
s.out.Info("SocksProxy.Start: socks5://%s", s.cfg.Listen)
|
||||
|
||||
promise := &libol.Promise{
|
||||
First: time.Second * 2,
|
||||
|
6
pkg/schema/ceci.go
Normal file
6
pkg/schema/ceci.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package schema
|
||||
|
||||
type Ceci struct {
|
||||
Name string `json:"name"`
|
||||
Config interface{} `json:"config"`
|
||||
}
|
@@ -6,7 +6,6 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
co "github.com/luscis/openlan/pkg/config"
|
||||
@@ -54,7 +53,7 @@ type Config struct {
|
||||
Dial func(ctx context.Context, network, addr string) (net.Conn, error)
|
||||
|
||||
// Backends forwarding socks request
|
||||
Backends []*co.HttpForward
|
||||
Backends co.FindBackend
|
||||
}
|
||||
|
||||
// Server is reponsible for accepting connections and handling
|
||||
@@ -121,7 +120,6 @@ func (s *Server) Serve(l net.Listener) error {
|
||||
}
|
||||
go s.ServeConn(conn)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ServeConn is used to serve a single connection.
|
||||
@@ -132,14 +130,14 @@ func (s *Server) ServeConn(conn net.Conn) error {
|
||||
// Read the version byte
|
||||
version := []byte{0}
|
||||
if _, err := bufConn.Read(version); err != nil {
|
||||
s.config.Logger.Error("socks: Failed to get version byte: %v", err)
|
||||
s.config.Logger.Error("Socks.ServeConn Failed to get version byte: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Ensure we are compatible
|
||||
if version[0] != socks5Version {
|
||||
err := fmt.Errorf("Unsupported SOCKS version: %v", version)
|
||||
s.config.Logger.Error("socks: %v", err)
|
||||
s.config.Logger.Error("Socks.ServeConn %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -147,7 +145,7 @@ func (s *Server) ServeConn(conn net.Conn) error {
|
||||
authContext, err := s.authenticate(conn, bufConn)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Failed to authenticate: %v", err)
|
||||
s.config.Logger.Error("socks: %v", err)
|
||||
s.config.Logger.Error("Socks.ServeConn %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -166,20 +164,22 @@ func (s *Server) ServeConn(conn net.Conn) error {
|
||||
}
|
||||
|
||||
dstAddr := request.DestAddr
|
||||
via := s.findForward(dstAddr.Address())
|
||||
if s.config.Backends != nil {
|
||||
via := s.config.Backends.FindBackend(dstAddr.Address())
|
||||
if via != nil {
|
||||
if err := s.toForward(request, conn, via); err != nil {
|
||||
s.config.Logger.Error("socks.forward: %v", err)
|
||||
s.config.Logger.Error("Socks.ServeConn: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
s.config.Logger.Info("socks.ServeConn: %s", dstAddr.Address())
|
||||
s.config.Logger.Info("Socks.ServeConn CONNECT %s", dstAddr.Address())
|
||||
//Process the client request
|
||||
if err := s.handleRequest(request, conn); err != nil {
|
||||
err = fmt.Errorf("Failed to handle request: %v", err)
|
||||
s.config.Logger.Error("socks: %v", err)
|
||||
s.config.Logger.Error("Socks.ServeConn %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -205,34 +205,13 @@ func (s *Server) openConn(remote string) (net.Conn, error) {
|
||||
return net.DialTimeout("tcp", remote, 10*time.Second)
|
||||
}
|
||||
|
||||
func (s *Server) isMatch(value string, rules []string) bool {
|
||||
if len(rules) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, rule := range rules {
|
||||
pattern := fmt.Sprintf(`(^|\.)%s(:\d+)?$`, regexp.QuoteMeta(rule))
|
||||
re := regexp.MustCompile(pattern)
|
||||
if re.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Server) findForward(host string) *co.HttpForward {
|
||||
for _, via := range s.config.Backends {
|
||||
if via != nil && s.isMatch(host, via.Match) {
|
||||
return via
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) toForward(req *Request, local net.Conn, via *co.HttpForward) error {
|
||||
dstAddr := req.DestAddr
|
||||
s.config.Logger.Info("socks.toForward: %s via %s", dstAddr.Address(), via.Server)
|
||||
proxy := via.SocksAddr()
|
||||
|
||||
target, err := s.openConn(via.Server)
|
||||
s.config.Logger.Info("Socks.ServeConn CONNECT %s via %s", dstAddr.Address(), proxy)
|
||||
|
||||
target, err := s.openConn(proxy)
|
||||
if err != nil {
|
||||
sendReply(local, networkUnreachable, nil)
|
||||
return err
|
||||
@@ -270,3 +249,7 @@ func (s *Server) toForward(req *Request, local net.Conn, via *co.HttpForward) er
|
||||
s.toTunnel(local, target)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) SetBackends(find co.FindBackend) {
|
||||
s.config.Backends = find
|
||||
}
|
||||
|
Reference in New Issue
Block a user