Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Macros | Enumerations | Functions | Variables
res_rtp_asterisk.c File Reference

Supports RTP and RTCP with Symmetric RTP support for NAT traversal. More...

#include "asterisk.h"
#include <arpa/nameser.h>
#include "asterisk/dns_core.h"
#include "asterisk/dns_internal.h"
#include "asterisk/dns_recurring.h"
#include <sys/time.h>
#include <signal.h>
#include <fcntl.h>
#include <math.h>
#include <openssl/opensslconf.h>
#include <openssl/opensslv.h>
#include <pjlib.h>
#include <pjlib-util.h>
#include <pjnath.h>
#include <ifaddrs.h>
#include "asterisk/conversions.h"
#include "asterisk/options.h"
#include "asterisk/logger_category.h"
#include "asterisk/stun.h"
#include "asterisk/pbx.h"
#include "asterisk/frame.h"
#include "asterisk/format_cache.h"
#include "asterisk/channel.h"
#include "asterisk/acl.h"
#include "asterisk/config.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/cli.h"
#include "asterisk/manager.h"
#include "asterisk/unaligned.h"
#include "asterisk/module.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/smoother.h"
#include "asterisk/uuid.h"
#include "asterisk/test.h"
#include "asterisk/data_buffer.h"
#include "asterisk/res_pjproject.h"
#include "asterisk/security_events.h"

Go to the source code of this file.

Data Structures

struct  ast_ice_host_candidate
 Structure which contains ICE host candidate mapping information. More...
 
struct  ast_rtcp
 Structure defining an RTCP session. More...
 
struct  ast_rtp
 RTP session description. More...
 
struct  ast_rtp_ioqueue_thread
 Structure which contains ioqueue thread information. More...
 
struct  ast_rtp_rtcp_nack_payload
 Structure for storing RTP packets for retransmission. More...
 
struct  frame_list
 
struct  host_candidates
 List of ICE host candidate mappings. More...
 
struct  ice_wrap
 
struct  ioqueues
 List of ioqueue threads. More...
 
struct  optional_ts
 
struct  rtp_learning_info
 RTP learning mode tracking information. More...
 
struct  rtp_red
 
struct  rtp_ssrc_mapping
 Structure used for mapping an incoming SSRC to an RTP instance. More...
 
struct  rtp_transport_wide_cc_packet_statistics
 Packet statistics (used for transport-cc) More...
 
struct  rtp_transport_wide_cc_statistics
 Statistics information (used for transport-cc) More...
 

Macros

#define CALC_LEARNING_MIN_DURATION(count)   (((count) - 1) * 9 - 5)
 Calculate the min learning duration in ms. More...
 
#define DEFAULT_DTLS_MTU   1200
 
#define DEFAULT_DTMF_TIMEOUT   (150 * (8000 / 1000))
 
#define DEFAULT_ICESUPPORT   1
 
#define DEFAULT_LEARNING_MIN_DURATION   CALC_LEARNING_MIN_DURATION(DEFAULT_LEARNING_MIN_SEQUENTIAL)
 
#define DEFAULT_LEARNING_MIN_SEQUENTIAL   4
 
#define DEFAULT_RTP_END   31000
 
#define DEFAULT_RTP_RECV_BUFFER_SIZE   20
 
#define DEFAULT_RTP_SEND_BUFFER_SIZE   250
 
#define DEFAULT_RTP_START   5000
 
#define DEFAULT_SRTP_REPLAY_PROTECTION   1
 
#define DEFAULT_STRICT_RTP   STRICT_RTP_YES
 
#define DEFAULT_STUN_SOFTWARE_ATTRIBUTE   1
 
#define DEFAULT_TURN_PORT   3478
 
#define FLAG_3389_WARNING   (1 << 0)
 
#define FLAG_DTMF_COMPENSATE   (1 << 4)
 
#define FLAG_NAT_ACTIVE   (3 << 1)
 
#define FLAG_NAT_INACTIVE   (0 << 1)
 
#define FLAG_NAT_INACTIVE_NOWARN   (1 << 1)
 
#define FLAG_NEED_MARKER_BIT   (1 << 3)
 
#define FLAG_REQ_LOCAL_BRIDGE_BIT   (1 << 5)
 
#define MAX_TIMESTAMP_SKEW   640
 
#define MAXIMUM_RTP_PORT   65535
 
#define MAXIMUM_RTP_RECV_BUFFER_SIZE   (DEFAULT_RTP_RECV_BUFFER_SIZE + 20)
 
#define MAXIMUM_RTP_SEND_BUFFER_SIZE   (DEFAULT_RTP_SEND_BUFFER_SIZE + 200)
 
#define MINIMUM_RTP_PORT   1024
 
#define MISSING_SEQNOS_ADDED_TRIGGER   2
 
#define OLD_PACKET_COUNT   1000
 
#define RESCALE(in, inmin, inmax, outmin, outmax)   ((((in - inmin)/(inmax-inmin))*(outmax-outmin))+outmin)
 
#define RTCP_DEFAULT_INTERVALMS   5000
 
#define RTCP_FB_NACK_BLOCK_WORD_LENGTH   2
 
#define RTCP_FB_REMB_BLOCK_WORD_LENGTH   4
 
#define RTCP_HEADER_SSRC_LENGTH   2
 
#define RTCP_LENGTH_MASK   0xFFFF
 
#define RTCP_LENGTH_SHIFT   0
 
#define RTCP_MAX_INTERVALMS   60000
 
#define RTCP_MIN_INTERVALMS   500
 
#define RTCP_PADDING_MASK   0x01
 
#define RTCP_PADDING_SHIFT   29
 
#define RTCP_PAYLOAD_TYPE_MASK   0xFF
 
#define RTCP_PAYLOAD_TYPE_SHIFT   16
 
#define RTCP_PT_APP   204
 
#define RTCP_PT_BYE   203
 
#define RTCP_PT_FUR   192
 
#define RTCP_PT_PSFB   AST_RTP_RTCP_PSFB
 
#define RTCP_PT_RR   AST_RTP_RTCP_RR
 
#define RTCP_PT_SDES   202
 
#define RTCP_PT_SR   AST_RTP_RTCP_SR
 
#define RTCP_REPORT_COUNT_MASK   0x1F
 
#define RTCP_REPORT_COUNT_SHIFT   24
 
#define RTCP_RR_BLOCK_WORD_LENGTH   6
 
#define RTCP_SR_BLOCK_WORD_LENGTH   5
 
#define RTCP_VALID_MASK   (RTCP_VERSION_MASK_SHIFTED | (((RTCP_PAYLOAD_TYPE_MASK & ~0x1)) << RTCP_PAYLOAD_TYPE_SHIFT))
 
#define RTCP_VALID_VALUE   (RTCP_VERSION_SHIFTED | (RTCP_PT_SR << RTCP_PAYLOAD_TYPE_SHIFT))
 
#define RTCP_VERSION   2U
 
#define RTCP_VERSION_MASK   0x03
 
#define RTCP_VERSION_MASK_SHIFTED   (RTCP_VERSION_MASK << RTCP_VERSION_SHIFT)
 
#define RTCP_VERSION_SHIFT   30
 
#define RTCP_VERSION_SHIFTED   (RTCP_VERSION << RTCP_VERSION_SHIFT)
 
#define RTP_DTLS_ESTABLISHED   -37
 
#define RTP_IGNORE_FIRST_PACKETS_COUNT   15
 
#define RTP_MTU   1200
 
#define RTP_SEQ_MOD   (1<<16)
 
#define SEQNO_CYCLE_OVER   65536
 
#define SRTP_MASTER_KEY_LEN   16
 
#define SRTP_MASTER_LEN   (SRTP_MASTER_KEY_LEN + SRTP_MASTER_SALT_LEN)
 
#define SRTP_MASTER_SALT_LEN   14
 
#define SSRC_MAPPING_ELEM_CMP(elem, value)   ((elem).instance == (value))
 SSRC mapping comparator for AST_VECTOR_REMOVE_CMP_UNORDERED() More...
 
#define STRICT_RTP_LEARN_TIMEOUT   5000
 Strict RTP learning timeout time in milliseconds. More...
 
#define TRANSPORT_SOCKET_RTCP   1
 
#define TRANSPORT_SOCKET_RTP   0
 
#define TRANSPORT_TURN_RTCP   3
 
#define TRANSPORT_TURN_RTP   2
 
#define TURN_STATE_WAIT_TIME   2000
 
#define ZFONE_PROFILE_ID   0x505a
 

Enumerations

enum  strict_rtp_mode { STRICT_RTP_NO = 0, STRICT_RTP_YES, STRICT_RTP_SEQNO }
 
enum  strict_rtp_state { STRICT_RTP_OPEN = 0, STRICT_RTP_LEARN, STRICT_RTP_CLOSED }
 

Functions

static void __init_pj_thread_storage (void)
 
static void __reg_module (void)
 
static struct ast_rtp_instance__rtp_find_instance_by_ssrc (struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned int ssrc, int source)
 
static int __rtp_recvfrom (struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int rtcp)
 
static int __rtp_sendto (struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int rtcp, int *via_ice, int use_srtp)
 
static void __unreg_module (void)
 
static void acl_change_stasis_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void ast2pj_rtp_ice_role (enum ast_rtp_ice_role ast_role, enum pj_ice_sess_role *pj_role)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static unsigned int ast_rtcp_calc_interval (struct ast_rtp *rtp)
 
static int ast_rtcp_calculate_sr_rr_statistics (struct ast_rtp_instance *instance, struct ast_rtp_rtcp_report *rtcp_report, struct ast_sockaddr remote_address, int ice, int sr)
 
static int ast_rtcp_generate_compound_prefix (struct ast_rtp_instance *instance, unsigned char *rtcpheader, struct ast_rtp_rtcp_report *report, int *sr)
 
static int ast_rtcp_generate_nack (struct ast_rtp_instance *instance, unsigned char *rtcpheader)
 
static int ast_rtcp_generate_report (struct ast_rtp_instance *instance, unsigned char *rtcpheader, struct ast_rtp_rtcp_report *rtcp_report, int *sr)
 
static int ast_rtcp_generate_sdes (struct ast_rtp_instance *instance, unsigned char *rtcpheader, struct ast_rtp_rtcp_report *rtcp_report)
 
static struct ast_frameast_rtcp_interpret (struct ast_rtp_instance *instance, struct ast_srtp *srtp, const unsigned char *rtcpdata, size_t size, struct ast_sockaddr *addr)
 
static struct ast_frameast_rtcp_read (struct ast_rtp_instance *instance)
 
static int ast_rtcp_write (const void *data)
 Write a RTCP packet to the far end. More...
 
static int ast_rtp_bundle (struct ast_rtp_instance *child, struct ast_rtp_instance *parent)
 
static void ast_rtp_change_source (struct ast_rtp_instance *instance)
 
static int ast_rtp_destroy (struct ast_rtp_instance *instance)
 
static int ast_rtp_dtmf_begin (struct ast_rtp_instance *instance, char digit)
 
static int ast_rtp_dtmf_compatible (struct ast_channel *chan0, struct ast_rtp_instance *instance0, struct ast_channel *chan1, struct ast_rtp_instance *instance1)
 
static int ast_rtp_dtmf_continuation (struct ast_rtp_instance *instance)
 
static int ast_rtp_dtmf_end (struct ast_rtp_instance *instance, char digit)
 
static int ast_rtp_dtmf_end_with_duration (struct ast_rtp_instance *instance, char digit, unsigned int duration)
 
static enum ast_rtp_dtmf_mode ast_rtp_dtmf_mode_get (struct ast_rtp_instance *instance)
 
static int ast_rtp_dtmf_mode_set (struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode)
 
static int ast_rtp_extension_enable (struct ast_rtp_instance *instance, enum ast_rtp_extension extension)
 
static int ast_rtp_fd (struct ast_rtp_instance *instance, int rtcp)
 
static const char * ast_rtp_get_cname (struct ast_rtp_instance *instance)
 
static unsigned int ast_rtp_get_ssrc (struct ast_rtp_instance *instance)
 
