@@ -2,7 +2,7 @@ EXECUTABLE = server | |||||
EXECUTABLECLI = client | EXECUTABLECLI = client | ||||
CC=g++ -lboost_system -lboost_thread | CC=g++ -lboost_system -lboost_thread | ||||
CFLAGS=-Wall -DDEBUG -Wreorder | |||||
CFLAGS=-Wall -DDEBUG -Wreorder -D_RENEG_ON_ | |||||
COMPILE=$(CC) $(CFLAGS) | COMPILE=$(CC) $(CFLAGS) | ||||
all: server client | all: server client | ||||
@@ -33,6 +33,28 @@ int CharsRead = 0; | |||||
// with this you can block sender thread during renegotiation | // with this you can block sender thread during renegotiation | ||||
mutex WriteReadMutex; | mutex WriteReadMutex; | ||||
bool handle_error_code(int& len, SSL* SSLHandler, int code, const char* func) | |||||
{ | |||||
switch( SSL_get_error( SSLHandler, code ) ) | |||||
{ | |||||
case SSL_ERROR_NONE: | |||||
len+=code; | |||||
return false; | |||||
case SSL_ERROR_ZERO_RETURN: | |||||
cout << "CONNETION CLOSE ON WRITE" << endl; | |||||
break; | |||||
case SSL_ERROR_WANT_READ: | |||||
cout << func << " WANT READ" << endl; | |||||
break; | |||||
case SSL_ERROR_WANT_WRITE: | |||||
cout << func << " WANT WRITE" << endl; | |||||
break; | |||||
} | |||||
return true; | |||||
} | |||||
void Sender() | void Sender() | ||||
{ | { | ||||
while(1) | while(1) | ||||
@@ -42,7 +64,14 @@ void Sender() | |||||
do | do | ||||
{ | { | ||||
lock_guard<mutex> lock(WriteReadMutex); | lock_guard<mutex> lock(WriteReadMutex); | ||||
len+=SSL_write(SSLHandler, buf.c_str()+len, buf.size()-len); | |||||
bool flag = true; | |||||
while( flag ) | |||||
{ | |||||
int code = SSL_write(SSLHandler, buf.c_str()+len, buf.size()-len); | |||||
flag = handle_error_code(len, SSLHandler, code, "SSL_write"); | |||||
} | |||||
// for debugging re-neg | // for debugging re-neg | ||||
cout << "SSL STATE: " << SSL_state_string(SSLHandler) << endl; | cout << "SSL STATE: " << SSL_state_string(SSLHandler) << endl; | ||||
} while( len != static_cast<int>(buf.size()) ); | } while( len != static_cast<int>(buf.size()) ); | ||||
@@ -59,7 +88,12 @@ void Client::receive() | |||||
int len_rcv = 0; | int len_rcv = 0; | ||||
{ | { | ||||
lock_guard<mutex> lock(WriteReadMutex); | lock_guard<mutex> lock(WriteReadMutex); | ||||
len_rcv = SSL_read(SSLHandler, buf, MAX_PACKET_SIZE); | |||||
bool flag = true; | |||||
while( flag ) | |||||
{ | |||||
len_rcv = SSL_read(SSLHandler, buf, MAX_PACKET_SIZE); | |||||
flag = handle_error_code(len_rcv, SSLHandler, len_rcv, "SSL_read"); | |||||
} | |||||
} | } | ||||
if( len_rcv != 0 ) | if( len_rcv != 0 ) | ||||
@@ -99,11 +133,12 @@ void Client::connect() | |||||
SSLHandler = SSL_new(_ctx); | SSLHandler = SSL_new(_ctx); | ||||
long mode = SSL_CTX_set_mode(_ctx, SSL_MODE_AUTO_RETRY); | |||||
if( ( mode & SSL_MODE_AUTO_RETRY) != SSL_MODE_AUTO_RETRY ) | |||||
{ | |||||
throw runtime_error("SSL_MODE_AUTO_RETRY couldn't be set"); | |||||
} | |||||
// if socket is blocking you can set this and forget about looking at SSL_get_error code on I/O calls | |||||
// long mode = SSL_CTX_set_mode(_ctx, SSL_MODE_AUTO_RETRY); | |||||
// if( ( mode & SSL_MODE_AUTO_RETRY) != SSL_MODE_AUTO_RETRY ) | |||||
// { | |||||
// throw runtime_error("SSL_MODE_AUTO_RETRY couldn't be set"); | |||||
// } | |||||
SSL_set_fd(SSLHandler, _handler); | SSL_set_fd(SSLHandler, _handler); | ||||
@@ -140,11 +175,13 @@ void Client::start() | |||||
if( FD_ISSET(_handler, &fd_read ) ) | if( FD_ISSET(_handler, &fd_read ) ) | ||||
{ | { | ||||
// this should be in other thread but... it works | // this should be in other thread but... it works | ||||
#ifdef _RENEG_ON_ | |||||
if( CharsRead > RENEG_INIT_LEN ) | if( CharsRead > RENEG_INIT_LEN ) | ||||
{ | { | ||||
CharsRead = 0; | CharsRead = 0; | ||||
renegotiate(); | renegotiate(); | ||||
} | } | ||||
#endif | |||||
receive(); | receive(); | ||||
} | } | ||||
} | } | ||||
@@ -3,7 +3,7 @@ | |||||
#define IP "127.0.0.1" | #define IP "127.0.0.1" | ||||
#define EXCHANGE_STRING "ABCDEFGHIJKLMNOPRSTUWXYZ" | #define EXCHANGE_STRING "ABCDEFGHIJKLMNOPRSTUWXYZ" | ||||
#define EXCHANGE_STRING_LEN sizeof(EXCHANGE_STRING)/sizeof(EXCHANGE_STRING[0]) | #define EXCHANGE_STRING_LEN sizeof(EXCHANGE_STRING)/sizeof(EXCHANGE_STRING[0]) | ||||
#define RENEG_INIT_LEN 200 | |||||
#define RENEG_INIT_LEN 4200 | |||||
#define CERTIFICATE_FILE "etc/cert" | #define CERTIFICATE_FILE "etc/cert" | ||||
#define PRIVATE_KEY_FILE "etc/pkey" | #define PRIVATE_KEY_FILE "etc/pkey" | ||||
#define SEND_ITERATIONS 100000 | #define SEND_ITERATIONS 100000 |
@@ -227,28 +227,41 @@ void Receive() | |||||
{ | { | ||||
lock_guard<mutex> lock(WriteReadMutex); | lock_guard<mutex> lock(WriteReadMutex); | ||||
len_rcv = SSL_read(handler.second, buf, 1024); | len_rcv = SSL_read(handler.second, buf, 1024); | ||||
} | |||||
if( len_rcv ) | |||||
{ | |||||
// dirty thing - if it has \n on the end - remove it | |||||
if( buf[len_rcv-1] == '\n' ) | |||||
buf[len_rcv-1] = '\0'; | |||||
cout << buf << endl; | |||||
// add it back to the socket so that select can use it | |||||
lock_guard<mutex> guard(SocketSetMutex); | |||||
SocketSet.insert(handler); | |||||
switch( SSL_get_error(handler.second, len_rcv) ) | |||||
{ | |||||
case SSL_ERROR_NONE: | |||||
{ | |||||
// dirty thing - if it has \n on the end - remove it | |||||
if( buf[len_rcv-1] == '\n' ) | |||||
buf[len_rcv-1] = '\0'; | |||||
cout << buf << endl; | |||||
{ | |||||
// add it back to the socket so that select can use it | |||||
lock_guard<mutex> guard(SocketSetMutex); | |||||
SocketSet.insert(handler); | |||||
// push handler ID and notify sender thread | |||||
WriteHandler = handler; | |||||
WaitForWrite.notify_one(); | |||||
} | |||||
break; | |||||
} | |||||
case SSL_ERROR_WANT_READ: | |||||
case SSL_ERROR_WANT_WRITE: | |||||
{ | |||||
cout << "WANT_SOMETHING WHEN Receive" << endl; | |||||
exit(1); | |||||
break; | |||||
} | |||||
default : | |||||
{ | |||||
cout << "Closing connection " << handler.first << endl; | |||||
::close(handler.first); | |||||
exit(1); | |||||
} | |||||
// push handler ID and notify sender thread | |||||
WriteHandler = handler; | |||||
WaitForWrite.notify_one(); | |||||
} | |||||
else | |||||
{ | |||||
cout << "Closing connection " << handler.first << endl; | |||||
::close(handler.first); | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -273,7 +286,28 @@ void Send() | |||||
do | do | ||||
{ | { | ||||
lock_guard<mutex> lock(WriteReadMutex); | lock_guard<mutex> lock(WriteReadMutex); | ||||
len+=SSL_write(handler.second, buf.c_str()+len, buf.size()-len); | |||||
int write_len=SSL_write(handler.second, buf.c_str()+len, buf.size()-len); | |||||
switch( SSL_get_error(handler.second, write_len) ) | |||||
{ | |||||
case SSL_ERROR_NONE: | |||||
{ | |||||
len += write_len; | |||||
break; | |||||
} | |||||
case SSL_ERROR_WANT_READ: | |||||
case SSL_ERROR_WANT_WRITE: | |||||
{ | |||||
cout << "WANT_SOMETHING WHEN Send" << endl; | |||||
exit(1); | |||||
break; | |||||
} | |||||
default : | |||||
{ | |||||
cout << "Closing connection " << handler.first << endl; | |||||
::close(handler.first); | |||||
exit(1); | |||||
} | |||||
} | |||||
// for debugging re-neg | // for debugging re-neg | ||||
// cout << "SSL STATE: " << SSL_state_string(handler.second) << endl; | // cout << "SSL STATE: " << SSL_state_string(handler.second) << endl; | ||||
} while( len != static_cast<int>(buf.size()) ); | } while( len != static_cast<int>(buf.size()) ); | ||||