Re: syn cache hash size sysctl

2016-07-19 Thread Joerg Jung


> Am 19.07.2016 um 23:16 schrieb Alexander Bluhm :
> 
>> On Tue, Jul 19, 2016 at 09:48:19PM +0100, Jason McIntyre wrote:
>> oh oh. i should have been clearer: they are sorted in sysctl(3), but in
>> sysctl(8) they are merely listed in the order that running "sysctl"
>> dumps them. so no sort neccessary for sysctl(8).
> 
> So now sysctl(8) has all net.inet.tcp in sysctl output order.
> 
> ok?

ok jung@

> bluhm
> 
> Index: lib/libc/gen/sysctl.3
> ===
> RCS file: /data/mirror/openbsd/cvs/src/lib/libc/gen/sysctl.3,v
> retrieving revision 1.266
> diff -u -p -r1.266 sysctl.3
> --- lib/libc/gen/sysctl.314 Jul 2016 17:34:06 -1.266
> +++ lib/libc/gen/sysctl.319 Jul 2016 20:36:19 -
> @@ -1188,6 +1188,7 @@ The currently defined protocols and name
> .It tcp Ta stats Ta structure Ta no
> .It tcp Ta synbucketlimit Ta integer Ta yes
> .It tcp Ta syncachelimit Ta integer Ta yes
> +.It tcp Ta synhashsize Ta integer Ta yes
> .It tcp Ta synuselimit Ta integer Ta yes
> .It udp Ta baddynamic Ta array Ta yes
> .It udp Ta checksum Ta integer Ta yes
> @@ -1617,6 +1618,10 @@ Returns the TCP statistics in a struct t
> The maximum number of entries allowed per hash bucket in the TCP SYN cache.
> .It Li tcp.syncachelimit
> The maximum number of entries allowed in the TCP SYN cache.
> +.It Li tcp.synhashsize
> +The number of buckets in the TCP SYN cache hash array.
> +After the value is set, the actual size changes when the alternative
> +SYN cache becomes empty and both SYN caches are swapped.
> .It Li tcp.synuselimit
> The minimum number of times the hash function for the TCP SYN cache is used
> before it is reseeded.
> Index: sbin/sysctl/sysctl.8
> ===
> RCS file: /data/mirror/openbsd/cvs/src/sbin/sysctl/sysctl.8,v
> retrieving revision 1.202
> diff -u -p -r1.202 sysctl.8
> --- sbin/sysctl/sysctl.85 Jul 2016 17:41:59 -1.202
> +++ sbin/sysctl/sysctl.819 Jul 2016 21:06:02 -
> @@ -256,7 +256,6 @@ and a few require a kernel compiled with
> .It net.inet.tcp.keepinittime Ta integer Ta yes
> .It net.inet.tcp.keepidle Ta integer Ta yes
> .It net.inet.tcp.keepintvl Ta integer Ta yes
> -.It net.inet.tcp.always_keepalive Ta integer Ta yes
> .It net.inet.tcp.slowhz Ta integer Ta no
> .It net.inet.tcp.baddynamic Ta array Ta yes
> .It net.inet.tcp.sack Ta integer Ta yes
> @@ -266,10 +265,13 @@ and a few require a kernel compiled with
> .It net.inet.tcp.ecn Ta integer Ta yes
> .It net.inet.tcp.syncachelimit Ta integer Ta yes
> .It net.inet.tcp.synbucketlimit Ta integer Ta yes
> -.It net.inet.tcp.synuselimit Ta integer Ta yes
> .It net.inet.tcp.rfc3390 Ta integer Ta yes
> .It net.inet.tcp.reasslimit Ta integer Ta yes
> +.It net.inet.tcp.sackholelimit Ta integer Ta yes
> +.It net.inet.tcp.always_keepalive Ta integer Ta yes
> +.It net.inet.tcp.synuselimit Ta integer Ta yes
> .It net.inet.tcp.rootonly Ta array Ta yes
> +.It net.inet.tcp.synhashsize Ta integer Ta yes
> .It net.inet.udp.checksum Ta integer Ta yes
> .It net.inet.udp.baddynamic Ta array Ta yes
> .It net.inet.udp.recvspace Ta integer Ta yes
> 



