diff --git a/src/iperf_api.c b/src/iperf_api.c index 2813eb8..9a264d1 100755 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -3169,9 +3169,6 @@ iperf_new_stream(struct iperf_test *test, int s) free(sp); return NULL; } - srandom(time(NULL)); - for (i = 0; i < test->settings->blksize; ++i) - sp->buffer[i] = random(); /* Set socket */ sp->socket = s; @@ -3196,7 +3193,8 @@ iperf_new_stream(struct iperf_test *test, int s) sp->diskfile_fd = -1; /* Initialize stream */ - if (iperf_init_stream(sp, test) < 0) { + if ((readentropy(sp->buffer, test->settings->blksize) < 0) || + (iperf_init_stream(sp, test) < 0)) { close(sp->buffer_fd); munmap(sp->buffer, sp->test->settings->blksize); free(sp->result); diff --git a/src/iperf_util.c b/src/iperf_util.c index 67981fb..5e35187 100644 --- a/src/iperf_util.c +++ b/src/iperf_util.c @@ -45,6 +45,37 @@ #include #include "cjson.h" +#include "iperf.h" +#include "iperf_api.h" + +/* + * Read entropy from /dev/urandom + * Errors are fatal. + * Returns 0 on success. + */ +int readentropy(void *out, size_t outsize) +{ + static FILE *frandom; + static const char rndfile[] = "/dev/urandom"; + + if (!outsize) return 0; + + if (frandom == NULL) { + frandom = fopen(rndfile, "rb"); + if (frandom == NULL) { + iperf_errexit(NULL, "error - failed to open %s: %s\n", + rndfile, strerror(errno)); + } + setbuf(frandom, NULL); + } + if (fread(out, 1, outsize, frandom) != outsize) { + iperf_errexit(NULL, "error - failed to read %s: %s\n", + rndfile, + feof(frandom) ? "EOF" : strerror(errno)); + } + return 0; +} + /* make_cookie * @@ -53,27 +84,21 @@ * Iperf uses this function to create test "cookies" which * server as unique test identifiers. These cookies are also * used for the authentication of stream connections. + * Assumes cookie has size (COOKIE_SIZE + 1) char's. */ void make_cookie(char *cookie) { - static int randomized = 0; - char hostname[500]; - struct timeval tv; - char temp[1000]; + unsigned char *out = (unsigned char*)cookie; + size_t pos; + static const unsigned char rndchars[] = "abcdefghijklmnopqrstuvwxyz234567"; - if ( ! randomized ) - srandom((int) time(0) ^ getpid()); - - /* Generate a string based on hostname, time, randomness, and filler. */ - (void) gethostname(hostname, sizeof(hostname)); - (void) gettimeofday(&tv, 0); - (void) snprintf(temp, sizeof(temp), "%s.%ld.%06ld.%08lx%08lx.%s", hostname, (unsigned long int) tv.tv_sec, (unsigned long int) tv.tv_usec, (unsigned long int) random(), (unsigned long int) random(), "1234567890123456789012345678901234567890"); - - /* Now truncate it to 36 bytes and terminate. */ - memcpy(cookie, temp, 36); - cookie[36] = '\0'; + readentropy(out, COOKIE_SIZE); + for (pos = 0; pos < (COOKIE_SIZE - 1); pos++) { + out[pos] = rndchars[out[pos] % (sizeof(rndchars) - 1)]; + } + out[pos] = '\0'; } diff --git a/src/iperf_util.h b/src/iperf_util.h index e422a11..59df2e2 100644 --- a/src/iperf_util.h +++ b/src/iperf_util.h @@ -29,6 +29,9 @@ #include "cjson.h" #include +#include + +int readentropy(void *out, size_t outsize); void make_cookie(char *);