Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/ip_input.c
Show First 20 Lines • Show All 892 Lines • ▼ Show 20 Lines | #endif | ||||
hash = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id); | hash = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id); | ||||
head = &V_ipq[hash]; | head = &V_ipq[hash]; | ||||
IPQ_LOCK(); | IPQ_LOCK(); | ||||
/* | /* | ||||
* Look for queue of fragments | * Look for queue of fragments | ||||
* of this datagram. | * of this datagram. | ||||
*/ | */ | ||||
/* XXX if TCP or UDP should check port numbers */ | |||||
rwatson: Just to be specific about the problem: IP fragments repeat the IP header, but not the higher… | |||||
TAILQ_FOREACH(fp, head, ipq_list) | TAILQ_FOREACH(fp, head, ipq_list) | ||||
if (ip->ip_id == fp->ipq_id && | if (ip->ip_id == fp->ipq_id && | ||||
ip->ip_src.s_addr == fp->ipq_src.s_addr && | ip->ip_src.s_addr == fp->ipq_src.s_addr && | ||||
ip->ip_dst.s_addr == fp->ipq_dst.s_addr && | ip->ip_dst.s_addr == fp->ipq_dst.s_addr && | ||||
#ifdef MAC | #ifdef MAC | ||||
mac_ipq_match(m, fp) && | mac_ipq_match(m, fp) && | ||||
#endif | #endif | ||||
ip->ip_p == fp->ipq_p) | ip->ip_p == fp->ipq_p) | ||||
▲ Show 20 Lines • Show All 960 Lines • Show Last 20 Lines |
Just to be specific about the problem: IP fragments repeat the IP header, but not the higher-level protocol headers from UDP and TCP. Therefore you not only cannot check the port numbers here (in later fragments they won't appear!) but it is also important that the IP ID space shared by an IP 2-tuple be unique. This means that your proposed changes to make them per-inpcb will lead to IP fragmentation being fundamentally broken, as fragments from different connections -- and even different protocols -- could be mixed up with one another.