[asterisk-commits] oej: branch oej/codename-pineapple r48134 - in
/team/oej/codename-pineapple: ...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Thu Nov 30 06:47:29 MST 2006
Author: oej
Date: Thu Nov 30 07:47:28 2006
New Revision: 48134
URL: http://svn.digium.com/view/asterisk?view=rev&rev=48134
Log:
Update to trunk
Modified:
team/oej/codename-pineapple/ (props changed)
team/oej/codename-pineapple/Makefile
team/oej/codename-pineapple/apps/app_voicemail.c
team/oej/codename-pineapple/channels/chan_iax2.c
team/oej/codename-pineapple/channels/chan_phone.c
team/oej/codename-pineapple/channels/chan_sip.c
team/oej/codename-pineapple/channels/chan_zap.c
team/oej/codename-pineapple/codecs/codec_zap.c
team/oej/codename-pineapple/configs/http.conf.sample
team/oej/codename-pineapple/configs/sip.conf.sample
team/oej/codename-pineapple/funcs/func_cdr.c
team/oej/codename-pineapple/include/asterisk/doxyref.h
team/oej/codename-pineapple/include/asterisk/threadstorage.h
team/oej/codename-pineapple/include/asterisk/utils.h
team/oej/codename-pineapple/main/http.c
team/oej/codename-pineapple/main/manager.c
team/oej/codename-pineapple/main/rtp.c
team/oej/codename-pineapple/main/utils.c
team/oej/codename-pineapple/pbx/pbx_spool.c
team/oej/codename-pineapple/res/res_musiconhold.c
team/oej/codename-pineapple/sounds/Makefile
Propchange: team/oej/codename-pineapple/
------------------------------------------------------------------------------
Binary property 'branch-1.4-blocked' - no diff available.
Propchange: team/oej/codename-pineapple/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.
Propchange: team/oej/codename-pineapple/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Nov 30 07:47:28 2006
@@ -1,1 +1,1 @@
-/trunk:1-48005
+/trunk:1-48133
Modified: team/oej/codename-pineapple/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/Makefile?view=diff&rev=48134&r1=48133&r2=48134
==============================================================================
--- team/oej/codename-pineapple/Makefile (original)
+++ team/oej/codename-pineapple/Makefile Thu Nov 30 07:47:28 2006
@@ -37,6 +37,11 @@
export ASTVARLIBDIR
export ASTDATADIR
export ASTLOGDIR
+export ASTLIBDIR
+export ASTMANDIR
+export ASTHEADERDIR
+export ASTBINDIR
+export ASTSBINDIR
export AGI_DIR
export ASTCONFPATH
export NOISY_BUILD
Modified: team/oej/codename-pineapple/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/apps/app_voicemail.c?view=diff&rev=48134&r1=48133&r2=48134
==============================================================================
--- team/oej/codename-pineapple/apps/app_voicemail.c (original)
+++ team/oej/codename-pineapple/apps/app_voicemail.c Thu Nov 30 07:47:28 2006
@@ -4673,7 +4673,7 @@
if(option_debug > 2)
ast_log(LOG_DEBUG,"Before init_mailstream, user is %s\n",vmu->imapuser);
ret = init_mailstream(vms, box);
- if (ret != 0) {
+ if (ret != 0 || !vms->mailstream) {
ast_log (LOG_ERROR,"Could not initialize mailstream\n");
return -1;
}
@@ -6970,22 +6970,13 @@
}
}
AST_LIST_TRAVERSE(&users, vmu, list) {
- char dirname[256];
- DIR *vmdir;
- struct dirent *vment;
- int vmcount = 0;
- char count[12];
+ int newmsgs = 0, oldmsgs = 0;
+ char count[12], tmp[256] = "";
if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
- make_dir(dirname, 255, vmu->context, vmu->mailbox, "INBOX");
- if ((vmdir = opendir(dirname))) {
- /* No matter what the format of VM, there will always be a .txt file for each message. */
- while ((vment = readdir(vmdir)))
- if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7,".txt",4))
- vmcount++;
- closedir(vmdir);
- }
- snprintf(count,sizeof(count),"%d",vmcount);
+ snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
+ inboxcount(tmp, &newmsgs, &oldmsgs);
+ snprintf(count,sizeof(count),"%d",newmsgs);
ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
}
}
@@ -8481,15 +8472,16 @@
if(option_debug > 3)
ast_log(LOG_DEBUG, "Entering callback mm_login\n");
- ast_copy_string(user, mb->user,sizeof(user));
+
+ ast_copy_string(user, mb->user, MAILTMPLEN);
/* We should only do this when necessary */
if (!ast_strlen_zero(authpassword)) {
- ast_copy_string(pwd, authpassword, sizeof(pwd));
+ ast_copy_string(pwd, authpassword, MAILTMPLEN);
} else {
AST_LIST_TRAVERSE(&users, vmu, list) {
if(!strcasecmp(mb->user, vmu->imapuser)) {
- ast_copy_string(pwd, vmu->imappassword, sizeof(pwd));
+ ast_copy_string(pwd, vmu->imappassword, MAILTMPLEN);
break;
}
}
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=48134&r1=48133&r2=48134
==============================================================================
--- team/oej/codename-pineapple/channels/chan_iax2.c (original)
+++ team/oej/codename-pineapple/channels/chan_iax2.c Thu Nov 30 07:47:28 2006
@@ -1195,6 +1195,20 @@
return res;
}
+/*!
+ * \todo XXX Note that this function contains a very expensive operation that
+ * happens for *every* incoming media frame. It iterates through every
+ * possible call number, locking and unlocking each one, to try to match the
+ * incoming frame to an active call. Call numbers can be up to 2^15, 32768.
+ * So, for an call with a local call number of 20000, every incoming audio
+ * frame would require 20000 mutex lock and unlock operations. Ouch.
+ *
+ * It's a shame that IAX2 media frames carry the source call number instead of
+ * the destination call number. If they did, this lookup wouldn't be needed.
+ * However, it's too late to change that now. Instead, we need to come up with
+ * a better way of indexing active calls so that these frequent lookups are not
+ * so expensive.
+ */
static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int lockpeer, int sockfd)
{
int res = 0;
Modified: team/oej/codename-pineapple/channels/chan_phone.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_phone.c?view=diff&rev=48134&r1=48133&r2=48134
==============================================================================
--- team/oej/codename-pineapple/channels/chan_phone.c (original)
+++ team/oej/codename-pineapple/channels/chan_phone.c Thu Nov 30 07:47:28 2006
@@ -48,11 +48,6 @@
#include <linux/telephony.h>
/* Still use some IXJ specific stuff */
#include <linux/version.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
-# include <linux/compiler.h>
-#endif
-#endif
#include <linux/ixjuser.h>
#include "asterisk/lock.h"
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=48134&r1=48133&r2=48134
==============================================================================
--- team/oej/codename-pineapple/channels/chan_sip.c (original)
+++ team/oej/codename-pineapple/channels/chan_sip.c Thu Nov 30 07:47:28 2006
@@ -12331,7 +12331,8 @@
if (sipmethod == SIP_INVITE) {
/* First we ACK */
transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
- ast_log(LOG_WARNING, "INVITE with REPLACEs failed to '%s'\n", get_header(&p->initreq, "From"));
+ if (option_debug)
+ ast_log(LOG_DEBUG, "Got 481 on Invite. Assuming INVITE with REPLACEs failed to '%s'\n", get_header(&p->initreq, "From"));
if (owner)
ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
@@ -14574,7 +14575,7 @@
error = 1;
}
if (error) {
- if (!p->initreq.header) /* New call */
+ if (!p->initreq.headers) /* New call */
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */
return -1;
}
@@ -16307,7 +16308,7 @@
autocreatepeer = ast_true(v->value);
} else if (!strcasecmp(v->name, "match_auth_username")) {
global_match_auth_username = ast_true(v->value);
- } else if (!strcasecmp(v->name, "global_srvlookup")) {
+ } else if (!strcasecmp(v->name, "srvlookup")) {
global_srvlookup = ast_true(v->value);
} else if (!strcasecmp(v->name, "pedantic")) {
pedanticsipchecking = ast_true(v->value);
Modified: team/oej/codename-pineapple/channels/chan_zap.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_zap.c?view=diff&rev=48134&r1=48133&r2=48134
==============================================================================
--- team/oej/codename-pineapple/channels/chan_zap.c (original)
+++ team/oej/codename-pineapple/channels/chan_zap.c Thu Nov 30 07:47:28 2006
@@ -8380,7 +8380,7 @@
startcic = linkset->pvts[0]->cic;
for (i = 0; i < linkset->numchans; i++) {
- if (linkset->pvts[i+1] && (linkset->pvts[i+1]->cic - linkset->pvts[i]->cic) == 1) {
+ if (linkset->pvts[i+1] && ((linkset->pvts[i+1]->cic - linkset->pvts[i]->cic) == 1) && (linkset->pvts[i]->cic - startcic < 31)) {
continue;
} else {
endcic = linkset->pvts[i]->cic;
@@ -10568,23 +10568,23 @@
return RESULT_SUCCESS;
}
-static const char pri_debug_help[] =
+static char pri_debug_help[] =
"Usage: pri debug span <span>\n"
" Enables debugging on a given PRI span\n";
-static const char pri_no_debug_help[] =
+static char pri_no_debug_help[] =
"Usage: pri no debug span <span>\n"
" Disables debugging on a given PRI span\n";
-static const char pri_really_debug_help[] =
+static char pri_really_debug_help[] =
"Usage: pri intensive debug span <span>\n"
" Enables debugging down to the Q.921 level\n";
-static const char pri_show_span_help[] =
+static char pri_show_span_help[] =
"Usage: pri show span <span>\n"
" Displays PRI Information on a given PRI span\n";
-static const char pri_show_spans_help[] =
+static char pri_show_spans_help[] =
"Usage: pri show spans\n"
" Displays PRI Information\n";
@@ -11556,7 +11556,6 @@
return RESULT_SUCCESS;
}
-#if 0
static int handle_ss7_show_linkset(int fd, int argc, char *argv[])
{
int linkset;
@@ -11573,49 +11572,44 @@
return RESULT_SUCCESS;
}
if (linksets[linkset-1].ss7)
- ss7 = linksets[linkset-1];
-
- if (
+ ss7 = &linksets[linkset-1];
+
+ ast_cli(fd, "SS7 linkset %d status: %s\n", linkset, (ss7->state == LINKSET_STATE_UP) ? "Up" : "Down");
return RESULT_SUCCESS;
}
-#endif
-
-static const char ss7_debug_help[] =
+
+static char ss7_debug_help[] =
"Usage: ss7 debug linkset <linkset>\n"
" Enables debugging on a given SS7 linkset\n";
-static const char ss7_no_debug_help[] =
+static char ss7_no_debug_help[] =
"Usage: ss7 no debug linkset <span>\n"
" Disables debugging on a given SS7 linkset\n";
-static const char ss7_block_cic_help[] =
+static char ss7_block_cic_help[] =
"Usage: ss7 block cic <linkset> <CIC>\n"
" Sends a remote blocking request for the given CIC on the specified linkset\n";
-static const char ss7_unblock_cic_help[] =
+static char ss7_unblock_cic_help[] =
"Usage: ss7 unblock cic <linkset> <CIC>\n"
" Sends a remote unblocking request for the given CIC on the specified linkset\n";
-#if 0
-static const char ss7_show_linkset_help[] =
+static char ss7_show_linkset_help[] =
"Usage: ss7 show linkset <span>\n"
- " Disables debugging on a given SS7 linkset\n";
-#endif
+ " Shows the status of an SS7 linkset.\n";
static struct ast_cli_entry zap_ss7_cli[] = {
{ { "ss7", "debug", "linkset", NULL }, handle_ss7_debug,
"Enables SS7 debugging on a linkset", ss7_debug_help, NULL },
{ { "ss7", "no", "debug", "linkset", NULL }, handle_ss7_no_debug,
- "Disables SS7 debugging on a linkset", ss7_debug_help, NULL },
+ "Disables SS7 debugging on a linkset", ss7_no_debug_help, NULL },
{ { "ss7", "block", "cic", NULL }, handle_ss7_block_cic,
"Disables SS7 debugging on a linkset", ss7_block_cic_help, NULL },
{ { "ss7", "unblock", "cic", NULL }, handle_ss7_unblock_cic,
"Disables SS7 debugging on a linkset", ss7_unblock_cic_help, NULL },
-#if 0
{ { "ss7", "show", "linkset", NULL }, handle_ss7_show_linkset,
- "Disables SS7 debugging on a linkset", ss7_show_linkset_help, NULL },
-#endif
+ "Shows the status of a linkset", ss7_show_linkset_help, NULL },
};
#endif /* HAVE_SS7 */
Modified: team/oej/codename-pineapple/codecs/codec_zap.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/codecs/codec_zap.c?view=diff&rev=48134&r1=48133&r2=48134
==============================================================================
--- team/oej/codename-pineapple/codecs/codec_zap.c (original)
+++ team/oej/codename-pineapple/codecs/codec_zap.c Thu Nov 30 07:47:28 2006
@@ -232,7 +232,7 @@
return zap_translate(pvt, pvt->t->dstfmt, pvt->t->srcfmt);
}
-static struct ast_frame *g729_fakesrc_sample()
+static struct ast_frame *g729_fakesrc_sample(void)
{
/* Don't bother really trying to test hardware ones. */
static struct ast_frame f = {
@@ -244,7 +244,7 @@
return &f;
}
-static struct ast_frame *g723_fakesrc_sample()
+static struct ast_frame *g723_fakesrc_sample(void)
{
/* Don't bother really trying to test hardware ones. */
static struct ast_frame f = {
Modified: team/oej/codename-pineapple/configs/http.conf.sample
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/configs/http.conf.sample?view=diff&rev=48134&r1=48133&r2=48134
==============================================================================
--- team/oej/codename-pineapple/configs/http.conf.sample (original)
+++ team/oej/codename-pineapple/configs/http.conf.sample Thu Nov 30 07:47:28 2006
@@ -28,10 +28,13 @@
;
;prefix=asterisk
-; HTTPS support: you need to enable it, define the port to use,
+; HTTPS support. In addition to enabled=yes, you need to
+; explicitly enable ssl, define the port to use,
; and have a certificate somewhere.
; sslenable=yes ; enable ssl - default no.
; sslbindport=4433 ; port to use - default is 8089
+; sslbindaddr=0.0.0.0 ; address to bind to - default is bindaddr.
+;
; sslcert=/tmp/foo.pem ; path to the certificate
;
; To produce a certificate you can e.g. use openssl
Modified: team/oej/codename-pineapple/configs/sip.conf.sample
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/configs/sip.conf.sample?view=diff&rev=48134&r1=48133&r2=48134
==============================================================================
--- team/oej/codename-pineapple/configs/sip.conf.sample (original)
+++ team/oej/codename-pineapple/configs/sip.conf.sample Thu Nov 30 07:47:28 2006
@@ -94,9 +94,11 @@
;language=en ; Default language setting for all users/peers
; This may also be set for individual users/peers
;relaxdtmf=yes ; Relax dtmf handling
-;rtptimeout=60 ; Terminate call if 60 seconds of no RTP activity
- ; when we're not on hold
-;rtpholdtimeout=300 ; Terminate call if 300 seconds of no RTP activity
+;rtptimeout=60 ; Terminate call if 60 seconds of no RTP or RTCP activity
+ ; when we're not on hold. This is to be able to hangup
+ ; a call in the case of a phone disappearing from the net,
+ ; like a powerloss or grandma tripping over a cable.
+;rtpholdtimeout=300 ; Terminate call if 300 seconds of no RTP or RTCP activity
; when we're on hold (must be > rtptimeout)
;trustrpid = no ; If Remote-Party-ID should be trusted
;sendrpid = yes ; If Remote-Party-ID should be sent
@@ -172,6 +174,15 @@
; You can subscribe to the status of extensions with a "hint" priority
; (See extensions.conf.sample for examples)
; chan_sip support two major formats for notifications: dialog-info and SIMPLE
+;
+; You will get more detailed reports (busy etc) if you have a call limit set
+; for a device. When the call limit is filled, we will indicate busy. Note that
+; you need at least 2 in order to be able to do attended transfers.
+;
+; For queues, you will need this level of detail in status reporting, regardless
+; if you use SIP subscriptions. Queues and manager use the same internal interface
+; for reading status information.
+;
; Note: Subscriptions does not work if you have a realtime dialplan and use the
; realtime switch.
;
Modified: team/oej/codename-pineapple/funcs/func_cdr.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/funcs/func_cdr.c?view=diff&rev=48134&r1=48133&r2=48134
==============================================================================
--- team/oej/codename-pineapple/funcs/func_cdr.c (original)
+++ team/oej/codename-pineapple/funcs/func_cdr.c Thu Nov 30 07:47:28 2006
@@ -129,7 +129,28 @@
" For example, 'start', 'answer', and 'end' will be retrieved as epoch\n"
" values, when the 'u' option is passed, but formatted as YYYY-MM-DD HH:MM:SS\n"
" otherwise. Similarly, disposition and amaflags will return their raw\n"
-" integral values.\n",
+" integral values.\n"
+" Here is a list of all the available cdr field names:\n"
+" clid lastdata disposition\n"
+" src start amaflags\n"
+" dst answer accountcode\n"
+" dcontext end uniqueid\n"
+" dstchannel duration userfield\n"
+" lastapp billsec channel\n"
+" All of the above variables are read-only, except for accountcode,\n"
+" userfield, and amaflags. You may, however, supply\n"
+" a name not on the above list, and create your own\n"
+" variable, whose value can be changed with this function,\n"
+" and this variable will be stored on the cdr.\n"
+" raw values for disposition:\n"
+" 1 = NO ANSWER\n"
+" 2 = BUSY\n"
+" 3 = FAILED\n"
+" 4 = ANSWERED\n"
+" raw values for amaflags:\n"
+" 1 = OMIT\n"
+" 2 = BILLING\n"
+" 3 = DOCUMENTATION\n",
};
static int unload_module(void)
Modified: team/oej/codename-pineapple/include/asterisk/doxyref.h
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/include/asterisk/doxyref.h?view=diff&rev=48134&r1=48133&r2=48134
==============================================================================
--- team/oej/codename-pineapple/include/asterisk/doxyref.h (original)
+++ team/oej/codename-pineapple/include/asterisk/doxyref.h Thu Nov 30 07:47:28 2006
@@ -40,7 +40,6 @@
* \arg \ref AstENUM : The IETF way to redirect from phone numbers to VoIP calls
* \arg \ref AstHTTP
* \arg \ref AstSpeech
- * \arg \ref DataStores
* \arg \ref ConfigFiles
* \arg \ref SoundFiles included in the Asterisk distribution
* \arg \ref AstCREDITS : A Thank You to contributors
@@ -65,6 +64,10 @@
/*! \page AstAPI Asterisk API
* \section Asteriskapi Asterisk API
* Some generic documents on the Asterisk architecture
+ *
+ * \arg \ref AstThreadStorage
+ * \arg \ref DataStores
+ *
* \subsection model_txt Generic Model
* \verbinclude model.txt
* \subsection channel_txt Channels
Modified: team/oej/codename-pineapple/include/asterisk/threadstorage.h
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/include/asterisk/threadstorage.h?view=diff&rev=48134&r1=48133&r2=48134
==============================================================================
--- team/oej/codename-pineapple/include/asterisk/threadstorage.h (original)
+++ team/oej/codename-pineapple/include/asterisk/threadstorage.h Thu Nov 30 07:47:28 2006
@@ -19,9 +19,28 @@
/*!
* \file threadstorage.h
* \author Russell Bryant <russell at digium.com>
- *
* \brief Definitions to aid in the use of thread local storage
-*/
+ */
+
+/*!
+ * \page AstThreadStorage The Asterisk Thread Storage API
+ *
+ *
+ * The POSIX threads (pthreads) API provides the ability to define thread
+ * specific data. The functions and structures defined here are intended
+ * to centralize the code that is commonly used when using thread local
+ * storage.
+ *
+ * The motivation for using this code in Asterisk is for situations where
+ * storing data on a thread-specific basis can provide some amount of
+ * performance benefit. For example, there are some call types in Asterisk
+ * where ast_frame structures must be allocated very rapidly (easily 50, 100,
+ * 200 times a second). Instead of doing the equivalent of that many calls
+ * to malloc() and free() per second, thread local storage is used to keep a
+ * list of unused frame structures so that they can be continuously reused.
+ *
+ * - \ref threadstorage.h
+ */
#ifndef ASTERISK_THREADSTORAGE_H
#define ASTERISK_THREADSTORAGE_H
@@ -73,7 +92,7 @@
*
* Example usage:
* \code
- * AST_THREADSTORAGE(my_buf, my_init, my_cleanup);
+ * AST_THREADSTORAGE_CUSTOM(my_buf, my_init, my_cleanup);
* \endcode
*/
#define AST_THREADSTORAGE_CUSTOM(name, c_init, c_cleanup) \
@@ -186,7 +205,7 @@
* current length may be bigger if previous operations in this thread have
* caused it to increase.
*
- * \return This function will return the thread locally storaged dynamic string
+ * \return This function will return the thread locally stored dynamic string
* associated with the thread storage management variable passed as the
* first argument.
* The result will be NULL in the case of a memory allocation error.
@@ -238,6 +257,102 @@
/*!
* \brief Set a thread locally stored dynamic string from a va_list
+ *
+ * \arg buf This is the address of a pointer to an ast_dynamic_str which should
+ * have been retrieved using ast_dynamic_str_thread_get. It will need to
+ * be updated in the case that the buffer has to be reallocated to
+ * accommodate a longer string than what it currently has space for.
+ * \arg max_len This is the maximum length to allow the string buffer to grow
+ * to. If this is set to 0, then there is no maximum length.
+ * \arg ts This is a pointer to the thread storage structure declared by using
+ * the AST_THREADSTORAGE macro. If declared with
+ * AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be
+ * (&my_buf).
+ * \arg fmt This is the format string (printf style)
+ * \arg ap This is the va_list
+ *
+ * \return The return value of this function is the same as that of the printf
+ * family of functions.
+ *
+ * Example usage:
+ * \code
+ * AST_THREADSTORAGE(my_str, my_str_init);
+ * #define MY_STR_INIT_SIZE 128
+ * ...
+ * void my_func(const char *fmt, ...)
+ * {
+ * struct ast_dynamic_str *buf;
+ * va_list ap;
+ *
+ * if (!(buf = ast_dynamic_str_thread_get(&my_str, MY_STR_INIT_SIZE)))
+ * return;
+ * ...
+ * va_start(fmt, ap);
+ * ast_dynamic_str_thread_set_va(&buf, 0, &my_str, fmt, ap);
+ * va_end(ap);
+ *
+ * printf("This is the string we just built: %s\n", buf->str);
+ * ...
+ * }
+ * \endcode
+ */
+#define ast_dynamic_str_thread_set_va(buf, max_len, ts, fmt, ap) \
+ ({ \
+ int __res; \
+ while ((__res = ast_dynamic_str_thread_build_va(buf, max_len, \
+ ts, 0, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) { \
+ va_end(ap); \
+ va_start(ap, fmt); \
+ } \
+ (__res); \
+ })
+
+/*!
+ * \brief Append to a thread local dynamic string using a va_list
+ *
+ * The arguments, return values, and usage of this are the same as those for
+ * ast_dynamic_str_thread_set_va(). However, instead of setting a new value
+ * for the string, this will append to the current value.
+ */
+#define ast_dynamic_str_thread_append_va(buf, max_len, ts, fmt, ap) \
+ ({ \
+ int __res; \
+ while ((__res = ast_dynamic_str_thread_build_va(buf, max_len, \
+ ts, 1, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) { \
+ va_end(ap); \
+ va_start(ap, fmt); \
+ } \
+ (__res); \
+ })
+
+/*!
+ * \brief Core functionality of ast_dynamic_str_thread_(set|append)_va
+ *
+ * The arguments to this function are the same as those described for
+ * ast_dynamic_str_thread_set_va except for an addition argument, append.
+ * If append is non-zero, this will append to the current string instead of
+ * writing over it.
+ *
+ * In the case that this function is called and the buffer was not large enough
+ * to hold the result, the partial write will be truncated, and the result
+ * AST_DYNSTR_BUILD_RETRY will be returned to indicate that the buffer size
+ * was increased, and the function should be called a second time.
+ *
+ * A return of AST_DYNSTR_BUILD_FAILED indicates a memory allocation error.
+ *
+ * A return value greater than or equal to zero indicates the number of
+ * characters that have been written, not including the terminating '\0'.
+ * In the append case, this only includes the number of characters appended.
+ *
+ * \note This function should never need to be called directly. It should
+ * through calling one of the other functions or macros defined in this
+ * file.
+ */
+int ast_dynamic_str_thread_build_va(struct ast_dynamic_str **buf, size_t max_len,
+ struct ast_threadstorage *ts, int append, const char *fmt, va_list ap);
+
+/*!
+ * \brief Set a thread locally stored dynamic string using variable arguments
*
* \arg buf This is the address of a pointer to an ast_dynamic_str which should
* have been retrieved using ast_dynamic_str_thread_get. It will need to
@@ -250,87 +365,6 @@
* AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be
* (&my_buf).
* \arg fmt This is the format string (printf style)
- * \arg ap This is the va_list
- *
- * \return The return value of this function is the same as that of the printf
- * family of functions.
- *
- * Example usage:
- * \code
- * AST_THREADSTORAGE(my_str, my_str_init);
- * #define MY_STR_INIT_SIZE 128
- * ...
- * void my_func(const char *fmt, ...)
- * {
- * struct ast_dynamic_str *buf;
- * va_list ap;
- *
- * if (!(buf = ast_dynamic_str_thread_get(&my_str, MY_STR_INIT_SIZE)))
- * return;
- * ...
- * va_start(fmt, ap);
- * ast_dynamic_str_thread_set_va(&buf, 0, &my_str, fmt, ap);
- * va_end(ap);
- *
- * printf("This is the string we just built: %s\n", buf->str);
- * ...
- * }
- * \endcode
- */
-#define ast_dynamic_str_thread_set_va(buf, max_len, ts, fmt, ap) \
- ({ \
- int __res; \
- while ((__res = ast_dynamic_str_thread_build_va(buf, max_len, \
- ts, 0, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) { \
- va_end(ap); \
- va_start(ap, fmt); \
- } \
- (__res); \
- })
-
-/*!
- * \brief Append to a thread local dynamic string using a va_list
- *
- * The arguments, return values, and usage of this are the same as those for
- * ast_dynamic_str_thread_set_va(). However, instead of setting a new value
- * for the string, this will append to the current value.
- */
-#define ast_dynamic_str_thread_append_va(buf, max_len, ts, fmt, ap) \
- ({ \
- int __res; \
- while ((__res = ast_dynamic_str_thread_build_va(buf, max_len, \
- ts, 1, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) { \
- va_end(ap); \
- va_start(ap, fmt); \
- } \
- (__res); \
- })
-
-/*!
- * \brief Core functionality of ast_dynamic_str_thread_(set|append)_va
- *
- * The arguments to this function are the same as those described for
- * ast_dynamic_str_thread_set_va except for an addition argument, append.
- * If append is non-zero, this will append to the current string instead of
- * writing over it.
- */
-int ast_dynamic_str_thread_build_va(struct ast_dynamic_str **buf, size_t max_len,
- struct ast_threadstorage *ts, int append, const char *fmt, va_list ap);
-
-/*!
- * \brief Set a thread locally stored dynamic string using variable arguments
- *
- * \arg buf This is the address of a pointer to an ast_dynamic_str which should
- * have been retrieved using ast_dynamic_str_thread_get. It will need to
- * be updated in the case that the buffer has to be reallocated to
- * accomodate a longer string than what it currently has space for.
- * \arg max_len This is the maximum length to allow the string buffer to grow
- * to. If this is set to 0, then there is no maximum length.
- * \arg ts This is a pointer to the thread storage structure declared by using
- * the AST_THREADSTORAGE macro. If declared with
- * AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be
- * (&my_buf).
- * \arg fmt This is the format string (printf style)
*
* \return The return value of this function is the same as that of the printf
* family of functions.
@@ -400,7 +434,7 @@
*
* \arg buf This is the address of a pointer to an ast_dynamic_str. It will
* need to be updated in the case that the buffer has to be reallocated to
- * accomodate a longer string than what it currently has space for.
+ * accommodate a longer string than what it currently has space for.
* \arg max_len This is the maximum length to allow the string buffer to grow
* to. If this is set to 0, then there is no maximum length.
*
@@ -424,7 +458,7 @@
)
/*!
- * \brief Append to a dynatic string
+ * \brief Append to a dynamic string
*
* The arguments, return values, and usage of this function are the same as
* ast_dynamic_str_set(). However, this function appends to the string instead
Modified: team/oej/codename-pineapple/include/asterisk/utils.h
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/include/asterisk/utils.h?view=diff&rev=48134&r1=48133&r2=48134
==============================================================================
--- team/oej/codename-pineapple/include/asterisk/utils.h (original)
+++ team/oej/codename-pineapple/include/asterisk/utils.h Thu Nov 30 07:47:28 2006
@@ -218,6 +218,16 @@
int test_for_thread_safety(void);
+/*!
+ * \brief thread-safe replacement for inet_ntoa().
+ *
+ * \note It is very important to note that even though this is a thread-safe
+ * replacement for inet_ntoa(), it is *not* reentrant. In a single
+ * thread, the result from a previous call to this function is no longer
+ * valid once it is called again. If the result from multiple calls to
+ * this function need to be kept or used at once, then the result must be
+ * copied to a local buffer before calling this function again.
+ */
const char *ast_inet_ntoa(struct in_addr ia);
#ifdef inet_ntoa
Modified: team/oej/codename-pineapple/main/http.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/main/http.c?view=diff&rev=48134&r1=48133&r2=48134
==============================================================================
--- team/oej/codename-pineapple/main/http.c (original)
+++ team/oej/codename-pineapple/main/http.c Thu Nov 30 07:47:28 2006
@@ -58,12 +58,28 @@
#define DEFAULT_PREFIX "/asterisk"
/*!
- * In order to have SSL support, we need the openssl libraries.
+ * In order to have TLS/SSL support, we need the openssl libraries.
* Still we can decide whether or not to use them by commenting
* in or out the DO_SSL macro.
+ * TLS/SSL support is basically implemented by reading from a config file
+ * (currently http.conf) the names of the certificate and cipher to use,
+ * and then run ssl_setup() to create an appropriate SSL_CTX (ssl_ctx)
+ * If we support multiple domains, presumably we need to read multiple
+ * certificates.
+ * When we are requested to open a TLS socket, we run make_file_from_fd()
+ * on the socket, to do the necessary setup. At the moment the context's name
+ * is hardwired in the function, but we can certainly make it into an extra
+ * parameter to the function.
+ *
* We declare most of ssl support variables unconditionally,
* because their number is small and this simplifies the code.
+ *
+ * NOTE: the ssl-support variables (ssl_ctx, do_ssl, certfile, cipher)
+ * and their setup should be moved to a more central place, e.g. asterisk.conf
+ * and the source files that processes it. Similarly, ssl_setup() should
+ * be run earlier in the startup process so modules have it available.
*/
+
#if defined(HAVE_OPENSSL) && (defined(HAVE_FUNOPEN) || defined(HAVE_FOPENCOOKIE))
#define DO_SSL /* comment in/out if you want to support ssl */
#endif
@@ -71,7 +87,9 @@
#ifdef DO_SSL
#include <openssl/ssl.h>
#include <openssl/err.h>
-SSL_CTX* ssl_ctx;
+static SSL_CTX* ssl_ctx;
+#else
+typedef struct {} SSL; /* so we can define a pointer to it */
#endif /* DO_SSL */
/* SSL support */
@@ -80,18 +98,46 @@
static char *certfile;
static char *cipher;
+/*!
+ * The following code implements a generic mechanism for starting
+ * services on a TCP or TLS socket.
+ * The service is configured in the struct server_args, and
+ * then started by calling server_start(desc) on the descriptor.
+ * server_start() first verifies if an instance of the service is active,
+ * and in case shuts it down. Then, if the service must be started, creates
+ * a socket and a thread in charge of doing the accept().
+ *
+ * The body of the thread is desc->accept_fn(desc), which the user can define
+ * freely. We supply a sample implementation, server_root(), structured as an
+ * infinite loop. At the beginning of each iteration it runs periodic_fn()
+ * if defined (e.g. to perform some cleanup etc.) then issues a poll()
+ * or equivalent with a timeout of 'poll_timeout' milliseconds, and if the
+ * following accept() is successful it creates a thread in charge of
+ * running the session, whose body is desc->worker_fn(). The argument of
+ * worker_fn() is a struct server_instance, which contains the address
+ * of the other party, a pointer to desc, the file descriptors (fd) on which
+ * we can do a select/poll (but NOT IO/, and a FILE * on which we can do I/O.
+ * We have both because we want to support plain and SSL sockets, and
+ * going through a FILE * lets us provide the encryption/decryption
+ * on the stream without using an auxiliary thread.
+ *
+ * NOTE: in order to let other parts of asterisk use these services,
+ * we need to do the following:
+ * + move struct server_instance and struct server_args to
+ * a common header file, together with prototypes for
+ * server_start() and server_root().
+ * +
+ */
+
/*!
* describes a server instance
*/
struct server_instance {
FILE *f; /* fopen/funopen result */
int fd; /* the socket returned by accept() */
- int is_ssl; /* is this an ssl session ? */
-#ifdef DO_SSL
SSL *ssl; /* ssl state */
-#endif
struct sockaddr_in requestor;
- ast_http_callback callback;
+ struct server_args *parent;
};
/*!
@@ -102,8 +148,16 @@
struct sockaddr_in oldsin;
int is_ssl; /* is this an SSL accept ? */
int accept_fd;
+ int poll_timeout;
pthread_t master;
+ void *(*accept_fn)(void *); /* the function in charge of doing the accept */
+ void (*periodic_fn)(void *); /* something we may want to run before after select on the accept socket */
+ void *(*worker_fn)(void *); /* the function in charge of doing the actual work */
+ const char *name;
};
+
+static void *server_root(void *arg);
+static void *httpd_helper_thread(void *arg);
/*!
* we have up to two accepting threads, one for http, one for https
@@ -112,12 +166,20 @@
.accept_fd = -1,
.master = AST_PTHREADT_NULL,
.is_ssl = 0,
+ .poll_timeout = -1,
+ .name = "http server",
+ .accept_fn = server_root,
+ .worker_fn = httpd_helper_thread,
};
static struct server_args https_desc = {
.accept_fd = -1,
.master = AST_PTHREADT_NULL,
.is_ssl = 1,
+ .poll_timeout = -1,
+ .name = "https server",
+ .accept_fn = server_root,
+ .worker_fn = httpd_helper_thread,
};
static struct ast_http_uri *uris; /*!< list of supported handlers */
@@ -471,19 +533,19 @@
}
#endif /* DO_SSL */
-static void *ast_httpd_helper_thread(void *data)
-{
- char buf[4096];
- char cookie[4096];
+/*!
+ * creates a FILE * from the fd passed by the accept thread.
+ * This operation is potentially expensive (certificate verification),
+ * so we do it in the child thread context.
+ */
+static void *make_file_from_fd(void *data)
+{
struct server_instance *ser = data;
- struct ast_variable *var, *prev=NULL, *vars=NULL;
- char *uri, *c, *title=NULL;
- int status = 200, contentlength = 0;
/*
* open a FILE * as appropriate.
*/
- if (!ser->is_ssl)
+ if (!ser->parent->is_ssl)
ser->f = fdopen(ser->fd, "w+");
#ifdef DO_SSL
else if ( (ser->ssl = SSL_new(ssl_ctx)) ) {
@@ -511,8 +573,20 @@
if (!ser->f) {
close(ser->fd);
ast_log(LOG_WARNING, "FILE * open failed!\n");
- goto done;
- }
+ free(ser);
+ return NULL;
+ }
+ return ser->parent->worker_fn(ser);
+}
+
+static void *httpd_helper_thread(void *data)
+{
+ char buf[4096];
+ char cookie[4096];
+ struct server_instance *ser = data;
+ struct ast_variable *var, *prev=NULL, *vars=NULL;
+ char *uri, *c, *title=NULL;
+ int status = 200, contentlength = 0;
if (!fgets(buf, sizeof(buf), ser->f))
goto done;
@@ -631,7 +705,7 @@
return NULL;
}
-static void *http_root(void *data)
+static void *server_root(void *data)
{
struct server_args *desc = data;
int fd;
@@ -642,9 +716,13 @@
pthread_attr_t attr;
for (;;) {
- int flags;
-
- ast_wait_for_input(desc->accept_fd, -1);
+ int i, flags;
+
+ if (desc->periodic_fn)
+ desc->periodic_fn(desc);
+ i = ast_wait_for_input(desc->accept_fd, desc->poll_timeout);
+ if (i <= 0)
+ continue;
sinlen = sizeof(sin);
fd = accept(desc->accept_fd, (struct sockaddr *)&sin, &sinlen);
if (fd < 0) {
@@ -661,13 +739,13 @@
flags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
ser->fd = fd;
- ser->is_ssl = desc->is_ssl;
+ ser->parent = desc;
memcpy(&ser->requestor, &sin, sizeof(ser->requestor));
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if (ast_pthread_create_background(&launched, &attr, ast_httpd_helper_thread, ser)) {
+ if (ast_pthread_create_background(&launched, &attr, make_file_from_fd, ser)) {
ast_log(LOG_WARNING, "Unable to launch helper thread: %s\n", strerror(errno));
close(ser->fd);
free(ser);
@@ -721,7 +799,12 @@
#endif
}
-static void http_server_start(struct server_args *desc)
+/*!
+ * This is a generic (re)start routine for a TCP server,
+ * which does the socket/bind/listen and starts a thread for handling
+ * accept().
+ */
+static void server_start(struct server_args *desc)
{
int flags;
int x = 1;
@@ -729,7 +812,7 @@
/* Do nothing if nothing has changed */
[... 797 lines stripped ...]
More information about the asterisk-commits
mailing list