receive.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. *$Id$
  3. *
  4. * Copyright (C) 2001-2003 Fhg Fokus
  5. *
  6. * This file is part of ser, a free SIP server.
  7. *
  8. * ser is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * For a license to use the ser software under conditions
  14. * other than those described here, or to purchase support for this
  15. * software, please contact iptel.org by e-mail at the following addresses:
  16. * [email protected]
  17. *
  18. * ser is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  26. */
  27. #include <string.h>
  28. #include <stdlib.h>
  29. #include <sys/time.h>
  30. #include "receive.h"
  31. #include "globals.h"
  32. #include "dprint.h"
  33. #include "route.h"
  34. #include "parser/msg_parser.h"
  35. #include "forward.h"
  36. #include "action.h"
  37. #include "mem/mem.h"
  38. #include "stats.h"
  39. #include "ip_addr.h"
  40. #include "script_cb.h"
  41. #include "dset.h"
  42. #ifdef DEBUG_DMALLOC
  43. #include <mem/dmalloc.h>
  44. #endif
  45. unsigned int msg_no=0;
  46. int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
  47. {
  48. struct sip_msg* msg;
  49. #ifdef STATS
  50. int skipped = 1;
  51. struct timeval tvb, tve;
  52. struct timezone tz;
  53. unsigned int diff;
  54. #endif
  55. msg=pkg_malloc(sizeof(struct sip_msg));
  56. if (msg==0) {
  57. LOG(L_ERR, "ERROR: receive_msg: no mem for sip_msg\n");
  58. goto error00;
  59. }
  60. msg_no++;
  61. /* number of vias parsed -- good for diagnostic info in replies */
  62. via_cnt=0;
  63. memset(msg,0, sizeof(struct sip_msg)); /* init everything to 0 */
  64. /* fill in msg */
  65. msg->buf=buf;
  66. msg->len=len;
  67. /* zero termination (termination of orig message bellow not that
  68. useful as most of the work is done with scrath-pad; -jiri */
  69. /* buf[len]=0; */ /* WARNING: zero term removed! */
  70. msg->rcv=*rcv_info;
  71. msg->id=msg_no;
  72. /* make a copy of the message */
  73. msg->orig=(char*) pkg_malloc(len+1);
  74. if (msg->orig==0){
  75. LOG(L_ERR, "ERROR:receive_msg: memory allocation failure\n");
  76. goto error01;
  77. }
  78. memcpy(msg->orig, buf, len);
  79. /* WARNING: zero term removed! */
  80. /* msg->orig[len]=0; */ /* null terminate it,good for using str* functions
  81. on it*/
  82. if (parse_msg(buf,len, msg)!=0){
  83. LOG(L_ERR, "ERROR: receive_msg: parse_msg failed\n");
  84. goto error02;
  85. }
  86. DBG("After parse_msg...\n");
  87. /* execute pre-script callbacks, if any; -jiri */
  88. /* if some of the callbacks said not to continue with
  89. script processing, don't do so
  90. */
  91. if (exec_pre_cb(msg)==0) goto error;
  92. /* ... and clear branches from previous message */
  93. clear_branches();
  94. if (msg->first_line.type==SIP_REQUEST){
  95. /* sanity checks */
  96. if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
  97. /* no via, send back error ? */
  98. LOG(L_ERR, "ERROR: receive_msg: no via found in request\n");
  99. goto error;
  100. }
  101. /* check if neccesarry to add receive?->moved to forward_req */
  102. /* exec routing script */
  103. DBG("preparing to run routing scripts...\n");
  104. #ifdef STATS
  105. gettimeofday( & tvb, &tz );
  106. #endif
  107. if (run_actions(rlist[0], msg)<0){
  108. LOG(L_WARN, "WARNING: receive_msg: "
  109. "error while trying script\n");
  110. goto error;
  111. }
  112. #ifdef STATS
  113. gettimeofday( & tve, &tz );
  114. diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
  115. stats->processed_requests++;
  116. stats->acc_req_time += diff;
  117. DBG("succesfully ran routing scripts...(%d usec)\n", diff);
  118. STATS_RX_REQUEST( msg->first_line.u.request.method_value );
  119. #endif
  120. }else if (msg->first_line.type==SIP_REPLY){
  121. /* sanity checks */
  122. if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
  123. /* no via, send back error ? */
  124. LOG(L_ERR, "ERROR: receive_msg: no via found in reply\n");
  125. goto error;
  126. }
  127. #if 0
  128. if ((msg->via2==0) || (msg->via2->error!=PARSE_OK)){
  129. /* no second via => error? */
  130. LOG(L_ERR, "ERROR: receive_msg: no 2nd via found in reply\n");
  131. goto error;
  132. }
  133. /* check if via1 == us */
  134. #endif
  135. #ifdef STATS
  136. gettimeofday( & tvb, &tz );
  137. STATS_RX_RESPONSE ( msg->first_line.u.reply.statuscode / 100 );
  138. #endif
  139. /* send the msg */
  140. forward_reply(msg);
  141. #ifdef STATS
  142. gettimeofday( & tve, &tz );
  143. diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
  144. stats->processed_responses++;
  145. stats->acc_res_time+=diff;
  146. DBG("succesfully ran reply processing...(%d usec)\n", diff);
  147. #endif
  148. }
  149. #ifdef STATS
  150. skipped = 0;
  151. #endif
  152. /* execute post-script callbacks, if any; -jiri */
  153. exec_post_cb(msg);
  154. DBG("receive_msg: cleaning up\n");
  155. free_sip_msg(msg);
  156. pkg_free(msg);
  157. #ifdef STATS
  158. if (skipped) STATS_RX_DROPS;
  159. #endif
  160. return 0;
  161. error:
  162. DBG("error:...\n");
  163. /* execute post-script callbacks, if any; -jiri */
  164. exec_post_cb(msg);
  165. error02:
  166. free_sip_msg(msg);
  167. error01:
  168. pkg_free(msg);
  169. error00:
  170. STATS_RX_DROPS;
  171. return -1;
  172. }