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