Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
actor-incubator
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
actor-incubator
Commits
050ee590
Commit
050ee590
authored
Sep 17, 2019
by
Joseph Noir
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Avoid temporary list for filtering
parent
bf7fb0ba
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
48 additions
and
65 deletions
+48
-65
libcaf_net/src/ip.cpp
libcaf_net/src/ip.cpp
+48
-65
No files found.
libcaf_net/src/ip.cpp
View file @
050ee590
...
@@ -80,29 +80,6 @@ int fetch_addr_str(char (&buf)[INET6_ADDRSTRLEN], sockaddr* addr) {
...
@@ -80,29 +80,6 @@ int fetch_addr_str(char (&buf)[INET6_ADDRSTRLEN], sockaddr* addr) {
:
AF_UNSPEC
;
:
AF_UNSPEC
;
}
}
void
find_by_name
(
const
vector
<
pair
<
string
,
ip_address
>>&
interfaces
,
string_view
name
,
vector
<
ip_address
>&
results
)
{
for
(
auto
&
p
:
interfaces
)
if
(
p
.
first
==
name
)
results
.
push_back
(
p
.
second
);
}
void
find_by_addr
(
const
vector
<
pair
<
string
,
ip_address
>>&
interfaces
,
ip_address
addr
,
vector
<
ip_address
>&
results
)
{
for
(
auto
&
p
:
interfaces
)
if
(
p
.
second
==
addr
)
results
.
push_back
(
p
.
second
);
}
void
find_localhost
(
const
vector
<
pair
<
string
,
ip_address
>>&
interfaces
,
vector
<
ip_address
>&
results
)
{
auto
v6_local
=
ip_address
{{
0
},
{
0x1
}};
auto
v4_local
=
ip_address
{
make_ipv4_address
(
127
,
0
,
0
,
1
)};
for
(
auto
&
p
:
interfaces
)
if
(
p
.
second
==
v4_local
||
p
.
second
==
v6_local
)
results
.
push_back
(
p
.
second
);
}
}
// namespace
}
// namespace
std
::
vector
<
ip_address
>
resolve
(
string_view
host
)
{
std
::
vector
<
ip_address
>
resolve
(
string_view
host
)
{
...
@@ -148,25 +125,22 @@ std::string hostname() {
...
@@ -148,25 +125,22 @@ std::string hostname() {
#ifdef CAF_WINDOWS
#ifdef CAF_WINDOWS
std
::
vector
<
ip_address
>
local_addresses
(
string_view
host
)
{
template
<
class
F
>
void
for_each_adapter
(
F
f
,
bool
is_link_local
)
{
using
adapters_ptr
=
std
::
unique_ptr
<
IP_ADAPTER_ADDRESSES
,
void
(
*
)(
void
*
)
>
;
using
adapters_ptr
=
std
::
unique_ptr
<
IP_ADAPTER_ADDRESSES
,
void
(
*
)(
void
*
)
>
;
if
(
host
==
v4_any_addr
)
return
{
ip_address
{
make_ipv4_address
(
0
,
0
,
0
,
0
)}};
if
(
host
==
v6_any_addr
)
return
{
ip_address
{}};
ULONG
len
=
0
;
ULONG
len
=
0
;
if
(
GetAdaptersAddresses
(
AF_UNSPEC
,
GAA_FLAG_INCLUDE_PREFIX
,
nullptr
,
nullptr
,
if
(
GetAdaptersAddresses
(
AF_UNSPEC
,
GAA_FLAG_INCLUDE_PREFIX
,
nullptr
,
nullptr
,
&
len
)
&
len
)
!=
ERROR_BUFFER_OVERFLOW
)
{
!=
ERROR_BUFFER_OVERFLOW
)
{
CAF_LOG_ERROR
(
"failed to get adapter addresses buffer length"
);
CAF_LOG_ERROR
(
"failed to get adapter addresses buffer length"
);
return
{}
;
return
;
}
}
auto
adapters
=
adapters_ptr
{
reinterpret_cast
<
IP_ADAPTER_ADDRESSES
*>
(
auto
adapters
=
adapters_ptr
{
reinterpret_cast
<
IP_ADAPTER_ADDRESSES
*>
(
::
malloc
(
len
),
::
malloc
(
len
),
free
};
free
};
if
(
!
adapters
)
{
if
(
!
adapters
)
{
CAF_LOG_ERROR
(
"malloc failed"
);
CAF_LOG_ERROR
(
"malloc failed"
);
return
{}
;
return
;
}
}
// TODO: The Microsoft WIN32 API example propopses to try three times, other
// TODO: The Microsoft WIN32 API example propopses to try three times, other
// examples online just perform the call once. If we notice the call to be
// examples online just perform the call once. If we notice the call to be
...
@@ -175,7 +149,7 @@ std::vector<ip_address> local_addresses(string_view host) {
...
@@ -175,7 +149,7 @@ std::vector<ip_address> local_addresses(string_view host) {
adapters
.
get
(),
&
len
)
adapters
.
get
(),
&
len
)
!=
ERROR_SUCCESS
)
{
!=
ERROR_SUCCESS
)
{
CAF_LOG_ERROR
(
"failed to get adapter addresses"
);
CAF_LOG_ERROR
(
"failed to get adapter addresses"
);
return
{}
;
return
;
}
}
char
ip_buf
[
INET6_ADDRSTRLEN
];
char
ip_buf
[
INET6_ADDRSTRLEN
];
char
name_buf
[
HOST_NAME_MAX
];
char
name_buf
[
HOST_NAME_MAX
];
...
@@ -191,39 +165,25 @@ std::vector<ip_address> local_addresses(string_view host) {
...
@@ -191,39 +165,25 @@ std::vector<ip_address> local_addresses(string_view host) {
getnameinfo
(
addr
->
Address
.
lpSockaddr
,
addr
->
Address
.
iSockaddrLength
,
getnameinfo
(
addr
->
Address
.
lpSockaddr
,
addr
->
Address
.
iSockaddrLength
,
ip_buf
,
sizeof
(
ip_buf
),
nullptr
,
0
,
NI_NUMERICHOST
);
ip_buf
,
sizeof
(
ip_buf
),
nullptr
,
0
,
NI_NUMERICHOST
);
ip_address
ip
;
ip_address
ip
;
if
(
auto
err
=
parse
(
ip_buf
,
ip
))
if
(
!
is_link_local
&&
starts_with
(
if_buf
,
"fe80:"
))
{
CAF_LOG_DEBUG
(
"skipping link-local address: "
<<
ip_buf
);
continue
;
continue
;
interfaces
.
emplace_back
(
name_buf
,
ip
);
}
else
if
(
auto
err
=
parse
(
ip_buf
,
ip
))
continue
;
f
(
name_buf
,
ip
);
}
}
}
}
std
::
vector
<
ip_address
>
results
;
ip_address
host_addr
;
if
(
host
.
empty
())
for
(
auto
&
p
:
interfaces
)
results
.
push_back
(
std
::
move
(
p
.
second
));
else
if
(
host
.
compare
(
localhost
)
==
0
)
find_localhost
(
interfaces
,
results
);
else
if
(
auto
err
=
parse
(
host
,
host_addr
))
find_by_name
(
interfaces
,
host
,
results
);
else
find_by_addr
(
interfaces
,
host_addr
,
results
);
return
results
;
}
}
#else // CAF_WINDOWS
#else // CAF_WINDOWS
std
::
vector
<
ip_address
>
local_addresses
(
string_view
host
)
{
template
<
class
F
>
if
(
host
==
v4_any_addr
)
void
for_each_adapter
(
F
f
,
bool
is_link_local
)
{
return
{
ip_address
{
make_ipv4_address
(
0
,
0
,
0
,
0
)}};
if
(
host
==
v6_any_addr
)
return
{
ip_address
{}};
ifaddrs
*
tmp
=
nullptr
;
ifaddrs
*
tmp
=
nullptr
;
if
(
getifaddrs
(
&
tmp
)
!=
0
)
if
(
getifaddrs
(
&
tmp
)
!=
0
)
return
{}
;
return
;
std
::
unique_ptr
<
ifaddrs
,
decltype
(
freeifaddrs
)
*>
addrs
{
tmp
,
freeifaddrs
};
std
::
unique_ptr
<
ifaddrs
,
decltype
(
freeifaddrs
)
*>
addrs
{
tmp
,
freeifaddrs
};
char
buffer
[
INET6_ADDRSTRLEN
];
char
buffer
[
INET6_ADDRSTRLEN
];
// Unless explicitly specified we are going to skip link-local addresses.
auto
is_link_local
=
starts_with
(
host
,
"fe80:"
);
std
::
vector
<
std
::
pair
<
std
::
string
,
ip_address
>>
interfaces
;
std
::
vector
<
std
::
pair
<
std
::
string
,
ip_address
>>
interfaces
;
for
(
auto
i
=
addrs
.
get
();
i
!=
nullptr
;
i
=
i
->
ifa_next
)
{
for
(
auto
i
=
addrs
.
get
();
i
!=
nullptr
;
i
=
i
->
ifa_next
)
{
auto
family
=
fetch_addr_str
(
buffer
,
i
->
ifa_addr
);
auto
family
=
fetch_addr_str
(
buffer
,
i
->
ifa_addr
);
...
@@ -236,25 +196,48 @@ std::vector<ip_address> local_addresses(string_view host) {
...
@@ -236,25 +196,48 @@ std::vector<ip_address> local_addresses(string_view host) {
CAF_LOG_ERROR
(
"could not parse into ip address "
<<
buffer
);
CAF_LOG_ERROR
(
"could not parse into ip address "
<<
buffer
);
continue
;
continue
;
}
}
interfaces
.
emplace_back
(
std
::
string
{
i
->
ifa_name
},
ip
);
f
({
i
->
ifa_name
,
strlen
(
i
->
ifa_name
)
},
ip
);
}
}
}
}
}
#endif // CAF_WINDOWS
std
::
vector
<
ip_address
>
local_addresses
(
string_view
host
)
{
// TODO: If is any addr, call resolve with PR #23.
if
(
host
==
v4_any_addr
)
return
{
ip_address
{
make_ipv4_address
(
0
,
0
,
0
,
0
)}};
if
(
host
==
v6_any_addr
)
return
{
ip_address
{}};
// Unless explicitly specified we are going to skip link-local addresses.
auto
is_link_local
=
starts_with
(
host
,
"fe80:"
);
std
::
vector
<
ip_address
>
results
;
std
::
vector
<
ip_address
>
results
;
ip_address
host_addr
;
ip_address
host_addr
;
if
(
host
.
empty
())
if
(
host
.
empty
())
{
for
(
auto
&
p
:
interfaces
)
for_each_adapter
([
&
](
string_view
,
ip_address
ip
)
{
results
.
push_back
(
std
::
move
(
p
.
second
));
results
.
push_back
(
ip
);
else
if
(
host
.
compare
(
localhost
)
==
0
)
},
is_link_local
);
find_localhost
(
interfaces
,
results
);
}
else
if
(
host
==
localhost
)
{
else
if
(
auto
err
=
parse
(
host
,
host_addr
))
auto
v6_local
=
ip_address
{{
0
},
{
0x1
}};
find_by_name
(
interfaces
,
host
,
results
);
auto
v4_local
=
ip_address
{
make_ipv4_address
(
127
,
0
,
0
,
1
)};
else
for_each_adapter
([
&
](
string_view
,
ip_address
ip
)
{
find_by_addr
(
interfaces
,
host_addr
,
results
);
if
(
ip
==
v4_local
||
ip
==
v6_local
)
results
.
push_back
(
ip
);
},
is_link_local
);
}
else
if
(
auto
err
=
parse
(
host
,
host_addr
))
{
for_each_adapter
([
&
](
string_view
iface
,
ip_address
ip
)
{
if
(
iface
==
host
)
results
.
push_back
(
ip
);
},
is_link_local
);
}
else
{
for_each_adapter
([
&
](
string_view
,
ip_address
ip
)
{
if
(
host_addr
==
ip
)
results
.
push_back
(
ip
);
},
is_link_local
);
}
return
results
;
return
results
;
}
}
#endif // CAF_WINDOWS
}
// namespace ip
}
// namespace ip
}
// namespace net
}
// namespace net
}
// namespace caf
}
// namespace caf
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment