[asterisk-commits] oej: branch oej/codename-pineapple r53128 - in
/team/oej/codename-pineapple: ...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Fri Feb 2 13:38:19 MST 2007
Author: oej
Date: Fri Feb 2 14:38:18 2007
New Revision: 53128
URL: http://svn.digium.com/view/asterisk?view=rev&rev=53128
Log:
Major update - the "Rod" version :-)
Added:
team/oej/codename-pineapple/channels/sip3/sip3_objects.c (with props)
team/oej/codename-pineapple/channels/sip3/sip3_transmit.c (with props)
Modified:
team/oej/codename-pineapple/Makefile
team/oej/codename-pineapple/channels/Makefile
team/oej/codename-pineapple/channels/chan_iax2.c
team/oej/codename-pineapple/channels/chan_sip.c
team/oej/codename-pineapple/channels/chan_sip3.c
team/oej/codename-pineapple/channels/sip3/Makefile
team/oej/codename-pineapple/channels/sip3/sip3.h
team/oej/codename-pineapple/channels/sip3/sip3_auth.c
team/oej/codename-pineapple/channels/sip3/sip3_callerid.c
team/oej/codename-pineapple/channels/sip3/sip3_cliami.c
team/oej/codename-pineapple/channels/sip3/sip3_compose.c
team/oej/codename-pineapple/channels/sip3/sip3_config.c
team/oej/codename-pineapple/channels/sip3/sip3_dialog.c
team/oej/codename-pineapple/channels/sip3/sip3_domain.c
team/oej/codename-pineapple/channels/sip3/sip3_monitor.c
team/oej/codename-pineapple/channels/sip3/sip3_network.c
team/oej/codename-pineapple/channels/sip3/sip3_parse.c
team/oej/codename-pineapple/channels/sip3/sip3_pokedevice.c
team/oej/codename-pineapple/channels/sip3/sip3_refer.c
team/oej/codename-pineapple/channels/sip3/sip3_sdprtp.c
team/oej/codename-pineapple/channels/sip3/sip3_services.c
team/oej/codename-pineapple/channels/sip3/sip3_subscribe.c
team/oej/codename-pineapple/channels/sip3/sip3_utils.c
team/oej/codename-pineapple/channels/sip3/sip3funcs.h
team/oej/codename-pineapple/configs/sip3.conf.sample
team/oej/codename-pineapple/funcs/func_strings.c
team/oej/codename-pineapple/main/asterisk.c
team/oej/codename-pineapple/main/cdr.c
team/oej/codename-pineapple/main/devicestate.c
team/oej/codename-pineapple/main/http.c
team/oej/codename-pineapple/main/manager.c
team/oej/codename-pineapple/main/pbx.c
team/oej/codename-pineapple/main/rtp.c
Modified: team/oej/codename-pineapple/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/Makefile?view=diff&rev=53128&r1=53127&r2=53128
==============================================================================
--- team/oej/codename-pineapple/Makefile (original)
+++ team/oej/codename-pineapple/Makefile Fri Feb 2 14:38:18 2007
@@ -540,6 +540,7 @@
echo "" ; \
echo ";[options]" ; \
echo ";internal_timing = yes" ; \
+ echo ";systemname = my_system_name ; prefix uniqueid with a system name for global uniqueness issues" ; \
echo "; Changing the following lines may compromise your security." ; \
echo ";[files]" ; \
echo ";astctlpermissions = 0660" ; \
Modified: team/oej/codename-pineapple/channels/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/Makefile?view=diff&rev=53128&r1=53127&r2=53128
==============================================================================
--- team/oej/codename-pineapple/channels/Makefile (original)
+++ team/oej/codename-pineapple/channels/Makefile Fri Feb 2 14:38:18 2007
@@ -16,7 +16,8 @@
SIP3_MODULES=chan_sip3.o sip3/sip3_network.o sip3/sip3_subscribe.o sip3/sip3_refer.o sip3/sip3_domain.o \
sip3/sip3_callerid.o sip3/sip3_auth.o sip3/sip3_sdprtp.o sip3/sip3_config.o \
sip3/sip3_cliami.o sip3/sip3_dialog.o sip3/sip3_services.o sip3/sip3_compose.o \
- sip3/sip3_parse.o sip3/sip3_utils.o sip3/sip3_pokedevice.o sip3/sip3_monitor.o
+ sip3/sip3_parse.o sip3/sip3_utils.o sip3/sip3_pokedevice.o sip3/sip3_monitor.o \
+ sip3/sip3_objects.o sip3/sip3_transmit.o
ifeq ($(OSARCH),OpenBSD)
PTLIB=-lpt_OpenBSD_x86_r
@@ -59,7 +60,7 @@
LOADABLE_MODS:=
endif
-all: _all sip3
+all: _all
include $(ASTTOPDIR)/Makefile.moddir_rules
Modified: team/oej/codename-pineapple/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_iax2.c?view=diff&rev=53128&r1=53127&r2=53128
==============================================================================
--- team/oej/codename-pineapple/channels/chan_iax2.c (original)
+++ team/oej/codename-pineapple/channels/chan_iax2.c Fri Feb 2 14:38:18 2007
@@ -6163,6 +6163,8 @@
if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
}
+
+ pthread_attr_destroy(&attr);
}
struct iax_dual {
@@ -6237,8 +6239,11 @@
d->chan1 = chan1m;
d->chan2 = chan2m;
- if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d))
+ if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
+ pthread_attr_destroy(&attr);
return 0;
+ }
+ pthread_attr_destroy(&attr);
free(d);
}
return -1;
Modified: team/oej/codename-pineapple/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_sip.c?view=diff&rev=53128&r1=53127&r2=53128
==============================================================================
--- team/oej/codename-pineapple/channels/chan_sip.c (original)
+++ team/oej/codename-pineapple/channels/chan_sip.c Fri Feb 2 14:38:18 2007
@@ -526,6 +526,7 @@
static struct ast_codec_pref default_prefs; /*!< Default codec prefs */
/* Global settings only apply to the channel */
+static int global_directrtpsetup; /*!< Enable support for Direct RTP setup (no re-invites) */
static int global_limitonpeers; /*!< Match call limit on peers only */
static int global_rtautoclear;
static int global_notifyringing; /*!< Send notifications on ringing */
@@ -562,7 +563,6 @@
/*! \brief Codecs that we support by default: */
static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263;
-static int noncodeccapability = AST_RTP_DTMF;
/* Object counters */
static int suserobjs = 0; /*!< Static users */
@@ -944,6 +944,7 @@
int peercapability; /*!< Supported peer capability */
int prefcodec; /*!< Preferred codec (outbound only) */
int noncodeccapability; /*!< DTMF RFC2833 telephony-event */
+ int jointnoncodeccapability; /*!< Joint Non codec capability */
int redircodecs; /*!< Redirect codecs */
int maxcallbitrate; /*!< Maximum Call Bitrate for Video Calls */
struct t38properties t38; /*!< T38 settings */
@@ -1095,6 +1096,7 @@
int inRinging; /*!< Number of calls ringing */
int onHold; /*!< Peer has someone on hold */
int call_limit; /*!< Limit of concurrent calls */
+ int busy_limit; /*!< Limit where we signal busy */
enum transfermodes allowtransfer; /*! SIP Refer restriction scheme */
char vmexten[AST_MAX_EXTENSION]; /*!< Dialplan extension for MWI notify message*/
char mailbox[AST_MAX_EXTENSION]; /*!< Mailbox setting for MWI checks */
@@ -1331,7 +1333,7 @@
static int sip_do_reload(enum channelreloadreason reason);
static int reload_config(enum channelreloadreason reason);
static int expire_register(void *data);
-static void *do_sip_monitor(void *data);
+static void *do_monitor(void *data);
static int restart_monitor(void);
static int sip_send_mwi_to_peer(struct sip_peer *peer);
static void sip_destroy(struct sip_pvt *p);
@@ -2960,7 +2962,8 @@
p->callingpres = ast->cid.cid_pres;
p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec);
-
+ p->jointnoncodeccapability = p->noncodeccapability;
+
/* If there are no audio formats left to offer, punt */
if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username);
@@ -3013,6 +3016,12 @@
if (sip_debug_test_pvt(p) || option_debug > 2)
ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
+
+ if (ast_test_flag(&p->flags[0], SIP_INC_COUNT)) {
+ update_call_counter(p, DEC_CALL_LIMIT);
+ if (option_debug > 1)
+ ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid);
+ }
/* Remove link from peer to subscription of MWI */
if (p->relatedpeer && p->relatedpeer->mwipvt)
@@ -3155,9 +3164,10 @@
/* incoming and outgoing affects the inUse counter */
case DEC_CALL_LIMIT:
/* Decrement inuse count if applicable */
- if (inuse && ast_test_flag(&fup->flags[0], SIP_INC_COUNT))
+ if (inuse && ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
ast_atomic_fetchadd_int(inuse, -1);
- else
+ ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
+ } else
*inuse = 0;
/* Decrement ringing count if applicable */
if (inringing && ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
@@ -3642,7 +3652,7 @@
we simply forget the frames if we get modem frames before the bridge is up.
Fax will re-transmit.
*/
- if (p->udptl && ast->_state != AST_STATE_UP)
+ if (p->udptl && ast->_state == AST_STATE_UP)
res = ast_udptl_write(p->udptl, frame);
sip_pvt_unlock(p);
}
@@ -5207,7 +5217,7 @@
newjointcapability = p->capability & (peercapability | vpeercapability);
newpeercapability = (peercapability | vpeercapability);
- newnoncodeccapability = noncodeccapability & peernoncodeccapability;
+ newnoncodeccapability = p->noncodeccapability & peernoncodeccapability;
if (debug) {
@@ -5221,7 +5231,7 @@
ast_getformatname_multiple(s4, BUFSIZ, newjointcapability));
ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n",
- ast_rtp_lookup_mime_multiple(s1, BUFSIZ, noncodeccapability, 0, 0),
+ ast_rtp_lookup_mime_multiple(s1, BUFSIZ, p->noncodeccapability, 0, 0),
ast_rtp_lookup_mime_multiple(s2, BUFSIZ, peernoncodeccapability, 0, 0),
ast_rtp_lookup_mime_multiple(s3, BUFSIZ, newnoncodeccapability, 0, 0));
}
@@ -5240,9 +5250,9 @@
/* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since
they are acceptable */
- p->jointcapability = newjointcapability; /* Our joint codec profile for this call */
- p->peercapability = newpeercapability; /* The other sides capability in latest offer */
- p->noncodeccapability = newnoncodeccapability; /* DTMF capabilities */
+ p->jointcapability = newjointcapability; /* Our joint codec profile for this call */
+ p->peercapability = newpeercapability; /* The other sides capability in latest offer */
+ p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */
ast_rtp_pt_copy(p->rtp, newaudiortp);
if (p->vrtp)
@@ -6394,7 +6404,7 @@
/* Now add DTMF RFC2833 telephony-event as a codec */
for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
- if (!(p->noncodeccapability & x))
+ if (!(p->jointnoncodeccapability & x))
continue;
add_noncodec_to_sdp(p, x, 8000,
@@ -6965,6 +6975,10 @@
pidfnote = "Unavailable";
break;
case AST_EXTENSION_ONHOLD:
+ statestring = "confirmed";
+ local_state = NOTIFY_INUSE;
+ pidfstate = "busy";
+ pidfnote = "On hold";
break;
case AST_EXTENSION_NOT_INUSE:
default:
@@ -7060,6 +7074,11 @@
else
ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
+ if (state == AST_EXTENSION_ONHOLD) {
+ ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n"
+ "<param pname=\"+sip.rendering\" pvalue=\"no\">\n"
+ "</target>\n</local>\n", mto);
+ }
ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
break;
case NONE:
@@ -10198,6 +10217,8 @@
ast_cli(fd, " VM Extension : %s\n", peer->vmexten);
ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
ast_cli(fd, " Call limit : %d\n", peer->call_limit);
+ if (peer->busy_limit)
+ ast_cli(fd, " Busy limit : %d\n", peer->busy_limit);
ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No"));
ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate);
@@ -10285,7 +10306,8 @@
astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox);
astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
- astman_append(s, "Call limit: %d\r\n", peer->call_limit);
+ astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
+ astman_append(s, "Busy-limit: %d\r\n", peer->busy_limit);
astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate);
astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N"));
astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
@@ -10457,6 +10479,7 @@
ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No");
ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No");
ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No");
+ ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No");
ast_cli(fd, " User Agent: %s\n", global_useragent);
ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime);
ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)"));
@@ -12841,8 +12864,10 @@
/* Could not start thread */
free(d); /* We don't need it anymore. If thread is created, d will be free'd
by sip_park_thread() */
+ pthread_attr_destroy(&attr);
return 0;
}
+ pthread_attr_destroy(&attr);
}
return -1;
}
@@ -15108,7 +15133,7 @@
\note This thread monitors all the SIP sessions and peers that needs notification of mwi
(and thus do not have a separate thread) indefinitely
*/
-static void *do_sip_monitor(void *data)
+static void *do_monitor(void *data)
{
int res;
struct sip_pvt *dialog;
@@ -15233,7 +15258,7 @@
pthread_kill(monitor_thread, SIGURG);
} else {
/* Start a new monitor */
- if (ast_pthread_create_background(&monitor_thread, NULL, do_sip_monitor, NULL) < 0) {
+ if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
ast_mutex_unlock(&monlock);
ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
return -1;
@@ -15343,9 +15368,13 @@
- not registered AST_DEVICE_UNAVAILABLE
- registered AST_DEVICE_NOT_INUSE
- fixed IP (!dynamic) AST_DEVICE_NOT_INUSE
+
+ Peers that does not have a known call and can't be reached by OPTIONS
+ - unreachable AST_DEVICE_UNAVAILABLE
If we return AST_DEVICE_UNKNOWN, the device state engine will try to find
out a state by walking the channel list.
+
*/
static int sip_devicestate(void *data)
{
@@ -15369,27 +15398,38 @@
if ((p = find_peer(host, NULL, 1))) {
if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
/* we have an address for the peer */
- /* if qualify is turned on, check the status */
- if (p->maxms && (p->lastms > p->maxms)) {
+
+ /* Check status in this order
+ - Hold
+ - Ringing
+ - Busy (enforced only by call limit)
+ - Inuse (we have a call)
+ - Unreachable (qualify)
+ If we don't find any of these state, report AST_DEVICE_NOT_INUSE
+ for registered devices */
+
+ if (p->onHold)
+ /* First check for hold or ring states */
+ res = AST_DEVICE_ONHOLD;
+ else if (p->inRinging) {
+ if (p->inRinging == p->inUse)
+ res = AST_DEVICE_RINGING;
+ else
+ res = AST_DEVICE_RINGINUSE;
+ } else if (p->call_limit && (p->inUse == p->call_limit))
+ /* check call limit */
+ res = AST_DEVICE_BUSY;
+ else if (p->call_limit && p->busy_limit && p->inUse >= p->busy_limit)
+ /* We're forcing busy before we've reached the call limit */
+ res = AST_DEVICE_BUSY;
+ else if (p->call_limit && p->inUse)
+ /* Not busy, but we do have a call */
+ res = AST_DEVICE_INUSE;
+ else if (p->maxms && (p->lastms > p->maxms))
+ /* We don't have a call. Are we reachable at all? Requires qualify= */
res = AST_DEVICE_UNAVAILABLE;
- } else {
- /* qualify is not on, or the peer is responding properly */
- /* check call limit */
- if (p->call_limit && (p->inUse == p->call_limit))
- res = AST_DEVICE_BUSY;
- else if (p->call_limit && p->inUse)
- res = AST_DEVICE_INUSE;
- else
- res = AST_DEVICE_NOT_INUSE;
- if (p->onHold)
- res = AST_DEVICE_ONHOLD;
- else if (p->inRinging) {
- if (p->inRinging == p->inUse)
- res = AST_DEVICE_RINGING;
- else
- res = AST_DEVICE_RINGINUSE;
- }
- }
+ else /* Default reply if we're registered and have no other data */
+ res = AST_DEVICE_NOT_INUSE;
} else {
/* there is no address, it's unavailable */
res = AST_DEVICE_UNAVAILABLE;
@@ -16299,6 +16339,7 @@
global_notifyringing = DEFAULT_NOTIFYRINGING;
global_limitonpeers = FALSE; /*!< Match call limit on peers only */
global_notifyhold = FALSE; /*!< Keep track of hold status for a peer */
+ global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */
global_alwaysauthreject = 0;
global_allowsubscribe = FALSE;
snprintf(global_useragent, sizeof(global_useragent), "%s %s", DEFAULT_USERAGENT, ASTERISK_VERSION);
@@ -16425,6 +16466,8 @@
ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
} else if (!strcasecmp(v->name, "limitonpeers")) {
global_limitonpeers = ast_true(v->value);
+ } else if (!strcasecmp(v->name, "directrtpsetup")) {
+ global_directrtpsetup = ast_true(v->value);
} else if (!strcasecmp(v->name, "notifyringing")) {
global_notifyringing = ast_true(v->value);
} else if (!strcasecmp(v->name, "notifyhold")) {
@@ -16975,6 +17018,11 @@
p = chan->tech_pvt;
if (!p)
return -1;
+
+ /* Disable early RTP bridge */
+ if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */
+ return 0;
+
sip_pvt_lock(p);
if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) {
/* If we're destroyed, don't bother */
Modified: team/oej/codename-pineapple/channels/chan_sip3.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_sip3.c?view=diff&rev=53128&r1=53127&r2=53128
==============================================================================
--- team/oej/codename-pineapple/channels/chan_sip3.c (original)
+++ team/oej/codename-pineapple/channels/chan_sip3.c Fri Feb 2 14:38:18 2007
@@ -9,7 +9,7 @@
/*
* Asterisk -- An open source telephony toolkit.
*
- * Copyright (C) 1999 - 2006, Digium, Inc.
+ * Copyright (C) 1999 - 2007, Digium, Inc.
*
* Mark Spencer <markster at digium.com>
* Chan_sip3 changes by Olle E. Johansson <oej at edvina.net>
@@ -50,7 +50,8 @@
*
* \ingroup channel_drivers
*/
-/*! \page Chan_sip3_overview Chan_SIP3:: Overview
+
+/*! \page chan_sip3_overview Chan_SIP3:: Overview
*
* \par Overview of the handling of SIP sessions
* The SIP channel handles several types of SIP sessions, or dialogs,
@@ -113,14 +114,20 @@
/*! \page chan_sip3_00index Chan_sip3: Index over docs
\title Chan_sip3 :: Index
+ - \ref chan_sip3_overview
- \subpage chan_sip3_start
+ - \subpage chan_sip3_security
- \subpage chan_sip3_objects
+ - \subpage chan_sip3_registrydb
- \subpage chan_sip3_files
- \subpage chan_sip3_auth
- \subpage chan_sip3_dialogs
- \subpage chan_sip3_transactions
- - \ref chan_sip3_overview
+ - \subpage sip3_timer_doc
- \subpage sip3_dialog_match
+ - \subpage chan_sip3_dialstring
+ - \subpage chan_sip3_natsupport
+
\par todo Things to do, ideas
- \subpage chan_sip3_todo
- \subpage chan_sip3_subs
@@ -137,11 +144,33 @@
to break the backwards compatibility. That's why the old channel
will still be around for a while.
+ Chan_sip3 is the road towards security (see \ref chan_sip3_security).
+ By adding a transaction layer and support for TCP connections, we can
+ add TLS for the TCP connections and negotiate keys for secure media
+ with SRTP.
+
** This work is sponsored by voop.com - the Internet Dialtone.
I am open for more sponsors - contact me on oej at edvina.net
\page chan_sip3_todo Chan_sip3: Things to do
\b Done
+ - Trying to reduce memory allocations for packets.
+ - sipsock_read allocates a packet that stays in memory
+ until the transaction is finished. If it's an initial
+ request, it's flagged to stay in memory and kept until
+ destruction of the dialog (or replacement of initreq).
+ - The issue here is parsing, since parsing destroys the
+ in-memory copy of the outbound message thus stopping
+ proper re-transmits. Added flag for parsing of packet,
+ trying to delay parsing until we send a response.
+ - Added new CLI command "sip list configs" to list all configuration options
+ Mostly for debugging
+
+ - Added new configuration engine
+ - Add T1 timer configuration settings
+ - Added configurable T2 timer, see \ref sip3_timer_doc
+ - Added time to astdb registry storage, so that expired registrations
+ won't be activated at restart
- removed pedantic mode
- added config option for qualify frequency timers
- merged peermatch and sipregister branches
@@ -156,11 +185,36 @@
- T38 does no longer depend on canreinvite settings
- removed userconf support (in favour of astum)
+ \b Larger changes required outside of chan_sip
+ - dnsmgr needs to follow DNS ttl
+ - dnsmgr needs to handle SRV, NAPTR
+
\b Halfdone
- Added separate TOS setting for presence. Need to run setsockopt
in a locked socket for that to work on the SIP interface.
- \b Todo
+ \par Todo - architecture
+ - check if the "defaultport" and "port" settings are working - port for remote peer?
+ - dnsmgr needs to be integrated and updated
+ - netsock?
+ - thread and separate port for outbound registrations
+ - receive queue between sipsock_read and handle_request
+ - inbound call authentication
+
+ \par Todo - ideas
+ - Implement support for a:rtcp sdp (needs changes in the rtp interface)
+ - Implement "busylimit" for signalling busy, but not enforcing a call limit
+ - Use "accept-language" to set language tags in error messages etc
+ - Implement "holdaction = music | sendhold"
+ - Handle 423 Interval too brief on registrations
+ - Accept-language to language tag.
+ - Fix T4 implementation
+ - Configuration setting implemented in global
+ - Check if usereqphone is a global flag
+ - Fix compact headers per peer
+ - Always enable "alwaysauthreject" and remove that option
+ - Check "insecure" option - do we still need it?
+ - Only check for pickup code if callgroup/pickupgroups are specified in config
- check resp 491 to INVITE processing
- Make show devices and the completion support domains too
- Fix realtime caching and optional loading
@@ -168,7 +222,6 @@
- authuser as a separate config option, please, please
- Split up source code file
- Add astum
- - Add T1 timer configuration settings
- Add auto-nat for RFC 1918 networks
- Add type=device for peers
- Add type=service for register= replacement
@@ -188,6 +241,7 @@
- Make debugaddr a ha list instead of one address and move it out of sipnet
- Save the last sent request/response for re-transmits
- RTP keepalives (STUN) for video
+ - Clean up 302 redirect - remove "promisredir" setting
\b Maybe
- add support for Path header
@@ -198,6 +252,20 @@
- ... And much more
*/
+/*!
+ \page chan_sip3_security Chan_sip3: The road to SIP security
+
+ Codename pineapple is the road towards SIP security.
+
+ - SIP/TLS is the way to secure signalling
+ - In order to get there, we need TCP
+ - In order to get TCP, we need a transaction state engine
+ - We also need a separation of network transmission over
+ reliable and unreliable transports and the SIP
+ core
+ - When we have that, we can add SRTP
+
+ */
/*!
\page chan_sip3_objects Chan_sip3: Devices, trunks and services
- \b phones are devices that connect to Asterisk. They register with
@@ -280,7 +348,7 @@
*/
/*!
- * \page chan_sip3_transactions Implementing transactions
+ * \page chan_sip3_transactions Chan_sip3: Implementing transactions
*
* A SIP transaction is a request and one or several responses.
* The INVITE transaction is special, it's a three-way handshake
@@ -324,6 +392,7 @@
* - For SUBSCRIBE dialogs, we need to keep the initial SUBSCRIBE
* Then unacknowledged NOTIFY transactions. Keep the transaction
* until timer expires
+ * - Queue system for incoming packets?
*
* SIP_dialog
* - sip_trans
@@ -370,7 +439,6 @@
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
-#include "asterisk/lock.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
@@ -384,7 +452,6 @@
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
-#include "asterisk/acl.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
@@ -435,7 +502,6 @@
/* --- Linked lists of various objects --------*/
struct sip_dialog *dialoglist = NULL; /*!< List of concurrent SIP dialogs */
-struct sip_device_list devicelist; /*!< The device list */
struct ast_config *notify_types; /*!< The list of manual NOTIFY types we know how to send */
/*---------------------------- Forward declarations of functions in chan_sip3.c */
@@ -452,21 +518,8 @@
static int sip_transfer(struct ast_channel *ast, const char *dest);
static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
static int sip_senddigit_begin(struct ast_channel *ast, char digit);
-static int sip_senddigit_end(struct ast_channel *ast, char digit);
-
-/*--- Transmitting responses and requests */
-static int transmit_sip_request(struct sip_dialog *p, struct sip_request *req);
-static int transmit_request(struct sip_dialog *p, int sipmethod, int inc, enum xmittype reliable, int newbranch);
-static int transmit_response_reliable(struct sip_dialog *p, const char *msg, const struct sip_request *req);
-static int transmit_response_with_attachment(enum responseattach attach, struct sip_dialog *p, const char *msg,
- const struct sip_request *req, enum xmittype reliable);
-static int transmit_response_with_unsupported(struct sip_dialog *p, const char *msg, const struct sip_request *req, const char *unsupported);
-static void transmit_fake_auth_response(struct sip_dialog *p, struct sip_request *req, int reliable);
-static int transmit_info_with_digit(struct sip_dialog *p, const char digit);
-static int transmit_info_with_vidupdate(struct sip_dialog *p);
-static int transmit_message_with_text(struct sip_dialog *p, const char *text);
-static int transmit_refer(struct sip_dialog *p, const char *dest);
-static int transmit_notify_with_mwi(struct sip_dialog *p, int newmsgs, int oldmsgs, char *vmexten);
+static int sip_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);
+
static void receive_message(struct sip_dialog *p, struct sip_request *req);
/*--- Dialog management */
@@ -479,17 +532,16 @@
static int sip_sipredirect(struct sip_dialog *p, const char *dest);
/*--- Codec handling / SDP */
-static void try_suggested_sip_codec(struct sip_dialog *p);
+GNURK void try_suggested_sip_codec(struct sip_dialog *p);
/*--- Authentication stuff */
static enum check_auth_result check_user_full(struct sip_dialog *p, struct sip_request *req,
int sipmethod, char *uri, enum xmittype reliable,
- struct sockaddr_in *sin, struct sip_peer **authpeer);
+ struct sockaddr_in *sin, struct sip_device **authpeer);
static int check_user(struct sip_dialog *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin);
/*--- Misc functions */
static int sip_sipredirect(struct sip_dialog *p, const char *dest);
-static int sip_addrcmp(char *name, struct sockaddr_in *sin); /* Support for peer matching */
/*--- Device monitoring and Device/extension state handling */
static int cb_extensionstate(char *context, char* exten, int state, void *data);
@@ -497,9 +549,9 @@
/*--- Applications, functions, CLI and manager command helpers */
GNURK int sip_notify(int fd, int argc, char *argv[]);
-static int func_header_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len);
-static int function_sippeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len);
-static int function_sipchaninfo_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len);
+static int func_header_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len);
+static int function_sippeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len);
+static int function_sipchaninfo_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len);
static int sip_dtmfmode(struct ast_channel *chan, void *data);
static int sip_addheader(struct ast_channel *chan, void *data);
@@ -511,14 +563,7 @@
GNURK inline int sip_debug_test_pvt(struct sip_dialog *p);
/*--- Device object handling */
-static struct sip_peer *temp_peer(const char *name);
-static struct sip_peer *temp_peer(const char *name);
-static void register_peer_exten(struct sip_peer *peer, int onoff);
-static enum parse_register_result parse_register_contact(struct sip_dialog *pvt, struct sip_peer *p, struct sip_request *req);
-
-/* Realtime device support */
-static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey);
-static void update_peer(struct sip_peer *p, int expiry);
+static enum parse_register_result parse_register_contact(struct sip_dialog *pvt, struct sip_device *p, struct sip_request *req);
/*--- Parsing SIP requests and responses */
static int get_also_info(struct sip_dialog *p, struct sip_request *oreq);
@@ -528,7 +573,7 @@
static int get_msg_text(char *buf, int len, struct sip_request *req);
/*--- Constructing requests and responses */
-static int create_addr_from_peer(struct sip_dialog *r, struct sip_peer *peer);
+static int create_addr_from_peer(struct sip_dialog *r, struct sip_device *peer);
static int add_vidupdate(struct sip_request *req);
/*------Request handling functions */
@@ -575,130 +620,31 @@
.send_text = sip_sendtext, /*!< Get text from the PBX to send out */
};
-/*! \brief Initialize the initital request packet in the pvt structure.
- This packet is used for creating replies and future requests in
- a dialog */
-GNURK void initialize_initreq(struct sip_dialog *dialog, struct sip_request *req)
-{
- if (dialog->initreq.headers && option_debug) {
- ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", dialog->callid);
- }
- /* Use this as the basis */
- copy_request(&dialog->initreq, req);
- /* XX Instead -allocate this request in the dialog->packets linked list */
- ast_set_flag(&dialog->initreq, SIP_PKT_INITREQ);
- parse_request(&dialog->initreq);
- if (ast_test_flag(req, SIP_PKT_DEBUG))
- ast_verbose("Initreq: %d headers, %d lines\n", dialog->initreq.headers, dialog->initreq.lines);
-}
-
-/*! \brief Find via branch parameter */
-GNURK void find_via_branch(struct sip_request *req, char *viabuf, size_t vialen)
-{
- char *dupvia;
- char *viabranch;
- char *sep;
-
- if (ast_strlen_zero(req->via))
- return;
- dupvia = ast_strdupa(req->via);
- if (!(viabranch = strcasestr(dupvia, ";branch=")))
- return;
- viabranch += 8;
- if ((sep = strchr(viabranch, ';')))
- *sep = '\0';
- if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug > 3)
- ast_log(LOG_DEBUG, "* Found via branch %s\n", viabranch);
- strncpy(viabuf, viabranch, vialen);
-}
-
-
-/*! \brief Make branch tag for via header if it does not exist yet */
-static char *ourdialogbranch(struct sip_dialog *dialog, int forcenewbranch)
-{
- char branch[20];
- int seed = 0;
-
- if (forcenewbranch || ast_strlen_zero(dialog->ourbranch)) {
- if (forcenewbranch)
- seed ^= ast_random();
- else
- seed = ast_random();
- snprintf(branch, sizeof(branch), "z9hG4bk%08x", seed);
- ast_string_field_set(dialog, ourbranch, branch);
- }
-
- return((char *) dialog->ourbranch);
-
-}
-
-/*! \brief Build a Via header for a request */
-GNURK void build_via(struct sip_dialog *dialog, int forcenewbranch)
-{
- /* Work around buggy UNIDEN UIP200 firmware */
- const char *rport = ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : "";
-
- /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */
- ast_string_field_build(dialog, via, "SIP/2.0/UDP %s:%d;branch=%s%s",
- ast_inet_ntoa(dialog->ourip), sipnet_ourport(),
- ourdialogbranch(dialog, forcenewbranch), rport);
-}
-
-GNURK void append_history_full(struct sip_dialog *p, const char *fmt, ...)
- __attribute__ ((format (printf, 2, 3)));
-
-/*! \brief Append to SIP dialog history with arg list */
-GNURK void append_history_va(struct sip_dialog *p, const char *fmt, va_list ap)
-{
- char buf[80], *c = buf; /* max history length */
- struct sip_history *hist;
- int l;
-
- vsnprintf(buf, sizeof(buf), fmt, ap);
- strsep(&c, "\r\n"); /* Trim up everything after \r or \n */
- l = strlen(buf) + 1;
- if (!(hist = ast_calloc(1, sizeof(*hist) + l)))
- return;
- if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) {
- free(hist);
- return;
- }
- memcpy(hist->event, buf, l);
- AST_LIST_INSERT_TAIL(p->history, hist, list);
-}
-
-/*! \brief Append to SIP dialog history with arg list */
-GNURK void append_history_full(struct sip_dialog *dialog, const char *fmt, ...)
-{
- va_list ap;
-
- if (!dialog)
- return;
- va_start(ap, fmt);
- append_history_va(dialog, fmt, ap);
- va_end(ap);
-
- return;
-}
-
-/*! \brief Copy SIP request, pre-parse it */
-GNURK void parse_copy(struct sip_request *dst, const struct sip_request *src)
-{
- memset(dst, 0, sizeof(*dst));
- memcpy(dst->data, src->data, sizeof(dst->data));
- dst->len = src->len;
- parse_request(dst);
-}
-
-/*! \brief add a blank line if no body */
-GNURK void add_blank(struct sip_request *req)
-{
- if (!req->lines) {
- /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
- snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
- req->len += strlen(req->data + req->len);
- }
-}
+/*! \brief This version of the sip channel tech has no send_digit_begin
+ * callback. This is for use with channels using SIP INFO DTMF so that
+ * the core knows that the channel doesn't want DTMF BEGIN frames. */
+static const struct ast_channel_tech sip_tech_info = {
+ .type = "SIP",
+ .description = "Session Initiation Protocol (SIP)",
+ .capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1),
+ .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
+ .requester = sip_request_call, /*!< Where we set up a call, but don't actually activate it */
+ .devicestate = sip_devicestate, /*!< Checking the status of a known SIP device */
+ .call = sip_call, /*!< Try calling Bob, says Alice */
+ .hangup = sip_hangup, /*!< Alice does not want to talk to Bob any more */
+ .answer = sip_answer, /*!< Bob answers the call */
+ .read = sip_read, /*!< Deliver media to the PBX */
+ .write = sip_write, /*!< Get media from the PBX side */
+ .write_video = sip_write, /*!< Get video media from the PBX side */
+ .indicate = sip_indicate, /*!< Get indications from the PBX side */
+ .transfer = sip_transfer, /*!< Transfer a call, severely broken */
+ .fixup = sip_fixup,
+ .send_digit_end = sip_senddigit_end, /*!< DTMF support */
+ .bridge = ast_rtp_bridge,
+ .early_bridge = ast_rtp_early_bridge,
+ .send_text = sip_sendtext, /*!< Get text from the PBX to send out */
+};
+
/*! \brief Send SIP MESSAGE text within a call
Called from PBX core sendtext() application */
@@ -707,8 +653,6 @@
struct sip_dialog *dialog = ast->tech_pvt;
int debug = sip_debug_test_pvt(dialog);
- if (debug)
- ast_verbose("Sending text %s on %s\n", text, ast->name);
if (!dialog)
return -1;
if (ast_strlen_zero(text))
@@ -719,165 +663,6 @@
return 0;
}
-/*! \brief Update peer object in realtime storage
- If the Asterisk system name is set in asterisk.conf, we will use
- that name and store that in the "regserver" field in the sippeers
- table to facilitate multi-server setups.
-*/
-static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey)
-{
- char port[10];
- char ipaddr[INET_ADDRSTRLEN];
- char regseconds[20];
-
- char *sysname = ast_config_AST_SYSTEM_NAME;
- char *syslabel = NULL;
-
- time_t nowtime = time(NULL) + expirey;
- const char *fc = fullcontact ? "fullcontact" : NULL;
-
- snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */
- ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
- snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
-
- if (ast_strlen_zero(sysname)) /* No system name, disable this */
- sysname = NULL;
- else if (ast_test_flag(&global.flags[1], SIP_PAGE2_RTSAVE_SYSNAME))
- syslabel = "regserver";
-
- if (fc)
- ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
- "port", port, "regseconds", regseconds,
- "defaultuser", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */
- else
- ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
- "port", port, "regseconds", regseconds,
- "defaultuser", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */
-}
-
-/*! \brief Automatically add peer extension to dial plan */
-static void register_peer_exten(struct sip_peer *device, int onoff)
-{
- char multi[256];
- char *stringp, *ext, *context;
-
- /* XXX note that global.regcontext is both a global 'enable' flag and
- * the name of the global regexten context, if not specified
- * individually.
- */
- if (ast_strlen_zero(global.regcontext))
- return;
-
- ast_copy_string(multi, S_OR(device->regexten, device->name), sizeof(multi));
- stringp = multi;
- while ((ext = strsep(&stringp, "&"))) {
- if ((context = strchr(ext, '@'))) {
- *context++ = '\0'; /* split ext at context */
- if (!ast_context_find(context)) {
- ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
- continue;
- }
- } else {
- context = global.regcontext;
- }
- if (onoff)
- ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
- ast_strdup(device->name), ast_free, "SIP");
- else
- ast_context_remove_extension(context, ext, 1, NULL);
- }
-}
-
-/*! \brief Destroy device object from memory */
-GNURK void sip_destroy_device(struct sip_peer *device)
-{
- logdebug(3, "Destroying SIP device %s\n", device->name);
- //if (option_debug > 2)
- //ast_log(LOG_DEBUG, "Destroying SIP %s %s\n", device->type & SIP_USER ? "user" : "peer", device->name);
-
- /* Delete it, it needs to disappear */
- if (device->call)
- sip_destroy(device->call);
- if (device->chanvars) {
- ast_variables_destroy(device->chanvars);
- device->chanvars = NULL;
- }
-
- if (device->mwipvt) /* We have an active subscription, delete it */
- sip_destroy(device->mwipvt);
-
- if (device->expire > -1)
- ast_sched_del(sched, device->expire);
- if (device->pokeexpire > -1)
- ast_sched_del(sched, device->pokeexpire);
- ast_free_ha(device->ha);
-
- if (device->type & SIP_PEER) {
- register_peer_exten(device, FALSE);
- clear_realm_authentication(device->auth);
- device->auth = (struct sip_auth *) NULL;
- if (ast_test_flag((&device->flags[1]), SIP_PAGE2_SELFDESTRUCT))
- sipcounters.autocreated_peers--;
[... 11359 lines stripped ...]
More information about the asterisk-commits
mailing list