blob: d45b1619b3bdf4909b7698453522b04000a54782 [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
22struct iofd_backend_ops {
23 int (*register_fd)(struct osmo_io_fd *iofd);
24 int (*unregister_fd)(struct osmo_io_fd *iofd);
25 int (*close)(struct osmo_io_fd *iofd);
26 void (*write_enable)(struct osmo_io_fd *iofd);
27 void (*write_disable)(struct osmo_io_fd *iofd);
28 void (*read_enable)(struct osmo_io_fd *iofd);
29 void (*read_disable)(struct osmo_io_fd *iofd);
30};
31
Daniel Willmannf89162f2023-06-26 19:24:46 +020032#define IOFD_FLAG_CLOSED (1<<0)
33#define IOFD_FLAG_IN_CALLBACK (1<<1)
34#define IOFD_FLAG_TO_FREE (1<<2)
35#define IOFD_FLAG_NOTIFY_CONNECTED (1<<3)
36
37#define IOFD_FLAG_SET(iofd, flag) \
38 (iofd)->flags |= (flag)
39
40#define IOFD_FLAG_UNSET(iofd, flag) \
41 (iofd)->flags &= ~(flag)
42
43#define IOFD_FLAG_ISSET(iofd, flag) ((iofd)->flags & (flag))
44
Harald Welte8857f3b2022-11-18 13:54:44 +010045struct osmo_io_fd {
46 /*! linked list for internal management */
47 struct llist_head list;
48 /*! actual operating-system level file decriptor */
49 int fd;
50 /*! type of read/write mode to use */
51 enum osmo_io_fd_mode mode;
52
53 /*! flags to guard closing/freeing of iofd */
Daniel Willmannf89162f2023-06-26 19:24:46 +020054 uint32_t flags;
Harald Welte8857f3b2022-11-18 13:54:44 +010055
Harald Welte8857f3b2022-11-18 13:54:44 +010056 /*! human-readable name to associte with fd */
Pau Espin Pedrol63e45e62023-06-16 16:19:45 +020057 char *name;
Harald Welte8857f3b2022-11-18 13:54:44 +010058
59 /*! send/recv (msg) callback functions */
60 struct osmo_io_ops io_ops;
61 /*! Pending msgb to keep partial data during segmentation */
62 struct msgb *pending;
63
64 /*! data pointer passed through to call-back function */
65 void *data;
66 /*! private number, extending \a data */
67 unsigned int priv_nr;
68
69 struct {
70 /*! talloc context from which to allocate msgb when reading */
71 const void *ctx;
72 /*! size of msgb to allocate (excluding headroom) */
73 unsigned int size;
74 /*! headroom to allocate when allocating msgb's */
75 unsigned int headroom;
76 } msgb_alloc;
77
78 struct {
79 /*! maximum length of write queue */
80 unsigned int max_length;
81 /*! current length of write queue */
82 unsigned int current_length;
83 /*! actual linked list implementing the transmit queue */
84 struct llist_head msg_queue;
85 } tx_queue;
86
87 union {
88 struct {
89 struct osmo_fd ofd;
90 } poll;
91 struct {
92 bool read_enabled;
93 bool read_pending;
94 bool write_pending;
95 bool write_enabled;
96 /* TODO: index into array of registered fd's? */
97 } uring;
98 } u;
99};
100
101enum iofd_msg_action {
102 IOFD_ACT_READ,
103 IOFD_ACT_WRITE,
104 IOFD_ACT_RECVFROM,
105 IOFD_ACT_SENDTO,
106 // TODO: SCTP_*
107};
108
109
110/* serialized version of 'struct msghdr' employed by sendmsg/recvmsg */
111struct iofd_msghdr {
112 struct llist_head list;
113 enum iofd_msg_action action;
114 struct msghdr hdr;
115 struct osmo_sockaddr osa;
116 struct iovec iov[1];
117 int flags;
118
119 struct msgb *msg;
120 struct osmo_io_fd *iofd;
121};
122
123enum iofd_seg_act {
124 IOFD_SEG_ACT_HANDLE_ONE,
125 IOFD_SEG_ACT_HANDLE_MORE,
126 IOFD_SEG_ACT_DEFER,
127};
128
129struct iofd_msghdr *iofd_msghdr_alloc(struct osmo_io_fd *iofd, enum iofd_msg_action action, struct msgb *msg);
130void iofd_msghdr_free(struct iofd_msghdr *msghdr);
131
132struct msgb *iofd_msgb_alloc(struct osmo_io_fd *iofd);
133struct msgb *iofd_msgb_pending(struct osmo_io_fd *iofd);
134struct msgb *iofd_msgb_pending_or_alloc(struct osmo_io_fd *iofd);
135
136void iofd_handle_segmented_read(struct osmo_io_fd *iofd, struct msgb *msg, int rc);
137
138int iofd_txqueue_enqueue(struct osmo_io_fd *iofd, struct iofd_msghdr *msghdr);
139void iofd_txqueue_enqueue_front(struct osmo_io_fd *iofd, struct iofd_msghdr *msghdr);
140struct iofd_msghdr *iofd_txqueue_dequeue(struct osmo_io_fd *iofd);