Skip to content
Snippets Groups Projects
Commit 5ebe2918 authored by Olivier SOLDANO's avatar Olivier SOLDANO Committed by Guillaume Roguez
Browse files

fix infinite loop in PMTUD


When the TLS session was closed during path mtu discovery,
the EINTR signal was captured by the retry loop, causing
it to loop indefinitelly as the state of the session was
TlsSessionState::SHUTDOWN ; each retry triggering another EINTR
from TlsSessionImpl::waitForRawData, making gnutls_heartbeat_ping
to return GNUTLS_E_INTERRUPTED on the pong wait).
the guard to this loop was modified to take into account the state
of the session on GNUTLS_E_ITERRUPTED.

Another do/while loop was guarded by the same condition in
TlsSessionImpl::send, the same countermeasures have been
put in place.

Change-Id: Ib2ab8975c8044d9bac0abdcace94d79b5eeb75b9
Reviewed-by: default avatarPhilippe Gorley <philippe.gorley@savoirfairelinux.com>
parent 2da70bbf
Branches
No related tags found
No related merge requests found
......@@ -552,7 +552,7 @@ TlsSession::TlsSessionImpl::send(const ValueType* tx_data, std::size_t tx_size,
ssize_t nwritten;
do {
nwritten = gnutls_record_send(session_, data_seq, chunck_sz);
} while (nwritten == GNUTLS_E_INTERRUPTED or nwritten == GNUTLS_E_AGAIN);
} while ((nwritten == GNUTLS_E_INTERRUPTED and state_ != TlsSessionState::SHUTDOWN) or nwritten == GNUTLS_E_AGAIN);
if (nwritten <= 0) {
/* Normally we would have to retry record_send but our internal
* state has not changed, so we have to ask for more data first.
......@@ -887,6 +887,10 @@ TlsSession::TlsSessionImpl::handleStateMtuDiscovery(UNUSED TlsSessionState state
if (gnutls_heartbeat_allowed(session_, GNUTLS_HB_LOCAL_ALLOWED_TO_SEND) == 1) {
if (!isServer_) {
pathMtuHeartbeat();
if (state_ == TlsSessionState::SHUTDOWN) {
RING_ERR("[TLS] session destroyed while performing PMTUD, shuting down");
return TlsSessionState::SHUTDOWN;
}
pmtudOver_ = true;
}
} else {
......@@ -948,7 +952,7 @@ TlsSession::TlsSessionImpl::pathMtuHeartbeat()
do {
errno_send = gnutls_heartbeat_ping(session_, bytesToSend, HEARTBEAT_TRIES, GNUTLS_HEARTBEAT_WAIT);
} while (errno_send == GNUTLS_E_AGAIN || errno_send == GNUTLS_E_INTERRUPTED);
} while (errno_send == GNUTLS_E_AGAIN || (errno_send == GNUTLS_E_INTERRUPTED && state_ != TlsSessionState::SHUTDOWN));
if (errno_send != GNUTLS_E_SUCCESS) {
RING_DBG() << "[TLS] PMTUD: mtu " << mtu << " [FAILED]";
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment