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