[Asterisk-cvs] asterisk/channels chan_sip.c,1.624,1.625
markster at lists.digium.com
markster at lists.digium.com
Sun Jan 9 23:42:07 CST 2005
Update of /usr/cvsroot/asterisk/channels
In directory mongoose.digium.com:/tmp/cvs-serv29158/channels
Modified Files:
chan_sip.c
Log Message:
Improve object destruction (bug #3286)
Index: chan_sip.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v
retrieving revision 1.624
retrieving revision 1.625
diff -u -d -r1.624 -r1.625
--- chan_sip.c 9 Jan 2005 20:09:48 -0000 1.624
+++ chan_sip.c 10 Jan 2005 05:46:25 -0000 1.625
@@ -1111,66 +1111,44 @@
realtime_update_peer(p->name, &p->addr, p->username, expiry);
}
-static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int temponly);
+static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int realtime);
static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
{
- struct ast_variable *var, *tmp=NULL;
- char iabuf[80];
struct sip_peer *peer=NULL;
- time_t nowtime, regseconds;
- int dynamic=0;
-
- if (sin)
- ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr);
+ struct ast_variable *var;
+ struct ast_variable *tmp;
+
if (peername)
var = ast_load_realtime("sipfriends", "name", peername, NULL);
- else
+ else if (sin) {
+ char iabuf[80];
+
+ ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr);
var = ast_load_realtime("sipfriends", "ipaddr", iabuf, NULL);
- if (var) {
- /* Make sure it's not a user only... */
- peer = build_peer(peername, var, 1);
- if (peer) {
- /* Add some finishing touches, addresses, etc */
- ast_set_flag(peer, SIP_REALTIME);
- tmp = var;
- while(tmp) {
- if (!strcasecmp(tmp->name, "type")) {
- if (strcasecmp(tmp->value, "friend") &&
- strcasecmp(tmp->value, "peer")) {
- /* Whoops, we weren't supposed to exist! */
- sip_destroy_peer(peer);
- peer = NULL;
- break;
- }
- } else if (!strcasecmp(tmp->name, "regseconds")) {
- if (sscanf(tmp->value, "%li", ®seconds) != 1)
- regseconds = 0;
- } else if (!strcasecmp(tmp->name, "ipaddr")) {
- inet_aton(tmp->value, &(peer->addr.sin_addr));
- } else if (!strcasecmp(tmp->name, "port")) {
- peer->addr.sin_port = htons(atoi(tmp->value));
- } else if (!strcasecmp(tmp->name, "host")) {
- if (!strcasecmp(tmp->value, "dynamic"))
- dynamic = 1;
- }
- tmp = tmp->next;
- }
- if (peer && dynamic) {
- time(&nowtime);
- if ((nowtime - regseconds) > 0) {
- memset(&peer->addr, 0, sizeof(peer->addr));
- if (option_debug)
- ast_log(LOG_DEBUG, "Bah, we're expired (%ld/%ld/%ld)!\n", nowtime - regseconds, regseconds, nowtime);
- }
- }
+ } else
+ return NULL;
+
+ if (!var)
+ return NULL;
+
+ tmp = var;
+ while(tmp) {
+ if (strcasecmp(tmp->name, "type"))
+ continue;
+
+ if (!strcasecmp(tmp->value, "user")) {
+ ast_destroy_realtime(var);
+ return NULL;
}
- ast_destroy_realtime(var);
- }
- if (peer) {
- /* Destroy, so when our caller unrefs, it will disappear */
- ASTOBJ_DESTROY(peer, sip_destroy_peer);
+
+ tmp = tmp->next;
}
+
+ peer = build_peer(peername, var, 1);
+ if (peer)
+ ast_set_flag(peer, SIP_REALTIME);
+ ast_destroy_realtime(var);
return peer;
}
@@ -1214,43 +1192,39 @@
free(user);
}
-static struct sip_user *build_user(const char *name, struct ast_variable *v);
+static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime);
static struct sip_user *realtime_user(const char *username)
{
struct ast_variable *var;
struct ast_variable *tmp;
- struct sip_user *user=NULL;
+ struct sip_user *user = NULL;
+
var = ast_load_realtime("sipfriends", "name", username, NULL);
- if (var) {
- /* Make sure it's not a user only... */
- user = build_user(username, var);
- if (user) {
- /* Move counter from s to r... */
- suserobjs--;
- ruserobjs++;
- /* Add some finishing touches, addresses, etc */
- ast_set_flag(user, SIP_REALTIME);
- tmp = var;
- while(tmp) {
- if (!strcasecmp(tmp->name, "type")) {
- if (strcasecmp(tmp->value, "friend") &&
- strcasecmp(tmp->value, "user")) {
- /* Whoops, we weren't supposed to exist! */
- sip_destroy_user(user);
- user = NULL;
- break;
- }
- }
- tmp = tmp->next;
- }
+
+ if (!var)
+ return NULL;
+
+ tmp = var;
+ while (tmp) {
+ if (strcasecmp(tmp->name, "type"))
+ continue;
+
+ if (!strcasecmp(tmp->value, "peer")) {
+ ast_destroy_realtime(var);
+ return NULL;
}
- ast_destroy_realtime(var);
+ tmp = tmp->next;
}
+
+ user = build_user(username, var, 1);
if (user) {
- /* Reference and destroy, so when our caller unrefs, we disappear */
- ASTOBJ_REF(user);
- ASTOBJ_DESTROY(user, sip_destroy_user);
+ /* Move counter from s to r... */
+ suserobjs--;
+ ruserobjs++;
+ /* Add some finishing touches, addresses, etc */
+ ast_set_flag(user, SIP_REALTIME);
}
+ ast_destroy_realtime(var);
return user;
}
@@ -1290,60 +1264,60 @@
p = find_peer(peer, NULL);
if (p) {
- found++;
- ast_copy_flags(r, p, SIP_PROMISCREDIR | SIP_USEREQPHONE | SIP_DTMF | SIP_NAT | SIP_REINVITE | SIP_INSECURE);
- r->capability = p->capability;
- if (r->rtp) {
- ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
- ast_rtp_setnat(r->rtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
- }
- if (r->vrtp) {
- ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
- ast_rtp_setnat(r->vrtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
- }
- strncpy(r->peername, p->username, sizeof(r->peername)-1);
- strncpy(r->authname, p->username, sizeof(r->authname)-1);
- strncpy(r->peersecret, p->secret, sizeof(r->peersecret)-1);
- strncpy(r->peermd5secret, p->md5secret, sizeof(r->peermd5secret)-1);
- strncpy(r->username, p->username, sizeof(r->username)-1);
- strncpy(r->tohost, p->tohost, sizeof(r->tohost)-1);
- strncpy(r->fullcontact, p->fullcontact, sizeof(r->fullcontact)-1);
- if (!r->initreq.headers && !ast_strlen_zero(p->fromdomain)) {
- if ((callhost = strchr(r->callid, '@'))) {
- strncpy(callhost + 1, p->fromdomain, sizeof(r->callid) - (callhost - r->callid) - 2);
- }
- }
- if (ast_strlen_zero(r->tohost)) {
- if (p->addr.sin_addr.s_addr)
- ast_inet_ntoa(r->tohost, sizeof(r->tohost), p->addr.sin_addr);
- else
- ast_inet_ntoa(r->tohost, sizeof(r->tohost), p->defaddr.sin_addr);
+ found++;
+ ast_copy_flags(r, p, SIP_PROMISCREDIR | SIP_USEREQPHONE | SIP_DTMF | SIP_NAT | SIP_REINVITE | SIP_INSECURE);
+ r->capability = p->capability;
+ if (r->rtp) {
+ ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
+ ast_rtp_setnat(r->rtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
+ }
+ if (r->vrtp) {
+ ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
+ ast_rtp_setnat(r->vrtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
+ }
+ strncpy(r->peername, p->username, sizeof(r->peername)-1);
+ strncpy(r->authname, p->username, sizeof(r->authname)-1);
+ strncpy(r->peersecret, p->secret, sizeof(r->peersecret)-1);
+ strncpy(r->peermd5secret, p->md5secret, sizeof(r->peermd5secret)-1);
+ strncpy(r->username, p->username, sizeof(r->username)-1);
+ strncpy(r->tohost, p->tohost, sizeof(r->tohost)-1);
+ strncpy(r->fullcontact, p->fullcontact, sizeof(r->fullcontact)-1);
+ if (!r->initreq.headers && !ast_strlen_zero(p->fromdomain)) {
+ if ((callhost = strchr(r->callid, '@'))) {
+ strncpy(callhost + 1, p->fromdomain, sizeof(r->callid) - (callhost - r->callid) - 2);
}
- if (!ast_strlen_zero(p->fromdomain))
- strncpy(r->fromdomain, p->fromdomain, sizeof(r->fromdomain)-1);
- if (!ast_strlen_zero(p->fromuser))
- strncpy(r->fromuser, p->fromuser, sizeof(r->fromuser)-1);
- r->maxtime = p->maxms;
- r->callgroup = p->callgroup;
- r->pickupgroup = p->pickupgroup;
- if (ast_test_flag(r, SIP_DTMF) == SIP_DTMF_RFC2833)
- r->noncodeccapability |= AST_RTP_DTMF;
+ }
+ if (ast_strlen_zero(r->tohost)) {
+ if (p->addr.sin_addr.s_addr)
+ ast_inet_ntoa(r->tohost, sizeof(r->tohost), p->addr.sin_addr);
else
- r->noncodeccapability &= ~AST_RTP_DTMF;
- strncpy(r->context, p->context,sizeof(r->context)-1);
- if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
- (!p->maxms || ((p->lastms >= 0) && (p->lastms <= p->maxms)))) {
- if (p->addr.sin_addr.s_addr) {
- r->sa.sin_addr = p->addr.sin_addr;
- r->sa.sin_port = p->addr.sin_port;
- } else {
- r->sa.sin_addr = p->defaddr.sin_addr;
- r->sa.sin_port = p->defaddr.sin_port;
- }
- memcpy(&r->recv, &r->sa, sizeof(r->recv));
+ ast_inet_ntoa(r->tohost, sizeof(r->tohost), p->defaddr.sin_addr);
+ }
+ if (!ast_strlen_zero(p->fromdomain))
+ strncpy(r->fromdomain, p->fromdomain, sizeof(r->fromdomain)-1);
+ if (!ast_strlen_zero(p->fromuser))
+ strncpy(r->fromuser, p->fromuser, sizeof(r->fromuser)-1);
+ r->maxtime = p->maxms;
+ r->callgroup = p->callgroup;
+ r->pickupgroup = p->pickupgroup;
+ if (ast_test_flag(r, SIP_DTMF) == SIP_DTMF_RFC2833)
+ r->noncodeccapability |= AST_RTP_DTMF;
+ else
+ r->noncodeccapability &= ~AST_RTP_DTMF;
+ strncpy(r->context, p->context,sizeof(r->context)-1);
+ if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
+ (!p->maxms || ((p->lastms >= 0) && (p->lastms <= p->maxms)))) {
+ if (p->addr.sin_addr.s_addr) {
+ r->sa.sin_addr = p->addr.sin_addr;
+ r->sa.sin_port = p->addr.sin_port;
} else {
- ASTOBJ_UNREF(p,sip_destroy_peer);
+ r->sa.sin_addr = p->defaddr.sin_addr;
+ r->sa.sin_port = p->defaddr.sin_port;
}
+ memcpy(&r->recv, &r->sa, sizeof(r->recv));
+ } else {
+ ASTOBJ_UNREF(p,sip_destroy_peer);
+ }
}
if (!p && !found) {
hostn = peer;
@@ -8644,7 +8618,7 @@
}
/*--- build_user: Initiate a SIP user structure from sip.conf ---*/
-static struct sip_user *build_user(const char *name, struct ast_variable *v)
+static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime)
{
struct sip_user *user;
int format;
@@ -8778,15 +8752,16 @@
}
/*--- build_peer: Build peer from config file ---*/
-static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int temponly)
+static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int realtime)
{
struct sip_peer *peer = NULL;
struct ast_ha *oldha = NULL;
int maskfound=0;
int obproxyfound=0;
int found=0;
+ time_t regseconds;
- if (!temponly)
+ if (!realtime)
/* Note we do NOT use find_peer here, to avoid realtime recursion */
peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name);
@@ -8797,7 +8772,7 @@
peer = malloc(sizeof(struct sip_peer));
if (peer) {
memset(peer, 0, sizeof(struct sip_peer));
- if (temponly)
+ if (realtime)
rpeerobjs++;
else
speerobjs++;
@@ -8838,7 +8813,12 @@
continue;
}
- if (!strcasecmp(v->name, "name"))
+ if (realtime && !strcasecmp(v->name, "regseconds")) {
+ if (sscanf(v->value, "%li", ®seconds) != 1)
+ regseconds = 0;
+ } else if (realtime && !strcasecmp(v->name, "ipaddr")) {
+ inet_aton(v->value, &(peer->addr.sin_addr));
+ } else if (realtime && !strcasecmp(v->name, "name"))
strncpy(peer->name, v->value, sizeof(peer->name)-1);
else if (!strcasecmp(v->name, "secret"))
strncpy(peer->secret, v->value, sizeof(peer->secret)-1);
@@ -8880,7 +8860,7 @@
ast_clear_flag(peer, SIP_DYNAMIC);
if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) {
- ASTOBJ_DESTROY(peer, sip_destroy_peer);
+ ASTOBJ_UNREF(peer, sip_destroy_peer);
return NULL;
}
}
@@ -8893,7 +8873,7 @@
inet_aton("255.255.255.255", &peer->mask);
} else if (!strcasecmp(v->name, "defaultip")) {
if (ast_get_ip(&peer->defaddr, v->value)) {
- ASTOBJ_DESTROY(peer, sip_destroy_peer);
+ ASTOBJ_UNREF(peer, sip_destroy_peer);
return NULL;
}
} else if (!strcasecmp(v->name, "permit") ||
@@ -8903,7 +8883,7 @@
maskfound++;
inet_aton(v->value, &peer->mask);
} else if (!strcasecmp(v->name, "port")) {
- if (ast_test_flag(peer, SIP_DYNAMIC))
+ if (!realtime && ast_test_flag(peer, SIP_DYNAMIC))
peer->defaddr.sin_port = htons(atoi(v->value));
else
peer->addr.sin_port = htons(atoi(v->value));
@@ -8955,6 +8935,16 @@
*/
v=v->next;
}
+ if (realtime && ast_test_flag(peer, SIP_DYNAMIC)) {
+ time_t nowtime;
+
+ time(&nowtime);
+ if ((nowtime - regseconds) > 0) {
+ memset(&peer->addr, 0, sizeof(peer->addr));
+ if (option_debug)
+ ast_log(LOG_DEBUG, "Bah, we're expired (%ld/%ld/%ld)!\n", nowtime - regseconds, regseconds, nowtime);
+ }
+ }
ast_copy_flags(peer, &peerflags, mask.flags);
if (!found && ast_test_flag(peer, SIP_DYNAMIC))
reg_source_db(peer);
@@ -9200,7 +9190,7 @@
utype = ast_variable_retrieve(cfg, cat, "type");
if (utype) {
if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
- user = build_user(cat, ast_variable_browse(cfg, cat));
+ user = build_user(cat, ast_variable_browse(cfg, cat), 0);
if (user) {
ASTOBJ_CONTAINER_LINK(&userl,user);
ASTOBJ_UNREF(user, sip_destroy_user);
More information about the svn-commits
mailing list