fix bad free
[oweals/gnunet.git] / src / include / gnunet_fragmentation_lib.h
1 /*
2      This file is part of GNUnet
3      Copyright (C) 2009, 2011, 2015 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 /**
19  * @author Christian Grothoff
20  *
21  * @file
22  * Library to help fragment messages
23  *
24  * @defgroup fragmentation  Fragmentation library
25  * Library to help fragment messages
26  * @{
27  *
28  * @todo Consider additional flow-control for sending from
29  *       fragmentation based on continuations.
30  */
31
32 #ifndef GNUNET_FRAGMENTATION_LIB_H
33 #define GNUNET_FRAGMENTATION_LIB_H
34
35 #include "gnunet_util_lib.h"
36 #include "gnunet_bandwidth_lib.h"
37 #include "gnunet_statistics_service.h"
38
39 #ifdef __cplusplus
40 extern "C"
41 {
42 #if 0                           /* keep Emacsens' auto-indent happy */
43 }
44 #endif
45 #endif
46
47
48 /**
49  * Fragmentation context.
50  */
51 struct GNUNET_FRAGMENT_Context;
52
53
54 /**
55  * Function that is called with messages created by the fragmentation
56  * module.  In the case of the 'proc' callback of the
57  * #GNUNET_FRAGMENT_context_create() function, this function must
58  * eventually call #GNUNET_FRAGMENT_context_transmission_done().
59  *
60  * @param cls closure
61  * @param msg the message that was created
62  */
63 typedef void
64 (*GNUNET_FRAGMENT_MessageProcessor) (void *cls,
65                                      const struct GNUNET_MessageHeader *msg);
66
67
68 /**
69  * Create a fragmentation context for the given message.
70  * Fragments the message into fragments of size @a mtu or
71  * less.  Calls @a proc on each un-acknowledged fragment,
72  * using both the expected @a msg_delay between messages and
73  * acknowledgements and the given @a tracker to guide the
74  * frequency of calls to @a proc.
75  *
76  * @param stats statistics context
77  * @param mtu the maximum message size for each fragment
78  * @param tracker bandwidth tracker to use for flow control (can be NULL)
79  * @param msg_delay initial delay to insert between fragment transmissions
80  *              based on previous messages
81  * @param ack_delay expected delay between fragment transmission
82  *              and ACK based on previous messages
83  * @param msg the message to fragment
84  * @param proc function to call for each fragment to transmit
85  * @param proc_cls closure for proc
86  * @return the fragmentation context
87  */
88 struct GNUNET_FRAGMENT_Context *
89 GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats,
90                                 uint16_t mtu,
91                                 struct GNUNET_BANDWIDTH_Tracker *tracker,
92                                 struct GNUNET_TIME_Relative msg_delay,
93                                 struct GNUNET_TIME_Relative ack_delay,
94                                 const struct GNUNET_MessageHeader *msg,
95                                 GNUNET_FRAGMENT_MessageProcessor proc,
96                                 void *proc_cls);
97
98
99 /**
100  * Continuation to call from the 'proc' function after the fragment
101  * has been transmitted (and hence the next fragment can now be
102  * given to proc).
103  *
104  * @param fc fragmentation context
105  */
106 void
107 GNUNET_FRAGMENT_context_transmission_done (struct GNUNET_FRAGMENT_Context *fc);
108
109
110 /**
111  * Process an acknowledgement message we got from the other
112  * side (to control re-transmits).
113  *
114  * @param fc fragmentation context
115  * @param msg acknowledgement message we received
116  * @return #GNUNET_OK if this ack completes the work of the 'fc'
117  *                   (all fragments have been received);
118  *         #GNUNET_NO if more messages are pending
119  *         #GNUNET_SYSERR if this ack is not valid for this fc
120  */
121 int
122 GNUNET_FRAGMENT_process_ack (struct GNUNET_FRAGMENT_Context *fc,
123                              const struct GNUNET_MessageHeader *msg);
124
125
126 /**
127  * Destroy the given fragmentation context (stop calling 'proc', free
128  * resources).
129  *
130  * @param fc fragmentation context
131  * @param msg_delay where to store average delay between individual message transmissions the
132  *         last message (OUT only)
133  * @param ack_delay where to store average delay between transmission and ACK for the
134  *         last message, set to FOREVER if the message was not fully transmitted (OUT only)
135  */
136 void
137 GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *fc,
138                                  struct GNUNET_TIME_Relative *msg_delay,
139                                  struct GNUNET_TIME_Relative *ack_delay);
140
141
142 /**
143  * Convert an ACK message to a printable format suitable for logging.
144  *
145  * @param ack message to print
146  * @return ack in human-readable format
147  */
148 const char *
149 GNUNET_FRAGMENT_print_ack (const struct GNUNET_MessageHeader *ack);
150
151
152 /**
153  * Defragmentation context (one per connection).
154  */
155 struct GNUNET_DEFRAGMENT_Context;
156
157
158 /**
159  * Function that is called with acknowledgement messages created by
160  * the fragmentation module.  Acknowledgements are cummulative,
161  * so it is OK to only transmit the 'latest' ack message for the same
162  * message ID.
163  *
164  * @param cls closure
165  * @param id unique message ID (modulo collisions)
166  * @param msg the message that was created
167  */
168 typedef void
169 (*GNUNET_DEFRAGMENT_AckProcessor) (void *cls,
170                                    uint32_t id,
171                                    const struct GNUNET_MessageHeader *msg);
172
173
174 /**
175  * Create a defragmentation context.
176  *
177  * @param stats statistics context
178  * @param mtu the maximum message size for each fragment
179  * @param num_msgs how many fragmented messages
180  *                 to we defragment at most at the same time?
181  * @param cls closure for @a proc and @a ackp
182  * @param proc function to call with defragmented messages
183  * @param ackp function to call with acknowledgements (to send
184  *             back to the other side)
185  * @return the defragmentation context
186  */
187 struct GNUNET_DEFRAGMENT_Context *
188 GNUNET_DEFRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats,
189                                   uint16_t mtu,
190                                   unsigned int num_msgs,
191                                   void *cls,
192                                   GNUNET_FRAGMENT_MessageProcessor proc,
193                                   GNUNET_DEFRAGMENT_AckProcessor ackp);
194
195
196 /**
197  * Destroy the given defragmentation context.
198  *
199  * @param dc defragmentation context
200  */
201 void
202 GNUNET_DEFRAGMENT_context_destroy (struct GNUNET_DEFRAGMENT_Context *dc);
203
204
205 /**
206  * We have received a fragment.  Process it.
207  *
208  * @param dc the context
209  * @param msg the message that was received
210  * @return #GNUNET_OK on success,
211  *         #GNUNET_NO if this was a duplicate,
212  *         #GNUNET_SYSERR on error
213  */
214 int
215 GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc,
216                                     const struct GNUNET_MessageHeader *msg);
217
218
219
220 #if 0                           /* keep Emacsens' auto-indent happy */
221 {
222 #endif
223 #ifdef __cplusplus
224 }
225 #endif
226
227 #endif
228
229 /** @} */  /* end of group */