aboutsummaryrefslogtreecommitdiff
path: root/src/include/gnunet_stream_lib.h
blob: 056695ba33cba539a77bb88b12b98eddf9107096 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
/*
     This file is part of GNUnet.
     (C) 2011, 2012 Christian Grothoff (and other contributing authors)

     GNUnet is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 3, or (at your
     option) any later version.

     GNUnet is distributed in the hope that it will be useful, but
     WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with GNUnet; see the file COPYING.  If not, write to the
     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
     Boston, MA 02111-1307, USA.
*/

/**
 * @file include/gnunet_stream_lib.h
 * @brief stream handling using mesh API
 * @author Sree Harsha Totakura
 */

#ifndef GNUNET_STREAM_LIB_H
#define GNUNET_STREAM_LIB_H

#ifdef __cplusplus
extern "C" 
{
#if 0
}
#endif
#endif

#include "gnunet_util_lib.h"
#include "gnunet_mesh_service.h"

/**
 * Stream status 
 */
enum GNUNET_STREAM_Status
  {
    /**
     * All previous read/write operations are successfully done
     */
    GNUNET_STREAM_OK,

    /**
     * A timeout occured while reading/writing the stream
     */
    GNUNET_STREAM_TIMEOUT,

    /**
     * Other side has shutdown the socket for this type of operation
     * (reading/writing)
     */
    GNUNET_STREAM_SHUTDOWN,

    /**
     * A serious error occured while operating on this stream
     */
    GNUNET_STREAM_SYSERR
  };

/**
 * Opaque handler for stream
 */
struct GNUNET_STREAM_Socket;

/**
 * Functions of this type will be called when a stream is established
 *
 * @param cls the closure from GNUNET_STREAM_open
 * @param socket socket to use to communicate with the other side (read/write)
 */
typedef void (*GNUNET_STREAM_OpenCallback) (void *cls,
					    struct GNUNET_STREAM_Socket *socket);


/**
 * Callback for signalling stream listen success; See
 * GNUNET_STREAM_OPTION_SIGNAL_LISTEN_SUCCESS
 */
typedef void (*GNUNET_STREAM_ListenSuccessCallback) (void);


/**
 * Options for the stream.
 */
enum GNUNET_STREAM_Option
  {
    /**
     * End of the option list.
     */
    GNUNET_STREAM_OPTION_END = 0,

    /**
     * Option to set the initial retransmission timeout (when do we retransmit
     * a packet that did not yield an acknowledgement for the first time?).  
     * Repeated retransmissions will then use an exponential back-off.
     * Takes a 'struct GNUNET_TIME_Relative' as the only argument.  A value
     * of '0' means to use the round-trip time (plus a tiny grace period);
     * this is also the default.
     */
    GNUNET_STREAM_OPTION_INITIAL_RETRANSMIT_TIMEOUT,

    /**
     * Option to set the write sequence number. Takes a uint32_t as parameter
     * to set the value of the write sequence number
     */
    GNUNET_STREAM_OPTION_TESTING_SET_WRITE_SEQUENCE_NUMBER,

    /**
     * Listen socket timeout in milliseconds given as uint32_t
     */
    GNUNET_STREAM_OPTION_LISTEN_TIMEOUT,

    /**
     * Option to register a callback when stream listening is successfull. Takes
     * parameter of the form GNUNET_STREAM_ListenSuccessCallback. The callback
     * is only called if listening is successful
     */
    GNUNET_STREAM_OPTION_SIGNAL_LISTEN_SUCCESS,

    /**
     * Option to set the maximum payload size in bytes of a stream data
     * packets. Takes an uint16_t as argument. Note that this should be less
     * than 64000 and cannot be zero. Default is 64000 bytes.
     */
    GNUNET_STREAM_OPTION_MAX_PAYLOAD_SIZE
  };


/**
 * Tries to open a stream to the target peer
 *
 * @param cfg configuration to use
 * @param target the target peer to which the stream has to be opened
 * @param app_port the application port number which uniquely identifies this
 *            stream
 * @param open_cb this function will be called after stream has be established;
 *          cannot be NULL
 * @param open_cb_cls the closure for open_cb
 * @param ... options to the stream, terminated by GNUNET_STREAM_OPTION_END
 * @return if successful it returns the stream socket; NULL if stream cannot be
 *         opened 
 */
