DF-2977 / srv.c
/* * DF-2977 / DF-2975 helper - listening socket with the httpready accept * filter attached. usage: srv <port> [holdsec] * Prints "LISTENING" once the filter is attached. */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <time.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, hold = argc > 2 ? atoi(argv[2]) : 60; int port = argc > 1 ? atoi(argv[1]) : 19000; char buf[4096]; time_t t0; 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); t0 = time(NULL); for (;;) { cs = accept(fd, NULL, NULL); if (cs < 0) { perror("accept"); return 1; } /* drain and close */ while (read(cs, buf, sizeof(buf)) > 0) ; close(cs); if (time(NULL) - t0 > (time_t)hold) break; } return 0; } |