Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add getipaddrs #30349

Merged
merged 9 commits into from
Dec 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Command-line option changes
New library functions
---------------------

* `getipaddrs()` function returns all the IP addresses of the local machine ([#30349])

Standard library changes
------------------------
Expand All @@ -39,3 +40,4 @@ Deprecated or removed
<!--- generated by NEWS-update.jl: -->
[#29998]: https://github.com/JuliaLang/julia/issues/29998
[#30323]: https://github.com/JuliaLang/julia/issues/30323
[#30349]: https://github.com/JuliaLang/julia/issues/30349
1 change: 1 addition & 0 deletions stdlib/Sockets/docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Sockets.listen(::Any)
Sockets.listen(::AbstractString)
Sockets.getaddrinfo
Sockets.getipaddr
Sockets.getipaddrs
Sockets.getalladdrinfo
Sockets.getnameinfo
Sockets.getsockname
Expand Down
1 change: 1 addition & 0 deletions stdlib/Sockets/src/Sockets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export
getalladdrinfo,
getnameinfo,
getipaddr,
getipaddrs,
getpeername,
getsockname,
listen,
Expand Down
41 changes: 41 additions & 0 deletions stdlib/Sockets/src/addrinfo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,44 @@ function getipaddr()
ccall(:uv_free_interface_addresses, Cvoid, (Ptr{UInt8}, Int32), addr, count)
return lo_present ? localhost : error("No networking interface available")
end

"""
getipaddrs(include_lo::Bool=false) -> Vector{IPv4}

Get the IP addresses of the local machine.

ararslan marked this conversation as resolved.
Show resolved Hide resolved
!!! compat "Julia 1.2"
This function is available as of Julia 1.2.

# Examples
```julia-repl
julia> getipaddrs()
2-element Array{IPv4,1}:
ip"10.255.0.183"
ip"172.17.0.1"
```
"""
function getipaddrs(include_lo::Bool=false)
addresses = IPv4[]
addr_ref = Ref{Ptr{UInt8}}(C_NULL)
count_ref = Ref{Int32}(1)
lo_present = false
err = ccall(:jl_uv_interface_addresses, Int32, (Ref{Ptr{UInt8}}, Ref{Int32}), addr_ref, count_ref)
uv_error("getlocalip", err)
addr, count = addr_ref[], count_ref[]
for i = 0:(count-1)
current_addr = addr + i*_sizeof_uv_interface_address
if 1 == ccall(:jl_uv_interface_address_is_internal, Int32, (Ptr{UInt8},), current_addr)
lo_present = true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dropping these seems odd to me. seems like these should probably be returned (with each entry being a namedtuple), or a perhaps configurable by function argument

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current behavior seems like it is a reasonable default, so we can add an option to list internal interfaces as well as external ones at a future time, although it would not be a bad addition to make in this PR given that this new feature won't land in a release until 1.2 in the spring.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added an include_lo argument.

julia> getipaddrs(false)
1-element Array{IPv4,1}:
 ip"10.255.0.183"

julia> getipaddrs()
1-element Array{IPv4,1}:
 ip"10.255.0.183"

julia> getipaddrs(true)
2-element Array{IPv4,1}:
 ip"127.0.0.1"   
 ip"10.255.0.183"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does my latest changes resolve this issue?

if !include_lo
continue
end
end
sockaddr = ccall(:jl_uv_interface_address_sockaddr, Ptr{Cvoid}, (Ptr{UInt8},), current_addr)
if ccall(:jl_sockaddr_in_is_ip4, Int32, (Ptr{Cvoid},), sockaddr) == 1
push!(addresses, IPv4(ntoh(ccall(:jl_sockaddr_host4, UInt32, (Ptr{Cvoid},), sockaddr))))
end
end
ccall(:uv_free_interface_addresses, Cvoid, (Ptr{UInt8}, Int32), addr, count)
return addresses
end
8 changes: 8 additions & 0 deletions stdlib/Sockets/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,14 @@ end
end
end

@testset "getipaddrs" begin
@test getipaddr() in getipaddrs()

@testset "include lo" begin
@test getipaddrs(true) >= getipaddrs()
end
end

@static if !Sys.iswindows()
# Issue #29234
@testset "TCPSocket stdin" begin
Expand Down