diff options
author | Luigi Rizzo <rizzo@icir.org> | 2006-04-10 10:40:13 +0000 |
---|---|---|
committer | Luigi Rizzo <rizzo@icir.org> | 2006-04-10 10:40:13 +0000 |
commit | 47df1e2020e7eab427026e7ee63ab987a9b459b7 (patch) | |
tree | c2ae7fa04f11c7d4b5a115012a10f995233cb6f5 /channels | |
parent | 20d187661793161f1f2e789eaa3dc2cc28c51845 (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.c | 65 |
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 |