add go-shadowsocks2 support
This commit is contained in:
parent
806bf0e8e2
commit
6f0bf7da03
@ -184,6 +184,8 @@ func parseChainNode(ns string) (nodes []gost.Node, err error) {
|
||||
connector = gost.SOCKS4AConnector()
|
||||
case "ss":
|
||||
connector = gost.ShadowConnector(node.User)
|
||||
case "ss2":
|
||||
connector = gost.Shadow2Connector(node.User)
|
||||
case "direct":
|
||||
connector = gost.SSHDirectForwardConnector()
|
||||
case "remote":
|
||||
@ -375,6 +377,8 @@ func (r *route) GenRouters() ([]router, error) {
|
||||
handler = gost.SOCKS4Handler()
|
||||
case "ss":
|
||||
handler = gost.ShadowHandler()
|
||||
case "ss2":
|
||||
handler = gost.Shadow2Handler()
|
||||
case "http":
|
||||
handler = gost.HTTPHandler()
|
||||
case "tcp":
|
||||
|
14
go.mod
14
go.mod
@ -4,6 +4,7 @@ require (
|
||||
git.torproject.org/pluggable-transports/goptlib.git v0.0.0-20180321061416-7d56ec4f381e
|
||||
git.torproject.org/pluggable-transports/obfs4.git v0.0.0-20181103133120-08f4d470188e
|
||||
github.com/Yawning/chacha20 v0.0.0-20170904085104-e3b1f968fc63 // indirect
|
||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
|
||||
github.com/bifurcation/mint v0.0.0-20181105071958-a14404e9a861 // indirect
|
||||
github.com/cheekybits/genny v1.0.0 // indirect
|
||||
github.com/dchest/siphash v1.2.1 // indirect
|
||||
@ -21,19 +22,20 @@ require (
|
||||
github.com/lucas-clemente/aes12 v0.0.0-20171027163421-cd47fb39b79f // indirect
|
||||
github.com/lucas-clemente/quic-go v0.10.0
|
||||
github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced // indirect
|
||||
github.com/miekg/dns v1.1.1
|
||||
github.com/miekg/dns v1.1.3
|
||||
github.com/onsi/ginkgo v1.7.0 // indirect
|
||||
github.com/onsi/gomega v1.4.3 // indirect
|
||||
github.com/pkg/errors v0.8.0 // indirect
|
||||
github.com/pkg/errors v0.8.1 // indirect
|
||||
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735
|
||||
github.com/shadowsocks/go-shadowsocks2 v0.0.11
|
||||
github.com/shadowsocks/shadowsocks-go v0.0.0-20170121203516-97a5c71f80ba
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
|
||||
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b // indirect
|
||||
github.com/tjfoc/gmsm v1.0.1 // indirect
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f // indirect
|
||||
golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e // indirect
|
||||
golang.org/x/crypto v0.0.0-20190130090550-b01c7a725664
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
|
||||
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc // indirect
|
||||
gopkg.in/gorilla/websocket.v1 v1.4.0
|
||||
gopkg.in/xtaci/kcp-go.v4 v4.3.2
|
||||
gopkg.in/xtaci/smux.v1 v1.0.7
|
||||
|
28
go.sum
28
go.sum
@ -4,6 +4,8 @@ git.torproject.org/pluggable-transports/obfs4.git v0.0.0-20181103133120-08f4d470
|
||||
git.torproject.org/pluggable-transports/obfs4.git v0.0.0-20181103133120-08f4d470188e/go.mod h1:jRZbfRcLIgFQoCw6tRmsnETVyIj54jOmXhHCYYa0jbs=
|
||||
github.com/Yawning/chacha20 v0.0.0-20170904085104-e3b1f968fc63 h1:I6/SJSN9wJMJ+ZyQaCHUlzoTA4ypU5Bb44YWR1wTY/0=
|
||||
github.com/Yawning/chacha20 v0.0.0-20170904085104-e3b1f968fc63/go.mod h1:nf+Komq6fVP4SwmKEaVGxHTyQGKREVlwjQKpvOV39yE=
|
||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY=
|
||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
|
||||
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI=
|
||||
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
|
||||
github.com/bifurcation/mint v0.0.0-20181105071958-a14404e9a861 h1:x17NvoJaphEzay72TFej4OSSsgu3xRYBLkbIwdofS/4=
|
||||
@ -48,17 +50,19 @@ github.com/lucas-clemente/quic-go v0.10.0 h1:xEF+pSHYAOcu+U10Meunf+DTtc8vhQDRqlA
|
||||
github.com/lucas-clemente/quic-go v0.10.0/go.mod h1:wuD+2XqEx8G9jtwx5ou2BEYBsE+whgQmlj0Vz/77PrY=
|
||||
github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced h1:zqEC1GJZFbGZA0tRyNZqRjep92K5fujFtFsu5ZW7Aug=
|
||||
github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced/go.mod h1:NCcRLrOTZbzhZvixZLlERbJtDtYsmMw8Jc4vS8Z0g58=
|
||||
github.com/miekg/dns v1.1.1 h1:DVkblRdiScEnEr0LR9nTnEQqHYycjkXW9bOjd+2EL2o=
|
||||
github.com/miekg/dns v1.1.1/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.3 h1:1g0r1IvskvgL8rR+AcHzUA+oFmGcQlaIm4IqakufeMM=
|
||||
github.com/miekg/dns v1.1.3/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 h1:7YvPJVmEeFHR1Tj9sZEYsmarJEQfMVYpd/Vyy/A8dqE=
|
||||
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
||||
github.com/shadowsocks/go-shadowsocks2 v0.0.11 h1:dXloqEhYnZV40jblWTK8kWeC0Eb+dgql4S0tj99e8j0=
|
||||
github.com/shadowsocks/go-shadowsocks2 v0.0.11/go.mod h1:R+KWaoIwRRhnpw6XV+dZil0XHi64Hc1D7hXUyXTjUzQ=
|
||||
github.com/shadowsocks/shadowsocks-go v0.0.0-20170121203516-97a5c71f80ba h1:tJgNXb3S+RkB4kNPi6N5OmEWe3m+Y3Qs6LUMiNDAONM=
|
||||
github.com/shadowsocks/shadowsocks-go v0.0.0-20170121203516-97a5c71f80ba/go.mod h1:mttDPaeLm87u74HMrP+n2tugXvIKWcwff/cqSX0lehY=
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU=
|
||||
@ -68,18 +72,18 @@ github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mn
|
||||
github.com/tjfoc/gmsm v1.0.1 h1:R11HlqhXkDospckjZEihx9SW/2VW0RgdwrykyWMFOQU=
|
||||
github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc=
|
||||
golang.org/x/crypto v0.0.0-20181015023909-0c41d7ab0a0e/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190130090550-b01c7a725664 h1:YbZJ76lQ1BqNhVe7dKTSB67wDrc2VPRR75IyGyyPDX8=
|
||||
golang.org/x/crypto v0.0.0-20190130090550-b01c7a725664/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc h1:a3CU5tJYVj92DY2LaA1kUkrsqD5/3mLDhx2NcNqyW+0=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 h1:ulvT7fqt0yHWzpJwI57MezWnYDVpCAYBVuYst/L+fAY=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e h1:njOxP/wVblhCLIUhjHXf6X+dzTt5OQ3vMQo9mkOIKIo=
|
||||
golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc h1:WiYx1rIFmx8c0mXAFtv5D/mHyKe1+jmuP7PViuwqwuQ=
|
||||
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
|
2
gost.go
2
gost.go
@ -19,7 +19,7 @@ import (
|
||||
)
|
||||
|
||||
// Version is the gost version.
|
||||
const Version = "2.7.2"
|
||||
const Version = "2.8.0"
|
||||
|
||||
// Debug is a flag that enables the debug log.
|
||||
var Debug bool
|
||||
|
2
node.go
2
node.go
@ -85,7 +85,7 @@ func ParseNode(s string) (node Node, err error) {
|
||||
}
|
||||
|
||||
switch node.Protocol {
|
||||
case "http", "http2", "socks4", "socks4a", "ss", "ssu", "sni":
|
||||
case "http", "http2", "socks4", "socks4a", "ss", "ss2", "ssu", "sni":
|
||||
case "socks", "socks5":
|
||||
node.Protocol = "socks5"
|
||||
case "tcp", "udp", "rtcp", "rudp": // port forwarding
|
||||
|
229
ss2.go
Normal file
229
ss2.go
Normal file
@ -0,0 +1,229 @@
|
||||
package gost
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/ginuerzh/gosocks5"
|
||||
"github.com/go-log/log"
|
||||
"github.com/shadowsocks/go-shadowsocks2/core"
|
||||
)
|
||||
|
||||
type shadow2Connector struct {
|
||||
Cipher *url.Userinfo
|
||||
}
|
||||
|
||||
// Shadow2Connector creates a Connector for go-shadowsocks2 proxy client.
|
||||
// It accepts a cipher info for shadowsocks data encryption/decryption.
|
||||
// The cipher must not be nil.
|
||||
func Shadow2Connector(cipher *url.Userinfo) Connector {
|
||||
return &shadow2Connector{Cipher: cipher}
|
||||
}
|
||||
|
||||
func (c *shadow2Connector) Connect(conn net.Conn, addr string, options ...ConnectOption) (net.Conn, error) {
|
||||
opts := &ConnectOptions{}
|
||||
for _, option := range options {
|
||||
option(opts)
|
||||
}
|
||||
|
||||
timeout := opts.Timeout
|
||||
if timeout <= 0 {
|
||||
timeout = ConnectTimeout
|
||||
}
|
||||
|
||||
conn.SetDeadline(time.Now().Add(timeout))
|
||||
defer conn.SetDeadline(time.Time{})
|
||||
|
||||
socksAddr, err := gosocks5.NewAddr(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rawaddr := sPool.Get().([]byte)
|
||||
defer sPool.Put(rawaddr)
|
||||
|
||||
n, err := socksAddr.Encode(rawaddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var method, password string
|
||||
cp := opts.User
|
||||
if cp == nil {
|
||||
cp = c.Cipher
|
||||
}
|
||||
if cp != nil {
|
||||
method = cp.Username()
|
||||
password, _ = cp.Password()
|
||||
}
|
||||
|
||||
cipher, err := core.PickCipher(method, nil, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conn = cipher.StreamConn(conn)
|
||||
if _, err := conn.Write(rawaddr[:n]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
type shadow2Handler struct {
|
||||
options *HandlerOptions
|
||||
}
|
||||
|
||||
// Shadow2Handler creates a server Handler for go-shadowsocks2 proxy server.
|
||||
func Shadow2Handler(opts ...HandlerOption) Handler {
|
||||
h := &shadow2Handler{}
|
||||
h.Init(opts...)
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
func (h *shadow2Handler) Init(options ...HandlerOption) {
|
||||
if h.options == nil {
|
||||
h.options = &HandlerOptions{}
|
||||
}
|
||||
|
||||
for _, opt := range options {
|
||||
opt(h.options)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *shadow2Handler) Handle(conn net.Conn) {
|
||||
defer conn.Close()
|
||||
|
||||
var method, password string
|
||||
users := h.options.Users
|
||||
if len(users) > 0 {
|
||||
method = users[0].Username()
|
||||
password, _ = users[0].Password()
|
||||
}
|
||||
|
||||
cipher, err := core.PickCipher(method, nil, password)
|
||||
if err != nil {
|
||||
log.Logf("[ss2] %s -> %s : %s",
|
||||
conn.RemoteAddr(), conn.LocalAddr(), err)
|
||||
return
|
||||
}
|
||||
|
||||
conn = cipher.StreamConn(conn)
|
||||
conn.SetReadDeadline(time.Now().Add(ReadTimeout))
|
||||
|
||||
addr, err := readAddr(conn)
|
||||
if err != nil {
|
||||
log.Logf("[ss2] %s -> %s : %s",
|
||||
conn.RemoteAddr(), conn.LocalAddr(), err)
|
||||
return
|
||||
}
|
||||
|
||||
// clear timer
|
||||
conn.SetReadDeadline(time.Time{})
|
||||
|
||||
host := addr.String()
|
||||
log.Logf("[ss2] %s -> %s -> %s",
|
||||
conn.RemoteAddr(), h.options.Node.String(), host)
|
||||
|
||||
if !Can("tcp", host, h.options.Whitelist, h.options.Blacklist) {
|
||||
log.Logf("[ss2] %s - %s : Unauthorized to tcp connect to %s",
|
||||
conn.RemoteAddr(), conn.LocalAddr(), host)
|
||||
return
|
||||
}
|
||||
|
||||
if h.options.Bypass.Contains(host) {
|
||||
log.Logf("[ss2] %s - %s : Bypass %s",
|
||||
conn.RemoteAddr(), conn.LocalAddr(), host)
|
||||
return
|
||||
}
|
||||
|
||||
retries := 1
|
||||
if h.options.Chain != nil && h.options.Chain.Retries > 0 {
|
||||
retries = h.options.Chain.Retries
|
||||
}
|
||||
if h.options.Retries > 0 {
|
||||
retries = h.options.Retries
|
||||
}
|
||||
|
||||
var cc net.Conn
|
||||
var route *Chain
|
||||
for i := 0; i < retries; i++ {
|
||||
route, err = h.options.Chain.selectRouteFor(host)
|
||||
if err != nil {
|
||||
log.Logf("[ss2] %s -> %s : %s",
|
||||
conn.RemoteAddr(), conn.LocalAddr(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
buf := bytes.Buffer{}
|
||||
fmt.Fprintf(&buf, "%s -> %s -> ",
|
||||
conn.RemoteAddr(), h.options.Node.String())
|
||||
for _, nd := range route.route {
|
||||
fmt.Fprintf(&buf, "%d@%s -> ", nd.ID, nd.String())
|
||||
}
|
||||
fmt.Fprintf(&buf, "%s", host)
|
||||
log.Log("[route]", buf.String())
|
||||
|
||||
cc, err = route.Dial(host,
|
||||
TimeoutChainOption(h.options.Timeout),
|
||||
HostsChainOption(h.options.Hosts),
|
||||
ResolverChainOption(h.options.Resolver),
|
||||
)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
log.Logf("[ss2] %s -> %s : %s",
|
||||
conn.RemoteAddr(), conn.LocalAddr(), err)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer cc.Close()
|
||||
|
||||
log.Logf("[ss2] %s <-> %s", conn.RemoteAddr(), host)
|
||||
transport(conn, cc)
|
||||
log.Logf("[ss2] %s >-< %s", conn.RemoteAddr(), host)
|
||||
}
|
||||
|
||||
func readAddr(r io.Reader) (*gosocks5.Addr, error) {
|
||||
addr := &gosocks5.Addr{}
|
||||
b := sPool.Get().([]byte)
|
||||
defer sPool.Put(b)
|
||||
|
||||
_, err := io.ReadFull(r, b[:1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addr.Type = b[0]
|
||||
|
||||
switch addr.Type {
|
||||
case gosocks5.AddrIPv4:
|
||||
_, err = io.ReadFull(r, b[:net.IPv4len])
|
||||
addr.Host = net.IP(b[0:net.IPv4len]).String()
|
||||
case gosocks5.AddrIPv6:
|
||||
_, err = io.ReadFull(r, b[:net.IPv6len])
|
||||
addr.Host = net.IP(b[0:net.IPv6len]).String()
|
||||
case gosocks5.AddrDomain:
|
||||
if _, err = io.ReadFull(r, b[:1]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addrlen := int(b[0])
|
||||
_, err = io.ReadFull(r, b[:addrlen])
|
||||
addr.Host = string(b[:addrlen])
|
||||
default:
|
||||
return nil, gosocks5.ErrBadAddrType
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = io.ReadFull(r, b[:2])
|
||||
addr.Port = binary.BigEndian.Uint16(b[:2])
|
||||
return addr, err
|
||||
}
|
Loading…
Reference in New Issue
Block a user