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-2024 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, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include "syshead.h"
29
30#include "buffer.h"
31#include "error.h"
32#include "integer.h"
33#include "misc.h"
34#include "mbuf.h"
35
36#include "memdbg.h"
37
38struct mbuf_set *
39mbuf_init(unsigned int size)
40{
41 struct mbuf_set *ret;
42 ALLOC_OBJ_CLEAR(ret, struct mbuf_set);
43 ret->capacity = adjust_power_of_2(size);
44 ALLOC_ARRAY(ret->array, struct mbuf_item, ret->capacity);
45 return ret;
46}
47
48void
50{
51 if (ms)
52 {
53 int i;
54 for (i = 0; i < (int) ms->len; ++i)
55 {
56 struct mbuf_item *item = &ms->array[MBUF_INDEX(ms->head, i, ms->capacity)];
57 mbuf_free_buf(item->buffer);
58 }
59 free(ms->array);
60 free(ms);
61 }
62}
63
64struct mbuf_buffer *
66{
67 struct mbuf_buffer *ret;
68 ALLOC_OBJ(ret, struct mbuf_buffer);
69 ret->buf = clone_buf(buf);
70 ret->refcount = 1;
71 ret->flags = 0;
72 return ret;
73}
74
75void
77{
78 if (mb)
79 {
80 if (--mb->refcount <= 0)
81 {
82 free_buf(&mb->buf);
83 free(mb);
84 }
85 }
86}
87
88void
89mbuf_add_item(struct mbuf_set *ms, const struct mbuf_item *item)
90{
91 ASSERT(ms);
92 if (ms->len == ms->capacity)
93 {
94 struct mbuf_item rm;
95 ASSERT(mbuf_extract_item(ms, &rm));
97 msg(D_MULTI_DROPPED, "MBUF: mbuf packet dropped");
98 }
99
100 ASSERT(ms->len < ms->capacity);
101
102 ms->array[MBUF_INDEX(ms->head, ms->len, ms->capacity)] = *item;
103 if (++ms->len > ms->max_queued)
104 {
105 ms->max_queued = ms->len;
106 }
107 ++item->buffer->refcount;
108}
109
110bool
111mbuf_extract_item(struct mbuf_set *ms, struct mbuf_item *item)
112{
113 bool ret = false;
114 if (ms)
115 {
116 while (ms->len)
117 {
118 *item = ms->array[ms->head];
119 ms->head = MBUF_INDEX(ms->head, 1, ms->capacity);
120 --ms->len;
121 if (item->instance) /* ignore dereferenced instances */
122 {
123 ret = true;
124 break;
125 }
126 }
127 }
128 return ret;
129}
130
131struct multi_instance *
133{
134 struct multi_instance *ret = NULL;
135 if (ms)
136 {
137 int i;
138 for (i = 0; i < (int) ms->len; ++i)
139 {
140 struct mbuf_item *item = &ms->array[MBUF_INDEX(ms->head, i, ms->capacity)];
141 if (item->instance)
142 {
143 ret = item->instance;
144 break;
145 }
146 }
147 }
148 return ret;
149}
150
151void
153{
154 if (ms)
155 {
156 int i;
157 for (i = 0; i < (int) ms->len; ++i)
158 {
159 struct mbuf_item *item = &ms->array[MBUF_INDEX(ms->head, i, ms->capacity)];
160 if (item->instance == mi)
161 {
162 mbuf_free_buf(item->buffer);
163 item->buffer = NULL;
164 item->instance = NULL;
165 msg(D_MBUF, "MBUF: dereferenced queued packet");
166 }
167 }
168 }
169}
void free_buf(struct buffer *buf)
Definition buffer.c:183
struct buffer clone_buf(const struct buffer *buf)
Definition buffer.c:115
#define ALLOC_OBJ(dptr, type)
Definition buffer.h:1055
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition buffer.h:1060
#define ALLOC_ARRAY(dptr, type, n)
Definition buffer.h:1066
#define D_MBUF
Definition errlevel.h:99
#define D_MULTI_DROPPED
Definition errlevel.h:101
static size_t adjust_power_of_2(size_t u)
Definition integer.h:181
void mbuf_add_item(struct mbuf_set *ms, const struct mbuf_item *item)
Definition mbuf.c:89
struct mbuf_buffer * mbuf_alloc_buf(const struct buffer *buf)
Definition mbuf.c:65
void mbuf_free_buf(struct mbuf_buffer *mb)
Definition mbuf.c:76
void mbuf_dereference_instance(struct mbuf_set *ms, struct multi_instance *mi)
Definition mbuf.c:152
bool mbuf_extract_item(struct mbuf_set *ms, struct mbuf_item *item)
Definition mbuf.c:111
void mbuf_free(struct mbuf_set *ms)
Definition mbuf.c:49
struct multi_instance * mbuf_peek_dowork(struct mbuf_set *ms)
Definition mbuf.c:132
struct mbuf_set * mbuf_init(unsigned int size)
Definition mbuf.c:39
#define MBUF_INDEX(head, offset, size)
Definition mbuf.h:39
#define msg(flags,...)
Definition error.h:144
#define ASSERT(x)
Definition error.h:195
Wrapper structure for dynamically allocated memory.
Definition buffer.h:61
unsigned int flags
Definition mbuf.h:47
struct buffer buf
Definition mbuf.h:43
int refcount
Definition mbuf.h:44
struct mbuf_buffer * buffer
Definition mbuf.h:52
struct multi_instance * instance
Definition mbuf.h:53
struct mbuf_item * array
Definition mbuf.h:62
unsigned int max_queued
Definition mbuf.h:61
unsigned int head
Definition mbuf.h:58
unsigned int len
Definition mbuf.h:59
unsigned int capacity
Definition mbuf.h:60
Server-mode state structure for one single VPN tunnel.
Definition multi.h:103