class ShadowsocksRuby::Protocols::Socks5Protocol

SOCKS 5 protocol

specification :

@note Now only implemented the server side protocol, not the client side protocol.

Constants

ATYP_DOMAIN
ATYP_IPV4
ATYP_IPV6
CMD_CONNECT
METHOD_NO_AUTH
REP_SUCCESS
RESERVED
SOCKS5

Attributes

next_protocol[RW]

Public Class Methods

new(params = {}) click to toggle source

@param [Hash] configuration parameters

# File lib/shadowsocks_ruby/protocols/packet/socks5.rb, line 26
def initialize params = {}
  @params = {}.merge(params)
end

Public Instance Methods

tcp_receive_from_client(n)
tcp_receive_from_client_first_packet(n) click to toggle source
# File lib/shadowsocks_ruby/protocols/packet/socks5.rb, line 30
def tcp_receive_from_client_first_packet n
  # check version
  version = async_recv(1).unpack("C").first
  if version != SOCKS5
    raise PharseError, "SOCKS version not supported: #{version.inspect}"
  end

  # client handshake v5
  nmethods = async_recv(1).unpack("C").first
  *methods = async_recv(nmethods).unpack("C*")
  if methods.include?(METHOD_NO_AUTH)
    packet = [SOCKS5, METHOD_NO_AUTH].pack("C*")
    send_data packet
  else
    raise PharseError, 'Unsupported authentication method. Only "No Authentication" is supported'
  end

  version, command, reserved = async_recv(3).unpack("C3")
  buf =''
  buf << (s = async_recv(1))
  address_type = s.unpack("C").first
  case address_type
  when ATYP_IPV4
    buf << async_recv(4)
  when ATYP_IPV6
    buf << async_recv(16)
  when ATYP_DOMAIN
    buf << (s = async_recv(1))
    domain_len = s.unpack("C").first
    buf << async_recv(domain_len)
    buf << async_recv(2) # port
  else
    raise PharseError, "unknown address_type: #{address_type}"
  end 

  packet = ([SOCKS5, REP_SUCCESS, RESERVED, 1, 0, 0, 0, 0, 0]).pack("C8n")
  send_data packet
  class << self
    alias tcp_receive_from_client tcp_receive_from_client_other_packet
  end

  # first packet is special:
  # ATYP + Destination Address + Destination Port
  buf        
end
Also aliased as: tcp_receive_from_client
tcp_receive_from_client_other_packet(n) click to toggle source
# File lib/shadowsocks_ruby/protocols/packet/socks5.rb, line 78
def tcp_receive_from_client_other_packet n
  async_recv(n)
end
tcp_receive_from_localbackend(n)
tcp_receive_from_localbackend_first_packet(n) click to toggle source
# File lib/shadowsocks_ruby/protocols/packet/socks5.rb, line 86
def tcp_receive_from_localbackend_first_packet n
  # check version
  version = async_recv(1).unpack("C").first
  if version != SOCKS5
    raise PharseError, "SOCKS version not supported: #{version.inspect}"
  end

  # client handshake v5
  nmethods = async_recv(1).unpack("C").first
  *methods = async_recv(nmethods).unpack("C*")
  if methods.include?(METHOD_NO_AUTH)
    packet = [SOCKS5, METHOD_NO_AUTH].pack("C*")
    send_data packet
  else
    raise PharseError, 'Unsupported authentication method. Only "No Authentication" is supported'
  end

  version, command, reserved = async_recv(3).unpack("C3")
  buf =''
  buf << (s = async_recv(1))
  address_type = s.unpack("C").first
  case address_type
  when ATYP_IPV4
    buf << async_recv(4)
  when ATYP_IPV6
    buf << async_recv(16)
  when ATYP_DOMAIN
    buf << (s = async_recv(1))
    domain_len = s.unpack("C").first
    buf << async_recv(domain_len)
    buf << async_recv(2) # port
  else
    raise PharseError, "unknown address_type: #{address_type}"
  end

  packet = ([SOCKS5, REP_SUCCESS, RESERVED, 1, 0, 0, 0, 0, 0]).pack("C8n")
  send_data packet

  class << self
    alias tcp_receive_from_localbackend tcp_receive_from_localbackend_other_packet
  end

  # first packet is special:
  # ATYP + Destination Address + Destination Port
  buf                
end
tcp_receive_from_localbackend_other_packet(n) click to toggle source
# File lib/shadowsocks_ruby/protocols/packet/socks5.rb, line 135
def tcp_receive_from_localbackend_other_packet n
  async_recv(n)
end
tcp_send_to_client(data) click to toggle source
# File lib/shadowsocks_ruby/protocols/packet/socks5.rb, line 82
def tcp_send_to_client data
  send_data data
end
tcp_send_to_localbackend(data) click to toggle source
# File lib/shadowsocks_ruby/protocols/packet/socks5.rb, line 139
def tcp_send_to_localbackend data
  send_data data
end