miniupnpd: use monotonic clock for timeouts, etc.

fixes #288

also changed set_startup_time()
This commit is contained in:
Thomas Bernard 2018-03-13 11:43:07 +01:00
parent 2d783f6e69
commit dd2aa84204
12 changed files with 112 additions and 65 deletions

View File

@ -1,4 +1,7 @@
$Id: Changelog.txt,v 1.432 2017/05/24 22:47:53 nanard Exp $ $Id: Changelog.txt,v 1.437 2018/03/12 22:45:13 nanard Exp $
2018/03/13:
Use monotonic clock for timeouts, etc.
2018/02/22: 2018/02/22:
Add option force_igd_desc_v1 to force devices and services versions Add option force_igd_desc_v1 to force devices and services versions

View File

@ -1,4 +1,4 @@
/* $Id: miniupnpd.c,v 1.221 2017/05/27 07:47:55 nanard Exp $ */ /* $Id: miniupnpd.c,v 1.226 2018/03/13 10:35:55 nanard Exp $ */
/* vim: tabstop=4 shiftwidth=4 noexpandtab /* vim: tabstop=4 shiftwidth=4 noexpandtab
* MiniUPnP project * MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
@ -794,43 +794,39 @@ sigusr1(int sig)
/* record the startup time, for returning uptime */ /* record the startup time, for returning uptime */
static void static void
set_startup_time(int sysuptime) set_startup_time(void)
{ {
startup_time = time(NULL); startup_time = upnp_time();
#ifdef USE_TIME_AS_BOOTID #ifdef USE_TIME_AS_BOOTID
if(startup_time > 60*60*24 && upnp_bootid == 1) { if(upnp_bootid == 1) {
/* We know we are not January the 1st 1970 */ upnp_bootid = (unsigned int)time(NULL);
upnp_bootid = (unsigned int)startup_time;
/* from UDA v1.1 : /* from UDA v1.1 :
* A convenient mechanism is to set this field value to the time * A convenient mechanism is to set this field value to the time
* that the device sends its initial announcement, expressed as * that the device sends its initial announcement, expressed as
* seconds elapsed since midnight January 1, 1970; */ * seconds elapsed since midnight January 1, 1970; */
} }
#endif /* USE_TIME_AS_BOOTID */ #endif /* USE_TIME_AS_BOOTID */
if(sysuptime) if(GETFLAG(SYSUPTIMEMASK))
{ {
/* use system uptime instead of daemon uptime */ /* use system uptime instead of daemon uptime */
#if defined(__linux__) #if defined(__linux__)
char buff[64]; unsigned long uptime = 0;
int uptime = 0, fd; FILE * f = fopen("/proc/uptime", "r");
fd = open("/proc/uptime", O_RDONLY); if(f == NULL)
if(fd < 0)
{ {
syslog(LOG_ERR, "open(\"/proc/uptime\" : %m"); syslog(LOG_ERR, "fopen(\"/proc/uptime\") : %m");
} }
else else
{ {
memset(buff, 0, sizeof(buff)); if(fscanf(f, "%lu", &uptime) != 1)
if(read(fd, buff, sizeof(buff) - 1) < 0)
{ {
syslog(LOG_ERR, "read(\"/proc/uptime\" : %m"); syslog(LOG_ERR, "fscanf(\"/proc/uptime\") : %m");
} }
else else
{ {
uptime = atoi(buff); syslog(LOG_INFO, "system uptime is %lu seconds", uptime);
syslog(LOG_INFO, "system uptime is %d seconds", uptime);
} }
close(fd); fclose(f);
startup_time -= uptime; startup_time -= uptime;
} }
#elif defined(SOLARIS_KSTATS) #elif defined(SOLARIS_KSTATS)
@ -1632,7 +1628,7 @@ init(int argc, char * * argv, struct runtime_vars * v)
syslog(LOG_NOTICE, "version " MINIUPNPD_VERSION " started"); syslog(LOG_NOTICE, "version " MINIUPNPD_VERSION " started");
#endif /* TOMATO */ #endif /* TOMATO */
set_startup_time(GETFLAG(SYSUPTIMEMASK)); set_startup_time();
/* presentation url */ /* presentation url */
if(presurl) if(presurl)
@ -2063,11 +2059,13 @@ main(int argc, char * * argv)
/* main loop */ /* main loop */
while(!quitting) while(!quitting)
{ {
#ifdef USE_TIME_AS_BOOTID
/* Correct startup_time if it was set with a RTC close to 0 */ /* Correct startup_time if it was set with a RTC close to 0 */
if((startup_time<60*60*24) && (time(NULL)>60*60*24)) if((upnp_bootid<60*60*24) && (time(NULL)>60*60*24))
{ {
set_startup_time(GETFLAG(SYSUPTIMEMASK)); upnp_bootid = time(NULL);
} }
#endif
/* send public address change notifications if needed */ /* send public address change notifications if needed */
if(should_send_public_address_change_notif) if(should_send_public_address_change_notif)
{ {

View File

@ -1,4 +1,4 @@
/* $Id: natpmp.c,v 1.52 2015/05/27 12:43:14 nanard Exp $ */ /* $Id: natpmp.c,v 1.55 2018/03/12 22:41:54 nanard Exp $ */
/* MiniUPnP project /* MiniUPnP project
* (c) 2007-2017 Thomas Bernard * (c) 2007-2017 Thomas Bernard
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
@ -247,7 +247,7 @@ void ProcessIncomingNATPMPPacket(int s, unsigned char *msg_buff, int len,
if(epoch_origin == 0) { if(epoch_origin == 0) {
epoch_origin = startup_time; epoch_origin = startup_time;
} }
WRITENU32(resp+4, time(NULL) - epoch_origin); WRITENU32(resp+4, upnp_time() - epoch_origin);
if(req[0] > 0) { if(req[0] > 0) {
/* invalid version */ /* invalid version */
syslog(LOG_WARNING, "unsupported NAT-PMP version : %u", syslog(LOG_WARNING, "unsupported NAT-PMP version : %u",
@ -382,15 +382,9 @@ void ProcessIncomingNATPMPPacket(int s, unsigned char *msg_buff, int len,
} }
} }
/* do the redirection */ /* do the redirection */
#if 0 timestamp = upnp_time() + lifetime;
timestamp = (unsigned)(time(NULL) - startup_time)
+ lifetime;
snprintf(desc, sizeof(desc), "NAT-PMP %u", timestamp);
#else
timestamp = time(NULL) + lifetime;
snprintf(desc, sizeof(desc), "NAT-PMP %hu %s", snprintf(desc, sizeof(desc), "NAT-PMP %hu %s",
eport, (proto==IPPROTO_TCP)?"tcp":"udp"); eport, (proto==IPPROTO_TCP)?"tcp":"udp");
#endif
/* TODO : check return code */ /* TODO : check return code */
if(upnp_redirect_internal(NULL, eport, senderaddrstr, if(upnp_redirect_internal(NULL, eport, senderaddrstr,
iport, proto, desc, iport, proto, desc,
@ -439,7 +433,7 @@ void SendNATPMPPublicAddressChangeNotification(int * sockets, int n_sockets)
if(epoch_origin == 0) { if(epoch_origin == 0) {
epoch_origin = startup_time; epoch_origin = startup_time;
} }
WRITENU32(notif+4, time(NULL) - epoch_origin); WRITENU32(notif+4, upnp_time() - epoch_origin);
#ifndef MULTIPLE_EXTERNAL_IP #ifndef MULTIPLE_EXTERNAL_IP
FillPublicAddressResponse(notif, 0); FillPublicAddressResponse(notif, 0);
if(notif[3]) if(notif[3])

View File

@ -1,4 +1,4 @@
/* $Id: pcpserver.c,v 1.39 2015/06/22 07:28:21 nanard Exp $ */ /* $Id: pcpserver.c,v 1.47 2018/03/13 10:21:19 nanard Exp $ */
/* MiniUPnP project /* MiniUPnP project
* Website : http://miniupnp.free.fr/ * Website : http://miniupnp.free.fr/
* Author : Peter Tatrai * Author : Peter Tatrai
@ -684,7 +684,7 @@ static int CreatePCPPeer_NAT(pcp_info_t *pcp_msg_info)
uint16_t eport = pcp_msg_info->ext_port; /* public port */ uint16_t eport = pcp_msg_info->ext_port; /* public port */
char peerip_s[INET6_ADDRSTRLEN], extip_s[INET6_ADDRSTRLEN]; char peerip_s[INET6_ADDRSTRLEN], extip_s[INET6_ADDRSTRLEN];
time_t timestamp = time(NULL) + pcp_msg_info->lifetime; time_t timestamp = upnp_time() + pcp_msg_info->lifetime;
int r; int r;
FillSA((struct sockaddr*)&intip, pcp_msg_info->mapped_ip, FillSA((struct sockaddr*)&intip, pcp_msg_info->mapped_ip,
@ -890,7 +890,7 @@ static int CreatePCPMap_NAT(pcp_info_t *pcp_msg_info)
char iaddr_old[INET6_ADDRSTRLEN]; char iaddr_old[INET6_ADDRSTRLEN];
uint16_t iport_old, eport_first = 0; uint16_t iport_old, eport_first = 0;
int any_eport_allowed = 0; int any_eport_allowed = 0;
unsigned int timestamp = time(NULL) + pcp_msg_info->lifetime; unsigned int timestamp = upnp_time() + pcp_msg_info->lifetime;
if (pcp_msg_info->ext_port == 0) { if (pcp_msg_info->ext_port == 0) {
pcp_msg_info->ext_port = pcp_msg_info->int_port; pcp_msg_info->ext_port = pcp_msg_info->int_port;
@ -1450,7 +1450,7 @@ static void createPCPResponse(unsigned char *response, pcp_info_t *pcp_msg_info)
if(epoch_origin == 0) { if(epoch_origin == 0) {
epoch_origin = startup_time; epoch_origin = startup_time;
} }
WRITENU32(response + 8, time(NULL) - epoch_origin); /* epochtime */ WRITENU32(response + 8, upnp_time() - epoch_origin); /* epochtime */
switch (pcp_msg_info->result_code) { switch (pcp_msg_info->result_code) {
/*long lifetime errors*/ /*long lifetime errors*/
case PCP_ERR_UNSUPP_VERSION: case PCP_ERR_UNSUPP_VERSION:
@ -1690,7 +1690,7 @@ void PCPPublicAddressChanged(int * sockets, int n_sockets)
/* according to RFC 6887 8.5 : /* according to RFC 6887 8.5 :
* if the external IP address(es) of the NAT (controlled by * if the external IP address(es) of the NAT (controlled by
* the PCP server) changes, the Epoch time MUST be reset. */ * the PCP server) changes, the Epoch time MUST be reset. */
epoch_origin = time(NULL); epoch_origin = upnp_time();
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
PCPSendUnsolicitedAnnounce(sockets, n_sockets, socket6); PCPSendUnsolicitedAnnounce(sockets, n_sockets, socket6);
#else /* IPv4 Only */ #else /* IPv4 Only */

View File

@ -1,4 +1,4 @@
/* $Id: testasyncsendto.c,v 1.4 2018/01/16 00:50:49 nanard Exp $ */ /* $Id: testasyncsendto.c,v 1.5 2018/03/13 10:25:52 nanard Exp $ */
/* vim: tabstop=4 shiftwidth=4 noexpandtab /* vim: tabstop=4 shiftwidth=4 noexpandtab
* MiniUPnP project * MiniUPnP project
* http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
@ -21,6 +21,8 @@
#include "asyncsendto.h" #include "asyncsendto.h"
struct lan_addr_list lan_addrs; struct lan_addr_list lan_addrs;
int runtime_flags = 0;
time_t startup_time = 0;
#define DEST_IP "239.255.255.250" #define DEST_IP "239.255.255.250"
#define DEST_PORT 1900 #define DEST_PORT 1900

View File

@ -1,7 +1,7 @@
/* $Id: testgetroute.c,v 1.5 2013/02/06 12:07:36 nanard Exp $ */ /* $Id: testgetroute.c,v 1.7 2018/03/13 10:25:52 nanard Exp $ */
/* MiniUPnP project /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2015 Thomas Bernard * (c) 2006-2018 Thomas Bernard
* This software is subject to the conditions detailed * This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */ * in the LICENCE file provided within the distribution */
@ -23,6 +23,8 @@
#endif #endif
struct lan_addr_list lan_addrs; struct lan_addr_list lan_addrs;
int runtime_flags = 0;
time_t startup_time = 0;
int int
main(int argc, char ** argv) main(int argc, char ** argv)

View File

@ -1,8 +1,8 @@
/* $Id: upnpevents.c,v 1.38 2017/11/02 15:50:35 nanard Exp $ */ /* $Id: upnpevents.c,v 1.39 2018/03/12 22:41:54 nanard Exp $ */
/* vim: tabstop=4 shiftwidth=4 noexpandtab /* vim: tabstop=4 shiftwidth=4 noexpandtab
* MiniUPnP project * MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2008-2017 Thomas Bernard * (c) 2008-2018 Thomas Bernard
* This software is subject to the conditions detailed * This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */ * in the LICENCE file provided within the distribution */
@ -182,7 +182,7 @@ upnpevents_addSubscriber(const char * eventurl,
if(!tmp) if(!tmp)
return NULL; return NULL;
if(timeout) if(timeout)
tmp->timeout = time(NULL) + timeout; tmp->timeout = upnp_time() + timeout;
LIST_INSERT_HEAD(&subscriberlist, tmp, entries); LIST_INSERT_HEAD(&subscriberlist, tmp, entries);
upnp_event_create_notify(tmp); upnp_event_create_notify(tmp);
return tmp->uuid; return tmp->uuid;
@ -197,10 +197,10 @@ upnpevents_renewSubscription(const char * sid, int sidlen, int timeout)
if((sidlen == 41) && (memcmp(sid, sub->uuid, 41) == 0)) { if((sidlen == 41) && (memcmp(sid, sub->uuid, 41) == 0)) {
#ifdef UPNP_STRICT #ifdef UPNP_STRICT
/* check if the subscription already timeouted */ /* check if the subscription already timeouted */
if(sub->timeout && time(NULL) > sub->timeout) if(sub->timeout && upnp_time() > sub->timeout)
continue; continue;
#endif #endif
sub->timeout = (timeout ? time(NULL) + timeout : 0); sub->timeout = (timeout ? upnp_time() + timeout : 0);
return sub->uuid; return sub->uuid;
} }
} }
@ -624,7 +624,7 @@ void upnpevents_processfds(fd_set *readset, fd_set *writeset)
obj = next; obj = next;
} }
/* remove timeouted subscribers */ /* remove timeouted subscribers */
curtime = time(NULL); curtime = upnp_time();
for(sub = subscriberlist.lh_first; sub != NULL; ) { for(sub = subscriberlist.lh_first; sub != NULL; ) {
subnext = sub->entries.le_next; subnext = sub->entries.le_next;
if(sub->timeout && curtime > sub->timeout && sub->notify == NULL) { if(sub->timeout && curtime > sub->timeout && sub->notify == NULL) {

View File

@ -1,7 +1,7 @@
/* $Id: upnppinhole.c,v 1.7 2014/12/09 09:13:53 nanard Exp $ */ /* $Id: upnppinhole.c,v 1.12 2018/03/13 10:24:55 nanard Exp $ */
/* MiniUPnP project /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2017 Thomas Bernard * (c) 2006-2018 Thomas Bernard
* This software is subject to the conditions detailed * This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */ * in the LICENCE file provided within the distribution */
@ -130,7 +130,7 @@ upnp_add_inboundpinhole(const char * raddr,
AF_INET6, iaddr, &address); AF_INET6, iaddr, &address);
return -4; return -4;
} }
current = time(NULL); current = upnp_time();
timestamp = current + leasetime; timestamp = current + leasetime;
r = 0; r = 0;
@ -252,7 +252,7 @@ upnp_get_pinhole_info(unsigned short uid,
if(r >= 0) { if(r >= 0) {
if(leasetime) { if(leasetime) {
time_t current_time; time_t current_time;
current_time = time(NULL); current_time = upnp_time();
if(timestamp > (unsigned int)current_time) if(timestamp > (unsigned int)current_time)
*leasetime = timestamp - current_time; *leasetime = timestamp - current_time;
else else
@ -289,7 +289,7 @@ upnp_update_inboundpinhole(unsigned short uid, unsigned int leasetime)
#if defined(USE_PF) || defined(USE_NETFILTER) #if defined(USE_PF) || defined(USE_NETFILTER)
unsigned int timestamp; unsigned int timestamp;
timestamp = time(NULL) + leasetime; timestamp = upnp_time() + leasetime;
return update_pinhole(uid, timestamp); return update_pinhole(uid, timestamp);
#else #else
UNUSED(uid); UNUSED(leasetime); UNUSED(uid); UNUSED(leasetime);
@ -331,7 +331,7 @@ upnp_check_pinhole_working(const char * uid,
/* TODO : to be implemented */ /* TODO : to be implemented */
#if 0 #if 0
FILE * fd; FILE * fd;
time_t expire = time(NULL); time_t expire = upnp_time();
char buf[1024], filename[] = "/var/log/kern.log", expire_time[32]=""; char buf[1024], filename[] = "/var/log/kern.log", expire_time[32]="";
int res = -4, str_len; int res = -4, str_len;

View File

@ -1,4 +1,4 @@
/* $Id: upnpredirect.c,v 1.92 2018/01/16 00:50:49 nanard Exp $ */ /* $Id: upnpredirect.c,v 1.93 2018/03/12 22:41:53 nanard Exp $ */
/* vim: tabstop=4 shiftwidth=4 noexpandtab /* vim: tabstop=4 shiftwidth=4 noexpandtab
* MiniUPnP project * MiniUPnP project
* http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
@ -25,6 +25,7 @@
#include "upnpglobalvars.h" #include "upnpglobalvars.h"
#include "upnpevents.h" #include "upnpevents.h"
#include "portinuse.h" #include "portinuse.h"
#include "upnputils.h"
#if defined(USE_NETFILTER) #if defined(USE_NETFILTER)
#include "netfilter/iptcrdr.h" #include "netfilter/iptcrdr.h"
#endif #endif
@ -202,7 +203,7 @@ int reload_from_lease_file()
syslog(LOG_WARNING, "could not unlink file %s : %m", lease_file); syslog(LOG_WARNING, "could not unlink file %s : %m", lease_file);
} }
current_time = time(NULL); current_time = upnp_time();
while(fgets(line, sizeof(line), fd)) { while(fgets(line, sizeof(line), fd)) {
syslog(LOG_DEBUG, "parsing lease file line '%s'", line); syslog(LOG_DEBUG, "parsing lease file line '%s'", line);
proto = line; proto = line;
@ -353,7 +354,7 @@ upnp_redirect(const char * rhost, unsigned short eport,
(rhost && (strcmp(rhost, rhost_old) == 0)))) { (rhost && (strcmp(rhost, rhost_old) == 0)))) {
syslog(LOG_INFO, "updating existing port mapping %hu %s (rhost '%s') => %s:%hu", syslog(LOG_INFO, "updating existing port mapping %hu %s (rhost '%s') => %s:%hu",
eport, protocol, rhost_old, iaddr_old, iport_old); eport, protocol, rhost_old, iaddr_old, iport_old);
timestamp = (leaseduration > 0) ? time(NULL) + leaseduration : 0; timestamp = (leaseduration > 0) ? upnp_time() + leaseduration : 0;
if(iport != iport_old) { if(iport != iport_old) {
r = update_portmapping(ext_if_name, eport, proto, iport, desc, timestamp); r = update_portmapping(ext_if_name, eport, proto, iport, desc, timestamp);
} else { } else {
@ -378,7 +379,7 @@ upnp_redirect(const char * rhost, unsigned short eport,
return -4; return -4;
#endif /* CHECK_PORTINUSE */ #endif /* CHECK_PORTINUSE */
} else { } else {
timestamp = (leaseduration > 0) ? time(NULL) + leaseduration : 0; timestamp = (leaseduration > 0) ? upnp_time() + leaseduration : 0;
syslog(LOG_INFO, "redirecting port %hu to %s:%hu protocol %s for: %s", syslog(LOG_INFO, "redirecting port %hu to %s:%hu protocol %s for: %s",
eport, iaddr, iport, protocol, desc); eport, iaddr, iport, protocol, desc);
return upnp_redirect_internal(rhost, eport, iaddr, iport, proto, return upnp_redirect_internal(rhost, eport, iaddr, iport, proto,
@ -448,7 +449,7 @@ upnp_get_redirection_infos(unsigned short eport, const char * protocol,
0, 0); 0, 0);
if(r == 0 && if(r == 0 &&
timestamp > 0 && timestamp > 0 &&
timestamp > (unsigned int)(current_time = time(NULL))) { timestamp > (unsigned int)(current_time = upnp_time())) {
*leaseduration = timestamp - current_time; *leaseduration = timestamp - current_time;
} else { } else {
*leaseduration = 0; *leaseduration = 0;
@ -481,7 +482,7 @@ upnp_get_redirection_infos_by_index(int index,
return -1; return -1;
else else
{ {
current_time = time(NULL); current_time = upnp_time();
*leaseduration = (timestamp > (unsigned int)current_time) *leaseduration = (timestamp > (unsigned int)current_time)
? (timestamp - current_time) ? (timestamp - current_time)
: 0; : 0;
@ -567,7 +568,7 @@ get_upnp_rules_state_list(int max_rules_number_target)
tmp = malloc(sizeof(struct rule_state)); tmp = malloc(sizeof(struct rule_state));
if(!tmp) if(!tmp)
return 0; return 0;
current_time = time(NULL); current_time = upnp_time();
nextruletoclean_timestamp = 0; nextruletoclean_timestamp = 0;
while(get_redirect_rule_by_index(i, /*ifname*/0, &tmp->eport, 0, 0, while(get_redirect_rule_by_index(i, /*ifname*/0, &tmp->eport, 0, 0,
&iport, &proto, 0, 0, 0,0, &timestamp, &iport, &proto, 0, 0, 0,0, &timestamp,

View File

@ -1,4 +1,4 @@
/* $Id: upnpsoap.c,v 1.149 2018/01/16 00:50:49 nanard Exp $ */ /* $Id: upnpsoap.c,v 1.151 2018/03/13 10:32:53 nanard Exp $ */
/* vim: tabstop=4 shiftwidth=4 noexpandtab /* vim: tabstop=4 shiftwidth=4 noexpandtab
* MiniUPnP project * MiniUPnP project
* http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
@ -32,6 +32,7 @@
#include "getifstats.h" #include "getifstats.h"
#include "getconnstatus.h" #include "getconnstatus.h"
#include "upnpurns.h" #include "upnpurns.h"
#include "upnputils.h"
/* utility function */ /* utility function */
static int is_numeric(const char * s) static int is_numeric(const char * s)
@ -274,7 +275,7 @@ GetStatusInfo(struct upnphttp * h, const char * action, const char * ns)
* Disconnecting, Disconnected */ * Disconnecting, Disconnected */
status = get_wan_connection_status_str(ext_if_name); status = get_wan_connection_status_str(ext_if_name);
uptime = (time(NULL) - startup_time); uptime = upnp_get_uptime();
bodylen = snprintf(body, sizeof(body), resp, bodylen = snprintf(body, sizeof(body), resp,
action, ns, /*SERVICE_TYPE_WANIPC,*/ action, ns, /*SERVICE_TYPE_WANIPC,*/
status, (long)uptime, action); status, (long)uptime, action);

View File

@ -1,7 +1,7 @@
/* $Id: upnputils.c,v 1.10 2014/11/07 11:53:39 nanard Exp $ */ /* $Id: upnputils.c,v 1.12 2018/03/13 10:25:20 nanard Exp $ */
/* MiniUPnP project /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2014 Thomas Bernard * (c) 2006-2018 Thomas Bernard
* This software is subject to the conditions detailed * This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */ * in the LICENCE file provided within the distribution */
@ -12,6 +12,7 @@
#include <syslog.h> #include <syslog.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <time.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -184,3 +185,38 @@ get_lan_for_peer(const struct sockaddr * peer)
return lan_addr; return lan_addr;
} }
time_t upnp_time(void)
{
#if defined(CLOCK_MONOTONIC_FAST) || defined(CLOCK_MONOTONIC)
#if defined(CLOCK_MONOTONIC_FAST)
#define UPNP_CLOCKID CLOCK_MONOTONIC_FAST
#else
#define UPNP_CLOCKID CLOCK_MONOTONIC
#endif
struct timespec ts;
if (clock_gettime(UPNP_CLOCKID, &ts) < 0)
return time(NULL);
else
return ts.tv_sec;
#else
return time(NULL);
#endif
}
time_t upnp_get_uptime(void)
{
#if defined(CLOCK_UPTIME_FAST) || defined(CLOCK_UPTIME)
#if defined(CLOCK_UPTIME_FAST)
#define UPNP_CLOCKID_UPTIME CLOCK_UPTIME_FAST
#else
#define UPNP_CLOCKID_UPTIME CLOCK_UPTIME
#endif
if(GETFLAG(SYSUPTIMEMASK))
{
struct timespec ts;
if (clock_gettime(UPNP_CLOCKID_UPTIME, &ts) >= 0)
return ts.tv_sec;
}
#endif
return upnp_time() - startup_time;
}

View File

@ -1,7 +1,7 @@
/* $Id: upnputils.h,v 1.6 2014/03/31 12:32:57 nanard Exp $ */ /* $Id: upnputils.h,v 1.9 2018/03/13 10:25:20 nanard Exp $ */
/* MiniUPnP project /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2011-2013 Thomas Bernard * (c) 2011-2018 Thomas Bernard
* This software is subject to the conditions detailed * This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */ * in the LICENCE file provided within the distribution */
@ -29,6 +29,16 @@ set_non_blocking(int fd);
struct lan_addr_s * struct lan_addr_s *
get_lan_for_peer(const struct sockaddr * peer); get_lan_for_peer(const struct sockaddr * peer);
/**
* get the time for upnp (release expiration, etc.)
* Similar to a monotonic time(NULL)
*/
time_t upnp_time(void);
/**
* return either the machine or the daemon uptime
*/
time_t upnp_get_uptime(void);
/** /**
* define portability macros * define portability macros