diff --git a/modules/presence/doc/presence_admin.xml b/modules/presence/doc/presence_admin.xml index 0c82bcdf81..fb0af88626 100644 --- a/modules/presence/doc/presence_admin.xml +++ b/modules/presence/doc/presence_admin.xml @@ -300,13 +300,17 @@ modparam("presence", "max_expires_publish", 3600)
<varname>server_address</varname> (str) - The optional presence server address which will become the value of + The optional presence server URI address which will become the value of Contact header filed for 200OK replies to Subscribe and Publish and in Notify messages. - If not set (as it is by default), OpenSIPS will generate the Conact URI - based on the interface it received the SIP traffic. + NOTE: this must be a fully formated SIP URI, with port and transport + parameter if the case. + + + If not set (as it is by default), OpenSIPS will generate the Contact + URI based on the interface it received the SIP traffic. Set <varname>server_address</varname> parameter diff --git a/modules/presence/notify.c b/modules/presence/notify.c index 8744d33162..67dc76f4b7 100644 --- a/modules/presence/notify.c +++ b/modules/presence/notify.c @@ -148,10 +148,10 @@ int build_str_hdr(subs_t* subs, int is_body, str* hdr, str* extra_hdrs) } status.len = strlen(status.s); - len = 7 /*Event: */ + subs->event->name.len +4 /*;id=*/+ subs->event_id.len+ - CRLF_LEN + 10 /*Contact: <*/ + subs->local_contact.len + 1/*>*/ + - ((subs->sockinfo && subs->sockinfo->proto!=PROTO_UDP)? - 15/*";transport=xxxx"*/:0) + CRLF_LEN + 20 /*Subscription-State: */ + + len = 7 /*Event: */ + subs->event->name.len + 4 /*;id=*/ + + subs->event_id.len + CRLF_LEN + + 10 /*Contact: <*/ + subs->local_contact.len + 1/*>*/ + CRLF_LEN + + 20 /*Subscription-State: */ + status.len + ((subs->status== TERMINATED_STATUS)?(10/*;reason=*/+ subs->reason.len):9/*expires=*/ + lexpire_len) + CRLF_LEN + (is_body? (14 /*Content-Type: */+subs->event->content_type.len + CRLF_LEN):0); @@ -185,33 +185,14 @@ int build_str_hdr(subs_t* subs, int is_body, str* hdr, str* extra_hdrs) memcpy(p, subs->event_id.s, subs->event_id.len); p += subs->event_id.len; } - memcpy(p, CRLF, CRLF_LEN); - p += CRLF_LEN; - memcpy(p ,"Contact: <", 10); - p += 10; + memcpy(p ,CRLF "Contact: <", CRLF_LEN+10); + p += CRLF_LEN+10; memcpy(p, subs->local_contact.s, subs->local_contact.len); p += subs->local_contact.len; - if (subs->sockinfo && subs->sockinfo->proto!=PROTO_UDP) - { - memcpy(p,";transport=",11); - p += 11; - p = proto2str(subs->sockinfo->proto, p); - if (p == NULL) - { - LM_ERR("invalid proto\n"); - pkg_free(hdr->s); - return -1; - } - } - *(p++) = '>'; - - memcpy(p, CRLF, CRLF_LEN); - p += CRLF_LEN; - - memcpy(p, "Subscription-State: ", 20); - p+= 20; + memcpy(p, ">" CRLF "Subscription-State: " , 1+CRLF_LEN+20); + p += 1+CRLF_LEN+20; memcpy(p, status.s, status.len); p += status.len; diff --git a/modules/presence/subscribe.c b/modules/presence/subscribe.c index 6f27447aa8..1f6f2e69d9 100644 --- a/modules/presence/subscribe.c +++ b/modules/presence/subscribe.c @@ -70,9 +70,7 @@ int send_2XX_reply(struct sip_msg * msg, int reply_code, int lexpire, lexpire_s = int2str((unsigned long)lexpire, &lexpire_len); len = 9 /*"Expires: "*/ + lexpire_len + CRLF_LEN - + 10 /*"Contact: <"*/ + local_contact->len + 1 /*">"*/ - + ((msg->rcv.proto!=PROTO_UDP)?15/*";transport=xxxx"*/:0) - + CRLF_LEN; + + 10 /*"Contact: <"*/ + local_contact->len + 1 /*">"*/ + CRLF_LEN; hdr_append = (char *)pkg_malloc( len ); if(hdr_append == NULL) @@ -86,25 +84,13 @@ int send_2XX_reply(struct sip_msg * msg, int reply_code, int lexpire, p += 9; memcpy(p,lexpire_s,lexpire_len); p += lexpire_len; - memcpy(p,CRLF,CRLF_LEN); - p += CRLF_LEN; /* contact header */ - memcpy(p,"Contact: <", 10); - p += 10; + memcpy(p, CRLF "Contact: <", CRLF_LEN+10); + p += CRLF_LEN + 10; memcpy(p,local_contact->s,local_contact->len); p += local_contact->len; - if (msg->rcv.proto!=PROTO_UDP) { - memcpy(p,";transport=",11); - p += 11; - p = proto2str(msg->rcv.proto, p); - if (p==NULL) { - LM_ERR("invalid proto\n"); - goto error; - } - } - *(p++) = '>'; - memcpy(p, CRLF, CRLF_LEN); - p += CRLF_LEN; + memcpy(p, ">" CRLF, 1+CRLF_LEN); + p += 1+CRLF_LEN; if (add_lump_rpl( msg, hdr_append, p-hdr_append, LUMP_RPL_HDR)==0 ) { @@ -753,8 +739,8 @@ int handle_subscribe(struct sip_msg* msg, char* force_active_param, char* tag) } -int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp, int* init_req, - str local_address) +int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp, + int* init_req, str local_address) { str rec_route= {0, 0}; int rt = 0; diff --git a/modules/presence/utils_func.h b/modules/presence/utils_func.h index c8ed9d4f03..3b62c80e6f 100644 --- a/modules/presence/utils_func.h +++ b/modules/presence/utils_func.h @@ -36,7 +36,6 @@ #include "../../str.h" #include "../../parser/msg_parser.h" -#define LCONTACT_BUF_SIZE 1024 #define BAD_EVENT_CODE 489 static inline int uandd_to_uri(str user, str domain, str *out) @@ -70,52 +69,60 @@ static inline int uandd_to_uri(str user, str domain, str *out) return 0; } -/* Build an contact URI but without the "transport" param - this is to be - * added when a send is done, depending on the used interface. +/* Build an contact URI with port and transport parameter */ static inline int get_local_contact(struct socket_info *sock, str* contact) { - static char buf[LCONTACT_BUF_SIZE]; + static char buf[MAX_URI_SIZE]; + char *p; - contact->s = buf; - contact->len= 0; - memset(buf, 0, LCONTACT_BUF_SIZE); + p = buf; /* write "sip:ip" */ - memcpy(contact->s+contact->len, "sip:", 4); - contact->len+= 4; + memcpy( p, "sip:", 4); + p += 4; /* if advertised address is set for this interface, use this one */ if (sock->adv_name_str.s) { - memcpy(contact->s+contact->len, sock->adv_name_str.s, sock->adv_name_str.len); - contact->len += sock->adv_name_str.len; + memcpy( p, sock->adv_name_str.s, sock->adv_name_str.len); + p += sock->adv_name_str.len; } else { - memcpy(contact->s+contact->len, sock->address_str.s, sock->address_str.len); - contact->len += sock->address_str.len; - } - if(contact->len> LCONTACT_BUF_SIZE - 21) - { - LM_ERR("buffer overflow\n"); - return -1; + memcpy( p, sock->address_str.s, sock->address_str.len); + p += sock->address_str.len; } + if ( (p-buf) < 6/*:nnnnn*/) + goto overflow; /* write ":port" if port defined */ if (sock->adv_name_str.s) { if(sock->adv_port_str.s) { - *(contact->s+(contact->len++)) = ':'; - memcpy(contact->s+contact->len, sock->adv_port_str.s, sock->adv_port_str.len); - contact->len += sock->adv_port_str.len; + *(p++) = ':'; + memcpy( p, sock->adv_port_str.s, sock->adv_port_str.len); + p += sock->adv_port_str.len; } - } - else + } else if (sock->port_no_str.len) { - *(contact->s+(contact->len++)) = ':'; - memcpy(contact->s+contact->len, sock->port_no_str.s, sock->port_no_str.len); - contact->len += sock->port_no_str.len; + *(p++) = ':'; + memcpy( p, sock->port_no_str.s, sock->port_no_str.len); + p += sock->port_no_str.len; + } + + if (sock->proto!=PROTO_UDP) { + if ( (p-buf) < 15/*;transport=xxxx*/) + goto overflow; + memcpy( p, ";transport=", 11); + p += 11; + p = proto2str(sock->proto, p); } + /* success */ + contact->s = buf; + contact->len = (int)(p-buf); return 0; +overflow: + LM_ERR("local contact gets too long, exceeding %d\n",MAX_URI_SIZE); + return -1; } int a_to_i (char *s,int len);