static int ast_rtp_get_stat (struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
 
static void ast_rtp_ice_add_cand (struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned comp_id, unsigned transport_id, pj_ice_cand_type type, pj_uint16_t local_pref, const pj_sockaddr_t *addr, const pj_sockaddr_t *base_addr, const pj_sockaddr_t *rel_addr, int addr_len)
 
static void ast_rtp_ice_add_remote_candidate (struct ast_rtp_instance *instance, const struct ast_rtp_engine_ice_candidate *candidate)
 
static void ast_rtp_ice_candidate_destroy (void *obj)
 Destructor for locally created ICE candidates.
 
static void ast_rtp_ice_change_components (struct ast_rtp_instance *instance, int num_components)
 
static struct ao2_containerast_rtp_ice_get_local_candidates (struct ast_rtp_instance *instance)
 
static const char * ast_rtp_ice_get_password (struct ast_rtp_instance *instance)
 
static const char * ast_rtp_ice_get_ufrag (struct ast_rtp_instance *instance)
 
static void ast_rtp_ice_lite (struct ast_rtp_instance *instance)
 
static void ast_rtp_ice_set_authentication (struct ast_rtp_instance *instance, const char *ufrag, const char *password)
 
static void ast_rtp_ice_set_role (struct ast_rtp_instance *instance, enum ast_rtp_ice_role role)
 
static void ast_rtp_ice_start (struct ast_rtp_instance *instance)
 
static void ast_rtp_ice_start_media (pj_ice_sess *ice, pj_status_t status)
 
static void ast_rtp_ice_stop (struct ast_rtp_instance *instance)
 
static void ast_rtp_ice_turn_request (struct ast_rtp_instance *instance, enum ast_rtp_ice_component_type component, enum ast_transport transport, const char *server, unsigned int port, const char *username, const char *password)
 
static struct ast_frameast_rtp_interpret (struct ast_rtp_instance *instance, struct ast_srtp *srtp, const struct ast_sockaddr *remote_address, unsigned char *read_area, int length, int prev_seqno, unsigned int bundled)
 
static int ast_rtp_local_bridge (struct ast_rtp_instance *instance0, struct ast_rtp_instance *instance1)
 
static int ast_rtp_new (struct ast_rtp_instance *instance, struct ast_sched_context *sched, struct ast_sockaddr *addr, void *data)
 
static void ast_rtp_on_ice_complete (pj_ice_sess *ice, pj_status_t status)
 
static void ast_rtp_on_ice_rx_data (pj_ice_sess *ice, unsigned comp_id, unsigned transport_id, void *pkt, pj_size_t size, const pj_sockaddr_t *src_addr, unsigned src_addr_len)
 
static pj_status_t ast_rtp_on_ice_tx_pkt (pj_ice_sess *ice, unsigned comp_id, unsigned transport_id, const void *pkt, pj_size_t size, const pj_sockaddr_t *dst_addr, unsigned dst_addr_len)
 
static void ast_rtp_on_turn_rtcp_state (pj_turn_sock *turn_sock, pj_turn_state_t old_state, pj_turn_state_t new_state)
 
static void ast_rtp_on_turn_rtp_state (pj_turn_sock *turn_sock, pj_turn_state_t old_state, pj_turn_state_t new_state)
 
static void ast_rtp_on_turn_rx_rtcp_data (pj_turn_sock *turn_sock, void *pkt, unsigned pkt_len, const pj_sockaddr_t *peer_addr, unsigned addr_len)
 
static void ast_rtp_on_turn_rx_rtp_data (pj_turn_sock *turn_sock, void *pkt, unsigned pkt_len, const pj_sockaddr_t *peer_addr, unsigned addr_len)
 
static void ast_rtp_on_valid_pair (pj_ice_sess *ice)
 
static void ast_rtp_prop_set (struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
 
static int ast_rtp_qos_set (struct ast_rtp_instance *instance, int tos, int cos, const char *desc)
 
static struct ast_frameast_rtp_read (struct ast_rtp_instance *instance, int rtcp)
 
static void ast_rtp_remote_address_set (struct ast_rtp_instance *instance, struct ast_sockaddr *addr)
 
static int ast_rtp_rtcp_handle_nack (struct ast_rtp_instance *instance, unsigned int *nackdata, unsigned int position, unsigned int length)
 
static int ast_rtp_sendcng (struct ast_rtp_instance *instance, int level)
 generate comfort noice (CNG) More...
 
static void ast_rtp_set_remote_ssrc (struct ast_rtp_instance *instance, unsigned int ssrc)
 
static void ast_rtp_set_stream_num (struct ast_rtp_instance *instance, int stream_num)
 
static void ast_rtp_stop (struct ast_rtp_instance *instance)
 
static void ast_rtp_stun_request (struct ast_rtp_instance *instance, struct ast_sockaddr *suggestion, const char *username)
 
static void ast_rtp_update_source (struct ast_rtp_instance *instance)
 
static int ast_rtp_write (struct ast_rtp_instance *instance, struct ast_frame *frame)
 
static int bridge_p2p_rtp_write (struct ast_rtp_instance *instance, struct ast_rtp_instance *instance1, unsigned int *rtpheader, int len, int hdrlen)
 
static void calc_mean_and_standard_deviation (double new_sample, double *mean, double *std_dev, unsigned int *count)
 
static double calc_media_experience_score (struct ast_rtp_instance *instance, double normdevrtt, double normdev_rxjitter, double stdev_rxjitter, double normdev_rxlost)
 Calculate a "media experience score" based on given data. More...
 
static void calc_rxstamp_and_jitter (struct timeval *tv, struct ast_rtp *rtp, unsigned int rx_rtp_ts, int mark)
 
static unsigned int calc_txstamp (struct ast_rtp *rtp, struct timeval *delivery)
 
static void calculate_lost_packet_statistics (struct ast_rtp *rtp, unsigned int *lost_packets, int *fraction_lost)
 
static void clean_stunaddr (void)
 
static int compare_by_value (int elem, int value)
 Helper function to compare an elem in a vector by value.
 
static struct ast_framecreate_dtmf_frame (struct ast_rtp_instance *instance, enum ast_frame_type type, int compensate)
 
static int create_new_socket (const char *type, int af)
 
static int find_by_value (int elem, int value)
 Helper function to find an elem in a vector by value.
 
static char * generate_random_string (char *buf, size_t size)
 
static char * handle_cli_rtcp_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_rtcp_set_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_rtp_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_rtp_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void host_candidate_overrides_clear (void)
 Helper function which clears the ICE host candidate mapping.
 
static int ice_candidate_cmp (void *obj, void *arg, int flags)
 
static int ice_candidates_compare (struct ao2_container *left, struct ao2_container *right)
 
static int ice_create (struct ast_rtp_instance *instance, struct ast_sockaddr *addr, int port, int replace)
 
static int ice_reset_session (struct ast_rtp_instance *instance)
 
static void ice_wrap_dtor (void *vdoomed)
 ao2 ICE wrapper object destructor. More...
 
static int ioqueue_worker_thread (void *data)
 Worker thread for ioqueue and timerheap.
 
static int load_module (void)
 
static void ntp2timeval (unsigned int msw, unsigned int lsw, struct timeval *tv)
 
static void pj2ast_rtp_ice_role (enum pj_ice_sess_role pj_role, enum ast_rtp_ice_role *ast_role)
 
static void pj_thread_register_check (void)
 Function used to check if the calling thread is registered with pjlib. If it is not it will be registered.
 
static struct ast_frameprocess_cn_rfc3389 (struct ast_rtp_instance *instance, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp, int payloadtype, int mark)
 
static struct ast_frameprocess_dtmf_cisco (struct ast_rtp_instance *instance, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp, int payloadtype, int mark)
 
static void process_dtmf_rfc2833 (struct ast_rtp_instance *instance, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp, int payloadtype, int mark, struct frame_list *frames)
 
static void put_unaligned_time24 (void *p, uint32_t time_msw, uint32_t time_lsw)
 
static struct ast_framered_t140_to_red (struct rtp_red *red)
 
static int red_write (const void *data)
 Write t140 redundancy frame. More...
 
static int reload_module (void)
 
static int rtcp_debug_test_addr (struct ast_sockaddr *addr)
 
static char * rtcp_do_debug_ip (struct ast_cli_args *a)
 
static int rtcp_mux (struct ast_rtp *rtp, const unsigned char *packet)
 
static const char * rtcp_payload_subtype2str (unsigned int pt, unsigned int subtype)
 
static const char * rtcp_payload_type2str (unsigned int pt)
 
static int rtcp_recvfrom (struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
 
static int rtcp_sendto (struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int *ice)
 
static void rtp_add_candidates_to_ice (struct ast_rtp_instance *instance, struct ast_rtp *rtp, struct ast_sockaddr *addr, int port, int component, int transport)
 
static int rtp_address_is_ice_blacklisted (const struct ast_sockaddr *address)
 
static int rtp_allocate_transport (struct ast_rtp_instance *instance, struct ast_rtp *rtp)
 
static void rtp_deallocate_transport (struct ast_rtp_instance *instance, struct ast_rtp *rtp)
 
static int rtp_debug_test_addr (struct ast_sockaddr *addr)
 
static char * rtp_do_debug_ip (struct ast_cli_args *a)
 
static struct ast_rtp_instancertp_find_instance_by_media_source_ssrc (struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned int ssrc)
 
static struct ast_rtp_instancertp_find_instance_by_packet_source_ssrc (struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned int ssrc)
 
static void rtp_instance_parse_extmap_extensions (struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned char *extension, int len)
 
static void rtp_instance_parse_transport_wide_cc (struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned char *data, int len)
 
static void rtp_instance_unlock (struct ast_rtp_instance *instance)
 
static void rtp_ioqueue_thread_destroy (struct ast_rtp_ioqueue_thread *ioqueue)
 Destroyer for ioqueue thread.
 
static struct ast_rtp_ioqueue_threadrtp_ioqueue_thread_get_or_create (void)
 Finder and allocator for an ioqueue thread.
 
static void rtp_ioqueue_thread_remove (struct ast_rtp_ioqueue_thread *ioqueue)
 Removal function for ioqueue thread, determines if it should be terminated and destroyed.
 
static int rtp_learning_rtp_seq_update (struct rtp_learning_info *info, uint16_t seq)
 
static void rtp_learning_seq_init (struct rtp_learning_info *info, uint16_t seq)
 
static void rtp_learning_start (struct ast_rtp *rtp)
 Start the strictrtp learning mode. More...
 
static int rtp_raw_write (struct ast_rtp_instance *instance, struct ast_frame *frame, int codec)
 
static int rtp_recvfrom (struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
 
static int rtp_red_buffer (struct ast_rtp_instance *instance, struct ast_frame *frame)
 
static int rtp_red_init (struct ast_rtp_instance *instance, int buffer_time, int *payloads, int generations)
 
static int rtp_reload (int reload, int by_external_config)
 
static int rtp_sendto (struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int *ice)
 
static void rtp_terminate_pjproject (void)
 
static int rtp_transport_wide_cc_feedback_produce (const void *data)
 
static void rtp_transport_wide_cc_feedback_status_append (unsigned char *rtcpheader, int *packet_len, int *status_vector_chunk_bits, uint16_t *status_vector_chunk, int *run_length_chunk_count, int *run_length_chunk_status, int status)
 
static void rtp_transport_wide_cc_feedback_status_vector_append (unsigned char *rtcpheader, int *packet_len, int *status_vector_chunk_bits, uint16_t *status_vector_chunk, int status)
 
static int rtp_transport_wide_cc_packet_statistics_cmp (struct rtp_transport_wide_cc_packet_statistics a, struct rtp_transport_wide_cc_packet_statistics b)
 
static void rtp_unload_acl (ast_rwlock_t *lock, struct ast_acl_list **acl)
 
static void rtp_write_rtcp_fir (struct ast_rtp_instance *instance, struct ast_rtp *rtp, struct ast_sockaddr *remote_address)
 
static void rtp_write_rtcp_psfb (struct ast_rtp_instance *instance, struct ast_rtp *rtp, struct ast_frame *frame, struct ast_sockaddr *remote_address)
 
static int store_stunaddr_resolved (const struct ast_dns_query *query)
 
static int stun_address_is_blacklisted (const struct ast_sockaddr *addr)
 
static void stunaddr_resolve_callback (const struct ast_dns_query *query)
 
static int timer_worker_thread (void *data)
 Worker thread for timerheap.
 
static void timeval2ntp (struct timeval tv, unsigned int *msw, unsigned int *lsw)
 
static int unload_module (void)
 
static void update_address_with_ice_candidate (pj_ice_sess *ice, enum ast_rtp_ice_component_type component, struct ast_sockaddr *cand_address)
 Helper function which updates an ast_sockaddr with the candidate used for the component.
 
static void update_jitter_stats (struct ast_rtp *rtp, unsigned int ia_jitter)
 
static void update_local_mes_stats (struct ast_rtp *rtp)
 
static void update_lost_stats (struct ast_rtp *rtp, unsigned int lost_packets)
 
static void update_reported_mes_stats (struct ast_rtp *rtp)
 
static int update_rtt_stats (struct ast_rtp *rtp, unsigned int lsr, unsigned int dlsr)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Asterisk RTP Stack" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, #ifdef 1 .requires = "res_pjproject", #endif }
 
static struct stasis_subscriptionacl_change_sub = NULL
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_rtp_engine_ice ast_rtp_ice
 
static pj_ice_sess_cb ast_rtp_ice_sess_cb
 
static pj_turn_sock_cb ast_rtp_turn_rtcp_sock_cb
 
static pj_turn_sock_cb ast_rtp_turn_rtp_sock_cb
 
static struct ast_rtp_engine asterisk_rtp_engine
 
static pj_caching_pool cachingpool
 Pool factory used by pjlib to allocate memory.
 
static struct ast_cli_entry cli_rtp []
 
static int dtmftimeout = DEFAULT_DTMF_TIMEOUT
 
static struct host_candidates host_candidates = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static struct ast_acl_listice_acl = NULL
 
static ast_rwlock_t ice_acl_lock = AST_RWLOCK_INIT_VALUE
 
static int icesupport = DEFAULT_ICESUPPORT
 
static struct ioqueues ioqueues = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static int learning_min_duration = DEFAULT_LEARNING_MIN_DURATION
 
static int learning_min_sequential = DEFAULT_LEARNING_MIN_SEQUENTIAL
 
static struct ast_sockaddr lo6 = { .len = 0 }
 
static struct ast_threadstorage pj_thread_storage = { .once = PTHREAD_ONCE_INIT , .key_init = __init_pj_thread_storage , .custom_init = NULL , }
 
static pj_pool_t * pool
 Global memory pool for configuration and timers.
 
struct ast_srtp_resres_srtp
 
struct ast_srtp_policy_resres_srtp_policy
 
static struct ast_sockaddr rtcpdebugaddr
 
static int rtcpdebugport
 
static int rtcpinterval = RTCP_DEFAULT_INTERVALMS
 
static int rtcpstats
 
static struct ast_sockaddr rtpdebugaddr
 
static int rtpdebugport
 
static int rtpend = DEFAULT_RTP_END
 
static int rtpstart = DEFAULT_RTP_START
 
static int srtp_replay_protection = DEFAULT_SRTP_REPLAY_PROTECTION
 
static int strictrtp = DEFAULT_STRICT_RTP
 
static struct ast_acl_liststun_acl = NULL
 
static ast_rwlock_t stun_acl_lock = AST_RWLOCK_INIT_VALUE
 
static int stun_software_attribute = DEFAULT_STUN_SOFTWARE_ATTRIBUTE
 
static struct sockaddr_in stunaddr
 
static ast_rwlock_t stunaddr_lock = AST_RWLOCK_INIT_VALUE
 
static struct ast_dns_query_recurringstunaddr_resolver = NULL
 
static pj_timer_heap_t * timer_heap
 Global timer heap.
 
static int timer_terminate
 Used to tell the timer thread to terminate.
 
static pj_thread_t * timer_thread
 Thread executing the timer heap.
 
static pj_str_t turnaddr
 
static pj_str_t turnpassword
 
static int turnport = DEFAULT_TURN_PORT
 
static pj_str_t turnusername
 

Detailed Description

Supports RTP and RTCP with Symmetric RTP support for NAT traversal.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Note
RTP is defined in RFC 3550.

Definition in file res_rtp_asterisk.c.

Macro Definition Documentation

#define CALC_LEARNING_MIN_DURATION (   count)    (((count) - 1) * 9 - 5)

Calculate the min learning duration in ms.

The min supported packet size represents 10 ms and we need to account for some jitter and fast clocks while learning. Some messed up devices have very bad jitter for a small packet sample size. Jitter can also be introduced by the network itself.

So we'll allow packets to come in every 9ms on average for fast clocking with the last one coming in 5ms early for jitter.

Definition at line 159 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define DEFAULT_DTMF_TIMEOUT   (150 * (8000 / 1000))

samples

Definition at line 142 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define DEFAULT_RTP_END   31000

Default maximum port number to end allocating RTP ports at

Definition at line 106 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define DEFAULT_RTP_RECV_BUFFER_SIZE   20

The initial size of the RTP receiver buffer

Definition at line 117 of file res_rtp_asterisk.c.

Referenced by ast_rtp_prop_set().

#define DEFAULT_RTP_SEND_BUFFER_SIZE   250

The initial size of the RTP send buffer

Definition at line 115 of file res_rtp_asterisk.c.

Referenced by ast_rtp_prop_set().

#define DEFAULT_RTP_START   5000

Default port number to start allocating RTP ports from

Definition at line 105 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define DEFAULT_STRICT_RTP   STRICT_RTP_YES

Enabled by default

Definition at line 189 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define MAXIMUM_RTP_PORT   65535

Maximum port number to accept

Definition at line 109 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define MAXIMUM_RTP_RECV_BUFFER_SIZE   (DEFAULT_RTP_RECV_BUFFER_SIZE + 20)

Maximum RTP receive buffer size

Definition at line 118 of file res_rtp_asterisk.c.

Referenced by ast_rtp_read().

#define MAXIMUM_RTP_SEND_BUFFER_SIZE   (DEFAULT_RTP_SEND_BUFFER_SIZE + 200)

Maximum RTP send buffer size

Definition at line 116 of file res_rtp_asterisk.c.

Referenced by ast_rtp_rtcp_handle_nack().

#define MINIMUM_RTP_PORT   1024

Minimum port number to accept

Definition at line 108 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define MISSING_SEQNOS_ADDED_TRIGGER   2

The number of immediate missing packets that will trigger an immediate NACK

Definition at line 120 of file res_rtp_asterisk.c.

Referenced by ast_rtp_read().

#define OLD_PACKET_COUNT   1000

The number of previous packets that are considered old

Definition at line 119 of file res_rtp_asterisk.c.

Referenced by ast_rtp_read().

#define RTCP_DEFAULT_INTERVALMS   5000

Default milli-seconds between RTCP reports we send

Definition at line 101 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define RTCP_MAX_INTERVALMS   60000

Max milli-seconds between RTCP reports we send

Definition at line 103 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define RTCP_MIN_INTERVALMS   500

Min milli-seconds between RTCP reports we send

Definition at line 102 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define RTCP_PT_APP   204

Application defined (From RFC3550)

Definition at line 135 of file res_rtp_asterisk.c.

#define RTCP_PT_BYE   203

Goodbye (To remove SSRC's from tables) (From RFC3550)

Definition at line 133 of file res_rtp_asterisk.c.

Referenced by ast_rtcp_interpret().

#define RTCP_PT_FUR   192

Full INTRA-frame Request / Fast Update Request (From RFC2032)

Definition at line 125 of file res_rtp_asterisk.c.

Referenced by ast_rtcp_interpret().

#define RTCP_PT_PSFB   AST_RTP_RTCP_PSFB

Payload Specific Feed Back (From RFC4585 also RFC5104)

Definition at line 138 of file res_rtp_asterisk.c.

Referenced by ast_rtcp_interpret().

#define RTCP_PT_RR   AST_RTP_RTCP_RR

Receiver Report (From RFC3550)

Definition at line 129 of file res_rtp_asterisk.c.

Referenced by ast_rtcp_interpret().

#define RTCP_PT_SDES   202

Source Description (From RFC3550)

Definition at line 131 of file res_rtp_asterisk.c.

Referenced by ast_rtcp_interpret().

#define RTCP_PT_SR   AST_RTP_RTCP_SR

Sender Report (From RFC3550)

Definition at line 127 of file res_rtp_asterisk.c.

Referenced by ast_rtcp_interpret().

#define RTP_IGNORE_FIRST_PACKETS_COUNT   15

Because both ends usually don't start sending RTP at the same time, some of the calculations like rtt and jitter will probably be unstable for a while so we'll skip some received packets before starting analyzing. This just affects analyzing; we still process the RTP as normal.

Definition at line 203 of file res_rtp_asterisk.c.

#define RTP_SEQ_MOD   (1<<16)

A sequence number can't be more than 16 bits

Definition at line 100 of file res_rtp_asterisk.c.

#define SEQNO_CYCLE_OVER   65536

The number after the maximum allowed sequence number

Definition at line 122 of file res_rtp_asterisk.c.

Referenced by ast_rtp_read().

#define SSRC_MAPPING_ELEM_CMP (   elem,
  value 
)    ((elem).instance == (value))

SSRC mapping comparator for AST_VECTOR_REMOVE_CMP_UNORDERED()

Parameters
elemElement to compare against
valueValue to compare with the vector element.
Return values
0if element does not match.
Non-zeroif element matches.

Definition at line 4192 of file res_rtp_asterisk.c.

Referenced by ast_rtp_bundle(), and ast_rtp_destroy().

#define STRICT_RTP_LEARN_TIMEOUT   5000

Strict RTP learning timeout time in milliseconds.

Note
Set to 5 seconds to allow reinvite chains for direct media to settle before media actually starts to arrive. There may be a reinvite collision involved on the other leg.

Definition at line 187 of file res_rtp_asterisk.c.

Referenced by ast_rtp_read().

Enumeration Type Documentation

Enumerator
STRICT_RTP_YES 

Don't adhere to any strict RTP rules

STRICT_RTP_SEQNO 

Strict RTP that restricts packets based on time and sequence number

Definition at line 174 of file res_rtp_asterisk.c.

174  {
175  STRICT_RTP_NO = 0, /*! Don't adhere to any strict RTP rules */
176  STRICT_RTP_YES, /*! Strict RTP that restricts packets based on time and sequence number */
177  STRICT_RTP_SEQNO, /*! Strict RTP that restricts packets based on sequence number */
178 };
Enumerator
STRICT_RTP_LEARN 

No RTP packets should be dropped, all sources accepted

STRICT_RTP_CLOSED 

Accept next packet as source

Definition at line 168 of file res_rtp_asterisk.c.

168  {
169  STRICT_RTP_OPEN = 0, /*! No RTP packets should be dropped, all sources accepted */
170  STRICT_RTP_LEARN, /*! Accept next packet as source */
171  STRICT_RTP_CLOSED, /*! Drop all RTP packets not coming from source that was learned */
172 };

Function Documentation

static struct ast_rtp_instance* __rtp_find_instance_by_ssrc ( struct ast_rtp_instance instance,
struct ast_rtp rtp,
unsigned int  ssrc,
int  source 
)
static
Precondition
instance is locked

Definition at line 6354 of file res_rtp_asterisk.c.

References ast_rtp_get_ssrc(), AST_VECTOR_GET_ADDR, AST_VECTOR_SIZE, rtp_ssrc_mapping::instance, rtp_ssrc_mapping::ssrc, ast_rtp::ssrc_mapping, rtp_ssrc_mapping::ssrc_valid, ast_rtp::themssrc, and ast_rtp::themssrc_valid.

Referenced by rtp_find_instance_by_media_source_ssrc(), and rtp_find_instance_by_packet_source_ssrc().

6356 {
6357  int index;
6358 
6359  if (!AST_VECTOR_SIZE(&rtp->ssrc_mapping)) {
6360  /* This instance is not bundled */
6361  return instance;
6362  }
6363 
6364  /* Find the bundled child instance */
6365  for (index = 0; index < AST_VECTOR_SIZE(&rtp->ssrc_mapping); ++index) {
6366  struct rtp_ssrc_mapping *mapping = AST_VECTOR_GET_ADDR(&rtp->ssrc_mapping, index);
6367  unsigned int mapping_ssrc = source ? ast_rtp_get_ssrc(mapping->instance) : mapping->ssrc;
6368 
6369  if (mapping->ssrc_valid && mapping_ssrc == ssrc) {
6370  return mapping->instance;
6371  }
6372  }
6373 
6374  /* Does the SSRC match the bundled parent? */
6375  if (rtp->themssrc_valid && rtp->themssrc == ssrc) {
6376  return instance;
6377  }
6378  return NULL;
6379 }
struct ast_rtp_instance * instance
The RTP instance this SSRC belongs to.
Structure used for mapping an incoming SSRC to an RTP instance.
unsigned int ssrc_valid
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
Definition: vector.h:668
struct ast_rtp::@480 ssrc_mapping
unsigned int themssrc_valid
unsigned int themssrc
static unsigned int ast_rtp_get_ssrc(struct ast_rtp_instance *instance)
unsigned int ssrc
The received SSRC.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
static int __rtp_recvfrom ( struct ast_rtp_instance instance,
void *  buf,
size_t  size,
int  flags,
struct ast_sockaddr sa,
int  rtcp 
)
static
Precondition
instance is locked

Definition at line 3169 of file res_rtp_asterisk.c.

References address, ao2_ref, ast_debug_dtls, ast_recvfrom(), AST_RTP_DTLS_CONNECTION_EXISTING, AST_RTP_DTLS_SETUP_ACTPASS, AST_RTP_DTLS_SETUP_PASSIVE, ast_rtp_instance_get_channel_id(), ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address, ast_rtp_instance_set_remote_address, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_pj_sockaddr_cmp(), ast_sockaddr_stringify(), ast_rtp::ice, ast_rtp::ice_active_remote_candidates, ast_rtp::ice_media_started, ast_rtp::ice_proposed_remote_candidates, ast_rtp::passthrough, pj_thread_register_check(), ice_wrap::real_ice, ast_rtp::rtcp_loop, ast_rtp::rtp_loop, ast_rtcp::s, and ast_rtcp::them.

Referenced by rtcp_recvfrom(), and rtp_recvfrom().

3170 {
3171  int len;
3172  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
3173 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
3174  char *in = buf;
3175 #endif
3176 #ifdef HAVE_PJPROJECT
3177  struct ast_sockaddr *loop = rtcp ? &rtp->rtcp_loop : &rtp->rtp_loop;
3178 #endif
3179 #ifdef TEST_FRAMEWORK
3180  struct ast_rtp_engine_test *test = ast_rtp_instance_get_test(instance);
3181 #endif
3182 
3183  if ((len = ast_recvfrom(rtcp ? rtp->rtcp->s : rtp->s, buf, size, flags, sa)) < 0) {
3184  return len;
3185  }
3186 
3187 #ifdef TEST_FRAMEWORK
3188  if (test && test->packets_to_drop > 0) {
3189  test->packets_to_drop--;
3190  return 0;
3191  }
3192 #endif
3193 
3194 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
3195  /* If this is an SSL packet pass it to OpenSSL for processing. RFC section for first byte value:
3196  * https://tools.ietf.org/html/rfc5764#section-5.1.2 */
3197  if ((*in >= 20) && (*in <= 63)) {
3198  struct dtls_details *dtls = !rtcp ? &rtp->dtls : &rtp->rtcp->dtls;
3199  int res = 0;
3200 
3201  /* If no SSL session actually exists terminate things */
3202  if (!dtls->ssl) {
3203  ast_log(LOG_ERROR, "Received SSL traffic on RTP instance '%p' without an SSL session\n",
3204  instance);
3205  return -1;
3206  }
3207 
3208  ast_debug_dtls(3, "(%p) DTLS - __rtp_recvfrom rtp=%p - Got SSL packet '%d'\n", instance, rtp, *in);
3209 
3210  /*
3211  * If ICE is in use, we can prevent a possible DOS attack
3212  * by allowing DTLS protocol messages (client hello, etc)
3213  * only from sources that are in the active remote
3214  * candidates list.
3215  */
3216 
3217 #ifdef HAVE_PJPROJECT
3218  if (rtp->ice) {
3219  int pass_src_check = 0;
3220  int ix = 0;
3221 
3222  /*
3223  * You'd think that this check would cause a "deadlock"
3224  * because ast_rtp_ice_start_media calls dtls_perform_handshake
3225  * before it sets ice_media_started = 1 so how can we do a
3226  * handshake if we're dropping packets before we send them
3227  * to openssl. Fortunately, dtls_perform_handshake just sets
3228  * up openssl to do the handshake and doesn't actually perform it
3229  * itself and the locking prevents __rtp_recvfrom from
3230  * running before the ice_media_started flag is set. So only
3231  * unexpected DTLS packets can get dropped here.
3232  */
3233  if (!rtp->ice_media_started) {
3234  ast_log(LOG_WARNING, "%s: DTLS packet from %s dropped. ICE not completed yet.\n",
3237  return 0;
3238  }
3239 
3240  /*
3241  * If we got this far, then there have to be candidates.
3242  * We have to use pjproject's rcands because they may have
3243  * peer reflexive candidates that our ice_active_remote_candidates
3244  * won't.
3245  */
3246  for (ix = 0; ix < rtp->ice->real_ice->rcand_cnt; ix++) {
3247  pj_ice_sess_cand *rcand = &rtp->ice->real_ice->rcand[ix];
3248  if (ast_sockaddr_pj_sockaddr_cmp(sa, &rcand->addr) == 0) {
3249  pass_src_check = 1;
3250  break;
3251  }
3252  }
3253 
3254  if (!pass_src_check) {
3255  ast_log(LOG_WARNING, "%s: DTLS packet from %s dropped. Source not in ICE active candidate list.\n",
3258  return 0;
3259  }
3260  }
3261 #endif
3262 
3263  /*
3264  * A race condition is prevented between dtls_perform_handshake()
3265  * and this function because both functions have to get the
3266  * instance lock before they can do anything. The
3267  * dtls_perform_handshake() function needs to start the timer
3268  * before we stop it below.
3269  */
3270 
3271  /* Before we feed data into OpenSSL ensure that the timeout timer is either stopped or completed */
3272  ao2_unlock(instance);
3273  dtls_srtp_stop_timeout_timer(instance, rtp, rtcp);
3274  ao2_lock(instance);
3275 
3276  /* If we don't yet know if we are active or passive and we receive a packet... we are obviously passive */
3277  if (dtls->dtls_setup == AST_RTP_DTLS_SETUP_ACTPASS) {
3278  dtls->dtls_setup = AST_RTP_DTLS_SETUP_PASSIVE;
3279  SSL_set_accept_state(dtls->ssl);
3280  }
3281 
3282  BIO_write(dtls->read_bio, buf, len);
3283 
3284  len = SSL_read(dtls->ssl, buf, len);
3285 
3286  if ((len < 0) && (SSL_get_error(dtls->ssl, len) == SSL_ERROR_SSL)) {
3287  unsigned long error = ERR_get_error();
3288  ast_log(LOG_ERROR, "DTLS failure occurred on RTP instance '%p' due to reason '%s', terminating\n",
3289  instance, ERR_reason_error_string(error));
3290  return -1;
3291  }
3292 
3293  if (SSL_is_init_finished(dtls->ssl)) {
3294  /* Any further connections will be existing since this is now established */
3295  dtls->connection = AST_RTP_DTLS_CONNECTION_EXISTING;
3296  /* Use the keying material to set up key/salt information */
3297  if ((res = dtls_srtp_setup(rtp, instance, rtcp))) {
3298  return res;
3299  }
3300  /* Notify that dtls has been established */
3301  res = RTP_DTLS_ESTABLISHED;
3302 
3303  ast_debug_dtls(3, "(%p) DTLS - __rtp_recvfrom rtp=%p - established'\n", instance, rtp);
3304  } else {
3305  /* Since we've sent additional traffic start the timeout timer for retransmission */
3306  dtls_srtp_start_timeout_timer(instance, rtp, rtcp);
3307  }
3308 
3309  return res;
3310  }
3311 #endif
3312 
3313 #ifdef HAVE_PJPROJECT
3314  if (!ast_sockaddr_isnull(loop) && !ast_sockaddr_cmp(loop, sa)) {
3315  /* ICE traffic will have been handled in the TURN callback, so skip it but update the address
3316  * so it reflects the actual source and not the loopback
3317  */
3318  if (rtcp) {
3319  ast_sockaddr_copy(sa, &rtp->rtcp->them);
3320  } else {
3322  }
3323  } else if (rtp->ice) {
3324  pj_str_t combined = pj_str(ast_sockaddr_stringify(sa));
3325  pj_sockaddr address;
3326  pj_status_t status;
3327  struct ice_wrap *ice;
3328 
3330 
3331  pj_sockaddr_parse(pj_AF_UNSPEC(), 0, &combined, &address);
3332 
3333  /* Release the instance lock to avoid deadlock with PJPROJECT group lock */
3334  ice = rtp->ice;
3335  ao2_ref(ice, +1);
3336  ao2_unlock(instance);
3337  status = pj_ice_sess_on_rx_pkt(ice->real_ice,
3338  rtcp ? AST_RTP_ICE_COMPONENT_RTCP : AST_RTP_ICE_COMPONENT_RTP,
3339  rtcp ? TRANSPORT_SOCKET_RTCP : TRANSPORT_SOCKET_RTP, buf, len, &address,
3340  pj_sockaddr_get_len(&address));
3341  ao2_ref(ice, -1);
3342  ao2_lock(instance);
3343  if (status != PJ_SUCCESS) {
3344  char err_buf[100];
3345 
3346  pj_strerror(status, err_buf, sizeof(err_buf));
3347  ast_log(LOG_WARNING, "PJ ICE Rx error status code: %d '%s'.\n",
3348  (int)status, err_buf);
3349  return -1;
3350  }
3351  if (!rtp->passthrough) {
3352  /* If a unidirectional ICE negotiation occurs then lock on to the source of the
3353  * ICE traffic and use it as the target. This will occur if the remote side only
3354  * wants to receive media but never send to us.
3355  */
3357  if (rtcp) {
3358  ast_sockaddr_copy(&rtp->rtcp->them, sa);
3359  } else {
3361  }
3362  }
3363  return 0;
3364  }
3365  rtp->passthrough = 0;
3366  }
3367 #endif
3368 
3369  return len;
3370 }
RTP session description.
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
struct ast_sockaddr them
static struct ast_sockaddr address
Address for UDPTL.
Definition: res_pjsip_t38.c:56
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
struct ao2_container * ice_active_remote_candidates
Socket address structure.
Definition: netsock2.h:97
static void pj_thread_register_check(void)
Function used to check if the calling thread is registered with pjlib. If it is not it will be regist...
const char * ast_rtp_instance_get_channel_id(struct ast_rtp_instance *instance)
Get the unique ID of the channel that owns this RTP instance.
Definition: rtp_engine.c:570
struct ao2_container * ice_proposed_remote_candidates
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
struct ast_sockaddr rtp_loop
struct ast_sockaddr rtcp_loop
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ice_wrap * ice
unsigned int ice_media_started
#define ast_rtp_instance_set_remote_address(instance, address)
Set the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1133
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
ssize_t ast_recvfrom(int sockfd, void *buf, size_t len, int flags, struct ast_sockaddr *src_addr)
Wrapper around recvfrom(2) that uses struct ast_sockaddr.
Definition: netsock2.c:606
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
#define ast_debug_dtls(sublevel,...)
Log debug level DTLS information.
Definition: rtp_engine.h:3051
int ast_sockaddr_pj_sockaddr_cmp(const struct ast_sockaddr *addr, const pj_sockaddr *pjaddr)
Compare an ast_sockaddr to a pj_sockaddr.
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1245
pj_ice_sess * real_ice
unsigned int passthrough
static int __rtp_sendto ( struct ast_rtp_instance instance,
void *  buf,
size_t  size,
int  flags,
struct ast_sockaddr sa,
int  rtcp,
int *  via_ice,
int  use_srtp 
)
static
Precondition
instance is locked

Definition at line 3385 of file res_rtp_asterisk.c.

References ao2_ref, ast_rtp_instance_get_data(), ast_rtp_instance_get_srtp(), ast_rtp_instance_set_last_tx(), ast_sendto(), ast_rtp::bundled, ast_rtp::ice, pj_thread_register_check(), ice_wrap::real_ice, and ast_rtcp::s.

Referenced by rtcp_sendto(), and rtp_sendto().

3386 {
3387  int len = size;
3388  void *temp = buf;
3389  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
3390  struct ast_rtp_instance *transport = rtp->bundled ? rtp->bundled : instance;
3391  struct ast_rtp *transport_rtp = ast_rtp_instance_get_data(transport);
3392  struct ast_srtp *srtp = ast_rtp_instance_get_srtp(transport, rtcp);
3393  int res;
3394 
3395  *via_ice = 0;
3396 
3397  if (use_srtp && res_srtp && srtp && res_srtp->protect(srtp, &temp, &len, rtcp) < 0) {
3398  return -1;
3399  }
3400 
3401 #ifdef HAVE_PJPROJECT
3402  if (transport_rtp->ice) {
3403  enum ast_rtp_ice_component_type component = rtcp ? AST_RTP_ICE_COMPONENT_RTCP : AST_RTP_ICE_COMPONENT_RTP;
3404  pj_status_t status;
3405  struct ice_wrap *ice;
3406 
3407  /* If RTCP is sharing the same socket then use the same component */
3408  if (rtcp && rtp->rtcp->s == rtp->s) {
3409  component = AST_RTP_ICE_COMPONENT_RTP;
3410  }
3411 
3413 
3414  /* Release the instance lock to avoid deadlock with PJPROJECT group lock */
3415  ice = transport_rtp->ice;
3416  ao2_ref(ice, +1);
3417  if (instance == transport) {
3418  ao2_unlock(instance);
3419  }
3420  status = pj_ice_sess_send_data(ice->real_ice, component, temp, len);
3421  ao2_ref(ice, -1);
3422  if (instance == transport) {
3423  ao2_lock(instance);
3424  }
3425  if (status == PJ_SUCCESS) {
3426  *via_ice = 1;
3427  return len;
3428  }
3429  }
3430 #endif
3431 
3432  res = ast_sendto(rtcp ? transport_rtp->rtcp->s : transport_rtp->s, temp, len, flags, sa);
3433  if (res > 0) {
3434  ast_rtp_instance_set_last_tx(instance, time(NULL));
3435  }
3436 
3437  return res;
3438 }
RTP session description.
ssize_t ast_sendto(int sockfd, const void *buf, size_t len, int flags, const struct ast_sockaddr *dest_addr)
Wrapper around sendto(2) that uses ast_sockaddr.
Definition: netsock2.c:614
struct ast_rtp_instance * bundled
struct ast_srtp * ast_rtp_instance_get_srtp(struct ast_rtp_instance *instance, int rtcp)
Obtain the SRTP instance associated with an RTP instance.
Definition: rtp_engine.c:2911
void ast_rtp_instance_set_last_tx(struct ast_rtp_instance *rtp, time_t time)
Set the last RTP transmission time.
Definition: rtp_engine.c:3944
static void pj_thread_register_check(void)
Function used to check if the calling thread is registered with pjlib. If it is not it will be regist...
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ice_wrap * ice
ast_rtp_ice_component_type
ICE component types.
Definition: rtp_engine.h:513
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
pj_ice_sess * real_ice
static unsigned int ast_rtcp_calc_interval ( struct ast_rtp rtp)
static
Todo:
XXX Do a more reasonable calculation on this one Look in RFC 3550 Section A.7 for an example

Definition at line 3461 of file res_rtp_asterisk.c.

References rtcpinterval.

Referenced by rtp_raw_write().

3462 {
3463  unsigned int interval;
3464  /*! \todo XXX Do a more reasonable calculation on this one
3465  * Look in RFC 3550 Section A.7 for an example*/
3466  interval = rtcpinterval;
3467  return interval;
3468 }
static int rtcpinterval
static struct ast_frame* ast_rtcp_interpret ( struct ast_rtp_instance instance,
struct ast_srtp srtp,
const unsigned char *  rtcpdata,
size_t  size,
struct ast_sockaddr addr 
)
static

True if we have seen an acceptable SSRC to learn the remote RTCP address

True if the ssrc value we have is valid and not garbage because it doesn't exist.

Always use packet source SSRC to find the rtp instance unless explicitly told not to.

Definition at line 6585 of file res_rtp_asterisk.c.

References ast_calloc, AST_CONTROL_VIDUPDATE, ast_debug, ast_debug_rtcp, AST_FRAME_CONTROL, AST_FRAME_RTCP, AST_FRIENDLY_OFFSET, ast_json_pack(), ast_json_unref(), ast_null_frame, ast_rtp_get_rate(), ast_rtp_instance_get_channel_id(), ast_rtp_instance_get_data(), ast_rtp_instance_get_prop(), AST_RTP_PROPERTY_NAT, AST_RTP_PROPERTY_REMB, ast_rtp_publish_rtcp_message(), AST_RTP_RTCP_FMT_FIR, AST_RTP_RTCP_FMT_NACK, AST_RTP_RTCP_FMT_PLI, AST_RTP_RTCP_FMT_REMB, ast_rtp_rtcp_handle_nack(), ast_rtp_rtcp_received_type(), ast_rtp_rtcp_report_alloc(), AST_RTP_RTCP_RTPFB, ast_samp2sec(), ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_stringify(), ast_rtp_rtcp_feedback_remb::br_exp, ast_rtp_rtcp_feedback_remb::br_mantissa, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_rtp::f, ast_rtp_rtcp_feedback::fmt, ast_frame_subclass::format, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::mallocd, ast_frame::offset, RAII_VAR, ast_rtp_rtcp_feedback::remb, ast_rtp_rtcp_report::report_block, ast_rtcp::reported_mes, RTCP_PT_BYE, RTCP_PT_FUR, RTCP_PT_PSFB, RTCP_PT_RR, RTCP_PT_SDES, RTCP_PT_SR, rtp_find_instance_by_media_source_ssrc(), rtp_find_instance_by_packet_source_ssrc(), ast_rtcp::rtt, ast_rtcp::rxlsr, ast_frame::samples, ast_rtp::send_buffer, ast_rtcp::soc, ast_rtcp::spc, ast_frame::src, ast_frame::stream_num, ast_rtp::stream_num, ast_rtp::strict_rtp_state, ast_frame::subclass, ast_rtcp::them, ast_rtcp::themrxlsr, ast_rtp::themssrc, and ast_rtp::themssrc_valid.

Referenced by ast_rtcp_read(), and ast_rtp_read().

6587 {
6588  struct ast_rtp_instance *transport = instance;
6589  struct ast_rtp *transport_rtp = ast_rtp_instance_get_data(instance);
6590  int len = size;
6591  unsigned int *rtcpheader = (unsigned int *)(rtcpdata);
6592  unsigned int packetwords;
6593  unsigned int position;
6594  unsigned int first_word;
6595  /*! True if we have seen an acceptable SSRC to learn the remote RTCP address */
6596  unsigned int ssrc_seen;
6597  struct ast_rtp_rtcp_report_block *report_block;
6598  struct ast_frame *f = &ast_null_frame;
6599 #ifdef TEST_FRAMEWORK
6600  struct ast_rtp_engine_test *test_engine;
6601 #endif
6602 
6603  /* If this is encrypted then decrypt the payload */
6604  if ((*rtcpheader & 0xC0) && res_srtp && srtp && res_srtp->unprotect(
6605  srtp, rtcpheader, &len, 1 | (srtp_replay_protection << 1)) < 0) {
6606  return &ast_null_frame;
6607  }
6608 
6609  packetwords = len / 4;
6610 
6611  ast_debug_rtcp(2, "(%s) RTCP got report of %d bytes from %s\n",
6613  len, ast_sockaddr_stringify(addr));
6614 
6615  /*
6616  * Validate the RTCP packet according to an adapted and slightly
6617  * modified RFC3550 validation algorithm.
6618  */
6619  if (packetwords < RTCP_HEADER_SSRC_LENGTH) {
6620  ast_debug_rtcp(2, "(%s) RTCP %p -- from %s: Frame size (%u words) is too short\n",
6622  transport_rtp, ast_sockaddr_stringify(addr), packetwords);
6623  return &ast_null_frame;
6624  }
6625  position = 0;
6626  first_word = ntohl(rtcpheader[position]);
6627  if ((first_word & RTCP_VALID_MASK) != RTCP_VALID_VALUE) {
6628  ast_debug_rtcp(2, "(%s) RTCP %p -- from %s: Failed first packet validity check\n",
6630  transport_rtp, ast_sockaddr_stringify(addr));
6631  return &ast_null_frame;
6632  }
6633  do {
6634  position += ((first_word >> RTCP_LENGTH_SHIFT) & RTCP_LENGTH_MASK) + 1;
6635  if (packetwords <= position) {
6636  break;
6637  }
6638  first_word = ntohl(rtcpheader[position]);
6639  } while ((first_word & RTCP_VERSION_MASK_SHIFTED) == RTCP_VERSION_SHIFTED);
6640  if (position != packetwords) {
6641  ast_debug_rtcp(2, "(%s) RTCP %p -- from %s: Failed packet version or length check\n",
6643  transport_rtp, ast_sockaddr_stringify(addr));
6644  return &ast_null_frame;
6645  }
6646 
6647  /*
6648  * Note: RFC3605 points out that true NAT (vs NAPT) can cause RTCP
6649  * to have a different IP address and port than RTP. Otherwise, when
6650  * strictrtp is enabled we could reject RTCP packets not coming from
6651  * the learned RTP IP address if it is available.
6652  */
6653 
6654  /*
6655  * strictrtp safety needs SSRC to match before we use the
6656  * sender's address for symmetrical RTP to send our RTCP
6657  * reports.
6658  *
6659  * If strictrtp is not enabled then claim to have already seen
6660  * a matching SSRC so we'll accept this packet's address for
6661  * symmetrical RTP.
6662  */
6663  ssrc_seen = transport_rtp->strict_rtp_state == STRICT_RTP_OPEN;
6664 
6665  position = 0;
6666  while (position < packetwords) {
6667  unsigned int i;
6668  unsigned int pt;
6669  unsigned int rc;
6670  unsigned int ssrc;
6671  /*! True if the ssrc value we have is valid and not garbage because it doesn't exist. */
6672  unsigned int ssrc_valid;
6673  unsigned int length;
6674  unsigned int min_length;
6675  /*! Always use packet source SSRC to find the rtp instance unless explicitly told not to. */
6676  unsigned int use_packet_source = 1;
6677 
6678  struct ast_json *message_blob;
6679  RAII_VAR(struct ast_rtp_rtcp_report *, rtcp_report, NULL, ao2_cleanup);
6680  struct ast_rtp_instance *child;
6681  struct ast_rtp *rtp;
6682  struct ast_rtp_rtcp_feedback *feedback;
6683 
6684  i = position;
6685  first_word = ntohl(rtcpheader[i]);
6686  pt = (first_word >> RTCP_PAYLOAD_TYPE_SHIFT) & RTCP_PAYLOAD_TYPE_MASK;
6687  rc = (first_word >> RTCP_REPORT_COUNT_SHIFT) & RTCP_REPORT_COUNT_MASK;
6688  /* RFC3550 says 'length' is the number of words in the packet - 1 */
6689  length = ((first_word >> RTCP_LENGTH_SHIFT) & RTCP_LENGTH_MASK) + 1;
6690 
6691  /* Check expected RTCP packet record length */
6692  min_length = RTCP_HEADER_SSRC_LENGTH;
6693  switch (pt) {
6694  case RTCP_PT_SR:
6695  min_length += RTCP_SR_BLOCK_WORD_LENGTH;
6696  /* fall through */
6697  case RTCP_PT_RR:
6698  min_length += (rc * RTCP_RR_BLOCK_WORD_LENGTH);
6699  use_packet_source = 0;
6700  break;
6701  case RTCP_PT_FUR:
6702  break;
6703  case AST_RTP_RTCP_RTPFB:
6704  switch (rc) {
6705  case AST_RTP_RTCP_FMT_NACK:
6706  min_length += RTCP_FB_NACK_BLOCK_WORD_LENGTH;
6707  break;
6708  default:
6709  break;
6710  }
6711  use_packet_source = 0;
6712  break;
6713  case RTCP_PT_PSFB:
6714  switch (rc) {
6715  case AST_RTP_RTCP_FMT_REMB:
6716  min_length += RTCP_FB_REMB_BLOCK_WORD_LENGTH;
6717  break;
6718  default:
6719  break;
6720  }
6721  break;
6722  case RTCP_PT_SDES:
6723  case RTCP_PT_BYE:
6724  /*
6725  * There may not be a SSRC/CSRC present. The packet is
6726  * useless but still valid if it isn't present.
6727  *
6728  * We don't know what min_length should be so disable the check
6729  */
6730  min_length = length;
6731  break;
6732  default:
6733  ast_debug_rtcp(1, "(%p) RTCP %p -- from %s: %u(%s) skipping record\n",
6734  instance, transport_rtp, ast_sockaddr_stringify(addr), pt, rtcp_payload_type2str(pt));
6735  if (rtcp_debug_test_addr(addr)) {
6736  ast_verbose("\n");
6737  ast_verbose("RTCP from %s: %u(%s) skipping record\n",
6738  ast_sockaddr_stringify(addr), pt, rtcp_payload_type2str(pt));
6739  }
6740  position += length;
6741  continue;
6742  }
6743  if (length < min_length) {
6744  ast_debug_rtcp(1, "(%p) RTCP %p -- from %s: %u(%s) length field less than expected minimum. Min:%u Got:%u\n",
6745  instance, transport_rtp, ast_sockaddr_stringify(addr), pt, rtcp_payload_type2str(pt),
6746  min_length - 1, length - 1);
6747  return &ast_null_frame;
6748  }
6749 
6750  /* Get the RTCP record SSRC if defined for the record */
6751  ssrc_valid = 1;
6752  switch (pt) {
6753  case RTCP_PT_SR:
6754  case RTCP_PT_RR:
6755  rtcp_report = ast_rtp_rtcp_report_alloc(rc);
6756  if (!rtcp_report) {
6757  return &ast_null_frame;
6758  }
6759  rtcp_report->reception_report_count = rc;
6760 
6761  ssrc = ntohl(rtcpheader[i + 2]);
6762  rtcp_report->ssrc = ssrc;
6763  break;
6764  case RTCP_PT_FUR:
6765  case RTCP_PT_PSFB:
6766  ssrc = ntohl(rtcpheader[i + 1]);
6767  break;
6768  case AST_RTP_RTCP_RTPFB:
6769  ssrc = ntohl(rtcpheader[i + 2]);
6770  break;
6771  case RTCP_PT_SDES:
6772  case RTCP_PT_BYE:
6773  default:
6774  ssrc = 0;
6775  ssrc_valid = 0;
6776  break;
6777  }
6778 
6779  if (rtcp_debug_test_addr(addr)) {
6780  const char *subtype = rtcp_payload_subtype2str(pt, rc);
6781 
6782  ast_verbose("\n");
6783  ast_verbose("RTCP from %s\n", ast_sockaddr_stringify(addr));
6784  ast_verbose("PT: %u (%s)\n", pt, rtcp_payload_type2str(pt));
6785  if (subtype) {
6786  ast_verbose("Packet Subtype: %u (%s)\n", rc, subtype);
6787  } else {
6788  ast_verbose("Reception reports: %u\n", rc);
6789  }
6790  ast_verbose("SSRC of sender: %u\n", ssrc);
6791  }
6792 
6793  /* Determine the appropriate instance for this */
6794  if (ssrc_valid) {
6795  /*
6796  * Depending on the payload type, either the packet source or media source
6797  * SSRC is used.
6798  */
6799  if (use_packet_source) {
6800  child = rtp_find_instance_by_packet_source_ssrc(transport, transport_rtp, ssrc);
6801  } else {
6802  child = rtp_find_instance_by_media_source_ssrc(transport, transport_rtp, ssrc);
6803  }
6804  if (child && child != transport) {
6805  /*
6806  * It is safe to hold the child lock while holding the parent lock.
6807  * We guarantee that the locking order is always parent->child or
6808  * that the child lock is not held when acquiring the parent lock.
6809  */
6810  ao2_lock(child);
6811  instance = child;
6812  rtp = ast_rtp_instance_get_data(instance);
6813  } else {
6814  /* The child is the parent! We don't need to unlock it. */
6815  child = NULL;
6816  rtp = transport_rtp;
6817  }
6818  } else {
6819  child = NULL;
6820  rtp = transport_rtp;
6821  }
6822 
6823  if (ssrc_valid && rtp->themssrc_valid) {
6824  /*
6825  * If the SSRC is 1, we still need to handle RTCP since this could be a
6826  * special case. For example, if we have a unidirectional video stream, the
6827  * SSRC may be set to 1 by the browser (in the case of chromium), and requests
6828  * will still need to be processed so that video can flow as expected. This
6829  * should only be done for PLI and FUR, since there is not a way to get the
6830  * appropriate rtp instance when the SSRC is 1.
6831  */
6832  int exception = (ssrc == 1 && !((pt == RTCP_PT_PSFB && rc == AST_RTP_RTCP_FMT_PLI) || pt == RTCP_PT_FUR));
6833  if ((ssrc != rtp->themssrc && use_packet_source && ssrc != 1)
6834  || exception) {
6835  /*
6836  * Skip over this RTCP record as it does not contain the
6837  * correct SSRC. We should not act upon RTCP records
6838  * for a different stream.
6839  */
6840  position += length;
6841  ast_debug_rtcp(1, "(%p) RTCP %p -- from %s: Skipping record, received SSRC '%u' != expected '%u'\n",
6842  instance, rtp, ast_sockaddr_stringify(addr), ssrc, rtp->themssrc);
6843  if (child) {
6844  ao2_unlock(child);
6845  }
6846  continue;
6847  }
6848  ssrc_seen = 1;
6849  }
6850 
6851  if (ssrc_seen && ast_rtp_instance_get_prop(instance, AST_RTP_PROPERTY_NAT)) {
6852  /* Send to whoever sent to us */
6853  if (ast_sockaddr_cmp(&rtp->rtcp->them, addr)) {
6854  ast_sockaddr_copy(&rtp->rtcp->them, addr);
6855  if (ast_debug_rtp_packet_is_allowed) {
6856  ast_debug(0, "(%p) RTCP NAT: Got RTCP from other end. Now sending to address %s\n",
6857  instance, ast_sockaddr_stringify(addr));
6858  }
6859  }
6860  }
6861 
6862  i += RTCP_HEADER_SSRC_LENGTH; /* Advance past header and ssrc */
6863  switch (pt) {
6864  case RTCP_PT_SR:
6865  gettimeofday(&rtp->rtcp->rxlsr, NULL);
6866  rtp->rtcp->themrxlsr = ((ntohl(rtcpheader[i]) & 0x0000ffff) << 16) | ((ntohl(rtcpheader[i + 1]) & 0xffff0000) >> 16);
6867  rtp->rtcp->spc = ntohl(rtcpheader[i + 3]);
6868  rtp->rtcp->soc = ntohl(rtcpheader[i + 4]);
6869 
6870  rtcp_report->type = RTCP_PT_SR;
6871  rtcp_report->sender_information.packet_count = rtp->rtcp->spc;
6872  rtcp_report->sender_information.octet_count = rtp->rtcp->soc;
6873  ntp2timeval((unsigned int)ntohl(rtcpheader[i]),
6874  (unsigned int)ntohl(rtcpheader[i + 1]),
6875  &rtcp_report->sender_information.ntp_timestamp);
6876  rtcp_report->sender_information.rtp_timestamp = ntohl(rtcpheader[i + 2]);
6877  if (rtcp_debug_test_addr(addr)) {
6878  ast_verbose("NTP timestamp: %u.%06u\n",
6879  (unsigned int)rtcp_report->sender_information.ntp_timestamp.tv_sec,
6880  (unsigned int)rtcp_report->sender_information.ntp_timestamp.tv_usec);
6881  ast_verbose("RTP timestamp: %u\n", rtcp_report->sender_information.rtp_timestamp);
6882  ast_verbose("SPC: %u\tSOC: %u\n",
6883  rtcp_report->sender_information.packet_count,
6884  rtcp_report->sender_information.octet_count);
6885  }
6886  i += RTCP_SR_BLOCK_WORD_LENGTH;
6887  /* Intentional fall through */
6888  case RTCP_PT_RR:
6889  if (rtcp_report->type != RTCP_PT_SR) {
6890  rtcp_report->type = RTCP_PT_RR;
6891  }
6892 
6893  if (rc > 0) {
6894  /* Don't handle multiple reception reports (rc > 1) yet */
6895  report_block = ast_calloc(1, sizeof(*report_block));
6896  if (!report_block) {
6897  if (child) {
6898  ao2_unlock(child);
6899  }
6900  return &ast_null_frame;
6901  }
6902  rtcp_report->report_block[0] = report_block;
6903  report_block->source_ssrc = ntohl(rtcpheader[i]);
6904  report_block->lost_count.packets = ntohl(rtcpheader[i + 1]) & 0x00ffffff;
6905  report_block->lost_count.fraction = ((ntohl(rtcpheader[i + 1]) & 0xff000000) >> 24);
6906  report_block->highest_seq_no = ntohl(rtcpheader[i + 2]);
6907  report_block->ia_jitter = ntohl(rtcpheader[i + 3]);
6908  report_block->lsr = ntohl(rtcpheader[i + 4]);
6909  report_block->dlsr = ntohl(rtcpheader[i + 5]);
6910  if (report_block->lsr) {
6911  int skewed = update_rtt_stats(rtp, report_block->lsr, report_block->dlsr);
6912  if (skewed && rtcp_debug_test_addr(addr)) {
6913  struct timeval now;
6914  unsigned int lsr_now, lsw, msw;
6915  gettimeofday(&now, NULL);
6916  timeval2ntp(now, &msw, &lsw);
6917  lsr_now = (((msw & 0xffff) << 16) | ((lsw & 0xffff0000) >> 16));
6918  ast_verbose("Internal RTCP NTP clock skew detected: "
6919  "lsr=%u, now=%u, dlsr=%u (%u:%03ums), "
6920  "diff=%u\n",
6921  report_block->lsr, lsr_now, report_block->dlsr, report_block->dlsr / 65536,
6922  (report_block->dlsr % 65536) * 1000 / 65536,
6923  report_block->dlsr - (lsr_now - report_block->lsr));
6924  }
6925  }
6926  update_jitter_stats(rtp, report_block->ia_jitter);
6927  update_lost_stats(rtp, report_block->lost_count.packets);
6928  /*
6929  * update_reported_mes_stats must be called AFTER
6930  * update_rtt_stats, update_jitter_stats and
6931  * update_lost_stats.
6932  */
6933  update_reported_mes_stats(rtp);
6934 
6935  if (rtcp_debug_test_addr(addr)) {
6936  int rate = ast_rtp_get_rate(rtp->f.subclass.format);
6937 
6938  ast_verbose(" Fraction lost: %d\n", report_block->lost_count.fraction);
6939  ast_verbose(" Packets lost so far: %u\n", report_block->lost_count.packets);
6940  ast_verbose(" Highest sequence number: %u\n", report_block->highest_seq_no & 0x0000ffff);
6941  ast_verbose(" Sequence number cycles: %u\n", report_block->highest_seq_no >> 16);
6942  ast_verbose(" Interarrival jitter (samp): %u\n", report_block->ia_jitter);
6943  ast_verbose(" Interarrival jitter (secs): %.6f\n", ast_samp2sec(report_block->ia_jitter, rate));
6944  ast_verbose(" Last SR(our NTP): %lu.%010lu\n",(unsigned long)(report_block->lsr) >> 16,((unsigned long)(report_block->lsr) << 16) * 4096);
6945  ast_verbose(" DLSR: %4.4f (sec)\n",(double)report_block->dlsr / 65536.0);
6946  ast_verbose(" RTT: %4.4f(sec)\n", rtp->rtcp->rtt);
6947  ast_verbose(" MES: %4.1f\n", rtp->rtcp->reported_mes);
6948  }
6949  }
6950  /* If and when we handle more than one report block, this should occur outside
6951  * this loop.
6952  */
6953 
6954  message_blob = ast_json_pack("{s: s, s: s, s: f, s: f}",
6955  "from", ast_sockaddr_stringify(addr),
6956  "to", transport_rtp->rtcp->local_addr_str,
6957  "rtt", rtp->rtcp->rtt,
6958  "mes", rtp->rtcp->reported_mes);
6960  rtcp_report,
6961  message_blob);
6962  ast_json_unref(message_blob);
6963 
6964  /* Return an AST_FRAME_RTCP frame with the ast_rtp_rtcp_report
6965  * object as a its data */
6966  transport_rtp->f.frametype = AST_FRAME_RTCP;
6967  transport_rtp->f.subclass.integer = pt;
6968  transport_rtp->f.data.ptr = rtp->rtcp->frame_buf + AST_FRIENDLY_OFFSET;
6969  memcpy(transport_rtp->f.data.ptr, rtcp_report, sizeof(struct ast_rtp_rtcp_report));
6970  transport_rtp->f.datalen = sizeof(struct ast_rtp_rtcp_report);
6971  if (rc > 0) {
6972  /* There's always a single report block stored, here */
6973  struct ast_rtp_rtcp_report *rtcp_report2;
6974  report_block = transport_rtp->f.data.ptr + transport_rtp->f.datalen + sizeof(struct ast_rtp_rtcp_report_block *);
6975  memcpy(report_block, rtcp_report->report_block[0], sizeof(struct ast_rtp_rtcp_report_block));
6976  rtcp_report2 = (struct ast_rtp_rtcp_report *)transport_rtp->f.data.ptr;
6977  rtcp_report2->report_block[0] = report_block;
6978  transport_rtp->f.datalen += sizeof(struct ast_rtp_rtcp_report_block);
6979  }
6980  transport_rtp->f.offset = AST_FRIENDLY_OFFSET;
6981  transport_rtp->f.samples = 0;
6982  transport_rtp->f.mallocd = 0;
6983  transport_rtp->f.delivery.tv_sec = 0;
6984  transport_rtp->f.delivery.tv_usec = 0;
6985  transport_rtp->f.src = "RTP";
6986  transport_rtp->f.stream_num = rtp->stream_num;
6987  f = &transport_rtp->f;
6988  break;
6989  case AST_RTP_RTCP_RTPFB:
6990  switch (rc) {
6991  case AST_RTP_RTCP_FMT_NACK:
6992  /* If retransmissions are not enabled ignore this message */
6993  if (!rtp->send_buffer) {
6994  break;
6995  }
6996 
6997  if (rtcp_debug_test_addr(addr)) {
6998  ast_verbose("Received generic RTCP NACK message\n");
6999  }
7000 
7001  ast_rtp_rtcp_handle_nack(instance, rtcpheader, position, length);
7002  break;
7003  default:
7004  break;
7005  }
7006  break;
7007  case RTCP_PT_FUR:
7008  /* Handle RTCP FUR as FIR by setting the format to 4 */
7009  rc = AST_RTP_RTCP_FMT_FIR;
7010  case RTCP_PT_PSFB:
7011  switch (rc) {
7012  case AST_RTP_RTCP_FMT_PLI:
7013  case AST_RTP_RTCP_FMT_FIR:
7014  if (rtcp_debug_test_addr(addr)) {
7015  ast_verbose("Received an RTCP Fast Update Request\n");
7016  }
7017  transport_rtp->f.frametype = AST_FRAME_CONTROL;
7018  transport_rtp->f.subclass.integer = AST_CONTROL_VIDUPDATE;
7019  transport_rtp->f.datalen = 0;
7020  transport_rtp->f.samples = 0;
7021  transport_rtp->f.mallocd = 0;
7022  transport_rtp->f.src = "RTP";
7023  f = &transport_rtp->f;
7024  break;
7025  case AST_RTP_RTCP_FMT_REMB:
7026  /* If REMB support is not enabled ignore this message */
7028  break;
7029  }
7030 
7031  if (rtcp_debug_test_addr(addr)) {
7032  ast_verbose("Received REMB report\n");
7033  }
7034  transport_rtp->f.frametype = AST_FRAME_RTCP;
7035  transport_rtp->f.subclass.integer = pt;
7036  transport_rtp->f.stream_num = rtp->stream_num;
7037  transport_rtp->f.data.ptr = rtp->rtcp->frame_buf + AST_FRIENDLY_OFFSET;
7038  feedback = transport_rtp->f.data.ptr;
7039  feedback->fmt = rc;
7040 
7041  /* We don't actually care about the SSRC information in the feedback message */
7042  first_word = ntohl(rtcpheader[i + 2]);
7043  feedback->remb.br_exp = (first_word >> 18) & ((1 << 6) - 1);
7044  feedback->remb.br_mantissa = first_word & ((1 << 18) - 1);
7045 
7046  transport_rtp->f.datalen = sizeof(struct ast_rtp_rtcp_feedback);
7047  transport_rtp->f.offset = AST_FRIENDLY_OFFSET;
7048  transport_rtp->f.samples = 0;
7049  transport_rtp->f.mallocd = 0;
7050  transport_rtp->f.delivery.tv_sec = 0;
7051  transport_rtp->f.delivery.tv_usec = 0;
7052  transport_rtp->f.src = "RTP";
7053  f = &transport_rtp->f;
7054  break;
7055  default:
7056  break;
7057  }
7058  break;
7059  case RTCP_PT_SDES:
7060  if (rtcp_debug_test_addr(addr)) {
7061  ast_verbose("Received an SDES from %s\n",
7062  ast_sockaddr_stringify(addr));
7063  }
7064 #ifdef TEST_FRAMEWORK
7065  if ((test_engine = ast_rtp_instance_get_test(instance))) {
7066  test_engine->sdes_received = 1;
7067  }
7068 #endif
7069  break;
7070  case RTCP_PT_BYE:
7071  if (rtcp_debug_test_addr(addr)) {
7072  ast_verbose("Received a BYE from %s\n",
7073  ast_sockaddr_stringify(addr));
7074  }
7075  break;
7076  default:
7077  break;
7078  }
7079  position += length;
7080  rtp->rtcp->rtcp_info = 1;
7081 
7082  if (child) {
7083  ao2_unlock(child);
7084  }
7085  }
7086 
7087  return f;
7088 }
static struct ast_rtp_instance * rtp_find_instance_by_media_source_ssrc(struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned int ssrc)
An object that represents data sent during a SR/RR RTCP report.
Definition: rtp_engine.h:361
RTP session description.
#define RTCP_PT_SR
enum strict_rtp_state strict_rtp_state
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
#define AST_RTP_RTCP_FMT_NACK
Definition: rtp_engine.h:333
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define AST_RTP_RTCP_FMT_PLI
Definition: rtp_engine.h:335
struct ast_data_buffer * send_buffer
struct ast_sockaddr them
An object that represents data received in a feedback report.
Definition: rtp_engine.h:388
struct ast_rtp_rtcp_report_block * report_block[0]
Definition: rtp_engine.h:374
static struct ast_rtp_instance * rtp_find_instance_by_packet_source_ssrc(struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned int ssrc)
A report block within a SR/RR report.
Definition: rtp_engine.h:346
unsigned int fmt
Definition: rtp_engine.h:389
unsigned int soc
struct ast_rtp_rtcp_feedback_remb remb
Definition: rtp_engine.h:391
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
struct stasis_message_type * ast_rtp_rtcp_received_type(void)
Message type for an RTCP message received from some external source.
struct ast_frame_subclass subclass
const char * ast_rtp_instance_get_channel_id(struct ast_rtp_instance *instance)
Get the unique ID of the channel that owns this RTP instance.
Definition: rtp_engine.c:570
struct timeval rxlsr
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
const char * src
unsigned int spc
#define AST_RTP_RTCP_RTPFB
Definition: rtp_engine.h:327
#define ast_debug(level,...)
Log a DEBUG message.
unsigned int themssrc_valid
void ast_rtp_publish_rtcp_message(struct ast_rtp_instance *rtp, struct stasis_message_type *message_type, struct ast_rtp_rtcp_report *report, struct ast_json *blob)
Publish an RTCP message to Stasis Message Bus API.
Definition: rtp_engine.c:3638
struct ast_rtp_rtcp_report * ast_rtp_rtcp_report_alloc(unsigned int report_blocks)
Allocate an ao2 ref counted instance of ast_rtp_rtcp_report.
Definition: rtp_engine.c:3627
#define RTCP_PT_RR
double ast_samp2sec(unsigned int _nsamp, unsigned int _rate)
Returns the duration in seconds of _nsamp samples at rate _rate.
Definition: time.h:316
unsigned int themssrc
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
unsigned int themrxlsr
static int ast_rtp_rtcp_handle_nack(struct ast_rtp_instance *instance, unsigned int *nackdata, unsigned int position, unsigned int length)
#define AST_RTP_RTCP_FMT_FIR
Definition: rtp_engine.h:337
union ast_frame::@224 data
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
#define RTCP_PT_FUR
struct ast_frame f
double reported_mes
struct timeval delivery
int ast_rtp_get_rate(const struct ast_format *format)
Retrieve the sample rate of a format according to RTP specifications.
Definition: rtp_engine.c:4224
struct ast_frame ast_null_frame
Definition: main/frame.c:79
int ast_rtp_instance_get_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property)
Get the value of an RTP instance property.
Definition: rtp_engine.c:738
Data structure associated with a single frame of data.
Abstract JSON element (object, array, string, int, ...).
#define RTCP_PT_SDES
enum ast_frame_type frametype
struct ast_format * format
#define ast_debug_rtcp(sublevel,...)
Log debug level RTCP information.
Definition: rtp_engine.h:3034
#define RTCP_PT_BYE
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define RTCP_PT_PSFB
#define AST_RTP_RTCP_FMT_REMB
Definition: rtp_engine.h:339
static struct ast_frame* ast_rtcp_read ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 7091 of file res_rtp_asterisk.c.

References AST_CONTROL_SRCCHANGE, ast_debug_stun, AST_FRAME_CONTROL, AST_FRIENDLY_OFFSET, ast_null_frame, ast_rtcp_interpret(), ast_rtp_instance_get_data(), ast_rtp_instance_get_srtp(), ast_sockaddr_copy(), ast_sockaddr_from_sin, ast_sockaddr_ipv4_mapped(), ast_sockaddr_is_ipv4(), ast_sockaddr_stringify(), ast_sockaddr_to_sin, ast_stun_handle_packet(), ast_rtp::f, ast_frame::frametype, ast_frame_subclass::integer, rtcp_recvfrom(), ast_rtcp::s, ast_frame::subclass, and ast_rtcp::them.

Referenced by ast_rtp_read().

7092 {
7093  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
7094  struct ast_srtp *srtp = ast_rtp_instance_get_srtp(instance, 1);
7095  struct ast_sockaddr addr;
7096  unsigned char rtcpdata[8192 + AST_FRIENDLY_OFFSET];
7097  unsigned char *read_area = rtcpdata + AST_FRIENDLY_OFFSET;
7098  size_t read_area_size = sizeof(rtcpdata) - AST_FRIENDLY_OFFSET;
7099  int res;
7100 
7101  /* Read in RTCP data from the socket */
7102  if ((res = rtcp_recvfrom(instance, read_area, read_area_size,
7103  0, &addr)) < 0) {
7104  if (res == RTP_DTLS_ESTABLISHED) {
7105  rtp->f.frametype = AST_FRAME_CONTROL;
7107  return &rtp->f;
7108  }
7109 
7110  ast_assert(errno != EBADF);
7111  if (errno != EAGAIN) {
7112  ast_log(LOG_WARNING, "RTCP Read error: %s. Hanging up.\n",
7113  (errno) ? strerror(errno) : "Unspecified");
7114  return NULL;
7115  }
7116  return &ast_null_frame;
7117  }
7118 
7119  /* If this was handled by the ICE session don't do anything further */
7120  if (!res) {
7121  return &ast_null_frame;
7122  }
7123 
7124  if (!*read_area) {
7125  struct sockaddr_in addr_tmp;
7126  struct ast_sockaddr addr_v4;
7127 
7128  if (ast_sockaddr_is_ipv4(&addr)) {
7129  ast_sockaddr_to_sin(&addr, &addr_tmp);
7130  } else if (ast_sockaddr_ipv4_mapped(&addr, &addr_v4)) {
7131  ast_debug_stun(2, "(%p) STUN using IPv6 mapped address %s\n",
7132  instance, ast_sockaddr_stringify(&addr));
7133  ast_sockaddr_to_sin(&addr_v4, &addr_tmp);
7134  } else {
7135  ast_debug_stun(2, "(%p) STUN cannot do for non IPv4 address %s\n",
7136  instance, ast_sockaddr_stringify(&addr));
7137  return &ast_null_frame;
7138  }
7139  if ((ast_stun_handle_packet(rtp->rtcp->s, &addr_tmp, read_area, res, NULL, NULL) == AST_STUN_ACCEPT)) {
7140  ast_sockaddr_from_sin(&addr, &addr_tmp);
7141  ast_sockaddr_copy(&rtp->rtcp->them, &addr);
7142  }
7143  return &ast_null_frame;
7144  }
7145 
7146  return ast_rtcp_interpret(instance, srtp, read_area, res, &addr);
7147 }
RTP session description.
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
int ast_sockaddr_ipv4_mapped(const struct ast_sockaddr *addr, struct ast_sockaddr *ast_mapped)
Convert an IPv4-mapped IPv6 address into an IPv4 address.
Definition: netsock2.c:37
struct ast_sockaddr them
struct ast_srtp * ast_rtp_instance_get_srtp(struct ast_rtp_instance *instance, int rtcp)
Obtain the SRTP instance associated with an RTP instance.
Definition: rtp_engine.c:2911
int ast_stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *data, size_t len, stun_cb_f *stun_cb, void *arg)
handle an incoming STUN message.
Definition: stun.c:293
Socket address structure.
Definition: netsock2.h:97
static int rtcp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
struct ast_frame_subclass subclass
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:778
static struct ast_frame * ast_rtcp_interpret(struct ast_rtp_instance *instance, struct ast_srtp *srtp, const unsigned char *rtcpdata, size_t size, struct ast_sockaddr *addr)
#define ast_debug_stun(sublevel,...)
Log debug level STUN information.
Definition: stun.h:54
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
struct ast_frame f
struct ast_frame ast_null_frame
Definition: main/frame.c:79
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:497
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:765
enum ast_frame_type frametype
static int ast_rtcp_write ( const void *  data)
static

Write a RTCP packet to the far end.

Note
Decide if we are going to send an SR (with Reception Block) or RR RR is sent if we have not sent any rtp packets in the previous interval

Scheduler callback

Definition at line 5002 of file res_rtp_asterisk.c.

References ao2_ref, ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address, ast_rtp_rtcp_report_alloc(), ast_sockaddr_copy(), ast_sockaddr_stringify(), ast_rtp::bundled, cleanup(), ast_rtp::ice, RAII_VAR, rtcp_sendto(), ast_rtcp::schedid, ast_rtcp::them, and ast_rtp::themssrc_valid.

Referenced by rtp_raw_write().

5003 {
5004  struct ast_rtp_instance *instance = (struct ast_rtp_instance *) data;
5005  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
5006  int res;
5007  int sr = 0;
5008  int packet_len = 0;
5009  int ice;
5010  struct ast_sockaddr remote_address = { { 0, } };
5011  unsigned char *rtcpheader;
5012  unsigned char bdata[AST_UUID_STR_LEN + 128] = ""; /* More than enough */
5013  RAII_VAR(struct ast_rtp_rtcp_report *, rtcp_report, NULL, ao2_cleanup);
5014 
5015  if (!rtp || !rtp->rtcp || rtp->rtcp->schedid == -1) {
5016  ao2_ref(instance, -1);
5017  return 0;
5018  }
5019 
5020  ao2_lock(instance);
5021  rtcpheader = bdata;
5022  rtcp_report = ast_rtp_rtcp_report_alloc(rtp->themssrc_valid ? 1 : 0);
5023  res = ast_rtcp_generate_compound_prefix(instance, rtcpheader, rtcp_report, &sr);
5024 
5025  if (res == 0 || res == 1) {
5026  goto cleanup;
5027  }
5028 
5029  packet_len += res;
5030 
5031  if (rtp->bundled) {
5032  ast_rtp_instance_get_remote_address(instance, &remote_address);
5033  } else {
5034  ast_sockaddr_copy(&remote_address, &rtp->rtcp->them);
5035  }
5036 
5037  res = rtcp_sendto(instance, (unsigned int *)rtcpheader, packet_len, 0, &remote_address, &ice);
5038  if (res < 0) {
5039  ast_log(LOG_ERROR, "RTCP %s transmission error to %s, rtcp halted %s\n",
5040  sr ? "SR" : "RR",
5041  ast_sockaddr_stringify(&rtp->rtcp->them),
5042  strerror(errno));
5043  res = 0;
5044  } else {
5045  ast_rtcp_calculate_sr_rr_statistics(instance, rtcp_report, remote_address, ice, sr);
5046  }
5047 
5048 cleanup:
5049  ao2_unlock(instance);
5050 
5051  if (!res) {
5052  /*
5053  * Not being rescheduled.
5054  */
5055  rtp->rtcp->schedid = -1;
5056  ao2_ref(instance, -1);
5057  }
5058 
5059  return res;
5060 }
An object that represents data sent during a SR/RR RTCP report.
Definition: rtp_engine.h:361
RTP session description.
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
struct ast_sockaddr them
struct ast_rtp_instance * bundled
Socket address structure.
Definition: netsock2.h:97
static void cleanup(void)
Clean up any old apps that we don't need any more.
Definition: res_stasis.c:327
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ice_wrap * ice
unsigned int themssrc_valid
struct ast_rtp_rtcp_report * ast_rtp_rtcp_report_alloc(unsigned int report_blocks)
Allocate an ao2 ref counted instance of ast_rtp_rtcp_report.
Definition: rtp_engine.c:3627
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
static int rtcp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int *ice)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1245
static int ast_rtp_bundle ( struct ast_rtp_instance child,
struct ast_rtp_instance parent 
)
static
Precondition
child is locked

