/***************************************************************************
- * Copyright (C) 2005-2018 by the Quassel Project *
+ * Copyright (C) 2005-2020 by the Quassel Project *
* devel@quassel-irc.org *
* *
* This program is free software; you can redistribute it and/or modify *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
-#include <QHostAddress>
-#include <QTimer>
+#include <utility>
+
#include <QtEndian>
-#ifdef HAVE_SSL
-# include <QSslSocket>
-#else
-# include <QTcpSocket>
-#endif
+#include <QHostAddress>
+#include <QSslSocket>
+#include <QTimer>
+#include "proxyline.h"
#include "remotepeer.h"
#include "util.h"
, _socket(socket)
, _compressor(new Compressor(socket, level, this))
, _signalProxy(nullptr)
+ , _proxyLine({})
+ , _useProxyLine(false)
, _heartBeatTimer(new QTimer(this))
, _heartBeatCount(0)
, _lag(0)
connect(socket, selectOverload<QAbstractSocket::SocketError>(&QAbstractSocket::error), this, &RemotePeer::onSocketError);
connect(socket, &QAbstractSocket::disconnected, this, &Peer::disconnected);
-#ifdef HAVE_SSL
auto* sslSocket = qobject_cast<QSslSocket*>(socket);
if (sslSocket) {
connect(sslSocket, &QSslSocket::encrypted, this, [this]() { emit secureStateChanged(true); });
}
-#endif
connect(_compressor, &Compressor::readyRead, this, &RemotePeer::onReadyRead);
connect(_compressor, &Compressor::error, this, &RemotePeer::onCompressionError);
QString RemotePeer::description() const
{
- if (socket())
- return socket()->peerAddress().toString();
+ return address();
+}
+
+QHostAddress RemotePeer::hostAddress() const
+{
+ if (_useProxyLine) {
+ return _proxyLine.sourceHost;
+ }
+ else if (socket()) {
+ return socket()->peerAddress();
+ }
- return QString();
+ return {};
}
QString RemotePeer::address() const
{
- if (socket())
- return socket()->peerAddress().toString();
-
- return QString();
+ QHostAddress address = hostAddress();
+ if (address.isNull()) {
+ return {};
+ }
+ else {
+ return address.toString();
+ }
}
quint16 RemotePeer::port() const
{
- if (socket())
+ if (_useProxyLine) {
+ return _proxyLine.sourcePort;
+ }
+ else if (socket()) {
return socket()->peerPort();
+ }
return 0;
}
if (socket()) {
if (isLocal())
return true;
-#ifdef HAVE_SSL
auto* sslSocket = qobject_cast<QSslSocket*>(socket());
if (sslSocket && sslSocket->isEncrypted())
return true;
-#endif
}
return false;
}
bool RemotePeer::isLocal() const
{
- if (socket()) {
- if (socket()->peerAddress() == QHostAddress::LocalHost || socket()->peerAddress() == QHostAddress::LocalHostIPv6)
- return true;
- }
- return false;
+ return hostAddress() == QHostAddress::LocalHost ||
+ hostAddress() == QHostAddress::LocalHostIPv6;
}
bool RemotePeer::isOpen() const
if (_msgSize == 0) {
if (_compressor->bytesAvailable() < 4)
return false;
- _compressor->read((char*)&_msgSize, 4);
+ _compressor->read((char*) &_msgSize, 4);
_msgSize = qFromBigEndian<quint32>(_msgSize);
if (_msgSize > maxMessageSize) {
dispatch(HeartBeat(QDateTime::currentDateTime().toUTC()));
++_heartBeatCount;
}
+
+void RemotePeer::setProxyLine(ProxyLine proxyLine)
+{
+ _proxyLine = std::move(proxyLine);
+
+ if (socket()) {
+ if (_proxyLine.protocol != QAbstractSocket::UnknownNetworkLayerProtocol) {
+ QList<QString> subnets = Quassel::optionValue("proxy-cidr").split(",");
+ for (const QString& subnet : subnets) {
+ if (socket()->peerAddress().isInSubnet(QHostAddress::parseSubnet(subnet))) {
+ _useProxyLine = true;
+ return;
+ }
+ }
+ }
+ }
+ _useProxyLine = false;
+}