// force close socket fd static void net_force_close(struct net_pool* np, struct net_socket* ns) { log_debug("net_force_close ...\n"); // FIXME: could not be delete, the buffer would be reused again // wbuffer_delete(&(ns->wbuff)); // rbuffer_delete(&(ns->rbuff)); // clear the buffer wbuffer_clear(&(ns->wbuff)); rbuffer_clear(&(ns->rbuff)); ns->status = SOCKET_STATUS_INVALID; if(ns->fd > 0) { poll_del(np->eventfd, ns->fd); socket_close(ns->fd); ns->fd = -1; } // reduce the count of client --np->count; np->onclose(np, ns->fd); net_remove_onlinechar(np, ns->id); }
int main(int argc, char **argv) { short revents; int i, listenfd, sockfd; int ret = 0; struct link *ln; struct addrinfo *server_ai = NULL; struct addrinfo *local_ai = NULL; struct addrinfo hint; check_ss_option(argc, argv, "client"); memset(&hint, 0, sizeof(hint)); hint.ai_family = AF_UNSPEC; hint.ai_socktype = SOCK_STREAM; ret = getaddrinfo(ss_opt.server_addr, ss_opt.server_port, &hint, &server_ai); if (ret != 0) { pr_warn("getaddrinfo error: %s\n", gai_strerror(ret)); goto out; } pr_ai_notice(server_ai, "server address"); ret = getaddrinfo(ss_opt.local_addr, ss_opt.local_port, &hint, &local_ai); if (ret != 0) { pr_warn("getaddrinfo error: %s\n", gai_strerror(ret)); goto out; } pr_ai_notice(local_ai, "listening address"); if (crypto_init(ss_opt.password, ss_opt.method) == -1) { ret = -1; goto out; } ss_init(); listenfd = do_listen(local_ai, "tcp"); clients[0].fd = listenfd; clients[0].events = POLLIN; while (1) { pr_debug("start polling\n"); ret = poll(clients, nfds, TCP_INACTIVE_TIMEOUT * 1000); if (ret == -1) err_exit("poll error"); else if (ret == 0) { reaper(); continue; } if (clients[0].revents & POLLIN) { sockfd = accept(clients[0].fd, NULL, NULL); if (sockfd == -1) { pr_warn("accept error\n"); } else if (poll_set(sockfd, POLLIN) == -1) { close(sockfd); } else { ln = create_link(sockfd, "client"); if (ln == NULL) { poll_del(sockfd); close(sockfd); } else { ln->server = server_ai; } } } for (i = 1; i < nfds; i++) { sockfd = clients[i].fd; if (sockfd == -1) continue; revents = clients[i].revents; if (revents == 0) continue; ln = get_link(sockfd); if (ln == NULL) { sock_warn(sockfd, "close: can't get link"); close(sockfd); continue; } if (revents & POLLIN) { client_do_pollin(sockfd, ln); } if (revents & POLLOUT) { client_do_pollout(sockfd, ln); } /* suppress the noise */ /* if (revents & POLLPRI) { */ /* sock_warn(sockfd, "POLLPRI"); */ /* } else if (revents & POLLERR) { */ /* sock_warn(sockfd, "POLLERR"); */ /* } else if (revents & POLLHUP) { */ /* sock_warn(sockfd, "POLLHUP"); */ /* } else if (revents & POLLNVAL) { */ /* sock_warn(sockfd, "POLLNVAL"); */ /* } */ } reaper(); } out: crypto_exit(); if (server_ai) freeaddrinfo(server_ai); if (local_ai) freeaddrinfo(local_ai); ss_exit(); if (ret == -1) exit(EXIT_FAILURE); else exit(EXIT_SUCCESS); }