1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
/*
* tcpconnect.h
*
* Created on: 27.02.2010
* Author: ed
*/
#ifndef TCPCONNECT_H_
#define TCPCONNECT_H_
#include <atomic>
#include <memory>
#include "meta.h"
#include "sockio.h"
#include <memory>
#ifdef HAVE_SSL
#include <openssl/bio.h>
#include "acbuf.h"
#endif
namespace acng
{
class tcpconnect;
class fileitem;
typedef std::shared_ptr<tcpconnect> tDlStreamHandle;
class tcpconnect
{
public:
virtual ~tcpconnect();
virtual int GetFD() { return m_conFd; }
inline cmstring & GetHostname() { return m_sHostName; }
inline cmstring & GetPort() { return m_sPort; }
void Disconnect();
#ifdef HAVE_SSL
inline BIO* GetBIO() { return m_bio;};
#endif
protected:
tcpconnect operator=(const tcpconnect&);
tcpconnect(const tcpconnect&) =default;
tcpconnect(cfg::tRepoData::IHookHandler *pStateReport);
int m_conFd =-1;
mstring m_sHostName, m_sPort;
std::weak_ptr<fileitem> m_lastFile;
public:
//! @brief Remember the file name belonging to the recently initiated transfer
inline void KnowLastFile(WEAK_PTR<fileitem> spRemItem) { m_lastFile = spRemItem; }
//! @brief Invalidate (truncate) recently touched file
void KillLastFile();
//! @brief Request tunneling with CONNECT and change identity if succeeded, and start TLS
bool StartTunnel(const tHttpUrl & realTarget, mstring& sError, cmstring *psAuthorization, bool bDoSSLinit);
private:
bool _Connect(mstring &sErrOut, int timeout);
cfg::tRepoData::IHookHandler *m_pStateObserver=nullptr;
protected:
#ifdef HAVE_SSL
BIO *m_bio = nullptr;
SSL_CTX * m_ctx = nullptr;
SSL * m_ssl = nullptr;
bool SSLinit(mstring &sErr, cmstring &host, cmstring &port);
#endif
friend class dl_con_factory;
};
class IDlConFactory
{
public:
/// Moves the connection handle to the reserve pool (resets the specified sptr).
/// Should only be supplied with IDLE connection handles in a sane state.
virtual void RecycleIdleConnection(tDlStreamHandle & handle) =0;
virtual tDlStreamHandle CreateConnected(cmstring &sHostname, cmstring &sPort,
mstring &sErrOut,
bool *pbSecondHand,
cfg::tRepoData::IHookHandler *pStateTracker
,bool ssl
,int timeout
,bool mustbevirgin
) =0;
virtual ~IDlConFactory() {};
};
class dl_con_factory : public IDlConFactory
{
public:
/// Moves the connection handle to the reserve pool (resets the specified sptr).
/// Should only be supplied with IDLE connection handles in a sane state.
virtual void RecycleIdleConnection(tDlStreamHandle & handle) override;
virtual tDlStreamHandle CreateConnected(cmstring &sHostname, cmstring &sPort,
mstring &sErrOut,
bool *pbSecondHand,
cfg::tRepoData::IHookHandler *pStateTracker
,bool ssl
,int timeout
,bool mustbevirgin
) override;
virtual ~dl_con_factory() {};
void dump_status();
time_t BackgroundCleanup();
protected:
friend class tcpconnect;
static std::atomic_uint g_nconns;
};
extern dl_con_factory g_tcp_con_factory;
/*
// little tool for related classes, helps counting all object instances
class instcount
{
private:
typedef std::atomic_uint tInstCounter;
tInstCounter& m_instCount;
public:
inline instcount(tInstCounter& cter) : m_instCount(cter) {
m_instCount.fetch_add(1);
}
virtual ~instcount() {
m_instCount.fetch_add(-1);
}
unsigned int GetInstCount(unsigned type) { return m_instCount.load();}
};
*/
}
#endif /* TCPCONNECT_H_ */
|