/* Web Polygraph http://www.web-polygraph.org/
* (C) 2003-2006 The Measurement Factory
* Licensed under the Apache License, Version 2.0 */
#include "base/polygraph.h"
#include "xstd/Clock.h"
#include "xstd/Ssl.h"
#include "base/UniqId.h"
#include "base/polyLogCats.h"
#include "runtime/SslWrap.h"
#include "runtime/ErrorMgr.h"
#include "runtime/polyBcastChannels.h"
#include "runtime/polyErrors.h"
#include "runtime/globals.h"
#include "server/SrvConnMgr.h"
SrvConnMgr::SrvConnMgr(User *aUser): theUser(aUser), theAcceptLmt(-1) {
Assert(theUser);
}
void SrvConnMgr::acceptLmt(int aLmt) {
theAcceptLmt = aLmt;
}
void SrvConnMgr::configureSsl(SslCtx *aCtx, const SslWrap *wrap) {
ConnMgr::configureSsl(aCtx, wrap);
if (!theSslCtx)
return;
const int cacheSize = wrap->sessionCacheSize();
if (wrap->resumpProb() > 0 && cacheSize != 0) {
aCtx->sessionCacheMode(SSL_SESS_CACHE_SERVER);
aCtx->sessionId(theUser->id().str());
if (cacheSize > 0)
aCtx->sessionCacheSize(cacheSize);
} else {
aCtx->sessionCacheMode(SSL_SESS_CACHE_OFF);
}
}
// return false iff fatal error
bool SrvConnMgr::accept(Socket &s) {
static const Time acceptTimeLmt = Time::Msec(10);
const Time startTime = TheClock;
// note: negative accept limit means no limit
for (int i = theAcceptLmt; i; --i) {
bool fatal = false;
Connection *conn = TheConnFarm.get();
conn->logCat(lgcSrvSide);
if (theSslCtx)
conn->useSsl(theSslCtx, 0);
if (!conn->accept(s, theSockOpt, fatal)) {
// note: no close() for an un-opened conn
TheConnFarm.put(conn);
return !fatal;
}
opened(conn);
conn->theRd.start(this); // wait for data
// occasionally, check if we have been acceting for too long
if (i % 10 == 0) {
Clock::Update(false);
if (TheClock - startTime > acceptTimeLmt)
break;
}
}
return true;
}
// this gets called for an idle conn and on the freshly accepted conn
void SrvConnMgr::noteReadReady(int fd) {
Connection *conn = TheConnIdx[fd];
Assert(conn);
TheConnIdx.check(conn);
if (conn->closing()) {
ConnMgr::noteReadReady(fd);
} else {
conn->theRd.stop(this);
TheFileScanner->clearTimeout(fd);
conn->read(); // we do the first read, not a xaction
if (!conn->bad()) {
if (!conn->exhausted()) {
conn->startUse();
theUser->noteConnReady(conn);
return;
}
if (!conn->useCnt())
ReportError2(errNoHdrClose, lgcSrvSide);
}
if (conn->useCnt())
closeIdle(conn, ConnCloseStat::ckIdleForeign);
else
closeBusy(conn);
}
}
void SrvConnMgr::putIdle(Connection *conn) {
Assert(!conn->theRd.theReserv && !conn->theWr.theReserv);
// there may be more requests waiting
if (conn->theRdBuf.contSize()) {
conn->startUse();
theUser->noteConnReady(conn);
} else {
ConnMgr::putIdle(conn);
}
}
syntax highlighted by Code2HTML, v. 0.9.1