Feature: support relay (proxy chains) (#539)
This commit is contained in:
@ -21,7 +21,6 @@ import (
|
||||
|
||||
type ShadowSocks struct {
|
||||
*Base
|
||||
server string
|
||||
cipher core.Cipher
|
||||
|
||||
// obfs
|
||||
@ -60,28 +59,34 @@ type v2rayObfsOption struct {
|
||||
Mux bool `obfs:"mux,omitempty"`
|
||||
}
|
||||
|
||||
func (ss *ShadowSocks) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn, error) {
|
||||
c, err := dialer.DialContext(ctx, "tcp", ss.server)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %w", ss.server, err)
|
||||
}
|
||||
tcpKeepAlive(c)
|
||||
func (ss *ShadowSocks) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
|
||||
switch ss.obfsMode {
|
||||
case "tls":
|
||||
c = obfs.NewTLSObfs(c, ss.obfsOption.Host)
|
||||
case "http":
|
||||
_, port, _ := net.SplitHostPort(ss.server)
|
||||
_, port, _ := net.SplitHostPort(ss.addr)
|
||||
c = obfs.NewHTTPObfs(c, ss.obfsOption.Host, port)
|
||||
case "websocket":
|
||||
var err error
|
||||
c, err = v2rayObfs.NewV2rayObfs(c, ss.v2rayOption)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %w", ss.server, err)
|
||||
return nil, fmt.Errorf("%s connect error: %w", ss.addr, err)
|
||||
}
|
||||
}
|
||||
c = ss.cipher.StreamConn(c)
|
||||
_, err = c.Write(serializesSocksAddr(metadata))
|
||||
return newConn(c, ss), err
|
||||
_, err := c.Write(serializesSocksAddr(metadata))
|
||||
return c, err
|
||||
}
|
||||
|
||||
func (ss *ShadowSocks) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn, error) {
|
||||
c, err := dialer.DialContext(ctx, "tcp", ss.addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %w", ss.addr, err)
|
||||
}
|
||||
tcpKeepAlive(c)
|
||||
|
||||
c, err = ss.StreamConn(c, metadata)
|
||||
return NewConn(c, ss), err
|
||||
}
|
||||
|
||||
func (ss *ShadowSocks) DialUDP(metadata *C.Metadata) (C.PacketConn, error) {
|
||||
@ -90,7 +95,7 @@ func (ss *ShadowSocks) DialUDP(metadata *C.Metadata) (C.PacketConn, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr, err := resolveUDPAddr("udp", ss.server)
|
||||
addr, err := resolveUDPAddr("udp", ss.addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -106,12 +111,12 @@ func (ss *ShadowSocks) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
|
||||
func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
|
||||
server := net.JoinHostPort(option.Server, strconv.Itoa(option.Port))
|
||||
addr := net.JoinHostPort(option.Server, strconv.Itoa(option.Port))
|
||||
cipher := option.Cipher
|
||||
password := option.Password
|
||||
ciph, err := core.PickCipher(cipher, nil, password)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ss %s initialize error: %w", server, err)
|
||||
return nil, fmt.Errorf("ss %s initialize error: %w", addr, err)
|
||||
}
|
||||
|
||||
var v2rayOption *v2rayObfs.Option
|
||||
@ -133,22 +138,22 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
|
||||
if option.Plugin == "obfs" {
|
||||
opts := simpleObfsOption{Host: "bing.com"}
|
||||
if err := decoder.Decode(option.PluginOpts, &opts); err != nil {
|
||||
return nil, fmt.Errorf("ss %s initialize obfs error: %w", server, err)
|
||||
return nil, fmt.Errorf("ss %s initialize obfs error: %w", addr, err)
|
||||
}
|
||||
|
||||
if opts.Mode != "tls" && opts.Mode != "http" {
|
||||
return nil, fmt.Errorf("ss %s obfs mode error: %s", server, opts.Mode)
|
||||
return nil, fmt.Errorf("ss %s obfs mode error: %s", addr, opts.Mode)
|
||||
}
|
||||
obfsMode = opts.Mode
|
||||
obfsOption = &opts
|
||||
} else if option.Plugin == "v2ray-plugin" {
|
||||
opts := v2rayObfsOption{Host: "bing.com", Mux: true}
|
||||
if err := decoder.Decode(option.PluginOpts, &opts); err != nil {
|
||||
return nil, fmt.Errorf("ss %s initialize v2ray-plugin error: %w", server, err)
|
||||
return nil, fmt.Errorf("ss %s initialize v2ray-plugin error: %w", addr, err)
|
||||
}
|
||||
|
||||
if opts.Mode != "websocket" {
|
||||
return nil, fmt.Errorf("ss %s obfs mode error: %s", server, opts.Mode)
|
||||
return nil, fmt.Errorf("ss %s obfs mode error: %s", addr, opts.Mode)
|
||||
}
|
||||
obfsMode = opts.Mode
|
||||
|
||||
@ -172,10 +177,10 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
|
||||
return &ShadowSocks{
|
||||
Base: &Base{
|
||||
name: option.Name,
|
||||
addr: addr,
|
||||
tp: C.Shadowsocks,
|
||||
udp: option.UDP,
|
||||
},
|
||||
server: server,
|
||||
cipher: ciph,
|
||||
|
||||
obfsMode: obfsMode,
|
||||
|
Reference in New Issue
Block a user