mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 17:35:40 +08:00
socks5: support udp in client mode
This commit is contained in:
parent
b2d40b69ff
commit
0d9f588e1f
@ -15,7 +15,7 @@ we can set up local listeners as proxy servers, and forward requests to internet
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
Listen(local proxy server):
|
Listen (local proxy server):
|
||||||
- Socks5 proxy(tcp&udp)
|
- Socks5 proxy(tcp&udp)
|
||||||
- Http proxy(tcp)
|
- Http proxy(tcp)
|
||||||
- SS proxy(tcp&udp)
|
- SS proxy(tcp&udp)
|
||||||
@ -25,12 +25,12 @@ Listen(local proxy server):
|
|||||||
- UDP over TCP tunnel
|
- UDP over TCP tunnel
|
||||||
- DNS Tunnel(udp2tcp)
|
- DNS Tunnel(udp2tcp)
|
||||||
|
|
||||||
Forward(upstream proxy server):
|
Forward (local proxy client/upstream proxy server):
|
||||||
- Socks5 proxy(tcp)
|
- Socks5 proxy(tcp)
|
||||||
- Http proxy(tcp)
|
- Http proxy(tcp)
|
||||||
- SS proxy(tcp&udp&uot)
|
- SS proxy(tcp&udp&uot)
|
||||||
|
|
||||||
DNS Forwarding Server(udp2tcp):
|
DNS Forwarding Server (udp2tcp):
|
||||||
- Listen on UDP and forward dns requests to remote dns server in TCP via forwarders
|
- Listen on UDP and forward dns requests to remote dns server in TCP via forwarders
|
||||||
- Specify different upstream dns server based on destinations(in rule file)
|
- Specify different upstream dns server based on destinations(in rule file)
|
||||||
- Tunnel mode: forward to a fixed upstream dns server
|
- Tunnel mode: forward to a fixed upstream dns server
|
||||||
|
57
socks5.go
57
socks5.go
@ -1,3 +1,5 @@
|
|||||||
|
// https://tools.ietf.org/html/rfc1928
|
||||||
|
|
||||||
// socks5 client:
|
// socks5 client:
|
||||||
// https://github.com/golang/net/tree/master/proxy
|
// https://github.com/golang/net/tree/master/proxy
|
||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
@ -237,7 +239,56 @@ func (s *SOCKS5) 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 *SOCKS5) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error) {
|
func (s *SOCKS5) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error) {
|
||||||
return nil, nil, errors.New("sock5 client does not support udp now")
|
// TODO: keep tcp connection until udp ended
|
||||||
|
c, err := s.cDialer.Dial("tcp", s.addr)
|
||||||
|
if err != nil {
|
||||||
|
logf("proxy-socks5 dialudp dial tcp to %s error: %s", s.addr, err)
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if c, ok := c.(*net.TCPConn); ok {
|
||||||
|
c.SetKeepAlive(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// send VER, NMETHODS, METHODS
|
||||||
|
c.Write([]byte{5, 1, 0})
|
||||||
|
|
||||||
|
buf := make([]byte, MaxAddrLen)
|
||||||
|
// read VER METHOD
|
||||||
|
if _, err := io.ReadFull(c, buf[:2]); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
dstAddr := ParseAddr(s.Addr())
|
||||||
|
// write VER CMD RSV ATYP DST.ADDR DST.PORT
|
||||||
|
c.Write(append([]byte{5, socks5UDPAssociate, 0}, dstAddr...))
|
||||||
|
|
||||||
|
// read VER REP RSV ATYP DST.ADDR DST.PORT
|
||||||
|
if _, err := io.ReadFull(c, buf[:3]); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rep := buf[1]
|
||||||
|
if rep != 0 {
|
||||||
|
logf("proxy-socks5 server reply: %d, not succeeded", rep)
|
||||||
|
return nil, nil, errors.New("server connect failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
uAddr, err := readAddr(c, buf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
logf("proxy-socks5 udp dial uAddr: %s", uAddr)
|
||||||
|
|
||||||
|
pc, nextHop, err := s.cDialer.DialUDP(network, uAddr.String())
|
||||||
|
if err != nil {
|
||||||
|
logf("proxy-socks5 dialudp to %s error: %s", uAddr.String(), err)
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pkc := NewSocks5PktConn(pc, nextHop, ParseAddr(addr), true)
|
||||||
|
return pkc, nextHop, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect takes an existing connection to a socks5 proxy server,
|
// connect takes an existing connection to a socks5 proxy server,
|
||||||
@ -602,6 +653,8 @@ func (pc *Socks5PktConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
|||||||
return pc.PacketConn.WriteTo(b, addr)
|
return pc.PacketConn.WriteTo(b, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := append(append([]byte{0, 0, 0}, b[:]...))
|
// buf := append([]byte{0, 0, 0}, b[:]...)
|
||||||
|
buf := append([]byte{0, 0, 0}, pc.tgtAddr...)
|
||||||
|
buf = append(buf, b[:]...)
|
||||||
return pc.PacketConn.WriteTo(buf, pc.writeAddr)
|
return pc.PacketConn.WriteTo(buf, pc.writeAddr)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user