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