sslRingBufferThreads.cpp [plain text]
#include "sslRingBufferThreads.h"
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include <strings.h>
#include <clAppUtils/sslAppUtils.h>
#include <utilLib/common.h>
#define LOG_TOP_IO 0
#if LOG_TOP_IO
static void logWrite(
char *who,
size_t written)
{
pthread_mutex_lock(&printfMutex);
printf("+++ %s wrote %4lu bytes\n", who, (unsigned long)written);
pthread_mutex_unlock(&printfMutex);
}
static void logRead(
char *who,
size_t bytesRead)
{
pthread_mutex_lock(&printfMutex);
printf("+++ %s read %4lu bytes\n", who, (unsigned long)bytesRead);
pthread_mutex_unlock(&printfMutex);
}
#else
#define logWrite(who, w)
#define logRead(who, r)
#endif
void *sslRbClientThread(void *arg)
{
SslRingBufferArgs *sslArgs = (SslRingBufferArgs *)arg;
OSStatus ortn;
SSLContextRef ctx = NULL;
RingBuffers ringBufs = {sslArgs->ringRead, sslArgs->ringWrite};
unsigned toMove = 0;
unsigned thisMove;
ortn = SSLNewContext(false, &ctx);
if(ortn) {
printSslErrStr("SSLNewContext", ortn);
goto cleanup;
}
ortn = SSLSetIOFuncs(ctx, ringReadFunc, ringWriteFunc);
if(ortn) {
printSslErrStr("SSLSetIOFuncs", ortn);
goto cleanup;
}
ortn = SSLSetConnection(ctx, (SSLConnectionRef)&ringBufs);
if(ortn) {
printSslErrStr("SSLSetConnection", ortn);
goto cleanup;
}
ortn = SSLSetEnabledCiphers(ctx, &sslArgs->cipherSuite, 1);
if(ortn) {
printSslErrStr("SSLSetEnabledCiphers", ortn);
goto cleanup;
}
if(sslArgs->idArray) {
ortn = SSLSetCertificate(ctx, sslArgs->idArray);
if(ortn) {
printSslErrStr("SSLSetCertificate", ortn);
goto cleanup;
}
}
if(sslArgs->trustedRoots) {
ortn = SSLSetTrustedRoots(ctx, sslArgs->trustedRoots, true);
if(ortn) {
printSslErrStr("SSLSetTrustedRoots", ortn);
goto cleanup;
}
}
SSLSetProtocolVersionEnabled(ctx, kSSLProtocolAll, false);
ortn = SSLSetProtocolVersionEnabled(ctx, sslArgs->prot, true);
if(ortn) {
printSslErrStr("SSLSetProtocolVersionEnabled", ortn);
goto cleanup;
}
sslArgs->iAmReady = true;
while(!(*sslArgs->goFlag)) {
if(*sslArgs->abortFlag) {
goto cleanup;
}
}
sslArgs->startHandshake = CFAbsoluteTimeGetCurrent();
do {
ortn = SSLHandshake(ctx);
if(*sslArgs->abortFlag) {
goto cleanup;
}
} while (ortn == errSSLWouldBlock);
if(ortn) {
printSslErrStr("SSLHandshake", ortn);
goto cleanup;
}
SSLGetNegotiatedCipher(ctx, &sslArgs->negotiatedCipher);
SSLGetNegotiatedProtocolVersion(ctx, &sslArgs->negotiatedProt);
sslArgs->startData = CFAbsoluteTimeGetCurrent();
toMove = sslArgs->xferSize;
if(toMove == 0) {
sslArgs->endData = sslArgs->startData;
goto cleanup;
}
do {
thisMove = sslArgs->chunkSize;
if(thisMove > toMove) {
thisMove = toMove;
}
size_t moved;
ortn = SSLWrite(ctx, sslArgs->xferBuf, thisMove, &moved);
if(ortn) {
printSslErrStr("SSLWrite", ortn);
goto cleanup;
}
logWrite("client", moved);
if(!sslArgs->runForever) {
toMove -= moved;
}
if(*sslArgs->abortFlag) {
goto cleanup;
}
} while(toMove || sslArgs->runForever);
sslArgs->endData = CFAbsoluteTimeGetCurrent();
cleanup:
if(ortn) {
*sslArgs->abortFlag = true;
}
if(*sslArgs->abortFlag && sslArgs->pauseOnError) {
testError(CSSM_FALSE);
}
if(ctx) {
SSLClose(ctx);
SSLDisposeContext(ctx);
}
if(ortn) {
printf("***Client thread returning %lu\n", (unsigned long)ortn);
}
pthread_exit((void*)ortn);
return (void *)ortn;
}
OSStatus sslRbServerThread(SslRingBufferArgs *sslArgs)
{
OSStatus ortn;
SSLContextRef ctx = NULL;
RingBuffers ringBufs = {sslArgs->ringRead, sslArgs->ringWrite};
unsigned toMove = 0;
unsigned thisMove;
ortn = SSLNewContext(true, &ctx);
if(ortn) {
printSslErrStr("SSLNewContext", ortn);
goto cleanup;
}
ortn = SSLSetIOFuncs(ctx, ringReadFunc, ringWriteFunc);
if(ortn) {
printSslErrStr("SSLSetIOFuncs", ortn);
goto cleanup;
}
ortn = SSLSetConnection(ctx, (SSLConnectionRef)&ringBufs);
if(ortn) {
printSslErrStr("SSLSetConnection", ortn);
goto cleanup;
}
ortn = SSLSetEnabledCiphers(ctx, &sslArgs->cipherSuite, 1);
if(ortn) {
printSslErrStr("SSLSetEnabledCiphers", ortn);
goto cleanup;
}
if(sslArgs->idArray) {
ortn = SSLSetCertificate(ctx, sslArgs->idArray);
if(ortn) {
printSslErrStr("SSLSetCertificate", ortn);
goto cleanup;
}
}
if(sslArgs->trustedRoots) {
ortn = SSLSetTrustedRoots(ctx, sslArgs->trustedRoots, true);
if(ortn) {
printSslErrStr("SSLSetTrustedRoots", ortn);
goto cleanup;
}
}
SSLSetProtocolVersionEnabled(ctx, kSSLProtocolAll, false);
ortn = SSLSetProtocolVersionEnabled(ctx, sslArgs->prot, true);
if(ortn) {
printSslErrStr("SSLSetProtocolVersionEnabled", ortn);
goto cleanup;
}
sslArgs->iAmReady = true;
while(!(*sslArgs->goFlag)) {
if(*sslArgs->abortFlag) {
goto cleanup;
}
}
sslArgs->startHandshake = CFAbsoluteTimeGetCurrent();
do {
ortn = SSLHandshake(ctx);
if(*sslArgs->abortFlag) {
goto cleanup;
}
} while (ortn == errSSLWouldBlock);
if(ortn) {
printSslErrStr("SSLHandshake", ortn);
goto cleanup;
}
SSLGetNegotiatedCipher(ctx, &sslArgs->negotiatedCipher);
SSLGetNegotiatedProtocolVersion(ctx, &sslArgs->negotiatedProt);
sslArgs->startData = CFAbsoluteTimeGetCurrent();
toMove = sslArgs->xferSize;
if(toMove == 0) {
sslArgs->endData = sslArgs->startData;
goto cleanup;
}
do {
thisMove = sslArgs->xferSize;
if(thisMove > toMove) {
thisMove = toMove;
}
size_t moved;
ortn = SSLRead(ctx, sslArgs->xferBuf, thisMove, &moved);
switch(ortn) {
case noErr:
break;
case errSSLWouldBlock:
ortn = noErr;
break;
default:
break;
}
if(ortn) {
printSslErrStr("SSLRead", ortn);
goto cleanup;
}
logRead("server", moved);
if(!sslArgs->runForever) {
toMove -= moved;
}
if(*sslArgs->abortFlag) {
goto cleanup;
}
} while(toMove || sslArgs->runForever);
sslArgs->endData = CFAbsoluteTimeGetCurrent();
cleanup:
if(ortn) {
*sslArgs->abortFlag = true;
}
if(*sslArgs->abortFlag && sslArgs->pauseOnError) {
testError(CSSM_FALSE);
}
if(ctx) {
SSLClose(ctx);
SSLDisposeContext(ctx);
}
if(ortn) {
printf("***Server thread returning %lu\n", (unsigned long)ortn);
}
return ortn;
}