struct GNUNET_STREAM_Socket *
GNUNET_STREAM_open (const struct GNUNET_CONFIGURATION_Handle *cfg,
                    const struct GNUNET_PeerIdentity *target,
                    GNUNET_MESH_ApplicationType app_port,
                    GNUNET_STREAM_OpenCallback open_cb,
		    void *open_cb_cls,
		    ...);


/**
 * Handle for shutdown
 */
struct GNUNET_STREAM_ShutdownHandle;


/**
 * Completion callback for shutdown
 *
 * @param cls the closure from GNUNET_STREAM_shutdown call
 * @param operation the operation that was shutdown (SHUT_RD, SHUT_WR,
 *          SHUT_RDWR) 
 */
typedef void (*GNUNET_STREAM_ShutdownCompletion) (void *cls,
                                                  int operation);


/**
 * Shutdown the stream for reading or writing (similar to man 2 shutdown).
 *
 * @param socket the stream socket
 * @param operation SHUT_RD, SHUT_WR or SHUT_RDWR
 * @param completion_cb the callback that will be called upon successful
 *          shutdown of given operation
 * @param completion_cls the closure for the completion callback
 * @return the shutdown handle; NULL in case of any error
 */
struct GNUNET_STREAM_ShutdownHandle *
GNUNET_STREAM_shutdown (struct GNUNET_STREAM_Socket *socket,
			int operation,
                        GNUNET_STREAM_ShutdownCompletion completion_cb,
                        void *completion_cls);


/**
 * Cancels a pending shutdown. Note that the shutdown messages may already
 * be sent and the stream is shutdown already for the operation given to
 * GNUNET_STREAM_shutdown(). This function only clears up any retranmissions of
 * shutdown messages and frees the shutdown handle.
 *
 * @param handle the shutdown handle returned from GNUNET_STREAM_shutdown
 */
void
GNUNET_STREAM_shutdown_cancel (struct GNUNET_STREAM_ShutdownHandle *handle);


/**
 * Closes the stream and frees the associated state. The stream should be
 * shutdown for both reading and writing before closing.
 *
 * @param socket the stream socket
 */
void
GNUNET_STREAM_close (struct GNUNET_STREAM_Socket *socket);


/**
 * Functions of this type are called upon new stream connection from other peers
 * or upon binding error which happen when the app_port given in
 * GNUNET_STREAM_listen() is already taken.
 *
 * @param cls the closure from GNUNET_STREAM_listen
 * @param socket the socket representing the stream; NULL on binding error
 * @param initiator the identity of the peer who wants to establish a stream
 *            with us; NULL on binding error
 * @return GNUNET_OK to keep the socket open, GNUNET_SYSERR to close the
 *             stream (the socket will be invalid after the call)
 */
typedef int (*GNUNET_STREAM_ListenCallback) (void *cls,
                                             struct GNUNET_STREAM_Socket *socket,
                                             const struct 
                                             GNUNET_PeerIdentity *initiator);


/**
 * A socket for listening.
 */
struct GNUNET_STREAM_ListenSocket;

/**
 * Listens for stream connections for a specific application ports
 *
 * @param cfg the configuration to use
 * @param app_port the application port for which new streams will be
 *         accepted. If another stream is listening on the same port the
 *         listen_cb will be called to signal binding error and the returned
 *         ListenSocket will be invalidated.
 * @param listen_cb this function will be called when a peer tries to establish
 *            a stream with us
 * @param listen_cb_cls closure for listen_cb
 * @param ... options to the stream, terminated by GNUNET_STREAM_OPTION_END
 * @return listen socket, NULL for any error
 */
struct GNUNET_STREAM_ListenSocket *
GNUNET_STREAM_listen (const struct GNUNET_CONFIGURATION_Handle *cfg,
                      GNUNET_MESH_ApplicationType app_port,
                      GNUNET_STREAM_ListenCallback listen_cb,
                      void *listen_cb_cls,
                      ...);


/**
 * Closes the listen socket
 *
 * @param lsocket the listen socket
 */
void
GNUNET_STREAM_listen_close (struct GNUNET_STREAM_ListenSocket *lsocket);


/**
 * Functions of this signature are called whenever writing operations
 * on a stream are executed
 *
 * @param cls the closure from GNUNET_STREAM_write
 * @param status the status of the stream at the time this function is called;
 *          GNUNET_STREAM_OK if writing to stream was completed successfully;
 *          GNUNET_STREAM_TIMEOUT if the given data is not sent successfully
 *          (this doesn't mean that the data is never sent, the receiver may
 *          have read the data but its ACKs may have been lost);
 *          GNUNET_STREAM_SHUTDOWN if the stream is shutdown for writing in the
 *          mean time; GNUNET_STREAM_SYSERR if the stream is broken and cannot
 *          be processed.
 * @param size the number of bytes written
 */