Definition at line 9460 of file res_rtp_asterisk.c.

References ao2_bump, ao2_ref, AST_RTP_DTLS_CONNECTION_EXISTING, ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address, ast_rtp_instance_set_remote_address, AST_VECTOR_APPEND, AST_VECTOR_ELEM_CLEANUP_NOOP, AST_VECTOR_REMOVE_CMP_UNORDERED, ast_rtp::bundled, rtp_ssrc_mapping::instance, rtp_ssrc_mapping::ssrc, ast_rtp::ssrc, ast_rtp::ssrc_mapping, SSRC_MAPPING_ELEM_CMP, rtp_ssrc_mapping::ssrc_valid, ast_rtp::themssrc, and ast_rtp::themssrc_valid.

9461 {
9462  struct ast_rtp *child_rtp = ast_rtp_instance_get_data(child);
9463  struct ast_rtp *parent_rtp;
9464  struct rtp_ssrc_mapping mapping;
9465  struct ast_sockaddr them = { { 0, } };
9466 
9467  if (child_rtp->bundled == parent) {
9468  return 0;
9469  }
9470 
9471  /* If this instance was already bundled then remove the SSRC mapping */
9472  if (child_rtp->bundled) {
9473  struct ast_rtp *bundled_rtp;
9474 
9475  ao2_unlock(child);
9476 
9477  /* The child lock can't be held while accessing the parent */
9478  ao2_lock(child_rtp->bundled);
9479  bundled_rtp = ast_rtp_instance_get_data(child_rtp->bundled);
9481  ao2_unlock(child_rtp->bundled);
9482 
9483  ao2_lock(child);
9484  ao2_ref(child_rtp->bundled, -1);
9485  child_rtp->bundled = NULL;
9486  }
9487 
9488  if (!parent) {
9489  /* We transitioned away from bundle so we need our own transport resources once again */
9490  rtp_allocate_transport(child, child_rtp);
9491  return 0;
9492  }
9493 
9494  parent_rtp = ast_rtp_instance_get_data(parent);
9495 
9496  /* We no longer need any transport related resources as we will use our parent RTP instance instead */
9497  rtp_deallocate_transport(child, child_rtp);
9498 
9499  /* Children maintain a reference to the parent to guarantee that the transport doesn't go away on them */
9500  child_rtp->bundled = ao2_bump(parent);
9501 
9502  mapping.ssrc = child_rtp->themssrc;
9503  mapping.ssrc_valid = child_rtp->themssrc_valid;
9504  mapping.instance = child;
9505 
9506  ao2_unlock(child);
9507 
9508  ao2_lock(parent);
9509 
9510  AST_VECTOR_APPEND(&parent_rtp->ssrc_mapping, mapping);
9511 
9512 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
9513  /* If DTLS-SRTP is already in use then add the local SSRC to it, otherwise it will get added once DTLS
9514  * negotiation has been completed.
9515  */
9516  if (parent_rtp->dtls.connection == AST_RTP_DTLS_CONNECTION_EXISTING) {
9517  dtls_srtp_add_local_ssrc(parent_rtp, parent, 0, child_rtp->ssrc, 0);
9518  }
9519 #endif
9520 
9521  /* Bundle requires that RTCP-MUX be in use so only the main remote address needs to match */
9522  ast_rtp_instance_get_remote_address(parent, &them);
9523 
9524  ao2_unlock(parent);
9525 
9526  ao2_lock(child);
9527 
9529 
9530  return 0;
9531 }
RTP session description.
Structure used for mapping an incoming SSRC to an RTP instance.
#define AST_VECTOR_REMOVE_CMP_UNORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison.
Definition: vector.h:488
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
struct ast_rtp_instance * bundled
#define SSRC_MAPPING_ELEM_CMP(elem, value)
SSRC mapping comparator for AST_VECTOR_REMOVE_CMP_UNORDERED()
Socket address structure.
Definition: netsock2.h:97
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
unsigned int ssrc
#define AST_VECTOR_ELEM_CLEANUP_NOOP(elem)
Vector element cleanup that does nothing.
Definition: vector.h:571
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ast_rtp::@480 ssrc_mapping
unsigned int themssrc_valid
unsigned int themssrc
#define ast_rtp_instance_set_remote_address(instance, address)
Set the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1133
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1245
static void ast_rtp_change_source ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 4539 of file res_rtp_asterisk.c.

References ast_debug_rtp, ast_rtp_instance_get_data(), ast_rtp_instance_get_srtp(), ast_rtp::expectedrxseqno, and ast_rtp::ssrc.

4540 {
4541  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4542  struct ast_srtp *srtp = ast_rtp_instance_get_srtp(instance, 0);
4543  struct ast_srtp *rtcp_srtp = ast_rtp_instance_get_srtp(instance, 1);
4544  unsigned int ssrc = ast_random();
4545 
4546  if (rtp->lastts) {
4547  /* We simply set this bit so that the next packet sent will have the marker bit turned on */
4548  ast_set_flag(rtp, FLAG_NEED_MARKER_BIT);
4549  }
4550 
4551  ast_debug_rtp(3, "(%p) RTP changing ssrc from %u to %u due to a source change\n",
4552  instance, rtp->ssrc, ssrc);
4553 
4554  if (srtp) {
4555  ast_debug_rtp(3, "(%p) RTP changing ssrc for SRTP from %u to %u\n",
4556  instance, rtp->ssrc, ssrc);
4557  res_srtp->change_source(srtp, rtp->ssrc, ssrc);
4558  if (rtcp_srtp != srtp) {
4559  res_srtp->change_source(rtcp_srtp, rtp->ssrc, ssrc);
4560  }
4561  }
4562 
4563  rtp->ssrc = ssrc;
4564 
4565  /* Since the source is changing, we don't know what sequence number to expect next */
4566  rtp->expectedrxseqno = -1;
4567 
4568  return;
4569 }
RTP session description.
struct ast_srtp * ast_rtp_instance_get_srtp(struct ast_rtp_instance *instance, int rtcp)
Obtain the SRTP instance associated with an RTP instance.
Definition: rtp_engine.c:2911
unsigned int ssrc
int expectedrxseqno
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
#define ast_debug_rtp(sublevel,...)
Log debug level RTP information.
Definition: rtp_engine.h:3017
static int ast_rtp_destroy ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 4195 of file res_rtp_asterisk.c.

References ao2_ref, ast_data_buffer_free(), ast_rtp_instance_get_data(), AST_SCHED_DEL, AST_VECTOR_ELEM_CLEANUP_NOOP, AST_VECTOR_FREE, AST_VECTOR_REMOVE_CMP_UNORDERED, ast_rtp::bundled, ast_rtp::f, ast_frame_subclass::format, ast_rtp::missing_seqno, ast_rtp::owner, rtp_transport_wide_cc_statistics::packet_statistics, ast_rtp::recv_buffer, rtp_red::schedid, ast_rtp::send_buffer, ast_rtp::ssrc_mapping, SSRC_MAPPING_ELEM_CMP, ast_frame::subclass, and ast_rtp::transport_wide_cc.

4196 {
4197  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4198 
4199  if (rtp->bundled) {
4200  struct ast_rtp *bundled_rtp;
4201 
4202  /* We can't hold our instance lock while removing ourselves from the parent */
4203  ao2_unlock(instance);
4204 
4205  ao2_lock(rtp->bundled);
4206  bundled_rtp = ast_rtp_instance_get_data(rtp->bundled);
4208  ao2_unlock(rtp->bundled);
4209 
4210  ao2_lock(instance);
4211  ao2_ref(rtp->bundled, -1);
4212  }
4213 
4214  rtp_deallocate_transport(instance, rtp);
4215 
4216  /* Destroy the smoother that was smoothing out audio if present */
4217  if (rtp->smoother) {
4218  ast_smoother_free(rtp->smoother);
4219  }
4220 
4221  /* Destroy RTCP if it was being used */
4222  if (rtp->rtcp) {
4223  /*
4224  * It is not possible for there to be an active RTCP scheduler
4225  * entry at this point since it holds a reference to the
4226  * RTP instance while it's active.
4227  */
4228  ast_free(rtp->rtcp->local_addr_str);
4229  ast_free(rtp->rtcp);
4230  }
4231 
4232  /* Destroy RED if it was being used */
4233  if (rtp->red) {
4234  ao2_unlock(instance);
4235  AST_SCHED_DEL(rtp->sched, rtp->red->schedid);
4236  ao2_lock(instance);
4237  ast_free(rtp->red);
4238  rtp->red = NULL;
4239  }
4240 
4241  /* Destroy the send buffer if it was being used */
4242  if (rtp->send_buffer) {
4244  }
4245 
4246  /* Destroy the recv buffer if it was being used */
4247  if (rtp->recv_buffer) {
4249  }
4250 
4252 
4253  ao2_cleanup(rtp->lasttxformat);
4254  ao2_cleanup(rtp->lastrxformat);
4255  ao2_cleanup(rtp->f.subclass.format);
4258 
4259  /* Finally destroy ourselves */
4260  rtp->owner = NULL;
4261  ast_free(rtp);
4262 
4263  return 0;
4264 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
RTP session description.
struct rtp_transport_wide_cc_statistics::@478 packet_statistics
#define AST_VECTOR_REMOVE_CMP_UNORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison.
Definition: vector.h:488
struct ast_rtp_instance * owner
The RTP instance owning us (used for debugging purposes) We don't hold a reference to the instance be...
struct ast_data_buffer * send_buffer
struct ast_rtp_instance * bundled
#define SSRC_MAPPING_ELEM_CMP(elem, value)
SSRC mapping comparator for AST_VECTOR_REMOVE_CMP_UNORDERED()
struct rtp_transport_wide_cc_statistics transport_wide_cc
struct ast_data_buffer * recv_buffer
struct ast_frame_subclass subclass
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition: sched.h:46
#define AST_VECTOR_ELEM_CLEANUP_NOOP(elem)
Vector element cleanup that does nothing.
Definition: vector.h:571
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ast_rtp::@480 ssrc_mapping
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
struct ast_rtp::@479 missing_seqno
struct ast_frame f
struct ast_format * format
void ast_data_buffer_free(struct ast_data_buffer *buffer)
Free a data buffer (and all held data payloads)
Definition: data_buffer.c:338
static int ast_rtp_dtmf_begin ( struct ast_rtp_instance instance,
char  digit 
)
static
Precondition
instance is locked

Definition at line 4282 of file res_rtp_asterisk.c.

References ast_debug, ast_format_get_sample_rate(), ast_format_none, ast_rtp_codecs_get_preferred_format(), ast_rtp_codecs_payload_code_tx(), ast_rtp_codecs_payload_code_tx_sample_rate(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_test_suite_event_notify, ast_tv(), ast_tvadd(), ast_tvnow(), ast_rtp::dtmf_samplerate_ms, RAII_VAR, rtp_sendto(), ast_rtp::send_digit, ast_rtp::sending_digit, ast_rtp::seqno, and ast_rtp::ssrc.

4283 {
4284  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4285  struct ast_sockaddr remote_address = { {0,} };
4286  int hdrlen = 12, res = 0, i = 0, payload = 101;
4287  unsigned int sample_rate = 8000;
4288  char data[256];
4289  unsigned int *rtpheader = (unsigned int*)data;
4290  RAII_VAR(struct ast_format *, payload_format, NULL, ao2_cleanup);
4291 
4292  ast_rtp_instance_get_remote_address(instance, &remote_address);
4293 
4294  /* If we have no remote address information bail out now */
4295  if (ast_sockaddr_isnull(&remote_address)) {
4296  return -1;
4297  }
4298 
4299  /* Convert given digit into what we want to transmit */
4300  if ((digit <= '9') && (digit >= '0')) {
4301  digit -= '0';
4302  } else if (digit == '*') {
4303  digit = 10;
4304  } else if (digit == '#') {
4305  digit = 11;
4306  } else if ((digit >= 'A') && (digit <= 'D')) {
4307  digit = digit - 'A' + 12;
4308  } else if ((digit >= 'a') && (digit <= 'd')) {
4309  digit = digit - 'a' + 12;
4310  } else {
4311  ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
4312  return -1;
4313  }
4314 
4315  if (rtp->lasttxformat == ast_format_none) {
4316  /* No audio frames have been written yet so we have to lookup both the preferred payload type and bitrate. */
4318  if (payload_format) {
4319  /* If we have a preferred type, use that. Otherwise default to 8K. */
4320  sample_rate = ast_format_get_sample_rate(payload_format);
4321  }
4322  } else {
4323  sample_rate = ast_format_get_sample_rate(rtp->lasttxformat);
4324  }
4325 
4326  /* Grab the matching DTMF type payload */
4327  payload = ast_rtp_codecs_payload_code_tx_sample_rate(ast_rtp_instance_get_codecs(instance), 0, NULL, AST_RTP_DTMF, sample_rate);
4328 
4329  /* If this returns -1, we are using a codec with a sample rate that does not have a matching RFC 2833/4733
4330  offer. The offer may have included a default-rate one that doesn't match the codec rate, so try to use that. */
4331  if (payload == -1) {
4332  sample_rate = DEFAULT_DTMF_SAMPLE_RATE_MS;
4334  }
4335  /* No default-rate offer either, trying to send a digit outside of what was negotiated for. */
4336  if (payload == -1) {
4337  return -1;
4338  }
4339 
4340  ast_test_suite_event_notify("DTMF_BEGIN", "Digit: %d\r\nPayload: %d\r\nRate: %d\r\n", digit, payload, sample_rate);
4341  ast_debug(1, "Sending digit '%d' at rate %d with payload %d\n", digit, sample_rate, payload);
4342 
4343  rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
4344  rtp->send_duration = 160;
4345  rtp->dtmf_samplerate_ms = (sample_rate / 1000);
4346  rtp->lastts += calc_txstamp(rtp, NULL) * rtp->dtmf_samplerate_ms;
4347  rtp->lastdigitts = rtp->lastts + rtp->send_duration;
4348 
4349  /* Create the actual packet that we will be sending */
4350  rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno));
4351  rtpheader[1] = htonl(rtp->lastdigitts);
4352  rtpheader[2] = htonl(rtp->ssrc);
4353 
4354  /* Actually send the packet */
4355  for (i = 0; i < 2; i++) {
4356  int ice;
4357 
4358  rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (rtp->send_duration));
4359  res = rtp_sendto(instance, (void *) rtpheader, hdrlen + 4, 0, &remote_address, &ice);
4360  if (res < 0) {
4361  ast_log(LOG_ERROR, "RTP Transmission error to %s: %s\n",
4362  ast_sockaddr_stringify(&remote_address),
4363  strerror(errno));
4364  }
4365  if (rtp_debug_test_addr(&remote_address)) {
4366  ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6d, ts %-6.6u, len %-6.6d)\n",
4367  ast_sockaddr_stringify(&remote_address),
4368  ice ? " (via ICE)" : "",
4369  payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
4370  }
4371  rtp->seqno++;
4372  rtp->send_duration += 160;
4373  rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno));
4374  }
4375 
4376  /* Record that we are in the process of sending a digit and information needed to continue doing so */
4377  rtp->sending_digit = 1;
4378  rtp->send_digit = digit;
4379  rtp->send_payload = payload;
4380 
4381  return 0;
4382 }
RTP session description.
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:749
Definition of a media format.
Definition: format.c:43
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
Socket address structure.
Definition: netsock2.h:97
struct ast_format * ast_format_none
Built-in "null" format.
Definition: format_cache.c:246
int ast_rtp_codecs_payload_code_tx(struct ast_rtp_codecs *codecs, int asterisk_format, const struct ast_format *format, int code)
Retrieve a tx mapped payload type based on whether it is an Asterisk format and the code...
Definition: rtp_engine.c:2094
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
unsigned int ssrc
unsigned int dtmf_samplerate_ms
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:189
struct ast_format * ast_rtp_codecs_get_preferred_format(struct ast_rtp_codecs *codecs)
Retrieve rx preferred format.
Definition: rtp_engine.c:1557
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
int ast_rtp_codecs_payload_code_tx_sample_rate(struct ast_rtp_codecs *codecs, int asterisk_format, const struct ast_format *format, int code, unsigned int sample_rate)
Retrieve a tx mapped payload type based on whether it is an Asterisk format and the code...
Definition: rtp_engine.c:2043
static int rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int *ice)
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:235
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
unsigned short seqno
#define AST_RTP_DTMF
Definition: rtp_engine.h:294
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1245
char sending_digit
static int ast_rtp_dtmf_compatible ( struct ast_channel chan0,
struct ast_rtp_instance instance0,
struct ast_channel chan1,
struct ast_rtp_instance instance1 
)
static
Precondition
Neither instance0 nor instance1 are locked

Definition at line 9243 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_prop(), and AST_RTP_PROPERTY_DTMF.

9244 {
9245  /* If both sides are not using the same method of DTMF transmission
9246  * (ie: one is RFC2833, other is INFO... then we can not do direct media.
9247  * --------------------------------------------------
9248  * | DTMF Mode | HAS_DTMF | Accepts Begin Frames |
9249  * |-----------|------------|-----------------------|
9250  * | Inband | False | True |
9251  * | RFC2833 | True | True |
9252  * | SIP INFO | False | False |
9253  * --------------------------------------------------
9254  */
9256  (!ast_channel_tech(chan0)->send_digit_begin != !ast_channel_tech(chan1)->send_digit_begin)) ? 0 : 1);
9257 }
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Definition: channel.h:628
int ast_rtp_instance_get_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property)
Get the value of an RTP instance property.
Definition: rtp_engine.c:738
static int ast_rtp_dtmf_continuation ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 4385 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_rtp::dtmf_samplerate_ms, rtp_sendto(), ast_rtp::send_digit, ast_rtp::seqno, and ast_rtp::ssrc.

4386 {
4387  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4388  struct ast_sockaddr remote_address = { {0,} };
4389  int hdrlen = 12, res = 0;
4390  char data[256];
4391  unsigned int *rtpheader = (unsigned int*)data;
4392  int ice;
4393 
4394  ast_rtp_instance_get_remote_address(instance, &remote_address);
4395 
4396  /* Make sure we know where the other side is so we can send them the packet */
4397  if (ast_sockaddr_isnull(&remote_address)) {
4398  return -1;
4399  }
4400 
4401  /* Actually create the packet we will be sending */
4402  rtpheader[0] = htonl((2 << 30) | (rtp->send_payload << 16) | (rtp->seqno));
4403  rtpheader[1] = htonl(rtp->lastdigitts);
4404  rtpheader[2] = htonl(rtp->ssrc);
4405  rtpheader[3] = htonl((rtp->send_digit << 24) | (0xa << 16) | (rtp->send_duration));
4406 
4407  /* Boom, send it on out */
4408  res = rtp_sendto(instance, (void *) rtpheader, hdrlen + 4, 0, &remote_address, &ice);
4409  if (res < 0) {
4410  ast_log(LOG_ERROR, "RTP Transmission error to %s: %s\n",
4411  ast_sockaddr_stringify(&remote_address),
4412  strerror(errno));
4413  }
4414 
4415  if (rtp_debug_test_addr(&remote_address)) {
4416  ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6d, ts %-6.6u, len %-6.6d)\n",
4417  ast_sockaddr_stringify(&remote_address),
4418  ice ? " (via ICE)" : "",
4419  rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
4420  }
4421 
4422  /* And now we increment some values for the next time we swing by */
4423  rtp->seqno++;
4424  rtp->send_duration += 160;
4425  rtp->lastts += calc_txstamp(rtp, NULL) * rtp->dtmf_samplerate_ms;
4426 
4427  return 0;
4428 }
RTP session description.
Socket address structure.
Definition: netsock2.h:97
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
unsigned int ssrc
unsigned int dtmf_samplerate_ms
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
static int rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int *ice)
unsigned short seqno
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1245
static int ast_rtp_dtmf_end ( struct ast_rtp_instance instance,
char  digit 
)
static
Precondition
instance is locked

Definition at line 4521 of file res_rtp_asterisk.c.

References ast_rtp_dtmf_end_with_duration().

4522 {
4523  return ast_rtp_dtmf_end_with_duration(instance, digit, 0);
4524 }
static int ast_rtp_dtmf_end_with_duration(struct ast_rtp_instance *instance, char digit, unsigned int duration)
static int ast_rtp_dtmf_end_with_duration ( struct ast_rtp_instance instance,
char  digit,
unsigned int  duration 
)
static
Precondition
instance is locked

Definition at line 4431 of file res_rtp_asterisk.c.

References ast_debug_rtp, ast_rtp_get_rate(), ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_tv(), ast_tvadd(), ast_tvnow(), cleanup(), ast_rtp::dtmf_samplerate_ms, ast_rtp::expectedseqno, ast_rtp::f, ast_frame_subclass::format, rtp_sendto(), ast_rtp::send_digit, ast_rtp::sending_digit, ast_rtp::seqno, ast_rtp::ssrc, and ast_frame::subclass.

Referenced by ast_rtp_dtmf_end().

4432 {
4433  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4434  struct ast_sockaddr remote_address = { {0,} };
4435  int hdrlen = 12, res = -1, i = 0;
4436  char data[256];
4437  unsigned int *rtpheader = (unsigned int*)data;
4438  unsigned int measured_samples;
4439 
4440  ast_rtp_instance_get_remote_address(instance, &remote_address);
4441 
4442  /* Make sure we know where the remote side is so we can send them the packet we construct */
4443  if (ast_sockaddr_isnull(&remote_address)) {
4444  goto cleanup;
4445  }
4446 
4447  /* Convert the given digit to the one we are going to send */
4448  if ((digit <= '9') && (digit >= '0')) {
4449  digit -= '0';
4450  } else if (digit == '*') {
4451  digit = 10;
4452  } else if (digit == '#') {
4453  digit = 11;
4454  } else if ((digit >= 'A') && (digit <= 'D')) {
4455  digit = digit - 'A' + 12;
4456  } else if ((digit >= 'a') && (digit <= 'd')) {
4457  digit = digit - 'a' + 12;
4458  } else {
4459  ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
4460  goto cleanup;
4461  }
4462 
4463  rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
4464 
4465  if (duration > 0 && (measured_samples = duration * ast_rtp_get_rate(rtp->f.subclass.format) / 1000) > rtp->send_duration) {
4466  ast_debug_rtp(2, "(%p) RTP adjusting final end duration from %d to %u\n",
4467  instance, rtp->send_duration, measured_samples);
4468  rtp->send_duration = measured_samples;
4469  }
4470 
4471  /* Construct the packet we are going to send */
4472  rtpheader[1] = htonl(rtp->lastdigitts);
4473  rtpheader[2] = htonl(rtp->ssrc);
4474  rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (rtp->send_duration));
4475  rtpheader[3] |= htonl((1 << 23));
4476 
4477  /* Send it 3 times, that's the magical number */
4478  for (i = 0; i < 3; i++) {
4479  int ice;
4480 
4481  rtpheader[0] = htonl((2 << 30) | (rtp->send_payload << 16) | (rtp->seqno));
4482 
4483  res = rtp_sendto(instance, (void *) rtpheader, hdrlen + 4, 0, &remote_address, &ice);
4484 
4485  if (res < 0) {
4486  ast_log(LOG_ERROR, "RTP Transmission error to %s: %s\n",
4487  ast_sockaddr_stringify(&remote_address),
4488  strerror(errno));
4489  }
4490 
4491  if (rtp_debug_test_addr(&remote_address)) {
4492  ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6d, ts %-6.6u, len %-6.6d)\n",
4493  ast_sockaddr_stringify(&remote_address),
4494  ice ? " (via ICE)" : "",
4495  rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
4496  }
4497 
4498  rtp->seqno++;
4499  }
4500  res = 0;
4501 
4502  /* Oh and we can't forget to turn off the stuff that says we are sending DTMF */
4503  rtp->lastts += calc_txstamp(rtp, NULL) * rtp->dtmf_samplerate_ms;
4504 
4505  /* Reset the smoother as the delivery time stored in it is now out of date */
4506  if (rtp->smoother) {
4507  ast_smoother_free(rtp->smoother);
4508  rtp->smoother = NULL;
4509  }
4510 cleanup:
4511  rtp->sending_digit = 0;
4512  rtp->send_digit = 0;
4513 
4514  /* Re-Learn expected seqno */
4515  rtp->expectedseqno = -1;
4516 
4517  return res;
4518 }
RTP session description.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
Socket address structure.
Definition: netsock2.h:97
struct ast_frame_subclass subclass
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
unsigned int ssrc
static void cleanup(void)
Clean up any old apps that we don't need any more.
Definition: res_stasis.c:327
unsigned int dtmf_samplerate_ms
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
struct ast_frame f
int ast_rtp_get_rate(const struct ast_format *format)
Retrieve the sample rate of a format according to RTP specifications.
Definition: rtp_engine.c:4224
#define ast_debug_rtp(sublevel,...)
Log debug level RTP information.
Definition: rtp_engine.h:3017
static int rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int *ice)
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:235
unsigned short seqno
struct ast_format * format
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1245
char sending_digit
static enum ast_rtp_dtmf_mode ast_rtp_dtmf_mode_get ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 4275 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), and ast_rtp::dtmfmode.

4276 {
4277  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4278  return rtp->dtmfmode;
4279 }
RTP session description.
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
enum ast_rtp_dtmf_mode dtmfmode
static int ast_rtp_dtmf_mode_set ( struct ast_rtp_instance instance,
enum ast_rtp_dtmf_mode  dtmf_mode 
)
static
Precondition
instance is locked

Definition at line 4267 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), and ast_rtp::dtmfmode.

4268 {
4269  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4270  rtp->dtmfmode = dtmf_mode;
4271  return 0;
4272 }
RTP session description.
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
enum ast_rtp_dtmf_mode dtmfmode
static int ast_rtp_fd ( struct ast_rtp_instance instance,
int  rtcp 
)
static
Precondition
instance is locked

Definition at line 8996 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), and ast_rtcp::s.

8997 {
8998  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
8999 
9000  return rtcp ? (rtp->rtcp ? rtp->rtcp->s : -1) : rtp->s;
9001 }
RTP session description.
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
static const char * ast_rtp_get_cname ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 9395 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), and ast_rtp::cname.

9396 {
9397  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
9398 
9399  return rtp->cname;
9400 }
RTP session description.
char cname[AST_UUID_STR_LEN]
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
static unsigned int ast_rtp_get_ssrc ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 9387 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), and ast_rtp::ssrc.

Referenced by __rtp_find_instance_by_ssrc().

9388 {
9389  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
9390 
9391  return rtp->ssrc;
9392 }
RTP session description.
unsigned int ssrc
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
static int ast_rtp_get_stat ( struct ast_rtp_instance instance,
struct ast_rtp_instance_stats stats,
enum ast_rtp_instance_stat  stat 
)
static
Precondition
instance is locked

