6b5c433b767c23bbf2b332b95de0eb35e6080d5b
[oweals/gnunet.git] / src / peerinfo / test_peerinfo_api_notify_friend_only.c
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2004, 2009 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 /**
20  * @file peerinfo/test_peerinfo_api_notify_friend_only.c
21  * @brief testcase friend only HELLO restrictions in for peerinfo
22  * @author Christian Grothoff
23  * @author Matthias Wachs
24  *
25  * TODO:
26  * - test merging of HELLOs (add same peer twice...)
27  */
28 #include "platform.h"
29 #include "gnunet_hello_lib.h"
30 #include "gnunet_util_lib.h"
31 #include "gnunet_peerinfo_service.h"
32 #include "gnunet_testing_lib.h"
33 #include "peerinfo.h"
34
35 #define TIMEOUT  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
36
37 static struct GNUNET_PEERINFO_Handle *h;
38 static struct GNUNET_PEERINFO_NotifyContext *pnc_w_fo;
39 static struct GNUNET_PEERINFO_NotifyContext *pnc_wo_fo;
40
41 static const struct GNUNET_CONFIGURATION_Handle *mycfg;
42
43 static int global_ret;
44
45 /**
46  * Did we get a HELLO callback for notification handle with friend HELLOS
47  * (expected)
48  */
49 static int res_cb_w_fo;
50
51 /**
52  * Did we get a HELLO callback for notification handle without friend HELLOS
53  * (not expected)
54  */
55 static int res_cb_wo_fo;
56
57 struct GNUNET_PeerIdentity pid;
58
59 struct GNUNET_SCHEDULER_Task *timeout_task;
60
61 static void
62 end_badly (void *cls)
63 {
64   timeout_task = NULL;
65   GNUNET_break(0);
66   if (NULL != pnc_wo_fo)
67   {
68     GNUNET_PEERINFO_notify_cancel (pnc_wo_fo);
69     pnc_wo_fo = NULL;
70   }
71   if (NULL != pnc_w_fo)
72   {
73     GNUNET_PEERINFO_notify_cancel (pnc_w_fo);
74     pnc_w_fo = NULL;
75   }
76   if (NULL != h)
77   {
78     GNUNET_PEERINFO_disconnect (h);
79     h = NULL;
80   }
81   global_ret = 255;
82 }
83
84
85 static void
86 done (void *cls)
87 {
88   if (NULL != pnc_w_fo)
89     GNUNET_PEERINFO_notify_cancel (pnc_w_fo);
90   pnc_w_fo = NULL;
91   if (NULL != pnc_wo_fo)
92     GNUNET_PEERINFO_notify_cancel (pnc_wo_fo);
93   pnc_wo_fo = NULL;
94   GNUNET_PEERINFO_disconnect (h);
95   h = NULL;
96
97   if (NULL != timeout_task)
98   {
99     GNUNET_SCHEDULER_cancel (timeout_task);
100     timeout_task = NULL;
101   }
102
103   if ((GNUNET_YES == res_cb_w_fo) && (GNUNET_NO == res_cb_wo_fo))
104     global_ret = 0;
105   else
106     GNUNET_break(0);
107 }
108
109 static ssize_t
110 address_generator (void *cls, size_t max, void *buf)
111 {
112   size_t *agc = cls;
113   ssize_t ret;
114   struct GNUNET_HELLO_Address address;
115
116   if (0 == *agc)
117     return GNUNET_SYSERR; /* Done */
118   memset (&address.peer, 0, sizeof(struct GNUNET_PeerIdentity));
119   address.address = "Address";
120   address.transport_name = "peerinfotest";
121   address.address_length = *agc;
122   ret = GNUNET_HELLO_add_address (&address,
123       GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_HOURS), buf, max);
124   (*agc)--;
125   return ret;
126 }
127
128
129 static void
130 process_w_fo (void *cls,
131               const struct GNUNET_PeerIdentity *peer,
132               const struct GNUNET_HELLO_Message *hello,
133               const char *err_msg)
134 {
135   if (err_msg != NULL)
136   {
137     GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
138         _("Error in communication with PEERINFO service\n"));
139     GNUNET_SCHEDULER_add_now (&done, NULL);
140     return;
141   }
142
143   if (NULL != peer)
144   {
145     GNUNET_log(GNUNET_ERROR_TYPE_INFO,
146         "Received callback for peer `%s' %s HELLO\n", GNUNET_i2s (peer),
147         (NULL != hello) ? "with" : "without");
148
149     if (NULL == hello)
150       return;
151
152     if (GNUNET_NO == GNUNET_HELLO_is_friend_only (hello))
153     {
154       GNUNET_break(0);
155       return;
156     }
157
158     GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Received %s HELLO for peer `%s'\n",
159         (GNUNET_YES == GNUNET_HELLO_is_friend_only (hello)) ? "friend only" : "public",
160         GNUNET_i2s (peer));
161     if (0 == memcmp (&pid, peer, sizeof(pid)))
162     {
163       res_cb_w_fo = GNUNET_YES;
164       GNUNET_SCHEDULER_add_now (&done, NULL);
165     }
166     return;
167   }
168 }
169
170 static void
171 process_wo_fo (void *cls, const struct GNUNET_PeerIdentity *peer,
172     const struct GNUNET_HELLO_Message *hello, const char *err_msg)
173 {
174   if (err_msg != NULL)
175   {
176     GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
177         _("Error in communication with PEERINFO service\n"));
178     GNUNET_SCHEDULER_add_now (&done, NULL);
179     return;
180   }
181
182   if (NULL != peer)
183   {
184     GNUNET_log(GNUNET_ERROR_TYPE_INFO,
185         "Received callback for peer `%s' %s HELLO\n", GNUNET_i2s (peer),
186         (NULL != hello) ? "with" : "without");
187
188     if (NULL == hello)
189       return;
190
191     if (GNUNET_YES == GNUNET_HELLO_is_friend_only (hello))
192     {
193       GNUNET_break(0);
194       return;
195     }
196
197     GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Received %s HELLO for peer `%s'\n",
198         (GNUNET_YES == GNUNET_HELLO_is_friend_only (hello)) ? "friend only" : "public",
199         GNUNET_i2s (peer));
200     if (0 == memcmp (&pid, peer, sizeof(pid)))
201     {
202       GNUNET_break(0);
203       res_cb_wo_fo = GNUNET_YES;
204     }
205   }
206 }
207
208
209 static void
210 add_peer ()
211 {
212   struct GNUNET_HELLO_Message *h2;
213   size_t agc;
214
215   agc = 2;
216   memset (&pid, 32, sizeof(pid));
217   h2 = GNUNET_HELLO_create (&pid.public_key, &address_generator, &agc,
218                             GNUNET_YES);
219   GNUNET_PEERINFO_add_peer (h, h2, NULL, NULL);
220   GNUNET_free(h2);
221 }
222
223
224 static void
225 run (void *cls,
226      const struct GNUNET_CONFIGURATION_Handle *cfg,
227      struct GNUNET_TESTING_Peer *peer)
228 {
229   timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
230   mycfg = cfg;
231   pnc_w_fo = GNUNET_PEERINFO_notify (mycfg, GNUNET_YES, &process_w_fo, NULL);
232   pnc_wo_fo = GNUNET_PEERINFO_notify (mycfg, GNUNET_NO, &process_wo_fo, NULL);
233   h = GNUNET_PEERINFO_connect (cfg);
234   GNUNET_assert(NULL != h);
235   add_peer ();
236 }
237
238
239 int
240 main (int argc, char *argv[])
241 {
242   res_cb_w_fo = GNUNET_NO;
243   res_cb_wo_fo = GNUNET_NO;
244   global_ret = 3;
245   if (0 != GNUNET_TESTING_service_run ("test-peerinfo-api-friend-only",
246                                        "peerinfo",
247                                        "test_peerinfo_api_data.conf",
248                                        &run, NULL))
249     return 1;
250   return global_ret;
251 }
252
253 /* end of test_peerinfo_api_notify_friend_only.c */