r_socks 0.1.8 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/r_socks/authenticator.rb +1 -1
- data/lib/r_socks/config.rb +16 -4
- data/lib/r_socks/connection_handler.rb +21 -137
- data/lib/r_socks/errors.rb +2 -0
- data/lib/r_socks/http_proxy_parser.rb +76 -0
- data/lib/r_socks/http_proxy_response_codes.rb +6 -0
- data/lib/r_socks/socks5_proxy_parser.rb +174 -0
- data/lib/r_socks/target_connection_handler.rb +5 -6
- data/lib/r_socks/version.rb +2 -2
- data/lib/r_socks.rb +5 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8aeaa60ff88cdf8c84892a5c95c9613d1bc8726fdaf3a5e8d113eeb47f6fb77a
|
4
|
+
data.tar.gz: 84ec2ec281d97bf06bfd3838131cb35c11869f85361157088e593f2be03c78cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b2c40a1456321518b5ce51918f34046ddb3f06056b634b08a026bd95cb231fe221c443848bf1dfd4c6d8add73363afcb47864c7de251c42786ce7778d08876e
|
7
|
+
data.tar.gz: 96df7a1ac2898bf062a8801b49570d351d5110946f309e8c3e74185e3e3f303f3b981d3781127f13971a6cd8a4f76c4dc6f0191c8fcd23f2e33f57cf42c68981
|
data/Gemfile.lock
CHANGED
data/lib/r_socks/config.rb
CHANGED
@@ -14,17 +14,29 @@ module RSocks
|
|
14
14
|
|
15
15
|
def auth_method=(method)
|
16
16
|
if method == :no_auth
|
17
|
-
@store[:auth_method] =
|
17
|
+
@store[:auth_method] = :no_auth
|
18
18
|
elsif method == :password
|
19
|
-
@store[:auth_method] =
|
20
|
-
|
19
|
+
@store[:auth_method] = :password
|
21
20
|
else
|
22
21
|
raise Error, "unknown auth method #{method}"
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
25
|
def auth_method
|
27
|
-
@store[:auth_method]
|
26
|
+
@store[:auth_method] || :password
|
27
|
+
end
|
28
|
+
|
29
|
+
def proxy_type=(type)
|
30
|
+
if type == :http
|
31
|
+
@store[:proxy_type] = :http
|
32
|
+
|
33
|
+
elsif type == :socks5
|
34
|
+
@store[:proxy_type] = :socks5
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def proxy_type
|
39
|
+
@store[:proxy_type] || :socks5
|
28
40
|
end
|
29
41
|
|
30
42
|
def proxy_buffer_size
|
@@ -1,12 +1,10 @@
|
|
1
1
|
require 'socket'
|
2
2
|
require 'eventmachine'
|
3
3
|
require 'socket'
|
4
|
-
require '
|
5
|
-
require 'r_socks/
|
6
|
-
require 'r_socks/socks5_bit_codes'
|
7
|
-
require 'r_socks/state_machine'
|
4
|
+
require 'r_socks/http_proxy_response_codes'
|
5
|
+
require 'r_socks/http_proxy_parser'
|
8
6
|
require 'r_socks/target_connection_handler'
|
9
|
-
require 'r_socks/
|
7
|
+
require 'r_socks/socks5_proxy_parser'
|
10
8
|
|
11
9
|
module RSocks
|
12
10
|
|
@@ -15,10 +13,8 @@ module RSocks
|
|
15
13
|
def initialize(config, *args)
|
16
14
|
super(*args)
|
17
15
|
@state_machine = RSocks::StateMachine.new
|
18
|
-
@original_addr = nil
|
19
|
-
@original_port = nil
|
20
|
-
@authenticator = RSocks::Authenticator.new(config.auth_adaptor)
|
21
16
|
@config = config
|
17
|
+
@parser = create_proxy_parser
|
22
18
|
end
|
23
19
|
|
24
20
|
def post_init
|
@@ -29,39 +25,29 @@ module RSocks
|
|
29
25
|
close_connection
|
30
26
|
end
|
31
27
|
end
|
32
|
-
# sample \x05\x01\x00\x03\ngoogle.com\x00P
|
33
28
|
|
34
29
|
def receive_data(data)
|
35
30
|
|
36
31
|
return send_data(not_accept) if data.nil? || data == ''
|
37
32
|
|
38
33
|
begin
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
passed = @authenticator.auth!(data)
|
46
|
-
if passed
|
47
|
-
send_data(RSocks::SUCCESS_RESPONSE)
|
48
|
-
@state_machine.connect!
|
49
|
-
return
|
50
|
-
end
|
51
|
-
|
34
|
+
begin
|
35
|
+
@addr, @port = @parser.call(data)
|
36
|
+
rescue RSocks::HttpAuthFailed, RSocks::HttpNotSupport
|
37
|
+
send_data(RSocks::HttpProxyResponseCodes::FAILED_AUTH)
|
38
|
+
close_connection_after_writing
|
39
|
+
rescue RSocks::NotSupport
|
52
40
|
send_data(RSocks::FAILED_RESPONSE)
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
if @state_machine.connect?
|
57
|
-
connect_request(data)
|
58
|
-
return
|
41
|
+
close_connection_after_writing
|
59
42
|
end
|
60
43
|
|
61
|
-
return
|
44
|
+
return unless @state_machine.start?
|
62
45
|
|
63
46
|
if @target.nil?
|
64
|
-
@target = EventMachine.connect(@addr, @port, RSocks::TargetConnectionHandler, self, @config
|
47
|
+
@target = EventMachine.connect(@addr, @port, RSocks::TargetConnectionHandler, self, @config)
|
48
|
+
if @config.proxy_type == :http
|
49
|
+
send_data(RSocks::HttpProxyResponseCodes::SUCCESS)
|
50
|
+
end
|
65
51
|
end
|
66
52
|
|
67
53
|
proxy_incoming_to(@target, @config.proxy_buffer_size)
|
@@ -82,116 +68,14 @@ module RSocks
|
|
82
68
|
|
83
69
|
private
|
84
70
|
|
85
|
-
def
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
if version != RSocks::VERSION || num <= 0
|
90
|
-
send_data(not_accept)
|
91
|
-
close_connection
|
92
|
-
end
|
93
|
-
|
94
|
-
position = 'C' * num
|
95
|
-
|
96
|
-
methods = data[2..-1].unpack(position)
|
97
|
-
|
98
|
-
data = nil
|
99
|
-
|
100
|
-
auth_method = @config.auth_method || RSocks::NO_AUTH
|
101
|
-
|
102
|
-
if methods.include?(auth_method)
|
103
|
-
|
104
|
-
if auth_method == RSocks::NO_AUTH
|
105
|
-
@state_machine.connect!
|
106
|
-
elsif auth_method == RSocks::PASSWORD_LOGIN
|
107
|
-
@state_machine.auth!
|
108
|
-
end
|
109
|
-
|
110
|
-
data = [RSocks::VERSION, auth_method].pack('CC')
|
111
|
-
end
|
112
|
-
|
113
|
-
if data.nil?
|
114
|
-
send_data(not_accept)
|
115
|
-
close_connection
|
116
|
-
end
|
117
|
-
|
118
|
-
send_data(data)
|
119
|
-
end
|
120
|
-
|
121
|
-
def connect_request(data)
|
122
|
-
version, cmd = data.unpack('CC')
|
123
|
-
return not_accept if version != RSocks::VERSION
|
124
|
-
|
125
|
-
begin
|
126
|
-
@addr, @port, @type = check_sock_cmd(cmd, data[2..-1])
|
127
|
-
rescue
|
128
|
-
send_data([RSocks::VERSION,RSocks::CONNECT_FAIL].pack('CC'))
|
129
|
-
return close_connection
|
71
|
+
def create_proxy_parser
|
72
|
+
if @config.proxy_type == :http
|
73
|
+
return RSocks::HttpProxyParser.new(@state_machine, @config)
|
130
74
|
end
|
131
75
|
|
132
|
-
@
|
133
|
-
|
134
|
-
send_data([RSocks::VERSION, RSocks::CONNECT_SUCCESS].
|
135
|
-
pack('CC') + pack_address_and_port_info(@type))
|
136
|
-
end
|
137
|
-
|
138
|
-
def check_sock_cmd(cmd, data)
|
139
|
-
raise RSocks::NotSupport unless cmd == RSocks::CMD_CONNECT
|
140
|
-
|
141
|
-
_, addr_type = data.unpack('CC')
|
142
|
-
|
143
|
-
address = nil
|
144
|
-
port = nil
|
145
|
-
type = nil
|
146
|
-
|
147
|
-
if addr_type == RSocks::ADDR_IPV4
|
148
|
-
type = RSocks::ADDR_IPV4
|
149
|
-
address, port = parse_address_port(data[2..-1], 4, type)
|
150
|
-
elsif addr_type == RSocks::ADDR_IPV6
|
151
|
-
type = RSocks::ADDR_IPV6
|
152
|
-
address, port = parse_address_port(data[2..-1], 16, type)
|
153
|
-
elsif addr_type == RSocks::ADDR_DOMAIN
|
154
|
-
type = RSocks::ADDR_DOMAIN
|
155
|
-
padding = data[2].unpack('C')[0]
|
156
|
-
address, port = parse_address_port(data[3..-1], padding, type)
|
76
|
+
if @config.proxy_type == :socks5
|
77
|
+
return RSocks::Socks5ProxyParser.new(@state_machine, @config, self)
|
157
78
|
end
|
158
|
-
|
159
|
-
[address, port, type]
|
160
|
-
end
|
161
|
-
|
162
|
-
def not_accept
|
163
|
-
[RSocks::VERSION, RSocks::NOT_ACCEPT].pack('CC')
|
164
|
-
end
|
165
|
-
|
166
|
-
def parse_address_port(data, padding, type)
|
167
|
-
address = data[0...padding]
|
168
|
-
port_start = padding
|
169
|
-
|
170
|
-
@original_port = data[port_start..-1]
|
171
|
-
@original_addr = address
|
172
|
-
|
173
|
-
temp = @original_port.unpack('CC')
|
174
|
-
|
175
|
-
port = (temp[0] << 8) | temp[1]
|
176
|
-
|
177
|
-
addr_str = if type == RSocks::ADDR_DOMAIN
|
178
|
-
address
|
179
|
-
else
|
180
|
-
IPAddr.ntop(address)
|
181
|
-
end
|
182
|
-
|
183
|
-
[addr_str, port]
|
184
|
-
end
|
185
|
-
|
186
|
-
def pack_address_and_port_info(type)
|
187
|
-
addr = @original_addr
|
188
|
-
if type == RSocks::ADDR_DOMAIN
|
189
|
-
domain_size = [addr.size].pack('C')
|
190
|
-
addr = domain_size + @original_addr
|
191
|
-
end
|
192
|
-
|
193
|
-
temp = [RSocks::KEEP_ONE_BIT, type]
|
194
|
-
temp.pack('C' * temp.size) + addr + @original_port
|
195
79
|
end
|
196
80
|
|
197
81
|
end
|
data/lib/r_socks/errors.rb
CHANGED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
module RSocks
|
4
|
+
class HttpProxyParser
|
5
|
+
|
6
|
+
def initialize(state_machine, config)
|
7
|
+
@state_machine = state_machine
|
8
|
+
@auth_method = config.auth_method
|
9
|
+
@default_user = ENV['RSOCKS_USER'] || 'default'
|
10
|
+
@default_password = ENV['RSOCKS_PASSWORD'] || 'default'
|
11
|
+
@adaptor = config.auth_adaptor
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(data)
|
15
|
+
parser_connect_http(data)
|
16
|
+
@state_machine.start!
|
17
|
+
[@schema_parse.host, @schema_parse.port]
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def parser_connect_http(data)
|
23
|
+
temp = data.split("\r\n")
|
24
|
+
host_format_checking(temp.shift)
|
25
|
+
generate_header(temp)
|
26
|
+
|
27
|
+
state = auth_user
|
28
|
+
raise RSocks::HttpAuthFailed unless state
|
29
|
+
state
|
30
|
+
end
|
31
|
+
|
32
|
+
def auth_user
|
33
|
+
temp = @header['Proxy-Authorization']
|
34
|
+
pattern = /^Basic /
|
35
|
+
token = temp.gsub(pattern, '')
|
36
|
+
begin
|
37
|
+
str = Base64.decode64(token)
|
38
|
+
@user, @password = str.split(':')
|
39
|
+
rescue
|
40
|
+
raise RSocks::HttpNotSupport, "token parse failed #{token}"
|
41
|
+
end
|
42
|
+
|
43
|
+
if @adaptor
|
44
|
+
return @adaptor.call(@user, @password)
|
45
|
+
else
|
46
|
+
return @password == @default_password && @user == @default_user
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def host_format_checking(data)
|
51
|
+
temp = data.split("\s")
|
52
|
+
raise RSocks::HttpNotSupport if temp[0] != 'CONNECT'
|
53
|
+
@schema_parse = URI("tcp://#{temp[1]}/")
|
54
|
+
end
|
55
|
+
|
56
|
+
def generate_header(arr)
|
57
|
+
header = {}
|
58
|
+
arr.each do |val|
|
59
|
+
name, value = val.split(':')
|
60
|
+
next if name.nil?
|
61
|
+
header[name.strip] = value&.strip
|
62
|
+
end
|
63
|
+
@header = header
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# state_machine = RSocks::StateMachine.new
|
69
|
+
# a = RSocks::HttpProxyParser.new(state_machine, RSocks::Config.new)
|
70
|
+
#
|
71
|
+
# data = "CONNECT www.google.com.sg:80 HTTP/1.1\r\nHost: www.google.com.sg:80\r\nUser-Agent: Surge macOS/939\r\nConnection: keep-alive\r\nProxy-Connection: keep-alive\r\nProxy-Authorization: Basic ZGVmYXVsdDpkZWZhdWx0\r\n\r\n"
|
72
|
+
#
|
73
|
+
# host, port = a.call(data)
|
74
|
+
#
|
75
|
+
# puts host
|
76
|
+
# puts port
|
@@ -0,0 +1,174 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
require 'r_socks/errors'
|
3
|
+
require 'r_socks/socks5_bit_codes'
|
4
|
+
require 'r_socks/state_machine'
|
5
|
+
require 'r_socks/target_connection_handler'
|
6
|
+
require 'r_socks/authenticator'
|
7
|
+
require 'r_socks/socks5_proxy_parser'
|
8
|
+
|
9
|
+
module RSocks
|
10
|
+
class Socks5ProxyParser
|
11
|
+
def initialize(state_machine, config, client)
|
12
|
+
@state_machine = state_machine
|
13
|
+
@auth_method = config.auth_method
|
14
|
+
@default_user = ENV['RSOCKS_USER'] || 'default'
|
15
|
+
@default_password = ENV['RSOCKS_PASSWORD'] || 'default'
|
16
|
+
@authenticator = RSocks::Authenticator.new(config.auth_adaptor)
|
17
|
+
@original_addr = nil
|
18
|
+
@original_port = nil
|
19
|
+
@config = config
|
20
|
+
@adaptor = config.auth_adaptor
|
21
|
+
@client = client
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def call(data)
|
26
|
+
if @state_machine.handshake?
|
27
|
+
init_handshake(data)
|
28
|
+
return
|
29
|
+
end
|
30
|
+
|
31
|
+
if @state_machine.auth?
|
32
|
+
passed = @authenticator.auth!(data)
|
33
|
+
if passed
|
34
|
+
send_data(RSocks::SUCCESS_RESPONSE)
|
35
|
+
@state_machine.connect!
|
36
|
+
return
|
37
|
+
end
|
38
|
+
|
39
|
+
send_data(RSocks::FAILED_RESPONSE)
|
40
|
+
return
|
41
|
+
end
|
42
|
+
|
43
|
+
if @state_machine.connect?
|
44
|
+
connect_request(data)
|
45
|
+
return [@addr, @port]
|
46
|
+
end
|
47
|
+
|
48
|
+
return send_data(not_accept) unless @state_machine.start?
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def init_handshake(data)
|
54
|
+
|
55
|
+
version, num = data.unpack('CC')
|
56
|
+
|
57
|
+
if version != RSocks::VERSION || num <= 0
|
58
|
+
send_data(not_accept)
|
59
|
+
close_connection
|
60
|
+
end
|
61
|
+
|
62
|
+
position = 'C' * num
|
63
|
+
|
64
|
+
methods = data[2..-1].unpack(position)
|
65
|
+
|
66
|
+
data = nil
|
67
|
+
|
68
|
+
|
69
|
+
auth_method = @config.auth_method == :password ? PASSWORD_LOGIN : RSocks::NO_AUTH
|
70
|
+
|
71
|
+
if methods.include?(auth_method)
|
72
|
+
|
73
|
+
if auth_method == RSocks::NO_AUTH
|
74
|
+
@state_machine.connect!
|
75
|
+
elsif auth_method == RSocks::PASSWORD_LOGIN
|
76
|
+
@state_machine.auth!
|
77
|
+
end
|
78
|
+
|
79
|
+
data = [RSocks::VERSION, auth_method].pack('CC')
|
80
|
+
end
|
81
|
+
|
82
|
+
if data.nil?
|
83
|
+
send_data(not_accept)
|
84
|
+
close_connection
|
85
|
+
end
|
86
|
+
|
87
|
+
send_data(data)
|
88
|
+
end
|
89
|
+
|
90
|
+
def connect_request(data)
|
91
|
+
version, cmd = data.unpack('CC')
|
92
|
+
return not_accept if version != RSocks::VERSION
|
93
|
+
|
94
|
+
begin
|
95
|
+
@addr, @port, @type = check_sock_cmd(cmd, data[2..-1])
|
96
|
+
rescue
|
97
|
+
send_data([RSocks::VERSION,RSocks::CONNECT_FAIL].pack('CC'))
|
98
|
+
return close_connection
|
99
|
+
end
|
100
|
+
|
101
|
+
@state_machine.start!
|
102
|
+
|
103
|
+
send_data([RSocks::VERSION, RSocks::CONNECT_SUCCESS].
|
104
|
+
pack('CC') + pack_address_and_port_info(@type))
|
105
|
+
end
|
106
|
+
|
107
|
+
def check_sock_cmd(cmd, data)
|
108
|
+
raise RSocks::NotSupport unless cmd == RSocks::CMD_CONNECT
|
109
|
+
|
110
|
+
_, addr_type = data.unpack('CC')
|
111
|
+
|
112
|
+
address = nil
|
113
|
+
port = nil
|
114
|
+
type = nil
|
115
|
+
|
116
|
+
if addr_type == RSocks::ADDR_IPV4
|
117
|
+
type = RSocks::ADDR_IPV4
|
118
|
+
address, port = parse_address_port(data[2..-1], 4, type)
|
119
|
+
elsif addr_type == RSocks::ADDR_IPV6
|
120
|
+
type = RSocks::ADDR_IPV6
|
121
|
+
address, port = parse_address_port(data[2..-1], 16, type)
|
122
|
+
elsif addr_type == RSocks::ADDR_DOMAIN
|
123
|
+
type = RSocks::ADDR_DOMAIN
|
124
|
+
padding = data[2].unpack('C')[0]
|
125
|
+
address, port = parse_address_port(data[3..-1], padding, type)
|
126
|
+
end
|
127
|
+
|
128
|
+
[address, port, type]
|
129
|
+
end
|
130
|
+
|
131
|
+
def not_accept
|
132
|
+
[RSocks::VERSION, RSocks::NOT_ACCEPT].pack('CC')
|
133
|
+
end
|
134
|
+
|
135
|
+
def parse_address_port(data, padding, type)
|
136
|
+
address = data[0...padding]
|
137
|
+
port_start = padding
|
138
|
+
|
139
|
+
@original_port = data[port_start..-1]
|
140
|
+
@original_addr = address
|
141
|
+
|
142
|
+
temp = @original_port.unpack('CC')
|
143
|
+
|
144
|
+
port = (temp[0] << 8) | temp[1]
|
145
|
+
|
146
|
+
addr_str = if type == RSocks::ADDR_DOMAIN
|
147
|
+
address
|
148
|
+
else
|
149
|
+
IPAddr.ntop(address)
|
150
|
+
end
|
151
|
+
|
152
|
+
[addr_str, port]
|
153
|
+
end
|
154
|
+
|
155
|
+
def pack_address_and_port_info(type)
|
156
|
+
addr = @original_addr
|
157
|
+
if type == RSocks::ADDR_DOMAIN
|
158
|
+
domain_size = [addr.size].pack('C')
|
159
|
+
addr = domain_size + @original_addr
|
160
|
+
end
|
161
|
+
|
162
|
+
temp = [RSocks::KEEP_ONE_BIT, type]
|
163
|
+
temp.pack('C' * temp.size) + addr + @original_port
|
164
|
+
end
|
165
|
+
|
166
|
+
def send_data(data)
|
167
|
+
@client.send_data(data)
|
168
|
+
end
|
169
|
+
|
170
|
+
def close_connection
|
171
|
+
@client.close_connection_after_writing
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -1,21 +1,20 @@
|
|
1
1
|
require 'eventmachine'
|
2
|
+
require 'r_socks/http_proxy_response_codes'
|
2
3
|
|
3
4
|
module RSocks
|
4
5
|
class TargetConnectionHandler < EM::Connection
|
5
6
|
|
6
|
-
def initialize(client, config
|
7
|
+
def initialize(client, config)
|
7
8
|
@client = client
|
8
|
-
@init_data = data
|
9
9
|
@config = config
|
10
10
|
end
|
11
11
|
|
12
12
|
def post_init
|
13
|
-
proxy_incoming_to(@client,
|
13
|
+
proxy_incoming_to(@client, @config.proxy_buffer_size)
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
send_data
|
18
|
-
@init_data = nil
|
16
|
+
def receive_data(data)
|
17
|
+
@client.send_data(data)
|
19
18
|
end
|
20
19
|
|
21
20
|
def proxy_target_unbound
|
data/lib/r_socks/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module RSocks
|
2
|
-
VERSION = "0.
|
3
|
-
end
|
2
|
+
VERSION = "0.2.0"
|
3
|
+
end
|
data/lib/r_socks.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: r_socks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick An
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-03-
|
11
|
+
date: 2020-03-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eventmachine
|
@@ -51,7 +51,10 @@ files:
|
|
51
51
|
- lib/r_socks/config.rb
|
52
52
|
- lib/r_socks/connection_handler.rb
|
53
53
|
- lib/r_socks/errors.rb
|
54
|
+
- lib/r_socks/http_proxy_parser.rb
|
55
|
+
- lib/r_socks/http_proxy_response_codes.rb
|
54
56
|
- lib/r_socks/socks5_bit_codes.rb
|
57
|
+
- lib/r_socks/socks5_proxy_parser.rb
|
55
58
|
- lib/r_socks/state_machine.rb
|
56
59
|
- lib/r_socks/target_connection_handler.rb
|
57
60
|
- lib/r_socks/tcp_server.rb
|