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