Example #1
0
static void
remote_recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
    struct remote_context *remote;
    struct client_context *client;

    remote = stream->data;
    client = remote->client;

    if (nread > 0) {
        reset_timer(remote);
        uv_read_stop(&remote->handle.stream);
        int clen = nread + PRIMITIVE_BYTES;
        uint8_t *c = remote->buf + HEADER_BYTES;
        int rc = crypto_encrypt(c, (uint8_t*)buf->base, nread);
        if (!rc) {
            forward_to_client(client, c, clen);
        } else {
            logger_log(LOG_ERR, "invalid tcp packet");
            close_client(client);
            close_remote(remote);
        }

    } else if (nread < 0){
        if (nread != UV_EOF) {
            logger_log(LOG_ERR, "receive from %s failed: %s", client->target_addr, uv_strerror(nread));
        }
        close_client(client);
        close_remote(remote);
    }
}
Example #2
0
static void
client_recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
    struct client_context *client = stream->data;
    struct remote_context *remote = client->remote;
    int clen;

    if (nread > 0) {
        reset_timer(remote);
        uv_read_stop(&client->handle.stream);

        switch (client->stage) {
        case XSTAGE_HANDSHAKE:
            if (verify_methods(buf->base, nread)) {
                handshake(client);
            } else {
                logger_log(LOG_ERR, "invalid method packet");
                close_client(client);
                close_remote(remote);
            }

            break;

        case XSTAGE_REQUEST:
            if (verify_request(buf->base, nread)) {
                request_start(client, buf->base);
            } else {
                logger_log(LOG_ERR, "invalid request packet");
                close_client(client);
                close_remote(remote);
            }

            break;

        case XSTAGE_FORWARD:
            clen = nread + PRIMITIVE_BYTES;
            uint8_t *c = client->buf + HEADER_BYTES;
            int rc = crypto_encrypt(c, (uint8_t*)buf->base, nread);
            if (rc) {
                logger_log(LOG_ERR, "encrypt failed");
                close_client(client);
                close_remote(remote);
            }
            forward_to_remote(remote, c, clen);

            break;

        default:
            break;
        }

    } else if (nread < 0) {
        if (nread != UV_EOF) {
            char addrbuf[INET6_ADDRSTRLEN + 1] = {0};
            uint16_t port = ip_name(&client->addr, addrbuf, sizeof addrbuf);
            logger_log(LOG_ERR, "receive from %s:%d failed: %s", addrbuf, port, uv_strerror(nread));
        }
        close_client(client);
        close_remote(remote);
    }
}
Example #3
0
static void
remote_recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
    struct remote_context *remote;
    struct client_context *client;

    remote = stream->data;
    client = remote->client;

    if (nread > 0) {
        reset_timer(remote);
        struct packet *packet = &remote->packet;
        int rc = packet_filter(packet, buf->base, nread);
        if (rc == PACKET_COMPLETED) {
            int clen = packet->size;
            int mlen = packet->size - PRIMITIVE_BYTES;
            uint8_t *c = packet->buf, *m = packet->buf;

            assert(mlen > 0 && mlen <= MAX_PACKET_SIZE - PRIMITIVE_BYTES);

            int err = crypto_decrypt(m, c, clen);
            if (err) {
                goto error;
            }

            uv_read_stop(&remote->handle.stream);
            forward_to_client(client, m, mlen);

        } else if (rc == PACKET_INVALID) {
            goto error;
        }

    } else if (nread < 0){
        if (nread != UV_EOF && verbose) {
            char addrbuf[INET6_ADDRSTRLEN + 1];
            int port = ip_name(&client->target_addr, addrbuf, sizeof(addrbuf));
            logger_log(LOG_ERR, "receive from %s:%d failed: %s", addrbuf, port, uv_strerror(nread));
        }
        close_client(client);
        close_remote(remote);
    }

    return;

