Add DCC passive-first + NAT mapping prefs

This commit is contained in:
2026-05-25 21:37:10 -06:00
parent fb491a6bb2
commit 92fe064e26
11 changed files with 155 additions and 2 deletions

View File

@@ -562,6 +562,7 @@ const struct prefs vars[] =
{"net_proxy_user", P_OFFSET (hex_net_proxy_user), TYPE_STR},
{"net_reconnect_delay", P_OFFINT (hex_net_reconnect_delay), TYPE_INT},
{"net_throttle", P_OFFINT (hex_net_throttle), TYPE_BOOL},
{"net_upnp", P_OFFINT (hex_net_upnp), TYPE_BOOL},
{"notify_timeout", P_OFFINT (hex_notify_timeout), TYPE_INT},
{"notify_whois_online", P_OFFINT (hex_notify_whois_online), TYPE_BOOL},
@@ -811,6 +812,7 @@ load_default_config(void)
prefs.hex_irc_whois_front = 1;
prefs.hex_net_auto_reconnect = 1;
prefs.hex_net_throttle = 1;
prefs.hex_net_upnp = 1;
prefs.hex_stamp_log = 1;
prefs.hex_stamp_text = 1;
prefs.hex_text_autocopy_text = 1;

View File

@@ -57,6 +57,7 @@
#include "text.h"
#include "url.h"
#include "zoitechatc.h"
#include "upnp.h"
/* Setting _FILE_OFFSET_BITS to 64 doesn't change lseek to use off64_t on Windows, so override lseek to the version that does */
#if defined(WIN32) && (!defined(__MINGW32__) && !defined(__MINGW64__))
@@ -371,6 +372,12 @@ dcc_connect_sok (struct DCC *dcc)
static void
dcc_close (struct DCC *dcc, enum dcc_state dccstat, int destroy)
{
if (dcc->port > 0)
{
if (prefs.hex_net_upnp)
upnp_rem_redir(dcc->port);
}
if (dcc->wiotag)
{
fe_input_remove (dcc->wiotag);
@@ -1711,6 +1718,8 @@ dcc_listen_init (struct DCC *dcc, session *sess)
set_blocking (dcc->sok);
dcc->iotag = fe_input_add (dcc->sok, FIA_READ|FIA_EX, dcc_accept, dcc);
if (prefs.hex_net_upnp)
upnp_add_redir(inet_ntoa(SAddr.sin_addr), dcc->port);
return TRUE;
}

View File

@@ -24,7 +24,8 @@ common_sources = [
'tree.c',
'url.c',
'userlist.c',
'util.c'
'util.c',
'upnp.c'
]
common_sysinfo_deps = []
@@ -115,6 +116,10 @@ if libssl_dep.found()
common_deps += libssl_dep
endif
if miniupnpc_dep.found()
common_deps += miniupnpc_dep
endif
if dbus_dep.found()
subdir('dbus')
common_deps += zoitechat_dbus_dep

111
src/common/upnp.c Normal file
View File

@@ -0,0 +1,111 @@
/*
* Copyright (C) Thomas Bernard
* Copyright (C) HexChat contributors
* Copyright (C) ZoiteChat contributors
*/
#include <stdio.h>
#include <string.h>
#include "upnp.h"
#ifdef USE_MINIUPNPC
#include <miniupnpc/miniupnpc.h>
#include <miniupnpc/upnpcommands.h>
#include <miniupnpc/upnperrors.h>
static struct UPNPUrls urls;
static struct IGDdatas data;
static int ready;
static char upnp_lanaddr[64];
void
upnp_init(void)
{
int err = 0;
int igd = 0;
char lanaddr[64] = {0};
struct UPNPDev *devlist;
memset(&urls, 0, sizeof(urls));
memset(&data, 0, sizeof(data));
ready = 0;
upnp_lanaddr[0] = 0;
devlist = upnpDiscover(2000, NULL, NULL, 0, 0, 2, &err);
if (!devlist)
devlist = upnpDiscover(2000, NULL, NULL, 0, 1, 2, &err);
if (!devlist)
return;
igd = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
if (igd == 1 || igd == 2 || igd == 3)
{
ready = 1;
snprintf(upnp_lanaddr, sizeof(upnp_lanaddr), "%s", lanaddr);
}
freeUPNPDevlist(devlist);
}
void
upnp_add_redir(const char *addr, int port)
{
char port_str[16];
const char *map_addr;
int r;
if (!ready)
upnp_init();
if (!ready)
return;
map_addr = upnp_lanaddr[0] ? upnp_lanaddr : addr;
if (!map_addr || !map_addr[0])
return;
snprintf(port_str, sizeof(port_str), "%d", port);
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
port_str, port_str, NULL, "zoitechat", "TCP", NULL, NULL);
if (r != UPNPCOMMAND_SUCCESS)
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
port_str, port_str, map_addr, "zoitechat", "TCP", NULL, NULL);
if (r != UPNPCOMMAND_SUCCESS)
return;
}
void
upnp_rem_redir(int port)
{
char port_str[16];
if (!ready)
upnp_init();
if (!ready)
return;
snprintf(port_str, sizeof(port_str), "%d", port);
UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port_str, "TCP", NULL);
}
#else
void
upnp_init(void)
{
}
void
upnp_add_redir(const char *addr, int port)
{
(void)addr;
(void)port;
}
void
upnp_rem_redir(int port)
{
(void)port;
}
#endif

14
src/common/upnp.h Normal file
View File

@@ -0,0 +1,14 @@
/*
* Copyright (C) Thomas Bernard
* Copyright (C) HexChat contributors
* Copyright (C) ZoiteChat contributors
*/
#ifndef ZOITECHAT_UPNP_H
#define ZOITECHAT_UPNP_H
void upnp_init(void);
void upnp_add_redir(const char *addr, int port);
void upnp_rem_redir(int port);
#endif

View File

@@ -54,6 +54,7 @@
#include "text.h"
#include "url.h"
#include "zoitechatc.h"
#include "upnp.h"
#if ! GLIB_CHECK_VERSION (2, 36, 0)
#include <glib-object.h> /* for g_type_init() */
@@ -961,6 +962,8 @@ xchat_init (void)
sound_load ();
notify_load ();
ignore_load ();
if (prefs.hex_net_upnp)
upnp_init ();
sts_init ();
g_snprintf (buf, sizeof (buf),

View File

@@ -202,6 +202,7 @@ struct zoitechatprefs
unsigned int hex_net_auto_reconnectonfail;
unsigned int hex_net_proxy_auth;
unsigned int hex_net_throttle;
unsigned int hex_net_upnp;
unsigned int hex_notify_whois_online;
unsigned int hex_perl_warnings;
unsigned int hex_stamp_log;