Closed 636f7374 closed 4 years ago
I see you use sija/ipaddress.cr in maxminddb.cr/shard.yml, I think it can be replaced.
sija/ipaddress.cr
I have used it in my organization branch.
Dependencies cause some risks (in an uncontrolled environment).
Socket::IPAddress
Just a suggestion.
module MaxMindDB class Reader def get(address : String | Int) get Socket::IPAddress.new address, 0_i32 end def check_ip_type!(address : Socket::IPAddress) case {metadata.ipVersion, address.family} when {4_i32, Socket::Family::INET6} message = String.build do |io| io << "Error looking up " << "'" << address.to_s << "'" << ". " io << "You attempted to look up an IPv6 address in an IPv4-only database." end raise ArgumentError.new message end end def get(address : Socket::IPAddress) check_ip_type! address pointer = find_address_in_tree address return resolve_data_pointer pointer if 0_i32 < pointer Any.new Hash(String, Any).new end private def find_address_in_tree(address : Socket::IPAddress) : Int32 raise InvalidAddress.new unless raw_address = MaxMindDB.ip_address_to_bytes address # raw_address = address.data bit_size = raw_address.size * 8_i32 node_number = start_node bit_size bit_size.times do |i| break if node_number >= metadata.nodeCount index = raw_address[i >> 3_i32] bit = 1_i32 & (index >> 7_i32 - (i % 8_i32)) node_number = read_node node_number, bit end return 0_i32 if node_number == metadata.nodeCount return node_number if node_number > metadata.nodeCount raise InvalidDataBase.new "Something bad happened" end end end
module MaxMindDB class InvalidAddress < Exception end def self.ipv4_address_to_bytes(ip_address : Socket::IPAddress) : Bytes buffer = IO::Memory.new 4_i32 split = ip_address.address.split "." split.each { |part| buffer.write Bytes[part.to_u8] } buffer.to_slice end def self.ipv6_address_to_bytes(ip_address : Socket::IPAddress) : Bytes? return unless ip_address.family.inet6? pointer = ip_address.to_unsafe.as LibC::SockaddrIn6* memory = IO::Memory.new 16_i32 {% if flag? :darwin %} ipv6_address = pointer.value.sin6_addr.__u6_addr.__u6_addr8 memory.write ipv6_address.to_slice {% else %} ipv6_address = pointer.value.sin6_addr.__in6_u.__u6_addr8 memory.write ipv6_address.to_slice {% end %} memory.to_slice end def self.ip_address_to_bytes(ip_address : Socket::IPAddress) : Bytes? case ip_address.family when .inet6? ipv6_address_to_bytes ip_address else ipv4_address_to_bytes ip_address end end end
I just provide it as a reference, if you are interested, you can always improve it yourself.
Summary
I see you use
sija/ipaddress.cr
in maxminddb.cr/shard.yml, I think it can be replaced.I have used it in my organization branch.
Dependencies cause some risks (in an uncontrolled environment).
Socket::IPAddress
will make its semantic expression cleaner.Just a suggestion.
Improve