shadowsocks_ruby 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|