6fbf66fa |
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single TCP/UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
* |
58716979 |
* Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> |
6fbf66fa |
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* |
caa54ac3 |
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
6fbf66fa |
*/
|
c110b289 |
#ifdef HAVE_CONFIG_H
#include "config.h"
#elif defined(_MSC_VER)
#include "config-msvc.h"
#endif
|
6fbf66fa |
#include "syshead.h"
#if P2MP
#include "buffer.h"
#include "error.h" |
9fc0e963 |
#include "integer.h" |
6fbf66fa |
#include "misc.h"
#include "mbuf.h"
#include "memdbg.h"
struct mbuf_set * |
81d882d5 |
mbuf_init(unsigned int size) |
6fbf66fa |
{ |
81d882d5 |
struct mbuf_set *ret;
ALLOC_OBJ_CLEAR(ret, struct mbuf_set);
ret->capacity = adjust_power_of_2(size);
ALLOC_ARRAY(ret->array, struct mbuf_item, ret->capacity);
return ret; |
6fbf66fa |
}
void |
81d882d5 |
mbuf_free(struct mbuf_set *ms) |
6fbf66fa |
{ |
81d882d5 |
if (ms) |
6fbf66fa |
{ |
81d882d5 |
int i;
for (i = 0; i < (int) ms->len; ++i)
{
struct mbuf_item *item = &ms->array[MBUF_INDEX(ms->head, i, ms->capacity)];
mbuf_free_buf(item->buffer);
}
free(ms->array);
free(ms); |
6fbf66fa |
}
}
struct mbuf_buffer * |
81d882d5 |
mbuf_alloc_buf(const struct buffer *buf) |
6fbf66fa |
{ |
81d882d5 |
struct mbuf_buffer *ret;
ALLOC_OBJ(ret, struct mbuf_buffer);
ret->buf = clone_buf(buf);
ret->refcount = 1;
ret->flags = 0;
return ret; |
6fbf66fa |
}
void |
81d882d5 |
mbuf_free_buf(struct mbuf_buffer *mb) |
6fbf66fa |
{ |
81d882d5 |
if (mb) |
6fbf66fa |
{ |
81d882d5 |
if (--mb->refcount <= 0)
{
free_buf(&mb->buf);
free(mb);
} |
6fbf66fa |
}
}
void |
81d882d5 |
mbuf_add_item(struct mbuf_set *ms, const struct mbuf_item *item) |
6fbf66fa |
{ |
81d882d5 |
ASSERT(ms);
if (ms->len == ms->capacity) |
6fbf66fa |
{ |
81d882d5 |
struct mbuf_item rm;
ASSERT(mbuf_extract_item(ms, &rm));
mbuf_free_buf(rm.buffer);
msg(D_MULTI_DROPPED, "MBUF: mbuf packet dropped"); |
6fbf66fa |
}
|
81d882d5 |
ASSERT(ms->len < ms->capacity); |
6fbf66fa |
|
81d882d5 |
ms->array[MBUF_INDEX(ms->head, ms->len, ms->capacity)] = *item;
if (++ms->len > ms->max_queued)
{
ms->max_queued = ms->len;
}
++item->buffer->refcount; |
6fbf66fa |
}
bool |
81d882d5 |
mbuf_extract_item(struct mbuf_set *ms, struct mbuf_item *item) |
6fbf66fa |
{ |
81d882d5 |
bool ret = false;
if (ms) |
6fbf66fa |
{ |
81d882d5 |
while (ms->len)
{
*item = ms->array[ms->head];
ms->head = MBUF_INDEX(ms->head, 1, ms->capacity);
--ms->len;
if (item->instance) /* ignore dereferenced instances */
{
ret = true;
break;
}
} |
6fbf66fa |
} |
81d882d5 |
return ret; |
6fbf66fa |
}
struct multi_instance * |
81d882d5 |
mbuf_peek_dowork(struct mbuf_set *ms) |
6fbf66fa |
{ |
81d882d5 |
struct multi_instance *ret = NULL;
if (ms) |
6fbf66fa |
{ |
81d882d5 |
int i;
for (i = 0; i < (int) ms->len; ++i)
{
struct mbuf_item *item = &ms->array[MBUF_INDEX(ms->head, i, ms->capacity)];
if (item->instance)
{
ret = item->instance;
break;
}
} |
6fbf66fa |
} |
81d882d5 |
return ret; |
6fbf66fa |
}
void |
81d882d5 |
mbuf_dereference_instance(struct mbuf_set *ms, struct multi_instance *mi) |
6fbf66fa |
{ |
81d882d5 |
if (ms) |
6fbf66fa |
{ |
81d882d5 |
int i;
for (i = 0; i < (int) ms->len; ++i)
{
struct mbuf_item *item = &ms->array[MBUF_INDEX(ms->head, i, ms->capacity)];
if (item->instance == mi)
{
mbuf_free_buf(item->buffer);
item->buffer = NULL;
item->instance = NULL;
msg(D_MBUF, "MBUF: dereferenced queued packet");
}
} |
6fbf66fa |
}
}
|
81d882d5 |
#else /* if P2MP */
static void |
4cd4899e |
dummy(void)
{ |
81d882d5 |
} |
6fbf66fa |
#endif /* P2MP */ |