static void *worker(void *self) { int fd, old_state; ssize_t ret; size_t blen = TUNBUFF_SIZ; //FIXME const struct worker_struct *ws = self; struct pollfd fds; char *buff; fds.fd = ws->efd[0]; fds.events = POLLIN; ret = curve25519_alloc_or_maybe_die(ws->c); if (ret < 0) syslog_panic("Cannot init curve25519!\n"); buff = xmalloc_aligned(blen, 64); syslog(LOG_INFO, "curvetun thread on CPU%u up!\n", ws->cpu); pthread_cleanup_push(xfree_func, ws->c); pthread_cleanup_push(curve25519_free, ws->c); pthread_cleanup_push(xfree_func, buff); while (likely(!sigint)) { poll(&fds, 1, -1); if ((fds.revents & POLLIN) != POLLIN) continue; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state); while ((ret = read_exact(ws->efd[0], &fd, sizeof(fd), 1)) > 0) { if (ret != sizeof(fd)) { sched_yield(); continue; } ret = ws->handler(fd, ws, buff, blen); if (ret) write_exact(ws->parent.refd, &fd, sizeof(fd), 1); } pthread_setcancelstate(old_state, NULL); } syslog(LOG_INFO, "curvetun thread on CPU%u down!\n", ws->cpu); pthread_cleanup_pop(1); pthread_cleanup_pop(1); pthread_cleanup_pop(1); pthread_exit((void *) ((long) ws->cpu)); }
int client_main(char *home, char *dev, char *host, char *port, int udp) { int fd = -1, tunfd = 0, retry_server = 0; int ret, try = 1, i; struct addrinfo hints, *ahead, *ai; struct pollfd fds[2]; struct curve25519_proto *p; struct curve25519_struct *c; char *buff; size_t blen = TUNBUFF_SIZ; //FIXME retry: if (!retry_server) { openlog("curvetun", LOG_PID | LOG_CONS | LOG_NDELAY, LOG_DAEMON); syslog(LOG_INFO, "curvetun client booting!\n"); } c = xmalloc(sizeof(struct curve25519_struct)); ret = curve25519_alloc_or_maybe_die(c); if (ret < 0) syslog_panic("Cannot init curve!\n"); p = get_serv_store_entry_proto_inf(); if (!p) syslog_panic("Cannot proto!\n"); memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM; hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP; hints.ai_flags = AI_NUMERICSERV; ret = getaddrinfo(host, port, &hints, &ahead); if (ret < 0) { syslog(LOG_ERR, "Cannot get address info! Retry!\n"); curve25519_free(c); xfree(c); fd = -1; retry_server = 1; closed_by_server = 0; sleep(1); goto retry; } for (ai = ahead; ai != NULL && fd < 0; ai = ai->ai_next) { fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (fd < 0) continue; ret = connect(fd, ai->ai_addr, ai->ai_addrlen); if (ret < 0) { syslog(LOG_ERR, "Cannot connect to remote, try %d: %s!\n", try++, strerror(errno)); close(fd); fd = -1; continue; } set_socket_keepalive(fd); set_mtu_disc_dont(fd); if (!udp) set_tcp_nodelay(fd); }