]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 271690 via svnmerge from
authorMatthew Nicholson <mnicholson@digium.com>
Tue, 22 Jun 2010 13:05:16 +0000 (13:05 +0000)
committerMatthew Nicholson <mnicholson@digium.com>
Tue, 22 Jun 2010 13:05:16 +0000 (13:05 +0000)
https://origsvn.digium.com/svn/asterisk/trunk

................
  r271690 | mnicholson | 2010-06-22 07:58:28 -0500 (Tue, 22 Jun 2010) | 18 lines

  Merged revisions 271689 via svnmerge from
  https://origsvn.digium.com/svn/asterisk/branches/1.4

  ........
    r271689 | mnicholson | 2010-06-22 07:52:27 -0500 (Tue, 22 Jun 2010) | 8 lines

    Modify chan_sip's packet generation api to automatically calculate the Content-Length.  This is done by storing packet content in a buffer until it is actually time to send the packet, at which time the size of the packet is calculated.  This change was made to ensure that the Content-Length is always correct.

    (closes issue #17326)
    Reported by: kenner
    Tested by: mnicholson, kenner

    Review: https://reviewboard.asterisk.org/r/693/
  ........

  This change also adds an ast_str_copy_string() function (similar to ast_copy_string), that copies one ast_str into another, properly handling embedded nulls.
................

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.2@271691 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c
configs/sip_notify.conf.sample
include/asterisk/strings.h

index 9bbf75946183c4ccecf4246a872b61dffd9c7f3a..3c20026564901242a3238b579dabe96d13bb92e6 100644 (file)
@@ -1195,7 +1195,7 @@ struct sip_socket {
  *
  * For outgoing packets, we initialize the fields with init_req() or init_resp()
  * (which fills the first line to "METHOD uri SIP/2.0" or "SIP/2.0 code text"),
- * and then fill the rest with add_header() and add_line().
+ * and then fill the rest with add_header() and add_content().
  * The \r\n at the end of the line are still there, so the get_header()
  * and similar functions don't work on these packets. 
  * \endverbatim
@@ -1217,6 +1217,7 @@ struct sip_request {
        /* Array of offsets into the request string of each SDP line*/
        ptrdiff_t line[SIP_MAX_LINES];
        struct ast_str *data;   
+       struct ast_str *content;
        /* XXX Do we need to unref socket.ser when the request goes away? */
        struct sip_socket socket;       /*!< The socket used for this request */
        AST_LIST_ENTRY(sip_request) next;
@@ -2570,6 +2571,7 @@ static void *sip_tcp_worker_fn(void *);
 /*--- Constructing requests and responses */
 static void initialize_initreq(struct sip_pvt *p, struct sip_request *req);
 static int init_req(struct sip_request *req, int sipmethod, const char *recip);
+static void deinit_req(struct sip_request *req);
 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);
@@ -2584,8 +2586,8 @@ static void build_callid_pvt(struct sip_pvt *pvt);
 static void build_callid_registry(struct sip_registry *reg, struct in_addr ourip, const char *fromdomain);
 static void make_our_tag(char *tagbuf, size_t len);
 static int add_header(struct sip_request *req, const char *var, const char *value);
-static int add_header_contentLength(struct sip_request *req, int len);
-static int add_line(struct sip_request *req, const char *line);
+static int add_content(struct sip_request *req, const char *line);
+static int finalize_content(struct sip_request *req);
 static int add_text(struct sip_request *req, const char *text);
 static int add_digit(struct sip_request *req, char digit, unsigned int duration, int mode);
 static int add_vidupdate(struct sip_request *req);
@@ -3079,14 +3081,8 @@ cleanup:
                ao2_t_unlink(threadt, me, "Removing tcptls helper thread, thread is closing");
                ao2_t_ref(me, -1, "Removing tcp_helper_threads threadinfo ref");
        }
-       if (reqcpy.data) {
-               ast_free(reqcpy.data);
-       }
-
-       if (req.data) {
-               ast_free(req.data);
-               req.data = NULL;
-       }
+       deinit_req(&reqcpy);
+       deinit_req(&req);
 
        /* if client, we own the parent session arguments and must decrement ref */
        if (ca) {
@@ -4204,6 +4200,7 @@ static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmitty
 {
        int res;
 
+       finalize_content(req);
        add_blank(req);
        if (sip_debug_test_pvt(p)) {
                const struct sockaddr_in *dst = sip_real_dst(p);
@@ -4218,7 +4215,7 @@ static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmitty
                parse_copy(&tmp, req);
                append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data->str, get_header(&tmp, "CSeq"), 
                        (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? REQ_OFFSET_TO_STR(&tmp, rlPart2) : sip_methods[tmp.method].text);
-               ast_free(tmp.data);
+               deinit_req(&tmp);
        }
 
        /* If we are sending a final response to an INVITE, stop retransmitting provisional responses */
@@ -4229,8 +4226,7 @@ static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmitty
        res = (reliable) ?
                 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
                __sip_xmit(p, req->data, req->len);
-       ast_free(req->data);
-       req->data = NULL;
+       deinit_req(req);
        if (res > 0)
                return 0;
        return res;
@@ -4248,6 +4244,7 @@ static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittyp
                p->sa = p->outboundproxy->ip;
        }
 
+       finalize_content(req);
        add_blank(req);
        if (sip_debug_test_pvt(p)) {
                if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE))
@@ -4259,15 +4256,12 @@ static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittyp
                struct sip_request tmp = { .rlPart1 = 0, };
                parse_copy(&tmp, req);
                append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data->str, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text);
