[asterisk-commits] branch oej/sipdiversion r9015 - in /team/oej/sipdiversion: ./ apps/ channels/...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Jan 31 11:54:53 MST 2006


Author: oej
Date: Tue Jan 31 12:54:41 2006
New Revision: 9015

URL: http://svn.digium.com/view/asterisk?rev=9015&view=rev
Log:
Merged revisions 8906,8919,8925-8926,8932,8938,8948-8949,8961,8976,8991,9001,9004,9013 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
r8906 | kpfleming | 2006-01-30 18:09:55 +0100 (Mon, 30 Jan 2006) | 10 lines

Merged revisions 8905 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r8905 | kpfleming | 2006-01-30 11:08:28 -0600 (Mon, 30 Jan 2006) | 2 lines

disable buggy PRI user-user code until it can be fixed

........

................
r8919 | oej | 2006-01-30 19:51:02 +0100 (Mon, 30 Jan 2006) | 6 lines

Issue #5793 
- simplification of check_auth
- constifications
- whitespace changes
Rizzo's patch with some changes

................
r8925 | oej | 2006-01-30 20:09:08 +0100 (Mon, 30 Jan 2006) | 3 lines

Issue #6035 - Don't send 403 on bad auth (correcting one of my old mistakes...) Reported by maik.
Patch inspired by, but not the patch in the bug tracker.

................
r8926 | oej | 2006-01-30 20:50:39 +0100 (Mon, 30 Jan 2006) | 2 lines

Issue 5892: Set a minimum T1 timer for calls. Reporter: twisted

................
r8932 | oej | 2006-01-30 21:36:38 +0100 (Mon, 30 Jan 2006) | 8 lines

- Doxygen and comments updates
- Moving structure declarations to top of file with the rest
- Adding some forward declarations for RTP interface functions

(All these changes to position in file are in preparation for splitting chan_sip up
into several files at some point in the future)


................
r8938 | mogorman | 2006-01-30 22:16:43 +0100 (Mon, 30 Jan 2006) | 3 lines

reverting  blocks 9 and 10 from revision 7547
fixes bug 6080

................
r8948 | kpfleming | 2006-01-31 01:17:43 +0100 (Tue, 31 Jan 2006) | 2 lines

increment for recent ast_channel change

................
r8949 | russell | 2006-01-31 01:24:34 +0100 (Tue, 31 Jan 2006) | 3 lines

add a note to hopefully decrease the chance that someone forgets to increment
.cleancount after changing the ast_channel structure

................
r8961 | kpfleming | 2006-01-31 04:45:09 +0100 (Tue, 31 Jan 2006) | 2 lines

Yes Virginia, Zaptel does support native ALAW

................
r8976 | oej | 2006-01-31 15:30:09 +0100 (Tue, 31 Jan 2006) | 3 lines

- Change "prefs" to "default_prefs" and move declaration to "default" group
- Add doxygen comments

................
r8991 | oej | 2006-01-31 17:02:35 +0100 (Tue, 31 Jan 2006) | 4 lines

- Moving two session (PVT) flags to peer PAGE2 (DYNAMIC and SELFDESTRUCT) to make room for more session-related flags
  This is needed for integrating patches in the bug tracker
- Adding doxygen comments

................
r9001 | russell | 2006-01-31 18:18:58 +0100 (Tue, 31 Jan 2006) | 3 lines

define a global null_frame object so when queueing a null frame, you don't
have to allocate one on the stack

................
r9004 | russell | 2006-01-31 18:57:12 +0100 (Tue, 31 Jan 2006) | 2 lines

remove some more local declarations of null frames

................
r9013 | oej | 2006-01-31 19:40:07 +0100 (Tue, 31 Jan 2006) | 3 lines

Optimize settings of defaults for a new peer object and make sure
we set the same defaults for autocreated peers and other peers.

................

Modified:
    team/oej/sipdiversion/   (props changed)
    team/oej/sipdiversion/.cleancount
    team/oej/sipdiversion/apps/app_meetme.c
    team/oej/sipdiversion/channel.c
    team/oej/sipdiversion/channels/chan_agent.c
    team/oej/sipdiversion/channels/chan_features.c
    team/oej/sipdiversion/channels/chan_h323.c
    team/oej/sipdiversion/channels/chan_iax2.c
    team/oej/sipdiversion/channels/chan_local.c
    team/oej/sipdiversion/channels/chan_mgcp.c
    team/oej/sipdiversion/channels/chan_sip.c
    team/oej/sipdiversion/channels/chan_zap.c
    team/oej/sipdiversion/configs/sip.conf.sample
    team/oej/sipdiversion/frame.c
    team/oej/sipdiversion/include/asterisk/channel.h
    team/oej/sipdiversion/include/asterisk/frame.h
    team/oej/sipdiversion/rtp.c
    team/oej/sipdiversion/udptl.c

Propchange: team/oej/sipdiversion/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Jan 31 12:54:41 2006
@@ -1,1 +1,1 @@
-/trunk:1-8901
+/trunk:1-9013

Modified: team/oej/sipdiversion/.cleancount
URL: http://svn.digium.com/view/asterisk/team/oej/sipdiversion/.cleancount?rev=9015&r1=9014&r2=9015&view=diff
==============================================================================
--- team/oej/sipdiversion/.cleancount (original)
+++ team/oej/sipdiversion/.cleancount Tue Jan 31 12:54:41 2006
@@ -1,1 +1,1 @@
-8
+9

