From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 107107 invoked by alias); 12 Jan 2017 10:59:27 -0000 Mailing-List: contact cygwin-help@cygwin.com; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner@cygwin.com Mail-Followup-To: cygwin@cygwin.com Received: (qmail 107083 invoked by uid 89); 12 Jan 2017 10:59:26 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.1 required=5.0 tests=AWL,BAYES_50,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,RCVD_IN_SORBS_SPAM,SPF_PASS autolearn=no version=3.3.2 spammy=secrets, Christians, christians, lately X-HELO: mail-ua0-f170.google.com Received: from mail-ua0-f170.google.com (HELO mail-ua0-f170.google.com) (209.85.217.170) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 12 Jan 2017 10:59:15 +0000 Received: by mail-ua0-f170.google.com with SMTP id i68so11481613uad.0 for ; Thu, 12 Jan 2017 02:59:15 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=nREDsntOoXGgdL/bfnlOCqQPu0MkQ4RjMLJdfHC7QwY=; b=QPLT+vY+y705LGT/QHhL38YntQmtwioBZt+wHo9AtUcnZPl7B1cTmQLdwSxxS6xIYq 8yvjwcRJxl9Az8Q7WQh1BP7ZBTosK/YWH3/8FVWiDAZ0AKD5y7KNNhPS9yvbNj6zTX4w avFmq5SyyEeAueryVcNlFrxIv3PfQwWKAqG/9z/q3GazHPX0sEraxY/Fzd85iUWL+bwb ljA674x2kbEyceP9uCv95tLBiZib/Qq+G8JVzS1UdIGeWkCCPrn/cdosVoBOKwepriW5 kHeLnrMFeZH6nJMJXdHs7HRcBA2X8nFFFca/m5+2sEtw6j9zL0plvXs9mdxV/2795wDz I9kQ== X-Gm-Message-State: AIkVDXLg/TSm+gNh1+6PbMkP09As2VHrp5lirOvAvybQszcRQCMv7+MDKi5IIbzpQsQS2IHoc8eO7kjRwT5grA== X-Received: by 10.159.34.231 with SMTP id 94mr247666uan.53.1484218753624; Thu, 12 Jan 2017 02:59:13 -0800 (PST) MIME-Version: 1.0 Received: by 10.103.133.147 with HTTP; Thu, 12 Jan 2017 02:59:13 -0800 (PST) In-Reply-To: <20170109171635.GB26337@calimero.vinschen.de> References: <20170109141306.GB843@calimero.vinschen.de> <20170109171635.GB26337@calimero.vinschen.de> From: Erik Bray Date: Thu, 12 Jan 2017 10:59:00 -0000 Message-ID: Subject: Re: Hangs on connect to UNIX socket being listened on in the same process (was: Cygwin hanging in pselect) To: cygwin@cygwin.com Content-Type: text/plain; charset=UTF-8 X-IsSubscribed: yes X-SW-Source: 2017-01/txt/msg00111.txt.bz2 On Mon, Jan 9, 2017 at 6:16 PM, Corinna Vinschen wrote: > On Jan 9 16:46, Erik Bray wrote: >> Hi Corinna, >> >> Thanks for the response. >> >> On Mon, Jan 9, 2017 at 3:13 PM, Corinna Vinschen wrote: >> > Right. It has to do with how connect/accept works on AF_LOCAL sockets. >> > The handshake doesn't work well for situations like yours, where the >> > same thread tries to connect and accept on the same socket. >> >> Actually I'm not entirely sure now that that's the issue, even >> considering that this has come up before. Or at the very least, >> there's an additional issue. I realized that when I tried separate >> client/server processes, in the server I had put an accept() call at >> the end so it would block there. With the server waiting to accept a >> connection it succeeded. However, when I replaced the accept() with a >> long sleep(), the client's connect() never returns. > > That's because connect infinitely waits for the accept to reply the > second half of the handshake. > >> IIUC the handshake can't succeed until and unless the server accepts a >> connection from the client. > > This is exactly the underlying problem. And interesting enough, even > though the handshake is in Cygwin since 2001, we never had a problem > with this until Christian started porting postfix in 2014! > >> I almost wonder if the server side in this case >> shouldn't start up a thread to accept the af_local handshake, but you >> would know better. > > No, I don't. We discussed this issue briefly back in 2014, but as > you can see we don't have a solution for this border case yet. > > Starting a thread may or may not work, but there are a couple of > use-cases to keep in mind (which I can't reproduce off the top of my head). > The old postfix cygwin-apps thread from 2014 might give you some idea. > >> > This has been found a problem in porting postfix already and at the time >> > we added a patch to circumvent the problem. Before calling connect, add >> > this: >> > >> > setsockopt (sock_server, SOL_SOCKET, SO_PEERCRED, NULL, 0); >> > setsockopt (sock_client, SOL_SOCKET, SO_PEERCRED, NULL, 0); >> > >> > This is, of course, a hack. The problem here is that server and client >> > of a socket are independent of each other, and there's typically no >> > way to know which process created the server side unless you already >> > are connected. Chicken/egg. >> >> I tried it and it worked, both in the single process and separate >> process examples. I see now--this sets >> fhandler_socket::no_getpeerid=true, so it doesn't have to do the >> handshake at all. > > Right. A better solution for the problem would be nice. Ultimately > we want to check if the other side of the socket is actually a Cygwin > process which knows the secret, not a stray native Windows process > which accidentally hopped on the bandwagon, and we want to exchange > the credentials so a subsequent SO_PEERCRED call returns correct values. Ah, okay. I found the original thread you mentioned, and I see that you sort of discussed some possibilities but nothing was quite satisfactory at the time, and it was dropped--you mentioned some idea about exchanging information via pipes, but that was a bit complicated and half-baked. Christian described a scheme in that thread which at least seemed like a way out of the connect hanging problem, and also improved the security (I think) by having separate server and client secrets, so that a malicious server could not gain the socket secret from the client. But he also worried: > The only drawback which remains is that the client performs the send() > before first recv() unconditionally. It will realize the bad server secret > lately on first recv(). Though you wrote: > Yeah, but it might be better than nothing and if it avoids the hangs, > even better. Which is sort of how I feel, though I do appreciate the security implication. One workaround to that which I think might be relatively simple: In Christian's scheme, after a connect() the client would be in a "connected but secret missing" state. What I would propose adding is that the client then fires up a thread to wait on receiving the server's secret (which it would send after receiving the client's secret in an accept()). Meanwhile, while the cliet is in the "secret missing" state, any subsequent send()s would place the sent data on a local buffer (no bigger than getsockopt(SO_SNDBUF) ?) that would only get flushed out to actual WSASendTo calls once the server secret is received. The only downside I see to this is the added overhead of having to start a thread for the purpose of waiting to receive the server's secret which--in many common cases--would be unneeded since the server may accept() immediately. So in that case we might default to blocking to receive the server's secret, but with a relatively brief timeout, and then only start up a thread in case the server secret isn't received quickly. Best, Erik -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple