Implementing a request-response filtering policy for UDP-based protocols is far more difficult than for TCP. Because there is no explicit connection, we cannot simply filter connection requests: each UDP (and ICMP) packet must be examined individually. Although a packet filter should only admit packets containing responses to earlier requests, individual packets generally do not carry enough information for a filter to correctly determine whether a packet is a request or a response. Moreover, the large number of UDP-based application protocols makes such protocol-specific packet processing unmanageable.
In addition, any filtering scheme that tries using well-known UDP port numbers to determine the protocol type of a packet is, at best, a heuristic. For example, consider a packet from source address A and UDP port 161 (SNMP) to destination machine B and UDP port 53 (DNS). This packet could be a DNS request from A (not running an SNMP server) with a DNS client coincidentally running on port 161. The same packet could equally well be an SNMP response from A, to a client coincidentally running at port 53 on B, which is not running a DNS server. This exact example is unlikely between two machines running Unix because of the BSD reserved port semantics; however, it could easily arise when one of the endpoints has been compromised, is running a UDP implementation that has no notion of reserved ports, or is running an unfriendly application (e.g. one that calls bindresvport()). A filter rule therefore cannot use either the source or destination port numbers to determine the protocol type of a given packet, which it needs in order to parse the packet and classify it as a request or a response.
We conclude, therefore, that UDP port numbers are unreliable filtering criteria and UDP application protocols are too varied for monitoring in a filter. To support a reliable request-response filter, we must therefore either:
With the first alternative, the packet filter does not need to examine the source or destination ports. It simply drops all inbound packets which have the request-response bit set to ``request.'' The request-response bit must be available to the application so that servers can detect requests masquerading as response packets.
With the second alternative, the filter uses the disjoint client and server port spaces as an implicit request-response bit by verifying that the packet is destined for a UDP port in the client range. This approach assumes that all UDP implementations honor the same port space partitioning. Partitioning the UDP port space between clients and servers (e.g. above and below port 32678) can be implemented straightforwardly in Unix kernels. Servers can always explicitly bind to a port in the server range. Clients must allow the kernel to assign a local port, which would fall in the client port space (32768 or above). By using a fixed cut-point between the client and server portions, the filter rules can use a simple comparison operator which can remain unchanged even as new UDP application protocols are deployed. The concept of ``privileged'' UDP ports would be abolished. The 4.4-BSD implementation attempts to partition its UDP port space: otherwise unspecified local ports are bound in the range 1025--5000; however, this range is not honored on other systems and overlaps with many IANA-assigned registered ports.
Even with a firewall that discards all inbound UDP packets marked as requests, external hosts can still send anything they want to a client port. Ultimately, only applications themselves have sufficient knowledge and state to perform exact request-response filtering. For example, only the client can detect and discard unsolicited responses from external hosts, as only the client knows exactly which requests are still outstanding. UDP applications receiving a request packet on a client port must treat the packet as an invalid protocol operation.
Of course, the final approach to re-designing UDP protocols is to discard UDP in favor of an explicit transaction-oriented protocol. Either VMTP  or transactional TCP  would allow exact request-response filtering. VMTP has an explicit request-response bit in the header, while with transactional TCP, we can again apply TCP SYN filtering. However, to the best of our knowledge, neither protocol has ever seen production use, and transactional TCP is also unable to address the second use of UDP---namely IP multicast traffic.