GNUnet  0.11.x
gnunet-service-messenger.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2020 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  */
27 
29 #include "messenger_api_message.h"
30 
32 {
35 };
36 
38 
39 static int
41 {
43  return GNUNET_OK;
44 }
45 
46 static void
48 {
49  struct GNUNET_MESSENGER_Client *msg_client = cls;
50 
51  const char *name = ((const char*) msg) + sizeof(*msg);
52 
53  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Handle created with name: %s\n", name);
54 
55  setup_handle_name (msg_client->handle, strlen (name) > 0? name : NULL);
56 
58 }
59 
60 static void
62 {
63  struct GNUNET_MESSENGER_Client *msg_client = cls;
64 
65  if (GNUNET_OK != update_handle (msg_client->handle))
66  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Name is required to update key!\n");
67 
69 }
70 
71 static void
73 {
74  struct GNUNET_MESSENGER_Client *msg_client = cls;
75 
76  GNUNET_SERVICE_client_drop (msg_client->client);
77 }
78 
79 static int
81 {
83  return GNUNET_OK;
84 }
85 
86 static void
88 {
89  struct GNUNET_MESSENGER_Client *msg_client = cls;
90 
91  const char *name = ((const char*) msg) + sizeof(*msg);
92 
93  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Handles name is now: %s\n", name);
94 
95  if (GNUNET_YES != set_handle_name (msg_client->handle, name))
96  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "No valid name: %s\n", name);
97 
99 }
100 
101 static void
103 {
104  struct GNUNET_MESSENGER_Client *msg_client = cls;
105 
106  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Opening room: %s\n",
107  GNUNET_h2s (&(msg->key)));
108 
109  if (GNUNET_YES == open_handle_room (msg_client->handle, &(msg->key)))
110  {
111  const struct GNUNET_ShortHashCode* member_id = get_handle_member_id(msg_client->handle, &(msg->key));
112 
113  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Opening room with member id: %s\n",
114  GNUNET_sh2s (member_id));
115 
117  struct GNUNET_MQ_Envelope *env;
118 
120  GNUNET_memcpy(&(response->key), &(msg->key), sizeof(msg->key));
121  GNUNET_MQ_send (msg_client->handle->mq, env);
122  }
123  else
124  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Opening room failed: %s\n",
125  GNUNET_h2s (&(msg->key)));
126 
128 }
129 
130 static void
132 {
133  struct GNUNET_MESSENGER_Client *msg_client = cls;
134 
135  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Entering room: %s, %s\n",
136  GNUNET_h2s (&(msg->key)), GNUNET_i2s (&(msg->door)));
137 
138  if (GNUNET_YES == entry_handle_room (msg_client->handle, &(msg->door), &(msg->key)))
139  {
140  const struct GNUNET_ShortHashCode* member_id = get_handle_member_id(msg_client->handle, &(msg->key));
141 
142  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Entering room with member id: %s\n",
143  GNUNET_sh2s (member_id));
144 
146  struct GNUNET_MQ_Envelope *env;
147 
149  GNUNET_memcpy(&(response->door), &(msg->door), sizeof(msg->door));
150  GNUNET_memcpy(&(response->key), &(msg->key), sizeof(msg->key));
151  GNUNET_MQ_send (msg_client->handle->mq, env);
152  }
153  else
154  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Entrance into room failed: %s, %s\n",
155  GNUNET_h2s (&(msg->key)), GNUNET_i2s (&(msg->door)));
156 
158 }
159 
160 static void
162 {
163  struct GNUNET_MESSENGER_Client *msg_client = cls;
164 
165  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Closing room: %s\n", GNUNET_h2s (&(msg->key)));
166 
167  if (GNUNET_YES == close_handle_room (msg_client->handle, &(msg->key)))
168  {
169  const struct GNUNET_ShortHashCode* member_id = get_handle_member_id(msg_client->handle, &(msg->key));
170 
171  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Closing room with member id: %s\n",
172  GNUNET_sh2s (member_id));
173 
175  struct GNUNET_MQ_Envelope *env;
176 
178  GNUNET_memcpy(&(response->key), &(msg->key), sizeof(msg->key));
179  GNUNET_MQ_send (msg_client->handle->mq, env);
180  }
181  else
182  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Closing room failed: %s\n", GNUNET_h2s (&(msg->key)));
183 
185 }
186 
187 static int
189 {
190  const uint16_t full_length = ntohs (msg->header.size) - sizeof(msg->header);
191 
192  if (full_length < sizeof(msg->key))
193  return GNUNET_NO;
194 
195  const uint16_t length = full_length - sizeof(msg->key);
196  const char *buffer = ((const char*) msg) + sizeof(*msg);
197 
198  struct GNUNET_MESSENGER_Message message;
199 
200  if (GNUNET_YES != decode_message (&message, length, buffer))
201  return GNUNET_NO;
202 
203  return GNUNET_OK;
204 }
205 
206 static void
208 {
209  struct GNUNET_MESSENGER_Client *msg_client = cls;
210 
211  const struct GNUNET_HashCode *key = &(msg->key);
212  const char *buffer = ((const char*) msg) + sizeof(*msg);
213 
214  const uint16_t length = ntohs (msg->header.size) - sizeof(*msg);
215 
216  struct GNUNET_MESSENGER_Message message;
217  decode_message (&message, length, buffer);
218 
219  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending message: %s to %s\n",
221  GNUNET_h2s (key));
222 
223  if (GNUNET_YES != send_handle_message (msg_client->handle, key, &message))
224  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Sending message failed: %s to %s\n",
226  GNUNET_h2s (key));
227 
229 }
230 
231 static void
233 {
234  struct GNUNET_MESSENGER_Client *msg_client = cls;
235 
236  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Requesting message from room: %s\n",
237  GNUNET_h2s (&(msg->key)));
238 
239  struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (messenger, &(msg->key));
240 
241  if (room)
242  get_room_message (room, msg_client->handle, &(msg->hash), GNUNET_YES);
243  else
244  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Room not found: %s\n",
245  GNUNET_h2s (&(msg->key)));
246 
248 }
249 
250 static void*
252 {
253  struct GNUNET_MESSENGER_Client *msg_client = GNUNET_new(struct GNUNET_MESSENGER_Client);
254 
255  msg_client->client = client;
256  msg_client->handle = add_service_handle (messenger, mq);
257 
258  return msg_client;
259 }
260 
261 static void
262 callback_client_disconnect (void *cls, struct GNUNET_SERVICE_Client *client, void *internal_cls)
263 {
264  struct GNUNET_MESSENGER_Client *msg_client = internal_cls;
265 
266  remove_service_handle (messenger, msg_client->handle);
267 
268  GNUNET_free(msg_client);
269 }
270 
278 static void
280 {
281  messenger = create_service (config, service);
282 
283  if ((!messenger) || (!messenger->cadet) || (!messenger->identity))
285 }
286 
293  &run,
296  NULL,
int decode_message(struct GNUNET_MESSENGER_Message *message, uint16_t length, const char *buffer)
Decodes a message from a given buffer of a maximal length in bytes.
struct GNUNET_MESSENGER_MessageHeader header
Header.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static void callback_client_disconnect(void *cls, struct GNUNET_SERVICE_Client *client, void *internal_cls)
struct GNUNET_CADET_Handle * cadet
GNUnet MESSENGER service.
static void handle_room_entry(void *cls, const struct GNUNET_MESSENGER_RoomMessage *msg)
#define GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_UPDATE
void setup_handle_name(struct GNUNET_MESSENGER_SrvHandle *handle, const char *name)
Tries to set the name and EGO key of a handle initially by looking up a specific name.
Handle to a service.
Definition: service.c:116
static void handle_room_open(void *cls, const struct GNUNET_MESSENGER_RoomMessage *msg)
struct GNUNET_SERVICE_Client * client
struct GNUNET_PeerIdentity door
static int check_set_name(void *cls, const struct GNUNET_MESSENGER_NameMessage *msg)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_CREATE
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *config, struct GNUNET_SERVICE_Handle *service)
Setup MESSENGER internals.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static int check_create(void *cls, const struct GNUNET_MESSENGER_CreateMessage *msg)
#define GNUNET_new(type)
Allocate a struct or union of the given type.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:531
struct GNUNET_MESSENGER_SrvHandle * add_service_handle(struct GNUNET_MESSENGER_Service *service, struct GNUNET_MQ_Handle *mq)
Creates and adds a new handle to a service using a given message queue.
struct GNUNET_MESSENGER_Service * messenger
static void handle_destroy(void *cls, const struct GNUNET_MESSENGER_DestroyMessage *msg)
A 256-bit hashcode.
Handle to a client that is connected to a service.
Definition: service.c:250
int send_handle_message(struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key, struct GNUNET_MESSENGER_Message *message)
Sends a message from a given handle to the room using a specific key.
Message to send something into a room.
struct GNUNET_MessageHeader header
#define GNUNET_MQ_check_zero_termination(m)
Insert code for a "check_" function that verifies that a given variable-length message received over ...
int open_handle_room(struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key)
Makes a given handle a member of the room using a specific key and opens the room from the handles se...
static int check_send_message(void *cls, const struct GNUNET_MESSENGER_SendMessage *msg)
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
static void handle_update(void *cls, const struct GNUNET_MESSENGER_UpdateMessage *msg)
Message to create a handle for a client.
int close_handle_room(struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key)
Removes the membership of the room using a specific key and closes it if no other handle from this se...
#define GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_SET_NAME
const char * GNUNET_MESSENGER_name_of_kind(enum GNUNET_MESSENGER_MessageKind kind)
Get the name of a message kind.
Definition: messenger_api.c:34
static const struct GNUNET_CONFIGURATION_Handle * config
#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE
static void handle_create(void *cls, const struct GNUNET_MESSENGER_CreateMessage *msg)
static void handle_get_message(void *cls, const struct GNUNET_MESSENGER_RecvMessage *msg)
struct GNUNET_MESSENGER_SrvRoom * get_service_room(struct GNUNET_MESSENGER_Service *service, const struct GNUNET_HashCode *key)
Returns the room identified by a given key for a service.
A 512-bit hashcode.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2325
static void handle_send_message(void *cls, const struct GNUNET_MESSENGER_SendMessage *msg)
struct GNUNET_HashCode key
The key used in the DHT.
static const char * get_message(void **buf, int *len, void *cls)
void remove_service_handle(struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle)
Removes a handle from a service and destroys it.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
Message to update the handle (its EGO key) for a client.
Message to destroy the handle for a client.
#define GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_DESTROY
#define GNUNET_MESSENGER_SERVICE_NAME
const struct GNUNET_MESSENGER_Message * get_room_message(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *hash, int request)
Returns a message from a room identified by a given hash.
Handle to a message queue.
Definition: mq.c:85
#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE
int set_handle_name(struct GNUNET_MESSENGER_SrvHandle *handle, const char *name)
Tries to rename the handle which implies renaming the EGO its using and moving all related data into ...
int update_handle(struct GNUNET_MESSENGER_SrvHandle *handle)
Tries to change the keypair of an EGO of a handle under the same name and informs all rooms about the...
#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN
#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE
configuration data
Definition: configuration.c:84
const char * name
Message to receive the current name of a handle.
GNUNET_SERVICE_MAIN(GNUNET_MESSENGER_SERVICE_NAME, GNUNET_SERVICE_OPTION_NONE, &run, &callback_client_connect, &callback_client_disconnect, NULL, GNUNET_MQ_hd_var_size(create, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_CREATE, struct GNUNET_MESSENGER_CreateMessage, NULL), GNUNET_MQ_hd_fixed_size(update, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_UPDATE, struct GNUNET_MESSENGER_UpdateMessage, NULL), GNUNET_MQ_hd_fixed_size(destroy, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_DESTROY, struct GNUNET_MESSENGER_DestroyMessage, NULL), GNUNET_MQ_hd_var_size(set_name, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_SET_NAME, struct GNUNET_MESSENGER_NameMessage, NULL), GNUNET_MQ_hd_fixed_size(room_open, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN, struct GNUNET_MESSENGER_RoomMessage, NULL), GNUNET_MQ_hd_fixed_size(room_entry, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY, struct GNUNET_MESSENGER_RoomMessage, NULL), GNUNET_MQ_hd_fixed_size(room_close, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE, struct GNUNET_MESSENGER_RoomMessage, NULL), GNUNET_MQ_hd_var_size(send_message, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE, struct GNUNET_MESSENGER_SendMessage, NULL), GNUNET_MQ_hd_fixed_size(get_message, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE, struct GNUNET_MESSENGER_RecvMessage, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
static struct MHD_Response * response
Our canonical response.
static void send_message(struct PeerContext *peer_ctx, struct GNUNET_MQ_Envelope *ev, const char *type)
Send a message to another peer.
#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY
const struct GNUNET_ShortHashCode * get_handle_member_id(const struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key)
Returns the member id of a given handle in a specific room.
struct GNUNET_MESSENGER_Service * create_service(const struct GNUNET_CONFIGURATION_Handle *config, struct GNUNET_SERVICE_Handle *service_handle)
Creates and allocates a new service using a given config and a GNUnet service handle.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
static void handle_room_close(void *cls, const struct GNUNET_MESSENGER_RoomMessage *msg)
static void destroy(void *cls)
static void handle_set_name(void *cls, const struct GNUNET_MESSENGER_NameMessage *msg)
int entry_handle_room(struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_PeerIdentity *door, const struct GNUNET_HashCode *key)
Makes a given handle a member of the room using a specific key and enters the room through a tunnel t...
Message to receive something from a room.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2244
General message to confirm interaction with a room.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
struct GNUNET_MESSENGER_SrvHandle * handle
struct GNUNET_IDENTITY_Handle * identity
GNUnet MESSENGER service.
#define GNUNET_free(ptr)
Wrapper around free.
messenger api: client and service implementation of GNUnet MESSENGER service
enum GNUNET_MESSENGER_MessageKind kind
The kind of the message.
static void * callback_client_connect(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)