/*
* This file is part of GNUnet
- * (C) 2009, 2011, 2012 Christian Grothoff (and other contributing authors)
+ * Copyright (C) 2009-2013, 2016 GNUnet e.V.
*
* GNUnet is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
*
* You should have received a copy of the GNU General Public License
* along with GNUnet; see the file COPYING. If not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
/**
* @brief postgres-based namestore backend
* @author Christian Grothoff
*/
-
#include "platform.h"
#include "gnunet_namestore_plugin.h"
#include "gnunet_namestore_service.h"
+#include "gnunet_gnsrecord_lib.h"
#include "gnunet_postgres_lib.h"
+#include "gnunet_pq_lib.h"
#include "namestore.h"
struct Plugin
{
+ /**
+ * Our configuration.
+ */
const struct GNUNET_CONFIGURATION_Handle *cfg;
/**
{
/* create indices */
if ( (GNUNET_OK !=
- GNUNET_POSTGRES_exec (dbh, "CREATE INDEX ir_zone_name_rv ON ns091records (zone_hash,record_name_hash,rvalue)")) ||
- (GNUNET_OK !=
- GNUNET_POSTGRES_exec (dbh, "CREATE INDEX ir_zone_delegation ON ns091records (zone_hash,zone_delegation)")) ||
+ GNUNET_POSTGRES_exec (dbh,
+ "CREATE INDEX ir_pkey_reverse ON ns097records (zone_private_key,pkey)")) ||
(GNUNET_OK !=
- GNUNET_POSTGRES_exec (dbh, "CREATE INDEX ir_zone_rv ON ns091records (zone_hash,rvalue)")) ||
+ GNUNET_POSTGRES_exec (dbh,
+ "CREATE INDEX ir_pkey_iter ON ns097records (zone_private_key,rvalue)")) ||
(GNUNET_OK !=
- GNUNET_POSTGRES_exec (dbh, "CREATE INDEX ir_zone ON ns091records (zone_hash)")) ||
+ GNUNET_POSTGRES_exec (dbh, "CREATE INDEX it_iter ON ns097records (rvalue)")) ||
(GNUNET_OK !=
- GNUNET_POSTGRES_exec (dbh, "CREATE INDEX ir_name_rv ON ns091records (record_name_hash,rvalue)")) ||
- (GNUNET_OK !=
- GNUNET_POSTGRES_exec (dbh, "CREATE INDEX ir_rv ON ns091records (rvalue)")) )
- LOG (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_POSTGRES_exec (dbh, "CREATE INDEX ir_label ON ns097records (label)")) )
+ LOG (GNUNET_ERROR_TYPE_ERROR,
_("Failed to create indices\n"));
}
* as needed as well).
*
* @param plugin the plugin context (state for this module)
- * @return GNUNET_OK on success
+ * @return #GNUNET_OK on success
*/
static int
database_setup (struct Plugin *plugin)
"namestore-postgres");
if (NULL == plugin->dbh)
return GNUNET_SYSERR;
- if (GNUNET_YES ==
+ if (GNUNET_YES ==
GNUNET_CONFIGURATION_get_value_yesno (plugin->cfg,
"namestore-postgres",
"TEMPORARY_TABLE"))
{
res =
PQexec (plugin->dbh,
- "CREATE TEMPORARY TABLE ns091records ("
- " zone_key BYTEA NOT NULL DEFAULT '',"
- " zone_delegation BYTEA NOT NULL DEFAULT '',"
- " zone_hash BYTEA NOT NULL DEFAULT '',"
+ "CREATE TEMPORARY TABLE ns097records ("
+ " zone_private_key BYTEA NOT NULL DEFAULT '',"
+ " pkey BYTEA DEFAULT '',"
+ " rvalue BYTEA NOT NULL DEFAULT '',"
" record_count INTEGER NOT NULL DEFAULT 0,"
" record_data BYTEA NOT NULL DEFAULT '',"
- " block_expiration_time BIGINT NOT NULL DEFAULT 0,"
- " signature BYTEA NOT NULL DEFAULT '',"
- " record_name TEXT NOT NULL DEFAULT '',"
- " record_name_hash BYTEA NOT NULL DEFAULT '',"
- " rvalue BIGINT NOT NULL DEFAULT 0"
+ " label TEXT NOT NULL DEFAULT ''"
")" "WITH OIDS");
}
else
+ {
res =
PQexec (plugin->dbh,
- "CREATE TABLE ns091records ("
- " zone_key BYTEA NOT NULL DEFAULT '',"
- " zone_delegation BYTEA NOT NULL DEFAULT '',"
- " zone_hash BYTEA NOT NULL DEFAULT '',"
+ "CREATE TABLE ns097records ("
+ " zone_private_key BYTEA NOT NULL DEFAULT '',"
+ " pkey BYTEA DEFAULT '',"
+ " rvalue BYTEA NOT NULL DEFAULT '',"
" record_count INTEGER NOT NULL DEFAULT 0,"
" record_data BYTEA NOT NULL DEFAULT '',"
- " block_expiration_time BIGINT NOT NULL DEFAULT 0,"
- " signature BYTEA NOT NULL DEFAULT '',"
- " record_name TEXT NOT NULL DEFAULT '',"
- " record_name_hash BYTEA NOT NULL DEFAULT '',"
- " rvalue BIGINT NOT NULL DEFAULT 0"
+ " label TEXT NOT NULL DEFAULT ''"
")" "WITH OIDS");
-
- if ((NULL == res) || ((PQresultStatus (res) != PGRES_COMMAND_OK) && (0 != strcmp ("42P07", /* duplicate table */
- PQresultErrorField
- (res,
- PG_DIAG_SQLSTATE)))))
+ }
+ if ( (NULL == res) ||
+ ((PQresultStatus (res) != PGRES_COMMAND_OK) &&
+ (0 != strcmp ("42P07", /* duplicate table */
+ PQresultErrorField
+ (res,
+ PG_DIAG_SQLSTATE)))))
{
- (void) GNUNET_POSTGRES_check_result (plugin->dbh, res, PGRES_COMMAND_OK, "CREATE TABLE",
- "ns091records");
+ (void) GNUNET_POSTGRES_check_result (plugin->dbh, res,
+ PGRES_COMMAND_OK, "CREATE TABLE",
+ "ns097records");
PQfinish (plugin->dbh);
plugin->dbh = NULL;
return GNUNET_SYSERR;
}
- if (PQresultStatus (res) == PGRES_COMMAND_OK)
- create_indices (plugin->dbh);
- PQclear (res);
+ create_indices (plugin->dbh);
-#define ALL "zone_key, record_name, record_count, record_data, block_expiration_time, signature"
if ((GNUNET_OK !=
GNUNET_POSTGRES_prepare (plugin->dbh,
- "put_records",
- "INSERT INTO ns091records (" ALL
- ", zone_delegation, zone_hash, record_name_hash, rvalue) VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", 10)) ||
- (GNUNET_OK !=
- GNUNET_POSTGRES_prepare (plugin->dbh,
- "remove_records",
- "DELETE FROM ns091records WHERE zone_hash=$1 AND record_name_hash=$2", 2)) ||
+ "store_records",
+ "INSERT INTO ns097records (zone_private_key, pkey, rvalue, record_count, record_data, label) VALUES "
+ "($1, $2, $3, $4, $5, $6)", 6)) ||
(GNUNET_OK !=
GNUNET_POSTGRES_prepare (plugin->dbh,
- "iterate_records",
- "SELECT " ALL
- " FROM ns091records WHERE zone_hash=$1 AND record_name_hash=$2 ORDER BY rvalue LIMIT 1 OFFSET $3", 3)) ||
+ "delete_records",
+ "DELETE FROM ns097records WHERE zone_private_key=$1 AND label=$2", 2)) ||
(GNUNET_OK !=
GNUNET_POSTGRES_prepare (plugin->dbh,
- "iterate_by_zone",
- "SELECT " ALL
- " FROM ns091records WHERE zone_hash=$1 ORDER BY rvalue LIMIT 1 OFFSET $2", 2)) ||
- (GNUNET_OK !=
- GNUNET_POSTGRES_prepare (plugin->dbh,
- "iterate_by_name",
- "SELECT " ALL
- " FROM ns091records WHERE record_name_hash=$1 ORDER BY rvalue LIMIT 1 OFFSET $2", 2)) ||
+ "zone_to_name",
+ "SELECT record_count,record_data,label FROM ns097records"
+ " WHERE zone_private_key=$1 AND pkey=$2", 2)) ||
(GNUNET_OK !=
GNUNET_POSTGRES_prepare (plugin->dbh,
- "iterate_all",
- "SELECT " ALL
- " FROM ns091records ORDER BY rvalue LIMIT 1 OFFSET $1", 1)) ||
+ "iterate_zone",
+ "SELECT record_count,record_data,label FROM ns097records"
+ " WHERE zone_private_key=$1 ORDER BY rvalue LIMIT 1 OFFSET $2", 2)) ||
(GNUNET_OK !=
GNUNET_POSTGRES_prepare (plugin->dbh,
- "zone_to_name",
- "SELECT " ALL
- " FROM ns091records WHERE zone_hash=$1 AND zone_delegation=$2", 2)) ||
+ "iterate_all_zones",
+ "SELECT record_count,record_data,label,zone_private_key"
+ " FROM ns097records ORDER BY rvalue LIMIT 1 OFFSET $1", 1)) ||
(GNUNET_OK !=
GNUNET_POSTGRES_prepare (plugin->dbh,
- "delete_zone",
- "DELETE FROM ns091records WHERE zone_hash=$1", 1)))
+ "lookup_label",
+ "SELECT record_count,record_data,label"
+ " FROM ns097records WHERE zone_private_key=$1 AND label=$2", 2)))
{
PQfinish (plugin->dbh);
plugin->dbh = NULL;
return GNUNET_SYSERR;
}
-#undef ALL
- return GNUNET_OK;
-}
-
-
-/**
- * Removes any existing record in the given zone with the same name.
- *
- * @param cls closure (internal context for the plugin)
- * @param zone hash of the public key of the zone
- * @param name name to remove (at most 255 characters long)
- * @return GNUNET_OK on success
- */
-static int
-namestore_postgres_remove_records (void *cls,
- const struct GNUNET_CRYPTO_ShortHashCode *zone,
- const char *name)
-{
- struct Plugin *plugin = cls;
- PGresult *ret;
- struct GNUNET_CRYPTO_ShortHashCode nh;
- const char *paramValues[] = {
- (const char *) zone,
- (const char *) &nh
- };
- int paramLengths[] = {
- sizeof (struct GNUNET_CRYPTO_ShortHashCode),
- sizeof (struct GNUNET_CRYPTO_ShortHashCode)
- };
- const int paramFormats[] = { 1, 1 };
- size_t name_len;
-
- name_len = strlen (name);
- GNUNET_CRYPTO_short_hash (name, name_len, &nh);
- ret =
- PQexecPrepared (plugin->dbh, "remove_records", 2, paramValues, paramLengths,
- paramFormats, 1);
- if (GNUNET_OK !=
- GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "PQexecPrepared", "remove_records"))
- return GNUNET_SYSERR;
- PQclear (ret);
return GNUNET_OK;
}
* same zone with the same name.
*
* @param cls closure (internal context for the plugin)
- * @param zone_key public key of the zone
- * @param expire when does the corresponding block in the DHT expire (until
- * when should we never do a DHT lookup for the same name again)?
- * @param name name that is being mapped (at most 255 characters long)
- * @param rd_count number of entries in 'rd' array
+ * @param zone_key private key of the zone
+ * @param label name that is being mapped (at most 255 characters long)
+ * @param rd_count number of entries in @a rd array
* @param rd array of records with data to store
- * @param signature signature of the record block, NULL if signature is unavailable (i.e.
- * because the user queried for a particular record type only)
- * @return GNUNET_OK on success, else GNUNET_SYSERR
+ * @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
-static int
-namestore_postgres_put_records (void *cls,
- const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
- struct GNUNET_TIME_Absolute expire,
- const char *name,
- unsigned int rd_count,
- const struct GNUNET_NAMESTORE_RecordData *rd,
- const struct GNUNET_CRYPTO_RsaSignature *signature)
+static int
+namestore_postgres_store_records (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
+ const char *label,
+ unsigned int rd_count,
+ const struct GNUNET_GNSRECORD_Data *rd)
{
struct Plugin *plugin = cls;
- PGresult *ret;
- struct GNUNET_CRYPTO_ShortHashCode zone;
- struct GNUNET_CRYPTO_ShortHashCode zone_delegation;
- struct GNUNET_CRYPTO_ShortHashCode nh;
- size_t name_len;
+ struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
uint64_t rvalue;
+ uint32_t rd_count_nbo = htonl ((uint32_t) rd_count);
size_t data_size;
unsigned int i;
- GNUNET_CRYPTO_short_hash (zone_key,
- sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
- &zone);
- (void) namestore_postgres_remove_records (plugin, &zone, name);
- name_len = strlen (name);
- GNUNET_CRYPTO_short_hash (name, name_len, &nh);
- memset (&zone_delegation, 0, sizeof (zone_delegation));
+ memset (&pkey, 0, sizeof (pkey));
for (i=0;i<rd_count;i++)
- if (rd[i].record_type == GNUNET_NAMESTORE_TYPE_PKEY)
+ if (GNUNET_GNSRECORD_TYPE_PKEY == rd[i].record_type)
{
- GNUNET_assert (sizeof (struct GNUNET_CRYPTO_ShortHashCode) == rd[i].data_size);
- memcpy (&zone_delegation,
- rd[i].data,
- sizeof (struct GNUNET_CRYPTO_ShortHashCode));
+ GNUNET_break (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) == rd[i].data_size);
+ memcpy (&pkey,
+ rd[i].data,
+ rd[i].data_size);
break;
}
rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
- data_size = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
+ data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
if (data_size > 64 * 65536)
{
GNUNET_break (0);
}
{
char data[data_size];
- uint64_t expire_be = GNUNET_htonll (expire.abs_value);
- uint64_t rvalue_be = GNUNET_htonll (rvalue);
- uint32_t rd_count_be = htonl ((uint32_t) rd_count);
+ // FIXME: use libgnunetpq!
const char *paramValues[] = {
(const char *) zone_key,
- (const char *) name,
- (const char *) &rd_count_be,
+ (const char *) &pkey,
+ (const char *) &rvalue,
+ (const char *) &rd_count_nbo,
(const char *) data,
- (const char *) &expire_be,
- (const char *) signature,
- (const char *) &zone_delegation,
- (const char *) &zone,
- (const char *) &nh,
- (const char *) &rvalue_be
+ label
};
int paramLengths[] = {
- sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
- name_len,
- sizeof (uint32_t),
+ sizeof (*zone_key),
+ sizeof (pkey),
+ sizeof (rvalue),
+ sizeof (rd_count_nbo),
data_size,
- sizeof (uint64_t),
- sizeof (struct GNUNET_CRYPTO_RsaSignature),
- sizeof (struct GNUNET_CRYPTO_ShortHashCode),
- sizeof (struct GNUNET_CRYPTO_ShortHashCode),
- sizeof (struct GNUNET_CRYPTO_ShortHashCode),
- sizeof (uint64_t)
+ strlen (label)
};
- const int paramFormats[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+ const int paramFormats[] = { 1, 1, 1, 1, 1, 1 };
+ PGresult *res;
- if (data_size != GNUNET_NAMESTORE_records_serialize (rd_count, rd,
+ if (data_size != GNUNET_GNSRECORD_records_serialize (rd_count, rd,
data_size, data))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
- ret =
- PQexecPrepared (plugin->dbh, "put_records", 10, paramValues, paramLengths,
- paramFormats, 1);
+
+ res =
+ PQexecPrepared (plugin->dbh, "store_records", 6,
+ paramValues, paramLengths, paramFormats, 1);
if (GNUNET_OK !=
- GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "PQexecPrepared", "put_records"))
+ GNUNET_POSTGRES_check_result (plugin->dbh,
+ res,
+ PGRES_COMMAND_OK,
+ "PQexecPrepared",
+ "store_records"))
return GNUNET_SYSERR;
- PQclear (ret);
+ PQclear (res);
+ return GNUNET_OK;
}
- return GNUNET_OK;
}
/**
- * The given 'postgres' result was obtained from the database.
- * Parse the record and give it to the iterator.
+ * A statement has been run. We should evaluate the result, and if possible
+ * call the given @a iter with the result.
*
* @param plugin plugin context
- * @param stmt_name name of the prepared statement that was executed
- * @param res result from postgres to interpret (and then clean up)
+ * @param res result from the statement that was run (to be cleaned up)
+ * @param zone_key private key of the zone, could be NULL, in which case we should
+ * get the zone from @a res
* @param iter iterator to call with the result
- * @param iter_cls closure for 'iter'
- * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error
- * 'iter' will have been called unless the return value is 'GNUNET_SYSERR'
+ * @param iter_cls closure for @a iter
+ * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
*/
static int
get_record_and_call_iterator (struct Plugin *plugin,
- const char *stmt_name,
- PGresult *res,
+ PGresult *res,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
{
- unsigned int record_count;
- size_t data_size;
- const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key;
- const struct GNUNET_CRYPTO_RsaSignature *sig;
- struct GNUNET_TIME_Absolute expiration;
const char *data;
- const char *name;
+ size_t data_size;
+ uint32_t record_count;
+ const char *label;
+ size_t label_len;
unsigned int cnt;
- size_t name_len;
if (GNUNET_OK !=
- GNUNET_POSTGRES_check_result (plugin->dbh, res, PGRES_TUPLES_OK, "PQexecPrepared",
- stmt_name))
+ GNUNET_POSTGRES_check_result (plugin->dbh, res, PGRES_TUPLES_OK,
+ "PQexecPrepared",
+ "iteration"))
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Ending iteration (postgres error)\n");
+ "Failing lookup (postgres error)\n");
return GNUNET_SYSERR;
}
-
if (0 == (cnt = PQntuples (res)))
{
/* no result */
- LOG (GNUNET_ERROR_TYPE_DEBUG,
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
"Ending iteration (no more results)\n");
PQclear (res);
- iter (iter_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL);
return GNUNET_NO;
}
GNUNET_assert (1 == cnt);
- if ((6 != PQnfields (res)) ||
- (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) != PQgetlength (res, 0, 0)) ||
- (sizeof (uint32_t) != PQfsize (res, 2)) ||
- (sizeof (uint64_t) != PQfsize (res, 4)) ||
- (sizeof (struct GNUNET_CRYPTO_RsaSignature) != PQgetlength (res, 0, 5)))
+ GNUNET_assert (3 + ((NULL == zone_key) ? 1 : 0) == PQnfields (res));
+ if (NULL == zone_key)
+ {
+ if (sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey) != PQgetlength (res, 0, 3))
+ {
+ GNUNET_break (0);
+ PQclear (res);
+ return GNUNET_SYSERR;
+ }
+ zone_key = (const struct GNUNET_CRYPTO_EcdsaPrivateKey *) PQgetvalue (res, 0, 3);
+ }
+ if (sizeof (uint32_t) != PQfsize (res, 0))
{
GNUNET_break (0);
PQclear (res);
return GNUNET_SYSERR;
}
- zone_key = (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) PQgetvalue (res, 0, 0);
- name = PQgetvalue (res, 0, 1);
- name_len = PQgetlength (res, 0, 1);
- record_count = ntohl (*(uint32_t *) PQgetvalue (res, 0, 2));
- data_size = PQgetlength (res, 0, 3);
- data = PQgetvalue (res, 0, 3);
- expiration.abs_value =
- GNUNET_ntohll (*(uint64_t *) PQgetvalue (res, 0, 4));
- sig = (const struct GNUNET_CRYPTO_RsaSignature*) PQgetvalue (res, 0, 5);
+
+ record_count = ntohl (*(uint32_t *) PQgetvalue (res, 0, 0));
+ data = PQgetvalue (res, 0, 1);
+ data_size = PQgetlength (res, 0, 1);
+ label = PQgetvalue (res, 0, 2);
+ label_len = PQgetlength (res, 0, 1);
if (record_count > 64 * 1024)
{
/* sanity check, don't stack allocate far too much just
return GNUNET_SYSERR;
}
{
- struct GNUNET_NAMESTORE_RecordData rd[record_count];
- char buf[name_len + 1];
-
- memcpy (buf, name, name_len);
- buf[name_len] = '\0';
+ struct GNUNET_GNSRECORD_Data rd[record_count];
+ char buf[label_len + 1];
+
+ memcpy (buf, label, label_len);
+ buf[label_len] = '\0';
if (GNUNET_OK !=
- GNUNET_NAMESTORE_records_deserialize (data_size, data,
+ GNUNET_GNSRECORD_records_deserialize (data_size, data,
record_count, rd))
{
GNUNET_break (0);
PQclear (res);
return GNUNET_SYSERR;
}
- iter (iter_cls, zone_key, expiration, buf,
- record_count, rd, sig);
+ iter (iter_cls, zone_key, buf, record_count, rd);
}
PQclear (res);
return GNUNET_OK;
}
-
-
+
+
/**
- * Iterate over the results for a particular key and zone in the
- * datastore. Will return at most one result to the iterator.
+ * Lookup records in the datastore for which we are the authority.
*
* @param cls closure (internal context for the plugin)
- * @param zone hash of public key of the zone, NULL to iterate over all zones
- * @param name name as string, NULL to iterate over all records of the zone
- * @param offset offset in the list of all matching records
+ * @param zone private key of the zone
+ * @param label name of the record in the zone
* @param iter function to call with the result
- * @param iter_cls closure for iter
- * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error
- * 'iter' will have been called unless the return value is 'GNUNET_SYSERR'
+ * @param iter_cls closure for @a iter
+ * @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
-static int
-namestore_postgres_iterate_records (void *cls,
- const struct GNUNET_CRYPTO_ShortHashCode *zone,
- const char *name,
- uint64_t offset,
- GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
+static int
+namestore_postgres_lookup_records (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+ const char *label,
+ GNUNET_NAMESTORE_RecordIterator iter,
+ void *iter_cls)
{
struct Plugin *plugin = cls;
- const char *stmt_name;
- struct GNUNET_CRYPTO_ShortHashCode name_hase;
- uint64_t offset_be = GNUNET_htonll (offset);
const char *paramValues[] = {
(const char *) zone,
- (const char *) &name_hase,
- (const char *) &offset_be,
- (const char *) zone,
- (const char *) &offset_be,
+ label
};
int paramLengths[] = {
- sizeof (struct GNUNET_CRYPTO_ShortHashCode),
- sizeof (struct GNUNET_CRYPTO_ShortHashCode),
- sizeof (uint64_t),
- sizeof (struct GNUNET_CRYPTO_ShortHashCode),
- sizeof (uint64_t)
+ sizeof (*zone),
+ strlen (label)
};
- const int paramFormats[] = { 1, 1, 1, 1, 1 };
- unsigned int num_params;
- unsigned int first_param;
+ const int paramFormats[] = { 1, 1 };
PGresult *res;
- if (NULL == zone)
- if (NULL == name)
- {
- stmt_name = "iterate_all";
- num_params = 1;
- first_param = 2;
- }
- else
- {
- GNUNET_CRYPTO_short_hash (name, strlen(name), &name_hase);
- stmt_name = "iterate_by_name";
- num_params = 2;
- first_param = 1;
- }
- else
- if (NULL == name)
- {
- stmt_name = "iterate_by_zone";
- num_params = 2;
- first_param = 3;
- }
- else
- {
- GNUNET_CRYPTO_short_hash (name, strlen(name), &name_hase);
- stmt_name = "iterate_records";
- num_params = 3;
- first_param = 0;
- }
- res =
- PQexecPrepared (plugin->dbh, stmt_name, num_params,
- ¶mValues[first_param],
- ¶mLengths[first_param],
- ¶mFormats[first_param], 1);
- return get_record_and_call_iterator (plugin, stmt_name, res, iter, iter_cls);
+ res = PQexecPrepared (plugin->dbh,
+ "lookup_label", 2,
+ paramValues, paramLengths, paramFormats,
+ 1);
+ return get_record_and_call_iterator (plugin,
+ res,
+ zone,
+ iter, iter_cls);
}
/**
- * Look for an existing PKEY delegation record for a given public key.
- * Returns at most one result to the iterator.
+ * Iterate over the results for a particular key and zone in the
+ * datastore. Will return at most one result to the iterator.
*
* @param cls closure (internal context for the plugin)
- * @param zone hash of public key of the zone to look up in, never NULL
- * @param value_zone hash of the public key of the target zone (value), never NULL
+ * @param zone hash of public key of the zone, NULL to iterate over all zones
+ * @param offset offset in the list of all matching records
* @param iter function to call with the result
- * @param iter_cls closure for iter
- * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error
- * 'iter' will have been called unless the return value is 'GNUNET_SYSERR'
+ * @param iter_cls closure for @a iter
+ * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
*/
static int
-namestore_postgres_zone_to_name (void *cls,
- const struct GNUNET_CRYPTO_ShortHashCode *zone,
- const struct GNUNET_CRYPTO_ShortHashCode *value_zone,
- GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
+namestore_postgres_iterate_records (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+ uint64_t offset,
+ GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
{
struct Plugin *plugin = cls;
- const char *paramValues[] = {
- (const char *) zone,
- (const char *) value_zone
- };
- int paramLengths[] = {
- sizeof (struct GNUNET_CRYPTO_ShortHashCode),
- sizeof (struct GNUNET_CRYPTO_ShortHashCode)
- };
- const int paramFormats[] = { 1, 1 };
- PGresult *res;
+ uint64_t offset_be = GNUNET_htonll (offset);
- res =
- PQexecPrepared (plugin->dbh, "zone_to_name", 2,
- paramValues, paramLengths, paramFormats, 1);
- return get_record_and_call_iterator (plugin, "zone_to_name", res, iter, iter_cls);
+ if (NULL == zone)
+ {
+ const char *paramValues[] = {
+ (const char *) &offset_be
+ };
+ int paramLengths[] = {
+ sizeof (offset_be)
+ };
+ const int paramFormats[] = { 1 };
+ PGresult *res;
+
+ res = PQexecPrepared (plugin->dbh,
+ "iterate_all_zones", 1,
+ paramValues, paramLengths, paramFormats,
+ 1);
+ return get_record_and_call_iterator (plugin,
+ res,
+ NULL,
+ iter, iter_cls);
+ }
+ else
+ {
+ const char *paramValues[] = {
+ (const char *) zone,
+ (const char *) &offset_be
+ };
+ int paramLengths[] = {
+ sizeof (*zone),
+ sizeof (offset_be)
+ };
+ const int paramFormats[] = { 1, 1 };
+ PGresult *res;
+
+ res = PQexecPrepared (plugin->dbh,
+ "iterate_zone", 2,
+ paramValues, paramLengths, paramFormats,
+ 1);
+ return get_record_and_call_iterator (plugin,
+ res,
+ zone,
+ iter, iter_cls);
+ }
}
/**
- * Delete an entire zone (all records). Not used in normal operation.
+ * Look for an existing PKEY delegation record for a given public key.
+ * Returns at most one result to the iterator.
*
* @param cls closure (internal context for the plugin)
- * @param zone zone to delete
+ * @param zone private key of the zone to look up in, never NULL
+ * @param value_zone public key of the target zone (value), never NULL
+ * @param iter function to call with the result
+ * @param iter_cls closure for @a iter
+ * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
*/
-static void
-namestore_postgres_delete_zone (void *cls,
- const struct GNUNET_CRYPTO_ShortHashCode *zone)
+static int
+namestore_postgres_zone_to_name (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone,
+ GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
{
struct Plugin *plugin = cls;
- PGresult *ret;
const char *paramValues[] = {
(const char *) zone,
+ (const char *) value_zone
};
int paramLengths[] = {
- sizeof (struct GNUNET_CRYPTO_ShortHashCode)
+ sizeof (*zone),
+ sizeof (*value_zone)
};
- const int paramFormats[] = { 1 };
+ const int paramFormats[] = { 1, 1 };
+ PGresult *res;
- ret =
- PQexecPrepared (plugin->dbh, "delete_zone", 1, paramValues, paramLengths,
- paramFormats, 1);
- if (GNUNET_OK !=
- GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "PQexecPrepared", "delete_zone"))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Deleting zone failed!\n");
- return;
- }
- PQclear (ret);
+ res = PQexecPrepared (plugin->dbh,
+ "zone_to_name", 2,
+ paramValues, paramLengths, paramFormats,
+ 1);
+ return get_record_and_call_iterator (plugin,
+ res,
+ zone,
+ iter, iter_cls);
}
/**
* Entry point for the plugin.
*
- * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*"
+ * @param cls the `struct GNUNET_NAMESTORE_PluginEnvironment*`
* @return NULL on error, othrewise the plugin context
*/
void *
if (NULL != plugin.cfg)
return NULL; /* can only initialize once! */
memset (&plugin, 0, sizeof (struct Plugin));
- plugin.cfg = cfg;
+ plugin.cfg = cfg;
if (GNUNET_OK != database_setup (&plugin))
{
database_shutdown (&plugin);
return NULL;
}
- api = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_PluginFunctions));
+ api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions);
api->cls = &plugin;
- api->put_records = &namestore_postgres_put_records;
- api->remove_records = &namestore_postgres_remove_records;
+ api->store_records = &namestore_postgres_store_records;
api->iterate_records = &namestore_postgres_iterate_records;
api->zone_to_name = &namestore_postgres_zone_to_name;
- api->delete_zone = &namestore_postgres_delete_zone;
- LOG (GNUNET_ERROR_TYPE_INFO,
+ api->lookup_records = &namestore_postgres_lookup_records;
+ LOG (GNUNET_ERROR_TYPE_INFO,
_("Postgres database running\n"));
return api;
}
database_shutdown (plugin);
plugin->cfg = NULL;
GNUNET_free (api);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
"postgres plugin is finished\n");
return NULL;
}