diff options
author | Vadim Yanitskiy <vyanitskiy@sysmocom.de> | 2021-12-23 16:02:07 +0700 |
---|---|---|
committer | Vadim Yanitskiy <vyanitskiy@sysmocom.de> | 2021-12-23 16:02:14 +0700 |
commit | 61ed7fcd7ae90ac024d421efc5237adb69c080fd (patch) | |
tree | 53ac3fe32340dafd4e6c79b9901f544458ff60f8 | |
parent | e59472a50a6a60df27f16bf0cfc4d40e4e6c5aa5 (diff) |
sctp_sock_activate_events(): use the new SCTP_EVENT API (RFC 6458)fixeria/sctp_event
Change-Id: Id3ed9cacd4b1b54b53f8abe772887e47fbc14560
Related: OS#5368
-rw-r--r-- | src/stream.c | 36 |
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; |