~ubuntu-branches/ubuntu/trusty/gnunet/trusty

« back to all changes in this revision

Viewing changes to src/stream/test_stream_local.c

  • Committer: Package Import Robot
  • Author(s): Bertrand Marc
  • Date: 2012-05-06 00:28:20 UTC
  • mfrom: (1.2.17)
  • Revision ID: package-import@ubuntu.com-20120506002820-n02u1ginv8pjh0ee
Tags: 0.9.2-1
* New maintainer (Closes: #660438).
* New upstream release (Closes: #621645).
* Remove debian/patches, not necessary any more.
* Update dependencies, according to README:
  + update minimal versions. 
  + depends on libunistring-dev.
  + depends on libltdl-dev instead of libltdl3-dev.
  + no need to depend on libgtk anymore.
  + gnunet-server suggests miniupnpc.
* debian/rules:
  + no need to define LOGFILE and PIDFILE.
  + create a minimal conf file.
  + cut gnunet-download-manager.scm extension.
  + remove autogenerated files in clean.
* Gnunet is now released under the GPL v3.
* Standards version 3.9.3.
* Add debian/watch.
* Adding Italian debconf translations, thanks to Beatrice Torracca
  (Closes: #663432).
* Move to dh-autoreconf and add extend-diff-ignore in debian/source/options.
* Remove gnunet-tools since gnunet-setup is not part of gnunet anymore
  (Closes:#651192).
* gnunet-server.init:
  + several services are now supervised by gnunet-service-arm.
  + define the logfile at run time.
* Use a secured group gnunetdns for SUID binaries and change permissions
  accordingly, see https://gnunet.org/gnunet-access-control-model
* gnunet-server.postinst, gnunet-server.postrm: use dpkg-statoverride to set
  and remove setuid permissions.
* Remove properly the old incompatible /etc/gnunetd.conf, use
  /etc/gnunet.conf instead.
* Add minimal (generic) man pages when information is available.
* Remove dpkg options for compression.
* gnunet-server.docs: add README.mysql and README.postgres.
* debian/rules: remove template binaries after dh_install.
* debian/copyright:
  + use copyright format 1.0.
  + mention AUTHORS and translators.
  + use GPL-3+ when possible.
  + add a paragraph for two files distributed under MIT/X11.
* Use dh_installdocs --link-doc to avoid redundancy.
* Remove unused debian/gnunet-dev.lintian-overrides.
* debian/control: add Vcs-git and Vcs-browser fields.
* gnunet-server.postrm:
  + use debconf to determine which user and group to delete.
  + remove /var/lib/gnunet on purge.
  + remove /etc/default/gnunet-server on purge (Closes: #668766).
* Make gnunet-dbg dependencies alternatives as it provides debugging
  symbol for all of them.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
     This file is part of GNUnet.
 
3
     (C) 2011, 2012 Christian Grothoff (and other contributing authors)
 
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., 59 Temple Place - Suite 330,
 
18
     Boston, MA 02111-1307, USA.
 
19
*/
 
20
 
 
21
/**
 
22
 * @file stream/test_stream_local.c
 
23
 * @brief Stream API testing between local peers
 
24
 * @author Sree Harsha Totakura
 
25
 */
 
26
 
 
27
#include <string.h>
 
28
 
 
29
#include "platform.h"
 
30
#include "gnunet_util_lib.h"
 
31
#include "gnunet_mesh_service.h"
 
32
#include "gnunet_stream_lib.h"
 
33
 
 
34
#define VERBOSE 1
 
35
 
 
36
/**
 
37
 * Structure for holding peer's sockets and IO Handles
 
38
 */
 
39
struct PeerData
 
40
{
 
41
  /**
 
42
   * Peer's stream socket
 
43
   */
 
44
  struct GNUNET_STREAM_Socket *socket;
 
45
 
 
46
  /**
 
47
   * Peer's io handle
 
48
   */
 
49
  struct GNUNET_STREAM_IOHandle *io_handle;
 
50
 
 
51
  /**
 
52
   * Bytes the peer has written
 
53
   */
 
54
  unsigned int bytes_wrote;
 
55
 
 
56
  /**
 
57
   * Byte the peer has read
 
58
   */
 
59
  unsigned int bytes_read;
 
60
};
 
61
 
 
62
static struct GNUNET_OS_Process *arm_pid;
 
63
static struct PeerData peer1;
 
64
static struct PeerData peer2;
 
65
static struct GNUNET_STREAM_ListenSocket *peer2_listen_socket;
 
66
 
 
67
static GNUNET_SCHEDULER_TaskIdentifier abort_task;
 
68
static GNUNET_SCHEDULER_TaskIdentifier test_task;
 
69
static GNUNET_SCHEDULER_TaskIdentifier read_task;
 
70
 
 
71
static char *data = "ABCD";
 
72
static int result;
 
73
 
 
74
/**
 
75
 * Shutdown nicely
 
76
 */
 
77
static void
 
78
do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 
79
{
 
80
  GNUNET_STREAM_close (peer1.socket);
 
81
  GNUNET_STREAM_close (peer2.socket);
 
82
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: shutdown\n");
 
83
  if (0 != abort_task)
 
84
  {
 
85
    GNUNET_SCHEDULER_cancel (abort_task);
 
86
  }
 
87
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: arm\n");
 
88
  if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM))
 
89
  {
 
90
    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
 
91
  }
 
92
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Wait\n");
 
93
  GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (arm_pid));
 
94
  GNUNET_OS_process_close (arm_pid);
 
95
}
 
96
 
 
97
 
 
98
/**
 
99
 * Something went wrong and timed out. Kill everything and set error flag
 
100
 */
 
101
static void
 
102
do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 
103
{
 
104
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: ABORT\n");
 
105
  if (0 != test_task)
 
106
  {
 
107
    GNUNET_SCHEDULER_cancel (test_task);
 
108
  }
 
109
  if (0 != read_task)
 
110
    {
 
111
      GNUNET_SCHEDULER_cancel (read_task);
 
112
    }
 
113
  result = GNUNET_SYSERR;
 
114
  abort_task = 0;
 
115
  do_shutdown (cls, tc);
 
116
}
 
117
 
 
118
 
 
119
/**
 
120
 * The write completion function; called upon writing some data to stream or
 
121
 * upon error
 
122
 *
 
123
 * @param cls the closure from GNUNET_STREAM_write/read
 
124
 * @param status the status of the stream at the time this function is called
 
125
 * @param size the number of bytes read or written
 
126
 */
 
127
static void 
 
128
write_completion (void *cls,
 
129
                  enum GNUNET_STREAM_Status status,
 
130
                  size_t size)
 
131
{
 
132
  struct PeerData *peer;
 
133
 
 
134
  peer = (struct PeerData *) cls;
 
135
  GNUNET_assert (GNUNET_STREAM_OK == status);
 
136
  GNUNET_assert (size < strlen (data));
 
137
  peer->bytes_wrote += size;
 
138
 
 
139
  if (peer->bytes_wrote < strlen(data)) /* Have more data to send */
 
140
    {
 
141
      peer->io_handle = GNUNET_STREAM_write (peer->socket,
 
142
                                             (void *) data,
 
143
                                             strlen(data) - peer->bytes_wrote,
 
144
                                             GNUNET_TIME_relative_multiply
 
145
                                             (GNUNET_TIME_UNIT_SECONDS, 5),
 
146
                                             &write_completion,
 
147
                                             cls);
 
148
      GNUNET_assert (NULL != peer->io_handle);
 
149
    }
 
150
  else
 
151
    {
 
152
      if (&peer1 == peer)   /* Peer1 has finished writing; should read now */
 
153
        {
 
154
          peer->io_handle = GNUNET_STREAM_read ((struct GNUNET_STREAM_Socket *)
 
155
                                                peer->socket,
 
156
                                                GNUNET_TIME_relative_multiply
 
157
                                                (GNUNET_TIME_UNIT_SECONDS, 5),
 
158
                                                &input_processor,
 
159
                                                cls);
 
160
          GNUNET_assert (NULL!=peer->io_handle);
 
161
        }
 
162
    }
 
163
}
 
164
 
 
165
 
 
166
/**
 
167
 * Function executed after stream has been established
 
168
 *
 
169
 * @param cls the closure from GNUNET_STREAM_open
 
170
 * @param socket socket to use to communicate with the other side (read/write)
 
171
 */
 
172
static void 
 
173
stream_open_cb (void *cls,
 
174
                struct GNUNET_STREAM_Socket *socket)
 
175
{
 
176
  struct PeerData *peer;
 
177
 
 
178
  peer = (struct PeerData *) cls;
 
179
  peer->bytes_wrote = 0;
 
180
  GNUNET_assert (socket == peer1.socket);
 
181
  GNUNET_assert (socket == peer->socket);
 
182
  peer->io_handle = GNUNET_STREAM_write (peer->socket, /* socket */
 
183
                                         (void *) data, /* data */
 
184
                                         strlen(data),
 
185
                                         GNUNET_TIME_relative_multiply
 
186
                                         (GNUNET_TIME_UNIT_SECONDS, 5),
 
187
                                         &write_completion,
 
188
                                         cls);
 
189
  GNUNET_assert (NULL != peer->io_handle);
 
190
}
 
191
 
 
192
 
 
193
/**
 
194
 * Input processor
 
195
 *
 
196
 * @param cls the closure from GNUNET_STREAM_write/read
 
197
 * @param status the status of the stream at the time this function is called
 
198
 * @param data traffic from the other side
 
199
 * @param size the number of bytes available in data read 
 
200
 * @return number of bytes of processed from 'data' (any data remaining should be
 
201
 *         given to the next time the read processor is called).
 
202
 */
 
203
static size_t
 
204
input_processor (void *cls,
 
205
                 enum GNUNET_STREAM_Status status,
 
206
                 const void *input_data,
 
207
                 size_t size)
 
208
{
 
209
  struct PeerData *peer;
 
210
 
 
211
  peer = (struct PeerData *) cls;
 
212
 
 
213
  GNUNET_assert (GNUNET_STERAM_OK == status);
 
214
  GNUNET_assert (size < strlen (data));
 
215
  GNUNET_assert (strncmp ((const char *) data + peer->bytes_read, 
 
216
                          (const char *) input_data,
 
217
                          size));
 
218
  peer->bytes_read += size;
 
219
  
 
220
  if (peer->bytes_read < strlen (data))
 
221
    {
 
222
      peer->io_handle = GNUNET_STREAM_read ((struct GNUNET_STREAM_Socket *)
 
223
                                            peer->socket,
 
224
                                            GNUNET_TIME_relative_multiply
 
225
                                            (GNUNET_TIME_UNIT_SECONDS, 5),
 
226
                                            &input_processor,
 
227
                                            cls);
 
228
      GNUNET_assert (NULL != peer->io_handle);
 
229
    }
 
230
  else 
 
231
    {
 
232
      if (&peer2 == peer)    /* Peer2 has completed reading; should write */
 
233
        {
 
234
          peer->bytes_wrote = 0;
 
235
          peer->io_handle = GNUNET_STREAM_write ((struct GNUNET_STREAM_Socket *)
 
236
                                                 peer->socket,
 
237
                                                 (void *) data,
 
238
                                                 strlen(data),
 
239
                                                 GNUNET_TIME_relative_multiply
 
240
                                                 (GNUNET_TIME_UNIT_SECONDS, 5),
 
241
                                                 &write_completion,
 
242
                                                 cls);
 
243
        }
 
244
      else                      /* Peer1 has completed reading. End of tests */
 
245
        {
 
246
          GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
 
247
        }
 
248
    } 
 
249
  return size;
 
250
}
 
251
 
 
252
  
 
253
/**
 
254
 * Scheduler call back; to be executed when a new stream is connected
 
255
 * Called from listen connect for peer2
 
256
 */
 
257
static void
 
258
stream_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 
259
{
 
260
  read_task = GNUNET_SCHEDULER_NO_TASK;
 
261
  GNUNET_assert (NULL != cls);
 
262
  peer2.bytes_read = 0;
 
263
  GNUNET_STREAM_listen_close (peer2_listen_socket); /* Close listen socket */
 
264
  peer2.io_handle = GNUNET_STREAM_read ((struct GNUNET_STREAM_Socket *) cls,
 
265
                                        GNUNET_TIME_relative_multiply
 
266
                                        (GNUNET_TIME_UNIT_SECONDS, 5),
 
267
                                        &input_processor,
 
268
                                        (void *) &peer2);
 
269
  GNUNET_assert (NULL != peer2.io_handle);
 
270
}
 
271
 
 
272
 
 
273
/**
 
274
 * Functions of this type are called upon new stream connection from other peers
 
275
 *
 
276
 * @param cls the closure from GNUNET_STREAM_listen
 
277
 * @param socket the socket representing the stream
 
278
 * @param initiator the identity of the peer who wants to establish a stream
 
279
 *            with us
 
280
 * @return GNUNET_OK to keep the socket open, GNUNET_SYSERR to close the
 
281
 *             stream (the socket will be invalid after the call)
 
282
 */
 
283
static int
 
284
stream_listen_cb (void *cls,
 
285
           struct GNUNET_STREAM_Socket *socket,
 
286
           const struct GNUNET_PeerIdentity *initiator)
 
287
{
 
288
  GNUNET_assert (NULL != socket);
 
289
  GNUNET_assert (NULL == initiator);   /* Local peer=NULL? */
 
290
  GNUNET_assert (socket != peer1.socket);
 
291
 
 
292
  peer2.socket = socket;
 
293
  read_task = GNUNET_SCHEDULER_add_now (&stream_read, (void *) socket);
 
294
  return GNUNET_OK;
 
295
}
 
296
 
 
297
 
 
298
/**
 
299
 * Testing function
 
300
 */
 
301
static void
 
302
test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 
303
{
 
304
  test_task = GNUNET_SCHEDULER_NO_TASK;
 
305
 
 
306
  /* Connect to stream library */
 
307
  peer1.socket = GNUNET_STREAM_open (NULL,         /* Null for local peer? */
 
308
                                     10,           /* App port */
 
309
                                     &stream_open_cb,
 
310
                                     (void *) &peer1);
 
311
  GNUNET_assert (NULL != peer1.socket);
 
312
  peer2_listen_socket = GNUNET_STREAM_listen (10 /* App port */
 
313
                                              &stream_listen_cb,
 
314
                                              NULL);
 
315
  GNUNET_assert (NULL != peer2_listen_socket);
 
316
                  
 
317
}
 
318
 
 
319
/**
 
320
 * Initialize framework and start test
 
321
 */
 
322
static void
 
323
run (void *cls, char *const *args, const char *cfgfile,
 
324
     const struct GNUNET_CONFIGURATION_Handle *cfg)
 
325
{
 
326
   GNUNET_log_setup ("test_stream_local",
 
327
#if VERBOSE
 
328
                    "DEBUG",
 
329
#else
 
330
                    "WARNING",
 
331
#endif
 
332
                    NULL);
 
333
   arm_pid =
 
334
     GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
 
335
                              "gnunet-service-arm",
 
336
#if VERBOSE_ARM
 
337
                              "-L", "DEBUG",
 
338
#endif
 
339
                              "-c", "test_stream_local.conf", NULL);
 
340
 
 
341
   abort_task =
 
342
     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
 
343
                                   (GNUNET_TIME_UNIT_SECONDS, 20), &do_abort,
 
344
                                    NULL);
 
345
 
 
346
   test_task = GNUNET_SCHEDULER_add_now (&test, (void *) cfg);
 
347
 
 
348
}
 
349
 
 
350
/**
 
351
 * Main function
 
352
 */
 
353
int main (int argc, char **argv)
 
354
{
 
355
  int ret;
 
356
 
 
357
  char *const argv2[] = { "test-stream-local",
 
358
                          "-c", "test_stream.conf",
 
359
#if VERBOSE
 
360
                          "-L", "DEBUG",
 
361
#endif
 
362
                          NULL
 
363
  };
 
364
  
 
365
  struct GNUNET_GETOPT_CommandLineOption options[] = {
 
366
    GNUNET_GETOPT_OPTION_END
 
367
  };
 
368
  
 
369
  ret =
 
370
      GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
 
371
                          "test-stream-local", "nohelp", options, &run, NULL);
 
372
 
 
373
  if (GNUNET_OK != ret)
 
374
  {
 
375
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "run failed with error code %d\n",
 
376
                ret);
 
377
    return 1;
 
378
  }
 
379
  if (GNUNET_SYSERR == result)
 
380
  {
 
381
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "test failed\n");
 
382
    return 1;
 
383
  }
 
384
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test ok\n");
 
385
  return 0;
 
386
}