mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-21 17:46:58 -05:00
socks client
This commit is contained in:
parent
b00ee67369
commit
f2e9d8a4e0
@ -97,7 +97,14 @@ func (v *ServerSpec) AddUser(user *User) {
|
||||
|
||||
func (v *ServerSpec) PickUser() *User {
|
||||
userCount := len(v.users)
|
||||
return v.users[dice.Roll(userCount)]
|
||||
switch userCount {
|
||||
case 0:
|
||||
return nil
|
||||
case 1:
|
||||
return v.users[0]
|
||||
default:
|
||||
return v.users[dice.Roll(userCount)]
|
||||
}
|
||||
}
|
||||
|
||||
func (v *ServerSpec) IsValid() bool {
|
||||
|
@ -166,13 +166,13 @@ func (v *Client) Dispatch(destination v2net.Destination, ray ray.OutboundRay) {
|
||||
type ClientFactory struct{}
|
||||
|
||||
// StreamCapability implements OutboundHandlerFactory.StreamCapability().
|
||||
func (v *ClientFactory) StreamCapability() v2net.NetworkList {
|
||||
func (ClientFactory) StreamCapability() v2net.NetworkList {
|
||||
return v2net.NetworkList{
|
||||
Network: []v2net.Network{v2net.Network_TCP},
|
||||
}
|
||||
}
|
||||
|
||||
// Create implements OutboundHandlerFactory.Create().
|
||||
func (v *ClientFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
||||
func (ClientFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
||||
return NewClient(rawConfig.(*ClientConfig), space, meta)
|
||||
}
|
||||
|
125
proxy/socks/client.go
Normal file
125
proxy/socks/client.go
Normal file
@ -0,0 +1,125 @@
|
||||
package socks
|
||||
|
||||
import (
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/log"
|
||||
"v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/protocol"
|
||||
"v2ray.com/core/common/retry"
|
||||
"v2ray.com/core/common/signal"
|
||||
"v2ray.com/core/proxy"
|
||||
"v2ray.com/core/transport/internet"
|
||||
"v2ray.com/core/transport/ray"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
serverPicker protocol.ServerPicker
|
||||
meta *proxy.OutboundHandlerMeta
|
||||
}
|
||||
|
||||
func NewClient(config *ClientConfig, space app.Space, meta *proxy.OutboundHandlerMeta) (*Client, error) {
|
||||
serverList := protocol.NewServerList()
|
||||
for _, rec := range config.Server {
|
||||
serverList.AddServer(protocol.NewServerSpecFromPB(*rec))
|
||||
}
|
||||
client := &Client{
|
||||
serverPicker: protocol.NewRoundRobinServerPicker(serverList),
|
||||
meta: meta,
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (c *Client) Dispatch(destination net.Destination, ray ray.OutboundRay) {
|
||||
var server *protocol.ServerSpec
|
||||
var conn internet.Connection
|
||||
|
||||
err := retry.ExponentialBackoff(5, 100).On(func() error {
|
||||
server = c.serverPicker.PickServer()
|
||||
dest := server.Destination()
|
||||
rawConn, err := internet.Dial(c.meta.Address, dest, c.meta.GetDialerOptions())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
conn = rawConn
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Warning("Socks|Client: Failed to find an available destination.")
|
||||
return
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
conn.SetReusable(false)
|
||||
|
||||
request := &protocol.RequestHeader{
|
||||
Version: socks5Version,
|
||||
Command: protocol.RequestCommandTCP,
|
||||
Address: destination.Address,
|
||||
Port: destination.Port,
|
||||
}
|
||||
if destination.Network == net.Network_UDP {
|
||||
request.Command = protocol.RequestCommandUDP
|
||||
}
|
||||
|
||||
user := server.PickUser()
|
||||
if user != nil {
|
||||
request.User = user
|
||||
}
|
||||
|
||||
udpRequest, err := ClientHandshake(request, conn, conn)
|
||||
if err != nil {
|
||||
log.Warning("Socks|Client: Failed to establish connection to server: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
var requestFunc func() error
|
||||
var responseFunc func() error
|
||||
if request.Command == protocol.RequestCommandTCP {
|
||||
requestFunc = func() error {
|
||||
defer ray.OutboundInput().ForceClose()
|
||||
return buf.PipeUntilEOF(ray.OutboundInput(), buf.NewWriter(conn))
|
||||
}
|
||||
responseFunc = func() error {
|
||||
defer ray.OutboundOutput().Close()
|
||||
return buf.PipeUntilEOF(buf.NewReader(conn), ray.OutboundOutput())
|
||||
}
|
||||
} else if request.Command == protocol.RequestCommandUDP {
|
||||
udpConn, err := internet.Dial(c.meta.Address, udpRequest.Destination(), c.meta.GetDialerOptions())
|
||||
if err != nil {
|
||||
log.Info("Socks|Client: Failed to create UDP connection: ", err)
|
||||
return
|
||||
}
|
||||
defer udpConn.Close()
|
||||
requestFunc = func() error {
|
||||
defer ray.OutboundInput().ForceClose()
|
||||
return buf.PipeUntilEOF(ray.OutboundInput(), &UDPWriter{request: request, writer: udpConn})
|
||||
}
|
||||
responseFunc = func() error {
|
||||
defer ray.OutboundOutput().Close()
|
||||
reader := &UDPReader{reader: net.NewTimeOutReader(16, udpConn)}
|
||||
return buf.PipeUntilEOF(reader, ray.OutboundOutput())
|
||||
}
|
||||
}
|
||||
|
||||
requestDone := signal.ExecuteAsync(requestFunc)
|
||||
responseDone := signal.ExecuteAsync(responseFunc)
|
||||
if err := signal.ErrorOrFinish2(requestDone, responseDone); err != nil {
|
||||
log.Info("Socks|Client: Connection ends with ", err)
|
||||
}
|
||||
}
|
||||
|
||||
type ClientFactory struct{}
|
||||
|
||||
func (ClientFactory) StreamCapability() net.NetworkList {
|
||||
return net.NetworkList{
|
||||
Network: []net.Network{net.Network_TCP},
|
||||
}
|
||||
}
|
||||
|
||||
func (ClientFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
||||
return NewClient(rawConfig.(*ClientConfig), space, meta)
|
||||
}
|
@ -3,6 +3,8 @@ package socks
|
||||
import (
|
||||
"io"
|
||||
|
||||
"fmt"
|
||||
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/errors"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
@ -90,7 +92,7 @@ func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol
|
||||
}
|
||||
|
||||
var expectedAuth byte = authNotRequired
|
||||
if len(s.config.Accounts) > 0 {
|
||||
if s.config.AuthType == AuthType_PASSWORD {
|
||||
expectedAuth = authPassword
|
||||
}
|
||||
|
||||
@ -99,21 +101,27 @@ func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol
|
||||
return nil, errors.New("Socks|Server: No matching auth method.")
|
||||
}
|
||||
|
||||
if err := writeSocks5AuthenticationResponse(writer, expectedAuth); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Println("s a")
|
||||
if expectedAuth == authPassword {
|
||||
username, password, err := readUsernamePassword(reader)
|
||||
if err != nil {
|
||||
return nil, errors.Base(err).Message("Socks|Server: Failed to read username or password.")
|
||||
}
|
||||
fmt.Println("s b")
|
||||
if !s.config.HasAccount(username, password) {
|
||||
writeSocks5AuthenticationResponse(writer, 0xFF)
|
||||
return nil, errors.Base(err).Message("Socks|Server: Invalid username or password.")
|
||||
}
|
||||
}
|
||||
|
||||
if err := writeSocks5AuthenticationResponse(writer, 0x00); err != nil {
|
||||
return nil, err
|
||||
if err := writeSocks5AuthenticationResponse(writer, 0x00); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("s c")
|
||||
buffer.Clear()
|
||||
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 4)); err != nil {
|
||||
return nil, err
|
||||
@ -194,21 +202,27 @@ func readUsernamePassword(reader io.Reader) (string, string, error) {
|
||||
return "", "", err
|
||||
}
|
||||
nUsername := int(buffer.Byte(1))
|
||||
fmt.Println("s username", nUsername)
|
||||
|
||||
buffer.Clear()
|
||||
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, nUsername)); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
username := buffer.String()
|
||||
fmt.Println("s username", username)
|
||||
buffer.Clear()
|
||||
|
||||
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 1)); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
nPassword := int(buffer.Byte(0))
|
||||
fmt.Println("s pwd", nPassword)
|
||||
buffer.Clear()
|
||||
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, nPassword)); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
password := buffer.String()
|
||||
fmt.Println("s pwd", password)
|
||||
return username, password, nil
|
||||
}
|
||||
|
||||
@ -244,9 +258,7 @@ func writeSocks5AuthenticationResponse(writer io.Writer, auth byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func writeSocks5Response(writer io.Writer, errCode byte, address v2net.Address, port v2net.Port) error {
|
||||
buffer := buf.NewLocal(64)
|
||||
buffer.AppendBytes(socks5Version, errCode, 0x00 /* reserved */)
|
||||
func appendAddress(buffer *buf.Buffer, address v2net.Address, port v2net.Port) {
|
||||
switch address.Family() {
|
||||
case v2net.AddressFamilyIPv4:
|
||||
buffer.AppendBytes(0x01)
|
||||
@ -259,6 +271,12 @@ func writeSocks5Response(writer io.Writer, errCode byte, address v2net.Address,
|
||||
buffer.AppendSupplier(serial.WriteString(address.Domain()))
|
||||
}
|
||||
buffer.AppendSupplier(serial.WriteUint16(port.Value()))
|
||||
}
|
||||
|
||||
func writeSocks5Response(writer io.Writer, errCode byte, address v2net.Address, port v2net.Port) error {
|
||||
buffer := buf.NewLocal(64)
|
||||
buffer.AppendBytes(socks5Version, errCode, 0x00 /* reserved */)
|
||||
appendAddress(buffer, address, port)
|
||||
|
||||
_, err := writer.Write(buffer.Bytes())
|
||||
return err
|
||||
@ -326,18 +344,162 @@ func DecodeUDPPacket(packet []byte) (*protocol.RequestHeader, []byte, error) {
|
||||
func EncodeUDPPacket(request *protocol.RequestHeader, data []byte) *buf.Buffer {
|
||||
b := buf.NewSmall()
|
||||
b.AppendBytes(0, 0, 0 /* Fragment */)
|
||||
switch request.Address.Family() {
|
||||
case v2net.AddressFamilyIPv4:
|
||||
b.AppendBytes(addrTypeIPv4)
|
||||
b.Append(request.Address.IP())
|
||||
case v2net.AddressFamilyIPv6:
|
||||
b.AppendBytes(addrTypeIPv6)
|
||||
b.Append(request.Address.IP())
|
||||
case v2net.AddressFamilyDomain:
|
||||
b.AppendBytes(addrTypeDomain, byte(len(request.Address.Domain())))
|
||||
b.AppendSupplier(serial.WriteString(request.Address.Domain()))
|
||||
}
|
||||
b.AppendSupplier(serial.WriteUint16(request.Port.Value()))
|
||||
appendAddress(b, request.Address, request.Port)
|
||||
b.Append(data)
|
||||
return b
|
||||
}
|
||||
|
||||
type UDPReader struct {
|
||||
reader io.Reader
|
||||
}
|
||||
|
||||
func (r *UDPReader) Read() (*buf.Buffer, error) {
|
||||
b := buf.NewSmall()
|
||||
if err := b.AppendSupplier(buf.ReadFrom(r.reader)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, data, err := DecodeUDPPacket(b.Bytes())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b.Clear()
|
||||
b.Append(data)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
type UDPWriter struct {
|
||||
request *protocol.RequestHeader
|
||||
writer io.Writer
|
||||
}
|
||||
|
||||
func (w *UDPWriter) Write(b *buf.Buffer) error {
|
||||
eb := EncodeUDPPacket(w.request, b.Bytes())
|
||||
b.Release()
|
||||
defer eb.Release()
|
||||
if _, err := w.writer.Write(eb.Bytes()); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) {
|
||||
authByte := byte(authNotRequired)
|
||||
if request.User != nil {
|
||||
authByte = byte(authPassword)
|
||||
}
|
||||
authRequest := []byte{socks5Version, 0x01, authByte}
|
||||
if _, err := writer.Write(authRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b := buf.NewLocal(64)
|
||||
if err := b.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if b.Byte(0) != socks5Version {
|
||||
return nil, errors.New("Socks|Client: Unexpected server version: ", b.Byte(0))
|
||||
}
|
||||
if b.Byte(1) != authByte {
|
||||
return nil, errors.New("Socks|Client: auth method not supported.")
|
||||
}
|
||||
|
||||
if authByte == authPassword {
|
||||
rawAccount, err := request.User.GetTypedAccount()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
account := rawAccount.(*Account)
|
||||
|
||||
fmt.Println("c username", account.Username)
|
||||
fmt.Println("c pwd", account.Password)
|
||||
b.Clear()
|
||||
b.AppendBytes(socks5Version, byte(len(account.Username)))
|
||||
b.Append([]byte(account.Username))
|
||||
b.AppendBytes(byte(len(account.Password)))
|
||||
b.Append([]byte(account.Password))
|
||||
fmt.Println("c a")
|
||||
if _, err := writer.Write(b.Bytes()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fmt.Println("c b")
|
||||
b.Clear()
|
||||
if err := b.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fmt.Println("c c")
|
||||
if b.Byte(1) != 0x00 {
|
||||
return nil, errors.New("Socks|Client: Server rejects account: ", b.Byte(1))
|
||||
}
|
||||
}
|
||||
|
||||
b.Clear()
|
||||
|
||||
command := byte(cmdTCPConnect)
|
||||
if request.Command == protocol.RequestCommandUDP {
|
||||
command = byte(cmdUDPPort)
|
||||
}
|
||||
b.AppendBytes(socks5Version, command, 0x00 /* reserved */)
|
||||
appendAddress(b, request.Address, request.Port)
|
||||
fmt.Println("c e")
|
||||
if _, err := writer.Write(b.Bytes()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b.Clear()
|
||||
fmt.Println("c f")
|
||||
if err := b.AppendSupplier(buf.ReadFullFrom(reader, 4)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp := b.Byte(1)
|
||||
if resp != 0x00 {
|
||||
return nil, errors.New("Socks|Client: Server rejects request: ", resp)
|
||||
}
|
||||
|
||||
addrType := b.Byte(3)
|
||||
|
||||
b.Clear()
|
||||
|
||||
var address v2net.Address
|
||||
switch addrType {
|
||||
case addrTypeIPv4:
|
||||
if err := b.AppendSupplier(buf.ReadFullFrom(reader, 4)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
address = v2net.IPAddress(b.Bytes())
|
||||
case addrTypeIPv6:
|
||||
if err := b.AppendSupplier(buf.ReadFullFrom(reader, 16)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
address = v2net.IPAddress(b.Bytes())
|
||||
case addrTypeDomain:
|
||||
if err := b.AppendSupplier(buf.ReadFullFrom(reader, 1)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
domainLength := int(b.Byte(0))
|
||||
if err := b.AppendSupplier(buf.ReadFullFrom(reader, domainLength)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
address = v2net.DomainAddress(string(b.BytesFrom(-domainLength)))
|
||||
default:
|
||||
return nil, errors.New("Socks|Server: Unknown address type: ", addrType)
|
||||
}
|
||||
|
||||
if err := b.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
port := v2net.PortFromBytes(b.BytesFrom(-2))
|
||||
|
||||
if request.Command == protocol.RequestCommandUDP {
|
||||
udpRequest := &protocol.RequestHeader{
|
||||
Version: socks5Version,
|
||||
Command: protocol.RequestCommandUDP,
|
||||
Address: address,
|
||||
Port: port,
|
||||
}
|
||||
return udpRequest, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -7,14 +7,12 @@ import (
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/bufio"
|
||||
"v2ray.com/core/common/errors"
|
||||
"v2ray.com/core/common/log"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/protocol"
|
||||
"v2ray.com/core/common/serial"
|
||||
"v2ray.com/core/common/signal"
|
||||
"v2ray.com/core/proxy"
|
||||
"v2ray.com/core/transport/internet"
|
||||
@ -193,7 +191,3 @@ func (v *ServerFactory) StreamCapability() v2net.NetworkList {
|
||||
func (v *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
||||
return NewServer(rawConfig.(*ServerConfig), space, meta), nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
common.Must(proxy.RegisterInboundHandlerCreator(serial.GetMessageType(new(ServerConfig)), new(ServerFactory)))
|
||||
}
|
||||
|
12
proxy/socks/socks.go
Normal file
12
proxy/socks/socks.go
Normal file
@ -0,0 +1,12 @@
|
||||
package socks
|
||||
|
||||
import (
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/serial"
|
||||
"v2ray.com/core/proxy"
|
||||
)
|
||||
|
||||
func init() {
|
||||
common.Must(proxy.RegisterOutboundHandlerCreator(serial.GetMessageType((*ClientConfig)(nil)), new(ClientFactory)))
|
||||
common.Must(proxy.RegisterInboundHandlerCreator(serial.GetMessageType((*ServerConfig)(nil)), new(ServerFactory)))
|
||||
}
|
254
testing/scenarios/socks_test.go
Normal file
254
testing/scenarios/socks_test.go
Normal file
@ -0,0 +1,254 @@
|
||||
package scenarios
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
socks1 "h12.me/socks"
|
||||
"v2ray.com/core"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/protocol"
|
||||
"v2ray.com/core/common/serial"
|
||||
"v2ray.com/core/proxy/dokodemo"
|
||||
"v2ray.com/core/proxy/freedom"
|
||||
"v2ray.com/core/proxy/socks"
|
||||
"v2ray.com/core/testing/assert"
|
||||
"v2ray.com/core/testing/servers/tcp"
|
||||
"v2ray.com/core/testing/servers/udp"
|
||||
)
|
||||
|
||||
func TestSocksBridgeTCP(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
tcpServer := tcp.Server{
|
||||
MsgProcessor: xor,
|
||||
}
|
||||
dest, err := tcpServer.Start()
|
||||
assert.Error(err).IsNil()
|
||||
defer tcpServer.Close()
|
||||
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*core.InboundConnectionConfig{
|
||||
{
|
||||
PortRange: v2net.SinglePortRange(serverPort),
|
||||
ListenOn: v2net.NewIPOrDomain(v2net.LocalHostIP),
|
||||
Settings: serial.ToTypedMessage(&socks.ServerConfig{
|
||||
AuthType: socks.AuthType_PASSWORD,
|
||||
Accounts: map[string]string{
|
||||
"Test Account": "Test Password",
|
||||
},
|
||||
Address: v2net.NewIPOrDomain(v2net.LocalHostIP),
|
||||
UdpEnabled: false,
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*core.OutboundConnectionConfig{
|
||||
{
|
||||
Settings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
clientPort := pickPort()
|
||||
clientConfig := &core.Config{
|
||||
Inbound: []*core.InboundConnectionConfig{
|
||||
{
|
||||
PortRange: v2net.SinglePortRange(clientPort),
|
||||
ListenOn: v2net.NewIPOrDomain(v2net.LocalHostIP),
|
||||
Settings: serial.ToTypedMessage(&dokodemo.Config{
|
||||
Address: v2net.NewIPOrDomain(dest.Address),
|
||||
Port: uint32(dest.Port),
|
||||
NetworkList: &v2net.NetworkList{
|
||||
Network: []v2net.Network{v2net.Network_TCP},
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*core.OutboundConnectionConfig{
|
||||
{
|
||||
Settings: serial.ToTypedMessage(&socks.ClientConfig{
|
||||
Server: []*protocol.ServerEndpoint{
|
||||
{
|
||||
Address: v2net.NewIPOrDomain(v2net.LocalHostIP),
|
||||
Port: uint32(serverPort),
|
||||
User: []*protocol.User{
|
||||
{
|
||||
Account: serial.ToTypedMessage(&socks.Account{
|
||||
Username: "Test Account",
|
||||
Password: "Test Password",
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
assert.Error(InitializeServerConfig(serverConfig)).IsNil()
|
||||
assert.Error(InitializeServerConfig(clientConfig)).IsNil()
|
||||
|
||||
conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{
|
||||
IP: []byte{127, 0, 0, 1},
|
||||
Port: int(clientPort),
|
||||
})
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
payload := "test payload"
|
||||
nBytes, err := conn.Write([]byte(payload))
|
||||
assert.Error(err).IsNil()
|
||||
assert.Int(nBytes).Equals(len(payload))
|
||||
|
||||
response := make([]byte, 1024)
|
||||
nBytes, err = conn.Read(response)
|
||||
assert.Error(err).IsNil()
|
||||
assert.Bytes(response[:nBytes]).Equals(xor([]byte(payload)))
|
||||
assert.Error(conn.Close()).IsNil()
|
||||
|
||||
CloseAllServers()
|
||||
}
|
||||
|
||||
func TestSocks4(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
tcpServer := tcp.Server{
|
||||
MsgProcessor: xor,
|
||||
}
|
||||
dest, err := tcpServer.Start()
|
||||
assert.Error(err).IsNil()
|
||||
defer tcpServer.Close()
|
||||
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*core.InboundConnectionConfig{
|
||||
{
|
||||
PortRange: v2net.SinglePortRange(serverPort),
|
||||
ListenOn: v2net.NewIPOrDomain(v2net.LocalHostIP),
|
||||
Settings: serial.ToTypedMessage(&socks.ServerConfig{
|
||||
AuthType: socks.AuthType_NO_AUTH,
|
||||
Address: v2net.NewIPOrDomain(v2net.LocalHostIP),
|
||||
UdpEnabled: false,
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*core.OutboundConnectionConfig{
|
||||
{
|
||||
Settings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
assert.Error(InitializeServerConfig(serverConfig)).IsNil()
|
||||
|
||||
dialer := socks1.DialSocksProxy(socks1.SOCKS4, v2net.TCPDestination(v2net.LocalHostIP, serverPort).NetAddr())
|
||||
conn, err := dialer("tcp", dest.NetAddr())
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
payload := "test payload"
|
||||
nBytes, err := conn.Write([]byte(payload))
|
||||
assert.Error(err).IsNil()
|
||||
assert.Int(nBytes).Equals(len(payload))
|
||||
|
||||
response := make([]byte, 1024)
|
||||
nBytes, err = conn.Read(response)
|
||||
assert.Error(err).IsNil()
|
||||
assert.Bytes(response[:nBytes]).Equals(xor([]byte(payload)))
|
||||
assert.Error(conn.Close()).IsNil()
|
||||
|
||||
CloseAllServers()
|
||||
}
|
||||
|
||||
func TestSocksBridageUDP(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
udpServer := udp.Server{
|
||||
MsgProcessor: xor,
|
||||
}
|
||||
dest, err := udpServer.Start()
|
||||
assert.Error(err).IsNil()
|
||||
defer udpServer.Close()
|
||||
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*core.InboundConnectionConfig{
|
||||
{
|
||||
PortRange: v2net.SinglePortRange(serverPort),
|
||||
ListenOn: v2net.NewIPOrDomain(v2net.LocalHostIP),
|
||||
Settings: serial.ToTypedMessage(&socks.ServerConfig{
|
||||
AuthType: socks.AuthType_PASSWORD,
|
||||
Accounts: map[string]string{
|
||||
"Test Account": "Test Password",
|
||||
},
|
||||
Address: v2net.NewIPOrDomain(v2net.LocalHostIP),
|
||||
UdpEnabled: true,
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*core.OutboundConnectionConfig{
|
||||
{
|
||||
Settings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
clientPort := pickPort()
|
||||
clientConfig := &core.Config{
|
||||
Inbound: []*core.InboundConnectionConfig{
|
||||
{
|
||||
PortRange: v2net.SinglePortRange(clientPort),
|
||||
ListenOn: v2net.NewIPOrDomain(v2net.LocalHostIP),
|
||||
Settings: serial.ToTypedMessage(&dokodemo.Config{
|
||||
Address: v2net.NewIPOrDomain(dest.Address),
|
||||
Port: uint32(dest.Port),
|
||||
NetworkList: &v2net.NetworkList{
|
||||
Network: []v2net.Network{v2net.Network_TCP, v2net.Network_UDP},
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*core.OutboundConnectionConfig{
|
||||
{
|
||||
Settings: serial.ToTypedMessage(&socks.ClientConfig{
|
||||
Server: []*protocol.ServerEndpoint{
|
||||
{
|
||||
Address: v2net.NewIPOrDomain(v2net.LocalHostIP),
|
||||
Port: uint32(serverPort),
|
||||
User: []*protocol.User{
|
||||
{
|
||||
Account: serial.ToTypedMessage(&socks.Account{
|
||||
Username: "Test Account",
|
||||
Password: "Test Password",
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
assert.Error(InitializeServerConfig(serverConfig)).IsNil()
|
||||
assert.Error(InitializeServerConfig(clientConfig)).IsNil()
|
||||
|
||||
conn, err := net.DialUDP("udp", nil, &net.UDPAddr{
|
||||
IP: []byte{127, 0, 0, 1},
|
||||
Port: int(clientPort),
|
||||
})
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
payload := "dokodemo request."
|
||||
nBytes, err := conn.Write([]byte(payload))
|
||||
assert.Error(err).IsNil()
|
||||
assert.Int(nBytes).Equals(len(payload))
|
||||
|
||||
response := make([]byte, 1024)
|
||||
nBytes, err = conn.Read(response)
|
||||
assert.Error(err).IsNil()
|
||||
assert.Bytes(response[:nBytes]).Equals(xor([]byte(payload)))
|
||||
assert.Error(conn.Close()).IsNil()
|
||||
|
||||
CloseAllServers()
|
||||
}
|
Loading…
Reference in New Issue
Block a user