-               ast_free(tmp.data);
+               deinit_req(&tmp);
        }
        res = (reliable) ?
                __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
                __sip_xmit(p, req->data, req->len);
-       if (req->data) {
-               ast_free(req->data);
-               req->data = NULL;
-       }
+       deinit_req(req);
        return res;
 }
 
@@ -5591,8 +5585,7 @@ static void __sip_destroy(struct sip_pvt *p, int lockowner, int lockdialoglist)
                free_old_route(p->route);
                p->route = NULL;
        }
-       if (p->initreq.data)
-               ast_free(p->initreq.data);
+       deinit_req(&p->initreq);
 
        /* Destroy Session-Timers if allocated */
        if (p->stimer) {
@@ -9100,30 +9093,37 @@ static int add_header(struct sip_request *req, const char *var, const char *valu
        return 0;       
 }
 
-/*! \brief Add 'Content-Length' header to SIP message */
-static int add_header_contentLength(struct sip_request *req, int len)
+/*! \brief Add 'Content-Length' header and content to SIP message */
+static int finalize_content(struct sip_request *req)
 {
        char clen[10];
 
-       snprintf(clen, sizeof(clen), "%d", len);
-       return add_header(req, "Content-Length", clen);
+       if (req->lines) {
+               ast_log(LOG_WARNING, "finalize_content() called on a message that has already been finalized\n");
+               return -1;
+       }
+
+       snprintf(clen, sizeof(clen), "%zd", ast_str_strlen(req->content));
+       add_header(req, "Content-Length", clen);
+
+       if (ast_str_strlen(req->content)) {
+               ast_str_append(&req->data, 0, "\r\n%s", ast_str_buffer(req->content));
+               req->len = ast_str_strlen(req->data);
+       }
+       req->lines = ast_str_strlen(req->content) ? 1 : 0;
+       return 0;
 }
 
 /*! \brief Add content (not header) to SIP message */
-static int add_line(struct sip_request *req, const char *line)
+static int add_content(struct sip_request *req, const char *line)
 {
-       if (req->lines == SIP_MAX_LINES)  {
-               ast_log(LOG_WARNING, "Out of SIP line space\n");
+       if (req->lines) {
+               ast_log(LOG_WARNING, "Can't add more content when the content has been finalized\n");
                return -1;
        }
-       if (!req->lines)
-               /* Add extra empty return */
-               req->len += ast_str_append(&req->data, 0, "\r\n");
-       req->line[req->lines] = req->len;
-       ast_str_append(&req->data, 0, "%s", line);
-       req->len = ast_str_strlen(req->data);
-       req->lines++;
-       return 0;       
+
+       ast_str_append(&req->content, 0, "%s", line);
+       return 0;
 }
 
 /*! \brief Copy one header field from one request to another */
@@ -9336,12 +9336,20 @@ static int init_resp(struct sip_request *resp, const char *msg)
        memset(resp, 0, sizeof(*resp));
        resp->method = SIP_RESPONSE;
        if (!(resp->data = ast_str_create(SIP_MIN_PACKET)))
-               return -1;
+               goto e_return;
+       if (!(resp->content = ast_str_create(SIP_MIN_PACKET)))
+               goto e_free_data;
        resp->header[0] = 0;
        ast_str_set(&resp->data, 0, "SIP/2.0 %s\r\n", msg);
        resp->len = resp->data->used;
        resp->headers++;
        return 0;
+
+e_free_data:
+       ast_free(resp->data);
+       resp->data = NULL;
+e_return:
+       return -1;
 }
 
 /*! \brief Initialize SIP request */
@@ -9350,15 +9358,37 @@ static int init_req(struct sip_request *req, int sipmethod, const char *recip)
        /* Initialize a request */
        memset(req, 0, sizeof(*req));
        if (!(req->data = ast_str_create(SIP_MIN_PACKET)))
-               return -1;
+               goto e_return;
+       if (!(req->content = ast_str_create(SIP_MIN_PACKET)))
+               goto e_free_data;
        req->method = sipmethod;
        req->header[0] = 0;
        ast_str_set(&req->data, 0, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
        req->len = ast_str_strlen(req->data);
        req->headers++;
        return 0;
+
+e_free_data:
+       ast_free(req->data);
+       req->data = NULL;
+e_return:
+       return -1;
+}
+
+/*! \brief Deinitialize SIP response/request */
+static void deinit_req(struct sip_request *req)
+{
+       if (req->data) {
+               ast_free(req->data);
+               req->data = NULL;
+       }
+       if (req->content) {
+               ast_free(req->content);
+               req->content = NULL;
+       }
 }
 
+
 /*! \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
@@ -9632,7 +9662,6 @@ static int __transmit_response(struct sip_pvt *p, const char *msg, const struct
                return -1;
        }
        respprep(&resp, p, msg, req);
-       add_header_contentLength(&resp, 0);
        /* If we are cancelling an incoming invite for some reason, add information
                about the reason why we are doing this in clear text */
        if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) {
@@ -9727,7 +9756,6 @@ static int transmit_response_with_unsupported(struct sip_pvt *p, const char *msg
        respprep(&resp, p, msg, req);
        append_date(&resp);
        add_header(&resp, "Unsupported", unsupported);
-       add_header_contentLength(&resp, 0);
        return send_response(p, &resp, XMIT_UNRELIABLE, 0);
 }
 
@@ -9742,8 +9770,6 @@ static int transmit_response_with_minse(struct sip_pvt *p, const char *msg, cons
 
        snprintf(minse_str, sizeof(minse_str), "%d", minse_int);
        add_header(&resp, "Min-SE", minse_str);
-
-       add_header_contentLength(&resp, 0);
        return send_response(p, &resp, XMIT_UNRELIABLE, 0);
 }
 
@@ -9774,7 +9800,6 @@ static int transmit_response_with_date(struct sip_pvt *p, const char *msg, const
        struct sip_request resp;
        respprep(&resp, p, msg, req);
        append_date(&resp);
-       add_header_contentLength(&resp, 0);
        return send_response(p, &resp, XMIT_UNRELIABLE, 0);
 }
 
@@ -9784,7 +9809,6 @@ static int transmit_response_with_allow(struct sip_pvt *p, const char *msg, cons
        struct sip_request resp;
        respprep(&resp, p, msg, req);
        add_header(&resp, "Accept", "application/sdp");
-       add_header_contentLength(&resp, 0);
        return send_response(p, &resp, reliable, 0);
 }
 
@@ -9804,7 +9828,6 @@ static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, const
        snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", sip_cfg.realm, randdata, stale ? ", stale=true" : "");
        respprep(&resp, p, msg, req);
        add_header(&resp, header, tmp);
-       add_header_contentLength(&resp, 0);
        append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount);
        return send_response(p, &resp, reliable, seqno);
 }
@@ -9827,8 +9850,7 @@ static int add_text(struct sip_request *req, const char *text)
 {
        /* XXX Convert \n's to \r\n's XXX */
        add_header(req, "Content-Type", "text/plain;charset=UTF-8");
-       add_header_contentLength(req, strlen(text));
-       add_line(req, text);
+       add_content(req, text);
        return 0;
 }
 
@@ -9852,14 +9874,12 @@ static int add_digit(struct sip_request *req, char digit, unsigned int duration,
                        event = atoi(&digit);
                snprintf(tmp, sizeof(tmp), "%d\r\n", event);
                add_header(req, "Content-Type", "application/dtmf");
-               add_header_contentLength(req, strlen(tmp));
-               add_line(req, tmp);
+               add_content(req, tmp);
        } else {
                /* Application/dtmf-relay as documented by Cisco */
                snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
                add_header(req, "Content-Type", "application/dtmf-relay");
-               add_header_contentLength(req, strlen(tmp));
-               add_line(req, tmp);
+               add_content(req, tmp);
        }
        return 0;
 }
@@ -9879,8 +9899,7 @@ static int add_vidupdate(struct sip_request *req)
                "  </vc_primitive>\r\n"
                " </media_control>\r\n";
        add_header(req, "Content-Type", "application/media_control+xml");
-       add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space));
-       add_line(req, xml_is_a_huge_waste_of_space);
+       add_content(req, xml_is_a_huge_waste_of_space);
        return 0;
 }
 
@@ -10081,7 +10100,6 @@ static void get_our_media_address(struct sip_pvt *p, int needvideo,
 */
 static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int oldsdp, int add_audio, int add_t38)
 {
-       int len = 0;
        int alreadysent = 0;
 
        struct sockaddr_in sin;
@@ -10372,55 +10390,43 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
        if (needtext)
                ast_str_append(&m_text, 0, "\r\n");
 
-       len = strlen(version) + strlen(subject) + strlen(owner) +
-               strlen(connection) + strlen(session_time);
-       if (needaudio)
-               len += m_audio->used + a_audio->used + strlen(hold);
-       if (needvideo) /* only if video response is appropriate */
-               len += m_video->used + a_video->used + strlen(bandwidth) + strlen(hold);
-       if (needtext) /* only if text response is appropriate */
-               len += m_text->used + a_text->used + strlen(hold);
-       if (add_t38)
-               len += m_modem->used + a_modem->used;
-
        add_header(resp, "Content-Type", "application/sdp");
-       add_header_contentLength(resp, len);
-       add_line(resp, version);
-       add_line(resp, owner);
-       add_line(resp, subject);
-       add_line(resp, connection);
+       add_content(resp, version);
+       add_content(resp, owner);
+       add_content(resp, subject);
+       add_content(resp, connection);
        if (needvideo)          /* only if video response is appropriate */
-               add_line(resp, bandwidth);
-       add_line(resp, session_time);
+               add_content(resp, bandwidth);
+       add_content(resp, session_time);
        if (needaudio) {
-               add_line(resp, m_audio->str);
-               add_line(resp, a_audio->str);
-               add_line(resp, hold);
+               add_content(resp, m_audio->str);
+               add_content(resp, a_audio->str);
+               add_content(resp, hold);
        } else if (p->offered_media[SDP_AUDIO].offered) {
                snprintf(dummy_answer, sizeof(dummy_answer), "m=audio 0 RTP/AVP %s\r\n", p->offered_media[SDP_AUDIO].text);
-               add_line(resp, dummy_answer);
+               add_content(resp, dummy_answer);
        }
        if (needvideo) { /* only if video response is appropriate */
-               add_line(resp, m_video->str);
-               add_line(resp, a_video->str);
-               add_line(resp, hold);   /* Repeat hold for the video stream */
+               add_content(resp, m_video->str);
+               add_content(resp, a_video->str);
+               add_content(resp, hold);        /* Repeat hold for the video stream */
        } else if (p->offered_media[SDP_VIDEO].offered) {
                snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].text);
-               add_line(resp, dummy_answer);
+               add_content(resp, dummy_answer);
        }
        if (needtext) { /* only if text response is appropriate */
-               add_line(resp, m_text->str);
-               add_line(resp, a_text->str);
-               add_line(resp, hold);   /* Repeat hold for the text stream */
+               add_content(resp, m_text->str);
+               add_content(resp, a_text->str);
+               add_content(resp, hold);        /* Repeat hold for the text stream */
        } else if (p->offered_media[SDP_TEXT].offered) {
                snprintf(dummy_answer, sizeof(dummy_answer), "m=text 0 RTP/AVP %s\r\n", p->offered_media[SDP_TEXT].text);
-               add_line(resp, dummy_answer);
+               add_content(resp, dummy_answer);
        }
        if (add_t38) {
-               add_line(resp, m_modem->str);
-               add_line(resp, a_modem->str);
+               add_content(resp, m_modem->str);
+               add_content(resp, a_modem->str);
        } else if (p->offered_media[SDP_IMAGE].offered) {
-               add_line(resp, "m=image 0 udptl t38\r\n");
+               add_content(resp, "m=image 0 udptl t38\r\n");
        }
 
        /* Update lastrtprx when we send our SDP */
@@ -10454,25 +10460,29 @@ static int transmit_response_with_t38_sdp(struct sip_pvt *p, char *msg, struct s
 /*! \brief copy SIP request (mostly used to save request for responses) */
 static void copy_request(struct sip_request *dst, const struct sip_request *src)
 {
+       /* XXX this function can encounter memory allocation errors, perhaps it
+        * should return a value */
+
        struct ast_str *duplicate = dst->data;
+       struct ast_str *duplicate_content = dst->content;
 
-       /* First copy stuff */
+       /* copy the entire request then restore the original data and content
+        * members from the dst request */
        memcpy(dst, src, sizeof(*dst));
        dst->data = duplicate;
+       dst->content = duplicate_content;
 
-       /* All these + 1's are to account for the need to include the NULL terminator
-        * Using typical string functions like ast_copy_string or ast_str_set will not
-        * work in this case because the src's data string is riddled with \0's all over
-        * the place and so a memcpy is the only way to accurately copy the string
-        */
-
-       if (!dst->data && !(dst->data = ast_str_create(src->data->used + 1)))
+       /* copy the data into the dst request */
+       if (!dst->data && !(dst->data = ast_str_create(ast_str_strlen(src->data) + 1)))
                return;
-       else if (dst->data->len < src->data->used + 1)
-               ast_str_make_space(&dst->data, src->data->used + 1);
-               
-       memcpy(dst->data->str, src->data->str, src->data->used + 1);
-       dst->data->used = src->data->used;
+       ast_str_copy_string(&dst->data, src->data);
+
+       /* copy the content into the dst request (if it exists) */
+       if (src->content) {
+               if (!dst->content && !(dst->content = ast_str_create(ast_str_strlen(src->content) + 1)))
+                       return;
+               ast_str_copy_string(&dst->content, src->content);
+       }
 }
 
 /*! \brief Used for 200 OK and 183 early media 
@@ -11000,10 +11010,6 @@ static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init)
                        add_sdp(&req, p, FALSE, FALSE, TRUE);
                } else if (p->rtp) 
                        add_sdp(&req, p, FALSE, TRUE, FALSE);
-       } else {
-               if (!p->notify_headers) {
-                       add_header_contentLength(&req, 0);
-               }
        }
 
        if (!p->initreq.headers || init > 2)
@@ -11317,8 +11323,7 @@ static int transmit_state_notify(struct sip_pvt *p, int state, int full, int tim
                break;
        }
 
-       add_header_contentLength(&req, tmp->used);
-       add_line(&req, tmp->str);
+       add_content(&req, tmp->str);
 
        p->pendinginvite = p->ocseq;    /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */
 
@@ -11371,8 +11376,7 @@ static int transmit_notify_with_mwi(struct sip_pvt *p, int newmsgs, int oldmsgs,
                        add_header(&req, "Subscription-State", "terminated;reason=timeout");
        }
 
-       add_header_contentLength(&req, out->used);
-       add_line(&req, out->str);
+       add_content(&req, out->str);
 
        if (!p->initreq.headers) 
                initialize_initreq(p, &req);
@@ -11394,8 +11398,7 @@ static int transmit_notify_with_sipfrag(struct sip_pvt *p, int cseq, char *messa
        add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
 
        snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
-       add_header_contentLength(&req, strlen(tmp));
-       add_line(&req, tmp);
+       add_content(&req, tmp);
 
        if (!p->initreq.headers)
                initialize_initreq(p, &req);
@@ -11415,6 +11418,12 @@ static int transmit_notify_custom(struct sip_pvt *p, struct ast_variable *vars)
        add_header(&req, newvar->name, newvar->value);
        for (var = vars; var; var = var->next) {
                char buf[512];
+
+               if (!strcasecmp(var->name, "Content-Length")) {
+                       ast_debug(2, "Ignoring pair %s=%s\n", var->name, var->value);
+                       continue; /* ignore content-length, it is calculated automatically */
+               }
+
                ast_debug(2, "  Adding pair %s=%s\n", var->name, var->value);
                ast_copy_string(buf, var->value, sizeof(buf));
                add_header(&req, var->name, ast_unescape_semicolon(buf));
@@ -11845,7 +11854,6 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
        snprintf(tmp, sizeof(tmp), "%d", r->expiry);
        add_header(&req, "Expires", tmp);
        add_header(&req, "Contact", p->our_contact);
-       add_header_contentLength(&req, 0);
 
        initialize_initreq(p, &req);
        if (sip_debug_test_pvt(p)) {
@@ -11990,7 +11998,6 @@ static int transmit_request(struct sip_pvt *p, int sipmethod, int seqno, enum xm
        if (sipmethod == SIP_CANCEL && p->answered_elsewhere) 
                add_header(&resp, "Reason", "SIP;cause=200;text=\"Call completed elsewhere\"");
 
-       add_header_contentLength(&resp, 0);
        return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
 }
 
@@ -12037,7 +12044,6 @@ static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int seqn
                add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
        }
 
-       add_header_contentLength(&resp, 0);
        return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);      
 }
 
@@ -18806,8 +18812,7 @@ static void *sip_park_thread(void *stuff)
 
        if (!transferee || !transferer) {
                ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" );
-               if (d->req.data)
-                       ast_free(d->req.data);
+               deinit_req(&d->req);
                free(d);
                return NULL;
        }
@@ -18818,8 +18823,7 @@ static void *sip_park_thread(void *stuff)
                ast_log(LOG_WARNING, "Masquerade failed.\n");
                transmit_response(transferer->tech_pvt, "503 Internal error", &req);
                ast_channel_unlock(transferee);
-               if (d->req.data)
-                       ast_free(d->req.data);
+               deinit_req(&d->req);
                free(d);
                return NULL;
        } 
@@ -18854,8 +18858,7 @@ static void *sip_park_thread(void *stuff)
                ast_debug(1, "SIP Call parked failed \n");
                /* Do not hangup call */
        }
-       if (d->req.data)
-               ast_free(d->req.data);
+       deinit_req(&d->req);
        free(d);
        return NULL;
 }
@@ -18949,8 +18952,7 @@ static int sip_park(struct ast_channel *chan1, struct ast_channel *chan2, struct
                d->seqno = seqno;
                if (ast_pthread_create_detached_background(&th, NULL, sip_park_thread, d) < 0) {
                        /* Could not start thread */
-                       if (d->req.data)
-                               ast_free(d->req.data);
+                       deinit_req(&d->req);
                        ast_free(d);    /* We don't need it anymore. If thread is created, d will be free'd
                                           by sip_park_thread() */
                        return 0;
@@ -22009,10 +22011,7 @@ static int sipsock_read(int *id, int fd, short events, void *ignore)
        req.socket.port = bindaddr.sin_port;
 
        handle_request_do(&req, &sin);
-       if (req.data) {
-               ast_free(req.data);
-               req.data = NULL;
-       }
+       deinit_req(&req);
 
        return 1;
 }
index 74ee9554b24b6cb424c2693759349c994f008f8a..b00af7824bb38393dd6e280c35c4cf9fd9286d0b 100644 (file)
@@ -2,47 +2,38 @@
 
 [aastra-check-cfg]
 Event=>check-sync
-Content-Length=>0
 
 [aastra-xml]
 Event=>aastra-xml
-Content-Length=>0
 
 ; Linksys
 
 [linksys-cold-restart]
 Event=>reboot_now
-Content-Length=>0
 
 [linksys-warm-restart]
 Event=>restart_now
-Content-Length=>0
 
 ; Polycom
 
 [polycom-check-cfg]
 Event=>check-sync
-Content-Length=>0
 
 ; Sipura
 
 [sipura-check-cfg]
 Event=>resync
-Content-Length=>0
 
 [sipura-get-report]
 Event=>report
-Content-Length=>0
 
 ; snom
 
 [snom-check-cfg]
 Event=>check-sync\;reboot=false
-Content-Length=>0
 
 [snom-reboot]
 Event=>reboot
-Content-Length=>0
 
 ;;
 ;; The following NOTIFY messages are not confirmed to work.
@@ -50,4 +41,3 @@ Content-Length=>0
 
 [cisco-check-cfg]
 Event=>check-sync
-Content-Length=>0
index efa9ddd001e666d2a978cf5cd8eaa84e8b1f17a2..ec20c90e71e685ae90e493c07eecb1de86a4a752 100644 (file)
@@ -573,6 +573,23 @@ int ast_str_make_space(struct ast_str **buf, size_t new_len),
 )
 #endif
 
+AST_INLINE_API(
+int ast_str_copy_string(struct ast_str **dst, struct ast_str *src),
+{
+
+       /* make sure our destination is large enough */
+       if (src->__AST_STR_USED + 1 > (*dst)->__AST_STR_LEN) {
+               if (ast_str_make_space(dst, src->__AST_STR_USED + 1)) {
+                       return -1;
+               }
+       }
+
+       memcpy((*dst)->__AST_STR_STR, src->__AST_STR_STR, src->__AST_STR_USED + 1);
+       (*dst)->__AST_STR_USED = src->__AST_STR_USED;
+       return 0;
+}
+)
+
 #define ast_str_alloca(init_len)                       \
        ({                                              \
                struct ast_str *__ast_str_buf;                  \