diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-08-13 19:43:17 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-08-13 19:43:17 +0000 |
commit | 54edcbe9ce37e934a0d045fdde27e9caa3ac145a (patch) | |
tree | 1f87dffbbb93f09bb4d0b606022ad9595d11bad8 | |
parent | 2151b951b91971bd9c906b12ab940b0ee0038001 (diff) | |
download | gnunet-54edcbe9ce37e934a0d045fdde27e9caa3ac145a.tar.gz gnunet-54edcbe9ce37e934a0d045fdde27e9caa3ac145a.zip |
mysql hackery
-rw-r--r-- | README | 56 | ||||
-rw-r--r-- | TODO | 150 | ||||
-rw-r--r-- | contrib/defaults.conf | 8 | ||||
-rw-r--r-- | src/datacache/Makefile.am | 70 | ||||
-rw-r--r-- | src/datacache/perf_datacache.c | 52 | ||||
-rw-r--r-- | src/datacache/perf_datacache_data_mysql.conf | 12 | ||||
-rw-r--r-- | src/datacache/perf_datacache_data_sqlite.conf (renamed from src/datacache/perf_datacache_data.conf) | 0 | ||||
-rw-r--r-- | src/datacache/plugin_datacache_mysql.c | 1092 | ||||
-rw-r--r-- | src/datacache/test_datacache.c | 50 | ||||
-rw-r--r-- | src/datacache/test_datacache_data_mysql.conf | 12 | ||||
-rw-r--r-- | src/datacache/test_datacache_data_sqlite.conf (renamed from src/datacache/test_datacache_data.conf) | 0 | ||||
-rw-r--r-- | src/datacache/test_datacache_quota.c | 50 | ||||
-rw-r--r-- | src/datastore/Makefile.am | 4 | ||||
-rw-r--r-- | src/datastore/plugin_datastore_mysql.c | 40 |
14 files changed, 1385 insertions, 211 deletions
@@ -19,17 +19,23 @@ https://gnunet.org/. | |||
19 | Dependencies: | 19 | Dependencies: |
20 | ============= | 20 | ============= |
21 | 21 | ||
22 | For the impatient, here is the list of immediate dependencies for | 22 | Please note that for many of its dependencies GNUnet requires very |
23 | running GNUnet: | 23 | recent versions of the libraries which are often NOT to be found in |
24 | stable distributions in 2010. While using older packages may in some | ||
25 | cases on some operating systems may seem to work in some limited | ||
26 | fashion, we are in many cases aware of serious problems with older | ||
27 | packages. Hence please make sure to use the versions listed below. | ||
28 | |||
29 | These are the direct dependencies for running GNUnet: | ||
24 | 30 | ||
25 | - libextractor >= 0.6.1 | 31 | - libextractor >= 0.6.1 |
26 | - libmicrohttpd >= 0.4.6 | 32 | - libmicrohttpd >= 0.9.0 |
27 | - libgcrypt >= 1.2 | 33 | - libgcrypt >= 1.2 |
28 | - libgmp >= 4.0 | 34 | - libgmp >= 4.0 |
29 | - libcurl >= 7.15.4 | 35 | - libcurl >= 7.21.0 |
30 | - libltdl >= 2.2 (part of GNU libtool) | 36 | - libltdl >= 2.2 (part of GNU libtool) |
31 | - sqlite >= 3.0 (alternative to MySQL) | 37 | - sqlite >= 3.0 (alternative to MySQL) |
32 | - mysql >= ??? (not yet supported) | 38 | - mysql >= 5.1 (alternative to sqLite) |
33 | - postgres >= ??? (not yet supported) | 39 | - postgres >= ??? (not yet supported) |
34 | 40 | ||
35 | Recommended autotools for compiling the SVN version are: | 41 | Recommended autotools for compiling the SVN version are: |
@@ -37,8 +43,6 @@ Recommended autotools for compiling the SVN version are: | |||
37 | - automake >= 1.11.1 | 43 | - automake >= 1.11.1 |
38 | - libtool >= 2.2 | 44 | - libtool >= 2.2 |
39 | 45 | ||
40 | See also README.debian for a list of Debian packages. | ||
41 | |||
42 | 46 | ||
43 | How to install? | 47 | How to install? |
44 | =============== | 48 | =============== |
@@ -47,6 +51,12 @@ The fastest way is to use a binary package if it is available for your | |||
47 | system. For a more detailed description, read the installation | 51 | system. For a more detailed description, read the installation |
48 | instructions on the webpage at https://gnunet.org/installation. | 52 | instructions on the webpage at https://gnunet.org/installation. |
49 | 53 | ||
54 | Note that some functions of GNUnet require "root" access. GNUnet will | ||
55 | install (tiny) SUID binaries for those functions is you run "make | ||
56 | install" as root. If you do not, GNUnet will still work, but some | ||
57 | functionality will not be available (including certain forms of NAT | ||
58 | traversal). | ||
59 | |||
50 | GNUnet requires the GNU MP library (http://www.gnu.org/software/gmp/) | 60 | GNUnet requires the GNU MP library (http://www.gnu.org/software/gmp/) |
51 | and libgcrypt (http://www.gnupg.org/). You can specify the path to | 61 | and libgcrypt (http://www.gnupg.org/). You can specify the path to |
52 | libgcrypt by passing "--with-gcrypt=PATH" to configure. You will also | 62 | libgcrypt by passing "--with-gcrypt=PATH" to configure. You will also |
@@ -195,20 +205,30 @@ testcase to the Mantis bugtracking system at | |||
195 | https://gnunet.org/bugs/. | 205 | https://gnunet.org/bugs/. |
196 | 206 | ||
197 | 207 | ||
198 | Running http on port 80 | 208 | Running http on port 80 and https on port 443 |
199 | ======================= | 209 | ============================================= |
200 | 210 | ||
201 | In order to hide GNUnet's HTTP traffic perfectly, you might consider | 211 | In order to hide GNUnet's HTTP/HTTPS traffic perfectly, you might |
202 | running GNUnet's HTTP transport on port 80. However, we do not | 212 | consider running GNUnet's HTTP/HTTPS transport on port 80/443. |
203 | recommend running GNUnet as root. Instead, forward port 80 to say | 213 | However, we do not recommend running GNUnet as root. Instead, forward |
204 | 8080 with this command (as root, in your startup scripts): | 214 | port 80 to say 8080 with this command (as root, in your startup |
215 | scripts): | ||
205 | 216 | ||
206 | # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080 | 217 | # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080 |
207 | 218 | ||
208 | Then set in the HTTP section of gnunet.conf the "ADVERTISED-PORT" | 219 | or for HTTPS |
209 | to "80" and "PORT" to 8080. You can do the same trick for the | 220 | |
210 | TCP and UDP transports if you want to map them to a priviledged | 221 | # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 4433 |
211 | port (from the point of view of the network). | 222 | |
223 | Then set in the HTTP section of gnunet.conf the "ADVERTISED-PORT" to | ||
224 | "80" and "PORT" to 8080 and similarly in the HTTPS section the | ||
225 | "ADVERTISED-PORT" to "443" and "PORT" to 4433. | ||
226 | |||
227 | You can do the same trick for the TCP and UDP transports if you want | ||
228 | to map them to a priviledged port (from the point of view of the | ||
229 | network). However, we are not aware of this providing any advantages | ||
230 | at this point. | ||
231 | |||
212 | 232 | ||
213 | 233 | ||
214 | Running the SMTP transport | 234 | Running the SMTP transport |
@@ -218,7 +238,7 @@ Running the SMTP transport | |||
218 | Running GNUnet over SMTP (e-mail) is a bit more involved. Note that | 238 | Running GNUnet over SMTP (e-mail) is a bit more involved. Note that |
219 | you do not need to run all transports (only running the NAT transport | 239 | you do not need to run all transports (only running the NAT transport |
220 | is the only thing that will not work). If you really want to do | 240 | is the only thing that will not work). If you really want to do |
221 | P2P over SMTP, read the instructions at http://gnunet.org/smtp.php3 | 241 | P2P over SMTP, read the instructions at http://gnunet.org/smtp |
222 | 242 | ||
223 | 243 | ||
224 | Stay tuned | 244 | Stay tuned |
@@ -3,6 +3,7 @@ | |||
3 | - only connect() sockets that are ready (select()) [Nils] | 3 | - only connect() sockets that are ready (select()) [Nils] |
4 | [On W32, we need to select after calling socket before doing connect etc.] | 4 | [On W32, we need to select after calling socket before doing connect etc.] |
5 | * CORE: | 5 | * CORE: |
6 | - derived key generation [Nils] | ||
6 | - Jun 27 11:51:54 core-7670 ERROR Assertion failed at gnunet-service-core.c:3616. | 7 | - Jun 27 11:51:54 core-7670 ERROR Assertion failed at gnunet-service-core.c:3616. |
7 | (transport notified us that we connected to ourselves!!!) | 8 | (transport notified us that we connected to ourselves!!!) |
8 | - transport-level disconnect (i.e. TCP) does not cause core-level | 9 | - transport-level disconnect (i.e. TCP) does not cause core-level |
@@ -12,36 +13,34 @@ | |||
12 | => may have been fixed with instant-notification of disconnect | 13 | => may have been fixed with instant-notification of disconnect |
13 | to core on session-oriented connection hick-up; not perfect but | 14 | to core on session-oriented connection hick-up; not perfect but |
14 | likely good enough until we get ATS going; still should be tested... | 15 | likely good enough until we get ATS going; still should be tested... |
15 | => "peers connected (transport)" now instantly goes to ZERO (core statistic), | 16 | ` => "peers connected (transport)" now instantly goes to ZERO (core statistic), |
16 | but "established sessions" stays up... | 17 | but "established sessions" stays up... |
17 | - derived key generation [Nils] | 18 | * PWNAT: [Nate/MW/Nils] |
18 | * PWNAT: [Nate/MW/Nils] | ||
19 | - W32 port | 19 | - W32 port |
20 | * GNUNET-GTK: [CG] | 20 | * GNUNET-GTK: [CG] |
21 | - bugs: | 21 | - handle 'lost parent' case for recursive downloads (need to move children!) |
22 | + handle 'lost parent' case for recursive downloads (need to move children!) | ||
23 | 22 | ||
24 | 0.9.0pre3: | 23 | 0.9.0pre3: |
25 | * Determine RC bugs and fix those! | 24 | * Determine RC bugs and fix those (release should have no known real bugs) |
26 | * DATASTORE: [LT] | 25 | * DATASTORE: [LT] |
27 | - GNUNET_DATASTORE_cancel method not tested [LT] | 26 | - GNUNET_DATASTORE_cancel method not tested [LT] |
28 | * TESTING: [Nate] | 27 | * TESTING: [Nate] |
29 | - test basic peer re-configure | 28 | - test basic peer re-configure |
30 | - consider changing API for peer-group termination to | 29 | * TOPOLOGY: [Nate] |
31 | call continuation when done | ||
32 | * TOPOLOGY: | ||
33 | - needs more testing (especially F2F topology) & transport blacklisting | 30 | - needs more testing (especially F2F topology) & transport blacklisting |
31 | * TRANSPORT-TCP [MW]: | ||
32 | - should use hash map to look up sessions | ||
34 | * NAT/UPNP: [MW] | 33 | * NAT/UPNP: [MW] |
35 | - finalize API design | 34 | - finalize API design |
36 | - code clean up | 35 | - code clean up |
37 | - testing | 36 | - testing |
38 | - integration with transport service | 37 | - integration with transport service |
39 | * MYSQL database backends: [CG] | 38 | - also do UPnP-based (external) IP detection |
40 | - datacache | 39 | (Note: build library always, build UPnP service when dependencies like libxml2 are available) |
41 | * FS: [CG] | 40 | * FS: [CG] |
42 | - library: | 41 | - library: |
43 | + reconstruct IBLOCKS from DBLOCKS if possible (during download; see FIXME in fs_download) | 42 | + reconstruct IBLOCKS from DBLOCKS if possible (during download; see FIXME in fs_download) |
44 | + add support for pushing "already seen" search results to FS service for bloomfilter (can wait) | 43 | + add support for pushing "already seen" search results to FS service for bloomfilter |
45 | + use different 'priority' for probe downloads vs. normal downloads | 44 | + use different 'priority' for probe downloads vs. normal downloads |
46 | - service: | 45 | - service: |
47 | + trust: do not charge when "idle" / load considerations (migration, routing) | 46 | + trust: do not charge when "idle" / load considerations (migration, routing) |
@@ -56,25 +55,26 @@ | |||
56 | + download | 55 | + download |
57 | + search | 56 | + search |
58 | + unindex | 57 | + unindex |
59 | * ARM: [CG/Safey] | 58 | - re-implement gnunet-auto-share |
60 | - better tracking of which config changes actually need to cause process restarts by ARM. | ||
61 | - handle gnunet-arm -k in combination with auto-start magic (what is the right thing here?) | ||
62 | - discover dependencies between services | ||
63 | * GNUNET-GTK: | 59 | * GNUNET-GTK: |
64 | - optimize meta-data for directories in 'add_dir_at_iter' | 60 | - optimize meta-data for directories in 'add_dir_at_iter' |
65 | - add progress dialog for 'add_dir_at_iter' scan (can take a while...) | ||
66 | - finish publish dialog details: | 61 | - finish publish dialog details: |
67 | + normalize keywords (edit subdialog) | 62 | + normalize keywords (edit subdialog) |
68 | + set/view previews (edit subdialog) | 63 | + set/view previews (edit subdialog) |
69 | - add tool bar | ||
70 | - implement download by URI dialog; figure out where to display those downloads! | 64 | - implement download by URI dialog; figure out where to display those downloads! |
71 | - figure out where in the GUI we should show active uploads/unindex operations and allow aborts | 65 | - figure out where in the GUI we should show active uploads/unindex operations and allow aborts |
72 | - implement unindex operation (use dialog with all indexed files for selection) | 66 | - implement unindex operation (use dialog with all indexed files for selection) |
73 | - do meaningful update to status line (starting up, peer running, #connections, shutdown, ...) | ||
74 | - events: | 67 | - events: |
75 | + search error | 68 | + search error |
76 | + publish error | 69 | + publish error |
77 | + unindex error | 70 | + unindex error |
71 | * POSTGRES database backends: [CG] | ||
72 | - datacache | ||
73 | - datastore | ||
74 | * ARM: [CG/Safey] | ||
75 | - better tracking of which config changes actually need to cause process restarts by ARM. | ||
76 | - handle gnunet-arm -k in combination with auto-start magic (what is the right thing here?) | ||
77 | - discover dependencies between services | ||
78 | * MONKEY: [Safey] | 78 | * MONKEY: [Safey] |
79 | - better crash management (attach debugging support, capture and analyze | 79 | - better crash management (attach debugging support, capture and analyze |
80 | debug output, detect random vs. deterministic crashes) | 80 | debug output, detect random vs. deterministic crashes) |
@@ -82,38 +82,26 @@ | |||
82 | - '-f FILENAME' option to write report to file instead of e-mail (for testing!) | 82 | - '-f FILENAME' option to write report to file instead of e-mail (for testing!) |
83 | 83 | ||
84 | 0.9.0: | 84 | 0.9.0: |
85 | * new webpage: | 85 | * Determine RC bugs and fix those (release should have no known real bugs) |
86 | * new webpage: [BL] | ||
86 | - convert documentation pages to books | 87 | - convert documentation pages to books |
87 | - update books (especially for developers) | 88 | - update books (especially for developers) |
88 | - make a NICE download page and figure out how to enable developers to publish TGZs nicely | 89 | - make a NICE download page and figure out how to enable developers to publish TGZs nicely |
89 | - port "contact" page | 90 | - port "contact" page |
90 | - add content type for "todo" items? | 91 | - add content type for "todo" items |
91 | * POSTGRES database backends: [CG] | 92 | * SETUP: [CG] |
92 | - datacache | ||
93 | - datastore | ||
94 | * Determine RC bugs and fix those! | ||
95 | * SETUP: | ||
96 | - design & implement new setup tool | 93 | - design & implement new setup tool |
97 | * TBENCH: [MW] | 94 | * TBENCH: [MW] |
98 | - good to have for transport/DV evaluation! | 95 | - good to have for transport/DV evaluation! |
99 | * TRACEKIT: [MW] | 96 | * TRACEKIT: [MW] |
100 | - good to have for DV/DHT evaluation! | 97 | - good to have for DHT evaluation! |
101 | * DV: | ||
102 | - performance tests | ||
103 | * DHT: [Nate] | 98 | * DHT: [Nate] |
104 | - performance tests | 99 | - performance tests |
105 | * STATISTICS: | ||
106 | - test notification-based statistics API [LT] | ||
107 | - implement statistics GUI | ||
108 | * PEERINFO: [NN] | ||
109 | - move peerinfo to new GUI? | ||
110 | - extend peer dialog with green-yellow-red connectivity status lights | ||
111 | - extend peer dialog with country flags and names | ||
112 | 100 | ||
113 | 0.9.x: | 101 | 0.9.1: |
114 | * TRANSPORT: [MW] | 102 | * TRANSPORT: [MW] |
115 | - WiFi transport backend [DB] | 103 | - WiFi transport backend [DB] |
116 | - SMTP transport backend | 104 | - implement gnunet-transport (transport configurator / tester) |
117 | - Implement method of learning our external addresses from | 105 | - Implement method of learning our external addresses from |
118 | other peers; need some kind of threshold-based | 106 | other peers; need some kind of threshold-based |
119 | scheme, limiting both the total number of addresses that we accept | 107 | scheme, limiting both the total number of addresses that we accept |
@@ -129,50 +117,70 @@ | |||
129 | a way to easily "veto" addresses off the list! | 117 | a way to easily "veto" addresses off the list! |
130 | => If MiM attacker uses vetoed address, blacklist the specific IP for | 118 | => If MiM attacker uses vetoed address, blacklist the specific IP for |
131 | the presumed neighbour! | 119 | the presumed neighbour! |
132 | - implement gnunet-transport (transport configurator / tester) | ||
133 | - UPnP-based IP detection | ||
134 | (Note: build library always, build service when libxml2/etc. are available) | ||
135 | * DV: | ||
136 | - proper bandwidth allocation | ||
137 | * FS: [CG] | ||
138 | - Remove KBlocks in gnunet-unindex (see discussion with Kenneth Almquist on gnunet-devs in 9/2009) | ||
139 | * PEERINFO: [NN] | ||
140 | - expire 'ancient' HELLOs (those without valid addresses AND that | ||
141 | we have not 'used' (for their public keys) in a while; need a way | ||
142 | to track actual 'use') | ||
143 | - make sue we also trigger notifications whenever HELLOs expire | ||
144 | * VPN [PT] | ||
145 | * UTIL: [CG] | ||
146 | - allow limiting UNIX socket access by UID/GID | ||
147 | |||
148 | |||
149 | |||
150 | Optimizations: | ||
151 | * TCP: | ||
152 | - should use hash map to look up sessions | ||
153 | * STATISTICS: | ||
154 | - should use BIO instead of mmap | ||
155 | * TRANSPORT: | ||
156 | - need to periodically probe latency/transport cost changes & possibly switch transport | 120 | - need to periodically probe latency/transport cost changes & possibly switch transport |
157 | - should use hash map to look up Neighbours (service AND plugins!) | 121 | - should use hash map to look up Neighbours (service AND plugins!) |
122 | * DV: [Nate] | ||
123 | - proper bandwidth allocation | ||
124 | - performance tests | ||
158 | * PEERINFO: | 125 | * PEERINFO: |
159 | - merge multiple HELLOs of the same peer in the transmission queue | 126 | - merge multiple HELLOs of the same peer in the transmission queue |
160 | (theoretically reduces overhead; bounds message queue size) | 127 | (theoretically reduces overhead; bounds message queue size) |
161 | - merge multiple iteration requests over "all" peers in the queue | 128 | - merge multiple iteration requests over "all" peers in the queue |
162 | (theoretically reduces overhead; bounds messgae queue size) | 129 | (theoretically reduces overhead; bounds messgae queue size) |
163 | * FS: | 130 | * STATISTICS: [CG] |
164 | - use different queue prioritization for probe-downloads vs. normal downloads (!?) | 131 | - should use BIO instead of mmap |
132 | * FS: [CG] | ||
133 | - Remove KBlocks in gnunet-unindex (see discussion with Kenneth Almquist on gnunet-devs in 9/2009) | ||
134 | - use different queue prioritization for probe-downloads vs. normal downloads | ||
135 | * UTIL: [CG] | ||
136 | - allow limiting UNIX socket access by UID/GID | ||
137 | * GNUNET-GTK: [CG] | ||
138 | - add tool bar | ||
139 | - do meaningful update to status line (starting up, peer running, #connections, shutdown, ...) | ||
140 | - add progress dialog for 'add_dir_at_iter' scan (can take a while...) | ||
141 | - NS list in search dialog should use colors to offset our own namespaces from the others | ||
142 | - right-clicking on NS list in search dialog should open menu that allows | ||
143 | * viewing full meta data | ||
144 | * deletion of namespace info | ||
165 | 145 | ||
166 | Minor features: | 146 | 0.9.2: |
147 | * PEERINFO: [NN] | ||
148 | - expire 'ancient' HELLOs (those without valid addresses AND that | ||
149 | we have not 'used' (for their public keys) in a while; need a way | ||
150 | to track actual 'use') | ||
151 | - make sue we also trigger notifications whenever HELLOs expire | ||
167 | * TCP: | 152 | * TCP: |
168 | - repeatedly resolve hostname and look up interfaces to determine our own IP | 153 | - repeatedly resolve hostname and look up interfaces to determine our own IP |
169 | - [./transport/plugin_transport_tcp.c:391]: (style) struct or union member 'Plugin::address_update_task' is never used (related to issue above) | 154 | - [./transport/plugin_transport_tcp.c:391]: (style) struct or union member 'Plugin::address_update_task' is never used (related to issue above) |
170 | * TRANSPORT: | 155 | * TRANSPORT: |
171 | - [./transport/gnunet-service-transport.c:173]: (style) struct or union member 'TransportPlugin::rebuild' is never used (related to TCP not refreshing external addresses?) | 156 | - [./transport/gnunet-service-transport.c:173]: (style) struct or union member 'TransportPlugin::rebuild' is never used (related to TCP not refreshing external addresses?) |
157 | - WiFi transport backend | ||
158 | * nice signal strength adjustment [MW] | ||
159 | * energy cost in ATS [MW] | ||
172 | * BLOCKS: | 160 | * BLOCKS: |
173 | - testcase would be nice... | 161 | - testcase would be nice |
174 | * GNUNET-GTK: | 162 | - generic block support for DHT |
175 | - NS list in search dialog should use colors to offset our own namespaces from the others | 163 | * STATISTICS: |
176 | - right-clicking on NS list in search dialog should open menu that allows | 164 | - test notification-based statistics API [LT] |
177 | * viewing full meta data | 165 | - implement statistics GUI (=> start from gnunet-gtk by button!) |
178 | * deletion of namespace info | 166 | * PEERINFO: [NN] |
167 | - move peerinfo to new GUI (=> start from gnunet-gtk by button!) | ||
168 | - extend peer dialog with green-yellow-red connectivity status lights | ||
169 | - extend peer dialog with country flags and names | ||
170 | |||
171 | 0.9.3: | ||
172 | * SMTP transport backend: | ||
173 | - sending (SMTP/SMTPS) | ||
174 | - receiving (IMAP/IMAPS/POP?) | ||
175 | - rate limiting | ||
176 | - improved batching | ||
177 | - resource limit integration with ATS | ||
178 | * VPN [PT] | ||
179 | - DNS hijacking | ||
180 | - DNS exit | ||
181 | - TCP entry/exit | ||
182 | - UDP entry/exit | ||
183 | - internal services | ||
184 | - integration with DHT routing | ||
185 | - optimized routes (beyond DHT/DV) | ||
186 | - "DNS" .gnunet | ||
diff --git a/contrib/defaults.conf b/contrib/defaults.conf index 74efa2260..94d64d932 100644 --- a/contrib/defaults.conf +++ b/contrib/defaults.conf | |||
@@ -205,6 +205,14 @@ USER = gnunet | |||
205 | # HOST = | 205 | # HOST = |
206 | # PORT = | 206 | # PORT = |
207 | 207 | ||
208 | [datacache-mysql] | ||
209 | DATABASE = gnunetcheck | ||
210 | # CONFIG = ~/.my.cnf | ||
211 | USER = gnunet | ||
212 | # PASSWORD = | ||
213 | # HOST = | ||
214 | # PORT = | ||
215 | |||
208 | [fs] | 216 | [fs] |
209 | AUTOSTART = YES | 217 | AUTOSTART = YES |
210 | INDEXDB = $SERVICEHOME/idxinfo.lst | 218 | INDEXDB = $SERVICEHOME/idxinfo.lst |
diff --git a/src/datacache/Makefile.am b/src/datacache/Makefile.am index a10343046..0598c2673 100644 --- a/src/datacache/Makefile.am +++ b/src/datacache/Makefile.am | |||
@@ -14,6 +14,9 @@ endif | |||
14 | if HAVE_SQLITE | 14 | if HAVE_SQLITE |
15 | SQLITE_PLUGIN = libgnunet_plugin_datacache_sqlite.la | 15 | SQLITE_PLUGIN = libgnunet_plugin_datacache_sqlite.la |
16 | endif | 16 | endif |
17 | if HAVE_MYSQL | ||
18 | MYSQL_PLUGIN = libgnunet_plugin_datacache_mysql.la | ||
19 | endif | ||
17 | 20 | ||
18 | lib_LTLIBRARIES = \ | 21 | lib_LTLIBRARIES = \ |
19 | libgnunetdatacache.la | 22 | libgnunetdatacache.la |
@@ -31,6 +34,7 @@ libgnunetdatacache_la_LDFLAGS = \ | |||
31 | 34 | ||
32 | plugin_LTLIBRARIES = \ | 35 | plugin_LTLIBRARIES = \ |
33 | $(SQLITE_PLUGIN) \ | 36 | $(SQLITE_PLUGIN) \ |
37 | $(MYSQL_PLUGIN) \ | ||
34 | libgnunet_plugin_datacache_template.la | 38 | libgnunet_plugin_datacache_template.la |
35 | 39 | ||
36 | 40 | ||
@@ -42,6 +46,17 @@ libgnunet_plugin_datacache_sqlite_la_LIBADD = \ | |||
42 | libgnunet_plugin_datacache_sqlite_la_LDFLAGS = \ | 46 | libgnunet_plugin_datacache_sqlite_la_LDFLAGS = \ |
43 | $(GN_PLUGIN_LDFLAGS) | 47 | $(GN_PLUGIN_LDFLAGS) |
44 | 48 | ||
49 | libgnunet_plugin_datacache_mysql_la_SOURCES = \ | ||
50 | plugin_datacache_mysql.c | ||
51 | libgnunet_plugin_datacache_mysql_la_LIBADD = \ | ||
52 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | ||
53 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
54 | $(GN_PLUGIN_LDFLAGS) $(MYSQL_LDFLAGS) -lmysqlclient | ||
55 | libgnunet_plugin_datacache_mysql_la_CPPFLAGS = \ | ||
56 | $(MYSQL_CPPFLAGS) | ||
57 | libgnunet_plugin_datacache_mysql_la_LDFLAGS = \ | ||
58 | $(GN_PLUGIN_LDFLAGS) $(MYSQL_LDFLAGS) -lmysqlclient | ||
59 | |||
45 | libgnunet_plugin_datacache_template_la_SOURCES = \ | 60 | libgnunet_plugin_datacache_template_la_SOURCES = \ |
46 | plugin_datacache_template.c | 61 | plugin_datacache_template.c |
47 | libgnunet_plugin_datacache_template_la_LIBADD = \ | 62 | libgnunet_plugin_datacache_template_la_LIBADD = \ |
@@ -51,36 +66,65 @@ libgnunet_plugin_datacache_template_la_LDFLAGS = \ | |||
51 | 66 | ||
52 | 67 | ||
53 | if HAVE_SQLITE | 68 | if HAVE_SQLITE |
54 | SQLITE_TESTS = \ | 69 | SQLITE_TESTS = \ |
55 | test_datacache \ | 70 | test_datacache_sqlite \ |
56 | test_datacache_quota \ | 71 | test_datacache_quota_sqlite \ |
57 | perf_datacache | 72 | perf_datacache_sqlite |
58 | endif | 73 | endif |
59 | 74 | ||
60 | check_PROGRAMS = $(SQLITE_TESTS) | 75 | if HAVE_MYSQL |
76 | MYSQL_TESTS = \ | ||
77 | test_datacache_mysql \ | ||
78 | test_datacache_quota_mysql \ | ||
79 | perf_datacache_mysql | ||
80 | endif | ||
81 | |||
82 | check_PROGRAMS = \ | ||
83 | $(SQLITE_TESTS) \ | ||
84 | $(MYSQL_TESTS) | ||
61 | 85 | ||
62 | if !DISABLE_TEST_RUN | 86 | if !DISABLE_TEST_RUN |
63 | TESTS = $(check_PROGRAMS) | 87 | TESTS = $(check_PROGRAMS) |
64 | endif | 88 | endif |
65 | 89 | ||
66 | test_datacache_SOURCES = \ | 90 | test_datacache_sqlite_SOURCES = \ |
91 | test_datacache.c | ||
92 | test_datacache_sqlite_LDADD = \ | ||
93 | $(top_builddir)/src/datacache/libgnunetdatacache.la \ | ||
94 | $(top_builddir)/src/util/libgnunetutil.la | ||
95 | |||
96 | test_datacache_quota_sqlite_SOURCES = \ | ||
97 | test_datacache_quota.c | ||
98 | test_datacache_quota_sqlite_LDADD = \ | ||
99 | $(top_builddir)/src/datacache/libgnunetdatacache.la \ | ||
100 | $(top_builddir)/src/util/libgnunetutil.la | ||
101 | |||
102 | perf_datacache_sqlite_SOURCES = \ | ||
103 | perf_datacache.c | ||
104 | perf_datacache_sqlite_LDADD = \ | ||
105 | $(top_builddir)/src/datacache/libgnunetdatacache.la \ | ||
106 | $(top_builddir)/src/util/libgnunetutil.la | ||
107 | |||
108 | test_datacache_mysql_SOURCES = \ | ||
67 | test_datacache.c | 109 | test_datacache.c |
68 | test_datacache_LDADD = \ | 110 | test_datacache_mysql_LDADD = \ |
69 | $(top_builddir)/src/datacache/libgnunetdatacache.la \ | 111 | $(top_builddir)/src/datacache/libgnunetdatacache.la \ |
70 | $(top_builddir)/src/util/libgnunetutil.la | 112 | $(top_builddir)/src/util/libgnunetutil.la |
71 | 113 | ||
72 | test_datacache_quota_SOURCES = \ | 114 | test_datacache_quota_mysql_SOURCES = \ |
73 | test_datacache_quota.c | 115 | test_datacache_quota.c |
74 | test_datacache_quota_LDADD = \ | 116 | test_datacache_quota_mysql_LDADD = \ |
75 | $(top_builddir)/src/datacache/libgnunetdatacache.la \ | 117 | $(top_builddir)/src/datacache/libgnunetdatacache.la \ |
76 | $(top_builddir)/src/util/libgnunetutil.la | 118 | $(top_builddir)/src/util/libgnunetutil.la |
77 | 119 | ||
78 | perf_datacache_SOURCES = \ | 120 | perf_datacache_mysql_SOURCES = \ |
79 | perf_datacache.c | 121 | perf_datacache.c |
80 | perf_datacache_LDADD = \ | 122 | perf_datacache_mysql_LDADD = \ |
81 | $(top_builddir)/src/datacache/libgnunetdatacache.la \ | 123 | $(top_builddir)/src/datacache/libgnunetdatacache.la \ |
82 | $(top_builddir)/src/util/libgnunetutil.la | 124 | $(top_builddir)/src/util/libgnunetutil.la |
83 | 125 | ||
84 | EXTRA_DIST = \ | 126 | EXTRA_DIST = \ |
85 | test_datacache_data.conf \ | 127 | test_datacache_data_sqlite.conf \ |
86 | perf_datacache_data.conf | 128 | perf_datacache_data_sqlite.conf \ |
129 | test_datacache_data_mysql.conf \ | ||
130 | perf_datacache_data_mysql.conf | ||
diff --git a/src/datacache/perf_datacache.c b/src/datacache/perf_datacache.c index a577927d0..e2eb474d4 100644 --- a/src/datacache/perf_datacache.c +++ b/src/datacache/perf_datacache.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2006, 2009 Christian Grothoff (and other contributing authors) | 3 | (C) 2006, 2009, 2010 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published |
@@ -36,6 +36,12 @@ static int ok; | |||
36 | 36 | ||
37 | static unsigned int found; | 37 | static unsigned int found; |
38 | 38 | ||
39 | /** | ||
40 | * Name of plugin under test. | ||
41 | */ | ||
42 | static const char *plugin_name; | ||
43 | |||
44 | |||
39 | static int | 45 | static int |
40 | checkIt (void *cls, | 46 | checkIt (void *cls, |
41 | struct GNUNET_TIME_Absolute exp, | 47 | struct GNUNET_TIME_Absolute exp, |
@@ -119,12 +125,15 @@ FAILURE: | |||
119 | } | 125 | } |
120 | 126 | ||
121 | 127 | ||
122 | static int | 128 | int |
123 | check () | 129 | main (int argc, char *argv[]) |
124 | { | 130 | { |
125 | char *const argv[] = { "perf-datacache-api", | 131 | const char *pos; |
132 | char cfg_name[128]; | ||
133 | char *const xargv[] = { | ||
134 | "perf-datacache", | ||
126 | "-c", | 135 | "-c", |
127 | "perf_datacache_data.conf", | 136 | cfg_name, |
128 | #if VERBOSE | 137 | #if VERBOSE |
129 | "-L", "DEBUG", | 138 | "-L", "DEBUG", |
130 | #endif | 139 | #endif |
@@ -133,31 +142,28 @@ check () | |||
133 | struct GNUNET_GETOPT_CommandLineOption options[] = { | 142 | struct GNUNET_GETOPT_CommandLineOption options[] = { |
134 | GNUNET_GETOPT_OPTION_END | 143 | GNUNET_GETOPT_OPTION_END |
135 | }; | 144 | }; |
136 | GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, | ||
137 | argv, "perf-datacache-api", "nohelp", | ||
138 | options, &run, NULL); | ||
139 | if (ok != 0) | ||
140 | fprintf (stderr, "Missed some perfcases: %d\n", ok); | ||
141 | return ok; | ||
142 | } | ||
143 | |||
144 | |||
145 | int | ||
146 | main (int argc, char *argv[]) | ||
147 | { | ||
148 | int ret; | ||
149 | 145 | ||
150 | GNUNET_DISK_directory_remove ("/tmp/perf-gnunetd-datacache"); | 146 | GNUNET_log_setup ("perf-datacache", |
151 | GNUNET_log_setup ("perf-datacache-api", | ||
152 | #if VERBOSE | 147 | #if VERBOSE |
153 | "DEBUG", | 148 | "DEBUG", |
154 | #else | 149 | #else |
155 | "WARNING", | 150 | "WARNING", |
156 | #endif | 151 | #endif |
157 | NULL); | 152 | NULL); |
158 | ret = check (); | 153 | /* determine name of plugin to use */ |
159 | 154 | plugin_name = argv[0]; | |
160 | return ret; | 155 | while (NULL != (pos = strstr(plugin_name, "_"))) |
156 | plugin_name = pos+1; | ||
157 | GNUNET_snprintf (cfg_name, | ||
158 | sizeof (cfg_name), | ||
159 | "perf_datacache_data_%s.conf", | ||
160 | plugin_name); | ||
161 | GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, | ||
162 | xargv, "perf-datacache", "nohelp", | ||
163 | options, &run, NULL); | ||
164 | if (ok != 0) | ||
165 | fprintf (stderr, "Missed some perfcases: %d\n", ok); | ||
166 | return ok; | ||
161 | } | 167 | } |
162 | 168 | ||
163 | /* end of perf_datacache.c */ | 169 | /* end of perf_datacache.c */ |
diff --git a/src/datacache/perf_datacache_data_mysql.conf b/src/datacache/perf_datacache_data_mysql.conf new file mode 100644 index 000000000..5a5f97c63 --- /dev/null +++ b/src/datacache/perf_datacache_data_mysql.conf | |||
@@ -0,0 +1,12 @@ | |||
1 | |||
2 | [perfcache] | ||
3 | QUOTA = 500000 | ||
4 | DATABASE = mysql | ||
5 | |||
6 | [datacache-mysql] | ||
7 | DATABASE = gnunetcheck | ||
8 | # CONFIG = ~/.my.cnf | ||
9 | # USER = | ||
10 | # PASSWORD = | ||
11 | # HOST = | ||
12 | # PORT = \ No newline at end of file | ||
diff --git a/src/datacache/perf_datacache_data.conf b/src/datacache/perf_datacache_data_sqlite.conf index 55e178d99..55e178d99 100644 --- a/src/datacache/perf_datacache_data.conf +++ b/src/datacache/perf_datacache_data_sqlite.conf | |||
diff --git a/src/datacache/plugin_datacache_mysql.c b/src/datacache/plugin_datacache_mysql.c new file mode 100644 index 000000000..4559a9d39 --- /dev/null +++ b/src/datacache/plugin_datacache_mysql.c | |||
@@ -0,0 +1,1092 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | (C) 2006, 2009, 2010 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 | /** | ||
22 | * @file datacache/plugin_datacache_mysql.c | ||
23 | * @brief mysql for an implementation of a database backend for the datacache | ||
24 | * @author Christian Grothoff | ||
25 | * | ||
26 | * SETUP INSTRUCTIONS: | ||
27 | * | ||
28 | * 1) Access mysql as root, | ||
29 | * <pre> | ||
30 | * | ||
31 | * $ mysql -u root -p | ||
32 | * | ||
33 | * </pre> | ||
34 | * and do the following. [You should replace $USER with the username | ||
35 | * that will be running the gnunetd process]. | ||
36 | * <pre> | ||
37 | * | ||
38 | CREATE DATABASE gnunet; | ||
39 | GRANT select,insert,update,delete,create,alter,drop,create temporary tables | ||
40 | ON gnunet.* TO $USER@localhost; | ||
41 | SET PASSWORD FOR $USER@localhost=PASSWORD('$the_password_you_like'); | ||
42 | FLUSH PRIVILEGES; | ||
43 | * | ||
44 | * </pre> | ||
45 | * 2) In the $HOME directory of $USER, create a ".my.cnf" file | ||
46 | * with the following lines | ||
47 | * <pre> | ||
48 | |||
49 | [client] | ||
50 | user=$USER | ||
51 | password=$the_password_you_like | ||
52 | |||
53 | * </pre> | ||
54 | * | ||
55 | * Thats it -- now you can configure your datastores in GNUnet to | ||
56 | * use MySQL. Note that .my.cnf file is a security risk unless its on | ||
57 | * a safe partition etc. The $HOME/.my.cnf can of course be a symbolic | ||
58 | * link. Even greater security risk can be achieved by setting no | ||
59 | * password for $USER. Luckily $USER has only priviledges to mess | ||
60 | * up GNUnet's tables, nothing else (unless you give him more, | ||
61 | * of course).<p> | ||
62 | * | ||
63 | * 3) Still, perhaps you should briefly try if the DB connection | ||
64 | * works. First, login as $USER. Then use, | ||
65 | * | ||
66 | * <pre> | ||
67 | * $ mysql -u $USER -p $the_password_you_like | ||
68 | * mysql> use gnunet; | ||
69 | * </pre> | ||
70 | * | ||
71 | * If you get the message "Database changed" it probably works. | ||
72 | * | ||
73 | * [If you get "ERROR 2002: Can't connect to local MySQL server | ||
74 | * through socket '/tmp/mysql.sock' (2)" it may be resolvable by | ||
75 | * "ln -s /var/run/mysqld/mysqld.sock /tmp/mysql.sock" | ||
76 | * so there may be some additional trouble depending on your mysql setup.] | ||
77 | * | ||
78 | * REPAIRING TABLES: | ||
79 | * - Its probably healthy to check your tables for inconsistencies | ||
80 | * every now and then. | ||
81 | * - If you get odd SEGVs on gnunetd startup, it might be that the mysql | ||
82 | * databases have been corrupted. | ||
83 | * - The tables can be verified/fixed in two ways; | ||
84 | * 1) by running mysqlcheck -A, or | ||
85 | * 2) by executing (inside of mysql using the GNUnet database): | ||
86 | * mysql> SHOW TABLES; | ||
87 | * mysql> REPAIR TABLE gnXXX; | ||
88 | * | ||
89 | * Make sure to replace XXX with the actual names of all tables. | ||
90 | * | ||
91 | * PROBLEMS? | ||
92 | * | ||
93 | * If you have problems related to the mysql module, your best | ||
94 | * friend is probably the mysql manual. The first thing to check | ||
95 | * is that mysql is basically operational, that you can connect | ||
96 | * to it, create tables, issue queries etc. | ||
97 | */ | ||
98 | #include "platform.h" | ||
99 | #include "gnunet_util_lib.h" | ||
100 | #include "plugin_datacache.h" | ||
101 | #include <mysql/mysql.h> | ||
102 | |||
103 | #define DEBUG_DATACACHE_MYSQL GNUNET_NO | ||
104 | |||
105 | /** | ||
106 | * Estimate of the per-entry overhead (including indices). | ||
107 | */ | ||
108 | #define OVERHEAD ((4*2+4*2+8*2+8*2+sizeof(GNUNET_HashCode)*5+8)) | ||
109 | |||
110 | /** | ||
111 | * Maximum number of supported parameters for a prepared | ||
112 | * statement. Increase if needed. | ||
113 | */ | ||
114 | #define MAX_PARAM 16 | ||
115 | |||
116 | /** | ||
117 | * Die with an error message that indicates | ||
118 | * a failure of the command 'cmd' with the message given | ||
119 | * by strerror(errno). | ||
120 | */ | ||
121 | #define DIE_MYSQL(cmd, dbh) do { GNUNET_log(GNUNET_ERROR_TYPE__ERROR, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, mysql_error((dbh)->dbf)); abort(); } while(0); | ||
122 | |||
123 | /** | ||
124 | * Log an error message at log-level 'level' that indicates | ||
125 | * a failure of the command 'cmd' on file 'filename' | ||
126 | * with the message given by strerror(errno). | ||
127 | */ | ||
128 | #define LOG_MYSQL(level, cmd, dbh) do { GNUNET_log(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, mysql_error((dbh)->dbf)); } while(0); | ||
129 | |||
130 | struct GNUNET_MysqlStatementHandle | ||
131 | { | ||
132 | struct GNUNET_MysqlStatementHandle *next; | ||
133 | |||
134 | struct GNUNET_MysqlStatementHandle *prev; | ||
135 | |||
136 | char *query; | ||
137 | |||
138 | MYSQL_STMT *statement; | ||
139 | |||
140 | int valid; | ||
141 | |||
142 | }; | ||
143 | |||
144 | |||
145 | /** | ||
146 | * Context for all functions in this plugin. | ||
147 | */ | ||
148 | struct Plugin | ||
149 | { | ||
150 | /** | ||
151 | * Our execution environment. | ||
152 | */ | ||
153 | struct GNUNET_DATACACHE_PluginEnvironment *env; | ||
154 | |||
155 | /** | ||
156 | * Handle to the mysql database. | ||
157 | */ | ||
158 | MYSQL *dbf; | ||
159 | |||
160 | struct GNUNET_MysqlStatementHandle *shead; | ||
161 | |||
162 | struct GNUNET_MysqlStatementHandle *stail; | ||
163 | |||
164 | /** | ||
165 | * Filename of "my.cnf" (msyql configuration). | ||
166 | */ | ||
167 | char *cnffile; | ||
168 | |||
169 | #define SELECT_VALUE_STMT "SELECT value,expire FROM gn080dstore FORCE INDEX (hashidx) WHERE hash=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?" | ||
170 | struct GNUNET_MysqlStatementHandle *select_value; | ||
171 | |||
172 | #define COUNT_VALUE_STMT "SELECT count(*) FROM gn080dstore FORCE INDEX (hashidx) WHERE hash=? AND type=? AND expire >= ?" | ||
173 | struct GNUNET_MysqlStatementHandle *count_value; | ||
174 | |||
175 | #define SELECT_OLD_VALUE_STMT "SELECT hash, vhash, type, value FROM gn080dstore FORCE INDEX (expireidx) ORDER BY puttime ASC LIMIT 1" | ||
176 | struct GNUNET_MysqlStatementHandle *select_old_value; | ||
177 | |||
178 | #define DELETE_VALUE_STMT "DELETE FROM gn080dstore WHERE hash = ? AND vhash = ? AND type = ? AND value = ?" | ||
179 | struct GNUNET_MysqlStatementHandle *delete_value; | ||
180 | |||
181 | #define INSERT_VALUE_STMT "INSERT INTO gn080dstore (type, puttime, expire, hash, vhash, value) "\ | ||
182 | "VALUES (?, ?, ?, ?, ?, ?)" | ||
183 | struct GNUNET_MysqlStatementHandle *insert_value; | ||
184 | |||
185 | #define UPDATE_VALUE_STMT "UPDATE gn080dstore FORCE INDEX (allidx) SET puttime=?, expire=? "\ | ||
186 | "WHERE hash=? AND vhash=? AND type=?" | ||
187 | struct GNUNET_MysqlStatementHandle *update_value; | ||
188 | |||
189 | }; | ||
190 | |||
191 | |||
192 | /** | ||
193 | * Obtain the location of ".my.cnf". | ||
194 | * @return NULL on error | ||
195 | */ | ||
196 | static char * | ||
197 | get_my_cnf_path (const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
198 | { | ||
199 | char *cnffile; | ||
200 | char *home_dir; | ||
201 | struct stat st; | ||
202 | #ifndef WINDOWS | ||
203 | struct passwd *pw; | ||
204 | #endif | ||
205 | int configured; | ||
206 | |||
207 | #ifndef WINDOWS | ||
208 | pw = getpwuid (getuid ()); | ||
209 | if (!pw) | ||
210 | { | ||
211 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, | ||
212 | "getpwuid"); | ||
213 | return NULL; | ||
214 | } | ||
215 | if (GNUNET_YES == | ||
216 | GNUNET_CONFIGURATION_have_value (cfg, | ||
217 | "datacache-mysql", "CONFIG")) | ||
218 | { | ||
219 | GNUNET_assert (GNUNET_OK == | ||
220 | GNUNET_CONFIGURATION_get_value_filename (cfg, | ||
221 | "datacache-mysql", "CONFIG", &cnffile)); | ||
222 | configured = GNUNET_YES; | ||
223 | } | ||
224 | else | ||
225 | { | ||
226 | home_dir = GNUNET_strdup (pw->pw_dir); | ||
227 | #else | ||
228 | home_dir = (char *) GNUNET_malloc (_MAX_PATH + 1); | ||
229 | plibc_conv_to_win_path ("~/", home_dir); | ||
230 | #endif | ||
231 | GNUNET_asprintf (&cnffile, "%s/.my.cnf", home_dir); | ||
232 | GNUNET_free (home_dir); | ||
233 | configured = GNUNET_NO; | ||
234 | } | ||
235 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
236 | _("Trying to use file `%s' for MySQL configuration.\n"), | ||
237 | cnffile); | ||
238 | if ((0 != STAT (cnffile, &st)) || | ||
239 | (0 != ACCESS (cnffile, R_OK)) || (!S_ISREG (st.st_mode))) | ||
240 | { | ||
241 | if (configured == GNUNET_YES) | ||
242 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
243 | _("Could not access file `%s': %s\n"), cnffile, | ||
244 | STRERROR (errno)); | ||
245 | GNUNET_free (cnffile); | ||
246 | return NULL; | ||
247 | } | ||
248 | return cnffile; | ||
249 | } | ||
250 | |||
251 | |||
252 | /** | ||
253 | * Free a prepared statement. | ||
254 | */ | ||
255 | static void | ||
256 | prepared_statement_destroy (struct Plugin *plugin, | ||
257 | struct GNUNET_MysqlStatementHandle | ||
258 | *s) | ||
259 | { | ||
260 | GNUNET_CONTAINER_DLL_remove (plugin->shead, | ||
261 | plugin->stail, | ||
262 | s); | ||
263 | if (s->valid) | ||
264 | mysql_stmt_close (s->statement); | ||
265 | GNUNET_free (s->query); | ||
266 | GNUNET_free (s); | ||
267 | } | ||
268 | |||
269 | |||
270 | /** | ||
271 | * Close database connection and all prepared statements (we got a DB | ||
272 | * disconnect error). | ||
273 | */ | ||
274 | static int | ||
275 | iclose (struct Plugin *plugin) | ||
276 | { | ||
277 | struct GNUNET_MysqlStatementHandle *spos; | ||
278 | |||
279 | spos = plugin->shead; | ||
280 | while (NULL != plugin->shead) | ||
281 | prepared_statement_destroy (plugin, | ||
282 | plugin->shead); | ||
283 | if (plugin->dbf != NULL) | ||
284 | { | ||
285 | mysql_close (plugin->dbf); | ||
286 | plugin->dbf = NULL; | ||
287 | } | ||
288 | return GNUNET_OK; | ||
289 | } | ||
290 | |||
291 | |||
292 | /** | ||
293 | * Open the connection with the database (and initialize | ||
294 | * our default options). | ||
295 | * | ||
296 | * @return GNUNET_OK on success | ||
297 | */ | ||
298 | static int | ||
299 | iopen (struct Plugin *ret) | ||
300 | { | ||
301 | char *mysql_dbname; | ||
302 | char *mysql_server; | ||
303 | char *mysql_user; | ||
304 | char *mysql_password; | ||
305 | unsigned long long mysql_port; | ||
306 | my_bool reconnect; | ||
307 | unsigned int timeout; | ||
308 | |||
309 | ret->dbf = mysql_init (NULL); | ||
310 | if (ret->dbf == NULL) | ||
311 | return GNUNET_SYSERR; | ||
312 | if (ret->cnffile != NULL) | ||
313 | mysql_options (ret->dbf, MYSQL_READ_DEFAULT_FILE, ret->cnffile); | ||
314 | mysql_options (ret->dbf, MYSQL_READ_DEFAULT_GROUP, "client"); | ||
315 | reconnect = 0; | ||
316 | mysql_options (ret->dbf, MYSQL_OPT_RECONNECT, &reconnect); | ||
317 | mysql_options (ret->dbf, | ||
318 | MYSQL_OPT_CONNECT_TIMEOUT, (const void *) &timeout); | ||
319 | mysql_options(ret->dbf, MYSQL_SET_CHARSET_NAME, "UTF8"); | ||
320 | timeout = 60; /* in seconds */ | ||
321 | mysql_options (ret->dbf, MYSQL_OPT_READ_TIMEOUT, (const void *) &timeout); | ||
322 | mysql_options (ret->dbf, MYSQL_OPT_WRITE_TIMEOUT, (const void *) &timeout); | ||
323 | mysql_dbname = NULL; | ||
324 | if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (ret->env->cfg, | ||
325 | "datacache-mysql", "DATABASE")) | ||
326 | GNUNET_assert (GNUNET_OK == | ||
327 | GNUNET_CONFIGURATION_get_value_string (ret->env->cfg, | ||
328 | "datacache-mysql", "DATABASE", | ||
329 | &mysql_dbname)); | ||
330 | else | ||
331 | mysql_dbname = GNUNET_strdup ("gnunet"); | ||
332 | mysql_user = NULL; | ||
333 | if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (ret->env->cfg, | ||
334 | "datacache-mysql", "USER")) | ||
335 | { | ||
336 | GNUNET_assert (GNUNET_OK == | ||
337 | GNUNET_CONFIGURATION_get_value_string (ret->env->cfg, | ||
338 | "datacache-mysql", "USER", | ||
339 | &mysql_user)); | ||
340 | } | ||
341 | mysql_password = NULL; | ||
342 | if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (ret->env->cfg, | ||
343 | "datacache-mysql", "PASSWORD")) | ||
344 | { | ||
345 | GNUNET_assert (GNUNET_OK == | ||
346 | GNUNET_CONFIGURATION_get_value_string (ret->env->cfg, | ||
347 | "datacache-mysql", "PASSWORD", | ||
348 | &mysql_password)); | ||
349 | } | ||
350 | mysql_server = NULL; | ||
351 | if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (ret->env->cfg, | ||
352 | "datacache-mysql", "HOST")) | ||
353 | { | ||
354 | GNUNET_assert (GNUNET_OK == | ||
355 | GNUNET_CONFIGURATION_get_value_string (ret->env->cfg, | ||
356 | "datacache-mysql", "HOST", | ||
357 | &mysql_server)); | ||
358 | } | ||
359 | mysql_port = 0; | ||
360 | if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (ret->env->cfg, | ||
361 | "datacache-mysql", "PORT")) | ||
362 | { | ||
363 | GNUNET_assert (GNUNET_OK == | ||
364 | GNUNET_CONFIGURATION_get_value_number (ret->env->cfg, "datacache-mysql", | ||
365 | "PORT", &mysql_port)); | ||
366 | } | ||
367 | |||
368 | GNUNET_assert (mysql_dbname != NULL); | ||
369 | mysql_real_connect (ret->dbf, mysql_server, mysql_user, mysql_password, | ||
370 | mysql_dbname, (unsigned int) mysql_port, NULL, | ||
371 | CLIENT_IGNORE_SIGPIPE); | ||
372 | GNUNET_free_non_null (mysql_server); | ||
373 | GNUNET_free_non_null (mysql_user); | ||
374 | GNUNET_free_non_null (mysql_password); | ||
375 | GNUNET_free (mysql_dbname); | ||
376 | if (mysql_error (ret->dbf)[0]) | ||
377 | { | ||
378 | LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, | ||
379 | "mysql_real_connect", ret); | ||
380 | return GNUNET_SYSERR; | ||
381 | } | ||
382 | return GNUNET_OK; | ||
383 | } | ||
384 | |||
385 | |||
386 | /** | ||
387 | * Run the given MySQL statement. | ||
388 | * | ||
389 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | ||
390 | */ | ||
391 | static int | ||
392 | run_statement (struct Plugin *plugin, | ||
393 | const char *statement) | ||
394 | { | ||
395 | if ((NULL == plugin->dbf) && (GNUNET_OK != iopen (plugin))) | ||
396 | return GNUNET_SYSERR; | ||
397 | mysql_query (plugin->dbf, statement); | ||
398 | if (mysql_error (plugin->dbf)[0]) | ||
399 | { | ||
400 | LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, | ||
401 | "mysql_query", plugin); | ||
402 | iclose (plugin); | ||
403 | return GNUNET_SYSERR; | ||
404 | } | ||
405 | return GNUNET_OK; | ||
406 | } | ||
407 | |||
408 | /** | ||
409 | * Create a prepared statement. | ||
410 | * | ||
411 | * @return NULL on error | ||
412 | */ | ||
413 | static struct GNUNET_MysqlStatementHandle * | ||
414 | prepared_statement_create (struct Plugin *plugin, | ||
415 | const char *statement) | ||
416 | { | ||
417 | struct GNUNET_MysqlStatementHandle *ret; | ||
418 | |||
419 | ret = GNUNET_malloc (sizeof (struct GNUNET_MysqlStatementHandle)); | ||
420 | ret->query = GNUNET_strdup (statement); | ||
421 | GNUNET_CONTAINER_DLL_insert (plugin->shead, | ||
422 | plugin->stail, | ||
423 | ret); | ||
424 | return ret; | ||
425 | } | ||
426 | |||
427 | |||
428 | /** | ||
429 | * Prepare a statement for running. | ||
430 | * | ||
431 | * @return GNUNET_OK on success | ||
432 | */ | ||
433 | static int | ||
434 | prepare_statement (struct Plugin *plugin, | ||
435 | struct GNUNET_MysqlStatementHandle *ret) | ||
436 | { | ||
437 | if (GNUNET_YES == ret->valid) | ||
438 | return GNUNET_OK; | ||
439 | if ((NULL == plugin->dbf) && | ||
440 | (GNUNET_OK != iopen (plugin))) | ||
441 | return GNUNET_SYSERR; | ||
442 | ret->statement = mysql_stmt_init (plugin->dbf); | ||
443 | if (ret->statement == NULL) | ||
444 | { | ||
445 | iclose (plugin); | ||
446 | return GNUNET_SYSERR; | ||
447 | } | ||
448 | if (mysql_stmt_prepare (ret->statement, | ||
449 | ret->query, | ||
450 | strlen (ret->query))) | ||
451 | { | ||
452 | LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, | ||
453 | "mysql_stmt_prepare", | ||
454 | plugin); | ||
455 | mysql_stmt_close (ret->statement); | ||
456 | ret->statement = NULL; | ||
457 | iclose (plugin); | ||
458 | return GNUNET_SYSERR; | ||
459 | } | ||
460 | ret->valid = GNUNET_YES; | ||
461 | return GNUNET_OK; | ||
462 | |||
463 | } | ||
464 | |||
465 | |||
466 | /** | ||
467 | * Bind the parameters for the given MySQL statement | ||
468 | * and run it. | ||
469 | * | ||
470 | * @param s statement to bind and run | ||
471 | * @param ap arguments for the binding | ||
472 | * @return GNUNET_SYSERR on error, GNUNET_OK on success | ||
473 | */ | ||
474 | static int | ||
475 | init_params (struct Plugin *plugin, | ||
476 | struct GNUNET_MysqlStatementHandle *s, | ||
477 | va_list ap) | ||
478 | { | ||
479 | MYSQL_BIND qbind[MAX_PARAM]; | ||
480 | unsigned int pc; | ||
481 | unsigned int off; | ||
482 | enum enum_field_types ft; | ||
483 | |||
484 | pc = mysql_stmt_param_count (s->statement); | ||
485 | if (pc > MAX_PARAM) | ||
486 | { | ||
487 | /* increase internal constant! */ | ||
488 | GNUNET_break (0); | ||
489 | return GNUNET_SYSERR; | ||
490 | } | ||
491 | memset (qbind, 0, sizeof (qbind)); | ||
492 | off = 0; | ||
493 | ft = 0; | ||
494 | while ((pc > 0) && (-1 != (ft = va_arg (ap, enum enum_field_types)))) | ||
495 | { | ||
496 | qbind[off].buffer_type = ft; | ||
497 | switch (ft) | ||
498 | { | ||
499 | case MYSQL_TYPE_FLOAT: | ||
500 | qbind[off].buffer = va_arg (ap, float *); | ||
501 | break; | ||
502 | case MYSQL_TYPE_LONGLONG: | ||
503 | qbind[off].buffer = va_arg (ap, unsigned long long *); | ||
504 | qbind[off].is_unsigned = va_arg (ap, int); | ||
505 | break; | ||
506 | case MYSQL_TYPE_LONG: | ||
507 | qbind[off].buffer = va_arg (ap, unsigned int *); | ||
508 | qbind[off].is_unsigned = va_arg (ap, int); | ||
509 | break; | ||
510 | case MYSQL_TYPE_VAR_STRING: | ||
511 | case MYSQL_TYPE_STRING: | ||
512 | case MYSQL_TYPE_BLOB: | ||
513 | qbind[off].buffer = va_arg (ap, void *); | ||
514 | qbind[off].buffer_length = va_arg (ap, unsigned long); | ||
515 | qbind[off].length = va_arg (ap, unsigned long *); | ||
516 | break; | ||
517 | default: | ||
518 | /* unsupported type */ | ||
519 | GNUNET_break (0); | ||
520 | return GNUNET_SYSERR; | ||
521 | } | ||
522 | pc--; | ||
523 | off++; | ||
524 | } | ||
525 | if (!((pc == 0) && (ft != -1) && (va_arg (ap, int) == -1))) | ||
526 | { | ||
527 | GNUNET_break (0); | ||
528 | return GNUNET_SYSERR; | ||
529 | } | ||
530 | if (mysql_stmt_bind_param (s->statement, qbind)) | ||
531 | { | ||
532 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
533 | _("`%s' failed at %s:%d with error: %s\n"), | ||
534 | "mysql_stmt_bind_param", | ||
535 | __FILE__, __LINE__, mysql_stmt_error (s->statement)); | ||
536 | iclose (plugin); | ||
537 | return GNUNET_SYSERR; | ||
538 | } | ||
539 | if (mysql_stmt_execute (s->statement)) | ||
540 | { | ||
541 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
542 | _("`%s' failed at %s:%d with error: %s\n"), | ||
543 | "mysql_stmt_execute", | ||
544 | __FILE__, __LINE__, mysql_stmt_error (s->statement)); | ||
545 | iclose (plugin); | ||
546 | return GNUNET_SYSERR; | ||
547 | } | ||
548 | return GNUNET_OK; | ||
549 | } | ||
550 | |||
551 | /** | ||
552 | * Type of a callback that will be called for each | ||
553 | * data set returned from MySQL. | ||
554 | * | ||
555 | * @param cls user-defined argument | ||
556 | * @param num_values number of elements in values | ||
557 | * @param values values returned by MySQL | ||
558 | * @return GNUNET_OK to continue iterating, GNUNET_SYSERR to abort | ||
559 | */ | ||
560 | typedef int (*GNUNET_MysqlDataProcessor) (void *cls, | ||
561 | unsigned int num_values, | ||
562 | MYSQL_BIND * values); | ||
563 | |||
564 | |||
565 | /** | ||
566 | * Run a prepared SELECT statement. | ||
567 | * | ||
568 | * @param result_size number of elements in results array | ||
569 | * @param results pointer to already initialized MYSQL_BIND | ||
570 | * array (of sufficient size) for passing results | ||
571 | * @param processor function to call on each result | ||
572 | * @param processor_cls extra argument to processor | ||
573 | * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective | ||
574 | * values (size + buffer-reference for pointers); terminated | ||
575 | * with "-1" | ||
576 | * @return GNUNET_SYSERR on error, otherwise | ||
577 | * the number of successfully affected (or queried) rows | ||
578 | */ | ||
579 | static int | ||
580 | prepared_statement_run_select (struct Plugin *plugin, | ||
581 | struct GNUNET_MysqlStatementHandle | ||
582 | *s, | ||
583 | unsigned int result_size, | ||
584 | MYSQL_BIND * results, | ||
585 | GNUNET_MysqlDataProcessor | ||
586 | processor, void *processor_cls, | ||
587 | ...) | ||
588 | { | ||
589 | va_list ap; | ||
590 | int ret; | ||
591 | unsigned int rsize; | ||
592 | int total; | ||
593 | |||
594 | if (GNUNET_OK != prepare_statement (plugin, s)) | ||
595 | { | ||
596 | GNUNET_break (0); | ||
597 | return GNUNET_SYSERR; | ||
598 | } | ||
599 | va_start (ap, processor_cls); | ||
600 | if (GNUNET_OK != init_params (plugin, s, ap)) | ||
601 | { | ||
602 | GNUNET_break (0); | ||
603 | va_end (ap); | ||
604 | return GNUNET_SYSERR; | ||
605 | } | ||
606 | va_end (ap); | ||
607 | rsize = mysql_stmt_field_count (s->statement); | ||
608 | if (rsize > result_size) | ||
609 | { | ||
610 | GNUNET_break (0); | ||
611 | return GNUNET_SYSERR; | ||
612 | } | ||
613 | if (mysql_stmt_bind_result (s->statement, results)) | ||
614 | { | ||
615 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
616 | _("`%s' failed at %s:%d with error: %s\n"), | ||
617 | "mysql_stmt_bind_result", | ||
618 | __FILE__, __LINE__, mysql_stmt_error (s->statement)); | ||
619 | iclose (plugin); | ||
620 | return GNUNET_SYSERR; | ||
621 | } | ||
622 | |||
623 | total = 0; | ||
624 | while (1) | ||
625 | { | ||
626 | ret = mysql_stmt_fetch (s->statement); | ||
627 | if (ret == MYSQL_NO_DATA) | ||
628 | break; | ||
629 | if (ret != 0) | ||
630 | { | ||
631 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
632 | _("`%s' failed at %s:%d with error: %s\n"), | ||
633 | "mysql_stmt_fetch", | ||
634 | __FILE__, __LINE__, mysql_stmt_error (s->statement)); | ||
635 | iclose (plugin); | ||
636 | return GNUNET_SYSERR; | ||
637 | } | ||
638 | if (processor != NULL) | ||
639 | if (GNUNET_OK != processor (processor_cls, rsize, results)) | ||
640 | break; | ||
641 | total++; | ||
642 | } | ||
643 | mysql_stmt_reset (s->statement); | ||
644 | return total; | ||
645 | } | ||
646 | |||
647 | |||
648 | |||
649 | /** | ||
650 | * Run a prepared statement that does NOT produce results. | ||
651 | * | ||
652 | * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective | ||
653 | * values (size + buffer-reference for pointers); terminated | ||
654 | * with "-1" | ||
655 | * @param insert_id NULL or address where to store the row ID of whatever | ||
656 | * was inserted (only for INSERT statements!) | ||
657 | * @return GNUNET_SYSERR on error, otherwise | ||
658 | * the number of successfully affected rows | ||
659 | */ | ||
660 | static int | ||
661 | prepared_statement_run (struct Plugin *plugin, | ||
662 | struct GNUNET_MysqlStatementHandle *s, | ||
663 | unsigned long long *insert_id, ...) | ||
664 | { | ||
665 | va_list ap; | ||
666 | int affected; | ||
667 | |||
668 | if (GNUNET_OK != prepare_statement (plugin, s)) | ||
669 | return GNUNET_SYSERR; | ||
670 | va_start (ap, insert_id); | ||
671 | if (GNUNET_OK != init_params (plugin, s, ap)) | ||
672 | { | ||
673 | va_end (ap); | ||
674 | return GNUNET_SYSERR; | ||
675 | } | ||
676 | va_end (ap); | ||
677 | affected = mysql_stmt_affected_rows (s->statement); | ||
678 | if (NULL != insert_id) | ||
679 | *insert_id = (unsigned long long) mysql_stmt_insert_id (s->statement); | ||
680 | mysql_stmt_reset (s->statement); | ||
681 | return affected; | ||
682 | } | ||
683 | |||
684 | |||
685 | static int | ||
686 | itable (struct Plugin *plugin) | ||
687 | { | ||
688 | #define MRUNS(a) (GNUNET_OK != run_statement (plugin, a) ) | ||
689 | if (MRUNS ("CREATE TEMPORARY TABLE gn080dstore (" | ||
690 | " type INT(11) UNSIGNED NOT NULL DEFAULT 0," | ||
691 | " puttime BIGINT UNSIGNED NOT NULL DEFAULT 0," | ||
692 | " expire BIGINT UNSIGNED NOT NULL DEFAULT 0," | ||
693 | " hash BINARY(64) NOT NULL DEFAULT ''," | ||
694 | " vhash BINARY(64) NOT NULL DEFAULT ''," | ||
695 | " value BLOB NOT NULL DEFAULT ''," | ||
696 | " INDEX hashidx (hash(64),type,expire)," | ||
697 | " INDEX allidx (hash(64),vhash(64),type)," | ||
698 | " INDEX expireidx (puttime)" ") ENGINE=InnoDB") || | ||
699 | MRUNS ("SET AUTOCOMMIT = 1")) | ||
700 | return GNUNET_SYSERR; | ||
701 | #undef MRUNS | ||
702 | #define PINIT(a,b) (NULL == (a = prepared_statement_create(plugin, b))) | ||
703 | if (PINIT (plugin->select_value, SELECT_VALUE_STMT) || | ||
704 | PINIT (plugin->count_value, COUNT_VALUE_STMT) || | ||
705 | PINIT (plugin->select_old_value, SELECT_OLD_VALUE_STMT) || | ||
706 | PINIT (plugin->delete_value, DELETE_VALUE_STMT) || | ||
707 | PINIT (plugin->insert_value, INSERT_VALUE_STMT) || | ||
708 | PINIT (plugin->update_value, UPDATE_VALUE_STMT)) | ||
709 | return GNUNET_SYSERR; | ||
710 | #undef PINIT | ||
711 | return GNUNET_OK; | ||
712 | } | ||
713 | |||
714 | |||
715 | /** | ||
716 | * Store an item in the datastore. | ||
717 | * | ||
718 | * @param cls closure (our "struct Plugin") | ||
719 | * @param key key to store data under | ||
720 | * @param size number of bytes in data | ||
721 | * @param data data to store | ||
722 | * @param type type of the value | ||
723 | * @param discard_time when to discard the value in any case | ||
724 | * @return 0 on error, number of bytes used otherwise | ||
725 | */ | ||
726 | static uint32_t | ||
727 | mysql_plugin_put (void *cls, | ||
728 | const GNUNET_HashCode * key, | ||
729 | uint32_t size, | ||
730 | const char *data, | ||
731 | enum GNUNET_BLOCK_Type type, | ||
732 | struct GNUNET_TIME_Absolute discard_time) | ||
733 | { | ||
734 | struct Plugin *plugin = cls; | ||
735 | struct GNUNET_TIME_Absolute now; | ||
736 | unsigned long k_length; | ||
737 | unsigned long h_length; | ||
738 | unsigned long v_length; | ||
739 | unsigned long long v_now; | ||
740 | unsigned long long v_discard_time; | ||
741 | unsigned int v_type; | ||
742 | GNUNET_HashCode vhash; | ||
743 | int ret; | ||
744 | |||
745 | if (size > GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
746 | return GNUNET_SYSERR; | ||
747 | GNUNET_CRYPTO_hash (data, size, &vhash); | ||
748 | now = GNUNET_TIME_absolute_get (); | ||
749 | |||
750 | /* first try UPDATE */ | ||
751 | h_length = sizeof (GNUNET_HashCode); | ||
752 | k_length = sizeof (GNUNET_HashCode); | ||
753 | v_length = size; | ||
754 | v_type = type; | ||
755 | v_now = (unsigned long long) now.value; | ||
756 | v_discard_time = (unsigned long long) discard_time.value; | ||
757 | if (GNUNET_OK == | ||
758 | prepared_statement_run (plugin, | ||
759 | plugin->update_value, | ||
760 | NULL, | ||
761 | MYSQL_TYPE_LONGLONG, | ||
762 | &v_now, | ||
763 | GNUNET_YES, | ||
764 | MYSQL_TYPE_LONGLONG, | ||
765 | &v_discard_time, | ||
766 | GNUNET_YES, | ||
767 | MYSQL_TYPE_BLOB, | ||
768 | key, | ||
769 | sizeof (GNUNET_HashCode), | ||
770 | &k_length, | ||
771 | MYSQL_TYPE_BLOB, | ||
772 | &vhash, | ||
773 | sizeof (GNUNET_HashCode), | ||
774 | &h_length, | ||
775 | MYSQL_TYPE_LONG, | ||
776 | &v_type, | ||
777 | GNUNET_YES, -1)) | ||
778 | return GNUNET_OK; | ||
779 | |||
780 | /* now try INSERT */ | ||
781 | h_length = sizeof (GNUNET_HashCode); | ||
782 | k_length = sizeof (GNUNET_HashCode); | ||
783 | v_length = size; | ||
784 | if (GNUNET_OK != | ||
785 | (ret = prepared_statement_run (plugin, | ||
786 | plugin->insert_value, | ||
787 | NULL, | ||
788 | MYSQL_TYPE_LONG, | ||
789 | &type, | ||
790 | GNUNET_YES, | ||
791 | MYSQL_TYPE_LONGLONG, | ||
792 | &v_now, | ||
793 | GNUNET_YES, | ||
794 | MYSQL_TYPE_LONGLONG, | ||
795 | &v_discard_time, | ||
796 | GNUNET_YES, | ||
797 | MYSQL_TYPE_BLOB, | ||
798 | key, | ||
799 | sizeof (GNUNET_HashCode), | ||
800 | &k_length, | ||
801 | MYSQL_TYPE_BLOB, | ||
802 | &vhash, | ||
803 | sizeof (GNUNET_HashCode), | ||
804 | &h_length, | ||
805 | MYSQL_TYPE_BLOB, | ||
806 | data, | ||
807 | (unsigned long) size, | ||
808 | &v_length, -1))) | ||
809 | { | ||
810 | if (ret == GNUNET_SYSERR) | ||
811 | itable (plugin); | ||
812 | return GNUNET_SYSERR; | ||
813 | } | ||
814 | return size + OVERHEAD; | ||
815 | } | ||
816 | |||
817 | |||
818 | static int | ||
819 | return_ok (void *cls, unsigned int num_values, MYSQL_BIND * values) | ||
820 | { | ||
821 | return GNUNET_OK; | ||
822 | } | ||
823 | |||
824 | |||
825 | /** | ||
826 | * Iterate over the results for a particular key | ||
827 | * in the datastore. | ||
828 | * | ||
829 | * @param cls closure (our "struct Plugin") | ||
830 | * @param key | ||
831 | * @param type entries of which type are relevant? | ||
832 | * @param iter maybe NULL (to just count) | ||
833 | * @param iter_cls closure for iter | ||
834 | * @return the number of results found | ||
835 | */ | ||
836 | static unsigned int | ||
837 | mysql_plugin_get (void *cls, | ||
838 | const GNUNET_HashCode * key, | ||
839 | enum GNUNET_BLOCK_Type type, | ||
840 | GNUNET_DATACACHE_Iterator iter, | ||
841 | void *iter_cls) | ||
842 | { | ||
843 | struct Plugin *plugin = cls; | ||
844 | MYSQL_BIND rbind[3]; | ||
845 | unsigned long h_length; | ||
846 | unsigned long v_length; | ||
847 | unsigned long long v_expire; | ||
848 | struct GNUNET_TIME_Absolute now; | ||
849 | struct GNUNET_TIME_Absolute expire; | ||
850 | unsigned int cnt; | ||
851 | unsigned long long total; | ||
852 | unsigned long long v_now; | ||
853 | unsigned int off; | ||
854 | unsigned int v_type; | ||
855 | int ret; | ||
856 | char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE]; | ||
857 | |||
858 | now = GNUNET_TIME_absolute_get (); | ||
859 | h_length = sizeof (GNUNET_HashCode); | ||
860 | v_length = sizeof (buffer); | ||
861 | total = -1; | ||
862 | memset (rbind, 0, sizeof (rbind)); | ||
863 | rbind[0].buffer_type = MYSQL_TYPE_LONGLONG; | ||
864 | rbind[0].buffer = &total; | ||
865 | rbind[0].is_unsigned = GNUNET_YES; | ||
866 | v_type = type; | ||
867 | v_now = (unsigned long long) now.value; | ||
868 | if ((GNUNET_OK != | ||
869 | (ret = prepared_statement_run_select (plugin, | ||
870 | plugin->count_value, | ||
871 | 1, | ||
872 | rbind, | ||
873 | return_ok, | ||
874 | NULL, | ||
875 | MYSQL_TYPE_BLOB, | ||
876 | key, | ||
877 | sizeof | ||
878 | (GNUNET_HashCode), | ||
879 | &h_length, | ||
880 | MYSQL_TYPE_LONG, | ||
881 | &v_type, GNUNET_YES, | ||
882 | MYSQL_TYPE_LONGLONG, | ||
883 | &v_now, GNUNET_YES, | ||
884 | -1))) | ||
885 | || (-1 == total)) | ||
886 | { | ||
887 | if (ret == GNUNET_SYSERR) | ||
888 | itable (plugin); | ||
889 | return GNUNET_SYSERR; | ||
890 | } | ||
891 | if ((iter == NULL) || (total == 0)) | ||
892 | return (int) total; | ||
893 | |||
894 | off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, total); | ||
895 | cnt = 0; | ||
896 | while (cnt < total) | ||
897 | { | ||
898 | memset (rbind, 0, sizeof (rbind)); | ||
899 | rbind[0].buffer_type = MYSQL_TYPE_BLOB; | ||
900 | rbind[0].buffer_length = sizeof (buffer); | ||
901 | rbind[0].length = &v_length; | ||
902 | rbind[0].buffer = buffer; | ||
903 | rbind[1].buffer_type = MYSQL_TYPE_LONGLONG; | ||
904 | rbind[1].is_unsigned = 1; | ||
905 | rbind[1].buffer = &v_expire; | ||
906 | off = (off + 1) % total; | ||
907 | if (GNUNET_OK != | ||
908 | (ret = prepared_statement_run_select (plugin, | ||
909 | plugin->select_value, | ||
910 | 2, | ||
911 | rbind, | ||
912 | return_ok, | ||
913 | NULL, | ||
914 | MYSQL_TYPE_BLOB, | ||
915 | key, | ||
916 | sizeof | ||
917 | (GNUNET_HashCode), | ||
918 | &h_length, | ||
919 | MYSQL_TYPE_LONG, | ||
920 | &v_type, | ||
921 | GNUNET_YES, | ||
922 | MYSQL_TYPE_LONGLONG, | ||
923 | &v_now, | ||
924 | GNUNET_YES, | ||
925 | MYSQL_TYPE_LONG, | ||
926 | &off, | ||
927 | GNUNET_YES, | ||
928 | -1))) | ||
929 | { | ||
930 | if (ret == GNUNET_SYSERR) | ||
931 | itable (plugin); | ||
932 | return GNUNET_SYSERR; | ||
933 | } | ||
934 | cnt++; | ||
935 | expire.value = v_expire; | ||
936 | if (GNUNET_OK != iter (iter_cls, | ||
937 | expire, | ||
938 | key, | ||
939 | v_length, buffer, | ||
940 | type)) | ||
941 | break; | ||
942 | } | ||
943 | return cnt; | ||
944 | } | ||
945 | |||
946 | |||
947 | /** | ||
948 | * Delete the entry with the lowest expiration value | ||
949 | * from the datacache right now. | ||
950 | * | ||
951 | * @param cls closure (our "struct Plugin") | ||
952 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | ||
953 | */ | ||
954 | static int | ||
955 | mysql_plugin_del (void *cls) | ||
956 | { | ||
957 | struct Plugin *plugin = cls; | ||
958 | |||
959 | MYSQL_BIND rbind[5]; | ||
960 | unsigned int v_type; | ||
961 | GNUNET_HashCode v_key; | ||
962 | GNUNET_HashCode vhash; | ||
963 | unsigned long k_length; | ||
964 | unsigned long h_length; | ||
965 | unsigned long v_length; | ||
966 | int ret; | ||
967 | char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE]; | ||
968 | |||
969 | k_length = sizeof (GNUNET_HashCode); | ||
970 | h_length = sizeof (GNUNET_HashCode); | ||
971 | v_length = sizeof (buffer); | ||
972 | memset (rbind, 0, sizeof (rbind)); | ||
973 | rbind[0].buffer_type = MYSQL_TYPE_BLOB; | ||
974 | rbind[0].buffer_length = sizeof (GNUNET_HashCode); | ||
975 | rbind[0].length = &k_length; | ||
976 | rbind[0].buffer = &v_key; | ||
977 | rbind[1].buffer_type = MYSQL_TYPE_BLOB; | ||
978 | rbind[1].buffer_length = sizeof (GNUNET_HashCode); | ||
979 | rbind[1].length = &h_length; | ||
980 | rbind[1].buffer = &vhash; | ||
981 | rbind[2].buffer_type = MYSQL_TYPE_LONG; | ||
982 | rbind[2].is_unsigned = 1; | ||
983 | rbind[2].buffer = &v_type; | ||
984 | rbind[3].buffer_type = MYSQL_TYPE_BLOB; | ||
985 | rbind[3].buffer_length = sizeof (buffer); | ||
986 | rbind[3].length = &v_length; | ||
987 | rbind[3].buffer = buffer; | ||
988 | if ((GNUNET_OK != | ||
989 | (ret = prepared_statement_run_select (plugin, | ||
990 | plugin->select_old_value, | ||
991 | 4, | ||
992 | rbind, | ||
993 | return_ok, | ||
994 | NULL, | ||
995 | -1))) || | ||
996 | (GNUNET_OK != | ||
997 | (ret = prepared_statement_run (plugin, | ||
998 | plugin->delete_value, | ||
999 | NULL, | ||
1000 | MYSQL_TYPE_BLOB, | ||
1001 | &v_key, | ||
1002 | sizeof (GNUNET_HashCode), | ||
1003 | &k_length, | ||
1004 | MYSQL_TYPE_BLOB, | ||
1005 | &vhash, | ||
1006 | sizeof (GNUNET_HashCode), | ||
1007 | &h_length, | ||
1008 | MYSQL_TYPE_LONG, | ||
1009 | &v_type, | ||
1010 | GNUNET_YES, | ||
1011 | MYSQL_TYPE_BLOB, | ||
1012 | buffer, | ||
1013 | (unsigned long) | ||
1014 | sizeof (buffer), | ||
1015 | &v_length, -1)))) | ||
1016 | { | ||
1017 | if (ret == GNUNET_SYSERR) | ||
1018 | itable (plugin); | ||
1019 | return GNUNET_SYSERR; | ||
1020 | } | ||
1021 | plugin->env->delete_notify (plugin->env->cls, | ||
1022 | &v_key, | ||
1023 | v_length + OVERHEAD); | ||
1024 | |||
1025 | return GNUNET_OK; | ||
1026 | } | ||
1027 | |||
1028 | |||
1029 | /** | ||
1030 | * Entry point for the plugin. | ||
1031 | * | ||
1032 | * @param cls closure (the "struct GNUNET_DATACACHE_PluginEnvironmnet") | ||
1033 | * @return the plugin's closure (our "struct Plugin") | ||
1034 | */ | ||
1035 | void * | ||
1036 | libgnunet_plugin_datacache_mysql_init (void *cls) | ||
1037 | { | ||
1038 | struct GNUNET_DATACACHE_PluginEnvironment *env = cls; | ||
1039 | struct GNUNET_DATACACHE_PluginFunctions *api; | ||
1040 | struct Plugin *plugin; | ||
1041 | |||
1042 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | ||
1043 | plugin->env = env; | ||
1044 | plugin->cnffile = get_my_cnf_path (env->cfg); | ||
1045 | if (GNUNET_OK != | ||
1046 | iopen (plugin)) | ||
1047 | { | ||
1048 | GNUNET_free_non_null (plugin->cnffile); | ||
1049 | GNUNET_free (plugin); | ||
1050 | return NULL; | ||
1051 | } | ||
1052 | if (GNUNET_OK != | ||
1053 | itable (plugin)) | ||
1054 | { | ||
1055 | iclose (plugin); | ||
1056 | GNUNET_free_non_null (plugin->cnffile); | ||
1057 | GNUNET_free (plugin); | ||
1058 | return NULL; | ||
1059 | } | ||
1060 | api = GNUNET_malloc (sizeof (struct GNUNET_DATACACHE_PluginFunctions)); | ||
1061 | api->cls = plugin; | ||
1062 | api->get = &mysql_plugin_get; | ||
1063 | api->put = &mysql_plugin_put; | ||
1064 | api->del = &mysql_plugin_del; | ||
1065 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, | ||
1066 | "mysql", _("MySQL datacache running\n")); | ||
1067 | return api; | ||
1068 | } | ||
1069 | |||
1070 | |||
1071 | /** | ||
1072 | * Exit point from the plugin. | ||
1073 | * | ||
1074 | * @param cls closure (our "struct Plugin") | ||
1075 | * @return NULL | ||
1076 | */ | ||
1077 | void * | ||
1078 | libgnunet_plugin_datacache_mysql_done (void *cls) | ||
1079 | { | ||
1080 | struct GNUNET_DATACACHE_PluginFunctions *api = cls; | ||
1081 | struct Plugin *plugin = api->cls; | ||
1082 | |||
1083 | iclose (plugin); | ||
1084 | GNUNET_free_non_null (plugin->cnffile); | ||
1085 | GNUNET_free (plugin); | ||
1086 | GNUNET_free (api); | ||
1087 | mysql_library_end (); | ||
1088 | return NULL; | ||
1089 | } | ||
1090 | |||
1091 | |||
1092 | /* end of plugin_datacache_mysql.c */ | ||
diff --git a/src/datacache/test_datacache.c b/src/datacache/test_datacache.c index 8e09a7692..c5acf365a 100644 --- a/src/datacache/test_datacache.c +++ b/src/datacache/test_datacache.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2006, 2009 Christian Grothoff (and other contributing authors) | 3 | (C) 2006, 2009, 2010 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published |
@@ -32,6 +32,11 @@ | |||
32 | 32 | ||
33 | static int ok; | 33 | static int ok; |
34 | 34 | ||
35 | /** | ||
36 | * Name of plugin under test. | ||
37 | */ | ||
38 | static const char *plugin_name; | ||
39 | |||
35 | 40 | ||
36 | static int | 41 | static int |
37 | checkIt (void *cls, | 42 | checkIt (void *cls, |
@@ -120,12 +125,15 @@ FAILURE: | |||
120 | } | 125 | } |
121 | 126 | ||
122 | 127 | ||
123 | static int | 128 | int |
124 | check () | 129 | main (int argc, char *argv[]) |
125 | { | 130 | { |
126 | char *const argv[] = { "test-datacache-api", | 131 | const char *pos; |
132 | char cfg_name[128]; | ||
133 | char *const xargv[] = { | ||
134 | "test-datacache", | ||
127 | "-c", | 135 | "-c", |
128 | "test_datacache_data.conf", | 136 | cfg_name, |
129 | #if VERBOSE | 137 | #if VERBOSE |
130 | "-L", "DEBUG", | 138 | "-L", "DEBUG", |
131 | #endif | 139 | #endif |
@@ -134,30 +142,28 @@ check () | |||
134 | struct GNUNET_GETOPT_CommandLineOption options[] = { | 142 | struct GNUNET_GETOPT_CommandLineOption options[] = { |
135 | GNUNET_GETOPT_OPTION_END | 143 | GNUNET_GETOPT_OPTION_END |
136 | }; | 144 | }; |
137 | GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, | ||
138 | argv, "test-datacache-api", "nohelp", | ||
139 | options, &run, NULL); | ||
140 | if (ok != 0) | ||
141 | fprintf (stderr, "Missed some testcases: %d\n", ok); | ||
142 | return ok; | ||
143 | } | ||
144 | 145 | ||
145 | 146 | GNUNET_log_setup ("test-datacache", | |
146 | int | ||
147 | main (int argc, char *argv[]) | ||
148 | { | ||
149 | int ret; | ||
150 | |||
151 | GNUNET_log_setup ("test-datacache-api", | ||
152 | #if VERBOSE | 147 | #if VERBOSE |
153 | "DEBUG", | 148 | "DEBUG", |
154 | #else | 149 | #else |
155 | "WARNING", | 150 | "WARNING", |
156 | #endif | 151 | #endif |
157 | NULL); | 152 | NULL); |
158 | ret = check (); | 153 | /* determine name of plugin to use */ |
159 | 154 | plugin_name = argv[0]; | |
160 | return ret; | 155 | while (NULL != (pos = strstr(plugin_name, "_"))) |
156 | plugin_name = pos+1; | ||
157 | GNUNET_snprintf (cfg_name, | ||
158 | sizeof (cfg_name), | ||
159 | "test_datacache_data_%s.conf", | ||
160 | plugin_name); | ||
161 | GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, | ||
162 | xargv, "test-datacache", "nohelp", | ||
163 | options, &run, NULL); | ||
164 | if (ok != 0) | ||
165 | fprintf (stderr, "Missed some testcases: %d\n", ok); | ||
166 | return ok; | ||
161 | } | 167 | } |
162 | 168 | ||
163 | /* end of test_datacache.c */ | 169 | /* end of test_datacache.c */ |
diff --git a/src/datacache/test_datacache_data_mysql.conf b/src/datacache/test_datacache_data_mysql.conf new file mode 100644 index 000000000..3086497df --- /dev/null +++ b/src/datacache/test_datacache_data_mysql.conf | |||
@@ -0,0 +1,12 @@ | |||
1 | |||
2 | [testcache] | ||
3 | QUOTA = 1000000 | ||
4 | DATABASE = mysql | ||
5 | |||
6 | [datacache-mysql] | ||
7 | DATABASE = gnunetcheck | ||
8 | # CONFIG = ~/.my.cnf | ||
9 | # USER = | ||
10 | # PASSWORD = | ||
11 | # HOST = | ||
12 | # PORT = \ No newline at end of file | ||
diff --git a/src/datacache/test_datacache_data.conf b/src/datacache/test_datacache_data_sqlite.conf index 2e8606682..2e8606682 100644 --- a/src/datacache/test_datacache_data.conf +++ b/src/datacache/test_datacache_data_sqlite.conf | |||
diff --git a/src/datacache/test_datacache_quota.c b/src/datacache/test_datacache_quota.c index f4686b6a3..9028196bd 100644 --- a/src/datacache/test_datacache_quota.c +++ b/src/datacache/test_datacache_quota.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2006, 2009 Christian Grothoff (and other contributing authors) | 3 | (C) 2006, 2009, 2010 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published |
@@ -33,6 +33,11 @@ | |||
33 | static int ok; | 33 | static int ok; |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * Name of plugin under test. | ||
37 | */ | ||
38 | static const char *plugin_name; | ||
39 | |||
40 | /** | ||
36 | * Quota is 1 MB. Each iteration of the test puts in about 1 MB of | 41 | * Quota is 1 MB. Each iteration of the test puts in about 1 MB of |
37 | * data. We do 10 iterations. Afterwards we check that the data from | 42 | * data. We do 10 iterations. Afterwards we check that the data from |
38 | * the first 5 iterations has all been discarded and that at least | 43 | * the first 5 iterations has all been discarded and that at least |
@@ -110,12 +115,15 @@ FAILURE: | |||
110 | } | 115 | } |
111 | 116 | ||
112 | 117 | ||
113 | static int | 118 | int |
114 | check () | 119 | main (int argc, char *argv[]) |
115 | { | 120 | { |
116 | char *const argv[] = { "test-datacache-quota", | 121 | const char *pos; |
122 | char cfg_name[128]; | ||
123 | char *const xargv[] = { | ||
124 | "test-datacache-quota", | ||
117 | "-c", | 125 | "-c", |
118 | "test_datacache_data.conf", | 126 | cfg_name, |
119 | #if VERBOSE | 127 | #if VERBOSE |
120 | "-L", "DEBUG", | 128 | "-L", "DEBUG", |
121 | #endif | 129 | #endif |
@@ -124,20 +132,7 @@ check () | |||
124 | struct GNUNET_GETOPT_CommandLineOption options[] = { | 132 | struct GNUNET_GETOPT_CommandLineOption options[] = { |
125 | GNUNET_GETOPT_OPTION_END | 133 | GNUNET_GETOPT_OPTION_END |
126 | }; | 134 | }; |
127 | GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, | 135 | |
128 | argv, "test-datacache-quota", "nohelp", | ||
129 | options, &run, NULL); | ||
130 | if (ok != 0) | ||
131 | fprintf (stderr, "Missed some testcases: %d\n", ok); | ||
132 | return ok; | ||
133 | } | ||
134 | |||
135 | |||
136 | int | ||
137 | main (int argc, char *argv[]) | ||
138 | { | ||
139 | int ret; | ||
140 | |||
141 | GNUNET_log_setup ("test-datacache-quota", | 136 | GNUNET_log_setup ("test-datacache-quota", |
142 | #if VERBOSE | 137 | #if VERBOSE |
143 | "DEBUG", | 138 | "DEBUG", |
@@ -145,9 +140,20 @@ main (int argc, char *argv[]) | |||
145 | "WARNING", | 140 | "WARNING", |
146 | #endif | 141 | #endif |
147 | NULL); | 142 | NULL); |
148 | ret = check (); | 143 | /* determine name of plugin to use */ |
149 | 144 | plugin_name = argv[0]; | |
150 | return ret; | 145 | while (NULL != (pos = strstr(plugin_name, "_"))) |
146 | plugin_name = pos+1; | ||
147 | GNUNET_snprintf (cfg_name, | ||
148 | sizeof (cfg_name), | ||
149 | "test_datacache_data_%s.conf", | ||
150 | plugin_name); | ||
151 | GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, | ||
152 | xargv, "test-datacache-quota", "nohelp", | ||
153 | options, &run, NULL); | ||
154 | if (ok != 0) | ||
155 | fprintf (stderr, "Missed some testcases: %d\n", ok); | ||
156 | return ok; | ||
151 | } | 157 | } |
152 | 158 | ||
153 | /* end of test_datacache_quota.c */ | 159 | /* end of test_datacache_quota.c */ |
diff --git a/src/datastore/Makefile.am b/src/datastore/Makefile.am index a96e22d4c..3c687e8ce 100644 --- a/src/datastore/Makefile.am +++ b/src/datastore/Makefile.am | |||
@@ -71,10 +71,10 @@ libgnunet_plugin_datastore_mysql_la_SOURCES = \ | |||
71 | plugin_datastore_mysql.c | 71 | plugin_datastore_mysql.c |
72 | libgnunet_plugin_datastore_mysql_la_LIBADD = \ | 72 | libgnunet_plugin_datastore_mysql_la_LIBADD = \ |
73 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 73 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
74 | $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lz -lsqlite3 | 74 | $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lz -lmysqlclient |
75 | libgnunet_plugin_datastore_mysql_la_LDFLAGS = \ | 75 | libgnunet_plugin_datastore_mysql_la_LDFLAGS = \ |
76 | $(GN_PLUGIN_LDFLAGS) $(MYSQL_LDFLAGS) -lmysqlclient | 76 | $(GN_PLUGIN_LDFLAGS) $(MYSQL_LDFLAGS) -lmysqlclient |
77 | libgnunet_plugin_datastore_sqlite_la_CPFLAGS = \ | 77 | libgnunet_plugin_datastore_mysql_la_CPPFLAGS = \ |
78 | $(MYSQL_CPPFLAGS) | 78 | $(MYSQL_CPPFLAGS) |
79 | 79 | ||
80 | 80 | ||
diff --git a/src/datastore/plugin_datastore_mysql.c b/src/datastore/plugin_datastore_mysql.c index 98c6c4ab3..c216e989c 100644 --- a/src/datastore/plugin_datastore_mysql.c +++ b/src/datastore/plugin_datastore_mysql.c | |||
@@ -572,46 +572,6 @@ run_statement (struct Plugin *plugin, | |||
572 | } | 572 | } |
573 | 573 | ||
574 | 574 | ||
575 | #if 0 | ||
576 | /** | ||
577 | * Run the given MySQL SELECT statement. The statement | ||
578 | * must have only a single result (one column, one row). | ||
579 | * | ||
580 | * @return result on success, NULL on error | ||
581 | */ | ||
582 | static char * | ||
583 | run_statement_select (struct Plugin *plugin, | ||
584 | const char *statement) | ||
585 | { | ||
586 | MYSQL_RES *sql_res; | ||
587 | MYSQL_ROW sql_row; | ||
588 | char *ret; | ||
589 | |||
590 | if ((NULL == plugin->dbf) && (GNUNET_OK != iopen (plugin))) | ||
591 | return NULL; | ||
592 | mysql_query (plugin->dbf, statement); | ||
593 | if ((mysql_error (plugin->dbf)[0]) || | ||
594 | (!(sql_res = mysql_use_result (plugin->dbf))) || | ||
595 | (!(sql_row = mysql_fetch_row (sql_res)))) | ||
596 | { | ||
597 | LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, | ||
598 | "mysql_query", plugin); | ||
599 | return NULL; | ||
600 | } | ||
601 | if ((mysql_num_fields (sql_res) != 1) || (sql_row[0] == NULL)) | ||
602 | { | ||
603 | GNUNET_break (mysql_num_fields (sql_res) == 1); | ||
604 | if (sql_res != NULL) | ||
605 | mysql_free_result (sql_res); | ||
606 | return NULL; | ||
607 | } | ||
608 | ret = GNUNET_strdup (sql_row[0]); | ||
609 | mysql_free_result (sql_res); | ||
610 | return ret; | ||
611 | } | ||
612 | #endif | ||
613 | |||
614 | |||
615 | /** | 575 | /** |
616 | * Create a prepared statement. | 576 | * Create a prepared statement. |
617 | * | 577 | * |