예제 #1
0
/* return 1 on success.
 * return 0 if could not send packet.
 * return -1 on failure (connection must be killed).
 */
static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const uint8_t *data, uint16_t length,
        bool priority)
{
    if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE) {
        return -1;
    }

    bool sendpriority = 1;

    if (send_pending_data(con) == -1) {
        if (priority) {
            sendpriority = 0;
        } else {
            return 0;
        }
    }

    uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES];

    uint16_t c_length = htons(length + crypto_box_MACBYTES);
    memcpy(packet, &c_length, sizeof(uint16_t));
    int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));

    if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t))) {
        return -1;
    }

    if (priority) {
        len = sendpriority ? send(con->sock, (const char *)packet, sizeof(packet), MSG_NOSIGNAL) : 0;

        if (len <= 0) {
            len = 0;
        }

        increment_nonce(con->sent_nonce);

        if ((unsigned int)len == sizeof(packet)) {
            return 1;
        }

        return add_priority(con, packet, sizeof(packet), len);
    }

    len = send(con->sock, (const char *)packet, sizeof(packet), MSG_NOSIGNAL);

    if (len <= 0) {
        return 0;
    }

    increment_nonce(con->sent_nonce);

    if ((unsigned int)len == sizeof(packet)) {
        return 1;
    }

    memcpy(con->last_packet, packet, sizeof(packet));
    con->last_packet_length = sizeof(packet);
    con->last_packet_sent = len;
    return 1;
}
예제 #2
0
/* return 1 on success.
 * return 0 if could not send packet.
 * return -1 on failure (connection must be killed).
 */
static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const uint8_t *data, uint16_t length)
{
    if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE)
        return -1;

    if (send_pending_data(con) == -1)
        return 0;

    uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES];

    uint16_t c_length = htons(length + crypto_box_MACBYTES);
    memcpy(packet, &c_length, sizeof(uint16_t));
    int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));

    if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t)))
        return -1;

    increment_nonce(con->sent_nonce);

    len = send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL);

    if ((unsigned int)len == sizeof(packet))
        return 1;

    if (len <= 0)
        return 0;

    memcpy(con->last_packet, packet, length);
    con->last_packet_length = sizeof(packet);
    con->last_packet_sent = len;
    return 1;
}
예제 #3
0
void JitteredPacedFlow::send_pending_data() {
  if (received_bytes < size) {
    //std::cout << "Sending Pending Data" << std::endl;
    if (next_seq_no + mss > size) {
      next_seq_no = last_unacked_seq;
    }
    uint32_t seqn = next_seq_no;
    if (seqn + mss > size) {
      return;
    }
    next_seq_no = seqn + mss;
    if (received.count(seqn) == 0) {
      //std::cout << get_current_time() << " Enqueing " << seqn << "\n";
      uint32_t priority = get_priority(seqn);
      Packet *p = new Packet(get_current_time(), this, seqn, \
                     priority, mss + hdr_size, \
                     src, dst);

      double td = src->queue->get_transmission_delay(p->size);
      double wait = td / rate;
      double jitter = (wait - td) * rand() / RAND_MAX;
      add_to_event_queue(new PacketQueuingEvent(get_current_time() + jitter,
        p, src->queue));
      add_to_event_queue(new FlowProcessingEvent(get_current_time() + wait,
        this));
    } else {
      send_pending_data();
    }
  }
}
예제 #4
0
static void do_TCP_confirmed(TCP_Server *TCP_server)
{
#ifdef TCP_SERVER_USE_EPOLL

    if (TCP_server->last_run_pinged == unix_time()) {
        return;
    }

    TCP_server->last_run_pinged = unix_time();
#endif
    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), 1);

            if (ret == 1) {
                conn->last_pinged = unix_time();
                conn->ping_id = ping_id;
            } else {
                if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY + TCP_PING_TIMEOUT)) {
                    kill_accepted(TCP_server, i);
                    continue;
                }
            }
        }

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

        send_pending_data(conn);

#ifndef TCP_SERVER_USE_EPOLL

        do_confirmed_recv(TCP_server, i);