Definition at line 9178 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_channel_id(), ast_rtp_instance_get_data(), AST_RTP_INSTANCE_STAT_CHANNEL_UNIQUEID, AST_RTP_INSTANCE_STAT_COMBINED_JITTER, AST_RTP_INSTANCE_STAT_COMBINED_LOSS, AST_RTP_INSTANCE_STAT_COMBINED_MES, AST_RTP_INSTANCE_STAT_COMBINED_RTT, AST_RTP_INSTANCE_STAT_LOCAL_MAXJITTER, AST_RTP_INSTANCE_STAT_LOCAL_MAXMES, AST_RTP_INSTANCE_STAT_LOCAL_MAXRXPLOSS, AST_RTP_INSTANCE_STAT_LOCAL_MINJITTER, AST_RTP_INSTANCE_STAT_LOCAL_MINMES, AST_RTP_INSTANCE_STAT_LOCAL_MINRXPLOSS, AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVJITTER, AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVMES, AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVRXPLOSS, AST_RTP_INSTANCE_STAT_LOCAL_SSRC, AST_RTP_INSTANCE_STAT_LOCAL_STDEVJITTER, AST_RTP_INSTANCE_STAT_LOCAL_STDEVMES, AST_RTP_INSTANCE_STAT_LOCAL_STDEVRXPLOSS, AST_RTP_INSTANCE_STAT_MAX_RTT, AST_RTP_INSTANCE_STAT_MIN_RTT, AST_RTP_INSTANCE_STAT_NORMDEVRTT, AST_RTP_INSTANCE_STAT_REMOTE_MAXJITTER, AST_RTP_INSTANCE_STAT_REMOTE_MAXMES, AST_RTP_INSTANCE_STAT_REMOTE_MAXRXPLOSS, AST_RTP_INSTANCE_STAT_REMOTE_MINJITTER, AST_RTP_INSTANCE_STAT_REMOTE_MINMES, AST_RTP_INSTANCE_STAT_REMOTE_MINRXPLOSS, AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVJITTER, AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVMES, AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVRXPLOSS, AST_RTP_INSTANCE_STAT_REMOTE_SSRC, AST_RTP_INSTANCE_STAT_REMOTE_STDEVJITTER, AST_RTP_INSTANCE_STAT_REMOTE_STDEVMES, AST_RTP_INSTANCE_STAT_REMOTE_STDEVRXPLOSS, AST_RTP_INSTANCE_STAT_RTT, AST_RTP_INSTANCE_STAT_RXCOUNT, AST_RTP_INSTANCE_STAT_RXJITTER, AST_RTP_INSTANCE_STAT_RXMES, AST_RTP_INSTANCE_STAT_RXOCTETCOUNT, AST_RTP_INSTANCE_STAT_RXPLOSS, AST_RTP_INSTANCE_STAT_STDEVRTT, AST_RTP_INSTANCE_STAT_TXCOUNT, AST_RTP_INSTANCE_STAT_TXJITTER, AST_RTP_INSTANCE_STAT_TXMES, AST_RTP_INSTANCE_STAT_TXOCTETCOUNT, AST_RTP_INSTANCE_STAT_TXPLOSS, ast_rtp_instance_stats::channel_uniqueid, ast_rtcp::expected_prior, ast_rtp_instance_stats::local_maxjitter, ast_rtp_instance_stats::local_maxmes, ast_rtp_instance_stats::local_maxrxploss, ast_rtp_instance_stats::local_minjitter, ast_rtp_instance_stats::local_minmes, ast_rtp_instance_stats::local_minrxploss, ast_rtp_instance_stats::local_normdevjitter, ast_rtp_instance_stats::local_normdevmes, ast_rtp_instance_stats::local_normdevrxploss, ast_rtp_instance_stats::local_ssrc, ast_rtp_instance_stats::local_stdevjitter, ast_rtp_instance_stats::local_stdevmes, ast_rtp_instance_stats::local_stdevrxploss, ast_rtp_instance_stats::maxrtt, ast_rtcp::maxrtt, ast_rtcp::maxrxjitter, ast_rtcp::maxrxlost, ast_rtcp::maxrxmes, ast_rtp_instance_stats::minrtt, ast_rtcp::minrtt, ast_rtcp::minrxjitter, ast_rtcp::minrxlost, ast_rtcp::minrxmes, ast_rtcp::normdev_rxjitter, ast_rtcp::normdev_rxlost, ast_rtcp::normdev_rxmes, ast_rtp_instance_stats::normdevrtt, ast_rtcp::normdevrtt, ast_rtcp::received_prior, ast_rtp_instance_stats::remote_maxjitter, ast_rtp_instance_stats::remote_maxmes, ast_rtp_instance_stats::remote_maxrxploss, ast_rtp_instance_stats::remote_minjitter, ast_rtp_instance_stats::remote_minmes, ast_rtp_instance_stats::remote_minrxploss, ast_rtp_instance_stats::remote_normdevjitter, ast_rtp_instance_stats::remote_normdevmes, ast_rtp_instance_stats::remote_normdevrxploss, ast_rtp_instance_stats::remote_ssrc, ast_rtp_instance_stats::remote_stdevjitter, ast_rtp_instance_stats::remote_stdevmes, ast_rtp_instance_stats::remote_stdevrxploss, ast_rtcp::reported_jitter, ast_rtcp::reported_lost, ast_rtcp::reported_maxjitter, ast_rtcp::reported_maxlost, ast_rtcp::reported_maxmes, ast_rtcp::reported_mes, ast_rtcp::reported_minjitter, ast_rtcp::reported_minlost, ast_rtcp::reported_minmes, ast_rtcp::reported_normdev_jitter, ast_rtcp::reported_normdev_lost, ast_rtcp::reported_normdev_mes, ast_rtcp::reported_stdev_jitter, ast_rtcp::reported_stdev_lost, ast_rtcp::reported_stdev_mes, ast_rtp_instance_stats::rtt, ast_rtcp::rtt, ast_rtp_instance_stats::rxcount, ast_rtp::rxcount, ast_rtp_instance_stats::rxjitter, ast_rtp::rxjitter, ast_rtp::rxmes, ast_rtp_instance_stats::rxmes, ast_rtp::rxoctetcount, ast_rtp_instance_stats::rxoctetcount, ast_rtp_instance_stats::rxploss, ast_rtp::ssrc, ast_rtcp::stdev_rxjitter, ast_rtcp::stdev_rxlost, ast_rtp_instance_stats::stdevrtt, ast_rtcp::stdevrtt, ast_rtp::themssrc, ast_rtp_instance_stats::txcount, ast_rtp::txcount, ast_rtp_instance_stats::txjitter, ast_rtp_instance_stats::txmes, ast_rtp::txoctetcount, ast_rtp_instance_stats::txoctetcount, and ast_rtp_instance_stats::txploss.

9179 {
9180  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
9181 
9182  if (!rtp->rtcp) {
9183  return -1;
9184  }
9185 
9186  AST_RTP_STAT_SET(AST_RTP_INSTANCE_STAT_TXCOUNT, -1, stats->txcount, rtp->txcount);
9187  AST_RTP_STAT_SET(AST_RTP_INSTANCE_STAT_RXCOUNT, -1, stats->rxcount, rtp->rxcount);
9188  AST_RTP_STAT_SET(AST_RTP_INSTANCE_STAT_TXOCTETCOUNT, -1, stats->txoctetcount, rtp->txoctetcount);
9189  AST_RTP_STAT_SET(AST_RTP_INSTANCE_STAT_RXOCTETCOUNT, -1, stats->rxoctetcount, rtp->rxoctetcount);
9190 
9201  AST_RTP_STAT_TERMINATOR(AST_RTP_INSTANCE_STAT_COMBINED_LOSS);
9202 
9213  AST_RTP_STAT_TERMINATOR(AST_RTP_INSTANCE_STAT_COMBINED_JITTER);
9214 
9215  AST_RTP_STAT_SET(AST_RTP_INSTANCE_STAT_RTT, AST_RTP_INSTANCE_STAT_COMBINED_RTT, stats->rtt, rtp->rtcp->rtt);
9216  AST_RTP_STAT_SET(AST_RTP_INSTANCE_STAT_MAX_RTT, AST_RTP_INSTANCE_STAT_COMBINED_RTT, stats->maxrtt, rtp->rtcp->maxrtt);
9217  AST_RTP_STAT_SET(AST_RTP_INSTANCE_STAT_MIN_RTT, AST_RTP_INSTANCE_STAT_COMBINED_RTT, stats->minrtt, rtp->rtcp->minrtt);
9220  AST_RTP_STAT_TERMINATOR(AST_RTP_INSTANCE_STAT_COMBINED_RTT);
9221 
9232  AST_RTP_STAT_TERMINATOR(AST_RTP_INSTANCE_STAT_COMBINED_MES);
9233 
9234 
9235  AST_RTP_STAT_SET(AST_RTP_INSTANCE_STAT_LOCAL_SSRC, -1, stats->local_ssrc, rtp->ssrc);
9236  AST_RTP_STAT_SET(AST_RTP_INSTANCE_STAT_REMOTE_SSRC, -1, stats->remote_ssrc, rtp->themssrc);
9238 
9239  return 0;
9240 }
RTP session description.
double reported_stdev_jitter
double reported_stdev_lost
double minrxmes
double rxjitter
double reported_minlost
double reported_minjitter
unsigned int txcount
unsigned int txcount
Definition: rtp_engine.h:398
unsigned int rxcount
unsigned int rxploss
Definition: rtp_engine.h:424
double rxmes
double stdev_rxjitter
double maxrxmes
double reported_maxlost
unsigned int expected_prior
const char * ast_rtp_instance_get_channel_id(struct ast_rtp_instance *instance)
Get the unique ID of the channel that owns this RTP instance.
Definition: rtp_engine.c:570
double minrxjitter
double stdev_rxlost
unsigned int ssrc
unsigned int rxoctetcount
double reported_normdev_lost
char channel_uniqueid[MAX_CHANNEL_ID]
Definition: rtp_engine.h:456
double reported_maxmes
double reported_normdev_mes
double normdev_rxlost
double maxrxjitter
unsigned int txoctetcount
Definition: rtp_engine.h:458
unsigned int rxcount
Definition: rtp_engine.h:400
unsigned int themssrc
unsigned int reported_lost
double stdevrtt
unsigned int rxoctetcount
Definition: rtp_engine.h:460
unsigned int received_prior
unsigned int local_ssrc
Definition: rtp_engine.h:452
double reported_maxjitter
unsigned int txploss
Definition: rtp_engine.h:422
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
double normdev_rxmes
double reported_mes
unsigned int txoctetcount
double reported_minmes
double reported_jitter
double normdevrtt
double minrxlost
double normdev_rxjitter
double maxrxlost
double reported_stdev_mes
unsigned int remote_ssrc
Definition: rtp_engine.h:454
double reported_normdev_jitter
static void ast_rtp_ice_add_cand ( struct ast_rtp_instance instance,
struct ast_rtp rtp,
unsigned  comp_id,
unsigned  transport_id,
pj_ice_cand_type  type,
pj_uint16_t  local_pref,
const pj_sockaddr_t *  addr,
const pj_sockaddr_t *  base_addr,
const pj_sockaddr_t *  rel_addr,
int  addr_len 
)
static
Precondition
instance is locked

Definition at line 1295 of file res_rtp_asterisk.c.

References ast_rtp_engine_ice_candidate::address, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_list, ao2_link, ao2_ref, ast_debug_ice, ast_rtp_ice_candidate_destroy(), AST_RTP_ICE_CANDIDATE_TYPE_HOST, AST_RTP_ICE_CANDIDATE_TYPE_RELAYED, AST_RTP_ICE_CANDIDATE_TYPE_SRFLX, ast_sockaddr_parse(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_strdup, ast_strndup, ast_rtp_engine_ice_candidate::foundation, ast_rtp::ice, ast_rtp::ice_local_candidates, ast_rtp_engine_ice_candidate::id, OBJ_POINTER, pj_thread_register_check(), ast_rtp_engine_ice_candidate::priority, ice_wrap::real_ice, ast_rtp_engine_ice_candidate::relay_address, ast_rtp_engine_ice_candidate::transport, and ast_rtp_engine_ice_candidate::type.

Referenced by ast_rtp_ice_turn_request(), and rtp_add_candidates_to_ice().

1299 {
1300  pj_str_t foundation;
1301  struct ast_rtp_engine_ice_candidate *candidate, *existing;
1302  struct ice_wrap *ice;
1303  char address[PJ_INET6_ADDRSTRLEN];
1304  pj_status_t status;
1305 
1306  if (!rtp->ice) {
1307  return;
1308  }
1309 
1311 
1312  pj_ice_calc_foundation(rtp->ice->real_ice->pool, &foundation, type, addr);
1313 
1314  if (!rtp->ice_local_candidates) {
1316  NULL, ice_candidate_cmp);
1317  if (!rtp->ice_local_candidates) {
1318  return;
1319  }
1320  }
1321 
1322  if (!(candidate = ao2_alloc(sizeof(*candidate), ast_rtp_ice_candidate_destroy))) {
1323  return;
1324  }
1325 
1326  candidate->foundation = ast_strndup(pj_strbuf(&foundation), pj_strlen(&foundation));
1327  candidate->id = comp_id;
1328  candidate->transport = ast_strdup("UDP");
1329 
1330  ast_sockaddr_parse(&candidate->address, pj_sockaddr_print(addr, address, sizeof(address), 0), 0);
1331  ast_sockaddr_set_port(&candidate->address, pj_sockaddr_get_port(addr));
1332 
1333  if (rel_addr) {
1334  ast_sockaddr_parse(&candidate->relay_address, pj_sockaddr_print(rel_addr, address, sizeof(address), 0), 0);
1335  ast_sockaddr_set_port(&candidate->relay_address, pj_sockaddr_get_port(rel_addr));
1336  }
1337 
1338  if (type == PJ_ICE_CAND_TYPE_HOST) {
1340  } else if (type == PJ_ICE_CAND_TYPE_SRFLX) {
1342  } else if (type == PJ_ICE_CAND_TYPE_RELAYED) {
1344  }
1345 
1346  if ((existing = ao2_find(rtp->ice_local_candidates, candidate, OBJ_POINTER))) {
1347  ao2_ref(existing, -1);
1348  ao2_ref(candidate, -1);
1349  return;
1350  }
1351 
1352  /* Release the instance lock to avoid deadlock with PJPROJECT group lock */
1353  ice = rtp->ice;
1354  ao2_ref(ice, +1);
1355  ao2_unlock(instance);
1356  status = pj_ice_sess_add_cand(ice->real_ice, comp_id, transport_id, type, local_pref,
1357  &foundation, addr, base_addr, rel_addr, addr_len, NULL);
1358  ao2_ref(ice, -1);
1359  ao2_lock(instance);
1360  if (!rtp->ice || status != PJ_SUCCESS) {
1361  ast_debug_ice(2, "(%p) ICE unable to add candidate: %s, %d\n", instance, ast_sockaddr_stringify(
1362  &candidate->address), candidate->priority);
1363  ao2_ref(candidate, -1);
1364  return;
1365  }
1366 
1367  /* By placing the candidate into the ICE session it will have produced the priority, so update the local candidate with it */
1368  candidate->priority = rtp->ice->real_ice->lcand[rtp->ice->real_ice->lcand_cnt - 1].prio;
1369 
1370  ast_debug_ice(2, "(%p) ICE add candidate: %s, %d\n", instance, ast_sockaddr_stringify(
1371  &candidate->address), candidate->priority);
1372 
1373  ao2_link(rtp->ice_local_candidates, candidate);
1374  ao2_ref(candidate, -1);
1375 }
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
#define OBJ_POINTER
Definition: astobj2.h:1150
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
#define ast_debug_ice(sublevel,...)
Log debug level ICE information.
Definition: rtp_engine.h:3063
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
Structure for an ICE candidate.
Definition: rtp_engine.h:525
static void pj_thread_register_check(void)
Function used to check if the calling thread is registered with pjlib. If it is not it will be regist...
enum ast_rtp_ice_candidate_type type
Definition: rtp_engine.h:532
static void ast_rtp_ice_candidate_destroy(void *obj)
Destructor for locally created ICE candidates.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ice_wrap * ice
struct ast_sockaddr relay_address
Definition: rtp_engine.h:531
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
enum ast_rtp_ice_component_type id
Definition: rtp_engine.h:527
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
#define ast_strndup(str, len)
A wrapper for strndup()
Definition: astmm.h:256
struct ao2_container * ice_local_candidates
struct ast_sockaddr address
Definition: rtp_engine.h:530
pj_ice_sess * real_ice
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
static void ast_rtp_ice_add_remote_candidate ( struct ast_rtp_instance instance,
const struct ast_rtp_engine_ice_candidate candidate 
)
static
Precondition
instance is locked

Definition at line 877 of file res_rtp_asterisk.c.

References ast_rtp_engine_ice_candidate::address, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_list, ao2_container_count(), ao2_link, ao2_ref, ast_debug_ice, ast_rtp_ice_candidate_destroy(), ast_rtp_instance_get_data(), ast_sockaddr_copy(), ast_strdup, ast_rtp_engine_ice_candidate::foundation, ast_rtp::ice_proposed_remote_candidates, ast_rtp_engine_ice_candidate::id, ast_rtp_engine_ice_candidate::priority, ast_rtp_engine_ice_candidate::relay_address, ast_rtp_engine_ice_candidate::transport, and ast_rtp_engine_ice_candidate::type.

878 {
879  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
880  struct ast_rtp_engine_ice_candidate *remote_candidate;
881 
882  /* ICE sessions only support UDP candidates */
883  if (strcasecmp(candidate->transport, "udp")) {
884  return;
885  }
886 
887  if (!rtp->ice_proposed_remote_candidates) {
889  AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, ice_candidate_cmp);
890  if (!rtp->ice_proposed_remote_candidates) {
891  return;
892  }
893  }
894 
895  /* If this is going to exceed the maximum number of ICE candidates don't even add it */
896  if (ao2_container_count(rtp->ice_proposed_remote_candidates) == PJ_ICE_MAX_CAND) {
897  return;
898  }
899 
900  if (!(remote_candidate = ao2_alloc(sizeof(*remote_candidate), ast_rtp_ice_candidate_destroy))) {
901  return;
902  }
903 
904  remote_candidate->foundation = ast_strdup(candidate->foundation);
905  remote_candidate->id = candidate->id;
906  remote_candidate->transport = ast_strdup(candidate->transport);
907  remote_candidate->priority = candidate->priority;
908  ast_sockaddr_copy(&remote_candidate->address, &candidate->address);
909  ast_sockaddr_copy(&remote_candidate->relay_address, &candidate->relay_address);
910  remote_candidate->type = candidate->type;
911 
912  ast_debug_ice(2, "(%p) ICE add remote candidate\n", instance);
913 
914  ao2_link(rtp->ice_proposed_remote_candidates, remote_candidate);
915  ao2_ref(remote_candidate, -1);
916 }
RTP session description.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
#define ast_debug_ice(sublevel,...)
Log debug level ICE information.
Definition: rtp_engine.h:3063
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
Structure for an ICE candidate.
Definition: rtp_engine.h:525
struct ao2_container * ice_proposed_remote_candidates
enum ast_rtp_ice_candidate_type type
Definition: rtp_engine.h:532
static void ast_rtp_ice_candidate_destroy(void *obj)
Destructor for locally created ICE candidates.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ast_sockaddr relay_address
Definition: rtp_engine.h:531
enum ast_rtp_ice_component_type id
Definition: rtp_engine.h:527
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
struct ast_sockaddr address
Definition: rtp_engine.h:530
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
static void ast_rtp_ice_change_components ( struct ast_rtp_instance instance,
int  num_components 
)
static
Precondition
instance is locked

Definition at line 1790 of file res_rtp_asterisk.c.

References ast_debug_ice, ast_rtp_instance_get_data(), ast_rtp::ice, ast_rtp::ice_num_components, and ice_reset_session().

1791 {
1792  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1793 
1794  /* Don't do anything if ICE is unsupported or if we're not changing the
1795  * number of components
1796  */
1797  if (!icesupport || !rtp->ice || rtp->ice_num_components == num_components) {
1798  return;
1799  }
1800 
1801  ast_debug_ice(2, "(%p) ICE change number of components %u -> %u\n", instance,
1802  rtp->ice_num_components, num_components);
1803 
1804  rtp->ice_num_components = num_components;
1805  ice_reset_session(instance);
1806 }
RTP session description.
#define ast_debug_ice(sublevel,...)
Log debug level ICE information.
Definition: rtp_engine.h:3063
static int ice_reset_session(struct ast_rtp_instance *instance)
struct ice_wrap * ice
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
unsigned int ice_num_components
static struct ao2_container* ast_rtp_ice_get_local_candidates ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 1245 of file res_rtp_asterisk.c.

References ao2_ref, ast_rtp_instance_get_data(), and ast_rtp::ice_local_candidates.

1246 {
1247  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1248 
1249  if (rtp->ice_local_candidates) {
1250  ao2_ref(rtp->ice_local_candidates, +1);
1251  }
1252 
1253  return rtp->ice_local_candidates;
1254 }
RTP session description.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
struct ao2_container * ice_local_candidates
static const char* ast_rtp_ice_get_password ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 1237 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), and ast_rtp::local_passwd.

1238 {
1239  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1240 
1241  return rtp->local_passwd;
1242 }
RTP session description.
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
char local_passwd[256]
static const char* ast_rtp_ice_get_ufrag ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 1229 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), and ast_rtp::local_ufrag.

1230 {
1231  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1232 
1233  return rtp->local_ufrag;
1234 }
RTP session description.
char local_ufrag[256]
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
static void ast_rtp_ice_lite ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 1257 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), ast_rtp::ice, pj_thread_register_check(), and ice_wrap::real_ice.

1258 {
1259  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1260 
1261  if (!rtp->ice) {
1262  return;
1263  }
1264 
1266 
1267  pj_ice_sess_change_role(rtp->ice->real_ice, PJ_ICE_SESS_ROLE_CONTROLLING);
1268 }
RTP session description.
static void pj_thread_register_check(void)
Function used to check if the calling thread is registered with pjlib. If it is not it will be regist...
struct ice_wrap * ice
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
pj_ice_sess * real_ice
static void ast_rtp_ice_set_authentication ( struct ast_rtp_instance instance,
const char *  ufrag,
const char *  password 
)
static
Precondition
instance is locked

Definition at line 836 of file res_rtp_asterisk.c.

References ast_copy_string(), ast_rtp_instance_get_data(), generate_random_string(), ast_rtp::local_passwd, ast_rtp::local_ufrag, ast_rtp::remote_passwd, and ast_rtp::remote_ufrag.

837 {
838  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
839  int ice_attrb_reset = 0;
840 
841  if (!ast_strlen_zero(ufrag)) {
842  if (!ast_strlen_zero(rtp->remote_ufrag) && strcmp(ufrag, rtp->remote_ufrag)) {
843  ice_attrb_reset = 1;
844  }
845  ast_copy_string(rtp->remote_ufrag, ufrag, sizeof(rtp->remote_ufrag));
846  }
847 
848  if (!ast_strlen_zero(password)) {
849  if (!ast_strlen_zero(rtp->remote_passwd) && strcmp(password, rtp->remote_passwd)) {
850  ice_attrb_reset = 1;
851  }
852  ast_copy_string(rtp->remote_passwd, password, sizeof(rtp->remote_passwd));
853  }
854 
855  /* If the remote ufrag or passwd changed, local ufrag and passwd need to regenerate */
856  if (ice_attrb_reset) {
857  generate_random_string(rtp->local_ufrag, sizeof(rtp->local_ufrag));
859  }
860 }
static char * generate_random_string(char *buf, size_t size)
Generate 32 byte random string (stolen from chan_sip.c)
Definition: res_calendar.c:719
RTP session description.
char local_ufrag[256]
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
char remote_passwd[256]
char local_passwd[256]
char remote_ufrag[256]
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
static void ast_rtp_ice_set_role ( struct ast_rtp_instance instance,
enum ast_rtp_ice_role  role 
)
static
Precondition
instance is locked

Definition at line 1271 of file res_rtp_asterisk.c.

References ast_debug_ice, ast_rtp_instance_get_data(), ast_rtp::ice, pj_thread_register_check(), ice_wrap::real_ice, and ast_rtp::role.

1272 {
1273  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1274 
1275  if (!rtp->ice) {
1276  ast_debug_ice(3, "(%p) ICE set role failed; no ice instance\n", instance);
1277  return;
1278  }
1279 
1280  rtp->role = role;
1281 
1282  if (!rtp->ice->real_ice->is_nominating && !rtp->ice->real_ice->is_complete) {
1284  ast_debug_ice(2, "(%p) ICE set role to %s\n",
1285  instance, role == AST_RTP_ICE_ROLE_CONTROLLED ? "CONTROLLED" : "CONTROLLING");
1286  pj_ice_sess_change_role(rtp->ice->real_ice, role == AST_RTP_ICE_ROLE_CONTROLLED ?
1287  PJ_ICE_SESS_ROLE_CONTROLLED : PJ_ICE_SESS_ROLE_CONTROLLING);
1288  } else {
1289  ast_debug_ice(2, "(%p) ICE not setting role because state is %s\n",
1290  instance, rtp->ice->real_ice->is_nominating ? "nominating" : "complete");
1291  }
1292 }
RTP session description.
#define ast_debug_ice(sublevel,...)
Log debug level ICE information.
Definition: rtp_engine.h:3063
static void pj_thread_register_check(void)
Function used to check if the calling thread is registered with pjlib. If it is not it will be regist...
struct ice_wrap * ice
enum ast_rtp_ice_role role
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
pj_ice_sess * real_ice
static void ast_rtp_ice_start ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 1087 of file res_rtp_asterisk.c.

References address, ast_rtp_engine_ice_candidate::address, ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_ref, ast_debug_ice, AST_RTP_ICE_CANDIDATE_TYPE_HOST, AST_RTP_ICE_CANDIDATE_TYPE_RELAYED, AST_RTP_ICE_CANDIDATE_TYPE_SRFLX, ast_rtp_instance_get_data(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_test_suite_event_notify, ast_rtp_engine_ice_candidate::foundation, ast_rtp::ice, ast_rtp::ice_active_remote_candidates, ast_rtp::ice_num_components, ast_rtp::ice_proposed_remote_candidates, ice_reset_session(), ast_rtp_engine_ice_candidate::id, pj_thread_register_check(), ast_rtp_engine_ice_candidate::priority, ice_wrap::real_ice, ast_rtp_engine_ice_candidate::relay_address, ast_rtp::remote_passwd, ast_rtp::remote_ufrag, ast_rtp::role, ast_rtp::strict_rtp_state, timer_heap, ast_rtp::turn_rtcp, ast_rtp::turn_rtp, and ast_rtp_engine_ice_candidate::type.

1088 {
1089  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1090  pj_str_t ufrag = pj_str(rtp->remote_ufrag), passwd = pj_str(rtp->remote_passwd);
1091  pj_ice_sess_cand candidates[PJ_ICE_MAX_CAND];
1092  struct ao2_iterator i;
1093  struct ast_rtp_engine_ice_candidate *candidate;
1094  int cand_cnt = 0, has_rtp = 0, has_rtcp = 0;
1095 
1096  if (!rtp->ice || !rtp->ice_proposed_remote_candidates) {
1097  return;
1098  }
1099 
1100  /* Check for equivalence in the lists */
1101  if (rtp->ice_active_remote_candidates &&
1102  !ice_candidates_compare(rtp->ice_proposed_remote_candidates, rtp->ice_active_remote_candidates)) {
1103  ast_debug_ice(2, "(%p) ICE proposed equals active candidates\n", instance);
1104  ao2_cleanup(rtp->ice_proposed_remote_candidates);
1105  rtp->ice_proposed_remote_candidates = NULL;
1106  /* If this ICE session is being preserved then go back to the role it currently is */
1107  pj2ast_rtp_ice_role(rtp->ice->real_ice->role, &rtp->role);
1108  return;
1109  }
1110 
1111  /* Out with the old, in with the new */
1112  ao2_cleanup(rtp->ice_active_remote_candidates);
1114  rtp->ice_proposed_remote_candidates = NULL;
1115 
1116  ast_debug_ice(2, "(%p) ICE start\n", instance);
1117 
1118  /* Reset the ICE session. Is this going to work? */
1119  if (ice_reset_session(instance)) {
1120  ast_log(LOG_NOTICE, "(%p) ICE failed to create replacement session\n", instance);
1121  return;
1122  }
1123 
1125 
1127 
1128  while ((candidate = ao2_iterator_next(&i)) && (cand_cnt < PJ_ICE_MAX_CAND)) {
1129  pj_str_t address;
1130 
1131  /* there needs to be at least one rtp and rtcp candidate in the list */
1132  has_rtp |= candidate->id == AST_RTP_ICE_COMPONENT_RTP;
1133  has_rtcp |= candidate->id == AST_RTP_ICE_COMPONENT_RTCP;
1134 
1135  pj_strdup2(rtp->ice->real_ice->pool, &candidates[cand_cnt].foundation,
1136  candidate->foundation);
1137  candidates[cand_cnt].comp_id = candidate->id;
1138  candidates[cand_cnt].prio = candidate->priority;
1139 
1140  pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&address, ast_sockaddr_stringify(&candidate->address)), &candidates[cand_cnt].addr);
1141 
1142  if (!ast_sockaddr_isnull(&candidate->relay_address)) {
1143  pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&address, ast_sockaddr_stringify(&candidate->relay_address)), &candidates[cand_cnt].rel_addr);
1144  }
1145 
1146  if (candidate->type == AST_RTP_ICE_CANDIDATE_TYPE_HOST) {
1147  candidates[cand_cnt].type = PJ_ICE_CAND_TYPE_HOST;
1148  } else if (candidate->type == AST_RTP_ICE_CANDIDATE_TYPE_SRFLX) {
1149  candidates[cand_cnt].type = PJ_ICE_CAND_TYPE_SRFLX;
1150  } else if (candidate->type == AST_RTP_ICE_CANDIDATE_TYPE_RELAYED) {
1151  candidates[cand_cnt].type = PJ_ICE_CAND_TYPE_RELAYED;
1152  }
1153 
1154  if (candidate->id == AST_RTP_ICE_COMPONENT_RTP && rtp->turn_rtp) {
1155  ast_debug_ice(2, "(%p) ICE RTP candidate %s\n", instance, ast_sockaddr_stringify(&candidate->address));
1156  /* Release the instance lock to avoid deadlock with PJPROJECT group lock */
1157  ao2_unlock(instance);
1158  pj_turn_sock_set_perm(rtp->turn_rtp, 1, &candidates[cand_cnt].addr, 1);
1159  ao2_lock(instance);
1160  } else if (candidate->id == AST_RTP_ICE_COMPONENT_RTCP && rtp->turn_rtcp) {
1161  ast_debug_ice(2, "(%p) ICE RTCP candidate %s\n", instance, ast_sockaddr_stringify(&candidate->address));
1162  /* Release the instance lock to avoid deadlock with PJPROJECT group lock */
1163  ao2_unlock(instance);
1164  pj_turn_sock_set_perm(rtp->turn_rtcp, 1, &candidates[cand_cnt].addr, 1);
1165  ao2_lock(instance);
1166  }
1167 
1168  cand_cnt++;
1169  ao2_ref(candidate, -1);
1170  }
1171 
1173 
1174  if (cand_cnt < ao2_container_count(rtp->ice_active_remote_candidates)) {
1175  ast_log(LOG_WARNING, "(%p) ICE lost %d candidates. Consider increasing PJ_ICE_MAX_CAND in PJSIP\n",
1176  instance, ao2_container_count(rtp->ice_active_remote_candidates) - cand_cnt);
1177  }
1178 
1179  if (!has_rtp) {
1180  ast_log(LOG_WARNING, "(%p) ICE no RTP candidates; skipping checklist\n", instance);
1181  }
1182 
1183  /* If we're only dealing with one ICE component, then we don't care about the lack of RTCP candidates */
1184  if (!has_rtcp && rtp->ice_num_components > 1) {
1185  ast_log(LOG_WARNING, "(%p) ICE no RTCP candidates; skipping checklist\n", instance);
1186  }
1187 
1188  if (rtp->ice && has_rtp && (has_rtcp || rtp->ice_num_components == 1)) {
1189  pj_status_t res;
1190  char reason[80];
1191  struct ice_wrap *ice;
1192 
1193  /* Release the instance lock to avoid deadlock with PJPROJECT group lock */
1194  ice = rtp->ice;
1195  ao2_ref(ice, +1);
1196  ao2_unlock(instance);
1197  res = pj_ice_sess_create_check_list(ice->real_ice, &ufrag, &passwd, cand_cnt, &candidates[0]);
1198  if (res == PJ_SUCCESS) {
1199  ast_debug_ice(2, "(%p) ICE successfully created checklist\n", instance);
1200  ast_test_suite_event_notify("ICECHECKLISTCREATE", "Result: SUCCESS");
1201  pj_ice_sess_start_check(ice->real_ice);
1202  pj_timer_heap_poll(timer_heap, NULL);
1203  ao2_ref(ice, -1);
1204  ao2_lock(instance);
1205  rtp->strict_rtp_state = STRICT_RTP_OPEN;
1206  return;
1207  }
1208  ao2_ref(ice, -1);
1209  ao2_lock(instance);
1210 
1211  pj_strerror(res, reason, sizeof(reason));
1212  ast_log(LOG_WARNING, "(%p) ICE failed to create session check list: %s\n", instance, reason);
1213  }
1214 
1215  ast_test_suite_event_notify("ICECHECKLISTCREATE", "Result: FAILURE");
1216 
1217  /* even though create check list failed don't stop ice as
1218  it might still work */
1219  /* however we do need to reset remote candidates since
1220  this function may be re-entered */
1222  rtp->ice_active_remote_candidates = NULL;
1223  if (rtp->ice) {
1224  rtp->ice->real_ice->rcand_cnt = rtp->ice->real_ice->clist.count = 0;
1225  }
1226 }
RTP session description.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
enum strict_rtp_state strict_rtp_state
static struct ast_sockaddr address
Address for UDPTL.
Definition: res_pjsip_t38.c:56
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ast_debug_ice(sublevel,...)
Log debug level ICE information.
Definition: rtp_engine.h:3063
struct ao2_container * ice_active_remote_candidates
Structure for an ICE candidate.
Definition: rtp_engine.h:525
static void pj_thread_register_check(void)
Function used to check if the calling thread is registered with pjlib. If it is not it will be regist...
struct ao2_container * ice_proposed_remote_candidates
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
enum ast_rtp_ice_candidate_type type
Definition: rtp_engine.h:532
pj_turn_sock * turn_rtp
static int ice_reset_session(struct ast_rtp_instance *instance)
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ice_wrap * ice
struct ast_sockaddr relay_address
Definition: rtp_engine.h:531
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:189
enum ast_rtp_ice_component_type id
Definition: rtp_engine.h:527
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
pj_turn_sock * turn_rtcp
enum ast_rtp_ice_role role
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
char remote_passwd[256]
char remote_ufrag[256]
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
struct ast_sockaddr address
Definition: rtp_engine.h:530
static pj_timer_heap_t * timer_heap
Global timer heap.
unsigned int ice_num_components
pj_ice_sess * real_ice
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
static void ast_rtp_ice_stop ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 947 of file res_rtp_asterisk.c.

References ao2_ref, ast_debug_ice, ast_rtp_instance_get_data(), and ast_rtp::ice.

948 {
949  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
950  struct ice_wrap *ice;
951 
952  ice = rtp->ice;
953  rtp->ice = NULL;
954  if (ice) {
955  /* Release the instance lock to avoid deadlock with PJPROJECT group lock */
956  ao2_unlock(instance);
957  ao2_ref(ice, -1);
958  ao2_lock(instance);
959  ast_debug_ice(2, "(%p) ICE stopped\n", instance);
960  }
961 }
RTP session description.
#define ast_debug_ice(sublevel,...)
Log debug level ICE information.
Definition: rtp_engine.h:3063
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ice_wrap * ice
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
static void ast_rtp_ice_turn_request ( struct ast_rtp_instance instance,
enum ast_rtp_ice_component_type  component,
enum ast_transport  transport,
const char *  server,
unsigned int  port,
const char *  username,
const char *  password 
)
static
Precondition
instance is locked

Definition at line 1633 of file res_rtp_asterisk.c.

References ao2_object_get_lockaddr(), ao2_ref, ast_debug_ice, ast_rtp_ice_add_cand(), ast_rtp_instance_get_data(), ast_rtp_instance_get_local_address(), ast_samp2tv(), ast_sockaddr_copy(), ast_sockaddr_is_ipv4(), ast_sockaddr_parse(), ast_sockaddr_port, ast_sockaddr_set_port, ast_tvadd(), ast_tvnow(), cachingpool, ast_rtp::cond, ast_rtp::ice, ast_rtp_ioqueue_thread::ioqueue, ast_rtp::ioqueue, ice_wrap::real_ice, ast_rtp::rtcp_loop, rtp_ioqueue_thread_get_or_create(), ast_rtp::rtp_loop, ast_rtp_ioqueue_thread::timerheap, ast_rtp::turn_rtcp, ast_rtp::turn_rtp, ast_rtp::turn_state, and ast_rtcp::us.

Referenced by rtp_add_candidates_to_ice().

1635 {
1636  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1637  pj_turn_sock **turn_sock;
1638  const pj_turn_sock_cb *turn_cb;
1639  pj_turn_tp_type conn_type;
1640  int conn_transport;
1641  pj_stun_auth_cred cred = { 0, };
1642  pj_str_t turn_addr;
1643  struct ast_sockaddr addr = { { 0, } };
1644  pj_stun_config stun_config;
1645  struct timeval wait = ast_tvadd(ast_tvnow(), ast_samp2tv(TURN_STATE_WAIT_TIME, 1000));
1646  struct timespec ts = { .tv_sec = wait.tv_sec, .tv_nsec = wait.tv_usec * 1000, };
1647  pj_turn_session_info info;
1648  struct ast_sockaddr local, loop;
1649  pj_status_t status;
1650  pj_turn_sock_cfg turn_sock_cfg;
1651  struct ice_wrap *ice;
1652 
1653  ast_rtp_instance_get_local_address(instance, &local);
1654  if (ast_sockaddr_is_ipv4(&local)) {
1655  ast_sockaddr_parse(&loop, "127.0.0.1", PARSE_PORT_FORBID);
1656  } else {
1657  ast_sockaddr_parse(&loop, "::1", PARSE_PORT_FORBID);
1658  }
1659 
1660  /* Determine what component we are requesting a TURN session for */
1661  if (component == AST_RTP_ICE_COMPONENT_RTP) {
1662  turn_sock = &rtp->turn_rtp;
1663  turn_cb = &ast_rtp_turn_rtp_sock_cb;
1664  conn_transport = TRANSPORT_TURN_RTP;
1665  ast_sockaddr_set_port(&loop, ast_sockaddr_port(&local));
1666  } else if (component == AST_RTP_ICE_COMPONENT_RTCP) {
1667  turn_sock = &rtp->turn_rtcp;
1668  turn_cb = &ast_rtp_turn_rtcp_sock_cb;
1669  conn_transport = TRANSPORT_TURN_RTCP;
1670  ast_sockaddr_set_port(&loop, ast_sockaddr_port(&rtp->rtcp->us));
1671  } else {
1672  return;
1673  }
1674 
1675  if (transport == AST_TRANSPORT_UDP) {
1676  conn_type = PJ_TURN_TP_UDP;
1677  } else if (transport == AST_TRANSPORT_TCP) {
1678  conn_type = PJ_TURN_TP_TCP;
1679  } else {
1680  ast_assert(0);
1681  return;
1682  }
1683 
1684  ast_sockaddr_parse(&addr, server, PARSE_PORT_FORBID);
1685 
1686  if (*turn_sock) {
1687  rtp->turn_state = PJ_TURN_STATE_NULL;
1688 
1689  /* Release the instance lock to avoid deadlock with PJPROJECT group lock */
1690  ao2_unlock(instance);
1691  pj_turn_sock_destroy(*turn_sock);
1692  ao2_lock(instance);
1693  while (rtp->turn_state != PJ_TURN_STATE_DESTROYING) {
1694  ast_cond_timedwait(&rtp->cond, ao2_object_get_lockaddr(instance), &ts);
1695  }
1696  }
1697 
1698  if (component == AST_RTP_ICE_COMPONENT_RTP && !rtp->ioqueue) {
1699  /*
1700  * We cannot hold the instance lock because we could wait
1701  * for the ioqueue thread to die and we might deadlock as
1702  * a result.
1703  */
1704  ao2_unlock(instance);
1706  ao2_lock(instance);
1707  if (!rtp->ioqueue) {
1708  return;
1709  }
1710  }
1711 
1712  pj_stun_config_init(&stun_config, &cachingpool.factory, 0, rtp->ioqueue->ioqueue, rtp->ioqueue->timerheap);
1713  if (!stun_software_attribute) {
1714  stun_config.software_name = pj_str(NULL);
1715  }
1716 
1717  /* Use ICE session group lock for TURN session to avoid deadlock */
1718  pj_turn_sock_cfg_default(&turn_sock_cfg);
1719  ice = rtp->ice;
1720  if (ice) {
1721  turn_sock_cfg.grp_lock = ice->real_ice->grp_lock;
1722  ao2_ref(ice, +1);
1723  }
1724 
1725  /* Release the instance lock to avoid deadlock with PJPROJECT group lock */
1726  ao2_unlock(instance);
1727  status = pj_turn_sock_create(&stun_config,
1728  ast_sockaddr_is_ipv4(&addr) ? pj_AF_INET() : pj_AF_INET6(), conn_type,
1729  turn_cb, &turn_sock_cfg, instance, turn_sock);
1730  ao2_cleanup(ice);
1731  if (status != PJ_SUCCESS) {
1732  ast_log(LOG_WARNING, "(%p) Could not create a TURN client socket\n", instance);
1733  ao2_lock(instance);
1734  return;
1735  }
1736 
1737  cred.type = PJ_STUN_AUTH_CRED_STATIC;
1738  pj_strset2(&cred.data.static_cred.username, (char*)username);
1739  cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN;
1740  pj_strset2(&cred.data.static_cred.data, (char*)password);
1741 
1742  pj_turn_sock_alloc(*turn_sock, pj_cstr(&turn_addr, server), port, NULL, &cred, NULL);
1743 
1744  ast_debug_ice(2, "(%p) ICE request TURN %s %s candidate\n", instance,
1745  transport == AST_TRANSPORT_UDP ? "UDP" : "TCP",
1746  component == AST_RTP_ICE_COMPONENT_RTP ? "RTP" : "RTCP");
1747 
1748  ao2_lock(instance);
1749 
1750  /*
1751  * Because the TURN socket is asynchronous and we are synchronous we need to
1752  * wait until it is done
1753  */
1754  while (rtp->turn_state < PJ_TURN_STATE_READY) {
1755  ast_cond_timedwait(&rtp->cond, ao2_object_get_lockaddr(instance), &ts);
1756  }
1757 
1758  /* If a TURN session was allocated add it as a candidate */
1759  if (rtp->turn_state != PJ_TURN_STATE_READY) {
1760  return;
1761  }
1762 
1763  pj_turn_sock_get_info(*turn_sock, &info);
1764 
1765  ast_rtp_ice_add_cand(instance, rtp, component, conn_transport,
1766  PJ_ICE_CAND_TYPE_RELAYED, 65535, &info.relay_addr, &info.relay_addr,
1767  &info.mapped_addr, pj_sockaddr_get_len(&info.relay_addr));
1768 
1769  if (component == AST_RTP_ICE_COMPONENT_RTP) {
1770  ast_sockaddr_copy(&rtp->rtp_loop, &loop);
1771  } else if (component == AST_RTP_ICE_COMPONENT_RTCP) {
1772  ast_sockaddr_copy(&rtp->rtcp_loop, &loop);
1773  }
1774 }
RTP session description.
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
static pj_caching_pool cachingpool
Pool factory used by pjlib to allocate memory.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
#define ast_debug_ice(sublevel,...)
Log debug level ICE information.
Definition: rtp_engine.h:3063
Socket address structure.
Definition: netsock2.h:97
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
struct ast_rtp_ioqueue_thread * ioqueue
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
Definition: astobj2.c:476
struct ast_sockaddr rtp_loop
struct ast_sockaddr rtcp_loop
pj_turn_sock * turn_rtp
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ice_wrap * ice
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:282
ast_cond_t cond
static void ast_rtp_ice_add_cand(struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned comp_id, unsigned transport_id, pj_ice_cand_type type, pj_uint16_t local_pref, const pj_sockaddr_t *addr, const pj_sockaddr_t *base_addr, const pj_sockaddr_t *rel_addr, int addr_len)
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
pj_ioqueue_t * ioqueue
Ioqueue which polls on sockets.
pj_turn_sock * turn_rtcp
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the local address that we are expecting RTP on.
Definition: rtp_engine.c:665
struct ast_sockaddr us
pj_turn_state_t turn_state
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:497
static struct ast_rtp_ioqueue_thread * rtp_ioqueue_thread_get_or_create(void)
Finder and allocator for an ioqueue thread.
pj_ice_sess * real_ice
pj_timer_heap_t * timerheap
Timer heap for scheduled items.
static int ast_rtp_local_bridge ( struct ast_rtp_instance instance0,
struct ast_rtp_instance instance1 
)
static
Precondition
Neither instance0 nor instance1 are locked

