Ejemplo n.º 1
0
static int
rumpsp_dispatch(int timeout_ms)
{
	unsigned int idx;
	int rv, seen;

	rv = poll(pollfds, maxidx+1, timeout_ms);
	if (rv == 0)
		return 0;
	
	if (rv < 0)
		return errno;

	seen = 0;
	for (idx = 0; seen < rv && idx <= maxidx; idx++) {
		struct rumpsp_chan *chan = &chanfds[idx];

		if (!(pollfds[idx].revents & (POLLIN|POLLOUT)))
			continue;
		seen++;

		if (idx == 0) {
			dispatch_accept(chan->fd);
		} else {
			if (pollfds[idx].revents & POLLIN) {
				handlers.readable(chan, chan->token);
			}

			if (pollfds[idx].revents & POLLOUT) {
				handlers.writable(chan, chan->token);
			}
		}
	}

	return 0;
}
Ejemplo n.º 2
0
int
main(int argc, char * argv[])
{
	/* State variables. */
	struct serverpool * SP;
	struct dynamodb_request_queue * QW;
	struct dynamodb_request_queue * QR;
	struct dispatch_state * D;
	int s;

	/* Command-line parameters. */
	char * opt_k = NULL;
	char * opt_l = NULL;
	char * opt_p = NULL;
	char * opt_r = NULL;
	char * opt_s = NULL;
	char * opt_t = NULL;
	int opt_1 = 0;

	/* Working variable. */
	char * dynamodb_host;
	char * key_id;
	char * key_secret;
	struct sock_addr ** sas;
	struct logging_file * logfile;
	struct capacity_reader * M;
	const char * ch;

	WARNP_INIT;

	/* Parse the command line. */
	while ((ch = GETOPT(argc, argv)) != NULL) {
		GETOPT_SWITCH(ch) {
		GETOPT_OPTARG("-k"):
			if (opt_k != NULL)
				usage();
			if ((opt_k = strdup(optarg)) == NULL)
				OPT_EPARSE(ch, optarg);
			break;
		GETOPT_OPTARG("-l"):
			if (opt_l != NULL)
				usage();
			if ((opt_l = strdup(optarg)) == NULL)
				OPT_EPARSE(ch, optarg);
			break;
		GETOPT_OPTARG("-p"):
			if (opt_p != NULL)
				usage();
			if ((opt_p = strdup(optarg)) == NULL)
				OPT_EPARSE(ch, optarg);
			break;
		GETOPT_OPTARG("-r"):
			if (opt_r != NULL)
				usage();
			if ((opt_r = strdup(optarg)) == NULL)
				OPT_EPARSE(ch, optarg);
			break;
		GETOPT_OPTARG("-s"):
			if (opt_s != NULL)
				usage();
			if ((opt_s = strdup(optarg)) == NULL)
				OPT_EPARSE(ch, optarg);
			break;
		GETOPT_OPTARG("-t"):
			if (opt_t != NULL)
				usage();
			if ((opt_t = strdup(optarg)) == NULL)
				OPT_EPARSE(ch, optarg);
			break;
		GETOPT_OPT("--version"):
			fprintf(stderr, "dynamodb-kv @VERSION@\n");
			exit(0);
		GETOPT_OPT("-1"):
			if (opt_1 != 0)
				usage();
			opt_1 = 1;
			break;
		GETOPT_MISSING_ARG:
			warn0("Missing argument to %s\n", ch);
			usage();
		GETOPT_DEFAULT:
			warn0("illegal option -- %s\n", ch);
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	/* We should have processed all the arguments. */
	if (argc != 0)
		usage();

	/* Verify that we have mandatory options. */
	if (opt_k == NULL)
		usage();
	if (opt_r == NULL)
		usage();
	if (opt_s == NULL)
		usage();
	if (opt_t == NULL)
		usage();

	/* Construct the DynamoDB endpoint host name. */
	if (asprintf(&dynamodb_host, "dynamodb.%s.amazonaws.com:80",
	    opt_r) == -1) {
		warnp("asprintf");
		exit(1);
	}

	/* Start looking up addresses for DynamoDB endpoints. */
	if ((SP = serverpool_create(dynamodb_host, 15, 120)) == NULL) {
		warnp("Error starting DNS lookups for %s", dynamodb_host);
		exit(1);
	}

	/* Read the key file. */
	if (aws_readkeys(opt_k, &key_id, &key_secret)) {
		warnp("Error reading AWS keys from %s", opt_k);
		exit(1);
	}

	/* Create DynamoDB request queues for writes and reads. */
	if ((QW = dynamodb_request_queue_init(key_id, key_secret,
	    opt_r, SP)) == NULL) {
		warnp("Error creating DynamoDB request queue");
		exit(1);
	}
	if ((QR = dynamodb_request_queue_init(key_id, key_secret,
	    opt_r, SP)) == NULL) {
		warnp("Error creating DynamoDB request queue");
		exit(1);
	}

	/* Start reading table throughput parameters. */
	if ((M = capacity_init(key_id, key_secret, opt_t, opt_r,
	    SP, QW, QR)) == NULL) {
		warnp("Error reading DynamoDB table metadata");
		exit(1);
	}

	/* Resolve the listening address. */
	if ((sas = sock_resolve(opt_s)) == NULL) {
		warnp("Error resolving socket address: %s", opt_s);
		exit(1);
	}
	if (sas[0] == NULL) {
		warn0("No addresses found for %s", opt_s);
		exit(1);
	}

	/* Create and bind a socket, and mark it as listening. */
	if (sas[1] != NULL)
		warn0("Listening on first of multiple addresses found for %s",
		    opt_s);
	if ((s = sock_listener(sas[0])) == -1)
		exit(1);

	/* If requested, create a log file. */
	if (opt_l != NULL) {
		if ((logfile = logging_open(opt_l)) == NULL) {
			warnp("Cannot open log file");
			exit(1);
		}
		dynamodb_request_queue_log(QW, logfile);
		dynamodb_request_queue_log(QR, logfile);
	} else {
		logfile = NULL;
	}

	/* Daemonize and write pid. */
	if (opt_p == NULL) {
		if (asprintf(&opt_p, "%s.pid", opt_s) == -1) {
			warnp("asprintf");
			exit(1);
		}
	}
	if (daemonize(opt_p)) {
		warnp("Failed to daemonize");
		exit(1);
	}

	/* Handle connections, one at once. */
	do {
		/* accept a connection. */
		if ((D = dispatch_accept(QW, QR, opt_t, s)) == NULL) {
			warnp("Error accepting new connection");
			exit(1);
		}

		/* Loop until the connection dies. */
		do {
			if (events_run()) {
				warnp("Error running event loop");
				exit(1);
			}
		} while (dispatch_alive(D));

		/* Clean up the connection. */
		if (dispatch_done(D))
			exit(1);
	} while (opt_1 == 0);

	/* Close the log file, if we have one. */
	if (logfile != NULL)
		logging_close(logfile);

	/* Close the listening socket. */
	close(s);

	/* Free the address structures. */
	sock_addr_freelist(sas);

	/* Stop performing DescribeTable requests. */
	capacity_free(M);

	/* Free DynamoDB request queues. */
	dynamodb_request_queue_free(QR);
	dynamodb_request_queue_free(QW);

	/* Stop DNS lookups. */
	serverpool_free(SP);

	/* Shut down the event subsystem. */
	events_shutdown();

	/* Free string allocated by asprintf. */
	free(dynamodb_host);

	/* Free key strings. */
	free(key_id);
	insecure_memzero(key_secret, strlen(key_secret));
	free(key_secret);

	/* Free option strings. */
	free(opt_k);
	free(opt_l);
	free(opt_p);
	free(opt_r);
	free(opt_s);
	free(opt_t);

	/* Success! */
	exit(0);
}
Ejemplo n.º 3
0
int
main(int argc, char * argv[])
{
	/* Command-line parameters. */
	int opt_d = 0;
	int opt_D = 0;
	int opt_e = 0;
	int opt_f = 0;
	int opt_F = 0;
	int opt_j = 0;
	const char * opt_k = NULL;
	intmax_t opt_n = 0;
	double opt_o = 0.0;
	char * opt_p = NULL;
	double opt_r = 0.0;
	int opt_R = 0;
	const char * opt_s = NULL;
	const char * opt_t = NULL;

	/* Working variables. */
	struct sock_addr ** sas_s;
	struct sock_addr ** sas_t;
	struct proto_secret * K;
	int ch;
	int s;

	WARNP_INIT;

	/* Parse the command line. */
	while ((ch = getopt(argc, argv, "dDefFjk:n:o:r:Rp:s:t:")) != -1) {
		switch (ch) {
		case 'd':
			if (opt_d || opt_e)
				usage();
			opt_d = 1;
			break;
		case 'D':
			if (opt_D)
				usage();
			opt_D = 1;
			break;
		case 'e':
			if (opt_d || opt_e)
				usage();
			opt_e = 1;
			break;
		case 'f':
			if (opt_f)
				usage();
			opt_f = 1;
			break;
		case 'F':
			if (opt_F)
				usage();
			opt_F = 1;
			break;
		case 'j':
			if (opt_j)
				usage();
			opt_j = 1;
			break;
		case 'k':
			if (opt_k)
				usage();
			opt_k = optarg;
			break;
		case 'n':
			if (opt_n != 0)
				usage();
			if ((opt_n = strtoimax(optarg, NULL, 0)) == 0) {
				warn0("Invalid option: -n %s", optarg);
				exit(1);
			}
			break;
		case 'o':
			if (opt_o != 0.0)
				usage();
			if ((opt_o = strtod(optarg, NULL)) == 0.0) {
				warn0("Invalid option: -o %s", optarg);
				exit(1);
			}
			break;
		case 'p':
			if (opt_p)
				usage();
			if ((opt_p = strdup(optarg)) == NULL)
				OPT_EPARSE(ch, optarg);
			break;
		case 'r':
			if (opt_r != 0.0)
				usage();
			if ((opt_r = strtod(optarg, NULL)) == 0.0) {
				warn0("Invalid option: -r %s", optarg);
				exit(1);
			}
			break;
		case 'R':
			if (opt_R)
				usage();
			opt_R = 1;
			break;
		case 's':
			if (opt_s)
				usage();
			opt_s = optarg;
			break;
		case 't':
			if (opt_t)
				usage();
			opt_t = optarg;
			break;
		default:
			usage();
		}
	}

	/* We should have processed all the arguments. */
	if (argc != optind)
		usage();

	/* Set defaults. */
	if (opt_n == 0)
		opt_n = 100;
	if (opt_o == 0.0)
		opt_o = 5.0;
	if (opt_r == 0.0)
		opt_r = 60.0;

	/* Sanity-check options. */
	if (!opt_d && !opt_e)
		usage();
	if (opt_k == NULL)
		usage();
	if ((opt_n < 0) || (opt_n > 500))
		usage();
	if (!(opt_o > 0.0))
		usage();
	if ((opt_r != 60.0) && opt_R)
		usage();
	if (opt_s == NULL)
		usage();
	if (opt_t == NULL)
		usage();

	/* Figure out where our pid should be written. */
	if (opt_p == NULL) {
		if (asprintf(&opt_p, "%s.pid", opt_s) == -1) {
			warnp("asprintf");
			exit(1);
		}
	}

	/* Daemonize early if we're going to wait for DNS to be ready. */
	if (opt_D && !opt_F && daemonize(opt_p)) {
		warnp("Failed to daemonize");
		exit(1);
	}

	/* Resolve source address. */
	while ((sas_s = sock_resolve(opt_s)) == NULL) {
		if (!opt_D) {
			warnp("Error resolving socket address: %s", opt_s);
			exit(1);
		}
		sleep(1);
	}
	if (sas_s[0] == NULL) {
		warn0("No addresses found for %s", opt_s);
		exit(1);
	}

	/* Resolve target address. */
	while ((sas_t = sock_resolve(opt_t)) == NULL) {
		if (!opt_D) {
			warnp("Error resolving socket address: %s", opt_t);
			exit(1);
		}
		sleep(1);
	}
	if (sas_t[0] == NULL) {
		warn0("No addresses found for %s", opt_t);
		exit(1);
	}

	/* Load the keying data. */
	if ((K = proto_crypt_secret(opt_k)) == NULL) {
		warnp("Error reading shared secret");
		exit(1);
	}

	/* Create and bind a socket, and mark it as listening. */
	if (sas_s[1] != NULL)
		warn0("Listening on first of multiple addresses found for %s",
		    opt_s);
	if ((s = sock_listener(sas_s[0])) == -1)
		exit(1);

	/* Daemonize and write pid. */
	if (!opt_F && daemonize(opt_p)) {
		warnp("Failed to daemonize");
		exit(1);
	}

	/* Start accepting connections. */
	if (dispatch_accept(s, opt_t, opt_R ? 0.0 : opt_r, sas_t, opt_d,
	    opt_f, opt_j, K, opt_n, opt_o)) {
		warnp("Failed to initialize connection acceptor");
		exit(1);
	}

	/* Infinite loop handling events. */
	do {
		if (events_run()) {
			warnp("Error running event loop");
			exit(1);
		}
	} while (1);

	/* NOTREACHED */
	/*
	 * If we could reach this point, we would free memory, close sockets,
	 * and otherwise clean up here.
	 */
}
Ejemplo n.º 4
0
int
main(int argc, char * argv[])
{
	/* Command-line parameters. */
	int opt_d = 0;
	int opt_D = 0;
	int opt_e = 0;
	int opt_f = 0;
	int opt_g = 0;
	int opt_F = 0;
	int opt_j = 0;
	const char * opt_k = NULL;
	intmax_t opt_n = 0;
	double opt_o = 0.0;
	char * opt_p = NULL;
	double opt_r = 0.0;
	int opt_R = 0;
	const char * opt_s = NULL;
	const char * opt_t = NULL;

	/* Working variables. */
	struct sock_addr ** sas_s;
	struct sock_addr ** sas_t;
	struct proto_secret * K;
	const char * ch;
	int s;

	WARNP_INIT;

	/* Parse the command line. */
	while ((ch = GETOPT(argc, argv)) != NULL) {
		GETOPT_SWITCH(ch) {
		GETOPT_OPT("-d"):
			if (opt_d || opt_e)
				usage();
			opt_d = 1;
			break;
		GETOPT_OPT("-D"):
			if (opt_D)
				usage();
			opt_D = 1;
			break;
		GETOPT_OPT("-e"):
			if (opt_d || opt_e)
				usage();
			opt_e = 1;
			break;
		GETOPT_OPT("-f"):
			if (opt_f)
				usage();
			opt_f = 1;
			break;
		GETOPT_OPT("-F"):
			if (opt_F)
				usage();
			opt_F = 1;
			break;
		GETOPT_OPT("-g"):
			if (opt_g)
				usage();
			opt_g = 1;
			break;
		GETOPT_OPT("-j"):
			if (opt_j)
				usage();
			opt_j = 1;
			break;
		GETOPT_OPTARG("-k"):
			if (opt_k)
				usage();
			opt_k = optarg;
			break;
		GETOPT_OPTARG("-n"):
			if (opt_n != 0)
				usage();
			if ((opt_n = strtoimax(optarg, NULL, 0)) == 0) {
				warn0("Invalid option: -n %s", optarg);
				exit(1);
			}
			if ((opt_n <= 0) || (opt_n > 500)) {
				warn0("The parameter to -n must be between 1 and 500\n");
				exit(1);
			}
			break;
		GETOPT_OPTARG("-o"):
			if (opt_o != 0.0)
				usage();
			if ((opt_o = strtod(optarg, NULL)) == 0.0) {
				warn0("Invalid option: -o %s", optarg);
				exit(1);
			}
			break;
		GETOPT_OPTARG("-p"):
			if (opt_p)
				usage();
			if ((opt_p = strdup(optarg)) == NULL)
				OPT_EPARSE(ch, optarg);
			break;
		GETOPT_OPTARG("-r"):
			if (opt_r != 0.0)
				usage();
			if ((opt_r = strtod(optarg, NULL)) == 0.0) {
				warn0("Invalid option: -r %s", optarg);
				exit(1);
			}
			break;
		GETOPT_OPT("-R"):
			if (opt_R)
				usage();
			opt_R = 1;
			break;
		GETOPT_OPTARG("-s"):
			if (opt_s)
				usage();
			opt_s = optarg;
			break;
		GETOPT_OPTARG("-t"):
			if (opt_t)
				usage();
			opt_t = optarg;
			break;
		GETOPT_OPT("-v"):
			fprintf(stderr, "spiped @VERSION@\n");
			exit(0);
		GETOPT_MISSING_ARG:
			warn0("Missing argument to %s\n", ch);
			/* FALLTHROUGH */
		GETOPT_DEFAULT:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	/* We should have processed all the arguments. */
	if (argc != 0)
		usage();

	/* Set defaults. */
	if (opt_n == 0)
		opt_n = 100;
	if (opt_o == 0.0)
		opt_o = 5.0;
	if (opt_r == 0.0)
		opt_r = 60.0;

	/* Sanity-check options. */
	if (!opt_d && !opt_e)
		usage();
	if (opt_f && opt_g)
		usage();
	if (opt_k == NULL)
		usage();
	if (!(opt_o > 0.0))
		usage();
	if ((opt_r != 60.0) && opt_R)
		usage();
	if (opt_s == NULL)
		usage();
	if (opt_t == NULL)
		usage();

	/* Figure out where our pid should be written. */
	if (opt_p == NULL) {
		if (asprintf(&opt_p, "%s.pid", opt_s) == -1) {
			warnp("asprintf");
			exit(1);
		}
	}

	/* Check whether we are running as init (e.g., inside a container). */
	if (getpid() == 1) {
		/* https://github.com/docker/docker/issues/7086 */
		warn0("WARNING: Applying workaround for Docker signal-handling bug");

		/* Bind an explicit signal handler for SIGTERM and SIGINT. */
		if (signal(SIGTERM, diediedie_handler) == SIG_ERR) {
			warnp("Failed to bind SIGTERM signal handler");
		}
		if (signal(SIGINT, diediedie_handler) == SIG_ERR) {
			warnp("Failed to bind SIGINT signal handler");
		}
	}

	/* Daemonize early if we're going to wait for DNS to be ready. */
	if (opt_D && !opt_F && daemonize(opt_p)) {
		warnp("Failed to daemonize");
		exit(1);
	}

	/* Resolve source address. */
	while ((sas_s = sock_resolve(opt_s)) == NULL) {
		if (!opt_D) {
			warnp("Error resolving socket address: %s", opt_s);
			exit(1);
		}
		sleep(1);
	}
	if (sas_s[0] == NULL) {
		warn0("No addresses found for %s", opt_s);
		exit(1);
	}

	/* Resolve target address. */
	while ((sas_t = sock_resolve(opt_t)) == NULL) {
		if (!opt_D) {
			warnp("Error resolving socket address: %s", opt_t);
			exit(1);
		}
		sleep(1);
	}
	if (sas_t[0] == NULL) {
		warn0("No addresses found for %s", opt_t);
		exit(1);
	}

	/* Load the keying data. */
	if ((K = proto_crypt_secret(opt_k)) == NULL) {
		warnp("Error reading shared secret");
		exit(1);
	}

	/* Create and bind a socket, and mark it as listening. */
	if (sas_s[1] != NULL)
		warn0("Listening on first of multiple addresses found for %s",
		    opt_s);
	if ((s = sock_listener(sas_s[0])) == -1)
		exit(1);

	/* Daemonize and write pid. */
	if (!opt_F && daemonize(opt_p)) {
		warnp("Failed to daemonize");
		exit(1);
	}

	/* Start accepting connections. */
	if (dispatch_accept(s, opt_t, opt_R ? 0.0 : opt_r, sas_t, opt_d,
	    opt_f, opt_g, opt_j, K, opt_n, opt_o)) {
		warnp("Failed to initialize connection acceptor");
		exit(1);
	}

	/* Infinite loop handling events. */
	do {
		if (events_run()) {
			warnp("Error running event loop");
			exit(1);
		}
	} while (1);

	/* NOTREACHED */
	/*
	 * If we could reach this point, we would free memory, close sockets,
	 * and otherwise clean up here.
	 */
}