[asterisk-commits] twilson: branch group/issue_17255-1.6.2 r315441 - in /team/group/issue_17255-...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Apr 26 10:40:55 CDT 2011
Author: twilson
Date: Tue Apr 26 10:40:50 2011
New Revision: 315441
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=315441
Log:
Import rgagnon's initial changes
Modified:
team/group/issue_17255-1.6.2/channels/chan_sip.c
team/group/issue_17255-1.6.2/include/asterisk/rtp.h
team/group/issue_17255-1.6.2/include/asterisk/sched.h
team/group/issue_17255-1.6.2/main/rtp.c
team/group/issue_17255-1.6.2/main/sched.c
Modified: team/group/issue_17255-1.6.2/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/issue_17255-1.6.2/channels/chan_sip.c?view=diff&rev=315441&r1=315440&r2=315441
==============================================================================
--- team/group/issue_17255-1.6.2/channels/chan_sip.c (original)
+++ team/group/issue_17255-1.6.2/channels/chan_sip.c Tue Apr 26 10:40:50 2011
@@ -2399,6 +2399,7 @@
static void ast_quiet_chan(struct ast_channel *chan);
static int attempt_transfer(struct sip_dual *transferer, struct sip_dual *target);
static int do_magic_pickup(struct ast_channel *channel, const char *extension, const char *context);
+static int scheduler_process_request_queue(const void *data);
/*!
* \brief generic function for determining if a correct transport is being
@@ -2645,6 +2646,7 @@
static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan);
static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl);
static void change_t38_state(struct sip_pvt *p, int state);
+static int sip_t38_abort(const void *data);
/*------ Session-Timers functions --------- */
static void proc_422_rsp(struct sip_pvt *p, struct sip_request *rsp);
@@ -3268,6 +3270,25 @@
}
}
+#ifdef REF_DEBUG
+#define ref_peer(arg1,arg2) _ref_peer((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define unref_peer(arg1,arg2) _unref_peer((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+static struct sip_peer *_ref_peer(struct sip_peer *peer, char *tag, char *file, int line, const char *func)
+{
+ if (peer)
+ _ao2_ref_debug(peer, 1, tag, file, line, func);
+ else
+ ast_log(LOG_ERROR, "Attempt to Ref a null peer pointer\n");
+ return peer;
+}
+
+static struct sip_peer *_unref_peer(struct sip_peer *peer, char *tag, char *file, int line, const char *func)
+{
+ if (peer)
+ _ao2_ref_debug(peer, -1, tag, file, line, func);
+ return NULL;
+}
+#else
/*!
* helper functions to unreference various types of objects.
* By handling them this way, we don't have to declare the
@@ -3275,15 +3296,16 @@
*/
static void *unref_peer(struct sip_peer *peer, char *tag)
{
- ao2_t_ref(peer, -1, tag);
+ ao2_ref(peer, -1);
return NULL;
}
static struct sip_peer *ref_peer(struct sip_peer *peer, char *tag)
{
- ao2_t_ref(peer, 1, tag);
+ ao2_ref(peer, 1);
return peer;
}
+#endif
/*! \brief maintain proper refcounts for a sip_pvt's outboundproxy
*
@@ -3322,6 +3344,11 @@
{
struct sip_pkt *cp;
+ if (!dialog) {
+ ast_log(LOG_ERROR, "Attempt unlink a null dialog\n");
+ return NULL;
+ }
+
dialog_ref(dialog, "Let's bump the count in the unlink so it doesn't accidentally become dead before we are done");
ao2_t_unlink(dialogs, dialog, "unlinking dialog via ao2_unlink");
@@ -3337,8 +3364,8 @@
}
if (dialog->registry) {
if (dialog->registry->call == dialog)
- dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all");
- dialog->registry = registry_unref(dialog->registry, "delete dialog->registry");
+ dialog->registry->call = dialog_unref(dialog->registry->call, "unref registry->call from dialog");
+ dialog->registry = registry_unref(dialog->registry, "unref dialog->registry from registry");
}
if (dialog->stateid > -1) {
ast_extension_state_del(dialog->stateid, NULL);
@@ -3378,6 +3405,8 @@
if (dialog->t38id > -1) {
AST_SCHED_DEL_UNREF(sched, dialog->t38id, dialog_unref(dialog, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
}
+
+ stop_session_timer(dialog);
dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time");
return NULL;
@@ -4176,15 +4205,13 @@
} else {
append_history(p, "AutoDestroy", "%s", p->callid);
ast_debug(3, "Auto destroying SIP dialog '%s'\n", p->callid);
- dialog_unlink_all(p, TRUE, TRUE); /* once it's unlinked and unrefd everywhere, it'll be freed automagically */
- /* dialog_unref(p, "unref dialog-- no other matching conditions"); -- unlink all now should finish off the dialog's references and free it. */
- /* sip_destroy(p); */ /* Go ahead and destroy dialog. All attempts to recover is done */
- /* sip_destroy also absorbs the reference */
+ dialog_unlink_all(p, TRUE, TRUE);
+ dialog_unref(p, "destroy dialog when ref removed for autokillid");
}
sip_pvt_unlock(p);
- dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it.");
+ dialog_unref(p, "remove ref for autokillid");
return 0;
}
@@ -4218,17 +4245,11 @@
*/
static int sip_cancel_destroy(struct sip_pvt *p)
{
- int res = 0;
if (p->autokillid > -1) {
- int res3;
-
- if (!(res3 = ast_sched_del(sched, p->autokillid))) {
- append_history(p, "CancelDestroy", "");
- p->autokillid = -1;
- dialog_unref(p, "dialog unrefd because autokillid is de-sched'd");
- }
- }
- return res;
+ append_history(p, "CancelDestroy", "");
+ AST_SCHED_DEL_UNREF(sched, p->autokillid, dialog_unref(p, "remove ref for autokillid"));
+ }
+ return 0;
}
/*! \brief Acknowledges receipt of a packet and stops retransmission
@@ -4861,8 +4882,8 @@
/* Delete it, it needs to disappear */
if (peer->call) {
- dialog_unlink_all(peer->call, TRUE, TRUE);
- peer->call = dialog_unref(peer->call, "peer->call is being unset");
+ dialog_unref(peer->call, "peer->call is being unset");
+ peer->call = dialog_unlink_all(peer->call, TRUE, TRUE);
}
@@ -5685,8 +5706,7 @@
reg->call->registry = registry_unref(reg->call->registry, "destroy reg->call->registry");
ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
dialog_unlink_all(reg->call, TRUE, TRUE);
- reg->call = dialog_unref(reg->call, "unref reg->call");
- /* reg->call = sip_destroy(reg->call); */
+ reg->call = dialog_unref(reg->call, "destroy dialog");
}
AST_SCHED_DEL(sched, reg->expire);
AST_SCHED_DEL(sched, reg->timeout);
@@ -5716,7 +5736,10 @@
{
struct sip_request *req;
+ /* Destroy Session-Timers if allocated */
if (p->stimer) {
+ p->stimer->quit_flag = 1;
+ stop_session_timer(p);
ast_free(p->stimer);
p->stimer = NULL;
}
@@ -5793,17 +5816,6 @@
p->route = NULL;
}
deinit_req(&p->initreq);
-
- /* Destroy Session-Timers if allocated */
- if (p->stimer) {
- p->stimer->quit_flag = 1;
- if (p->stimer->st_active == TRUE && p->stimer->st_schedid > -1) {
- AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
- dialog_unref(p, "removing session timer ref"));
- }
- ast_free(p->stimer);
- p->stimer = NULL;
- }
/* Clear history */
if (p->history) {
@@ -6700,7 +6712,7 @@
struct ast_control_t38_parameters parameters = p->t38.their_parms;
if (p->t38.state == T38_PEER_REINVITE) {
- AST_SCHED_DEL(sched, p->t38id);
+ AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters));
@@ -7403,8 +7415,7 @@
return NULL;
if (ast_string_field_init(p, 512)) {
- ao2_t_ref(p, -1, "failed to string_field_init, drop p");
- return NULL;
+ return dialog_unref(p, "failed to string_field_init, drop p");
}
if (req) {
@@ -7458,13 +7469,6 @@
p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
if (ast_test_flag(&p->flags[1], SIP_PAGE2_TEXTSUPPORT))
p->trtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
- if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) {
- if (!(p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr))) {
- /* udptl creation failed, T38 can not be supported on this dialog */
- ast_log(LOG_ERROR, "UDPTL creation failed\n");
- ast_clear_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT);
- }
- }
if (!p->rtp|| (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)
|| (ast_test_flag(&p->flags[1], SIP_PAGE2_TEXTSUPPORT) && !p->trtp)) {
ast_log(LOG_WARNING, "Unable to create RTP audio %s%ssession: %s\n",
@@ -7474,8 +7478,8 @@
ast_variables_destroy(p->chanvars);
p->chanvars = NULL;
}
- ao2_t_ref(p, -1, "failed to create RTP audio session, drop p");
- return NULL;
+ return dialog_unref(p, "failed to create RTP audio session, drop p");
+ /* Why is this next line still here? */
p->t38_maxdatagram = global_t38_maxdatagram;
}
ast_rtp_setqos(p->rtp, global_tos_audio, global_cos_audio, "SIP RTP");
@@ -7766,7 +7770,7 @@
/*! \brief find or create a dialog structure for an incoming SIP message.
* Connect incoming SIP message to current dialog or create new dialog structure
* Returns a reference to the sip_pvt object, remember to give it back once done.
- * Called by handle_incoming(), sipsock_read
+ * Called by handle_request_do()
*/
static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *sin, const int intended_method)
{
@@ -7860,13 +7864,14 @@
if ((p = sip_alloc(callid, sin, 1, intended_method, req))) {
/* Ok, we've created a dialog, let's go and process it */
sip_pvt_lock(p);
+ dialog_ref(p, "add ref in find_call()");
} else {
/* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
getting a dialog from sip_alloc.
-
+
Without a dialog we can't retransmit and handle ACKs and all that, but at least
send an error message.
-
+
Sorry, we apologize for the inconvienience
*/
transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error");
@@ -10056,7 +10061,6 @@
char se_hdr[256];
snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval,
strefresher2str(p->stimer->st_ref));
- add_header(req, "Require", "timer");
add_header(req, "Session-Expires", se_hdr);
snprintf(se_hdr, sizeof(se_hdr), "%d", st_get_se(p, FALSE));
add_header(req, "Min-SE", se_hdr);
@@ -11486,21 +11490,21 @@
if (!mwi->us.sin_port && mwi->portno) {
mwi->us.sin_port = htons(mwi->portno);
}
-
+
/* Setup the destination of our subscription */
if (create_addr(mwi->call, mwi->hostname, &mwi->us, 0)) {
dialog_unlink_all(mwi->call, TRUE, TRUE);
mwi->call = dialog_unref(mwi->call, "unref dialog after unlink_all");
return 0;
}
-
+
if (!mwi->dnsmgr && mwi->portno) {
mwi->call->sa.sin_port = htons(mwi->portno);
mwi->call->recv.sin_port = htons(mwi->portno);
} else {
mwi->portno = ntohs(mwi->call->sa.sin_port);
}
-
+
/* Set various other information */
if (!ast_strlen_zero(mwi->authuser)) {
ast_string_field_set(mwi->call, peername, mwi->authuser);
@@ -11522,10 +11526,10 @@
build_via(mwi->call);
build_callid_pvt(mwi->call);
ast_set_flag(&mwi->call->flags[0], SIP_OUTGOING);
-
+
/* Associate the call with us */
mwi->call->mwi = ASTOBJ_REF(mwi);
-
+
/* Actually send the packet */
transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 2);
@@ -11896,8 +11900,7 @@
if (create_addr(p, channame, NULL, 0)) {
/* Maybe they're not registered, etc. */
dialog_unlink_all(p, TRUE, TRUE);
- dialog_unref(p, "unref dialog inside for loop" );
- /* sip_destroy(p); */
+ dialog_unref(p, "destroy dialog");
astman_send_error(s, m, "Could not create address");
return 0;
}
@@ -12088,7 +12091,7 @@
ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
return 0;
} else {
- p = dialog_ref(r->call, "getting a copy of the r->call dialog in transmit_register");
+ p = dialog_ref(r->call, "add ref for transmit_register()");
make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */
ast_string_field_set(p, theirtag, NULL); /* forget their old tag, so we don't match tags when getting response */
}
@@ -12116,7 +12119,7 @@
/* we have what we hope is a temporary network error,
* probably DNS. We need to reschedule a registration try */
dialog_unlink_all(p, TRUE, TRUE);
- p = dialog_unref(p, "unref dialog after unlink_all");
+ p = dialog_unref(p, "destroy dialog");
if (r->timeout > -1) {
AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r,
registry_unref(_data, "del for REPLACE of registry ptr"),
@@ -12131,6 +12134,8 @@
return 0;
}
+ dialog_ref(p, "add ref for transmit_register()");
+
/* Copy back Call-ID in case create_addr changed it */
ast_string_field_set(r, callid, p->callid);
if (!r->dnsmgr && r->portno) {
@@ -12140,8 +12145,8 @@
r->portno = ntohs(p->sa.sin_port);
}
ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
- r->call = dialog_ref(p, "copying dialog into registry r->call"); /* Save pointer to SIP dialog */
- p->registry = registry_addref(r, "transmit_register: addref to p->registry in transmit_register"); /* Add pointer to registry in packet */
+ r->call = dialog_ref(p, "point registry->call to dialog"); /* Save pointer to SIP dialog */
+ p->registry = registry_addref(r, "point dialog->registry to registry"); /* Add pointer to registry in packet */
if (!ast_strlen_zero(r->secret)) { /* Secret (password) */
ast_string_field_set(p, peersecret, r->secret);
}
@@ -12298,7 +12303,7 @@
r->regattempts++; /* Another attempt */
ast_debug(4, "REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
res = send_request(p, &req, XMIT_CRITICAL, p->ocseq);
- dialog_unref(p, "p is finished here at the end of transmit_register");
+ dialog_unref(p, "remove ref for transmit_register()");
return res;
}
@@ -14609,7 +14614,7 @@
}
if (authpeer) {
- ao2_t_ref(peer, 1, "copy pointer into (*authpeer)");
+ ref_peer(peer, "copy pointer into (*authpeer)");
(*authpeer) = peer; /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
}
@@ -15109,7 +15114,7 @@
ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
user_iter = ao2_iterator_init(peers, 0);
- while ((user = ao2_iterator_next(&user_iter))) {
+ while ((user = ao2_t_iterator_next(&user_iter, "iterate thru peers table"))) {
ao2_lock(user);
if (!(user->type & SIP_TYPE_USER)) {
ao2_unlock(user);
@@ -15320,9 +15325,10 @@
peerarray[total_peers++] = peer;
ao2_unlock(peer);
+ unref_peer(peer, "toss iterator peer ptr");
}
ao2_iterator_destroy(&i);
-
+
qsort(peerarray, total_peers, sizeof(struct sip_peer *), peercomparefunc);
for(k=0; k < total_peers; k++) {
@@ -15330,11 +15336,10 @@
char srch[2000];
char pstatus;
peer = peerarray[k];
-
+
ao2_lock(peer);
if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) {
ao2_unlock(peer);
- unref_peer(peer, "toss iterator peer ptr before continue");
continue;
}
@@ -15401,9 +15406,8 @@
realtimepeers ? (peer->is_realtime ? "yes":"no") : "no");
}
ao2_unlock(peer);
- unref_peer(peer, "toss iterator peer ptr");
- }
-
+ }
+
if (!s)
ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n",
total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline);
@@ -15585,10 +15589,9 @@
}
sip_pvt_unlock(dialog);
- /* no, the unlink should handle this: dialog_unref(dialog, "needdestroy: one more refcount decrement to allow dialog to be destroyed"); */
- /* the CMP_MATCH will unlink this dialog from the dialog hash table */
- dialog_unlink_all(dialog, TRUE, FALSE);
- return 0; /* the unlink_all should unlink this from the table, so.... no need to return a match */
+ dialog_unlink_all(dialog, TRUE, TRUE);
+ dialog = dialog_unref(dialog, "destroy dialog");
+ return 0;
}
sip_pvt_unlock(dialog);
@@ -16180,7 +16183,7 @@
struct sip_peer *user;
user_iter = ao2_iterator_init(peers, 0);
- while ((user = ao2_iterator_next(&user_iter))) {
+ while ((user = ao2_t_iterator_next(&user_iter, "iterate thru peers table"))) {
ao2_lock(user);
if (!(user->type & SIP_TYPE_USER)) {
ao2_unlock(user);
@@ -16288,25 +16291,46 @@
static char *sip_show_sched(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
struct ast_str *cbuf;
- struct ast_cb_names cbnames = {9, { "retrans_pkt",
- "__sip_autodestruct",
- "expire_register",
- "auto_congest",
- "sip_reg_timeout",
- "sip_poke_peer_s",
- "sip_poke_noanswer",
- "sip_reregister",
- "sip_reinvite_retry"},
- { retrans_pkt,
- __sip_autodestruct,
- expire_register,
- auto_congest,
- sip_reg_timeout,
- sip_poke_peer_s,
- sip_poke_noanswer,
- sip_reregister,
- sip_reinvite_retry}};
-
+ struct ast_cb_names cbnames = {17,
+ {
+ "__sip_autodestruct",
+ "ast_rtcp_write",
+ "ast_rtp_red_write",
+ "auto_congest",
+ "expire_register",
+ "proc_session_timer",
+ "retrans_pkt",
+ "scheduler_process_request_queue",
+ "send_provisional_keepalive_with_sdp",
+ "send_provisional_keepalive",
+ "sip_poke_noanswer",
+ "sip_poke_peer_s",
+ "sip_reg_timeout",
+ "sip_reinvite_retry",
+ "sip_reregister",
+ "sip_subscribe_mwi_do",
+ "sip_t38_abort"
+ },
+ {
+ __sip_autodestruct,
+ ast_rtcp_write,
+ ast_rtp_red_write,
+ auto_congest,
+ expire_register,
+ proc_session_timer,
+ retrans_pkt,
+ scheduler_process_request_queue,
+ send_provisional_keepalive_with_sdp,
+ send_provisional_keepalive,
+ sip_poke_noanswer,
+ sip_poke_peer_s,
+ sip_reg_timeout,
+ sip_reinvite_retry,
+ sip_reregister,
+ sip_subscribe_mwi_do,
+ sip_t38_abort
+ }};
+
switch (cmd) {
case CLI_INIT:
e->command = "sip show sched";
@@ -17094,7 +17118,7 @@
sip_pvt_unlock(cur);
- ao2_t_ref(cur, -1, "toss dialog ptr set by iterator_next");
+ dialog_unref(cur, "toss dialog ptr set by iterator_next");
}
ao2_iterator_destroy(&i);
@@ -17151,7 +17175,7 @@
found++;
}
sip_pvt_unlock(cur);
- ao2_t_ref(cur, -1, "toss dialog ptr from iterator_next");
+ dialog_unref(cur, "toss dialog ptr from iterator_next");
}
ao2_iterator_destroy(&i);
@@ -17513,8 +17537,7 @@
if (create_addr(p, a->argv[i], NULL, 1)) {
/* Maybe they're not registered, etc. */
dialog_unlink_all(p, TRUE, TRUE);
- dialog_unref(p, "unref dialog inside for loop" );
- /* sip_destroy(p); */
+ p = dialog_unref(p, "destroy dialog");
ast_cli(a->fd, "Could not create address for '%s'\n", a->argv[i]);
continue;
}
@@ -20878,7 +20901,7 @@
if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */
enum ast_channel_state c_state = c->_state;
- if (c_state != AST_STATE_UP && reinvite &&
+ if (c_state != AST_STATE_UP && (c_state != AST_STATE_DOWN) && reinvite &&
(p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) {
/* If these conditions are true, and the channel is still in the 'ringing'
* state, then this likely means that we have a situation where the initial
@@ -20963,6 +20986,10 @@
transmit_response(p, "100 Trying", req);
if (p->t38.state == T38_PEER_REINVITE) {
+ if (p->t38id > -1) {
+ /* reset t38 abort timer */
+ AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "remove ref for t38id"));
+ }
p->t38id = ast_sched_add(sched, 5000, sip_t38_abort, dialog_ref(p, "passing dialog ptr into sched structure based on t38id for sip_t38_abort."));
} else if (p->t38.state == T38_ENABLED) {
ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
@@ -21045,8 +21072,9 @@
ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
transferer->refer->status = REFER_FAILED;
sip_pvt_unlock(targetcall_pvt);
- if (targetcall_pvt)
- ao2_t_ref(targetcall_pvt, -1, "Drop targetcall_pvt pointer");
+ if (targetcall_pvt) {
+ dialog_unref(targetcall_pvt, "Drop targetcall_pvt pointer");
+ }
return -1;
}
@@ -21107,7 +21135,7 @@
}
}
if (targetcall_pvt)
- ao2_t_ref(targetcall_pvt, -1, "drop targetcall_pvt");
+ dialog_unref(targetcall_pvt, "drop targetcall_pvt");
return 1;
}
@@ -21512,6 +21540,10 @@
if (pkt->seqno == p->lastinvite && pkt->response_code == 487) {
AST_SCHED_DEL(sched, pkt->retransid);
UNLINK(pkt, p->packets, prev_pkt);
+ dialog_unref(p, "unref packet->owner from dialog");
+ if (pkt->data) {
+ ast_free(pkt->data);
+ }
ast_free(pkt);
break;
}
@@ -22614,7 +22646,7 @@
ast_mutex_lock(&netlock);
/* Find the active SIP dialog or create a new one */
- p = find_call(req, sin, req->method); /* returns p locked */
+ p = find_call(req, sin, req->method); /* returns p locked, and ref'd */
if (p == NULL) {
ast_debug(1, "Invalid SIP message - rejected , no callid, len %d\n", req->len);
ast_mutex_unlock(&netlock);
@@ -22630,7 +22662,7 @@
if (lockretry != 1) {
sip_pvt_unlock(p);
- ao2_t_ref(p, -1, "release p (from find_call) inside lockretry loop"); /* we'll look for it again, but p is dead now */
+ dialog_unref(p, "release p (from find_call) inside lockretry loop"); /* we'll look for it again, but p is dead now */
ast_mutex_unlock(&netlock);
/* Sleep for a very short amount of time */
usleep(1);
@@ -22650,7 +22682,7 @@
if (!queue_request(p, req)) {
/* the request has been queued for later handling */
sip_pvt_unlock(p);
- ao2_t_ref(p, -1, "release p (from find_call) after queueing request");
+ dialog_unref(p, "release p (from find_call) after queueing request");
ast_mutex_unlock(&netlock);
return 1;
}
@@ -22663,7 +22695,7 @@
/* XXX We could add retry-after to make sure they come back */
append_history(p, "LockFail", "Owner lock failed, transaction failed.");
sip_pvt_unlock(p);
- ao2_t_ref(p, -1, "release p (from find_call) at end of lockretry"); /* p is gone after the return */
+ dialog_unref(p, "release p (from find_call) at end of lockretry"); /* p is gone after the return */
ast_mutex_unlock(&netlock);
return 1;
}
@@ -22687,7 +22719,7 @@
if (p->owner && !nounlock)
ast_channel_unlock(p->owner);
sip_pvt_unlock(p);
- ao2_t_ref(p, -1, "throw away dialog ptr from find_call at end of routine"); /* p is gone after the return */
+ dialog_unref(p, "throw away dialog ptr from find_call at end of routine"); /* p is gone after the return */
ast_mutex_unlock(&netlock);
return 1;
}
@@ -22980,8 +23012,7 @@
if (create_addr_from_peer(p, peer)) {
/* Maybe they're not registered, etc. */
dialog_unlink_all(p, TRUE, TRUE);
- dialog_unref(p, "unref dialog p just created via sip_alloc");
- /* sip_destroy(p); */
+ dialog_unref(p, "destroy dialog");
return 0;
}
/* Recalculate our side, and recalculate Call ID */
@@ -23186,9 +23217,9 @@
}
if (p->stimer->st_active == TRUE) {
+ ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
dialog_unref(p, "Removing session timer ref"));
- ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
start_session_timer(p);
}
}
@@ -23198,15 +23229,16 @@
static void stop_session_timer(struct sip_pvt *p)
{
if (!p->stimer) {
- ast_log(LOG_WARNING, "Null stimer in stop_session_timer - %s\n", p->callid);
return;
}
if (p->stimer->st_active == TRUE) {
p->stimer->st_active = FALSE;
- AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
+ if (p->stimer->st_schedid > -1) {
+ ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
+ AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
dialog_unref(p, "removing session timer ref"));
- ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
+ }
}
}
@@ -23219,13 +23251,22 @@
return;
}
- p->stimer->st_schedid = ast_sched_add(sched, p->stimer->st_interval * 1000 / 2, proc_session_timer,
- dialog_ref(p, "adding session timer ref"));
+ if (p->stimer->st_schedid > -1) {
+ /* in the event a timer is already going, stop it */
+ ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
+ AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
+ dialog_unref(p, "unref stimer->st_schedid from dialog"));
+ }
+
+ p->stimer->st_schedid = ast_sched_add(sched, p->stimer->st_interval * 1000 / 2, proc_session_timer,
+ dialog_ref(p, "adding session timer ref"));
if (p->stimer->st_schedid < 0) {
dialog_unref(p, "removing session timer ref");
- ast_log(LOG_ERROR, "ast_sched_add failed.\n");
- }
- ast_debug(2, "Session timer started: %d - %s\n", p->stimer->st_schedid, p->callid);
+ ast_log(LOG_ERROR, "ast_sched_add failed - %s\n", p->callid);
+ } else {
+ p->stimer->st_active = TRUE;
+ ast_debug(2, "Session timer started: %d - %s in %d ms\n", p->stimer->st_schedid, p->callid, p->stimer->st_interval * 500);
+ }
}
@@ -23297,8 +23338,9 @@
if (!res) {
/* An error occurred. Stop session timer processing */
if (p->stimer) {
+ ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
p->stimer->st_schedid = -1;
- stop_session_timer(p);
+ p->stimer->st_active = FALSE;
}
/* If we are not asking to be rescheduled, then we need to release our
@@ -23513,9 +23555,8 @@
}
if (peer->call) {
- dialog_unlink_all(peer->call, TRUE, TRUE);
- peer->call = dialog_unref(peer->call, "unref dialog peer->call");
- /* peer->call = sip_destroy(peer->call);*/
+ dialog_unref(peer->call, "unref dialog peer->call");
+ peer->call = dialog_unlink_all(peer->call, TRUE, TRUE);
}
/* Don't send a devstate change if nothing changed. */
@@ -23563,9 +23604,8 @@
if (sipdebug) {
ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
}
- dialog_unlink_all(peer->call, TRUE, TRUE);
- peer->call = dialog_unref(peer->call, "unref dialog peer->call");
- /* peer->call = sip_destroy(peer->call); */
+ dialog_unref(peer->call, "unref dialog peer->call");
+ peer->call = dialog_unlink_all(peer->call, TRUE, TRUE);
}
if (!(p = sip_alloc(NULL, NULL, 0, SIP_OPTIONS, NULL))) {
return -1;
@@ -23609,6 +23649,7 @@
#endif
peer->ps = ast_tvnow();
if (xmitres == XMIT_ERROR) {
+ ref_peer(peer, "add ref for peerexpire (fake, for sip_poke_noanswer to remove");
sip_poke_noanswer(peer); /* Immediately unreachable, network problems */
} else if (!force) {
AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, peer->maxms * 2, sip_poke_noanswer, peer,
@@ -23616,7 +23657,6 @@
unref_peer(peer, "removing poke peer ref"),
ref_peer(peer, "adding poke peer ref"));
}
- dialog_unref(p, "unref dialog at end of sip_poke_peer, obtained from sip_alloc, just before it goes out of scope");
return 0;
}
@@ -23778,8 +23818,7 @@
if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
dialog_unlink_all(p, TRUE, TRUE);
- dialog_unref(p, "unref dialog p from mem fail");
- /* sip_destroy(p); */
+ dialog_unref(p, "destroy dialog");
ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
*cause = AST_CAUSE_SWITCH_CONGESTION;
return NULL;
@@ -23848,8 +23887,7 @@
*cause = AST_CAUSE_UNREGISTERED;
ast_debug(3, "Cant create SIP call - target device not registered\n");
dialog_unlink_all(p, TRUE, TRUE);
- dialog_unref(p, "unref dialog p UNREGISTERED");
- /* sip_destroy(p); */
+ dialog_unref(p, "destroy dialog");
return NULL;
}
if (ast_strlen_zero(p->peername) && ext)
@@ -23892,9 +23930,8 @@
sip_pvt_unlock(p);
if (!tmpc) {
dialog_unlink_all(p, TRUE, TRUE);
- /* sip_destroy(p); */
- }
- dialog_unref(p, "toss pvt ptr at end of sip_request_call");
+ dialog_unref(p, "destroy dialog");
+ }
ast_update_use_count();
restart_monitor();
return tmpc;
@@ -24338,7 +24375,7 @@
return NULL;
if (ast_string_field_init(peer, 512)) {
- ao2_t_ref(peer, -1, "failed to string_field_init, drop peer");
+ unref_peer(peer, "failed to string_field_init, drop peer");
return NULL;
}
@@ -24433,7 +24470,7 @@
return NULL;
if (ast_string_field_init(peer, 512)) {
- ao2_t_ref(peer, -1, "failed to string_field_init, drop peer");
+ unref_peer(peer, "failed to string_field_init, drop peer");
return NULL;
}
@@ -26561,6 +26598,7 @@
static int unload_module(void)
{
struct sip_pvt *p;
+ struct sip_peer *peer;
struct sip_threadinfo *th;
struct ast_context *con;
struct ao2_iterator i;
@@ -26619,7 +26657,7 @@
while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
if (p->owner)
ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
- ao2_t_ref(p, -1, "toss dialog ptr from iterator_next");
+ dialog_unref(p, "toss dialog ptr from iterator_next");
}
ao2_iterator_destroy(&i);
@@ -26636,7 +26674,22 @@
i = ao2_iterator_init(dialogs, 0);
while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
dialog_unlink_all(p, TRUE, TRUE);
- ao2_t_ref(p, -1, "throw away iterator result");
+ dialog_unref(p, "throw away iterator result");
+ p = dialog_unref(p, "destroy dialog");
+ }
+ ao2_iterator_destroy(&i);
+
+ /* Destroy all the peers and free their memory */
+ i = ao2_iterator_init(peers, 0);
+ while ((peer = ao2_t_iterator_next(&i, "iterate thru peers"))) {
+ if (peer->pokeexpire > -1) {
+ AST_SCHED_DEL_UNREF(sched, peer->pokeexpire, unref_peer(peer, "remove poke peer ref"));
+ }
+ if (peer->expire > -1) {
+ AST_SCHED_DEL_UNREF(sched, peer->expire, unref_peer(peer, "remove registration ref"));
+ }
+ unlink_peer_from_tables(peer);
+ unref_peer(peer, "throw away iterator result");
}
ao2_iterator_destroy(&i);
Modified: team/group/issue_17255-1.6.2/include/asterisk/rtp.h
URL: http://svnview.digium.com/svn/asterisk/team/group/issue_17255-1.6.2/include/asterisk/rtp.h?view=diff&rev=315441&r1=315440&r2=315441
==============================================================================
--- team/group/issue_17255-1.6.2/include/asterisk/rtp.h (original)
+++ team/group/issue_17255-1.6.2/include/asterisk/rtp.h Tue Apr 26 10:40:50 2011
@@ -202,6 +202,10 @@
struct ast_frame *ast_rtp_read(struct ast_rtp *rtp);
+int ast_rtcp_write(const void *data);
+
+int ast_rtp_red_write(const void *data);
+
struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp);
int ast_rtp_fd(struct ast_rtp *rtp);
Modified: team/group/issue_17255-1.6.2/include/asterisk/sched.h
URL: http://svnview.digium.com/svn/asterisk/team/group/issue_17255-1.6.2/include/asterisk/sched.h?view=diff&rev=315441&r1=315440&r2=315441
==============================================================================
--- team/group/issue_17255-1.6.2/include/asterisk/sched.h (original)
+++ team/group/issue_17255-1.6.2/include/asterisk/sched.h Tue Apr 26 10:40:50 2011
@@ -162,8 +162,8 @@
struct ast_cb_names {
int numassocs;
- char *list[10];
- ast_sched_cb cblist[10];
+ char *list[18];
+ ast_sched_cb cblist[18];
};
/*!
Modified: team/group/issue_17255-1.6.2/main/rtp.c
URL: http://svnview.digium.com/svn/asterisk/team/group/issue_17255-1.6.2/main/rtp.c?view=diff&rev=315441&r1=315440&r2=315441
==============================================================================
--- team/group/issue_17255-1.6.2/main/rtp.c (original)
+++ team/group/issue_17255-1.6.2/main/rtp.c Tue Apr 26 10:40:50 2011
@@ -179,7 +179,6 @@
};
static struct ast_frame *red_t140_to_red(struct rtp_red *red);
-static int red_write(const void *data);
struct rtp_red {
struct ast_frame t140; /*!< Primary data */
@@ -199,7 +198,6 @@
AST_LIST_HEAD_NOLOCK(frame_list, ast_frame);
/* Forward declarations */
-static int ast_rtcp_write(const void *data);
static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw);
static int ast_rtcp_write_sr(const void *data);
static int ast_rtcp_write_rr(const void *data);
@@ -3612,7 +3610,7 @@
/*! \brief Write and RTCP packet to the far end
* \note Decide if we are going to send an SR (with Reception Block) or RR
* RR is sent if we have not sent any rtp packets in the previous interval */
-static int ast_rtcp_write(const void *data)
+int ast_rtcp_write(const void *data)
{
struct ast_rtp *rtp = (struct ast_rtp *)data;
int res;
@@ -4883,7 +4881,7 @@
/*! \brief Write t140 redundacy frame
* \param data primary data to be buffered
*/
-static int red_write(const void *data)
+int ast_rtp_red_write(const void *data)
{
struct ast_rtp *rtp = (struct ast_rtp*) data;
@@ -4966,7 +4964,7 @@
r->t140red_data[x*4] = r->pt[x];
}
r->t140red_data[x*4] = r->pt[x] = red_data_pt[x]; /* primary pt */
- r->schedid = ast_sched_add(rtp->sched, ti, red_write, rtp);
+ r->schedid = ast_sched_add(rtp->sched, ti, ast_rtp_red_write, rtp);
rtp->red = r;
r->t140.datalen = 0;
Modified: team/group/issue_17255-1.6.2/main/sched.c
URL: http://svnview.digium.com/svn/asterisk/team/group/issue_17255-1.6.2/main/sched.c?view=diff&rev=315441&r1=315440&r2=315441
==============================================================================
--- team/group/issue_17255-1.6.2/main/sched.c (original)
+++ team/group/issue_17255-1.6.2/main/sched.c Tue Apr 26 10:40:50 2011
@@ -539,7 +539,7 @@
ast_str_append(buf, 0, " %s : %d\n", cbnames->list[i], countlist[i]);
}
- ast_str_append(buf, 0, " <unknown> : %d\n", countlist[cbnames->numassocs]);
+ ast_str_append(buf, 0, " <unknown> : %d\n", countlist[cbnames->numassocs]);
}
/*! \brief Dump the contents of the scheduler to LOG_DEBUG */
More information about the asterisk-commits
mailing list