cosmetics
[tomato.git] / release / src / router / openvpn / mbuf.c
blob55960b3e518915284c754742c8389ee93dc41bbd
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.
8 * Copyright (C) 2002-2009 OpenVPN Technologies, Inc. <sales@openvpn.net>
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.
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.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "syshead.h"
27 #if P2MP
29 #include "buffer.h"
30 #include "error.h"
31 #include "misc.h"
32 #include "mbuf.h"
34 #include "memdbg.h"
36 struct mbuf_set *
37 mbuf_init (unsigned int size)
39 struct mbuf_set *ret;
40 ALLOC_OBJ_CLEAR (ret, struct mbuf_set);
41 mutex_init (&ret->mutex);
42 ret->capacity = adjust_power_of_2 (size);
43 ALLOC_ARRAY (ret->array, struct mbuf_item, ret->capacity);
44 return ret;
47 void
48 mbuf_free (struct mbuf_set *ms)
50 if (ms)
52 int i;
53 for (i = 0; i < (int) ms->len; ++i)
55 struct mbuf_item *item = &ms->array[MBUF_INDEX(ms->head, i, ms->capacity)];
56 mbuf_free_buf (item->buffer);
58 free (ms->array);
59 mutex_destroy (&ms->mutex);
60 free (ms);
64 struct mbuf_buffer *
65 mbuf_alloc_buf (const struct buffer *buf)
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;
75 void
76 mbuf_free_buf (struct mbuf_buffer *mb)
78 if (mb)
80 if (--mb->refcount <= 0)
82 free_buf (&mb->buf);
83 free (mb);
88 void
89 mbuf_add_item (struct mbuf_set *ms, const struct mbuf_item *item)
91 ASSERT (ms);
92 mutex_lock (&ms->mutex);
93 if (ms->len == ms->capacity)
95 struct mbuf_item rm;
96 ASSERT (mbuf_extract_item (ms, &rm, false));
97 mbuf_free_buf (rm.buffer);
98 msg (D_MULTI_DROPPED, "MBUF: mbuf packet dropped");
101 ASSERT (ms->len < ms->capacity);
103 ms->array[MBUF_INDEX(ms->head, ms->len, ms->capacity)] = *item;
104 if (++ms->len > ms->max_queued)
105 ms->max_queued = ms->len;
106 ++item->buffer->refcount;
107 mutex_unlock (&ms->mutex);
110 bool
111 mbuf_extract_item (struct mbuf_set *ms, struct mbuf_item *item, const bool lock)
113 bool ret = false;
114 if (ms)
116 if (lock)
117 mutex_lock (&ms->mutex);
118 while (ms->len)
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 */
125 ret = true;
126 break;
129 if (lock)
130 mutex_unlock (&ms->mutex);
132 return ret;
135 struct multi_instance *
136 mbuf_peek_dowork (struct mbuf_set *ms)
138 struct multi_instance *ret = NULL;
139 if (ms)
141 int i;
142 mutex_lock (&ms->mutex);
143 for (i = 0; i < (int) ms->len; ++i)
145 struct mbuf_item *item = &ms->array[MBUF_INDEX(ms->head, i, ms->capacity)];
146 if (item->instance)
148 ret = item->instance;
149 break;
152 mutex_unlock (&ms->mutex);
154 return ret;
157 void
158 mbuf_dereference_instance (struct mbuf_set *ms, struct multi_instance *mi)
160 if (ms)
162 int i;
163 mutex_lock (&ms->mutex);
164 for (i = 0; i < (int) ms->len; ++i)
166 struct mbuf_item *item = &ms->array[MBUF_INDEX(ms->head, i, ms->capacity)];
167 if (item->instance == mi)
169 mbuf_free_buf (item->buffer);
170 item->buffer = NULL;
171 item->instance = NULL;
172 msg (D_MBUF, "MBUF: dereferenced queued packet");
175 mutex_unlock (&ms->mutex);
179 #else
180 static void dummy(void) {}
181 #endif /* P2MP */