diff options
author | rmudgett <rmudgett@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-08-20 16:48:10 +0000 |
---|---|---|
committer | rmudgett <rmudgett@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-08-20 16:48:10 +0000 |
commit | b97106edbf460d54203370576160d47325e49710 (patch) | |
tree | d3954c4e1d3ebe7a3d54ebe017e23c933a15f40b /channels/chan_sip.c | |
parent | f8d0dcac122feafe9ebd0aba502263f829c77667 (diff) |
Merged revisions 283123 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
................
r283123 | rmudgett | 2010-08-20 11:46:22 -0500 (Fri, 20 Aug 2010) | 9 lines
Merged revision 278274 from
https://origsvn.digium.com/svn/asterisk/trunk
..........
r278274 | rmudgett | 2010-07-20 17:38:13 -0500 (Tue, 20 Jul 2010) | 1 line
Reference correct struct member for unlikely event PRI_EVENT_CONFIG_ERR.
..........
................
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.2@283124 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_sip.c')
-rw-r--r-- | channels/chan_sip.c | 111 |
1 files changed, 70 insertions, 41 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index dc8e98713..89cfe8f12 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -3104,6 +3104,32 @@ cleanup: return NULL; } +/* this func is used with ao2_callback to unlink/delete all marked + peers */ +static int peer_is_marked(void *peerobj, void *arg, int flags) +{ + struct sip_peer *peer = peerobj; + return peer->the_mark ? CMP_MATCH : 0; +} + + +/* \brief Unlink all marked peers from ao2 containers */ +static void unlink_marked_peers_from_tables(void) +{ + ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, NULL, + "initiating callback to remove marked peers"); + ao2_t_callback(peers_by_ip, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, NULL, + "initiating callback to remove marked peers"); +} + +/* \brief Unlink single peer from all ao2 containers */ +static void unlink_peer_from_tables(struct sip_peer *peer) +{ + ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table"); + if (peer->addr.sin_addr.s_addr) { + ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); + } +} /*! * helper functions to unreference various types of objects. @@ -8130,10 +8156,10 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action int vportno = -1; /*!< RTP Video port number */ int tportno = -1; /*!< RTP Text port number */ int udptlportno = -1; /*!< UDPTL Image port number */ - struct sockaddr_in sin; /*!< media socket address */ - struct sockaddr_in vsin; /*!< video socket address */ - struct sockaddr_in isin; /*!< image socket address */ - struct sockaddr_in tsin; /*!< text socket address */ + struct sockaddr_in sin = { 0, }; /*!< media socket address */ + struct sockaddr_in vsin = { 0, }; /*!< video socket address */ + struct sockaddr_in isin = { 0, }; /*!< image socket address */ + struct sockaddr_in tsin = { 0, }; /*!< text socket address */ /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ int peercapability = 0, peernoncodeccapability = 0; @@ -8648,7 +8674,10 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action ast_set_write_format(p->owner, p->owner->writeformat); } - if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { + if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) + && (sin.sin_addr.s_addr || vsin.sin_addr.s_addr || + isin.sin_addr.s_addr || tsin.sin_addr.s_addr) + && (!sendonly || sendonly == -1)) { ast_queue_control(p->owner, AST_CONTROL_UNHOLD); /* Activate a re-invite */ ast_queue_frame(p->owner, &ast_null_frame); @@ -8664,7 +8693,9 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action if (sip_cfg.notifyhold) sip_peer_hold(p, FALSE); ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ - } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { + } else if (!(sin.sin_addr.s_addr || vsin.sin_addr.s_addr || + isin.sin_addr.s_addr || tsin.sin_addr.s_addr) + || (sendonly && sendonly != -1)) { int already_on_hold = ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); ast_queue_control_data(p->owner, AST_CONTROL_HOLD, S_OR(p->mohsuggest, NULL), @@ -11315,27 +11346,30 @@ static int transmit_state_notify(struct sip_pvt *p, int state, int full, int tim int need = strlen(caller->cid.cid_num) + strlen(p->fromdomain) + sizeof("sip:@"); local_target = alloca(need); snprintf(local_target, need, "sip:%s@%s", caller->cid.cid_num, p->fromdomain); - local_display = ast_strdupa(caller->cid.cid_name); + if (!(ast_strlen_zero(caller->cid.cid_name))) { + local_display = ast_strdupa(caller->cid.cid_name); + } ast_channel_unlock(caller); caller = NULL; } + /* We create a fake call-id which the phone will send back in an INVITE + * Replaces header which we can grab and do some magic with. */ + ast_str_append(&tmp, 0, + "<dialog id=\"%s\" call-id=\"pickup-%s\" direction=\"recipient\">\n" + "<remote>\n" + /* See the limitations of this above. Luckily the phone seems to still be + happy when these values are not correct. */ + "<identity display=\"%s\">%s</identity>\n" + "<target uri=\"%s\"/>\n" + "</remote>\n" + "<local>\n" + "<identity>%s</identity>\n" + "<target uri=\"%s\"/>\n" + "</local>\n", + p->exten, p->callid, local_display, local_target, local_target, mto, mto); + } else { + ast_str_append(&tmp, 0, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); } - - /* We create a fake call-id which the phone will send back in an INVITE - Replaces header which we can grab and do some magic with. */ - ast_str_append(&tmp, 0, - "<dialog id=\"%s\" call-id=\"pickup-%s\" direction=\"recipient\">\n" - "<remote>\n" - /* See the limitations of this above. Luckily the phone seems to still be - happy when these values are not correct. */ - "<identity display=\"%s\">%s</identity>\n" - "<target uri=\"%s\"/>\n" - "</remote>\n" - "<local>\n" - "<identity>%s</identity>\n" - "<target uri=\"%s\"/>\n" - "</local>\n", - p->exten, p->callid, local_display, local_target, local_target, mto, mto); } else { ast_str_append(&tmp, 0, "<dialog id=\"%s\">\n", p->exten); } @@ -12114,7 +12148,6 @@ static int expire_register(const void *data) peer->expire = -1; peer->portinuri = 0; - memset(&peer->addr, 0, sizeof(peer->addr)); destroy_association(peer); /* remove registration data from storage */ set_socket_transport(&peer->socket, peer->default_outbound_transport); @@ -12136,12 +12169,13 @@ static int expire_register(const void *data) if (peer->selfdestruct || ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { - ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table"); - if (peer->addr.sin_addr.s_addr) { - ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); - } + unlink_peer_from_tables(peer); } + /* Only clear the addr after we check for destruction. The addr must remain + * in order to unlink from the peers_by_ip container correctly */ + memset(&peer->addr, 0, sizeof(peer->addr)); + unref_peer(peer, "removing peer ref for expire_register"); return 0; @@ -15131,14 +15165,6 @@ static int dialog_needdestroy(void *dialogobj, void *arg, int flags) return 0; } -/* this func is used with ao2_callback to unlink/delete all marked - peers */ -static int peer_is_marked(void *peerobj, void *arg, int flags) -{ - struct sip_peer *peer = peerobj; - return peer->the_mark ? CMP_MATCH : 0; -} - /*! \brief Remove temporary realtime objects from memory (CLI) */ /*! \todo XXXX Propably needs an overhaul after removal of the devices */ static char *sip_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) @@ -15241,8 +15267,7 @@ static char *sip_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli } ao2_iterator_destroy(&i); if (pruned) { - ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, NULL, - "initiating callback to remove marked peers"); + unlink_marked_peers_from_tables(); ast_cli(a->fd, "%d peers pruned.\n", pruned); } else ast_cli(a->fd, "No peers found to prune.\n"); @@ -23772,6 +23797,8 @@ static void set_peer_defaults(struct sip_peer *peer) peer->timer_t1 = global_t1; peer->timer_b = global_timer_b; clear_peer_mailboxes(peer); + peer->transports = default_transports; + peer->default_outbound_transport = default_primary_transport; } /*! \brief Create temporary peer (used in autocreatepeer mode) */ @@ -23914,6 +23941,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str /* If we have realm authentication information, remove them (reload) */ clear_realm_authentication(peer->auth); peer->auth = NULL; + /* clear the transport information. We will detect if a default value is required after parsing the config */ peer->default_outbound_transport = 0; peer->transports = 0; @@ -25145,6 +25173,8 @@ static int reload_config(enum channelreloadreason reason) ast_netsock_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP"); } } + } else { + ast_netsock_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP"); } if (stunaddr.sin_addr.s_addr != 0) { ast_debug(1, "stun to %s:%d\n", @@ -25803,9 +25833,8 @@ static int sip_do_reload(enum channelreloadreason reason) start_poke = time(0); /* Prune peers who still are supposed to be deleted */ - ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, NULL, - "callback to remove marked peers"); - + unlink_marked_peers_from_tables(); + ast_debug(4, "--------------- Done destroying pruned peers\n"); /* Send qualify (OPTIONS) to all peers */ |