From 2cf15043eba6ed7b16526145dcf6a2b563b9712d Mon Sep 17 00:00:00 2001 From: Nathan Wagner Date: Tue, 23 Sep 2014 10:11:05 +0000 Subject: [PATCH] Added defines for uuid sizes. Cleaned up the internals of the uuid library, refactored code and fixed a bug in the state initialization for version 1 uuids. --- Makefile | 2 +- internal.c | 112 ++++++++++++++++++++++++++++------------------------- pduuid.h | 8 +++- 3 files changed, 68 insertions(+), 54 deletions(-) diff --git a/Makefile b/Makefile index ed7deb6..52d7b7d 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ CFLAGS=-Wall -I. -L. # set the following for windows #LDFLAGS += -liphlpapi -all: libpduuid.a +all: libpduuid.a uuidgen windows: libpduuid.a uuidgen.o $(CC) $(CFLAGS) -Wall -L. -o $@ uuidgen.o -lpduuid $(LDFLAGS) -liphlpapi diff --git a/internal.c b/internal.c index c911099..c9a72f6 100644 --- a/internal.c +++ b/internal.c @@ -6,6 +6,9 @@ #include #include #include +#include + +#include #include "hash.h" @@ -37,6 +40,24 @@ #include #endif +#if 0 +static void pnode(uint64_t node) { + unsigned int bytes[6]; + int i; + for (i=0;i<6;i++) { + bytes[5-i] = node & 0xff; + node >>= 8; + } + + fprintf(stderr, "%02x", bytes[0]); + + for (i=1;i<6;i++) { + fprintf(stderr, ":%02x", bytes[i]); + } + fprintf(stderr, "\n"); +} +#endif + static void set_time_low(pd_uuid_t *u, uint32_t low) { u->data[0] = (low >> 24) & 0xff; u->data[1] = (low >> 16) & 0xff; @@ -157,6 +178,7 @@ static uint64_t random_mc_mac(struct pd_uuid_state *s) { return node; } + /* * TODO would probably make more sense to use a destination array * rather than returning an integer @@ -187,6 +209,8 @@ static uint64_t current_node(struct pd_uuid_state *st) { if (req->ifr_flags & IFF_NOARP) { continue; } + + if (ioctl(s, SIOCGIFHWADDR, req) == 0) { data = (unsigned char *)req->ifr_hwaddr.sa_data; node = data[0]; @@ -196,7 +220,10 @@ static uint64_t current_node(struct pd_uuid_state *st) { node = node << 8; node += data[4]; node = node << 8; node += data[5]; close(s); + return node; + } else { + fprintf(stderr, "ioctl to read address failed: %d\n", errno); } } } @@ -278,15 +305,13 @@ static int read_state(struct pd_uuid_state *s) { uint64_t node; s->available = 0; - s->node = 0LL; - s->clock_sequence = 0; - s->timestamp = 0LL; node = current_node(s); if (!s->available || s->node != node) { s->clock_sequence = random_clock_sequence(s); } + s->node = node; return 0; } @@ -342,64 +367,23 @@ int pd_uuid_init_state(struct pd_uuid_state *s) { s->random_bytes = get_bytes; s->rng_state = 0; + s->node = 0; s->available = 0; return 1; } +static int pd_uuid_make_v1_any(struct pd_uuid_state *s, pd_uuid_t *uuid, int rmac); int pd_uuid_make_v1(struct pd_uuid_state *s, pd_uuid_t *uuid) { - struct pd_uuid_state ls; - uint64_t now; - int err; - - if (!s) { - s = &ls; - pd_uuid_init_state(s); - } - - if (s->get_lock) { - if ((err = s->get_lock(s->lock_data)) != 0) { - /* TODO set uuid to nil ? */ - /* be cute and have an "error" uuid? */ - return 0; - } - } - - if (s->read_state) { - if ((err = s->read_state(s)) != 0) { - return 0; - } - } - - now = current_time(); - - if (s->available && s->timestamp > now) { - s->clock_sequence++; - } else { - s->timestamp = now; - } - - if (s->save_state) { - if ((err = s->save_state(s)) != 0) { - return 0; - } - } - - if (s->release_lock) { - if ((err = s->release_lock(s->lock_data)) != 0) { - /* TODO set uuid to nil ? */ - /* be cute and have an "error" uuid? */ - return 0; - } - } - - format_uuid(uuid, s, 1); - - return 1; + return pd_uuid_make_v1_any(s, uuid, 0); } int pd_uuid_make_v1mc(struct pd_uuid_state *s, pd_uuid_t *uuid) { + return pd_uuid_make_v1_any(s, uuid, 1); +} + +static int pd_uuid_make_v1_any(struct pd_uuid_state *s, pd_uuid_t *uuid, int rmac) { struct pd_uuid_state ls; uint64_t now; uint64_t node; @@ -425,7 +409,11 @@ int pd_uuid_make_v1mc(struct pd_uuid_state *s, pd_uuid_t *uuid) { } now = current_time(); - node = random_mc_mac(s); + if (rmac) { + node = random_mc_mac(s); + } else { + node = current_node(s); + } if (!s->available || s->node != node) { s->clock_sequence = random_clock_sequence(s); @@ -500,6 +488,26 @@ int pd_uuid_make_v5(struct pd_uuid_state *s, pd_uuid_t *uuid, pd_uuid_t *ns, voi return 1; } +/* + * s must point to enough space + */ +char *pd_uuid_get_string(pd_uuid_t *uuid, char *s) { + char *r; + int i; + + r = s; + + for (i=0;i<16;i++) { + r += sprintf(r, "%.2x", (int)uuid->data[i]); + if (i == 3 || i == 5 || i == 7 || i == 9) { + *r++ = '-'; + *r = 0; + } + } + + return s; +} + int pd_uuid_set_string(pd_uuid_t *uuid, char *s) { unsigned int byte; int i; diff --git a/pduuid.h b/pduuid.h index 14ad6da..36f7efa 100644 --- a/pduuid.h +++ b/pduuid.h @@ -3,10 +3,16 @@ #include +#define PD_UUID_BINLEN 16 +#define PD_UUID_STRLEN 36 + struct pd_uuid_state { uint64_t timestamp, node; uint16_t clock_sequence; int available; + void *rng_state; + unsigned char uuid[16]; + int (*get_lock)(void *); int (*release_lock)(void *); void *lock_data; @@ -15,7 +21,6 @@ struct pd_uuid_state { /* TODO hook for a random number generator? */ unsigned long (*random_bytes)(void *out, unsigned long outlen, void *prng_state); - void *rng_state; }; struct pd_uuid { @@ -37,6 +42,7 @@ int pd_uuid_cmp(pd_uuid_t *a, pd_uuid_t *b); int pd_set_uuid_hash(pd_uuid_t *s, void *hash, int version); int pd_uuid_set_string(pd_uuid_t *uuid, char *s); +char *pd_uuid_get_string(pd_uuid_t *uuid, char *s); unsigned long pd_uuid_rng_get_bytes(unsigned char *out, unsigned long outlen); -- 2.40.0