* Use our own time-based UUID generation functions, to help eliminate potential compiling issues.
This commit is contained in:
parent
a78c7c9077
commit
25861ebf92
20
Makefile
20
Makefile
@ -1,14 +1,14 @@
|
||||
# $Id$
|
||||
# MiniUPnP project
|
||||
# http://miniupnp.free.fr/
|
||||
# Author : Thomas Bernard
|
||||
# MiniDLNA project
|
||||
# http://sourceforge.net/projects/minidlna/
|
||||
# (c) 2008-2009 Justin Maggard
|
||||
# for use with GNU Make
|
||||
# To install use :
|
||||
# $ PREFIX=/dummyinstalldir make -f Makefile.linux install
|
||||
# $ PREFIX=/dummyinstalldir make install
|
||||
# or :
|
||||
# $ INSTALLPREFIX=/usr/local make -f Makefile.linux install
|
||||
# $ INSTALLPREFIX=/usr/local make install
|
||||
# or :
|
||||
# $ make -f Makefile.linux install
|
||||
# $ make install
|
||||
#
|
||||
#CFLAGS = -Wall -O -D_GNU_SOURCE -g -DDEBUG
|
||||
#CFLAGS = -Wall -g -Os -D_GNU_SOURCE
|
||||
@ -27,7 +27,7 @@ ETCINSTALLDIR = $(PREFIX)/etc
|
||||
BASEOBJS = minidlna.o upnphttp.o upnpdescgen.o upnpsoap.o \
|
||||
upnpreplyparse.o minixml.o \
|
||||
getifaddr.o daemonize.o upnpglobalvars.o \
|
||||
options.o minissdp.o upnpevents.o \
|
||||
options.o minissdp.o uuid.o upnpevents.o \
|
||||
sql.o utils.o metadata.o scanner.o inotify.o \
|
||||
tivo_utils.o tivo_beacon.o tivo_commands.o \
|
||||
tagutils/textutils.o tagutils/misc.o tagutils/tagutils.o \
|
||||
@ -76,8 +76,7 @@ depend: config.h
|
||||
|
||||
minidlna.o: config.h upnpglobalvars.h minidlnatypes.h
|
||||
minidlna.o: upnphttp.h upnpdescgen.h minidlnapath.h getifaddr.h upnpsoap.h
|
||||
minidlna.o: options.h minissdp.h daemonize.h upnpevents.h
|
||||
minidlna.o: commonrdr.h log.h
|
||||
minidlna.o: options.h minissdp.h daemonize.h upnpevents.h log.h
|
||||
upnphttp.o: config.h upnphttp.h upnpdescgen.h minidlnapath.h upnpsoap.h
|
||||
upnphttp.o: upnpevents.h image_utils.h sql.h log.h icons.c
|
||||
upnpdescgen.o: config.h upnpdescgen.h minidlnapath.h upnpglobalvars.h
|
||||
@ -95,7 +94,8 @@ options.o: minidlnatypes.h
|
||||
minissdp.o: config.h upnpdescstrings.h minidlnapath.h upnphttp.h
|
||||
minissdp.o: upnpglobalvars.h minidlnatypes.h minissdp.h log.h
|
||||
upnpevents.o: config.h upnpevents.h minidlnapath.h upnpglobalvars.h
|
||||
upnpevents.o: minidlnatypes.h upnpdescgen.h log.h
|
||||
upnpevents.o: minidlnatypes.h upnpdescgen.h log.h uuid.h
|
||||
uuid.o: uuid.h
|
||||
testupnpdescgen.o: config.h upnpdescgen.h
|
||||
upnpdescgen.o: config.h upnpdescgen.h minidlnapath.h upnpglobalvars.h
|
||||
upnpdescgen.o: minidlnatypes.h upnpdescstrings.h
|
||||
|
35
commonrdr.h
35
commonrdr.h
@ -1,35 +0,0 @@
|
||||
/* MiniUPnP project
|
||||
* (c) 2006-2007 Thomas Bernard
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* This software is subject to the conditions detailed
|
||||
* in the LICENCE file provided within the distribution */
|
||||
#ifndef __COMMONRDR_H__
|
||||
#define __COMMONRDR_H__
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/* init and shutdown functions */
|
||||
int
|
||||
init_redirect(void);
|
||||
|
||||
void
|
||||
shutdown_redirect(void);
|
||||
|
||||
/* get_redirect_rule() gets internal IP and port from
|
||||
* interface, external port and protocl
|
||||
*/
|
||||
int
|
||||
get_redirect_rule(const char * ifname, unsigned short eport, int proto,
|
||||
char * iaddr, int iaddrlen, unsigned short * iport,
|
||||
char * desc, int desclen,
|
||||
u_int64_t * packets, u_int64_t * bytes);
|
||||
|
||||
int
|
||||
get_redirect_rule_by_index(int index,
|
||||
char * ifname, unsigned short * eport,
|
||||
char * iaddr, int iaddrlen, unsigned short * iport,
|
||||
int * proto, char * desc, int desclen,
|
||||
u_int64_t * packets, u_int64_t * bytes);
|
||||
|
||||
#endif
|
||||
|
@ -1,8 +1,8 @@
|
||||
#! /bin/sh
|
||||
# $Id$
|
||||
# miniupnp daemon
|
||||
# http://miniupnp.free.fr or http://miniupnp.tuxfamily.org/
|
||||
# (c) 2006-2007 Thomas Bernard
|
||||
# MiniDLNA project
|
||||
# http://sourceforge.net/projects/minidlna/
|
||||
# (c) 2008-2009 Justin Maggard
|
||||
# This software is subject to the conditions detailed in the
|
||||
# LICENCE file provided within the distribution
|
||||
|
||||
@ -25,7 +25,6 @@ ${RM} ${CONFIGFILE}
|
||||
# Detect if there are missing headers
|
||||
# NOTE: This check only works with a normal distro
|
||||
[ ! -e "/usr/include/sqlite3.h" ] && MISSING="libsqlite3 $MISSING"
|
||||
[ ! -e "/usr/include/uuid/uuid.h" ] && MISSING="libuuid $MISSING"
|
||||
[ ! -e "/usr/include/jpeglib.h" ] && MISSING="libjpeg $MISSING"
|
||||
[ ! -e "/usr/include/libexif/exif-loader.h" ] && MISSING="libexif $MISSING"
|
||||
[ ! -e "/usr/include/id3tag.h" ] && MISSING="libid3tag $MISSING"
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include "upnpevents.h"
|
||||
#include "scanner.h"
|
||||
#include "inotify.h"
|
||||
#include "commonrdr.h"
|
||||
#include "log.h"
|
||||
#ifdef TIVO_SUPPORT
|
||||
#include "tivo_beacon.h"
|
||||
|
38
upnpevents.c
38
upnpevents.c
@ -1,10 +1,15 @@
|
||||
/* $Id$ */
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2008 Thomas Bernard
|
||||
/* MiniDLNA project
|
||||
* http://minidlna.sourceforge.net/
|
||||
* (c) 2008-2009 Justin Maggard
|
||||
*
|
||||
* This software is subject to the conditions detailed
|
||||
* in the LICENCE file provided within the distribution */
|
||||
|
||||
* in the LICENCE file provided within the distribution
|
||||
*
|
||||
* Portions of the code from the MiniUPnP Project
|
||||
* (c) Thomas Bernard licensed under BSD revised license
|
||||
* detailed in the LICENSE.miniupnpd file provided within
|
||||
* the distribution.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
@ -24,14 +29,9 @@
|
||||
#include "minidlnapath.h"
|
||||
#include "upnpglobalvars.h"
|
||||
#include "upnpdescgen.h"
|
||||
#include "uuid.h"
|
||||
#include "log.h"
|
||||
|
||||
#define HAVE_UUID 1
|
||||
|
||||
#ifdef HAVE_UUID
|
||||
#include <uuid/uuid.h>
|
||||
#endif
|
||||
|
||||
/* stuctures definitions */
|
||||
struct subscriber {
|
||||
LIST_ENTRY(subscriber) entries;
|
||||
@ -95,14 +95,12 @@ newSubscriber(const char * eventurl, const char * callback, int callbacklen)
|
||||
tmp->callback[callbacklen] = '\0';
|
||||
/* make a dummy uuid */
|
||||
strncpy(tmp->uuid, uuidvalue, sizeof(tmp->uuid));
|
||||
#ifdef HAVE_UUID
|
||||
uuid_t uuid;
|
||||
uuid_generate_time(uuid);
|
||||
uuid_unparse_lower(uuid, tmp->uuid+5);
|
||||
#else
|
||||
tmp->uuid[sizeof(tmp->uuid)-1] = '\0';
|
||||
snprintf(tmp->uuid+37, 5, "%04lx", random() & 0xffff);
|
||||
#endif
|
||||
if( get_uuid_string(tmp->uuid+5) != 0 )
|
||||
{
|
||||
tmp->uuid[sizeof(tmp->uuid)-1] = '\0';
|
||||
snprintf(tmp->uuid+37, 5, "%04lx", random() & 0xffff);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
16
upnpevents.h
16
upnpevents.h
@ -1,9 +1,15 @@
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2008 Thomas Bernard
|
||||
/* MiniDLNA project
|
||||
* http://minidlna.sourceforge.net/
|
||||
* (c) 2008-2009 Justin Maggard
|
||||
*
|
||||
* This software is subject to the conditions detailed
|
||||
* in the LICENCE file provided within the distribution */
|
||||
|
||||
* in the LICENCE file provided within the distribution
|
||||
*
|
||||
* Portions of the code from the MiniUPnP Project
|
||||
* (c) Thomas Bernard licensed under BSD revised license
|
||||
* detailed in the LICENSE.miniupnpd file provided within
|
||||
* the distribution.
|
||||
*/
|
||||
#ifndef __UPNPEVENTS_H__
|
||||
#define __UPNPEVENTS_H__
|
||||
enum subscriber_service_enum {
|
||||
|
@ -1,10 +1,15 @@
|
||||
/* $Id$ */
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2006 Thomas Bernard
|
||||
/* MiniDLNA project
|
||||
* http://minidlna.sourceforge.net/
|
||||
* (c) 2008-2009 Justin Maggard
|
||||
*
|
||||
* This software is subject to the conditions detailed
|
||||
* in the LICENCE file provided within the distribution */
|
||||
|
||||
* in the LICENCE file provided within the distribution
|
||||
*
|
||||
* Portions of the code from the MiniUPnP Project
|
||||
* (c) Thomas Bernard licensed under BSD revised license
|
||||
* detailed in the LICENSE.miniupnpd file provided within
|
||||
* the distribution.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
|
@ -1,9 +1,15 @@
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2006 Thomas Bernard
|
||||
/* MiniDLNA project
|
||||
* http://minidlna.sourceforge.net/
|
||||
* (c) 2008-2009 Justin Maggard
|
||||
*
|
||||
* This software is subject to the conditions detailed
|
||||
* in the LICENCE file provided within the distribution */
|
||||
|
||||
* in the LICENCE file provided within the distribution
|
||||
*
|
||||
* Portions of the code from the MiniUPnP Project
|
||||
* (c) Thomas Bernard licensed under BSD revised license
|
||||
* detailed in the LICENSE.miniupnpd file provided within
|
||||
* the distribution.
|
||||
*/
|
||||
#ifndef __UPNPGLOBALVARS_H__
|
||||
#define __UPNPGLOBALVARS_H__
|
||||
|
||||
|
11
upnpsoap.h
11
upnpsoap.h
@ -1,9 +1,10 @@
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2006 Thomas Bernard
|
||||
/* MiniDLNA project
|
||||
* http://minidlna.sourceforge.net/
|
||||
* (c) 2008-2009 Justin Maggard
|
||||
*
|
||||
* This software is subject to the conditions detailed
|
||||
* in the LICENCE file provided within the distribution */
|
||||
|
||||
* in the LICENCE file provided within the distribution
|
||||
*/
|
||||
#ifndef __UPNPSOAP_H__
|
||||
#define __UPNPSOAP_H__
|
||||
|
||||
|
246
uuid.c
Normal file
246
uuid.c
Normal file
@ -0,0 +1,246 @@
|
||||
/* MiniDLNA project
|
||||
*
|
||||
* http://sourceforge.net/projects/minidlna/
|
||||
* (c) 2009 Justin Maggard
|
||||
* This software is subject to the conditions detailed
|
||||
* in the LICENCE file provided within the distribution
|
||||
*
|
||||
* Much of this code and ideas for this code have been taken
|
||||
* from Helge Deller's proposed Linux kernel patch (which
|
||||
* apparently never made it upstream), and some from Busybox.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <string.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#define ETH_ALEN 6
|
||||
#define NSEC_PER_SEC 1000000000L
|
||||
#define NSEC_PER_MSEC 1000000L
|
||||
|
||||
static u_int32_t clock_seq;
|
||||
static const u_int32_t clock_seq_max = 0x3fff; /* 14 bits */
|
||||
static int clock_seq_initialized;
|
||||
|
||||
unsigned long long
|
||||
monotonic_us(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts);
|
||||
return ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000;
|
||||
}
|
||||
|
||||
int
|
||||
read_bootid_node(u_int8_t *buf, size_t size)
|
||||
{
|
||||
FILE *boot_id;
|
||||
|
||||
if(size != 6)
|
||||
return -1;
|
||||
|
||||
boot_id = fopen("/proc/sys/kernel/random/boot_id", "r");
|
||||
if(!boot_id)
|
||||
return -1;
|
||||
if((fseek(boot_id, 24, SEEK_SET) < 0) ||
|
||||
(fscanf(boot_id, "%02x%02x%02x%02x%02x%02x",
|
||||
(unsigned *)&buf[0], (unsigned *)&buf[1], (unsigned *)&buf[2],
|
||||
(unsigned *)&buf[3], (unsigned *)&buf[4], (unsigned *)&buf[5]) != 6))
|
||||
{
|
||||
fclose(boot_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fclose(boot_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
read_random_bytes(unsigned char *buf, size_t size)
|
||||
{
|
||||
int i;
|
||||
pid_t pid;
|
||||
|
||||
i = open("/dev/urandom", O_RDONLY);
|
||||
if(i >= 0)
|
||||
{
|
||||
read(i, buf, size);
|
||||
close(i);
|
||||
}
|
||||
/* Paranoia. /dev/urandom may be missing.
|
||||
* rand() is guaranteed to generate at least [0, 2^15) range,
|
||||
* but lowest bits in some libc are not so "random". */
|
||||
srand(monotonic_us());
|
||||
pid = getpid();
|
||||
while(1)
|
||||
{
|
||||
for(i = 0; i < size; i++)
|
||||
buf[i] ^= rand() >> 5;
|
||||
if(pid == 0)
|
||||
break;
|
||||
srand(pid);
|
||||
pid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
init_clockseq(void)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
|
||||
read_random_bytes(buf, 4);
|
||||
memcpy(&clock_seq, &buf, sizeof(clock_seq));
|
||||
clock_seq &= clock_seq_max;
|
||||
clock_seq_initialized = 1;
|
||||
}
|
||||
|
||||
int
|
||||
generate_uuid(unsigned char uuid_out[16])
|
||||
{
|
||||
static u_int64_t last_time_all;
|
||||
static unsigned int clock_seq_started;
|
||||
static char last_node[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
struct timespec ts;
|
||||
u_int64_t time_all;
|
||||
int inc_clock_seq = 0;
|
||||
|
||||
struct ifaddrs *ifaddr, *ifa;
|
||||
unsigned char mac[6];
|
||||
struct ifreq ifr;
|
||||
int fd;
|
||||
|
||||
int found_mac = 0;
|
||||
|
||||
memset(&mac, '\0', sizeof(mac));
|
||||
/* Get the spatially unique node identifier */
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if( fd < 0 )
|
||||
return -1;
|
||||
|
||||
if(getifaddrs(&ifaddr) == -1)
|
||||
{
|
||||
DPRINTF(E_ERROR, L_HTTP, "getifaddrs(): %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
|
||||
{
|
||||
if(ifa->ifa_addr->sa_family != AF_PACKET)
|
||||
continue;
|
||||
if(ifa->ifa_flags & IFF_LOOPBACK)
|
||||
continue;
|
||||
|
||||
strcpy(ifr.ifr_name, ifa->ifa_name);
|
||||
if(strncmp(last_node, ifa->ifa_name, sizeof(last_node)) != 0)
|
||||
{
|
||||
inc_clock_seq = 1;
|
||||
strncpy(last_node, ifa->ifa_name, sizeof(last_node));
|
||||
}
|
||||
|
||||
if(ioctl(fd, SIOCGIFHWADDR, &ifr) == 0)
|
||||
memmove(mac, ifr.ifr_hwaddr.sa_data, 6);
|
||||
|
||||
found_mac = 1;
|
||||
break;
|
||||
}
|
||||
close(fd);
|
||||
freeifaddrs(ifaddr);
|
||||
|
||||
if(found_mac)
|
||||
{
|
||||
memcpy(&uuid_out[10], mac, ETH_ALEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use bootid's nodeID if no network interface found */
|
||||
DPRINTF(E_INFO, L_HTTP, "Could not find MAC. Use bootid's nodeID.\n");
|
||||
if( read_bootid_node(&uuid_out[10], 6) != 0)
|
||||
{
|
||||
DPRINTF(E_INFO, L_HTTP, "bootid node not successfully read.\n");
|
||||
read_random_bytes(&uuid_out[10], 6);
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine 60-bit timestamp value. For UUID version 1, this is
|
||||
* represented by Coordinated Universal Time (UTC) as a count of 100-
|
||||
* nanosecond intervals since 00:00:00.00, 15 October 1582 (the date of
|
||||
* Gregorian reform to the Christian calendar).
|
||||
*/
|
||||
syscall(__NR_clock_gettime, CLOCK_REALTIME, &ts);
|
||||
time_all = ((u_int64_t)ts.tv_sec) * (NSEC_PER_SEC / 100);
|
||||
time_all += ts.tv_nsec / 100;
|
||||
|
||||
/* add offset from Gregorian Calendar to Jan 1 1970 */
|
||||
time_all += 12219292800000ULL * (NSEC_PER_MSEC / 100);
|
||||
time_all &= 0x0fffffffffffffffULL; /* limit to 60 bits */
|
||||
|
||||
/* Determine clock sequence (max. 14 bit) */
|
||||
if(!clock_seq_initialized)
|
||||
{
|
||||
init_clockseq();
|
||||
clock_seq_started = clock_seq;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(inc_clock_seq || time_all <= last_time_all)
|
||||
{
|
||||
clock_seq = (clock_seq + 1) & clock_seq_max;
|
||||
if(clock_seq == clock_seq_started)
|
||||
{
|
||||
clock_seq = (clock_seq - 1) & clock_seq_max;
|
||||
}
|
||||
}
|
||||
else
|
||||
clock_seq_started = clock_seq;
|
||||
}
|
||||
last_time_all = time_all;
|
||||
|
||||
/* Fill in timestamp and clock_seq values */
|
||||
uuid_out[3] = (u_int8_t)time_all;
|
||||
uuid_out[2] = (u_int8_t)(time_all >> 8);
|
||||
uuid_out[1] = (u_int8_t)(time_all >> 16);
|
||||
uuid_out[0] = (u_int8_t)(time_all >> 24);
|
||||
uuid_out[5] = (u_int8_t)(time_all >> 32);
|
||||
uuid_out[4] = (u_int8_t)(time_all >> 40);
|
||||
uuid_out[7] = (u_int8_t)(time_all >> 48);
|
||||
uuid_out[6] = (u_int8_t)(time_all >> 56);
|
||||
|
||||
uuid_out[8] = clock_seq >> 8;
|
||||
uuid_out[9] = clock_seq & 0xff;
|
||||
|
||||
/* Set UUID version to 1 --- time-based generation */
|
||||
uuid_out[6] = (uuid_out[6] & 0x0F) | 0x10;
|
||||
/* Set the UUID variant to DCE */
|
||||
uuid_out[8] = (uuid_out[8] & 0x3F) | 0x80;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Places a null-terminated 37-byte time-based UUID string in the buffer pointer to by buf.
|
||||
* A large enough buffer must already be allocated. */
|
||||
int
|
||||
get_uuid_string(char *buf)
|
||||
{
|
||||
unsigned char uuid[16];
|
||||
|
||||
if( generate_uuid(uuid) != 0 )
|
||||
return -1;
|
||||
|
||||
sprintf(buf, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], uuid[8],
|
||||
uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
|
||||
buf[36] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
16
uuid.h
Normal file
16
uuid.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* UUID generation functions
|
||||
*
|
||||
* Project : minidlna
|
||||
* Website : http://sourceforge.net/projects/minidlna/
|
||||
* Author : Justin Maggard
|
||||
* Copyright (c) 2009 Justin Maggard
|
||||
* This software is subject to the conditions detailed in the
|
||||
* LICENCE file provided in this distribution.
|
||||
* */
|
||||
#ifndef __UUID_H__
|
||||
#define __UUID_H__
|
||||
|
||||
int
|
||||
get_uuid_string(char *buf);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user