Re: syn cache hash size sysctl

2016-07-19 Thread Alexander Bluhm
On Tue, Jul 19, 2016 at 09:48:19PM +0100, Jason McIntyre wrote:
> oh oh. i should have been clearer: they are sorted in sysctl(3), but in
> sysctl(8) they are merely listed in the order that running "sysctl"
> dumps them. so no sort neccessary for sysctl(8).

So now sysctl(8) has all net.inet.tcp in sysctl output order.

ok?

bluhm

Index: lib/libc/gen/sysctl.3
===
RCS file: /data/mirror/openbsd/cvs/src/lib/libc/gen/sysctl.3,v
retrieving revision 1.266
diff -u -p -r1.266 sysctl.3
--- lib/libc/gen/sysctl.3   14 Jul 2016 17:34:06 -  1.266
+++ lib/libc/gen/sysctl.3   19 Jul 2016 20:36:19 -
@@ -1188,6 +1188,7 @@ The currently defined protocols and name
 .It tcp Ta stats Ta structure Ta no
 .It tcp Ta synbucketlimit Ta integer Ta yes
 .It tcp Ta syncachelimit Ta integer Ta yes
+.It tcp Ta synhashsize Ta integer Ta yes
 .It tcp Ta synuselimit Ta integer Ta yes
 .It udp Ta baddynamic Ta array Ta yes
 .It udp Ta checksum Ta integer Ta yes
@@ -1617,6 +1618,10 @@ Returns the TCP statistics in a struct t
 The maximum number of entries allowed per hash bucket in the TCP SYN cache.
 .It Li tcp.syncachelimit
 The maximum number of entries allowed in the TCP SYN cache.
+.It Li tcp.synhashsize
+The number of buckets in the TCP SYN cache hash array.
+After the value is set, the actual size changes when the alternative
+SYN cache becomes empty and both SYN caches are swapped.
 .It Li tcp.synuselimit
 The minimum number of times the hash function for the TCP SYN cache is used
 before it is reseeded.
Index: sbin/sysctl/sysctl.8
===
RCS file: /data/mirror/openbsd/cvs/src/sbin/sysctl/sysctl.8,v
retrieving revision 1.202
diff -u -p -r1.202 sysctl.8
--- sbin/sysctl/sysctl.85 Jul 2016 17:41:59 -   1.202
+++ sbin/sysctl/sysctl.819 Jul 2016 21:06:02 -
@@ -256,7 +256,6 @@ and a few require a kernel compiled with
 .It net.inet.tcp.keepinittime Ta integer Ta yes
 .It net.inet.tcp.keepidle Ta integer Ta yes
 .It net.inet.tcp.keepintvl Ta integer Ta yes
-.It net.inet.tcp.always_keepalive Ta integer Ta yes
 .It net.inet.tcp.slowhz Ta integer Ta no
 .It net.inet.tcp.baddynamic Ta array Ta yes
 .It net.inet.tcp.sack Ta integer Ta yes
@@ -266,10 +265,13 @@ and a few require a kernel compiled with
 .It net.inet.tcp.ecn Ta integer Ta yes
 .It net.inet.tcp.syncachelimit Ta integer Ta yes
 .It net.inet.tcp.synbucketlimit Ta integer Ta yes
-.It net.inet.tcp.synuselimit Ta integer Ta yes
 .It net.inet.tcp.rfc3390 Ta integer Ta yes
 .It net.inet.tcp.reasslimit Ta integer Ta yes
+.It net.inet.tcp.sackholelimit Ta integer Ta yes
+.It net.inet.tcp.always_keepalive Ta integer Ta yes
+.It net.inet.tcp.synuselimit Ta integer Ta yes
 .It net.inet.tcp.rootonly Ta array Ta yes
+.It net.inet.tcp.synhashsize Ta integer Ta yes
 .It net.inet.udp.checksum Ta integer Ta yes
 .It net.inet.udp.baddynamic Ta array Ta yes
 .It net.inet.udp.recvspace Ta integer Ta yes



Re: syn cache hash size sysctl

