Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754547AbbBAVa5 (ORCPT ); Sun, 1 Feb 2015 16:30:57 -0500 Received: from fallback7.mail.ru ([94.100.181.128]:47879 "EHLO fallback7.mail.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753719AbbBAVaz (ORCPT ); Sun, 1 Feb 2015 16:30:55 -0500 From: =?UTF-8?B?QXNrYXIgU2FmaW4=?= To: linux-kernel@vger.kernel.org Subject: =?UTF-8?B?VENQIGNvbm5lY3Rpb25zIGNvbWUgaW4gd3Jvbmcgb3JkZXI=?= MIME-Version: 1.0 X-Mailer: Mail.Ru Mailer 1.0 X-Originating-IP: [213.87.131.120] Date: Mon, 02 Feb 2015 00:30:31 +0300 Reply-To: =?UTF-8?B?QXNrYXIgU2FmaW4=?= X-Priority: 3 (Normal) Message-ID: <1422826231.817940808@f237.i.mail.ru> Content-Type: text/plain; charset=utf-8 X-Mras: Ok X-Spam: undefined Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from base64 to 8bit by nfs id t11LV3Ug032162 Content-Length: 4539 Lines: 189 Consider the following code: // C99, No error checking for simplicity #include #include #include #include #include #include #include static int tcp_connect_loop (const char *host, const char *protocol, struct addrinfo *res) { for (; res != NULL; res = res->ai_next) { int result = socket (res->ai_family, res->ai_socktype, res->ai_protocol); if (result != -1) { if (connect (result, res->ai_addr, res->ai_addrlen) == 0) { return result; } close (result); } } // SOMEDAY: печатать больше инфы (то же для tcp_listen_loop)? errx (EXIT_FAILURE, "sh_tcp_connect: [%s]:%s: all structs returned by getaddrinfo failed", host, protocol); } int //@ sh_tcp_connect (const char *host, const char *protocol, int family)//@; { struct addrinfo hints = {}; hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; struct addrinfo *res; getaddrinfo (host, protocol, &hints, &res); // POSIX 2013 says that now 'res' list contains at least one item int result; result = tcp_connect_loop (host, protocol, res); freeaddrinfo (res); return result; } static int tcp_listen_loop (const char *protocol, struct addrinfo *res) { for (; res != NULL; res = res->ai_next) { int result = socket (res->ai_family, res->ai_socktype, res->ai_protocol); if (result != -1) { const int on = 1; if (setsockopt (result, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != -1) { if (bind (result, res->ai_addr, res->ai_addrlen) == 0) { return result; } } close (result); } } errx (EXIT_FAILURE, "sh_tcp_listen: *:%s: all structs returned by getaddrinfo failed", protocol); } int //@ sh_tcp_listen (const char *protocol, int family)//@; { struct addrinfo hints = {}; hints.ai_flags = AI_PASSIVE; hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; struct addrinfo *res; getaddrinfo (NULL, protocol, &hints, &res); int result; result = tcp_listen_loop (protocol, res); listen (result, 5); freeaddrinfo (res); return result; } #ifndef N #define N 100000 #endif int main (int argc, char *argv[]) { if (strcmp (argv[1], "-l") == 0) { int l = sh_tcp_listen (argv[2], AF_INET); for (;;) { int s = accept (l, NULL, NULL); if (s == -1) { continue; } char buf[1000]; write (1, buf, read (s, buf, sizeof (buf))); close (s); } } else { for (int i = 0; i != N; ++i) { int s = sh_tcp_connect (argv[1], argv[2], AF_INET); dprintf (s, "%d\n", i); close (s); } } exit (EXIT_SUCCESS); } Compile this code as, for example, /tmp/x (again: this is C99), then run: /tmp/x -l 5555 > /tmp/ooo This command will accept connections and write coming data to /tmp/ooo . Okey, then run in another terminal: /tmp/x localhost 5555 This command will connect to localhost, write 0, then connect again, write 1, etc. Soon you will not have available ports, so /tmp/x will fail before it will perform all N connections, this is OK. When this command complete, go to the first terminal and kill the program using Ctrl-C. Then look in /tmp/ooo and notice the last line, let's assume this is 28290. Then compare /tmp/ooo with the right monotonic number sequence: echo {0..28290} | tr ' ' '\n' | diff -ur - /tmp/ooo With some luck you will notice that /tmp/ooo is wrong. For example, I got the following: --- - 2015-02-02 00:24:35.606008461 +0300 +++ /tmp/ooo 2015-02-02 00:09:25.002694629 +0300 @@ -7391,8 +7391,6 @@ 7390 7391 7392 -7393 -7394 7395 7396 7397 @@ -7546,6 +7544,8 @@ 7545 7546 7547 +7393 +7394 7548 7549 7550 If 'diff' doesn't report difference, then try again and again. Is this a bug? I think that this is a bug. Linux ideal-os 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt2-1 (2014-12-08) x86_64 GNU/Linux Debian 8.0 Jessie GNU C Library (Debian GLIBC 2.19-13) stable release version 2.19, by Roland McGrath et al. == Askar Safin http://vk.com/safinaskar Kazan, Russia????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?