static inline void *__mtype_new_list( MTYPE *mt, int count ) { MTBLANK *top, *end; uint32_t c, i; if( count <= 0 ) return NULL; c = (uint32_t) count; lock_mem( mt ); // get enough while( mt->fcount < c ) __mtype_alloc_free( mt, 0 ); top = end = mt->flist; // run down count - 1 elements for( i = c - 1; i > 0; i-- ) end = end->next; // end is now the last in the list we want mt->flist = end->next; mt->fcount -= c; unlock_mem( mt ); end->next = NULL; return (void *) top; }
static inline void __mtype_free_list( MTYPE *mt, int count, void *first, void *last ) { MTBLANK *l = (MTBLANK *) last; lock_mem( mt ); l->next = mt->flist; mt->flist = first; mt->fcount += count; unlock_mem( mt ); }
static inline void __mtype_free( MTYPE *mt, void *p ) { MTBLANK *b = (MTBLANK *) p; lock_mem( mt ); b->next = mt->flist; mt->flist = p; ++(mt->fcount); unlock_mem( mt ); }
/** * Return a new anonymous memory mapping that holds <b>sz</b> bytes. * * Memory mappings are unlike the results from malloc() in that they are * handled separately by the operating system, and as such can have different * kernel-level flags set on them. * * The "flags" argument may be zero or more of ANONMAP_PRIVATE and * ANONMAP_NOINHERIT. * * Memory returned from this function must be released with * tor_munmap_anonymous(). * * If <b>inherit_result_out</b> is non-NULL, set it to one of * INHERIT_RES_KEEP, INHERIT_RES_DROP, or INHERIT_RES_ZERO, depending on the * properties of the returned memory. * * [Note: OS people use the word "anonymous" here to mean that the memory * isn't associated with any file. This has *nothing* to do with the kind of * anonymity that Tor is trying to provide.] */ void * tor_mmap_anonymous(size_t sz, unsigned flags, inherit_res_t *inherit_result_out) { void *ptr; inherit_res_t itmp=0; if (inherit_result_out == NULL) { inherit_result_out = &itmp; } *inherit_result_out = INHERIT_RES_KEEP; #if defined(_WIN32) HANDLE mapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, /*attributes*/ PAGE_READWRITE, HIGH_SIZE_T_BYTES(sz), sz & 0xffffffff, NULL /* name */); raw_assert(mapping != NULL); ptr = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, /* Offset */ 0 /* Extend to end of mapping */); raw_assert(ptr); CloseHandle(mapping); /* mapped view holds a reference */ #elif defined(HAVE_SYS_MMAN_H) ptr = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); raw_assert(ptr != MAP_FAILED); raw_assert(ptr != NULL); #else ptr = tor_malloc_zero(sz); #endif if (flags & ANONMAP_PRIVATE) { int lock_result = lock_mem(ptr, sz); raw_assert(lock_result == 0); int nodump_result = nodump_mem(ptr, sz); raw_assert(nodump_result == 0); } if (flags & ANONMAP_NOINHERIT) { int noinherit_result = noinherit_mem(ptr, sz, inherit_result_out); raw_assert(noinherit_result == 0); } return ptr; }
static inline void *__mtype_new( MTYPE *mt ) { MTBLANK *b; lock_mem( mt ); if( !mt->fcount ) __mtype_alloc_free( mt, 0 ); b = mt->flist; mt->flist = b->next; --(mt->fcount); unlock_mem( mt ); b->next = NULL; return (void *) b; }
IOBUF *stats_report_mtype( char *name, MTYPE *mt, time_t ts, IOBUF *b ) { char *prfx = ctl->stats->self->prefix; uint32_t freec, alloc; uint64_t bytes; // grab some stats under lock // we CANNOT bprintf under lock because // one of the reported types is buffers lock_mem( mt ); bytes = (uint64_t) mt->alloc_sz * (uint64_t) mt->total; alloc = mt->total; freec = mt->fcount; unlock_mem( mt ); // and report them bprintf( "mem.%s.free %u", name, freec ); bprintf( "mem.%s.alloc %u", name, alloc ); bprintf( "mem.%s.kb %lu", name, bytes / 1024 ); return b; }
int main(int argc, char *argv[]) { unsigned char bytes[4096]; int c; bool do_not_fork = false, log_console = false, log_syslog = false; char *log_logfile = NULL; char *bytes_file = NULL; int verbose = 0; char server_type[128]; bool show_bps = false; libusb_context *ctx = NULL; libusb_device_handle *handle = NULL; std::string username, password; std::vector<std::string> hosts; int log_level = LOG_INFO; fprintf(stderr, "eb_server_Araneus_Alea v" VERSION ", (C) 2009-2015 by [email protected]\n"); while((c = getopt(argc, argv, "I:hSX:P:o:L:l:snv")) != -1) { switch(c) { case 'I': hosts.push_back(optarg); break; case 'S': show_bps = true; break; case 'X': get_auth_from_file(optarg, username, password); break; case 'P': pid_file = optarg; break; case 'v': verbose++; break; case 'o': bytes_file = optarg; break; case 's': log_syslog = true; break; case 'L': log_level = atoi(optarg); break; case 'l': log_logfile = optarg; break; case 'n': do_not_fork = true; log_console = true; break; case 'h': help(); return 0; default: help(); return 1; } } if (!hosts.empty() && (username.length() == 0 || password.length() == 0)) error_exit("please select a file with authentication parameters (username + password) using the -X switch"); if (hosts.empty() && !bytes_file) error_exit("no host to connect to or file to write to given"); (void)umask(0177); no_core(); lock_mem(bytes, sizeof bytes); set_logging_parameters(log_console, log_logfile, log_syslog, log_level); if(libusb_init(&ctx) < 0) error_exit("Error initialising Araneus Alea"); libusb_set_debug(ctx, 3); handle = libusb_open_device_with_vid_pid(ctx,USB_VENDOR_ARANEUS,USB_ARANEUS_PRODUCT_ALEA); if (!handle) error_exit("No Alea device found"); if(libusb_claim_interface(handle, 0) < 0){ error_exit("Cannot Claim Interface"); } snprintf(server_type, sizeof server_type, "eb_server_Araneus_Alea v" VERSION); if (!do_not_fork) { if (daemon(0, 0) == -1) error_exit("fork failed"); } write_pid(pid_file); protocol *p = NULL; if (!hosts.empty()) p = new protocol(&hosts, username, password, true, server_type, DEFAULT_COMM_TO); signal(SIGPIPE, SIG_IGN); signal(SIGTERM, sig_handler); signal(SIGINT , sig_handler); signal(SIGQUIT, sig_handler); init_showbps(); set_showbps_start_ts(); for(;!do_exit;) { if (libusb_bulk_transfer(handle, (1 | LIBUSB_ENDPOINT_IN), (unsigned char *)bytes, sizeof bytes, &c, TIMEOUT) < 0) error_exit("Failed to retrieve random bytes from device %x", c); //////// if (show_bps) update_showbps(sizeof bytes); if (bytes_file) emit_buffer_to_file(bytes_file, bytes, sizeof bytes); if (!hosts.empty() && p -> message_transmit_entropy_data(bytes, sizeof bytes, &do_exit) == -1) { dolog(LOG_INFO, "connection closed"); p -> drop(); } set_showbps_start_ts(); } delete p; memset(bytes, 0x00, sizeof bytes); unlink(pid_file); return 0; }
void main_loop(std::vector<std::string> * hosts, char *bytes_file, char show_bps, std::string username, std::string password, const char *cdevice) { int n_to_do, bits_out=0, loop; char *dummy; static short psl=0, psr=0; /* previous samples */ static char a=1; /* alternater */ unsigned char byte_out=0; int input_buffer_size; char *input_buffer; snd_pcm_t *chandle; snd_pcm_format_t format; int err; unsigned char bytes[4096]; // 4096 * 8: 9992, must be less then 9999 int bytes_out = 0; char server_type[128]; snprintf(server_type, sizeof server_type, "eb_server_audio v" VERSION " %s", cdevice); protocol *p = NULL; if (!hosts -> empty()) p = new protocol(hosts, username, password, true, server_type, DEFAULT_COMM_TO); lock_mem(bytes, sizeof bytes); recover_sound_dev(&chandle, false, cdevice, &format); init_showbps(); set_showbps_start_ts(); for(;!do_exit;) { char got_any = 0; input_buffer_size = snd_pcm_frames_to_bytes(chandle, DEFAULT_SAMPLE_RATE * 2); input_buffer = reinterpret_cast<char *>(malloc_locked(input_buffer_size)); if (!input_buffer) error_exit("problem allocating %d bytes of memory", input_buffer_size); /* Discard the first data read */ /* it often contains weird looking data - probably a click from */ /* driver loading / card initialisation */ snd_pcm_sframes_t garbage_frames_read = snd_pcm_readi(chandle, input_buffer, DEFAULT_SAMPLE_RATE); /* Make sure we aren't hitting a disconnect/suspend case */ if (garbage_frames_read < 0) { dolog(LOG_INFO, "snd_pcm_readi: failed retrieving audio", snd_strerror(garbage_frames_read)); // FIXME if ((err = snd_pcm_recover(chandle, garbage_frames_read, 0)) < 0) { dolog(LOG_INFO, "snd_pcm_recover fail : %s", snd_strerror(err)); dolog(LOG_INFO, "Failure retrieving sound from soundcard, re-opening device"); recover_sound_dev(&chandle, true, cdevice, &format); } } /* Read a buffer of audio */ n_to_do = DEFAULT_SAMPLE_RATE * 2; dummy = input_buffer; while (n_to_do > 0 && !do_exit) { snd_pcm_sframes_t frames_read = snd_pcm_readi(chandle, dummy, n_to_do); /* Make sure we aren't hitting a disconnect/suspend case */ if (frames_read < 0) frames_read = snd_pcm_recover(chandle, frames_read, 0); /* Nope, something else is wrong. Bail. */ if (frames_read == -1) { if ((err = snd_pcm_recover(chandle, frames_read, 0)) < 0) { dolog(LOG_INFO, "snd_pcm_recover fail : %s", snd_strerror(err)); dolog(LOG_INFO, "Failure retrieving sound from soundcard, re-opening device"); recover_sound_dev(&chandle, true, cdevice, &format); } } else { n_to_do -= frames_read; dummy += frames_read; } } /* de-biase the data */ for(loop=0; loop<(DEFAULT_SAMPLE_RATE * 2/*16bits*/ * 2/*stereo*/ * 2) && !do_exit; loop+=8) { int w1, w2, w3, w4, o1, o2; if (format == SND_PCM_FORMAT_S16_BE) { w1 = (input_buffer[loop+0]<<8) + input_buffer[loop+1]; w2 = (input_buffer[loop+2]<<8) + input_buffer[loop+3]; w3 = (input_buffer[loop+4]<<8) + input_buffer[loop+5]; w4 = (input_buffer[loop+6]<<8) + input_buffer[loop+7]; } else { w1 = (input_buffer[loop+1]<<8) + input_buffer[loop+0]; w2 = (input_buffer[loop+3]<<8) + input_buffer[loop+2]; w3 = (input_buffer[loop+5]<<8) + input_buffer[loop+4]; w4 = (input_buffer[loop+7]<<8) + input_buffer[loop+6]; } /* Determine order of channels for each sample, subtract previous sample * to compensate for unbalanced audio devices */ o1 = order(w1-psl, w2-psr); o2 = order(w3-psl, w4-psr); if (a > 0) { psl = w3; psr = w4; } else { psl = w1; psr = w2; } /* If both samples have the same order, there is bias in the samples, so we * discard them; if both channels are equal on either sample, we discard * them too; additionally, alternate the sample we'll use next (even more * bias removal) */ if (o1 == o2 || o1 < 0 || o2 < 0) { a = -a; } else { /* We've got a random bit; the bit is either the order from the first or * the second sample, determined by the alternator 'a' */ char bit = (a > 0) ? o1 : o2; byte_out <<= 1; byte_out += bit; bits_out++; got_any = 1; if (bits_out>=8) { bytes[bytes_out++] = byte_out; if (bytes_out == sizeof bytes) { if (show_bps) update_showbps(sizeof bytes); if (bytes_file) emit_buffer_to_file(bytes_file, bytes, bytes_out); if (p && p -> message_transmit_entropy_data(bytes, bytes_out) == -1) { dolog(LOG_INFO, "connection closed"); p -> drop(); } set_showbps_start_ts(); bytes_out = 0; } bits_out = 0; } } } if (!got_any) dolog(LOG_WARNING, "no bits in audio-stream, please make sure the recording channel is not muted"); free_locked(input_buffer, input_buffer_size); } unlock_mem(bytes, sizeof bytes); if (!do_exit) snd_pcm_close(chandle); delete p; }
int main(int argc, char *argv[]) { unsigned char bytes[4096]; unsigned char cur_byte = 0; int bits = 0; int c; bool do_not_fork = false, log_console = false, log_syslog = false; char *log_logfile = NULL; char *bytes_file = NULL; bool show_bps = false; std::string username, password; std::vector<std::string> hosts; int log_level = LOG_INFO; fprintf(stderr, "%s, (C) 2009-2015 by [email protected]\n", server_type); while((c = getopt(argc, argv, "hX:P:So:I:L:l:sn")) != -1) { switch(c) { case 'X': get_auth_from_file(optarg, username, password); break; case 'P': pid_file = optarg; break; case 'S': show_bps = true; break; case 'o': bytes_file = optarg; break; case 'I': hosts.push_back(optarg); break; case 's': log_syslog = true; break; case 'L': log_level = atoi(optarg); break; case 'l': log_logfile = optarg; break; case 'n': do_not_fork = true; log_console = true; break; case 'h': help(); return 0; default: help(); return 1; } } if (!hosts.empty() && (username.length() == 0 || password.length() == 0)) error_exit("please select a file with authentication parameters (username + password) using the -X switch"); if (hosts.empty() && !bytes_file) error_exit("no host to connect to or file to write to given"); (void)umask(0177); no_core(); lock_mem(bytes, sizeof bytes); set_logging_parameters(log_console, log_logfile, log_syslog, log_level); if (!do_not_fork && !show_bps) { if (daemon(0, 0) == -1) error_exit("fork failed"); } write_pid(pid_file); protocol *p = NULL; if (!hosts.empty()) p = new protocol(&hosts, username, password, true, server_type, DEFAULT_COMM_TO); signal(SIGPIPE, SIG_IGN); signal(SIGTERM, sig_handler); signal(SIGINT , sig_handler); signal(SIGQUIT, sig_handler); struct libusb_device **devs = NULL; libusb_device_handle **devhs; int index = 0, n = 0, use_n = 0; if (libusb_init(NULL) < 0) error_exit("cannot init libusb"); if (libusb_get_device_list(NULL, &devs) < 0) error_exit("cannot retrieve usb devicelist"); while(devs[n] != NULL) { n++; } dolog(LOG_INFO, "Found %d devices", n); devhs = (libusb_device_handle **)malloc(sizeof(libusb_device_handle *) * n); for(index=0; index<n; index++) { uint8_t bus_nr = libusb_get_bus_number(devs[index]); uint8_t dev_nr = libusb_get_device_address(devs[index]); struct libusb_device_descriptor desc; libusb_get_device_descriptor(devs[index], &desc); dolog(LOG_INFO, "Opening device %d: %d/%d %04x:%04x", index, bus_nr, dev_nr, desc.idVendor, desc.idProduct); if (desc.idVendor == 0x1d6b) // ignore continue; if (libusb_open(devs[index], &devhs[use_n++]) != 0) error_exit("error getting usb handle"); } dolog(LOG_INFO, "Using %d devices", use_n); if (use_n == 0) error_exit("no devices found which can be used"); init_showbps(); set_showbps_start_ts(); int dev_index = 0; for(;!do_exit;) { // gather random data double t1 = gen_entropy_data(devhs[dev_index]), t2 = gen_entropy_data(devhs[dev_index]); if (++dev_index >= use_n) dev_index = 0; if (t1 == t2) continue; cur_byte <<= 1; if (t1 > t2) cur_byte |= 1; if (++bits == 8) { bytes[index++] = cur_byte; bits = 0; if (index == sizeof bytes) { if (show_bps) update_showbps(sizeof bytes); if (bytes_file) emit_buffer_to_file(bytes_file, bytes, index); if (p && p -> message_transmit_entropy_data(bytes, index, &do_exit) == -1) { dolog(LOG_INFO, "connection closed"); p -> drop(); } set_showbps_start_ts(); index = 0; // skip header } } } memset(bytes, 0x00, sizeof bytes); for(index=0; index<n; index++) libusb_close(devhs[index]); libusb_free_device_list(devs, 1); libusb_exit(NULL); free(devhs); unlink(pid_file); return 0; }
int main(int argc, char *argv[]) { unsigned char bytes[4096]; int bits = 0, index = 0; int c; bool do_not_fork = false, log_console = false, log_syslog = false; char *log_logfile = NULL; char *bytes_file = NULL; bool show_bps = false; std::string username, password; std::vector<std::string> hosts; int log_level = LOG_INFO; fprintf(stderr, "%s, (C) 2009-2015 by [email protected]\n", server_type); while((c = getopt(argc, argv, "I:hX:P:So:L:l:sn")) != -1) { switch(c) { case 'X': get_auth_from_file(optarg, username, password); break; case 'P': pid_file = optarg; break; case 'S': show_bps = true; break; case 'o': bytes_file = optarg; break; case 'I': hosts.push_back(optarg); break; case 's': log_syslog = true; break; case 'L': log_level = atoi(optarg); break; case 'l': log_logfile = optarg; break; case 'n': do_not_fork = true; log_console = true; break; case 'h': help(); return 0; default: help(); return 1; } } if (!hosts.empty() && (username.length() == 0 || password.length() == 0)) error_exit("please select a file with authentication parameters (username + password) using the -X switch"); if (hosts.empty() && !bytes_file) error_exit("no host to connect to or file to write to given"); (void)umask(0177); no_core(); lock_mem(bytes, sizeof bytes); set_logging_parameters(log_console, log_logfile, log_syslog, log_level); if (!do_not_fork && !show_bps) { if (daemon(0, 0) == -1) error_exit("fork failed"); } write_pid(pid_file); signal(SIGPIPE, SIG_IGN); signal(SIGTERM, sig_handler); signal(SIGINT , sig_handler); signal(SIGQUIT, sig_handler); protocol *p = NULL; if (!hosts.empty()) p = new protocol(&hosts, username, password, true, server_type, DEFAULT_COMM_TO); int slp = get_clock_res(); dolog(LOG_INFO, "resolution of clock is %dns", slp); init_showbps(); set_showbps_start_ts(); unsigned char cur_byte = 0; int equal_cnt = 0; for(;!do_exit;) { // gather random data double t1 = gen_entropy_data(slp), t2 = gen_entropy_data(slp); if (t1 == t2) { equal_cnt++; if (equal_cnt > 5 && slp < 1000) { dolog(LOG_DEBUG, "increasing sleep to %dns", slp); slp++; } continue; } equal_cnt = 0; cur_byte <<= 1; if (t1 >= t2) cur_byte |= 1; if (++bits == 8) { bytes[index++] = cur_byte; bits = 0; if (index == sizeof bytes) { if (show_bps) update_showbps(sizeof bytes); if (bytes_file) emit_buffer_to_file(bytes_file, bytes, index); if (p && p -> message_transmit_entropy_data(bytes, index, &do_exit) == -1) { dolog(LOG_INFO, "connection closed"); p -> drop(); } set_showbps_start_ts(); index = 0; // skip header } } } memset(bytes, 0x00, sizeof bytes); unlink(pid_file); delete p; return 0; }
int main(int argc, char *argv[]) { unsigned char bytes[BLOCK_SIZE]; int read_fd = -1; int c; bool do_not_fork = false, log_console = false, log_syslog = false; char *log_logfile = NULL; char *device = NULL; char *serial = NULL; char *bytes_file = NULL; bool show_bps = false; std::string username, password; std::vector<std::string> hosts; int log_level = LOG_INFO; fprintf(stderr, "%s, (C) 2009-2015 by [email protected]\n", server_type); while((c = getopt(argc, argv, "hSX:P:o:p:I:d:L:l:sn")) != -1) { switch(c) { case 'S': show_bps = true; break; case 'X': get_auth_from_file(optarg, username, password); break; case 'P': pid_file = optarg; break; case 'o': bytes_file = optarg; break; case 'p': serial = optarg; break; case 'I': hosts.push_back(optarg); break; case 'd': device = optarg; break; case 's': log_syslog = true; break; case 'L': log_level = atoi(optarg); break; case 'l': log_logfile = optarg; break; case 'n': do_not_fork = true; log_console = true; break; case 'h': help(); return 0; default: help(); return 1; } } if (!hosts.empty() && (username.length() == 0 || password.length() == 0)) error_exit("please select a file with authentication parameters (username + password) using the -X switch"); if (hosts.empty() && !bytes_file) error_exit("no host to connect to or file to write to given"); set_logging_parameters(log_console, log_logfile, log_syslog, log_level); if (device) read_fd = open(device, O_RDONLY); if (read_fd == -1) error_exit("error opening %s", device); if (serial) set_serial_parameters(read_fd, serial); (void)umask(0177); no_core(); lock_mem(bytes, sizeof bytes); if (!do_not_fork) { if (daemon(0, 0) == -1) error_exit("fork failed"); } protocol *p = NULL; if (!hosts.empty()) p = new protocol(&hosts, username, password, true, server_type, DEFAULT_COMM_TO); write_pid(pid_file); signal(SIGPIPE, SIG_IGN); signal(SIGTERM, sig_handler); signal(SIGINT , sig_handler); signal(SIGQUIT, sig_handler); init_showbps(); set_showbps_start_ts(); for(;!do_exit;) { if (READ(read_fd, bytes, BLOCK_SIZE, &do_exit) != BLOCK_SIZE) error_exit("error reading from input"); if (show_bps) update_showbps(BLOCK_SIZE); if (bytes_file) emit_buffer_to_file(bytes_file, bytes, BLOCK_SIZE); if (p && p -> message_transmit_entropy_data(bytes, BLOCK_SIZE, &do_exit) == -1) { dolog(LOG_INFO, "connection closed"); p -> drop(); } set_showbps_start_ts(); } memset(bytes, 0x00, sizeof bytes); unlink(pid_file); delete p; return 0; }
int main(int argc, char *argv[]) { int dev_random_fd = open(DEV_RANDOM, O_RDWR); const int max_bits_in_kernel_rng = kernel_rng_get_max_entropy_count(); const int write_threshold = kernel_rng_get_write_threshold(); int c; bool do_not_fork = false, log_console = false, log_syslog = false; char *log_logfile = NULL; std::string username, password; int interval = -1; std::vector<std::string> hosts; int log_level = LOG_INFO; printf("eb_client_linux_kernel v" VERSION ", (C) 2009-2017 by [email protected]\n"); while((c = getopt(argc, argv, "b:hX:P:I:L:l:sn")) != -1) { switch(c) { case 'b': interval = atof(optarg); if (interval < 1) error_exit("Interval must be > 0"); break; case 'X': get_auth_from_file(optarg, username, password); break; case 'P': pid_file = optarg; break; case 'I': hosts.push_back(optarg); break; case 's': log_syslog = true; break; case 'L': log_level = atoi(optarg); break; case 'l': log_logfile = optarg; break; case 'n': do_not_fork = true; log_console = true; break; default: help(); return 1; } } if (username.length() == 0 || password.length() == 0) error_exit("please select a file with authentication parameters (username + password) using the -X switch"); if (hosts.empty()) error_exit("no host to connect to selected"); set_logging_parameters(log_console, log_logfile, log_syslog, log_level); if (!do_not_fork) { if (daemon(0, 0) == -1) error_exit("fork failed"); } protocol *p = new protocol(&hosts, username, password, false, client_type, DEFAULT_COMM_TO); (void)umask(0177); no_core(); write_pid(pid_file); signal(SIGPIPE, SIG_IGN); signal(SIGTERM, sig_handler); signal(SIGINT , sig_handler); signal(SIGQUIT, sig_handler); dolog(LOG_INFO, "started with %d bits in kernel rng", kernel_rng_get_entropy_count()); if (dev_random_fd == -1) error_exit("failed to open %s", DEV_RANDOM); bit_count_estimator bce(BCE_SHANNON); for(;!do_exit;) { struct timeval tv, *ptv = NULL; if (interval > 0) { tv.tv_sec = interval / 1000; tv.tv_usec = int(interval * 1000) % 1000; ptv = &tv; } // wait for /dev/random te become writable which means the entropy- // level dropped below a certain threshold fd_set write_fd; FD_ZERO(&write_fd); FD_SET(dev_random_fd, &write_fd); dolog(LOG_DEBUG, "wait for low-event"); for(;!do_exit;) { int rc = select(dev_random_fd + 1, NULL, &write_fd, NULL, ptv); printf("%d\n", rc); if (rc >= 0) break; if (errno != EINTR && errno != EAGAIN) error_exit("Select error: %m"); } if (do_exit) break; int n_bits_in_kernel_rng = kernel_rng_get_entropy_count(); dolog(LOG_DEBUG, "kernel rng bit count: %d", n_bits_in_kernel_rng); if (n_bits_in_kernel_rng < write_threshold) { /* find out how many bits to add */ int n_bits_to_get = max_bits_in_kernel_rng - n_bits_in_kernel_rng; if (n_bits_to_get <= 0) { dolog(LOG_DEBUG, "number of bits to get <= 0: %d", n_bits_to_get); continue; } if (n_bits_to_get > 9999) n_bits_to_get = 9999; if (n_bits_to_get < 8) n_bits_to_get = 8; dolog(LOG_INFO, "%d bits left (%d max), will get %d bits", n_bits_in_kernel_rng, max_bits_in_kernel_rng, n_bits_to_get); int n_bytes_to_get = (n_bits_to_get + 7) / 8; unsigned char *buffer = static_cast<unsigned char *>(malloc(n_bytes_to_get)); if (!buffer) error_exit("out of memory allocating %d bytes", n_bytes_to_get); lock_mem(buffer, n_bytes_to_get); int n_bytes = p -> request_bytes(buffer, n_bits_to_get, false, &do_exit); if (do_exit) break; int is_n_bits = bce.get_bit_count(reinterpret_cast<unsigned char *>(buffer), n_bytes); int rc = kernel_rng_add_entropy(reinterpret_cast<unsigned char *>(buffer), n_bytes, is_n_bits); if (rc == -1) error_exit("error submiting entropy data to kernel"); dolog(LOG_DEBUG, "new entropy count: %d", kernel_rng_get_entropy_count()); memset(buffer, 0x00, n_bytes_to_get); unlock_mem(buffer, n_bytes_to_get); free(buffer); } } unlink(pid_file); delete p; return 0; }