GNUnet debian-0.24.3-23-g589b01d60
testing_core_cmd_connect.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 2024 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 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_testing_lib.h"
32#include "gnunet_core_service.h"
33
34
35//#define NUM_MESSAGES 10
36//#define NUM_CHANNELS 2
37//
38#define MTYPE 12345
39
43#define LOG(kind, ...) \
44 GNUNET_log_from (kind, "testing-core-connect", __VA_ARGS__)
45
46
47static void
49{
50 struct GNUNET_TESTING_CORE_Channel *channel = cls;
51
53 "Received message (%" PRIu64 ", %" PRIu64 ", %s) - going to call handlers\n",
54 GNUNET_ntohll (msg->id),
55 GNUNET_ntohll (msg->batch),
56 msg->node_id);
57 LOG (GNUNET_ERROR_TYPE_DEBUG, " (We: %s)\n", channel->connect_state->node_id);
58
59 if (0 == strncmp (msg->node_id, channel->connect_state->node_id, NODE_ID_LEN))
61 "We received a message from ourself!\n");
62
63 for (uint32_t i = 0; i < channel->connect_state->recv_handlers_len; i++)
64 {
65 if (NULL == channel->connect_state->recv_handlers[i]) continue;
66 // FIXME: set cls per handler
67 channel->connect_state->recv_handlers[i] (
69 channel,
70 msg);
71 }
72
73 // FIXME do we need to call something like the below?
74 //GNUNET_CORE_UNDERLAY_DUMMY_receive_continue (channel->connect_state->h,
75 // channel->mq);
76}
77
78
83connect_traits (void *cls,
84 const void **ret,
85 const char *trait,
86 unsigned int index)
87{
88 struct GNUNET_TESTING_CORE_ConnectState *connect_state = cls;
89 struct GNUNET_TESTING_Trait traits[] = {
92 };
93
95 ret,
96 trait,
97 index);
98}
99
100
101static void
103 void *cls,
104 const struct GNUNET_PeerIdentity *my_identity)
105{
106 struct GNUNET_TESTING_CORE_ConnectState *connect_state = cls;
108 "Connected to core, own pid: %s\n",
110 GNUNET_memcpy (&connect_state->peer_id, my_identity, sizeof (struct GNUNET_PeerIdentity));
111 GNUNET_TESTING_async_finish (&connect_state->ac);
112 // TODO we could finish connect at the first incoming connection
113}
114
115
116static void *
118 void *cls,
119 const struct GNUNET_PeerIdentity *peer_id,
120 struct GNUNET_MQ_Handle *mq,
121 enum GNUNET_CORE_PeerClass class)
122{
123 struct GNUNET_TESTING_CORE_ConnectState *connect_state = cls;
124 struct GNUNET_TESTING_CORE_Channel *channel;
125 (void) class; // unused
126
128 "A new connection was established with peer %s\n",
131 " (us: %s)\n",
134 "size of connect_state: %lu of channel: %lu\n",
135 sizeof (struct GNUNET_TESTING_CORE_ConnectState),
136 sizeof (struct GNUNET_TESTING_CORE_Channel));
138 "memcmp: %u\n",
142 " (That's us - connection was established to ourself)\n");
143
144 channel = GNUNET_new (struct GNUNET_TESTING_CORE_Channel);
145 channel->connect_state = connect_state;
146 channel->mq = mq;
147 GNUNET_memcpy (&channel->peer_id, peer_id, sizeof (struct GNUNET_PeerIdentity));
149 {
151 "Inserting channel into list\n");
152 if ((NULL != connect_state->channels_head) &&
153 (NULL != connect_state->channels_tail))
154 {
156 "Peer at list head: %s\n",
159 "Peer at list tail: %s\n",
161 }
162 else
163 {
165 "empty list\n");
166 }
169 channel);
170 }
171
172 /* Call connect handlers from test */
174 for (uint32_t i = 0; i < connect_state->connect_cbs_len; i++)
175 {
176 // TODO check if we really want to pass everything as-is
177 struct GNUNET_TESTING_CORE_ConnectCb *connect_cb_struct =
178 &connect_state->connect_cbs[i];
179 // FIXME this might return something, but the implemented function also
180 // returns nothing
181 connect_cb_struct->callback (connect_cb_struct->cls,
182 peer_id,
183 mq);
184 }
185
186 //if ((connect_state->num_channels_target == connect_state->channels_len) &&
187 // (GNUNET_NO == connect_state->finished))
188 //{
189 // LOG (GNUNET_ERROR_TYPE_DEBUG, "(post connect_cb _async_finish)\n");
190 // GNUNET_TESTING_async_finish (&connect_state->ac);
191 // connect_state->finished = GNUNET_YES;
192 //}
193 //LOG (GNUNET_ERROR_TYPE_DEBUG,
194 // "(post connect_cb - %u of %u)\n",
195 // connect_state->channels_len,
196 // connect_state->num_channels_target);
197
198 return channel;
199}
200
201
202static void
204 void *cls,
205 const struct GNUNET_PeerIdentity *peer,
206 void *peer_cls)
207{
208 struct GNUNET_TESTING_CORE_ConnectState *connect_state = cls;
209 struct GNUNET_TESTING_CORE_Channel *channel = peer_cls;
210
211 LOG (GNUNET_ERROR_TYPE_DEBUG, "from notify_disconnect_cb()\n");
213 "Channel from peer %s (peer_cls) disconnects\n",
214 GNUNET_i2s (&channel->peer_id));
216 " %s (arg)\n",
217 GNUNET_i2s (peer));
219 " (we are %s)\n",
226 //if (NULL != channel->next)
227 if (0 != GNUNET_memcmp (&connect_state->peer_id, peer))
228 {
229 /* this channel might not be in the list */
230 LOG (GNUNET_ERROR_TYPE_DEBUG, "removing channel from list\n");
233 channel);
234 }
235 GNUNET_free (channel);
236}
237
238
239static void
242{
243 struct GNUNET_TESTING_CORE_ConnectState *connect_state = cls;
244 const struct GNUNET_TESTING_Command *arm_cmd;
246 {
249 };
250 const struct GNUNET_CORE_ServiceInfo service_info =
251 {
253 .version = { 1, 0 },
254 .version_max = { 1, 0 },
255 .version_min = { 1, 0 },
256 };
257
259 "(%s) Going to connect to core\n",
260 connect_state->node_id);
261
263 is,
264 connect_state->arm_service_label);
265 if (NULL == arm_cmd)
267 if (GNUNET_OK !=
268 GNUNET_TESTING_ARM_get_trait_config (
269 arm_cmd,
270 &connect_state->cfg))
272
273 connect_state->h = GNUNET_CORE_connect (connect_state->cfg,
274 connect_state, // cls
275 init_cb,
278 handlers,
279 &service_info);
280
281}
282
283
284static void
286{
287 struct GNUNET_TESTING_CORE_ConnectState *connect_state = cls;
288
289 GNUNET_assert (NULL != connect_state->h);
290 GNUNET_CORE_disconnect (connect_state->h);
291 // TODO cleanup!
292}
293
294
295
296const struct GNUNET_TESTING_Command
298 const char *label,
299 const char* node_id,
300 char *arm_service_label)
301{
302 struct GNUNET_TESTING_CORE_ConnectState *connect_state;
303
304 // TODO get handler from caller to call on new connections
305
306 connect_state = GNUNET_new (struct GNUNET_TESTING_CORE_ConnectState);
307 connect_state->node_id = GNUNET_strdup (node_id);
309 connect_state->recv_handlers_len = 0;
310 connect_state->recv_handlers =
311 GNUNET_new_array (connect_state->recv_handlers_len,
313 connect_state->connect_cbs_len = 0;
314 connect_state->connect_cbs =
315 GNUNET_new_array (connect_state->connect_cbs_len,
317 connect_state->finished = GNUNET_NO;
318 LOG (GNUNET_ERROR_TYPE_DEBUG, "(Setting up _cmd_connect)\n");
319 return GNUNET_TESTING_command_new_ac ( // TODO make this sync?
320 connect_state, // state
321 label,
325 &connect_state->ac); // TODO make this sync?
326}
327
328
329/* end of src/service/core/testing_core_connect.c */
struct GNUNET_MQ_MessageHandlers handlers[]
Definition: 003.c:1
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static int ret
Final status code.
Definition: gnunet-arm.c:93
static char * peer_id
Option –peer.
Definition: gnunet-cadet.c:42
static struct GNUNET_TESTING_Interpreter * is
struct GNUNET_PeerIdentity my_identity
Our peer identity.
Core service; the main API for encrypted P2P communications.
struct GNUNET_TESTING_Trait GNUNET_CORE_TESTING_make_trait_connect(const struct GNUNET_TESTING_CORE_ConnectState *value)
void(* GNUNET_TESTING_CORE_handle_msg)(void *cls, struct GNUNET_TESTING_CORE_Channel *channel, const struct GNUNET_TESTING_CORE_Message *msg)
#define NODE_ID_LEN
struct GNUNET_TESTING_Command GNUNET_TESTING_command_new_ac(void *cls, const char *label, GNUNET_TESTING_CommandRunRoutine run, GNUNET_TESTING_CommandCleanupRoutine cleanup, GNUNET_TESTING_CommandGetTraits traits, struct GNUNET_TESTING_AsyncContext *ac)
Create a new command that may be asynchronous.
void GNUNET_TESTING_async_finish(struct GNUNET_TESTING_AsyncContext *ac)
The asynchronous command of ac has finished.
#define GNUNET_TESTING_FAIL(is)
Print failing line number and trigger shutdown.
const struct GNUNET_TESTING_Command * GNUNET_TESTING_interpreter_lookup_command(struct GNUNET_TESTING_Interpreter *is, const char *label)
Lookup command by label.
struct GNUNET_TESTING_Trait GNUNET_TESTING_trait_end(void)
"end" of traits array.
enum GNUNET_GenericReturnValue GNUNET_TESTING_get_trait(const struct GNUNET_TESTING_Trait *traits, const void **ret, const char *trait, unsigned int index)
Obtain value of a trait from a command.
GNUNET_CORE_PeerClass
The peer class gives a hint about the capabilities of a peer.
struct GNUNET_CORE_Handle * GNUNET_CORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls, GNUNET_CORE_StartupCallback init, GNUNET_CORE_ConnectEventHandler connects, GNUNET_CORE_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers, struct GNUNET_CORE_ServiceInfo *service_info)
Connect to the core service.
Definition: core_api.c:698
void GNUNET_CORE_disconnect(struct GNUNET_CORE_Handle *handle)
Disconnect from the core service.
Definition: core_api.c:744
@ GNUNET_CORE_SERVICE_TEST
Identifier for testing the api.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:54
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_NO
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
Gnunet service info - identifying compatibility with a range of version of a service communicating ov...
enum GNUNET_CORE_Service service
Identifier of the service on top of CORE.
Handle to a message queue.
Definition: mq.c:87
Message handler for a specific message type.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_MQ_Handle * mq
struct GNUNET_TESTING_CORE_ConnectState * connect_state
struct GNUNET_PeerIdentity peer_id
GNUNET_TESTING_CORE_connect_cb callback
struct GNUNET_TESTING_CORE_ConnectCb * connect_cbs
Connect callback TODO we probably only need a single one.
GNUNET_TESTING_CORE_handle_msg * recv_handlers
Receive callback.
struct GNUNET_TESTING_AsyncContext ac
struct GNUNET_TESTING_CORE_Channel * channels_tail
struct GNUNET_TESTING_CORE_Channel * channels_head
enum GNUNET_GenericReturnValue finished
const struct GNUNET_CONFIGURATION_Handle * cfg
A command to be run by the interpreter.
struct GNUNET_TESTING_CommandLabel label
Label for the command.
Global state of the interpreter, used by a command to access information about other commands.
A struct GNUNET_TESTING_Trait can be used to exchange data between cmds.
unsigned int index
Index number associated with the trait.
static enum GNUNET_GenericReturnValue traits(void *cls, const void **ret, const char *trait, unsigned int index)
This function prepares an array with traits.
static void exec_connect_run(void *cls, struct GNUNET_TESTING_Interpreter *is)
static void * connect_cb(void *cls, const struct GNUNET_PeerIdentity *peer_id, struct GNUNET_MQ_Handle *mq, enum GNUNET_CORE_PeerClass class)
const struct GNUNET_TESTING_Command GNUNET_TESTING_CORE_cmd_connect(const char *label, const char *node_id, char *arm_service_label)
static void init_cb(void *cls, const struct GNUNET_PeerIdentity *my_identity)
#define MTYPE
static void exec_connect_cleanup(void *cls)
static void disconnect_cb(void *cls, const struct GNUNET_PeerIdentity *peer, void *peer_cls)
static enum GNUNET_GenericReturnValue connect_traits(void *cls, const void **ret, const char *trait, unsigned int index)
This function prepares an array with traits.
#define LOG(kind,...)
Generic logging shortcut.
static void handle_test(void *cls, const struct GNUNET_TESTING_CORE_Message *msg)