aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2012-05-24 08:43:24 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2012-05-24 08:43:24 +0000
commit6743123dcc6b37dabf2759f384a7f6ad08a08bec (patch)
treebe57184bdbf1224c5875616e2e015d129620edc5
parent7f0c6d43d3534506c7d76c4701c9b98ef47ebe40 (diff)
downloadgnunet-6743123dcc6b37dabf2759f384a7f6ad08a08bec.tar.gz
gnunet-6743123dcc6b37dabf2759f384a7f6ad08a08bec.zip
- fix for 0002371, 0002343: mst freed in callback
-rw-r--r--src/include/gnunet_server_lib.h6
-rw-r--r--src/util/Makefile.am6
-rw-r--r--src/util/server.c8
-rw-r--r--src/util/server_mst.c6
-rw-r--r--src/util/test_server_mst_interrupt.c81
5 files changed, 103 insertions, 4 deletions
diff --git a/src/include/gnunet_server_lib.h b/src/include/gnunet_server_lib.h
index c0a0a5cba..73fe8000e 100644
--- a/src/include/gnunet_server_lib.h
+++ b/src/include/gnunet_server_lib.h
@@ -607,11 +607,15 @@ struct GNUNET_SERVER_MessageStreamTokenizer;
607 * Functions with this signature are called whenever a 607 * Functions with this signature are called whenever a
608 * complete message is received by the tokenizer. 608 * complete message is received by the tokenizer.
609 * 609 *
610 * Do not call GNUNET_SERVER_mst_destroy in callback
611 *
610 * @param cls closure 612 * @param cls closure
611 * @param client identification of the client 613 * @param client identification of the client
612 * @param message the actual message 614 * @param message the actual message
615 *
616 * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing
613 */ 617 */
614typedef void (*GNUNET_SERVER_MessageTokenizerCallback) (void *cls, void *client, 618typedef int (*GNUNET_SERVER_MessageTokenizerCallback) (void *cls, void *client,
615 const struct 619 const struct
616 GNUNET_MessageHeader * 620 GNUNET_MessageHeader *
617 message); 621 message);
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index eb0495998..9e670d950 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -195,6 +195,7 @@ check_PROGRAMS = \
195 test_resolver_api \ 195 test_resolver_api \
196 test_scheduler \ 196 test_scheduler \
197 test_scheduler_delay \ 197 test_scheduler_delay \
198 test_server_mst_interrupt \
198 test_server \ 199 test_server \
199 test_server_disconnect \ 200 test_server_disconnect \
200 test_server_with_client \ 201 test_server_with_client \
@@ -402,6 +403,11 @@ test_scheduler_delay_SOURCES = \
402test_scheduler_delay_LDADD = \ 403test_scheduler_delay_LDADD = \
403 $(top_builddir)/src/util/libgnunetutil.la 404 $(top_builddir)/src/util/libgnunetutil.la
404 405
406test_server_mst_interrupt_SOURCES = \
407 test_server_mst_interrupt.c
408test_server_mst_interrupt_LDADD = \
409 $(top_builddir)/src/util/libgnunetutil.la
410
405test_server_SOURCES = \ 411test_server_SOURCES = \
406 test_server.c 412 test_server.c
407test_server_LDADD = \ 413test_server_LDADD = \
diff --git a/src/util/server.c b/src/util/server.c
index 69d64a702..3f1edf3ea 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -1104,8 +1104,10 @@ restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1104 * @param cls closure (struct GNUNET_SERVER_Handle) 1104 * @param cls closure (struct GNUNET_SERVER_Handle)
1105 * @param client identification of the client (struct GNUNET_SERVER_Client*) 1105 * @param client identification of the client (struct GNUNET_SERVER_Client*)
1106 * @param message the actual message 1106 * @param message the actual message
1107 *
1108 * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing
1107 */ 1109 */
1108static void 1110static int
1109client_message_tokenizer_callback (void *cls, void *client, 1111client_message_tokenizer_callback (void *cls, void *client,
1110 const struct GNUNET_MessageHeader *message) 1112 const struct GNUNET_MessageHeader *message)
1111{ 1113{
@@ -1120,7 +1122,11 @@ client_message_tokenizer_callback (void *cls, void *client,
1120 ret = GNUNET_SERVER_inject (server, sender, message); 1122 ret = GNUNET_SERVER_inject (server, sender, message);
1121 sender->in_process_client_buffer = GNUNET_NO; 1123 sender->in_process_client_buffer = GNUNET_NO;
1122 if ( (GNUNET_OK != ret) || (GNUNET_YES == sender->shutdown_now) ) 1124 if ( (GNUNET_OK != ret) || (GNUNET_YES == sender->shutdown_now) )
1125 {
1123 GNUNET_SERVER_client_disconnect (sender); 1126 GNUNET_SERVER_client_disconnect (sender);
1127 return GNUNET_SYSERR;
1128 }
1129 return GNUNET_OK;
1124} 1130}
1125 1131
1126 1132
diff --git a/src/util/server_mst.c b/src/util/server_mst.c
index 1523de91a..9dd04f0fa 100644
--- a/src/util/server_mst.c
+++ b/src/util/server_mst.c
@@ -221,7 +221,8 @@ do_align:
221 if (one_shot == GNUNET_YES) 221 if (one_shot == GNUNET_YES)
222 one_shot = GNUNET_SYSERR; 222 one_shot = GNUNET_SYSERR;
223 mst->off += want; 223 mst->off += want;
224 mst->cb (mst->cb_cls, client_identity, hdr); 224 if (GNUNET_SYSERR == mst->cb (mst->cb_cls, client_identity, hdr))
225 return GNUNET_SYSERR;
225 if (mst->off == mst->pos) 226 if (mst->off == mst->pos)
226 { 227 {
227 /* reset to beginning of buffer, it's free right now! */ 228 /* reset to beginning of buffer, it's free right now! */
@@ -261,7 +262,8 @@ do_align:
261 } 262 }
262 if (one_shot == GNUNET_YES) 263 if (one_shot == GNUNET_YES)
263 one_shot = GNUNET_SYSERR; 264 one_shot = GNUNET_SYSERR;
264 mst->cb (mst->cb_cls, client_identity, hdr); 265 if (GNUNET_SYSERR == mst->cb (mst->cb_cls, client_identity, hdr))
266 return GNUNET_SYSERR;
265 buf += want; 267 buf += want;
266 size -= want; 268 size -= want;
267 } 269 }
diff --git a/src/util/test_server_mst_interrupt.c b/src/util/test_server_mst_interrupt.c
new file mode 100644
index 000000000..fd34bd00a
--- /dev/null
+++ b/src/util/test_server_mst_interrupt.c
@@ -0,0 +1,81 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20/**
21 * @file util/test_server_mst_interrupt.c
22 * @brief test for interrupt message processing in server_mst.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_protocols.h"
27#include "gnunet_client_lib.h"
28#include "gnunet_scheduler_lib.h"
29#include "gnunet_server_lib.h"
30#include "gnunet_time_lib.h"
31
32static struct GNUNET_SERVER_MessageStreamTokenizer * mst;
33static int ret;
34
35/* Callback destroying mst with data in buffer */
36static int
37mst_cb (void *cls, void *client,
38 const struct GNUNET_MessageHeader * message)
39{
40 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MST gave me message, destroying\n");
41 GNUNET_SERVER_mst_destroy (mst);
42 return GNUNET_SYSERR;
43}
44
45/**
46 * Main method
47 */
48static int
49check ()
50{
51
52 struct GNUNET_PeerIdentity id;
53 struct GNUNET_MessageHeader msg[2];
54
55 /* Prepare */
56 memset (&id, sizeof (id), '\0');
57 msg[0].size = htons (sizeof (msg));
58 msg[0].type = htons (sizeof (GNUNET_MESSAGE_TYPE_DUMMY));
59
60 mst = GNUNET_SERVER_mst_create(mst_cb, NULL);
61
62 GNUNET_SERVER_mst_receive(mst, &id, (const char *) &msg, 2 * sizeof (msg), GNUNET_NO, GNUNET_NO);
63
64 /* If we reach this line, it did not crash */
65 ret = 0;
66
67 return ret;
68}
69
70int
71main (int argc, char *argv[])
72{
73 ret = 1;
74
75 GNUNET_log_setup ("test_server", "WARNING", NULL);
76 check ();
77
78 return ret;
79}
80
81/* end of test_server_mst_interrupt.c */