OpenVPN
mbuf.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2002-2025 OpenVPN Inc <sales@openvpn.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, see <https://www.gnu.org/licenses/>.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include "syshead.h"
28
29#include "buffer.h"
30#include "error.h"
31#include "integer.h"
32#include "misc.h"
33#include "mbuf.h"
34
35#include "memdbg.h"
36
37struct mbuf_set *
38mbuf_init(unsigned int size)
39{
40 struct mbuf_set *ret;
41 ALLOC_OBJ_CLEAR(ret, struct mbuf_set);
42 ret->capacity = adjust_power_of_2(size);
43 ALLOC_ARRAY(ret->array, struct mbuf_item, ret->capacity);
44 return ret;
45}
46
47void
49{
50 if (ms)
51 {
52 int i;
53 for (i = 0; i < (int)ms->len; ++i)
54 {
55 struct mbuf_item *item = &ms->array[MBUF_INDEX(ms->head, i, ms->capacity)];
56 mbuf_free_buf(item->buffer);
57 }
58 free(ms->array);
59 free(ms);
60 }
61}
62
63struct mbuf_buffer *
65{
66 struct mbuf_buffer *ret;
67 ALLOC_OBJ(ret, struct mbuf_buffer);
68 ret->buf = clone_buf(buf);
69 ret->refcount = 1;
70 ret->flags = 0;
71 return ret;
72}
73
74void
76{
77 if (mb)
78 {
79 if (--mb->refcount <= 0)
80 {
81 free_buf(&mb->buf);
82 free(mb);
83 }
84 }
85}
86
87void
88mbuf_add_item(struct mbuf_set *ms, const struct mbuf_item *item)
89{
90 ASSERT(ms);
91 if (ms->len == ms->capacity)
92 {
93 struct mbuf_item rm;
94 ASSERT(mbuf_extract_item(ms, &rm));
96 msg(D_MULTI_DROPPED, "MBUF: mbuf packet dropped");
97 }
98
99 ASSERT(ms->len < ms->capacity);
100
101 ms->array[MBUF_INDEX(ms->head, ms->len, ms->capacity)] = *item;
102 if (++ms->len > ms->max_queued)
103 {
104 ms->max_queued = ms->len;
105 }
106 ++item->buffer->refcount;
107}
108
109bool
110mbuf_extract_item(struct mbuf_set *ms, struct mbuf_item *item)
111{
112 bool ret = false;
113 if (ms)
114 {
115 while (ms->len)
116 {
117 *item = ms->array[ms->head];
118 ms->head = MBUF_INDEX(ms->head, 1, ms->capacity);
119 --ms->len;
120 if (item->instance) /* ignore dereferenced instances */
121 {
122 ret = true;
123 break;
124 }
125 }
126 }
127 return ret;
128}
129
130struct multi_instance *
132{
133 struct multi_instance *ret = NULL;
134 if (ms)
135 {
136 int i;
137 for (i = 0; i < (int)ms->len; ++i)
138 {
139 struct mbuf_item *item = &ms->array[MBUF_INDEX(ms->head, i, ms->capacity)];
140 if (item->instance)
141 {
142 ret = item->instance;
143 break;
144 }
145 }
146 }
147 return ret;
148}
149
150void
152{
153 if (ms)
154 {
155 int i;
156 for (i = 0; i < (int)ms->len; ++i)
157 {
158 struct mbuf_item *item = &ms->array[MBUF_INDEX(ms->head, i, ms->capacity)];
159 if (item->instance == mi)
160 {
161 mbuf_free_buf(item->buffer);
162 item->buffer = NULL;
163 item->instance = NULL;
164 msg(D_MBUF, "MBUF: dereferenced queued packet");
165 }
166 }
167 }
168}
void free_buf(struct buffer *buf)
Definition buffer.c:184
struct buffer clone_buf(const struct buffer *buf)
Definition buffer.c:116
#define ALLOC_OBJ(dptr, type)
Definition buffer.h:1037
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition buffer.h:1042
#define ALLOC_ARRAY(dptr, type, n)
Definition buffer.h:1048
#define D_MBUF
Definition errlevel.h:98
#define D_MULTI_DROPPED
Definition errlevel.h:100
static size_t adjust_power_of_2(size_t u)
Definition integer.h:184
void mbuf_add_item(struct mbuf_set *ms, const struct mbuf_item *item)
Definition mbuf.c:88
struct mbuf_buffer * mbuf_alloc_buf(const struct buffer *buf)
Definition mbuf.c:64
void mbuf_free_buf(struct mbuf_buffer *mb)
Definition mbuf.c:75
void mbuf_dereference_instance(struct mbuf_set *ms, struct multi_instance *mi)
Definition mbuf.c:151
bool mbuf_extract_item(struct mbuf_set *ms, struct mbuf_item *item)
Definition mbuf.c:110
void mbuf_free(struct mbuf_set *ms)
Definition mbuf.c:48
struct multi_instance * mbuf_peek_dowork(struct mbuf_set *ms)
Definition mbuf.c:131
struct mbuf_set * mbuf_init(unsigned int size)
Definition mbuf.c:38
#define MBUF_INDEX(head, offset, size)
Definition mbuf.h:38
#define msg(flags,...)
Definition error.h:150
#define ASSERT(x)
Definition error.h:217
Wrapper structure for dynamically allocated memory.
Definition buffer.h:60
unsigned int flags
Definition mbuf.h:46
struct buffer buf
Definition mbuf.h:42
int refcount
Definition mbuf.h:43
struct mbuf_buffer * buffer
Definition mbuf.h:51
struct multi_instance * instance
Definition mbuf.h:52
struct mbuf_item * array
Definition mbuf.h:61
unsigned int max_queued
Definition mbuf.h:60
unsigned int head
Definition mbuf.h:57
unsigned int len
Definition mbuf.h:58
unsigned int capacity
Definition mbuf.h:59
Server-mode state structure for one single VPN tunnel.
Definition multi.h:103