2016-07-19 Thread Claudio Jeker
On Tue, Jul 19, 2016 at 10:40:14PM +0200, Alexander Bluhm wrote:
> On Tue, Jul 19, 2016 at 09:19:25PM +0100, Jason McIntyre wrote:
> > On Tue, Jul 19, 2016 at 10:09:47PM +0200, Alexander Bluhm wrote:
> > > On Tue, Jul 19, 2016 at 08:55:58PM +0200, Joerg Jung wrote:
> > > > Please, also document it, at least in sysctl(8).
> 
> Next try, with input from jmc@
> 
> bluhm
> 
> Index: lib/libc/gen/sysctl.3
> ===
> RCS file: /data/mirror/openbsd/cvs/src/lib/libc/gen/sysctl.3,v
> retrieving revision 1.266
> diff -u -p -r1.266 sysctl.3
> --- lib/libc/gen/sysctl.3 14 Jul 2016 17:34:06 -  1.266
> +++ lib/libc/gen/sysctl.3 19 Jul 2016 20:36:19 -
> @@ -1188,6 +1188,7 @@ The currently defined protocols and name
>  .It tcp Ta stats Ta structure Ta no
>  .It tcp Ta synbucketlimit Ta integer Ta yes
>  .It tcp Ta syncachelimit Ta integer Ta yes
> +.It tcp Ta synhashsize Ta integer Ta yes
>  .It tcp Ta synuselimit Ta integer Ta yes
>  .It udp Ta baddynamic Ta array Ta yes
>  .It udp Ta checksum Ta integer Ta yes
> @@ -1617,6 +1618,10 @@ Returns the TCP statistics in a struct t
>  The maximum number of entries allowed per hash bucket in the TCP SYN cache.
>  .It Li tcp.syncachelimit
>  The maximum number of entries allowed in the TCP SYN cache.
> +.It Li tcp.synhashsize
> +The number of buckets in the TCP SYN cache hash array.
> +After the value is set, the actual size changes when the alternative
> +SYN cache becomes empty and both SYN caches are swapped.
>  .It Li tcp.synuselimit
>  The minimum number of times the hash function for the TCP SYN cache is used
>  before it is reseeded.
> Index: sbin/sysctl/sysctl.8
> ===
> RCS file: /data/mirror/openbsd/cvs/src/sbin/sysctl/sysctl.8,v
> retrieving revision 1.202
> diff -u -p -r1.202 sysctl.8
> --- sbin/sysctl/sysctl.8  5 Jul 2016 17:41:59 -   1.202
> +++ sbin/sysctl/sysctl.8  19 Jul 2016 20:31:39 -
> @@ -264,8 +264,9 @@ and a few require a kernel compiled with
>  .It net.inet.tcp.rstppslimit Ta integer Ta yes
>  .It net.inet.tcp.ackonpush Ta integer Ta yes
>  .It net.inet.tcp.ecn Ta integer Ta yes
> -.It net.inet.tcp.syncachelimit Ta integer Ta yes
>  .It net.inet.tcp.synbucketlimit Ta integer Ta yes
> +.It net.inet.tcp.syncachelimit Ta integer Ta yes
> +.It net.inet.tcp.synhashsize Ta integer Ta yes
>  .It net.inet.tcp.synuselimit Ta integer Ta yes
>  .It net.inet.tcp.rfc3390 Ta integer Ta yes
>  .It net.inet.tcp.reasslimit Ta integer Ta yes
> 

Reads OK. I would love to actually reduce the syncache knobs to one or two
and have the kernel select the other two values based on the first two.
As in keep synuselimit and syncachelimit and ditch synbucketlimit and
synhashsize. I always have to look up the code to make usefull decisions
about these values.

-- 
:wq Claudio



Re: syn cache hash size sysctl

2016-07-19 Thread Alexander Bluhm
On Tue, Jul 19, 2016 at 09:19:25PM +0100, Jason McIntyre wrote:
> On Tue, Jul 19, 2016 at 10:09:47PM +0200, Alexander Bluhm wrote:
> > On Tue, Jul 19, 2016 at 08:55:58PM +0200, Joerg Jung wrote:
> > > Please, also document it, at least in sysctl(8).

Next try, with input from jmc@

bluhm

