Skip to content

Commit 3913527

Browse files
authored
✨ Add option to enable reuse address (#5)
1 parent b3ac5f9 commit 3913527

File tree

6 files changed

+22
-0
lines changed

6 files changed

+22
-0
lines changed

include/asyncpp/io/detail/io_engine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ namespace asyncpp::io::detail {
8484
virtual void socket_multicast_set_send_interface(socket_handle_t socket, address iface) = 0;
8585
virtual void socket_multicast_set_ttl(socket_handle_t socket, size_t ttl) = 0;
8686
virtual void socket_multicast_set_loopback(socket_handle_t socket, bool enabled) = 0;
87+
virtual void socket_allow_reuse_address(socket_handle_t socket, bool enabled) = 0;
8788
virtual void socket_shutdown(socket_handle_t socket, bool receive, bool send) = 0;
8889
virtual bool enqueue_connect(socket_handle_t socket, endpoint ep, completion_data* cd) = 0;
8990
virtual bool enqueue_accept(socket_handle_t socket, completion_data* cd) = 0;

include/asyncpp/io/socket.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ namespace asyncpp::io {
105105
void multicast_set_ttl(size_t ttl);
106106
void multicast_set_loopback(bool enabled);
107107

108+
void allow_reuse_address(bool enabled);
109+
108110
[[nodiscard]] detail::io_engine::socket_handle_t native_handle() const noexcept { return m_fd; }
109111
[[nodiscard]] detail::io_engine::socket_handle_t release() noexcept {
110112
if (m_io != nullptr && m_fd != detail::io_engine::invalid_socket_handle)

src/io_engine_generic_unix.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,12 @@ namespace asyncpp::io::detail {
234234
}
235235
}
236236

237+
void io_engine_generic_unix::socket_allow_reuse_address(socket_handle_t socket, bool enabled) {
238+
int val = enabled ? 1 : 0;
239+
auto res = setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&val), sizeof(val));
240+
if (res < 0) throw std::system_error(errno, std::system_category(), "setsockopt failed");
241+
}
242+
237243
void io_engine_generic_unix::socket_shutdown(socket_handle_t socket, bool receive, bool send) {
238244
int mode = 0;
239245
if (receive && send)

src/io_engine_generic_unix.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ namespace asyncpp::io::detail {
1919
void socket_multicast_set_send_interface(socket_handle_t socket, address iface) override;
2020
void socket_multicast_set_ttl(socket_handle_t socket, size_t ttl) override;
2121
void socket_multicast_set_loopback(socket_handle_t socket, bool enabled) override;
22+
void socket_allow_reuse_address(socket_handle_t socket, bool enabled) override;
2223
void socket_shutdown(socket_handle_t socket, bool receive, bool send) override;
2324

2425
file_handle_t file_open(const char* filename, std::ios_base::openmode mode) override;

src/io_engine_iocp.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ namespace asyncpp::io::detail {
8989
void socket_multicast_set_send_interface(socket_handle_t socket, address iface) override;
9090
void socket_multicast_set_ttl(socket_handle_t socket, size_t ttl) override;
9191
void socket_multicast_set_loopback(socket_handle_t socket, bool enabled) override;
92+
void socket_allow_reuse_address(socket_handle_t socket, bool enabled) override;
9293
void socket_shutdown(socket_handle_t socket, bool receive, bool send) override;
9394
bool enqueue_connect(socket_handle_t socket, endpoint ep, completion_data* cd) override;
9495
bool enqueue_accept(socket_handle_t socket, completion_data* cd) override;
@@ -452,6 +453,12 @@ namespace asyncpp::io::detail {
452453
}
453454
}
454455

456+
void io_engine_iocp::socket_allow_reuse_address(socket_handle_t socket, bool enabled) {
457+
int val = enabled ? 1 : 0;
458+
auto res = setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char*>(&val), sizeof(val));
459+
if (res < 0) throw std::system_error(WSAGetLastError(), std::system_category(), "setsockopt failed");
460+
}
461+
455462
void io_engine_iocp::socket_shutdown(socket_handle_t socket, bool receive, bool send) {
456463
int mode = 0;
457464
if (receive && send)

src/socket.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@ namespace asyncpp::io {
147147
m_io->engine()->socket_multicast_set_loopback(m_fd, enabled);
148148
}
149149

150+
void socket::allow_reuse_address(bool enabled) {
151+
if (m_fd == detail::io_engine::invalid_socket_handle) throw std::logic_error("invalid socket");
152+
m_io->engine()->socket_allow_reuse_address(m_fd, enabled);
153+
}
154+
150155
void socket::close_send() {
151156
if (m_fd == detail::io_engine::invalid_socket_handle) throw std::logic_error("invalid socket");
152157
m_io->engine()->socket_shutdown(m_fd, false, true);

0 commit comments

Comments
 (0)