Definition at line 9150 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), ast_rtp::ssrc, ast_rtp::ssrc_orig, and ast_rtp::ssrc_saved.

9151 {
9152  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance0);
9153 
9154  ao2_lock(instance0);
9155  ast_set_flag(rtp, FLAG_NEED_MARKER_BIT | FLAG_REQ_LOCAL_BRIDGE_BIT);
9156  if (rtp->smoother) {
9157  ast_smoother_free(rtp->smoother);
9158  rtp->smoother = NULL;
9159  }
9160 
9161  /* We must use a new SSRC when local bridge ends */
9162  if (!instance1) {
9163  rtp->ssrc = rtp->ssrc_orig;
9164  rtp->ssrc_orig = 0;
9165  rtp->ssrc_saved = 0;
9166  } else if (!rtp->ssrc_saved) {
9167  /* In case ast_rtp_local_bridge is called multiple times, only save the ssrc from before local bridge began */
9168  rtp->ssrc_orig = rtp->ssrc;
9169  rtp->ssrc_saved = 1;
9170  }
9171 
9172  ao2_unlock(instance0);
9173 
9174  return 0;
9175 }
RTP session description.
unsigned int ssrc
unsigned char ssrc_saved
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
unsigned int ssrc_orig
static int ast_rtp_new ( struct ast_rtp_instance instance,
struct ast_sched_context sched,
struct ast_sockaddr addr,
void *  data 
)
static
Precondition
instance is locked

Definition at line 4139 of file res_rtp_asterisk.c.

References ao2_bump, ast_calloc, ast_format_none, ast_rtp_instance_set_data(), ast_sockaddr_copy(), ast_uuid_generate_str(), AST_VECTOR_INIT, ast_rtp::bind_address, ast_rtp::cname, ast_rtp::expectedrxseqno, ast_rtp::expectedseqno, ast_rtp::f, ast_frame_subclass::format, ast_rtp::owner, rtp_transport_wide_cc_statistics::packet_statistics, ast_rtp::rxstart, rtp_transport_wide_cc_statistics::schedid, ast_rtp::seqno, ast_rtp::ssrc, ast_rtp::ssrc_mapping, ast_rtp::stream_num, ast_frame::subclass, and ast_rtp::transport_wide_cc.

4142 {
4143  struct ast_rtp *rtp = NULL;
4144 
4145  /* Create a new RTP structure to hold all of our data */
4146  if (!(rtp = ast_calloc(1, sizeof(*rtp)))) {
4147  return -1;
4148  }
4149  rtp->owner = instance;
4150  /* Set default parameters on the newly created RTP structure */
4151  rtp->ssrc = ast_random();
4152  ast_uuid_generate_str(rtp->cname, sizeof(rtp->cname));
4153  rtp->seqno = ast_random() & 0x7fff;
4154  rtp->expectedrxseqno = -1;
4155  rtp->expectedseqno = -1;
4156  rtp->rxstart = -1;
4157  rtp->sched = sched;
4158  ast_sockaddr_copy(&rtp->bind_address, addr);
4159  /* Transport creation operations can grab the RTP data from the instance, so set it */
4160  ast_rtp_instance_set_data(instance, rtp);
4161 
4162  if (rtp_allocate_transport(instance, rtp)) {
4163  return -1;
4164  }
4165 
4166  if (AST_VECTOR_INIT(&rtp->ssrc_mapping, 1)) {
4167  return -1;
4168  }
4169 
4171  return -1;
4172  }
4173  rtp->transport_wide_cc.schedid = -1;
4174 
4176  rtp->lastrxformat = ao2_bump(ast_format_none);
4177  rtp->lasttxformat = ao2_bump(ast_format_none);
4178  rtp->stream_num = -1;
4179 
4180  return 0;
4181 }
RTP session description.
struct rtp_transport_wide_cc_statistics::@478 packet_statistics
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
struct ast_rtp_instance * owner
The RTP instance owning us (used for debugging purposes) We don't hold a reference to the instance be...
struct rtp_transport_wide_cc_statistics transport_wide_cc
struct ast_format * ast_format_none
Built-in "null" format.
Definition: format_cache.c:246
struct ast_frame_subclass subclass
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
unsigned int ssrc
char cname[AST_UUID_STR_LEN]
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
void ast_rtp_instance_set_data(struct ast_rtp_instance *instance, void *data)
Set the data portion of an RTP instance.
Definition: rtp_engine.c:580
struct ast_rtp::@480 ssrc_mapping
int expectedrxseqno
double rxstart
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:141
struct ast_frame f
struct ast_sockaddr bind_address
unsigned short seqno
struct ast_format * format
static void ast_rtp_prop_set ( struct ast_rtp_instance instance,
enum ast_rtp_property  property,
int  value 
)
static
Precondition
instance is locked

Definition at line 8807 of file res_rtp_asterisk.c.

References ao2_ref, ast_bind(), ast_calloc, ast_data_buffer_alloc(), ast_data_buffer_free(), ast_debug_rtcp, ast_find_ourip(), ast_free_ptr(), ast_rtp_instance_get_channel_id(), ast_rtp_instance_get_data(), ast_rtp_instance_get_local_address(), ast_rtp_instance_get_remote_address, AST_RTP_INSTANCE_RTCP_STANDARD, AST_RTP_PROPERTY_ASYMMETRIC_CODEC, AST_RTP_PROPERTY_RETRANS_RECV, AST_RTP_PROPERTY_RETRANS_SEND, AST_RTP_PROPERTY_RTCP, ast_sched_del(), ast_sockaddr_copy(), ast_sockaddr_is_ipv4(), ast_sockaddr_is_ipv6(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_strdup, AST_VECTOR_FREE, AST_VECTOR_INIT, ast_rtp::asymmetric_codec, DEFAULT_RTP_RECV_BUFFER_SIZE, DEFAULT_RTP_SEND_BUFFER_SIZE, ast_rtp::ice, ast_rtp::missing_seqno, ast_rtp::recv_buffer, rtp_add_candidates_to_ice(), ast_rtcp::s, rtp_transport_wide_cc_statistics::schedid, ast_rtcp::schedid, ast_rtp::send_buffer, ast_rtcp::them, ast_rtp::transport_wide_cc, and ast_rtcp::us.

8808 {
8809  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
8810 
8811  if (property == AST_RTP_PROPERTY_RTCP) {
8812  if (value) {
8813  struct ast_sockaddr local_addr;
8814 
8815  if (rtp->rtcp && rtp->rtcp->type == value) {
8816  ast_debug_rtcp(1, "(%p) RTCP ignoring duplicate property\n", instance);
8817  return;
8818  }
8819 
8820  if (!rtp->rtcp) {
8821  rtp->rtcp = ast_calloc(1, sizeof(*rtp->rtcp));
8822  if (!rtp->rtcp) {
8823  return;
8824  }
8825  rtp->rtcp->s = -1;
8826 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
8827  rtp->rtcp->dtls.timeout_timer = -1;
8828 #endif
8829  rtp->rtcp->schedid = -1;
8830  }
8831 
8832  rtp->rtcp->type = value;
8833 
8834  /* Grab the IP address and port we are going to use */
8835  ast_rtp_instance_get_local_address(instance, &rtp->rtcp->us);
8836  if (value == AST_RTP_INSTANCE_RTCP_STANDARD) {
8837  ast_sockaddr_set_port(&rtp->rtcp->us,
8838  ast_sockaddr_port(&rtp->rtcp->us) + 1);
8839  }
8840 
8841  ast_sockaddr_copy(&local_addr, &rtp->rtcp->us);
8842  if (!ast_find_ourip(&local_addr, &rtp->rtcp->us, 0)) {
8843  ast_sockaddr_set_port(&local_addr, ast_sockaddr_port(&rtp->rtcp->us));
8844  } else {
8845  /* Failed to get local address reset to use default. */
8846  ast_sockaddr_copy(&local_addr, &rtp->rtcp->us);
8847  }
8848 
8849  ast_free(rtp->rtcp->local_addr_str);
8850  rtp->rtcp->local_addr_str = ast_strdup(ast_sockaddr_stringify(&local_addr));
8851  if (!rtp->rtcp->local_addr_str) {
8852  ast_free(rtp->rtcp);
8853  rtp->rtcp = NULL;
8854  return;
8855  }
8856 
8857  if (value == AST_RTP_INSTANCE_RTCP_STANDARD) {
8858  /* We're either setting up RTCP from scratch or
8859  * switching from MUX. Either way, we won't have
8860  * a socket set up, and we need to set it up
8861  */
8862  if ((rtp->rtcp->s =
8863  create_new_socket("RTCP",
8864  ast_sockaddr_is_ipv4(&rtp->rtcp->us) ?
8865  AF_INET :
8866  ast_sockaddr_is_ipv6(&rtp->rtcp->us) ?
8867  AF_INET6 : -1)) < 0) {
8868  ast_debug_rtcp(1, "(%p) RTCP failed to create a new socket\n", instance);
8869  ast_free(rtp->rtcp->local_addr_str);
8870  ast_free(rtp->rtcp);
8871  rtp->rtcp = NULL;
8872  return;
8873  }
8874 
8875  /* Try to actually bind to the IP address and port we are going to use for RTCP, if this fails we have to bail out */
8876  if (ast_bind(rtp->rtcp->s, &rtp->rtcp->us)) {
8877  ast_debug_rtcp(1, "(%p) RTCP failed to setup RTP instance\n", instance);
8878  close(rtp->rtcp->s);
8879  ast_free(rtp->rtcp->local_addr_str);
8880  ast_free(rtp->rtcp);
8881  rtp->rtcp = NULL;
8882  return;
8883  }
8884 #ifdef HAVE_PJPROJECT
8885  if (rtp->ice) {
8886  rtp_add_candidates_to_ice(instance, rtp, &rtp->rtcp->us, ast_sockaddr_port(&rtp->rtcp->us), AST_RTP_ICE_COMPONENT_RTCP, TRANSPORT_SOCKET_RTCP);
8887  }
8888 #endif
8889 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
8890  dtls_setup_rtcp(instance);
8891 #endif
8892  } else {
8893  struct ast_sockaddr addr;
8894  /* RTCPMUX uses the same socket as RTP. If we were previously using standard RTCP
8895  * then close the socket we previously created.
8896  *
8897  * It may seem as though there is a possible race condition here where we might try
8898  * to close the RTCP socket while it is being used to send data. However, this is not
8899  * a problem in practice since setting and adjusting of RTCP properties happens prior
8900  * to activating RTP. It is not until RTP is activated that timers start for RTCP
8901  * transmission
8902  */
8903  if (rtp->rtcp->s > -1 && rtp->rtcp->s != rtp->s) {
8904  close(rtp->rtcp->s);
8905  }
8906  rtp->rtcp->s = rtp->s;
8907  ast_rtp_instance_get_remote_address(instance, &addr);
8908  ast_sockaddr_copy(&rtp->rtcp->them, &addr);
8909 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
8910  if (rtp->rtcp->dtls.ssl && rtp->rtcp->dtls.ssl != rtp->dtls.ssl) {
8911  SSL_free(rtp->rtcp->dtls.ssl);
8912  }
8913  rtp->rtcp->dtls.ssl = rtp->dtls.ssl;
8914 #endif
8915  }
8916 
8917  ast_debug_rtcp(1, "(%s) RTCP setup on RTP instance\n",
8919  } else {
8920  if (rtp->rtcp) {
8921  if (rtp->rtcp->schedid > -1) {
8922  ao2_unlock(instance);
8923  if (!ast_sched_del(rtp->sched, rtp->rtcp->schedid)) {
8924  /* Successfully cancelled scheduler entry. */
8925  ao2_ref(instance, -1);
8926  } else {
8927  /* Unable to cancel scheduler entry */
8928  ast_debug_rtcp(1, "(%p) RTCP failed to tear down RTCP\n", instance);
8929  ao2_lock(instance);
8930  return;
8931  }
8932  ao2_lock(instance);
8933  rtp->rtcp->schedid = -1;
8934  }
8935  if (rtp->transport_wide_cc.schedid > -1) {
8936  ao2_unlock(instance);
8937  if (!ast_sched_del(rtp->sched, rtp->transport_wide_cc.schedid)) {
8938  ao2_ref(instance, -1);
8939  } else {
8940  ast_debug_rtcp(1, "(%p) RTCP failed to tear down transport-cc feedback\n", instance);
8941  ao2_lock(instance);
8942  return;
8943  }
8944  ao2_lock(instance);
8945  rtp->transport_wide_cc.schedid = -1;
8946  }
8947  if (rtp->rtcp->s > -1 && rtp->rtcp->s != rtp->s) {
8948  close(rtp->rtcp->s);
8949  }
8950 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
8951  ao2_unlock(instance);
8952  dtls_srtp_stop_timeout_timer(instance, rtp, 1);
8953  ao2_lock(instance);
8954 
8955  if (rtp->rtcp->dtls.ssl && rtp->rtcp->dtls.ssl != rtp->dtls.ssl) {
8956  SSL_free(rtp->rtcp->dtls.ssl);
8957  }
8958 #endif
8959  ast_free(rtp->rtcp->local_addr_str);
8960  ast_free(rtp->rtcp);
8961  rtp->rtcp = NULL;
8962  ast_debug_rtcp(1, "(%s) RTCP torn down on RTP instance\n",
8964  }
8965  }
8966  } else if (property == AST_RTP_PROPERTY_ASYMMETRIC_CODEC) {
8967  rtp->asymmetric_codec = value;
8968  } else if (property == AST_RTP_PROPERTY_RETRANS_SEND) {
8969  if (value) {
8970  if (!rtp->send_buffer) {
8972  }
8973  } else {
8974  if (rtp->send_buffer) {
8976  rtp->send_buffer = NULL;
8977  }
8978  }
8979  } else if (property == AST_RTP_PROPERTY_RETRANS_RECV) {
8980  if (value) {
8981  if (!rtp->recv_buffer) {
8983  AST_VECTOR_INIT(&rtp->missing_seqno, 0);
8984  }
8985  } else {
8986  if (rtp->recv_buffer) {
8988  rtp->recv_buffer = NULL;
8990  }
8991  }
8992  }
8993 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
RTP session description.
struct ast_data_buffer * ast_data_buffer_alloc(ast_data_buffer_free_callback free_fn, size_t size)
Allocate a data buffer.
Definition: data_buffer.c:145
int ast_find_ourip(struct ast_sockaddr *ourip, const struct ast_sockaddr *bindaddr, int family)
Find our IP address.
Definition: acl.c:1051
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
struct ast_data_buffer * send_buffer
struct ast_sockaddr them
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
struct rtp_transport_wide_cc_statistics transport_wide_cc
struct ast_data_buffer * recv_buffer
void ast_free_ptr(void *ptr)
free() wrapper
Definition: main/astmm.c:1739
Socket address structure.
Definition: netsock2.h:97
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
Definition: netsock2.c:590
const char * ast_rtp_instance_get_channel_id(struct ast_rtp_instance *instance)
Get the unique ID of the channel that owns this RTP instance.
Definition: rtp_engine.c:570
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
static void rtp_add_candidates_to_ice(struct ast_rtp_instance *instance, struct ast_rtp *rtp, struct ast_sockaddr *addr, int port, int component, int transport)
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ice_wrap * ice
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
struct ast_rtp::@479 missing_seqno
#define DEFAULT_RTP_RECV_BUFFER_SIZE
int ast_sched_del(struct ast_sched_context *con, int id) attribute_warn_unused_result
Deletes a scheduled event.
Definition: sched.c:614
void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the local address that we are expecting RTP on.
Definition: rtp_engine.c:665
#define DEFAULT_RTP_SEND_BUFFER_SIZE
struct ast_sockaddr us
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:497
#define ast_debug_rtcp(sublevel,...)
Log debug level RTCP information.
Definition: rtp_engine.h:3034
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1245
unsigned int asymmetric_codec
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524
void ast_data_buffer_free(struct ast_data_buffer *buffer)
Free a data buffer (and all held data payloads)
Definition: data_buffer.c:338
static int ast_rtp_qos_set ( struct ast_rtp_instance instance,
int  tos,
int  cos,
const char *  desc 
)
static
Precondition
instance is locked

Definition at line 9326 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), and ast_set_qos().

9327 {
9328  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
9329 
9330  return ast_set_qos(rtp->s, tos, cos, desc);
9331 }
RTP session description.
int ast_set_qos(int sockfd, int tos, int cos, const char *desc)
Set type of service.
Definition: netsock2.c:621
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
static struct ast_frame * ast_rtp_read ( struct ast_rtp_instance instance,
int  rtcp 
)
static
Precondition
instance is locked

Definition at line 8140 of file res_rtp_asterisk.c.

References ast_codec_media_type2str(), AST_CONTROL_SRCCHANGE, ast_data_buffer_count(), ast_data_buffer_get(), ast_data_buffer_max(), ast_data_buffer_put(), ast_data_buffer_remove(), ast_data_buffer_resize(), ast_debug, ast_debug_rtcp, ast_debug_rtp, ast_debug_stun, AST_FRAME_CONTROL, ast_frame_free(), ast_frdup, ast_free_ptr(), AST_FRIENDLY_OFFSET, AST_LIST_FIRST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_TAIL, ast_malloc, ast_null_frame, ast_rtcp_interpret(), ast_rtcp_read(), ast_rtp_codecs_get_stream_type(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_data(), ast_rtp_instance_get_prop(), ast_rtp_instance_get_remote_address, ast_rtp_instance_get_requested_target_address(), ast_rtp_instance_get_srtp(), AST_RTP_INSTANCE_RTCP_STANDARD, ast_rtp_instance_set_incoming_source_address(), ast_rtp_instance_set_remote_address, AST_RTP_PROPERTY_NAT, ast_rtp_rtcp_report_alloc(), ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_from_sin, ast_sockaddr_ipv4_mapped(), ast_sockaddr_is_ipv4(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_sockaddr_to_sin, ast_stun_handle_packet(), ast_test_suite_event_notify, ast_tvdiff_ms(), ast_tvnow(), AST_VECTOR_ADD_SORTED, AST_VECTOR_ELEM_CLEANUP_NOOP, AST_VECTOR_GET_CMP, AST_VECTOR_REMOVE_CMP_ORDERED, AST_VECTOR_RESET, AST_VECTOR_SIZE, ast_rtp_rtcp_nack_payload::buf, codecs, compare_by_value(), ast_rtp::expectedrxseqno, ast_rtp::f, find_by_value(), ast_frame::frametype, ast_frame_subclass::integer, ast_rtp::lastrxseqno, MAXIMUM_RTP_RECV_BUFFER_SIZE, ast_rtp::missing_seqno, MISSING_SEQNOS_ADDED_TRIGGER, OLD_PACKET_COUNT, rtp_learning_info::packets, ast_rtp::prevrxseqno, rtp_learning_info::proposed_address, RAII_VAR, ast_rtp::recv_buffer, rtcp_sendto(), rtp_find_instance_by_packet_source_ssrc(), rtp_recvfrom(), ast_frame::seqno, SEQNO_CYCLE_OVER, ast_rtp_rtcp_nack_payload::size, ast_rtp::ssrc_mapping, rtp_learning_info::start, rtp_learning_info::stream_type, ast_rtp::strict_rtp_address, STRICT_RTP_CLOSED, STRICT_RTP_LEARN, STRICT_RTP_LEARN_TIMEOUT, ast_rtp::strict_rtp_state, ast_frame::subclass, ast_rtcp::them, and ast_rtp::themssrc_valid.

8141 {
8142  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
8143  struct ast_srtp *srtp;
8144  RAII_VAR(struct ast_rtp_instance *, child, NULL, rtp_instance_unlock);
8145  struct ast_sockaddr addr;
8146  int res, hdrlen = 12, version, payloadtype;
8147  unsigned char *read_area = rtp->rawdata + AST_FRIENDLY_OFFSET;
8148  size_t read_area_size = sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET;
8149  unsigned int *rtpheader = (unsigned int*)(read_area), seqno, ssrc, timestamp, prev_seqno;
8150  struct ast_sockaddr remote_address = { {0,} };
8151  struct frame_list frames;
8152  struct ast_frame *frame;
8153  unsigned int bundled;
8154 
8155  /* If this is actually RTCP let's hop on over and handle it */
8156  if (rtcp) {
8157  if (rtp->rtcp && rtp->rtcp->type == AST_RTP_INSTANCE_RTCP_STANDARD) {
8158  return ast_rtcp_read(instance);
8159  }
8160  return &ast_null_frame;
8161  }
8162 
8163  /* Actually read in the data from the socket */
8164  if ((res = rtp_recvfrom(instance, read_area, read_area_size, 0,
8165  &addr)) < 0) {
8166  if (res == RTP_DTLS_ESTABLISHED) {
8167  rtp->f.frametype = AST_FRAME_CONTROL;
8169  return &rtp->f;
8170  }
8171 
8172  ast_assert(errno != EBADF);
8173  if (errno != EAGAIN) {
8174  ast_log(LOG_WARNING, "RTP Read error: %s. Hanging up.\n",
8175  (errno) ? strerror(errno) : "Unspecified");
8176  return NULL;
8177  }
8178  return &ast_null_frame;
8179  }
8180 
8181  /* If this was handled by the ICE session don't do anything */
8182  if (!res) {
8183  return &ast_null_frame;
8184  }
8185 
8186  /* This could be a multiplexed RTCP packet. If so, be sure to interpret it correctly */
8187  if (rtcp_mux(rtp, read_area)) {
8188  return ast_rtcp_interpret(instance, ast_rtp_instance_get_srtp(instance, 1), read_area, res, &addr);
8189  }
8190 
8191  /* Make sure the data that was read in is actually enough to make up an RTP packet */
8192  if (res < hdrlen) {
8193  /* If this is a keepalive containing only nulls, don't bother with a warning */
8194  int i;
8195  for (i = 0; i < res; ++i) {
8196  if (read_area[i] != '\0') {
8197  ast_log(LOG_WARNING, "RTP Read too short\n");
8198  return &ast_null_frame;
8199  }
8200  }
8201  return &ast_null_frame;
8202  }
8203 
8204  /* Get fields and verify this is an RTP packet */
8205  seqno = ntohl(rtpheader[0]);
8206 
8207  ast_rtp_instance_get_remote_address(instance, &remote_address);
8208 
8209  if (!(version = (seqno & 0xC0000000) >> 30)) {
8210  struct sockaddr_in addr_tmp;
8211  struct ast_sockaddr addr_v4;
8212  if (ast_sockaddr_is_ipv4(&addr)) {
8213  ast_sockaddr_to_sin(&addr, &addr_tmp);
8214  } else if (ast_sockaddr_ipv4_mapped(&addr, &addr_v4)) {
8215  ast_debug_stun(1, "(%p) STUN using IPv6 mapped address %s\n",
8216  instance, ast_sockaddr_stringify(&addr));
8217  ast_sockaddr_to_sin(&addr_v4, &addr_tmp);
8218  } else {
8219  ast_debug_stun(1, "(%p) STUN cannot do for non IPv4 address %s\n",
8220  instance, ast_sockaddr_stringify(&addr));
8221  return &ast_null_frame;
8222  }
8223  if ((ast_stun_handle_packet(rtp->s, &addr_tmp, read_area, res, NULL, NULL) == AST_STUN_ACCEPT) &&
8224  ast_sockaddr_isnull(&remote_address)) {
8225  ast_sockaddr_from_sin(&addr, &addr_tmp);
8226  ast_rtp_instance_set_remote_address(instance, &addr);
8227  }
8228  return &ast_null_frame;
8229  }
8230 
8231  /* If the version is not what we expected by this point then just drop the packet */
8232  if (version != 2) {
8233  return &ast_null_frame;
8234  }
8235 
8236  /* We use the SSRC to determine what RTP instance this packet is actually for */
8237  ssrc = ntohl(rtpheader[2]);
8238 
8239  /* We use the SRTP data from the provided instance that it came in on, not the child */
8240  srtp = ast_rtp_instance_get_srtp(instance, 0);
8241 
8242  /* Determine the appropriate instance for this */
8243  child = rtp_find_instance_by_packet_source_ssrc(instance, rtp, ssrc);
8244  if (!child) {
8245  /* Neither the bundled parent nor any child has this SSRC */
8246  return &ast_null_frame;
8247  }
8248  if (child != instance) {
8249  /* It is safe to hold the child lock while holding the parent lock, we guarantee that the locking order
8250  * is always parent->child or that the child lock is not held when acquiring the parent lock.
8251  */
8252  ao2_lock(child);
8253  instance = child;
8254  rtp = ast_rtp_instance_get_data(instance);
8255  } else {
8256  /* The child is the parent! We don't need to unlock it. */
8257  child = NULL;
8258  }
8259 
8260  /* If strict RTP protection is enabled see if we need to learn the remote address or if we need to drop the packet */
8261  switch (rtp->strict_rtp_state) {
8262  case STRICT_RTP_LEARN:
8263  /*
8264  * Scenario setup:
8265  * PartyA -- Ast1 -- Ast2 -- PartyB
8266  *
8267  * The learning timeout is necessary for Ast1 to handle the above
8268  * setup where PartyA calls PartyB and Ast2 initiates direct media
8269  * between Ast1 and PartyB. Ast1 may lock onto the Ast2 stream and
8270  * never learn the PartyB stream when it starts. The timeout makes
8271  * Ast1 stay in the learning state long enough to see and learn the
8272  * RTP stream from PartyB.
8273  *
8274  * To mitigate against attack, the learning state cannot switch
8275  * streams while there are competing streams. The competing streams
8276  * interfere with each other's qualification. Once we accept a
8277  * stream and reach the timeout, an attacker cannot interfere
8278  * anymore.
8279  *
8280  * Here are a few scenarios and each one assumes that the streams
8281  * are continuous:
8282  *
8283  * 1) We already have a known stream source address and the known
8284  * stream wants to change to a new source address. An attacking
8285  * stream will block learning the new stream source. After the
8286  * timeout we re-lock onto the original stream source address which
8287  * likely went away. The result is one way audio.
8288  *
8289  * 2) We already have a known stream source address and the known
8290  * stream doesn't want to change source addresses. An attacking
8291  * stream will not be able to replace the known stream. After the
8292  * timeout we re-lock onto the known stream. The call is not
8293  * affected.
8294  *
8295  * 3) We don't have a known stream source address. This presumably
8296  * is the start of a call. Competing streams will result in staying
8297  * in learning mode until a stream becomes the victor and we reach
8298  * the timeout. We cannot exit learning if we have no known stream
8299  * to lock onto. The result is one way audio until there is a victor.
8300  *
8301  * If we learn a stream source address before the timeout we will be
8302  * in scenario 1) or 2) when a competing stream starts.
8303  */
8305  && STRICT_RTP_LEARN_TIMEOUT < ast_tvdiff_ms(ast_tvnow(), rtp->rtp_source_learn.start)) {
8306  ast_verb(4, "%p -- Strict RTP learning complete - Locking on source address %s\n",
8308  ast_test_suite_event_notify("STRICT_RTP_LEARN", "Source: %s",
8311  } else {
8312  struct ast_sockaddr target_address;
8313 
8314  if (!ast_sockaddr_cmp(&rtp->strict_rtp_address, &addr)) {
8315  /*
8316  * We are open to learning a new address but have received
8317  * traffic from the current address, accept it and reset
8318  * the learning counts for a new source. When no more
8319  * current source packets arrive a new source can take over
8320  * once sufficient traffic is received.
8321  */
8322  rtp_learning_seq_init(&rtp->rtp_source_learn, seqno);
8323  break;
8324  }
8325 
8326  /*
8327  * We give preferential treatment to the requested target address
8328  * (negotiated SDP address) where we are to send our RTP. However,
8329  * the other end has no obligation to send from that address even
8330  * though it is practically a requirement when NAT is involved.
8331  */
8332  ast_rtp_instance_get_requested_target_address(instance, &target_address);
8333  if (!ast_sockaddr_cmp(&target_address, &addr)) {
8334  /* Accept the negotiated target RTP stream as the source */
8335  ast_verb(4, "%p -- Strict RTP switching to RTP target address %s as source\n",
8336  rtp, ast_sockaddr_stringify(&addr));
8337  ast_sockaddr_copy(&rtp->strict_rtp_address, &addr);
8338  rtp_learning_seq_init(&rtp->rtp_source_learn, seqno);
8339  break;
8340  }
8341 
8342  /*
8343  * Trying to learn a new address. If we pass a probationary period
8344  * with it, that means we've stopped getting RTP from the original
8345  * source and we should switch to it.
8346  */
8347  if (!ast_sockaddr_cmp(&rtp->rtp_source_learn.proposed_address, &addr)) {
8348  if (rtp->rtp_source_learn.stream_type == AST_MEDIA_TYPE_UNKNOWN) {
8349  struct ast_rtp_codecs *codecs;
8350 
8351  codecs = ast_rtp_instance_get_codecs(instance);
8352  rtp->rtp_source_learn.stream_type =
8354  ast_verb(4, "%p -- Strict RTP qualifying stream type: %s\n",
8355  rtp, ast_codec_media_type2str(rtp->rtp_source_learn.stream_type));
8356  }
8357  if (!rtp_learning_rtp_seq_update(&rtp->rtp_source_learn, seqno)) {
8358  /* Accept the new RTP stream */
8359  ast_verb(4, "%p -- Strict RTP switching source address to %s\n",
8360  rtp, ast_sockaddr_stringify(&addr));
8361  ast_sockaddr_copy(&rtp->strict_rtp_address, &addr);
8362  rtp_learning_seq_init(&rtp->rtp_source_learn, seqno);
8363  break;
8364  }
8365  /* Not ready to accept the RTP stream candidate */
8366  ast_debug_rtp(1, "(%p) RTP %p -- Received packet from %s, dropping due to strict RTP protection. Will switch to it in %d packets.\n",
8367  instance, rtp, ast_sockaddr_stringify(&addr), rtp->rtp_source_learn.packets);
8368  } else {
8369  /*
8370  * This is either an attacking stream or
8371  * the start of the expected new stream.
8372  */
8373  ast_sockaddr_copy(&rtp->rtp_source_learn.proposed_address, &addr);
8374  rtp_learning_seq_init(&rtp->rtp_source_learn, seqno);
8375  ast_debug_rtp(1, "(%p) RTP %p -- Received packet from %s, dropping due to strict RTP protection. Qualifying new stream.\n",
8376  instance, rtp, ast_sockaddr_stringify(&addr));
8377  }
8378  return &ast_null_frame;
8379  }
8380  /* Fall through */
8381  case STRICT_RTP_CLOSED:
8382  /*
8383  * We should not allow a stream address change if the SSRC matches
8384  * once strictrtp learning is closed. Any kind of address change
8385  * like this should have happened while we were in the learning
8386  * state. We do not want to allow the possibility of an attacker
8387  * interfering with the RTP stream after the learning period.
8388  * An attacker could manage to get an RTCP packet redirected to
8389  * them which can contain the SSRC value.
8390  */
8391  if (!ast_sockaddr_cmp(&rtp->strict_rtp_address, &addr)) {
8392  break;
8393  }
8394  ast_debug_rtp(1, "(%p) RTP %p -- Received packet from %s, dropping due to strict RTP protection.\n",
8395  instance, rtp, ast_sockaddr_stringify(&addr));
8396 #ifdef TEST_FRAMEWORK
8397  {
8398  static int strict_rtp_test_event = 1;
8399  if (strict_rtp_test_event) {
8400  ast_test_suite_event_notify("STRICT_RTP_CLOSED", "Source: %s",
8401  ast_sockaddr_stringify(&addr));
8402  strict_rtp_test_event = 0; /* Only run this event once to prevent possible spam */
8403  }
8404  }
8405 #endif
8406  return &ast_null_frame;
8407  case STRICT_RTP_OPEN:
8408  break;
8409  }
8410 
8411  /* If symmetric RTP is enabled see if the remote side is not what we expected and change where we are sending audio */
8413  if (ast_sockaddr_cmp(&remote_address, &addr)) {
8414  /* do not update the originally given address, but only the remote */
8416  ast_sockaddr_copy(&remote_address, &addr);
8417  if (rtp->rtcp && rtp->rtcp->type == AST_RTP_INSTANCE_RTCP_STANDARD) {
8418  ast_sockaddr_copy(&rtp->rtcp->them, &addr);
8419  ast_sockaddr_set_port(&rtp->rtcp->them, ast_sockaddr_port(&addr) + 1);
8420  }
8421  ast_set_flag(rtp, FLAG_NAT_ACTIVE);
8422  if (ast_debug_rtp_packet_is_allowed)
8423  ast_debug(0, "(%p) RTP NAT: Got audio from other end. Now sending to address %s\n",
8424  instance, ast_sockaddr_stringify(&remote_address));
8425  }
8426  }
8427 
8428  /* Pull out the various other fields we will need */
8429  payloadtype = (seqno & 0x7f0000) >> 16;
8430  seqno &= 0xffff;
8431  timestamp = ntohl(rtpheader[1]);
8432 
8433 #ifdef AST_DEVMODE
8434  if (should_drop_packets(&addr)) {
8435  ast_debug(0, "(%p) RTP: drop received packet from %s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6d)\n",
8436  instance, ast_sockaddr_stringify(&addr), payloadtype, seqno, timestamp, res - hdrlen);
8437  return &ast_null_frame;
8438  }
8439 #endif
8440 
8441  if (rtp_debug_test_addr(&addr)) {
8442  ast_verbose("Got RTP packet from %s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6d)\n",
8443  ast_sockaddr_stringify(&addr),
8444  payloadtype, seqno, timestamp, res - hdrlen);
8445  }
8446 
8447  AST_LIST_HEAD_INIT_NOLOCK(&frames);
8448 
8449  bundled = (child || AST_VECTOR_SIZE(&rtp->ssrc_mapping)) ? 1 : 0;
8450 
8451  prev_seqno = rtp->lastrxseqno;
8452  /* We need to save lastrxseqno for use by jitter before resetting it. */
8453  rtp->prevrxseqno = rtp->lastrxseqno;
8454  rtp->lastrxseqno = seqno;
8455 
8456  if (!rtp->recv_buffer) {
8457  /* If there is no receive buffer then we can pass back the frame directly */
8458  frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled);
8459  AST_LIST_INSERT_TAIL(&frames, frame, frame_list);
8460  return AST_LIST_FIRST(&frames);
8461  } else if (rtp->expectedrxseqno == -1 || seqno == rtp->expectedrxseqno) {
8462  rtp->expectedrxseqno = seqno + 1;
8463 
8464  /* We've cycled over, so go back to 0 */
8465  if (rtp->expectedrxseqno == SEQNO_CYCLE_OVER) {
8466  rtp->expectedrxseqno = 0;
8467  }
8468 
8469  /* If there are no buffered packets that will be placed after this frame then we can
8470  * return it directly without duplicating it.
8471  */
8472  if (!ast_data_buffer_count(rtp->recv_buffer)) {
8473  frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled);
8474  AST_LIST_INSERT_TAIL(&frames, frame, frame_list);
8475  return AST_LIST_FIRST(&frames);
8476  }
8477 
8480  ast_debug_rtp(2, "(%p) RTP Packet with sequence number '%d' on instance is no longer missing\n",
8481  instance, seqno);
8482  }
8483 
8484  /* If we don't have the next packet after this we can directly return the frame, as there is no
8485  * chance it will be overwritten.
8486  */
8487  if (!ast_data_buffer_get(rtp->recv_buffer, rtp->expectedrxseqno)) {
8488  frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled);
8489  AST_LIST_INSERT_TAIL(&frames, frame, frame_list);
8490  return AST_LIST_FIRST(&frames);
8491  }
8492 
8493  /* Otherwise we need to dupe the frame so that the potential processing of frames placed after
8494  * it do not overwrite the data. You may be thinking that we could just add the current packet
8495  * to the head of the frames list and avoid having to duplicate it but this would result in out
8496  * of order packet processing by libsrtp which we are trying to avoid.
8497  */
8498  frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled));
8499  if (frame) {
8500  AST_LIST_INSERT_TAIL(&frames, frame, frame_list);
8501  prev_seqno = seqno;
8502  }
8503 
8504  /* Add any additional packets that we have buffered and that are available */
8505  while (ast_data_buffer_count(rtp->recv_buffer)) {
8506  struct ast_rtp_rtcp_nack_payload *payload;
8507 
8509  if (!payload) {
8510  break;
8511  }
8512 
8513  frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, payload->buf, payload->size, prev_seqno, bundled));
8514  ast_free(payload);
8515 
8516  if (!frame) {
8517  /* If this packet can't be interpreted due to being out of memory we return what we have and assume
8518  * that we will determine it is a missing packet later and NACK for it.
8519  */
8520  return AST_LIST_FIRST(&frames);
8521  }
8522 
8523  ast_debug_rtp(2, "(%p) RTP pulled buffered packet with sequence number '%d' to additionally return\n",
8524  instance, frame->seqno);
8525  AST_LIST_INSERT_TAIL(&frames, frame, frame_list);
8526  prev_seqno = rtp->expectedrxseqno;
8527  rtp->expectedrxseqno++;
8528  if (rtp->expectedrxseqno == SEQNO_CYCLE_OVER) {
8529  rtp->expectedrxseqno = 0;
8530  }
8531  }
8532 
8533  return AST_LIST_FIRST(&frames);
8534  } else if ((((seqno - rtp->expectedrxseqno) > 100) && timestamp > rtp->lastividtimestamp) ||
8536  int inserted = 0;
8537 
8538  /* We have a large number of outstanding buffered packets or we've jumped far ahead in time.
8539  * To compensate we dump what we have in the buffer and place the current packet in a logical
8540  * spot. In the case of video we also require a full frame to give the decoding side a fighting
8541  * chance.
8542  */
8543 
8544  if (rtp->rtp_source_learn.stream_type == AST_MEDIA_TYPE_VIDEO) {
8545  ast_debug_rtp(2, "(%p) RTP source has wild gap or packet loss, sending FIR\n",
8546  instance);
8547  rtp_write_rtcp_fir(instance, rtp, &remote_address);
8548  }
8549 
8550  /* This works by going through the progression of the sequence number retrieving buffered packets
8551  * or inserting the current received packet until we've run out of packets. This ensures that the
8552  * packets are in the correct sequence number order.
8553  */
8554  while (ast_data_buffer_count(rtp->recv_buffer)) {
8555  struct ast_rtp_rtcp_nack_payload *payload;
8556 
8557  /* If the packet we received is the one we are expecting at this point then add it in */
8558  if (rtp->expectedrxseqno == seqno) {
8559  frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled));
8560  if (frame) {
8561  AST_LIST_INSERT_TAIL(&frames, frame, frame_list);
8562  prev_seqno = seqno;
8563  ast_debug_rtp(2, "(%p) RTP inserted just received packet with sequence number '%d' in correct order\n",
8564  instance, seqno);
8565  }
8566  /* It is possible due to packet retransmission for this packet to also exist in the receive
8567  * buffer so we explicitly remove it in case this occurs, otherwise the receive buffer will
8568  * never be empty.
8569  */
8570  payload = (struct ast_rtp_rtcp_nack_payload *)ast_data_buffer_remove(rtp->recv_buffer, seqno);
8571  if (payload) {
8572  ast_free(payload);
8573  }
8574  rtp->expectedrxseqno++;
8575  if (rtp->expectedrxseqno == SEQNO_CYCLE_OVER) {
8576  rtp->expectedrxseqno = 0;
8577  }
8578  inserted = 1;
8579  continue;
8580  }
8581 
8583  if (payload) {
8584  frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, payload->buf, payload->size, prev_seqno, bundled));
8585  if (frame) {
8586  AST_LIST_INSERT_TAIL(&frames, frame, frame_list);
8587  prev_seqno = rtp->expectedrxseqno;
8588  ast_debug_rtp(2, "(%p) RTP emptying queue and returning packet with sequence number '%d'\n",
8589  instance, frame->seqno);
8590  }
8591  ast_free(payload);
8592  }
8593 
8594  rtp->expectedrxseqno++;
8595  if (rtp->expectedrxseqno == SEQNO_CYCLE_OVER) {
8596  rtp->expectedrxseqno = 0;
8597  }
8598  }
8599 
8600  if (!inserted) {
8601  /* This current packet goes after them, and we assume that packets going forward will follow
8602  * that new sequence number increment. It is okay for this to not be duplicated as it is guaranteed
8603  * to be the last packet processed right now and it is also guaranteed that it will always return
8604  * non-NULL.
8605  */
8606  frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled);
8607  AST_LIST_INSERT_TAIL(&frames, frame, frame_list);
8608  rtp->expectedrxseqno = seqno + 1;
8609  if (rtp->expectedrxseqno == SEQNO_CYCLE_OVER) {
8610  rtp->expectedrxseqno = 0;
8611  }
8612 
8613  ast_debug_rtp(2, "(%p) RTP adding just received packet with sequence number '%d' to end of dumped queue\n",
8614  instance, seqno);
8615  }
8616 
8617  /* When we flush increase our chance for next time by growing the receive buffer when possible
8618  * by how many packets we missed, to give ourselves a bit more breathing room.
8619  */
8622  ast_debug_rtp(2, "(%p) RTP receive buffer is now at maximum of %zu\n", instance, ast_data_buffer_max(rtp->recv_buffer));
8623 
8624  /* As there is such a large gap we don't want to flood the order side with missing packets, so we
8625  * give up and start anew.
8626  */
8628 
8629  return AST_LIST_FIRST(&frames);
8630  }
8631 
8632  /* We're finished with the frames list */
8633  ast_frame_free(AST_LIST_FIRST(&frames), 0);
8634 
8635  /* Determine if the received packet is from the last OLD_PACKET_COUNT (1000 by default) packets or not.
8636  * For the case where the received sequence number exceeds that of the expected sequence number we calculate
8637  * the past sequence number that would be 1000 sequence numbers ago. If the received sequence number
8638  * exceeds or meets that then it is within OLD_PACKET_COUNT packets ago. For example if the expected
8639  * sequence number is 100 and we receive 65530, then it would be considered old. This is because
8640  * 65535 - 1000 + 100 = 64635 which gives us the sequence number at which we would consider the packets
8641  * old. Since 65530 is above that, it would be considered old.
8642  * For the case where the received sequence number is less than the expected sequence number we can do
8643  * a simple subtraction to see if it is 1000 packets ago or not.
8644  */
8645  if ((seqno < rtp->expectedrxseqno && ((rtp->expectedrxseqno - seqno) <= OLD_PACKET_COUNT)) ||
8646  (seqno > rtp->expectedrxseqno && (seqno >= (65535 - OLD_PACKET_COUNT + rtp->expectedrxseqno)))) {
8647  /* If this is a packet from the past then we have received a duplicate packet, so just drop it */
8648  ast_debug_rtp(2, "(%p) RTP received an old packet with sequence number '%d', dropping it\n",
8649  instance, seqno);
8650  return &ast_null_frame;
8651  } else if (ast_data_buffer_get(rtp->recv_buffer, seqno)) {
8652  /* If this is a packet we already have buffered then it is a duplicate, so just drop it */
8653  ast_debug_rtp(2, "(%p) RTP received a duplicate transmission of packet with sequence number '%d', dropping it\n",
8654  instance, seqno);
8655  return &ast_null_frame;
8656  } else {
8657  /* This is an out of order packet from the future */
8658  struct ast_rtp_rtcp_nack_payload *payload;
8659  int missing_seqno;
8660  int remove_failed;
8661  unsigned int missing_seqnos_added = 0;
8662 
8663  ast_debug_rtp(2, "(%p) RTP received an out of order packet with sequence number '%d' while expecting '%d' from the future\n",
8664  instance, seqno, rtp->expectedrxseqno);
8665 
8666  payload = ast_malloc(sizeof(*payload) + res);
8667  if (!payload) {
8668  /* If the payload can't be allocated then we can't defer this packet right now.
8669  * Instead of dumping what we have we pretend we lost this packet. It will then
8670  * get NACKed later or the existing buffer will be returned entirely. Well, we may
8671  * try since we're seemingly out of memory. It's a bad situation all around and
8672  * packets are likely to get lost anyway.
8673  */
8674  return &ast_null_frame;
8675  }
8676 
8677  payload->size = res;
8678  memcpy(payload->buf, rtpheader, res);
8679  if (ast_data_buffer_put(rtp->recv_buffer, seqno, payload) == -1) {
8680  ast_free(payload);
8681  }
8682 
8683  /* If this sequence number is removed that means we had a gap and this packet has filled it in
8684  * some. Since it was part of the gap we will have already added any other missing sequence numbers
8685  * before it (and possibly after it) to the vector so we don't need to do that again. Note that
8686  * remove_failed will be set to -1 if the sequence number isn't removed, and 0 if it is.
8687  */
8688  remove_failed = AST_VECTOR_REMOVE_CMP_ORDERED(&rtp->missing_seqno, seqno, find_by_value,
8690  if (!remove_failed) {
8691  ast_debug_rtp(2, "(%p) RTP packet with sequence number '%d' is no longer missing\n",
8692  instance, seqno);
8693  }
8694 
8695  /* The missing sequence number code works by taking the sequence number of the
8696  * packet we've just received and going backwards until we hit the sequence number
8697  * of the last packet we've received. While doing so we check to make sure that the
8698  * sequence number is not already missing and that it is not already buffered.
8699  */
8700  missing_seqno = seqno;
8701  while (remove_failed) {
8702  missing_seqno -= 1;
8703 
8704  /* If we've cycled backwards then start back at the top */
8705  if (missing_seqno < 0) {
8706  missing_seqno = 65535;
8707  }
8708 
8709  /* We've gone backwards enough such that we've hit the previous sequence number */
8710  if (missing_seqno == prev_seqno) {
8711  break;
8712  }
8713 
8714  /* We don't want missing sequence number duplicates. If, for some reason,
8715  * packets are really out of order, we could end up in this scenario:
8716  *
8717  * We are expecting sequence number 100
8718  * We receive sequence number 105
8719  * Sequence numbers 100 through 104 get added to the vector
8720  * We receive sequence number 101 (this section is skipped)
8721  * We receive sequence number 103
8722  * Sequence number 102 is added to the vector
8723  *
8724  * This will prevent the duplicate from being added.
8725  */
8726  if (AST_VECTOR_GET_CMP(&rtp->missing_seqno, missing_seqno,
8727  find_by_value)) {
8728  continue;
8729  }
8730 
8731  /* If this packet has been buffered already then don't count it amongst the
8732  * missing.
8733  */
8734  if (ast_data_buffer_get(rtp->recv_buffer, missing_seqno)) {
8735  continue;
8736  }
8737 
8738  ast_debug_rtp(2, "(%p) RTP added missing sequence number '%d'\n",
8739  instance, missing_seqno);
8740  AST_VECTOR_ADD_SORTED(&rtp->missing_seqno, missing_seqno,
8742  missing_seqnos_added++;
8743  }
8744 
8745  /* When we add a large number of missing sequence numbers we assume there was a substantial
8746  * gap in reception so we trigger an immediate NACK. When our data buffer is 1/4 full we
8747  * assume that the packets aren't just out of order but have actually been lost. At 1/2
8748  * full we get more aggressive and ask for retransmission when we get a new packet.
8749  * To get them back we construct and send a NACK causing the sender to retransmit them.
8750  */
8751  if (missing_seqnos_added >= MISSING_SEQNOS_ADDED_TRIGGER ||
8754  int packet_len = 0;
8755  int res = 0;
8756  int ice;
8757  int sr;
8758  size_t data_size = AST_UUID_STR_LEN + 128 + (AST_VECTOR_SIZE(&rtp->missing_seqno) * 4);
8759  RAII_VAR(unsigned char *, rtcpheader, NULL, ast_free_ptr);
8760  RAII_VAR(struct ast_rtp_rtcp_report *, rtcp_report,
8762  ao2_cleanup);
8763 
8764  /* Sufficient space for RTCP headers and report, SDES with CNAME, NACK header,
8765  * and worst case 4 bytes per missing sequence number.
8766  */
8767  rtcpheader = ast_malloc(sizeof(*rtcpheader) + data_size);
8768  if (!rtcpheader) {
8769  ast_debug_rtcp(1, "(%p) RTCP failed to allocate memory for NACK\n", instance);
8770  return &ast_null_frame;
8771  }
8772 
8773  memset(rtcpheader, 0, data_size);
8774 
8775  res = ast_rtcp_generate_compound_prefix(instance, rtcpheader, rtcp_report, &sr);
8776 
8777  if (res == 0 || res == 1) {
8778  return &ast_null_frame;
8779  }
8780 
8781  packet_len += res;
8782 
8783  res = ast_rtcp_generate_nack(instance, rtcpheader + packet_len);
8784 
8785  if (res == 0) {
8786  ast_debug_rtcp(1, "(%p) RTCP failed to construct NACK, stopping here\n", instance);
8787  return &ast_null_frame;
8788  }
8789 
8790  packet_len += res;
8791 
8792  res = rtcp_sendto(instance, rtcpheader, packet_len, 0, &remote_address, &ice);
8793  if (res < 0) {
8794  ast_debug_rtcp(1, "(%p) RTCP failed to send NACK request out\n", instance);
8795  } else {
8796  ast_debug_rtcp(2, "(%p) RTCP sending a NACK request to get missing packets\n", instance);
8797  /* Update RTCP SR/RR statistics */
8798  ast_rtcp_calculate_sr_rr_statistics(instance, rtcp_report, remote_address, ice, sr);
8799  }
8800  }
8801  }
8802 
8803  return &ast_null_frame;
8804 }
An object that represents data sent during a SR/RR RTCP report.
Definition: rtp_engine.h:361
RTP session description.
#define ast_frdup(fr)
Copies a frame.
#define AST_VECTOR_ADD_SORTED(vec, elem, cmp)
Add an element into a sorted vector.
Definition: vector.h:371
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421
enum strict_rtp_state strict_rtp_state
void * ast_data_buffer_remove(struct ast_data_buffer *buffer, size_t pos)
Remove a data payload from the data buffer.
Definition: data_buffer.c:299
#define SEQNO_CYCLE_OVER
Structure for storing RTP packets for retransmission.
#define OLD_PACKET_COUNT
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
static int compare_by_value(int elem, int value)
Helper function to compare an elem in a vector by value.
#define MISSING_SEQNOS_ADDED_TRIGGER
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:749
struct ast_sockaddr proposed_address
int ast_sockaddr_ipv4_mapped(const struct ast_sockaddr *addr, struct ast_sockaddr *ast_mapped)
Convert an IPv4-mapped IPv6 address into an IPv4 address.
Definition: netsock2.c:37
struct ast_sockaddr them
const char * ast_codec_media_type2str(enum ast_media_type type)
Conversion function to take a media type and turn it into a string.
Definition: codec.c:348
static struct ast_rtp_instance * rtp_find_instance_by_packet_source_ssrc(struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned int ssrc)
struct ast_srtp * ast_rtp_instance_get_srtp(struct ast_rtp_instance *instance, int rtcp)
Obtain the SRTP instance associated with an RTP instance.
Definition: rtp_engine.c:2911
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
struct ast_data_buffer * recv_buffer
int ast_stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *data, size_t len, stun_cb_f *stun_cb, void *arg)
handle an incoming STUN message.
Definition: stun.c:293
void ast_free_ptr(void *ptr)
free() wrapper
Definition: main/astmm.c:1739
Socket address structure.
Definition: netsock2.h:97
struct ast_frame_subclass subclass
int ast_data_buffer_put(struct ast_data_buffer *buffer, size_t pos, void *payload)
Place a data payload at a position in the data buffer.
Definition: data_buffer.c:203
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:778
#define AST_VECTOR_ELEM_CLEANUP_NOOP(elem)
Vector element cleanup that does nothing.
Definition: vector.h:571
static struct ao2_container * codecs
Registered codecs.
Definition: codec.c:48
#define MAXIMUM_RTP_RECV_BUFFER_SIZE
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_rtp::@480 ssrc_mapping
unsigned int themssrc_valid
void * ast_data_buffer_get(const struct ast_data_buffer *buffer, size_t pos)
Retrieve a data payload from the data buffer.
Definition: data_buffer.c:269
#define STRICT_RTP_LEARN_TIMEOUT
Strict RTP learning timeout time in milliseconds.
struct ast_rtp_rtcp_report * ast_rtp_rtcp_report_alloc(unsigned int report_blocks)
Allocate an ao2 ref counted instance of ast_rtp_rtcp_report.
Definition: rtp_engine.c:3627
static struct ast_frame * ast_rtcp_interpret(struct ast_rtp_instance *instance, struct ast_srtp *srtp, const unsigned char *rtcpdata, size_t size, struct ast_sockaddr *addr)
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:189
#define ast_debug_stun(sublevel,...)
Log debug level STUN information.
Definition: stun.h:54
static int rtp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
int expectedrxseqno
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
struct timeval start
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
#define ast_rtp_instance_set_remote_address(instance, address)
Set the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1133
static struct ast_frame * ast_rtcp_read(struct ast_rtp_instance *instance)
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
Definition: vector.h:625
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
enum ast_media_type stream_type
struct ast_rtp::@479 missing_seqno
struct ast_sockaddr strict_rtp_address
struct ast_frame f
#define AST_VECTOR_GET_CMP(vec, value, cmp)
Get an element from a vector that matches the given comparison.
Definition: vector.h:731
#define AST_VECTOR_REMOVE_CMP_ORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison while maintaining order...
Definition: vector.h:540
struct ast_frame ast_null_frame
Definition: main/frame.c:79
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
#define ast_debug_rtp(sublevel,...)
Log debug level RTP information.
Definition: rtp_engine.h:3017
size_t ast_data_buffer_count(const struct ast_data_buffer *buffer)
Return the number of payloads in a data buffer.
Definition: data_buffer.c:356
void ast_rtp_instance_get_requested_target_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the requested target address of the remote endpoint.
Definition: rtp_engine.c:695
int ast_rtp_instance_get_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property)
Get the value of an RTP instance property.
Definition: rtp_engine.c:738
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:497
Data structure associated with a single frame of data.
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:765
enum ast_frame_type frametype
static int rtcp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int *ice)
#define ast_debug_rtcp(sublevel,...)
Log debug level RTCP information.
Definition: rtp_engine.h:3034
void ast_data_buffer_resize(struct ast_data_buffer *buffer, size_t size)
Resize a data buffer.
Definition: data_buffer.c:168
enum ast_media_type ast_rtp_codecs_get_stream_type(struct ast_rtp_codecs *codecs)
Determine the type of RTP stream media from the codecs mapped.
Definition: rtp_engine.c:1514
static int find_by_value(int elem, int value)
Helper function to find an elem in a vector by value.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1245
size_t ast_data_buffer_max(const struct ast_data_buffer *buffer)
Return the maximum number of payloads a data buffer can hold.
Definition: data_buffer.c:363
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
int ast_rtp_instance_set_incoming_source_address(struct ast_rtp_instance *instance, const struct ast_sockaddr *address)
Set the incoming source address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:628
void ast_frame_free(struct ast_frame *frame, int cache)
Frees a frame or list of frames.
Definition: main/frame.c:176
static void ast_rtp_remote_address_set ( struct ast_rtp_instance instance,
struct ast_sockaddr addr 
)
static
Precondition
instance is locked

