Apply IPV6_V6ONLY only when socket is AF_INET6

This commit is contained in:
yhirose 2020-05-04 22:16:43 -04:00
parent 1c50ac3667
commit 8728db7477

View File

@ -1198,20 +1198,18 @@ inline int close_socket(socket_t sock) {
#endif #endif
} }
template <typename T> template <typename T> inline ssize_t handle_EINTR(T fn) {
inline ssize_t handle_EINTR(T fn) {
ssize_t res = false; ssize_t res = false;
while (true) { while (true) {
res = fn(); res = fn();
if (res < 0 && errno == EINTR) { if (res < 0 && errno == EINTR) { continue; }
continue;
}
break; break;
} }
return res; return res;
} }
#define HANDLE_EINTR(method, ...) (handle_EINTR([&]() { return method(__VA_ARGS__); })) #define HANDLE_EINTR(method, ...) \
(handle_EINTR([&]() { return method(__VA_ARGS__); }))
inline ssize_t select_read(socket_t sock, time_t sec, time_t usec) { inline ssize_t select_read(socket_t sock, time_t sec, time_t usec) {
#ifdef CPPHTTPLIB_USE_POLL #ifdef CPPHTTPLIB_USE_POLL
@ -1231,7 +1229,8 @@ inline ssize_t select_read(socket_t sock, time_t sec, time_t usec) {
tv.tv_sec = static_cast<long>(sec); tv.tv_sec = static_cast<long>(sec);
tv.tv_usec = static_cast<decltype(tv.tv_usec)>(usec); tv.tv_usec = static_cast<decltype(tv.tv_usec)>(usec);
return HANDLE_EINTR(select, static_cast<int>(sock + 1), &fds, nullptr, nullptr, &tv); return HANDLE_EINTR(select, static_cast<int>(sock + 1), &fds, nullptr,
nullptr, &tv);
#endif #endif
} }
@ -1253,7 +1252,8 @@ inline ssize_t select_write(socket_t sock, time_t sec, time_t usec) {
tv.tv_sec = static_cast<long>(sec); tv.tv_sec = static_cast<long>(sec);
tv.tv_usec = static_cast<decltype(tv.tv_usec)>(usec); tv.tv_usec = static_cast<decltype(tv.tv_usec)>(usec);
return HANDLE_EINTR(select, static_cast<int>(sock + 1), nullptr, &fds, nullptr, &tv); return HANDLE_EINTR(select, static_cast<int>(sock + 1), nullptr, &fds,
nullptr, &tv);
#endif #endif
} }
@ -1286,7 +1286,8 @@ inline bool wait_until_socket_is_ready(socket_t sock, time_t sec, time_t usec) {
tv.tv_sec = static_cast<long>(sec); tv.tv_sec = static_cast<long>(sec);
tv.tv_usec = static_cast<decltype(tv.tv_usec)>(usec); tv.tv_usec = static_cast<decltype(tv.tv_usec)>(usec);
if (HANDLE_EINTR(select, static_cast<int>(sock + 1), &fdsr, &fdsw, &fdse, &tv) > 0 && if (HANDLE_EINTR(select, static_cast<int>(sock + 1), &fdsr, &fdsw, &fdse,
&tv) > 0 &&
(FD_ISSET(sock, &fdsr) || FD_ISSET(sock, &fdsw))) { (FD_ISSET(sock, &fdsr) || FD_ISSET(sock, &fdsw))) {
int error = 0; int error = 0;
socklen_t len = sizeof(error); socklen_t len = sizeof(error);
@ -1470,15 +1471,17 @@ socket_t create_socket(const char *host, int port, Fn fn,
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char *>(&yes), setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char *>(&yes),
sizeof(yes)); sizeof(yes));
int no = 0;
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char *>(&no),
sizeof(no));
#ifdef SO_REUSEPORT #ifdef SO_REUSEPORT
setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, reinterpret_cast<char *>(&yes), setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, reinterpret_cast<char *>(&yes),
sizeof(yes)); sizeof(yes));
#endif #endif
if (rp->ai_family == AF_INET6) {
int no = 0;
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char *>(&no),
sizeof(no));
}
// bind or connect // bind or connect
if (fn(sock, *rp)) { if (fn(sock, *rp)) {
freeaddrinfo(result); freeaddrinfo(result);
@ -5127,4 +5130,3 @@ namespace detail {
} // namespace httplib } // namespace httplib
#endif // CPPHTTPLIB_HTTPLIB_H #endif // CPPHTTPLIB_HTTPLIB_H