Refactored secure read and write into SecureSocket

This commit is contained in:
Jerry (Xinyu Hou)
2016-08-24 17:52:02 +01:00
committed by Andrew Nelless
parent 61b489ab3d
commit 08a73218e6
4 changed files with 203 additions and 155 deletions

View File

@@ -140,6 +140,115 @@ SecureSocket::secureAccept()
getSocket(), isReadable(), isWritable()));
}
TCPSocket::EJobResult
SecureSocket::doRead()
{
static UInt8 buffer[4096];
memset(buffer, 0, sizeof(buffer));
int bytesRead = 0;
int status = 0;
if (isSecureReady()) {
status = secureRead(buffer, sizeof(buffer), bytesRead);
if (status < 0) {
return kBreak;
}
else if (status == 0) {
return kNew;
}
}
else {
return kRetry;
}
if (bytesRead > 0) {
bool wasEmpty = (m_inputBuffer.getSize() == 0);
// slurp up as much as possible
do {
m_inputBuffer.write(buffer, bytesRead);
status = secureRead(buffer, sizeof(buffer), bytesRead);
if (status < 0) {
return kBreak;
}
} while (bytesRead > 0 || status > 0);
// send input ready if input buffer was empty
if (wasEmpty) {
sendEvent(m_events->forIStream().inputReady());
}
}
else {
// remote write end of stream hungup. our input side
// has therefore shutdown but don't flush our buffer
// since there's still data to be read.
sendEvent(m_events->forIStream().inputShutdown());
if (!m_writable && m_inputBuffer.getSize() == 0) {
sendEvent(m_events->forISocket().disconnected());
m_connected = false;
}
m_readable = false;
return kNew;
}
return kRetry;
}
TCPSocket::EJobResult
SecureSocket::doWrite()
{
static bool s_retry = false;
static int s_retrySize = 0;
static void* s_staticBuffer = NULL;
// write data
int bufferSize = 0;
int bytesWrote = 0;
int status = 0;
if (s_retry) {
bufferSize = s_retrySize;
}
else {
bufferSize = m_outputBuffer.getSize();
s_staticBuffer = malloc(bufferSize);
memcpy(s_staticBuffer, m_outputBuffer.peek(bufferSize), bufferSize);
}
if (bufferSize == 0) {
return kRetry;
}
if (isSecureReady()) {
status = secureWrite(s_staticBuffer, bufferSize, bytesWrote);
if (status > 0) {
s_retry = false;
bufferSize = 0;
free(s_staticBuffer);
s_staticBuffer = NULL;
}
else if (status < 0) {
return kBreak;
}
else if (status == 0) {
s_retry = true;
s_retrySize = bufferSize;
return kNew;
}
}
else {
return kRetry;
}
if (bytesWrote > 0) {
discardWrittenData(bytesWrote);
return kNew;
}
return kRetry;
}
int
SecureSocket::secureRead(void* buffer, int size, int& read)
{

View File

@@ -48,6 +48,8 @@ public:
newJob();
void secureConnect();
void secureAccept();
EJobResult doRead();
EJobResult doWrite();
bool isReady() const { return m_secureReady; }
bool isFatal() const { return m_fatal; }
void isFatal(bool b) { m_fatal = b; }