#endif
    }
}
예제 #5
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;
            }
        }
    }
}
예제 #6
0
static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata)
{
    send_pending_data(conn);
    send_ping_response(conn);
    send_ping_request(conn);

    uint8_t packet[MAX_PACKET_SIZE];
    int len;

    if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY)) {
        uint64_t ping_id = random_64b();

        if (!ping_id) {
            ++ping_id;
        }

        conn->ping_request_id = conn->ping_id = ping_id;
        send_ping_request(conn);
        conn->last_pinged = unix_time();
    }

    if (conn->ping_id && is_timeout(conn->last_pinged, TCP_PING_TIMEOUT)) {
        conn->status = TCP_CLIENT_DISCONNECTED;
        return 0;
    }

    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) {
            conn->status = TCP_CLIENT_DISCONNECTED;
            break;
        }

        if (handle_TCP_packet(conn, packet, len, userdata) == -1) {
            conn->status = TCP_CLIENT_DISCONNECTED;
            break;
        }
    }

    return 0;
}
예제 #7
0
/* Run the TCP connection
 */
void do_TCP_connection(TCP_Client_Connection *TCP_connection, void *userdata)
{
    unix_time_update();

    if (TCP_connection->status == TCP_CLIENT_DISCONNECTED) {
        return;
    }

    if (TCP_connection->status == TCP_CLIENT_PROXY_HTTP_CONNECTING) {
        if (send_pending_data(TCP_connection) == 0) {
            int ret = proxy_http_read_connection_response(TCP_connection);

            if (ret == -1) {
                TCP_connection->kill_at = 0;
                TCP_connection->status = TCP_CLIENT_DISCONNECTED;
            }

            if (ret == 1) {
                generate_handshake(TCP_connection);
                TCP_connection->status = TCP_CLIENT_CONNECTING;
            }
        }
    }

    if (TCP_connection->status == TCP_CLIENT_PROXY_SOCKS5_CONNECTING) {
        if (send_pending_data(TCP_connection) == 0) {
            int ret = socks5_read_handshake_response(TCP_connection);

            if (ret == -1) {
                TCP_connection->kill_at = 0;
                TCP_connection->status = TCP_CLIENT_DISCONNECTED;
            }

            if (ret == 1) {
                proxy_socks5_generate_connection_request(TCP_connection);
                TCP_connection->status = TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED;
            }
        }
    }

    if (TCP_connection->status == TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED) {
        if (send_pending_data(TCP_connection) == 0) {
            int ret = proxy_socks5_read_connection_response(TCP_connection);

            if (ret == -1) {
                TCP_connection->kill_at = 0;
                TCP_connection->status = TCP_CLIENT_DISCONNECTED;
            }

            if (ret == 1) {
                generate_handshake(TCP_connection);
                TCP_connection->status = TCP_CLIENT_CONNECTING;
            }
        }
    }

    if (TCP_connection->status == TCP_CLIENT_CONNECTING) {
        if (send_pending_data(TCP_connection) == 0) {
            TCP_connection->status = TCP_CLIENT_UNCONFIRMED;
        }
    }

    if (TCP_connection->status == TCP_CLIENT_UNCONFIRMED) {
        uint8_t data[TCP_SERVER_HANDSHAKE_SIZE];
        int len = read_TCP_packet(TCP_connection->sock, data, sizeof(data));

        if (sizeof(data) == len) {
            if (handle_handshake(TCP_connection, data) == 0) {
                TCP_connection->kill_at = ~0;
                TCP_connection->status = TCP_CLIENT_CONFIRMED;
            } else {
                TCP_connection->kill_at = 0;
                TCP_connection->status = TCP_CLIENT_DISCONNECTED;
            }
        }
    }

    if (TCP_connection->status == TCP_CLIENT_CONFIRMED) {
        do_confirmed_TCP(TCP_connection, userdata);
    }

    if (TCP_connection->kill_at <= unix_time()) {
        TCP_connection->status = TCP_CLIENT_DISCONNECTED;
    }
}