mirror of
https://github.com/opnsense/src.git
synced 2026-06-08 16:22:46 -04:00
accept_filter: return different errors for non-listener and a busy socket
The fact that an accept filter needs to be cleared first before setting to a different one isn't properly documented. The requirement that the socket needs already be listening, although trivial, isn't documented either. At least return a more meaningful error than EINVAL for an existing filter. Cover this with a test case.
This commit is contained in:
parent
c68eed82a3
commit
19307b86d3
2 changed files with 37 additions and 1 deletions
|
|
@ -276,10 +276,14 @@ accept_filt_setopt(struct socket *so, struct sockopt *sopt)
|
|||
* without first removing it.
|
||||
*/
|
||||
SOCK_LOCK(so);
|
||||
if (!SOLISTENING(so) || so->sol_accept_filter != NULL) {
|
||||
if (__predict_false(!SOLISTENING(so))) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (__predict_false(so->sol_accept_filter != NULL)) {
|
||||
error = EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Invoke the accf_create() method of the filter if required. The
|
||||
|
|
|
|||
|
|
@ -209,11 +209,43 @@ ATF_TC_BODY(tls, tc)
|
|||
ATF_REQUIRE((a = accept(l, NULL, 0)) > 0);
|
||||
}
|
||||
|
||||
/* Check changing to a different filter. */
|
||||
ATF_TC_WITHOUT_HEAD(change);
|
||||
ATF_TC_BODY(change, tc)
|
||||
{
|
||||
struct accept_filter_arg dfa = {
|
||||
.af_name = "dataready"
|
||||
};
|
||||
struct accept_filter_arg hfa = {
|
||||
.af_name = "httpready"
|
||||
};
|
||||
struct sockaddr_in sin;
|
||||
int n, l;
|
||||
|
||||
l = listensock(&sin);
|
||||
accfon(l, &dfa);
|
||||
|
||||
/* Refuse to change filter without explicit removal of the old one. */
|
||||
ATF_REQUIRE(setsockopt(l, SOL_SOCKET, SO_ACCEPTFILTER, &hfa,
|
||||
sizeof(hfa)) != 0 && errno == EBUSY);
|
||||
|
||||
/* But allow after clearing. */
|
||||
ATF_REQUIRE(setsockopt(l, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0) == 0);
|
||||
ATF_REQUIRE(setsockopt(l, SOL_SOCKET, SO_ACCEPTFILTER, &hfa,
|
||||
sizeof(hfa)) == 0);
|
||||
|
||||
/* Must be listening socket. */
|
||||
ATF_REQUIRE((n = socket(PF_INET, SOCK_STREAM, 0)) > 0);
|
||||
ATF_REQUIRE(setsockopt(n, SOL_SOCKET, SO_ACCEPTFILTER, &dfa,
|
||||
sizeof(dfa)) != 0 && errno == EINVAL);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, data);
|
||||
ATF_TP_ADD_TC(tp, http);
|
||||
ATF_TP_ADD_TC(tp, tls);
|
||||
ATF_TP_ADD_TC(tp, change);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue