Exemplo n.º 1
0
void
consumer_start(void *arg) {
    uv_loop_t loop;
    struct server_context *server = arg;

#ifndef CROSS_COMPILE
    char name[24] = {0};
    sprintf(name, "consumer-%d", server->index + 1);
    pthread_setname_np(pthread_self(), name);
#endif

    uv_loop_init(&loop);

    struct resolver_context *res = NULL;
    if (server->nameserver_num >= 0) {
        res = resolver_init(&loop, 0,
          server->nameserver_num == 0 ? NULL : server->nameservers, server->nameserver_num);
        loop.data = res;
    }

    tcp_bind(&loop, server);

    if (server->udprelay) {
        udprelay_start(&loop, server);
    }

    uv_run(&loop, UV_RUN_DEFAULT);

    close_loop(&loop);

    if (server->nameserver_num >= 0) {
        resolver_destroy(res);
    }

    uv_sem_post(&server->semaphore);
}
Exemplo n.º 2
0
int
main(int argc, char *argv[]) {
    int rc;
    uv_loop_t *loop;

    parse_opts(argc, argv);

#if !defined(_WIN32)
    if (xsignal) {
        return signal_process(xsignal, pidfile);
    }
#endif

    if (!password || !server_addr_buf) {
        print_usage(argv[0]);
        return 1;
    }

    init();

#if !defined(_WIN32)
    if (daemon_mode) {
        if (daemonize()) {
            return 1;
        }
        if (already_running(pidfile)) {
            logger_stderr("xsocks already running.");
            return 1;
        }
    }
#endif

    loop = uv_default_loop();

    rc = resolve_addr(local_addr, &bind_addr);
    if (rc) {
        logger_stderr("invalid local address");
        return 1;
    }

    rc = resolve_addr(server_addr_buf, &server_addr);
    if (rc) {
        logger_stderr("invalid server address");
        return 1;
    }

    udprelay_init();

    if (concurrency <= 1) {
        struct server_context ctx;
        ctx.udprelay = 1;
        ctx.udp_fd = create_socket(SOCK_DGRAM, 0);
        ctx.local_addr = &bind_addr;
        ctx.server_addr = &server_addr;

        uv_tcp_init(loop, &ctx.tcp);
        rc = uv_tcp_bind(&ctx.tcp, &bind_addr, 0);
        if (rc) {
            logger_stderr("bind error: %s", uv_strerror(rc));
            return 1;
        }
        rc = uv_listen((uv_stream_t*)&ctx.tcp, 128, client_accept_cb);
        if (rc == 0) {
            logger_log(LOG_INFO, "listening on %s", local_addr);

#if !defined(_WIN32)
            setup_signal(loop, signal_cb, &ctx);
#endif

            udprelay_start(loop, &ctx);

            uv_run(loop, UV_RUN_DEFAULT);

            close_loop(loop);

        } else {
            logger_stderr("listen error: %s", uv_strerror(rc));
        }

    } else {
#if !defined(_WIN32)
        struct server_context *servers = calloc(concurrency, sizeof(servers[0]));
        for (int i = 0; i < concurrency; i++) {
            struct server_context *ctx = servers + i;
            ctx->index = i;
            ctx->tcp_fd = create_socket(SOCK_STREAM, 1);
            ctx->udp_fd = create_socket(SOCK_DGRAM, 1);
            ctx->udprelay = 1;
            ctx->accept_cb = client_accept_cb;
            ctx->local_addr = &bind_addr;
            ctx->server_addr = &server_addr;
            rc = uv_sem_init(&ctx->semaphore, 0);
            rc = uv_thread_create(&ctx->thread_id, consumer_start, ctx);
        }

        logger_log(LOG_INFO, "listening on %s", local_addr);

        setup_signal(loop, signal_cb, servers);

        uv_run(loop, UV_RUN_DEFAULT);

        close_loop(loop);

        for (int i = 0; i < concurrency; i++) {
            uv_sem_wait(&servers[i].semaphore);
        }
        free(servers);
#else
        logger_stderr("don't support multithreading.");
        return 1;
#endif
	}

    udprelay_destroy();

#if !defined(_WIN32)
    if (daemon_mode) {
        delete_pidfile(pidfile);
    }
#endif

    logger_exit();

    return 0;
}
Exemplo n.º 3
0
int
main(int argc, char *argv[]) {
    int rc;
    uv_loop_t *loop;
    struct sockaddr bind_addr;

    parse_opts(argc, argv);

    if (xsignal) {
        return signal_process(xsignal, pidfile);
    }

    if (!tunnel_mode || !dest_addr || !password) {
        print_usage(argv[0]);
        return 1;
    }

    if (init()) {
        return 1;
    }

    if (daemon_mode) {
        if (daemonize()) {
            return 1;
        }
        if (already_running(pidfile)) {
            logger_stderr("xtunnel already running.");
            return 1;
        }
    }

    loop = uv_default_loop();

    rc = resolve_addr(source_addr, &bind_addr);
    if (rc) {
        logger_stderr("invalid local address");
        return 1;
    }

    rc = resolve_addr(dest_addr, &target_addr);
    if (rc) {
        logger_stderr("invalid target address");
        return 1;
    }

    if (concurrency <= 1) {
        struct server_context ctx;
        uv_tcp_init(loop, &ctx.tcp);
        rc = uv_tcp_bind(&ctx.tcp, &bind_addr, 0);
        if (rc) {
            logger_stderr("bind error: %s", uv_strerror(rc));
            return 1;
        }
        rc = uv_listen((uv_stream_t*)&ctx.tcp, SOMAXCONN, source_accept_cb);
        if (rc == 0) {
            logger_log(LOG_INFO, "listening on %s", source_addr);

            setup_signal(loop, signal_cb, &ctx);

            uv_run(loop, UV_RUN_DEFAULT);

            close_loop(loop);

        } else {
            logger_stderr("listen error: %s", uv_strerror(rc));
        }

    } else {
        struct server_context *servers = calloc(concurrency, sizeof(servers[0]));
        for (int i = 0; i < concurrency; i++) {
            struct server_context *ctx = servers + i;
            ctx->index = i;
            ctx->tcp_fd = create_socket(SOCK_STREAM, 1);
            ctx->accept_cb = source_accept_cb;
            ctx->nameserver_num = -1;
            ctx->local_addr = &bind_addr;
            rc = uv_sem_init(&ctx->semaphore, 0);
            rc = uv_thread_create(&ctx->thread_id, consumer_start, ctx);
        }

        logger_log(LOG_INFO, "listening on %s", source_addr);

        setup_signal(loop, signal_cb, servers);

        uv_run(loop, UV_RUN_DEFAULT);

        close_loop(loop);

        for (int i = 0; i < concurrency; i++) {
            uv_sem_wait(&servers[i].semaphore);
        }
        free(servers);
    }

    if (daemon_mode) {
        delete_pidfile(pidfile);
    }

    return 0;
}