aboutsummaryrefslogtreecommitdiff
path: root/src/messenger/messenger_api_room.c
diff options
context:
space:
mode:
authorTheJackiMonster <thejackimonster@gmail.com>2020-11-01 22:57:28 +0100
committerTheJackiMonster <thejackimonster@gmail.com>2021-03-06 01:30:37 +0100
commit2925310d67483aca6e055e1ce0593c6463cd6c72 (patch)
tree2cc8aacafc25563cdccde2eee9a90f9ca257d405 /src/messenger/messenger_api_room.c
parent82b864a64679b0a735201724907cdf2b7e4e16c3 (diff)
downloadgnunet-2925310d67483aca6e055e1ce0593c6463cd6c72.tar.gz
gnunet-2925310d67483aca6e055e1ce0593c6463cd6c72.zip
-added core functionality of the messenger service
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> formatting messenger code Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -completed core functionality of messenger service Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -code cleanup and reuse Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> +added structure to memberships of rooms Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -implemented member permission checks and deletion of messages Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -moved solving requests out of updating last messages (also forward before update) Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -reduced complexity of permisson check and changed load/save of rooms Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -added save/load for accessed keys and basement peers of a room Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -implemented save/load for members with their history and session Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -abstracted management of egos and contacts Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -fix warning Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -abstracted management of members Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -fixed and adjusted test case Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -separated handling of direct and anonymous contacts Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -messenger added member-sessions which fix multiple edge cases, also additional cleanup Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -updated docs and fixed memory leak Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -changed info messages and added protocol version exchange Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -adjusted client api to use contacts from sessions Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -added more logging and fixed wrong session usage Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -adjusted comm0 test case and removed adding members from checking messages Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -fixed test-case for peer exchange Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -getting multiple peers connected in test-case with cadet Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -fixed wrong assert and added tunnel version check -simplified handling and forwarding Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -fixed merging last messages and cycling info messages Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -automated adding sessions and members Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -corrected use of identity keys and signatures Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -adding local joining on entering external room Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -fixed test-case comm0 Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -added more test-cases with generic setup Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -fixed multiple simultaneous channels blocking each other Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -making test-cases more precise Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -added check of members in test-cases, reduced merge messages Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -unified delayed operations: requests, deletions and merges Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -finished handling of operations Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -fixed member session historystorage, added request permission check and padding for transmission Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -improved padding and removed automatic recursive requests Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -implemented filter for sending messages and added private messages to API level Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -wrong setups fixed with proper ego lookups Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -fixed problem with anonymous ego and changed to discrete-level padding Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -added links to replace deleted messages, added local deletion and fixed anonymous id changing Signed-off-by: TheJackiMonster <thejackimonster@gmail.com> -added session completion and removal through completion process Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
Diffstat (limited to 'src/messenger/messenger_api_room.c')
-rw-r--r--src/messenger/messenger_api_room.c214
1 files changed, 164 insertions, 50 deletions
diff --git a/src/messenger/messenger_api_room.c b/src/messenger/messenger_api_room.c
index 5fedf1a78..df141ca12 100644
--- a/src/messenger/messenger_api_room.c
+++ b/src/messenger/messenger_api_room.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2020 GNUnet e.V. 3 Copyright (C) 2020--2021 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -30,6 +30,8 @@
30struct GNUNET_MESSENGER_Room* 30struct GNUNET_MESSENGER_Room*
31create_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCode *key) 31create_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCode *key)
32{ 32{
33 GNUNET_assert((handle) && (key));
34
33 struct GNUNET_MESSENGER_Room *room = GNUNET_new(struct GNUNET_MESSENGER_Room); 35 struct GNUNET_MESSENGER_Room *room = GNUNET_new(struct GNUNET_MESSENGER_Room);
34 36
35 room->handle = handle; 37 room->handle = handle;
@@ -38,11 +40,10 @@ create_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCod
38 room->opened = GNUNET_NO; 40 room->opened = GNUNET_NO;
39 room->contact_id = NULL; 41 room->contact_id = NULL;
40 42
41 room->members = GNUNET_CONTAINER_multishortmap_create (8, GNUNET_NO);
42
43 init_list_tunnels (&(room->entries)); 43 init_list_tunnels (&(room->entries));
44 44
45 room->messages = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); 45 room->messages = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO);
46 room->members = GNUNET_CONTAINER_multishortmap_create (8, GNUNET_NO);
46 47
47 return room; 48 return room;
48} 49}
@@ -50,9 +51,10 @@ create_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCod
50static int 51static int
51iterate_destroy_message (void *cls, const struct GNUNET_HashCode *key, void *value) 52iterate_destroy_message (void *cls, const struct GNUNET_HashCode *key, void *value)
52{ 53{
53 struct GNUNET_MESSENGER_Message *message = value; 54 struct GNUNET_MESSENGER_RoomMessageEntry *entry = value;
54 55
55 destroy_message (message); 56 destroy_message (entry->message);
57 GNUNET_free(entry);
56 58
57 return GNUNET_YES; 59 return GNUNET_YES;
58} 60}
@@ -60,8 +62,7 @@ iterate_destroy_message (void *cls, const struct GNUNET_HashCode *key, void *val
60void 62void
61destroy_room (struct GNUNET_MESSENGER_Room *room) 63destroy_room (struct GNUNET_MESSENGER_Room *room)
62{ 64{
63 if (room->members) 65 GNUNET_assert(room);
64 GNUNET_CONTAINER_multishortmap_destroy (room->members);
65 66
66 clear_list_tunnels (&(room->entries)); 67 clear_list_tunnels (&(room->entries));
67 68
@@ -72,6 +73,9 @@ destroy_room (struct GNUNET_MESSENGER_Room *room)
72 GNUNET_CONTAINER_multihashmap_destroy (room->messages); 73 GNUNET_CONTAINER_multihashmap_destroy (room->messages);
73 } 74 }
74 75
76 if (room->members)
77 GNUNET_CONTAINER_multishortmap_destroy (room->members);
78
75 if (room->contact_id) 79 if (room->contact_id)
76 GNUNET_free(room->contact_id); 80 GNUNET_free(room->contact_id);
77 81
@@ -81,65 +85,111 @@ destroy_room (struct GNUNET_MESSENGER_Room *room)
81const struct GNUNET_MESSENGER_Message* 85const struct GNUNET_MESSENGER_Message*
82get_room_message (const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash) 86get_room_message (const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash)
83{ 87{
84 return GNUNET_CONTAINER_multihashmap_get (room->messages, hash); 88 GNUNET_assert((room) && (hash));
89
90 struct GNUNET_MESSENGER_RoomMessageEntry *entry = GNUNET_CONTAINER_multihashmap_get (
91 room->messages, hash
92 );
93
94 return (entry? entry->message : NULL);
95}
96
97struct GNUNET_MESSENGER_Contact*
98get_room_sender (const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash)
99{
100 GNUNET_assert((room) && (hash));
101
102 struct GNUNET_MESSENGER_RoomMessageEntry *entry = GNUNET_CONTAINER_multihashmap_get (
103 room->messages, hash
104 );
105
106 return (entry? entry->sender : NULL);
85} 107}
86 108
87static void 109static void
88handle_join_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, 110handle_join_message (struct GNUNET_MESSENGER_Room *room, struct GNUNET_MESSENGER_Contact *sender,
89 const struct GNUNET_HashCode *hash) 111 const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
90{ 112{
91 struct GNUNET_MESSENGER_Contact *contact = get_handle_contact_by_pubkey (room->handle, &(message->body.join.key)); 113 if (!sender)
114 {
115 struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store(room->handle);
116 struct GNUNET_HashCode context;
117
118 get_context_from_member(&(room->key), &(message->header.sender_id), &context);
119
120 sender = get_store_contact(store, &context, &(message->body.join.key));
121 }
92 122
93 if (contact) 123 if ((GNUNET_YES != GNUNET_CONTAINER_multishortmap_contains_value(room->members, &(message->header.sender_id), sender)) &&
94 GNUNET_CONTAINER_multishortmap_put (room->members, &(message->header.sender_id), contact, 124 (GNUNET_OK == GNUNET_CONTAINER_multishortmap_put(room->members, &(message->header.sender_id), sender,
95 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 125 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)))
126 increase_contact_rc(sender);
96} 127}
97 128
98static void 129static void
99handle_leave_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, 130handle_leave_message (struct GNUNET_MESSENGER_Room *room, struct GNUNET_MESSENGER_Contact *sender,
100 const struct GNUNET_HashCode *hash) 131 const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
101{ 132{
102 GNUNET_CONTAINER_multishortmap_remove_all (room->members, &(message->header.sender_id)); 133 if ((!sender) ||
134 (GNUNET_YES != GNUNET_CONTAINER_multishortmap_remove(room->members, &(message->header.sender_id), sender)))
135 return;
136
137 struct GNUNET_HashCode context;
138 get_context_from_member(&(room->key), &(message->header.sender_id), &context);
139
140 struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store(room->handle);
141
142 if (GNUNET_YES == decrease_contact_rc(sender))
143 remove_store_contact(store, sender, &context);
103} 144}
104 145
105static void 146static void
106handle_name_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, 147handle_name_message (struct GNUNET_MESSENGER_Room *room, struct GNUNET_MESSENGER_Contact *sender,
107 const struct GNUNET_HashCode *hash) 148 const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
108{ 149{
109 struct GNUNET_MESSENGER_Contact *contact = GNUNET_CONTAINER_multishortmap_get (room->members, 150 if (!sender)
110 &(message->header.sender_id)); 151 return;
111 152
112 if (contact) 153 set_contact_name (sender, message->body.name.name);
113 set_contact_name (contact, message->body.name.name);
114} 154}
115 155
116static void 156static void
117handle_key_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, 157handle_key_message (struct GNUNET_MESSENGER_Room *room, struct GNUNET_MESSENGER_Contact *sender,
118 const struct GNUNET_HashCode *hash) 158 const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
119{ 159{
120 struct GNUNET_MESSENGER_Contact *contact = GNUNET_CONTAINER_multishortmap_get (room->members, 160 if (!sender)
121 &(message->header.sender_id)); 161 return;
162
163 struct GNUNET_HashCode context;
164 get_context_from_member(&(room->key), &(message->header.sender_id), &context);
122 165
123 if (contact) 166 struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store(room->handle);
124 swap_handle_contact_by_pubkey (room->handle, contact, &(message->body.key.key)); 167
168 update_store_contact(store, sender, &context, &context, &(message->body.key.key));
125} 169}
126 170
127static void 171static void
128handle_id_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, 172handle_id_message (struct GNUNET_MESSENGER_Room *room, struct GNUNET_MESSENGER_Contact *sender,
129 const struct GNUNET_HashCode *hash) 173 const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
130{ 174{
131 struct GNUNET_MESSENGER_Contact *contact = GNUNET_CONTAINER_multishortmap_get (room->members, 175 if ((!sender) ||
132 &(message->header.sender_id)); 176 (GNUNET_YES != GNUNET_CONTAINER_multishortmap_remove(room->members, &(message->header.sender_id), sender)) ||
177 (GNUNET_OK != GNUNET_CONTAINER_multishortmap_put(room->members, &(message->body.id.id), sender,
178 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)))
179 return;
180
181 struct GNUNET_HashCode context, next_context;
182 get_context_from_member(&(room->key), &(message->header.sender_id), &context);
183 get_context_from_member(&(room->key), &(message->body.id.id), &next_context);
133 184
134 if ((contact) && (GNUNET_OK 185 struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store(room->handle);
135 == GNUNET_CONTAINER_multishortmap_put (room->members, &(message->body.id.id), contact, 186
136 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) 187 update_store_contact(store, sender, &context, &next_context, get_contact_key(sender));
137 GNUNET_CONTAINER_multishortmap_remove (room->members, &(message->header.sender_id), contact);
138} 188}
139 189
140static void 190static void
141handle_miss_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, 191handle_miss_message (struct GNUNET_MESSENGER_Room *room, struct GNUNET_MESSENGER_Contact *sender,
142 const struct GNUNET_HashCode *hash) 192 const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
143{ 193{
144 if ((room->contact_id) && (0 == GNUNET_memcmp(&(message->header.sender_id), room->contact_id))) 194 if ((room->contact_id) && (0 == GNUNET_memcmp(&(message->header.sender_id), room->contact_id)))
145 { 195 {
@@ -150,9 +200,25 @@ handle_miss_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MES
150 } 200 }
151} 201}
152 202
203static void
204handle_delete_message (struct GNUNET_MESSENGER_Room *room, struct GNUNET_MESSENGER_Contact *sender,
205 const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
206{
207 struct GNUNET_MESSENGER_RoomMessageEntry *entry = GNUNET_CONTAINER_multihashmap_get (
208 room->messages, &(message->body.delete.hash)
209 );
210
211 if ((entry) && ((entry->sender == sender) || (get_handle_contact (room->handle, &(room->key)) == sender)) &&
212 (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (room->messages, &(message->body.delete.hash), entry)))
213 {
214 destroy_message (entry->message);
215 GNUNET_free(entry);
216 }
217}
218
153void 219void
154handle_room_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, 220handle_room_message (struct GNUNET_MESSENGER_Room *room, struct GNUNET_MESSENGER_Contact *sender,
155 const struct GNUNET_HashCode *hash) 221 const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
156{ 222{
157 if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (room->messages, hash)) 223 if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (room->messages, hash))
158 return; 224 return;
@@ -160,30 +226,78 @@ handle_room_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MES
160 switch (message->header.kind) 226 switch (message->header.kind)
161 { 227 {
162 case GNUNET_MESSENGER_KIND_JOIN: 228 case GNUNET_MESSENGER_KIND_JOIN:
163 handle_join_message (room, message, hash); 229 handle_join_message (room, sender, message, hash);
164 break; 230 break;
165 case GNUNET_MESSENGER_KIND_LEAVE: 231 case GNUNET_MESSENGER_KIND_LEAVE:
166 handle_leave_message (room, message, hash); 232 handle_leave_message (room, sender, message, hash);
167 break; 233 break;
168 case GNUNET_MESSENGER_KIND_NAME: 234 case GNUNET_MESSENGER_KIND_NAME:
169 handle_name_message (room, message, hash); 235 handle_name_message (room, sender, message, hash);
170 break; 236 break;
171 case GNUNET_MESSENGER_KIND_KEY: 237 case GNUNET_MESSENGER_KIND_KEY:
172 handle_key_message (room, message, hash); 238 handle_key_message (room, sender, message, hash);
173 break; 239 break;
174 case GNUNET_MESSENGER_KIND_ID: 240 case GNUNET_MESSENGER_KIND_ID:
175 handle_id_message (room, message, hash); 241 handle_id_message (room, sender, message, hash);
176 break; 242 break;
177 case GNUNET_MESSENGER_KIND_MISS: 243 case GNUNET_MESSENGER_KIND_MISS:
178 handle_miss_message (room, message, hash); 244 handle_miss_message (room, sender, message, hash);
245 break;
246 case GNUNET_MESSENGER_KIND_DELETE:
247 handle_delete_message (room, sender, message, hash);
179 break; 248 break;
180 default: 249 default:
181 break; 250 break;
182 } 251 }
183 252
184 struct GNUNET_MESSENGER_Message *clone = copy_message (message); 253 struct GNUNET_MESSENGER_RoomMessageEntry *entry = GNUNET_new(struct GNUNET_MESSENGER_RoomMessageEntry);
254
255 if (!entry)
256 return;
257
258 entry->sender = sender;
259 entry->message = copy_message (message);
185 260
186 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (room->messages, hash, clone, 261 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (room->messages, hash, entry,
187 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) 262 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
188 destroy_message (clone); 263 {
264 destroy_message (entry->message);
265 GNUNET_free(entry);
266 }
267}
268
269struct GNUNET_MESSENGER_MemberCall
270{
271 struct GNUNET_MESSENGER_Room *room;
272 GNUNET_MESSENGER_MemberCallback callback;
273 void *cls;
274};
275
276static int
277iterate_local_members (void* cls, const struct GNUNET_ShortHashCode *key, void *value)
278{
279 struct GNUNET_MESSENGER_MemberCall *call = cls;
280 struct GNUNET_MESSENGER_Contact *contact = value;
281
282 return call->callback(call->cls, call->room, contact);
283}
284
285int
286iterate_room_members (struct GNUNET_MESSENGER_Room *room, GNUNET_MESSENGER_MemberCallback callback,
287 void* cls)
288{
289 GNUNET_assert(room);
290
291 if (!callback)
292 return GNUNET_CONTAINER_multishortmap_iterate(room->members, NULL, NULL);
293
294 struct GNUNET_MESSENGER_MemberCall call;
295
296 call.room = room;
297 call.callback = callback;
298 call.cls = cls;
299
300 GNUNET_assert(callback);
301
302 return GNUNET_CONTAINER_multishortmap_iterate(room->members, iterate_local_members, &call);
189} 303}