From nobody Wed Apr 3 17:46:38 2024 X-Original-To: freebsd-net@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4V8scz3pbnz5FVLq for ; Wed, 3 Apr 2024 17:46:43 +0000 (UTC) (envelope-from cryintothebluesky@gmail.com) Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "smtp.gmail.com", Issuer "GTS CA 1D4" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4V8scz20jtz43nN for ; Wed, 3 Apr 2024 17:46:43 +0000 (UTC) (envelope-from cryintothebluesky@gmail.com) Authentication-Results: mx1.freebsd.org; none Received: by mail-wr1-x436.google.com with SMTP id ffacd0b85a97d-343892ca0a7so30131f8f.3 for ; Wed, 03 Apr 2024 10:46:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1712166400; x=1712771200; darn=freebsd.org; h=mime-version:references:in-reply-to:message-id:subject:cc:to:from :date:from:to:cc:subject:date:message-id:reply-to; bh=yqpm2eFf42oRt0iz3klClOVntxAvvohahQ7oTn86uJQ=; b=LEet/ovRNHi/UIh60QRE5rtjkzKx6htQ79HLUM0EG0SKSBFR4WTUEX03XFVF+PqujE 8GOk8O6fZxmjowRFMlI4K7dHXoE3IyojThqsR1O8CbPTkaQirc/zJDHKmXSeo2MDXzZR h7sL5JZXmr06/o8e0WKfMycaIbLP8nO/3VXzU/OtPoCZP1toXey71U/Bwi1ISNyg9euU c5So6DWqdStEHed9r6Yz1+SA5N93qNzoLqpD2dzoi2qbKjhRiYHrW+hCv5ZQl7f0bdU5 VuKUtTbAie+cQBVE2NMPojNzh39CN3ytWniBPvJ0kghZS7zGKO05dPrMQ6M8iVTRU3XY /Pjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712166400; x=1712771200; h=mime-version:references:in-reply-to:message-id:subject:cc:to:from :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=yqpm2eFf42oRt0iz3klClOVntxAvvohahQ7oTn86uJQ=; b=W96GOqN/GJ/NqvbOhfnqKPEsVnQz4B+6h/V0sTlGh0naVtjiDT+is4xfgwaUc995bg WM8uY1db6o/1tnelrpZpv6E0io8v6rKc4vnzA2VWiL+aWKnrZ554p+amd82WlSM3sgj1 SeNA1Pht4gMdIiz/sEJFXhCiUo4RL+h949g6v4uV2ny+9AZkRWsP5Lij6wxU2v99I1Ju HmSMxngy9Nkl05HzNuvqNOR7bSIUWaGT2aC3XTQ8a1gNm3tn9DrKWpPfrApPfhKTJD+8 L+vvMhET2lGtroWgbXzk1rq3KR6UOzXX/ZcGzCcHhldo9dKc1+t/owaUpFAY8pwaiYaf T7lw== X-Gm-Message-State: AOJu0YyYUgidP2J9Ed320TT6adNoQgCeSlN/lAJlGO5N02i/MXB3q44a VRMYZw53TsBIYHwLojLGJcA9Y2rDJpMQNMS6J/fvVc0x+B6hU8ir X-Google-Smtp-Source: AGHT+IG0/Gp67cESZfZxCMcFy8PHrKEbD51uTCKOaxSu8LEP16uroLHXM7hOqg6ft+gF4AqpIR1Fbw== X-Received: by 2002:adf:fec4:0:b0:33e:b7f8:7c66 with SMTP id q4-20020adffec4000000b0033eb7f87c66mr184582wrs.41.1712166400295; Wed, 03 Apr 2024 10:46:40 -0700 (PDT) Received: from z600.home.lan (193.85.199.146.dyn.plus.net. [146.199.85.193]) by smtp.gmail.com with ESMTPSA id y17-20020a056000109100b00341de3abb0esm17711535wrw.20.2024.04.03.10.46.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Apr 2024 10:46:39 -0700 (PDT) Date: Wed, 3 Apr 2024 18:46:38 +0100 From: Sad Clouds To: Michael Tuexen Cc: "freebsd-net@freebsd.org" Subject: Re: TCP socket handling errors Message-Id: <20240403184638.aaf842926a7665d1f7fc8b14@gmail.com> In-Reply-To: <0BA9AF99-A50F-472F-8139-1BA9EA067F91@lurchi.franken.de> References: <20240403131434.c3bfa64c726505d842408c80@gmail.com> <20240403144445.9a5662aa66975430c73f9e6d@gmail.com> <0BA9AF99-A50F-472F-8139-1BA9EA067F91@lurchi.franken.de> X-Mailer: Sylpheed 3.7.0 (GTK+ 2.24.32; x86_64-pc-linux-gnu) List-Id: Networking and TCP/IP with FreeBSD List-Archive: https://lists.freebsd.org/archives/freebsd-net List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-net@freebsd.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="Multipart=_Wed__3_Apr_2024_18_46_38_+0100_SbkNPf9x/jE9zv/H" X-Spamd-Bar: ---- X-Rspamd-Pre-Result: action=no action; module=replies; Message is reply to one we originated X-Spamd-Result: default: False [-4.00 / 15.00]; REPLY(-4.00)[]; ASN(0.00)[asn:15169, ipnet:2a00:1450::/32, country:US] X-Rspamd-Queue-Id: 4V8scz20jtz43nN This is a multi-part message in MIME format. --Multipart=_Wed__3_Apr_2024_18_46_38_+0100_SbkNPf9x/jE9zv/H Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Wed, 3 Apr 2024 17:28:52 +0200 Michael Tuexen wrote: > > On 3. Apr 2024, at 15:44, Sad Clouds wrote: > > > > I found a bug that is still open from May 2010 and describes the same > > behaviour that I see with my application: > > > > https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=146845 > > > > If this hasn't been fixed over the last 14 years, then I guess I will > > add some code to simply ignore ECONNRESET on close(2) for FreeBSD and > > MacOS. This seems the be the general advice from other people who hit > > this issue. > I'll bring this up on the bi-weekly FreeBSD transport call. > > Best regards > Michael > > > Hello, I've attached a test program, this easily reproduces the issue on Raspberry Pi 4 within a few seconds of running it. Server output: $ ./econnreset server Server: accept() Server: shutdown() Server: close() ... Server: accept() Server: shutdown() Server: close() close() failed, error=Connection reset by peer Client output (aborts when server exists due to close() failure): $ while true; do ./econnreset client || break; done Client: connect() Client: shutdown() Client: close() ... Client: connect() Assertion failed: (int_val == 0), function client, file econnreset.c, line 156. Abort trap (core dumped) --Multipart=_Wed__3_Apr_2024_18_46_38_+0100_SbkNPf9x/jE9zv/H Content-Type: text/x-csrc; name="econnreset.c" Content-Disposition: attachment; filename="econnreset.c" Content-Transfer-Encoding: 7bit /* * cc -D_POSIX_C_SOURCE=200809L -D__BSD_VISIBLE -D__XSI_VISIBLE \ * -O2 -std=c11 -Wpedantic -Wall -o econnreset econnreset.c */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define ADDR "127.0.0.1" #define PORT 9999 #define SIZE (10 * 1024U * 1024U) #define CLI_ID "client" #define CLI_ID_LEN 6 #define SRV_ID "server" #define SRV_ID_LEN 6 static void server() { int int_val, sockfd, connfd; struct sockaddr_storage socket_addr = {0}; socklen_t socket_addr_size; uint8_t snd_buf[1024], rcv_buf[1024]; size_t snd_size, rcv_size, io_size; ssize_t ssize_val; /* Socket family */ ((struct sockaddr_in *)&socket_addr)->sin_family = AF_INET; /* Socket address */ int_val = inet_pton(AF_INET, ADDR, &(((struct sockaddr_in *)&socket_addr)->sin_addr)); assert(int_val == 1); /* Socket port */ ((struct sockaddr_in *)&socket_addr)->sin_port = htons(PORT); /* Socket size */ socket_addr_size = sizeof(struct sockaddr_in); sockfd = socket(socket_addr.ss_family, SOCK_STREAM, 0); assert(sockfd >= 0); int_val = bind(sockfd, (const struct sockaddr *)&socket_addr, socket_addr_size); assert(int_val == 0); int_val = listen(sockfd, 128); assert(int_val == 0); while (1) { printf("Server: accept()\n"); connfd = accept(sockfd, NULL, NULL); assert(connfd >= 0); /* Size of data to send/receive */ snd_size = rcv_size = SIZE; /* Data copy loop */ while (snd_size != 0 && rcv_size != 0) { /* Send data */ io_size = (sizeof(snd_buf) <= snd_size) ? sizeof(snd_buf) : snd_size; ssize_val = send(connfd, snd_buf, io_size, MSG_NOSIGNAL); if (ssize_val < 0) { fprintf(stderr, "send() failed, error=%s\n", strerror(errno)); goto cleanup; } snd_size -= (size_t)ssize_val; /* Receive data */ io_size = (sizeof(rcv_buf) <= rcv_size) ? sizeof(rcv_buf) : rcv_size; ssize_val = recv(connfd, rcv_buf, io_size, MSG_NOSIGNAL | MSG_WAITALL); if (ssize_val < 0) { fprintf(stderr, "recv() failed, error=%s\n", strerror(errno)); goto cleanup; } rcv_size -= (size_t)ssize_val; } /* Send server ID string to client */ ssize_val = send(connfd, SRV_ID, SRV_ID_LEN, MSG_NOSIGNAL); if (ssize_val <= 0) { fprintf(stderr, "send() failed, error=%s\n", strerror(errno)); goto cleanup; } /* No more sending, do TCP half close */ printf("Server: shutdown()\n"); int_val = shutdown(connfd, SHUT_WR); if (int_val != 0) { fprintf(stderr, "shutdown() failed, error=%s\n", strerror(errno)); goto cleanup; } /* Receive client ID string and verify it */ ssize_val = recv(connfd, rcv_buf, CLI_ID_LEN, MSG_NOSIGNAL | MSG_WAITALL); if (ssize_val < 0) { fprintf(stderr, "recv() failed, error=%s\n", strerror(errno)); goto cleanup; } assert(ssize_val == CLI_ID_LEN); assert(strncmp((char *)rcv_buf, CLI_ID, CLI_ID_LEN) == 0); cleanup: printf("Server: close()\n"); int_val = close(connfd); if (int_val != 0) { /* We hit https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=146845 */ fprintf(stderr, "close() failed, error=%s\n", strerror(errno)); exit(EXIT_FAILURE); } } } static void client() { int int_val, connfd; struct sockaddr_storage socket_addr = {0}; socklen_t socket_addr_size; uint8_t snd_buf[1024], rcv_buf[1024]; size_t snd_size, rcv_size, io_size; ssize_t ssize_val; /* Socket family */ ((struct sockaddr_in *)&socket_addr)->sin_family = AF_INET; /* Socket address */ int_val = inet_pton(AF_INET, ADDR, &(((struct sockaddr_in *)&socket_addr)->sin_addr)); assert(int_val == 1); /* Socket port */ ((struct sockaddr_in *)&socket_addr)->sin_port = htons(PORT); /* Socket size */ socket_addr_size = sizeof(struct sockaddr_in); connfd = socket(socket_addr.ss_family, SOCK_STREAM, 0); assert(connfd >= 0); printf("Client: connect()\n"); int_val = connect(connfd, (const struct sockaddr *)&socket_addr, socket_addr_size); assert(int_val == 0); /* Size of data to send/receive */ snd_size = rcv_size = SIZE; /* Data copy loop */ while (snd_size != 0 && rcv_size != 0) { /* Send data */ io_size = (sizeof(snd_buf) <= snd_size) ? sizeof(snd_buf) : snd_size; ssize_val = send(connfd, snd_buf, io_size, MSG_NOSIGNAL); assert(ssize_val >= 0); snd_size -= (size_t)ssize_val; /* Receive data */ io_size = (sizeof(rcv_buf) <= rcv_size) ? sizeof(rcv_buf) : rcv_size; ssize_val = recv(connfd, rcv_buf, io_size, MSG_NOSIGNAL | MSG_WAITALL); assert(ssize_val >= 0); rcv_size -= (size_t)ssize_val; } /* Send client ID string to server */ ssize_val = send(connfd, CLI_ID, CLI_ID_LEN, MSG_NOSIGNAL); assert(ssize_val >= 0); /* No more sending, do TCP half close */ printf("Client: shutdown()\n"); int_val = shutdown(connfd, SHUT_WR); assert(int_val == 0); /* Receive server ID string and verify it */ ssize_val = recv(connfd, rcv_buf, SRV_ID_LEN, MSG_NOSIGNAL | MSG_WAITALL); assert(ssize_val == SRV_ID_LEN); assert(strncmp((char *)rcv_buf, SRV_ID, SRV_ID_LEN) == 0); printf("Client: close()\n"); int_val = close(connfd); if (int_val != 0) { /* We hit https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=146845 */ fprintf(stderr, "close() failed, error=%s\n", strerror(errno)); exit(EXIT_FAILURE); } } int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage: econnreset client | server\n"); exit(EXIT_FAILURE); } if (strcmp(argv[1], "client") == 0) { client(); } else if (strcmp(argv[1], "server") == 0) { server(); } else { printf("Usage: econnreset client | server\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } --Multipart=_Wed__3_Apr_2024_18_46_38_+0100_SbkNPf9x/jE9zv/H--