tcpops_mod.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /**
  2. * Copyright 2015 (C) Orange
  3. * <[email protected]>
  4. *
  5. * This file is part of Kamailio, a free SIP server.
  6. *
  7. * This file is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version
  11. *
  12. *
  13. * This file is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. */
  23. #include <stdio.h>
  24. #include <unistd.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include "../../globals.h"
  28. #include "../../sr_module.h"
  29. #include "../../tcp_options.h"
  30. #include "../../dprint.h"
  31. #include "../../mod_fix.h"
  32. #include "tcpops.h"
  33. MODULE_VERSION
  34. static int mod_init(void);
  35. static int child_init(int);
  36. static void mod_destroy(void);
  37. static int w_tcp_keepalive_enable4(sip_msg_t* msg, char* con, char* idle, char *cnt, char *intvl);
  38. static int w_tcp_keepalive_enable3(sip_msg_t* msg, char* idle, char *cnt, char *intvl);
  39. static int w_tcp_keepalive_disable1(sip_msg_t* msg, char* con);
  40. static int w_tcp_keepalive_disable0(sip_msg_t* msg);
  41. static int w_tcpops_set_connection_lifetime2(sip_msg_t* msg, char* con, char* time);
  42. static int w_tcpops_set_connection_lifetime1(sip_msg_t* msg, char* time);
  43. static int fixup_numpv(void** param, int param_no);
  44. static cmd_export_t cmds[]={
  45. {"tcp_keepalive_enable", (cmd_function)w_tcp_keepalive_enable4, 4, fixup_numpv,
  46. 0, ANY_ROUTE},
  47. {"tcp_keepalive_enable", (cmd_function)w_tcp_keepalive_enable3, 3, fixup_numpv,
  48. 0, REQUEST_ROUTE|ONREPLY_ROUTE},
  49. {"tcp_keepalive_disable", (cmd_function)w_tcp_keepalive_disable1, 1, fixup_numpv,
  50. 0, ANY_ROUTE},
  51. {"tcp_keepalive_disable", (cmd_function)w_tcp_keepalive_disable0, 0, 0,
  52. 0, REQUEST_ROUTE|ONREPLY_ROUTE},
  53. {"tcp_set_connection_lifetime", (cmd_function)w_tcpops_set_connection_lifetime2, 2, fixup_numpv,
  54. 0, ANY_ROUTE},
  55. {"tcp_set_connection_lifetime", (cmd_function)w_tcpops_set_connection_lifetime1, 1, fixup_numpv,
  56. 0, REQUEST_ROUTE|ONREPLY_ROUTE},
  57. {0, 0, 0, 0, 0, 0}
  58. };
  59. struct module_exports exports = {
  60. "tcpops",
  61. DEFAULT_DLFLAGS, /* dlopen flags */
  62. cmds, /* exported functions to config */
  63. 0, /* exported parameters to config */
  64. 0, /* exported statistics */
  65. 0, /* exported MI functions */
  66. 0, /* exported pseudo-variables */
  67. 0, /* extra processes */
  68. mod_init, /* module initialization function */
  69. 0, /* response function */
  70. mod_destroy, /* destroy function */
  71. child_init /* per child init function */
  72. };
  73. /**
  74. * init module function
  75. */
  76. static int mod_init(void)
  77. {
  78. LM_DBG("TCP keepalive module loaded.\n");
  79. return 0;
  80. }
  81. /**
  82. * @brief Initialize async module children
  83. */
  84. static int child_init(int rank)
  85. {
  86. return 0;
  87. }
  88. /**
  89. * destroy module function
  90. */
  91. static void mod_destroy(void)
  92. {
  93. LM_DBG("TCP keepalive module unloaded.\n");
  94. }
  95. #define _IVALUE_ERROR(NAME) LM_ERR("invalid parameter '" #NAME "' (must be a number)\n")
  96. #define _IVALUE(NAME)\
  97. int i_##NAME ;\
  98. if(fixup_get_ivalue(msg, (gparam_t*)NAME, &( i_##NAME))!=0)\
  99. { \
  100. _IVALUE_ERROR(NAME);\
  101. return -1;\
  102. }
  103. /**
  104. *
  105. */
  106. static int w_tcp_keepalive_enable4(sip_msg_t* msg, char* con, char* idle, char *cnt, char *intvl)
  107. {
  108. int fd;
  109. int closefd = 0;
  110. _IVALUE (con)
  111. if (msg != NULL && msg->rcv.proto_reserved1 == i_con) {
  112. if (!tcpops_get_current_fd(msg->rcv.proto_reserved1, &fd)) {
  113. return -1;
  114. }
  115. } else {
  116. if (!tcpops_acquire_fd_from_tcpmain(i_con, &fd)) {
  117. return -1;
  118. }
  119. closefd = 1;
  120. }
  121. _IVALUE (idle)
  122. _IVALUE (cnt)
  123. _IVALUE (intvl)
  124. return tcpops_keepalive_enable(fd, i_idle, i_cnt, i_intvl, closefd);
  125. }
  126. static int w_tcp_keepalive_enable3(sip_msg_t* msg, char* idle, char *cnt, char *intvl)
  127. {
  128. int fd;
  129. if (unlikely(msg == NULL)) {
  130. return -1;
  131. }
  132. if(unlikely(msg->rcv.proto != PROTO_TCP && msg->rcv.proto != PROTO_TLS && msg->rcv.proto != PROTO_WS && msg->rcv.proto != PROTO_WSS))
  133. {
  134. LM_ERR("the current message does not come from a TCP connection\n");
  135. return -1;
  136. }
  137. if (!tcpops_get_current_fd(msg->rcv.proto_reserved1, &fd)) {
  138. return -1;
  139. }
  140. _IVALUE (idle)
  141. _IVALUE (cnt)
  142. _IVALUE (intvl)
  143. return tcpops_keepalive_enable(fd, i_idle, i_cnt, i_intvl, 0);
  144. }
  145. static int w_tcp_keepalive_disable1(sip_msg_t* msg, char* con)
  146. {
  147. int fd;
  148. int closefd = 0;
  149. _IVALUE (con)
  150. if (msg != NULL && msg->rcv.proto_reserved1 == i_con) {
  151. if (!tcpops_get_current_fd(msg->rcv.proto_reserved1, &fd)) {
  152. return -1;
  153. }
  154. } else {
  155. if (!tcpops_acquire_fd_from_tcpmain(i_con, &fd)) {
  156. return -1;
  157. }
  158. closefd = 1;
  159. }
  160. return tcpops_keepalive_disable(fd, closefd);
  161. }
  162. static int w_tcp_keepalive_disable0(sip_msg_t* msg)
  163. {
  164. int fd;
  165. if (unlikely(msg == NULL))
  166. return -1;
  167. if(unlikely(msg->rcv.proto != PROTO_TCP && msg->rcv.proto != PROTO_TLS && msg->rcv.proto != PROTO_WS && msg->rcv.proto != PROTO_WSS))
  168. {
  169. LM_ERR("the current message does not come from a TCP connection\n");
  170. return -1;
  171. }
  172. if (!tcpops_get_current_fd(msg->rcv.proto_reserved1, &fd)) {
  173. return -1;
  174. }
  175. return tcpops_keepalive_disable(fd, 0);
  176. }
  177. static int w_tcpops_set_connection_lifetime2(sip_msg_t* msg, char* conid, char* time)
  178. {
  179. struct tcp_connection *s_con;
  180. int ret = -1;
  181. _IVALUE (conid)
  182. _IVALUE (time)
  183. if (unlikely((s_con = tcpconn_get(i_conid, 0, 0, 0, 0)) == NULL)) {
  184. LM_ERR("invalid connection id %d, (must be a TCP connid)\n", i_conid);
  185. return 0;
  186. } else {
  187. ret = tcpops_set_connection_lifetime(s_con, i_time);
  188. tcpconn_put(s_con);
  189. }
  190. return ret;
  191. }
  192. static int w_tcpops_set_connection_lifetime1(sip_msg_t* msg, char* time)
  193. {
  194. struct tcp_connection *s_con;
  195. int ret = -1;
  196. _IVALUE (time)
  197. if(unlikely(msg->rcv.proto != PROTO_TCP && msg->rcv.proto != PROTO_TLS && msg->rcv.proto != PROTO_WS && msg->rcv.proto != PROTO_WSS))
  198. {
  199. LM_ERR("the current message does not come from a TCP connection\n");
  200. return -1;
  201. }
  202. if (unlikely((s_con = tcpconn_get(msg->rcv.proto_reserved1, 0, 0, 0, 0)) == NULL)) {
  203. return -1;
  204. } else {
  205. ret = tcpops_set_connection_lifetime(s_con, i_time);
  206. tcpconn_put(s_con);
  207. }
  208. return ret;
  209. }
  210. /**
  211. *
  212. */
  213. static int fixup_numpv(void** param, int param_no)
  214. {
  215. return fixup_igp_null(param, 1);
  216. }