Module: Socksproxyable::InstanceMethodsConnect
- Included in:
- TCPSocket
- Defined in:
- lib/socksify/socksproxyable.rb
Overview
instance methods #socks_connect & #socks_receive_reply
Instance Method Summary collapse
-
#socks_connect(host, port) ⇒ Object
rubocop:disable Metrics.
-
#socks_receive_reply ⇒ Object
returns [bind_addr: String, bind_port: Fixnum] rubocop:disable Metrics.
Instance Method Details
#socks_connect(host, port) ⇒ Object
rubocop:disable Metrics
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/socksify/socksproxyable.rb', line 70 def socks_connect(host, port) port = Socket.getservbyname(port) if port.is_a?(String) req = +'' Socksify.debug_debug 'Sending destination address' req << TCPSocket.socks_version_hex Socksify.debug_debug TCPSocket.socks_version_hex.unpack 'H*' req << "\001" req << "\000" if self.class.socks_version == '5' req << [port].pack('n') if /^4/.match?(self.class.socks_version) host = Resolv::DNS.new.getaddress(host).to_s if self.class.socks_version == '4' Socksify.debug_debug host if host =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ # to IPv4 address req << "\001" if self.class.socks_version == '5' ip = (1..4).map { |i| Regexp.last_match(i).to_i }.pack('CCCC') req << ip elsif /^[:0-9a-f]+$/.match?(host) # to IPv6 address raise 'TCP/IPv6 over SOCKS is not yet supported (inet_pton missing in Ruby & not supported by Tor' # req << "\004" # UNREACHABLE elsif self.class.socks_version == '5' # to hostname # req << "\003" + [host.size].pack('C') + host req << "\003#{[host.size].pack('C')}#{host}" else req << "\000\000\000\001" << "\007\000" Socksify.debug_notice host req << host << "\000" end req << [port].pack('n') if self.class.socks_version == '5' write req socks_receive_reply Socksify.debug_notice "Connected to #{host}:#{port} over SOCKS" end |
#socks_receive_reply ⇒ Object
returns [bind_addr: String, bind_port: Fixnum] rubocop:disable Metrics
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 146 147 148 149 150 |
# File 'lib/socksify/socksproxyable.rb', line 105 def socks_receive_reply Socksify.debug_debug 'Waiting for SOCKS reply' if self.class.socks_version == '5' connect_reply = recv(4) raise SOCKSError, "Server doesn't reply" if connect_reply.empty? Socksify.debug_debug connect_reply.unpack 'H*' raise SOCKSError, "SOCKS version #{connect_reply[0..0]} is not 5" if connect_reply[0..0] != "\005" raise SOCKSError.for_response_code(connect_reply.bytes.to_a[1]) if connect_reply[1..1] != "\000" Socksify.debug_debug 'Waiting for bind_addr' bind_addr_len = case connect_reply[3..3] when "\001" 4 when "\003" recv(1).bytes.first when "\004" 16 else raise SOCKSError.for_response_code(connect_reply.bytes.to_a[3]) end bind_addr_s = recv(bind_addr_len) bind_addr = case connect_reply[3..3] when "\001" bind_addr_s.bytes.to_a.join('.') when "\003" bind_addr_s when "\004" # Untested! i = 0 ip6 = '' bind_addr_s.each_byte do |b| ip6 += ':' if i.positive? && i.even? i += 1 ip6 += b.to_s(16).rjust(2, '0') end end bind_port = recv(bind_addr_len + 2) [bind_addr, bind_port.unpack('n')] else connect_reply = recv(8) unless connect_reply[0] == "\000" && connect_reply[1] == "\x5A" Socksify.debug_debug connect_reply.unpack 'H' raise SOCKSError, 'Failed while connecting througth socks' end end end |