[asterisk-commits] dvossel: branch dvossel/iax2encryption_trunk r174883 - in /team/dvossel/iax2e...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Feb 11 11:26:37 CST 2009
Author: dvossel
Date: Wed Feb 11 11:26:37 2009
New Revision: 174883
URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=174883
Log:
synicify the branch
Modified:
team/dvossel/iax2encryption_trunk/ (props changed)
team/dvossel/iax2encryption_trunk/apps/app_chanspy.c
team/dvossel/iax2encryption_trunk/apps/app_rpt.c
team/dvossel/iax2encryption_trunk/apps/app_stack.c
team/dvossel/iax2encryption_trunk/apps/app_voicemail.c
team/dvossel/iax2encryption_trunk/channels/chan_sip.c
team/dvossel/iax2encryption_trunk/include/asterisk/slinfactory.h
team/dvossel/iax2encryption_trunk/main/channel.c
team/dvossel/iax2encryption_trunk/main/jitterbuf.c
team/dvossel/iax2encryption_trunk/main/manager.c
team/dvossel/iax2encryption_trunk/main/slinfactory.c
Propchange: team/dvossel/iax2encryption_trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-blocked' - no diff available.
Propchange: team/dvossel/iax2encryption_trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.
Propchange: team/dvossel/iax2encryption_trunk/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Wed Feb 11 11:26:37 2009
@@ -1,1 +1,1 @@
-/trunk:1-174360
+/trunk:1-174882
Modified: team/dvossel/iax2encryption_trunk/apps/app_chanspy.c
URL: http://svn.digium.com/svn-view/asterisk/team/dvossel/iax2encryption_trunk/apps/app_chanspy.c?view=diff&rev=174883&r1=174882&r2=174883
==============================================================================
--- team/dvossel/iax2encryption_trunk/apps/app_chanspy.c (original)
+++ team/dvossel/iax2encryption_trunk/apps/app_chanspy.c Wed Feb 11 11:26:37 2009
@@ -829,22 +829,9 @@
chanspy_ds_free(peer_chanspy_ds), prev = peer,
peer_chanspy_ds = next_chanspy_ds ? next_chanspy_ds :
next_channel(chan, prev, spec, exten, context, &chanspy_ds), next_chanspy_ds = NULL) {
- const char *group;
int igrp = !mygroup;
- char *groups[NUM_SPYGROUPS];
- char *mygroups[NUM_SPYGROUPS];
- int num_groups = 0;
- char dup_group[512];
- int num_mygroups = 0;
- char *dup_mygroup;
- int x;
- int y;
+ int ienf = !myenforced;
char *s;
- char *buffer;
- char *end;
- char *ext;
- char *form_enforced;
- int ienf = !myenforced;
peer = peer_chanspy_ds->chan;
@@ -873,7 +860,16 @@
}
if (mygroup) {
- dup_mygroup = ast_strdupa(mygroup);
+ int num_groups = 0;
+ int num_mygroups = 0;
+ char dup_group[512];
+ char dup_mygroup[512];
+ char *groups[NUM_SPYGROUPS];
+ char *mygroups[NUM_SPYGROUPS];
+ const char *group;
+ int x;
+ int y;
+ ast_copy_string(dup_mygroup, mygroup, sizeof(dup_mygroup));
num_mygroups = ast_app_separate_args(dup_mygroup, ':', mygroups,
ARRAY_LEN(mygroups));
@@ -899,35 +895,28 @@
}
if (myenforced) {
-
- /* We don't need to allocate more space than just the
- length of (peer->name) for ext as we will cut the
- channel name's ending before copying into ext */
-
- ext = alloca(strlen(peer->name));
-
- form_enforced = alloca(strlen(myenforced) + 3);
-
- strcpy(form_enforced, ":");
- strcat(form_enforced, myenforced);
- strcat(form_enforced, ":");
-
- buffer = ast_strdupa(peer->name);
-
- if ((end = strchr(buffer, '-'))) {
+ char ext[AST_CHANNEL_NAME + 3];
+ char buffer[512];
+ char *end;
+
+ snprintf(buffer, sizeof(buffer) - 1, ":%s:", myenforced);
+
+ ast_copy_string(ext + 1, peer->name, sizeof(ext) - 1);
+ if ((end = strchr(ext, '-'))) {
*end++ = ':';
*end = '\0';
}
- strcpy(ext, ":");
- strcat(ext, buffer);
-
- if (strcasestr(form_enforced, ext))
+ ext[0] = ':';
+
+ if (strcasestr(buffer, ext)) {
ienf = 1;
- }
-
- if (!ienf)
+ }
+ }
+
+ if (!ienf) {
continue;
+ }
strcpy(peer_name, "spy-");
strncat(peer_name, peer->name, AST_NAME_STRLEN - 4 - 1);
Modified: team/dvossel/iax2encryption_trunk/apps/app_rpt.c
URL: http://svn.digium.com/svn-view/asterisk/team/dvossel/iax2encryption_trunk/apps/app_rpt.c?view=diff&rev=174883&r1=174882&r2=174883
==============================================================================
--- team/dvossel/iax2encryption_trunk/apps/app_rpt.c (original)
+++ team/dvossel/iax2encryption_trunk/apps/app_rpt.c Wed Feb 11 11:26:37 2009
@@ -318,6 +318,7 @@
#include <signal.h>
#include <stdio.h>
+#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
@@ -599,8 +600,8 @@
int mode;
struct rpt_link mylink;
char param[TELEPARAMSIZE];
- int submode;
- unsigned int parrot;
+ intptr_t submode;
+ uintptr_t parrot;
pthread_t threadid;
} ;
@@ -4971,7 +4972,7 @@
case PARROT: /* Repeat stuff */
- sprintf(mystr,PARROTFILE,myrpt->name,mytele->parrot);
+ sprintf(mystr,PARROTFILE,myrpt->name,(unsigned int)mytele->parrot);
if (ast_fileexists(mystr,NULL,mychannel->language) <= 0)
{
imdone = 1;
@@ -4979,14 +4980,14 @@
break;
}
wait_interval(myrpt, DLY_PARROT, mychannel);
- sprintf(mystr,PARROTFILE,myrpt->name,mytele->parrot);
+ sprintf(mystr,PARROTFILE,myrpt->name,(unsigned int)mytele->parrot);
res = ast_streamfile(mychannel, mystr, mychannel->language);
if (!res)
res = ast_waitstream(mychannel, "");
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
ast_stopstream(mychannel);
- sprintf(mystr,PARROTFILE,myrpt->name,mytele->parrot);
+ sprintf(mystr,PARROTFILE,myrpt->name,(unsigned int)mytele->parrot);
strcat(mystr,".wav");
unlink(mystr);
imdone = 1;
@@ -5254,7 +5255,7 @@
memset((char *)tele,0,sizeof(struct rpt_tele));
tele->rpt = myrpt;
tele->mode = mode;
- if (mode == PARROT) tele->parrot = (unsigned int) data;
+ if (mode == PARROT) tele->parrot = (uintptr_t) data;
else mylink = (struct rpt_link *) data;
rpt_mutex_lock(&myrpt->lock);
if((mode == CONNFAIL) || (mode == REMDISC) || (mode == CONNECTED) ||
@@ -5268,7 +5269,7 @@
strncpy(tele->param, (char *) data, TELEPARAMSIZE - 1);
tele->param[TELEPARAMSIZE - 1] = 0;
}
- if (mode == REMXXX) tele->submode = (int) data;
+ if (mode == REMXXX) tele->submode = (intptr_t) data;
insque((struct qelem *)tele, (struct qelem *)myrpt->tele.next);
rpt_mutex_unlock(&myrpt->lock);
pthread_attr_init(&attr);
@@ -6375,6 +6376,7 @@
static int function_cop(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
{
char string[16];
+ int res;
int i, r;
@@ -6383,7 +6385,7 @@
switch(myatoi(param)){
case 1: /* System reset */
- system("killall -9 asterisk");
+ res = system("killall -9 asterisk");
return DC_COMPLETE;
case 2:
@@ -9636,7 +9638,8 @@
static int function_remote(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
{
char *s,*s1,*s2;
- int i,j,p,r,ht,k,l,ls2,m,d,offset,offsave, modesave, defmode;
+ int i,j,r,ht,k,l,ls2,m,d,offset,offsave, modesave, defmode=0;
+ intptr_t p;
char multimode = 0;
char oc,*cp,*cp1,*cp2;
char tmp[20], freq[20] = "", savestr[20] = "";
@@ -11988,7 +11991,7 @@
ast_closestream(myrpt->parrotstream);
myrpt->parrotstream = NULL;
myrpt->parrotstate = 2;
- rpt_telemetry(myrpt,PARROT,(struct rpt_link *) myrpt->parrotcnt++);
+ rpt_telemetry(myrpt,PARROT,(void *) ((intptr_t)myrpt->parrotcnt++));
}
if (myrpt->cmdAction.state == CMD_STATE_READY)
{ /* there is a command waiting to be processed */
@@ -13661,7 +13664,7 @@
donodelog(myrpt,str);
}
if (!phone_mode) send_newkey(chan);
- return AST_PBX_KEEPALIVE;
+ return 0;
}
/* well, then it is a remote */
rpt_mutex_lock(&myrpt->lock);
Modified: team/dvossel/iax2encryption_trunk/apps/app_stack.c
URL: http://svn.digium.com/svn-view/asterisk/team/dvossel/iax2encryption_trunk/apps/app_stack.c?view=diff&rev=174883&r1=174882&r2=174883
==============================================================================
--- team/dvossel/iax2encryption_trunk/apps/app_stack.c (original)
+++ team/dvossel/iax2encryption_trunk/apps/app_stack.c Wed Feb 11 11:26:37 2009
@@ -596,16 +596,16 @@
int res;
ast_debug(1, "Trying gosub with arguments '%s'\n", gosub_args);
- ast_copy_string(chan->context, "app_stack_gosub_virtual_context", sizeof(chan->context));
- ast_copy_string(chan->exten, "s", sizeof(chan->exten));
- chan->priority = 0;
if ((res = pbx_exec(chan, theapp, gosub_args)) == 0) {
struct ast_pbx *pbx = chan->pbx;
+ struct ast_pbx_args args;
+ memset(&args, 0, sizeof(args));
+ args.no_hangup_chan = 1;
/* Suppress warning about PBX already existing */
chan->pbx = NULL;
ast_agi_send(agi->fd, chan, "100 result=0 Trying...\n");
- ast_pbx_run(chan);
+ ast_pbx_run_args(chan, &args);
ast_agi_send(agi->fd, chan, "200 result=0 Gosub complete\n");
if (chan->pbx) {
ast_free(chan->pbx);
@@ -638,13 +638,8 @@
static int unload_module(void)
{
- struct ast_context *con;
-
- if (ast_agi_unregister && ast_agi_unregister(ast_module_info->self, &gosub_agi_command) == 1) {
- if ((con = ast_context_find("app_stack_gosub_virtual_context"))) {
- ast_context_remove_extension2(con, "s", 1, NULL, 0);
- ast_context_destroy(con, "app_stack"); /* leave nothing behind */
- }
+ if (ast_agi_unregister) {
+ ast_agi_unregister(ast_module_info->self, &gosub_agi_command);
}
ast_unregister_application(app_return);
@@ -659,15 +654,8 @@
static int load_module(void)
{
- struct ast_context *con;
-
- if (ast_agi_register && ast_agi_register(ast_module_info->self, &gosub_agi_command) == 1) {
- if (!(con = ast_context_find_or_create(NULL, NULL, "app_stack_gosub_virtual_context", "app_stack"))) {
- ast_log(LOG_ERROR, "Virtual context 'app_stack_gosub_virtual_context' does not exist and unable to create\n");
- return AST_MODULE_LOAD_DECLINE;
- } else {
- ast_add_extension2(con, 1, "s", 1, NULL, NULL, "KeepAlive", ast_strdup(""), ast_free_ptr, "app_stack");
- }
+ if (ast_agi_register) {
+ ast_agi_register(ast_module_info->self, &gosub_agi_command);
}
ast_register_application_xml(app_pop, pop_exec);
Modified: team/dvossel/iax2encryption_trunk/apps/app_voicemail.c
URL: http://svn.digium.com/svn-view/asterisk/team/dvossel/iax2encryption_trunk/apps/app_voicemail.c?view=diff&rev=174883&r1=174882&r2=174883
==============================================================================
--- team/dvossel/iax2encryption_trunk/apps/app_voicemail.c (original)
+++ team/dvossel/iax2encryption_trunk/apps/app_voicemail.c Wed Feb 11 11:26:37 2009
@@ -1117,8 +1117,8 @@
ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser));
} else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) {
ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword));
- } else if (!strcasecmp(tmp->name, "imapvmshareid")) {
- ast_copy_string(retval->imapvmshareid, tmp->value, sizeof(retval->imapvmshareid));
+ } else if (!strcasecmp(var->name, "imapvmshareid")) {
+ ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid));
#endif
} else
apply_option(retval, var->name, var->value);
Modified: team/dvossel/iax2encryption_trunk/channels/chan_sip.c
URL: http://svn.digium.com/svn-view/asterisk/team/dvossel/iax2encryption_trunk/channels/chan_sip.c?view=diff&rev=174883&r1=174882&r2=174883
==============================================================================
--- team/dvossel/iax2encryption_trunk/channels/chan_sip.c (original)
+++ team/dvossel/iax2encryption_trunk/channels/chan_sip.c Wed Feb 11 11:26:37 2009
@@ -5230,9 +5230,11 @@
if (inuse) {
sip_pvt_lock(fup);
ao2_lock(p);
- if ((*inuse > 0) && ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
- (*inuse)--;
- ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
+ if (*inuse > 0) {
+ if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
+ (*inuse)--;
+ ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
+ }
} else {
*inuse = 0;
}
@@ -5244,9 +5246,11 @@
if (inringing) {
sip_pvt_lock(fup);
ao2_lock(p);
- if ((*inringing > 0)&& ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) {
- (*inringing)--;
- ast_clear_flag(&fup->flags[0], SIP_INC_RINGING);
+ if (*inringing > 0) {
+ if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) {
+ (*inringing)--;
+ ast_clear_flag(&fup->flags[0], SIP_INC_RINGING);
+ }
} else {
*inringing = 0;
}
@@ -5310,7 +5314,9 @@
sip_pvt_lock(fup);
ao2_lock(p);
if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) {
- (*inringing)--;
+ if (*inringing > 0) {
+ (*inringing)--;
+ }
ast_clear_flag(&fup->flags[0], SIP_INC_RINGING);
}
ao2_unlock(p);
@@ -22300,6 +22306,7 @@
peer->socket.type = SIP_TRANSPORT_UDP;
peer->socket.fd = -1;
}
+ peer->type = SIP_TYPE_PEER;
ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
ast_string_field_set(peer, context, sip_cfg.default_context);
Modified: team/dvossel/iax2encryption_trunk/include/asterisk/slinfactory.h
URL: http://svn.digium.com/svn-view/asterisk/team/dvossel/iax2encryption_trunk/include/asterisk/slinfactory.h?view=diff&rev=174883&r1=174882&r2=174883
==============================================================================
--- team/dvossel/iax2encryption_trunk/include/asterisk/slinfactory.h (original)
+++ team/dvossel/iax2encryption_trunk/include/asterisk/slinfactory.h Wed Feb 11 11:26:37 2009
@@ -38,16 +38,27 @@
size_t holdlen; /*!< Number of samples currently in the hold */
unsigned int size; /*!< Number of samples currently in the factory */
unsigned int format; /*!< Current format the translation path is converting from */
+ unsigned int output_format; /*!< The output format desired */
};
/*!
- * \brief Initialize an slinfactory
+ * \brief Initialize a slinfactory
*
* \param sf The slinfactory to initialize
*
* \return Nothing
*/
void ast_slinfactory_init(struct ast_slinfactory *sf);
+
+/*!
+ * \brief Initialize a slinfactory
+ *
+ * \param sf The slinfactory to initialize
+ * \param sample_rate The output sample rate desired
+ *
+ * \return 0 on success, non-zero on failure
+ */
+int ast_slinfactory_init_rate(struct ast_slinfactory *sf, unsigned int sample_rate);
/*!
* \brief Destroy the contents of a slinfactory
@@ -63,7 +74,7 @@
void ast_slinfactory_destroy(struct ast_slinfactory *sf);
/*!
- * \brief Feed audio into an slinfactory
+ * \brief Feed audio into a slinfactory
*
* \param sf The slinfactory to feed into
* \param f Frame containing audio to feed in
@@ -73,7 +84,7 @@
int ast_slinfactory_feed(struct ast_slinfactory *sf, struct ast_frame *f);
/*!
- * \brief Read samples from an slinfactory
+ * \brief Read samples from a slinfactory
*
* \param sf The slinfactory to read from
* \param buf Buffer to put samples into
@@ -84,7 +95,7 @@
int ast_slinfactory_read(struct ast_slinfactory *sf, short *buf, size_t samples);
/*!
- * \brief Retrieve number of samples currently in an slinfactory
+ * \brief Retrieve number of samples currently in a slinfactory
*
* \param sf The slinfactory to peek into
*
@@ -93,7 +104,7 @@
unsigned int ast_slinfactory_available(const struct ast_slinfactory *sf);
/*!
- * \brief Flush the contents of an slinfactory
+ * \brief Flush the contents of a slinfactory
*
* \param sf The slinfactory to flush
*
Modified: team/dvossel/iax2encryption_trunk/main/channel.c
URL: http://svn.digium.com/svn-view/asterisk/team/dvossel/iax2encryption_trunk/main/channel.c?view=diff&rev=174883&r1=174882&r2=174883
==============================================================================
--- team/dvossel/iax2encryption_trunk/main/channel.c (original)
+++ team/dvossel/iax2encryption_trunk/main/channel.c Wed Feb 11 11:26:37 2009
@@ -1410,7 +1410,10 @@
ast_free(chan);
AST_RWLIST_UNLOCK(&channels);
- ast_devstate_changed_literal(AST_DEVICE_NOT_INUSE, name);
+ /* Queue an unknown state, because, while we know that this particular
+ * instance is dead, we don't know the state of all other possible
+ * instances. */
+ ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name);
}
struct ast_datastore *ast_channel_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
Modified: team/dvossel/iax2encryption_trunk/main/jitterbuf.c
URL: http://svn.digium.com/svn-view/asterisk/team/dvossel/iax2encryption_trunk/main/jitterbuf.c?view=diff&rev=174883&r1=174882&r2=174883
==============================================================================
--- team/dvossel/iax2encryption_trunk/main/jitterbuf.c (original)
+++ team/dvossel/iax2encryption_trunk/main/jitterbuf.c Wed Feb 11 11:26:37 2009
@@ -510,27 +510,33 @@
jb_dbg2("jb_put(%x,%x,%ld,%ld,%ld)\n", jb, data, ms, ts, now);
- jb->info.frames_in++;
-
- if (jb->frames && jb->dropem)
+ numts = 0;
+ if (jb->frames)
+ numts = jb->frames->prev->ts - jb->frames->ts;
+
+ if (numts >= jb->info.conf.max_jitterbuf) {
+ if (!jb->dropem) {
+ ast_debug(1, "Attempting to exceed Jitterbuf max %ld timeslots\n",
+ jb->info.conf.max_jitterbuf);
+ jb->dropem = 1;
+ }
+ jb->info.frames_dropped++;
return JB_DROP;
- jb->dropem = 0;
+ } else {
+ jb->dropem = 0;
+ }
if (type == JB_TYPE_VOICE) {
/* presently, I'm only adding VOICE frames to history and drift calculations; mostly because with the
* IAX integrations, I'm sending retransmitted control frames with their awkward timestamps through */
- if (history_put(jb,ts,now,ms))
+ if (history_put(jb,ts,now,ms)) {
+ jb->info.frames_dropped++;
return JB_DROP;
- }
- numts = 0;
- if (jb->frames)
- numts = jb->frames->prev->ts - jb->frames->ts;
- if (numts >= jb->info.conf.max_jitterbuf) {
- ast_debug(1, "Attempting to exceed Jitterbuf max %ld timeslots\n",
- jb->info.conf.max_jitterbuf);
- jb->dropem = 1;
- return JB_DROP;
- }
+ }
+ }
+
+ jb->info.frames_in++;
+
/* if put into head of queue, caller needs to reschedule */
if (queue_put(jb,data,type,ms,ts)) {
return JB_SCHED;
Modified: team/dvossel/iax2encryption_trunk/main/manager.c
URL: http://svn.digium.com/svn-view/asterisk/team/dvossel/iax2encryption_trunk/main/manager.c?view=diff&rev=174883&r1=174882&r2=174883
==============================================================================
--- team/dvossel/iax2encryption_trunk/main/manager.c (original)
+++ team/dvossel/iax2encryption_trunk/main/manager.c Wed Feb 11 11:26:37 2009
@@ -149,7 +149,39 @@
{{ "restart", "gracefully", NULL }},
};
-struct mansession {
+/* In order to understand what the heck is going on with the
+ * mansession_session and mansession structs, we need to have a bit of a history
+ * lesson.
+ *
+ * In the beginning, there was the mansession. The mansession contained data that was
+ * intrinsic to a manager session, such as the time that it started, the name of the logged-in
+ * user, etc. In addition to these parameters were the f and fd parameters. For typical manager
+ * sessions, these were used to represent the TCP socket over which the AMI session was taking
+ * place. It makes perfect sense for these fields to be a part of the session-specific data since
+ * the session actually defines this information.
+ *
+ * Then came the HTTP AMI sessions. With these, the f and fd fields need to be opened and closed
+ * for every single action that occurs. Thus the f and fd fields aren't really specific to the session
+ * but rather to the action that is being executed. Because a single session may execute many commands
+ * at once, some sort of safety needed to be added in order to be sure that we did not end up with fd
+ * leaks from one action overwriting the f and fd fields used by a previous action before the previous action
+ * has had a chance to properly close its handles.
+ *
+ * The initial idea to solve this was to use thread synchronization, but this prevented multiple actions
+ * from being run at the same time in a single session. Some manager actions may block for a long time, thus
+ * creating a large queue of actions to execute. In addition, this fix did not address the basic architectural
+ * issue that for HTTP manager sessions, the f and fd variables are not really a part of the session, but are
+ * part of the action instead.
+ *
+ * The new idea was to create a structure on the stack for each HTTP Manager action. This structure would
+ * contain the action-specific information, such as which file to write to. In order to maintain expectations
+ * of action handlers and not have to change the public API of the manager code, we would need to name this
+ * new stacked structure 'mansession' and contain within it the old mansession struct that we used to use.
+ * We renamed the old mansession struct 'mansession_session' to hopefully convey that what is in this structure
+ * is session-specific data. The structure that it is wrapped in, called a 'mansession' really contains action-specific
+ * data.
+ */
+struct mansession_session {
pthread_t ms_t; /*!< Execution thread, basically useless */
ast_mutex_t __lock; /*!< Thread lock -- don't use in action callbacks, it's already taken care of */
/* XXX need to document which fields it is protecting */
@@ -175,12 +207,23 @@
int writetimeout; /*!< Timeout for ast_carefulwrite() */
int pending_event; /*!< Pending events indicator in case when waiting_thread is NULL */
AST_LIST_HEAD_NOLOCK(mansession_datastores, ast_datastore) datastores; /*!< Data stores on the session */
- AST_LIST_ENTRY(mansession) list;
+ AST_LIST_ENTRY(mansession_session) list;
};
-#define NEW_EVENT(m) (AST_LIST_NEXT(m->last_ev, eq_next))
-
-static AST_LIST_HEAD_STATIC(sessions, mansession);
+/* In case you didn't read that giant block of text above the mansession_session struct, the
+ * 'mansession' struct is named this solely to keep the API the same in Asterisk. This structure really
+ * represents data that is different from Manager action to Manager action. The mansession_session pointer
+ * contained within points to session-specific data.
+ */
+struct mansession {
+ struct mansession_session *session;
+ FILE *f;
+ int fd;
+};
+
+#define NEW_EVENT(m) (AST_LIST_NEXT(m->session->last_ev, eq_next))
+
+static AST_LIST_HEAD_STATIC(sessions, mansession_session);
/*! \brief user descriptor, as read from the config file.
*
@@ -428,7 +471,7 @@
static int check_manager_session_inuse(const char *name)
{
- struct mansession *session = NULL;
+ struct mansession_session *session = NULL;
AST_LIST_LOCK(&sessions);
AST_LIST_TRAVERSE(&sessions, session, list) {
@@ -459,13 +502,13 @@
* \param s manager session to get parameter from.
* \return displayconnects config option value.
*/
-static int manager_displayconnects (struct mansession *s)
+static int manager_displayconnects (struct mansession_session *session)
{
struct ast_manager_user *user = NULL;
int ret = 0;
AST_RWLIST_RDLOCK(&users);
- if ((user = get_manager_by_name_locked (s->username)))
+ if ((user = get_manager_by_name_locked (session->username)))
ret = user->displayconnects;
AST_RWLIST_UNLOCK(&users);
@@ -678,7 +721,7 @@
/*! \brief CLI command manager list connected */
static char *handle_showmanconn(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- struct mansession *s;
+ struct mansession_session *session;
time_t now = time(NULL);
#define HSMCONN_FORMAT1 " %-15.15s %-15.15s %-10.10s %-10.10s %-8.8s %-8.8s %-5.5s %-5.5s\n"
#define HSMCONN_FORMAT2 " %-15.15s %-15.15s %-10d %-10d %-8d %-8d %-5.5d %-5.5d\n"
@@ -698,8 +741,8 @@
ast_cli(a->fd, HSMCONN_FORMAT1, "Username", "IP Address", "Start", "Elapsed", "FileDes", "HttpCnt", "Read", "Write");
AST_LIST_LOCK(&sessions);
- AST_LIST_TRAVERSE(&sessions, s, list) {
- ast_cli(a->fd, HSMCONN_FORMAT2, s->username, ast_inet_ntoa(s->sin.sin_addr), (int)(s->sessionstart), (int)(now - s->sessionstart), s->fd, s->inuse, s->readperm, s->writeperm);
+ AST_LIST_TRAVERSE(&sessions, session, list) {
+ ast_cli(a->fd, HSMCONN_FORMAT2, session->username, ast_inet_ntoa(session->sin.sin_addr), (int)(session->sessionstart), (int)(now - session->sessionstart), session->fd, session->inuse, session->readperm, session->writeperm);
count++;
}
AST_LIST_UNLOCK(&sessions);
@@ -787,30 +830,30 @@
/*
* destroy a session, leaving the usecount
*/
-static void free_session(struct mansession *s)
-{
- struct eventqent *eqe = s->last_ev;
+static void free_session(struct mansession_session *session)
+{
+ struct eventqent *eqe = session->last_ev;
struct ast_datastore *datastore;
/* Get rid of each of the data stores on the session */
- while ((datastore = AST_LIST_REMOVE_HEAD(&s->datastores, entry))) {
+ while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) {
/* Free the data store */
ast_datastore_free(datastore);
}
- if (s->f != NULL)
- fclose(s->f);
- ast_mutex_destroy(&s->__lock);
- ast_free(s);
+ if (session->f != NULL)
+ fclose(session->f);
+ ast_mutex_destroy(&session->__lock);
+ ast_free(session);
unref_event(eqe);
}
-static void destroy_session(struct mansession *s)
+static void destroy_session(struct mansession_session *session)
{
AST_LIST_LOCK(&sessions);
- AST_LIST_REMOVE(&sessions, s, list);
+ AST_LIST_REMOVE(&sessions, session, list);
ast_atomic_fetchadd_int(&num_sessions, -1);
- free_session(s);
+ free_session(session);
AST_LIST_UNLOCK(&sessions);
}
@@ -899,7 +942,11 @@
*/
static int send_string(struct mansession *s, char *string)
{
- return ast_careful_fwrite(s->f, s->fd, string, strlen(string), s->writetimeout);
+ if (s->f) {
+ return ast_careful_fwrite(s->f, s->fd, string, strlen(string), s->session->writetimeout);
+ } else {
+ return ast_careful_fwrite(s->session->f, s->session->fd, string, strlen(string), s->session->writetimeout);
+ }
}
/*!
@@ -930,7 +977,7 @@
ast_str_set_va(&buf, 0, fmt, ap);
va_end(ap);
- if (s->f != NULL) {
+ if (s->f != NULL || s->session->f != NULL) {
send_string(s, ast_str_buffer(buf));
} else {
ast_verbose("fd == -1 in astman_append, should not happen\n");
@@ -939,7 +986,7 @@
/*! \note NOTE: XXX this comment is unclear and possibly wrong.
Callers of astman_send_error(), astman_send_response() or astman_send_ack() must EITHER
- hold the session lock _or_ be running in an action callback (in which case s->busy will
+ hold the session lock _or_ be running in an action callback (in which case s->session->busy will
be non-zero). In either of these cases, there is no need to lock-protect the session's
fd, since no other output will be sent (events will be queued), and no input will
be read until either the current action finishes or get_input() obtains the session
@@ -1005,10 +1052,10 @@
{
int maskint = strings_to_mask(eventmask);
- ast_mutex_lock(&s->__lock);
+ ast_mutex_lock(&s->session->__lock);
if (maskint >= 0)
- s->send_events = maskint;
- ast_mutex_unlock(&s->__lock);
+ s->session->send_events = maskint;
+ ast_mutex_unlock(&s->session->__lock);
return maskint;
}
@@ -1034,12 +1081,12 @@
AST_RWLIST_WRLOCK(&users);
if (!(user = get_manager_by_name_locked(username))) {
- ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->sin.sin_addr), username);
- } else if (user->ha && !ast_apply_ha(user->ha, &(s->sin))) {
- ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), username);
+ ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
+ } else if (user->ha && !ast_apply_ha(user->ha, &(s->session->sin))) {
+ ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
} else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) {
const char *key = astman_get_header(m, "Key");
- if (!ast_strlen_zero(key) && !ast_strlen_zero(s->challenge) && user->secret) {
+ if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) {
int x;
int len = 0;
char md5key[256] = "";
@@ -1047,7 +1094,7 @@
unsigned char digest[16];
MD5Init(&md5);
- MD5Update(&md5, (unsigned char *) s->challenge, strlen(s->challenge));
+ MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge));
MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret));
MD5Final(digest, &md5);
for (x = 0; x < 16; x++)
@@ -1056,24 +1103,24 @@
error = 0;
} else {
ast_debug(1, "MD5 authentication is not possible. challenge: '%s'\n",
- S_OR(s->challenge, ""));
+ S_OR(s->session->challenge, ""));
}
} else if (password && user->secret && !strcmp(password, user->secret))
error = 0;
if (error) {
- ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), username);
+ ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
AST_RWLIST_UNLOCK(&users);
return -1;
}
/* auth complete */
- ast_copy_string(s->username, username, sizeof(s->username));
- s->readperm = user->readperm;
- s->writeperm = user->writeperm;
- s->writetimeout = user->writetimeout;
- s->sessionstart = time(NULL);
+ ast_copy_string(s->session->username, username, sizeof(s->session->username));
+ s->session->readperm = user->readperm;
+ s->session->writeperm = user->writeperm;
+ s->session->writetimeout = user->writetimeout;
+ s->session->sessionstart = time(NULL);
set_eventmask(s, astman_get_header(m, "Events"));
AST_RWLIST_UNLOCK(&users);
@@ -1549,76 +1596,76 @@
/* XXX maybe put an upper bound, or prevent the use of 0 ? */
}
- ast_mutex_lock(&s->__lock);
- if (s->waiting_thread != AST_PTHREADT_NULL)
- pthread_kill(s->waiting_thread, SIGURG);
-
- if (s->managerid) { /* AMI-over-HTTP session */
+ ast_mutex_lock(&s->session->__lock);
+ if (s->session->waiting_thread != AST_PTHREADT_NULL)
+ pthread_kill(s->session->waiting_thread, SIGURG);
+
+ if (s->session->managerid) { /* AMI-over-HTTP session */
/*
* Make sure the timeout is within the expire time of the session,
* as the client will likely abort the request if it does not see
* data coming after some amount of time.
*/
time_t now = time(NULL);
- int max = s->sessiontimeout - now - 10;
+ int max = s->session->sessiontimeout - now - 10;
if (max < 0) /* We are already late. Strange but possible. */
max = 0;
if (timeout < 0 || timeout > max)
timeout = max;
- if (!s->send_events) /* make sure we record events */
- s->send_events = -1;
- }
- ast_mutex_unlock(&s->__lock);
+ if (!s->session->send_events) /* make sure we record events */
+ s->session->send_events = -1;
+ }
+ ast_mutex_unlock(&s->session->__lock);
/* XXX should this go inside the lock ? */
- s->waiting_thread = pthread_self(); /* let new events wake up this thread */
+ s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */
ast_debug(1, "Starting waiting for an event!\n");
for (x = 0; x < timeout || timeout < 0; x++) {
- ast_mutex_lock(&s->__lock);
+ ast_mutex_lock(&s->session->__lock);
if (NEW_EVENT(s))
needexit = 1;
/* We can have multiple HTTP session point to the same mansession entry.
* The way we deal with it is not very nice: newcomers kick out the previous
* HTTP session. XXX this needs to be improved.
*/
- if (s->waiting_thread != pthread_self())
+ if (s->session->waiting_thread != pthread_self())
needexit = 1;
- if (s->needdestroy)
+ if (s->session->needdestroy)
needexit = 1;
- ast_mutex_unlock(&s->__lock);
+ ast_mutex_unlock(&s->session->__lock);
if (needexit)
break;
- if (s->managerid == 0) { /* AMI session */
- if (ast_wait_for_input(s->fd, 1000))
+ if (s->session->managerid == 0) { /* AMI session */
+ if (ast_wait_for_input(s->session->fd, 1000))
break;
} else { /* HTTP session */
sleep(1);
}
}
ast_debug(1, "Finished waiting for an event!\n");
- ast_mutex_lock(&s->__lock);
- if (s->waiting_thread == pthread_self()) {
+ ast_mutex_lock(&s->session->__lock);
+ if (s->session->waiting_thread == pthread_self()) {
struct eventqent *eqe;
astman_send_response(s, m, "Success", "Waiting for Event completed.");
while ( (eqe = NEW_EVENT(s)) ) {
ref_event(eqe);
- if (((s->readperm & eqe->category) == eqe->category) &&
- ((s->send_events & eqe->category) == eqe->category)) {
+ if (((s->session->readperm & eqe->category) == eqe->category) &&
+ ((s->session->send_events & eqe->category) == eqe->category)) {
astman_append(s, "%s", eqe->eventdata);
}
- s->last_ev = unref_event(s->last_ev);
+ s->session->last_ev = unref_event(s->session->last_ev);
}
astman_append(s,
"Event: WaitEventComplete\r\n"
"%s"
"\r\n", idText);
- s->waiting_thread = AST_PTHREADT_NULL;
+ s->session->waiting_thread = AST_PTHREADT_NULL;
} else {
ast_debug(1, "Abandoning event request!\n");
}
- ast_mutex_unlock(&s->__lock);
+ ast_mutex_unlock(&s->session->__lock);
return 0;
}
@@ -1635,7 +1682,7 @@
astman_start_ack(s, m);
AST_RWLIST_TRAVERSE(&actions, cur, list) {
- if (s->writeperm & cur->authority || cur->authority == 0)
+ if (s->session->writeperm & cur->authority || cur->authority == 0)
astman_append(s, "%s: %s (Priv: %s)\r\n",
cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
}
@@ -1684,10 +1731,10 @@
astman_send_error(s, m, "Authentication failed");
return -1;
}
- s->authenticated = 1;
- if (manager_displayconnects(s))
- ast_verb(2, "%sManager '%s' logged on from %s\n", (s->managerid ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr));
- ast_log(LOG_EVENT, "%sManager '%s' logged on from %s\n", (s->managerid ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr));
+ s->session->authenticated = 1;
+ if (manager_displayconnects(s->session))
+ ast_verb(2, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_inet_ntoa(s->session->sin.sin_addr));
+ ast_log(LOG_EVENT, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_inet_ntoa(s->session->sin.sin_addr));
astman_send_ack(s, m, "Authentication accepted");
return 0;
}
@@ -1697,12 +1744,12 @@
const char *authtype = astman_get_header(m, "AuthType");
if (!strcasecmp(authtype, "MD5")) {
- if (ast_strlen_zero(s->challenge))
- snprintf(s->challenge, sizeof(s->challenge), "%ld", ast_random());
- ast_mutex_lock(&s->__lock);
+ if (ast_strlen_zero(s->session->challenge))
+ snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random());
+ ast_mutex_lock(&s->session->__lock);
astman_start_ack(s, m);
- astman_append(s, "Challenge: %s\r\n\r\n", s->challenge);
- ast_mutex_unlock(&s->__lock);
+ astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge);
+ ast_mutex_unlock(&s->session->__lock);
} else {
astman_send_error(s, m, "Must specify AuthType");
}
@@ -2412,7 +2459,7 @@
}
} else if (!ast_strlen_zero(app)) {
/* To run the System application (or anything else that goes to shell), you must have the additional System privilege */
- if (!(s->writeperm & EVENT_FLAG_SYSTEM)
+ if (!(s->session->writeperm & EVENT_FLAG_SYSTEM)
&& (
strcasestr(app, "system") == 0 || /* System(rm -rf /)
TrySystem(rm -rf /) */
@@ -2584,22 +2631,22 @@
{
int ret = 0;
- ast_mutex_lock(&s->__lock);
- if (s->f != NULL) {
+ ast_mutex_lock(&s->session->__lock);
+ if (s->session->f != NULL) {
struct eventqent *eqe;
while ( (eqe = NEW_EVENT(s)) ) {
ref_event(eqe);
- if (!ret && s->authenticated &&
- (s->readperm & eqe->category) == eqe->category &&
- (s->send_events & eqe->category) == eqe->category) {
+ if (!ret && s->session->authenticated &&
+ (s->session->readperm & eqe->category) == eqe->category &&
+ (s->session->send_events & eqe->category) == eqe->category) {
if (send_string(s, eqe->eventdata) < 0)
ret = -1; /* don't send more */
}
- s->last_ev = unref_event(s->last_ev);
- }
- }
- ast_mutex_unlock(&s->__lock);
+ s->session->last_ev = unref_event(s->session->last_ev);
+ }
+ }
+ ast_mutex_unlock(&s->session->__lock);
return ret;
}
@@ -2924,26 +2971,26 @@
ast_debug(1, "Manager received command '%s'\n", action);
if (ast_strlen_zero(action)) {
- ast_mutex_lock(&s->__lock);
+ ast_mutex_lock(&s->session->__lock);
astman_send_error(s, m, "Missing action in request");
- ast_mutex_unlock(&s->__lock);
+ ast_mutex_unlock(&s->session->__lock);
return 0;
}
- if (!s->authenticated && strcasecmp(action, "Login") && strcasecmp(action, "Logoff") && strcasecmp(action, "Challenge")) {
- ast_mutex_lock(&s->__lock);
+ if (!s->session->authenticated && strcasecmp(action, "Login") && strcasecmp(action, "Logoff") && strcasecmp(action, "Challenge")) {
+ ast_mutex_lock(&s->session->__lock);
astman_send_error(s, m, "Permission denied");
- ast_mutex_unlock(&s->__lock);
+ ast_mutex_unlock(&s->session->__lock);
return 0;
}
- if (!allowmultiplelogin && !s->authenticated && user &&
+ if (!allowmultiplelogin && !s->session->authenticated && user &&
(!strcasecmp(action, "Login") || !strcasecmp(action, "Challenge"))) {
if (check_manager_session_inuse(user)) {
sleep(1);
- ast_mutex_lock(&s->__lock);
+ ast_mutex_lock(&s->session->__lock);
astman_send_error(s, m, "Login Already In Use");
- ast_mutex_unlock(&s->__lock);
+ ast_mutex_unlock(&s->session->__lock);
return -1;
}
}
@@ -2952,7 +2999,7 @@
AST_RWLIST_TRAVERSE(&actions, tmp, list) {
if (strcasecmp(action, tmp->action))
continue;
- if (s->writeperm & tmp->authority || tmp->authority == 0)
+ if (s->session->writeperm & tmp->authority || tmp->authority == 0)
ret = tmp->func(s, m);
else
astman_send_error(s, m, "Permission denied");
@@ -2963,9 +3010,9 @@
if (!tmp) {
char buf[512];
snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action);
- ast_mutex_lock(&s->__lock);
+ ast_mutex_lock(&s->session->__lock);
astman_send_error(s, m, buf);
- ast_mutex_unlock(&s->__lock);
+ ast_mutex_unlock(&s->session->__lock);
}
if (ret)
return ret;
@@ -2991,16 +3038,16 @@
static int get_input(struct mansession *s, char *output)
{
int res, x;
- int maxlen = sizeof(s->inbuf) - 1;
- char *src = s->inbuf;
+ int maxlen = sizeof(s->session->inbuf) - 1;
+ char *src = s->session->inbuf;
/*
* Look for \r\n within the buffer. If found, copy to the output
* buffer and return, trimming the \r\n (not used afterwards).
*/
- for (x = 0; x < s->inlen; x++) {
+ for (x = 0; x < s->session->inlen; x++) {
int cr; /* set if we have \r */
- if (src[x] == '\r' && x+1 < s->inlen && src[x+1] == '\n')
+ if (src[x] == '\r' && x+1 < s->session->inlen && src[x+1] == '\n')
cr = 2; /* Found. Update length to include \r\n */
else if (src[x] == '\n')
cr = 1; /* also accept \n only */
@@ -3009,32 +3056,32 @@
memmove(output, src, x); /*... but trim \r\n */
output[x] = '\0'; /* terminate the string */
x += cr; /* number of bytes used */
- s->inlen -= x; /* remaining size */
- memmove(src, src + x, s->inlen); /* remove used bytes */
+ s->session->inlen -= x; /* remaining size */
[... 673 lines stripped ...]
More information about the asterisk-commits
mailing list