Add an accept filter for TCP based DNS requests. It waits until the
whole first request is present before returning from accept.
This commit is contained in:
parent
3b19fa3597
commit
744eaff7e6
@ -391,6 +391,7 @@ bktr_load="NO" # Brooktree Bt848/Bt878 TV/Video Capture Card
|
||||
ispfw_load="NO" # Qlogic ISP Firmware
|
||||
agp_load="NO" # agp module
|
||||
accf_data_load="NO" # Wait for data accept filter
|
||||
accf_dns_load="NO" # Wait for data accept filter
|
||||
accf_http_load="NO" # Wait for full HTTP request accept filter
|
||||
random_load="NO" # Random device
|
||||
speaker_load="NO" # AT speaker module
|
||||
|
@ -887,6 +887,7 @@ options MBUF_PROFILING
|
||||
|
||||
# Statically Link in accept filters
|
||||
options ACCEPT_FILTER_DATA
|
||||
options ACCEPT_FILTER_DNS
|
||||
options ACCEPT_FILTER_HTTP
|
||||
|
||||
# TCP_SIGNATURE adds support for RFC 2385 (TCP-MD5) digests. These are
|
||||
|
@ -1902,6 +1902,7 @@ netgraph/ng_tee.c optional netgraph_tee
|
||||
netgraph/ng_tty.c optional netgraph_tty
|
||||
netgraph/ng_vjc.c optional netgraph_vjc
|
||||
netinet/accf_data.c optional accept_filter_data
|
||||
netinet/accf_dns.c optional accept_filter_dns
|
||||
netinet/accf_http.c optional accept_filter_http
|
||||
netinet/if_atm.c optional atm
|
||||
netinet/if_ether.c optional ether
|
||||
|
@ -342,6 +342,7 @@ ATA_NOPCI opt_ata.h
|
||||
|
||||
# Net stuff.
|
||||
ACCEPT_FILTER_DATA
|
||||
ACCEPT_FILTER_DNS
|
||||
ACCEPT_FILTER_HTTP
|
||||
ALTQ opt_global.h
|
||||
ALTQ_CBQ opt_altq.h
|
||||
|
@ -6,6 +6,7 @@ SUBDIR= ${_3dfx} \
|
||||
${_3dfx_linux} \
|
||||
${_aac} \
|
||||
accf_data \
|
||||
accf_dns \
|
||||
accf_http \
|
||||
${_acpi} \
|
||||
age \
|
||||
|
8
sys/modules/accf_dns/Makefile
Normal file
8
sys/modules/accf_dns/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../netinet
|
||||
|
||||
KMOD= accf_dns
|
||||
SRCS= accf_dns.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
135
sys/netinet/accf_dns.c
Normal file
135
sys/netinet/accf_dns.c
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2007 David Malone <dwmalone@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define ACCEPT_FILTER_MOD
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/socketvar.h>
|
||||
|
||||
/* check for full DNS request */
|
||||
static void sohasdns(struct socket *so, void *arg, int waitflag);
|
||||
|
||||
struct packet {
|
||||
struct mbuf *m; /* Current mbuf. */
|
||||
struct mbuf *n; /* nextpkt mbuf. */
|
||||
unsigned long moff; /* Offset of the beginning of m. */
|
||||
unsigned long offset; /* Which offset we are working at. */
|
||||
unsigned long len; /* The number of bytes we have to play with. */
|
||||
};
|
||||
|
||||
#define DNS_OK 0
|
||||
#define DNS_WAIT -1
|
||||
#define DNS_RUN -2
|
||||
|
||||
/* check we can skip over various parts of DNS request */
|
||||
static int skippacket(struct sockbuf *sb);
|
||||
|
||||
static struct accept_filter accf_dns_filter = {
|
||||
"dnsready",
|
||||
sohasdns,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static moduledata_t accf_dns_mod = {
|
||||
"accf_dns",
|
||||
accept_filt_generic_mod_event,
|
||||
&accf_dns_filter
|
||||
};
|
||||
|
||||
DECLARE_MODULE(accf_dns, accf_dns_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
|
||||
|
||||
static void
|
||||
sohasdns(struct socket *so, void *arg, int waitflag)
|
||||
{
|
||||
struct sockbuf *sb = &so->so_rcv;
|
||||
|
||||
/* If the socket is full, we're ready. */
|
||||
if (sb->sb_cc >= sb->sb_hiwat || sb->sb_mbcnt >= sb->sb_mbmax)
|
||||
goto ready;
|
||||
|
||||
/* Check and see if we have a request. */
|
||||
if (skippacket(sb) == DNS_WAIT)
|
||||
return;
|
||||
|
||||
ready:
|
||||
so->so_upcall = NULL;
|
||||
so->so_rcv.sb_flags &= ~SB_UPCALL;
|
||||
soisconnected(so);
|
||||
return;
|
||||
}
|
||||
|
||||
#define GET8(p, val) do { \
|
||||
if (p->offset < p->moff) \
|
||||
return DNS_RUN; \
|
||||
while (p->offset >= p->moff + p->m->m_len) { \
|
||||
p->moff += p->m->m_len; \
|
||||
p->m = p->m->m_next; \
|
||||
if (p->m == NULL) { \
|
||||
p->m = p->n; \
|
||||
p->n = p->m->m_nextpkt; \
|
||||
} \
|
||||
if (p->m == NULL) \
|
||||
return DNS_WAIT; \
|
||||
} \
|
||||
val = *(mtod(p->m, unsigned char *) + (p->offset - p->moff)); \
|
||||
p->offset++; \
|
||||
} while (0)
|
||||
|
||||
#define GET16(p, val) do { \
|
||||
unsigned int v0, v1; \
|
||||
GET8(p, v0); \
|
||||
GET8(p, v1); \
|
||||
val = v0 * 0x100 + v1; \
|
||||
} while (0)
|
||||
|
||||
static int
|
||||
skippacket(struct sockbuf *sb) {
|
||||
unsigned long packlen;
|
||||
struct packet q, *p = &q;
|
||||
|
||||
if (sb->sb_cc < 2)
|
||||
return DNS_WAIT;
|
||||
|
||||
q.m = sb->sb_mb;
|
||||
q.n = q.m->m_nextpkt;
|
||||
q.moff = 0;
|
||||
q.offset = 0;
|
||||
q.len = sb->sb_cc;
|
||||
|
||||
GET16(p, packlen);
|
||||
if (packlen + 2 < q.len)
|
||||
return DNS_WAIT;
|
||||
|
||||
return DNS_OK;
|
||||
}
|
Loading…
Reference in New Issue
Block a user