diff options
-rw-r--r-- | src/transport/Makefile.am | 3 | ||||
-rw-r--r-- | src/transport/test_transport_api.c | 117 | ||||
-rw-r--r-- | src/transport/transport-testing-send.c | 241 | ||||
-rw-r--r-- | src/transport/transport-testing.c | 223 | ||||
-rw-r--r-- | src/transport/transport-testing.h | 183 |
5 files changed, 613 insertions, 154 deletions
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index 767031e6f..d6c4e3ccf 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am | |||
@@ -153,7 +153,8 @@ libgnunettransporttesting_la_SOURCES = \ | |||
153 | transport-testing.c transport-testing.h \ | 153 | transport-testing.c transport-testing.h \ |
154 | transport-testing-filenames.c \ | 154 | transport-testing-filenames.c \ |
155 | transport-testing-loggers.c \ | 155 | transport-testing-loggers.c \ |
156 | transport-testing-main.c | 156 | transport-testing-main.c \ |
157 | transport-testing-send.c | ||
157 | libgnunettransporttesting_la_LIBADD = \ | 158 | libgnunettransporttesting_la_LIBADD = \ |
158 | libgnunettransport.la \ | 159 | libgnunettransport.la \ |
159 | $(top_builddir)/src/hello/libgnunethello.la \ | 160 | $(top_builddir)/src/hello/libgnunethello.la \ |
diff --git a/src/transport/test_transport_api.c b/src/transport/test_transport_api.c index bc0061363..4da4f2533 100644 --- a/src/transport/test_transport_api.c +++ b/src/transport/test_transport_api.c | |||
@@ -36,31 +36,8 @@ | |||
36 | */ | 36 | */ |
37 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) | 37 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) |
38 | 38 | ||
39 | /** | ||
40 | * How long until we give up on transmitting the message? | ||
41 | */ | ||
42 | #define TIMEOUT_TRANSMIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | ||
43 | |||
44 | #define TEST_MESSAGE_SIZE 2600 | ||
45 | |||
46 | #define TEST_MESSAGE_TYPE 12345 | ||
47 | |||
48 | |||
49 | static struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc; | 39 | static struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc; |
50 | 40 | ||
51 | static struct GNUNET_TRANSPORT_TransmitHandle *th; | ||
52 | |||
53 | |||
54 | static void | ||
55 | custom_shutdown (void *cls) | ||
56 | { | ||
57 | if (NULL != th) | ||
58 | { | ||
59 | GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); | ||
60 | th = NULL; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | 41 | ||
65 | static void | 42 | static void |
66 | notify_receive (void *cls, | 43 | notify_receive (void *cls, |
@@ -81,8 +58,8 @@ notify_receive (void *cls, | |||
81 | GNUNET_free (ps); | 58 | GNUNET_free (ps); |
82 | } | 59 | } |
83 | 60 | ||
84 | if ((TEST_MESSAGE_TYPE == ntohs (message->type)) && | 61 | if ((GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE == ntohs (message->type)) && |
85 | (TEST_MESSAGE_SIZE == ntohs (message->size))) | 62 | (GNUNET_TRANSPORT_TESTING_LARGE_MESSAGE_SIZE == ntohs (message->size))) |
86 | { | 63 | { |
87 | ccc->global_ret = GNUNET_OK; | 64 | ccc->global_ret = GNUNET_OK; |
88 | GNUNET_SCHEDULER_shutdown (); | 65 | GNUNET_SCHEDULER_shutdown (); |
@@ -96,90 +73,6 @@ notify_receive (void *cls, | |||
96 | } | 73 | } |
97 | 74 | ||
98 | 75 | ||
99 | static size_t | ||
100 | notify_ready (void *cls, | ||
101 | size_t size, | ||
102 | void *buf) | ||
103 | { | ||
104 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls; | ||
105 | struct GNUNET_MessageHeader *hdr; | ||
106 | |||
107 | th = NULL; | ||
108 | if (buf == NULL) | ||
109 | { | ||
110 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
111 | "Timeout occurred while waiting for transmit_ready\n"); | ||
112 | GNUNET_SCHEDULER_shutdown (); | ||
113 | ccc->global_ret = 42; | ||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | GNUNET_assert (size >= TEST_MESSAGE_SIZE); | ||
118 | if (NULL != buf) | ||
119 | { | ||
120 | memset (buf, '\0', TEST_MESSAGE_SIZE); | ||
121 | hdr = buf; | ||
122 | hdr->size = htons (TEST_MESSAGE_SIZE); | ||
123 | hdr->type = htons (TEST_MESSAGE_TYPE); | ||
124 | } | ||
125 | |||
126 | { | ||
127 | char *ps = GNUNET_strdup (GNUNET_i2s (&ccc->p[1]->id)); | ||
128 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
129 | "Peer %u (`%4s') sending message with type %u and size %u bytes to peer %u (`%4s')\n", | ||
130 | ccc->p[1]->no, | ||
131 | ps, | ||
132 | ntohs (hdr->type), | ||
133 | ntohs (hdr->size), | ||
134 | p->no, | ||
135 | GNUNET_i2s (&p->id)); | ||
136 | GNUNET_free (ps); | ||
137 | } | ||
138 | return TEST_MESSAGE_SIZE; | ||
139 | } | ||
140 | |||
141 | |||
142 | static void | ||
143 | sendtask (void *cls) | ||
144 | { | ||
145 | { | ||
146 | char *receiver_s = GNUNET_strdup (GNUNET_i2s (&ccc->p[0]->id)); | ||
147 | |||
148 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
149 | "Sending message from peer %u (`%s') -> peer %u (`%s') !\n", | ||
150 | ccc->p[1]->no, | ||
151 | GNUNET_i2s (&ccc->p[1]->id), | ||
152 | ccc->p[0]->no, | ||
153 | receiver_s); | ||
154 | GNUNET_free (receiver_s); | ||
155 | } | ||
156 | ccc->global_ret = GNUNET_SYSERR; | ||
157 | th = GNUNET_TRANSPORT_notify_transmit_ready (ccc->p[1]->th, | ||
158 | &ccc->p[0]->id, | ||
159 | TEST_MESSAGE_SIZE, | ||
160 | TIMEOUT_TRANSMIT, | ||
161 | ¬ify_ready, | ||
162 | ccc->p[0]); | ||
163 | GNUNET_assert (NULL != th); | ||
164 | } | ||
165 | |||
166 | |||
167 | static void | ||
168 | notify_disconnect (void *cls, | ||
169 | struct GNUNET_TRANSPORT_TESTING_PeerContext *me, | ||
170 | const struct GNUNET_PeerIdentity *other) | ||
171 | { | ||
172 | GNUNET_TRANSPORT_TESTING_log_disconnect (cls, | ||
173 | me, | ||
174 | other); | ||
175 | if (NULL != th) | ||
176 | { | ||
177 | GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); | ||
178 | th = NULL; | ||
179 | } | ||
180 | } | ||
181 | |||
182 | |||
183 | /** | 76 | /** |
184 | * Runs the test. | 77 | * Runs the test. |
185 | * | 78 | * |
@@ -192,12 +85,12 @@ test (char *argv[], | |||
192 | int bi_directional) | 85 | int bi_directional) |
193 | { | 86 | { |
194 | struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext my_ccc = { | 87 | struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext my_ccc = { |
195 | .connect_continuation = &sendtask, | 88 | .connect_continuation = &GNUNET_TRANSPORT_TESTING_large_send, |
89 | .connect_continuation_cls = &my_ccc, | ||
196 | .config_file = "test_transport_api_data.conf", | 90 | .config_file = "test_transport_api_data.conf", |
197 | .rec = ¬ify_receive, | 91 | .rec = ¬ify_receive, |
198 | .nc = &GNUNET_TRANSPORT_TESTING_log_connect, | 92 | .nc = &GNUNET_TRANSPORT_TESTING_log_connect, |
199 | .nd = ¬ify_disconnect, | 93 | .nd = &GNUNET_TRANSPORT_TESTING_log_disconnect, |
200 | .shutdown_task = &custom_shutdown, | ||
201 | .timeout = TIMEOUT, | 94 | .timeout = TIMEOUT, |
202 | .bi_directional = bi_directional | 95 | .bi_directional = bi_directional |
203 | }; | 96 | }; |
diff --git a/src/transport/transport-testing-send.c b/src/transport/transport-testing-send.c new file mode 100644 index 000000000..20d1f2fbc --- /dev/null +++ b/src/transport/transport-testing-send.c | |||
@@ -0,0 +1,241 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2016 GNUnet e.V. | ||
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., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file transport-testing-send.c | ||
22 | * @brief convenience transmission function for tests | ||
23 | * @author Christian Grothoff | ||
24 | */ | ||
25 | #include "transport-testing.h" | ||
26 | |||
27 | /** | ||
28 | * Acceptable transmission delay. | ||
29 | */ | ||
30 | #define TIMEOUT_TRANSMIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | ||
31 | |||
32 | |||
33 | static size_t | ||
34 | notify_ready (void *cls, | ||
35 | size_t size, | ||
36 | void *buf) | ||
37 | { | ||
38 | struct TRANSPORT_TESTING_SendJob *sj = cls; | ||
39 | struct GNUNET_TRANSPORT_TESTING_PeerContext *sender = sj->sender; | ||
40 | struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver = sj->receiver; | ||
41 | struct GNUNET_TRANSPORT_TESTING_Handle *tth = sender->tth; | ||
42 | uint16_t msize = sj->msize; | ||
43 | struct GNUNET_TRANSPORT_TESTING_TestMessage *test; | ||
44 | |||
45 | sj->th = NULL; | ||
46 | GNUNET_CONTAINER_DLL_remove (tth->sj_head, | ||
47 | tth->sj_tail, | ||
48 | sj); | ||
49 | if (NULL == buf) | ||
50 | { | ||
51 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
52 | "Timeout occurred while waiting for transmit_ready\n"); | ||
53 | GNUNET_SCHEDULER_shutdown (); | ||
54 | GNUNET_free (sj); | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | GNUNET_assert (size >= msize); | ||
59 | if (NULL != buf) | ||
60 | { | ||
61 | memset (buf, '\0', msize); | ||
62 | test = buf; | ||
63 | test->header.size = htons (msize); | ||
64 | test->header.type = htons (sj->mtype); | ||
65 | test->num = htonl (sj->num); | ||
66 | } | ||
67 | |||
68 | { | ||
69 | char *ps = GNUNET_strdup (GNUNET_i2s (&sender->id)); | ||
70 | |||
71 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
72 | "Sending message %u from %u (%s) with type %u and size %u bytes to peer %u (%s)\n", | ||
73 | (unsigned int) sj->num, | ||
74 | sender->no, | ||
75 | ps, | ||
76 | sj->mtype, | ||
77 | msize, | ||
78 | receiver->no, | ||
79 | GNUNET_i2s (&receiver->id)); | ||
80 | GNUNET_free (ps); | ||
81 | } | ||
82 | GNUNET_free (sj); | ||
83 | return msize; | ||
84 | } | ||
85 | |||
86 | |||
87 | /** | ||
88 | * Return @a cx in @a cls. | ||
89 | */ | ||
90 | static void | ||
91 | find_cr (void *cls, | ||
92 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cx) | ||
93 | { | ||
94 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest **cr = cls; | ||
95 | |||
96 | *cr = cx; | ||
97 | } | ||
98 | |||
99 | |||
100 | /** | ||
101 | * Send a test message of type @a mtype and size @a msize from | ||
102 | * peer @a sender to peer @a receiver. The peers should be | ||
103 | * connected when this function is called. | ||
104 | * | ||
105 | * @param sender the sending peer | ||
106 | * @param receiver the receiving peer | ||
107 | * @param mtype message type to use | ||
108 | * @param msize size of the message, at least `sizeof (struct GNUNET_TRANSPORT_TESTING_TestMessage)` | ||
109 | * @param num unique message number | ||
110 | * @return #GNUNET_OK if message was queued, | ||
111 | * #GNUNET_NO if peers are not connected | ||
112 | * #GNUNET_SYSERR if @a msize is illegal | ||
113 | */ | ||
114 | int | ||
115 | GNUNET_TRANSPORT_TESTING_send (struct GNUNET_TRANSPORT_TESTING_PeerContext *sender, | ||
116 | struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver, | ||
117 | uint16_t mtype, | ||
118 | uint16_t msize, | ||
119 | uint32_t num) | ||
120 | { | ||
121 | struct GNUNET_TRANSPORT_TESTING_Handle *tth = sender->tth; | ||
122 | struct TRANSPORT_TESTING_SendJob *sj; | ||
123 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cr; | ||
124 | |||
125 | if (msize < sizeof (struct GNUNET_TRANSPORT_TESTING_TestMessage)) | ||
126 | { | ||
127 | GNUNET_break (0); | ||
128 | return GNUNET_SYSERR; | ||
129 | } | ||
130 | cr = NULL; | ||
131 | GNUNET_TRANSPORT_TESTING_find_connecting_context (sender, | ||
132 | receiver, | ||
133 | &find_cr, | ||
134 | &cr); | ||
135 | if (NULL == cr) | ||
136 | GNUNET_TRANSPORT_TESTING_find_connecting_context (receiver, | ||
137 | sender, | ||
138 | &find_cr, | ||
139 | &cr); | ||
140 | if ( (NULL == cr) || | ||
141 | (GNUNET_YES != cr->connected) ) | ||
142 | { | ||
143 | GNUNET_break (0); | ||
144 | return GNUNET_NO; | ||
145 | } | ||
146 | sj = GNUNET_new (struct TRANSPORT_TESTING_SendJob); | ||
147 | sj->num = num; | ||
148 | sj->sender = sender; | ||
149 | sj->receiver = receiver; | ||
150 | sj->mtype = mtype; | ||
151 | sj->msize = msize; | ||
152 | GNUNET_CONTAINER_DLL_insert (tth->sj_head, | ||
153 | tth->sj_tail, | ||
154 | sj); | ||
155 | { | ||
156 | char *receiver_s = GNUNET_strdup (GNUNET_i2s (&receiver->id)); | ||
157 | |||
158 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
159 | "Sending message from peer %u (`%s') -> peer %u (`%s') !\n", | ||
160 | sender->no, | ||
161 | GNUNET_i2s (&sender->id), | ||
162 | receiver->no, | ||
163 | receiver_s); | ||
164 | GNUNET_free (receiver_s); | ||
165 | } | ||
166 | sj->th = GNUNET_TRANSPORT_notify_transmit_ready (sender->th, | ||
167 | &receiver->id, | ||
168 | msize, | ||
169 | TIMEOUT_TRANSMIT, | ||
170 | ¬ify_ready, | ||
171 | sj); | ||
172 | GNUNET_assert (NULL != sj->th); | ||
173 | return GNUNET_OK; | ||
174 | } | ||
175 | |||
176 | |||
177 | /** | ||
178 | * Task that sends a test message from the | ||
179 | * first peer to the second peer. | ||
180 | * | ||
181 | * @param ccc context which should contain at least two peers, the | ||
182 | * first two of which should be currently connected | ||
183 | */ | ||
184 | static void | ||
185 | do_send (struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc, | ||
186 | uint16_t size) | ||
187 | { | ||
188 | int ret; | ||
189 | |||
190 | ccc->global_ret = GNUNET_SYSERR; | ||
191 | ret = GNUNET_TRANSPORT_TESTING_send (ccc->p[0], | ||
192 | ccc->p[1], | ||
193 | GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE, | ||
194 | size, | ||
195 | ccc->send_num_gen++); | ||
196 | GNUNET_assert (GNUNET_SYSERR != ret); | ||
197 | if (GNUNET_NO == ret) | ||
198 | { | ||
199 | GNUNET_break (0); | ||
200 | ccc->global_ret = GNUNET_SYSERR; | ||
201 | GNUNET_SCHEDULER_shutdown (); | ||
202 | } | ||
203 | } | ||
204 | |||
205 | |||
206 | /** | ||
207 | * Task that sends a minimalistic test message from the | ||
208 | * first peer to the second peer. | ||
209 | * | ||
210 | * @param cls the `struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext` | ||
211 | * which should contain at least two peers, the first two | ||
212 | * of which should be currently connected | ||
213 | */ | ||
214 | void | ||
215 | GNUNET_TRANSPORT_TESTING_simple_send (void *cls) | ||
216 | { | ||
217 | struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = cls; | ||
218 | |||
219 | do_send (ccc, | ||
220 | sizeof (struct GNUNET_MessageHeader)); | ||
221 | } | ||
222 | |||
223 | |||
224 | /** | ||
225 | * Task that sends a large test message from the | ||
226 | * first peer to the second peer. | ||
227 | * | ||
228 | * @param cls the `struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext` | ||
229 | * which should contain at least two peers, the first two | ||
230 | * of which should be currently connected | ||
231 | */ | ||
232 | void | ||
233 | GNUNET_TRANSPORT_TESTING_large_send (void *cls) | ||
234 | { | ||
235 | struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = cls; | ||
236 | |||
237 | do_send (ccc, | ||
238 | 2600); | ||
239 | } | ||
240 | |||
241 | /* end of transport-testing-send.c */ | ||
diff --git a/src/transport/transport-testing.c b/src/transport/transport-testing.c index 322627459..50c297389 100644 --- a/src/transport/transport-testing.c +++ b/src/transport/transport-testing.c | |||
@@ -44,11 +44,21 @@ find_peer_context (struct GNUNET_TRANSPORT_TESTING_Handle *tth, | |||
44 | } | 44 | } |
45 | 45 | ||
46 | 46 | ||
47 | static void | 47 | /** |
48 | notify_connecting_context (struct GNUNET_TRANSPORT_TESTING_Handle *tth, | 48 | * Find any connecting context matching the given pair of peers. |
49 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p1, | 49 | * |
50 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p2) | 50 | * @param p1 first peer |
51 | * @param p2 second peer | ||
52 | * @param cb function to call | ||
53 | * @param cb_cls closure for @a cb | ||
54 | */ | ||
55 | void | ||
56 | GNUNET_TRANSPORT_TESTING_find_connecting_context (struct GNUNET_TRANSPORT_TESTING_PeerContext *p1, | ||
57 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p2, | ||
58 | GNUNET_TRANSPORT_TESTING_ConnectContextCallback cb, | ||
59 | void *cb_cls) | ||
51 | { | 60 | { |
61 | struct GNUNET_TRANSPORT_TESTING_Handle *tth = p1->tth; | ||
52 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc; | 62 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc; |
53 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn; | 63 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn; |
54 | 64 | ||
@@ -56,28 +66,55 @@ notify_connecting_context (struct GNUNET_TRANSPORT_TESTING_Handle *tth, | |||
56 | { | 66 | { |
57 | ccn = cc->next; | 67 | ccn = cc->next; |
58 | if ( (cc->p1 == p1) && | 68 | if ( (cc->p1 == p1) && |
59 | (cc->p2 == p2) ) | 69 | (cc->p2 == p2) ) |
60 | cc->p1_c = GNUNET_YES; | 70 | cb (cb_cls, |
61 | if ( (cc->p1 == p2) && | 71 | cc); |
62 | (cc->p2 == p1) ) | ||
63 | cc->p2_c = GNUNET_YES; | ||
64 | if ( (cc->p1_c == GNUNET_YES) && | ||
65 | (cc->p2_c == GNUNET_YES) ) | ||
66 | { | ||
67 | cc->cb (cc->cb_cls); | ||
68 | GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc); | ||
69 | } | ||
70 | } | 72 | } |
71 | } | 73 | } |
72 | 74 | ||
73 | 75 | ||
74 | static void | 76 | static void |
77 | set_p1c (void *cls, | ||
78 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cx) | ||
79 | { | ||
80 | cx->p1_c = GNUNET_YES; | ||
81 | } | ||
82 | |||
83 | |||
84 | static void | ||
85 | set_p2c (void *cls, | ||
86 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cx) | ||
87 | { | ||
88 | cx->p2_c = GNUNET_YES; | ||
89 | } | ||
90 | |||
91 | |||
92 | static void | ||
93 | clear_p1c (void *cls, | ||
94 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cx) | ||
95 | { | ||
96 | cx->p1_c = GNUNET_NO; | ||
97 | } | ||
98 | |||
99 | |||
100 | static void | ||
101 | clear_p2c (void *cls, | ||
102 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cx) | ||
103 | { | ||
104 | cx->p2_c = GNUNET_NO; | ||
105 | } | ||
106 | |||
107 | |||
108 | static void | ||
75 | notify_connect (void *cls, | 109 | notify_connect (void *cls, |
76 | const struct GNUNET_PeerIdentity *peer) | 110 | const struct GNUNET_PeerIdentity *peer) |
77 | { | 111 | { |
78 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls; | 112 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls; |
113 | struct GNUNET_TRANSPORT_TESTING_Handle *tth = p->tth; | ||
79 | char *p2_s; | 114 | char *p2_s; |
80 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p2; | 115 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p2; |
116 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc; | ||
117 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn; | ||
81 | 118 | ||
82 | p2 = find_peer_context (p->tth, | 119 | p2 = find_peer_context (p->tth, |
83 | peer); | 120 | peer); |
@@ -100,30 +137,83 @@ notify_connect (void *cls, | |||
100 | p->no, | 137 | p->no, |
101 | GNUNET_i2s (&p->id)); | 138 | GNUNET_i2s (&p->id)); |
102 | GNUNET_free (p2_s); | 139 | GNUNET_free (p2_s); |
103 | notify_connecting_context (p->tth, | 140 | /* update flags in connecting contexts */ |
104 | p, | 141 | GNUNET_TRANSPORT_TESTING_find_connecting_context (p, |
105 | p2); | 142 | p2, |
143 | &set_p1c, | ||
144 | NULL); | ||
145 | GNUNET_TRANSPORT_TESTING_find_connecting_context (p2, | ||
146 | p, | ||
147 | &set_p2c, | ||
148 | NULL); | ||
149 | /* update set connected flag for all requests */ | ||
150 | for (cc = tth->cc_head; NULL != cc; cc = cc->next) | ||
151 | { | ||
152 | if (GNUNET_YES == cc->connected) | ||
153 | continue; | ||
154 | if ( (GNUNET_YES == cc->p1_c) && | ||
155 | (GNUNET_YES == cc->p2_c) ) | ||
156 | { | ||
157 | cc->connected = GNUNET_YES; | ||
158 | /* stop trying to connect */ | ||
159 | if (NULL != cc->tct) | ||
160 | { | ||
161 | GNUNET_SCHEDULER_cancel (cc->tct); | ||
162 | cc->tct = NULL; | ||
163 | } | ||
164 | if (NULL != cc->oh) | ||
165 | { | ||
166 | GNUNET_TRANSPORT_offer_hello_cancel (cc->oh); | ||
167 | cc->oh = NULL; | ||
168 | } | ||
169 | if (NULL != cc->ats_sh) | ||
170 | { | ||
171 | GNUNET_ATS_connectivity_suggest_cancel (cc->ats_sh); | ||
172 | cc->ats_sh = NULL; | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | /* then notify application */ | ||
177 | for (cc = tth->cc_head; NULL != cc; cc = ccn) | ||
178 | { | ||
179 | ccn = cc->next; | ||
180 | if ( (GNUNET_YES == cc->connected) && | ||
181 | (NULL != cc->cb) ) | ||
182 | { | ||
183 | cc->cb (cc->cb_cls); | ||
184 | cc->cb = NULL; /* only notify once! */ | ||
185 | } | ||
186 | } | ||
106 | } | 187 | } |
107 | 188 | ||
108 | 189 | ||
190 | /** | ||
191 | * Offer the current HELLO of P2 to P1. | ||
192 | * | ||
193 | * @param cls our `struct GNUNET_TRANSPORT_TESTING_ConnectRequest` | ||
194 | */ | ||
195 | static void | ||
196 | offer_hello (void *cls); | ||
197 | |||
198 | |||
109 | static void | 199 | static void |
110 | notify_disconnect (void *cls, | 200 | notify_disconnect (void *cls, |
111 | const struct GNUNET_PeerIdentity *peer) | 201 | const struct GNUNET_PeerIdentity *peer) |
112 | { | 202 | { |
113 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls; | 203 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls; |
204 | struct GNUNET_TRANSPORT_TESTING_Handle *tth = p->tth; | ||
114 | char *p2_s; | 205 | char *p2_s; |
115 | /* Find PeerContext */ | 206 | /* Find PeerContext */ |
116 | int no = 0; | 207 | int no = 0; |
117 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p2 = NULL; | 208 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p2 = NULL; |
118 | 209 | struct TRANSPORT_TESTING_SendJob *sj; | |
119 | if (NULL != p) | 210 | struct TRANSPORT_TESTING_SendJob *sjn; |
120 | { | 211 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc; |
121 | p2 = find_peer_context (p->tth, | 212 | |
122 | peer); | 213 | p2 = find_peer_context (p->tth, |
123 | no = p->no; | 214 | peer); |
124 | } | 215 | no = p->no; |
125 | 216 | if (NULL != p2) | |
126 | if (p2 != NULL) | ||
127 | GNUNET_asprintf (&p2_s, | 217 | GNUNET_asprintf (&p2_s, |
128 | "%u (`%s')", | 218 | "%u (`%s')", |
129 | p2->no, | 219 | p2->no, |
@@ -138,12 +228,57 @@ notify_disconnect (void *cls, | |||
138 | no, | 228 | no, |
139 | GNUNET_i2s (&p->id)); | 229 | GNUNET_i2s (&p->id)); |
140 | GNUNET_free (p2_s); | 230 | GNUNET_free (p2_s); |
141 | 231 | /* notify about disconnect */ | |
142 | if (NULL == p) | ||
143 | return; | ||
144 | if (NULL != p->nd) | 232 | if (NULL != p->nd) |
145 | p->nd (p->cb_cls, | 233 | p->nd (p->cb_cls, |
146 | peer); | 234 | peer); |
235 | if (NULL == p2) | ||
236 | return; | ||
237 | /* abort all transmissions this disconnected pair is involved in */ | ||
238 | for (sj = tth->sj_head; NULL != sj; sj = sjn) | ||
239 | { | ||
240 | sjn = sj->next; | ||
241 | if ( ( (sj->sender == p2) && | ||
242 | (sj->receiver == p) ) || | ||
243 | ( (sj->receiver == p2) && | ||
244 | (sj->sender == p) ) ) | ||
245 | { | ||
246 | GNUNET_CONTAINER_DLL_remove (tth->sj_head, | ||
247 | tth->sj_tail, | ||
248 | sj); | ||
249 | GNUNET_TRANSPORT_notify_transmit_ready_cancel (sj->th); | ||
250 | GNUNET_free (sj); | ||
251 | } | ||
252 | } | ||
253 | /* update set connected flags for all requests */ | ||
254 | GNUNET_TRANSPORT_TESTING_find_connecting_context (p, | ||
255 | p2, | ||
256 | &clear_p1c, | ||
257 | NULL); | ||
258 | GNUNET_TRANSPORT_TESTING_find_connecting_context (p2, | ||
259 | p, | ||
260 | &clear_p2c, | ||
261 | NULL); | ||
262 | /* resume connectivity requests as necessary */ | ||
263 | for (cc = tth->cc_head; NULL != cc; cc = cc->next) | ||
264 | { | ||
265 | if (GNUNET_NO == cc->connected) | ||
266 | continue; | ||
267 | if ( (GNUNET_YES != cc->p1_c) || | ||
268 | (GNUNET_YES != cc->p2_c) ) | ||
269 | { | ||
270 | cc->connected = GNUNET_NO; | ||
271 | /* start trying to connect */ | ||
272 | if ( (NULL == cc->tct) && | ||
273 | (NULL == cc->oh) ) | ||
274 | cc->tct = GNUNET_SCHEDULER_add_now (&offer_hello, | ||
275 | cc); | ||
276 | if (NULL == cc->ats_sh) | ||
277 | cc->ats_sh = GNUNET_ATS_connectivity_suggest (cc->p1->ats, | ||
278 | &p2->id, | ||
279 | 1); | ||
280 | } | ||
281 | } | ||
147 | } | 282 | } |
148 | 283 | ||
149 | 284 | ||
@@ -352,6 +487,9 @@ GNUNET_TRANSPORT_TESTING_restart_peer (struct GNUNET_TRANSPORT_TESTING_PeerConte | |||
352 | GNUNET_TRANSPORT_TESTING_StartCallback restart_cb, | 487 | GNUNET_TRANSPORT_TESTING_StartCallback restart_cb, |
353 | void *restart_cb_cls) | 488 | void *restart_cb_cls) |
354 | { | 489 | { |
490 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc; | ||
491 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn; | ||
492 | |||
355 | /* shutdown */ | 493 | /* shutdown */ |
356 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 494 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
357 | "Stopping peer %u (`%s')\n", | 495 | "Stopping peer %u (`%s')\n", |
@@ -367,6 +505,13 @@ GNUNET_TRANSPORT_TESTING_restart_peer (struct GNUNET_TRANSPORT_TESTING_PeerConte | |||
367 | GNUNET_TRANSPORT_disconnect (p->th); | 505 | GNUNET_TRANSPORT_disconnect (p->th); |
368 | p->th = NULL; | 506 | p->th = NULL; |
369 | } | 507 | } |
508 | for (cc = p->tth->cc_head; NULL != cc; cc = ccn) | ||
509 | { | ||
510 | ccn = cc->next; | ||
511 | if ( (cc->p1 == p) || | ||
512 | (cc->p2 == p) ) | ||
513 | GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc); | ||
514 | } | ||
370 | if (NULL != p->ats) | 515 | if (NULL != p->ats) |
371 | { | 516 | { |
372 | GNUNET_ATS_connectivity_done (p->ats); | 517 | GNUNET_ATS_connectivity_done (p->ats); |
@@ -427,7 +572,16 @@ void | |||
427 | GNUNET_TRANSPORT_TESTING_stop_peer (struct GNUNET_TRANSPORT_TESTING_PeerContext *p) | 572 | GNUNET_TRANSPORT_TESTING_stop_peer (struct GNUNET_TRANSPORT_TESTING_PeerContext *p) |
428 | { | 573 | { |
429 | struct GNUNET_TRANSPORT_TESTING_Handle *tth = p->tth; | 574 | struct GNUNET_TRANSPORT_TESTING_Handle *tth = p->tth; |
575 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc; | ||
576 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn; | ||
430 | 577 | ||
578 | for (cc = tth->cc_head; NULL != cc; cc = ccn) | ||
579 | { | ||
580 | ccn = cc->next; | ||
581 | if ( (cc->p1 == p) || | ||
582 | (cc->p2 == p) ) | ||
583 | GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc); | ||
584 | } | ||
431 | if (NULL != p->ghh) | 585 | if (NULL != p->ghh) |
432 | { | 586 | { |
433 | GNUNET_TRANSPORT_get_hello_cancel (p->ghh); | 587 | GNUNET_TRANSPORT_get_hello_cancel (p->ghh); |
@@ -478,15 +632,6 @@ GNUNET_TRANSPORT_TESTING_stop_peer (struct GNUNET_TRANSPORT_TESTING_PeerContext | |||
478 | 632 | ||
479 | 633 | ||
480 | /** | 634 | /** |
481 | * Offer the current HELLO of P2 to P1. | ||
482 | * | ||
483 | * @param cls our `struct GNUNET_TRANSPORT_TESTING_ConnectRequest` | ||
484 | */ | ||
485 | static void | ||
486 | offer_hello (void *cls); | ||
487 | |||
488 | |||
489 | /** | ||
490 | * Function called after the HELLO was passed to the | 635 | * Function called after the HELLO was passed to the |
491 | * transport service. | 636 | * transport service. |
492 | */ | 637 | */ |
diff --git a/src/transport/transport-testing.h b/src/transport/transport-testing.h index 4be451d35..e61621b2e 100644 --- a/src/transport/transport-testing.h +++ b/src/transport/transport-testing.h | |||
@@ -207,8 +207,69 @@ struct GNUNET_TRANSPORT_TESTING_ConnectRequest | |||
207 | */ | 207 | */ |
208 | void *cb_cls; | 208 | void *cb_cls; |
209 | 209 | ||
210 | int p1_c; // dead? | 210 | /** |
211 | int p2_c; // dead? | 211 | * Set if peer1 says the connection is up to peer2. |
212 | */ | ||
213 | int p1_c; | ||
214 | |||
215 | /** | ||
216 | * Set if peer2 says the connection is up to peer1. | ||
217 | */ | ||
218 | int p2_c; | ||
219 | |||
220 | /** | ||
221 | * #GNUNET_YES if both @e p1_c and @e p2_c are #GNUNET_YES. | ||
222 | */ | ||
223 | int connected; | ||
224 | }; | ||
225 | |||
226 | |||
227 | /** | ||
228 | * Information we keep for active transmission jobs. | ||
229 | */ | ||
230 | struct TRANSPORT_TESTING_SendJob | ||
231 | { | ||
232 | |||
233 | /** | ||
234 | * Kept in a DLL. | ||
235 | */ | ||
236 | struct TRANSPORT_TESTING_SendJob *next; | ||
237 | |||
238 | /** | ||
239 | * Kept in a DLL. | ||
240 | */ | ||
241 | struct TRANSPORT_TESTING_SendJob *prev; | ||
242 | |||
243 | /** | ||
244 | * Sender of the message. | ||
245 | */ | ||
246 | struct GNUNET_TRANSPORT_TESTING_PeerContext *sender; | ||
247 | |||
248 | /** | ||
249 | * Receiver of the message. | ||
250 | */ | ||
251 | struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver; | ||
252 | |||
253 | /** | ||
254 | * Operation handle. | ||
255 | */ | ||
256 | struct GNUNET_TRANSPORT_TransmitHandle *th; | ||
257 | |||
258 | /** | ||
259 | * Number of the message. | ||
260 | */ | ||
261 | uint32_t num; | ||
262 | |||
263 | /** | ||
264 | * Type of message to send. | ||
265 | */ | ||
266 | uint16_t mtype; | ||
267 | |||
268 | /** | ||
269 | * Length of the message. | ||
270 | */ | ||
271 | uint16_t msize; | ||
272 | |||
212 | }; | 273 | }; |
213 | 274 | ||
214 | 275 | ||
@@ -233,6 +294,16 @@ struct GNUNET_TRANSPORT_TESTING_Handle | |||
233 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc_tail; | 294 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc_tail; |
234 | 295 | ||
235 | /** | 296 | /** |
297 | * Kept in a DLL. | ||
298 | */ | ||
299 | struct TRANSPORT_TESTING_SendJob *sj_head; | ||
300 | |||
301 | /** | ||
302 | * Kept in a DLL. | ||
303 | */ | ||
304 | struct TRANSPORT_TESTING_SendJob *sj_tail; | ||
305 | |||
306 | /** | ||
236 | * head DLL of peers | 307 | * head DLL of peers |
237 | */ | 308 | */ |
238 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p_head; | 309 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p_head; |
@@ -341,6 +412,32 @@ void | |||
341 | GNUNET_TRANSPORT_TESTING_connect_peers_cancel (struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc); | 412 | GNUNET_TRANSPORT_TESTING_connect_peers_cancel (struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc); |
342 | 413 | ||
343 | 414 | ||
415 | /** | ||
416 | * Function called on matching connect requests. | ||
417 | * | ||
418 | * @param cls closure | ||
419 | * @param cc request matching the query | ||
420 | */ | ||
421 | typedef void | ||
422 | (*GNUNET_TRANSPORT_TESTING_ConnectContextCallback)(void *cls, | ||
423 | struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc); | ||
424 | |||
425 | |||
426 | /** | ||
427 | * Find any connecting context matching the given pair of peers. | ||
428 | * | ||
429 | * @param p1 first peer | ||
430 | * @param p2 second peer | ||
431 | * @param cb function to call | ||
432 | * @param cb_cls closure for @a cb | ||
433 | */ | ||
434 | void | ||
435 | GNUNET_TRANSPORT_TESTING_find_connecting_context (struct GNUNET_TRANSPORT_TESTING_PeerContext *p1, | ||
436 | struct GNUNET_TRANSPORT_TESTING_PeerContext *p2, | ||
437 | GNUNET_TRANSPORT_TESTING_ConnectContextCallback cb, | ||
438 | void *cb_cls); | ||
439 | |||
440 | |||
344 | /* ********************** high-level process functions *************** */ | 441 | /* ********************** high-level process functions *************** */ |
345 | 442 | ||
346 | 443 | ||
@@ -531,6 +628,14 @@ struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext | |||
531 | */ | 628 | */ |
532 | int global_ret; | 629 | int global_ret; |
533 | 630 | ||
631 | /** | ||
632 | * Generator for the `num` field in test messages. Incremented each | ||
633 | * time #GNUNET_TRANSPORT_TESTING_simple_send or | ||
634 | * #GNUNET_TRANSPORT_TESTING_large_send are used to transmit a | ||
635 | * message. | ||
636 | */ | ||
637 | uint32_t send_num_gen; | ||
638 | |||
534 | /* ******* internal state, clients should not mess with this **** */ | 639 | /* ******* internal state, clients should not mess with this **** */ |
535 | 640 | ||
536 | /** | 641 | /** |
@@ -652,6 +757,80 @@ GNUNET_TRANSPORT_TESTING_main_ (const char *argv0, | |||
652 | #define GNUNET_TRANSPORT_TESTING_main(num_peers,check,check_cls) \ | 757 | #define GNUNET_TRANSPORT_TESTING_main(num_peers,check,check_cls) \ |
653 | GNUNET_TRANSPORT_TESTING_main_ (argv[0], __FILE__, num_peers, check, check_cls) | 758 | GNUNET_TRANSPORT_TESTING_main_ (argv[0], __FILE__, num_peers, check, check_cls) |
654 | 759 | ||
760 | /* ***************** Convenience functions for sending ********* */ | ||
761 | |||
762 | |||
763 | /** | ||
764 | * Send a test message of type @a mtype and size @a msize from | ||
765 | * peer @a sender to peer @a receiver. The peers should be | ||
766 | * connected when this function is called. | ||
767 | * | ||
768 | * @param sender the sending peer | ||
769 | * @param receiver the receiving peer | ||
770 | * @param mtype message type to use | ||
771 | * @param msize size of the message, at least `sizeof (struct GNUNET_TRANSPORT_TESTING_TestMessage)` | ||
772 | * @param num unique message number | ||
773 | * @return #GNUNET_OK if message was queued, | ||
774 | * #GNUNET_NO if peers are not connected | ||
775 | * #GNUNET_SYSERR if @a msize is illegal | ||
776 | */ | ||
777 | int | ||
778 | GNUNET_TRANSPORT_TESTING_send (struct GNUNET_TRANSPORT_TESTING_PeerContext *sender, | ||
779 | struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver, | ||
780 | uint16_t mtype, | ||
781 | uint16_t msize, | ||
782 | uint32_t num); | ||
783 | |||
784 | |||
785 | /** | ||
786 | * Message type used by #GNUNET_TRANSPORT_TESTING_simple_send(). | ||
787 | */ | ||
788 | #define GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE 12345 | ||
789 | |||
790 | GNUNET_NETWORK_STRUCT_BEGIN | ||
791 | struct GNUNET_TRANSPORT_TESTING_TestMessage | ||
792 | { | ||
793 | /** | ||
794 | * Type is #GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE. | ||
795 | */ | ||
796 | struct GNUNET_MessageHeader header; | ||
797 | |||
798 | /** | ||
799 | * Monotonically increasing counter throughout the test. | ||
800 | */ | ||
801 | uint32_t num GNUNET_PACKED; | ||
802 | }; | ||
803 | GNUNET_NETWORK_STRUCT_END | ||
804 | |||
805 | |||
806 | /** | ||
807 | * Task that sends a minimalistic test message from the | ||
808 | * first peer to the second peer. | ||
809 | * | ||
810 | * @param cls the `struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext` | ||
811 | * which should contain at least two peers, the first two | ||
812 | * of which should be currently connected | ||
813 | */ | ||
814 | void | ||
815 | GNUNET_TRANSPORT_TESTING_simple_send (void *cls); | ||
816 | |||
817 | /** | ||
818 | * Size of a message sent with | ||
819 | * #GNUNET_TRANSPORT_TESTING_large_send(). Big enough | ||
820 | * to usually force defragmentation. | ||
821 | */ | ||
822 | #define GNUNET_TRANSPORT_TESTING_LARGE_MESSAGE_SIZE 2600 | ||
823 | |||
824 | /** | ||
825 | * Task that sends a large test message from the | ||
826 | * first peer to the second peer. | ||
827 | * | ||
828 | * @param cls the `struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext` | ||
829 | * which should contain at least two peers, the first two | ||
830 | * of which should be currently connected | ||
831 | */ | ||
832 | void | ||
833 | GNUNET_TRANSPORT_TESTING_large_send (void *cls); | ||
655 | 834 | ||
656 | 835 | ||
657 | /* ********************** log-only convenience functions ************* */ | 836 | /* ********************** log-only convenience functions ************* */ |