Hi Marc,
Thanks for this fix!
I'm curious as to why this code is BSD licensed now?
Cheers
Martin
-----Original Message-----
From: owner-abisource-cvs-commit@abisource.com on behalf of cvs@abisource.com
Sent: Sun 7/5/2009 5:42 AM
To: abisource-cvs-commit@abisource.com
Subject: uwog - r27137 - abiword/trunk/plugins/collab/backends/service/xp
Author: uwog
Date: 2009-07-04 21:42:17 +0200 (Sat, 04 Jul 2009)
New Revision: 27137
Modified:
abiword/trunk/plugins/collab/backends/service/xp/RealmConnection.cpp
abiword/trunk/plugins/collab/backends/service/xp/RealmConnection.h
abiword/trunk/plugins/collab/backends/service/xp/tls_tunnel.cpp
abiword/trunk/plugins/collab/backends/service/xp/tls_tunnel.h
Log:
Fix a tls tunnel disconnect crash, and relicense the ssl code under a BSD style license
Modified: abiword/trunk/plugins/collab/backends/service/xp/RealmConnection.cpp
===================================================================
--- abiword/trunk/plugins/collab/backends/service/xp/RealmConnection.cpp 2009-07-04 19:33:20 UTC (rev 27136)
+++ abiword/trunk/plugins/collab/backends/service/xp/RealmConnection.cpp 2009-07-04 19:42:17 UTC (rev 27137)
@@ -47,7 +47,8 @@
m_sig(sig),
m_buddies(),
m_pdp_ptr(),
- m_tls_tunnel_ptr()
+ m_tls_tunnel_ptr(),
+ m_mutex()
{
}
@@ -59,6 +60,7 @@
try {
// setup our local TLS tunnel to the realm
m_tls_tunnel_ptr.reset(new tls_tunnel::ClientProxy(m_address, m_port, m_ca_file, false));
+ m_tls_tunnel_ptr->setup();
asio::thread thread(boost::bind(&tls_tunnel::ClientProxy::run, m_tls_tunnel_ptr));
// connect to the tunnel
@@ -99,9 +101,14 @@
return true;
}
+// only the mainloop should call this function
void RealmConnection::disconnect()
{
UT_DEBUGMSG(("RealmConnection::disconnect()\n"));
+ abicollab::scoped_lock lock(m_mutex);
+
+ // trigger a disconnect; _disconnect will detect this, and perform
+ // the complete disconnect
if (m_socket.is_open())
{
asio::error_code ac;
@@ -168,10 +175,12 @@
}
}
+// disconnects, and signals the main loop of the disconnect
void RealmConnection::_disconnect()
{
UT_DEBUGMSG(("RealmConnection::_disconnect()\n"));
-
+ abicollab::scoped_lock lock(m_mutex);
+
if (m_socket.is_open())
{
asio::error_code ac;
@@ -191,7 +200,6 @@
m_tls_tunnel_ptr->stop();
m_tls_tunnel_ptr.reset();
}
-
// signal the packet queue, so the listener will be informed of the
// disconnect; this is a bit wacky (design wise), but it works
m_packet_queue.signal();
Modified: abiword/trunk/plugins/collab/backends/service/xp/RealmConnection.h
===================================================================
--- abiword/trunk/plugins/collab/backends/service/xp/RealmConnection.h 2009-07-04 19:33:20 UTC (rev 27136)
+++ abiword/trunk/plugins/collab/backends/service/xp/RealmConnection.h 2009-07-04 19:42:17 UTC (rev 27137)
@@ -29,6 +29,7 @@
#include "RealmGrowBuffer.h"
#include "RealmProtocol.h"
#include "tls_tunnel.h"
+#include <sync/xp/lock.h>
#include <sync/xp/SynchronizedQueue.h>
class AP_Dialog_GenericProgress;
@@ -137,6 +138,8 @@
m_pdp_ptr;
boost::shared_ptr<tls_tunnel::ClientProxy>
m_tls_tunnel_ptr;
+
+ abicollab::mutex m_mutex;
};
typedef boost::shared_ptr<RealmConnection> ConnectionPtr;
Modified: abiword/trunk/plugins/collab/backends/service/xp/tls_tunnel.cpp
===================================================================
--- abiword/trunk/plugins/collab/backends/service/xp/tls_tunnel.cpp 2009-07-04 19:33:20 UTC (rev 27136)
+++ abiword/trunk/plugins/collab/backends/service/xp/tls_tunnel.cpp 2009-07-04 19:42:17 UTC (rev 27137)
@@ -1,21 +1,31 @@
-/* Copyright (C) 2008 AbiSource Corporation B.V.
+/* Copyright (c) 2008-2009, AbiSource Corporation B.V.
+ * All rights reserved.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of AbiSource Corporation B.V. nor the
+ * names of other contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * THIS SOFTWARE IS PROVIDED BY ABISOURCE CORPORATION B.V. AND OTHER
+ * CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ABISOURCE
+ * CORPORATION B.V OR OTHER CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#include "tls_tunnel.h"
#define return_val_if_neg(C, val) { if (C < 0) {return val;} }
@@ -170,7 +180,12 @@
{
}
-ClientTransport::ClientTransport(const std::string& host, unsigned short port, boost::function<void (socket_ptr_t)> on_connect)
+Transport::~Transport()
+{
+}
+
+ClientTransport::ClientTransport(const std::string& host, unsigned short port,
+ boost::function<void (transport_ptr_t, socket_ptr_t)> on_connect)
: Transport(),
host_(host),
port_(port),
@@ -184,10 +199,11 @@
asio::ip::tcp::resolver::iterator iterator(resolver.resolve(query));
socket_ptr_t socket_ptr(new asio::ip::tcp::socket(io_service()));
socket_ptr->connect(*iterator);
- on_connect_(socket_ptr);
+ on_connect_(shared_from_this(), socket_ptr);
}
-ServerTransport::ServerTransport(const std::string& ip, unsigned short port, boost::function<void (socket_ptr_t)> on_connect)
+ServerTransport::ServerTransport(const std::string& ip, unsigned short port,
+ boost::function<void (transport_ptr_t, socket_ptr_t)> on_connect)
: Transport(),
acceptor_(io_service(), asio::ip::tcp::endpoint(asio::ip::address_v4::from_string(ip), port)),
on_connect_(on_connect)
@@ -203,7 +219,7 @@
if (error) {
return;
}
- on_connect_(socket_ptr);
+ on_connect_(shared_from_this(), socket_ptr);
accept();
}
@@ -230,21 +246,35 @@
gnutls_certificate_free_credentials(x509cred);
}
-void Proxy::run() {
- transport().run();
+void Proxy::run()
+{
+ // We copy the transport member pointer here to make sure the transport
+ // object can't be deleted another thread (for example by the reset call
+ // in ::stop()), while the transport is still running...
+ // This is the reason that I would love to get rid of the transport member
+ // variable, but I don't know how yet...
+ transport_ptr_t trans(transport_ptr_);
+ if (trans)
+ trans->run();
+ trans.reset();
}
-void Proxy::stop() {
- transport().stop(); // DOES THIS io.close() cancel stuff??
- if (t)
- {
+void Proxy::stop()
+{
+ if (transport_ptr_)
+ transport_ptr_->stop();
+
+ if (t) {
t->join();
t = NULL;
}
+
+ transport_ptr_.reset();
}
Proxy::Proxy(const std::string& ca_file)
- : t(NULL)
+ : transport_ptr_(),
+ t(NULL)
{
// setup certificates
if (gnutls_certificate_allocate_credentials(&x509cred) < 0)
@@ -254,32 +284,39 @@
}
void Proxy::on_local_read(const asio::error_code& error, std::size_t bytes_transferred,
- session_ptr_t session_ptr, socket_ptr_t local_socket_ptr, buffer_ptr_t local_buffer_ptr, socket_ptr_t remote_socket_ptr) {
+ transport_ptr_t transport_ptr, session_ptr_t session_ptr, socket_ptr_t local_socket_ptr,
+ buffer_ptr_t local_buffer_ptr, socket_ptr_t remote_socket_ptr)
+{
if (error) {
- disconnect_(session_ptr, local_socket_ptr, remote_socket_ptr);
+ disconnect_(transport_ptr, session_ptr, local_socket_ptr, remote_socket_ptr);
return;
}
// write the data to the tunnel connection
int num_forwarded = gnutls_record_send(*session_ptr, &(*local_buffer_ptr)[0], bytes_transferred);
if (num_forwarded < 0) {
- disconnect_(session_ptr, local_socket_ptr, remote_socket_ptr);
+ disconnect_(transport_ptr, session_ptr, local_socket_ptr, remote_socket_ptr);
return;
}
local_socket_ptr->async_receive(
asio::buffer(&(*local_buffer_ptr)[0], local_buffer_ptr->size()),
boost::bind(&Proxy::on_local_read, this, asio::placeholders::error, asio::placeholders::bytes_transferred,
- session_ptr, local_socket_ptr, local_buffer_ptr, remote_socket_ptr)
+ transport_ptr, session_ptr, local_socket_ptr, local_buffer_ptr, remote_socket_ptr)
);
}
-void Proxy::tunnel(session_ptr_t session_ptr, socket_ptr_t local_socket_ptr, socket_ptr_t remote_socket_ptr) {
+void Proxy::tunnel(transport_ptr_t transport_ptr, session_ptr_t session_ptr,
+ socket_ptr_t local_socket_ptr, socket_ptr_t remote_socket_ptr)
+{
buffer_ptr_t local_buffer_ptr(new std::vector<char>(LOCAL_BUFFER_SIZE));
- t = new asio::thread(boost::bind(&Proxy::tunnel_, this, session_ptr, local_socket_ptr, local_buffer_ptr, remote_socket_ptr));
+ t = new asio::thread(boost::bind(&Proxy::tunnel_, this, transport_ptr,
+ session_ptr, local_socket_ptr, local_buffer_ptr, remote_socket_ptr));
}
-void Proxy::disconnect_(session_ptr_t session_ptr, socket_ptr_t local_socket_ptr, socket_ptr_t remote_socket_ptr) {
+void Proxy::disconnect_(transport_ptr_t /*transport_ptr*/, session_ptr_t session_ptr,
+ socket_ptr_t local_socket_ptr, socket_ptr_t remote_socket_ptr)
+{
// shutdown the tls session (ignore any error condition)
if (session_ptr)
gnutls_bye(*session_ptr, GNUTLS_SHUT_RDWR);
@@ -297,11 +334,13 @@
}
}
-void Proxy::tunnel_(session_ptr_t session_ptr, socket_ptr_t local_socket_ptr, buffer_ptr_t local_buffer_ptr, socket_ptr_t remote_socket_ptr) {
+void Proxy::tunnel_(transport_ptr_t transport_ptr, session_ptr_t session_ptr, socket_ptr_t local_socket_ptr,
+ buffer_ptr_t local_buffer_ptr, socket_ptr_t remote_socket_ptr)
+{
local_socket_ptr->async_receive(
asio::buffer(&(*local_buffer_ptr)[0], local_buffer_ptr->size()),
boost::bind(&Proxy::on_local_read, this, asio::placeholders::error, asio::placeholders::bytes_transferred,
- session_ptr, local_socket_ptr, local_buffer_ptr, remote_socket_ptr)
+ transport_ptr, session_ptr, local_socket_ptr, local_buffer_ptr, remote_socket_ptr)
);
ssize_t bytes_transferred = 0;
@@ -324,7 +363,7 @@
}
}
- disconnect_(session_ptr, local_socket_ptr, remote_socket_ptr);
+ disconnect_(transport_ptr, session_ptr, local_socket_ptr, remote_socket_ptr);
}
static const int PRIORITIES[] = { GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, 0 };
@@ -333,34 +372,56 @@
// FIXME: this clientproxy can only handle 1 SSL connection at the same time
ClientProxy::ClientProxy(const std::string& connect_address, unsigned short connect_port,
const std::string& ca_file, bool check_hostname)
-try
: Proxy(ca_file),
- transport_(connect_address, connect_port, boost::bind(&ClientProxy::on_transport_connect, this, _1)),
local_address_("127.0.0.1"),
local_port_(0),
connect_address_(connect_address),
+ connect_port_(connect_port),
acceptor_ptr(),
check_hostname_(check_hostname)
{
- for (unsigned short port = MIN_CLIENT_PORT; port <= MAX_CLIENT_PORT; port++) {
- try {
- acceptor_ptr.reset(new asio::ip::tcp::acceptor(transport_.io_service(), asio::ip::tcp::endpoint(asio::ip::address_v4::from_string(local_address_), port), false));
- local_port_ = port;
- break;
- } catch (asio::system_error& se) {
- if (port == MAX_CLIENT_PORT)
- throw se;
- if (se.code() != asio::error::address_in_use)
- throw se;
- // this port is already in use, try another one
- continue;
+}
+
+void ClientProxy::setup()
+{
+ try
+ {
+ // FIXME: should we make the proxy a shared ptr?
+ transport_ptr_.reset(new ClientTransport(connect_address_, connect_port_,
+ boost::bind(&ClientProxy::on_transport_connect, this, _1, _2)));
+
+ for (unsigned short port = MIN_CLIENT_PORT; port <= MAX_CLIENT_PORT; port++) {
+ try {
+ acceptor_ptr.reset(
+ new asio::ip::tcp::acceptor(transport_ptr_->io_service(),
+ asio::ip::tcp::endpoint(asio::ip::address_v4::from_string(local_address_),
+ port), false));
+ local_port_ = port;
+ break;
+ } catch (asio::system_error& se) {
+ if (port == MAX_CLIENT_PORT)
+ throw se;
+ if (se.code() != asio::error::address_in_use)
+ throw se;
+ // this port is already in use, try another one
+ continue;
+ }
}
- }
- transport_.connect();
-} catch (asio::system_error& se) {
- throw Exception(std::string(TRANSPORT_ERROR) + se.what());
+
+ // connect the transport
+ boost::static_pointer_cast<ClientTransport>(transport_ptr_)->connect();
+ } catch (asio::system_error& se) {
+ throw Exception(std::string(TRANSPORT_ERROR) + se.what());
+ }
}
+void ClientProxy::stop()
+{
+ acceptor_ptr->close();
+ acceptor_ptr.reset();
+ Proxy::stop();
+}
+
const std::string& ClientProxy::local_address() const {
return local_address_;
}
@@ -369,31 +430,28 @@
return local_port_;
}
-Transport& ClientProxy::transport() {
- return static_cast<Transport&>(transport_);
-}
-
-void ClientProxy::on_transport_connect(socket_ptr_t remote_socket_ptr) {
+void ClientProxy::on_transport_connect(transport_ptr_t transport_ptr, socket_ptr_t remote_socket_ptr) {
session_ptr_t session_ptr = setup_tls_session(remote_socket_ptr);
if (!session_ptr) {
- disconnect_(session_ptr_t(), socket_ptr_t(), remote_socket_ptr);
+ disconnect_(transport_ptr, session_ptr_t(), socket_ptr_t(), remote_socket_ptr);
throw Exception(TLS_SETUP_ERROR);
}
// start accepting connections on the local socket
- socket_ptr_t local_socket_ptr(new asio::ip::tcp::socket(transport_.io_service()));
+ socket_ptr_t local_socket_ptr(new asio::ip::tcp::socket(transport_ptr->io_service()));
acceptor_ptr->async_accept(*local_socket_ptr, boost::bind(&ClientProxy::on_client_connect, this,
- asio::placeholders::error, session_ptr, local_socket_ptr, remote_socket_ptr));
+ asio::placeholders::error, transport_ptr, session_ptr, local_socket_ptr, remote_socket_ptr));
}
void ClientProxy::on_client_connect(const asio::error_code& error,
- session_ptr_t session_ptr, socket_ptr_t local_socket_ptr, socket_ptr_t remote_socket_ptr) {
+ transport_ptr_t transport_ptr, session_ptr_t session_ptr,
+ socket_ptr_t local_socket_ptr, socket_ptr_t remote_socket_ptr) {
if (error) {
- disconnect_(session_ptr, local_socket_ptr, remote_socket_ptr);
+ disconnect_(transport_ptr, session_ptr, local_socket_ptr, remote_socket_ptr);
return;
}
- tunnel(session_ptr, local_socket_ptr, remote_socket_ptr);
+ tunnel(transport_ptr, session_ptr, local_socket_ptr, remote_socket_ptr);
}
session_ptr_t ClientProxy::setup_tls_session(socket_ptr_t remote_socket_ptr) {
@@ -443,7 +501,8 @@
const std::string& ca_file, const std::string& cert_file, const std::string& key_file)
try
: Proxy(ca_file),
- transport_(bind_ip, bind_port, boost::bind(&ServerProxy::on_transport_connect, this, _1)),
+ bind_ip_(bind_ip),
+ bind_port_(bind_port),
local_port_(local_port)
{
// setup tls server state
@@ -457,36 +516,39 @@
throw Exception(TLS_SETUP_ERROR);
gnutls_certificate_set_dh_params(x509cred, dh_params);
-
- // start accepting connections
- transport_.accept();
} catch (asio::system_error& se) {
throw Exception(std::string(TRANSPORT_ERROR) + se.what());
}
-
-Transport& ServerProxy::transport() {
- return static_cast<Transport&>(transport_);
+
+void ServerProxy::setup()
+{
+ // FIXME: should we make the proxy a shared ptr?
+ transport_ptr_.reset(new ServerTransport(bind_ip_, bind_port_,
+ boost::bind(&ServerProxy::on_transport_connect, this, _1, _2)));
+
+ // start accepting connections
+ boost::static_pointer_cast<ServerTransport>(transport_ptr_)->accept();
}
-void ServerProxy::on_transport_connect(socket_ptr_t remote_socket_ptr) {
+void ServerProxy::on_transport_connect(transport_ptr_t transport_ptr, socket_ptr_t remote_socket_ptr) {
session_ptr_t session_ptr = setup_tls_session(remote_socket_ptr);
if (!session_ptr) {
- disconnect_(session_ptr_t(), socket_ptr_t(), remote_socket_ptr);
+ disconnect_(transport_ptr, session_ptr_t(), socket_ptr_t(), remote_socket_ptr);
return;
}
- socket_ptr_t local_socket_ptr(new asio::ip::tcp::socket(transport_.io_service()));
+ socket_ptr_t local_socket_ptr(new asio::ip::tcp::socket(transport_ptr->io_service()));
try {
- asio::ip::tcp::resolver resolver(transport_.io_service());
+ asio::ip::tcp::resolver resolver(transport_ptr->io_service());
asio::ip::tcp::resolver::query query("127.0.0.1", boost::lexical_cast<std::string>(local_port_));
asio::ip::tcp::resolver::iterator iterator(resolver.resolve(query));
local_socket_ptr->connect(*iterator);
} catch (asio::system_error& /*se*/) {
- disconnect_(session_ptr, local_socket_ptr, remote_socket_ptr);
+ disconnect_(transport_ptr, session_ptr, local_socket_ptr, remote_socket_ptr);
return;
}
- tunnel(session_ptr, local_socket_ptr, remote_socket_ptr);
+ tunnel(transport_ptr, session_ptr, local_socket_ptr, remote_socket_ptr);
}
session_ptr_t ServerProxy::setup_tls_session(socket_ptr_t remote_socket_ptr) {
Modified: abiword/trunk/plugins/collab/backends/service/xp/tls_tunnel.h
===================================================================
--- abiword/trunk/plugins/collab/backends/service/xp/tls_tunnel.h 2009-07-04 19:33:20 UTC (rev 27136)
+++ abiword/trunk/plugins/collab/backends/service/xp/tls_tunnel.h 2009-07-04 19:42:17 UTC (rev 27137)
@@ -1,28 +1,39 @@
-/* Copyright (C) 2008 AbiSource Corporation B.V.
+/* Copyright (c) 2008-2009, AbiSource Corporation B.V.
+ * All rights reserved.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of AbiSource Corporation B.V. nor the
+ * names of other contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * THIS SOFTWARE IS PROVIDED BY ABISOURCE CORPORATION B.V. AND OTHER
+ * CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ABISOURCE
+ * CORPORATION B.V OR OTHER CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#ifndef __TLS_TUNNEL_H__
#define __TLS_TUNNEL_H__
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
#include <boost/lexical_cast.hpp>
-#include <boost/function.hpp>
+#include <boost/enable_shared_from_this.hpp>
#include <asio.hpp>
-#include <boost/bind.hpp>
#include <string>
#include <vector>
#ifdef _MSC_VER
@@ -47,39 +58,45 @@
std::string message_;
};
-class Transport {
+class Transport : public boost::enable_shared_from_this<Transport> {
public:
- asio::io_service& io_service();
+ asio::io_service& io_service();
void run();
void stop();
protected:
Transport();
+ virtual ~Transport();
private:
asio::io_service io_service_;
asio::io_service::work work_;
};
+typedef boost::shared_ptr<Transport> transport_ptr_t;
+
class ClientTransport : public Transport {
public:
- ClientTransport(const std::string& host, unsigned short port, boost::function<void (socket_ptr_t)> on_connect);
+ ClientTransport(const std::string& host, unsigned short port,
+ boost::function<void (transport_ptr_t, socket_ptr_t)> on_connect);
void connect();
private:
std::string host_;
unsigned short port_;
- boost::function<void (socket_ptr_t)> on_connect_;
+ boost::function<void (transport_ptr_t, socket_ptr_t)> on_connect_;
};
+
class ServerTransport : public Transport {
public:
- ServerTransport(const std::string& ip, unsigned short port, boost::function<void (socket_ptr_t)> on_connect);
+ ServerTransport(const std::string& ip, unsigned short port,
+ boost::function<void (transport_ptr_t, socket_ptr_t)> on_connect);
void accept();
private:
void on_accept(const asio::error_code& error, socket_ptr_t socket_ptr);
asio::ip::tcp::acceptor acceptor_;
- boost::function<void (socket_ptr_t)> on_connect_;
+ boost::function<void (transport_ptr_t, socket_ptr_t)> on_connect_;
};
class Proxy {
@@ -87,22 +104,29 @@
virtual ~Proxy();
static bool tls_tunnel_init();
static void tls_tunnel_deinit();
+ virtual void setup() = 0;
void run();
- void stop();
- virtual Transport& transport() = 0;
+ virtual void stop();
protected:
Proxy(const std::string& ca_file);
-
+
void on_local_read(const asio::error_code& error, std::size_t bytes_transferred,
- session_ptr_t session_ptr, socket_ptr_t local_socket_ptr, buffer_ptr_t local_buffer_ptr, socket_ptr_t remote_socket_ptr);
- void tunnel(session_ptr_t session_ptr, socket_ptr_t local_socket_ptr, socket_ptr_t remote_socket_ptr);
- void disconnect_(session_ptr_t session_ptr, socket_ptr_t local_socket_ptr, socket_ptr_t remote_socket_ptr);
+ transport_ptr_t transport_ptr, session_ptr_t session_ptr, socket_ptr_t local_socket_ptr,
+ buffer_ptr_t local_buffer_ptr, socket_ptr_t remote_socket_ptr);
+ void tunnel(transport_ptr_t transport_ptr, session_ptr_t session_ptr,
+ socket_ptr_t local_socket_ptr, socket_ptr_t remote_socket_ptr);
+ void disconnect_(transport_ptr_t transport_ptr, session_ptr_t session_ptr,
+ socket_ptr_t local_socket_ptr, socket_ptr_t remote_socket_ptr);
gnutls_certificate_credentials_t x509cred;
+ transport_ptr_t transport_ptr_; // we only store this as a member so we are able to start/stop the transport
+
private:
- void tunnel_(session_ptr_t session_ptr, socket_ptr_t local_socket_ptr, buffer_ptr_t local_buffer_ptr, socket_ptr_t remote_socket_ptr);
+ void tunnel_(transport_ptr_t transport_ptr, session_ptr_t session_ptr,
+ socket_ptr_t local_socket_ptr, buffer_ptr_t local_buffer_ptr,
+ socket_ptr_t remote_socket);
asio::thread* t;
};
@@ -113,20 +137,22 @@
ClientProxy(const std::string& connect_address, unsigned short connect_port,
const std::string& ca_file, bool check_hostname);
+ virtual void setup();
+ virtual void stop();
+
const std::string& local_address() const;
unsigned short local_port() const;
-
+
private:
- Transport& transport();
- void on_transport_connect(socket_ptr_t remote_socket_ptr);
- void on_client_connect(const asio::error_code& error,
+ void on_transport_connect(transport_ptr_t transport_ptr, socket_ptr_t remote_socket_ptr);
+ void on_client_connect(const asio::error_code& error, transport_ptr_t transport_ptr,
session_ptr_t session_ptr, socket_ptr_t local_socket_ptr, socket_ptr_t remote_socket_ptr);
session_ptr_t setup_tls_session(socket_ptr_t remote_socket_ptr);
- ClientTransport transport_;
std::string local_address_;
unsigned short local_port_;
std::string connect_address_;
+ unsigned short connect_port_;
boost::shared_ptr<asio::ip::tcp::acceptor> acceptor_ptr;
bool check_hostname_;
};
@@ -135,13 +161,15 @@
public:
ServerProxy(const std::string& bind_ip, unsigned short bind_port, unsigned short local_port,
const std::string& ca_file, const std::string& cert_file, const std::string& key_file);
+
+ virtual void setup();
private:
- Transport& transport();
- void on_transport_connect(socket_ptr_t remote_socket_ptr);
+ void on_transport_connect(transport_ptr_t transport_ptr, socket_ptr_t remote_socket_ptr);
session_ptr_t setup_tls_session(socket_ptr_t remote_socket_ptr);
-
- ServerTransport transport_;
+
+ std::string bind_ip_;
+ unsigned short bind_port_;
unsigned short local_port_;
gnutls_dh_params_t dh_params;
};
-----------------------------------------------
To unsubscribe from this list, send a message to
abisource-cvs-commit-request@abisource.com with the word
unsubscribe in the message body.
This archive was generated by hypermail 2.1.8 : Sun Jul 05 2009 - 04:08:22 CEST