Modified: team/oej/sipdiversion/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipdiversion/apps/app_meetme.c?rev=9015&r1=9014&r2=9015&view=diff
==============================================================================
--- team/oej/sipdiversion/apps/app_meetme.c (original)
+++ team/oej/sipdiversion/apps/app_meetme.c Tue Jan 31 12:54:41 2006
@@ -206,7 +206,6 @@
 };
 
 static int admin_exec(struct ast_channel *chan, void *data);
-static struct ast_frame null_frame = { AST_FRAME_NULL, };
 
 static void *recordthread(void *args);
 
@@ -426,8 +425,6 @@
 	unsigned char *data;
 	int len;
 	int res = -1;
-	short *data2;
-	int x;
 
 	if (!chan->_softhangup)
 		res = ast_autoservice_start(chan);
@@ -448,10 +445,7 @@
 		len = 0;
 	}
 	if (data) {
-		data2 = alloca(len * 2);
-		for (x=0;x<len;x++)
-			data2[x] = AST_MULAW(data[x]);
-		careful_write(conf->fd, (unsigned char *)data2, len << 1, 1);
+		careful_write(conf->fd, data, len, 1);
 	}
 
 	AST_LIST_UNLOCK(&confs);
@@ -1579,7 +1573,7 @@
 								if (conf->transpath[index]) {
 									conf->transframe[index] = ast_translate(conf->transpath[index], conf->origframe, 0);
 									if (!conf->transframe[index])
-										conf->transframe[index] = &null_frame;
+										conf->transframe[index] = &ast_null_frame;
 								}
 							}
 						}

Modified: team/oej/sipdiversion/channel.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipdiversion/channel.c?rev=9015&r1=9014&r2=9015&view=diff
==============================================================================
--- team/oej/sipdiversion/channel.c (original)
+++ team/oej/sipdiversion/channel.c Tue Jan 31 12:54:41 2006
@@ -1760,17 +1760,13 @@
 	void *data;
 	int res;
 #endif
-	static struct ast_frame null_frame = {
-		AST_FRAME_NULL,
-	};
-	
 	ast_mutex_lock(&chan->lock);
 	if (chan->masq) {
 		if (ast_do_masquerade(chan)) {
 			ast_log(LOG_WARNING, "Failed to perform masquerade\n");
 			f = NULL;
 		} else
-			f =  &null_frame;
+			f =  &ast_null_frame;
 		ast_mutex_unlock(&chan->lock);
 		return f;
 	}
@@ -1838,8 +1834,7 @@
 				chan->timingdata = NULL;
 				ast_mutex_unlock(&chan->lock);
 			}
-			f =  &null_frame;
-			return f;
+			return &ast_null_frame;
 		} else
 			ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name);
 	} else
@@ -1851,8 +1846,7 @@
 		chan->generatordata = NULL;     /* reset to let ast_write get through */
 		chan->generator->generate(chan, tmp, -1, -1);
 		chan->generatordata = tmp;
-		f = &null_frame;
-		return f;
+		return &ast_null_frame;
 	}
 
 	/* Check for pending read queue */
@@ -1872,7 +1866,7 @@
 				f = chan->tech->exception(chan);
 			else {
 				ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
-				f = &null_frame;
+				f = &ast_null_frame;
 			}
 			/* Clear the exception flag */
 			ast_clear_flag(chan, AST_FLAG_EXCEPTION);
@@ -1898,7 +1892,7 @@
 			if (f->subclass == AST_CONTROL_ANSWER) {
 				if (prestate == AST_STATE_UP) {
 					ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
-					f = &null_frame;
+					f = &ast_null_frame;
 				}
 				/* Answer the CDR */
 				ast_setstate(chan, AST_STATE_UP);
@@ -1912,7 +1906,7 @@
 					chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
 				else
 					ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
-				f = &null_frame;
+				f = &ast_null_frame;
 			}
 			break;
 		case AST_FRAME_DTMF_BEGIN:
@@ -1924,14 +1918,14 @@
 		case AST_FRAME_VOICE:
 			if (dropaudio) {
 				ast_frfree(f);
-				f = &null_frame;
+				f = &ast_null_frame;
 			} else if (!(f->subclass & chan->nativeformats)) {
 				/* This frame can't be from the current native formats -- drop it on the
 				   floor */
 				ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
 					chan->name, ast_getformatname(f->subclass), ast_getformatname(chan->nativeformats));
 				ast_frfree(f);
-				f = &null_frame;
+				f = &ast_null_frame;
 			} else {
 				if (chan->spies)
 					queue_frame_to_spies(chan, f, SPY_READ);
@@ -1962,7 +1956,7 @@
 
 				if (chan->readtrans) {
 					if (!(f = ast_translate(chan->readtrans, f, 1)))
-						f = &null_frame;
+						f = &ast_null_frame;
 				}
 
 				/* Run any generator sitting on the channel */
@@ -3121,10 +3115,9 @@
 			);
 		ast_channel_free(clone);
 	} else {
-		struct ast_frame null_frame = { AST_FRAME_NULL, };
 		ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
 		ast_set_flag(clone, AST_FLAG_ZOMBIE);
-		ast_queue_frame(clone, &null_frame);
+		ast_queue_frame(clone, &ast_null_frame);
 		ast_mutex_unlock(&clone->lock);
 	}
 	

Modified: team/oej/sipdiversion/channels/chan_agent.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipdiversion/channels/chan_agent.c?rev=9015&r1=9014&r2=9015&view=diff
==============================================================================
--- team/oej/sipdiversion/channels/chan_agent.c (original)
+++ team/oej/sipdiversion/channels/chan_agent.c Tue Jan 31 12:54:41 2006
@@ -438,7 +438,6 @@
 {
 	struct agent_pvt *p = ast->tech_pvt;
 	struct ast_frame *f = NULL;
-	static struct ast_frame null_frame = { AST_FRAME_NULL, };
 	static struct ast_frame answer_frame = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
 	const char *status;
 	ast_mutex_lock(&p->lock); 
@@ -448,7 +447,7 @@
 		p->chan->fdno = (ast->fdno == AST_AGENT_FD) ? AST_TIMING_FD : ast->fdno;
 		f = ast_read(p->chan);
 	} else
