From 715a220850e75a6ab377951a3efb31fbbbc0d5b7 Mon Sep 17 00:00:00 2001 From: Olle Johansson Date: Tue, 3 Jan 2006 09:30:19 +0000 Subject: Bug #6109: Fix unprotected list in RTP, implement AST_LIST macros, update doxygen docs git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@7730 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- rtp.c | 221 ++++++++++++++++++++++++++++++++---------------------------------- 1 file changed, 108 insertions(+), 113 deletions(-) (limited to 'rtp.c') diff --git a/rtp.c b/rtp.c index afdd6d129..3f0f7452a 100644 --- a/rtp.c +++ b/rtp.c @@ -61,38 +61,38 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #define RTP_MTU 1200 -#define DEFAULT_DTMF_TIMEOUT 3000 /* samples */ +#define DEFAULT_DTMF_TIMEOUT 3000 /*!< samples */ static int dtmftimeout = DEFAULT_DTMF_TIMEOUT; -static int rtpstart = 0; -static int rtpend = 0; -static int rtpdebug = 0; /* Are we debugging? */ -static struct sockaddr_in rtpdebugaddr; /* Debug packets to/from this host */ +static int rtpstart = 0; /*!< First port for RTP sessions (set in rtp.conf) */ +static int rtpend = 0; /*!< Last port for RTP sessions (set in rtp.conf) */ +static int rtpdebug = 0; /*!< Are we debugging? */ +static struct sockaddr_in rtpdebugaddr; /*!< Debug packets to/from this host */ #ifdef SO_NO_CHECK static int nochecksums = 0; #endif -/* The value of each payload format mapping: */ +/*! \brief The value of each payload format mapping: */ struct rtpPayloadType { - int isAstFormat; /* whether the following code is an AST_FORMAT */ + int isAstFormat; /*!< whether the following code is an AST_FORMAT */ int code; }; -#define MAX_RTP_PT 256 +#define MAX_RTP_PT 256 #define FLAG_3389_WARNING (1 << 0) #define FLAG_NAT_ACTIVE (3 << 1) #define FLAG_NAT_INACTIVE (0 << 1) #define FLAG_NAT_INACTIVE_NOWARN (1 << 1) +/*! \brief RTP session description */ struct ast_rtp { int s; char resp; struct ast_frame f; unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET]; - /*! Synchronization source, RFC 3550, page 10. */ - unsigned int ssrc; + unsigned int ssrc; /*!< Synchronization source, RFC 3550, page 10. */ unsigned int lastts; unsigned int lastdigitts; unsigned int lastrxts; @@ -106,25 +106,21 @@ struct ast_rtp { unsigned int dtmfduration; int nat; unsigned int flags; - /*! Socket representation of the local endpoint. */ - struct sockaddr_in us; - /*! Socket representation of the remote endpoint. */ - struct sockaddr_in them; + struct sockaddr_in us; /*!< Socket representation of the local endpoint. */ + struct sockaddr_in them; /*!< Socket representation of the remote endpoint. */ struct timeval rxcore; struct timeval txcore; struct timeval dtmfmute; struct ast_smoother *smoother; int *ioid; - /*! Sequence number, RFC 3550, page 13. */ - unsigned short seqno; + unsigned short seqno; /*!< Sequence number, RFC 3550, page 13. */ unsigned short rxseqno; struct sched_context *sched; struct io_context *io; void *data; ast_rtp_callback callback; struct rtpPayloadType current_RTP_PT[MAX_RTP_PT]; - /*! a cache for the result of rtp_lookup_code(): */ - int rtp_lookup_code_cache_isAstFormat; + int rtp_lookup_code_cache_isAstFormat; /*!< a cache for the result of rtp_lookup_code(): */ int rtp_lookup_code_cache_code; int rtp_lookup_code_cache_result; struct ast_rtcp *rtcp; @@ -141,15 +137,13 @@ struct ast_rtp { * */ struct ast_rtcp { - /*! Socket */ - int s; - /*! Socket representation of the local endpoint. */ - struct sockaddr_in us; - /*! Socket representation of the remote endpoint. */ - struct sockaddr_in them; + int s; /*!< Socket */ + struct sockaddr_in us; /*!< Socket representation of the local endpoint. */ + struct sockaddr_in them; /*!< Socket representation of the remote endpoint. */ }; -static struct ast_rtp_protocol *protos = NULL; +/*! \brief List of current sessions */ +static AST_LIST_HEAD_STATIC(protos, ast_rtp_protocol); int ast_rtp_fd(struct ast_rtp *rtp) { @@ -229,9 +223,8 @@ static struct ast_frame *process_cisco_dtmf(struct ast_rtp *rtp, unsigned char * struct ast_frame *f = NULL; event = ntohl(*((unsigned int *)(data))); event &= 0x001F; -#if 0 - printf("Cisco Digit: %08x (len = %d)\n", event, len); -#endif + if (option_debug > 2 || rtpdebug) + ast_log(LOG_DEBUG, "Cisco DTMF Digit: %08x (len = %d)\n", event, len); if (event < 10) { resp = '0' + event; } else if (event < 11) { @@ -269,6 +262,7 @@ static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *dat unsigned int duration; char resp = 0; struct ast_frame *f = NULL; + event = ntohl(*((unsigned int *)(data))); event >>= 24; event_end = ntohl(*((unsigned int *)(data))); @@ -276,7 +270,7 @@ static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *dat event_end >>= 24; duration = ntohl(*((unsigned int *)(data))); duration &= 0xFFFF; - if (rtpdebug) + if (rtpdebug || option_debug > 2) ast_log(LOG_DEBUG, "- RTP 2833 Event: %08x (len = %d)\n", event, len); if (event < 10) { resp = '0' + event; @@ -638,61 +632,61 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp) /* The following array defines the MIME Media type (and subtype) for each of our codecs, or RTP-specific data type. */ static struct { - struct rtpPayloadType payloadType; - char* type; - char* subtype; + struct rtpPayloadType payloadType; + char* type; + char* subtype; } mimeTypes[] = { - {{1, AST_FORMAT_G723_1}, "audio", "G723"}, - {{1, AST_FORMAT_GSM}, "audio", "GSM"}, - {{1, AST_FORMAT_ULAW}, "audio", "PCMU"}, - {{1, AST_FORMAT_ALAW}, "audio", "PCMA"}, - {{1, AST_FORMAT_G726}, "audio", "G726-32"}, - {{1, AST_FORMAT_ADPCM}, "audio", "DVI4"}, - {{1, AST_FORMAT_SLINEAR}, "audio", "L16"}, - {{1, AST_FORMAT_LPC10}, "audio", "LPC"}, - {{1, AST_FORMAT_G729A}, "audio", "G729"}, - {{1, AST_FORMAT_SPEEX}, "audio", "speex"}, - {{1, AST_FORMAT_ILBC}, "audio", "iLBC"}, - {{0, AST_RTP_DTMF}, "audio", "telephone-event"}, - {{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event"}, - {{0, AST_RTP_CN}, "audio", "CN"}, - {{1, AST_FORMAT_JPEG}, "video", "JPEG"}, - {{1, AST_FORMAT_PNG}, "video", "PNG"}, - {{1, AST_FORMAT_H261}, "video", "H261"}, - {{1, AST_FORMAT_H263}, "video", "H263"}, - {{1, AST_FORMAT_H263_PLUS}, "video", "h263-1998"}, + {{1, AST_FORMAT_G723_1}, "audio", "G723"}, + {{1, AST_FORMAT_GSM}, "audio", "GSM"}, + {{1, AST_FORMAT_ULAW}, "audio", "PCMU"}, + {{1, AST_FORMAT_ALAW}, "audio", "PCMA"}, + {{1, AST_FORMAT_G726}, "audio", "G726-32"}, + {{1, AST_FORMAT_ADPCM}, "audio", "DVI4"}, + {{1, AST_FORMAT_SLINEAR}, "audio", "L16"}, + {{1, AST_FORMAT_LPC10}, "audio", "LPC"}, + {{1, AST_FORMAT_G729A}, "audio", "G729"}, + {{1, AST_FORMAT_SPEEX}, "audio", "speex"}, + {{1, AST_FORMAT_ILBC}, "audio", "iLBC"}, + {{0, AST_RTP_DTMF}, "audio", "telephone-event"}, + {{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event"}, + {{0, AST_RTP_CN}, "audio", "CN"}, + {{1, AST_FORMAT_JPEG}, "video", "JPEG"}, + {{1, AST_FORMAT_PNG}, "video", "PNG"}, + {{1, AST_FORMAT_H261}, "video", "H261"}, + {{1, AST_FORMAT_H263}, "video", "H263"}, + {{1, AST_FORMAT_H263_PLUS}, "video", "h263-1998"}, }; /* Static (i.e., well-known) RTP payload types for our "AST_FORMAT..."s: also, our own choices for dynamic payload types. This is our master table for transmission */ static struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = { - [0] = {1, AST_FORMAT_ULAW}, + [0] = {1, AST_FORMAT_ULAW}, #ifdef USE_DEPRECATED_G726 - [2] = {1, AST_FORMAT_G726}, /* Technically this is G.721, but if Cisco can do it, so can we... */ + [2] = {1, AST_FORMAT_G726}, /* Technically this is G.721, but if Cisco can do it, so can we... */ #endif - [3] = {1, AST_FORMAT_GSM}, - [4] = {1, AST_FORMAT_G723_1}, - [5] = {1, AST_FORMAT_ADPCM}, /* 8 kHz */ - [6] = {1, AST_FORMAT_ADPCM}, /* 16 kHz */ - [7] = {1, AST_FORMAT_LPC10}, - [8] = {1, AST_FORMAT_ALAW}, - [10] = {1, AST_FORMAT_SLINEAR}, /* 2 channels */ - [11] = {1, AST_FORMAT_SLINEAR}, /* 1 channel */ - [13] = {0, AST_RTP_CN}, - [16] = {1, AST_FORMAT_ADPCM}, /* 11.025 kHz */ - [17] = {1, AST_FORMAT_ADPCM}, /* 22.050 kHz */ - [18] = {1, AST_FORMAT_G729A}, - [19] = {0, AST_RTP_CN}, /* Also used for CN */ - [26] = {1, AST_FORMAT_JPEG}, - [31] = {1, AST_FORMAT_H261}, - [34] = {1, AST_FORMAT_H263}, - [103] = {1, AST_FORMAT_H263_PLUS}, - [97] = {1, AST_FORMAT_ILBC}, - [101] = {0, AST_RTP_DTMF}, - [110] = {1, AST_FORMAT_SPEEX}, - [111] = {1, AST_FORMAT_G726}, - [121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */ + [3] = {1, AST_FORMAT_GSM}, + [4] = {1, AST_FORMAT_G723_1}, + [5] = {1, AST_FORMAT_ADPCM}, /* 8 kHz */ + [6] = {1, AST_FORMAT_ADPCM}, /* 16 kHz */ + [7] = {1, AST_FORMAT_LPC10}, + [8] = {1, AST_FORMAT_ALAW}, + [10] = {1, AST_FORMAT_SLINEAR}, /* 2 channels */ + [11] = {1, AST_FORMAT_SLINEAR}, /* 1 channel */ + [13] = {0, AST_RTP_CN}, + [16] = {1, AST_FORMAT_ADPCM}, /* 11.025 kHz */ + [17] = {1, AST_FORMAT_ADPCM}, /* 22.050 kHz */ + [18] = {1, AST_FORMAT_G729A}, + [19] = {0, AST_RTP_CN}, /* Also used for CN */ + [26] = {1, AST_FORMAT_JPEG}, + [31] = {1, AST_FORMAT_H261}, + [34] = {1, AST_FORMAT_H263}, + [103] = {1, AST_FORMAT_H263_PLUS}, + [97] = {1, AST_FORMAT_ILBC}, + [101] = {0, AST_RTP_DTMF}, + [110] = {1, AST_FORMAT_SPEEX}, + [111] = {1, AST_FORMAT_G726}, + [121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */ }; void ast_rtp_pt_clear(struct ast_rtp* rtp) @@ -741,18 +735,18 @@ static void ast_rtp_pt_copy(struct ast_rtp *dest, struct ast_rtp *src) dest->rtp_lookup_code_cache_result = 0; } -/*--- get_proto: Get channel driver interface structure */ +/*! \brief Get channel driver interface structure */ static struct ast_rtp_protocol *get_proto(struct ast_channel *chan) { struct ast_rtp_protocol *cur; - cur = protos; - while(cur) { - if (cur->type == chan->type) { + AST_LIST_LOCK(&protos); + AST_LIST_TRAVERSE(&protos, cur, list) { + if (cur->type == chan->type) return cur; - } - cur = cur->next; } + AST_LIST_UNLOCK(&protos); + return NULL; } @@ -773,13 +767,15 @@ int ast_rtp_make_compatible(struct ast_channel *dest, struct ast_channel *src) destpr = get_proto(dest); srcpr = get_proto(src); if (!destpr) { - ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", dest->name); + if (option_debug) + ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", dest->name); ast_mutex_unlock(&dest->lock); ast_mutex_unlock(&src->lock); return 0; } if (!srcpr) { - ast_log(LOG_WARNING, "Channel '%s' has no RTP, not doing anything\n", src->name); + if (option_debug) + ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", src->name); ast_mutex_unlock(&dest->lock); ast_mutex_unlock(&src->lock); return 0; @@ -809,13 +805,15 @@ int ast_rtp_make_compatible(struct ast_channel *dest, struct ast_channel *src) ast_rtp_pt_copy(vdestp, vsrcp); ast_mutex_unlock(&dest->lock); ast_mutex_unlock(&src->lock); - ast_log(LOG_DEBUG, "Seeded SDP of '%s' with that of '%s'\n", dest->name, src->name); + if (option_debug) + ast_log(LOG_DEBUG, "Seeded SDP of '%s' with that of '%s'\n", dest->name, src->name); return 1; } -/* Make a note of a RTP paymoad type that was seen in a SDP "m=" line. */ -/* By default, use the well-known value for this type (although it may */ -/* still be set to a different value by a subsequent "a=rtpmap:" line): */ +/*! \brief Make a note of a RTP paymoad type that was seen in a SDP "m=" line. + * By default, use the well-known value for this type (although it may + * still be set to a different value by a subsequent "a=rtpmap:" line) + */ void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt) { if (pt < 0 || pt > MAX_RTP_PT) @@ -826,11 +824,10 @@ void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt) } } -/* Make a note of a RTP payload type (with MIME type) that was seen in */ -/* a SDP "a=rtpmap:" line. */ +/*! \brief Make a note of a RTP payload type (with MIME type) that was seen in + a SDP "a=rtpmap:" line. */ void ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt, char* mimeType, char* mimeSubtype) - { int i; @@ -846,8 +843,8 @@ void ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt, } } -/* Return the union of all of the codecs that were set by rtp_set...() calls */ -/* They're returned as two distinct sets: AST_FORMATs, and AST_RTPs */ +/*! \brief Return the union of all of the codecs that were set by rtp_set...() calls + * They're returned as two distinct sets: AST_FORMATs, and AST_RTPs */ void ast_rtp_get_current_formats(struct ast_rtp* rtp, int* astFormats, int* nonAstFormats) { int pt; @@ -879,7 +876,7 @@ struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt) return result; } -/* Looks up an RTP code out of our *static* outbound list */ +/*! \brief Looks up an RTP code out of our *static* outbound list */ int ast_rtp_lookup_code(struct ast_rtp* rtp, const int isAstFormat, const int code) { int pt; @@ -1533,44 +1530,42 @@ int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_f) return 0; } -/*--- ast_rtp_proto_unregister: Unregister interface to channel driver */ +/*! \brief Unregister interface to channel driver */ void ast_rtp_proto_unregister(struct ast_rtp_protocol *proto) { - struct ast_rtp_protocol *cur, *prev; + struct ast_rtp_protocol *cur; - cur = protos; - prev = NULL; - while(cur) { + AST_LIST_LOCK(&protos); + AST_LIST_TRAVERSE_SAFE_BEGIN(&protos, cur, list) { if (cur == proto) { - if (prev) - prev->next = proto->next; - else - protos = proto->next; - return; + AST_LIST_REMOVE_CURRENT(&protos, list); + break; } - prev = cur; - cur = cur->next; } + AST_LIST_TRAVERSE_SAFE_END + AST_LIST_UNLOCK(&protos); } -/*--- ast_rtp_proto_register: Register interface to channel driver */ +/*! \brief Register interface to channel driver */ int ast_rtp_proto_register(struct ast_rtp_protocol *proto) { struct ast_rtp_protocol *cur; - cur = protos; - while(cur) { + + AST_LIST_LOCK(&protos); + AST_LIST_TRAVERSE(&protos, cur, list) { if (cur->type == proto->type) { ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type); + AST_LIST_UNLOCK(&protos); return -1; } - cur = cur->next; } - proto->next = protos; - protos = proto; + AST_LIST_INSERT_HEAD(&protos, proto, list); + AST_LIST_UNLOCK(&protos); + return 0; } -/* ast_rtp_bridge: Bridge calls. If possible and allowed, initiate +/*! \brief Bridge calls. If possible and allowed, initiate re-invite so the peers exchange media directly outside of Asterisk. */ enum ast_bridge_result ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) @@ -1935,7 +1930,7 @@ void ast_rtp_reload(void) } -/*--- ast_rtp_init: Initialize the RTP system in Asterisk */ +/*! \brief Initialize the RTP system in Asterisk */ void ast_rtp_init(void) { ast_cli_register(&cli_debug); -- cgit v1.2.3