aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/datacache/plugin_datacache_postgres.c25
-rw-r--r--src/datastore/plugin_datastore_postgres.c20
-rw-r--r--src/gns/Makefile.am4
-rw-r--r--src/gns/gnunet-gns.c6
-rwxr-xr-xsrc/gns/test_gns_cname_lookup.sh4
-rwxr-xr-xsrc/gns/test_gns_gns2dns_cname_lookup.sh2
-rw-r--r--src/gns/test_gns_lookup.conf2
-rwxr-xr-xsrc/gns/test_plugin_rest_gns.sh68
-rw-r--r--src/identity/plugin_rest_identity.c37
-rw-r--r--src/include/gnunet_pq_lib.h142
-rw-r--r--src/namecache/plugin_namecache_postgres.c38
-rw-r--r--src/namestore/Makefile.am7
-rw-r--r--src/namestore/plugin_namestore_postgres.c64
-rw-r--r--src/namestore/test_plugin_namestore.c3
-rwxr-xr-xsrc/namestore/test_plugin_rest_namestore.sh195
-rw-r--r--src/nat/gnunet-service-nat.c15
-rw-r--r--src/nat/nat.conf.in3
-rw-r--r--src/peerstore/test_peerstore_api_data.conf3
-rw-r--r--src/peerstore/test_peerstore_api_sync.c37
-rw-r--r--src/pq/Makefile.am2
-rw-r--r--src/pq/pq.c43
-rw-r--r--src/pq/pq.h57
-rw-r--r--src/pq/pq_connect.c183
-rw-r--r--src/pq/pq_eval.c59
-rw-r--r--src/pq/pq_exec.c15
-rw-r--r--src/pq/pq_prepare.c39
-rw-r--r--src/pq/pq_result_helper.c2
-rw-r--r--src/pq/test_pq.c186
-rw-r--r--src/transport/plugin_transport_http_server.c2
-rw-r--r--src/util/gnunet-service-resolver.c10
30 files changed, 784 insertions, 489 deletions
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c
index 59dff9067..c532550ae 100644
--- a/src/datacache/plugin_datacache_postgres.c
+++ b/src/datacache/plugin_datacache_postgres.c
@@ -48,7 +48,7 @@ struct Plugin
48 /** 48 /**
49 * Native Postgres database handle. 49 * Native Postgres database handle.
50 */ 50 */
51 PGconn *dbh; 51 struct GNUNET_PQ_Context *dbh;
52 52
53 /** 53 /**
54 * Number of key-value pairs in the database. 54 * Number of key-value pairs in the database.
@@ -122,26 +122,11 @@ init_connection (struct Plugin *plugin)
122 }; 122 };
123 123
124 plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->env->cfg, 124 plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->env->cfg,
125 "datacache-postgres"); 125 "datacache-postgres",
126 es,
127 ps);
126 if (NULL == plugin->dbh) 128 if (NULL == plugin->dbh)
127 return GNUNET_SYSERR; 129 return GNUNET_SYSERR;
128 if (GNUNET_OK !=
129 GNUNET_PQ_exec_statements (plugin->dbh,
130 es))
131 {
132 PQfinish (plugin->dbh);
133 plugin->dbh = NULL;
134 return GNUNET_SYSERR;
135 }
136
137 if (GNUNET_OK !=
138 GNUNET_PQ_prepare_statements (plugin->dbh,
139 ps))
140 {
141 PQfinish (plugin->dbh);
142 plugin->dbh = NULL;
143 return GNUNET_SYSERR;
144 }
145 return GNUNET_OK; 130 return GNUNET_OK;
146} 131}
147 132
@@ -710,7 +695,7 @@ libgnunet_plugin_datacache_postgres_done (void *cls)
710 struct GNUNET_DATACACHE_PluginFunctions *api = cls; 695 struct GNUNET_DATACACHE_PluginFunctions *api = cls;
711 struct Plugin *plugin = api->cls; 696 struct Plugin *plugin = api->cls;
712 697
713 PQfinish (plugin->dbh); 698 GNUNET_PQ_disconnect (plugin->dbh);
714 GNUNET_free (plugin); 699 GNUNET_free (plugin);
715 GNUNET_free (api); 700 GNUNET_free (api);
716 return NULL; 701 return NULL;
diff --git a/src/datastore/plugin_datastore_postgres.c b/src/datastore/plugin_datastore_postgres.c
index 181cf8cf8..0811edfd7 100644
--- a/src/datastore/plugin_datastore_postgres.c
+++ b/src/datastore/plugin_datastore_postgres.c
@@ -54,7 +54,7 @@ struct Plugin
54 /** 54 /**
55 * Native Postgres database handle. 55 * Native Postgres database handle.
56 */ 56 */
57 PGconn *dbh; 57 struct GNUNET_PQ_Context *dbh;
58}; 58};
59 59
60 60
@@ -172,21 +172,11 @@ init_connection (struct Plugin *plugin)
172#undef RESULT_COLUMNS 172#undef RESULT_COLUMNS
173 173
174 plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->env->cfg, 174 plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->env->cfg,
175 "datastore-postgres"); 175 "datastore-postgres",
176 es,
177 ps);
176 if (NULL == plugin->dbh) 178 if (NULL == plugin->dbh)
177 return GNUNET_SYSERR; 179 return GNUNET_SYSERR;
178
179 if ((GNUNET_OK !=
180 GNUNET_PQ_exec_statements (plugin->dbh,
181 es)) ||
182 (GNUNET_OK !=
183 GNUNET_PQ_prepare_statements (plugin->dbh,
184 ps)))
185 {
186 PQfinish (plugin->dbh);
187 plugin->dbh = NULL;
188 return GNUNET_SYSERR;
189 }
190 return GNUNET_OK; 180 return GNUNET_OK;
191} 181}
192 182
@@ -974,7 +964,7 @@ libgnunet_plugin_datastore_postgres_done (void *cls)
974 struct GNUNET_DATASTORE_PluginFunctions *api = cls; 964 struct GNUNET_DATASTORE_PluginFunctions *api = cls;
975 struct Plugin *plugin = api->cls; 965 struct Plugin *plugin = api->cls;
976 966
977 PQfinish (plugin->dbh); 967 GNUNET_PQ_disconnect (plugin->dbh);
978 GNUNET_free (plugin); 968 GNUNET_free (plugin);
979 GNUNET_free (api); 969 GNUNET_free (api);
980 return NULL; 970 return NULL;
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am
index 4a152a6df..6cc09c098 100644
--- a/src/gns/Makefile.am
+++ b/src/gns/Makefile.am
@@ -268,6 +268,10 @@ check_SCRIPTS += \
268 test_proxy.sh 268 test_proxy.sh
269endif 269endif
270endif 270endif
271if HAVE_JSON
272check_SCRIPTS += \
273 test_plugin_rest_gns.sh
274endif
271endif 275endif
272 276
273 277
diff --git a/src/gns/gnunet-gns.c b/src/gns/gnunet-gns.c
index 5f4061f7d..510e46d14 100644
--- a/src/gns/gnunet-gns.c
+++ b/src/gns/gnunet-gns.c
@@ -201,6 +201,12 @@ run (void *cls,
201 201
202 cfg = c; 202 cfg = c;
203 to_task = NULL; 203 to_task = NULL;
204 {
205 char *colon;
206
207 if (NULL != (colon = strchr (lookup_name, ':')))
208 *colon = '\0';
209 }
204 if (GNUNET_OK != GNUNET_DNSPARSER_check_name (lookup_name)) 210 if (GNUNET_OK != GNUNET_DNSPARSER_check_name (lookup_name))
205 { 211 {
206 fprintf (stderr, 212 fprintf (stderr,
diff --git a/src/gns/test_gns_cname_lookup.sh b/src/gns/test_gns_cname_lookup.sh
index d168e4acb..f71346127 100755
--- a/src/gns/test_gns_cname_lookup.sh
+++ b/src/gns/test_gns_cname_lookup.sh
@@ -45,7 +45,7 @@ gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME_PLUS -t CNAME -V $TEST_RE
45gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_CNAME_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf 45gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_CNAME_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf
46RES_CNAME=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t A -c test_gns_lookup.conf` 46RES_CNAME=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t A -c test_gns_lookup.conf`
47RES_CNAME_RAW=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t CNAME -c test_gns_lookup.conf` 47RES_CNAME_RAW=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t CNAME -c test_gns_lookup.conf`
48RES_CNAME_DNS=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf` 48RES_CNAME_DNS=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf | grep $TEST_IP_DNS`
49echo NOW 49echo NOW
50gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf 50gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf
51echo WON 51echo WON
@@ -76,7 +76,7 @@ else
76 exit 1 76 exit 1
77fi 77fi
78 78
79if [ "$RES_CNAME_DNS" = "$TEST_IP_DNS" ] 79if echo "$RES_CNAME_DNS" | grep "$TEST_IP_DNS" > /dev/null
80then 80then
81 echo "PASS: IP resolution from DNS" 81 echo "PASS: IP resolution from DNS"
82 exit 0 82 exit 0
diff --git a/src/gns/test_gns_gns2dns_cname_lookup.sh b/src/gns/test_gns_gns2dns_cname_lookup.sh
index 87d684515..71e48a2bd 100755
--- a/src/gns/test_gns_gns2dns_cname_lookup.sh
+++ b/src/gns/test_gns_gns2dns_cname_lookup.sh
@@ -85,7 +85,7 @@ else
85 ret=1 85 ret=1
86fi 86fi
87 87
88if [ "$RES_IP6" = "$TEST_IP6" ] 88if echo "$RES_IP6" | grep "$TEST_IP6" > /dev/null
89then 89then
90 echo "PASS: Resolved $TEST_DOMAIN to $RES_IP6." 90 echo "PASS: Resolved $TEST_DOMAIN to $RES_IP6."
91else 91else
diff --git a/src/gns/test_gns_lookup.conf b/src/gns/test_gns_lookup.conf
index 2b874f80d..130d190e7 100644
--- a/src/gns/test_gns_lookup.conf
+++ b/src/gns/test_gns_lookup.conf
@@ -1,7 +1,7 @@
1@INLINE@ test_gns_defaults.conf 1@INLINE@ test_gns_defaults.conf
2 2
3[namecache] 3[namecache]
4DISABLE = YES 4DISABLE = NO
5 5
6[PATHS] 6[PATHS]
7GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-gns-peer-1/ 7GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-gns-peer-1/
diff --git a/src/gns/test_plugin_rest_gns.sh b/src/gns/test_plugin_rest_gns.sh
index ec495a04b..da46330d6 100755
--- a/src/gns/test_plugin_rest_gns.sh
+++ b/src/gns/test_plugin_rest_gns.sh
@@ -1,7 +1,20 @@
1#!/usr/bin/bash 1#!/bin/sh
2 2# This file is in the public domain.
3#First, start gnunet-arm and the rest-service. 3trap "gnunet-arm -e -c test_gns_lookup.conf" SIGINT
4#Exit 0 means success, exit 1 means failed test 4
5LOCATION=$(which gnunet-config)
6if [ -z $LOCATION ]
7then
8 LOCATION="gnunet-config"
9fi
10$LOCATION --version 1> /dev/null
11if test $? != 0
12then
13 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
14 exit 77
15fi
16
17rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME`
5 18
6gns_link="http://localhost:7776/gns" 19gns_link="http://localhost:7776/gns"
7wrong_link="http://localhost:7776/gnsandmore" 20wrong_link="http://localhost:7776/gnsandmore"
@@ -9,42 +22,47 @@ wrong_link="http://localhost:7776/gnsandmore"
9curl_get () { 22curl_get () {
10 #$1 is link 23 #$1 is link
11 #$2 is grep 24 #$2 is grep
12 cache="$(curl -v "$1" 2>&1 | grep "$2")" 25 cache="$(gnurl -v "$1" 2>&1 | grep "$2")"
13 #echo $cache 26 #echo "$cache"
14 if [ "" == "$cache" ] 27 if [ "" == "$cache" ]
15 then 28 then
29 gnunet-identity -D "$TEST_TLD" -c test_gns_lookup.conf > /dev/null 2>&1
30 gnunet-arm -e -c test_gns_lookup.conf
16 exit 1 31 exit 1
17 fi 32 fi
18} 33}
34TEST_TLD="testtld"
19 35
20gnunet-identity -D "test_plugin_rest_gns" > /dev/null 2>&1 36gnunet-arm -s -c test_gns_lookup.conf
21 37curl_get "$gns_link/www.$TEST_TLD" "error"
22curl_get "$gns_link/www.test_plugin_rest_gns" "error"
23
24gnunet-identity -C "test_plugin_rest_gns"
25 38
26curl_get "$gns_link/www.test_plugin_rest_gns" "\[\]" 39gnunet-identity -C "$TEST_TLD" -c test_gns_lookup.conf
40sleep 0.5
41curl_get "$gns_link/www.$TEST_TLD" "\[\]"
27 42
28gnunet-namestore -z "test_plugin_rest_gns" -p -a -n www -e 1d -V 1.1.1.1 -t A 43gnunet-namestore -z "$TEST_TLD" -p -a -n www -e 1d -V 1.1.1.1 -t A -c test_gns_lookup.conf
29 44
30curl_get "$gns_link/www.test_plugin_rest_gns" "1.1.1.1" 45curl_get "$gns_link/www.$TEST_TLD" "1.1.1.1"
31 46
32gnunet-namestore -z "test_plugin_rest_gns" -p -a -n www -e 1d -V 1::1 -t AAAA 47gnunet-namestore -z "$TEST_TLD" -p -a -n www -e 1d -V 1::1 -t AAAA -c test_gns_lookup.conf
33 48
34curl_get "$gns_link/www.test_plugin_rest_gns" "1::1.*1.1.1.1" 49curl_get "$gns_link/www.$TEST_TLD" "1::1.*1.1.1.1"
35 50
36gnunet-namestore -z "test_plugin_rest_gns" -p -a -n www -e 1d -V 1.1.1.2 -t A 51gnunet-namestore -z "$TEST_TLD" -p -a -n www -e 1d -V 1.1.1.2 -t A -c test_gns_lookup.conf
37 52
38curl_get "$gns_link/www.test_plugin_rest_gns" "1.1.1.2.*1::1.*1.1.1.1" 53curl_get "$gns_link/www.$TEST_TLD" "1.1.1.2.*1::1.*1.1.1.1"
39curl_get "$gns_link/www.test_plugin_rest_gns?record_type=A" "1.1.1.2.*1.1.1.1" 54curl_get "$gns_link/www.$TEST_TLD?record_type=A" "1.1.1.2.*1.1.1.1"
40curl_get "$gns_link/www.test_plugin_rest_gns?record_type=AAAA" "1::1" 55curl_get "$gns_link/www.$TEST_TLD?record_type=AAAA" "1::1"
41curl_get "$gns_link/www.test_plugin_rest_gns?record_type=WRONG_TYPE" "1.1.1.2.*1::1.*1.1.1.1" 56curl_get "$gns_link/www.$TEST_TLD?record_type=WRONG_TYPE" "1.1.1.2.*1::1.*1.1.1.1"
42 57
43gnunet-namestore -z "test_plugin_rest_gns" -p -a -n www1 -e 1d -V 1.1.1.1 -t A 58gnunet-namestore -z "$TEST_TLD" -p -a -n www1 -e 1d -V 1.1.1.1 -t A -c test_gns_lookup.conf
44curl_get "$gns_link/www1.test_plugin_rest_gns" "1.1.1.1" 59curl_get "$gns_link/www1.$TEST_TLD" "1.1.1.1"
45 60
46gnunet-identity -D "test_plugin_rest_gns" > /dev/null 2>&1 61gnunet-namestore -z "$TEST_TLD" -d -n www1 -c test_gns_lookup.conf
62gnunet-namestore -z "$TEST_TLD" -d -n www -c test_gns_lookup.conf
47 63
48curl_get "$gns_link/www1.test_plugin_rest_gns" "error" 64gnunet-identity -D "$TEST_TLD" -c test_gns_lookup.conf > /dev/null 2>&1
49 65
66curl_get "$gns_link/www1.$TEST_TLD" "error"
67gnunet-arm -e -c -c test_gns_lookup.conf
50exit 0 68exit 0
diff --git a/src/identity/plugin_rest_identity.c b/src/identity/plugin_rest_identity.c
index 247d09282..e052ac6b3 100644
--- a/src/identity/plugin_rest_identity.c
+++ b/src/identity/plugin_rest_identity.c
@@ -1234,11 +1234,46 @@ init_egos (void *cls,
1234 GNUNET_IDENTITY_ego_get_public_key (ego, &pk); 1234 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
1235 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); 1235 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
1236 ego_entry->ego = ego; 1236 ego_entry->ego = ego;
1237 GNUNET_asprintf (&ego_entry->identifier, "%s", identifier); 1237 ego_entry->identifier = GNUNET_strdup (identifier);
1238 GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, 1238 GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head,
1239 handle->ego_tail, 1239 handle->ego_tail,
1240 ego_entry); 1240 ego_entry);
1241 return;
1242 }
1243 // Check if ego exists
1244 for (ego_entry = handle->ego_head; NULL != ego_entry;)
1245 {
1246 struct EgoEntry *tmp = ego_entry;
1247 ego_entry = ego_entry->next;
1248 if (ego != tmp->ego)
1249 continue;
1250 // Deleted
1251 if (NULL == identifier)
1252 {
1253 GNUNET_CONTAINER_DLL_remove (handle->ego_head,
1254 handle->ego_tail,
1255 tmp);
1256 GNUNET_free (tmp->keystring);
1257 GNUNET_free (tmp->identifier);
1258 GNUNET_free (tmp);
1259 }
1260 else {
1261 // Renamed
1262 GNUNET_free (tmp->identifier);
1263 tmp->identifier = GNUNET_strdup (identifier);
1264 }
1265 return;
1241 } 1266 }
1267 // New ego
1268 ego_entry = GNUNET_new (struct EgoEntry);
1269 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
1270 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
1271 ego_entry->ego = ego;
1272 GNUNET_asprintf (&ego_entry->identifier, "%s", identifier);
1273 GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head,
1274 handle->ego_tail,
1275 ego_entry);
1276
1242} 1277}
1243 1278
1244/** 1279/**
diff --git a/src/include/gnunet_pq_lib.h b/src/include/gnunet_pq_lib.h
index 6c576c8ab..2aea77b7f 100644
--- a/src/include/gnunet_pq_lib.h
+++ b/src/include/gnunet_pq_lib.h
@@ -46,15 +46,16 @@
46 * @param scratch_length number of entries left in @a scratch 46 * @param scratch_length number of entries left in @a scratch
47 * @return -1 on error, number of offsets used in @a scratch otherwise 47 * @return -1 on error, number of offsets used in @a scratch otherwise
48 */ 48 */
49typedef int (*GNUNET_PQ_QueryConverter) (void *cls, 49typedef int
50 const void *data, 50(*GNUNET_PQ_QueryConverter) (void *cls,
51 size_t data_len, 51 const void *data,
52 void *param_values[], 52 size_t data_len,
53 int param_lengths[], 53 void *param_values[],
54 int param_formats[], 54 int param_lengths[],
55 unsigned int param_length, 55 int param_formats[],
56 void *scratch[], 56 unsigned int param_length,
57 unsigned int scratch_length); 57 void *scratch[],
58 unsigned int scratch_length);
58 59
59 60
60/** 61/**
@@ -214,12 +215,13 @@ GNUNET_PQ_query_param_uint64 (const uint64_t *x);
214 * #GNUNET_YES if all results could be extracted 215 * #GNUNET_YES if all results could be extracted
215 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) 216 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
216 */ 217 */
217typedef int (*GNUNET_PQ_ResultConverter) (void *cls, 218typedef int
218 PGresult *result, 219(*GNUNET_PQ_ResultConverter) (void *cls,
219 int row, 220 PGresult *result,
220 const char *fname, 221 int row,
221 size_t *dst_size, 222 const char *fname,
222 void *dst); 223 size_t *dst_size,
224 void *dst);
223 225
224 226
225/** 227/**
@@ -229,7 +231,9 @@ typedef int (*GNUNET_PQ_ResultConverter) (void *cls,
229 * @param cls closure 231 * @param cls closure
230 * @param rd result data to clean up 232 * @param rd result data to clean up
231 */ 233 */
232typedef void (*GNUNET_PQ_ResultCleanup) (void *cls, void *rd); 234typedef void
235(*GNUNET_PQ_ResultCleanup) (void *cls,
236 void *rd);
233 237
234 238
235/** 239/**
@@ -420,16 +424,22 @@ GNUNET_PQ_result_spec_uint64 (const char *name, uint64_t *u64);
420/* ************************* pq.c functions ************************ */ 424/* ************************* pq.c functions ************************ */
421 425
422/** 426/**
427 * Postgres context.
428 */
429struct GNUNET_PQ_Context;
430
431
432/**
423 * Execute a prepared statement. 433 * Execute a prepared statement.
424 * 434 *
425 * @param db_conn database connection 435 * @param db database context
426 * @param name name of the prepared statement 436 * @param name name of the prepared statement
427 * @param params parameters to the statement 437 * @param params parameters to the statement
428 * @return postgres result 438 * @return postgres result
429 * @deprecated (should become an internal API) 439 * @deprecated (should become an internal API)
430 */ 440 */
431PGresult * 441PGresult *
432GNUNET_PQ_exec_prepared (PGconn *db_conn, 442GNUNET_PQ_exec_prepared (struct GNUNET_PQ_Context *db,
433 const char *name, 443 const char *name,
434 const struct GNUNET_PQ_QueryParam *params); 444 const struct GNUNET_PQ_QueryParam *params);
435 445
@@ -468,7 +478,7 @@ GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs);
468 * Check the @a result's error code to see what happened. 478 * Check the @a result's error code to see what happened.
469 * Also logs errors. 479 * Also logs errors.
470 * 480 *
471 * @param connection connection to execute the statement in 481 * @param db database to execute the statement in
472 * @param statement_name name of the statement that created @a result 482 * @param statement_name name of the statement that created @a result
473 * @param result result to check 483 * @param result result to check
474 * @return status code from the result, mapping PQ status 484 * @return status code from the result, mapping PQ status
@@ -478,7 +488,7 @@ GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs);
478 * @deprecated (low level, let's see if we can do with just the high-level functions) 488 * @deprecated (low level, let's see if we can do with just the high-level functions)
479 */ 489 */
480enum GNUNET_DB_QueryStatus 490enum GNUNET_DB_QueryStatus
481GNUNET_PQ_eval_result (PGconn *connection, 491GNUNET_PQ_eval_result (struct GNUNET_PQ_Context *db,
482 const char *statement_name, 492 const char *statement_name,
483 PGresult *result); 493 PGresult *result);
484 494
@@ -488,7 +498,7 @@ GNUNET_PQ_eval_result (PGconn *connection,
488 * statement in @a connnection using the given @a params. Returns the 498 * statement in @a connnection using the given @a params. Returns the
489 * resulting session state. 499 * resulting session state.
490 * 500 *
491 * @param connection connection to execute the statement in 501 * @param db database to execute the statement with
492 * @param statement_name name of the statement 502 * @param statement_name name of the statement
493 * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated) 503 * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated)
494 * @return status code from the result, mapping PQ status 504 * @return status code from the result, mapping PQ status
@@ -500,7 +510,7 @@ GNUNET_PQ_eval_result (PGconn *connection,
500 * zero; if INSERT was successful, we return one. 510 * zero; if INSERT was successful, we return one.
501 */ 511 */
502enum GNUNET_DB_QueryStatus 512enum GNUNET_DB_QueryStatus
503GNUNET_PQ_eval_prepared_non_select (PGconn *connection, 513GNUNET_PQ_eval_prepared_non_select (struct GNUNET_PQ_Context *db,
504 const char *statement_name, 514 const char *statement_name,
505 const struct GNUNET_PQ_QueryParam *params); 515 const struct GNUNET_PQ_QueryParam *params);
506 516
@@ -513,9 +523,10 @@ GNUNET_PQ_eval_prepared_non_select (PGconn *connection,
513 * @param result the postgres result 523 * @param result the postgres result
514 * @param num_result the number of results in @a result 524 * @param num_result the number of results in @a result
515 */ 525 */
516typedef void (*GNUNET_PQ_PostgresResultHandler) (void *cls, 526typedef void
517 PGresult *result, 527(*GNUNET_PQ_PostgresResultHandler) (void *cls,
518 unsigned int num_results); 528 PGresult *result,
529 unsigned int num_results);
519 530
520 531
521/** 532/**
@@ -525,7 +536,7 @@ typedef void (*GNUNET_PQ_PostgresResultHandler) (void *cls,
525 * status including the number of results given to @a rh (possibly zero). 536 * status including the number of results given to @a rh (possibly zero).
526 * @a rh will not have been called if the return value is negative. 537 * @a rh will not have been called if the return value is negative.
527 * 538 *
528 * @param connection connection to execute the statement in 539 * @param db database to execute the statement with
529 * @param statement_name name of the statement 540 * @param statement_name name of the statement
530 * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated) 541 * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated)
531 * @param rh function to call with the result set, NULL to ignore 542 * @param rh function to call with the result set, NULL to ignore
@@ -534,7 +545,7 @@ typedef void (*GNUNET_PQ_PostgresResultHandler) (void *cls,
534 * codes to `enum GNUNET_DB_QueryStatus`. 545 * codes to `enum GNUNET_DB_QueryStatus`.
535 */ 546 */
536enum GNUNET_DB_QueryStatus 547enum GNUNET_DB_QueryStatus
537GNUNET_PQ_eval_prepared_multi_select (PGconn *connection, 548GNUNET_PQ_eval_prepared_multi_select (struct GNUNET_PQ_Context *db,
538 const char *statement_name, 549 const char *statement_name,
539 const struct GNUNET_PQ_QueryParam *params, 550 const struct GNUNET_PQ_QueryParam *params,
540 GNUNET_PQ_PostgresResultHandler rh, 551 GNUNET_PQ_PostgresResultHandler rh,
@@ -549,7 +560,7 @@ GNUNET_PQ_eval_prepared_multi_select (PGconn *connection,
549 * value was #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT. Returns the 560 * value was #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT. Returns the
550 * resulting session status. 561 * resulting session status.
551 * 562 *
552 * @param connection connection to execute the statement in 563 * @param db database to execute the statement with
553 * @param statement_name name of the statement 564 * @param statement_name name of the statement
554 * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated) 565 * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated)
555 * @param[in,out] rs result specification to use for storing the result of the query 566 * @param[in,out] rs result specification to use for storing the result of the query
@@ -557,11 +568,11 @@ GNUNET_PQ_eval_prepared_multi_select (PGconn *connection,
557 * codes to `enum GNUNET_DB_QueryStatus`. 568 * codes to `enum GNUNET_DB_QueryStatus`.
558 */ 569 */
559enum GNUNET_DB_QueryStatus 570enum GNUNET_DB_QueryStatus
560GNUNET_PQ_eval_prepared_singleton_select ( 571GNUNET_PQ_eval_prepared_singleton_select (struct GNUNET_PQ_Context *db,
561 PGconn *connection, 572 const char *statement_name,
562 const char *statement_name, 573 const struct
563 const struct GNUNET_PQ_QueryParam *params, 574 GNUNET_PQ_QueryParam *params,
564 struct GNUNET_PQ_ResultSpec *rs); 575 struct GNUNET_PQ_ResultSpec *rs);
565 576
566 577
567/* ******************** pq_prepare.c functions ************** */ 578/* ******************** pq_prepare.c functions ************** */
@@ -587,6 +598,7 @@ struct GNUNET_PQ_PreparedStatement
587 * Number of arguments included in @e sql. 598 * Number of arguments included in @e sql.
588 */ 599 */
589 unsigned int num_arguments; 600 unsigned int num_arguments;
601
590}; 602};
591 603
592 604
@@ -616,14 +628,14 @@ GNUNET_PQ_make_prepare (const char *name,
616/** 628/**
617 * Request creation of prepared statements @a ps from Postgres. 629 * Request creation of prepared statements @a ps from Postgres.
618 * 630 *
619 * @param connection connection to prepare the statements for 631 * @param db database to prepare the statements for
620 * @param ps #GNUNET_PQ_PREPARED_STATEMENT_END-terminated array of prepared 632 * @param ps #GNUNET_PQ_PREPARED_STATEMENT_END-terminated array of prepared
621 * statements. 633 * statements.
622 * @return #GNUNET_OK on success, 634 * @return #GNUNET_OK on success,
623 * #GNUNET_SYSERR on error 635 * #GNUNET_SYSERR on error
624 */ 636 */
625int 637int
626GNUNET_PQ_prepare_statements (PGconn *connection, 638GNUNET_PQ_prepare_statements (struct GNUNET_PQ_Context *db,
627 const struct GNUNET_PQ_PreparedStatement *ps); 639 const struct GNUNET_PQ_PreparedStatement *ps);
628 640
629 641
@@ -681,14 +693,14 @@ GNUNET_PQ_make_try_execute (const char *sql);
681/** 693/**
682 * Request execution of an array of statements @a es from Postgres. 694 * Request execution of an array of statements @a es from Postgres.
683 * 695 *
684 * @param connection connection to execute the statements over 696 * @param pq database to execute the statements in
685 * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated array of prepared 697 * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated array of prepared
686 * statements. 698 * statements.
687 * @return #GNUNET_OK on success (modulo statements where errors can be ignored) 699 * @return #GNUNET_OK on success (modulo statements where errors can be ignored)
688 * #GNUNET_SYSERR on error 700 * #GNUNET_SYSERR on error
689 */ 701 */
690int 702int
691GNUNET_PQ_exec_statements (PGconn *connection, 703GNUNET_PQ_exec_statements (struct GNUNET_PQ_Context *db,
692 const struct GNUNET_PQ_ExecuteStatement *es); 704 const struct GNUNET_PQ_ExecuteStatement *es);
693 705
694 706
@@ -698,26 +710,70 @@ GNUNET_PQ_exec_statements (PGconn *connection,
698/** 710/**
699 * Create a connection to the Postgres database using @a config_str 711 * Create a connection to the Postgres database using @a config_str
700 * for the configuration. Initialize logging via GNUnet's log 712 * for the configuration. Initialize logging via GNUnet's log
701 * routines and disable Postgres's logger. 713 * routines and disable Postgres's logger. Also ensures that the
714 * statements in @a es are executed whenever we (re)connect to the
715 * database, and that the prepared statements in @a ps are "ready".
716 * If statements in @es fail that were created with
717 * #GNUNET_PQ_make_execute(), then the entire operation fails.
702 * 718 *
703 * @param config_str configuration to use 719 * @param config_str configuration to use
720 * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated
721 * array of statements to execute upon EACH connection, can be NULL
722 * @param ps array of prepared statements to prepare, can be NULL
704 * @return NULL on error 723 * @return NULL on error
705 */ 724 */
706PGconn * 725struct GNUNET_PQ_Context *
707GNUNET_PQ_connect (const char *config_str); 726GNUNET_PQ_connect (const char *config_str,
727 const struct GNUNET_PQ_ExecuteStatement *es,
728 const struct GNUNET_PQ_PreparedStatement *ps);
708 729
709 730
710/** 731/**
711 * Connect to a postgres database using the configuration 732 * Connect to a postgres database using the configuration
712 * option "CONFIG" in @a section. 733 * option "CONFIG" in @a section. Also ensures that the
734 * statements in @a es are executed whenever we (re)connect to the
735 * database, and that the prepared statements in @a ps are "ready".
713 * 736 *
714 * @param cfg configuration 737 * @param cfg configuration
715 * @param section configuration section to use to get Postgres configuration options 738 * @param section configuration section to use to get Postgres configuration options
739 * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated
740 * array of statements to execute upon EACH connection, can be NULL
741 * @param ps array of prepared statements to prepare, can be NULL
716 * @return the postgres handle, NULL on error 742 * @return the postgres handle, NULL on error
717 */ 743 */
718PGconn * 744struct GNUNET_PQ_Context *
719GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, 745GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg,
720 const char *section); 746 const char *section,
747 const struct GNUNET_PQ_ExecuteStatement *es,
748 const struct GNUNET_PQ_PreparedStatement *ps);
749
750
751/**
752 * Reinitialize the database @a db if the connection is down.
753 *
754 * @param db database connection to reinitialize
755 */
756void
757GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db);
758
759
760/**
761 * Reinitialize the database @a db.
762 *
763 * @param db database connection to reinitialize
764 */
765void
766GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db);
767
768
769/**
770 * Disconnect from the database, destroying the prepared statements
771 * and releasing other associated resources.
772 *
773 * @param db database handle to disconnect (will be free'd)
774 */
775void
776GNUNET_PQ_disconnect (struct GNUNET_PQ_Context *db);
721 777
722 778
723#endif /* GNUNET_PQ_LIB_H_ */ 779#endif /* GNUNET_PQ_LIB_H_ */
diff --git a/src/namecache/plugin_namecache_postgres.c b/src/namecache/plugin_namecache_postgres.c
index e4b360ef2..35bf5c2ff 100644
--- a/src/namecache/plugin_namecache_postgres.c
+++ b/src/namecache/plugin_namecache_postgres.c
@@ -42,9 +42,9 @@ struct Plugin
42 const struct GNUNET_CONFIGURATION_Handle *cfg; 42 const struct GNUNET_CONFIGURATION_Handle *cfg;
43 43
44 /** 44 /**
45 * Native Postgres database handle. 45 * Postgres database handle.
46 */ 46 */
47 PGconn *dbh; 47 struct GNUNET_PQ_Context *dbh;
48}; 48};
49 49
50 50
@@ -75,10 +75,6 @@ database_setup (struct Plugin *plugin)
75 "WITH OIDS"); 75 "WITH OIDS");
76 const struct GNUNET_PQ_ExecuteStatement *cr; 76 const struct GNUNET_PQ_ExecuteStatement *cr;
77 77
78 plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->cfg,
79 "namecache-postgres");
80 if (NULL == plugin->dbh)
81 return GNUNET_SYSERR;
82 if (GNUNET_YES == 78 if (GNUNET_YES ==
83 GNUNET_CONFIGURATION_get_value_yesno (plugin->cfg, 79 GNUNET_CONFIGURATION_get_value_yesno (plugin->cfg,
84 "namecache-postgres", 80 "namecache-postgres",
@@ -90,7 +86,6 @@ database_setup (struct Plugin *plugin)
90 { 86 {
91 cr = &es_default; 87 cr = &es_default;
92 } 88 }
93
94 { 89 {
95 struct GNUNET_PQ_ExecuteStatement es[] = { 90 struct GNUNET_PQ_ExecuteStatement es[] = {
96 *cr, 91 *cr,
@@ -100,18 +95,6 @@ database_setup (struct Plugin *plugin)
100 "CREATE INDEX ir_block_expiration ON ns096blocks (expiration_time)"), 95 "CREATE INDEX ir_block_expiration ON ns096blocks (expiration_time)"),
101 GNUNET_PQ_EXECUTE_STATEMENT_END 96 GNUNET_PQ_EXECUTE_STATEMENT_END
102 }; 97 };
103
104 if (GNUNET_OK !=
105 GNUNET_PQ_exec_statements (plugin->dbh,
106 es))
107 {
108 PQfinish (plugin->dbh);
109 plugin->dbh = NULL;
110 return GNUNET_SYSERR;
111 }
112 }
113
114 {
115 struct GNUNET_PQ_PreparedStatement ps[] = { 98 struct GNUNET_PQ_PreparedStatement ps[] = {
116 GNUNET_PQ_make_prepare ("cache_block", 99 GNUNET_PQ_make_prepare ("cache_block",
117 "INSERT INTO ns096blocks (query, block, expiration_time) VALUES " 100 "INSERT INTO ns096blocks (query, block, expiration_time) VALUES "
@@ -128,16 +111,13 @@ database_setup (struct Plugin *plugin)
128 GNUNET_PQ_PREPARED_STATEMENT_END 111 GNUNET_PQ_PREPARED_STATEMENT_END
129 }; 112 };
130 113
131 if (GNUNET_OK != 114 plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->cfg,
132 GNUNET_PQ_prepare_statements (plugin->dbh, 115 "namecache-postgres",
133 ps)) 116 es,
134 { 117 ps);
135 PQfinish (plugin->dbh);
136 plugin->dbh = NULL;
137 return GNUNET_SYSERR;
138 }
139 } 118 }
140 119 if (NULL == plugin->dbh)
120 return GNUNET_SYSERR;
141 return GNUNET_OK; 121 return GNUNET_OK;
142} 122}
143 123
@@ -311,7 +291,7 @@ namecache_postgres_lookup_block (void *cls,
311static void 291static void
312database_shutdown (struct Plugin *plugin) 292database_shutdown (struct Plugin *plugin)
313{ 293{
314 PQfinish (plugin->dbh); 294 GNUNET_PQ_disconnect (plugin->dbh);
315 plugin->dbh = NULL; 295 plugin->dbh = NULL;
316} 296}
317 297
diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am
index b9fa83103..646effd9b 100644
--- a/src/namestore/Makefile.am
+++ b/src/namestore/Makefile.am
@@ -681,6 +681,13 @@ check_SCRIPTS = \
681 test_namestore_lookup.sh \ 681 test_namestore_lookup.sh \
682 test_namestore_delete.sh 682 test_namestore_delete.sh
683 683
684if HAVE_MHD
685if HAVE_JSON
686check_SCRIPTS += \
687 test_plugin_rest_namestore.sh
688endif
689endif
690
684EXTRA_DIST = \ 691EXTRA_DIST = \
685 test_common.c \ 692 test_common.c \
686 test_namestore_api.conf \ 693 test_namestore_api.conf \
diff --git a/src/namestore/plugin_namestore_postgres.c b/src/namestore/plugin_namestore_postgres.c
index 5148ca0f5..23893538b 100644
--- a/src/namestore/plugin_namestore_postgres.c
+++ b/src/namestore/plugin_namestore_postgres.c
@@ -45,9 +45,9 @@ struct Plugin
45 const struct GNUNET_CONFIGURATION_Handle *cfg; 45 const struct GNUNET_CONFIGURATION_Handle *cfg;
46 46
47 /** 47 /**
48 * Native Postgres database handle. 48 * Postgres database handle.
49 */ 49 */
50 PGconn *dbh; 50 struct GNUNET_PQ_Context *dbh;
51}; 51};
52 52
53 53
@@ -88,30 +88,8 @@ database_setup (struct Plugin *plugin)
88 ")" 88 ")"
89 "WITH OIDS"); 89 "WITH OIDS");
90 const struct GNUNET_PQ_ExecuteStatement *cr; 90 const struct GNUNET_PQ_ExecuteStatement *cr;
91 struct GNUNET_PQ_ExecuteStatement sc = GNUNET_PQ_EXECUTE_STATEMENT_END;
91 92
92 plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->cfg,
93 "namestore-postgres");
94 if (NULL == plugin->dbh)
95 return GNUNET_SYSERR;
96 if (GNUNET_YES ==
97 GNUNET_CONFIGURATION_get_value_yesno (plugin->cfg,
98 "namestore-postgres",
99 "ASYNC_COMMIT"))
100 {
101 struct GNUNET_PQ_ExecuteStatement es[] = {
102 GNUNET_PQ_make_try_execute ("SET synchronous_commit TO off"),
103 GNUNET_PQ_EXECUTE_STATEMENT_END
104 };
105
106 if (GNUNET_OK !=
107 GNUNET_PQ_exec_statements (plugin->dbh,
108 es))
109 {
110 PQfinish (plugin->dbh);
111 plugin->dbh = NULL;
112 return GNUNET_SYSERR;
113 }
114 }
115 if (GNUNET_YES == 93 if (GNUNET_YES ==
116 GNUNET_CONFIGURATION_get_value_yesno (plugin->cfg, 94 GNUNET_CONFIGURATION_get_value_yesno (plugin->cfg,
117 "namestore-postgres", 95 "namestore-postgres",
@@ -124,6 +102,12 @@ database_setup (struct Plugin *plugin)
124 cr = &es_default; 102 cr = &es_default;
125 } 103 }
126 104
105 if (GNUNET_YES ==
106 GNUNET_CONFIGURATION_get_value_yesno (plugin->cfg,
107 "namestore-postgres",
108 "ASYNC_COMMIT"))
109 sc = GNUNET_PQ_make_try_execute ("SET synchronous_commit TO off");
110
127 { 111 {
128 struct GNUNET_PQ_ExecuteStatement es[] = { 112 struct GNUNET_PQ_ExecuteStatement es[] = {
129 *cr, 113 *cr,
@@ -135,20 +119,9 @@ database_setup (struct Plugin *plugin)
135 "ON ns098records (label)"), 119 "ON ns098records (label)"),
136 GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS zone_label " 120 GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS zone_label "
137 "ON ns098records (zone_private_key,label)"), 121 "ON ns098records (zone_private_key,label)"),
122 sc,
138 GNUNET_PQ_EXECUTE_STATEMENT_END 123 GNUNET_PQ_EXECUTE_STATEMENT_END
139 }; 124 };
140
141 if (GNUNET_OK !=
142 GNUNET_PQ_exec_statements (plugin->dbh,
143 es))
144 {
145 PQfinish (plugin->dbh);
146 plugin->dbh = NULL;
147 return GNUNET_SYSERR;
148 }
149 }
150
151 {
152 struct GNUNET_PQ_PreparedStatement ps[] = { 125 struct GNUNET_PQ_PreparedStatement ps[] = {
153 GNUNET_PQ_make_prepare ("store_records", 126 GNUNET_PQ_make_prepare ("store_records",
154 "INSERT INTO ns098records" 127 "INSERT INTO ns098records"
@@ -183,16 +156,13 @@ database_setup (struct Plugin *plugin)
183 GNUNET_PQ_PREPARED_STATEMENT_END 156 GNUNET_PQ_PREPARED_STATEMENT_END
184 }; 157 };
185 158
186 if (GNUNET_OK != 159 plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->cfg,
187 GNUNET_PQ_prepare_statements (plugin->dbh, 160 "namestore-postgres",
188 ps)) 161 es,
189 { 162 ps);
190 PQfinish (plugin->dbh);
191 plugin->dbh = NULL;
192 return GNUNET_SYSERR;
193 }
194 } 163 }
195 164 if (NULL == plugin->dbh)
165 return GNUNET_SYSERR;
196 return GNUNET_OK; 166 return GNUNET_OK;
197} 167}
198 168
@@ -593,7 +563,7 @@ namestore_postgres_zone_to_name (void *cls,
593static void 563static void
594database_shutdown (struct Plugin *plugin) 564database_shutdown (struct Plugin *plugin)
595{ 565{
596 PQfinish (plugin->dbh); 566 GNUNET_PQ_disconnect (plugin->dbh);
597 plugin->dbh = NULL; 567 plugin->dbh = NULL;
598} 568}
599 569
diff --git a/src/namestore/test_plugin_namestore.c b/src/namestore/test_plugin_namestore.c
index a3d9f44c4..03b1a21e4 100644
--- a/src/namestore/test_plugin_namestore.c
+++ b/src/namestore/test_plugin_namestore.c
@@ -167,8 +167,9 @@ run (void *cls,
167 } 167 }
168 put_record (nsp, 1); 168 put_record (nsp, 1);
169 get_record (nsp, 1); 169 get_record (nsp, 1);
170 170#ifndef DARWIN // #5582
171 unload_plugin (nsp); 171 unload_plugin (nsp);
172#endif
172} 173}
173 174
174 175
diff --git a/src/namestore/test_plugin_rest_namestore.sh b/src/namestore/test_plugin_rest_namestore.sh
index 532c7caae..f3a4b7c49 100755
--- a/src/namestore/test_plugin_rest_namestore.sh
+++ b/src/namestore/test_plugin_rest_namestore.sh
@@ -1,44 +1,65 @@
1#!/usr/bin/bash 1#!/bin/sh
2trap "gnunet-arm -e -c test_gns_lookup.conf" SIGINT
2 3
3#First, start gnunet-arm and the rest-service. 4LOCATION=$(which gnunet-config)
4#Exit 0 means success, exit 1 means failed test 5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_namestore_api.conf -f -s paths -o GNUNET_TEST_HOME`
5 17
6namestore_link="http://localhost:7776/namestore" 18namestore_link="http://localhost:7776/namestore"
7wrong_link="http://localhost:7776/namestoreandmore" 19wrong_link="http://localhost:7776/namestoreandmore"
8 20
9 21
10curl_get () { 22curl_get () {
11 #$1 is link 23 #$1 is link
12 #$2 is grep 24 #$2 is grep
13 cache="$(curl -v "$1" 2>&1 | grep "$2")" 25 resp=$(curl -v "$1" 2>&1)
14 echo $cache 26 cache="$(echo $resp | grep "$2")"
15 if [ "" == "$cache" ] 27 #echo $cache
16 then 28 if [ "" == "$cache" ]
17 exit 1 29 then
18 fi 30 echo "Error in get response: $resp, expected $2"
31 gnunet-arm -e -c test_namestore_api.conf
32 exit 1
33 fi
19} 34}
20 35
21curl_post () { 36curl_post () {
22 #$1 is link 37 #$1 is link
23 #$2 is data 38 #$2 is data
24 #$3 is grep 39 #$3 is grep
25 cache="$(curl -v -X "POST" "$1" --data "$2" 2>&1 | grep "$3")" 40 resp=$(curl -v -X "POST" "$1" --data "$2" 2>&1)
26 echo $cache 41 cache="$(echo $resp | grep "$3")"
27 if [ "" == "$cache" ] 42 #echo $cache
28 then 43 if [ "" == "$cache" ]
29 exit 1 44 then
30 fi 45 echo "Error in post response: $resp ($2), expected $3"
46 gnunet-arm -e -c test_namestore_api.conf
47 exit 1
48 fi
31} 49}
32 50
33curl_delete () { 51curl_delete () {
34 #$1 is link 52 #$1 is link
35 #$2 is grep 53 #$2 is grep
36 cache="$(curl -v -X "DELETE" "$1" 2>&1 | grep "$2")" 54 resp=$(curl -v -X "DELETE" "$1" 2>&1)
37 echo $cache 55 cache="$(echo $resp | grep "$2")"
38 if [ "" == "$cache" ] 56 #echo $cache
39 then 57 if [ "" == "$cache" ]
40 exit 1 58 then
41 fi 59 echo "Error in delete response: $resp, expected $2"
60 gnunet-arm -e -c test_namestore_api.conf
61 exit 1
62 fi
42} 63}
43 64
44# curl_put () { 65# curl_put () {
@@ -55,93 +76,61 @@ curl_delete () {
55 76
56#Test subsystem default identity 77#Test subsystem default identity
57 78
79TEST_ID="test"
80gnunet-arm -s -c test_namestore_api.conf
81gnunet-arm -i rest -c test_namestore_api.conf
58#Test GET 82#Test GET
59gnunet-identity -D "test_plugin_rest_namestore" 83gnunet-identity -C $TEST_ID -c test_namestore_api.conf
60gnunet-identity -C "test_plugin_rest_namestore" 84test="$(gnunet-namestore -D -z $TEST_ID -c test_namestore_api.conf)"
61test="$(gnunet-namestore -D -z "test_plugin_rest_namestore")" 85name=$TEST_ID
62name="test_plugin_rest_namestore" 86public="$(gnunet-identity -d -c test_namestore_api.conf | grep $TEST_ID | awk 'NR==1{print $3}')"
63public="$(gnunet-identity -d | grep "test_plugin_rest_namestore" | awk 'NR==1{print $3}')" 87gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY" -c test_namestore_api.conf
64if [ "" == "$test" ]
65then
66 #if no entries for test_plugin_rest_namestore
67 curl_get "${namestore_link}/$name" "error"
68 curl_get "${namestore_link}/" "error"
69 curl_get "${namestore_link}/$public" "error"
70else
71 #if entries exists (that should not be possible)
72 curl_get "${namestore_link}" "HTTP/1.1 200 OK"
73 curl_get "${namestore_link}/$name" "HTTP/1.1 200 OK"
74 curl_get "${namestore_link}/" "error"
75 curl_get "${namestore_link}/$public" "error"
76fi
77gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY"
78curl_get "${namestore_link}" "HTTP/1.1 200 OK" 88curl_get "${namestore_link}" "HTTP/1.1 200 OK"
79curl_get "${namestore_link}/$name" "HTTP/1.1 200 OK" 89curl_get "${namestore_link}/$name" "HTTP/1.1 200 OK"
80curl_get "${namestore_link}/" "error"
81curl_get "${namestore_link}/$public" "error" 90curl_get "${namestore_link}/$public" "error"
82gnunet-namestore -z $name -d -n "test_entry" 91gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf
83 92
84#Test POST with NAME 93#Test POST with NAME
85curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":"test_entry"}' "HTTP/1.1 204 No Content" 94curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0}],"record_name":"test_entry"}' "HTTP/1.1 204 No Content"
86gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 95gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1
87#value 96
88curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRGxxx", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":"test_entry"}' "error" 97# invalid values
89gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 98curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRGxxx", "record_type":"PKEY", "expiration_time":"1d","flag":0}],"record_name":"test_entry"}' "error"
90curl_post "${namestore_link}/$name" '{"value":"", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":"test_entry"}' "error" 99gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1
91gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 100
92curl_post "${namestore_link}/$name" '{"value_missing":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRGxxx", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":"test_entry"}' "error" 101
93gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 102curl_post "${namestore_link}/$name" '{"data": [{"value":"", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name"}]:"test_entry"}' "error"
94#time 103gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1
95curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"0d","flag":0,"record_name":"test_entry"}' "HTTP/1.1 204" 104
96gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 105curl_post "${namestore_link}/$name" '{"data": [{"record_type":"PKEY", "expiration_time":"1d","flag":0}],"record_name":"test_entry"}' "error"
97curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"10000d","flag":0,"record_name":"test_entry"}' "HTTP/1.1 204" 106gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1
98gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 107
99curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"now","flag":0,"record_name":"test_entry"}' "error" 108#expirations
100gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 109curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"0d","flag":0}],"record_name":"test_entry"}' "HTTP/1.1 204"
101curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"","flag":0,"record_name":"test_entry"}' "error" 110gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1
102gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 111
103curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time_missing":"1d","flag":0,"record_name":"test_entry"}' "error" 112curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"10000d","flag":0}],"record_name":"test_entry"}' "HTTP/1.1 204"
104gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 113gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1
105#flag 114
106curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":"test_entry"}' "HTTP/1.1 204 No Content" 115curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"now","flag":0}],"record_name":"test_entry"}' "error"
107gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 116gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1
108curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":2,"record_name":"test_entry"}' "HTTP/1.1 204 No Content" 117
109gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 118curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time_missing":"1d","flag":0}],"record_name":"test_entry"}' "error"
110curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":8,"record_name":"test_entry"}' "HTTP/1.1 204 No Content" 119gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1
111gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 120
112curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":16,"record_name":"test_entry"}' "HTTP/1.1 204 No Content"
113gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
114curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":-1,"record_name":"test_entry"}' "error"
115gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
116curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":"Test","record_name":"test_entry"}' "error"
117gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
118curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":,"record_name":"test_entry"}' "error"
119gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
120curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag_missing":0,"record_name":"test_entry"}' "error"
121gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
122#record_name 121#record_name
123curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":"test_entry"}' "HTTP/1.1 204 No Content" 122curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0}],"record_name":""}' "error"
124curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":"test_entry"}' "HTTP/1.1 204 No Content" 123gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1
125gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 124curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0}],"record_name_missing":"test_entry"}' "error"
126curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":""}' "error" 125gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1
127gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
128curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name_missing":"test_entry"}' "error"
129gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
130
131#wrong zone
132curl_post "${namestore_link}/$public" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":"test_entry"}' "error"
133gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
134 126
135#Test DELETE 127#Test DELETE
136gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY" 128gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY" -c test_namestore_api.conf
137curl_delete "${namestore_link}/$name?record_name=test_entry" "HTTP/1.1 204" 129curl_delete "${namestore_link}/$name?record_name=test_entry" "HTTP/1.1 204"
138curl_delete "${namestore_link}/$name?record_name=test_entry" "error" 130curl_delete "${namestore_link}/$name?record_name=test_entry" "error"
139gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY" 131gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY" -c test_namestore_api.conf
140curl_delete "${namestore_link}/$public?record_name=test_entry" "error" 132curl_delete "${namestore_link}/$public?record_name=test_entry" "error"
141 133
142 134gnunet-arm -e -c test_namestore_api.conf
143#Test default identity
144#not possible without defining
145
146exit 0; 135exit 0;
147 136
diff --git a/src/nat/gnunet-service-nat.c b/src/nat/gnunet-service-nat.c
index 694949dde..59a340324 100644
--- a/src/nat/gnunet-service-nat.c
+++ b/src/nat/gnunet-service-nat.c
@@ -335,6 +335,11 @@ static struct StunExternalIP *se_tail;
335 */ 335 */
336int enable_upnp; 336int enable_upnp;
337 337
338/**
339 * Is IP Scanning enabled? #GNUNET_YES if enabled, #GNUNET_NO if disabled,
340 * without, only explicitly specified IPs will be handled (HOLE_EXTERNAL)
341 */
342int enable_ipscan;
338 343
339/** 344/**
340 * Remove and free an entry from the #lal_head DLL. 345 * Remove and free an entry from the #lal_head DLL.
@@ -1939,12 +1944,18 @@ run (void *cls,
1939 &dyndns_frequency)) 1944 &dyndns_frequency))
1940 dyndns_frequency = DYNDNS_FREQUENCY; 1945 dyndns_frequency = DYNDNS_FREQUENCY;
1941 1946
1947 enable_ipscan
1948 = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1949 "NAT",
1950 "ENABLE_IPSCAN");
1951
1942 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 1952 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1943 NULL); 1953 NULL);
1944 stats = GNUNET_STATISTICS_create ("nat", 1954 stats = GNUNET_STATISTICS_create ("nat",
1945 cfg); 1955 cfg);
1946 scan_task = GNUNET_SCHEDULER_add_now (&run_scan, 1956 if (GNUNET_YES == enable_ipscan)
1947 NULL); 1957 scan_task = GNUNET_SCHEDULER_add_now (&run_scan,
1958 NULL);
1948} 1959}
1949 1960
1950 1961
diff --git a/src/nat/nat.conf.in b/src/nat/nat.conf.in
index a8dbee953..4c068c394 100644
--- a/src/nat/nat.conf.in
+++ b/src/nat/nat.conf.in
@@ -12,6 +12,9 @@ UNIX_MATCH_GID = YES
12# Enable UPNP by default? 12# Enable UPNP by default?
13ENABLE_UPNP = YES 13ENABLE_UPNP = YES
14 14
15# Enable scanning for all system IP addresses?
16ENABLE_IPSCAN = YES
17
15# Disable IPv6 support 18# Disable IPv6 support
16# FIXME: move entirely to transport plugins! 19# FIXME: move entirely to transport plugins!
17DISABLEV6 = NO 20DISABLEV6 = NO
diff --git a/src/peerstore/test_peerstore_api_data.conf b/src/peerstore/test_peerstore_api_data.conf
index 3ebda50eb..614d0cf5b 100644
--- a/src/peerstore/test_peerstore_api_data.conf
+++ b/src/peerstore/test_peerstore_api_data.conf
@@ -5,8 +5,9 @@ GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-peerstore
5START_ON_DEMAND = YES 5START_ON_DEMAND = YES
6BINARY = gnunet-service-peerstore 6BINARY = gnunet-service-peerstore
7UNIXPATH = $GNUNET_TMP/gnunet-service-peerstore.sock 7UNIXPATH = $GNUNET_TMP/gnunet-service-peerstore.sock
8HOME = $SERVICEHOME
9DATABASE = sqlite 8DATABASE = sqlite
9UNIX_MATCH_UID = NO
10UNIX_MATCH_GID = YES
10#PREFIX = xterm -e gdb --args 11#PREFIX = xterm -e gdb --args
11 12
12[peerstore-sqlite] 13[peerstore-sqlite]
diff --git a/src/peerstore/test_peerstore_api_sync.c b/src/peerstore/test_peerstore_api_sync.c
index b2ac860b7..bfeae6ed8 100644
--- a/src/peerstore/test_peerstore_api_sync.c
+++ b/src/peerstore/test_peerstore_api_sync.c
@@ -117,6 +117,28 @@ test_cont (void *cls)
117 NULL); 117 NULL);
118} 118}
119 119
120static void
121disc_cont (void *cls)
122{
123 GNUNET_PEERSTORE_disconnect (h, GNUNET_YES);
124 h = NULL;
125 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
126 &test_cont,
127 NULL);
128}
129
130static void
131store_cont (void *cls, int success)
132{
133 ok = success;
134 /* We need to wait a little bit to give the disconnect
135 a chance to actually finish the operation; otherwise,
136 the test may fail non-deterministically if the new
137 connection is faster than the cleanup routine of the
138 old one. */
139 GNUNET_SCHEDULER_add_now (&disc_cont,
140 NULL);
141}
120 142
121/** 143/**
122 * Actually run the test. 144 * Actually run the test.
@@ -132,18 +154,7 @@ test1 ()
132 val, strlen (val) + 1, 154 val, strlen (val) + 1,
133 GNUNET_TIME_UNIT_FOREVER_ABS, 155 GNUNET_TIME_UNIT_FOREVER_ABS,
134 GNUNET_PEERSTORE_STOREOPTION_REPLACE, 156 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
135 NULL, NULL); 157 &store_cont, NULL);
136 GNUNET_PEERSTORE_disconnect (h,
137 GNUNET_YES);
138 h = NULL;
139 /* We need to wait a little bit to give the disconnect
140 a chance to actually finish the operation; otherwise,
141 the test may fail non-deterministically if the new
142 connection is faster than the cleanup routine of the
143 old one. */
144 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
145 &test_cont,
146 NULL);
147} 158}
148 159
149 160
@@ -171,7 +182,7 @@ main (int argc, char *argv[])
171 if (0 != 182 if (0 !=
172 GNUNET_TESTING_service_run ("test-gnunet-peerstore-sync", 183 GNUNET_TESTING_service_run ("test-gnunet-peerstore-sync",
173 "peerstore", 184 "peerstore",
174 "test_peerstore_api_data.conf", 185 "peerstore.conf",
175 &run, NULL)) 186 &run, NULL))
176 return 1; 187 return 1;
177 if (0 != ok) 188 if (0 != ok)
diff --git a/src/pq/Makefile.am b/src/pq/Makefile.am
index 9270e6fe0..750a1d48d 100644
--- a/src/pq/Makefile.am
+++ b/src/pq/Makefile.am
@@ -22,7 +22,7 @@ libgnunetpq_la_LIBADD = -lpq \
22libgnunetpq_la_LDFLAGS = \ 22libgnunetpq_la_LDFLAGS = \
23 $(POSTGRESQL_LDFLAGS) \ 23 $(POSTGRESQL_LDFLAGS) \
24 $(GN_LIB_LDFLAGS) \ 24 $(GN_LIB_LDFLAGS) \
25 -version-info 0:0:0 25 -version-info 1:0:0
26 26
27if ENABLE_TEST_RUN 27if ENABLE_TEST_RUN
28TESTS = \ 28TESTS = \
diff --git a/src/pq/pq.c b/src/pq/pq.c
index 7e97c8f72..d2b9a6174 100644
--- a/src/pq/pq.c
+++ b/src/pq/pq.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2014, 2015, 2016 GNUnet e.V. 3 Copyright (C) 2014, 2015, 2016, 2017, 2019 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -25,33 +25,30 @@
25 * @author Christian Grothoff 25 * @author Christian Grothoff
26 */ 26 */
27#include "platform.h" 27#include "platform.h"
28#include "gnunet_util_lib.h" 28#include "pq.h"
29#include "gnunet_pq_lib.h"
30
31 29
32/** 30/**
33 * Execute a prepared statement. 31 * Execute a prepared statement.
34 * 32 *
35 * @param db_conn database connection 33 * @param db database handle
36 * @param name name of the prepared statement 34 * @param name name of the prepared statement
37 * @param params parameters to the statement 35 * @param params parameters to the statement
38 * @return postgres result 36 * @return postgres result
39 */ 37 */
40PGresult * 38PGresult *
41GNUNET_PQ_exec_prepared (PGconn *db_conn, 39GNUNET_PQ_exec_prepared (struct GNUNET_PQ_Context *db,
42 const char *name, 40 const char *name,
43 const struct GNUNET_PQ_QueryParam *params) 41 const struct GNUNET_PQ_QueryParam *params)
44{ 42{
45 unsigned int len; 43 unsigned int len;
46 unsigned int i;
47 44
48 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 45 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
49 "Running prepared statement `%s' on %p\n", 46 "Running prepared statement `%s' on %p\n",
50 name, 47 name,
51 db_conn); 48 db);
52 /* count the number of parameters */ 49 /* count the number of parameters */
53 len = 0; 50 len = 0;
54 for (i = 0; 0 != params[i].num_params; i++) 51 for (unsigned int i = 0; 0 != params[i].num_params; i++)
55 len += params[i].num_params; 52 len += params[i].num_params;
56 53
57 /* new scope to allow stack allocation without alloca */ 54 /* new scope to allow stack allocation without alloca */
@@ -67,10 +64,11 @@ GNUNET_PQ_exec_prepared (PGconn *db_conn,
67 unsigned int soff; 64 unsigned int soff;
68 PGresult *res; 65 PGresult *res;
69 int ret; 66 int ret;
67 ConnStatusType status;
70 68
71 off = 0; 69 off = 0;
72 soff = 0; 70 soff = 0;
73 for (i = 0; 0 != params[i].num_params; i++) 71 for (unsigned int i = 0; 0 != params[i].num_params; i++)
74 { 72 {
75 const struct GNUNET_PQ_QueryParam *x = &params[i]; 73 const struct GNUNET_PQ_QueryParam *x = &params[i];
76 74
@@ -97,13 +95,24 @@ GNUNET_PQ_exec_prepared (PGconn *db_conn,
97 "pq", 95 "pq",
98 "Executing prepared SQL statement `%s'\n", 96 "Executing prepared SQL statement `%s'\n",
99 name); 97 name);
100 res = PQexecPrepared (db_conn, 98 res = PQexecPrepared (db->conn,
101 name, 99 name,
102 len, 100 len,
103 (const char **) param_values, 101 (const char **) param_values,
104 param_lengths, 102 param_lengths,
105 param_formats, 103 param_formats,
106 1); 104 1);
105 if ( (PGRES_COMMAND_OK != PQresultStatus (res)) &&
106 (CONNECTION_OK != (status = PQstatus (db->conn))) )
107 {
108 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
109 "pq",
110 "Database disconnected on SQL statement `%s' (reconnecting)\n",
111 name);
112 GNUNET_PQ_reconnect (db);
113 res = NULL;
114 }
115
107 for (off = 0; off < soff; off++) 116 for (off = 0; off < soff; off++)
108 GNUNET_free (scratch[off]); 117 GNUNET_free (scratch[off]);
109 return res; 118 return res;
@@ -120,9 +129,7 @@ GNUNET_PQ_exec_prepared (PGconn *db_conn,
120void 129void
121GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs) 130GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs)
122{ 131{
123 unsigned int i; 132 for (unsigned int i = 0; NULL != rs[i].conv; i++)
124
125 for (i = 0; NULL != rs[i].conv; i++)
126 if (NULL != rs[i].cleaner) 133 if (NULL != rs[i].cleaner)
127 rs[i].cleaner (rs[i].cls, 134 rs[i].cleaner (rs[i].cls,
128 rs[i].dst); 135 rs[i].dst);
@@ -145,12 +152,12 @@ GNUNET_PQ_extract_result (PGresult *result,
145 struct GNUNET_PQ_ResultSpec *rs, 152 struct GNUNET_PQ_ResultSpec *rs,
146 int row) 153 int row)
147{ 154{
148 unsigned int i; 155 if (NULL == result)
149 int ret; 156 return GNUNET_SYSERR;
150 157 for (unsigned int i = 0; NULL != rs[i].conv; i++)
151 for (i = 0; NULL != rs[i].conv; i++)
152 { 158 {
153 struct GNUNET_PQ_ResultSpec *spec; 159 struct GNUNET_PQ_ResultSpec *spec;
160 int ret;
154 161
155 spec = &rs[i]; 162 spec = &rs[i];
156 ret = spec->conv (spec->cls, 163 ret = spec->conv (spec->cls,
diff --git a/src/pq/pq.h b/src/pq/pq.h
new file mode 100644
index 000000000..b30f4f0d4
--- /dev/null
+++ b/src/pq/pq.h
@@ -0,0 +1,57 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2017, 2019 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 */
20/**
21 * @file pq/pq.h
22 * @brief shared internal data structures of libgnunetpq
23 * @author Christian Grothoff
24 */
25#ifndef PQ_H
26#define PQ_H
27
28#include "gnunet_util_lib.h"
29#include "gnunet_pq_lib.h"
30
31/**
32 * Handle to Postgres database.
33 */
34struct GNUNET_PQ_Context
35{
36 /**
37 * Actual connection.
38 */
39 PGconn *conn;
40
41 /**
42 * Statements to execute upon connection.
43 */
44 struct GNUNET_PQ_ExecuteStatement *es;
45
46 /**
47 * Prepared statements.
48 */
49 struct GNUNET_PQ_PreparedStatement *ps;
50
51 /**
52 * Configuration to use to connect to the DB.
53 */
54 char *config_str;
55};
56
57#endif
diff --git a/src/pq/pq_connect.c b/src/pq/pq_connect.c
index 79b9d6107..882df4f89 100644
--- a/src/pq/pq_connect.c
+++ b/src/pq/pq_connect.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2017 GNUnet e.V. 3 Copyright (C) 2017, 2019 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -23,8 +23,7 @@
23 * @author Christian Grothoff 23 * @author Christian Grothoff
24 */ 24 */
25#include "platform.h" 25#include "platform.h"
26#include "gnunet_util_lib.h" 26#include "pq.h"
27#include "gnunet_pq_lib.h"
28 27
29 28
30/** 29/**
@@ -40,12 +39,14 @@ pq_notice_receiver_cb (void *arg,
40 const PGresult *res) 39 const PGresult *res)
41{ 40{
42 /* do nothing, intentionally */ 41 /* do nothing, intentionally */
42 (void) arg;
43 (void) res;
43} 44}
44 45
45 46
46/** 47/**
47 * Function called by libpq whenever it wants to log something. 48 * Function called by libpq whenever it wants to log something.
48 * We log those using the Taler logger. 49 * We log those using the GNUnet logger.
49 * 50 *
50 * @param arg the SQL connection that was used 51 * @param arg the SQL connection that was used
51 * @param message information about some libpq event 52 * @param message information about some libpq event
@@ -54,6 +55,7 @@ static void
54pq_notice_processor_cb (void *arg, 55pq_notice_processor_cb (void *arg,
55 const char *message) 56 const char *message)
56{ 57{
58 (void) arg;
57 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, 59 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO,
58 "pq", 60 "pq",
59 "%s", 61 "%s",
@@ -64,68 +66,189 @@ pq_notice_processor_cb (void *arg,
64/** 66/**
65 * Create a connection to the Postgres database using @a config_str 67 * Create a connection to the Postgres database using @a config_str
66 * for the configuration. Initialize logging via GNUnet's log 68 * for the configuration. Initialize logging via GNUnet's log
67 * routines and disable Postgres's logger. 69 * routines and disable Postgres's logger. Also ensures that the
70 * statements in @a es are executed whenever we (re)connect to the
71 * database, and that the prepared statements in @a ps are "ready".
72 * If statements in @es fail that were created with
73 * #GNUNET_PQ_make_execute(), then the entire operation fails.
74 *
75 * The caller MUST ensure that @a es and @a ps remain allocated and
76 * initialized in memory until #GNUNET_PQ_disconnect() is called,
77 * as they may be needed repeatedly and no copy will be made.
68 * 78 *
69 * @param config_str configuration to use 79 * @param config_str configuration to use
80 * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated
81 * array of statements to execute upon EACH connection, can be NULL
82 * @param ps array of prepared statements to prepare, can be NULL
70 * @return NULL on error 83 * @return NULL on error
71 */ 84 */
72PGconn * 85struct GNUNET_PQ_Context *
73GNUNET_PQ_connect (const char *config_str) 86GNUNET_PQ_connect (const char *config_str,
87 const struct GNUNET_PQ_ExecuteStatement *es,
88 const struct GNUNET_PQ_PreparedStatement *ps)
74{ 89{
75 PGconn *conn; 90 struct GNUNET_PQ_Context *db;
91 unsigned int elen = 0;
92 unsigned int plen = 0;
93
94 if (NULL != es)
95 while (NULL != es[elen].sql)
96 elen++;
97 if (NULL != ps)
98 while (NULL != ps[plen].name)
99 plen++;
100
101 db = GNUNET_new (struct GNUNET_PQ_Context);
102 db->config_str = GNUNET_strdup (config_str);
103 if (0 != elen)
104 {
105 db->es = GNUNET_new_array (elen + 1,
106 struct GNUNET_PQ_ExecuteStatement);
107 memcpy (db->es,
108 es,
109 elen * sizeof (struct GNUNET_PQ_ExecuteStatement));
110 }
111 if (0 != plen)
112 {
113 db->ps = GNUNET_new_array (plen + 1,
114 struct GNUNET_PQ_PreparedStatement);
115 memcpy (db->ps,
116 ps,
117 plen * sizeof (struct GNUNET_PQ_PreparedStatement));
118 }
119 GNUNET_PQ_reconnect (db);
120 if (NULL == db->conn)
121 {
122 GNUNET_free (db->config_str);
123 GNUNET_free (db);
124 return NULL;
125 }
126 return db;
127}
128
129
130/**
131 * Reinitialize the database @a db if the connection is down.
132 *
133 * @param db database connection to reinitialize
134 */
135void
136GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db)
137{
138 if (CONNECTION_BAD != PQstatus (db->conn))
139 return;
140 GNUNET_PQ_reconnect (db);
141}
142
76 143
77 conn = PQconnectdb (config_str); 144/**
78 if ((NULL == conn) || 145 * Reinitialize the database @a db.
79 (CONNECTION_OK != 146 *
80 PQstatus (conn))) 147 * @param db database connection to reinitialize
148 */
149void
150GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db)
151{
152 if (NULL != db->conn)
153 PQfinish (db->conn);
154 db->conn = PQconnectdb (db->config_str);
155 if ((NULL == db->conn) ||
156 (CONNECTION_OK != PQstatus (db->conn)))
81 { 157 {
82 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, 158 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
83 "pq", 159 "pq",
84 "Database connection to '%s' failed: %s\n", 160 "Database connection to '%s' failed: %s\n",
85 config_str, 161 db->config_str,
86 (NULL != conn) ? 162 (NULL != db->conn) ?
87 PQerrorMessage (conn) 163 PQerrorMessage (db->conn)
88 : "PQconnectdb returned NULL"); 164 : "PQconnectdb returned NULL");
89 if (NULL != conn) 165 if (NULL != db->conn)
90 PQfinish (conn); 166 {
91 return NULL; 167 PQfinish (db->conn);
168 db->conn = NULL;
169 }
170 return;
92 } 171 }
93 PQsetNoticeReceiver (conn, 172 PQsetNoticeReceiver (db->conn,
94 &pq_notice_receiver_cb, 173 &pq_notice_receiver_cb,
95 conn); 174 db);
96 PQsetNoticeProcessor (conn, 175 PQsetNoticeProcessor (db->conn,
97 &pq_notice_processor_cb, 176 &pq_notice_processor_cb,
98 conn); 177 db);
99 return conn; 178 if ( (NULL != db->es) &&
179 (GNUNET_OK !=
180 GNUNET_PQ_exec_statements (db,
181 db->es)) )
182 {
183 PQfinish (db->conn);
184 db->conn = NULL;
185 return;
186 }
187 if ( (NULL != db->ps) &&
188 (GNUNET_OK !=
189 GNUNET_PQ_prepare_statements (db,
190 db->ps)) )
191 {
192 PQfinish (db->conn);
193 db->conn = NULL;
194 return;
195 }
100} 196}
101 197
102 198
103/** 199/**
104 * Connect to a postgres database using the configuration 200 * Connect to a postgres database using the configuration
105 * option "CONFIG" in @a section. 201 * option "CONFIG" in @a section. Also ensures that the
202 * statements in @a es are executed whenever we (re)connect to the
203 * database, and that the prepared statements in @a ps are "ready".
204 *
205 * The caller MUST ensure that @a es and @a ps remain allocated and
206 * initialized in memory until #GNUNET_PQ_disconnect() is called,
207 * as they may be needed repeatedly and no copy will be made.
106 * 208 *
107 * @param cfg configuration 209 * @param cfg configuration
108 * @param section configuration section to use to get Postgres configuration options 210 * @param section configuration section to use to get Postgres configuration options
211 * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated
212 * array of statements to execute upon EACH connection, can be NULL
213 * @param ps array of prepared statements to prepare, can be NULL
109 * @return the postgres handle, NULL on error 214 * @return the postgres handle, NULL on error
110 */ 215 */
111PGconn * 216struct GNUNET_PQ_Context *
112GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, 217GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg,
113 const char *section) 218 const char *section,
219 const struct GNUNET_PQ_ExecuteStatement *es,
220 const struct GNUNET_PQ_PreparedStatement *ps)
114{ 221{
115 PGconn *dbh; 222 struct GNUNET_PQ_Context *db;
116 char *conninfo; 223 char *conninfo;
117 224
118 /* Open database and precompile statements */
119 if (GNUNET_OK != 225 if (GNUNET_OK !=
120 GNUNET_CONFIGURATION_get_value_string (cfg, 226 GNUNET_CONFIGURATION_get_value_string (cfg,
121 section, 227 section,
122 "CONFIG", 228 "CONFIG",
123 &conninfo)) 229 &conninfo))
124 conninfo = NULL; 230 conninfo = NULL;
125 dbh = GNUNET_PQ_connect (conninfo == NULL ? "" : conninfo); 231 db = GNUNET_PQ_connect (conninfo == NULL ? "" : conninfo,
232 es,
233 ps);
126 GNUNET_free_non_null (conninfo); 234 GNUNET_free_non_null (conninfo);
127 return dbh; 235 return db;
128} 236}
129 237
130 238
239/**
240 * Disconnect from the database, destroying the prepared statements
241 * and releasing other associated resources.
242 *
243 * @param db database handle to disconnect (will be free'd)
244 */
245void
246GNUNET_PQ_disconnect (struct GNUNET_PQ_Context *db)
247{
248 GNUNET_free_non_null (db->es);
249 GNUNET_free_non_null (db->ps);
250 PQfinish (db->conn);
251 GNUNET_free (db);
252}
253
131/* end of pq/pq_connect.c */ 254/* end of pq/pq_connect.c */
diff --git a/src/pq/pq_eval.c b/src/pq/pq_eval.c
index 1d041f226..5bcf8ca0e 100644
--- a/src/pq/pq_eval.c
+++ b/src/pq/pq_eval.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2017 GNUnet e.V. 3 Copyright (C) 2017, 2019 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -23,8 +23,7 @@
23 * @author Christian Grothoff 23 * @author Christian Grothoff
24 */ 24 */
25#include "platform.h" 25#include "platform.h"
26#include "gnunet_util_lib.h" 26#include "pq.h"
27#include "gnunet_pq_lib.h"
28 27
29 28
30/** 29/**
@@ -47,7 +46,7 @@
47 * Check the @a result's error code to see what happened. 46 * Check the @a result's error code to see what happened.
48 * Also logs errors. 47 * Also logs errors.
49 * 48 *
50 * @param connection connection to execute the statement in 49 * @param db database to execute the statement with
51 * @param statement_name name of the statement that created @a result 50 * @param statement_name name of the statement that created @a result
52 * @param result result to check 51 * @param result result to check
53 * @return status code from the result, mapping PQ status 52 * @return status code from the result, mapping PQ status
@@ -57,17 +56,31 @@
57 * @deprecated (low level, let's see if we can do with just the high-level functions) 56 * @deprecated (low level, let's see if we can do with just the high-level functions)
58 */ 57 */
59enum GNUNET_DB_QueryStatus 58enum GNUNET_DB_QueryStatus
60GNUNET_PQ_eval_result (PGconn *connection, 59GNUNET_PQ_eval_result (struct GNUNET_PQ_Context *db,
61 const char *statement_name, 60 const char *statement_name,
62 PGresult *result) 61 PGresult *result)
63{ 62{
64 ExecStatusType est; 63 ExecStatusType est;
65 64
65 if (NULL == result)
66 return GNUNET_DB_STATUS_SOFT_ERROR;
66 est = PQresultStatus (result); 67 est = PQresultStatus (result);
67 if ((PGRES_COMMAND_OK != est) && 68 if ((PGRES_COMMAND_OK != est) &&
68 (PGRES_TUPLES_OK != est)) 69 (PGRES_TUPLES_OK != est))
69 { 70 {
70 const char *sqlstate; 71 const char *sqlstate;
72 ConnStatusType status;
73
74 if (CONNECTION_OK != (status = PQstatus (db->conn)))
75 {
76 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO,
77 "pq",
78 "Database connection failed during query `%s': %d (reconnecting)\n",
79 statement_name,
80 status);
81 GNUNET_PQ_reconnect (db);
82 return GNUNET_DB_STATUS_SOFT_ERROR;
83 }
71 84
72 sqlstate = PQresultErrorField (result, 85 sqlstate = PQresultErrorField (result,
73 PG_DIAG_SQLSTATE); 86 PG_DIAG_SQLSTATE);
@@ -94,7 +107,7 @@ GNUNET_PQ_eval_result (PGconn *connection,
94 PG_DIAG_MESSAGE_DETAIL), 107 PG_DIAG_MESSAGE_DETAIL),
95 PQresultErrorMessage (result), 108 PQresultErrorMessage (result),
96 PQresStatus (PQresultStatus (result)), 109 PQresStatus (PQresultStatus (result)),
97 PQerrorMessage (connection)); 110 PQerrorMessage (db->conn));
98 return GNUNET_DB_STATUS_SOFT_ERROR; 111 return GNUNET_DB_STATUS_SOFT_ERROR;
99 } 112 }
100 if (0 == strcmp (sqlstate, 113 if (0 == strcmp (sqlstate,
@@ -111,7 +124,7 @@ GNUNET_PQ_eval_result (PGconn *connection,
111 PG_DIAG_MESSAGE_DETAIL), 124 PG_DIAG_MESSAGE_DETAIL),
112 PQresultErrorMessage (result), 125 PQresultErrorMessage (result),
113 PQresStatus (PQresultStatus (result)), 126 PQresStatus (PQresultStatus (result)),
114 PQerrorMessage (connection)); 127 PQerrorMessage (db->conn));
115 return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; 128 return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
116 } 129 }
117 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, 130 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
@@ -124,7 +137,7 @@ GNUNET_PQ_eval_result (PGconn *connection,
124 PG_DIAG_MESSAGE_DETAIL), 137 PG_DIAG_MESSAGE_DETAIL),
125 PQresultErrorMessage (result), 138 PQresultErrorMessage (result),
126 PQresStatus (PQresultStatus (result)), 139 PQresStatus (PQresultStatus (result)),
127 PQerrorMessage (connection)); 140 PQerrorMessage (db->conn));
128 return GNUNET_DB_STATUS_HARD_ERROR; 141 return GNUNET_DB_STATUS_HARD_ERROR;
129 } 142 }
130 return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; 143 return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
@@ -136,7 +149,7 @@ GNUNET_PQ_eval_result (PGconn *connection,
136 * statement in @a connnection using the given @a params. Returns the 149 * statement in @a connnection using the given @a params. Returns the
137 * resulting session state. 150 * resulting session state.
138 * 151 *
139 * @param connection connection to execute the statement in 152 * @param db database to execute the statement with
140 * @param statement_name name of the statement 153 * @param statement_name name of the statement
141 * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated) 154 * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated)
142 * @return status code from the result, mapping PQ status 155 * @return status code from the result, mapping PQ status
@@ -148,17 +161,19 @@ GNUNET_PQ_eval_result (PGconn *connection,
148 * zero; if INSERT was successful, we return one. 161 * zero; if INSERT was successful, we return one.
149 */ 162 */
150enum GNUNET_DB_QueryStatus 163enum GNUNET_DB_QueryStatus
151GNUNET_PQ_eval_prepared_non_select (PGconn *connection, 164GNUNET_PQ_eval_prepared_non_select (struct GNUNET_PQ_Context *db,
152 const char *statement_name, 165 const char *statement_name,
153 const struct GNUNET_PQ_QueryParam *params) 166 const struct GNUNET_PQ_QueryParam *params)
154{ 167{
155 PGresult *result; 168 PGresult *result;
156 enum GNUNET_DB_QueryStatus qs; 169 enum GNUNET_DB_QueryStatus qs;
157 170
158 result = GNUNET_PQ_exec_prepared (connection, 171 result = GNUNET_PQ_exec_prepared (db,
159 statement_name, 172 statement_name,
160 params); 173 params);
161 qs = GNUNET_PQ_eval_result (connection, 174 if (NULL == result)
175 return GNUNET_DB_STATUS_SOFT_ERROR;
176 qs = GNUNET_PQ_eval_result (db,
162 statement_name, 177 statement_name,
163 result); 178 result);
164 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) 179 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
@@ -182,7 +197,7 @@ GNUNET_PQ_eval_prepared_non_select (PGconn *connection,
182 * status including the number of results given to @a rh (possibly zero). 197 * status including the number of results given to @a rh (possibly zero).
183 * @a rh will not have been called if the return value is negative. 198 * @a rh will not have been called if the return value is negative.
184 * 199 *
185 * @param connection connection to execute the statement in 200 * @param db database to execute the statement with
186 * @param statement_name name of the statement 201 * @param statement_name name of the statement
187 * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated) 202 * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated)
188 * @param rh function to call with the result set, NULL to ignore 203 * @param rh function to call with the result set, NULL to ignore
@@ -191,7 +206,7 @@ GNUNET_PQ_eval_prepared_non_select (PGconn *connection,
191 * codes to `enum GNUNET_DB_QueryStatus`. 206 * codes to `enum GNUNET_DB_QueryStatus`.
192 */ 207 */
193enum GNUNET_DB_QueryStatus 208enum GNUNET_DB_QueryStatus
194GNUNET_PQ_eval_prepared_multi_select (PGconn *connection, 209GNUNET_PQ_eval_prepared_multi_select (struct GNUNET_PQ_Context *db,
195 const char *statement_name, 210 const char *statement_name,
196 const struct GNUNET_PQ_QueryParam *params, 211 const struct GNUNET_PQ_QueryParam *params,
197 GNUNET_PQ_PostgresResultHandler rh, 212 GNUNET_PQ_PostgresResultHandler rh,
@@ -201,10 +216,12 @@ GNUNET_PQ_eval_prepared_multi_select (PGconn *connection,
201 enum GNUNET_DB_QueryStatus qs; 216 enum GNUNET_DB_QueryStatus qs;
202 unsigned int ret; 217 unsigned int ret;
203 218
204 result = GNUNET_PQ_exec_prepared (connection, 219 result = GNUNET_PQ_exec_prepared (db,
205 statement_name, 220 statement_name,
206 params); 221 params);
207 qs = GNUNET_PQ_eval_result (connection, 222 if (NULL == result)
223 return GNUNET_DB_STATUS_SOFT_ERROR;
224 qs = GNUNET_PQ_eval_result (db,
208 statement_name, 225 statement_name,
209 result); 226 result);
210 if (qs < 0) 227 if (qs < 0)
@@ -230,7 +247,7 @@ GNUNET_PQ_eval_prepared_multi_select (PGconn *connection,
230 * value was #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT. Returns the 247 * value was #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT. Returns the
231 * resulting session status. 248 * resulting session status.
232 * 249 *
233 * @param connection connection to execute the statement in 250 * @param db database to execute the statement with
234 * @param statement_name name of the statement 251 * @param statement_name name of the statement
235 * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated) 252 * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated)
236 * @param[in,out] rs result specification to use for storing the result of the query 253 * @param[in,out] rs result specification to use for storing the result of the query
@@ -238,7 +255,7 @@ GNUNET_PQ_eval_prepared_multi_select (PGconn *connection,
238 * codes to `enum GNUNET_DB_QueryStatus`. 255 * codes to `enum GNUNET_DB_QueryStatus`.
239 */ 256 */
240enum GNUNET_DB_QueryStatus 257enum GNUNET_DB_QueryStatus
241GNUNET_PQ_eval_prepared_singleton_select (PGconn *connection, 258GNUNET_PQ_eval_prepared_singleton_select (struct GNUNET_PQ_Context *db,
242 const char *statement_name, 259 const char *statement_name,
243 const struct 260 const struct
244 GNUNET_PQ_QueryParam *params, 261 GNUNET_PQ_QueryParam *params,
@@ -247,10 +264,12 @@ GNUNET_PQ_eval_prepared_singleton_select (PGconn *connection,
247 PGresult *result; 264 PGresult *result;
248 enum GNUNET_DB_QueryStatus qs; 265 enum GNUNET_DB_QueryStatus qs;
249 266
250 result = GNUNET_PQ_exec_prepared (connection, 267 result = GNUNET_PQ_exec_prepared (db,
251 statement_name, 268 statement_name,
252 params); 269 params);
253 qs = GNUNET_PQ_eval_result (connection, 270 if (NULL == result)
271 return GNUNET_DB_STATUS_SOFT_ERROR;
272 qs = GNUNET_PQ_eval_result (db,
254 statement_name, 273 statement_name,
255 result); 274 result);
256 if (qs < 0) 275 if (qs < 0)
diff --git a/src/pq/pq_exec.c b/src/pq/pq_exec.c
index 00527151a..fd4feae53 100644
--- a/src/pq/pq_exec.c
+++ b/src/pq/pq_exec.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2017 GNUnet e.V. 3 Copyright (C) 2017, 2019 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -23,8 +23,7 @@
23 * @author Christian Grothoff 23 * @author Christian Grothoff
24 */ 24 */
25#include "platform.h" 25#include "platform.h"
26#include "gnunet_util_lib.h" 26#include "pq.h"
27#include "gnunet_pq_lib.h"
28 27
29 28
30/** 29/**
@@ -67,14 +66,14 @@ GNUNET_PQ_make_try_execute (const char *sql)
67/** 66/**
68 * Request execution of an array of statements @a es from Postgres. 67 * Request execution of an array of statements @a es from Postgres.
69 * 68 *
70 * @param connection connection to execute the statements over 69 * @param db database to execute the statements with
71 * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated array of prepared 70 * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated array of prepared
72 * statements. 71 * statements.
73 * @return #GNUNET_OK on success (modulo statements where errors can be ignored) 72 * @return #GNUNET_OK on success (modulo statements where errors can be ignored)
74 * #GNUNET_SYSERR on error 73 * #GNUNET_SYSERR on error
75 */ 74 */
76int 75int
77GNUNET_PQ_exec_statements (PGconn *connection, 76GNUNET_PQ_exec_statements (struct GNUNET_PQ_Context *db,
78 const struct GNUNET_PQ_ExecuteStatement *es) 77 const struct GNUNET_PQ_ExecuteStatement *es)
79{ 78{
80 for (unsigned int i = 0; NULL != es[i].sql; i++) 79 for (unsigned int i = 0; NULL != es[i].sql; i++)
@@ -84,8 +83,8 @@ GNUNET_PQ_exec_statements (PGconn *connection,
84 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 83 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
85 "Running statement `%s' on %p\n", 84 "Running statement `%s' on %p\n",
86 es[i].sql, 85 es[i].sql,
87 connection); 86 db);
88 result = PQexec (connection, 87 result = PQexec (db->conn,
89 es[i].sql); 88 es[i].sql);
90 if ((GNUNET_NO == es[i].ignore_errors) && 89 if ((GNUNET_NO == es[i].ignore_errors) &&
91 (PGRES_COMMAND_OK != PQresultStatus (result))) 90 (PGRES_COMMAND_OK != PQresultStatus (result)))
@@ -100,7 +99,7 @@ GNUNET_PQ_exec_statements (PGconn *connection,
100 PG_DIAG_MESSAGE_DETAIL), 99 PG_DIAG_MESSAGE_DETAIL),
101 PQresultErrorMessage (result), 100 PQresultErrorMessage (result),
102 PQresStatus (PQresultStatus (result)), 101 PQresStatus (PQresultStatus (result)),
103 PQerrorMessage (connection)); 102 PQerrorMessage (db->conn));
104 PQclear (result); 103 PQclear (result);
105 return GNUNET_SYSERR; 104 return GNUNET_SYSERR;
106 } 105 }
diff --git a/src/pq/pq_prepare.c b/src/pq/pq_prepare.c
index 0facf100f..b7003fb69 100644
--- a/src/pq/pq_prepare.c
+++ b/src/pq/pq_prepare.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2017 GNUnet e.V. 3 Copyright (C) 2017, 2019 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -23,8 +23,7 @@
23 * @author Christian Grothoff 23 * @author Christian Grothoff
24 */ 24 */
25#include "platform.h" 25#include "platform.h"
26#include "gnunet_util_lib.h" 26#include "pq.h"
27#include "gnunet_pq_lib.h"
28 27
29 28
30/** 29/**
@@ -53,16 +52,42 @@ GNUNET_PQ_make_prepare (const char *name,
53/** 52/**
54 * Request creation of prepared statements @a ps from Postgres. 53 * Request creation of prepared statements @a ps from Postgres.
55 * 54 *
56 * @param connection connection to prepare the statements for 55 * @param db database to prepare the statements for
57 * @param ps #GNUNET_PQ_PREPARED_STATEMENT_END-terminated array of prepared 56 * @param ps #GNUNET_PQ_PREPARED_STATEMENT_END-terminated array of prepared
58 * statements. 57 * statements.
59 * @return #GNUNET_OK on success, 58 * @return #GNUNET_OK on success,
60 * #GNUNET_SYSERR on error 59 * #GNUNET_SYSERR on error
61 */ 60 */
62int 61int
63GNUNET_PQ_prepare_statements (PGconn *connection, 62GNUNET_PQ_prepare_statements (struct GNUNET_PQ_Context *db,
64 const struct GNUNET_PQ_PreparedStatement *ps) 63 const struct GNUNET_PQ_PreparedStatement *ps)
65{ 64{
65 if (db->ps != ps)
66 {
67 /* add 'ps' to list db->ps of prepared statements to run on reconnect! */
68 unsigned int olen = 0; /* length of existing 'db->ps' array */
69 unsigned int nlen = 0; /* length of 'ps' array */
70 struct GNUNET_PQ_PreparedStatement *rps; /* combined array */
71
72 if (NULL != db->ps)
73 while (NULL != db->ps[olen].name)
74 olen++;
75 while (NULL != ps[nlen].name)
76 nlen++;
77 rps = GNUNET_new_array (olen + nlen + 1,
78 struct GNUNET_PQ_PreparedStatement);
79 if (NULL != db->ps)
80 memcpy (rps,
81 db->ps,
82 olen * sizeof (struct GNUNET_PQ_PreparedStatement));
83 memcpy (&rps[olen],
84 ps,
85 nlen * sizeof (struct GNUNET_PQ_PreparedStatement));
86 GNUNET_free_non_null (db->ps);
87 db->ps = rps;
88 }
89
90 /* actually prepare statements */
66 for (unsigned int i = 0; NULL != ps[i].name; i++) 91 for (unsigned int i = 0; NULL != ps[i].name; i++)
67 { 92 {
68 PGresult *ret; 93 PGresult *ret;
@@ -72,7 +97,7 @@ GNUNET_PQ_prepare_statements (PGconn *connection,
72 "Preparing SQL statement `%s' as `%s'\n", 97 "Preparing SQL statement `%s' as `%s'\n",
73 ps[i].sql, 98 ps[i].sql,
74 ps[i].name); 99 ps[i].name);
75 ret = PQprepare (connection, 100 ret = PQprepare (db->conn,
76 ps[i].name, 101 ps[i].name,
77 ps[i].sql, 102 ps[i].sql,
78 ps[i].num_arguments, 103 ps[i].num_arguments,
@@ -84,7 +109,7 @@ GNUNET_PQ_prepare_statements (PGconn *connection,
84 _ ("PQprepare (`%s' as `%s') failed with error: %s\n"), 109 _ ("PQprepare (`%s' as `%s') failed with error: %s\n"),
85 ps[i].sql, 110 ps[i].sql,
86 ps[i].name, 111 ps[i].name,
87 PQerrorMessage (connection)); 112 PQerrorMessage (db->conn));
88 PQclear (ret); 113 PQclear (ret);
89 return GNUNET_SYSERR; 114 return GNUNET_SYSERR;
90 } 115 }
diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c
index cfb16ac12..1fb1e71c0 100644
--- a/src/pq/pq_result_helper.c
+++ b/src/pq/pq_result_helper.c
@@ -587,7 +587,7 @@ extract_abs_time (void *cls,
587 res = (int64_t *) PQgetvalue (result, 587 res = (int64_t *) PQgetvalue (result,
588 row, 588 row,
589 fnum); 589 fnum);
590 if (INT64_MAX == *res) 590 if (INT64_MAX == GNUNET_ntohll ((uint64_t) *res))
591 *udst = GNUNET_TIME_UNIT_FOREVER_ABS; 591 *udst = GNUNET_TIME_UNIT_FOREVER_ABS;
592 else 592 else
593 udst->abs_value_us = GNUNET_ntohll ((uint64_t) *res); 593 udst->abs_value_us = GNUNET_ntohll ((uint64_t) *res);
diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c
index 697d8e580..a103aca5d 100644
--- a/src/pq/test_pq.c
+++ b/src/pq/test_pq.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 (C) 2015, 2016 GNUnet e.V. 3 (C) 2015, 2016, 2019 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -23,75 +23,65 @@
23 * @author Christian Grothoff <christian@grothoff.org> 23 * @author Christian Grothoff <christian@grothoff.org>
24 */ 24 */
25#include "platform.h" 25#include "platform.h"
26#include "gnunet_util_lib.h" 26#include "pq.h"
27#include "gnunet_pq_lib.h"
28 27
29 28
30/** 29/**
31 * Setup prepared statements. 30 * Setup prepared statements.
32 * 31 *
33 * @param db_conn connection handle to initialize 32 * @param db database handle to initialize
34 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure 33 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
35 */ 34 */
36static int 35static int
37postgres_prepare (PGconn *db_conn) 36postgres_prepare (struct GNUNET_PQ_Context *db)
38{ 37{
39 PGresult *result; 38 struct GNUNET_PQ_PreparedStatement ps[] = {
40 39 GNUNET_PQ_make_prepare ("test_insert",
41#define PREPARE(name, sql, ...) \ 40 "INSERT INTO test_pq ("
42 do { \ 41 " pub"
43 result = PQprepare (db_conn, name, sql, __VA_ARGS__); \ 42 ",sig"
44 if (PGRES_COMMAND_OK != PQresultStatus (result)) \ 43 ",abs_time"
45 { \ 44 ",forever"
46 GNUNET_break (0); \ 45 ",hash"
47 PQclear (result); result = NULL; \ 46 ",vsize"
48 return GNUNET_SYSERR; \ 47 ",u16"
49 } \ 48 ",u32"
50 PQclear (result); result = NULL; \ 49 ",u64"
51 } while (0); 50 ") VALUES "
51 "($1, $2, $3, $4, $5, $6,"
52 "$7, $8, $9);",
53 9),
54 GNUNET_PQ_make_prepare ("test_select",
55 "SELECT"
56 " pub"
57 ",sig"
58 ",abs_time"
59 ",forever"
60 ",hash"
61 ",vsize"
62 ",u16"
63 ",u32"
64 ",u64"
65 " FROM test_pq"
66 " ORDER BY abs_time DESC "
67 " LIMIT 1;",
68 0),
69 GNUNET_PQ_PREPARED_STATEMENT_END
70 };
52 71
53 PREPARE ("test_insert", 72 return GNUNET_PQ_prepare_statements (db,
54 "INSERT INTO test_pq (" 73 ps);
55 " pub"
56 ",sig"
57 ",abs_time"
58 ",forever"
59 ",hash"
60 ",vsize"
61 ",u16"
62 ",u32"
63 ",u64"
64 ") VALUES "
65 "($1, $2, $3, $4, $5, $6,"
66 "$7, $8, $9);",
67 9, NULL);
68 PREPARE ("test_select",
69 "SELECT"
70 " pub"
71 ",sig"
72 ",abs_time"
73 ",forever"
74 ",hash"
75 ",vsize"
76 ",u16"
77 ",u32"
78 ",u64"
79 " FROM test_pq"
80 " ORDER BY abs_time DESC "
81 " LIMIT 1;",
82 0, NULL);
83 return GNUNET_OK;
84#undef PREPARE
85} 74}
86 75
87 76
88/** 77/**
89 * Run actual test queries. 78 * Run actual test queries.
90 * 79 *
80 * @param db database handle
91 * @return 0 on success 81 * @return 0 on success
92 */ 82 */
93static int 83static int
94run_queries (PGconn *conn) 84run_queries (struct GNUNET_PQ_Context *db)
95{ 85{
96 struct GNUNET_CRYPTO_RsaPublicKey *pub; 86 struct GNUNET_CRYPTO_RsaPublicKey *pub;
97 struct GNUNET_CRYPTO_RsaPublicKey *pub2 = NULL; 87 struct GNUNET_CRYPTO_RsaPublicKey *pub2 = NULL;
@@ -155,7 +145,7 @@ run_queries (PGconn *conn)
155 GNUNET_PQ_result_spec_end 145 GNUNET_PQ_result_spec_end
156 }; 146 };
157 147
158 result = GNUNET_PQ_exec_prepared (conn, 148 result = GNUNET_PQ_exec_prepared (db,
159 "test_insert", 149 "test_insert",
160 params_insert); 150 params_insert);
161 if (PGRES_COMMAND_OK != PQresultStatus (result)) 151 if (PGRES_COMMAND_OK != PQresultStatus (result))
@@ -171,7 +161,7 @@ run_queries (PGconn *conn)
171 } 161 }
172 162
173 PQclear (result); 163 PQclear (result);
174 result = GNUNET_PQ_exec_prepared (conn, 164 result = GNUNET_PQ_exec_prepared (db,
175 "test_select", 165 "test_select",
176 params_select); 166 params_select);
177 if (1 != 167 if (1 !=
@@ -224,67 +214,71 @@ int
224main (int argc, 214main (int argc,
225 const char *const argv[]) 215 const char *const argv[])
226{ 216{
227 PGconn *conn; 217 struct GNUNET_PQ_ExecuteStatement es[] = {
228 PGresult *result; 218 GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS test_pq ("
219 " pub BYTEA NOT NULL"
220 ",sig BYTEA NOT NULL"
221 ",abs_time INT8 NOT NULL"
222 ",forever INT8 NOT NULL"
223 ",hash BYTEA NOT NULL CHECK(LENGTH(hash)=64)"
224 ",vsize VARCHAR NOT NULL"
225 ",u16 INT2 NOT NULL"
226 ",u32 INT4 NOT NULL"
227 ",u64 INT8 NOT NULL"
228 ")"),
229 GNUNET_PQ_EXECUTE_STATEMENT_END
230 };
231 struct GNUNET_PQ_Context *db;
229 int ret; 232 int ret;
230 233
231 GNUNET_log_setup ("test-pq", 234 GNUNET_log_setup ("test-pq",
232 "WARNING", 235 "WARNING",
233 NULL); 236 NULL);
234 conn = PQconnectdb ("postgres:///gnunetcheck"); 237 db = GNUNET_PQ_connect ("postgres:///gnunetcheck",
235 if (CONNECTION_OK != PQstatus (conn)) 238 es,
239 NULL);
240 if (CONNECTION_OK != PQstatus (db->conn))
236 { 241 {
237 fprintf (stderr, 242 fprintf (stderr,
238 "Cannot run test, database connection failed: %s\n", 243 "Cannot run test, database connection failed: %s\n",
239 PQerrorMessage (conn)); 244 PQerrorMessage (db->conn));
240 GNUNET_break (0); 245 GNUNET_break (0);
241 PQfinish (conn); 246 GNUNET_PQ_disconnect (db);
242 return 77; /* signal test was skipped */ 247 return 77; /* signal test was skipped */
243 } 248 }
244
245 result = PQexec (conn,
246 "CREATE TEMPORARY TABLE IF NOT EXISTS test_pq ("
247 " pub BYTEA NOT NULL"
248 ",sig BYTEA NOT NULL"
249 ",abs_time INT8 NOT NULL"
250 ",forever INT8 NOT NULL"
251 ",hash BYTEA NOT NULL CHECK(LENGTH(hash)=64)"
252 ",vsize VARCHAR NOT NULL"
253 ",u16 INT2 NOT NULL"
254 ",u32 INT4 NOT NULL"
255 ",u64 INT8 NOT NULL"
256 ")");
257 if (PGRES_COMMAND_OK != PQresultStatus (result))
258 {
259 fprintf (stderr,
260 "Failed to create table: %s\n",
261 PQerrorMessage (conn));
262 PQclear (result);
263 PQfinish (conn);
264 return 1;
265 }
266 PQclear (result);
267 if (GNUNET_OK != 249 if (GNUNET_OK !=
268 postgres_prepare (conn)) 250 postgres_prepare (db))
269 { 251 {
270 GNUNET_break (0); 252 GNUNET_break (0);
271 PQfinish (conn); 253 GNUNET_PQ_disconnect (db);
272 return 1; 254 return 1;
273 } 255 }
274 ret = run_queries (conn); 256 ret = run_queries (db);
275 result = PQexec (conn, 257#if TEST_RESTART
276 "DROP TABLE test_pq"); 258 fprintf (stderr, "Please restart Postgres database now!\n");
277 if (PGRES_COMMAND_OK != PQresultStatus (result)) 259 sleep (60);
260 ret = run_queries (db);
261 fprintf (stderr, "Result: %d (expect: 1 -- if you restarted the DB)\n", ret);
262 ret = run_queries (db);
263 fprintf (stderr, "Result: %d (expect: 0)\n", ret);
264#endif
278 { 265 {
279 fprintf (stderr, 266 struct GNUNET_PQ_ExecuteStatement es[] = {
280 "Failed to create table: %s\n", 267 GNUNET_PQ_make_execute ("DROP TABLE test_pq"),
281 PQerrorMessage (conn)); 268 GNUNET_PQ_EXECUTE_STATEMENT_END
282 PQclear (result); 269 };
283 PQfinish (conn); 270
284 return 1; 271 if (GNUNET_OK !=
272 GNUNET_PQ_exec_statements (db,
273 es))
274 {
275 fprintf (stderr,
276 "Failed to drop table\n");
277 GNUNET_PQ_disconnect (db);
278 return 1;
279 }
285 } 280 }
286 PQclear (result); 281 GNUNET_PQ_disconnect (db);
287 PQfinish (conn);
288 return ret; 282 return ret;
289} 283}
290 284
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c
index 51555a56f..6e106fe78 100644
--- a/src/transport/plugin_transport_http_server.c
+++ b/src/transport/plugin_transport_http_server.c
@@ -2856,7 +2856,7 @@ server_start_report_addresses (struct HTTP_Server_Plugin *plugin)
2856 2856
2857 plugin->nat 2857 plugin->nat
2858 = GNUNET_NAT_register (plugin->env->cfg, 2858 = GNUNET_NAT_register (plugin->env->cfg,
2859 "transport-http_server", 2859 plugin->name,
2860 IPPROTO_TCP, 2860 IPPROTO_TCP,
2861 (unsigned int) res, 2861 (unsigned int) res,
2862 (const struct sockaddr **) addrs, 2862 (const struct sockaddr **) addrs,
diff --git a/src/util/gnunet-service-resolver.c b/src/util/gnunet-service-resolver.c
index 23ba39fee..d7d456fba 100644
--- a/src/util/gnunet-service-resolver.c
+++ b/src/util/gnunet-service-resolver.c
@@ -642,9 +642,9 @@ try_cache (const char *hostname,
642 const struct GNUNET_DNSPARSER_Record *record = rle->record; 642 const struct GNUNET_DNSPARSER_Record *record = rle->record;
643 643
644 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 644 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
645 "Found cache entry for '%s', record type '%u'\n", 645 "Checking cache entry for '%s', record is for '%s'\n",
646 hostname, 646 hostname,
647 record_type); 647 record->name);
648 if ((GNUNET_DNSPARSER_TYPE_CNAME == record->type) && 648 if ((GNUNET_DNSPARSER_TYPE_CNAME == record->type) &&
649 (GNUNET_DNSPARSER_TYPE_CNAME != record_type) && (GNUNET_NO == found)) 649 (GNUNET_DNSPARSER_TYPE_CNAME != record_type) && (GNUNET_NO == found))
650 { 650 {
@@ -653,7 +653,8 @@ try_cache (const char *hostname,
653 process_get (hostname, record_type, client_request_id, client); 653 process_get (hostname, record_type, client_request_id, client);
654 return GNUNET_YES; /* counts as a cache "hit" */ 654 return GNUNET_YES; /* counts as a cache "hit" */
655 } 655 }
656 found |= send_reply (rle->record, record_type, client_request_id, client); 656 if (0 == strcmp (record->name, hostname))
657 found |= send_reply (rle->record, record_type, client_request_id, client);
657 } 658 }
658 if (GNUNET_NO == found) 659 if (GNUNET_NO == found)
659 return GNUNET_NO; /* had records, but none matched! */ 660 return GNUNET_NO; /* had records, but none matched! */
@@ -723,6 +724,9 @@ cache_answers (const char *name,
723 { 724 {
724 rc = GNUNET_new (struct ResolveCache); 725 rc = GNUNET_new (struct ResolveCache);
725 rc->hostname = GNUNET_strdup (name); 726 rc->hostname = GNUNET_strdup (name);
727 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
728 "Caching record for name %s under %s\n",
729 record->name, name);
726 GNUNET_CONTAINER_DLL_insert (cache_head, cache_tail, rc); 730 GNUNET_CONTAINER_DLL_insert (cache_head, cache_tail, rc);
727 cache_size++; 731 cache_size++;
728 } 732 }