mirror of https://github.com/aria2/aria2
WinTLS: Fix abrupt connection closing and closing in general.
Fixes GH-277pull/287/head
parent
04f875e273
commit
e0d6d04fe8
|
@ -134,8 +134,7 @@ WinTLSSession::WinTLSSession(WinTLSContext* ctx)
|
||||||
cred_(ctx->getCredHandle()),
|
cred_(ctx->getCredHandle()),
|
||||||
writeBuffered_(0),
|
writeBuffered_(0),
|
||||||
state_(st_constructed),
|
state_(st_constructed),
|
||||||
status_(SEC_E_OK),
|
status_(SEC_E_OK)
|
||||||
eof_(false)
|
|
||||||
{
|
{
|
||||||
memset(&handle_, 0, sizeof(handle_));
|
memset(&handle_, 0, sizeof(handle_));
|
||||||
}
|
}
|
||||||
|
@ -170,11 +169,17 @@ int WinTLSSession::setSNIHostname(const std::string& hostname)
|
||||||
|
|
||||||
int WinTLSSession::closeConnection()
|
int WinTLSSession::closeConnection()
|
||||||
{
|
{
|
||||||
if (state_ != st_connected || state_ != st_closing) {
|
if (state_ != st_connected && state_ != st_closing) {
|
||||||
|
if (state_ != st_error) {
|
||||||
|
status_ = SEC_E_INVALID_HANDLE;
|
||||||
|
state_ = st_error;
|
||||||
|
}
|
||||||
|
A2_LOG_DEBUG("WinTLS: Cannot close connection");
|
||||||
return TLS_ERR_ERROR;
|
return TLS_ERR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state_ == st_connected) {
|
if (state_ == st_connected) {
|
||||||
|
A2_LOG_DEBUG("WinTLS: Closing connection");
|
||||||
state_ = st_closing;
|
state_ = st_closing;
|
||||||
|
|
||||||
DWORD dwShut = SCHANNEL_SHUTDOWN;
|
DWORD dwShut = SCHANNEL_SHUTDOWN;
|
||||||
|
@ -239,6 +244,7 @@ int WinTLSSession::closeConnection()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
A2_LOG_DEBUG("WinTLS: Closed Connection");
|
||||||
state_ = st_closed;
|
state_ = st_closed;
|
||||||
return TLS_ERR_OK;
|
return TLS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
@ -444,18 +450,18 @@ ssize_t WinTLSSession::readData(void* data, size_t len)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(eof_) {
|
if (state_ == st_closing || state_ == st_closed || state_ == st_error) {
|
||||||
if(decBuf_.size()) {
|
auto nread = decBuf_.size();
|
||||||
A2_LOG_DEBUG("WinTLS: Sending out decrypted buffer after EOF");
|
if (nread) {
|
||||||
auto nread = decBuf_.size();
|
|
||||||
assert(nread < len);
|
assert(nread < len);
|
||||||
memcpy(data, decBuf_.data(), nread);
|
memcpy(data, decBuf_.data(), nread);
|
||||||
decBuf_.clear();
|
decBuf_.clear();
|
||||||
|
A2_LOG_DEBUG("WinTLS: Sending out decrypted buffer after EOF");
|
||||||
return nread;
|
return nread;
|
||||||
}
|
}
|
||||||
A2_LOG_DEBUG("WinTLS: EOF was already seen");
|
|
||||||
|
|
||||||
return 0;
|
A2_LOG_DEBUG("WinTLS: Read request aborted. Connection already closed");
|
||||||
|
return state_ == st_error ? TLS_ERR_ERROR : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state_ == st_handshake_write || state_ == st_handshake_write_last ||
|
if (state_ == st_handshake_write || state_ == st_handshake_write_last ||
|
||||||
|
@ -468,6 +474,7 @@ ssize_t WinTLSSession::readData(void* data, size_t len)
|
||||||
}
|
}
|
||||||
// Continue.
|
// Continue.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state_ != st_connected) {
|
if (state_ != st_connected) {
|
||||||
status_ = SEC_E_INVALID_HANDLE;
|
status_ = SEC_E_INVALID_HANDLE;
|
||||||
return TLS_ERR_ERROR;
|
return TLS_ERR_ERROR;
|
||||||
|
@ -484,16 +491,17 @@ ssize_t WinTLSSession::readData(void* data, size_t len)
|
||||||
if (read < 0 && errno == WSAEWOULDBLOCK) {
|
if (read < 0 && errno == WSAEWOULDBLOCK) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (read == 0) {
|
|
||||||
A2_LOG_DEBUG("WinTLS: EOF sensed");
|
|
||||||
eof_ = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (read < 0) {
|
if (read < 0) {
|
||||||
status_ = SEC_E_INCOMPLETE_MESSAGE;
|
status_ = SEC_E_INCOMPLETE_MESSAGE;
|
||||||
state_ = st_error;
|
state_ = st_error;
|
||||||
return TLS_ERR_ERROR;
|
return TLS_ERR_ERROR;
|
||||||
}
|
}
|
||||||
|
if (read == 0) {
|
||||||
|
A2_LOG_DEBUG("WinTLS: Connection abruptly closed!");
|
||||||
|
// At least try to gracefully close our write end.
|
||||||
|
closeConnection();
|
||||||
|
break;
|
||||||
|
}
|
||||||
readBuf_.advance(read);
|
readBuf_.advance(read);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,7 +559,7 @@ ssize_t WinTLSSession::readData(void* data, size_t len)
|
||||||
}
|
}
|
||||||
if (status_ == SEC_I_CONTEXT_EXPIRED) {
|
if (status_ == SEC_I_CONTEXT_EXPIRED) {
|
||||||
// Connection is gone now, but the buffered bytes are still valid.
|
// Connection is gone now, but the buffered bytes are still valid.
|
||||||
A2_LOG_DEBUG("WinTLS: Connection closed!");
|
A2_LOG_DEBUG("WinTLS: Connection gracefully closed!");
|
||||||
closeConnection();
|
closeConnection();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -559,8 +567,8 @@ ssize_t WinTLSSession::readData(void* data, size_t len)
|
||||||
|
|
||||||
len = std::min(decBuf_.size(), len);
|
len = std::min(decBuf_.size(), len);
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
if (eof_) {
|
if (state_ != st_connected) {
|
||||||
return 0;
|
return state_ == st_error ? TLS_ERR_ERROR : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TLS_ERR_WOULDBLOCK;
|
return TLS_ERR_WOULDBLOCK;
|
||||||
|
@ -689,6 +697,12 @@ restart:
|
||||||
state_ = st_error;
|
state_ = st_error;
|
||||||
return TLS_ERR_ERROR;
|
return TLS_ERR_ERROR;
|
||||||
}
|
}
|
||||||
|
if (read == 0) {
|
||||||
|
A2_LOG_DEBUG("WinTLS: Connection abruptly closed during handshake!");
|
||||||
|
status_ = SEC_E_INCOMPLETE_MESSAGE;
|
||||||
|
state_ = st_error;
|
||||||
|
return TLS_ERR_ERROR;
|
||||||
|
}
|
||||||
readBuf_.advance(read);
|
readBuf_.advance(read);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,9 +207,6 @@ private:
|
||||||
|
|
||||||
SECURITY_STATUS status_;
|
SECURITY_STATUS status_;
|
||||||
std::unique_ptr<SecPkgContext_StreamSizes> streamSizes_;
|
std::unique_ptr<SecPkgContext_StreamSizes> streamSizes_;
|
||||||
|
|
||||||
// true on EOF
|
|
||||||
bool eof_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
Loading…
Reference in New Issue