1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
14 */
15
16 /*
17 * This file implements a socketfilter used to deter TCP connections.
18 * To defer a connection means to delay the return of accept(3SOCKET)
19 * until at least one byte is ready to be read(2). This filter may be
20 * applied automatically or programmatically through the use of
21 * soconfig(1M) and setsockopt(3SOCKET).
22 */
23
24 #include <sys/kmem.h>
25 #include <sys/systm.h>
26 #include <sys/stropts.h>
27 #include <sys/strsun.h>
28 #include <sys/socketvar.h>
29 #include <sys/sockfilter.h>
30 #include <sys/note.h>
31 #include <sys/taskq.h>
32
33 #define DATAFILT_MODULE "datafilt"
34
35 static struct modlmisc dataf_modlmisc = {
36 &mod_miscops,
37 "Kernel data-ready socket filter"
38 };
39
40 static struct modlinkage dataf_modlinkage = {
41 MODREV_1,
42 &dataf_modlmisc,
43 NULL
44 };
45
46 static sof_rval_t
47 dataf_attach_passive_cb(sof_handle_t handle, sof_handle_t ph,
48 void *parg, struct sockaddr *laddr, socklen_t laddrlen,
49 struct sockaddr *faddr, socklen_t faddrlen, void **cookiep)
50 {
51 _NOTE(ARGUNUSED(handle, ph, parg, laddr, laddrlen, faddr, faddrlen,
52 cookiep));
53 return (SOF_RVAL_DEFER);
54 }
55
56 static void
57 dataf_detach_cb(sof_handle_t handle, void *cookie, cred_t *cr)
58 {
59 _NOTE(ARGUNUSED(handle, cookie, cr));
60 }
61
62 static mblk_t *
63 dataf_data_in_cb(sof_handle_t handle, void *cookie, mblk_t *mp, int flags,
64 size_t *lenp)
65 {
66 _NOTE(ARGUNUSED(handle, cookie, mp, flags, lenp));
67
68 if (mp != NULL && MBLKL(mp) > 0) {
69 sof_newconn_ready(handle);
70 sof_bypass(handle);
71 }
72
73 return (mp);
74 }
75
76 static sof_ops_t dataf_ops = {
77 .sofop_attach_passive = dataf_attach_passive_cb,
78 .sofop_detach = dataf_detach_cb,
79 .sofop_data_in = dataf_data_in_cb
80 };
81
82 int
83 _init(void)
84 {
85 int err;
86
87 err = sof_register(SOF_VERSION, DATAFILT_MODULE, &dataf_ops, 0);
88 if (err != 0)
89 return (err);
90 if ((err = mod_install(&dataf_modlinkage)) != 0)
91 (void) sof_unregister(DATAFILT_MODULE);
92
93 return (err);
94 }
95
96 int
97 _fini(void)
98 {
99 int err;
100
101 if ((err = sof_unregister(DATAFILT_MODULE)) != 0)
102 return (err);
103
104 return (mod_remove(&dataf_modlinkage));
105 }
106
107 int
108 _info(struct modinfo *modinfop)
109 {
110 return (mod_info(&dataf_modlinkage, modinfop));
111 }