aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2021-12-23 16:02:07 +0700
committerVadim Yanitskiy <vyanitskiy@sysmocom.de>2021-12-23 16:02:14 +0700
commit61ed7fcd7ae90ac024d421efc5237adb69c080fd (patch)
tree53ac3fe32340dafd4e6c79b9901f544458ff60f8
parente59472a50a6a60df27f16bf0cfc4d40e4e6c5aa5 (diff)
sctp_sock_activate_events(): use the new SCTP_EVENT API (RFC 6458)fixeria/sctp_event
-rw-r--r--src/stream.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/stream.c b/src/stream.c
index 4379212..73b1795 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -173,6 +173,42 @@ static int sctp_sock_activate_events(int fd)
struct sctp_event_subscribe event;
int rc;
+#ifdef SCTP_EVENT
+ /* See https://datatracker.ietf.org/doc/html/rfc6458 Section 6.2.2
+ * and 480ba9c18a27ff77b02a2012e50dfd3e20ee9f7a in linux.git */
+ unsigned int elen = sizeof(struct sctp_event);
+ struct sctp_event e;
+ unsigned int i;
+
+ /* Use getsockopt() to check if SCTP_EVENT is supported by the kernel.
+ * The related code is only present in kernels >= 5.0. */
+ e = (struct sctp_event) { .se_type = SCTP_DATA_IO_EVENT }; // FIXME: se_assoc_id
+ if (getsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &e, &elen) != 0)
+ goto fallback;
+
+ const uint16_t events[] = {
+ SCTP_DATA_IO_EVENT,
+ SCTP_ASSOC_CHANGE,
+ SCTP_PEER_ADDR_CHANGE,
+ SCTP_SEND_FAILED,
+ SCTP_REMOTE_ERROR,
+ SCTP_SHUTDOWN_EVENT,
+ };
+
+ for (i = 0; i < ARRAY_SIZE(events); i++) {
+ e = (struct sctp_event) { .se_type = events[i], .se_on = 1 }; // FIXME: se_assoc_id
+ if ((rc = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &e, sizeof(e))) != 0) {
+ LOGP(DLINP, LOGL_ERROR,
+ "Couldn't activate SCTP event %u on FD %u\n",
+ events[i], fd);
+ return rc;
+ }
+ }
+
+ return 0;
+#endif
+
+fallback:
/* subscribe for all relevant events */
memset((uint8_t *)&event, 0, sizeof(event));
event.sctp_data_io_event = 1;