aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2022-10-03 13:23:35 +0900
committerMartin Schanzenbach <schanzen@gnunet.org>2022-10-03 13:23:35 +0900
commite891aa916c09b3e79c02f7c486f3e1a1c015769a (patch)
treee0e3eb9c1828b8652c91bc9bb624395ebe256544 /src
parent4611664be0ba79ec7029a74cf961f28f2a658241 (diff)
downloadgnunet-e891aa916c09b3e79c02f7c486f3e1a1c015769a.tar.gz
gnunet-e891aa916c09b3e79c02f7c486f3e1a1c015769a.zip
NAMESTORE: Bulk store API and fix for delayed store activities
New API: GNUNET_NAMESTORE_records_store2 which allows the caller to pass an array of records in order to facilitate bulk import of zone data. Further, the transactional API requires that monitors and namecache updates are delayed until transactions are actually commited.
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_namestore_service.h37
-rw-r--r--src/namestore/gnunet-service-namestore.c294
-rw-r--r--src/namestore/namestore.conf.in6
-rw-r--r--src/namestore/namestore.h43
-rw-r--r--src/namestore/namestore_api.c105
-rw-r--r--src/namestore/perf_namestore_api_postgres.conf1
-rw-r--r--src/namestore/perf_namestore_api_sqlite.conf1
-rw-r--r--src/namestore/plugin_namestore_sqlite.c1
-rw-r--r--src/namestore/plugin_rest_namestore.c108
-rw-r--r--src/namestore/test_plugin_namestore_postgres.conf1
-rw-r--r--src/namestore/test_plugin_namestore_sqlite.conf1
11 files changed, 440 insertions, 158 deletions
diff --git a/src/include/gnunet_namestore_service.h b/src/include/gnunet_namestore_service.h
index dc6aeaa69..b795494af 100644
--- a/src/include/gnunet_namestore_service.h
+++ b/src/include/gnunet_namestore_service.h
@@ -148,6 +148,43 @@ GNUNET_NAMESTORE_records_store (struct GNUNET_NAMESTORE_Handle *h,
148 void *cont_cls); 148 void *cont_cls);
149 149
150/** 150/**
151 * Store one or more record sets in the namestore. If any item is already present,
152 * it is replaced with the new record. Use an empty array to
153 * remove all records under the given name.
154 *
155 * The continuation is called after the records have been stored in the
156 * database. They may not yet have been commited. Monitors may be notified
157 * asynchronously (basically with a buffer when commited).
158 * However, if any monitor is consistently too slow to
159 * keep up with the changes, calling @a cont will be delayed until the
160 * monitors do keep up.
161 * Uncommited store requests within a transaction (GNUNET_NAMESTORE_transaction_begin)
162 * cause @a cont to be called immediately before the commit and before
163 * notification of monitors.
164 *
165 * @param h handle to the namestore
166 * @param pkey private key of the zone
167 * @param rd_set_count the number of record sets
168 * @param a_label an array of size @a rd_set_count of names for each record set
169 * @param a_rd_count an array of size @a rd_set_count containing the number of records in the corresponding 'rd' array
170 * @param a_rd an array of size @a rd_set_count of arrays of records with data to store
171 * @param cont continuation to call when done
172 * @param cont_cls closure for @a cont
173 * @return handle to abort the request
174 */
175
176struct GNUNET_NAMESTORE_QueueEntry *
177GNUNET_NAMESTORE_records_store2 (
178 struct GNUNET_NAMESTORE_Handle *h,
179 const struct GNUNET_IDENTITY_PrivateKey *pkey,
180 unsigned int rd_set_count,
181 const char **a_label,
182 unsigned int *a_rd_count,
183 const struct GNUNET_GNSRECORD_Data **a_rd,
184 GNUNET_NAMESTORE_ContinuationWithStatus cont,
185 void *cont_cls);
186
187/**
151 * Store an item in the namestore. If the item is already present, 188 * Store an item in the namestore. If the item is already present,
152 * it is replaced with the new record. Use an empty array to 189 * it is replaced with the new record. Use an empty array to
153 * remove all records under the given name. 190 * remove all records under the given name.
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c
index b860d7a3c..ada2acb16 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -147,6 +147,11 @@ struct NamestoreClient
147 char *db_lib_name; 147 char *db_lib_name;
148 148
149 /** 149 /**
150 * GNUNET_YES if this nc has begun a transaction which is uncommited.
151 */
152 int in_transaction;
153
154 /**
150 * Message queue for transmission to @e client 155 * Message queue for transmission to @e client
151 */ 156 */
152 struct GNUNET_MQ_Handle *mq; 157 struct GNUNET_MQ_Handle *mq;
@@ -308,10 +313,26 @@ struct StoreActivity
308 struct NamestoreClient *nc; 313 struct NamestoreClient *nc;
309 314
310 /** 315 /**
311 * Copy of the original store message (as data fields in @e rd will 316 * The request ID
317 */
318 uint32_t rid;
319
320 /**
321 * Wheather or not this store action is already commited.
322 * The store activity will not be processed unless this field is GNUNET_YES
323 */
324 int uncommited;
325
326 /**
327 * The zone private key
328 */
329 struct GNUNET_IDENTITY_PrivateKey private_key;
330
331 /**
332 * Copy of the original record set (as data fields in @e rd will
312 * point into it!). 333 * point into it!).
313 */ 334 */
314 const struct RecordStoreMessage *rsm; 335 const struct RecordSet *rs;
315 336
316 /** 337 /**
317 * Next zone monitor that still needs to be notified about this PUT. 338 * Next zone monitor that still needs to be notified about this PUT.
@@ -879,7 +900,7 @@ send_lookup_response (struct NamestoreClient *nc,
879 * @param rid client's request ID 900 * @param rid client's request ID
880 */ 901 */
881static void 902static void
882send_store_response (struct NamestoreClient *nc, int res, const char*emsg, 903send_store_response (struct NamestoreClient *nc, int res, const char *emsg,
883 uint32_t rid) 904 uint32_t rid)
884{ 905{
885 struct GNUNET_MQ_Envelope *env; 906 struct GNUNET_MQ_Envelope *env;
@@ -1105,7 +1126,7 @@ warn_monitor_slow (void *cls)
1105static void 1126static void
1106continue_store_activity (struct StoreActivity *sa) 1127continue_store_activity (struct StoreActivity *sa)
1107{ 1128{
1108 const struct RecordStoreMessage *rp_msg = sa->rsm; 1129 const struct RecordSet *rd_set = sa->rs;
1109 unsigned int rd_count; 1130 unsigned int rd_count;
1110 size_t name_len; 1131 size_t name_len;
1111 size_t rd_ser_len; 1132 size_t rd_ser_len;
@@ -1113,11 +1134,20 @@ continue_store_activity (struct StoreActivity *sa)
1113 const char *name_tmp; 1134 const char *name_tmp;
1114 const char *rd_ser; 1135 const char *rd_ser;
1115 1136
1116 rid = ntohl (rp_msg->gns_header.r_id); 1137 // If we are in a transaction, do not notify monitors or update
1117 name_len = ntohs (rp_msg->name_len); 1138 // cached. This will be done when we are commiting.
1118 rd_count = ntohs (rp_msg->rd_count); 1139 if (GNUNET_YES == sa->uncommited)
1119 rd_ser_len = ntohs (rp_msg->rd_len); 1140 {
1120 name_tmp = (const char *) &rp_msg[1]; 1141 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1142 "Transaction not yet committed, delaying monitor and cache updates\n");
1143 send_store_response (sa->nc, GNUNET_YES, NULL, sa->rid);
1144 GNUNET_SERVICE_client_continue (sa->nc->client);
1145 return;
1146 }
1147 name_len = ntohs (rd_set->name_len);
1148 rd_count = ntohs (rd_set->rd_count);
1149 rd_ser_len = ntohs (rd_set->rd_len);
1150 name_tmp = (const char *) &rd_set[1];
1121 rd_ser = &name_tmp[name_len]; 1151 rd_ser = &name_tmp[name_len];
1122 { 1152 {
1123 struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)]; 1153 struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
@@ -1129,7 +1159,7 @@ continue_store_activity (struct StoreActivity *sa)
1129 1159
1130 for (struct ZoneMonitor *zm = sa->zm_pos; NULL != zm; zm = sa->zm_pos) 1160 for (struct ZoneMonitor *zm = sa->zm_pos; NULL != zm; zm = sa->zm_pos)
1131 { 1161 {
1132 if ((0 != GNUNET_memcmp (&rp_msg->private_key, &zm->zone)) && 1162 if ((0 != GNUNET_memcmp (&sa->private_key, &zm->zone)) &&
1133 (0 != GNUNET_memcmp (&zm->zone, &zero))) 1163 (0 != GNUNET_memcmp (&zm->zone, &zero)))
1134 { 1164 {
1135 sa->zm_pos = zm->next; /* not interesting to this monitor */ 1165 sa->zm_pos = zm->next; /* not interesting to this monitor */
@@ -1153,7 +1183,7 @@ continue_store_activity (struct StoreActivity *sa)
1153 zm->limit--; 1183 zm->limit--;
1154 send_lookup_response_with_filter (zm->nc, 1184 send_lookup_response_with_filter (zm->nc,
1155 0, 1185 0,
1156 &rp_msg->private_key, 1186 &sa->private_key,
1157 sa->conv_name, 1187 sa->conv_name,
1158 rd_count, 1188 rd_count,
1159 rd, 1189 rd,
@@ -1163,8 +1193,8 @@ continue_store_activity (struct StoreActivity *sa)
1163 /* great, done with the monitors, unpack (again) for refresh_block operation */ 1193 /* great, done with the monitors, unpack (again) for refresh_block operation */
1164 refresh_block (sa->nc, 1194 refresh_block (sa->nc,
1165 NULL, 1195 NULL,
1166 rid, 1196 sa->rid,
1167 &rp_msg->private_key, 1197 &sa->private_key,
1168 sa->conv_name, 1198 sa->conv_name,
1169 rd_count, 1199 rd_count,
1170 rd); 1200 rd);
@@ -1240,7 +1270,8 @@ client_disconnect_cb (void *cls,
1240 for (cop = cop_head; NULL != cop; cop = cop->next) 1270 for (cop = cop_head; NULL != cop; cop = cop->next)
1241 if (nc == cop->nc) 1271 if (nc == cop->nc)
1242 cop->nc = NULL; 1272 cop->nc = NULL;
1243 GNUNET_break (NULL == GNUNET_PLUGIN_unload (nc->db_lib_name, nc->GSN_database)); 1273 GNUNET_break (NULL == GNUNET_PLUGIN_unload (nc->db_lib_name,
1274 nc->GSN_database));
1244 GNUNET_free (nc->db_lib_name); 1275 GNUNET_free (nc->db_lib_name);
1245 GNUNET_free (nc); 1276 GNUNET_free (nc);
1246} 1277}
@@ -1549,29 +1580,16 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
1549static int 1580static int
1550check_record_store (void *cls, const struct RecordStoreMessage *rp_msg) 1581check_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1551{ 1582{
1552 size_t name_len;
1553 size_t msg_size; 1583 size_t msg_size;
1554 size_t msg_size_exp; 1584 size_t min_size_exp;
1555 size_t rd_ser_len; 1585 size_t rd_set_count;
1556 const char *name_tmp;
1557 1586
1558 (void) cls; 1587 (void) cls;
1559 name_len = ntohs (rp_msg->name_len);
1560 msg_size = ntohs (rp_msg->gns_header.header.size); 1588 msg_size = ntohs (rp_msg->gns_header.header.size);
1561 rd_ser_len = ntohs (rp_msg->rd_len); 1589 rd_set_count = ntohs (rp_msg->rd_set_count);
1562 msg_size_exp = sizeof(struct RecordStoreMessage) + name_len + rd_ser_len; 1590 min_size_exp = sizeof(struct RecordStoreMessage) + sizeof (struct RecordSet)
1563 if (msg_size != msg_size_exp) 1591 * rd_set_count;
1564 { 1592 if (msg_size < min_size_exp)
1565 GNUNET_break (0);
1566 return GNUNET_SYSERR;
1567 }
1568 if ((0 == name_len) || (name_len > MAX_NAME_LEN))
1569 {
1570 GNUNET_break (0);
1571 return GNUNET_SYSERR;
1572 }
1573 name_tmp = (const char *) &rp_msg[1];
1574 if ('\0' != name_tmp[name_len - 1])
1575 { 1593 {
1576 GNUNET_break (0); 1594 GNUNET_break (0);
1577 return GNUNET_SYSERR; 1595 return GNUNET_SYSERR;
@@ -1620,77 +1638,61 @@ get_block_exp_existing (void *cls,
1620 } 1638 }
1621} 1639}
1622 1640
1623 1641static enum GNUNET_GenericReturnValue
1624/** 1642store_record_set (struct NamestoreClient *nc,
1625 * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message 1643 const struct GNUNET_IDENTITY_PrivateKey *private_key,
1626 * 1644 const struct RecordSet *rd_set,
1627 * @param cls client sending the message 1645 char **conv_name,
1628 * @param rp_msg message of type `struct RecordStoreMessage` 1646 ssize_t *len,
1629 */ 1647 char **emsg)
1630static void
1631handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1632{ 1648{
1633 struct NamestoreClient *nc = cls;
1634 size_t name_len; 1649 size_t name_len;
1635 size_t rd_ser_len; 1650 size_t rd_ser_len;
1636 uint32_t rid;
1637 const char *name_tmp; 1651 const char *name_tmp;
1638 char *conv_name;
1639 const char *rd_ser; 1652 const char *rd_ser;
1640 unsigned int rd_count; 1653 unsigned int rd_count;
1641 int res; 1654 int res;
1642 struct StoreActivity *sa;
1643 struct GNUNET_TIME_Absolute existing_block_exp; 1655 struct GNUNET_TIME_Absolute existing_block_exp;
1644 struct GNUNET_TIME_Absolute new_block_exp; 1656 struct GNUNET_TIME_Absolute new_block_exp;
1645 1657 *len = sizeof (struct RecordSet);
1646 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1658
1647 "Received NAMESTORE_RECORD_STORE message\n"); 1659 name_len = ntohs (rd_set->name_len);
1648 existing_block_exp = GNUNET_TIME_UNIT_ZERO_ABS; 1660 *len += name_len;
1649 new_block_exp = GNUNET_TIME_UNIT_ZERO_ABS; 1661 rd_count = ntohs (rd_set->rd_count);
1650 rid = ntohl (rp_msg->gns_header.r_id); 1662 rd_ser_len = ntohs (rd_set->rd_len);
1651 name_len = ntohs (rp_msg->name_len); 1663 *len += rd_ser_len;
1652 rd_count = ntohs (rp_msg->rd_count); 1664 name_tmp = (const char *) &rd_set[1];
1653 rd_ser_len = ntohs (rp_msg->rd_len);
1654 name_tmp = (const char *) &rp_msg[1];
1655 rd_ser = &name_tmp[name_len]; 1665 rd_ser = &name_tmp[name_len];
1656 { 1666 {
1657 struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)]; 1667 struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
1658 char *emsg;
1659 1668
1660 /* Extracting and converting private key */ 1669 /* Extracting and converting private key */
1661 conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp); 1670 *conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1662 if (NULL == conv_name) 1671 if (NULL == *conv_name)
1663 { 1672 {
1664 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1673 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1665 "Error normalizing name `%s'\n", 1674 "Error normalizing name `%s'\n",
1666 name_tmp); 1675 name_tmp);
1667 send_store_response (nc, GNUNET_SYSERR, _ ("Error normalizing name."), 1676 *emsg = GNUNET_strdup (_ ("Error normalizing name."));
1668 rid); 1677 return GNUNET_SYSERR;
1669 GNUNET_SERVICE_client_continue (nc->client);
1670 return;
1671 } 1678 }
1672 1679
1673 /* Check name for validity */ 1680 /* Check name for validity */
1674 if (GNUNET_OK != GNUNET_GNSRECORD_label_check (conv_name, &emsg)) 1681 if (GNUNET_OK != GNUNET_GNSRECORD_label_check (*conv_name, emsg))
1675 { 1682 {
1676 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1683 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1677 "Label invalid: `%s'\n", 1684 "Label invalid: `%s'\n",
1678 emsg); 1685 *emsg);
1679 send_store_response (nc, GNUNET_SYSERR, emsg, rid); 1686 GNUNET_free (*conv_name);
1680 GNUNET_free (emsg); 1687 return -1;
1681 GNUNET_free (conv_name);
1682 GNUNET_SERVICE_client_continue (nc->client);
1683 return;
1684 } 1688 }
1685 1689
1686 if (GNUNET_OK != 1690 if (GNUNET_OK !=
1687 GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count, rd)) 1691 GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count, rd))
1688 { 1692 {
1689 send_store_response (nc, GNUNET_SYSERR, 1693 *emsg = GNUNET_strdup (_ ("Error deserializing records."));
1690 _ ("Error deserializing records."), rid); 1694 GNUNET_free (*conv_name);
1691 GNUNET_free (conv_name); 1695 return GNUNET_SYSERR;
1692 GNUNET_SERVICE_client_continue (nc->client);
1693 return;
1694 } 1696 }
1695 1697
1696 GNUNET_STATISTICS_update (statistics, 1698 GNUNET_STATISTICS_update (statistics,
@@ -1700,10 +1702,10 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1700 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1702 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1701 "Creating %u records for name `%s'\n", 1703 "Creating %u records for name `%s'\n",
1702 (unsigned int) rd_count, 1704 (unsigned int) rd_count,
1703 conv_name); 1705 *conv_name);
1704 if ((GNUNET_NO == nc->GSN_database->lookup_records (nc->GSN_database->cls, 1706 if ((GNUNET_NO == nc->GSN_database->lookup_records (nc->GSN_database->cls,
1705 &rp_msg->private_key, 1707 private_key,
1706 conv_name, 1708 *conv_name,
1707 &get_block_exp_existing, 1709 &get_block_exp_existing,
1708 &existing_block_exp)) && 1710 &existing_block_exp)) &&
1709 (rd_count == 0)) 1711 (rd_count == 0))
@@ -1711,7 +1713,7 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1711 /* This name does not exist, so cannot be removed */ 1713 /* This name does not exist, so cannot be removed */
1712 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1714 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1713 "Name `%s' does not exist, no deletion required\n", 1715 "Name `%s' does not exist, no deletion required\n",
1714 conv_name); 1716 *conv_name);
1715 res = GNUNET_NO; 1717 res = GNUNET_NO;
1716 } 1718 }
1717 else 1719 else
@@ -1728,7 +1730,6 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1728 struct GNUNET_GNSRECORD_Data rd_nf[GNUNET_NZL (rd_count) + 1]; 1730 struct GNUNET_GNSRECORD_Data rd_nf[GNUNET_NZL (rd_count) + 1];
1729 unsigned int rd_clean_off; 1731 unsigned int rd_clean_off;
1730 unsigned int rd_nf_count; 1732 unsigned int rd_nf_count;
1731 char *emsg;
1732 int have_nick; 1733 int have_nick;
1733 1734
1734 rd_clean_off = 0; 1735 rd_clean_off = 0;
@@ -1737,35 +1738,34 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1737 { 1738 {
1738 rd_clean[rd_clean_off] = rd[i]; 1739 rd_clean[rd_clean_off] = rd[i];
1739 1740
1740 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) || 1741 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, *conv_name)) ||
1741 (GNUNET_GNSRECORD_TYPE_NICK != rd[i].record_type)) 1742 (GNUNET_GNSRECORD_TYPE_NICK != rd[i].record_type))
1742 rd_clean_off++; 1743 rd_clean_off++;
1743 1744
1744 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) && 1745 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, *conv_name)) &&
1745 (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type)) 1746 (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type))
1746 { 1747 {
1747 cache_nick (&rp_msg->private_key, &rd[i]); 1748 // FIXME: In case this is an uncommited transaction,
1749 // we should not do this here. Can we do this in the store activity?
1750 cache_nick (private_key, &rd[i]);
1748 have_nick = GNUNET_YES; 1751 have_nick = GNUNET_YES;
1749 } 1752 }
1750 } 1753 }
1751 if (GNUNET_OK != 1754 if (GNUNET_OK !=
1752 GNUNET_GNSRECORD_normalize_record_set (conv_name, 1755 GNUNET_GNSRECORD_normalize_record_set (*conv_name,
1753 rd_clean, 1756 rd_clean,
1754 rd_clean_off, 1757 rd_clean_off,
1755 rd_nf, 1758 rd_nf,
1756 &rd_nf_count, 1759 &rd_nf_count,
1757 &new_block_exp, 1760 &new_block_exp,
1758 GNUNET_GNSRECORD_FILTER_NONE, 1761 GNUNET_GNSRECORD_FILTER_NONE,
1759 &emsg)) 1762 emsg))
1760 { 1763 {
1761 send_store_response (nc, GNUNET_SYSERR, emsg, rid); 1764 GNUNET_free (*conv_name);
1762 GNUNET_free (emsg); 1765 return GNUNET_SYSERR;
1763 GNUNET_SERVICE_client_continue (nc->client);
1764 GNUNET_free (conv_name);
1765 return;
1766 } 1766 }
1767 /* 1767 /*
1768 * If existing_block_exp is 0, then there was not record set 1768 * If existing_block_exp is 0, then there was no record set
1769 * and no tombstone. 1769 * and no tombstone.
1770 * Otherwise, if the existing block expiration is after the 1770 * Otherwise, if the existing block expiration is after the
1771 * new block expiration would be, we need to add a tombstone 1771 * new block expiration would be, we need to add a tombstone
@@ -1781,36 +1781,91 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1781 rd_nf[rd_nf_count].flags = GNUNET_GNSRECORD_RF_PRIVATE; 1781 rd_nf[rd_nf_count].flags = GNUNET_GNSRECORD_RF_PRIVATE;
1782 rd_nf_count++; 1782 rd_nf_count++;
1783 } 1783 }
1784 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) && 1784 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, *conv_name)) &&
1785 (GNUNET_NO == have_nick)) 1785 (GNUNET_NO == have_nick))
1786 { 1786 {
1787 /* remove nick record from cache, in case we have one there */ 1787 /* remove nick record from cache, in case we have one there */
1788 cache_nick (&rp_msg->private_key, NULL); 1788 // FIXME: In case this is an uncommited transaction,
1789 // we should not do this here. Can we do this in the store activity?
1790 cache_nick (private_key, NULL);
1789 } 1791 }
1790 res = nc->GSN_database->store_records (nc->GSN_database->cls, 1792 res = nc->GSN_database->store_records (nc->GSN_database->cls,
1791 &rp_msg->private_key, 1793 private_key,
1792 conv_name, 1794 *conv_name,
1793 rd_nf_count, 1795 rd_nf_count,
1794 rd_nf); 1796 rd_nf);
1795 } 1797 }
1796 1798
1797 if (GNUNET_OK != res) 1799 if (GNUNET_SYSERR == res)
1798 { 1800 {
1799 /* store not successful, no need to tell monitors */ 1801 /* store not successful, no need to tell monitors */
1800 send_store_response (nc, res, _ ("Store failed"), rid); 1802 *emsg = GNUNET_strdup (_ ("Store failed"));
1803 GNUNET_free (*conv_name);
1804 return GNUNET_SYSERR;
1805 }
1806 }
1807 return res;
1808}
1809
1810/**
1811 * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message
1812 *
1813 * @param cls client sending the message
1814 * @param rp_msg message of type `struct RecordStoreMessage`
1815 */
1816static void
1817handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1818{
1819 struct NamestoreClient *nc = cls;
1820 size_t name_len;
1821 size_t rd_ser_len;
1822 uint32_t rid;
1823 uint16_t rd_set_count;
1824 const char *name_tmp;
1825 char *conv_name;
1826 char *emsg = NULL;
1827 const char *buf;
1828 const char *rd_ser;
1829 unsigned int rd_count;
1830 ssize_t read;
1831 struct StoreActivity *sa;
1832 struct RecordSet *rs;
1833 struct GNUNET_TIME_Absolute existing_block_exp;
1834 struct GNUNET_TIME_Absolute new_block_exp;
1835 enum GNUNET_GenericReturnValue res;
1836
1837 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1838 "Received NAMESTORE_RECORD_STORE message\n");
1839 existing_block_exp = GNUNET_TIME_UNIT_ZERO_ABS;
1840 new_block_exp = GNUNET_TIME_UNIT_ZERO_ABS;
1841 rid = ntohl (rp_msg->gns_header.r_id);
1842 rd_set_count = ntohs (rp_msg->rd_set_count);
1843 buf = (const char *) &rp_msg[1];
1844 for (int i = 0; i < rd_set_count; i++)
1845 {
1846 rs = (struct RecordSet *) buf;
1847 res = store_record_set (nc, &rp_msg->private_key,
1848 rs, &conv_name, &read, &emsg);
1849 if (GNUNET_OK != res)
1850 {
1851 send_store_response (nc, res, emsg,
1852 rid);
1853 GNUNET_free (emsg);
1801 GNUNET_SERVICE_client_continue (nc->client); 1854 GNUNET_SERVICE_client_continue (nc->client);
1802 GNUNET_free (conv_name);
1803 return; 1855 return;
1804 } 1856 }
1805 sa = GNUNET_malloc (sizeof(struct StoreActivity) 1857 sa = GNUNET_malloc (sizeof(struct StoreActivity) + read);
1806 + ntohs (rp_msg->gns_header.header.size));
1807 GNUNET_CONTAINER_DLL_insert (sa_head, sa_tail, sa); 1858 GNUNET_CONTAINER_DLL_insert (sa_head, sa_tail, sa);
1808 sa->nc = nc; 1859 sa->nc = nc;
1809 sa->rsm = (const struct RecordStoreMessage *) &sa[1]; 1860 sa->rs = (const struct RecordSet *) &sa[1];
1810 GNUNET_memcpy (&sa[1], rp_msg, ntohs (rp_msg->gns_header.header.size)); 1861 GNUNET_memcpy (&sa[1], rs, read);
1862 sa->rid = rid;
1863 sa->private_key = rp_msg->private_key;
1811 sa->zm_pos = monitor_head; 1864 sa->zm_pos = monitor_head;
1812 sa->conv_name = conv_name; 1865 sa->conv_name = conv_name;
1866 sa->uncommited = nc->in_transaction;
1813 continue_store_activity (sa); 1867 continue_store_activity (sa);
1868 buf += read;
1814 } 1869 }
1815} 1870}
1816 1871
@@ -1826,6 +1881,8 @@ handle_tx_control (void *cls, const struct TxControlMessage *tx_msg)
1826 struct NamestoreClient *nc = cls; 1881 struct NamestoreClient *nc = cls;
1827 struct TxControlResultMessage *txr_msg; 1882 struct TxControlResultMessage *txr_msg;
1828 struct GNUNET_MQ_Envelope *env; 1883 struct GNUNET_MQ_Envelope *env;
1884 struct StoreActivity *sa = sa_head;
1885 struct StoreActivity *sn;
1829 enum GNUNET_GenericReturnValue ret; 1886 enum GNUNET_GenericReturnValue ret;
1830 char *emsg = NULL; 1887 char *emsg = NULL;
1831 char *err_tmp; 1888 char *err_tmp;
@@ -1836,14 +1893,47 @@ handle_tx_control (void *cls, const struct TxControlMessage *tx_msg)
1836 case GNUNET_NAMESTORE_TX_BEGIN: 1893 case GNUNET_NAMESTORE_TX_BEGIN:
1837 ret = nc->GSN_database->transaction_begin (nc->GSN_database->cls, 1894 ret = nc->GSN_database->transaction_begin (nc->GSN_database->cls,
1838 &emsg); 1895 &emsg);
1896 nc->in_transaction = GNUNET_YES;
1839 break; 1897 break;
1840 case GNUNET_NAMESTORE_TX_COMMIT: 1898 case GNUNET_NAMESTORE_TX_COMMIT:
1841 ret = nc->GSN_database->transaction_commit (nc->GSN_database->cls, 1899 ret = nc->GSN_database->transaction_commit (nc->GSN_database->cls,
1842 &emsg); 1900 &emsg);
1901 if (GNUNET_SYSERR != ret)
1902 {
1903 nc->in_transaction = GNUNET_NO;
1904 while (NULL != sa)
1905 {
1906 if ((nc != sa->nc) ||
1907 (GNUNET_NO == sa->uncommited))
1908 {
1909 sa = sa->next;
1910 continue;
1911 }
1912 sa->uncommited = GNUNET_NO;
1913 continue_store_activity (sa);
1914 sa = sa->next;
1915 }
1916 }
1843 break; 1917 break;
1844 case GNUNET_NAMESTORE_TX_ROLLBACK: 1918 case GNUNET_NAMESTORE_TX_ROLLBACK:
1845 ret = nc->GSN_database->transaction_rollback (nc->GSN_database->cls, 1919 ret = nc->GSN_database->transaction_rollback (nc->GSN_database->cls,
1846 &emsg); 1920 &emsg);
1921 if (GNUNET_SYSERR != ret)
1922 {
1923 nc->in_transaction = GNUNET_NO;
1924 while (NULL != sa)
1925 {
1926 if ((nc != sa->nc) ||
1927 (GNUNET_NO == sa->uncommited))
1928 {
1929 sa = sa->next;
1930 continue;
1931 }
1932 sn = sa->next;
1933 free_store_activity (sa);
1934 sa = sn;
1935 }
1936 }
1847 break; 1937 break;
1848 default: 1938 default:
1849 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1939 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
diff --git a/src/namestore/namestore.conf.in b/src/namestore/namestore.conf.in
index a9c928c66..fe7d4002c 100644
--- a/src/namestore/namestore.conf.in
+++ b/src/namestore/namestore.conf.in
@@ -21,12 +21,9 @@ CACHE_KEYS = YES
21 21
22 22
23[namestore-sqlite] 23[namestore-sqlite]
24INIT_ON_CONNECT = YES
24FILENAME = $GNUNET_DATA_HOME/namestore/sqlite.db 25FILENAME = $GNUNET_DATA_HOME/namestore/sqlite.db
25 26
26[namestore-heap]
27FILENAME = $GNUNET_DATA_HOME/namestore/heap.db
28
29
30[namestore-postgres] 27[namestore-postgres]
31# How to connect to the database 28# How to connect to the database
32CONFIG = postgres:///gnunet 29CONFIG = postgres:///gnunet
@@ -34,6 +31,7 @@ CONFIG = postgres:///gnunet
34TEMPORARY_TABLE = NO 31TEMPORARY_TABLE = NO
35# Use asynchronous commit (SET synchronous_commit TO OFF). 32# Use asynchronous commit (SET synchronous_commit TO OFF).
36ASYNC_COMMIT = NO 33ASYNC_COMMIT = NO
34INIT_ON_CONNECT = YES
37 35
38[uri] 36[uri]
39gns = gnunet-namestore -e 1a -u 37gns = gnunet-namestore -e 1a -u
diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h
index ad02ffb48..d7b6fd13e 100644
--- a/src/namestore/namestore.h
+++ b/src/namestore/namestore.h
@@ -51,23 +51,9 @@ struct GNUNET_NAMESTORE_Header
51 uint32_t r_id GNUNET_PACKED; 51 uint32_t r_id GNUNET_PACKED;
52}; 52};
53 53
54 54struct RecordSet
55/**
56 * Store a record to the namestore (as authority).
57 */
58struct RecordStoreMessage
59{ 55{
60 /** 56 /**
61 * Type will be #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE
62 */
63 struct GNUNET_NAMESTORE_Header gns_header;
64
65 /**
66 * Expiration time
67 */
68 struct GNUNET_TIME_AbsoluteNBO expire;
69
70 /**
71 * Name length 57 * Name length
72 */ 58 */
73 uint16_t name_len GNUNET_PACKED; 59 uint16_t name_len GNUNET_PACKED;
@@ -87,14 +73,35 @@ struct RecordStoreMessage
87 */ 73 */
88 uint16_t reserved GNUNET_PACKED; 74 uint16_t reserved GNUNET_PACKED;
89 75
76
77 /* followed by:
78 * name with length name_len
79 * serialized record data with rd_count records
80 */
81};
82
83/**
84 * Store a record to the namestore (as authority).
85 */
86struct RecordStoreMessage
87{
88 /**
89 * Type will be #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE
90 */
91 struct GNUNET_NAMESTORE_Header gns_header;
92
90 /** 93 /**
91 * The private key of the authority. 94 * The private key of the authority.
92 */ 95 */
93 struct GNUNET_IDENTITY_PrivateKey private_key; 96 struct GNUNET_IDENTITY_PrivateKey private_key;
94 97
95 /* followed by: 98 /**
96 * name with length name_len 99 * Number of record sets
97 * serialized record data with rd_count records 100 */
101 uint16_t rd_set_count;
102
103 /**
104 * Followed by rd_set_count RecordSets
98 */ 105 */
99}; 106};
100 107
diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c
index 51ee25acf..f9ed2b620 100644
--- a/src/namestore/namestore_api.c
+++ b/src/namestore/namestore_api.c
@@ -1095,32 +1095,60 @@ GNUNET_NAMESTORE_records_store (
1095 GNUNET_NAMESTORE_ContinuationWithStatus cont, 1095 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1096 void *cont_cls) 1096 void *cont_cls)
1097{ 1097{
1098 return GNUNET_NAMESTORE_records_store2 (h, pkey, 1, &label, &rd_count, &rd,
1099 cont, cont_cls);
1100}
1101
1102struct GNUNET_NAMESTORE_QueueEntry *
1103GNUNET_NAMESTORE_records_store2 (
1104 struct GNUNET_NAMESTORE_Handle *h,
1105 const struct GNUNET_IDENTITY_PrivateKey *pkey,
1106 unsigned int rd_set_count,
1107 const char **a_label,
1108 unsigned int *a_rd_count,
1109 const struct GNUNET_GNSRECORD_Data **a_rd,
1110 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1111 void *cont_cls)
1112{
1098 struct GNUNET_NAMESTORE_QueueEntry *qe; 1113 struct GNUNET_NAMESTORE_QueueEntry *qe;
1099 struct GNUNET_MQ_Envelope *env; 1114 struct GNUNET_MQ_Envelope *env;
1115 const char *label;
1116 unsigned int rd_count;
1117 const struct GNUNET_GNSRECORD_Data *rd;
1100 char *name_tmp; 1118 char *name_tmp;
1101 char *rd_ser; 1119 char *rd_ser;
1102 ssize_t rd_ser_len; 1120 ssize_t rd_ser_len[rd_set_count];
1103 size_t name_len; 1121 size_t name_len;
1104 uint32_t rid; 1122 uint32_t rid;
1105 struct RecordStoreMessage *msg; 1123 struct RecordStoreMessage *msg;
1124 struct RecordSet *rd_set;
1106 ssize_t sret; 1125 ssize_t sret;
1126 int i;
1127 size_t rd_set_len = 0;
1107 1128
1108 name_len = strlen (label) + 1; 1129 for (i = 0; i < rd_set_count; i++)
1109 if (name_len > MAX_NAME_LEN)
1110 { 1130 {
1111 GNUNET_break (0); 1131 label = a_label[i];
1112 return NULL; 1132 rd_count = a_rd_count[i];
1113 } 1133 rd = a_rd[i];
1114 rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd); 1134 name_len = strlen (label) + 1;
1115 if (rd_ser_len < 0) 1135 if (name_len > MAX_NAME_LEN)
1116 { 1136 {
1117 GNUNET_break (0); 1137 GNUNET_break (0);
1118 return NULL; 1138 return NULL;
1119 } 1139 }
1120 if (rd_ser_len > UINT16_MAX) 1140 rd_ser_len[i] = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1121 { 1141 if (rd_ser_len[i] < 0)
1122 GNUNET_break (0); 1142 {
1123 return NULL; 1143 GNUNET_break (0);
1144 return NULL;
1145 }
1146 if (rd_ser_len[i] > UINT16_MAX)
1147 {
1148 GNUNET_break (0);
1149 return NULL;
1150 }
1151 rd_set_len = sizeof (struct RecordSet) + name_len + rd_ser_len[i];
1124 } 1152 }
1125 rid = get_op_id (h); 1153 rid = get_op_id (h);
1126 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry); 1154 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
@@ -1132,30 +1160,38 @@ GNUNET_NAMESTORE_records_store (
1132 1160
1133 /* setup msg */ 1161 /* setup msg */
1134 env = GNUNET_MQ_msg_extra (msg, 1162 env = GNUNET_MQ_msg_extra (msg,
1135 name_len + rd_ser_len, 1163 rd_set_len,
1136 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE); 1164 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE);
1137 msg->gns_header.r_id = htonl (rid); 1165 msg->gns_header.r_id = htonl (rid);
1138 msg->name_len = htons (name_len); 1166 msg->rd_set_count = htons (rd_set_count);
1139 msg->rd_count = htons (rd_count);
1140 msg->rd_len = htons (rd_ser_len);
1141 msg->reserved = ntohs (0);
1142 msg->private_key = *pkey; 1167 msg->private_key = *pkey;
1143 1168 rd_set = (struct RecordSet*) &msg[1];
1144 name_tmp = (char *) &msg[1]; 1169 for (int i = 0; i < rd_set_count; i++)
1145 GNUNET_memcpy (name_tmp, label, name_len);
1146 rd_ser = &name_tmp[name_len];
1147 sret = GNUNET_GNSRECORD_records_serialize (rd_count, rd, rd_ser_len, rd_ser);
1148 if ((0 > sret) || (sret != rd_ser_len))
1149 { 1170 {
1150 GNUNET_break (0); 1171 label = a_label[i];
1151 GNUNET_free (env); 1172 rd = a_rd[i];
1152 return NULL; 1173 name_len = strlen (label) + 1;
1174 rd_set->name_len = htons (name_len);
1175 rd_set->rd_count = htons (a_rd_count[i]);
1176 rd_set->rd_len = htons (rd_ser_len[i]);
1177 rd_set->reserved = ntohs (0);
1178 name_tmp = (char *) &rd_set[1];
1179 GNUNET_memcpy (name_tmp, label, name_len);
1180 rd_ser = &name_tmp[name_len];
1181 sret = GNUNET_GNSRECORD_records_serialize (a_rd_count[i], rd, rd_ser_len[i],
1182 rd_ser);
1183 if ((0 > sret) || (sret != rd_ser_len[i]))
1184 {
1185 GNUNET_break (0);
1186 GNUNET_free (env);
1187 return NULL;
1188 }
1189 // Point to next RecordSet
1190 rd_set = (struct RecordSet*) &name_tmp[name_len + rd_ser_len[i]];
1153 } 1191 }
1154 GNUNET_assert (rd_ser_len == sret);
1155 LOG (GNUNET_ERROR_TYPE_DEBUG, 1192 LOG (GNUNET_ERROR_TYPE_DEBUG,
1156 "Sending NAMESTORE_RECORD_STORE message for name `%s' with %u records\n", 1193 "Sending NAMESTORE_RECORD_STORE message for name %u record sets\n",
1157 label, 1194 rd_set_count);
1158 rd_count);
1159 qe->timeout_task = 1195 qe->timeout_task =
1160 GNUNET_SCHEDULER_add_delayed (NAMESTORE_DELAY_TOLERANCE, &warn_delay, qe); 1196 GNUNET_SCHEDULER_add_delayed (NAMESTORE_DELAY_TOLERANCE, &warn_delay, qe);
1161 if (NULL == h->mq) 1197 if (NULL == h->mq)
@@ -1171,6 +1207,7 @@ GNUNET_NAMESTORE_records_store (
1171 return qe; 1207 return qe;
1172} 1208}
1173 1209
1210
1174static struct GNUNET_NAMESTORE_QueueEntry * 1211static struct GNUNET_NAMESTORE_QueueEntry *
1175records_lookup ( 1212records_lookup (
1176 struct GNUNET_NAMESTORE_Handle *h, 1213 struct GNUNET_NAMESTORE_Handle *h,
diff --git a/src/namestore/perf_namestore_api_postgres.conf b/src/namestore/perf_namestore_api_postgres.conf
index 52d0ecdd5..12fc24d4b 100644
--- a/src/namestore/perf_namestore_api_postgres.conf
+++ b/src/namestore/perf_namestore_api_postgres.conf
@@ -9,3 +9,4 @@ DISABLE = YES
9[namestore-postgres] 9[namestore-postgres]
10CONFIG = connect_timeout=10 dbname=gnunetcheck 10CONFIG = connect_timeout=10 dbname=gnunetcheck
11TEMPORARY_TABLE = YES 11TEMPORARY_TABLE = YES
12INIT_ON_CONNECT = YES
diff --git a/src/namestore/perf_namestore_api_sqlite.conf b/src/namestore/perf_namestore_api_sqlite.conf
index de0fa3f1f..55c3dc812 100644
--- a/src/namestore/perf_namestore_api_sqlite.conf
+++ b/src/namestore/perf_namestore_api_sqlite.conf
@@ -5,3 +5,4 @@ DISABLE = YES
5 5
6[namestore-sqlite] 6[namestore-sqlite]
7FILENAME = $GNUNET_TEST_HOME/namestore/sqlite_test.db 7FILENAME = $GNUNET_TEST_HOME/namestore/sqlite_test.db
8INIT_ON_CONNECT = YES
diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c
index f1097ad0a..35fd340ab 100644
--- a/src/namestore/plugin_namestore_sqlite.c
+++ b/src/namestore/plugin_namestore_sqlite.c
@@ -871,6 +871,7 @@ database_connect (struct Plugin *plugin)
871 GNUNET_free (sqlite_filename); 871 GNUNET_free (sqlite_filename);
872 return GNUNET_SYSERR; 872 return GNUNET_SYSERR;
873 } 873 }
874 GNUNET_free (sqlite_filename);
874 GNUNET_break (SQLITE_OK == 875 GNUNET_break (SQLITE_OK ==
875 sqlite3_busy_timeout (plugin->dbh, 876 sqlite3_busy_timeout (plugin->dbh,
876 BUSY_TIMEOUT_MS)); 877 BUSY_TIMEOUT_MS));
diff --git a/src/namestore/plugin_rest_namestore.c b/src/namestore/plugin_rest_namestore.c
index 0475960eb..b9c32e087 100644
--- a/src/namestore/plugin_rest_namestore.c
+++ b/src/namestore/plugin_rest_namestore.c
@@ -721,6 +721,114 @@ ns_lookup_cb (void *cls,
721 } 721 }
722} 722}
723 723
724/**
725 * Handle namestore POST import
726 *
727 * @param con_handle the connection handle
728 * @param url the url
729 * @param cls the RequestHandle
730 */
731/*void
732namestore_import (struct GNUNET_REST_RequestHandle *con_handle,
733 const char *url,
734 void *cls)
735{
736 struct RequestHandle *handle = cls;
737 struct EgoEntry *ego_entry;
738 struct GNUNET_GNSRECORD_Data *rd_import;
739 char *egoname;
740 json_t *data_js;
741 json_error_t err;
742
743 char term_data[handle->rest_handle->data_size + 1];
744
745 if (0 >= handle->rest_handle->data_size)
746 {
747 handle->response_code = MHD_HTTP_BAD_REQUEST;
748 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_NO_DATA);
749 GNUNET_SCHEDULER_add_now (&do_error, handle);
750 return;
751 }
752 term_data[handle->rest_handle->data_size] = '\0';
753 GNUNET_memcpy (term_data,
754 handle->rest_handle->data,
755 handle->rest_handle->data_size);
756 data_js = json_loads (term_data, JSON_DECODE_ANY, &err);
757 if (NULL == data_js)
758 {
759 GNUNET_asprintf (&handle->emsg, "Error parsing data: %s", err.text);
760 GNUNET_SCHEDULER_add_now (&do_error, handle);
761 return;
762 }
763 if (!json_is_array (data_js))
764 {
765 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_INVALID_DATA);
766 GNUNET_SCHEDULER_add_now (&do_error, handle);
767 json_decref (data_js);
768 return;
769 }
770 size_t num_records = json_array_size (data_js);
771 rd_import = GNUNET_malloc (sizeof (*rd_import) * json_array_size (data_js));
772 for (int i = 0; i < num_records)
773 struct GNUNET_JSON_Specification gnsspec[] =
774 { GNUNET_GNSRECORD_JSON_spec_gnsrecord (&handle->rd, &handle->rd_count,
775 &handle->record_name),
776 GNUNET_JSON_spec_end () };
777 if (GNUNET_OK != GNUNET_JSON_parse (data_js, gnsspec, NULL, NULL))
778 {
779 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_INVALID_DATA);
780 GNUNET_SCHEDULER_add_now (&do_error, handle);
781 json_decref (data_js);
782 return;
783 }
784 GNUNET_JSON_parse_free (gnsspec);
785 if (0 >= strlen (handle->record_name))
786 {
787 handle->response_code = MHD_HTTP_BAD_REQUEST;
788 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_INVALID_DATA);
789 GNUNET_SCHEDULER_add_now (&do_error, handle);
790 json_decref (data_js);
791 return;
792 }
793 json_decref (data_js);
794
795 egoname = NULL;
796 ego_entry = NULL;
797
798 // set zone to name if given
799 if (strlen (GNUNET_REST_API_NS_NAMESTORE) + 1 >= strlen (handle->url))
800 {
801 handle->response_code = MHD_HTTP_NOT_FOUND;
802 handle->emsg = GNUNET_strdup (GNUNET_REST_IDENTITY_NOT_FOUND);
803 GNUNET_SCHEDULER_add_now (&do_error, handle);
804 return;
805 }
806 egoname = &handle->url[strlen (GNUNET_REST_API_NS_NAMESTORE) + 1];
807 ego_entry = get_egoentry_namestore (handle, egoname);
808
809 if (NULL == ego_entry)
810 {
811 handle->response_code = MHD_HTTP_NOT_FOUND;
812 handle->emsg = GNUNET_strdup (GNUNET_REST_IDENTITY_NOT_FOUND);
813 GNUNET_SCHEDULER_add_now (&do_error, handle);
814 return;
815 }
816 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
817 handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
818 handle->zone_pkey,
819 handle->record_name,
820 &ns_lookup_error_cb,
821 handle,
822 &ns_lookup_cb,
823 handle);
824 if (NULL == handle->ns_qe)
825 {
826 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_FAILED);
827 GNUNET_SCHEDULER_add_now (&do_error, handle);
828 return;
829 }
830}
831*/
724 832
725/** 833/**
726 * Handle namestore POST/PUT request 834 * Handle namestore POST/PUT request
diff --git a/src/namestore/test_plugin_namestore_postgres.conf b/src/namestore/test_plugin_namestore_postgres.conf
index 2ce8a7792..3b5cb8699 100644
--- a/src/namestore/test_plugin_namestore_postgres.conf
+++ b/src/namestore/test_plugin_namestore_postgres.conf
@@ -1,3 +1,4 @@
1[namestore-postgres] 1[namestore-postgres]
2CONFIG = connect_timeout=10 dbname=gnunetcheck 2CONFIG = connect_timeout=10 dbname=gnunetcheck
3INIT_ON_CONNECT = YES
3TEMPORARY_TABLE = YES 4TEMPORARY_TABLE = YES
diff --git a/src/namestore/test_plugin_namestore_sqlite.conf b/src/namestore/test_plugin_namestore_sqlite.conf
index 24eecd286..365198db2 100644
--- a/src/namestore/test_plugin_namestore_sqlite.conf
+++ b/src/namestore/test_plugin_namestore_sqlite.conf
@@ -1,2 +1,3 @@
1[namestore-sqlite] 1[namestore-sqlite]
2FILENAME = $GNUNET_TMP/gnunet-test-plugin-namestore-sqlite/sqlite.db 2FILENAME = $GNUNET_TMP/gnunet-test-plugin-namestore-sqlite/sqlite.db
3INIT_ON_CONNECT = YES