0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #include <ndrstandard.h>
0039 #include <sys/stat.h>
0040 #include <unistd.h>
0041 #include <fcntl.h>
0042 #include <stdlib.h>
0043
0044 #include <ndebug.h>
0045 #include <sys/time.h>
0046 #include <nstdutil.h>
0047
0048
0049
0050
0051
0052
0053
0054 exprivate MUTEX_LOCKDECL(M_uuid_lock);
0055 exprivate volatile unsigned int M_seedp;
0056 exprivate volatile unsigned int M_counter;
0057 exprivate volatile unsigned int M_init_done=EXFALSE;
0058
0059
0060
0061
0062
0063
0064
0065
0066 exprivate int ndrx_get_rnd_bytes(unsigned char *output, size_t len)
0067 {
0068 int ret = EXSUCCEED;
0069 int fd=EXFAIL, flags, i;
0070
0071 fd = open("/dev/urandom", O_RDONLY);
0072
0073 if (fd == EXFAIL)
0074 {
0075 fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
0076 }
0077
0078 if (fd >= 0)
0079 {
0080 flags = fcntl(fd, F_GETFD);
0081
0082 if (flags >= 0)
0083 {
0084 fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
0085 }
0086 }
0087 else
0088 {
0089 EXFAIL_OUT(ret);
0090 }
0091
0092 for (i=0; i<len; i++)
0093 {
0094 output[i]=0;
0095 if (EXSUCCEED!=read(fd, output+i, 1))
0096 {
0097
0098 }
0099
0100 }
0101
0102 out:
0103
0104 if (EXFAIL!=fd)
0105 {
0106 close(fd);
0107 }
0108
0109 return ret;
0110 }
0111
0112
0113
0114
0115 expublic void ndrx_rand_seedset(unsigned int *seed)
0116 {
0117 struct timeval tv;
0118 unsigned char buf[sizeof(*seed)];
0119 int i;
0120 char *p;
0121
0122 gettimeofday(&tv, 0);
0123 *seed = (getpid() << 16) ^ getuid() ^ (unsigned int)tv.tv_sec ^ (unsigned int)tv.tv_usec;
0124
0125
0126 if (EXSUCCEED==ndrx_get_rnd_bytes(buf, sizeof(*seed)))
0127 {
0128 p = (char *)seed;
0129 for (i=0; i<sizeof(*seed); i++)
0130 {
0131 p[i] = p[i] ^ buf[i];
0132 }
0133 }
0134 }
0135
0136
0137
0138
0139 exprivate void ndrx_cid_init(void)
0140 {
0141 unsigned int locl_seedp;
0142 unsigned char buf[sizeof(unsigned int)];
0143 unsigned char *p;
0144 int i;
0145
0146 ndrx_rand_seedset(&locl_seedp);
0147 M_counter = rand_r(&locl_seedp);
0148
0149
0150 if (EXSUCCEED==ndrx_get_rnd_bytes(buf, sizeof(unsigned int)))
0151 {
0152 p = (unsigned char *)&M_counter;
0153 for (i=0; i<sizeof(unsigned int); i++)
0154 {
0155 p[i] = p[i] ^ buf[i];
0156 }
0157 }
0158 M_seedp = locl_seedp;
0159 }
0160
0161
0162
0163
0164
0165
0166 expublic void ndrx_cid_generate(unsigned char prefix, exuuid_t out)
0167 {
0168 int i;
0169 unsigned int counter;
0170 unsigned short rnd;
0171 char *out_p = (char *)out;
0172 unsigned pid = getpid();
0173 struct timeval tv;
0174 unsigned int locl_seedp;
0175
0176
0177 if (!M_init_done)
0178 {
0179 MUTEX_LOCK_V(M_uuid_lock);
0180 if (!M_init_done)
0181 {
0182 ndrx_cid_init();
0183 M_init_done = EXTRUE;
0184 }
0185 MUTEX_UNLOCK_V(M_uuid_lock);
0186 }
0187
0188
0189 out_p[0] = prefix;
0190
0191
0192 out_p[1] = (pid >>24) & 0xff;
0193 out_p[2] = (pid >>16) & 0xff;
0194 out_p[3] = (pid >>8) & 0xff;
0195 out_p[4] = (pid) & 0xff;
0196
0197
0198 MUTEX_LOCK_V(M_uuid_lock);
0199
0200 M_counter++;
0201 counter = M_counter;
0202
0203 locl_seedp=M_seedp;
0204
0205 rnd=0;
0206 for (i=0; i<sizeof(rnd); i++)
0207 {
0208 rnd<<=8;
0209 rnd|=rand_r(&locl_seedp) & 0xff;
0210 }
0211
0212 M_seedp=locl_seedp;
0213
0214 MUTEX_UNLOCK_V(M_uuid_lock);
0215
0216
0217 gettimeofday(&tv, 0);
0218
0219
0220
0221
0222
0223
0224 out_p[5] = (tv.tv_usec >>7) & 0xff;
0225 out_p[6] = (counter >>16) & 0xff;
0226 out_p[7] = (counter >>8) & 0xff;
0227 out_p[8] = (counter) & 0xff;
0228
0229
0230 gettimeofday(&tv, 0);
0231
0232
0233
0234
0235 out_p[9] = (tv.tv_usec & 0xfe) | ((tv.tv_sec >>32) & 0xff);
0236 out_p[10] = (tv.tv_sec >>24) & 0xff;
0237 out_p[11] = (tv.tv_sec >>16) & 0xff;
0238 out_p[12] = (tv.tv_sec >>8) & 0xff;
0239 out_p[13] = (tv.tv_sec) & 0xff;
0240
0241
0242 out_p[14] = (rnd >> 8) & 0xff;
0243 out_p[15] = (rnd) & 0xff;
0244 }
0245
0246