Add Tomato modifications exactly as is, wrapped by ifdef TOMATO

Add Tomato modifications exactly as is in Tomato firmware, wrapped by #ifdef TOMATO so that it is dormant in base miniupnpd.
This will ease merging upstream changes back to Tomato.
This commit is contained in:
edrikk 2015-06-05 23:19:52 -04:00
parent 9fe747894c
commit ec0707d559
1 changed files with 205 additions and 0 deletions

View File

@ -49,6 +49,7 @@
#include <sys/un.h>
#endif
#include <sys/stat.h>
#include "macros.h"
#include "upnpglobalvars.h"
#include "upnphttp.h"
@ -109,6 +110,181 @@ int get_udp_dst_port (char *payload);
static volatile sig_atomic_t quitting = 0;
volatile sig_atomic_t should_send_public_address_change_notif = 0;
#ifdef TOMATO
#if 1
/* Tomato specific code */
static volatile int gotusr2 = 0;
static void
sigusr2(int sig)
{
gotusr2 = 1;
}
static void
tomato_save(const char *fname)
{
unsigned short eport;
unsigned short iport;
unsigned int leaseduration;
unsigned int timestamp;
char proto[4];
char iaddr[32];
char desc[64];
char rhost[32];
int n;
FILE *f;
int t;
char tmp[128];
strcpy(tmp, "/etc/upnp/saveXXXXXX");
if ((t = mkstemp(tmp)) != -1)
{
if ((f = fdopen(t, "w")) != NULL)
{
n = 0;
while (upnp_get_redirection_infos_by_index(n, &eport, proto, &iport, iaddr, sizeof(iaddr), desc, sizeof(desc), rhost, sizeof(rhost), &leaseduration) == 0)
{
timestamp = (leaseduration > 0) ? time(NULL) + leaseduration : 0;
fprintf(f, "%s %u %s %u [%s] %u\n", proto, eport, iaddr, iport, desc, timestamp);
++n;
}
fclose(f);
rename(tmp, fname);
}
else
{
close(t);
}
unlink(tmp);
}
}
static void
tomato_load(void)
{
FILE *f;
char s[256];
unsigned short eport;
unsigned short iport;
unsigned int leaseduration;
unsigned int timestamp;
time_t current_time;
char proto[4];
char iaddr[32];
char *rhost;
char *a, *b;
if ((f = fopen("/etc/upnp/data", "r")) != NULL)
{
current_time = time(NULL);
s[sizeof(s) - 1] = 0;
while (fgets(s, sizeof(s) - 1, f)) {
if (sscanf(s, "%3s %hu %31s %hu [%*s] %u", proto, &eport, iaddr, &iport, &timestamp) >= 4)
{
if (((a = strchr(s, '[')) != NULL) && ((b = strrchr(a, ']')) != NULL))
{
if (timestamp > 0)
{
if (timestamp > current_time)
leaseduration = current_time - timestamp;
else
continue;
}
else
{
leaseduration = 0; /* default value */
}
*b = 0;
rhost = NULL;
upnp_redirect(rhost, eport, iaddr, iport, proto, a + 1, leaseduration);
}
}
}
fclose(f);
}
#ifdef ENABLE_NATPMP
#if 0
ScanNATPMPforExpiration();
#endif
#endif
unlink("/etc/upnp/load");
}
static void
tomato_delete(void)
{
FILE *f;
char s[128];
unsigned short eport;
unsigned short iport;
unsigned int leaseduration;
char proto[4];
char iaddr[32];
char desc[64];
char rhost[32];
int n;
if ((f = fopen("/etc/upnp/delete", "r")) != NULL)
{
s[sizeof(s) - 1] = 0;
while (fgets(s, sizeof(s) - 1, f))
{
if (sscanf(s, "%3s %hu", proto, &eport) == 2)
{
if (proto[0] == '*')
{
n = upnp_get_portmapping_number_of_entries();
while (--n >= 0)
{
if (upnp_get_redirection_infos_by_index(n, &eport, proto, &iport, iaddr, sizeof(iaddr), desc, sizeof(desc), rhost, sizeof(rhost), &leaseduration) == 0)
{
upnp_delete_redirection(eport, proto);
}
}
break;
}
else
{
upnp_delete_redirection(eport, proto);
}
}
}
fclose(f);
unlink("/etc/upnp/delete");
}
}
static void
tomato_helper(void)
{
struct stat st;
if (stat("/etc/upnp/delete", &st) == 0)
{
tomato_delete();
}
if (stat("/etc/upnp/load", &st) == 0)
{
tomato_load();
}
if (stat("/etc/upnp/save", &st) == 0)
{
tomato_save("/etc/upnp/data");
unlink("/etc/upnp/save");
}
if (stat("/etc/upnp/info", &st) == 0)
{
tomato_save("/etc/upnp/data.info");
unlink("/etc/upnp/info");
}
}
#endif /* 1 (tomato) */
#endif /* TOMATO */
/* OpenAndConfHTTPSocket() :
* setup the socket used to handle incoming HTTP connections. */
static int
@ -1412,6 +1588,10 @@ init(int argc, char * * argv, struct runtime_vars * v)
syslog(LOG_ERR, "MiniUPnPd is already running. EXITING");
return 1;
}
#ifdef TOMATO
syslog(LOG_NOTICE, "version " MINIUPNPD_VERSION " started");
#endif
set_startup_time(GETFLAG(SYSUPTIMEMASK));
@ -1442,8 +1622,14 @@ init(int argc, char * * argv, struct runtime_vars * v)
syslog(LOG_ERR, "Failed to set %s handler. EXITING", "SIGINT");
return 1;
}
#ifdef TOMATO
sa.sa_handler = sigusr2;
sigaction(SIGUSR2, &sa, NULL);
if(signal(SIGPIPE, SIG_IGN) == SIG_ERR)
#else
sa.sa_handler = SIG_IGN;
if(sigaction(SIGPIPE, &sa, NULL) < 0)
#endif
{
syslog(LOG_ERR, "Failed to ignore SIGPIPE signals");
}
@ -1477,6 +1663,10 @@ init(int argc, char * * argv, struct runtime_vars * v)
reload_from_lease_file();
#endif
#ifdef TOMATO
tomato_load();
#endif
return 0;
print_usage:
fprintf(stderr, "Usage:\n\t"
@ -1810,6 +2000,10 @@ main(int argc, char * * argv)
}
#endif
#ifdef TOMATO
tomato_helper();
#endif
/* main loop */
while(!quitting)
{
@ -2064,6 +2258,14 @@ main(int argc, char * * argv)
if(select(max_fd+1, &readset, &writeset, 0, &timeout) < 0)
{
if(quitting) goto shutdown;
#ifdef TOMATO
if (gotusr2)
{
gotusr2 = 0;
tomato_helper();
continue;
}
#endif
if(errno == EINTR) continue; /* interrupted by a signal, start again */
syslog(LOG_ERR, "select(all): %m");
syslog(LOG_ERR, "Failed to select open sockets. EXITING");
@ -2349,6 +2551,9 @@ shutdown:
/* try to send pending packets */
finalize_sendto();
#ifdef TOMATO
tomato_save("/etc/upnp/data");
#endif
/* close out open sockets */
while(upnphttphead.lh_first != NULL)
{