quic: source address and ECN support in the network layer

Make the abstraction over UDP connections higher level,
and add support for setting the source address and ECN
bits in sent packets, and receving the destination
address and ECN bits in received packets.

There is no good way that I can find to identify the
source IP address of packets we send. Look up the
destination IP address of the first packet received on
each connection, and use this as the source address
for all future packets we send. This avoids unexpected
path migration, where the address we send from changes
without our knowing it.

Reject received packets sent from an unexpected peer
address.

In the future, when we support path migration, we will want
to relax these restrictions.

ECN bits may be used to detect network congestion.
We don't make use of them at this time, but this CL adds
the necessary UDP layer support to do so in the future.

This CL also lays the groundwork for using more efficient
platform APIs to send/receive packets in the future.
(sendmmsg/recvmmsg/GSO/GRO)

These features require platform-specific APIs.
Add support for Darwin and Linux to start with,
with a graceful fallback on other OSs.

For golang/go#58547

Change-Id: I1c97cc0d3e52fff18e724feaaac4a50d3df671bc
Reviewed-on: https://go-review.googlesource.com/c/net/+/565255
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/internal/quic/udp.go b/internal/quic/udp.go
new file mode 100644
index 0000000..0a57828
--- /dev/null
+++ b/internal/quic/udp.go
@@ -0,0 +1,30 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.21
+
+package quic
+
+import "net/netip"
+
+// Per-plaform consts describing support for various features.
+//
+// const udpECNSupport indicates whether the platform supports setting
+// the ECN (Explicit Congestion Notification) IP header bits.
+//
+// const udpInvalidLocalAddrIsError indicates whether sending a packet
+// from an local address not associated with the system is an error.
+// For example, assuming 127.0.0.2 is not a local address, does sending
+// from it (using IP_PKTINFO or some other such feature) result in an error?
+
+// unmapAddrPort returns a with any IPv4-mapped IPv6 address prefix removed.
+func unmapAddrPort(a netip.AddrPort) netip.AddrPort {
+	if a.Addr().Is4In6() {
+		return netip.AddrPortFrom(
+			a.Addr().Unmap(),
+			a.Port(),
+		)
+	}
+	return a
+}