GNUnet 0.22.1
messenger_api_contact_store.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2020--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 */
27
28#include "gnunet_common.h"
30#include "messenger_api_util.h"
31
32void
34{
35 GNUNET_assert (store);
36
39
40 store->counter = 0;
41}
42
43
46 const struct GNUNET_HashCode *key,
47 void *value)
48{
49 struct GNUNET_MESSENGER_Contact *contact;
50
52
53 contact = value;
54
55 destroy_contact (contact);
56 return GNUNET_YES;
57}
58
59
60void
62{
63 GNUNET_assert ((store) && (store->contacts));
64
65 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Clear contact store\n");
66
71
74}
75
76
79 const struct GNUNET_HashCode *context,
80 struct GNUNET_HashCode *hash)
81{
82 const struct GNUNET_CRYPTO_PublicKey *anonymous;
83 struct GNUNET_HashCode anonHash;
84
85 GNUNET_assert (hash);
86
87 anonymous = get_anonymous_public_key ();
88
89 GNUNET_CRYPTO_hash (anonymous, sizeof(*anonymous), &anonHash);
90
91 if ((context) && (0 == GNUNET_CRYPTO_hash_cmp (hash, &anonHash)))
92 {
93 GNUNET_memcpy (hash, context, sizeof(*context));
94 return store->anonymous;
95 }
96 else
97 return store->contacts;
98}
99
100
103 const struct GNUNET_HashCode *context,
104 const struct GNUNET_HashCode *key_hash)
105{
107 struct GNUNET_HashCode hash;
108
109 GNUNET_assert ((store) && (store->contacts) && (context) && (key_hash));
110
111 GNUNET_memcpy (&hash, key_hash, sizeof(*key_hash));
112
113 map = select_store_contact_map (store, context, &hash);
114
116}
117
118
121 const struct GNUNET_HashCode *context,
122 const struct GNUNET_CRYPTO_PublicKey *pubkey)
123{
125 struct GNUNET_MESSENGER_Contact *contact;
126 struct GNUNET_HashCode hash;
127
128 GNUNET_assert ((store) && (store->contacts) && (pubkey));
129
130 GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash);
131
132 map = select_store_contact_map (store, context, &hash);
133 contact = GNUNET_CONTAINER_multihashmap_get (map, &hash);
134
135 if (contact)
136 {
137 if (0 != GNUNET_memcmp (pubkey, get_contact_key (contact)))
138 {
139 char *str;
141
143 "Contact in store uses wrong key: %s\n", str);
144 GNUNET_free (str);
145 return NULL;
146 }
147
148 return contact;
149 }
150
151 contact = create_contact (pubkey, ++(store->counter));
152
153 if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (map, &hash, contact,
155
156 return contact;
157
158 destroy_contact (contact);
159 return NULL;
160}
161
162
163void
165 struct GNUNET_MESSENGER_Contact *contact,
166 const struct GNUNET_HashCode *context,
167 const struct GNUNET_HashCode *next_context,
168 const struct GNUNET_CRYPTO_PublicKey *pubkey)
169{
170 const struct GNUNET_CRYPTO_PublicKey *oldkey;
172 struct GNUNET_HashCode hash;
173
174 GNUNET_assert ((store) && (store->contacts) && (contact) && (pubkey));
175
176 oldkey = get_contact_key (contact);
177 GNUNET_CRYPTO_hash (oldkey, sizeof(*oldkey), &hash);
178
179 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Update contact store entry: %s\n",
180 GNUNET_h2s (&hash));
181
182 map = select_store_contact_map (store, context, &hash);
183
184 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (map, &hash, contact))
185 {
186 GNUNET_memcpy (&(contact->public_key), pubkey, sizeof(*pubkey));
187
188 GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash);
189
190 map = select_store_contact_map (store, next_context, &hash);
191
192 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (map, &hash, contact,
194
195 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Updating a contact failed: %s\n",
196 GNUNET_h2s (&hash));
197 }
198}
199
200
201void
203 struct GNUNET_MESSENGER_Contact *contact,
204 const struct GNUNET_HashCode *context)
205{
206 const struct GNUNET_CRYPTO_PublicKey *pubkey;
208 struct GNUNET_HashCode hash;
209
210 GNUNET_assert ((store) && (store->contacts) && (contact));
211
212 pubkey = get_contact_key (contact);
213 GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash);
214
215 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Remove contact store entry: %s\n",
216 GNUNET_h2s (&hash));
217
218 map = select_store_contact_map (store, context, &hash);
219
220 if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (map, &hash, contact))
221 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Removing a contact failed: %s\n",
222 GNUNET_h2s (&hash));
223
224 destroy_contact (contact);
225}
struct GNUNET_HashCode key
The key used in the DHT.
static pa_context * context
Pulseaudio context.
static struct GNUNET_CRYPTO_PublicKey pubkey
Public key of the zone to look in.
static char * value
Value of the record to add/remove.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
int GNUNET_CRYPTO_hash_cmp(const struct GNUNET_HashCode *h1, const struct GNUNET_HashCode *h2)
Compare function for HashCodes, producing a total ordering of all hashcodes.
Definition: crypto_hash.c:221
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
, ' bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE...
#define GNUNET_log(kind,...)
char * GNUNET_CRYPTO_public_key_to_string(const struct GNUNET_CRYPTO_PublicKey *key)
Creates a (Base32) string representation of the public key.
Definition: crypto_pkey.c:379
#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_YES
@ GNUNET_NO
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_INVALID
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_free(ptr)
Wrapper around free.
const struct GNUNET_CRYPTO_PublicKey * get_contact_key(const struct GNUNET_MESSENGER_Contact *contact)
Returns the public key of a given contact.
void destroy_contact(struct GNUNET_MESSENGER_Contact *contact)
Destroys a contact and frees its memory fully.
struct GNUNET_MESSENGER_Contact * create_contact(const struct GNUNET_CRYPTO_PublicKey *key, size_t unique_id)
Creates and allocates a new contact with a given public key.
struct GNUNET_MESSENGER_Contact * get_store_contact_raw(struct GNUNET_MESSENGER_ContactStore *store, const struct GNUNET_HashCode *context, const struct GNUNET_HashCode *key_hash)
Returns a contact using the hash of a specific public key.
void update_store_contact(struct GNUNET_MESSENGER_ContactStore *store, struct GNUNET_MESSENGER_Contact *contact, const struct GNUNET_HashCode *context, const struct GNUNET_HashCode *next_context, const struct GNUNET_CRYPTO_PublicKey *pubkey)
Moves a contact from the store to another location matching a given public key and member context.
void clear_contact_store(struct GNUNET_MESSENGER_ContactStore *store)
Clears a contact store, wipes its content and deallocates its memory.
void init_contact_store(struct GNUNET_MESSENGER_ContactStore *store)
Initializes a contact store as fully empty.
static enum GNUNET_GenericReturnValue iterate_destroy_contacts(void *cls, const struct GNUNET_HashCode *key, void *value)
struct GNUNET_MESSENGER_Contact * get_store_contact(struct GNUNET_MESSENGER_ContactStore *store, const struct GNUNET_HashCode *context, const struct GNUNET_CRYPTO_PublicKey *pubkey)
Returns a contact using a specific public key.
void remove_store_contact(struct GNUNET_MESSENGER_ContactStore *store, struct GNUNET_MESSENGER_Contact *contact, const struct GNUNET_HashCode *context)
Removes a contact from the store which uses a given member context.
static struct GNUNET_CONTAINER_MultiHashMap * select_store_contact_map(struct GNUNET_MESSENGER_ContactStore *store, const struct GNUNET_HashCode *context, struct GNUNET_HashCode *hash)
const struct GNUNET_CRYPTO_PublicKey * get_anonymous_public_key(void)
Returns the public identity key of GNUNET_IDENTITY_ego_get_anonymous() without recalculating it every...
static struct GNUNET_CONTAINER_MultiPeerMap * map
Peermap of PeerIdentities to "struct PeerEntry" (for fast lookup).
Definition: peer.c:63
Internal representation of the hash map.
An identity key as per LSD0001.
A 512-bit hashcode.
struct GNUNET_CONTAINER_MultiHashMap * contacts
struct GNUNET_CONTAINER_MultiHashMap * anonymous
struct GNUNET_CRYPTO_PublicKey public_key