mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 17:35:40 +08:00
ssr: add ssr support
This commit is contained in:
parent
d7c12ab2ab
commit
d406a8edde
@ -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