diff options
author | Peter Wemm <peter@FreeBSD.org> | 2013-07-28 05:06:53 +0000 |
---|---|---|
committer | Peter Wemm <peter@FreeBSD.org> | 2013-07-28 05:06:53 +0000 |
commit | f2be5817e9c3cb98a81689acb42dc6549ae0448f (patch) | |
tree | 3c0eb477642c8cddce38b6c98c437cca2f2cbda9 /network_io/unix/sockopt.c | |
parent | b641829dcad12c65ed87cf0ebe11100791b9256a (diff) |
Notes
Diffstat (limited to 'network_io/unix/sockopt.c')
-rw-r--r-- | network_io/unix/sockopt.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/network_io/unix/sockopt.c b/network_io/unix/sockopt.c index 3fc932f42f5e..7b67c2ec13a1 100644 --- a/network_io/unix/sockopt.c +++ b/network_io/unix/sockopt.c @@ -381,12 +381,33 @@ apr_status_t apr_gethostname(char *buf, apr_int32_t len, apr_pool_t *cont) } #if APR_HAS_SO_ACCEPTFILTER -apr_status_t apr_socket_accept_filter(apr_socket_t *sock, char *name, - char *args) +apr_status_t apr_socket_accept_filter(apr_socket_t *sock, char *nonconst_name, + char *nonconst_args) { + /* these should have been const; act like they are */ + const char *name = nonconst_name; + const char *args = nonconst_args; + struct accept_filter_arg af; - strncpy(af.af_name, name, 16); - strncpy(af.af_arg, args, 256 - 16); + socklen_t optlen = sizeof(af); + + /* FreeBSD returns an error if the filter is already set; ignore + * this call if we previously set it to the same value. + */ + if ((getsockopt(sock->socketdes, SOL_SOCKET, SO_ACCEPTFILTER, + &af, &optlen)) == 0) { + if (!strcmp(name, af.af_name) && !strcmp(args, af.af_arg)) { + return APR_SUCCESS; + } + } + + /* Uhh, at least in FreeBSD 9 the fields are declared as arrays of + * these lengths; did sizeof not work in some ancient release? + * + * FreeBSD kernel sets the last byte to a '\0'. + */ + apr_cpystrn(af.af_name, name, 16); + apr_cpystrn(af.af_arg, args, 256 - 16); if ((setsockopt(sock->socketdes, SOL_SOCKET, SO_ACCEPTFILTER, &af, sizeof(af))) < 0) { |