예제 #1
0
파일: mem.c 프로젝트: ghostflame/ministry
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;
}
예제 #2
0
파일: mem.c 프로젝트: ghostflame/ministry
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 );
}
예제 #3
0
파일: mem.c 프로젝트: ghostflame/ministry
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 );
}
예제 #4
0
파일: mem.c 프로젝트: ghostflame/ministry
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;
}
예제 #5
0
파일: stats.c 프로젝트: ant1441/ministry
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;
}
예제 #6
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;
}
예제 #7
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;
}