tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: TCP connections clogging up accf_http(9) (was: ESTABLISHED sockets with no fd open?



Sorry, wrong program attached.  Here's the right one.

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <arpa/inet.h>
#include <unistd.h>
#include <sys/socket.h>
#include <err.h>

#define LISTENADDR "192.168.1.12"
#define LISTENPORT 12345

void
do_listen(int backlog)
{
	int lsck = socket(AF_INET, SOCK_STREAM, 0);
	if (lsck == -1)
		err(1, "socket");

	struct sockaddr_in sa = {
		.sin_len = sizeof sa,
		.sin_family = AF_INET,
		.sin_port = htons(LISTENPORT)
	};

	int r = inet_pton(AF_INET, LISTENADDR, &sa.sin_addr);
	if (r != 1)
		errx(1, "inet_pton: %d", r);

	if (bind(lsck, (struct sockaddr *)&sa, sizeof sa) == -1)
		err(1, "bind");

	if (listen(lsck, backlog) == -1)
		err(1, "listen");

	//warnx("listening, backlog %d", backlog);

	struct accept_filter_arg accf;
	memset(&accf, 0, sizeof accf);
	strcpy(accf.af_name, "httpready");
	if (setsockopt(lsck, SOL_SOCKET, SO_ACCEPTFILTER, &accf, sizeof accf) == -1)
		err(1, "setsockopt");

	int sck;
	while ((sck = accept(lsck, NULL, NULL)) != -1) {
		//warnx("accepted");

		r = fork();
		if (r == -1)
			err(1, "fork");

		if (r == 0) {
			char buf[128];
			ssize_t ret = read(sck, buf, sizeof buf);
			//if (ret <= 0)
			//	warnx("read: %zd", ret);
			//else
			//	printf("read '%s'\n", buf);

			close(sck);
			exit(0);
		} else
			close(sck);
	}

	err(1, "accept");

}

void
do_connect(int backlog)
{
	int conns = 0;
	struct sockaddr_in sa = {
		.sin_len = sizeof sa,
		.sin_family = AF_INET,
		.sin_port = htons(LISTENPORT)
	};

	int r = inet_pton(AF_INET, LISTENADDR, &sa.sin_addr);
	if (r != 1)
		errx(1, "inet_pton: %d", r);


	while (true) {
		int sck = socket(AF_INET, SOCK_STREAM, 0);
		if (sck == -1)
			err(1, "socket");

		if (connect(sck, (struct sockaddr *)&sa, sizeof sa) == -1) {
			warn("connect");
			break;
		}

		conns++;
	}

	warnx("established %d connections before it blew up, backlog was %d", conns, backlog);

	system("pkill accftest"); // ...
}

int
main(int argc, char **argv)
{
	int backlog = strtol(argv[1], NULL, 0);
	int r = fork();

	if (r == -1)
		err(1, "fork");

	if (r == 0) {
		sleep(1);
		do_connect(backlog);
	} else {
		do_listen(backlog);
	}
}



Home | Main Index | Thread Index | Old Index