[asterisk-commits] russell: branch 1.6.1 r180263 - in /branches/1.6.1: ./ channels/chan_sip.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Mar 4 15:09:17 CST 2009
Author: russell
Date: Wed Mar 4 15:09:13 2009
New Revision: 180263
URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=180263
Log:
Merged revisions 180261 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk
........
r180261 | russell | 2009-03-04 15:01:05 -0600 (Wed, 04 Mar 2009) | 54 lines
Resolve object matching issues related to the removal of the sip_user object.
Previously, chan_sip had both sip_peer and sip_user objects in memory. A
patch went in to remove sip_user to simplify the code, since everything
could be done with just sip_peer. This patch resolves some regressions
found that were introduced by those changes.
This code comes from svn/asterisk/team/group/sip-object-matching/.
Here is a list of the changes that have been made:
1) When doing a match by name with the find_peer() function, make it much
easier to specify which objects should be matched by having a parameter
that specifies exactly which object types should be considered. Also,
update find_by_name() to handle this parameter. Finally, update all
code to use the new option values.
2) When looking up an object for an outbound request by name, consider
peers only. (create_addr())
3) Only match peers on an incoming registration request.
4) When doing authentication (except for SUBSCRIBE), look up users
by name, instead of all objects by name.
5) When doing authentication (except for SUBSCRIBE), after looking for
a user by name, look for a peer by IP address, instead of all objects
by IP address.
6) When handling the SIP qualify CLI command or manager action, look for
a peer by name, instead of any object by name.
7) When handling the SIP unregister CLI command, look for a peer by name,
instead of any object by name.
9) In sip_do_debug_peer(), search for a peer by name, instead of any object
by name.
9) When handling the SIPPEER() dialplan function, search for a peer by name,
instead of any object by name.
10) In the following session timer related functions, st_get_se(),
st_get_refresher(), and st_get_mode(), when looking for an object for a
given sip_pvt using pvt->peername, look for a peer by name, instead of any
object by name.
11) Fix build_peer() to properly handle the case where separate type=peer and
type=user entries were specified in sip.conf.
(closes issue #14505)
Reported by: lmadsen
Review: http://reviewboard.digium.com/r/172/
........
Modified:
branches/1.6.1/ (props changed)
branches/1.6.1/channels/chan_sip.c
Propchange: branches/1.6.1/
------------------------------------------------------------------------------
Binary property 'trunk-merged' - no diff available.
Modified: branches/1.6.1/channels/chan_sip.c
URL: http://svn.digium.com/svn-view/asterisk/branches/1.6.1/channels/chan_sip.c?view=diff&rev=180263&r1=180262&r2=180263
==============================================================================
--- branches/1.6.1/channels/chan_sip.c (original)
+++ branches/1.6.1/channels/chan_sip.c Wed Mar 4 15:09:13 2009
@@ -210,8 +210,9 @@
#define SIPBUFSIZE 512
/* Arguments for find_peer */
-#define FINDALLDEVICES FALSE
-#define FINDONLYUSERS TRUE
+#define FINDUSERS (1 << 0)
+#define FINDPEERS (1 << 1)
+#define FINDALLDEVICES (FINDUSERS | FINDPEERS)
#define XMIT_ERROR -2
@@ -1548,7 +1549,6 @@
char rt_fromcontact; /*!< P: copy fromcontact from realtime */
char host_dynamic; /*!< P: Dynamic Peers register with Asterisk */
char selfdestruct; /*!< P: Automatic peers need to destruct themselves */
- char onlymatchonip; /*!< P: Only match on IP for incoming calls (old type=peer) */
char the_mark; /*!< moved out of ASTOBJ into struct proper; That which bears the_mark should be deleted! */
int expire; /*!< When to expire this peer registration */
@@ -2096,14 +2096,14 @@
/*--- Device object handling */
static struct sip_peer *temp_peer(const char *name);
-static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int ispeer);
+static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime);
static int update_call_counter(struct sip_pvt *fup, int event);
static void sip_destroy_peer(struct sip_peer *peer);
static void sip_destroy_peer_fn(void *peer);
static void set_peer_defaults(struct sip_peer *peer);
static struct sip_peer *temp_peer(const char *name);
static void register_peer_exten(struct sip_peer *peer, int onoff);
-static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime, int forcenamematch, int devstate_only);
+static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime, int which_objects, int devstate_only);
static int sip_poke_peer_s(const void *data);
static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req);
static void reg_source_db(struct sip_peer *peer);
@@ -4080,7 +4080,7 @@
/* Peer found in realtime, now build it in memory */
- peer = build_peer(newpeername, var, varregs, TRUE, FALSE);
+ peer = build_peer(newpeername, var, varregs, TRUE);
if (!peer) {
if(peerlist)
ast_config_destroy(peerlist);
@@ -4125,7 +4125,7 @@
*/
struct peer_finding_info {
struct sip_peer tmp_peer;
- int forcenamematch;
+ int which_objects;
};
/* Function to assist finding peers by name only */
@@ -4139,28 +4139,45 @@
return 0;
}
- /* If we're only looking for name matches, we should avoid type=peer devices,
- since these should not match on any name-based search */
- if (pfi->forcenamematch && search->onlymatchonip) {
- return 0;
+ switch (pfi->which_objects) {
+ case FINDUSERS:
+ if (!(search->type & SIP_TYPE_USER)) {
+ return 0;
+ }
+ break;
+ case FINDPEERS:
+ if (!(search->type & SIP_TYPE_PEER)) {
+ return 0;
+ }
+ break;
+ case FINDALLDEVICES:
+ break;
}
return CMP_MATCH | CMP_STOP;
}
-/*! \brief Locate device by name or ip address
+/*!
+ * \brief Locate device by name or ip address
+ *
+ * \param which_objects Define which objects should be matched when doing a lookup
+ * by name. Valid options are FINDUSERS, FINDPEERS, or FINDALLDEVICES.
+ * Note that this option is not used at all when doing a lookup by IP.
+ *
* This is used on find matching device on name or ip/port.
- If the device was declared as type=peer, we don't match on peer name on incoming INVITEs.
-
- \note Avoid using this function in new functions if there is a way to avoid it, i
- since it might cause a database lookup.
-*/
-static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime, int forcenamematch, int devstate_only)
+ * If the device was declared as type=peer, we don't match on peer name on incoming INVITEs.
+ *
+ * \note Avoid using this function in new functions if there is a way to avoid it,
+ * since it might cause a database lookup.
+ */
+static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime, int which_objects, int devstate_only)
{
struct sip_peer *p = NULL;
if (peer) {
- struct peer_finding_info pfi = { .forcenamematch = forcenamematch, };
+ struct peer_finding_info pfi = {
+ .which_objects = which_objects,
+ };
ast_copy_string(pfi.tmp_peer.name, peer, sizeof(pfi.tmp_peer.name));
p = ao2_t_callback(peers, OBJ_POINTER, find_by_name, &pfi, "ao2_callback in peers table");
} else if (sin) { /* search by addr? */
@@ -4432,7 +4449,7 @@
dialog->sa.sin_family = AF_INET;
dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
- peer = find_peer(peername, NULL, TRUE, FINDALLDEVICES, FALSE);
+ peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE);
if (peer) {
int res;
@@ -11200,7 +11217,7 @@
ast_string_field_set(p, exten, name);
build_contact(p);
- peer = find_peer(name, NULL, TRUE, FINDALLDEVICES, FALSE);
+ peer = find_peer(name, NULL, TRUE, FINDPEERS, FALSE);
if (!(peer && ast_apply_ha(peer->ha, sin))) {
/* Peer fails ACL check */
if (peer) {
@@ -12086,11 +12103,11 @@
peer = find_peer(of, NULL, TRUE, FINDALLDEVICES, FALSE);
} else {
/* First find devices based on username (avoid all type=peer's) */
- peer = find_peer(of, NULL, TRUE, FINDONLYUSERS, FALSE);
+ peer = find_peer(of, NULL, TRUE, FINDUSERS, FALSE);
/* Then find devices based on IP */
if (!peer) {
- peer = find_peer(NULL, &p->recv, TRUE, FINDALLDEVICES, FALSE);
+ peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE);
}
}
@@ -13420,7 +13437,7 @@
return CLI_SHOWUSAGE;
load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
- if ((peer = find_peer(argv[3], NULL, load_realtime, FINDALLDEVICES, FALSE))) {
+ if ((peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE))) {
sip_poke_peer(peer, 1);
unref_peer(peer, "qualify: done with peer");
} else if (type == 0) {
@@ -13502,7 +13519,8 @@
return CLI_SHOWUSAGE;
load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
- peer = find_peer(argv[3], NULL, load_realtime, FINDALLDEVICES, FALSE);
+ peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE);
+
if (s) { /* Manager */
if (peer) {
const char *id = astman_get_header(m, "ActionID");
@@ -13780,7 +13798,7 @@
/* Load from realtime storage? */
load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? TRUE : FALSE;
- if ((user = find_peer(a->argv[3], NULL, load_realtime, TRUE, FALSE))) {
+ if ((user = find_peer(a->argv[3], NULL, load_realtime, FINDUSERS, FALSE))) {
ao2_lock(user);
ast_cli(a->fd, "\n\n");
ast_cli(a->fd, " * Name : %s\n", user->name);
@@ -13938,7 +13956,7 @@
if (a->argc != 3)
return CLI_SHOWUSAGE;
- if ((peer = find_peer(a->argv[2], NULL, load_realtime, FINDALLDEVICES, TRUE))) {
+ if ((peer = find_peer(a->argv[2], NULL, load_realtime, FINDPEERS, TRUE))) {
if (peer->expire > 0) {
expire_register(ref_peer(peer, "ref for expire_register"));
ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]);
@@ -14910,7 +14928,7 @@
/*! \brief Turn on SIP debugging for a given peer */
static char *sip_do_debug_peer(int fd, char *arg)
{
- struct sip_peer *peer = find_peer(arg, NULL, TRUE, FINDALLDEVICES, FALSE);
+ struct sip_peer *peer = find_peer(arg, NULL, TRUE, FINDPEERS, FALSE);
if (!peer)
ast_cli(fd, "No such peer '%s'\n", arg);
else if (peer->addr.sin_addr.s_addr == 0)
@@ -15406,7 +15424,7 @@
else
colname = "ip";
- if (!(peer = find_peer(data, NULL, TRUE, FINDALLDEVICES, FALSE)))
+ if (!(peer = find_peer(data, NULL, TRUE, FINDPEERS, FALSE)))
return -1;
if (!strcasecmp(colname, "ip")) {
@@ -20617,7 +20635,7 @@
if (p->stimer->st_cached_max_se) {
return p->stimer->st_cached_max_se;
} else if (p->peername) {
- struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDALLDEVICES, FALSE);
+ struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDPEERS, FALSE);
if (pp) {
p->stimer->st_cached_max_se = pp->stimer.st_max_se;
unref_peer(pp, "unref peer pointer from find_peer call in st_get_se");
@@ -20630,7 +20648,7 @@
if (p->stimer->st_cached_min_se) {
return p->stimer->st_cached_min_se;
} else if (p->peername) {
- struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDALLDEVICES, FALSE);
+ struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDPEERS, FALSE);
if (pp) {
p->stimer->st_cached_min_se = pp->stimer.st_min_se;
unref_peer(pp, "unref peer pointer from find_peer call in st_get_se (2)");
@@ -20652,7 +20670,7 @@
return p->stimer->st_cached_ref;
if (p->peername) {
- struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDALLDEVICES, FALSE);
+ struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDPEERS, FALSE);
if (pp) {
p->stimer->st_cached_ref = pp->stimer.st_ref;
unref_peer(pp, "unref peer pointer from find_peer call in st_get_refresher");
@@ -20677,7 +20695,7 @@
return p->stimer->st_cached_mode;
if (p->peername) {
- struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDALLDEVICES, FALSE);
+ struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDPEERS, FALSE);
if (pp) {
p->stimer->st_cached_mode = pp->stimer.st_mode_oper;
unref_peer(pp, "unref peer pointer from find_peer call in st_get_mode");
@@ -21507,7 +21525,7 @@
}
/*! \brief Build peer from configuration (file or realtime static/dynamic) */
-static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int ispeer)
+static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
{
struct sip_peer *peer = NULL;
struct ast_ha *oldha = NULL;
@@ -21522,7 +21540,7 @@
const char *srvlookup = NULL;
static int deprecation_warning = 1;
struct ast_str *fullcontact = ast_str_alloca(512);
-
+
if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
/* Note we do NOT use find_peer here, to avoid realtime recursion */
/* We also use a case-sensitive comparison (unlike find_peer) so
@@ -21532,13 +21550,13 @@
ast_copy_string(tmp_peer.name, name, sizeof(tmp_peer.name));
peer = ao2_t_find(peers, &tmp_peer, OBJ_POINTER | OBJ_UNLINK, "find and unlink peer from peers table");
}
-
+
if (peer) {
/* Already in the list, remove it and it will be added back (or FREE'd) */
found++;
if (!(peer->the_mark))
firstpass = 0;
- } else {
+ } else {
if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct")))
return NULL;
@@ -21548,8 +21566,6 @@
} else
ast_atomic_fetchadd_int(&speerobjs, 1);
}
-
- peer->onlymatchonip = ispeer; /* If type=peer, don't match on caller ID for incoming calls */
/* Note that our peer HAS had its reference count increased */
if (firstpass) {
@@ -21557,9 +21573,10 @@
oldha = peer->ha;
peer->ha = NULL;
set_peer_defaults(peer); /* Set peer defaults */
+ peer->type = 0;
}
if (!found && name)
- ast_copy_string(peer->name, name, sizeof(peer->name));
+ ast_copy_string(peer->name, name, sizeof(peer->name));
/* If we have channel variables, remove them (reload) */
if (peer->chanvars) {
@@ -21613,13 +21630,10 @@
}
} else if (!strcasecmp(v->name, "type")) {
if (!strcasecmp(v->value, "peer")) {
- peer->onlymatchonip = TRUE; /* For realtime support, add type=peer in the table */
- peer->type = SIP_TYPE_PEER;
+ peer->type |= SIP_TYPE_PEER;
} else if (!strcasecmp(v->value, "user")) {
- peer->onlymatchonip = FALSE;
- peer->type = SIP_TYPE_USER;
+ peer->type |= SIP_TYPE_USER;
} else if (!strcasecmp(v->value, "friend")) {
- peer->onlymatchonip = FALSE;
peer->type = SIP_TYPE_USER | SIP_TYPE_PEER;
}
} else if (!strcasecmp(v->name, "secret"))
@@ -22618,10 +22632,10 @@
hassip = ast_variable_retrieve(ucfg, cat, "hassip");
registersip = ast_variable_retrieve(ucfg, cat, "registersip");
if (ast_true(hassip) || (!hassip && genhassip)) {
- peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, FALSE);
+ peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
if (peer) {
ao2_t_link(peers, peer, "link peer into peer table");
- if (peer->addr.sin_addr.s_addr) {
+ if ((peer->type & SIP_TYPE_PEER) && peer->addr.sin_addr.s_addr) {
ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
}
@@ -22670,27 +22684,24 @@
ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
continue;
} else {
- int is_peer = 0;
if (!strcasecmp(utype, "user")) {
- is_peer = 1;
+ ;
} else if (!strcasecmp(utype, "friend")) {
- is_peer = 1;
- } else if (!strcasecmp(utype, "peer"))
- is_peer = 2;
- else {
+ ;
+ } else if (!strcasecmp(utype, "peer")) {
+ ;
+ } else {
ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
continue;
}
- if (is_peer) {
- peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, is_peer == 2);
- if (peer) {
- ao2_t_link(peers, peer, "link peer into peers table");
- if (peer->addr.sin_addr.s_addr) {
- ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
- }
- unref_peer(peer, "unref the result of the build_peer call. Now, the links from the tables are the only ones left.");
- peer_count++;
+ peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
+ if (peer) {
+ ao2_t_link(peers, peer, "link peer into peers table");
+ if ((peer->type & SIP_TYPE_PEER) && peer->addr.sin_addr.s_addr) {
+ ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
}
+ unref_peer(peer, "unref the result of the build_peer call. Now, the links from the tables are the only ones left.");
+ peer_count++;
}
}
}
More information about the asterisk-commits
mailing list