fix(ristsender): enable --rtp-sequence and --rtp-timestamp extraction
The RTP seq/timestamp extraction in input_udp_recv was disabled since
be32351 (2020) with a "TODO: Figure out why this does not work" comment.
The root cause was a buffer offset bug: recvfrom writes the UDP payload
at recv_buf + ipheader_bytes, but the extraction code read recv_buf[2..7]
— the reserved IP-header prefix area — returning garbage.
This commit is contained in:
@@ -41,6 +41,11 @@ Bug Fixes:
|
||||
refused to start the SRP/AES code paths in those environments
|
||||
rather than silently downgrade. Fixes #210.
|
||||
|
||||
Tools:
|
||||
- ristsender now preserves incoming RTP sequence numbers and
|
||||
timestamps when the --rtp-sequence and --rtp-timestamp options
|
||||
are used. Previously these options had no effect.
|
||||
|
||||
Hardening / follow-ups to 0.2.15:
|
||||
|
||||
- EAP-SRP authentication retry exhaustion did not drop the failed
|
||||
|
||||
@@ -64,6 +64,9 @@ test('Main profile receive client mode, sender server mode packet loss 25%', tes
|
||||
test('Main profile encryption receive server mode, sender client mode', test_send_receive, args: ['1', 'rist://@127.0.0.1:6001?secret=12345678&aes-type=128', 'rist://127.0.0.1:6001?secret=12345678&aes-type=128', '0'],suite: ['main', 'unicast', 'server', 'encryption'])
|
||||
test('Main profile encryption receive client mode, sender server mode ', test_send_receive, args: ['1', 'rist://127.0.0.1:6002?secret=12345678&aes-type=128', 'rist://@127.0.0.1:6002?secret=12345678&aes-type=128', '0'],suite: ['main', 'unicast', 'client', 'encryption'])
|
||||
test('Main profile encryption receive client mode, sender server mode AES256 ', test_send_receive, args: ['1', 'rist://127.0.0.1:6007?secret=12345678&aes-type=256', 'rist://@127.0.0.1:6007?secret=12345678&aes-type=256', '0'],suite: ['main', 'unicast', 'client', 'encryption'])
|
||||
#Caller-controlled seq (RIST_DATA_FLAGS_USE_SEQ) passthrough
|
||||
test('Main profile USE_SEQ passthrough', test_send_receive, args: ['1', 'rist://@127.0.0.1:6020?rtt-max=10&rtt-min=1', 'rist://127.0.0.1:6020?rtt-max=10&rtt-min=1', '0', '0', '1'], suite: ['main', 'unicast', 'use_seq'])
|
||||
test('Main profile USE_SEQ passthrough 10% loss', test_send_receive, args: ['1', 'rist://@127.0.0.1:6021?rtt-max=10&rtt-min=1', 'rist://127.0.0.1:6021?rtt-max=10&rtt-min=1', '10', '0', '1'], suite: ['main', 'unicast', 'use_seq'])
|
||||
#Encryption tests where 1 side has enabled encryption these should fail
|
||||
test('Main profile encryption receive server mode unencrypted, sender client mode', test_send_receive, args: ['1', 'rist://@127.0.0.1:6003', 'rist://127.0.0.1:6003?secret=12345678&aes-type=128', '0'], should_fail: true)
|
||||
test('Main profile encryption receive server mode, sender client mode unencrypted', test_send_receive, args: ['1', 'rist://@127.0.0.1:6004?secret=12345678&aes-type=128', 'rist://127.0.0.1:6004', '0'], should_fail: true)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "librist/librist.h"
|
||||
#include "rist-private.h"
|
||||
#include <stdatomic.h>
|
||||
#include <inttypes.h>
|
||||
#include "mpegts.h"
|
||||
#include "endian-shim.h"
|
||||
|
||||
@@ -17,6 +18,8 @@
|
||||
|
||||
atomic_ulong failed;
|
||||
atomic_ulong stop;
|
||||
int use_seq = 0;
|
||||
#define USE_SEQ_START 1000
|
||||
|
||||
struct rist_logging_settings *logging_settings_sender = NULL;
|
||||
struct rist_logging_settings *logging_settings_receiver = NULL;
|
||||
@@ -143,10 +146,15 @@ static PTHREAD_START_FUNC(send_data, arg) {
|
||||
else {
|
||||
hdr->flags1 = htobe16(0x1111);
|
||||
}
|
||||
sprintf(&buffer[offset+sizeof(*hdr)+1], "DEADBEAF TEST PACKET #%i-%i", send_counter, ts);
|
||||
int pkt_id = use_seq ? (send_counter + USE_SEQ_START) : send_counter;
|
||||
sprintf(&buffer[offset+sizeof(*hdr)+1], "DEADBEAF TEST PACKET #%i-%i", pkt_id, ts);
|
||||
}
|
||||
data.payload = &buffer;
|
||||
data.payload_len = 188 * random_num;
|
||||
if (use_seq) {
|
||||
data.flags = RIST_DATA_FLAGS_USE_SEQ;
|
||||
data.seq = (uint64_t)(send_counter + USE_SEQ_START);
|
||||
}
|
||||
int ret = rist_sender_data_write(rist_sender, &data);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to send test packet with error code %d!\n", ret);
|
||||
@@ -179,7 +187,7 @@ static PTHREAD_START_FUNC(send_data, arg) {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc != 5 && argc != 6) {
|
||||
if (argc < 5 || argc > 7) {
|
||||
return 99;
|
||||
}
|
||||
int profile = atoi(argv[1]);
|
||||
@@ -189,8 +197,10 @@ int main(int argc, char *argv[]) {
|
||||
int npd = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (argc == 6)
|
||||
if (argc >= 6)
|
||||
npd = atoi(argv[5]);
|
||||
if (argc >= 7)
|
||||
use_seq = atoi(argv[6]);
|
||||
|
||||
struct rist_ctx *receiver_ctx = NULL;
|
||||
struct rist_ctx *sender_ctx = NULL;
|
||||
@@ -249,6 +259,13 @@ int main(int argc, char *argv[]) {
|
||||
if (!got_first) {
|
||||
receive_count = (int)b->seq;
|
||||
got_first = true;
|
||||
if (use_seq && (int)b->seq < USE_SEQ_START) {
|
||||
fprintf(stderr, "USE_SEQ: first seq %"PRIu64" < expected start %d, "
|
||||
"sender-supplied seq was not preserved\n",
|
||||
b->seq, USE_SEQ_START);
|
||||
atomic_store(&failed, 1);
|
||||
atomic_store(&stop, 1);
|
||||
}
|
||||
}
|
||||
// Check entire mpegts structure
|
||||
int tsindex = (int)(b->payload_len / 188);
|
||||
|
||||
+11
-14
@@ -193,16 +193,14 @@ const char help_str[] = "Usage: %s [OPTIONS] \nWhere OPTIONS are:\n"
|
||||
" --statsinterval 1000 \\\n"
|
||||
" --verbose-level 6 \n";
|
||||
|
||||
/*
|
||||
static uint64_t risttools_convertRTPtoNTP(uint32_t i_rtp)
|
||||
{
|
||||
uint64_t i_ntp;
|
||||
int32_t clock = 90000;
|
||||
i_ntp = (uint64_t)i_rtp << 32;
|
||||
i_ntp /= clock;
|
||||
int32_t clock = 90000;
|
||||
i_ntp = (uint64_t)i_rtp << 32;
|
||||
i_ntp /= clock;
|
||||
return i_ntp;
|
||||
}
|
||||
*/
|
||||
|
||||
#if HAVE_SRP_SUPPORT
|
||||
char *srpfile = NULL;
|
||||
@@ -243,20 +241,19 @@ static void input_udp_recv(struct evsocket_ctx *evctx, int fd, short revents, vo
|
||||
// If we wanted to be more accurate, we could use the kernel nic capture timestamp (linux)
|
||||
data_block.ts_ntp = 0;
|
||||
data_block.flags = 0;
|
||||
uint8_t *rtp_hdr = recv_buf + ipheader_bytes;
|
||||
if (callback_object->udp_config->rtp_timestamp && recv_bufsize > 12)
|
||||
{
|
||||
// Extract timestamp from rtp header
|
||||
//uint32_t rtp_time = (recv_buf[4] << 24) | (recv_buf[5] << 16) | (recv_buf[6] << 8) | recv_buf[7];
|
||||
// Convert to NTP (assumes 90Khz)
|
||||
//data_block.ts_ntp = risttools_convertRTPtoNTP(rtp_time);
|
||||
// TODO: Figure out why this does not work (commenting out for now)
|
||||
uint32_t rtp_time = ((uint32_t)rtp_hdr[4] << 24) |
|
||||
((uint32_t)rtp_hdr[5] << 16) |
|
||||
((uint32_t)rtp_hdr[6] << 8) |
|
||||
(uint32_t)rtp_hdr[7];
|
||||
data_block.ts_ntp = risttools_convertRTPtoNTP(rtp_time);
|
||||
}
|
||||
if (callback_object->udp_config->rtp_sequence && recv_bufsize > 12)
|
||||
{
|
||||
// Extract sequence number from rtp header
|
||||
//data_block.seq = (uint64_t)((recv_buf[2] << 8) | recv_buf[3]);
|
||||
//data_block.flags = RIST_DATA_FLAGS_USE_SEQ;
|
||||
// TODO: Figure out why this does not work (commenting out for now)
|
||||
data_block.seq = (uint64_t)(((uint16_t)rtp_hdr[2] << 8) | rtp_hdr[3]);
|
||||
data_block.flags = RIST_DATA_FLAGS_USE_SEQ;
|
||||
}
|
||||
if (callback_object->udp_config->version == 1 && callback_object->udp_config->multiplex_mode == LIBRIST_MULTIPLEX_MODE_IPV4) {
|
||||
data_block.virt_src_port = UINT16_MAX;
|
||||
|
||||
Reference in New Issue
Block a user