typedef void (*GNUNET_STREAM_CompletionContinuation) (void *cls,
						      enum GNUNET_STREAM_Status
						      status,
						      size_t size);


/**
 * Handle to cancel IO write operations.
 */
struct GNUNET_STREAM_WriteHandle;


/**
 * Handle to cancel IO read operations.
 */
struct GNUNET_STREAM_ReadHandle;

/**
 * Tries to write the given data to the stream. The maximum size of data that
 * can be written per a write operation is ~ 4MB (64 * (64000 - sizeof (struct
 * GNUNET_STREAM_DataMessage))). If size is greater than this it is not an API
 * violation, however only the said number of maximum bytes will be written.
 *
 * @param socket the socket representing a stream
 * @param data the data buffer from where the data is written into the stream
 * @param size the number of bytes to be written from the data buffer
 * @param timeout the timeout period
 * @param write_cont the function to call upon writing some bytes into the
 *          stream 
 * @param write_cont_cls the closure
 *
 * @return handle to cancel the operation; if a previous write is pending NULL
 *           is returned. If the stream has been shutdown for this operation or
 *           is broken then write_cont is immediately called and NULL is
 *           returned.
 */
struct GNUNET_STREAM_WriteHandle *
GNUNET_STREAM_write (struct GNUNET_STREAM_Socket *socket,
                     const void *data,
                     size_t size,
                     struct GNUNET_TIME_Relative timeout,
                     GNUNET_STREAM_CompletionContinuation write_cont,
                     void *write_cont_cls);


/**
 * Functions of this signature are called whenever data is available from the
 * stream.
 *
 * @param cls the closure from GNUNET_STREAM_read
 * @param status the status of the stream at the time this function is called
 * @param data traffic from the other side
 * @param size the number of bytes available in data read; will be 0 on timeout 
 * @return number of bytes of processed from 'data' (any data remaining should be
 *         given to the next time the read processor is called).
 */
typedef size_t (*GNUNET_STREAM_DataProcessor) (void *cls,
                                               enum GNUNET_STREAM_Status status,
                                               const void *data,
                                               size_t size);


/**
 * Tries to read data from the stream. Should not be called when another read
 * handle is present; the existing read handle should be canceled with
 * GNUNET_STREAM_read_cancel(). Only one read handle per socket is present at
 * any time
 *
 * @param socket the socket representing a stream
 * @param timeout the timeout period
 * @param proc function to call with data (once only)
 * @param proc_cls the closure for proc
 * @return handle to cancel the operation; NULL is returned if the stream has
 *           been shutdown for this type of opeartion (the DataProcessor is
 *           immediately called with GNUNET_STREAM_SHUTDOWN as status)
 */
struct GNUNET_STREAM_ReadHandle *
GNUNET_STREAM_read (struct GNUNET_STREAM_Socket *socket,
                    struct GNUNET_TIME_Relative timeout,
		    GNUNET_STREAM_DataProcessor proc,
		    void *proc_cls);


/**
 * Cancels pending write operation. Also cancels packet retransmissions which
 * may have resulted otherwise.
 *
 * CAUTION: Normally a write operation is considered successful if the data
 * given to it is sent and acknowledged by the receiver. As data is divided
 * into packets, it is possible that not all packets are received by the
 * receiver. Any missing packets are then retransmitted till the receiver
 * acknowledges all packets or until a timeout . During this scenario if the
 * write operation is cancelled all such retransmissions are also
 * cancelled. This may leave the receiver's receive buffer incompletely filled
 * as some missing packets are never retransmitted. So this operation should be
 * used before shutting down transmission from our side or before closing the
 * socket.
 *
 * @param wh write operation handle to cancel
 */
void
GNUNET_STREAM_write_cancel (struct GNUNET_STREAM_WriteHandle *wh);


/**
 * Cancel pending read operation.
 *
 * @param rh read operation handle to cancel
 */
void
GNUNET_STREAM_read_cancel (struct GNUNET_STREAM_ReadHandle *rh);


#if 0
{
#endif
#ifdef __cplusplus
}
#endif

#endif  /* STREAM_PROTOCOL_H */