[cpp-sp] branch dev/4.0.0 updated: SSPCPP-956 - Add "retryErrors" parameter to TCPListener directive
Scott Cantor
cantor.2 at osu.edu
Fri Nov 1 12:28:05 UTC 2024
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch dev/4.0.0
in repository cpp-sp.
View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=36bd2e91cc1bac1c17527052b02c515f6d24e370
The following commit(s) were added to refs/heads/dev/4.0.0 by this push:
new 36bd2e91 SSPCPP-956 - Add "retryErrors" parameter to TCPListener directive
36bd2e91 is described below
commit 36bd2e91cc1bac1c17527052b02c515f6d24e370
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Oct 24 09:58:07 2022 -0400
SSPCPP-956 - Add "retryErrors" parameter to TCPListener directive
https://shibboleth.atlassian.net/browse/SSPCPP-956
---
schemas/shibboleth-3.0-native-sp-config.xsd | 3 +-
shibsp/remoting/impl/SocketListener.cpp | 83 ++++++++++++++++++++++-------
shibsp/remoting/impl/SocketListener.h | 5 +-
shibsp/remoting/impl/TCPListener.cpp | 12 +++++
4 files changed, 83 insertions(+), 20 deletions(-)
diff --git a/schemas/shibboleth-3.0-native-sp-config.xsd b/schemas/shibboleth-3.0-native-sp-config.xsd
index 3f39260c..75a9df92 100644
--- a/schemas/shibboleth-3.0-native-sp-config.xsd
+++ b/schemas/shibboleth-3.0-native-sp-config.xsd
@@ -9,7 +9,7 @@
elementFormDefault="qualified"
attributeFormDefault="unqualified"
blockDefault="substitution"
- version="3.2">
+ version="3.4">
<import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd" />
<import namespace="urn:oasis:names:tc:SAML:2.0:assertion" schemaLocation="saml-schema-assertion-2.0.xsd"/>
@@ -874,6 +874,7 @@
<attribute name="clientPort" type="unsignedInt"/>
<attribute name="acl" type="conf:listOfStrings"/>
<attribute name="stackSize" type="unsignedInt"/>
+ <attribute name="retryErrors" type="conf:string"/>
</complexType>
</element>
<element name="Listener" type="conf:PluggableType"/>
diff --git a/shibsp/remoting/impl/SocketListener.cpp b/shibsp/remoting/impl/SocketListener.cpp
index 4c475376..55c5c38a 100644
--- a/shibsp/remoting/impl/SocketListener.cpp
+++ b/shibsp/remoting/impl/SocketListener.cpp
@@ -34,6 +34,9 @@
#include <stack>
#include <sstream>
#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
#include <xercesc/sax/SAXException.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>
@@ -223,6 +226,16 @@ bool SocketListener::init(bool force)
return true;
}
+void SocketListener::set_retry_errors(const string& retry_errors)
+{
+ const char* error_list = retry_errors.c_str();
+ std::vector<string> string_list;
+ boost::split(string_list, error_list, boost::is_any_of(", \t"), boost::token_compress_on);
+ for (vector<string>::const_iterator i = string_list.begin(); i != string_list.end(); ++i) {
+ m_retry_errors.push_back(atoi(i->c_str()));
+ }
+}
+
bool SocketListener::run(bool* shutdown)
{
#ifdef _DEBUG
@@ -325,36 +338,68 @@ DDF SocketListener::send(const DDF& in)
if (send(sock,(char*)&len,sizeof(len)) != sizeof(len) || send(sock,ostr.c_str(),outlen) != outlen) {
log_error();
this->close(sock);
- if (retry)
+ if (retry) {
retry--;
+ log->debug("retrying failed send");
+ }
else
throw ListenerException("Failure sending remoted message ($1).", params(1,in.name()));
}
else {
// SUCCESS.
+ log->debug("send completed, reading response message");
+
+ // Read the message size.
+ int size_read;
+ bool retry_error = false;
+ while ((size_read = recv(sock,(char*)&len,sizeof(len))) != sizeof(len)) {
+ // Apparently this happens when a signal interrupts the blocking call.
+ if (errno == EINTR) continue;
+
+ int native_error;
+ if (size_read == -1) {
+ log_error("reading size of output message", &native_error);
+ }
+ else {
+ log->error("error reading size of output message (%d != %d)", size_read, sizeof(len));
+ native_error = 0;
+ }
+ this->close(sock);
+
+ if (std::find(m_retry_errors.begin(), m_retry_errors.end(), native_error) != m_retry_errors.end()) {
+ log->debug("recv error %d is retryable", native_error);
+ if (retry) {
+ retry_error = true;
+ retry--;
+ break;
+ }
+ else {
+ log->debug("not retrying on second failure");
+ }
+ }
+ else {
+ log->debug("recv error %d is not retryable", native_error);
+ }
+
+ throw ListenerException("Failure receiving response to remoted message ($1).", params(1,in.name()));
+ }
+
+ // If recv had retryable error restart loop and try again
+ if (retry_error) {
+ log->debug("retrying");
+ retry_error = false;
+ continue;
+ }
+
+ len = ntohl(len);
retry = -1;
}
}
- log->debug("send completed, reading response message");
-
// Read the message.
- int size_read;
- while ((size_read = recv(sock,(char*)&len,sizeof(len))) != sizeof(len)) {
- if (errno == EINTR) continue; // Apparently this happens when a signal interrupts the blocking call.
- if (size_read == -1) {
- log_error("reading size of output message");
- }
- else {
- log->error("error reading size of output message (%d != %d)", size_read, sizeof(len));
- }
- this->close(sock);
- throw ListenerException("Failure receiving response to remoted message ($1).", params(1,in.name()));
- }
- len = ntohl(len);
-
char buf[16384];
stringstream is;
+ int size_read;
while (len) {
size_read = recv(sock, buf, sizeof(buf));
if (size_read > 0) {
@@ -400,7 +445,7 @@ DDF SocketListener::send(const DDF& in)
return out;
}
-bool SocketListener::log_error(const char* fn) const
+bool SocketListener::log_error(const char* fn, int* native_error) const
{
if (!fn)
fn = "unknown";
@@ -413,6 +458,8 @@ bool SocketListener::log_error(const char* fn) const
#else
int rc=errno;
#endif
+ if (native_error != nullptr)
+ *native_error = rc;
const char *msg;
#ifdef HAVE_STRERROR_R
char buf[256];
diff --git a/shibsp/remoting/impl/SocketListener.h b/shibsp/remoting/impl/SocketListener.h
index 5c6e34ba..4a183e68 100644
--- a/shibsp/remoting/impl/SocketListener.h
+++ b/shibsp/remoting/impl/SocketListener.h
@@ -79,13 +79,16 @@ namespace shibsp {
bool m_catchAll;
protected:
- bool log_error(const char* fn=nullptr) const; // for OS-level errors
+ void set_retry_errors(const std::string& retry_errors);
+ bool log_error(const char* fn=nullptr, int* native_error=nullptr) const; // for OS-level errors
xmltooling::logging::Category* log;
/// @endcond
private:
+
boost::scoped_ptr<SocketPool> m_socketpool;
bool* m_shutdown;
+ std::vector<int> m_retry_errors;
// Manage child threads
friend class ServerThread;
diff --git a/shibsp/remoting/impl/TCPListener.cpp b/shibsp/remoting/impl/TCPListener.cpp
index 89d61e34..ee437ae9 100644
--- a/shibsp/remoting/impl/TCPListener.cpp
+++ b/shibsp/remoting/impl/TCPListener.cpp
@@ -108,6 +108,7 @@ namespace shibsp {
static const XMLCh acl[] = UNICODE_LITERAL_3(a,c,l);
static const XMLCh clientAddress[] = UNICODE_LITERAL_13(c,l,i,e,n,t,A,d,d,r,e,s,s);
static const XMLCh clientPort[] = UNICODE_LITERAL_10(c,l,i,e,n,t,P,o,r,t);
+ static const XMLCh retryErrors[] = UNICODE_LITERAL_11(r,e,t,r,y,E,r,r,o,r,s);
};
TCPListener::TCPListener(const DOMElement* e) : SocketListener(e), m_port(0)
@@ -116,6 +117,17 @@ TCPListener::TCPListener(const DOMElement* e) : SocketListener(e), m_port(0)
if (SPConfig::getConfig().isEnabled(SPConfig::InProcess)) {
m_address = XMLHelper::getAttrString(e, nullptr, clientAddress);
m_port = XMLHelper::getAttrInt(e, 0, clientPort);
+ string retry_errors = XMLHelper::getAttrString(e, nullptr, retryErrors);
+ if (!retry_errors.empty()) {
+ if (retry_errors.find_first_not_of("0123456789, \t") == std::string::npos) {
+ log->info("retrying on error codes: %s", retry_errors.c_str());
+ set_retry_errors(retry_errors);
+ }
+ else {
+ log->error("invalid characters in retryErrors, skipping");
+ }
+
+ }
}
// Back-off to address setting, environment, or default.
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list