void* listen_thread(void* p) { (void)p; AddressInfo* info = parse_address_info(); while (1) { int r = poll(info->fd, info->size, -1); if (r < 0) { log_warning("poll failed %s", strerror(errno)); continue; } for (int i = 0; i < info->size; ++i) { if (info->fd[i].revents != 0) { int client = accept(info->fd[i].fd, NULL, NULL); if (client < 0) { log_error("accept %d failed: %s", info->fd[i].fd, strerror(errno)); continue; } dispatch_client(client); } } } return NULL; }
int main(int argc, char * argv[]) { struct pollfd pfd[2]; if(argc > 1 && !strcmp(argv[1], "-g")) { get_stats(); exit(0); } /* register cleanup hooks */ signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); pfd[0].fd = open_socket(NSCD_SOCKET); if(pfd[0].fd < 0) return 1; pfd[1].fd = open_socket(NSCD_SOCKET_OLD); if(pfd[1].fd < 0) { close(pfd[0].fd); return 1; } pfd[0].events = POLLIN; pfd[1].events = POLLIN; /* In debug mode, we don't daemonize. We also print debugging * information about what is going on inside gnscd. */ if(argc < 2 || strcmp(argv[1], "-d")) { /* become a daemon */ daemon(0, 0); setsid(); write_pid(); /* ignore job control signals */ signal(SIGTTOU, SIG_IGN); signal(SIGTTIN, SIG_IGN); signal(SIGTSTP, SIG_IGN); } else debug = 1; /* don't die if a client closes a socket on us */ signal(SIGPIPE, SIG_IGN); /* make sure we don't get recursive calls */ __nss_disable_nscd(); if(cache_init() < 0) exit(1); /* listen for clients and dispatch them to threads */ for(;;) { int i; if(poll(pfd, 2, -1) < 0) if(errno != EINTR) exit(1); for(i = 0; i < 2; i++) { int client; if(!pfd[i].revents) continue; client = accept(pfd[i].fd, NULL, NULL); if(client < 0) /* odd... poll() says we can accept but accept failed? */ continue; if(dispatch_client(client) < 0) close(client); } } return 0; }
/* Create a connection to a host trough a socks5 * If success s contain a socket to server * * If listen port != 0, it means bind mode, * so host and port will be ignored * * Return: * -1, connection error, unavailable socks server * 0, connection error, socks5 negociation * 1, connection establish, socket is set in struct s */ int new_socket_with_socks(s_socket *s, char *sockshost, int socksport, char *username, char *password, char *host, int port, int listen, int version, int ssl, int cmd) { int maxfd = 0, res; fd_set set_read, set_write; s_socks_conf conf; s_socks_client_config config; conf.config.cli = &config; char method[] = { 0x00, 0x02 }; conf.config.cli->n_allowed_method = 2; conf.config.cli->allowed_method = method; /* If no username or password we don't use auth */ if ( username == NULL || password == NULL ) --conf.config.cli->n_allowed_method; conf.config.cli->loop = 1; conf.config.cli->cmd = cmd; conf.config.cli->host = host; conf.config.cli->port = port; conf.config.cli->listen = listen; conf.config.cli->version = version; conf.config.cli->username = username; conf.config.cli->password = password; //memcpy(&conf.config, &config, sizeof(s_socks_serv_cli_config)); s_client c; init_client (&c, 0, M_CLIENT, &conf); c.soc.soc = new_client_socket(sockshost, socksport, &c.soc.adrC, &c.soc.adrS); if ( c.soc.soc < 0 ){ return -1; } #ifdef HAVE_LIBSSL /* Init SSL here */ if (ssl == 1){ TRACE(L_DEBUG, "client: socks5 enable ssl ..."); c.soc.ssl = ssl_neogiciate_client(c.soc.soc); if ( c.soc.ssl == NULL ){ ERROR(L_VERBOSE, "client: ssl error"); return -3; } TRACE(L_DEBUG, "client: ssl ok."); } #endif /* HAVE_LIBSSL */ /* Select loop */ while (conf.config.cli->loop == 1 && c.soc.soc != -1) { FD_ZERO (&set_read); FD_ZERO (&set_write); maxfd = 0; /* Adds the socket in read fds */ init_select_client(&c.soc, &c.socks, &c.buf, &maxfd, &set_read, &set_write); res = select (maxfd+1, &set_read, &set_write, NULL, NULL); if (res > 0) { dispatch_client(&c, &set_read, &set_write); } else if ( res == 0){ }else if (res < 0) { if (errno == EINTR) ; /* Received signal, it does nothing */ else { perror ("select"); disconnection(&c); return -1; } } } memcpy(s, &c.soc, sizeof(s_socket)); return (c.soc.soc >= 0); }