Skip to content

Commit

Permalink
Added time out for SSL
Browse files Browse the repository at this point in the history
1) SSL_read() block for more than 10 sec, waiting for peer to close.
I setsockopt() the socket to have timeout 3, this make things much
more smooth.

2) Adjusted some debug information
  • Loading branch information
lava committed Jan 27, 2012
1 parent 302de56 commit fc03cb9
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 58 deletions.
86 changes: 55 additions & 31 deletions Cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ static string reply404 = "HTTP/1.1 404 Not Found\r\nServer: twproxy\r\nConnectio

extern int serverPorts[];

MySocket *Cache::getReplySocket(string host, bool isSSL)
MySocket *Cache::getReplySocket(string host, bool isSSL, int serverPort)
{
assert(host.find(':') != string::npos);
assert(host.find(':') < (host.length()-1));
Expand All @@ -81,7 +81,7 @@ MySocket *Cache::getReplySocket(string host, bool isSSL)
//cout << "making connection to " << hostStr << ":" << port << endl;
replySock = new MySocket(hostStr.c_str(), port);
if(isSSL) {
replySock->enableSSLClient();
replySock->enableSSLClient(serverPort);
}
} catch(char *e) {
cout << e << endl;
Expand Down Expand Up @@ -111,9 +111,9 @@ static void dbg_print_vector(CacheEntry *ent, string url, int browserId, string
}


int Cache::votingFetchInsertWriteback(string url, string request, int browserId, MySocket *browserSock, string host, bool isSSL, MySocket *replySock)
{
int Cache::votingFetchInsertWriteback(string url, string request, int browserId, MySocket *browserSock, string host, bool isSSL, MySocket *replySock) {
assert(browserId >= 0);
int ret_val = 0;
//find() will take care of all checks, including same url, same method, different
//cookie for the same browser or different browser
CacheEntry *ent = find(url, request);
Expand All @@ -125,14 +125,14 @@ int Cache::votingFetchInsertWriteback(string url, string request, int browserId,
int ret = ent->updateReqVec(browserId);
assert(ret == 1);

dbg_print_vector(ent, url, browserId, "new request");
dbg_print_vector(ent, url, browserId, "NULL => CACHE_NEW");

addToStore(url, ent);
while(ent->getReqState() != CACHE_IN) {
pthread_cond_wait(&cache_cond, &cache_mutex);
cache_cond_wait();
}

dbg_print_vector(ent, url, browserId, "woken up");
dbg_print_vector(ent, url, browserId, "CACHE_NEW woken up when CACHE_IN");

sendBrowser(browserSock, ent, browserId);
}
Expand All @@ -141,21 +141,21 @@ int Cache::votingFetchInsertWriteback(string url, string request, int browserId,
int ret = ent->updateReqVec(browserId);
//opera is really making two same requests to http://google.com, no difference
// assert(ret == 1);
dbg_print_vector(ent, url, browserId, "cache in hit");
dbg_print_vector(ent, url, browserId, "CACHE_IN");

sendBrowser(browserSock, ent, browserId);
}
else if(ent->getReqState() == CACHE_FETCHING) {
//somebody is fetching the request, wait till done
int ret = ent->updateReqVec(browserId);
// assert(ret == 1);
dbg_print_vector(ent, url, browserId, "network fetching");
dbg_print_vector(ent, url, browserId, "CACHE_FETCHING");

while(ent->getReqState() != CACHE_IN) {
pthread_cond_wait(&cache_cond, &cache_mutex);
cache_cond_wait();
}

dbg_print_vector(ent, url, browserId, "fetched");
dbg_print_vector(ent, url, browserId, "CACHE_FETCHING woken up when CACHE_IN");

sendBrowser(browserSock, ent, browserId);
}
Expand All @@ -165,49 +165,75 @@ int Cache::votingFetchInsertWriteback(string url, string request, int browserId,
int ret = ent->updateReqVec(browserId);
// assert(ret == 1);

dbg_print_vector(ent, url, browserId, "voted, go fetching");
dbg_print_vector(ent, url, browserId, "CACHE_NEW => CACHE_FETCHING");

ent->setReqState(CACHE_FETCHING);
pthread_mutex_unlock(&cache_mutex);
fetch(ent, host, isSSL, browserId, replySock);
pthread_mutex_lock(&cache_mutex);
cache_unlock();
ret_val = fetch(ent, host, isSSL, browserId, replySock);
cache_lock();

dbg_print_vector(ent, url, browserId, "CACHE_FETCHING => CACHE_IN");

ent->setReqState(CACHE_IN);
sendBrowser(browserSock, ent, browserId);
}
else
assert(false);
return 0;
return ret_val;
}

int Cache::sendBrowser(MySocket *browserSock, CacheEntry *ent, int browserId) {
cache_dbg("sendBrowser send to browser %d, response length %d\n", browserId, ent->getResponse().length());
bool ret = browserSock->write_bytes(ent->getResponse().c_str(), ent->getResponse().length());

assert(ret);
ent->updateRespVec(browserId);
return 0;
}

void Cache::getHTTPResponseVote(string host, string request, string url, int serverPort,
MySocket *browserSock, bool isSSL, MySocket *replySock)
{
MySocket *browserSock, bool isSSL, MySocket *replySock) {
if(replySock == NULL) {
cout << "get...Vote(): replySock is NULL, give browser 404" << endl;
browserSock->write_bytes(reply404);
return;
}
int browserId = -1;
pthread_mutex_lock(&cache_mutex);
cache_lock();
browserId = serverPort - serverPorts[0];

votingFetchInsertWriteback(url, request, browserId, browserSock, host, isSSL, replySock);

pthread_mutex_unlock(&cache_mutex);
cache_unlock();

cache_cond_broadcast();
}

void Cache::cache_lock() {
cache_dbg("cache_lock\n");
pthread_mutex_lock(&cache_mutex);
}
void Cache::cache_unlock() {
cache_dbg("cache_unlock\n");
pthread_mutex_unlock(&cache_mutex);
}
void Cache::cache_cond_wait() {
cache_dbg("before cache_wait\n");
pthread_cond_wait(&cache_cond, &cache_mutex);
cache_dbg("after cache_wait\n");
}
void Cache::cache_cond_broadcast() {
cache_dbg("cache_cond_broadcastt\n");
pthread_cond_broadcast(&cache_cond);
}


static void dbg_fetch(int ret) {
switch(ret) {
case ENOT_CONNECTED:
cache_dbg("ESOCKET_CONNECTED returned by replySock->read()\n");
break;
case ECONN_CLOSED:
//cache_dbg("ESOCKET_CLOSED returned by replySock->read()\n");
cache_dbg("ESOCKET_CLOSED returned by replySock->read()\n");
break;
case ESOCKET_ERROR:
cache_dbg("ESOCKET_ERROR returned by replySock->read()\n");
Expand All @@ -220,25 +246,22 @@ static void dbg_fetch(int ret) {


int Cache::fetch(CacheEntry *ent, string host, bool isSSL, int browserId, MySocket *replySock) {
if(replySock == NULL) {
cout << "returning 404" << endl;
ent->appendResponse(reply404);
return -1;
}
if(!replySock->write_bytes(ent->getRequest())) {
cout << "returning 404" << endl;
cerr << "fetch() fail to send request, give browser 404" << endl;
ent->appendResponse(reply404);
delete replySock;
return -1;
}
printf("FETCH CALLED %s, response length: %d\n", ent->getUrl().c_str(), ent->getResponse().length());
printf("%d FETCH CALLED %s, response length: %d\n", browserId, ent->getUrl().c_str(), ent->getResponse().length());
unsigned char buf[1024];
int num_bytes;
while((num_bytes = replySock->read(buf, sizeof(buf))) > 0) {
cerr << "read " << num_bytes << " from " << browserId << ent->getUrl().c_str() << endl;
ent->appendResponse((const char *)buf, num_bytes);
}
dbg_fetch(num_bytes);

printf("FETCHED %s, response length: %d\n", ent->getUrl().c_str(), ent->getResponse().length());
printf("%d FETCHED %s, response length: %d\n", browserId, ent->getUrl().c_str(), ent->getResponse().length());
delete replySock;
return 0;
}
Expand All @@ -247,6 +270,7 @@ void Cache::handleResponse(MySocket *browserSock, MySocket *replySock, string re
{
if(!replySock->write_bytes(request)) {
// XXX FIXME we should do something other than 404 here
cerr << "handleResponse() fail to send request, give browser 404" << endl;
browserSock->write_bytes(reply404);
return;
}
Expand All @@ -265,7 +289,7 @@ void Cache::getHTTPResponseNoVote(string host, string request, string url, int s
MySocket *browserSock, bool isSSL, MySocket *replySock)
{
if(replySock == NULL) {
cout << "returning 404" << endl;
cout << "get...NoVote(): replySock is NULL, give browser 404" << endl;
browserSock->write_bytes(reply404);
return;
}
Expand Down
8 changes: 6 additions & 2 deletions Cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Cache {
int serverPort, MySocket *browserSock, bool isSSL, MySocket *replySock);
void getHTTPResponseVote(std::string host, std::string request, std::string url,
int serverPort, MySocket *browserSock, bool isSSL, MySocket *replySock);
MySocket *getReplySocket(std::string host, bool isSSL);
MySocket *getReplySocket(std::string host, bool isSSL, int serverPort);
static void setNumBrowsers(const int num);
protected:
void handleResponse(MySocket *browserSock, MySocket *replySock, std::string request);
Expand All @@ -36,7 +36,11 @@ class Cache {
int sendBrowser(MySocket *browserSock, CacheEntry *ent, int browserId);

int fetch(CacheEntry *ent, std::string host, bool isSSL, int browserId, MySocket *replySock);


void cache_lock();
void cache_unlock();
void cache_cond_wait();
void cache_cond_broadcast();

std::map<std::string, CacheEntry*> m_store;

Expand Down
24 changes: 17 additions & 7 deletions MySocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@
using namespace std;

//#define CHK_SSL(err) if ((err) <= 0) {printf("CHK_SSL failed\n"); ERR_print_errors_fp(stderr); exit(2); }
#define ASSERT_SSL(err, msg, socket) if ((err) <= 0) { \
printf("ASSERT_SSL err: %d %s\n", err, msg); \
#define ASSERT_SSL(err, msg, socket, port) if ((err) <= 0) { \
printf("%d ASSERT_SSL err: %d %s\n", port, err, msg); \
socket->printSSLError(err); \
ERR_print_errors_fp(stderr);}

Expand Down Expand Up @@ -295,7 +295,7 @@ void MySocket::close(void)
ctx = NULL;
}

void MySocket::enableSSLServer(MySocket *clientSock, string host)
void MySocket::enableSSLServer(MySocket *clientSock, string host, int serverPort)
{
if(sockFd < 0) return;

Expand Down Expand Up @@ -330,7 +330,7 @@ void MySocket::enableSSLServer(MySocket *clientSock, string host)
int err = 1, ret = SSL_ERROR_NONE;
do {
err = SSL_accept (ssl);
ASSERT_SSL(err, "SSL_accept in enableSSLServer()\n", this);
ASSERT_SSL(err, "SSL_accept in enableSSLServer()\n", this, serverPort);
ret = SSL_get_error(ssl, err);
} while(ret == SSL_ERROR_WANT_READ || ret == SSL_ERROR_WANT_WRITE);

Expand All @@ -340,7 +340,7 @@ void MySocket::enableSSLServer(MySocket *clientSock, string host)
isSSLBrowserSock = 1;
}

void MySocket::enableSSLClient(void)
void MySocket::enableSSLClient(int serverPort)
{
if(sockFd < 0) return;

Expand All @@ -353,8 +353,18 @@ void MySocket::enableSSLClient(void)
ssl = SSL_new (ctx); CHK_NULL(ssl);
SSL_set_fd (ssl, sockFd);
int err = SSL_connect (ssl);
ASSERT_SSL(err, "SSL_connect in enableClient()\n", this);
ASSERT_SSL(err, "SSL_connect in enableClient()\n", this, serverPort);
//CHK_SSL(err);

struct timeval tv;
tv.tv_usec = 0;
tv.tv_sec = 3;
int ret = setsockopt(sockFd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
if(ret) {
perror("setsockopt fail");
assert(false);
}


mitm_dbg("SSL connection using %s\n", SSL_get_cipher (ssl));
/*
Expand Down Expand Up @@ -520,7 +530,7 @@ void MySocket::__enableSSLServer(void)
ssl = SSL_new (ctx); CHK_NULL(ssl);
SSL_set_fd (ssl, sockFd);
int err = SSL_accept (ssl);
ASSERT_SSL(err, "SSL_accept", this);
//ASSERT_SSL(err, "SSL_accept", this);
//CHK_SSL(err);

printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
Expand Down
4 changes: 2 additions & 2 deletions MySocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ class MySocket {
bool write_bytes(std::string buffer);
bool write_bytes(const void *buffer, int len);
void __enableSSLServer(void);
void enableSSLServer(MySocket *, string);
void enableSSLClient(void);
void enableSSLServer(MySocket *, string, int);
void enableSSLClient(int);

/*
* a helper function so select can be used
Expand Down
9 changes: 9 additions & 0 deletions UI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,15 @@ string UIMgr::decodeUrl(string url) {
return ret;
}

void UIMgr::processUI(MySocket *sock, string url, int serverPort, bool isSSL, int type) {
assert(type != 0);
if(type > 0)
processUILog(sock, url, serverPort, isSSL);
else
processUIGet(sock, serverPort, isSSL);
}


void UIMgr::processUILog(MySocket *sock, string url, int serverPort, bool isSSL) {
if(!isSSL) {
processUILog_http(sock, url, serverPort);
Expand Down
6 changes: 4 additions & 2 deletions UI.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ class UIMgr {
UIMgr();
~UIMgr();
int isUIRequest(string url);
void processUILog(MySocket *sock, string url, int serverPort, bool isSSL);
void processUIGet(MySocket *sock, int serverPort, bool isSSL);
void processUI(MySocket *sock, string url, int serverPort, bool isSSL, int type);
protected:
deque<UIQueueEntry *> ui_queue;
pthread_mutex_t ui_mutex;
Expand All @@ -26,6 +25,9 @@ class UIMgr {
void putLock(string msg = "");
string decodeUrl(string url);

void processUILog(MySocket *sock, string url, int serverPort, bool isSSL);
void processUIGet(MySocket *sock, int serverPort, bool isSSL);

void processUILog_http(MySocket *sock, string url, int serverPort);
void processUILog_https(MySocket *sock, string url, int serverPort);
void processUIGet_http(MySocket *sock, int serverPort);
Expand Down
2 changes: 1 addition & 1 deletion dbg.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

#define ui_dbg(...);

//#define cache_dbg(...) do{printf(__VA_ARGS__);}while(0);
#define cache_dbg(...) do{printf(__VA_ARGS__);}while(0);

//#define httpreq_dbg(...) do{printf(__VA_ARGS__);}while(0);

Expand Down
Loading

0 comments on commit fc03cb9

Please sign in to comment.