shadowsocks_ruby 0.1.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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/.yardopts +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +160 -0
- data/Rakefile +14 -0
- data/bin/aruba +17 -0
- data/bin/bundler +17 -0
- data/bin/console +14 -0
- data/bin/cucumber +17 -0
- data/bin/einhorn +17 -0
- data/bin/einhornsh +17 -0
- data/bin/htmldiff +17 -0
- data/bin/ldiff +17 -0
- data/bin/lrucache_server +16 -0
- data/bin/rake +17 -0
- data/bin/rspec +17 -0
- data/bin/setup +8 -0
- data/bin/yard +17 -0
- data/bin/yardoc +17 -0
- data/bin/yri +17 -0
- data/config.example.json +6 -0
- data/exe/sslocal-ruby +4 -0
- data/exe/ssserver-ruby +4 -0
- data/lib/shadowsocks_ruby/app.rb +236 -0
- data/lib/shadowsocks_ruby/cipher/cipher.rb +112 -0
- data/lib/shadowsocks_ruby/cipher/openssl.rb +81 -0
- data/lib/shadowsocks_ruby/cipher/rbnacl.rb +64 -0
- data/lib/shadowsocks_ruby/cipher/rc4_md5.rb +54 -0
- data/lib/shadowsocks_ruby/cipher/table.rb +65 -0
- data/lib/shadowsocks_ruby/cli/sslocal_runner.rb +125 -0
- data/lib/shadowsocks_ruby/cli/ssserver_runner.rb +115 -0
- data/lib/shadowsocks_ruby/connections/backend_connection.rb +50 -0
- data/lib/shadowsocks_ruby/connections/connection.rb +195 -0
- data/lib/shadowsocks_ruby/connections/server_connection.rb +63 -0
- data/lib/shadowsocks_ruby/connections/tcp/client_connection.rb +43 -0
- data/lib/shadowsocks_ruby/connections/tcp/destination_connection.rb +19 -0
- data/lib/shadowsocks_ruby/connections/tcp/localbackend_connection.rb +29 -0
- data/lib/shadowsocks_ruby/connections/tcp/remoteserver_connection.rb +18 -0
- data/lib/shadowsocks_ruby/connections/udp/client_connection.rb +43 -0
- data/lib/shadowsocks_ruby/connections/udp/destination_connection.rb +18 -0
- data/lib/shadowsocks_ruby/connections/udp/localbackend_connection.rb +29 -0
- data/lib/shadowsocks_ruby/connections/udp/remoteserver_connection.rb +18 -0
- data/lib/shadowsocks_ruby/protocols/cipher/iv_cipher.rb +99 -0
- data/lib/shadowsocks_ruby/protocols/cipher/no_iv_cipher.rb +53 -0
- data/lib/shadowsocks_ruby/protocols/cipher/verify_sha1.rb +138 -0
- data/lib/shadowsocks_ruby/protocols/obfs/http_simple.rb +189 -0
- data/lib/shadowsocks_ruby/protocols/obfs/tls_ticket.rb +342 -0
- data/lib/shadowsocks_ruby/protocols/packet/plain.rb +51 -0
- data/lib/shadowsocks_ruby/protocols/packet/shadowsocks.rb +88 -0
- data/lib/shadowsocks_ruby/protocols/packet/socks5.rb +162 -0
- data/lib/shadowsocks_ruby/protocols/protocol.rb +164 -0
- data/lib/shadowsocks_ruby/protocols/protocol_stack.rb +117 -0
- data/lib/shadowsocks_ruby/util.rb +52 -0
- data/lib/shadowsocks_ruby/version.rb +3 -0
- data/lib/shadowsocks_ruby.rb +86 -0
- data/shadowsocks_ruby.gemspec +48 -0
- metadata +290 -0
@@ -0,0 +1,164 @@
|
|
1
|
+
module ShadowsocksRuby
|
2
|
+
# Protocols are layered. Each layer know nothing about other layers.
|
3
|
+
# (data) | TOP: HTTP, FTP, STMP ... ^ (data)
|
4
|
+
# Pack | layer 3 protocol packet | Unpack
|
5
|
+
# Encrypt | layer 2 protocol cipher | Decrypt
|
6
|
+
# Obfuscate | layer 1 protocol obfuscate | DeObfuscate
|
7
|
+
# (opaque) V Bottom: TCP/UDP | (opaque)
|
8
|
+
#
|
9
|
+
#
|
10
|
+
# === Protocols
|
11
|
+
# There are 16 hooks can be called on protocols, which are:
|
12
|
+
# * tcp_receive_from_client
|
13
|
+
# * tcp_send_to_client
|
14
|
+
# * tcp_receive_from_remoteserver
|
15
|
+
# * tcp_send_to_remoteserver
|
16
|
+
# * tcp_receive_from_localbackend
|
17
|
+
# * tcp_send_to_localbackend
|
18
|
+
# * tcp_receive_from_destination
|
19
|
+
# * tcp_send_to_destination
|
20
|
+
# * udp_receive_from_client
|
21
|
+
# * udp_send_to_client
|
22
|
+
# * udp_receive_from_remoteserver
|
23
|
+
# * udp_send_to_remoteserver
|
24
|
+
# * udp_receive_from_localbackend
|
25
|
+
# * udp_send_to_localbackend
|
26
|
+
# * udp_receive_from_destination
|
27
|
+
# * udp_send_to_destination
|
28
|
+
#
|
29
|
+
# Each receive_from hook's job is to return data of exact length required by upper level protocol.
|
30
|
+
#
|
31
|
+
# Each send_to hook's job is to get the send work done, with the data it received from the upper level protocol.
|
32
|
+
#
|
33
|
+
# Each hook can call next layer protocols's corresponding receive_from and send_to hook,
|
34
|
+
#
|
35
|
+
# The bottom layer calls +Connection+'s corresponding receive_from and send_to hook.
|
36
|
+
#
|
37
|
+
# The +Connection+ then map corresponding receive_from and send_to hook to real data transfer
|
38
|
+
# methods +async_recv+ and +send_data+.
|
39
|
+
#
|
40
|
+
#
|
41
|
+
# @see Connections
|
42
|
+
# @see ProtocolStack
|
43
|
+
module Protocols
|
44
|
+
|
45
|
+
# This module include helper methods for a Packet/Cipher/Obfs Protocol.
|
46
|
+
#
|
47
|
+
# To simplify boring long method name writing (eg: tcp_receive_from_client, tcp_send_to_client),
|
48
|
+
# two Adapter method are introduced and could be untilized:
|
49
|
+
# +#async_recv+ and +#send_data+,
|
50
|
+
# they will be adapted to long method names (eg: tcp_receive_from_client, tcp_send_to_client) at runtime.
|
51
|
+
#
|
52
|
+
# This helper module implement dummy {#async_recv} and {#send_data}, do nothing but just raise,
|
53
|
+
# in order to make things clear.
|
54
|
+
#
|
55
|
+
# To use it, use +include DummyHelper+ to include it into your protocol implementation.
|
56
|
+
module DummyHelper
|
57
|
+
|
58
|
+
# Receive n bytes of data
|
59
|
+
# @param[Integer] n length of data to receive
|
60
|
+
# @raise ProtocolError
|
61
|
+
# @return [String] Should return real data on runtime
|
62
|
+
def async_recv n
|
63
|
+
raise ProtocolError, "async_recv must be set before use"
|
64
|
+
end
|
65
|
+
|
66
|
+
# Send data
|
67
|
+
# @param[String] data data to send
|
68
|
+
# @raise ProtocolError
|
69
|
+
def send_data data
|
70
|
+
raise ProtocolError, "send_data must be set before use"
|
71
|
+
end
|
72
|
+
|
73
|
+
# If user code don't want to implement a method, it can call this to raise Error.
|
74
|
+
# @raise UnimplementError
|
75
|
+
def raise_me *args
|
76
|
+
raise UnimplementError, "Some day may implement this: " + caller[0][/`.*'/][1..-2]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# This module include helper methods for deal with @buffer.
|
81
|
+
#
|
82
|
+
module BufferHelper
|
83
|
+
def tcp_receive_from_remoteserver_other_packet_helper n
|
84
|
+
if n == -1
|
85
|
+
return @buffer.slice!(0, @buffer.length)
|
86
|
+
elsif n < @buffer.length
|
87
|
+
class << self
|
88
|
+
alias tcp_receive_from_remoteserver tcp_receive_from_remoteserver_in_buffer
|
89
|
+
end
|
90
|
+
return @buffer.slice!(0, n)
|
91
|
+
else
|
92
|
+
if n == @buffer.length
|
93
|
+
return @buffer.slice!(0, n)
|
94
|
+
else
|
95
|
+
data = async_recv(n - @buffer.length)
|
96
|
+
return @buffer.slice!(0, n) << data
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def tcp_receive_from_remoteserver_in_buffer n
|
102
|
+
if n == -1
|
103
|
+
class << self
|
104
|
+
alias tcp_receive_from_remoteserver tcp_receive_from_remoteserver_other_packet
|
105
|
+
end
|
106
|
+
return @buffer.slice!(0, @buffer.length)
|
107
|
+
elsif n < @buffer.length
|
108
|
+
return @buffer.slice!(0, n)
|
109
|
+
else
|
110
|
+
class << self
|
111
|
+
alias tcp_receive_from_remoteserver tcp_receive_from_remoteserver_other_packet
|
112
|
+
end
|
113
|
+
if n == @buffer.length
|
114
|
+
return @buffer.slice!(0, n)
|
115
|
+
else
|
116
|
+
data = async_recv(n - @buffer.length)
|
117
|
+
return @buffer.slice!(0, n) << data
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def tcp_receive_from_localbackend_other_packet_helper n
|
123
|
+
if n == -1
|
124
|
+
return @buffer.slice!(0, @buffer.length)
|
125
|
+
elsif n < @buffer.length
|
126
|
+
class << self
|
127
|
+
alias tcp_receive_from_localbackend tcp_receive_from_localbackend_in_buffer
|
128
|
+
end
|
129
|
+
return @buffer.slice!(0, n)
|
130
|
+
else
|
131
|
+
if n == @buffer.length
|
132
|
+
return @buffer.slice!(0, n)
|
133
|
+
else
|
134
|
+
data = async_recv(n - @buffer.length)
|
135
|
+
return @buffer.slice!(0, n) << data
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
def tcp_receive_from_localbackend_in_buffer n
|
142
|
+
if n == -1
|
143
|
+
class << self
|
144
|
+
alias tcp_receive_from_localbackend tcp_receive_from_localbackend_other_packet
|
145
|
+
end
|
146
|
+
return @buffer.slice!(0, @buffer.length)
|
147
|
+
elsif n < @buffer.length
|
148
|
+
return @buffer.slice!(0, n)
|
149
|
+
else
|
150
|
+
class << self
|
151
|
+
alias tcp_receive_from_localbackend tcp_receive_from_localbackend_other_packet
|
152
|
+
end
|
153
|
+
if n == @buffer.length
|
154
|
+
return @buffer.slice!(0, n)
|
155
|
+
else
|
156
|
+
data = async_recv(n - @buffer.length)
|
157
|
+
return @buffer.slice!(0, n) << data
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require "to_camel_case"
|
2
|
+
|
3
|
+
module ShadowsocksRuby
|
4
|
+
module Protocols
|
5
|
+
|
6
|
+
# Factory class for build protocol stacks
|
7
|
+
#
|
8
|
+
# @see Protocols
|
9
|
+
class ProtocolStack
|
10
|
+
|
11
|
+
# @example This is what a cfg_ary Array look like
|
12
|
+
# [
|
13
|
+
# ["some_packet_protocol_name"], # a packet protocol is required
|
14
|
+
# ["some_cipher_protocol_name", {:cipher => "some_cipher_object"}], # a cipher protocol is optional
|
15
|
+
# ["some_obfs_protocol_name", {:obfs_params => "..."}] # a obfs protocol is optional
|
16
|
+
# ]
|
17
|
+
#
|
18
|
+
# @param [Array] cfg_ary
|
19
|
+
# @param [String] cipher_name
|
20
|
+
# @param [password] password
|
21
|
+
def initialize cfg_ary, cipher_name, password
|
22
|
+
@cfg_ary = cfg_ary.map do |protocol_name, param|
|
23
|
+
protocol_class = protocol_name.to_camel_case + "Protocol"
|
24
|
+
protocol_class = Protocols.const_get(protocol_class)
|
25
|
+
[protocol_class, param ||= {}]
|
26
|
+
end
|
27
|
+
@cipher_name = cipher_name
|
28
|
+
@password = password
|
29
|
+
end
|
30
|
+
|
31
|
+
# Factory method for build a protocol stack
|
32
|
+
#
|
33
|
+
# @param [EventMachine::Connection] conn
|
34
|
+
# @return top protocol (packet protocol) in the stack
|
35
|
+
def build! conn
|
36
|
+
cipher = nil
|
37
|
+
|
38
|
+
protocols = @cfg_ary.map do | klass, params|
|
39
|
+
case klass.to_s
|
40
|
+
when Protocols::PlainProtocol.to_s, Protocols::Socks5Protocol.to_s, \
|
41
|
+
Protocols::ShadowsocksProtocol.to_s, Protocols::HttpSimpleProtocol.to_s
|
42
|
+
# do nothing, these are known protocols don't need cipher
|
43
|
+
when Protocols::TlsTicketProtocol.to_s
|
44
|
+
# this protocol need a key
|
45
|
+
params = {:key => (cipher ||= Cipher.build(@cipher_name, @password)).key}.merge(params)
|
46
|
+
else
|
47
|
+
params = {:cipher => (cipher ||= Cipher.build(@cipher_name, @password))}.merge(params)
|
48
|
+
end
|
49
|
+
klass.new(params)
|
50
|
+
end
|
51
|
+
|
52
|
+
protocols.each_cons(2) do | p, p1 |
|
53
|
+
p.next_protocol = p1
|
54
|
+
end
|
55
|
+
|
56
|
+
protocols.last.tap do |p|
|
57
|
+
p.next_protocol = conn
|
58
|
+
end
|
59
|
+
|
60
|
+
protocols.each do |p|
|
61
|
+
case
|
62
|
+
when conn.is_a?(ShadowsocksRuby::Connections::TCP::ClientConnection)
|
63
|
+
class << p
|
64
|
+
extend Forwardable
|
65
|
+
def_delegator :@next_protocol, :tcp_receive_from_client, :async_recv
|
66
|
+
def_delegator :@next_protocol, :tcp_send_to_client, :send_data
|
67
|
+
end
|
68
|
+
when conn.is_a?(ShadowsocksRuby::Connections::TCP::RemoteServerConnection)
|
69
|
+
class << p
|
70
|
+
extend Forwardable
|
71
|
+
def_delegator :@next_protocol, :tcp_receive_from_remoteserver, :async_recv
|
72
|
+
def_delegator :@next_protocol, :tcp_send_to_remoteserver, :send_data
|
73
|
+
end
|
74
|
+
when conn.is_a?(ShadowsocksRuby::Connections::TCP::LocalBackendConnection)
|
75
|
+
class << p
|
76
|
+
extend Forwardable
|
77
|
+
def_delegator :@next_protocol, :tcp_receive_from_localbackend, :async_recv
|
78
|
+
def_delegator :@next_protocol, :tcp_send_to_localbackend, :send_data
|
79
|
+
end
|
80
|
+
when conn.is_a?(ShadowsocksRuby::Connections::TCP::DestinationConnection)
|
81
|
+
class << p
|
82
|
+
extend Forwardable
|
83
|
+
def_delegator :@next_protocol, :tcp_receive_from_destination, :async_recv
|
84
|
+
def_delegator :@next_protocol, :tcp_send_to_destination, :send_data
|
85
|
+
end
|
86
|
+
when conn.is_a?(ShadowsocksRuby::Connections::UDP::ClientConnection)
|
87
|
+
class << p
|
88
|
+
extend Forwardable
|
89
|
+
def_delegator :@next_protocol, :udp_receive_from_client, :async_recv
|
90
|
+
def_delegator :@next_protocol, :udp_send_to_client, :send_data
|
91
|
+
end
|
92
|
+
when conn.is_a?(ShadowsocksRuby::Connections::UDP::RemoteServerConnection)
|
93
|
+
class << p
|
94
|
+
extend Forwardable
|
95
|
+
def_delegator :@next_protocol, :udp_receive_from_remoteserver, :async_recv
|
96
|
+
def_delegator :@next_protocol, :udp_send_to_remoteserver, :send_data
|
97
|
+
end
|
98
|
+
when conn.is_a?(ShadowsocksRuby::Connections::UDP::LocalBackendConnection)
|
99
|
+
class << p
|
100
|
+
extend Forwardable
|
101
|
+
def_delegator :@next_protocol, :udp_receive_from_localbackend, :async_recv
|
102
|
+
def_delegator :@next_protocol, :udp_send_to_localbackend, :send_data
|
103
|
+
end
|
104
|
+
when conn.is_a?(ShadowsocksRuby::Connections::UDP::DestinationConnection)
|
105
|
+
class << p
|
106
|
+
extend Forwardable
|
107
|
+
def_delegator :@next_protocol, :udp_receive_from_destination, :async_recv
|
108
|
+
def_delegator :@next_protocol, :udp_send_to_destination, :send_data
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
protocols.first
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module ShadowsocksRuby
|
2
|
+
# Various utility functions
|
3
|
+
module Util
|
4
|
+
module_function
|
5
|
+
|
6
|
+
ATYP_IPV4 = 1
|
7
|
+
ATYP_DOMAIN = 3
|
8
|
+
ATYP_IPV6 = 4
|
9
|
+
|
10
|
+
# Hex encodes a message
|
11
|
+
#
|
12
|
+
# @param [String] bytes The bytes to encode
|
13
|
+
#
|
14
|
+
# @return [String] Tasty, tasty hexadecimal
|
15
|
+
def bin2hex(bytes)
|
16
|
+
bytes.to_s.unpack("H*").first
|
17
|
+
end
|
18
|
+
|
19
|
+
# Hex decodes a message
|
20
|
+
#
|
21
|
+
# @param [String] hex hex to decode.
|
22
|
+
#
|
23
|
+
# @return [String] crisp and clean bytes
|
24
|
+
def hex2bin(hex)
|
25
|
+
[hex.to_s].pack("H*")
|
26
|
+
end
|
27
|
+
|
28
|
+
# Parse address bytes
|
29
|
+
# @param [String] bytes The bytes to parse
|
30
|
+
# @return [Array<String, Integer>] Return Host, Port
|
31
|
+
def parse_address_bin(bytes)
|
32
|
+
address_type = bytes.slice!(0, 1).unpack("C").first
|
33
|
+
case address_type
|
34
|
+
when ATYP_IPV4
|
35
|
+
host = IPAddr.ntop bytes.slice!(0, 4)
|
36
|
+
port = bytes.slice!(0, 2).unpack('n').first
|
37
|
+
[host, port]
|
38
|
+
when ATYP_IPV6
|
39
|
+
host = IPAddr.ntop bytes.slice!(0, 16)
|
40
|
+
port = bytes.slice!(0, 2).unpack('n').first
|
41
|
+
[host, port]
|
42
|
+
when ATYP_DOMAIN
|
43
|
+
domain_len = bytes.slice!(0, 1).unpack("C").first
|
44
|
+
host = bytes.slice!(0, domain_len)
|
45
|
+
port = bytes.slice!(0, 2).unpack('n').first
|
46
|
+
[host, port]
|
47
|
+
else
|
48
|
+
raise PharseError, "unknown address_type: #{address_type}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'eventmachine'
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
require "shadowsocks_ruby/version"
|
6
|
+
require "shadowsocks_ruby/util"
|
7
|
+
require "shadowsocks_ruby/cipher/cipher"
|
8
|
+
require "shadowsocks_ruby/cipher/openssl"
|
9
|
+
|
10
|
+
%w[ openssl rbnacl rc4_md5 table ].each do |file|
|
11
|
+
require "shadowsocks_ruby/cipher/#{file}"
|
12
|
+
end
|
13
|
+
|
14
|
+
require "shadowsocks_ruby/protocols/protocol"
|
15
|
+
require "shadowsocks_ruby/protocols/protocol_stack"
|
16
|
+
|
17
|
+
# autoload protocols in these directories
|
18
|
+
%w[ packet cipher obfs ].each do |dir|
|
19
|
+
Dir[File.join(File.dirname(__FILE__) ,"shadowsocks_ruby", "protocols", dir , "*.rb")].each do |file|
|
20
|
+
file = File.basename(file,".rb")
|
21
|
+
require "shadowsocks_ruby/protocols/#{dir}/#{file}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
require "shadowsocks_ruby/connections/connection"
|
26
|
+
require "shadowsocks_ruby/connections/server_connection"
|
27
|
+
require "shadowsocks_ruby/connections/backend_connection"
|
28
|
+
|
29
|
+
%w[ client_connection remoteserver_connection localbackend_connection destination_connection ].each do |file|
|
30
|
+
require "shadowsocks_ruby/connections/tcp/#{file}"
|
31
|
+
end
|
32
|
+
|
33
|
+
%w[ client_connection remoteserver_connection localbackend_connection destination_connection ].each do |file|
|
34
|
+
require "shadowsocks_ruby/connections/udp/#{file}"
|
35
|
+
end
|
36
|
+
|
37
|
+
require "shadowsocks_ruby/app"
|
38
|
+
|
39
|
+
require "shadowsocks_ruby/cli/ssserver_runner"
|
40
|
+
require "shadowsocks_ruby/cli/sslocal_runner"
|
41
|
+
|
42
|
+
module ShadowsocksRuby
|
43
|
+
# This indicate a known failure by Shadowsock package.
|
44
|
+
# rescue this module will rescue all Shadowsocks known failure.
|
45
|
+
module MyErrorModule; end
|
46
|
+
# This indicates a failure in the App Class.
|
47
|
+
class AppError < ArgumentError
|
48
|
+
include MyErrorModule
|
49
|
+
end
|
50
|
+
|
51
|
+
# This indicates a failure in the Cipher Class.
|
52
|
+
class CipherError < ArgumentError
|
53
|
+
include MyErrorModule
|
54
|
+
end
|
55
|
+
|
56
|
+
# This indicates a failure in the Protocol Class.
|
57
|
+
class ProtocolError < ArgumentError
|
58
|
+
include MyErrorModule
|
59
|
+
end
|
60
|
+
|
61
|
+
# This indicates a failure in the Protocol pharse.
|
62
|
+
class PharseError < StandardError
|
63
|
+
include MyErrorModule
|
64
|
+
end
|
65
|
+
|
66
|
+
# This indicates a failure in Connection. A function is called out of fiber context.
|
67
|
+
class OutOfFiberContextError < StandardError
|
68
|
+
include MyErrorModule
|
69
|
+
end
|
70
|
+
|
71
|
+
# This indicates a failure in Connection
|
72
|
+
class ConnectionError < StandardError
|
73
|
+
include MyErrorModule
|
74
|
+
end
|
75
|
+
|
76
|
+
# This indicates a failure in Connection. The Buffer is oversized.
|
77
|
+
class BufferOversizeError < StandardError
|
78
|
+
include MyErrorModule
|
79
|
+
end
|
80
|
+
|
81
|
+
# This indicates something is unimplemented
|
82
|
+
class UnimplementError < StandardError
|
83
|
+
include MyErrorModule
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "shadowsocks_ruby/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "shadowsocks_ruby"
|
8
|
+
spec.version = ShadowsocksRuby::VERSION
|
9
|
+
spec.author = "zhenkyle"
|
10
|
+
spec.email = "zhenkyle@gmail.com"
|
11
|
+
|
12
|
+
spec.summary = %q{A flexible platform for writing tunnel proxy to help you bypass firewalls.}
|
13
|
+
spec.description = %q{ShadowsocksRuby is a flexible platform for writing [shadowsocks](https://github.com/shadowsocks/shadowsocks) like tunnel proxy to help you bypass firewalls.}
|
14
|
+
spec.homepage = "https://github.com/zhenkyle/shadowsocks_ruby"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
21
|
+
spec.metadata["yard.run"] = "yri" # use "yard" to build full HTML docs.
|
22
|
+
else
|
23
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
24
|
+
"public gem pushes."
|
25
|
+
end
|
26
|
+
|
27
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
28
|
+
f.match(%r{^(test|spec|features)/})
|
29
|
+
end
|
30
|
+
spec.bindir = "exe"
|
31
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
32
|
+
spec.require_paths = ["lib"]
|
33
|
+
|
34
|
+
spec.add_development_dependency "bundler", "~> 1.13"
|
35
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
36
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
37
|
+
spec.add_development_dependency "evented-spec", "~> 1.0.0.beta2"
|
38
|
+
spec.add_development_dependency "em-http-request", "~> 1.1.5"
|
39
|
+
spec.add_development_dependency('aruba', '~> 0.14.2')
|
40
|
+
spec.add_development_dependency('yard', '~> 0.9.8')
|
41
|
+
|
42
|
+
spec.add_runtime_dependency "eventmachine", "~> 1.2.1"
|
43
|
+
spec.add_runtime_dependency "rbnacl-libsodium", "~> 1.0.11"
|
44
|
+
spec.add_runtime_dependency "openssl", "~> 2.0.2"
|
45
|
+
spec.add_runtime_dependency "lrucache", "~> 0.1.4"
|
46
|
+
spec.add_runtime_dependency "to_camel_case", "~>1.0.0"
|
47
|
+
spec.add_runtime_dependency 'einhorn'
|
48
|
+
end
|