DragonFlyBSD Kernel Audit
DF-2975 / srv.c
← back to finding ↓ download raw
/*
 * DF-2975 helper - same filtered listener as DF-2977's srv.c, port argv[1].
 * usage: srv <port>
 */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#ifndef SO_ACCEPTFILTER
#define SO_ACCEPTFILTER 0x1000
#endif

/* struct accept_filter_arg from <sys/socket.h> */

int main(int argc, char **argv)
{
	struct accept_filter_arg afa;
	struct sockaddr_in sa;
	int fd, cs, port = argc > 1 ? atoi(argv[1]) : 19001;
	char buf[4096];

	fd = socket(AF_INET, SOCK_STREAM, 0);
	memset(&sa, 0, sizeof(sa));
	sa.sin_family = AF_INET;
	sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	sa.sin_port = htons(port);
	if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
		perror("bind"); return 1;
	}
	if (listen(fd, 16) < 0) { perror("listen"); return 1; }
	memset(&afa, 0, sizeof(afa));
	strcpy(afa.af_name, "httpready");
	if (setsockopt(fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa,
		       sizeof(afa)) < 0) {
		perror("setsockopt SO_ACCEPTFILTER"); return 1;
	}
	printf("LISTENING port=%d filter=httpready\n", port);
	fflush(stdout);
	for (;;) {
		cs = accept(fd, NULL, NULL);
		if (cs < 0) { perror("accept"); return 1; }
		while (read(cs, buf, sizeof(buf)) > 0)
			;
		close(cs);
	}
	return 0;
}