Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/netinet/udp_usrreq.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/netinet/udp_usrreq.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.13 retrieving revision 1.24.2.1 diff -u -p -r1.13 -r1.24.2.1 --- src/sys/netinet/udp_usrreq.c 1994/05/13 06:06:56 1.13 +++ src/sys/netinet/udp_usrreq.c 1996/02/02 06:13:02 1.24.2.1 @@ -1,3 +1,5 @@ +/* $NetBSD: udp_usrreq.c,v 1.24.2.1 1996/02/02 06:13:02 mycroft Exp $ */ + /* * Copyright (c) 1982, 1986, 1988, 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -30,8 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * from: @(#)udp_usrreq.c 8.4 (Berkeley) 1/21/94 - * $Id: udp_usrreq.c,v 1.13 1994/05/13 06:06:56 mycroft Exp $ + * @(#)udp_usrreq.c 8.4 (Berkeley) 1/21/94 */ #include @@ -48,6 +49,7 @@ #include #include +#include #include #include #include @@ -66,16 +68,21 @@ int udpcksum = 0; /* XXX */ #endif struct sockaddr_in udp_in = { sizeof(udp_in), AF_INET }; -struct inpcb *udp_last_inpcb = &udb; static void udp_detach __P((struct inpcb *)); static void udp_notify __P((struct inpcb *, int)); static struct mbuf *udp_saveopt __P((caddr_t, int, int)); +#ifndef UDBHASHSIZE +#define UDBHASHSIZE 128 +#endif +int udbhashsize = UDBHASHSIZE; + void udp_init() { - udb.inp_next = udb.inp_prev = &udb; + + in_pcbinit(&udbtable, udbhashsize); } void @@ -120,7 +127,7 @@ udp_input(m, iphlen) * Make mbuf data length reflect UDP length. * If not enough data to reflect UDP length, drop. */ - len = ntohs((u_short)uh->uh_ulen); + len = ntohs((u_int16_t)uh->uh_ulen); if (ip->ip_len != len) { if (len > ip->ip_len) { udpstat.udps_badlen++; @@ -150,7 +157,7 @@ udp_input(m, iphlen) } } - if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || + if (IN_MULTICAST(ip->ip_dst.s_addr) || in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) { struct socket *last; /* @@ -181,7 +188,9 @@ udp_input(m, iphlen) * (Algorithm copied from raw_intr().) */ last = NULL; - for (inp = udb.inp_next; inp != &udb; inp = inp->inp_next) { + for (inp = udbtable.inpt_queue.cqh_first; + inp != (struct inpcb *)&udbtable.inpt_queue; + inp = inp->inp_queue.cqe_next) { if (inp->inp_lport != uh->uh_dport) continue; if (inp->inp_laddr.s_addr != INADDR_ANY) { @@ -201,8 +210,8 @@ udp_input(m, iphlen) if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { if (sbappendaddr(&last->so_rcv, - (struct sockaddr *)&udp_in, - n, (struct mbuf *)0) == 0) { + sintosa(&udp_in), n, + (struct mbuf *)0) == 0) { m_freem(n); udpstat.udps_fullsock++; } else @@ -231,8 +240,8 @@ udp_input(m, iphlen) udpstat.udps_noportbcast++; goto bad; } - if (sbappendaddr(&last->so_rcv, (struct sockaddr *)&udp_in, - m, (struct mbuf *)0) == 0) { + if (sbappendaddr(&last->so_rcv, sintosa(&udp_in), m, + (struct mbuf *)0) == 0) { udpstat.udps_fullsock++; goto bad; } @@ -242,27 +251,23 @@ udp_input(m, iphlen) /* * Locate pcb for datagram. */ - inp = udp_last_inpcb; - if (inp->inp_lport != uh->uh_dport || - inp->inp_fport != uh->uh_sport || - inp->inp_faddr.s_addr != ip->ip_src.s_addr || - inp->inp_laddr.s_addr != ip->ip_dst.s_addr) { - inp = in_pcblookup(&udb, ip->ip_src, uh->uh_sport, - ip->ip_dst, uh->uh_dport, INPLOOKUP_WILDCARD); - if (inp) - udp_last_inpcb = inp; - udpstat.udpps_pcbcachemiss++; - } + inp = in_pcbhashlookup(&udbtable, ip->ip_src, uh->uh_sport, + ip->ip_dst, uh->uh_dport); if (inp == 0) { - udpstat.udps_noport++; - if (m->m_flags & (M_BCAST | M_MCAST)) { - udpstat.udps_noportbcast++; - goto bad; + ++udpstat.udps_pcbhashmiss; + inp = in_pcblookup(&udbtable, ip->ip_src, uh->uh_sport, + ip->ip_dst, uh->uh_dport, INPLOOKUP_WILDCARD); + if (inp == 0) { + udpstat.udps_noport++; + if (m->m_flags & (M_BCAST | M_MCAST)) { + udpstat.udps_noportbcast++; + goto bad; + } + *ip = save_ip; + ip->ip_len += iphlen; + icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0); + return; } - *ip = save_ip; - ip->ip_len += iphlen; - icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0); - return; } /* @@ -301,8 +306,8 @@ udp_input(m, iphlen) m->m_len -= iphlen; m->m_pkthdr.len -= iphlen; m->m_data += iphlen; - if (sbappendaddr(&inp->inp_socket->so_rcv, (struct sockaddr *)&udp_in, - m, opts) == 0) { + if (sbappendaddr(&inp->inp_socket->so_rcv, sintosa(&udp_in), m, + opts) == 0) { udpstat.udps_fullsock++; goto bad; } @@ -361,17 +366,25 @@ udp_ctlinput(cmd, sa, ip) { register struct udphdr *uh; extern struct in_addr zeroin_addr; - extern u_char inetctlerrmap[]; + extern int inetctlerrmap[]; + void (*notify) __P((struct inpcb *, int)) = udp_notify; + int errno; - if (!PRC_IS_REDIRECT(cmd) && - ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0)) + if ((unsigned)cmd >= PRC_NCMDS) + return; + errno = inetctlerrmap[cmd]; + if (PRC_IS_REDIRECT(cmd)) + notify = in_rtchange, ip = 0; + else if (cmd == PRC_HOSTDEAD) + ip = 0; + else if (errno == 0) return; if (ip) { uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2)); - in_pcbnotify(&udb, sa, uh->uh_dport, ip->ip_src, uh->uh_sport, - cmd, udp_notify); + in_pcbnotify(&udbtable, sa, uh->uh_dport, ip->ip_src, + uh->uh_sport, errno, notify); } else - in_pcbnotify(&udb, sa, 0, zeroin_addr, 0, cmd, udp_notify); + in_pcbnotifyall(&udbtable, sa, errno, notify); } int @@ -397,7 +410,7 @@ udp_output(inp, m, addr, control) /* * Must block input while temporarily connected. */ - s = splnet(); + s = splsoftnet(); error = in_pcbconnect(inp, addr); if (error) { splx(s); @@ -427,7 +440,7 @@ udp_output(inp, m, addr, control) ui->ui_next = ui->ui_prev = 0; ui->ui_x1 = 0; ui->ui_pr = IPPROTO_UDP; - ui->ui_len = htons((u_short)len + sizeof (struct udphdr)); + ui->ui_len = htons((u_int16_t)len + sizeof (struct udphdr)); ui->ui_src = inp->inp_laddr; ui->ui_dst = inp->inp_faddr; ui->ui_sport = inp->inp_lport; @@ -478,7 +491,7 @@ udp_usrreq(so, req, m, addr, control) int s; if (req == PRU_CONTROL) - return (in_control(so, (int)m, (caddr_t)addr, + return (in_control(so, (long)m, (caddr_t)addr, (struct ifnet *)control)); if (inp == NULL && req != PRU_ATTACH) { error = EINVAL; @@ -495,8 +508,8 @@ udp_usrreq(so, req, m, addr, control) error = EINVAL; break; } - s = splnet(); - error = in_pcballoc(so, &udb); + s = splsoftnet(); + error = in_pcballoc(so, &udbtable); splx(s); if (error) break; @@ -511,7 +524,7 @@ udp_usrreq(so, req, m, addr, control) break; case PRU_BIND: - s = splnet(); + s = splsoftnet(); error = in_pcbbind(inp, addr); splx(s); break; @@ -525,7 +538,7 @@ udp_usrreq(so, req, m, addr, control) error = EISCONN; break; } - s = splnet(); + s = splsoftnet(); error = in_pcbconnect(inp, addr); splx(s); if (error == 0) @@ -545,7 +558,7 @@ udp_usrreq(so, req, m, addr, control) error = ENOTCONN; break; } - s = splnet(); + s = splsoftnet(); in_pcbdisconnect(inp); inp->inp_laddr.s_addr = INADDR_ANY; splx(s); @@ -608,10 +621,8 @@ static void udp_detach(inp) struct inpcb *inp; { - int s = splnet(); + int s = splsoftnet(); - if (inp == udp_last_inpcb) - udp_last_inpcb = &udb; in_pcbdetach(inp); splx(s); }