diff --git a/README.md b/README.md index 0695706..7498a75 100644 --- a/README.md +++ b/README.md @@ -306,7 +306,7 @@ Examples: Services: dhcpd: service=dhcpd,INTERFACE,START_IP,END_IP - e.g.,service=dhcpd,en0,192.168.50.100,192.168.50.199 + e.g.,service=dhcpd,eth1,192.168.50.100,192.168.50.199 ``` @@ -335,7 +335,7 @@ glider -config CONFIGPATH -listen :8080 -verbose - dhcpd: - service=dhcpd,INTERFACE,START_IP,END_IP - - e.g., service=dhcpd,en0,192.168.50.100,192.168.50.199 + - e.g., service=dhcpd,eth1,192.168.50.100,192.168.50.199 ## Linux Service diff --git a/config.go b/config.go index cefbede..24e0449 100644 --- a/config.go +++ b/config.go @@ -321,6 +321,6 @@ func usage() { fmt.Fprintf(w, "Services:\n") fmt.Fprintf(w, " dhcpd: service=dhcpd,INTERFACE,START_IP,END_IP\n") - fmt.Fprintf(w, " e.g.,service=dhcpd,en0,192.168.50.100,192.168.50.199\n") + fmt.Fprintf(w, " e.g.,service=dhcpd,eth1,192.168.50.100,192.168.50.199\n") fmt.Fprintf(w, "\n") } diff --git a/config/glider.conf.example b/config/glider.conf.example index fb309e0..1c55e60 100644 --- a/config/glider.conf.example +++ b/config/glider.conf.example @@ -221,7 +221,7 @@ dnsrecord=www.example.com/2606:2800:220:1:248:1893:25c8:1946 # SERVICES # service=dhcpd,INTERFACE,START_IP,END_IP # e.g.: -# service=dhcpd,en0,192.168.50.100,192.168.50.199 +# service=dhcpd,eth1,192.168.50.100,192.168.50.199 # INTERFACE SPECIFIC # ------------------ diff --git a/proxy/ss/server.go b/proxy/ss/server.go index 953bc2d..d75953d 100644 --- a/proxy/ss/server.go +++ b/proxy/ss/server.go @@ -67,7 +67,7 @@ func (s *SS) Serve(c net.Conn) { if uot && dialer.Addr() == "DIRECT" { rc, err := net.ListenPacket("udp", "") if err != nil { - log.F("[ssuot] UDP remote listen error: %v", err) + log.F("[ss] UDP remote listen error: %v", err) } defer rc.Close() @@ -76,7 +76,7 @@ func (s *SS) Serve(c net.Conn) { n, err := c.Read(buf) if err != nil { - log.F("[ssuot] error in read: %s\n", err) + log.F("[ss] error in read: %s\n", err) return } @@ -85,7 +85,7 @@ func (s *SS) Serve(c net.Conn) { n, _, err = rc.ReadFrom(buf) if err != nil { - log.F("[ssuot] read error: %v", err) + log.F("[ss] read error: %v", err) } c.Write(buf[:n]) diff --git a/proxy/vless/server.go b/proxy/vless/server.go index 58b0fb9..4612d2d 100644 --- a/proxy/vless/server.go +++ b/proxy/vless/server.go @@ -2,6 +2,7 @@ package vless import ( "bytes" + "encoding/binary" "fmt" "io" "io/ioutil" @@ -61,18 +62,18 @@ func (s *VLess) Serve(c net.Conn) { return } - switch cmd { - case CmdTCP: - s.ServeTCP(c, tgt) - case CmdUDP: - s.ServeUOT(c, tgt) - } -} - -// ServeTCP serves tcp requests. -func (s *VLess) ServeTCP(c net.Conn, tgt string) { + network := "tcp" dialer := s.proxy.NextDialer(tgt) - rc, err := dialer.Dial("tcp", tgt) + if cmd == CmdUDP { + // there is no upstream proxy, just serve it + if dialer.Addr() == "DIRECT" { + s.ServeUoT(c, tgt) + return + } + network = "udp" + } + + rc, err := dialer.Dial(network, tgt) if err != nil { log.F("[vless] %s <-> %s via %s, error in dial: %v", c.RemoteAddr(), tgt, dialer.Addr(), err) return @@ -91,7 +92,61 @@ func (s *VLess) ServeTCP(c net.Conn, tgt string) { } // ServeUOT serves udp over tcp requests. -func (s *VLess) ServeUOT(c net.Conn, tgt string) { +func (s *VLess) ServeUoT(c net.Conn, tgt string) { + rc, err := net.ListenPacket("udp", "") + if err != nil { + log.F("[vless] UDP remote listen error: %v", err) + return + } + defer rc.Close() + + tgtAddr, err := net.ResolveUDPAddr("udp", tgt) + if err != nil { + log.F("[vless] error in ResolveUDPAddr: %v", err) + return + } + + go func() { + buf := pool.GetBuffer(proxy.UDPBufSize) + defer pool.PutBuffer(buf) + for { + _, err := io.ReadFull(c, buf[:2]) + if err != nil { + log.F("[vless] read c error: %s\n", err) + return + } + + length := binary.BigEndian.Uint16(buf[:2]) + n, err := io.ReadFull(c, buf[:length]) + + _, err = rc.WriteTo(buf[:n], tgtAddr) + if err != nil { + log.F("[vless] write rc error: %s\n", err) + return + } + } + }() + + log.F("[vless] %s <-tcp-> %s - %s <-udp-> %s via DIRECT", c.RemoteAddr(), c.LocalAddr(), rc.LocalAddr(), tgt) + + buf := pool.GetBuffer(proxy.UDPBufSize) + defer pool.PutBuffer(buf) + + for { + n, _, err := rc.ReadFrom(buf[2:]) + if err != nil { + log.F("[vless] read rc error: %v", err) + break + } + + binary.BigEndian.PutUint16(buf[:2], uint16(n)) + _, err = c.Write(buf[:2+n]) + if err != nil { + log.F("[vless] write c error: %v", err) + break + } + } + } func (s *VLess) readHeader(r io.Reader) (CmdType, error) {