예제 #1
0
static void accept_cb(EV_P_ ev_io *w, int revents)
{
    listen_ctx_t *listener = (listen_ctx_t *)w;
    struct sockaddr_storage destaddr;
    int err;

    int serverfd = accept(listener->fd, NULL, NULL);
    if (serverfd == -1) {
        ERROR("accept");
        return;
    }

    err = getdestaddr(serverfd, &destaddr);
    if (err) {
        ERROR("getdestaddr");
        return;
    }

    setnonblocking(serverfd);
    int opt = 1;
    setsockopt(serverfd, SOL_TCP, TCP_NODELAY, &opt, sizeof(opt));
#ifdef SO_NOSIGPIPE
    setsockopt(serverfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif

    int index                    = rand() % listener->remote_num;
    struct sockaddr *remote_addr = listener->remote_addr[index];

    int remotefd = socket(remote_addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
    if (remotefd < 0) {
        ERROR("socket");
        return;
    }

    setsockopt(remotefd, SOL_TCP, TCP_NODELAY, &opt, sizeof(opt));
#ifdef SO_NOSIGPIPE
    setsockopt(remotefd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif

    // Setup
    setnonblocking(remotefd);

    server_t *server = new_server(serverfd, listener->method);
    remote_t *remote = new_remote(remotefd, listener->timeout);
    server->remote   = remote;
    remote->server   = server;
    server->destaddr = destaddr;

    connect(remotefd, remote_addr, get_sockaddr_len(remote_addr));
    // listen to remote connected event
    ev_io_start(EV_A_ & remote->send_ctx->io);
    ev_io_start(EV_A_ & server->recv_ctx->io);
    ev_timer_start(EV_A_ & remote->send_ctx->watcher);
}
예제 #2
0
static void
accept_cb(EV_P_ ev_io *w, int revents)
{
    listen_ctx_t *listener = (listen_ctx_t *)w;
    struct sockaddr_storage destaddr;
    int err;

    int serverfd = accept(listener->fd, NULL, NULL);
    if (serverfd == -1) {
        ERROR("accept");
        return;
    }

    err = getdestaddr(serverfd, &destaddr);
    if (err) {
        ERROR("getdestaddr");
        return;
    }

    setnonblocking(serverfd);
    int opt = 1;
    setsockopt(serverfd, SOL_TCP, TCP_NODELAY, &opt, sizeof(opt));
#ifdef SO_NOSIGPIPE
    setsockopt(serverfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif

    int index                    = rand() % listener->remote_num;
    struct sockaddr *remote_addr = listener->remote_addr[index];

    int remotefd = socket(remote_addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
    if (remotefd == -1) {
        ERROR("socket");
        return;
    }

    // Set flags
    setsockopt(remotefd, SOL_TCP, TCP_NODELAY, &opt, sizeof(opt));
#ifdef SO_NOSIGPIPE
    setsockopt(remotefd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif

    // Enable TCP keepalive feature
    int keepAlive    = 1;
    int keepIdle     = 40;
    int keepInterval = 20;
    int keepCount    = 5;
    setsockopt(remotefd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
    setsockopt(remotefd, SOL_TCP, TCP_KEEPIDLE, (void *)&keepIdle, sizeof(keepIdle));
    setsockopt(remotefd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
    setsockopt(remotefd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));

    // Set non blocking
    setnonblocking(remotefd);

    // Enable MPTCP
    if (listener->mptcp == 1) {
        int err = setsockopt(remotefd, SOL_TCP, MPTCP_ENABLED, &opt, sizeof(opt));
        if (err == -1) {
            ERROR("failed to enable multipath TCP");
        }
    }

    server_t *server = new_server(serverfd, listener->method);
    remote_t *remote = new_remote(remotefd, listener->timeout);
    server->remote   = remote;
    remote->server   = server;
    server->destaddr = destaddr;

    int r = connect(remotefd, remote_addr, get_sockaddr_len(remote_addr));

    if (r == -1 && errno != CONNECT_IN_PROGRESS) {
        ERROR("connect");
        close_and_free_remote(EV_A_ remote);
        close_and_free_server(EV_A_ server);
        return;
    }

    // listen to remote connected event
    ev_io_start(EV_A_ & remote->send_ctx->io);
    ev_timer_start(EV_A_ & remote->send_ctx->watcher);
    ev_io_start(EV_A_ & server->recv_ctx->io);
}
예제 #3
0
static void
poll_cb(uv_poll_t *watcher, int status, int events) {
 	char buffer[1024] = {0};
    char control_buffer[64] = {0};
    struct iovec iov[1];
    struct msghdr msg;
    struct sockaddr client_addr;
    struct server_context *server = container_of(watcher, struct server_context, watcher);

    if (status >= 0) {
        msg.msg_name = &client_addr;
        msg.msg_namelen = sizeof(client_addr);
        msg.msg_control = control_buffer;
        msg.msg_controllen = sizeof(control_buffer);
        iov[0].iov_base = buffer;
        iov[0].iov_len = sizeof(buffer);
        msg.msg_iov = iov;
        msg.msg_iovlen = 1;

        int msglen = recvmsg(watcher->io_watcher.fd, &msg, 0);
        if (msglen <= 0) {
            logger_stderr("receive from client error: %s", strerror(errno));
        }

        struct sockaddr dest_addr;
        if (getdestaddr(&msg, &dest_addr)) {
            logger_stderr("can not get destination address");
        }

        int addrlen = dest_addr.sa_family == AF_INET ? IPV4_HEADER_LEN : IPV6_HEADER_LEN;

        int mlen = addrlen + msglen;
        int clen = PRIMITIVE_BYTES + mlen;
        uint8_t *c = malloc(clen);
        uint8_t *m = c + PRIMITIVE_BYTES;

        /*
         *
         * xsocks UDP Request
         * +------+----------+----------+----------+
         * | ATYP | DST.ADDR | DST.PORT |   DATA   |
         * +------+----------+----------+----------+
         * |  1   | Variable |    2     | Variable |
         * +------+----------+----------+----------+
         *
         */
        if (dest_addr.sa_family == AF_INET) {
            struct sockaddr_in *addr = (struct sockaddr_in *)&dest_addr;
            m[0] = ATYP_IPV4;
            memcpy(m + 1, &addr->sin_addr, 4);
            memcpy(m + 1 + 4, &addr->sin_port, 2);

        } else {
            struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&dest_addr;
            m[0] = ATYP_IPV6;
            memcpy(m + 1, &addr->sin6_addr, 16);
            memcpy(m + 1 + 16, &addr->sin6_port, 2);
        }
        memcpy(m + addrlen, buffer, msglen);

        int rc = crypto_encrypt(c, m, mlen);
        if (!rc) {
            char key[KEY_BYTES + 1] = {0};
            crypto_generickey((uint8_t *)key, sizeof(key) -1, (uint8_t *)&client_addr, sizeof(client_addr), NULL, 0);

            struct client_context *client = NULL;
            uv_mutex_lock(&mutex);
            cache_lookup(cache, key, (void *)&client);
            uv_mutex_unlock(&mutex);
            if (client == NULL) {
                client = new_client();
                client->addr = client_addr;
                memcpy(client->key, key, sizeof(key));

                uv_timer_init(watcher->loop, client->timer);

                uv_udp_init(watcher->loop, &client->server_handle);
                client->server_handle.data = client;
                uv_udp_recv_start(&client->server_handle, server_alloc_cb, server_recv_cb);

                uv_mutex_lock(&mutex);
                cache_insert(cache, client->key, (void *)client);
                uv_mutex_unlock(&mutex);
            }

            reset_timer(client);
            forward_to_server(server->server_addr, client, c, clen);
        }
    }
}
예제 #4
0
static void accept_cb(EV_P_ ev_io *w, int revents)
{
    struct listen_ctx *listener = (struct listen_ctx *)w;
    struct sockaddr_storage destaddr;
    int err;

    int clientfd = accept(listener->fd, NULL, NULL);
    if (clientfd == -1) {
        ERROR("accept");
        return;
    }

    err = getdestaddr(clientfd, &destaddr);
    if (err) {
        ERROR("getdestaddr");
        return;
    }

    setnonblocking(clientfd);
#ifdef SO_NOSIGPIPE
    int opt = 1;
    setsockopt(clientfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif

    struct addrinfo hints, *res;
    int sockfd;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    int index = rand() % listener->remote_num;
    err =
        getaddrinfo(listener->remote_addr[index].host,
                    listener->remote_addr[index].port, &hints, &res);
    if (err) {
        ERROR("getaddrinfo");
        return;
    }

    sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    if (sockfd < 0) {
        ERROR("socket");
        freeaddrinfo(res);
        return;
    }

#ifdef SO_NOSIGPIPE
    setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif

    // Setup
    setnonblocking(sockfd);

    struct server *server = new_server(clientfd, listener->method);
    struct remote *remote = new_remote(sockfd, listener->timeout);
    server->remote = remote;
    remote->server = server;
    server->destaddr = destaddr;

    connect(sockfd, res->ai_addr, res->ai_addrlen);
    freeaddrinfo(res);
    // listen to remote connected event
    ev_io_start(EV_A_ & remote->send_ctx->io);
    ev_timer_start(EV_A_ & remote->send_ctx->watcher);
}