[asterisk-commits] branch oej/peermatch r10860 - in
/team/oej/peermatch: ./ channels/
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Thu Feb 23 00:30:46 MST 2006
Author: oej
Date: Thu Feb 23 01:30:42 2006
New Revision: 10860
URL: http://svn.digium.com/view/asterisk?rev=10860&view=rev
Log:
- Removing the sip_user structure
- Still using a separate object list of sip_users, but using the same structure definition
- Defining a friend once, linking to both the peer and the user list
Might turn into a problem with re-configuration of a peer, but want to test this
- This also improves the subscribe status, since we now have *one* call limit for
a friend - both for incoming and outbound calls. Subscriptions will now work as expected,
regardless if the call is incoming or outgoing
Added:
team/oej/peermatch/README.peermatch (with props)
Modified:
team/oej/peermatch/channels/chan_sip.c
Added: team/oej/peermatch/README.peermatch
URL: http://svn.digium.com/view/asterisk/team/oej/peermatch/README.peermatch?rev=10860&view=auto
==============================================================================
--- team/oej/peermatch/README.peermatch (added)
+++ team/oej/peermatch/README.peermatch Thu Feb 23 01:30:42 2006
@@ -1,0 +1,14 @@
+This branch implements these changes:
+
+- Removes the sip_user code object. To simplify the code, we now always use the
+ same memory structure for all devices, regardless if they are a peer or a user
+
+- Matches incoming calls on
+ - SIP_USER From: name
+ - SIP_PEER From: name
+ - SIP_PEER IP/port
+
+- Creates only one in-memory object for a friend, thus improving the
+ subscribe functionality. A call limit now applies to both incoming and
+ outgoing calls, since we have only ONE memory object.
+
Propchange: team/oej/peermatch/README.peermatch
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/oej/peermatch/README.peermatch
------------------------------------------------------------------------------
svn:keywords = Author Id Date Revision
Propchange: team/oej/peermatch/README.peermatch
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: team/oej/peermatch/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/peermatch/channels/chan_sip.c?rev=10860&r1=10859&r2=10860&view=diff
==============================================================================
--- team/oej/peermatch/channels/chan_sip.c (original)
+++ team/oej/peermatch/channels/chan_sip.c Thu Feb 23 01:30:42 2006
@@ -170,6 +170,12 @@
submitting a patch. If these two lists do not match properly
bad things will happen.
*/
+
+enum objecttype {
+ SIP_USER = (1 << 0), /* USER places calls to the PBX */
+ SIP_PEER = (1 << 1), /* Peer receives calls from PBX (and places calls) */
+ SIP_FRIEND = (1 << 2), /* Friend receives calls from PBX (and places calls) */
+};
enum subscriptiontype {
NONE = 0,
@@ -739,39 +745,11 @@
char data[0];
};
-/*! \brief Structure for SIP user data. User's place calls to us */
-struct sip_user {
- /* Users who can access various contexts */
- ASTOBJ_COMPONENTS(struct sip_user);
- char secret[80]; /*!< Password */
- char md5secret[80]; /*!< Password in md5 */
- char context[AST_MAX_CONTEXT]; /*!< Default context for incoming calls */
- char subscribecontext[AST_MAX_CONTEXT]; /* Default context for subscriptions */
- char cid_num[80]; /*!< Caller ID num */
- char cid_name[80]; /*!< Caller ID name */
- char accountcode[AST_MAX_ACCOUNT_CODE]; /* Account code */
- char language[MAX_LANGUAGE]; /*!< Default language for this user */
- char musicclass[MAX_MUSICCLASS];/*!< Music on Hold class */
- char useragent[256]; /*!< User agent in SIP request */
- struct ast_codec_pref prefs; /*!< codec prefs */
- ast_group_t callgroup; /*!< Call group */
- ast_group_t pickupgroup; /*!< Pickup Group */
- unsigned int flags; /*!< SIP flags */
- unsigned int sipoptions; /*!< Supported SIP options */
- struct ast_flags flags_page2; /*!< SIP_PAGE2 flags */
- int amaflags; /*!< AMA flags for billing */
- int callingpres; /*!< Calling id presentation */
- int capability; /*!< Codec capability */
- int inUse; /*!< Number of calls in use */
- int call_limit; /*!< Limit of concurrent calls */
- struct ast_ha *ha; /*!< ACL setting */
- struct ast_variable *chanvars; /*!< Variables to set for channel created by user */
-};
-
/*! \brief Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) */
struct sip_peer {
ASTOBJ_COMPONENTS(struct sip_peer); /*!< name, refcount, objflags, object pointers */
/*!< peer->name is the unique name of this object */
+ enum objecttype type; /*!< SIP_PEER or SIP_USER */
char secret[80]; /*!< Password */
char md5secret[80]; /*!< Password in MD5 */
struct sip_auth *auth; /*!< Realm authentication list */
@@ -872,7 +850,7 @@
/*! \brief The user list: Users and friends */
static struct ast_user_list {
- ASTOBJ_CONTAINER_COMPONENTS(struct sip_user);
+ ASTOBJ_CONTAINER_COMPONENTS(struct sip_peer);
} userl;
/*! \brief The peer list: Peers and Friends */
@@ -927,7 +905,7 @@
static int build_reply_digest(struct sip_pvt *p, int method, char *digest, int digest_len);
static int update_call_counter(struct sip_pvt *fup, int event);
static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int realtime);
-static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime);
+static struct sip_peer *build_user(const char *name, struct ast_variable *v, int realtime);
static int sip_do_reload(enum channelreloadreason reason);
static int expire_register(void *data);
static struct ast_channel *sip_request_call(const char *type, int format, void *data, int *cause);
@@ -1672,36 +1650,43 @@
}
}
-/*! \brief Destroy peer object from memory */
-static void sip_destroy_peer(struct sip_peer *peer)
+/*! \brief Destroy device object from memory */
+static void sip_destroy_device(struct sip_peer *device)
{
if (option_debug > 2)
- ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name);
+ ast_log(LOG_DEBUG, "Destroying SIP %s %s\n", device->type == SIP_USER ? "user" : "peer", device->name);
/* Delete it, it needs to disappear */
- if (peer->call)
- sip_destroy(peer->call);
- if (peer->chanvars) {
- ast_variables_destroy(peer->chanvars);
- peer->chanvars = NULL;
- }
- if (peer->expire > -1)
- ast_sched_del(sched, peer->expire);
- if (peer->pokeexpire > -1)
- ast_sched_del(sched, peer->pokeexpire);
- register_peer_exten(peer, 0);
- ast_free_ha(peer->ha);
- if (ast_test_flag((&peer->flags_page2), SIP_PAGE2_SELFDESTRUCT))
- apeerobjs--;
- else if (ast_test_flag(peer, SIP_REALTIME))
- rpeerobjs--;
- else
- speerobjs--;
- clear_realm_authentication(peer->auth);
- peer->auth = (struct sip_auth *) NULL;
- if (peer->dnsmgr)
- ast_dnsmgr_release(peer->dnsmgr);
- free(peer);
+ if (device->call)
+ sip_destroy(device->call);
+ if (device->chanvars) {
+ ast_variables_destroy(device->chanvars);
+ device->chanvars = NULL;
+ }
+ if (device->expire > -1)
+ ast_sched_del(sched, device->expire);
+ if (device->pokeexpire > -1)
+ ast_sched_del(sched, device->pokeexpire);
+ ast_free_ha(device->ha);
+ if ( device->type == SIP_PEER) {
+ register_peer_exten(device, FALSE);
+ clear_realm_authentication(device->auth);
+ if (ast_test_flag((&device->flags_page2), SIP_PAGE2_SELFDESTRUCT))
+ apeerobjs--;
+ else if (ast_test_flag(device, SIP_REALTIME))
+ rpeerobjs--;
+ else
+ speerobjs--;
+ } else { /* SIP_USER */
+ if (ast_test_flag(device, SIP_REALTIME))
+ ruserobjs--;
+ else
+ suserobjs--;
+ }
+ device->auth = (struct sip_auth *) NULL;
+ if (device->dnsmgr)
+ ast_dnsmgr_release(device->dnsmgr);
+ free(device);
}
/*! \brief Update peer data in database (if used) */
@@ -1813,31 +1798,14 @@
return p;
}
-/*! \brief Remove user object from in-memory storage */
-static void sip_destroy_user(struct sip_user *user)
-{
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name);
- ast_free_ha(user->ha);
- if (user->chanvars) {
- ast_variables_destroy(user->chanvars);
- user->chanvars = NULL;
- }
- if (ast_test_flag(user, SIP_REALTIME))
- ruserobjs--;
- else
- suserobjs--;
- free(user);
-}
-
/*! \brief Load user from realtime storage
* Loads user from "sipusers" category in realtime (extconfig.conf)
* Users are matched on From: user name (the domain in skipped) */
-static struct sip_user *realtime_user(const char *username)
+static struct sip_peer *realtime_user(const char *username)
{
struct ast_variable *var;
struct ast_variable *tmp;
- struct sip_user *user = NULL;
+ struct sip_peer *user = NULL;
var = ast_load_realtime("sipusers", "name", username, NULL);
@@ -1852,8 +1820,7 @@
}
}
- user = build_user(username, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS));
-
+ user = build_user(username, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS));
if (!user) { /* No user found */
ast_variables_destroy(var);
return NULL;
@@ -1877,9 +1844,9 @@
* Locates user by name (From: sip uri user name part) first
* from in-memory list (static configuration) then from
* realtime storage (defined in extconfig.conf) */
-static struct sip_user *find_user(const char *name, int realtime)
-{
- struct sip_user *u = NULL;
+static struct sip_peer *find_user(const char *name, int realtime)
+{
+ struct sip_peer *u = NULL;
u = ASTOBJ_CONTAINER_FIND(&userl,name);
if (!u && realtime) {
u = realtime_user(name);
@@ -1997,7 +1964,7 @@
if (p) {
found++;
if (create_addr_from_peer(dialog, p))
- ASTOBJ_UNREF(p, sip_destroy_peer);
+ ASTOBJ_UNREF(p, sip_destroy_device);
}
if (!p) {
if (found)
@@ -2031,7 +1998,7 @@
return -1;
}
} else {
- ASTOBJ_UNREF(p, sip_destroy_peer);
+ ASTOBJ_UNREF(p, sip_destroy_device);
return 0;
}
}
@@ -2267,10 +2234,8 @@
static int update_call_counter(struct sip_pvt *fup, int event)
{
char name[256];
- int *inuse, *call_limit;
int outgoing = ast_test_flag(fup, SIP_OUTGOING);
- struct sip_user *u = NULL;
- struct sip_peer *p = NULL;
+ struct sip_peer *device = NULL;
if (option_debug > 2)
ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
@@ -2283,63 +2248,49 @@
/* Check the list of users */
if (!outgoing) /* Only check users for incoming calls */
- u = find_user(name, 1);
-
- if (u) {
- inuse = &u->inUse;
- call_limit = &u->call_limit;
- p = NULL;
- } else {
+ device = find_user(name, 1);
+
+ if (!device) {
/* Try to find peer */
- if (!p)
- p = find_peer(fup->peername, NULL, 1);
- if (p) {
- inuse = &p->inUse;
- call_limit = &p->call_limit;
- ast_copy_string(name, fup->peername, sizeof(name));
- } else {
+ device = find_peer(fup->peername, NULL, 1);
+ if (!device) {
if (option_debug > 1)
- ast_log(LOG_DEBUG, "%s is not a local user, no call limit\n", name);
+ ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name);
return 0;
}
+ ast_copy_string(name, fup->peername, sizeof(name));
}
switch(event) {
/* incoming and outgoing affects the inUse counter */
case DEC_CALL_LIMIT:
- if ( *inuse > 0 ) {
+ if ( device->inUse > 0 ) {
if (ast_test_flag(fup, SIP_INC_COUNT))
- (*inuse)--;
+ device->inUse--;
} else {
- *inuse = 0;
+ device->inUse= 0;
}
if (option_debug > 1 || sipdebug) {
- ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
+ ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", device->type == SIP_USER ? "user":"peer", name, device->call_limit);
}
break;
case INC_CALL_LIMIT:
- if (*call_limit > 0 ) {
- if (*inuse >= *call_limit) {
- ast_log(LOG_ERROR, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
- if (u)
- ASTOBJ_UNREF(u, sip_destroy_user);
- else
- ASTOBJ_UNREF(p, sip_destroy_peer);
+ if (device->call_limit > 0 ) {
+ if (device->inUse >= device->call_limit) {
+ ast_log(LOG_ERROR, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", device->type == SIP_USER ? "user":"peer", name, device->call_limit);
+ ASTOBJ_UNREF(device, sip_destroy_device);
return -1;
}
}
- (*inuse)++;
+ device->inUse++;
ast_set_flag(fup, SIP_INC_COUNT);
if (option_debug > 1 || sipdebug) {
- ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit);
+ ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", device->type == SIP_USER ? "user":"peer", name, device->inUse, device->call_limit);
}
break;
default:
ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
}
- if (u)
- ASTOBJ_UNREF(u, sip_destroy_user);
- else
- ASTOBJ_UNREF(p, sip_destroy_peer);
+ ASTOBJ_UNREF(device, sip_destroy_device);
return 0;
}
@@ -5774,7 +5725,7 @@
ast_device_state_changed("SIP/%s", peer->name);
if (ast_test_flag((&peer->flags_page2), SIP_PAGE2_SELFDESTRUCT) || ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTAUTOCLEAR)) {
peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer);
- ASTOBJ_UNREF(peer, sip_destroy_peer);
+ ASTOBJ_UNREF(peer, sip_destroy_device);
}
return 0;
@@ -6501,7 +6452,7 @@
peer = find_peer(name, NULL, 1);
if (!(peer && ast_apply_ha(peer->ha, sin))) {
if (peer)
- ASTOBJ_UNREF(peer, sip_destroy_peer);
+ ASTOBJ_UNREF(peer, sip_destroy_device);
}
if (peer) {
if (!ast_test_flag((&peer->flags_page2), SIP_PAGE2_DYNAMIC)) {
@@ -6587,7 +6538,7 @@
}
}
if (peer)
- ASTOBJ_UNREF(peer, sip_destroy_peer);
+ ASTOBJ_UNREF(peer, sip_destroy_device);
return res;
}
@@ -7055,8 +7006,7 @@
*/
static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, int reliable, struct sockaddr_in *sin, int ignore, char *mailbox, int mailboxlen)
{
- struct sip_user *user = NULL;
- struct sip_peer *peer;
+ struct sip_peer *device = NULL;
char *of, from[256], *c;
char *rpid, rpid_num[50];
char iabuf[INET_ADDRSTRLEN];
@@ -7123,224 +7073,172 @@
return 0;
if (!mailbox) /* If it's a mailbox SUBSCRIBE, don't check users */
- user = find_user(of, 1);
-
- /* Find user based on user name in the from header */
- if (user && ast_apply_ha(user->ha, sin)) {
- ast_copy_flags(p, user, SIP_FLAGS_TO_COPY);
+ device = find_user(of, 1);
+ if (device && !ast_apply_ha(device->ha, sin)) {
+ ast_verbose("Found user '%s', but fails host access\n", device->name);
+ ASTOBJ_UNREF(device,sip_destroy_device);
+ device = NULL;
+ }
+
+ if (!device) {
+ /* Secondly, match on peer name */
+ device = find_peer(of, NULL, 1);
+ if (device && !ast_apply_ha(device->ha, sin)) {
+ ASTOBJ_UNREF(device,sip_destroy_device);
+ device = NULL;
+ }
+
+ /* Thirdly match on IP/port */
+ if (!device) {
+ /* Look for peer based on the IP address we received data from */
+ /* If peer is registered from this IP address or have this as a default
+ IP address, this call is from the peer
+ */
+ device = find_peer(NULL, &p->recv, 1);
+ }
+ if (device && !ast_apply_ha(device->ha, sin)) {
+ ASTOBJ_UNREF(device,sip_destroy_device);
+ device = NULL;
+ }
+ }
+
+ /* No user or peer found */
+ if (!device) {
+ if (debug)
+ ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
+
+ /* do we allow guests? */
+ if (!global_allowguest)
+ res = -1; /* we don't want any guests, authentication will fail */
+#ifdef OSP_SUPPORT
+ else if (global_allowguest == 2) {
+ ast_copy_flags(p, &global_flags, SIP_OSPAUTH);
+ res = check_auth(p, req, "", "", "", sipmethod, uri, reliable, ignore);
+ }
+#endif
+ return res;
+ }
+
+ /* Ok, we have a device, let's check authentication if needed */
+ ast_copy_flags(p, device, SIP_FLAGS_TO_COPY);
+
+ /* Copy SIP extensions profile to peer */
+ if (p->sipoptions)
+ device->sipoptions = p->sipoptions;
+
+ /* copy channel vars */
+ for (v = device->chanvars ; v ; v = v->next) {
+ if ((tmpvar = ast_variable_new(v->name, v->value))) {
+ tmpvar->next = p->chanvars;
+ p->chanvars = tmpvar;
+ }
+ }
+ p->prefs = device->prefs;
+ /* replace callerid if rpid found, and not restricted */
+ if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) {
+ char *tmp;
+ if (*calleridname)
+ ast_string_field_set(p, cid_name, calleridname);
+ tmp = ast_strdupa(rpid_num);
+ if (tmp) {
+ ast_shrink_phone_number(tmp);
+ ast_string_field_set(p, cid_num, tmp);
+ } else {
+ ast_string_field_set(p, cid_num, rpid_num);
+ }
+ }
+
+ if (p->rtp) {
+ if (option_debug)
+ ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
+ ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
+ }
+ if (p->vrtp) {
+ if (option_debug)
+ ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
+ ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
+ }
+ if (device->maxms && device->lastms)
+ p->timer_t1 = device->lastms;
+ if (ast_test_flag(device, SIP_INSECURE_INVITE)) {
+ /* Pretend there is no required authentication */
+ ast_string_field_free(p, peersecret);
+ ast_string_field_free(p, peermd5secret);
+ }
+
+ /* Now, check auth */
+ if (!(res = check_auth(p, req, device->name, device->secret, device->md5secret, sipmethod, uri, reliable, ignore))) {
+ /* We have positive authentication, let's configure this SIP session */
+ sip_cancel_destroy(p);
+ ast_copy_flags(p, device, SIP_FLAGS_TO_COPY);
+ /* Copy SIP extensions profile from INVITE */
+ if (p->sipoptions)
+ device->sipoptions = p->sipoptions;
+
+ /* If we have a call limit, set flag */
+ if (device->call_limit)
+ ast_set_flag(p, SIP_CALL_LIMIT);
+ if (!ast_strlen_zero(device->context))
+ ast_string_field_set(p, context, device->context);
+ if (!ast_strlen_zero(device->cid_num) && !ast_strlen_zero(p->cid_num)) {
+ char *tmp = ast_strdupa(device->cid_num);
+ if (tmp) {
+ ast_shrink_phone_number(tmp);
+ ast_string_field_set(p, cid_num, tmp);
+ } else {
+ ast_string_field_set(p, cid_num, device->cid_num);
+ }
+ }
+ if (!ast_strlen_zero(device->cid_name) && !ast_strlen_zero(p->cid_num))
+ ast_string_field_set(p, cid_name, device->cid_name);
+ if (device->type == SIP_USER) {
+ ast_string_field_set(p, username, device->name);
+ } else { /* SIP_PEER */
+ ast_string_field_set(p, peersecret, device->secret);
+ ast_string_field_set(p, peermd5secret, device->md5secret);
+ ast_string_field_set(p, fullcontact, device->fullcontact);
+ ast_string_field_set(p, peername, device->name);
+ ast_string_field_set(p, authname, device->name);
+ if (!ast_strlen_zero(device->username)) {
+ ast_string_field_set(p, username, device->username);
+ /* Use the default username for authentication on outbound calls */
+ ast_string_field_set(p, authname, device->username);
+ }
+ }
+ ast_string_field_set(p, subscribecontext, device->subscribecontext);
+ ast_string_field_set(p, accountcode, device->accountcode);
+ ast_string_field_set(p, language, device->language);
+ ast_string_field_set(p, musicclass, device->musicclass);
+ p->amaflags = device->amaflags;
+ p->callgroup = device->callgroup;
+ p->pickupgroup = device->pickupgroup;
+ p->callingpres = device->callingpres;
+ p->capability = device->capability;
+ p->jointcapability = device->capability;
+ p->prefs = device->prefs;
+ if (p->peercapability)
+ p->jointcapability &= p->peercapability;
+ if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
+ p->noncodeccapability |= AST_RTP_DTMF;
+ else
+ p->noncodeccapability &= ~AST_RTP_DTMF;
+
/* copy channel vars */
- for (v = user->chanvars ; v ; v = v->next) {
+ for (v = device->chanvars ; v ; v = v->next) {
if ((tmpvar = ast_variable_new(v->name, v->value))) {
tmpvar->next = p->chanvars;
p->chanvars = tmpvar;
}
}
- p->prefs = user->prefs;
- /* replace callerid if rpid found, and not restricted */
- if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) {
- char *tmp;
- if (*calleridname)
- ast_string_field_set(p, cid_name, calleridname);
- tmp = ast_strdupa(rpid_num);
- if (tmp) {
- ast_shrink_phone_number(tmp);
- ast_string_field_set(p, cid_num, tmp);
- } else {
- ast_string_field_set(p, cid_num, rpid_num);
- }
- }
-
- if (p->rtp) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
- ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
- }
- if (p->vrtp) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
- ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
- }
- if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri, reliable, ignore))) {
- sip_cancel_destroy(p);
- ast_copy_flags(p, user, SIP_FLAGS_TO_COPY);
- /* Copy SIP extensions profile from INVITE */
- if (p->sipoptions)
- user->sipoptions = p->sipoptions;
-
- /* If we have a call limit, set flag */
- if (user->call_limit)
- ast_set_flag(p, SIP_CALL_LIMIT);
- if (!ast_strlen_zero(user->context))
- ast_string_field_set(p, context, user->context);
- if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) {
- char *tmp = ast_strdupa(user->cid_num);
- if (tmp) {
- ast_shrink_phone_number(tmp);
- ast_string_field_set(p, cid_num, tmp);
- } else {
- ast_string_field_set(p, cid_num, user->cid_num);
- }
- }
- if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num))
- ast_string_field_set(p, cid_name, user->cid_name);
- ast_string_field_set(p, username, user->name);
- ast_string_field_set(p, peersecret, user->secret);
- ast_string_field_set(p, peermd5secret, user->md5secret);
- ast_string_field_set(p, subscribecontext, user->subscribecontext);
- ast_string_field_set(p, accountcode, user->accountcode);
- ast_string_field_set(p, language, user->language);
- ast_string_field_set(p, musicclass, user->musicclass);
- p->amaflags = user->amaflags;
- p->callgroup = user->callgroup;
- p->pickupgroup = user->pickupgroup;
- p->callingpres = user->callingpres;
- p->capability = user->capability;
- p->jointcapability = user->capability;
- if (p->peercapability)
- p->jointcapability &= p->peercapability;
- if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
- p->noncodeccapability |= AST_RTP_DTMF;
- else
- p->noncodeccapability &= ~AST_RTP_DTMF;
- }
- if (user && debug)
- ast_verbose("Found user '%s'\n", user->name);
- } else {
- if (user) {
- if (!mailbox && debug)
- ast_verbose("Found user '%s', but fails host access\n", user->name);
- ASTOBJ_UNREF(user,sip_destroy_user);
- }
- user = NULL;
- }
-
- if (!user) {
- /* Secondly, match on peer name */
- peer = find_peer(of, NULL, 1);
-
- /* Thirdly match on IP/port */
- if (!peer) {
- /* Look for peer based on the IP address we received data from */
- /* If peer is registered from this IP address or have this as a default
- IP address, this call is from the peer
- */
- peer = find_peer(NULL, &p->recv, 1);
- }
-
- if (peer) {
- if (debug)
- ast_verbose("Found peer '%s'\n", peer->name);
- /* Take the peer */
- ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
-
- /* Copy SIP extensions profile to peer */
- if (p->sipoptions)
- peer->sipoptions = p->sipoptions;
-
- /* replace callerid if rpid found, and not restricted */
- if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) {
- char *tmp = ast_strdupa(rpid_num);
- if (*calleridname)
- ast_string_field_set(p, cid_name, calleridname);
- if (tmp) {
- ast_shrink_phone_number(tmp);
- ast_string_field_set(p, cid_num, tmp);
- } else {
- ast_string_field_set(p, cid_num, rpid_num);
- }
- }
- if (p->rtp) {
- ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
- ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
- }
- if (p->vrtp) {
- ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
- ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
- }
- ast_string_field_set(p, peersecret, peer->secret);
- ast_string_field_set(p, peermd5secret, peer->md5secret);
- ast_string_field_set(p, subscribecontext, peer->subscribecontext);
- p->callingpres = peer->callingpres;
- if (peer->maxms && peer->lastms)
- p->timer_t1 = peer->lastms;
- if (ast_test_flag(peer, SIP_INSECURE_INVITE)) {
- /* Pretend there is no required authentication */
- ast_string_field_free(p, peersecret);
- ast_string_field_free(p, peermd5secret);
- }
- if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri, reliable, ignore))) {
- ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
- /* If we have a call limit, set flag */
- if (peer->call_limit)
- ast_set_flag(p, SIP_CALL_LIMIT);
- ast_string_field_set(p, peername, peer->name);
- ast_string_field_set(p, authname, peer->name);
-
- /* copy channel vars */
- for (v = peer->chanvars ; v ; v = v->next) {
- if ((tmpvar = ast_variable_new(v->name, v->value))) {
- tmpvar->next = p->chanvars;
- p->chanvars = tmpvar;
- }
- }
- if (mailbox)
- snprintf(mailbox, mailboxlen, ",%s,", peer->mailbox);
- if (!ast_strlen_zero(peer->username)) {
- ast_string_field_set(p, username, peer->username);
- /* Use the default username for authentication on outbound calls */
- ast_string_field_set(p, authname, peer->username);
- }
- if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) {
- char *tmp = ast_strdupa(peer->cid_num);
- if (tmp) {
- ast_shrink_phone_number(tmp);
- ast_string_field_set(p, cid_num, tmp);
- } else {
- ast_string_field_set(p, cid_num, peer->cid_num);
- }
- }
- if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name))
- ast_string_field_set(p, cid_name, peer->cid_name);
- ast_string_field_set(p, fullcontact, peer->fullcontact);
- if (!ast_strlen_zero(peer->context))
- ast_string_field_set(p, context, peer->context);
- ast_string_field_set(p, peersecret, peer->secret);
- ast_string_field_set(p, peermd5secret, peer->md5secret);
- ast_string_field_set(p, language, peer->language);
- ast_string_field_set(p, accountcode, peer->accountcode);
- p->amaflags = peer->amaflags;
- p->callgroup = peer->callgroup;
- p->pickupgroup = peer->pickupgroup;
- p->capability = peer->capability;
- p->prefs = peer->prefs;
- p->jointcapability = peer->capability;
- if (p->peercapability)
- p->jointcapability &= p->peercapability;
- if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
- p->noncodeccapability |= AST_RTP_DTMF;
- else
- p->noncodeccapability &= ~AST_RTP_DTMF;
- }
- ASTOBJ_UNREF(peer, sip_destroy_peer);
- } else {
- if (debug)
- ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
-
- /* do we allow guests? */
- if (!global_allowguest)
- res = -1; /* we don't want any guests, authentication will fail */
-#ifdef OSP_SUPPORT
- else if (global_allowguest == 2) {
- ast_copy_flags(p, &global_flags, SIP_OSPAUTH);
- res = check_auth(p, req, "", "", "", sipmethod, uri, reliable, ignore);
- }
-#endif
- }
-
- }
-
- if (user)
- ASTOBJ_UNREF(user, sip_destroy_user);
+ if (mailbox)
+ snprintf(mailbox, mailboxlen, ",%s,", device->mailbox);
+ }
+ if (device && debug)
+ ast_verbose("Found %s '%s'\n", device->type == SIP_USER ? "user" : "peer", device->name);
+
+ if (device)
+ ASTOBJ_UNREF(device, sip_destroy_device);
+
return res;
}
@@ -7775,8 +7673,7 @@
/*! \brief sip_prune_realtime: Remove temporary realtime objects from memory (CLI) */
static int sip_prune_realtime(int fd, int argc, char *argv[])
{
- struct sip_peer *peer;
- struct sip_user *user;
+ struct sip_peer *device;
int pruneuser = FALSE;
int prunepeer = FALSE;
int multi = FALSE;
@@ -7862,7 +7759,7 @@
ASTOBJ_UNLOCK(iterator);
} while (0) );
if (pruned) {
- ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
+ ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_device);
ast_cli(fd, "%d peers pruned.\n", pruned);
} else
ast_cli(fd, "No peers found to prune.\n");
@@ -7885,7 +7782,7 @@
ASTOBJ_UNLOCK(iterator);
} while (0) );
if (pruned) {
- ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user);
+ ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_device);
ast_cli(fd, "%d users pruned.\n", pruned);
} else
ast_cli(fd, "No users found to prune.\n");
@@ -7893,24 +7790,24 @@
}
} else {
if (prunepeer) {
- if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
- if (!ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
+ if ((device = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
+ if (!ast_test_flag((&device->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
- ASTOBJ_CONTAINER_LINK(&peerl, peer);
+ ASTOBJ_CONTAINER_LINK(&peerl, device);
} else
ast_cli(fd, "Peer '%s' pruned.\n", name);
- ASTOBJ_UNREF(peer, sip_destroy_peer);
+ ASTOBJ_UNREF(device, sip_destroy_device);
} else
ast_cli(fd, "Peer '%s' not found.\n", name);
}
if (pruneuser) {
- if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
- if (!ast_test_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
+ if ((device = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
+ if (!ast_test_flag((&device->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name);
- ASTOBJ_CONTAINER_LINK(&userl, user);
+ ASTOBJ_CONTAINER_LINK(&userl, device);
} else
ast_cli(fd, "User '%s' pruned.\n", name);
- ASTOBJ_UNREF(user, sip_destroy_user);
+ ASTOBJ_UNREF(device, sip_destroy_device);
} else
ast_cli(fd, "User '%s' not found.\n", name);
}
@@ -8116,7 +8013,7 @@
ast_cli(fd, " %s = %s\n", v->name, v->value);
}
ast_cli(fd,"\n");
- ASTOBJ_UNREF(peer,sip_destroy_peer);
+ ASTOBJ_UNREF(peer,sip_destroy_device);
} else if (peer && type == 1) { /* manager listing */
char *actionid = astman_get_header(m,"ActionID");
@@ -8188,7 +8085,7 @@
}
}
- ASTOBJ_UNREF(peer,sip_destroy_peer);
+ ASTOBJ_UNREF(peer,sip_destroy_device);
} else {
ast_cli(fd,"Peer %s not found.\n", argv[3]);
@@ -8202,7 +8099,7 @@
static int sip_show_user(int fd, int argc, char *argv[])
{
char cbuf[256];
- struct sip_user *user;
+ struct sip_peer *user;
struct ast_codec_pref *pref;
struct ast_variable *v;
int x = 0, codec = 0, load_realtime;
@@ -8253,7 +8150,7 @@
ast_cli(fd, " %s = %s\n", v->name, v->value);
}
ast_cli(fd,"\n");
- ASTOBJ_UNREF(user,sip_destroy_user);
+ ASTOBJ_UNREF(user,sip_destroy_device);
} else {
ast_cli(fd,"User %s not found.\n", argv[3]);
ast_cli(fd,"\n");
@@ -8864,7 +8761,7 @@
ast_set_flag(&global_flags_page2, SIP_PAGE2_DEBUG_CONSOLE);
} else
ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[3]);
- ASTOBJ_UNREF(peer,sip_destroy_peer);
+ ASTOBJ_UNREF(peer,sip_destroy_device);
} else
ast_cli(fd, "No such peer '%s'\n", argv[3]);
return RESULT_SUCCESS;
@@ -9399,7 +9296,7 @@
}
}
- ASTOBJ_UNREF(peer, sip_destroy_peer);
+ ASTOBJ_UNREF(peer, sip_destroy_device);
return 0;
}
@@ -11415,7 +11312,7 @@
ASTOBJ_WRLOCK(peer);
sip_send_mwi_to_peer(peer);
ASTOBJ_UNLOCK(peer);
- ASTOBJ_UNREF(peer,sip_destroy_peer);
+ ASTOBJ_UNREF(peer,sip_destroy_device);
} else {
/* Reset where we come from */
lastpeernum = -1;
@@ -11595,7 +11492,7 @@
/* there is no address, it's unavailable */
res = AST_DEVICE_UNAVAILABLE;
}
- ASTOBJ_UNREF(p,sip_destroy_peer);
+ ASTOBJ_UNREF(p,sip_destroy_device);
} else {
hp = ast_gethostbyname(host, &ahp);
if (hp)
@@ -11945,10 +11842,44 @@
return a;
}
+/*! \brief Set peer defaults before configuring specific configurations */
+static void set_peer_defaults(struct sip_peer *peer)
+{
+ peer->expire = -1;
+ peer->pokeexpire = -1;
+ ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY);
+ strcpy(peer->context, default_context);
+ strcpy(peer->subscribecontext, default_subscribecontext);
+ strcpy(peer->language, default_language);
+ strcpy(peer->musicclass, default_musicclass);
+ peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
+ peer->addr.sin_family = AF_INET;
+ peer->defaddr.sin_family = AF_INET;
+ peer->capability = global_capability;
+ peer->rtptimeout = global_rtptimeout;
+ peer->rtpholdtimeout = global_rtpholdtimeout;
+ peer->rtpkeepalive = global_rtpkeepalive;
+ strcpy(peer->vmexten, default_vmexten);
+ ast_copy_flags(peer, &global_flags, SIP_USEREQPHONE);
+ peer->secret[0] = '\0';
+ peer->md5secret[0] = '\0';
+ peer->cid_num[0] = '\0';
+ peer->cid_name[0] = '\0';
+ peer->fromdomain[0] = '\0';
+ peer->fromuser[0] = '\0';
+ peer->regexten[0] = '\0';
+ peer->mailbox[0] = '\0';
+ peer->callgroup = 0;
+ peer->pickupgroup = 0;
+ peer->maxms = default_qualify;
+ peer->prefs = default_prefs;
+}
+
+
/*! \brief Initiate a SIP user structure from configuration (configuration or realtime) */
-static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime)
-{
- struct sip_user *user;
+static struct sip_peer *build_user(const char *name, struct ast_variable *v, int realtime)
+{
+ struct sip_peer *user;
int format;
struct ast_ha *oldha = NULL;
char *varname = NULL, *varval = NULL;
@@ -11956,22 +11887,16 @@
struct ast_flags userflags = {(0)};
struct ast_flags mask = {(0)};
-
if (!(user = ast_calloc(1, sizeof(*user))))
return NULL;
suserobjs++;
ASTOBJ_INIT(user);
+ user-> type = SIP_USER;
ast_copy_string(user->name, name, sizeof(user->name));
oldha = user->ha;
user->ha = NULL;
- ast_copy_flags(user, &global_flags, SIP_FLAGS_TO_COPY);
- user->capability = global_capability;
- user->prefs = default_prefs;
- /* set default context */
- strcpy(user->context, default_context);
- strcpy(user->language, default_language);
- strcpy(user->musicclass, default_musicclass);
+ set_peer_defaults(user); /* Set default values for this object */
for (; v; v = v->next) {
if (handle_common_options(&userflags, &mask, v))
continue;
@@ -12035,39 +11960,6 @@
return user;
}
-/*! \brief Set peer defaults before configuring specific configurations */
-static void set_peer_defaults(struct sip_peer *peer)
-{
- peer->expire = -1;
- peer->pokeexpire = -1;
- ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY);
- strcpy(peer->context, default_context);
- strcpy(peer->subscribecontext, default_subscribecontext);
- strcpy(peer->language, default_language);
- strcpy(peer->musicclass, default_musicclass);
- peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
- peer->addr.sin_family = AF_INET;
- peer->defaddr.sin_family = AF_INET;
- peer->capability = global_capability;
- peer->rtptimeout = global_rtptimeout;
- peer->rtpholdtimeout = global_rtpholdtimeout;
- peer->rtpkeepalive = global_rtpkeepalive;
- strcpy(peer->vmexten, default_vmexten);
- ast_copy_flags(peer, &global_flags, SIP_USEREQPHONE);
- peer->secret[0] = '\0';
- peer->md5secret[0] = '\0';
- peer->cid_num[0] = '\0';
- peer->cid_name[0] = '\0';
- peer->fromdomain[0] = '\0';
- peer->fromuser[0] = '\0';
- peer->regexten[0] = '\0';
- peer->mailbox[0] = '\0';
- peer->callgroup = 0;
- peer->pickupgroup = 0;
- peer->maxms = default_qualify;
- peer->prefs = default_prefs;
-}
-
/*! \brief Create temporary peer (used in autocreatepeer mode) */
static struct sip_peer *temp_peer(const char *name)
{
@@ -12128,6 +12020,8 @@
peer->expire = -1;
peer->pokeexpire = -1;
}
+ peer->type = SIP_PEER;
+
/* Note that our peer HAS had its reference count incrased */
peer->lastmsgssent = -1;
@@ -12202,7 +12096,7 @@
ast_clear_flag((&peer->flags_page2), SIP_PAGE2_DYNAMIC);
if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) {
- ASTOBJ_UNREF(peer, sip_destroy_peer);
+ ASTOBJ_UNREF(peer, sip_destroy_device);
return NULL;
}
}
@@ -12216,7 +12110,7 @@
}
} else if (!strcasecmp(v->name, "defaultip")) {
if (ast_get_ip(&peer->defaddr, v->value)) {
- ASTOBJ_UNREF(peer, sip_destroy_peer);
+ ASTOBJ_UNREF(peer, sip_destroy_device);
return NULL;
}
} else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
@@ -12329,8 +12223,7 @@
{
struct ast_config *cfg;
struct ast_variable *v;
- struct sip_peer *peer;
- struct sip_user *user;
+ struct sip_peer *device;
struct ast_hostent ahp;
char *cat;
struct hostent *hp;
@@ -12629,31 +12522,33 @@
ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
continue;
} else {
- int is_user = 0, is_peer = 0;
+ enum objecttype type;
if (!strcasecmp(utype, "user"))
- is_user = 1;
+ type = SIP_USER;
else if (!strcasecmp(utype, "friend"))
- is_user = is_peer = 1;
+ type = SIP_FRIEND;
else if (!strcasecmp(utype, "peer"))
- is_peer = 1;
+ type = SIP_PEER;
else {
ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
continue;
}
- if (is_user) {
- user = build_user(cat, ast_variable_browse(cfg, cat), 0);
- if (user) {
- ASTOBJ_CONTAINER_LINK(&userl,user);
- ASTOBJ_UNREF(user, sip_destroy_user);
- user_count++;
+ if (type == SIP_PEER || type == SIP_FRIEND) {
+ device = build_peer(cat, ast_variable_browse(cfg, cat), 0);
+ if (device) {
+ ASTOBJ_CONTAINER_LINK(&peerl,device);
+ ASTOBJ_UNREF(device, sip_destroy_device);
+ peer_count++;
}
}
- if (is_peer) {
- peer = build_peer(cat, ast_variable_browse(cfg, cat), 0);
- if (peer) {
- ASTOBJ_CONTAINER_LINK(&peerl,peer);
- ASTOBJ_UNREF(peer, sip_destroy_peer);
- peer_count++;
+ if (type == SIP_USER || type == SIP_FRIEND) {
+ /* We already have a device for a friend, link it in again */
+ if (type != SIP_FRIEND)
+ device = build_user(cat, ast_variable_browse(cfg, cat), 0);
+ if (device) {
+ ASTOBJ_CONTAINER_LINK(&userl,device);
+ ASTOBJ_UNREF(device, sip_destroy_device);
+ user_count++;
}
}
}
@@ -13044,7 +12939,7 @@
} while(0));
/* Then, actually destroy users and registry */
- ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
+ ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_device);
if (option_debug > 3)
ast_log(LOG_DEBUG, "--------------- Done destroying user list\n");
ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy);
@@ -13054,7 +12949,7 @@
reload_config(reason);
/* Prune peers who still are supposed to be deleted */
- ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
+ ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_device);
if (option_debug > 3)
ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n");
@@ -13255,9 +13150,9 @@
[... 12 lines stripped ...]
More information about the asterisk-commits
mailing list