Changed secureSocket routines to return a status, and modify an argument for num of bytes handled #4697
This commit is contained in:
parent
86ad2bf080
commit
35e09c46b9
|
@ -474,22 +474,23 @@ TCPSocket::serviceConnected(ISocketMultiplexerJob* job,
|
|||
if (write) {
|
||||
try {
|
||||
// write data
|
||||
UInt32 n = m_outputBuffer.getSize();
|
||||
int buffSize = m_outputBuffer.getSize();
|
||||
int bytesWrote = 0;
|
||||
int status = 0;
|
||||
|
||||
if (s_retryOutputBufferSize > 0) {
|
||||
n = s_retryOutputBufferSize;
|
||||
buffSize = s_retryOutputBufferSize;
|
||||
}
|
||||
|
||||
const void* buffer = m_outputBuffer.peek(n);
|
||||
const void* buffer = m_outputBuffer.peek(buffSize);
|
||||
if (isSecure()) {
|
||||
if (isSecureReady()) {
|
||||
s_retryOutputBufferSize = n;
|
||||
n = secureWrite(buffer, n);
|
||||
|
||||
if (n > 0) {
|
||||
s_retryOutputBufferSize = buffSize;
|
||||
status = secureWrite(buffer, buffSize, bytesWrote);
|
||||
if (status > 0) {
|
||||
s_retryOutputBufferSize = 0;
|
||||
}
|
||||
else if (n < 0) {
|
||||
else if (status < 0) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -498,12 +499,12 @@ TCPSocket::serviceConnected(ISocketMultiplexerJob* job,
|
|||
}
|
||||
}
|
||||
else {
|
||||
n = (UInt32)ARCH->writeSocket(m_socket, buffer, n);
|
||||
bytesWrote = (UInt32)ARCH->writeSocket(m_socket, buffer, buffSize);
|
||||
}
|
||||
|
||||
// discard written data
|
||||
if (n > 0) {
|
||||
m_outputBuffer.pop(n);
|
||||
if (bytesWrote > 0) {
|
||||
m_outputBuffer.pop(bytesWrote);
|
||||
if (m_outputBuffer.getSize() == 0) {
|
||||
sendEvent(m_events->forIStream().outputFlushed());
|
||||
m_flushed = true;
|
||||
|
@ -543,12 +544,13 @@ TCPSocket::serviceConnected(ISocketMultiplexerJob* job,
|
|||
try {
|
||||
static UInt8 buffer[4096];
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
size_t n = 0;
|
||||
int bytesRead = 0;
|
||||
int status = 0;
|
||||
|
||||
if (isSecure()) {
|
||||
if (isSecureReady()) {
|
||||
n = secureRead(buffer, sizeof(buffer));
|
||||
if (n < 0) {
|
||||
status = secureRead(buffer, sizeof(buffer), bytesRead);
|
||||
if (status < 0) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -557,27 +559,27 @@ TCPSocket::serviceConnected(ISocketMultiplexerJob* job,
|
|||
}
|
||||
}
|
||||
else {
|
||||
n = ARCH->readSocket(m_socket, buffer, sizeof(buffer));
|
||||
bytesRead = (int) ARCH->readSocket(m_socket, buffer, sizeof(buffer));
|
||||
}
|
||||
|
||||
if (n > 0) {
|
||||
if (bytesRead > 0) {
|
||||
bool wasEmpty = (m_inputBuffer.getSize() == 0);
|
||||
|
||||
// slurp up as much as possible
|
||||
do {
|
||||
m_inputBuffer.write(buffer, (UInt32)n);
|
||||
m_inputBuffer.write(buffer, bytesRead);
|
||||
|
||||
if (isSecure() && isSecureReady()) {
|
||||
n = secureRead(buffer, sizeof(buffer));
|
||||
if (n < 0) {
|
||||
status = secureRead(buffer, sizeof(buffer), bytesRead);
|
||||
if (status < 0) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
n = ARCH->readSocket(m_socket, buffer, sizeof(buffer));
|
||||
bytesRead = (int) ARCH->readSocket(m_socket, buffer, sizeof(buffer));
|
||||
}
|
||||
|
||||
} while (n > 0);
|
||||
} while (bytesRead > 0 || status > 0);
|
||||
|
||||
// send input ready if input buffer was empty
|
||||
if (wasEmpty) {
|
||||
|
|
|
@ -67,8 +67,8 @@ protected:
|
|||
IEventQueue* getEvents() { return m_events; }
|
||||
virtual bool isSecureReady() { return false; }
|
||||
virtual bool isSecure() { return false; }
|
||||
virtual UInt32 secureRead(void* buffer, UInt32) { return 0; }
|
||||
virtual UInt32 secureWrite(const void*, UInt32) { return 0; }
|
||||
virtual int secureRead(void* buffer, int, int& ) { return 0; }
|
||||
virtual int secureWrite(const void*, int, int& ) { return 0; }
|
||||
|
||||
void setJob(ISocketMultiplexerJob*);
|
||||
ISocketMultiplexerJob*
|
||||
|
|
|
@ -111,18 +111,17 @@ SecureSocket::secureAccept()
|
|||
getSocket(), isReadable(), isWritable()));
|
||||
}
|
||||
|
||||
UInt32
|
||||
SecureSocket::secureRead(void* buffer, UInt32 n)
|
||||
int
|
||||
SecureSocket::secureRead(void* buffer, int size, int& read)
|
||||
{
|
||||
int r = 0;
|
||||
if (m_ssl->m_ssl != NULL) {
|
||||
LOG((CLOG_DEBUG2 "reading secure socket"));
|
||||
r = SSL_read(m_ssl->m_ssl, buffer, n);
|
||||
read = SSL_read(m_ssl->m_ssl, buffer, size);
|
||||
|
||||
static int retry;
|
||||
|
||||
// Check result will cleanup the connection in the case of a fatal
|
||||
checkResult(r, retry);
|
||||
checkResult(read, retry);
|
||||
|
||||
if (retry) {
|
||||
return 0;
|
||||
|
@ -132,25 +131,24 @@ SecureSocket::secureRead(void* buffer, UInt32 n)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
// According to SSL spec, r must not be negative and not have an error code
|
||||
// from SSL_get_error(). If this happens, it is itself an error. Let the
|
||||
// parent handle the case
|
||||
return (UInt32)r;
|
||||
// According to SSL spec, the number of bytes read must not be negative and
|
||||
// not have an error code from SSL_get_error(). If this happens, it is
|
||||
// itself an error. Let the parent handle the case
|
||||
return read;
|
||||
}
|
||||
|
||||
UInt32
|
||||
SecureSocket::secureWrite(const void* buffer, UInt32 n)
|
||||
int
|
||||
SecureSocket::secureWrite(const void* buffer, int size, int& wrote)
|
||||
{
|
||||
int r = 0;
|
||||
if (m_ssl->m_ssl != NULL) {
|
||||
LOG((CLOG_DEBUG2 "writing secure socket:%p", this));
|
||||
|
||||
r = SSL_write(m_ssl->m_ssl, buffer, n);
|
||||
wrote = SSL_write(m_ssl->m_ssl, buffer, size);
|
||||
|
||||
static int retry;
|
||||
|
||||
// Check result will cleanup the connection in the case of a fatal
|
||||
checkResult(r, retry);
|
||||
checkResult(wrote, retry);
|
||||
|
||||
if (retry) {
|
||||
return 0;
|
||||
|
@ -163,7 +161,7 @@ SecureSocket::secureWrite(const void* buffer, UInt32 n)
|
|||
// According to SSL spec, r must not be negative and not have an error code
|
||||
// from SSL_get_error(). If this happens, it is itself an error. Let the
|
||||
// parent handle the case
|
||||
return (UInt32)r;
|
||||
return wrote;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -378,12 +376,13 @@ SecureSocket::showCertificate()
|
|||
}
|
||||
|
||||
void
|
||||
SecureSocket::checkResult(int n, int& retry)
|
||||
SecureSocket::checkResult(int status, int& retry)
|
||||
{
|
||||
// ssl errors are a little quirky. the "want" errors are normal and
|
||||
// should result in a retry.
|
||||
|
||||
int errorCode = SSL_get_error(m_ssl->m_ssl, n);
|
||||
int errorCode = SSL_get_error(m_ssl->m_ssl, status);
|
||||
|
||||
switch (errorCode) {
|
||||
case SSL_ERROR_NONE:
|
||||
retry = 0;
|
||||
|
@ -416,10 +415,10 @@ SecureSocket::checkResult(int n, int& retry)
|
|||
case SSL_ERROR_SYSCALL:
|
||||
LOG((CLOG_ERR "some secure socket I/O error occurred"));
|
||||
if (ERR_peek_error() == 0) {
|
||||
if (n == 0) {
|
||||
if (status == 0) {
|
||||
LOG((CLOG_ERR "an EOF violates the protocol"));
|
||||
}
|
||||
else if (n == -1) {
|
||||
else if (status == -1) {
|
||||
// underlying socket I/O reproted an error
|
||||
try {
|
||||
ARCH->throwErrorOnSocket(getSocket());
|
||||
|
|
|
@ -48,8 +48,8 @@ public:
|
|||
void isFatal(bool b) { m_fatal = b; }
|
||||
bool isSecureReady();
|
||||
bool isSecure() { return true; }
|
||||
UInt32 secureRead(void* buffer, UInt32 n);
|
||||
UInt32 secureWrite(const void* buffer, UInt32 n);
|
||||
int secureRead(void* buffer, int size, int& read);
|
||||
int secureWrite(const void* buffer, int size, int& wrote);
|
||||
void initSsl(bool server);
|
||||
bool loadCertificates(String& CertFile);
|
||||
void maxRetry(int limit) { m_maxRetry = limit; };
|
||||
|
|
Loading…
Reference in New Issue