diff options
| author | Anton <anton@picapica> | 2017-12-30 21:06:08 +0400 |
|---|---|---|
| committer | Anton <anton@picapica> | 2017-12-30 21:06:08 +0400 |
| commit | fe90bf0b2eb78f74836b6ab7832aa06e6d48b673 (patch) | |
| tree | 206e168819d1dde81d29d8e11ab22c33646de0de | |
| parent | 87c68a2ecadee7c86d80b585a2ed47b352c7b2d6 (diff) | |
| download | pica-pica-fe90bf0b2eb78f74836b6ab7832aa06e6d48b673.tar.gz pica-pica-fe90bf0b2eb78f74836b6ab7832aa06e6d48b673.zip | |
pica-client: implemented autoconfiguration of address for direct incoming connections
| -rw-r--r-- | Makefile.am | 3 | ||||
| -rw-r--r-- | PICA_netconf.h | 9 | ||||
| -rw-r--r-- | pica-client/dialogs/settingsdialog.cpp | 50 | ||||
| -rw-r--r-- | pica-client/dialogs/settingsdialog.h | 4 | ||||
| -rw-r--r-- | pica-client/pica-client.pro | 11 | ||||
| -rw-r--r-- | pica-client/skynet.cpp | 28 |
6 files changed, 97 insertions, 8 deletions
diff --git a/Makefile.am b/Makefile.am index ec75613..c60d6b1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -111,7 +111,8 @@ PICA_client.h \ PICA_msgproc.c \ PICA_msgproc.h \ PICA_common.h PICA_proto.h \ -PICA_id.c PICA_id.h +PICA_id.c PICA_id.h \ +PICA_netconf.c PICA_netconf.h nodist_pica_client_pica_client_SOURCES = \ moc_accountswindow.cpp \ diff --git a/PICA_netconf.h b/PICA_netconf.h index 13b4044..8e779b6 100644 --- a/PICA_netconf.h +++ b/PICA_netconf.h @@ -4,6 +4,7 @@ #ifndef WIN32 #include <netinet/in.h> +#include <arpa/inet.h> #else @@ -19,6 +20,10 @@ typedef u_long in_addr_t; typedef u_short in_port_t; #endif +#ifdef __cplusplus +extern "C" { +#endif + int PICA_is_reserved_addr_ipv4(in_addr_t); in_addr_t PICA_guess_listening_addr_ipv4(); @@ -27,5 +32,9 @@ in_addr_t PICA_guess_listening_addr_ipv4(); int PICA_upnp_autoconfigure_ipv4(int public_port, int local_port, char *public_ip); #endif +#ifdef __cplusplus +} +#endif + #endif 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) |
