Пример #1
0
static int handle_request(struct mg_connection *conn)
{
	static const char *PONG_STR =
		"{\"version\" : \"brubeck %s\", \"pid\" : %d, \"status\" : \"%s\"}\n";

	if (!strcmp(conn->request_method, "GET")) {
		if (!strcmp(conn->uri, "/ping")) {
			struct brubeck_server *brubeck = conn->server_param;
			const char *status = "OK";

			if (brubeck->at_capacity)
				status = "CAPACITY";
			if (!brubeck->running)
				status = "SHUTDOWN";

			send_headers(conn);
			mg_printf_data(conn, PONG_STR, GIT_SHA, getpid(), status);
			return MG_TRUE;
		}

		if (!strcmp(conn->uri, "/stats"))
			return send_stats(conn);

		if (starts_with(conn->uri, "/metric/"))
			return send_metric(conn);
	}

	if (!strcmp(conn->request_method, "POST")) {
		if (starts_with(conn->uri, "/expire/"))
			return expire_metric(conn);
	}

	return MG_FALSE;
}
Пример #2
0
static int
handle_request(void *cls, struct MHD_Connection *connection,
               const char *url, const char *method,
               const char *version, const char *upload_data,
               size_t *upload_data_size, void **con_cls)
{
    int ret;
    struct MHD_Response *response = NULL;
    struct brubeck_server *brubeck = cls;

    if (!strcmp(method, "GET")) {
        if (!strcmp(url, "/ping")) {
            char *jsonr;
            json_t *pong = json_pack("{s:s, s:i, s:s}",
                                     "version", "brubeck " GIT_SHA,
                                     "pid", (int)getpid(),
                                     "status", "OK");

            jsonr = json_dumps(pong, JSON_PRESERVE_ORDER);
            response = MHD_create_response_from_data(strlen(jsonr), jsonr, 1, 0);
            json_decref(pong);
        }

        else if (!strcmp(url, "/stats"))
            response = send_stats(brubeck);

        else if (starts_with(url, "/metric/"))
            response = send_metric(brubeck, url);
    }
    else if (!strcmp(method, "POST")) {
        if (starts_with(url, "/expire/"))
            response = expire_metric(brubeck, url);
    }

    if (!response) {
        static const char *NOT_FOUND = "404 not found";
        response = MHD_create_response_from_data(
                       strlen(NOT_FOUND), (void *)NOT_FOUND, 0, 0);
        MHD_add_response_header(response, "Connection", "close");
        ret = MHD_queue_response(connection, 404, response);
    } else {
        MHD_add_response_header(response, "Connection", "close");
        MHD_add_response_header(response, "Content-Type", "application/json");
        ret = MHD_queue_response(connection, 200, response);
    }

    MHD_destroy_response(response);
    return ret;
}
Пример #3
0
int main(int argc, char **argv)
{
	int opt;
	int do_list = 0;
	char *do_load = NULL;

	while ((opt = getopt(argc, argv, "h?b:lf:a:n:kR:B:")) != EOF) {
		switch (opt) {
	        case 'b':
			dbname = optarg;
			break;
		case 'f':
			if (do_load) {
				fprintf(stderr, "Duplicate option -f\n");
				usage();
			}
			do_load = optarg;
			break;
		case 'l':
			do_list = 1;
			break;
		case 'a':
			active_probing = atoi(optarg);
			break;
		case 'n':
			negative_timeout = atoi(optarg);
			break;
		case 'k':
			no_kernel_broadcasts = 1;
			break;
		case 'R':
			if ((broadcast_rate = atoi(optarg)) <= 0 ||
			    (broadcast_rate = 1000/broadcast_rate) <= 0) {
				fprintf(stderr, "Invalid ARP rate\n");
				exit(-1);
			}
			break;
		case 'B':
			if ((broadcast_burst = atoi(optarg)) <= 0 ||
			    (broadcast_burst = 1000*broadcast_burst) <= 0) {
				fprintf(stderr, "Invalid ARP burst\n");
				exit(-1);
			}
			break;
		case 'h':
		case '?':
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (argc > 0) {
		ifnum = argc;
		ifnames = argv;
		ifvec = malloc(argc*sizeof(int));
		if (!ifvec) {
			perror("malloc");
			exit(-1);
		}
	}

	if ((udp_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("socket");
		exit(-1);
	}

        if (ifnum) {
		int i;
		struct ifreq ifr;
		memset(&ifr, 0, sizeof(ifr));
		for (i=0; i<ifnum; i++) {
			strncpy(ifr.ifr_name, ifnames[i], IFNAMSIZ);
			if (ioctl(udp_sock, SIOCGIFINDEX, &ifr)) {
				perror("ioctl(SIOCGIFINDEX)");
				exit(-1);;
			}
			ifvec[i] = ifr.ifr_ifindex;
		}
	}

	dbase = dbopen(dbname, O_CREAT|O_RDWR, 0644, DB_HASH, NULL);
	if (dbase == NULL) {
		perror("db_open");
		exit(-1);
	}

	if (do_load) {
		char buf[128];
		FILE *fp;
		struct dbkey k;
		DBT dbkey, dbdat;

		dbkey.data = &k;
		dbkey.size = sizeof(k);

		if (strcmp(do_load, "-") == 0 || strcmp(do_load, "--") == 0) {
			fp = stdin;
		} else if ((fp = fopen(do_load, "r")) == NULL) {
			perror("fopen");
			goto do_abort;
		}

		buf[sizeof(buf)-1] = 0;
		while (fgets(buf, sizeof(buf)-1, fp)) {
			__u8 b1[6];
			char ipbuf[128];
			char macbuf[128];

			if (buf[0] == '#')
				continue;

			if (sscanf(buf, "%u%s%s", &k.iface, ipbuf, macbuf) != 3) {
				fprintf(stderr, "Wrong format of input file \"%s\"\n", do_load);
				goto do_abort;
			}
			if (strncmp(macbuf, "FAILED:", 7) == 0)
				continue;
			if (!inet_aton(ipbuf, (struct in_addr*)&k.addr)) {
				fprintf(stderr, "Invalid IP address: \"%s\"\n", ipbuf);
				goto do_abort;
			}

			dbdat.data = hexstring_a2n(macbuf, b1, 6);
			if (dbdat.data == NULL)
				goto do_abort;
			dbdat.size = 6;

			if (dbase->put(dbase, &dbkey, &dbdat, 0)) {
				perror("hash->put");
				goto do_abort;
			}
		}
		dbase->sync(dbase, 0);
		if (fp != stdin)
			fclose(fp);
	}

	if (do_list) {
		DBT dbkey, dbdat;
		printf("%-8s %-15s %s\n", "#Ifindex", "IP", "MAC");
		while (dbase->seq(dbase, &dbkey, &dbdat, R_NEXT) == 0) {
			struct dbkey *key = dbkey.data;
			if (handle_if(key->iface)) {
				if (!IS_NEG(dbdat.data)) {
					char b1[18];
					printf("%-8d %-15s %s\n",
					       key->iface,
					       inet_ntoa(*(struct in_addr*)&key->addr),
					       hexstring_n2a(dbdat.data, 6, b1, 18));
				} else {
					printf("%-8d %-15s FAILED: %dsec ago\n",
					       key->iface,
					       inet_ntoa(*(struct in_addr*)&key->addr),
					       NEG_AGE(dbdat.data));
				}
			}
		}
	}

	if (do_load || do_list)
		goto out;

	pset[0].fd = socket(PF_PACKET, SOCK_DGRAM, 0);
	if (pset[0].fd < 0) {
		perror("socket");
		exit(-1);
	}

	if (1) {
		struct sockaddr_ll sll;
		memset(&sll, 0, sizeof(sll));
		sll.sll_family = AF_PACKET;
		sll.sll_protocol = htons(ETH_P_ARP);
		sll.sll_ifindex = (ifnum == 1 ? ifvec[0] : 0);
		if (bind(pset[0].fd, (struct sockaddr*)&sll, sizeof(sll)) < 0) {
			perror("bind");
			goto do_abort;
		}
	}

	if (rtnl_open(&rth, RTMGRP_NEIGH) < 0) {
		perror("rtnl_open");
		goto do_abort;
	}
	pset[1].fd = rth.fd;

	load_initial_table();

	if (daemon(0, 0)) {
		perror("arpd: daemon");
		goto do_abort;
	}

	openlog("arpd", LOG_PID | LOG_CONS, LOG_DAEMON);
	catch_signal(SIGINT, sig_exit);
	catch_signal(SIGTERM, sig_exit);
	catch_signal(SIGHUP, sig_sync);
	catch_signal(SIGUSR1, sig_stats);

#define EVENTS (POLLIN|POLLPRI|POLLERR|POLLHUP)
	pset[0].events = EVENTS;
	pset[0].revents = 0;
	pset[1].events = EVENTS;
	pset[1].revents = 0;

	sigsetjmp(env, 1);

	for (;;) {
		in_poll = 1;

		if (do_exit)
			break;
		if (do_sync) {
			in_poll = 0;
			dbase->sync(dbase, 0);
			do_sync = 0;
			in_poll = 1;
		}
		if (do_stats)
			send_stats();
		if (poll(pset, 2, 30000) > 0) {
			in_poll = 0;
			if (pset[0].revents&EVENTS)
				get_arp_pkt();
			if (pset[1].revents&EVENTS)
				get_kern_msg();
		} else {
			do_sync = 1;
		}
	}

	undo_sysctl_adjustments();
out:
	dbase->close(dbase);
	exit(0);

do_abort:
	dbase->close(dbase);
	exit(-1);
}
Пример #4
0
/*
 * main:
 *	The main program.
 */
int
main(int ac, char **av)
{
	PLAYER		*pp;
	int		had_char;
	static fd_set	read_fds;
	static FLAG	first = TRUE;
	static FLAG	server = FALSE;
	int		c;
	static struct timeval	linger = { 0, 0 };
	static struct timeval	timeout = { 0, 0 }, *to;
	struct spawn	*sp, *spnext;
	int		ret;
	int		nready;
	int		fd;

	First_arg = av[0];

	config();

	while ((c = getopt(ac, av, "sp:a:D:")) != -1) {
		switch (c) {
		  case 's':
			server = TRUE;
			break;
		  case 'p':
			should_announce = FALSE;
			Server_port = atoi(optarg);
			break;
		  case 'a':
			if (!inet_aton(optarg, (struct in_addr *)&Server_addr))
				err(1, "bad interface address: %s", optarg);
			break;
		  case 'D':
			config_arg(optarg);
			break;
		  default:
erred:
			fprintf(stderr,
			    "usage: %s [-s] [-a addr] [-Dvar=value ...] "
			    "[-p port]\n",
			    av[0]);
			exit(2);
		}
	}
	if (optind < ac)
		goto erred;

	/* Open syslog: */
	openlog("huntd", LOG_PID | (conf_logerr && !server? LOG_PERROR : 0),
		LOG_DAEMON);

	/* Initialise game parameters: */
	init();

again:
	do {
		/* First, poll to see if we can get input */
		do {
			read_fds = Fds_mask;
			errno = 0;
			timerclear(&timeout);
			nready = select(Num_fds, &read_fds, NULL, NULL,
			    &timeout);
			if (nready < 0 && errno != EINTR) {
				logit(LOG_ERR, "select");
				cleanup(1);
			}
		} while (nready < 0);

		if (nready == 0) {
			/*
			 * Nothing was ready. We do some work now
			 * to see if the simulation has any pending work
			 * to do, and decide if we need to block
			 * indefinitely or just timeout.
			 */
			do {
				if (conf_simstep && can_moveshots()) {
				/*
				 * block for a short time before continuing
				 * with explosions, bullets and whatnot
				 */
					to = &timeout;
					to->tv_sec =  conf_simstep / 1000000;
					to->tv_usec = conf_simstep % 1000000;
				} else
				/*
				 * since there's nothing going on,
				 * just block waiting for external activity
				 */
					to = NULL;

				read_fds = Fds_mask;
				errno = 0;
				nready = select(Num_fds, &read_fds, NULL, NULL,
				    to);
				if (nready < 0 && errno != EINTR) {
					logit(LOG_ERR, "select");
					cleanup(1);
				}
			} while (nready < 0);
		}

		/* Remember which descriptors are active: */
		Have_inp = read_fds;

		/* Answer new player connections: */
		if (FD_ISSET(Socket, &Have_inp))
			answer_first();

		/* Continue answering new player connections: */
		for (sp = Spawn; sp; ) {
			spnext = sp->next;
			fd = sp->fd;
			if (FD_ISSET(fd, &Have_inp) && answer_next(sp)) {
				/*
				 * Remove from the spawn list. (fd remains in
				 * read set).
				 */
				*sp->prevnext = sp->next;
				if (sp->next)
					sp->next->prevnext = sp->prevnext;
				free(sp);

				/* We probably consumed all data. */
				FD_CLR(fd, &Have_inp);

				/* Announce game if this is the first spawn. */
				if (first && should_announce)
					announce_game();
				first = FALSE;
			}
			sp = spnext;
		}

		/* Process input and move bullets until we've exhausted input */
		had_char = TRUE;
		while (had_char) {

			moveshots();
			for (pp = Player; pp < End_player; )
				if (pp->p_death[0] != '\0')
					zap(pp, TRUE);
				else
					pp++;
			for (pp = Monitor; pp < End_monitor; )
				if (pp->p_death[0] != '\0')
					zap(pp, FALSE);
				else
					pp++;

			had_char = FALSE;
			for (pp = Player; pp < End_player; pp++)
				if (havechar(pp)) {
					execute(pp);
					pp->p_nexec++;
					had_char = TRUE;
				}
			for (pp = Monitor; pp < End_monitor; pp++)
				if (havechar(pp)) {
					mon_execute(pp);
					pp->p_nexec++;
					had_char = TRUE;
				}
		}

		/* Handle a datagram sent to the server socket: */
		if (FD_ISSET(Server_socket, &Have_inp))
			handle_wkport(Server_socket);

		/* Answer statistics connections: */
		if (FD_ISSET(Status, &Have_inp))
			send_stats();

		/* Flush/synchronize all the displays: */
		for (pp = Player; pp < End_player; pp++) {
			if (FD_ISSET(pp->p_fd, &read_fds)) {
				sendcom(pp, READY, pp->p_nexec);
				pp->p_nexec = 0;
			}
			flush(pp);
		}
		for (pp = Monitor; pp < End_monitor; pp++) {
			if (FD_ISSET(pp->p_fd, &read_fds)) {
				sendcom(pp, READY, pp->p_nexec);
				pp->p_nexec = 0;
			}
			flush(pp);
		}
	} while (Nplayer > 0);

	/* No more players! */

	/* No players yet or a continuous game? */
	if (first || conf_linger < 0)
		goto again;

	/* Wait a short while for one to come back: */
	read_fds = Fds_mask;
	linger.tv_sec = conf_linger;
	while ((ret = select(Num_fds, &read_fds, NULL, NULL, &linger)) < 0) {
		if (errno != EINTR) {
			logit(LOG_WARNING, "select");
			break;
		}
		read_fds = Fds_mask;
		linger.tv_sec = conf_linger;
		linger.tv_usec = 0;
	}
	if (ret > 0)
		/* Someone returned! Resume the game: */
		goto again;
	/* else, it timed out, and the game is really over. */

	/* If we are an inetd server, we should re-init the map and restart: */
	if (server) {
		clear_scores();
		makemaze();
		clearwalls();
		makeboots();
		first = TRUE;
		goto again;
	}

	/* Get rid of any attached monitors: */
	for (pp = Monitor; pp < End_monitor; )
		zap(pp, FALSE);

	/* Fin: */
	cleanup(0);
	exit(0);
}
Пример #5
0
void handle_sigusr1()
{
    send_stats();
}
Пример #6
0
		/*
void draw_points(int r, int g, int b, const std::vector<GLfloat>& v) {
	if(v.empty()) {
		return;
	}

	glPointSize(5);
	glDisable(GL_TEXTURE_2D);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	glColor4ub(r, g, b, 255);
	glVertexPointer(2, GL_FLOAT, 0, &v[0]);
	glDrawArrays(GL_POINTS, 0, v.size()/2);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	glEnable(GL_TEXTURE_2D);
	glColor4ub(255, 255, 255, 255);
}

void draw_stats(const std::vector<record_ptr>& records)
{
	if(!player_move_record_vertex_array.empty()) {
		glDisable(GL_TEXTURE_2D);
		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
		glColor4ub(0, 0, 255, 128);
		glVertexPointer(2, GL_FLOAT, 0, &player_move_record_vertex_array[0]);
		glDrawArrays(GL_LINES, 0, player_move_record_vertex_array.size()/2);
		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
		glEnable(GL_TEXTURE_2D);
		glColor4ub(255, 255, 255, 255);
	}

	draw_points(255, 0, 0, die_record_vertex_array);
	draw_points(255, 255, 0, quit_record_vertex_array);
}
*/
void flush()
{
	send_stats(write_queue);
	threading::lock lck(upload_queue_mutex());
	send_stats_signal().notify_one();
}
Пример #7
0
/* Return values:
 * Negative on error
 * 0 on success with a reusable socket
 * 1 on success with a non-reusable socket */
static int process_request(int client, uid_t uid, request_header * req, void * key)
{
	struct cache_entry * entry;
	void * reply;
	int32_t reply_len;
	time_t refresh_interval;
	pthread_mutex_t * extra_mutex = NULL;
	int r;
	
	if(debug)
		printf("Got request type %d (key = [%s]) from UID %d on FD %d\n", req->type, (char *) key, uid, client);
	/* first check for control messages */
	if(req->type > LASTDBREQ && req->type != GETPWENT && req->type != GETGRENT && req->type != GETAI && req->type != INITGROUPS)
	{
		if(req->type == SHUTDOWN)
			exit(0);
		if(req->type == GETSTAT)
		{
			/* to aid the use of -g in figuring out whether
			 * gnscd is answering queries correctly, grab
			 * the cache mutex and release it to make sure
			 * it's not stuck locked by some thread */
			pthread_mutex_lock(&cache_mutex);
			pthread_mutex_unlock(&cache_mutex);
			send_stats(client, uid);
		}
		if(req->type == INVALIDATE)
		{
			/* key is "passwd" "group" or "hosts" */
			/* use memcmp not strcmp for security */
			/* if it's hosts, call res_init() */
			/* NOT IMPLEMENTED */
		}
		return 1;
	}
	
	/* not a control message, so check if the service is disabled */
	if(is_disabled(req->type))
	{
		if(debug)
			printf("Service type %d disabled\n", req->type);
		r = generate_disabled_reply(req->type, &reply, &reply_len);
		if(r < 0)
			return -1;
		if(write_all(client, reply, reply_len, SHORT_TIMEOUT) != reply_len)
			return -1;
		return r;
	}
	
	/* if it is a GET*ENT query, grab the extra mutex */
	if(req->type == GETPWENT)
		extra_mutex = pwent_query_mutex;
	else if(req->type == GETGRENT)
		extra_mutex = grent_query_mutex;
	if(extra_mutex)
		pthread_mutex_lock(extra_mutex);
	
	pthread_mutex_lock(&cache_mutex);
	r = cache_search(req, key, uid, &entry);
	if(r < 0 && extra_mutex)
	{
		if(debug)
			printf("Not in the cache, requesting iteration.\n");
		/* request it */
		r = request_ent_cache(req, key, uid);
		if(r >= 0)
			r = cache_search(req, key, uid, &entry);
	}
	if(r >= 0)
	{
		if(debug)
			printf("Found it in the cache!\n");
		r = entry->close_socket;
		/* reset the refresh count */
		entry->refreshes = 0;
		if(write_all(client, entry->reply, entry->reply_len, SHORT_TIMEOUT) != entry->reply_len)
			r = -1;
		pthread_mutex_unlock(&cache_mutex);
		if(extra_mutex)
			pthread_mutex_unlock(extra_mutex);
		return r;
	}
	pthread_mutex_unlock(&cache_mutex);
	
	if(debug)
		printf("Not in the cache.\n");
	
	if(!extra_mutex)
		/* find it */
		r = generate_reply(req, key, uid, &reply, &reply_len, &refresh_interval);
	else
		r = -1;
	
	if(r >= 0)
	{
		int close_socket = r;
		int add_result = -1;
		
		if(write_all(client, reply, reply_len, SHORT_TIMEOUT) != reply_len)
		{
			if(debug)
				printf("Failed to write to client %d\n", client);
			r = -1;
		}
		
		pthread_mutex_lock(&cache_mutex);
		/* don't add duplicate entries */
		if(cache_search(req, key, uid, &entry) < 0)
			add_result = cache_add(req, key, uid, reply, reply_len, close_socket, refresh_interval);
		if(add_result < 0)
			/* either it was already in the cache or adding it failed */
			free(reply);
		pthread_mutex_unlock(&cache_mutex);
	}
	
	/* if it was a GET*ENT query, release the extra mutex */
	if(extra_mutex)
		pthread_mutex_unlock(extra_mutex);
	
	return r;
}