Ejemplo n.º 1
0
int main()
{
    make_encryptor(NULL, &crypto, METHOD_SHADOWCRYPT, (uint8_t*)PASSWORD);

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PROXY_PORT);
    inet_pton(AF_INET, PROXY_IP_ADDR, &(addr.sin_addr));

    server_core((struct sockaddr*)&addr, sizeof(addr));

    return 0;
}
Ejemplo n.º 2
0
static void connect_cb(uv_stream_t* listener, int status)
{
	int n;

	if (status) {
		SHOW_UV_ERROR(listener->loop);
		return;
	}

	server_ctx *ctx = calloc(1, sizeof(server_ctx));
	ctx->handshake_buffer = calloc(1, HANDSHAKE_BUFFER_SIZE);

	if (!ctx || !ctx->handshake_buffer)
		FATAL("malloc() failed!");

	ctx->client.data = ctx;
	ctx->remote.data = ctx;
	
	make_encryptor(&crypto, &ctx->encoder, 0, NULL);

	n = uv_tcp_init(listener->loop, &ctx->client);
	if (n)
		SHOW_UV_ERROR_AND_EXIT(listener->loop);

	n = uv_accept(listener, (uv_stream_t *)(void *)&ctx->client);
	if (n)
		SHOW_UV_ERROR_AND_EXIT(listener->loop);

	n = uv_tcp_nodelay(&ctx->client, 1);
	if (n)
		SHOW_UV_ERROR_AND_EXIT(listener->loop);

	#ifdef KEEPALIVE_TIMEOUT
	n = uv_tcp_keepalive(&ctx->client, 1, KEEPALIVE_TIMEOUT);
	if (n)
		SHOW_UV_ERROR_AND_EXIT(listener->loop);
	#endif /* KEEPALIVE_TIMEOUT */

	n = uv_read_start((uv_stream_t *)(void *)&ctx->client, client_handshake_alloc_cb, client_handshake_read_cb);
	if (n)
		SHOW_UV_ERROR_AND_EXIT(listener->loop);

	LOGCONN(&ctx->client, "Accepted connection from %s");
}
Ejemplo n.º 3
0
int main(int argc, char *argv[])
{
	char **newargv = uv_setup_args(argc, argv);
	char *server_listen = SERVER_LISTEN;
	int server_port = SERVER_PORT;
	uint8_t *password = (uint8_t *)PASSWORD;
	uint8_t crypt_method = CRYPTO_METHOD;
	char *pid_path = PID_FILE;

	char opt;
	while((opt = getopt(argc, newargv, "l:p:k:f:m:")) != -1) { // not portable to windows
		switch(opt) {
			case 'l':
			    server_listen = optarg;
			    break;
			case 'p':
			    server_port = atoi(optarg);
			    break;
			case 'k':
			    password = (uint8_t *)optarg;
			    break;
			case 'f':
			    pid_path = optarg;
			    break;
			case 'm':
			    if (!strcmp("rc4", optarg))
			    	crypt_method = METHOD_RC4;
			    else if (!strcmp("shadow", optarg))
			    	crypt_method = METHOD_SHADOWCRYPT;
			    break;
			default:
				fprintf(stderr, USAGE, newargv[0]);
				abort();
		}
	}

	FILE *pid_file = fopen(pid_path, "wb");
	if (!pid_file)
		FATAL("fopen failed, %s", strerror(errno));
	fprintf(pid_file, "%d", getpid());
	fclose(pid_file);

	char *process_title = malloc(PROCESS_TITLE_LENGTH); // we do not like waste memory
	if (!process_title)
		FATAL("malloc() failed!");
	snprintf(process_title, PROCESS_TITLE_LENGTH, PROCESS_TITLE, server_port);
	uv_set_process_title(process_title);
	free(process_title);

	LOGI(WELCOME_MESSAGE);

	if (crypt_method == METHOD_SHADOWCRYPT)
		LOGI("Using shadowcrypt crypto");
	else if (crypt_method == METHOD_RC4)
		LOGI("Using RC4 crypto");
	else
		FATAL("Crypto unknown!");

	make_encryptor(NULL, &crypto, crypt_method, password);

	LOGI("Crypto ready");
	
	int n;
	uv_loop_t *loop = uv_default_loop();
	uv_tcp_t listener;

	struct sockaddr_in6 addr = uv_ip6_addr(server_listen, server_port);

	n = uv_tcp_init(loop, &listener);
	if (n)
		SHOW_UV_ERROR_AND_EXIT(loop);

	n = uv_tcp_bind6(&listener, addr);
	if (n)
		SHOW_UV_ERROR_AND_EXIT(loop);

	n = uv_listen((uv_stream_t*)(void *)&listener, 5, connect_cb);
	if (n)
		SHOW_UV_ERROR_AND_EXIT(loop);
	LOGI("Listening on %s:%d", server_listen, server_port);

	#ifndef NDEBUG
	setup_signal_handler(loop);
	#endif /* !NDEBUG */

	return uv_run(loop);
}
Ejemplo n.º 4
0
void child_core(int fd)
{
    /* make child encryptor*/
    make_encryptor(&crypto, &chd_crypto, 0, NULL);


    uint8_t buf[BUF_SIZE];
    size_t remote_addr_len;
    struct sockaddr *remote_addr;
    if (read_addr(fd, buf, &remote_addr, &remote_addr_len) != 0) {
        clean_exit(errno, "get remote addr error", 1, fd);
    }

    int remote_fd;
    if ((remote_fd = socket(remote_addr->sa_family, SOCK_STREAM, 0)) < 0) {
        clean_exit(errno, "cannot open socket", 1, fd);
    }

    int optval = 1;
    if (setsockopt(remote_fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval)) == -1) {
        clean_exit(errno, "set socket option error", 1, fd);
    }
        
    if (connect(remote_fd, remote_addr, remote_addr_len) < 0 ) {
        clean_exit(errno, "cannnot connect remote", 1, fd);
    }
    free(remote_addr);
    remote_addr = NULL;
    remote_addr_len = 0;


    /* use poll */
    struct pollfd fds[2];
    fds[0].fd = fd;
    fds[1].fd = remote_fd;
    fds[0].events = POLLIN | POLLERR | POLLHUP;
    fds[1].events = POLLIN | POLLERR | POLLHUP;

    size_t read_size;
    int rc;
    while (poll(fds, 2, -1) > 0) {
        if (fds[0].revents & (POLLIN | POLLHUP)) {
            rc = crypt_recv(fd, buf, BUF_SIZE);
	    if (rc > 0) {
	        read_size = (size_t)rc;
		if (sendall(remote_fd, buf, read_size, 0) < read_size) break;
            }
            else if (rc == 0) {
                fds[0].fd = -1;
                shutdown(fd, SHUT_RD);
                shutdown(remote_fd, SHUT_WR);
            }
            else {
                break;
            }
        }
        
        if (fds[1].revents & (POLLIN | POLLHUP)) {
            rc = recv(remote_fd, buf, BUF_SIZE, 0);
            if (read_size > 0) {
	        read_size = (size_t)rc;
		if (crypt_sendall(fd, buf, read_size) < read_size) break;
            }
            else if (read_size == 0) {
                fds[1].fd = -1;
                shutdown(fd, SHUT_WR);
                shutdown(remote_fd, SHUT_RD);              
            }
            else {
                break;
            }
        }

        if (fds[0].fd == fds[1].fd) clean_exit(0, "close all sock", 0);
        if ((fds[0].revents & POLLERR) || (fds[1].revents & POLLERR)) break;
    }
    clean_exit(errno, "socket pair error exit", 0);
}