From 48afcd604b2d797aad83bec25530c3b34dc7ec9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Wed, 10 Mar 2021 14:18:10 +0100 Subject: [PATCH 1/2] Add Socket::IPAddress.valid? --- spec/std/socket/address_spec.cr | 18 ++++++++++++++++++ src/socket/address.cr | 25 +++++++++++++++++++++---- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/spec/std/socket/address_spec.cr b/spec/std/socket/address_spec.cr index 500df202160a..873f06ab2c2c 100644 --- a/spec/std/socket/address_spec.cr +++ b/spec/std/socket/address_spec.cr @@ -98,6 +98,24 @@ describe Socket::IPAddress do end end + it ".valid_v6?" do + Socket::IPAddress.valid_v6?("::1").should be_true + Socket::IPAddress.valid_v6?("x").should be_false + Socket::IPAddress.valid_v6?("127.0.0.1").should be_false + end + + it ".valid_v4?" do + Socket::IPAddress.valid_v4?("127.0.0.1").should be_true + Socket::IPAddress.valid_v4?("::1").should be_false + Socket::IPAddress.valid_v4?("x").should be_false + end + + it ".valid?" do + Socket::IPAddress.valid?("127.0.0.1").should be_true + Socket::IPAddress.valid?("::1").should be_true + Socket::IPAddress.valid?("x").should be_false + end + it "#loopback?" do Socket::IPAddress.new("127.0.0.1", 0).loopback?.should be_true Socket::IPAddress.new("127.255.255.254", 0).loopback?.should be_true diff --git a/src/socket/address.cr b/src/socket/address.cr index 298ca77e89bb..6a210b45a32f 100644 --- a/src/socket/address.cr +++ b/src/socket/address.cr @@ -82,11 +82,11 @@ class Socket @addr : LibC::In6Addr | LibC::InAddr def initialize(@address : String, @port : Int32) - if addr = ip6?(address) + if addr = IPAddress.address_v6?(address) @addr = addr @family = Family::INET6 @size = sizeof(LibC::SockaddrIn6) - elsif addr = ip4?(address) + elsif addr = IPAddress.address_v4?(address) @addr = addr @family = Family::INET @size = sizeof(LibC::SockaddrIn) @@ -164,12 +164,29 @@ class Socket {% end %} end - private def ip6?(address) + # Returns `true` if *address* is a valid IPv4 or IPv6 address. + def self.valid?(address : String) : Bool + valid_v4?(address) || valid_v6?(address) + end + + # Returns `true` if *address* is a valid IPv4 address. + def self.valid_v6?(address : String) : Bool + !address_v6?(address).nil? + end + + # :nodoc: + protected def self.address_v6?(address : String) addr = uninitialized LibC::In6Addr addr if LibC.inet_pton(LibC::AF_INET6, address, pointerof(addr)) == 1 end - private def ip4?(address) + # Returns `true` if *address* is a valid IPv5 address. + def self.valid_v4?(address : String) : Bool + !address_v4?(address).nil? + end + + # :nodoc: + protected def self.address_v4?(address : String) addr = uninitialized LibC::InAddr addr if LibC.inet_pton(LibC::AF_INET, address, pointerof(addr)) == 1 end From 77fe25041a862a896050f0afcca25e3711cee3fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Thu, 8 Sep 2022 12:59:48 +0200 Subject: [PATCH 2/2] Deprecate Socket.ip? --- src/socket.cr | 1 + 1 file changed, 1 insertion(+) diff --git a/src/socket.cr b/src/socket.cr index 7781515f7e6e..6f401d5eaad9 100644 --- a/src/socket.cr +++ b/src/socket.cr @@ -517,6 +517,7 @@ class Socket < IO end # Returns `true` if the string represents a valid IPv4 or IPv6 address. + @[Deprecated("Use `IPAddress.valid?` instead")] def self.ip?(string : String) addr = LibC::In6Addr.new ptr = pointerof(addr).as(Void*)