diff options
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 |
269 | endif | 269 | endif |
270 | endif | 270 | endif |
271 | if HAVE_JSON | ||
272 | check_SCRIPTS += \ | ||
273 | test_plugin_rest_gns.sh | ||
274 | endif | ||
271 | endif | 275 | endif |
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 | |||
45 | gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_CNAME_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf | 45 | gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_CNAME_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf |
46 | RES_CNAME=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t A -c test_gns_lookup.conf` | 46 | RES_CNAME=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t A -c test_gns_lookup.conf` |
47 | RES_CNAME_RAW=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t CNAME -c test_gns_lookup.conf` | 47 | RES_CNAME_RAW=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t CNAME -c test_gns_lookup.conf` |
48 | RES_CNAME_DNS=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf` | 48 | RES_CNAME_DNS=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf | grep $TEST_IP_DNS` |
49 | echo NOW | 49 | echo NOW |
50 | gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf | 50 | gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf |
51 | echo WON | 51 | echo WON |
@@ -76,7 +76,7 @@ else | |||
76 | exit 1 | 76 | exit 1 |
77 | fi | 77 | fi |
78 | 78 | ||
79 | if [ "$RES_CNAME_DNS" = "$TEST_IP_DNS" ] | 79 | if echo "$RES_CNAME_DNS" | grep "$TEST_IP_DNS" > /dev/null |
80 | then | 80 | then |
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 |
86 | fi | 86 | fi |
87 | 87 | ||
88 | if [ "$RES_IP6" = "$TEST_IP6" ] | 88 | if echo "$RES_IP6" | grep "$TEST_IP6" > /dev/null |
89 | then | 89 | then |
90 | echo "PASS: Resolved $TEST_DOMAIN to $RES_IP6." | 90 | echo "PASS: Resolved $TEST_DOMAIN to $RES_IP6." |
91 | else | 91 | else |
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] |
4 | DISABLE = YES | 4 | DISABLE = NO |
5 | 5 | ||
6 | [PATHS] | 6 | [PATHS] |
7 | GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-gns-peer-1/ | 7 | GNUNET_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. | 3 | trap "gnunet-arm -e -c test_gns_lookup.conf" SIGINT |
4 | #Exit 0 means success, exit 1 means failed test | 4 | |
5 | LOCATION=$(which gnunet-config) | ||
6 | if [ -z $LOCATION ] | ||
7 | then | ||
8 | LOCATION="gnunet-config" | ||
9 | fi | ||
10 | $LOCATION --version 1> /dev/null | ||
11 | if test $? != 0 | ||
12 | then | ||
13 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
14 | exit 77 | ||
15 | fi | ||
16 | |||
17 | rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME` | ||
5 | 18 | ||
6 | gns_link="http://localhost:7776/gns" | 19 | gns_link="http://localhost:7776/gns" |
7 | wrong_link="http://localhost:7776/gnsandmore" | 20 | wrong_link="http://localhost:7776/gnsandmore" |
@@ -9,42 +22,47 @@ wrong_link="http://localhost:7776/gnsandmore" | |||
9 | curl_get () { | 22 | curl_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 | } |
34 | TEST_TLD="testtld" | ||
19 | 35 | ||
20 | gnunet-identity -D "test_plugin_rest_gns" > /dev/null 2>&1 | 36 | gnunet-arm -s -c test_gns_lookup.conf |
21 | 37 | curl_get "$gns_link/www.$TEST_TLD" "error" | |
22 | curl_get "$gns_link/www.test_plugin_rest_gns" "error" | ||
23 | |||
24 | gnunet-identity -C "test_plugin_rest_gns" | ||
25 | 38 | ||
26 | curl_get "$gns_link/www.test_plugin_rest_gns" "\[\]" | 39 | gnunet-identity -C "$TEST_TLD" -c test_gns_lookup.conf |
40 | sleep 0.5 | ||
41 | curl_get "$gns_link/www.$TEST_TLD" "\[\]" | ||
27 | 42 | ||
28 | gnunet-namestore -z "test_plugin_rest_gns" -p -a -n www -e 1d -V 1.1.1.1 -t A | 43 | gnunet-namestore -z "$TEST_TLD" -p -a -n www -e 1d -V 1.1.1.1 -t A -c test_gns_lookup.conf |
29 | 44 | ||
30 | curl_get "$gns_link/www.test_plugin_rest_gns" "1.1.1.1" | 45 | curl_get "$gns_link/www.$TEST_TLD" "1.1.1.1" |
31 | 46 | ||
32 | gnunet-namestore -z "test_plugin_rest_gns" -p -a -n www -e 1d -V 1::1 -t AAAA | 47 | gnunet-namestore -z "$TEST_TLD" -p -a -n www -e 1d -V 1::1 -t AAAA -c test_gns_lookup.conf |
33 | 48 | ||
34 | curl_get "$gns_link/www.test_plugin_rest_gns" "1::1.*1.1.1.1" | 49 | curl_get "$gns_link/www.$TEST_TLD" "1::1.*1.1.1.1" |
35 | 50 | ||
36 | gnunet-namestore -z "test_plugin_rest_gns" -p -a -n www -e 1d -V 1.1.1.2 -t A | 51 | gnunet-namestore -z "$TEST_TLD" -p -a -n www -e 1d -V 1.1.1.2 -t A -c test_gns_lookup.conf |
37 | 52 | ||
38 | curl_get "$gns_link/www.test_plugin_rest_gns" "1.1.1.2.*1::1.*1.1.1.1" | 53 | curl_get "$gns_link/www.$TEST_TLD" "1.1.1.2.*1::1.*1.1.1.1" |
39 | curl_get "$gns_link/www.test_plugin_rest_gns?record_type=A" "1.1.1.2.*1.1.1.1" | 54 | curl_get "$gns_link/www.$TEST_TLD?record_type=A" "1.1.1.2.*1.1.1.1" |
40 | curl_get "$gns_link/www.test_plugin_rest_gns?record_type=AAAA" "1::1" | 55 | curl_get "$gns_link/www.$TEST_TLD?record_type=AAAA" "1::1" |
41 | curl_get "$gns_link/www.test_plugin_rest_gns?record_type=WRONG_TYPE" "1.1.1.2.*1::1.*1.1.1.1" | 56 | curl_get "$gns_link/www.$TEST_TLD?record_type=WRONG_TYPE" "1.1.1.2.*1::1.*1.1.1.1" |
42 | 57 | ||
43 | gnunet-namestore -z "test_plugin_rest_gns" -p -a -n www1 -e 1d -V 1.1.1.1 -t A | 58 | gnunet-namestore -z "$TEST_TLD" -p -a -n www1 -e 1d -V 1.1.1.1 -t A -c test_gns_lookup.conf |
44 | curl_get "$gns_link/www1.test_plugin_rest_gns" "1.1.1.1" | 59 | curl_get "$gns_link/www1.$TEST_TLD" "1.1.1.1" |
45 | 60 | ||
46 | gnunet-identity -D "test_plugin_rest_gns" > /dev/null 2>&1 | 61 | gnunet-namestore -z "$TEST_TLD" -d -n www1 -c test_gns_lookup.conf |
62 | gnunet-namestore -z "$TEST_TLD" -d -n www -c test_gns_lookup.conf | ||
47 | 63 | ||
48 | curl_get "$gns_link/www1.test_plugin_rest_gns" "error" | 64 | gnunet-identity -D "$TEST_TLD" -c test_gns_lookup.conf > /dev/null 2>&1 |
49 | 65 | ||
66 | curl_get "$gns_link/www1.$TEST_TLD" "error" | ||
67 | gnunet-arm -e -c -c test_gns_lookup.conf | ||
50 | exit 0 | 68 | exit 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 | */ |
49 | typedef int (*GNUNET_PQ_QueryConverter) (void *cls, | 49 | typedef 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 | */ |
217 | typedef int (*GNUNET_PQ_ResultConverter) (void *cls, | 218 | typedef 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 | */ |
232 | typedef void (*GNUNET_PQ_ResultCleanup) (void *cls, void *rd); | 234 | typedef 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 | */ | ||
429 | struct 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 | */ |
431 | PGresult * | 441 | PGresult * |
432 | GNUNET_PQ_exec_prepared (PGconn *db_conn, | 442 | GNUNET_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 | */ |
480 | enum GNUNET_DB_QueryStatus | 490 | enum GNUNET_DB_QueryStatus |
481 | GNUNET_PQ_eval_result (PGconn *connection, | 491 | GNUNET_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 | */ |
502 | enum GNUNET_DB_QueryStatus | 512 | enum GNUNET_DB_QueryStatus |
503 | GNUNET_PQ_eval_prepared_non_select (PGconn *connection, | 513 | GNUNET_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 | */ |
516 | typedef void (*GNUNET_PQ_PostgresResultHandler) (void *cls, | 526 | typedef 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 | */ |
536 | enum GNUNET_DB_QueryStatus | 547 | enum GNUNET_DB_QueryStatus |
537 | GNUNET_PQ_eval_prepared_multi_select (PGconn *connection, | 548 | GNUNET_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 | */ |
559 | enum GNUNET_DB_QueryStatus | 570 | enum GNUNET_DB_QueryStatus |
560 | GNUNET_PQ_eval_prepared_singleton_select ( | 571 | GNUNET_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 | */ |
625 | int | 637 | int |
626 | GNUNET_PQ_prepare_statements (PGconn *connection, | 638 | GNUNET_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 | */ |
690 | int | 702 | int |
691 | GNUNET_PQ_exec_statements (PGconn *connection, | 703 | GNUNET_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 | */ |
706 | PGconn * | 725 | struct GNUNET_PQ_Context * |
707 | GNUNET_PQ_connect (const char *config_str); | 726 | GNUNET_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 | */ |
718 | PGconn * | 744 | struct GNUNET_PQ_Context * |
719 | GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, | 745 | GNUNET_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 | */ | ||
756 | void | ||
757 | GNUNET_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 | */ | ||
765 | void | ||
766 | GNUNET_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 | */ | ||
775 | void | ||
776 | GNUNET_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, | |||
311 | static void | 291 | static void |
312 | database_shutdown (struct Plugin *plugin) | 292 | database_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 | ||
684 | if HAVE_MHD | ||
685 | if HAVE_JSON | ||
686 | check_SCRIPTS += \ | ||
687 | test_plugin_rest_namestore.sh | ||
688 | endif | ||
689 | endif | ||
690 | |||
684 | EXTRA_DIST = \ | 691 | EXTRA_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, | |||
593 | static void | 563 | static void |
594 | database_shutdown (struct Plugin *plugin) | 564 | database_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 |
2 | trap "gnunet-arm -e -c test_gns_lookup.conf" SIGINT | ||
2 | 3 | ||
3 | #First, start gnunet-arm and the rest-service. | 4 | LOCATION=$(which gnunet-config) |
4 | #Exit 0 means success, exit 1 means failed test | 5 | if [ -z $LOCATION ] |
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_namestore_api.conf -f -s paths -o GNUNET_TEST_HOME` | ||
5 | 17 | ||
6 | namestore_link="http://localhost:7776/namestore" | 18 | namestore_link="http://localhost:7776/namestore" |
7 | wrong_link="http://localhost:7776/namestoreandmore" | 19 | wrong_link="http://localhost:7776/namestoreandmore" |
8 | 20 | ||
9 | 21 | ||
10 | curl_get () { | 22 | curl_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 | ||
21 | curl_post () { | 36 | curl_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 | ||
33 | curl_delete () { | 51 | curl_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 | ||
79 | TEST_ID="test" | ||
80 | gnunet-arm -s -c test_namestore_api.conf | ||
81 | gnunet-arm -i rest -c test_namestore_api.conf | ||
58 | #Test GET | 82 | #Test GET |
59 | gnunet-identity -D "test_plugin_rest_namestore" | 83 | gnunet-identity -C $TEST_ID -c test_namestore_api.conf |
60 | gnunet-identity -C "test_plugin_rest_namestore" | 84 | test="$(gnunet-namestore -D -z $TEST_ID -c test_namestore_api.conf)" |
61 | test="$(gnunet-namestore -D -z "test_plugin_rest_namestore")" | 85 | name=$TEST_ID |
62 | name="test_plugin_rest_namestore" | 86 | public="$(gnunet-identity -d -c test_namestore_api.conf | grep $TEST_ID | awk 'NR==1{print $3}')" |
63 | public="$(gnunet-identity -d | grep "test_plugin_rest_namestore" | awk 'NR==1{print $3}')" | 87 | gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY" -c test_namestore_api.conf |
64 | if [ "" == "$test" ] | ||
65 | then | ||
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" | ||
70 | else | ||
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" | ||
76 | fi | ||
77 | gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY" | ||
78 | curl_get "${namestore_link}" "HTTP/1.1 200 OK" | 88 | curl_get "${namestore_link}" "HTTP/1.1 200 OK" |
79 | curl_get "${namestore_link}/$name" "HTTP/1.1 200 OK" | 89 | curl_get "${namestore_link}/$name" "HTTP/1.1 200 OK" |
80 | curl_get "${namestore_link}/" "error" | ||
81 | curl_get "${namestore_link}/$public" "error" | 90 | curl_get "${namestore_link}/$public" "error" |
82 | gnunet-namestore -z $name -d -n "test_entry" | 91 | gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf |
83 | 92 | ||
84 | #Test POST with NAME | 93 | #Test POST with NAME |
85 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":"test_entry"}' "HTTP/1.1 204 No Content" | 94 | curl_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" |
86 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | 95 | gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 |
87 | #value | 96 | |
88 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRGxxx", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":"test_entry"}' "error" | 97 | # invalid values |
89 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | 98 | curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRGxxx", "record_type":"PKEY", "expiration_time":"1d","flag":0}],"record_name":"test_entry"}' "error" |
90 | curl_post "${namestore_link}/$name" '{"value":"", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":"test_entry"}' "error" | 99 | gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 |
91 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | 100 | |
92 | curl_post "${namestore_link}/$name" '{"value_missing":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRGxxx", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":"test_entry"}' "error" | 101 | |
93 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | 102 | curl_post "${namestore_link}/$name" '{"data": [{"value":"", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name"}]:"test_entry"}' "error" |
94 | #time | 103 | gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 |
95 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"0d","flag":0,"record_name":"test_entry"}' "HTTP/1.1 204" | 104 | |
96 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | 105 | curl_post "${namestore_link}/$name" '{"data": [{"record_type":"PKEY", "expiration_time":"1d","flag":0}],"record_name":"test_entry"}' "error" |
97 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"10000d","flag":0,"record_name":"test_entry"}' "HTTP/1.1 204" | 106 | gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 |
98 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | 107 | |
99 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"now","flag":0,"record_name":"test_entry"}' "error" | 108 | #expirations |
100 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | 109 | curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"0d","flag":0}],"record_name":"test_entry"}' "HTTP/1.1 204" |
101 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"","flag":0,"record_name":"test_entry"}' "error" | 110 | gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 |
102 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | 111 | |
103 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time_missing":"1d","flag":0,"record_name":"test_entry"}' "error" | 112 | curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"10000d","flag":0}],"record_name":"test_entry"}' "HTTP/1.1 204" |
104 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | 113 | gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 |
105 | #flag | 114 | |
106 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":"test_entry"}' "HTTP/1.1 204 No Content" | 115 | curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"now","flag":0}],"record_name":"test_entry"}' "error" |
107 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | 116 | gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 |
108 | curl_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 | |
109 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | 118 | curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time_missing":"1d","flag":0}],"record_name":"test_entry"}' "error" |
110 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":8,"record_name":"test_entry"}' "HTTP/1.1 204 No Content" | 119 | gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 |
111 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | 120 | |
112 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":16,"record_name":"test_entry"}' "HTTP/1.1 204 No Content" | ||
113 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | ||
114 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":-1,"record_name":"test_entry"}' "error" | ||
115 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | ||
116 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":"Test","record_name":"test_entry"}' "error" | ||
117 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | ||
118 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":,"record_name":"test_entry"}' "error" | ||
119 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | ||
120 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag_missing":0,"record_name":"test_entry"}' "error" | ||
121 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | ||
122 | #record_name | 121 | #record_name |
123 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":"test_entry"}' "HTTP/1.1 204 No Content" | 122 | curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0}],"record_name":""}' "error" |
124 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":"test_entry"}' "HTTP/1.1 204 No Content" | 123 | gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 |
125 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | 124 | curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0}],"record_name_missing":"test_entry"}' "error" |
126 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":""}' "error" | 125 | gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 |
127 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | ||
128 | curl_post "${namestore_link}/$name" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name_missing":"test_entry"}' "error" | ||
129 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | ||
130 | |||
131 | #wrong zone | ||
132 | curl_post "${namestore_link}/$public" '{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","flag":0,"record_name":"test_entry"}' "error" | ||
133 | gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1 | ||
134 | 126 | ||
135 | #Test DELETE | 127 | #Test DELETE |
136 | gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY" | 128 | gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY" -c test_namestore_api.conf |
137 | curl_delete "${namestore_link}/$name?record_name=test_entry" "HTTP/1.1 204" | 129 | curl_delete "${namestore_link}/$name?record_name=test_entry" "HTTP/1.1 204" |
138 | curl_delete "${namestore_link}/$name?record_name=test_entry" "error" | 130 | curl_delete "${namestore_link}/$name?record_name=test_entry" "error" |
139 | gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY" | 131 | gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY" -c test_namestore_api.conf |
140 | curl_delete "${namestore_link}/$public?record_name=test_entry" "error" | 132 | curl_delete "${namestore_link}/$public?record_name=test_entry" "error" |
141 | 133 | ||
142 | 134 | gnunet-arm -e -c test_namestore_api.conf | |
143 | #Test default identity | ||
144 | #not possible without defining | ||
145 | |||
146 | exit 0; | 135 | exit 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 | */ |
336 | int enable_upnp; | 336 | int 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 | */ | ||
342 | int 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? |
13 | ENABLE_UPNP = YES | 13 | ENABLE_UPNP = YES |
14 | 14 | ||
15 | # Enable scanning for all system IP addresses? | ||
16 | ENABLE_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! |
17 | DISABLEV6 = NO | 20 | DISABLEV6 = 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 | |||
5 | START_ON_DEMAND = YES | 5 | START_ON_DEMAND = YES |
6 | BINARY = gnunet-service-peerstore | 6 | BINARY = gnunet-service-peerstore |
7 | UNIXPATH = $GNUNET_TMP/gnunet-service-peerstore.sock | 7 | UNIXPATH = $GNUNET_TMP/gnunet-service-peerstore.sock |
8 | HOME = $SERVICEHOME | ||
9 | DATABASE = sqlite | 8 | DATABASE = sqlite |
9 | UNIX_MATCH_UID = NO | ||
10 | UNIX_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 | ||
120 | static void | ||
121 | disc_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 | |||
130 | static void | ||
131 | store_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 \ | |||
22 | libgnunetpq_la_LDFLAGS = \ | 22 | libgnunetpq_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 | ||
27 | if ENABLE_TEST_RUN | 27 | if ENABLE_TEST_RUN |
28 | TESTS = \ | 28 | TESTS = \ |
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 | */ |
40 | PGresult * | 38 | PGresult * |
41 | GNUNET_PQ_exec_prepared (PGconn *db_conn, | 39 | GNUNET_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 = ¶ms[i]; | 73 | const struct GNUNET_PQ_QueryParam *x = ¶ms[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, | |||
120 | void | 129 | void |
121 | GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs) | 130 | GNUNET_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 | */ | ||
34 | struct 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 | |||
54 | pq_notice_processor_cb (void *arg, | 55 | pq_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 | */ |
72 | PGconn * | 85 | struct GNUNET_PQ_Context * |
73 | GNUNET_PQ_connect (const char *config_str) | 86 | GNUNET_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 | */ | ||
135 | void | ||
136 | GNUNET_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 | */ | ||
149 | void | ||
150 | GNUNET_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 | */ |
111 | PGconn * | 216 | struct GNUNET_PQ_Context * |
112 | GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, | 217 | GNUNET_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 | */ | ||
245 | void | ||
246 | GNUNET_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 | */ |
59 | enum GNUNET_DB_QueryStatus | 58 | enum GNUNET_DB_QueryStatus |
60 | GNUNET_PQ_eval_result (PGconn *connection, | 59 | GNUNET_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 | */ |
150 | enum GNUNET_DB_QueryStatus | 163 | enum GNUNET_DB_QueryStatus |
151 | GNUNET_PQ_eval_prepared_non_select (PGconn *connection, | 164 | GNUNET_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 | */ |
193 | enum GNUNET_DB_QueryStatus | 208 | enum GNUNET_DB_QueryStatus |
194 | GNUNET_PQ_eval_prepared_multi_select (PGconn *connection, | 209 | GNUNET_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 | */ |
240 | enum GNUNET_DB_QueryStatus | 257 | enum GNUNET_DB_QueryStatus |
241 | GNUNET_PQ_eval_prepared_singleton_select (PGconn *connection, | 258 | GNUNET_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 | */ |
76 | int | 75 | int |
77 | GNUNET_PQ_exec_statements (PGconn *connection, | 76 | GNUNET_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 | */ |
62 | int | 61 | int |
63 | GNUNET_PQ_prepare_statements (PGconn *connection, | 62 | GNUNET_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 | */ |
36 | static int | 35 | static int |
37 | postgres_prepare (PGconn *db_conn) | 36 | postgres_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 | */ |
93 | static int | 83 | static int |
94 | run_queries (PGconn *conn) | 84 | run_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 | |||
224 | main (int argc, | 214 | main (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 | } |