Definition at line 9004 of file res_rtp_asterisk.c.

References ast_debug_rtcp, ast_ouraddrfor(), ast_rtp_instance_get_data(), ast_rtp_instance_get_local_address(), AST_RTP_INSTANCE_RTCP_STANDARD, ast_rtp_instance_set_local_address(), ast_rtp_instance_set_remote_address, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_strdup, AST_VECTOR_GET_ADDR, AST_VECTOR_SIZE, rtp_ssrc_mapping::instance, ast_rtp::last_end_timestamp, ast_rtp::last_seqno, rtp_learning_start(), ast_rtp::ssrc_mapping, ast_rtp::strict_rtp_address, ast_rtp::strict_rtp_state, strictrtp, ast_rtcp::them, and ast_rtcp::us.

9005 {
9006  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
9007  struct ast_sockaddr local;
9008  int index;
9009 
9010  ast_rtp_instance_get_local_address(instance, &local);
9011  if (!ast_sockaddr_isnull(addr)) {
9012  /* Update the local RTP address with what is being used */
9013  if (ast_ouraddrfor(addr, &local)) {
9014  /* Failed to update our address so reuse old local address */
9015  ast_rtp_instance_get_local_address(instance, &local);
9016  } else {
9017  ast_rtp_instance_set_local_address(instance, &local);
9018  }
9019  }
9020 
9021  if (rtp->rtcp && !ast_sockaddr_isnull(addr)) {
9022  ast_debug_rtcp(1, "(%p) RTCP setting address on RTP instance\n", instance);
9023  ast_sockaddr_copy(&rtp->rtcp->them, addr);
9024 
9025  if (rtp->rtcp->type == AST_RTP_INSTANCE_RTCP_STANDARD) {
9026  ast_sockaddr_set_port(&rtp->rtcp->them, ast_sockaddr_port(addr) + 1);
9027 
9028  /* Update the local RTCP address with what is being used */
9029  ast_sockaddr_set_port(&local, ast_sockaddr_port(&local) + 1);
9030  }
9031  ast_sockaddr_copy(&rtp->rtcp->us, &local);
9032 
9033  ast_free(rtp->rtcp->local_addr_str);
9034  rtp->rtcp->local_addr_str = ast_strdup(ast_sockaddr_stringify(&local));
9035  }
9036 
9037  /* Update any bundled RTP instances */
9038  for (index = 0; index < AST_VECTOR_SIZE(&rtp->ssrc_mapping); ++index) {
9039  struct rtp_ssrc_mapping *mapping = AST_VECTOR_GET_ADDR(&rtp->ssrc_mapping, index);
9040 
9042  }
9043 
9044  /* Need to reset the DTMF last sequence number and the timestamp of the last END packet */
9045  rtp->last_seqno = 0;
9046  rtp->last_end_timestamp.ts = 0;
9047  rtp->last_end_timestamp.is_set = 0;
9048 
9049  if (strictrtp && rtp->strict_rtp_state != STRICT_RTP_OPEN
9050  && !ast_sockaddr_isnull(addr) && ast_sockaddr_cmp(addr, &rtp->strict_rtp_address)) {
9051  /* We only need to learn a new strict source address if we've been told the source is
9052  * changing to something different.
9053  */
9054  ast_verb(4, "%p -- Strict RTP learning after remote address set to: %s\n",
9055  rtp, ast_sockaddr_stringify(addr));
9056  rtp_learning_start(rtp);
9057  }
9058 }
struct ast_rtp_instance * instance
The RTP instance this SSRC belongs to.
RTP session description.
Structure used for mapping an incoming SSRC to an RTP instance.
enum strict_rtp_state strict_rtp_state
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
struct ast_sockaddr them
static void rtp_learning_start(struct ast_rtp *rtp)
Start the strictrtp learning mode.
optional_ts last_end_timestamp
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
Socket address structure.
Definition: netsock2.h:97
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
int ast_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us)
Get our local IP address when contacting a remote host.
Definition: acl.c:1004
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
Definition: vector.h:668
struct ast_rtp::@480 ssrc_mapping
int ast_rtp_instance_set_local_address(struct ast_rtp_instance *instance, const struct ast_sockaddr *address)
Set the address that we are expecting to receive RTP on.
Definition: rtp_engine.c:610
static int strictrtp
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
#define ast_rtp_instance_set_remote_address(instance, address)
Set the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1133
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
struct ast_sockaddr strict_rtp_address
void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the local address that we are expecting RTP on.
Definition: rtp_engine.c:665
struct ast_sockaddr us
unsigned int last_seqno
#define ast_debug_rtcp(sublevel,...)
Log debug level RTCP information.
Definition: rtp_engine.h:3034
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
static int ast_rtp_rtcp_handle_nack ( struct ast_rtp_instance instance,
unsigned int *  nackdata,
unsigned int  position,
unsigned int  length 
)
static
Precondition
instance is locked

Definition at line 6448 of file res_rtp_asterisk.c.

References ast_data_buffer_get(), ast_data_buffer_max(), ast_data_buffer_resize(), ast_debug_rtcp, AST_RTP_EXTENSION_ABS_SEND_TIME, ast_rtp_instance_extmap_get_id(), ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address, ast_tvnow(), ast_rtp_rtcp_nack_payload::buf, ast_rtp::ice, MAXIMUM_RTP_SEND_BUFFER_SIZE, rtp_sendto(), ast_rtp::send_buffer, and ast_rtp_rtcp_nack_payload::size.

Referenced by ast_rtcp_interpret().

6450 {
6451  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
6452  int res = 0;
6453  int blp_index;
6454  int packet_index;
6455  int ice;
6456  struct ast_rtp_rtcp_nack_payload *payload;
6457  unsigned int current_word;
6458  unsigned int pid; /* Packet ID which refers to seqno of lost packet */
6459  unsigned int blp; /* Bitmask of following lost packets */
6460  struct ast_sockaddr remote_address = { {0,} };
6461  int abs_send_time_id;
6462  unsigned int now_msw = 0;
6463  unsigned int now_lsw = 0;
6464  unsigned int packets_not_found = 0;
6465 
6466  if (!rtp->send_buffer) {
6467  ast_debug_rtcp(1, "(%p) RTCP tried to handle NACK request, "
6468  "but we don't have a RTP packet storage!\n", instance);
6469  return res;
6470  }
6471 
6473  if (abs_send_time_id != -1) {
6474  timeval2ntp(ast_tvnow(), &now_msw, &now_lsw);
6475  }
6476 
6477  ast_rtp_instance_get_remote_address(instance, &remote_address);
6478 
6479  /*
6480  * We use index 3 because with feedback messages, the FCI (Feedback Control Information)
6481  * does not begin until after the version, packet SSRC, and media SSRC words.
6482  */
6483  for (packet_index = 3; packet_index < length; packet_index++) {
6484  current_word = ntohl(nackdata[position + packet_index]);
6485  pid = current_word >> 16;
6486  /* We know the remote end is missing this packet. Go ahead and send it if we still have it. */
6487  payload = (struct ast_rtp_rtcp_nack_payload *)ast_data_buffer_get(rtp->send_buffer, pid);
6488  if (payload) {
6489  if (abs_send_time_id != -1) {
6490  /* On retransmission we need to update the timestamp within the packet, as it
6491  * is supposed to contain when the packet was actually sent.
6492  */
6493  put_unaligned_time24(payload->buf + 17, now_msw, now_lsw);
6494  }
6495  res += rtp_sendto(instance, payload->buf, payload->size, 0, &remote_address, &ice);
6496  } else {
6497  ast_debug_rtcp(1, "(%p) RTCP received NACK request for RTP packet with seqno %d, "
6498  "but we don't have it\n", instance, pid);
6499  packets_not_found++;
6500  }
6501  /*
6502  * The bitmask. Denoting the least significant bit as 1 and its most significant bit
6503  * as 16, then bit i of the bitmask is set to 1 if the receiver has not received RTP
6504  * packet (pid+i)(modulo 2^16). Otherwise, it is set to 0. We cannot assume bits set
6505  * to 0 after a bit set to 1 have actually been received.
6506  */
6507  blp = current_word & 0xffff;
6508  blp_index = 1;
6509  while (blp) {
6510  if (blp & 1) {
6511  /* Packet (pid + i)(modulo 2^16) is missing too. */
6512  unsigned int seqno = (pid + blp_index) % 65536;
6513  payload = (struct ast_rtp_rtcp_nack_payload *)ast_data_buffer_get(rtp->send_buffer, seqno);
6514  if (payload) {
6515  if (abs_send_time_id != -1) {
6516  put_unaligned_time24(payload->buf + 17, now_msw, now_lsw);
6517  }
6518  res += rtp_sendto(instance, payload->buf, payload->size, 0, &remote_address, &ice);
6519  } else {
6520  ast_debug_rtcp(1, "(%p) RTCP remote end also requested RTP packet with seqno %d, "
6521  "but we don't have it\n", instance, seqno);
6522  packets_not_found++;
6523  }
6524  }
6525  blp >>= 1;
6526  blp_index++;
6527  }
6528  }
6529 
6530  if (packets_not_found) {
6531  /* Grow the send buffer based on how many packets were not found in the buffer, but
6532  * enforce a maximum.
6533  */
6535  ast_data_buffer_max(rtp->send_buffer) + packets_not_found));
6536  ast_debug_rtcp(2, "(%p) RTCP send buffer on RTP instance is now at maximum of %zu\n",
6537  instance, ast_data_buffer_max(rtp->send_buffer));
6538  }
6539 
6540  return res;
6541 }
RTP session description.
int ast_rtp_instance_extmap_get_id(struct ast_rtp_instance *instance, enum ast_rtp_extension extension)
Retrieve the id for an RTP extension.
Definition: rtp_engine.c:908
Structure for storing RTP packets for retransmission.
struct ast_data_buffer * send_buffer
#define MAXIMUM_RTP_SEND_BUFFER_SIZE
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
Socket address structure.
Definition: netsock2.h:97
struct ice_wrap * ice
void * ast_data_buffer_get(const struct ast_data_buffer *buffer, size_t pos)
Retrieve a data payload from the data buffer.
Definition: data_buffer.c:269
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
static int rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int *ice)
#define ast_debug_rtcp(sublevel,...)
Log debug level RTCP information.
Definition: rtp_engine.h:3034
void ast_data_buffer_resize(struct ast_data_buffer *buffer, size_t size)
Resize a data buffer.
Definition: data_buffer.c:168
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1245
size_t ast_data_buffer_max(const struct ast_data_buffer *buffer)
Return the maximum number of payloads a data buffer can hold.
Definition: data_buffer.c:363
static int ast_rtp_sendcng ( struct ast_rtp_instance instance,
int  level 
)
static

generate comfort noice (CNG)

Precondition
instance is locked

Definition at line 9338 of file res_rtp_asterisk.c.

References AST_RTP_CN, ast_rtp_codecs_payload_code_tx(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_tv(), ast_tvadd(), ast_tvnow(), rtp_sendto(), ast_rtp::seqno, and ast_rtp::ssrc.

9339 {
9340  unsigned int *rtpheader;
9341  int hdrlen = 12;
9342  int res, payload = 0;
9343  char data[256];
9344  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
9345  struct ast_sockaddr remote_address = { {0,} };
9346  int ice;
9347 
9348  ast_rtp_instance_get_remote_address(instance, &remote_address);
9349 
9350  if (ast_sockaddr_isnull(&remote_address)) {
9351  return -1;
9352  }
9353 
9355 
9356  level = 127 - (level & 0x7f);
9357 
9358  rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
9359 
9360  /* Get a pointer to the header */
9361  rtpheader = (unsigned int *)data;
9362  rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno));
9363  rtpheader[1] = htonl(rtp->lastts);
9364  rtpheader[2] = htonl(rtp->ssrc);
9365  data[12] = level;
9366 
9367  res = rtp_sendto(instance, (void *) rtpheader, hdrlen + 1, 0, &remote_address, &ice);
9368 
9369  if (res < 0) {
9370  ast_log(LOG_ERROR, "RTP Comfort Noise Transmission error to %s: %s\n", ast_sockaddr_stringify(&remote_address), strerror(errno));
9371  return res;
9372  }
9373 
9374  if (rtp_debug_test_addr(&remote_address)) {
9375  ast_verbose("Sent Comfort Noise RTP packet to %s%s (type %-2.2d, seq %-6.6d, ts %-6.6u, len %-6.6d)\n",
9376  ast_sockaddr_stringify(&remote_address),
9377  ice ? " (via ICE)" : "",
9378  AST_RTP_CN, rtp->seqno, rtp->lastdigitts, res - hdrlen);
9379  }
9380 
9381  rtp->seqno++;
9382 
9383  return res;
9384 }
RTP session description.
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:749
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
Socket address structure.
Definition: netsock2.h:97
int ast_rtp_codecs_payload_code_tx(struct ast_rtp_codecs *codecs, int asterisk_format, const struct ast_format *format, int code)
Retrieve a tx mapped payload type based on whether it is an Asterisk format and the code...
Definition: rtp_engine.c:2094
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
unsigned int ssrc
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
static int rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int *ice)
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:235
unsigned short seqno
#define AST_RTP_CN
Definition: rtp_engine.h:296
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1245
static void ast_rtp_set_remote_ssrc ( struct ast_rtp_instance instance,
unsigned int  ssrc 
)
static
Precondition
instance is locked

Definition at line 9403 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), AST_VECTOR_GET_ADDR, AST_VECTOR_SIZE, ast_rtp::bundled, rtp_ssrc_mapping::instance, rtp_ssrc_mapping::ssrc, ast_rtp::ssrc, ast_rtp::ssrc_mapping, rtp_ssrc_mapping::ssrc_valid, ast_rtp::themssrc, and ast_rtp::themssrc_valid.

9404 {
9405  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
9406 
9407  if (rtp->themssrc_valid && rtp->themssrc == ssrc) {
9408  return;
9409  }
9410 
9411  rtp->themssrc = ssrc;
9412  rtp->themssrc_valid = 1;
9413 
9414  /* If this is bundled we need to update the SSRC mapping */
9415  if (rtp->bundled) {
9416  struct ast_rtp *bundled_rtp;
9417  int index;
9418 
9419  ao2_unlock(instance);
9420 
9421  /* The child lock can't be held while accessing the parent */
9422  ao2_lock(rtp->bundled);
9423  bundled_rtp = ast_rtp_instance_get_data(rtp->bundled);
9424 
9425  for (index = 0; index < AST_VECTOR_SIZE(&bundled_rtp->ssrc_mapping); ++index) {
9426  struct rtp_ssrc_mapping *mapping = AST_VECTOR_GET_ADDR(&bundled_rtp->ssrc_mapping, index);
9427 
9428  if (mapping->instance == instance) {
9429  mapping->ssrc = ssrc;
9430  mapping->ssrc_valid = 1;
9431  break;
9432  }
9433  }
9434 
9435  ao2_unlock(rtp->bundled);
9436 
9437  ao2_lock(instance);
9438  }
9439 }
struct ast_rtp_instance * instance
The RTP instance this SSRC belongs to.
RTP session description.
Structure used for mapping an incoming SSRC to an RTP instance.
struct ast_rtp_instance * bundled
unsigned int ssrc_valid
unsigned int ssrc
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
Definition: vector.h:668
struct ast_rtp::@480 ssrc_mapping
unsigned int themssrc_valid
unsigned int themssrc
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
unsigned int ssrc
The received SSRC.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
static void ast_rtp_stop ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 9275 of file res_rtp_asterisk.c.

References ao2_ref, ast_debug_rtp, ast_rtp_instance_get_channel_id(), ast_rtp_instance_get_data(), ast_rtp_instance_set_remote_address, AST_SCHED_DEL, ast_sched_del(), AST_SCHED_DEL_UNREF, rtp_transport_wide_cc_statistics::schedid, ast_rtcp::schedid, rtp_red::schedid, and ast_rtp::transport_wide_cc.

9276 {
9277  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
9278  struct ast_sockaddr addr = { {0,} };
9279 
9280 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
9281  ao2_unlock(instance);
9282  AST_SCHED_DEL_UNREF(rtp->sched, rtp->rekeyid, ao2_ref(instance, -1));
9283 
9284  dtls_srtp_stop_timeout_timer(instance, rtp, 0);
9285  if (rtp->rtcp) {
9286  dtls_srtp_stop_timeout_timer(instance, rtp, 1);
9287  }
9288  ao2_lock(instance);
9289 #endif
9290  ast_debug_rtp(1, "(%s) RTP Stop\n",
9292 
9293  if (rtp->rtcp && rtp->rtcp->schedid > -1) {
9294  ao2_unlock(instance);
9295  if (!ast_sched_del(rtp->sched, rtp->rtcp->schedid)) {
9296  /* successfully cancelled scheduler entry. */
9297  ao2_ref(instance, -1);
9298  }
9299  ao2_lock(instance);
9300  rtp->rtcp->schedid = -1;
9301  }
9302 
9303  if (rtp->transport_wide_cc.schedid > -1) {
9304  ao2_unlock(instance);
9305  if (!ast_sched_del(rtp->sched, rtp->transport_wide_cc.schedid)) {
9306  ao2_ref(instance, -1);
9307  }
9308  ao2_lock(instance);
9309  rtp->transport_wide_cc.schedid = -1;
9310  }
9311 
9312  if (rtp->red) {
9313  ao2_unlock(instance);
9314  AST_SCHED_DEL(rtp->sched, rtp->red->schedid);
9315  ao2_lock(instance);
9316  ast_free(rtp->red);
9317  rtp->red = NULL;
9318  }
9319 
9320  ast_rtp_instance_set_remote_address(instance, &addr);
9321 
9322  ast_set_flag(rtp, FLAG_NEED_MARKER_BIT);
9323 }
RTP session description.
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:82
struct rtp_transport_wide_cc_statistics transport_wide_cc
Socket address structure.
Definition: netsock2.h:97
const char * ast_rtp_instance_get_channel_id(struct ast_rtp_instance *instance)
Get the unique ID of the channel that owns this RTP instance.
Definition: rtp_engine.c:570
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition: sched.h:46
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ast_rtp_instance_set_remote_address(instance, address)
Set the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1133
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
int ast_sched_del(struct ast_sched_context *con, int id) attribute_warn_unused_result
Deletes a scheduled event.
Definition: sched.c:614
#define ast_debug_rtp(sublevel,...)
Log debug level RTP information.
Definition: rtp_engine.h:3017
static void ast_rtp_stun_request ( struct ast_rtp_instance instance,
struct ast_sockaddr suggestion,
const char *  username 
)
static
Precondition
instance is NOT locked

Definition at line 9260 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), ast_sockaddr_from_sin, ast_sockaddr_to_sin, and ast_stun_request().

9261 {
9262  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
9263  struct sockaddr_in suggestion_tmp;
9264 
9265  /*
9266  * The instance should not be locked because we can block
9267  * waiting for a STUN respone.
9268  */
9269  ast_sockaddr_to_sin(suggestion, &suggestion_tmp);
9270  ast_stun_request(rtp->s, &suggestion_tmp, username, NULL);
9271  ast_sockaddr_from_sin(suggestion, &suggestion_tmp);
9272 }
RTP session description.
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:778
int ast_stun_request(int s, struct sockaddr_in *dst, const char *username, struct sockaddr_in *answer)
Generic STUN request.
Definition: stun.c:415
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:765
static void ast_rtp_update_source ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 4527 of file res_rtp_asterisk.c.

References ast_debug_rtp, and ast_rtp_instance_get_data().

4528 {
4529  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4530 
4531  /* We simply set this bit so that the next packet sent will have the marker bit turned on */
4532  ast_set_flag(rtp, FLAG_NEED_MARKER_BIT);
4533  ast_debug_rtp(3, "(%p) RTP setting the marker bit due to a source update\n", instance);
4534 
4535  return;
4536 }
RTP session description.
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
#define ast_debug_rtp(sublevel,...)
Log debug level RTP information.
Definition: rtp_engine.h:3017
static int ast_rtp_write ( struct ast_rtp_instance instance,
struct ast_frame frame 
)
static
Precondition
instance is locked

