corex_nio.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /**
  2. * $Id$
  3. *
  4. * Copyright (C) 2009 SIP-Router.org
  5. *
  6. * This file is part of Extensible SIP Router, a free SIP server.
  7. *
  8. * Permission to use, copy, modify, and distribute this software for any
  9. * purpose with or without fee is hereby granted, provided that the above
  10. * copyright notice and this permission notice appear in all copies.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  13. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  14. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  15. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  16. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  17. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  18. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  19. */
  20. #include "corex_nio.h"
  21. /**
  22. * init nio function
  23. */
  24. int nio_intercept_init(void)
  25. {
  26. int route_no;
  27. pv_spec_t avp_spec;
  28. route_no=route_get(&event_rt, "network:msg");
  29. if (route_no==-1)
  30. {
  31. LM_ERR("failed to find event_route[network:msg]\n");
  32. return -1;
  33. }
  34. if (event_rt.rlist[route_no]==0)
  35. {
  36. LM_ERR("event_route[network:msg] is empty\n");
  37. return -1;
  38. }
  39. nio_route_no=route_no;
  40. if (nio_min_msg_len < 0)
  41. {
  42. LM_WARN("min_msg_len is less then zero, setting it to zero");
  43. nio_min_msg_len = 0;
  44. }
  45. if (nio_msg_avp_param.s && nio_msg_avp_param.len > 0)
  46. {
  47. if (pv_parse_spec(&nio_msg_avp_param, &avp_spec)==0
  48. || avp_spec.type!=PVT_AVP)
  49. {
  50. LM_ERR("malformed or non AVP %.*s AVP definition\n",
  51. nio_msg_avp_param.len, nio_msg_avp_param.s);
  52. return -1;
  53. }
  54. if(pv_get_avp_name(0, &(avp_spec.pvp), &nio_msg_avp_name,
  55. &nio_msg_avp_type)!=0)
  56. {
  57. LM_ERR("[%.*s]- invalid AVP definition\n",
  58. nio_msg_avp_param.len, nio_msg_avp_param.s);
  59. return -1;
  60. }
  61. } else {
  62. LM_WARN("no AVP defined to store modified message\n");
  63. }
  64. /* register network hooks */
  65. sr_event_register_cb(SREV_NET_DATA_IN, nio_msg_received);
  66. sr_event_register_cb(SREV_NET_DATA_OUT, nio_msg_sent);
  67. #ifdef USE_TCP
  68. tcp_set_clone_rcvbuf(1);
  69. #endif
  70. return 0;
  71. }
  72. /**
  73. *
  74. */
  75. int nio_msg_received(void *data)
  76. {
  77. sip_msg_t msg;
  78. str *obuf;
  79. char *nbuf = NULL;
  80. int_str avp_value;
  81. struct usr_avp *avp;
  82. struct run_act_ctx ra_ctx;
  83. obuf = (str*)data;
  84. if (obuf->len < nio_min_msg_len) {
  85. return -1;
  86. }
  87. memset(&msg, 0, sizeof(sip_msg_t));
  88. msg.buf = obuf->s;
  89. msg.len = obuf->len;
  90. nio_is_incoming = 1;
  91. init_run_actions_ctx(&ra_ctx);
  92. run_actions(&ra_ctx, event_rt.rlist[nio_route_no], &msg);
  93. if(nio_msg_avp_name.n!=0) {
  94. avp = NULL;
  95. avp=search_first_avp(nio_msg_avp_type, nio_msg_avp_name,
  96. &avp_value, 0);
  97. if(avp!=NULL && is_avp_str_val(avp)) {
  98. msg.buf = avp_value.s.s;
  99. msg.len = avp_value.s.len;
  100. nbuf = nio_msg_update(&msg, (unsigned int*)&obuf->len);
  101. if(obuf->len>=BUF_SIZE) {
  102. LM_ERR("new buffer overflow (%d)\n", obuf->len);
  103. pkg_free(nbuf);
  104. return -1;
  105. }
  106. memcpy(obuf->s, nbuf, obuf->len);
  107. obuf->s[obuf->len] = '\0';
  108. } else {
  109. LM_WARN("no value set for AVP %.*s, using unmodified message\n",
  110. nio_msg_avp_param.len, nio_msg_avp_param.s);
  111. }
  112. }
  113. if(nbuf!=NULL)
  114. pkg_free(nbuf);
  115. free_sip_msg(&msg);
  116. return 0;
  117. }
  118. /**
  119. *
  120. */
  121. int nio_msg_sent(void *data)
  122. {
  123. sip_msg_t msg;
  124. str *obuf;
  125. int_str avp_value;
  126. struct usr_avp *avp;
  127. struct run_act_ctx ra_ctx;
  128. obuf = (str*)data;
  129. if (obuf->len < nio_min_msg_len) {
  130. return -1;
  131. }
  132. memset(&msg, 0, sizeof(sip_msg_t));
  133. msg.buf = obuf->s;
  134. msg.len = obuf->len;
  135. nio_is_incoming = 0;
  136. init_run_actions_ctx(&ra_ctx);
  137. run_actions(&ra_ctx, event_rt.rlist[nio_route_no], &msg);
  138. if(nio_msg_avp_name.n!=0) {
  139. avp = NULL;
  140. avp=search_first_avp(nio_msg_avp_type, nio_msg_avp_name,
  141. &avp_value, 0);
  142. if(avp!=NULL && is_avp_str_val(avp)) {
  143. msg.buf = avp_value.s.s;
  144. msg.len = avp_value.s.len;
  145. obuf->s = nio_msg_update(&msg, (unsigned int*)&obuf->len);
  146. } else {
  147. LM_WARN("no value set for AVP %.*s, using unmodified message\n",
  148. nio_msg_avp_param.len, nio_msg_avp_param.s);
  149. }
  150. }
  151. free_sip_msg(&msg);
  152. return 0;
  153. }
  154. /**
  155. *
  156. */
  157. int nio_check_incoming(void)
  158. {
  159. return (nio_is_incoming) ? 1 : -1;
  160. }
  161. /**
  162. *
  163. */
  164. char* nio_msg_update(sip_msg_t *msg, unsigned int *olen)
  165. {
  166. struct dest_info dst;
  167. init_dest_info(&dst);
  168. dst.proto = PROTO_UDP;
  169. return build_req_buf_from_sip_req(msg,
  170. olen, &dst, BUILD_NO_LOCAL_VIA|BUILD_NO_VIA1_UPDATE);
  171. }