Explorar o código

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.
Timothy Flynn %!s(int64=2) %!d(string=hai) anos
pai
achega
fb83ceaf57

+ 7 - 1
Userland/Libraries/LibCore/TCPServer.cpp

@@ -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;

+ 6 - 1
Userland/Libraries/LibCore/TCPServer.h

@@ -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();