[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