blob: e8f4ea28ac899a40eab162a1d2d15d207bbdb841 [file] [log] [blame]
Harald Welte8857f3b2022-11-18 13:54:44 +01001/*! \file osmo_io_internal.h */
2
3#pragma once
4
5#include <unistd.h>
6#include <stdbool.h>
7
8#include <osmocom/core/osmo_io.h>
9#include <osmocom/core/linuxlist.h>
10#include <osmocom/core/msgb.h>
11#include <osmocom/core/select.h>
12#include <osmocom/core/socket.h>
13
14#include "../config.h"
15
16#define OSMO_IO_DEFAULT_MSGB_SIZE 1024
17#define OSMO_IO_DEFAULT_MSGB_HEADROOM 128
18
19extern const struct iofd_backend_ops iofd_poll_ops;
20#define OSMO_IO_BACKEND_DEFAULT "POLL"
21
Daniel Willmannf91d2aa2023-01-04 18:20:55 +010022#if defined(HAVE_URING)
23extern const struct iofd_backend_ops iofd_uring_ops;
24#endif
25
Harald Welte8857f3b2022-11-18 13:54:44 +010026struct iofd_backend_ops {
27 int (*register_fd)(struct osmo_io_fd *iofd);
28 int (*unregister_fd)(struct osmo_io_fd *iofd);
29 int (*close)(struct osmo_io_fd *iofd);
30 void (*write_enable)(struct osmo_io_fd *iofd);
31 void (*write_disable)(struct osmo_io_fd *iofd);
32 void (*read_enable)(struct osmo_io_fd *iofd);
33 void (*read_disable)(struct osmo_io_fd *iofd);
34};
35
Daniel Willmannf89162f2023-06-26 19:24:46 +020036#define IOFD_FLAG_CLOSED (1<<0)
37#define IOFD_FLAG_IN_CALLBACK (1<<1)
38#define IOFD_FLAG_TO_FREE (1<<2)
39#define IOFD_FLAG_NOTIFY_CONNECTED (1<<3)
40
41#define IOFD_FLAG_SET(iofd, flag) \
42 (iofd)->flags |= (flag)
43
44#define IOFD_FLAG_UNSET(iofd, flag) \
45 (iofd)->flags &= ~(flag)
46
47#define IOFD_FLAG_ISSET(iofd, flag) ((iofd)->flags & (flag))
48
Harald Welte8857f3b2022-11-18 13:54:44 +010049struct osmo_io_fd {
50 /*! linked list for internal management */
51 struct llist_head list;
52 /*! actual operating-system level file decriptor */
53 int fd;
54 /*! type of read/write mode to use */
55 enum osmo_io_fd_mode mode;
56
57 /*! flags to guard closing/freeing of iofd */
Daniel Willmannf89162f2023-06-26 19:24:46 +020058 uint32_t flags;
Harald Welte8857f3b2022-11-18 13:54:44 +010059
Harald Welte8857f3b2022-11-18 13:54:44 +010060 /*! human-readable name to associte with fd */
Pau Espin Pedrol63e45e62023-06-16 16:19:45 +020061 char *name;
Harald Welte8857f3b2022-11-18 13:54:44 +010062
63 /*! send/recv (msg) callback functions */
64 struct osmo_io_ops io_ops;
65 /*! Pending msgb to keep partial data during segmentation */
66 struct msgb *pending;
67
68 /*! data pointer passed through to call-back function */
69 void *data;
70 /*! private number, extending \a data */
71 unsigned int priv_nr;
72
73 struct {
74 /*! talloc context from which to allocate msgb when reading */
75 const void *ctx;
76 /*! size of msgb to allocate (excluding headroom) */
77 unsigned int size;
78 /*! headroom to allocate when allocating msgb's */
79 unsigned int headroom;
80 } msgb_alloc;
81
82 struct {
83 /*! maximum length of write queue */
84 unsigned int max_length;
85 /*! current length of write queue */
86 unsigned int current_length;
87 /*! actual linked list implementing the transmit queue */
88 struct llist_head msg_queue;
89 } tx_queue;
90
91 union {
92 struct {
93 struct osmo_fd ofd;
94 } poll;
95 struct {
96 bool read_enabled;
Harald Welte8857f3b2022-11-18 13:54:44 +010097 bool write_enabled;
Daniel Willmannf91d2aa2023-01-04 18:20:55 +010098 void *read_msghdr;
99 void *write_msghdr;
Harald Welte8857f3b2022-11-18 13:54:44 +0100100 /* TODO: index into array of registered fd's? */
101 } uring;
102 } u;
103};
104
105enum iofd_msg_action {
106 IOFD_ACT_READ,
107 IOFD_ACT_WRITE,
108 IOFD_ACT_RECVFROM,
109 IOFD_ACT_SENDTO,
110 // TODO: SCTP_*
111};
112
113
Harald Welte987a86a2023-11-18 18:46:24 +0100114/*! serialized version of 'struct msghdr' employed by sendmsg/recvmsg */
Harald Welte8857f3b2022-11-18 13:54:44 +0100115struct iofd_msghdr {
Harald Welte987a86a2023-11-18 18:46:24 +0100116 /*! entry into osmo_io_fd.tx_queue.msg_queue */
Harald Welte8857f3b2022-11-18 13:54:44 +0100117 struct llist_head list;
118 enum iofd_msg_action action;
Harald Welte987a86a2023-11-18 18:46:24 +0100119 /*! the 'struct msghdr' we are wrapping/ecapsulating here */
Harald Welte8857f3b2022-11-18 13:54:44 +0100120 struct msghdr hdr;
Harald Welte987a86a2023-11-18 18:46:24 +0100121 /*! socket address of the remote peer */
Harald Welte8857f3b2022-11-18 13:54:44 +0100122 struct osmo_sockaddr osa;
Harald Welte987a86a2023-11-18 18:46:24 +0100123 /*! io-vector we need to pass as argument to sendmsg/recvmsg; is set up
124 * to point into msg below */
Harald Welte8857f3b2022-11-18 13:54:44 +0100125 struct iovec iov[1];
Harald Welte987a86a2023-11-18 18:46:24 +0100126 /*! flags we pass as argument to sendmsg / recvmsg */
Harald Welte8857f3b2022-11-18 13:54:44 +0100127 int flags;
128
Harald Welte987a86a2023-11-18 18:46:24 +0100129 /*! message-buffer containing data for this I/O operation */
Harald Welte8857f3b2022-11-18 13:54:44 +0100130 struct msgb *msg;
Harald Welte987a86a2023-11-18 18:46:24 +0100131 /*! I/O file descriptor on which we perform this I/O operation */
Harald Welte8857f3b2022-11-18 13:54:44 +0100132 struct osmo_io_fd *iofd;
133};
134
135enum iofd_seg_act {
136 IOFD_SEG_ACT_HANDLE_ONE,
137 IOFD_SEG_ACT_HANDLE_MORE,
138 IOFD_SEG_ACT_DEFER,
139};
140
141struct iofd_msghdr *iofd_msghdr_alloc(struct osmo_io_fd *iofd, enum iofd_msg_action action, struct msgb *msg);
142void iofd_msghdr_free(struct iofd_msghdr *msghdr);
143
144struct msgb *iofd_msgb_alloc(struct osmo_io_fd *iofd);
145struct msgb *iofd_msgb_pending(struct osmo_io_fd *iofd);
146struct msgb *iofd_msgb_pending_or_alloc(struct osmo_io_fd *iofd);
147
Daniel Willmann2b34e922023-08-23 18:02:13 +0200148void iofd_handle_recv(struct osmo_io_fd *iofd, struct msgb *msg, int rc, struct iofd_msghdr *msghdr);
Daniel Willmann84611882023-11-21 10:17:00 +0100149void iofd_handle_send_completion(struct osmo_io_fd *iofd, int rc, struct iofd_msghdr *msghdr);
Harald Welte8857f3b2022-11-18 13:54:44 +0100150void iofd_handle_segmented_read(struct osmo_io_fd *iofd, struct msgb *msg, int rc);
151
152int iofd_txqueue_enqueue(struct osmo_io_fd *iofd, struct iofd_msghdr *msghdr);
153void iofd_txqueue_enqueue_front(struct osmo_io_fd *iofd, struct iofd_msghdr *msghdr);
154struct iofd_msghdr *iofd_txqueue_dequeue(struct osmo_io_fd *iofd);