Index: sys/conf/options =================================================================== RCS file: /home/ncvs/src/sys/conf/options,v retrieving revision 1.121.2.25 diff -c -r1.121.2.25 options *** sys/conf/options 2000/06/13 08:48:00 1.121.2.25 --- sys/conf/options 2000/06/19 21:33:44 *************** *** 272,277 **** --- 272,278 ---- NETGRAPH_TTY opt_netgraph.h NETGRAPH_UI opt_netgraph.h NETGRAPH_VJC opt_netgraph.h + IF_ADDR_HASH opt_ipaddrhash.h # ATM (HARP version) ATM_CORE opt_atm.h Index: sys/netinet/in.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/in.c,v retrieving revision 1.39.2.2 diff -c -r1.39.2.2 in.c *** sys/netinet/in.c 1999/08/29 16:29:33 1.39.2.2 --- sys/netinet/in.c 2000/06/19 21:33:44 *************** *** 34,39 **** --- 34,41 ---- * $FreeBSD: src/sys/netinet/in.c,v 1.39.2.2 1999/08/29 16:29:33 peter Exp $ */ + #include "opt_ipaddrhash.h" + #include #include #include *************** *** 51,56 **** --- 53,62 ---- #include + #ifdef IF_ADDR_HASH + extern int ip_addr_hash_status; /* see ip_input.c */ + #endif + static MALLOC_DEFINE(M_IPMADDR, "in_multi", "internet multicast address"); static void in_socktrim __P((struct sockaddr_in *)); *************** *** 221,226 **** --- 227,235 ---- TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_link); ifa = &ia->ia_ifa; TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link); + #ifdef IF_ADDR_HASH + ip_addr_hash_status = 0; /* mark hash as stale */ + #endif ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr; ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr; *************** *** 352,357 **** --- 361,369 ---- oia = ia; TAILQ_REMOVE(&in_ifaddrhead, oia, ia_link); IFAFREE(&oia->ia_ifa); + #ifdef IF_ADDR_HASH + ip_addr_hash_status = 0; /* mark hash as stale */ + #endif splx(s); break; Index: sys/netinet/in.h =================================================================== RCS file: /home/ncvs/src/sys/netinet/in.h,v retrieving revision 1.38.2.3 diff -c -r1.38.2.3 in.h *** sys/netinet/in.h 1999/08/29 16:29:34 1.38.2.3 --- sys/netinet/in.h 2000/06/19 21:33:44 *************** *** 201,207 **** * for servers, not necessarily privileged. (IP_PORTRANGE_DEFAULT) */ #define IPPORT_RESERVED 1024 ! #define IPPORT_USERRESERVED 5000 /* * Default local port range to use by setting IP_PORTRANGE_HIGH --- 201,207 ---- * for servers, not necessarily privileged. (IP_PORTRANGE_DEFAULT) */ #define IPPORT_RESERVED 1024 ! #define IPPORT_USERRESERVED 30000 /* * Default local port range to use by setting IP_PORTRANGE_HIGH Index: sys/netinet/ip_input.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_input.c,v retrieving revision 1.111.2.9 diff -c -r1.111.2.9 ip_input.c *** sys/netinet/ip_input.c 2000/06/13 07:12:34 1.111.2.9 --- sys/netinet/ip_input.c 2000/06/19 21:33:44 *************** *** 43,48 **** --- 43,49 ---- #include "opt_ipdivert.h" #include "opt_ipfilter.h" #include "opt_ipstealth.h" + #include "opt_ipaddrhash.h" #include *************** *** 125,130 **** --- 126,151 ---- SYSCTL_STRUCT(_net_inet_ip, IPCTL_STATS, stats, CTLFLAG_RD, &ipstat, ipstat, ""); + #ifdef IF_ADDR_HASH + /* global variable to indicate that ip address hash is in sync + * with in_ifaddrhead queue + */ + int ip_addr_hash_status = 0; /* -1: disabled; 0: needs sync; 1: in sync */ + /* a wrapper to avoid if_addr modifications */ + struct ip_addr_hash_entry { + struct in_ifaddr *ia; + struct ip_addr_hash_entry *next; + }; + typedef struct ip_addr_hash_entry **ip_addr_hash_pos; + static struct ip_addr_hash_entry **ip_addr_hash = 0; + static struct ip_addr_hash_entry *ip_addr_hash_entry_cache = 0; + static int ip_addr_hash_cap = 0; /* slots in a hash */ + static void ip_addr_hash_reset(void); + static void ip_addr_hash_clean(void); + static int ip_addr_hash_find(struct in_addr addr, ip_addr_hash_pos *pos); + static struct in_ifaddr *ip_addr_hash_has(struct in_addr addr); + #endif /* IF_ADDR_HASH */ + /* Packet reassembly stuff */ #define IPREASS_NHASH_LOG2 6 #define IPREASS_NHASH (1 << IPREASS_NHASH_LOG2) *************** *** 471,476 **** --- 492,505 ---- /* * Check our list of addresses, to see if the packet is for us. */ + #ifdef IF_ADDR_HASH + if (ip_addr_hash_status == 0) + ip_addr_hash_reset(); + if (ip_addr_hash_status > 0) { + if (ip_addr_hash_has(ip->ip_dst)) + goto ours; + } else /* XXX: error prone */ + #endif for (ia = TAILQ_FIRST(&in_ifaddrhead); ia; ia = TAILQ_NEXT(ia, ia_link)) { #define satosin(sa) ((struct sockaddr_in *)(sa)) *************** *** 1669,1671 **** --- 1698,1793 ---- } return 0; } + + + #ifdef IF_ADDR_HASH + + /* destroys old address hash if any and computes new hash if possible */ + static void + ip_addr_hash_reset(void) { + int new_cap = 0; + int hash_count, add_count; + struct in_ifaddr *ia; + + if (ip_addr_hash_status < 0) + panic("ip_addr_hash_reset -- called for a disabled hash"); + + printf("ip_addr_hash_reset: starting (old: capacity: %d)\n", ip_addr_hash_cap); + + /* calculate new hash capacity */ + hash_count = 0; + for (ia = TAILQ_FIRST(&in_ifaddrhead); ia; ia = TAILQ_NEXT(ia, ia_link)) + hash_count++; + new_cap = 2*hash_count + 1; /* XXX: ideally, this should be a prime number */ + + /* do we need to allocate a new hash? */ + if (ip_addr_hash_cap != new_cap) { + if (ip_addr_hash) + ip_addr_hash_clean(); + ip_addr_hash = malloc(sizeof(*ip_addr_hash)*new_cap, M_TEMP, M_WAITOK); + ip_addr_hash_entry_cache = malloc(sizeof(*ip_addr_hash_entry_cache)*hash_count, M_TEMP, M_WAITOK); + if (!ip_addr_hash || !ip_addr_hash_entry_cache) + panic("ip_addr_hash_reset -- cannot allocate hash"); + ip_addr_hash_cap = new_cap; + } + + /* initialize the hash with new values */ + bzero(ip_addr_hash, sizeof(*ip_addr_hash)*ip_addr_hash_cap); + bzero(ip_addr_hash_entry_cache, sizeof(*ip_addr_hash_entry_cache)*hash_count); + add_count = 0; + for (ia = TAILQ_FIRST(&in_ifaddrhead); ia; ia = TAILQ_NEXT(ia, ia_link)) { + const struct in_addr addr = IA_SIN(ia)->sin_addr; + struct ip_addr_hash_entry *e; + ip_addr_hash_pos pos; + + if (ip_addr_hash_find(addr, &pos)) { + printf("ip_addr_hash_reset: %s conflicts with ", inet_ntoa(IA_SIN(*pos)->sin_addr)); + printf("%s, disabling hash optimization due to internal error\n", inet_ntoa(addr)); + ip_addr_hash_clean(); + ip_addr_hash_status = -1; + return; + } + if (add_count >= hash_count) + panic("ip_addr_hash_reset -- ia list grew?!"); + e = ip_addr_hash_entry_cache + add_count; + e->ia = ia; + e->next = 0; + *pos = e; + add_count++; + } + + ip_addr_hash_status = 1; + /* XXX: remove this message? */ + printf("ip_addr_hash_reset: done (%d entries, %d bytes)\n", + hash_count, sizeof(*ip_addr_hash)*ip_addr_hash_cap + + sizeof(*ip_addr_hash_entry_cache)*hash_count); + } + + static void + ip_addr_hash_clean(void) { + FREE(ip_addr_hash_entry_cache, M_TEMP); + FREE(ip_addr_hash, M_TEMP); + ip_addr_hash = 0; + ip_addr_hash_entry_cache = 0; + ip_addr_hash_cap = 0; + } + + static int + ip_addr_hash_find(struct in_addr addr, ip_addr_hash_pos *posp) { + *posp = &ip_addr_hash[addr.s_addr % ip_addr_hash_cap]; + /* scan collision chain */ + while (**posp && IA_SIN((**posp)->ia)->sin_addr.s_addr != addr.s_addr) + *posp = &(**posp)->next; + return **posp != 0; + } + + static struct in_ifaddr * + ip_addr_hash_has(struct in_addr addr) { + ip_addr_hash_pos pos; + if (ip_addr_hash_find(addr, &pos)) + return (*pos)->ia; + else + return 0; + } + + #endif /* IF_ADDR_HASH */ Index: sys/netinet/tcp_input.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/tcp_input.c,v retrieving revision 1.82.2.4 diff -c -r1.82.2.4 tcp_input.c *** sys/netinet/tcp_input.c 2000/04/25 05:07:54 1.82.2.4 --- sys/netinet/tcp_input.c 2000/06/19 21:34:01 *************** *** 85,91 **** SYSCTL_INT(_net_inet_tcp, OID_AUTO, log_in_vain, CTLFLAG_RW, &log_in_vain, 0, ""); ! int tcp_delack_enabled = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, delayed_ack, CTLFLAG_RW, &tcp_delack_enabled, 0, ""); --- 85,91 ---- SYSCTL_INT(_net_inet_tcp, OID_AUTO, log_in_vain, CTLFLAG_RW, &log_in_vain, 0, ""); ! int tcp_delack_enabled = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, delayed_ack, CTLFLAG_RW, &tcp_delack_enabled, 0, ""); Index: sys/netinet/tcp_timer.h =================================================================== RCS file: /home/ncvs/src/sys/netinet/tcp_timer.h,v retrieving revision 1.13.2.1 diff -c -r1.13.2.1 tcp_timer.h *** sys/netinet/tcp_timer.h 1999/08/29 16:29:56 1.13.2.1 --- sys/netinet/tcp_timer.h 2000/06/19 21:34:02 *************** *** 87,93 **** /* * Time constants. */ ! #define TCPTV_MSL ( 30*PR_SLOWHZ) /* max seg lifetime (hah!) */ #define TCPTV_SRTTBASE 0 /* base roundtrip time; if 0, no idea yet */ #define TCPTV_RTOBASE ( 3*PR_SLOWHZ) /* assumed RTO if no info */ --- 87,93 ---- /* * Time constants. */ ! #define TCPTV_MSL ( 3*PR_SLOWHZ) /* max seg lifetime (hah!) */ #define TCPTV_SRTTBASE 0 /* base roundtrip time; if 0, no idea yet */ #define TCPTV_RTOBASE ( 3*PR_SLOWHZ) /* assumed RTO if no info */ Index: sys/sys/socket.h =================================================================== RCS file: /home/ncvs/src/sys/sys/socket.h,v retrieving revision 1.27.2.4 diff -c -r1.27.2.4 socket.h *** sys/sys/socket.h 2000/03/08 06:32:44 1.27.2.4 --- sys/sys/socket.h 2000/06/19 21:34:02 *************** *** 268,274 **** /* * Maximum queue length specifiable by listen. */ ! #define SOMAXCONN 128 /* * Message header for recvmsg and sendmsg calls. --- 268,274 ---- /* * Maximum queue length specifiable by listen. */ ! #define SOMAXCONN 1024 /* * Message header for recvmsg and sendmsg calls.