/* Web Polygraph http://www.web-polygraph.org/
* (C) 2003-2006 The Measurement Factory
* Licensed under the Apache License, Version 2.0 */
#ifndef POLYGRAPH__RUNTIME_CONNECTION_H
#define POLYGRAPH__RUNTIME_CONNECTION_H
#include "xstd/Queue.h"
#include "xstd/NetAddr.h"
#include "xstd/Socket.h"
#include "xstd/FileScanner.h"
#include "base/ConnCloseStat.h"
#include "runtime/IOBuf.h"
class ConnMgr;
class PortMgr;
class SslCtx;
class SslSession;
class Ssl;
// bi-directional connection based on a socket with I/O buffers
class Connection: public QueueItem {
public:
typedef ConnCloseStat::CloseKind CloseKind;
typedef Size (Connection::*IoMethod)();
class HalfPipe {
public:
HalfPipe(Connection &aConn, IOBuf &aBuf, IODir aDir):
theConn(aConn), theBuf(aBuf), theDir(aDir) { reset(); }
void reset();
void start(FileScanUser *u);
void start(FileScanUser *u, Time timeout);
void stop(FileScanUser *u);
void changeUser(FileScanUser *uOld, FileScanUser *uNew);
public:
Connection &theConn;
IOBuf &theBuf;
IODir theDir;
FileScanReserv theReserv;
int theIOCnt;
bool isReady;
};
friend class HalfPipe;
public:
Connection();
~Connection() { if (theSock) closeNow(); }
void reset();
int seqId() const { return theSeqId; }
Socket &sock() { return theSock; }
int fd() const { return theSock.fd(); }
const NetAddr &raddr() const { return theAddr; }
NetAddr laddr() const;
int lport() const { return theLocPort; }
int rport() const;
ConnMgr *mgr() const { return theMgr; }
int logCat() const { return theLogCat; }
bool exhausted() const { return isAtEof && !theRdBuf.contSize(); }
bool atEof() const { return isAtEof; }
bool bad() const { return isBad; }
CloseKind closeKind() const { return theCloseKind; }
bool sslConfigured() const { return theSslCtx != 0; }
const Ssl *sslActive() const { return theSsl; }
bool sslActivate();
SslSession *sslSession();
void sslSessionForget();
bool connect(const NetAddr &addr, const SockOpt &opt, PortMgr *aPortMgr);
bool accept(Socket &s, const SockOpt &opt, bool &fatal);
Size read();
Size write();
bool closing() const { return theCloseKind != ConnCloseStat::ckNone; }
bool closeNow(); // closes everything
// initiates SSL close, returns true if done; does not close raw sock
bool closeAsync(FileScanUser *u, bool &fatal);
void mgr(ConnMgr *aMgr) { theMgr = aMgr; }
void logCat(int aLogCat) { theLogCat = aLogCat; }
void useSsl(const SslCtx *aCtx, SslSession *aSess);
bool pipelineable() const;
bool reusable() const;
void useCountLimit(int aLimit) { theUseCountLmt = aLimit; }
void useLevelLimit(int aLimit) { theUseLevelLmt = aLimit; }
int useCnt() const { return theUseCnt; }
int useLevel() const { return theUseLvl; }
void startUse();
void finishUse();
bool inUse() const { return theUseLvl > 0; }
Time useStart() const { return theUseStart; }
bool isIdle() const { return theUseLvl == 0; }
int useLevelMax() const { return theUseLvlMax; }
bool tunneling() const { return theTunnel.known() && theTunnel != raddr(); }
const NetAddr &tunnelEnd() const { return theTunnel; }
void tunnelEnd(const NetAddr &addr) { theTunnel = addr; }
Time openTime() const { return theOpenTime; }
int ioCnt() const { return theRd.theIOCnt + theWr.theIOCnt; }
void bad(bool be) { isBad = be; }
void lastUse(bool be) { isLastUse = be; }
void closeKind(CloseKind aKind) { theCloseKind = aKind; }
void decMaxIoSize(Size aMax);
void maxIoSize(Size aMax) { theMaxIoSize = aMax; }
protected:
void sslStart(int role);
bool sslAccept();
bool sslConnect();
Size sslRead(Size ioSz);
Size sslWrite(Size ioSz);
bool sslCloseNow();
bool sslCloseAsync(FileScanUser *u, bool &fatal);
void sslForget();
void sslError(int err, const char *operation);
Size rawRead(Size ioSz);
Size rawWrite(Size ioSz);
bool rawCloseNow();
void rawError(const char *operation);
bool setSockOpt(const SockOpt &opt);
bool preIo(HalfPipe &ioPipe, const char *operation);
void reportErrorLoc();
public:
RdBuf theRdBuf;
WrBuf theWrBuf;
HalfPipe theRd; // these refer to bufs; must go after them!
HalfPipe theWr;
protected:
Socket theSock;
NetAddr theAddr;
mutable ConnMgr *theMgr;
PortMgr *thePortMgr; // used to pass address to bind call
const SslCtx *theSslCtx; // set by owner to request ssl encription
SslSession *theSslSession; // set by owner if resumption is needed
NetAddr theTunnel; // the other end of the tunnel if tunneling
int theLocPort;
mutable int theRemPort; // used as a cache for sock().rport()
Time theOpenTime;
Time theUseStart; // start of the current/last "use"
int theUseCountLmt; // maximum total number of uses allowed
int theUseLevelLmt; // maximum total number of uses allowed
int theUseCnt; // number of "uses" since open()
int theUseLvl; // number of current concurrent "uses"
int theUseLvlMax; // maximum use level since open()
CloseKind theCloseKind; // how the connection was closed
Size theMaxIoSize; // per-io limit, reset after each IO
int theLogCat; // log entry category
bool isBad;
bool isAtEof;
bool isLastUse; // this must be the last use of the conn
private:
static int TheLastSeqId;
int theSeqId;
Ssl *theSsl; // created internally if needed
};
#endif
syntax highlighted by Code2HTML, v. 0.9.1