diff --git a/daemon/call.c b/daemon/call.c index d0deb210c..a2adfe2fd 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -531,6 +531,7 @@ static void count_stream_stats_kernel(struct packet_stream *ps) { else \ diff_ ## x ## _ ## io = (ke)->x - ks_val; \ atomic64_add(&ps->stats_ ## io.x, diff_ ## x ## _ ## io); \ + atomic64_add(&ps->selected_sfd->local_intf->stats_ ## io.x, diff_ ## x ## _ ## io); \ RTPE_STATS_ADD(x ## _kernel, diff_ ## x ## _ ## io); \ } while (0) diff --git a/daemon/codec.c b/daemon/codec.c index 039290541..46117b81c 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -1619,6 +1619,8 @@ static int __handler_func_sequencer(struct media_packet *mp, struct transcode_pa atomic64_inc(&ssrc_in->packets); atomic64_add(&ssrc_in->octets, mp->payload.len); + atomic64_inc(&mp->sfd->local_intf->stats_in.packets); + atomic64_add(&mp->sfd->local_intf->stats_in.bytes, mp->payload.len); if (packet->bypass_seq) { // bypass sequencer @@ -1660,6 +1662,7 @@ static int __handler_func_sequencer(struct media_packet *mp, struct transcode_pa if (func_ret != 1) __transcode_packet_free(packet); ssrc_in_p->duplicates++; + atomic64_inc(&mp->sfd->local_intf->stats.duplicates); RTPE_STATS_INC(rtp_duplicates); goto out; } diff --git a/daemon/media_player.c b/daemon/media_player.c index 8260742bd..ece5e3121 100644 --- a/daemon/media_player.c +++ b/daemon/media_player.c @@ -252,6 +252,8 @@ static bool __send_timer_send_1(struct rtp_header *rh, struct packet_stream *sin atomic64_inc(&sink->stats_out.packets); atomic64_add(&sink->stats_out.bytes, cp->s.len); + atomic64_inc(&sink_fd->local_intf->stats_out.packets); + atomic64_add(&sink_fd->local_intf->stats_out.bytes, cp->s.len); log_info_pop(); diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 1132e2439..e9e23b548 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -717,7 +717,7 @@ static void __interface_append(struct intf_config *ifa, sockfamily_t *fam, bool g_hash_table_insert(__intf_spec_addr_type_hash, &spec->local_address, spec); } - ifc = uid_slice_alloc(ifc, &lif->list); + ifc = uid_slice_alloc0(ifc, &lif->list); ice_foundation(&ifc->ice_foundation); ifc->advertised_address = ifa->advertised_address; ifc->spec = spec; @@ -1523,6 +1523,8 @@ static void __stream_update_stats(struct packet_stream *ps, int have_in_lock) { parent->jitter = stats_info.ssrc_stats[u].jitter; RTPE_STATS_ADD(packets_lost, stats_info.ssrc_stats[u].total_lost); + atomic64_add(&ps->selected_sfd->local_intf->stats.packets_lost, + stats_info.ssrc_stats[u].total_lost); uint32_t ssrc_map_out = ssrc_ctx->ssrc_map_out; @@ -1939,6 +1941,7 @@ static void media_packet_rtp_in(struct packet_handler_ctx *phc) phc->payload_type, FMT_M(endpoint_print_buf(&phc->mp.fsin))); atomic64_inc(&phc->mp.stream->stats_in.errors); + atomic64_inc(&phc->mp.sfd->local_intf->stats_in.errors); RTPE_STATS_INC(errors_user); } else { @@ -2128,6 +2131,7 @@ static int media_packet_address_check(struct packet_handler_ctx *phc) FMT_M(sockaddr_print_buf(&phc->mp.stream->endpoint.address), phc->mp.stream->endpoint.port)); atomic64_inc(&phc->mp.stream->stats_in.errors); + atomic64_inc(&phc->mp.sfd->local_intf->stats_in.errors); ret = -1; } } @@ -2488,7 +2492,6 @@ static int stream_packet(struct packet_handler_ctx *phc) { phc->mp.raw = phc->s; - // XXX separate stats for received/sent if (atomic64_inc(&phc->mp.stream->stats_in.packets) == 0) { if (phc->mp.stream->component == 1) { if (phc->mp.media->index == 1) @@ -2497,6 +2500,8 @@ static int stream_packet(struct packet_handler_ctx *phc) { } } atomic64_add(&phc->mp.stream->stats_in.bytes, phc->s.len); + atomic64_inc(&phc->mp.sfd->local_intf->stats_in.packets); + atomic64_add(&phc->mp.sfd->local_intf->stats_in.bytes, phc->s.len); atomic64_set(&phc->mp.stream->last_packet, rtpe_now.tv_sec); RTPE_STATS_INC(packets_user); RTPE_STATS_ADD(bytes_user, phc->s.len); @@ -2660,6 +2665,7 @@ next_mirror: err_next: ilog(LOG_DEBUG | LOG_FLAG_LIMIT ,"Error when sending message. Error: %s", strerror(errno)); atomic64_inc(&sink->stats_in.errors); + atomic64_inc(&sink->selected_sfd->local_intf->stats_out.errors); RTPE_STATS_INC(errors_user); goto next; @@ -2702,6 +2708,7 @@ out: if (handler_ret < 0) { atomic64_inc(&phc->mp.stream->stats_in.errors); + atomic64_inc(&phc->mp.sfd->local_intf->stats_in.errors); RTPE_STATS_INC(errors_user); } diff --git a/include/interface_counter_stats_fields.inc b/include/interface_counter_stats_fields.inc new file mode 100644 index 000000000..40e19415f --- /dev/null +++ b/include/interface_counter_stats_fields.inc @@ -0,0 +1,2 @@ +F(packets_lost) +F(duplicates) diff --git a/include/interface_counter_stats_fields_dir.inc b/include/interface_counter_stats_fields_dir.inc new file mode 100644 index 000000000..02e3b06b6 --- /dev/null +++ b/include/interface_counter_stats_fields_dir.inc @@ -0,0 +1,3 @@ +F(packets) +F(bytes) +F(errors) diff --git a/include/media_socket.h b/include/media_socket.h index 815466527..28dd73454 100644 --- a/include/media_socket.h +++ b/include/media_socket.h @@ -105,12 +105,26 @@ struct intf_spec { struct intf_address local_address; struct port_pool port_pool; }; +struct interface_counter_stats_dir { +#define F(n) atomic64 n; +#include "interface_counter_stats_fields_dir.inc" +#undef F +}; +struct interface_counter_stats { +#define F(n) atomic64 n; +#include "interface_counter_stats_fields.inc" +#undef F +}; struct local_intf { struct intf_spec *spec; struct intf_address advertised_address; unsigned int unique_id; /* starting with 0 - serves as preference */ const struct logical_intf *logical; str ice_foundation; + + struct interface_counter_stats_dir stats_in, + stats_out; + struct interface_counter_stats stats; }; struct intf_list { struct local_intf *local_intf; diff --git a/t/test-transcode.c b/t/test-transcode.c index 9ccf8193d..a1e316f02 100644 --- a/t/test-transcode.c +++ b/t/test-transcode.c @@ -240,11 +240,16 @@ static void __packet_seq_ts(const char *file, int line, struct call_media *media str pl_exp = pload_exp; // from media_packet_rtp() + struct local_intf lif = { }; + struct stream_fd sfd = { + .local_intf = &lif, + }; struct media_packet mp = { .call = &call, .media = media, .media_out = other_media, .ssrc_in = get_ssrc_ctx(ssrc, media->monologue->ssrc_hash, SSRC_DIR_INPUT, NULL), + .sfd = &sfd, }; // from __stream_ssrc() if (!MEDIA_ISSET(media, TRANSCODE))