Index: lib/libc/gen/sysctl.3
===
RCS file: /data/mirror/openbsd/cvs/src/lib/libc/gen/sysctl.3,v
retrieving revision 1.266
diff -u -p -r1.266 sysctl.3
--- lib/libc/gen/sysctl.3   14 Jul 2016 17:34:06 -  1.266
+++ lib/libc/gen/sysctl.3   19 Jul 2016 20:36:19 -
@@ -1188,6 +1188,7 @@ The currently defined protocols and name
 .It tcp Ta stats Ta structure Ta no
 .It tcp Ta synbucketlimit Ta integer Ta yes
 .It tcp Ta syncachelimit Ta integer Ta yes
+.It tcp Ta synhashsize Ta integer Ta yes
 .It tcp Ta synuselimit Ta integer Ta yes
 .It udp Ta baddynamic Ta array Ta yes
 .It udp Ta checksum Ta integer Ta yes
@@ -1617,6 +1618,10 @@ Returns the TCP statistics in a struct t
 The maximum number of entries allowed per hash bucket in the TCP SYN cache.
 .It Li tcp.syncachelimit
 The maximum number of entries allowed in the TCP SYN cache.
+.It Li tcp.synhashsize
+The number of buckets in the TCP SYN cache hash array.
+After the value is set, the actual size changes when the alternative
+SYN cache becomes empty and both SYN caches are swapped.
 .It Li tcp.synuselimit
 The minimum number of times the hash function for the TCP SYN cache is used
 before it is reseeded.
Index: sbin/sysctl/sysctl.8
===
RCS file: /data/mirror/openbsd/cvs/src/sbin/sysctl/sysctl.8,v
retrieving revision 1.202
diff -u -p -r1.202 sysctl.8
--- sbin/sysctl/sysctl.85 Jul 2016 17:41:59 -   1.202
+++ sbin/sysctl/sysctl.819 Jul 2016 20:31:39 -
@@ -264,8 +264,9 @@ and a few require a kernel compiled with
 .It net.inet.tcp.rstppslimit Ta integer Ta yes
 .It net.inet.tcp.ackonpush Ta integer Ta yes
 .It net.inet.tcp.ecn Ta integer Ta yes
-.It net.inet.tcp.syncachelimit Ta integer Ta yes
 .It net.inet.tcp.synbucketlimit Ta integer Ta yes
+.It net.inet.tcp.syncachelimit Ta integer Ta yes
+.It net.inet.tcp.synhashsize Ta integer Ta yes
 .It net.inet.tcp.synuselimit Ta integer Ta yes
 .It net.inet.tcp.rfc3390 Ta integer Ta yes
 .It net.inet.tcp.reasslimit Ta integer Ta yes



Re: syn cache hash size sysctl

2016-07-19 Thread Alexander Bluhm
On Tue, Jul 19, 2016 at 08:55:58PM +0200, Joerg Jung wrote:
> Please, also document it, at least in sysctl(8).

like this?

bluhm

Index: lib/libc/gen/sysctl.3
===
RCS file: /data/mirror/openbsd/cvs/src/lib/libc/gen/sysctl.3,v
retrieving revision 1.266
diff -u -p -r1.266 sysctl.3
--- lib/libc/gen/sysctl.3   14 Jul 2016 17:34:06 -  1.266
+++ lib/libc/gen/sysctl.3   19 Jul 2016 20:06:54 -
@@ -1189,6 +1189,7 @@ The currently defined protocols and name
 .It tcp Ta synbucketlimit Ta integer Ta yes
 .It tcp Ta syncachelimit Ta integer Ta yes
 .It tcp Ta synuselimit Ta integer Ta yes
+.It tcp Ta synhashsize Ta integer Ta yes
 .It udp Ta baddynamic Ta array Ta yes
 .It udp Ta checksum Ta integer Ta yes
 .It udp Ta recvspace Ta integer Ta yes
@@ -1619,7 +1620,11 @@ The maximum number of entries allowed pe
 The maximum number of entries allowed in the TCP SYN cache.
 .It Li tcp.synuselimit
 The minimum number of times the hash function for the TCP SYN cache is used
