summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorsilby <silby@FreeBSD.org>2002-04-26 02:07:46 +0000
committersilby <silby@FreeBSD.org>2002-04-26 02:07:46 +0000
commitdd3cd5fed6df2d8b97036107ac5ef6e2b04bf7e8 (patch)
treee3d11ae343cdd5c86800f10650b42963d5e33da1 /sys/kern
parent522debf4fd85d981f5118693ad97663ad0d16c6b (diff)
downloadFreeBSD-src-dd3cd5fed6df2d8b97036107ac5ef6e2b04bf7e8.zip
FreeBSD-src-dd3cd5fed6df2d8b97036107ac5ef6e2b04bf7e8.tar.gz
Make sure that sockets undergoing accept filtering are aborted in a
LRU fashion when the listen queue fills up. Previously, there was no mechanism to kick out old sockets, leading to an easy DoS of daemons using accept filtering. Reviewed by: alfred MFC after: 3 days
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/uipc_sockbuf.c8
-rw-r--r--sys/kern/uipc_socket.c3
-rw-r--r--sys/kern/uipc_socket2.c8
3 files changed, 15 insertions, 4 deletions
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 47bf7bb..1a8afd3 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -127,6 +127,7 @@ soisconnected(so)
head->so_incqlen--;
so->so_state &= ~SS_INCOMP;
TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
+ head->so_qlen++;
so->so_state |= SS_COMP;
sorwakeup(head);
wakeup_one(&head->so_timeo);
@@ -202,12 +203,17 @@ sonewconn(head, connstatus)
if (connstatus) {
TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
so->so_state |= SS_COMP;
+ head->so_qlen++;
} else {
+ if (head->so_incqlen >= head->so_qlimit) {
+ struct socket *sp;
+ sp = TAILQ_FIRST(&head->so_incomp);
+ (void) soabort(sp);
+ }
TAILQ_INSERT_TAIL(&head->so_incomp, so, so_list);
so->so_state |= SS_INCOMP;
head->so_incqlen++;
}
- head->so_qlen++;
if (connstatus) {
sorwakeup(head);
wakeup((caddr_t)&head->so_timeo);
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 6c68a79..0e0fbd9 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -281,7 +281,6 @@ sofree(so)
} else {
panic("sofree: not queued");
}
- head->so_qlen--;
so->so_state &= ~SS_INCOMP;
so->so_head = NULL;
}
@@ -1674,7 +1673,7 @@ filt_solisten(struct knote *kn, long hint)
{
struct socket *so = (struct socket *)kn->kn_fp->f_data;
- kn->kn_data = so->so_qlen - so->so_incqlen;
+ kn->kn_data = so->so_qlen;
return (! TAILQ_EMPTY(&so->so_comp));
}
diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c
index 47bf7bb..1a8afd3 100644
--- a/sys/kern/uipc_socket2.c
+++ b/sys/kern/uipc_socket2.c
@@ -127,6 +127,7 @@ soisconnected(so)
head->so_incqlen--;
so->so_state &= ~SS_INCOMP;
TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
+ head->so_qlen++;
so->so_state |= SS_COMP;
sorwakeup(head);
wakeup_one(&head->so_timeo);
@@ -202,12 +203,17 @@ sonewconn(head, connstatus)
if (connstatus) {
TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
so->so_state |= SS_COMP;
+ head->so_qlen++;
} else {
+ if (head->so_incqlen >= head->so_qlimit) {
+ struct socket *sp;
+ sp = TAILQ_FIRST(&head->so_incomp);
+ (void) soabort(sp);
+ }
TAILQ_INSERT_TAIL(&head->so_incomp, so, so_list);
so->so_state |= SS_INCOMP;
head->so_incqlen++;
}
- head->so_qlen++;
if (connstatus) {
sorwakeup(head);
wakeup((caddr_t)&head->so_timeo);
OpenPOWER on IntegriCloud