Bug#1088985: libsoup doesn't close connections, remaining as CLOSE_WAIT forever
Sergio Costas
sergio.costas at canonical.com
Tue Dec 3 19:42:48 GMT 2024
Package: libsoup-3.0-0
Version: 3.2.2-2
Severity: important
X-Debbugs-Cc: sergio.costas at canonical.com
Dear maintainer,
first of all, this bug has been fixed in libsoup 3.3 and later.
I wrote a little http server in C with libsoup and a client in
python using requests. The client periodically asks the server
for some data and closes the connection.
I found that in a Raspberry Pi with Raspbian (based on Debian
stable), the client hung up after some time working. After
researching, I discovered a lot of CLOSE_WAIT connections
linked to my server. After some time, there were so many
connections in that state that no new connections could be
made.
I did several tests, including writting a minimal server and
doing petitions with CURL, both in the Raspberry Pi as in a
virtual machine with DEBIAN BOOKWORM, and was able to
reproduce it, and confirmed that the culprit is libsoup:
updating it to version 3.3.0 (compiled from the git sources)
the problem disappears.
HOW TO REPRODUCE:
compile and launch this minimal server:
#include <gio/gio.h>
#include <glib.h>
#include <libsoup/soup.h>
#include <stdio.h>
#define SERVER_PORT 40006
SoupServer *server;
static int counter = 0;
void server_call(
SoupServer* server,
SoupServerMessage* msg,
const char* path,
GHashTable* query,
gpointer user_data
) {
gchar *response = g_strdup_printf("{\"counter\":%d}", counter++);
g_print("Received petition; response: %s\n", response);
soup_server_message_set_response(msg, "application/json", SOUP_MEMORY_TAKE, response, strlen(response));
soup_server_message_set_status(msg, 200, "OK");
}
void startup(GApplication *app, gpointer data) {
server = soup_server_new ("server-header", "simple-httpd ", NULL);
GError *error = NULL;
soup_server_listen_all (server, SERVER_PORT, SOUP_SERVER_LISTEN_IPV4_ONLY, &error);
soup_server_add_handler(server, NULL, server_call, NULL, NULL);
}
int main(int argc, char **argv) {
g_autoptr(GApplication) app =
g_application_new("com.rastersoft.souptest", G_APPLICATION_IS_SERVICE);
g_application_hold(app);
g_signal_connect(app, "startup", (GCallback)startup, NULL);
g_application_run(app, argc, argv);
return 0;
}
You can use this Makefile:
LIBS=glib-2.0 gio-2.0 gobject-2.0 libsoup-3.0
soup_test: soup_test.o
gcc -g -o $@ $^ `pkg-config --libs $(LIBS)`
soup_test.o: soup_test.c
gcc -c -g -O2 `pkg-config --cflags $(LIBS)` -o $@ $<
Now launch the server and, in another terminal, do a
netstat -ntop |grep CLOSE_WAIT
It should show nothing. Now, run:
curl http://127.0.0.1:40006
It should show {"counter":0} as response. If you now do again
netstat -ntop |grep CLOSE_WAIT
one line should appear, pinned to soup_test. Running CURL
more times will do appear more and more CLOSE_WAIT sockets.
As I already commented, this problem can cause resource
exhaustion, and also has already been fixed upstream.
-- System Information:
Debian Release: 12.8
APT prefers stable-updates
APT policy: (500, 'stable-updates'), (500, 'stable-security'), (500, 'stable')
Architecture: amd64 (x86_64)
Kernel: Linux 6.1.0-28-amd64 (SMP w/2 CPU threads; PREEMPT)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
Versions of packages libsoup-3.0-0 depends on:
ii glib-networking 2.74.0-4
ii libbrotli1 1.0.9-2+b6
ii libc6 2.36-9+deb12u9
ii libglib2.0-0 2.74.6-2+deb12u4
ii libgssapi-krb5-2 1.20.1-2+deb12u2
ii libnghttp2-14 1.52.0-1+deb12u2
ii libpsl5 0.21.2-1
ii libsoup-3.0-common 3.2.2-2
ii libsqlite3-0 3.40.1-2+deb12u1
ii zlib1g 1:1.2.13.dfsg-1
libsoup-3.0-0 recommends no packages.
libsoup-3.0-0 suggests no packages.
-- no debconf information
More information about the pkg-gnome-maintainers
mailing list