Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/meson.build b/meson.build
- index 8b0bd404..5233671e 100644
- --- a/meson.build
- +++ b/meson.build
- @@ -18,6 +18,8 @@ libgmodule_dep = dependency('gmodule-2.0')
- libcanberra_dep = dependency('libcanberra', version: '>= 0.22',
- required: get_option('libcanberra'))
- +miniupnpc_dep = dependency('miniupnpc', version: '>= 2.0.0',
- + required: get_option('miniupnpc'))
- dbus_glib_dep = dependency('dbus-glib-1', required: get_option('dbus'))
- global_deps = []
- @@ -183,6 +185,7 @@ if meson.version().version_compare('>= 0.53.0')
- 'Plugin Support': get_option('plugin'),
- 'DBus Support': dbus_glib_dep.found(),
- 'libcanberra': libcanberra_dep.found(),
- + 'miniupnpc': miniupnpc_dep.found(),
- }, section: 'Features')
- summary({
- diff --git a/meson_options.txt b/meson_options.txt
- index c2ca54a2..9527f3b1 100644
- --- a/meson_options.txt
- +++ b/meson_options.txt
- @@ -22,6 +22,9 @@ option('dbus', type: 'feature', value: 'auto',
- option('libcanberra', type: 'feature', value: 'auto',
- description: 'Support for sound alerts, Unix only'
- )
- +option('miniupnpc', type: 'feature', value: 'auto',
- + description: 'Support for DCC Universal Plug & Play, Unix only'
- +)
- # Install options
- option('dbus-service-use-appid', type: 'boolean', value: false,
- diff --git a/src/common/dcc.c b/src/common/dcc.c
- index df129e68..5e1091c1 100644
- --- a/src/common/dcc.c
- +++ b/src/common/dcc.c
- @@ -57,6 +57,7 @@
- #include "text.h"
- #include "url.h"
- #include "hexchatc.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,11 @@ dcc_connect_sok (struct DCC *dcc)
- static void
- dcc_close (struct DCC *dcc, enum dcc_state dccstat, int destroy)
- {
- + if (dcc->port > 0) // && dcc->pasvid ??
- + {
- + upnp_rem_redir (dcc->port);
- + }
- +
- if (dcc->wiotag)
- {
- fe_input_remove (dcc->wiotag);
- @@ -1660,6 +1666,8 @@ dcc_listen_init (struct DCC *dcc, session *sess)
- SAddr.sin_family = AF_INET;
- + /*printf("prefs.local_ip=%08x\n", prefs.local_ip);*/
- + /*printf("SAddr.sin_addr.s_addr=%s => ip interne\n", inet_ntoa(SAddr.sin_addr));*/
- /*if local_ip is specified use that*/
- if (prefs.local_ip != 0xffffffff)
- {
- @@ -1706,6 +1714,7 @@ dcc_listen_init (struct DCC *dcc, session *sess)
- getsockname (dcc->sok, (struct sockaddr *) &SAddr, &len);
- dcc->port = ntohs (SAddr.sin_port);
- + /*printf("dcc port = %d\n", dcc->port);*/
- /*if we have a dcc_ip, we use that, so the remote client can connect*/
- /*else we try to take an address from hex_dcc_ip*/
- @@ -1718,12 +1727,17 @@ dcc_listen_init (struct DCC *dcc, session *sess)
- dcc->addr = ntohl (dcc->addr);
- + /*printf("dcc_get_my_address=%s = ext ip\n", net_ip(dcc->addr));*/
- +
- set_nonblocking (dcc->sok);
- listen (dcc->sok, 1);
- set_blocking (dcc->sok);
- dcc->iotag = fe_input_add (dcc->sok, FIA_READ|FIA_EX, dcc_accept, dcc);
- + /* redirect port dcc->port => dcc->addr:dcc->port */
- + upnp_add_redir (inet_ntoa(SAddr.sin_addr), dcc->port);
- +
- return TRUE;
- }
- diff --git a/src/common/hexchat.c b/src/common/hexchat.c
- index 3ba7ed6d..e5b7a694 100644
- --- a/src/common/hexchat.c
- +++ b/src/common/hexchat.c
- @@ -52,6 +52,7 @@
- #include "text.h"
- #include "url.h"
- #include "hexchatc.h"
- +#include "upnp.h"
- #if ! GLIB_CHECK_VERSION (2, 36, 0)
- #include <glib-object.h> /* for g_type_init() */
- @@ -844,6 +845,7 @@ xchat_init (void)
- sound_load ();
- notify_load ();
- ignore_load ();
- + init_upnp ();
- g_snprintf (buf, sizeof (buf),
- "NAME %s~%s~\n" "CMD query %%s\n\n"\
- diff --git a/src/common/meson.build b/src/common/meson.build
- index 84e2fca3..23285fa9 100644
- --- a/src/common/meson.build
- +++ b/src/common/meson.build
- @@ -21,7 +21,8 @@ common_sources = [
- 'tree.c',
- 'url.c',
- 'userlist.c',
- - 'util.c'
- + 'util.c',
- + 'upnp.c'
- ]
- common_sysinfo_deps = []
- @@ -77,6 +78,11 @@ if libssl_dep.found()
- common_deps += libssl_dep
- endif
- +if miniupnpc_dep.found()
- + common_sources += 'upnp.c'
- + common_deps += miniupnpc_dep
- +endif
- +
- if dbus_glib_dep.found()
- subdir('dbus')
- common_deps += hexchat_dbus_dep
- diff --git a/src/common/upnp.c b/src/common/upnp.c
- new file mode 100644
- index 00000000..4d9ef357
- --- /dev/null
- +++ b/src/common/upnp.c
- @@ -0,0 +1,141 @@
- +/* upnp.c */
- +
- +/*
- +Adapted from XChat patches here: http://miniupnp.free.fr/ (c) Thomas Bernard
- +Changes to work in Hexchat (c) somercet at gmail, released under GPL 2.0
- +*/
- +
- +#include <stdio.h>
- +#include <string.h>
- +
- +#include "hexchat.h"
- +#include "network.h"
- +#include "upnp.h"
- +
- +#include <miniupnpc/miniwget.h>
- +#include <miniupnpc/miniupnpc.h>
- +#include <miniupnpc/upnpcommands.h>
- +
- +static struct UPNPUrls urls;
- +static struct IGDdatas data;
- +
- +void init_upnp (void)
- +{
- + struct UPNPDev * devlist;
- + struct UPNPDev * dev;
- + char * descXML;
- + int descXMLsize = 0;
- + unsigned char Ttl = 2;
- + int upnperror = 0, statusCode = 0;
- + printf("TB : init_upnp()\n");
- + memset(&urls, 0, sizeof(struct UPNPUrls));
- + memset(&data, 0, sizeof(struct IGDdatas));
- + devlist = upnpDiscover(
- + 2000,
- + NULL, /*multicast interface*/
- + NULL, /*minissdpd socket path*/
- + 0, /*sameport*/
- + 0, /*ipv6*/
- + Ttl, /* "miniupnpc.h: should default to 2 */
- + &upnperror);
- +
- +/*
- +upnpDiscover( int delay,
- + const char * multicastif,
- + const char * minissdpdsock,
- + int localport,
- + int ipv6,
- + unsigned char ttl,
- + int * error);
- +*/
- +
- +
- + if (devlist)
- + {
- + dev = devlist;
- + while (dev)
- + {
- + if (strstr (dev->st, "InternetGatewayDevice"))
- + break;
- + dev = dev->pNext;
- + }
- + if (!dev)
- + dev = devlist; /* defaulting to first device */
- +
- + printf("UPnP device :\n"
- + " desc: %s\n st: %s\n",
- + dev->descURL, dev->st);
- +
- + descXML = miniwget(dev->descURL, &descXMLsize, 1, &statusCode);
- +
- + /* miniupnpc-2.2.3/src/miniwget.c
- + scope is only for IPv6, say connecting from inside a link-local
- + network.
- +
- + IPv6 Services for UPnP Residential Networks draft-bnss-v6ops-upnp-01.txt
- +
- + status_code is "HTTP status code"
- + void *
- + miniwget(
- + const char * url,
- + int * size,
- + unsigned int scope_id,
- + int * status_code)
- + */
- +
- + if (descXML)
- + {
- + parserootdesc (descXML, descXMLsize, &data);
- + free (descXML); descXML = 0;
- + GetUPNPUrls (&urls, &data, dev->descURL, 1);
- + /* miniupnpc-2.2.3/src/miniupnpc.c build_absolute_url() calls
- + char *if_indextoname(unsigned int ifindex, char *ifname);
- + another IPv6 LL only thing
- +
- + MINIUPNP_LIBSPEC void
- + GetUPNPUrls(
- + struct UPNPUrls * urls,
- + struct IGDdatas * data,
- + const char * descURL,
- + unsigned int scope_id)
- + */
- + }
- + freeUPNPDevlist(devlist);
- + }
- + else
- + {
- + /* error ! */
- + }
- +}
- +
- +void upnp_add_redir (const char * addr, int port)
- +{
- + char port_str[16];
- + int r;
- + printf("TB : upnp_add_redir (%s, %d)\n", addr, port);
- + if(urls.controlURL[0] == '\0')
- + {
- + printf("TB : the init was not done !\n");
- + return;
- + }
- + sprintf(port_str, "%d", port);
- + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
- + port_str, port_str, addr, "xchat", "TCP", NULL, NULL);
- + if(r==0)
- + printf("AddPortMapping(%s, %s, %s) failed\n", port_str, port_str, addr);
- +}
- +
- +void upnp_rem_redir (int port)
- +{
- + char port_str[16];
- + //int t; // unused
- + printf("TB : upnp_rem_redir (%d)\n", port);
- + if(urls.controlURL[0] == '\0')
- + {
- + printf("TB : the init was not done !\n");
- + return;
- + }
- + sprintf(port_str, "%d", port);
- + UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port_str, "TCP", NULL);
- +}
- +
- diff --git a/src/common/upnp.h b/src/common/upnp.h
- new file mode 100644
- index 00000000..adb84989
- --- /dev/null
- +++ b/src/common/upnp.h
- @@ -0,0 +1,16 @@
- +/* upnp.h */
- +
- +/*
- +Adapted from XChat patches here: http://miniupnp.free.fr/ (c) Thomas Bernard
- +Changes to work in Hexchat (c) somercet at gmail, released under GPL 2.0
- +*/
- +
- +#ifndef XCHAT_UPNP_H
- +#define XCHAT_UPNP_H
- +
- +void init_upnp (void);
- +void upnp_add_redir (const char * addr, int port);
- +void upnp_rem_redir (int port);
- +
- +#endif
- +
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement