123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- /*
- * $Id$
- *
- * Copyright (C) 2005 iptelorg GmbH
- * Written by Jan Janak <[email protected]>
- *
- * This file is part of SER, a free SIP server.
- *
- * SER is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version
- *
- * For a license to use the SER software under conditions other than those
- * described here, or to purchase support for this software, please contact
- * iptel.org by e-mail at the following addresses: [email protected]
- *
- * SER is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
- /** @addtogroup xmlrpc
- * @{
- */
- /** @file
- * XML-RPC requests are carried in the body of HTTP requests, but HTTP
- * requests does not contain some mandatory SIP headers and thus cannot
- * be processed by SER directly. This file contains functions that can
- * turn HTTP requests into SIP request by inserting fake mandatory SIP
- * headers, such as Via. This allows SER to process such HTTP requests
- * and extract the body of the request, which contains the XML-RPC
- * document.
- */
- #include "http.h"
- #include "../../mem/mem.h"
- #include "../../dprint.h"
- #include "../../parser/parse_via.h"
- #include "../../data_lump.h"
- #include "../../ip_addr.h"
- #include "../../msg_translator.h"
- #include "../../ut.h"
- #include <string.h>
- /** Insert fake Via header field into SIP message.
- *
- * This function takes a SIP message and a Via header field
- * as text and inserts the Via header field into the SIP
- * message, modifying the data structures within the SIP
- * message to make it look that the Via header field was
- * received with the message.
- *
- * @param msg a pointer to the currently processed SIP message
- * @param via the Via header field text to be inserted
- * @param via_len size of the Via header field being inserted
- * @return 0 on succes, a negative number on error.
- */
- static int insert_fake_via(sip_msg_t* msg, char* via, int via_len)
- {
- struct via_body* vb = 0;
- via_cnt++;
- vb = pkg_malloc(sizeof(struct via_body));
- if (vb == 0){
- ERR("insert_fake_via: Out of memory\n");
- goto error;
- }
- msg->h_via1 = pkg_malloc(sizeof(hdr_field_t));
- if (!msg->h_via1) {
- ERR("No memory left\n");
- goto error;
- }
- memset(msg->h_via1, 0, sizeof(hdr_field_t));
- memset(vb, 0, sizeof(struct via_body));
- /* FIXME: The code below would break if the VIA prefix
- * gets changed in config.h
- */
- msg->h_via1->name.s = via;
- msg->h_via1->name.len = 3;
- msg->h_via1->body.s = via + 5;
- msg->h_via1->body.len = via_len - 5 - CRLF_LEN;
- msg->h_via1->type = HDR_VIA_T;
- msg->h_via1->parsed = vb;
- /* This field is used by the msg translator to add a new
- * via when forwarding the request. It must point to an existing
- * header field because otherwise call to anchor_lump, which does
- * hdr.s - buf, would crash
- */
- vb->hdr.s = msg->headers->name.s;
- vb->hdr.len = 0;
-
- msg->via1 = vb;
-
- /* We have to replace the zero terminating character right behind
- * CRLF because otherwise the parser will return an error.
- * It expects that there is either a next header field or another
- * CRLF delimiter
- */
- via[via_len] = 'a';
- parse_via(via + 5, via + via_len + 1, vb);
- if (vb->error == PARSE_ERROR){
- ERR("Bad via\n");
- goto error;
- }
- if (msg->last_header == 0) {
- msg->headers = msg->h_via1;
- msg->last_header = msg->h_via1;
- } else {
- msg->last_header->next = msg->h_via1;
- msg->last_header = msg->h_via1;
- }
- return 0;
- error:
- if (vb) {
- free_via_list(vb);
- pkg_free(vb);
- }
- if (msg->h_via1) pkg_free(msg->h_via1);
- return -1;
- }
- static int insert_via_lump(sip_msg_t* msg, char* via, int via_len)
- {
- struct lump* anchor;
-
- anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, HDR_VIA_T);
- if (anchor == 0) {
- ERR("Unable to create anchor\n");
- return -1;
- }
- if (insert_new_lump_after(anchor, via, via_len, HDR_VIA_T) == 0) {
- ERR("Unable to insert via lump\n");
- return -1;
- }
- return 0;
- }
- /** Create a fake Via header field.
- *
- * This function creates a fake Via header field and inserts
- * the fake header field into the header of the HTTP request.
- * The fake Via header field contains the source IP address
- * and port of the TCP/IP connection.
- */
- int create_via(sip_msg_t* msg, char* s1, char* s2)
- {
- char* via;
- unsigned int via_len;
- str ip, port;
- struct hostport hp;
- struct dest_info dst;
- ip.s = ip_addr2a(&msg->rcv.src_ip);
- ip.len = strlen(ip.s);
- port.s = int2str(msg->rcv.src_port, &port.len);
- hp.host = &ip;
- hp.port = &port;
- init_dst_from_rcv(&dst, &msg->rcv);
- via = via_builder(&via_len, &dst, 0, 0, &hp);
- if (!via) {
- ERR("Unable to build Via header field\n");
- return -1;
- }
- if (insert_fake_via(msg, via, via_len) < 0) {
- pkg_free(via);
- return -1;
- }
- if (insert_via_lump(msg, via, via_len - CRLF_LEN) < 0) {
- pkg_free(via);
- return -1;
- }
- return 1;
- }
- /** @} */
|