#include #include #include #include #include #include #include #include #include #include static bool closehalf = false; static void * worker(void *arg) { u_int nsockets = *(u_int *)arg, half = nsockets / 2; int *sockets; u_short seed[3]; sockets = malloc(nsockets * sizeof(int)); arc4random_buf(seed, sizeof(seed)); for (u_int i = 0; i < nsockets; i++) { char s[INET_ADDRSTRLEN]; struct sockaddr_in sin = { .sin_family = AF_INET }; long r; int rv; sockets[i] = socket(AF_INET, SOCK_DGRAM, 0); if(__predict_false(sockets[i] == -1)) { warn("Socket"); continue; } do { r = nrand48(seed); sin.sin_port = (u_short)(r >> 24); } while (__predict_false(sin.sin_port == 0)); sin.sin_addr.s_addr = htonl((10 << 24) | ((u_int)r & 0xffffff)); rv = connect(sockets[i], (struct sockaddr *)&sin, sizeof(sin)); if (__predict_false(rv != 0)) warn("Connect to %s:%u", inet_ntop(AF_INET, &sin.sin_addr, s, sizeof(s)), ntohs(sin.sin_port)); if (closehalf && i >= half) close(sockets[i - half]); } return (NULL); } int main(int argc, char *argv[]) { u_int nthreads = (u_int)sysconf(_SC_NPROCESSORS_ONLN); u_int nsockets = 1000; pthread_t *threads; int c; while ((c = getopt(argc, argv, "cn:t:")) != -1) switch (c) { case 'c': closehalf = true; break; case 'n': nsockets = (u_int)strtol(optarg, NULL, 10); break; case 't': nthreads = (u_int)strtol(optarg, NULL, 10); break; default: errx(EX_USAGE, "Usage: %s [-c] [-n sockets] [-t threads]", argv[0]); } printf("%u threads, %u sockets\n", nthreads, nsockets); threads = malloc(nthreads * sizeof(pthread_t)); for (u_int i = 0; i < nthreads; i++) pthread_create(&threads[i], NULL, worker, &nsockets); for (u_int i = 0; i < nthreads; i++) pthread_join(threads[i], NULL); }