6 #include <glog/logging.h>
8 static bool is_ipv4_mapped_ipv6_addresses(in6_addr
const& sa
)
11 return sa
.s6_addr
[0] == 0 &&
21 sa
.s6_addr
[10] == 0xff &&
22 sa
.s6_addr
[11] == 0xff;
28 std::function
<void(void)> read_hook
,
29 std::chrono::milliseconds read_timeout
,
30 std::chrono::milliseconds write_timeout
,
31 std::chrono::milliseconds starttls_timeout
)
33 fd_in
, fd_out
, read_hook
, read_timeout
, write_timeout
, starttls_timeout
)
35 // Get our local IP address as "us".
37 if (-1 == getsockname(fd_in
, &us_addr_
.addr
, &us_addr_len_
)) {
38 // Ignore ENOTSOCK errors from getsockname, useful for testing.
39 PLOG_IF(WARNING
, ENOTSOCK
!= errno
) << "getsockname failed";
42 switch (us_addr_len_
) {
43 case sizeof(sockaddr_in
):
44 PCHECK(inet_ntop(AF_INET
, &us_addr_
.addr_in
.sin_addr
, us_addr_str_
,
47 us_address_literal_
= IP4::to_address_literal(us_addr_str_
);
49 case sizeof(sockaddr_in6
):
50 PCHECK(inet_ntop(AF_INET6
, &us_addr_
.addr_in6
.sin6_addr
, us_addr_str_
,
53 us_address_literal_
= IP6::to_address_literal(us_addr_str_
);
56 LOG(FATAL
) << "bogus address length (" << us_addr_len_
57 << ") returned from getsockname";
61 // Get the remote IP address as "them".
63 if (-1 == getpeername(fd_out
, &them_addr_
.addr
, &them_addr_len_
)) {
64 // Ignore ENOTSOCK errors from getpeername, useful for testing.
65 PLOG_IF(WARNING
, ENOTSOCK
!= errno
) << "getpeername failed";
68 switch (them_addr_len_
) {
69 case sizeof(sockaddr_in
):
70 PCHECK(inet_ntop(AF_INET
, &them_addr_
.addr_in
.sin_addr
, them_addr_str_
,
71 sizeof them_addr_str_
)
73 them_address_literal_
= IP4::to_address_literal(them_addr_str_
);
76 case sizeof(sockaddr_in6
):
77 if (is_ipv4_mapped_ipv6_addresses(them_addr_
.addr_in6
.sin6_addr
)) {
78 PCHECK(inet_ntop(AF_INET
, &them_addr_
.addr_in6
.sin6_addr
.s6_addr
[12],
79 them_addr_str_
, sizeof them_addr_str_
)
81 them_address_literal_
= IP4::to_address_literal(them_addr_str_
);
82 // LOG(INFO) << "IPv4 disguised as IPv6: " << them_addr_str_;
85 PCHECK(inet_ntop(AF_INET6
, &them_addr_
.addr_in6
.sin6_addr
,
86 them_addr_str_
, sizeof them_addr_str_
)
88 them_address_literal_
= IP6::to_address_literal(them_addr_str_
);
93 LOG(FATAL
) << "bogus address length (" << them_addr_len_
94 << ") returned from getpeername";