error:
    logger_log(LOG_ERR, "invalid tcp packet");
    if (verbose) {
        dump_hex(buf->base, nread, "invalid tcp Packet");
    }
    close_client(client);
    close_remote(remote);
}
Example #4
0
void
client_accept_cb(uv_stream_t *server, int status) {
    struct client_context *client = new_client();
    struct remote_context *remote = new_remote(idle_timeout);

    client->remote = remote;
    remote->client = client;

    uv_timer_init(server->loop, remote->timer);

    uv_tcp_init(server->loop, &client->handle.tcp);
    uv_tcp_init(server->loop, &remote->handle.tcp);


    int rc = uv_accept(server, &client->handle.stream);
    if (rc == 0) {
        int namelen = sizeof client->addr;
        uv_tcp_getpeername(&client->handle.tcp, &client->addr, &namelen);
        reset_timer(remote); // start timer
        connect_to_remote(remote);
    } else {
        logger_log(LOG_ERR, "accept error: %s", uv_strerror(rc));
        close_client(client);
        close_remote(remote);
    }
}
Example #5
0
static void
client_send_cb(uv_write_t *req, int status) {
    struct client_context *client = req->data;
    struct remote_context *remote = client->remote;

    if (status == 0) {
        if (client->stage == XSTAGE_REQUEST) {
            receive_from_client(client);

        } else if (client->stage == XSTAGE_FORWARD) {
            receive_from_remote(remote);

        } else if (client->stage == XSTAGE_TERMINATE) {
            close_client(client);
            close_remote(remote);
        }

    } else {
        char addrbuf[INET6_ADDRSTRLEN + 1] = {0};
        int port = ip_name(&client->addr, addrbuf, sizeof addrbuf);
        if (client->stage == XSTAGE_FORWARD) {
            logger_log(LOG_ERR, "%s:%d <- %s failed: %s", addrbuf, port, client->target_addr, uv_strerror(status));
        } else {
            logger_log(LOG_ERR, "forward to %s:%d failed: %s", addrbuf, port, uv_strerror(status));
        }
    }

    free(req);
}
Example #6
0
static void
remote_recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
    struct remote_context *remote;
    struct client_context *client;

    remote = stream->data;
    client = remote->client;

    if (nread > 0) {
        reset_timer(remote);
        struct packet *packet = &remote->packet;
        int rc = packet_filter(packet, buf->base, nread);
        if (rc == PACKET_COMPLETED) {
            uint8_t *m = packet->buf;
            int mlen = packet->size - PRIMITIVE_BYTES;

            int err = crypto_decrypt(m, packet->buf, packet->size);
            if (err) {
                goto error;
            }

            uv_read_stop(&remote->handle.stream);
            forward_to_client(client, m, mlen);

        } else if (rc == PACKET_INVALID) {
            goto error;
        }

    } else if (nread < 0){
        if (nread != UV_EOF) {
            logger_log(LOG_ERR, "receive from %s failed: %s", dest_addr_buf, uv_strerror(nread));
        }
        close_client(client);
        close_remote(remote);
    }

    return;

