RTP: send RTCP to clinet in server mode

Send RTCP correctly in the server mode to a client if we have the RTCP
connection (== receiving RTCP from the client).

It is done in the same way as it is currently implemented when UG is in
receiver-only mode without explicit remote address.
This commit is contained in:
Martin Pulec
2024-04-25 09:20:20 +02:00
parent 4191160a16
commit bb3d1e128f
4 changed files with 33 additions and 7 deletions

View File

@@ -905,11 +905,10 @@ error:
return NULL;
}
static const struct in6_addr in6_blackhole = IN6ADDR_BLACKHOLE_INIT;
bool udp_is_blackhole(socket_udp *s) {
return s->sock.ss_family == AF_INET6 &&
memcmp(&((struct sockaddr_in6 *) &s->sock)->sin6_addr, &in6_blackhole, IN6_BLACKHOLE_PREFIX_LEN) == 0;
is_addr_blackhole(
&((struct sockaddr_in6 *) &s->sock)->sin6_addr);
}
void udp_set_receiver(socket_udp *s, struct sockaddr *sa, socklen_t len) {

View File

@@ -1074,7 +1074,8 @@ struct rtp *rtp_init_if(const char *addr, const char *iface,
session->opt = (options *) malloc(sizeof(options));
session->userdata = userdata;
session->mt_recv = multithreaded;
session->send_rtcp_to_origin = tx_port == 0 && is_host_loopback(addr);
session->send_rtcp_to_origin =
(tx_port == 0 && is_host_loopback(addr)) || is_host_blackhole(addr);
if (rx_port == 0) {
const unsigned random_off = (ug_rand() % (IPPORT_MAX - IPPORT_DYNAMIC + 1)) & ~1U;

View File

@@ -3,7 +3,7 @@
* @author Martin Pulec <pulec@cesnet.cz>
*/
/*
* Copyright (c) 2016-2023 CESNET z.s.p.o.
* Copyright (c) 2016-2024 CESNET
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,9 @@
#include "config_win32.h"
#endif
#include <limits.h>
#include <stdint.h>
#ifdef WIN32
#include <tchar.h>
#else
@@ -156,6 +159,26 @@ static struct addrinfo *resolve_host(const char *hostname, const char *err_prefi
return ai;
}
/// returns true for RFC 6666 IPv6 black hole address
bool
is_addr_blackhole(const struct in6_addr *addr)
{
static const struct in6_addr in6_blackhole = IN6ADDR_BLACKHOLE_INIT;
return memcmp(addr, &in6_blackhole, IN6_BLACKHOLE_PREFIX_LEN) == 0;
}
/// returns true for RFC 6666 IPv6 black hole address string
bool
is_host_blackhole(const char *hostname)
{
if (strchr(hostname, ':') == NULL) { // not an IPv6 literal
return false;
}
struct in6_addr ipv6_addr;
inet_pton(AF_INET6, hostname, &ipv6_addr);
return is_addr_blackhole(&ipv6_addr);
}
bool is_host_loopback(const char *hostname)
{
struct addrinfo *ai = resolve_host(hostname, "is_host_loopback: ");

View File

@@ -3,7 +3,7 @@
* @author Martin Pulec <pulec@cesnet.cz>
*/
/*
* Copyright (c) 2016-2021 CESNET z.s.p.o.
* Copyright (c) 2016-2024 CESNET
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -50,19 +50,22 @@
#define IN6_MAX_ASCII_LEN 39 // 32 nibbles + 7 colons
#define IN6ADDR_BLACKHOLE_INIT { { { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } } // RFC 6666
#define IN6_BLACKHOLE_PREFIX_LEN 8
#define IN6_BLACKHOLE_PREFIX_LEN 8 // in bytes (64 bit prefix)
#define IN6_BLACKHOLE_STR "100::1"
#ifdef __cplusplus
extern "C" {
#endif
struct in6_addr;
struct sockaddr;
struct sockaddr_storage;
bool is_addr_blackhole(const struct in6_addr *addr);
bool is_addr_linklocal(struct sockaddr *sa);
bool is_addr_loopback(struct sockaddr *sa);
bool is_addr_private(struct sockaddr *sa);
bool is_addr_multicast(const char *addr);
bool is_host_blackhole(const char *hostname);
bool is_host_loopback(const char *hostname);
bool is_host_private(const char *hostname);
uint16_t socket_get_recv_port(int fd);