Ejemplo n.º 1
0
static int do_unconfirmed(TCP_Server *TCP_server, uint32_t i)
{
    TCP_Secure_Connection *conn = &TCP_server->unconfirmed_connection_queue[i];

    if (conn->status != TCP_STATUS_UNCONFIRMED)
        return -1;

    uint8_t packet[MAX_PACKET_SIZE];
    int len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key, conn->recv_nonce,
              packet, sizeof(packet));

    if (len == 0) {
        return -1;
    } else if (len == -1) {
        kill_TCP_connection(conn);
        return -1;
    } else {
        int index_new;

        if ((index_new = confirm_TCP_connection(TCP_server, conn, packet, len)) == -1) {
            kill_TCP_connection(conn);
        } else {
            memset(conn, 0, sizeof(TCP_Secure_Connection));
        }

        return index_new;
    }
}
Ejemplo n.º 2
0
static void do_TCP_incomming(TCP_Server *TCP_server)
{
    uint32_t i;

    for (i = 0; i < MAX_INCOMMING_CONNECTIONS; ++i) {
        if (TCP_server->incomming_connection_queue[i].status != TCP_STATUS_CONNECTED)
            continue;

        int ret = read_connection_handshake(&TCP_server->incomming_connection_queue[i], TCP_server->secret_key);

        if (ret == -1) {
            kill_TCP_connection(&TCP_server->incomming_connection_queue[i]);
        } else if (ret == 1) {
            TCP_Secure_Connection *conn_old = &TCP_server->incomming_connection_queue[i];
            TCP_Secure_Connection *conn_new =
                &TCP_server->unconfirmed_connection_queue[TCP_server->unconfirmed_connection_queue_index % MAX_INCOMMING_CONNECTIONS];

            if (conn_new->status != TCP_STATUS_NO_STATUS)
                kill_TCP_connection(conn_new);

            memcpy(conn_new, conn_old, sizeof(TCP_Secure_Connection));
            memset(conn_old, 0, sizeof(TCP_Secure_Connection));
            ++TCP_server->unconfirmed_connection_queue_index;
        }
    }
}
Ejemplo n.º 3
0
static int do_incoming(TCP_Server *TCP_server, uint32_t i)
{
    if (TCP_server->incomming_connection_queue[i].status != TCP_STATUS_CONNECTED)
        return -1;

    int ret = read_connection_handshake(&TCP_server->incomming_connection_queue[i], TCP_server->secret_key);

    if (ret == -1) {
        kill_TCP_connection(&TCP_server->incomming_connection_queue[i]);
    } else if (ret == 1) {
        int index_new = TCP_server->unconfirmed_connection_queue_index % MAX_INCOMMING_CONNECTIONS;
        TCP_Secure_Connection *conn_old = &TCP_server->incomming_connection_queue[i];
        TCP_Secure_Connection *conn_new = &TCP_server->unconfirmed_connection_queue[index_new];

        if (conn_new->status != TCP_STATUS_NO_STATUS)
            kill_TCP_connection(conn_new);

        memcpy(conn_new, conn_old, sizeof(TCP_Secure_Connection));
        memset(conn_old, 0, sizeof(TCP_Secure_Connection));
        ++TCP_server->unconfirmed_connection_queue_index;

        return index_new;
    }

    return -1;
}
Ejemplo n.º 4
0
static void do_TCP_unconfirmed(TCP_Server *TCP_server)
{
    uint32_t i;

    for (i = 0; i < MAX_INCOMMING_CONNECTIONS; ++i) {
        TCP_Secure_Connection *conn = &TCP_server->unconfirmed_connection_queue[i];

        if (conn->status != TCP_STATUS_UNCONFIRMED)
            continue;

        uint8_t packet[MAX_PACKET_SIZE];
        int len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key, conn->recv_nonce,
                  packet, sizeof(packet));

        if (len == 0) {
            continue;
        } else if (len == -1) {
            kill_TCP_connection(conn);
            continue;
        } else {
            if (confirm_TCP_connection(TCP_server, conn, packet, len) == -1) {
                kill_TCP_connection(conn);
            } else {
                memset(conn, 0, sizeof(TCP_Secure_Connection));
            }
        }
    }
}
Ejemplo n.º 5
0
static void do_TCP_unconfirmed(TCP_Server *TCP_server)
{
    uint32_t i;

    for (i = 0; i < MAX_INCOMMING_CONNECTIONS; ++i) {
        TCP_Secure_Connection *conn = &TCP_server->unconfirmed_connection_queue[i];

        if (conn->status != TCP_STATUS_UNCONFIRMED)
            continue;

        uint8_t packet[MAX_PACKET_SIZE];
        int len = read_packet_TCP_secure_connection(conn, packet, sizeof(packet));

        if (len == 0) {
            continue;
        } else if (len == -1) {
            kill_TCP_connection(conn);
            continue;
        } else {
            //TODO
            confirm_TCP_connection(conn, packet, len);
            kill_TCP_connection(conn);
        }
    }
}
Ejemplo n.º 6
0
static void do_TCP_confirmed(TCP_Server *TCP_server)
{
    uint32_t i;

    for (i = 0; i < TCP_server->size_accepted_connections; ++i) {
        TCP_Secure_Connection *conn = &TCP_server->accepted_connection_array[i];

        if (conn->status != TCP_STATUS_CONFIRMED)
            continue;

        if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY)) {
            uint8_t ping[1 + sizeof(uint64_t)];
            ping[0] = TCP_PACKET_PING;
            uint64_t ping_id = random_64b();

            if (!ping_id)
                ++ping_id;

            memcpy(ping + 1, &ping_id, sizeof(uint64_t));
            int ret = write_packet_TCP_secure_connection(conn, ping, sizeof(ping));

            if (ret == 1) {
                conn->last_pinged = unix_time();
                conn->ping_id = ping_id;
            }
        }

        if (conn->ping_id && is_timeout(conn->last_pinged, TCP_PING_TIMEOUT)) {
            kill_TCP_connection(conn);
            del_accepted(TCP_server, i);
            continue;
        }

        send_pending_data(conn);
        uint8_t packet[MAX_PACKET_SIZE];
        int len;

        while ((len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key,
                      conn->recv_nonce, packet, sizeof(packet)))) {
            if (len == -1) {
                kill_TCP_connection(conn);
                del_accepted(TCP_server, i);
                break;
            }

            if (handle_TCP_packet(TCP_server, i, packet, len) == -1) {
                kill_TCP_connection(conn);
                del_accepted(TCP_server, i);
                break;
            }
        }
    }
}
Ejemplo n.º 7
0
/* return 1 on success
 * return 0 on failure
 */
