mirror of
				https://github.com/nadoo/glider.git
				synced 2025-11-04 07:42:38 +08:00 
			
		
		
		
	ssr: add ssr support
This commit is contained in:
		
							parent
							
								
									d4a1d59d31
								
							
						
					
					
						commit
						2e6ab5767a
					
				@ -48,6 +48,8 @@ func DialerFromURL(s string, dialer Dialer) (Dialer, error) {
 | 
				
			|||||||
		return NewSOCKS5(addr, user, pass, dialer)
 | 
							return NewSOCKS5(addr, user, pass, dialer)
 | 
				
			||||||
	case "ss":
 | 
						case "ss":
 | 
				
			||||||
		return NewSS(addr, user, pass, dialer)
 | 
							return NewSS(addr, user, pass, dialer)
 | 
				
			||||||
 | 
						case "ssr":
 | 
				
			||||||
 | 
							return NewSSR(addr, user, pass, u.RawQuery, dialer)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil, errors.New("unknown schema '" + u.Scheme + "'")
 | 
						return nil, errors.New("unknown schema '" + u.Scheme + "'")
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										12
									
								
								http.go
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								http.go
									
									
									
									
									
								
							@ -69,7 +69,7 @@ func (s *HTTP) ListenAndServe() {
 | 
				
			|||||||
	for {
 | 
						for {
 | 
				
			||||||
		c, err := l.Accept()
 | 
							c, err := l.Accept()
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			logf("failed to accept: %v", err)
 | 
								logf("proxy-http failed to accept: %v", err)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -130,7 +130,7 @@ func (s *HTTP) Serve(c net.Conn) {
 | 
				
			|||||||
	rc, err := s.dialer.Dial("tcp", tgt)
 | 
						rc, err := s.dialer.Dial("tcp", tgt)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Fprintf(c, "%s 502 ERROR\r\n\r\n", proto)
 | 
							fmt.Fprintf(c, "%s 502 ERROR\r\n\r\n", proto)
 | 
				
			||||||
		logf("failed to dial: %v", err)
 | 
							logf("proxy-http failed to dial: %v", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer rc.Close()
 | 
						defer rc.Close()
 | 
				
			||||||
@ -164,7 +164,7 @@ func (s *HTTP) Serve(c net.Conn) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	respHeader, err := respTP.ReadMIMEHeader()
 | 
						respHeader, err := respTP.ReadMIMEHeader()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		logf("read header error:%s", err)
 | 
							logf("proxy-http read header error:%s", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -191,7 +191,7 @@ func (s *HTTP) servHTTPS(method, requestURI, proto string, c net.Conn) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		c.Write([]byte(proto))
 | 
							c.Write([]byte(proto))
 | 
				
			||||||
		c.Write([]byte(" 502 ERROR\r\n\r\n"))
 | 
							c.Write([]byte(" 502 ERROR\r\n\r\n"))
 | 
				
			||||||
		logf("failed to dial: %v", err)
 | 
							logf("proxy-http failed to dial: %v", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -218,7 +218,7 @@ func (s *HTTP) NextDialer(dstAddr string) Dialer { return s.dialer.NextDialer(ds
 | 
				
			|||||||
func (s *HTTP) Dial(network, addr string) (net.Conn, error) {
 | 
					func (s *HTTP) Dial(network, addr string) (net.Conn, error) {
 | 
				
			||||||
	rc, err := s.dialer.Dial(network, s.addr)
 | 
						rc, err := s.dialer.Dial(network, s.addr)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		logf("dial to %s error: %s", s.addr, err)
 | 
							logf("proxy-http dial to %s error: %s", s.addr, err)
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -261,7 +261,7 @@ func parseFirstLine(tp *textproto.Reader) (r1, r2, r3 string, ok bool) {
 | 
				
			|||||||
	line, err := tp.ReadLine()
 | 
						line, err := tp.ReadLine()
 | 
				
			||||||
	// logf("first line: %s", line)
 | 
						// logf("first line: %s", line)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		logf("read request line error:%s", err)
 | 
							logf("proxy-http read request line error:%s", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										4
									
								
								ss.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								ss.go
									
									
									
									
									
								
							@ -210,7 +210,7 @@ func (s *SS) NextDialer(dstAddr string) Dialer { return s.dialer.NextDialer(dstA
 | 
				
			|||||||
func (s *SS) Dial(network, addr string) (net.Conn, error) {
 | 
					func (s *SS) Dial(network, addr string) (net.Conn, error) {
 | 
				
			||||||
	target := ParseAddr(addr)
 | 
						target := ParseAddr(addr)
 | 
				
			||||||
	if target == nil {
 | 
						if target == nil {
 | 
				
			||||||
		return nil, errors.New("Unable to parse address: " + addr)
 | 
							return nil, errors.New("proxy-ss unable to parse address: " + addr)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if network == "uot" {
 | 
						if network == "uot" {
 | 
				
			||||||
@ -219,7 +219,7 @@ func (s *SS) Dial(network, addr string) (net.Conn, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	c, err := s.dialer.Dial("tcp", s.addr)
 | 
						c, err := s.dialer.Dial("tcp", s.addr)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		logf("dial to %s error: %s", s.addr, err)
 | 
							logf("proxy-ss dial to %s error: %s", s.addr, err)
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										132
									
								
								ssr.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								ssr.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,132 @@
 | 
				
			|||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						shadowsocksr "github.com/sun8911879/shadowsocksR"
 | 
				
			||||||
 | 
						"github.com/sun8911879/shadowsocksR/obfs"
 | 
				
			||||||
 | 
						"github.com/sun8911879/shadowsocksR/protocol"
 | 
				
			||||||
 | 
						"github.com/sun8911879/shadowsocksR/ssr"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SSR .
 | 
				
			||||||
 | 
					type SSR struct {
 | 
				
			||||||
 | 
						dialer Dialer
 | 
				
			||||||
 | 
						addr   string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						EncryptMethod   string
 | 
				
			||||||
 | 
						EncryptPassword string
 | 
				
			||||||
 | 
						Obfs            string
 | 
				
			||||||
 | 
						ObfsParam       string
 | 
				
			||||||
 | 
						ObfsData        interface{}
 | 
				
			||||||
 | 
						Protocol        string
 | 
				
			||||||
 | 
						ProtocolParam   string
 | 
				
			||||||
 | 
						ProtocolData    interface{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewSSR returns a shadowsocksr proxy, ssr://method:pass@host:port/rawQuery
 | 
				
			||||||
 | 
					func NewSSR(addr, method, pass, rawQuery string, dialer Dialer) (*SSR, error) {
 | 
				
			||||||
 | 
						s := &SSR{
 | 
				
			||||||
 | 
							dialer:          dialer,
 | 
				
			||||||
 | 
							addr:            addr,
 | 
				
			||||||
 | 
							EncryptMethod:   method,
 | 
				
			||||||
 | 
							EncryptPassword: pass,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p, _ := url.ParseQuery(rawQuery)
 | 
				
			||||||
 | 
						if v, ok := p["protocol"]; ok {
 | 
				
			||||||
 | 
							s.Protocol = v[0]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if v, ok := p["protocol_param"]; ok {
 | 
				
			||||||
 | 
							s.ProtocolParam = v[0]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if v, ok := p["obfs"]; ok {
 | 
				
			||||||
 | 
							s.Obfs = v[0]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if v, ok := p["obfs_param"]; ok {
 | 
				
			||||||
 | 
							s.ObfsParam = v[0]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return s, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Addr returns forwarder's address
 | 
				
			||||||
 | 
					func (s *SSR) Addr() string { return s.addr }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NextDialer returns the next dialer
 | 
				
			||||||
 | 
					func (s *SSR) NextDialer(dstAddr string) Dialer { return s.dialer.NextDialer(dstAddr) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Dial connects to the address addr on the network net via the proxy.
 | 
				
			||||||
 | 
					func (s *SSR) Dial(network, addr string) (net.Conn, error) {
 | 
				
			||||||
 | 
						target := ParseAddr(addr)
 | 
				
			||||||
 | 
						if target == nil {
 | 
				
			||||||
 | 
							return nil, errors.New("proxy-ssr unable to parse address: " + addr)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cipher, err := shadowsocksr.NewStreamCipher(s.EncryptMethod, s.EncryptPassword)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c, err := s.dialer.Dial("tcp", s.addr)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logf("proxy-ssr dial to %s error: %s", s.addr, err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if c, ok := c.(*net.TCPConn); ok {
 | 
				
			||||||
 | 
							c.SetKeepAlive(true)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ssrconn := shadowsocksr.NewSSTCPConn(c, cipher)
 | 
				
			||||||
 | 
						if ssrconn.Conn == nil || ssrconn.RemoteAddr() == nil {
 | 
				
			||||||
 | 
							return nil, errors.New("proxy-ssr nil connection")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// should initialize obfs/protocol now
 | 
				
			||||||
 | 
						rs := strings.Split(ssrconn.RemoteAddr().String(), ":")
 | 
				
			||||||
 | 
						port, _ := strconv.Atoi(rs[1])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ssrconn.IObfs = obfs.NewObfs(s.Obfs)
 | 
				
			||||||
 | 
						obfsServerInfo := &ssr.ServerInfoForObfs{
 | 
				
			||||||
 | 
							Host:   rs[0],
 | 
				
			||||||
 | 
							Port:   uint16(port),
 | 
				
			||||||
 | 
							TcpMss: 1460,
 | 
				
			||||||
 | 
							Param:  s.ObfsParam,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ssrconn.IObfs.SetServerInfo(obfsServerInfo)
 | 
				
			||||||
 | 
						ssrconn.IProtocol = protocol.NewProtocol(s.Protocol)
 | 
				
			||||||
 | 
						protocolServerInfo := &ssr.ServerInfoForObfs{
 | 
				
			||||||
 | 
							Host:   rs[0],
 | 
				
			||||||
 | 
							Port:   uint16(port),
 | 
				
			||||||
 | 
							TcpMss: 1460,
 | 
				
			||||||
 | 
							Param:  s.ProtocolParam,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ssrconn.IProtocol.SetServerInfo(protocolServerInfo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if s.ObfsData == nil {
 | 
				
			||||||
 | 
							s.ObfsData = ssrconn.IObfs.GetData()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ssrconn.IObfs.SetData(s.ObfsData)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if s.ProtocolData == nil {
 | 
				
			||||||
 | 
							s.ProtocolData = ssrconn.IProtocol.GetData()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ssrconn.IProtocol.SetData(s.ProtocolData)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if _, err := ssrconn.Write(target); err != nil {
 | 
				
			||||||
 | 
							ssrconn.Close()
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ssrconn, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DialUDP connects to the given address via the proxy.
 | 
				
			||||||
 | 
					func (s *SSR) DialUDP(network, addr string) (net.PacketConn, net.Addr, error) {
 | 
				
			||||||
 | 
						return nil, nil, errors.New("proxy-ssr udp not supported now")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user