This is an automated email from the ASF dual-hosted git repository.
swebb2066 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git
The following commit(s) were added to refs/heads/master by this push:
new 9659f082 Ensure messages are delivered by TelnetAppender when the
socket is in a TIME_WAIT state (#495)
9659f082 is described below
commit 9659f082c59ce4535d6e0ab9bd7867c9121c0a4d
Author: michieldwitte <[email protected]>
AuthorDate: Sat Apr 19 04:03:09 2025 +0200
Ensure messages are delivered by TelnetAppender when the socket is in a
TIME_WAIT state (#495)
Co-authored-by: Michiel De Witte <[email protected]>
---
src/main/cpp/aprserversocket.cpp | 16 +++++++++++++++-
src/main/cpp/serversocket.cpp | 6 ++++++
src/main/cpp/telnetappender.cpp | 12 +++++++++++-
src/main/include/log4cxx/helpers/serversocket.h | 5 +++++
src/main/include/log4cxx/net/telnetappender.h | 12 ++++++++++++
src/main/include/log4cxx/private/aprserversocket.h | 5 +++++
src/test/cpp/net/socketappendertestcase.cpp | 2 +-
src/test/cpp/net/telnetappendertestcase.cpp | 1 +
8 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/src/main/cpp/aprserversocket.cpp b/src/main/cpp/aprserversocket.cpp
index e9d49c0c..b7bd27f5 100644
--- a/src/main/cpp/aprserversocket.cpp
+++ b/src/main/cpp/aprserversocket.cpp
@@ -35,7 +35,12 @@ struct APRServerSocket::APRServerSocketPriv : public
ServerSocketPrivate {
apr_socket_t* socket;
};
-APRServerSocket::APRServerSocket(int port) :
+#if LOG4CXX_ABI_VERSION <= 15
+APRServerSocket::APRServerSocket(int port) :
+ APRServerSocket(port, false) {}
+#endif
+
+APRServerSocket::APRServerSocket(int port, bool reuseAddress) :
ServerSocket(std::make_unique<APRServerSocketPriv>()){
apr_status_t status =
apr_socket_create(&_priv->socket, APR_INET, SOCK_STREAM,
@@ -53,6 +58,15 @@ APRServerSocket::APRServerSocket(int port) :
throw SocketException(status);
}
+ if (reuseAddress) {
+ apr_status_t status = apr_socket_opt_set(_priv->socket,
APR_SO_REUSEADDR, 1);
+
+ if (status != APR_SUCCESS)
+ {
+ throw SocketException(status);
+ }
+ }
+
// Create server socket address (including port number)
apr_sockaddr_t* server_addr;
status =
diff --git a/src/main/cpp/serversocket.cpp b/src/main/cpp/serversocket.cpp
index 1a12ec84..e696bd1c 100644
--- a/src/main/cpp/serversocket.cpp
+++ b/src/main/cpp/serversocket.cpp
@@ -51,6 +51,12 @@ void ServerSocket::setSoTimeout(int newVal)
m_priv->timeout = newVal;
}
+#if LOG4CXX_ABI_VERSION <= 15
ServerSocketUniquePtr ServerSocket::create(int port){
return std::make_unique<APRServerSocket>(port);
}
+#endif
+
+ServerSocketUniquePtr ServerSocket::create(int port, bool reuseAddress){
+ return std::make_unique<APRServerSocket>(port, reuseAddress);
+}
diff --git a/src/main/cpp/telnetappender.cpp b/src/main/cpp/telnetappender.cpp
index d012f66f..aa1374cd 100644
--- a/src/main/cpp/telnetappender.cpp
+++ b/src/main/cpp/telnetappender.cpp
@@ -58,6 +58,7 @@ struct TelnetAppender::TelnetAppenderPriv : public
AppenderSkeletonPrivate
{ stopAcceptingConnections(); }
int port;
+ bool reuseAddress = false;
ConnectionList connections;
LogString encoding;
LOG4CXX_NS::helpers::CharsetEncoderPtr encoder;
@@ -112,7 +113,7 @@ void TelnetAppender::activateOptions(Pool& /* p */)
{
if (_priv->serverSocket == NULL)
{
- _priv->serverSocket = ServerSocket::create(_priv->port);
+ _priv->serverSocket = ServerSocket::create(_priv->port,
_priv->reuseAddress);
_priv->serverSocket->setSoTimeout(1000);
}
@@ -135,6 +136,10 @@ void TelnetAppender::setOption(const LogString& option,
{
setEncoding(value);
}
+ else if (StringHelper::equalsIgnoreCase(option,
LOG4CXX_STR("REUSEADDRESS"), LOG4CXX_STR("reuseaddress")))
+ {
+ setReuseAddress(OptionConverter::toBoolean(value, true));
+ }
else
{
AppenderSkeleton::setOption(option, value);
@@ -358,6 +363,11 @@ void TelnetAppender::setMaxConnections(int newValue)
}
}
+void TelnetAppender::setReuseAddress(bool reuseAddress)
+{
+ _priv->reuseAddress = reuseAddress;
+}
+
bool TelnetAppender::requiresLayout() const
{
return false;
diff --git a/src/main/include/log4cxx/helpers/serversocket.h
b/src/main/include/log4cxx/helpers/serversocket.h
index aad824a3..5b7bd4a1 100644
--- a/src/main/include/log4cxx/helpers/serversocket.h
+++ b/src/main/include/log4cxx/helpers/serversocket.h
@@ -57,7 +57,12 @@ class LOG4CXX_EXPORT ServerSocket
*/
void setSoTimeout(int timeout);
+#if LOG4CXX_ABI_VERSION <= 15
static ServerSocketUniquePtr create(int port);
+ static ServerSocketUniquePtr create(int port, bool
reuseAddress);
+#else
+ static ServerSocketUniquePtr create(int port, bool reuseAddress
= false);
+#endif
};
} // namespace helpers
diff --git a/src/main/include/log4cxx/net/telnetappender.h
b/src/main/include/log4cxx/net/telnetappender.h
index 6af888c4..a35169b1 100644
--- a/src/main/include/log4cxx/net/telnetappender.h
+++ b/src/main/include/log4cxx/net/telnetappender.h
@@ -42,6 +42,9 @@ especially when monitoring a servlet remotely.
If no layout is provided, the log message only is sent to attached client(s).
+The ReuseAddress option is disabled by default,
+enable it if you want it to be able to bind to the address immediately after
restarting / crashing
+
See TelnetAppender::setOption() for the available options.
*/
@@ -96,6 +99,7 @@ class LOG4CXX_EXPORT TelnetAppender : public AppenderSkeleton
Port | {int} | 23
MaxConnections | {int} | 20
Encoding |
C,UTF-8,UTF-16,UTF-16BE,UTF-16LE,646,US-ASCII,ISO646-US,ANSI_X3.4-1968,ISO-8859-1,ISO-LATIN-1
| UTF-8
+ ReuseAddress | True,False | True
\sa AppenderSkeleton::setOption()
*/
@@ -125,6 +129,14 @@ class LOG4CXX_EXPORT TelnetAppender : public
AppenderSkeleton
*/
void setMaxConnections(int newValue);
+ /**
+ Set the SO_REUSEADDR option to of the server socket.
+ This allows the socket to bind to an address that is in a
TIME_WAIT state.
+ This is useful for restarting immediately after it has been
closed.
+
+ \sa setOption
+ */
+ void setReuseAddress(bool reuseAddress);
/** Shutdown this appender. */
void close() override;
diff --git a/src/main/include/log4cxx/private/aprserversocket.h
b/src/main/include/log4cxx/private/aprserversocket.h
index 07984d17..d8b3617f 100644
--- a/src/main/include/log4cxx/private/aprserversocket.h
+++ b/src/main/include/log4cxx/private/aprserversocket.h
@@ -31,7 +31,12 @@ namespace helpers
class LOG4CXX_EXPORT APRServerSocket : public helpers::ServerSocket
{
public:
+#if LOG4CXX_ABI_VERSION <= 15
APRServerSocket(int port);
+ APRServerSocket(int port, bool reuseAddress);
+#else
+ APRServerSocket(int port, bool reuseAddress = false);
+#endif
void close() override;
diff --git a/src/test/cpp/net/socketappendertestcase.cpp
b/src/test/cpp/net/socketappendertestcase.cpp
index 2d5accdd..607863f2 100644
--- a/src/test/cpp/net/socketappendertestcase.cpp
+++ b/src/test/cpp/net/socketappendertestcase.cpp
@@ -80,7 +80,7 @@ class SocketAppenderTestCase : public AppenderSkeletonTestCase
helpers::ServerSocketUniquePtr serverSocket;
try
{
- serverSocket =
helpers::ServerSocket::create(tcpPort);
+ serverSocket =
helpers::ServerSocket::create(tcpPort, true);
}
catch (std::exception& ex)
{
diff --git a/src/test/cpp/net/telnetappendertestcase.cpp
b/src/test/cpp/net/telnetappendertestcase.cpp
index b7aebbe5..1e5a7437 100644
--- a/src/test/cpp/net/telnetappendertestcase.cpp
+++ b/src/test/cpp/net/telnetappendertestcase.cpp
@@ -105,6 +105,7 @@ class TelnetAppenderTestCase : public
AppenderSkeletonTestCase
TelnetAppenderPtr appender(new TelnetAppender());
appender->setPort(TEST_PORT);
appender->setMaxConnections(1);
+ appender->setReuseAddress(true);
Pool p;
appender->activateOptions(p);
LoggerPtr root(Logger::getRootLogger());