Definition at line 5474 of file res_rtp_asterisk.c.

References ao2_replace, AST_CONTROL_VIDUPDATE, ast_debug_rtp, ast_format_can_be_smoothed(), ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_default_ms(), ast_format_get_minimum_bytes(), ast_format_get_minimum_ms(), ast_format_get_name(), ast_format_get_smoother_flags(), AST_FRAME_CONTROL, AST_FRAME_RTCP, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frdup, ast_rtp_codecs_get_framing(), ast_rtp_codecs_payload_code_tx(), ast_rtp_instance_get_channel_id(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address, AST_RTP_RTCP_PSFB, ast_sockaddr_isnull(), ast_format::codec, ast_frame::data, ast_frame::datalen, ast_frame_subclass::format, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::offset, rtp_raw_write(), and ast_frame::subclass.

Referenced by red_write(), and rtp_red_buffer().

5475 {
5476  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
5477  struct ast_sockaddr remote_address = { {0,} };
5478  struct ast_format *format;
5479  int codec;
5480 
5481  ast_rtp_instance_get_remote_address(instance, &remote_address);
5482 
5483  /* If we don't actually know the remote address don't even bother doing anything */
5484  if (ast_sockaddr_isnull(&remote_address)) {
5485  ast_debug_rtp(1, "(%p) RTP no remote address on instance, so dropping frame\n", instance);
5486  return 0;
5487  }
5488 
5489  /* VP8: is this a request to send a RTCP FIR? */
5490  if (frame->frametype == AST_FRAME_CONTROL && frame->subclass.integer == AST_CONTROL_VIDUPDATE) {
5491  rtp_write_rtcp_fir(instance, rtp, &remote_address);
5492  return 0;
5493  } else if (frame->frametype == AST_FRAME_RTCP) {
5494  if (frame->subclass.integer == AST_RTP_RTCP_PSFB) {
5495  rtp_write_rtcp_psfb(instance, rtp, frame, &remote_address);
5496  }
5497  return 0;
5498  }
5499 
5500  /* If there is no data length we can't very well send the packet */
5501  if (!frame->datalen) {
5502  ast_debug_rtp(1, "(%p) RTP received frame with no data for instance, so dropping frame\n", instance);
5503  return 0;
5504  }
5505 
5506  /* If the packet is not one our RTP stack supports bail out */
5507  if (frame->frametype != AST_FRAME_VOICE && frame->frametype != AST_FRAME_VIDEO && frame->frametype != AST_FRAME_TEXT) {
5508  ast_log(LOG_WARNING, "RTP can only send voice, video, and text\n");
5509  return -1;
5510  }
5511 
5512  if (rtp->red) {
5513  /* return 0; */
5514  /* no primary data or generations to send */
5515  if ((frame = red_t140_to_red(rtp->red)) == NULL)
5516  return 0;
5517  }
5518 
5519  /* Grab the subclass and look up the payload we are going to use */
5521  1, frame->subclass.format, 0);
5522  if (codec < 0) {
5523  ast_log(LOG_WARNING, "Don't know how to send format %s packets with RTP\n",
5525  return -1;
5526  }
5527 
5528  /* Note that we do not increase the ref count here as this pointer
5529  * will not be held by any thing explicitly. The format variable is
5530  * merely a convenience reference to frame->subclass.format */
5531  format = frame->subclass.format;
5532  if (ast_format_cmp(rtp->lasttxformat, format) == AST_FORMAT_CMP_NOT_EQUAL) {
5533  /* Oh dear, if the format changed we will have to set up a new smoother */
5534  ast_debug_rtp(1, "(%s) RTP ooh, format changed from %s to %s\n",
5536  ast_format_get_name(rtp->lasttxformat),
5538  ao2_replace(rtp->lasttxformat, format);
5539  if (rtp->smoother) {
5540  ast_smoother_free(rtp->smoother);
5541  rtp->smoother = NULL;
5542  }
5543  }
5544 
5545  /* If no smoother is present see if we have to set one up */
5546  if (!rtp->smoother && ast_format_can_be_smoothed(format)) {
5547  unsigned int smoother_flags = ast_format_get_smoother_flags(format);
5548  unsigned int framing_ms = ast_rtp_codecs_get_framing(ast_rtp_instance_get_codecs(instance));
5549 
5550  if (!framing_ms && (smoother_flags & AST_SMOOTHER_FLAG_FORCED)) {
5551  framing_ms = ast_format_get_default_ms(format);
5552  }
5553 
5554  if (framing_ms) {
5555  rtp->smoother = ast_smoother_new((framing_ms * ast_format_get_minimum_bytes(format)) / ast_format_get_minimum_ms(format));
5556  if (!rtp->smoother) {
5557  ast_log(LOG_WARNING, "Unable to create smoother: format %s ms: %u len: %u\n",
5558  ast_format_get_name(format), framing_ms, ast_format_get_minimum_bytes(format));
5559  return -1;
5560  }
5561  ast_smoother_set_flags(rtp->smoother, smoother_flags);
5562  }
5563  }
5564 
5565  /* Feed audio frames into the actual function that will create a frame and send it */
5566  if (rtp->smoother) {
5567  struct ast_frame *f;
5568 
5569  if (ast_smoother_test_flag(rtp->smoother, AST_SMOOTHER_FLAG_BE)) {
5570  ast_smoother_feed_be(rtp->smoother, frame);
5571  } else {
5572  ast_smoother_feed(rtp->smoother, frame);
5573  }
5574 
5575  while ((f = ast_smoother_read(rtp->smoother)) && (f->data.ptr)) {
5576  rtp_raw_write(instance, f, codec);
5577  }
5578  } else {
5579  int hdrlen = 12;
5580  struct ast_frame *f = NULL;
5581 
5582  if (frame->offset < hdrlen) {
5583  f = ast_frdup(frame);
5584  } else {
5585  f = frame;
5586  }
5587  if (f->data.ptr) {
5588  rtp_raw_write(instance, f, codec);
5589  }
5590  if (f != frame) {
5591  ast_frfree(f);
5592  }
5593 
5594  }
5595 
5596  return 0;
5597 }
RTP session description.
#define ast_frdup(fr)
Copies a frame.
static int rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame *frame, int codec)
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:749
Definition of a media format.
Definition: format.c:43
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
Socket address structure.
Definition: netsock2.h:97
int ast_rtp_codecs_payload_code_tx(struct ast_rtp_codecs *codecs, int asterisk_format, const struct ast_format *format, int code)
Retrieve a tx mapped payload type based on whether it is an Asterisk format and the code...
Definition: rtp_engine.c:2094
unsigned int ast_rtp_codecs_get_framing(struct ast_rtp_codecs *codecs)
Get the framing used for a set of codecs.
Definition: rtp_engine.c:1640
struct ast_frame_subclass subclass
int ast_format_get_smoother_flags(const struct ast_format *format)
Get smoother flags for this format.
Definition: format.c:349
const char * ast_rtp_instance_get_channel_id(struct ast_rtp_instance *instance)
Get the unique ID of the channel that owns this RTP instance.
Definition: rtp_engine.c:570
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
unsigned int ast_format_get_minimum_bytes(const struct ast_format *format)
Get the minimum number of bytes expected in a frame for this format.
Definition: format.c:374
int ast_format_can_be_smoothed(const struct ast_format *format)
Get whether or not the format can be smoothed.
Definition: format.c:344
struct ast_codec * codec
Pointer to the codec in use for this format.
Definition: format.c:47
union ast_frame::@224 data
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
unsigned int ast_format_get_default_ms(const struct ast_format *format)
Get the default framing size (in milliseconds) for a format.
Definition: format.c:359
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:501
#define ast_debug_rtp(sublevel,...)
Log debug level RTP information.
Definition: rtp_engine.h:3017
Data structure associated with a single frame of data.
#define AST_RTP_RTCP_PSFB
Definition: rtp_engine.h:329
enum ast_frame_type frametype
struct ast_format * format
unsigned int ast_format_get_minimum_ms(const struct ast_format *format)
Get the minimum amount of media carried in this format.
Definition: format.c:364
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1245
static int bridge_p2p_rtp_write ( struct ast_rtp_instance instance,
struct ast_rtp_instance instance1,
unsigned int *  rtpheader,
int  len,
int  hdrlen 
)
static
Precondition
instance is locked

Definition at line 7150 of file res_rtp_asterisk.c.

References ao2_replace, ast_debug_rtp, ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_name(), ast_format_none, ast_rtp_codecs_find_payload_code(), ast_rtp_codecs_get_payload(), ast_rtp_codecs_payload_code_tx(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_data(), ast_rtp_instance_get_prop(), ast_rtp_instance_get_remote_address, AST_RTP_PROPERTY_NAT, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_rtp::asymmetric_codec, ast_rtp::last_end_timestamp, RAII_VAR, rtp_sendto(), ast_rtp::sending_digit, and ast_rtp::ssrc.

7152 {
7153  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
7154  struct ast_rtp *bridged;
7155  int res = 0, payload = 0, bridged_payload = 0, mark;
7156  RAII_VAR(struct ast_rtp_payload_type *, payload_type, NULL, ao2_cleanup);
7157  int reconstruct = ntohl(rtpheader[0]);
7158  struct ast_sockaddr remote_address = { {0,} };
7159  int ice;
7160  unsigned int timestamp = ntohl(rtpheader[1]);
7161 
7162  /* Get fields from packet */
7163  payload = (reconstruct & 0x7f0000) >> 16;
7164  mark = (reconstruct & 0x800000) >> 23;
7165 
7166  /* Check what the payload value should be */
7167  payload_type = ast_rtp_codecs_get_payload(ast_rtp_instance_get_codecs(instance), payload);
7168  if (!payload_type) {
7169  return -1;
7170  }
7171 
7172  /* Otherwise adjust bridged payload to match */
7173  bridged_payload = ast_rtp_codecs_payload_code_tx(ast_rtp_instance_get_codecs(instance1),
7174  payload_type->asterisk_format, payload_type->format, payload_type->rtp_code);
7175 
7176  /* If no codec could be matched between instance and instance1, then somehow things were made incompatible while we were still bridged. Bail. */
7177  if (bridged_payload < 0) {
7178  return -1;
7179  }
7180 
7181  /* If the payload coming in is not one of the negotiated ones then send it to the core, this will cause formats to change and the bridge to break */
7182  if (ast_rtp_codecs_find_payload_code(ast_rtp_instance_get_codecs(instance1), bridged_payload) == -1) {
7183  ast_debug_rtp(1, "(%p, %p) RTP unsupported payload type received\n", instance, instance1);
7184  return -1;
7185  }
7186 
7187  /*
7188  * Even if we are no longer in dtmf, we could still be receiving
7189  * re-transmissions of the last dtmf end still. Feed those to the
7190  * core so they can be filtered accordingly.
7191  */
7192  if (rtp->last_end_timestamp.is_set && rtp->last_end_timestamp.ts == timestamp) {
7193  ast_debug_rtp(1, "(%p, %p) RTP feeding packet with duplicate timestamp to core\n", instance, instance1);
7194  return -1;
7195  }
7196 
7197  if (payload_type->asterisk_format) {
7198  ao2_replace(rtp->lastrxformat, payload_type->format);
7199  }
7200 
7201  /*
7202  * We have now determined that we need to send the RTP packet
7203  * out the bridged instance to do local bridging so we must unlock
7204  * the receiving instance to prevent deadlock with the bridged
7205  * instance.
7206  *
7207  * Technically we should grab a ref to instance1 so it won't go
7208  * away on us. However, we should be safe because the bridged
7209  * instance won't change without both channels involved being
7210  * locked and we currently have the channel lock for the receiving
7211  * instance.
7212  */
7213  ao2_unlock(instance);
7214  ao2_lock(instance1);
7215 
7216  /*
7217  * Get the peer rtp pointer now to emphasize that using it
7218  * must happen while instance1 is locked.
7219  */
7220  bridged = ast_rtp_instance_get_data(instance1);
7221 
7222 
7223  /* If bridged peer is in dtmf, feed all packets to core until it finishes to avoid infinite dtmf */
7224  if (bridged->sending_digit) {
7225  ast_debug_rtp(1, "(%p, %p) RTP Feeding packet to core until DTMF finishes\n", instance, instance1);
7226  ao2_unlock(instance1);
7227  ao2_lock(instance);
7228  return -1;
7229  }
7230 
7231  if (payload_type->asterisk_format) {
7232  /*
7233  * If bridged peer has already received rtp, perform the asymmetric codec check
7234  * if that feature has been activated
7235  */
7236  if (!bridged->asymmetric_codec
7237  && bridged->lastrxformat != ast_format_none
7238  && ast_format_cmp(payload_type->format, bridged->lastrxformat) == AST_FORMAT_CMP_NOT_EQUAL) {
7239  ast_debug_rtp(1, "(%p, %p) RTP asymmetric RTP codecs detected (TX: %s, RX: %s) sending frame to core\n",
7240  instance, instance1, ast_format_get_name(payload_type->format),
7241  ast_format_get_name(bridged->lastrxformat));
7242  ao2_unlock(instance1);
7243  ao2_lock(instance);
7244  return -1;
7245  }
7246 
7247  ao2_replace(bridged->lasttxformat, payload_type->format);
7248  }
7249 
7250  ast_rtp_instance_get_remote_address(instance1, &remote_address);
7251 
7252  if (ast_sockaddr_isnull(&remote_address)) {
7253  ast_debug_rtp(5, "(%p, %p) RTP remote address is null, most likely RTP has been stopped\n",
7254  instance, instance1);
7255  ao2_unlock(instance1);
7256  ao2_lock(instance);
7257  return 0;
7258  }
7259 
7260  /* If the marker bit has been explicitly set turn it on */
7261  if (ast_test_flag(bridged, FLAG_NEED_MARKER_BIT)) {
7262  mark = 1;
7263  ast_clear_flag(bridged, FLAG_NEED_MARKER_BIT);
7264  }
7265 
7266  /* Set the marker bit for the first local bridged packet which has the first bridged peer's SSRC. */
7267  if (ast_test_flag(bridged, FLAG_REQ_LOCAL_BRIDGE_BIT)) {
7268  mark = 1;
7269  ast_clear_flag(bridged, FLAG_REQ_LOCAL_BRIDGE_BIT);
7270  }
7271 
7272  /* Reconstruct part of the packet */
7273  reconstruct &= 0xFF80FFFF;
7274  reconstruct |= (bridged_payload << 16);
7275  reconstruct |= (mark << 23);
7276  rtpheader[0] = htonl(reconstruct);
7277 
7278  if (mark) {
7279  /* make this rtp instance aware of the new ssrc it is sending */
7280  bridged->ssrc = ntohl(rtpheader[2]);
7281  }
7282 
7283  /* Send the packet back out */
7284  res = rtp_sendto(instance1, (void *)rtpheader, len, 0, &remote_address, &ice);
7285  if (res < 0) {
7286  if (!ast_rtp_instance_get_prop(instance1, AST_RTP_PROPERTY_NAT) || (ast_rtp_instance_get_prop(instance1, AST_RTP_PROPERTY_NAT) && (ast_test_flag(bridged, FLAG_NAT_ACTIVE) == FLAG_NAT_ACTIVE))) {
7287  ast_log(LOG_WARNING,
7288  "RTP Transmission error of packet to %s: %s\n",
7289  ast_sockaddr_stringify(&remote_address),
7290  strerror(errno));
7291  } else if (((ast_test_flag(bridged, FLAG_NAT_ACTIVE) == FLAG_NAT_INACTIVE) || ast_debug_rtp_packet_is_allowed) && !ast_test_flag(bridged, FLAG_NAT_INACTIVE_NOWARN)) {
7292  if (ast_debug_rtp_packet_is_allowed || DEBUG_ATLEAST(1)) {
7293  ast_log(LOG_WARNING,
7294  "RTP NAT: Can't write RTP to private "
7295  "address %s, waiting for other end to "
7296  "send audio...\n",
7297  ast_sockaddr_stringify(&remote_address));
7298  }
7299  ast_set_flag(bridged, FLAG_NAT_INACTIVE_NOWARN);
7300  }
7301  ao2_unlock(instance1);
7302  ao2_lock(instance);
7303  return 0;
7304  }
7305 
7306  if (rtp_debug_test_addr(&remote_address)) {
7307  ast_verbose("Sent RTP P2P packet to %s%s (type %-2.2d, len %-6.6d)\n",
7308  ast_sockaddr_stringify(&remote_address),
7309  ice ? " (via ICE)" : "",
7310  bridged_payload, len - hdrlen);
7311  }
7312 
7313  ao2_unlock(instance1);
7314  ao2_lock(instance);
7315  return 0;
7316 }
RTP session description.
struct ast_rtp_payload_type * ast_rtp_codecs_get_payload(struct ast_rtp_codecs *codecs, int payload)
Retrieve rx payload mapped information by payload type.
Definition: rtp_engine.c:1533
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:749
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
optional_ts last_end_timestamp
Socket address structure.
Definition: netsock2.h:97
struct ast_format * ast_format_none
Built-in "null" format.
Definition: format_cache.c:246
int ast_rtp_codecs_payload_code_tx(struct ast_rtp_codecs *codecs, int asterisk_format, const struct ast_format *format, int code)
Retrieve a tx mapped payload type based on whether it is an Asterisk format and the code...
Definition: rtp_engine.c:2094
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
unsigned int ssrc
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:501
#define ast_debug_rtp(sublevel,...)
Log debug level RTP information.
Definition: rtp_engine.h:3017
static int rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int *ice)
int ast_rtp_instance_get_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property)
Get the value of an RTP instance property.
Definition: rtp_engine.c:738
int ast_rtp_codecs_find_payload_code(struct ast_rtp_codecs *codecs, int payload)
Search for the tx payload type in the ast_rtp_codecs structure.
Definition: rtp_engine.c:2099
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1245
unsigned int asymmetric_codec
char sending_digit
static double calc_media_experience_score ( struct ast_rtp_instance instance,
double  normdevrtt,
double  normdev_rxjitter,
double  stdev_rxjitter,
double  normdev_rxlost 
)
static

Calculate a "media experience score" based on given data.

Technically, a mean opinion score (MOS) cannot be calculated without the involvement of human eyes (video) and ears (audio). Thus instead we'll approximate an opinion using the given parameters, and call it a media experience score.

The tallied score is based upon recommendations and formulas from ITU-T G.107, ITU-T G.109, ITU-T G.113, and other various internet sources.

Parameters
instanceRTP instance
normdevrttThe average round trip time
normdev_rxjitterThe smoothed jitter
stdev_rxjitterThe jitter standard deviation value
normdev_rxlostThe average number of packets lost since last check
Returns
A media experience score.
Note
The calculations in this function could probably be simplified but calculating a MOS using the information available publicly, then re-scaling it to 0.0 -> 100.0 makes the process clearer and easier to troubleshoot or change.

Definition at line 6224 of file res_rtp_asterisk.c.

6227 {
6228  double r_value;
6229  double pseudo_mos;
6230  double mes = 0;
6231 
6232  /*
6233  * While the media itself might be okay, a significant enough delay could make
6234  * for an unpleasant user experience.
6235  *
6236  * Calculate the effective latency by using the given round trip time, and adding
6237  * jitter scaled according to its standard deviation. The scaling is done in order
6238  * to increase jitter's weight since a higher deviation can result in poorer overall
6239  * quality.
6240  */
6241  double effective_latency = (normdevrtt * 1000)
6242  + ((normdev_rxjitter * 2) * (stdev_rxjitter / 3))
6243  + 10;
6244 
6245  /*
6246  * Using the defaults for the standard transmission rating factor ("R" value)
6247  * one arrives at 93.2 (see ITU-T G.107 for more details), so we'll use that
6248  * as the starting value and subtract deficiencies that could affect quality.
6249  *
6250  * Calculate the impact of the effective latency. Influence increases with
6251  * values over 160 as the significant "lag" can degrade user experience.
6252  */
6253  if (effective_latency < 160) {
6254  r_value = 93.2 - (effective_latency / 40);
6255  } else {
6256  r_value = 93.2 - (effective_latency - 120) / 10;
6257  }
6258 
6259  /* Next evaluate the impact of lost packets */
6260  r_value = r_value - (normdev_rxlost * 2.0);
6261 
6262  /*
6263  * Finally convert the "R" value into a opinion/quality score between 1 (really anything
6264  * below 3 should be considered poor) and 4.5 (the highest achievable for VOIP).
6265  */
6266  if (r_value < 0) {
6267  pseudo_mos = 1.0;
6268  } else if (r_value > 100) {
6269  pseudo_mos = 4.5;
6270  } else {
6271  pseudo_mos = 1 + (0.035 * r_value) + (r_value * (r_value - 60) * (100 - r_value) * 0.000007);
6272  }
6273 
6274  /*
6275  * We're going to rescale the 0.0->5.0 pseudo_mos to the 0.0->100.0 MES.
6276  * For those ranges, we could actually just multiply the pseudo_mos
6277  * by 20 but we may want to change the scale later.
6278  */
6279  mes = RESCALE(pseudo_mos, 0.0, 5.0, 0.0, 100.0);
6280 
6281  return mes;
6282 }
static int ice_reset_session ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 1015 of file res_rtp_asterisk.c.

References ao2_object_get_lockaddr(), ast_debug_ice, ast_rtp_instance_get_data(), ast_samp2tv(), ast_sockaddr_stringify(), ast_tvadd(), ast_tvnow(), ast_rtp::cond, ast_rtp::ice, ast_rtp::ice_media_started, ast_rtp::ice_num_components, ast_rtp::ice_original_rtp_addr, ast_rtp::ice_port, ice_wrap::real_ice, ast_rtp::role, ast_rtp::turn_rtcp, and ast_rtp::turn_state.

Referenced by ast_rtp_ice_change_components(), and ast_rtp_ice_start().

1016 {
1017  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1018  int res;
1019 
1020  ast_debug_ice(3, "(%p) ICE resetting\n", instance);
1021  if (!rtp->ice->real_ice->is_nominating && !rtp->ice->real_ice->is_complete) {
1022  ast_debug_ice(3, " (%p) ICE nevermind, not ready for a reset\n", instance);
1023  return 0;
1024  }
1025 
1026  ast_debug_ice(3, "(%p) ICE recreating ICE session %s (%d)\n",
1027  instance, ast_sockaddr_stringify(&rtp->ice_original_rtp_addr), rtp->ice_port);
1028  res = ice_create(instance, &rtp->ice_original_rtp_addr, rtp->ice_port, 1);
1029  if (!res) {
1030  /* Use the current expected role for the ICE session */
1031  enum pj_ice_sess_role role = PJ_ICE_SESS_ROLE_UNKNOWN;
1032  ast2pj_rtp_ice_role(rtp->role, &role);
1033  pj_ice_sess_change_role(rtp->ice->real_ice, role);
1034  }
1035 
1036  /* If we only have one component now, and we previously set up TURN for RTCP,
1037  * we need to destroy that TURN socket.
1038  */
1039  if (rtp->ice_num_components == 1 && rtp->turn_rtcp) {
1040  struct timeval wait = ast_tvadd(ast_tvnow(), ast_samp2tv(TURN_STATE_WAIT_TIME, 1000));
1041  struct timespec ts = { .tv_sec = wait.tv_sec, .tv_nsec = wait.tv_usec * 1000, };
1042 
1043  rtp->turn_state = PJ_TURN_STATE_NULL;
1044 
1045  /* Release the instance lock to avoid deadlock with PJPROJECT group lock */
1046  ao2_unlock(instance);
1047  pj_turn_sock_destroy(rtp->turn_rtcp);
1048  ao2_lock(instance);
1049  while (rtp->turn_state != PJ_TURN_STATE_DESTROYING) {
1050  ast_cond_timedwait(&rtp->cond, ao2_object_get_lockaddr(instance), &ts);
1051  }
1052  }
1053 
1054  rtp->ice_media_started = 0;
1055 
1056  return res;
1057 }
RTP session description.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
#define ast_debug_ice(sublevel,...)
Log debug level ICE information.
Definition: rtp_engine.h:3063
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
Definition: astobj2.c:476
unsigned int ice_port
struct ast_sockaddr ice_original_rtp_addr
struct ice_wrap * ice
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:282
ast_cond_t cond
unsigned int ice_media_started
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
pj_turn_sock * turn_rtcp
enum ast_rtp_ice_role role
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
pj_turn_state_t turn_state
unsigned int ice_num_components
pj_ice_sess * real_ice
static void ice_wrap_dtor ( void *  vdoomed)
static

ao2 ICE wrapper object destructor.

Parameters
vdoomedObject being destroyed.
Note
The associated struct ast_rtp_instance object must not be locked when unreffing the object. Otherwise we could deadlock trying to destroy the PJPROJECT ICE structure.

Definition at line 972 of file res_rtp_asterisk.c.

References pj_thread_register_check(), and ice_wrap::real_ice.

973 {
974  struct ice_wrap *ice = vdoomed;
975 
976  if (ice->real_ice) {
978 
979  pj_ice_sess_destroy(ice->real_ice);
980  }
981 }
static void pj_thread_register_check(void)
Function used to check if the calling thread is registered with pjlib. If it is not it will be regist...
pj_ice_sess * real_ice
static int red_write ( const void *  data)
static

Write t140 redundancy frame.

Parameters
dataprimary data to be buffered

Scheduler callback

Definition at line 9067 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), ast_rtp_write(), ast_frame::datalen, and rtp_red::t140.

Referenced by rtp_red_init().

9068 {
9069  struct ast_rtp_instance *instance = (struct ast_rtp_instance*) data;
9070  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
9071 
9072  ao2_lock(instance);
9073  if (rtp->red->t140.datalen > 0) {
9074  ast_rtp_write(instance, &rtp->red->t140);
9075  }
9076  ao2_unlock(instance);
9077 
9078  return 1;
9079 }
RTP session description.
static int ast_rtp_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
struct ast_frame t140
static int rtcp_recvfrom ( struct ast_rtp_instance instance,
void *  buf,
size_t  size,
int  flags,
struct ast_sockaddr sa 
)
static
Precondition
instance is locked

Definition at line 3373 of file res_rtp_asterisk.c.

References __rtp_recvfrom().

Referenced by ast_rtcp_read().

3374 {
3375  return __rtp_recvfrom(instance, buf, size, flags, sa, 1);
3376 }
static int __rtp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int rtcp)
static int rtcp_sendto ( struct ast_rtp_instance instance,
void *  buf,
size_t  size,
int  flags,
struct ast_sockaddr sa,
int *  ice 
)
static
Precondition
instance is locked

Definition at line 3441 of file res_rtp_asterisk.c.

References __rtp_sendto().

Referenced by ast_rtcp_write(), and ast_rtp_read().

3442 {
3443  return __rtp_sendto(instance, buf, size, flags, sa, 1, ice, 1);
3444 }
struct ice_wrap * ice
static int __rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int rtcp, int *via_ice, int use_srtp)
static void rtp_add_candidates_to_ice ( struct ast_rtp_instance instance,
struct ast_rtp rtp,
struct ast_sockaddr addr,
int  port,
int  component,
int  transport 
)
static
Precondition
instance is locked

Definition at line 3656 of file res_rtp_asterisk.c.

