Class: ShadowsocksRuby::Protocols::Socks5Protocol::TCP::LocalBackend

Inherits:
Object
  • Object
show all
Defined in:
lib/shadowsocks_ruby/protocols/packet/socks5.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params = {}) ⇒ LocalBackend

Returns a new instance of LocalBackend.

Parameters:

  • params (Hash) (defaults to: {})

    Configuration parameters


95
96
97
# File 'lib/shadowsocks_ruby/protocols/packet/socks5.rb', line 95

def initialize params = {}
  @params = {}.merge(params)
end

Instance Attribute Details

#next_protocolObject

Returns the value of attribute next_protocol


92
93
94
# File 'lib/shadowsocks_ruby/protocols/packet/socks5.rb', line 92

def next_protocol
  @next_protocol
end

Instance Method Details

#async_recv_first_packet(n) ⇒ Object Also known as: async_recv


99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/shadowsocks_ruby/protocols/packet/socks5.rb', line 99

def async_recv_first_packet n
  x = @next_protocol  # check version

  version = x.async_recv(1).unpack("C").first
  if version != SOCKS5
    raise PharseError, "SOCKS version not supported: #{version.inspect}"
  end

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

  version, command, reserved = x.async_recv(3).unpack("C3")
  buf =''
  buf << (s = x.async_recv(1))
  address_type = s.unpack("C").first
  case address_type
  when ATYP_IPV4
    buf << x.async_recv(4)
  when ATYP_IPV6
    buf << x.async_recv(16)
  when ATYP_DOMAIN
    buf << (s = x.async_recv(1))
    domain_len = s.unpack("C").first
    buf << x.async_recv(domain_len)
    buf << x.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")
  x.send_data packet

  class << self
    alias async_recv async_recv_other_packet
  end

  # first packet is special:
  # ATYP + Destination Address + Destination Port
  buf                
end

#async_recv_other_packet(n) ⇒ Object


149
150
151
152
# File 'lib/shadowsocks_ruby/protocols/packet/socks5.rb', line 149

def async_recv_other_packet n
  x = @next_protocol
  x.async_recv(n)
end

#send_data(data) ⇒ Object


154
155
156
157
# File 'lib/shadowsocks_ruby/protocols/packet/socks5.rb', line 154

def send_data data
  x = @next_protocol
  x.send_data data
end