static int accept_connection(TCP_Server *TCP_server, sock_t sock)
{
    if (!sock_valid(sock))
        return 0;

    if (!set_socket_nonblock(sock)) {
        kill_sock(sock);
        return 0;
    }

    if (!set_socket_nosigpipe(sock)) {
        kill_sock(sock);
        return 0;
    }

    TCP_Secure_Connection *conn =
        &TCP_server->incomming_connection_queue[TCP_server->incomming_connection_queue_index % MAX_INCOMMING_CONNECTIONS];

    if (conn->status != TCP_STATUS_NO_STATUS)
        kill_TCP_connection(conn);

    conn->status = TCP_STATUS_CONNECTED;
    conn->sock = sock;
    conn->next_packet_length = 0;

    ++TCP_server->incomming_connection_queue_index;
    return 1;
}
Ejemplo n.º 8
0
/* Kill a TCP relay connection.
 *
 * return 0 on success.
 * return -1 on failure.
 */
static int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number)
{
    TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);

    if (!tcp_con) {
        return -1;
    }

    unsigned int i;

    for (i = 0; i < tcp_c->connections_length; ++i) {
        TCP_Connection_to *con_to = get_connection(tcp_c, i);

        if (con_to) {
            rm_tcp_connection_from_conn(con_to, tcp_connections_number);
        }
    }

    if (tcp_con->onion) {
        --tcp_c->onion_num_conns;
    }

    kill_TCP_connection(tcp_con->connection);

    return wipe_tcp_connection(tcp_c, tcp_connections_number);
}
Ejemplo n.º 9
0
void kill_tcp_connections(TCP_Connections *tcp_c)
{
    unsigned int i;

    for (i = 0; i < tcp_c->tcp_connections_length; ++i) {
        kill_TCP_connection(tcp_c->tcp_connections[i].connection);
    }

    free(tcp_c->tcp_connections);
    free(tcp_c->connections);
    free(tcp_c);
}
Ejemplo n.º 10
0
static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection *con, uint8_t *data, uint16_t length)
{
    int index = add_accepted(TCP_server, con);

    if (index == -1)
        return -1;

    TCP_Secure_Connection *conn = &TCP_server->accepted_connection_array[index];

    if (handle_TCP_packet(TCP_server, index, data, length) == -1) {
        kill_TCP_connection(conn);
        del_accepted(TCP_server, index);
    }

    return 0;
}
Ejemplo n.º 11
0
static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number)
{
    TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);

    if (!tcp_con) {
        return -1;
    }

    if (tcp_con->status == TCP_CONN_SLEEPING) {
        return -1;
    }

    IP_Port ip_port = tcp_con_ip_port(tcp_con->connection);
    uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE];
    memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE);
    kill_TCP_connection(tcp_con->connection);
    tcp_con->connection = new_TCP_connection(ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key,
                          &tcp_c->proxy_info);

    if (!tcp_con->connection) {
        kill_tcp_relay_connection(tcp_c, tcp_connections_number);
        return -1;
    }

    unsigned int i;

    for (i = 0; i < tcp_c->connections_length; ++i) {
        TCP_Connection_to *con_to = get_connection(tcp_c, i);

        if (con_to) {
            set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_NONE, 0);
        }
    }

    if (tcp_con->onion) {
        --tcp_c->onion_num_conns;
        tcp_con->onion = 0;
    }

    tcp_con->lock_count = 0;
    tcp_con->sleep_count = 0;
    tcp_con->connected_time = 0;
    tcp_con->status = TCP_CONN_VALID;
    tcp_con->unsleep = 0;

    return 0;
}
Ejemplo n.º 12
0
static int sleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number)
{
    TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);

    if (!tcp_con) {
        return -1;
    }

    if (tcp_con->status != TCP_CONN_CONNECTED) {
        return -1;
    }

    if (tcp_con->lock_count != tcp_con->sleep_count) {
        return -1;
    }

    tcp_con->ip_port = tcp_con_ip_port(tcp_con->connection);
    memcpy(tcp_con->relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE);

    kill_TCP_connection(tcp_con->connection);
    tcp_con->connection = nullptr;

    unsigned int i;

    for (i = 0; i < tcp_c->connections_length; ++i) {
        TCP_Connection_to *con_to = get_connection(tcp_c, i);

        if (con_to) {
            set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_NONE, 0);
        }
    }

    if (tcp_con->onion) {
        --tcp_c->onion_num_conns;
        tcp_con->onion = 0;
    }

    tcp_con->lock_count = 0;
    tcp_con->sleep_count = 0;
    tcp_con->connected_time = 0;
    tcp_con->status = TCP_CONN_SLEEPING;
    tcp_con->unsleep = 0;

    return 0;
}
Ejemplo n.º 13
0
static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection *con, const uint8_t *data,
                                  uint16_t length)
{
    int index = add_accepted(TCP_server, con);

    if (index == -1) {
        kill_TCP_connection(con);
        return -1;
    }

    sodium_memzero(con, sizeof(TCP_Secure_Connection));

    if (handle_TCP_packet(TCP_server, index, data, length) == -1) {
        kill_accepted(TCP_server, index);
        return -1;
    }

    return index;
}
Ejemplo n.º 14
0
static void do_TCP_epoll(TCP_Server *TCP_server)
{
#define MAX_EVENTS 16
    struct epoll_event events[MAX_EVENTS];
    int nfds;

    while ((nfds = epoll_wait(TCP_server->efd, events, MAX_EVENTS, 0)) > 0) {
        int n;

        for (n = 0; n < nfds; ++n) {
            sock_t sock = events[n].data.u64 & 0xFFFFFFFF;
            int status = (events[n].data.u64 >> 32) & 0xFFFF, index = (events[n].data.u64 >> 48);

            if ((events[n].events & EPOLLERR) || (events[n].events & EPOLLHUP)) {
                switch (status) {
                    case TCP_SOCKET_LISTENING: {
                        //should never happen
                        break;
                    }

                    case TCP_SOCKET_INCOMING: {
                        kill_TCP_connection(&TCP_server->incomming_connection_queue[index]);
                        break;
                    }

                    case TCP_SOCKET_UNCONFIRMED: {
                        kill_TCP_connection(&TCP_server->unconfirmed_connection_queue[index]);
                        break;
                    }

                    case TCP_SOCKET_CONFIRMED: {
                        kill_accepted(TCP_server, index);
                        break;
                    }
                }

                continue;
            }


            if (!(events[n].events & EPOLLIN)) {
                continue;
            }

            switch (status) {
                case TCP_SOCKET_LISTENING: {
                    //socket is from socks_listening, accept connection
                    struct sockaddr_storage addr;
                    unsigned int addrlen = sizeof(addr);
                    sock_t sock_new;

                    sock_new = accept(sock, (struct sockaddr *)&addr, &addrlen);

                    int index_new = TCP_server->incomming_connection_queue_index % MAX_INCOMMING_CONNECTIONS;

                    if (!accept_connection(TCP_server, sock_new)) {
                        break;
                    }

                    struct epoll_event ev = {
                        .events = EPOLLIN | EPOLLET,
                        .data.u64 = sock_new | ((uint64_t)TCP_SOCKET_INCOMING << 32) | ((uint64_t)index_new << 48)
                    };

                    if (epoll_ctl(TCP_server->efd, EPOLL_CTL_ADD, sock_new, &ev) == -1) {
                        kill_TCP_connection(&TCP_server->incomming_connection_queue[index_new]);
                        break;
                    }

                    break;
                }

                case TCP_SOCKET_INCOMING: {
                    int index_new;

                    if ((index_new = do_incoming(TCP_server, index)) != -1) {
                        events[n].events = EPOLLIN | EPOLLET;
                        events[n].data.u64 = sock | ((uint64_t)TCP_SOCKET_UNCONFIRMED << 32) | ((uint64_t)index_new << 48);

                        if (epoll_ctl(TCP_server->efd, EPOLL_CTL_MOD, sock, &events[n]) == -1) {
                            kill_TCP_connection(&TCP_server->unconfirmed_connection_queue[index_new]);
                            break;
                        }
                    }

                    break;
                }

                case TCP_SOCKET_UNCONFIRMED: {
                    int index_new;

                    if ((index_new = do_unconfirmed(TCP_server, index)) != -1) {
                        events[n].events = EPOLLIN | EPOLLET;
                        events[n].data.u64 = sock | ((uint64_t)TCP_SOCKET_CONFIRMED << 32) | ((uint64_t)index_new << 48);

                        if (epoll_ctl(TCP_server->efd, EPOLL_CTL_MOD, sock, &events[n]) == -1) {
                            //remove from confirmed connections
                            kill_accepted(TCP_server, index_new);
                            break;
                        }
                    }

                    break;
                }

                case TCP_SOCKET_CONFIRMED: {
                    do_confirmed_recv(TCP_server, index);
                    break;
                }
            }
        }
    }

#undef MAX_EVENTS
}
#endif

void do_TCP_server(TCP_Server *TCP_server)
{
    unix_time_update();

#ifdef TCP_SERVER_USE_EPOLL
    do_TCP_epoll(TCP_server);

#else
    do_TCP_accept_new(TCP_server);
    do_TCP_incomming(TCP_server);
    do_TCP_unconfirmed(TCP_server);
#endif

    do_TCP_confirmed(TCP_server);
}