summaryrefslogtreecommitdiffstats
blob: 69f719d11e543894d01c903accd8fd842c26fc09 (plain)
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
/*
 * Copyright (c) 2012-2016 Isode Limited.
 * All rights reserved.
 * See the COPYING file for more information.
 */

#include <Swiften/Network/ProxiedConnection.h>

#include <boost/bind.hpp>

#include <Swiften/Base/ByteArray.h>
#include <Swiften/Base/Log.h>
#include <Swiften/Network/ConnectionFactory.h>
#include <Swiften/Network/HostAddressPort.h>

using namespace Swift;

ProxiedConnection::ProxiedConnection(
		DomainNameResolver* resolver, 
		ConnectionFactory* connectionFactory, 
		TimerFactory* timerFactory, 
		const std::string& proxyHost, 
		int proxyPort) : 
			resolver_(resolver),
			connectionFactory_(connectionFactory), 
			timerFactory_(timerFactory), 
			proxyHost_(proxyHost), 
			proxyPort_(proxyPort), 
			server_(HostAddressPort(HostAddress("0.0.0.0"), 0)) {
	connected_ = false;
}

ProxiedConnection::~ProxiedConnection() {
	cancelConnector();
	if (connection_) {
		connection_->onDataRead.disconnect(boost::bind(&ProxiedConnection::handleDataRead, shared_from_this(), _1));
		connection_->onDisconnected.disconnect(boost::bind(&ProxiedConnection::handleDisconnected, shared_from_this(), _1));
	}
	if (connected_) {
		SWIFT_LOG(warning) << "Connection was still established." << std::endl;
	}
}

void ProxiedConnection::cancelConnector() {
	if (connector_) {
		connector_->onConnectFinished.disconnect(boost::bind(&ProxiedConnection::handleConnectFinished, shared_from_this(), _1));
		connector_->stop();
		connector_.reset();
	}
}

void ProxiedConnection::connect(const HostAddressPort& server) {
	server_ = server;

	connector_ = Connector::create(proxyHost_, proxyPort_, boost::optional<std::string>(), resolver_, connectionFactory_, timerFactory_);
	connector_->onConnectFinished.connect(boost::bind(&ProxiedConnection::handleConnectFinished, shared_from_this(), _1));
	connector_->start();
}

void ProxiedConnection::listen() {
	assert(false);
	connection_->listen();
}

void ProxiedConnection::disconnect() {
	cancelConnector();
	connected_ = false;
	if (connection_) {
		connection_->disconnect();
	}
}

void ProxiedConnection::handleDisconnected(const boost::optional<Error>& error) {
	onDisconnected(error);
}

void ProxiedConnection::write(const SafeByteArray& data) {
	connection_->write(data);
}

void ProxiedConnection::handleConnectFinished(Connection::ref connection) {
	cancelConnector();
	if (connection) {
		connection_ = connection;
		connection_->onDataRead.connect(boost::bind(&ProxiedConnection::handleDataRead, shared_from_this(), _1));
		connection_->onDisconnected.connect(boost::bind(&ProxiedConnection::handleDisconnected, shared_from_this(), _1));
		
		initializeProxy();
	}
	else {
		onConnectFinished(true);
	}
}

void ProxiedConnection::handleDataRead(boost::shared_ptr<SafeByteArray> data) {
	if (!connected_) {
		handleProxyInitializeData(data);
	}
	else {
		onDataRead(data);
	}
}

HostAddressPort ProxiedConnection::getLocalAddress() const {
	return connection_->getLocalAddress();
}

HostAddressPort ProxiedConnection::getRemoteAddress() const {
	return connection_->getRemoteAddress();
}

void ProxiedConnection::setProxyInitializeFinished(bool success) {
	connected_ = success;
	if (!success) {
		disconnect();
	}
	onConnectFinished(!success);
}

void ProxiedConnection::reconnect() {
	if (connected_) {
		connection_->onDataRead.disconnect(boost::bind(&ProxiedConnection::handleDataRead, shared_from_this(), _1));
		connection_->onDisconnected.disconnect(boost::bind(&ProxiedConnection::handleDisconnected, shared_from_this(), _1));
		connection_->disconnect();
	}
	connect(server_);
}