mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
375 lines
12 KiB
375 lines
12 KiB
diff --git a/Makefile.am b/Makefile.am
|
|
index 258de5e..a61bc57 100644
|
|
--- a/Makefile.am
|
|
+++ b/Makefile.am
|
|
@@ -5,7 +5,7 @@ rtpproxy_SOURCES=main.c rtp.h rtp_server.c rtp_server.h \
|
|
rtpp_command.c rtpp_command.h rtpp_log.c rtpp_network.h rtpp_network.c \
|
|
rtpp_syslog_async.c rtpp_syslog_async.h rtpp_notify.c rtpp_notify.h \
|
|
rtpp_command_async.h rtpp_command_async.c
|
|
-rtpproxy_LDADD=-lm -lpthread
|
|
+rtpproxy_LDADD=-lm -lpthread @LIBS_XMLRPC@
|
|
dist_man_MANS=rtpproxy.8
|
|
makeann_SOURCES=makeann.c rtp.h g711.h
|
|
makeann_LDADD=@LIBS_G729@ @LIBS_GSM@
|
|
diff --git a/Makefile.in b/Makefile.in
|
|
index 47c14fd..cdb5e43 100644
|
|
--- a/Makefile.in
|
|
+++ b/Makefile.in
|
|
@@ -217,7 +217,7 @@ rtpproxy_SOURCES = main.c rtp.h rtp_server.c rtp_server.h \
|
|
rtpp_syslog_async.c rtpp_syslog_async.h rtpp_notify.c rtpp_notify.h \
|
|
rtpp_command_async.h rtpp_command_async.c
|
|
|
|
-rtpproxy_LDADD = -lm -lpthread
|
|
+rtpproxy_LDADD = -lm -lpthread @LIBS_XMLRPC@
|
|
dist_man_MANS = rtpproxy.8
|
|
makeann_SOURCES = makeann.c rtp.h g711.h
|
|
makeann_LDADD = @LIBS_G729@ @LIBS_GSM@
|
|
diff --git a/aclocal.m4 b/aclocal.m4
|
|
index b36bc80..0970c41 100644
|
|
--- a/aclocal.m4
|
|
+++ b/aclocal.m4
|
|
@@ -13,8 +13,8 @@
|
|
|
|
m4_ifndef([AC_AUTOCONF_VERSION],
|
|
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
|
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],,
|
|
-[m4_warning([this file was generated for autoconf 2.68.
|
|
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.67],,
|
|
+[m4_warning([this file was generated for autoconf 2.67.
|
|
You have another version of autoconf. It may work, but is not guaranteed to.
|
|
If you have problems, you may need to regenerate the build system entirely.
|
|
To do so, use the procedure documented by the package, typically `autoreconf'.])])
|
|
diff --git a/config.h.in b/config.h.in
|
|
index cd0c23a..87491e3 100644
|
|
--- a/config.h.in
|
|
+++ b/config.h.in
|
|
@@ -14,6 +14,9 @@
|
|
/* Define if you have libgsm library installed */
|
|
#undef ENABLE_GSM
|
|
|
|
+/* Define if you have xmlrpc library installed */
|
|
+#undef ENABLE_XMLRPC
|
|
+
|
|
/* Define to 1 if you have `alloca', as a function or macro. */
|
|
#undef HAVE_ALLOCA
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 54c1a60..1c88b99 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -53,6 +53,17 @@ then
|
|
AC_DEFINE([ENABLE_G729], 1, [Define if you have libg729 library installed])
|
|
)
|
|
fi
|
|
+
|
|
+# XML-RPC-Libs:
|
|
+AC_CHECK_HEADERS(xmlrpc_client.h xmlrpc.h, found_xmlrpc=yes)
|
|
+if test "$found_xmlrpc" = yes
|
|
+then
|
|
+ AC_CHECK_LIB(curl, curl_version,
|
|
+ LIBS_XMLRPC="-lcurl -lxmlrpc_client -lxmlrpc -lxmlrpc_util -lxmlrpc_xmlparse -lxmlrpc_xmltok"
|
|
+ AC_DEFINE([ENABLE_XMLRPC], 1, [Define if you have XML-RPC-Client library installed])
|
|
+ )
|
|
+fi
|
|
+
|
|
##if test -z "$G729_SUPPORT"
|
|
##then
|
|
## echo "*************************************************************************** $ECHO_C" 1>&6
|
|
@@ -94,4 +105,5 @@ AC_CONFIG_FILES([Makefile])
|
|
AC_SUBST(AM_CFLAGS)
|
|
AC_SUBST(LIBS_GSM)
|
|
AC_SUBST(LIBS_G729)
|
|
+AC_SUBST(LIBS_XMLRPC)
|
|
AC_OUTPUT
|
|
diff --git a/rtpp_command.c b/rtpp_command.c
|
|
index c5734ae..d6072de 100644
|
|
--- a/rtpp_command.c
|
|
+++ b/rtpp_command.c
|
|
@@ -69,6 +69,9 @@ struct proto_cap proto_caps[] = {
|
|
{ "20081102", "Support for setting codecs in the update/lookup command" },
|
|
{ "20081224", "Support for session timeout notifications" },
|
|
{ "20090810", "Support for automatic bridging" },
|
|
+#ifdef ENABLE_XMLRPC
|
|
+ { "20100819", "Support for timeout notifications using XML-RPC towards Kamailio/sip-router.org" },
|
|
+#endif
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
@@ -269,6 +272,7 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
|
|
char *socket_name_u, *notify_tag;
|
|
struct sockaddr *local_addr;
|
|
char c;
|
|
+ struct rtpp_timeout_handler * my_timeout_h;
|
|
|
|
requested_nsamples = -1;
|
|
ia[0] = ia[1] = NULL;
|
|
@@ -468,7 +472,7 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
|
|
}
|
|
call_id = argv[1];
|
|
if (op == UPDATE || op == LOOKUP || op == PLAY) {
|
|
- max_argc = (op == UPDATE ? 8 : 6);
|
|
+ max_argc = (op == PLAY ? 6 : 8);
|
|
if (argc < 5 || argc > max_argc) {
|
|
rtpp_log_write(RTPP_LOG_ERR, cf->stable.glog, "command syntax error");
|
|
reply_error(&cf->stable, controlfd, &raddr, rlen, cookie, 4);
|
|
@@ -478,7 +482,7 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
|
|
to_tag = argv[5];
|
|
if (op == PLAY && argv[0][1] != '\0')
|
|
playcount = atoi(argv[0] + 1);
|
|
- if (op == UPDATE && argc > 6) {
|
|
+ if (op != PLAY && argc > 6) {
|
|
socket_name_u = argv[6];
|
|
if (strncmp("unix:", socket_name_u, 5) == 0)
|
|
socket_name_u += 5;
|
|
@@ -965,25 +969,39 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
|
|
}
|
|
|
|
pthread_mutex_lock(&cf->glock);
|
|
- if (op == UPDATE) {
|
|
- if (cf->timeout_handler->socket_name == NULL && socket_name_u != NULL)
|
|
- rtpp_log_write(RTPP_LOG_ERR, spa->log, "must permit notification socket with -n");
|
|
+
|
|
+ if ((op == UPDATE) || (op == LOOKUP)){
|
|
if (spa->timeout_data.notify_tag != NULL) {
|
|
free(spa->timeout_data.notify_tag);
|
|
spa->timeout_data.notify_tag = NULL;
|
|
}
|
|
- if (cf->timeout_handler->socket_name != NULL && socket_name_u != NULL) {
|
|
- if (strcmp(cf->timeout_handler->socket_name, socket_name_u) != 0) {
|
|
- rtpp_log_write(RTPP_LOG_ERR, spa->log, "invalid socket name %s", socket_name_u);
|
|
- socket_name_u = NULL;
|
|
- } else {
|
|
+ spa->timeout_data.handler = NULL;
|
|
+ if (socket_name_u != NULL) {
|
|
+ if (cf->timeout_handler != NULL && cf->timeout_handler->socket_name != NULL
|
|
+ && strlen(cf->timeout_handler->socket_name) == strlen(socket_name_u)
|
|
+ && strcmp(cf->timeout_handler->socket_name, socket_name_u) != 0) {
|
|
rtpp_log_write(RTPP_LOG_INFO, spa->log, "setting timeout handler");
|
|
spa->timeout_data.handler = cf->timeout_handler;
|
|
spa->timeout_data.notify_tag = strdup(notify_tag);
|
|
+ } else {
|
|
+ rtpp_log_write(RTPP_LOG_INFO, spa->log, "setting custom timeout handler (%s)", socket_name_u);
|
|
+ my_timeout_h = malloc(sizeof(struct rtpp_timeout_handler));
|
|
+ if (my_timeout_h == NULL) {
|
|
+ rtpp_log_write(RTPP_LOG_ERR, spa->log, "Unable to allocate memory");
|
|
+ } else {
|
|
+ memset(my_timeout_h, 0, sizeof(struct rtpp_timeout_handler));
|
|
+ my_timeout_h->socket_name = (char *)malloc(strlen(socket_name_u) + 1);
|
|
+ if(my_timeout_h->socket_name != NULL) {
|
|
+ strcpy(my_timeout_h->socket_name, socket_name_u);
|
|
+ spa->timeout_data.handler = my_timeout_h;
|
|
+ if (notify_tag != NULL) spa->timeout_data.notify_tag = strdup(notify_tag);
|
|
+ else spa->timeout_data.notify_tag = NULL;
|
|
+ } else {
|
|
+ rtpp_log_write(RTPP_LOG_ERR, spa->log, "Unable to allocate memory");
|
|
+ free(my_timeout_h);
|
|
+ }
|
|
+ }
|
|
}
|
|
- } else if (socket_name_u == NULL && spa->timeout_data.handler != NULL) {
|
|
- spa->timeout_data.handler = NULL;
|
|
- rtpp_log_write(RTPP_LOG_INFO, spa->log, "disabling timeout handler");
|
|
}
|
|
}
|
|
|
|
diff --git a/rtpp_notify.c b/rtpp_notify.c
|
|
index e92c9ec..e6b30e4 100644
|
|
--- a/rtpp_notify.c
|
|
+++ b/rtpp_notify.c
|
|
@@ -42,10 +42,24 @@
|
|
#include "rtpp_session.h"
|
|
#include "rtpp_util.h"
|
|
|
|
+#ifdef ENABLE_XMLRPC
|
|
+#include <xmlrpc.h>
|
|
+#include <xmlrpc_client.h>
|
|
+#define XMLRPC_CLIENT_NAME "XML-RPC RTPProxy Client"
|
|
+#define XMLRPC_CLIENT_VERSION "0.2"
|
|
+#endif
|
|
+
|
|
struct rtpp_notify_wi
|
|
{
|
|
char *notify_buf;
|
|
int len;
|
|
+#ifdef ENABLE_XMLRPC
|
|
+ char *call_id;
|
|
+ int call_id_len;
|
|
+ char *param;
|
|
+ int param_len;
|
|
+ int custom_handler;
|
|
+#endif
|
|
struct rtpp_timeout_handler *th;
|
|
rtpp_log_t glog;
|
|
struct rtpp_notify_wi *next;
|
|
@@ -258,6 +272,13 @@ rtpp_notify_schedule(struct cfg *cf, struct rtpp_session *sp)
|
|
if (wi == NULL)
|
|
return -1;
|
|
|
|
+#ifdef ENABLE_XMLRPC
|
|
+ if (th != cf->timeout_handler)
|
|
+ wi->custom_handler = 1;
|
|
+ else
|
|
+ wi->custom_handler = 0;
|
|
+#endif
|
|
+
|
|
wi->th = th;
|
|
if (sp->timeout_data.notify_tag == NULL) {
|
|
/* two 5-digit numbers, space, \0 and \n */
|
|
@@ -289,6 +310,59 @@ rtpp_notify_schedule(struct cfg *cf, struct rtpp_session *sp)
|
|
len = snprintf(wi->notify_buf, len, "%s\n",
|
|
sp->timeout_data.notify_tag);
|
|
}
|
|
+#ifdef ENABLE_XMLRPC
|
|
+
|
|
+ // rtpp_log_write(RTPP_LOG_ERR, wi->glog, "Timeout socket is: %s (%p)\n", wi->th->socket_name, wi->th->socket_name);
|
|
+
|
|
+ if (strncmp("xmlrpc:", wi->th->socket_name, 7) == 0) {
|
|
+ // Copy the Socket-Name
|
|
+ len = strlen(wi->th->socket_name)+1;
|
|
+ if (wi->param == NULL) {
|
|
+ wi->param = malloc(len);
|
|
+ if (wi->param == NULL) {
|
|
+ rtpp_notify_queue_return_free_item(wi);
|
|
+ return -1;
|
|
+ }
|
|
+ } else {
|
|
+ notify_buf = realloc(wi->param, len);
|
|
+ if (notify_buf == NULL) {
|
|
+ rtpp_notify_queue_return_free_item(wi);
|
|
+ return -1;
|
|
+ }
|
|
+ wi->param = notify_buf;
|
|
+ }
|
|
+ memset(wi->param, '\0', len);
|
|
+ len = snprintf(wi->param, len, "%s",
|
|
+ wi->th->socket_name);
|
|
+ wi->param_len = len;
|
|
+
|
|
+ // rtpp_log_write(RTPP_LOG_ERR, wi->glog, "wi->param %s (%p)\n", wi->param, wi->param);
|
|
+
|
|
+ // Copy the Call-ID:
|
|
+ len = strlen(sp->call_id)+1;
|
|
+ if (wi->call_id == NULL) {
|
|
+ wi->call_id = malloc(len);
|
|
+ if (wi->call_id == NULL) {
|
|
+ rtpp_notify_queue_return_free_item(wi);
|
|
+ return -1;
|
|
+ }
|
|
+ } else {
|
|
+ notify_buf = realloc(wi->call_id, len);
|
|
+ if (notify_buf == NULL) {
|
|
+ rtpp_notify_queue_return_free_item(wi);
|
|
+ return -1;
|
|
+ }
|
|
+ wi->call_id = notify_buf;
|
|
+ }
|
|
+ memset(wi->call_id, '\0', len);
|
|
+ len = snprintf(wi->call_id, len, "%s",
|
|
+ sp->call_id);
|
|
+ wi->call_id_len = len;
|
|
+
|
|
+ // rtpp_log_write(RTPP_LOG_ERR, wi->glog, "wi->call_id %s (%p)\n", wi->call_id, wi->call_id);
|
|
+
|
|
+ }
|
|
+#endif
|
|
|
|
wi->glog = cf->stable.glog;
|
|
|
|
@@ -345,29 +419,72 @@ reconnect_timeout_handler(rtpp_log_t log, struct rtpp_timeout_handler *th)
|
|
}
|
|
}
|
|
|
|
+#ifdef ENABLE_XMLRPC
|
|
+static int
|
|
+do_xmlrpc_timeout_notification(rtpp_log_t log, struct rtpp_notify_wi *wi) {
|
|
+ xmlrpc_env env;
|
|
+ xmlrpc_value *result;
|
|
+
|
|
+ /* Start up our XML-RPC client library. */
|
|
+ xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, XMLRPC_CLIENT_NAME, XMLRPC_CLIENT_VERSION);
|
|
+ xmlrpc_env_init(&env);
|
|
+
|
|
+ /* Get the dialog-Info: */
|
|
+ result = xmlrpc_client_call(&env, wi->param+7,
|
|
+ "dlg_terminate_dlg", "(s)",
|
|
+ wi->call_id);
|
|
+ if (env.fault_occurred) {
|
|
+ rtpp_log_write(RTPP_LOG_ERR, wi->glog, "%s: XML-RPC Fault: %s (%d)\n", wi->call_id, env.fault_string, env.fault_code);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /* Dispose of our result value. */
|
|
+ xmlrpc_DECREF(result);
|
|
+
|
|
+ /* Shutdown our XML-RPC client library. */
|
|
+ xmlrpc_env_clean(&env);
|
|
+ xmlrpc_client_cleanup();
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+#endif
|
|
+
|
|
static void
|
|
do_timeout_notification(struct rtpp_notify_wi *wi, int retries)
|
|
{
|
|
int result;
|
|
|
|
- if (wi->th->connected == 0) {
|
|
- reconnect_timeout_handler(wi->glog, wi->th);
|
|
-
|
|
- /* If connect fails, no notification will be sent */
|
|
- if (wi->th->connected == 0) {
|
|
- rtpp_log_write(RTPP_LOG_ERR, wi->glog, "unable to send timeout notification");
|
|
- return;
|
|
- }
|
|
+ if (strncmp("xmlrpc:", wi->th->socket_name, 7) == 0) {
|
|
+ result = do_xmlrpc_timeout_notification(wi->glog, wi);
|
|
+ } else {
|
|
+ if (wi->th->connected == 0) {
|
|
+ reconnect_timeout_handler(wi->glog, wi->th);
|
|
+
|
|
+ /* If connect fails, no notification will be sent */
|
|
+ if (wi->th->connected == 0) {
|
|
+ rtpp_log_write(RTPP_LOG_ERR, wi->glog, "unable to send timeout notification");
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ do {
|
|
+ result = send(wi->th->fd, wi->notify_buf, wi->len - 1, 0);
|
|
+ } while (result == -1 && errno == EINTR);
|
|
}
|
|
|
|
- do {
|
|
- result = send(wi->th->fd, wi->notify_buf, wi->len - 1, 0);
|
|
- } while (result == -1 && errno == EINTR);
|
|
-
|
|
if (result < 0) {
|
|
wi->th->connected = 0;
|
|
rtpp_log_ewrite(RTPP_LOG_ERR, wi->glog, "failed to send timeout notification");
|
|
if (retries > 0)
|
|
do_timeout_notification(wi, retries - 1);
|
|
}
|
|
+#ifdef ENABLE_XMLRPC
|
|
+ // In case we use a custom timeout handler, we have to free it.
|
|
+ if (wi->th && (wi->custom_handler == 1)) {
|
|
+ free(wi->th->socket_name);
|
|
+ free(wi->th);
|
|
+ wi->th = 0;
|
|
+ }
|
|
+#endif
|
|
+
|
|
}
|
|
diff --git a/rtpp_session.c b/rtpp_session.c
|
|
index 03e3d8a..51b3319 100644
|
|
--- a/rtpp_session.c
|
|
+++ b/rtpp_session.c
|
|
@@ -41,6 +41,7 @@
|
|
#include "rtpp_record.h"
|
|
#include "rtpp_session.h"
|
|
#include "rtpp_util.h"
|
|
+#include "rtpp_notify.h"
|
|
|
|
void
|
|
init_hash_table(struct cfg_stable *cf)
|