diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2012-05-24 08:43:24 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2012-05-24 08:43:24 +0000 |
commit | 6743123dcc6b37dabf2759f384a7f6ad08a08bec (patch) | |
tree | be57184bdbf1224c5875616e2e015d129620edc5 | |
parent | 7f0c6d43d3534506c7d76c4701c9b98ef47ebe40 (diff) | |
download | gnunet-6743123dcc6b37dabf2759f384a7f6ad08a08bec.tar.gz gnunet-6743123dcc6b37dabf2759f384a7f6ad08a08bec.zip |
- fix for 0002371, 0002343: mst freed in callback
-rw-r--r-- | src/include/gnunet_server_lib.h | 6 | ||||
-rw-r--r-- | src/util/Makefile.am | 6 | ||||
-rw-r--r-- | src/util/server.c | 8 | ||||
-rw-r--r-- | src/util/server_mst.c | 6 | ||||
-rw-r--r-- | src/util/test_server_mst_interrupt.c | 81 |
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 | */ |
614 | typedef void (*GNUNET_SERVER_MessageTokenizerCallback) (void *cls, void *client, | 618 | typedef 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 = \ | |||
402 | test_scheduler_delay_LDADD = \ | 403 | test_scheduler_delay_LDADD = \ |
403 | $(top_builddir)/src/util/libgnunetutil.la | 404 | $(top_builddir)/src/util/libgnunetutil.la |
404 | 405 | ||
406 | test_server_mst_interrupt_SOURCES = \ | ||
407 | test_server_mst_interrupt.c | ||
408 | test_server_mst_interrupt_LDADD = \ | ||
409 | $(top_builddir)/src/util/libgnunetutil.la | ||
410 | |||
405 | test_server_SOURCES = \ | 411 | test_server_SOURCES = \ |
406 | test_server.c | 412 | test_server.c |
407 | test_server_LDADD = \ | 413 | test_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 | */ |
1108 | static void | 1110 | static int |
1109 | client_message_tokenizer_callback (void *cls, void *client, | 1111 | client_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 | |||
32 | static struct GNUNET_SERVER_MessageStreamTokenizer * mst; | ||
33 | static int ret; | ||
34 | |||
35 | /* Callback destroying mst with data in buffer */ | ||
36 | static int | ||
37 | mst_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 | */ | ||
48 | static int | ||
49 | check () | ||
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 | |||
70 | int | ||
71 | main (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 */ | ||