Skip to content

Commit 250aecc

Browse files
mgkuhnKeno
authored andcommitted
Sockets: fix getipaddr/getipaddrs documentation, add islinklocaladdr function (#34300)
* fix getipaddr/getipaddrs documentation - resolved IPv4/IPv6 confusion, e.g. getipaddrs() does _not_ return only IPv4 - more realistic example addresses - example addresses taken from address ranges reserved for documentation https://en.wikipedia.org/wiki/Reserved_IP_addresses * add Sockets.islinklocaladdr IPv6 interfaces always have a link-local address configured, which is also reported by getipaddrs(). However, typical application servers are not reachable under their link-local address, therefore this convenience function helps users of getipaddrs() to filter out such addresses with `filter(!islinklocaladdr, getipaddrs())`. This commits also adds a "See also" hint that in applications where a server process has been started remotely via ssh that `split(ENV["SSH_CONNECTION"], ' ')[3]` can be a preferable alternative source for the IP address under which this server is reachable (namely the address that ssh has already used successfully to get here).
1 parent 5315476 commit 250aecc

File tree

5 files changed

+59
-12
lines changed

5 files changed

+59
-12
lines changed

stdlib/Sockets/docs/src/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Sockets.listen(::AbstractString)
99
Sockets.getaddrinfo
1010
Sockets.getipaddr
1111
Sockets.getipaddrs
12+
Sockets.islinklocaladdr
1213
Sockets.getalladdrinfo
1314
Sockets.DNSError
1415
Sockets.getnameinfo

stdlib/Sockets/src/IPAddr.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ function parse(::Type{IPv6}, str::AbstractString)
238238
end
239239

240240
#
241-
# This support IPv4 addresses in the common dot (IPv4) or colon (IPv6)
241+
# This supports IP addresses in the common dot (IPv4) or colon (IPv6)
242242
# separated formats. Most other common formats use a standard integer encoding
243243
# of the appropriate size and should use the appropriate constructor
244244
#

stdlib/Sockets/src/Sockets.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export
1414
getnameinfo,
1515
getipaddr,
1616
getipaddrs,
17+
islinklocaladdr,
1718
getpeername,
1819
getsockname,
1920
listen,

stdlib/Sockets/src/addrinfo.jl

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,9 @@ addresses are available.
241241
Get an IP address of the local machine of the specified type. Throws if no
242242
addresses of the specified type are available.
243243
244+
This function is a backwards-compatibility wrapper around [`getipaddrs`](@ref).
245+
New applications should use [`getipaddrs`](@ref) instead.
246+
244247
# Examples
245248
```julia-repl
246249
julia> getipaddr()
@@ -249,6 +252,8 @@ ip"192.168.1.28"
249252
julia> getipaddr(IPv6)
250253
ip"fe80::9731:35af:e1c5:6e49"
251254
```
255+
256+
See also: [`getipaddrs`](@ref)
252257
"""
253258
function getipaddr(addr_type::Type{T}) where T<:IPAddr
254259
addrs = getipaddrs(addr_type)
@@ -265,31 +270,35 @@ getipaddr() = getipaddr(IPv4)
265270

266271

267272
"""
268-
getipaddrs(; loopback::Bool=false) -> Vector{IPAddr}
273+
getipaddrs(addr_type::Type{T}=IPAddr; loopback::Bool=false) where T<:IPAddr -> Vector{T}
269274
270-
Get the IPv4 addresses of the local machine.
275+
Get the IP addresses of the local machine.
271276
272-
getipaddrs(addr_type::Type{T}; loopback::Bool=false) where T<:IPAddr -> Vector{T}
277+
Setting the optional `addr_type` parameter to `IPv4` or `IPv6` causes only addresses of that type to be returned.
273278
274-
Get the IP addresses of the local machine of the specified type.
275-
276-
The `loopback` keyword argument dictates whether loopback addresses are included.
279+
The `loopback` keyword argument dictates whether loopback addresses (e.g. `ip"127.0.0.1"`, `ip"::1"`) are included.
277280
278281
!!! compat "Julia 1.2"
279282
This function is available as of Julia 1.2.
280283
281284
# Examples
282285
```julia-repl
283286
julia> getipaddrs()
284-
2-element Array{IPv4,1}:
285-
ip"10.255.0.183"
286-
ip"172.17.0.1"
287+
5-element Array{IPAddr,1}:
288+
ip"198.51.100.17"
289+
ip"203.0.113.2"
290+
ip"2001:db8:8:4:445e:5fff:fe5d:5500"
291+
ip"2001:db8:8:4:c164:402e:7e3c:3668"
292+
ip"fe80::445e:5fff:fe5d:5500"
287293
288294
julia> getipaddrs(IPv6)
289-
2-element Array{IPv6,1}:
290-
ip"fe80::9731:35af:e1c5:6e49"
295+
3-element Array{IPv6,1}:
296+
ip"2001:db8:8:4:445e:5fff:fe5d:5500"
297+
ip"2001:db8:8:4:c164:402e:7e3c:3668"
291298
ip"fe80::445e:5fff:fe5d:5500"
292299
```
300+
301+
See also: [`islinklocaladdr`](@ref), `split(ENV["SSH_CONNECTION"], ' ')[3]`
293302
"""
294303
function getipaddrs(addr_type::Type{T}=IPAddr; loopback::Bool=false) where T<:IPAddr
295304
addresses = T[]
@@ -319,3 +328,29 @@ function getipaddrs(addr_type::Type{T}=IPAddr; loopback::Bool=false) where T<:IP
319328
ccall(:uv_free_interface_addresses, Cvoid, (Ptr{UInt8}, Int32), addr, count)
320329
return addresses
321330
end
331+
332+
"""
333+
islinklocaladdr(addr::IPAddr)
334+
335+
Tests if an IP address is a link-local address. Link-local addresses
336+
are not guaranteed to be unique beyond their network segment,
337+
therefore routers do not forward them. Link-local addresses are from
338+
the address blocks `169.254.0.0/16` or `fe80::/10`.
339+
340+
# Example
341+
```julia
342+
filter(!islinklocaladdr, getipaddrs())
343+
```
344+
"""
345+
function islinklocaladdr(addr::IPv4)
346+
# RFC 3927
347+
return (addr.host &
348+
0xFFFF0000) ==
349+
0xA9FE0000
350+
end
351+
function islinklocaladdr(addr::IPv6)
352+
# RFC 4291
353+
return (addr.host &
354+
0xFFC00000000000000000000000000000) ==
355+
0xFE800000000000000000000000000000
356+
end

stdlib/Sockets/test/runtests.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,16 @@ end
507507
end
508508
end
509509

510+
@testset "address scope" begin
511+
@test islinklocaladdr(ip"169.254.1.0")
512+
@test islinklocaladdr(ip"169.254.254.255")
513+
@test islinklocaladdr(ip"fe80::")
514+
@test islinklocaladdr(ip"febf::")
515+
@test !islinklocaladdr(ip"127.0.0.1")
516+
@test !islinklocaladdr(ip"2001::")
517+
518+
end
519+
510520
@static if !Sys.iswindows()
511521
# Issue #29234
512522
@testset "TCPSocket stdin" begin

0 commit comments

Comments
 (0)