mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 01:15:41 +08:00
vless: support fallback to a http server
This commit is contained in:
parent
422869b37a
commit
829a0d7f80
20
.github/workflows/docker.yml
vendored
20
.github/workflows/docker.yml
vendored
@ -1,20 +0,0 @@
|
||||
name: Publish Docker image
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
push_to_registry:
|
||||
name: Push Docker image to Docker Hub
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@v2
|
||||
- name: Push to Docker Hub
|
||||
uses: docker/build-push-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
repository: nadoo/glider
|
||||
tag_with_ref: true
|
||||
|
@ -167,7 +167,7 @@ VMess scheme:
|
||||
vmess://[security:]uuid@host:port?alterID=num
|
||||
|
||||
VLESS scheme:
|
||||
vless://uuid@host:port
|
||||
vless://uuid@host:port[?fallback=127.0.0.1:80]
|
||||
|
||||
Trojan scheme:
|
||||
trojan://pass@host:port[?skipVerify=true]
|
||||
|
@ -162,7 +162,7 @@ func usage() {
|
||||
fmt.Fprintf(w, "\n")
|
||||
|
||||
fmt.Fprintf(w, "VLESS scheme:\n")
|
||||
fmt.Fprintf(w, " vless://uuid@host:port\n")
|
||||
fmt.Fprintf(w, " vless://uuid@host:port[?fallback=127.0.0.1:80]\n")
|
||||
fmt.Fprintf(w, "\n")
|
||||
|
||||
fmt.Fprintf(w, "Trojan scheme:\n")
|
||||
|
@ -45,6 +45,8 @@ listen=socks5://:1080
|
||||
|
||||
# listen on 1234 as vless proxy server.
|
||||
# listen=vless://uuid@:1234
|
||||
# listen on 1234 as vless proxy server, fallback to 127.0.0.1:8080 http server when client auth failed.
|
||||
# listen=vless://uuid@:1234?fallback=127.0.0.1:8080
|
||||
|
||||
# listen on 1081 as a linux transparent proxy server.
|
||||
# listen=redir://:1081
|
||||
|
@ -49,41 +49,62 @@ func (s *VLess) Serve(c net.Conn) {
|
||||
c.SetKeepAlive(true)
|
||||
}
|
||||
|
||||
c = NewServerConn(c)
|
||||
cmd, err := s.readHeader(c)
|
||||
if err != nil {
|
||||
log.F("[vless] verify header error: %v", err)
|
||||
return
|
||||
}
|
||||
var fallback bool
|
||||
var dialer proxy.Dialer
|
||||
target := s.fallback
|
||||
|
||||
tgt, err := ReadAddrString(c)
|
||||
wbuf := pool.GetWriteBuffer()
|
||||
defer pool.PutWriteBuffer(wbuf)
|
||||
|
||||
cmd, err := s.readHeader(io.TeeReader(c, wbuf))
|
||||
if err != nil {
|
||||
log.F("[vless] get target error: %v", err)
|
||||
return
|
||||
if s.fallback == "" {
|
||||
log.F("[vless] verify header error: %v", err)
|
||||
return
|
||||
}
|
||||
fallback = true
|
||||
log.F("[vless] verify header error: %v, fallback to %s", err, s.fallback)
|
||||
}
|
||||
|
||||
network := "tcp"
|
||||
dialer := s.proxy.NextDialer(tgt)
|
||||
if cmd == CmdUDP {
|
||||
// there is no upstream proxy, just serve it
|
||||
if dialer.Addr() == "DIRECT" {
|
||||
s.ServeUoT(c, tgt)
|
||||
dialer = s.proxy.NextDialer(target)
|
||||
if !fallback {
|
||||
c = NewServerConn(c)
|
||||
target, err = ReadAddrString(c)
|
||||
if err != nil {
|
||||
log.F("[vless] get target error: %v", err)
|
||||
return
|
||||
}
|
||||
network = "udp"
|
||||
|
||||
if cmd == CmdUDP {
|
||||
// there is no upstream proxy, just serve it
|
||||
if dialer.Addr() == "DIRECT" {
|
||||
s.ServeUoT(c, target)
|
||||
return
|
||||
}
|
||||
network = "udp"
|
||||
}
|
||||
}
|
||||
|
||||
rc, err := dialer.Dial(network, tgt)
|
||||
rc, err := dialer.Dial(network, target)
|
||||
if err != nil {
|
||||
log.F("[vless] %s <-> %s via %s, error in dial: %v", c.RemoteAddr(), tgt, dialer.Addr(), err)
|
||||
log.F("[vless] %s <-> %s via %s, error in dial: %v", c.RemoteAddr(), target, dialer.Addr(), err)
|
||||
return
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
log.F("[vless] %s <-> %s via %s", c.RemoteAddr(), tgt, dialer.Addr())
|
||||
if fallback {
|
||||
_, err := rc.Write(wbuf.Bytes())
|
||||
if err != nil {
|
||||
log.F("[vless] write to rc error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
log.F("[vless] %s <-> %s via %s", c.RemoteAddr(), target, dialer.Addr())
|
||||
|
||||
if err = proxy.Relay(c, rc); err != nil {
|
||||
log.F("[vless] %s <-> %s via %s, relay error: %v", c.RemoteAddr(), tgt, dialer.Addr(), err)
|
||||
log.F("[vless] %s <-> %s via %s, relay error: %v", c.RemoteAddr(), target, dialer.Addr(), err)
|
||||
// record remote conn failure only
|
||||
if !strings.Contains(err.Error(), s.addr) {
|
||||
s.proxy.Record(dialer, false)
|
||||
@ -91,7 +112,7 @@ func (s *VLess) Serve(c net.Conn) {
|
||||
}
|
||||
}
|
||||
|
||||
// ServeUOT serves udp over tcp requests.
|
||||
// ServeUoT serves udp over tcp requests.
|
||||
func (s *VLess) ServeUoT(c net.Conn, tgt string) {
|
||||
rc, err := net.ListenPacket("udp", "")
|
||||
if err != nil {
|
||||
@ -118,6 +139,10 @@ func (s *VLess) ServeUoT(c net.Conn, tgt string) {
|
||||
|
||||
length := binary.BigEndian.Uint16(buf[:2])
|
||||
n, err := io.ReadFull(c, buf[:length])
|
||||
if err != nil {
|
||||
log.F("[vless] read payload error: %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = rc.WriteTo(buf[:n], tgtAddr)
|
||||
if err != nil {
|
||||
@ -127,7 +152,7 @@ func (s *VLess) ServeUoT(c net.Conn, tgt string) {
|
||||
}
|
||||
}()
|
||||
|
||||
log.F("[vless] %s <-tcp-> %s - %s <-udp-> %s via DIRECT", c.RemoteAddr(), c.LocalAddr(), rc.LocalAddr(), tgt)
|
||||
log.F("[vless] %s <-tcp-> %s - %s <-udp-> %s", c.RemoteAddr(), c.LocalAddr(), rc.LocalAddr(), tgt)
|
||||
|
||||
buf := pool.GetBuffer(proxy.UDPBufSize)
|
||||
defer pool.PutBuffer(buf)
|
||||
|
@ -24,10 +24,11 @@ const (
|
||||
|
||||
// VLess struct.
|
||||
type VLess struct {
|
||||
dialer proxy.Dialer
|
||||
proxy proxy.Proxy
|
||||
addr string
|
||||
uuid [16]byte
|
||||
dialer proxy.Dialer
|
||||
proxy proxy.Proxy
|
||||
addr string
|
||||
uuid [16]byte
|
||||
fallback string
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -55,6 +56,11 @@ func NewVLess(s string, d proxy.Dialer, p proxy.Proxy) (*VLess, error) {
|
||||
uuid: uuid,
|
||||
}
|
||||
|
||||
v.fallback = "127.0.0.1:80"
|
||||
if custom := u.Query().Get("fallback"); custom != "" {
|
||||
v.fallback = custom
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user