osmo_io: Only allow reading/writing if the relevant callback is set
Allow the callbacks to be NULL, but then sending/receiving is disabled.
There are some cases where we only care about writing to or reading from
an fd.
Change-Id: I11ce072510b591f7881d09888524426579bd0169
diff --git a/src/core/osmo_io.c b/src/core/osmo_io.c
index c67787b..2b2b7dd 100644
--- a/src/core/osmo_io.c
+++ b/src/core/osmo_io.c
@@ -355,6 +355,12 @@
int osmo_iofd_write_msgb(struct osmo_io_fd *iofd, struct msgb *msg)
{
int rc;
+
+ if (OSMO_UNLIKELY(!iofd->io_ops.write_cb)) {
+ LOGPIO(iofd, LOGL_ERROR, "write_cb not set, Rejecting msgb\n");
+ return -EINVAL;
+ }
+
struct iofd_msghdr *msghdr = iofd_msghdr_alloc(iofd, IOFD_ACT_WRITE, msg);
if (!msghdr)
return -ENOMEM;
@@ -392,6 +398,10 @@
int rc;
OSMO_ASSERT(iofd->mode == OSMO_IO_FD_MODE_RECVFROM_SENDTO);
+ if (OSMO_UNLIKELY(!iofd->io_ops.sendto_cb)) {
+ LOGPIO(iofd, LOGL_ERROR, "sendto_cb not set, Rejecting msgb\n");
+ return -EINVAL;
+ }
struct iofd_msghdr *msghdr = iofd_msghdr_alloc(iofd, IOFD_ACT_SENDTO, msg);
if (!msghdr)
@@ -477,7 +487,8 @@
return rc;
IOFD_FLAG_UNSET(iofd, IOFD_FLAG_CLOSED);
- osmo_iofd_ops.read_enable(iofd);
+ if (iofd->io_ops.read_cb)
+ osmo_iofd_ops.read_enable(iofd);
if (iofd->tx_queue.current_length > 0)
osmo_iofd_ops.write_enable(iofd);
@@ -658,6 +669,24 @@
void osmo_iofd_set_ioops(struct osmo_io_fd *iofd, const struct osmo_io_ops *ioops)
{
iofd->io_ops = *ioops;
+
+ switch (iofd->mode) {
+ case OSMO_IO_FD_MODE_READ_WRITE:
+ if (iofd->io_ops.read_cb)
+ osmo_iofd_ops.read_enable(iofd);
+ else
+ osmo_iofd_ops.read_disable(iofd);
+ break;
+ case OSMO_IO_FD_MODE_RECVFROM_SENDTO:
+ if (iofd->io_ops.recvfrom_cb)
+ osmo_iofd_ops.read_enable(iofd);
+ else
+ osmo_iofd_ops.read_disable(iofd);
+ break;
+ case OSMO_IO_FD_MODE_SCTP_RECVMSG_SENDMSG:
+ default:
+ OSMO_ASSERT(0);
+ }
}
/*! Notify the user if/when the socket is connected.