References ast_rtp_engine_ice_candidate::address, ao2_iterator_destroy(), ao2_iterator_init(), ao2_ref, ast_debug_ice, ast_inet_ntoa(), AST_LIST_TRAVERSE, ast_rtp_ice_add_cand(), ast_rtp_ice_turn_request(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_sockaddr_cmp(), ast_sockaddr_cmp_addr(), ast_sockaddr_from_sockaddr, ast_sockaddr_is_any(), ast_sockaddr_is_ipv4(), ast_sockaddr_isnull(), ast_sockaddr_setnull(), ast_sockaddr_to_pj_sockaddr(), ast_strdupa, ast_stun_request(), ast_rtp_ioqueue_thread::count, ast_rtp::ice_local_candidates, and ast_rtcp::s.

Referenced by ast_rtp_prop_set().

3658 {
3659  unsigned int count = 0;
3660  struct ifaddrs *ifa, *ia;
3661  struct ast_sockaddr tmp;
3662  pj_sockaddr pjtmp;
3663  struct ast_ice_host_candidate *candidate;
3664  int af_inet_ok = 0, af_inet6_ok = 0;
3665  struct sockaddr_in stunaddr_copy;
3666 
3667  if (ast_sockaddr_is_ipv4(addr)) {
3668  af_inet_ok = 1;
3669  } else if (ast_sockaddr_is_any(addr)) {
3670  af_inet_ok = af_inet6_ok = 1;
3671  } else {
3672  af_inet6_ok = 1;
3673  }
3674 
3675  if (getifaddrs(&ifa) < 0) {
3676  /* If we can't get addresses, we can't load ICE candidates */
3677  ast_log(LOG_ERROR, "(%p) ICE Error obtaining list of local addresses: %s\n",
3678  instance, strerror(errno));
3679  } else {
3680  ast_debug_ice(2, "(%p) ICE add system candidates\n", instance);
3681  /* Iterate through the list of addresses obtained from the system,
3682  * until we've iterated through all of them, or accepted
3683  * PJ_ICE_MAX_CAND candidates */
3684  for (ia = ifa; ia && count < PJ_ICE_MAX_CAND; ia = ia->ifa_next) {
3685  /* Interface is either not UP or doesn't have an address assigned,
3686  * eg, a ppp that just completed LCP but no IPCP yet */
3687  if (!ia->ifa_addr || (ia->ifa_flags & IFF_UP) == 0) {
3688  continue;
3689  }
3690 
3691  /* Filter out non-IPvX addresses, eg, link-layer */
3692  if (ia->ifa_addr->sa_family != AF_INET && ia->ifa_addr->sa_family != AF_INET6) {
3693  continue;
3694  }
3695 
3696  ast_sockaddr_from_sockaddr(&tmp, ia->ifa_addr);
3697 
3698  if (ia->ifa_addr->sa_family == AF_INET) {
3699  const struct sockaddr_in *sa_in = (struct sockaddr_in*)ia->ifa_addr;
3700  if (!af_inet_ok) {
3701  continue;
3702  }
3703 
3704  /* Skip 127.0.0.0/8 (loopback) */
3705  /* Don't use IFF_LOOPBACK check since one could assign usable
3706  * publics to the loopback */
3707  if ((sa_in->sin_addr.s_addr & htonl(0xFF000000)) == htonl(0x7F000000)) {
3708  continue;
3709  }
3710 
3711  /* Skip 0.0.0.0/8 based on RFC1122, and from pjproject */
3712  if ((sa_in->sin_addr.s_addr & htonl(0xFF000000)) == 0) {
3713  continue;
3714  }
3715  } else { /* ia->ifa_addr->sa_family == AF_INET6 */
3716  if (!af_inet6_ok) {
3717  continue;
3718  }
3719 
3720  /* Filter ::1 */
3721  if (!ast_sockaddr_cmp_addr(&lo6, &tmp)) {
3722  continue;
3723  }
3724  }
3725 
3726  /* Pull in the host candidates from [ice_host_candidates] */
3728  AST_LIST_TRAVERSE(&host_candidates, candidate, next) {
3729  if (!ast_sockaddr_cmp(&candidate->local, &tmp)) {
3730  /* candidate->local matches actual assigned, so check if
3731  * advertised is blacklisted, if not, add it to the
3732  * advertised list. Not that it would make sense to remap
3733  * a local address to a blacklisted address, but honour it
3734  * anyway. */
3735  if (!rtp_address_is_ice_blacklisted(&candidate->advertised)) {
3736  ast_sockaddr_to_pj_sockaddr(&candidate->advertised, &pjtmp);
3737  pj_sockaddr_set_port(&pjtmp, port);
3738  ast_rtp_ice_add_cand(instance, rtp, component, transport,
3739  PJ_ICE_CAND_TYPE_HOST, 65535, &pjtmp, &pjtmp, NULL,
3740  pj_sockaddr_get_len(&pjtmp));
3741  ++count;
3742  }
3743 
3744  if (!candidate->include_local) {
3745  /* We don't want to advertise the actual address */
3746  ast_sockaddr_setnull(&tmp);
3747  }
3748 
3749  break;
3750  }
3751  }
3753 
3754  /* we had an entry in [ice_host_candidates] that matched, and
3755  * didn't have include_local_address set. Alternatively, adding
3756  * that match resulted in us going to PJ_ICE_MAX_CAND */
3757  if (ast_sockaddr_isnull(&tmp) || count == PJ_ICE_MAX_CAND) {
3758  continue;
3759  }
3760 
3761  if (rtp_address_is_ice_blacklisted(&tmp)) {
3762  continue;
3763  }
3764 
3765  ast_sockaddr_to_pj_sockaddr(&tmp, &pjtmp);
3766  pj_sockaddr_set_port(&pjtmp, port);
3767  ast_rtp_ice_add_cand(instance, rtp, component, transport,
3768  PJ_ICE_CAND_TYPE_HOST, 65535, &pjtmp, &pjtmp, NULL,
3769  pj_sockaddr_get_len(&pjtmp));
3770  ++count;
3771  }
3772  freeifaddrs(ifa);
3773  }
3774 
3775  ast_rwlock_rdlock(&stunaddr_lock);
3776  memcpy(&stunaddr_copy, &stunaddr, sizeof(stunaddr));
3777  ast_rwlock_unlock(&stunaddr_lock);
3778 
3779  /* If configured to use a STUN server to get our external mapped address do so */
3780  if (stunaddr_copy.sin_addr.s_addr && !stun_address_is_blacklisted(addr) &&
3781  (ast_sockaddr_is_ipv4(addr) || ast_sockaddr_is_any(addr)) &&
3782  count < PJ_ICE_MAX_CAND) {
3783  struct sockaddr_in answer;
3784  int rsp;
3785 
3786  ast_debug_category(3, AST_DEBUG_CATEGORY_ICE | AST_DEBUG_CATEGORY_STUN,
3787  "(%p) ICE request STUN %s %s candidate\n", instance,
3788  transport == AST_TRANSPORT_UDP ? "UDP" : "TCP",
3789  component == AST_RTP_ICE_COMPONENT_RTP ? "RTP" : "RTCP");
3790 
3791  /*
3792  * The instance should not be locked because we can block
3793  * waiting for a STUN respone.
3794  */
3795  ao2_unlock(instance);
3796  rsp = ast_stun_request(component == AST_RTP_ICE_COMPONENT_RTCP
3797  ? rtp->rtcp->s : rtp->s, &stunaddr_copy, NULL, &answer);
3798  ao2_lock(instance);
3799  if (!rsp) {
3800  struct ast_rtp_engine_ice_candidate *candidate;
3801  pj_sockaddr ext, base;
3802  pj_str_t mapped = pj_str(ast_strdupa(ast_inet_ntoa(answer.sin_addr)));
3803  int srflx = 1, baseset = 0;
3804  struct ao2_iterator i;
3805 
3806  pj_sockaddr_init(pj_AF_INET(), &ext, &mapped, ntohs(answer.sin_port));
3807 
3808  /*
3809  * If the returned address is the same as one of our host
3810  * candidates, don't send the srflx. At the same time,
3811  * we need to set the base address (raddr).
3812  */
3814  while (srflx && (candidate = ao2_iterator_next(&i))) {
3815  if (!baseset && ast_sockaddr_is_ipv4(&candidate->address)) {
3816  baseset = 1;
3817  ast_sockaddr_to_pj_sockaddr(&candidate->address, &base);
3818  }
3819 
3820  if (!pj_sockaddr_cmp(&candidate->address, &ext)) {
3821  srflx = 0;
3822  }
3823 
3824  ao2_ref(candidate, -1);
3825  }
3827 
3828  if (srflx && baseset) {
3829  pj_sockaddr_set_port(&base, port);
3830  ast_rtp_ice_add_cand(instance, rtp, component, transport,
3831  PJ_ICE_CAND_TYPE_SRFLX, 65535, &ext, &base, &base,
3832  pj_sockaddr_get_len(&ext));
3833  }
3834  }
3835  }
3836 
3837  /* If configured to use a TURN relay create a session and allocate */
3838  if (pj_strlen(&turnaddr)) {
3839  ast_rtp_ice_turn_request(instance, component, AST_TRANSPORT_TCP, pj_strbuf(&turnaddr), turnport,
3840  pj_strbuf(&turnusername), pj_strbuf(&turnpassword));
3841  }
3842 }
List of ICE host candidate mappings.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
static ast_rwlock_t stunaddr_lock
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ast_debug_ice(sublevel,...)
Log debug level ICE information.
Definition: rtp_engine.h:3063
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
Structure for an ICE candidate.
Definition: rtp_engine.h:525
Socket address structure.
Definition: netsock2.h:97
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
Definition: netsock2.c:413
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:138
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
Definition: netsock2.c:534
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
int ast_stun_request(int s, struct sockaddr_in *dst, const char *username, struct sockaddr_in *answer)
Generic STUN request.
Definition: stun.c:415
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
static void ast_rtp_ice_add_cand(struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned comp_id, unsigned transport_id, pj_ice_cand_type type, pj_uint16_t local_pref, const pj_sockaddr_t *addr, const pj_sockaddr_t *base_addr, const pj_sockaddr_t *rel_addr, int addr_len)
#define ast_sockaddr_from_sockaddr(addr, sa)
Converts a struct sockaddr to a struct ast_sockaddr.
Definition: netsock2.h:819
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:928
struct ao2_container * ice_local_candidates
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
Structure which contains ICE host candidate mapping information.
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:497
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
struct ast_sockaddr address
Definition: rtp_engine.h:530
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
static void ast_rtp_ice_turn_request(struct ast_rtp_instance *instance, enum ast_rtp_ice_component_type component, enum ast_transport transport, const char *server, unsigned int port, const char *username, const char *password)
int ast_sockaddr_to_pj_sockaddr(const struct ast_sockaddr *addr, pj_sockaddr *pjaddr)
Fill a pj_sockaddr from an ast_sockaddr.
static struct ast_rtp_instance* rtp_find_instance_by_media_source_ssrc ( struct ast_rtp_instance instance,
struct ast_rtp rtp,
unsigned int  ssrc 
)
static
Precondition
instance is locked

Definition at line 6389 of file res_rtp_asterisk.c.

References __rtp_find_instance_by_ssrc().

Referenced by ast_rtcp_interpret().

6391 {
6392  return __rtp_find_instance_by_ssrc(instance, rtp, ssrc, 1);
6393 }
static struct ast_rtp_instance * __rtp_find_instance_by_ssrc(struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned int ssrc, int source)
static struct ast_rtp_instance* rtp_find_instance_by_packet_source_ssrc ( struct ast_rtp_instance instance,
struct ast_rtp rtp,
unsigned int  ssrc 
)
static
Precondition
instance is locked

Definition at line 6382 of file res_rtp_asterisk.c.

References __rtp_find_instance_by_ssrc().

Referenced by ast_rtcp_interpret(), and ast_rtp_read().

6384 {
6385  return __rtp_find_instance_by_ssrc(instance, rtp, ssrc, 0);
6386 }
static struct ast_rtp_instance * __rtp_find_instance_by_ssrc(struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned int ssrc, int source)
static void rtp_learning_start ( struct ast_rtp rtp)
static

Start the strictrtp learning mode.

Parameters
rtpRTP session description

Definition at line 3589 of file res_rtp_asterisk.c.

References ast_tvnow(), ast_rtp::lastrxseqno, rtp_learning_info::proposed_address, rtp_learning_info::start, STRICT_RTP_LEARN, and ast_rtp::strict_rtp_state.

Referenced by ast_rtp_remote_address_set().

3590 {
3592  memset(&rtp->rtp_source_learn.proposed_address, 0,
3593  sizeof(rtp->rtp_source_learn.proposed_address));
3594  rtp->rtp_source_learn.start = ast_tvnow();
3595  rtp_learning_seq_init(&rtp->rtp_source_learn, (uint16_t) rtp->lastrxseqno);
3596 }
enum strict_rtp_state strict_rtp_state
struct ast_sockaddr proposed_address
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
struct timeval start
static int rtp_raw_write ( struct ast_rtp_instance instance,
struct ast_frame frame,
int  codec 
)
static
Precondition
instance is locked

Definition at line 5077 of file res_rtp_asterisk.c.

References ao2_ref, ast_data_buffer_put(), ast_debug, ast_debug_rtcp, ast_debug_rtp, ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_g722, AST_FRAME_VIDEO, AST_FRAME_VOICE, AST_FRFLAG_HAS_SEQUENCE_NUMBER, AST_FRFLAG_HAS_TIMING_INFO, ast_malloc, ast_rtcp_calc_interval(), ast_rtcp_write(), AST_RTP_EXTENSION_ABS_SEND_TIME, ast_rtp_get_rate(), ast_rtp_instance_extmap_get_id(), ast_rtp_instance_get_channel_id(), ast_rtp_instance_get_data(), ast_rtp_instance_get_prop(), ast_rtp_instance_get_remote_address, AST_RTP_PROPERTY_NAT, ast_sched_add(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_tvnow(), ast_tvzero(), ast_rtp_rtcp_nack_payload::buf, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_rtp::expectedseqno, ast_frame_subclass::format, ast_frame_subclass::frame_ending, ast_frame::frametype, MAX_TIMESTAMP_SKEW, rtp_sendto(), ast_frame::samples, ast_rtcp::schedid, ast_rtp::send_buffer, ast_rtp::sending_digit, ast_frame::seqno, ast_rtp::seqno, ast_rtp_rtcp_nack_payload::size, ast_rtp::ssrc, ast_frame::subclass, and ast_frame::ts.

Referenced by ast_rtp_write(), and multicast_rtp_write().

5078 {
5079  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
5080  int pred, mark = 0;
5081  unsigned int ms = calc_txstamp(rtp, &frame->delivery);
5082  struct ast_sockaddr remote_address = { {0,} };
5083  int rate = ast_rtp_get_rate(frame->subclass.format) / 1000;
5084  unsigned int seqno;
5085 #ifdef TEST_FRAMEWORK
5086  struct ast_rtp_engine_test *test = ast_rtp_instance_get_test(instance);
5087 #endif
5088 
5090  frame->samples /= 2;
5091  }
5092 
5093  if (rtp->sending_digit) {
5094  return 0;
5095  }
5096 
5097 #ifdef TEST_FRAMEWORK
5098  if (test && test->send_report) {
5099  test->send_report = 0;
5100  ast_rtcp_write(instance);
5101  return 0;
5102  }
5103 #endif
5104 
5105  if (frame->frametype == AST_FRAME_VOICE) {
5106  pred = rtp->lastts + frame->samples;
5107 
5108  /* Re-calculate last TS */
5109  rtp->lastts = rtp->lastts + ms * rate;
5110  if (ast_tvzero(frame->delivery)) {
5111  /* If this isn't an absolute delivery time, Check if it is close to our prediction,
5112  and if so, go with our prediction */
5113  if (abs((int)rtp->lastts - pred) < MAX_TIMESTAMP_SKEW) {
5114  rtp->lastts = pred;
5115  } else {
5116  ast_debug_rtp(3, "(%p) RTP audio difference is %d, ms is %u\n",
5117  instance, abs((int)rtp->lastts - pred), ms);
5118  mark = 1;
5119  }
5120  }
5121  } else if (frame->frametype == AST_FRAME_VIDEO) {
5122  mark = frame->subclass.frame_ending;
5123  pred = rtp->lastovidtimestamp + frame->samples;
5124  /* Re-calculate last TS */
5125  rtp->lastts = rtp->lastts + ms * 90;
5126  /* If it's close to our prediction, go for it */
5127  if (ast_tvzero(frame->delivery)) {
5128  if (abs((int)rtp->lastts - pred) < 7200) {
5129  rtp->lastts = pred;
5130  rtp->lastovidtimestamp += frame->samples;
5131  } else {
5132  ast_debug_rtp(3, "(%p) RTP video difference is %d, ms is %u (%u), pred/ts/samples %u/%d/%d\n",
5133  instance, abs((int)rtp->lastts - pred), ms, ms * 90, rtp->lastts, pred, frame->samples);
5134  rtp->lastovidtimestamp = rtp->lastts;
5135  }
5136  }
5137  } else {
5138  pred = rtp->lastotexttimestamp + frame->samples;
5139  /* Re-calculate last TS */
5140  rtp->lastts = rtp->lastts + ms;
5141  /* If it's close to our prediction, go for it */
5142  if (ast_tvzero(frame->delivery)) {
5143  if (abs((int)rtp->lastts - pred) < 7200) {
5144  rtp->lastts = pred;
5145  rtp->lastotexttimestamp += frame->samples;
5146  } else {
5147  ast_debug_rtp(3, "(%p) RTP other difference is %d, ms is %u, pred/ts/samples %u/%d/%d\n",
5148  instance, abs((int)rtp->lastts - pred), ms, rtp->lastts, pred, frame->samples);
5149  rtp->lastotexttimestamp = rtp->lastts;
5150  }
5151  }
5152  }
5153 
5154  /* If we have been explicitly told to set the marker bit then do so */
5155  if (ast_test_flag(rtp, FLAG_NEED_MARKER_BIT)) {
5156  mark = 1;
5157  ast_clear_flag(rtp, FLAG_NEED_MARKER_BIT);
5158  }
5159 
5160  /* If the timestamp for non-digt packets has moved beyond the timestamp for digits, update the digit timestamp */
5161  if (rtp->lastts > rtp->lastdigitts) {
5162  rtp->lastdigitts = rtp->lastts;
5163  }
5164 
5165  /* Assume that the sequence number we expect to use is what will be used until proven otherwise */
5166  seqno = rtp->seqno;
5167 
5168  /* If the frame contains sequence number information use it to influence our sequence number */
5169  if (ast_test_flag(frame, AST_FRFLAG_HAS_SEQUENCE_NUMBER)) {
5170  if (rtp->expectedseqno != -1) {
5171  /* Determine where the frame from the core is in relation to where we expected */
5172  int difference = frame->seqno - rtp->expectedseqno;
5173 
5174  /* If there is a substantial difference then we've either got packets really out
5175  * of order, or the source is RTP and it has cycled. If this happens we resync
5176  * the sequence number adjustments to this frame. If we also have packet loss
5177  * things won't be reflected correctly but it will sort itself out after a bit.
5178  */
5179  if (abs(difference) > 100) {
5180  difference = 0;
5181  }
5182 
5183  /* Adjust the sequence number being used for this packet accordingly */
5184  seqno += difference;
5185 
5186  if (difference >= 0) {
5187  /* This frame is on time or in the future */
5188  rtp->expectedseqno = frame->seqno + 1;
5189  rtp->seqno += difference;
5190  }
5191  } else {
5192  /* This is the first frame with sequence number we've seen, so start keeping track */
5193  rtp->expectedseqno = frame->seqno + 1;
5194  }
5195  } else {
5196  rtp->expectedseqno = -1;
5197  }
5198 
5199  if (ast_test_flag(frame, AST_FRFLAG_HAS_TIMING_INFO)) {
5200  rtp->lastts = frame->ts * rate;
5201  }
5202 
5203  ast_rtp_instance_get_remote_address(instance, &remote_address);
5204 
5205  /* If we know the remote address construct a packet and send it out */
5206  if (!ast_sockaddr_isnull(&remote_address)) {
5207  int hdrlen = 12;
5208  int res;
5209  int ice;
5210  int ext = 0;
5211  int abs_send_time_id;
5212  int packet_len;
5213  unsigned char *rtpheader;
5214 
5215  /* If the abs-send-time extension has been negotiated determine how much space we need */
5217  if (abs_send_time_id != -1) {
5218  /* 4 bytes for the shared information, 1 byte for identifier, 3 bytes for abs-send-time */
5219  hdrlen += 8;
5220  ext = 1;
5221  }
5222 
5223  packet_len = frame->datalen + hdrlen;
5224  rtpheader = (unsigned char *)(frame->data.ptr - hdrlen);
5225 
5226  put_unaligned_uint32(rtpheader, htonl((2 << 30) | (ext << 28) | (codec << 16) | (seqno) | (mark << 23)));
5227  put_unaligned_uint32(rtpheader + 4, htonl(rtp->lastts));
5228  put_unaligned_uint32(rtpheader + 8, htonl(rtp->ssrc));
5229 
5230  /* We assume right now that we will only ever have the abs-send-time extension in the packet
5231  * which simplifies things a bit.
5232  */
5233  if (abs_send_time_id != -1) {
5234  unsigned int now_msw;
5235  unsigned int now_lsw;
5236 
5237  /* This happens before being placed into the retransmission buffer so that when we
5238  * retransmit we only have to update the timestamp, not everything else.
5239  */
5240  put_unaligned_uint32(rtpheader + 12, htonl((0xBEDE << 16) | 1));
5241  rtpheader[16] = (abs_send_time_id << 4) | 2;
5242 
5243  timeval2ntp(ast_tvnow(), &now_msw, &now_lsw);
5244  put_unaligned_time24(rtpheader + 17, now_msw, now_lsw);
5245  }
5246 
5247  /* If retransmissions are enabled, we need to store this packet for future use */
5248  if (rtp->send_buffer) {
5249  struct ast_rtp_rtcp_nack_payload *payload;
5250 
5251  payload = ast_malloc(sizeof(*payload) + packet_len);
5252  if (payload) {
5253  payload->size = packet_len;
5254  memcpy(payload->buf, rtpheader, packet_len);
5255  if (ast_data_buffer_put(rtp->send_buffer, rtp->seqno, payload) == -1) {
5256  ast_free(payload);
5257  }
5258  }
5259  }
5260 
5261  res = rtp_sendto(instance, (void *)rtpheader, packet_len, 0, &remote_address, &ice);
5262  if (res < 0) {
5263  if (!ast_rtp_instance_get_prop(instance, AST_RTP_PROPERTY_NAT) || (ast_rtp_instance_get_prop(instance, AST_RTP_PROPERTY_NAT) && (ast_test_flag(rtp, FLAG_NAT_ACTIVE) == FLAG_NAT_ACTIVE))) {
5264  ast_debug_rtp(1, "(%p) RTP transmission error of packet %d to %s: %s\n",
5265  instance, rtp->seqno,
5266  ast_sockaddr_stringify(&remote_address),
5267  strerror(errno));
5268  } else if (((ast_test_flag(rtp, FLAG_NAT_ACTIVE) == FLAG_NAT_INACTIVE) || ast_debug_rtp_packet_is_allowed) && !ast_test_flag(rtp, FLAG_NAT_INACTIVE_NOWARN)) {
5269  /* Only give this error message once if we are not RTP debugging */
5270  if (ast_debug_rtp_packet_is_allowed)
5271  ast_debug(0, "(%p) RTP NAT: Can't write RTP to private address %s, waiting for other end to send audio...\n",
5272  instance, ast_sockaddr_stringify(&remote_address));
5273  ast_set_flag(rtp, FLAG_NAT_INACTIVE_NOWARN);
5274  }
5275  } else {
5276  if (rtp->rtcp && rtp->rtcp->schedid < 0) {
5277  ast_debug_rtcp(2, "(%s) RTCP starting transmission in %u ms\n",
5279  ao2_ref(instance, +1);
5280  rtp->rtcp->schedid = ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, instance);
5281  if (rtp->rtcp->schedid < 0) {
5282  ao2_ref(instance, -1);
5283  ast_log(LOG_WARNING, "scheduling RTCP transmission failed.\n");
5284  }
5285  }
5286  }
5287 
5288  if (rtp_debug_test_addr(&remote_address)) {
5289  ast_verbose("Sent RTP packet to %s%s (type %-2.2d, seq %-6.6d, ts %-6.6u, len %-6.6d)\n",
5290  ast_sockaddr_stringify(&remote_address),
5291  ice ? " (via ICE)" : "",
5292  codec, rtp->seqno, rtp->lastts, res - hdrlen);
5293  }
5294  }
5295 
5296  /* If the sequence number that has been used doesn't match what we expected then this is an out of
5297  * order late packet, so we don't need to increment as we haven't yet gotten the expected frame from
5298  * the core.
5299  */
5300  if (seqno == rtp->seqno) {
5301  rtp->seqno++;
5302  }
5303 
5304  return 0;
5305 }
RTP session description.
int ast_rtp_instance_extmap_get_id(struct ast_rtp_instance *instance, enum ast_rtp_extension extension)
Retrieve the id for an RTP extension.
Definition: rtp_engine.c:908
Structure for storing RTP packets for retransmission.
static int ast_rtcp_write(const void *data)
Write a RTCP packet to the far end.
struct ast_data_buffer * send_buffer
#define MAX_TIMESTAMP_SKEW
Definition: chan_iax2.c:712
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:117
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
struct ast_format * ast_format_g722
Built-in cached g722 format.
Definition: format_cache.c:106
Socket address structure.
Definition: netsock2.h:97
struct ast_frame_subclass subclass
const char * ast_rtp_instance_get_channel_id(struct ast_rtp_instance *instance)
Get the unique ID of the channel that owns this RTP instance.
Definition: rtp_engine.c:570
int ast_data_buffer_put(struct ast_data_buffer *buffer, size_t pos, void *payload)
Place a data payload at a position in the data buffer.
Definition: data_buffer.c:203
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
unsigned int ssrc
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define ast_debug(level,...)
Log a DEBUG message.
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
union ast_frame::@224 data
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:567
struct timeval delivery
int ast_rtp_get_rate(const struct ast_format *format)
Retrieve the sample rate of a format according to RTP specifications.
Definition: rtp_engine.c:4224
#define ast_debug_rtp(sublevel,...)
Log debug level RTP information.
Definition: rtp_engine.h:3017
static int rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int *ice)
int ast_rtp_instance_get_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property)
Get the value of an RTP instance property.
Definition: rtp_engine.c:738
static unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp)
enum ast_frame_type frametype
unsigned short seqno
struct ast_format * format
#define ast_debug_rtcp(sublevel,...)
Log debug level RTCP information.
Definition: rtp_engine.h:3034
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1245
char sending_digit
static int rtp_recvfrom ( struct ast_rtp_instance instance,
void *  buf,
size_t  size,
int  flags,
struct ast_sockaddr sa 
)
static
Precondition
instance is locked

Definition at line 3379 of file res_rtp_asterisk.c.

References __rtp_recvfrom().

Referenced by ast_rtp_read().

3380 {
3381  return __rtp_recvfrom(instance, buf, size, flags, sa, 0);
3382 }
static int __rtp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int rtcp)
static int rtp_red_buffer ( struct ast_rtp_instance instance,
struct ast_frame frame 
)
static
Precondition
instance is locked

Definition at line 9115 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), ast_rtp_write(), rtp_red::buf_data, ast_frame::data, ast_frame::datalen, rtp_red::t140, and ast_frame::ts.

9116 {
9117  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
9118  struct rtp_red *red = rtp->red;
9119 
9120  if (!red) {
9121  return 0;
9122  }
9123 
9124  if (frame->datalen > 0) {
9125  if (red->t140.datalen > 0) {
9126  const unsigned char *primary = red->buf_data;
9127 
9128  /* There is something already in the T.140 buffer */
9129  if (primary[0] == 0x08 || primary[0] == 0x0a || primary[0] == 0x0d) {
9130  /* Flush the previous T.140 packet if it is a command */
9131  ast_rtp_write(instance, &rtp->red->t140);
9132  } else {
9133  primary = frame->data.ptr;
9134  if (primary[0] == 0x08 || primary[0] == 0x0a || primary[0] == 0x0d) {
9135  /* Flush the previous T.140 packet if we are buffering a command now */
9136  ast_rtp_write(instance, &rtp->red->t140);
9137  }
9138  }
9139  }
9140 
9141  memcpy(&red->buf_data[red->t140.datalen], frame->data.ptr, frame->datalen);
9142  red->t140.datalen += frame->datalen;
9143  red->t140.ts = frame->ts;
9144  }
9145 
9146  return 0;
9147 }
RTP session description.
static int ast_rtp_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
union ast_frame::@224 data
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
struct ast_frame t140
unsigned char buf_data[64000]
static int rtp_red_init ( struct ast_rtp_instance instance,
int  buffer_time,
int *  payloads,
int  generations 
)
static
Precondition
instance is locked

Definition at line 9082 of file res_rtp_asterisk.c.

References ast_calloc, ast_format_t140_red, AST_FRAME_TEXT, ast_rtp_instance_get_data(), ast_sched_add(), rtp_red::buf_data, ast_frame::data, ast_frame_subclass::format, ast_frame::frametype, rtp_red::num_gen, rtp_red::pt, red_write(), rtp_red::schedid, ast_frame::subclass, rtp_red::t140, rtp_red::t140red, and rtp_red::ti.

9083 {
9084  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
9085  int x;
9086 
9087  rtp->red = ast_calloc(1, sizeof(*rtp->red));
9088  if (!rtp->red) {
9089  return -1;
9090  }
9091 
9092  rtp->red->t140.frametype = AST_FRAME_TEXT;
9094  rtp->red->t140.data.ptr = &rtp->red->buf_data;
9095 
9096  rtp->red->t140red = rtp->red->t140;
9097  rtp->red->t140red.data.ptr = &rtp->red->t140red_data;
9098 
9099  rtp->red->ti = buffer_time;
9100  rtp->red->num_gen = generations;
9101  rtp->red->hdrlen = generations * 4 + 1;
9102 
9103  for (x = 0; x < generations; x++) {
9104  rtp->red->pt[x] = payloads[x];
9105  rtp->red->pt[x] |= 1 << 7; /* mark redundant generations pt */
9106  rtp->red->t140red_data[x*4] = rtp->red->pt[x];
9107  }
9108  rtp->red->t140red_data[x*4] = rtp->red->pt[x] = payloads[x]; /* primary pt */
9109  rtp->red->schedid = ast_sched_add(rtp->sched, generations, red_write, instance);
9110 
9111  return 0;
9112 }
RTP session description.
struct ast_format * ast_format_t140_red
Built-in cached t140 red format.
Definition: format_cache.c:236
struct ast_frame_subclass subclass
struct ast_frame t140red
union ast_frame::@224 data
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
unsigned char pt[AST_RED_MAX_GENERATION]
struct ast_frame t140
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:567
unsigned char buf_data[64000]
static int red_write(const void *data)
Write t140 redundancy frame.
enum ast_frame_type frametype
struct ast_format * format
static int rtp_reload ( int  reload,
int  by_external_config 
)
static

This resource is not "reloaded" so much as unloaded and loaded again. In the case of the TURN related variables, the memory referenced by a previously loaded instance should have been released when the corresponding pool was destroyed. If at some point in the future this resource were to support ACTUAL live reconfiguration and did NOT release the pool this will cause a small memory leak.

Definition at line 9944 of file res_rtp_asterisk.c.

References ast_append_acl(), ast_calloc, ast_cli_register_multiple, ast_cli_unregister_multiple(), ast_config_destroy(), ast_config_load2(), ast_debug_stun, ast_dns_resolve_recurring(), ast_false(), ast_free_acl_list(), ast_inet_ntoa(), AST_MODPRI_CHANNEL_DEPEND, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_named_acl_change_type(), ast_parse_arg(), ast_pjproject_caching_pool_destroy(), ast_pjproject_caching_pool_init(), AST_PJPROJECT_INIT_LOG_LEVEL, ast_rtp_engine_unregister(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_security_topic(), ast_skip_blanks(), ast_sockaddr_copy(), ast_sockaddr_parse(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_sockaddr_split_hostport(), ast_sockaddr_stringify_host(), ast_sockaddr_to_sin, ast_strdupa, ast_true(), ASTERISK_GPL_KEY, cachingpool, CALC_LEARNING_MIN_DURATION, CONFIG_FLAG_FILEUNCHANGED, DEFAULT_DTMF_TIMEOUT, DEFAULT_RTP_END, DEFAULT_RTP_START, DEFAULT_STRICT_RTP, host_candidate_overrides_clear(), ice_acl, learning_min_duration, learning_min_sequential, lock, MAXIMUM_RTP_PORT, MINIMUM_RTP_PORT, ast_variable::name, ast_variable::next, pj_thread_register_check(), RTCP_DEFAULT_INTERVALMS, RTCP_MAX_INTERVALMS, RTCP_MIN_INTERVALMS, rtcpinterval, rtpend, stasis_message_type(), stasis_subscription_accept_message_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, stasis_subscription_set_filter(), stasis_unsubscribe_and_join(), STRICT_RTP_SEQNO, STRICT_RTP_YES, strictrtp, stun_acl, timer_heap, timer_terminate, timer_thread, timer_worker_thread(), and ast_variable::value.

9945 {
9946  struct ast_config *cfg;
9947  const char *s;
9948  struct ast_flags config_flags = { (reload && !by_external_config) ? CONFIG_FLAG_FILEUNCHANGED : 0 };
9949 
9950 #ifdef HAVE_PJPROJECT
9951  struct ast_variable *var;
9952  struct ast_ice_host_candidate *candidate;
9953  int acl_subscription_flag = 0;
9954 #endif
9955 
9956  cfg = ast_config_load2("rtp.conf", "rtp", config_flags);
9957  if (!cfg || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
9958  return 0;
9959  }
9960 
9961 #ifdef SO_NO_CHECK
9962  nochecksums = 0;
9963 #endif
9964 
9968  dtmftimeout = DEFAULT_DTMF_TIMEOUT;
9970  learning_min_sequential = DEFAULT_LEARNING_MIN_SEQUENTIAL;
9971  learning_min_duration = DEFAULT_LEARNING_MIN_DURATION;
9972  srtp_replay_protection = DEFAULT_SRTP_REPLAY_PROTECTION;
9973 
9974  /** This resource is not "reloaded" so much as unloaded and loaded again.
9975  * In the case of the TURN related variables, the memory referenced by a
9976  * previously loaded instance *should* have been released when the
9977  * corresponding pool was destroyed. If at some point in the future this
9978  * resource were to support ACTUAL live reconfiguration and did NOT release
9979  * the pool this will cause a small memory leak.
9980  */
9981 
9982 #ifdef HAVE_PJPROJECT
9983  icesupport = DEFAULT_ICESUPPORT;
9984  stun_software_attribute = DEFAULT_STUN_SOFTWARE_ATTRIBUTE;
9985  turnport = DEFAULT_TURN_PORT;
9986  clean_stunaddr();
9987  turnaddr = pj_str(NULL);
9988  turnusername = pj_str(NULL);
9989  turnpassword = pj_str(NULL);
9991 #endif
9992 
9993 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
9994  dtls_mtu = DEFAULT_DTLS_MTU;
9995 #endif
9996 
9997  if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) {
9998  rtpstart = atoi(s);
9999  if (rtpstart < MINIMUM_RTP_PORT)
10001  if (rtpstart > MAXIMUM_RTP_PORT)
10003  }
10004  if ((s = ast_variable_retrieve(cfg, "general", "rtpend"))) {
10005  rtpend = atoi(s);
10006  if (rtpend < MINIMUM_RTP_PORT)
10008  if (rtpend > MAXIMUM_RTP_PORT)
10010  }
10011  if ((s = ast_variable_retrieve(cfg, "general", "rtcpinterval"))) {
10012  rtcpinterval = atoi(s);
10013  if (rtcpinterval == 0)
10014  rtcpinterval = 0; /* Just so we're clear... it's zero */
10016  rtcpinterval = RTCP_MIN_INTERVALMS; /* This catches negative numbers too */
10019  }
10020  if ((s = ast_variable_retrieve(cfg, "general", "rtpchecksums"))) {
10021 #ifdef SO_NO_CHECK
10022  nochecksums = ast_false(s) ? 1 : 0;
10023 #else
10024  if (ast_false(s))
10025  ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
10026 #endif
10027  }
10028  if ((s = ast_variable_retrieve(cfg, "general", "dtmftimeout"))) {
10029  dtmftimeout = atoi(s);
10030  if ((dtmftimeout < 0) || (dtmftimeout > 64000)) {
10031  ast_log(LOG_WARNING, "DTMF timeout of '%d' outside range, using default of '%d' instead\n",
10032  dtmftimeout, DEFAULT_DTMF_TIMEOUT);
10033  dtmftimeout = DEFAULT_DTMF_TIMEOUT;
10034  };
10035  }
10036  if ((s = ast_variable_retrieve(cfg, "general", "strictrtp"))) {
10037  if (ast_true(s)) {
10039  } else if (!strcasecmp(s, "seqno")) {
10041  } else {
10042  strictrtp = STRICT_RTP_NO;
10043  }
10044  }
10045  if ((s = ast_variable_retrieve(cfg, "general", "probation"))) {
10046  if ((sscanf(s, "%d", &learning_min_sequential) != 1) || learning_min_sequential <= 1) {
10047  ast_log(LOG_WARNING, "Value for 'probation' could not be read, using default of '%d' instead\n",
10048  DEFAULT_LEARNING_MIN_SEQUENTIAL);
10049  learning_min_sequential = DEFAULT_LEARNING_MIN_SEQUENTIAL;
10050  }
10052  }
10053  if ((s = ast_variable_retrieve(cfg, "general", "srtpreplayprotection"))) {
10054  srtp_replay_protection = ast_true(s);
10055  }
10056 #ifdef HAVE_PJPROJECT
10057  if ((s = ast_variable_retrieve(cfg, "general", "icesupport"))) {
10058  icesupport = ast_true(s);
10059  }
10060  if ((s = ast_variable_retrieve(cfg, "general", "stun_software_attribute"))) {
10061  stun_software_attribute = ast_true(s);
10062  }
10063  if ((s = ast_variable_retrieve(cfg, "general", "stunaddr"))) {
10064  char *hostport, *host, *port;
10065  unsigned int port_parsed = STANDARD_STUN_PORT;
10066  struct ast_sockaddr stunaddr_parsed;
10067 
10068  hostport = ast_strdupa(s);
10069 
10070  if (!ast_parse_arg(hostport, PARSE_ADDR, &stunaddr_parsed)) {
10071  ast_debug_stun(3, "stunaddr = '%s' does not need name resolution\n",
10072  ast_sockaddr_stringify_host(&stunaddr_parsed));
10073  if (!ast_sockaddr_port(&stunaddr_parsed)) {
10074  ast_sockaddr_set_port(&stunaddr_parsed, STANDARD_STUN_PORT);
10075  }
10076  ast_rwlock_wrlock(&stunaddr_lock);
10077  ast_sockaddr_to_sin(&stunaddr_parsed, &stunaddr);
10078  ast_rwlock_unlock(&stunaddr_lock);
10079  } else if (ast_sockaddr_split_hostport(hostport, &host, &port, 0)) {
10080  if (port) {
10081  ast_parse_arg(port, PARSE_UINT32|PARSE_IN_RANGE, &port_parsed, 1, 65535);
10082  }
10083  stunaddr.sin_port = htons(port_parsed);
10084 
10085  stunaddr_resolver = ast_dns_resolve_recurring(host, T_A, C_IN,
10086  &stunaddr_resolve_callback, NULL);
10087  if (!stunaddr_resolver) {
10088  ast_log(LOG_ERROR, "Failed to setup recurring DNS resolution of stunaddr '%s'",
10089  host);
10090  }
10091  } else {
10092  ast_log(LOG_ERROR, "Failed to parse stunaddr '%s'", hostport);
10093  }
10094  }
10095  if ((s = ast_variable_retrieve(cfg, "general", "turnaddr"))) {
10096  struct sockaddr_in addr;
10097  addr.sin_port = htons(DEFAULT_TURN_PORT);
10098  if (ast_parse_arg(s, PARSE_INADDR, &addr)) {
10099  ast_log(LOG_WARNING, "Invalid TURN server address: %s\n", s);
10100  } else {
10101  pj_strdup2_with_null(pool, &turnaddr, ast_inet_ntoa(addr.sin_addr));
10102  /* ntohs() is not a bug here. The port number is used in host byte order with
10103  * a pjnat API. */
10104  turnport = ntohs(addr.sin_port);
10105  }
10106  }
10107  if ((s = ast_variable_retrieve(cfg, "general", "turnusername"))) {
10108  pj_strdup2_with_null(pool, &turnusername, s);
10109  }
10110  if ((s = ast_variable_retrieve(cfg, "general", "turnpassword"))) {
10111  pj_strdup2_with_null(pool, &turnpassword, s);
10112  }
10113 
10115  for (var = ast_variable_browse(cfg, "ice_host_candidates"); var; var = var->next) {
10116  struct ast_sockaddr local_addr, advertised_addr;
10117  unsigned int include_local_address = 0;
10118  char *sep;
10119 
10120  ast_sockaddr_setnull(&local_addr);
10121  ast_sockaddr_setnull(&advertised_addr);
10122 
10123  if (ast_parse_arg(var->name, PARSE_ADDR | PARSE_PORT_IGNORE, &local_addr)) {
10124  ast_log(LOG_WARNING, "Invalid local ICE host address: %s\n", var->name);
10125  continue;
10126  }
10127 
10128  sep = strchr(var->value,',');
10129  if (sep) {
10130  *sep = '\0';
10131  sep++;
10132  sep = ast_skip_blanks(sep);
10133  include_local_address = strcmp(sep, "include_local_address") == 0;
10134  }
10135 
10136  if (ast_parse_arg(var->value, PARSE_ADDR | PARSE_PORT_IGNORE, &advertised_addr)) {
10137  ast_log(LOG_WARNING, "Invalid advertised ICE host address: %s\n", var->value);
10138  continue;
10139  }
10140 
10141  if (!(candidate = ast_calloc(1, sizeof(*candidate)))) {
10142  ast_log(LOG_ERROR, "Failed to allocate ICE host candidate mapping.\n");
10143  break;
10144  }
10145 
10146  candidate->include_local = include_local_address;
10147 
10148  ast_sockaddr_copy(&candidate->local, &local_addr);
10149  ast_sockaddr_copy(&candidate->advertised, &advertised_addr);
10150 
10151  AST_RWLIST_INSERT_TAIL(&host_candidates, candidate, next);
10152  }
10154 
10155  ast_rwlock_wrlock(&ice_acl_lock);
10156  ast_rwlock_wrlock(&stun_acl_lock);
10157 
10160 
10161  for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
10162  const char* sense = NULL;
10163  struct ast_acl_list **acl = NULL;
10164  if (strncasecmp(var->name, "ice_", 4) == 0) {
10165  sense = var->name + 4;
10166  acl = &ice_acl;
10167  } else if (strncasecmp(var->name, "stun_", 5) == 0) {
10168  sense = var->name + 5;
10169  acl = &stun_acl;
10170  } else {
10171  continue;
10172  }
10173 
10174  if (strcasecmp(sense, "blacklist") == 0) {
10175  sense = "deny";
10176  }
10177 
10178  if (strcasecmp(sense, "acl") && strcasecmp(sense, "permit") && strcasecmp(sense, "deny")) {
10179  continue;
10180  }
10181 
10182  ast_append_acl(sense, var->value, acl, NULL, &acl_subscription_flag);
10183  }
10184  ast_rwlock_unlock(&ice_acl_lock);
10185  ast_rwlock_unlock(&stun_acl_lock);
10186 
10187  if (acl_subscription_flag && !acl_change_sub) {
10188  acl_change_sub = stasis_subscribe(ast_security_topic(), acl_change_stasis_cb, NULL);
10191  } else if (!acl_subscription_flag && acl_change_sub) {
10193  }
10194 #endif
10195 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
10196  if ((s = ast_variable_retrieve(cfg, "general", "dtls_mtu"))) {
10197  if ((sscanf(s, "%d", &dtls_mtu) != 1) || dtls_mtu < 256) {
10198  ast_log(LOG_WARNING, "Value for 'dtls_mtu' could not be read, using default of '%d' instead\n",
10199  DEFAULT_DTLS_MTU);
10200  dtls_mtu = DEFAULT_DTLS_MTU;
10201  }
10202  }
10203 #endif
10204 
10205  ast_config_destroy(cfg);
10206 
10207  /* Choosing an odd start port casues issues (like a potential infinite loop) and as odd parts are not
10208  chosen anyway, we are going to round up and issue a warning */
10209  if (rtpstart & 1) {
10210  rtpstart++;
10211  ast_log(LOG_WARNING, "Odd start value for RTP port in rtp.conf, rounding up to %d\n", rtpstart);
10212  }
10213 
10214  if (rtpstart >= rtpend) {
10215  ast_log(LOG_WARNING, "Unreasonable values for RTP start/end port in rtp.conf\n");
10218  }
10219  ast_verb(2, "RTP Allocating from port range %d -> %d\n", rtpstart, rtpend);
10220  return 0;
10221 }
struct ast_variable * next
#define DEFAULT_STRICT_RTP
List of ICE host candidate mappings.
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *p_result,...)
The argument parsing routine.
Definition: main/config.c:3827
#define DEFAULT_DTMF_TIMEOUT
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
static int rtpstart
#define MINIMUM_RTP_PORT
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3321
Structure for variables, used for configurations and for channel variables.
static pj_pool_t * pool
Global memory pool for configuration and timers.
static ast_rwlock_t stunaddr_lock
#define RTCP_MIN_INTERVALMS
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
Definition: stasis.c:1077
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
struct stasis_message_type * ast_named_acl_change_type(void)
a stasis_message_type for changes against a named ACL or the set of all named ACLs ...
Wrapper for an ast_acl linked list.
Definition: acl.h:76
#define DEFAULT_RTP_END
Socket address structure.
Definition: netsock2.h:97
#define RTCP_MAX_INTERVALMS
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:138
struct ast_dns_query_recurring * ast_dns_resolve_recurring(const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data)
Asynchronously resolve a DNS query, and continue resolving it according to the lowest TTL available...
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
int ast_sockaddr_split_hostport(char *str, char **host, char **port, int flags)
Splits a string into its host and port components.
Definition: netsock2.c:164
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define MAXIMUM_RTP_PORT
static struct ast_acl_list * stun_acl
static struct ast_acl_list * ice_acl
#define ast_debug_stun(sublevel,...)
Log debug level STUN information.
Definition: stun.h:54
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: utils.c:2199
#define DEFAULT_RTP_START
static void host_candidate_overrides_clear(void)
Helper function which clears the ICE host candidate mapping.
static int strictrtp
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl)
Free a list of ACLs.
Definition: acl.c:233
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:161
Definition: test_acl.c:111
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:928
#define RTCP_DEFAULT_INTERVALMS
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1134
Structure used to handle boolean flags.
Definition: utils.h:199
static int learning_min_duration
static struct stasis_subscription * acl_change_sub
Definition: chan_iax2.c:328
void ast_append_acl(const char *sense, const char *stuff, struct ast_acl_list **path, int *error, int *named_acl_flag)
Add a rule to an ACL struct.
Definition: acl.c:429
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
Definition: utils.c:2216
Structure which contains ICE host candidate mapping information.
static int learning_min_sequential
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
Definition: stasis.c:1023
static int rtcpinterval
struct stasis_topic * ast_security_topic(void)
A stasis_topic which publishes messages for security related issues.
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:765
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define CALC_LEARNING_MIN_DURATION(count)
Calculate the min learning duration in ms.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
static int rtpend
static char * ast_sockaddr_stringify_host(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only, suitable for a URL (with brack...
Definition: netsock2.h:327
static int rtp_sendto ( struct ast_rtp_instance instance,
void *  buf,
size_t  size,
int  flags,
struct ast_sockaddr sa,
int *  ice 
)
static
Precondition
instance is locked

Definition at line 3447 of file res_rtp_asterisk.c.

References __rtp_sendto(), ast_rtp_instance_get_data(), ast_rtp::txcount, and ast_rtp::txoctetcount.

Referenced by ast_rtp_dtmf_begin(), ast_rtp_dtmf_continuation(), ast_rtp_dtmf_end_with_duration(), ast_rtp_rtcp_handle_nack(), ast_rtp_sendcng(), bridge_p2p_rtp_write(), and rtp_raw_write().

3448 {
3449  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
3450  int hdrlen = 12;
3451  int res;
3452 
3453  if ((res = __rtp_sendto(instance, buf, size, flags, sa, 0, ice, 1)) > 0) {
3454  rtp->txcount++;
3455  rtp->txoctetcount += (res - hdrlen);
3456  }
3457 
3458  return res;
3459 }
RTP session description.
unsigned int txcount
struct ice_wrap * ice
static int __rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int rtcp, int *via_ice, int use_srtp)
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
unsigned int txoctetcount

Variable Documentation

pj_turn_sock_cb ast_rtp_turn_rtcp_sock_cb
static
Initial value:
= {
.on_rx_data = ast_rtp_on_turn_rx_rtcp_data,
.on_state = ast_rtp_on_turn_rtcp_state,
}

Definition at line 1504 of file res_rtp_asterisk.c.

pj_turn_sock_cb ast_rtp_turn_rtp_sock_cb
static
Initial value:
= {
.on_rx_data = ast_rtp_on_turn_rx_rtp_data,
.on_state = ast_rtp_on_turn_rtp_state,
}

Definition at line 1438 of file res_rtp_asterisk.c.

struct ast_acl_list* ice_acl = NULL
static

ACL for ICE addresses

Definition at line 240 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

int learning_min_duration = DEFAULT_LEARNING_MIN_DURATION
static

Lowest acceptable timeout between the first and the last sequential RTP frame.

Definition at line 223 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

int learning_min_sequential = DEFAULT_LEARNING_MIN_SEQUENTIAL
static

Number of sequential RTP frames needed from a single source during learning mode to accept new source.

Definition at line 222 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

struct ast_sockaddr rtcpdebugaddr
static

Debug RTCP packets to/from this host

Definition at line 215 of file res_rtp_asterisk.c.

int rtcpdebugport
static

Debug only RTCP packets from IP or IP+Port if port is > 0

Definition at line 217 of file res_rtp_asterisk.c.

int rtcpinterval = RTCP_DEFAULT_INTERVALMS
static

Time between rtcp reports in millisecs

Definition at line 213 of file res_rtp_asterisk.c.

Referenced by ast_rtcp_calc_interval(), and rtp_reload().

int rtcpstats
static

Are we debugging RTCP?

Definition at line 212 of file res_rtp_asterisk.c.

struct ast_sockaddr rtpdebugaddr
static

Debug packets to/from this host

Definition at line 214 of file res_rtp_asterisk.c.

int rtpdebugport
static

Debug only RTP packets from IP or IP+Port if port is > 0

Definition at line 216 of file res_rtp_asterisk.c.

int rtpend = DEFAULT_RTP_END
static

Last port for RTP sessions (set in rtp.conf)

Definition at line 211 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

int rtpstart = DEFAULT_RTP_START
static

First port for RTP sessions (set in rtp.conf)

Definition at line 210 of file res_rtp_asterisk.c.

int strictrtp = DEFAULT_STRICT_RTP
static

Only accept RTP frames from a defined source. If we receive an indication of a changing source, enter learning mode.

Definition at line 221 of file res_rtp_asterisk.c.

Referenced by ast_rtp_remote_address_set(), and rtp_reload().

struct ast_acl_list* stun_acl = NULL
static

ACL for STUN requests

Definition at line 244 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

ast_rwlock_t stunaddr_lock = AST_RWLOCK_INIT_VALUE
static

stunaddr recurring resolution

Definition at line 248 of file res_rtp_asterisk.c.