-
Notifications
You must be signed in to change notification settings - Fork 304
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HPCC-32715 SSL_connect/accept should honor timeout provided #19156
base: candidate-9.8.x
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -727,13 +727,16 @@ void CRemoteBase::connectSocket(SocketEndpoint &ep, unsigned connectTimeoutMs, u | |
//PrintStackReport(); | ||
} | ||
bool ok = true; | ||
unsigned connecttimeoutMs = DEFAULT_CONNECT_TIME; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rmtclient has it's own default connect time dafsConnectTimeoutMs |
||
try | ||
{ | ||
CCycleTimer timer; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. previously the timer was outside of the loop, i.e. 'connectTimeoutMs' was for the whole attempt time, now timer is (in effect) reset each attempt. Should move up outside of while loop. |
||
if (tm.timemon) | ||
{ | ||
unsigned remaining; | ||
if (tm.timemon->timedout(&remaining)) | ||
THROWJSOCKEXCEPTION(JSOCKERR_connection_failed); | ||
connecttimeoutMs = remaining; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this means there's 2 timing constructs, it would be better/cleaner to unify on 1. Also I've noticed a bizarre bug in the existing sRFTM. I think this code should either be:
OR, and I think preferable given other existing code in this method reliant on CTimeMon:
( and replace sRFTM tm(connectTimeoutMs); with CTimeMon timeMon(connectTimeoutMs); ) and similar for the secure_connect below. |
||
socket.setown(ISocket::connect_timeout(ep,remaining)); | ||
} | ||
else | ||
|
@@ -767,7 +770,8 @@ void CRemoteBase::connectSocket(SocketEndpoint &ep, unsigned connectTimeoutMs, u | |
} | ||
else | ||
ssock.setown(createSecureSocket(socket.getClear(), nullptr)); | ||
int status = ssock->secure_connect(); | ||
unsigned remainingMs = timer.remainingMs(connecttimeoutMs); | ||
int status = ssock->secure_connect(remainingMs); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see comments above re. using same timer construct (either the CTimeMon or new CCycleTimer) |
||
if (status < 0) | ||
throw createDafsException(DAFSERR_connection_failed, "Failure to establish secure connection"); | ||
socket.setown(ssock.getLink()); | ||
|
@@ -1128,7 +1132,7 @@ IDaFsConnection *createDaFsConnection(const SocketEndpoint &ep, DAFSConnectCfg c | |
|
||
///////////////////////// | ||
|
||
ISocket *checkSocketSecure(ISocket *socket) | ||
ISocket *checkSocketSecure(ISocket *socket, unsigned timeoutms = DEFAULT_CONNECT_TIME) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldn't this default be in the header? |
||
{ | ||
if (securitySettings.queryConnectMethod() == SSLNone) | ||
return LINK(socket); | ||
|
@@ -1144,7 +1148,7 @@ ISocket *checkSocketSecure(ISocket *socket) | |
try | ||
{ | ||
ssock.setown(createSecureSocket(LINK(socket), nullptr)); | ||
int status = ssock->secure_connect(); | ||
int status = ssock->secure_connect(timeoutms); | ||
if (status < 0) | ||
throw createDafsException(DAFSERR_connection_failed, "Failure to establish secure connection"); | ||
return ssock.getClear(); | ||
|
@@ -1173,6 +1177,7 @@ ISocket *connectDafs(SocketEndpoint &ep, unsigned timeoutms, const IPropertyTree | |
|
||
if (isContainerized()) | ||
{ | ||
CCycleTimer timer; | ||
socket.setown(ISocket::connect_timeout(ep, timeoutms)); | ||
|
||
if (service && service->getPropBool("@tls")) | ||
|
@@ -1182,7 +1187,8 @@ ISocket *connectDafs(SocketEndpoint &ep, unsigned timeoutms, const IPropertyTree | |
try | ||
{ | ||
ssock.setown(createSecureSocket(LINK(socket), service->queryProp("@issuer"))); | ||
int status = ssock->secure_connect(); | ||
unsigned remainingMs = timer.remainingMs(timeoutms); | ||
int status = ssock->secure_connect(remainingMs); | ||
if (status < 0) | ||
throw createDafsException(DAFSERR_connection_failed, "Failure to establish secure connection to dafilesrv"); | ||
return ssock.getClear(); | ||
|
@@ -1214,12 +1220,15 @@ ISocket *connectDafs(SocketEndpoint &ep, unsigned timeoutms, const IPropertyTree | |
{ | ||
if ( (securitySettings.queryConnectMethod() == SSLNone) || (securitySettings.queryConnectMethod() == SSLOnly) || (securitySettings.queryConnectMethod() == UnsecureAndSSL)) | ||
{ | ||
CCycleTimer timer; | ||
socket.setown(ISocket::connect_timeout(ep, timeoutms)); | ||
return checkSocketSecure(socket); | ||
unsigned remainingMs = timer.remainingMs(timeoutms); | ||
return checkSocketSecure(socket, remainingMs); | ||
} | ||
|
||
// SSLFirst or UnsecureFirst ... | ||
|
||
unsigned remainingMs; | ||
unsigned newtimeout = timeoutms; | ||
if (newtimeout > 5000) | ||
newtimeout = 5000; | ||
|
@@ -1229,10 +1238,12 @@ ISocket *connectDafs(SocketEndpoint &ep, unsigned timeoutms, const IPropertyTree | |
{ | ||
conAttempts--; | ||
bool connected = false; | ||
CCycleTimer timer; | ||
try | ||
{ | ||
socket.setown(ISocket::connect_timeout(ep, newtimeout)); | ||
connected = true; | ||
remainingMs = timer.remainingMs(newtimeout); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure this is right. Let's say connectDafs (.., timeoutms=60000, ..) maybe should be:
but CCycleTimer should be outside of attempts loop too I think. |
||
newtimeout = timeoutms; | ||
} | ||
catch (IJSOCK_Exception *e) | ||
|
@@ -1257,7 +1268,7 @@ ISocket *connectDafs(SocketEndpoint &ep, unsigned timeoutms, const IPropertyTree | |
{ | ||
try | ||
{ | ||
return checkSocketSecure(socket); | ||
return checkSocketSecure(socket, remainingMs); | ||
} | ||
catch (IDAFS_Exception *e) | ||
{ | ||
|
@@ -1343,7 +1354,7 @@ unsigned getRemoteVersion(ISocket *origSock, StringBuffer &ver) | |
if (!origSock) | ||
return 0; | ||
|
||
Owned<ISocket> socket = checkSocketSecure(origSock); | ||
Owned<ISocket> socket = checkSocketSecure(origSock, 10000); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. any significance to 10000 vs using default ? |
||
|
||
unsigned ret; | ||
MemoryBuffer sendbuf; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,7 +63,7 @@ extern DAFSCLIENT_API int getDafsInfo(ISocket * socket, unsigned level, StringBu | |
extern DAFSCLIENT_API void setDafsEndpointPort(SocketEndpoint &ep); | ||
extern DAFSCLIENT_API void setDafsLocalMountRedirect(const IpAddress &ip,const char *dir,const char *mountdir); | ||
extern DAFSCLIENT_API ISocket *connectDafs(SocketEndpoint &ep, unsigned timeoutms, const IPropertyTree *service); // NOTE: might alter ep.port if configured for multiple ports ... | ||
extern DAFSCLIENT_API ISocket *checkSocketSecure(ISocket *socket); | ||
extern DAFSCLIENT_API ISocket *checkSocketSecure(ISocket *socket, unsigned timeoutms); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cpp has unsigned timeoutms = DEFAULT_CONNECT_TIME, I suspect default should be here. |
||
extern DAFSCLIENT_API unsigned short getActiveDaliServixPort(const IpAddress &ip); | ||
extern DAFSCLIENT_API unsigned getDaliServixVersion(const IpAddress &ip,StringBuffer &ver); | ||
extern DAFSCLIENT_API unsigned getDaliServixVersion(const SocketEndpoint &ep,StringBuffer &ver); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -142,7 +142,7 @@ class CascadeManager : public CInterface | |
if (!ssock) | ||
throw makeStringException(ROXIE_TLS_ERROR, "Roxie CascadeManager failed creating secure socket for roxie control message"); | ||
|
||
int status = ssock->secure_connect(); | ||
int status = ssock->secure_connect(2000); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do wonder whether the secure socket connect/accept defaults should be different from the jsocket defaults. And then maybe this/other places, could generally rely on the defaults. |
||
if (status < 0) | ||
{ | ||
StringBuffer err; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,6 +44,8 @@ | |
#define WAIT_FOREVER ((unsigned)-1) | ||
#endif | ||
|
||
#define DEFAULT_CONNECT_TIME (100*1000) // for connect_wait | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. now used for accept too, prob. either worth updating the comment, or introducing another #define (or constexpr) for defaultAcceptTimeMs. |
||
|
||
enum JSOCKET_ERROR_CODES { | ||
JSOCKERR_ok = 0, | ||
JSOCKERR_not_opened = -1, // accept,name,peer_name,read,write | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1099,16 +1099,19 @@ protected: friend class CMPPacketReader; | |
} | ||
if (remaining<10000) | ||
remaining = 10000; // 10s min granularity for MP | ||
|
||
CCycleTimer timer; | ||
newsock.setown(ISocket::connect_timeout(remoteep,remaining)); | ||
|
||
#if defined(_USE_OPENSSL) | ||
if (parent->useTLS) | ||
{ | ||
Owned<ISecureSocket> ssock = secureContextClient->createSecureSocket(newsock.getClear()); | ||
int tlsTraceLevel = SSLogMin; | ||
if (parent->mpTraceLevel >= MPVerboseMsgThreshold) | ||
tlsTraceLevel = SSLogMax; | ||
int status = ssock->secure_connect(tlsTraceLevel); | ||
Owned<ISecureSocket> ssock = secureContextClient->createSecureSocket(newsock.getClear(), tlsTraceLevel); | ||
tm.timedout(&remaining); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think should be:
|
||
int status = ssock->secure_connect(remaining); | ||
if (status < 0) | ||
{ | ||
ssock->close(); | ||
|
@@ -2567,11 +2570,11 @@ int CMPConnectThread::run() | |
#if defined(_USE_OPENSSL) | ||
if (parent->useTLS) | ||
{ | ||
Owned<ISecureSocket> ssock = secureContextServer->createSecureSocket(sock.getClear()); | ||
int tlsTraceLevel = SSLogMin; | ||
if (parent->mpTraceLevel >= MPVerboseMsgThreshold) | ||
tlsTraceLevel = SSLogMax; | ||
int status = ssock->secure_accept(tlsTraceLevel); | ||
Owned<ISecureSocket> ssock = secureContextServer->createSecureSocket(sock.getClear(), tlsTraceLevel); | ||
int status = ssock->secure_accept(10000); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see other comment(s). There's a few different constants used for secure_connect/secure_accept, in most cases sensible defaults should be used. I think secure socket connect/accept should have different defaults to jsocket's raw socket connect/accept. They are not expected to have the same timing semantics. |
||
if (status < 0) | ||
{ | ||
ssock->close(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remainingMs could be zero here (due to some weird delay in createSecureSocket),
but strictly speaking it should probably abort if so before trying to call secure_connect.