888ca09d |
/*
*$Id$
|
7dd0b342 |
*
* Copyright (C) 2001-2003 Fhg Fokus
*
* 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:
* info@iptel.org
*
* 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
|
049f64c2 |
*
* History:
* ---------
|
18dbc018 |
* 2003-02-28 scratchpad compatibility abandoned (jiri)
|
049f64c2 |
* 2003-01-29 transport-independent message zero-termination in
* receive_msg (jiri)
|
ab130758 |
* 2003-02-07 undoed jiri's zero term. changes (they break tcp) (andrei)
|
8fc80c33 |
* 2003-02-10 moved zero-term in the calling functions (udp_receive &
* tcp_read_req)
|
888ca09d |
*/
|
7dd0b342 |
|
888ca09d |
#include <string.h>
|
3e429f5c |
#include <stdlib.h>
|
4f3faaaf |
#include <sys/time.h>
|
888ca09d |
#include "receive.h"
|
4e2fdd79 |
#include "globals.h"
|
888ca09d |
#include "dprint.h"
#include "route.h"
|
3881f12c |
#include "parser/msg_parser.h"
|
888ca09d |
#include "forward.h"
|
3e429f5c |
#include "action.h"
|
dda9dab1 |
#include "mem/mem.h"
#include "stats.h"
|
4e2fdd79 |
#include "ip_addr.h"
|
caf80ae6 |
#include "script_cb.h"
#include "dset.h"
|
888ca09d |
|
5b253cc6 |
|
03150098 |
#ifdef DEBUG_DMALLOC
|
dda9dab1 |
#include <mem/dmalloc.h>
|
0a974a1d |
#endif
|
5b253cc6 |
|
e72b5b50 |
unsigned int msg_no=0;
|
8fc80c33 |
/* WARNING: buf must be 0 terminated (buf[len]=0) or some things might
* break (e.g.: modules/textops)
*/
|
f2f969dd |
int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
|
888ca09d |
{
|
22d4aa5d |
struct sip_msg* msg;
|
985f6f0f |
#ifdef STATS
int skipped = 1;
|
4f3faaaf |
struct timeval tvb, tve;
struct timezone tz;
unsigned int diff;
|
985f6f0f |
#endif
|
e72b5b50 |
|
6fa79282 |
msg=pkg_malloc(sizeof(struct sip_msg));
|
caf80ae6 |
if (msg==0) {
LOG(L_ERR, "ERROR: receive_msg: no mem for sip_msg\n");
goto error00;
}
|
e72b5b50 |
msg_no++;
|
caf80ae6 |
/* number of vias parsed -- good for diagnostic info in replies */
via_cnt=0;
|
5b253cc6 |
|
22d4aa5d |
memset(msg,0, sizeof(struct sip_msg)); /* init everything to 0 */
|
4ac74c03 |
/* fill in msg */
|
22d4aa5d |
msg->buf=buf;
msg->len=len;
|
9b47a45c |
/* zero termination (termination of orig message bellow not that
useful as most of the work is done with scrath-pad; -jiri */
|
6ee62314 |
/* buf[len]=0; */ /* WARNING: zero term removed! */
|
f2f969dd |
msg->rcv=*rcv_info;
|
22d4aa5d |
msg->id=msg_no;
|
888ca09d |
|
22d4aa5d |
if (parse_msg(buf,len, msg)!=0){
|
caf80ae6 |
LOG(L_ERR, "ERROR: receive_msg: parse_msg failed\n");
goto error02;
|
888ca09d |
}
|
e72b5b50 |
DBG("After parse_msg...\n");
|
caf80ae6 |
/* execute pre-script callbacks, if any; -jiri */
|
a50f3f89 |
/* if some of the callbacks said not to continue with
script processing, don't do so
*/
if (exec_pre_cb(msg)==0) goto error;
|
caf80ae6 |
/* ... and clear branches from previous message */
clear_branches();
|
22d4aa5d |
if (msg->first_line.type==SIP_REQUEST){
|
888ca09d |
/* sanity checks */
|
34af87af |
if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
|
888ca09d |
/* no via, send back error ? */
|
e72b5b50 |
LOG(L_ERR, "ERROR: receive_msg: no via found in request\n");
goto error;
|
888ca09d |
}
|
f8d46776 |
/* check if neccesarry to add receive?->moved to forward_req */
|
0a6afa42 |
|
f20a56a2 |
/* exec routing script */
|
f8d46776 |
DBG("preparing to run routing scripts...\n");
|
4f3faaaf |
#ifdef STATS
gettimeofday( & tvb, &tz );
#endif
|
caf80ae6 |
|
22d4aa5d |
if (run_actions(rlist[0], msg)<0){
|
caf80ae6 |
|
4ac74c03 |
LOG(L_WARN, "WARNING: receive_msg: "
|
f20a56a2 |
"error while trying script\n");
|
4ac74c03 |
goto error;
}
|
caf80ae6 |
|
4f3faaaf |
#ifdef STATS
gettimeofday( & tve, &tz );
diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
stats->processed_requests++;
stats->acc_req_time += diff;
DBG("succesfully ran routing scripts...(%d usec)\n", diff);
|
dda9dab1 |
STATS_RX_REQUEST( msg->first_line.u.request.method_value );
|
4f3faaaf |
#endif
|
22d4aa5d |
}else if (msg->first_line.type==SIP_REPLY){
|
888ca09d |
/* sanity checks */
|
34af87af |
if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
|
888ca09d |
/* no via, send back error ? */
|
e72b5b50 |
LOG(L_ERR, "ERROR: receive_msg: no via found in reply\n");
goto error;
|
888ca09d |
}
|
e22bbdb8 |
#if 0
|
34af87af |
if ((msg->via2==0) || (msg->via2->error!=PARSE_OK)){
|
e22bbdb8 |
/* no second via => error? */
|
e72b5b50 |
LOG(L_ERR, "ERROR: receive_msg: no 2nd via found in reply\n");
goto error;
|
e22bbdb8 |
}
|
888ca09d |
/* check if via1 == us */
|
caf80ae6 |
#endif
|
5b253cc6 |
|
4f3faaaf |
#ifdef STATS
gettimeofday( & tvb, &tz );
|
9598488f |
STATS_RX_RESPONSE ( msg->first_line.u.reply.statuscode / 100 );
|
4f3faaaf |
#endif
|
888ca09d |
/* send the msg */
|
b908cdeb |
forward_reply(msg);
|
4f3faaaf |
#ifdef STATS
gettimeofday( & tve, &tz );
diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
stats->processed_responses++;
stats->acc_res_time+=diff;
DBG("succesfully ran reply processing...(%d usec)\n", diff);
#endif
|
888ca09d |
}
|
f571aa35 |
#ifdef STATS
skipped = 0;
#endif
|
caf80ae6 |
/* execute post-script callbacks, if any; -jiri */
exec_post_cb(msg);
|
7f858173 |
DBG("receive_msg: cleaning up\n");
|
22d4aa5d |
free_sip_msg(msg);
|
6fa79282 |
pkg_free(msg);
|
f571aa35 |
#ifdef STATS
|
dda9dab1 |
if (skipped) STATS_RX_DROPS;
|
f571aa35 |
#endif
|
888ca09d |
return 0;
error:
|
e72b5b50 |
DBG("error:...\n");
|
caf80ae6 |
/* execute post-script callbacks, if any; -jiri */
exec_post_cb(msg);
error02:
|
22d4aa5d |
free_sip_msg(msg);
|
6fa79282 |
pkg_free(msg);
|
caf80ae6 |
error00:
|
dda9dab1 |
STATS_RX_DROPS;
|
888ca09d |
return -1;
}
|