summaryrefslogtreecommitdiffstats
blob: 16bab0d74f297aff4740bdc65ce941af14994328 (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(std::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_);
}