module SocksTunnel::Local::Server
Public Instance Methods
post_init()
click to toggle source
# File lib/socks_tunnel/local.rb, line 41 def post_init @fiber = Fiber.new do greeting loop { do_command } end end
receive_data(data)
click to toggle source
# File lib/socks_tunnel/local.rb, line 48 def receive_data(data) if @connection @connection.send_encoded_data(data.to_s) else @data = data @fiber = nil if @fiber.resume end end
unbind()
click to toggle source
# File lib/socks_tunnel/local.rb, line 57 def unbind @connection.close_connection if @connection end
Private Instance Methods
clear_data()
click to toggle source
# File lib/socks_tunnel/local.rb, line 146 def clear_data @data = nil end
do_command()
click to toggle source
IN ----
—–-------
——----------
———-+ |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT | ----
—–-------
——----------
———-+ | 1 | 1 | X'00' | 1 | Variable | 2 | ----
—–-------
——----------
———-+
OUT see the defination of reply_data
# File lib/socks_tunnel/local.rb, line 96 def do_command _, cmd, _, atype, addr_length = @data.unpack("C5") header_length = 0 case atype when 1, 4 # 1: ipv4, 4 bytes / 4: ipv6, 16 bytes ip_length = 4 * atype host = IPAddr.ntop @data[4, ip_length] port = @data[4 + ip_length, 2].unpack('S>').first header_length = ip_length + 6 when 3 # domain name host = @data[5, addr_length] port = @data[5 + addr_length, 2].unpack('S>').first header_length = addr_length + 7 else panic :address_type_not_supported end case cmd when 1 send_data reply_data(:success) @connection = EventMachine.connect(Config.remote_server_host, Config.remote_server_port, Connection) @connection.server = self @connection.send_encoded_data("#{host}:#{port}") @connection.send_encoded_data(@data[header_length, -1]) clear_data Fiber.yield when 2, 3 # bind, udp panic :command_not_supported else panic :command_not_supported end end
greeting()
click to toggle source
IN ----
———-----------
|VER | NMETHODS | METHODS | ----
———-----------
| 1 | 1 | 1 to 255 | ----
———-----------
OUT ----
——–+ |VER | METHOD | ----
——–+ | 1 | 1 | ----
——–+
# File lib/socks_tunnel/local.rb, line 76 def greeting ver = @data.unpack("C").first clear_data if ver == 5 send_data "\x05\x00" # NO AUTHENTICATION REQUIRED else send_data "\x05\xFF" # NO ACCEPTABLE METHODS end Fiber.yield end
panic(reply_type)
click to toggle source
# File lib/socks_tunnel/local.rb, line 150 def panic(reply_type) send_data reply_data(reply_type) Fiber.yield true end
reply_data(type)
click to toggle source
----
—–-------
——----------
———-+ |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | ----
—–-------
——----------
———-+ | 1 | 1 | X'00' | 1 | Variable | 2 | ----
—–-------
——----------
———-+
# File lib/socks_tunnel/local.rb, line 135 def reply_data(type) @replies_hash ||= begin { success: 0, command_not_supported: 7, address_type_not_supported: 8, }.map { |k, v| [k, ("\x05#{[v].pack('C')}\x00\x01\x00\x00\x00\x00\x00\x00")] }.to_h end @replies_hash[type] end