int main(int argc, char const *argv[]) { char err[SOCKET_ERR_LEN]; pool = buffer_pool_create(100); prev_recv = prev_send = 0; recv_total = send_total = 0; int sfd = tcp_server_serve(err, "localhost", 3456, SOMAXCONN); if (sfd < 0) { printf("%d %s\n", sfd, err); return 0; } if (set_nonblock(err, sfd) != 0) { printf("%s\n", err); return 0; } if (set_tcp_nodelay(err, sfd, 1) != 0) { printf("%s\n", err); return 0; } event_loop_t *loop = event_loop_create(100, 10); assert(loop != NULL); create_timer(loop, 1000, print_info, NULL); create_event(loop, sfd, EV_RDABLE, server_accept_cb, NULL); event_loop_start(loop); }
void server_accept_cb(event_loop_t *loop, int fd, void *data) { int cfd; int port; char ip[256]; char err[SOCKET_ERR_LEN]; while (1) { cfd = tcp_accept(err, fd, ip, 256, &port); if (cfd < 0) { if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) { break; } else { printf("accept: %s\n", err); break; } } printf("client %s:%d\n", ip, port); if (set_nonblock(err, cfd) != 0) { printf("%s\n", err); close(cfd); } if (set_tcp_nodelay(err, cfd, 1) != 0) { printf("%s\n", err); close(cfd); } buffer_chain_t *chain = malloc(sizeof(*chain)); assert(chain != NULL); chain->pool = pool; chain->rbuf = chain->wbuf = buffer_pool_get(pool); chain->sent = chain->recv = 0; connection_t *conn = malloc(sizeof(*conn)); assert(conn != NULL); conn->chain = chain; conn->total = 0; conn->eof = 0; conn->writing = 0; create_event(loop, cfd, EV_RDABLE, client_readcb, conn); } }
//----------------------------------------------------------------------------- CySocket* CySocket::accept() { init(); SOCKET newSock = ::accept(sock, (sockaddr *) &addr, &addr_len); if (newSock == INVALID_SOCKET) { dperror("accept: invalid socket\n"); return NULL; } CySocket *new_ySocket = new CySocket(newSock); if (new_ySocket != NULL) { new_ySocket->setAddr(addr); #ifdef TCP_CORK new_ySocket->set_option(IPPROTO_TCP, TCP_CORK); #else set_tcp_nodelay(); #endif } new_ySocket->isOpened = true; // handling = true; return new_ySocket; }
int nepim_socket_tcp_opt(FILE *err, int family, int sd, int nodelay, int mss) { if (set_tcp_nodelay(err, sd, nodelay)) { /* Tolerate failure in setting NODELAY for PF_UNIX sockets */ if (family != PF_UNIX) return NEPIM_SOCK_ERR_NODELAY; } if (nepim_socket_mss(err, sd, mss)) { /* Tolerate failure in setting TCP_MAXSEG for PF_UNIX sockets */ if (family != PF_UNIX) return NEPIM_SOCK_ERR_MSS; } return NEPIM_SOCK_ERR_NONE; }
/* * Fetches the resource denoted by |uri|. */ static void fetch_uri(const struct URI *uri) { spdylay_session_callbacks callbacks; int fd; SSL_CTX *ssl_ctx; SSL *ssl; struct Request req; struct Connection connection; int rv; nfds_t npollfds = 1; struct pollfd pollfds[1]; uint16_t spdy_proto_version; request_init(&req, uri); setup_spdylay_callbacks(&callbacks); /* Establish connection and setup SSL */ fd = connect_to(req.host, req.port); ssl_ctx = SSL_CTX_new(SSLv23_client_method()); if(ssl_ctx == NULL) { dief("SSL_CTX_new", ERR_error_string(ERR_get_error(), NULL)); } init_ssl_ctx(ssl_ctx, &spdy_proto_version); ssl = SSL_new(ssl_ctx); if(ssl == NULL) { dief("SSL_new", ERR_error_string(ERR_get_error(), NULL)); } /* To simplify the program, we perform SSL/TLS handshake in blocking I/O. */ ssl_handshake(ssl, fd); connection.ssl = ssl; connection.want_io = IO_NONE; /* Here make file descriptor non-block */ make_non_block(fd); set_tcp_nodelay(fd); printf("[INFO] SPDY protocol version = %d\n", spdy_proto_version); rv = spdylay_session_client_new(&connection.session, spdy_proto_version, &callbacks, &connection); if(rv != 0) { diec("spdylay_session_client_new", rv); } /* Submit the HTTP request to the outbound queue. */ submit_request(&connection, &req); pollfds[0].fd = fd; ctl_poll(pollfds, &connection); /* Event loop */ while(spdylay_session_want_read(connection.session) || spdylay_session_want_write(connection.session)) { int nfds = poll(pollfds, npollfds, -1); if(nfds == -1) { dief("poll", strerror(errno)); } if(pollfds[0].revents & (POLLIN | POLLOUT)) { exec_io(&connection); } if((pollfds[0].revents & POLLHUP) || (pollfds[0].revents & POLLERR)) { die("Connection error"); } ctl_poll(pollfds, &connection); } /* Resource cleanup */ spdylay_session_del(connection.session); SSL_shutdown(ssl); SSL_free(ssl); SSL_CTX_free(ssl_ctx); shutdown(fd, SHUT_WR); close(fd); request_free(&req); }
int server_main(char *home, char *dev, char *port, int udp, int ipv4, int log) { int lfd = -1, kdpfd, nfds, nfd, curfds, efd[2], refd[2], tunfd, i; unsigned int cpus = 0, threads, udp_cpu = 0; ssize_t ret; struct epoll_event *events; struct addrinfo hints, *ahead, *ai; auth_log = !!log; openlog("curvetun", LOG_PID | LOG_CONS | LOG_NDELAY, LOG_DAEMON); syslog(LOG_INFO, "curvetun server booting!\n"); syslog_maybe(!auth_log, LOG_INFO, "curvetun user logging disabled!\n"); parse_userfile_and_generate_user_store_or_die(home); 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_PASSIVE; ret = getaddrinfo(NULL, port, &hints, &ahead); if (ret < 0) syslog_panic("Cannot get address info!\n"); for (ai = ahead; ai != NULL && lfd < 0; ai = ai->ai_next) { lfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (lfd < 0) continue; if (ai->ai_family == AF_INET6) { #ifdef IPV6_V6ONLY ret = set_ipv6_only(lfd); if (ret < 0) { close(lfd); lfd = -1; continue; } #else close(lfd); lfd = -1; continue; #endif /* IPV6_V6ONLY */ } set_reuseaddr(lfd); set_mtu_disc_dont(lfd); ret = bind(lfd, ai->ai_addr, ai->ai_addrlen); if (ret < 0) { close(lfd); lfd = -1; continue; } if (!udp) { ret = listen(lfd, 5); if (ret < 0) { close(lfd); lfd = -1; continue; } } if (ipv4 == -1) { ipv4 = (ai->ai_family == AF_INET6 ? 0 : (ai->ai_family == AF_INET ? 1 : -1)); } syslog_maybe(auth_log, LOG_INFO, "curvetun on IPv%d via %s " "on port %s!\n", ai->ai_family == AF_INET ? 4 : 6, udp ? "UDP" : "TCP", port); syslog_maybe(auth_log, LOG_INFO, "Allowed overlay proto is " "IPv%d!\n", ipv4 ? 4 : 6); } freeaddrinfo(ahead); if (lfd < 0 || ipv4 < 0) syslog_panic("Cannot create socket!\n"); tunfd = tun_open_or_die(dev ? dev : DEVNAME_SERVER, IFF_TUN | IFF_NO_PI); pipe_or_die(efd, O_NONBLOCK); pipe_or_die(refd, O_NONBLOCK); set_nonblocking(lfd); events = xzmalloc(MAX_EPOLL_SIZE * sizeof(*events)); for (i = 0; i < MAX_EPOLL_SIZE; ++i) events[i].data.fd = -1; kdpfd = epoll_create(MAX_EPOLL_SIZE); if (kdpfd < 0) syslog_panic("Cannot create socket!\n"); set_epoll_descriptor(kdpfd, EPOLL_CTL_ADD, lfd, udp ? EPOLLIN | EPOLLET | EPOLLONESHOT : EPOLLIN); set_epoll_descriptor(kdpfd, EPOLL_CTL_ADD, efd[0], EPOLLIN); set_epoll_descriptor(kdpfd, EPOLL_CTL_ADD, refd[0], EPOLLIN); set_epoll_descriptor(kdpfd, EPOLL_CTL_ADD, tunfd, EPOLLIN | EPOLLET | EPOLLONESHOT); curfds = 4; trie_init(); cpus = get_number_cpus_online(); threads = cpus * THREADS_PER_CPU; if (!ispow2(threads)) syslog_panic("Thread number not power of two!\n"); threadpool = xzmalloc(sizeof(*threadpool) * threads); thread_spawn_or_panic(cpus, efd[1], refd[1], tunfd, ipv4, udp); init_cpusched(threads); register_socket(tunfd); register_socket(lfd); syslog(LOG_INFO, "curvetun up and running!\n"); while (likely(!sigint)) { nfds = epoll_wait(kdpfd, events, curfds, -1); if (nfds < 0) { syslog(LOG_ERR, "epoll_wait error: %s\n", strerror(errno)); break; } for (i = 0; i < nfds; ++i) { if (unlikely(events[i].data.fd < 0)) continue; if (events[i].data.fd == lfd && !udp) { int ncpu; char hbuff[256], sbuff[256]; struct sockaddr_storage taddr; socklen_t tlen; tlen = sizeof(taddr); nfd = accept(lfd, (struct sockaddr *) &taddr, &tlen); if (nfd < 0) { syslog(LOG_ERR, "accept error: %s\n", strerror(errno)); continue; } if (curfds + 1 > MAX_EPOLL_SIZE) { close(nfd); continue; } curfds++; ncpu = register_socket(nfd); memset(hbuff, 0, sizeof(hbuff)); memset(sbuff, 0, sizeof(sbuff)); getnameinfo((struct sockaddr *) &taddr, tlen, hbuff, sizeof(hbuff), sbuff, sizeof(sbuff), NI_NUMERICHOST | NI_NUMERICSERV); syslog_maybe(auth_log, LOG_INFO, "New connection " "from %s:%s (%d active client connections) - id %d on CPU%d", hbuff, sbuff, curfds-4, nfd, ncpu); set_nonblocking(nfd); set_socket_keepalive(nfd); set_tcp_nodelay(nfd); ret = set_epoll_descriptor2(kdpfd, EPOLL_CTL_ADD, nfd, EPOLLIN | EPOLLET | EPOLLONESHOT); if (ret < 0) { close(nfd); curfds--; continue; } } else if (events[i].data.fd == refd[0]) { int fd_one; ret = read_exact(refd[0], &fd_one, sizeof(fd_one), 1); if (ret != sizeof(fd_one) || fd_one <= 0) continue; ret = set_epoll_descriptor2(kdpfd, EPOLL_CTL_MOD, fd_one, EPOLLIN | EPOLLET | EPOLLONESHOT); if (ret < 0) { close(fd_one); continue; } } else if (events[i].data.fd == efd[0]) { int fd_del, test; ret = read_exact(efd[0], &fd_del, sizeof(fd_del), 1); if (ret != sizeof(fd_del) || fd_del <= 0) continue; ret = read(fd_del, &test, sizeof(test)); if (ret < 0 && errno == EBADF) continue; ret = set_epoll_descriptor2(kdpfd, EPOLL_CTL_DEL, fd_del, 0); if (ret < 0) { close(fd_del); continue; } close(fd_del); curfds--; unregister_socket(fd_del); syslog_maybe(auth_log, LOG_INFO, "Closed connection " "with id %d (%d active client connections remain)\n", fd_del, curfds-4); } else { int cpu, fd_work = events[i].data.fd; if (!udp) cpu = socket_to_cpu(fd_work); else udp_cpu = (udp_cpu + 1) & (threads - 1); write_exact(threadpool[udp ? udp_cpu : cpu].efd[1], &fd_work, sizeof(fd_work), 1); } } } syslog(LOG_INFO, "curvetun prepare shut down!\n"); close(lfd); close(efd[0]); close(efd[1]); close(refd[0]); close(refd[1]); close(tunfd); thread_finish(cpus); xfree(threadpool); xfree(events); unregister_socket(lfd); unregister_socket(tunfd); destroy_cpusched(); trie_cleanup(); destroy_user_store(); syslog(LOG_INFO, "curvetun shut down!\n"); closelog(); return 0; }
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); }
/* * Fetches the resource denoted by |uri|. */ static void fetch_uri(const struct URI *uri) { spdylay_session_callbacks callbacks; int fd; struct Request req; struct Connection connection; int rv; nfds_t npollfds = 1; struct pollfd pollfds[1]; uint16_t spdy_proto_version = 3; request_init(&req, uri); setup_spdylay_callbacks(&callbacks); /* Establish connection and setup SSL */ fd = connect_to(req.host, req.port); if (-1 == fd) abort (); connection.fd = fd; connection.want_io = IO_NONE; /* Here make file descriptor non-block */ make_non_block(fd); set_tcp_nodelay(fd); printf("[INFO] SPDY protocol version = %d\n", spdy_proto_version); rv = spdylay_session_client_new(&connection.session, spdy_proto_version, &callbacks, &connection); if(rv != 0) { diec("spdylay_session_client_new", rv); } /* Submit the HTTP request to the outbound queue. */ submit_request(&connection, &req); pollfds[0].fd = fd; ctl_poll(pollfds, &connection); /* Event loop */ while(spdylay_session_want_read(connection.session) || spdylay_session_want_write(connection.session)) { int nfds = poll(pollfds, npollfds, -1); if(nfds == -1) { dief("poll", strerror(errno)); } if(pollfds[0].revents & (POLLIN | POLLOUT)) { exec_io(&connection); } if((pollfds[0].revents & POLLHUP) || (pollfds[0].revents & POLLERR)) { die("Connection error"); } ctl_poll(pollfds, &connection); } /* Resource cleanup */ spdylay_session_del(connection.session); shutdown(fd, SHUT_WR); MHD_socket_close_(fd); request_free(&req); }