diff options
author | Matthew Nicholson <mnicholson@digium.com> | 2009-02-06 16:28:19 +0000 |
---|---|---|
committer | Matthew Nicholson <mnicholson@digium.com> | 2009-02-06 16:28:19 +0000 |
commit | 647b68ec233b4ecb7a5568dfe4fab41852e827fa (patch) | |
tree | f78da3f0cca00925437704772a64f7de2ea2b523 /channels | |
parent | b2484d7db9680d902a557b473790b2a4bac8c888 (diff) |
Merged revisions 173917 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r173917 | mnicholson | 2009-02-06 10:20:23 -0600 (Fri, 06 Feb 2009) | 7 lines
Limit the addition of the Contact header in SIP responses according to various
SIP RFCs.
(closes issue #13602)
Reported by: hjourdain
Tested by: mnicholson
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@173952 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_sip.c | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 1ff034e0f..98a3a75c1 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -2512,6 +2512,7 @@ static int init_req(struct sip_request *req, int sipmethod, const char *recip); static int reqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch); static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod); static int init_resp(struct sip_request *resp, const char *msg); +static inline int resp_needs_contact(const char *msg, enum sipmethod method); static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req); static const struct sockaddr_in *sip_real_dst(const struct sip_pvt *p); static void build_via(struct sip_pvt *p); @@ -8378,6 +8379,66 @@ static int init_req(struct sip_request *req, int sipmethod, const char *recip) return 0; } +/*! \brief Test if this response needs a contact header */ +static inline int resp_needs_contact(const char *msg, enum sipmethod method) { + /* Requirements for Contact header inclusion in responses generated + * from the header tables found in the following RFCs. Where the + * Contact header was marked mandatory (m) or optional (o) this + * function returns 1. + * + * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER) + * - RFC 2976 (INFO) + * - RFC 3262 (PRACK) + * - RFC 3265 (SUBSCRIBE, NOTIFY) + * - RFC 3311 (UPDATE) + * - RFC 3428 (MESSAGE) + * - RFC 3515 (REFER) + * - RFC 3903 (PUBLISH) + */ + + switch (method) { + /* 1xx, 2xx, 3xx, 485 */ + case SIP_INVITE: + case SIP_UPDATE: + case SIP_SUBSCRIBE: + case SIP_NOTIFY: + if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3)) + return 1; + break; + + /* 2xx, 3xx, 485 */ + case SIP_REGISTER: + case SIP_OPTIONS: + if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3)) + return 1; + break; + + /* 3xx, 485 */ + case SIP_BYE: + case SIP_PRACK: + case SIP_MESSAGE: + case SIP_PUBLISH: + if (msg[0] == '3' || !strncmp(msg, "485", 3)) + return 1; + break; + + /* 2xx, 3xx, 4xx, 5xx, 6xx */ + case SIP_REFER: + if (msg[0] >= '2' && msg[0] <= '6') + return 1; + break; + + /* contact will not be included for everything else */ + case SIP_ACK: + case SIP_CANCEL: + case SIP_INFO: + case SIP_PING: + default: + return 0; + } + return 0; +} + /*! \brief Prepare SIP response packet */ static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req) @@ -8431,7 +8492,7 @@ static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); add_header(resp, "Contact", contact); /* Not when we unregister */ } - } else if (msg[0] != '4' && !ast_strlen_zero(p->our_contact)) { + } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) { add_header(resp, "Contact", p->our_contact); } |