ss: add udp over tcp support

This commit is contained in:
nadoo 2017-09-08 12:09:57 +08:00
parent 0e8263ddfa
commit aeb0acab33
3 changed files with 43 additions and 4 deletions

View File

@ -41,7 +41,7 @@ General:
- Rule proxy based on destinations: [Config Examples](config/examples) - Rule proxy based on destinations: [Config Examples](config/examples)
TODO: TODO:
- [ ] UDP over TCP - [x] UDP over TCP (ss)
- [ ] UDP Tunnel - [ ] UDP Tunnel
- [ ] Linux tproxy support & UDP Relay - [ ] Linux tproxy support & UDP Relay
- [ ] TUN/TAP device support - [ ] TUN/TAP device support

View File

@ -57,6 +57,9 @@ func ServerFromURL(s string, sDialer Dialer) (Server, error) {
case "dnstun": case "dnstun":
d := strings.Split(addr, "=") d := strings.Split(addr, "=")
return NewDNSTun(d[0], d[1], sDialer) return NewDNSTun(d[0], d[1], sDialer)
case "uottun":
d := strings.Split(addr, "=")
return NewUoTTun(d[0], d[1], sDialer)
} }
return nil, errors.New("unknown schema '" + u.Scheme + "'") return nil, errors.New("unknown schema '" + u.Scheme + "'")

42
ss.go
View File

@ -12,7 +12,7 @@ import (
"github.com/shadowsocks/go-shadowsocks2/socks" "github.com/shadowsocks/go-shadowsocks2/socks"
) )
const udpBufSize = 64 * 1024 const udpBufSize = 65536
// SS . // SS .
type SS struct { type SS struct {
@ -40,7 +40,7 @@ func NewSS(addr, method, pass string, cDialer Dialer, sDialer Dialer) (*SS, erro
// ListenAndServe serves ss requests. // ListenAndServe serves ss requests.
func (s *SS) ListenAndServe() { func (s *SS) ListenAndServe() {
go s.ListenAndServeUDP() // go s.ListenAndServeUDP()
s.ListenAndServeTCP() s.ListenAndServeTCP()
} }
@ -80,6 +80,37 @@ func (s *SS) ServeTCP(c net.Conn) {
return return
} }
// udp over tcp
if UoT(tgt[0]) {
rc, err := net.ListenPacket("udp", "")
if err != nil {
logf("UDP remote listen error: %v", err)
}
defer rc.Close()
req := make([]byte, udpBufSize)
n, err := c.Read(req)
if err != nil {
logf("error in ioutil.ReadAll: %s\n", err)
return
}
tgtAddr, _ := net.ResolveUDPAddr("udp", tgt.String())
rc.WriteTo(req[:n], tgtAddr)
buf := make([]byte, udpBufSize)
n, _, err = rc.ReadFrom(buf)
if err != nil {
logf("proxy-uottun read error: %v", err)
}
c.Write(buf[:n])
logf("proxy-ss %s <-tcp-> %s <-> %s <-udp-> %s ", c.RemoteAddr(), c.LocalAddr(), rc.LocalAddr(), tgt)
return
}
rc, err := s.sDialer.Dial("tcp", tgt.String()) rc, err := s.sDialer.Dial("tcp", tgt.String())
if err != nil { if err != nil {
logf("proxy-ss failed to connect to target: %v", err) logf("proxy-ss failed to connect to target: %v", err)
@ -171,7 +202,12 @@ func (s *SS) Dial(network, addr string) (net.Conn, error) {
return nil, errors.New("Unable to parse address: " + addr) return nil, errors.New("Unable to parse address: " + addr)
} }
c, err := s.cDialer.Dial(network, s.addr) // udp over tcp tag
if network == "udp" {
target[0] = target[0] | 0x8
}
c, err := s.cDialer.Dial("tcp", s.addr)
if err != nil { if err != nil {
logf("dial to %s error: %s", s.addr, err) logf("dial to %s error: %s", s.addr, err)
return nil, err return nil, err