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