From 8c416bc42e2cd6ca7b09cf0147ab235223c6491f Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 28 Apr 2025 09:44:18 -0400 Subject: [PATCH] MT#55283 obsolete usage of xmlrpc-c Replace with hand-rolled requests made via libcurl. Background: libxmlrpc-core-c3-dev packaging is currently broken in Debian Sid and this is a good opportunity to move away from it. Ref: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1102554 Change-Id: I8a09452220993afdac19654edf13d7f3f6ba64c9 (cherry picked from commit 5d985372d877783872b82f141dec66827d187384) --- daemon/Makefile | 4 +- daemon/call.c | 97 +++++++++++++++++++++++--------- debian/control | 1 - docs/compiling_and_installing.md | 1 - el/rtpengine.spec | 4 +- t/Makefile | 4 +- utils/gen-common-flags | 7 --- 7 files changed, 77 insertions(+), 41 deletions(-) diff --git a/daemon/Makefile b/daemon/Makefile index 7a4293e6f..25ec5cb81 100644 --- a/daemon/Makefile +++ b/daemon/Makefile @@ -23,7 +23,7 @@ CFLAGS+= $(CFLAGS_LIBZ) CFLAGS+= $(CFLAGS_OPENSSL) CFLAGS+= $(CFLAGS_LIBEVENT) CFLAGS+= $(CFLAGS_LIBPCRE) -CFLAGS+= $(CFLAGS_XMLRPC) +CFLAGS+= $(CFLAGS_LIBCURL) CFLAGS+= $(CFLAGS_JSON_GLIB) CFLAGS+= $(CFLAGS_LIBWEBSOCKETS) CFLAGS+= $(CFLAGS_LIBNFTNL) @@ -58,11 +58,11 @@ LDLIBS+= $(LDLIBS_GLIB) LDLIBS+= $(LDLIBS_GTHREAD) LDLIBS+= $(LDLIBS_LIBZ) LDLIBS+= $(LDLIBS_LIBPCRE) +LDLIBS+= $(LDLIBS_LIBCURL) LDLIBS+= $(LDLIBS_LIBCRYPTO) LDLIBS+= $(LDLIBS_OPENSSL) LDLIBS+= $(LDLIBS_LIBEVENT) LDLIBS+= $(LDLIBS_LIBPCAP) -LDLIBS+= $(LDLIBS_XMLRPC) LDLIBS+= $(LDLIBS_LIBHIREDIS) LDLIBS+= $(LDLIBS_JSON_GLIB) LDLIBS+= $(LDLIBS_LIBWEBSOCKETS) diff --git a/daemon/call.c b/daemon/call.c index 0ee9cf033..c39a8dd8b 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include @@ -304,11 +304,13 @@ out: log_info_pop(); } +static size_t cb_curl_write(char *ptr, size_t size, size_t nmemb, void *userdata) { + g_string_append_len(userdata, ptr, size * nmemb); + return size * nmemb; +} + void xmlrpc_kill_calls(void *p) { struct xmlrpc_helper *xh = p; - xmlrpc_env e; - xmlrpc_client *c; - xmlrpc_value *r; pid_t pid; sigset_t ss; int i = 0; @@ -385,47 +387,90 @@ retry: alarm(5); - xmlrpc_env_init(&e); - xmlrpc_client_setup_global_const(&e); - xmlrpc_client_create(&e, XMLRPC_CLIENT_NO_FLAGS, "ngcp-rtpengine", RTPENGINE_VERSION, - NULL, 0, &c); - if (e.fault_occurred) + g_autoptr(GString) body = g_string_new(""); + g_autoptr(GString) response = g_string_new(""); + + int ret = CURLE_FAILED_INIT; + CURL *curl = curl_easy_init(); + if (!curl) + goto fault; + if ((ret = curl_easy_setopt(curl, CURLOPT_URL, url)) != CURLE_OK) + goto fault; + if ((ret = curl_easy_setopt(curl, CURLOPT_POST, 1)) != CURLE_OK) + goto fault; + if ((ret = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cb_curl_write)) != CURLE_OK) goto fault; + if ((ret = curl_easy_setopt(curl, CURLOPT_WRITEDATA, response)) != CURLE_OK) + goto fault; + if ((ret = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, &(struct curl_slist) + {.data = "Content-type: text/xml"})) != CURLE_OK) + goto fault; + - r = NULL; switch (xh->fmt) { case XF_SEMS: - xmlrpc_client_call2f(&e, c, url, "di", &r, "(ssss)", - "sbc", "postControlCmd", tag->s, "teardown"); + g_string_append_printf(body, "" + "" + "di" + "" + "sbc" + "postControlCmd" + "" STR_FORMAT "" + "teardown" + "" + "", + STR_FMT(tag)); break; case XF_CALLID: - xmlrpc_client_call2f(&e, c, url, "teardown", &r, "(s)", call_id->s); + g_string_append_printf(body, "" + "" + "teardown" + "" + "" STR_FORMAT "" + "" + "", + STR_FMT(call_id)); break; case XF_KAMAILIO: - xmlrpc_client_call2f(&e, c, url, "dlg.terminate_dlg", &r, "(sss)", - call_id->s, tag->s, tag2->s); + g_string_append_printf(body, "" + "" + "dlg.terminate_dlg" + "" + "" STR_FORMAT "" + "" STR_FORMAT "" + "" STR_FORMAT "" + "" + "", + STR_FMT(call_id), STR_FMT(tag), STR_FMT(tag2)); break; } - if (r) - xmlrpc_DECREF(r); - if (e.fault_occurred) { - if (strcasestr(e.fault_string, "dialog not found")) + if ((ret = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body->str)) != CURLE_OK) + goto fault; + + if ((ret = curl_easy_perform(curl)) != CURLE_OK) + goto fault; + + if (strcasestr(response->str, "")) { + if (strcasestr(response->str, "dialog not found")) ; - else + else { + ret = CURLE_HTTP_RETURNED_ERROR; goto fault; + } } - xmlrpc_client_destroy(c); for (int j = 0; j < els_per_ent; j++) free(g_queue_pop_head(&xh->strings)); - xmlrpc_env_clean(&e); - - _exit(0); fault: - ilog(LOG_WARNING, "XMLRPC fault occurred: %s", e.fault_string); - _exit(1); + curl_easy_cleanup(curl); + + if (ret != CURLE_OK) { + ilog(LOG_WARNING, "XMLRPC fault occurred: %s", curl_easy_strerror(ret)); + _exit(1); + } + _exit(0); } g_slice_free1(sizeof(*xh), xh); diff --git a/debian/control b/debian/control index 0cf82a5aa..e9f4b0579 100644 --- a/debian/control +++ b/debian/control @@ -47,7 +47,6 @@ Build-Depends: libtest2-suite-perl, liburing-dev (>= 2.3) , libwebsockets-dev, - libxmlrpc-core-c3-dev (>= 1.16.07), libxtables-dev (>= 1.4) | iptables-dev (>= 1.4), ngcp-libcodec-chain-dev (>= 12.5) , pandoc, diff --git a/docs/compiling_and_installing.md b/docs/compiling_and_installing.md index 181833a8b..5fc8e3ffe 100644 --- a/docs/compiling_and_installing.md +++ b/docs/compiling_and_installing.md @@ -71,7 +71,6 @@ test suite. - *zlib* - *OpenSSL* - *PCRE* library - - *XMLRPC-C* version 1.16.08 or higher - *hiredis* library - *gperf* - *libcurl* version 3.x or 4.x diff --git a/el/rtpengine.spec b/el/rtpengine.spec index 61e517aaf..946033a4d 100644 --- a/el/rtpengine.spec +++ b/el/rtpengine.spec @@ -29,7 +29,7 @@ Conflicts: %{name}-kernel < %{version}-%{release} BuildRequires: gcc make pkgconfig %{redhat_rpm_config} BuildRequires: glib2-devel libcurl-devel openssl-devel pcre-devel -BuildRequires: xmlrpc-c-devel zlib-devel hiredis-devel +BuildRequires: zlib-devel hiredis-devel BuildRequires: libpcap-devel libevent-devel json-glib-devel BuildRequires: mosquitto-devel BuildRequires: gperf perl-IPC-Cmd @@ -50,7 +50,7 @@ BuildRequires: pkgconfig(libmnl) pkgconfig(libnftnl) pandoc ncurses-devel BuildRequires: pkgconfig(libiptc) %endif -%if 0%{?with_transcoding} > 0 +if 0%{?with_transcoding} > 0 BuildRequires: ffmpeg-devel Requires(pre): ffmpeg-libs %endif diff --git a/t/Makefile b/t/Makefile index d1c2eedc8..3b7b34a21 100644 --- a/t/Makefile +++ b/t/Makefile @@ -21,6 +21,7 @@ CFLAGS+= $(CFLAGS_GLIB) CFLAGS+= $(CFLAGS_GTHREAD) CFLAGS+= $(CFLAGS_OPENSSL) CFLAGS+= $(CFLAGS_LIBPCRE) +CFLAGS+= $(CFLAGS_LIBCURL) CFLAGS+= $(CFLAGS_JSON_GLIB) ifeq ($(with_transcoding),yes) CFLAGS+= $(CFLAGS_LIBAVCODEC) @@ -33,7 +34,6 @@ CFLAGS+= $(CFLAGS_OPUS) CFLAGS+= $(CFLAGS_LIBZ) CFLAGS+= $(CFLAGS_LIBWEBSOCKETS) CFLAGS+= $(CFLAGS_LIBEVENT) -CFLAGS+= $(CFLAGS_XMLRPC) CFLAGS+= -DWITH_TRANSCODING ifeq ($(RTPENGINE_EXTENDED_TESTS),1) CFLAGS+= -DWITH_AMR_TESTS @@ -49,6 +49,7 @@ LDLIBS+= $(LDLIBS_GTHREAD) LDLIBS+= $(LDLIBS_LIBCRYPTO) LDLIBS+= $(LDLIBS_OPENSSL) LDLIBS+= $(LDLIBS_LIBPCRE) +LDLIBS+= $(LDLIBS_LIBCURL) LDLIBS+= $(LDLIBS_JSON_GLIB) ifeq ($(with_transcoding),yes) LDLIBS+= $(LDLIBS_LIBAVCODEC) @@ -62,7 +63,6 @@ LDLIBS+= $(LDLIBS_LIBZ) LDLIBS+= $(LDLIBS_LIBWEBSOCKETS) LDLIBS+= $(LDLIBS_LIBPCAP) LDLIBS+= $(LDLIBS_LIBEVENT) -LDLIBS+= $(LDLIBS_XMLRPC) LDLIBS+= $(LDLIBS_LIBHIREDIS) LDLIBS+= $(LDLIBS_MYSQL) endif diff --git a/utils/gen-common-flags b/utils/gen-common-flags index 09f3bd8e3..7db0ed958 100755 --- a/utils/gen-common-flags +++ b/utils/gen-common-flags @@ -87,13 +87,6 @@ gen-pkgconf-flags OPENSSL openssl gen-pkgconf-flags OPUS opus gen-pkgconf-flags SPANDSP spandsp -echo "export CFLAGS_XMLRPC := $(pkg-config xmlrpc_client --cflags 2> /dev/null || xmlrpc-c-config client --cflags)" -echo "CFLAGS_XMLRPC += $(pkg-config xmlrpc --cflags 2> /dev/null)" -echo "CFLAGS_XMLRPC += $(pkg-config xmlrpc_util --cflags 2> /dev/null)" -echo "export LDLIBS_XMLRPC := $(pkg-config xmlrpc_client --libs 2> /dev/null || xmlrpc-c-config client --libs)" -echo "LDLIBS_XMLRPC += $(pkg-config xmlrpc --libs 2> /dev/null)" -echo "LDLIBS_XMLRPC += $(pkg-config xmlrpc_util --libs 2> /dev/null)" - echo "export CFLAGS_MYSQL := $(mysql_config --cflags)" echo "export LDLIBS_MYSQL := $(mysql_config --libs)"