GNUnet  0.20.0
messenger_api_contact_store.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2020--2021 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  */
26 #include "platform.h"
28 
29 #include "messenger_api_contact.h"
30 #include "messenger_api_util.h"
31 
32 void
34 {
35  GNUNET_assert (store);
36 
39 }
40 
41 static int
43  const struct GNUNET_HashCode *key,
44  void *value)
45 {
46  struct GNUNET_MESSENGER_Contact *contact = value;
47  destroy_contact (contact);
48  return GNUNET_YES;
49 }
50 
51 void
53 {
54  GNUNET_assert ((store) && (store->contacts));
55 
58 
61 }
62 
63 static struct GNUNET_CONTAINER_MultiHashMap*
65  const struct GNUNET_HashCode *context,
66  struct GNUNET_HashCode *hash)
67 {
68  const struct GNUNET_IDENTITY_PublicKey *anonymous = get_anonymous_public_key ();
69 
70  struct GNUNET_HashCode anonHash;
71  GNUNET_CRYPTO_hash (anonymous, sizeof(*anonymous), &anonHash);
72 
73  if ((context) && (0 == GNUNET_CRYPTO_hash_cmp(hash, &anonHash)))
74  {
75  GNUNET_memcpy(hash, context, sizeof(*context));
76  return store->anonymous;
77  }
78  else
79  return store->contacts;
80 }
81 
84  const struct GNUNET_HashCode *context,
85  const struct GNUNET_HashCode *key_hash)
86 {
87  GNUNET_assert ((store) && (store->contacts) && (context) && (key_hash));
88 
89  struct GNUNET_HashCode hash;
90  GNUNET_memcpy(&hash, key_hash, sizeof(*key_hash));
91 
93  store, context, &hash
94  );
95 
96  return GNUNET_CONTAINER_multihashmap_get (map, &hash);
97 }
98 
101  const struct GNUNET_HashCode *context,
102  const struct GNUNET_IDENTITY_PublicKey *pubkey)
103 {
104  GNUNET_assert ((store) && (store->contacts) && (context) && (pubkey));
105 
106  struct GNUNET_HashCode hash;
107  GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash);
108 
110  store, context, &hash
111  );
112 
114 
115  if (contact)
116  {
117  if (0 != GNUNET_memcmp(pubkey, get_contact_key(contact)))
118  {
120  GNUNET_log (GNUNET_ERROR_TYPE_INVALID, "Contact in store uses wrong key: %s\n", str);
121  GNUNET_free (str);
122  return NULL;
123  }
124 
125  return contact;
126  }
127 
128  contact = create_contact (pubkey);
129 
130  if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (map, &hash, contact,
132  return contact;
133 
134  destroy_contact (contact);
135  return NULL;
136 }
137 
138 void
140  struct GNUNET_MESSENGER_Contact* contact,
141  const struct GNUNET_HashCode *context,
142  const struct GNUNET_HashCode *next_context,
143  const struct GNUNET_IDENTITY_PublicKey *pubkey)
144 {
145  GNUNET_assert ((store) && (store->contacts) && (contact) && (pubkey));
146 
147  const struct GNUNET_IDENTITY_PublicKey* oldkey = get_contact_key (contact);
148 
149  struct GNUNET_HashCode hash;
150  GNUNET_CRYPTO_hash (oldkey, sizeof(*oldkey), &hash);
151 
153  store, context, &hash
154  );
155 
156  if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (map, &hash, contact))
157  {
158  GNUNET_memcpy(&(contact->public_key), pubkey, sizeof(*pubkey));
159 
160  GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash);
161 
163  store, next_context, &hash
164  );
165 
166  if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (map, &hash, contact,
168  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Updating a contact failed: %s\n",
169  GNUNET_h2s(&hash));
170  }
171 }
172 
173 void
175  struct GNUNET_MESSENGER_Contact* contact,
176  const struct GNUNET_HashCode *context)
177 {
178  GNUNET_assert ((store) && (store->contacts) && (contact));
179 
180  const struct GNUNET_IDENTITY_PublicKey* pubkey = get_contact_key(contact);
181 
182  struct GNUNET_HashCode hash;
183  GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash);
184 
186  store, context, &hash
187  );
188 
189  if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (map, &hash, contact))
190  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Removing a contact failed: %s\n",
191  GNUNET_h2s(&hash));
192 
193  destroy_contact (contact);
194 }
static struct GNUNET_CONTAINER_MultiPeerMap * map
Handle to the map used to store old latency values for peers.
struct GNUNET_HashCode key
The key used in the DHT.
static pa_context * context
Pulseaudio context.
static struct GNUNET_IDENTITY_PublicKey pubkey
Public key of the zone to look in.
static char * value
Value of the record to add/remove.
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
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.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
enum GNUNET_GenericReturnValue 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.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
, ' bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE...
char * GNUNET_IDENTITY_public_key_to_string(const struct GNUNET_IDENTITY_PublicKey *key)
Creates a (Base32) string representation of the public key.
#define GNUNET_log(kind,...)
#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_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
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_MESSENGER_Contact * create_contact(const struct GNUNET_IDENTITY_PublicKey *key)
Creates and allocates a new contact with a given public key from an EGO.
void destroy_contact(struct GNUNET_MESSENGER_Contact *contact)
Destroys a contact and frees its memory fully.
const struct GNUNET_IDENTITY_PublicKey * get_contact_key(const struct GNUNET_MESSENGER_Contact *contact)
Returns the public key of a given contact.
messenger api: client implementation of GNUnet MESSENGER service
struct GNUNET_MESSENGER_Contact * get_store_contact(struct GNUNET_MESSENGER_ContactStore *store, const struct GNUNET_HashCode *context, const struct GNUNET_IDENTITY_PublicKey *pubkey)
Returns a contact using a specific public key.
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 struct GNUNET_CONTAINER_MultiHashMap * select_store_contact_map(struct GNUNET_MESSENGER_ContactStore *store, const struct GNUNET_HashCode *context, struct GNUNET_HashCode *hash)
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.
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_IDENTITY_PublicKey *pubkey)
Moves a contact from the store to another location matching a given public key and member context.
static int iterate_destroy_contacts(void *cls, const struct GNUNET_HashCode *key, void *value)
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.
messenger api: client implementation of GNUnet MESSENGER service
const struct GNUNET_IDENTITY_PublicKey * get_anonymous_public_key()
Returns the public identity key of GNUNET_IDENTITY_ego_get_anonymous() without recalculating it every...
messenger api: client implementation of GNUnet MESSENGER service
Internal representation of the hash map.
A 512-bit hashcode.
An identity key as per LSD0001.
struct GNUNET_CONTAINER_MultiHashMap * contacts
struct GNUNET_CONTAINER_MultiHashMap * anonymous
struct GNUNET_IDENTITY_PublicKey public_key