[asterisk-commits] branch oej/test-this-branch r11774 - in
/team/oej/test-this-branch: ./ channels/
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Sat Mar 4 02:47:54 MST 2006
Author: oej
Date: Sat Mar 4 03:47:50 2006
New Revision: 11774
URL: http://svn.digium.com/view/asterisk?rev=11774&view=rev
Log:
Adding the improved peermatch branch
Modified:
team/oej/test-this-branch/README.test-this-branch
team/oej/test-this-branch/UPGRADE.txt
team/oej/test-this-branch/channels/chan_sip.c
Modified: team/oej/test-this-branch/README.test-this-branch
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/README.test-this-branch?rev=11774&r1=11773&r2=11774&view=diff
==============================================================================
--- team/oej/test-this-branch/README.test-this-branch (original)
+++ team/oej/test-this-branch/README.test-this-branch Sat Mar 4 03:47:50 2006
@@ -14,11 +14,11 @@
----------------------
This branch includes the following branches
- sipdiversion: Additional support for the Diversion: header
-- jitterbuffer: Jitterbuffer for RTP in chan_sip (#3854)
-- videosupport: Improved support for video (#5427)
-- peermatch: New peer matching algorithm (no bug report yet)
-- rtcp: Improved support for RTCP (#2863)
-- dialplan-ami-events: Report dialplan reload in manager (#5741)
+- jitterbuffer: Jitterbuffer for RTP in chan_sip (#3854, Securax/ZOA)
+- videosupport: Improved support for video (#5427, John Martin)
+- peermatch: New peer matching algorithm (#6612, oej)
+- rtcp: Improved support for RTCP (#2863, folsson/John Martin)
+- dialplan-ami-events: Report dialplan reload in manager (#5741, oej)
- sipregister: A new registration architecture (rizzo, oej #5834)
- subscribemwi: Support for SIP subscription of MWI notification (oej #6390)
- iptos: New IPtos support, separate audio and signalling (#6355)
@@ -35,7 +35,7 @@
Coming here soon:
- metermaids: Subscription support for parking lots (#5779)
-
+- siptransfer: Improved SIP transfer support
All of these exist in the bug tracker. Please report your findings
in each open issue report, so that we get the feedback for each
@@ -84,6 +84,16 @@
This means that in most configurations, you can configure a phone entry as
"type=peer" instead of "type=friend". Subscriptions will work much better
with just one object to match.
+
+We have also removed the sip_user structure and only uses one device
+data structure in the code. For type=friend, we use *one* object instead of
+two, still linking it to the user and the peer list.
+This means that call_limits now are implemented for the device only
+once. Incoming and outgoing channels are counted on the same object,
+not separate objects as before. This also improves the SIP SUBSCRIBE
+support (blinking lamps) as outbound and incoming calls are handled
+by the same in-memory object. In most cases, type=peer will work as
+well.
* Multiparking - multiple parking lots in Asterisk
--------------------------------------------------
Modified: team/oej/test-this-branch/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/UPGRADE.txt?rev=11774&r1=11773&r2=11774&view=diff
==============================================================================
--- team/oej/test-this-branch/UPGRADE.txt (original)
+++ team/oej/test-this-branch/UPGRADE.txt Sat Mar 4 03:47:50 2006
@@ -56,6 +56,8 @@
The SIP channel:
* The "incominglimit" setting is replaced by the "call-limit" setting in sip.conf.
+* The matching on incoming calls is now done on peer From: user names after matching
+ user names and before matching peers by IP address.
Installation:
Modified: team/oej/test-this-branch/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/channels/chan_sip.c?rev=11774&r1=11773&r2=11774&view=diff
==============================================================================
--- team/oej/test-this-branch/channels/chan_sip.c (original)
+++ team/oej/test-this-branch/channels/chan_sip.c Sat Mar 4 03:47:50 2006
@@ -185,6 +185,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,
@@ -776,40 +782,10 @@
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 parkinglot[AST_MAX_EXTENSION];/*!< Default parking lot */
- 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 */
- int maxcallbitrate; /*!< Maximum Bitrate for a video call */
-};
-
/*! \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 */
+ enum objecttype type; /*!< SIP_PEER and/or SIP_USER */
/*!< peer->name is the unique name of this object */
char secret[80]; /*!< Password */
char md5secret[80]; /*!< Password in MD5 */
@@ -917,7 +893,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 */
@@ -972,7 +948,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);
@@ -1003,8 +979,7 @@
static int find_sip_method(char *msg);
static unsigned int parse_sip_options(struct sip_pvt *pvt, char *supported);
static void sip_destroy(struct sip_pvt *p);
-static void sip_destroy_peer(struct sip_peer *peer);
-static void sip_destroy_user(struct sip_user *user);
+static void sip_destroy_device(struct sip_peer *device);
static void parse_request(struct sip_request *req);
static char *get_header(struct sip_request *req, const char *name);
static void copy_request(struct sip_request *dst,struct sip_request *src);
@@ -1014,7 +989,7 @@
static int __sip_do_register(struct sip_registry *r);
static int restart_monitor(void);
static char *generate_random_string(char *buf, size_t size);
-static void set_peer_defaults(struct sip_peer *peer);
+static void set_device_defaults(struct sip_peer *peer);
static struct sip_peer *temp_peer(const char *name);
static int sip_send_mwi_to_peer(struct sip_peer *peer);
static int sip_scheddestroy(struct sip_pvt *p, int ms);
@@ -1726,46 +1701,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->mwipvt) { /* We have an active subscription, delete it */
- sip_destroy(peer->mwipvt);
- }
-
- 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);
- if (peer->registry) {
- /* OEJ - NEeds to do a proper OBJECT dereference and delinking here */
- //
- //sip_registry_destroy(peer->registry);
- }
- 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) */
@@ -1877,31 +1849,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);
@@ -1916,8 +1871,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;
@@ -1941,9 +1895,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);
@@ -2069,7 +2023,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)
@@ -2103,7 +2057,7 @@
return -1;
}
} else {
- ASTOBJ_UNREF(p, sip_destroy_peer);
+ ASTOBJ_UNREF(p, sip_destroy_device);
return 0;
}
}
@@ -2345,10 +2299,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");
@@ -2361,63 +2313,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;
}
@@ -5903,7 +5841,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;
@@ -6630,7 +6568,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)) {
@@ -6717,7 +6655,7 @@
}
}
if (peer)
- ASTOBJ_UNREF(peer, sip_destroy_peer);
+ ASTOBJ_UNREF(peer, sip_destroy_device);
return res;
}
@@ -7283,8 +7221,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, struct sip_peer **authpeer)
{
- 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];
@@ -7350,240 +7287,175 @@
if (ast_strlen_zero(of))
return 0;
- if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */
- 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);
+ if (!authpeer) /* If it's a mailbox SUBSCRIBE, don't check users */
+ 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);
- ast_copy_flags((&p->flags_page2),(&user->flags_page2), SIP_PAGE2_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);
- ast_string_field_set(p, parkinglot, user->parkinglot);
- p->amaflags = user->amaflags;
- p->callgroup = user->callgroup;
- p->pickupgroup = user->pickupgroup;
- p->callingpres = user->callingpres;
- p->capability = user->capability;
- p->jointcapability = user->capability;
- p->maxcallbitrate = user->maxcallbitrate;
- if (!ast_test_flag((&p->flags_page2), SIP_PAGE2_VIDEOSUPPORT) && p->vrtp) {
- ast_rtp_destroy(p->vrtp);
- p->vrtp = NULL;
- }
- 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 (!authpeer && 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 (authpeer) {
- (*authpeer) = peer; /* We might want to add a ref to the object here, to keep it in memory a bit longer if it is realtime */
- ASTOBJ_REF(peer); /* Any function that uses authpeer needs to ASTOBJ_UNREF */
- }
- 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;
- p->maxcallbitrate = peer->maxcallbitrate;
- if (!ast_test_flag((&p->flags_page2), SIP_PAGE2_VIDEOSUPPORT) && p->vrtp) {
- ast_rtp_destroy(p->vrtp);
- p->vrtp = NULL;
- }
- 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 (authpeer) {
+ (*authpeer) = device;
+ ASTOBJ_REF(device);
+ }
+ }
+ 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;
}
@@ -8020,8 +7892,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;
@@ -8107,7 +7978,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");
@@ -8130,7 +8001,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");
@@ -8138,24 +8009,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);
}
@@ -8364,7 +8235,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");
@@ -8438,7 +8309,7 @@
}
}
- ASTOBJ_UNREF(peer,sip_destroy_peer);
+ ASTOBJ_UNREF(peer,sip_destroy_device);
} else {
ast_cli(fd,"Peer %s not found.\n", argv[3]);
@@ -8452,7 +8323,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;
@@ -8503,7 +8374,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");
@@ -9121,7 +8992,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;
@@ -9658,7 +9529,7 @@
}
}
- ASTOBJ_UNREF(peer, sip_destroy_peer);
+ ASTOBJ_UNREF(peer, sip_destroy_device);
return 0;
}
@@ -11218,7 +11089,7 @@
ast_set_flag(p, SIP_NEEDDESTROY);
}
if (authpeer)
- ASTOBJ_UNREF(authpeer, sip_destroy_peer);
+ ASTOBJ_UNREF(authpeer, sip_destroy_device);
return 1;
}
@@ -11711,7 +11582,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;
@@ -11891,7 +11762,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)
@@ -12241,10 +12112,46 @@
return a;
}
+/*! \brief Set device defaults before configuring specific configurations */
+static void set_device_defaults(struct sip_peer *device)
+{
+ device->expire = -1;
+ device->pokeexpire = -1;
+ ast_copy_flags(device, &global_flags, SIP_FLAGS_TO_COPY);
+ strcpy(device->context, default_context);
+ strcpy(device->subscribecontext, default_subscribecontext);
+ strcpy(device->language, default_language);
+ strcpy(device->musicclass, default_musicclass);
+ strcpy(device->parkinglot, default_parkinglot);
+ device->addr.sin_port = htons(DEFAULT_SIP_PORT);
+ device->addr.sin_family = AF_INET;
+ device->defaddr.sin_family = AF_INET;
+ device->capability = global_capability;
+ device->rtptimeout = global_rtptimeout;
+ device->rtpholdtimeout = global_rtpholdtimeout;
+ device->rtpkeepalive = global_rtpkeepalive;
+ device->maxcallbitrate = default_maxcallbitrate;
+ strcpy(device->vmexten, default_vmexten);
+ ast_copy_flags(device, &global_flags, SIP_USEREQPHONE);
+ device->secret[0] = '\0';
+ device->md5secret[0] = '\0';
+ device->cid_num[0] = '\0';
+ device->cid_name[0] = '\0';
+ device->fromdomain[0] = '\0';
+ device->fromuser[0] = '\0';
+ device->regexten[0] = '\0';
+ device->mailbox[0] = '\0';
+ device->callgroup = 0;
+ device->pickupgroup = 0;
+ device->maxms = default_qualify;
+ device->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;
@@ -12258,17 +12165,11 @@
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);
- strcpy(user->parkinglot, default_parkinglot);
+ set_device_defaults(user); /* Set default values for this object */
for (; v; v = v->next) {
if (handle_common_options(&userflags, &mask, v))
continue;
@@ -12345,41 +12246,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);
- strcpy(peer->parkinglot, default_parkinglot);
- 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->maxcallbitrate = default_maxcallbitrate;
- peer->rtptimeout = global_rtptimeout;
- peer->rtpholdtimeout = global_rtpholdtimeout;
- peer->rtpkeepalive = global_rtpkeepalive;
[... 154 lines stripped ...]
More information about the asterisk-commits
mailing list