diff options
| -rw-r--r-- | sys/netinet/in_pcb.c | 103 | ||||
| -rw-r--r-- | sys/netinet/in_pcb.h | 5 | ||||
| -rw-r--r-- | sys/netinet/tcp_subr.c | 65 | ||||
| -rw-r--r-- | sys/netinet/tcp_timewait.c | 65 | ||||
| -rw-r--r-- | sys/netinet/tcp_var.h | 1 | ||||
| -rw-r--r-- | sys/netinet/udp_usrreq.c | 29 |
6 files changed, 72 insertions, 196 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 0a8e95238cd1..d87b2a8cce9b 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -62,8 +62,6 @@ #include <netinet/in_pcb.h> #include <netinet/in_var.h> #include <netinet/ip_var.h> -#include <netinet/tcp.h> -#include <netinet/tcp_var.h> #ifdef INET6 #include <netinet/ip6.h> #include <netinet6/ip6_var.h> @@ -657,110 +655,27 @@ in_setpeeraddr(so, nam) return 0; } -/* - * Pass some notification to all connections of a protocol - * associated with address dst. The local address and/or port numbers - * may be specified to limit the search. The "usual action" will be - * taken, depending on the ctlinput cmd. The caller must filter any - * cmds that are uninteresting (e.g., no error in the map). - * Call the protocol specific routine (if any) to report - * any errors for each matching socket. - * - * If tcp_seq_check != 0 it also checks if tcp_sequence is - * a valid TCP sequence number for the session. - */ void -in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify, tcp_sequence, tcp_seq_check) +in_pcbnotifyall(head, faddr, errno, notify) struct inpcbhead *head; - struct sockaddr *dst; - u_int fport_arg, lport_arg; - struct in_addr laddr; - int cmd; - void (*notify) __P((struct inpcb *, int)); - u_int32_t tcp_sequence; - int tcp_seq_check; -{ - register struct inpcb *inp, *oinp; struct in_addr faddr; - u_short fport = fport_arg, lport = lport_arg; - int errno, s; - - if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET) - return; - faddr = ((struct sockaddr_in *)dst)->sin_addr; - if (faddr.s_addr == INADDR_ANY) - return; - - errno = inetctlerrmap[cmd]; - s = splnet(); - for (inp = LIST_FIRST(head); inp != NULL;) { -#ifdef INET6 - if ((inp->inp_vflag & INP_IPV4) == 0) { - inp = LIST_NEXT(inp, inp_list); - continue; - } -#endif - if (inp->inp_faddr.s_addr != faddr.s_addr || - inp->inp_socket == 0 || inp->inp_lport != lport || - inp->inp_laddr.s_addr != laddr.s_addr || - inp->inp_fport != fport) { - inp = LIST_NEXT(inp, inp_list); - continue; - } - /* - * If tcp_seq_check is set, then skip sessions where - * the sequence number is not one of a unacknowledged - * packet. - * - * If it doesn't match, we break the loop, as only a - * single session can match on src/dst ip addresses - * and TCP port numbers. - */ - if ((tcp_seq_check == 1) && (tcp_seq_vs_sess(inp, tcp_sequence) == 0)) - break; - oinp = inp; - inp = LIST_NEXT(inp, inp_list); - if (notify) - (*notify)(oinp, errno); - } - splx(s); -} - -void -in_pcbnotifyall(head, dst, cmd, notify) - struct inpcbhead *head; - struct sockaddr *dst; - int cmd; + int errno; void (*notify) __P((struct inpcb *, int)); { - register struct inpcb *inp, *oinp; - struct in_addr faddr; - int errno, s; - - if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET) - return; - faddr = ((struct sockaddr_in *)dst)->sin_addr; - if (faddr.s_addr == INADDR_ANY) - return; + struct inpcb *inp, *ninp; + int s; - errno = inetctlerrmap[cmd]; s = splnet(); - for (inp = LIST_FIRST(head); inp != NULL;) { + for (inp = LIST_FIRST(head); inp != NULL; inp = ninp) { + ninp = LIST_NEXT(inp, inp_list); #ifdef INET6 - if ((inp->inp_vflag & INP_IPV4) == 0) { - inp = LIST_NEXT(inp, inp_list); + if ((inp->inp_vflag & INP_IPV4) == 0) continue; - } #endif if (inp->inp_faddr.s_addr != faddr.s_addr || - inp->inp_socket == 0) { - inp = LIST_NEXT(inp, inp_list); + inp->inp_socket == NULL) continue; - } - oinp = inp; - inp = LIST_NEXT(inp, inp_list); - if (notify) - (*notify)(oinp, errno); + (*notify)(inp, errno); } splx(s); } diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index 7e4cfbe37517..f4abb4d0a440 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -290,10 +290,7 @@ struct inpcb * in_pcblookup_hash __P((struct inpcbinfo *, struct in_addr, u_int, struct in_addr, u_int, int, struct ifnet *)); -void in_pcbnotify __P((struct inpcbhead *, struct sockaddr *, - u_int, struct in_addr, u_int, int, void (*)(struct inpcb *, int), - u_int32_t, int)); -void in_pcbnotifyall __P((struct inpcbhead *, struct sockaddr *, +void in_pcbnotifyall __P((struct inpcbhead *, struct in_addr, int, void (*)(struct inpcb *, int))); void in_pcbrehash __P((struct inpcb *)); int in_setpeeraddr __P((struct socket *so, struct sockaddr **nam)); diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index c1505974a4fb..b70d2b5a8817 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -976,41 +976,46 @@ tcp_ctlinput(cmd, sa, vip) { struct ip *ip = vip; struct tcphdr *th; + struct in_addr faddr; + struct inpcb *inp; + struct tcpcb *tp; void (*notify) __P((struct inpcb *, int)) = tcp_notify; - tcp_seq tcp_sequence = 0; - int tcp_seq_check = 0; + tcp_seq icmp_seq; + int s; + + faddr = ((struct sockaddr_in *)sa)->sin_addr; + if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY) + return; if (cmd == PRC_QUENCH) notify = tcp_quench; - else if (icmp_may_rst && cmd == PRC_UNREACH_ADMIN_PROHIB && ip) { - tcp_seq_check = 1; + else if (icmp_may_rst && cmd == PRC_UNREACH_ADMIN_PROHIB && ip) notify = tcp_drop_syn_sent; - } else if (cmd == PRC_MSGSIZE) + else if (cmd == PRC_MSGSIZE) notify = tcp_mtudisc; else if (PRC_IS_REDIRECT(cmd)) { - /* - * Redirects go to all references to the destination, - * and use in_rtchange to invalidate the route cache. - */ ip = 0; notify = in_rtchange; } else if (cmd == PRC_HOSTDEAD) - /* - * Dead host indications: notify all references to the - * destination. - */ ip = 0; else if ((unsigned)cmd > PRC_NCMDS || inetctlerrmap[cmd] == 0) return; if (ip) { + s = splnet(); th = (struct tcphdr *)((caddr_t)ip + (IP_VHL_HL(ip->ip_vhl) << 2)); - if (tcp_seq_check == 1) - tcp_sequence = ntohl(th->th_seq); - in_pcbnotify(&tcb, sa, th->th_dport, ip->ip_src, th->th_sport, - cmd, notify, tcp_sequence, tcp_seq_check); + inp = in_pcblookup_hash(&tcbinfo, faddr, th->th_dport, + ip->ip_src, th->th_sport, 0, NULL); + if (inp != NULL && inp->inp_socket != NULL) { + icmp_seq = htonl(th->th_seq); + tp = intotcpcb(inp); + if (SEQ_GEQ(icmp_seq, tp->snd_una) && + SEQ_LT(icmp_seq, tp->snd_max)) + (*notify)(inp, inetctlerrmap[cmd]); + } + splx(s); } else - in_pcbnotifyall(&tcb, sa, cmd, notify); + in_pcbnotifyall(&tcb, faddr, inetctlerrmap[cmd], notify); } #ifdef INET6 @@ -1097,30 +1102,6 @@ tcp6_ctlinput(cmd, sa, d) #endif /* INET6 */ /* - * Check if the supplied TCP sequence number is a sequence number - * for a sent but unacknowledged packet on the given TCP session. - */ -int -tcp_seq_vs_sess(inp, tcp_sequence) - struct inpcb *inp; - tcp_seq tcp_sequence; -{ - struct tcpcb *tp = intotcpcb(inp); - /* - * If the sequence number is less than that of the last - * unacknowledged packet, or greater than that of the - * last sent, the given sequence number is not that - * of a sent but unacknowledged packet for this session. - */ - if (SEQ_LT(tcp_sequence, tp->snd_una) || - SEQ_GT(tcp_sequence, tp->snd_max)) { - return(0); - } else { - return(1); - } -} - -/* * When a source quench is received, close congestion window * to one segment. We will gradually open it again as we proceed. */ diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c index c1505974a4fb..b70d2b5a8817 100644 --- a/sys/netinet/tcp_timewait.c +++ b/sys/netinet/tcp_timewait.c @@ -976,41 +976,46 @@ tcp_ctlinput(cmd, sa, vip) { struct ip *ip = vip; struct tcphdr *th; + struct in_addr faddr; + struct inpcb *inp; + struct tcpcb *tp; void (*notify) __P((struct inpcb *, int)) = tcp_notify; - tcp_seq tcp_sequence = 0; - int tcp_seq_check = 0; + tcp_seq icmp_seq; + int s; + + faddr = ((struct sockaddr_in *)sa)->sin_addr; + if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY) + return; if (cmd == PRC_QUENCH) notify = tcp_quench; - else if (icmp_may_rst && cmd == PRC_UNREACH_ADMIN_PROHIB && ip) { - tcp_seq_check = 1; + else if (icmp_may_rst && cmd == PRC_UNREACH_ADMIN_PROHIB && ip) notify = tcp_drop_syn_sent; - } else if (cmd == PRC_MSGSIZE) + else if (cmd == PRC_MSGSIZE) notify = tcp_mtudisc; else if (PRC_IS_REDIRECT(cmd)) { - /* - * Redirects go to all references to the destination, - * and use in_rtchange to invalidate the route cache. - */ ip = 0; notify = in_rtchange; } else if (cmd == PRC_HOSTDEAD) - /* - * Dead host indications: notify all references to the - * destination. - */ ip = 0; else if ((unsigned)cmd > PRC_NCMDS || inetctlerrmap[cmd] == 0) return; if (ip) { + s = splnet(); th = (struct tcphdr *)((caddr_t)ip + (IP_VHL_HL(ip->ip_vhl) << 2)); - if (tcp_seq_check == 1) - tcp_sequence = ntohl(th->th_seq); - in_pcbnotify(&tcb, sa, th->th_dport, ip->ip_src, th->th_sport, - cmd, notify, tcp_sequence, tcp_seq_check); + inp = in_pcblookup_hash(&tcbinfo, faddr, th->th_dport, + ip->ip_src, th->th_sport, 0, NULL); + if (inp != NULL && inp->inp_socket != NULL) { + icmp_seq = htonl(th->th_seq); + tp = intotcpcb(inp); + if (SEQ_GEQ(icmp_seq, tp->snd_una) && + SEQ_LT(icmp_seq, tp->snd_max)) + (*notify)(inp, inetctlerrmap[cmd]); + } + splx(s); } else - in_pcbnotifyall(&tcb, sa, cmd, notify); + in_pcbnotifyall(&tcb, faddr, inetctlerrmap[cmd], notify); } #ifdef INET6 @@ -1097,30 +1102,6 @@ tcp6_ctlinput(cmd, sa, d) #endif /* INET6 */ /* - * Check if the supplied TCP sequence number is a sequence number - * for a sent but unacknowledged packet on the given TCP session. - */ -int -tcp_seq_vs_sess(inp, tcp_sequence) - struct inpcb *inp; - tcp_seq tcp_sequence; -{ - struct tcpcb *tp = intotcpcb(inp); - /* - * If the sequence number is less than that of the last - * unacknowledged packet, or greater than that of the - * last sent, the given sequence number is not that - * of a sent but unacknowledged packet for this session. - */ - if (SEQ_LT(tcp_sequence, tp->snd_una) || - SEQ_GT(tcp_sequence, tp->snd_max)) { - return(0); - } else { - return(1); - } -} - -/* * When a source quench is received, close congestion window * to one segment. We will gradually open it again as we proceed. */ diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index dc69d3e0c11e..e361caf57756 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -392,7 +392,6 @@ void tcp_mtudisc __P((struct inpcb *, int)); struct tcpcb * tcp_newtcpcb __P((struct inpcb *)); int tcp_output __P((struct tcpcb *)); -int tcp_seq_vs_sess __P((struct inpcb *, tcp_seq)); void tcp_quench __P((struct inpcb *, int)); void tcp_respond __P((struct tcpcb *, void *, struct tcphdr *, struct mbuf *, tcp_seq, tcp_seq, int)); diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 2e7fe8958857..1dd3eee9f216 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -504,31 +504,34 @@ udp_ctlinput(cmd, sa, vip) struct sockaddr *sa; void *vip; { - register struct ip *ip = vip; - register struct udphdr *uh; + struct ip *ip = vip; + struct udphdr *uh; void (*notify) __P((struct inpcb *, int)) = udp_notify; + struct in_addr faddr; + struct inpcb *inp; + int s; + + faddr = ((struct sockaddr_in *)sa)->sin_addr; + if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY) + return; if (PRC_IS_REDIRECT(cmd)) { - /* - * Redirects go to all references to the destination, - * and use in_rtchange to invalidate the route cache. - */ ip = 0; notify = in_rtchange; } else if (cmd == PRC_HOSTDEAD) - /* - * Dead host indications: notify all references to the - * destination. - */ ip = 0; else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) return; if (ip) { + s = splnet(); uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2)); - in_pcbnotify(&udb, sa, uh->uh_dport, ip->ip_src, uh->uh_sport, - cmd, notify, 0, 0); + inp = in_pcblookup_hash(&udbinfo, faddr, uh->uh_dport, + ip->ip_src, uh->uh_sport, 0, NULL); + if (inp != NULL && inp->inp_socket != NULL) + (*notify)(inp, inetctlerrmap[cmd]); + splx(s); } else - in_pcbnotifyall(&udb, sa, cmd, notify); + in_pcbnotifyall(&udb, faddr, inetctlerrmap[cmd], notify); } static int |
