Skip to content

Commit 02ccf69

Browse files
committed
refactor: Move port mapping code to its own module
This commit does not change behavior.
1 parent 4b8b71e commit 02ccf69

File tree

8 files changed

+163
-135
lines changed

8 files changed

+163
-135
lines changed

src/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ BITCOIN_CORE_H = \
152152
key_io.h \
153153
logging.h \
154154
logging/timer.h \
155+
mapport.h \
155156
memusage.h \
156157
merkleblock.h \
157158
miner.h \
@@ -299,6 +300,7 @@ libbitcoin_server_a_SOURCES = \
299300
index/blockfilterindex.cpp \
300301
index/txindex.cpp \
301302
init.cpp \
303+
mapport.cpp \
302304
miner.cpp \
303305
net.cpp \
304306
net_processing.cpp \

src/init.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <interfaces/chain.h>
2727
#include <interfaces/node.h>
2828
#include <key.h>
29+
#include <mapport.h>
2930
#include <miner.h>
3031
#include <net.h>
3132
#include <net_permissions.h>

src/mapport.cpp

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Copyright (c) 2011-2020 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#if defined(HAVE_CONFIG_H)
6+
#include <config/bitcoin-config.h>
7+
#endif
8+
9+
#include <mapport.h>
10+
11+
#include <clientversion.h>
12+
#include <logging.h>
13+
#include <net.h>
14+
#include <netaddress.h>
15+
#include <netbase.h>
16+
#include <threadinterrupt.h>
17+
#include <util/system.h>
18+
19+
#ifdef USE_UPNP
20+
#include <miniupnpc/miniupnpc.h>
21+
#include <miniupnpc/upnpcommands.h>
22+
#include <miniupnpc/upnperrors.h>
23+
// The minimum supported miniUPnPc API version is set to 10. This keeps compatibility
24+
// with Ubuntu 16.04 LTS and Debian 8 libminiupnpc-dev packages.
25+
static_assert(MINIUPNPC_API_VERSION >= 10, "miniUPnPc API version >= 10 assumed");
26+
#endif
27+
28+
#include <cassert>
29+
#include <chrono>
30+
#include <functional>
31+
#include <string>
32+
#include <thread>
33+
34+
#ifdef USE_UPNP
35+
static CThreadInterrupt g_upnp_interrupt;
36+
static std::thread g_upnp_thread;
37+
static void ThreadMapPort()
38+
{
39+
std::string port = strprintf("%u", GetListenPort());
40+
const char * multicastif = nullptr;
41+
const char * minissdpdpath = nullptr;
42+
struct UPNPDev * devlist = nullptr;
43+
char lanaddr[64];
44+
45+
int error = 0;
46+
#if MINIUPNPC_API_VERSION < 14
47+
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
48+
#else
49+
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
50+
#endif
51+
52+
struct UPNPUrls urls;
53+
struct IGDdatas data;
54+
int r;
55+
56+
r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
57+
if (r == 1)
58+
{
59+
if (fDiscover) {
60+
char externalIPAddress[40];
61+
r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
62+
if (r != UPNPCOMMAND_SUCCESS) {
63+
LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
64+
} else {
65+
if (externalIPAddress[0]) {
66+
CNetAddr resolved;
67+
if (LookupHost(externalIPAddress, resolved, false)) {
68+
LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved.ToString());
69+
AddLocal(resolved, LOCAL_UPNP);
70+
}
71+
} else {
72+
LogPrintf("UPnP: GetExternalIPAddress failed.\n");
73+
}
74+
}
75+
}
76+
77+
std::string strDesc = PACKAGE_NAME " " + FormatFullVersion();
78+
79+
do {
80+
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
81+
82+
if (r != UPNPCOMMAND_SUCCESS) {
83+
LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", port, port, lanaddr, r, strupnperror(r));
84+
} else {
85+
LogPrintf("UPnP Port Mapping successful.\n");
86+
}
87+
} while (g_upnp_interrupt.sleep_for(std::chrono::minutes(20)));
88+
89+
r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
90+
LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r);
91+
freeUPNPDevlist(devlist); devlist = nullptr;
92+
FreeUPNPUrls(&urls);
93+
} else {
94+
LogPrintf("No valid UPnP IGDs found\n");
95+
freeUPNPDevlist(devlist); devlist = nullptr;
96+
if (r != 0)
97+
FreeUPNPUrls(&urls);
98+
}
99+
}
100+
101+
void StartMapPort()
102+
{
103+
if (!g_upnp_thread.joinable()) {
104+
assert(!g_upnp_interrupt);
105+
g_upnp_thread = std::thread((std::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort)));
106+
}
107+
}
108+
109+
void InterruptMapPort()
110+
{
111+
if(g_upnp_thread.joinable()) {
112+
g_upnp_interrupt();
113+
}
114+
}
115+
116+
void StopMapPort()
117+
{
118+
if(g_upnp_thread.joinable()) {
119+
g_upnp_thread.join();
120+
g_upnp_interrupt.reset();
121+
}
122+
}
123+
124+
#else
125+
void StartMapPort()
126+
{
127+
// Intentionally left blank.
128+
}
129+
void InterruptMapPort()
130+
{
131+
// Intentionally left blank.
132+
}
133+
void StopMapPort()
134+
{
135+
// Intentionally left blank.
136+
}
137+
#endif

