keep addr
[oweals/gnunet.git] / src / util / test_network.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009 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 2, 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  * @file util/test_network.c
22  * @brief tests for network.c
23  */
24 #include "platform.h"
25 #include "gnunet_common.h"
26 #include "gnunet_network_lib.h"
27 #include "gnunet_scheduler_lib.h"
28 #include "gnunet_time_lib.h"
29
30 #define VERBOSE GNUNET_NO
31
32 #define PORT 12435
33
34
35 static struct GNUNET_NETWORK_SocketHandle *csock;
36
37 static struct GNUNET_NETWORK_SocketHandle *asock;
38
39 static struct GNUNET_NETWORK_SocketHandle *lsock;
40
41 static size_t sofar;
42
43 static int ls;
44
45
46
47 /**
48  * Create and initialize a listen socket for the server.
49  *
50  * @return -1 on error, otherwise the listen socket
51  */
52 static int
53 open_listen_socket ()
54 {
55   const static int on = 1;
56   struct sockaddr_in sa;
57   int fd;
58
59   memset (&sa, 0, sizeof (sa));
60   sa.sin_port = htons (PORT);
61   fd = SOCKET (AF_INET, SOCK_STREAM, 0);
62   GNUNET_assert (fd >= 0);
63   if (SETSOCKOPT (fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
64     GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
65                 "setsockopt");
66   GNUNET_assert (BIND (fd, &sa, sizeof (sa)) >= 0);
67   LISTEN (fd, 5);
68   return fd;
69 }
70
71 static void
72 receive_check (void *cls,
73                const void *buf,
74                size_t available,
75                const struct sockaddr *addr, socklen_t addrlen, int errCode)
76 {
77   int *ok = cls;
78
79 #if VERBOSE
80   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receive validates incoming data\n");
81 #endif
82   GNUNET_assert (buf != NULL);  /* no timeout */
83   if (0 == memcmp (&"Hello World"[sofar], buf, available))
84     sofar += available;
85   if (sofar < 12)
86     {
87 #if VERBOSE
88       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receive needs more data\n");
89 #endif
90       GNUNET_NETWORK_receive (asock,
91                               1024,
92                               GNUNET_TIME_relative_multiply
93                               (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check,
94                               cls);
95     }
96   else
97     {
98 #if VERBOSE
99       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
100                   "Receive closes accepted socket\n");
101 #endif
102       *ok = 0;
103       GNUNET_NETWORK_socket_destroy (asock);
104     }
105 }
106
107
108 static void
109 run_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
110 {
111 #if VERBOSE
112   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test accepts connection\n");
113 #endif
114   asock = GNUNET_NETWORK_socket_create_from_accept (tc->sched,
115                                                     NULL, NULL, ls, 1024);
116   GNUNET_assert (asock != NULL);
117   GNUNET_assert (GNUNET_YES == GNUNET_NETWORK_socket_check (asock));
118 #if VERBOSE
119   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test destroys listen socket\n");
120 #endif
121   GNUNET_NETWORK_socket_destroy (lsock);
122 #if VERBOSE
123   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
124               "Test asks to receive on accepted socket\n");
125 #endif
126   GNUNET_NETWORK_receive (asock,
127                           1024,
128                           GNUNET_TIME_relative_multiply
129                           (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check, cls);
130 }
131
132 static size_t
133 make_hello (void *cls, size_t size, void *buf)
134 {
135 #if VERBOSE
136   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
137               "Test prepares to transmit on connect socket\n");
138 #endif
139   GNUNET_assert (size >= 12);
140   strcpy ((char *) buf, "Hello World");
141   return 12;
142 }
143
144 static void
145 task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
146 {
147   ls = open_listen_socket ();
148   lsock = GNUNET_NETWORK_socket_create_from_existing (tc->sched, ls, 0);
149   GNUNET_assert (lsock != NULL);
150   csock = GNUNET_NETWORK_socket_create_from_connect (tc->sched,
151                                                      "localhost", PORT, 1024);
152   GNUNET_assert (csock != NULL);
153 #if VERBOSE
154   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test asks for write notification\n");
155 #endif
156   GNUNET_assert (NULL !=
157                  GNUNET_NETWORK_notify_transmit_ready (csock,
158                                                        12,
159                                                        GNUNET_TIME_UNIT_SECONDS,
160                                                        &make_hello, NULL));
161 #if VERBOSE
162   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test destroys client socket\n");
163 #endif
164   GNUNET_NETWORK_socket_destroy (csock);
165 #if VERBOSE
166   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test prepares to accept\n");
167 #endif
168   GNUNET_SCHEDULER_add_read (tc->sched,
169                              GNUNET_NO,
170                              GNUNET_SCHEDULER_PRIORITY_HIGH,
171                              GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
172                              GNUNET_TIME_UNIT_FOREVER_REL,
173                              ls, &run_accept, cls);
174 }
175
176
177 /**
178  * Main method, starts scheduler with task ,
179  * checks that "ok" is correct at the end.
180  */
181 static int
182 check ()
183 {
184   int ok;
185
186   ok = 1;
187   GNUNET_SCHEDULER_run (&task, &ok);
188   return ok;
189 }
190
191
192
193 int
194 main (int argc, char *argv[])
195 {
196   int ret = 0;
197
198   GNUNET_log_setup ("test_network",
199 #if VERBOSE
200                     "DEBUG",
201 #else
202                     "WARNING",
203 #endif
204                     NULL);
205   ret += check ();
206   return ret;
207 }
208
209 /* end of test_network.c */