summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorLuigi Rizzo <rizzo@icir.org>2006-04-10 10:40:13 +0000
committerLuigi Rizzo <rizzo@icir.org>2006-04-10 10:40:13 +0000
commit47df1e2020e7eab427026e7ee63ab987a9b459b7 (patch)
treec2ae7fa04f11c7d4b5a115012a10f995233cb6f5 /channels
parent20d187661793161f1f2e789eaa3dc2cc28c51845 (diff)
- describe how sip packets are stored internally;
- remove useless braces or local variables; - simplify some code sequences; - mark with XXX a possible locking issue. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@18788 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_sip.c65
1 files changed, 43 insertions, 22 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 8f4f70074..417efe33a 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -489,6 +489,25 @@ struct sip_request {
char data[SIP_MAX_PACKET];
};
+/*
+ * A sip packet is stored into the data[] buffer, with the header followed
+ * by an empty line and the body of the message.
+ * On outgoing packets, data is accumulated in data[] with len reflecting
+ * the next available byte, headers and lines count the number of lines
+ * in both parts. There are no '\0' in data[0..len-1].
+ *
+ * On received packet, the input read from the socket is copied into data[],
+ * len is set and the string is NUL-terminated. Then a parser fills up
+ * the other fields -header[] and line[] to point to the lines of the
+ * message, rlPart1 and rlPart2 parse the first lnie as below:
+ *
+ * Requests have in the first line METHOD URI SIP/2.0
+ * rlPart1 = method; rlPart2 = uri;
+ * Responses have in the first line SIP/2.0 code description
+ * rlPart1 = SIP/2.0; rlPart2 = code + description;
+ *
+ */
+
/*! \brief structure used in transfers */
struct sip_dual {
struct ast_channel *chan1;
@@ -1345,7 +1364,6 @@ static int __sip_reliable_xmit(struct sip_pvt *p, int seqno, int resp, char *dat
pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */
if (fatal)
ast_set_flag(pkt, FLAG_FATAL);
-
if (pkt->timer_t1)
siptimer_a = pkt->timer_t1 * 2;
@@ -1492,16 +1510,14 @@ static int __sip_semi_ack(struct sip_pvt *p, int seqno, int resp, int sipmethod)
{
struct sip_pkt *cur;
int res = -1;
- char *msg = sip_methods[sipmethod].text;
- for (cur = p->packets; cur ; cur = cur->next) {
- if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
- ((ast_test_flag(cur, FLAG_RESPONSE)) ||
- (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
+ for (cur = p->packets; cur; cur = cur->next) {
+ if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp &&
+ (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) {
/* this is our baby */
if (cur->retransid > -1) {
if (option_debug > 3 && sipdebug)
- ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, msg);
+ ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
ast_sched_del(sched, cur->retransid);
}
cur->retransid = -1;
@@ -1642,6 +1658,7 @@ static void realtime_update_peer(const char *peername, struct sockaddr_in *sin,
char ipaddr[20];
char regseconds[20];
time_t nowtime;
+ const char *fc = fullcontact ? "fullcontact" : NULL;
time(&nowtime);
nowtime += expirey;
@@ -1649,10 +1666,9 @@ static void realtime_update_peer(const char *peername, struct sockaddr_in *sin,
ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr);
snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
- if (fullcontact)
- ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, "fullcontact", fullcontact, NULL);
- else
- ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, NULL);
+ ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
+ "port", port, "regseconds", regseconds,
+ "username", username, fc, fullcontact, NULL); /* note fc _can_ be NULL */
}
/*! \brief Automatically add peer extension to dial plan */
@@ -1895,6 +1911,8 @@ static struct sip_user *find_user(const char *name, int realtime)
/*! \brief Create address structure from peer reference */
static int create_addr_from_peer(struct sip_pvt *r, struct sip_peer *peer)
{
+ int natflags;
+
if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) &&
(!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) {
r->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr;
@@ -1911,15 +1929,16 @@ static int create_addr_from_peer(struct sip_pvt *r, struct sip_peer *peer)
r->vrtp = NULL;
}
r->prefs = peer->prefs;
+ natflags = ast_test_flag(&r->flags[0], SIP_NAT) & SIP_NAT_ROUTE;
if (r->rtp) {
if (option_debug)
- ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(&r->flags[0], SIP_NAT) & SIP_NAT_ROUTE));
- ast_rtp_setnat(r->rtp, (ast_test_flag(&r->flags[0], SIP_NAT) & SIP_NAT_ROUTE));
+ ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", natflags);
+ ast_rtp_setnat(r->rtp, natflags);
}
if (r->vrtp) {
if (option_debug)
- ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(&r->flags[0], SIP_NAT) & SIP_NAT_ROUTE));
- ast_rtp_setnat(r->vrtp, (ast_test_flag(&r->flags[0], SIP_NAT) & SIP_NAT_ROUTE));
+ ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", natflags);
+ ast_rtp_setnat(r->vrtp, natflags);
}
ast_string_field_set(r, peername, peer->username);
ast_string_field_set(r, authname, peer->username);
@@ -2048,6 +2067,7 @@ static int auto_congest(void *nothing)
ast_mutex_lock(&p->lock);
p->initid = -1;
if (p->owner) {
+ /* XXX fails on possible deadlock */
if (!ast_mutex_trylock(&p->owner->lock)) {
ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name);
ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
@@ -2214,9 +2234,8 @@ static void __sip_destroy(struct sip_pvt *p, int lockowner)
/* remove all current packets in this dialog */
while((cp = p->packets)) {
p->packets = p->packets->next;
- if (cp->retransid > -1) {
+ if (cp->retransid > -1)
ast_sched_del(sched, cp->retransid);
- }
free(cp);
}
if (p->chanvars) {
@@ -2685,16 +2704,18 @@ static int sip_write(struct ast_channel *ast, struct ast_frame *frame)
Basically update any ->owner links */
static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
{
+ int ret = -1;
struct sip_pvt *p = newchan->tech_pvt;
+
ast_mutex_lock(&p->lock);
- if (p->owner != oldchan) {
+ if (p->owner != oldchan)
ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
- ast_mutex_unlock(&p->lock);
- return -1;
+ else {
+ p->owner = newchan;
+ ret = 0;
}
- p->owner = newchan;
ast_mutex_unlock(&p->lock);
- return 0;
+ return ret;
}
/*! \brief Send DTMF character on SIP channel