Skip to content

Commit

Permalink
Merge pull request #10492 from straight-shoota/feature/socket-ipaddre…
Browse files Browse the repository at this point in the history
…ss-valid
  • Loading branch information
straight-shoota authored Sep 9, 2022
2 parents 8137fa6 + 77d204f commit 338e442
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 4 deletions.
18 changes: 18 additions & 0 deletions spec/std/socket/address_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,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
Expand Down
26 changes: 22 additions & 4 deletions src/socket/address.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -424,6 +441,7 @@ class Socket
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*)
Expand Down

0 comments on commit 338e442

Please sign in to comment.