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
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
37 mbuf_init (unsigned int size
)
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
);
48 mbuf_free (struct mbuf_set
*ms
)
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
);
59 mutex_destroy (&ms
->mutex
);
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
);
76 mbuf_free_buf (struct mbuf_buffer
*mb
)
80 if (--mb
->refcount
<= 0)
89 mbuf_add_item (struct mbuf_set
*ms
, const struct mbuf_item
*item
)
92 mutex_lock (&ms
->mutex
);
93 if (ms
->len
== ms
->capacity
)
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
);
111 mbuf_extract_item (struct mbuf_set
*ms
, struct mbuf_item
*item
, const bool lock
)
117 mutex_lock (&ms
->mutex
);
120 *item
= ms
->array
[ms
->head
];
121 ms
->head
= MBUF_INDEX(ms
->head
, 1, ms
->capacity
);
123 if (item
->instance
) /* ignore dereferenced instances */
130 mutex_unlock (&ms
->mutex
);
135 struct multi_instance
*
136 mbuf_peek_dowork (struct mbuf_set
*ms
)
138 struct multi_instance
*ret
= NULL
;
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
)];
148 ret
= item
->instance
;
152 mutex_unlock (&ms
->mutex
);
158 mbuf_dereference_instance (struct mbuf_set
*ms
, struct multi_instance
*mi
)
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
);
171 item
->instance
= NULL
;
172 msg (D_MBUF
, "MBUF: dereferenced queued packet");
175 mutex_unlock (&ms
->mutex
);
180 static void dummy(void) {}