int control_start(void) { int len; if ((len = make_sock()) == -1) return -1; unlink(CONTROLSOCKET); if (bind(fd, (struct sockaddr *)&sun, len) == -1 || chmod(CONTROLSOCKET, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) == -1 || set_cloexec(fd) == -1 || set_nonblock(fd) == -1 || listen(fd, sizeof(control_fds)) == -1) { close(fd); return -1; } eloop_event_add(fd, control_handle, NULL); return fd; }
/* ARGSUSED */ static void control_handle(__unused void *arg) { struct sockaddr_un run; socklen_t len; struct fd_list *l; int f; len = sizeof(run); if ((f = accept(fd, (struct sockaddr *)&run, &len)) == -1) return; set_cloexec(f); l = malloc(sizeof(*l)); if (l) { l->fd = f; l->listener = 0; l->next = control_fds; control_fds = l; eloop_event_add(l->fd, control_handle_data, l); } }
int main(int argc, char **argv) { int c, result, exit_code; size_t i, nruns = 25; struct pipe *p; struct timespec ts, te, t; while ((c = getopt(argc, argv, "a:n:r:w:")) != -1) { switch (c) { case 'a': nactive = (size_t)atoi(optarg); break; case 'n': npipes = (size_t)atoi(optarg); break; case 'r': nruns = (size_t)atoi(optarg); break; case 'w': nwrites = (size_t)atoi(optarg); break; default: errx(EXIT_FAILURE, "illegal argument `%c'", c); } } if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) err(EXIT_FAILURE, "clock_gettime"); if ((e = eloop_new()) == NULL) err(EXIT_FAILURE, "eloop_init"); if (nactive > npipes) nactive = npipes; pipes = calloc(npipes, sizeof(*p)); if (pipes == NULL) err(EXIT_FAILURE, "malloc"); for (i = 0, p = pipes; i < npipes; i++, p++) { if (pipe2(p->fd, O_CLOEXEC | O_NONBLOCK) == -1) err(EXIT_FAILURE, "pipe"); if (eloop_event_add(e, p->fd[0], read_cb, p) == -1) err(EXIT_FAILURE, "eloop_event_add"); } printf("active = %zu, pipes = %zu, runs = %zu, writes = %zu\n", nactive, npipes, nruns, nwrites); exit_code = EXIT_SUCCESS; for (i = 0; i < nruns; i++) { result = runone(&t); if (result != EXIT_SUCCESS) exit_code = result; printf("run %zu took %lld.%.9ld seconds, result %d\n", i + 1, (long long)t.tv_sec, t.tv_nsec, result); } eloop_free(e); free(pipes); if (clock_gettime(CLOCK_MONOTONIC, &te) == -1) err(EXIT_FAILURE, "clock_gettime"); timespecsub(&te, &ts, &t); printf("total %lld.%.9ld seconds, result %d\n", (long long)t.tv_sec, t.tv_nsec, exit_code); exit(exit_code); }
static int ipv6ns_open(void) { int on; int len; struct icmp6_filter filt; #ifdef IPV6_SEND_DAD union { struct sockaddr sa; struct sockaddr_in6 sin; } su; #endif if (sock != -1) return sock; sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); if (sock == -1) return -1; on = 1; if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)) == -1) goto eexit; on = 1; if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, sizeof(on)) == -1) goto eexit; ICMP6_FILTER_SETBLOCKALL(&filt); #ifdef IPV6_SEND_DAD /* We send DAD requests from the unspecified address. */ unspec_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); if (unspec_sock == -1) goto eexit; if (setsockopt(unspec_sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, sizeof(filt)) == -1) goto eexit; memset(&su, 0, sizeof(su)); su.sin.sin6_family = AF_INET6; #ifdef SIN6_LEN su.sin.sin6_len = sizeof(su.sin); #endif if (bind(unspec_sock, &su.sa, sizeof(su.sin)) == -1) goto eexit; #endif ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filt); if (setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, sizeof(filt)) == -1) goto eexit; set_cloexec(sock); #if DEBUG_MEMORY atexit(ipv6ns_cleanup); #endif #ifdef LISTEN_DAD syslog(LOG_WARNING, "kernel does not report DAD results to userland"); syslog(LOG_WARNING, "warning listening to duplicated addresses on the wire"); #endif len = CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int)); sndbuf = calloc(1, len); if (sndbuf == NULL) goto eexit; sndhdr.msg_namelen = sizeof(struct sockaddr_in6); sndhdr.msg_iov = sndiov; sndhdr.msg_iovlen = 1; sndhdr.msg_control = sndbuf; sndhdr.msg_controllen = len; rcvbuf = calloc(1, len); if (rcvbuf == NULL) goto eexit; rcvhdr.msg_name = &from; rcvhdr.msg_namelen = sizeof(from); rcvhdr.msg_iov = rcviov; rcvhdr.msg_iovlen = 1; rcvhdr.msg_control = rcvbuf; rcvhdr.msg_controllen = len; rcviov[0].iov_base = ansbuf; rcviov[0].iov_len = sizeof(ansbuf); eloop_event_add(sock, ipv6ns_handledata, NULL); return sock; eexit: syslog(LOG_ERR, "%s: %m", __func__); close(sock); sock = -1; free(sndbuf); sndbuf = NULL; free(rcvbuf); rcvbuf = NULL; return -1; }