1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-12-22 23:03:25 +01:00

Add tox network profiling

Profiling can be enabled with the -s run option
This commit is contained in:
jfreegman 2022-01-30 13:18:14 -05:00
parent cec96e1ea3
commit b91f5a8758
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
5 changed files with 333 additions and 18 deletions

View File

@ -14,7 +14,7 @@ LDFLAGS += ${USER_LDFLAGS}
OBJ = autocomplete.o avatars.o bootstrap.o chat.o chat_commands.o configdir.o curl_util.o execute.o
OBJ += file_transfers.o friendlist.o global_commands.o conference_commands.o conference.o help.o input.o line_info.o
OBJ += log.o message_queue.o misc_tools.o name_lookup.o notify.o prompt.o qr_code.o settings.o
OBJ += log.o message_queue.o misc_tools.o name_lookup.o netprof.o notify.o prompt.o qr_code.o settings.o
OBJ += term_mplex.o toxic.o toxic_strings.o windows.o
# Check if debug build is enabled

270
src/netprof.c Normal file
View File

@ -0,0 +1,270 @@
/* netprof.c
*
*
* Copyright (C) 2022 Toxic All Rights Reserved.
*
* This file is part of Toxic.
*
* Toxic is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Toxic is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Toxic. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdint.h>
#include <stdio.h>
#include "netprof.h"
#include "../../toxcore/toxcore/tox_private.h" // set this to your local toxcore source directory
static void log_tcp_packet_id(FILE *fp, unsigned int id, uint64_t total, uint64_t TCP_id_sent, uint64_t TCP_id_recv)
{
switch (id) {
case TOX_NETPROF_PACKET_ID_ZERO:
case TOX_NETPROF_PACKET_ID_ONE:
case TOX_NETPROF_PACKET_ID_TWO:
case TOX_NETPROF_PACKET_ID_TCP_DISCONNECT:
case TOX_NETPROF_PACKET_ID_FOUR:
case TOX_NETPROF_PACKET_ID_TCP_PONG:
case TOX_NETPROF_PACKET_ID_TCP_OOB_SEND:
case TOX_NETPROF_PACKET_ID_TCP_OOB_RECV:
case TOX_NETPROF_PACKET_ID_TCP_ONION_REQUEST:
case TOX_NETPROF_PACKET_ID_TCP_ONION_RESPONSE:
case TOX_NETPROF_PACKET_ID_TCP_DATA: {
if (TCP_id_recv || TCP_id_sent) {
fprintf(fp, "0x%02x (total): %lu (%.2f%%)\n", id, TCP_id_sent + TCP_id_recv,
((float)TCP_id_recv + TCP_id_sent) / total * 100.0);
}
if (TCP_id_sent) {
fprintf(fp, "0x%02x (sent): %lu (%.2f%%)\n", id, TCP_id_sent, (float)TCP_id_sent / total * 100.0);
}
if (TCP_id_recv) {
fprintf(fp, "0x%02x (recv): %lu (%.2f%%)\n", id, TCP_id_recv, (float)TCP_id_recv / total * 100.0);
}
break;
}
default:
return;
}
}
static void log_udp_packet_id(FILE *fp, unsigned int id, uint64_t total, uint64_t UDP_id_sent, uint64_t UDP_id_recv)
{
switch (id) {
case TOX_NETPROF_PACKET_ID_ZERO:
case TOX_NETPROF_PACKET_ID_ONE:
case TOX_NETPROF_PACKET_ID_TWO:
case TOX_NETPROF_PACKET_ID_FOUR:
case TOX_NETPROF_PACKET_ID_COOKIE_REQUEST:
case TOX_NETPROF_PACKET_ID_COOKIE_RESPONSE:
case TOX_NETPROF_PACKET_ID_CRYPTO_HS:
case TOX_NETPROF_PACKET_ID_CRYPTO_DATA:
case TOX_NETPROF_PACKET_ID_CRYPTO:
case TOX_NETPROF_PACKET_ID_LAN_DISCOVERY:
case TOX_NETPROF_PACKET_ID_ONION_SEND_INITIAL:
case TOX_NETPROF_PACKET_ID_ONION_SEND_1:
case TOX_NETPROF_PACKET_ID_ONION_SEND_2:
case TOX_NETPROF_PACKET_ID_ANNOUNCE_REQUEST:
case TOX_NETPROF_PACKET_ID_ANNOUNCE_RESPONSE:
case TOX_NETPROF_PACKET_ID_ONION_DATA_REQUEST:
case TOX_NETPROF_PACKET_ID_ONION_DATA_RESPONSE:
case TOX_NETPROF_PACKET_ID_ONION_RECV_3:
case TOX_NETPROF_PACKET_ID_ONION_RECV_2:
case TOX_NETPROF_PACKET_ID_ONION_RECV_1:
case TOX_NETPROF_PACKET_ID_BOOTSTRAP_INFO: {
if (UDP_id_recv || UDP_id_sent) {
fprintf(fp, "0x%02x (total): %lu (%.2f%%)\n", id, UDP_id_sent + UDP_id_recv,
((float)UDP_id_recv + UDP_id_sent) / total * 100.0);
}
if (UDP_id_sent) {
fprintf(fp, "0x%02x (sent): %lu (%.2f%%)\n", id, UDP_id_sent, (float)UDP_id_sent / total * 100.0);
}
if (UDP_id_recv) {
fprintf(fp, "0x%02x (recv): %lu (%.2f%%)\n", id, UDP_id_recv, (float)UDP_id_recv / total * 100.0);
}
break;
}
default:
return;
}
}
static void dump_packet_id_counts(const Tox *m, FILE *fp, uint64_t total_count, Tox_Netprof_Packet_Type packet_type)
{
if (packet_type == TOX_NETPROF_PACKET_TYPE_TCP) {
fprintf(fp, "--- TCP packet counts by packet ID --- \n");
} else {
fprintf(fp, "--- UDP packet counts by packet ID --- \n");
}
for (unsigned long i = TOX_NETPROF_PACKET_ID_ZERO; i <= TOX_NETPROF_PACKET_ID_BOOTSTRAP_INFO; ++i) {
const uint64_t id_count_sent = tox_netprof_get_packet_id_count(m, packet_type, i, TOX_NETPROF_DIRECTION_SENT);
const uint64_t id_count_recv = tox_netprof_get_packet_id_count(m, packet_type, i, TOX_NETPROF_DIRECTION_RECV);
if (packet_type == TOX_NETPROF_PACKET_TYPE_TCP) {
log_tcp_packet_id(fp, i, total_count, id_count_sent, id_count_recv);
} else {
log_udp_packet_id(fp, i, total_count, id_count_sent, id_count_recv);
}
}
fprintf(fp, "\n\n");
}
static void dump_packet_id_bytes(const Tox *m, FILE *fp, uint64_t total_bytes, Tox_Netprof_Packet_Type packet_type)
{
if (packet_type == TOX_NETPROF_PACKET_TYPE_TCP) {
fprintf(fp, "--- TCP byte counts by packet ID --- \n");
} else {
fprintf(fp, "--- UDP byte counts by packet ID --- \n");
}
for (unsigned long i = TOX_NETPROF_PACKET_ID_ZERO; i <= TOX_NETPROF_PACKET_ID_BOOTSTRAP_INFO; ++i) {
const uint64_t id_bytes_sent = tox_netprof_get_packet_id_bytes(m, packet_type, i, TOX_NETPROF_DIRECTION_SENT);
const uint64_t id_bytes_recv = tox_netprof_get_packet_id_bytes(m, packet_type, i, TOX_NETPROF_DIRECTION_RECV);
if (packet_type == TOX_NETPROF_PACKET_TYPE_TCP) {
log_tcp_packet_id(fp, i, total_bytes, id_bytes_sent, id_bytes_recv);
} else {
log_udp_packet_id(fp, i, total_bytes, id_bytes_sent, id_bytes_recv);
}
}
fprintf(fp, "\n\n");
}
static void dump_packet_count_totals(const Tox *m, FILE *fp, uint64_t total_packet_count,
uint64_t UDP_count_sent, uint64_t UDP_count_recv,
uint64_t TCP_count_sent, uint64_t TCP_count_recv)
{
const uint64_t total_UDP_count = UDP_count_sent + UDP_count_recv;
const uint64_t total_TCP_count = TCP_count_sent + TCP_count_recv;
const uint64_t total_packet_count_sent = UDP_count_sent + TCP_count_sent;
const uint64_t total_packet_count_recv = UDP_count_recv + TCP_count_recv;
fprintf(fp, "--- Total packet counts --- \n");
fprintf(fp, "Total packets: %lu\n", total_packet_count);
fprintf(fp, "Total packets sent: %lu (%.2f%%)\n", total_packet_count_sent,
(float)total_packet_count_sent / total_packet_count * 100.0);
fprintf(fp, "Total packets recv: %lu (%.2f%%)\n", total_packet_count_recv,
(float)total_packet_count_recv / total_packet_count * 100.0);
fprintf(fp, "total UDP packets: %lu (%.2f%%)\n", total_UDP_count,
(float)total_UDP_count / total_packet_count * 100.0);
fprintf(fp, "UDP packets sent: %lu (%.2f%%)\n", UDP_count_sent,
(float)UDP_count_sent / total_packet_count * 100.0);
fprintf(fp, "UDP packets recv: %lu (%.2f%%)\n", UDP_count_recv,
(float)UDP_count_recv / total_packet_count * 100.0);
fprintf(fp, "Total TCP packets: %lu (%.2f%%)\n", total_TCP_count,
(float)total_TCP_count / total_packet_count * 100.0);
fprintf(fp, "TCP packets sent: %lu (%.2f%%)\n", TCP_count_sent,
(float)TCP_count_sent / total_packet_count * 100.0);
fprintf(fp, "TCP packets recv: %lu (%.2f%%)\n", TCP_count_recv,
(float)TCP_count_recv / total_packet_count * 100.0);
fprintf(fp, "\n\n");
}
void dump_packet_bytes_totals(const Tox *m, FILE *fp, const uint64_t total_bytes,
const uint64_t UDP_bytes_sent, const uint64_t UDP_bytes_recv,
const uint64_t TCP_bytes_sent, const uint64_t TCP_bytes_recv)
{
const uint64_t total_UDP_bytes = UDP_bytes_sent + UDP_bytes_recv;
const uint64_t total_TCP_bytes = TCP_bytes_sent + TCP_bytes_recv;
const uint64_t total_bytes_sent = UDP_bytes_sent + TCP_bytes_sent;
const uint64_t total_bytes_recv = UDP_bytes_recv + TCP_bytes_recv;
fprintf(fp, "--- Total byte counts --- \n");
fprintf(fp, "Total bytes: %lu\n", total_bytes);
fprintf(fp, "Total bytes sent: %lu (%.2f%%)\n", total_bytes_sent,
(float)total_bytes_sent / total_bytes * 100.0);
fprintf(fp, "Total bytes recv: %lu (%.2f%%)\n", total_bytes_recv,
(float)total_bytes_recv / total_bytes * 100.0);
fprintf(fp, "Total UDP bytes: %lu (%.2f%%)\n", total_UDP_bytes,
(float)total_UDP_bytes / total_bytes * 100.0);
fprintf(fp, "UDP bytes sent: %lu (%.2f%%)\n", UDP_bytes_sent,
(float)UDP_bytes_sent / total_bytes * 100.0);
fprintf(fp, "UDP bytes recv: %lu (%.2f%%)\n", UDP_bytes_recv,
(float)UDP_bytes_recv / total_bytes * 100.0);
fprintf(fp, "Total TCP bytes: %lu (%.2f%%)\n", total_TCP_bytes,
(float)total_TCP_bytes / total_bytes * 100.0);
fprintf(fp, "TCP bytes sent: %lu (%.2f%%)\n", TCP_bytes_sent,
(float)TCP_bytes_sent / total_bytes * 100.0);
fprintf(fp, "TCP bytes recv: %lu (%.2f%%)\n", TCP_bytes_recv,
(float)TCP_bytes_recv / total_bytes * 100.0);
fprintf(fp, "\n\n");
}
void netprof_log_dump(const Tox *m, FILE *fp)
{
if (fp == NULL) {
fprintf(stderr, "Failed to dump network statistics: null file pointer\n");
return;
}
const uint64_t UDP_count_sent = tox_netprof_get_packet_total_count(m, TOX_NETPROF_PACKET_TYPE_UDP,
TOX_NETPROF_DIRECTION_SENT);
const uint64_t UDP_count_recv = tox_netprof_get_packet_total_count(m, TOX_NETPROF_PACKET_TYPE_UDP,
TOX_NETPROF_DIRECTION_RECV);
const uint64_t TCP_count_sent = tox_netprof_get_packet_total_count(m, TOX_NETPROF_PACKET_TYPE_TCP,
TOX_NETPROF_DIRECTION_SENT);
const uint64_t TCP_count_recv = tox_netprof_get_packet_total_count(m, TOX_NETPROF_PACKET_TYPE_TCP,
TOX_NETPROF_DIRECTION_RECV);
const uint64_t UDP_bytes_sent = tox_netprof_get_packet_total_bytes(m, TOX_NETPROF_PACKET_TYPE_UDP,
TOX_NETPROF_DIRECTION_SENT);
const uint64_t UDP_bytes_recv = tox_netprof_get_packet_total_bytes(m, TOX_NETPROF_PACKET_TYPE_UDP,
TOX_NETPROF_DIRECTION_RECV);
const uint64_t TCP_bytes_sent = tox_netprof_get_packet_total_bytes(m, TOX_NETPROF_PACKET_TYPE_TCP,
TOX_NETPROF_DIRECTION_SENT);
const uint64_t TCP_bytes_recv = tox_netprof_get_packet_total_bytes(m, TOX_NETPROF_PACKET_TYPE_TCP,
TOX_NETPROF_DIRECTION_RECV);
const uint64_t total_count = UDP_count_sent + UDP_count_recv + TCP_count_sent + TCP_count_recv;
const uint64_t total_bytes = UDP_bytes_sent + UDP_bytes_recv + TCP_bytes_sent + TCP_bytes_recv;
dump_packet_count_totals(m, fp, total_count, UDP_count_sent, UDP_count_recv, TCP_count_sent, TCP_count_recv);
dump_packet_bytes_totals(m, fp, total_bytes, UDP_bytes_sent, UDP_bytes_recv, TCP_bytes_sent, TCP_bytes_recv);
dump_packet_id_counts(m, fp, total_count, TOX_NETPROF_PACKET_TYPE_TCP);
dump_packet_id_counts(m, fp, total_count, TOX_NETPROF_PACKET_TYPE_UDP);
dump_packet_id_bytes(m, fp, total_bytes, TOX_NETPROF_PACKET_TYPE_TCP);
dump_packet_id_bytes(m, fp, total_bytes, TOX_NETPROF_PACKET_TYPE_UDP);
fflush(fp);
}

30
src/netprof.h Normal file
View File

@ -0,0 +1,30 @@
/* netprof.h
*
*
* Copyright (C) 2022 Toxic All Rights Reserved.
*
* This file is part of Toxic.
*
* Toxic is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Toxic is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Toxic. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TOXIC_NETPROF
#define TOXIC_NETPROF
#include <tox/tox.h>
void netprof_log_dump(const Tox *m, FILE *fp);
#endif // TOXIC_NETPROF

View File

@ -58,6 +58,7 @@
#include "message_queue.h"
#include "misc_tools.h"
#include "name_lookup.h"
#include "netprof.h"
#include "notify.h"
#include "prompt.h"
#include "settings.h"
@ -143,6 +144,22 @@ static void catch_SIGSEGV(int sig)
exit(EXIT_FAILURE);
}
void cb_toxcore_logger(Tox *m, TOX_LOG_LEVEL level, const char *file, uint32_t line, const char *func,
const char *message, void *user_data)
{
UNUSED_VAR(user_data);
UNUSED_VAR(file);
UNUSED_VAR(m);
if (user_data) {
FILE *fp = (FILE *)user_data;
fprintf(fp, "[%d] %u:%s() - %s\n", level, line, func, message);
fflush(fp);
} else {
fprintf(stderr, "[%d] %u:%s() - %s\n", level, line, func, message);
}
}
static void flag_window_resize(int sig)
{
UNUSED_VAR(sig);
@ -177,6 +194,10 @@ void free_global_data(void)
void exit_toxic_success(Tox *m)
{
if (arg_opts.netprof_log_dump) {
netprof_log_dump(m, arg_opts.netprof_fp);
}
store_data(m, DATA_FILE);
user_password = (struct user_password) {
@ -207,6 +228,11 @@ void exit_toxic_success(Tox *m)
arg_opts.log_fp = NULL;
}
if (arg_opts.netprof_fp != NULL) {
fclose(arg_opts.netprof_fp);
arg_opts.netprof_fp = NULL;
}
endwin();
curl_global_cleanup();
@ -229,22 +255,6 @@ void exit_toxic_err(const char *errmsg, int errcode)
exit(EXIT_FAILURE);
}
void cb_toxcore_logger(Tox *m, Tox_Log_Level level, const char *file, uint32_t line, const char *func,
const char *message, void *user_data)
{
UNUSED_VAR(user_data);
UNUSED_VAR(file);
UNUSED_VAR(m);
if (user_data) {
FILE *fp = (FILE *)user_data;
fprintf(fp, "[%d] %u:%s() - %s\n", level, line, func, message);
fflush(fp);
} else {
fprintf(stderr, "[%d] %u:%s() - %s\n", level, line, func, message);
}
}
/* Sets ncurses refresh rate. Lower values make it refresh more often. */
void set_window_refresh_rate(size_t refresh_rate)
{
@ -1199,6 +1209,7 @@ static void print_usage(void)
fprintf(stderr, " -p, --SOCKS5-proxy Use SOCKS5 proxy: Requires [IP] [port]\n");
fprintf(stderr, " -P, --HTTP-proxy Use HTTP proxy: Requires [IP] [port]\n");
fprintf(stderr, " -r, --namelist Use specified name lookup server list\n");
fprintf(stderr, " -s, --netstats Dump network statistic to log on exit: Requires [path]\n");
fprintf(stderr, " -t, --force-tcp Force toxic to use a TCP connection (use with proxies)\n");
fprintf(stderr, " -T, --tcp-server Act as a TCP relay server: Requires [port]\n");
fprintf(stderr, " -u, --unencrypt-data Unencrypt an encrypted data file\n");
@ -1238,6 +1249,7 @@ static void parse_args(int argc, char *argv[])
{"help", no_argument, 0, 'h'},
{"noconnect", no_argument, 0, 'o'},
{"namelist", required_argument, 0, 'r'},
{"netstats", required_argument, 0, 's'},
{"force-tcp", no_argument, 0, 't'},
{"tcp-server", required_argument, 0, 'T'},
{"SOCKS5-proxy", required_argument, 0, 'p'},
@ -1247,7 +1259,7 @@ static void parse_args(int argc, char *argv[])
{NULL, no_argument, NULL, 0},
};
const char *opts_str = "4bdehLotuxvc:f:l:n:r:p:P:T:";
const char *opts_str = "4bdehLotuxvc:f:l:n:r:s:p:P:T:";
int opt = 0;
int indexptr = 0;

View File

@ -142,6 +142,9 @@ struct arg_opts {
bool logging;
FILE *log_fp;
bool netprof_log_dump;
FILE *netprof_fp;
char proxy_address[256];
uint8_t proxy_type;
uint16_t proxy_port;