3 #include <openssl/bio.h>
4 #include <openssl/ssl.h>
6 #include <boost/format.hpp>
7 #include <loki/ScopeGuard.h>
11 /*static */Connector
& Connector::getInstance()
13 static Connector instance__
;
17 Connection
Connector::connect(const std::string
& remote_address
, boost::uint16_t port
, bool use_ssl
/* = false*/)
19 boost::format
fmt("%1%:%2%");
20 fmt
% remote_address
% port
;
21 ::BIO
* bio(use_ssl
? connectSSL_(fmt
.str()) : connect_(fmt
.str()));
22 return Connection(bio
);
25 Connector::Connector()
28 Connector::~Connector()
31 ::BIO
* Connector::connectSSL_(const std::string
& target
)
33 ::SSL_CTX
* ssl_context
= ::SSL_CTX_new(::SSLv23_client_method());
35 throw std::runtime_error("failed to allocate SSL context"); // HERE be more eloquent
38 Loki::ScopeGuard ssl_context_guard
= Loki::MakeGuard(SSL_CTX_free
, ssl_context
);
39 /* We'd normally set some stuff like the verify paths and
40 * mode here because as things stand this will connect to
41 * any server whose certificate is signed by any CA. */
42 ::BIO
* bio(BIO_new_ssl_connect(ssl_context
));
44 throw std::runtime_error("Failed to create connection socket"); // HERE too
47 Loki::ScopeGuard bio_guard
= Loki::MakeGuard(::BIO_free
, bio
);
49 BIO_get_ssl(bio
, &ssl
);
51 throw std::runtime_error("Can't locate SSL pointer");
54 SSL_set_mode(ssl
, SSL_MODE_AUTO_RETRY
);
55 // we might want to do some other things with the SSL HERE
56 BIO_set_conn_hostname(bio
, target
.c_str());
57 if (BIO_do_connect(bio
) <= 0)
58 throw std::runtime_error("Failed to create connection"); // HERE again
61 if (BIO_do_handshake(bio
) <= 0)
62 throw std::runtime_error("handshake failed"); // HERE again
67 ssl_context_guard
.Dismiss();
71 ::BIO
* Connector::connect_(const std::string
& target
)
73 // BIO_new_connect wants a char*, not a const char*
74 std::vector
< char > buff(target
.begin(), target
.end());
76 ::BIO
* bio(::BIO_new_connect(&(buff
[0])));
78 throw std::runtime_error("Failed to create connection socket"); // HERE be more eloquent
81 Loki::ScopeGuard bio_guard
= Loki::MakeGuard(::BIO_free
, bio
);
82 if (::BIO_do_connect(bio
) <= 0)
83 throw std::runtime_error("Failed to create the connection");