rtpproxy.patch 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. diff --git a/Makefile.am b/Makefile.am
  2. index 258de5e..a61bc57 100644
  3. --- a/Makefile.am
  4. +++ b/Makefile.am
  5. @@ -5,7 +5,7 @@ rtpproxy_SOURCES=main.c rtp.h rtp_server.c rtp_server.h \
  6. rtpp_command.c rtpp_command.h rtpp_log.c rtpp_network.h rtpp_network.c \
  7. rtpp_syslog_async.c rtpp_syslog_async.h rtpp_notify.c rtpp_notify.h \
  8. rtpp_command_async.h rtpp_command_async.c
  9. -rtpproxy_LDADD=-lm -lpthread
  10. +rtpproxy_LDADD=-lm -lpthread @LIBS_XMLRPC@
  11. dist_man_MANS=rtpproxy.8
  12. makeann_SOURCES=makeann.c rtp.h g711.h
  13. makeann_LDADD=@LIBS_G729@ @LIBS_GSM@
  14. diff --git a/Makefile.in b/Makefile.in
  15. index 47c14fd..cdb5e43 100644
  16. --- a/Makefile.in
  17. +++ b/Makefile.in
  18. @@ -217,7 +217,7 @@ rtpproxy_SOURCES = main.c rtp.h rtp_server.c rtp_server.h \
  19. rtpp_syslog_async.c rtpp_syslog_async.h rtpp_notify.c rtpp_notify.h \
  20. rtpp_command_async.h rtpp_command_async.c
  21. -rtpproxy_LDADD = -lm -lpthread
  22. +rtpproxy_LDADD = -lm -lpthread @LIBS_XMLRPC@
  23. dist_man_MANS = rtpproxy.8
  24. makeann_SOURCES = makeann.c rtp.h g711.h
  25. makeann_LDADD = @LIBS_G729@ @LIBS_GSM@
  26. diff --git a/aclocal.m4 b/aclocal.m4
  27. index b36bc80..0970c41 100644
  28. --- a/aclocal.m4
  29. +++ b/aclocal.m4
  30. @@ -13,8 +13,8 @@
  31. m4_ifndef([AC_AUTOCONF_VERSION],
  32. [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
  33. -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],,
  34. -[m4_warning([this file was generated for autoconf 2.68.
  35. +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.67],,
  36. +[m4_warning([this file was generated for autoconf 2.67.
  37. You have another version of autoconf. It may work, but is not guaranteed to.
  38. If you have problems, you may need to regenerate the build system entirely.
  39. To do so, use the procedure documented by the package, typically `autoreconf'.])])
  40. diff --git a/config.h.in b/config.h.in
  41. index cd0c23a..87491e3 100644
  42. --- a/config.h.in
  43. +++ b/config.h.in
  44. @@ -14,6 +14,9 @@
  45. /* Define if you have libgsm library installed */
  46. #undef ENABLE_GSM
  47. +/* Define if you have xmlrpc library installed */
  48. +#undef ENABLE_XMLRPC
  49. +
  50. /* Define to 1 if you have `alloca', as a function or macro. */
  51. #undef HAVE_ALLOCA
  52. diff --git a/configure.ac b/configure.ac
  53. index 54c1a60..1c88b99 100644
  54. --- a/configure.ac
  55. +++ b/configure.ac
  56. @@ -53,6 +53,17 @@ then
  57. AC_DEFINE([ENABLE_G729], 1, [Define if you have libg729 library installed])
  58. )
  59. fi
  60. +
  61. +# XML-RPC-Libs:
  62. +AC_CHECK_HEADERS(xmlrpc_client.h xmlrpc.h, found_xmlrpc=yes)
  63. +if test "$found_xmlrpc" = yes
  64. +then
  65. + AC_CHECK_LIB(curl, curl_version,
  66. + LIBS_XMLRPC="-lcurl -lxmlrpc_client -lxmlrpc -lxmlrpc_util -lxmlrpc_xmlparse -lxmlrpc_xmltok"
  67. + AC_DEFINE([ENABLE_XMLRPC], 1, [Define if you have XML-RPC-Client library installed])
  68. + )
  69. +fi
  70. +
  71. ##if test -z "$G729_SUPPORT"
  72. ##then
  73. ## echo "*************************************************************************** $ECHO_C" 1>&6
  74. @@ -94,4 +105,5 @@ AC_CONFIG_FILES([Makefile])
  75. AC_SUBST(AM_CFLAGS)
  76. AC_SUBST(LIBS_GSM)
  77. AC_SUBST(LIBS_G729)
  78. +AC_SUBST(LIBS_XMLRPC)
  79. AC_OUTPUT
  80. diff --git a/rtpp_command.c b/rtpp_command.c
  81. index c5734ae..d6072de 100644
  82. --- a/rtpp_command.c
  83. +++ b/rtpp_command.c
  84. @@ -69,6 +69,9 @@ struct proto_cap proto_caps[] = {
  85. { "20081102", "Support for setting codecs in the update/lookup command" },
  86. { "20081224", "Support for session timeout notifications" },
  87. { "20090810", "Support for automatic bridging" },
  88. +#ifdef ENABLE_XMLRPC
  89. + { "20100819", "Support for timeout notifications using XML-RPC towards Kamailio/sip-router.org" },
  90. +#endif
  91. { NULL, NULL }
  92. };
  93. @@ -269,6 +272,7 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
  94. char *socket_name_u, *notify_tag;
  95. struct sockaddr *local_addr;
  96. char c;
  97. + struct rtpp_timeout_handler * my_timeout_h;
  98. requested_nsamples = -1;
  99. ia[0] = ia[1] = NULL;
  100. @@ -468,7 +472,7 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
  101. }
  102. call_id = argv[1];
  103. if (op == UPDATE || op == LOOKUP || op == PLAY) {
  104. - max_argc = (op == UPDATE ? 8 : 6);
  105. + max_argc = (op == PLAY ? 6 : 8);
  106. if (argc < 5 || argc > max_argc) {
  107. rtpp_log_write(RTPP_LOG_ERR, cf->stable.glog, "command syntax error");
  108. reply_error(&cf->stable, controlfd, &raddr, rlen, cookie, 4);
  109. @@ -478,7 +482,7 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
  110. to_tag = argv[5];
  111. if (op == PLAY && argv[0][1] != '\0')
  112. playcount = atoi(argv[0] + 1);
  113. - if (op == UPDATE && argc > 6) {
  114. + if (op != PLAY && argc > 6) {
  115. socket_name_u = argv[6];
  116. if (strncmp("unix:", socket_name_u, 5) == 0)
  117. socket_name_u += 5;
  118. @@ -965,25 +969,39 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
  119. }
  120. pthread_mutex_lock(&cf->glock);
  121. - if (op == UPDATE) {
  122. - if (cf->timeout_handler->socket_name == NULL && socket_name_u != NULL)
  123. - rtpp_log_write(RTPP_LOG_ERR, spa->log, "must permit notification socket with -n");
  124. +
  125. + if ((op == UPDATE) || (op == LOOKUP)){
  126. if (spa->timeout_data.notify_tag != NULL) {
  127. free(spa->timeout_data.notify_tag);
  128. spa->timeout_data.notify_tag = NULL;
  129. }
  130. - if (cf->timeout_handler->socket_name != NULL && socket_name_u != NULL) {
  131. - if (strcmp(cf->timeout_handler->socket_name, socket_name_u) != 0) {
  132. - rtpp_log_write(RTPP_LOG_ERR, spa->log, "invalid socket name %s", socket_name_u);
  133. - socket_name_u = NULL;
  134. - } else {
  135. + spa->timeout_data.handler = NULL;
  136. + if (socket_name_u != NULL) {
  137. + if (cf->timeout_handler != NULL && cf->timeout_handler->socket_name != NULL
  138. + && strlen(cf->timeout_handler->socket_name) == strlen(socket_name_u)
  139. + && strcmp(cf->timeout_handler->socket_name, socket_name_u) != 0) {
  140. rtpp_log_write(RTPP_LOG_INFO, spa->log, "setting timeout handler");
  141. spa->timeout_data.handler = cf->timeout_handler;
  142. spa->timeout_data.notify_tag = strdup(notify_tag);
  143. + } else {
  144. + rtpp_log_write(RTPP_LOG_INFO, spa->log, "setting custom timeout handler (%s)", socket_name_u);
  145. + my_timeout_h = malloc(sizeof(struct rtpp_timeout_handler));
  146. + if (my_timeout_h == NULL) {
  147. + rtpp_log_write(RTPP_LOG_ERR, spa->log, "Unable to allocate memory");
  148. + } else {
  149. + memset(my_timeout_h, 0, sizeof(struct rtpp_timeout_handler));
  150. + my_timeout_h->socket_name = (char *)malloc(strlen(socket_name_u) + 1);
  151. + if(my_timeout_h->socket_name != NULL) {
  152. + strcpy(my_timeout_h->socket_name, socket_name_u);
  153. + spa->timeout_data.handler = my_timeout_h;
  154. + if (notify_tag != NULL) spa->timeout_data.notify_tag = strdup(notify_tag);
  155. + else spa->timeout_data.notify_tag = NULL;
  156. + } else {
  157. + rtpp_log_write(RTPP_LOG_ERR, spa->log, "Unable to allocate memory");
  158. + free(my_timeout_h);
  159. + }
  160. + }
  161. }
  162. - } else if (socket_name_u == NULL && spa->timeout_data.handler != NULL) {
  163. - spa->timeout_data.handler = NULL;
  164. - rtpp_log_write(RTPP_LOG_INFO, spa->log, "disabling timeout handler");
  165. }
  166. }
  167. diff --git a/rtpp_notify.c b/rtpp_notify.c
  168. index e92c9ec..e6b30e4 100644
  169. --- a/rtpp_notify.c
  170. +++ b/rtpp_notify.c
  171. @@ -42,10 +42,24 @@
  172. #include "rtpp_session.h"
  173. #include "rtpp_util.h"
  174. +#ifdef ENABLE_XMLRPC
  175. +#include <xmlrpc.h>
  176. +#include <xmlrpc_client.h>
  177. +#define XMLRPC_CLIENT_NAME "XML-RPC RTPProxy Client"
  178. +#define XMLRPC_CLIENT_VERSION "0.2"
  179. +#endif
  180. +
  181. struct rtpp_notify_wi
  182. {
  183. char *notify_buf;
  184. int len;
  185. +#ifdef ENABLE_XMLRPC
  186. + char *call_id;
  187. + int call_id_len;
  188. + char *param;
  189. + int param_len;
  190. + int custom_handler;
  191. +#endif
  192. struct rtpp_timeout_handler *th;
  193. rtpp_log_t glog;
  194. struct rtpp_notify_wi *next;
  195. @@ -258,6 +272,13 @@ rtpp_notify_schedule(struct cfg *cf, struct rtpp_session *sp)
  196. if (wi == NULL)
  197. return -1;
  198. +#ifdef ENABLE_XMLRPC
  199. + if (th != cf->timeout_handler)
  200. + wi->custom_handler = 1;
  201. + else
  202. + wi->custom_handler = 0;
  203. +#endif
  204. +
  205. wi->th = th;
  206. if (sp->timeout_data.notify_tag == NULL) {
  207. /* two 5-digit numbers, space, \0 and \n */
  208. @@ -289,6 +310,59 @@ rtpp_notify_schedule(struct cfg *cf, struct rtpp_session *sp)
  209. len = snprintf(wi->notify_buf, len, "%s\n",
  210. sp->timeout_data.notify_tag);
  211. }
  212. +#ifdef ENABLE_XMLRPC
  213. +
  214. + // rtpp_log_write(RTPP_LOG_ERR, wi->glog, "Timeout socket is: %s (%p)\n", wi->th->socket_name, wi->th->socket_name);
  215. +
  216. + if (strncmp("xmlrpc:", wi->th->socket_name, 7) == 0) {
  217. + // Copy the Socket-Name
  218. + len = strlen(wi->th->socket_name)+1;
  219. + if (wi->param == NULL) {
  220. + wi->param = malloc(len);
  221. + if (wi->param == NULL) {
  222. + rtpp_notify_queue_return_free_item(wi);
  223. + return -1;
  224. + }
  225. + } else {
  226. + notify_buf = realloc(wi->param, len);
  227. + if (notify_buf == NULL) {
  228. + rtpp_notify_queue_return_free_item(wi);
  229. + return -1;
  230. + }
  231. + wi->param = notify_buf;
  232. + }
  233. + memset(wi->param, '\0', len);
  234. + len = snprintf(wi->param, len, "%s",
  235. + wi->th->socket_name);
  236. + wi->param_len = len;
  237. +
  238. + // rtpp_log_write(RTPP_LOG_ERR, wi->glog, "wi->param %s (%p)\n", wi->param, wi->param);
  239. +
  240. + // Copy the Call-ID:
  241. + len = strlen(sp->call_id)+1;
  242. + if (wi->call_id == NULL) {
  243. + wi->call_id = malloc(len);
  244. + if (wi->call_id == NULL) {
  245. + rtpp_notify_queue_return_free_item(wi);
  246. + return -1;
  247. + }
  248. + } else {
  249. + notify_buf = realloc(wi->call_id, len);
  250. + if (notify_buf == NULL) {
  251. + rtpp_notify_queue_return_free_item(wi);
  252. + return -1;
  253. + }
  254. + wi->call_id = notify_buf;
  255. + }
  256. + memset(wi->call_id, '\0', len);
  257. + len = snprintf(wi->call_id, len, "%s",
  258. + sp->call_id);
  259. + wi->call_id_len = len;
  260. +
  261. + // rtpp_log_write(RTPP_LOG_ERR, wi->glog, "wi->call_id %s (%p)\n", wi->call_id, wi->call_id);
  262. +
  263. + }
  264. +#endif
  265. wi->glog = cf->stable.glog;
  266. @@ -345,29 +419,72 @@ reconnect_timeout_handler(rtpp_log_t log, struct rtpp_timeout_handler *th)
  267. }
  268. }
  269. +#ifdef ENABLE_XMLRPC
  270. +static int
  271. +do_xmlrpc_timeout_notification(rtpp_log_t log, struct rtpp_notify_wi *wi) {
  272. + xmlrpc_env env;
  273. + xmlrpc_value *result;
  274. +
  275. + /* Start up our XML-RPC client library. */
  276. + xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, XMLRPC_CLIENT_NAME, XMLRPC_CLIENT_VERSION);
  277. + xmlrpc_env_init(&env);
  278. +
  279. + /* Get the dialog-Info: */
  280. + result = xmlrpc_client_call(&env, wi->param+7,
  281. + "dlg_terminate_dlg", "(s)",
  282. + wi->call_id);
  283. + if (env.fault_occurred) {
  284. + rtpp_log_write(RTPP_LOG_ERR, wi->glog, "%s: XML-RPC Fault: %s (%d)\n", wi->call_id, env.fault_string, env.fault_code);
  285. + return -1;
  286. + }
  287. +
  288. + /* Dispose of our result value. */
  289. + xmlrpc_DECREF(result);
  290. +
  291. + /* Shutdown our XML-RPC client library. */
  292. + xmlrpc_env_clean(&env);
  293. + xmlrpc_client_cleanup();
  294. +
  295. + return 0;
  296. +}
  297. +#endif
  298. +
  299. static void
  300. do_timeout_notification(struct rtpp_notify_wi *wi, int retries)
  301. {
  302. int result;
  303. - if (wi->th->connected == 0) {
  304. - reconnect_timeout_handler(wi->glog, wi->th);
  305. -
  306. - /* If connect fails, no notification will be sent */
  307. - if (wi->th->connected == 0) {
  308. - rtpp_log_write(RTPP_LOG_ERR, wi->glog, "unable to send timeout notification");
  309. - return;
  310. - }
  311. + if (strncmp("xmlrpc:", wi->th->socket_name, 7) == 0) {
  312. + result = do_xmlrpc_timeout_notification(wi->glog, wi);
  313. + } else {
  314. + if (wi->th->connected == 0) {
  315. + reconnect_timeout_handler(wi->glog, wi->th);
  316. +
  317. + /* If connect fails, no notification will be sent */
  318. + if (wi->th->connected == 0) {
  319. + rtpp_log_write(RTPP_LOG_ERR, wi->glog, "unable to send timeout notification");
  320. + return;
  321. + }
  322. + }
  323. +
  324. + do {
  325. + result = send(wi->th->fd, wi->notify_buf, wi->len - 1, 0);
  326. + } while (result == -1 && errno == EINTR);
  327. }
  328. - do {
  329. - result = send(wi->th->fd, wi->notify_buf, wi->len - 1, 0);
  330. - } while (result == -1 && errno == EINTR);
  331. -
  332. if (result < 0) {
  333. wi->th->connected = 0;
  334. rtpp_log_ewrite(RTPP_LOG_ERR, wi->glog, "failed to send timeout notification");
  335. if (retries > 0)
  336. do_timeout_notification(wi, retries - 1);
  337. }
  338. +#ifdef ENABLE_XMLRPC
  339. + // In case we use a custom timeout handler, we have to free it.
  340. + if (wi->th && (wi->custom_handler == 1)) {
  341. + free(wi->th->socket_name);
  342. + free(wi->th);
  343. + wi->th = 0;
  344. + }
  345. +#endif
  346. +
  347. }
  348. diff --git a/rtpp_session.c b/rtpp_session.c
  349. index 03e3d8a..51b3319 100644
  350. --- a/rtpp_session.c
  351. +++ b/rtpp_session.c
  352. @@ -41,6 +41,7 @@
  353. #include "rtpp_record.h"
  354. #include "rtpp_session.h"
  355. #include "rtpp_util.h"
  356. +#include "rtpp_notify.h"
  357. void
  358. init_hash_table(struct cfg_stable *cf)