[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