67 lines
1.4 KiB
Ruby
67 lines
1.4 KiB
Ruby
|
module EventMachine
|
||
|
module Protocols
|
||
|
# Basic SOCKS v4 client implementation
|
||
|
#
|
||
|
# Use as you would any regular connection:
|
||
|
#
|
||
|
# class MyConn < EM::P::Socks4
|
||
|
# def post_init
|
||
|
# send_data("sup")
|
||
|
# end
|
||
|
#
|
||
|
# def receive_data(data)
|
||
|
# send_data("you said: #{data}")
|
||
|
# end
|
||
|
# end
|
||
|
#
|
||
|
# EM.connect socks_host, socks_port, MyConn, host, port
|
||
|
#
|
||
|
class Socks4 < Connection
|
||
|
def initialize(host, port)
|
||
|
@host = Socket.gethostbyname(host).last
|
||
|
@port = port
|
||
|
@socks_error_code = nil
|
||
|
@buffer = ''
|
||
|
setup_methods
|
||
|
end
|
||
|
|
||
|
def setup_methods
|
||
|
class << self
|
||
|
def post_init; socks_post_init; end
|
||
|
def receive_data(*a); socks_receive_data(*a); end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def restore_methods
|
||
|
class << self
|
||
|
remove_method :post_init
|
||
|
remove_method :receive_data
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def socks_post_init
|
||
|
header = [4, 1, @port, @host, 0].flatten.pack("CCnA4C")
|
||
|
send_data(header)
|
||
|
end
|
||
|
|
||
|
def socks_receive_data(data)
|
||
|
@buffer << data
|
||
|
return if @buffer.size < 8
|
||
|
|
||
|
header_resp = @buffer.slice! 0, 8
|
||
|
_, r = header_resp.unpack("cc")
|
||
|
if r != 90
|
||
|
@socks_error_code = r
|
||
|
close_connection
|
||
|
return
|
||
|
end
|
||
|
|
||
|
restore_methods
|
||
|
|
||
|
post_init
|
||
|
receive_data(@buffer) unless @buffer.empty?
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|