aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-04-25 16:41:22 +0200
committerChristian Grothoff <christian@grothoff.org>2018-04-25 16:41:22 +0200
commit303334e67262bb6121dfbd245c66535f259d08af (patch)
tree1a92109915ffe63b7e2815edc6a6355f4065a48c /src
parent3c62493eb1aaa74812bbb79431686d99652417f4 (diff)
downloadgnunet-303334e67262bb6121dfbd245c66535f259d08af.tar.gz
gnunet-303334e67262bb6121dfbd245c66535f259d08af.zip
enable caching private->public key mapping in memory to improve CPU consumption for large zone insertions
Diffstat (limited to 'src')
-rw-r--r--src/gns/gnunet-gns-proxy.c14
-rw-r--r--src/gnsrecord/gnsrecord_crypto.c108
-rw-r--r--src/include/gnunet_gnsrecord_lib.h19
-rw-r--r--src/namestore/gnunet-service-namestore.c26
-rw-r--r--src/namestore/namestore.conf.in11
5 files changed, 155 insertions, 23 deletions
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c
index 8b9aa599e..08663a57e 100644
--- a/src/gns/gnunet-gns-proxy.c
+++ b/src/gns/gnunet-gns-proxy.c
@@ -855,9 +855,9 @@ mhd_content_cb (void *cls,
855 return MHD_CONTENT_READER_END_OF_STREAM; 855 return MHD_CONTENT_READER_END_OF_STREAM;
856 } 856 }
857 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 857 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
858 "Writing %lu/%lu bytes\n", 858 "Writing %llu/%llu bytes\n",
859 bytes_to_copy, 859 (unsigned long long) bytes_to_copy,
860 s5r->io_len); 860 (unsigned long long) s5r->io_len);
861 GNUNET_memcpy (buf, 861 GNUNET_memcpy (buf,
862 s5r->io_buf, 862 s5r->io_buf,
863 bytes_to_copy); 863 bytes_to_copy);
@@ -1307,12 +1307,12 @@ curl_download_cb (void *ptr,
1307 if (sizeof (s5r->io_buf) - s5r->io_len < total) 1307 if (sizeof (s5r->io_buf) - s5r->io_len < total)
1308 { 1308 {
1309 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1309 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1310 "Pausing CURL `%s%s' download, not enough space %lu %lu %lu\n", 1310 "Pausing CURL `%s%s' download, not enough space %llu %llu %llu\n",
1311 s5r->domain, 1311 s5r->domain,
1312 s5r->url, 1312 s5r->url,
1313 sizeof (s5r->io_buf), 1313 (unsigned long long) sizeof (s5r->io_buf),
1314 s5r->io_len, 1314 (unsigned long long) s5r->io_len,
1315 total); 1315 (unsigned long long) total);
1316 return CURL_WRITEFUNC_PAUSE; /* not enough space */ 1316 return CURL_WRITEFUNC_PAUSE; /* not enough space */
1317 } 1317 }
1318 GNUNET_memcpy (&s5r->io_buf[s5r->io_len], 1318 GNUNET_memcpy (&s5r->io_buf[s5r->io_len],
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c
index dd628ea76..27c83b90e 100644
--- a/src/gnsrecord/gnsrecord_crypto.c
+++ b/src/gnsrecord/gnsrecord_crypto.c
@@ -72,6 +72,7 @@ derive_block_aes_key (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
72 * Sign name and records 72 * Sign name and records
73 * 73 *
74 * @param key the private key 74 * @param key the private key
75 * @param pkey associated public key
75 * @param expire block expiration 76 * @param expire block expiration
76 * @param label the name for the records 77 * @param label the name for the records
77 * @param rd record data 78 * @param rd record data
@@ -79,17 +80,17 @@ derive_block_aes_key (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
79 * @return NULL on error (block too large) 80 * @return NULL on error (block too large)
80 */ 81 */
81struct GNUNET_GNSRECORD_Block * 82struct GNUNET_GNSRECORD_Block *
82GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, 83block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
83 struct GNUNET_TIME_Absolute expire, 84 const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey,
84 const char *label, 85 struct GNUNET_TIME_Absolute expire,
85 const struct GNUNET_GNSRECORD_Data *rd, 86 const char *label,
86 unsigned int rd_count) 87 const struct GNUNET_GNSRECORD_Data *rd,
88 unsigned int rd_count)
87{ 89{
88 size_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, 90 size_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
89 rd); 91 rd);
90 char payload[sizeof (uint32_t) + payload_len]; 92 char payload[sizeof (uint32_t) + payload_len];
91 struct GNUNET_GNSRECORD_Block *block; 93 struct GNUNET_GNSRECORD_Block *block;
92 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
93 struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey; 94 struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey;
94 struct GNUNET_CRYPTO_SymmetricInitializationVector iv; 95 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
95 struct GNUNET_CRYPTO_SymmetricSessionKey skey; 96 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
@@ -139,12 +140,10 @@ GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
139 "gns"); 140 "gns");
140 GNUNET_CRYPTO_ecdsa_key_get_public (dkey, 141 GNUNET_CRYPTO_ecdsa_key_get_public (dkey,
141 &block->derived_key); 142 &block->derived_key);
142 GNUNET_CRYPTO_ecdsa_key_get_public (key,
143 &pkey);
144 derive_block_aes_key (&iv, 143 derive_block_aes_key (&iv,
145 &skey, 144 &skey,
146 label, 145 label,
147 &pkey); 146 pkey);
148 GNUNET_break (payload_len + sizeof (uint32_t) == 147 GNUNET_break (payload_len + sizeof (uint32_t) ==
149 GNUNET_CRYPTO_symmetric_encrypt (payload, 148 GNUNET_CRYPTO_symmetric_encrypt (payload,
150 payload_len + sizeof (uint32_t), 149 payload_len + sizeof (uint32_t),
@@ -167,6 +166,97 @@ GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
167 166
168 167
169/** 168/**
169 * Sign name and records
170 *
171 * @param key the private key
172 * @param expire block expiration
173 * @param label the name for the records
174 * @param rd record data
175 * @param rd_count number of records
176 * @return NULL on error (block too large)
177 */
178struct GNUNET_GNSRECORD_Block *
179GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
180 struct GNUNET_TIME_Absolute expire,
181 const char *label,
182 const struct GNUNET_GNSRECORD_Data *rd,
183 unsigned int rd_count)
184{
185 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
186
187 GNUNET_CRYPTO_ecdsa_key_get_public (key,
188 &pkey);
189 return block_create (key,
190 &pkey,
191 expire,
192 label,
193 rd,
194 rd_count);
195}
196
197
198/**
199 * Line in cache mapping private keys to public keys.
200 */
201struct KeyCacheLine
202{
203 /**
204 * A private key.
205 */
206 struct GNUNET_CRYPTO_EcdsaPrivateKey key;
207
208 /**
209 * Associated public key.
210 */
211 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
212
213};
214
215
216/**
217 * Sign name and records, cache derived public key (also keeps the
218 * private key in static memory, so do not use this function if
219 * keeping the private key in the process'es RAM is a major issue).
220 *
221 * @param key the private key
222 * @param expire block expiration
223 * @param label the name for the records
224 * @param rd record data
225 * @param rd_count number of records
226 * @return NULL on error (block too large)
227 */
228struct GNUNET_GNSRECORD_Block *
229GNUNET_GNSRECORD_block_create2 (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
230 struct GNUNET_TIME_Absolute expire,
231 const char *label,
232 const struct GNUNET_GNSRECORD_Data *rd,
233 unsigned int rd_count)
234{
235#define CSIZE 64
236 static struct KeyCacheLine cache[CSIZE];
237 struct KeyCacheLine *line;
238
239 line = &cache[(*(unsigned int *) key) ^ CSIZE];
240 if (0 != memcmp (&line->key,
241 key,
242 sizeof (*key)))
243 {
244 /* cache miss, recompute */
245 line->key = *key;
246 GNUNET_CRYPTO_ecdsa_key_get_public (key,
247 &line->pkey);
248 }
249 return block_create (key,
250 &line->pkey,
251 expire,
252 label,
253 rd,
254 rd_count);
255}
256
257
258
259/**
170 * Check if a signature is valid. This API is used by the GNS Block 260 * Check if a signature is valid. This API is used by the GNS Block
171 * to validate signatures received from the network. 261 * to validate signatures received from the network.
172 * 262 *
diff --git a/src/include/gnunet_gnsrecord_lib.h b/src/include/gnunet_gnsrecord_lib.h
index f07bd3ef3..38346ada3 100644
--- a/src/include/gnunet_gnsrecord_lib.h
+++ b/src/include/gnunet_gnsrecord_lib.h
@@ -558,6 +558,25 @@ GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
558 558
559 559
560/** 560/**
561 * Sign name and records, cache derived public key (also keeps the
562 * private key in static memory, so do not use this function if
563 * keeping the private key in the process'es RAM is a major issue).
564 *
565 * @param key the private key
566 * @param expire block expiration
567 * @param label the name for the records
568 * @param rd record data
569 * @param rd_count number of records in @a rd
570 */
571struct GNUNET_GNSRECORD_Block *
572GNUNET_GNSRECORD_block_create2 (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
573 struct GNUNET_TIME_Absolute expire,
574 const char *label,
575 const struct GNUNET_GNSRECORD_Data *rd,
576 unsigned int rd_count);
577
578
579/**
561 * Check if a signature is valid. This API is used by the GNS Block 580 * Check if a signature is valid. This API is used by the GNS Block
562 * to validate signatures received from the network. 581 * to validate signatures received from the network.
563 * 582 *
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c
index f8ac6c31c..c5a37dcac 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -251,6 +251,12 @@ static struct ZoneMonitor *monitor_tail;
251 */ 251 */
252static struct GNUNET_NotificationContext *monitor_nc; 252static struct GNUNET_NotificationContext *monitor_nc;
253 253
254/**
255 * Optimize block insertion by caching map of private keys to
256 * public keys in memory?
257 */
258static int cache_keys;
259
254 260
255/** 261/**
256 * Task run during shutdown. 262 * Task run during shutdown.
@@ -707,11 +713,18 @@ refresh_block (struct NamestoreClient *nc,
707 ? GNUNET_TIME_UNIT_ZERO_ABS 713 ? GNUNET_TIME_UNIT_ZERO_ABS
708 : GNUNET_GNSRECORD_record_get_expiration_time (res_count, 714 : GNUNET_GNSRECORD_record_get_expiration_time (res_count,
709 res); 715 res);
710 block = GNUNET_GNSRECORD_block_create (zone_key, 716 if (cache_keys)
711 exp_time, 717 block = GNUNET_GNSRECORD_block_create2 (zone_key,
712 name, 718 exp_time,
713 res, 719 name,
714 res_count); 720 res,
721 res_count);
722 else
723 block = GNUNET_GNSRECORD_block_create (zone_key,
724 exp_time,
725 name,
726 res,
727 res_count);
715 GNUNET_assert (NULL != block); 728 GNUNET_assert (NULL != block);
716 GNUNET_CRYPTO_ecdsa_key_get_public (zone_key, 729 GNUNET_CRYPTO_ecdsa_key_get_public (zone_key,
717 &pkey); 730 &pkey);
@@ -1722,6 +1735,9 @@ run (void *cls,
1722 monitor_nc = GNUNET_notification_context_create (1); 1735 monitor_nc = GNUNET_notification_context_create (1);
1723 namecache = GNUNET_NAMECACHE_connect (cfg); 1736 namecache = GNUNET_NAMECACHE_connect (cfg);
1724 /* Loading database plugin */ 1737 /* Loading database plugin */
1738 cache_keys = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1739 "namestore",
1740 "CACHE_KEYS");
1725 if (GNUNET_OK != 1741 if (GNUNET_OK !=
1726 GNUNET_CONFIGURATION_get_value_string (cfg, 1742 GNUNET_CONFIGURATION_get_value_string (cfg,
1727 "namestore", 1743 "namestore",
diff --git a/src/namestore/namestore.conf.in b/src/namestore/namestore.conf.in
index f19ac5643..8b5e440b8 100644
--- a/src/namestore/namestore.conf.in
+++ b/src/namestore/namestore.conf.in
@@ -9,8 +9,17 @@ HOSTNAME = localhost
9BINARY = gnunet-service-namestore 9BINARY = gnunet-service-namestore
10ACCEPT_FROM = 127.0.0.1; 10ACCEPT_FROM = 127.0.0.1;
11ACCEPT_FROM6 = ::1; 11ACCEPT_FROM6 = ::1;
12
13# Which database should we use?
12DATABASE = sqlite 14DATABASE = sqlite
13 15
16# Should we optimize publishing record by caching the mapping
17# from zone private keys to zone public keys in memory?
18# (Set to NO if totally paranoid about keeping private keys
19# in RAM longer than necessary.)
20CACHE_KEYS = YES
21
22
14[namestore-sqlite] 23[namestore-sqlite]
15FILENAME = $GNUNET_DATA_HOME/namestore/sqlite.db 24FILENAME = $GNUNET_DATA_HOME/namestore/sqlite.db
16 25
@@ -38,5 +47,3 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-fcfsd.sock
38 47
39# On what port does the FCFS daemon listen for HTTP clients? 48# On what port does the FCFS daemon listen for HTTP clients?
40HTTPPORT = 18080 49HTTPPORT = 18080
41
42