diff options
author | Omar Tarabai <tarabai@devegypt.com> | 2014-05-14 16:40:45 +0000 |
---|---|---|
committer | Omar Tarabai <tarabai@devegypt.com> | 2014-05-14 16:40:45 +0000 |
commit | a760c1b877f3a9ac17f2577cdc298f793c574407 (patch) | |
tree | 7411c99a1865aa1b1a6e1141172aa9a1378d4db7 /src/peerstore | |
parent | cb67c0bb1e6f2a5bae0295a75bc1f4b1b9f9f765 (diff) | |
download | gnunet-a760c1b877f3a9ac17f2577cdc298f793c574407.tar.gz gnunet-a760c1b877f3a9ac17f2577cdc298f793c574407.zip |
peerstore helper file
Diffstat (limited to 'src/peerstore')
-rw-r--r-- | src/peerstore/Makefile.am | 9 | ||||
-rw-r--r-- | src/peerstore/gnunet-service-peerstore.c | 73 | ||||
-rw-r--r-- | src/peerstore/peerstore.h | 20 | ||||
-rw-r--r-- | src/peerstore/peerstore_api.c | 33 | ||||
-rw-r--r-- | src/peerstore/peerstore_common.c | 139 | ||||
-rw-r--r-- | src/peerstore/peerstore_common.h | 93 | ||||
-rw-r--r-- | src/peerstore/plugin_peerstore_sqlite.c | 136 |
7 files changed, 371 insertions, 132 deletions
diff --git a/src/peerstore/Makefile.am b/src/peerstore/Makefile.am index 4c4c84ed1..b7b7f3ea5 100644 --- a/src/peerstore/Makefile.am +++ b/src/peerstore/Makefile.am | |||
@@ -27,20 +27,23 @@ lib_LTLIBRARIES = \ | |||
27 | libgnunetpeerstore.la | 27 | libgnunetpeerstore.la |
28 | 28 | ||
29 | gnunet_peerstore_SOURCES = \ | 29 | gnunet_peerstore_SOURCES = \ |
30 | gnunet-peerstore.c | 30 | gnunet-peerstore.c |
31 | gnunet_peerstore_LDADD = \ | 31 | gnunet_peerstore_LDADD = \ |
32 | $(top_builddir)/src/util/libgnunetutil.la \ | 32 | $(top_builddir)/src/util/libgnunetutil.la \ |
33 | libgnunetpeerstore.la \ | 33 | libgnunetpeerstore.la \ |
34 | $(GN_LIBINTL) | 34 | $(GN_LIBINTL) |
35 | 35 | ||
36 | gnunet_service_peerstore_SOURCES = \ | 36 | gnunet_service_peerstore_SOURCES = \ |
37 | gnunet-service-peerstore.c | 37 | gnunet-service-peerstore.c \ |
38 | peerstore_common.c | ||
39 | gnunet_service_peerstore_CFLAGS = $(AM_CFLAGS) | ||
38 | gnunet_service_peerstore_LDADD = \ | 40 | gnunet_service_peerstore_LDADD = \ |
39 | $(top_builddir)/src/util/libgnunetutil.la \ | 41 | $(top_builddir)/src/util/libgnunetutil.la \ |
40 | $(GN_LIBINTL) | 42 | $(GN_LIBINTL) |
41 | 43 | ||
42 | libgnunetpeerstore_la_SOURCES = \ | 44 | libgnunetpeerstore_la_SOURCES = \ |
43 | peerstore_api.c | 45 | peerstore_api.c \ |
46 | peerstore_common.c | ||
44 | libgnunetpeerstore_la_LIBADD = \ | 47 | libgnunetpeerstore_la_LIBADD = \ |
45 | $(top_builddir)/src/util/libgnunetutil.la | 48 | $(top_builddir)/src/util/libgnunetutil.la |
46 | libgnunetpeerstore_la_LDFLAGS = \ | 49 | libgnunetpeerstore_la_LDFLAGS = \ |
diff --git a/src/peerstore/gnunet-service-peerstore.c b/src/peerstore/gnunet-service-peerstore.c index 303f25027..990fa2c88 100644 --- a/src/peerstore/gnunet-service-peerstore.c +++ b/src/peerstore/gnunet-service-peerstore.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "peerstore.h" | 28 | #include "peerstore.h" |
29 | #include "gnunet_peerstore_plugin.h" | 29 | #include "gnunet_peerstore_plugin.h" |
30 | #include "peerstore_common.h" | ||
30 | 31 | ||
31 | //TODO: GNUNET_SERVER_receive_done() ? | 32 | //TODO: GNUNET_SERVER_receive_done() ? |
32 | //TODO: implement value lifetime | 33 | //TODO: implement value lifetime |
@@ -79,6 +80,20 @@ handle_client_disconnect (void *cls, | |||
79 | } | 80 | } |
80 | 81 | ||
81 | /** | 82 | /** |
83 | * Handle an iterate request from client | ||
84 | * | ||
85 | * @param cls unused | ||
86 | * @param client identification of the client | ||
87 | * @param message the actual message | ||
88 | */ | ||
89 | void handle_iterate (void *cls, | ||
90 | struct GNUNET_SERVER_Client *client, | ||
91 | const struct GNUNET_MessageHeader *message) | ||
92 | { | ||
93 | |||
94 | } | ||
95 | |||
96 | /** | ||
82 | * Handle a store request from client | 97 | * Handle a store request from client |
83 | * | 98 | * |
84 | * @param cls unused | 99 | * @param cls unused |
@@ -89,49 +104,46 @@ void handle_store (void *cls, | |||
89 | struct GNUNET_SERVER_Client *client, | 104 | struct GNUNET_SERVER_Client *client, |
90 | const struct GNUNET_MessageHeader *message) | 105 | const struct GNUNET_MessageHeader *message) |
91 | { | 106 | { |
92 | struct StoreRequestMessage *req; | 107 | struct GNUNET_PEERSTORE_Record *record; |
93 | uint16_t req_size; | ||
94 | uint16_t ss_size; | ||
95 | uint16_t key_size; | ||
96 | uint16_t value_size; | ||
97 | char *sub_system; | ||
98 | char *key; | ||
99 | void *value; | ||
100 | uint16_t response_type; | 108 | uint16_t response_type; |
101 | struct GNUNET_SERVER_TransmitContext *tc; | 109 | struct GNUNET_SERVER_TransmitContext *tc; |
102 | 110 | ||
103 | req_size = ntohs(message->size); | 111 | record = PEERSTORE_parse_record_message(message); |
104 | if(req_size < sizeof(struct StoreRequestMessage)) | 112 | if(NULL == record) |
113 | { | ||
114 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Malformed store request from client\n"); | ||
115 | GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); | ||
116 | return; | ||
117 | } | ||
118 | if(NULL == record->sub_system) | ||
119 | { | ||
120 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Sub system not supplied in client store request\n"); | ||
121 | GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); | ||
122 | return; | ||
123 | } | ||
124 | if(NULL == record->peer) | ||
105 | { | 125 | { |
106 | GNUNET_break(0); | 126 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Peer id not supplied in client store request\n"); |
107 | GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); | 127 | GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); |
108 | return; | 128 | return; |
109 | } | 129 | } |
110 | req = (struct StoreRequestMessage *)message; | 130 | if(NULL == record->key) |
111 | ss_size = ntohs(req->sub_system_size); | ||
112 | key_size = ntohs(req->key_size); | ||
113 | value_size = ntohs(req->value_size); | ||
114 | if(ss_size + key_size + value_size + sizeof(struct StoreRequestMessage) | ||
115 | != req_size) | ||
116 | { | 131 | { |
117 | GNUNET_break(0); | 132 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Key not supplied in client store request\n"); |
118 | GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); | 133 | GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); |
119 | return; | 134 | return; |
120 | } | 135 | } |
121 | sub_system = (char *)&req[1]; | ||
122 | key = sub_system + ss_size; | ||
123 | value = key + key_size; | ||
124 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Received a store request (size: %lu) for sub system `%s', peer `%s', key `%s'\n", | 136 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Received a store request (size: %lu) for sub system `%s', peer `%s', key `%s'\n", |
125 | value_size, | 137 | record->value_size, |
126 | sub_system, | 138 | record->sub_system, |
127 | GNUNET_i2s (&req->peer), | 139 | GNUNET_i2s (record->peer), |
128 | key); | 140 | record->key); |
129 | if(GNUNET_OK == db->store_record(db->cls, | 141 | if(GNUNET_OK == db->store_record(db->cls, |
130 | sub_system, | 142 | record->sub_system, |
131 | &req->peer, | 143 | record->peer, |
132 | key, | 144 | record->key, |
133 | value, | 145 | record->value, |
134 | value_size)) | 146 | record->value_size)) |
135 | { | 147 | { |
136 | response_type = GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT_OK; | 148 | response_type = GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT_OK; |
137 | } | 149 | } |
@@ -161,6 +173,7 @@ run (void *cls, | |||
161 | { | 173 | { |
162 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { | 174 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { |
163 | {&handle_store, NULL, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE, 0}, | 175 | {&handle_store, NULL, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE, 0}, |
176 | {&handle_iterate, NULL, GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE, 0}, | ||
164 | {NULL, NULL, 0, 0} | 177 | {NULL, NULL, 0, 0} |
165 | }; | 178 | }; |
166 | char *database; | 179 | char *database; |
diff --git a/src/peerstore/peerstore.h b/src/peerstore/peerstore.h index 29e2ed866..521c5c11b 100644 --- a/src/peerstore/peerstore.h +++ b/src/peerstore/peerstore.h | |||
@@ -23,15 +23,18 @@ | |||
23 | * @author Omar Tarabai | 23 | * @author Omar Tarabai |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #ifndef PEERSTORE_H_ | ||
27 | #define PEERSTORE_H_ | ||
28 | |||
26 | #include "gnunet_peerstore_service.h" | 29 | #include "gnunet_peerstore_service.h" |
27 | 30 | ||
28 | 31 | ||
29 | GNUNET_NETWORK_STRUCT_BEGIN | 32 | GNUNET_NETWORK_STRUCT_BEGIN |
30 | 33 | ||
31 | /** | 34 | /** |
32 | * Message carrying a PEERSTORE store request | 35 | * Message carrying a PEERSTORE record message |
33 | */ | 36 | */ |
34 | struct StoreRequestMessage | 37 | struct StoreRecordMessage |
35 | { | 38 | { |
36 | 39 | ||
37 | /** | 40 | /** |
@@ -40,10 +43,9 @@ struct StoreRequestMessage | |||
40 | struct GNUNET_MessageHeader header; | 43 | struct GNUNET_MessageHeader header; |
41 | 44 | ||
42 | /** | 45 | /** |
43 | * Size of the sub_system string | 46 | * #GNUNET_YES if peer id value set, #GNUNET_NO otherwise |
44 | * Allocated at position 0 after this struct | ||
45 | */ | 47 | */ |
46 | size_t sub_system_size; | 48 | uint16_t peer_set; |
47 | 49 | ||
48 | /** | 50 | /** |
49 | * Peer Identity | 51 | * Peer Identity |
@@ -51,6 +53,12 @@ struct StoreRequestMessage | |||
51 | struct GNUNET_PeerIdentity peer; | 53 | struct GNUNET_PeerIdentity peer; |
52 | 54 | ||
53 | /** | 55 | /** |
56 | * Size of the sub_system string | ||
57 | * Allocated at position 0 after this struct | ||
58 | */ | ||
59 | size_t sub_system_size; | ||
60 | |||
61 | /** | ||
54 | * Size of the key string | 62 | * Size of the key string |
55 | * Allocated at position 1 after this struct | 63 | * Allocated at position 1 after this struct |
56 | */ | 64 | */ |
@@ -70,3 +78,5 @@ struct StoreRequestMessage | |||
70 | }; | 78 | }; |
71 | 79 | ||
72 | GNUNET_NETWORK_STRUCT_END | 80 | GNUNET_NETWORK_STRUCT_END |
81 | |||
82 | #endif | ||
diff --git a/src/peerstore/peerstore_api.c b/src/peerstore/peerstore_api.c index fe6ff0fe3..68c171d52 100644 --- a/src/peerstore/peerstore_api.c +++ b/src/peerstore/peerstore_api.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "peerstore.h" | 28 | #include "peerstore.h" |
29 | #include "peerstore_common.h" | ||
29 | 30 | ||
30 | #define LOG(kind,...) GNUNET_log_from (kind, "peerstore-api",__VA_ARGS__) | 31 | #define LOG(kind,...) GNUNET_log_from (kind, "peerstore-api",__VA_ARGS__) |
31 | 32 | ||
@@ -209,11 +210,7 @@ GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h, | |||
209 | void *cont_cls) | 210 | void *cont_cls) |
210 | { | 211 | { |
211 | struct GNUNET_PEERSTORE_StoreContext *sc; | 212 | struct GNUNET_PEERSTORE_StoreContext *sc; |
212 | struct StoreRequestMessage *srm; | 213 | struct StoreRecordMessage *srm; |
213 | size_t ss_size; | ||
214 | size_t key_size; | ||
215 | size_t request_size; | ||
216 | void *dummy; | ||
217 | 214 | ||
218 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 215 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
219 | "Storing value (size: %lu) for subsytem `%s', peer `%s', key `%s'\n", | 216 | "Storing value (size: %lu) for subsytem `%s', peer `%s', key `%s'\n", |
@@ -222,26 +219,12 @@ GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h, | |||
222 | sc->cont = cont; | 219 | sc->cont = cont; |
223 | sc->cont_cls = cont_cls; | 220 | sc->cont_cls = cont_cls; |
224 | sc->h = h; | 221 | sc->h = h; |
225 | ss_size = strlen(sub_system) + 1; | 222 | srm = PEERSTORE_create_record_message(sub_system, |
226 | key_size = strlen(key) + 1; | 223 | peer, |
227 | request_size = sizeof(struct StoreRequestMessage) + | 224 | key, |
228 | ss_size + | 225 | value, |
229 | key_size + | 226 | size, |
230 | size; | 227 | lifetime); |
231 | srm = GNUNET_malloc(request_size); | ||
232 | srm->header.size = htons(request_size); | ||
233 | srm->header.type = htons(GNUNET_MESSAGE_TYPE_PEERSTORE_STORE); | ||
234 | srm->key_size = htons(key_size); | ||
235 | srm->lifetime = lifetime; | ||
236 | srm->peer = *peer; | ||
237 | srm->sub_system_size = htons(ss_size); | ||
238 | srm->value_size = htons(size); | ||
239 | dummy = &srm[1]; | ||
240 | memcpy(dummy, sub_system, ss_size); | ||
241 | dummy += ss_size; | ||
242 | memcpy(dummy, key, key_size); | ||
243 | dummy += key_size; | ||
244 | memcpy(dummy, value, size); | ||
245 | GNUNET_CLIENT_transmit_and_get_response(h->client, | 228 | GNUNET_CLIENT_transmit_and_get_response(h->client, |
246 | (const struct GNUNET_MessageHeader *)srm, | 229 | (const struct GNUNET_MessageHeader *)srm, |
247 | GNUNET_TIME_UNIT_FOREVER_REL, | 230 | GNUNET_TIME_UNIT_FOREVER_REL, |
diff --git a/src/peerstore/peerstore_common.c b/src/peerstore/peerstore_common.c new file mode 100644 index 000000000..f8c6862de --- /dev/null +++ b/src/peerstore/peerstore_common.c | |||
@@ -0,0 +1,139 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | (C) 2012-2013 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file peerstore/peerstore_common.c | ||
22 | * @brief Helper peerstore functions | ||
23 | * @author Omar Tarabai | ||
24 | */ | ||
25 | |||
26 | #include "peerstore_common.h" | ||
27 | |||
28 | /** | ||
29 | * Creates a record message ready to be sent | ||
30 | * | ||
31 | * @param sub_system sub system string | ||
32 | * @param peer Peer identity (can be NULL) | ||
33 | * @param key record key string (can be NULL) | ||
34 | * @param value record value BLOB (can be NULL) | ||
35 | * @param value_size record value size in bytes (set to 0 if value is NULL) | ||
36 | * @param lifetime relative time after which the record expires | ||
37 | * @return pointer to record message struct | ||
38 | */ | ||
39 | struct StoreRecordMessage * | ||
40 | PEERSTORE_create_record_message(const char *sub_system, | ||
41 | const struct GNUNET_PeerIdentity *peer, | ||
42 | const char *key, | ||
43 | const void *value, | ||
44 | size_t value_size, | ||
45 | struct GNUNET_TIME_Relative lifetime) | ||
46 | { | ||
47 | struct StoreRecordMessage *srm; | ||
48 | size_t ss_size; | ||
49 | size_t key_size; | ||
50 | size_t request_size; | ||
51 | void *dummy; | ||
52 | |||
53 | ss_size = strlen(sub_system) + 1; | ||
54 | if(NULL == key) | ||
55 | key_size = 0; | ||
56 | else | ||
57 | key_size = strlen(key) + 1; | ||
58 | request_size = sizeof(struct StoreRecordMessage) + | ||
59 | ss_size + | ||
60 | key_size + | ||
61 | value_size; | ||
62 | srm = GNUNET_malloc(request_size); | ||
63 | srm->header.size = htons(request_size); | ||
64 | srm->header.type = htons(GNUNET_MESSAGE_TYPE_PEERSTORE_STORE); | ||
65 | srm->key_size = htons(key_size); | ||
66 | srm->lifetime = lifetime; | ||
67 | if(NULL == peer) | ||
68 | srm->peer_set = htons(GNUNET_NO); | ||
69 | else | ||
70 | { | ||
71 | srm->peer_set = htons(GNUNET_YES); | ||
72 | srm->peer = *peer; | ||
73 | } | ||
74 | srm->sub_system_size = htons(ss_size); | ||
75 | srm->value_size = htons(value_size); | ||
76 | dummy = &srm[1]; | ||
77 | memcpy(dummy, sub_system, ss_size); | ||
78 | dummy += ss_size; | ||
79 | memcpy(dummy, key, key_size); | ||
80 | dummy += key_size; | ||
81 | memcpy(dummy, value, value_size); | ||
82 | return srm; | ||
83 | |||
84 | } | ||
85 | |||
86 | /** | ||
87 | * Parses a message carrying a record | ||
88 | * | ||
89 | * @param message the actual message | ||
90 | * @return Pointer to record or NULL if error | ||
91 | */ | ||
92 | struct GNUNET_PEERSTORE_Record * | ||
93 | PEERSTORE_parse_record_message(const struct GNUNET_MessageHeader *message) | ||
94 | { | ||
95 | struct StoreRecordMessage *srm; | ||
96 | struct GNUNET_PEERSTORE_Record *record; | ||
97 | uint16_t req_size; | ||
98 | uint16_t ss_size; | ||
99 | uint16_t key_size; | ||
100 | uint16_t value_size; | ||
101 | char *dummy; | ||
102 | |||
103 | req_size = ntohs(message->size); | ||
104 | if(req_size < sizeof(struct StoreRecordMessage)) | ||
105 | return NULL; | ||
106 | srm = (struct StoreRecordMessage *)message; | ||
107 | ss_size = ntohs(srm->sub_system_size); | ||
108 | key_size = ntohs(srm->key_size); | ||
109 | value_size = ntohs(srm->value_size); | ||
110 | if(ss_size + key_size + value_size + sizeof(struct StoreRecordMessage) | ||
111 | != req_size) | ||
112 | return NULL; | ||
113 | record = GNUNET_new(struct GNUNET_PEERSTORE_Record); | ||
114 | if(GNUNET_YES == ntohs(srm->peer_set)) | ||
115 | { | ||
116 | record->peer = GNUNET_new(struct GNUNET_PeerIdentity); | ||
117 | memcpy(record->peer, &srm->peer, sizeof(struct GNUNET_PeerIdentity)); | ||
118 | } | ||
119 | record->lifetime = srm->lifetime; | ||
120 | dummy = (char *)&srm[1]; | ||
121 | if(ss_size > 0) | ||
122 | { | ||
123 | record->sub_system = GNUNET_strdup(dummy); | ||
124 | dummy += ss_size; | ||
125 | } | ||
126 | if(key_size > 0) | ||
127 | { | ||
128 | record->key = GNUNET_strdup(dummy); | ||
129 | dummy += key_size; | ||
130 | } | ||
131 | if(value_size > 0) | ||
132 | { | ||
133 | record->value = GNUNET_malloc(value_size); | ||
134 | memcpy(record->value, dummy, value_size); | ||
135 | } | ||
136 | record->value_size = value_size; | ||
137 | |||
138 | return record; | ||
139 | } | ||
diff --git a/src/peerstore/peerstore_common.h b/src/peerstore/peerstore_common.h new file mode 100644 index 000000000..93fb9931b --- /dev/null +++ b/src/peerstore/peerstore_common.h | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | (C) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file peerstore/peerstore_common.h | ||
23 | * @brief Helper peerstore functions | ||
24 | * @author Omar Tarabai | ||
25 | */ | ||
26 | |||
27 | #include "peerstore.h" | ||
28 | |||
29 | /** | ||
30 | * PEERSTORE single record | ||
31 | */ | ||
32 | struct GNUNET_PEERSTORE_Record | ||
33 | { | ||
34 | |||
35 | /** | ||
36 | * Responsible sub system string | ||
37 | */ | ||
38 | char *sub_system; | ||
39 | |||
40 | /** | ||
41 | * Peer Identity | ||
42 | */ | ||
43 | struct GNUNET_PeerIdentity *peer; | ||
44 | |||
45 | /** | ||
46 | * Record key string | ||
47 | */ | ||
48 | char *key; | ||
49 | |||
50 | /** | ||
51 | * Record value BLOB | ||
52 | */ | ||
53 | void *value; | ||
54 | |||
55 | /** | ||
56 | * Size of value BLOB | ||
57 | */ | ||
58 | size_t value_size; | ||
59 | |||
60 | /** | ||
61 | * Lifetime of record | ||
62 | */ | ||
63 | struct GNUNET_TIME_Relative lifetime; | ||
64 | |||
65 | }; | ||
66 | |||
67 | /** | ||
68 | * Creates a record message ready to be sent | ||
69 | * | ||
70 | * @param sub_system sub system string | ||
71 | * @param peer Peer identity (can be NULL) | ||
72 | * @param key record key string (can be NULL) | ||
73 | * @param value record value BLOB (can be NULL) | ||
74 | * @param value_size record value size in bytes (set to 0 if value is NULL) | ||
75 | * @param lifetime relative time after which the record expires | ||
76 | * @return pointer to record message struct | ||
77 | */ | ||
78 | struct StoreRecordMessage * | ||
79 | PEERSTORE_create_record_message(const char *sub_system, | ||
80 | const struct GNUNET_PeerIdentity *peer, | ||
81 | const char *key, | ||
82 | const void *value, | ||
83 | size_t value_size, | ||
84 | struct GNUNET_TIME_Relative lifetime); | ||
85 | |||
86 | /** | ||
87 | * Parses a message carrying a record | ||
88 | * | ||
89 | * @param message the actual message | ||
90 | * @return Pointer to record or NULL if error | ||
91 | */ | ||
92 | struct GNUNET_PEERSTORE_Record * | ||
93 | PEERSTORE_parse_record_message(const struct GNUNET_MessageHeader *message); | ||
diff --git a/src/peerstore/plugin_peerstore_sqlite.c b/src/peerstore/plugin_peerstore_sqlite.c index ac6d30931..10ab17650 100644 --- a/src/peerstore/plugin_peerstore_sqlite.c +++ b/src/peerstore/plugin_peerstore_sqlite.c | |||
@@ -90,101 +90,67 @@ struct Plugin | |||
90 | /** | 90 | /** |
91 | * Precompiled SQL for selecting from peerstoredata | 91 | * Precompiled SQL for selecting from peerstoredata |
92 | */ | 92 | */ |
93 | sqlite3_stmt *select_peerstoredata_by_ss; | 93 | sqlite3_stmt *select_peerstoredata_by_key; |
94 | 94 | ||
95 | /** | 95 | /** |
96 | * Precompiled SQL for selecting from peerstoredata | 96 | * Precompiled SQL for selecting from peerstoredata |
97 | */ | 97 | */ |
98 | sqlite3_stmt *select_peerstoredata_by_both; | 98 | sqlite3_stmt *select_peerstoredata_by_all; |
99 | 99 | ||
100 | }; | 100 | }; |
101 | 101 | ||
102 | /** | 102 | /** |
103 | * The given 'sqlite' statement has been prepared to be run. | ||
104 | * It will return a record which should be given to the iterator. | ||
105 | * Runs the statement and parses the returned record. | ||
106 | * | ||
107 | * @param plugin plugin context | ||
108 | * @param stmt to run (and then clean up) | ||
109 | * @param iter iterator to call with the result | ||
110 | * @param iter_cls closure for @a iter | ||
111 | * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error | ||
112 | */ | ||
113 | static int | ||
114 | get_record_and_call_iterator (struct Plugin *plugin, | ||
115 | sqlite3_stmt *stmt, | ||
116 | GNUNET_PEERSTORE_RecordIterator iter, void *iter_cls) | ||
117 | { | ||
118 | int ret; | ||
119 | int sret; | ||
120 | const struct GNUNET_PeerIdentity *pid; | ||
121 | const char *sub_system; | ||
122 | const void *value; | ||
123 | size_t value_size; | ||
124 | |||
125 | ret = GNUNET_NO; | ||
126 | if (SQLITE_ROW == (sret = sqlite3_step (stmt))) | ||
127 | { | ||
128 | pid = sqlite3_column_blob(stmt, 0); | ||
129 | sub_system = (const char*) sqlite3_column_text(stmt, 1); | ||
130 | value = sqlite3_column_blob(stmt, 2); | ||
131 | value_size = sqlite3_column_bytes(stmt, 2); | ||
132 | if (NULL != iter) | ||
133 | iter (iter_cls, pid, sub_system, value, value_size); | ||
134 | ret = GNUNET_YES; | ||
135 | } | ||
136 | else | ||
137 | { | ||
138 | if (SQLITE_DONE != sret) | ||
139 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); | ||
140 | } | ||
141 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
142 | LOG_SQLITE (plugin, | ||
143 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
144 | "sqlite3_reset"); | ||
145 | return ret; | ||
146 | |||
147 | } | ||
148 | |||
149 | /** | ||
150 | * Iterate over the records given an optional peer id | 103 | * Iterate over the records given an optional peer id |
151 | * and/or sub system. | 104 | * and/or key. |
152 | * | 105 | * |
153 | * @param cls closure (internal context for the plugin) | 106 | * @param cls closure (internal context for the plugin) |
107 | * @param sub_system name of sub system | ||
154 | * @param peer Peer identity (can be NULL) | 108 | * @param peer Peer identity (can be NULL) |
155 | * @param sub_system name of sub system (can be NULL) | 109 | * @param key entry key string (can be NULL) |
156 | * @param iter function to call with the result | 110 | * @param iter function to call with the result |
157 | * @param iter_cls closure for @a iter | 111 | * @param iter_cls closure for @a iter |
158 | * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error | 112 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
159 | */ | 113 | */ |
160 | static int | 114 | static int |
161 | peerstore_sqlite_iterate_records (void *cls, | 115 | peerstore_sqlite_iterate_records (void *cls, |
162 | const struct GNUNET_PeerIdentity *peer, | ||
163 | const char *sub_system, | 116 | const char *sub_system, |
117 | const struct GNUNET_PeerIdentity *peer, | ||
118 | const char *key, | ||
164 | GNUNET_PEERSTORE_RecordIterator iter, void *iter_cls) | 119 | GNUNET_PEERSTORE_RecordIterator iter, void *iter_cls) |
165 | { | 120 | { |
166 | struct Plugin *plugin = cls; | 121 | struct Plugin *plugin = cls; |
167 | sqlite3_stmt *stmt; | 122 | sqlite3_stmt *stmt; |
168 | int err = 0; | 123 | int err = 0; |
124 | int sret; | ||
125 | const char *ret_sub_system; | ||
126 | const struct GNUNET_PeerIdentity *ret_peer; | ||
127 | const char *ret_key; | ||
128 | const void *ret_value; | ||
129 | size_t ret_value_size; | ||
169 | 130 | ||
170 | if(NULL == sub_system && NULL == peer) | 131 | if(NULL == peer && NULL == key) |
132 | { | ||
171 | stmt = plugin->select_peerstoredata; | 133 | stmt = plugin->select_peerstoredata; |
172 | else if(NULL == sub_system) | 134 | err = (SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC)); |
135 | } | ||
136 | else if(NULL == key) | ||
173 | { | 137 | { |
174 | stmt = plugin->select_peerstoredata_by_pid; | 138 | stmt = plugin->select_peerstoredata_by_pid; |
175 | err = (SQLITE_OK != sqlite3_bind_blob(stmt, 1, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC)); | 139 | err = (SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC)) |
140 | || (SQLITE_OK != sqlite3_bind_blob(stmt, 2, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC)); | ||
176 | } | 141 | } |
177 | else if(NULL == peer) | 142 | else if(NULL == peer) |
178 | { | 143 | { |
179 | stmt = plugin->select_peerstoredata_by_ss; | 144 | stmt = plugin->select_peerstoredata_by_key; |
180 | err = (SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC)); | 145 | err = (SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC)) |
146 | || (SQLITE_OK != sqlite3_bind_text(stmt, 3, key, strlen(key) + 1, SQLITE_STATIC)); | ||
181 | } | 147 | } |
182 | else | 148 | else |
183 | { | 149 | { |
184 | stmt = plugin->select_peerstoredata_by_both; | 150 | stmt = plugin->select_peerstoredata_by_all; |
185 | err = | 151 | err = (SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC)) |
186 | (SQLITE_OK != sqlite3_bind_blob(stmt, 1, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC)) | 152 | || (SQLITE_OK != sqlite3_bind_blob(stmt, 2, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC)) |
187 | || (SQLITE_OK != sqlite3_bind_text(stmt, 2, sub_system, strlen(sub_system) + 1, SQLITE_STATIC)); | 153 | || (SQLITE_OK != sqlite3_bind_text(stmt, 3, key, strlen(key) + 1, SQLITE_STATIC)); |
188 | } | 154 | } |
189 | 155 | ||
190 | if (err) | 156 | if (err) |
@@ -197,7 +163,31 @@ peerstore_sqlite_iterate_records (void *cls, | |||
197 | "sqlite3_reset"); | 163 | "sqlite3_reset"); |
198 | return GNUNET_SYSERR; | 164 | return GNUNET_SYSERR; |
199 | } | 165 | } |
200 | return get_record_and_call_iterator (plugin, stmt, iter, iter_cls); | 166 | while (SQLITE_ROW == (sret = sqlite3_step (stmt))) |
167 | { | ||
168 | ret_sub_system = (const char *)sqlite3_column_text(stmt, 0); | ||
169 | ret_peer = sqlite3_column_blob(stmt, 1); | ||
170 | ret_key = (const char *)sqlite3_column_text(stmt, 2); | ||
171 | ret_value = sqlite3_column_blob(stmt, 3); | ||
172 | ret_value_size = sqlite3_column_bytes(stmt, 3); | ||
173 | if (NULL != iter) | ||
174 | iter (iter_cls, ret_sub_system, ret_peer, ret_key, ret_value, ret_value_size); | ||
175 | } | ||
176 | if (SQLITE_DONE != sret) | ||
177 | { | ||
178 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); | ||
179 | err = 1; | ||
180 | } | ||
181 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
182 | { | ||
183 | LOG_SQLITE (plugin, | ||
184 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
185 | "sqlite3_reset"); | ||
186 | err = 1; | ||
187 | } | ||
188 | if(err) | ||
189 | return GNUNET_SYSERR; | ||
190 | return GNUNET_OK; | ||
201 | } | 191 | } |
202 | 192 | ||
203 | /** | 193 | /** |
@@ -362,17 +352,25 @@ database_setup (struct Plugin *plugin) | |||
362 | "INSERT INTO peerstoredata (sub_system, peer_id, key, value) VALUES (?,?,?,?);", | 352 | "INSERT INTO peerstoredata (sub_system, peer_id, key, value) VALUES (?,?,?,?);", |
363 | &plugin->insert_peerstoredata); | 353 | &plugin->insert_peerstoredata); |
364 | sql_prepare(plugin->dbh, | 354 | sql_prepare(plugin->dbh, |
365 | "SELECT peer_id, sub_system, value FROM peerstoredata", | 355 | "SELECT peer_id, sub_system, value FROM peerstoredata" |
356 | " WHERE sub_system = ?", | ||
366 | &plugin->select_peerstoredata); | 357 | &plugin->select_peerstoredata); |
367 | sql_prepare(plugin->dbh, | 358 | sql_prepare(plugin->dbh, |
368 | "SELECT peer_id, sub_system, value FROM peerstoredata WHERE peer_id = ?", | 359 | "SELECT peer_id, sub_system, value FROM peerstoredata" |
360 | " WHERE sub_system = ?" | ||
361 | " AND peer_id = ?", | ||
369 | &plugin->select_peerstoredata_by_pid); | 362 | &plugin->select_peerstoredata_by_pid); |
370 | sql_prepare(plugin->dbh, | 363 | sql_prepare(plugin->dbh, |
371 | "SELECT peer_id, sub_system, value FROM peerstoredata WHERE sub_system = ?", | 364 | "SELECT peer_id, sub_system, value FROM peerstoredata" |
372 | &plugin->select_peerstoredata_by_ss); | 365 | " WHERE sub_system = ?" |
366 | " AND key = ?", | ||
367 | &plugin->select_peerstoredata_by_key); | ||
373 | sql_prepare(plugin->dbh, | 368 | sql_prepare(plugin->dbh, |
374 | "SELECT peer_id, sub_system, value FROM peerstoredata WHERE peer_id = ? AND sub_system = ?", | 369 | "SELECT peer_id, sub_system, value FROM peerstoredata" |
375 | &plugin->select_peerstoredata_by_both); | 370 | " WHERE sub_system = ?" |
371 | " AND peer_id = ?" | ||
372 | " AND key = ?", | ||
373 | &plugin->select_peerstoredata_by_all); | ||
376 | 374 | ||
377 | return GNUNET_OK; | 375 | return GNUNET_OK; |
378 | } | 376 | } |