LibCore: Allow TCPServer's port to be reused after it exits

This hasn't been an issue on Serenity, but on Linux, if a program opens
a TCPServer on some port and then exits, that program can't be re-run
until the OS makes the port available again. This is usually ~2x the TCP
socket's maximum segment lifetime, upwards of a minute.

Add an option to TCPServer to allow re-using the port after the program
exits.
This commit is contained in:
Timothy Flynn 2022-11-14 08:28:43 -05:00 committed by Tim Flynn
parent 2675b9390b
commit fb83ceaf57
2 changed files with 13 additions and 2 deletions

View file

@ -39,13 +39,19 @@ TCPServer::~TCPServer()
MUST(Core::System::close(m_fd));
}
ErrorOr<void> TCPServer::listen(IPv4Address const& address, u16 port)
ErrorOr<void> TCPServer::listen(IPv4Address const& address, u16 port, AllowAddressReuse allow_address_reuse)
{
if (m_listening)
return Error::from_errno(EADDRINUSE);
auto socket_address = SocketAddress(address, port);
auto in = socket_address.to_sockaddr_in();
if (allow_address_reuse == AllowAddressReuse::Yes) {
int option = 1;
TRY(Core::System::setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)));
}
TRY(Core::System::bind(m_fd, (sockaddr const*)&in, sizeof(in)));
TRY(Core::System::listen(m_fd, 5));
m_listening = true;

View file

@ -20,8 +20,13 @@ public:
static ErrorOr<NonnullRefPtr<TCPServer>> try_create(Object* parent = nullptr);
virtual ~TCPServer() override;
enum class AllowAddressReuse {
Yes,
No,
};
bool is_listening() const { return m_listening; }
ErrorOr<void> listen(IPv4Address const& address, u16 port);
ErrorOr<void> listen(IPv4Address const& address, u16 port, AllowAddressReuse = AllowAddressReuse::No);
ErrorOr<void> set_blocking(bool blocking);
ErrorOr<NonnullOwnPtr<Stream::TCPSocket>> accept();