Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Functions | Variables
uuid.c File Reference

Universally unique identifier support. More...

#include "asterisk.h"
#include <uuid/uuid.h>
#include <fcntl.h>
#include "asterisk/uuid.h"
#include "asterisk/utils.h"
#include "asterisk/strings.h"
#include "asterisk/logger.h"
#include "asterisk/lock.h"
Include dependency graph for uuid.c:

Go to the source code of this file.

Data Structures

struct  ast_uuid
 

Functions

struct ast_uuidast_str_to_uuid (char *str)
 Convert a string to a UUID. More...
 
void ast_uuid_clear (struct ast_uuid *uuid)
 Clear a UUID by setting it to be a nil UUID (all 0s) More...
 
int ast_uuid_compare (struct ast_uuid *left, struct ast_uuid *right)
 Compare two UUIDs. More...
 
struct ast_uuidast_uuid_copy (struct ast_uuid *src)
 Make a copy of a UUID. More...
 
struct ast_uuidast_uuid_generate (void)
 Generate a UUID. More...
 
char * ast_uuid_generate_str (char *buf, size_t size)
 Generate a UUID string. More...
 
void ast_uuid_init (void)
 Initialize the UUID system. More...
 
int ast_uuid_is_nil (struct ast_uuid *uuid)
 Check if a UUID is a nil UUID (all 0s) More...
 
char * ast_uuid_to_str (struct ast_uuid *uuid, char *buf, size_t size)
 Convert a UUID to a string. More...
 
static void generate_uuid (struct ast_uuid *uuid)
 

Variables

static int has_dev_urandom
 
static ast_mutex_t uuid_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 

Detailed Description

Universally unique identifier support.

ExtRef:
Depends on libuuid, a component of the e2fsprogs package - http://e2fsprogs.sourceforge.net/

Definition in file uuid.c.

Function Documentation

◆ ast_str_to_uuid()

struct ast_uuid* ast_str_to_uuid ( char *  str)

Convert a string to a UUID.

This function allocates memory on the heap. The returned pointer must be freed using ast_free()

Parameters
strThe string to convert to a UUID
Return values
NULLFailed to convert
non-NULLThe heap-allocated converted UUID

Definition at line 151 of file uuid.c.

References ast_free, ast_log, ast_malloc, LOG_WARNING, NULL, and ast_uuid::uu.

Referenced by AST_TEST_DEFINE(), and is_valid_uuid().

152 {
153  struct ast_uuid *uuid = ast_malloc(sizeof(*uuid));
154  int res;
155 
156  if (!uuid) {
157  return NULL;
158  }
159  res = uuid_parse(str, uuid->uu);
160  if (res) {
161  ast_log(LOG_WARNING, "Unable to convert string %s into a UUID\n", str);
162  ast_free(uuid);
163  return NULL;
164  }
165  return uuid;
166 }
#define LOG_WARNING
Definition: logger.h:274
const char * str
Definition: app_jack.c:147
#define NULL
Definition: resample.c:96
Definition: uuid.c:39
#define ast_log
Definition: astobj2.c:42
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
#define ast_free(a)
Definition: astmm.h:182
uuid_t uu
Definition: uuid.c:40

◆ ast_uuid_clear()

void ast_uuid_clear ( struct ast_uuid uuid)

Clear a UUID by setting it to be a nil UUID (all 0s)

Parameters
uuidUUID to clear

Definition at line 184 of file uuid.c.

References ast_uuid::uu.

Referenced by AST_TEST_DEFINE().

185 {
186  uuid_clear(uuid->uu);
187 }
uuid_t uu
Definition: uuid.c:40

◆ ast_uuid_compare()

int ast_uuid_compare ( struct ast_uuid left,
struct ast_uuid right 
)

Compare two UUIDs.

Parameters
leftFirst UUID to compare
rightSecond UUID to compare
Return values
<0left is lexicographically less than right
0left and right are the same
>0left is lexicographically greater than right

Definition at line 179 of file uuid.c.

References ast_uuid::uu.

Referenced by AST_TEST_DEFINE().

180 {
181  return uuid_compare(left->uu, right->uu);
182 }
uuid_t uu
Definition: uuid.c:40

◆ ast_uuid_copy()

struct ast_uuid* ast_uuid_copy ( struct ast_uuid src)

Make a copy of a UUID.

This function allocates memory on the heap. The returned pointer must be freed using ast_free()

Parameters
srcThe source UUID to copy
Return values
NULLFailed to copy
non-NULLThe heap-allocated duplicate UUID

Definition at line 168 of file uuid.c.

References ast_malloc, NULL, and ast_uuid::uu.

Referenced by AST_TEST_DEFINE().

169 {
170  struct ast_uuid *dst = ast_malloc(sizeof(*dst));
171 
172  if (!dst) {
173  return NULL;
174  }
175  uuid_copy(dst->uu, src->uu);
176  return dst;
177 }
#define NULL
Definition: resample.c:96
Definition: uuid.c:39
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
uuid_t uu
Definition: uuid.c:40

◆ ast_uuid_generate()

struct ast_uuid* ast_uuid_generate ( void  )

