Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add configure option to disable upcalls #710

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,15 @@ AC_ARG_ENABLE(programs,
enable_programs=$enableval,enable_programs=yes)
AM_CONDITIONAL([COND_PROGRAMS], [test "$enable_programs" = yes])

AC_ARG_ENABLE(upcalls,
AC_HELP_STRING( [--enable-upcalls],
[enable socket upcall support @<:@default=yes@:>@]),
enable_upcalls=$enableval,enable_upcalls=yes)
if test x$enable_upcalls = xno; then
APPCFLAGS="$APPCFLAGS -DDISABLE_UPCALLS"
AC_DEFINE(DISABLE_UPCALLS, 1, [Disable upcall support])
fi

AC_CHECK_TYPE(size_t)
AC_CHECK_TYPE(ssize_t)

Expand Down
43 changes: 4 additions & 39 deletions usrsctplib/netinet/sctp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -5931,20 +5931,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
}
}
#if defined(__Userspace__)
if ((stcb != NULL) &&
((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
(stcb->sctp_socket != NULL)) {
ACCEPT_LOCK();
if (stcb->sctp_socket->so_head != NULL) {
upcall_socket = stcb->sctp_socket->so_head;
} else {
upcall_socket = stcb->sctp_socket;
}
SOCK_LOCK(upcall_socket);
soref(upcall_socket);
SOCK_UNLOCK(upcall_socket);
ACCEPT_UNLOCK();
}
upcall_socket = sctp_get_upcall_socket_or_accept_head(stcb);
#endif
if (IS_SCTP_CONTROL(ch)) {
/* process the control portion of the SCTP packet */
Expand Down Expand Up @@ -6036,19 +6023,8 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
goto out;
}
#if defined(__Userspace__)
if ((upcall_socket == NULL) &&
((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
(stcb->sctp_socket != NULL)) {
ACCEPT_LOCK();
if (stcb->sctp_socket->so_head != NULL) {
upcall_socket = stcb->sctp_socket->so_head;
} else {
upcall_socket = stcb->sctp_socket;
}
SOCK_LOCK(upcall_socket);
soref(upcall_socket);
SOCK_UNLOCK(upcall_socket);
ACCEPT_UNLOCK();
if (upcall_socket != NULL) {
upcall_socket = sctp_get_upcall_socket_or_accept_head(stcb);
}
#endif

Expand Down Expand Up @@ -6191,18 +6167,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
SCTP_TCB_UNLOCK(stcb);
}
#if defined(__Userspace__)
if (upcall_socket != NULL) {
if (upcall_socket->so_upcall != NULL) {
if (soreadable(upcall_socket) ||
sowriteable(upcall_socket) ||
upcall_socket->so_error) {
(*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
}
}
ACCEPT_LOCK();
SOCK_LOCK(upcall_socket);
sorele(upcall_socket);
}
sctp_do_upcall_socket_if_readable_writeable_or_error(upcall_socket);
#endif
if (inp_decr != NULL) {
/* reduce ref-count */
Expand Down
17 changes: 1 addition & 16 deletions usrsctplib/netinet/sctp_usrreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -554,22 +554,7 @@ sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
inner_ip->ip_len,
(uint32_t)ntohs(icmp->icmp_nextmtu));
#if defined(__Userspace__)
if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
(stcb->sctp_socket != NULL)) {
struct socket *upcall_socket;

upcall_socket = stcb->sctp_socket;
SOCK_LOCK(upcall_socket);
soref(upcall_socket);
SOCK_UNLOCK(upcall_socket);
if ((upcall_socket->so_upcall != NULL) &&
(upcall_socket->so_error != 0)) {
(*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
}
ACCEPT_LOCK();
SOCK_LOCK(upcall_socket);
sorele(upcall_socket);
}
stcp_upcall_socket_if_error(stcb);
#endif
} else {
if ((stcb == NULL) && (inp != NULL)) {
Expand Down
138 changes: 89 additions & 49 deletions usrsctplib/netinet/sctputil.c
Original file line number Diff line number Diff line change
Expand Up @@ -1881,14 +1881,7 @@ sctp_timeout_handler(void *t)
SCTP_OS_TIMER_DEACTIVATE(&tmr->timer);

#if defined(__Userspace__)
if ((stcb != NULL) &&
((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
(stcb->sctp_socket != NULL)) {
upcall_socket = stcb->sctp_socket;
SOCK_LOCK(upcall_socket);
soref(upcall_socket);
SOCK_UNLOCK(upcall_socket);
}
upcall_socket = sctp_get_upcall_socket(stcb);
#endif
/* call the handler for the appropriate timer type */
switch (type) {
Expand Down Expand Up @@ -2206,15 +2199,7 @@ sctp_timeout_handler(void *t)

out_decr:
#if defined(__Userspace__)
if (upcall_socket != NULL) {
if ((upcall_socket->so_upcall != NULL) &&
(upcall_socket->so_error != 0)) {
(*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
}
ACCEPT_LOCK();
SOCK_LOCK(upcall_socket);
sorele(upcall_socket);
}
sctp_do_upcall_socket_if_error(upcall_socket);
#endif
/* These reference counts were incremented in sctp_timer_start(). */
if (inp != NULL) {
Expand Down Expand Up @@ -8281,22 +8266,7 @@ sctp_recv_icmp_tunneled_packet(udp_tun_icmp_param_t param)
ntohs(inner_ip->ip_len),
(uint32_t)ntohs(icmp->icmp_nextmtu));
#if defined(__Userspace__)
if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
(stcb->sctp_socket != NULL)) {
struct socket *upcall_socket;

upcall_socket = stcb->sctp_socket;
SOCK_LOCK(upcall_socket);
soref(upcall_socket);
SOCK_UNLOCK(upcall_socket);
if ((upcall_socket->so_upcall != NULL) &&
(upcall_socket->so_error != 0)) {
(*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
}
ACCEPT_LOCK();
SOCK_LOCK(upcall_socket);
sorele(upcall_socket);
}
sctp_upcall_socket_if_error(stcb);
#endif
} else {
if ((stcb == NULL) && (inp != NULL)) {
Expand Down Expand Up @@ -8453,22 +8423,7 @@ sctp_recv_icmp6_tunneled_packet(udp_tun_icmp_param_t param)
sctp6_notify(inp, stcb, net, type, code,
ntohl(ip6cp->ip6c_icmp6->icmp6_mtu));
#if defined(__Userspace__)
if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
(stcb->sctp_socket != NULL)) {
struct socket *upcall_socket;

upcall_socket = stcb->sctp_socket;
SOCK_LOCK(upcall_socket);
soref(upcall_socket);
SOCK_UNLOCK(upcall_socket);
if ((upcall_socket->so_upcall != NULL) &&
(upcall_socket->so_error != 0)) {
(*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
}
ACCEPT_LOCK();
SOCK_LOCK(upcall_socket);
sorele(upcall_socket);
}
sctp_upcall_socket_if_error(stcb);
#endif
} else {
if ((stcb == NULL) && (inp != NULL)) {
Expand Down Expand Up @@ -8723,3 +8678,88 @@ sctp_add_substate(struct sctp_tcb *stcb, int substate)
#endif
}


#if defined(__Userspace__)
struct socket* sctp_get_upcall_socket(struct sctp_tcb * stcb)
{
#ifdef DISABLE_UPCALLS
return NULL;
#else
struct socket* upcall_socket = NULL;
if ((stcb != NULL) &&
((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
(stcb->sctp_socket != NULL)) {
upcall_socket = stcb->sctp_socket;
SOCK_LOCK(upcall_socket);
soref(upcall_socket);
SOCK_UNLOCK(upcall_socket);
}
return upcall_socket;
#endif
}

struct socket* sctp_get_upcall_socket_or_accept_head(struct sctp_tcb * stcb)
{
#ifdef DISABLE_UPCALLS
return NULL;
#else
struct socket* upcall_socket = NULL;
if ((stcb != NULL) &&
((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
(stcb->sctp_socket != NULL)) {
ACCEPT_LOCK();
if (stcb->sctp_socket->so_head != NULL) {
upcall_socket = stcb->sctp_socket->so_head;
} else {
upcall_socket = stcb->sctp_socket;
}
SOCK_LOCK(upcall_socket);
soref(upcall_socket);
SOCK_UNLOCK(upcall_socket);
ACCEPT_UNLOCK();
}
return upcall_socket;
#endif
}


void sctp_do_upcall_socket_if_error(struct socket *upcall_socket)
{
#ifndef DISABLE_UPCALLS
if (upcall_socket != NULL) {
if ((upcall_socket->so_upcall != NULL) &&
(upcall_socket->so_error != 0)) {
(*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
}
ACCEPT_LOCK();
SOCK_LOCK(upcall_socket);
sorele(upcall_socket);
}
#endif
}

void sctp_do_upcall_socket_if_readable_writeable_or_error(struct socket *upcall_socket)
{
#ifndef DISABLE_UPCALLS
if (upcall_socket != NULL) {
if (upcall_socket->so_upcall != NULL) {
if (soreadable(upcall_socket) ||
sowriteable(upcall_socket) ||
upcall_socket->so_error != 0) {
(*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
}
}
ACCEPT_LOCK();
SOCK_LOCK(upcall_socket);
sorele(upcall_socket);
}
#endif
}

void sctp_upcall_socket_if_error(struct sctp_tcb *stcb)
{
struct socket *upcall_socket;
upcall_socket = sctp_get_upcall_socket(stcb);
sctp_do_upcall_socket_if_error(upcall_socket);
}
#endif
8 changes: 8 additions & 0 deletions usrsctplib/netinet/sctputil.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,5 +371,13 @@ uint32_t sctp_msecs_to_ticks(uint32_t);
uint32_t sctp_ticks_to_secs(uint32_t);
uint32_t sctp_secs_to_ticks(uint32_t);

#if defined(__Userspace__)
void sctp_upcall_socket_if_error(struct sctp_tcb *);
struct socket* sctp_get_upcall_socket(struct sctp_tcb *);
struct socket* sctp_get_upcall_socket_or_accept_head(struct sctp_tcb * stcb);
void sctp_do_upcall_socket_if_error(struct socket *);
void sctp_do_upcall_socket_if_readable_writeable_or_error(struct socket *);
#endif

#endif /* _KERNEL */
#endif
17 changes: 1 addition & 16 deletions usrsctplib/netinet6/sctp6_usrreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,22 +614,7 @@ sctp6_ctlinput(int cmd, struct sockaddr *pktdst, void *d)
ip6cp->ip6c_icmp6->icmp6_code,
ntohl(ip6cp->ip6c_icmp6->icmp6_mtu));
#if defined(__Userspace__)
if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
(stcb->sctp_socket != NULL)) {
struct socket *upcall_socket;

upcall_socket = stcb->sctp_socket;
SOCK_LOCK(upcall_socket);
soref(upcall_socket);
SOCK_UNLOCK(upcall_socket);
if ((upcall_socket->so_upcall != NULL) &&
(upcall_socket->so_error != 0)) {
(*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
}
ACCEPT_LOCK();
SOCK_LOCK(upcall_socket);
sorele(upcall_socket);
}
stcp_upcall_socket_if_error(stcb);
#endif
} else {
if ((stcb == NULL) && (inp != NULL)) {
Expand Down
5 changes: 5 additions & 0 deletions usrsctplib/user_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -3369,6 +3369,10 @@ usrsctp_set_upcall(struct socket *so, void (*upcall)(struct socket *, void *, in
return (-1);
}

#ifdef DISABLE_UPCALLS
errno = ENOSYS;
return -1;
#else
SOCK_LOCK(so);
so->so_upcall = upcall;
so->so_upcallarg = arg;
Expand All @@ -3377,6 +3381,7 @@ usrsctp_set_upcall(struct socket *so, void (*upcall)(struct socket *, void *, in
SOCK_UNLOCK(so);

return (0);
#endif
}

#define USRSCTP_TUNABLE_SET_DEF(__field, __prefix) \
Expand Down
Loading