X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fserver_mst.c;h=0a686a079e6323e44ef949a774fd4c6ef991c21c;hb=60de5f48cbfc3868570284e91415ca7e06c390e1;hp=0a6eee49cd2a98548f0e8ebb6f3982aeb432f55d;hpb=68401426269d202ae48d4942842f365198886c57;p=oweals%2Fgnunet.git diff --git a/src/util/server_mst.c b/src/util/server_mst.c index 0a6eee49c..0a686a079 100644 --- a/src/util/server_mst.c +++ b/src/util/server_mst.c @@ -1,10 +1,10 @@ /* This file is part of GNUnet. - (C) 2010 Christian Grothoff (and other contributing authors) + Copyright (C) 2010 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 2, or (at your + by the Free Software Foundation; either version 3, or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but @@ -14,8 +14,8 @@ You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /** @@ -25,13 +25,8 @@ */ #include "platform.h" -#include "gnunet_common.h" -#include "gnunet_connection_lib.h" -#include "gnunet_scheduler_lib.h" -#include "gnunet_server_lib.h" -#include "gnunet_time_lib.h" +#include "gnunet_util_lib.h" -#define DEBUG_SERVER_MST GNUNET_EXTRA_LOGGING #if HAVE_UNALIGNED_64_ACCESS #define ALIGN_FACTOR 4 @@ -86,7 +81,7 @@ struct GNUNET_SERVER_MessageStreamTokenizer * Create a message stream tokenizer. * * @param cb function to call on completed messages - * @param cb_cls closure for cb + * @param cb_cls closure for @a cb * @return handle to tokenizer */ struct GNUNET_SERVER_MessageStreamTokenizer * @@ -95,7 +90,7 @@ GNUNET_SERVER_mst_create (GNUNET_SERVER_MessageTokenizerCallback cb, { struct GNUNET_SERVER_MessageStreamTokenizer *ret; - ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_MessageStreamTokenizer)); + ret = GNUNET_new (struct GNUNET_SERVER_MessageStreamTokenizer); ret->hdr = GNUNET_malloc (GNUNET_SERVER_MIN_BUFFER_SIZE); ret->curr_buf = GNUNET_SERVER_MIN_BUFFER_SIZE; ret->cb = cb; @@ -111,17 +106,18 @@ GNUNET_SERVER_mst_create (GNUNET_SERVER_MessageTokenizerCallback cb, * @param mst tokenizer to use * @param client_identity ID of client for which this is a buffer * @param buf input data to add - * @param size number of bytes in buf + * @param size number of bytes in @a buf * @param purge should any excess bytes in the buffer be discarded * (i.e. for packet-based services like UDP) * @param one_shot only call callback once, keep rest of message in buffer - * @return GNUNET_OK if we are done processing (need more data) - * GNUNET_NO if one_shot was set and we have another message ready - * GNUNET_SYSERR if the data stream is corrupt + * @return #GNUNET_OK if we are done processing (need more data) + * #GNUNET_NO if @a one_shot was set and we have another message ready + * #GNUNET_SYSERR if the data stream is corrupt */ int GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst, - void *client_identity, const char *buf, size_t size, + void *client_identity, + const char *buf, size_t size, int purge, int one_shot) { const struct GNUNET_MessageHeader *hdr; @@ -132,16 +128,17 @@ GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst, unsigned long offset; int ret; -#if DEBUG_SERVER_MST + GNUNET_assert (mst->off <= mst->pos); + GNUNET_assert (mst->pos <= mst->curr_buf); LOG (GNUNET_ERROR_TYPE_DEBUG, "Server-mst receives %u bytes with %u bytes already in private buffer\n", (unsigned int) size, (unsigned int) (mst->pos - mst->off)); -#endif ret = GNUNET_OK; ibuf = (char *) mst->hdr; while (mst->pos > 0) { do_align: + GNUNET_assert (mst->pos >= mst->off); if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) || (0 != (mst->off % ALIGN_FACTOR))) { @@ -176,15 +173,18 @@ do_align: GNUNET_break_op (0); return GNUNET_SYSERR; } - if (mst->curr_buf - mst->off < want) + if ( (mst->curr_buf - mst->off < want) && + (mst->off > 0) ) { - /* need more space */ + /* can get more space by moving */ mst->pos -= mst->off; memmove (ibuf, &ibuf[mst->off], mst->pos); mst->off = 0; } - if (want > mst->curr_buf) + if (mst->curr_buf < want) { + /* need to get more space by growing buffer */ + GNUNET_assert (0 == mst->off); mst->hdr = GNUNET_realloc (mst->hdr, want); ibuf = (char *) mst->hdr; mst->curr_buf = want; @@ -193,6 +193,7 @@ do_align: if (mst->pos - mst->off < want) { delta = GNUNET_MIN (want - (mst->pos - mst->off), size); + GNUNET_assert (mst->pos + delta <= mst->curr_buf); memcpy (&ibuf[mst->pos], buf, delta); mst->pos += delta; buf += delta; @@ -217,7 +218,8 @@ do_align: if (one_shot == GNUNET_YES) one_shot = GNUNET_SYSERR; mst->off += want; - mst->cb (mst->cb_cls, client_identity, hdr); + if (GNUNET_SYSERR == mst->cb (mst->cb_cls, client_identity, hdr)) + return GNUNET_SYSERR; if (mst->off == mst->pos) { /* reset to beginning of buffer, it's free right now! */ @@ -225,17 +227,16 @@ do_align: mst->pos = 0; } } + GNUNET_assert (0 == mst->pos); while (size > 0) { -#if DEBUG_SERVER_MST LOG (GNUNET_ERROR_TYPE_DEBUG, "Server-mst has %u bytes left in inbound buffer\n", (unsigned int) size); -#endif if (size < sizeof (struct GNUNET_MessageHeader)) break; offset = (unsigned long) buf; - need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO; + need_align = (0 != (offset % ALIGN_FACTOR)) ? GNUNET_YES : GNUNET_NO; if (GNUNET_NO == need_align) { /* can try to do zero-copy and process directly from original buffer */ @@ -248,7 +249,7 @@ do_align: return GNUNET_SYSERR; } if (size < want) - break; /* or not, buffer incomplete, so copy to private buffer... */ + break; /* or not: buffer incomplete, so copy to private buffer... */ if (one_shot == GNUNET_SYSERR) { /* cannot call callback again, but return value saying that @@ -258,7 +259,8 @@ do_align: } if (one_shot == GNUNET_YES) one_shot = GNUNET_SYSERR; - mst->cb (mst->cb_cls, client_identity, hdr); + if (GNUNET_SYSERR == mst->cb (mst->cb_cls, client_identity, hdr)) + return GNUNET_SYSERR; buf += want; size -= want; } @@ -278,17 +280,18 @@ copy: ibuf = (char *) mst->hdr; mst->curr_buf = size + mst->pos; } - GNUNET_assert (mst->pos + size <= mst->curr_buf); + GNUNET_assert (size + mst->pos <= mst->curr_buf); memcpy (&ibuf[mst->pos], buf, size); mst->pos += size; } if (purge) + { mst->off = 0; -#if DEBUG_SERVER_MST + mst->pos = 0; + } LOG (GNUNET_ERROR_TYPE_DEBUG, "Server-mst leaves %u bytes in private buffer\n", (unsigned int) (mst->pos - mst->off)); -#endif return ret; }