Generate a UUID.

This function allocates memory on the heap. The returned pointer must be freed using ast_free()

Return values
NULLGeneration failed
non-NULLheap-allocated UUID

Definition at line 125 of file uuid.c.

References ast_malloc, generate_uuid(), and NULL.

Referenced by AST_TEST_DEFINE().

126 {
127  struct ast_uuid *uuid = ast_malloc(sizeof(*uuid));
128 
129  if (!uuid) {
130  return NULL;
131  }
132  generate_uuid(uuid);
133  return uuid;
134 }
static void generate_uuid(struct ast_uuid *uuid)
Definition: uuid.c:52
#define NULL
Definition: resample.c:96
Definition: uuid.c:39
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193

◆ ast_uuid_generate_str()

char* ast_uuid_generate_str ( char *  buf,
size_t  size 
)

Generate a UUID string.

Since
12.0.0
Parameters
bufThe buffer where the UUID string will be stored
sizeThe size of the buffer. Must be at least AST_UUID_STR_LEN.
Returns
The UUID string (a pointer to buf)

Definition at line 143 of file uuid.c.

References ast_uuid_to_str(), and generate_uuid().

Referenced by add_msid_to_stream(), ast_datastores_alloc_datastore(), ast_rtp_new(), ast_sip_publish_client_alloc_datastore(), ast_sip_session_alloc_datastore(), ast_sorcery_alloc(), AST_TEST_DEFINE(), ast_websocket_uri_cb(), asterisk_daemon(), bridge_base_init(), build_entity_id(), generate_exchange_uuid(), mock_retrieve_multiple(), playback_create(), sorcery_config_open(), and stir_shaken_add_origid().

