summaryrefslogtreecommitdiffstats
path: root/pica-client
diff options
context:
space:
mode:
authorAnton <anton@picapica>2017-12-30 21:06:08 +0400
committerAnton <anton@picapica>2017-12-30 21:06:08 +0400
commitfe90bf0b2eb78f74836b6ab7832aa06e6d48b673 (patch)
tree206e168819d1dde81d29d8e11ab22c33646de0de /pica-client
parent87c68a2ecadee7c86d80b585a2ed47b352c7b2d6 (diff)
downloadpica-pica-fe90bf0b2eb78f74836b6ab7832aa06e6d48b673.tar.gz
pica-pica-fe90bf0b2eb78f74836b6ab7832aa06e6d48b673.zip
pica-client: implemented autoconfiguration of address for direct incoming connections
Diffstat (limited to 'pica-client')
-rw-r--r--pica-client/dialogs/settingsdialog.cpp50
-rw-r--r--pica-client/dialogs/settingsdialog.h4
-rw-r--r--pica-client/pica-client.pro11
-rw-r--r--pica-client/skynet.cpp28
4 files changed, 86 insertions, 7 deletions
diff --git a/pica-client/dialogs/settingsdialog.cpp b/pica-client/dialogs/settingsdialog.cpp
index d16bb63..1bd7812 100644
--- a/pica-client/dialogs/settingsdialog.cpp
+++ b/pica-client/dialogs/settingsdialog.cpp
@@ -1,6 +1,7 @@
#include "settingsdialog.h"
#include "../settings.h"
#include "../globals.h"
+#include "../../PICA_netconf.h"
#include <QGroupBox>
#include <QVBoxLayout>
@@ -28,6 +29,11 @@ SettingsDialog::SettingsDialog(QWidget *parent) :
rbEnableOutgoingConns = new QRadioButton(tr("Connect to the remote peer directly if possible"), this);
rbEnableIncomingConns = new QRadioButton(tr("Enable incoming direct connections"), this);
+#ifdef HAVE_LIBMINIUPNPC
+ cbEnableUPnP = new QCheckBox(tr("Enable UPnP"));
+ cbEnableUPnP->setChecked(true);
+#endif
+
rbEnableIncomingConns->setChecked(true);
connect(rbEnableIncomingConns, SIGNAL(toggled(bool)), this, SLOT(toggleIncomingConnections(bool)));
@@ -49,6 +55,8 @@ SettingsDialog::SettingsDialog(QWidget *parent) :
QList<QHostAddress> hostIfAddrs = QNetworkInterface::allAddresses();
QHostAddress ifAddr;
+ addr->addItem(QString("autoconfigure"));
+
foreach (ifAddr, hostIfAddrs)
if (ifAddr.protocol() == QAbstractSocket::IPv4Protocol)
addr->addItem(ifAddr.toString());
@@ -57,6 +65,9 @@ SettingsDialog::SettingsDialog(QWidget *parent) :
directc2cLayout->addWidget(rbDisableDirectConns);
directc2cLayout->addWidget(rbEnableOutgoingConns);
directc2cLayout->addWidget(rbEnableIncomingConns);
+#ifdef HAVE_LIBMINIUPNPC
+ directc2cLayout->addWidget(cbEnableUPnP);
+#endif
directc2cLayout->addWidget(lbAddr);
directc2cLayout->addWidget(addr);
directc2cLayout->addWidget(lbPubPort);
@@ -99,6 +110,9 @@ void SettingsDialog::toggleIncomingConnections(bool checked)
addr->setEnabled(checked);
publicPort->setEnabled(checked);
localPort->setEnabled(checked);
+#ifdef HAVE_LIBMINIUPNPC
+ cbEnableUPnP->setEnabled(checked);
+#endif
}
void SettingsDialog::OK()
@@ -139,7 +153,37 @@ void SettingsDialog::loadSettings()
break;
}
- addr->lineEdit()->setText(st.loadValue("direct_c2c.public_addr", "0.0.0.0").toString());
+#ifdef HAVE_LIBMINIUPNPC
+ cbEnableUPnP->setChecked(st.loadValue("direct_c2c.upnp_enabled", 1).toBool());
+#endif
+
+ addr->lineEdit()->setText(st.loadValue("direct_c2c.public_addr", "autoconfigure").toString());
+
+ if (addr->lineEdit()->text().contains(QString("autoconfigure")))
+ {
+ in_addr_t guess;
+ struct in_addr in;
+
+ guess = PICA_guess_listening_addr_ipv4();
+ in.s_addr = guess;
+ addr->lineEdit()->setText(QString("autoconfigured(%1)").arg(inet_ntoa(in)));
+
+#ifdef HAVE_LIBMINIUPNPC
+ if (cbEnableUPnP->isChecked() && PICA_is_reserved_addr_ipv4(guess))
+ {
+ int ret;
+ char public_ip[64];
+ ret = PICA_upnp_autoconfigure_ipv4(st.loadValue("direct_c2c.public_port", 2298).toInt(),
+ st.loadValue("direct_c2c.local_port", 2298).toInt(),
+ public_ip);
+
+ if (ret)
+ {
+ addr->lineEdit()->setText(QString("autoconfigured(%1)").arg(public_ip));
+ }
+ }
+#endif
+ }
publicPort->setValue(st.loadValue("direct_c2c.public_port", 2298).toInt());
localPort->setValue(st.loadValue("direct_c2c.local_port", 2298).toInt());
@@ -162,6 +206,10 @@ void SettingsDialog::storeSettings()
st.storeValue("direct_c2c.state", QString::number(c2c_state));
+#ifdef HAVE_LIBMINIUPNPC
+ st.storeValue("direct_c2c.upnp_enabled", cbEnableUPnP->isChecked() ? "1" : "0");
+#endif
+
st.storeValue("direct_c2c.public_addr", addr->lineEdit()->text());
st.storeValue("direct_c2c.public_port", QString::number(publicPort->value()));
st.storeValue("direct_c2c.local_port", QString::number(localPort->value()));
diff --git a/pica-client/dialogs/settingsdialog.h b/pica-client/dialogs/settingsdialog.h
index f0ab0cd..233fd3e 100644
--- a/pica-client/dialogs/settingsdialog.h
+++ b/pica-client/dialogs/settingsdialog.h
@@ -7,6 +7,7 @@
#include <QSpinBox>
#include <QRadioButton>
#include <QComboBox>
+#include <QCheckBox>
class SettingsDialog : public QDialog
{
@@ -23,6 +24,9 @@ private:
QRadioButton *rbDisableDirectConns;
QRadioButton *rbEnableOutgoingConns;
QRadioButton *rbEnableIncomingConns;
+#ifdef HAVE_LIBMINIUPNPC
+ QCheckBox *cbEnableUPnP;
+#endif
QComboBox *addr;
QSpinBox *publicPort;
diff --git a/pica-client/pica-client.pro b/pica-client/pica-client.pro
index ef9f9fd..205d215 100644
--- a/pica-client/pica-client.pro
+++ b/pica-client/pica-client.pro
@@ -38,7 +38,8 @@ SOURCES += main.cpp\
filetransfercontroller.cpp \
sound.cpp \
dialogs/settingsdialog.cpp \
- settings.cpp
+ settings.cpp \
+ ../PICA_netconf.c
HEADERS += mainwindow.h \
chatwindow.h \
@@ -70,10 +71,12 @@ HEADERS += mainwindow.h \
filetransfercontroller.h \
sound.h \
dialogs/settingsdialog.h \
- settings.h
+ settings.h \
+ ../PICA_netconf.h
DEFINES = PICA_MULTITHREADED
+DEFINES += HAVE_LIBMINIUPNPC
FORMS += mainwindow.ui
@@ -85,6 +88,4 @@ unix: PKGCONFIG += libssl
unix: CONFIG += link_pkgconfig
unix: PKGCONFIG += libcrypto
-
-
-
+unix|win32: LIBS += -lminiupnpc
diff --git a/pica-client/skynet.cpp b/pica-client/skynet.cpp
index 8e22635..d2abb64 100644
--- a/pica-client/skynet.cpp
+++ b/pica-client/skynet.cpp
@@ -11,6 +11,7 @@
#include "dhparam.h"
#include "askpassword.h"
#include "settings.h"
+#include "../PICA_netconf.h"
SkyNet::SkyNet()
: nodes(config_dbname), QObject(0)
@@ -345,9 +346,34 @@ void SkyNet::Join(Accounts::AccountRecord &accrec)
{
int pub_port = st.loadValue("direct_c2c.public_port", 2298).toInt();
int loc_port = st.loadValue("direct_c2c.local_port", 2298).toInt();
+ QString public_addr = st.loadValue("direct_c2c.public_addr", "autoconfigure").toString();
+
+ if (public_addr.contains("autoconfigure"))
+ {
+ in_addr_t guess;
+ struct in_addr in;
+
+ guess = PICA_guess_listening_addr_ipv4();
+ in.s_addr = guess;
+ public_addr = QString(inet_ntoa(in));
+#ifdef HAVE_LIBMINIUPNPC
+ if (st.loadValue("direct_c2c.upnp_enabled", 1).toBool() && PICA_is_reserved_addr_ipv4(guess))
+ {
+ int ret;
+ char public_ip[64];
+ ret = PICA_upnp_autoconfigure_ipv4(pub_port, loc_port, public_ip);
+
+ if (ret)
+ {
+ public_addr = QString(public_ip);
+ }
+ }
+#endif
+ emit StatusMsg(QString(tr("Using autoconfigured address %1 port %2 for incoming direct connections")).arg(public_addr).arg(pub_port), false);
+ }
int ret = PICA_new_listener(acc,
- st.loadValue("direct_c2c.public_addr", "0.0.0.0").toString().toAscii().constData(),
+ public_addr.toAscii().constData(),
pub_port,
loc_port, &listener);
if (ret != PICA_OK)