-before it is reseeded.
+before it gets reseeded.
+.It Li tcp.synhashsize
+The number of buckets in the TCP SYN cache hash array.
+After the value is set, the actual size changes when the alternative
+SYN cache gets empty and both SYN caches are swapped.
 .It Li udp.baddynamic
 Analogous to
 .Li tcp.baddynamic
Index: sbin/sysctl/sysctl.8
===
RCS file: /data/mirror/openbsd/cvs/src/sbin/sysctl/sysctl.8,v
retrieving revision 1.202
diff -u -p -r1.202 sysctl.8
--- sbin/sysctl/sysctl.85 Jul 2016 17:41:59 -   1.202
+++ sbin/sysctl/sysctl.819 Jul 2016 19:53:16 -
@@ -267,6 +267,7 @@ and a few require a kernel compiled with
 .It net.inet.tcp.syncachelimit Ta integer Ta yes
 .It net.inet.tcp.synbucketlimit Ta integer Ta yes
 .It net.inet.tcp.synuselimit Ta integer Ta yes
+.It net.inet.tcp.synhashsize Ta integer Ta yes
 .It net.inet.tcp.rfc3390 Ta integer Ta yes
 .It net.inet.tcp.reasslimit Ta integer Ta yes
 .It net.inet.tcp.rootonly Ta array Ta yes



Re: syn cache hash size sysctl

2016-07-19 Thread Joerg Jung
On Tue, Jul 19, 2016 at 06:13:42PM +0200, Alexander Bluhm wrote:
> Hi,
> 
> claudio@ suggested to have a tunable size for the syn cache hash
> array.  As we are swapping between two syn caches for random reseeding
> anyway, this feature can be added easily.  When the cache is empty,
> we can change the hash size.
> 
> This allows an admin under SYN flood attack to tune his machine.
> sysctl net.inet.tcp.synhashsize=1

Makes sense to me and I like this.
 
> ok?

ok jung@

Please, also document it, at least in sysctl(8).
 
