mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 01:15:41 +08:00
strategy: add checktimeout config. (#89)
This commit is contained in:
parent
47406ce4ce
commit
a22b1d9c86
@ -116,9 +116,11 @@ glider -config CONFIGPATH -listen :8080 -verbose
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
glider v0.6.10 usage:
|
||||
glider v0.7.0 usage:
|
||||
-checkinterval int
|
||||
proxy check interval(seconds) (default 30)
|
||||
-checktimeout int
|
||||
proxy check timeout(seconds) (default 10)
|
||||
-checkwebsite string
|
||||
proxy check HTTP(NOT HTTPS) website address, format: HOST[:PORT], default port: 80 (default "www.apple.com")
|
||||
-config string
|
||||
@ -139,6 +141,8 @@ glider v0.6.10 usage:
|
||||
timeout value used in multiple dnsservers switch(seconds) (default 3)
|
||||
-forward value
|
||||
forward url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS[,SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS]
|
||||
-include value
|
||||
include file
|
||||
-interface string
|
||||
source ip or source interface
|
||||
-listen value
|
||||
|
@ -7,41 +7,35 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// UDPBufSize is the size of udp buffer
|
||||
// UDPBufSize is the size of udp buffer.
|
||||
const UDPBufSize = 65536
|
||||
|
||||
// Conn struct
|
||||
// Conn is a base conn struct.
|
||||
type Conn struct {
|
||||
r *bufio.Reader
|
||||
net.Conn
|
||||
}
|
||||
|
||||
// NewConn .
|
||||
// NewConn returns a new conn.
|
||||
func NewConn(c net.Conn) *Conn {
|
||||
return &Conn{bufio.NewReader(c), c}
|
||||
}
|
||||
|
||||
// NewConnSize .
|
||||
func NewConnSize(c net.Conn, n int) *Conn {
|
||||
return &Conn{bufio.NewReaderSize(c, n), c}
|
||||
}
|
||||
|
||||
// Peek .
|
||||
// Peek returns the next n bytes without advancing the reader.
|
||||
func (c *Conn) Peek(n int) ([]byte, error) {
|
||||
return c.r.Peek(n)
|
||||
}
|
||||
|
||||
// Read .
|
||||
func (c *Conn) Read(p []byte) (int, error) {
|
||||
return c.r.Read(p)
|
||||
}
|
||||
|
||||
// Reader returns the internal bufio.Reader
|
||||
// Reader returns the internal bufio.Reader.
|
||||
func (c *Conn) Reader() *bufio.Reader {
|
||||
return c.r
|
||||
}
|
||||
|
||||
// Relay .
|
||||
// Relay relays between left and right.
|
||||
func Relay(left, right net.Conn) (int64, int64, error) {
|
||||
type res struct {
|
||||
N int64
|
||||
@ -67,8 +61,8 @@ func Relay(left, right net.Conn) (int64, int64, error) {
|
||||
return n, rs.N, err
|
||||
}
|
||||
|
||||
// TimedCopy copy from src to dst at target with read timeout
|
||||
func TimedCopy(dst net.PacketConn, target net.Addr, src net.PacketConn, timeout time.Duration) error {
|
||||
// RelayUDP copys from src to dst at target with read timeout.
|
||||
func RelayUDP(dst net.PacketConn, target net.Addr, src net.PacketConn, timeout time.Duration) error {
|
||||
buf := make([]byte, UDPBufSize)
|
||||
for {
|
||||
src.SetReadDeadline(time.Now().Add(timeout))
|
||||
@ -84,7 +78,7 @@ func TimedCopy(dst net.PacketConn, target net.Addr, src net.PacketConn, timeout
|
||||
}
|
||||
}
|
||||
|
||||
// OutboundIP returns preferred outbound ip of this machine
|
||||
// OutboundIP returns preferred outbound ip of this machine.
|
||||
func OutboundIP() string {
|
||||
conn, err := net.Dial("udp", "8.8.8.8:80")
|
||||
if err != nil {
|
||||
|
1
conf.go
1
conf.go
@ -40,6 +40,7 @@ func confInit() {
|
||||
flag.StringVar(&conf.StrategyConfig.Strategy, "strategy", "rr", "forward strategy, default: rr")
|
||||
flag.StringVar(&conf.StrategyConfig.CheckWebSite, "checkwebsite", "www.apple.com", "proxy check HTTP(NOT HTTPS) website address, format: HOST[:PORT], default port: 80")
|
||||
flag.IntVar(&conf.StrategyConfig.CheckInterval, "checkinterval", 30, "proxy check interval(seconds)")
|
||||
flag.IntVar(&conf.StrategyConfig.CheckTimeout, "checktimeout", 10, "proxy check timeout(seconds)")
|
||||
flag.IntVar(&conf.StrategyConfig.MaxFailures, "maxfailures", 3, "max failures to change forwarder status to disabled")
|
||||
flag.StringVar(&conf.StrategyConfig.IntFace, "interface", "", "source ip or source interface")
|
||||
|
||||
|
@ -155,6 +155,8 @@ checkwebsite=www.apple.com
|
||||
# check interval(seconds)
|
||||
checkinterval=30
|
||||
|
||||
# check timeout(seconds)
|
||||
checktimeout=10
|
||||
|
||||
# DNS FORWARDING SERVER
|
||||
# ----------------
|
||||
|
6
go.mod
6
go.mod
@ -19,9 +19,9 @@ require (
|
||||
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b // indirect
|
||||
github.com/tjfoc/gmsm v1.0.1 // indirect
|
||||
github.com/xtaci/kcp-go v5.0.7+incompatible
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a // indirect
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313 // indirect
|
||||
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a
|
||||
golang.org/x/net v0.0.0-20190313220215-9f648a60d977 // indirect
|
||||
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f // indirect
|
||||
)
|
||||
|
||||
// Replace dependency modules with local developing copy
|
||||
|
6
go.sum
6
go.sum
@ -38,6 +38,8 @@ golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28
|
||||
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a h1:YX8ljsm6wXlHZO+aRz9Exqr0evNhKRNe5K/gi+zKh4U=
|
||||
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20190301231341-16b79f2e4e95 h1:fY7Dsw114eJN4boqzVSbpVHO6rTdhq6/GnXeu+PKnzU=
|
||||
golang.org/x/net v0.0.0-20190301231341-16b79f2e4e95/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190310074541-c10a0554eabf h1:J7RqX9u0J9ZB37CGaFc2VC+QZZT6E6jnDbrboEFVo0U=
|
||||
@ -46,6 +48,8 @@ golang.org/x/net v0.0.0-20190311031020-56fb01167e7d h1:vQJbQvu6+H699vOmHa20TEBI9
|
||||
golang.org/x/net v0.0.0-20190311031020-56fb01167e7d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190313220215-9f648a60d977 h1:actzWV6iWn3GLqN8dZjzsB+CLt+gaV2+wsxroxiQI8I=
|
||||
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190302025703-b6889370fb10 h1:xQJI9OEiErEQ++DoXOHqEpzsGMrAv2Q2jyCpi7DmfpQ=
|
||||
golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -69,4 +73,6 @@ golang.org/x/sys v0.0.0-20190311152110-c8c8c57fd1e1 h1:FQNj2xvjQ1lgFyzbSybGZr792
|
||||
golang.org/x/sys v0.0.0-20190311152110-c8c8c57fd1e1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313 h1:pczuHS43Cp2ktBEEmLwScxgjWsBSzdaQiKzUyf3DTTc=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f h1:yCrMx/EeIue0+Qca57bWZS7VX6ymEoypmhWyPhz0NHM=
|
||||
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -26,10 +26,10 @@ import (
|
||||
"github.com/nadoo/glider/proxy"
|
||||
)
|
||||
|
||||
// Version is socks5 version number
|
||||
// Version is socks5 version number.
|
||||
const Version = 5
|
||||
|
||||
// SOCKS5 struct
|
||||
// SOCKS5 is a base socks5 struct.
|
||||
type SOCKS5 struct {
|
||||
dialer proxy.Dialer
|
||||
addr string
|
||||
@ -43,7 +43,7 @@ func init() {
|
||||
}
|
||||
|
||||
// NewSOCKS5 returns a Proxy that makes SOCKS v5 connections to the given address
|
||||
// with an optional username and password. See RFC 1928
|
||||
// with an optional username and password. (RFC 1928)
|
||||
func NewSOCKS5(s string, dialer proxy.Dialer) (*SOCKS5, error) {
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
@ -65,23 +65,23 @@ func NewSOCKS5(s string, dialer proxy.Dialer) (*SOCKS5, error) {
|
||||
return h, nil
|
||||
}
|
||||
|
||||
// NewSocks5Dialer returns a socks5 proxy dialer
|
||||
// NewSocks5Dialer returns a socks5 proxy dialer.
|
||||
func NewSocks5Dialer(s string, dialer proxy.Dialer) (proxy.Dialer, error) {
|
||||
return NewSOCKS5(s, dialer)
|
||||
}
|
||||
|
||||
// NewSocks5Server returns a socks5 proxy server
|
||||
// NewSocks5Server returns a socks5 proxy server.
|
||||
func NewSocks5Server(s string, dialer proxy.Dialer) (proxy.Server, error) {
|
||||
return NewSOCKS5(s, dialer)
|
||||
}
|
||||
|
||||
// ListenAndServe serves socks5 requests
|
||||
// ListenAndServe serves socks5 requests.
|
||||
func (s *SOCKS5) ListenAndServe() {
|
||||
go s.ListenAndServeUDP()
|
||||
s.ListenAndServeTCP()
|
||||
}
|
||||
|
||||
// ListenAndServeTCP .
|
||||
// ListenAndServeTCP listen and serve on tcp port.
|
||||
func (s *SOCKS5) ListenAndServeTCP() {
|
||||
l, err := net.Listen("tcp", s.addr)
|
||||
if err != nil {
|
||||
@ -102,7 +102,7 @@ func (s *SOCKS5) ListenAndServeTCP() {
|
||||
}
|
||||
}
|
||||
|
||||
// Serve .
|
||||
// Serve serves a connection.
|
||||
func (s *SOCKS5) Serve(c net.Conn) {
|
||||
defer c.Close()
|
||||
|
||||
@ -148,7 +148,7 @@ func (s *SOCKS5) Serve(c net.Conn) {
|
||||
}
|
||||
}
|
||||
|
||||
// ListenAndServeUDP serves udp requests
|
||||
// ListenAndServeUDP serves udp requests.
|
||||
func (s *SOCKS5) ListenAndServeUDP() {
|
||||
lc, err := net.ListenPacket("udp", s.addr)
|
||||
if err != nil {
|
||||
@ -189,7 +189,7 @@ func (s *SOCKS5) ListenAndServeUDP() {
|
||||
nm.Store(raddr.String(), pc)
|
||||
|
||||
go func() {
|
||||
conn.TimedCopy(c, raddr, pc, 2*time.Minute)
|
||||
conn.RelayUDP(c, raddr, pc, 2*time.Minute)
|
||||
pc.Close()
|
||||
nm.Delete(raddr.String())
|
||||
}()
|
||||
@ -211,7 +211,7 @@ func (s *SOCKS5) ListenAndServeUDP() {
|
||||
|
||||
}
|
||||
|
||||
// Addr returns forwarder's address
|
||||
// Addr returns forwarder's address.
|
||||
func (s *SOCKS5) Addr() string {
|
||||
if s.addr == "" {
|
||||
return s.dialer.Addr()
|
||||
@ -219,7 +219,7 @@ func (s *SOCKS5) Addr() string {
|
||||
return s.addr
|
||||
}
|
||||
|
||||
// NextDialer returns the next dialer
|
||||
// NextDialer returns the next dialer.
|
||||
func (s *SOCKS5) NextDialer(dstAddr string) proxy.Dialer { return s.dialer.NextDialer(dstAddr) }
|
||||
|
||||
// Dial connects to the address addr on the network net via the SOCKS5 proxy.
|
||||
@ -244,7 +244,7 @@ func (s *SOCKS5) Dial(network, addr string) (net.Conn, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// DialUDP connects to the given address via the proxy
|
||||
// DialUDP connects to the given address via the proxy.
|
||||
func (s *SOCKS5) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error) {
|
||||
c, err := s.dialer.Dial("tcp", s.addr)
|
||||
if err != nil {
|
||||
@ -293,7 +293,7 @@ func (s *SOCKS5) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.A
|
||||
|
||||
// connect takes an existing connection to a socks5 proxy server,
|
||||
// and commands the server to extend that connection to target,
|
||||
// which must be a canonical address with a host and port
|
||||
// which must be a canonical address with a host and port.
|
||||
func (s *SOCKS5) connect(conn net.Conn, target string) error {
|
||||
host, portStr, err := net.SplitHostPort(target)
|
||||
if err != nil {
|
||||
@ -424,7 +424,7 @@ func (s *SOCKS5) connect(conn net.Conn, target string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Handshake fast-tracks SOCKS initialization to get target address to connect
|
||||
// Handshake fast-tracks SOCKS initialization to get target address to connect.
|
||||
func (s *SOCKS5) handshake(rw io.ReadWriter) (socks.Addr, error) {
|
||||
// Read RFC 1928 for request and reply structure and sizes
|
||||
buf := make([]byte, socks.MaxAddrLen)
|
||||
|
@ -16,7 +16,7 @@ import (
|
||||
"github.com/nadoo/glider/proxy"
|
||||
)
|
||||
|
||||
// SS .
|
||||
// SS is a base ss struct.
|
||||
type SS struct {
|
||||
dialer proxy.Dialer
|
||||
addr string
|
||||
@ -29,7 +29,7 @@ func init() {
|
||||
proxy.RegisterServer("ss", NewSSServer)
|
||||
}
|
||||
|
||||
// NewSS returns a shadowsocks proxy
|
||||
// NewSS returns a ss proxy.
|
||||
func NewSS(s string, dialer proxy.Dialer) (*SS, error) {
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
@ -55,23 +55,23 @@ func NewSS(s string, dialer proxy.Dialer) (*SS, error) {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// NewSSDialer returns a ss proxy dialer
|
||||
// NewSSDialer returns a ss proxy dialer.
|
||||
func NewSSDialer(s string, dialer proxy.Dialer) (proxy.Dialer, error) {
|
||||
return NewSS(s, dialer)
|
||||
}
|
||||
|
||||
// NewSSServer returns a ss proxy server
|
||||
// NewSSServer returns a ss proxy server.
|
||||
func NewSSServer(s string, dialer proxy.Dialer) (proxy.Server, error) {
|
||||
return NewSS(s, dialer)
|
||||
}
|
||||
|
||||
// ListenAndServe serves ss requests
|
||||
// ListenAndServe serves ss requests.
|
||||
func (s *SS) ListenAndServe() {
|
||||
go s.ListenAndServeUDP()
|
||||
s.ListenAndServeTCP()
|
||||
}
|
||||
|
||||
// ListenAndServeTCP serves tcp ss requests
|
||||
// ListenAndServeTCP serves tcp ss requests.
|
||||
func (s *SS) ListenAndServeTCP() {
|
||||
l, err := net.Listen("tcp", s.addr)
|
||||
if err != nil {
|
||||
@ -92,7 +92,7 @@ func (s *SS) ListenAndServeTCP() {
|
||||
|
||||
}
|
||||
|
||||
// Serve serves tcp ss requests
|
||||
// Serve serves a connection.
|
||||
func (s *SS) Serve(c net.Conn) {
|
||||
defer c.Close()
|
||||
|
||||
@ -166,7 +166,7 @@ func (s *SS) Serve(c net.Conn) {
|
||||
|
||||
}
|
||||
|
||||
// ListenAndServeUDP serves udp ss requests
|
||||
// ListenAndServeUDP serves udp ss requests.
|
||||
func (s *SS) ListenAndServeUDP() {
|
||||
lc, err := net.ListenPacket("udp", s.addr)
|
||||
if err != nil {
|
||||
@ -204,7 +204,7 @@ func (s *SS) ListenAndServeUDP() {
|
||||
nm.Store(raddr.String(), pc)
|
||||
|
||||
go func() {
|
||||
conn.TimedCopy(c, raddr, pc, 2*time.Minute)
|
||||
conn.RelayUDP(c, raddr, pc, 2*time.Minute)
|
||||
pc.Close()
|
||||
nm.Delete(raddr.String())
|
||||
}()
|
||||
@ -225,12 +225,12 @@ func (s *SS) ListenAndServeUDP() {
|
||||
}
|
||||
}
|
||||
|
||||
// ListCipher .
|
||||
// ListCipher returns all the ciphers supported.
|
||||
func ListCipher() string {
|
||||
return strings.Join(core.ListCipher(), " ")
|
||||
}
|
||||
|
||||
// Addr returns forwarder's address
|
||||
// Addr returns forwarder's address.
|
||||
func (s *SS) Addr() string {
|
||||
if s.addr == "" {
|
||||
return s.dialer.Addr()
|
||||
@ -238,7 +238,7 @@ func (s *SS) Addr() string {
|
||||
return s.addr
|
||||
}
|
||||
|
||||
// NextDialer returns the next dialer
|
||||
// NextDialer returns the next dialer.
|
||||
func (s *SS) NextDialer(dstAddr string) proxy.Dialer { return s.dialer.NextDialer(dstAddr) }
|
||||
|
||||
// Dial connects to the address addr on the network net via the proxy.
|
||||
@ -268,7 +268,7 @@ func (s *SS) Dial(network, addr string) (net.Conn, error) {
|
||||
|
||||
}
|
||||
|
||||
// DialUDP connects to the given address via the proxy
|
||||
// DialUDP connects to the given address via the proxy.
|
||||
func (s *SS) DialUDP(network, addr string) (net.PacketConn, net.Addr, error) {
|
||||
pc, nextHop, err := s.dialer.DialUDP(network, s.addr)
|
||||
if err != nil {
|
||||
|
@ -16,8 +16,8 @@ import (
|
||||
type UDPTun struct {
|
||||
dialer proxy.Dialer
|
||||
addr string
|
||||
taddr string // tunnel addr
|
||||
uaddr *net.UDPAddr // tunnel addr
|
||||
taddr string // tunnel addr string
|
||||
tuaddr *net.UDPAddr // tunnel addr
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -41,7 +41,7 @@ func NewUDPTun(s string, dialer proxy.Dialer) (*UDPTun, error) {
|
||||
taddr: d[1],
|
||||
}
|
||||
|
||||
p.uaddr, err = net.ResolveUDPAddr("udp", p.taddr)
|
||||
p.tuaddr, err = net.ResolveUDPAddr("udp", p.taddr)
|
||||
return p, err
|
||||
}
|
||||
|
||||
@ -85,7 +85,7 @@ func (s *UDPTun) ListenAndServe() {
|
||||
nm.Store(raddr.String(), pc)
|
||||
|
||||
go func() {
|
||||
conn.TimedCopy(c, raddr, pc, 2*time.Minute)
|
||||
conn.RelayUDP(c, raddr, pc, 2*time.Minute)
|
||||
pc.Close()
|
||||
nm.Delete(raddr.String())
|
||||
}()
|
||||
@ -94,7 +94,7 @@ func (s *UDPTun) ListenAndServe() {
|
||||
pc = v.(net.PacketConn)
|
||||
}
|
||||
|
||||
_, err = pc.WriteTo(buf[:n], s.uaddr)
|
||||
_, err = pc.WriteTo(buf[:n], s.tuaddr)
|
||||
if err != nil {
|
||||
log.F("[udptun] remote write error: %v", err)
|
||||
continue
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
"github.com/nadoo/glider/proxy"
|
||||
)
|
||||
|
||||
// UoTTun udp over tcp tunnel
|
||||
// UoTTun is a base udp over tcp tunnel struct.
|
||||
type UoTTun struct {
|
||||
dialer proxy.Dialer
|
||||
addr string
|
||||
@ -24,7 +24,7 @@ func init() {
|
||||
proxy.RegisterServer("uottun", NewUoTTunServer)
|
||||
}
|
||||
|
||||
// NewUoTTun returns a UoTTun proxy
|
||||
// NewUoTTun returns a UoTTun proxy.
|
||||
func NewUoTTun(s string, dialer proxy.Dialer) (*UoTTun, error) {
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
@ -44,12 +44,12 @@ func NewUoTTun(s string, dialer proxy.Dialer) (*UoTTun, error) {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// NewUoTTunServer returns a uot tunnel server
|
||||
// NewUoTTunServer returns a uot tunnel server.
|
||||
func NewUoTTunServer(s string, dialer proxy.Dialer) (proxy.Server, error) {
|
||||
return NewUoTTun(s, dialer)
|
||||
}
|
||||
|
||||
// ListenAndServe .
|
||||
// ListenAndServe listen and serve on tcp.
|
||||
func (s *UoTTun) ListenAndServe() {
|
||||
c, err := net.ListenPacket("udp", s.addr)
|
||||
if err != nil {
|
||||
@ -78,7 +78,7 @@ func (s *UoTTun) ListenAndServe() {
|
||||
go func() {
|
||||
// no remote forwarder, just a local udp forwarder
|
||||
if urc, ok := rc.(*net.UDPConn); ok {
|
||||
conn.TimedCopy(c, clientAddr, urc, 2*time.Minute)
|
||||
conn.RelayUDP(c, clientAddr, urc, 2*time.Minute)
|
||||
urc.Close()
|
||||
return
|
||||
}
|
||||
@ -103,7 +103,7 @@ func (s *UoTTun) ListenAndServe() {
|
||||
}
|
||||
}
|
||||
|
||||
// Serve .
|
||||
// Serve is not allowed to be called directly.
|
||||
func (s *UoTTun) Serve(c net.Conn) {
|
||||
// TODO
|
||||
log.F("[uottun] func Serve: can not be called directly")
|
||||
|
@ -35,6 +35,7 @@ func NewConfFromFile(ruleFile string) (*Config, error) {
|
||||
f.StringVar(&p.StrategyConfig.Strategy, "strategy", "rr", "forward strategy, default: rr")
|
||||
f.StringVar(&p.StrategyConfig.CheckWebSite, "checkwebsite", "www.apple.com", "proxy check HTTP(NOT HTTPS) website address, format: HOST[:PORT], default port: 80")
|
||||
f.IntVar(&p.StrategyConfig.CheckInterval, "checkinterval", 30, "proxy check interval(seconds)")
|
||||
f.IntVar(&p.StrategyConfig.CheckTimeout, "checktimeout", 10, "proxy check timeout(seconds)")
|
||||
f.StringVar(&p.StrategyConfig.IntFace, "interface", "", "source ip or source interface")
|
||||
|
||||
f.StringSliceUniqVar(&p.DNSServers, "dnsserver", nil, "remote dns server")
|
||||
|
@ -15,16 +15,17 @@ import (
|
||||
"github.com/nadoo/glider/proxy"
|
||||
)
|
||||
|
||||
// Checker is an interface of forwarder checker
|
||||
// Checker is an interface of forwarder checker.
|
||||
type Checker interface {
|
||||
Check()
|
||||
}
|
||||
|
||||
// Config of strategy
|
||||
// Config is strategy config struct.
|
||||
type Config struct {
|
||||
Strategy string
|
||||
CheckWebSite string
|
||||
CheckInterval int
|
||||
CheckTimeout int
|
||||
MaxFailures int
|
||||
IntFace string
|
||||
}
|
||||
@ -36,7 +37,7 @@ func (p priSlice) Len() int { return len(p) }
|
||||
func (p priSlice) Less(i, j int) bool { return p[i].Priority() > p[j].Priority() }
|
||||
func (p priSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
|
||||
// Dialer .
|
||||
// Dialer is base dialer struct.
|
||||
type Dialer struct {
|
||||
config *Config
|
||||
fwdrs priSlice
|
||||
@ -48,7 +49,7 @@ type Dialer struct {
|
||||
nextForwarder func(addr string) *proxy.Forwarder
|
||||
}
|
||||
|
||||
// NewDialer returns a new strategy dialer
|
||||
// NewDialer returns a new strategy dialer.
|
||||
func NewDialer(s []string, c *Config) proxy.Dialer {
|
||||
var fwdrs []*proxy.Forwarder
|
||||
for _, chain := range s {
|
||||
@ -111,20 +112,20 @@ func newDialer(fwdrs []*proxy.Forwarder, c *Config) *Dialer {
|
||||
return d
|
||||
}
|
||||
|
||||
// Addr returns forwarder's address
|
||||
// Addr returns forwarder's address.
|
||||
func (d *Dialer) Addr() string { return "STRATEGY" }
|
||||
|
||||
// Dial connects to the address addr on the network net
|
||||
// Dial connects to the address addr on the network net.
|
||||
func (d *Dialer) Dial(network, addr string) (net.Conn, error) {
|
||||
return d.NextDialer(addr).Dial(network, addr)
|
||||
}
|
||||
|
||||
// DialUDP connects to the given address
|
||||
// DialUDP connects to the given address.
|
||||
func (d *Dialer) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error) {
|
||||
return d.NextDialer(addr).DialUDP(network, addr)
|
||||
}
|
||||
|
||||
// NextDialer returns the next dialer
|
||||
// NextDialer returns the next dialer.
|
||||
func (d *Dialer) NextDialer(dstAddr string) proxy.Dialer {
|
||||
d.mu.RLock()
|
||||
defer d.mu.RUnlock()
|
||||
@ -132,13 +133,13 @@ func (d *Dialer) NextDialer(dstAddr string) proxy.Dialer {
|
||||
return d.nextForwarder(dstAddr)
|
||||
}
|
||||
|
||||
// Priority returns the active priority of dialer
|
||||
// Priority returns the active priority of dialer.
|
||||
func (d *Dialer) Priority() uint32 { return atomic.LoadUint32(&d.priority) }
|
||||
|
||||
// SetPriority sets the active priority of daler
|
||||
// SetPriority sets the active priority of daler.
|
||||
func (d *Dialer) SetPriority(p uint32) { atomic.StoreUint32(&d.priority, p) }
|
||||
|
||||
// initAvailable traverse d.fwdrs and init the available forwarder slice
|
||||
// initAvailable traverse d.fwdrs and init the available forwarder slice.
|
||||
func (d *Dialer) initAvailable() {
|
||||
for _, f := range d.fwdrs {
|
||||
if f.Enabled() {
|
||||
@ -162,7 +163,7 @@ func (d *Dialer) initAvailable() {
|
||||
}
|
||||
}
|
||||
|
||||
// onStatusChanged will be called when fwdr's status changed
|
||||
// onStatusChanged will be called when fwdr's status changed.
|
||||
func (d *Dialer) onStatusChanged(fwdr *proxy.Forwarder) {
|
||||
d.mu.Lock()
|
||||
defer d.mu.Unlock()
|
||||
@ -189,7 +190,7 @@ func (d *Dialer) onStatusChanged(fwdr *proxy.Forwarder) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check implements the Checker interface
|
||||
// Check implements the Checker interface.
|
||||
func (d *Dialer) Check() {
|
||||
for i := 0; i < len(d.fwdrs); i++ {
|
||||
go d.check(i)
|
||||
@ -229,11 +230,19 @@ func (d *Dialer) check(i int) {
|
||||
f.Disable()
|
||||
log.F("[check] %s(%d) -> %s, DISABLED. error in read: %s", f.Addr(), f.Priority(), d.config.CheckWebSite, err)
|
||||
} else if bytes.Equal([]byte("HTTP"), buf) {
|
||||
f.Enable()
|
||||
retry = 2
|
||||
|
||||
readTime := time.Since(startTime)
|
||||
f.SetLatency(int64(readTime))
|
||||
log.F("[check] %s(%d) -> %s, ENABLED. connect time: %s", f.Addr(), f.Priority(), d.config.CheckWebSite, readTime.String())
|
||||
|
||||
if readTime > time.Duration(d.config.CheckTimeout)*time.Second {
|
||||
f.Disable()
|
||||
log.F("[check] %s(%d) -> %s, DISABLED. connect timeout: %s", f.Addr(), f.Priority(), d.config.CheckWebSite, readTime)
|
||||
} else {
|
||||
retry = 2
|
||||
f.Enable()
|
||||
log.F("[check] %s(%d) -> %s, ENABLED. connect time: %s", f.Addr(), f.Priority(), d.config.CheckWebSite, readTime)
|
||||
}
|
||||
|
||||
} else {
|
||||
f.Disable()
|
||||
log.F("[check] %s(%d) -> %s, DISABLED. server response: %s", f.Addr(), f.Priority(), d.config.CheckWebSite, buf)
|
||||
|
Loading…
Reference in New Issue
Block a user