-		f = &null_frame;
+		f = &ast_null_frame;
 	if (!f) {
 		/* If there's a channel, hang it up (if it's on a callback) make it NULL */
 		if (p->chan) {
@@ -486,7 +485,7 @@
  						ast_verbose(VERBOSE_PREFIX_3 "%s answered, waiting for '#' to acknowledge\n", p->chan->name);
  					/* Don't pass answer along */
  					ast_frfree(f);
- 					f = &null_frame;
+ 					f = &ast_null_frame;
  				} else {
  					p->acknowledged = 1;
  					/* Use the builtin answer frame for the 
@@ -513,7 +512,7 @@
  			/* don't pass voice until the call is acknowledged */
  			if (!p->acknowledged) {
  				ast_frfree(f);
- 				f = &null_frame;
+ 				f = &ast_null_frame;
  			}
  			break;
   		}
@@ -899,7 +898,6 @@
 static struct ast_channel *agent_new(struct agent_pvt *p, int state)
 {
 	struct ast_channel *tmp;
-	struct ast_frame null_frame = { AST_FRAME_NULL };
 #if 0
 	if (!p->chan) {
 		ast_log(LOG_WARNING, "No channel? :(\n");
@@ -950,7 +948,7 @@
 		if( ast_mutex_trylock(&p->app_lock) )
 		{
 			if (p->chan) {
-				ast_queue_frame(p->chan, &null_frame);
+				ast_queue_frame(p->chan, &ast_null_frame);
 				ast_mutex_unlock(&p->lock);	/* For other thread to read the condition. */
 				ast_mutex_lock(&p->app_lock);
 				ast_mutex_lock(&p->lock);

Modified: team/oej/sipdiversion/channels/chan_features.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipdiversion/channels/chan_features.c?rev=9015&r1=9014&r2=9015&view=diff
==============================================================================
--- team/oej/sipdiversion/channels/chan_features.c (original)
+++ team/oej/sipdiversion/channels/chan_features.c Tue Jan 31 12:54:41 2006
@@ -241,12 +241,11 @@
 
 static struct ast_frame  *features_read(struct ast_channel *ast)
 {
-	static struct ast_frame null_frame = { AST_FRAME_NULL, };
 	struct feature_pvt *p = ast->tech_pvt;
 	struct ast_frame *f;
 	int x;
 	
-	f = &null_frame;
+	f = &ast_null_frame;
 	ast_mutex_lock(&p->lock);
 	x = indexof(p, ast, 0);
 	if (!x && p->subchan) {

Modified: team/oej/sipdiversion/channels/chan_h323.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipdiversion/channels/chan_h323.c?rev=9015&r1=9014&r2=9015&view=diff
==============================================================================
--- team/oej/sipdiversion/channels/chan_h323.c (original)
+++ team/oej/sipdiversion/channels/chan_h323.c Tue Jan 31 12:54:41 2006
@@ -543,7 +543,6 @@
 {
 	/* Retrieve audio/etc from channel.  Assumes pvt->lock is already held. */
 	struct ast_frame *f;
-	static struct ast_frame null_frame = { AST_FRAME_NULL, };
 
 	/* Only apply it for the first packet, we just need the correct ip/port */
 	if (pvt->options.nat) {
@@ -554,7 +553,7 @@
 	f = ast_rtp_read(pvt->rtp);
 	/* Don't send RFC2833 if we're not supposed to */
 	if (f && (f->frametype == AST_FRAME_DTMF) && !(pvt->options.dtmfmode & H323_DTMF_RFC2833)) {
-		return &null_frame;
+		return &ast_null_frame;
 	}
 	if (pvt->owner) {
 		/* We already hold the channel lock */
@@ -563,7 +562,7 @@
 				/* Try to avoid deadlock */
 				if (ast_mutex_trylock(&pvt->owner->lock)) {
 					ast_log(LOG_NOTICE, "Format changed but channel is locked. Ignoring frame...\n");
-					return &null_frame;
+					return &ast_null_frame;
 				}
 				ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
 				pvt->owner->nativeformats = f->subclass;

Modified: team/oej/sipdiversion/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipdiversion/channels/chan_iax2.c?rev=9015&r1=9014&r2=9015&view=diff
==============================================================================
--- team/oej/sipdiversion/channels/chan_iax2.c (original)
+++ team/oej/sipdiversion/channels/chan_iax2.c Tue Jan 31 12:54:41 2006
@@ -3103,9 +3103,8 @@
 
 static struct ast_frame *iax2_read(struct ast_channel *c) 
 {
-	static struct ast_frame f = { AST_FRAME_NULL, };
 	ast_log(LOG_NOTICE, "I should never be called!\n");
-	return &f;
+	return &ast_null_frame;
 }
 
 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1)

Modified: team/oej/sipdiversion/channels/chan_local.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipdiversion/channels/chan_local.c?rev=9015&r1=9014&r2=9015&view=diff
==============================================================================
--- team/oej/sipdiversion/channels/chan_local.c (original)
+++ team/oej/sipdiversion/channels/chan_local.c Tue Jan 31 12:54:41 2006
@@ -224,9 +224,7 @@
 
 static struct ast_frame  *local_read(struct ast_channel *ast)
 {
-	static struct ast_frame null = { AST_FRAME_NULL, };
-
-	return &null;
+	return &ast_null_frame;
 }
 
 static int local_write(struct ast_channel *ast, struct ast_frame *f)

Modified: team/oej/sipdiversion/channels/chan_mgcp.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipdiversion/channels/chan_mgcp.c?rev=9015&r1=9014&r2=9015&view=diff
==============================================================================
--- team/oej/sipdiversion/channels/chan_mgcp.c (original)
+++ team/oej/sipdiversion/channels/chan_mgcp.c Tue Jan 31 12:54:41 2006
@@ -1219,12 +1219,11 @@
 {
 	/* Retrieve audio/etc from channel.  Assumes sub->lock is already held. */
 	struct ast_frame *f;
-	static struct ast_frame null_frame = { AST_FRAME_NULL, };
 
 	f = ast_rtp_read(sub->rtp);
 	/* Don't send RFC2833 if we're not supposed to */
 	if (f && (f->frametype == AST_FRAME_DTMF) && !(sub->parent->dtmfmode & MGCP_DTMF_RFC2833))
-		return &null_frame;
+		return &ast_null_frame;
 	if (sub->owner) {
 		/* We already hold the channel lock */
 		if (f->frametype == AST_FRAME_VOICE) {

Modified: team/oej/sipdiversion/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipdiversion/channels/chan_sip.c?rev=9015&r1=9014&r2=9015&view=diff
==============================================================================
--- team/oej/sipdiversion/channels/chan_sip.c (original)
+++ team/oej/sipdiversion/channels/chan_sip.c Tue Jan 31 12:54:41 2006
@@ -34,6 +34,7 @@
  * \todo Better support of forking
  *
  * \ingroup channel_drivers
+ *
  */
 
 
@@ -363,6 +364,7 @@
 #define DEFAULT_PEDANTIC	FALSE
 #define DEFAULT_AUTOCREATEPEER	FALSE
 #define DEFAULT_QUALIFY		FALSE
+#define DEFAULT_T1MIN		100		/*!< 100 MS for minimal roundtrip time */
 #ifndef DEFAULT_USERAGENT
 #define DEFAULT_USERAGENT "Asterisk PBX"	/*!< Default Useragent: header unless re-defined in sip.conf */
 #endif
@@ -378,6 +380,7 @@
 static int default_qualify;		/*!< Default Qualify= setting */
 static char default_vmexten[AST_MAX_EXTENSION];
 static char default_musicclass[MAX_MUSICCLASS];		/*!< Global music on hold class */
+static struct ast_codec_pref default_prefs;		/*!< Default codec prefs */
 
 /* Global settings only apply to the channel */
 static int global_rtautoclear = 120;
@@ -403,6 +406,7 @@
 static char global_useragent[AST_MAX_EXTENSION];	/*!< Useragent for the SIP channel */
 static int allow_external_domains;	/*!< Accept calls to external SIP domains? */
 static int global_callevents;		/*!< Whether we send manager events or not */
+static int global_t1min;		/*!< T1 roundtrip time minimum */
 
 /*! \brief Codecs that we support by default: */
 static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263;
@@ -441,13 +445,12 @@
 static int sip_reloading = FALSE;			/*!< Flag for avoiding multiple reloads at the same time */
 static enum channelreloadreason sip_reloadreason;	/*!< Reason for last reload/load of configuration */
 
-static struct sched_context *sched;
-static struct io_context *io;
+static struct sched_context *sched;	/*!< The scheduling context */
+static struct io_context *io;		/*!< The IO context */
 
 #define DEC_CALL_LIMIT	0
 #define INC_CALL_LIMIT	1
 
-static struct ast_codec_pref prefs;
 
 /*! \brief sip_request: The data grabbed from the UDP socket */
 struct sip_request {
@@ -464,6 +467,13 @@
 	unsigned int flags;	/*!< SIP_PKT Flags for this packet */
 };
 
+/*! \brief structure used in transfers */
+struct sip_dual {
+	struct ast_channel *chan1;
+	struct ast_channel *chan2;
+	struct sip_request req;
+};
+
 struct sip_pkt;
 
 /*! \brief Parameters to the transmit_invite function */
@@ -478,11 +488,13 @@
 	enum sip_auth_type auth_type;	/*!< Authentication type */
 };
 
+/*! \brief Structure to save routing information for a SIP session */
 struct sip_route {
 	struct sip_route *next;
 	char hop[0];
 };
 
+/*! \brief Modes for SIP domain handling in the PBX */
 enum domain_mode {
 	SIP_DOMAIN_AUTO,	/*!< This domain is auto-configured */
 	SIP_DOMAIN_CONFIG,	/*!< This domain is from configuration */
@@ -515,7 +527,9 @@
 	struct sip_auth *next;          /*!< Next auth structure in list */
 };
 
-/*--- Various flags for the flags field in the pvt structure */
+/*--- Various flags for the flags field in the pvt structure 
+ Peer only flags should be set in PAGE2 below
+*/
 #define SIP_ALREADYGONE		(1 << 0)	/*!< Whether or not we've already been destroyed by our peer */
 #define SIP_NEEDDESTROY		(1 << 1)	/*!< if we need to be destroyed */
 #define SIP_NOVIDEO		(1 << 2)	/*!< Didn't get video in invite, don't offer */
@@ -530,14 +544,13 @@
 #define SIP_REALTIME		(1 << 11)	/*!< Flag for realtime users */
 #define SIP_USECLIENTCODE	(1 << 12)	/*!< Trust X-ClientCode info message */
 #define SIP_OUTGOING		(1 << 13)	/*!< Is this an outgoing call? */
-#define SIP_SELFDESTRUCT	(1 << 14)	
-#define SIP_DYNAMIC		(1 << 15)	/*!< Is this a dynamic peer? */
-/* --- Choices for DTMF support in SIP channel */
-#define SIP_DTMF		(3 << 16)	/*!< three settings, uses two bits */
-#define SIP_DTMF_RFC2833	(0 << 16)	/*!< RTP DTMF */
-#define SIP_DTMF_INBAND		(1 << 16)	/*!< Inband audio, only for ULAW/ALAW */
-#define SIP_DTMF_INFO		(2 << 16)	/*!< SIP Info messages */
-#define SIP_DTMF_AUTO		(3 << 16)	/*!< AUTO switch between rfc2833 and in-band DTMF */
+#define SIP_FREEBIT		(1 << 14)	/*!< Free for session-related use */
+#define SIP_FREEBIT3		(1 << 15)	/*!< Free for session-related use */
+#define SIP_DTMF		(3 << 16)	/*!< DTMF Support: four settings, uses two bits */
+#define SIP_DTMF_RFC2833	(0 << 16)	/*!< DTMF Support: RTP DTMF - "rfc2833" */
+#define SIP_DTMF_INBAND		(1 << 16)	/*!< DTMF Support: Inband audio, only for ULAW/ALAW - "inband" */
+#define SIP_DTMF_INFO		(2 << 16)	/*!< DTMF Support: SIP Info messages - "info" */
+#define SIP_DTMF_AUTO		(3 << 16)	/*!< DTMF Support: AUTO switch between rfc2833 and in-band DTMF */
 /* NAT settings */
 #define SIP_NAT			(3 << 18)	/*!< four settings, uses two bits */
 #define SIP_NAT_NEVER		(0 << 18)	/*!< No nat support */
@@ -575,7 +588,7 @@
 	 SIP_PROG_INBAND | SIP_OSPAUTH | SIP_USECLIENTCODE | SIP_NAT | \
 	 SIP_INSECURE_PORT | SIP_INSECURE_INVITE)
 
-/* a new page of flags for peer */
+/* a new page of flags for peers */
 #define SIP_PAGE2_RTCACHEFRIENDS	(1 << 0)
 #define SIP_PAGE2_RTUPDATE		(1 << 1)
 #define SIP_PAGE2_RTAUTOCLEAR		(1 << 2)
@@ -584,6 +597,8 @@
 #define SIP_PAGE2_DEBUG			(3 << 5)
 #define SIP_PAGE2_DEBUG_CONFIG 		(1 << 5)
 #define SIP_PAGE2_DEBUG_CONSOLE 	(1 << 6)
+#define SIP_PAGE2_DYNAMIC		(1 << 7)	/*!< Dynamic Peers register with Asterisk */
+#define SIP_PAGE2_SELFDESTRUCT		(1 << 8)	/*!< Automatic peers need to destruct themselves */
 
 /* SIP packet flags */
 #define SIP_PKT_DEBUG		(1 << 0)	/*!< Debug this packet */
@@ -898,7 +913,7 @@
 static int transmit_response(struct sip_pvt *p, char *msg, struct sip_request *req);
 static int transmit_response_with_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, int retrans);
 static int transmit_response_with_unsupported(struct sip_pvt *p, char *msg, struct sip_request *req, char *unsupported);
-static int transmit_response_with_auth(struct sip_pvt *p, char *msg, struct sip_request *req, const char *rand, int reliable, char *header, int stale);
+static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, struct sip_request *req, const char *rand, int reliable, const char *header, int stale);
 static int transmit_request(struct sip_pvt *p, int sipmethod, int inc, int reliable, int newbranch);
 static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int inc, int reliable, int newbranch);
 static int transmit_invite(struct sip_pvt *p, int sipmethod, int sendsdp, int init);
@@ -917,7 +932,6 @@
 static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime);
 static int sip_do_reload(enum channelreloadreason reason);
 static int expire_register(void *data);
-
 static struct ast_channel *sip_request_call(const char *type, int format, void *data, int *cause);
 static int sip_devicestate(void *data);
 static int sip_sendtext(struct ast_channel *ast, const char *text);
@@ -933,6 +947,9 @@
 static int clear_realm_authentication(struct sip_auth *authlist);                            /* Clear realm authentication list (at reload) */
 static struct sip_auth *add_realm_authentication(struct sip_auth *authlist, char *configuration, int lineno);   /* Add realm authentication in list */
 static struct sip_auth *find_realm_authentication(struct sip_auth *authlist, const char *realm);         /* Find authentication for a specific realm */
+static int check_auth(struct sip_pvt *p, struct sip_request *req, const char *username,
+		      const char *secret, const char *md5secret, int sipmethod,
+		      char *uri, int reliable, int ignore);
 static int check_sip_domain(const char *domain, char *context, size_t len); /* Check if domain is one of our local domains */
 static void append_date(struct sip_request *req);	/* Append date to SIP packet */
 static int determine_firstline_parts(struct sip_request *req);
@@ -944,13 +961,22 @@
 static unsigned int parse_sip_options(struct sip_pvt *pvt, char *supported);
 static void sip_destroy(struct sip_pvt *p);
 static void parse_request(struct sip_request *req);
-static char *get_header(struct sip_request *req, char *name);
+static char *get_header(struct sip_request *req, const char *name);
 static void copy_request(struct sip_request *dst,struct sip_request *src);
 static int transmit_response_reliable(struct sip_pvt *p, char *msg, struct sip_request *req, int fatal);
 static int transmit_register(struct sip_registry *r, int sipmethod, char *auth, char *authheader);
 static int sip_poke_peer(struct sip_peer *peer);
 static int __sip_do_register(struct sip_registry *r);
 static int restart_monitor(void);
+static void set_peer_defaults(struct sip_peer *peer);
+static struct sip_peer *temp_peer(const char *name);
+
+
+/*----- RTP interface functions */
+static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active);
+static struct ast_rtp *sip_get_rtp_peer(struct ast_channel *chan);
+static struct ast_rtp *sip_get_vrtp_peer(struct ast_channel *chan);
+static int sip_get_codec(struct ast_channel *chan);
 
 /*! \brief Definition of this channel for PBX channel registration */
 static const struct ast_channel_tech sip_tech = {
@@ -974,6 +1000,16 @@
 	.send_text = sip_sendtext,
 };
 
+/*! \brief Interface structure with callbacks used to connect to RTP module */
+static struct ast_rtp_protocol sip_rtp = {
+	type: channeltype,
+	get_rtp_info: sip_get_rtp_peer,
+	get_vrtp_info: sip_get_vrtp_peer,
+	set_rtp_peer: sip_set_rtp_peer,
+	get_codec: sip_get_codec,
+};
+
+
 /*!
   \brief Thread-safe random number generator
   \return a random number
@@ -1287,7 +1323,9 @@
 	return 0;
 }
 
-/*! \brief Transmit packet with retransmits */
+/*! \brief Transmit packet with retransmits 
+	\return 0 on success, -1 on failure to allocate packet 
+*/
 static int __sip_reliable_xmit(struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod)
 {
 	struct sip_pkt *pkt;
@@ -1654,7 +1692,7 @@
 		ast_sched_del(sched, peer->pokeexpire);
 	register_peer_exten(peer, 0);
 	ast_free_ha(peer->ha);
-	if (ast_test_flag(peer, SIP_SELFDESTRUCT))
+	if (ast_test_flag((&peer->flags_page2), SIP_PAGE2_SELFDESTRUCT))
 		apeerobjs--;
 	else if (ast_test_flag(peer, SIP_REALTIME))
 		rpeerobjs--;
@@ -1914,8 +1952,9 @@
 	r->callgroup = peer->callgroup;
 	r->pickupgroup = peer->pickupgroup;
 	/* Set timer T1 to RTT for this peer (if known by qualify=) */
+	/* Minimum is settable or default to 100 ms */
 	if (peer->maxms && peer->lastms)
-		r->timer_t1 = peer->lastms;
+		r->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
 	if ((ast_test_flag(r, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(r, SIP_DTMF) == SIP_DTMF_AUTO))
 		r->noncodeccapability |= AST_RTP_DTMF;
 	else
@@ -2971,7 +3010,7 @@
 	return _default;
 }
 
-static char *__get_header(struct sip_request *req, char *name, int *start)
+static char *__get_header(struct sip_request *req, const char *name, int *start)
 {
 	int pass;
 
@@ -3007,7 +3046,7 @@
 }
 
 /*! \brief Get header from SIP request */
-static char *get_header(struct sip_request *req, char *name)
+static char *get_header(struct sip_request *req, const char *name)
 {
 	int start = 0;
 	return __get_header(req, name, &start);
@@ -3018,11 +3057,10 @@
 {
 	/* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
 	struct ast_frame *f;
-	static struct ast_frame null_frame = { AST_FRAME_NULL, };
 	
 	if (!p->rtp) {
 		/* We have no RTP allocated for this channel */
-		return &null_frame;
+		return &ast_null_frame;
 	}
 
 	switch(ast->fdno) {
@@ -3039,11 +3077,11 @@
 		f = ast_rtcp_read(p->vrtp);	/* RTCP Control Channel for video */
 		break;
 	default:
-		f = &null_frame;
+		f = &ast_null_frame;
 	}
 	/* Don't forward RFC2833 if we're not supposed to */
 	if (f && (f->frametype == AST_FRAME_DTMF) && (ast_test_flag(p, SIP_DTMF) != SIP_DTMF_RFC2833))
-		return &null_frame;
+		return &ast_null_frame;
 
 	if (p->owner) {
 		/* We already hold the channel lock */
@@ -3142,7 +3180,8 @@
 	p->autokillid = -1;
 	p->subscribed = NONE;
 	p->stateid = -1;
-	p->prefs = prefs;
+	p->prefs = default_prefs;		/* Set default codecs for this call */
+
 	if (intended_method != SIP_OPTIONS)	/* Peerpoke has it's own system */
 		p->timer_t1 = 500;	/* Default SIP retransmission timer T1 (RFC 3261) */
 #ifdef OSP_SUPPORT
@@ -3725,12 +3764,11 @@
 	if ((bridgepeer=ast_bridged_channel(p->owner))) {
 		/* We have a bridge */
 		/* Turn on/off music on hold if we are holding/unholding */
-		struct ast_frame af = { AST_FRAME_NULL, };
 		if (sin.sin_addr.s_addr && !sendonly) {
 			ast_moh_stop(bridgepeer);
 		
 			/* Activate a re-invite */
-			ast_queue_frame(p->owner, &af);
+			ast_queue_frame(p->owner, &ast_null_frame);
 		} else {
 			/* No address for RTP, we're on hold */
 			
@@ -3738,7 +3776,7 @@
 			if (sendonly)
 				ast_rtp_stop(p->rtp);
 			/* Activate a re-invite */
-			ast_queue_frame(p->owner, &af);
+			ast_queue_frame(p->owner, &ast_null_frame);
 		}
 	}
 
@@ -4046,7 +4084,7 @@
 }
 
 /*! \brief Initialize SIP response, based on SIP request */
-static int init_resp(struct sip_request *req, char *resp, struct sip_request *orig)
+static int init_resp(struct sip_request *req, const char *resp, struct sip_request *orig)
 {
 	/* Initialize a response */
 	if (req->headers || req->len) {
@@ -4079,7 +4117,7 @@
 
 
 /*! \brief Prepare SIP response packet */
-static int respprep(struct sip_request *resp, struct sip_pvt *p, char *msg, struct sip_request *req)
+static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, struct sip_request *req)
 {
 	char newto[256], *ot;
 
@@ -4310,7 +4348,7 @@
 }
 
 /*! \brief Respond with authorization request */
-static int transmit_response_with_auth(struct sip_pvt *p, char *msg, struct sip_request *req, const char *randdata, int reliable, char *header, int stale)
+static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, struct sip_request *req, const char *randdata, int reliable, const char *header, int stale)
 {
 	struct sip_request resp;
 	char tmp[256];
@@ -5732,7 +5770,7 @@
 	register_peer_exten(peer, 0);
 	peer->expire = -1;
 	ast_device_state_changed("SIP/%s", peer->name);
-	if (ast_test_flag(peer, SIP_SELFDESTRUCT) || ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTAUTOCLEAR)) {
+	if (ast_test_flag((&peer->flags_page2), SIP_PAGE2_SELFDESTRUCT) || ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTAUTOCLEAR)) {
 		peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer);
 		ASTOBJ_UNREF(peer, sip_destroy_peer);
 	}
@@ -6185,19 +6223,19 @@
 
 /*! \brief  Check user authorization from peer definition 
 	Some actions, like REGISTER and INVITEs from peers require
-	authentication (if peer have secret set) */
+	authentication (if peer have secret set) 
+	\return -1 on Error, 0 on success, 1 on challenge sent
+	
+*/
 static int check_auth(struct sip_pvt *p, struct sip_request *req, const char *username,
 		      const char *secret, const char *md5secret, int sipmethod,
 		      char *uri, int reliable, int ignore)
 {
-	int res = -1;
-	char *response = "407 Proxy Authentication Required";
-	char *reqheader = "Proxy-Authorization";
-	char *respheader = "Proxy-Authenticate";
-	char *authtoken;
-#ifdef OSP_SUPPORT
-	char *osptoken;
-#endif
+	const char *response = "407 Proxy Authentication Required";
+	const char *reqheader = "Proxy-Authorization";
+	const char *respheader = "Proxy-Authenticate";
+	const char *authtoken;
+
 	/* Always OK if no secret */
 	if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)
 #ifdef OSP_SUPPORT
@@ -6216,36 +6254,30 @@
 	}
 #ifdef OSP_SUPPORT
 	else {
-		ast_log (LOG_DEBUG, "Checking OSP Authentication!\n");
+		char *osptoken;
+		if (option_debug)
+			ast_log (LOG_DEBUG, "Checking OSP Authentication!\n");
 		osptoken = get_header (req, "P-OSP-Auth-Token");
 		switch (ast_test_flag (p, SIP_OSPAUTH)) {
 			case SIP_OSPAUTH_NO:
 				break;
 			case SIP_OSPAUTH_GATEWAY:
-				if (ast_strlen_zero (osptoken)) {
-					if (ast_strlen_zero (secret) && ast_strlen_zero (md5secret)) {
+				if (ast_strlen_zero(osptoken)) {
+					if (ast_strlen_zero(secret) && ast_strlen_zero (md5secret))
 						return 0;
-					}
-				}
-				else {
-					return check_osptoken (p, osptoken);
+				} else {
+					return check_osptoken(p, osptoken);
 				}
 				break;
 			case SIP_OSPAUTH_PROXY:
-				if (ast_strlen_zero (osptoken)) {
+				if (ast_strlen_zero(osptoken))
 					return 0;
-				} 
-				else {
-					return check_osptoken (p, osptoken);
-				}
+				return check_osptoken(p, osptoken);
 				break;
 			case SIP_OSPAUTH_EXCLUSIVE:
-				if (ast_strlen_zero (osptoken)) {
+				if (ast_strlen_zero(osptoken))
 					return -1;
-				}
-				else {
-					return check_osptoken (p, osptoken);
-				}
+				return check_osptoken(p, osptoken);
 				break;
 			default:
 				return -1;
@@ -6256,134 +6288,108 @@
 	if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
 		/* This is a retransmitted invite/register/etc, don't reconstruct authentication
 		   information */
-		if (!ast_strlen_zero(p->randdata)) {
-			if (!reliable) {
-				/* Resend message if this was NOT a reliable delivery.   Otherwise the
-				   retransmission should get it */
-				transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
-				/* Schedule auto destroy in 15 seconds */
-				sip_scheddestroy(p, 15000);
-			}
-			res = 1;
-		}
+		if (!reliable) {
+			/* Resend message if this was NOT a reliable delivery.   Otherwise the
+			   retransmission should get it */
+			transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
+			/* Schedule auto destroy in 32 seconds (according to RFC 3261) */
+			sip_scheddestroy(p, 32000);
+		}
+		return 1;	/* Auth sent */
 	} else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
-		ast_string_field_build(p, randdata, "%08x", thread_safe_rand());
+		/* We have no auth, so issue challenge and request authentication */
+		ast_string_field_build(p, randdata, "%08x", thread_safe_rand());	/* Create nonce for challenge */
 		transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
-		/* Schedule auto destroy in 15 seconds */
-		sip_scheddestroy(p, 15000);
-		res = 1;
-	} else {
+		/* Schedule auto destroy in 32 seconds */
+		sip_scheddestroy(p, 32000);
+		return 1;	/* Auth sent */
+	} else {	/* We have auth, so check it */
 		/* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
-		   an example in the spec of just what it is you're doing a hash on. */
-		char a1[256];
-		char a2[256];
+	   	an example in the spec of just what it is you're doing a hash on. */
 		char a1_hash[256];
-		char a2_hash[256];
-		char resp[256];
 		char resp_hash[256]="";
 		char tmp[256];
 		char *c;
-		char *z;
-		char *ua_hash ="";
-		char *resp_uri ="";
-		char *nonce = "";
-		char *digestusername = "";
 		int  wrongnonce = FALSE;
-		const char *usednonce = p->randdata;
-
-		/* Find their response among the mess that we'r sent for comparison */
+		int  good_response;
+		const char *usednonce = p->randdata; /* XXX check */
+
+		/* table of recognised keywords, and their value in the digest */
+		enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
+		struct x {
+			const char *key;
+			const char *s;
+		} *i, keys[] = {
+			[K_RESP] = { "response=", "" },
+			[K_URI] = { "uri=", "" },
+			[K_USER] = { "username=", "" },
+			[K_NONCE] = { "nonce=", "" },
+			[K_LAST] = { NULL, NULL}
+		};
+
+		/* Make a copy of the response and parse it */
 		ast_copy_string(tmp, authtoken, sizeof(tmp));
 		c = tmp;
 
-		while(c) {
-			c = ast_skip_blanks(c);
-			if (!*c)
+		while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
+			for (i = keys; i->key != NULL; i++) {
+				const char *separator = ",";	/* default */
+
+				if (strncasecmp(c, i->key, strlen(i->key)) != 0)
+					continue;
+				/* Found. Skip keyword, take text in quotes or up to the separator. */
+				c += strlen(i->key);
+				if (*c == '"') { /* in quotes. Skip first and look for last */
+					c++;
+					separator = "\"";
+				}
+				i->s = c;
+				strsep(&c, separator);
 				break;
-			if (!strncasecmp(c, "response=", strlen("response="))) {
-				c+= strlen("response=");
-				if ((*c == '\"')) {
-					ua_hash=++c;
-					if ((c = strchr(c,'\"')))
-						*c = '\0';
-
-				} else {
-					ua_hash=c;
-					if ((c = strchr(c,',')))
-						*c = '\0';
-				}
-
-			} else if (!strncasecmp(c, "uri=", strlen("uri="))) {
-				c+= strlen("uri=");
-				if ((*c == '\"')) {
-					resp_uri=++c;
-					if ((c = strchr(c,'\"')))
-						*c = '\0';
-				} else {
-					resp_uri=c;
-					if ((c = strchr(c,',')))
-						*c = '\0';
-				}
-
-			} else if (!strncasecmp(c, "username=", strlen("username="))) {
-				c+= strlen("username=");
-				if ((*c == '\"')) {
-					digestusername=++c;
-					if((c = strchr(c,'\"')))
-						*c = '\0';
-				} else {
-					digestusername=c;
-					if((c = strchr(c,',')))
-						*c = '\0';
-				}
-			} else if (!strncasecmp(c, "nonce=", strlen("nonce="))) {
-				c+= strlen("nonce=");
-				if ((*c == '\"')) {
-					nonce=++c;
-					if ((c = strchr(c,'\"')))
-						*c = '\0';
-				} else {
-					nonce=c;
-					if ((c = strchr(c,',')))
-						*c = '\0';
-				}
-
-			} else
-				if ((z = strchr(c,' ')) || (z = strchr(c,','))) c=z;
-			if (c)
-				c++;
+			}
+			if (i->key == NULL) /* not found, jump after space or comma */
+				strsep(&c, " ,");
 		}
 		/* Verify that digest username matches  the username we auth as */
-		if (strcmp(username, digestusername)) {
+		if (strcmp(username, keys[K_USER].s)) {
+			ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
+				username, keys[K_USER].s);
 			/* Oops, we're trying something here */
 			return -2;
 		}
 
 		/* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
-		if (strcasecmp(p->randdata, nonce)) {
+		if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */
 			wrongnonce = TRUE;
-			usednonce = nonce;
-		}
-
-		snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret);
-
-		if (!ast_strlen_zero(resp_uri))
-			snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, resp_uri);
-		else
-			snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, uri);
+			usednonce = keys[K_NONCE].s;
+		}
 
 		if (!ast_strlen_zero(md5secret))
-			snprintf(a1_hash, sizeof(a1_hash), "%s", md5secret);
-		else
+			ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
+		else {
+			char a1[256];
+			snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret);
 			ast_md5_hash(a1_hash, a1);
-
-		ast_md5_hash(a2_hash, a2);
-
-		snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
-		ast_md5_hash(resp_hash, resp);
-
+		}
+
+		/* compute the expected response to compare with what we received */
+		{
+			char a2[256];
+			char a2_hash[256];
+			char resp[256];
+
+			snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
+					!ast_strlen_zero(keys[K_URI].s) ? keys[K_URI].s : uri);
+			ast_md5_hash(a2_hash, a2);
+			snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
+			ast_md5_hash(resp_hash, resp);
+		}
+
+		good_response = keys[K_RESP].s &&
+				!strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
 		if (wrongnonce) {
 			ast_string_field_build(p, randdata, "%08x", thread_safe_rand());
-			if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) {
+			if (good_response) {
 				if (sipdebug)
 					ast_log(LOG_NOTICE, "stale nonce received from '%s'\n", get_header(req, "To"));
 				/* We got working auth token, based on stale nonce . */
@@ -6395,18 +6401,20 @@
 				transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
 			}
 
-			/* Schedule auto destroy in 15 seconds */
-			sip_scheddestroy(p, 15000);
-			return 1;
+			/* Schedule auto destroy in 32 seconds */

[... 1278 lines stripped ...]


More information about the asterisk-commits mailing list