> bluhm
> 
> Index: netinet/tcp_input.c
> ===
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_input.c,v
> retrieving revision 1.324
> diff -u -p -r1.324 tcp_input.c
> --- netinet/tcp_input.c   1 Jul 2016 18:37:15 -   1.324
> +++ netinet/tcp_input.c   19 Jul 2016 15:02:35 -
> @@ -3266,7 +3266,7 @@ tcp_mss_adv(struct mbuf *m, int af)
>   */
>  
>  /* syn hash parameters */
> -int  tcp_syn_cache_size = TCP_SYN_HASH_SIZE;
> +int  tcp_syn_hash_size = TCP_SYN_HASH_SIZE;
>  int  tcp_syn_cache_limit = TCP_SYN_HASH_SIZE*TCP_SYN_BUCKET_SIZE;
>  int  tcp_syn_bucket_limit = 3*TCP_SYN_BUCKET_SIZE;
>  int  tcp_syn_use_limit = 10;
> @@ -3360,7 +3360,13 @@ syn_cache_init(void)
>   int i;
>  
>   /* Initialize the hash buckets. */
> - for (i = 0; i < tcp_syn_cache_size; i++) {
> + tcp_syn_cache[0].scs_buckethead = mallocarray(tcp_syn_hash_size,
> + sizeof(struct syn_cache_head), M_SYNCACHE, M_WAITOK|M_ZERO);
> + tcp_syn_cache[1].scs_buckethead = mallocarray(tcp_syn_hash_size,
> + sizeof(struct syn_cache_head), M_SYNCACHE, M_WAITOK|M_ZERO);
> + tcp_syn_cache[0].scs_size = tcp_syn_hash_size;
> + tcp_syn_cache[1].scs_size = tcp_syn_hash_size;
> + for (i = 0; i < tcp_syn_hash_size; i++) {
>   TAILQ_INIT(_syn_cache[0].scs_buckethead[i].sch_bucket);
>   TAILQ_INIT(_syn_cache[1].scs_buckethead[i].sch_bucket);
>   }
> @@ -3377,7 +3383,7 @@ syn_cache_insert(struct syn_cache *sc, s
>   struct syn_cache_set *set = _syn_cache[tcp_syn_cache_active];
>   struct syn_cache_head *scp;
>   struct syn_cache *sc2;
> - int s;
> + int i, s;
>  
>   s = splsoftnet();
>  
> @@ -3385,16 +3391,33 @@ syn_cache_insert(struct syn_cache *sc, s
>* If there are no entries in the hash table, reinitialize
>* the hash secrets.  To avoid useless cache swaps and
>* reinitialization, use it until the limit is reached.
> +  * An emtpy cache is also the oportunity to resize the hash.
>*/
>   if (set->scs_count == 0 && set->scs_use <= 0) {
> - arc4random_buf(set->scs_random, sizeof(set->scs_random));
>   set->scs_use = tcp_syn_use_limit;
> + if (set->scs_size != tcp_syn_hash_size) {
> + scp = mallocarray(tcp_syn_hash_size, sizeof(struct
> + syn_cache_head), M_SYNCACHE, M_NOWAIT|M_ZERO);
> + if (scp == NULL) {
> + /* Try again next time. */
> + set->scs_use = 0;
> + } else {
> + free(set->scs_buckethead, M_SYNCACHE,
> + set->scs_size *
> + sizeof(struct syn_cache_head));
> + set->scs_buckethead = scp;
> + set->scs_size = tcp_syn_hash_size;
> + for (i = 0; i < tcp_syn_hash_size; i++)
> + TAILQ_INIT([i].sch_bucket);
> + }
> + }
> + arc4random_buf(set->scs_random, sizeof(set->scs_random));
>   tcpstat.tcps_sc_seedrandom++;
>   }
>  
>   SYN_HASHALL(sc->sc_hash, >sc_src.sa, >sc_dst.sa,
>   set->scs_random);
> - scp = >scs_buckethead[sc->sc_hash % tcp_syn_cache_size];
> + scp = >scs_buckethead[sc->sc_hash % set->scs_size];
>   sc->sc_buckethead = scp;
>  
>   /*
> @@ -3437,7 +3460,7 @@ syn_cache_insert(struct syn_cache *sc, s
>*/
>   scp2 = scp;
>   if (TAILQ_EMPTY(>sch_bucket)) {
> - sce = >scs_buckethead[tcp_syn_cache_size];
> + sce = >scs_buckethead[set->scs_size];
>   for (++scp2; scp2 != scp; scp2++) {
>   if (scp2 >= sce)
>   scp2 = >scs_buckethead[0];
> @@ -3595,7 +3618,7 @@ syn_cache_lookup(struct sockaddr *src, s
>   if (sets[i]->scs_count == 0)
>   continue;
>   SYN_HASHALL(hash, src, dst, sets[i]->scs_random);
> - scp = [i]->scs_buckethead[hash % tcp_syn_cache_size];
> + scp = [i]->scs_buckethead[hash % sets[i]->scs_size];
>   *headp = scp;
>   TAILQ_FOREACH(sc, >sch_bucket, sc_bucketq) 

syn cache hash size sysctl

2016-07-19 Thread Alexander Bluhm
Hi,

claudio@ suggested to have a tunable size for the syn cache hash
array.  As we are swapping between two syn caches for random reseeding
anyway, this feature can be added easily.  When the cache is empty,
we can change the hash size.

This allows an admin under SYN flood attack to tune his machine.
sysctl net.inet.tcp.synhashsize=1

ok?

bluhm

Index: netinet/tcp_input.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_input.c,v
retrieving revision 1.324
diff -u -p -r1.324 tcp_input.c
--- netinet/tcp_input.c 1 Jul 2016 18:37:15 -   1.324
+++ netinet/tcp_input.c 19 Jul 2016 15:02:35 -
@@ -3266,7 +3266,7 @@ tcp_mss_adv(struct mbuf *m, int af)
  */
 
 /* syn hash parameters */
-inttcp_syn_cache_size = TCP_SYN_HASH_SIZE;
+inttcp_syn_hash_size = TCP_SYN_HASH_SIZE;
 inttcp_syn_cache_limit = TCP_SYN_HASH_SIZE*TCP_SYN_BUCKET_SIZE;
 inttcp_syn_bucket_limit = 3*TCP_SYN_BUCKET_SIZE;
 inttcp_syn_use_limit = 10;
@@ -3360,7 +3360,13 @@ syn_cache_init(void)
int i;
 
/* Initialize the hash buckets. */
-   for (i = 0; i < tcp_syn_cache_size; i++) {
+   tcp_syn_cache[0].scs_buckethead = mallocarray(tcp_syn_hash_size,
+   sizeof(struct syn_cache_head), M_SYNCACHE, M_WAITOK|M_ZERO);
+   tcp_syn_cache[1].scs_buckethead = mallocarray(tcp_syn_hash_size,
+   sizeof(struct syn_cache_head), M_SYNCACHE, M_WAITOK|M_ZERO);
+   tcp_syn_cache[0].scs_size = tcp_syn_hash_size;
+   tcp_syn_cache[1].scs_size = tcp_syn_hash_size;
+   for (i = 0; i < tcp_syn_hash_size; i++) {
TAILQ_INIT(_syn_cache[0].scs_buckethead[i].sch_bucket);
TAILQ_INIT(_syn_cache[1].scs_buckethead[i].sch_bucket);
}
@@ -3377,7 +3383,7 @@ syn_cache_insert(struct syn_cache *sc, s
struct syn_cache_set *set = _syn_cache[tcp_syn_cache_active];
struct syn_cache_head *scp;
struct syn_cache *sc2;
-   int s;
+   int i, s;
 
s = splsoftnet();
 
@@ -3385,16 +3391,33 @@ syn_cache_insert(struct syn_cache *sc, s
 * If there are no entries in the hash table, reinitialize
 * the hash secrets.  To avoid useless cache swaps and
 * reinitialization, use it until the limit is reached.
+* An emtpy cache is also the oportunity to resize the hash.
 */
if (set->scs_count == 0 && set->scs_use <= 0) {
-   arc4random_buf(set->scs_random, sizeof(set->scs_random));
set->scs_use = tcp_syn_use_limit;
+   if (set->scs_size != tcp_syn_hash_size) {
+   scp = mallocarray(tcp_syn_hash_size, sizeof(struct
+   syn_cache_head), M_SYNCACHE, M_NOWAIT|M_ZERO);
+   if (scp == NULL) {
+   /* Try again next time. */
+   set->scs_use = 0;
+   } else {
+   free(set->scs_buckethead, M_SYNCACHE,
+   set->scs_size *
+   sizeof(struct syn_cache_head));
+   set->scs_buckethead = scp;
+   set->scs_size = tcp_syn_hash_size;
+   for (i = 0; i < tcp_syn_hash_size; i++)
+   TAILQ_INIT([i].sch_bucket);
+   }
+   }
+   arc4random_buf(set->scs_random, sizeof(set->scs_random));
tcpstat.tcps_sc_seedrandom++;
}
 
SYN_HASHALL(sc->sc_hash, >sc_src.sa, >sc_dst.sa,
set->scs_random);
-   scp = >scs_buckethead[sc->sc_hash % tcp_syn_cache_size];
+   scp = >scs_buckethead[sc->sc_hash % set->scs_size];
sc->sc_buckethead = scp;
 
/*
@@ -3437,7 +3460,7 @@ syn_cache_insert(struct syn_cache *sc, s
 */
scp2 = scp;
if (TAILQ_EMPTY(>sch_bucket)) {
-   sce = >scs_buckethead[tcp_syn_cache_size];
+   sce = >scs_buckethead[set->scs_size];
for (++scp2; scp2 != scp; scp2++) {
if (scp2 >= sce)
scp2 = >scs_buckethead[0];
@@ -3595,7 +3618,7 @@ syn_cache_lookup(struct sockaddr *src, s
if (sets[i]->scs_count == 0)
continue;
SYN_HASHALL(hash, src, dst, sets[i]->scs_random);
-   scp = [i]->scs_buckethead[hash % tcp_syn_cache_size];
+   scp = [i]->scs_buckethead[hash % sets[i]->scs_size];
*headp = scp;
TAILQ_FOREACH(sc, >sch_bucket, sc_bucketq) {
if (sc->sc_hash != hash)
Index: netinet/tcp_usrreq.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_usrreq.c,v
retrieving revision 1.132