src/mapport.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) 2011-2020 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_MAPPORT_H
6+
#define BITCOIN_MAPPORT_H
7+
8+
/** -upnp default */
9+
#ifdef USE_UPNP
10+
static const bool DEFAULT_UPNP = USE_UPNP;
11+
#else
12+
static const bool DEFAULT_UPNP = false;
13+
#endif
14+
15+
void StartMapPort();
16+
void InterruptMapPort();
17+
void StopMapPort();
18+
19+
#endif // BITCOIN_MAPPORT_H

src/net.cpp

Lines changed: 0 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,6 @@
3333
#include <poll.h>
3434
#endif
3535

36-
#ifdef USE_UPNP
37-
#include <miniupnpc/miniupnpc.h>
38-
#include <miniupnpc/upnpcommands.h>
39-
#include <miniupnpc/upnperrors.h>
40-
// The minimum supported miniUPnPc API version is set to 10. This keeps compatibility
41-
// with Ubuntu 16.04 LTS and Debian 8 libminiupnpc-dev packages.
42-
static_assert(MINIUPNPC_API_VERSION >= 10, "miniUPnPc API version >= 10 assumed");
43-
#endif
44-
4536
#include <algorithm>
4637
#include <cstdint>
4738
#include <unordered_map>
@@ -1539,121 +1530,6 @@ void CConnman::WakeMessageHandler()
15391530
condMsgProc.notify_one();
15401531
}
15411532