error:
    logger_log(LOG_ERR, "invalid tcp packet");
    close_client(client);
    close_remote(remote);
}
Example #7
0
void
connect_to_remote(struct remote_context *remote) {
    remote->stage = XSTAGE_CONNECT;
    remote->connect_req.data = remote;
    int rc = uv_tcp_connect(&remote->connect_req, &remote->handle.tcp, &remote->addr, remote_connect_cb);
    if (rc) {
        logger_log(LOG_ERR, "connect to %s error: %s", remote->client->target_addr, uv_strerror(rc));
        close_client(remote->client);
        close_remote(remote);
    }
}
Example #8
0
static void
remote_timer_expire(uv_timer_t *handle) {
    struct remote_context *remote = handle->data;
    struct client_context *client = remote->client;
    if (verbose) {
        char addrbuf[INET6_ADDRSTRLEN + 1] = {0};
        uint16_t port = ip_name(&client->addr, addrbuf, sizeof addrbuf);
        logger_log(LOG_WARNING, "%s:%d <-> %s connection timeout", addrbuf, port, client->target_addr);
    }
    close_client(remote->client);
    close_remote(remote);
}
Example #9
0
void
connect_to_remote(struct remote_context *remote) {
    remote->stage = XSTAGE_CONNECT;
    remote->connect_req.data = remote;
    int rc = uv_tcp_connect(&remote->connect_req, &remote->handle.tcp, &server_addr, remote_connect_cb);
    if (rc) {
        char addrbuf[INET6_ADDRSTRLEN + 1];
        ip_name(&server_addr, addrbuf, sizeof(addrbuf));
        logger_log(LOG_ERR, "connect to %s error: %s", addrbuf, uv_strerror(rc));
        close_client(remote->client);
        close_remote(remote);
    }
}
Example #10
0
void
resolve_remote(struct remote_context *remote, char *host, uint16_t port) {
    if (verbose) {
        logger_log(LOG_INFO, "resolve %s", host);
    }
    struct resolver_context *dns = uv_key_get(&thread_resolver_key);
    remote->stage = XSTAGE_RESOLVE;
    remote->host_query = resolver_query(dns, host, port, resolve_cb, remote);
    if (remote->host_query == NULL) {
        remote->stage = XSTAGE_TERMINATE;
        close_client(remote->client);
        close_remote(remote);
    }
}
Example #11
0
static void
remote_timer_expire(uv_timer_t *handle) {
    struct remote_context *remote = handle->data;
    struct client_context *client = remote->client;
    if (verbose) {
        struct sockaddr peername;
        int namelen = sizeof peername;
        uv_tcp_getpeername(&client->handle.tcp, &peername, &namelen);
        char addr[INET6_ADDRSTRLEN + 1];
        int port = ip_name(&peername, addr, sizeof addr);
        logger_log(LOG_WARNING, "%s:%d <-> %s connection timeout", addr, port, dest_addr_buf);
    }
    close_client(client);
    close_remote(remote);
}
Example #12
0
static void
remote_timer_expire(uv_timer_t *handle) {
    struct remote_context *remote = handle->data;
    struct client_context *client = remote->client;
    if (verbose) {
        struct sockaddr peername;
        int namelen = sizeof peername;
        uv_tcp_getpeername(&client->handle.tcp, &peername, &namelen);
        char addr1[INET6_ADDRSTRLEN + 1];
        char addr2[INET6_ADDRSTRLEN + 1];
        int p1 = ip_name(&peername, addr1, sizeof addr2);
        int p2 = ip_name(&client->target_addr, addr2, sizeof(addr2));
        logger_log(LOG_WARNING, "%s:%d <-> %s:%d timeout", addr1, p1, addr2, p2);
    }
    close_client(client);
    close_remote(remote);
}
Example #13
0
static void
resolve_cb(struct sockaddr *addr, void *data) {
    struct remote_context *remote = data;

    if (addr == NULL) {
        logger_log(LOG_ERR, "resolve %s failed: %s",
          remote->client->target_addr, resolver_lasterror(remote->host_query));
        remote->stage = XSTAGE_TERMINATE;
        close_client(remote->client);
        close_remote(remote);

    } else {
        if (verbose) {
            logger_log(LOG_INFO, "connect to %s", remote->client->target_addr);
        }
        remote->addr = *addr;
        connect_to_remote(remote);
    }
}
Example #14
0
static void
remote_connect_cb(uv_connect_t *req, int status) {
    struct remote_context *remote = (struct remote_context *)req->data;
    struct client_context *client = remote->client;

    if (status == 0) {
        reset_timer(remote);
        client->stage = XSTAGE_FORWARD;
        remote->stage = XSTAGE_FORWARD;
        request_to_server(remote);
        receive_from_remote(remote);

    } else {
        if (status != UV_ECANCELED) {
            logger_log(LOG_ERR, "connect to server failed: %s", uv_strerror(status));
            close_client(client);
            close_remote(remote);
        }
    }
}
Example #15
0
static void
remote_connect_cb(uv_connect_t *req, int status) {
    struct remote_context *remote = (struct remote_context *)req->data;
    struct client_context *client = remote->client;

    if (status == 0) {
        reset_timer(remote);
        client->stage = XSTAGE_FORWARD;
        remote->stage = XSTAGE_FORWARD;
        request_to_server(remote);
        receive_from_remote(remote);

    } else {
        if (status != UV_ECANCELED) {
            char addrbuf[INET6_ADDRSTRLEN + 1];
            ip_name(&server_addr, addrbuf, sizeof(addrbuf));
            logger_log(LOG_ERR, "connect to %s failed: %s", addrbuf, uv_strerror(status));
            close_client(client);
            close_remote(remote);
        }
    }
}