示例#1
0
int main( int argc, const char** argv ){
  ss_info info;
  ss_init( &info, argc, argv );
  if ( 0 == info.exit_status ){
    ss_run( &info );
  }
  return ss_exit( &info );
}
示例#2
0
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);
}