1542-
1543-
1544-
1545-
1546-
1547-
#ifdef USE_UPNP
1548-
static CThreadInterrupt g_upnp_interrupt;
1549-
static std::thread g_upnp_thread;
1550-
static void ThreadMapPort()
1551-
{
1552-
std::string port = strprintf("%u", GetListenPort());
1553-
const char * multicastif = nullptr;
1554-
const char * minissdpdpath = nullptr;
1555-
struct UPNPDev * devlist = nullptr;
1556-
char lanaddr[64];
1557-
1558-
int error = 0;
1559-
#if MINIUPNPC_API_VERSION < 14
1560-
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1561-
#else
1562-
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
1563-
#endif
1564-
1565-
struct UPNPUrls urls;
1566-
struct IGDdatas data;
1567-
int r;
1568-
1569-
r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1570-
if (r == 1)
1571-
{
1572-
if (fDiscover) {
1573-
char externalIPAddress[40];
1574-
r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1575-
if (r != UPNPCOMMAND_SUCCESS) {
1576-
LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
1577-
} else {
1578-
if (externalIPAddress[0]) {
1579-
CNetAddr resolved;
1580-
if (LookupHost(externalIPAddress, resolved, false)) {
1581-
LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved.ToString());
1582-
AddLocal(resolved, LOCAL_UPNP);
1583-
}
1584-
} else {
1585-
LogPrintf("UPnP: GetExternalIPAddress failed.\n");
1586-
}
1587-
}
1588-
}
1589-
1590-
std::string strDesc = PACKAGE_NAME " " + FormatFullVersion();
1591-
1592-
do {
1593-
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
1594-
1595-
if (r != UPNPCOMMAND_SUCCESS) {
1596-
LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", port, port, lanaddr, r, strupnperror(r));
1597-
} else {
1598-
LogPrintf("UPnP Port Mapping successful.\n");
1599-
}
1600-
} while (g_upnp_interrupt.sleep_for(std::chrono::minutes(20)));
1601-
1602-
r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
1603-
LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r);
1604-
freeUPNPDevlist(devlist); devlist = nullptr;
1605-
FreeUPNPUrls(&urls);
1606-
} else {
1607-
LogPrintf("No valid UPnP IGDs found\n");
1608-
freeUPNPDevlist(devlist); devlist = nullptr;
1609-
if (r != 0)
1610-
FreeUPNPUrls(&urls);
1611-
}
1612-
}
1613-
1614-
void StartMapPort()
1615-
{
1616-
if (!g_upnp_thread.joinable()) {
1617-
assert(!g_upnp_interrupt);
1618-
g_upnp_thread = std::thread((std::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort)));
1619-
}
1620-
}
1621-
1622-
void InterruptMapPort()
1623-
{
1624-
if(g_upnp_thread.joinable()) {
1625-
g_upnp_interrupt();
1626-
}
1627-
}
1628-
1629-
void StopMapPort()
1630-
{
1631-
if(g_upnp_thread.joinable()) {
1632-
g_upnp_thread.join();
1633-
g_upnp_interrupt.reset();
1634-
}
1635-
}
1636-
1637-
#else
1638-
void StartMapPort()
1639-
{
1640-
// Intentionally left blank.
1641-
}
1642-
void InterruptMapPort()
1643-
{
1644-
// Intentionally left blank.
1645-
}
1646-
void StopMapPort()
1647-
{
1648-
// Intentionally left blank.
1649-
}
1650-
#endif
1651-
1652-
1653-
1654-
1655-
1656-
16571533
void CConnman::ThreadDNSAddressSeed()
16581534
{
16591535
FastRandomContext rng;

src/net.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,6 @@ static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS = 2;
6767
static const int MAX_FEELER_CONNECTIONS = 1;
6868
/** -listen default */
6969
static const bool DEFAULT_LISTEN = true;
70-
/** -upnp default */
71-
#ifdef USE_UPNP
72-
static const bool DEFAULT_UPNP = USE_UPNP;
73-
#else
74-
static const bool DEFAULT_UPNP = false;
75-
#endif
7670
/** The maximum number of peer connections to maintain. */
7771
static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
7872
/** The default for -maxuploadtarget. 0 = Unlimited */
@@ -181,9 +175,6 @@ enum class ConnectionType {
181175
};
182176

183177
void Discover();
184-
void StartMapPort();
185-
void InterruptMapPort();
186-
void StopMapPort();
187178
uint16_t GetListenPort();
188179

189180
enum

src/node/interfaces.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <interfaces/handler.h>
1313
#include <interfaces/node.h>
1414
#include <interfaces/wallet.h>
15+
#include <mapport.h>
1516
#include <net.h>
1617
#include <net_processing.h>
1718
#include <netaddress.h>

src/qt/optionsmodel.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@
1313
#include <qt/guiutil.h>
1414

1515
#include <interfaces/node.h>
16-
#include <validation.h> // For DEFAULT_SCRIPTCHECK_THREADS
16+
#include <mapport.h>
1717
#include <net.h>
1818
#include <netbase.h>
19-
#include <txdb.h> // for -dbcache defaults
19+
#include <txdb.h> // for -dbcache defaults
2020
#include <util/string.h>
21+
#include <validation.h> // For DEFAULT_SCRIPTCHECK_THREADS
2122

2223
#include <QDebug>
2324
#include <QSettings>

0 commit comments

Comments
 (0)