TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Potholes to avoid when migrating to IPv6

146 点作者 deafcalculus超过 6 年前

22 条评论

GlitchMr超过 6 年前
Don&#x27;t manually parse those things. If your database provides a way to parse those (like PostgreSQL does), make use of it. Use what your programming language provides, and if it really doesn&#x27;t provide the functionality to parse IPv6 addresses, use a library to do so.<p>For example, in Rust you can write this:<p><pre><code> use std::error::Error; use std::net::{AddrParseError, SocketAddr}; fn parse_address(addr: &amp;str) -&gt; Result&lt;SocketAddr, AddrParseError&gt; { addr.parse() .or_else(|_| Ok(SocketAddr::new(addr.parse()?, 10443))) } fn main() -&gt; Result&lt;(), Box&lt;dyn Error&gt;&gt; { let addresses = [ &quot;[2001:0db8:f00f::0553:1211:0088]:10444&quot;, &quot;2001:0db8:f00f::0553:1211:0088&quot;, ]; for address in &amp;addresses { println!(&quot;{:?}&quot;, parse_address(address)?); } Ok(()) } </code></pre> This isn&#x27;t specific to IPv6 by the way. It also applies to other standards like CSV (although I suppose with CSV it does vary, I saw so many broken CSV files that sometimes a custom implementation is the best way to go to parse those).
评论 #18794216 未加载
评论 #18795269 未加载
评论 #18794674 未加载
zAy0LfpBZLC8mAC超过 6 年前
Well, I mean, yes, those are all mistakes people are going to make, no doubt about that. But somehow the solution is missing?<p>The core mistake here is using string manipulation at all. The only correct way to handle string data is to parse it, and then either operate on the parsed data structure, or re-serialize into a canonical format and use that for comparisons and stuff.<p>And in the best case, you don&#x27;t try to build your own parser, but use a well-tested one that&#x27;s already there. For the particular use case of parsing IP addresses, it&#x27;s probably best to use getaddrinfo() with AI_NUMERICHOST, and for re-serialization getnameinfo() with the same flag. If those don&#x27;t understand the address, you most likely won&#x27;t be able to connect anyway. And they will handle stuff like link-local addresses correctly, at least as long as you are on the host that actually has the respective interface.<p>For databases, you use column types intended for storing IP addresses, so the database will do the parsing and canonicalization for you.<p>And when you actually have to build a parser yourself, read the damn spec for the format instead of going by what you think the format is, because most likely it&#x27;s not that.<p>And mind you that most of those problems are not really IPv6-specific. There are also many ways to write an IPv4 address that your average parser will understand. Most of those are generally frowned upon, so they don&#x27;t occur often, but if you want to reliably compare IPv4 addresses, you actually need to do the same as for IPv6.
评论 #18794602 未加载
nieve超过 6 年前
It won&#x27;t solve most of the problems, but if you&#x27;re using PostgreSQL its native inet datatype (which supports 4 or 6) instead of a text or binary string can save a world of pain and there are alternatives in some other RDBMSs:<p><a href="https:&#x2F;&#x2F;www.postgresql.org&#x2F;docs&#x2F;current&#x2F;datatype-net-types.html#DATATYPE-INET" rel="nofollow">https:&#x2F;&#x2F;www.postgresql.org&#x2F;docs&#x2F;current&#x2F;datatype-net-types.h...</a> <a href="https:&#x2F;&#x2F;www.postgresql.org&#x2F;docs&#x2F;current&#x2F;functions-net.html" rel="nofollow">https:&#x2F;&#x2F;www.postgresql.org&#x2F;docs&#x2F;current&#x2F;functions-net.html</a><p>First class network and ip types that properly support contains and exclusion operators make a lot of things less error-prone and potentially much faster.
评论 #18794728 未加载
peterwwillis超过 6 年前
Don&#x27;t try to parse things without a standard. Even CSV and e-mail addresses are more complicated than they seem.<p>Also, it&#x27;s pretty silly that we still use these unintuitive conventions from 40 years ago for modern systems. Is 192.168.2.8:10443 an address? A phone number and extension? Is it TCP, UDP? IPv4, IPv6? An HTTPS service, or just something resembling its decimal notation assigned service number? Are there multiple services proxied behind this one address? Can I route between them? When I request a URI, does the application know what I really want&#x2F;expect? What about a timeout for my request? What about authentication&#x2F;authorization? Consistency requirements? Idempotence? Security guarantees?<p>Operating systems don&#x27;t even take &lt;host&gt;:&lt;port&gt; arguments for network syscalls, that&#x27;s just a convention we sort of came up with and later stuck to. But as a URL it&#x27;s pretty crap. I suggest we replace them with modern URLs that can embed tiered information such as session IDs, service types, routes, security requirements, operational parameters, etc. Most people may only need <a href="https:&#x2F;&#x2F;google.com&#x2F;" rel="nofollow">https:&#x2F;&#x2F;google.com&#x2F;</a>, but sometimes we may also want to request webv2+uquic+v6:&#x2F;SC,TLSv1.3&#x2F;userid[s:84742049]@google.com(r:NA)&#x2F; . I know that&#x27;s ugly as sin, but hopefully people wouldn&#x27;t need to specify all of that all of the time (service name&#x2F;version, transport, address, strong consistency, TLS 1.3, userid, session id, host&#x2F;namespace, North American region).
评论 #18795739 未加载
评论 #18793996 未加载
评论 #18794531 未加载
评论 #18794698 未加载
donatj超过 6 年前
It’s certainly been said but IPv6 to my eyes is awash in second system syndrome, which has largely slowed its adoption.<p>The complexity of handling addresses is plainly a failure of the design. Using colons for separators when they’re already being used for ports served no purpose but to confuse. Having more than a single valid form of an address again only serves to confuse.<p>If there’s anything to learn from the UNIX principals it’s there is great power in making things easily manipulated as strings. The design of IPv6 makes this impossible.
评论 #18794327 未加载
评论 #18796089 未加载
评论 #18795386 未加载
评论 #18798161 未加载
评论 #18794660 未加载
mgerdts超过 6 年前
Not just ipv6.<p><pre><code> $ ping 127.1 PING 127.1 (127.0.0.1): 56 data bytes ... $ ping $(((127 &lt;&lt; 24) + 1)) PING 2130706433 (127.0.0.1): 56 data bytes ... </code></pre> I&#x27;ve primarily seen the second form in the early days of the web when spammers were presumably trying to bypass mail or web filters that were scanning for blacklisted IPs.<p>Edit: fix formatting
评论 #18794573 未加载
评论 #18795278 未加载
swinglock超过 6 年前
The problem was (and remained) programmers thinking addresses are strings.
评论 #18795287 未加载
评论 #18794668 未加载
评论 #18794300 未加载
评论 #18795913 未加载
magicalhippo超过 6 年前
I&#x27;m really stumped as to why they didn&#x27;t eliminate ports when designing IPv6. Having the last bits in the address take the role of ports makes sense given the hierarchical nature of IPv6 addresses. The first bits specify the network (my home), next bits the device, and last bits the service&#x2F;endpoint on that device.<p>It would also make parsing much easier given that they chose : as separator in the addresses.
评论 #18795006 未加载
z3t4超过 6 年前
Another gotcha is that ipv4 and ipv6 has different firewall tables. So if you for example have blocked <i>all</i> traffic besides port 80, you <i>also</i> need to do it on ipv6 !
评论 #18794174 未加载
评论 #18794296 未加载
评论 #18794407 未加载
fanf2超过 6 年前
All of this flailing around would have been avoided by either thinking carefully about canonical representations, or reading <a href="https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc5952" rel="nofollow">https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc5952</a>
signa11超过 6 年前
fwiw, rfc-5952, specifically, sec:6 outlines recommended string representations. also, it is generally much nicer to use &#x27;sock_storage&#x27; as an underlying representation of AF_{UNIX&#x2F;INET,INET6}, endpoints rather than building abstractions to tide over differences of &#x27;socaddr_*&#x27;
contravariant超过 6 年前
Maybe this is a stupid question at this point but if using colons introduces this degree of ambiguity why not stick with simple periods? Or any other separator for that matter.
nly超过 6 年前
Even putting aside the ambiguity of using &#x27;:&#x27; as a address:port delimiter, there are differences between platforms in parsing <i>just IPv6 addresses</i><p>e.g. on Linux&#x2F;glibc 2.28<p><pre><code> [cling]$ #include &lt;arpa&#x2F;inet.h&gt; [cling]$ ::in6_addr dst; [cling]$ dst (::in6_addr &amp;) @0x7ff318aff010 [cling]$ inet_pton (AF_INET6, &quot;1234:1234:1234:1234:1234::1234:8.8.8.8&quot;, &amp;dst) (int) 0 [cling]$ inet_pton (AF_INET6, &quot;1234:1234:1234:1234:1234:1234:8.8.8.8&quot;, &amp;dst) (int) 1 </code></pre> Here &#x27;::&#x27; in this &#x27;full&#x27; address is (correctly) rejected.<p>However, although I haven&#x27;t verified this on FreeBSD (perhaps someone can?), there&#x27;s a comment in the libc source suggesting that this will be accepted there<p><a href="https:&#x2F;&#x2F;github.com&#x2F;freebsd&#x2F;freebsd&#x2F;blob&#x2F;1d6e4247415d264485ee94b59fdbc12e0c566fd0&#x2F;lib&#x2F;libc&#x2F;inet&#x2F;inet_pton.c#L127" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;freebsd&#x2F;freebsd&#x2F;blob&#x2F;1d6e4247415d264485ee...</a><p>Parsing sucks.
throwaway12iii超过 6 年前
Obviously the point of the article is to not manually parse ip addresses.<p>Well actually, python can do that just as well as all the other languages.<p><pre><code> &gt;&gt;&gt; import ipaddress &gt;&gt;&gt; ipaddress.ip_address(&#x27;2001:db8::&#x27;) IPv6Address(&#x27;2001:db8::&#x27;)</code></pre>
评论 #18794019 未加载
评论 #18794022 未加载
评论 #18793960 未加载
pdkl95超过 6 年前
The fundamental problem in the example:<p><pre><code> leader_host = bigdata.example.org:10443 </code></pre> is &quot;:10443&quot; is not part of the <i>host</i>name. The field is called &quot;leader_host&quot;; if a port is needed, it should use it&#x27;s own field instead of trying to overload the host field.<p><pre><code> leader_host = bigdata.example.org leader_port = 10443 </code></pre> (and as as others have already mentioned, don&#x27;t write your own parser when they already exist in your stdlib&#x2F;etc)
ta57746uhhj超过 6 年前
IPv6 was over-engineered. We need IPv5 which just fixes the address space, then have a rethink about v7 ... without all the nonsense.
mrunkel超过 6 年前
Why not split the parameters?<p>Address and port as separate values makes more sense to me.
评论 #18794396 未加载
评论 #18794414 未加载
johnklos超过 6 年前
Canonicalize everything, then compare the canonicalized results. We&#x27;ve got this ;)
peanut-walrus超过 6 年前
&#x27;:&#x27; is also a perfectly valid character in a domain name, so the naive splitting already does not work in the IPv4 ecosystem.
评论 #18794143 未加载
ggm超过 6 年前
I&#x27;ve taken to using python split(&#x27;:&#x27;)[:-1] and like constructs
评论 #18793597 未加载
评论 #18793615 未加载
评论 #18793811 未加载
emilfihlman超过 6 年前
IPv6 is a clusterfuck of &quot;hey lest add x!&quot; and &quot;lets forget reasonable previous experience!&quot;.
thisacctforreal超过 6 年前
Call me a luddite but I&#x27;m not looking forward to IPv6.<p>How about IPv5; add another byte.<p>We can keep the colons 192:168:1:1:1.