Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp2973862ybt; Mon, 22 Jun 2020 11:36:33 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzLqWHhG323k+8QccBWnqGmgZM1mUhwFDfzzuBow7AF7RdivcV1QyVDu8C+9ktGh/etgsl1 X-Received: by 2002:a17:906:f2c4:: with SMTP id gz4mr2524278ejb.484.1592850993453; Mon, 22 Jun 2020 11:36:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1592850993; cv=none; d=google.com; s=arc-20160816; b=uIqqLZXgedPkw6iQx7Fd88VtMVOvb4PQuA4tmKH9eYjSBSkuntRiNXRDPDaUG9aD3H TkISHYaWFiHEmdl/7/aqVHa626v5wct5AvCD96lMgy5hpyYaIwyh+0sorYJ8WFbrz0d4 96yapNAo32nkuYZzSW9wwFqzCtEqgHUR+EbJqyctFHAYAdqzZOh9/7Kbm7CPjS/+f5M3 qPsJXUG1kpouQ/mS2ghqECjSWZx/fA1sL1LoexkFSFGHdW5nEHtJauhIorEQDS7LkDCq C/k/7YdnsZm3tNZrnro+hMvxHGkXR1zkInRQesqSTfXLBE4RoBPEoX1bni4fTRd7o/Rp Qtpw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:to:references:message-id :content-transfer-encoding:cc:date:in-reply-to:from:subject :mime-version; bh=jQ5LYR2twAGNkU2WYQqAq+fID8wVKMkHAVEvqUllcxA=; b=w15yJkg/bz/kyvUjo6hWoetpAhmzLrKhLqHxA2gK6eK7diQYnzxkUsM3RU0+ZvAbQ8 FScQNAqPsZmozXtl+bO4EIcGQbw8dAQjLX64L8Fa1/HNe20d94gKqdaeePNyEiRSHGX0 P0r1AUaGWs2v4KfpPOHqq4R1+4H3B7EdaUrzkqpzbsOS1RIaJVj74/FKEvmvQWkQfaaO S27xJj0KydpN19hZ1y9u6w8G4+Wf4eKII/v2x74lg7gfBrsR74985Y2oWqQm6md23ZNT 5SlxmNahiB4CaR6oPXmZhf9tprL1hRrqsQm++a+OcheXDW6TxucFFKbPH1QSf6A8xhRX PaHQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id p20si4972780ejr.120.2020.06.22.11.36.08; Mon, 22 Jun 2020 11:36:33 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730361AbgFVSeH convert rfc822-to-8bit (ORCPT + 99 others); Mon, 22 Jun 2020 14:34:07 -0400 Received: from mail-n.franken.de ([193.175.24.27]:55891 "EHLO drew.franken.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1730139AbgFVSeH (ORCPT ); Mon, 22 Jun 2020 14:34:07 -0400 Received: from [10.0.3.1] (unknown [212.201.121.94]) (Authenticated sender: lurchi) by mail-n.franken.de (Postfix) with ESMTPSA id EC0A87220C6C8; Mon, 22 Jun 2020 20:34:02 +0200 (CEST) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.80.23.2.2\)) Subject: Re: Strange problem with SCTP+IPv6 From: Michael Tuexen In-Reply-To: <20200622183253.GQ2491@localhost.localdomain> Date: Mon, 22 Jun 2020 20:34:00 +0200 Cc: minyard@acm.org, Xin Long , Vlad Yasevich , Neil Horman , linux-sctp@vger.kernel.org, LKML Content-Transfer-Encoding: 8BIT Message-Id: References: <20200621155604.GA23135@minyard.net> <20200622165759.GA3235@minyard.net> <4B68D06C-00F4-42C3-804A-B5531AABCE21@lurchi.franken.de> <20200622183253.GQ2491@localhost.localdomain> To: Marcelo Ricardo Leitner X-Mailer: Apple Mail (2.3608.80.23.2.2) X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=disabled version=3.4.1 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on mail-n.franken.de Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org > On 22. Jun 2020, at 20:32, Marcelo Ricardo Leitner wrote: > > On Mon, Jun 22, 2020 at 08:01:24PM +0200, Michael Tuexen wrote: >>> On 22. Jun 2020, at 18:57, Corey Minyard wrote: >>> >>> On Mon, Jun 22, 2020 at 08:01:23PM +0800, Xin Long wrote: >>>> On Sun, Jun 21, 2020 at 11:56 PM Corey Minyard wrote: >>>>> >>>>> I've stumbled upon a strange problem with SCTP and IPv6. If I create an >>>>> sctp listening socket on :: and set the IPV6_V6ONLY socket option on it, >>>>> then I make a connection to it using ::1, the connection will drop after >>>>> 2.5 seconds with an ECONNRESET error. >>>>> >>>>> It only happens on SCTP, it doesn't have the issue if you connect to a >>>>> full IPv6 address instead of ::1, and it doesn't happen if you don't >>>>> set IPV6_V6ONLY. I have verified current end of tree kernel.org. >>>>> I tried on an ARM system and x86_64. >>>>> >>>>> I haven't dug into the kernel to see if I could find anything yet, but I >>>>> thought I would go ahead and report it. I am attaching a reproducer. >>>>> Basically, compile the following code: >>>> The code only set IPV6_V6ONLY on server side, so the client side will >>>> still bind all the local ipv4 addresses (as you didn't call bind() to >>>> bind any specific addresses ). Then after the connection is created, >>>> the client will send HB on the v4 paths to the server. The server >>>> will abort the connection, as it can't support v4. >>>> >>>> So you can work around it by either: >>>> >>>> - set IPV6_V6ONLY on client side. >>>> >>>> or >>>> >>>> - bind to the specific v6 addresses on the client side. >>>> >>>> I don't see RFC said something about this. >>>> So it may not be a good idea to change the current behaviour >>>> to not establish the connection in this case, which may cause regression. >>> >>> Ok, I understand this. It's a little strange, but I see why it works >>> this way. >> I don't. I would expect it to work as I described in my email. >> Could someone explain me how and why it is behaving different from >> my expectation? > > It looks like a bug to me. Testing with this test app here, I can see > the INIT_ACK being sent with a bunch of ipv4 addresses in it and > that's unexpected for a v6only socket. As is, it's the server saying > "I'm available at these other addresses too, but not." I agree. Best regards Michael > > Thanks, > Marcelo > >> >> Best regards >> Michael >>> >>> Thanks, >>> >>> -corey >>> >>>> >>>>> >>>>> gcc -g -o sctptest -Wall sctptest.c >>>>> >>>>> and run it in one window as a server: >>>>> >>>>> ./sctptest a >>>>> >>>>> (Pass in any option to be the server) and run the following in another >>>>> window as the client: >>>>> >>>>> ./sctptest >>>>> >>>>> It disconnects after about 2.5 seconds. If it works, it should just sit >>>>> there forever. >>>>> >>>>> -corey >>>>> >>>>> >>>>> #include >>>>> #include >>>>> #include >>>>> #include >>>>> #include >>>>> #include >>>>> #include >>>>> #include >>>>> #include >>>>> #include >>>>> #include >>>>> >>>>> static int >>>>> getaddr(const char *addr, const char *port, bool listen, >>>>> struct addrinfo **rai) >>>>> { >>>>> struct addrinfo *ai, hints; >>>>> >>>>> memset(&hints, 0, sizeof(hints)); >>>>> hints.ai_flags = AI_ADDRCONFIG; >>>>> if (listen) >>>>> hints.ai_flags |= AI_PASSIVE; >>>>> hints.ai_family = AF_UNSPEC; >>>>> hints.ai_socktype = SOCK_STREAM; >>>>> hints.ai_protocol = IPPROTO_SCTP; >>>>> if (getaddrinfo(addr, port, &hints, &ai)) { >>>>> perror("getaddrinfo"); >>>>> return -1; >>>>> } >>>>> >>>>> *rai = ai; >>>>> return 0; >>>>> } >>>>> >>>>> static int >>>>> waitread(int s) >>>>> { >>>>> char data[1]; >>>>> ssize_t rv; >>>>> >>>>> rv = read(s, data, sizeof(data)); >>>>> if (rv == -1) { >>>>> perror("read"); >>>>> return -1; >>>>> } >>>>> printf("Read %d bytes\n", (int) rv); >>>>> return 0; >>>>> } >>>>> >>>>> static int >>>>> do_server(void) >>>>> { >>>>> int err, ls, s, optval; >>>>> struct addrinfo *ai; >>>>> >>>>> printf("Server\n"); >>>>> >>>>> err = getaddr("::", "3023", true, &ai); >>>>> if (err) >>>>> return err; >>>>> >>>>> ls = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); >>>>> if (ls == -1) { >>>>> perror("socket"); >>>>> return -1; >>>>> } >>>>> >>>>> optval = 1; >>>>> if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, >>>>> (void *)&optval, sizeof(optval)) == -1) { >>>>> perror("setsockopt reuseaddr"); >>>>> return -1; >>>>> } >>>>> >>>>> /* Comment this out and it will work. */ >>>>> if (setsockopt(ls, IPPROTO_IPV6, IPV6_V6ONLY, &optval, >>>>> sizeof(optval)) == -1) { >>>>> perror("setsockopt ipv6 only"); >>>>> return -1; >>>>> } >>>>> >>>>> err = bind(ls, ai->ai_addr, ai->ai_addrlen); >>>>> if (err == -1) { >>>>> perror("bind"); >>>>> return -1; >>>>> } >>>>> >>>>> err = listen(ls, 5); >>>>> if (err == -1) { >>>>> perror("listen"); >>>>> return -1; >>>>> } >>>>> >>>>> s = accept(ls, NULL, NULL); >>>>> if (s == -1) { >>>>> perror("accept"); >>>>> return -1; >>>>> } >>>>> >>>>> close(ls); >>>>> >>>>> err = waitread(s); >>>>> close(s); >>>>> return err; >>>>> } >>>>> >>>>> static int >>>>> do_client(void) >>>>> { >>>>> int err, s; >>>>> struct addrinfo *ai; >>>>> >>>>> printf("Client\n"); >>>>> >>>>> err = getaddr("::1", "3023", false, &ai); >>>>> if (err) >>>>> return err; >>>>> >>>>> s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); >>>>> if (s == -1) { >>>>> perror("socket"); >>>>> return -1; >>>>> } >>>>> >>>>> err = connect(s, ai->ai_addr, ai->ai_addrlen); >>>>> if (err == -1) { >>>>> perror("connect"); >>>>> return -1; >>>>> } >>>>> >>>>> err = waitread(s); >>>>> close(s); >>>>> return err; >>>>> } >>>>> >>>>> int >>>>> main(int argc, char *argv[]) >>>>> { >>>>> int err; >>>>> >>>>> if (argc > 1) >>>>> err = do_server(); >>>>> else >>>>> err = do_client(); >>>>> return !!err; >>>>> } >>>>> >>