also config files
[oweals/gnunet.git] / src / transport / transport-testing-send.c
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 it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your 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      Affero General Public License for more details.
14
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
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 ( \
31     GNUNET_TIME_UNIT_SECONDS, 30)
32
33
34 /**
35  * Return @a cx in @a cls.
36  */
37 static void
38 find_cr (void *cls,
39          struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cx)
40 {
41   struct GNUNET_TRANSPORT_TESTING_ConnectRequest **cr = cls;
42
43   if (GNUNET_NO == cx->connected)
44     return;
45   *cr = cx;
46 }
47
48
49 /**
50  * Send a test message of type @a mtype and size @a msize from
51  * peer @a sender to peer @a receiver.  The peers should be
52  * connected when this function is called.
53  *
54  * @param sender the sending peer
55  * @param receiver the receiving peer
56  * @param mtype message type to use
57  * @param msize size of the message, at least `sizeof (struct GNUNET_TRANSPORT_TESTING_TestMessage)`
58  * @param num unique message number
59  * @param cont continuation to call after transmission
60  * @param cont_cls closure for @a cont
61  * @return #GNUNET_OK if message was queued,
62  *         #GNUNET_NO if peers are not connected
63  *         #GNUNET_SYSERR if @a msize is illegal
64  */
65 int
66 GNUNET_TRANSPORT_TESTING_send (struct
67                                GNUNET_TRANSPORT_TESTING_PeerContext *sender,
68                                struct GNUNET_TRANSPORT_TESTING_PeerContext *
69                                receiver,
70                                uint16_t mtype,
71                                uint16_t msize,
72                                uint32_t num,
73                                GNUNET_SCHEDULER_TaskCallback cont,
74                                void *cont_cls)
75 {
76   struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cr;
77   struct GNUNET_MQ_Envelope *env;
78   struct GNUNET_TRANSPORT_TESTING_TestMessage *test;
79
80   if (msize < sizeof(struct GNUNET_TRANSPORT_TESTING_TestMessage))
81   {
82     GNUNET_break (0);
83     return GNUNET_SYSERR;
84   }
85   cr = NULL;
86   GNUNET_TRANSPORT_TESTING_find_connecting_context (sender,
87                                                     receiver,
88                                                     &find_cr,
89                                                     &cr);
90   if (NULL == cr)
91     GNUNET_TRANSPORT_TESTING_find_connecting_context (receiver,
92                                                       sender,
93                                                       &find_cr,
94                                                       &cr);
95   if (NULL == cr)
96   {
97     GNUNET_break (0);
98     return GNUNET_NO;
99   }
100   if (NULL == cr->mq)
101   {
102     GNUNET_break (0);
103     return GNUNET_NO;
104   }
105   {
106     char *receiver_s = GNUNET_strdup (GNUNET_i2s (&receiver->id));
107
108     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
109                 "Sending message from peer %u (`%s') -> peer %u (`%s') !\n",
110                 sender->no,
111                 GNUNET_i2s (&sender->id),
112                 receiver->no,
113                 receiver_s);
114     GNUNET_free (receiver_s);
115   }
116   env = GNUNET_MQ_msg_extra (test,
117                              msize - sizeof(*test),
118                              mtype);
119   test->num = htonl (num);
120   memset (&test[1],
121           num,
122           msize - sizeof(*test));
123   GNUNET_MQ_notify_sent (env,
124                          cont,
125                          cont_cls);
126   GNUNET_MQ_send (cr->mq,
127                   env);
128   return GNUNET_OK;
129 }
130
131
132 /**
133  * Task that sends a test message from the
134  * first peer to the second peer.
135  *
136  * @param ccc context which should contain at least two peers, the
137  *        first two of which should be currently connected
138  * @param size desired message size
139  * @param cont continuation to call after transmission
140  * @param cont_cls closure for @a cont
141  */
142 static void
143 do_send (struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc,
144          uint16_t size,
145          GNUNET_SCHEDULER_TaskCallback cont,
146          void *cont_cls)
147 {
148   int ret;
149
150   ccc->global_ret = GNUNET_SYSERR;
151   ret = GNUNET_TRANSPORT_TESTING_send (ccc->p[0],
152                                        ccc->p[1],
153                                        GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE,
154                                        size,
155                                        ccc->send_num_gen++,
156                                        cont,
157                                        cont_cls);
158   GNUNET_assert (GNUNET_SYSERR != ret);
159   if (GNUNET_NO == ret)
160   {
161     GNUNET_break (0);
162     ccc->global_ret = GNUNET_SYSERR;
163     GNUNET_SCHEDULER_shutdown ();
164   }
165 }
166
167
168 /**
169  * Task that sends a minimalistic test message from the
170  * first peer to the second peer.
171  *
172  * @param cls the `struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext`
173  *        which should contain at least two peers, the first two
174  *        of which should be currently connected
175  */
176 void
177 GNUNET_TRANSPORT_TESTING_simple_send (void *cls)
178 {
179   struct GNUNET_TRANSPORT_TESTING_SendClosure *sc = cls;
180   int done;
181   size_t msize;
182
183   if (0 < sc->num_messages)
184   {
185     sc->num_messages--;
186     done = (0 == sc->num_messages);
187   }
188   else
189   {
190     done = 0;   /* infinite loop */
191   }
192   msize = sizeof(struct GNUNET_TRANSPORT_TESTING_TestMessage);
193   if (NULL != sc->get_size_cb)
194     msize = sc->get_size_cb (sc->num_messages);
195   /* if this was the last message, call the continuation,
196      otherwise call this function again */
197   do_send (sc->ccc,
198            msize,
199            done ? sc->cont : &GNUNET_TRANSPORT_TESTING_simple_send,
200            done ? sc->cont_cls : sc);
201 }
202
203
204 /**
205  * Task that sends a large test message from the
206  * first peer to the second peer.
207  *
208  * @param cls the `struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext`
209  *        which should contain at least two peers, the first two
210  *        of which should be currently connected
211  */
212 void
213 GNUNET_TRANSPORT_TESTING_large_send (void *cls)
214 {
215   struct GNUNET_TRANSPORT_TESTING_SendClosure *sc = cls;
216   int done;
217   size_t msize;
218
219   if (0 < sc->num_messages)
220   {
221     sc->num_messages--;
222     done = (0 == sc->num_messages);
223   }
224   else
225   {
226     done = 0;   /* infinite loop */
227   }
228   msize = 2600;
229   if (NULL != sc->get_size_cb)
230     msize = sc->get_size_cb (sc->num_messages);
231   /* if this was the last message, call the continuation,
232      otherwise call this function again */
233   do_send (sc->ccc,
234            msize,
235            done ? sc->cont : &GNUNET_TRANSPORT_TESTING_large_send,
236            done ? sc->cont_cls : sc);
237 }
238
239
240 /* end of transport-testing-send.c */