144 {
145  struct ast_uuid uuid;
146 
147  generate_uuid(&uuid);
148  return ast_uuid_to_str(&uuid, buf, size);
149 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static void generate_uuid(struct ast_uuid *uuid)
Definition: uuid.c:52
Definition: uuid.c:39
char * ast_uuid_to_str(struct ast_uuid *uuid, char *buf, size_t size)
Convert a UUID to a string.
Definition: uuid.c:136

◆ ast_uuid_init()

void ast_uuid_init ( void  )

Initialize the UUID system.

Definition at line 194 of file uuid.c.

References ast_debug, ast_log, dev_urandom_fd, has_dev_urandom, LOG_WARNING, and ast_uuid::uu.

Referenced by asterisk_daemon().

195 {
196  /* This requires some explanation.
197  *
198  * libuuid generates UUIDs based on random number generation. This involves
199  * opening a handle to /dev/urandom or /dev/random in order to get random
200  * data for the UUIDs.
201  *
202  * This is thread-safe, to a point. The problem is that the first attempt
203  * to generate a UUID will result in opening the random number handle. Once
204  * the handle is opened, all further generation is thread safe. This
205  * first generation can be potentially risky if multiple threads attempt
206  * to generate a UUID at the same time, though, since there is no thread
207  * synchronization used within libuuid. To get around this potential
208  * issue, we go ahead and generate a UUID up front so that the underlying
209  * work is done before we start requesting UUIDs for real.
210  *
211  * Think of this along the same lines as initializing a singleton.
212  */
213  uuid_t uu;
214  int dev_urandom_fd;
215 
216  dev_urandom_fd = open("/dev/urandom", O_RDONLY);
217  if (dev_urandom_fd < 0) {
218  ast_log(LOG_WARNING, "It appears your system does not have /dev/urandom on it. This\n"
219  "means that UUID generation will use a pseudorandom number generator. Since\n"
220  "the thread-safety of your system's random number generator cannot\n"
221  "be guaranteed, we have to synchronize UUID generation. This may result\n"
222  "in decreased performance. It is highly recommended that you set up your\n"
223  "system to have /dev/urandom\n");
224  } else {
225  has_dev_urandom = 1;
226  close(dev_urandom_fd);
227  }
228  uuid_generate_random(uu);
229 
230  ast_debug(1, "UUID system initiated\n");
231 }
static int dev_urandom_fd
Definition: main/utils.c:792
#define LOG_WARNING
Definition: logger.h:274
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static int has_dev_urandom
Definition: uuid.c:37
uuid_t uu
Definition: uuid.c:40

◆ ast_uuid_is_nil()

int ast_uuid_is_nil ( struct ast_uuid uuid)

Check if a UUID is a nil UUID (all 0s)

Parameters
uuidUUID to check
Return values
0The UUID is not nil
non-zeroThe UUID is nil

Definition at line 189 of file uuid.c.

References ast_uuid::uu.

Referenced by AST_TEST_DEFINE().

190 {
191  return uuid_is_null(uuid->uu);
192 }
uuid_t uu
Definition: uuid.c:40

◆ ast_uuid_to_str()

char* ast_uuid_to_str ( struct ast_uuid uuid,
char *  buf,
size_t  size 
)

Convert a UUID to a string.

Parameters
uuidThe UUID to convert to a string
[out]bufThe buffer where the UUID string will be stored
sizeThe size of the buffer. Must be at least AST_UUID_STR_LEN.
Returns
The UUID string (a pointer to buf)

Definition at line 136 of file uuid.c.

References ast_assert, ast_str_to_lower(), AST_UUID_STR_LEN, and ast_uuid::uu.

Referenced by AST_TEST_DEFINE(), and ast_uuid_generate_str().

137 {
138  ast_assert(size >= AST_UUID_STR_LEN);
139  uuid_unparse(uuid->uu, buf);
140  return ast_str_to_lower(buf);
141 }
#define AST_UUID_STR_LEN
Definition: uuid.h:27
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define ast_assert(a)
Definition: utils.h:695
static force_inline char * ast_str_to_lower(char *str)
Convert a string to all lower-case.
Definition: strings.h:1268
uuid_t uu
Definition: uuid.c:40

◆ generate_uuid()

static void generate_uuid ( struct ast_uuid uuid)
static

Definition at line 52 of file uuid.c.

References ast_mutex_lock, ast_mutex_unlock, has_dev_urandom, ast_uuid::uu, and uuid_lock.

Referenced by ast_uuid_generate(), and ast_uuid_generate_str().

53 {
54  /* libuuid provides three methods of generating uuids,
55  * uuid_generate(), uuid_generate_random(), and uuid_generate_time().
56  *
57  * uuid_generate_random() creates a UUID based on random numbers. The method
58  * attempts to use either /dev/urandom or /dev/random to generate random values.
59  * If these resources are unavailable, then random numbers will be generated
60  * using C library calls to generate pseudorandom numbers.
61  * This method of generating UUIDs corresponds to section 4.4 of RFC 4122.
62  *
63  * uuid_generate_time() creates a UUID based on the current time plus
64  * a system identifier (MAC address of the ethernet interface). This
65  * method of generating UUIDs corresponds to section 4.2 of RFC 4122.
66  *
67  * uuid_generate() will check if /dev/urandom or /dev/random is available to
68  * use. If so, it will use uuid_generate_random(). Otherwise, it will use
69  * uuid_generate_time(). The idea is that it avoids using pseudorandom
70  * numbers if necessary.
71  *
72  * For our purposes, we do not use the time-based UUID at all. There are
73  * several reasons for this:
74  *
75  * 1) The time-based algorithm makes use of a daemon process (uuidd) in order
76  * to ensure that any concurrent requests for UUIDs result in unique results.
77  * Use of this daemon is a bit dodgy for a few reasons
78  *
79  * a) libuuid assumes a hardcoded location for the .pid file of the daemon.
80  * However, the daemon could already be running on the system in a different
81  * location than expected. If this is the case, then attempting to connect
82  * to the daemon will fail, and attempting to launch another instance in
83  * the expected location will also fail.
84  *
85  * b) If the daemon is not running, then the first attempt to create a
86  * time-based UUID will result in launching the daemon. Because of the hard-
87  * coded locations that libuuid assumes for the daemon, Asterisk must be
88  * run with permissions that will allow for the daemon to be launched in
89  * the expected directories.
90  *
91  * c) Once the daemon is running, concurrent requests for UUIDs are thread-safe.
92  * However, the actual launching of the daemon is not thread-safe since libuuid
93  * uses no synchronization primitives to ensure that only one thread (or process)
94  * launches the daemon.
95  *
96  * d) When libuuid launches the daemon, it sets an inactivity timer.
97  * If no UUID generation requests are issued in that time period,
98  * then the daemon will exit. If a new request should occur after the daemon
99  * exits, then the daemon will be relaunched. Given point c), we cannot
100  * necessarily guarantee the thread-safety of time-based UUID generation since
101  * we cannot necessarily guarantee the daemon is running as we expect.
102  * We could set up a watchdog thread to generate UUIDs at regular intervals to
103  * prevent the daemon from exiting, but frankly, that sucks.
104  *
105  * 2) Since the MAC address of the Ethernet interface is part of the UUID when
106  * using the time-based method, there is information leaked.
107  *
108  * Given these drawbacks, we stick to only using random UUIDs. The chance of /dev/random
109  * or /dev/urandom not existing on systems in this age is next to none.
110  */
111 
112  /* XXX Currently, we only protect this call if the user has no /dev/urandom on their system.
113  * If it turns out that there are issues with UUID generation despite the presence of
114  * /dev/urandom, then we may need to make the locking/unlocking unconditional.
115  */
116  if (!has_dev_urandom) {
118  }
119  uuid_generate_random(uuid->uu);
120  if (!has_dev_urandom) {
122  }
123 }
#define ast_mutex_lock(a)
Definition: lock.h:187
static int has_dev_urandom
Definition: uuid.c:37
static ast_mutex_t uuid_lock
Definition: uuid.c:35
uuid_t uu
Definition: uuid.c:40
#define ast_mutex_unlock(a)
Definition: lock.h:188

Variable Documentation

◆ has_dev_urandom

int has_dev_urandom
static

Definition at line 37 of file uuid.c.

Referenced by ast_uuid_init(), and generate_uuid().

◆ uuid_lock

ast_mutex_t uuid_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 35 of file uuid.c.

Referenced by generate_uuid().