From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Robin Tarsiger Newsgroups: gmane.emacs.devel Subject: Re: ai_flags in calls to getaddrinfo Date: Fri, 1 Jan 2021 05:40:48 -0600 Message-ID: <05b7ddd3-2a37-8ae6-31b8-07e212538595@dasyatidae.com> References: <83sg7mggls.fsf@gnu.org> <838s9dgkzt.fsf@gnu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="19910"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.6.0 Cc: emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Fri Jan 01 12:41:43 2021 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kvIoQ-000542-BG for ged-emacs-devel@m.gmane-mx.org; Fri, 01 Jan 2021 12:41:42 +0100 Original-Received: from localhost ([::1]:43688 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kvIoP-00048C-Da for ged-emacs-devel@m.gmane-mx.org; Fri, 01 Jan 2021 06:41:41 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:49726) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kvInd-0003hO-Lo for emacs-devel@gnu.org; Fri, 01 Jan 2021 06:40:53 -0500 Original-Received: from out4-smtp.messagingengine.com ([66.111.4.28]:51679) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kvInb-0002ze-8m; Fri, 01 Jan 2021 06:40:53 -0500 Original-Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id 105EE5C0079; Fri, 1 Jan 2021 06:40:50 -0500 (EST) Original-Received: from mailfrontend2 ([10.202.2.163]) by compute1.internal (MEProxy); Fri, 01 Jan 2021 06:40:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm1; bh=cZbrTjC4vgLpvBjsj17dH8VzVb9yNhfYsIx5LHMNK ps=; b=DKxFjdFDS87N6u9pIlysEiZ6faEa8gvoebXh6RR4mcDN18+aIyXZxvHS4 mhXCqMFTX53g5QK2Ev8TlNmGY/L2K6L/uIoa5KC50zs9sMPj2OrXsYpOS9TAf0eh ImBlVH19SzZeB9vMI8PjnEFaccDEZl4UPfwDOFtlXH/jA2if0WMYiYzRAIVehetA a5PtFP93QdiskhyoO4XsOBCmLyF4/0K18ay5SXrDfUsgvKulBt3T5w3ds/Sx8mGn 4+HUeocr8P8DnpG9rzu4mpozaSGvzn8vCF1H3+7GigNpGS5fD0cyQebm9i6D7vFm /XR619us9L3wA2xUHAjTNK3Sd0rMQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrvddvjedgfeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepvfhfhffukffffgggjggtgfesthekredttdefjeenucfhrhhomheptfhosghi nhcuvfgrrhhsihhgvghruceorhhtthesuggrshihrghtihgurggvrdgtohhmqeenucggtf frrghtthgvrhhnpeehveehleevlefhkeduheefffeffeekvdffudekhfektdehueduffek feduieefhfenucffohhmrghinhepmhhitghrohhsohhfthdrtghomhenucfkphepjeeird dvheefrdejhedrfeegnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghi lhhfrhhomheprhhtthesuggrshihrghtihgurggvrdgtohhm X-ME-Proxy: Original-Received: from [192.168.1.65] (76-253-75-34.lightspeed.austtx.sbcglobal.net [76.253.75.34]) by mail.messagingengine.com (Postfix) with ESMTPA id 91C661080057; Fri, 1 Jan 2021 06:40:48 -0500 (EST) In-Reply-To: <838s9dgkzt.fsf@gnu.org> Content-Language: en-US-large Received-SPF: none client-ip=66.111.4.28; envelope-from=rtt@dasyatidae.com; helo=out4-smtp.messagingengine.com X-Spam_score_int: -59 X-Spam_score: -6.0 X-Spam_bar: ------ X-Spam_report: (-6.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, NICE_REPLY_A=-3.399, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:262235 Archived-At: So, as I come back to this, I think I tunnel-visioned on the AI_V4MAPPED behavior at first since that was what you changed, but I now think that's a red herring, and the potential problem in Emacs is the _last_ part of this: >>> On one of the systems on which I work, getaddrinfo called with >>> AF_INET6 fails with EAI_NODATA, for some reason. That causes >>> network-lookup-address-info to fail when passed 'ipv6' as the last >>> argument. Some non-zero return values from getaddrinfo, including EAI_NODATA, don't actually indicate resolution failures. From glibc getaddrinfo(3), there's also EAI_NONAME and EAI_ADDRFAMILY. I think the real point of difficulty is that network_lookup_address_info_1 always turns these into messageable warnings. To be clear, is that the behavior you are seeing on the Windows 10 machine, or is there some different failure occurring? I notice that EAI_NODATA isn't mentioned in the Windows docs[1], but if it's actually getting returned, I'd guess it has the same semantics as in glibc: "got a valid result indicating no addresses found". The exact distinction between "answer is: no data" error codes is more nonportable, but that won't matter if you treat them identically. [1] https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo#return-value >From an elisp standpoint, what do you want to have actually happen: 1. If a program requests a name that doesn't exist at all? 2. If a program requests a name that exists and has addresses of some families (such as IPv4 addresses), but the program has specifically requested another family (such as IPv6)? 3. If a program requests a name that exists but has no addresses at all? This is entirely possible in the DNS; dasyatidae.com is even currently such a name, having only MX records and no address records. Based on the docstring, I would imagine a silent nil for all three. In particular, the docstring implies that out-of-family addresses are _not_ returned when FAMILY is not nil. But I don't know how elisp programs currently use network-lookup-address-info. >From another perspective, when would a program pass a non-nil FAMILY value in the first place? If a program just wants any address, that's already handled by passing nil for FAMILY. If what you want is to treat it more like a preference rather than a requirement, you'll probably have to do something more complicated. If FAMILY expresses a requirement, then nil would be correct if nothing matches the criteria. (There's a potential question of whether AI_ADDRCONFIG is relevant if you want to be DWIM-y, but let's leave that for later.) I think that's the key here in terms of what can be done in Emacs. More comments below on other things. >> Does it have any IPv6 addresses configured, or no? What is >> its resolver configuration like? > > No idea. If you tell me how to find out, I will try. This system is > behind firewalls up the kazoo, so it could be something essential for > IPv6 DNS is blocked or intentionally disabled. If you run 'ipconfig/all' from a command line (which, if you are not familiar, you can launch by running 'cmd' from the 'Run' dialog, which in turn can be accessed through the Windows+R shortcut), it should display a bunch of information about active network connections, including local IP addresses and DNS resolver addresses. >> AI_V4MAPPED is meant for the case where an application expects only >> IPv6-formatted addresses in a list, but a host with only IPv4 addresses >> should have those addresses included in a mangled form. It is an >> address format compatibility hack. (The compatibility hack extends >> to other parts of the network stack, so that attempting to connect to >> such an address actually results in IPv4 packets on the wire, etc.) > > Yes, I understand that much. But it could be better than a total > failure, at least in some use cases, no? That's why this flag exists, > right? Not really. It's more a convenience for C programs that for whatever reason don't want to or can't dispatch on the address family all the time, potentially do multiple getaddrinfo calls, etc. In almost all cases, handling v4 and v6 addresses as separate is saner, or at least I think so, and it looks like we're in that straightforward dual-format world already from elisp's perspective. To put it differently: from my perspective, the main use for AI_V4MAPPED is when there is no IPv4-handling code path at all, and all IPv4 addresses are routed through the "IPv6" path as compatibility-mapped, which can save some complexity and hassle elsewhere. If you code against "true" multi-address-family, then it's just a faucet for bugs (say, trying to filter out some IPv4 netblocks but then letting them through anyway when they come through mapped into pseudo-IPv6 addresses). I'm not sure all C network programmers would agree with me. >> On a GNU system, I think this will do nothing; it's not clear to me >> what AI_V4MAPPED would even mean when ai_family = AF_UNSPEC, >> because AF_UNSPEC means IPv4 addresses can be returned directly. > > According to the GNU/Linux getaddrinfo man page: > > If hints.ai_flags specifies the AI_V4MAPPED flag, and > hints.ai_family was specified as AF_INET6, and no matching IPv6 > addresses could be found, then return IPv4-mapped IPv6 addresses > in the list pointed to by res. If both AI_V4MAPPED and AI_ALL > are specified in hints.ai_flags, then return both IPv6 and > IPv4-mapped IPv6 addresses in the list pointed to by res. AI_ALL > is ignored if AI_V4MAPPED is not also specified. > > So it does sound like these flags do have effect on GNU/Linux. If ai_family is AF_INET6, it does. I don't think it has an effect if ai_family is AF_UNSPEC. I am not 100% sure, but a quick test with resolving some names from a GNU/Linux machine (v4-only, v6-only, dual-stack) with AF_UNSPEC didn't return anything different with AI_V4MAPPED or AI_V4MAPPED | AI_ALL compared to none of those. >> What about "localhost"? > Works as expected, without EAI_NODATA. I interpret "as expected" to mean that when you ask for localhost in AF_INET6, you get ::1 back. Is that right? > On the > system in question, using the patched code and nil as FAMILY in the > network-lookup-address-info yields the expected result, including, > surprisingly, what looks like a valid IPv6 address, even though > specifying 'ipv6 for FAMILY does indeed return a compatibility-hacked > IPv4 address. What happens if you pass nil for FAMILY but without the AI_V4MAPPED patch, on that system? Have you observed AI_V4MAPPED producing better results in any circumstance when you do not set FAMILY to ipv6? I conjecture that your upstream resolver is blocking AAAA queries, and that AF_UNSPEC is going through a slightly different path, maybe even issuing an ANY query which is actually responded to with records from both address families, which are then passed through because response filtering and query filtering are different. If this is close to true, I'm not sure there's a sane way for an application to handle inconsistent resolver behavior of that stripe. > If this is controversial, maybe having it as opt-in behavior, > controlled by some new optional argument, would be useful? If it turns out to be something Windows-specific, you could of course conditionalize on that. If it's network-specific, and there's an actual need to handle it, then maybe a global "workaround for this particular bad behavior" toggle, but that could be starting down a rabbit hole, because there's a lot of possible network-specific bogus behaviors. It would separately be sane to add a hint-list argument or something to network-lookup-address-info and derive ai_flags from that; if it is determined that AI_V4MAPPED is actually desirable sometimes, then that would be a good way to go about it, essentially passing the getaddrinfo behavior up one level. But let's see what's actually going on first. > I found about this issue because 2 tests in test/src/process-tests.el > failed, both of them called network-lookup-address-info with second > arg 'ipv6'. You mean lookup-family-specification and lookup-google, I imagine? Hmm. If I get a chance, I will see what Emacs does with the forms from those tests on one of my Windows machines and report back. -RTT