in sources/Google.Solutions.Iap/Protocol/SshRelaySession.cs [325:420]
public async Task<uint> IoAsync(
Func<INetworkStream, Task<uint>> ioAction,
Func<INetworkStream, CancellationToken, Task> resendUnacknoledgedDataAction,
bool treatNormalCloseAsError,
CancellationToken cancellationToken)
{
var attempt = 0;
while (true)
{
try
{
var connection = await GetConnectionAsync(
resendUnacknoledgedDataAction,
cancellationToken)
.ConfigureAwait(false);
Debug.Assert(connection != null);
return await ioAction(connection!).ConfigureAwait(false);
}
catch (WebSocketStreamClosedByClientException)
{
throw;
}
catch (WebSocketStreamClosedByServerException e)
{
IapTraceSource.Log.TraceError(e);
switch ((SshRelayCloseCode)e.CloseStatus)
{
case SshRelayCloseCode.NORMAL:
case SshRelayCloseCode.DESTINATION_READ_FAILED:
case SshRelayCloseCode.DESTINATION_WRITE_FAILED:
//
// NB. We get a DESTINATION_*_FAILED if the
// backend closed the connection (as opposed
// to the relay).
//
if (treatNormalCloseAsError)
{
throw;
}
else
{
//
// Server closed the connection normally.
//
return 0;
}
case SshRelayCloseCode.NOT_AUTHORIZED:
throw new SshRelayDeniedException(
$"The server denied access: " +
e.CloseStatusDescription);
case SshRelayCloseCode.FAILED_TO_REWIND:
case SshRelayCloseCode.SID_UNKNOWN:
case SshRelayCloseCode.SID_IN_USE:
throw new SshRelayReconnectException(
"The server closed the connection unexpectedly and " +
"reestablishing the connection failed: " +
e.CloseStatusDescription);
case SshRelayCloseCode.FAILED_TO_CONNECT_TO_BACKEND:
throw new SshRelayConnectException(
"The server could not connect to the backend: " +
e.CloseStatusDescription);
case SshRelayCloseCode.LOOKUP_FAILED:
case SshRelayCloseCode.LOOKUP_FAILED_RECONNECT:
throw new SshRelayBackendNotFoundException(
"The backend could not be found");
default:
{
if (attempt++ >= MaxReconnects)
{
TraceVerbose($"Failed to reconnect after {attempt} attempts");
throw;
}
else
{
//
// Try again.
//
await DisconnectAsync(cancellationToken)
.ConfigureAwait(true);
TraceVerbose("Attempting to reconnect");
break;
}
}
}
}
}
}