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)
|
||||
case "ss":
|
||||
return NewSS(addr, user, pass, dialer)
|
||||
case "ssr":
|
||||
return NewSSR(addr, user, pass, u.RawQuery, dialer)
|
||||
}
|
||||
|
||||
return nil, errors.New("unknown schema '" + u.Scheme + "'")
|
||||
|
12
http.go
12
http.go
@ -69,7 +69,7 @@ func (s *HTTP) ListenAndServe() {
|
||||
for {
|
||||
c, err := l.Accept()
|
||||
if err != nil {
|
||||
logf("failed to accept: %v", err)
|
||||
logf("proxy-http failed to accept: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
@ -130,7 +130,7 @@ func (s *HTTP) Serve(c net.Conn) {
|
||||
rc, err := s.dialer.Dial("tcp", tgt)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
defer rc.Close()
|
||||
@ -164,7 +164,7 @@ func (s *HTTP) Serve(c net.Conn) {
|
||||
|
||||
respHeader, err := respTP.ReadMIMEHeader()
|
||||
if err != nil {
|
||||
logf("read header error:%s", err)
|
||||
logf("proxy-http read header error:%s", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -191,7 +191,7 @@ func (s *HTTP) servHTTPS(method, requestURI, proto string, c net.Conn) {
|
||||
if err != nil {
|
||||
c.Write([]byte(proto))
|
||||
c.Write([]byte(" 502 ERROR\r\n\r\n"))
|
||||
logf("failed to dial: %v", err)
|
||||
logf("proxy-http failed to dial: %v", err)
|
||||
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) {
|
||||
rc, err := s.dialer.Dial(network, s.addr)
|
||||
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
|
||||
}
|
||||
|
||||
@ -261,7 +261,7 @@ func parseFirstLine(tp *textproto.Reader) (r1, r2, r3 string, ok bool) {
|
||||
line, err := tp.ReadLine()
|
||||
// logf("first line: %s", line)
|
||||
if err != nil {
|
||||
logf("read request line error:%s", err)
|
||||
logf("proxy-http read request line error:%s", err)
|
||||
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) {
|
||||
target := ParseAddr(addr)
|
||||
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" {
|
||||
@ -219,7 +219,7 @@ func (s *SS) Dial(network, addr string) (net.Conn, error) {
|
||||
|
||||
c, err := s.dialer.Dial("tcp", s.addr)
|
||||
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
|
||||
}
|
||||
|
||||
|
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