mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 17:35:40 +08:00
vless: added udp support
This commit is contained in:
parent
bc68535dcd
commit
b323a62ce6
@ -377,7 +377,7 @@ glider -config CONFIGPATH -listen :8080 -verbose
|
|||||||
|
|
||||||
## Customize Build
|
## Customize Build
|
||||||
|
|
||||||
You can customize and build glider by yourself if you want a smaller binary.
|
You can customize and build glider if you want a smaller binary.
|
||||||
|
|
||||||
1. Clone the source code:
|
1. Clone the source code:
|
||||||
```bash
|
```bash
|
||||||
@ -385,8 +385,8 @@ You can customize and build glider by yourself if you want a smaller binary.
|
|||||||
```
|
```
|
||||||
2. Customize features:
|
2. Customize features:
|
||||||
|
|
||||||
```open `feature.go` & `feature_linux.go`, comment out the packages you don't need```
|
|
||||||
```bash
|
```bash
|
||||||
|
open `feature.go` & `feature_linux.go`, comment out the packages you don't need
|
||||||
// _ "github.com/nadoo/glider/proxy/kcp"
|
// _ "github.com/nadoo/glider/proxy/kcp"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
4
go.mod
4
go.mod
@ -10,10 +10,10 @@ require (
|
|||||||
github.com/nadoo/ipset v0.3.0
|
github.com/nadoo/ipset v0.3.0
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||||
github.com/xtaci/kcp-go/v5 v5.5.17
|
github.com/xtaci/kcp-go/v5 v5.5.17
|
||||||
golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae
|
golang.org/x/crypto v0.0.0-20201002094018-c90954cbb977
|
||||||
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10 // indirect
|
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10 // indirect
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect
|
||||||
golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c // indirect
|
golang.org/x/tools v0.0.0-20201002055958-0d28ed0cbe40 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
|
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
8
go.sum
8
go.sum
@ -118,8 +118,8 @@ golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPh
|
|||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig=
|
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig=
|
||||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae h1:duLSQW+DZ5MsXKX7kc4rXlq6/mmxz4G6ewJuBPlhRe0=
|
golang.org/x/crypto v0.0.0-20201002094018-c90954cbb977 h1:yH6opeNE+0SY+7pXT4gclZUoKHogXeC2EvOSHGOMGPU=
|
||||||
golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20201002094018-c90954cbb977/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||||
@ -173,8 +173,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
|||||||
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c h1:iHhCR0b26amDCiiO+kBguKZom9aMF+NrFxh9zeKR/XU=
|
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c h1:iHhCR0b26amDCiiO+kBguKZom9aMF+NrFxh9zeKR/XU=
|
||||||
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20200808161706-5bf02b21f123/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200808161706-5bf02b21f123/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c h1:9BSeO6440XJVa2mxIcRAndAol4g4g2KflCVGcHx9Yu8=
|
golang.org/x/tools v0.0.0-20201002055958-0d28ed0cbe40 h1:ErPN1Z9An7dXc56pRUCKgWJkjYzc3hE+y15ky9E8qxU=
|
||||||
golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
golang.org/x/tools v0.0.0-20201002055958-0d28ed0cbe40/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||||
|
@ -172,14 +172,14 @@ func (s *SS) Serve(c net.Conn) {
|
|||||||
func (s *SS) ListenAndServeUDP() {
|
func (s *SS) ListenAndServeUDP() {
|
||||||
lc, err := net.ListenPacket("udp", s.addr)
|
lc, err := net.ListenPacket("udp", s.addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.F("[ss-udp] failed to listen on %s: %v", s.addr, err)
|
log.F("[ssu] failed to listen on %s: %v", s.addr, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer lc.Close()
|
defer lc.Close()
|
||||||
|
|
||||||
lc = s.PacketConn(lc)
|
lc = s.PacketConn(lc)
|
||||||
|
|
||||||
log.F("[ss-udp] listening UDP on %s", s.addr)
|
log.F("[ssu] listening UDP on %s", s.addr)
|
||||||
|
|
||||||
var nm sync.Map
|
var nm sync.Map
|
||||||
buf := make([]byte, proxy.UDPBufSize)
|
buf := make([]byte, proxy.UDPBufSize)
|
||||||
@ -189,7 +189,7 @@ func (s *SS) ListenAndServeUDP() {
|
|||||||
|
|
||||||
n, raddr, err := c.ReadFrom(buf)
|
n, raddr, err := c.ReadFrom(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.F("[ss-udp] remote read error: %v", err)
|
log.F("[ssu] remote read error: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ func (s *SS) ListenAndServeUDP() {
|
|||||||
if !ok && v == nil {
|
if !ok && v == nil {
|
||||||
lpc, nextHop, err := s.proxy.DialUDP("udp", c.tgtAddr.String())
|
lpc, nextHop, err := s.proxy.DialUDP("udp", c.tgtAddr.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.F("[ss-udp] remote dial error: %v", err)
|
log.F("[ssu] remote dial error: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +211,7 @@ func (s *SS) ListenAndServeUDP() {
|
|||||||
nm.Delete(raddr.String())
|
nm.Delete(raddr.String())
|
||||||
}()
|
}()
|
||||||
|
|
||||||
log.F("[ss-udp] %s <-> %s", raddr, c.tgtAddr)
|
log.F("[ssu] %s <-> %s", raddr, c.tgtAddr)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
pc = v.(*PktConn)
|
pc = v.(*PktConn)
|
||||||
@ -219,11 +219,11 @@ func (s *SS) ListenAndServeUDP() {
|
|||||||
|
|
||||||
_, err = pc.WriteTo(buf[:n], pc.writeAddr)
|
_, err = pc.WriteTo(buf[:n], pc.writeAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.F("[ss-udp] remote write error: %v", err)
|
log.F("[ssu] remote write error: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// log.F("[ss-udp] %s <-> %s", raddr, c.tgtAddr)
|
// log.F("[ssu] %s <-> %s", raddr, c.tgtAddr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ func NewPktConn(c net.Conn, tgtAddr socks.Addr) *PktConn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReadFrom implements the necessary function of net.PacketConn.
|
// ReadFrom implements the necessary function of net.PacketConn.
|
||||||
|
// TODO: we know that we use it in proxy.RelayUDP and the length of b is enough, check it later.
|
||||||
func (pc *PktConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
func (pc *PktConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
||||||
// ATYP, DST.ADDR, DST.PORT
|
// ATYP, DST.ADDR, DST.PORT
|
||||||
_, err := socks.ReadAddr(pc.Conn)
|
_, err := socks.ReadAddr(pc.Conn)
|
||||||
@ -50,6 +51,10 @@ func (pc *PktConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
|||||||
return 0, nil, err
|
return 0, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(b) < length {
|
||||||
|
return 0, nil, errors.New("buf size is not enough")
|
||||||
|
}
|
||||||
|
|
||||||
// Payload
|
// Payload
|
||||||
n, err := io.ReadFull(pc.Conn, b[:length])
|
n, err := io.ReadFull(pc.Conn, b[:length])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -69,5 +74,6 @@ func (pc *PktConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
|||||||
binary.Write(buf, binary.BigEndian, uint16(len(b)))
|
binary.Write(buf, binary.BigEndian, uint16(len(b)))
|
||||||
buf.WriteString("\r\n")
|
buf.WriteString("\r\n")
|
||||||
buf.Write(b)
|
buf.Write(b)
|
||||||
|
|
||||||
return pc.Write(buf.Bytes())
|
return pc.Write(buf.Bytes())
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,8 @@ type Conn struct {
|
|||||||
rcved bool
|
rcved bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConn returns a new vless client conn.
|
// ClientConn returns a new vless client conn.
|
||||||
func NewConn(c net.Conn, uuid [16]byte, target string) (*Conn, error) {
|
func ClientConn(c net.Conn, uuid [16]byte, network, target string) (*Conn, error) {
|
||||||
atyp, addr, port, err := ParseAddr(target)
|
atyp, addr, port, err := ParseAddr(target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -40,7 +40,12 @@ func NewConn(c net.Conn, uuid [16]byte, target string) (*Conn, error) {
|
|||||||
buf.WriteByte(Version) // ver
|
buf.WriteByte(Version) // ver
|
||||||
buf.Write(uuid[:]) // uuid
|
buf.Write(uuid[:]) // uuid
|
||||||
buf.WriteByte(0) // addLen
|
buf.WriteByte(0) // addLen
|
||||||
buf.WriteByte(CmdTCP) // cmd
|
|
||||||
|
cmd := CmdTCP
|
||||||
|
if network == "udp" {
|
||||||
|
cmd = CmdUDP
|
||||||
|
}
|
||||||
|
buf.WriteByte(cmd) // cmd
|
||||||
|
|
||||||
// target
|
// target
|
||||||
err = binary.Write(buf, binary.BigEndian, uint16(port)) // port
|
err = binary.Write(buf, binary.BigEndian, uint16(port)) // port
|
||||||
|
53
proxy/vless/packet.go
Normal file
53
proxy/vless/packet.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package vless
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/nadoo/glider/pool"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PktConn .
|
||||||
|
type PktConn struct {
|
||||||
|
net.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPktConn returns a PktConn.
|
||||||
|
func NewPktConn(c net.Conn) *PktConn {
|
||||||
|
return &PktConn{Conn: c}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadFrom implements the necessary function of net.PacketConn.
|
||||||
|
// TODO: we know that we use it in proxy.RelayUDP and the length of b is enough, check it later.
|
||||||
|
func (pc *PktConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
||||||
|
// Length
|
||||||
|
if _, err := io.ReadFull(pc.Conn, b[:2]); err != nil {
|
||||||
|
return 0, nil, err
|
||||||
|
}
|
||||||
|
length := int(binary.BigEndian.Uint16(b[:2]))
|
||||||
|
|
||||||
|
if len(b) < length {
|
||||||
|
return 0, nil, errors.New("buf size is not enough")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Payload
|
||||||
|
n, err := io.ReadFull(pc.Conn, b[:length])
|
||||||
|
if err != nil {
|
||||||
|
return 0, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return n, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo implements the necessary function of net.PacketConn.
|
||||||
|
func (pc *PktConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
||||||
|
buf := pool.GetWriteBuffer()
|
||||||
|
defer pool.PutWriteBuffer(buf)
|
||||||
|
|
||||||
|
binary.Write(buf, binary.BigEndian, uint16(len(b)))
|
||||||
|
buf.Write(b)
|
||||||
|
|
||||||
|
return pc.Write(buf.Bytes())
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package vless
|
package vless
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
@ -60,10 +59,15 @@ func (s *VLess) Dial(network, addr string) (net.Conn, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return NewConn(rc, s.uuid, addr)
|
return ClientConn(rc, s.uuid, network, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialUDP connects to the given address via the proxy.
|
// DialUDP connects to the given address via the proxy.
|
||||||
func (s *VLess) DialUDP(network, addr string) (net.PacketConn, net.Addr, error) {
|
func (s *VLess) DialUDP(network, addr string) (net.PacketConn, net.Addr, error) {
|
||||||
return nil, nil, errors.New("vless client does not support udp now")
|
c, err := s.Dial("udp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pkc := NewPktConn(c)
|
||||||
|
return pkc, nil, nil
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/nadoo/glider/pool"
|
|
||||||
"golang.org/x/crypto/chacha20poly1305"
|
"golang.org/x/crypto/chacha20poly1305"
|
||||||
|
|
||||||
|
"github.com/nadoo/glider/pool"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Request Options
|
// Request Options
|
||||||
|
@ -226,9 +226,8 @@ func checkWebSite(fwdr *Forwarder, website string, timeout time.Duration, buf []
|
|||||||
|
|
||||||
rc, err := fwdr.Dial("tcp", website)
|
rc, err := fwdr.Dial("tcp", website)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.F("[check] %s(%d) -> %s, FAILED. error in dial: %s", fwdr.Addr(), fwdr.Priority(), website, err)
|
||||||
fwdr.Disable()
|
fwdr.Disable()
|
||||||
log.F("[check] %s(%d) -> %s, FAILED. error in dial: %s", fwdr.Addr(), fwdr.Priority(),
|
|
||||||
website, err)
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
defer rc.Close()
|
defer rc.Close()
|
||||||
@ -239,24 +238,21 @@ func checkWebSite(fwdr *Forwarder, website string, timeout time.Duration, buf []
|
|||||||
|
|
||||||
_, err = io.WriteString(rc, "GET / HTTP/1.0\r\n\r\n")
|
_, err = io.WriteString(rc, "GET / HTTP/1.0\r\n\r\n")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.F("[check] %s(%d) -> %s, FAILED. error in write: %s", fwdr.Addr(), fwdr.Priority(), website, err)
|
||||||
fwdr.Disable()
|
fwdr.Disable()
|
||||||
log.F("[check] %s(%d) -> %s, FAILED. error in write: %s", fwdr.Addr(), fwdr.Priority(),
|
|
||||||
website, err)
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = io.ReadFull(rc, buf)
|
_, err = io.ReadFull(rc, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.F("[check] %s(%d) -> %s, FAILED. error in read: %s", fwdr.Addr(), fwdr.Priority(), website, err)
|
||||||
fwdr.Disable()
|
fwdr.Disable()
|
||||||
log.F("[check] %s(%d) -> %s, FAILED. error in read: %s", fwdr.Addr(), fwdr.Priority(),
|
|
||||||
website, err)
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.Equal([]byte("HTTP"), buf) {
|
if !bytes.Equal([]byte("HTTP"), buf) {
|
||||||
|
log.F("[check] %s(%d) -> %s, FAILED. server response: %s", fwdr.Addr(), fwdr.Priority(), website, buf)
|
||||||
fwdr.Disable()
|
fwdr.Disable()
|
||||||
log.F("[check] %s(%d) -> %s, FAILED. server response: %s", fwdr.Addr(), fwdr.Priority(),
|
|
||||||
website, buf)
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,15 +260,13 @@ func checkWebSite(fwdr *Forwarder, website string, timeout time.Duration, buf []
|
|||||||
fwdr.SetLatency(int64(readTime))
|
fwdr.SetLatency(int64(readTime))
|
||||||
|
|
||||||
if readTime > timeout {
|
if readTime > timeout {
|
||||||
|
log.F("[check] %s(%d) -> %s, FAILED. check timeout: %s", fwdr.Addr(), fwdr.Priority(), website, readTime)
|
||||||
fwdr.Disable()
|
fwdr.Disable()
|
||||||
log.F("[check] %s(%d) -> %s, FAILED. check timeout: %s", fwdr.Addr(), fwdr.Priority(),
|
|
||||||
website, readTime)
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.F("[check] %s(%d) -> %s, SUCCESS. elapsed time: %s", fwdr.Addr(), fwdr.Priority(), website, readTime)
|
||||||
fwdr.Enable()
|
fwdr.Enable()
|
||||||
log.F("[check] %s(%d) -> %s, SUCCESS. connect time: %s", fwdr.Addr(), fwdr.Priority(),
|
|
||||||
website, readTime)
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user