aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ABOUT-NLS1101
-rw-r--r--AUTHORS85
-rw-r--r--COPYING674
-rw-r--r--ChangeLog1704
-rw-r--r--HACKING57
-rw-r--r--INSTALL237
-rw-r--r--Makefile.am14
-rw-r--r--NEWS1
-rw-r--r--RATIONALE246
-rw-r--r--README257
-rw-r--r--TODO150
-rwxr-xr-xbin/grephdr.sh3
-rwxr-xr-xbin/grepsrc.sh3
-rwxr-xr-xbin/rename.sh6
-rwxr-xr-xbootstrap7
-rwxr-xr-xconfig.rpath614
-rw-r--r--configure.ac821
-rw-r--r--contrib/Makefile.am19
-rw-r--r--contrib/config.scm1568
-rwxr-xr-xcontrib/coverage.sh13
-rw-r--r--contrib/defaults.conf139
-rw-r--r--contrib/gnunet-logo-big.pngbin0 -> 250489 bytes
-rw-r--r--contrib/gnunet-logo-color.pngbin0 -> 6851 bytes
-rw-r--r--contrib/hostlist.cgi5
-rw-r--r--contrib/hostlist.php35
-rwxr-xr-xcontrib/report.sh200
-rw-r--r--doc/man/Makefile.am7
-rw-r--r--doc/man/gnunet-arm.157
-rw-r--r--doc/man/gnunet-peerinfo.142
-rw-r--r--doc/man/gnunet-statistics.150
-rw-r--r--doc/man/gnunet-transport.196
-rw-r--r--m4/Makefile.am1
-rw-r--r--m4/align.m428
-rw-r--r--po/ChangeLog16
-rw-r--r--po/GNUnet.pot5168
-rw-r--r--po/LINGUAS2
-rw-r--r--po/Makefile.in.in403
-rw-r--r--po/Makevars41
-rw-r--r--po/Makevars.template41
-rw-r--r--po/POTFILES.in0
-rw-r--r--po/Rules-quot47
-rw-r--r--po/boldquot.sed10
-rw-r--r--po/de.gmobin0 -> 40027 bytes
-rw-r--r--po/de.po7387
-rw-r--r--po/en@boldquot.header25
-rw-r--r--po/en@quot.header22
-rw-r--r--po/es.gmobin0 -> 31722 bytes
-rw-r--r--po/es.po6921
-rw-r--r--po/insert-header.sin23
-rw-r--r--po/quot.sed6
-rw-r--r--po/remove-potcdate.sin19
-rw-r--r--po/stamp-po1
-rw-r--r--po/sv.gmobin0 -> 19833 bytes
-rw-r--r--po/sv.po5885
-rw-r--r--po/update.pl230
-rw-r--r--po/vi.gmobin0 -> 166871 bytes
-rw-r--r--po/vi.po5772
-rwxr-xr-xpre-commit17
-rw-r--r--src/Makefile.am17
-rw-r--r--src/arm/Makefile.am58
-rw-r--r--src/arm/arm.h32
-rw-r--r--src/arm/arm_api.c337
-rw-r--r--src/arm/gnunet-arm.c180
-rw-r--r--src/arm/gnunet-service-arm.c712
-rw-r--r--src/arm/test_arm_api.c140
-rw-r--r--src/arm/test_arm_api_data.conf7
-rwxr-xr-xsrc/arm/test_gnunet_arm.sh117
-rw-r--r--src/core/Makefile.am68
-rw-r--r--src/core/core.h308
-rw-r--r--src/core/core_api.c1071
-rw-r--r--src/core/gnunet-service-core.c2859
-rw-r--r--src/core/test_core_api.c368
-rw-r--r--src/core/test_core_api_data.conf27
-rw-r--r--src/core/test_core_api_peer1.conf40
-rw-r--r--src/core/test_core_api_peer2.conf39
-rw-r--r--src/core/test_core_api_start_only.c257
-rw-r--r--src/datastore/plugin_datastore.h241
-rw-r--r--src/fragmentation/Makefile.am28
-rw-r--r--src/fragmentation/fragmentation.c702
-rw-r--r--src/fragmentation/test_fragmentation.c439
-rw-r--r--src/hello/Makefile.am28
-rw-r--r--src/hello/hello.c482
-rw-r--r--src/hello/test_hello.c185
-rw-r--r--src/include/Makefile.am42
-rw-r--r--src/include/gettext.h71
-rw-r--r--src/include/gnunet_arm_service.h107
-rw-r--r--src/include/gnunet_client_lib.h160
-rw-r--r--src/include/gnunet_common.h469
-rw-r--r--src/include/gnunet_configuration_lib.h238
-rw-r--r--src/include/gnunet_container_lib.h784
-rw-r--r--src/include/gnunet_core_service.h323
-rw-r--r--src/include/gnunet_crypto_lib.h567
-rw-r--r--src/include/gnunet_datastore_service.h187
-rw-r--r--src/include/gnunet_directories.h.in34
-rw-r--r--src/include/gnunet_disk_lib.h279
-rw-r--r--src/include/gnunet_fragmentation_lib.h113
-rw-r--r--src/include/gnunet_getopt_lib.h251
-rw-r--r--src/include/gnunet_hello_lib.h201
-rw-r--r--src/include/gnunet_network_lib.h308
-rw-r--r--src/include/gnunet_os_lib.h158
-rw-r--r--src/include/gnunet_peerinfo_service.h111
-rw-r--r--src/include/gnunet_plugin_lib.h84
-rw-r--r--src/include/gnunet_program_lib.h90
-rw-r--r--src/include/gnunet_protocols.h319
-rw-r--r--src/include/gnunet_pseudonym_lib.h125
-rw-r--r--src/include/gnunet_resolver_service.h135
-rw-r--r--src/include/gnunet_scheduler_lib.h442
-rw-r--r--src/include/gnunet_server_lib.h498
-rw-r--r--src/include/gnunet_service_lib.h140
-rw-r--r--src/include/gnunet_signal_lib.h73
-rw-r--r--src/include/gnunet_signatures.h77
-rw-r--r--src/include/gnunet_statistics_service.h157
-rw-r--r--src/include/gnunet_strings_lib.h139
-rw-r--r--src/include/gnunet_time_lib.h246
-rw-r--r--src/include/gnunet_transport_service.h241
-rw-r--r--src/include/gnunet_upnp_service.h75
-rw-r--r--src/include/gnunet_util_lib.h64
-rw-r--r--src/include/platform.h221
-rw-r--r--src/include/plibc.h582
-rw-r--r--src/include/winproc.h216
-rw-r--r--src/peerinfo/Makefile.am56
-rw-r--r--src/peerinfo/gnunet-peerinfo.c152
-rw-r--r--src/peerinfo/gnunet-service-peerinfo.c708
-rw-r--r--src/peerinfo/peerinfo.h135
-rw-r--r--src/peerinfo/peerinfo_api.c302
-rw-r--r--src/peerinfo/test_peerinfo_api.c175
-rw-r--r--src/peerinfo/test_peerinfo_api_data.conf5
-rw-r--r--src/resolver/Makefile.am46
-rw-r--r--src/resolver/gnunet-service-resolver.c483
-rw-r--r--src/resolver/resolver.h63
-rw-r--r--src/resolver/resolver_api.c468
-rw-r--r--src/resolver/test_resolver_api.c229
-rw-r--r--src/resolver/test_resolver_api_data.conf5
-rw-r--r--src/statistics/Makefile.am59
-rw-r--r--src/statistics/gnunet-service-statistics.c470
-rw-r--r--src/statistics/gnunet-statistics.c179
-rw-r--r--src/statistics/statistics.h94
-rw-r--r--src/statistics/statistics_api.c688
-rwxr-xr-xsrc/statistics/test_gnunet_statistics.sh177
-rw-r--r--src/statistics/test_statistics_api.c177
-rw-r--r--src/statistics/test_statistics_api_data.conf5
-rw-r--r--src/template/Makefile.am37
-rw-r--r--src/template/gnunet-service-template.c87
-rw-r--r--src/template/gnunet-template.c81
-rw-r--r--src/template/test_template_api.c45
-rw-r--r--src/transport/Makefile.am84
-rw-r--r--src/transport/NOTES46
-rw-r--r--src/transport/gnunet-service-transport.c2852
-rw-r--r--src/transport/gnunet-transport.c42
-rw-r--r--src/transport/plugin_transport.h468
-rw-r--r--src/transport/plugin_transport_http.c2085
-rw-r--r--src/transport/plugin_transport_smtp.c906
-rw-r--r--src/transport/plugin_transport_tcp.c1782
-rw-r--r--src/transport/plugin_transport_template.c335
-rw-r--r--src/transport/plugin_transport_udp.c592
-rw-r--r--src/transport/test_transport_api.c305
-rw-r--r--src/transport/test_transport_api_data.conf24
-rw-r--r--src/transport/test_transport_api_peer1.conf25
-rw-r--r--src/transport/test_transport_api_peer2.conf25
-rw-r--r--src/transport/transport.h238
-rw-r--r--src/transport/transport_api.c1863
-rw-r--r--src/upnp/Makefile.am59
-rw-r--r--src/upnp/draft-cheshire-nat-pmp.txt1160
-rw-r--r--src/upnp/test_upnp.c110
-rw-r--r--src/upnp/upnp.c721
-rw-r--r--src/upnp/upnp.h82
-rw-r--r--src/upnp/upnp_init.c208
-rw-r--r--src/upnp/upnp_ip.c47
-rw-r--r--src/upnp/upnp_ip.h40
-rw-r--r--src/upnp/upnp_util.c152
-rw-r--r--src/upnp/upnp_util.h68
-rw-r--r--src/upnp/upnp_xmlnode.c487
-rw-r--r--src/upnp/upnp_xmlnode.h92
-rw-r--r--src/util/Makefile.am308
-rw-r--r--src/util/client.c526
-rw-r--r--src/util/common_allocation.c206
-rw-r--r--src/util/common_endian.c52
-rw-r--r--src/util/common_gettext.c42
-rw-r--r--src/util/common_logging.c401
-rw-r--r--src/util/configuration.c848
-rw-r--r--src/util/container_bloomfilter.c677
-rw-r--r--src/util/container_heap.c533
-rw-r--r--src/util/container_meta_data.c721
-rw-r--r--src/util/container_multihashmap.c334
-rw-r--r--src/util/crypto_aes.c148
-rw-r--r--src/util/crypto_crc.c106
-rw-r--r--src/util/crypto_hash.c791
-rw-r--r--src/util/crypto_ksk.c791
-rw-r--r--src/util/crypto_random.c136
-rw-r--r--src/util/crypto_rsa.c948
-rw-r--r--src/util/disk.c954
-rw-r--r--src/util/getopt.c1077
-rw-r--r--src/util/getopt_helpers.c200
-rw-r--r--src/util/network.c1239
-rw-r--r--src/util/os_installation.c443
-rw-r--r--src/util/os_load.c653
-rw-r--r--src/util/os_network.c286
-rw-r--r--src/util/os_priority.c186
-rw-r--r--src/util/perf_crypto_hash.c64
-rw-r--r--src/util/plugin.c243
-rw-r--r--src/util/program.c202
-rw-r--r--src/util/pseudonym.c545
-rw-r--r--src/util/scheduler.c886
-rw-r--r--src/util/server.c1091
-rw-r--r--src/util/server_tc.c198
-rw-r--r--src/util/service.c1451
-rw-r--r--src/util/signal.c76
-rw-r--r--src/util/strings.c396
-rw-r--r--src/util/test_client.c195
-rw-r--r--src/util/test_common_allocation.c112
-rw-r--r--src/util/test_common_endian.c42
-rw-r--r--src/util/test_common_logging.c100
-rw-r--r--src/util/test_configuration.c229
-rw-r--r--src/util/test_configuration_data.conf30
-rw-r--r--src/util/test_container_bloomfilter.c246
-rw-r--r--src/util/test_container_heap.c112
-rw-r--r--src/util/test_container_meta_data.c262
-rw-r--r--src/util/test_container_meta_data_image.jpgbin0 -> 136107 bytes
-rw-r--r--src/util/test_container_multihashmap.c113
-rw-r--r--src/util/test_crypto_aes.c180
-rw-r--r--src/util/test_crypto_aes_weak.c203
-rw-r--r--src/util/test_crypto_crc.c221
-rw-r--r--src/util/test_crypto_hash.c165
-rw-r--r--src/util/test_crypto_ksk.c220
-rw-r--r--src/util/test_crypto_random.c71
-rw-r--r--src/util/test_crypto_rsa.c335
-rw-r--r--src/util/test_disk.c274
-rw-r--r--src/util/test_getopt.c239
-rw-r--r--src/util/test_network.c209
-rw-r--r--src/util/test_network_addressing.c193
-rw-r--r--src/util/test_network_receive_cancel.c164
-rw-r--r--src/util/test_network_timeout.c144
-rw-r--r--src/util/test_network_timeout_no_connect.c95
-rw-r--r--src/util/test_network_transmit_cancel.c97
-rw-r--r--src/util/test_os_load.c182
-rw-r--r--src/util/test_os_network.c73
-rw-r--r--src/util/test_os_priority.c61
-rw-r--r--src/util/test_plugin.c64
-rw-r--r--src/util/test_plugin_plug.c42
-rw-r--r--src/util/test_program.c94
-rw-r--r--src/util/test_program_data.conf0
-rw-r--r--src/util/test_pseudonym.c138
-rw-r--r--src/util/test_pseudonym_data.conf8
-rw-r--r--src/util/test_scheduler.c263
-rw-r--r--src/util/test_scheduler_delay.c107
-rw-r--r--src/util/test_server.c287
-rw-r--r--src/util/test_server_disconnect.c241
-rw-r--r--src/util/test_server_with_client.c215
-rw-r--r--src/util/test_service.c337
-rw-r--r--src/util/test_service_data.conf26
-rw-r--r--src/util/test_strings.c111
-rw-r--r--src/util/test_time.c122
-rw-r--r--src/util/time.c286
253 files changed, 101835 insertions, 0 deletions
diff --git a/ABOUT-NLS b/ABOUT-NLS
new file mode 100644
index 000000000..ec20977e0
--- /dev/null
+++ b/ABOUT-NLS
@@ -0,0 +1,1101 @@
11 Notes on the Free Translation Project
2***************************************
3
4Free software is going international! The Free Translation Project is
5a way to get maintainers of free software, translators, and users all
6together, so that free software will gradually become able to speak many
7languages. A few packages already provide translations for their
8messages.
9
10 If you found this `ABOUT-NLS' file inside a distribution, you may
11assume that the distributed package does use GNU `gettext' internally,
12itself available at your nearest GNU archive site. But you do _not_
13need to install GNU `gettext' prior to configuring, installing or using
14this package with messages translated.
15
16 Installers will find here some useful hints. These notes also
17explain how users should proceed for getting the programs to use the
18available translations. They tell how people wanting to contribute and
19work on translations can contact the appropriate team.
20
21 When reporting bugs in the `intl/' directory or bugs which may be
22related to internationalization, you should tell about the version of
23`gettext' which is used. The information can be found in the
24`intl/VERSION' file, in internationalized packages.
25
261.1 Quick configuration advice
27==============================
28
29If you want to exploit the full power of internationalization, you
30should configure it using
31
32 ./configure --with-included-gettext
33
34to force usage of internationalizing routines provided within this
35package, despite the existence of internationalizing capabilities in the
36operating system where this package is being installed. So far, only
37the `gettext' implementation in the GNU C library version 2 provides as
38many features (such as locale alias, message inheritance, automatic
39charset conversion or plural form handling) as the implementation here.
40It is also not possible to offer this additional functionality on top
41of a `catgets' implementation. Future versions of GNU `gettext' will
42very likely convey even more functionality. So it might be a good idea
43to change to GNU `gettext' as soon as possible.
44
45 So you need _not_ provide this option if you are using GNU libc 2 or
46you have installed a recent copy of the GNU gettext package with the
47included `libintl'.
48
491.2 INSTALL Matters
50===================
51
52Some packages are "localizable" when properly installed; the programs
53they contain can be made to speak your own native language. Most such
54packages use GNU `gettext'. Other packages have their own ways to
55internationalization, predating GNU `gettext'.
56
57 By default, this package will be installed to allow translation of
58messages. It will automatically detect whether the system already
59provides the GNU `gettext' functions. If not, the included GNU
60`gettext' library will be used. This library is wholly contained
61within this package, usually in the `intl/' subdirectory, so prior
62installation of the GNU `gettext' package is _not_ required.
63Installers may use special options at configuration time for changing
64the default behaviour. The commands:
65
66 ./configure --with-included-gettext
67 ./configure --disable-nls
68
69will, respectively, bypass any pre-existing `gettext' to use the
70internationalizing routines provided within this package, or else,
71_totally_ disable translation of messages.
72
73 When you already have GNU `gettext' installed on your system and run
74configure without an option for your new package, `configure' will
75probably detect the previously built and installed `libintl.a' file and
76will decide to use this. This might not be desirable. You should use
77the more recent version of the GNU `gettext' library. I.e. if the file
78`intl/VERSION' shows that the library which comes with this package is
79more recent, you should use
80
81 ./configure --with-included-gettext
82
83to prevent auto-detection.
84
85 The configuration process will not test for the `catgets' function
86and therefore it will not be used. The reason is that even an
87emulation of `gettext' on top of `catgets' could not provide all the
88extensions of the GNU `gettext' library.
89
90 Internationalized packages usually have many `po/LL.po' files, where
91LL gives an ISO 639 two-letter code identifying the language. Unless
92translations have been forbidden at `configure' time by using the
93`--disable-nls' switch, all available translations are installed
94together with the package. However, the environment variable `LINGUAS'
95may be set, prior to configuration, to limit the installed set.
96`LINGUAS' should then contain a space separated list of two-letter
97codes, stating which languages are allowed.
98
991.3 Using This Package
100======================
101
102As a user, if your language has been installed for this package, you
103only have to set the `LANG' environment variable to the appropriate
104`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code,
105and `CC' is an ISO 3166 two-letter country code. For example, let's
106suppose that you speak German and live in Germany. At the shell
107prompt, merely execute `setenv LANG de_DE' (in `csh'),
108`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash').
109This can be done from your `.login' or `.profile' file, once and for
110all.
111
112 You might think that the country code specification is redundant.
113But in fact, some languages have dialects in different countries. For
114example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The
115country code serves to distinguish the dialects.
116
117 The locale naming convention of `LL_CC', with `LL' denoting the
118language and `CC' denoting the country, is the one use on systems based
119on GNU libc. On other systems, some variations of this scheme are
120used, such as `LL' or `LL_CC.ENCODING'. You can get the list of
121locales supported by your system for your language by running the
122command `locale -a | grep '^LL''.
123
124 Not all programs have translations for all languages. By default, an
125English message is shown in place of a nonexistent translation. If you
126understand other languages, you can set up a priority list of languages.
127This is done through a different environment variable, called
128`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG'
129for the purpose of message handling, but you still need to have `LANG'
130set to the primary language; this is required by other parts of the
131system libraries. For example, some Swedish users who would rather
132read translations in German than English for when Swedish is not
133available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'.
134
135 Special advice for Norwegian users: The language code for Norwegian
136bokma*l changed from `no' to `nb' recently (in 2003). During the
137transition period, while some message catalogs for this language are
138installed under `nb' and some older ones under `no', it's recommended
139for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and
140older translations are used.
141
142 In the `LANGUAGE' environment variable, but not in the `LANG'
143environment variable, `LL_CC' combinations can be abbreviated as `LL'
144to denote the language's main dialect. For example, `de' is equivalent
145to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT'
146(Portuguese as spoken in Portugal) in this context.
147
1481.4 Translating Teams
149=====================
150
151For the Free Translation Project to be a success, we need interested
152people who like their own language and write it well, and who are also
153able to synergize with other translators speaking the same language.
154Each translation team has its own mailing list. The up-to-date list of
155teams can be found at the Free Translation Project's homepage,
156`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams"
157area.
158
159 If you'd like to volunteer to _work_ at translating messages, you
160should become a member of the translating team for your own language.
161The subscribing address is _not_ the same as the list itself, it has
162`-request' appended. For example, speakers of Swedish can send a
163message to `sv-request@li.org', having this message body:
164
165 subscribe
166
167 Keep in mind that team members are expected to participate
168_actively_ in translations, or at solving translational difficulties,
169rather than merely lurking around. If your team does not exist yet and
170you want to start one, or if you are unsure about what to do or how to
171get started, please write to `translation@iro.umontreal.ca' to reach the
172coordinator for all translator teams.
173
174 The English team is special. It works at improving and uniformizing
175the terminology in use. Proven linguistic skills are praised more than
176programming skills, here.
177
1781.5 Available Packages
179======================
180
181Languages are not equally supported in all packages. The following
182matrix shows the current state of internationalization, as of October
1832006. The matrix shows, in regard of each package, for which languages
184PO files have been submitted to translation coordination, with a
185translation percentage of at least 50%.
186
187 Ready PO files af am ar az be bg bs ca cs cy da de el en en_GB eo
188 +----------------------------------------------------+
189 GNUnet | [] |
190 a2ps | [] [] [] [] [] |
191 aegis | () |
192 ant-phone | () |
193 anubis | [] |
194 ap-utils | |
195 aspell | [] [] [] [] [] |
196 bash | [] [] [] |
197 batchelor | [] |
198 bfd | |
199 bibshelf | [] |
200 binutils | [] |
201 bison | [] [] |
202 bison-runtime | |
203 bluez-pin | [] [] [] [] [] |
204 cflow | [] |
205 clisp | [] [] |
206 console-tools | [] [] |
207 coreutils | [] [] [] |
208 cpio | |
209 cpplib | [] [] [] |
210 cryptonit | [] |
211 darkstat | [] () [] |
212 dialog | [] [] [] [] [] [] |
213 diffutils | [] [] [] [] [] [] |
214 doodle | [] |
215 e2fsprogs | [] [] |
216 enscript | [] [] [] [] |
217 error | [] [] [] [] |
218 fetchmail | [] [] () [] |
219 fileutils | [] [] |
220 findutils | [] [] [] |
221 flex | [] [] [] |
222 fslint | [] |
223 gas | |
224 gawk | [] [] [] |
225 gbiff | [] |
226 gcal | [] |
227 gcc | [] |
228 gettext-examples | [] [] [] [] [] |
229 gettext-runtime | [] [] [] [] [] |
230 gettext-tools | [] [] |
231 gimp-print | [] [] [] [] |
232 gip | [] |
233 gliv | [] |
234 glunarclock | [] |
235 gmult | [] [] |
236 gnubiff | () |
237 gnucash | () () [] |
238 gnucash-glossary | [] () |
239 gnuedu | |
240 gnulib | [] [] [] [] [] [] |
241 gnunet-gtk | |
242 gnutls | |
243 gpe-aerial | [] [] |
244 gpe-beam | [] [] |
245 gpe-calendar | |
246 gpe-clock | [] [] |
247 gpe-conf | [] [] |
248 gpe-contacts | |
249 gpe-edit | [] |
250 gpe-filemanager | |
251 gpe-go | [] |
252 gpe-login | [] [] |
253 gpe-ownerinfo | [] [] |
254 gpe-package | |
255 gpe-sketchbook | [] [] |
256 gpe-su | [] [] |
257 gpe-taskmanager | [] [] |
258 gpe-timesheet | [] |
259 gpe-today | [] [] |
260 gpe-todo | |
261 gphoto2 | [] [] [] [] |
262 gprof | [] [] |
263 gpsdrive | () () |
264 gramadoir | [] [] |
265 grep | [] [] [] [] [] [] |
266 gretl | |
267 gsasl | |
268 gss | |
269 gst-plugins | [] [] [] [] |
270 gst-plugins-base | [] [] [] |
271 gst-plugins-good | [] [] [] [] [] [] [] |
272 gstreamer | [] [] [] [] [] [] [] |
273 gtick | () |
274 gtkam | [] [] [] |
275 gtkorphan | [] [] |
276 gtkspell | [] [] [] [] |
277 gutenprint | [] |
278 hello | [] [] [] [] [] |
279 id-utils | [] [] |
280 impost | |
281 indent | [] [] [] |
282 iso_3166 | [] [] |
283 iso_3166_2 | |
284 iso_4217 | [] |
285 iso_639 | [] [] |
286 jpilot | [] |
287 jtag | |
288 jwhois | |
289 kbd | [] [] [] [] |
290 keytouch | |
291 keytouch-editor | |
292 keytouch-keyboa... | |
293 latrine | () |
294 ld | [] |
295 leafpad | [] [] [] [] [] |
296 libc | [] [] [] [] [] |
297 libexif | [] |
298 libextractor | [] |
299 libgpewidget | [] [] [] |
300 libgpg-error | [] |
301 libgphoto2 | [] [] |
302 libgphoto2_port | [] [] |
303 libgsasl | |
304 libiconv | [] [] |
305 libidn | [] [] |
306 lifelines | [] () |
307 lilypond | [] |
308 lingoteach | |
309 lynx | [] [] [] [] |
310 m4 | [] [] [] [] |
311 mailutils | [] |
312 make | [] [] |
313 man-db | [] () [] [] |
314 minicom | [] [] [] |
315 mysecretdiary | [] [] |
316 nano | [] [] [] |
317 nano_1_0 | [] () [] [] |
318 opcodes | [] |
319 parted | |
320 pilot-qof | [] |
321 psmisc | [] |
322 pwdutils | |
323 python | |
324 qof | |
325 radius | [] |
326 recode | [] [] [] [] [] [] |
327 rpm | [] [] |
328 screem | |
329 scrollkeeper | [] [] [] [] [] [] [] [] |
330 sed | [] [] [] |
331 sh-utils | [] [] |
332 shared-mime-info | [] [] [] [] |
333 sharutils | [] [] [] [] [] [] |
334 shishi | |
335 silky | |
336 skencil | [] () |
337 sketch | [] () |
338 solfege | |
339 soundtracker | [] [] |
340 sp | [] |
341 stardict | [] |
342 system-tools-ba... | [] [] [] [] [] [] [] [] [] |
343 tar | [] |
344 texinfo | [] [] [] |
345 textutils | [] [] [] |
346 tin | () () |
347 tp-robot | [] |
348 tuxpaint | [] [] [] [] [] |
349 unicode-han-tra... | |
350 unicode-transla... | |
351 util-linux | [] [] [] [] |
352 vorbis-tools | [] [] [] [] |
353 wastesedge | () |
354 wdiff | [] [] [] [] |
355 wget | [] [] |
356 xchat | [] [] [] [] [] [] |
357 xkeyboard-config | |
358 xpad | [] [] |
359 +----------------------------------------------------+
360 af am ar az be bg bs ca cs cy da de el en en_GB eo
361 10 0 1 2 9 22 1 42 41 2 60 95 16 1 17 16
362
363 es et eu fa fi fr ga gl gu he hi hr hu id is it
364 +--------------------------------------------------+
365 GNUnet | |
366 a2ps | [] [] [] () |
367 aegis | |
368 ant-phone | [] |
369 anubis | [] |
370 ap-utils | [] [] |
371 aspell | [] [] [] |
372 bash | [] [] [] |
373 batchelor | [] [] |
374 bfd | [] |
375 bibshelf | [] [] [] |
376 binutils | [] [] [] |
377 bison | [] [] [] [] [] [] |
378 bison-runtime | [] [] [] [] [] |
379 bluez-pin | [] [] [] [] [] |
380 cflow | [] |
381 clisp | [] [] |
382 console-tools | |
383 coreutils | [] [] [] [] [] [] |
384 cpio | [] [] [] |
385 cpplib | [] [] |
386 cryptonit | [] |
387 darkstat | [] () [] [] [] |
388 dialog | [] [] [] [] [] [] [] [] |
389 diffutils | [] [] [] [] [] [] [] [] [] |
390 doodle | [] [] |
391 e2fsprogs | [] [] [] |
392 enscript | [] [] [] |
393 error | [] [] [] [] [] |
394 fetchmail | [] |
395 fileutils | [] [] [] [] [] [] |
396 findutils | [] [] [] [] |
397 flex | [] [] [] |
398 fslint | [] |
399 gas | [] [] |
400 gawk | [] [] [] [] |
401 gbiff | [] |
402 gcal | [] [] |
403 gcc | [] |
404 gettext-examples | [] [] [] [] [] [] |
405 gettext-runtime | [] [] [] [] [] [] |
406 gettext-tools | [] [] [] |
407 gimp-print | [] [] |
408 gip | [] [] [] |
409 gliv | () |
410 glunarclock | [] [] [] |
411 gmult | [] [] [] |
412 gnubiff | () () |
413 gnucash | () () () |
414 gnucash-glossary | [] [] |
415 gnuedu | [] |
416 gnulib | [] [] [] [] [] [] [] [] |
417 gnunet-gtk | |
418 gnutls | |
419 gpe-aerial | [] [] |
420 gpe-beam | [] [] |
421 gpe-calendar | |
422 gpe-clock | [] [] [] [] |
423 gpe-conf | [] |
424 gpe-contacts | [] [] |
425 gpe-edit | [] [] [] [] |
426 gpe-filemanager | [] |
427 gpe-go | [] [] [] |
428 gpe-login | [] [] [] |
429 gpe-ownerinfo | [] [] [] [] [] |
430 gpe-package | [] |
431 gpe-sketchbook | [] [] |
432 gpe-su | [] [] [] [] |
433 gpe-taskmanager | [] [] [] |
434 gpe-timesheet | [] [] [] [] |
435 gpe-today | [] [] [] [] |
436 gpe-todo | [] |
437 gphoto2 | [] [] [] [] [] |
438 gprof | [] [] [] [] |
439 gpsdrive | () () [] () |
440 gramadoir | [] [] |
441 grep | [] [] [] [] [] [] [] [] [] [] [] [] |
442 gretl | [] [] [] |
443 gsasl | [] [] |
444 gss | [] |
445 gst-plugins | [] [] [] |
446 gst-plugins-base | [] [] |
447 gst-plugins-good | [] [] [] |
448 gstreamer | [] [] [] |
449 gtick | [] |
450 gtkam | [] [] [] [] |
451 gtkorphan | [] [] |
452 gtkspell | [] [] [] [] [] [] |
453 gutenprint | [] |
454 hello | [] [] [] [] [] [] [] [] [] [] [] [] [] |
455 id-utils | [] [] [] [] [] |
456 impost | [] [] |
457 indent | [] [] [] [] [] [] [] [] [] [] |
458 iso_3166 | [] [] [] |
459 iso_3166_2 | [] |
460 iso_4217 | [] [] [] [] |
461 iso_639 | [] [] [] [] [] |
462 jpilot | [] [] |
463 jtag | [] |
464 jwhois | [] [] [] [] [] |
465 kbd | [] [] |
466 keytouch | [] |
467 keytouch-editor | [] |
468 keytouch-keyboa... | [] |
469 latrine | [] [] [] |
470 ld | [] [] |
471 leafpad | [] [] [] [] [] [] |
472 libc | [] [] [] [] [] |
473 libexif | [] |
474 libextractor | [] |
475 libgpewidget | [] [] [] [] [] |
476 libgpg-error | |
477 libgphoto2 | [] [] [] |
478 libgphoto2_port | [] [] |
479 libgsasl | [] [] |
480 libiconv | [] [] |
481 libidn | [] [] |
482 lifelines | () |
483 lilypond | [] |
484 lingoteach | [] [] [] |
485 lynx | [] [] [] |
486 m4 | [] [] [] [] |
487 mailutils | [] [] |
488 make | [] [] [] [] [] [] [] [] |
489 man-db | () |
490 minicom | [] [] [] [] |
491 mysecretdiary | [] [] [] |
492 nano | [] [] [] [] [] [] |
493 nano_1_0 | [] [] [] [] [] |
494 opcodes | [] [] [] [] |
495 parted | [] [] [] [] |
496 pilot-qof | |
497 psmisc | [] [] [] |
498 pwdutils | |
499 python | |
500 qof | [] |
501 radius | [] [] |
502 recode | [] [] [] [] [] [] [] [] |
503 rpm | [] [] |
504 screem | |
505 scrollkeeper | [] [] [] |
506 sed | [] [] [] [] [] |
507 sh-utils | [] [] [] [] [] [] [] |
508 shared-mime-info | [] [] [] [] [] [] |
509 sharutils | [] [] [] [] [] [] [] [] |
510 shishi | |
511 silky | [] |
512 skencil | [] [] |
513 sketch | [] [] |
514 solfege | [] |
515 soundtracker | [] [] [] |
516 sp | [] |
517 stardict | [] |
518 system-tools-ba... | [] [] [] [] [] [] [] [] |
519 tar | [] [] [] [] [] [] [] |
520 texinfo | [] [] |
521 textutils | [] [] [] [] [] |
522 tin | [] () |
523 tp-robot | [] [] [] [] |
524 tuxpaint | [] [] |
525 unicode-han-tra... | |
526 unicode-transla... | [] [] |
527 util-linux | [] [] [] [] [] [] [] |
528 vorbis-tools | [] [] |
529 wastesedge | () |
530 wdiff | [] [] [] [] [] [] [] [] |
531 wget | [] [] [] [] [] [] [] [] |
532 xchat | [] [] [] [] [] [] [] [] |
533 xkeyboard-config | [] [] [] [] |
534 xpad | [] [] [] |
535 +--------------------------------------------------+
536 es et eu fa fi fr ga gl gu he hi hr hu id is it
537 88 22 14 2 40 115 61 14 1 8 1 6 59 31 0 52
538
539 ja ko ku ky lg lt lv mk mn ms mt nb ne nl nn no
540 +-------------------------------------------------+
541 GNUnet | |
542 a2ps | () [] [] () |
543 aegis | () |
544 ant-phone | [] |
545 anubis | [] [] [] |
546 ap-utils | [] |
547 aspell | [] [] |
548 bash | [] |
549 batchelor | [] [] |
550 bfd | |
551 bibshelf | [] |
552 binutils | |
553 bison | [] [] [] |
554 bison-runtime | [] [] [] |
555 bluez-pin | [] [] [] |
556 cflow | |
557 clisp | [] |
558 console-tools | |
559 coreutils | [] |
560 cpio | |
561 cpplib | [] |
562 cryptonit | [] |
563 darkstat | [] [] |
564 dialog | [] [] |
565 diffutils | [] [] [] |
566 doodle | |
567 e2fsprogs | [] |
568 enscript | [] |
569 error | [] |
570 fetchmail | [] [] |
571 fileutils | [] [] |
572 findutils | [] |
573 flex | [] [] |
574 fslint | [] [] |
575 gas | |
576 gawk | [] [] |
577 gbiff | [] |
578 gcal | |
579 gcc | |
580 gettext-examples | [] [] |
581 gettext-runtime | [] [] [] |
582 gettext-tools | [] [] |
583 gimp-print | [] [] |
584 gip | [] [] |
585 gliv | [] |
586 glunarclock | [] [] |
587 gmult | [] [] |
588 gnubiff | |
589 gnucash | () () |
590 gnucash-glossary | [] |
591 gnuedu | |
592 gnulib | [] [] [] [] |
593 gnunet-gtk | |
594 gnutls | |
595 gpe-aerial | [] |
596 gpe-beam | [] |
597 gpe-calendar | [] |
598 gpe-clock | [] [] [] |
599 gpe-conf | [] [] |
600 gpe-contacts | [] |
601 gpe-edit | [] [] [] |
602 gpe-filemanager | [] [] |
603 gpe-go | [] [] [] |
604 gpe-login | [] [] [] |
605 gpe-ownerinfo | [] [] |
606 gpe-package | [] [] |
607 gpe-sketchbook | [] [] |
608 gpe-su | [] [] [] |
609 gpe-taskmanager | [] [] [] [] |
610 gpe-timesheet | [] |
611 gpe-today | [] [] |
612 gpe-todo | [] |
613 gphoto2 | [] [] |
614 gprof | |
615 gpsdrive | () () () |
616 gramadoir | () |
617 grep | [] [] [] [] |
618 gretl | |
619 gsasl | [] |
620 gss | |
621 gst-plugins | [] |
622 gst-plugins-base | |
623 gst-plugins-good | [] |
624 gstreamer | [] |
625 gtick | |
626 gtkam | [] |
627 gtkorphan | [] |
628 gtkspell | [] [] |
629 gutenprint | |
630 hello | [] [] [] [] [] [] |
631 id-utils | [] |
632 impost | |
633 indent | [] [] |
634 iso_3166 | [] |
635 iso_3166_2 | [] |
636 iso_4217 | [] [] [] |
637 iso_639 | [] [] |
638 jpilot | () () () |
639 jtag | |
640 jwhois | [] |
641 kbd | [] |
642 keytouch | [] |
643 keytouch-editor | |
644 keytouch-keyboa... | |
645 latrine | [] |
646 ld | |
647 leafpad | [] [] |
648 libc | [] [] [] [] [] |
649 libexif | |
650 libextractor | |
651 libgpewidget | [] |
652 libgpg-error | |
653 libgphoto2 | [] |
654 libgphoto2_port | [] |
655 libgsasl | [] |
656 libiconv | |
657 libidn | [] [] |
658 lifelines | [] |
659 lilypond | |
660 lingoteach | [] |
661 lynx | [] [] |
662 m4 | [] [] |
663 mailutils | |
664 make | [] [] [] |
665 man-db | () |
666 minicom | [] |
667 mysecretdiary | [] |
668 nano | [] [] [] |
669 nano_1_0 | [] [] [] |
670 opcodes | [] |
671 parted | [] [] |
672 pilot-qof | |
673 psmisc | [] [] [] |
674 pwdutils | |
675 python | |
676 qof | |
677 radius | |
678 recode | [] |
679 rpm | [] [] |
680 screem | [] |
681 scrollkeeper | [] [] [] [] |
682 sed | [] [] |
683 sh-utils | [] [] |
684 shared-mime-info | [] [] [] [] [] |
685 sharutils | [] [] |
686 shishi | |
687 silky | [] |
688 skencil | |
689 sketch | |
690 solfege | |
691 soundtracker | |
692 sp | () |
693 stardict | [] [] |
694 system-tools-ba... | [] [] [] [] |
695 tar | [] [] [] |
696 texinfo | [] [] [] |
697 textutils | [] [] [] |
698 tin | |
699 tp-robot | [] |
700 tuxpaint | [] |
701 unicode-han-tra... | |
702 unicode-transla... | |
703 util-linux | [] [] |
704 vorbis-tools | [] |
705 wastesedge | [] |
706 wdiff | [] [] |
707 wget | [] [] |
708 xchat | [] [] [] [] |
709 xkeyboard-config | [] |
710 xpad | [] [] [] |
711 +-------------------------------------------------+
712 ja ko ku ky lg lt lv mk mn ms mt nb ne nl nn no
713 52 24 2 2 1 3 0 2 3 21 0 15 1 97 5 1
714
715 nso or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv ta
716 +------------------------------------------------------+
717 GNUnet | |
718 a2ps | () [] [] [] [] [] [] |
719 aegis | () () |
720 ant-phone | [] [] |
721 anubis | [] [] [] |
722 ap-utils | () |
723 aspell | [] [] |
724 bash | [] [] [] |
725 batchelor | [] [] |
726 bfd | |
727 bibshelf | [] |
728 binutils | [] [] |
729 bison | [] [] [] [] [] |
730 bison-runtime | [] [] [] [] |
731 bluez-pin | [] [] [] [] [] [] [] [] [] |
732 cflow | [] |
733 clisp | [] |
734 console-tools | [] |
735 coreutils | [] [] [] [] |
736 cpio | [] [] [] |
737 cpplib | [] |
738 cryptonit | [] [] |
739 darkstat | [] [] [] [] [] [] |
740 dialog | [] [] [] [] [] [] [] [] [] |
741 diffutils | [] [] [] [] [] [] |
742 doodle | [] [] |
743 e2fsprogs | [] [] |
744 enscript | [] [] [] [] [] |
745 error | [] [] [] [] |
746 fetchmail | [] [] [] |
747 fileutils | [] [] [] [] [] |
748 findutils | [] [] [] [] [] [] |
749 flex | [] [] [] [] [] |
750 fslint | [] [] [] [] |
751 gas | |
752 gawk | [] [] [] [] |
753 gbiff | [] |
754 gcal | [] |
755 gcc | [] |
756 gettext-examples | [] [] [] [] [] [] [] [] |
757 gettext-runtime | [] [] [] [] [] [] [] [] |
758 gettext-tools | [] [] [] [] [] [] [] |
759 gimp-print | [] [] |
760 gip | [] [] [] [] |
761 gliv | [] [] [] [] |
762 glunarclock | [] [] [] [] [] [] |
763 gmult | [] [] [] [] |
764 gnubiff | () |
765 gnucash | () [] |
766 gnucash-glossary | [] [] [] |
767 gnuedu | |
768 gnulib | [] [] [] [] [] |
769 gnunet-gtk | [] |
770 gnutls | [] [] |
771 gpe-aerial | [] [] [] [] [] [] [] |
772 gpe-beam | [] [] [] [] [] [] [] |
773 gpe-calendar | [] |
774 gpe-clock | [] [] [] [] [] [] [] [] |
775 gpe-conf | [] [] [] [] [] [] [] |
776 gpe-contacts | [] [] [] [] [] |
777 gpe-edit | [] [] [] [] [] [] [] [] |
778 gpe-filemanager | [] [] |
779 gpe-go | [] [] [] [] [] [] |
780 gpe-login | [] [] [] [] [] [] [] [] |
781 gpe-ownerinfo | [] [] [] [] [] [] [] [] |
782 gpe-package | [] [] |
783 gpe-sketchbook | [] [] [] [] [] [] [] [] |
784 gpe-su | [] [] [] [] [] [] [] [] |
785 gpe-taskmanager | [] [] [] [] [] [] [] [] |
786 gpe-timesheet | [] [] [] [] [] [] [] [] |
787 gpe-today | [] [] [] [] [] [] [] [] |
788 gpe-todo | [] [] [] [] |
789 gphoto2 | [] [] [] [] [] |
790 gprof | [] [] [] |
791 gpsdrive | [] [] [] |
792 gramadoir | [] [] |
793 grep | [] [] [] [] [] [] [] [] |
794 gretl | [] |
795 gsasl | [] [] [] |
796 gss | [] [] [] |
797 gst-plugins | [] [] [] [] |
798 gst-plugins-base | [] |
799 gst-plugins-good | [] [] [] [] |
800 gstreamer | [] [] [] |
801 gtick | [] |
802 gtkam | [] [] [] [] |
803 gtkorphan | [] |
804 gtkspell | [] [] [] [] [] [] [] [] |
805 gutenprint | [] |
806 hello | [] [] [] [] [] [] [] [] |
807 id-utils | [] [] [] [] |
808 impost | [] |
809 indent | [] [] [] [] [] [] |
810 iso_3166 | [] [] [] [] [] [] |
811 iso_3166_2 | |
812 iso_4217 | [] [] [] [] |
813 iso_639 | [] [] [] [] |
814 jpilot | |
815 jtag | [] |
816 jwhois | [] [] [] [] |
817 kbd | [] [] [] |
818 keytouch | [] |
819 keytouch-editor | [] |
820 keytouch-keyboa... | [] |
821 latrine | [] [] |
822 ld | [] |
823 leafpad | [] [] [] [] [] [] |
824 libc | [] [] [] [] [] |
825 libexif | [] |
826 libextractor | [] [] |
827 libgpewidget | [] [] [] [] [] [] [] |
828 libgpg-error | [] [] |
829 libgphoto2 | [] |
830 libgphoto2_port | [] [] [] |
831 libgsasl | [] [] [] [] |
832 libiconv | [] [] |
833 libidn | [] [] () |
834 lifelines | [] [] |
835 lilypond | |
836 lingoteach | [] |
837 lynx | [] [] [] |
838 m4 | [] [] [] [] [] |
839 mailutils | [] [] [] [] |
840 make | [] [] [] [] |
841 man-db | [] [] |
842 minicom | [] [] [] [] [] |
843 mysecretdiary | [] [] [] [] |
844 nano | [] [] [] |
845 nano_1_0 | [] [] [] [] |
846 opcodes | [] [] |
847 parted | [] |
848 pilot-qof | [] |
849 psmisc | [] [] |
850 pwdutils | [] [] |
851 python | |
852 qof | [] [] |
853 radius | [] [] |
854 recode | [] [] [] [] [] [] [] |
855 rpm | [] [] [] [] |
856 screem | |
857 scrollkeeper | [] [] [] [] [] [] [] |
858 sed | [] [] [] [] [] [] [] [] [] |
859 sh-utils | [] [] [] |
860 shared-mime-info | [] [] [] [] [] |
861 sharutils | [] [] [] [] |
862 shishi | [] |
863 silky | [] |
864 skencil | [] [] [] |
865 sketch | [] [] [] |
866 solfege | [] |
867 soundtracker | [] [] |
868 sp | |
869 stardict | [] [] [] |
870 system-tools-ba... | [] [] [] [] [] [] [] [] [] |
871 tar | [] [] [] [] [] |
872 texinfo | [] [] [] [] |
873 textutils | [] [] [] |
874 tin | () |
875 tp-robot | [] |
876 tuxpaint | [] [] [] [] [] |
877 unicode-han-tra... | |
878 unicode-transla... | |
879 util-linux | [] [] [] [] |
880 vorbis-tools | [] [] |
881 wastesedge | |
882 wdiff | [] [] [] [] [] [] |
883 wget | [] [] [] [] |
884 xchat | [] [] [] [] [] [] [] |
885 xkeyboard-config | [] [] |
886 xpad | [] [] [] |
887 +------------------------------------------------------+
888 nso or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv ta
889 0 2 3 58 30 54 5 73 72 4 40 46 11 50 128 2
890
891 tg th tk tr uk ven vi wa xh zh_CN zh_HK zh_TW zu
892 +---------------------------------------------------+
893 GNUnet | [] | 2
894 a2ps | [] [] [] | 19
895 aegis | | 0
896 ant-phone | [] [] | 6
897 anubis | [] [] [] | 11
898 ap-utils | () [] | 4
899 aspell | [] [] [] | 15
900 bash | [] | 11
901 batchelor | [] [] | 9
902 bfd | | 1
903 bibshelf | [] | 7
904 binutils | [] [] [] | 9
905 bison | [] [] [] | 19
906 bison-runtime | [] [] [] | 15
907 bluez-pin | [] [] [] [] [] [] | 28
908 cflow | [] [] | 5
909 clisp | | 6
910 console-tools | [] [] | 5
911 coreutils | [] [] | 16
912 cpio | [] [] [] | 9
913 cpplib | [] [] [] [] | 11
914 cryptonit | | 5
915 darkstat | [] () () | 15
916 dialog | [] [] [] [] [] | 30
917 diffutils | [] [] [] [] | 28
918 doodle | [] | 6
919 e2fsprogs | [] [] | 10
920 enscript | [] [] [] | 16
921 error | [] [] [] [] | 18
922 fetchmail | [] [] | 12
923 fileutils | [] [] [] | 18
924 findutils | [] [] [] | 17
925 flex | [] [] | 15
926 fslint | [] | 9
927 gas | [] | 3
928 gawk | [] [] | 15
929 gbiff | [] | 5
930 gcal | [] | 5
931 gcc | [] [] [] | 6
932 gettext-examples | [] [] [] [] [] [] | 27
933 gettext-runtime | [] [] [] [] [] [] | 28
934 gettext-tools | [] [] [] [] [] | 19
935 gimp-print | [] [] | 12
936 gip | [] [] | 12
937 gliv | [] [] | 8
938 glunarclock | [] [] [] | 15
939 gmult | [] [] [] [] | 15
940 gnubiff | [] | 1
941 gnucash | () | 2
942 gnucash-glossary | [] [] | 9
943 gnuedu | [] | 2
944 gnulib | [] [] [] [] [] | 28
945 gnunet-gtk | | 1
946 gnutls | | 2
947 gpe-aerial | [] [] | 14
948 gpe-beam | [] [] | 14
949 gpe-calendar | [] | 3
950 gpe-clock | [] [] [] [] | 21
951 gpe-conf | [] [] | 14
952 gpe-contacts | [] [] | 10
953 gpe-edit | [] [] [] [] | 20
954 gpe-filemanager | [] | 6
955 gpe-go | [] [] | 15
956 gpe-login | [] [] [] [] [] | 21
957 gpe-ownerinfo | [] [] [] [] | 21
958 gpe-package | [] | 6
959 gpe-sketchbook | [] [] | 16
960 gpe-su | [] [] [] | 20
961 gpe-taskmanager | [] [] [] | 20
962 gpe-timesheet | [] [] [] [] | 18
963 gpe-today | [] [] [] [] [] | 21
964 gpe-todo | [] | 7
965 gphoto2 | [] [] [] [] | 20
966 gprof | [] [] | 11
967 gpsdrive | | 4
968 gramadoir | [] | 7
969 grep | [] [] [] [] | 34
970 gretl | | 4
971 gsasl | [] [] | 8
972 gss | [] | 5
973 gst-plugins | [] [] [] | 15
974 gst-plugins-base | [] [] [] | 9
975 gst-plugins-good | [] [] [] [] [] | 20
976 gstreamer | [] [] [] | 17
977 gtick | [] | 3
978 gtkam | [] | 13
979 gtkorphan | [] | 7
980 gtkspell | [] [] [] [] [] [] | 26
981 gutenprint | | 3
982 hello | [] [] [] [] [] | 37
983 id-utils | [] [] | 14
984 impost | [] | 4
985 indent | [] [] [] [] | 25
986 iso_3166 | [] [] [] [] | 16
987 iso_3166_2 | | 2
988 iso_4217 | [] [] | 14
989 iso_639 | [] | 14
990 jpilot | [] [] [] [] | 7
991 jtag | [] | 3
992 jwhois | [] [] [] | 13
993 kbd | [] [] | 12
994 keytouch | [] | 4
995 keytouch-editor | | 2
996 keytouch-keyboa... | [] | 3
997 latrine | [] [] | 8
998 ld | [] [] [] [] | 8
999 leafpad | [] [] [] [] | 23
1000 libc | [] [] [] | 23
1001 libexif | [] | 4
1002 libextractor | [] | 5
1003 libgpewidget | [] [] [] | 19
1004 libgpg-error | [] | 4
1005 libgphoto2 | [] | 8
1006 libgphoto2_port | [] [] [] | 11
1007 libgsasl | [] | 8
1008 libiconv | [] | 7
1009 libidn | [] [] | 10
1010 lifelines | | 4
1011 lilypond | | 2
1012 lingoteach | [] | 6
1013 lynx | [] [] [] | 15
1014 m4 | [] [] [] | 18
1015 mailutils | [] | 8
1016 make | [] [] [] | 20
1017 man-db | [] | 6
1018 minicom | [] | 14
1019 mysecretdiary | [] [] | 12
1020 nano | [] [] | 17
1021 nano_1_0 | [] [] [] | 18
1022 opcodes | [] [] | 10
1023 parted | [] [] [] | 10
1024 pilot-qof | [] | 3
1025 psmisc | [] | 10
1026 pwdutils | [] | 3
1027 python | | 0
1028 qof | [] | 4
1029 radius | [] | 6
1030 recode | [] [] [] | 25
1031 rpm | [] [] [] [] | 14
1032 screem | [] | 2
1033 scrollkeeper | [] [] [] [] | 26
1034 sed | [] [] [] | 22
1035 sh-utils | [] | 15
1036 shared-mime-info | [] [] [] [] | 24
1037 sharutils | [] [] [] | 23
1038 shishi | | 1
1039 silky | [] | 4
1040 skencil | [] | 7
1041 sketch | | 6
1042 solfege | | 2
1043 soundtracker | [] [] | 9
1044 sp | [] | 3
1045 stardict | [] [] [] [] | 11
1046 system-tools-ba... | [] [] [] [] [] [] [] | 37
1047 tar | [] [] [] [] | 20
1048 texinfo | [] [] [] | 15
1049 textutils | [] [] [] | 17
1050 tin | | 1
1051 tp-robot | [] [] [] | 10
1052 tuxpaint | [] [] [] | 16
1053 unicode-han-tra... | | 0
1054 unicode-transla... | | 2
1055 util-linux | [] [] [] | 20
1056 vorbis-tools | [] [] | 11
1057 wastesedge | | 1
1058 wdiff | [] [] | 22
1059 wget | [] [] [] | 19
1060 xchat | [] [] [] [] | 29
1061 xkeyboard-config | [] [] [] [] | 11
1062 xpad | [] [] [] | 14
1063 +---------------------------------------------------+
1064 77 teams tg th tk tr uk ven vi wa xh zh_CN zh_HK zh_TW zu
1065 170 domains 0 1 1 77 39 0 136 10 1 48 5 54 0 2028
1066
1067 Some counters in the preceding matrix are higher than the number of
1068visible blocks let us expect. This is because a few extra PO files are
1069used for implementing regional variants of languages, or language
1070dialects.
1071
1072 For a PO file in the matrix above to be effective, the package to
1073which it applies should also have been internationalized and
1074distributed as such by its maintainer. There might be an observable
1075lag between the mere existence a PO file and its wide availability in a
1076distribution.
1077
1078 If October 2006 seems to be old, you may fetch a more recent copy of
1079this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date
1080matrix with full percentage details can be found at
1081`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'.
1082
10831.6 Using `gettext' in new packages
1084===================================
1085
1086If you are writing a freely available program and want to
1087internationalize it you are welcome to use GNU `gettext' in your
1088package. Of course you have to respect the GNU Library General Public
1089License which covers the use of the GNU `gettext' library. This means
1090in particular that even non-free programs can use `libintl' as a shared
1091library, whereas only free software can use `libintl' as a static
1092library or use modified versions of `libintl'.
1093
1094 Once the sources are changed appropriately and the setup can handle
1095the use of `gettext' the only thing missing are the translations. The
1096Free Translation Project is also available for packages which are not
1097developed inside the GNU project. Therefore the information given above
1098applies also for every other Free Software Project. Contact
1099`translation@iro.umontreal.ca' to make the `.pot' files available to
1100the translation teams.
1101
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 000000000..950320941
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,85 @@
1Primary developers (0.9.x series):
2Christian Grothoff <christian@grothoff.org>
3Heikki Lindholm <holindho@cs.helsinki.fi>
4Nils Durner <durner@gnunet.org>
5Milan Bouchet-Valat <nalimilan@club.fr>
6
7Code contributions also came from:
8Adam Warrington [ UPnP ]
9Alex Harper [ OS X CPU load ]
10Andrew McDonald <andrew@mcdonald.org.uk> [ SHA-512]
11Antti Salonen
12Blake Matheny <bmatheny@mobocracy.net>
13Clytie Siddall <clytie@riverland.net.au>
14David Kuehling <dvdkhlng@gmx.de>
15Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
16Eric Haumant
17Eric Noack <corvus-gnunet@cybertrench.com>
18Felix von Leitner [ diet libc snprintf for win32 ]
19Gerd Knorr <kraxel@bytesex.org>
20Glenn McGrath <bug1@iinet.net.au>
21Hendrik Pagenhardt <Hendrik.Pagenhardt@gmx.net>
22Heikki Lindholm <holindho@cs.helsinki.fi>
23Igor Wronsky <iwronsky@users.sourceforge.net>
24Ioana Patrascu <ioanapatrascu@yahoo.com>
25<january@hushmail.com>
26Jake Dust <jakedust@gmail.com>
27James Blackwell <jblack@linuxguru.net>
28Jean-Luc Cooke <jlcooke@certainkey.com> [ SHA-512]
29Jussi Eloranta <eloranta@cc.jyu.fi>
30Jürgen Appel <jappel@linux01.gwdg.de>
31Kevin Vandersloot <kfv101@psu.edu> [original code of gnome-system-monitor]
32Krista Bennett Grothoff <krista@grothoff.org>
33Kyle McMartin <kyle@debian.org> [ SHA-512]
34Larry Waldo
35Ludovic Courtès <ludo@chbouib.org>
36Marko Räihä
37Michael John Wensley <michael@wensley.org.uk>
38Nathan Evans <nevans6@du.edu>
39Paul Ruth <ruth@cs.purdue.edu>
40Renaldo Ferreira <rf@cs.purdue.edu>
41Risto Saarelma
42Roman Zippel
43Romain Lievin
44sheda <uc.sheda@laposte.net>
45Simo Viitanen
46Tiberius Stef <tstef@cs.purdue.edu>
47Tomi Tukiainen
48Tuomas Toivonen
49Tzvetan Horozov <chorozov@gmail.com>
50Uli Luckas <luckas@musoft.de>
51Vasil Dimov <vd@datamax.bg>
52Werner Koch <libgcrypt@g10code.com> [original code of libgcrypt]
53
54Translations (webpage, documentation, as far as known):
55Chinese : Di Ma
56Danish : Jens Palsberg <palsberg@cs.ucla.edu>
57Deutsch : Christian Grothoff <christian@grothoff.org>,
58 Nils Durner <durner@gnunet.org>
59French : Mathieu <mollo@bghflt.org>,
60 Eric Haumant
61 Milan <nalimilan@club-internet.fr>
62Japanese : Hiroshi Yamauchi <yamauchi@cs.purdue.edu>
63Polish : Adam Welc <welc@cs.purdue.edu>
64Romaneste : Bogdan Carbunar <carbunar@cs.purdue.edu>
65Kinyarwanda: Steven Michael Murphy <murf@e-tools.com>
66Vietnamese : Phan Vinh Thinh <teppi82@gmail.com> and Clytie Siddall <clytie@riverland.net.au>
67Swedish : Daniel Nylander <po@danielnylander.se>
68Spanish : Miguel Angel Arruga Vivas <miguel.13@telefonica.net>
69Turkish : Nilgün Belma Bugüner <nilgun@buguner.name.tr>
70
71Logos:
72GNU in Net : Christian Muellner <chris@flop.de>
73GNU with Net : Christian Muellner <chris@flop.de>
74AFS Face : Alex Jones <alexrjones@ntlworld.com>
75new GNU in Net: Nicklas Larsson <whybill@gmail.com>
76
77Maintainers:
78FreeBSD : Kirill Ponomarew <ponomarew@oberon.net>
79Debian GNU/Linux: Daniel Baumann <daniel.baumann@panthera-systems.net> and
80 Arnaud Kyheng <Arnaud.Kyheng@free.fr>
81OS X : Jussi Eloranta <eloranta@cc.jyu.fi>
82
83
84If you have contributed and are not listed here, please
85notify one of the maintainers in order to be added.
diff --git a/COPYING b/COPYING
new file mode 100644
index 000000000..94a9ed024
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
1 GNU GENERAL PUBLIC LICENSE
2 Version 3, 29 June 2007
3
4 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5 Everyone is permitted to copy and distribute verbatim copies
6 of this license document, but changing it is not allowed.
7
8 Preamble
9
10 The GNU General Public License is a free, copyleft license for
11software and other kinds of works.
12
13 The licenses for most software and other practical works are designed
14to take away your freedom to share and change the works. By contrast,
15the GNU General Public License is intended to guarantee your freedom to
16share and change all versions of a program--to make sure it remains free
17software for all its users. We, the Free Software Foundation, use the
18GNU General Public License for most of our software; it applies also to
19any other work released this way by its authors. You can apply it to
20your programs, too.
21
22 When we speak of free software, we are referring to freedom, not
23price. Our General Public Licenses are designed to make sure that you
24have the freedom to distribute copies of free software (and charge for
25them if you wish), that you receive source code or can get it if you
26want it, that you can change the software or use pieces of it in new
27free programs, and that you know you can do these things.
28
29 To protect your rights, we need to prevent others from denying you
30these rights or asking you to surrender the rights. Therefore, you have
31certain responsibilities if you distribute copies of the software, or if
32you modify it: responsibilities to respect the freedom of others.
33
34 For example, if you distribute copies of such a program, whether
35gratis or for a fee, you must pass on to the recipients the same
36freedoms that you received. You must make sure that they, too, receive
37or can get the source code. And you must show them these terms so they
38know their rights.
39
40 Developers that use the GNU GPL protect your rights with two steps:
41(1) assert copyright on the software, and (2) offer you this License
42giving you legal permission to copy, distribute and/or modify it.
43
44 For the developers' and authors' protection, the GPL clearly explains
45that there is no warranty for this free software. For both users' and
46authors' sake, the GPL requires that modified versions be marked as
47changed, so that their problems will not be attributed erroneously to
48authors of previous versions.
49
50 Some devices are designed to deny users access to install or run
51modified versions of the software inside them, although the manufacturer
52can do so. This is fundamentally incompatible with the aim of
53protecting users' freedom to change the software. The systematic
54pattern of such abuse occurs in the area of products for individuals to
55use, which is precisely where it is most unacceptable. Therefore, we
56have designed this version of the GPL to prohibit the practice for those
57products. If such problems arise substantially in other domains, we
58stand ready to extend this provision to those domains in future versions
59of the GPL, as needed to protect the freedom of users.
60
61 Finally, every program is threatened constantly by software patents.
62States should not allow patents to restrict development and use of
63software on general-purpose computers, but in those that do, we wish to
64avoid the special danger that patents applied to a free program could
65make it effectively proprietary. To prevent this, the GPL assures that
66patents cannot be used to render the program non-free.
67
68 The precise terms and conditions for copying, distribution and
69modification follow.
70
71 TERMS AND CONDITIONS
72
73 0. Definitions.
74
75 "This License" refers to version 3 of the GNU General Public License.
76
77 "Copyright" also means copyright-like laws that apply to other kinds of
78works, such as semiconductor masks.
79
80 "The Program" refers to any copyrightable work licensed under this
81License. Each licensee is addressed as "you". "Licensees" and
82"recipients" may be individuals or organizations.
83
84 To "modify" a work means to copy from or adapt all or part of the work
85in a fashion requiring copyright permission, other than the making of an
86exact copy. The resulting work is called a "modified version" of the
87earlier work or a work "based on" the earlier work.
88
89 A "covered work" means either the unmodified Program or a work based
90on the Program.
91
92 To "propagate" a work means to do anything with it that, without
93permission, would make you directly or secondarily liable for
94infringement under applicable copyright law, except executing it on a
95computer or modifying a private copy. Propagation includes copying,
96distribution (with or without modification), making available to the
97public, and in some countries other activities as well.
98
99 To "convey" a work means any kind of propagation that enables other
100parties to make or receive copies. Mere interaction with a user through
101a computer network, with no transfer of a copy, is not conveying.
102
103 An interactive user interface displays "Appropriate Legal Notices"
104to the extent that it includes a convenient and prominently visible
105feature that (1) displays an appropriate copyright notice, and (2)
106tells the user that there is no warranty for the work (except to the
107extent that warranties are provided), that licensees may convey the
108work under this License, and how to view a copy of this License. If
109the interface presents a list of user commands or options, such as a
110menu, a prominent item in the list meets this criterion.
111
112 1. Source Code.
113
114 The "source code" for a work means the preferred form of the work
115for making modifications to it. "Object code" means any non-source
116form of a work.
117
118 A "Standard Interface" means an interface that either is an official
119standard defined by a recognized standards body, or, in the case of
120interfaces specified for a particular programming language, one that
121is widely used among developers working in that language.
122
123 The "System Libraries" of an executable work include anything, other
124than the work as a whole, that (a) is included in the normal form of
125packaging a Major Component, but which is not part of that Major
126Component, and (b) serves only to enable use of the work with that
127Major Component, or to implement a Standard Interface for which an
128implementation is available to the public in source code form. A
129"Major Component", in this context, means a major essential component
130(kernel, window system, and so on) of the specific operating system
131(if any) on which the executable work runs, or a compiler used to
132produce the work, or an object code interpreter used to run it.
133
134 The "Corresponding Source" for a work in object code form means all
135the source code needed to generate, install, and (for an executable
136work) run the object code and to modify the work, including scripts to
137control those activities. However, it does not include the work's
138System Libraries, or general-purpose tools or generally available free
139programs which are used unmodified in performing those activities but
140which are not part of the work. For example, Corresponding Source
141includes interface definition files associated with source files for
142the work, and the source code for shared libraries and dynamically
143linked subprograms that the work is specifically designed to require,
144such as by intimate data communication or control flow between those
145subprograms and other parts of the work.
146
147 The Corresponding Source need not include anything that users
148can regenerate automatically from other parts of the Corresponding
149Source.
150
151 The Corresponding Source for a work in source code form is that
152same work.
153
154 2. Basic Permissions.
155
156 All rights granted under this License are granted for the term of
157copyright on the Program, and are irrevocable provided the stated
158conditions are met. This License explicitly affirms your unlimited
159permission to run the unmodified Program. The output from running a
160covered work is covered by this License only if the output, given its
161content, constitutes a covered work. This License acknowledges your
162rights of fair use or other equivalent, as provided by copyright law.
163
164 You may make, run and propagate covered works that you do not
165convey, without conditions so long as your license otherwise remains
166in force. You may convey covered works to others for the sole purpose
167of having them make modifications exclusively for you, or provide you
168with facilities for running those works, provided that you comply with
169the terms of this License in conveying all material for which you do
170not control copyright. Those thus making or running the covered works
171for you must do so exclusively on your behalf, under your direction
172and control, on terms that prohibit them from making any copies of
173your copyrighted material outside their relationship with you.
174
175 Conveying under any other circumstances is permitted solely under
176the conditions stated below. Sublicensing is not allowed; section 10
177makes it unnecessary.
178
179 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180
181 No covered work shall be deemed part of an effective technological
182measure under any applicable law fulfilling obligations under article
18311 of the WIPO copyright treaty adopted on 20 December 1996, or
184similar laws prohibiting or restricting circumvention of such
185measures.
186
187 When you convey a covered work, you waive any legal power to forbid
188circumvention of technological measures to the extent such circumvention
189is effected by exercising rights under this License with respect to
190the covered work, and you disclaim any intention to limit operation or
191modification of the work as a means of enforcing, against the work's
192users, your or third parties' legal rights to forbid circumvention of
193technological measures.
194
195 4. Conveying Verbatim Copies.
196
197 You may convey verbatim copies of the Program's source code as you
198receive it, in any medium, provided that you conspicuously and
199appropriately publish on each copy an appropriate copyright notice;
200keep intact all notices stating that this License and any
201non-permissive terms added in accord with section 7 apply to the code;
202keep intact all notices of the absence of any warranty; and give all
203recipients a copy of this License along with the Program.
204
205 You may charge any price or no price for each copy that you convey,
206and you may offer support or warranty protection for a fee.
207
208 5. Conveying Modified Source Versions.
209
210 You may convey a work based on the Program, or the modifications to
211produce it from the Program, in the form of source code under the
212terms of section 4, provided that you also meet all of these conditions:
213
214 a) The work must carry prominent notices stating that you modified
215 it, and giving a relevant date.
216
217 b) The work must carry prominent notices stating that it is
218 released under this License and any conditions added under section
219 7. This requirement modifies the requirement in section 4 to
220 "keep intact all notices".
221
222 c) You must license the entire work, as a whole, under this
223 License to anyone who comes into possession of a copy. This
224 License will therefore apply, along with any applicable section 7
225 additional terms, to the whole of the work, and all its parts,
226 regardless of how they are packaged. This License gives no
227 permission to license the work in any other way, but it does not
228 invalidate such permission if you have separately received it.
229
230 d) If the work has interactive user interfaces, each must display
231 Appropriate Legal Notices; however, if the Program has interactive
232 interfaces that do not display Appropriate Legal Notices, your
233 work need not make them do so.
234
235 A compilation of a covered work with other separate and independent
236works, which are not by their nature extensions of the covered work,
237and which are not combined with it such as to form a larger program,
238in or on a volume of a storage or distribution medium, is called an
239"aggregate" if the compilation and its resulting copyright are not
240used to limit the access or legal rights of the compilation's users
241beyond what the individual works permit. Inclusion of a covered work
242in an aggregate does not cause this License to apply to the other
243parts of the aggregate.
244
245 6. Conveying Non-Source Forms.
246
247 You may convey a covered work in object code form under the terms
248of sections 4 and 5, provided that you also convey the
249machine-readable Corresponding Source under the terms of this License,
250in one of these ways:
251
252 a) Convey the object code in, or embodied in, a physical product
253 (including a physical distribution medium), accompanied by the
254 Corresponding Source fixed on a durable physical medium
255 customarily used for software interchange.
256
257 b) Convey the object code in, or embodied in, a physical product
258 (including a physical distribution medium), accompanied by a
259 written offer, valid for at least three years and valid for as
260 long as you offer spare parts or customer support for that product
261 model, to give anyone who possesses the object code either (1) a
262 copy of the Corresponding Source for all the software in the
263 product that is covered by this License, on a durable physical
264 medium customarily used for software interchange, for a price no
265 more than your reasonable cost of physically performing this
266 conveying of source, or (2) access to copy the
267 Corresponding Source from a network server at no charge.
268
269 c) Convey individual copies of the object code with a copy of the
270 written offer to provide the Corresponding Source. This
271 alternative is allowed only occasionally and noncommercially, and
272 only if you received the object code with such an offer, in accord
273 with subsection 6b.
274
275 d) Convey the object code by offering access from a designated
276 place (gratis or for a charge), and offer equivalent access to the
277 Corresponding Source in the same way through the same place at no
278 further charge. You need not require recipients to copy the
279 Corresponding Source along with the object code. If the place to
280 copy the object code is a network server, the Corresponding Source
281 may be on a different server (operated by you or a third party)
282 that supports equivalent copying facilities, provided you maintain
283 clear directions next to the object code saying where to find the
284 Corresponding Source. Regardless of what server hosts the
285 Corresponding Source, you remain obligated to ensure that it is
286 available for as long as needed to satisfy these requirements.
287
288 e) Convey the object code using peer-to-peer transmission, provided
289 you inform other peers where the object code and Corresponding
290 Source of the work are being offered to the general public at no
291 charge under subsection 6d.
292
293 A separable portion of the object code, whose source code is excluded
294from the Corresponding Source as a System Library, need not be
295included in conveying the object code work.
296
297 A "User Product" is either (1) a "consumer product", which means any
298tangible personal property which is normally used for personal, family,
299or household purposes, or (2) anything designed or sold for incorporation
300into a dwelling. In determining whether a product is a consumer product,
301doubtful cases shall be resolved in favor of coverage. For a particular
302product received by a particular user, "normally used" refers to a
303typical or common use of that class of product, regardless of the status
304of the particular user or of the way in which the particular user
305actually uses, or expects or is expected to use, the product. A product
306is a consumer product regardless of whether the product has substantial
307commercial, industrial or non-consumer uses, unless such uses represent
308the only significant mode of use of the product.
309
310 "Installation Information" for a User Product means any methods,
311procedures, authorization keys, or other information required to install
312and execute modified versions of a covered work in that User Product from
313a modified version of its Corresponding Source. The information must
314suffice to ensure that the continued functioning of the modified object
315code is in no case prevented or interfered with solely because
316modification has been made.
317
318 If you convey an object code work under this section in, or with, or
319specifically for use in, a User Product, and the conveying occurs as
320part of a transaction in which the right of possession and use of the
321User Product is transferred to the recipient in perpetuity or for a
322fixed term (regardless of how the transaction is characterized), the
323Corresponding Source conveyed under this section must be accompanied
324by the Installation Information. But this requirement does not apply
325if neither you nor any third party retains the ability to install
326modified object code on the User Product (for example, the work has
327been installed in ROM).
328
329 The requirement to provide Installation Information does not include a
330requirement to continue to provide support service, warranty, or updates
331for a work that has been modified or installed by the recipient, or for
332the User Product in which it has been modified or installed. Access to a
333network may be denied when the modification itself materially and
334adversely affects the operation of the network or violates the rules and
335protocols for communication across the network.
336
337 Corresponding Source conveyed, and Installation Information provided,
338in accord with this section must be in a format that is publicly
339documented (and with an implementation available to the public in
340source code form), and must require no special password or key for
341unpacking, reading or copying.
342
343 7. Additional Terms.
344
345 "Additional permissions" are terms that supplement the terms of this
346License by making exceptions from one or more of its conditions.
347Additional permissions that are applicable to the entire Program shall
348be treated as though they were included in this License, to the extent
349that they are valid under applicable law. If additional permissions
350apply only to part of the Program, that part may be used separately
351under those permissions, but the entire Program remains governed by
352this License without regard to the additional permissions.
353
354 When you convey a copy of a covered work, you may at your option
355remove any additional permissions from that copy, or from any part of
356it. (Additional permissions may be written to require their own
357removal in certain cases when you modify the work.) You may place
358additional permissions on material, added by you to a covered work,
359for which you have or can give appropriate copyright permission.
360
361 Notwithstanding any other provision of this License, for material you
362add to a covered work, you may (if authorized by the copyright holders of
363that material) supplement the terms of this License with terms:
364
365 a) Disclaiming warranty or limiting liability differently from the
366 terms of sections 15 and 16 of this License; or
367
368 b) Requiring preservation of specified reasonable legal notices or
369 author attributions in that material or in the Appropriate Legal
370 Notices displayed by works containing it; or
371
372 c) Prohibiting misrepresentation of the origin of that material, or
373 requiring that modified versions of such material be marked in
374 reasonable ways as different from the original version; or
375
376 d) Limiting the use for publicity purposes of names of licensors or
377 authors of the material; or
378
379 e) Declining to grant rights under trademark law for use of some
380 trade names, trademarks, or service marks; or
381
382 f) Requiring indemnification of licensors and authors of that
383 material by anyone who conveys the material (or modified versions of
384 it) with contractual assumptions of liability to the recipient, for
385 any liability that these contractual assumptions directly impose on
386 those licensors and authors.
387
388 All other non-permissive additional terms are considered "further
389restrictions" within the meaning of section 10. If the Program as you
390received it, or any part of it, contains a notice stating that it is
391governed by this License along with a term that is a further
392restriction, you may remove that term. If a license document contains
393a further restriction but permits relicensing or conveying under this
394License, you may add to a covered work material governed by the terms
395of that license document, provided that the further restriction does
396not survive such relicensing or conveying.
397
398 If you add terms to a covered work in accord with this section, you
399must place, in the relevant source files, a statement of the
400additional terms that apply to those files, or a notice indicating
401where to find the applicable terms.
402
403 Additional terms, permissive or non-permissive, may be stated in the
404form of a separately written license, or stated as exceptions;
405the above requirements apply either way.
406
407 8. Termination.
408
409 You may not propagate or modify a covered work except as expressly
410provided under this License. Any attempt otherwise to propagate or
411modify it is void, and will automatically terminate your rights under
412this License (including any patent licenses granted under the third
413paragraph of section 11).
414
415 However, if you cease all violation of this License, then your
416license from a particular copyright holder is reinstated (a)
417provisionally, unless and until the copyright holder explicitly and
418finally terminates your license, and (b) permanently, if the copyright
419holder fails to notify you of the violation by some reasonable means
420prior to 60 days after the cessation.
421
422 Moreover, your license from a particular copyright holder is
423reinstated permanently if the copyright holder notifies you of the
424violation by some reasonable means, this is the first time you have
425received notice of violation of this License (for any work) from that
426copyright holder, and you cure the violation prior to 30 days after
427your receipt of the notice.
428
429 Termination of your rights under this section does not terminate the
430licenses of parties who have received copies or rights from you under
431this License. If your rights have been terminated and not permanently
432reinstated, you do not qualify to receive new licenses for the same
433material under section 10.
434
435 9. Acceptance Not Required for Having Copies.
436
437 You are not required to accept this License in order to receive or
438run a copy of the Program. Ancillary propagation of a covered work
439occurring solely as a consequence of using peer-to-peer transmission
440to receive a copy likewise does not require acceptance. However,
441nothing other than this License grants you permission to propagate or
442modify any covered work. These actions infringe copyright if you do
443not accept this License. Therefore, by modifying or propagating a
444covered work, you indicate your acceptance of this License to do so.
445
446 10. Automatic Licensing of Downstream Recipients.
447
448 Each time you convey a covered work, the recipient automatically
449receives a license from the original licensors, to run, modify and
450propagate that work, subject to this License. You are not responsible
451for enforcing compliance by third parties with this License.
452
453 An "entity transaction" is a transaction transferring control of an
454organization, or substantially all assets of one, or subdividing an
455organization, or merging organizations. If propagation of a covered
456work results from an entity transaction, each party to that
457transaction who receives a copy of the work also receives whatever
458licenses to the work the party's predecessor in interest had or could
459give under the previous paragraph, plus a right to possession of the
460Corresponding Source of the work from the predecessor in interest, if
461the predecessor has it or can get it with reasonable efforts.
462
463 You may not impose any further restrictions on the exercise of the
464rights granted or affirmed under this License. For example, you may
465not impose a license fee, royalty, or other charge for exercise of
466rights granted under this License, and you may not initiate litigation
467(including a cross-claim or counterclaim in a lawsuit) alleging that
468any patent claim is infringed by making, using, selling, offering for
469sale, or importing the Program or any portion of it.
470
471 11. Patents.
472
473 A "contributor" is a copyright holder who authorizes use under this
474License of the Program or a work on which the Program is based. The
475work thus licensed is called the contributor's "contributor version".
476
477 A contributor's "essential patent claims" are all patent claims
478owned or controlled by the contributor, whether already acquired or
479hereafter acquired, that would be infringed by some manner, permitted
480by this License, of making, using, or selling its contributor version,
481but do not include claims that would be infringed only as a
482consequence of further modification of the contributor version. For
483purposes of this definition, "control" includes the right to grant
484patent sublicenses in a manner consistent with the requirements of
485this License.
486
487 Each contributor grants you a non-exclusive, worldwide, royalty-free
488patent license under the contributor's essential patent claims, to
489make, use, sell, offer for sale, import and otherwise run, modify and
490propagate the contents of its contributor version.
491
492 In the following three paragraphs, a "patent license" is any express
493agreement or commitment, however denominated, not to enforce a patent
494(such as an express permission to practice a patent or covenant not to
495sue for patent infringement). To "grant" such a patent license to a
496party means to make such an agreement or commitment not to enforce a
497patent against the party.
498
499 If you convey a covered work, knowingly relying on a patent license,
500and the Corresponding Source of the work is not available for anyone
501to copy, free of charge and under the terms of this License, through a
502publicly available network server or other readily accessible means,
503then you must either (1) cause the Corresponding Source to be so
504available, or (2) arrange to deprive yourself of the benefit of the
505patent license for this particular work, or (3) arrange, in a manner
506consistent with the requirements of this License, to extend the patent
507license to downstream recipients. "Knowingly relying" means you have
508actual knowledge that, but for the patent license, your conveying the
509covered work in a country, or your recipient's use of the covered work
510in a country, would infringe one or more identifiable patents in that
511country that you have reason to believe are valid.
512
513 If, pursuant to or in connection with a single transaction or
514arrangement, you convey, or propagate by procuring conveyance of, a
515covered work, and grant a patent license to some of the parties
516receiving the covered work authorizing them to use, propagate, modify
517or convey a specific copy of the covered work, then the patent license
518you grant is automatically extended to all recipients of the covered
519work and works based on it.
520
521 A patent license is "discriminatory" if it does not include within
522the scope of its coverage, prohibits the exercise of, or is
523conditioned on the non-exercise of one or more of the rights that are
524specifically granted under this License. You may not convey a covered
525work if you are a party to an arrangement with a third party that is
526in the business of distributing software, under which you make payment
527to the third party based on the extent of your activity of conveying
528the work, and under which the third party grants, to any of the
529parties who would receive the covered work from you, a discriminatory
530patent license (a) in connection with copies of the covered work
531conveyed by you (or copies made from those copies), or (b) primarily
532for and in connection with specific products or compilations that
533contain the covered work, unless you entered into that arrangement,
534or that patent license was granted, prior to 28 March 2007.
535
536 Nothing in this License shall be construed as excluding or limiting
537any implied license or other defenses to infringement that may
538otherwise be available to you under applicable patent law.
539
540 12. No Surrender of Others' Freedom.
541
542 If conditions are imposed on you (whether by court order, agreement or
543otherwise) that contradict the conditions of this License, they do not
544excuse you from the conditions of this License. If you cannot convey a
545covered work so as to satisfy simultaneously your obligations under this
546License and any other pertinent obligations, then as a consequence you may
547not convey it at all. For example, if you agree to terms that obligate you
548to collect a royalty for further conveying from those to whom you convey
549the Program, the only way you could satisfy both those terms and this
550License would be to refrain entirely from conveying the Program.
551
552 13. Use with the GNU Affero General Public License.
553
554 Notwithstanding any other provision of this License, you have
555permission to link or combine any covered work with a work licensed
556under version 3 of the GNU Affero General Public License into a single
557combined work, and to convey the resulting work. The terms of this
558License will continue to apply to the part which is the covered work,
559but the special requirements of the GNU Affero General Public License,
560section 13, concerning interaction through a network will apply to the
561combination as such.
562
563 14. Revised Versions of this License.
564
565 The Free Software Foundation may publish revised and/or new versions of
566the GNU General Public License from time to time. Such new versions will
567be similar in spirit to the present version, but may differ in detail to
568address new problems or concerns.
569
570 Each version is given a distinguishing version number. If the
571Program specifies that a certain numbered version of the GNU General
572Public License "or any later version" applies to it, you have the
573option of following the terms and conditions either of that numbered
574version or of any later version published by the Free Software
575Foundation. If the Program does not specify a version number of the
576GNU General Public License, you may choose any version ever published
577by the Free Software Foundation.
578
579 If the Program specifies that a proxy can decide which future
580versions of the GNU General Public License can be used, that proxy's
581public statement of acceptance of a version permanently authorizes you
582to choose that version for the Program.
583
584 Later license versions may give you additional or different
585permissions. However, no additional obligations are imposed on any
586author or copyright holder as a result of your choosing to follow a
587later version.
588
589 15. Disclaimer of Warranty.
590
591 THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599
600 16. Limitation of Liability.
601
602 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610SUCH DAMAGES.
611
612 17. Interpretation of Sections 15 and 16.
613
614 If the disclaimer of warranty and limitation of liability provided
615above cannot be given local legal effect according to their terms,
616reviewing courts shall apply local law that most closely approximates
617an absolute waiver of all civil liability in connection with the
618Program, unless a warranty or assumption of liability accompanies a
619copy of the Program in return for a fee.
620
621 END OF TERMS AND CONDITIONS
622
623 How to Apply These Terms to Your New Programs
624
625 If you develop a new program, and you want it to be of the greatest
626possible use to the public, the best way to achieve this is to make it
627free software which everyone can redistribute and change under these terms.
628
629 To do so, attach the following notices to the program. It is safest
630to attach them to the start of each source file to most effectively
631state the exclusion of warranty; and each file should have at least
632the "copyright" line and a pointer to where the full notice is found.
633
634 <one line to give the program's name and a brief idea of what it does.>
635 Copyright (C) <year> <name of author>
636
637 This program is free software: you can redistribute it and/or modify
638 it under the terms of the GNU General Public License as published by
639 the Free Software Foundation, either version 3 of the License, or
640 (at your option) any later version.
641
642 This program is distributed in the hope that it will be useful,
643 but WITHOUT ANY WARRANTY; without even the implied warranty of
644 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 GNU General Public License for more details.
646
647 You should have received a copy of the GNU General Public License
648 along with this program. If not, see <http://www.gnu.org/licenses/>.
649
650Also add information on how to contact you by electronic and paper mail.
651
652 If the program does terminal interaction, make it output a short
653notice like this when it starts in an interactive mode:
654
655 <program> Copyright (C) <year> <name of author>
656 This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 This is free software, and you are welcome to redistribute it
658 under certain conditions; type `show c' for details.
659
660The hypothetical commands `show w' and `show c' should show the appropriate
661parts of the General Public License. Of course, your program's commands
662might be different; for a GUI interface, you would use an "about box".
663
664 You should also get your employer (if you work as a programmer) or school,
665if any, to sign a "copyright disclaimer" for the program, if necessary.
666For more information on this, and how to apply and follow the GNU GPL, see
667<http://www.gnu.org/licenses/>.
668
669 The GNU General Public License does not permit incorporating your program
670into proprietary programs. If your program is a subroutine library, you
671may consider it more useful to permit linking proprietary applications with
672the library. If this is what you want to do, use the GNU Lesser General
673Public License instead of this License. But first, please read
674<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 000000000..1bf887e46
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,1704 @@
1Sun Feb 1 19:51:40 MST 2009
2 Fixed Mantis #1429 (struct padding could cause sizeof
3 to be different on AMD64, using gcc-ism "packed" to
4 avoid this problem).
5
6Sun Feb 1 00:37:16 MST 2009
7 Fixed problem in DHT client protocol that could cause
8 PUT requests from clients to be (frequently) lost.
9
10Sun Nov 2 16:06:47 MST 2008
11 Fixed problem with MySQL disconnects in one module
12 impacting MySQL correctness in another module (caused
13 crashes).
14
15Sat Aug 16 00:18:34 CEST 2008
16 Improved keyword extraction
17 Fixed expiration time of keywords
18 Releasing 0.8.0b.
19
20Sun Jul 20 15:27:11 MDT 2008
21 Releasing 0.8.0a.
22
23Thu Jul 10 00:59:31 MDT 2008
24 Fixed bug where datastore resizing would not
25 result in bloomfilter update during gnunet-update.
26
27Sat Jun 28 23:43:00 MDT 2008
28 Fixed bug preventing namespace advertisements from
29 being processed.
30
31Sat Jun 14 00:54:39 MDT 2008
32 Releasing 0.8.0.
33
34Fri Jun 13 23:51:00 MDT 2008
35 GNUnet now compiles on OpenBSD.
36
37Wed Jun 11 22:17:09 MDT 2008
38 Made state of gnunet-auto-share persistent.
39 Added support for multiple directories. Improved
40 FSUI/ECRS APIs to reduce the number of threads needed
41 for probing. Increased number of concurrent probes
42 allowed.
43
44Sat Jun 7 17:54:49 MDT 2008
45 Simplified namespaces a lot. Shorter timeouts for
46 trying to connect to gnunetd to prevent interactive
47 apps from blocking too long when gnunetd is not
48 running.
49
50Sun Jun 1 21:11:54 MDT 2008
51 Releasing 0.8.0pre1.
52
53Sun Jun 1 13:41:27 MDT 2008
54 Split of libgnunetpseudonym from libgnunetnamespace
55 (with major API extension and changes).
56
57Tue May 6 04:10:02 MDT 2008
58 Added simple sanity check for [MODULES] values.
59 Added "-s" and "-q" options to gnunet-peer-info.
60
61Thu Apr 24 00:05:17 MDT 2008
62 Simplified FSUI stop/abort/pause/resume API calls
63 (no need to pass FSUI context anymore).
64
65Mon Apr 21 21:05:20 MDT 2008
66 Adding buffered IO for FSUI's serialize and
67 deserialize code.
68
69Sun Apr 20 20:01:20 MDT 2008
70 Fixed bug in HTTP transport causing lonely messages
71 (responses to GET) not to be delivered.
72
73Mon Mar 24 21:15:36 MDT 2008
74 Fixed various problems with downloading locally
75 indexed large files (downloading large files from
76 other peers should not have been a problem).
77
78Sun Mar 2 15:33:41 MST 2008
79 Added option to allow user to disable IPv6 support.
80 Releasing 0.8.0pre0.
81
82Sat Mar 1 21:14:02 MST 2008
83 Fixed some dstore performance issues.
84 Made transports alternate between trying IPv4 and IPv6
85 if both are available (since one of them maybe
86 misconfigured).
87
88Mon Feb 25 23:25:48 MST 2008
89 Cleanup of the DNS code: removed GNUNET_IPvXAddress
90 and GNUNET_PRIP; centralized all DNS lookup code in
91 util/network/dns.c; improved IPv6 support for
92 network-client code.
93
94Mon Feb 25 00:01:27 MST 2008
95 Added asynchronous search and download methods for
96 ECRS library. FSUI now can do with only one thread
97 per search or download (until now, we had two
98 threads per search / download).
99
100Tue Feb 19 20:35:28 MST 2008
101 Updated database schemata to support O(1) operations
102 even if there are N files under the same keywords.
103 This breaks database backwards compatibility (and
104 no migration code is provided).
105
106Mon Feb 18 19:47:37 MST 2008
107 Added new options -u and -s to gnunet-insert.
108
109Sat Feb 16 21:37:33 MST 2008
110 Implemented gnunet-auto-share for automatic
111 sharing of directories.
112
113Thu Feb 14 01:02:32 MST 2008
114 Made HTTP transport work over IPv6 as well.
115
116Wed Feb 13 22:59:07 MST 2008
117 Modified mySQL and SQLite datastores to return diverse
118 result sets during (partial) hash-based get iterations
119 (should result in more diverse keyword result sets).
120
121Tue Feb 12 23:54:34 MST 2008
122 First shot at integrated hostlist HTTP server based
123 on libmicrohttpd.
124
125Sat Feb 9 22:06:23 MST 2008
126 Minor changes to the ECRS/FSUI APIs for searches
127 (no more timeouts and/or max-results). Clients who
128 need these features could easily implement them
129 directly (and they are not really useful to begin
130 with).
131 Also, the IPv4 and IPv6 protocols are being integrated
132 so that we only listen to one port (running both IPv4
133 and IPv6 over the same port). This break transport
134 compatibility, but given that we're breaking protocol
135 compatibility for file-sharing already, this may
136 actually be a bit of a good thing (since it will now
137 be possible to tell if peers running the new GAP code
138 are connected to other peers running the new GAP code).
139
140Sun Feb 3 13:17:09 MST 2008
141 Dramatic changes to the GAP implementation (breaking
142 protocol compatibility). Essentially, we can save
143 a few bytes in each reply. More importantly, the new
144 code allows the searching client to specify a set of
145 replies that are not desired (hopefully helping to
146 dramatically increase the diversity of search replies
147 obtained over time). Note that the actual encoding
148 and databases are not affected (just P2P protocol).
149 The update is not complete yet, but should compile.
150
151Tue Jan 8 20:07:20 MST 2008
152 Added option for testing ("make check") to use weak(er)
153 PRNG for key generation (thanks to Werner Koch for
154 pointing out how to do it).
155
156Thu Dec 22 20:10:37 MST 2007
157 Releasing GNUnet 0.7.3.
158
159Sun Dec 9 14:34:32 MST 2007
160 Implemented MySQL version of the dstore-module. This
161 means that sqLite is now again truly optional.
162
163Sat Dec 8 15:15:53 MST 2007
164 Integrated F2F topology into main topology module
165 (options are used to choose between F2F-only (old F2F),
166 minimum number of friend connections (NEW) or entirely
167 arbitrary connection set (default)).
168
169Thu Dec 6 20:51:17 MST 2007
170 The SMTP transport is working again.
171
172Thu Nov 22 20:49:16 MST 2007
173 United all libgnunetutil_*.so libraries into one big
174 libgnunetutil.so library (eliminates issues for binary
175 packagers and reduces file size by about 20%). Also
176 made sure that all exported symbols start with "GNUNET_".
177
178Sat Sep 29 16:48:24 MDT 2007
179 Improved MySQL sqstore module performance.
180 Releasing GNUnet 0.7.2c.
181
182Sat Sep 8 18:01:36 MDT 2007
183 HTTP transport seems finally ready.
184
185Sat Aug 25 23:58:21 MDT 2007
186 New and improved gnunet-setup GTK interface.
187
188Mon Jul 30 00:07:44 MDT 2007
189 Releasing GNUnet 0.7.2b.
190
191Sun Jul 29 01:53:32 MDT 2007
192 Fixing log rotation.
193
194Sat Jul 21 23:42:11 MDT 2007
195 Radical changes to MySQL implementation (trying to
196 address certain scalability issues).
197
198Sat Jul 7 00:22:47 MDT 2007
199 Releasing GNUnet 0.7.2a.
200
201Fri Jul 6 22:54:52 MDT 2007
202 Fixed bugs in F2F topology code. Eliminated a few
203 confusing LOG messages.
204
205Sun Jul 1 20:35:00 MDT 2007
206 Fixed issue with too many TCP connections being
207 created. Reduced CPU overheads by increasing
208 requirements for grouping of messages. Improved
209 various error messages.
210
211Sat Jun 30 01:55:34 MDT 2007
212 Improved bloomfilter recomputation after quota change.
213 Fixed bloomfilter size computation. You must run
214 gnunet-update (will take a while).
215
216Fri Jun 29 00:56:03 MDT 2007
217 Avoid re-connecting shortly after connection was shutdown.
218
219Thu Jun 28 01:10:01 MDT 2007
220 Fixed high-latency problems for certain SQLite operations.
221 Also improved SQLite performance (but not scalability) a
222 bit. Resolved MySQL disconnect crash (gnunetd would crash
223 if mysqld was stopped).
224
225Sat Jun 23 16:56:03 MDT 2007
226 Improved CPU consumption from content migration code
227 by querying the DB less often, using the same content
228 for more peers (at the expense of 1 MB extra memory
229 utilization). Fixed a deadlock.
230
231Wed Jun 20 17:10:38 MDT 2007
232 Fixed bug in MySQL module.
233
234Sun Jun 17 00:09:13 MDT 2007
235 Releasing GNUnet 0.7.2.
236
237Sat Jun 16 04:43:20 MDT 2007
238 http transport is amost back, now needing the
239 new libmicrohttpd. However, the code is still
240 highly experimental and not ready for production
241 use.
242
243Fri Jun 8 23:44:01 MDT 2007
244 Fixed bugs preventing namespace search from
245 working. Also extended testcase to cover
246 namespace search.
247
248Tue May 29 23:15:27 MDT 2007
249 Fixed a major bug which resulted in peers without
250 traffic between them disconnecting (even if that
251 session was their only connection).
252 Fixed another major bug where nodes would not
253 properly forward HELLOs from other peers (given
254 certain common/default configuration options).
255
256Sun May 27 22:39:48 MDT 2007
257 Added new API gnunet_testing_lib.h to make it
258 easier to write testcases that need to start
259 gnunetd. API is now used everywhere and the
260 ugly peer.conf files and directories are gone.
261 Fixed a bug with inserting empty directories.
262 Extended ECRS API to allow partial file download.
263
264Sat May 26 18:24:15 MDT 2007
265 Fixed bugs with testcases (changes in names and
266 structure of options were not reflected in .conf
267 files for various testcases).
268 Fixed issues with command-line option handling (failed to
269 override configuration file options).
270 Fixed bogus nesting in GAP routing algorithm (caused
271 random request drops).
272
273Fri May 25 12:23:38 MDT 2007
274 Finished extended URITRACK API.
275 Renamed various (minor) libraries and function calls to
276 get somewhat more consistent naming conventions.
277
278Sun Apr 15 22:15:37 MDT 2007
279 Implemented heuristic for better packing of gnunet-directories.
280
281Sun Mar 25 13:47:08 MDT 2007
282 Releasing GNUnet 0.7.1c.
283
284Wed Feb 28 15:29:05 MST 2007
285 Enabled abortion of gnunet-peer-info with CTRL-C.
286
287Mon Feb 26 19:19:29 MST 2007
288 Fixed handling of -d option by gnunet-download
289 if -f option is not given.
290
291Sat Feb 24 15:43:14 MST 2007
292 Fixed various bugs related to content expiration.
293 Completed message coverage in stats implementation.
294
295Fri Feb 23 17:55:46 MST 2007
296 Fixed potential deadlock during download shutdown sequence.
297
298Thu Feb 15 21:54:15 MST 2007
299 Added support for IO load detection.
300
301Sun Feb 11 13:53:13 MST 2007
302 Releasing GNUnet 0.7.1b.
303
304Thu Feb 8 13:21:34 MST 2007
305 Updating gettext to 0.16.1.
306 Minor bugfix in build process (#1180, #1181).
307 Minor bugfix in gnunet-search (#1179).
308
309Sun Jan 28 02:43:37 MST 2007
310 Improving support for multiple choice configuration items
311 in gnunet-setup.
312
313Sat Jan 27 16:02:02 MST 2007
314 Changing $-expansion for interpretation of configuration file
315 (again). Also, now the base-path for gnunetd defaults to
316 "/var/lib/gnunet" instead of "/var/lib/GNUnet".
317
318Tue Jan 23 19:48:37 MST 2007
319 Fixed problem with split-extractor keywords not being used
320 for uploads.
321
322Tue Jan 16 21:43:26 MST 2007
323 Expanded transport APIs to avoid building messages for
324 transmission just to have them rejected by blocking TCPs
325 with full transmission queues (happened quite a bit).
326
327Mon Jan 8 22:21:15 MST 2007
328 Making computation of send buffer permuations more
329 efficient (in terms of calling weak_randomi) by only
330 computing permuations over the actually selected messages.
331
332Mon Jan 8 21:34:02 MST 2007
333 Forcing -O3 for crypto library (performance critical).
334 Enforcing message queue limit for daemon (somehow got lost
335 on the way to 0.7.1, was responsible for high CPU load).
336 Fixing cron job deletion in core (clean shutdown).
337
338Sun Dec 31 23:56:31 MST 2006
339 ncurses may need "-lm" in order to link.
340 Releasing GNUnet 0.7.1a.
341
342Sat Dec 30 00:21:49 MST 2006
343 DHT routing now seems to work (not integrated with file-sharing,
344 only for gnunet-dht-query).
345
346Fri Dec 29 09:38:53 MST 2006
347 Added UPnP support to GNUnet (IPv4 only, #843).
348
349Thu Dec 28 21:22:10 MST 2006
350 Hostname resolution with gnunet-peer-info implemented (#1076).
351 Proper linking of gnunet-pseudonym (#1161).
352 Drop group permissions when changing user (#1162).
353 gnunet-download support for directory files implemented (#1013).
354
355Thu Dec 28 20:44:45 MST 2006
356 Hopefully fixing build problems on certain systems with
357 unusual installation of iconv.
358
359Tue Dec 26 20:54:03 MST 2006
360 Added additional gnunet-gtk options to client configuration
361 specification file.
362
363Sun Dec 24 18:06:04 MST 2006
364 Limit memory utilization by select write queue.
365 Improved select write buffering (fewer malloc/free
366 operations and less copying).
367
368Sat Dec 23 22:12:17 MST 2006
369 Updated various man pages and some configuration documentation.
370 Fixed TCP transport (did not work with NAT if port was set to 0).
371 Fixed verbose option for gnunet-transport-check.
372 Updated hostlist scripts in contrib/ to reflect new protocol IDs.
373 Allow aborting of gnunet-transport-check with CTRL-C.
374 Allow testing of bi-directional transports behind NAT with
375 gnunet-transport-check.
376
377Fri Dec 22 19:21:25 MST 2006
378 Added option to set maximum number of file descriptors
379 (convenience for OS X users where the default is too low).
380 Releasing GNUnet 0.7.1.
381
382Thu Dec 21 20:03:07 MST 2006
383 Fixed gnunet-insert "-e" option. Fixed various
384 crashes in client code. Improved OS X portability.
385
386Tue Dec 19 19:03:48 MST 2006
387 Allowing GNUnet (without gnunet-setup) to be build
388 on systems without guile.
389
390Sun Dec 17 16:54:33 MST 2006
391 Various improvements for OS X portability.
392 CPU load detection fix for Solaris.
393
394Sat Dec 16 11:42:13 MST 2006
395 Bugfixes in collection library (gnunet-pseudonym).
396
397Mon Dec 11 21:11:54 MST 2006
398 Implemented ncurses/dialog based gnunet-setup wizard.
399 Releasing GNUnet 0.7.1pre2.
400
401Sun Dec 10 00:36:11 MST 2006
402 Fixed load calculation code. More aggressive utilization
403 of available resources.
404
405Mon Dec 4 13:24:12 MST 2006
406 Releasing GNUnet 0.7.1pre1.
407
408Wed Nov 29 22:20:26 MST 2006
409 Fixed various bugs with (de)serialization of FSUI state
410 and closing searches with associated downloads. Extended
411 FSUI test suite.
412
413Mon Nov 27 08:51:46 MST 2006
414 Added conversion of ECRS error messages to FSUI
415 error event messages.
416
417Sun Nov 19 00:20:14 MST 2006
418 Improved error handling. gnunetd now can communicate
419 text error messages to clients (not just error codes).
420
421Wed Nov 15 23:17:36 MST 2006
422 Fixed expiration time setting. Improved bias of
423 migration towards valuable content.
424 Releasing GNUnet 0.7.1pre0.
425
426Wed Nov 1 20:58:44 MST 2006
427 Fixed MySQL database size underreporting.
428
429Wed Nov 1 13:09:53 MST 2006
430 Fixed some problems with index creation in sqlite
431 datastore (discovered with new sqlite benchmarking
432 code). Performance should improve significantly
433 (observed was a factor of 4-10 depending on
434 database size and operation).
435
436Thu Oct 19 23:44:24 MDT 2006
437 Completed huge update to FSUI API (not fully debugged).
438 Major changes include:
439 * clients can associate pointer with each action
440 * abort methods can cancel action (but do not stop everything)
441 * upload and unindex operations can now be suspended and resumed
442 * cleaned up naming conventions
443
444Thu Sep 14 23:44:17 MDT 2006
445 Breaking UDP transport protocol compatibility -- some
446 fields have to be switched around to make it work with
447 the new select code. Expect to see some warnings when
448 interacting with 0.7.0 peers.
449
450Tue Sep 5 21:28:25 PDT 2006
451 Switched ncurses interface of gnunet-setup to use
452 external dialog library (new dependency!).
453
454Fri Aug 18 00:01:37 PDT 2006
455 Swiched http bootstrap mechanism to using libcurl
456 (new dependency!).
457
458Sat May 20 08:37:02 PDT 2006
459 Releasing GNUnet 0.7.0e.
460
461Sun May 14 02:51:15 PDT 2006
462 Major gnunet-setup GTK code cleanup (now uses libglade).
463
464Sat May 13 19:35:49 PDT 2006
465 Made headers more C++ friendly.
466
467Wed May 10 22:11:17 PDT 2006
468 Fixing bug that could result in hanging the UDP transport;
469 found by Luigi Auriemma (thanks!).
470
471Sat May 6 00:17:59 PDT 2006
472 Releasing GNUnet 0.7.0d.
473
474Fri May 5 01:33:42 PDT 2006
475 Fixed bug with priorities of IBlocks of uploaded content
476 (priority was left at zero, making those blocks be
477 possibly discarded rather quickly once the datastore filled
478 up).
479
480Tue May 2 00:01:25 PDT 2006
481 Fixed bug in gap where the tracking of query origins for
482 optimizing routing paths lacked a simple assignment of the
483 query origin (found by code inspection). As a result,
484 routing performance should improve further. Also fixed
485 small memory leak in gap and reduced memory consumption by
486 fixing Mantis #1058.
487
488Sat Apr 22 13:50:39 PDT 2006
489 Fixed bug in util/cron.c where stopCron() would wait for an
490 unnecessary sleep to complete.
491
492Sat Mar 18 12:54:11 PST 2006
493 Releasing GNUnet 0.7.0c.
494
495Thu Mar 16 22:14:01 PST 2006
496 Fixing various routing problems (resulting in better utilization
497 of bandwidth by routing more content and less queries).
498
499Wed Mar 15 00:00:14 PST 2006
500 Fixing various content migration bugs (one that disabled it,
501 one that made it unlikely that migration was even tried, and
502 then various crashes in formerly dead code).
503
504Mon Jan 23 19:04:17 PST 2006
505 Added Swedish translation.
506
507Sun Jan 1 21:35:59 PST 2006
508 Reduced amount of hashing done to be O(n) and not O(n^2) for
509 n local search results (for example, for 100 results, this can
510 make the difference between hashing 200 MB and hashing 20 MB).
511
512Sat Dec 31 17:02:37 PST 2005
513 Added support for using -k multiple times in gnunet-pseudonym.
514
515Wen Dec 28 00:22:54 CET 2005
516 Fixed deadlock in http transport.
517
518Fri Dec 23 17:17:18 PST 2005
519 Releasing GNUnet 0.7.0b.
520
521Sat Nov 19 16:00:16 PST 2005
522 Releasing GNUnet 0.7.0a.
523
524Fri Oct 7 15:28:02 PDT 2005
525 Fixing Mantis #946.
526
527Thu Sep 15 23:56:39 PDT 2005
528 Fixed various gcc 4.0 warnings.
529
530Sun Aug 28 15:29:56 PDT 2005
531 Releasing GNUnet 0.7.0.
532
533Sun Aug 28 01:46:26 PDT 2005
534 Updated German translation.
535
536Tue Aug 23 00:45:57 PDT 2005
537 Fixed undersynchronization that may result in segv if pending
538 download was cancelled.
539
540Mon Aug 22 00:37:11 PDT 2005
541 Made "UPDATE" use a prepared statement in MySQL datastore.
542
543Sun Aug 21 23:08:57 PDT 2005
544 Fixed bugs causing unnecessary long delays for downloads from
545 loopback. Also now bypassing routing table for loopback download
546 (faster, avoids pollution of the routing table when not needed).
547
548Sun Aug 21 18:42:14 PDT 2005
549 Fixed memory leak in gnunet-insert -R. Improved memory utilization
550 by SQlite dramatically (see discussion on gnunet-developers).
551
552Sat Aug 20 21:04:28 PDT 2005
553 Fixed (rare) segmentation fault in insertion code.
554
555Sat Aug 20 19:31:10 PDT 2005
556 Yet another tiny bug -- but one that hangs gnunetd; fixed in pre6a.
557
558Sat Aug 20 13:51:01 PDT 2005
559 Releasing 0.7.0pre6.
560
561Sat Aug 20 12:51:27 PDT 2005
562 Changed sqlite data format to avoid encoding-decoding
563 (breaks compatibility with previous datastores, in particular
564 since conversion code is NOT provided).
565 The page size was also increased, rendering the database files
566 incompatible, too.
567
568Thu Aug 18 21:18:28 PDT 2005
569 Made quotations match GNU standards.
570
571Wed Aug 17 20:05:19 PDT 2005
572 Fixed bug that would prevent P2P messages from being
573 transmitted under certain (common) circumstances.
574
575Mon Aug 15 00:08:47 PDT 2005
576 Bugfest. Fixed various bugs in MySQL, fragmentation,
577 core and fs (see Mantis for more details).
578
579Mon Jul 18 01:03:05 CEST 2005
580 Alpha-rename fest. Releasing 0.7.0pre5.
581
582Sun Jul 17 13:49:40 CEST 2005
583 Fixed problems with struct alignment on 64-bit
584 AMDs. Fixed recently introduced memory leak.
585 Fixed various compiler warnings.
586
587Sat Jul 16 23:55:31 CEST 2005
588 Fixed various minor problems with platforms
589 without gettext/NLS support and for 64-bit size_ts.
590 Also fixed a couple of other compiler warnings.
591 Cleaned up connection.c code.
592
593Mon Jul 11 14:41:18 CEST 2005
594 Fixed tiny memory leak in http_bootstrap.
595
596Mon Jul 11 02:22:24 CEST 2005
597 Fixed long-standing problems in statuscalls wrt
598 network load estimates, leading to too-high bandwidth
599 consumption on average. Fixed minor memory leaks.
600 Fixed far too often session-key exchange (was done
601 also for sessions that were already up).
602
603Thu Jul 7 15:22:21 CEST 2005
604 Fixed bug in identity, missing ntohs for protocol ID.
605 Fixed bug in topology, wrong calculation of saturation.
606
607Wed Jul 6 22:34:30 CEST 2005
608 Fixed bugs in core with respect to possible infinite
609 recursion caused by fragmentation callbacks. Also
610 differenciated between fatal transport sends and
611 transient transport sends. Cleanup of some APIs.
612
613Sat Jul 2 17:21:07 CEST 2005
614 Fixed bugs in gnunet-pseudonym (listing of namespaces),
615 FSUI (double-free for namespace creation), cleaned up
616 APIs and implemented clearing of completed downloads
617 (FSUI). Releasing 0.7.0pre4.
618
619Fri Jul 1 15:08:42 CEST 2005
620 Added statistics for transports and other connection-
621 related functions. Prevented core from dropping
622 messages just because transport is (temporarily)
623 blocked. Made transport selection in identity random
624 again where necessary.
625
626Thu Jun 30 20:05:15 CEST 2005
627 Added cache for KBlocks (can speed up insertion speed
628 for recursive inserts quite a bit).
629
630Thu Jun 30 13:52:17 CEST 2005
631 Enabled IPv6 by default. Fixed various minor bugs.
632
633Tue Jun 28 13:41:58 UTC 2005
634 Fixed various open FIXMEs, including error handling,
635 bad performance and some memory leaks (gnunet-tools
636 only, not in gnunetd).
637
638Mon Jun 27 17:21:09 CEST 2005
639 Fixed double-free segfault.
640 Fixed problem with session timeout not happening.
641 Fixed issue with too lazy slot reclaim for reconnect.
642 Made reconnect scanning more incremental (1/10th of
643 the work every 500ms instead of full work every 5s).
644 Fixed memory leak in advertisement processing.
645
646Sun Jun 26 18:21:17 CEST 2005
647 Plenty of bugfixes everywhere, gnunet-setup works
648 now. Releasing 0.7.0pre3.
649
650Sat Jun 11 11:25:24 EST 2005
651 Fixed various problems with recursive upload
652 (thread stack size too small, wrong filenames
653 passed around, wrong list of filenames updated).
654
655Sat Apr 2 01:54:23 EST 2005
656 Various bugfixes, some of them critical (segfaults,
657 protocol errors (resulting in failures to connect),
658 old version of configuration file would be
659 generated if configuration was missing,
660 gnunet-insert would not properly work with multiple
661 keywords (-k and -K options)). Releasing 0.7.0pre2.
662
663Thu Mar 31 21:38:06 EST 2005
664 Releasing 0.7.0pre1.
665
666Tue Mar 8 14:45:55 EST 2005
667 OpenSSL cannot fully support SHA-512. Eliminated as an
668 option (not necessary, GPL incompatible, trouble, work
669 to maintain -- in summary: not worth it).
670
671Sat Mar 5 00:33:51 EST 2005
672 Changing hash algorithm to SHA-512.
673 Changing symcipher algorithm to AES-256.
674
675Sun Feb 27 21:59:31 EST 2005
676 All unit testcases pass. Releasing 0.7.0pre0.
677
678Sat Feb 12 17:35:08 EST 2005
679 Fixed mysql-test. Changed MySQL to use prepared statements,
680 avoids conversion (mysql_escape_string) and is faster on the
681 server-side, too.
682
683Wed Dec 15 20:47:40 EST 2004
684 Removed support for password encryption of namespace keys.
685 Hardly used and adds hardly any security. Encrypt /home if
686 you need this, would be more effective anyway.
687
688Fri Nov 26 06:27:12 EST 2004
689 Sessionkey exchange works now, at least with OpenSSL. There
690 seems to be some quirk in some version of libcrypt with
691 respect to RSA encryption. Anyway, it is a heisenbug (sometimes
692 RSA decryption does not result in what was originally
693 encrypted), but I have the feeling this problem existed
694 already in 0.6.5 -- and it is now detected and does not
695 occur all the time.
696
697Tue Nov 23 02:35:50 EST 2004
698 The CVS may look like it's compiling, but that's just because
699 most of the service modules are not even attempted.
700 And without those, nothing will work. But in good news,
701 util, transport and server do compile now.
702
703Sun Nov 21 03:53:22 EST 2004
704 Starting to make incompatible changes. Once this is commited
705 to CVS (which will only happen once at least some parts compile
706 again), this version will no longer be compatible with any
707 previously released version of GNUnet (and highly experimental).
708 Do not yet use the new code on-line, do not expect it to work
709 at all!
710
711Sun Nov 14 16:49:02 EST 2004
712 Debugged collections, seems to work (not that it looks pretty,
713 but it basically works, the rest is UI work). Fixed deadlock
714 in gnunet-gtk logging. Releasing GNUnet 0.6.5.
715
716Thu Nov 4 09:04:48 EST 2004
717 Added (highly experimental) support for collections.
718
719Sat Sep 25 22:29:48 EST 2004
720 Releasing GNUnet 0.6.4a.
721
722Sun Sep 19 23:39:04 EST 2004
723 Various code cleanups and minor bugfixes.
724
725Sun Aug 29 15:11:28 IST 2004
726 Releasing GNUnet 0.6.4.
727
728Tue Aug 24 20:59:14 IST 2004
729 Significant enhancements to namespaces. A namespace can
730 now be annotated with meta-data at the time that it is
731 created.
732
733Sat Aug 21 01:00:06 IST 2004
734 Adding GNU gettext support to configure.
735
736Thu Aug 19 01:26:55 IST 2004
737 Migrating gnunet-gtk to GTK 2.0 (tested with 2.4).
738
739Mon Aug 16 00:30:59 IST 2004
740 Removed gcry. Added dependency on GNU MP library (libgmp)
741 for kblocks.
742
743Tue Aug 3 17:57:43 IST 2004
744 Fixed bugs in gnunet-update. Fixed segfault in AFS startup.
745 Fixed warnings in gnunet-peer-info/gnunetd. Fixed packaging
746 error (not all of util/gcry included in distribution).
747 Releasing GNUnet 0.6.3a.
748
749Mon Aug 2 20:06:07 IST 2004
750 Releasing GNUnet 0.6.3.
751
752Sun Aug 1 01:31:19 IST 2004
753 Changed most places from HexName to the new, shorter EncName.
754 Pushed URIs for namespaces and keyword searches into more
755 widespread use. Replaced all occurences of sprintf with
756 SNPRINTF (to obtain extra bounds check).
757
758Sun Jul 11 13:54:01 IST 2004
759 Moved testcases for libgnunet_util to util/ directory.
760 Made DB testcases in afs/module/ run for each available
761 database and not just the one configured in /etc/gnunet.conf.
762
763Fri Jun 25 21:05:59 IST 2004
764 Releasing GNUnet 0.6.2b (resolves various minor bugs).
765
766Wed May 5 17:34:39 EST 2004
767 Releasing GNUnet 0.6.2a (resolves libgcrypt and packageing
768 issues, improved gtk-statistics, other minor bugfixes).
769
770Fri Apr 30 21:36:23 EST 2004
771 Fixed synchronization problem in cron (only relevant for
772 parallel downloading). Releasing GNUnet 0.6.2.
773
774Mon Apr 26 21:13:45 EST 2004
775 Added support to gnunet-check to convert file index database
776 to new design. Removed support for pre 0.6.1b bloomfilter
777 conversion (would have been too messy to support both).
778 Added old-version check to gnunetd startup to make updates
779 more systematic in the future (not perfect, though).
780
781Mon Apr 26 19:27:29 EST 2004
782 Recursive insertion of directories with gnunet-gtk
783 now works including the progress bar.
784
785Sun Apr 25 18:24:55 EST 2004
786 Global changes to fix bug #698. The fix is still
787 incomplete with respect to pthread.h specific structs.
788
789Sun Apr 25 15:20:29 EST 2004
790 Fixed compile error in IPv6 transports.
791
792Fri Apr 23 23:38:01 EST 2004
793 Added recursive insertion of directories to gnunet-gtk.
794 Progress-bar does not work yet, also libextractor is
795 always used (no option to turn it off).
796
797Fri Apr 23 21:49:18 EST 2004
798 Removed need to specify _protocol in configuration file
799 (shorter is better).
800
801Wed Apr 21 23:32:36 EST 2004
802 Added code to bound priority used by clients by twice the
803 average priority of requests from other peers that are
804 routed at the moment. That prevents clients from exposing
805 themselves with excessively high priorities (and also
806 avoids giving too much credit/trust needlessly).
807
808Tue Apr 20 22:27:19 EST 2004
809 Added possibility of using a link instead of making a copy
810 if gnunetd and the insert-client both run on the same machine.
811
812Tue Apr 20 00:00:58 EST 2004
813 Added network transparency for indexing files (by copying
814 them to a GNUnet(d) specific directory). This breaks
815 unindexing (for files indexed with previous versions) and
816 forces the user to make a copy of the file. In the near
817 future we should resolve this problem by allowing the use
818 of a link.
819
820Sun Apr 18 17:24:34 EST 2004
821 Adding recursive, parallel download of directories to
822 gnunet-download
823
824Sun Apr 18 01:57:32 EST 2004
825 gnunet-transport-check can now be used to check
826 external connectivity (with other peers).
827
828Sat Apr 17 17:46:19 EST 2004
829 Reduced memory consuption for AFS insertion and
830 download.
831
832Sat Apr 10 21:17:46 EST 2004
833 Implemented statistics-plot in gnunet-gtk based on
834 gnome-system-monitor code.
835
836Fri Apr 9 22:01:51 EST 2004
837 Added support for libextractor > 0.2.7.
838
839Fri Apr 9 0:29:20 EST 2004
840 Completed --help conversion.
841
842Wed Mar 31 15:40:51 EST 2004
843 Releasing 0.6.1d.
844
845Tue Mar 30 22:42:13 EST 2004
846 Integrated gnunet-pseudonym-create, -delete and -list into
847 gnunet-pseudonym as well as gnunet-directory-list, -emptydb
848 and -print into gnunet-directory.
849
850Tue Mar 2 10:46:01 EST 2004
851 Fixing bug preventing download for indexed files <= 1k.
852
853Sat Feb 28 03:43:34 EST 2004
854 Releasing 0.6.1c.
855
856Sat Feb 21 06:16:47 EST 2004
857 Modified requestmanager to improve performance at the end of the
858 download.
859
860Thu Feb 19 00:48:33 EST 2004
861 Fixed integer underflow possibly causing slow download performance.
862
863Sun Feb 15 15:17:05 EST 2004
864 Fixed weak key failures with libgcrypt.
865
866Sun Feb 15 13:14:44 EST 2004
867 New routing code (untested) commited.
868
869Sun Feb 15 11:58:10 EST 2004
870 Fixing problem with 64-bit size_t on alpha (#655).
871
872Sat Jan 31 04:32:33 EST 2004
873 Releasing 0.6.1b.
874
875Fri Jan 23 00:00:09 EST 2004
876 Fixed indexed content being overwritten by migrated content
877
878Thu Jan 22 19:27:33 EST 2004
879 Fixed integer-overflow problems in statuscalls.
880 Fixed missing ttl/priority adjustment for NS-Queries.
881 Fixed bug in routing that would let very old queries survive.
882
883Thu Jan 15 23:14:54 EST 2004
884 Fixed size of super-bloomfilter (was factor of 32 to small).
885 Fixed option -r of gnunet-check (would not increment bloom filters
886 to appropriate value).
887
888Wed Dec 31 17:07:40 EST 2003
889 Fixed various routing and bandwidth allocation problems.
890 Releasing 0.6.1a.
891
892Wed Dec 24 00:00:00 EST 2003
893 Releasing 0.6.1.
894
895Fri Dec 19 00:57:29 EST 2003
896 NAT transport passes tests.
897
898Sat Dec 13 00:16:41 EST 2003
899 Added NAT transport.
900
901Thu Oct 16 19:20:29 EST 2003
902 Added greedy knapsack heuristic for use by CPU-overloaded
903 systems.
904
905Mon Oct 13 22:36:45 EST 2003
906 Improved gnunet-gtk code that forks of gnunetd (some extra checking,
907 use fork-exec instead of system(), pass configuration file as
908 argument).
909
910Sun Oct 12 03:42:55 EST 2003
911 Split bandwidth montoring into up and downstream.
912 Why stop sending replies merely because we *receive* traffic!?
913 Also reduced frequency of HELO exchange.
914 Added more statistics (traffic by type).
915
916Fri Oct 10 02:05:13 EST 2003
917 Fixed bug that wasted a lot of CPU time.
918 Better CPU usage control by making knapsack
919 solving (frequency and problem size) dependent
920 on CPU load.
921
922Thu Oct 9 14:29:35 EST 2003
923 Releasing 0.6.0a.
924
925Sun Oct 5 21:35:23 EST 2003
926 GNUnet 0.6.0 released.
927
928Sat Oct 4 12:54:55 EST 2003
929 Fixed bug in timer code (discovered in testcase).
930 Added extensive testcases for platform dependent code.
931
932Fri Sep 19 01:38:00 EST 2003
933 Added code to allow namespace queries to return multiple
934 results. Updates are now displayed in separate tabs.
935
936Wed Sep 17 23:54:15 EST 2003
937 Migrated libgcrypt code in util to comply with
938 libgcrypt 1.1.43 (and it passes the tests just fine)
939
940Wed Sep 17 22:59:16 EST 2003
941 Fixed problems with updates in namespaces in the GTK code.
942 Added boolean search capability (x AND y) to GTK search.
943 Made namespace search frequency respect TTL delays.
944
945Thu Aug 21 19:42:57 EST 2003
946 GNUnet 0.5.5 released.
947
948Tue Aug 12 20:48:39 EST 2003
949 Support for namespaces with updates is there,
950 but requires testing.
951
952Sun Jul 27 14:48:19 EST 2003
953 Added download summary window to gnunet-gtk.
954
955Fri Jul 25 14:15:37 CET 2003
956 Unioned gnunet-insert-multi and gnunet-insert-sblock
957 into gnunet-insert.
958
959Thu Jun 26 23:22:12 EST 2003
960 Added draft support for directories.
961
962Thu Jun 26 23:21:41 EST 2003
963 GNUnet 0.5.4a released
964
965Sat Jun 14 19:21:41 EST 2003
966 Added support for HTTP-PROXY to download the hostlist.
967
968Wed May 29 01:13:15 EST 2003
969 Fixing some ugly bugs in connection.c that caused
970 permanent connection-drop and connection-establish
971 cycles (every 5 minutes).
972
973Sat May 24 03:12:42 EST 2003
974 Migrated subset of libgcrypt into GNUnet tree to use
975 it instead of OpenSSL or libgcrypt. RSA in the new
976 code is broken at the moment.
977
978Sun May 18 04:10:25 EST 2003
979 GNUnet 0.5.4 released.
980
981Sat May 10 21:39:35 EST 2003
982 Only download hostlist after a while if we were
983 not able to connect (to reduce load on hostlist
984 servers).
985
986Fri May 2 23:20:15 EST 2003
987 Added code to handle massive collisions in datastore
988 (thousands of files under the same keyword).
989
990Sun Apr 27 23:52:12 EST 2003
991 GNUnet 0.5.3 released.
992
993Wed Apr 23 03:20:21 EST 2003
994 Build system cleanup, location of mysql, gdbm, tdb and
995 db can now be specified.
996
997Mon Apr 21 01:54:24 EST 2003
998 Made random content selection with pIdx faster
999 (do not read entire pidx files) and fully random
1000 (added code to weigh pidx files by number of entries).
1001
1002Sun Apr 20 23:25:45 EST 2003
1003 Fixed double-free in TCP transport code (seems to have
1004 only had a real chance to occur under BSD in practice).
1005
1006Sat Apr 19 14:42:37 EST 2003
1007 Replaced use of dlopen for plugins with the more
1008 portable ltdl from libtool.
1009
1010Thu Apr 17 20:36:42 EST 2003
1011 Added synchronization to pIdx, also use truncate
1012 to remove last n entries instead of re-writing the
1013 entire file (much, much faster).
1014
1015Mon Apr 7 00:00:07 EST 2003
1016 Implemented gnunet-delete.
1017
1018Sat Apr 5 15:55:31 EST 2003
1019 Made directory database use 256 sub-directories
1020 (should increase speed a lot, with the new DB
1021 manager, this will result in at most 2048
1022 files per directory).
1023
1024Mon Mar 31 16:51:24 EST 2003
1025 gnunet-convert and gnunet-check compile again
1026 with the new DB code.
1027
1028Sun Mar 30 13:14:52 CET 2003
1029 Added BSD DB (libdb) support.
1030
1031Sun Mar 23 04:04:38 EST 2003
1032 Big gnunet-gtk cleanup.
1033
1034Tue Mar 18 01:52:18 EST 2003
1035 Releasing 0.5.2a.
1036
1037Sun Mar 16 20:24:24 EST 2003
1038 Caching of RSA signatures for HELOs reduced CPU
1039 usage dramatically, from an average of 31% to less
1040 than 5% on my machine.
1041
1042Sun Mar 16 01:21:16 EST 2003
1043 Fixed locking problem and problem with TCP transport
1044 (bad set of sockets in select).
1045
1046Sat Mar 15 03:02:42 EST 2003
1047 Fixed bug that copied wrong content (garbage) into
1048 replies for other peers. This one was introduced
1049 briefly before 0.5.2. Argh.
1050
1051Fri Feb 28 00:23:02 EST 2003
1052 Fixed segfault in gnunet-gtk when closing search
1053 sub-window.
1054
1055Thu Feb 27 16:23:20 EST 2003
1056 Releasing GNUnet 0.5.2.
1057
1058Mon Feb 24 00:28:52 EST 2003
1059 Cleaning up the AFS routing code, also some tweaks
1060 to improve anonymity against an active attacker.
1061
1062Thu Feb 20 23:51:30 EST 2003
1063 gnunet-tracekit works now nicely (and with dot).
1064 Also, GNUnet now attempts to locate a configuration
1065 file in /etc/gnunet.conf if ~/.gnunet/gnunet.conf
1066 does not exist (and nothing is specified on the
1067 command line).
1068
1069Wed Feb 12 23:21:44 EST 2003
1070 Fixed deadlock between pingpong and connection
1071 module.
1072
1073Tue Feb 4 13:22:09 EST 2003
1074 Releasing GNUnet 0.5.1(a).
1075
1076Tue Feb 4 04:05:58 EST 2003
1077 RSA encryption of OpenSSL has been changed to pure
1078 PKCS #1 to achieve compatibility with libgcrypt.
1079
1080Mon Feb 3 18:46:54 EST 2003
1081 RSA signature encoding has been changed from raw
1082 to PKCS #1 compatible encoding. This should help
1083 making the migration to libgcrypt easier in the
1084 future. RSA & libgcrypt are still not friends,
1085 but the GNUnet code should be mostly there.
1086
1087Fri Jan 31 10:40:01 EST 2003
1088 gnunet-peer-info tool was added. This tool can
1089 prints information about all known peers and may
1090 be useful for diagnostics.
1091
1092Mon Jan 20 17:54:51 EST 2003
1093 A large number of memory leaks got fixed thanks
1094 to the new automated scripts to find them.
1095
1096Thu Jan 16 00:49:20 EST 2003
1097 Nearly finished removing dependencies on OpenSSL
1098 (using libgcrypt instead), $FOO-expansion in
1099 configuration parsing and RSA (public key crypto)
1100 are the only missing pieces.
1101
1102Mon Jan 13 01:53:45 EST 2003
1103 Fixed deadlock in gnunetd (would stop processing
1104 messages).
1105
1106Sun Dec 27 13:34:11 CET 2002
1107 Fixed segmentation fault that occured when number
1108 of known peers goes over 128.
1109
1110Sat Dec 21 16:27:11 CET 2002
1111 Releasing GNUnet 0.5.0.
1112
1113Sat Dec 14 03:47:05 CET 2002
1114 Bugfixes over bugfixes. Various memory leaks
1115 from gnunetd to gnunet-download, problems
1116 with bloomfilters and gnunet-check, enforcing
1117 storage limitations set by the user, fixes
1118 in the UDP, TCP and SMTP transports;
1119 better thread termination (avoid asynchronous
1120 cancellation). Not to mention the new
1121 tools gnunet-transport-check and gnunet-tbench
1122 for the evaulation of correctness and performance
1123 of the transport services.
1124
1125Wed Nov 6 22:49:24 EST 2002
1126 Added load smoothing for network and CPU load
1127 such that we quickly adapt to increasing load,
1128 but slowly reduce the (effective) load value
1129 used in the policy if the load drops. This should
1130 help avoiding 0-1 policies where we always jump
1131 up and down between 100% load and no load, letting
1132 in one period all traffic through and in the next
1133 none.
1134
1135Wed Nov 6 00:31:39 EST 2002
1136 Added port==0 for UDP and TCP transport as an
1137 option to indicate that the transport is to be
1138 used only to establish connections to other
1139 peers but not as a server-socket (that is,
1140 if the port is 0, other GNUnet peers can not
1141 connect to the local node's UDP or TCP port,
1142 but the local node can still use UDP
1143 (unidirectional) or TCP (even bi-directional)
1144 to talk to other peers. This is useful if a
1145 node is behind a NAT box and can not receive
1146 inbound traffic but is able to send messages to
1147 other peers (and in the case of TCP even receive
1148 messages if the local peer initiated the
1149 bi-directional connection). Currently, a peer
1150 must always provide at least one transport under
1151 which the peer can be "actively" reached since
1152 otherwise other peers will not keep the public
1153 key of that peer and thus not be able to
1154 complete the session key exchange. For NAT-box
1155 peers, SMTP might be a viable choice for that
1156 "active" protocol.
1157
1158Fri Oct 11 02:16:42 EST 2002
1159 Added bloomfilter interface and calls to the BF from
1160 the AFS service implementation. Missing for working
1161 bloomfilter are calls from gnunet-insert to update
1162 the bloom-filter (top-CHK and super-queries) and the
1163 actual bloom-filter implementation.
1164
1165Tue Oct 8 20:35:45 EST 2002
1166 TCP transport now works with only one thread (using
1167 select) instead of one thread per peer-connection.
1168
1169Fri Sep 27 02:24:52 EST 2002
1170 New content encoding (still only 1k blocks, but with
1171 CHK style IBocks and GBlocks for aggressive content
1172 migration) now seems to work.
1173
1174Mon Sep 16 01:57:55 EST 2002
1175 Implemented gnunet-chat, a demo-application for
1176 how to develop p2p applications on top of GNUnet.
1177
1178Sun Sep 15 22:48:28 EST 2002
1179 Fixing (long standing) problem with segfaults under BSD
1180 due to stack overflow in threads.
1181
1182Sun Sep 15 02:04:52 EST 2002
1183 TCP transport layer implementation seems to work now.
1184 gnunet.conf is now documented on the web. HELO exchange
1185 is fixed, so is the CS-connection whitelisting.
1186
1187Fri Sep 13 00:51:01 EST 2002
1188 Update on the progress towards 0.4.9. What is missing?
1189 * new content encoding to facilitate:
1190 - content migration
1191 - discriminated routing (downloads vs. searches)
1192 - variable blocksize (?)
1193 - self-synchronizing stream encoding (?)
1194 * additional transport layers (SMTP, TCP, HTTP)
1195 * demo application (chat) for how to use the API
1196 * documentation on new gnunet.conf
1197 * known bugs:
1198 - Igor reports, HELO exchange is broken
1199 - David reports, CS-connection whitelisting is broken
1200 - rpm.spec is outdated (add GNUnet's dynamic libraries)
1201
1202 What has been resolved so far:
1203 Major:
1204 * transport and application layer have been abstracted
1205 * dynamic loading of transports and applications is
1206 implemented
1207 * routing much faster since slots are freed earlier
1208 * querymanager is more intelligent in where to send
1209 queries (presumably, not tested)
1210
1211 Refactoring:
1212 * configuration can store options from commandline
1213 * statistics is totally dynamic and can be extended
1214 * connection buffer does callbacks on applications to
1215 fill buffers with queries instead of noise, and
1216 the querymanager makes use of this
1217
1218 Moving:
1219 * common/ is gone
1220 * gnettypes.h is gone
1221 * AFS specific code is all in AFS
1222 * renaming is also done
1223
1224Sun Aug 25 15:30:56 EST 2002
1225 Moving work towards 0.4.9 to CVS. The major goals are:
1226 * independent transport layer (UDP, TCP, SMTP, HTTP,
1227 any of these should be possible in the future); also,
1228 the MTU may be defined differently by any one of them.
1229 * independent application layer. Anonymous File Sharing
1230 (AFS) should just be one application for the GNUnet
1231 core.
1232
1233 Other minor goals and refactorings include:
1234 * configuration - we should be able to update dynamically
1235 options from the gnunet.conf file. E.g. by adding options
1236 from the command line
1237 * statistics - we should not have a hardwired fixed set
1238 of datapoints, the statistics module should be useful
1239 for any kind of statistics
1240 * noise reduction - the connection buffer should allow
1241 the use of intelligent applications that get notified
1242 if noise would be send and then can plug in useful data
1243
1244 And then there is just moving stuff:
1245 * move "common/" to where it belongs (either applications
1246 or server)
1247 * gnettypes is bad if we want to seperate app specifcs
1248 and core. The typedefs should be placed where they are
1249 used
1250 * database does not belong in util, it's AFS specific
1251 * AFS: cleaner separation between database, encoding,
1252 protocol implementation, shell-tools and GUI code.
1253
1254 And finally, renaming:
1255 * if we have TCP for peer-to-peer communications,
1256 we can't use "TCP" vs. "UDP" to distinguish p2p from
1257 client-server, thus: "UDP" becomes "p2p" and "TCP"
1258 becomes "CS". At least where they were used to distinguish
1259 node-to-node and client-server (gnunetd).
1260
1261Sun Aug 25 15:02:31 EST 2002
1262 Releasing GNUnet 0.4.6.
1263
1264Thu Aug 22 01:31:21 EEST 2002
1265 gnunet-gtk should now be able to perform multiple
1266 search and download operations simultaneously (atleast a couple).
1267
1268Tue Aug 20 23:11:10 EEST 2002
1269 Fixed segfault in gnunet-search and gnunet-gtk which appeared
1270 when there was lots of results.
1271 Modified gnunetd to return more results at once if there
1272 is excess bandwidth.
1273
1274Sun Aug 18 23:57:10 EST 2002
1275 Reworked the lookup-database. The old database got
1276 into trouble storing data when it was 6% full. Some
1277 simulations show that the new approach should manage
1278 94% and should be about as fast (more CPU, presumably
1279 slightly fewer random disc accesses).
1280 This change is INCOMPATIBLE with 0.4.5. You *must*
1281 run "gnunet-check -a" before starting this new version
1282 of gnunetd in order to migrate to the new format. For
1283 database simulation and statistical numbers, see
1284 also src/historical/simula.c.
1285
1286Fri Aug 16 17:07:15 EST 2002
1287 Releasing GNUnet 0.4.5.
1288
1289Fri Aug 16 16:43:39 EST 2002
1290 Added feature that will allow the specification of
1291 multiple URLs for downloading the initial hostlist.
1292
1293Mon Aug 12 02:28:14 EST 2002
1294 Fixed big problem in requestmanager that would
1295 make downloads *very* slow for no good reason
1296 at all (ttl increment in wrong place would make
1297 us defer the next request for more than twice
1298 as long as needed, plus some other minor bugs).
1299
1300Mon Aug 12 01:31:03 EST 2002
1301 Fixed bug #347 (option "-H" to gnunet-clients for
1302 connecting to a remote gnunetd node).
1303
1304Mon Aug 12 01:10:17 EST 2002
1305 Fixed bug #348 (no more scan of the entire database
1306 on startup, instead the databases (gdbm, tdb) contain
1307 an entry that gives the nubmer of entries). Note that
1308 this is not done for contentdatabase_directory.
1309
1310Sun Aug 11 17:00:03 EEST 2002
1311 Crude file insertion capabilities added to gnunet-gtk gui.
1312
1313Thu Aug 8 19:13:34 EST 2002
1314 Added progress bar / printing of insertion status to
1315 gnunet-insert (option "-V").
1316
1317Thu Aug 8 19:02:33 EST 2002
1318 Cleaning up code (establishing sessions, etc.)
1319
1320Thu Aug 8 18:03:05 EST 2002
1321 Fixed bug #343 (overflow in stats) by moving to
1322 long long. Let's hope that __BYTE_ORDER is
1323 actually defined outside of netinet/in.h.
1324
1325Thu Aug 8 17:47:17 EST 2002
1326 Fixed gnunetd segfaulting if gnunet.conf is not
1327 available. Also, recvfrom returning -1 with
1328 errno == EAGAIN was fixed earlier.
1329
1330Wed Jul 31 23:38:36 EST 2002
1331 Released 0.4.4.
1332
1333Wed Jul 31 21:35:53 EST 2002
1334 Fixed bug with TCP connection that would not
1335 free thread resources and eventually lead to
1336 gnunetd not being able to start new threads
1337 anymore (mantis: #339).
1338
1339Tue Jul 30 23:38:51 EST 2002
1340 Fixed SIGHUP exiting. The main loop was exiting
1341 because recvfrom returned -1 with errno EINTR,
1342 which caused us to break out of the main loop.
1343 Also added gnunetd.pid file to simplify killing
1344 (or re-reading configuration of) the server.
1345 You must specify the PIDFILE in gnunet.conf!
1346
1347Tue Jul 30 20:38:47 EST 2002
1348 Started writing code to enable re-reading of the
1349 configuration file whenever we receive a SIGHUP.
1350 Works, except that after we've read the new
1351 config file, gnunetd exits (unknown why).
1352
1353Mon Jul 29 18:52:23 EST 2002
1354 Added shutdown code that terminates connection when
1355 SIGTERM is received (to avoid keeping lots of UDP
1356 traffic for the next couple of minutes from hosts
1357 that still believe we're up).
1358
1359Sat Jul 27 12:39:47 EST 2002
1360 Added code to measure network load asymmetrically (useful
1361 for DSL users).
1362
1363Fri Jul 26 22:46:54 EST 2002
1364 Released 0.4.3.
1365
1366Wed Jul 24 21:13:08 EST 2002
1367 Fixed bug in locking and segfault (Linux tolerated,
1368 BSD crashed, both in connection.c), added logging service.
1369
1370Tue Jul 23 00:41:17 EST 2002
1371 Made gnunetd fork like a nice deamon should. Also
1372 started to add a logging service.
1373
1374Sun Jul 21 20:39:20 EST 2002
1375 Fixed issue with check_database (index checking too
1376 strict if content is available in database and
1377 on-demand encoded; also a bounds check was missing).
1378
1379Sun Jul 21 16:05:20 EST 2002
1380 Fixed deadlock in heloexchange (knownhost requires
1381 recursive lock).
1382
1383Sun Jul 21 02:02:32 EST 2002
1384 Improved routing table. Now does more dynamic memory
1385 allocation, reducing the fixed-size per slot from 700
1386 to 56 bytes. Increased number of slots from 512 to
1387 8092 (which is the optimal number for a 56 kbps
1388 modem connection).
1389
1390Sat Jul 20 23:57:06 EST 2002
1391 Fixed bug that caused problems for files
1392 that were indexed and that had spaces in
1393 the filename.
1394
1395Wed Jul 17 22:50:24 EST 2002
1396 Fixed bug that prohibited a transitive HELO exchange
1397 in many cases.
1398
1399Wed Jul 17 01:48:44 EST 2002
1400 Fixed a couple of bugs in gnunet-check and the
1401 insertion-tools. Now gnunet-check seems to run like
1402 a charm. Running it to detect and fix problems in
1403 the GNUnet databases seems now recommendable :-).
1404 Note that you must stop gnunetd before running
1405 gnunet-check.
1406
1407Mon Jul 15 22:27:45 EST 2002
1408 Added return values for insertion. If we run out of
1409 space (in particular for the fixed-size index
1410 database), we can now communicate the problem to the
1411 user.
1412 gnunet-check is now pretty much feature-complete,
1413 but it takes of course very, very long to run. There
1414 is now also a man-page for gnunet-check.
1415
1416Thu Jul 11 11:33:34 EST 2002
1417 Added randomized order of blocks for the download
1418 (patch by I. Wronsky).
1419
1420Thu Jun 20 21:13:21 EST 2002
1421 Added HANGUP, a message send if one side terminates the connection.
1422 Sending the message is optional, but it is nicer to have it. Also
1423 started on gnunet-check, a tool to check database consistency.
1424
1425Thu Jun 20 03:11:01 EST 2002
1426 Improved handling of collisions in the hashes in the
1427 lookup module (uses no longer a linear scan on the
1428 collisions file but a hashtable for the collisions!).
1429
1430Tue Jun 18 20:29:38 EST 2002
1431 Released GNUnet 0.4.2.
1432
1433Tue Jun 18 20:20:55 EST 2002
1434 Fixed bugs in blacklisting IPs. Added feature to allow specification
1435 which networks are trusted enough to connect to the trusted TCP
1436 port (TCP/2086 no longer needs to be firewalled!).
1437
1438Tue Jun 18 02:35:53 EST 2002
1439 Fixed problems with ttl (negative TTL queries were forwarded),
1440 also better flushing of buffers and fewer SKEY exchanges due to
1441 a now working implementation of the blacklist. A DNS lookup for
1442 the NAT-box-IP configuration was also added.
1443
1444Sun Jun 16 04:11:01 EST 2002
1445 Added code to provide statistics (gnunet-stats).
1446 Incomplete.
1447
1448Sun Jun 9 22:56:02 EST 2002
1449 Released GNUnet 0.4.1.
1450
1451Sat Jun 8 05:00:36 EST 2002
1452 Several small bugfixes (list of shared files not updated on
1453 insertion, highest-bit of trust not interpreted as dirty,
1454 rpm dependency on libextractor added.
1455 Also many improvments to the build process.
1456
1457Wed Jun 5 17:01:58 EST 2002
1458 Made sure that HELOs don't trigger Ping-Pong if we don't
1459 really learn anything new.
1460
1461Tue Jun 4 17:17:45 EST 2002
1462 The port numbers were not in network-byte order. Fixing
1463 this is trivial, but it breaks compatibility with 0.4.0.
1464 Thanks to Rick Kennell for reporting the endianess issue.
1465
1466Mon Jun 3 20:35:47 EST 2002
1467 Fixed bug with CRC not endian-converted in gnunet-gtk.
1468 Added mimetype and filename support to gnunet-gtk.
1469
1470Sun Jun 2 03:52:18 EST 2002
1471 Released 0.4.0.
1472
1473Sat Jun 1 22:13:12 EST 2002
1474 Added three-way handshake for SKEY exchange. Not tested.
1475
1476Sat Jun 1 16:55:18 EST 2002
1477 Fixed potential DDoS problem where malicious hosts could
1478 trick GNUnet servers to repeatedly probe a non-partitipating host
1479 trying to establish a connection. I wonder how many other
1480 p2p systems are vulnerable. (Fix: after HELO, play PING-PONG).
1481 The endianess issues should be fixed throughout the system, but
1482 not tested on a real machine so far.
1483
1484Sat May 25 15:55:11 EST 2002
1485 Moved to new CVS server. First changes towards 0.4.0:
1486 * mostly-big-endian
1487 * insert/index via TCP
1488 * bugfixes (mostly performance)
1489
1490Sat May 18 16:00:06 EST 2002
1491 Added mimetype, filename and version number to RootNodes
1492 (mostly incompatible change!). Added automatic generic keyword
1493 and mime-type extraction via libextractor to gnunet-insert.
1494
1495Tue May 14 23:59:40 EST 2002
1496 New storage database is starting to look good. We can now store
1497 the data in a directory (one file per block), a gdbm database,
1498 and presumably (not tested) in a tdb database.
1499
1500Sat May 11 22:10:56 EST 2002
1501 Completed, deployed and tested the new TCPIO code. This changes
1502 the gnunetd-client protocol. Essentially, we convert the TCP stream
1503 into records with a length and type header. This should allow us
1504 to fix bug #212 and add other features in the future. The current
1505 change is really only changing the core TCP code and not anything
1506 around it. We should deploy some demultiplexing code later.
1507
1508Tue May 7 20:56:40 EST 2002
1509 Added IP blacklisting (for virtual private networks).
1510
1511Sat May 4 14:08:23 EST 2002
1512 Fixed bug with bad insertion of files smaller than 1k.
1513
1514Fri May 3 23:25:16 EST 2002
1515 Added IP change detection (useful for dialup) [bug #272].
1516 Added code to ensure that a HELO is life instantly
1517 after receiving it, fixing the 'unknown host,
1518 refusing SKEY problem' (bug #273). Other minor
1519 bugfixes (#274, #283).
1520
1521Sun Apr 14 22:36:03 EST 2002
1522 Added option to allow NAT boxes not to exchange
1523 foreign HELOs and thus expose the private
1524 network. Fixed bug that all other hosts should
1525 in fact do this exchange.
1526
1527Sat Apr 13 11:02:59 EST 2002
1528 Make sure that files are readable before returning TRUE
1529 in assertIsFile()
1530
1531Fri Apr 12 03:01:06 EST 2002
1532 Added padding messages with random if maximum
1533 packet size is not reached. All encrypted
1534 packets now look absolutely uniform in size
1535 for a non-participating adversary (before,
1536 a host that had few queries may have sent packets
1537 that were less than the maximum size).
1538
1539Thu Apr 11 01:43:28 EST 2002
1540 Added sequence numbers to protocol to defend
1541 against replay attacks (bug #185).
1542
1543Wed Apr 10 02:07:25 EST 2002
1544 Bugfix gnunet-insert-mp3 (endless loop).
1545 Updated documentation.
1546
1547Mon Apr 8 00:07:15 EST 2002
1548 Fixed endless-loop bug when activemigration is turned
1549 on (during startup).
1550
1551Fri Apr 5 02:03:13 EST 2002
1552 Released 0.3.3.
1553
1554Fri Apr 5 00:33:42 EST 2002
1555 gnunet-gtk, the gtk+ based GUI is now functional and
1556 has all the features of gnunet-search and gnunet-download,
1557 including boolean queries. In fact, it is a bit better than
1558 gnunet-download as it shows the progress of the download.
1559 The manpage for gnunet-gtk was updated. Minor bugfixes.
1560
1561Mon Mar 25 02:59:13 EST 2002
1562 Changed writeFile to use a fourth parameter which is the
1563 desired permissions for the file. Files in data/hosts
1564 are now world-readable. Created man pages
1565
1566Mon Mar 18 17:56:52 EST 2002
1567 Released 0.3.2.
1568
1569Sun Mar 17 10:47:51 EST 2002
1570 Got rid of far too frequent key exchange attempts.
1571 Added expiration for very-long-dead host keys. Stopped
1572 forwarding of expired HELOs (receiver drops anyway).
1573
1574Wed Mar 14 05:46:20 EST 2002
1575 Fixed some file location inconsistencies. All files are
1576 now in $HOME/GNUnet. RPM installation points to /var/GNUnet
1577 and the config file is ~/GNUnet/gnunet.conf
1578 Finished port to FreeBSD. This included mostly changes
1579 to src/util/statuscalls.c, but also several changes to
1580 the build system. Added a stat() call in the server code
1581 to make sure the config file exists before sending it to
1582 the OpenSSL conf code. Added getopt to source to fix
1583 portability issues. Changed FREEBSD defs to SOMEBSD, also
1584 changed in configure.in. Compiles and works on at least
1585 FreeBSD 4.5 and OpenBSD 3.0
1586
1587Wed Mar 6 23:15:36 EST 2002
1588 Added code for 'fast scan' of the database for
1589 content to discard (should be called partial
1590 scan). This improves the startup-time dramatically.
1591 Every source file got the GNU header.
1592
1593Tue Mar 5 22:42:36 EST 2002
1594 Added option for *not* participating in content
1595 migration. Added timeout option to gnunet-search.
1596 gnunetd now periodically (1h) scans for new content,
1597 no restarting required.
1598
1599Mon Mar 4 23:21:51 EST 2002
1600 Optimized routing and content migration. Distance
1601 of the hash to the identity of the local host is
1602 now taken into account for routing. Hosts give
1603 higher priority to content that is close to their
1604 identity (priority towards keeping it). If the
1605 network grows, this should significantly improve
1606 the performance. Also, the choice of the hosts
1607 for routing is now based on proximity (to the
1608 query), the activity level of the host and its
1609 credit ranking.
1610
1611Sun Mar 3 00:14:58 EST 2002
1612 Implemented binary queries ("AND") for gnunet-search.
1613 Made sure that content is not downloaded again if
1614 already present (if there is other content, we
1615 overwrite). Fixed bug in gnunet-download
1616 (uninitialzied time-to-live).
1617
1618Sat Mar 2 01:57:37 EST 2002
1619 Finished porting the download-code to C. Now files can
1620 be downloaded in using shell commands. No GUI though.
1621 Released GNUnet v0.3.1.
1622
1623Wed Feb 20 23:47:19 EST 2002
1624 Big CVS moving operation.
1625
1626Sat Feb 16 23:17:27 EST 2002
1627 Started migration to GNUnet.
1628
1629Sun Feb 3 01:20:37 EST 2002
1630 Extracted crc32 method from zlib and put only that method into
1631 primitives. Reduces our memory footprint (if nobody else uses
1632 zlib) and we no longer depend no that library (always good).
1633
1634Sat Feb 2 22:56:32 EST 2002
1635 Building final tarball for v0.3.0.
1636
1637Wed Jan 30 23:41:04 EST 2002
1638 Created mp32gnet, a tool to automaticall index mp3 files
1639 using information from the mp3 header as keywords (title,
1640 artist, album, comments). The mp3 parsing code comes from
1641 the GPL tool mp3info.
1642
1643Tue Jan 29 17:36:48 EST 2002
1644 Fixed bug with files that were not closed under certain
1645 circumstances and lead to an exhaustion of the number of
1646 concurrently open files.
1647
1648Mon Jan 21 23:34:44 EST 2002
1649 Bumping version numbers to v0.3.0 (not yet released, needs some
1650 more testing to be on the safe side).
1651
1652Sun Jan 20 02:09:06 EST 2002
1653 Content gathering now discards the least important
1654 content in favour of new, more important content (if
1655 there is not space for all content). The cron
1656 management is now used everywhere. The rpm, the init-script
1657 and the gproxy shell script have been revised.
1658
1659Sun Jan 13 23:17:58 EST 2002
1660 Created cron management, replacing old control
1661 thread (allows for better timing of events).
1662 EvaluateContent now gets the priority of the
1663 query that the content had.
1664
1665Sun Jan 13 00:54:56 EST 2002
1666 Improved choice in number of hosts to forward
1667 queries to (now dynamic, depending on priority, etc.)
1668 Removed many, many allocations in print statements
1669 which also caused memory leaks if active (see
1670 debugging.h).
1671 Added CRC checking of the root node in GProxy. Fixed
1672 problem with CRC in IBlocks for large files.
1673 Added dialog to GProxy to choose where to save the file.
1674
1675Sat Jan 5 14:25:31 EST 2002
1676 Optimized routing table. Routing table is now a hashtable
1677 (collisions are handled by droping either the former or the
1678 new entry). Each bucket has it's own lock, the global
1679 semaphore is gone. The table has many more entries (we can
1680 afford that now that there is no longer a linear search).
1681
1682Wed Dec 26 19:30:41 CET 2001
1683 Created v0.2.0
1684
1685Tue Dec 25 21:24:18 CET 2001
1686 Fixed TTL errors that made queries loop. Added host-evaluation
1687 to policy (drop packets from untrusted hosts under load). Found that CRC-errors
1688 are related to policy decisions ("drop"), cosmetic fix.
1689
1690Sun Nov 25 08:10:52 EST 2001
1691 Added triple-hash functionality and on-demand encoding (lookup.c).
1692
1693Sat Nov 24 07:46:10 EST 2001
1694 Added randomized choice of hosts for the hosttable.
1695
1696Thu Nov 22 04:57:57 EST 2001
1697 Fixed another bunch of big bugs, tested, seems to work smoothly. Creating V0.1.0.
1698
1699Mon Nov 19 01:22:42 EST 2001:
1700 Fixed biggest (show-stopper) bugs. Creating V0.0.3
1701
1702Fri Oct 26 02:20:00 EST 2001:
1703 Created ChangeLog. Report important changes here,
1704 report small changes to CVS only.
diff --git a/HACKING b/HACKING
new file mode 100644
index 000000000..3c50af952
--- /dev/null
+++ b/HACKING
@@ -0,0 +1,57 @@
1Naming conventions:
2
3include files:
4- _lib: library without need for a process
5- _service: library that needs a service process
6- _plugin: plugin definition
7- _protocol: structs used in network protocol
8- exceptions:
9 * GNUNET_config.h --- generated // FIXME: decapitalize
10 * platform.h --- first included
11 * plibc.h --- external library
12 * gnunet_common.h --- fundamental routines
13 * gnunet_directories.h --- generated
14 * gettext.h --- external library
15
16
17exported symbols:
18- must start with "GNUNET_modulename_" and be defined in "modulename.c"
19- exceptions: those defined in gnunet_common.h
20
21
22testcases:
23- must be called "test_module-under-test_case-description.c"
24- "case-description" maybe omitted if there is only one test
25
26
27performance tests:
28- must be called "perf_module-under-test_case-description.c"
29- "case-description" maybe omitted if there is only one test
30
31
32
33src/ directories:
34- apps: end-user applications (i.e., gnunet-search)
35- connectors: libraries requiring services (i.e., libgnunetstatistics)
36- libs: standalone libraries (i.e., libgnunetecrs, etc.)
37- plugins: loadable plugins (i.e., TCP transport, MySQL backend)
38 * transports: udp/tcp/http/dv???
39- services: arm-controlled applications (i.e., gnunet-service-statistics)
40- util: library for everyone
41
42For each directory in services, there should be one
43in connectors and vice-versa.
44
45For each entry in apps, there should be one in libs.
46
47
48
49Minimum file-sharing system (in order of dependency):
50gnunet-arm
51gnunet-transport (name?)
52gnunet-core (name?)
53gnunet-datastore
54gnunet-statistics (integrate traffic?)
55gnunet-dv
56gnunet-dht
57gnunet-fs
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 000000000..d3c5b40a9
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,237 @@
1Installation Instructions
2*************************
3
4Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
52006, 2007 Free Software Foundation, Inc.
6
7This file is free documentation; the Free Software Foundation gives
8unlimited permission to copy, distribute and modify it.
9
10Basic Installation
11==================
12
13Briefly, the shell commands `./configure; make; make install' should
14configure, build, and install this package. The following
15more-detailed instructions are generic; see the `README' file for
16instructions specific to this package.
17
18 The `configure' shell script attempts to guess correct values for
19various system-dependent variables used during compilation. It uses
20those values to create a `Makefile' in each directory of the package.
21It may also create one or more `.h' files containing system-dependent
22definitions. Finally, it creates a shell script `config.status' that
23you can run in the future to recreate the current configuration, and a
24file `config.log' containing compiler output (useful mainly for
25debugging `configure').
26
27 It can also use an optional file (typically called `config.cache'
28and enabled with `--cache-file=config.cache' or simply `-C') that saves
29the results of its tests to speed up reconfiguring. Caching is
30disabled by default to prevent problems with accidental use of stale
31cache files.
32
33 If you need to do unusual things to compile the package, please try
34to figure out how `configure' could check whether to do them, and mail
35diffs or instructions to the address given in the `README' so they can
36be considered for the next release. If you are using the cache, and at
37some point `config.cache' contains results you don't want to keep, you
38may remove or edit it.
39
40 The file `configure.ac' (or `configure.in') is used to create
41`configure' by a program called `autoconf'. You need `configure.ac' if
42you want to change it or regenerate `configure' using a newer version
43of `autoconf'.
44
45The simplest way to compile this package is:
46
47 1. `cd' to the directory containing the package's source code and type
48 `./configure' to configure the package for your system.
49
50 Running `configure' might take a while. While running, it prints
51 some messages telling which features it is checking for.
52
53 2. Type `make' to compile the package.
54
55 3. Optionally, type `make check' to run any self-tests that come with
56 the package.
57
58 4. Type `make install' to install the programs and any data files and
59 documentation.
60
61 5. You can remove the program binaries and object files from the
62 source code directory by typing `make clean'. To also remove the
63 files that `configure' created (so you can compile the package for
64 a different kind of computer), type `make distclean'. There is
65 also a `make maintainer-clean' target, but that is intended mainly
66 for the package's developers. If you use it, you may have to get
67 all sorts of other programs in order to regenerate files that came
68 with the distribution.
69
70 6. Often, you can also type `make uninstall' to remove the installed
71 files again.
72
73Compilers and Options
74=====================
75
76Some systems require unusual options for compilation or linking that the
77`configure' script does not know about. Run `./configure --help' for
78details on some of the pertinent environment variables.
79
80 You can give `configure' initial values for configuration parameters
81by setting variables in the command line or in the environment. Here
82is an example:
83
84 ./configure CC=c99 CFLAGS=-g LIBS=-lposix
85
86 *Note Defining Variables::, for more details.
87
88Compiling For Multiple Architectures
89====================================
90
91You can compile the package for more than one kind of computer at the
92same time, by placing the object files for each architecture in their
93own directory. To do this, you can use GNU `make'. `cd' to the
94directory where you want the object files and executables to go and run
95the `configure' script. `configure' automatically checks for the
96source code in the directory that `configure' is in and in `..'.
97
98 With a non-GNU `make', it is safer to compile the package for one
99architecture at a time in the source code directory. After you have
100installed the package for one architecture, use `make distclean' before
101reconfiguring for another architecture.
102
103Installation Names
104==================
105
106By default, `make install' installs the package's commands under
107`/usr/local/bin', include files under `/usr/local/include', etc. You
108can specify an installation prefix other than `/usr/local' by giving
109`configure' the option `--prefix=PREFIX'.
110
111 You can specify separate installation prefixes for
112architecture-specific files and architecture-independent files. If you
113pass the option `--exec-prefix=PREFIX' to `configure', the package uses
114PREFIX as the prefix for installing programs and libraries.
115Documentation and other data files still use the regular prefix.
116
117 In addition, if you use an unusual directory layout you can give
118options like `--bindir=DIR' to specify different values for particular
119kinds of files. Run `configure --help' for a list of the directories
120you can set and what kinds of files go in them.
121
122 If the package supports it, you can cause programs to be installed
123with an extra prefix or suffix on their names by giving `configure' the
124option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
125
126Optional Features
127=================
128
129Some packages pay attention to `--enable-FEATURE' options to
130`configure', where FEATURE indicates an optional part of the package.
131They may also pay attention to `--with-PACKAGE' options, where PACKAGE
132is something like `gnu-as' or `x' (for the X Window System). The
133`README' should mention any `--enable-' and `--with-' options that the
134package recognizes.
135
136 For packages that use the X Window System, `configure' can usually
137find the X include and library files automatically, but if it doesn't,
138you can use the `configure' options `--x-includes=DIR' and
139`--x-libraries=DIR' to specify their locations.
140
141Specifying the System Type
142==========================
143
144There may be some features `configure' cannot figure out automatically,
145but needs to determine by the type of machine the package will run on.
146Usually, assuming the package is built to be run on the _same_
147architectures, `configure' can figure that out, but if it prints a
148message saying it cannot guess the machine type, give it the
149`--build=TYPE' option. TYPE can either be a short name for the system
150type, such as `sun4', or a canonical name which has the form:
151
152 CPU-COMPANY-SYSTEM
153
154where SYSTEM can have one of these forms:
155
156 OS KERNEL-OS
157
158 See the file `config.sub' for the possible values of each field. If
159`config.sub' isn't included in this package, then this package doesn't
160need to know the machine type.
161
162 If you are _building_ compiler tools for cross-compiling, you should
163use the option `--target=TYPE' to select the type of system they will
164produce code for.
165
166 If you want to _use_ a cross compiler, that generates code for a
167platform different from the build platform, you should specify the
168"host" platform (i.e., that on which the generated programs will
169eventually be run) with `--host=TYPE'.
170
171Sharing Defaults
172================
173
174If you want to set default values for `configure' scripts to share, you
175can create a site shell script called `config.site' that gives default
176values for variables like `CC', `cache_file', and `prefix'.
177`configure' looks for `PREFIX/share/config.site' if it exists, then
178`PREFIX/etc/config.site' if it exists. Or, you can set the
179`CONFIG_SITE' environment variable to the location of the site script.
180A warning: not all `configure' scripts look for a site script.
181
182Defining Variables
183==================
184
185Variables not defined in a site shell script can be set in the
186environment passed to `configure'. However, some packages may run
187configure again during the build, and the customized values of these
188variables may be lost. In order to avoid this problem, you should set
189them in the `configure' command line, using `VAR=value'. For example:
190
191 ./configure CC=/usr/local2/bin/gcc
192
193causes the specified `gcc' to be used as the C compiler (unless it is
194overridden in the site shell script).
195
196Unfortunately, this technique does not work for `CONFIG_SHELL' due to
197an Autoconf bug. Until the bug is fixed you can use this workaround:
198
199 CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
200
201`configure' Invocation
202======================
203
204`configure' recognizes the following options to control how it operates.
205
206`--help'
207`-h'
208 Print a summary of the options to `configure', and exit.
209
210`--version'
211`-V'
212 Print the version of Autoconf used to generate the `configure'
213 script, and exit.
214
215`--cache-file=FILE'
216 Enable the cache: use and save the results of the tests in FILE,
217 traditionally `config.cache'. FILE defaults to `/dev/null' to
218 disable caching.
219
220`--config-cache'
221`-C'
222 Alias for `--cache-file=config.cache'.
223
224`--quiet'
225`--silent'
226`-q'
227 Do not print messages saying which checks are being made. To
228 suppress all normal output, redirect it to `/dev/null' (any error
229 messages will still be shown).
230
231`--srcdir=DIR'
232 Look for the package's source code in directory DIR. Usually
233 `configure' can determine that directory automatically.
234
235`configure' also accepts some other, not widely useful, options. Run
236`configure --help' for more details.
237
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 000000000..c736a533d
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,14 @@
1INCLUDES = -I$(top_srcdir)/src/include
2SUBDIRS = contrib src po
3
4EXTRA_DIST = \
5 ABOUT-NLS \
6 config.rpath \
7 install-sh \
8 HACKING \
9 UPDATING \
10 PLATFORMS \
11 acinclude.m4
12
13ACLOCAL_AMFLAGS = -I m4
14
diff --git a/NEWS b/NEWS
new file mode 100644
index 000000000..898a3dab3
--- /dev/null
+++ b/NEWS
@@ -0,0 +1 @@
See ChangeLog.
diff --git a/RATIONALE b/RATIONALE
new file mode 100644
index 000000000..e68dcb883
--- /dev/null
+++ b/RATIONALE
@@ -0,0 +1,246 @@
1This document is a summary of why we're moving to GNUnet NG and what
2this major redesign tries to address.
3
4First of all, the redesign does not (intentionally) change anything
5fundamental about the application-level protocols or how files are
6encoded and shared. However, it is not protocol-compatible due to
7other changes that do not relate to the essence of the application
8protocols.
9
10
11The redesign tries to address the following major problem groups
12describing isssues that apply more or less to all GNUnet versions
13prior to 0.9.x:
14
15
16PROBLEM GROUP 1 (scalability):
17* The code was modular, but bugs were not. Memory corruption
18 in one plugin could cause crashes in others and it was not
19 always easy to identify the culprit. This approach
20 fundamentally does not scale (in the sense of GNUnet being
21 a framework and a GNUnet server running hundreds of
22 different application protocols -- and the result still
23 being debuggable, secure and stable).
24* The code was heavily multi-threaded resulting in complex
25 locking operations. GNUnet 0.8.x had over 70 different
26 mutexes and almost 1000 lines of lock/unlock operations.
27 It is challenging for even good programmers to program or
28 maintain good multi-threaded code with this complexity.
29 The excessive locking essentially prevents GNUnet from
30 actually doing much in parallel on multicores.
31* Despite efforts like Freeway, it was virtually
32 impossible to contribute code to GNUnet that was not
33 writen in C/C++.
34* Changes to the configuration almost always required restarts
35 of gnunetd; the existence of change-notifications does not
36 really change that (how many users are even aware of SIGHUP,
37 and how few options worked with that -- and at what expense
38 in code complexity!).
39* Valgrinding could only be done for the entire gnunetd
40 process. Given that gnunetd does quite a bit of
41 CPU-intensive crypto, this could not be done for a system
42 under heavy (or even moderate) load.
43* Stack overflows with threads, while rare under Linux these
44 days, result in really nasty and hard-to-find crashes.
45* structs of function pointers in service APIs were
46 needlessly adding complexity, especially since in
47 most cases there was no polymorphism
48
49SOLUTION:
50* Use multiple, lously-coupled processes and one big select
51 loop in each (supported by a powerful library to eliminate
52 code duplication for each process).
53* Eliminate all threads, manage the processes with a
54 master-process (gnunet-arm, for automatic restart manager)
55 which also ensures that configuration changes trigger the
56 necessary restarts.
57* Use continuations (with timeouts) as a way to unify
58 cron-jobs and other event-based code (such as waiting
59 on network IO).
60 => Using multiple processes ensures that memory corruption
61 stays localized.
62 => Using multiple processes will make it easy to contribute
63 services written in other language(s).
64 => Individual services can now be subjected to valgrind
65 => Process priorities can be used to schedule the CPU better
66 Note that we can not just use one process with a big
67 select loop because we have blocking operations (and the
68 blocking is outside of our control, thanks MySQL,
69 sqlite, gethostbyaddr, etc.). So in order to perform
70 reasonably well, we need some construct for parallel
71 execution.
72
73 RULE: If your service contains blocking functions, it
74 MUST be a process by itself.
75* Eliminate structs with function pointers for service APIs;
76 instead, provide a library (still ending in _service.h) API
77 that transmits the requests nicely to the respective
78 process (easier to use, no need to "request" service
79 in the first place; API can cause process to be started/stopped
80 via ARM if necessary).
81
82
83PROBLEM GROUP 2 (UTIL-APIs causing bugs):
84* The existing logging functions were awkward to use and
85 their expressive power was never really used for much.
86* While we had some rules for naming functions, there
87 were still plenty of inconsistencies.
88* Specification of default values in configuration could
89 result in inconsistencies between defaults in
90 config.scm and defaults used by the program; also,
91 different defaults might have been specified for the
92 same option in different parts of the program.
93* The TIME API did not distinguish between absolute
94 and relative time, requiring users to know which
95 type of value some variable contained and to
96 manually convert properly. Combined with the
97 possibility of integer overflows this is a major
98 source of bugs.
99* The TIME API for seconds has a theoretical problem
100 with a 32-bit overflow on some platforms which is
101 only partially fixed by the old code with some
102 hackery.
103
104SOLUTION:
105* Logging was radically simplified.
106* Functions are now more conistently named.
107* Configuration has no more defaults; instead,
108 we load a global default configuration file
109 before the user-specific configuration (which
110 can be used to override defaults); the global
111 default configuration file will be generated
112 from config.scm.
113* Time now distinguishes between
114 struct GNUNET_TIME_Absolute and
115 struct GNUNET_TIME_Relative. We use structs
116 so that the compiler won't coerce for us
117 (forcing the use of specific conversion
118 functions which have checks for overflows, etc.).
119 Naturally the need to use these functions makes
120 the code a bit more verbose, but that's a good
121 thing given the potential for bugs.
122* There is no more TIME API function to do anything
123 with 32-bit seconds
124
125
126PROBLEM GROUP 3 (statistics):
127* Databases and others needed to store capacity values
128 similar to what stats was already doing, but
129 across process lifetimes ("state"-API was a partial
130 solution for that, but using it was clunky)
131* Only gnunetd could use statistics, but other
132 processes in the GNUnet system might have had
133 good uses for it as well
134
135SOLUTION:
136* New statistics library and service that offer
137 an API to inspect and modify statistics
138* Statistics are distinguished by service name
139 in addition to the name of the value
140* Statistics can be marked as persistent, in
141 which case they are written to disk when
142 the statistics service shuts down.
143 => One solution for existing stats uses,
144 application stats, database stats and
145 versioning information!
146
147
148PROBLEM GROUP 4 (Testing):
149* The existing structure of the code with modules
150 stored in places far away from the test code
151 resulted in tools like lcov not giving good results.
152* The codebase had evolved into a complex, deeply
153 nested hierarchy often with directories that
154 then only contained a single file. Some of these
155 files had the same name making it hard to find
156 the source corresponding to a crash based on
157 the reported filename/line information.
158* Non-trivial portions of the code lacked good testcases,
159 and it was not always obvious which parts of the code
160 were not well-tested.
161
162SOLUTION:
163* Code that should be tested together is now
164 in the same directory.
165* The hierarchy is now essentially flat, each
166 major service having on directory under src/;
167 naming conventions help to make sure that
168 files have globally-unique names
169* All code added to the new repository must
170 come with testcases with reasonable coverage.
171
172
173PROBLEM GROUP 5 (core/transports):
174* The new DV service requires session key exchange
175 between DV-neighbours, but the existing
176 session key code can not be used to achieve this.
177* The core requires certain services
178 (such as identity, pingpong, fragmentation,
179 transport, traffic, session) which makes it
180 meaningless to have these as modules
181 (especially since there is really only one
182 way to implement these)
183* HELLO's are larger than necessary since we need
184 one for each transport (and hence often have
185 to pick a subset of our HELLOs to transmit)
186* Fragmentation is done at the core level but only
187 required for a few transports; future versions of
188 these transports might want to be aware of fragments
189 and do things like retransmission
190* Autoconfiguration is hard since we have no good
191 way to detect (and then use securely) our external IP address
192* It is currently not possible for multiple transports
193 between the same pair of peers to be used concurrently
194 in the same direction(s)
195* We're using lots of cron-based jobs to periodically
196 try (and fail) to build and transmit
197
198SOLUTION:
199* Rewrite core to integrate most of these services
200 into one "core" service.
201* Redesign HELLO to contain the addresses for
202 all enabled transports in one message (avoiding
203 having to transmit the public key and signature
204 many, many times)
205* With discovery being part of the transport service,
206 it is now also possible to "learn" our external
207 IP address from other peers (we just add plausible
208 addresses to the list; other peers will discard
209 those addresses that don't work for them!)
210* New DV will consist of a "transport" and a
211 high-level service (to handle encrypted DV
212 control- and data-messages).
213* Move expiration from one field per HELLO to one
214 per address
215* Require signature in PONG, not in HELLO (and confirm
216 on address at a time)
217* Move fragmentation into helper library linked
218 against by UDP (and others that might need it)
219* Link-to-link advertising of our HELLO is transport
220 responsibility; global advertising/bootstrap remains
221 responsibility of higher layers
222* Change APIs to be event-based (transports pull for
223 transmission data instead of core pushing and failing)
224
225
226PROBLEM GROUP 6 (FS-APIs):
227* As with gnunetd, the FS-APIs are heavily threaded,
228 resulting in hard-to-understand code (slightly
229 better than gnunetd, but not much).
230* GTK in particular does not like this, resulting
231 in complicated code to switch to the GTK event
232 thread when needed (which may still be causing
233 problems on Gnome, not sure).
234* If GUIs die (or are not properly shutdown), state
235 of current transactions is lost (FSUI only
236 saves to disk on shutdown)
237
238SOLUTION (draft, not done yet, details missing...):
239* Eliminate threads from FS-APIs
240 => Open question: how to best write the APIs to
241 allow integration with diverse event loops
242 of GUI libraries?
243* Store FS-state always also on disk
244 => Open question: how to do this without
245 compromising state/scalability?
246
diff --git a/README b/README
new file mode 100644
index 000000000..84330e2ab
--- /dev/null
+++ b/README
@@ -0,0 +1,257 @@
1 Welcome to GNUnet
2
3
4What is GNUnet?
5===============
6
7GNUnet is peer-to-peer framework focusing on security. The first and
8primary application for GNUnet is anonymous file-sharing. GNUnet is
9currently developed by a worldwide group of independent free software
10developers. GNUnet is a part of the GNU project (http://www.gnu.org/).
11
12This is a BETA release. While there are no known significant bugs, we
13are still changing significant aspects of the system in any other
14version. While we believe that the system is usable, quite a few
15important features -- which would improve performance make the life of
16users easier -- are still missing. Also, the documentation may not be
17adequate for inexperienced users.
18
19For a longer description of the GNUnet System see our webpages
20http://www.gnu.org/software/gnunet/ and http://gnunet.org/.
21
22
23Dependencies:
24=============
25
26For the impatient, here is the list of immediate dependencies for
27running GNUnet:
28
29- libextractor >= 0.5.20b
30- libgcrypt >= 1.2
31- libgmp >= 4.0
32- libcurl >= 7.15.4
33- libltdl >= 2.2 (part of GNU libtool)
34- libguile >= 1.8 (required for gnunet-setup)
35- GNU adns >= 1.0 (strongly recommended)
36- mysql >= 5.0 (strongly recommended)
37- sqlite >= 3.0 (alternative to MySQL)
38
39Certain gnunet-setup plugins would also like to have:
40- GTK >= 2.6.0
41- Qt >= 4.0
42- dialog >= 1.0-20051207
43- ncurses
44
45Certain transports would also like to have:
46- libmicrohttpd >= 0.4.0b
47- libcurl >= 7.15.4
48- libesmtp >= 1.0.4
49
50
51Recommended autotools for compiling the SVN version are:
52- autoconf >= 2.59
53- automake >= 1.9.4
54- libtool >= 1.5
55- libltdl >= 2.2.0 (only in Debian experimental)
56
57See also README.debian for a list of Debian packages.
58
59
60How to install?
61===============
62
63The fastest way is to use a binary package if it is available for your
64system. For a more detailed description, read the installation
65instructions on the webpage at http://gnunet.org/documentation.php3.
66
67
68If you install from source, you need to install libextractor
69first (download from http://gnunet.org/libextractor/). Then
70you can start the actual GNUnet compilation process with:
71
72$ ./configure --prefix=$HOME --with-extractor=$HOME
73$ make
74# make install
75# gnunet-setup -d
76# gnunetd
77
78This will compile and install GNUnet to ~/bin/, ~/lib/ and ~/man/.
79gnunet-setup will create the daemon configuration (-d); this step is
80interactive. You can run gnunet-setup as root for a system-wide
81installation or as a particular user to create a personal
82installation. If you do not want to run gnunetd as root, gnunet-setup
83can be used to add a user "gnunet". Data will then be stored in
84/var/lib/GNUnet and gnunetd will run as that user. Note that
85additional, per-user configuration files (~/.gnunet/gnunet.conf) also
86need to be created by each user by running gnunet-setup without the -d
87option. Depending on your operating system the wizards of
88gnunet-setup can also be used to create an init script that starts
89gnunetd each time the system boots. For more general information
90about the GNU build process read the INSTALL file.
91
92GNUnet requires the GNU MP library (http://www.gnu.org/software/gmp/)
93and libgcrypt. You can specify the path to libgcrypt by passing
94"--with-gcrypt=PATH" to configure. You will also need either sqlite
95(version 3 or higher) or MySQL (version 5.0 or higher).
96
97If you are compiling the code from subversion, you have to run
98". bootstrap" before ./configure. If you receive an error during the
99running of ". bootstrap" that looks like "macro `AM_PATH_GTK' not
100found in library", you may need to run aclocal by hand with the -I
101option, pointing to your aclocal m4 macros, i.e.
102
103$ aclocal -I /usr/local/share/aclocal
104
105
106Configuration
107=============
108
109GNUnet uses two types of configuration files, one for the daemon
110(called gnunetd.conf) and one for each user (gnunet.conf). You can
111create and edit these configuration files with the gnunet-setup tool.
112You need to add the option "-d" to gnunet-setup in order to edit
113gnunetd.conf (by default, gnunet-setup will edit gnunet.conf). The
114defaults that are created the first time you run gnunet-setup are
115usually ok, you may want to adjust the limitations (space consumption,
116bandwidth, etc.) though. The configuration files are human-readable;
117gnunetd's configuration is typically located at "/etc/gnunetd.conf".
118The per-user configuration file should be at "~/.gnunet/gnunet.conf".
119A default version of the per-user configuration will automatically
120be created whenever you run any tool that needs that particular
121cofniguration file.
122
123You MUST create /etc/gnunetd.conf explicitly before starting gnunetd,
124and the recommended way to do this is to run gnunet-setup -d (plus
125possibly options to specify which user interface you would perfer).
126
127If you want to use a different configuration file, pass the name of
128the configuration file as an argument with the option "-c" to any
129GNUnet application. Sending a SIGHUP to the gnunetd process will
130cause gnunetd to re-read the configuration file. Note that not all
131options can be changed at runtime this way (e.g. to change any port
132number, you must fully restart gnunetd).
133
134After changing certain options (or updating GNUnet) you must re-run
135gnunet-update.
136
137
138Usage
139=====
140
141First, you must obtain an initial list of GNUnet hosts. Knowing a
142single peer is sufficient since after that GNUnet propagates
143information about other peers. Note that the default "gnunetd.conf"
144contains URLs from where gnunetd downloads an initial hostlist
145whenever it is started. If you want to create an alternative URL for
146others to use, the file can be generated on any machine running
147gnunetd by periodically executing
148
149$ cat $GNUNETD_HOME/data/hosts/* > the_file
150
151If the solution with the URL is not feasible for your situation, you
152can also add hosts manually. The GNUnet webpage has a public
153directory of hostkeys under http://gnunet.org/hosts/. You
154can of course use any other source for these files. Copy the hostkeys
155to "$GNUNETD_HOME/data/hosts/" (where $GNUNETD_HOME is the
156directory specified in the /etc/gnunetd.conf configuration file).
157
158Now start the local node using "gnunetd". gnunetd should run 24/7 if
159you want to maximize your anonymity. You may start it as a service
160with "/etc/init.d/gnunetd start". To insert files into GNUnet, use
161the "gnunet-insert" command.
162
163The GTK user interface is shipped separately from GNUnet. After
164downloading and installing gnunet-gtk, you can invoke the GUI with:
165
166$ gnunet-gtk
167
168For Qt/KDE users, there is also a QT user interface (also shipped
169separately). If you install gnunet-qt, you can invoke the GUI with:
170
171$ gnunet-qt
172
173If you want to use the shell (part of this distribution), use
174
175$ gnunet-search KEYWORD
176
177This will display a list of results to the console. Then use
178
179$ gnunet-download -o FILENAME GNUNET_URI
180
181to retrieve a file. The GNUNET_URI is printed by gnunet-search
182together with a description.
183
184In order to share files, the easiest way is to create a directory
185with the files (and directories) that you want to share and run
186
187$ nohup gnunet-auto-share NAME-OF-THE-DIRECTORY &
188
189For further documentation, see our webpage.
190
191
192Hacking GNUnet
193==============
194
195Contributions are welcome, please submit bugs to
196https://gnunet.org/mantis/. Please make sure to run contrib/report.sh
197and include the output with your bug reports. More about how to
198report bugs can be found in the GNUnet FAQ on the webpage. Submit
199patches via E-Mail to gnunet-developers@gnu.org.
200
201In order to run the unit tests with "make check", you need to
202set an environment variable ("GNUNET_PREFIX") to the directory
203where GNUnet is installed (usually, GNUnet will use OS specific
204tricks in order to try to figure out the PREFIX, but since the
205testcase binaries are not installed, that trick does not work
206for them). Also, before running any testcases, you must
207complete the installation first. Quick summary:
208
209$ ./configure --prefix=$SOMEWHERE
210$ make
211$ make install
212$ export GNUNET_PREFIX=$SOMEWHERE
213$ make check
214
215If any testcases fail to pass on your system, run "contrib/report.sh"
216and report the output together with information about the failing
217testcase to the Mantis bugtracking system at
218https://gnunet.org/mantis/.
219
220
221Running http on port 80
222=======================
223
224In order to hide GNUnet's HTTP traffic perfectly, you might consider
225running GNUnet's HTTP transport on port 80. However, you should not
226run GNUnet as root. Instead, forward port 80 to say 8080 with this
227command (as root, in your startup scripts):
228
229# iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
230
231Then set in the HTTP section of gnunetd.conf the "ADVERTISED-PORT"
232to "80" and "PORT" to 8080. You can do the same trick for the
233TCP and UDP transports if you want to map them to a priviledged
234port (from the point of view of the network).
235
236
237Running the SMTP transport
238==========================
239
240Running GNUnet over SMTP (e-mail) is a bit more involved. Note that
241you do not need to run all transports (only running the NAT transport
242is the only thing that will not work). If you really want to do
243P2P over SMTP, read the instructions at http://gnunet.org/smtp.php3
244
245
246Stay tuned
247==========
248
249* http://www.gnu.org/software/gnunet/
250* http://gnunet.org/
251* https://gnunet.org/mantis/
252* https://gnunet.org/drupal/
253* http://mail.gnu.org/mailman/listinfo/gnunet-developers
254* http://mail.gnu.org/mailman/listinfo/help-gnunet
255* http://mail.gnu.org/mailman/listinfo/info-gnunet
256* http://mail.gnu.org/mailman/listinfo/gnunet-svn
257
diff --git a/TODO b/TODO
new file mode 100644
index 000000000..8c97584cc
--- /dev/null
+++ b/TODO
@@ -0,0 +1,150 @@
1PHASE #1: (Goal: settle key design questions)
2
3Core:
4* API review: should "bpm" and "last_activity" arguments be
5 included in the ClientEventHandler?
6* Internal: topology
7* Internal: bandwidth allocation (inbound limits, trust)
8* Internal: advertising (propagate other peers' HELLOs, find new ones)
9* Internal: bootstrapping
10 => bootstrap should use plugins, possible multiple at the same time!
11
12Util:
13* Should "server" argument be given in event callbacks?
14* consider adding "get_time" to "configuration" API
15
16
17PHASE #2: (Goal: recover basic core functionality)
18
19Datastores:
20* implement sqlite-based sqstore/datastore service
21 + implement library (talks to service)
22 + implement service (datastore + talks to plugin)
23 + implement sqlite plugin (talks to DB)
24* implement sqlite-based dstore services
25 + implement library (talks to service)
26 + implement service (talks to plugin)
27 + implement sqlite plugin (talks to DB)
28
29Applications:
30* implement hostlist service (need to bootstrap!)
31* DHT, DV
32* FS / fs-libs
33
34Databases:
35* mysql & postgres backend
36
37Transports:
38* UDP backend (need LIBRARY to support (de)fragmentation!)
39* HTTP backend
40* Testing:
41 + Testcases for set_quota, timeouts, disconnects, transmit_ready_cancel
42 + Better coverage of gnunet-service-transport (hello validation)
43 + direct test of plugins compliance to plugin API
44
45
46PHASE #3: (Goal: ready for pre-release) [completion-goal: end of 2009]
47
48* testing
49* setup
50* gtk, qt GUIs
51* tbench
52* tracekit
53* vpn
54
55
56
57Minor TODO items:
58* SERVER:
59 - inefficient memmove
60* TRANSPORT:
61 - transport_api: support forcing disconnects through low quotas!
62 - API: consider having core provide priority and possibly
63 deadline information for each message
64 (likely important for DV plugin which wants to loop back!)
65 - implement transport API to pretty-print transport address
66 + transport_api extension (API extension!)
67 + service-transport extension (protocol extension)
68 - add calls to statistics in various places
69 - implement gnunet-transport (transport configurator / tester)
70 - UPnP-based IP detection
71 (Note: build library always, build service when libxml2/etc. are available)
72 - instantly filter addresses from *other* peers that
73 are *equal* to our own address + port (i.e., localhost:2086). We
74 no longer filter those for outgoing (helps with loopback testing
75 and keeps the code clean), but we should filter strictly *impossible*
76 incoming addresses! This is for efficiency, not correctness.
77 - We currently are happy to take any address told to us in a WELCOME
78 to our set of addresses; we should have some minimal threshold-based
79 scheme, limiting both the total number of addresses that we accept
80 this way as well as requiring multiple confirmations; also, we
81 should possibly try to confirm that the given address works for
82 us ourselves (loopback-style) before adding it to the list
83 [SECURITY issue]
84 - not sure current way of doing ACKs works well-enough
85 with unreliable transports where the ACK maybe lost;
86 the "is_new" check would then possibly prevent future
87 ACKs to be delivered, all while we're happily
88 receiving messages from that peer! Worse, the other
89 peer won't generate another ACK since it thinks we're
90 connected just fine...
91 Key questions:
92 + How necessary is ACKing in the first place? (alternatives?)
93 + Should we transmit ACKs in response to every HELLO? (would that
94 fully address the problem?)
95 - latency measurements implemented in the transport
96 plugins makes it only work for bi-di transports
97 and results in code replication
98 - should latency be included in the ReceiveCallback and
99 NotifyConnect or passed on request?
100* SETUP:
101 - auto-generate "defaults.conf" using gnunet-setup from "config.scm"
102 - integrate all options into "config.scm"
103 - change config-file writing to exclude options set to default values
104* ARM:
105 - implement exponential back-off for service restarts
106 - better tracking of which config changes actually need to cause process restarts by ARM.
107 - have way to specify dependencies between services (to manage ARM restarts better)
108* PEERINFO:
109 - have gnunet-peerinfo print actual host addresses again
110 - add option to gnunet-peerinfo to modify trust value
111* POSTGRES-DB:
112 - finish postgres implementation; simplify other SQLs using new stats
113* HTTPS transport
114 - PolariSSL for MHD?
115 - https integration
116* GAP improvements:
117 - active reply route caching design & implementation of service,
118 gap extension!
119
120=> PRE-RELEASE
121
122PHASE #4: [completion-goal: mid 2010]
123* Documentation
124* new webpage
125
126
127
128
129Stuff to remember:
130* Features eliminated from util:
131 - threading (goal: good riddance!)
132 - complex logging features [ectx-passing, target-kinds] (goal: good riddance!)
133 - complex configuration features [defaults, notifications] (goal: good riddance!)
134 - network traffic monitors (goal: eliminate)
135 - IPC semaphores (goal: d-bus? / eliminate?)
136 - second timers
137 - DNS lookup (goal: have async service; issue: still need synchronous resolution in places, current code may not be portable)
138 => code shrunk from 61 files to 34, 22k LOC to 15k LOC, 470k to 330k (with symbols)
139* New features in util:
140 - scheduler
141 - service and program boot-strap code
142* Major changes in util:
143 - more expressive server (replaces selector)
144* Open questions:
145 - how to integrate scheduler with GTK event loop!
146
147
148
149Test coverage:
150* UTIL: 75%, 4914 out of 6463
diff --git a/bin/grephdr.sh b/bin/grephdr.sh
new file mode 100755
index 000000000..b0f979196
--- /dev/null
+++ b/bin/grephdr.sh
@@ -0,0 +1,3 @@
1#!/bin/sh
2# grepsrc.sh string --- greps for string over all java files
3find . -name "*.h" -print | grep -v "#" | xargs grep "$@"
diff --git a/bin/grepsrc.sh b/bin/grepsrc.sh
new file mode 100755
index 000000000..0c18dd7d2
--- /dev/null
+++ b/bin/grepsrc.sh
@@ -0,0 +1,3 @@
1#!/bin/sh
2# grepsrc.sh string --- greps for string over all C files
3find . -name "*.c" -print | grep -v "#" | xargs grep -n "$*"
diff --git a/bin/rename.sh b/bin/rename.sh
new file mode 100755
index 000000000..7d5790b41
--- /dev/null
+++ b/bin/rename.sh
@@ -0,0 +1,6 @@
1#!/bin/sh
2for n in `find * -name "*.c"` `find * -name "*.h"`
3do
4 cat $n | sed -e "s/$1/$2/g" > $n.new
5 mv $n.new $n || echo "Move failed: $n.new to $n"
6done
diff --git a/bootstrap b/bootstrap
new file mode 100755
index 000000000..e5ddbc6a8
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,7 @@
1#!/bin/sh
2libtoolize -ifc
3aclocal -I m4
4autoheader
5autoconf
6automake --add-missing --copy
7
diff --git a/config.rpath b/config.rpath
new file mode 100755
index 000000000..c492a93b6
--- /dev/null
+++ b/config.rpath
@@ -0,0 +1,614 @@
1#! /bin/sh
2# Output a system dependent set of variables, describing how to set the
3# run time search path of shared libraries in an executable.
4#
5# Copyright 1996-2006 Free Software Foundation, Inc.
6# Taken from GNU libtool, 2001
7# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
8#
9# This file is free software; the Free Software Foundation gives
10# unlimited permission to copy and/or distribute it, with or without
11# modifications, as long as this notice is preserved.
12#
13# The first argument passed to this file is the canonical host specification,
14# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
15# or
16# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
17# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
18# should be set by the caller.
19#
20# The set of defined variables is at the end of this script.
21
22# Known limitations:
23# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
24# than 256 bytes, otherwise the compiler driver will dump core. The only
25# known workaround is to choose shorter directory names for the build
26# directory and/or the installation directory.
27
28# All known linkers require a `.a' archive for static linking (except MSVC,
29# which needs '.lib').
30libext=a
31shrext=.so
32
33host="$1"
34host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
35host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
36host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
37
38# Code taken from libtool.m4's _LT_CC_BASENAME.
39
40for cc_temp in $CC""; do
41 case $cc_temp in
42 compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
43 distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
44 \-*) ;;
45 *) break;;
46 esac
47done
48cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
49
50# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
51
52wl=
53if test "$GCC" = yes; then
54 wl='-Wl,'
55else
56 case "$host_os" in
57 aix*)
58 wl='-Wl,'
59 ;;
60 darwin*)
61 case $cc_basename in
62 xlc*)
63 wl='-Wl,'
64 ;;
65 esac
66 ;;
67 mingw* | pw32* | os2*)
68 ;;
69 hpux9* | hpux10* | hpux11*)
70 wl='-Wl,'
71 ;;
72 irix5* | irix6* | nonstopux*)
73 wl='-Wl,'
74 ;;
75 newsos6)
76 ;;
77 linux*)
78 case $cc_basename in
79 icc* | ecc*)
80 wl='-Wl,'
81 ;;
82 pgcc | pgf77 | pgf90)
83 wl='-Wl,'
84 ;;
85 ccc*)
86 wl='-Wl,'
87 ;;
88 como)
89 wl='-lopt='
90 ;;
91 *)
92 case `$CC -V 2>&1 | sed 5q` in
93 *Sun\ C*)
94 wl='-Wl,'
95 ;;
96 esac
97 ;;
98 esac
99 ;;
100 osf3* | osf4* | osf5*)
101 wl='-Wl,'
102 ;;
103 sco3.2v5*)
104 ;;
105 solaris*)
106 wl='-Wl,'
107 ;;
108 sunos4*)
109 wl='-Qoption ld '
110 ;;
111 sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
112 wl='-Wl,'
113 ;;
114 sysv4*MP*)
115 ;;
116 unicos*)
117 wl='-Wl,'
118 ;;
119 uts4*)
120 ;;
121 esac
122fi
123
124# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
125
126hardcode_libdir_flag_spec=
127hardcode_libdir_separator=
128hardcode_direct=no
129hardcode_minus_L=no
130
131case "$host_os" in
132 cygwin* | mingw* | pw32*)
133 # FIXME: the MSVC++ port hasn't been tested in a loooong time
134 # When not using gcc, we currently assume that we are using
135 # Microsoft Visual C++.
136 if test "$GCC" != yes; then
137 with_gnu_ld=no
138 fi
139 ;;
140 interix*)
141 # we just hope/assume this is gcc and not c89 (= MSVC++)
142 with_gnu_ld=yes
143 ;;
144 openbsd*)
145 with_gnu_ld=no
146 ;;
147esac
148
149ld_shlibs=yes
150if test "$with_gnu_ld" = yes; then
151 # Set some defaults for GNU ld with shared library support. These
152 # are reset later if shared libraries are not supported. Putting them
153 # here allows them to be overridden if necessary.
154 # Unlike libtool, we use -rpath here, not --rpath, since the documented
155 # option of GNU ld is called -rpath, not --rpath.
156 hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
157 case "$host_os" in
158 aix3* | aix4* | aix5*)
159 # On AIX/PPC, the GNU linker is very broken
160 if test "$host_cpu" != ia64; then
161 ld_shlibs=no
162 fi
163 ;;
164 amigaos*)
165 hardcode_libdir_flag_spec='-L$libdir'
166 hardcode_minus_L=yes
167 # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
168 # that the semantics of dynamic libraries on AmigaOS, at least up
169 # to version 4, is to share data among multiple programs linked
170 # with the same dynamic library. Since this doesn't match the
171 # behavior of shared libraries on other platforms, we cannot use
172 # them.
173 ld_shlibs=no
174 ;;
175 beos*)
176 if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
177 :
178 else
179 ld_shlibs=no
180 fi
181 ;;
182 cygwin* | mingw* | pw32*)
183 # hardcode_libdir_flag_spec is actually meaningless, as there is
184 # no search path for DLLs.
185 hardcode_libdir_flag_spec='-L$libdir'
186 if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
187 :
188 else
189 ld_shlibs=no
190 fi
191 ;;
192 interix3*)
193 hardcode_direct=no
194 hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
195 ;;
196 linux*)
197 if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
198 :
199 else
200 ld_shlibs=no
201 fi
202 ;;
203 netbsd*)
204 ;;
205 solaris*)
206 if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
207 ld_shlibs=no
208 elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
209 :
210 else
211 ld_shlibs=no
212 fi
213 ;;
214 sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
215 case `$LD -v 2>&1` in
216 *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
217 ld_shlibs=no
218 ;;
219 *)
220 if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
221 hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
222 else
223 ld_shlibs=no
224 fi
225 ;;
226 esac
227 ;;
228 sunos4*)
229 hardcode_direct=yes
230 ;;
231 *)
232 if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
233 :
234 else
235 ld_shlibs=no
236 fi
237 ;;
238 esac
239 if test "$ld_shlibs" = no; then
240 hardcode_libdir_flag_spec=
241 fi
242else
243 case "$host_os" in
244 aix3*)
245 # Note: this linker hardcodes the directories in LIBPATH if there
246 # are no directories specified by -L.
247 hardcode_minus_L=yes
248 if test "$GCC" = yes; then
249 # Neither direct hardcoding nor static linking is supported with a
250 # broken collect2.
251 hardcode_direct=unsupported
252 fi
253 ;;
254 aix4* | aix5*)
255 if test "$host_cpu" = ia64; then
256 # On IA64, the linker does run time linking by default, so we don't
257 # have to do anything special.
258 aix_use_runtimelinking=no
259 else
260 aix_use_runtimelinking=no
261 # Test if we are trying to use run time linking or normal
262 # AIX style linking. If -brtl is somewhere in LDFLAGS, we
263 # need to do runtime linking.
264 case $host_os in aix4.[23]|aix4.[23].*|aix5*)
265 for ld_flag in $LDFLAGS; do
266 if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
267 aix_use_runtimelinking=yes
268 break
269 fi
270 done
271 ;;
272 esac
273 fi
274 hardcode_direct=yes
275 hardcode_libdir_separator=':'
276 if test "$GCC" = yes; then
277 case $host_os in aix4.[012]|aix4.[012].*)
278 collect2name=`${CC} -print-prog-name=collect2`
279 if test -f "$collect2name" && \
280 strings "$collect2name" | grep resolve_lib_name >/dev/null
281 then
282 # We have reworked collect2
283 hardcode_direct=yes
284 else
285 # We have old collect2
286 hardcode_direct=unsupported
287 hardcode_minus_L=yes
288 hardcode_libdir_flag_spec='-L$libdir'
289 hardcode_libdir_separator=
290 fi
291 ;;
292 esac
293 fi
294 # Begin _LT_AC_SYS_LIBPATH_AIX.
295 echo 'int main () { return 0; }' > conftest.c
296 ${CC} ${LDFLAGS} conftest.c -o conftest
297 aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
298}'`
299 if test -z "$aix_libpath"; then
300 aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
301}'`
302 fi
303 if test -z "$aix_libpath"; then
304 aix_libpath="/usr/lib:/lib"
305 fi
306 rm -f conftest.c conftest
307 # End _LT_AC_SYS_LIBPATH_AIX.
308 if test "$aix_use_runtimelinking" = yes; then
309 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
310 else
311 if test "$host_cpu" = ia64; then
312 hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
313 else
314 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
315 fi
316 fi
317 ;;
318 amigaos*)
319 hardcode_libdir_flag_spec='-L$libdir'
320 hardcode_minus_L=yes
321 # see comment about different semantics on the GNU ld section
322 ld_shlibs=no
323 ;;
324 bsdi[45]*)
325 ;;
326 cygwin* | mingw* | pw32*)
327 # When not using gcc, we currently assume that we are using
328 # Microsoft Visual C++.
329 # hardcode_libdir_flag_spec is actually meaningless, as there is
330 # no search path for DLLs.
331 hardcode_libdir_flag_spec=' '
332 libext=lib
333 ;;
334 darwin* | rhapsody*)
335 hardcode_direct=no
336 if test "$GCC" = yes ; then
337 :
338 else
339 case $cc_basename in
340 xlc*)
341 ;;
342 *)
343 ld_shlibs=no
344 ;;
345 esac
346 fi
347 ;;
348 dgux*)
349 hardcode_libdir_flag_spec='-L$libdir'
350 ;;
351 freebsd1*)
352 ld_shlibs=no
353 ;;
354 freebsd2.2*)
355 hardcode_libdir_flag_spec='-R$libdir'
356 hardcode_direct=yes
357 ;;
358 freebsd2*)
359 hardcode_direct=yes
360 hardcode_minus_L=yes
361 ;;
362 freebsd* | kfreebsd*-gnu | dragonfly*)
363 hardcode_libdir_flag_spec='-R$libdir'
364 hardcode_direct=yes
365 ;;
366 hpux9*)
367 hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
368 hardcode_libdir_separator=:
369 hardcode_direct=yes
370 # hardcode_minus_L: Not really in the search PATH,
371 # but as the default location of the library.
372 hardcode_minus_L=yes
373 ;;
374 hpux10*)
375 if test "$with_gnu_ld" = no; then
376 hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
377 hardcode_libdir_separator=:
378 hardcode_direct=yes
379 # hardcode_minus_L: Not really in the search PATH,
380 # but as the default location of the library.
381 hardcode_minus_L=yes
382 fi
383 ;;
384 hpux11*)
385 if test "$with_gnu_ld" = no; then
386 hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
387 hardcode_libdir_separator=:
388 case $host_cpu in
389 hppa*64*|ia64*)
390 hardcode_direct=no
391 ;;
392 *)
393 hardcode_direct=yes
394 # hardcode_minus_L: Not really in the search PATH,
395 # but as the default location of the library.
396 hardcode_minus_L=yes
397 ;;
398 esac
399 fi
400 ;;
401 irix5* | irix6* | nonstopux*)
402 hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
403 hardcode_libdir_separator=:
404 ;;
405 netbsd*)
406 hardcode_libdir_flag_spec='-R$libdir'
407 hardcode_direct=yes
408 ;;
409 newsos6)
410 hardcode_direct=yes
411 hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
412 hardcode_libdir_separator=:
413 ;;
414 openbsd*)
415 hardcode_direct=yes
416 if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
417 hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
418 else
419 case "$host_os" in
420 openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
421 hardcode_libdir_flag_spec='-R$libdir'
422 ;;
423 *)
424 hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
425 ;;
426 esac
427 fi
428 ;;
429 os2*)
430 hardcode_libdir_flag_spec='-L$libdir'
431 hardcode_minus_L=yes
432 ;;
433 osf3*)
434 hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
435 hardcode_libdir_separator=:
436 ;;
437 osf4* | osf5*)
438 if test "$GCC" = yes; then
439 hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
440 else
441 # Both cc and cxx compiler support -rpath directly
442 hardcode_libdir_flag_spec='-rpath $libdir'
443 fi
444 hardcode_libdir_separator=:
445 ;;
446 solaris*)
447 hardcode_libdir_flag_spec='-R$libdir'
448 ;;
449 sunos4*)
450 hardcode_libdir_flag_spec='-L$libdir'
451 hardcode_direct=yes
452 hardcode_minus_L=yes
453 ;;
454 sysv4)
455 case $host_vendor in
456 sni)
457 hardcode_direct=yes # is this really true???
458 ;;
459 siemens)
460 hardcode_direct=no
461 ;;
462 motorola)
463 hardcode_direct=no #Motorola manual says yes, but my tests say they lie
464 ;;
465 esac
466 ;;
467 sysv4.3*)
468 ;;
469 sysv4*MP*)
470 if test -d /usr/nec; then
471 ld_shlibs=yes
472 fi
473 ;;
474 sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
475 ;;
476 sysv5* | sco3.2v5* | sco5v6*)
477 hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
478 hardcode_libdir_separator=':'
479 ;;
480 uts4*)
481 hardcode_libdir_flag_spec='-L$libdir'
482 ;;
483 *)
484 ld_shlibs=no
485 ;;
486 esac
487fi
488
489# Check dynamic linker characteristics
490# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
491libname_spec='lib$name'
492case "$host_os" in
493 aix3*)
494 ;;
495 aix4* | aix5*)
496 ;;
497 amigaos*)
498 ;;
499 beos*)
500 ;;
501 bsdi[45]*)
502 ;;
503 cygwin* | mingw* | pw32*)
504 shrext=.dll
505 ;;
506 darwin* | rhapsody*)
507 shrext=.dylib
508 ;;
509 dgux*)
510 ;;
511 freebsd1*)
512 ;;
513 kfreebsd*-gnu)
514 ;;
515 freebsd* | dragonfly*)
516 ;;
517 gnu*)
518 ;;
519 hpux9* | hpux10* | hpux11*)
520 case $host_cpu in
521 ia64*)
522 shrext=.so
523 ;;
524 hppa*64*)
525 shrext=.sl
526 ;;
527 *)
528 shrext=.sl
529 ;;
530 esac
531 ;;
532 interix3*)
533 ;;
534 irix5* | irix6* | nonstopux*)
535 case "$host_os" in
536 irix5* | nonstopux*)
537 libsuff= shlibsuff=
538 ;;
539 *)
540 case $LD in
541 *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
542 *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
543 *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
544 *) libsuff= shlibsuff= ;;
545 esac
546 ;;
547 esac
548 ;;
549 linux*oldld* | linux*aout* | linux*coff*)
550 ;;
551 linux*)
552 ;;
553 knetbsd*-gnu)
554 ;;
555 netbsd*)
556 ;;
557 newsos6)
558 ;;
559 nto-qnx*)
560 ;;
561 openbsd*)
562 ;;
563 os2*)
564 libname_spec='$name'
565 shrext=.dll
566 ;;
567 osf3* | osf4* | osf5*)
568 ;;
569 solaris*)
570 ;;
571 sunos4*)
572 ;;
573 sysv4 | sysv4.3*)
574 ;;
575 sysv4*MP*)
576 ;;
577 sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
578 ;;
579 uts4*)
580 ;;
581esac
582
583sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
584escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
585shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
586escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
587
588LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
589
590# How to pass a linker flag through the compiler.
591wl="$escaped_wl"
592
593# Static library suffix (normally "a").
594libext="$libext"
595
596# Shared library suffix (normally "so").
597shlibext="$shlibext"
598
599# Flag to hardcode \$libdir into a binary during linking.
600# This must work even if \$libdir does not exist.
601hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
602
603# Whether we need a single -rpath flag with a separated argument.
604hardcode_libdir_separator="$hardcode_libdir_separator"
605
606# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
607# resulting binary.
608hardcode_direct="$hardcode_direct"
609
610# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
611# resulting binary.
612hardcode_minus_L="$hardcode_minus_L"
613
614EOF
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 000000000..ff6a91d33
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,821 @@
1# This file is part of GNUnet.
2# (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors)
3#
4# GNUnet is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published
6# by the Free Software Foundation; either version 2, or (at your
7# option) any later version.
8#
9# GNUnet is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12# General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with GNUnet; see the file COPYING. If not, write to the
16# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17# Boston, MA 02111-1307, USA.
18#
19#
20# Process this file with autoconf to produce a configure script.
21#
22#
23AC_PREREQ(2.61)
24AC_INIT([gnunet], [0.9.0pre0],[bug-gnunet@gnu.org])
25AM_INIT_AUTOMAKE([gnunet], [0.9.0pre0])
26AC_CONFIG_HEADERS([gnunet_config.h])
27
28AH_TOP([#define _GNU_SOURCE 1])
29
30# Checks for programs.
31AC_CANONICAL_HOST
32AC_PROG_AWK
33AC_PROG_CC
34AC_PROG_CPP
35AC_PROG_CXX
36AC_PROG_OBJC
37AC_PROG_INSTALL
38AC_PROG_LN_S
39AC_PROG_MAKE_SET
40LT_CONFIG_LTDL_DIR([libltdl])
41AC_CANONICAL_HOST
42LT_INIT([disable-static dlopen win32-dll])
43LTDL_INIT
44AC_SUBST(LTDLINCL)
45AC_SUBST(LIBLTDL)
46AC_SUBST(MKDIR_P)
47
48# large file support
49AC_SYS_LARGEFILE
50AC_FUNC_FSEEKO
51
52
53if test "$enable_shared" = "no"
54then
55 AC_MSG_ERROR([GNUnet only works with shared libraries. Sorry.])
56fi
57
58CFLAGS="-Wall $CFLAGS"
59# use '-fno-strict-aliasing', but only if the compiler can take it
60if gcc -fno-strict-aliasing -S -o /dev/null -xc /dev/null >/dev/null 2>&1;
61then
62 CFLAGS="-fno-strict-aliasing $CFLAGS"
63fi
64
65# Use Linux interface name unless the OS has a different preference
66DEFAULT_INTERFACE="\"eth0\""
67
68# Check system type
69case "$host_os" in
70*darwin* | *rhapsody* | *macosx*)
71 AC_DEFINE_UNQUOTED(OSX,1,[This is an OS X system])
72 CFLAGS="-no-cpp-precomp -fno-common $CFLAGS"
73 AC_MSG_WARN([The VPN application cannot be compiled on your OS])
74 build_target="macosx"
75 DEFAULT_INTERFACE="\"en0\""
76 LIBPREFIX=
77 DLLDIR=lib
78 ;;
79linux*)
80 AC_DEFINE_UNQUOTED(LINUX,1,[This is a Linux system])
81 build_target="linux"
82 LIBPREFIX=
83 DLLDIR=lib
84 AC_PATH_XTRA
85 ;;
86freebsd*)
87 AC_DEFINE_UNQUOTED(SOMEBSD,1,[This is a BSD system])
88 AC_DEFINE_UNQUOTED(FREEBSD,1,[This is a FreeBSD system])
89 CFLAGS="-D_THREAD_SAFE $CFLAGS"
90 build_target="freebsd"
91 LIBPREFIX=
92 DLLDIR=lib
93 ;;
94openbsd*)
95 AC_DEFINE_UNQUOTED(SOMEBSD,1,[This is a BSD system])
96 AC_DEFINE_UNQUOTED(OPENBSD,1,[This is an OpenBSD system])
97 LIBS=`echo $LIBS | sed -e "s/-ldl//"`
98 build_target="openbsd"
99 LIBPREFIX=
100 DLLDIR=lib
101 ;;
102netbsd*)
103 AC_DEFINE_UNQUOTED(SOMEBSD,1,[This is a BSD system])
104 AC_DEFINE_UNQUOTED(NETBSD,1,[This is a NetBSD system])
105 LIBPREFIX=
106 DLLDIR=lib
107 ;;
108*solaris*)
109 AC_DEFINE_UNQUOTED(SOLARIS,1,[This is a Solaris system])
110 AC_DEFINE_UNQUOTED(_REENTRANT,1,[Need with solaris or errno doesnt work])
111 AC_CHECK_LIB(resolv, res_init)
112 AC_CHECK_LIB(rt, nanosleep)
113 build_target="solaris"
114 LIBPREFIX=
115 DLLDIR=lib
116 ;;
117*arm-linux*)
118 AC_DEFINE_UNQUOTED(LINUX,1,[This is a Linux system])
119 CFLAGS="-D_REENTRANT -fPIC -pipe $CFLAGS"
120 build_target="linux"
121 LIBPREFIX=
122 DLLDIR=lib
123 ;;
124*cygwin*)
125 AC_DEFINE_UNQUOTED(CYGWIN,1,[This is a Cygwin system])
126 AC_DEFINE_UNQUOTED(WINDOWS,1,[This is a Windows system])
127 AC_CHECK_LIB(intl, gettext)
128 LDFLAGS="$LDFLAGS -no-undefined"
129 CFLAGS="-mms-bitfields $CFLAGS"
130 build_target="cygwin"
131 LIBPREFIX=lib
132 DLLDIR=bin
133 AC_PROG_CXX
134 ;;
135*mingw*)
136 AC_DEFINE_UNQUOTED(MINGW,1,[This is a MinGW system])
137 AC_DEFINE_UNQUOTED(WINDOWS,1,[This is a Windows system])
138 AC_DEFINE_UNQUOTED(_WIN32,1,[This is a Windows system])
139 AC_CHECK_LIB(intl, gettext)
140 LDFLAGS="$LDFLAGS -no-undefined -Wl,--export-all-symbols"
141 LIBS="$LIBS -lws2_32 -lplibc"
142 CFLAGS="-mms-bitfields $CFLAGS"
143 build_target="mingw"
144 AC_PROG_CXX
145 LIBPREFIX=lib
146 DLLDIR=bin
147 ;;
148*)
149 AC_MSG_RESULT(Unrecognised OS $host_os)
150 AC_DEFINE_UNQUOTED(OTHEROS,1,[Some strange OS])
151;;
152esac
153AC_DEFINE_UNQUOTED([GNUNET_DEFAULT_INTERFACE], $DEFAULT_INTERFACE, [This should be the default choice for the name of the first network interface])
154AC_SUBST(DEFAULT_INTERFACE)
155
156AC_MSG_CHECKING([for build target])
157AM_CONDITIONAL(MACOSX, test "$build_target" = "macosx")
158AM_CONDITIONAL(CYGWIN, test "$build_target" = "cygwin")
159AM_CONDITIONAL(MINGW, test "$build_target" = "mingw")
160AM_CONDITIONAL(SOLARIS, test "$build_target" = "solaris")
161AM_CONDITIONAL(XFREEBSD, test "$build_target" = "freebsd")
162AM_CONDITIONAL(OPENBSD, test "$build_target" = "openbsd")
163AM_CONDITIONAL(LINUX, test "$build_target" = "linux")
164AC_MSG_RESULT([$build_target])
165AC_SUBST(build_target)
166AM_CONDITIONAL([am__fastdepOBJC], false)
167AC_UNALIGNED_64_ACCESS
168
169# some other checks for standard libs
170AC_SEARCH_LIBS([gethostbyname], [nsl ws2_32])
171AC_CHECK_LIB(socket, socket)
172AC_CHECK_LIB(m, log)
173AC_CHECK_LIB(c, getloadavg, AC_DEFINE(HAVE_GETLOADAVG,1,[getloadavg supported]))
174
175# 'save' libs; only those libs found so far will be
176# linked against _everywhere_. For the others, we
177# will be more selective!
178SAVE_LIBS=$LIBS
179
180# libgcrypt
181gcrypt=0
182AM_PATH_LIBGCRYPT(1.2.0, gcrypt=1)
183
184if test $gcrypt = 0
185then
186 AC_MSG_ERROR([GNUnet needs libgcrypt])
187fi
188
189
190# libcurl
191LIBCURL_CHECK_CONFIG(,7.15.4,,AC_MSG_ERROR([GNUnet requires libcurl >= 7.15.4]))
192# restore LIBS
193LIBS=$SAVE_LIBS
194
195# restore LIBS
196LIBS=$SAVE_LIBS
197
198# test for kvm and kstat (for CPU stats under BSD/Solaris)
199AC_CHECK_LIB([kvm],[kvm_open])
200AC_CHECK_LIB([kstat],[kstat_open])
201
202# test for libextractor
203extractor=0
204AC_MSG_CHECKING(for libextractor)
205AC_ARG_WITH(extractor,
206 [ --with-extractor=PFX base of libextractor installation],
207 [AC_MSG_RESULT([$with_extractor])
208 case $with_extractor in
209 no)
210 ;;
211 yes)
212 AC_CHECK_HEADERS(extractor.h,
213 AC_CHECK_LIB([extractor], [EXTRACTOR_loadDefaultLibraries],
214 extractor=1))
215 ;;
216 *)
217 LDFLAGS="-L$with_extractor/lib $LDFLAGS"
218 CPPFLAGS="-I$with_extractor/include $CPPFLAGS"
219 AC_CHECK_HEADERS(extractor.h,
220 AC_CHECK_LIB([extractor], [EXTRACTOR_loadDefaultLibraries],
221 EXT_LIB_PATH="-L$with_extractor/lib $EXT_LIB_PATH"
222 extractor=1))
223 ;;
224 esac
225 ],
226 [AC_MSG_RESULT([--with-extractor not specified])
227 AC_CHECK_HEADERS(extractor.h,
228 AC_CHECK_LIB([extractor], [EXTRACTOR_loadDefaultLibraries],
229 extractor=1))])
230if test "$extractor" != 1
231then
232 AC_MSG_ERROR([GNUnet requires libextractor])
233fi
234# restore LIBS
235LIBS=$SAVE_LIBS
236
237
238# Checks for standard header files.
239AC_HEADER_DIRENT
240AC_HEADER_STDC
241
242# Check for headers that are ALWAYS required
243AC_CHECK_HEADERS([fcntl.h math.h errno.h ctype.h limits.h stdio.h stdlib.h string.h unistd.h stdarg.h signal.h locale.h sys/stat.h sys/types.h],,AC_MSG_ERROR([Compiling GNUnet requires standard UNIX headers files]))
244
245# Checks for headers that are only required on some systems or opional (and where we do NOT abort if they are not there)
246AC_CHECK_HEADERS([langinfo.h sys/param.h sys/mount.h sys/statvfs.h sys/select.h sockLib.h sys/mman.h sys/msg.h sys/vfs.h arpa/inet.h fcntl.h libintl.h netdb.h netinet/in.h sys/ioctl.h sys/socket.h sys/time.h unistd.h kstat.h sys/sysinfo.h kvm.h sys/file.h sys/resource.h iconv.h ifaddrs.h mach/mach.h stddef.h sys/timeb.h terminos.h])
247
248# Check for GMP header (and abort if not present)
249AC_CHECK_HEADERS([gmp.h],,AC_MSG_ERROR([Compiling GNUnet requires gmp.h (from the GNU MP library, libgmp)]))
250
251# test for libgmp
252gmp=0
253AC_MSG_CHECKING(for libgmp)
254AC_ARG_WITH(gmp,
255 [ --with-gmp=PFX base of libgmp installation],
256 [AC_MSG_RESULT([$with_gmp])
257 case $with_gmp in
258 no)
259 ;;
260 yes)
261 AC_CHECK_HEADERS(gmp.h,
262 AC_CHECK_LIB([gmp], [__gmpz_add],
263 gmp=1))
264 ;;
265 *)
266 LDFLAGS="-L$with_gmp/lib $LDFLAGS"
267 CPPFLAGS="-I$with_gmp/include $CPPFLAGS"
268 AC_CHECK_HEADERS(gmp.h,
269 AC_CHECK_LIB([gmp], [__gmpz_add],
270 EXT_LIB_PATH="-L$with_gmp/lib $EXT_LIB_PATH"
271 gmp=1))
272 ;;
273 esac
274 ],
275 [AC_MSG_RESULT([--with-gmp not specified])
276 AC_CHECK_HEADERS(gmp.h,
277 AC_CHECK_LIB([gmp], [__gmpz_add],
278 gmp=1))])
279if test "$gmp" != 1
280then
281 AC_MSG_ERROR([GNUnet requires libgmp])
282fi
283
284SAVE_LDFLAGS=$LDFLAGS
285SAVE_CPPFLAGS=$CPPFLAGS
286
287# test for sqlite
288sqlite=false
289AC_MSG_CHECKING(for SQLite)
290AC_ARG_WITH(sqlite,
291 [ --with-sqlite=PFX base of SQLite installation],
292 [AC_MSG_RESULT("$with_sqlite")
293 case $with_sqlite in
294 no)
295 ;;
296 yes)
297 AC_CHECK_HEADERS(sqlite3.h,
298 sqlite=true)
299 ;;
300 *)
301 LDFLAGS="-L$with_sqlite/lib $LDFLAGS"
302 CPPFLAGS="-I$with_sqlite/include $CPPFLAGS"
303 AC_CHECK_HEADERS(sqlite3.h,
304 EXT_LIB_PATH="-L$with_sqlite/lib $EXT_LIB_PATH"
305 SQLITE_LDFLAGS="-L$with_sqlite/lib"
306 SQLITE_CPPFLAGS="-I$with_sqlite/include"
307 sqlite=true)
308 LDFLAGS=$SAVE_LDFLAGS
309 CPPFLAGS=$SAVE_CPPFLAGS
310 ;;
311 esac
312 ],
313 [AC_MSG_RESULT([--with-sqlite not specified])
314 AC_CHECK_HEADERS(sqlite3.h, sqlite=true)])
315AM_CONDITIONAL(HAVE_SQLITE, test x$sqlite = xtrue)
316AC_SUBST(SQLITE_CPPFLAGS)
317AC_SUBST(SQLITE_LDFLAGS)
318
319# test for postgres
320postgres=false
321AC_MSG_CHECKING(for postgres)
322AC_ARG_WITH(postgres,
323 [ --with-postgres=PFX base of postgres installation],
324 [AC_MSG_RESULT("$with_postgres")
325 case $with_postgres in
326 no)
327 ;;
328 yes)
329 AC_CHECK_HEADERS(postgresql/libpq-fe.h,
330 postgres=true)
331 ;;
332 *)
333 LDFLAGS="-L$with_postgres/lib $LDFLAGS"
334 CPPFLAGS="-I$with_postgres/include $CPPFLAGS"
335 AC_CHECK_HEADERS(postgresql/libpq-fe.h,
336 EXT_LIB_PATH="-L$with_postgres/lib $EXT_LIB_PATH"
337 SQLITE_LDFLAGS="-L$with_postgres/lib"
338 SQLITE_CPPFLAGS="-I$with_postgres/include"
339 postgres=true)
340 LDFLAGS=$SAVE_LDFLAGS
341 CPPFLAGS=$SAVE_CPPFLAGS
342 ;;
343 esac
344 ],
345 [AC_MSG_RESULT([--with-postgres not specified])
346 AC_CHECK_HEADERS(postgresql/libpq-fe.h, postgres=true)])
347AM_CONDITIONAL(HAVE_POSTGRES, test x$postgres = xtrue)
348AC_SUBST(POSTGRES_CPPFLAGS)
349AC_SUBST(POSTGRES_LDFLAGS)
350
351
352# test for libz (maybe required for linking mysql)
353zlib=1
354AC_CHECK_LIB(z, compress,,zlib=0)
355AM_CONDITIONAL(HAVE_ZLIB, test x$zlib = x1)
356if test "$zlib" != 1
357then
358 AC_MSG_ERROR([GNUnet requires zlib])
359fi
360
361# mysql & windows
362AC_CHECK_TYPES([sigset_t, off_t], [], [], [#include <sys/types.h>])
363AC_CHECK_TYPES([size_t], [], [], [#include <stdio.h>])
364
365if test "$build_target" = "mingw"
366then
367 CYGWIN_MYSQL_MAGIC="#include <mysql/my_global.h>"
368fi
369
370# test for mysql
371mysql=false
372mysqlfail=false
373SAVE_LDFLAGS=$LDFLAGS
374SAVE_CPPFLAGS=$CPPFLAGS
375AC_MSG_CHECKING(for mysql)
376AC_ARG_WITH(mysql,
377 [ --with-mysql=PFX base of MySQL installation],
378 [AC_MSG_RESULT("$with_mysql")
379 if test "$with_mysql" != "no"
380 then
381 if test "$with_mysql" != "yes"
382 then
383 LDFLAGS="-L$with_mysql/lib -L$with_mysql/lib/mysql $LDFLAGS $ZLIBS"
384 CPPFLAGS="-I$with_mysql/include $CPPFLAGS"
385 fi
386 AC_CHECK_HEADERS(mysql/mysql.h,
387 AC_CHECK_LIB(mysqlclient, mysql_init,
388 MYSQL_LDFLAGS="-L$with_mysql/lib -L$with_mysql/lib/mysql"
389 MYSQL_CPPFLAGS="-I$with_mysql/include"
390
391 mysql=true), [], [$CYGWIN_MYSQL_MAGIC])
392 fi
393 ],
394 [AC_MSG_RESULT([--with-mysql not specified])
395 LDFLAGS="-L/usr/lib/mysql $LDFLAGS $ZLIBS"
396 AC_CHECK_LIB(mysqlclient, mysql_init,
397 [AC_CHECK_HEADERS(mysql/mysql.h,
398 MYSQL_LDFLAGS="-L/usr/lib/mysql"
399 mysql=true
400
401 , [], [$CYGWIN_MYSQL_MAGIC])])
402 ])
403
404AC_SUBST(MYSQL_LDFLAGS)
405AC_SUBST(MYSQL_CPPFLAGS)
406
407# additional version check for mysql
408AC_ARG_ENABLE(mysql-version-check, [ --disable-mysql-version-check do not check MySQL version],, enable_mysql_version_check=yes)
409if test "$mysql" = "true" -a "x$enable_mysql_version_check" = "xyes"
410then
411 AC_MSG_CHECKING(mysql version)
412 AC_RUN_IFELSE([AC_LANG_PROGRAM(
413 [[$CYGWIN_MYSQL_MAGIC
414 #include <mysql/mysql.h>]],
415 [[if (MYSQL_VERSION_ID < 40100)
416 return(-1);
417 else
418 return(0);
419 ]])
420 ],mysql=true,mysql=false)
421 if test "$mysql" = "false"
422 then
423 mysqlfail=true
424 AC_MSG_RESULT([fail, >= 4.1 required])
425 else
426 AC_MSG_RESULT(ok)
427 fi
428fi
429AM_CONDITIONAL(HAVE_MYSQL, test x$mysql = xtrue)
430AM_CONDITIONAL(HAVE_MYSQLE, test "0" = "1")
431# restore LIBS
432LIBS=$SAVE_LIBS
433LDFLAGS=$SAVE_LDFLAGS
434CPPFLAGS=$SAVE_CPPFLAGS
435
436if test "$sqlite" = 0 -a "$mysql" = 0
437then
438 AC_MSG_ERROR([GNUnet requires SQLite or MySQL])
439fi
440
441# GNUnet Setup
442dialog=0
443LIBS="-lm $LIBS"
444AC_CHECK_LIB([ncursesw],[wmove])
445AC_MSG_CHECKING([for dialog 1.0-20051207])
446AC_ARG_WITH(dialog,
447 [ --with-dialog=PFX base of dialog installation],
448 [AC_MSG_RESULT([$with_dialog])
449 case $with_dialog in
450 no)
451 ;;
452 yes)
453 AC_CHECK_HEADERS(dialog.h,
454 AC_CHECK_LIB([dialog], [dlg_menu],
455 dialog=1))
456 ;;
457 *)
458 LDFLAGS="-L$with_dialog/lib $LDFLAGS"
459 CPPFLAGS="-I$with_dialog/include $CPPFLAGS"
460 AC_CHECK_HEADERS(dialog.h,
461 AC_CHECK_LIB([dialog], [dlg_menu],
462 EXT_LIB_PATH="-L$with_dialog/lib $EXT_LIB_PATH"
463 dialog=1))
464 ;;
465 esac
466 ],
467 [AC_MSG_RESULT([--with-dialog not specified])
468 AC_CHECK_HEADERS(dialog.h,
469 AC_CHECK_LIB([dialog], [dlg_menu],
470 dialog=1))])
471
472AM_CONDITIONAL(HAVE_DIALOG, test x$dialog = x1)
473AC_DEFINE_UNQUOTED([HAVE_DIALOG], $dialog, [We have dialog])
474
475cdialog=0
476AC_ARG_WITH(cdialog,
477 [ --with-cdialog=PFX base of cdialog installation],
478 [AC_MSG_RESULT([$with_cdialog])
479 case $with_cdialog in
480 no)
481 ;;
482 yes)
483 AC_CHECK_HEADERS(cdialog/dialog.h,
484 AC_CHECK_LIB([cdialog], [dlg_menu],
485 cdialog=1))
486 ;;
487 *)
488 LDFLAGS="-L$with_cdialog/lib $LDFLAGS"
489 CPPFLAGS="-I$with_cdialog/include $CPPFLAGS"
490 AC_CHECK_HEADERS(cdialog/dialog.h,
491 AC_CHECK_LIB([cdialog], [dlg_menu],
492 EXT_LIB_PATH="-L$with_cdialog/lib $EXT_LIB_PATH"
493 cdialog=1))
494 ;;
495 esac
496 ],
497 [AC_MSG_RESULT([--with-cdialog not specified])
498 AC_CHECK_HEADERS(cdialog/dialog.h,
499 AC_CHECK_LIB([cdialog], [dlg_menu],
500 cdialog=1))])
501
502AM_CONDITIONAL(HAVE_CDIALOG, test x$cdialog = x1)
503AC_DEFINE_UNQUOTED([HAVE_CDIALOG], $cdialog, [We have cdialog])
504# restore LIBS
505LIBS=$SAVE_LIBS
506
507# libmicrohttpd
508lmhd=0
509AC_MSG_CHECKING([for libmicrohttpd])
510AC_ARG_WITH(microhttpd,
511 [ --with-microhttpd=PFX base of libmicrohttpd installation],
512 [AC_MSG_RESULT([$with_microhttpd])
513 case $with_microhttpd in
514 no)
515 ;;
516 yes)
517 AC_CHECK_HEADERS([microhttpd.h],
518 AC_CHECK_DECL(MHD_OPTION_PER_IP_CONNECTION_LIMIT,
519 AC_CHECK_LIB([microhttpd], [MHD_start_daemon],
520 lmhd=1),
521 [],[#include "src/include/platform.h"
522 #include <microhttpd.h>]),,
523 [#include "src/include/platform.h"])
524 ;;
525 *)
526 LDFLAGS="-L$with_microhttpd/lib $LDFLAGS"
527 CPPFLAGS="-I$with_microhttpd/include $CPPFLAGS"
528 AC_CHECK_HEADERS(microhttpd.h,
529 AC_CHECK_DECL(MHD_OPTION_PER_IP_CONNECTION_LIMIT,
530 AC_CHECK_LIB([microhttpd], [MHD_start_daemon],
531 EXT_LIB_PATH="-L$with_microhttpd/lib $EXT_LIB_PATH"
532 lmhd=1),
533 [],[#include "src/include/platform.h"
534 #include <microhttpd.h>]),,
535 [#include "src/include/platform.h"])
536 ;;
537 esac
538 ],
539 [AC_MSG_RESULT([--with-microhttpd not specified])
540 AC_CHECK_HEADERS([microhttpd.h],
541 AC_CHECK_DECL(MHD_OPTION_PER_IP_CONNECTION_LIMIT,
542 AC_CHECK_LIB([microhttpd], [MHD_start_daemon],
543 lmhd=1),
544 [],[#include "src/include/platform.h"
545 #include <microhttpd.h>]),,
546 [#include "src/include/platform.h"])])
547AM_CONDITIONAL(HAVE_MHD, test x$lmhd = x1)
548AC_DEFINE_UNQUOTED([HAVE_MHD], $lmhd, [We have libmicrohttpd])
549# restore LIBS
550LIBS=$SAVE_LIBS
551
552# libesmtp
553esmtp=0
554AC_MSG_CHECKING([for libesmtp])
555AC_ARG_WITH(esmtp,
556 [ --with-esmtp=PFX base of libesmtp installation],
557 [AC_MSG_RESULT([$with_esmtp])
558 case $with_esmtp in
559 no)
560 ;;
561 yes)
562 AC_CHECK_HEADERS(libesmtp.h,
563 AC_CHECK_LIB([esmtp], [smtp_start_session],
564 esmtp=1))
565 ;;
566 *)
567 LDFLAGS="-L$with_esmtp/lib $LDFLAGS"
568 CPPFLAGS="-I$with_esmtp/include $CPPFLAGS"
569 AC_CHECK_HEADERS(libesmtp.h,
570 AC_CHECK_LIB([esmtp], [smtp_start_session],
571 EXT_LIB_PATH="-L$with_esmtp/lib $EXT_LIB_PATH"
572 esmtp=1))
573 ;;
574 esac
575 ],
576 [AC_MSG_RESULT([--with-esmtp not specified])
577 AC_CHECK_HEADERS(libesmtp.h,
578 AC_CHECK_LIB([esmtp], [smtp_start_session],
579 esmtp=1))])
580AM_CONDITIONAL(HAVE_ESMTP, test x$esmtp = x1)
581AC_DEFINE_UNQUOTED([HAVE_ESMTP], $esmtp, [We have libesmtp])
582# restore LIBS
583LIBS=$SAVE_LIBS
584
585# check for gettext
586AM_GNU_GETTEXT_VERSION([0.16.1])
587AM_GNU_GETTEXT([external])
588
589# check for iconv
590AM_ICONV
591
592# Checks for standard typedefs, structures, and compiler characteristics.
593AC_C_CONST
594AC_TYPE_PID_T
595AC_TYPE_SIZE_T
596AC_TYPE_MODE_T
597AC_HEADER_TIME
598AC_HEADER_STAT
599AC_HEADER_STDBOOL
600AC_STRUCT_TM
601
602
603
604
605# Checks for library functions.
606AC_FUNC_CLOSEDIR_VOID
607AC_FUNC_FORK
608AC_PROG_GCC_TRADITIONAL
609AC_FUNC_MEMCMP
610AC_FUNC_SELECT_ARGTYPES
611AC_FUNC_CHOWN
612
613AC_TYPE_SIGNAL
614AC_FUNC_STAT
615AC_FUNC_STRFTIME
616AC_FUNC_VPRINTF
617AC_HEADER_SYS_WAIT
618AC_TYPE_OFF_T
619AC_TYPE_UID_T
620AC_CHECK_FUNCS([floor gethostname memmove rmdir strncasecmp strrchr strtol atoll dup2 fdatasync ftruncate gettimeofday memset mkdir mkfifo select socket strcasecmp strchr strdup strerror strstr clock_gettime getrusage rand uname setlocale getcwd mktime gmtime_r gmtime strlcpy strlcat ftruncate stat64 sbrk mmap mremap setrlimit gethostbyaddr initgroups getifaddrs freeifaddrs getnameinfo getaddrinfo inet_ntoa localtime_r nl_langinfo putenv realpath strndup gethostbyname2 gethostbyname])
621
622# restore LIBS
623LIBS=$SAVE_LIBS
624
625
626
627# check for guile
628guile=0
629AC_MSG_CHECKING(for guile 1.8)
630AC_ARG_WITH(guile,
631 [ --with-guile=PFX base of guile installation],
632 [AC_MSG_RESULT([$with_guile])
633 case $with_guile in
634 no)
635 ;;
636 yes)
637 AC_CHECK_HEADERS(libguile.h,
638 AC_CHECK_LIB([guile], [scm_c_define_gsubr],
639 guile=1, [],
640 -lgmp $LIBLTDL))
641 ;;
642 *)
643 LDFLAGS="-L$with_guile/lib $LDFLAGS"
644 CPPFLAGS="-I$with_guile/include $CPPFLAGS"
645 AC_CHECK_HEADERS(libguile.h,
646 AC_CHECK_LIB([guile], [scm_c_define_gsubr],
647 EXT_LIB_PATH="-L$with_guile/lib $EXT_LIB_PATH"
648 guile=1, [],
649 -lgmp $LIBLTDL))
650 ;;
651 esac
652 ],
653 [AC_MSG_RESULT([--with-guile not specified])
654 AC_CHECK_HEADERS(libguile.h,
655 AC_CHECK_LIB([guile], [scm_c_define_gsubr],
656 guile=1, [], -lgmp $LIBLTDL))])
657
658if test "$guile" = 1
659then
660 AC_CHECK_LIB([guile], [scm_init_guile], [],
661 AC_MSG_ERROR([Guile doesn't provide scm_init_guile(). Please report to bug-gnunet@gnu.org]), -lgmp $LIBLTDL)
662 AC_DEFINE_UNQUOTED([HAVE_GUILE], 1, [We have GUILE])
663else
664 AC_DEFINE_UNQUOTED([HAVE_GUILE], 0, [We do NOT have GUILE])
665fi
666AM_CONDITIONAL(HAVE_GUILE, test x$guile = x1)
667# restore LIBS
668LIBS=$SAVE_LIBS
669
670gn_user_home_dir="~/.gnunet"
671AC_ARG_WITH(user-home-dir,
672 AC_HELP_STRING(
673 [--with-user-home-dir=DIR],
674 [default user home directory (~/.gnunet)]),
675 [gn_user_home_dir=$withval])
676AC_SUBST(GN_USER_HOME_DIR, $gn_user_home_dir)
677gn_daemon_home_dir="/var/lib/gnunet"
678AC_ARG_WITH(daemon-home-dir,
679 AC_HELP_STRING(
680 [--with-daemon-home-dir=DIR],
681 [default daemon home directory (/var/lib/gnunet)]),
682 [gn_daemon_home_dir=$withval])
683AC_SUBST(GN_DAEMON_HOME_DIR, $gn_daemon_home_dir)
684gn_daemon_config_dir="/etc"
685AC_ARG_WITH(daemon-config-dir,
686 AC_HELP_STRING(
687 [--with-daemon-config-dir=DIR],
688 [default daemon config directory (/etc)]),
689 [gn_daemon_config_dir=$withval])
690AC_SUBST(GN_DAEMON_CONFIG_DIR, $gn_daemon_config_dir)
691gn_daemon_pidfile="/var/run/gnunetd/pid"
692AC_ARG_WITH(daemon-pidfile,
693 AC_HELP_STRING(
694 [--with-daemon-pidfile=FILE],
695 [default daemon pidfile (/var/run/gnunetd/pid)]),
696 [gn_daemon_pidfile=$withval])
697AC_SUBST(GN_DAEMON_PIDFILE, $gn_daemon_pidfile)
698
699GN_INTLINCL=""
700GN_LIBINTL="$LTLIBINTL"
701AC_ARG_ENABLE(framework, [ --enable-framework enable Mac OS X framework build helpers],enable_framework_build=$enableval)
702AM_CONDITIONAL(WANT_FRAMEWORK, test x$enable_framework_build = xyes)
703if test x$enable_framework_build = xyes
704then
705 AC_DEFINE([FRAMEWORK_BUILD], 1, [Build a Mac OS X Framework])
706 GN_INTLINCL='-I$(top_srcdir)/src/intlemu'
707 GN_LIBINTL='$(top_builddir)/src/intlemu/libintlemu.la -framework CoreFoundation'
708 AC_LIB_APPENDTOVAR([CPPFLAGS], [$GN_INTLINCL])
709fi
710
711GN_LIB_LDFLAGS="-export-dynamic -no-undefined"
712GN_PLUGIN_LDFLAGS="-export-dynamic -avoid-version -module -no-undefined"
713dnl TODO insert a proper check here
714AC_CACHE_CHECK([whether -export-symbols-regex works],
715 gn_cv_export_symbols_regex_works,
716 [
717 case "$host_os" in
718 mingw*) gn_cv_export_symbols_regex_works=no;;
719 *) gn_cv_export_symbols_regex_works=yes;;
720 esac
721 ])
722if test "x$gn_cv_export_symbols_regex_works" = "xyes"
723then
724 GN_LIB_LDFLAGS="$GN_LIB_LDFLAGS -export-symbols-regex \"GNUNET_@<:@a-zA-Z0-9_@:>@*\""
725 GN_PLUGIN_LDFLAGS="$GN_PLUGIN_LDFLAGS -export-symbols-regex \"@<:@a-zA-Z0-9_@:>@*\""
726fi
727AC_SUBST(GN_LIB_LDFLAGS)
728AC_SUBST(GN_PLUGIN_LDFLAGS)
729AC_SUBST(GN_INTLINCL)
730AC_SUBST(GN_LIBINTL)
731
732AC_SUBST(CPPFLAGS)
733AC_SUBST(LIBS)
734AC_SUBST(LDFLAGS)
735AC_SUBST(EXT_LIB_PATH)
736AC_SUBST(EXT_LIBS)
737
738AC_SUBST(LIBPREFIX)
739AC_SUBST(DLLDIR)
740AC_SUBST(EXT_LIB_PATH)
741
742
743# gcov compilation
744use_gcov=no
745AC_ARG_ENABLE([coverage], AS_HELP_STRING([--enable-coverage],
746 [Compile the library with code coverage support (default is NO)]),
747 [use_gcov=yes], [use_gcov=no])
748AM_CONDITIONAL([USE_COVERAGE], [test "x$use_gcov" = "xyes"])
749
750
751
752AC_CONFIG_FILES([ po/Makefile.in m4/Makefile
753Makefile
754contrib/Makefile
755src/Makefile
756src/arm/Makefile
757src/core/Makefile
758src/include/Makefile
759src/include/gnunet_directories.h
760src/util/Makefile
761src/fragmentation/Makefile
762src/hello/Makefile
763src/peerinfo/Makefile
764src/resolver/Makefile
765src/statistics/Makefile
766src/template/Makefile
767src/transport/Makefile
768])
769AC_OUTPUT
770
771# Finally: summary!
772
773# warn user if mysql found but not used due to version
774if test "$mysqlfail" = "true"
775then
776 AC_MSG_NOTICE([NOTICE: MySQL found, but too old. MySQL support will not be compiled.])
777fi
778
779# sqlite
780if test "x$sqlite" = "x0"
781then
782 AC_MSG_NOTICE([NOTICE: sqlite not found. sqLite support will not be compiled.])
783fi
784
785if test "x$dialog" != "x1" -a "x$cdialog" != "x1"
786then
787 AC_MSG_NOTICE([NOTICE: curses based gnunet-setup frontends will not be installed.])
788fi
789
790if test "x$lmhd" != "x1"
791then
792 AC_MSG_NOTICE([NOTICE: libmicrohttpd not found, http transport will not be installed.])
793fi
794
795AC_MSG_NOTICE([NOTICE: Database support is set to MySQL: $mysql, SQLite: $sqlite])
796
797# guile
798if test "x$guile" = "x0"
799then
800 AC_MSG_NOTICE([WARNING: Guile not found, gnunet-setup will not be installed.])
801fi
802
803if test "$enable_framework_build" = "yes"
804then
805 AC_MSG_NOTICE([NOTICE: Mac OS X framework build enabled.])
806fi
807
808AC_MSG_NOTICE([********************************************
809You can build GNUnet with
810 make install
811now. After that, install gnunet-gtk or gnunet-qt and run
812 gnunet-setup -d wizard-gtk
813(on graphical systems with GTK) or
814 gnunet-setup -d wizard-qt
815(on graphical systems with QT) or
816 gnunet-setup -d wizard-curses
817(on text-based systems with curses) in order to make important configuration
818settings. If neither works for you, you can find a template configuration
819file in the contrib/ subdirectory. Copy it to /etc/gnunetd.conf and modify it
820using your favourite text editor.
821********************************************])
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
new file mode 100644
index 000000000..50758e9ad
--- /dev/null
+++ b/contrib/Makefile.am
@@ -0,0 +1,19 @@
1dist_pkgdata_DATA = \
2 gnunet-logo-color.png \
3 defaults.conf \
4 config.scm
5
6EXTRA_DIST = \
7 coverage.sh \
8 hostlist.cgi \
9 hostlist.php \
10 report.sh
11
12# init_gnunet_redhat \
13# init_gnunet_ubuntu \
14# visualize_stats.sh \
15# gnmessage.sh \
16# junkinsert.sh \
17# junklookup.sh \
18# namespacehelper.sh
19
diff --git a/contrib/config.scm b/contrib/config.scm
new file mode 100644
index 000000000..d7fd931fa
--- /dev/null
+++ b/contrib/config.scm
@@ -0,0 +1,1568 @@
1;; This is not a stand-alone guile application.
2;; It can only be executed from within gnunet-setup.
3;;
4;; GNUnet setup defines a function "build-tree-node"
5;; (with arguments section, option, description, help,
6;; children, visible, value and range) which is
7;; used by the script to create the configuration tree.
8;;
9;; GNUnet setup defines a function "change-visible"
10;; (with arguments context, section, option, yesno) which
11;; can be used by the script to dynamically change the
12;; visibility of options.
13;;
14;; GNUnet setup defines a function "get-option"
15;; (with arguments context, section, option) which
16;; can be used to query the current value of an option.
17;;
18;; GNUnet setup defines a function "set-option"
19;; (with arguments context, section, option, value) which
20;; can be used to set the value of an option.
21;;
22;;
23;; GNUnet setup requires two functions from this script.
24;; First, a function "gnunet-config-setup" which constructs the
25;; configuration tree.
26;;
27;; Second, a function "gnunet-config-change" which is notified whenever
28;; configuration options are changed; the script can then
29;; change the visibility of other options.
30
31
32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
33
34;; for GNU gettext
35(define (_ msg) msg)
36
37;; common string
38(define (nohelp)
39 (_ "No help available.") )
40
41(define (nathelp)
42 (_ "You can use 'make check' in src/transports/upnp/ to find out if your NAT supports UPnP. You should disable this option if you are sure that you are not behind a NAT. If your NAT box does not support UPnP, having this on will not do much harm (only cost a small amount of resources).") )
43
44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
45
46;; menu definitions
47
48;; meta-menu
49
50(define (meta-exp builder)
51 (builder
52 "Meta"
53 "EXPERIMENTAL"
54 (_ "Prompt for development and/or incomplete code")
55 (_
56"If EXPERIMENTAL is set to NO, options for experimental code are not shown. If in doubt, use NO.
57
58Some options apply to experimental code that maybe in a state of development where the functionality, stability, or the level of testing is not yet high enough for general use. These features are said to be of \"alpha\" quality. If a feature is currently in alpha, uninformed use is discouraged (since the developers then do not fancy \"Why doesn't this work?\" type messages).
59
60However, active testing and qualified feedback of these features is always welcome. Users should just be aware that alpha features may not meet the normal level of reliability or it may fail to work in some special cases. Bug reports are usually welcomed by the developers, but please read the documents <file://README> and <http://gnunet.org/faq.php3> and use <https://gnunet.org/mantis/> for how to report problems." )
61 '()
62 #t
63 #f
64 #f
65 'advanced) )
66
67(define (meta-adv builder)
68 (builder
69 "Meta"
70 "ADVANCED"
71 (_ "Show options for advanced users")
72 (_
73"These are options that maybe difficult to understand for the beginner. These options typically refer to features that allow tweaking of the installation. If in a hurry, say NO." )
74 '()
75 #t
76 #t
77 #f
78 'always) )
79
80(define (meta-rare builder)
81 (builder
82 "Meta"
83 "RARE"
84 (_ "Show rarely used options")
85 (_
86"These are options that hardly anyone actually needs. If you plan on doing development on GNUnet, you may want to look into these. If in doubt or in a hurry, say NO." )
87 '()
88 #t
89 #t
90 #f
91 'advanced) )
92
93(define (meta builder)
94 (builder
95 "Meta"
96 ""
97 (_ "Meta-configuration")
98 (_ "Which level of configuration should be available")
99 (list
100 (meta-adv builder)
101 (meta-rare builder)
102 (meta-exp builder)
103 )
104 #t
105 #f
106 #f
107 'always) )
108
109;; fundamentals
110
111(define (paths-home builder)
112 (builder
113 "PATHS"
114 "GNUNETD_HOME"
115 (_ "Full pathname of GNUnet HOME directory")
116 (_
117"This gives the root-directory of the GNUnet installation. Make sure there is some space left in that directory. :-) Users inserting or indexing files will be able to store data in this directory up to the (global) quota specified below. Having a few gigabytes of free space is recommended." )
118 '()
119 #t
120 "/var/lib/gnunet"
121 '()
122 'always) )
123
124;; General menu
125
126(define (fs-path builder)
127 (builder
128 "FS"
129 "DIR"
130 (_ "Full pathname of GNUnet directory for file-sharing data")
131 (nohelp)
132 '()
133 #t
134 "$GNUNETD_HOME/data/fs"
135 '()
136 'always) )
137
138(define (kv-path builder)
139 (builder
140 "KEYVALUE_DATABASE"
141 "DIR"
142 (_ "Full pathname to the directory with the key-value database")
143 (_ "Note that the kvstore is currently not used.")
144 '()
145 #f
146 "$GNUNETD_HOME/kvstore/"
147 '()
148 'never) )
149
150(define (index-path builder)
151 (builder
152 "FS"
153 "INDEX-DIRECTORY"
154 (_ "Full pathname of GNUnet directory for indexed files symbolic links")
155 (nohelp)
156 '()
157 #t
158 "$GNUNETD_HOME/data/shared"
159 '()
160 'always) )
161
162(define (general-helloexpires builder)
163 (builder
164 "GNUNETD"
165 "HELLOEXPIRES"
166 (_ "How many minutes should peer advertisements last?")
167 (_
168"How many minutes is the current IP valid? (GNUnet will sign HELLO messages with this expiration timeline. If you are on dialup, 60 (for 1 hour) is suggested. If you have a static IP address, you may want to set this to a large value (say 14400). The default is 1440 (1 day). If your IP changes periodically, you will want to choose an expiry period smaller than the frequency with which your IP changes." )
169 '()
170 #t
171 1440
172 (cons 1 14400)
173 'advanced) )
174
175(define (general-hostlisturl builder)
176 (builder
177 "GNUNETD"
178 "HOSTLISTURL"
179 (_ "Where can GNUnet find an initial list of peers?")
180 (_
181"GNUnet can automatically update the hostlist from the web. While GNUnet internally communicates which hosts are online, it is typically a good idea to get a fresh hostlist whenever gnunetd starts from the WEB. By setting this option, you can specify from which server gnunetd should try to download the hostlist. The default should be fine for now.
182
183The general format is a list of space-separated URLs. Each URL must have the format http://HOSTNAME/FILENAME
184
185If you want to setup an alternate hostlist server, you must run a permanent node and \"cat data/hosts/* > hostlist\" every few minutes to keep the list up-to-date.
186
187If you do not specify a HOSTLISTURL, you must copy valid hostkeys to data/hosts manually.")
188 '()
189 #t
190 "http://gnunet.org/hostlist.php http://gnunet.mine.nu:8081/hostlist http://vserver1236.vserver-on.de/hostlist-074"
191 '()
192 'always) )
193
194(define (general-http-proxy builder)
195 (builder
196 "GNUNETD"
197 "HTTP-PROXY"
198 (_ "HTTP Proxy Server")
199 (_
200"If you have to use a proxy for outbound HTTP connections, specify the proxy configuration here. Default is no proxy." )
201 '()
202 #t
203 ""
204 '()
205 'advanced) )
206
207
208(define (general-hosts builder)
209 (builder
210 "GNUNETD"
211 "HOSTS"
212 (_ "Name of the directory where gnunetd should store contact information about peers")
213 (_
214"Unless you want to share the directory directly using a webserver, the default is most likely just fine." )
215 '()
216 #t
217 "$GNUNETD_HOME/data/hosts/"
218 '()
219 'rare) )
220
221
222;; logging options
223
224(define (log-level description option builder)
225 (builder
226 "LOGGING"
227 option
228 description
229 (nohelp)
230 '()
231 #t
232 "WARNING"
233 (list "SC" "NOTHING" "FATAL" "ERROR" "WARNING" "INFO" "STATUS" "DEBUG")
234 'always))
235
236(define (log-keeplog builder)
237 (builder
238 "GNUNETD"
239 "KEEPLOG"
240 (_ "How long should logs be kept?")
241 (_
242"How long should logs be kept? If you specify a value greater than zero, a log is created each day with the date appended to its filename. These logs are deleted after $KEEPLOG days. To keep logs forever, set this value to 0." )
243 '()
244 #t
245 3
246 (cons 0 36500)
247 'advanced) )
248
249(define (daemon-fdlimit builder)
250 (builder
251 "GNUNETD"
252 "FDLIMIT"
253 (_ "What maximum number of open file descriptors should be requested from the OS?")
254 (_
255"The default of 1024 should be fine for most systems. If your system can support more, increasing the number might help support additional clients on machines with plenty of bandwidth. For embedded systems, a smaller number might be acceptable. A value of 0 will leave the descriptor limit untouched. This option is mostly for OS X systems where the default is too low. Note that if gnunetd cannot obtain the desired number of file descriptors from the operating system, it will print a warning and try to run with what it is given." )
256 '()
257 #t
258 1024
259 (cons 64 65536)
260 'rare) )
261
262(define (log-logfile builder)
263 (builder
264 "GNUNETD"
265 "LOGFILE"
266 (_ "Where should gnunetd write the logs?")
267 (nohelp)
268 '()
269 #f
270 "$GNUNETD_HOME/daemon-logs"
271 '()
272 'rare) )
273
274(define (log-devel builder)
275 (builder
276 "LOGGING"
277 "DEVELOPER"
278 (_ "Enable for extra-verbose logging.")
279 (nohelp)
280 '()
281 #f
282 #f
283 #f
284 'rare) )
285
286(define (logging builder)
287 (builder
288 "LOGGING"
289 ""
290 (_ "Logging")
291 (_ "Specify which system messages should be logged how")
292 (list
293 (log-keeplog builder)
294 (log-logfile builder)
295 (log-devel builder)
296 (log-level (_ "Logging of events for users") "USER-LEVEL" builder)
297 (log-level (_ "Logging of events for the system administrator") "ADMIN-LEVEL" builder)
298 )
299 #t
300 #f
301 #f
302 'advanced) )
303
304
305(define (general-pidfile builder)
306 (builder
307 "GNUNETD"
308 "PIDFILE"
309 (_ "Where should gnunetd write the PID?")
310 (_ "The default is no longer /var/run/gnunetd.pid since we could not delete the file on shutdown at that location." )
311 '()
312 #f
313 "/var/run/gnunetd/pid"
314 '()
315 'rare) )
316
317
318(define (general-username builder)
319 (builder
320 "GNUNETD"
321 "USER"
322 (_ "As which user should gnunetd run?")
323 (_
324"Empty means \"current user\". On computer startup, it is root/SYSTEM. Under Windows, this setting affects the creation of a new system service only.")
325 '()
326 #f
327 ""
328 '()
329 'advanced) )
330
331
332
333(define (general-autostart builder)
334 (builder
335 "GNUNETD"
336 "AUTOSTART"
337 (_ "Should gnunetd be automatically started when the system boots?")
338 (_ "Set to YES if gnunetd should be automatically started on boot. If this option is set, gnunet-setup will install a script to start the daemon upon completion. This option may not work on all systems.")
339 '()
340 #t
341 #f
342 #f
343 'rare) )
344
345
346(define (general-transports builder)
347 (builder
348 "GNUNETD"
349 "TRANSPORTS"
350 (_ "Which transport mechanisms should GNUnet use?")
351 (_
352"Use a space-separated list of modules, e.g. \"udp smtp tcp\". The available transports are udp, tcp, http, smtp and nat.
353
354Loading the 'nat' and 'tcp' modules is required for peers behind NAT boxes that cannot directly be reached from the outside. Peers that are NOT behind a NAT box and that want to *allow* peers that ARE behind a NAT box to connect must ALSO load the 'nat' module. Note that the actual transfer will always be via tcp initiated by the peer behind the NAT box. The nat transport requires the use of tcp, http and/or smtp in addition to nat itself.")
355 '()
356 #t
357 "udp tcp http nat"
358 (list "MC" "udp" "tcp" "nat" "http" "smtp")
359 'always) )
360
361
362(define (general-applications builder)
363 (builder
364 "GNUNETD"
365 "APPLICATIONS"
366 (_ "Which applications should gnunetd support?")
367 (_
368"Whenever this option is changed, you MUST run gnunet-update. Currently, the available applications are:
369
370advertising: advertises your peer to other peers. Without it, your peer will not participate in informing peers about other peers. You should always load this module.
371
372getoption: allows clients to query gnunetd about the values of various configuration options. Many tools need this. You should always load this module.
373
374stats: allows tools like gnunet-stats and gnunet-gtk to query gnunetd about various statistics. This information is usually quite useful to diagnose errors, hence it is recommended that you load this module.
375
376traffic: keeps track of how many messages were recently received and transmitted. This information can then be used to establish how much cover traffic is currently available. The amount of cover traffic becomes important if you want to make anonymous requests with an anonymity level that is greater than one. It is recommended that you load this module.
377
378fs: needed for anonymous file sharing. You should always load this module.
379
380hostlist: integrated hostlist HTTP server. Useful if you want to offer a hostlist and running Apache would be overkill.
381
382chat: broadcast chat (demo-application, ALPHA quality). Required for gnunet-chat. Note that the current implementation of chat is not considered to be secure.
383
384tbench: benchmark transport performance. Required for gnunet-tbench. Note that tbench allows other users to abuse your resources.
385
386tracekit: topology visualization toolkit. Required for gnunet-tracekit. Note that loading tracekit will make it slightly easier for an adversary to compromise your anonymity." )
387 '()
388 #t
389 "advertising getoption fs stats traffic"
390 (list "MC" "advertising" "getoption" "fs" "hostlist" "stats" "traffic" "dht" "tracekit" "tbench" "vpn" "chat")
391 'always) )
392
393
394
395(define (tcpserver-disable builder)
396 (builder
397 "TCPSERVER"
398 "DISABLE"
399 (_ "Disable client-server connections")
400 (_ "This option can be used to tell gnunetd not to open the client port. When run like this, gnunetd will participate as a peer in the network but not support any user interfaces. This may be useful for headless systems that are never expected to have end-user interactions. Note that this will also prevent you from running diagnostic tools like gnunet-stats!")
401 '()
402 #t
403 #f
404 #f
405 'rare) )
406
407
408(define (gnunetd-disable-ipv6 builder)
409 (builder
410 "GNUNETD"
411 "DISABLE-IPV6"
412 (_ "YES disables IPv6 support, NO enables IPv6 support")
413 (_ "This option may be useful on peers where the kernel does not support IPv6. You might also want to set this option if you do not have an IPv6 network connection.")
414 '()
415 #t
416 #t
417 #t
418 'advanced) )
419
420
421(define (gnunetd-private-network builder)
422 (builder
423 "GNUNETD"
424 "PRIVATE-NETWORK"
425 (_ "Disable peer discovery")
426 (_ "The option 'PRIVATE-NETWORK' can be used to limit the connections of this peer to peers of which the hostkey has been copied by hand to data/hosts; if this option is given, GNUnet will not accept advertisements of peers that the local node does not already know about. Note that in order for this option to work, HOSTLISTURL should either not be set at all or be set to a trusted peer that only advertises the private network. Also, the option does NOT work at the moment if the NAT transport is loaded; for that, a couple of lines above would need some minor editing :-).")
427 '()
428 #t
429 #f
430 #f
431 'rare) )
432
433(define (network-disable-advertising builder)
434 (builder
435 "NETWORK"
436 "DISABLE-ADVERTISEMENTS"
437 (_ "Disable advertising this peer to other peers")
438 (nohelp)
439 '()
440 #t
441 #f
442 #f
443 'rare) )
444
445(define (network-disable-autoconnect builder)
446 (builder
447 "NETWORK"
448 "DISABLE-AUTOCONNECT"
449 (_ "Disable automatic establishment of connections")
450 (_ "If this option is enabled, GNUnet will not automatically establish connections to other peers, but instead wait for applications to specifically request connections to other peers (or for other peers to connect to us).")
451 '()
452 #t
453 #f
454 #f
455 'experimental) )
456
457(define (network-disable-helloexchange builder)
458 (builder
459 "NETWORK"
460 "HELLOEXCHANGE"
461 (_ "Enable advertising of other peers by this peer")
462 (_ "This option may be useful during testing, but turning it off is dangerous! If in any doubt, set it to YES (which is the default).")
463 '()
464 #t
465 #t
466 #t
467 'experimental) )
468
469(define (network-port builder)
470 (builder
471 "NETWORK"
472 "PORT"
473 (_ "Port for communication with GNUnet user interfaces")
474 (_ "Which is the client-server port that is used between gnunetd and the clients (TCP only). You may firewall this port for non-local machines (but you do not have to since GNUnet will perform access control and only allow connections from machines that are listed under TRUSTED).")
475 '()
476 #t
477 2087
478 (cons 1 65535)
479 'advanced) )
480
481(define (hostlist-port builder)
482 (builder
483 "HOSTLIST"
484 "PORT"
485 (_ "Port for the integrated hostlist HTTP server")
486 (nohelp)
487 '()
488 #t
489 8080
490 (cons 1 65535)
491 'hostlist-loaded) )
492
493(define (network-trusted builder)
494 (builder
495 "NETWORK"
496 "TRUSTED"
497 (_ "IPv4 networks allowed to use gnunetd server")
498 (_ "This option specifies which hosts are trusted enough to connect as clients (to the TCP port). This is useful if you run gnunetd on one host of your network and want to allow all other hosts to use this node as their server. By default, this is set to 'loopback only'. The format is IP/NETMASK where the IP is specified in dotted-decimal and the netmask either in CIDR notation (/16) or in dotted decimal (255.255.0.0). Several entries must be separated by a semicolon, spaces are not allowed.")
499 '()
500 #t
501 "127.0.0.0/8;"
502 '()
503 'advanced) )
504
505(define (network-trusted6 builder)
506 (builder
507 "NETWORK"
508 "TRUSTED6"
509 (_ "IPv6 networks allowed to use gnunetd server")
510 (_ "This option specifies which hosts are trusted enough to connect as clients (to the TCP port). This is useful if you run gnunetd on one host of your network and want to allow all other hosts to use this node as their server. By default, this is set to 'loopback only'. The format is IP/NETMASK where the IP is specified in dotted-decimal and the netmask either in CIDR notation (/16) or in dotted decimal (255.255.0.0). Several entries must be separated by a semicolon, spaces are not allowed.")
511 '()
512 #t
513 "::1;"
514 '()
515 'ipv6) )
516
517
518(define (limit-allow builder)
519 (builder
520 "GNUNETD"
521 "LIMIT-ALLOW"
522 (_ "Limit connections to the specfied set of peers.")
523 (_ "If this option is not set, any peer is allowed to connect. If it is set, only the specified peers are allowed. Specify the list of peer IDs (not IPs!)")
524 '()
525 #t
526 ""
527 '()
528 'rare))
529
530(define (general-groupname builder)
531 (builder
532 "GNUNETD"
533 "GROUP"
534 (_ "Run gnunetd as this group.")
535 (_ "When started as root, gnunetd will change permissions to the given group.")
536 '()
537 #t
538 "gnunetd"
539 '()
540 'advanced))
541
542(define (limit-deny builder)
543 (builder
544 "GNUNETD"
545 "LIMIT-DENY"
546 (_ "Prevent the specfied set of peers from connecting.")
547 (_ "If this option is not set, any peer is allowed to connect. If the ID of a peer is listed here, connections from that peer will be refused. Specify the list of peer IDs (not IPs!)")
548 '()
549 #t
550 ""
551 '()
552 'rare))
553
554(define (advertising builder)
555 (builder
556 "ADVERTISING"
557 ""
558 (_ "Topology Maintenance")
559 (_ "Rarely used settings for peer advertisements and connections")
560 (list
561 (general-helloexpires builder)
562 (tcpserver-disable builder)
563 (gnunetd-private-network builder)
564 (network-disable-advertising builder)
565 (network-disable-helloexchange builder)
566 (network-disable-autoconnect builder)
567 (limit-allow builder)
568 (limit-deny builder)
569 )
570 #t
571 #f
572 #f
573 'rare) )
574
575(define (general builder)
576 (builder
577 "GNUNETD"
578 ""
579 (_ "General settings")
580 (_ "Settings that change the behavior of GNUnet in general")
581 (list
582 (network-port builder)
583 (hostlist-port builder)
584 (network-trusted builder)
585 (general-hostlisturl builder)
586 (general-hosts builder)
587 (general-http-proxy builder)
588 (f2f builder)
589 (fs-path builder)
590 (index-path builder)
591 (daemon-fdlimit builder)
592 (gnunetd-disable-ipv6 builder)
593 (general-username builder)
594 (general-groupname builder)
595 (general-pidfile builder)
596 (general-autostart builder)
597 )
598 #t
599 #f
600 #f
601 'always) )
602
603(define (modules builder)
604 (builder
605 "MODULES"
606 ""
607 (_ "Modules")
608 (_ "Settings that select specific implementations for GNUnet modules")
609 (list
610 (modules-sqstore builder)
611 (modules-dstore builder)
612 (modules-topology builder)
613 )
614 #t
615 #f
616 #f
617 'advanced) )
618
619
620
621
622(define (fundamentals builder)
623 (builder
624 "PATHS"
625 ""
626 (_ "Fundamentals")
627 ""
628 (list
629 (paths-home builder)
630 (general-applications builder)
631 (general-transports builder)
632 (modules builder)
633 )
634 #t
635 #f
636 #f
637 'always) )
638
639
640;; modules menu
641
642(define (modules-sqstore builder)
643 (builder
644 "MODULES"
645 "sqstore"
646 (_ "Which database should be used?")
647 (_
648"Which database should be used? The options are \"sqstore_sqlite\", \"sqstore_postgres\" and \"sqstore_mysql\". You must run gnunet-update after changing this value!
649
650In order to use MySQL or Postgres, you must configure the respective database, which is relatively simple. Read the file doc/README.mysql or doc/README.postgres for how to setup the respective database." )
651 '()
652 #t
653 "sqstore_sqlite"
654 (list "SC" "sqstore_sqlite" "sqstore_postgres" "sqstore_mysql")
655 'fs-loaded) )
656
657(define (modules-dstore builder)
658 (builder
659 "MODULES"
660 "dstore"
661 (_ "Which topology should be used?")
662 (_ "Which database should be used for the temporary datastore of the DHT?" )
663 '()
664 #t
665 "dstore_sqlite"
666 (list "SC" "dstore_sqlite" "dstore_mysql")
667 'advanced) )
668
669
670(define (modules-topology builder)
671 (builder
672 "MODULES"
673 "topology"
674 (_ "Which topology should be used?")
675 (_
676"Which topology should be used? The only option at the moment is \"topology_default\"" )
677 '()
678 #t
679 "topology_default"
680 (list "SC" "topology_default")
681 'rare) )
682
683
684;; f2f menu
685
686(define (f2f-minimum builder)
687 (builder
688 "F2F"
689 "MINIMUM"
690 (_ "The minimum number of connected friends before this peer is allowed to connect to peers that are not listed as friends")
691 (_ "Note that this option does not guarantee that the peer will be able to connect to the specified number of friends. Also, if the peer had connected to a sufficient number of friends and then established non-friend connections, some of the friends may drop out of the network, temporarily resulting in having fewer than the specified number of friends connected while being connected to non-friends. However, it is guaranteed that the peer itself will never choose to drop a friend's connection if this would result in dropping below the specified number of friends (unless that number is higher than the overall connection target).")
692 '()
693 #t
694 0
695 (cons 0 1024)
696 'f2fr) )
697
698(define (f2f-restrict builder)
699 (builder
700 "F2F"
701 "FRIENDS-ONLY"
702 (_ "If set to YES, the peer is only allowed to connect to other peers that are explicitly specified as friends")
703 (_ "Use YES only if you have (trustworthy) friends that use GNUnet and are afraid of establishing (direct) connections to unknown peers")
704 '()
705 #t
706 #f
707 #f
708 'advanced) )
709
710(define (f2f-friends builder)
711 (builder
712 "F2F"
713 "FRIENDS"
714 (_ "List of friends for friend-to-friend topology")
715 (_ "Specifies the name of a file which contains a list of GNUnet peer IDs that are friends. If used with the friend-to-friend topology, this will ensure that GNUnet only connects to these peers (via any available transport).")
716 '()
717 #f
718 "$GNUNETD_HOME/friends"
719 '()
720 'f2f) )
721
722(define (f2f builder)
723 (builder
724 "F2F"
725 ""
726 (_ "Friend-to-Friend Topology Specification")
727 (_ "Settings for restricting connections to friends")
728 (list
729 (f2f-restrict builder)
730 (f2f-minimum builder)
731 (f2f-friends builder)
732 )
733 #t
734 #f
735 #f
736 'advanced) )
737
738;; mysql menu
739
740(define (mysql-database builder)
741 (builder
742 "MYSQL"
743 "DATABASE"
744 (_ "Name of the MySQL database GNUnet should use")
745 (nohelp)
746 '()
747 #t
748 "gnunet"
749 '()
750 'mysql) )
751
752(define (mysql-config builder)
753 (builder
754 "MYSQL"
755 "CONFIG"
756 (_ "Configuration file that specifies the MySQL username and password")
757 (nohelp)
758 '()
759 #t
760 "/etc/my.cnf"
761 '()
762 'mysql) )
763
764(define (mysql builder)
765 (builder
766 "MYSQL"
767 ""
768 (_ "Configuration of the MySQL database")
769 (nohelp)
770 (list
771 (mysql-config builder)
772 (mysql-database builder)
773 )
774 #t
775 #f
776 #f
777 'mysql) )
778
779
780
781;; applications menu
782
783(define (fs-quota builder)
784 (builder
785 "FS"
786 "QUOTA"
787 (_ "MB of diskspace GNUnet can use for anonymous file sharing")
788 (_
789"How much disk space (MB) is GNUnet allowed to use for anonymous file sharing? This does not take indexed files into account, only the space directly used by GNUnet is accounted for. GNUnet will gather content from the network if the current space-consumption is below the number given here (and if content migration is allowed below).
790
791Note that if you change the quota, you need to run gnunet-update afterwards.")
792 '()
793 #t
794 1024
795 (cons 1 1000000)
796 'always))
797
798
799(define (fs-migration-buffer builder)
800 (builder
801 "FS"
802 "MIGRATIONBUFFERSIZE"
803 (_ "Number of entries in the migration buffer")
804 (_ "Each entry uses about 32k of memory. More entries can reduce disk IO and CPU usage at the expense of having gnunetd use more memory. Very large values may again increase CPU usage. A value of 0 will prevent your peer from sending unsolicited responses.")
805 '()
806 #t
807 64
808 (cons 0 1048576)
809 'always))
810
811
812(define (fs-gap-tablesize builder)
813 (builder
814 "GAP"
815 "TABLESIZE"
816 (_ "Size of the routing table for anonymous routing.")
817 (nohelp)
818 '()
819 #t
820 65536
821 (cons 1024 1048576)
822 'rare))
823
824(define (fs-dht-tablesize builder)
825 (builder
826 "DHT"
827 "TABLESIZE"
828 (_ "Size of the routing table for DHT routing.")
829 (nohelp)
830 '()
831 #t
832 1024
833 (cons 128 1048576)
834 'rare))
835
836
837(define (fs-activemigration builder)
838 (builder
839 "FS"
840 "ACTIVEMIGRATION"
841 (_ "Allow migrating content to this peer.")
842 (_
843"If you say yes here, GNUnet will migrate content to your server, and you will not be able to control what data is stored on your machine.
844
845If you activate it, you can claim for *all* the non-indexed (-n to gnunet-insert) content that you did not know what it was even if an adversary takes control of your machine. If you do not activate it, it is obvious that you have knowledge of all the content that is hosted on your machine and thus can be considered liable for it.")
846 '()
847 #t
848 #f
849 #f
850 'advanced))
851
852
853(define (dstore-quota builder)
854 (builder
855 "DSTORE"
856 "QUOTA"
857 (_ "MB of diskspace GNUnet can use for caching DHT index data (the data will be stored in /tmp)")
858 (_ "DHT index data is inherently small and expires comparatively quickly. It is deleted whenever gnunetd is shut down.
859
860The size of the DSTORE QUOTA is specified in MB.")
861 '()
862 #t
863 1
864 (cons 1 1024)
865 'rare))
866
867
868(define (fs builder)
869 (builder
870 "FS"
871 ""
872 (_ "Options for anonymous file sharing")
873 (nohelp)
874 (list
875 (fs-quota builder)
876 (fs-activemigration builder)
877 (fs-gap-tablesize builder)
878 (fs-dht-tablesize builder)
879 (dstore-quota builder)
880 (mysql builder)
881 )
882 #t
883 #t
884 #f
885 'fs-loaded))
886
887(define (applications builder)
888 (builder
889 ""
890 ""
891 (_ "Applications")
892 (nohelp)
893 (list
894 (fs builder)
895 )
896 #t
897 #f
898 #f
899 'always) )
900
901;; transport menus
902
903(define (nat builder)
904 (builder
905 "NAT"
906 "LIMITED"
907 (_ "Is this machine unreachable behind a NAT?")
908 (_ "Set to YES if this machine is behind a NAT that limits connections from the outside to the GNUnet port and that cannot be traversed using UPnP. Note that if you have configured your NAT box to allow direct connections from other machines to the GNUnet ports or if GNUnet can open ports using UPnP, you should set the option to NO. Set this only to YES if other peers cannot contact you directly. You can use 'make check' in src/transports/upnp/ to find out if your NAT supports UPnP. You can also use gnunet-transport-check with the '-p' option in order to determine which setting results in more connections. Use YES only if you get no connections otherwise. Set to AUTO to use YES if the local IP is belongs to a private IP network and NO otherwise.")
909 '()
910 #t
911 "AUTO"
912 (list "SC" "YES" "AUTO" "NO")
913 'nat-loaded) )
914
915(define (tcp-port builder)
916 (builder
917 "TCP"
918 "PORT"
919 (_ "Which port should be used by the TCP IPv4 transport?")
920 (nohelp)
921 '()
922 #t
923 2086
924 (cons 0 65535)
925 'advanced))
926
927(define (tcp-upnp builder)
928 (builder
929 "TCP"
930 "UPNP"
931 (_ "Should we try to determine our external IP using UPnP?")
932 (nathelp)
933 '()
934 #t
935 #t
936 #f
937 'tcp-loaded))
938
939(define (tcp-blacklist builder)
940 (builder
941 "TCP"
942 "BLACKLISTV4"
943 (_ "Which IP(v4)s are not allowed to connect?")
944 (nohelp)
945 '()
946 #t
947 "127.0.0.1;"
948 '()
949 'advanced))
950
951(define (tcp-whitelist builder)
952 (builder
953 "TCP"
954 "WHITELISTV4"
955 (_ "Which IP(v4)s are allowed to connect? Leave empty to use the IP of your primary network interface.")
956 (nohelp)
957 '()
958 #t
959 ""
960 '()
961 'advanced))
962
963(define (tcp6-blacklist builder)
964 (builder
965 "TCP"
966 "BLACKLISTV6"
967 (_ "Which IPv6s are not allowed to connect?")
968 (nohelp)
969 '()
970 #t
971 ""
972 '()
973 'ipv6))
974
975(define (tcp6-whitelist builder)
976 (builder
977 "TCP"
978 "WHITELISTV6"
979 (_ "Which IPv6s are allowed to connect? Leave empty to allow any IP to connect.")
980 (nohelp)
981 '()
982 #t
983 ""
984 '()
985 'ipv6))
986
987
988(define (tcp builder)
989 (builder
990 "TCP"
991 ""
992 (_ "TCP transport")
993 (nohelp)
994 (list
995 (tcp-port builder)
996 (tcp-upnp builder)
997 (tcp-blacklist builder)
998 (tcp-whitelist builder)
999 (tcp6-blacklist builder)
1000 (tcp6-whitelist builder)
1001 )
1002 #t
1003 #f
1004 #f
1005 'tcp-loaded) )
1006
1007
1008(define (http-port builder)
1009 (builder
1010 "HTTP"
1011 "PORT"
1012 (_ "Which port should be used by the HTTP transport?")
1013 (nohelp)
1014 '()
1015 #t
1016 1080
1017 (cons 0 65535)
1018 'advanced))
1019
1020(define (http-upnp builder)
1021 (builder
1022 "HTTP"
1023 "UPNP"
1024 (_ "Should we try to determine our external IP using UPnP?")
1025 (nathelp)
1026 '()
1027 #t
1028 #t
1029 #f
1030 'http-port-nz))
1031
1032(define (http-advertised-port builder)
1033 (builder
1034 "HTTP"
1035 "ADVERTISED-PORT"
1036 (_ "Which is the external port of the HTTP transport?")
1037 (_ "Use this option if your firewall maps, say, port 80 to your real HTTP port. This can be useful in making the HTTP messages appear even more legit (without needing to run gnunetd as root due to the use of a privileged port).")
1038 '()
1039 #t
1040 80
1041 (cons 0 65535)
1042 'advanced))
1043
1044(define (http builder)
1045 (builder
1046 "HTTP"
1047 ""
1048 (_ "HTTP transport")
1049 (nohelp)
1050 (list
1051 (http-port builder)
1052 (http-advertised-port builder)
1053 (http-upnp builder)
1054 )
1055 #t
1056 #f
1057 #f
1058 'http-loaded) )
1059
1060
1061
1062
1063(define (smtp-mtu builder)
1064 (builder
1065 "SMTP"
1066 "MTU"
1067 (_ "What is the maximum transfer unit for SMTP?")
1068 (nohelp)
1069 '()
1070 #t
1071 65528
1072 (cons 1200 65528)
1073 'smtp-loaded))
1074
1075(define (smtp-ratelimit builder)
1076 (builder
1077 "SMTP"
1078 "RATELIMIT"
1079 (_ "What is the maximum number of e-mails that gnunetd would be allowed to send per hour?")
1080 (_ "Use 0 for unlimited")
1081 '()
1082 #t
1083 0
1084 (cons 0 1048576)
1085 'smtp-loaded))
1086
1087(define (smtp-email builder)
1088 (builder
1089 "SMTP"
1090 "EMAIL"
1091 (_ "Which e-mail address should be used to send e-mail to this peer?")
1092 (_ "You must make sure that e-mail received at this address is forwarded to the PIPE which is read by gnunetd. Use the FILTER option to filter e-mail with procmail and the PIPE option to set the name of the pipe.")
1093 '()
1094 #t
1095 "gnunet@localhost"
1096 '()
1097 'smtp-loaded))
1098
1099(define (smtp-filter builder)
1100 (builder
1101 "SMTP"
1102 "FILTER"
1103 (_ "Which header line should other peers include in e-mails to enable filtering?")
1104 (_ "You can specify a header line here which can then be used by procmail to filter GNUnet e-mail from your inbox and forward it to gnunetd.")
1105 '()
1106 #t
1107 "X-mailer: GNUnet"
1108 '()
1109 'smtp-loaded))
1110
1111(define (smtp-pipe builder)
1112 (builder
1113 "SMTP"
1114 "PIPE"
1115 (_ "What is the filename of the pipe where gnunetd can read its e-mail?")
1116 (_ "Have a look at contrib/dot-procmailrc for an example .procmailrc file.")
1117 '()
1118 #t
1119 "$GNUNETD_HOME/smtp-pipe"
1120 '()
1121 'smtp-loaded))
1122
1123(define (smtp-server builder)
1124 (builder
1125 "SMTP"
1126 "SERVER"
1127 (_ "What is the name and port of the server for outgoing e-mail?")
1128 (_ "The basic format is HOSTNAME:PORT.")
1129 '()
1130 #t
1131 "localhost:25"
1132 '()
1133 'smtp-loaded))
1134
1135(define (smtp builder)
1136 (builder
1137 "SMTP"
1138 ""
1139 (_ "SMTP transport")
1140 (nohelp)
1141 (list
1142 (smtp-email builder)
1143 (smtp-ratelimit builder)
1144 (smtp-filter builder)
1145 (smtp-pipe builder)
1146 (smtp-server builder)
1147 (smtp-mtu builder)
1148 )
1149 #t
1150 #f
1151 #f
1152 'smtp-loaded) )
1153
1154
1155
1156
1157
1158(define (udp-port builder)
1159 (builder
1160 "UDP"
1161 "PORT"
1162 (_ "Which port should be used by the UDP IPv4 transport?")
1163 (nohelp)
1164 '()
1165 #t
1166 2086
1167 (cons 0 65535)
1168 'advanced))
1169
1170(define (udp-upnp builder)
1171 (builder
1172 "UDP"
1173 "UPNP"
1174 (_ "Should we try to determine our external IP using UPnP?")
1175 (nathelp)
1176 '()
1177 #t
1178 #t
1179 #f
1180 'udp-port-nz))
1181
1182(define (udp-mtu builder)
1183 (builder
1184 "UDP"
1185 "MTU"
1186 (_ "What is the maximum transfer unit for UDP?")
1187 (nohelp)
1188 '()
1189 #t
1190 1472
1191 (cons 1200 65500)
1192 'rare))
1193
1194(define (udp-blacklist builder)
1195 (builder
1196 "UDP"
1197 "BLACKLISTV4"
1198 (_ "Which IPs are not allowed to connect?")
1199 (nohelp)
1200 '()
1201 #t
1202 "127.0.0.1;"
1203 '()
1204 'advanced))
1205
1206(define (udp-whitelist builder)
1207 (builder
1208 "UDP"
1209 "WHITELISTV4"
1210 (_ "Which IPs are allowed to connect? Leave empty to allow connections from any IP.")
1211 (nohelp)
1212 '()
1213 #t
1214 ""
1215 '()
1216 'advanced))
1217
1218(define (udp6-blacklist builder)
1219 (builder
1220 "UDP"
1221 "BLACKLISTV6"
1222 (_ "Which IPv6s are not allowed to connect?")
1223 (nohelp)
1224 '()
1225 #t
1226 ""
1227 '()
1228 'ipv6))
1229
1230(define (udp6-whitelist builder)
1231 (builder
1232 "UDP6"
1233 "WHITELISTV6"
1234 (_ "Which IPv6s are allowed to connect? Leave empty to allow any IP to connect.")
1235 (nohelp)
1236 '()
1237 #t
1238 ""
1239 '()
1240 'ipv6))
1241
1242(define (udp builder)
1243 (builder
1244 "UDP"
1245 ""
1246 (_ "UDP transport")
1247 (nohelp)
1248 (list
1249 (udp-port builder)
1250 (udp-upnp builder)
1251 (udp-mtu builder)
1252 (udp-blacklist builder)
1253 (udp-whitelist builder)
1254 (udp6-blacklist builder)
1255 (udp6-whitelist builder)
1256 )
1257 #t
1258 #f
1259 #f
1260 'udp-loaded) )
1261
1262
1263
1264(define (network-interface builder)
1265 (builder
1266 "NETWORK"
1267 "INTERFACE"
1268 (_ "Network interface")
1269 (nohelp)
1270 '()
1271 #t
1272 "eth0"
1273 '()
1274 'advanced) )
1275
1276(define (network-ip builder)
1277 (builder
1278 "NETWORK"
1279 "IP"
1280 (_ "External IP address (leave empty to try auto-detection)")
1281 (nohelp)
1282 '()
1283 #t
1284 ""
1285 '()
1286 'advanced) )
1287
1288(define (network-ip6 builder)
1289 (builder
1290 "NETWORK"
1291 "IP6"
1292 (_ "External IPv6 address (leave empty to try auto-detection)")
1293 (nohelp)
1294 '()
1295 #t
1296 ""
1297 '()
1298 'ipv6) )
1299
1300(define (transports builder)
1301 (builder
1302 ""
1303 ""
1304 (_ "Transports")
1305 (nohelp)
1306 (list
1307 (nat builder)
1308 (network-interface builder)
1309 (network-ip builder)
1310 (tcp builder)
1311 (udp builder)
1312 (http builder)
1313 (smtp builder)
1314 )
1315 #t
1316 #f
1317 #f
1318 'always) )
1319
1320
1321
1322(define (load-maxdown builder)
1323 (builder
1324 "LOAD"
1325 "MAXNETDOWNBPSTOTAL"
1326 (_ "What is the maximum number of bytes per second that we may receive?")
1327 (nohelp)
1328 '()
1329 #t
1330 50000
1331 (cons 1 999999999)
1332 'always))
1333
1334(define (load-maxup builder)
1335 (builder
1336 "LOAD"
1337 "MAXNETUPBPSTOTAL"
1338 (_ "What is the maximum number of bytes per second that we may send?")
1339 (nohelp)
1340 '()
1341 #t
1342 50000
1343 (cons 1 999999999)
1344 'always))
1345
1346(define (load-cpu builder)
1347 (builder
1348 "LOAD"
1349 "MAXCPULOAD"
1350 (_ "What is the maximum CPU load (percentage)?")
1351 (_ "The highest tolerable CPU load. Load here always refers to the total system load, that is it includes CPU utilization by other processes. A value of 50 means that once your 1 minute-load average goes over 50% non-idle, GNUnet will try to reduce CPU consumption until the load goes under the threshold. Reasonable values are typically between 50 and 100. Multiprocessors may use values above 100." )
1352 '()
1353 #t
1354 100
1355 (cons 0 10000)
1356 'always))
1357
1358(define (load-io builder)
1359 (builder
1360 "LOAD"
1361 "MAXIOLOAD"
1362 (_ "What is the maximum IO load (permille)?")
1363 (_
1364"The highest tolerable IO load. Load here refers to the percentage of CPU cycles wasted waiting for IO for the entire system, that is it includes disk utilization by other processes. A value of 10 means that once the average number of cycles wasted waiting for IO is more than 10% non-idle, GNUnet will try to reduce IO until the load goes under the threshold. Reasonable values are typically between 10 and 75." )
1365 '()
1366 #t
1367 50
1368 (cons 0 10000)
1369 'advanced))
1370
1371(define (load-cpu-hard builder)
1372 (builder
1373 "LOAD"
1374 "HARDCPULIMIT"
1375 (_ "What is the maximum CPU load (hard limit)?")
1376 (_ "The highest tolerable CPU load. This is the hard limit, so once it is reached, gnunetd will start to massively drop data to reduce the load. Use with caution.")
1377 '()
1378 #t
1379 0
1380 (cons 0 99999)
1381 'rare))
1382
1383(define (load-hard-up-limit builder)
1384 (builder
1385 "LOAD"
1386 "HARDUPLIMIT"
1387 (_ "What is the maximum upstream bandwidth (hard limit)?")
1388 (_ "The limit is given as a percentage of the MAXNETUPBPS limit. Use 100 to have MAXNETUPBPS be the hard limit. Use zero for no limit.")
1389 '()
1390 #t
1391 0
1392 (cons 0 999999999)
1393 'rare))
1394
1395
1396(define (load-priority builder)
1397 (builder
1398 "LOAD"
1399 "PRIORITY"
1400 (_ "What priority should gnunetd use to run?")
1401 (_ "You can specify priorities like NORMAL, ABOVE NORMAL, BELOW NORMAL, HIGH and IDLE or a numerical integer value (man nice). The default is IDLE, which should result in gnunetd only using resources that would otherwise be idle.")
1402 '()
1403 #t
1404 "IDLE"
1405 '()
1406 'always))
1407
1408
1409(define (load-padding builder)
1410 (builder
1411 "GNUNETD-EXPERIMENTAL"
1412 "PADDING"
1413 (_ "Should we disable random padding (experimental option)?")
1414 (nohelp)
1415 '()
1416 #t
1417 #f
1418 #f
1419 'experimental))
1420
1421(define (load-basiclimiting builder)
1422 (builder
1423 "LOAD"
1424 "BASICLIMITING"
1425 (_ "Use basic bandwidth limitation? (YES/NO). If in doubt, say YES.")
1426 (_
1427"Basic bandwidth limitation (YES) means simply that the bandwidth limits specified apply to GNUnet and only to GNUnet. If set to YES, you simply specify the maximum bandwidth (upstream and downstream) that GNUnet is allowed to use and GNUnet will stick to those limitations. This is useful if your overall bandwidth is so large that the limit is mostly used to ensure that enough capacity is left for other applications. Even if you want to dedicate your entire connection to GNUnet you should not set the limits to values higher than what you have since GNUnet uses those limits to determine for example the number of connections to establish (and it would be inefficient if that computation yields a number that is far too high).
1428
1429While basic bandwidth limitation is simple and always works, there are some situations where it is not perfect. Suppose you are running another application which performs a larger download. During that particular time, it would be nice if GNUnet would throttle its bandwidth consumption (automatically) and resume using more bandwidth after the download is complete. This is obviously advanced magic since GNUnet will have to monitor the behavior of other applications. Another scenario is a monthly cap on bandwidth imposed by your ISP, which you would want to ensure is obeyed. Here, you may want GNUnet to monitor the traffic from other applications to ensure that the combined long-term traffic is within the pre-set bounds. Note that you should probably not set the bounds tightly since GNUnet may observe that the bounds are about to be broken but would be unable to stop other applications from continuing to use bandwidth.
1430
1431If either of these two scenarios applies, set BASICLIMITING to NO. Then set the bandwidth limits to the COMBINED amount of traffic that is acceptable for both GNUnet and other applications. GNUnet will then immediately throttle bandwidth consumption if the short-term average is above the limit, and it will also try to ensure that the long-term average is below the limit. Note however that using NO can have the effect of GNUnet (almost) ceasing operations after other applications perform high-volume downloads that are beyond the defined limits. GNUnet would reduce consumption until the long-term limits are again within bounds.
1432
1433NO only works on platforms where GNUnet can monitor the amount of traffic that the local host puts out on the network. This is only implemented for Linux and Win32. In order for the code to work, GNUnet needs to know the specific network interface that is used for the external connection (after all, the amount of traffic on loopback or on the LAN should never be counted since it is irrelevant).")
1434 '()
1435 #t
1436 #t
1437 #f
1438 'advanced))
1439
1440(define (load-interfaces builder)
1441 (builder
1442 "LOAD"
1443 "INTERFACES"
1444 (_ "Network interface to monitor")
1445 (_ "For which interfaces should we do accounting? GNUnet will evaluate the total traffic (not only the GNUnet related traffic) and adjust its bandwidth usage accordingly. You can currently only specify a single interface. GNUnet will also use this interface to determine the IP to use. Typical values are eth0, ppp0, eth1, wlan0, etc. 'ifconfig' will tell you what you have. Never use 'lo', that just won't work. Under Windows, specify the index number reported by 'gnunet-win-tool -n'.")
1446 '()
1447 #t
1448 "eth0"
1449 (list "*" "eth0" "eth1" "eth2")
1450 'nobasiclimit))
1451
1452(define (load builder)
1453 (builder
1454 ""
1455 ""
1456 (_ "Load management")
1457 (nohelp)
1458 (list
1459 (load-priority builder)
1460 (load-maxdown builder)
1461 (load-maxup builder)
1462 (load-hard-up-limit builder)
1463 (load-cpu builder)
1464 (load-io builder)
1465 (load-cpu-hard builder)
1466 (load-basiclimiting builder)
1467 (load-interfaces builder)
1468 (load-padding builder)
1469 )
1470 #t
1471 #f
1472 #f
1473 'always) )
1474
1475
1476;; main-menu
1477
1478(define (main builder)
1479 (builder
1480 "Root"
1481 ""
1482 (_ "Root node")
1483 (nohelp)
1484 (list
1485 (meta builder)
1486 (fundamentals builder)
1487 (general builder)
1488 (advertising builder)
1489 (logging builder)
1490 (load builder)
1491 (transports builder)
1492 (applications builder)
1493 )
1494 #t
1495 #f
1496 #f
1497 'always) )
1498
1499
1500
1501;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1502
1503;; first main method: build tree using build-tree-node
1504;; The lambda expression is used to throw away the last argument,
1505;; which we use internally and which is not used by build-tree-node!
1506(define (gnunet-config-setup)
1507 (main
1508 (lambda (a b c d e f g h i) (build-tree-node a b c d e f g h) ) ) )
1509
1510
1511;; second main method: update visibility (and values)
1512;; "change" uses again the tree builder but this time
1513;; scans the "i" tags to determine how the visibility needs to change
1514
1515(define (gnunet-config-change ctx)
1516 (let
1517 (
1518 (advanced (get-option ctx "Meta" "ADVANCED"))
1519 (rare (get-option ctx "Meta" "RARE"))
1520 (nobasiclimit (not (get-option ctx "LOAD" "BASICLIMITING")))
1521 (experimental (get-option ctx "Meta" "EXPERIMENTAL"))
1522 (ipv6 (not (get-option ctx "GNUNETD" "DISABLE-IPV6")))
1523 (f2fr (not (get-option ctx "F2F" "RESTRICT") ) )
1524 (f2f (or (get-option ctx "F2F" "FRIENDS-ONLY")
1525 (not (eq? (get-option ctx "F2F" "MINIMUM") 0) ) ) )
1526 (tcp-port-nz (eq? (get-option ctx "TCP" "PORT") 0) )
1527 (udp-port-nz (eq? (get-option ctx "UDP" "PORT") 0) )
1528 (http-port-nz (eq? (get-option ctx "HTTP" "PORT") 0) )
1529 (mysql (string= (get-option ctx "MODULES" "sqstore") "sqstore_mysql") )
1530 (fs-loaded (list? (member "fs" (string-split (get-option ctx "GNUNETD" "APPLICATIONS") #\ ) ) ) )
1531 (hostlist-loaded (list? (member "hostlist" (string-split (get-option ctx "GNUNETD" "APPLICATIONS") #\ ) ) ) )
1532 (nat-loaded (list? (member "nat" (string-split (get-option ctx "GNUNETD" "TRANSPORTS") #\ ) ) ) )
1533 (tcp-loaded (list? (member "tcp" (string-split (get-option ctx "GNUNETD" "TRANSPORTS") #\ ) ) ) )
1534 (udp-loaded (list? (member "udp" (string-split (get-option ctx "GNUNETD" "TRANSPORTS") #\ ) ) ) )
1535 (http-loaded (list? (member "http" (string-split (get-option ctx "GNUNETD" "TRANSPORTS") #\ ) ) ) )
1536 (smtp-loaded (list? (member "smtp" (string-split (get-option ctx "GNUNETD" "TRANSPORTS") #\ ) ) ) )
1537 )
1538 (begin
1539 (main
1540 (lambda (a b c d e f g h i)
1541 (begin
1542 (cond
1543 ((eq? i 'advanced) (change-visible ctx a b advanced))
1544 ((eq? i 'rare) (change-visible ctx a b (and advanced rare)))
1545 ((eq? i 'experimental) (change-visible ctx a b (and advanced experimental)))
1546 ((eq? i 'f2f) (change-visible ctx a b f2f))
1547 ((eq? i 'ipv6) (change-visible ctx a b ipv6))
1548 ((eq? i 'f2fr) (change-visible ctx a b f2fr))
1549 ((eq? i 'mysql) (change-visible ctx a b mysql))
1550 ((eq? i 'fs-loaded) (change-visible ctx a b fs-loaded))
1551 ((eq? i 'hostlist-loaded) (change-visible ctx a b hostlist-loaded))
1552 ((eq? i 'nat-unlimited)(change-visible ctx a b nat-unlimited))
1553 ((eq? i 'tcp-port-nz) (change-visible ctx a b tcp-port-nz))
1554 ((eq? i 'udp-port-nz) (change-visible ctx a b udp-port-nz))
1555 ((eq? i 'nat-loaded) (change-visible ctx a b nat-loaded))
1556 ((eq? i 'udp-loaded) (change-visible ctx a b udp-loaded))
1557 ((eq? i 'tcp-loaded) (change-visible ctx a b tcp-loaded))
1558 ((eq? i 'http-loaded) (change-visible ctx a b http-loaded))
1559 ((eq? i 'smtp-loaded) (change-visible ctx a b smtp-loaded))
1560 ((eq? i 'nobasiclimit) (change-visible ctx a b nobasiclimit))
1561 (else 'nothing)
1562 )
1563 ) ) )
1564 (change-visible ctx "NETWORK" "PORT" (and advanced (not (get-option ctx "TCPSERVER" "DISABLE"))))
1565 (change-visible ctx "NETWORK" "TRUSTED" (and advanced (not (get-option ctx "TCPSERVER" "DISABLE"))))
1566 )
1567) )
1568
diff --git a/contrib/coverage.sh b/contrib/coverage.sh
new file mode 100755
index 000000000..72314ae67
--- /dev/null
+++ b/contrib/coverage.sh
@@ -0,0 +1,13 @@
1#!/bin/sh
2# make sure configure was run with coverage enabled...
3lcov --directory . --zerocounters
4make check
5for n in `find * -name "*.gc??" | grep libs`
6do
7 cd `dirname $n`
8 mv `basename $n` ..
9 cd -
10done
11lcov --directory . --capture --output-file app.info
12mkdir -p doc/coverage
13genhtml -o doc/coverage app.info
diff --git a/contrib/defaults.conf b/contrib/defaults.conf
new file mode 100644
index 000000000..d6100b77d
--- /dev/null
+++ b/contrib/defaults.conf
@@ -0,0 +1,139 @@
1[PATHS]
2SERVICEHOME = /var/lib/gnunet/
3DEFAULTCONFIG = /etc/gnunetd.conf
4
5[gnunetd]
6HOSTKEY = $SERVICEHOME/.hostkey
7
8[TESTING]
9WEAKRANDOM = NO
10
11
12[tcp]
13PORT = 2086
14TIMEOUT = 300000
15ALLOW_SHUTDOWN = NO
16# MAXBUF =
17# DISABLEV6 =
18# BINDTO =
19# ACCEPT_FROM =
20# ACCEPT_FROM6 =
21# REJECT_FROM =
22# REJECT_FROM6 =
23
24
25[arm]
26PORT = 2087
27HOSTNAME = localhost
28HOME = $SERVICEHOME
29CONFIG = $DEFAULTCONFIG
30BINARY = gnunet-service-arm
31ACCEPT_FROM = 127.0.0.1;
32ACCEPT_FROM6 = ::1;
33ALLOW_SHUTDOWN = YES
34# GLOBAL_PREFIX =
35# USERNAME =
36# MAXBUF =
37# TIMEOUT =
38# DISABLEV6 =
39# BINDTO =
40# REJECT_FROM =
41# REJECT_FROM6 =
42# PREFIX =
43
44[statistics]
45PORT = 2088
46HOSTNAME = localhost
47HOME = $SERVICEHOME
48CONFIG = $DEFAULTCONFIG
49BINARY = gnunet-service-statistics
50ACCEPT_FROM = 127.0.0.1;
51ACCEPT_FROM6 = ::1;
52ALLOW_SHUTDOWN = YES
53# USERNAME =
54# MAXBUF =
55# TIMEOUT =
56# DISABLEV6 =
57# BINDTO =
58# REJECT_FROM =
59# REJECT_FROM6 =
60# PREFIX =
61
62[resolver]
63PORT = 2089
64HOSTNAME = localhost
65HOME = $SERVICEHOME
66CONFIG = $DEFAULTCONFIG
67BINARY = gnunet-service-resolver
68ACCEPT_FROM = 127.0.0.1;
69ACCEPT_FROM6 = ::1;
70ALLOW_SHUTDOWN = YES
71# USERNAME =
72# MAXBUF =
73# TIMEOUT =
74# DISABLEV6 =
75# BINDTO =
76# REJECT_FROM =
77# REJECT_FROM6 =
78# PREFIX =
79
80[peerinfo]
81PORT = 2090
82HOSTNAME = localhost
83HOME = $SERVICEHOME
84CONFIG = $DEFAULTCONFIG
85BINARY = gnunet-service-peerinfo
86ACCEPT_FROM = 127.0.0.1;
87ACCEPT_FROM6 = ::1;
88ALLOW_SHUTDOWN = YES
89# USERNAME =
90# MAXBUF =
91# TIMEOUT =
92# DISABLEV6 =
93# BINDTO =
94# REJECT_FROM =
95# REJECT_FROM6 =
96# PREFIX =
97HOSTS = $SERVICEHOME/data/hosts/
98TRUST = $SERVICEHOME/data/credit/
99
100
101[transport]
102PORT = 2091
103HOSTNAME = localhost
104HOME = $SERVICEHOME
105CONFIG = $DEFAULTCONFIG
106BINARY = gnunet-service-transport
107DEFAULT_QUOTA_IN = 50000
108DEFAULT_QUOTA_OUT = 50000
109NEIGHBOUR_LIMIT = 50
110ACCEPT_FROM = 127.0.0.1;
111ACCEPT_FROM6 = ::1;
112ALLOW_SHUTDOWN = YES
113# USERNAME =
114# MAXBUF =
115# TIMEOUT =
116# DISABLEV6 =
117# BINDTO =
118# REJECT_FROM =
119# REJECT_FROM6 =
120# PREFIX =
121
122
123[core]
124PORT = 2092
125HOSTNAME = localhost
126HOME = $SERVICEHOME
127CONFIG = $DEFAULTCONFIG
128BINARY = gnunet-service-core
129ACCEPT_FROM = 127.0.0.1;
130ACCEPT_FROM6 = ::1;
131ALLOW_SHUTDOWN = YES
132# USERNAME =
133# MAXBUF =
134# TIMEOUT =
135# DISABLEV6 =
136# BINDTO =
137# REJECT_FROM =
138# REJECT_FROM6 =
139# PREFIX =
diff --git a/contrib/gnunet-logo-big.png b/contrib/gnunet-logo-big.png
new file mode 100644
index 000000000..54c418f8f
--- /dev/null
+++ b/contrib/gnunet-logo-big.png
Binary files differ
diff --git a/contrib/gnunet-logo-color.png b/contrib/gnunet-logo-color.png
new file mode 100644
index 000000000..326822ebd
--- /dev/null
+++ b/contrib/gnunet-logo-color.png
Binary files differ
diff --git a/contrib/hostlist.cgi b/contrib/hostlist.cgi
new file mode 100644
index 000000000..f04246e47
--- /dev/null
+++ b/contrib/hostlist.cgi
@@ -0,0 +1,5 @@
1#!/bin/sh
2# This is a CGI script to generate the host list on-demand.
3# by Michael Wensley, with minor improvements by Christian Grothoff
4echo -ne "Content-Type: application/octet-stream\r\n\r\n"
5cat /var/lib/gnunet/data/hosts/*.{2,3,4,5,6,8,12,17,23,25}
diff --git a/contrib/hostlist.php b/contrib/hostlist.php
new file mode 100644
index 000000000..158561542
--- /dev/null
+++ b/contrib/hostlist.php
@@ -0,0 +1,35 @@
1<?php
2// Requires PHP >= 4.3.0
3// Author: "Krasko Oleksandr" <0m3r.mail@gmail.com>
4// Minor improvements by Christian Grothoff <christian@grothoff.org>
5header("Content-Type: application/octet-stream\r\n\r\n");
6$extmas = array();
7$pv=$_GET['p'];
8if (isset($pv))
9 {
10 for ($ii=0;$ii<64;$ii++)
11 if (0 != ($pv & (1 << $ii)))
12 $extmas[] = $ii;
13 }
14else
15 {
16 $extmas = array('2','3','4','5','6','8','12','17','23','25');
17 }
18$path = '/var/lib/gnunet/data/hosts/'; // adjust as necessary
19$dir = opendir($path);
20if (! $dir)
21 die("Cannot open directory $path.\n");
22$mas = array();
23while ($fname = readdir($dir)) {
24 $fn = $path . '/' . $fname;
25 if (is_file($fn)) {
26 $dpo = strpos($fname, '.') + 1;
27 $len = strlen($fname);
28 if (in_array(substr($fname, $dpo - $len), $extmas))
29 $mas[] = $fn;
30 }
31}
32shuffle($mas); // randomize order
33foreach ($mas as $val)
34 echo file_get_contents($val);
35?>
diff --git a/contrib/report.sh b/contrib/report.sh
new file mode 100755
index 000000000..76abe5a7c
--- /dev/null
+++ b/contrib/report.sh
@@ -0,0 +1,200 @@
1#!/bin/sh
2
3TEST=`type type|grep not`
4if test -n "$TEST"; then
5 WHICH=which
6else
7 WHICH=type
8fi
9
10echo "On some systems, you may need to change /bin/sh to point to bash"
11echo
12echo "Please submit the following information with your bug report: "
13echo "--------------------------------------------------------------"
14OS=`uname -s 2>/dev/null`
15echo "OS : $OS"
16REL=`uname -r 2>/dev/null`
17echo "OS RELEASE : $REL"
18HW=`uname -m 2>/dev/null`
19echo "HARDWARE : $HW"
20
21TEST=`$WHICH gcc 2>/dev/null`
22if test -n "$TEST"; then
23 VERS=`gcc --version 2>/dev/null | head -n 1`
24 echo "gcc : $VERS"
25else
26 echo "gcc : Not Found";
27fi
28
29TEST=`$WHICH gmake 2>/dev/null`
30if test -n "$TEST" ; then
31 gmake --version 2>/dev/null |\
32 awk -F, '{print $1}' |\
33 awk '/GNU Make/{print "GNU gmake :",$NF}'
34else
35 TEST=`make --version 2>/dev/null`
36 if test -n "$TEST"; then
37 make --version 2>/dev/null |\
38 awk -F, '{print $1}' |\
39 awk '/GNU Make/{print "make :",$NF}'
40 else
41 echo "make : Not Found"
42 fi
43fi
44
45TEST=`$WHICH autoconf 2>/dev/null`
46if test -n "$TEST"; then
47 autoconf --version |\
48 head -n 1 |\
49 awk '{\
50 if (length($4) == 0) {\
51 print "autoconf : "$3\
52 } else {\
53 print "autoconf : "$4\
54 }}'
55else
56 echo "autoconf : Not Found"
57fi
58
59TEST=`$WHICH automake 2>/dev/null`
60if test -n "$TEST"; then
61 automake --version 2>/dev/null |\
62 head -n 1 |\
63 awk '{print "automake : "$4}'
64else
65 echo "automake : Not Found"
66fi
67
68TEST=`$WHICH libtool 2>/dev/null`
69if test -n "$TEST"; then
70 libtool --version 2>/dev/null |\
71 head -n 1 |\
72 awk '{print "libtool : "$4}'
73else
74 echo "libtool : Not Found"
75fi
76
77TEST=`$WHICH extract 2>/dev/null`
78if test -n "$TEST"; then
79 extract -v 2>/dev/null |\
80 head -n 1 |\
81 awk '{print "libextractor : "$2}'
82else
83 echo "libextractor : Not Found"
84fi
85
86TEST=`$WHICH gnunetd 2>/dev/null`
87if test -n "$TEST"; then
88 gnunetd -v | sed -e "s/v//" 2>/dev/null |\
89 awk '{print "GNUnet : "$2}'
90else
91 echo "GNUnet : Not Found"
92fi
93
94TEST=`$WHICH libgcrypt-config 2> /dev/null`
95if test -n "$TEST"; then
96 libgcrypt-config --version 2> /dev/null | \
97 awk '{print "libgcrypt : "$1}'
98else
99 echo "libgcrypt : Not Found"
100fi
101
102TEST=`$WHICH mysql_config 2> /dev/null`
103if test -n "$TEST"; then
104 mysql_config --version 2> /dev/null | \
105 awk '{print "mysql : "$1}'
106else
107 echo "mysql : Not Found"
108fi
109
110TEST=`$WHICH pkg-config 2> /dev/null`
111if test -n "$TEST"; then
112 pkg-config --version 2> /dev/null | \
113 awk '{print "pkg-config : "$1}'
114else
115 echo "pkg-config : Not Found"
116fi
117
118TEST=`$WHICH pkg-config 2> /dev/null`
119if test -n "$TEST"; then
120 pkg-config --modversion glib-2.0 2> /dev/null | \
121 awk '{print "glib2 : "$1}'
122else
123 echo "glib2 : Not Found"
124fi
125
126TEST=`$WHICH pkg-config 2> /dev/null`
127if test -n "$TEST"; then
128 pkg-config --modversion gtk+-2.0 2> /dev/null | \
129 awk '{print "gtk2+ : "$1}'
130else
131 echo "gtk2+ : Not Found"
132fi
133
134TEST=`$WHICH dpkg 2> /dev/null`
135if test -n "$TEST"; then
136 LINES=`dpkg -s libgmp3-dev | grep Version | wc -l`
137 if test "$LINES" = "1"
138 then
139 VERSION=`dpkg -s libgmp3-dev | grep Version | awk '{print $2}'`
140 echo "GMP : libgmp3-dev-$VERSION.deb"
141 else
142 echo "GMP : dpkg: libgmp3-dev not installed"
143 fi
144else
145 TEST=`$WHICH rpm 2> /dev/null`
146 if test -n "$TEST"; then
147 rpm -q gmp | sed -e "s/gmp-//" 2> /dev/null | \
148 awk '{print "GMP : "$1.rpm}'
149 else
150 echo "GMP : Test not available"
151 fi
152fi
153
154TEST=`$WHICH gettext 2> /dev/null`
155if test -n "$TEST"; then
156 gettext --version | head -n1 2> /dev/null | \
157 awk '{print "GNU gettext : "$4}'
158else
159 echo "GNU gettext : Not found"
160fi
161
162
163TEST=`$WHICH guile 2> /dev/null`
164if test -n "$TEST"; then
165 guile --version | head -n1 2> /dev/null | \
166 awk '{print "Guile : "$2}'
167else
168 echo "Guile : Not found"
169fi
170
171
172TEST=`$WHICH curl-config 2> /dev/null`
173if test -n "$TEST"; then
174 curl-config --version | head -n1 2> /dev/null | \
175 awk '{print "libcurl : "$2}'
176else
177 echo "libcurl : Not found"
178fi
179
180
181TEST=`grep "Id:" /usr/include/adns.h 2> /dev/null`
182if test -n "$TEST"; then
183 echo "$TEST" | awk '{print "GNU adns : "$4}'
184else
185 echo "GNU adns : Not found"
186fi
187
188TEST=`which qmake 2> /dev/null`
189if test -x "$TEST"; then
190 qmake --version | tail -n 1 | awk '{print "Qt : "$4}'
191else
192 echo "Qt : Not found"
193fi
194
195
196
197
198
199
200echo "--------------------------------------------------------------"
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
new file mode 100644
index 000000000..734fc9c85
--- /dev/null
+++ b/doc/man/Makefile.am
@@ -0,0 +1,7 @@
1man_MANS = \
2 gnunet-arm.1 \
3 gnunet-peerinfo.1 \
4 gnunet-statistics.1 \
5 gnunet-transport.c
6
7EXTRA_DIST = ${man_MANS}
diff --git a/doc/man/gnunet-arm.1 b/doc/man/gnunet-arm.1
new file mode 100644
index 000000000..e440479c3
--- /dev/null
+++ b/doc/man/gnunet-arm.1
@@ -0,0 +1,57 @@
1.TH GNUNET\-ARM 1 "Mar 7, 2009" "GNUnet"
2
3.SH NAME
4gnunet\-arm \- control GNUnet services
5
6.SH SYNOPSIS
7.B gnunet-arm
8.RI [ options ]
9.br
10
11.SH DESCRIPTION
12\fBgnunet\-arm\fP can be used to start or stop GNUnet services, including the ARM service itself.
13
14.SH OPTIONS
15
16.TP
17.IP "\-c FILENAME, \-\-config=FILENAME"
18Use the configuration file FILENAME.
19
20.TP
21.IP "\-e, \-\-end"
22Shutdown all GNUnet services (including ARM).
23
24.TP
25.IP "\-h, \-\-help"
26Print short help on options.
27
28.TP
29.IP "\-L LOGLEVEL, \-\-loglevel=LOGLEVEL"
30Use LOGLEVEL for logging. Valid values are DEBUG, INFO, WARNING and ERROR.
31
32.TP
33.IP "\-i SERVICE, \-\-init=SERVICE"
34Starts the specified SERVICE if it is not already running.
35
36.TP
37.IP "\-k SERVICE, \-\-kill=SERVICE"
38Stop the specified SERVICE if it is running.
39
40.TP
41.IP "\-s, \-\-start"
42Start all GNUnet default services on this system (including ARM).
43
44.TP
45.IP "\-t SERVICE, \-\-test=SERVICE"
46Report if the specified SERVICE is running.
47
48.TP
49.IP "\-v, \-\-version"
50Print GNUnet version number.
51
52
53.SH BUGS
54Report bugs by using Mantis <https://gnunet.org/mantis/> or by sending electronic mail to <gnunet\-developers@gnu.org>
55
56.SH SEE ALSO
57gnunet\-service\-arm(1)
diff --git a/doc/man/gnunet-peerinfo.1 b/doc/man/gnunet-peerinfo.1
new file mode 100644
index 000000000..2980d3544
--- /dev/null
+++ b/doc/man/gnunet-peerinfo.1
@@ -0,0 +1,42 @@
1.TH GNUNET-PEERINFO 1 "Mar 15, 2009" "GNUnet"
2
3.SH NAME
4gnunet\-peerinfo \- Display information about other peers.
5
6.SH SYNOPSIS
7.B gnunet\-peerinfo
8.RI [ options ]
9.br
10
11.SH DESCRIPTION
12.PP
13\fBgnunet\-peerinfo\fP display the known addresses and trust of known peers.
14
15.SH OPTIONS
16.B
17.IP "\-c FILENAME, \-\-config=FILENAME"
18Load config file (default: /etc/gnunet.conf)
19.B
20.IP "\-h, \-\-help"
21Print help page
22.B
23.IP "\-n, \-\-numeric"
24Disable resolution of IPs to hostnames
25.B
26.IP "\-q, \-\-quiet"
27Do not print anything but the peer identities
28.B
29.IP "\-s, \-\-self"
30Print only our own identity (together with "\-q", this is the exact line that other peers would have to put in to their friends file in order to consider this peer one of their friends in F2F mode).
31.B
32.IP "\-v, \-\-version"
33Print the version number
34.B
35.IP "\-L LOGLEVEL, \-\-loglelvel=LOGLEVEL"
36Set the loglevel
37
38.SH BUGS
39Report bugs by using mantis <https://gnunet.org/mantis/> or by sending electronic mail to <gnunet\-developers@gnu.org>
40
41.SH SEE ALSO
42gnunet.conf(5)
diff --git a/doc/man/gnunet-statistics.1 b/doc/man/gnunet-statistics.1
new file mode 100644
index 000000000..8a23e01e0
--- /dev/null
+++ b/doc/man/gnunet-statistics.1
@@ -0,0 +1,50 @@
1.TH GNUNET\-STATISTICS 1 "Mar 6, 2009" "GNUnet"
2
3.SH NAME
4gnunet\-statistics \- Display statistics about your GNUnet system
5
6.SH SYNOPSIS
7.B gnunet-statistics
8.RI [ options ] [ VALUE ]
9.br
10
11.SH DESCRIPTION
12\fBgnunet\-statistics\fP is used to display detailed information about various aspect of GNUnet's operation. This tool only works if the "statistics" service is available.
13gnunet\-statistics can be used to set a value by giving the options \-n, \-s and also a VALUE.
14
15.SH OPTIONS
16
17.TP
18.IP "\-c FILENAME, \-\-config=FILENAME"
19Use the configuration file FILENAME.
20
21.TP
22.IP "\-h, \-\-help"
23Print short help on options.
24
25.TP
26.IP "\-L LOGLEVEL, \-\-loglevel=LOGLEVEL"
27Use LOGLEVEL for logging. Valid values are DEBUG, INFO, WARNING and ERROR.
28
29.TP
30.IP "\-n NAME, \-\-name=NAME"
31Each statistic has a name that is unique with in its subsystem. With this option, the output can be restricted to statistics that have a particular name.
32
33.TP
34.IP "\-p, \-\-persistent"
35When setting a value, make the value persistent. If the value used to be persistent and this flag is not given, it will be marked as non\-persistent.
36
37.TP
38.IP "\-s SUBSYSTEM, \-\-subsystem=SUBSYSTEM"
39Statistics are kept for various subsystems. With this option, the output can be restricted to a particular subsystem only.
40
41.TP
42.IP "\-v, \-\-version"
43Print GNUnet version number.
44
45
46.SH BUGS
47Report bugs by using Mantis <https://gnunet.org/mantis/> or by sending electronic mail to <gnunet\-developers@gnu.org>
48
49.SH SEE ALSO
50gnunet\-service\-statistics(1)
diff --git a/doc/man/gnunet-transport.1 b/doc/man/gnunet-transport.1
new file mode 100644
index 000000000..643759395
--- /dev/null
+++ b/doc/man/gnunet-transport.1
@@ -0,0 +1,96 @@
1.TH GNUNET-TRANSPORT "1" "23 Dec 2006" "GNUnet"
2.SH NAME
3gnunet\-transport \- a tool to test a GNUnet transport service
4.SH SYNOPSIS
5.B gnunet\-transport\
6[\fIOPTIONS\fR]
7.SH DESCRIPTION
8.PP
9gnunet\-transport can be used to test or profile
10a GNUnet transport service. The tool can be used to test
11both the correctness of the software as well as the correctness
12of the configuration. gnunet\-transport features two modes,
13called loopback mode and ping mode. In loopback mode the test is limited to testing if the
14transport can be used to communicate with itself (loopback).
15This mode does not include communication with other peers which
16may be blocked by firewalls and other general Internet connectivity
17problems. The loopback mode is particularly useful to test
18the SMTP transport service since this service is fairly hard to
19configure correctly and most problems can be reveiled by just
20testing the loopback. In ping mode the tool will attempt to download
21peer advertisements from the URL specified in the configuration file
22and then try to contact each of the peers. Note that it is perfectly
23normal that some peers do not respond, but if no peer responds something
24is likely to be wrong. The configuration is always taken
25from the configuration file. Do not run gnunetd while running
26gnunet\-transport since the transport services cannot
27be used by two processes at the same time.
28.PP
29gnunet\-transport will always produce an error\-message for
30the NAT transport in loopback mode. If NAT is configured in accept\-mode (as in,
31accept connections from peers using network address translation),
32the check will fail with the message "could not create HELO",
33which is correct since the peer itself is clearly not going to
34advertise itself as a NAT. If the peer is configured in NAT\-mode,
35that is, the peer is behind a NAT box, the message will be
36'could not connect'. For NAT, both messages are NOT errors
37but exactly what is supposed to happen.
38.PP
39Similarly, a NAT\-ed peer should typically configure the TCP transport
40to use port 0 (not listen on any port). In this case,
41gnunet\-transport will print 'could not create HELO' for the
42TCP transport. This is also ok. In fact, a correctly configured
43peer using NAT should give just two errors (could not connect for
44tcp and could not create HELO for NAT) when tested using
45gnunet\-transport\. The reason is, that gnunet\-transport\
46only tests loopback connectivity, and for a NAT\-ed peer, that just
47does not apply.
48.PP
49Note that in ping mode the HTTP download times out after 5 minutes,
50so if the list of peers is very large and not all peers can be
51queried within the 5 minutes the tool may abort before trying all
52peers.
53.TP
54\fB\-c \fIFILENAME\fR, \fB\-\-config=\fIFILENAME\fR
55use config file (default: /etc/gnunetd.conf)
56.TP
57\fB\-h\fR, \fB\-\-help\fR
58print help page
59.TP
60\fB\-L \fILOGLEVEL\fR, \fB\-\-loglevel=\fILOGLEVEL\fR
61change the loglevel. Possible values for \fILOGLEVEL\fR are NOTHING, FATAL, ERROR, FAILURE, WARNING, MESSAGE, INFO, DEBUG, CRON and EVERYTHING.
62.TP
63\fB\-p\fR, \fB\-\-ping\fR
64use ping mode (loopback mode is default)
65.TP
66\fB\-r\fI COUNT \fB\-\-repeat=\fICOUNT\fR
67send COUNT messages in a sequence over the same connection
68.TP
69\fB\-s\fI SIZE \fB\-\-size=\fISIZE\fR
70test using the specified message size, default is 11
71.TP
72\fB\-t\fI TRANSPORT\fR, \fB\-\-transport=\fITRANSPORT\fR
73run using the specified transport, if not given the transports
74configured in the configuration file are used.
75.TP
76\fB\-u \fIUSER\fR, \fB\-\-user=USER\fR
77run as user USER (and if available as group USER). Note that to use this option, you will probably have to start gnunet-transport as
78root. It is typically better to directly start gnunet-transport as that user instead.
79.TP
80\fB\-v\fR, \fB\-\-version\fR
81print the version number
82.TP
83\fB\-V\fR, \fB\-\-verbose\fR
84be verbose
85.SH NOTES
86gnunet\-transport can run for a long time, depending on
87how high you have set the \fICOUNT\fR level. Run first with small numbers
88for \fICOUNT\fR to get an initial estimate on the runtime.
89.SH FILES
90.TP
91/etc/gnunetd.conf
92default gnunetd configuration file
93.SH "REPORTING BUGS"
94Report bugs by using mantis <https://gnunet.org/mantis/> or by sending electronic mail to <gnunet-developers@gnu.org>
95.SH "SEE ALSO"
96\fBgnunetd.conf\fP(5), \fBgnunetd\fP(1)
diff --git a/m4/Makefile.am b/m4/Makefile.am
new file mode 100644
index 000000000..128870999
--- /dev/null
+++ b/m4/Makefile.am
@@ -0,0 +1 @@
EXTRA_DIST = .
diff --git a/m4/align.m4 b/m4/align.m4
new file mode 100644
index 000000000..256300e37
--- /dev/null
+++ b/m4/align.m4
@@ -0,0 +1,28 @@
1# align.m4
2dnl Copyright (C) 2008 Christian Grothoff
3dnl This file is free software, distributed under the terms of the GNU
4dnl General Public License. As a special exception to the GNU General
5dnl Public License, this file may be distributed as part of a program
6dnl that contains a configuration script generated by Autoconf, under
7dnl the same distribution terms as the rest of that program.
8
9# Define HAVE_UNALIGNED_64_ACCESS if reading a 64-bit value at a 32-bit aligned offset works
10# Note that the program intentionally causes a SIGBUS (so you may
11# see some message along those lines on the console).
12AC_DEFUN([AC_UNALIGNED_64_ACCESS],
13[AC_CACHE_CHECK([whether unaligned 64-bit access works],
14 ac_cv_unaligned_64_access,
15 [
16 AC_RUN_IFELSE(AC_LANG_PROGRAM([[struct S { int a,b,c;};]],
17 [[struct S s = {0,0,0}; long long * p = &s.b;
18 long long x = *p; return (int) x*x;]]),
19 ac_cv_unaligned_64_access=yes,
20 ac_cv_unaligned_64_access=no,
21 ac_cv_unaligned_64_access=no)
22 ])
23 case "$ac_cv_unaligned_64_access" in
24 *yes) value=1;;
25 *) value=0;;
26 esac
27 AC_DEFINE_UNQUOTED([HAVE_UNALIGNED_64_ACCESS], $value, [We can access-64 bit values that are only 32-bit aligned])
28])
diff --git a/po/ChangeLog b/po/ChangeLog
new file mode 100644
index 000000000..7ff113c61
--- /dev/null
+++ b/po/ChangeLog
@@ -0,0 +1,16 @@
12007-02-08 gettextize <bug-gnu-gettext@gnu.org>
2
3 * Makefile.in.in: Upgrade to gettext-0.16.1.
4 * Rules-quot: Upgrade to gettext-0.16.1.
5
62004-08-21 gettextize <bug-gnu-gettext@gnu.org>
7
8 * Makefile.in.in: New file, from gettext-0.14.
9 * boldquot.sed: New file, from gettext-0.14.
10 * en@boldquot.header: New file, from gettext-0.14.
11 * en@quot.header: New file, from gettext-0.14.
12 * insert-header.sin: New file, from gettext-0.14.
13 * quot.sed: New file, from gettext-0.14.
14 * remove-potcdate.sin: New file, from gettext-0.14.
15 * Rules-quot: New file, from gettext-0.14.
16
diff --git a/po/GNUnet.pot b/po/GNUnet.pot
new file mode 100644
index 000000000..47bf3dfae
--- /dev/null
+++ b/po/GNUnet.pot
@@ -0,0 +1,5168 @@
1# SOME DESCRIPTIVE TITLE.
2# Copyright (C) YEAR Christian Grothoff
3# This file is distributed under the same license as the PACKAGE package.
4# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5#
6#, fuzzy
7msgid ""
8msgstr ""
9"Project-Id-Version: PACKAGE VERSION\n"
10"Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n"
11"POT-Creation-Date: 2009-01-08 10:55-0700\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"
15"MIME-Version: 1.0\n"
16"Content-Type: text/plain; charset=CHARSET\n"
17"Content-Transfer-Encoding: 8bit\n"
18
19#: src/setup/ncurses/wizard_curs.c:72 src/setup/lib/wizard_util.c:155
20#: src/setup/lib/wizard_util.c:210
21msgid "Error"
22msgstr ""
23
24#: src/setup/ncurses/wizard_curs.c:80
25msgid "Help"
26msgstr ""
27
28#: src/setup/ncurses/wizard_curs.c:87
29msgid "Error!"
30msgstr ""
31
32#: src/setup/ncurses/wizard_curs.c:101 src/applications/vpn/cs.c:94
33msgid "No"
34msgstr ""
35
36#: src/setup/ncurses/wizard_curs.c:102 src/applications/vpn/cs.c:94
37msgid "Yes"
38msgstr ""
39
40#: src/setup/ncurses/wizard_curs.c:118 src/setup/ncurses/wizard_curs.c:183
41#: src/setup/ncurses/wizard_curs.c:299 src/setup/ncurses/mconf.c:189
42#: src/setup/ncurses/mconf.c:285 src/setup/ncurses/mconf.c:365
43#: src/setup/ncurses/mconf.c:456
44msgid "Internal error! (Choice invalid?)"
45msgstr ""
46
47#: src/setup/ncurses/wizard_curs.c:150
48msgid "Abort"
49msgstr ""
50
51#: src/setup/ncurses/wizard_curs.c:151
52msgid "Ok"
53msgstr ""
54
55#: src/setup/ncurses/wizard_curs.c:218 src/setup/ncurses/wizard_curs.c:284
56#: src/setup/ncurses/wizard_curs.c:425
57msgid "GNUnet configuration"
58msgstr ""
59
60#: src/setup/ncurses/wizard_curs.c:220
61msgid ""
62"Welcome to GNUnet!\n"
63"\n"
64"This assistant will ask you a few basic questions in order to configure "
65"GNUnet.\n"
66"\n"
67"Please visit our homepage at\n"
68"\thttp://gnunet.org/\n"
69"and join our community at\n"
70"\thttp://gnunet.org/drupal/\n"
71"\n"
72"Have a lot of fun,\n"
73"\n"
74"the GNUnet team"
75msgstr ""
76
77#: src/setup/ncurses/wizard_curs.c:286
78msgid ""
79"Choose the network interface that connects your computer to the internet "
80"from the list below."
81msgstr ""
82
83#: src/setup/ncurses/wizard_curs.c:304 src/setup/ncurses/wizard_curs.c:318
84msgid ""
85"The \"Network interface\" is the device that connects your computer to the "
86"internet. This is usually a modem, an ISDN card or a network card in case "
87"you are using DSL."
88msgstr ""
89
90#: src/setup/ncurses/wizard_curs.c:315
91msgid "Network configuration: interface"
92msgstr ""
93
94#: src/setup/ncurses/wizard_curs.c:317
95msgid ""
96"What is the name of the network interface that connects your computer to the "
97"Internet?"
98msgstr ""
99
100#: src/setup/ncurses/wizard_curs.c:328
101msgid "Network configuration: IP"
102msgstr ""
103
104#: src/setup/ncurses/wizard_curs.c:330
105msgid "What is this computer's public IP address or hostname?"
106msgstr ""
107
108#: src/setup/ncurses/wizard_curs.c:331
109msgid ""
110"If your provider always assigns the same IP-Address to you (a \"static\" IP-"
111"Address), enter it into the \"IP-Address\" field. If your IP-Address changes "
112"every now and then (\"dynamic\" IP-Address) but there's a hostname that "
113"always points to your actual IP-Address (\"Dynamic DNS\"), you can also "
114"enter it here.\n"
115"If left empty, GNUnet will try to automatically detect the IP.\n"
116"You can specify a hostname, GNUnet will then use DNS to resolve it.\n"
117"If in doubt, leave this empty."
118msgstr ""
119
120#: src/setup/ncurses/wizard_curs.c:346
121msgid "Bandwidth configuration: upload"
122msgstr ""
123
124#: src/setup/ncurses/wizard_curs.c:348
125msgid "How much upstream bandwidth (in bytes/s) may be used?"
126msgstr ""
127
128#: src/setup/ncurses/wizard_curs.c:349
129msgid ""
130"You can limit GNUnet's resource usage here.\n"
131"\n"
132"The \"upstream\" is the data channel through which data is *sent* to the "
133"internet. The limit is the maximum amount which GNUnet is allowed to use. If "
134"you have a flatrate, you can set it to the maximum speed of your internet "
135"connection. You should not use a value that is higher than what your actual "
136"connection allows."
137msgstr ""
138
139#: src/setup/ncurses/wizard_curs.c:361
140msgid "Bandwidth configuration: download"
141msgstr ""
142
143#: src/setup/ncurses/wizard_curs.c:363
144msgid "How much downstream bandwidth (in bytes/s) may be used?"
145msgstr ""
146
147#: src/setup/ncurses/wizard_curs.c:364
148msgid ""
149"You can limit GNUnet's resource usage here.\n"
150"\n"
151"The \"downstream\" is the data channel through which data is *received* from "
152"the internet. The limit is the maximum amount which GNUnet is allowed to "
153"use. If you have a flatrate, you can set it to the maximum speed of your "
154"internet connection. You should not use a value that is higher than what "
155"your actual connection allows."
156msgstr ""
157
158#: src/setup/ncurses/wizard_curs.c:376
159msgid "Quota configuration"
160msgstr ""
161
162#: src/setup/ncurses/wizard_curs.c:377
163msgid "What is the maximum size of the datastore in MB?"
164msgstr ""
165
166#: src/setup/ncurses/wizard_curs.c:378
167msgid ""
168"The GNUnet datastore contains all content that GNUnet needs to store "
169"(indexed, inserted and migrated content)."
170msgstr ""
171
172#: src/setup/ncurses/wizard_curs.c:390
173msgid "Daemon configuration: user account"
174msgstr ""
175
176#: src/setup/ncurses/wizard_curs.c:391
177msgid "As which user should gnunetd be run?"
178msgstr ""
179
180#: src/setup/ncurses/wizard_curs.c:393
181msgid ""
182"For security reasons, it is a good idea to let this setup create a new user "
183"account under which the GNUnet service is started at system startup.\n"
184"\n"
185"However, GNUnet may not be able to access files other than its own. This "
186"includes files you want to publish in GNUnet. You'll have to grant read "
187"permissions to the user specified below.\n"
188"\n"
189"Leave the field empty to run GNUnet with system privileges.\n"
190msgstr ""
191
192#: src/setup/ncurses/wizard_curs.c:410
193msgid "Daemon configuration: group account"
194msgstr ""
195
196#: src/setup/ncurses/wizard_curs.c:411
197msgid "As which group should gnunetd be run?"
198msgstr ""
199
200#: src/setup/ncurses/wizard_curs.c:413
201msgid ""
202"For security reasons, it is a good idea to let this setup create a new group "
203"for the chosen user account.\n"
204"\n"
205"You can also specify a already existent group here.\n"
206"\n"
207"Only members of this group will be allowed to start and stop the the GNUnet "
208"server and have access to GNUnet server data.\n"
209msgstr ""
210
211#: src/setup/ncurses/wizard_curs.c:427
212msgid "Do you want to automatically launch GNUnet as a system service?"
213msgstr ""
214
215#: src/setup/ncurses/wizard_curs.c:429
216msgid ""
217"If you say \"yes\" here, the GNUnet background process will be automatically "
218"started when you turn on your computer. If you say \"no\" here, you have to "
219"launch GNUnet yourself each time you want to use it."
220msgstr ""
221
222#: src/setup/ncurses/wizard_curs.c:452 src/setup/gtk/wizard_gtk.c:414
223#, c-format
224msgid "Unable to save configuration file `%s':"
225msgstr ""
226
227#: src/setup/ncurses/wizard_curs.c:472
228msgid "Unable to create user account for daemon."
229msgstr ""
230
231#: src/setup/ncurses/wizard_curs.c:483
232msgid "Unable to setup autostart for daemon."
233msgstr ""
234
235#: src/setup/ncurses/wizard_curs.c:498
236msgid "Save configuration?"
237msgstr ""
238
239#: src/setup/ncurses/wizard_curs.c:499
240msgid "Save configuration now?"
241msgstr ""
242
243#: src/setup/ncurses/wizard_curs.c:539 src/setup/ncurses/mconf.c:500
244msgid "GNUnet Configuration"
245msgstr ""
246
247#: src/setup/ncurses/wizard_curs.c:543
248msgid "Back"
249msgstr ""
250
251#: src/setup/ncurses/mconf.c:96
252msgid "Exit"
253msgstr ""
254
255#: src/setup/ncurses/mconf.c:99
256msgid "Up"
257msgstr ""
258
259#: src/setup/ncurses/mconf.c:102
260msgid "Cancel"
261msgstr ""
262
263#: src/setup/ncurses/mconf.c:221 src/setup/ncurses/mconf.c:408
264msgid "Internal error! (Value invalid?)"
265msgstr ""
266
267#: src/setup/ncurses/mconf.c:398
268msgid "Invalid input, expecting floating point value."
269msgstr ""
270
271#: src/setup/ncurses/mconf.c:439
272msgid "Invalid input, expecting integer."
273msgstr ""
274
275#: src/setup/ncurses/mconf.c:446
276msgid "Value is not in legal range."
277msgstr ""
278
279#: src/setup/ncurses/mconf.c:512 src/setup/text/conf.c:569
280#, c-format
281msgid "Configuration unchanged, no need to save.\n"
282msgstr ""
283
284#: src/setup/ncurses/mconf.c:518
285msgid "Do you wish to save your new configuration?"
286msgstr ""
287
288#: src/setup/ncurses/mconf.c:532
289#, c-format
290msgid ""
291"\n"
292"End of configuration.\n"
293msgstr ""
294
295#: src/setup/ncurses/mconf.c:537
296#, c-format
297msgid ""
298"\n"
299"Your configuration changes were NOT saved.\n"
300msgstr ""
301
302#: src/setup/gnunet-win-tool.c:52
303msgid "list all network adapters"
304msgstr ""
305
306#: src/setup/gnunet-win-tool.c:55
307msgid "install GNUnet as Windows service"
308msgstr ""
309
310#: src/setup/gnunet-win-tool.c:58
311msgid "uninstall GNUnet service"
312msgstr ""
313
314#: src/setup/gnunet-win-tool.c:61
315msgid "increase the maximum number of TCP/IP connections"
316msgstr ""
317
318#: src/setup/gnunet-win-tool.c:64
319msgid "display a file's hash value"
320msgstr ""
321
322#: src/setup/gnunet-win-tool.c:125
323#, c-format
324msgid "GNUnet service installed successfully.\n"
325msgstr ""
326
327#: src/setup/gnunet-win-tool.c:128 src/setup/gnunet-win-tool.c:156
328#, c-format
329msgid "This version of Windows doesn't support services.\n"
330msgstr ""
331
332#: src/setup/gnunet-win-tool.c:132 src/setup/gnunet-win-tool.c:160
333#, c-format
334msgid "Error: can't open Service Control Manager: %s\n"
335msgstr ""
336
337#: src/setup/gnunet-win-tool.c:137
338#, c-format
339msgid "Error: can't create service: %s\n"
340msgstr ""
341
342#: src/setup/gnunet-win-tool.c:140 src/setup/gnunet-win-tool.c:172
343#, c-format
344msgid "Unknown error.\n"
345msgstr ""
346
347#: src/setup/gnunet-win-tool.c:153
348#, c-format
349msgid "Service deleted.\n"
350msgstr ""
351
352#: src/setup/gnunet-win-tool.c:165
353#, c-format
354msgid "Error: can't access service: %s\n"
355msgstr ""
356
357#: src/setup/gnunet-win-tool.c:169
358#, c-format
359msgid "Error: can't delete service: %s\n"
360msgstr ""
361
362#: src/setup/gtk/ngconf.c:389
363msgid "Configuration saved."
364msgstr ""
365
366#: src/setup/gtk/ngconf.c:399
367msgid "Failed to save configuration."
368msgstr ""
369
370#: src/setup/gtk/ngconf.c:424
371msgid "Configuration changed. Save?"
372msgstr ""
373
374#: src/setup/gtk/ngconf.c:437
375msgid "Error saving configuration."
376msgstr ""
377
378#: src/setup/gtk/wizard_gtk.c:141
379msgid "(unknown connection)"
380msgstr ""
381
382#: src/setup/gtk/wizard_gtk.c:438
383msgid "Do you want to save the new configuration?"
384msgstr ""
385
386#: src/setup/gtk/wizard_gtk.c:470
387msgid "Unable to create user account:"
388msgstr ""
389
390#: src/setup/gtk/wizard_gtk.c:480
391msgid "Unable to change startup process:"
392msgstr ""
393
394#: src/setup/gtk/wizard_gtk.c:495
395msgid ""
396"Running gnunet-update failed.\n"
397"This maybe due to insufficient permissions, please check your "
398"configuration.\n"
399"Finally, run gnunet-update manually."
400msgstr ""
401
402#: src/setup/gnunet-setup.c:65
403#, c-format
404msgid "Can only set one option per invocation.\n"
405msgstr ""
406
407#: src/setup/gnunet-setup.c:73
408#, c-format
409msgid ""
410"Invalid syntax, argument to 'set' must have the format SECTION:"
411"OPTION=VALUE.\n"
412msgstr ""
413
414#: src/setup/gnunet-setup.c:87
415#, c-format
416msgid "Can only display one option per invocation.\n"
417msgstr ""
418
419#: src/setup/gnunet-setup.c:94
420#, c-format
421msgid ""
422"Invalid syntax, argument to 'get' must have the format SECTION:OPTION.\n"
423msgstr ""
424
425#: src/setup/gnunet-setup.c:108
426msgid "generate configuration for gnunetd, the GNUnet daemon"
427msgstr ""
428
429#: src/setup/gnunet-setup.c:111 src/setup/gnunet-setup.c:127
430#: src/server/gnunet-update.c:268
431msgid "print a value from the configuration file to stdout"
432msgstr ""
433
434#: src/setup/gnunet-setup.c:113 src/setup/gnunet-setup.c:129
435msgid "Tool to setup GNUnet."
436msgstr ""
437
438#: src/setup/gnunet-setup.c:115 src/setup/gnunet-setup.c:131
439msgid "update a value in the configuration file"
440msgstr ""
441
442#: src/setup/gnunet-setup.c:338
443#, c-format
444msgid "Too many arguments.\n"
445msgstr ""
446
447#: src/setup/gnunet-setup.c:344
448msgid "No interface specified, using default.\n"
449msgstr ""
450
451#: src/setup/gnunet-setup.c:392
452#, c-format
453msgid "Configuration file `%s' must be a filename (but is a directory).\n"
454msgstr ""
455
456#: src/setup/gnunet-setup.c:439
457#, c-format
458msgid "Undefined option.\n"
459msgstr ""
460
461#: src/setup/gnunet-setup.c:496
462#, c-format
463msgid "`%s' is not available.\n"
464msgstr ""
465
466#: src/setup/gnunet-setup.c:516
467#, c-format
468msgid "Unknown operation '%s'.\n"
469msgstr ""
470
471#: src/setup/gnunet-setup.c:517 src/util/getopt/getopt.c:1072
472#, c-format
473msgid "Use --help to get a list of options.\n"
474msgstr ""
475
476#: src/setup/text/conf.c:79
477msgid "yes"
478msgstr ""
479
480#: src/setup/text/conf.c:80
481msgid "no"
482msgstr ""
483
484#: src/setup/text/conf.c:106
485#, c-format
486msgid "\tEnter yes (%s), no (%s) or help (%s): "
487msgstr ""
488
489#: src/setup/text/conf.c:115
490msgid "\tPossible choices:\n"
491msgstr ""
492
493#: src/setup/text/conf.c:123
494msgid "\tUse single space prefix to avoid conflicts with hotkeys!\n"
495msgstr ""
496
497#: src/setup/text/conf.c:125
498#, c-format
499msgid "\tEnter string (type '%s' for default value `%s'): "
500msgstr ""
501
502#: src/setup/text/conf.c:143
503#, c-format
504msgid "\t Enter choice (default is %c): "
505msgstr ""
506
507#: src/setup/text/conf.c:147
508#, c-format
509msgid "\tEnter floating point (type '%s' for default value %f): "
510msgstr ""
511
512#: src/setup/text/conf.c:153
513#, c-format
514msgid ""
515"\tEnter unsigned integer in interval [%llu,%llu] (type '%s' for default "
516"value %llu): "
517msgstr ""
518
519#: src/setup/text/conf.c:187
520#, c-format
521msgid "Yes\n"
522msgstr ""
523
524#: src/setup/text/conf.c:192
525#, c-format
526msgid "No\n"
527msgstr ""
528
529#: src/setup/text/conf.c:195 src/setup/text/conf.c:236
530#: src/setup/text/conf.c:266 src/setup/text/conf.c:329
531#: src/setup/text/conf.c:387
532#, c-format
533msgid "Help\n"
534msgstr ""
535
536#: src/setup/text/conf.c:198 src/setup/text/conf.c:213
537#: src/setup/text/conf.c:276 src/setup/text/conf.c:307
538#: src/setup/text/conf.c:365
539#, c-format
540msgid "Abort\n"
541msgstr ""
542
543#: src/setup/text/conf.c:354 src/setup/text/conf.c:416
544#, c-format
545msgid ""
546"\n"
547"Invalid entry, try again (use '?' for help): "
548msgstr ""
549
550#: src/setup/text/conf.c:422
551#, c-format
552msgid "Unknown kind %x (internal error). Skipping option.\n"
553msgstr ""
554
555#: src/setup/text/conf.c:484
556msgid "\tDescend? (y/n/?) "
557msgstr ""
558
559#: src/setup/text/conf.c:493
560msgid "Aborted.\n"
561msgstr ""
562
563#: src/setup/text/conf.c:506
564msgid "Invalid entry.\n"
565msgstr ""
566
567#: src/setup/text/conf.c:524
568#, c-format
569msgid "Unknown kind %x (internal error). Aborting.\n"
570msgstr ""
571
572#: src/setup/text/conf.c:556
573#, c-format
574msgid "You can always press ENTER to keep the current value.\n"
575msgstr ""
576
577#: src/setup/text/conf.c:557
578#, c-format
579msgid "Use the '%s' key to abort.\n"
580msgstr ""
581
582#: src/setup/text/conf.c:575
583#, c-format
584msgid ""
585"Save configuration? Answer 'y' for yes, 'n' for no, 'r' to repeat "
586"configuration. "
587msgstr ""
588
589#: src/setup/text/conf.c:590
590#, c-format
591msgid "Configuration was unchanged, no need to save.\n"
592msgstr ""
593
594#: src/setup/text/conf.c:599
595#, c-format
596msgid "Configuration file `%s' written.\n"
597msgstr ""
598
599#: src/setup/lib/tree.c:191
600#, c-format
601msgid ""
602"Internal error: entry `%s' in section `%s' not found for visibility change!\n"
603msgstr ""
604
605#: src/setup/lib/wizard_util.c:126
606msgid "Can't open Service Control Manager"
607msgstr ""
608
609#: src/setup/lib/wizard_util.c:132
610msgid "Can't create service"
611msgstr ""
612
613#: src/setup/lib/wizard_util.c:136
614msgid "Error changing the permissions of the GNUnet directory"
615msgstr ""
616
617#: src/setup/lib/wizard_util.c:141
618msgid "Cannot write to the registry"
619msgstr ""
620
621#: src/setup/lib/wizard_util.c:144
622msgid "Can't access the service"
623msgstr ""
624
625#: src/setup/lib/wizard_util.c:147
626msgid "Can't delete the service"
627msgstr ""
628
629#: src/setup/lib/wizard_util.c:150
630msgid "Unknown error"
631msgstr ""
632
633#: src/setup/lib/wizard_util.c:186
634msgid "This version of Windows does not support multiple users."
635msgstr ""
636
637#: src/setup/lib/wizard_util.c:190
638msgid "Error creating user"
639msgstr ""
640
641#: src/setup/lib/wizard_util.c:194
642msgid "Error accessing local security policy"
643msgstr ""
644
645#: src/setup/lib/wizard_util.c:199
646msgid "Error granting service right to user"
647msgstr ""
648
649#: src/setup/lib/wizard_util.c:204
650msgid "Unknown error while creating a new user"
651msgstr ""
652
653#: src/setup/lib/gns.c:297
654#, c-format
655msgid ""
656"Configuration does not satisfy constraints of configuration specification "
657"file `%s'!\n"
658msgstr ""
659
660#: src/util/disk/storage.c:172
661#, c-format
662msgid "`%s' failed for drive `%s': %u\n"
663msgstr ""
664
665#: src/util/disk/storage.c:524
666#, c-format
667msgid "Expected `%s' to be a directory!\n"
668msgstr ""
669
670#: src/util/error/error.c:152
671#, c-format
672msgid "Message `%.*s' repeated %u times in the last %llus\n"
673msgstr ""
674
675#: src/util/error/error.c:254
676#, c-format
677msgid ""
678"\n"
679"Press any key to continue\n"
680msgstr ""
681
682#: src/util/error/error.c:336 src/util/error/error.c:371
683msgid "DEBUG"
684msgstr ""
685
686#: src/util/error/error.c:338 src/util/error/error.c:373
687msgid "STATUS"
688msgstr ""
689
690#: src/util/error/error.c:340 src/util/error/error.c:377
691msgid "WARNING"
692msgstr ""
693
694#: src/util/error/error.c:342 src/util/error/error.c:379
695msgid "ERROR"
696msgstr ""
697
698#: src/util/error/error.c:344 src/util/error/error.c:381
699msgid "FATAL"
700msgstr ""
701
702#: src/util/error/error.c:346 src/util/error/error.c:383
703msgid "USER"
704msgstr ""
705
706#: src/util/error/error.c:348 src/util/error/error.c:385
707msgid "ADMIN"
708msgstr ""
709
710#: src/util/error/error.c:350 src/util/error/error.c:387
711msgid "DEVELOPER"
712msgstr ""
713
714#: src/util/error/error.c:352 src/util/error/error.c:389
715msgid "REQUEST"
716msgstr ""
717
718#: src/util/error/error.c:354 src/util/error/error.c:391
719msgid "BULK"
720msgstr ""
721
722#: src/util/error/error.c:356 src/util/error/error.c:393
723msgid "IMMEDIATE"
724msgstr ""
725
726#: src/util/error/error.c:358
727msgid "ALL"
728msgstr ""
729
730#: src/util/error/error.c:375
731msgid "INFO"
732msgstr ""
733
734#: src/util/error/error.c:394
735msgid "NOTHING"
736msgstr ""
737
738#: src/util/network_client/tcpio.c:98 src/util/network_client/tcpio.c:154
739msgid "Could not find valid value for HOST in section NETWORK.\n"
740msgstr ""
741
742#: src/util/network_client/tcpio.c:123
743#, c-format
744msgid "Syntax error in configuration entry HOST in section NETWORK: `%s'\n"
745msgstr ""
746
747#: src/util/network_client/tcpio.c:335
748#, c-format
749msgid "Error connecting to %s:%u. Is the daemon running?\n"
750msgstr ""
751
752#: src/util/network_client/tcpio.c:398
753#, c-format
754msgid "Cannot connect to %s:%u: %s\n"
755msgstr ""
756
757#: src/util/network_client/tcpio.c:636
758msgid "Reading result from gnunetd failed, reply invalid!\n"
759msgstr ""
760
761#: src/util/getopt/setoption.c:59
762#, c-format
763msgid ""
764"Setting option `%s' in section `%s' to `%s' when processing command line "
765"option `%s' was denied.\n"
766msgstr ""
767
768#: src/util/getopt/setoption.c:138 src/util/getopt/setoption.c:155
769#, c-format
770msgid "You must pass a number to the `%s' option.\n"
771msgstr ""
772
773#: src/util/getopt/printhelp.c:49
774#, c-format
775msgid ""
776"Arguments mandatory for long options are also mandatory for short options.\n"
777msgstr ""
778
779#: src/util/getopt/getopt.c:684
780#, c-format
781msgid "%s: option `%s' is ambiguous\n"
782msgstr ""
783
784#: src/util/getopt/getopt.c:710
785#, c-format
786msgid "%s: option `--%s' does not allow an argument\n"
787msgstr ""
788
789#: src/util/getopt/getopt.c:716
790#, c-format
791msgid "%s: option `%c%s' does not allow an argument\n"
792msgstr ""
793
794#: src/util/getopt/getopt.c:737 src/util/getopt/getopt.c:909
795#, c-format
796msgid "%s: option `%s' requires an argument\n"
797msgstr ""
798
799#: src/util/getopt/getopt.c:767
800#, c-format
801msgid "%s: unrecognized option `--%s'\n"
802msgstr ""
803
804#: src/util/getopt/getopt.c:771
805#, c-format
806msgid "%s: unrecognized option `%c%s'\n"
807msgstr ""
808
809#: src/util/getopt/getopt.c:797
810#, c-format
811msgid "%s: illegal option -- %c\n"
812msgstr ""
813
814#: src/util/getopt/getopt.c:799
815#, c-format
816msgid "%s: invalid option -- %c\n"
817msgstr ""
818
819#: src/util/getopt/getopt.c:828 src/util/getopt/getopt.c:958
820#, c-format
821msgid "%s: option requires an argument -- %c\n"
822msgstr ""
823
824#: src/util/getopt/getopt.c:876
825#, c-format
826msgid "%s: option `-W %s' is ambiguous\n"
827msgstr ""
828
829#: src/util/getopt/getopt.c:894
830#, c-format
831msgid "%s: option `-W %s' does not allow an argument\n"
832msgstr ""
833
834#: src/util/network/ip.c:96 src/util/network/ip.c:160 src/transports/ip.c:260
835#, c-format
836msgid "No interface specified in section `%s' under `%s'!\n"
837msgstr ""
838
839#: src/util/network/ip.c:127 src/util/network/ip.c:246 src/transports/ip.c:291
840#, c-format
841msgid "Could not obtain IP for interface `%s' using `%s'.\n"
842msgstr ""
843
844#: src/util/network/ip.c:216
845#, c-format
846msgid ""
847"Could not find interface `%s' using `%s', trying to find another interface.\n"
848msgstr ""
849
850#: src/util/network/ip.c:295
851#, c-format
852msgid "Could not find an IP address for interface `%s'.\n"
853msgstr ""
854
855#: src/util/network/ip.c:306
856#, c-format
857msgid ""
858"There is more than one IP address specified for interface `%s'.\n"
859"GNUnet will use %s.\n"
860msgstr ""
861
862#: src/util/network/ip.c:330
863#, c-format
864msgid "Could not resolve `%s' to determine our IP address: %s\n"
865msgstr ""
866
867#: src/util/network/ip.c:363
868#, c-format
869msgid "GNUnet now uses the IP address %s.\n"
870msgstr ""
871
872#: src/util/network/ipcheck.c:106 src/util/network/ipcheck.c:136
873#: src/util/network/ipcheck.c:186 src/util/network/ipcheck.c:211
874#: src/util/network/ipcheck.c:219
875#, c-format
876msgid "Invalid format for IP: `%s'\n"
877msgstr ""
878
879#: src/util/network/ipcheck.c:167
880#, c-format
881msgid "Invalid network notation ('/%d' is not legal in IPv4 CIDR)."
882msgstr ""
883
884#: src/util/network/ipcheck.c:269
885#, c-format
886msgid "Invalid network notation (does not end with ';': `%s')\n"
887msgstr ""
888
889#: src/util/network/ipcheck.c:306
890#, c-format
891msgid "Wrong format `%s' for netmask\n"
892msgstr ""
893
894#: src/util/network/ipcheck.c:338
895#, c-format
896msgid "Wrong format `%s' for network\n"
897msgstr ""
898
899#: src/util/network/dns.c:472
900#, c-format
901msgid "Could not resolve `%s' (%s): %s\n"
902msgstr ""
903
904#: src/util/network/dns.c:523 src/util/network/dns.c:591
905#, c-format
906msgid "Could not find IP of host `%s': %s\n"
907msgstr ""
908
909#: src/util/network/select.c:310
910msgid "Received malformed message (too small) from connection. Closing.\n"
911msgstr ""
912
913#: src/util/network/select.c:495
914#, c-format
915msgid "select listen socket for `%s' not valid!\n"
916msgstr ""
917
918#: src/util/config/config.c:296
919#, c-format
920msgid "Syntax error in configuration file `%s' at line %d.\n"
921msgstr ""
922
923#: src/util/config/config.c:592
924#, c-format
925msgid ""
926"Configuration value '%llu' for '%s' in section '%s' is out of legal bounds [%"
927"llu,%llu]\n"
928msgstr ""
929
930#: src/util/config/config.c:602
931#, c-format
932msgid "Configuration value '%s' for '%s' in section '%s' should be a number\n"
933msgstr ""
934
935#: src/util/config/config.c:688
936#, c-format
937msgid ""
938"Configuration value '%s' for '%s' in section '%s' is not in set of legal "
939"choices\n"
940msgstr ""
941
942#: src/util/crypto/locking_gcrypt.c:80
943#, c-format
944msgid "libgcrypt has not the expected version (version %s is required).\n"
945msgstr ""
946
947#: src/util/crypto/symcipher_gcrypt.c:46 src/util/crypto/symcipher_gcrypt.c:53
948#: src/util/crypto/hostkey_gcrypt.c:64 src/util/crypto/hostkey_gcrypt.c:71
949#: src/util/loggers/file.c:271 src/util/loggers/file.c:289
950#: src/applications/sqstore_sqlite/sqlite.c:45
951#: src/applications/sqstore_sqlite/sqlite.c:52
952#: src/applications/kvstore_sqlite/kv_sqlite.c:44
953#: src/applications/kvstore_sqlite/kv_sqlite.c:51
954#: src/applications/kvstore_mysql/kv_mysql.c:44
955#: src/applications/kvstore_mysql/kv_mysql.c:51
956#: src/applications/dstore_sqlite/dstore.c:94
957#: src/applications/dstore_sqlite/dstore.c:101
958#: src/applications/dstore_sqlite/dstore.c:222
959#: src/applications/dstore_sqlite/dstore.c:259
960#: src/applications/dstore_sqlite/dstore.c:285
961#: src/applications/dstore_sqlite/dstore.c:345
962#: src/applications/dstore_sqlite/dstore.c:366
963#: src/applications/dstore_sqlite/dstore.c:378
964#: src/applications/dstore_sqlite/dstore.c:407
965#: src/applications/dstore_sqlite/dstore.c:511
966#: src/applications/dstore_sqlite/dstore.c:555
967#: src/include/gnunet_util_error.h:249 src/include/gnunet_util_error.h:256
968#: src/include/gnunet_util_error.h:263
969#, c-format
970msgid "`%s' failed at %s:%d with error: %s\n"
971msgstr ""
972
973#: src/util/crypto/hostkey_gcrypt.c:907
974#, c-format
975msgid "RSA signature verification failed at %s:%d: %s\n"
976msgstr ""
977
978#: src/util/os/user.c:108 src/util/os/user.c:125
979#, c-format
980msgid "`%s' returned with error code %u"
981msgstr ""
982
983#: src/util/os/user.c:155 src/util/os/user.c:200
984#, c-format
985msgid "Cannot obtain information about user `%s': %s\n"
986msgstr ""
987
988#: src/util/os/user.c:156
989msgid "No such user"
990msgstr ""
991
992#: src/util/os/user.c:171
993#, c-format
994msgid "Cannot change user/group to `%s': %s\n"
995msgstr ""
996
997#: src/util/os/semaphore.c:227
998#, c-format
999msgid "Can't create semaphore: %i"
1000msgstr ""
1001
1002#: src/util/os/cpustatus.c:464
1003msgid "Cannot query the CPU usage (Windows NT).\n"
1004msgstr ""
1005
1006#: src/util/os/cpustatus.c:487
1007msgid "Cannot query the CPU usage (Win 9x)\n"
1008msgstr ""
1009
1010#: src/util/os/dso.c:59
1011#, c-format
1012msgid "Initialization of plugin mechanism failed: %s!\n"
1013msgstr ""
1014
1015#: src/util/os/dso.c:120
1016#, c-format
1017msgid "`%s' failed for library `%s' with error: %s\n"
1018msgstr ""
1019
1020#: src/util/os/dso.c:162
1021#, c-format
1022msgid "`%s' failed to resolve method '%s' with error: %s\n"
1023msgstr ""
1024
1025#: src/util/os/statuscalls.c:197 src/util/os/statuscalls.c:342
1026#, c-format
1027msgid "Failed to parse interface data from `%s'.\n"
1028msgstr ""
1029
1030#: src/util/os/statuscalls.c:390 src/util/os/statuscalls.c:400
1031#, c-format
1032msgid ""
1033"No network interfaces defined in configuration section `%s' under `%s'!\n"
1034msgstr ""
1035
1036#: src/util/os/osconfig.c:153
1037msgid "Setting open descriptor limit not supported.\n"
1038msgstr ""
1039
1040#: src/util/os/osconfig.c:463 src/util/os/osconfig.c:492
1041#, c-format
1042msgid "Command `%s' failed with error code %u\n"
1043msgstr ""
1044
1045#: src/util/os/priority.c:78
1046#, c-format
1047msgid "Invalid process priority `%s'\n"
1048msgstr ""
1049
1050#: src/util/threads/semaphore.c:168 src/util/threads/pthread.c:157
1051#: src/util/threads/mutex.c:146
1052#, c-format
1053msgid "Real-time delay violation (%llu ms) at %s:%u\n"
1054msgstr ""
1055
1056#: src/util/threads/pthread.c:169 src/util/threads/pthread.c:176
1057#: src/util/threads/pthread.c:182 src/util/threads/pthread.c:276
1058#, c-format
1059msgid "`%s' failed with error code %s: %s\n"
1060msgstr ""
1061
1062#: src/util/threads/pthread.c:188 src/util/threads/pthread.c:286
1063#, c-format
1064msgid "`%s' failed with error code %d: %s\n"
1065msgstr ""
1066
1067#: src/util/threads/mutex.c:155 src/util/threads/mutex.c:201
1068#, c-format
1069msgid "Invalid argument for `%s'.\n"
1070msgstr ""
1071
1072#: src/util/threads/mutex.c:160
1073#, c-format
1074msgid "Deadlock due to `%s'.\n"
1075msgstr ""
1076
1077#: src/util/threads/mutex.c:187
1078#, c-format
1079msgid "Lock acquired for too long (%llu ms) at %s:%u\n"
1080msgstr ""
1081
1082#: src/util/threads/mutex.c:207
1083#, c-format
1084msgid "Permission denied for `%s'.\n"
1085msgstr ""
1086
1087#: src/util/boot/startup.c:259
1088#, c-format
1089msgid "Failed to run %s: %s %d\n"
1090msgstr ""
1091
1092#: src/util/string/string.c:55
1093msgid "ms"
1094msgstr ""
1095
1096#: src/util/string/string.c:61
1097msgid "s"
1098msgstr ""
1099
1100#: src/util/string/string.c:65
1101msgid "m"
1102msgstr ""
1103
1104#: src/util/string/string.c:69
1105msgid "h"
1106msgstr ""
1107
1108#: src/util/string/string.c:73
1109msgid " days"
1110msgstr ""
1111
1112#: src/util/string/string.c:89
1113msgid "b"
1114msgstr ""
1115
1116#: src/util/string/string.c:95
1117msgid "KiB"
1118msgstr ""
1119
1120#: src/util/string/string.c:99
1121msgid "MiB"
1122msgstr ""
1123
1124#: src/util/string/string.c:103
1125msgid "GiB"
1126msgstr ""
1127
1128#: src/util/string/string.c:107
1129msgid "TiB"
1130msgstr ""
1131
1132#: src/util/string/string.c:226
1133msgid "Failed to expand `$HOME': environment variable `HOME' not set"
1134msgstr ""
1135
1136#: src/util/loggers/file.c:229
1137#, c-format
1138msgid "Failed to open log-file `%s': %s\n"
1139msgstr ""
1140
1141#: src/util/loggers/file.c:250
1142msgid "GNUnet error log"
1143msgstr ""
1144
1145#: src/util/loggers/memory.c:72
1146msgid "Out of memory (for logging)\n"
1147msgstr ""
1148
1149#: src/util/pseudonym/names.c:79
1150msgid "no-name"
1151msgstr ""
1152
1153#: src/applications/datastore/datastore.c:183
1154#: src/applications/datastore/datastore.c:199
1155#, c-format
1156msgid "Availability test failed for `%s' at %s:%d.\n"
1157msgstr ""
1158
1159#: src/applications/datastore/datastore.c:401
1160msgid "# requests filtered by bloom filter"
1161msgstr ""
1162
1163#: src/applications/datastore/datastore.c:403
1164msgid "# bloom filter false positives"
1165msgstr ""
1166
1167#: src/applications/datastore/datastore.c:406
1168msgid "# bytes allowed in datastore"
1169msgstr ""
1170
1171#: src/applications/datastore/datastore.c:423
1172msgid "Failed to load state service. Trying to do without.\n"
1173msgstr ""
1174
1175#: src/applications/datastore/datastore.c:529
1176#, c-format
1177msgid "Datastore conversion at approximately %u%%\n"
1178msgstr ""
1179
1180#: src/applications/datastore/datastore.c:576
1181#, c-format
1182msgid "Starting datastore conversion (this may take a while).\n"
1183msgstr ""
1184
1185#: src/applications/datastore/datastore.c:584
1186#, c-format
1187msgid "Completed datastore conversion.\n"
1188msgstr ""
1189
1190#: src/applications/datastore/datastore.c:592
1191msgid "Failed to load sqstore service. Check your configuration!\n"
1192msgstr ""
1193
1194#: src/applications/rpc/rpc.c:339
1195#, c-format
1196msgid ""
1197"%s:%d - RPC %s:%p could not be registered: another callback is already using "
1198"this name (%p)\n"
1199msgstr ""
1200
1201#: src/applications/rpc/rpc.c:398
1202#, c-format
1203msgid "%s:%d - async RPC %s:%p could not be unregistered: not found\n"
1204msgstr ""
1205
1206#: src/applications/rpc/rpc.c:951
1207#, c-format
1208msgid "`%s' registering handlers %d %d %d\n"
1209msgstr ""
1210
1211#: src/applications/rpc/rpc.c:972
1212#, c-format
1213msgid "Failed to initialize `%s' service.\n"
1214msgstr ""
1215
1216#: src/applications/tbench/tbenchtest.c:53
1217#, c-format
1218msgid "Using %u messages of size %u for %u times.\n"
1219msgstr ""
1220
1221#: src/applications/tbench/tbenchtest.c:85
1222#, c-format
1223msgid "Times: max %16llu min %16llu mean %12.3f variance %12.3f\n"
1224msgstr ""
1225
1226#: src/applications/tbench/tbenchtest.c:89
1227#, c-format
1228msgid "Loss: max %16u min %16u mean %12.3f variance %12.3f\n"
1229msgstr ""
1230
1231#: src/applications/tbench/tbenchtest.c:95
1232#, c-format
1233msgid ""
1234"\n"
1235"Failed to receive reply from gnunetd.\n"
1236msgstr ""
1237
1238#: src/applications/tbench/tbenchtest.c:149
1239#, c-format
1240msgid "Running benchmark...\n"
1241msgstr ""
1242
1243#: src/applications/tbench/tbench.c:422
1244msgid "allows profiling of direct peer-to-peer connections"
1245msgstr ""
1246
1247#: src/applications/tbench/gnunet-tbench.c:63
1248#: src/applications/tracekit/gnunet-tracekit.c:302
1249msgid "Start GNUnet transport benchmarking tool."
1250msgstr ""
1251
1252#: src/applications/tbench/gnunet-tbench.c:65
1253msgid "output in gnuplot format"
1254msgstr ""
1255
1256#: src/applications/tbench/gnunet-tbench.c:69
1257msgid "number of iterations"
1258msgstr ""
1259
1260#: src/applications/tbench/gnunet-tbench.c:73
1261msgid "number of messages to use per iteration"
1262msgstr ""
1263
1264#: src/applications/tbench/gnunet-tbench.c:76
1265msgid "receiver host identifier (ENC file name)"
1266msgstr ""
1267
1268#: src/applications/tbench/gnunet-tbench.c:79
1269msgid "message size"
1270msgstr ""
1271
1272#: src/applications/tbench/gnunet-tbench.c:82
1273msgid "sleep for SPACE ms after each a message block"
1274msgstr ""
1275
1276#: src/applications/tbench/gnunet-tbench.c:85
1277msgid "time to wait for the completion of an iteration (in ms)"
1278msgstr ""
1279
1280#: src/applications/tbench/gnunet-tbench.c:90
1281msgid "number of messages in a message block"
1282msgstr ""
1283
1284#: src/applications/tbench/gnunet-tbench.c:126
1285#: src/applications/tracekit/gnunet-tracekit.c:352
1286#: src/applications/tracekit/tracekittest.c:133
1287#: src/applications/template/gnunet-template.c:95
1288#: src/applications/stats/gnunet-stats.c:121
1289#: src/applications/vpn/gnunet-vpn.c:154
1290#, c-format
1291msgid "Error establishing connection with gnunetd.\n"
1292msgstr ""
1293
1294#: src/applications/tbench/gnunet-tbench.c:142
1295#, c-format
1296msgid "You must specify a receiver!\n"
1297msgstr ""
1298
1299#: src/applications/tbench/gnunet-tbench.c:152
1300#, c-format
1301msgid "Invalid receiver peer ID specified (`%s' is not valid name).\n"
1302msgstr ""
1303
1304#: src/applications/tbench/gnunet-tbench.c:189
1305#, c-format
1306msgid "Time:\n"
1307msgstr ""
1308
1309#: src/applications/tbench/gnunet-tbench.c:190
1310#, c-format
1311msgid "\tmax %llums\n"
1312msgstr ""
1313
1314#: src/applications/tbench/gnunet-tbench.c:191
1315#, c-format
1316msgid "\tmin %llums\n"
1317msgstr ""
1318
1319#: src/applications/tbench/gnunet-tbench.c:192
1320#, c-format
1321msgid "\tmean %8.4fms\n"
1322msgstr ""
1323
1324#: src/applications/tbench/gnunet-tbench.c:193
1325#, c-format
1326msgid "\tvariance %8.4fms\n"
1327msgstr ""
1328
1329#: src/applications/tbench/gnunet-tbench.c:195
1330#, c-format
1331msgid "Loss:\n"
1332msgstr ""
1333
1334#: src/applications/tbench/gnunet-tbench.c:196
1335#, c-format
1336msgid "\tmax %u\n"
1337msgstr ""
1338
1339#: src/applications/tbench/gnunet-tbench.c:197
1340#, c-format
1341msgid "\tmin %u\n"
1342msgstr ""
1343
1344#: src/applications/tbench/gnunet-tbench.c:198
1345#, c-format
1346msgid "\tmean %8.4f\n"
1347msgstr ""
1348
1349#: src/applications/tbench/gnunet-tbench.c:199
1350#, c-format
1351msgid "\tvariance %8.4f\n"
1352msgstr ""
1353
1354#: src/applications/tbench/gnunet-tbench.c:205
1355#, c-format
1356msgid "Output format not known, this should not happen.\n"
1357msgstr ""
1358
1359#: src/applications/tbench/gnunet-tbench.c:211
1360#, c-format
1361msgid ""
1362"\n"
1363"Did not receive the message from gnunetd. Is gnunetd running?\n"
1364msgstr ""
1365
1366#: src/applications/traffic/traffic.c:454
1367#, c-format
1368msgid "# bytes transmitted of type %d"
1369msgstr ""
1370
1371#: src/applications/traffic/traffic.c:470
1372#, c-format
1373msgid "# bytes received of type %d"
1374msgstr ""
1375
1376#: src/applications/traffic/traffic.c:489
1377#, c-format
1378msgid "# bytes received in plaintext of type %d"
1379msgstr ""
1380
1381#: src/applications/traffic/traffic.c:652
1382msgid "tracks bandwidth utilization by gnunetd"
1383msgstr ""
1384
1385#: src/applications/sqstore_sqlite/sqlite.c:218
1386#, c-format
1387msgid "Unable to initialize SQLite: %s.\n"
1388msgstr ""
1389
1390#: src/applications/sqstore_sqlite/sqlite.c:434
1391#: src/applications/sqstore_sqlite/sqlite.c:469
1392#, c-format
1393msgid "Invalid data in %s. Trying to fix (by deletion).\n"
1394msgstr ""
1395
1396#: src/applications/sqstore_sqlite/sqlite.c:435
1397#: src/applications/sqstore_sqlite/sqlite.c:470
1398msgid "sqlite datastore"
1399msgstr ""
1400
1401#: src/applications/sqstore_sqlite/sqlite.c:1474
1402#: src/applications/sqstore_mysql/mysql.c:1078
1403msgid "# bytes in datastore"
1404msgstr ""
1405
1406#: src/applications/sqstore_sqlite/sqlite.c:1476
1407msgid "# bytes allocated by SQLite"
1408msgstr ""
1409
1410#: src/applications/sqstore_mysql/mysql.c:1085
1411#: src/applications/sqstore_mysql/mysql.c:1160
1412msgid ""
1413"Failed to load MySQL database module. Check that MySQL is running and "
1414"configured properly!\n"
1415msgstr ""
1416
1417#: src/applications/tracekit/gnunet-tracekit.c:104
1418#, c-format
1419msgid "`%s' connected to `%s'.\n"
1420msgstr ""
1421
1422#: src/applications/tracekit/gnunet-tracekit.c:110
1423#: src/applications/tracekit/tracekittest.c:67
1424#, c-format
1425msgid "`%s' is not connected to any peer.\n"
1426msgstr ""
1427
1428#: src/applications/tracekit/gnunet-tracekit.c:295
1429msgid "probe network to the given DEPTH"
1430msgstr ""
1431
1432#: src/applications/tracekit/gnunet-tracekit.c:299
1433msgid ""
1434"specify output format; 0 for human readable output, 1 for dot, 2 for vcg"
1435msgstr ""
1436
1437#: src/applications/tracekit/gnunet-tracekit.c:306
1438msgid "use PRIORITY for the priority of the trace request"
1439msgstr ""
1440
1441#: src/applications/tracekit/gnunet-tracekit.c:310
1442msgid "wait DELAY seconds for replies"
1443msgstr ""
1444
1445#: src/applications/tracekit/gnunet-tracekit.c:344
1446#, c-format
1447msgid ""
1448"Format specification invalid. Use 0 for user-readable, 1 for dot, 2 for "
1449"vcg.\n"
1450msgstr ""
1451
1452#: src/applications/tracekit/tracekittest.c:60
1453#, c-format
1454msgid "`%.*s' connected to `%.*s'.\n"
1455msgstr ""
1456
1457#: src/applications/tracekit/tracekit.c:440
1458msgid "allows mapping of the network topology"
1459msgstr ""
1460
1461#: src/applications/advertising/advertising_test.c:47
1462#: src/applications/hostlist/hostlisttest.c:40
1463#: src/applications/session/sessiontest.c:40
1464#: src/applications/session/sessiontest_nat_http.c:40
1465#: src/applications/session/sessiontest_nat.c:40
1466#: src/applications/stats/statistics.c:247
1467msgid "# of connected peers"
1468msgstr ""
1469
1470#: src/applications/advertising/advertising.c:194
1471#, c-format
1472msgid "HELLO message from `%s' has an invalid signature. Dropping.\n"
1473msgstr ""
1474
1475#: src/applications/advertising/advertising.c:205
1476msgid "HELLO message has expiration too far in the future. Dropping.\n"
1477msgstr ""
1478
1479#: src/applications/advertising/advertising.c:406
1480msgid "Could not send HELLO+PING, ping buffer full.\n"
1481msgstr ""
1482
1483#: src/applications/advertising/advertising.c:429
1484msgid "Failed to create an advertisement for this peer. Will not send PING.\n"
1485msgstr ""
1486
1487#: src/applications/advertising/advertising.c:581
1488#, c-format
1489msgid "Advertising my transport %d to selected peers.\n"
1490msgstr ""
1491
1492#: src/applications/advertising/advertising.c:590
1493msgid ""
1494"Announcing ourselves pointless: no other peers are known to us so far.\n"
1495msgstr ""
1496
1497#: src/applications/advertising/advertising.c:868
1498msgid "# Peer advertisements received"
1499msgstr ""
1500
1501#: src/applications/advertising/advertising.c:871
1502msgid "# Peer advertisements of type NAT received"
1503msgstr ""
1504
1505#: src/applications/advertising/advertising.c:874
1506msgid "# Peer advertisements confirmed via PONG"
1507msgstr ""
1508
1509#: src/applications/advertising/advertising.c:877
1510msgid "# Peer advertisements updating earlier HELLOs"
1511msgstr ""
1512
1513#: src/applications/advertising/advertising.c:880
1514msgid "# Peer advertisements discarded due to load"
1515msgstr ""
1516
1517#: src/applications/advertising/advertising.c:883
1518msgid "# Peer advertisements for unsupported transport"
1519msgstr ""
1520
1521#: src/applications/advertising/advertising.c:886
1522msgid "# Peer advertisements not confirmed due to ping busy"
1523msgstr ""
1524
1525#: src/applications/advertising/advertising.c:889
1526msgid "# Peer advertisements not confirmed due to lack of self ad"
1527msgstr ""
1528
1529#: src/applications/advertising/advertising.c:892
1530msgid "# Peer advertisements not confirmed due to send error"
1531msgstr ""
1532
1533#: src/applications/advertising/advertising.c:894
1534msgid "# Self advertisments transmitted"
1535msgstr ""
1536
1537#: src/applications/advertising/advertising.c:896
1538msgid "# Foreign advertisements forwarded"
1539msgstr ""
1540
1541#: src/applications/advertising/advertising.c:898
1542#: src/applications/pingpong/pingpong.c:528
1543msgid "# plaintext PING messages sent"
1544msgstr ""
1545
1546#: src/applications/advertising/advertising.c:904
1547#: src/applications/session/connect.c:932
1548#, c-format
1549msgid "`%s' registering handler %d (plaintext and ciphertext)\n"
1550msgstr ""
1551
1552#: src/applications/advertising/advertising.c:922
1553msgid ""
1554"ensures that this peer is known by other peers and discovers other peers"
1555msgstr ""
1556
1557#: src/applications/fragmentation/fragmentation.c:578
1558msgid "# messages defragmented"
1559msgstr ""
1560
1561#: src/applications/fragmentation/fragmentation.c:580
1562msgid "# messages fragmented"
1563msgstr ""
1564
1565#: src/applications/fragmentation/fragmentation.c:581
1566msgid "# fragments discarded"
1567msgstr ""
1568
1569#: src/applications/fragmentation/fragmentation.c:592
1570#, c-format
1571msgid "`%s' registering handler %d\n"
1572msgstr ""
1573
1574#: src/applications/topology_default/topology.c:466
1575#, c-format
1576msgid "Could not read friends list `%s'\n"
1577msgstr ""
1578
1579#: src/applications/topology_default/topology.c:485
1580#, c-format
1581msgid "Failed to read friends list from `%s'\n"
1582msgstr ""
1583
1584#: src/applications/topology_default/topology.c:505
1585msgid "Syntax error in topology specification, skipping bytes.\n"
1586msgstr ""
1587
1588#: src/applications/topology_default/topology.c:523
1589#, c-format
1590msgid "Syntax error in topology specification, skipping bytes `%s'.\n"
1591msgstr ""
1592
1593#: src/applications/topology_default/topology.c:535
1594msgid ""
1595"Fewer friends specified than required by minimum friend count. Will only "
1596"connect to friends.\n"
1597msgstr ""
1598
1599#: src/applications/topology_default/topology.c:543
1600msgid ""
1601"More friendly connections required than target total number of connections.\n"
1602msgstr ""
1603
1604#: src/applications/topology_default/topology.c:726
1605msgid "maintains GNUnet default mesh topology"
1606msgstr ""
1607
1608#: src/applications/chat/tools/gnunet-chat.c:107
1609msgid "anonymous"
1610msgstr ""
1611
1612#: src/applications/chat/tools/gnunet-chat.c:113
1613#, c-format
1614msgid "`%s' said: %s\n"
1615msgstr ""
1616
1617#: src/applications/chat/tools/gnunet-chat.c:116
1618#: src/applications/chat/tools/gnunet-chat.c:119
1619#, c-format
1620msgid "`%s' said to you: %s\n"
1621msgstr ""
1622
1623#: src/applications/chat/tools/gnunet-chat.c:122
1624#, c-format
1625msgid "`%s' said for sure: %s\n"
1626msgstr ""
1627
1628#: src/applications/chat/tools/gnunet-chat.c:125
1629#, c-format
1630msgid "`%s' said to you for sure: %s\n"
1631msgstr ""
1632
1633#: src/applications/chat/tools/gnunet-chat.c:128
1634#, c-format
1635msgid "`%s' was confirmed that you received: %s\n"
1636msgstr ""
1637
1638#: src/applications/chat/tools/gnunet-chat.c:131
1639#, c-format
1640msgid "`%s' was confirmed that you and only you received: %s\n"
1641msgstr ""
1642
1643#: src/applications/chat/tools/gnunet-chat.c:134
1644#, c-format
1645msgid "`%s' was confirmed that you received from him or her: %s\n"
1646msgstr ""
1647
1648#: src/applications/chat/tools/gnunet-chat.c:139
1649#, c-format
1650msgid "`%s' was confirmed that you and only you received from him or her: %s\n"
1651msgstr ""
1652
1653#: src/applications/chat/tools/gnunet-chat.c:142
1654#, c-format
1655msgid "`%s' said off the record: %s\n"
1656msgstr ""
1657
1658#: src/applications/chat/tools/gnunet-chat.c:145
1659#, c-format
1660msgid "<%s> said using an unknown message type: %s\n"
1661msgstr ""
1662
1663#: src/applications/chat/tools/gnunet-chat.c:167
1664#, c-format
1665msgid "`%s' entered the room\n"
1666msgstr ""
1667
1668#: src/applications/chat/tools/gnunet-chat.c:167
1669#, c-format
1670msgid "`%s' left the room\n"
1671msgstr ""
1672
1673#: src/applications/chat/tools/gnunet-chat.c:239
1674#: src/applications/chat/tools/gnunet-chat.c:348
1675#, c-format
1676msgid "Failed to send message.\n"
1677msgstr ""
1678
1679#: src/applications/chat/tools/gnunet-chat.c:265
1680#: src/applications/chat/tools/gnunet-chat.c:524
1681#, c-format
1682msgid "Joined room `%s' as user `%s'.\n"
1683msgstr ""
1684
1685#: src/applications/chat/tools/gnunet-chat.c:293
1686#, c-format
1687msgid "Changed username to `%s'.\n"
1688msgstr ""
1689
1690#: src/applications/chat/tools/gnunet-chat.c:301
1691#, c-format
1692msgid "Unknown command `%s'.\n"
1693msgstr ""
1694
1695#: src/applications/chat/tools/gnunet-chat.c:316
1696#, c-format
1697msgid "Syntax: /msg USERNAME MESSAGE"
1698msgstr ""
1699
1700#: src/applications/chat/tools/gnunet-chat.c:324
1701#, c-format
1702msgid "Unknown user `%s'\n"
1703msgstr ""
1704
1705#: src/applications/chat/tools/gnunet-chat.c:339
1706#, c-format
1707msgid "User `%s' is currently not in the room!\n"
1708msgstr ""
1709
1710#: src/applications/chat/tools/gnunet-chat.c:361
1711#, c-format
1712msgid "Users in room `%s': "
1713msgstr ""
1714
1715#: src/applications/chat/tools/gnunet-chat.c:390
1716msgid ""
1717"Use `/join #roomname' to join a chat room. Joining a room will cause you to "
1718"leave the current room"
1719msgstr ""
1720
1721#: src/applications/chat/tools/gnunet-chat.c:393
1722msgid ""
1723"Use `/nick nickname' to change your nickname. This will cause you to leave "
1724"the current room and immediately rejoin it with the new name."
1725msgstr ""
1726
1727#: src/applications/chat/tools/gnunet-chat.c:396
1728msgid ""
1729"Use `/msg nickname message' to send a private message to the specified user"
1730msgstr ""
1731
1732#: src/applications/chat/tools/gnunet-chat.c:398
1733msgid "The `/notice' command is an alias for `/msg'"
1734msgstr ""
1735
1736#: src/applications/chat/tools/gnunet-chat.c:400
1737msgid "The `/query' command is an alias for `/msg'"
1738msgstr ""
1739
1740#: src/applications/chat/tools/gnunet-chat.c:402
1741msgid "Use `/quit' to terminate gnunet-chat"
1742msgstr ""
1743
1744#: src/applications/chat/tools/gnunet-chat.c:404
1745msgid "The `/leave' command is an alias for `/quit'"
1746msgstr ""
1747
1748#: src/applications/chat/tools/gnunet-chat.c:407
1749msgid "Use `/names' to list all of the current members in the chat room"
1750msgstr ""
1751
1752#: src/applications/chat/tools/gnunet-chat.c:409
1753msgid "Use `/help command' to get help for a specific command"
1754msgstr ""
1755
1756#: src/applications/chat/tools/gnunet-chat.c:457
1757msgid "Join a chat on GNUnet."
1758msgstr ""
1759
1760#: src/applications/chat/tools/gnunet-chat.c:461
1761msgid "set the nickname to use (required)"
1762msgstr ""
1763
1764#: src/applications/chat/tools/gnunet-chat.c:464
1765msgid "set the chat room to join"
1766msgstr ""
1767
1768#: src/applications/chat/tools/gnunet-chat.c:495
1769#, c-format
1770msgid "You must specify a nickname\n"
1771msgstr ""
1772
1773#: src/applications/chat/tools/gnunet-chat.c:515
1774#, c-format
1775msgid "Failed to join room `%s'\n"
1776msgstr ""
1777
1778#: src/applications/chat/module/chat.c:325
1779#, c-format
1780msgid "`%s' registering CS handlers %d and %d\n"
1781msgstr ""
1782
1783#: src/applications/chat/module/chat.c:347
1784msgid "enables P2P-chat (incomplete)"
1785msgstr ""
1786
1787#: src/applications/chat/lib/messaging.c:353
1788#: src/applications/identity/hostkey.c:122
1789#, c-format
1790msgid "Failed to access GNUnet home directory `%s'\n"
1791msgstr ""
1792
1793#: src/applications/chat/lib/messaging.c:389
1794#, c-format
1795msgid "Existing key in file `%s' failed format check, creating new key.\n"
1796msgstr ""
1797
1798#: src/applications/chat/lib/messaging.c:399
1799msgid "Creating new key for this nickname (this may take a while).\n"
1800msgstr ""
1801
1802#: src/applications/chat/lib/messaging.c:411
1803msgid "Done creating key.\n"
1804msgstr ""
1805
1806#: src/applications/dstore_mysql/dstore_mysql.c:471
1807msgid "Failed to initialize MySQL database connection for dstore.\n"
1808msgstr ""
1809
1810#: src/applications/dstore_mysql/dstore_mysql.c:494
1811#: src/applications/dstore_sqlite/dstore.c:636
1812msgid "# bytes in dstore"
1813msgstr ""
1814
1815#: src/applications/dstore_mysql/dstore_mysql.c:496
1816#: src/applications/dstore_sqlite/dstore.c:638
1817msgid "# max bytes allowed in dstore"
1818msgstr ""
1819
1820#: src/applications/transport/transport.c:191
1821#, c-format
1822msgid ""
1823"Converting peer address to string failed, transport type %d not supported\n"
1824msgstr ""
1825
1826#: src/applications/transport/transport.c:246
1827#, c-format
1828msgid "Transport connection attempt failed, transport type %d not supported\n"
1829msgstr ""
1830
1831#: src/applications/transport/transport.c:299
1832#, c-format
1833msgid ""
1834"Transport failed to connect to peer `%s' (%u HELLOs known, none worked)\n"
1835msgstr ""
1836
1837#: src/applications/transport/transport.c:376
1838#, c-format
1839msgid "Transmission attempt failed, transport type %d unknown.\n"
1840msgstr ""
1841
1842#: src/applications/transport/transport.c:500
1843#, c-format
1844msgid "No transport of type %d known.\n"
1845msgstr ""
1846
1847#: src/applications/transport/transport.c:560
1848msgid "No transport succeeded in creating a hello!\n"
1849msgstr ""
1850
1851#: src/applications/transport/transport.c:761
1852#, c-format
1853msgid "Loading transports `%s'\n"
1854msgstr ""
1855
1856#: src/applications/transport/transport.c:781
1857#, c-format
1858msgid "Could not load transport plugin `%s'\n"
1859msgstr ""
1860
1861#: src/applications/transport/transport.c:795
1862#, c-format
1863msgid "Transport library `%s' did not provide required function '%s%s'.\n"
1864msgstr ""
1865
1866#: src/applications/transport/transport.c:824
1867#, c-format
1868msgid "Loaded transport `%s'\n"
1869msgstr ""
1870
1871#: src/applications/transport/transport.c:836
1872#: src/server/gnunet-peer-info.c:252
1873#, c-format
1874msgid "I am peer `%s'.\n"
1875msgstr ""
1876
1877#: src/applications/dht/tools/dht_multipeer_test.c:80
1878#: src/applications/dht/tools/dht_twopeer_test.c:47
1879#: src/applications/dht/module/table.c:783
1880msgid "# dht connections"
1881msgstr ""
1882
1883#: src/applications/dht/tools/dht-query.c:54
1884msgid "Query (get KEY, put KEY VALUE) DHT table."
1885msgstr ""
1886
1887#: src/applications/dht/tools/dht-query.c:58
1888msgid "allow TIME ms to process a GET command"
1889msgstr ""
1890
1891#: src/applications/dht/tools/dht-query.c:107
1892#, c-format
1893msgid "Issuing `%s(%s,%s)' command.\n"
1894msgstr ""
1895
1896#: src/applications/dht/tools/dht-query.c:142
1897#: src/applications/fs/tools/gnunet-auto-share.c:669
1898#, c-format
1899msgid "Failed to connect to gnunetd.\n"
1900msgstr ""
1901
1902#: src/applications/dht/tools/dht-query.c:155
1903#, c-format
1904msgid "Command `%s' requires an argument (`%s').\n"
1905msgstr ""
1906
1907#: src/applications/dht/tools/dht-query.c:172
1908#, c-format
1909msgid "Command `%s' requires two arguments (`%s' and `%s').\n"
1910msgstr ""
1911
1912#: src/applications/dht/tools/dht-query.c:183
1913#, c-format
1914msgid "Unsupported command `%s'. Aborting.\n"
1915msgstr ""
1916
1917#: src/applications/dht/module/table.c:785
1918msgid "# dht discovery messages received"
1919msgstr ""
1920
1921#: src/applications/dht/module/table.c:787
1922msgid "# dht route host lookups performed"
1923msgstr ""
1924
1925#: src/applications/dht/module/table.c:789
1926msgid "# dht discovery messages sent"
1927msgstr ""
1928
1929#: src/applications/dht/module/routing.c:879
1930msgid "# dht replies routed"
1931msgstr ""
1932
1933#: src/applications/dht/module/routing.c:881
1934msgid "# dht requests routed"
1935msgstr ""
1936
1937#: src/applications/dht/module/routing.c:883
1938msgid "# dht get requests received"
1939msgstr ""
1940
1941#: src/applications/dht/module/routing.c:885
1942msgid "# dht put requests received"
1943msgstr ""
1944
1945#: src/applications/dht/module/routing.c:887
1946msgid "# dht results received"
1947msgstr ""
1948
1949#: src/applications/dht/module/routing.c:892
1950#, c-format
1951msgid "`%s' registering p2p handlers: %d %d %d\n"
1952msgstr ""
1953
1954#: src/applications/dht/module/cs.c:122
1955#, c-format
1956msgid "`%s' failed. Terminating connection to client.\n"
1957msgstr ""
1958
1959#: src/applications/dht/module/cs.c:250
1960#, c-format
1961msgid "`%s' registering client handlers: %d %d\n"
1962msgstr ""
1963
1964#: src/applications/dht/module/cs.c:273
1965msgid "Enables efficient non-anonymous routing"
1966msgstr ""
1967
1968#: src/applications/identity/hostkey.c:155
1969#, c-format
1970msgid ""
1971"Existing hostkey in file `%s' failed format check, creating new hostkey.\n"
1972msgstr ""
1973
1974#: src/applications/identity/hostkey.c:164
1975msgid "Creating new hostkey (this may take a while).\n"
1976msgstr ""
1977
1978#: src/applications/identity/hostkey.c:176
1979msgid "Done creating hostkey.\n"
1980msgstr ""
1981
1982#: src/applications/identity/identity.c:333
1983#, c-format
1984msgid ""
1985"File `%s' in directory `%s' does not match naming convention. Removed.\n"
1986msgstr ""
1987
1988#: src/applications/identity/identity.c:408
1989#, c-format
1990msgid "Still no peers found in `%s'!\n"
1991msgstr ""
1992
1993#: src/applications/identity/identity.c:731
1994#: src/applications/identity/identity.c:757
1995#, c-format
1996msgid "Removed file `%s' containing invalid HELLO data.\n"
1997msgstr ""
1998
1999#: src/applications/identity/identity.c:809
2000#, c-format
2001msgid "Signature failed verification: peer `%s' not known.\n"
2002msgstr ""
2003
2004#: src/applications/identity/identity.c:819
2005msgid "Signature failed verification: signature invalid.\n"
2006msgstr ""
2007
2008#: src/applications/identity/identity.c:935
2009#: src/applications/identity/identity.c:1058
2010#, c-format
2011msgid "Peer `%s' is currently strictly blacklisted (for another %llums).\n"
2012msgstr ""
2013
2014#: src/applications/identity/identity.c:1061
2015#, c-format
2016msgid "Peer `%s' is currently blacklisted (for another %llums).\n"
2017msgstr ""
2018
2019#: src/applications/pingpong/pingpong.c:134
2020#: src/applications/pingpong/pingpong.c:203
2021#: src/applications/pingpong/pingpong.c:273
2022#: src/applications/pingpong/pingpong.c:345
2023#, c-format
2024msgid "Received malformed `%s' message. Dropping.\n"
2025msgstr ""
2026
2027#: src/applications/pingpong/pingpong.c:146
2028msgid "Received ping for another peer. Dropping.\n"
2029msgstr ""
2030
2031#: src/applications/pingpong/pingpong.c:215
2032#, c-format
2033msgid "Received PING from `%s' not destined for us!\n"
2034msgstr ""
2035
2036#: src/applications/pingpong/pingpong.c:315
2037#: src/applications/pingpong/pingpong.c:381
2038msgid ""
2039"Could not match PONG against any PING. Try increasing MAX_PING_PONG "
2040"constant.\n"
2041msgstr ""
2042
2043#: src/applications/pingpong/pingpong.c:425
2044msgid "Cannot create PING, table full. Try increasing MAX_PING_PONG.\n"
2045msgstr ""
2046
2047#: src/applications/pingpong/pingpong.c:518
2048msgid "# encrypted PONG messages received"
2049msgstr ""
2050
2051#: src/applications/pingpong/pingpong.c:520
2052msgid "# plaintext PONG messages received"
2053msgstr ""
2054
2055#: src/applications/pingpong/pingpong.c:522
2056msgid "# encrypted PING messages received"
2057msgstr ""
2058
2059#: src/applications/pingpong/pingpong.c:524
2060msgid "# PING messages created"
2061msgstr ""
2062
2063#: src/applications/pingpong/pingpong.c:526
2064#: src/applications/session/connect.c:926
2065msgid "# encrypted PONG messages sent"
2066msgstr ""
2067
2068#: src/applications/pingpong/pingpong.c:530
2069#: src/applications/session/connect.c:924
2070msgid "# encrypted PING messages sent"
2071msgstr ""
2072
2073#: src/applications/pingpong/pingpong.c:532
2074msgid "# plaintext PONG messages sent"
2075msgstr ""
2076
2077#: src/applications/pingpong/pingpong.c:536
2078msgid "# plaintext PONG transmissions failed"
2079msgstr ""
2080
2081#: src/applications/pingpong/pingpong.c:546
2082#, c-format
2083msgid "`%s' registering handlers %d %d (plaintext and ciphertext)\n"
2084msgstr ""
2085
2086#: src/applications/hostlist/hostlist.c:165
2087msgid "# hostlist requests received"
2088msgstr ""
2089
2090#: src/applications/hostlist/hostlist.c:167
2091msgid "# hostlist HELLOs returned"
2092msgstr ""
2093
2094#: src/applications/hostlist/hostlist.c:169
2095msgid "# hostlist bytes returned"
2096msgstr ""
2097
2098#: src/applications/hostlist/hostlist.c:199
2099msgid "integrated HTTP hostlist server"
2100msgstr ""
2101
2102#: src/applications/session/connect.c:238
2103#, c-format
2104msgid "Session key from peer `%s' could not be verified.\n"
2105msgstr ""
2106
2107#: src/applications/session/connect.c:282
2108#, c-format
2109msgid "Cannot encrypt sessionkey, peer `%s' not known!\n"
2110msgstr ""
2111
2112#: src/applications/session/connect.c:489
2113#, c-format
2114msgid "Could not create any HELLO for myself (have transports `%s')!\n"
2115msgstr ""
2116
2117#: src/applications/session/connect.c:599
2118#, c-format
2119msgid "Session key received from peer `%s' has invalid format (discarded).\n"
2120msgstr ""
2121
2122#: src/applications/session/connect.c:632
2123#, c-format
2124msgid "Session key received from peer `%s' is for `%s' and not for me!\n"
2125msgstr ""
2126
2127#: src/applications/session/connect.c:659
2128#, c-format
2129msgid "Invalid `%s' message received from peer `%s'.\n"
2130msgstr ""
2131
2132#: src/applications/session/connect.c:670
2133#, c-format
2134msgid "setkey `%s' from `%s' fails CRC check (have: %u, want %u).\n"
2135msgstr ""
2136
2137#: src/applications/session/connect.c:728
2138#, c-format
2139msgid ""
2140"Error parsing encrypted session key from `%s', given message part size is "
2141"invalid.\n"
2142msgstr ""
2143
2144#: src/applications/session/connect.c:741
2145#, c-format
2146msgid "Unknown type in embedded message from `%s': %u (size: %u)\n"
2147msgstr ""
2148
2149#: src/applications/session/connect.c:916
2150msgid "# session keys sent"
2151msgstr ""
2152
2153#: src/applications/session/connect.c:918
2154msgid "# session keys rejected"
2155msgstr ""
2156
2157#: src/applications/session/connect.c:920
2158msgid "# session keys accepted"
2159msgstr ""
2160
2161#: src/applications/session/connect.c:922
2162msgid "# sessions established"
2163msgstr ""
2164
2165#: src/applications/fs/tools/gnunet-pseudonym.c:70
2166#: src/applications/fs/tools/gnunet-auto-share.c:199
2167#: src/applications/fs/tools/gnunet-insert.c:246
2168#: src/applications/fs/tools/gnunet-search.c:125
2169#: src/applications/fs/tools/gnunet-download.c:77
2170msgid "set the desired LEVEL of sender-anonymity"
2171msgstr ""
2172
2173#: src/applications/fs/tools/gnunet-pseudonym.c:73
2174msgid "automate creation of a namespace by starting a collection"
2175msgstr ""
2176
2177#: src/applications/fs/tools/gnunet-pseudonym.c:77
2178msgid "create a new pseudonym under the given NICKNAME"
2179msgstr ""
2180
2181#: src/applications/fs/tools/gnunet-pseudonym.c:80
2182msgid "delete the pseudonym with the given NICKNAME"
2183msgstr ""
2184
2185#: src/applications/fs/tools/gnunet-pseudonym.c:83
2186msgid "end automated building of a namespace (ends collection)"
2187msgstr ""
2188
2189#: src/applications/fs/tools/gnunet-pseudonym.c:85
2190msgid "Create new pseudonyms, delete pseudonyms or list existing pseudonyms."
2191msgstr ""
2192
2193#: src/applications/fs/tools/gnunet-pseudonym.c:89
2194msgid ""
2195"use the given keyword to advertise the namespace (use when creating a new "
2196"pseudonym)"
2197msgstr ""
2198
2199#: src/applications/fs/tools/gnunet-pseudonym.c:92
2200msgid "specify metadata describing the namespace or collection"
2201msgstr ""
2202
2203#: src/applications/fs/tools/gnunet-pseudonym.c:96
2204msgid ""
2205"do not generate an advertisement for this namespace (use when creating a new "
2206"pseudonym)"
2207msgstr ""
2208
2209#: src/applications/fs/tools/gnunet-pseudonym.c:99
2210msgid "do not list the pseudonyms from the pseudonym database"
2211msgstr ""
2212
2213#: src/applications/fs/tools/gnunet-pseudonym.c:103
2214msgid ""
2215"specify IDENTIFIER to be the address of the entrypoint to content in the "
2216"namespace (use when creating a new pseudonym)"
2217msgstr ""
2218
2219#: src/applications/fs/tools/gnunet-pseudonym.c:106
2220msgid "set the rating of a namespace"
2221msgstr ""
2222
2223#: src/applications/fs/tools/gnunet-pseudonym.c:141
2224#, c-format
2225msgid "Namespace `%s' has rating %d.\n"
2226msgstr ""
2227
2228#: src/applications/fs/tools/gnunet-pseudonym.c:143
2229#, c-format
2230msgid "Namespace `%s' (%s) has rating %d.\n"
2231msgstr ""
2232
2233#: src/applications/fs/tools/gnunet-pseudonym.c:175
2234#, c-format
2235msgid "\tRating (after update): %d\n"
2236msgstr ""
2237
2238#: src/applications/fs/tools/gnunet-pseudonym.c:179
2239#: src/applications/fs/tools/gnunet-pseudonym.c:241
2240#: src/applications/fs/tools/gnunet-insert.c:101
2241#, c-format
2242msgid "\tUnknown namespace `%s'\n"
2243msgstr ""
2244
2245#: src/applications/fs/tools/gnunet-pseudonym.c:217
2246#, c-format
2247msgid "Collection stopped.\n"
2248msgstr ""
2249
2250#: src/applications/fs/tools/gnunet-pseudonym.c:219
2251#, c-format
2252msgid "Failed to stop collection (not active?).\n"
2253msgstr ""
2254
2255#: src/applications/fs/tools/gnunet-pseudonym.c:230
2256#, c-format
2257msgid "Pseudonym `%s' deleted.\n"
2258msgstr ""
2259
2260#: src/applications/fs/tools/gnunet-pseudonym.c:235
2261#, c-format
2262msgid "Error deleting pseudonym `%s' (does not exist?).\n"
2263msgstr ""
2264
2265#: src/applications/fs/tools/gnunet-pseudonym.c:256
2266msgid "Started collection.\n"
2267msgstr ""
2268
2269#: src/applications/fs/tools/gnunet-pseudonym.c:260
2270msgid "Failed to start collection.\n"
2271msgstr ""
2272
2273#: src/applications/fs/tools/gnunet-pseudonym.c:296
2274msgid "Could not create namespace.\n"
2275msgstr ""
2276
2277#: src/applications/fs/tools/gnunet-pseudonym.c:304
2278#, c-format
2279msgid "Namespace `%s' created (root: %s).\n"
2280msgstr ""
2281
2282#: src/applications/fs/tools/gnunet-pseudonym.c:321
2283#, c-format
2284msgid "You must specify a name for the collection (`%s' option).\n"
2285msgstr ""
2286
2287#: src/applications/fs/tools/gnunet-pseudonym.c:329
2288#, c-format
2289msgid "Could not access namespace information.\n"
2290msgstr ""
2291
2292#: src/applications/fs/tools/gnunet-directory.c:84
2293#, c-format
2294msgid "==> Directory `%s':\n"
2295msgstr ""
2296
2297#: src/applications/fs/tools/gnunet-directory.c:88
2298#, c-format
2299msgid "=\tError reading directory.\n"
2300msgstr ""
2301
2302#: src/applications/fs/tools/gnunet-directory.c:118
2303#, c-format
2304msgid "File format error (not a GNUnet directory?)\n"
2305msgstr ""
2306
2307#: src/applications/fs/tools/gnunet-directory.c:120
2308#, c-format
2309msgid "%d files found in directory.\n"
2310msgstr ""
2311
2312#: src/applications/fs/tools/gnunet-directory.c:135
2313msgid "Perform directory related operations."
2314msgstr ""
2315
2316#: src/applications/fs/tools/gnunet-directory.c:138
2317msgid "remove all entries from the directory database and stop tracking URIs"
2318msgstr ""
2319
2320#: src/applications/fs/tools/gnunet-directory.c:142
2321msgid "list entries from the directory database"
2322msgstr ""
2323
2324#: src/applications/fs/tools/gnunet-directory.c:145
2325msgid "start tracking entries for the directory database"
2326msgstr ""
2327
2328#: src/applications/fs/tools/gnunet-directory.c:168
2329#, c-format
2330msgid "Listed %d matching entries.\n"
2331msgstr ""
2332
2333#: src/applications/fs/tools/gnunet-auto-share.c:117
2334#, c-format
2335msgid "Upload of `%s' at %llu out of %llu bytes.\n"
2336msgstr ""
2337
2338#: src/applications/fs/tools/gnunet-auto-share.c:130
2339#, c-format
2340msgid "Upload of `%s' complete, URI is `%s'.\n"
2341msgstr ""
2342
2343#: src/applications/fs/tools/gnunet-auto-share.c:139
2344#, c-format
2345msgid "Upload aborted.\n"
2346msgstr ""
2347
2348#: src/applications/fs/tools/gnunet-auto-share.c:145
2349#, c-format
2350msgid "Error uploading file: %s\n"
2351msgstr ""
2352
2353#: src/applications/fs/tools/gnunet-auto-share.c:154
2354#, c-format
2355msgid "Starting upload of `%s'.\n"
2356msgstr ""
2357
2358#: src/applications/fs/tools/gnunet-auto-share.c:164
2359#, c-format
2360msgid "Uploading suspended.\n"
2361msgstr ""
2362
2363#: src/applications/fs/tools/gnunet-auto-share.c:179
2364#, c-format
2365msgid "Uploading `%s' resumed.\n"
2366msgstr ""
2367
2368#: src/applications/fs/tools/gnunet-auto-share.c:186
2369#, c-format
2370msgid "Unexpected event: %d\n"
2371msgstr ""
2372
2373#: src/applications/fs/tools/gnunet-auto-share.c:205
2374msgid ""
2375"run in debug mode; gnunet-auto-share will not daemonize and error messages "
2376"will be written to stderr instead of a logfile"
2377msgstr ""
2378
2379#: src/applications/fs/tools/gnunet-auto-share.c:211
2380#: src/applications/fs/tools/gnunet-insert.c:259
2381msgid ""
2382"do not use libextractor to add additional references to directory entries "
2383"and/or the published file"
2384msgstr ""
2385
2386#: src/applications/fs/tools/gnunet-auto-share.c:213
2387msgid "Automatically share a directory."
2388msgstr ""
2389
2390#: src/applications/fs/tools/gnunet-auto-share.c:216
2391#: src/applications/fs/tools/gnunet-insert.c:273
2392msgid ""
2393"add an additional keyword for all files and directories (this option can be "
2394"specified multiple times)"
2395msgstr ""
2396
2397#: src/applications/fs/tools/gnunet-auto-share.c:221
2398#: src/applications/fs/tools/gnunet-insert.c:290
2399msgid "specify the priority of the content"
2400msgstr ""
2401
2402#: src/applications/fs/tools/gnunet-auto-share.c:468
2403#: src/applications/fs/tools/gnunet-auto-share.c:903
2404#, c-format
2405msgid "Could not access `%s': %s\n"
2406msgstr ""
2407
2408#: src/applications/fs/tools/gnunet-auto-share.c:547
2409#, c-format
2410msgid "Unknown keyword type `%s' in metadata configuration\n"
2411msgstr ""
2412
2413#: src/applications/fs/tools/gnunet-auto-share.c:652
2414#, c-format
2415msgid "Failed to stop running gnunet-auto-share.\n"
2416msgstr ""
2417
2418#: src/applications/fs/tools/gnunet-auto-share.c:918
2419#, c-format
2420msgid "Directory `%s' is already on the list of shared directories.\n"
2421msgstr ""
2422
2423#: src/applications/fs/tools/gnunet-auto-share.c:939
2424msgid ""
2425"The specified directories were added to the list of shared directories.\n"
2426msgstr ""
2427
2428#: src/applications/fs/tools/gnunet-auto-share.c:961
2429#, c-format
2430msgid "Could not open logfile `%s': %s\n"
2431msgstr ""
2432
2433#: src/applications/fs/tools/gnunet-insert.c:115
2434#, c-format
2435msgid "Created entry `%s' in namespace `%s'\n"
2436msgstr ""
2437
2438#: src/applications/fs/tools/gnunet-insert.c:120
2439#, c-format
2440msgid "Failed to add entry to namespace `%s' (does it exist?)\n"
2441msgstr ""
2442
2443#: src/applications/fs/tools/gnunet-insert.c:135
2444#, c-format
2445msgid "Keywords for file `%s':\n"
2446msgstr ""
2447
2448#: src/applications/fs/tools/gnunet-insert.c:144
2449msgid "filename"
2450msgstr ""
2451
2452#: src/applications/fs/tools/gnunet-insert.c:146
2453msgid "mimetype"
2454msgstr ""
2455
2456#: src/applications/fs/tools/gnunet-insert.c:186
2457#, c-format
2458msgid "%16llu of %16llu bytes inserted (estimating %6s to completion) - %s\n"
2459msgstr ""
2460
2461#: src/applications/fs/tools/gnunet-insert.c:198
2462#, c-format
2463msgid "Upload of `%s' complete, %llu bytes took %llu seconds (%8.3f KiB/s).\n"
2464msgstr ""
2465
2466#: src/applications/fs/tools/gnunet-insert.c:209
2467#, c-format
2468msgid "File `%s' has URI: %s\n"
2469msgstr ""
2470
2471#: src/applications/fs/tools/gnunet-insert.c:220
2472#, c-format
2473msgid ""
2474"\n"
2475"Upload aborted.\n"
2476msgstr ""
2477
2478#: src/applications/fs/tools/gnunet-insert.c:225
2479#, c-format
2480msgid ""
2481"\n"
2482"Error uploading file: %s"
2483msgstr ""
2484
2485#: src/applications/fs/tools/gnunet-insert.c:234
2486#, c-format
2487msgid ""
2488"\n"
2489"Unexpected event: %d\n"
2490msgstr ""
2491
2492#: src/applications/fs/tools/gnunet-insert.c:250
2493msgid ""
2494"even if gnunetd is running on the local machine, force the creation of a "
2495"copy instead of making a link to the GNUnet share directory"
2496msgstr ""
2497
2498#: src/applications/fs/tools/gnunet-insert.c:255
2499msgid "disable adding the creation time to the metadata of the uploaded file"
2500msgstr ""
2501
2502#: src/applications/fs/tools/gnunet-insert.c:263
2503msgid ""
2504"print list of extracted keywords that would be used, but do not perform "
2505"upload"
2506msgstr ""
2507
2508#: src/applications/fs/tools/gnunet-insert.c:265
2509msgid "Make files available to GNUnet for sharing."
2510msgstr ""
2511
2512#: src/applications/fs/tools/gnunet-insert.c:269
2513msgid ""
2514"add an additional keyword for the top-level file or directory (this option "
2515"can be specified multiple times)"
2516msgstr ""
2517
2518#: src/applications/fs/tools/gnunet-insert.c:278
2519msgid "set the meta-data for the given TYPE to the given VALUE"
2520msgstr ""
2521
2522#: src/applications/fs/tools/gnunet-insert.c:281
2523msgid ""
2524"do not index, perform full insertion (stores entire file in encrypted form "
2525"in GNUnet database)"
2526msgstr ""
2527
2528#: src/applications/fs/tools/gnunet-insert.c:286
2529msgid ""
2530"specify ID of an updated version to be published in the future (for "
2531"namespace insertions only)"
2532msgstr ""
2533
2534#: src/applications/fs/tools/gnunet-insert.c:294
2535msgid "publish the files under the pseudonym NAME (place file into namespace)"
2536msgstr ""
2537
2538#: src/applications/fs/tools/gnunet-insert.c:297
2539msgid ""
2540"only simulte the process but do not do any actual publishing (useful to "
2541"compute URIs)"
2542msgstr ""
2543
2544#: src/applications/fs/tools/gnunet-insert.c:301
2545msgid ""
2546"set the ID of this version of the publication (for namespace insertions only)"
2547msgstr ""
2548
2549#: src/applications/fs/tools/gnunet-insert.c:305
2550msgid ""
2551"URI to be published (can be used instead of passing a file to add keywords "
2552"to the file with the respective URI)"
2553msgstr ""
2554
2555#: src/applications/fs/tools/gnunet-insert.c:342
2556#, c-format
2557msgid "You must specify one and only one filename for insertion.\n"
2558msgstr ""
2559
2560#: src/applications/fs/tools/gnunet-insert.c:348
2561#, c-format
2562msgid "You must NOT specify an URI and a filename.\n"
2563msgstr ""
2564
2565#: src/applications/fs/tools/gnunet-insert.c:354
2566#, c-format
2567msgid "Cannot extract metadata from a URI!\n"
2568msgstr ""
2569
2570#: src/applications/fs/tools/gnunet-insert.c:400
2571#, c-format
2572msgid "Could not access namespace `%s' (does not exist?).\n"
2573msgstr ""
2574
2575#: src/applications/fs/tools/gnunet-insert.c:408
2576#, c-format
2577msgid "Option `%s' is required when using option `%s'.\n"
2578msgstr ""
2579
2580#: src/applications/fs/tools/gnunet-insert.c:419
2581#: src/applications/fs/tools/gnunet-insert.c:427
2582#, c-format
2583msgid "Option `%s' makes no sense without option `%s'.\n"
2584msgstr ""
2585
2586#: src/applications/fs/tools/gnunet-search.c:128
2587msgid "Search GNUnet for files."
2588msgstr ""
2589
2590#: src/applications/fs/tools/gnunet-search.c:132
2591msgid "write encountered (decrypted) search results to FILENAME"
2592msgstr ""
2593
2594#: src/applications/fs/tools/gnunet-search.c:169
2595#, c-format
2596msgid "Error converting arguments to URI!\n"
2597msgstr ""
2598
2599#: src/applications/fs/tools/gnunet-unindex.c:61
2600#, c-format
2601msgid ""
2602"%16llu of %16llu bytes unindexed (estimating %llu seconds to "
2603"completion) "
2604msgstr ""
2605
2606#: src/applications/fs/tools/gnunet-unindex.c:73
2607#, c-format
2608msgid ""
2609"\n"
2610"Unindexing of `%s' complete, %llu bytes took %llu seconds (%8.3f KiB/s).\n"
2611msgstr ""
2612
2613#: src/applications/fs/tools/gnunet-unindex.c:88
2614#, c-format
2615msgid ""
2616"\n"
2617"Error unindexing file: %s\n"
2618msgstr ""
2619
2620#: src/applications/fs/tools/gnunet-unindex.c:108
2621msgid "Unindex files."
2622msgstr ""
2623
2624#: src/applications/fs/tools/gnunet-unindex.c:145
2625msgid "Not enough arguments. You must specify a filename.\n"
2626msgstr ""
2627
2628#: src/applications/fs/tools/gnunet-unindex.c:163
2629#, c-format
2630msgid "`%s' failed. Is `%s' a file?\n"
2631msgstr ""
2632
2633#: src/applications/fs/tools/gnunet-download.c:82
2634msgid ""
2635"download a GNUnet directory that has already been downloaded. Requires that "
2636"a filename of an existing file is specified instead of the URI. The "
2637"download will only download the top-level files in the directory unless the "
2638"`-R' option is also specified."
2639msgstr ""
2640
2641#: src/applications/fs/tools/gnunet-download.c:85
2642msgid "delete incomplete downloads (when aborted with CTRL-C)"
2643msgstr ""
2644
2645#: src/applications/fs/tools/gnunet-download.c:87
2646msgid "Download files from GNUnet."
2647msgstr ""
2648
2649#: src/applications/fs/tools/gnunet-download.c:91
2650msgid "write the file to FILENAME"
2651msgstr ""
2652
2653#: src/applications/fs/tools/gnunet-download.c:95
2654msgid "set the maximum number of parallel downloads that are allowed"
2655msgstr ""
2656
2657#: src/applications/fs/tools/gnunet-download.c:98
2658msgid "download a GNUnet directory recursively"
2659msgstr ""
2660
2661#: src/applications/fs/tools/gnunet-download.c:119
2662#, c-format
2663msgid "Download of file `%s' at %16llu out of %16llu bytes (%8.3f KiB/s)\n"
2664msgstr ""
2665
2666#: src/applications/fs/tools/gnunet-download.c:133
2667#, c-format
2668msgid "Download aborted.\n"
2669msgstr ""
2670
2671#: src/applications/fs/tools/gnunet-download.c:139
2672#, c-format
2673msgid "Error downloading: %s\n"
2674msgstr ""
2675
2676#: src/applications/fs/tools/gnunet-download.c:145
2677#, c-format
2678msgid "Download of file `%s' complete. Speed was %8.3f KiB per second.\n"
2679msgstr ""
2680
2681#: src/applications/fs/tools/gnunet-download.c:191
2682msgid "no name given"
2683msgstr ""
2684
2685#: src/applications/fs/tools/gnunet-download.c:197
2686#, c-format
2687msgid "Starting download `%s'\n"
2688msgstr ""
2689
2690#: src/applications/fs/tools/gnunet-download.c:239
2691msgid "Not enough arguments. You must specify a GNUnet file URI\n"
2692msgstr ""
2693
2694#: src/applications/fs/tools/gnunet-download.c:257
2695#, c-format
2696msgid "URI `%s' invalid for gnunet-download.\n"
2697msgstr ""
2698
2699#: src/applications/fs/tools/gnunet-download.c:300
2700#, c-format
2701msgid "No filename specified, using `%s' instead (for now).\n"
2702msgstr ""
2703
2704#: src/applications/fs/tools/gnunet-download.c:342
2705#, c-format
2706msgid "Could not access gnunet-directory file `%s'\n"
2707msgstr ""
2708
2709#: src/applications/fs/tools/gnunet-download.c:363
2710#, c-format
2711msgid "Downloading %d files from directory `%s'.\n"
2712msgstr ""
2713
2714#: src/applications/fs/tools/gnunet-download.c:366
2715#, c-format
2716msgid "Did not find any files in directory `%s'\n"
2717msgstr ""
2718
2719#: src/applications/fs/tools/gnunet-download.c:404
2720#, c-format
2721msgid "File stored as `%s'.\n"
2722msgstr ""
2723
2724#: src/applications/fs/uritrack/file_info.c:98
2725msgid "Collecting file identifiers disabled.\n"
2726msgstr ""
2727
2728#: src/applications/fs/uritrack/file_info.c:377
2729#, c-format
2730msgid "Deleted corrupt URI database in `%s'."
2731msgstr ""
2732
2733#: src/applications/fs/ecrs/upload.c:158
2734#, c-format
2735msgid "`%s' is not a file.\n"
2736msgstr ""
2737
2738#: src/applications/fs/ecrs/upload.c:166
2739#, c-format
2740msgid "Cannot get size of file `%s'"
2741msgstr ""
2742
2743#: src/applications/fs/ecrs/upload.c:175
2744msgid "Failed to connect to gnunetd."
2745msgstr ""
2746
2747#: src/applications/fs/ecrs/upload.c:187
2748#, c-format
2749msgid "Cannot hash `%s'.\n"
2750msgstr ""
2751
2752#: src/applications/fs/ecrs/upload.c:215
2753#, c-format
2754msgid "Initialization for indexing file `%s' failed.\n"
2755msgstr ""
2756
2757#: src/applications/fs/ecrs/upload.c:223
2758#, c-format
2759msgid "Indexing file `%s' failed. Suggestion: try to insert the file.\n"
2760msgstr ""
2761
2762#: src/applications/fs/ecrs/upload.c:237
2763#, c-format
2764msgid "Cannot open file `%s': `%s'"
2765msgstr ""
2766
2767#: src/applications/fs/ecrs/upload.c:322
2768#, c-format
2769msgid "Indexing data of file `%s' failed at position %llu.\n"
2770msgstr ""
2771
2772#: src/applications/fs/ecrs/helper.c:91
2773msgid "No keywords specified!\n"
2774msgstr ""
2775
2776#: src/applications/fs/ecrs/helper.c:99
2777msgid "Number of double-quotes not balanced!\n"
2778msgstr ""
2779
2780#: src/applications/fs/ecrs/helper.c:398
2781#, c-format
2782msgid "Renaming of file `%s' to `%s' failed: %s\n"
2783msgstr ""
2784
2785#: src/applications/fs/ecrs/helper.c:408
2786#, c-format
2787msgid "Could not rename file `%s' to `%s': file exists\n"
2788msgstr ""
2789
2790#: src/applications/fs/ecrs/parser.c:165
2791#, c-format
2792msgid ""
2793"Unknown metadata type in metadata option `%s'. Using metadata type "
2794"`unknown' instead.\n"
2795msgstr ""
2796
2797#: src/applications/fs/ecrs/search.c:152
2798msgid "CHK URI not allowed for search.\n"
2799msgstr ""
2800
2801#: src/applications/fs/ecrs/search.c:207
2802msgid "LOC URI not allowed for search.\n"
2803msgstr ""
2804
2805#: src/applications/fs/ecrs/namespace.c:365
2806#, c-format
2807msgid "File `%s' does not contain a pseudonym.\n"
2808msgstr ""
2809
2810#: src/applications/fs/ecrs/namespace.c:376
2811#, c-format
2812msgid "Format of pseudonym `%s' is invalid.\n"
2813msgstr ""
2814
2815#: src/applications/fs/ecrs/namespace.c:535
2816#: src/applications/fs/ecrs/namespace.c:547
2817#: src/applications/fs/ecrs/namespace.c:559
2818#, c-format
2819msgid "Format of file `%s' is invalid, trying to remove.\n"
2820msgstr ""
2821
2822#: src/applications/fs/ecrs/download.c:599
2823msgid ""
2824"Decrypted content does not match key. This is either a bug or a maliciously "
2825"inserted file. Download aborted.\n"
2826msgstr ""
2827
2828#: src/applications/fs/ecrs/download.c:609
2829msgid "IO error."
2830msgstr ""
2831
2832#: src/applications/fs/collection/collection.c:559
2833#: src/applications/fs/collection/collection.c:562
2834#, c-format
2835msgid "Revision %u"
2836msgstr ""
2837
2838#: src/applications/fs/fsui/upload.c:330
2839msgid "Application aborted."
2840msgstr ""
2841
2842#: src/applications/fs/fsui/upload.c:344
2843msgid "Failed to create temporary directory."
2844msgstr ""
2845
2846#: src/applications/fs/fsui/deserialize.c:927
2847#, c-format
2848msgid "FSUI state file `%s' had syntax error at offset %u.\n"
2849msgstr ""
2850
2851#: src/applications/fs/fsui/unindex.c:114
2852msgid "Unindexing failed (no reason given)"
2853msgstr ""
2854
2855#: src/applications/fs/gap/plan.c:944
2856msgid "# gap requests total sent"
2857msgstr ""
2858
2859#: src/applications/fs/gap/plan.c:946
2860msgid "# gap content total planned"
2861msgstr ""
2862
2863#: src/applications/fs/gap/plan.c:948
2864msgid "# gap routes succeeded"
2865msgstr ""
2866
2867#: src/applications/fs/gap/plan.c:949
2868msgid "# trust spent"
2869msgstr ""
2870
2871#: src/applications/fs/gap/fs.c:157
2872msgid "Datastore full.\n"
2873msgstr ""
2874
2875#: src/applications/fs/gap/fs.c:831
2876msgid "# gap requests total received"
2877msgstr ""
2878
2879#: src/applications/fs/gap/fs.c:833
2880msgid "# gap requests dropped due to load"
2881msgstr ""
2882
2883#: src/applications/fs/gap/fs.c:835
2884msgid "# gap content total received"
2885msgstr ""
2886
2887#: src/applications/fs/gap/fs.c:837
2888msgid "# gap total trust awarded"
2889msgstr ""
2890
2891#: src/applications/fs/gap/fs.c:865
2892#, c-format
2893msgid ""
2894"`%s' registering client handlers %d %d %d %d %d %d %d %d and P2P handlers %d "
2895"%d\n"
2896msgstr ""
2897
2898#: src/applications/fs/gap/fs.c:921
2899msgid "enables (anonymous) file-sharing"
2900msgstr ""
2901
2902#: src/applications/fs/gap/ondemand.c:173
2903#, c-format
2904msgid ""
2905"Because the file `%s' has been unavailable for 3 days it got removed from "
2906"your share. Please unindex files before deleting them as the index now "
2907"contains invalid references!\n"
2908msgstr ""
2909
2910#: src/applications/fs/gap/ondemand.c:451
2911msgid "Indexed content changed (does not match its hash).\n"
2912msgstr ""
2913
2914#: src/applications/fs/gap/ondemand.c:569
2915#, c-format
2916msgid ""
2917"Unindexed ODB block `%s' from offset %llu already missing from datastore.\n"
2918msgstr ""
2919
2920#: src/applications/fs/gap/pid_table.c:177
2921msgid "# distinct interned peer IDs in pid table"
2922msgstr ""
2923
2924#: src/applications/fs/gap/pid_table.c:180
2925msgid "# total RC of interned peer IDs in pid table"
2926msgstr ""
2927
2928#: src/applications/fs/gap/querymanager.c:708
2929msgid "# gap client queries received"
2930msgstr ""
2931
2932#: src/applications/fs/gap/querymanager.c:710
2933msgid "# gap replies sent to clients"
2934msgstr ""
2935
2936#: src/applications/fs/gap/querymanager.c:712
2937msgid "# gap client requests tracked"
2938msgstr ""
2939
2940#: src/applications/fs/gap/querymanager.c:714
2941msgid "# gap client requests injected"
2942msgstr ""
2943
2944#: src/applications/fs/gap/querymanager.c:717
2945msgid "# gap query bloomfilter resizing updates"
2946msgstr ""
2947
2948#: src/applications/fs/gap/migration.c:437
2949msgid "# blocks migrated"
2950msgstr ""
2951
2952#: src/applications/fs/gap/migration.c:439
2953msgid "# blocks injected for migration"
2954msgstr ""
2955
2956#: src/applications/fs/gap/migration.c:441
2957msgid "# blocks fetched for migration"
2958msgstr ""
2959
2960#: src/applications/fs/gap/migration.c:443
2961msgid "# on-demand fetches for migration"
2962msgstr ""
2963
2964#: src/applications/fs/gap/gap.c:694
2965msgid "# gap queries dropped (table full)"
2966msgstr ""
2967
2968#: src/applications/fs/gap/gap.c:696
2969msgid "# gap queries dropped (redundant)"
2970msgstr ""
2971
2972#: src/applications/fs/gap/gap.c:698
2973msgid "# gap queries routed"
2974msgstr ""
2975
2976#: src/applications/fs/gap/gap.c:700
2977msgid "# gap content found locally"
2978msgstr ""
2979
2980#: src/applications/fs/gap/gap.c:703
2981msgid "# gap queries refreshed existing record"
2982msgstr ""
2983
2984#: src/applications/fs/gap/gap.c:704
2985msgid "# trust earned"
2986msgstr ""
2987
2988#: src/applications/fs/gap/fs_dht.c:256
2989msgid "# blocks pushed into DHT"
2990msgstr ""
2991
2992#: src/applications/fs/gap/anonymity.c:56
2993msgid "Failed to get traffic stats.\n"
2994msgstr ""
2995
2996#: src/applications/testing/remote.c:68
2997#, c-format
2998msgid "scp command is : %s \n"
2999msgstr ""
3000
3001#: src/applications/testing/remote.c:491
3002#, c-format
3003msgid "Friend list of %s:%d\n"
3004msgstr ""
3005
3006#: src/applications/testing/remote.c:513
3007#, c-format
3008msgid "scp command for friend file copy is : %s \n"
3009msgstr ""
3010
3011#: src/applications/testing/remote.c:535
3012#, c-format
3013msgid "connecting peer %s:%d to peer %s:%d\n"
3014msgstr ""
3015
3016#: src/applications/testing/remotetest.c:38
3017msgid "Set up multiple gnunetd daemons across multiple hosts."
3018msgstr ""
3019
3020#: src/applications/testing/remotetest.c:43
3021msgid "set number of daemons to start"
3022msgstr ""
3023
3024#: src/applications/testing/testing.c:268
3025#: src/applications/testing/remotetopologies.c:367
3026#, c-format
3027msgid "Waiting for peers to connect"
3028msgstr ""
3029
3030#: src/applications/testing/remotetopologies.c:213
3031#, c-format
3032msgid "Connecting nodes in 2d torus topology: %u rows %u columns\n"
3033msgstr ""
3034
3035#: src/applications/testing/remotetopologies.c:491
3036#, c-format
3037msgid "Failed to establish connection with peers.\n"
3038msgstr ""
3039
3040#: src/applications/bootstrap_http/http.c:113
3041#, c-format
3042msgid "Bootstrap data obtained from `%s' is invalid.\n"
3043msgstr ""
3044
3045#: src/applications/bootstrap_http/http.c:126
3046#: src/applications/bootstrap_http/http.c:277
3047#: src/applications/bootstrap_http/http.c:294
3048#: src/applications/bootstrap_http/http.c:333
3049#: src/applications/bootstrap_http/http.c:352
3050#: src/applications/bootstrap_http/http.c:365
3051#: src/applications/bootstrap_http/http.c:375
3052#: src/applications/bootstrap_http/http.c:385 src/transports/upnp/upnp.c:356
3053#: src/transports/upnp/upnp.c:541 src/transports/http.c:1085
3054#: src/transports/http.c:1209 src/transports/http.c:1377
3055#: src/transports/http.c:1777 src/transports/http.c:1827
3056#, c-format
3057msgid "%s failed at %s:%d: `%s'\n"
3058msgstr ""
3059
3060#: src/applications/bootstrap_http/http.c:185
3061msgid "No hostlist URL specified in configuration, will not bootstrap.\n"
3062msgstr ""
3063
3064#: src/applications/bootstrap_http/http.c:226
3065#, c-format
3066msgid "Bootstrapping using `%s'.\n"
3067msgstr ""
3068
3069#: src/applications/bootstrap_http/http.c:254
3070#, c-format
3071msgid "Trying to download hostlist from `%s'\n"
3072msgstr ""
3073
3074#: src/applications/bootstrap_http/http.c:391
3075#, c-format
3076msgid "Downloaded %llu bytes from `%s'.\n"
3077msgstr ""
3078
3079#: src/applications/bootstrap_http/http.c:425
3080msgid "# HELLOs downloaded via http"
3081msgstr ""
3082
3083#: src/applications/getoption/getoption.c:78
3084#, c-format
3085msgid "`%s' registering client handler %d\n"
3086msgstr ""
3087
3088#: src/applications/getoption/getoption.c:88
3089msgid "allows clients to determine gnunetd's configuration"
3090msgstr ""
3091
3092#: src/applications/template/template.c:70
3093#, c-format
3094msgid "`%s' registering client handler %d and %d\n"
3095msgstr ""
3096
3097#: src/applications/template/gnunet-template.c:42
3098msgid "Template description."
3099msgstr ""
3100
3101#: src/applications/stats/clientapi.c:331
3102msgid "Uptime (seconds)"
3103msgstr ""
3104
3105#: src/applications/stats/sqstats.c:151
3106msgid "# Any-Blocks"
3107msgstr ""
3108
3109#: src/applications/stats/sqstats.c:152
3110msgid "# DBlocks"
3111msgstr ""
3112
3113#: src/applications/stats/sqstats.c:153
3114msgid "# SBlocks"
3115msgstr ""
3116
3117#: src/applications/stats/sqstats.c:154
3118msgid "# KBlocks"
3119msgstr ""
3120
3121#: src/applications/stats/sqstats.c:155
3122msgid "# NBlocks"
3123msgstr ""
3124
3125#: src/applications/stats/sqstats.c:156
3126msgid "# KNBlocks"
3127msgstr ""
3128
3129#: src/applications/stats/sqstats.c:157
3130msgid "# OnDemand-Blocks"
3131msgstr ""
3132
3133#: src/applications/stats/sqstats.c:158
3134msgid "# Unknown-Blocks"
3135msgstr ""
3136
3137#: src/applications/stats/sqstats.c:159
3138msgid "# expired"
3139msgstr ""
3140
3141#: src/applications/stats/sqstats.c:160
3142msgid "# expire in 1h"
3143msgstr ""
3144
3145#: src/applications/stats/sqstats.c:161
3146msgid "# expire in 24h"
3147msgstr ""
3148
3149#: src/applications/stats/sqstats.c:162
3150msgid "# expire in 1 week"
3151msgstr ""
3152
3153#: src/applications/stats/sqstats.c:163
3154msgid "# expire in 1 month"
3155msgstr ""
3156
3157#: src/applications/stats/sqstats.c:164
3158msgid "# zero priority"
3159msgstr ""
3160
3161#: src/applications/stats/sqstats.c:165
3162msgid "# priority one"
3163msgstr ""
3164
3165#: src/applications/stats/sqstats.c:166
3166msgid "# priority larger than one"
3167msgstr ""
3168
3169#: src/applications/stats/sqstats.c:167
3170msgid "# no anonymity"
3171msgstr ""
3172
3173#: src/applications/stats/sqstats.c:168
3174msgid "# anonymity one"
3175msgstr ""
3176
3177#: src/applications/stats/sqstats.c:169
3178msgid "# anonymity larger than one"
3179msgstr ""
3180
3181#: src/applications/stats/statistics.c:238
3182#, no-c-format
3183msgid "% of allowed network load (up)"
3184msgstr ""
3185
3186#: src/applications/stats/statistics.c:240
3187#, no-c-format
3188msgid "% of allowed network load (down)"
3189msgstr ""
3190
3191#: src/applications/stats/statistics.c:243
3192#, no-c-format
3193msgid "% of allowed cpu load"
3194msgstr ""
3195
3196#: src/applications/stats/statistics.c:246
3197#, no-c-format
3198msgid "% of allowed io load"
3199msgstr ""
3200
3201#: src/applications/stats/statistics.c:249
3202msgid "# bytes of noise received"
3203msgstr ""
3204
3205#: src/applications/stats/statistics.c:251
3206msgid "# plibc handles"
3207msgstr ""
3208
3209#: src/applications/stats/statistics.c:441
3210#, c-format
3211msgid "`%s' registering client handlers %d %d %d and p2p handler %d\n"
3212msgstr ""
3213
3214#: src/applications/stats/statistics.c:463
3215msgid "keeps statistics about gnunetd's operation"
3216msgstr ""
3217
3218#: src/applications/stats/gnunet-stats.c:61
3219#, c-format
3220msgid "Supported peer-to-peer messages:\n"
3221msgstr ""
3222
3223#: src/applications/stats/gnunet-stats.c:64
3224#, c-format
3225msgid "Supported client-server messages:\n"
3226msgstr ""
3227
3228#: src/applications/stats/gnunet-stats.c:83
3229#: src/applications/vpn/gnunet-vpn.c:59
3230msgid "Print statistics about GNUnet operations."
3231msgstr ""
3232
3233#: src/applications/stats/gnunet-stats.c:87
3234msgid "prints supported protocol messages"
3235msgstr ""
3236
3237#: src/applications/stats/gnunet-stats.c:136
3238#, c-format
3239msgid "Error reading information from gnunetd.\n"
3240msgstr ""
3241
3242#: src/applications/vpn/gnunet-vpn.c:63
3243msgid "Suppress display of asynchronous log messages"
3244msgstr ""
3245
3246#: src/applications/vpn/p2p.c:75
3247msgid "VPN IP src not anonymous. drop..\n"
3248msgstr ""
3249
3250#: src/applications/vpn/p2p.c:83
3251msgid "VPN IP not anonymous, drop.\n"
3252msgstr ""
3253
3254#: src/applications/vpn/p2p.c:92
3255msgid "VPN Received, not anonymous, drop.\n"
3256msgstr ""
3257
3258#: src/applications/vpn/p2p.c:97
3259#, c-format
3260msgid "VPN Received unknown IP version %d...\n"
3261msgstr ""
3262
3263#: src/applications/vpn/p2p.c:110
3264#, c-format
3265msgid "<- GNUnet(%d) : %s\n"
3266msgstr ""
3267
3268#: src/applications/vpn/p2p.c:139
3269msgid "Could not write the tunnelled IP to the OS... Did to setup a tunnel?\n"
3270msgstr ""
3271
3272#: src/applications/vpn/p2p.c:183
3273msgid "Receive route request\n"
3274msgstr ""
3275
3276#: src/applications/vpn/p2p.c:193
3277#, c-format
3278msgid "Prepare route announcement level %d\n"
3279msgstr ""
3280
3281#: src/applications/vpn/p2p.c:208
3282#, c-format
3283msgid "Send route announcement %d with route announce\n"
3284msgstr ""
3285
3286#: src/applications/vpn/p2p.c:217
3287#, c-format
3288msgid "Send outside table info %d\n"
3289msgstr ""
3290
3291#: src/applications/vpn/p2p.c:239
3292msgid "Receive route announce.\n"
3293msgstr ""
3294
3295#: src/applications/vpn/p2p.c:247
3296msgid "Going to try insert route into local table.\n"
3297msgstr ""
3298
3299#: src/applications/vpn/p2p.c:256
3300#, c-format
3301msgid "Inserting with hops %d\n"
3302msgstr ""
3303
3304#: src/applications/vpn/p2p.c:273
3305#, c-format
3306msgid "Request level %d from peer %d\n"
3307msgstr ""
3308
3309#: src/applications/vpn/p2p.c:300
3310#, c-format
3311msgid "Receive table limit on peer reached %d\n"
3312msgstr ""
3313
3314#: src/applications/vpn/vpn.c:180
3315#, c-format
3316msgid "Not storing route to myself from peer %d\n"
3317msgstr ""
3318
3319#: src/applications/vpn/vpn.c:194
3320#, c-format
3321msgid "Duplicate route to node from peer %d, choosing minimum hops"
3322msgstr ""
3323
3324#: src/applications/vpn/vpn.c:230
3325#, c-format
3326msgid "Inserting route from peer %d in route table at location %d\n"
3327msgstr ""
3328
3329#: src/applications/vpn/vpn.c:247
3330#, c-format
3331msgid "RFC4193 Frame length %d is too big for GNUnet!\n"
3332msgstr ""
3333
3334#: src/applications/vpn/vpn.c:254
3335#, c-format
3336msgid "RFC4193 Frame length %d too small\n"
3337msgstr ""
3338
3339#: src/applications/vpn/vpn.c:273
3340#, c-format
3341msgid "RFC4193 Ethertype %x and IP version %x do not match!\n"
3342msgstr ""
3343
3344#: src/applications/vpn/vpn.c:289
3345#, c-format
3346msgid "RFC4193 Going to try and make a tunnel in slot %d\n"
3347msgstr ""
3348
3349#: src/applications/vpn/vpn.c:295
3350#, c-format
3351msgid "Cannot open tunnel device: %s"
3352msgstr ""
3353
3354#: src/applications/vpn/vpn.c:331
3355#, c-format
3356msgid "RFC4193 Create skips gnu%d as we are already using it\n"
3357msgstr ""
3358
3359#: src/applications/vpn/vpn.c:346
3360#, c-format
3361msgid "Cannot set tunnel name to %s because of %s\n"
3362msgstr ""
3363
3364#: src/applications/vpn/vpn.c:356
3365#, c-format
3366msgid "Configured tunnel name to %s\n"
3367msgstr ""
3368
3369#: src/applications/vpn/vpn.c:398
3370#, c-format
3371msgid "Cannot get socket flags for gnu%d because %s\n"
3372msgstr ""
3373
3374#: src/applications/vpn/vpn.c:408
3375#, c-format
3376msgid "Cannot set socket flags for gnu%d because %s\n"
3377msgstr ""
3378
3379#: src/applications/vpn/vpn.c:418
3380#, c-format
3381msgid "Cannot set MTU for gnu%d because %s\n"
3382msgstr ""
3383
3384#: src/applications/vpn/vpn.c:426
3385#, c-format
3386msgid "Cannot get interface index for gnu%d because %s\n"
3387msgstr ""
3388
3389#: src/applications/vpn/vpn.c:440
3390#, c-format
3391msgid "IPv6 ifaddr gnu%d - %x:%x:%x:%x:%x:%x:%x:%x/%d\n"
3392msgstr ""
3393
3394#: src/applications/vpn/vpn.c:455
3395#, c-format
3396msgid "Cannot set interface IPv6 address for gnu%d because %s\n"
3397msgstr ""
3398
3399#: src/applications/vpn/vpn.c:471
3400#, c-format
3401msgid "IPv6 route gnu%d - destination %x:%x:%x:%x:%x:%x:%x:%x/%d\n"
3402msgstr ""
3403
3404#: src/applications/vpn/vpn.c:485
3405#, c-format
3406msgid "Cannot add route IPv6 address for gnu%s because %s\n"
3407msgstr ""
3408
3409#: src/applications/vpn/vpn.c:528
3410msgid ""
3411"RFC4193 We have run out of memory and so I can't store a tunnel for this "
3412"peer.\n"
3413msgstr ""
3414
3415#: src/applications/vpn/vpn.c:579
3416#, c-format
3417msgid "RFC4193 Thread running (frame %d tunnel %d f2f %d) ...\n"
3418msgstr ""
3419
3420#: src/applications/vpn/vpn.c:661
3421#, c-format
3422msgid "VPN dropping connection %x\n"
3423msgstr ""
3424
3425#: src/applications/vpn/vpn.c:670
3426#, c-format
3427msgid "VPN cannot drop connection %x\n"
3428msgstr ""
3429
3430#: src/applications/vpn/vpn.c:690
3431msgid "RFC4193 Thread exiting\n"
3432msgstr ""
3433
3434#: src/applications/vpn/vpn.c:712
3435msgid "realise alloc ram\n"
3436msgstr ""
3437
3438#: src/applications/vpn/vpn.c:735
3439msgid "realise add routes\n"
3440msgstr ""
3441
3442#: src/applications/vpn/vpn.c:849
3443msgid "realise copy table\n"
3444msgstr ""
3445
3446#: src/applications/vpn/vpn.c:898
3447#, c-format
3448msgid "`%s' initialising RFC4913 module %d and %d\n"
3449msgstr ""
3450
3451#: src/applications/vpn/vpn.c:903
3452#, c-format
3453msgid "RFC4193 my First 4 hex digits of host id are %x\n"
3454msgstr ""
3455
3456#: src/applications/vpn/vpn.c:942
3457msgid "enables IPv6 over GNUnet (incomplete)"
3458msgstr ""
3459
3460#: src/applications/vpn/vpn.c:963
3461msgid "RFC4193 Waiting for tun thread to end\n"
3462msgstr ""
3463
3464#: src/applications/vpn/vpn.c:978
3465msgid "RFC4193 The tun thread has ended\n"
3466msgstr ""
3467
3468#: src/applications/vpn/vpn.c:996
3469#, c-format
3470msgid "RFC4193 Closing tunnel %d fd %d\n"
3471msgstr ""
3472
3473#: src/server/core.c:119 src/server/core.c:318
3474#, c-format
3475msgid "Configuration value `%s' under [MODULES] for `%s' is invalid!\n"
3476msgstr ""
3477
3478#: src/server/core.c:140
3479#, c-format
3480msgid "Application module `%s' already initialized!\n"
3481msgstr ""
3482
3483#: src/server/core.c:194
3484#, c-format
3485msgid "Failed to load plugin `%s' at %s:%d. Unloading plugin.\n"
3486msgstr ""
3487
3488#: src/server/core.c:244
3489#, c-format
3490msgid "Could not shutdown `%s': application not loaded\n"
3491msgstr ""
3492
3493#: src/server/core.c:255
3494#, c-format
3495msgid "Could not shutdown application `%s': not initialized\n"
3496msgstr ""
3497
3498#: src/server/core.c:265
3499#, c-format
3500msgid "Could not find '%s%s' method in library `%s'.\n"
3501msgstr ""
3502
3503#: src/server/core.c:422
3504#, c-format
3505msgid "Could not release %p: service not loaded\n"
3506msgstr ""
3507
3508#: src/server/core.c:531
3509#, c-format
3510msgid "Could not properly shutdown application `%s'.\n"
3511msgstr ""
3512
3513#: src/server/core.c:676
3514#, c-format
3515msgid "Could not properly unload service `%s'!\n"
3516msgstr ""
3517
3518#: src/server/gnunet-update.c:146
3519#, c-format
3520msgid "Updating data for module `%s'\n"
3521msgstr ""
3522
3523#: src/server/gnunet-update.c:151
3524#, c-format
3525msgid "Failed to update data for module `%s'\n"
3526msgstr ""
3527
3528#: src/server/gnunet-update.c:225 src/server/gnunetd.c:124
3529msgid "Core initialization failed.\n"
3530msgstr ""
3531
3532#: src/server/gnunet-update.c:270
3533msgid "Updates GNUnet datastructures after version change."
3534msgstr ""
3535
3536#: src/server/gnunet-update.c:274 src/server/gnunet-transport-check.c:376
3537msgid "run as user LOGIN"
3538msgstr ""
3539
3540#: src/server/gnunet-update.c:278
3541msgid "run in client mode (for getting client configuration values)"
3542msgstr ""
3543
3544#: src/server/version.c:125
3545msgid ""
3546"Failed to determine filename used to store GNUnet version information!\n"
3547msgstr ""
3548
3549#: src/server/gnunetd.c:85
3550#, c-format
3551msgid "`%s' startup complete.\n"
3552msgstr ""
3553
3554#: src/server/gnunetd.c:89
3555#, c-format
3556msgid "`%s' is shutting down.\n"
3557msgstr ""
3558
3559#: src/server/gnunetd.c:179
3560msgid ""
3561"run in debug mode; gnunetd will not daemonize and error messages will be "
3562"written to stderr instead of a logfile"
3563msgstr ""
3564
3565#: src/server/gnunetd.c:183
3566msgid "Starts the gnunetd daemon."
3567msgstr ""
3568
3569#: src/server/gnunetd.c:186
3570msgid "disable padding with random data (experimental)"
3571msgstr ""
3572
3573#: src/server/gnunetd.c:190
3574msgid "print all log messages to the console (only works together with -d)"
3575msgstr ""
3576
3577#: src/server/gnunetd.c:194
3578msgid "specify username as which gnunetd should run"
3579msgstr ""
3580
3581#: src/server/gnunetd.c:275
3582#, c-format
3583msgid "Configuration or GNUnet version changed. You need to run `%s'!\n"
3584msgstr ""
3585
3586#: src/server/tcpserver.c:121
3587#, c-format
3588msgid "The `%s' request received from client is malformed.\n"
3589msgstr ""
3590
3591#: src/server/tcpserver.c:409
3592#, c-format
3593msgid "`%s' failed for port %d. Is gnunetd already running?\n"
3594msgstr ""
3595
3596#: src/server/tcpserver.c:487 src/server/tcpserver.c:512
3597#, c-format
3598msgid ""
3599"Malformed network specification in the configuration in section `%s' for "
3600"entry `%s': %s\n"
3601msgstr ""
3602
3603#: src/server/tcpserver.c:572
3604#, c-format
3605msgid "Registering failed, message type %d already in use.\n"
3606msgstr ""
3607
3608#: src/server/startup.c:219
3609#, c-format
3610msgid "Unable to obtain filesystem information for `%s': %u\n"
3611msgstr ""
3612
3613#: src/server/startup.c:237
3614#, c-format
3615msgid ""
3616"Filesystem `%s' of partition `%s' is unknown. Please contact gnunet-"
3617"developers@gnu.org!"
3618msgstr ""
3619
3620#: src/server/startup.c:252
3621#, c-format
3622msgid ""
3623"Limiting datastore size to %llu GB, because the `%s' filesystem does not "
3624"support larger files. Please consider storing the database on a NTFS "
3625"partition!\n"
3626msgstr ""
3627
3628#: src/server/startup.c:291
3629#, c-format
3630msgid "Insufficient access permissions for `%s': %s\n"
3631msgstr ""
3632
3633#: src/server/gnunet-peer-info.c:55
3634msgid "Print information about GNUnet peers."
3635msgstr ""
3636
3637#: src/server/gnunet-peer-info.c:59
3638msgid "don't resolve host names"
3639msgstr ""
3640
3641#: src/server/gnunet-peer-info.c:62
3642msgid "output only the identity strings"
3643msgstr ""
3644
3645#: src/server/gnunet-peer-info.c:65
3646msgid "output our own identity only"
3647msgstr ""
3648
3649#: src/server/gnunet-peer-info.c:130 src/server/gnunet-peer-info.c:164
3650#, c-format
3651msgid "Could not get address of peer `%s'.\n"
3652msgstr ""
3653
3654#: src/server/gnunet-peer-info.c:143
3655#, c-format
3656msgid "`%s' message invalid (signature invalid).\n"
3657msgstr ""
3658
3659#: src/server/gnunet-peer-info.c:168
3660#, c-format
3661msgid "Peer `%s' with trust %8u\n"
3662msgstr ""
3663
3664#: src/server/gnunet-peer-info.c:175
3665#, c-format
3666msgid "Peer `%s' with trust %8u and address `%s'\n"
3667msgstr ""
3668
3669#: src/server/connection.c:1313
3670#, c-format
3671msgid "`%s' selected %d out of %d messages (MTU: %d).\n"
3672msgstr ""
3673
3674#: src/server/connection.c:1323
3675#, c-format
3676msgid "Message details: %u: length %d, priority: %d\n"
3677msgstr ""
3678
3679#: src/server/connection.c:3129
3680#, c-format
3681msgid "Message from `%s' discarded: invalid format.\n"
3682msgstr ""
3683
3684#: src/server/connection.c:3218
3685#, c-format
3686msgid "Invalid sequence number %u <= %u, dropping message.\n"
3687msgstr ""
3688
3689#: src/server/connection.c:3240
3690msgid "Message received more than one day old. Dropped.\n"
3691msgstr ""
3692
3693#: src/server/connection.c:3763
3694msgid "# outgoing messages dropped"
3695msgstr ""
3696
3697#: src/server/connection.c:3766
3698msgid "# bytes of outgoing messages dropped"
3699msgstr ""
3700
3701#: src/server/connection.c:3768
3702msgid "# connections closed (HANGUP sent)"
3703msgstr ""
3704
3705#: src/server/connection.c:3772
3706msgid "# connections closed (transport issue)"
3707msgstr ""
3708
3709#: src/server/connection.c:3775
3710msgid "# bytes encrypted"
3711msgstr ""
3712
3713#: src/server/connection.c:3779
3714msgid "# bytes transmitted"
3715msgstr ""
3716
3717#: src/server/connection.c:3783
3718msgid "# bytes received"
3719msgstr ""
3720
3721#: src/server/connection.c:3785
3722msgid "# bytes decrypted"
3723msgstr ""
3724
3725#: src/server/connection.c:3786
3726msgid "# bytes noise sent"
3727msgstr ""
3728
3729#: src/server/connection.c:3789
3730msgid "# total bytes per second send limit"
3731msgstr ""
3732
3733#: src/server/connection.c:3792
3734msgid "# total bytes per second receive limit"
3735msgstr ""
3736
3737#: src/server/connection.c:3795
3738msgid "# total number of messages in send buffers"
3739msgstr ""
3740
3741#: src/server/connection.c:3798
3742msgid "# total number of bytes we were allowed to send but did not"
3743msgstr ""
3744
3745#: src/server/connection.c:3801
3746msgid "# total number of bytes we were allowed to sent"
3747msgstr ""
3748
3749#: src/server/connection.c:3804
3750msgid "# total number of bytes we are currently allowed to send"
3751msgstr ""
3752
3753#: src/server/connection.c:3807
3754msgid "# transports switched to stream transport"
3755msgstr ""
3756
3757#: src/server/connection.c:3810
3758msgid "# average connection lifetime (in ms)"
3759msgstr ""
3760
3761#: src/server/connection.c:3813
3762msgid "# conn. shutdown: other peer sent too much"
3763msgstr ""
3764
3765#: src/server/connection.c:3816
3766msgid "# conn. shutdown: we lacked bandwidth"
3767msgstr ""
3768
3769#: src/server/connection.c:3819
3770msgid "# conn. shutdown: other peer timed out"
3771msgstr ""
3772
3773#: src/server/connection.c:3822
3774msgid "# conn. shutdown: timed out during connect"
3775msgstr ""
3776
3777#: src/server/connection.c:3825
3778msgid "# conn. shutdown: other peer requested it"
3779msgstr ""
3780
3781#: src/server/handler.c:442
3782#, c-format
3783msgid "Received corrupt message from peer `%s' in %s:%d.\n"
3784msgstr ""
3785
3786#: src/server/gnunet-transport-check.c:121
3787#, c-format
3788msgid "`%s': Could not create hello.\n"
3789msgstr ""
3790
3791#: src/server/gnunet-transport-check.c:129
3792#, c-format
3793msgid "`%s': Could not connect.\n"
3794msgstr ""
3795
3796#: src/server/gnunet-transport-check.c:163
3797#, c-format
3798msgid "`%s': Could not send.\n"
3799msgstr ""
3800
3801#: src/server/gnunet-transport-check.c:179
3802#, c-format
3803msgid "`%s': Did not receive message within %llu ms.\n"
3804msgstr ""
3805
3806#: src/server/gnunet-transport-check.c:192
3807#, c-format
3808msgid "`%s': Could not disconnect.\n"
3809msgstr ""
3810
3811#: src/server/gnunet-transport-check.c:200
3812#, c-format
3813msgid ""
3814"`%s' transport OK. It took %ums to transmit %llu messages of %llu bytes "
3815"each.\n"
3816msgstr ""
3817
3818#: src/server/gnunet-transport-check.c:231
3819#, c-format
3820msgid " Transport %d is not being tested\n"
3821msgstr ""
3822
3823#: src/server/gnunet-transport-check.c:261
3824#, c-format
3825msgid ""
3826"\n"
3827"Contacting `%s'."
3828msgstr ""
3829
3830#: src/server/gnunet-transport-check.c:286
3831#, c-format
3832msgid " Connection failed\n"
3833msgstr ""
3834
3835#: src/server/gnunet-transport-check.c:292
3836#, c-format
3837msgid " Connection failed (bug?)\n"
3838msgstr ""
3839
3840#: src/server/gnunet-transport-check.c:330
3841#, c-format
3842msgid "Timeout after %llums.\n"
3843msgstr ""
3844
3845#: src/server/gnunet-transport-check.c:332
3846#, c-format
3847msgid "OK!\n"
3848msgstr ""
3849
3850#: src/server/gnunet-transport-check.c:357
3851msgid "Tool to test if GNUnet transport services are operational."
3852msgstr ""
3853
3854#: src/server/gnunet-transport-check.c:361
3855msgid "ping peers from HOSTLISTURL that match transports"
3856msgstr ""
3857
3858#: src/server/gnunet-transport-check.c:364
3859msgid "send COUNT messages"
3860msgstr ""
3861
3862#: src/server/gnunet-transport-check.c:367
3863msgid "send messages with SIZE bytes payload"
3864msgstr ""
3865
3866#: src/server/gnunet-transport-check.c:370
3867msgid "specifies which TRANSPORT should be tested"
3868msgstr ""
3869
3870#: src/server/gnunet-transport-check.c:373
3871msgid "specifies after how many MS to time-out"
3872msgstr ""
3873
3874#: src/server/gnunet-transport-check.c:381
3875msgid "repeat each test X times"
3876msgstr ""
3877
3878#: src/server/gnunet-transport-check.c:449
3879#, c-format
3880msgid "Testing transport(s) %s\n"
3881msgstr ""
3882
3883#: src/server/gnunet-transport-check.c:451
3884#, c-format
3885msgid "Available transport(s): %s\n"
3886msgstr ""
3887
3888#: src/server/gnunet-transport-check.c:501
3889#, c-format
3890msgid ""
3891"\n"
3892"%d out of %d peers contacted successfully (%d times transport unavailable).\n"
3893msgstr ""
3894
3895#: src/transports/common.c:370
3896#, c-format
3897msgid "Port is 0, will only send using %s.\n"
3898msgstr ""
3899
3900#: src/transports/smtp.c:367 src/transports/udp.c:107 src/transports/tcp.c:271
3901#: src/transports/tcp.c:291
3902#, c-format
3903msgid "Received malformed message via %s. Ignored.\n"
3904msgstr ""
3905
3906#: src/transports/smtp.c:459
3907msgid "SMTP filter string to invalid, lacks ': '\n"
3908msgstr ""
3909
3910#: src/transports/smtp.c:469
3911#, c-format
3912msgid "SMTP filter string to long, capped to `%s'\n"
3913msgstr ""
3914
3915#: src/transports/smtp.c:564 src/transports/smtp.c:575
3916#: src/transports/smtp.c:589 src/transports/smtp.c:609
3917#: src/transports/smtp.c:634 src/transports/smtp.c:643
3918#: src/transports/smtp.c:657 src/transports/smtp.c:669
3919#, c-format
3920msgid "SMTP: `%s' failed: %s.\n"
3921msgstr ""
3922
3923#: src/transports/smtp.c:814
3924msgid "No email-address specified, can not start SMTP transport.\n"
3925msgstr ""
3926
3927#: src/transports/smtp.c:831
3928msgid "# bytes received via SMTP"
3929msgstr ""
3930
3931#: src/transports/smtp.c:832
3932msgid "# bytes sent via SMTP"
3933msgstr ""
3934
3935#: src/transports/smtp.c:834
3936msgid "# bytes dropped by SMTP (outgoing)"
3937msgstr ""
3938
3939#: src/transports/upnp/upnp.c:431
3940#, c-format
3941msgid "%s failed for url `%s' and post-data `%s' at %s:%d: `%s'\n"
3942msgstr ""
3943
3944#: src/transports/upnp/upnp.c:476
3945#, c-format
3946msgid "upnp: NAT Returned IP: %s\n"
3947msgstr ""
3948
3949#: src/transports/http.c:2019 src/transports/tcp.c:811
3950#, c-format
3951msgid ""
3952"The UPnP service could not be loaded. To disable UPnP, set the configuration "
3953"option \"UPNP\" in section \"%s\" to \"NO\"\n"
3954msgstr ""
3955
3956#: src/transports/http.c:2028
3957msgid "# bytes received via HTTP"
3958msgstr ""
3959
3960#: src/transports/http.c:2029
3961msgid "# bytes sent via HTTP"
3962msgstr ""
3963
3964#: src/transports/http.c:2031
3965msgid "# bytes dropped by HTTP (outgoing)"
3966msgstr ""
3967
3968#: src/transports/http.c:2032
3969msgid "# HTTP GET issued"
3970msgstr ""
3971
3972#: src/transports/http.c:2034
3973msgid "# HTTP GET received"
3974msgstr ""
3975
3976#: src/transports/http.c:2035
3977msgid "# HTTP PUT issued"
3978msgstr ""
3979
3980#: src/transports/http.c:2037
3981msgid "# HTTP PUT received"
3982msgstr ""
3983
3984#: src/transports/http.c:2039
3985msgid "# HTTP select calls"
3986msgstr ""
3987
3988#: src/transports/http.c:2041
3989msgid "# HTTP send calls"
3990msgstr ""
3991
3992#: src/transports/http.c:2044
3993msgid "# HTTP curl send callbacks"
3994msgstr ""
3995
3996#: src/transports/http.c:2046
3997msgid "# HTTP curl receive callbacks"
3998msgstr ""
3999
4000#: src/transports/http.c:2048
4001msgid "# HTTP mhd access callbacks"
4002msgstr ""
4003
4004#: src/transports/http.c:2050
4005msgid "# HTTP mhd read callbacks"
4006msgstr ""
4007
4008#: src/transports/http.c:2052
4009msgid "# HTTP mhd close callbacks"
4010msgstr ""
4011
4012#: src/transports/http.c:2054
4013msgid "# HTTP connect calls"
4014msgstr ""
4015
4016#: src/transports/ip.c:70 src/transports/ip.c:365
4017#, c-format
4018msgid "Failed to obtain my (external) %s address!\n"
4019msgstr ""
4020
4021#: src/transports/udp.c:472 src/transports/tcp.c:728
4022#, c-format
4023msgid "Failed to bind to %s port %d.\n"
4024msgstr ""
4025
4026#: src/transports/udp.c:538
4027#, c-format
4028msgid "MTU %llu for `%s' is probably too low!\n"
4029msgstr ""
4030
4031#: src/transports/udp.c:562
4032msgid "# bytes received via UDP"
4033msgstr ""
4034
4035#: src/transports/udp.c:563
4036msgid "# bytes sent via UDP"
4037msgstr ""
4038
4039#: src/transports/udp.c:565
4040msgid "# bytes dropped by UDP (outgoing)"
4041msgstr ""
4042
4043#: src/transports/udp.c:567
4044msgid "# UDP connections (right now)"
4045msgstr ""
4046
4047#: src/transports/tcp.c:821
4048msgid "# bytes received via TCP"
4049msgstr ""
4050
4051#: src/transports/tcp.c:822
4052msgid "# bytes sent via TCP"
4053msgstr ""
4054
4055#: src/transports/tcp.c:824
4056msgid "# bytes dropped by TCP (outgoing)"
4057msgstr ""
4058
4059#: src/include/gnunet_util_getopt.h:154
4060msgid "print this help"
4061msgstr ""
4062
4063#: src/include/gnunet_util_getopt.h:163
4064msgid "print the version number"
4065msgstr ""
4066
4067#: src/include/gnunet_util_getopt.h:169
4068msgid "configure logging to use LOGLEVEL"
4069msgstr ""
4070
4071#: src/include/gnunet_util_getopt.h:175
4072msgid "be verbose"
4073msgstr ""
4074
4075#: src/include/gnunet_util_getopt.h:181
4076msgid "use configuration file FILENAME"
4077msgstr ""
4078
4079#: src/include/gnunet_util_getopt.h:187
4080msgid "specify host on which gnunetd is running"
4081msgstr ""
4082
4083#: src/include/gnunet_util_error.h:219 src/include/gnunet_util_error.h:224
4084#: src/include/gnunet_util_error.h:230 src/include/gnunet_util_error.h:232
4085#, c-format
4086msgid "Internal error: assertion failed at %s:%d.\n"
4087msgstr ""
4088
4089#: src/include/gnunet_util_error.h:242
4090#, c-format
4091msgid ""
4092"External protocol violation: assertion failed at %s:%d (no need to panic, we "
4093"can handle this).\n"
4094msgstr ""
4095
4096#: src/include/gnunet_util_error.h:270 src/include/gnunet_util_error.h:277
4097#, c-format
4098msgid "`%s' failed on file `%s' at %s:%d with error: %s\n"
4099msgstr ""
4100
4101#: contrib/config-daemon.scm:39 contrib/config-client.scm:40
4102msgid "No help available."
4103msgstr ""
4104
4105#: contrib/config-daemon.scm:42
4106msgid ""
4107"You can use 'make check' in src/transports/upnp/ to find out if your NAT "
4108"supports UPnP. You should disable this option if you are sure that you are "
4109"not behind a NAT. If your NAT box does not support UPnP, having this on "
4110"will not do much harm (only cost a small amount of resources)."
4111msgstr ""
4112
4113#: contrib/config-daemon.scm:54 contrib/config-client.scm:53
4114msgid "Prompt for development and/or incomplete code"
4115msgstr ""
4116
4117#: contrib/config-daemon.scm:56 contrib/config-client.scm:55
4118msgid ""
4119"If EXPERIMENTAL is set to NO, options for experimental code are not shown. "
4120"If in doubt, use NO.\n"
4121"\n"
4122"Some options apply to experimental code that maybe in a state of development "
4123"where the functionality, stability, or the level of testing is not yet high "
4124"enough for general use. These features are said to be of \"alpha\" "
4125"quality. If a feature is currently in alpha, uninformed use is discouraged "
4126"(since the developers then do not fancy \"Why doesn't this work?\" type "
4127"messages).\n"
4128"\n"
4129"However, active testing and qualified feedback of these features is always "
4130"welcome. Users should just be aware that alpha features may not meet the "
4131"normal level of reliability or it may fail to work in some special cases. "
4132"Bug reports are usually welcomed by the developers, but please read the "
4133"documents <file://README> and <http://gnunet.org/faq.php3> and use <https://"
4134"gnunet.org/mantis/> for how to report problems."
4135msgstr ""
4136
4137#: contrib/config-daemon.scm:71 contrib/config-client.scm:70
4138msgid "Show options for advanced users"
4139msgstr ""
4140
4141#: contrib/config-daemon.scm:73 contrib/config-client.scm:72
4142msgid ""
4143"These are options that maybe difficult to understand for the beginner. These "
4144"options typically refer to features that allow tweaking of the "
4145"installation. If in a hurry, say NO."
4146msgstr ""
4147
4148#: contrib/config-daemon.scm:84 contrib/config-client.scm:83
4149msgid "Show rarely used options"
4150msgstr ""
4151
4152#: contrib/config-daemon.scm:86 contrib/config-client.scm:85
4153msgid ""
4154"These are options that hardly anyone actually needs. If you plan on doing "
4155"development on GNUnet, you may want to look into these. If in doubt or in a "
4156"hurry, say NO."
4157msgstr ""
4158
4159#: contrib/config-daemon.scm:97 contrib/config-client.scm:96
4160msgid "Meta-configuration"
4161msgstr ""
4162
4163#: contrib/config-daemon.scm:98 contrib/config-client.scm:97
4164msgid "Which level of configuration should be available"
4165msgstr ""
4166
4167#: contrib/config-daemon.scm:115
4168msgid "Full pathname of GNUnet HOME directory"
4169msgstr ""
4170
4171#: contrib/config-daemon.scm:117
4172msgid ""
4173"This gives the root-directory of the GNUnet installation. Make sure there is "
4174"some space left in that directory. :-) Users inserting or indexing files "
4175"will be able to store data in this directory up to the (global) quota "
4176"specified below. Having a few gigabytes of free space is recommended."
4177msgstr ""
4178
4179#: contrib/config-daemon.scm:130
4180msgid "Full pathname of GNUnet directory for file-sharing data"
4181msgstr ""
4182
4183#: contrib/config-daemon.scm:142
4184msgid "Full pathname to the directory with the key-value database"
4185msgstr ""
4186
4187#: contrib/config-daemon.scm:143
4188msgid "Note that the kvstore is currently not used."
4189msgstr ""
4190
4191#: contrib/config-daemon.scm:154
4192msgid "Full pathname of GNUnet directory for indexed files symbolic links"
4193msgstr ""
4194
4195#: contrib/config-daemon.scm:166
4196msgid "How many minutes should peer advertisements last?"
4197msgstr ""
4198
4199#: contrib/config-daemon.scm:168
4200msgid ""
4201"How many minutes is the current IP valid? (GNUnet will sign HELLO messages "
4202"with this expiration timeline. If you are on dialup, 60 (for 1 hour) is "
4203"suggested. If you have a static IP address, you may want to set this to a "
4204"large value (say 14400). The default is 1440 (1 day). If your IP changes "
4205"periodically, you will want to choose an expiry period smaller than the "
4206"frequency with which your IP changes."
4207msgstr ""
4208
4209#: contrib/config-daemon.scm:179
4210msgid "Where can GNUnet find an initial list of peers?"
4211msgstr ""
4212
4213#: contrib/config-daemon.scm:181
4214msgid ""
4215"GNUnet can automatically update the hostlist from the web. While GNUnet "
4216"internally communicates which hosts are online, it is typically a good idea "
4217"to get a fresh hostlist whenever gnunetd starts from the WEB. By setting "
4218"this option, you can specify from which server gnunetd should try to "
4219"download the hostlist. The default should be fine for now.\n"
4220"\t\t\n"
4221"The general format is a list of space-separated URLs. Each URL must have "
4222"the format http://HOSTNAME/FILENAME\n"
4223"\t\t\n"
4224"If you want to setup an alternate hostlist server, you must run a permanent "
4225"node and \"cat data/hosts/* > hostlist\" every few minutes to keep the list "
4226"up-to-date.\n"
4227"\t\t\n"
4228"If you do not specify a HOSTLISTURL, you must copy valid hostkeys to data/"
4229"hosts manually."
4230msgstr ""
4231
4232#: contrib/config-daemon.scm:198
4233msgid "HTTP Proxy Server"
4234msgstr ""
4235
4236#: contrib/config-daemon.scm:200
4237msgid ""
4238"If you have to use a proxy for outbound HTTP connections, specify the proxy "
4239"configuration here. Default is no proxy."
4240msgstr ""
4241
4242#: contrib/config-daemon.scm:212
4243msgid ""
4244"Name of the directory where gnunetd should store contact information about "
4245"peers"
4246msgstr ""
4247
4248#: contrib/config-daemon.scm:214
4249msgid ""
4250"Unless you want to share the directory directly using a webserver, the "
4251"default is most likely just fine."
4252msgstr ""
4253
4254#: contrib/config-daemon.scm:240 contrib/config-client.scm:140
4255msgid "How long should logs be kept?"
4256msgstr ""
4257
4258#: contrib/config-daemon.scm:242 contrib/config-client.scm:142
4259msgid ""
4260"How long should logs be kept? If you specify a value greater than zero, a "
4261"log is created each day with the date appended to its filename. These logs "
4262"are deleted after $KEEPLOG days.\tTo keep logs forever, set this value to 0."
4263msgstr ""
4264
4265#: contrib/config-daemon.scm:253
4266msgid ""
4267"What maximum number of open file descriptors should be requested from the OS?"
4268msgstr ""
4269
4270#: contrib/config-daemon.scm:255
4271msgid ""
4272"The default of 1024 should be fine for most systems. If your system can "
4273"support more, increasing the number might help support additional clients on "
4274"machines with plenty of bandwidth. For embedded systems, a smaller number "
4275"might be acceptable. A value of 0 will leave the descriptor limit "
4276"untouched. This option is mostly for OS X systems where the default is too "
4277"low. Note that if gnunetd cannot obtain the desired number of file "
4278"descriptors from the operating system, it will print a warning and try to "
4279"run with what it is given."
4280msgstr ""
4281
4282#: contrib/config-daemon.scm:266
4283msgid "Where should gnunetd write the logs?"
4284msgstr ""
4285
4286#: contrib/config-daemon.scm:278
4287msgid "Enable for extra-verbose logging."
4288msgstr ""
4289
4290#: contrib/config-daemon.scm:290 contrib/config-client.scm:165
4291msgid "Logging"
4292msgstr ""
4293
4294#: contrib/config-daemon.scm:291 contrib/config-client.scm:166
4295msgid "Specify which system messages should be logged how"
4296msgstr ""
4297
4298#: contrib/config-daemon.scm:296 contrib/config-client.scm:170
4299msgid "Logging of events for users"
4300msgstr ""
4301
4302#: contrib/config-daemon.scm:297 contrib/config-client.scm:171
4303msgid "Logging of events for the system administrator"
4304msgstr ""
4305
4306#: contrib/config-daemon.scm:309
4307msgid "Where should gnunetd write the PID?"
4308msgstr ""
4309
4310#: contrib/config-daemon.scm:310
4311msgid ""
4312"The default is no longer /var/run/gnunetd.pid since we could not delete the "
4313"file on shutdown at that location."
4314msgstr ""
4315
4316#: contrib/config-daemon.scm:322
4317msgid "As which user should gnunetd run?"
4318msgstr ""
4319
4320#: contrib/config-daemon.scm:324
4321msgid ""
4322"Empty means \"current user\". On computer startup, it is root/SYSTEM. Under "
4323"Windows, this setting affects the creation of a new system service only."
4324msgstr ""
4325
4326#: contrib/config-daemon.scm:337
4327msgid "Should gnunetd be automatically started when the system boots?"
4328msgstr ""
4329
4330#: contrib/config-daemon.scm:338
4331msgid ""
4332"Set to YES if gnunetd should be automatically started on boot. If this "
4333"option is set, gnunet-setup will install a script to start the daemon upon "
4334"completion. This option may not work on all systems."
4335msgstr ""
4336
4337#: contrib/config-daemon.scm:350
4338msgid "Which transport mechanisms should GNUnet use?"
4339msgstr ""
4340
4341#: contrib/config-daemon.scm:352
4342msgid ""
4343"Use a space-separated list of modules, e.g. \"udp smtp tcp\". The "
4344"available transports are udp, tcp, http, smtp and nat.\n"
4345"\t\t\n"
4346"Loading the 'nat' and 'tcp' modules is required for peers behind NAT boxes "
4347"that cannot directly be reached from the outside. Peers that are NOT behind "
4348"a NAT box and that want to *allow* peers that ARE behind a NAT box to "
4349"connect must ALSO load the 'nat' module. Note that the actual transfer will "
4350"always be via tcp initiated by the peer behind the NAT box. The nat "
4351"transport requires the use of tcp, http and/or smtp in addition to nat "
4352"itself."
4353msgstr ""
4354
4355#: contrib/config-daemon.scm:366
4356msgid "Which applications should gnunetd support?"
4357msgstr ""
4358
4359#: contrib/config-daemon.scm:368
4360msgid ""
4361"Whenever this option is changed, you MUST run gnunet-update. Currently, the "
4362"available applications are:\n"
4363"\n"
4364"advertising: advertises your peer to other peers. Without it, your peer will "
4365"not participate in informing peers about other peers. You should always "
4366"load this module.\n"
4367"\n"
4368"getoption: allows clients to query gnunetd about the values of various "
4369"configuration options. Many tools need this. You should always load this "
4370"module.\n"
4371"\n"
4372"stats: allows tools like gnunet-stats and gnunet-gtk to query gnunetd about "
4373"various statistics. This information is usually quite useful to diagnose "
4374"errors, hence it is recommended that you load this module.\n"
4375"\n"
4376"traffic: keeps track of how many messages were recently received and "
4377"transmitted. This information can then be used to establish how much cover "
4378"traffic is currently available. The amount of cover traffic becomes "
4379"important if you want to make anonymous requests with an anonymity level "
4380"that is greater than one. It is recommended that you load this module.\n"
4381"\n"
4382"fs: needed for anonymous file sharing. You should always load this module.\n"
4383"\n"
4384"hostlist: integrated hostlist HTTP server. Useful if you want to offer a "
4385"hostlist and running Apache would be overkill.\n"
4386"\n"
4387"chat: broadcast chat (demo-application, ALPHA quality).\tRequired for gnunet-"
4388"chat. Note that the current implementation of chat is not considered to be "
4389"secure.\n"
4390"\n"
4391"tbench: benchmark transport performance. Required for gnunet-tbench. Note "
4392"that tbench allows other users to abuse your resources.\n"
4393"\n"
4394"tracekit: topology visualization toolkit. Required for gnunet-tracekit. "
4395"Note that loading tracekit will make it slightly easier for an adversary to "
4396"compromise your anonymity."
4397msgstr ""
4398
4399#: contrib/config-daemon.scm:399
4400msgid "Disable client-server connections"
4401msgstr ""
4402
4403#: contrib/config-daemon.scm:400
4404msgid ""
4405"This option can be used to tell gnunetd not to open the client port. When "
4406"run like this, gnunetd will participate as a peer in the network but not "
4407"support any user interfaces. This may be useful for headless systems that "
4408"are never expected to have end-user interactions. Note that this will also "
4409"prevent you from running diagnostic tools like gnunet-stats!"
4410msgstr ""
4411
4412#: contrib/config-daemon.scm:412
4413msgid "YES disables IPv6 support, NO enables IPv6 support"
4414msgstr ""
4415
4416#: contrib/config-daemon.scm:413
4417msgid ""
4418"This option may be useful on peers where the kernel does not support IPv6. "
4419"You might also want to set this option if you do not have an IPv6 network "
4420"connection."
4421msgstr ""
4422
4423#: contrib/config-daemon.scm:425
4424msgid "Disable peer discovery"
4425msgstr ""
4426
4427#: contrib/config-daemon.scm:426
4428msgid ""
4429"The option 'PRIVATE-NETWORK' can be used to limit the connections of this "
4430"peer to peers of which the hostkey has been copied by hand to data/hosts; "
4431"if this option is given, GNUnet will not accept advertisements of peers that "
4432"the local node does not already know about. Note that in order for this "
4433"option to work, HOSTLISTURL should either not be set at all or be set to a "
4434"trusted peer that only advertises the private network. Also, the option does "
4435"NOT work at the moment if the NAT transport is loaded; for that, a couple of "
4436"lines above would need some minor editing :-)."
4437msgstr ""
4438
4439#: contrib/config-daemon.scm:437
4440msgid "Disable advertising this peer to other peers"
4441msgstr ""
4442
4443#: contrib/config-daemon.scm:449
4444msgid "Disable automatic establishment of connections"
4445msgstr ""
4446
4447#: contrib/config-daemon.scm:450
4448msgid ""
4449"If this option is enabled, GNUnet will not automatically establish "
4450"connections to other peers, but instead wait for applications to "
4451"specifically request connections to other peers (or for other peers to "
4452"connect to us)."
4453msgstr ""
4454
4455#: contrib/config-daemon.scm:461
4456msgid "Enable advertising of other peers by this peer"
4457msgstr ""
4458
4459#: contrib/config-daemon.scm:462
4460msgid ""
4461"This option may be useful during testing, but turning it off is dangerous! "
4462"If in any doubt, set it to YES (which is the default)."
4463msgstr ""
4464
4465#: contrib/config-daemon.scm:473
4466msgid "Port for communication with GNUnet user interfaces"
4467msgstr ""
4468
4469#: contrib/config-daemon.scm:474
4470msgid ""
4471"Which is the client-server port that is used between gnunetd and the clients "
4472"(TCP only). You may firewall this port for non-local machines (but you do "
4473"not have to since GNUnet will perform access control and only allow "
4474"connections from machines that are listed under TRUSTED)."
4475msgstr ""
4476
4477#: contrib/config-daemon.scm:485
4478msgid "Port for the integrated hostlist HTTP server"
4479msgstr ""
4480
4481#: contrib/config-daemon.scm:497
4482msgid "IPv4 networks allowed to use gnunetd server"
4483msgstr ""
4484
4485#: contrib/config-daemon.scm:498 contrib/config-daemon.scm:510
4486msgid ""
4487"This option specifies which hosts are trusted enough to connect as clients "
4488"(to the TCP port). This is useful if you run gnunetd on one host of your "
4489"network and want to allow all other hosts to use this node as their server. "
4490"By default, this is set to 'loopback only'. The format is IP/NETMASK where "
4491"the IP is specified in dotted-decimal and the netmask either in CIDR "
4492"notation (/16) or in dotted decimal (255.255.0.0). Several entries must be "
4493"separated by a semicolon, spaces are not allowed."
4494msgstr ""
4495
4496#: contrib/config-daemon.scm:509
4497msgid "IPv6 networks allowed to use gnunetd server"
4498msgstr ""
4499
4500#: contrib/config-daemon.scm:522
4501msgid "Limit connections to the specfied set of peers."
4502msgstr ""
4503
4504#: contrib/config-daemon.scm:523
4505msgid ""
4506"If this option is not set, any peer is allowed to connect. If it is set, "
4507"only the specified peers are allowed. Specify the list of peer IDs (not IPs!)"
4508msgstr ""
4509
4510#: contrib/config-daemon.scm:534
4511msgid "Run gnunetd as this group."
4512msgstr ""
4513
4514#: contrib/config-daemon.scm:535
4515msgid ""
4516"When started as root, gnunetd will change permissions to the given group."
4517msgstr ""
4518
4519#: contrib/config-daemon.scm:546
4520msgid "Prevent the specfied set of peers from connecting."
4521msgstr ""
4522
4523#: contrib/config-daemon.scm:547
4524msgid ""
4525"If this option is not set, any peer is allowed to connect. If the ID of a "
4526"peer is listed here, connections from that peer will be refused. Specify "
4527"the list of peer IDs (not IPs!)"
4528msgstr ""
4529
4530#: contrib/config-daemon.scm:558
4531msgid "Topology Maintenance"
4532msgstr ""
4533
4534#: contrib/config-daemon.scm:559
4535msgid "Rarely used settings for peer advertisements and connections"
4536msgstr ""
4537
4538#: contrib/config-daemon.scm:579
4539msgid "General settings"
4540msgstr ""
4541
4542#: contrib/config-daemon.scm:580
4543msgid "Settings that change the behavior of GNUnet in general"
4544msgstr ""
4545
4546#: contrib/config-daemon.scm:607
4547msgid "Modules"
4548msgstr ""
4549
4550#: contrib/config-daemon.scm:608
4551msgid "Settings that select specific implementations for GNUnet modules"
4552msgstr ""
4553
4554#: contrib/config-daemon.scm:626
4555msgid "Fundamentals"
4556msgstr ""
4557
4558#: contrib/config-daemon.scm:646
4559msgid "Which database should be used?"
4560msgstr ""
4561
4562#: contrib/config-daemon.scm:648
4563msgid ""
4564"Which database should be used? The options are \"sqstore_sqlite\", "
4565"\"sqstore_postgres\" and \"sqstore_mysql\". You must run gnunet-update "
4566"after changing this value!\n"
4567"\t\t\t\n"
4568"In order to use MySQL or Postgres, you must configure the respective "
4569"database, which is relatively simple. Read the file doc/README.mysql or doc/"
4570"README.postgres for how to setup the respective database."
4571msgstr ""
4572
4573#: contrib/config-daemon.scm:661 contrib/config-daemon.scm:674
4574msgid "Which topology should be used?"
4575msgstr ""
4576
4577#: contrib/config-daemon.scm:662
4578msgid "Which database should be used for the temporary datastore of the DHT?"
4579msgstr ""
4580
4581#: contrib/config-daemon.scm:676
4582msgid ""
4583"Which topology should be used? The only option at the moment is "
4584"\"topology_default\""
4585msgstr ""
4586
4587#: contrib/config-daemon.scm:690
4588msgid ""
4589"The minimum number of connected friends before this peer is allowed to "
4590"connect to peers that are not listed as friends"
4591msgstr ""
4592
4593#: contrib/config-daemon.scm:691
4594msgid ""
4595"Note that this option does not guarantee that the peer will be able to "
4596"connect to the specified number of friends. Also, if the peer had connected "
4597"to a sufficient number of friends and then established non-friend "
4598"connections, some of the friends may drop out of the network, temporarily "
4599"resulting in having fewer than the specified number of friends connected "
4600"while being connected to non-friends. However, it is guaranteed that the "
4601"peer itself will never choose to drop a friend's connection if this would "
4602"result in dropping below the specified number of friends (unless that number "
4603"is higher than the overall connection target)."
4604msgstr ""
4605
4606#: contrib/config-daemon.scm:702
4607msgid ""
4608"If set to YES, the peer is only allowed to connect to other peers that are "
4609"explicitly specified as friends"
4610msgstr ""
4611
4612#: contrib/config-daemon.scm:703
4613msgid ""
4614"Use YES only if you have (trustworthy) friends that use GNUnet and are "
4615"afraid of establishing (direct) connections to unknown peers"
4616msgstr ""
4617
4618#: contrib/config-daemon.scm:714
4619msgid "List of friends for friend-to-friend topology"
4620msgstr ""
4621
4622#: contrib/config-daemon.scm:715
4623msgid ""
4624"Specifies the name of a file which contains a list of GNUnet peer IDs that "
4625"are friends. If used with the friend-to-friend topology, this will ensure "
4626"that GNUnet only connects to these peers (via any available transport)."
4627msgstr ""
4628
4629#: contrib/config-daemon.scm:726
4630msgid "Friend-to-Friend Topology Specification"
4631msgstr ""
4632
4633#: contrib/config-daemon.scm:727
4634msgid "Settings for restricting connections to friends"
4635msgstr ""
4636
4637#: contrib/config-daemon.scm:744
4638msgid "Name of the MySQL database GNUnet should use"
4639msgstr ""
4640
4641#: contrib/config-daemon.scm:756
4642msgid "Configuration file that specifies the MySQL username and password"
4643msgstr ""
4644
4645#: contrib/config-daemon.scm:768
4646msgid "Configuration of the MySQL database"
4647msgstr ""
4648
4649#: contrib/config-daemon.scm:787
4650msgid "MB of diskspace GNUnet can use for anonymous file sharing"
4651msgstr ""
4652
4653#: contrib/config-daemon.scm:789
4654msgid ""
4655"How much disk space (MB) is GNUnet allowed to use for anonymous file "
4656"sharing? This does not take indexed files into account, only the space "
4657"directly used by GNUnet is accounted for. GNUnet will gather content from "
4658"the network if the current space-consumption is below the number given here "
4659"(and if content migration is allowed below).\n"
4660"\n"
4661"Note that if you change the quota, you need to run gnunet-update afterwards."
4662msgstr ""
4663
4664#: contrib/config-daemon.scm:803
4665msgid "Number of entries in the migration buffer"
4666msgstr ""
4667
4668#: contrib/config-daemon.scm:804
4669msgid ""
4670"Each entry uses about 32k of memory. More entries can reduce disk IO and "
4671"CPU usage at the expense of having gnunetd use more memory. Very large "
4672"values may again increase CPU usage. A value of 0 will prevent your peer "
4673"from sending unsolicited responses."
4674msgstr ""
4675
4676#: contrib/config-daemon.scm:816
4677msgid "Size of the routing table for anonymous routing."
4678msgstr ""
4679
4680#: contrib/config-daemon.scm:828
4681msgid "Size of the routing table for DHT routing."
4682msgstr ""
4683
4684#: contrib/config-daemon.scm:841
4685msgid "Allow migrating content to this peer."
4686msgstr ""
4687
4688#: contrib/config-daemon.scm:843
4689msgid ""
4690"If you say yes here, GNUnet will migrate content to your server, and you "
4691"will not be able to control what data is stored on your machine. \n"
4692"\t\t\t\n"
4693"If you activate it, you can claim for *all* the non-indexed (-n to gnunet-"
4694"insert) content that you did not know what it was even if an adversary takes "
4695"control of your machine. If you do not activate it, it is obvious that you "
4696"have knowledge of all the content that is hosted on your machine and thus "
4697"can be considered liable for it."
4698msgstr ""
4699
4700#: contrib/config-daemon.scm:857
4701msgid ""
4702"MB of diskspace GNUnet can use for caching DHT index data (the data will be "
4703"stored in /tmp)"
4704msgstr ""
4705
4706#: contrib/config-daemon.scm:858
4707msgid ""
4708"DHT index data is inherently small and expires comparatively quickly. It is "
4709"deleted whenever gnunetd is shut down.\n"
4710"\n"
4711"The size of the DSTORE QUOTA is specified in MB."
4712msgstr ""
4713
4714#: contrib/config-daemon.scm:872
4715msgid "Options for anonymous file sharing"
4716msgstr ""
4717
4718#: contrib/config-daemon.scm:891
4719msgid "Applications"
4720msgstr ""
4721
4722#: contrib/config-daemon.scm:907
4723msgid "Is this machine unreachable behind a NAT?"
4724msgstr ""
4725
4726#: contrib/config-daemon.scm:908
4727msgid ""
4728"Set to YES if this machine is behind a NAT that limits connections from the "
4729"outside to the GNUnet port and that cannot be traversed using UPnP. Note "
4730"that if you have configured your NAT box to allow direct connections from "
4731"other machines to the GNUnet ports or if GNUnet can open ports using UPnP, "
4732"you should set the option to NO. Set this only to YES if other peers cannot "
4733"contact you directly. You can use 'make check' in src/transports/upnp/ to "
4734"find out if your NAT supports UPnP. You can also use gnunet-transport-check "
4735"with the '-p' option in order to determine which setting results in more "
4736"connections. Use YES only if you get no connections otherwise. Set to AUTO "
4737"to use YES if the local IP is belongs to a private IP network and NO "
4738"otherwise."
4739msgstr ""
4740
4741#: contrib/config-daemon.scm:919
4742msgid "Which port should be used by the TCP IPv4 transport?"
4743msgstr ""
4744
4745#: contrib/config-daemon.scm:931 contrib/config-daemon.scm:1024
4746#: contrib/config-daemon.scm:1174
4747msgid "Should we try to determine our external IP using UPnP?"
4748msgstr ""
4749
4750#: contrib/config-daemon.scm:943
4751msgid "Which IP(v4)s are not allowed to connect?"
4752msgstr ""
4753
4754#: contrib/config-daemon.scm:955
4755msgid ""
4756"Which IP(v4)s are allowed to connect? Leave empty to use the IP of your "
4757"primary network interface."
4758msgstr ""
4759
4760#: contrib/config-daemon.scm:967 contrib/config-daemon.scm:1222
4761msgid "Which IPv6s are not allowed to connect?"
4762msgstr ""
4763
4764#: contrib/config-daemon.scm:979 contrib/config-daemon.scm:1234
4765msgid ""
4766"Which IPv6s are allowed to connect? Leave empty to allow any IP to connect."
4767msgstr ""
4768
4769#: contrib/config-daemon.scm:992
4770msgid "TCP transport"
4771msgstr ""
4772
4773#: contrib/config-daemon.scm:1012
4774msgid "Which port should be used by the HTTP transport?"
4775msgstr ""
4776
4777#: contrib/config-daemon.scm:1036
4778msgid "Which is the external port of the HTTP transport?"
4779msgstr ""
4780
4781#: contrib/config-daemon.scm:1037
4782msgid ""
4783"Use this option if your firewall maps, say, port 80 to your real HTTP port. "
4784"This can be useful in making the HTTP messages appear even more legit "
4785"(without needing to run gnunetd as root due to the use of a privileged port)."
4786msgstr ""
4787
4788#: contrib/config-daemon.scm:1048
4789msgid "HTTP transport"
4790msgstr ""
4791
4792#: contrib/config-daemon.scm:1067
4793msgid "What is the maximum transfer unit for SMTP?"
4794msgstr ""
4795
4796#: contrib/config-daemon.scm:1079
4797msgid ""
4798"What is the maximum number of e-mails that gnunetd would be allowed to send "
4799"per hour?"
4800msgstr ""
4801
4802#: contrib/config-daemon.scm:1080
4803msgid "Use 0 for unlimited"
4804msgstr ""
4805
4806#: contrib/config-daemon.scm:1091
4807msgid "Which e-mail address should be used to send e-mail to this peer?"
4808msgstr ""
4809
4810#: contrib/config-daemon.scm:1092
4811msgid ""
4812"You must make sure that e-mail received at this address is forwarded to the "
4813"PIPE which is read by gnunetd. Use the FILTER option to filter e-mail with "
4814"procmail and the PIPE option to set the name of the pipe."
4815msgstr ""
4816
4817#: contrib/config-daemon.scm:1103
4818msgid ""
4819"Which header line should other peers include in e-mails to enable filtering?"
4820msgstr ""
4821
4822#: contrib/config-daemon.scm:1104
4823msgid ""
4824"You can specify a header line here which can then be used by procmail to "
4825"filter GNUnet e-mail from your inbox and forward it to gnunetd."
4826msgstr ""
4827
4828#: contrib/config-daemon.scm:1115
4829msgid "What is the filename of the pipe where gnunetd can read its e-mail?"
4830msgstr ""
4831
4832#: contrib/config-daemon.scm:1116
4833msgid "Have a look at contrib/dot-procmailrc for an example .procmailrc file."
4834msgstr ""
4835
4836#: contrib/config-daemon.scm:1127
4837msgid "What is the name and port of the server for outgoing e-mail?"
4838msgstr ""
4839
4840#: contrib/config-daemon.scm:1128
4841msgid "The basic format is HOSTNAME:PORT."
4842msgstr ""
4843
4844#: contrib/config-daemon.scm:1139
4845msgid "SMTP transport"
4846msgstr ""
4847
4848#: contrib/config-daemon.scm:1162
4849msgid "Which port should be used by the UDP IPv4 transport?"
4850msgstr ""
4851
4852#: contrib/config-daemon.scm:1186
4853msgid "What is the maximum transfer unit for UDP?"
4854msgstr ""
4855
4856#: contrib/config-daemon.scm:1198
4857msgid "Which IPs are not allowed to connect?"
4858msgstr ""
4859
4860#: contrib/config-daemon.scm:1210
4861msgid ""
4862"Which IPs are allowed to connect? Leave empty to allow connections from any "
4863"IP."
4864msgstr ""
4865
4866#: contrib/config-daemon.scm:1246
4867msgid "UDP transport"
4868msgstr ""
4869
4870#: contrib/config-daemon.scm:1268
4871msgid "Network interface"
4872msgstr ""
4873
4874#: contrib/config-daemon.scm:1280
4875msgid "External IP address (leave empty to try auto-detection)"
4876msgstr ""
4877
4878#: contrib/config-daemon.scm:1292
4879msgid "External IPv6 address (leave empty to try auto-detection)"
4880msgstr ""
4881
4882#: contrib/config-daemon.scm:1304
4883msgid "Transports"
4884msgstr ""
4885
4886#: contrib/config-daemon.scm:1326
4887msgid "What is the maximum number of bytes per second that we may receive?"
4888msgstr ""
4889
4890#: contrib/config-daemon.scm:1338
4891msgid "What is the maximum number of bytes per second that we may send?"
4892msgstr ""
4893
4894#: contrib/config-daemon.scm:1350
4895msgid "What is the maximum CPU load (percentage)?"
4896msgstr ""
4897
4898#: contrib/config-daemon.scm:1351
4899msgid ""
4900"The highest tolerable CPU load. Load here always refers to the total system "
4901"load, that is it includes CPU utilization by other processes. A value of 50 "
4902"means that once your 1 minute-load average goes over 50% non-idle, GNUnet "
4903"will try to reduce CPU consumption until the load goes under the threshold. "
4904"Reasonable values are typically between 50 and 100. Multiprocessors may use "
4905"values above 100."
4906msgstr ""
4907
4908#: contrib/config-daemon.scm:1362
4909msgid "What is the maximum IO load (permille)?"
4910msgstr ""
4911
4912#: contrib/config-daemon.scm:1364
4913msgid ""
4914"The highest tolerable IO load. Load here refers to the percentage of CPU "
4915"cycles wasted waiting for IO for the entire system, that is it includes disk "
4916"utilization by other processes. A value of 10 means that once the average "
4917"number of cycles wasted waiting for IO is more than 10% non-idle, GNUnet "
4918"will try to reduce IO until the load goes under the threshold. Reasonable "
4919"values are typically between 10 and 75."
4920msgstr ""
4921
4922#: contrib/config-daemon.scm:1375
4923msgid "What is the maximum CPU load (hard limit)?"
4924msgstr ""
4925
4926#: contrib/config-daemon.scm:1376
4927msgid ""
4928"The highest tolerable CPU load. This is the hard limit, so once it is "
4929"reached, gnunetd will start to massively drop data to reduce the load. Use "
4930"with caution."
4931msgstr ""
4932
4933#: contrib/config-daemon.scm:1387
4934msgid "What is the maximum upstream bandwidth (hard limit)?"
4935msgstr ""
4936
4937#: contrib/config-daemon.scm:1388
4938msgid ""
4939"The limit is given as a percentage of the MAXNETUPBPS limit. Use 100 to "
4940"have MAXNETUPBPS be the hard limit. Use zero for no limit."
4941msgstr ""
4942
4943#: contrib/config-daemon.scm:1400
4944msgid "What priority should gnunetd use to run?"
4945msgstr ""
4946
4947#: contrib/config-daemon.scm:1401
4948msgid ""
4949"You can specify priorities like NORMAL, ABOVE NORMAL, BELOW NORMAL, HIGH and "
4950"IDLE or a numerical integer value (man nice). The default is IDLE, which "
4951"should result in gnunetd only using resources that would otherwise be idle."
4952msgstr ""
4953
4954#: contrib/config-daemon.scm:1413
4955msgid "Should we disable random padding (experimental option)?"
4956msgstr ""
4957
4958#: contrib/config-daemon.scm:1425
4959msgid "Use basic bandwidth limitation? (YES/NO). If in doubt, say YES."
4960msgstr ""
4961
4962#: contrib/config-daemon.scm:1427
4963msgid ""
4964"Basic bandwidth limitation (YES) means simply that the bandwidth limits "
4965"specified apply to GNUnet and only to GNUnet. If set to YES, you simply "
4966"specify the maximum bandwidth (upstream and downstream) that GNUnet is "
4967"allowed to use and GNUnet will stick to those limitations. This is useful "
4968"if your overall bandwidth is so large that the limit is mostly used to "
4969"ensure that enough capacity is left for other applications. Even if you "
4970"want to dedicate your entire connection to GNUnet you should not set the "
4971"limits to values higher than what you have since GNUnet uses those limits to "
4972"determine for example the number of connections to establish (and it would "
4973"be inefficient if that computation yields a number that is far too high). \n"
4974"\n"
4975"While basic bandwidth limitation is simple and always works, there are some "
4976"situations where it is not perfect. Suppose you are running another "
4977"application which performs a larger download. During that particular time, "
4978"it would be nice if GNUnet would throttle its bandwidth consumption "
4979"(automatically) and resume using more bandwidth after the download is "
4980"complete. This is obviously advanced magic since GNUnet will have to "
4981"monitor the behavior of other applications. Another scenario is a monthly "
4982"cap on bandwidth imposed by your ISP, which you would want to ensure is "
4983"obeyed. Here, you may want GNUnet to monitor the traffic from other "
4984"applications to ensure that the combined long-term traffic is within the pre-"
4985"set bounds. Note that you should probably not set the bounds tightly since "
4986"GNUnet may observe that the bounds are about to be broken but would be "
4987"unable to stop other applications from continuing to use bandwidth.\n"
4988"\n"
4989"If either of these two scenarios applies, set BASICLIMITING to NO. Then set "
4990"the bandwidth limits to the COMBINED amount of traffic that is acceptable "
4991"for both GNUnet and other applications. GNUnet will then immediately "
4992"throttle bandwidth consumption if the short-term average is above the limit, "
4993"and it will also try to ensure that the long-term average is below the "
4994"limit. Note however that using NO can have the effect of GNUnet (almost) "
4995"ceasing operations after other applications perform high-volume downloads "
4996"that are beyond the defined limits. GNUnet would reduce consumption until "
4997"the long-term limits are again within bounds.\n"
4998"\n"
4999"NO only works on platforms where GNUnet can monitor the amount of traffic "
5000"that the local host puts out on the network. This is only implemented for "
5001"Linux and Win32. In order for the code to work, GNUnet needs to know the "
5002"specific network interface that is used for the external connection (after "
5003"all, the amount of traffic on loopback or on the LAN should never be counted "
5004"since it is irrelevant)."
5005msgstr ""
5006
5007#: contrib/config-daemon.scm:1444
5008msgid "Network interface to monitor"
5009msgstr ""
5010
5011#: contrib/config-daemon.scm:1445
5012msgid ""
5013"For which interfaces should we do accounting? GNUnet will evaluate the "
5014"total traffic (not only the GNUnet related traffic) and adjust its bandwidth "
5015"usage accordingly. You can currently only specify a single interface. GNUnet "
5016"will also use this interface to determine the IP to use. Typical values are "
5017"eth0, ppp0, eth1, wlan0, etc. 'ifconfig' will tell you what you have. "
5018"Never use 'lo', that just won't work. Under Windows, specify the index "
5019"number reported by 'gnunet-win-tool -n'."
5020msgstr ""
5021
5022#: contrib/config-daemon.scm:1456
5023msgid "Load management"
5024msgstr ""
5025
5026#: contrib/config-daemon.scm:1482 contrib/config-client.scm:413
5027msgid "Root node"
5028msgstr ""
5029
5030#: contrib/config-client.scm:153
5031msgid "Where should gnunet-clients write their logs?"
5032msgstr ""
5033
5034#: contrib/config-client.scm:185
5035msgid "On which machine and port is gnunetd running (for clients)?"
5036msgstr ""
5037
5038#: contrib/config-client.scm:186
5039msgid "This is equivalent to the -H option. The format is IP:PORT."
5040msgstr ""
5041
5042#: contrib/config-client.scm:197
5043msgid "What is the path to the configuration file for gnunetd?"
5044msgstr ""
5045
5046#: contrib/config-client.scm:198
5047msgid "This option is used when clients need to start gnunetd."
5048msgstr ""
5049
5050#: contrib/config-client.scm:210
5051msgid "General options"
5052msgstr ""
5053
5054#: contrib/config-client.scm:227
5055msgid "Do not add metadata listing the creation time for inserted content"
5056msgstr ""
5057
5058#: contrib/config-client.scm:239
5059msgid "Which non-default extractors should GNUnet use for keyword extractors"
5060msgstr ""
5061
5062#: contrib/config-client.scm:240
5063msgid ""
5064"Specify which additional extractor libraries should be used. gnunet-insert "
5065"uses libextractor to extract keywords from files. libextractor can be "
5066"dynamically extended to handle additional file formats. If you want to use "
5067"more than the default set of extractors, specify additional extractor "
5068"libraries here. The format is [[-]LIBRARYNAME[:[-]LIBRARYNAME]*].\n"
5069"\n"
5070"The default is to use filenames and to break larger words at spaces (and "
5071"underscores, etc.). This should be just fine for most people. The '-' "
5072"before a library name indicates that this should be executed last and makes "
5073"only sense for the split-library."
5074msgstr ""
5075
5076#: contrib/config-client.scm:253
5077msgid "How many entries should the URI DB table have?"
5078msgstr ""
5079
5080#: contrib/config-client.scm:254
5081msgid ""
5082"GNUnet uses two bytes per entry on the disk. This database is used to keep "
5083"track of how a particular URI has been used in the past. For example, "
5084"GNUnet may remember that a particular URI has been found in a search "
5085"previously or corresponds to a file uploaded by the user. This information "
5086"can then be used by user-interfaces to filter URI lists, such as search "
5087"results. If the database is full, older entries will be discarded. The "
5088"default value should be sufficient without causing undue disk utilization."
5089msgstr ""
5090
5091#: contrib/config-client.scm:265
5092msgid "Location of the file specifying metadata for the auto-share directory"
5093msgstr ""
5094
5095#: contrib/config-client.scm:277
5096msgid ""
5097"Location of the file with the PID of any running gnunet-auto-share daemon "
5098"process"
5099msgstr ""
5100
5101#: contrib/config-client.scm:289
5102msgid "Location of the log file for gnunet-auto-share"
5103msgstr ""
5104
5105#: contrib/config-client.scm:301
5106msgid "File-Sharing options"
5107msgstr ""
5108
5109#: contrib/config-client.scm:319
5110msgid "Which plugins should be loaded by gnunet-gtk?"
5111msgstr ""
5112
5113#: contrib/config-client.scm:320
5114msgid ""
5115"Load the about plugin for the about dialog. The daemon plugin allows "
5116"starting and stopping of gnunetd and displays information about gnunetd. "
5117"The fs plugin provides the file-sharing functionality. The stats plugin "
5118"displays various statistics about gnunetd."
5119msgstr ""
5120
5121#: contrib/config-client.scm:331
5122msgid "How frequently (in milli-seconds) should the statistics update?"
5123msgstr ""
5124
5125#: contrib/config-client.scm:332
5126msgid ""
5127"Each pixel in the stats dialog corresponds to the time interval specified "
5128"here."
5129msgstr ""
5130
5131#: contrib/config-client.scm:344
5132msgid "Do not show thumbnail previews from meta-data in search results"
5133msgstr ""
5134
5135#: contrib/config-client.scm:345
5136msgid ""
5137"This option is useful for people who maybe offended by some previews or use "
5138"gnunet-gtk at work and would like to avoid bad surprises."
5139msgstr ""
5140
5141#: contrib/config-client.scm:356
5142msgid "Do not show search results for files that were uploaded by us"
5143msgstr ""
5144
5145#: contrib/config-client.scm:357
5146msgid ""
5147"This option is useful to eliminate files that the user already has from the "
5148"search. Naturally, enabling this option maybe confusing because some "
5149"obviously expected search results would no longer show up. This option only "
5150"works if the URI_DB_SIZE option under FS is not zero (since the URI DB is "
5151"used to determine which files the user is sharing)"
5152msgstr ""
5153
5154#: contrib/config-client.scm:369
5155msgid "To which directory should gnunet-gtk save downloads to?"
5156msgstr ""
5157
5158#: contrib/config-client.scm:381
5159msgid "Options related to gnunet-gtk"
5160msgstr ""
5161
5162#: contrib/config-client.scm:401
5163msgid "Full pathname of GNUnet client HOME directory"
5164msgstr ""
5165
5166#: contrib/config-client.scm:402
5167msgid "The directory for GNUnet files that belong to the user."
5168msgstr ""
diff --git a/po/LINGUAS b/po/LINGUAS
new file mode 100644
index 000000000..07778ccfd
--- /dev/null
+++ b/po/LINGUAS
@@ -0,0 +1,2 @@
1# set of available languages
2vi de sv es
diff --git a/po/Makefile.in.in b/po/Makefile.in.in
new file mode 100644
index 000000000..5022b8b18
--- /dev/null
+++ b/po/Makefile.in.in
@@ -0,0 +1,403 @@
1# Makefile for PO directory in any package using GNU gettext.
2# Copyright (C) 1995-1997, 2000-2006 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
3#
4# This file can be copied and used freely without restrictions. It can
5# be used in projects which are not available under the GNU General Public
6# License but which still want to provide support for the GNU gettext
7# functionality.
8# Please note that the actual code of GNU gettext is covered by the GNU
9# General Public License and is *not* in the public domain.
10#
11# Origin: gettext-0.16
12
13PACKAGE = @PACKAGE@
14VERSION = @VERSION@
15PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
16
17SHELL = /bin/sh
18@SET_MAKE@
19
20srcdir = @srcdir@
21top_srcdir = @top_srcdir@
22VPATH = @srcdir@
23
24prefix = @prefix@
25exec_prefix = @exec_prefix@
26datarootdir = @datarootdir@
27datadir = @datadir@
28localedir = @localedir@
29gettextsrcdir = $(datadir)/gettext/po
30
31INSTALL = @INSTALL@
32INSTALL_DATA = @INSTALL_DATA@
33
34# We use $(mkdir_p).
35# In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as
36# "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions,
37# @install_sh@ does not start with $(SHELL), so we add it.
38# In automake >= 1.10, @mkdir_p@ is derived from ${MKDIR_P}, which is defined
39# either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake
40# versions, $(mkinstalldirs) and $(install_sh) are unused.
41mkinstalldirs = $(SHELL) @install_sh@ -d
42install_sh = $(SHELL) @install_sh@
43MKDIR_P = @MKDIR_P@
44mkdir_p = @mkdir_p@
45
46GMSGFMT_ = @GMSGFMT@
47GMSGFMT_no = @GMSGFMT@
48GMSGFMT_yes = @GMSGFMT_015@
49GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT))
50MSGFMT_ = @MSGFMT@
51MSGFMT_no = @MSGFMT@
52MSGFMT_yes = @MSGFMT_015@
53MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
54XGETTEXT_ = @XGETTEXT@
55XGETTEXT_no = @XGETTEXT@
56XGETTEXT_yes = @XGETTEXT_015@
57XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
58MSGMERGE = msgmerge
59MSGMERGE_UPDATE = @MSGMERGE@ --update
60MSGINIT = msginit
61MSGCONV = msgconv
62MSGFILTER = msgfilter
63
64POFILES = @POFILES@
65GMOFILES = @GMOFILES@
66UPDATEPOFILES = @UPDATEPOFILES@
67DUMMYPOFILES = @DUMMYPOFILES@
68DISTFILES.common = Makefile.in.in remove-potcdate.sin \
69$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3)
70DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \
71$(POFILES) $(GMOFILES) \
72$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3)
73
74POTFILES = \
75
76CATALOGS = @CATALOGS@
77
78# Makevars gets inserted here. (Don't remove this line!)
79
80.SUFFIXES:
81.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update
82
83.po.mo:
84 @echo "$(MSGFMT) -c -o $@ $<"; \
85 $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@
86
87.po.gmo:
88 @lang=`echo $* | sed -e 's,.*/,,'`; \
89 test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
90 echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o $${lang}.gmo $${lang}.po"; \
91 cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
92
93.sin.sed:
94 sed -e '/^#/d' $< > t-$@
95 mv t-$@ $@
96
97
98all: all-@USE_NLS@
99
100all-yes: stamp-po
101all-no:
102
103# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no
104# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because
105# we don't want to bother translators with empty POT files). We assume that
106# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty.
107# In this case, stamp-po is a nop (i.e. a phony target).
108
109# stamp-po is a timestamp denoting the last time at which the CATALOGS have
110# been loosely updated. Its purpose is that when a developer or translator
111# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS,
112# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent
113# invocations of "make" will do nothing. This timestamp would not be necessary
114# if updating the $(CATALOGS) would always touch them; however, the rule for
115# $(POFILES) has been designed to not touch files that don't need to be
116# changed.
117stamp-po: $(srcdir)/$(DOMAIN).pot
118 test ! -f $(srcdir)/$(DOMAIN).pot || \
119 test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
120 @test ! -f $(srcdir)/$(DOMAIN).pot || { \
121 echo "touch stamp-po" && \
122 echo timestamp > stamp-poT && \
123 mv stamp-poT stamp-po; \
124 }
125
126# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update',
127# otherwise packages like GCC can not be built if only parts of the source
128# have been downloaded.
129
130# This target rebuilds $(DOMAIN).pot; it is an expensive operation.
131# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed.
132$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed
133 if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \
134 msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \
135 else \
136 msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \
137 fi; \
138 $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
139 --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \
140 --files-from=$(srcdir)/POTFILES.in \
141 --copyright-holder='$(COPYRIGHT_HOLDER)' \
142 --msgid-bugs-address="$$msgid_bugs_address"
143 test ! -f $(DOMAIN).po || { \
144 if test -f $(srcdir)/$(DOMAIN).pot; then \
145 sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \
146 sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \
147 if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \
148 rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \
149 else \
150 rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \
151 mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \
152 fi; \
153 else \
154 mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \
155 fi; \
156 }
157
158# This rule has no dependencies: we don't need to update $(DOMAIN).pot at
159# every "make" invocation, only create it when it is missing.
160# Only "make $(DOMAIN).pot-update" or "make dist" will force an update.
161$(srcdir)/$(DOMAIN).pot:
162 $(MAKE) $(DOMAIN).pot-update
163
164# This target rebuilds a PO file if $(DOMAIN).pot has changed.
165# Note that a PO file is not touched if it doesn't need to be changed.
166$(POFILES): $(srcdir)/$(DOMAIN).pot
167 @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
168 if test -f "$(srcdir)/$${lang}.po"; then \
169 test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
170 echo "$${cdcmd}$(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot"; \
171 cd $(srcdir) && $(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot; \
172 else \
173 $(MAKE) $${lang}.po-create; \
174 fi
175
176
177install: install-exec install-data
178install-exec:
179install-data: install-data-@USE_NLS@
180 if test "$(PACKAGE)" = "gettext-tools"; then \
181 $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \
182 for file in $(DISTFILES.common) Makevars.template; do \
183 $(INSTALL_DATA) $(srcdir)/$$file \
184 $(DESTDIR)$(gettextsrcdir)/$$file; \
185 done; \
186 for file in Makevars; do \
187 rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
188 done; \
189 else \
190 : ; \
191 fi
192install-data-no: all
193install-data-yes: all
194 $(mkdir_p) $(DESTDIR)$(datadir)
195 @catalogs='$(CATALOGS)'; \
196 for cat in $$catalogs; do \
197 cat=`basename $$cat`; \
198 lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
199 dir=$(localedir)/$$lang/LC_MESSAGES; \
200 $(mkdir_p) $(DESTDIR)$$dir; \
201 if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \
202 $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \
203 echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \
204 for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
205 if test -n "$$lc"; then \
206 if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
207 link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
208 mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
209 mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
210 (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
211 for file in *; do \
212 if test -f $$file; then \
213 ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
214 fi; \
215 done); \
216 rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
217 else \
218 if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
219 :; \
220 else \
221 rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
222 mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
223 fi; \
224 fi; \
225 rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
226 ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
227 ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
228 cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
229 echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \
230 fi; \
231 done; \
232 done
233
234install-strip: install
235
236installdirs: installdirs-exec installdirs-data
237installdirs-exec:
238installdirs-data: installdirs-data-@USE_NLS@
239 if test "$(PACKAGE)" = "gettext-tools"; then \
240 $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \
241 else \
242 : ; \
243 fi
244installdirs-data-no:
245installdirs-data-yes:
246 $(mkdir_p) $(DESTDIR)$(datadir)
247 @catalogs='$(CATALOGS)'; \
248 for cat in $$catalogs; do \
249 cat=`basename $$cat`; \
250 lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
251 dir=$(localedir)/$$lang/LC_MESSAGES; \
252 $(mkdir_p) $(DESTDIR)$$dir; \
253 for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
254 if test -n "$$lc"; then \
255 if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
256 link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
257 mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
258 mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
259 (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
260 for file in *; do \
261 if test -f $$file; then \
262 ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
263 fi; \
264 done); \
265 rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
266 else \
267 if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
268 :; \
269 else \
270 rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
271 mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
272 fi; \
273 fi; \
274 fi; \
275 done; \
276 done
277
278# Define this as empty until I found a useful application.
279installcheck:
280
281uninstall: uninstall-exec uninstall-data
282uninstall-exec:
283uninstall-data: uninstall-data-@USE_NLS@
284 if test "$(PACKAGE)" = "gettext-tools"; then \
285 for file in $(DISTFILES.common) Makevars.template; do \
286 rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
287 done; \
288 else \
289 : ; \
290 fi
291uninstall-data-no:
292uninstall-data-yes:
293 catalogs='$(CATALOGS)'; \
294 for cat in $$catalogs; do \
295 cat=`basename $$cat`; \
296 lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
297 for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \
298 rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
299 done; \
300 done
301
302check: all
303
304info dvi ps pdf html tags TAGS ctags CTAGS ID:
305
306mostlyclean:
307 rm -f remove-potcdate.sed
308 rm -f stamp-poT
309 rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po
310 rm -fr *.o
311
312clean: mostlyclean
313
314distclean: clean
315 rm -f Makefile Makefile.in POTFILES *.mo
316
317maintainer-clean: distclean
318 @echo "This command is intended for maintainers to use;"
319 @echo "it deletes files that may require special tools to rebuild."
320 rm -f stamp-po $(GMOFILES)
321
322distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
323dist distdir:
324 $(MAKE) update-po
325 @$(MAKE) dist2
326# This is a separate target because 'update-po' must be executed before.
327dist2: stamp-po $(DISTFILES)
328 dists="$(DISTFILES)"; \
329 if test "$(PACKAGE)" = "gettext-tools"; then \
330 dists="$$dists Makevars.template"; \
331 fi; \
332 if test -f $(srcdir)/$(DOMAIN).pot; then \
333 dists="$$dists $(DOMAIN).pot stamp-po"; \
334 fi; \
335 if test -f $(srcdir)/ChangeLog; then \
336 dists="$$dists ChangeLog"; \
337 fi; \
338 for i in 0 1 2 3 4 5 6 7 8 9; do \
339 if test -f $(srcdir)/ChangeLog.$$i; then \
340 dists="$$dists ChangeLog.$$i"; \
341 fi; \
342 done; \
343 if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \
344 for file in $$dists; do \
345 if test -f $$file; then \
346 cp -p $$file $(distdir) || exit 1; \
347 else \
348 cp -p $(srcdir)/$$file $(distdir) || exit 1; \
349 fi; \
350 done
351
352update-po: Makefile
353 $(MAKE) $(DOMAIN).pot-update
354 test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES)
355 $(MAKE) update-gmo
356
357# General rule for creating PO files.
358
359.nop.po-create:
360 @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \
361 echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \
362 exit 1
363
364# General rule for updating PO files.
365
366.nop.po-update:
367 @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \
368 if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \
369 tmpdir=`pwd`; \
370 echo "$$lang:"; \
371 test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
372 echo "$${cdcmd}$(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \
373 cd $(srcdir); \
374 if $(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$tmpdir/$$lang.new.po; then \
375 if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
376 rm -f $$tmpdir/$$lang.new.po; \
377 else \
378 if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
379 :; \
380 else \
381 echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
382 exit 1; \
383 fi; \
384 fi; \
385 else \
386 echo "msgmerge for $$lang.po failed!" 1>&2; \
387 rm -f $$tmpdir/$$lang.new.po; \
388 fi
389
390$(DUMMYPOFILES):
391
392update-gmo: Makefile $(GMOFILES)
393 @:
394
395Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@
396 cd $(top_builddir) \
397 && $(SHELL) ./config.status $(subdir)/$@.in po-directories
398
399force:
400
401# Tell versions [3.59,3.63) of GNU make not to export all variables.
402# Otherwise a system limit (for SysV at least) may be exceeded.
403.NOEXPORT:
diff --git a/po/Makevars b/po/Makevars
new file mode 100644
index 000000000..085957181
--- /dev/null
+++ b/po/Makevars
@@ -0,0 +1,41 @@
1# Makefile variables for PO directory in any package using GNU gettext.
2
3# Usually the message domain is the same as the package name.
4DOMAIN = $(PACKAGE)
5
6# These two variables depend on the location of this directory.
7subdir = po
8top_builddir = ..
9
10# These options get passed to xgettext.
11XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
12
13# This is the copyright holder that gets inserted into the header of the
14# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
15# package. (Note that the msgstr strings, extracted from the package's
16# sources, belong to the copyright holder of the package.) Translators are
17# expected to transfer the copyright for their translations to this person
18# or entity, or to disclaim their copyright. The empty string stands for
19# the public domain; in this case the translators are expected to disclaim
20# their copyright.
21COPYRIGHT_HOLDER = Christian Grothoff
22
23# This is the email address or URL to which the translators shall report
24# bugs in the untranslated strings:
25# - Strings which are not entire sentences, see the maintainer guidelines
26# in the GNU gettext documentation, section 'Preparing Strings'.
27# - Strings which use unclear terms or require additional context to be
28# understood.
29# - Strings which make invalid assumptions about notation of date, time or
30# money.
31# - Pluralisation problems.
32# - Incorrect English spelling.
33# - Incorrect formatting.
34# It can be your email address, or a mailing list address where translators
35# can write to without being subscribed, or the URL of a web page through
36# which the translators can contact you.
37MSGID_BUGS_ADDRESS = gnunet-developers@mail.gnu.org
38
39# This is the list of locale categories, beyond LC_MESSAGES, for which the
40# message catalogs shall be used. It is usually empty.
41EXTRA_LOCALE_CATEGORIES =
diff --git a/po/Makevars.template b/po/Makevars.template
new file mode 100644
index 000000000..32692ab4b
--- /dev/null
+++ b/po/Makevars.template
@@ -0,0 +1,41 @@
1# Makefile variables for PO directory in any package using GNU gettext.
2
3# Usually the message domain is the same as the package name.
4DOMAIN = $(PACKAGE)
5
6# These two variables depend on the location of this directory.
7subdir = po
8top_builddir = ..
9
10# These options get passed to xgettext.
11XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
12
13# This is the copyright holder that gets inserted into the header of the
14# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
15# package. (Note that the msgstr strings, extracted from the package's
16# sources, belong to the copyright holder of the package.) Translators are
17# expected to transfer the copyright for their translations to this person
18# or entity, or to disclaim their copyright. The empty string stands for
19# the public domain; in this case the translators are expected to disclaim
20# their copyright.
21COPYRIGHT_HOLDER = Free Software Foundation, Inc.
22
23# This is the email address or URL to which the translators shall report
24# bugs in the untranslated strings:
25# - Strings which are not entire sentences, see the maintainer guidelines
26# in the GNU gettext documentation, section 'Preparing Strings'.
27# - Strings which use unclear terms or require additional context to be
28# understood.
29# - Strings which make invalid assumptions about notation of date, time or
30# money.
31# - Pluralisation problems.
32# - Incorrect English spelling.
33# - Incorrect formatting.
34# It can be your email address, or a mailing list address where translators
35# can write to without being subscribed, or the URL of a web page through
36# which the translators can contact you.
37MSGID_BUGS_ADDRESS =
38
39# This is the list of locale categories, beyond LC_MESSAGES, for which the
40# message catalogs shall be used. It is usually empty.
41EXTRA_LOCALE_CATEGORIES =
diff --git a/po/POTFILES.in b/po/POTFILES.in
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/po/POTFILES.in
diff --git a/po/Rules-quot b/po/Rules-quot
new file mode 100644
index 000000000..9c2a995e3
--- /dev/null
+++ b/po/Rules-quot
@@ -0,0 +1,47 @@
1# Special Makefile rules for English message catalogs with quotation marks.
2
3DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot
4
5.SUFFIXES: .insert-header .po-update-en
6
7en@quot.po-create:
8 $(MAKE) en@quot.po-update
9en@boldquot.po-create:
10 $(MAKE) en@boldquot.po-update
11
12en@quot.po-update: en@quot.po-update-en
13en@boldquot.po-update: en@boldquot.po-update-en
14
15.insert-header.po-update-en:
16 @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \
17 if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \
18 tmpdir=`pwd`; \
19 echo "$$lang:"; \
20 ll=`echo $$lang | sed -e 's/@.*//'`; \
21 LC_ALL=C; export LC_ALL; \
22 cd $(srcdir); \
23 if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$ll -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \
24 if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
25 rm -f $$tmpdir/$$lang.new.po; \
26 else \
27 if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
28 :; \
29 else \
30 echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
31 exit 1; \
32 fi; \
33 fi; \
34 else \
35 echo "creation of $$lang.po failed!" 1>&2; \
36 rm -f $$tmpdir/$$lang.new.po; \
37 fi
38
39en@quot.insert-header: insert-header.sin
40 sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header
41
42en@boldquot.insert-header: insert-header.sin
43 sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header
44
45mostlyclean: mostlyclean-quot
46mostlyclean-quot:
47 rm -f *.insert-header
diff --git a/po/boldquot.sed b/po/boldquot.sed
new file mode 100644
index 000000000..4b937aa51
--- /dev/null
+++ b/po/boldquot.sed
@@ -0,0 +1,10 @@
1s/"\([^"]*\)"/“\1â€/g
2s/`\([^`']*\)'/‘\1’/g
3s/ '\([^`']*\)' / ‘\1’ /g
4s/ '\([^`']*\)'$/ ‘\1’/g
5s/^'\([^`']*\)' /‘\1’ /g
6s/“â€/""/g
7s/“/“/g
8s/â€/â€/g
9s/‘/‘/g
10s/’/’/g
diff --git a/po/de.gmo b/po/de.gmo
new file mode 100644
index 000000000..c3cd1fde4
--- /dev/null
+++ b/po/de.gmo
Binary files differ
diff --git a/po/de.po b/po/de.po
new file mode 100644
index 000000000..b1e089b98
--- /dev/null
+++ b/po/de.po
@@ -0,0 +1,7387 @@
1# German translations for GNUnet package
2# German messages for GNUnet.
3# Copyright (C) 2004, 2005 Christian Grothoff
4# This file is distributed under the same license as the GNUnet package.
5# Christian Grothoff <christian@grothoff.org>, 2004, 2005.
6msgid ""
7msgstr ""
8"Project-Id-Version: GNUnet 0.7.0b\n"
9"Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n"
10"POT-Creation-Date: 2009-01-08 10:55-0700\n"
11"PO-Revision-Date: 2006-03-17 21:37+0100\n"
12"Last-Translator: Nils Durner <durner@gnunet.org>\n"
13"Language-Team: German <de@li.org>\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=(n != 1);\n"
18
19#: src/setup/ncurses/wizard_curs.c:72 src/setup/lib/wizard_util.c:155
20#: src/setup/lib/wizard_util.c:210
21msgid "Error"
22msgstr "Fehler"
23
24#: src/setup/ncurses/wizard_curs.c:80
25msgid "Help"
26msgstr "Hilfe"
27
28#: src/setup/ncurses/wizard_curs.c:87
29#, fuzzy
30msgid "Error!"
31msgstr "Fehler"
32
33#: src/setup/ncurses/wizard_curs.c:101 src/applications/vpn/cs.c:94
34msgid "No"
35msgstr "Nein"
36
37#: src/setup/ncurses/wizard_curs.c:102 src/applications/vpn/cs.c:94
38msgid "Yes"
39msgstr "Ja"
40
41#: src/setup/ncurses/wizard_curs.c:118 src/setup/ncurses/wizard_curs.c:183
42#: src/setup/ncurses/wizard_curs.c:299 src/setup/ncurses/mconf.c:189
43#: src/setup/ncurses/mconf.c:285 src/setup/ncurses/mconf.c:365
44#: src/setup/ncurses/mconf.c:456
45msgid "Internal error! (Choice invalid?)"
46msgstr ""
47
48#: src/setup/ncurses/wizard_curs.c:150
49#, fuzzy
50msgid "Abort"
51msgstr "_über"
52
53#: src/setup/ncurses/wizard_curs.c:151
54#, fuzzy
55msgid "Ok"
56msgstr "k"
57
58#: src/setup/ncurses/wizard_curs.c:218 src/setup/ncurses/wizard_curs.c:284
59#: src/setup/ncurses/wizard_curs.c:425
60msgid "GNUnet configuration"
61msgstr "GNUnet Konfiguration"
62
63#: src/setup/ncurses/wizard_curs.c:220
64msgid ""
65"Welcome to GNUnet!\n"
66"\n"
67"This assistant will ask you a few basic questions in order to configure "
68"GNUnet.\n"
69"\n"
70"Please visit our homepage at\n"
71"\thttp://gnunet.org/\n"
72"and join our community at\n"
73"\thttp://gnunet.org/drupal/\n"
74"\n"
75"Have a lot of fun,\n"
76"\n"
77"the GNUnet team"
78msgstr ""
79"Willkommen bei GNUnet!\n"
80"\n"
81"Dieser Assistent wird Ihnen einige grundlegende Fragen stellen, um GNUnet zu "
82"konfigurieren.\n"
83"\n"
84"Bitte besuchen Sie unsere Homepage\n"
85"\thttp://gnunet.org\n"
86"und schließen Sie sich unserer Community an:\n"
87"\thttps://gnunet.org/drupal/\n"
88"\n"
89"Viel Spaß,\n"
90"\n"
91"das GNUnet-Team"
92
93#: src/setup/ncurses/wizard_curs.c:286
94msgid ""
95"Choose the network interface that connects your computer to the internet "
96"from the list below."
97msgstr ""
98"Wählen Sie das Netzwerkgerät, das Ihren Computer mit dem Internet verbindet, "
99"aus unten stehender Liste."
100
101#: src/setup/ncurses/wizard_curs.c:304 src/setup/ncurses/wizard_curs.c:318
102msgid ""
103"The \"Network interface\" is the device that connects your computer to the "
104"internet. This is usually a modem, an ISDN card or a network card in case "
105"you are using DSL."
106msgstr ""
107"Das \"Netzwerkgerät\" ist das Gerät, das Ihren Computer mit dem Internet "
108"verbindet. Dies ist üblicherweise ein Modem, eine ISDN-Karte oder eine "
109"Netzwerkkarte falls Sie DSL nutzen."
110
111#: src/setup/ncurses/wizard_curs.c:315
112#, fuzzy
113msgid "Network configuration: interface"
114msgstr "Netzwerkgerät:"
115
116#: src/setup/ncurses/wizard_curs.c:317
117msgid ""
118"What is the name of the network interface that connects your computer to the "
119"Internet?"
120msgstr ""
121"Was ist der Name des Netzwerkgerätes, das Ihren Computer mit dem Internet "
122"verbindet?"
123
124#: src/setup/ncurses/wizard_curs.c:328
125#, fuzzy
126msgid "Network configuration: IP"
127msgstr "GNUnet Konfiguration"
128
129#: src/setup/ncurses/wizard_curs.c:330
130#, fuzzy
131msgid "What is this computer's public IP address or hostname?"
132msgstr ""
133"Wie heißt die öffentliche IP-Adresse oder der öffentliche Name dieses "
134"Computers?\n"
135"Wenn Sie nicht sicher sind, lassen Sie dieses Feld leer."
136
137#: src/setup/ncurses/wizard_curs.c:331
138#, fuzzy
139msgid ""
140"If your provider always assigns the same IP-Address to you (a \"static\" IP-"
141"Address), enter it into the \"IP-Address\" field. If your IP-Address changes "
142"every now and then (\"dynamic\" IP-Address) but there's a hostname that "
143"always points to your actual IP-Address (\"Dynamic DNS\"), you can also "
144"enter it here.\n"
145"If left empty, GNUnet will try to automatically detect the IP.\n"
146"You can specify a hostname, GNUnet will then use DNS to resolve it.\n"
147"If in doubt, leave this empty."
148msgstr ""
149"Wenn Ihr Provider Ihnen immer die gleiche IP-Adresse zuweist (eine "
150"\"statische\" IP-Adresse), so geben Sie diese in das \"IP-Adresse\"-Feld "
151"ein. Wenn sich Ihre IP-Adresse immer wieder ändert (\"dynamische\" IP-"
152"Adresse), es jedoch einen Rechnernamen gibt, der immer auf Ihre aktuelle IP-"
153"Adresse verweist, so können Sie diesen ebenfalls eintragen.\n"
154"Wenn Sie nicht sicher sind, so können Sie das Feld leer lassen. GNUnet wird "
155"dann versuchen, Ihre IP-Adresse automatisch zu bestimmen."
156
157#: src/setup/ncurses/wizard_curs.c:346
158#, fuzzy
159msgid "Bandwidth configuration: upload"
160msgstr "GNUnet Konfiguration"
161
162#: src/setup/ncurses/wizard_curs.c:348
163#, fuzzy
164msgid "How much upstream bandwidth (in bytes/s) may be used?"
165msgstr "Wieviel Upstream (Bytes/s) darf verwendet werden?"
166
167#: src/setup/ncurses/wizard_curs.c:349
168#, fuzzy
169msgid ""
170"You can limit GNUnet's resource usage here.\n"
171"\n"
172"The \"upstream\" is the data channel through which data is *sent* to the "
173"internet. The limit is the maximum amount which GNUnet is allowed to use. If "
174"you have a flatrate, you can set it to the maximum speed of your internet "
175"connection. You should not use a value that is higher than what your actual "
176"connection allows."
177msgstr ""
178"Hier können Sie GNUnets Ressourcenverwendung einschränken.\n"
179"\n"
180"Der \"Upstream\" ist der Datenkanal, durch den Daten an das Internet "
181"*gesendet* werden. Das Limit ist entweder das gesamte Maximum für diesem "
182"Computer oder wieviel GNUnet selbst verwenden darf. Dies können Sie später "
183"festlegen. Wenn Sie eine Flatrate haben, können Sie die maximale "
184"Geschwindigkeit Ihrer Internetverbindung angeben."
185
186#: src/setup/ncurses/wizard_curs.c:361
187#, fuzzy
188msgid "Bandwidth configuration: download"
189msgstr "GNUnet Konfiguration"
190
191#: src/setup/ncurses/wizard_curs.c:363
192#, fuzzy
193msgid "How much downstream bandwidth (in bytes/s) may be used?"
194msgstr "Wieviel Downstream (Bytes/s) darf verwendet werden?"
195
196#: src/setup/ncurses/wizard_curs.c:364
197#, fuzzy
198msgid ""
199"You can limit GNUnet's resource usage here.\n"
200"\n"
201"The \"downstream\" is the data channel through which data is *received* from "
202"the internet. The limit is the maximum amount which GNUnet is allowed to "
203"use. If you have a flatrate, you can set it to the maximum speed of your "
204"internet connection. You should not use a value that is higher than what "
205"your actual connection allows."
206msgstr ""
207"Hier können Sie GNUnets Ressourcenverwendung einschränken.\n"
208"\n"
209"Der \"Downstream\" ist der Datenkanal, durch den Daten vom Internet "
210"*empfangen* werden. Das Limit ist entweder das gesamte Maximum für diesem "
211"Computer oder wieviel GNUnet selbst verwenden darf. Dies können Sie später "
212"festlegen. Wenn Sie eine Flatrate haben, können Sie die maximale "
213"Geschwindigkeit Ihrer Internetverbindung angeben."
214
215#: src/setup/ncurses/wizard_curs.c:376
216#, fuzzy
217msgid "Quota configuration"
218msgstr "GNUnet Konfiguration"
219
220#: src/setup/ncurses/wizard_curs.c:377
221msgid "What is the maximum size of the datastore in MB?"
222msgstr ""
223
224#: src/setup/ncurses/wizard_curs.c:378
225#, fuzzy
226msgid ""
227"The GNUnet datastore contains all content that GNUnet needs to store "
228"(indexed, inserted and migrated content)."
229msgstr ""
230"Was ist die maximale Größe des GNUnet Datenspeichers (in MB)?\n"
231"Der GNUnet Datenspeicher enthält alle Daten, die GNUnet erzeugt (Indexdaten, "
232"eingefügte und migrierte Inhalte)."
233
234#: src/setup/ncurses/wizard_curs.c:390
235#, fuzzy
236msgid "Daemon configuration: user account"
237msgstr "Fehler beim Anlegen des Benutzerkontos:"
238
239#: src/setup/ncurses/wizard_curs.c:391
240msgid "As which user should gnunetd be run?"
241msgstr ""
242
243#: src/setup/ncurses/wizard_curs.c:393
244#, fuzzy
245msgid ""
246"For security reasons, it is a good idea to let this setup create a new user "
247"account under which the GNUnet service is started at system startup.\n"
248"\n"
249"However, GNUnet may not be able to access files other than its own. This "
250"includes files you want to publish in GNUnet. You'll have to grant read "
251"permissions to the user specified below.\n"
252"\n"
253"Leave the field empty to run GNUnet with system privileges.\n"
254msgstr ""
255"Geben Sie den Benutzer an, dem der GNUnet Dienst gehören soll.\n"
256"\n"
257"Aus Sicherheitsgründen ist es eine gute Idee, dieses Setup ein neues "
258"Benutzerkonto anlegen zu lassen, unter dem der GNUnet Dienst beim "
259"Systemstart läuft.\n"
260"\n"
261"Natürlich kann GNUnet dann nur auf seine eigenen Dateien zugreifen. Dies "
262"betrifft auch Dateien, die Sie im GNUnet veröffentlichen möchten. Sie müssen "
263"dann dem unten angegebenen Benutzerkonto zuerst Leseberechtigungen geben.\n"
264"\n"
265"Lassen Sie dieses Feld leer, wenn Sie GNUnet mit Systemprivilegien laufen "
266"lassen möchten.\n"
267"\n"
268"GNUnet Benutzer:"
269
270#: src/setup/ncurses/wizard_curs.c:410
271msgid "Daemon configuration: group account"
272msgstr ""
273
274#: src/setup/ncurses/wizard_curs.c:411
275msgid "As which group should gnunetd be run?"
276msgstr ""
277
278#: src/setup/ncurses/wizard_curs.c:413
279#, fuzzy
280msgid ""
281"For security reasons, it is a good idea to let this setup create a new group "
282"for the chosen user account.\n"
283"\n"
284"You can also specify a already existent group here.\n"
285"\n"
286"Only members of this group will be allowed to start and stop the the GNUnet "
287"server and have access to GNUnet server data.\n"
288msgstr ""
289"Definieren Sie eine Gruppe, der der GNUnet Dienst gehört.\n"
290"\n"
291"Aus Sicherheitsgründen ist es eine gute Idee, dieses Setup eine neue Gruppe "
292"für das gewählte Benutzerkonto anlegen zu lassen.\n"
293"\n"
294"Sie können hier auch eine bestehende Gruppe angeben.\n"
295"\n"
296"Nur Mitglieder dieser Gruppe dürfen den GNUnet Server starten und anhalten "
297"und haben Zugriff auf die Daten des GNUnet Servers.\n"
298"\n"
299"GNUnet Gruppe:"
300
301#: src/setup/ncurses/wizard_curs.c:427
302msgid "Do you want to automatically launch GNUnet as a system service?"
303msgstr ""
304
305#: src/setup/ncurses/wizard_curs.c:429
306#, fuzzy
307msgid ""
308"If you say \"yes\" here, the GNUnet background process will be automatically "
309"started when you turn on your computer. If you say \"no\" here, you have to "
310"launch GNUnet yourself each time you want to use it."
311msgstr ""
312"Möchten Sie GNUnet als Systemdienst starten?\n"
313"\n"
314"Wenn Sie hier \"Ja\" sagen, so wird der GNUnet Hintergrundprozess jedesmal "
315"automatisch gestartet, wenn Sie Ihren Computer einschalten. Wenn Sie hier "
316"\"Nein\" sagen, so müssen Sie GNUnet jedesmal selbst starten, wenn Sie es "
317"verwenden möchten."
318
319#: src/setup/ncurses/wizard_curs.c:452 src/setup/gtk/wizard_gtk.c:414
320#, c-format
321msgid "Unable to save configuration file `%s':"
322msgstr "Fehler beim Speichern der Konfigurationsdatei `%s':"
323
324#: src/setup/ncurses/wizard_curs.c:472
325#, fuzzy
326msgid "Unable to create user account for daemon."
327msgstr "Fehler beim Anlegen des Benutzerkontos:"
328
329#: src/setup/ncurses/wizard_curs.c:483
330msgid "Unable to setup autostart for daemon."
331msgstr ""
332
333#: src/setup/ncurses/wizard_curs.c:498
334#, fuzzy
335msgid "Save configuration?"
336msgstr "GNUnet Konfiguration"
337
338#: src/setup/ncurses/wizard_curs.c:499
339#, fuzzy
340msgid "Save configuration now?"
341msgstr "GNUnet Konfiguration"
342
343#: src/setup/ncurses/wizard_curs.c:539 src/setup/ncurses/mconf.c:500
344#, fuzzy
345msgid "GNUnet Configuration"
346msgstr "GNUnet Konfiguration"
347
348#: src/setup/ncurses/wizard_curs.c:543
349msgid "Back"
350msgstr "Zurück"
351
352#: src/setup/ncurses/mconf.c:96
353msgid "Exit"
354msgstr ""
355
356#: src/setup/ncurses/mconf.c:99
357msgid "Up"
358msgstr "Oben"
359
360#: src/setup/ncurses/mconf.c:102
361msgid "Cancel"
362msgstr "Abbrechen"
363
364#: src/setup/ncurses/mconf.c:221 src/setup/ncurses/mconf.c:408
365msgid "Internal error! (Value invalid?)"
366msgstr ""
367
368#: src/setup/ncurses/mconf.c:398
369msgid "Invalid input, expecting floating point value."
370msgstr ""
371
372#: src/setup/ncurses/mconf.c:439
373msgid "Invalid input, expecting integer."
374msgstr ""
375
376#: src/setup/ncurses/mconf.c:446
377msgid "Value is not in legal range."
378msgstr ""
379
380#: src/setup/ncurses/mconf.c:512 src/setup/text/conf.c:569
381#, fuzzy, c-format
382msgid "Configuration unchanged, no need to save.\n"
383msgstr ""
384"Konfiguration oder die GNUnet Version hat sich geändert. Sie müssen `%s' "
385"ausführen!\n"
386
387#: src/setup/ncurses/mconf.c:518
388#, fuzzy
389msgid "Do you wish to save your new configuration?"
390msgstr "Möchten Sie Ihre Einstellungen speichern?"
391
392#: src/setup/ncurses/mconf.c:532
393#, fuzzy, c-format
394msgid ""
395"\n"
396"End of configuration.\n"
397msgstr " gconfig\tGTK Konfiguration\n"
398
399#: src/setup/ncurses/mconf.c:537
400#, fuzzy, c-format
401msgid ""
402"\n"
403"Your configuration changes were NOT saved.\n"
404msgstr "Konfigurationsdatei `%s' wurde erzeugt.\n"
405
406#: src/setup/gnunet-win-tool.c:52
407msgid "list all network adapters"
408msgstr ""
409
410#: src/setup/gnunet-win-tool.c:55
411msgid "install GNUnet as Windows service"
412msgstr ""
413
414#: src/setup/gnunet-win-tool.c:58
415msgid "uninstall GNUnet service"
416msgstr ""
417
418#: src/setup/gnunet-win-tool.c:61
419msgid "increase the maximum number of TCP/IP connections"
420msgstr ""
421
422#: src/setup/gnunet-win-tool.c:64
423msgid "display a file's hash value"
424msgstr ""
425
426#: src/setup/gnunet-win-tool.c:125
427#, c-format
428msgid "GNUnet service installed successfully.\n"
429msgstr "Der GNUnet Dienst wurde erfolgreich installiert.\n"
430
431#: src/setup/gnunet-win-tool.c:128 src/setup/gnunet-win-tool.c:156
432#, c-format
433msgid "This version of Windows doesn't support services.\n"
434msgstr "Diese Version von Windows unterstützt keine Dienste.\n"
435
436#: src/setup/gnunet-win-tool.c:132 src/setup/gnunet-win-tool.c:160
437#, c-format
438msgid "Error: can't open Service Control Manager: %s\n"
439msgstr "Fehler: der Dienstemanager konnte nicht geöffnet werden: %s\n"
440
441#: src/setup/gnunet-win-tool.c:137
442#, c-format
443msgid "Error: can't create service: %s\n"
444msgstr "Fehler: Dienst konnte nicht angelegt werden: %s\n"
445
446#: src/setup/gnunet-win-tool.c:140 src/setup/gnunet-win-tool.c:172
447#, c-format
448msgid "Unknown error.\n"
449msgstr "Unbekannter Fehler.\n"
450
451#: src/setup/gnunet-win-tool.c:153
452#, c-format
453msgid "Service deleted.\n"
454msgstr "Dienst gelöscht.\n"
455
456#: src/setup/gnunet-win-tool.c:165
457#, c-format
458msgid "Error: can't access service: %s\n"
459msgstr "Fehler: auf den Dienst konnte nicht zugegriffen werden: %s\n"
460
461#: src/setup/gnunet-win-tool.c:169
462#, c-format
463msgid "Error: can't delete service: %s\n"
464msgstr "Fehler: Dienst konnte nicht gelöscht werden: %s\n"
465
466#: src/setup/gtk/ngconf.c:389
467#, fuzzy
468msgid "Configuration saved."
469msgstr "GNUnet Konfiguration"
470
471#: src/setup/gtk/ngconf.c:399
472#, fuzzy
473msgid "Failed to save configuration."
474msgstr "Fehler beim Speichern der Konfiguration!"
475
476#: src/setup/gtk/ngconf.c:424
477#, fuzzy
478msgid "Configuration changed. Save?"
479msgstr ""
480"Konfiguration oder die GNUnet Version hat sich geändert. Sie müssen `%s' "
481"ausführen!\n"
482
483#: src/setup/gtk/ngconf.c:437
484#, fuzzy
485msgid "Error saving configuration."
486msgstr "Fehler beim Speichern der Konfiguration!"
487
488#: src/setup/gtk/wizard_gtk.c:141
489#, fuzzy
490msgid "(unknown connection)"
491msgstr "Netzwerkverbindung"
492
493#: src/setup/gtk/wizard_gtk.c:438
494#, fuzzy
495msgid "Do you want to save the new configuration?"
496msgstr "Möchten Sie Ihre Einstellungen speichern?"
497
498#: src/setup/gtk/wizard_gtk.c:470
499msgid "Unable to create user account:"
500msgstr "Fehler beim Anlegen des Benutzerkontos:"
501
502#: src/setup/gtk/wizard_gtk.c:480
503msgid "Unable to change startup process:"
504msgstr "Startprozeß konnte nicht geändert werden:"
505
506#: src/setup/gtk/wizard_gtk.c:495
507msgid ""
508"Running gnunet-update failed.\n"
509"This maybe due to insufficient permissions, please check your "
510"configuration.\n"
511"Finally, run gnunet-update manually."
512msgstr ""
513
514#: src/setup/gnunet-setup.c:65
515#, c-format
516msgid "Can only set one option per invocation.\n"
517msgstr ""
518
519#: src/setup/gnunet-setup.c:73
520#, c-format
521msgid ""
522"Invalid syntax, argument to 'set' must have the format SECTION:"
523"OPTION=VALUE.\n"
524msgstr ""
525
526#: src/setup/gnunet-setup.c:87
527#, c-format
528msgid "Can only display one option per invocation.\n"
529msgstr ""
530
531#: src/setup/gnunet-setup.c:94
532#, c-format
533msgid ""
534"Invalid syntax, argument to 'get' must have the format SECTION:OPTION.\n"
535msgstr ""
536
537#: src/setup/gnunet-setup.c:108
538msgid "generate configuration for gnunetd, the GNUnet daemon"
539msgstr "Generiere Konfiguration für gnunetd, den GNUnet Daemon"
540
541#: src/setup/gnunet-setup.c:111 src/setup/gnunet-setup.c:127
542#: src/server/gnunet-update.c:268
543msgid "print a value from the configuration file to stdout"
544msgstr ""
545"Einen Wert aus der Konfigurationsdatei auf der Standardausgabe ausgeben"
546
547#: src/setup/gnunet-setup.c:113 src/setup/gnunet-setup.c:129
548msgid "Tool to setup GNUnet."
549msgstr "Werkzeug für die Einrichtung von GNUnet."
550
551#: src/setup/gnunet-setup.c:115 src/setup/gnunet-setup.c:131
552#, fuzzy
553msgid "update a value in the configuration file"
554msgstr ""
555"Einen Wert aus der Konfigurationsdatei auf der Standardausgabe ausgeben"
556
557#: src/setup/gnunet-setup.c:338
558#, fuzzy, c-format
559msgid "Too many arguments.\n"
560msgstr "Ungültige Kommandozeilen Parameter.\n"
561
562#: src/setup/gnunet-setup.c:344
563#, fuzzy
564msgid "No interface specified, using default.\n"
565msgstr "Keine Oberfläche angegeben, verwende Standard\n"
566
567#: src/setup/gnunet-setup.c:392
568#, fuzzy, c-format
569msgid "Configuration file `%s' must be a filename (but is a directory).\n"
570msgstr ""
571"Konfigurationsdatei `%s' nicht gefunden. Bitte führen Sie gnunet-setup aus!\n"
572
573#: src/setup/gnunet-setup.c:439
574#, fuzzy, c-format
575msgid "Undefined option.\n"
576msgstr "Weitere Einstellungen"
577
578#: src/setup/gnunet-setup.c:496
579#, fuzzy, c-format
580msgid "`%s' is not available.\n"
581msgstr "`%s' ist nicht verfügbar."
582
583#: src/setup/gnunet-setup.c:516
584#, fuzzy, c-format
585msgid "Unknown operation '%s'.\n"
586msgstr "Unbekannte Operation `%s'\n"
587
588#: src/setup/gnunet-setup.c:517 src/util/getopt/getopt.c:1072
589#, c-format
590msgid "Use --help to get a list of options.\n"
591msgstr "Verwenden Sie --help, um eine Liste der Optionen zu erhalten.\n"
592
593#: src/setup/text/conf.c:79
594#, fuzzy
595msgid "yes"
596msgstr "Ja"
597
598#: src/setup/text/conf.c:80
599msgid "no"
600msgstr ""
601
602#: src/setup/text/conf.c:106
603#, c-format
604msgid "\tEnter yes (%s), no (%s) or help (%s): "
605msgstr ""
606
607#: src/setup/text/conf.c:115
608msgid "\tPossible choices:\n"
609msgstr ""
610
611#: src/setup/text/conf.c:123
612msgid "\tUse single space prefix to avoid conflicts with hotkeys!\n"
613msgstr ""
614
615#: src/setup/text/conf.c:125
616#, c-format
617msgid "\tEnter string (type '%s' for default value `%s'): "
618msgstr ""
619
620#: src/setup/text/conf.c:143
621#, c-format
622msgid "\t Enter choice (default is %c): "
623msgstr ""
624
625#: src/setup/text/conf.c:147
626#, c-format
627msgid "\tEnter floating point (type '%s' for default value %f): "
628msgstr ""
629
630#: src/setup/text/conf.c:153
631#, c-format
632msgid ""
633"\tEnter unsigned integer in interval [%llu,%llu] (type '%s' for default "
634"value %llu): "
635msgstr ""
636
637#: src/setup/text/conf.c:187
638#, fuzzy, c-format
639msgid "Yes\n"
640msgstr "Ja"
641
642#: src/setup/text/conf.c:192
643#, fuzzy, c-format
644msgid "No\n"
645msgstr "Nein"
646
647#: src/setup/text/conf.c:195 src/setup/text/conf.c:236
648#: src/setup/text/conf.c:266 src/setup/text/conf.c:329
649#: src/setup/text/conf.c:387
650#, fuzzy, c-format
651msgid "Help\n"
652msgstr "Hilfe"
653
654#: src/setup/text/conf.c:198 src/setup/text/conf.c:213
655#: src/setup/text/conf.c:276 src/setup/text/conf.c:307
656#: src/setup/text/conf.c:365
657#, fuzzy, c-format
658msgid "Abort\n"
659msgstr "_über"
660
661#: src/setup/text/conf.c:354 src/setup/text/conf.c:416
662#, c-format
663msgid ""
664"\n"
665"Invalid entry, try again (use '?' for help): "
666msgstr ""
667
668#: src/setup/text/conf.c:422
669#, c-format
670msgid "Unknown kind %x (internal error). Skipping option.\n"
671msgstr ""
672
673#: src/setup/text/conf.c:484
674msgid "\tDescend? (y/n/?) "
675msgstr ""
676
677#: src/setup/text/conf.c:493
678msgid "Aborted.\n"
679msgstr ""
680
681#: src/setup/text/conf.c:506
682#, fuzzy
683msgid "Invalid entry.\n"
684msgstr "Ungültiger Parameter: `%s'\n"
685
686#: src/setup/text/conf.c:524
687#, c-format
688msgid "Unknown kind %x (internal error). Aborting.\n"
689msgstr ""
690
691#: src/setup/text/conf.c:556
692#, c-format
693msgid "You can always press ENTER to keep the current value.\n"
694msgstr ""
695
696#: src/setup/text/conf.c:557
697#, c-format
698msgid "Use the '%s' key to abort.\n"
699msgstr ""
700
701#: src/setup/text/conf.c:575
702#, c-format
703msgid ""
704"Save configuration? Answer 'y' for yes, 'n' for no, 'r' to repeat "
705"configuration. "
706msgstr ""
707
708#: src/setup/text/conf.c:590
709#, fuzzy, c-format
710msgid "Configuration was unchanged, no need to save.\n"
711msgstr ""
712"Konfiguration oder die GNUnet Version hat sich geändert. Sie müssen `%s' "
713"ausführen!\n"
714
715#: src/setup/text/conf.c:599
716#, fuzzy, c-format
717msgid "Configuration file `%s' written.\n"
718msgstr "Konfigurationsdatei `%s' wurde erzeugt.\n"
719
720#: src/setup/lib/tree.c:191
721#, c-format
722msgid ""
723"Internal error: entry `%s' in section `%s' not found for visibility change!\n"
724msgstr ""
725
726#: src/setup/lib/wizard_util.c:126
727msgid "Can't open Service Control Manager"
728msgstr "Der Dienstemanager konnte nicht geöffnet werden"
729
730#: src/setup/lib/wizard_util.c:132
731msgid "Can't create service"
732msgstr "Der Dienst konnte nicht angelegt werden"
733
734#: src/setup/lib/wizard_util.c:136
735msgid "Error changing the permissions of the GNUnet directory"
736msgstr "Fehler beim Ändern der Berechtigungen des GNUnet Verzeichnisses"
737
738#: src/setup/lib/wizard_util.c:141
739#, fuzzy
740msgid "Cannot write to the registry"
741msgstr "Konnte nicht in die Registry schreiben"
742
743#: src/setup/lib/wizard_util.c:144
744msgid "Can't access the service"
745msgstr "Auf den Dienst konnte nicht zugegriffen werden"
746
747#: src/setup/lib/wizard_util.c:147
748msgid "Can't delete the service"
749msgstr "Dienst konnte nicht gelöscht werden"
750
751#: src/setup/lib/wizard_util.c:150
752msgid "Unknown error"
753msgstr "Unbekannter Fehler"
754
755#: src/setup/lib/wizard_util.c:186
756msgid "This version of Windows does not support multiple users."
757msgstr "Diese Version von Windows ist nicht Mehrbenutzerfähig."
758
759#: src/setup/lib/wizard_util.c:190
760msgid "Error creating user"
761msgstr "Fehler beim Anlegen des Benutzers"
762
763#: src/setup/lib/wizard_util.c:194
764msgid "Error accessing local security policy"
765msgstr "Fehler beim Zugriff auf die lokale Sicherheitsrichtlinie"
766
767#: src/setup/lib/wizard_util.c:199
768msgid "Error granting service right to user"
769msgstr "Fehler beim Zuweisen des Dienstrechtes dem Benutzer"
770
771#: src/setup/lib/wizard_util.c:204
772msgid "Unknown error while creating a new user"
773msgstr "Unbekannter Fehler beim Anlegen des neuen Benutzers"
774
775#: src/setup/lib/gns.c:297
776#, fuzzy, c-format
777msgid ""
778"Configuration does not satisfy constraints of configuration specification "
779"file `%s'!\n"
780msgstr ""
781"Die Konfigurationsdatei muss in der Sektion `%s' unter `%s' ein Verzeichnis "
782"für FS Daten angeben.\n"
783
784#: src/util/disk/storage.c:172
785#, fuzzy, c-format
786msgid "`%s' failed for drive `%s': %u\n"
787msgstr "`%s' fehlgeschlagen für Laufwerk %s: %u\n"
788
789#: src/util/disk/storage.c:524
790#, fuzzy, c-format
791msgid "Expected `%s' to be a directory!\n"
792msgstr "`%s' erwartet, dass `%s' ein Verzeichnis ist!\n"
793
794#: src/util/error/error.c:152
795#, c-format
796msgid "Message `%.*s' repeated %u times in the last %llus\n"
797msgstr ""
798
799#: src/util/error/error.c:254
800#, c-format
801msgid ""
802"\n"
803"Press any key to continue\n"
804msgstr ""
805
806#: src/util/error/error.c:336 src/util/error/error.c:371
807msgid "DEBUG"
808msgstr "DEBUG"
809
810#: src/util/error/error.c:338 src/util/error/error.c:373
811msgid "STATUS"
812msgstr ""
813
814#: src/util/error/error.c:340 src/util/error/error.c:377
815msgid "WARNING"
816msgstr "WARNUNG"
817
818#: src/util/error/error.c:342 src/util/error/error.c:379
819msgid "ERROR"
820msgstr "FEHLER"
821
822#: src/util/error/error.c:344 src/util/error/error.c:381
823msgid "FATAL"
824msgstr "SCHWERWIEGEND"
825
826#: src/util/error/error.c:346 src/util/error/error.c:383
827msgid "USER"
828msgstr ""
829
830#: src/util/error/error.c:348 src/util/error/error.c:385
831msgid "ADMIN"
832msgstr ""
833
834#: src/util/error/error.c:350 src/util/error/error.c:387
835msgid "DEVELOPER"
836msgstr ""
837
838#: src/util/error/error.c:352 src/util/error/error.c:389
839msgid "REQUEST"
840msgstr ""
841
842#: src/util/error/error.c:354 src/util/error/error.c:391
843msgid "BULK"
844msgstr ""
845
846#: src/util/error/error.c:356 src/util/error/error.c:393
847msgid "IMMEDIATE"
848msgstr ""
849
850#: src/util/error/error.c:358
851msgid "ALL"
852msgstr ""
853
854#: src/util/error/error.c:375
855msgid "INFO"
856msgstr "INFO"
857
858#: src/util/error/error.c:394
859msgid "NOTHING"
860msgstr "NICHTS"
861
862#: src/util/network_client/tcpio.c:98 src/util/network_client/tcpio.c:154
863msgid "Could not find valid value for HOST in section NETWORK.\n"
864msgstr ""
865
866#: src/util/network_client/tcpio.c:123
867#, fuzzy, c-format
868msgid "Syntax error in configuration entry HOST in section NETWORK: `%s'\n"
869msgstr "Syntaxfehler in Konfigurationsdatei `%s' in Zeile %d.\n"
870
871#: src/util/network_client/tcpio.c:335
872#, fuzzy, c-format
873msgid "Error connecting to %s:%u. Is the daemon running?\n"
874msgstr "Verbindung zu %u.%u.%u.%u:%u fehlgeschlagen: %s\n"
875
876#: src/util/network_client/tcpio.c:398
877#, fuzzy, c-format
878msgid "Cannot connect to %s:%u: %s\n"
879msgstr "Verbindung zu %u.%u.%u.%u:%u fehlgeschlagen: %s\n"
880
881#: src/util/network_client/tcpio.c:636
882#, fuzzy
883msgid "Reading result from gnunetd failed, reply invalid!\n"
884msgstr "`%s' fehlgeschlagen, Antwort ist ungültig!\n"
885
886#: src/util/getopt/setoption.c:59
887#, c-format
888msgid ""
889"Setting option `%s' in section `%s' to `%s' when processing command line "
890"option `%s' was denied.\n"
891msgstr ""
892
893#: src/util/getopt/setoption.c:138 src/util/getopt/setoption.c:155
894#, c-format
895msgid "You must pass a number to the `%s' option.\n"
896msgstr "Sie müssen für die Option `%s' zusätzlich eine Zahl angeben.\n"
897
898#: src/util/getopt/printhelp.c:49
899#, c-format
900msgid ""
901"Arguments mandatory for long options are also mandatory for short options.\n"
902msgstr ""
903"Parameter, die für lange Optionen zwingend sind, sind auch für kurze "
904"Optionen zwingend.\n"
905
906#: src/util/getopt/getopt.c:684
907#, c-format
908msgid "%s: option `%s' is ambiguous\n"
909msgstr "%s: Option `%s' ist mehrdeutig\n"
910
911#: src/util/getopt/getopt.c:710
912#, c-format
913msgid "%s: option `--%s' does not allow an argument\n"
914msgstr "%s: Option '--%s' erlaubt keinen Parameter\n"
915
916#: src/util/getopt/getopt.c:716
917#, c-format
918msgid "%s: option `%c%s' does not allow an argument\n"
919msgstr "%s: Option '%c%s' erlaubt keinen Parameter\n"
920
921#: src/util/getopt/getopt.c:737 src/util/getopt/getopt.c:909
922#, c-format
923msgid "%s: option `%s' requires an argument\n"
924msgstr "%s: Option `%s' benötigt einen Parameter\n"
925
926#: src/util/getopt/getopt.c:767
927#, c-format
928msgid "%s: unrecognized option `--%s'\n"
929msgstr "%s: unbekannte Option '--%s'\n"
930
931#: src/util/getopt/getopt.c:771
932#, c-format
933msgid "%s: unrecognized option `%c%s'\n"
934msgstr "%s: unbekannte Option '%c%s'\n"
935
936#: src/util/getopt/getopt.c:797
937#, c-format
938msgid "%s: illegal option -- %c\n"
939msgstr "%s: unerlaubte Option -- %c\n"
940
941#: src/util/getopt/getopt.c:799
942#, c-format
943msgid "%s: invalid option -- %c\n"
944msgstr "%s: ungültige Option -- %c\n"
945
946#: src/util/getopt/getopt.c:828 src/util/getopt/getopt.c:958
947#, c-format
948msgid "%s: option requires an argument -- %c\n"
949msgstr "%s: Option benötigt einen Parameter -- %c\n"
950
951#: src/util/getopt/getopt.c:876
952#, c-format
953msgid "%s: option `-W %s' is ambiguous\n"
954msgstr "%s: Option '-W %s' ist mehrdeutig\n"
955
956#: src/util/getopt/getopt.c:894
957#, c-format
958msgid "%s: option `-W %s' does not allow an argument\n"
959msgstr "%s: Option '-W %s' erlaubt keinen Parameter\n"
960
961#: src/util/network/ip.c:96 src/util/network/ip.c:160 src/transports/ip.c:260
962#, fuzzy, c-format
963msgid "No interface specified in section `%s' under `%s'!\n"
964msgstr ""
965"Es sind keine Netzwerkgeräte in der Konfigurationsdatei in der Sektion `%s' "
966"unter `%s' definiert!\n"
967
968#: src/util/network/ip.c:127 src/util/network/ip.c:246 src/transports/ip.c:291
969#, c-format
970msgid "Could not obtain IP for interface `%s' using `%s'.\n"
971msgstr ""
972"Es konnte keine IP für das Gerät `%s' unter Verwendung von `%s' ermittelt "
973"werden.\n"
974
975#: src/util/network/ip.c:216
976#, fuzzy, c-format
977msgid ""
978"Could not find interface `%s' using `%s', trying to find another interface.\n"
979msgstr ""
980"Gerät `%s' konnte in `%s' nicht gefunden werden, es wird versucht, ein "
981"anderes Gerät zu finden.\n"
982
983#: src/util/network/ip.c:295
984#, c-format
985msgid "Could not find an IP address for interface `%s'.\n"
986msgstr "Es konnte keine IP-Adresse für das Gerät `%s' ermittelt werden.\n"
987
988#: src/util/network/ip.c:306
989#, fuzzy, c-format
990msgid ""
991"There is more than one IP address specified for interface `%s'.\n"
992"GNUnet will use %s.\n"
993msgstr ""
994"Es ist mehr als eine IP-Adresse für das Gerät `%s' angegeben.\n"
995"GNUnet wird %u.%u.%u.%u. verwenden.\n"
996
997#: src/util/network/ip.c:330
998#, c-format
999msgid "Could not resolve `%s' to determine our IP address: %s\n"
1000msgstr ""
1001"`%s' konnte nicht aufgelöst werden, um unsere IP-Adresse zu ermitteln: %s\n"
1002
1003#: src/util/network/ip.c:363
1004#, fuzzy, c-format
1005msgid "GNUnet now uses the IP address %s.\n"
1006msgstr "GNUnet verwendet nun die IP-Adresse %u.%u.%u.%u.\n"
1007
1008#: src/util/network/ipcheck.c:106 src/util/network/ipcheck.c:136
1009#: src/util/network/ipcheck.c:186 src/util/network/ipcheck.c:211
1010#: src/util/network/ipcheck.c:219
1011#, c-format
1012msgid "Invalid format for IP: `%s'\n"
1013msgstr "Ungültiges Format für IP: `%s'\n"
1014
1015#: src/util/network/ipcheck.c:167
1016#, c-format
1017msgid "Invalid network notation ('/%d' is not legal in IPv4 CIDR)."
1018msgstr "Ungültige Netzwerk Notation ('/%d ist nicht gültig in IPv4 CIDR)."
1019
1020#: src/util/network/ipcheck.c:269
1021#, c-format
1022msgid "Invalid network notation (does not end with ';': `%s')\n"
1023msgstr "Ungültige Netzwerk Notation (endet nicht mit ';': `%s')\n"
1024
1025#: src/util/network/ipcheck.c:306
1026#, fuzzy, c-format
1027msgid "Wrong format `%s' for netmask\n"
1028msgstr "Falsches Format `%s' für Netzmaske: %s\n"
1029
1030#: src/util/network/ipcheck.c:338
1031#, fuzzy, c-format
1032msgid "Wrong format `%s' for network\n"
1033msgstr "Falsches Format `%s' für Netzwerk: %s\n"
1034
1035#: src/util/network/dns.c:472
1036#, fuzzy, c-format
1037msgid "Could not resolve `%s' (%s): %s\n"
1038msgstr "`%s' konnte nicht aufgelöst werden: %s\n"
1039
1040#: src/util/network/dns.c:523 src/util/network/dns.c:591
1041#, c-format
1042msgid "Could not find IP of host `%s': %s\n"
1043msgstr "IP des Hosts `%s' konnte nicht ermittelt werden: %s\n"
1044
1045#: src/util/network/select.c:310
1046#, fuzzy
1047msgid "Received malformed message (too small) from connection. Closing.\n"
1048msgstr ""
1049"Es wurde per TCP von einem anderen Knoten eine ungültige Nachricht (Größe %"
1050"u) empfangen. Verbindung wird geschlossen.\n"
1051
1052#: src/util/network/select.c:495
1053#, c-format
1054msgid "select listen socket for `%s' not valid!\n"
1055msgstr ""
1056
1057#: src/util/config/config.c:296
1058#, c-format
1059msgid "Syntax error in configuration file `%s' at line %d.\n"
1060msgstr "Syntaxfehler in Konfigurationsdatei `%s' in Zeile %d.\n"
1061
1062#: src/util/config/config.c:592
1063#, c-format
1064msgid ""
1065"Configuration value '%llu' for '%s' in section '%s' is out of legal bounds [%"
1066"llu,%llu]\n"
1067msgstr ""
1068
1069#: src/util/config/config.c:602
1070#, c-format
1071msgid "Configuration value '%s' for '%s' in section '%s' should be a number\n"
1072msgstr ""
1073
1074#: src/util/config/config.c:688
1075#, c-format
1076msgid ""
1077"Configuration value '%s' for '%s' in section '%s' is not in set of legal "
1078"choices\n"
1079msgstr ""
1080
1081#: src/util/crypto/locking_gcrypt.c:80
1082#, c-format
1083msgid "libgcrypt has not the expected version (version %s is required).\n"
1084msgstr ""
1085"libgcrypt hat nicht die erwartete Version (Version %s wird vorausgesetzt).\n"
1086
1087#: src/util/crypto/symcipher_gcrypt.c:46 src/util/crypto/symcipher_gcrypt.c:53
1088#: src/util/crypto/hostkey_gcrypt.c:64 src/util/crypto/hostkey_gcrypt.c:71
1089#: src/util/loggers/file.c:271 src/util/loggers/file.c:289
1090#: src/applications/sqstore_sqlite/sqlite.c:45
1091#: src/applications/sqstore_sqlite/sqlite.c:52
1092#: src/applications/kvstore_sqlite/kv_sqlite.c:44
1093#: src/applications/kvstore_sqlite/kv_sqlite.c:51
1094#: src/applications/kvstore_mysql/kv_mysql.c:44
1095#: src/applications/kvstore_mysql/kv_mysql.c:51
1096#: src/applications/dstore_sqlite/dstore.c:94
1097#: src/applications/dstore_sqlite/dstore.c:101
1098#: src/applications/dstore_sqlite/dstore.c:222
1099#: src/applications/dstore_sqlite/dstore.c:259
1100#: src/applications/dstore_sqlite/dstore.c:285
1101#: src/applications/dstore_sqlite/dstore.c:345
1102#: src/applications/dstore_sqlite/dstore.c:366
1103#: src/applications/dstore_sqlite/dstore.c:378
1104#: src/applications/dstore_sqlite/dstore.c:407
1105#: src/applications/dstore_sqlite/dstore.c:511
1106#: src/applications/dstore_sqlite/dstore.c:555
1107#: src/include/gnunet_util_error.h:249 src/include/gnunet_util_error.h:256
1108#: src/include/gnunet_util_error.h:263
1109#, c-format
1110msgid "`%s' failed at %s:%d with error: %s\n"
1111msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n"
1112
1113#: src/util/crypto/hostkey_gcrypt.c:907
1114#, c-format
1115msgid "RSA signature verification failed at %s:%d: %s\n"
1116msgstr "RSA Signaturüberprüfung fehlgeschlagen bei %s:%d: %s\n"
1117
1118#: src/util/os/user.c:108 src/util/os/user.c:125
1119#, fuzzy, c-format
1120msgid "`%s' returned with error code %u"
1121msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n"
1122
1123#: src/util/os/user.c:155 src/util/os/user.c:200
1124#, fuzzy, c-format
1125msgid "Cannot obtain information about user `%s': %s\n"
1126msgstr "Fehler beim Speichern der Konfigurationsdatei: `%s': %s.\n"
1127
1128#: src/util/os/user.c:156
1129msgid "No such user"
1130msgstr ""
1131
1132#: src/util/os/user.c:171
1133#, c-format
1134msgid "Cannot change user/group to `%s': %s\n"
1135msgstr "Benutzer/Gruppe kann nicht zu `%s' gewechselt werden: %s\n"
1136
1137#: src/util/os/semaphore.c:227
1138#, c-format
1139msgid "Can't create semaphore: %i"
1140msgstr "Semaphore konnte nicht angelegt werden: %i"
1141
1142#: src/util/os/cpustatus.c:464
1143msgid "Cannot query the CPU usage (Windows NT).\n"
1144msgstr "CPU Nutzung kann nicht ermittelt werden (Windows NT).\n"
1145
1146#: src/util/os/cpustatus.c:487
1147msgid "Cannot query the CPU usage (Win 9x)\n"
1148msgstr "CPU Nutzung kann nicht ermittelt werden (Win 9x).\n"
1149
1150#: src/util/os/dso.c:59
1151#, c-format
1152msgid "Initialization of plugin mechanism failed: %s!\n"
1153msgstr "Initialisierung des Plugin Mechanismuses fehlgeschlagen: %s!\n"
1154
1155#: src/util/os/dso.c:120
1156#, fuzzy, c-format
1157msgid "`%s' failed for library `%s' with error: %s\n"
1158msgstr "`%s' fehlgeschlagen für die Bibliothek `%s'. Ort: %s:%d. Fehler: %s\n"
1159
1160#: src/util/os/dso.c:162
1161#, fuzzy, c-format
1162msgid "`%s' failed to resolve method '%s' with error: %s\n"
1163msgstr ""
1164"`%s' konnte die Methode '%s%s' nicht auflösen. Ort: %s:%d. Fehler: %s\n"
1165
1166#: src/util/os/statuscalls.c:197 src/util/os/statuscalls.c:342
1167#, fuzzy, c-format
1168msgid "Failed to parse interface data from `%s'.\n"
1169msgstr "Fehler beim Parsen der Gerätedaten von `%s' bei %s:%d.\n"
1170
1171#: src/util/os/statuscalls.c:390 src/util/os/statuscalls.c:400
1172#, c-format
1173msgid ""
1174"No network interfaces defined in configuration section `%s' under `%s'!\n"
1175msgstr ""
1176"Es sind keine Netzwerkgeräte in der Konfigurationsdatei in der Sektion `%s' "
1177"unter `%s' definiert!\n"
1178
1179#: src/util/os/osconfig.c:153
1180msgid "Setting open descriptor limit not supported.\n"
1181msgstr ""
1182
1183#: src/util/os/osconfig.c:463 src/util/os/osconfig.c:492
1184#, fuzzy, c-format
1185msgid "Command `%s' failed with error code %u\n"
1186msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n"
1187
1188#: src/util/os/priority.c:78
1189#, fuzzy, c-format
1190msgid "Invalid process priority `%s'\n"
1191msgstr "Ungültige Antwort auf `%s'.\n"
1192
1193#: src/util/threads/semaphore.c:168 src/util/threads/pthread.c:157
1194#: src/util/threads/mutex.c:146
1195#, fuzzy, c-format
1196msgid "Real-time delay violation (%llu ms) at %s:%u\n"
1197msgstr "Unerwartete sehr große Allokierung (%u Bytes) bei %s:%d!\n"
1198
1199#: src/util/threads/pthread.c:169 src/util/threads/pthread.c:176
1200#: src/util/threads/pthread.c:182 src/util/threads/pthread.c:276
1201#, fuzzy, c-format
1202msgid "`%s' failed with error code %s: %s\n"
1203msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n"
1204
1205#: src/util/threads/pthread.c:188 src/util/threads/pthread.c:286
1206#, fuzzy, c-format
1207msgid "`%s' failed with error code %d: %s\n"
1208msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n"
1209
1210#: src/util/threads/mutex.c:155 src/util/threads/mutex.c:201
1211#, fuzzy, c-format
1212msgid "Invalid argument for `%s'.\n"
1213msgstr "Ungültiger Parameter: `%s'\n"
1214
1215#: src/util/threads/mutex.c:160
1216#, fuzzy, c-format
1217msgid "Deadlock due to `%s'.\n"
1218msgstr "Durch `%s' ist ein Deadlock bei %s:%d entstanden\n"
1219
1220#: src/util/threads/mutex.c:187
1221#, fuzzy, c-format
1222msgid "Lock acquired for too long (%llu ms) at %s:%u\n"
1223msgstr "Unerwartete sehr große Allokierung (%u Bytes) bei %s:%d!\n"
1224
1225#: src/util/threads/mutex.c:207
1226#, fuzzy, c-format
1227msgid "Permission denied for `%s'.\n"
1228msgstr "Zugriff verweigert für `%s' bei %s:%d.\n"
1229
1230#: src/util/boot/startup.c:259
1231#, fuzzy, c-format
1232msgid "Failed to run %s: %s %d\n"
1233msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n"
1234
1235#: src/util/string/string.c:55
1236msgid "ms"
1237msgstr "ms"
1238
1239#: src/util/string/string.c:61
1240msgid "s"
1241msgstr "s"
1242
1243#: src/util/string/string.c:65
1244msgid "m"
1245msgstr "m"
1246
1247#: src/util/string/string.c:69
1248msgid "h"
1249msgstr "h"
1250
1251#: src/util/string/string.c:73
1252msgid " days"
1253msgstr " Tage"
1254
1255#: src/util/string/string.c:89
1256msgid "b"
1257msgstr "b"
1258
1259#: src/util/string/string.c:95
1260msgid "KiB"
1261msgstr ""
1262
1263#: src/util/string/string.c:99
1264msgid "MiB"
1265msgstr ""
1266
1267#: src/util/string/string.c:103
1268msgid "GiB"
1269msgstr ""
1270
1271#: src/util/string/string.c:107
1272msgid "TiB"
1273msgstr ""
1274
1275#: src/util/string/string.c:226
1276msgid "Failed to expand `$HOME': environment variable `HOME' not set"
1277msgstr ""
1278
1279#: src/util/loggers/file.c:229
1280#, fuzzy, c-format
1281msgid "Failed to open log-file `%s': %s\n"
1282msgstr "Datei wurde als `%s' gespeichert.\n"
1283
1284#: src/util/loggers/file.c:250
1285#, fuzzy
1286msgid "GNUnet error log"
1287msgstr "GNUnet Netzwerk Topologie tracen."
1288
1289#: src/util/loggers/memory.c:72
1290msgid "Out of memory (for logging)\n"
1291msgstr ""
1292
1293#: src/util/pseudonym/names.c:79
1294#, fuzzy
1295msgid "no-name"
1296msgstr "Name anzeigen"
1297
1298#: src/applications/datastore/datastore.c:183
1299#: src/applications/datastore/datastore.c:199
1300#, c-format
1301msgid "Availability test failed for `%s' at %s:%d.\n"
1302msgstr "Verfügbarkeitstest für `%s' fehlgeschlagen bei %s:%d.\n"
1303
1304#: src/applications/datastore/datastore.c:401
1305msgid "# requests filtered by bloom filter"
1306msgstr ""
1307
1308#: src/applications/datastore/datastore.c:403
1309msgid "# bloom filter false positives"
1310msgstr ""
1311
1312#: src/applications/datastore/datastore.c:406
1313msgid "# bytes allowed in datastore"
1314msgstr "# bytes erlaubt in der Datenbank"
1315
1316#: src/applications/datastore/datastore.c:423
1317#, fuzzy
1318msgid "Failed to load state service. Trying to do without.\n"
1319msgstr "Der Transportdienst auf Port %d konnte nicht gestartet werden.\n"
1320
1321#: src/applications/datastore/datastore.c:529
1322#, c-format
1323msgid "Datastore conversion at approximately %u%%\n"
1324msgstr ""
1325
1326#: src/applications/datastore/datastore.c:576
1327#, fuzzy, c-format
1328msgid "Starting datastore conversion (this may take a while).\n"
1329msgstr "Ein neuer Hostkey wird erzeugt (dies kann eine Weile dauern).\n"
1330
1331#: src/applications/datastore/datastore.c:584
1332#, c-format
1333msgid "Completed datastore conversion.\n"
1334msgstr ""
1335
1336#: src/applications/datastore/datastore.c:592
1337#, fuzzy
1338msgid "Failed to load sqstore service. Check your configuration!\n"
1339msgstr "Der Transportdienst auf Port %d konnte nicht gestartet werden.\n"
1340
1341#: src/applications/rpc/rpc.c:339
1342#, fuzzy, c-format
1343msgid ""
1344"%s:%d - RPC %s:%p could not be registered: another callback is already using "
1345"this name (%p)\n"
1346msgstr ""
1347"%s::%s - RPC %s:%p konnte nicht registriert werden: ein anderer Callback "
1348"verwendet bereits diesen Namen (%p)\n"
1349
1350#: src/applications/rpc/rpc.c:398
1351#, fuzzy, c-format
1352msgid "%s:%d - async RPC %s:%p could not be unregistered: not found\n"
1353msgstr ""
1354"%s::%s - async RPC %s:%p konnte nicht unregistriert werden: nicht gefunden\n"
1355
1356#: src/applications/rpc/rpc.c:951
1357#, c-format
1358msgid "`%s' registering handlers %d %d %d\n"
1359msgstr "`%s' registriert Handler %d %d %d\n"
1360
1361#: src/applications/rpc/rpc.c:972
1362#, c-format
1363msgid "Failed to initialize `%s' service.\n"
1364msgstr "`%s' Dienst konnte nicht initialisiert werden.\n"
1365
1366#: src/applications/tbench/tbenchtest.c:53
1367#, c-format
1368msgid "Using %u messages of size %u for %u times.\n"
1369msgstr "Verwende %u Nachrichten der Größe %u %umal.\n"
1370
1371#: src/applications/tbench/tbenchtest.c:85
1372#, c-format
1373msgid "Times: max %16llu min %16llu mean %12.3f variance %12.3f\n"
1374msgstr "Zeiten: Max %16llu Min %16llu Mittel %12.3f Varianz %12.3f\n"
1375
1376#: src/applications/tbench/tbenchtest.c:89
1377#, c-format
1378msgid "Loss: max %16u min %16u mean %12.3f variance %12.3f\n"
1379msgstr "Verloren: Max %16u Min %16u Mittel %12.3f Varianz %12.3f\n"
1380
1381#: src/applications/tbench/tbenchtest.c:95
1382#, c-format
1383msgid ""
1384"\n"
1385"Failed to receive reply from gnunetd.\n"
1386msgstr ""
1387"\n"
1388"Fehler beim Empfangen der Antwort von gnunetd.\n"
1389
1390#: src/applications/tbench/tbenchtest.c:149
1391#, c-format
1392msgid "Running benchmark...\n"
1393msgstr "Benchmark läuft...\n"
1394
1395#: src/applications/tbench/tbench.c:422
1396msgid "allows profiling of direct peer-to-peer connections"
1397msgstr "Ermöglicht das Untersuchen direkter Peer-to-Peer Verbindungen"
1398
1399#: src/applications/tbench/gnunet-tbench.c:63
1400#: src/applications/tracekit/gnunet-tracekit.c:302
1401msgid "Start GNUnet transport benchmarking tool."
1402msgstr "GNUnet Transport Benchmarking Werkzeug starten."
1403
1404#: src/applications/tbench/gnunet-tbench.c:65
1405msgid "output in gnuplot format"
1406msgstr "Ausgabe im gnuplot Format"
1407
1408#: src/applications/tbench/gnunet-tbench.c:69
1409msgid "number of iterations"
1410msgstr "Anzahl an Durchläufen"
1411
1412#: src/applications/tbench/gnunet-tbench.c:73
1413msgid "number of messages to use per iteration"
1414msgstr "Anzahl an Nachrichten, die pro Durchlauf verwendet wird"
1415
1416#: src/applications/tbench/gnunet-tbench.c:76
1417msgid "receiver host identifier (ENC file name)"
1418msgstr "Bezeichner des Empfängerhosts (ENC Dateiname)"
1419
1420#: src/applications/tbench/gnunet-tbench.c:79
1421msgid "message size"
1422msgstr "Nachrichtengröße"
1423
1424#: src/applications/tbench/gnunet-tbench.c:82
1425msgid "sleep for SPACE ms after each a message block"
1426msgstr "Für SPACE ms nach jedem Nachrichtenblock pausieren"
1427
1428#: src/applications/tbench/gnunet-tbench.c:85
1429msgid "time to wait for the completion of an iteration (in ms)"
1430msgstr "Zeit, die gewartet wird, bis der Durchlauf fertiggestellt wird (in ms)"
1431
1432#: src/applications/tbench/gnunet-tbench.c:90
1433msgid "number of messages in a message block"
1434msgstr "Anzahl an Nachrichten in einem Nachrichtenblock"
1435
1436#: src/applications/tbench/gnunet-tbench.c:126
1437#: src/applications/tracekit/gnunet-tracekit.c:352
1438#: src/applications/tracekit/tracekittest.c:133
1439#: src/applications/template/gnunet-template.c:95
1440#: src/applications/stats/gnunet-stats.c:121
1441#: src/applications/vpn/gnunet-vpn.c:154
1442#, c-format
1443msgid "Error establishing connection with gnunetd.\n"
1444msgstr "Fehler beim Aufbauen einer Verbindung mit gnunetd.\n"
1445
1446#: src/applications/tbench/gnunet-tbench.c:142
1447#, c-format
1448msgid "You must specify a receiver!\n"
1449msgstr "Sie müssen einen Empfänger angeben!\n"
1450
1451#: src/applications/tbench/gnunet-tbench.c:152
1452#, c-format
1453msgid "Invalid receiver peer ID specified (`%s' is not valid name).\n"
1454msgstr ""
1455"Ungültige Empfängerknoten ID angegeben (`%s' ist kein gültiger Name).\n"
1456
1457#: src/applications/tbench/gnunet-tbench.c:189
1458#, c-format
1459msgid "Time:\n"
1460msgstr "Zeit:\n"
1461
1462#: src/applications/tbench/gnunet-tbench.c:190
1463#, c-format
1464msgid "\tmax %llums\n"
1465msgstr "\tMax %llums\n"
1466
1467#: src/applications/tbench/gnunet-tbench.c:191
1468#, c-format
1469msgid "\tmin %llums\n"
1470msgstr "\tMin %llums\n"
1471
1472#: src/applications/tbench/gnunet-tbench.c:192
1473#, c-format
1474msgid "\tmean %8.4fms\n"
1475msgstr "\tMittel %8.4fms\n"
1476
1477#: src/applications/tbench/gnunet-tbench.c:193
1478#, c-format
1479msgid "\tvariance %8.4fms\n"
1480msgstr "\tVarianz %8.4fms\n"
1481
1482#: src/applications/tbench/gnunet-tbench.c:195
1483#, c-format
1484msgid "Loss:\n"
1485msgstr "Verlust:\n"
1486
1487#: src/applications/tbench/gnunet-tbench.c:196
1488#, c-format
1489msgid "\tmax %u\n"
1490msgstr "\tMax %u\n"
1491
1492#: src/applications/tbench/gnunet-tbench.c:197
1493#, c-format
1494msgid "\tmin %u\n"
1495msgstr "\tMin %u\n"
1496
1497#: src/applications/tbench/gnunet-tbench.c:198
1498#, c-format
1499msgid "\tmean %8.4f\n"
1500msgstr "\tMittel %8.4fms\n"
1501
1502#: src/applications/tbench/gnunet-tbench.c:199
1503#, c-format
1504msgid "\tvariance %8.4f\n"
1505msgstr "\tVarianz %8.4f\n"
1506
1507#: src/applications/tbench/gnunet-tbench.c:205
1508#, c-format
1509msgid "Output format not known, this should not happen.\n"
1510msgstr "Ausgabeformat ist unbekannt, dies sollte nicht passieren.\n"
1511
1512#: src/applications/tbench/gnunet-tbench.c:211
1513#, c-format
1514msgid ""
1515"\n"
1516"Did not receive the message from gnunetd. Is gnunetd running?\n"
1517msgstr ""
1518"\n"
1519"Es wurde keine Nachricht von gnunetd empfangen. Läuft gnunetd?\n"
1520
1521#: src/applications/traffic/traffic.c:454
1522#, c-format
1523msgid "# bytes transmitted of type %d"
1524msgstr "# Bytes des Typs %d übertragen"
1525
1526#: src/applications/traffic/traffic.c:470
1527#, c-format
1528msgid "# bytes received of type %d"
1529msgstr "# Bytes des Typs %d empfangen"
1530
1531#: src/applications/traffic/traffic.c:489
1532#, fuzzy, c-format
1533msgid "# bytes received in plaintext of type %d"
1534msgstr "# Bytes des Typs %d empfangen"
1535
1536#: src/applications/traffic/traffic.c:652
1537msgid "tracks bandwidth utilization by gnunetd"
1538msgstr "Verfolgt die Bandbreitennutzung von gnunetd"
1539
1540#: src/applications/sqstore_sqlite/sqlite.c:218
1541#, c-format
1542msgid "Unable to initialize SQLite: %s.\n"
1543msgstr "SQLite Datenbank konnte nicht initialisiert werden: %s.\n"
1544
1545#: src/applications/sqstore_sqlite/sqlite.c:434
1546#: src/applications/sqstore_sqlite/sqlite.c:469
1547#, c-format
1548msgid "Invalid data in %s. Trying to fix (by deletion).\n"
1549msgstr "Ungültige Daten in %s. Korrektur wird versucht (durch Löschung).\n"
1550
1551#: src/applications/sqstore_sqlite/sqlite.c:435
1552#: src/applications/sqstore_sqlite/sqlite.c:470
1553msgid "sqlite datastore"
1554msgstr "sqlite Datenspeicher"
1555
1556#: src/applications/sqstore_sqlite/sqlite.c:1474
1557#: src/applications/sqstore_mysql/mysql.c:1078
1558msgid "# bytes in datastore"
1559msgstr "# bytes in der Datenbank"
1560
1561#: src/applications/sqstore_sqlite/sqlite.c:1476
1562#, fuzzy
1563msgid "# bytes allocated by SQLite"
1564msgstr "# bytes erlaubt in der Datenbank"
1565
1566#: src/applications/sqstore_mysql/mysql.c:1085
1567#: src/applications/sqstore_mysql/mysql.c:1160
1568msgid ""
1569"Failed to load MySQL database module. Check that MySQL is running and "
1570"configured properly!\n"
1571msgstr ""
1572"Fehler beim Laden des MySQL Datenbankmoduls. Prüfen Sie, ob MySQL läuft und "
1573"richtig eingerichtet ist!\n"
1574
1575#: src/applications/tracekit/gnunet-tracekit.c:104
1576#, c-format
1577msgid "`%s' connected to `%s'.\n"
1578msgstr "`%s' hat sich mit `%s' verbunden.\n"
1579
1580#: src/applications/tracekit/gnunet-tracekit.c:110
1581#: src/applications/tracekit/tracekittest.c:67
1582#, c-format
1583msgid "`%s' is not connected to any peer.\n"
1584msgstr "`%s' ist zu keinem Knoten verbunden.\n"
1585
1586#: src/applications/tracekit/gnunet-tracekit.c:295
1587msgid "probe network to the given DEPTH"
1588msgstr "Netzwerk bis zur angegebenen Tiefe DEPTH sondieren"
1589
1590#: src/applications/tracekit/gnunet-tracekit.c:299
1591msgid ""
1592"specify output format; 0 for human readable output, 1 for dot, 2 for vcg"
1593msgstr "Gibt das Ausgabeformat an: 0 für menschen-lesbar, 1 für dot, 2 für vcg"
1594
1595#: src/applications/tracekit/gnunet-tracekit.c:306
1596#, fuzzy
1597msgid "use PRIORITY for the priority of the trace request"
1598msgstr "PRIO als Priorität für die Trace Anfragen verwenden"
1599
1600#: src/applications/tracekit/gnunet-tracekit.c:310
1601msgid "wait DELAY seconds for replies"
1602msgstr "DELAY Sekunden auf Antworten warten"
1603
1604#: src/applications/tracekit/gnunet-tracekit.c:344
1605#, c-format
1606msgid ""
1607"Format specification invalid. Use 0 for user-readable, 1 for dot, 2 for "
1608"vcg.\n"
1609msgstr ""
1610"Formatangabe ungültig. Verwenden Sie 0 für menschen-lesbar, 1 für dot und 2 "
1611"für vcg.\n"
1612
1613#: src/applications/tracekit/tracekittest.c:60
1614#, fuzzy, c-format
1615msgid "`%.*s' connected to `%.*s'.\n"
1616msgstr "`%s' hat sich mit `%s' verbunden.\n"
1617
1618#: src/applications/tracekit/tracekit.c:440
1619msgid "allows mapping of the network topology"
1620msgstr "Erlaubt die Kartographierung der Netzwerktopologie"
1621
1622#: src/applications/advertising/advertising_test.c:47
1623#: src/applications/hostlist/hostlisttest.c:40
1624#: src/applications/session/sessiontest.c:40
1625#: src/applications/session/sessiontest_nat_http.c:40
1626#: src/applications/session/sessiontest_nat.c:40
1627#: src/applications/stats/statistics.c:247
1628msgid "# of connected peers"
1629msgstr "# verbundener Knoten"
1630
1631#: src/applications/advertising/advertising.c:194
1632#, fuzzy, c-format
1633msgid "HELLO message from `%s' has an invalid signature. Dropping.\n"
1634msgstr ""
1635"Hello Nachricht von `%s' ist ungültig (Signatur ist ungültig). Nachricht "
1636"wurde verworfen.\n"
1637
1638#: src/applications/advertising/advertising.c:205
1639#, fuzzy
1640msgid "HELLO message has expiration too far in the future. Dropping.\n"
1641msgstr ""
1642"Empfangene Hello Nachricht ist ungültig (Ablaufzeit über Limit). Nachricht "
1643"wurde verworfen.\n"
1644
1645#: src/applications/advertising/advertising.c:406
1646#, fuzzy
1647msgid "Could not send HELLO+PING, ping buffer full.\n"
1648msgstr "Hellos+PING konnten nicht gesendet werden, Ping Puffer ist voll.\n"
1649
1650#: src/applications/advertising/advertising.c:429
1651msgid "Failed to create an advertisement for this peer. Will not send PING.\n"
1652msgstr ""
1653
1654#: src/applications/advertising/advertising.c:581
1655#, c-format
1656msgid "Advertising my transport %d to selected peers.\n"
1657msgstr "Transport %d wird ausgewählten anderen Knoten bekannt gegeben.\n"
1658
1659#: src/applications/advertising/advertising.c:590
1660msgid ""
1661"Announcing ourselves pointless: no other peers are known to us so far.\n"
1662msgstr ""
1663"Bekanntmachung von uns zwecklos: bis jetzt sind uns keine anderen Knoten "
1664"bekannt.\n"
1665
1666#: src/applications/advertising/advertising.c:868
1667msgid "# Peer advertisements received"
1668msgstr "# Knotenankündigungen empfangen"
1669
1670#: src/applications/advertising/advertising.c:871
1671#, fuzzy
1672msgid "# Peer advertisements of type NAT received"
1673msgstr "# Knotenankündigungen empfangen"
1674
1675#: src/applications/advertising/advertising.c:874
1676#, fuzzy
1677msgid "# Peer advertisements confirmed via PONG"
1678msgstr "# Knotenankündigungen empfangen"
1679
1680#: src/applications/advertising/advertising.c:877
1681#, fuzzy
1682msgid "# Peer advertisements updating earlier HELLOs"
1683msgstr "# Knotenankündigungen empfangen"
1684
1685#: src/applications/advertising/advertising.c:880
1686#, fuzzy
1687msgid "# Peer advertisements discarded due to load"
1688msgstr "# Knotenankündigungen empfangen"
1689
1690#: src/applications/advertising/advertising.c:883
1691#, fuzzy
1692msgid "# Peer advertisements for unsupported transport"
1693msgstr "# Knotenankündigungen empfangen"
1694
1695#: src/applications/advertising/advertising.c:886
1696#, fuzzy
1697msgid "# Peer advertisements not confirmed due to ping busy"
1698msgstr "# Knotenankündigungen empfangen"
1699
1700#: src/applications/advertising/advertising.c:889
1701#, fuzzy
1702msgid "# Peer advertisements not confirmed due to lack of self ad"
1703msgstr "# Knotenankündigungen empfangen"
1704
1705#: src/applications/advertising/advertising.c:892
1706#, fuzzy
1707msgid "# Peer advertisements not confirmed due to send error"
1708msgstr "# Knotenankündigungen empfangen"
1709
1710#: src/applications/advertising/advertising.c:894
1711msgid "# Self advertisments transmitted"
1712msgstr "# Selbstbekanntmachungen übertragen"
1713
1714#: src/applications/advertising/advertising.c:896
1715msgid "# Foreign advertisements forwarded"
1716msgstr "# Bekanntmachungen von anderen übertragen"
1717
1718#: src/applications/advertising/advertising.c:898
1719#: src/applications/pingpong/pingpong.c:528
1720msgid "# plaintext PING messages sent"
1721msgstr "# Klartext PING Nachrichten gesendet"
1722
1723#: src/applications/advertising/advertising.c:904
1724#: src/applications/session/connect.c:932
1725#, c-format
1726msgid "`%s' registering handler %d (plaintext and ciphertext)\n"
1727msgstr "`%s' registriert Handler %d (Plaintext und Ciphertext)\n"
1728
1729#: src/applications/advertising/advertising.c:922
1730msgid ""
1731"ensures that this peer is known by other peers and discovers other peers"
1732msgstr ""
1733"Stellt sicher, dass dieser Knoten anderen Knoten bekannt ist und entdeckt "
1734"andere Knoten"
1735
1736#: src/applications/fragmentation/fragmentation.c:578
1737msgid "# messages defragmented"
1738msgstr "# defragmentierter Nachrichten"
1739
1740#: src/applications/fragmentation/fragmentation.c:580
1741msgid "# messages fragmented"
1742msgstr "# fragmentierter Nachrichten"
1743
1744#: src/applications/fragmentation/fragmentation.c:581
1745msgid "# fragments discarded"
1746msgstr "# verworfener Nachrichten"
1747
1748#: src/applications/fragmentation/fragmentation.c:592
1749#, c-format
1750msgid "`%s' registering handler %d\n"
1751msgstr "`%s' registriert Handler %d\n"
1752
1753#: src/applications/topology_default/topology.c:466
1754#, fuzzy, c-format
1755msgid "Could not read friends list `%s'\n"
1756msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n"
1757
1758#: src/applications/topology_default/topology.c:485
1759#, c-format
1760msgid "Failed to read friends list from `%s'\n"
1761msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n"
1762
1763#: src/applications/topology_default/topology.c:505
1764msgid "Syntax error in topology specification, skipping bytes.\n"
1765msgstr "Syntaxfehler in Topolgieangabe, Bytes werden übersprungen.\n"
1766
1767#: src/applications/topology_default/topology.c:523
1768#, c-format
1769msgid "Syntax error in topology specification, skipping bytes `%s'.\n"
1770msgstr "Syntaxfehler in Topologieangabe, überspringe Bytes `%s'.\n"
1771
1772#: src/applications/topology_default/topology.c:535
1773msgid ""
1774"Fewer friends specified than required by minimum friend count. Will only "
1775"connect to friends.\n"
1776msgstr ""
1777
1778#: src/applications/topology_default/topology.c:543
1779msgid ""
1780"More friendly connections required than target total number of connections.\n"
1781msgstr ""
1782
1783#: src/applications/topology_default/topology.c:726
1784msgid "maintains GNUnet default mesh topology"
1785msgstr ""
1786
1787#: src/applications/chat/tools/gnunet-chat.c:107
1788msgid "anonymous"
1789msgstr ""
1790
1791#: src/applications/chat/tools/gnunet-chat.c:113
1792#, fuzzy, c-format
1793msgid "`%s' said: %s\n"
1794msgstr "`%s' %s schlug fehl: %s\n"
1795
1796#: src/applications/chat/tools/gnunet-chat.c:116
1797#: src/applications/chat/tools/gnunet-chat.c:119
1798#, fuzzy, c-format
1799msgid "`%s' said to you: %s\n"
1800msgstr "`%s' %s schlug fehl: %s\n"
1801
1802#: src/applications/chat/tools/gnunet-chat.c:122
1803#, fuzzy, c-format
1804msgid "`%s' said for sure: %s\n"
1805msgstr "`%s' fehlgeschlagen für Laufwerk %s: %u\n"
1806
1807#: src/applications/chat/tools/gnunet-chat.c:125
1808#, fuzzy, c-format
1809msgid "`%s' said to you for sure: %s\n"
1810msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n"
1811
1812#: src/applications/chat/tools/gnunet-chat.c:128
1813#, fuzzy, c-format
1814msgid "`%s' was confirmed that you received: %s\n"
1815msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n"
1816
1817#: src/applications/chat/tools/gnunet-chat.c:131
1818#, c-format
1819msgid "`%s' was confirmed that you and only you received: %s\n"
1820msgstr ""
1821
1822#: src/applications/chat/tools/gnunet-chat.c:134
1823#, c-format
1824msgid "`%s' was confirmed that you received from him or her: %s\n"
1825msgstr ""
1826
1827#: src/applications/chat/tools/gnunet-chat.c:139
1828#, c-format
1829msgid "`%s' was confirmed that you and only you received from him or her: %s\n"
1830msgstr ""
1831
1832#: src/applications/chat/tools/gnunet-chat.c:142
1833#, fuzzy, c-format
1834msgid "`%s' said off the record: %s\n"
1835msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n"
1836
1837#: src/applications/chat/tools/gnunet-chat.c:145
1838#, c-format
1839msgid "<%s> said using an unknown message type: %s\n"
1840msgstr ""
1841
1842#: src/applications/chat/tools/gnunet-chat.c:167
1843#, c-format
1844msgid "`%s' entered the room\n"
1845msgstr ""
1846
1847#: src/applications/chat/tools/gnunet-chat.c:167
1848#, fuzzy, c-format
1849msgid "`%s' left the room\n"
1850msgstr "Fehler beim Binden an UDP Port %d.\n"
1851
1852#: src/applications/chat/tools/gnunet-chat.c:239
1853#: src/applications/chat/tools/gnunet-chat.c:348
1854#, fuzzy, c-format
1855msgid "Failed to send message.\n"
1856msgstr "Zustellung der Nachricht `%s' fehlgeschlagen.\n"
1857
1858#: src/applications/chat/tools/gnunet-chat.c:265
1859#: src/applications/chat/tools/gnunet-chat.c:524
1860#, fuzzy, c-format
1861msgid "Joined room `%s' as user `%s'.\n"
1862msgstr "Ungültige Antwort auf `%s' von Knoten `%s' empfangen.\n"
1863
1864#: src/applications/chat/tools/gnunet-chat.c:293
1865#, fuzzy, c-format
1866msgid "Changed username to `%s'.\n"
1867msgstr "Benutzer/Gruppe kann nicht zu `%s' gewechselt werden: %s\n"
1868
1869#: src/applications/chat/tools/gnunet-chat.c:301
1870#, fuzzy, c-format
1871msgid "Unknown command `%s'.\n"
1872msgstr "Unbekannte Operation `%s'\n"
1873
1874#: src/applications/chat/tools/gnunet-chat.c:316
1875#, c-format
1876msgid "Syntax: /msg USERNAME MESSAGE"
1877msgstr ""
1878
1879#: src/applications/chat/tools/gnunet-chat.c:324
1880#, fuzzy, c-format
1881msgid "Unknown user `%s'\n"
1882msgstr "Unbekannte Operation `%s'\n"
1883
1884#: src/applications/chat/tools/gnunet-chat.c:339
1885#, c-format
1886msgid "User `%s' is currently not in the room!\n"
1887msgstr ""
1888
1889#: src/applications/chat/tools/gnunet-chat.c:361
1890#, c-format
1891msgid "Users in room `%s': "
1892msgstr ""
1893
1894#: src/applications/chat/tools/gnunet-chat.c:390
1895msgid ""
1896"Use `/join #roomname' to join a chat room. Joining a room will cause you to "
1897"leave the current room"
1898msgstr ""
1899
1900#: src/applications/chat/tools/gnunet-chat.c:393
1901msgid ""
1902"Use `/nick nickname' to change your nickname. This will cause you to leave "
1903"the current room and immediately rejoin it with the new name."
1904msgstr ""
1905
1906#: src/applications/chat/tools/gnunet-chat.c:396
1907msgid ""
1908"Use `/msg nickname message' to send a private message to the specified user"
1909msgstr ""
1910
1911#: src/applications/chat/tools/gnunet-chat.c:398
1912msgid "The `/notice' command is an alias for `/msg'"
1913msgstr ""
1914
1915#: src/applications/chat/tools/gnunet-chat.c:400
1916msgid "The `/query' command is an alias for `/msg'"
1917msgstr ""
1918
1919#: src/applications/chat/tools/gnunet-chat.c:402
1920msgid "Use `/quit' to terminate gnunet-chat"
1921msgstr ""
1922
1923#: src/applications/chat/tools/gnunet-chat.c:404
1924msgid "The `/leave' command is an alias for `/quit'"
1925msgstr ""
1926
1927#: src/applications/chat/tools/gnunet-chat.c:407
1928msgid "Use `/names' to list all of the current members in the chat room"
1929msgstr ""
1930
1931#: src/applications/chat/tools/gnunet-chat.c:409
1932msgid "Use `/help command' to get help for a specific command"
1933msgstr ""
1934
1935#: src/applications/chat/tools/gnunet-chat.c:457
1936msgid "Join a chat on GNUnet."
1937msgstr ""
1938
1939#: src/applications/chat/tools/gnunet-chat.c:461
1940msgid "set the nickname to use (required)"
1941msgstr ""
1942
1943#: src/applications/chat/tools/gnunet-chat.c:464
1944msgid "set the chat room to join"
1945msgstr ""
1946
1947#: src/applications/chat/tools/gnunet-chat.c:495
1948#, fuzzy, c-format
1949msgid "You must specify a nickname\n"
1950msgstr "Sie müssen einen Empfänger angeben!\n"
1951
1952#: src/applications/chat/tools/gnunet-chat.c:515
1953#, fuzzy, c-format
1954msgid "Failed to join room `%s'\n"
1955msgstr "Fehler beim Binden an UDP Port %d.\n"
1956
1957#: src/applications/chat/module/chat.c:325
1958#, fuzzy, c-format
1959msgid "`%s' registering CS handlers %d and %d\n"
1960msgstr "`%s' registriert Handler %d und %d\n"
1961
1962#: src/applications/chat/module/chat.c:347
1963msgid "enables P2P-chat (incomplete)"
1964msgstr "Ermöglicht P2P-Chat"
1965
1966#: src/applications/chat/lib/messaging.c:353
1967#: src/applications/identity/hostkey.c:122
1968#, fuzzy, c-format
1969msgid "Failed to access GNUnet home directory `%s'\n"
1970msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n"
1971
1972#: src/applications/chat/lib/messaging.c:389
1973#, fuzzy, c-format
1974msgid "Existing key in file `%s' failed format check, creating new key.\n"
1975msgstr ""
1976"Formatüberprüfung schlug für die existierende Hostkeydatei `%s' fehl, es "
1977"wird ein neuer Hostkey erzeugt.\n"
1978
1979#: src/applications/chat/lib/messaging.c:399
1980#, fuzzy
1981msgid "Creating new key for this nickname (this may take a while).\n"
1982msgstr "Ein neuer Hostkey wird erzeugt (dies kann eine Weile dauern).\n"
1983
1984#: src/applications/chat/lib/messaging.c:411
1985#, fuzzy
1986msgid "Done creating key.\n"
1987msgstr "Hostkey wurde erfolgreich erzeugt.\n"
1988
1989#: src/applications/dstore_mysql/dstore_mysql.c:471
1990#, fuzzy
1991msgid "Failed to initialize MySQL database connection for dstore.\n"
1992msgstr "SQLite Datenbank konnte nicht initialisiert werden.\n"
1993
1994#: src/applications/dstore_mysql/dstore_mysql.c:494
1995#: src/applications/dstore_sqlite/dstore.c:636
1996#, fuzzy
1997msgid "# bytes in dstore"
1998msgstr "# bytes in der Datenbank"
1999
2000#: src/applications/dstore_mysql/dstore_mysql.c:496
2001#: src/applications/dstore_sqlite/dstore.c:638
2002#, fuzzy
2003msgid "# max bytes allowed in dstore"
2004msgstr "# bytes erlaubt in der Datenbank"
2005
2006#: src/applications/transport/transport.c:191
2007#, c-format
2008msgid ""
2009"Converting peer address to string failed, transport type %d not supported\n"
2010msgstr ""
2011
2012#: src/applications/transport/transport.c:246
2013#, c-format
2014msgid "Transport connection attempt failed, transport type %d not supported\n"
2015msgstr ""
2016
2017#: src/applications/transport/transport.c:299
2018#, c-format
2019msgid ""
2020"Transport failed to connect to peer `%s' (%u HELLOs known, none worked)\n"
2021msgstr ""
2022
2023#: src/applications/transport/transport.c:376
2024#, fuzzy, c-format
2025msgid "Transmission attempt failed, transport type %d unknown.\n"
2026msgstr "Kein Transport des Typs %d bekannt.\n"
2027
2028#: src/applications/transport/transport.c:500
2029#, c-format
2030msgid "No transport of type %d known.\n"
2031msgstr "Kein Transport des Typs %d bekannt.\n"
2032
2033#: src/applications/transport/transport.c:560
2034msgid "No transport succeeded in creating a hello!\n"
2035msgstr ""
2036
2037#: src/applications/transport/transport.c:761
2038#, fuzzy, c-format
2039msgid "Loading transports `%s'\n"
2040msgstr "Teste Transport(e) %s\n"
2041
2042#: src/applications/transport/transport.c:781
2043#, fuzzy, c-format
2044msgid "Could not load transport plugin `%s'\n"
2045msgstr "Anwendung `%s' konnte nicht initialisiert werden.\n"
2046
2047#: src/applications/transport/transport.c:795
2048#, c-format
2049msgid "Transport library `%s' did not provide required function '%s%s'.\n"
2050msgstr ""
2051"Transport Bibliothek `%s' stellt nicht die benötigte Funktion '%s%s' zur "
2052"Verfügung.\n"
2053
2054#: src/applications/transport/transport.c:824
2055#, fuzzy, c-format
2056msgid "Loaded transport `%s'\n"
2057msgstr "Verfügbare(r) Transport(e): %s\n"
2058
2059#: src/applications/transport/transport.c:836
2060#: src/server/gnunet-peer-info.c:252
2061#, c-format
2062msgid "I am peer `%s'.\n"
2063msgstr "Ich bin Peer `%s'.\n"
2064
2065#: src/applications/dht/tools/dht_multipeer_test.c:80
2066#: src/applications/dht/tools/dht_twopeer_test.c:47
2067#: src/applications/dht/module/table.c:783
2068msgid "# dht connections"
2069msgstr ""
2070
2071#: src/applications/dht/tools/dht-query.c:54
2072#, fuzzy
2073msgid "Query (get KEY, put KEY VALUE) DHT table."
2074msgstr "Eine DHT Tabelle abfragen (get KEY, put KEY VALUE, remove KEY VALUE)."
2075
2076#: src/applications/dht/tools/dht-query.c:58
2077#, fuzzy
2078msgid "allow TIME ms to process a GET command"
2079msgstr "TIME ms erlauben, um jedes Kommando zu bearbeiten"
2080
2081#: src/applications/dht/tools/dht-query.c:107
2082#, fuzzy, c-format
2083msgid "Issuing `%s(%s,%s)' command.\n"
2084msgstr "'%s(%s,%s)' fehlgeschlagen.\n"
2085
2086#: src/applications/dht/tools/dht-query.c:142
2087#: src/applications/fs/tools/gnunet-auto-share.c:669
2088#, c-format
2089msgid "Failed to connect to gnunetd.\n"
2090msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n"
2091
2092#: src/applications/dht/tools/dht-query.c:155
2093#, c-format
2094msgid "Command `%s' requires an argument (`%s').\n"
2095msgstr "Kommando `%s' benötigt eine zusätzliche Angabe (`%s').\n"
2096
2097#: src/applications/dht/tools/dht-query.c:172
2098#, c-format
2099msgid "Command `%s' requires two arguments (`%s' and `%s').\n"
2100msgstr "Kommando `%s' benötigt zwei zusätzliche Angaben (`%s' und `%s').\n"
2101
2102#: src/applications/dht/tools/dht-query.c:183
2103#, c-format
2104msgid "Unsupported command `%s'. Aborting.\n"
2105msgstr "Kommando `%s' wird nicht unterstützt. Vorgang wird abgebrochen.\n"
2106
2107#: src/applications/dht/module/table.c:785
2108#, fuzzy
2109msgid "# dht discovery messages received"
2110msgstr "# verschlüsselter PING Nachrichten empfangen"
2111
2112#: src/applications/dht/module/table.c:787
2113msgid "# dht route host lookups performed"
2114msgstr ""
2115
2116#: src/applications/dht/module/table.c:789
2117#, fuzzy
2118msgid "# dht discovery messages sent"
2119msgstr "# verschlüsselter PING Nachrichten empfangen"
2120
2121#: src/applications/dht/module/routing.c:879
2122msgid "# dht replies routed"
2123msgstr ""
2124
2125#: src/applications/dht/module/routing.c:881
2126msgid "# dht requests routed"
2127msgstr "# dht Anfragen weitergeleitet"
2128
2129#: src/applications/dht/module/routing.c:883
2130#, fuzzy
2131msgid "# dht get requests received"
2132msgstr "# Client Trace-Anfragen empfangen"
2133
2134#: src/applications/dht/module/routing.c:885
2135#, fuzzy
2136msgid "# dht put requests received"
2137msgstr "# Client Trace-Anfragen empfangen"
2138
2139#: src/applications/dht/module/routing.c:887
2140#, fuzzy
2141msgid "# dht results received"
2142msgstr "# Bytes empfangen über TCP"
2143
2144#: src/applications/dht/module/routing.c:892
2145#, fuzzy, c-format
2146msgid "`%s' registering p2p handlers: %d %d %d\n"
2147msgstr "`%s' registriert Handler %d %d %d\n"
2148
2149#: src/applications/dht/module/cs.c:122
2150#, c-format
2151msgid "`%s' failed. Terminating connection to client.\n"
2152msgstr "`%s' fehlgeschlagen. Beende Verbindung zu Client.\n"
2153
2154#: src/applications/dht/module/cs.c:250
2155#, fuzzy, c-format
2156msgid "`%s' registering client handlers: %d %d\n"
2157msgstr "`%s' registriert Client-Handler %d\n"
2158
2159#: src/applications/dht/module/cs.c:273
2160msgid "Enables efficient non-anonymous routing"
2161msgstr ""
2162
2163#: src/applications/identity/hostkey.c:155
2164#, c-format
2165msgid ""
2166"Existing hostkey in file `%s' failed format check, creating new hostkey.\n"
2167msgstr ""
2168"Formatüberprüfung schlug für die existierende Hostkeydatei `%s' fehl, es "
2169"wird ein neuer Hostkey erzeugt.\n"
2170
2171#: src/applications/identity/hostkey.c:164
2172msgid "Creating new hostkey (this may take a while).\n"
2173msgstr "Ein neuer Hostkey wird erzeugt (dies kann eine Weile dauern).\n"
2174
2175#: src/applications/identity/hostkey.c:176
2176msgid "Done creating hostkey.\n"
2177msgstr "Hostkey wurde erfolgreich erzeugt.\n"
2178
2179#: src/applications/identity/identity.c:333
2180#, c-format
2181msgid ""
2182"File `%s' in directory `%s' does not match naming convention. Removed.\n"
2183msgstr ""
2184"Die Datei `%s' im Verzeichnis `%s' entspricht nicht der Namenskonvention. "
2185"Datei wurde entfernt.\n"
2186
2187#: src/applications/identity/identity.c:408
2188#, fuzzy, c-format
2189msgid "Still no peers found in `%s'!\n"
2190msgstr "Dienst `%s' konnte nicht ordentlich entladen werden!\n"
2191
2192#: src/applications/identity/identity.c:731
2193#: src/applications/identity/identity.c:757
2194#, fuzzy, c-format
2195msgid "Removed file `%s' containing invalid HELLO data.\n"
2196msgstr "Datei `%s' enthielt ungültige Hello Daten und wurde entfernt.\n"
2197
2198#: src/applications/identity/identity.c:809
2199#, c-format
2200msgid "Signature failed verification: peer `%s' not known.\n"
2201msgstr ""
2202"Signatur kann nicht verifiziert werden, der Knoten `%s' ist uns nicht "
2203"bekannt!\n"
2204
2205#: src/applications/identity/identity.c:819
2206msgid "Signature failed verification: signature invalid.\n"
2207msgstr "Verifikation einer Signatur fehlgeschlagen: Signatur ist ungültig.\n"
2208
2209#: src/applications/identity/identity.c:935
2210#: src/applications/identity/identity.c:1058
2211#, c-format
2212msgid "Peer `%s' is currently strictly blacklisted (for another %llums).\n"
2213msgstr ""
2214
2215#: src/applications/identity/identity.c:1061
2216#, c-format
2217msgid "Peer `%s' is currently blacklisted (for another %llums).\n"
2218msgstr ""
2219
2220#: src/applications/pingpong/pingpong.c:134
2221#: src/applications/pingpong/pingpong.c:203
2222#: src/applications/pingpong/pingpong.c:273
2223#: src/applications/pingpong/pingpong.c:345
2224#, c-format
2225msgid "Received malformed `%s' message. Dropping.\n"
2226msgstr "Beschädigte `%s' Nachricht empfangen. Nachricht wird verworfen.\n"
2227
2228#: src/applications/pingpong/pingpong.c:146
2229msgid "Received ping for another peer. Dropping.\n"
2230msgstr "Ping für einen anderen Knoten empfangen. Ping wird verworfen.\n"
2231
2232#: src/applications/pingpong/pingpong.c:215
2233#, fuzzy, c-format
2234msgid "Received PING from `%s' not destined for us!\n"
2235msgstr "Empfangener PING ist nicht an uns gerichtet!\n"
2236
2237#: src/applications/pingpong/pingpong.c:315
2238#: src/applications/pingpong/pingpong.c:381
2239msgid ""
2240"Could not match PONG against any PING. Try increasing MAX_PING_PONG "
2241"constant.\n"
2242msgstr ""
2243"PONG konnte keinem PING zugeordnet werden. Versuchen Sie die Konstante "
2244"MAX_PING_PONG hochzusetzen.\n"
2245
2246#: src/applications/pingpong/pingpong.c:425
2247msgid "Cannot create PING, table full. Try increasing MAX_PING_PONG.\n"
2248msgstr ""
2249"PING konnte nicht erstellt werden, da die Tabelle voll ist. Versuchen Sie, "
2250"die Konstante MAX_PING_PONG hochzusetzen.\n"
2251
2252#: src/applications/pingpong/pingpong.c:518
2253msgid "# encrypted PONG messages received"
2254msgstr "# verschlüsselter PONG Nachrichten empfangen"
2255
2256#: src/applications/pingpong/pingpong.c:520
2257msgid "# plaintext PONG messages received"
2258msgstr "# Klartext PONG Nachrichten empfangen"
2259
2260#: src/applications/pingpong/pingpong.c:522
2261msgid "# encrypted PING messages received"
2262msgstr "# verschlüsselter PING Nachrichten empfangen"
2263
2264#: src/applications/pingpong/pingpong.c:524
2265msgid "# PING messages created"
2266msgstr "# PING Nachrichten erstellt"
2267
2268#: src/applications/pingpong/pingpong.c:526
2269#: src/applications/session/connect.c:926
2270msgid "# encrypted PONG messages sent"
2271msgstr "# verschlüsselter PONG Nachrichten gesendet"
2272
2273#: src/applications/pingpong/pingpong.c:530
2274#: src/applications/session/connect.c:924
2275msgid "# encrypted PING messages sent"
2276msgstr "# verschlüsselter PING Nachrichten gesendet"
2277
2278#: src/applications/pingpong/pingpong.c:532
2279#, fuzzy
2280msgid "# plaintext PONG messages sent"
2281msgstr "# Klartext PING Nachrichten gesendet"
2282
2283#: src/applications/pingpong/pingpong.c:536
2284#, fuzzy
2285msgid "# plaintext PONG transmissions failed"
2286msgstr "# Klartext PONG Nachrichten empfangen"
2287
2288#: src/applications/pingpong/pingpong.c:546
2289#, c-format
2290msgid "`%s' registering handlers %d %d (plaintext and ciphertext)\n"
2291msgstr "`%s' registriert Handler %d %d (Plaintext und Ciphertext)\n"
2292
2293#: src/applications/hostlist/hostlist.c:165
2294#, fuzzy
2295msgid "# hostlist requests received"
2296msgstr "# Client Trace-Anfragen empfangen"
2297
2298#: src/applications/hostlist/hostlist.c:167
2299msgid "# hostlist HELLOs returned"
2300msgstr ""
2301
2302#: src/applications/hostlist/hostlist.c:169
2303msgid "# hostlist bytes returned"
2304msgstr ""
2305
2306#: src/applications/hostlist/hostlist.c:199
2307msgid "integrated HTTP hostlist server"
2308msgstr ""
2309
2310#: src/applications/session/connect.c:238
2311#, c-format
2312msgid "Session key from peer `%s' could not be verified.\n"
2313msgstr "Sitzungsschlüssel von Knoten `%s' konnte nicht überprüft werden.\n"
2314
2315#: src/applications/session/connect.c:282
2316#, c-format
2317msgid "Cannot encrypt sessionkey, peer `%s' not known!\n"
2318msgstr ""
2319"Sitzungsschlüssel kann nicht verschlüsselt werden, Knoten `%s' ist uns nicht "
2320"bekannt!\n"
2321
2322#: src/applications/session/connect.c:489
2323#, fuzzy, c-format
2324msgid "Could not create any HELLO for myself (have transports `%s')!\n"
2325msgstr "Hostkey konnte nicht erzeugt werden!\n"
2326
2327#: src/applications/session/connect.c:599
2328#, fuzzy, c-format
2329msgid "Session key received from peer `%s' has invalid format (discarded).\n"
2330msgstr "Empfangene Nachricht ist ungültig.\n"
2331
2332#: src/applications/session/connect.c:632
2333#, fuzzy, c-format
2334msgid "Session key received from peer `%s' is for `%s' and not for me!\n"
2335msgstr "Empfangene Nachricht ist ungültig.\n"
2336
2337#: src/applications/session/connect.c:659
2338#, c-format
2339msgid "Invalid `%s' message received from peer `%s'.\n"
2340msgstr "Ungültige `%s' Nachricht von Knoten `%s' empfangen.\n"
2341
2342#: src/applications/session/connect.c:670
2343#, c-format
2344msgid "setkey `%s' from `%s' fails CRC check (have: %u, want %u).\n"
2345msgstr ""
2346"setkey `%s' von `%s' hat eine ungültige CRC Prüfsumme (tatsächlich: %u, "
2347"erwartet: %u).\n"
2348
2349#: src/applications/session/connect.c:728
2350#, fuzzy, c-format
2351msgid ""
2352"Error parsing encrypted session key from `%s', given message part size is "
2353"invalid.\n"
2354msgstr ""
2355"Fehler beim Parsen des Verschlüsselten Sitzungsschlüssels, gegebene "
2356"Nachrichtenteilgröße ist ungültig.\n"
2357
2358#: src/applications/session/connect.c:741
2359#, fuzzy, c-format
2360msgid "Unknown type in embedded message from `%s': %u (size: %u)\n"
2361msgstr "Unbekannter Typ in engebetteter Nachricht: %u (%u bytes)\n"
2362
2363#: src/applications/session/connect.c:916
2364msgid "# session keys sent"
2365msgstr "# Sitzungsschlüssel gesendet"
2366
2367#: src/applications/session/connect.c:918
2368msgid "# session keys rejected"
2369msgstr "# Sitzungsschlüssel abgelehnt"
2370
2371#: src/applications/session/connect.c:920
2372msgid "# session keys accepted"
2373msgstr "# Sitzungsschlüssel akzeptiert"
2374
2375#: src/applications/session/connect.c:922
2376msgid "# sessions established"
2377msgstr "# Sitzungen aufgebaut"
2378
2379#: src/applications/fs/tools/gnunet-pseudonym.c:70
2380#: src/applications/fs/tools/gnunet-auto-share.c:199
2381#: src/applications/fs/tools/gnunet-insert.c:246
2382#: src/applications/fs/tools/gnunet-search.c:125
2383#: src/applications/fs/tools/gnunet-download.c:77
2384msgid "set the desired LEVEL of sender-anonymity"
2385msgstr "Gewünschten Grad an Sender-Anonymität festlegen"
2386
2387#: src/applications/fs/tools/gnunet-pseudonym.c:73
2388msgid "automate creation of a namespace by starting a collection"
2389msgstr ""
2390"Erstellung eines Namespaces durch das Anfangen einer Collection "
2391"automatisieren"
2392
2393#: src/applications/fs/tools/gnunet-pseudonym.c:77
2394msgid "create a new pseudonym under the given NICKNAME"
2395msgstr "Neues Pseudonym unter dem angegebenen NICKNAME erstellen"
2396
2397#: src/applications/fs/tools/gnunet-pseudonym.c:80
2398msgid "delete the pseudonym with the given NICKNAME"
2399msgstr "Pseudonym mit dem angegeben NICKNAME löschen"
2400
2401#: src/applications/fs/tools/gnunet-pseudonym.c:83
2402msgid "end automated building of a namespace (ends collection)"
2403msgstr ""
2404"Automatisierte Erstellung eines Namespaces beenden (beendet Collection)"
2405
2406#: src/applications/fs/tools/gnunet-pseudonym.c:85
2407msgid "Create new pseudonyms, delete pseudonyms or list existing pseudonyms."
2408msgstr ""
2409"Erstellen von neuen Pseudonymen, Löschen von Pseudonymen und Auflisten von "
2410"bestehenden Pseudonymen."
2411
2412#: src/applications/fs/tools/gnunet-pseudonym.c:89
2413msgid ""
2414"use the given keyword to advertise the namespace (use when creating a new "
2415"pseudonym)"
2416msgstr ""
2417"Das angegebene schlüsselwort verwenden, um den Namespace bekanntzumachen (zu "
2418"verwenden, wenn ein neues Pseudonym erstellt wird)"
2419
2420#: src/applications/fs/tools/gnunet-pseudonym.c:92
2421#, fuzzy
2422msgid "specify metadata describing the namespace or collection"
2423msgstr ""
2424"Automatisierte Erstellung eines Namespaces beenden (beendet Collection)"
2425
2426#: src/applications/fs/tools/gnunet-pseudonym.c:96
2427msgid ""
2428"do not generate an advertisement for this namespace (use when creating a new "
2429"pseudonym)"
2430msgstr ""
2431"Keine Bekanntmachung für diesen Namespace erstellen (zu verwenden, wenn ein "
2432"neues Pseudonym erstellt wird)"
2433
2434#: src/applications/fs/tools/gnunet-pseudonym.c:99
2435msgid "do not list the pseudonyms from the pseudonym database"
2436msgstr "Keine Ausgabe der Pseudonyme in der Pseudonymdatenbank"
2437
2438#: src/applications/fs/tools/gnunet-pseudonym.c:103
2439msgid ""
2440"specify IDENTIFIER to be the address of the entrypoint to content in the "
2441"namespace (use when creating a new pseudonym)"
2442msgstr ""
2443"IDENTIFIER als Adresse angeben, die der Einsprungspunkt zu den Inhalten im "
2444"Namespace ist (zu verwenden, wenn ein neues Pseudonym erstellt wird)"
2445
2446#: src/applications/fs/tools/gnunet-pseudonym.c:106
2447msgid "set the rating of a namespace"
2448msgstr "das Rating eines Namespaces setzen"
2449
2450#: src/applications/fs/tools/gnunet-pseudonym.c:141
2451#, c-format
2452msgid "Namespace `%s' has rating %d.\n"
2453msgstr "Namespace `%s' hat das Rating %d.\n"
2454
2455#: src/applications/fs/tools/gnunet-pseudonym.c:143
2456#, c-format
2457msgid "Namespace `%s' (%s) has rating %d.\n"
2458msgstr "Namespace `%s' (%s) hat das Rating %d.\n"
2459
2460#: src/applications/fs/tools/gnunet-pseudonym.c:175
2461#, c-format
2462msgid "\tRating (after update): %d\n"
2463msgstr "\tRating (nach Update): %d\n"
2464
2465#: src/applications/fs/tools/gnunet-pseudonym.c:179
2466#: src/applications/fs/tools/gnunet-pseudonym.c:241
2467#: src/applications/fs/tools/gnunet-insert.c:101
2468#, fuzzy, c-format
2469msgid "\tUnknown namespace `%s'\n"
2470msgstr "Unbekannte Operation `%s'\n"
2471
2472#: src/applications/fs/tools/gnunet-pseudonym.c:217
2473#, c-format
2474msgid "Collection stopped.\n"
2475msgstr "Collection beendet.\n"
2476
2477#: src/applications/fs/tools/gnunet-pseudonym.c:219
2478#, c-format
2479msgid "Failed to stop collection (not active?).\n"
2480msgstr "Fehler beim Beenden der Collection (nicht aktiv?).\n"
2481
2482#: src/applications/fs/tools/gnunet-pseudonym.c:230
2483#, c-format
2484msgid "Pseudonym `%s' deleted.\n"
2485msgstr "Pseudonym `%s' wurde gelöscht.\n"
2486
2487#: src/applications/fs/tools/gnunet-pseudonym.c:235
2488#, c-format
2489msgid "Error deleting pseudonym `%s' (does not exist?).\n"
2490msgstr "Fehler beim Löschen des Pseudonyms `%s' (existiert nicht?).\n"
2491
2492#: src/applications/fs/tools/gnunet-pseudonym.c:256
2493#, fuzzy
2494msgid "Started collection.\n"
2495msgstr "Collection `%s' begonnen.\n"
2496
2497#: src/applications/fs/tools/gnunet-pseudonym.c:260
2498msgid "Failed to start collection.\n"
2499msgstr "Fehler beim Starten der Collection.\n"
2500
2501#: src/applications/fs/tools/gnunet-pseudonym.c:296
2502#, fuzzy
2503msgid "Could not create namespace.\n"
2504msgstr "Namespace `%s' konnte nicht erstellt werden (existiert bereits?).\n"
2505
2506#: src/applications/fs/tools/gnunet-pseudonym.c:304
2507#, c-format
2508msgid "Namespace `%s' created (root: %s).\n"
2509msgstr "Namespace `%s' wurde erstellt (Root: %s).\n"
2510
2511#: src/applications/fs/tools/gnunet-pseudonym.c:321
2512#, fuzzy, c-format
2513msgid "You must specify a name for the collection (`%s' option).\n"
2514msgstr ""
2515"Sie müssen einen Namen für die PID Datei in Sektion `%s' unter `%s' "
2516"angeben.\n"
2517
2518#: src/applications/fs/tools/gnunet-pseudonym.c:329
2519#, c-format
2520msgid "Could not access namespace information.\n"
2521msgstr "Auf die Namespace Informationen konnte nicht zugegriffen werden.\n"
2522
2523#: src/applications/fs/tools/gnunet-directory.c:84
2524#, c-format
2525msgid "==> Directory `%s':\n"
2526msgstr "==> Verzeichnis `%s':\n"
2527
2528#: src/applications/fs/tools/gnunet-directory.c:88
2529#, c-format
2530msgid "=\tError reading directory.\n"
2531msgstr "=\tFehler beim Lesen des Verzeichnisses.\n"
2532
2533#: src/applications/fs/tools/gnunet-directory.c:118
2534#, c-format
2535msgid "File format error (not a GNUnet directory?)\n"
2536msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n"
2537
2538#: src/applications/fs/tools/gnunet-directory.c:120
2539#, c-format
2540msgid "%d files found in directory.\n"
2541msgstr "%d Dateien im Verzeichnis gefunden.\n"
2542
2543#: src/applications/fs/tools/gnunet-directory.c:135
2544msgid "Perform directory related operations."
2545msgstr "Verzeichnisbezogene Operationen durchführen."
2546
2547#: src/applications/fs/tools/gnunet-directory.c:138
2548msgid "remove all entries from the directory database and stop tracking URIs"
2549msgstr ""
2550"Alle Einträge aus der Verzeichnis Datenbank löschen und das Verfolgen von "
2551"URIs abbrechen"
2552
2553#: src/applications/fs/tools/gnunet-directory.c:142
2554msgid "list entries from the directory database"
2555msgstr "Einträge aus der Verzeichnis Datenbank auflisten"
2556
2557#: src/applications/fs/tools/gnunet-directory.c:145
2558msgid "start tracking entries for the directory database"
2559msgstr "Anfangen, Einträge für die Verzeichnis Datenbank zu verfolgen"
2560
2561#: src/applications/fs/tools/gnunet-directory.c:168
2562#, c-format
2563msgid "Listed %d matching entries.\n"
2564msgstr "%d übereinstimmende Einträge aufgelistet.\n"
2565
2566#: src/applications/fs/tools/gnunet-auto-share.c:117
2567#, fuzzy, c-format
2568msgid "Upload of `%s' at %llu out of %llu bytes.\n"
2569msgstr "Download der Datei `%s' bei %16llu von %16llu Bytes (%8.3f kbps)\n"
2570
2571#: src/applications/fs/tools/gnunet-auto-share.c:130
2572#, fuzzy, c-format
2573msgid "Upload of `%s' complete, URI is `%s'.\n"
2574msgstr ""
2575"Upload von `%s' komplett, derzeitige durchschnittliche Geschwindigkeit "
2576"beträgt %8.3f KB/s.\n"
2577
2578#: src/applications/fs/tools/gnunet-auto-share.c:139
2579#, fuzzy, c-format
2580msgid "Upload aborted.\n"
2581msgstr ""
2582"\n"
2583"Upload abgebrochen.\n"
2584
2585#: src/applications/fs/tools/gnunet-auto-share.c:145
2586#, fuzzy, c-format
2587msgid "Error uploading file: %s\n"
2588msgstr ""
2589"\n"
2590"Fehler beim Uploaden der Datei: %s\n"
2591
2592#: src/applications/fs/tools/gnunet-auto-share.c:154
2593#, fuzzy, c-format
2594msgid "Starting upload of `%s'.\n"
2595msgstr "Collection `%s' begonnen.\n"
2596
2597#: src/applications/fs/tools/gnunet-auto-share.c:164
2598#, fuzzy, c-format
2599msgid "Uploading suspended.\n"
2600msgstr "Upload abgewiesen!"
2601
2602#: src/applications/fs/tools/gnunet-auto-share.c:179
2603#, fuzzy, c-format
2604msgid "Uploading `%s' resumed.\n"
2605msgstr "Upload abgewiesen!"
2606
2607#: src/applications/fs/tools/gnunet-auto-share.c:186
2608#, c-format
2609msgid "Unexpected event: %d\n"
2610msgstr ""
2611
2612#: src/applications/fs/tools/gnunet-auto-share.c:205
2613#, fuzzy
2614msgid ""
2615"run in debug mode; gnunet-auto-share will not daemonize and error messages "
2616"will be written to stderr instead of a logfile"
2617msgstr ""
2618"Im Debug-Modus ausführen. gnunetd wird nicht im Hintergrund laufen und "
2619"Fehlermeldungen werden nicht in die Protokolldatei, sondern auf die "
2620"Standardfehlerausgabe (stderr) geschrieben."
2621
2622#: src/applications/fs/tools/gnunet-auto-share.c:211
2623#: src/applications/fs/tools/gnunet-insert.c:259
2624#, fuzzy
2625msgid ""
2626"do not use libextractor to add additional references to directory entries "
2627"and/or the published file"
2628msgstr ""
2629"benutze libextractor um weitere direkte Referenzen zu Dateien in "
2630"Verzeichnissen zu erzeugen"
2631
2632#: src/applications/fs/tools/gnunet-auto-share.c:213
2633msgid "Automatically share a directory."
2634msgstr ""
2635
2636#: src/applications/fs/tools/gnunet-auto-share.c:216
2637#: src/applications/fs/tools/gnunet-insert.c:273
2638msgid ""
2639"add an additional keyword for all files and directories (this option can be "
2640"specified multiple times)"
2641msgstr ""
2642"Ein zusätzliches Schlüsselwort für alle Dateien und Verzeichnisse hinzufügen "
2643"(diese Option kann mehrmals angegeben werden)"
2644
2645#: src/applications/fs/tools/gnunet-auto-share.c:221
2646#: src/applications/fs/tools/gnunet-insert.c:290
2647msgid "specify the priority of the content"
2648msgstr "Die Priorität des Inhalts angeben"
2649
2650#: src/applications/fs/tools/gnunet-auto-share.c:468
2651#: src/applications/fs/tools/gnunet-auto-share.c:903
2652#, fuzzy, c-format
2653msgid "Could not access `%s': %s\n"
2654msgstr "`%s' konnte nicht aufgelöst werden: %s\n"
2655
2656#: src/applications/fs/tools/gnunet-auto-share.c:547
2657#, c-format
2658msgid "Unknown keyword type `%s' in metadata configuration\n"
2659msgstr ""
2660
2661#: src/applications/fs/tools/gnunet-auto-share.c:652
2662#, fuzzy, c-format
2663msgid "Failed to stop running gnunet-auto-share.\n"
2664msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n"
2665
2666#: src/applications/fs/tools/gnunet-auto-share.c:918
2667#, c-format
2668msgid "Directory `%s' is already on the list of shared directories.\n"
2669msgstr ""
2670
2671#: src/applications/fs/tools/gnunet-auto-share.c:939
2672msgid ""
2673"The specified directories were added to the list of shared directories.\n"
2674msgstr ""
2675
2676#: src/applications/fs/tools/gnunet-auto-share.c:961
2677#, fuzzy, c-format
2678msgid "Could not open logfile `%s': %s\n"
2679msgstr "Datei wurde als `%s' gespeichert.\n"
2680
2681#: src/applications/fs/tools/gnunet-insert.c:115
2682#, c-format
2683msgid "Created entry `%s' in namespace `%s'\n"
2684msgstr "Eintag `%s' in Namespace `%s' wurde erstellt\n"
2685
2686#: src/applications/fs/tools/gnunet-insert.c:120
2687#, c-format
2688msgid "Failed to add entry to namespace `%s' (does it exist?)\n"
2689msgstr ""
2690"Der Eintrag konnte dem Namespace `%s' nicht hinzugefügt werden (existiert "
2691"er?)\n"
2692
2693#: src/applications/fs/tools/gnunet-insert.c:135
2694#, c-format
2695msgid "Keywords for file `%s':\n"
2696msgstr "Schlüsselwörter für Datei `%s':\n"
2697
2698#: src/applications/fs/tools/gnunet-insert.c:144
2699msgid "filename"
2700msgstr ""
2701
2702#: src/applications/fs/tools/gnunet-insert.c:146
2703msgid "mimetype"
2704msgstr ""
2705
2706#: src/applications/fs/tools/gnunet-insert.c:186
2707#, c-format
2708msgid "%16llu of %16llu bytes inserted (estimating %6s to completion) - %s\n"
2709msgstr ""
2710"%16llu von %16llu Bytes eingefügt (geschätzte %6s bis Fertigstellung) - %s\n"
2711
2712#: src/applications/fs/tools/gnunet-insert.c:198
2713#, c-format
2714msgid "Upload of `%s' complete, %llu bytes took %llu seconds (%8.3f KiB/s).\n"
2715msgstr ""
2716"Upload von `%s' komplett, %llu Bytes brauchten %llu Sekunden (%8.3f KB/s).\n"
2717
2718#: src/applications/fs/tools/gnunet-insert.c:209
2719#, c-format
2720msgid "File `%s' has URI: %s\n"
2721msgstr "Datei `%s' hat URI: %s\n"
2722
2723#: src/applications/fs/tools/gnunet-insert.c:220
2724#, c-format
2725msgid ""
2726"\n"
2727"Upload aborted.\n"
2728msgstr ""
2729"\n"
2730"Upload abgebrochen.\n"
2731
2732#: src/applications/fs/tools/gnunet-insert.c:225
2733#, fuzzy, c-format
2734msgid ""
2735"\n"
2736"Error uploading file: %s"
2737msgstr ""
2738"\n"
2739"Fehler beim Uploaden der Datei: %s\n"
2740
2741#: src/applications/fs/tools/gnunet-insert.c:234
2742#, c-format
2743msgid ""
2744"\n"
2745"Unexpected event: %d\n"
2746msgstr ""
2747
2748#: src/applications/fs/tools/gnunet-insert.c:250
2749msgid ""
2750"even if gnunetd is running on the local machine, force the creation of a "
2751"copy instead of making a link to the GNUnet share directory"
2752msgstr ""
2753"Obwohl gnunetd auf der lokalen Maschiene läuft die Erstellung einer Kopie "
2754"anstelle der Erzeugung eines Links auf das GNUnet Share-Verzeichnis "
2755"erzwingen."
2756
2757#: src/applications/fs/tools/gnunet-insert.c:255
2758msgid "disable adding the creation time to the metadata of the uploaded file"
2759msgstr ""
2760
2761#: src/applications/fs/tools/gnunet-insert.c:263
2762msgid ""
2763"print list of extracted keywords that would be used, but do not perform "
2764"upload"
2765msgstr ""
2766"Liste der extrahierten Schlüsselworte, die verwendet werden würden, "
2767"ausgeben, aber keinen Upload durchführen"
2768
2769#: src/applications/fs/tools/gnunet-insert.c:265
2770msgid "Make files available to GNUnet for sharing."
2771msgstr "Dateien GNUnet zum Filesharing zur Verfügung stellen."
2772
2773#: src/applications/fs/tools/gnunet-insert.c:269
2774msgid ""
2775"add an additional keyword for the top-level file or directory (this option "
2776"can be specified multiple times)"
2777msgstr ""
2778"Ein zusätzliches Schlüsselwort für die Datei oder das Verzeichnis auf der "
2779"obersten Ebene hinzufügen (diese Option kann mehrmals angegeben werden)"
2780
2781#: src/applications/fs/tools/gnunet-insert.c:278
2782msgid "set the meta-data for the given TYPE to the given VALUE"
2783msgstr ""
2784"Die Meta-Daten des angegebenen Typs TYPE auf den angegebenen Wert VALUE "
2785"setzen"
2786
2787#: src/applications/fs/tools/gnunet-insert.c:281
2788msgid ""
2789"do not index, perform full insertion (stores entire file in encrypted form "
2790"in GNUnet database)"
2791msgstr ""
2792"Nicht indizieren, sondern komplett einfügen (speichert die gesamte Datei in "
2793"verschlüsselter Form in der GNUnet Datenbank)"
2794
2795#: src/applications/fs/tools/gnunet-insert.c:286
2796msgid ""
2797"specify ID of an updated version to be published in the future (for "
2798"namespace insertions only)"
2799msgstr ""
2800"ID einer aktualisierten Version angeben, die in der Zukunft veröffentlich "
2801"werden soll. (nur für das Einfügen in Namespaces)"
2802
2803#: src/applications/fs/tools/gnunet-insert.c:294
2804msgid "publish the files under the pseudonym NAME (place file into namespace)"
2805msgstr ""
2806"Die Datei unter dem Pseudonym NAME veröffentlichen (platziert die Datei in "
2807"einem Namespace)"
2808
2809#: src/applications/fs/tools/gnunet-insert.c:297
2810msgid ""
2811"only simulte the process but do not do any actual publishing (useful to "
2812"compute URIs)"
2813msgstr ""
2814
2815#: src/applications/fs/tools/gnunet-insert.c:301
2816msgid ""
2817"set the ID of this version of the publication (for namespace insertions only)"
2818msgstr ""
2819"die ID dieser Version der Veröffentlichung setzen (nur für das Einfügen in "
2820"Namespaces)"
2821
2822#: src/applications/fs/tools/gnunet-insert.c:305
2823msgid ""
2824"URI to be published (can be used instead of passing a file to add keywords "
2825"to the file with the respective URI)"
2826msgstr ""
2827
2828#: src/applications/fs/tools/gnunet-insert.c:342
2829#, c-format
2830msgid "You must specify one and only one filename for insertion.\n"
2831msgstr "Sie dürfen nur eine Datei zum Deindizieren angeben.\n"
2832
2833#: src/applications/fs/tools/gnunet-insert.c:348
2834#, fuzzy, c-format
2835msgid "You must NOT specify an URI and a filename.\n"
2836msgstr "Sie müssen einen Empfänger angeben!\n"
2837
2838#: src/applications/fs/tools/gnunet-insert.c:354
2839#, c-format
2840msgid "Cannot extract metadata from a URI!\n"
2841msgstr ""
2842
2843#: src/applications/fs/tools/gnunet-insert.c:400
2844#, c-format
2845msgid "Could not access namespace `%s' (does not exist?).\n"
2846msgstr "Konnte nicht auf den Namespace `%s' zugreifen (existiert nicht?).\n"
2847
2848#: src/applications/fs/tools/gnunet-insert.c:408
2849#, fuzzy, c-format
2850msgid "Option `%s' is required when using option `%s'.\n"
2851msgstr "Option `%s' macht keinen Sinn ohne die Option `%s'.\n"
2852
2853#: src/applications/fs/tools/gnunet-insert.c:419
2854#: src/applications/fs/tools/gnunet-insert.c:427
2855#, c-format
2856msgid "Option `%s' makes no sense without option `%s'.\n"
2857msgstr "Option `%s' macht keinen Sinn ohne die Option `%s'.\n"
2858
2859#: src/applications/fs/tools/gnunet-search.c:128
2860msgid "Search GNUnet for files."
2861msgstr "Das GNUnet nach Dateien durchsuchen."
2862
2863#: src/applications/fs/tools/gnunet-search.c:132
2864msgid "write encountered (decrypted) search results to FILENAME"
2865msgstr "Begegnete (entschlüsselte) Suchergebnisse in FILENAME schreiben"
2866
2867#: src/applications/fs/tools/gnunet-search.c:169
2868#, c-format
2869msgid "Error converting arguments to URI!\n"
2870msgstr "Fehler beim Konvertieren von Parametern in URI!\n"
2871
2872#: src/applications/fs/tools/gnunet-unindex.c:61
2873#, c-format
2874msgid ""
2875"%16llu of %16llu bytes unindexed (estimating %llu seconds to "
2876"completion) "
2877msgstr ""
2878"%16llu von %16llu Bytes deindiziert (schätze %llu Sekunden bis "
2879"Fertigstellung) "
2880
2881#: src/applications/fs/tools/gnunet-unindex.c:73
2882#, c-format
2883msgid ""
2884"\n"
2885"Unindexing of `%s' complete, %llu bytes took %llu seconds (%8.3f KiB/s).\n"
2886msgstr ""
2887"\n"
2888"Deindizierung von `%s' abgeschlossen, %llu Bytes benötigten %llu Sekunden (%"
2889"8.3f kbps).\n"
2890
2891#: src/applications/fs/tools/gnunet-unindex.c:88
2892#, c-format
2893msgid ""
2894"\n"
2895"Error unindexing file: %s\n"
2896msgstr ""
2897"\n"
2898"Fehler beim Deindizieren der Datei: %s\n"
2899
2900#: src/applications/fs/tools/gnunet-unindex.c:108
2901msgid "Unindex files."
2902msgstr "Dateien deindizieren."
2903
2904#: src/applications/fs/tools/gnunet-unindex.c:145
2905#, fuzzy
2906msgid "Not enough arguments. You must specify a filename.\n"
2907msgstr "Nicht genügend Parameter. Sie müssen eine GNUnet Datei URI angeben\n"
2908
2909#: src/applications/fs/tools/gnunet-unindex.c:163
2910#, c-format
2911msgid "`%s' failed. Is `%s' a file?\n"
2912msgstr "`%s' schlug fehl. Ist `%s' eine Datei?\n"
2913
2914#: src/applications/fs/tools/gnunet-download.c:82
2915msgid ""
2916"download a GNUnet directory that has already been downloaded. Requires that "
2917"a filename of an existing file is specified instead of the URI. The "
2918"download will only download the top-level files in the directory unless the "
2919"`-R' option is also specified."
2920msgstr ""
2921
2922#: src/applications/fs/tools/gnunet-download.c:85
2923msgid "delete incomplete downloads (when aborted with CTRL-C)"
2924msgstr ""
2925
2926#: src/applications/fs/tools/gnunet-download.c:87
2927msgid "Download files from GNUnet."
2928msgstr "Dateien aus dem GNUnet herunterladen."
2929
2930#: src/applications/fs/tools/gnunet-download.c:91
2931msgid "write the file to FILENAME"
2932msgstr "Schreibe die Datei in DATEINAME"
2933
2934#: src/applications/fs/tools/gnunet-download.c:95
2935msgid "set the maximum number of parallel downloads that are allowed"
2936msgstr ""
2937
2938#: src/applications/fs/tools/gnunet-download.c:98
2939msgid "download a GNUnet directory recursively"
2940msgstr "Das GNUnet Verzeichnis rekursiv herunterladen"
2941
2942#: src/applications/fs/tools/gnunet-download.c:119
2943#, c-format
2944msgid "Download of file `%s' at %16llu out of %16llu bytes (%8.3f KiB/s)\n"
2945msgstr "Download der Datei `%s' bei %16llu von %16llu Bytes (%8.3f kbps)\n"
2946
2947#: src/applications/fs/tools/gnunet-download.c:133
2948#, c-format
2949msgid "Download aborted.\n"
2950msgstr "Download abgebrochen.\n"
2951
2952#: src/applications/fs/tools/gnunet-download.c:139
2953#, c-format
2954msgid "Error downloading: %s\n"
2955msgstr "Fehler beim Download: %s\n"
2956
2957#: src/applications/fs/tools/gnunet-download.c:145
2958#, c-format
2959msgid "Download of file `%s' complete. Speed was %8.3f KiB per second.\n"
2960msgstr ""
2961"Download der Datei `%s' abgeschlossen. Geschwindigkeit war %8.3f KB/s.\n"
2962
2963#: src/applications/fs/tools/gnunet-download.c:191
2964msgid "no name given"
2965msgstr ""
2966
2967#: src/applications/fs/tools/gnunet-download.c:197
2968#, fuzzy, c-format
2969msgid "Starting download `%s'\n"
2970msgstr "Collection `%s' begonnen.\n"
2971
2972#: src/applications/fs/tools/gnunet-download.c:239
2973msgid "Not enough arguments. You must specify a GNUnet file URI\n"
2974msgstr "Nicht genügend Parameter. Sie müssen eine GNUnet Datei URI angeben\n"
2975
2976#: src/applications/fs/tools/gnunet-download.c:257
2977#, c-format
2978msgid "URI `%s' invalid for gnunet-download.\n"
2979msgstr "URI `%s' ist ungültig für gnunet-download.\n"
2980
2981#: src/applications/fs/tools/gnunet-download.c:300
2982#, fuzzy, c-format
2983msgid "No filename specified, using `%s' instead (for now).\n"
2984msgstr "Kein Tabellenname angegeben, verwende `%s'.\n"
2985
2986#: src/applications/fs/tools/gnunet-download.c:342
2987#, fuzzy, c-format
2988msgid "Could not access gnunet-directory file `%s'\n"
2989msgstr "Konfigurationsdatei `%s' konnte nicht geparst werden.\n"
2990
2991#: src/applications/fs/tools/gnunet-download.c:363
2992#, fuzzy, c-format
2993msgid "Downloading %d files from directory `%s'.\n"
2994msgstr "Dateien aus dem GNUnet herunterladen."
2995
2996#: src/applications/fs/tools/gnunet-download.c:366
2997#, fuzzy, c-format
2998msgid "Did not find any files in directory `%s'\n"
2999msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n"
3000
3001#: src/applications/fs/tools/gnunet-download.c:404
3002#, c-format
3003msgid "File stored as `%s'.\n"
3004msgstr "Datei wurde als `%s' gespeichert.\n"
3005
3006#: src/applications/fs/uritrack/file_info.c:98
3007msgid "Collecting file identifiers disabled.\n"
3008msgstr "Einsammeln von Dateibezeichnern deaktiviert.\n"
3009
3010#: src/applications/fs/uritrack/file_info.c:377
3011#, c-format
3012msgid "Deleted corrupt URI database in `%s'."
3013msgstr ""
3014
3015#: src/applications/fs/ecrs/upload.c:158
3016#, c-format
3017msgid "`%s' is not a file.\n"
3018msgstr "`%s' ist keine Datei.\n"
3019
3020#: src/applications/fs/ecrs/upload.c:166
3021#, c-format
3022msgid "Cannot get size of file `%s'"
3023msgstr "Die Größe der Datei `%s' konnte nicht ermittelt werden"
3024
3025#: src/applications/fs/ecrs/upload.c:175
3026msgid "Failed to connect to gnunetd."
3027msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden."
3028
3029#: src/applications/fs/ecrs/upload.c:187
3030#, c-format
3031msgid "Cannot hash `%s'.\n"
3032msgstr "`%s' konnte nicht gehashed werden.\n"
3033
3034#: src/applications/fs/ecrs/upload.c:215
3035#, c-format
3036msgid "Initialization for indexing file `%s' failed.\n"
3037msgstr "Initialisierung der Indizierung der Datei `%s' fehlgeschlagen.\n"
3038
3039#: src/applications/fs/ecrs/upload.c:223
3040#, fuzzy, c-format
3041msgid "Indexing file `%s' failed. Suggestion: try to insert the file.\n"
3042msgstr "Indizieren der Datei `%s' schlug fehl. Versuch Datei einzufügen...\n"
3043
3044#: src/applications/fs/ecrs/upload.c:237
3045#, fuzzy, c-format
3046msgid "Cannot open file `%s': `%s'"
3047msgstr "Konfigurationsdatei `%s' konnte nicht geöffnet werden.\n"
3048
3049#: src/applications/fs/ecrs/upload.c:322
3050#, fuzzy, c-format
3051msgid "Indexing data of file `%s' failed at position %llu.\n"
3052msgstr "Indizierung der Daten schlug an Position %i fehl.\n"
3053
3054#: src/applications/fs/ecrs/helper.c:91
3055msgid "No keywords specified!\n"
3056msgstr "Keine Schlüsselwörter angegeben!\n"
3057
3058#: src/applications/fs/ecrs/helper.c:99
3059msgid "Number of double-quotes not balanced!\n"
3060msgstr ""
3061
3062#: src/applications/fs/ecrs/helper.c:398
3063#, c-format
3064msgid "Renaming of file `%s' to `%s' failed: %s\n"
3065msgstr "Umbenennen der Datei `%s' zu `%s' fehlgeschlagen: %s\n"
3066
3067#: src/applications/fs/ecrs/helper.c:408
3068#, c-format
3069msgid "Could not rename file `%s' to `%s': file exists\n"
3070msgstr ""
3071"Datei `%s' konnte nicht zu `%s' umbenannt werden: Datei existiert bereits\n"
3072
3073#: src/applications/fs/ecrs/parser.c:165
3074#, c-format
3075msgid ""
3076"Unknown metadata type in metadata option `%s'. Using metadata type "
3077"`unknown' instead.\n"
3078msgstr ""
3079
3080#: src/applications/fs/ecrs/search.c:152
3081msgid "CHK URI not allowed for search.\n"
3082msgstr "CHK URI ist nicht erlaubt für Suchen.\n"
3083
3084#: src/applications/fs/ecrs/search.c:207
3085msgid "LOC URI not allowed for search.\n"
3086msgstr "LOC URI ist nicht erlaubt für Suchen.\n"
3087
3088#: src/applications/fs/ecrs/namespace.c:365
3089#, c-format
3090msgid "File `%s' does not contain a pseudonym.\n"
3091msgstr "Die Datei `%s' enthält kein Pseudonym.\n"
3092
3093#: src/applications/fs/ecrs/namespace.c:376
3094#, c-format
3095msgid "Format of pseudonym `%s' is invalid.\n"
3096msgstr "Format des Pseudonyms `%s' ist ungültig.\n"
3097
3098#: src/applications/fs/ecrs/namespace.c:535
3099#: src/applications/fs/ecrs/namespace.c:547
3100#: src/applications/fs/ecrs/namespace.c:559
3101#, fuzzy, c-format
3102msgid "Format of file `%s' is invalid, trying to remove.\n"
3103msgstr "Format der Datei `%s' ist ungültig.\n"
3104
3105#: src/applications/fs/ecrs/download.c:599
3106msgid ""
3107"Decrypted content does not match key. This is either a bug or a maliciously "
3108"inserted file. Download aborted.\n"
3109msgstr ""
3110"Entschlüsselter Inhalt entspricht nicht dem Schlüssel. Dies ist entweder ein "
3111"Bug oder eine mit bösen Absichten eingefügte Datei. Download wurde "
3112"abgebrochen.\n"
3113
3114#: src/applications/fs/ecrs/download.c:609
3115msgid "IO error."
3116msgstr ""
3117
3118#: src/applications/fs/collection/collection.c:559
3119#: src/applications/fs/collection/collection.c:562
3120#, c-format
3121msgid "Revision %u"
3122msgstr ""
3123
3124#: src/applications/fs/fsui/upload.c:330
3125#, fuzzy
3126msgid "Application aborted."
3127msgstr "_Optionen"
3128
3129#: src/applications/fs/fsui/upload.c:344
3130#, fuzzy
3131msgid "Failed to create temporary directory."
3132msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n"
3133
3134#: src/applications/fs/fsui/deserialize.c:927
3135#, c-format
3136msgid "FSUI state file `%s' had syntax error at offset %u.\n"
3137msgstr "FSUI Statusdatei `%s' hatte einen Syntaxfehler bei Offset %u.\n"
3138
3139#: src/applications/fs/fsui/unindex.c:114
3140msgid "Unindexing failed (no reason given)"
3141msgstr ""
3142
3143#: src/applications/fs/gap/plan.c:944
3144#, fuzzy
3145msgid "# gap requests total sent"
3146msgstr "# gap Anfragen insgesamt empfangen"
3147
3148#: src/applications/fs/gap/plan.c:946
3149#, fuzzy
3150msgid "# gap content total planned"
3151msgstr "# gap Anfragen insgesamt empfangen"
3152
3153#: src/applications/fs/gap/plan.c:948
3154#, fuzzy
3155msgid "# gap routes succeeded"
3156msgstr "# gap Routing erfolgreich (insgesamt)"
3157
3158#: src/applications/fs/gap/plan.c:949
3159msgid "# trust spent"
3160msgstr ""
3161
3162#: src/applications/fs/gap/fs.c:157
3163msgid "Datastore full.\n"
3164msgstr ""
3165
3166#: src/applications/fs/gap/fs.c:831
3167msgid "# gap requests total received"
3168msgstr "# gap Anfragen insgesamt empfangen"
3169
3170#: src/applications/fs/gap/fs.c:833
3171#, fuzzy
3172msgid "# gap requests dropped due to load"
3173msgstr "# gap Anfragen verworfen: Kollision in RT"
3174
3175#: src/applications/fs/gap/fs.c:835
3176#, fuzzy
3177msgid "# gap content total received"
3178msgstr "# gap Anfragen insgesamt empfangen"
3179
3180#: src/applications/fs/gap/fs.c:837
3181msgid "# gap total trust awarded"
3182msgstr ""
3183
3184#: src/applications/fs/gap/fs.c:865
3185#, fuzzy, c-format
3186msgid ""
3187"`%s' registering client handlers %d %d %d %d %d %d %d %d and P2P handlers %d "
3188"%d\n"
3189msgstr "`%s' registriert die Client Handler %d %d %d %d %d %d %d %d %d\n"
3190
3191#: src/applications/fs/gap/fs.c:921
3192msgid "enables (anonymous) file-sharing"
3193msgstr "Ermöglicht (anonymes) Filesharing"
3194
3195#: src/applications/fs/gap/ondemand.c:173
3196#, c-format
3197msgid ""
3198"Because the file `%s' has been unavailable for 3 days it got removed from "
3199"your share. Please unindex files before deleting them as the index now "
3200"contains invalid references!\n"
3201msgstr ""
3202"Weil die Datei `%s' nun seit 3 Tagen nicht zur Verfügung steht, wurde Sie "
3203"aus Ihrem Share entfernt. Bitte deindizieren Sie Dateien, bevor Sie sie "
3204"löschen, da Ihr Index nun ungültige Referenzen enthält!\n"
3205
3206#: src/applications/fs/gap/ondemand.c:451
3207msgid "Indexed content changed (does not match its hash).\n"
3208msgstr ""
3209
3210#: src/applications/fs/gap/ondemand.c:569
3211#, c-format
3212msgid ""
3213"Unindexed ODB block `%s' from offset %llu already missing from datastore.\n"
3214msgstr ""
3215"Deindizierter ODB Block `%s' vom Offset %llu fehlt bereits im "
3216"Datenspeicher.\n"
3217
3218#: src/applications/fs/gap/pid_table.c:177
3219msgid "# distinct interned peer IDs in pid table"
3220msgstr ""
3221
3222#: src/applications/fs/gap/pid_table.c:180
3223msgid "# total RC of interned peer IDs in pid table"
3224msgstr ""
3225
3226#: src/applications/fs/gap/querymanager.c:708
3227#, fuzzy
3228msgid "# gap client queries received"
3229msgstr "# gap Anfragen insgesamt empfangen"
3230
3231#: src/applications/fs/gap/querymanager.c:710
3232#, fuzzy
3233msgid "# gap replies sent to clients"
3234msgstr "# gap Anfragen insgesamt empfangen"
3235
3236#: src/applications/fs/gap/querymanager.c:712
3237#, fuzzy
3238msgid "# gap client requests tracked"
3239msgstr "# gap Anfragen insgesamt empfangen"
3240
3241#: src/applications/fs/gap/querymanager.c:714
3242#, fuzzy
3243msgid "# gap client requests injected"
3244msgstr "# Client Trace-Anfragen empfangen"
3245
3246#: src/applications/fs/gap/querymanager.c:717
3247msgid "# gap query bloomfilter resizing updates"
3248msgstr ""
3249
3250#: src/applications/fs/gap/migration.c:437
3251msgid "# blocks migrated"
3252msgstr "# Blöcke migriert"
3253
3254#: src/applications/fs/gap/migration.c:439
3255#, fuzzy
3256msgid "# blocks injected for migration"
3257msgstr "# Blöcke migriert"
3258
3259#: src/applications/fs/gap/migration.c:441
3260#, fuzzy
3261msgid "# blocks fetched for migration"
3262msgstr "# Blöcke migriert"
3263
3264#: src/applications/fs/gap/migration.c:443
3265#, fuzzy
3266msgid "# on-demand fetches for migration"
3267msgstr "# Blöcke migriert"
3268
3269#: src/applications/fs/gap/gap.c:694
3270#, fuzzy
3271msgid "# gap queries dropped (table full)"
3272msgstr "# gap falsche Antworten"
3273
3274#: src/applications/fs/gap/gap.c:696
3275#, fuzzy
3276msgid "# gap queries dropped (redundant)"
3277msgstr "# gap falsche Antworten"
3278
3279#: src/applications/fs/gap/gap.c:698
3280#, fuzzy
3281msgid "# gap queries routed"
3282msgstr "# dht Anfragen weitergeleitet"
3283
3284#: src/applications/fs/gap/gap.c:700
3285msgid "# gap content found locally"
3286msgstr ""
3287
3288#: src/applications/fs/gap/gap.c:703
3289msgid "# gap queries refreshed existing record"
3290msgstr ""
3291
3292#: src/applications/fs/gap/gap.c:704
3293#, fuzzy
3294msgid "# trust earned"
3295msgstr "# dht Anfragen weitergeleitet"
3296
3297#: src/applications/fs/gap/fs_dht.c:256
3298msgid "# blocks pushed into DHT"
3299msgstr ""
3300
3301#: src/applications/fs/gap/anonymity.c:56
3302msgid "Failed to get traffic stats.\n"
3303msgstr "Statistiken über den Netzwerkverkehr konnten nicht ermittelt werden.\n"
3304
3305#: src/applications/testing/remote.c:68
3306#, c-format
3307msgid "scp command is : %s \n"
3308msgstr ""
3309
3310#: src/applications/testing/remote.c:491
3311#, fuzzy, c-format
3312msgid "Friend list of %s:%d\n"
3313msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n"
3314
3315#: src/applications/testing/remote.c:513
3316#, c-format
3317msgid "scp command for friend file copy is : %s \n"
3318msgstr ""
3319
3320#: src/applications/testing/remote.c:535
3321#, fuzzy, c-format
3322msgid "connecting peer %s:%d to peer %s:%d\n"
3323msgstr "Verbindung zu %u.%u.%u.%u:%u fehlgeschlagen: %s\n"
3324
3325#: src/applications/testing/remotetest.c:38
3326msgid "Set up multiple gnunetd daemons across multiple hosts."
3327msgstr ""
3328
3329#: src/applications/testing/remotetest.c:43
3330#, fuzzy
3331msgid "set number of daemons to start"
3332msgstr "Anzahl an Nachrichten, die pro Durchlauf verwendet wird"
3333
3334#: src/applications/testing/testing.c:268
3335#: src/applications/testing/remotetopologies.c:367
3336#, fuzzy, c-format
3337msgid "Waiting for peers to connect"
3338msgstr ""
3339"Warte darauf, dass sich andere Knoten verbinden (%u Iterationen "
3340"verbleiben)...\n"
3341
3342#: src/applications/testing/remotetopologies.c:213
3343#, c-format
3344msgid "Connecting nodes in 2d torus topology: %u rows %u columns\n"
3345msgstr ""
3346
3347#: src/applications/testing/remotetopologies.c:491
3348#, fuzzy, c-format
3349msgid "Failed to establish connection with peers.\n"
3350msgstr "Fehler beim Aufbauen einer Verbindung mit gnunetd.\n"
3351
3352#: src/applications/bootstrap_http/http.c:113
3353#, fuzzy, c-format
3354msgid "Bootstrap data obtained from `%s' is invalid.\n"
3355msgstr "Format des Pseudonyms `%s' ist ungültig.\n"
3356
3357#: src/applications/bootstrap_http/http.c:126
3358#: src/applications/bootstrap_http/http.c:277
3359#: src/applications/bootstrap_http/http.c:294
3360#: src/applications/bootstrap_http/http.c:333
3361#: src/applications/bootstrap_http/http.c:352
3362#: src/applications/bootstrap_http/http.c:365
3363#: src/applications/bootstrap_http/http.c:375
3364#: src/applications/bootstrap_http/http.c:385 src/transports/upnp/upnp.c:356
3365#: src/transports/upnp/upnp.c:541 src/transports/http.c:1085
3366#: src/transports/http.c:1209 src/transports/http.c:1377
3367#: src/transports/http.c:1777 src/transports/http.c:1827
3368#, c-format
3369msgid "%s failed at %s:%d: `%s'\n"
3370msgstr "`%s' schlug fehl bei %s:%d mit dem Fehler: `%s'.\n"
3371
3372#: src/applications/bootstrap_http/http.c:185
3373msgid "No hostlist URL specified in configuration, will not bootstrap.\n"
3374msgstr ""
3375
3376#: src/applications/bootstrap_http/http.c:226
3377#, c-format
3378msgid "Bootstrapping using `%s'.\n"
3379msgstr ""
3380
3381#: src/applications/bootstrap_http/http.c:254
3382#, fuzzy, c-format
3383msgid "Trying to download hostlist from `%s'\n"
3384msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n"
3385
3386#: src/applications/bootstrap_http/http.c:391
3387#, fuzzy, c-format
3388msgid "Downloaded %llu bytes from `%s'.\n"
3389msgstr "Dateien aus dem GNUnet herunterladen."
3390
3391#: src/applications/bootstrap_http/http.c:425
3392#, fuzzy
3393msgid "# HELLOs downloaded via http"
3394msgstr "# Hellos per HTTP heruntergeladen"
3395
3396#: src/applications/getoption/getoption.c:78
3397#, c-format
3398msgid "`%s' registering client handler %d\n"
3399msgstr "`%s' registriert Client-Handler %d\n"
3400
3401#: src/applications/getoption/getoption.c:88
3402msgid "allows clients to determine gnunetd's configuration"
3403msgstr "Erlaubt es Clients die Konfiguration von gnunetd abzufragen"
3404
3405#: src/applications/template/template.c:70
3406#, c-format
3407msgid "`%s' registering client handler %d and %d\n"
3408msgstr "`%s' registriert Client-Handler %d and %d\n"
3409
3410#: src/applications/template/gnunet-template.c:42
3411msgid "Template description."
3412msgstr ""
3413
3414#: src/applications/stats/clientapi.c:331
3415msgid "Uptime (seconds)"
3416msgstr "Laufzeit (Sekunden)"
3417
3418#: src/applications/stats/sqstats.c:151
3419msgid "# Any-Blocks"
3420msgstr ""
3421
3422#: src/applications/stats/sqstats.c:152
3423msgid "# DBlocks"
3424msgstr ""
3425
3426#: src/applications/stats/sqstats.c:153
3427msgid "# SBlocks"
3428msgstr ""
3429
3430#: src/applications/stats/sqstats.c:154
3431msgid "# KBlocks"
3432msgstr ""
3433
3434#: src/applications/stats/sqstats.c:155
3435msgid "# NBlocks"
3436msgstr ""
3437
3438#: src/applications/stats/sqstats.c:156
3439msgid "# KNBlocks"
3440msgstr ""
3441
3442#: src/applications/stats/sqstats.c:157
3443msgid "# OnDemand-Blocks"
3444msgstr ""
3445
3446#: src/applications/stats/sqstats.c:158
3447msgid "# Unknown-Blocks"
3448msgstr ""
3449
3450#: src/applications/stats/sqstats.c:159
3451msgid "# expired"
3452msgstr ""
3453
3454#: src/applications/stats/sqstats.c:160
3455msgid "# expire in 1h"
3456msgstr ""
3457
3458#: src/applications/stats/sqstats.c:161
3459msgid "# expire in 24h"
3460msgstr ""
3461
3462#: src/applications/stats/sqstats.c:162
3463msgid "# expire in 1 week"
3464msgstr ""
3465
3466#: src/applications/stats/sqstats.c:163
3467msgid "# expire in 1 month"
3468msgstr ""
3469
3470#: src/applications/stats/sqstats.c:164
3471msgid "# zero priority"
3472msgstr ""
3473
3474#: src/applications/stats/sqstats.c:165
3475msgid "# priority one"
3476msgstr ""
3477
3478#: src/applications/stats/sqstats.c:166
3479msgid "# priority larger than one"
3480msgstr ""
3481
3482#: src/applications/stats/sqstats.c:167
3483msgid "# no anonymity"
3484msgstr ""
3485
3486#: src/applications/stats/sqstats.c:168
3487msgid "# anonymity one"
3488msgstr ""
3489
3490#: src/applications/stats/sqstats.c:169
3491msgid "# anonymity larger than one"
3492msgstr ""
3493
3494#: src/applications/stats/statistics.c:238
3495#, no-c-format
3496msgid "% of allowed network load (up)"
3497msgstr "% of allowed network load (up)"
3498
3499#: src/applications/stats/statistics.c:240
3500#, no-c-format
3501msgid "% of allowed network load (down)"
3502msgstr "% of allowed network load (down)"
3503
3504#: src/applications/stats/statistics.c:243
3505#, no-c-format
3506msgid "% of allowed cpu load"
3507msgstr "% of allowed cpu load"
3508
3509#: src/applications/stats/statistics.c:246
3510#, fuzzy, no-c-format
3511msgid "% of allowed io load"
3512msgstr "% of allowed cpu load"
3513
3514#: src/applications/stats/statistics.c:249
3515msgid "# bytes of noise received"
3516msgstr "# Bytes Rauschen empfangen"
3517
3518#: src/applications/stats/statistics.c:251
3519msgid "# plibc handles"
3520msgstr ""
3521
3522#: src/applications/stats/statistics.c:441
3523#, fuzzy, c-format
3524msgid "`%s' registering client handlers %d %d %d and p2p handler %d\n"
3525msgstr "`%s' registriert die Client Handler %d %d %d %d %d %d %d %d %d\n"
3526
3527#: src/applications/stats/statistics.c:463
3528msgid "keeps statistics about gnunetd's operation"
3529msgstr "Hält Statistiken über Betrieb von gnunetd"
3530
3531#: src/applications/stats/gnunet-stats.c:61
3532#, c-format
3533msgid "Supported peer-to-peer messages:\n"
3534msgstr "unterstützte Peer-to-Peer Nachrichten:\n"
3535
3536#: src/applications/stats/gnunet-stats.c:64
3537#, c-format
3538msgid "Supported client-server messages:\n"
3539msgstr "unterstützte Client-Server Nachrichten:\n"
3540
3541#: src/applications/stats/gnunet-stats.c:83
3542#: src/applications/vpn/gnunet-vpn.c:59
3543msgid "Print statistics about GNUnet operations."
3544msgstr "Statistiken der GNUnet Aktivitäten ausgeben."
3545
3546#: src/applications/stats/gnunet-stats.c:87
3547msgid "prints supported protocol messages"
3548msgstr "gibt unterstützte Protokollnachrichten aus"
3549
3550#: src/applications/stats/gnunet-stats.c:136
3551#, c-format
3552msgid "Error reading information from gnunetd.\n"
3553msgstr "Fehler beim Lesen von Informationen von gnunetd.\n"
3554
3555#: src/applications/vpn/gnunet-vpn.c:63
3556msgid "Suppress display of asynchronous log messages"
3557msgstr ""
3558
3559#: src/applications/vpn/p2p.c:75
3560msgid "VPN IP src not anonymous. drop..\n"
3561msgstr ""
3562
3563#: src/applications/vpn/p2p.c:83
3564msgid "VPN IP not anonymous, drop.\n"
3565msgstr ""
3566
3567#: src/applications/vpn/p2p.c:92
3568msgid "VPN Received, not anonymous, drop.\n"
3569msgstr ""
3570
3571#: src/applications/vpn/p2p.c:97
3572#, fuzzy, c-format
3573msgid "VPN Received unknown IP version %d...\n"
3574msgstr "Es wurde eine unbekannte Testbed Nachricht des Typs %u empfangen.\n"
3575
3576#: src/applications/vpn/p2p.c:110
3577#, c-format
3578msgid "<- GNUnet(%d) : %s\n"
3579msgstr ""
3580
3581#: src/applications/vpn/p2p.c:139
3582msgid "Could not write the tunnelled IP to the OS... Did to setup a tunnel?\n"
3583msgstr ""
3584
3585#: src/applications/vpn/p2p.c:183
3586msgid "Receive route request\n"
3587msgstr ""
3588
3589#: src/applications/vpn/p2p.c:193
3590#, c-format
3591msgid "Prepare route announcement level %d\n"
3592msgstr ""
3593
3594#: src/applications/vpn/p2p.c:208
3595#, c-format
3596msgid "Send route announcement %d with route announce\n"
3597msgstr ""
3598
3599#: src/applications/vpn/p2p.c:217
3600#, c-format
3601msgid "Send outside table info %d\n"
3602msgstr ""
3603
3604#: src/applications/vpn/p2p.c:239
3605msgid "Receive route announce.\n"
3606msgstr ""
3607
3608#: src/applications/vpn/p2p.c:247
3609msgid "Going to try insert route into local table.\n"
3610msgstr ""
3611
3612#: src/applications/vpn/p2p.c:256
3613#, c-format
3614msgid "Inserting with hops %d\n"
3615msgstr ""
3616
3617#: src/applications/vpn/p2p.c:273
3618#, c-format
3619msgid "Request level %d from peer %d\n"
3620msgstr ""
3621
3622#: src/applications/vpn/p2p.c:300
3623#, c-format
3624msgid "Receive table limit on peer reached %d\n"
3625msgstr ""
3626
3627#: src/applications/vpn/vpn.c:180
3628#, c-format
3629msgid "Not storing route to myself from peer %d\n"
3630msgstr ""
3631
3632#: src/applications/vpn/vpn.c:194
3633#, c-format
3634msgid "Duplicate route to node from peer %d, choosing minimum hops"
3635msgstr ""
3636
3637#: src/applications/vpn/vpn.c:230
3638#, c-format
3639msgid "Inserting route from peer %d in route table at location %d\n"
3640msgstr ""
3641
3642#: src/applications/vpn/vpn.c:247
3643#, c-format
3644msgid "RFC4193 Frame length %d is too big for GNUnet!\n"
3645msgstr ""
3646
3647#: src/applications/vpn/vpn.c:254
3648#, c-format
3649msgid "RFC4193 Frame length %d too small\n"
3650msgstr ""
3651
3652#: src/applications/vpn/vpn.c:273
3653#, c-format
3654msgid "RFC4193 Ethertype %x and IP version %x do not match!\n"
3655msgstr ""
3656
3657#: src/applications/vpn/vpn.c:289
3658#, c-format
3659msgid "RFC4193 Going to try and make a tunnel in slot %d\n"
3660msgstr ""
3661
3662#: src/applications/vpn/vpn.c:295
3663#, fuzzy, c-format
3664msgid "Cannot open tunnel device: %s"
3665msgstr "Konfigurationsdatei `%s' konnte nicht geöffnet werden.\n"
3666
3667#: src/applications/vpn/vpn.c:331
3668#, c-format
3669msgid "RFC4193 Create skips gnu%d as we are already using it\n"
3670msgstr ""
3671
3672#: src/applications/vpn/vpn.c:346
3673#, c-format
3674msgid "Cannot set tunnel name to %s because of %s\n"
3675msgstr ""
3676
3677#: src/applications/vpn/vpn.c:356
3678#, c-format
3679msgid "Configured tunnel name to %s\n"
3680msgstr ""
3681
3682#: src/applications/vpn/vpn.c:398
3683#, c-format
3684msgid "Cannot get socket flags for gnu%d because %s\n"
3685msgstr ""
3686
3687#: src/applications/vpn/vpn.c:408
3688#, c-format
3689msgid "Cannot set socket flags for gnu%d because %s\n"
3690msgstr ""
3691
3692#: src/applications/vpn/vpn.c:418
3693#, c-format
3694msgid "Cannot set MTU for gnu%d because %s\n"
3695msgstr ""
3696
3697#: src/applications/vpn/vpn.c:426
3698#, c-format
3699msgid "Cannot get interface index for gnu%d because %s\n"
3700msgstr ""
3701
3702#: src/applications/vpn/vpn.c:440
3703#, c-format
3704msgid "IPv6 ifaddr gnu%d - %x:%x:%x:%x:%x:%x:%x:%x/%d\n"
3705msgstr ""
3706
3707#: src/applications/vpn/vpn.c:455
3708#, fuzzy, c-format
3709msgid "Cannot set interface IPv6 address for gnu%d because %s\n"
3710msgstr "Es konnte keine IP-Adresse für das Gerät `%s' ermittelt werden.\n"
3711
3712#: src/applications/vpn/vpn.c:471
3713#, c-format
3714msgid "IPv6 route gnu%d - destination %x:%x:%x:%x:%x:%x:%x:%x/%d\n"
3715msgstr ""
3716
3717#: src/applications/vpn/vpn.c:485
3718#, fuzzy, c-format
3719msgid "Cannot add route IPv6 address for gnu%s because %s\n"
3720msgstr "Es konnte keine IP-Adresse für das Gerät `%s' ermittelt werden.\n"
3721
3722#: src/applications/vpn/vpn.c:528
3723msgid ""
3724"RFC4193 We have run out of memory and so I can't store a tunnel for this "
3725"peer.\n"
3726msgstr ""
3727
3728#: src/applications/vpn/vpn.c:579
3729#, c-format
3730msgid "RFC4193 Thread running (frame %d tunnel %d f2f %d) ...\n"
3731msgstr ""
3732
3733#: src/applications/vpn/vpn.c:661
3734#, c-format
3735msgid "VPN dropping connection %x\n"
3736msgstr ""
3737
3738#: src/applications/vpn/vpn.c:670
3739#, c-format
3740msgid "VPN cannot drop connection %x\n"
3741msgstr ""
3742
3743#: src/applications/vpn/vpn.c:690
3744msgid "RFC4193 Thread exiting\n"
3745msgstr ""
3746
3747#: src/applications/vpn/vpn.c:712
3748msgid "realise alloc ram\n"
3749msgstr ""
3750
3751#: src/applications/vpn/vpn.c:735
3752msgid "realise add routes\n"
3753msgstr ""
3754
3755#: src/applications/vpn/vpn.c:849
3756msgid "realise copy table\n"
3757msgstr ""
3758
3759#: src/applications/vpn/vpn.c:898
3760#, fuzzy, c-format
3761msgid "`%s' initialising RFC4913 module %d and %d\n"
3762msgstr "`%s' registriert Handler %d und %d\n"
3763
3764#: src/applications/vpn/vpn.c:903
3765#, c-format
3766msgid "RFC4193 my First 4 hex digits of host id are %x\n"
3767msgstr ""
3768
3769#: src/applications/vpn/vpn.c:942
3770#, fuzzy
3771msgid "enables IPv6 over GNUnet (incomplete)"
3772msgstr "Ermöglicht P2P-Chat"
3773
3774#: src/applications/vpn/vpn.c:963
3775msgid "RFC4193 Waiting for tun thread to end\n"
3776msgstr ""
3777
3778#: src/applications/vpn/vpn.c:978
3779msgid "RFC4193 The tun thread has ended\n"
3780msgstr ""
3781
3782#: src/applications/vpn/vpn.c:996
3783#, c-format
3784msgid "RFC4193 Closing tunnel %d fd %d\n"
3785msgstr ""
3786
3787#: src/server/core.c:119 src/server/core.c:318
3788#, c-format
3789msgid "Configuration value `%s' under [MODULES] for `%s' is invalid!\n"
3790msgstr ""
3791
3792#: src/server/core.c:140
3793#, c-format
3794msgid "Application module `%s' already initialized!\n"
3795msgstr "Anwendungsmodul `%s' ist bereits initialisiert!\n"
3796
3797#: src/server/core.c:194
3798#, c-format
3799msgid "Failed to load plugin `%s' at %s:%d. Unloading plugin.\n"
3800msgstr "Fehler beim Laden des Plugins `%s' bei %s:%d. Plugin wird entladen.\n"
3801
3802#: src/server/core.c:244
3803#, c-format
3804msgid "Could not shutdown `%s': application not loaded\n"
3805msgstr "`%s' kann nicht heruntergefahren werden: Anwendung ist nicht geladen\n"
3806
3807#: src/server/core.c:255
3808#, c-format
3809msgid "Could not shutdown application `%s': not initialized\n"
3810msgstr ""
3811"Anwendung `%s' kann nicht heruntergefahren werden: sie ist nicht "
3812"initialisiert\n"
3813
3814#: src/server/core.c:265
3815#, c-format
3816msgid "Could not find '%s%s' method in library `%s'.\n"
3817msgstr "Methode '%s%s' kann in Bibliothek `%s' nicht gefunden werden.\n"
3818
3819#: src/server/core.c:422
3820#, c-format
3821msgid "Could not release %p: service not loaded\n"
3822msgstr "%p kann nicht freigegeben werden: Dienst ist nicht geladen\n"
3823
3824#: src/server/core.c:531
3825#, c-format
3826msgid "Could not properly shutdown application `%s'.\n"
3827msgstr "Anwendung `%s' konnte nicht ordentlich heruntergefahren werden.\n"
3828
3829#: src/server/core.c:676
3830#, c-format
3831msgid "Could not properly unload service `%s'!\n"
3832msgstr "Dienst `%s' konnte nicht ordentlich entladen werden!\n"
3833
3834#: src/server/gnunet-update.c:146
3835#, c-format
3836msgid "Updating data for module `%s'\n"
3837msgstr "Daten des Moduls `%s' werden aktualisiert\n"
3838
3839#: src/server/gnunet-update.c:151
3840#, c-format
3841msgid "Failed to update data for module `%s'\n"
3842msgstr "Fehler beim Aktualisieren der Daten des Moduls `%s'\n"
3843
3844#: src/server/gnunet-update.c:225 src/server/gnunetd.c:124
3845#, fuzzy
3846msgid "Core initialization failed.\n"
3847msgstr " Verbindung fehlgeschlagen\n"
3848
3849#: src/server/gnunet-update.c:270
3850msgid "Updates GNUnet datastructures after version change."
3851msgstr "GNUnet Datenstrukturen nach einer Versionsänderung aktualisieren."
3852
3853#: src/server/gnunet-update.c:274 src/server/gnunet-transport-check.c:376
3854msgid "run as user LOGIN"
3855msgstr "als Benutzer LOGIN ausführen"
3856
3857#: src/server/gnunet-update.c:278
3858msgid "run in client mode (for getting client configuration values)"
3859msgstr ""
3860"Im Benuter-Modus laufen (um benutzerspezifische Konfigurationseinstellungen "
3861"zu holen"
3862
3863#: src/server/version.c:125
3864msgid ""
3865"Failed to determine filename used to store GNUnet version information!\n"
3866msgstr ""
3867
3868#: src/server/gnunetd.c:85
3869#, c-format
3870msgid "`%s' startup complete.\n"
3871msgstr "`%s' Startvorgang abgeschlossen.\n"
3872
3873#: src/server/gnunetd.c:89
3874#, c-format
3875msgid "`%s' is shutting down.\n"
3876msgstr "`%s' fährt herunter.\n"
3877
3878#: src/server/gnunetd.c:179
3879msgid ""
3880"run in debug mode; gnunetd will not daemonize and error messages will be "
3881"written to stderr instead of a logfile"
3882msgstr ""
3883"Im Debug-Modus ausführen. gnunetd wird nicht im Hintergrund laufen und "
3884"Fehlermeldungen werden nicht in die Protokolldatei, sondern auf die "
3885"Standardfehlerausgabe (stderr) geschrieben."
3886
3887#: src/server/gnunetd.c:183
3888msgid "Starts the gnunetd daemon."
3889msgstr "Startet den gnunetd Daemonen."
3890
3891#: src/server/gnunetd.c:186
3892msgid "disable padding with random data (experimental)"
3893msgstr ""
3894
3895#: src/server/gnunetd.c:190
3896msgid "print all log messages to the console (only works together with -d)"
3897msgstr ""
3898
3899#: src/server/gnunetd.c:194
3900#, fuzzy
3901msgid "specify username as which gnunetd should run"
3902msgstr "Gibt an, auf welchem Host gnunetd läuft"
3903
3904#: src/server/gnunetd.c:275
3905#, c-format
3906msgid "Configuration or GNUnet version changed. You need to run `%s'!\n"
3907msgstr ""
3908"Konfiguration oder die GNUnet Version hat sich geändert. Sie müssen `%s' "
3909"ausführen!\n"
3910
3911#: src/server/tcpserver.c:121
3912#, c-format
3913msgid "The `%s' request received from client is malformed.\n"
3914msgstr "Die `%s' Anfrage, die vom Client empfangen wurde, ist beschädigt.\n"
3915
3916#: src/server/tcpserver.c:409
3917#, fuzzy, c-format
3918msgid "`%s' failed for port %d. Is gnunetd already running?\n"
3919msgstr "`%s' schlug fehl für Port %d: %s. Läuft gnunetd bereits?\n"
3920
3921#: src/server/tcpserver.c:487 src/server/tcpserver.c:512
3922#, c-format
3923msgid ""
3924"Malformed network specification in the configuration in section `%s' for "
3925"entry `%s': %s\n"
3926msgstr ""
3927"Beschädigte Netzwerkangabe in der Konfigurationsdatei in Sektion `%s' für "
3928"Eintrag `%s': %s\n"
3929
3930#: src/server/tcpserver.c:572
3931#, fuzzy, c-format
3932msgid "Registering failed, message type %d already in use.\n"
3933msgstr "%s schlug fehl, Nachrichten Typ %d ist bereits in Verwendung.\n"
3934
3935#: src/server/startup.c:219
3936#, fuzzy, c-format
3937msgid "Unable to obtain filesystem information for `%s': %u\n"
3938msgstr "Fehler beim Speichern der Konfigurationsdatei: `%s': %s.\n"
3939
3940#: src/server/startup.c:237
3941#, c-format
3942msgid ""
3943"Filesystem `%s' of partition `%s' is unknown. Please contact gnunet-"
3944"developers@gnu.org!"
3945msgstr ""
3946
3947#: src/server/startup.c:252
3948#, c-format
3949msgid ""
3950"Limiting datastore size to %llu GB, because the `%s' filesystem does not "
3951"support larger files. Please consider storing the database on a NTFS "
3952"partition!\n"
3953msgstr ""
3954
3955#: src/server/startup.c:291
3956#, c-format
3957msgid "Insufficient access permissions for `%s': %s\n"
3958msgstr ""
3959
3960#: src/server/gnunet-peer-info.c:55
3961msgid "Print information about GNUnet peers."
3962msgstr "Informationen über andere GNUnet Knoten ausgeben."
3963
3964#: src/server/gnunet-peer-info.c:59
3965msgid "don't resolve host names"
3966msgstr ""
3967
3968#: src/server/gnunet-peer-info.c:62
3969msgid "output only the identity strings"
3970msgstr ""
3971
3972#: src/server/gnunet-peer-info.c:65
3973msgid "output our own identity only"
3974msgstr ""
3975
3976#: src/server/gnunet-peer-info.c:130 src/server/gnunet-peer-info.c:164
3977#, c-format
3978msgid "Could not get address of peer `%s'.\n"
3979msgstr "Adresse des Knotens `%s' konnte nicht ermittelt werden.\n"
3980
3981#: src/server/gnunet-peer-info.c:143
3982#, fuzzy, c-format
3983msgid "`%s' message invalid (signature invalid).\n"
3984msgstr "Hello Nachricht ist ungültig (Signatur ist ungültig).\n"
3985
3986#: src/server/gnunet-peer-info.c:168
3987#, fuzzy, c-format
3988msgid "Peer `%s' with trust %8u\n"
3989msgstr "Knoten `%s' mit Vertrauen %8u und Adresse `%s'\n"
3990
3991#: src/server/gnunet-peer-info.c:175
3992#, c-format
3993msgid "Peer `%s' with trust %8u and address `%s'\n"
3994msgstr "Knoten `%s' mit Vertrauen %8u und Adresse `%s'\n"
3995
3996#: src/server/connection.c:1313
3997#, c-format
3998msgid "`%s' selected %d out of %d messages (MTU: %d).\n"
3999msgstr "`%s' wählte %d von %d Nachrichten aus (MTU: %d).\n"
4000
4001#: src/server/connection.c:1323
4002#, c-format
4003msgid "Message details: %u: length %d, priority: %d\n"
4004msgstr "Nachrichten Details: %u: Länge %d, Priorität: %d\n"
4005
4006#: src/server/connection.c:3129
4007#, c-format
4008msgid "Message from `%s' discarded: invalid format.\n"
4009msgstr "Nachricht von `%s' verworfen: ungültiges Format.\n"
4010
4011#: src/server/connection.c:3218
4012#, c-format
4013msgid "Invalid sequence number %u <= %u, dropping message.\n"
4014msgstr "Ungültige Sequenznummer %u <= %u, Nachricht wird verworfen.\n"
4015
4016#: src/server/connection.c:3240
4017msgid "Message received more than one day old. Dropped.\n"
4018msgstr ""
4019"Empfangene Nachricht ist mehr als ein Tag alt. Nachricht wird verworfen.\n"
4020
4021#: src/server/connection.c:3763
4022msgid "# outgoing messages dropped"
4023msgstr "# ausgehender Nachrichten verworfen"
4024
4025#: src/server/connection.c:3766
4026msgid "# bytes of outgoing messages dropped"
4027msgstr "# Bytes ausgehender Nachrichten verworfen"
4028
4029#: src/server/connection.c:3768
4030msgid "# connections closed (HANGUP sent)"
4031msgstr "# geschlossener Verbindungen (HANGUP gesendet)"
4032
4033#: src/server/connection.c:3772
4034#, fuzzy
4035msgid "# connections closed (transport issue)"
4036msgstr "# geschlossener Verbindungen (HANGUP gesendet)"
4037
4038#: src/server/connection.c:3775
4039msgid "# bytes encrypted"
4040msgstr "# Bytes verschlüsselt"
4041
4042#: src/server/connection.c:3779
4043#, fuzzy
4044msgid "# bytes transmitted"
4045msgstr "# Bytes des Typs %d übertragen"
4046
4047#: src/server/connection.c:3783
4048#, fuzzy
4049msgid "# bytes received"
4050msgstr "# Bytes empfangen über TCP"
4051
4052#: src/server/connection.c:3785
4053msgid "# bytes decrypted"
4054msgstr "# Bytes entschlüsselt"
4055
4056#: src/server/connection.c:3786
4057msgid "# bytes noise sent"
4058msgstr "# Bytes Rauschen gesendet"
4059
4060#: src/server/connection.c:3789
4061msgid "# total bytes per second send limit"
4062msgstr ""
4063
4064#: src/server/connection.c:3792
4065#, fuzzy
4066msgid "# total bytes per second receive limit"
4067msgstr "# Bytes Rauschen empfangen"
4068
4069#: src/server/connection.c:3795
4070#, fuzzy
4071msgid "# total number of messages in send buffers"
4072msgstr "Anzahl an Nachrichten in einem Nachrichtenblock"
4073
4074#: src/server/connection.c:3798
4075#, fuzzy
4076msgid "# total number of bytes we were allowed to send but did not"
4077msgstr "Anzahl an Nachrichten in einem Nachrichtenblock"
4078
4079#: src/server/connection.c:3801
4080#, fuzzy
4081msgid "# total number of bytes we were allowed to sent"
4082msgstr "Anzahl an Nachrichten in einem Nachrichtenblock"
4083
4084#: src/server/connection.c:3804
4085msgid "# total number of bytes we are currently allowed to send"
4086msgstr ""
4087
4088#: src/server/connection.c:3807
4089msgid "# transports switched to stream transport"
4090msgstr ""
4091
4092#: src/server/connection.c:3810
4093msgid "# average connection lifetime (in ms)"
4094msgstr ""
4095
4096#: src/server/connection.c:3813
4097msgid "# conn. shutdown: other peer sent too much"
4098msgstr ""
4099
4100#: src/server/connection.c:3816
4101msgid "# conn. shutdown: we lacked bandwidth"
4102msgstr ""
4103
4104#: src/server/connection.c:3819
4105msgid "# conn. shutdown: other peer timed out"
4106msgstr ""
4107
4108#: src/server/connection.c:3822
4109msgid "# conn. shutdown: timed out during connect"
4110msgstr ""
4111
4112#: src/server/connection.c:3825
4113msgid "# conn. shutdown: other peer requested it"
4114msgstr ""
4115
4116#: src/server/handler.c:442
4117#, fuzzy, c-format
4118msgid "Received corrupt message from peer `%s' in %s:%d.\n"
4119msgstr "Beschädigte Nachricht von Knoten `%s' in %s:%d empfangen.\n"
4120
4121#: src/server/gnunet-transport-check.c:121
4122#, c-format
4123msgid "`%s': Could not create hello.\n"
4124msgstr "`%s': Hello konnte nicht erzeugt werden.\n"
4125
4126#: src/server/gnunet-transport-check.c:129
4127#, c-format
4128msgid "`%s': Could not connect.\n"
4129msgstr "`%s': Verbindung konnte nicht hergestellt werden.\n"
4130
4131#: src/server/gnunet-transport-check.c:163
4132#, c-format
4133msgid "`%s': Could not send.\n"
4134msgstr "`%s': Kann nicht senden.\n"
4135
4136#: src/server/gnunet-transport-check.c:179
4137#, c-format
4138msgid "`%s': Did not receive message within %llu ms.\n"
4139msgstr "`%s': Nachricht wurde nicht innerhalb %llu ms empfangen.\n"
4140
4141#: src/server/gnunet-transport-check.c:192
4142#, c-format
4143msgid "`%s': Could not disconnect.\n"
4144msgstr "`%s': Verbindung konnte nicht getrennt werden.\n"
4145
4146#: src/server/gnunet-transport-check.c:200
4147#, fuzzy, c-format
4148msgid ""
4149"`%s' transport OK. It took %ums to transmit %llu messages of %llu bytes "
4150"each.\n"
4151msgstr ""
4152"`%s' Transport funktioniert. Es dauerte %ums, um %d Nachrichten zu je %d "
4153"Bytes zu übertragen.\n"
4154
4155#: src/server/gnunet-transport-check.c:231
4156#, fuzzy, c-format
4157msgid " Transport %d is not being tested\n"
4158msgstr " Transport %d ist nicht verfügbar\n"
4159
4160#: src/server/gnunet-transport-check.c:261
4161#, c-format
4162msgid ""
4163"\n"
4164"Contacting `%s'."
4165msgstr ""
4166"\n"
4167"Kontaktiere `%s'."
4168
4169#: src/server/gnunet-transport-check.c:286
4170#, c-format
4171msgid " Connection failed\n"
4172msgstr " Verbindung fehlgeschlagen\n"
4173
4174#: src/server/gnunet-transport-check.c:292
4175#, c-format
4176msgid " Connection failed (bug?)\n"
4177msgstr " Verbindung fehlgeschlagen (Bug?)\n"
4178
4179#: src/server/gnunet-transport-check.c:330
4180#, c-format
4181msgid "Timeout after %llums.\n"
4182msgstr ""
4183
4184#: src/server/gnunet-transport-check.c:332
4185#, fuzzy, c-format
4186msgid "OK!\n"
4187msgstr "OK"
4188
4189#: src/server/gnunet-transport-check.c:357
4190msgid "Tool to test if GNUnet transport services are operational."
4191msgstr ""
4192"Werkzeug, mit dem getestet werden kann, ob die GNUnet Transport Dienste "
4193"funktionsfähig sind."
4194
4195#: src/server/gnunet-transport-check.c:361
4196msgid "ping peers from HOSTLISTURL that match transports"
4197msgstr "Knoten aus HOSTLISTURL anpingen, deren Transports passen"
4198
4199#: src/server/gnunet-transport-check.c:364
4200msgid "send COUNT messages"
4201msgstr "COUNT Nachrichten versenden"
4202
4203#: src/server/gnunet-transport-check.c:367
4204msgid "send messages with SIZE bytes payload"
4205msgstr "Nachrichten mit SIZE Bytes Nutzlast versenden"
4206
4207#: src/server/gnunet-transport-check.c:370
4208msgid "specifies which TRANSPORT should be tested"
4209msgstr "Gibt an, welcher TRANSPORT getestet werden soll"
4210
4211#: src/server/gnunet-transport-check.c:373
4212msgid "specifies after how many MS to time-out"
4213msgstr "Gibt an, nach wievielen MS die Zeit abgelaufen sein soll"
4214
4215#: src/server/gnunet-transport-check.c:381
4216msgid "repeat each test X times"
4217msgstr ""
4218
4219#: src/server/gnunet-transport-check.c:449
4220#, c-format
4221msgid "Testing transport(s) %s\n"
4222msgstr "Teste Transport(e) %s\n"
4223
4224#: src/server/gnunet-transport-check.c:451
4225#, c-format
4226msgid "Available transport(s): %s\n"
4227msgstr "Verfügbare(r) Transport(e): %s\n"
4228
4229#: src/server/gnunet-transport-check.c:501
4230#, fuzzy, c-format
4231msgid ""
4232"\n"
4233"%d out of %d peers contacted successfully (%d times transport unavailable).\n"
4234msgstr ""
4235"%d von %d Knoten erfolgreich kontaktiert (%d mal war der Transport nicht "
4236"verfügbar).\n"
4237
4238#: src/transports/common.c:370
4239#, c-format
4240msgid "Port is 0, will only send using %s.\n"
4241msgstr ""
4242
4243#: src/transports/smtp.c:367 src/transports/udp.c:107 src/transports/tcp.c:271
4244#: src/transports/tcp.c:291
4245#, fuzzy, c-format
4246msgid "Received malformed message via %s. Ignored.\n"
4247msgstr ""
4248"Es wurde eine ungültige Nachricht per SMTP empfangen (ungültige Größe).\n"
4249
4250#: src/transports/smtp.c:459
4251#, fuzzy
4252msgid "SMTP filter string to invalid, lacks ': '\n"
4253msgstr "SMTP Filterstring zu lang, wurde auf `%s' abgeschnitten\n"
4254
4255#: src/transports/smtp.c:469
4256#, c-format
4257msgid "SMTP filter string to long, capped to `%s'\n"
4258msgstr "SMTP Filterstring zu lang, wurde auf `%s' abgeschnitten\n"
4259
4260#: src/transports/smtp.c:564 src/transports/smtp.c:575
4261#: src/transports/smtp.c:589 src/transports/smtp.c:609
4262#: src/transports/smtp.c:634 src/transports/smtp.c:643
4263#: src/transports/smtp.c:657 src/transports/smtp.c:669
4264#, fuzzy, c-format
4265msgid "SMTP: `%s' failed: %s.\n"
4266msgstr "`%s' schlug fehl: %s\n"
4267
4268#: src/transports/smtp.c:814
4269#, fuzzy
4270msgid "No email-address specified, can not start SMTP transport.\n"
4271msgstr ""
4272"Kein Filter für E-Mail angegeben, es kann keine Bekanntmachung erstellt "
4273"werden.\n"
4274
4275#: src/transports/smtp.c:831
4276#, fuzzy
4277msgid "# bytes received via SMTP"
4278msgstr "# Bytes empfangen über TCP"
4279
4280#: src/transports/smtp.c:832
4281#, fuzzy
4282msgid "# bytes sent via SMTP"
4283msgstr "# Bytes gesendet über TCP"
4284
4285#: src/transports/smtp.c:834
4286#, fuzzy
4287msgid "# bytes dropped by SMTP (outgoing)"
4288msgstr "# Bytes verworfen von TCP (ausgehend)"
4289
4290#: src/transports/upnp/upnp.c:431
4291#, fuzzy, c-format
4292msgid "%s failed for url `%s' and post-data `%s' at %s:%d: `%s'\n"
4293msgstr "`%s' schlug fehl bei %s:%d mit dem Fehler: `%s'.\n"
4294
4295#: src/transports/upnp/upnp.c:476
4296#, c-format
4297msgid "upnp: NAT Returned IP: %s\n"
4298msgstr ""
4299
4300#: src/transports/http.c:2019 src/transports/tcp.c:811
4301#, c-format
4302msgid ""
4303"The UPnP service could not be loaded. To disable UPnP, set the configuration "
4304"option \"UPNP\" in section \"%s\" to \"NO\"\n"
4305msgstr ""
4306
4307#: src/transports/http.c:2028
4308msgid "# bytes received via HTTP"
4309msgstr "# Bytes empfangen über HTTP"
4310
4311#: src/transports/http.c:2029
4312msgid "# bytes sent via HTTP"
4313msgstr "# Bytes gesendet über HTTP"
4314
4315#: src/transports/http.c:2031
4316msgid "# bytes dropped by HTTP (outgoing)"
4317msgstr "# Bytes verworfen von HTTP"
4318
4319#: src/transports/http.c:2032
4320msgid "# HTTP GET issued"
4321msgstr ""
4322
4323#: src/transports/http.c:2034
4324#, fuzzy
4325msgid "# HTTP GET received"
4326msgstr "# Bytes empfangen über TCP"
4327
4328#: src/transports/http.c:2035
4329msgid "# HTTP PUT issued"
4330msgstr ""
4331
4332#: src/transports/http.c:2037
4333#, fuzzy
4334msgid "# HTTP PUT received"
4335msgstr "# Bytes empfangen über TCP"
4336
4337#: src/transports/http.c:2039
4338msgid "# HTTP select calls"
4339msgstr ""
4340
4341#: src/transports/http.c:2041
4342msgid "# HTTP send calls"
4343msgstr ""
4344
4345#: src/transports/http.c:2044
4346msgid "# HTTP curl send callbacks"
4347msgstr ""
4348
4349#: src/transports/http.c:2046
4350msgid "# HTTP curl receive callbacks"
4351msgstr ""
4352
4353#: src/transports/http.c:2048
4354msgid "# HTTP mhd access callbacks"
4355msgstr ""
4356
4357#: src/transports/http.c:2050
4358msgid "# HTTP mhd read callbacks"
4359msgstr ""
4360
4361#: src/transports/http.c:2052
4362msgid "# HTTP mhd close callbacks"
4363msgstr ""
4364
4365#: src/transports/http.c:2054
4366#, fuzzy
4367msgid "# HTTP connect calls"
4368msgstr "# verbundener Knoten"
4369
4370#: src/transports/ip.c:70 src/transports/ip.c:365
4371#, fuzzy, c-format
4372msgid "Failed to obtain my (external) %s address!\n"
4373msgstr "Fehler beim Bestimmen der (externen) IP-Adresse!\n"
4374
4375#: src/transports/udp.c:472 src/transports/tcp.c:728
4376#, fuzzy, c-format
4377msgid "Failed to bind to %s port %d.\n"
4378msgstr "Fehler beim Binden an UDP Port %d.\n"
4379
4380#: src/transports/udp.c:538
4381#, fuzzy, c-format
4382msgid "MTU %llu for `%s' is probably too low!\n"
4383msgstr ""
4384"MTU für `%s' ist möglicherweise zu gering (Fragmentierung ist nicht "
4385"implementiert!)\n"
4386
4387#: src/transports/udp.c:562
4388msgid "# bytes received via UDP"
4389msgstr "# Bytes empfangen über UDP"
4390
4391#: src/transports/udp.c:563
4392msgid "# bytes sent via UDP"
4393msgstr "# Bytes gesendet über UDP"
4394
4395#: src/transports/udp.c:565
4396msgid "# bytes dropped by UDP (outgoing)"
4397msgstr "# Bytes verworfen von UDP (outgoing)"
4398
4399#: src/transports/udp.c:567
4400msgid "# UDP connections (right now)"
4401msgstr ""
4402
4403#: src/transports/tcp.c:821
4404msgid "# bytes received via TCP"
4405msgstr "# Bytes empfangen über TCP"
4406
4407#: src/transports/tcp.c:822
4408msgid "# bytes sent via TCP"
4409msgstr "# Bytes gesendet über TCP"
4410
4411#: src/transports/tcp.c:824
4412msgid "# bytes dropped by TCP (outgoing)"
4413msgstr "# Bytes verworfen von TCP (ausgehend)"
4414
4415#: src/include/gnunet_util_getopt.h:154
4416msgid "print this help"
4417msgstr "Gibt diese Hilfe aus"
4418
4419#: src/include/gnunet_util_getopt.h:163
4420msgid "print the version number"
4421msgstr "Versionsnummer ausgeben"
4422
4423#: src/include/gnunet_util_getopt.h:169
4424msgid "configure logging to use LOGLEVEL"
4425msgstr ""
4426
4427#: src/include/gnunet_util_getopt.h:175
4428msgid "be verbose"
4429msgstr "umfangreiche Meldungen ausgeben"
4430
4431#: src/include/gnunet_util_getopt.h:181
4432msgid "use configuration file FILENAME"
4433msgstr "Konfigurationsdatei FILENAME verwenden"
4434
4435#: src/include/gnunet_util_getopt.h:187
4436msgid "specify host on which gnunetd is running"
4437msgstr "Gibt an, auf welchem Host gnunetd läuft"
4438
4439#: src/include/gnunet_util_error.h:219 src/include/gnunet_util_error.h:224
4440#: src/include/gnunet_util_error.h:230 src/include/gnunet_util_error.h:232
4441#, fuzzy, c-format
4442msgid "Internal error: assertion failed at %s:%d.\n"
4443msgstr "Absicherung fehlgeschlagen bei %s:%d.\n"
4444
4445#: src/include/gnunet_util_error.h:242
4446#, c-format
4447msgid ""
4448"External protocol violation: assertion failed at %s:%d (no need to panic, we "
4449"can handle this).\n"
4450msgstr ""
4451
4452#: src/include/gnunet_util_error.h:270 src/include/gnunet_util_error.h:277
4453#, fuzzy, c-format
4454msgid "`%s' failed on file `%s' at %s:%d with error: %s\n"
4455msgstr "`%s' schlug bei Datei `%s' fehl. Ort: %s:%d. Fehler: %s\n"
4456
4457#: contrib/config-daemon.scm:39 contrib/config-client.scm:40
4458msgid "No help available."
4459msgstr "Keine Hilfe verfügbar."
4460
4461#: contrib/config-daemon.scm:42
4462msgid ""
4463"You can use 'make check' in src/transports/upnp/ to find out if your NAT "
4464"supports UPnP. You should disable this option if you are sure that you are "
4465"not behind a NAT. If your NAT box does not support UPnP, having this on "
4466"will not do much harm (only cost a small amount of resources)."
4467msgstr ""
4468
4469#: contrib/config-daemon.scm:54 contrib/config-client.scm:53
4470msgid "Prompt for development and/or incomplete code"
4471msgstr ""
4472
4473#: contrib/config-daemon.scm:56 contrib/config-client.scm:55
4474msgid ""
4475"If EXPERIMENTAL is set to NO, options for experimental code are not shown. "
4476"If in doubt, use NO.\n"
4477"\n"
4478"Some options apply to experimental code that maybe in a state of development "
4479"where the functionality, stability, or the level of testing is not yet high "
4480"enough for general use. These features are said to be of \"alpha\" "
4481"quality. If a feature is currently in alpha, uninformed use is discouraged "
4482"(since the developers then do not fancy \"Why doesn't this work?\" type "
4483"messages).\n"
4484"\n"
4485"However, active testing and qualified feedback of these features is always "
4486"welcome. Users should just be aware that alpha features may not meet the "
4487"normal level of reliability or it may fail to work in some special cases. "
4488"Bug reports are usually welcomed by the developers, but please read the "
4489"documents <file://README> and <http://gnunet.org/faq.php3> and use <https://"
4490"gnunet.org/mantis/> for how to report problems."
4491msgstr ""
4492
4493#: contrib/config-daemon.scm:71 contrib/config-client.scm:70
4494msgid "Show options for advanced users"
4495msgstr ""
4496
4497#: contrib/config-daemon.scm:73 contrib/config-client.scm:72
4498msgid ""
4499"These are options that maybe difficult to understand for the beginner. These "
4500"options typically refer to features that allow tweaking of the "
4501"installation. If in a hurry, say NO."
4502msgstr ""
4503
4504#: contrib/config-daemon.scm:84 contrib/config-client.scm:83
4505#, fuzzy
4506msgid "Show rarely used options"
4507msgstr "Maskierte Optionen anzeigen"
4508
4509#: contrib/config-daemon.scm:86 contrib/config-client.scm:85
4510msgid ""
4511"These are options that hardly anyone actually needs. If you plan on doing "
4512"development on GNUnet, you may want to look into these. If in doubt or in a "
4513"hurry, say NO."
4514msgstr ""
4515
4516#: contrib/config-daemon.scm:97 contrib/config-client.scm:96
4517#, fuzzy
4518msgid "Meta-configuration"
4519msgstr "GNUnet Konfiguration"
4520
4521#: contrib/config-daemon.scm:98 contrib/config-client.scm:97
4522msgid "Which level of configuration should be available"
4523msgstr ""
4524
4525#: contrib/config-daemon.scm:115
4526#, fuzzy
4527msgid "Full pathname of GNUnet HOME directory"
4528msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n"
4529
4530#: contrib/config-daemon.scm:117
4531msgid ""
4532"This gives the root-directory of the GNUnet installation. Make sure there is "
4533"some space left in that directory. :-) Users inserting or indexing files "
4534"will be able to store data in this directory up to the (global) quota "
4535"specified below. Having a few gigabytes of free space is recommended."
4536msgstr ""
4537
4538#: contrib/config-daemon.scm:130
4539#, fuzzy
4540msgid "Full pathname of GNUnet directory for file-sharing data"
4541msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n"
4542
4543#: contrib/config-daemon.scm:142
4544#, fuzzy
4545msgid "Full pathname to the directory with the key-value database"
4546msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n"
4547
4548#: contrib/config-daemon.scm:143
4549#, fuzzy
4550msgid "Note that the kvstore is currently not used."
4551msgstr "# gap Routingschächte im Moment in Verwendung"
4552
4553#: contrib/config-daemon.scm:154
4554#, fuzzy
4555msgid "Full pathname of GNUnet directory for indexed files symbolic links"
4556msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n"
4557
4558#: contrib/config-daemon.scm:166
4559msgid "How many minutes should peer advertisements last?"
4560msgstr ""
4561
4562#: contrib/config-daemon.scm:168
4563msgid ""
4564"How many minutes is the current IP valid? (GNUnet will sign HELLO messages "
4565"with this expiration timeline. If you are on dialup, 60 (for 1 hour) is "
4566"suggested. If you have a static IP address, you may want to set this to a "
4567"large value (say 14400). The default is 1440 (1 day). If your IP changes "
4568"periodically, you will want to choose an expiry period smaller than the "
4569"frequency with which your IP changes."
4570msgstr ""
4571
4572#: contrib/config-daemon.scm:179
4573msgid "Where can GNUnet find an initial list of peers?"
4574msgstr ""
4575
4576#: contrib/config-daemon.scm:181
4577msgid ""
4578"GNUnet can automatically update the hostlist from the web. While GNUnet "
4579"internally communicates which hosts are online, it is typically a good idea "
4580"to get a fresh hostlist whenever gnunetd starts from the WEB. By setting "
4581"this option, you can specify from which server gnunetd should try to "
4582"download the hostlist. The default should be fine for now.\n"
4583"\t\t\n"
4584"The general format is a list of space-separated URLs. Each URL must have "
4585"the format http://HOSTNAME/FILENAME\n"
4586"\t\t\n"
4587"If you want to setup an alternate hostlist server, you must run a permanent "
4588"node and \"cat data/hosts/* > hostlist\" every few minutes to keep the list "
4589"up-to-date.\n"
4590"\t\t\n"
4591"If you do not specify a HOSTLISTURL, you must copy valid hostkeys to data/"
4592"hosts manually."
4593msgstr ""
4594
4595#: contrib/config-daemon.scm:198
4596msgid "HTTP Proxy Server"
4597msgstr ""
4598
4599#: contrib/config-daemon.scm:200
4600msgid ""
4601"If you have to use a proxy for outbound HTTP connections, specify the proxy "
4602"configuration here. Default is no proxy."
4603msgstr ""
4604
4605#: contrib/config-daemon.scm:212
4606msgid ""
4607"Name of the directory where gnunetd should store contact information about "
4608"peers"
4609msgstr ""
4610
4611#: contrib/config-daemon.scm:214
4612msgid ""
4613"Unless you want to share the directory directly using a webserver, the "
4614"default is most likely just fine."
4615msgstr ""
4616
4617#: contrib/config-daemon.scm:240 contrib/config-client.scm:140
4618msgid "How long should logs be kept?"
4619msgstr ""
4620
4621#: contrib/config-daemon.scm:242 contrib/config-client.scm:142
4622msgid ""
4623"How long should logs be kept? If you specify a value greater than zero, a "
4624"log is created each day with the date appended to its filename. These logs "
4625"are deleted after $KEEPLOG days.\tTo keep logs forever, set this value to 0."
4626msgstr ""
4627
4628#: contrib/config-daemon.scm:253
4629msgid ""
4630"What maximum number of open file descriptors should be requested from the OS?"
4631msgstr ""
4632
4633#: contrib/config-daemon.scm:255
4634msgid ""
4635"The default of 1024 should be fine for most systems. If your system can "
4636"support more, increasing the number might help support additional clients on "
4637"machines with plenty of bandwidth. For embedded systems, a smaller number "
4638"might be acceptable. A value of 0 will leave the descriptor limit "
4639"untouched. This option is mostly for OS X systems where the default is too "
4640"low. Note that if gnunetd cannot obtain the desired number of file "
4641"descriptors from the operating system, it will print a warning and try to "
4642"run with what it is given."
4643msgstr ""
4644
4645#: contrib/config-daemon.scm:266
4646msgid "Where should gnunetd write the logs?"
4647msgstr ""
4648
4649#: contrib/config-daemon.scm:278
4650msgid "Enable for extra-verbose logging."
4651msgstr ""
4652
4653#: contrib/config-daemon.scm:290 contrib/config-client.scm:165
4654msgid "Logging"
4655msgstr ""
4656
4657#: contrib/config-daemon.scm:291 contrib/config-client.scm:166
4658msgid "Specify which system messages should be logged how"
4659msgstr ""
4660
4661#: contrib/config-daemon.scm:296 contrib/config-client.scm:170
4662msgid "Logging of events for users"
4663msgstr ""
4664
4665#: contrib/config-daemon.scm:297 contrib/config-client.scm:171
4666msgid "Logging of events for the system administrator"
4667msgstr ""
4668
4669#: contrib/config-daemon.scm:309
4670msgid "Where should gnunetd write the PID?"
4671msgstr ""
4672
4673#: contrib/config-daemon.scm:310
4674msgid ""
4675"The default is no longer /var/run/gnunetd.pid since we could not delete the "
4676"file on shutdown at that location."
4677msgstr ""
4678
4679#: contrib/config-daemon.scm:322
4680msgid "As which user should gnunetd run?"
4681msgstr ""
4682
4683#: contrib/config-daemon.scm:324
4684msgid ""
4685"Empty means \"current user\". On computer startup, it is root/SYSTEM. Under "
4686"Windows, this setting affects the creation of a new system service only."
4687msgstr ""
4688
4689#: contrib/config-daemon.scm:337
4690msgid "Should gnunetd be automatically started when the system boots?"
4691msgstr ""
4692
4693#: contrib/config-daemon.scm:338
4694msgid ""
4695"Set to YES if gnunetd should be automatically started on boot. If this "
4696"option is set, gnunet-setup will install a script to start the daemon upon "
4697"completion. This option may not work on all systems."
4698msgstr ""
4699
4700#: contrib/config-daemon.scm:350
4701msgid "Which transport mechanisms should GNUnet use?"
4702msgstr ""
4703
4704#: contrib/config-daemon.scm:352
4705msgid ""
4706"Use a space-separated list of modules, e.g. \"udp smtp tcp\". The "
4707"available transports are udp, tcp, http, smtp and nat.\n"
4708"\t\t\n"
4709"Loading the 'nat' and 'tcp' modules is required for peers behind NAT boxes "
4710"that cannot directly be reached from the outside. Peers that are NOT behind "
4711"a NAT box and that want to *allow* peers that ARE behind a NAT box to "
4712"connect must ALSO load the 'nat' module. Note that the actual transfer will "
4713"always be via tcp initiated by the peer behind the NAT box. The nat "
4714"transport requires the use of tcp, http and/or smtp in addition to nat "
4715"itself."
4716msgstr ""
4717
4718#: contrib/config-daemon.scm:366
4719msgid "Which applications should gnunetd support?"
4720msgstr ""
4721
4722#: contrib/config-daemon.scm:368
4723msgid ""
4724"Whenever this option is changed, you MUST run gnunet-update. Currently, the "
4725"available applications are:\n"
4726"\n"
4727"advertising: advertises your peer to other peers. Without it, your peer will "
4728"not participate in informing peers about other peers. You should always "
4729"load this module.\n"
4730"\n"
4731"getoption: allows clients to query gnunetd about the values of various "
4732"configuration options. Many tools need this. You should always load this "
4733"module.\n"
4734"\n"
4735"stats: allows tools like gnunet-stats and gnunet-gtk to query gnunetd about "
4736"various statistics. This information is usually quite useful to diagnose "
4737"errors, hence it is recommended that you load this module.\n"
4738"\n"
4739"traffic: keeps track of how many messages were recently received and "
4740"transmitted. This information can then be used to establish how much cover "
4741"traffic is currently available. The amount of cover traffic becomes "
4742"important if you want to make anonymous requests with an anonymity level "
4743"that is greater than one. It is recommended that you load this module.\n"
4744"\n"
4745"fs: needed for anonymous file sharing. You should always load this module.\n"
4746"\n"
4747"hostlist: integrated hostlist HTTP server. Useful if you want to offer a "
4748"hostlist and running Apache would be overkill.\n"
4749"\n"
4750"chat: broadcast chat (demo-application, ALPHA quality).\tRequired for gnunet-"
4751"chat. Note that the current implementation of chat is not considered to be "
4752"secure.\n"
4753"\n"
4754"tbench: benchmark transport performance. Required for gnunet-tbench. Note "
4755"that tbench allows other users to abuse your resources.\n"
4756"\n"
4757"tracekit: topology visualization toolkit. Required for gnunet-tracekit. "
4758"Note that loading tracekit will make it slightly easier for an adversary to "
4759"compromise your anonymity."
4760msgstr ""
4761
4762#: contrib/config-daemon.scm:399
4763msgid "Disable client-server connections"
4764msgstr ""
4765
4766#: contrib/config-daemon.scm:400
4767msgid ""
4768"This option can be used to tell gnunetd not to open the client port. When "
4769"run like this, gnunetd will participate as a peer in the network but not "
4770"support any user interfaces. This may be useful for headless systems that "
4771"are never expected to have end-user interactions. Note that this will also "
4772"prevent you from running diagnostic tools like gnunet-stats!"
4773msgstr ""
4774
4775#: contrib/config-daemon.scm:412
4776msgid "YES disables IPv6 support, NO enables IPv6 support"
4777msgstr ""
4778
4779#: contrib/config-daemon.scm:413
4780msgid ""
4781"This option may be useful on peers where the kernel does not support IPv6. "
4782"You might also want to set this option if you do not have an IPv6 network "
4783"connection."
4784msgstr ""
4785
4786#: contrib/config-daemon.scm:425
4787msgid "Disable peer discovery"
4788msgstr ""
4789
4790#: contrib/config-daemon.scm:426
4791msgid ""
4792"The option 'PRIVATE-NETWORK' can be used to limit the connections of this "
4793"peer to peers of which the hostkey has been copied by hand to data/hosts; "
4794"if this option is given, GNUnet will not accept advertisements of peers that "
4795"the local node does not already know about. Note that in order for this "
4796"option to work, HOSTLISTURL should either not be set at all or be set to a "
4797"trusted peer that only advertises the private network. Also, the option does "
4798"NOT work at the moment if the NAT transport is loaded; for that, a couple of "
4799"lines above would need some minor editing :-)."
4800msgstr ""
4801
4802#: contrib/config-daemon.scm:437
4803msgid "Disable advertising this peer to other peers"
4804msgstr ""
4805
4806#: contrib/config-daemon.scm:449
4807msgid "Disable automatic establishment of connections"
4808msgstr ""
4809
4810#: contrib/config-daemon.scm:450
4811msgid ""
4812"If this option is enabled, GNUnet will not automatically establish "
4813"connections to other peers, but instead wait for applications to "
4814"specifically request connections to other peers (or for other peers to "
4815"connect to us)."
4816msgstr ""
4817
4818#: contrib/config-daemon.scm:461
4819msgid "Enable advertising of other peers by this peer"
4820msgstr ""
4821
4822#: contrib/config-daemon.scm:462
4823msgid ""
4824"This option may be useful during testing, but turning it off is dangerous! "
4825"If in any doubt, set it to YES (which is the default)."
4826msgstr ""
4827
4828#: contrib/config-daemon.scm:473
4829#, fuzzy
4830msgid "Port for communication with GNUnet user interfaces"
4831msgstr "Informationen über andere GNUnet Knoten ausgeben."
4832
4833#: contrib/config-daemon.scm:474
4834msgid ""
4835"Which is the client-server port that is used between gnunetd and the clients "
4836"(TCP only). You may firewall this port for non-local machines (but you do "
4837"not have to since GNUnet will perform access control and only allow "
4838"connections from machines that are listed under TRUSTED)."
4839msgstr ""
4840
4841#: contrib/config-daemon.scm:485
4842msgid "Port for the integrated hostlist HTTP server"
4843msgstr ""
4844
4845#: contrib/config-daemon.scm:497
4846msgid "IPv4 networks allowed to use gnunetd server"
4847msgstr ""
4848
4849#: contrib/config-daemon.scm:498 contrib/config-daemon.scm:510
4850msgid ""
4851"This option specifies which hosts are trusted enough to connect as clients "
4852"(to the TCP port). This is useful if you run gnunetd on one host of your "
4853"network and want to allow all other hosts to use this node as their server. "
4854"By default, this is set to 'loopback only'. The format is IP/NETMASK where "
4855"the IP is specified in dotted-decimal and the netmask either in CIDR "
4856"notation (/16) or in dotted decimal (255.255.0.0). Several entries must be "
4857"separated by a semicolon, spaces are not allowed."
4858msgstr ""
4859
4860#: contrib/config-daemon.scm:509
4861msgid "IPv6 networks allowed to use gnunetd server"
4862msgstr ""
4863
4864#: contrib/config-daemon.scm:522
4865msgid "Limit connections to the specfied set of peers."
4866msgstr ""
4867
4868#: contrib/config-daemon.scm:523
4869msgid ""
4870"If this option is not set, any peer is allowed to connect. If it is set, "
4871"only the specified peers are allowed. Specify the list of peer IDs (not IPs!)"
4872msgstr ""
4873
4874#: contrib/config-daemon.scm:534
4875#, fuzzy
4876msgid "Run gnunetd as this group."
4877msgstr "gnunet-update ausführen"
4878
4879#: contrib/config-daemon.scm:535
4880msgid ""
4881"When started as root, gnunetd will change permissions to the given group."
4882msgstr ""
4883
4884#: contrib/config-daemon.scm:546
4885msgid "Prevent the specfied set of peers from connecting."
4886msgstr ""
4887
4888#: contrib/config-daemon.scm:547
4889msgid ""
4890"If this option is not set, any peer is allowed to connect. If the ID of a "
4891"peer is listed here, connections from that peer will be refused. Specify "
4892"the list of peer IDs (not IPs!)"
4893msgstr ""
4894
4895#: contrib/config-daemon.scm:558
4896msgid "Topology Maintenance"
4897msgstr ""
4898
4899#: contrib/config-daemon.scm:559
4900msgid "Rarely used settings for peer advertisements and connections"
4901msgstr ""
4902
4903#: contrib/config-daemon.scm:579
4904#, fuzzy
4905msgid "General settings"
4906msgstr "Weitere Einstellungen"
4907
4908#: contrib/config-daemon.scm:580
4909msgid "Settings that change the behavior of GNUnet in general"
4910msgstr ""
4911
4912#: contrib/config-daemon.scm:607
4913msgid "Modules"
4914msgstr ""
4915
4916#: contrib/config-daemon.scm:608
4917msgid "Settings that select specific implementations for GNUnet modules"
4918msgstr ""
4919
4920#: contrib/config-daemon.scm:626
4921msgid "Fundamentals"
4922msgstr ""
4923
4924#: contrib/config-daemon.scm:646
4925msgid "Which database should be used?"
4926msgstr ""
4927
4928#: contrib/config-daemon.scm:648
4929msgid ""
4930"Which database should be used? The options are \"sqstore_sqlite\", "
4931"\"sqstore_postgres\" and \"sqstore_mysql\". You must run gnunet-update "
4932"after changing this value!\n"
4933"\t\t\t\n"
4934"In order to use MySQL or Postgres, you must configure the respective "
4935"database, which is relatively simple. Read the file doc/README.mysql or doc/"
4936"README.postgres for how to setup the respective database."
4937msgstr ""
4938
4939#: contrib/config-daemon.scm:661 contrib/config-daemon.scm:674
4940msgid "Which topology should be used?"
4941msgstr ""
4942
4943#: contrib/config-daemon.scm:662
4944msgid "Which database should be used for the temporary datastore of the DHT?"
4945msgstr ""
4946
4947#: contrib/config-daemon.scm:676
4948msgid ""
4949"Which topology should be used? The only option at the moment is "
4950"\"topology_default\""
4951msgstr ""
4952
4953#: contrib/config-daemon.scm:690
4954msgid ""
4955"The minimum number of connected friends before this peer is allowed to "
4956"connect to peers that are not listed as friends"
4957msgstr ""
4958
4959#: contrib/config-daemon.scm:691
4960msgid ""
4961"Note that this option does not guarantee that the peer will be able to "
4962"connect to the specified number of friends. Also, if the peer had connected "
4963"to a sufficient number of friends and then established non-friend "
4964"connections, some of the friends may drop out of the network, temporarily "
4965"resulting in having fewer than the specified number of friends connected "
4966"while being connected to non-friends. However, it is guaranteed that the "
4967"peer itself will never choose to drop a friend's connection if this would "
4968"result in dropping below the specified number of friends (unless that number "
4969"is higher than the overall connection target)."
4970msgstr ""
4971
4972#: contrib/config-daemon.scm:702
4973msgid ""
4974"If set to YES, the peer is only allowed to connect to other peers that are "
4975"explicitly specified as friends"
4976msgstr ""
4977
4978#: contrib/config-daemon.scm:703
4979msgid ""
4980"Use YES only if you have (trustworthy) friends that use GNUnet and are "
4981"afraid of establishing (direct) connections to unknown peers"
4982msgstr ""
4983
4984#: contrib/config-daemon.scm:714
4985msgid "List of friends for friend-to-friend topology"
4986msgstr ""
4987
4988#: contrib/config-daemon.scm:715
4989msgid ""
4990"Specifies the name of a file which contains a list of GNUnet peer IDs that "
4991"are friends. If used with the friend-to-friend topology, this will ensure "
4992"that GNUnet only connects to these peers (via any available transport)."
4993msgstr ""
4994
4995#: contrib/config-daemon.scm:726
4996msgid "Friend-to-Friend Topology Specification"
4997msgstr ""
4998
4999#: contrib/config-daemon.scm:727
5000#, fuzzy
5001msgid "Settings for restricting connections to friends"
5002msgstr "`%s' fehlgeschlagen. Beende Verbindung zu Client.\n"
5003
5004#: contrib/config-daemon.scm:744
5005msgid "Name of the MySQL database GNUnet should use"
5006msgstr ""
5007
5008#: contrib/config-daemon.scm:756
5009#, fuzzy
5010msgid "Configuration file that specifies the MySQL username and password"
5011msgstr ""
5012"Konfiguration oder die GNUnet Version hat sich geändert. Sie müssen `%s' "
5013"ausführen!\n"
5014
5015#: contrib/config-daemon.scm:768
5016#, fuzzy
5017msgid "Configuration of the MySQL database"
5018msgstr ""
5019"Konfiguration oder die GNUnet Version hat sich geändert. Sie müssen `%s' "
5020"ausführen!\n"
5021
5022#: contrib/config-daemon.scm:787
5023#, fuzzy
5024msgid "MB of diskspace GNUnet can use for anonymous file sharing"
5025msgstr "Ermöglicht (anonymes) Filesharing"
5026
5027#: contrib/config-daemon.scm:789
5028msgid ""
5029"How much disk space (MB) is GNUnet allowed to use for anonymous file "
5030"sharing? This does not take indexed files into account, only the space "
5031"directly used by GNUnet is accounted for. GNUnet will gather content from "
5032"the network if the current space-consumption is below the number given here "
5033"(and if content migration is allowed below).\n"
5034"\n"
5035"Note that if you change the quota, you need to run gnunet-update afterwards."
5036msgstr ""
5037
5038#: contrib/config-daemon.scm:803
5039#, fuzzy
5040msgid "Number of entries in the migration buffer"
5041msgstr "Anzahl an Nachrichten in einem Nachrichtenblock"
5042
5043#: contrib/config-daemon.scm:804
5044msgid ""
5045"Each entry uses about 32k of memory. More entries can reduce disk IO and "
5046"CPU usage at the expense of having gnunetd use more memory. Very large "
5047"values may again increase CPU usage. A value of 0 will prevent your peer "
5048"from sending unsolicited responses."
5049msgstr ""
5050
5051#: contrib/config-daemon.scm:816
5052msgid "Size of the routing table for anonymous routing."
5053msgstr ""
5054
5055#: contrib/config-daemon.scm:828
5056msgid "Size of the routing table for DHT routing."
5057msgstr ""
5058
5059#: contrib/config-daemon.scm:841
5060msgid "Allow migrating content to this peer."
5061msgstr ""
5062
5063#: contrib/config-daemon.scm:843
5064msgid ""
5065"If you say yes here, GNUnet will migrate content to your server, and you "
5066"will not be able to control what data is stored on your machine. \n"
5067"\t\t\t\n"
5068"If you activate it, you can claim for *all* the non-indexed (-n to gnunet-"
5069"insert) content that you did not know what it was even if an adversary takes "
5070"control of your machine. If you do not activate it, it is obvious that you "
5071"have knowledge of all the content that is hosted on your machine and thus "
5072"can be considered liable for it."
5073msgstr ""
5074
5075#: contrib/config-daemon.scm:857
5076msgid ""
5077"MB of diskspace GNUnet can use for caching DHT index data (the data will be "
5078"stored in /tmp)"
5079msgstr ""
5080
5081#: contrib/config-daemon.scm:858
5082msgid ""
5083"DHT index data is inherently small and expires comparatively quickly. It is "
5084"deleted whenever gnunetd is shut down.\n"
5085"\n"
5086"The size of the DSTORE QUOTA is specified in MB."
5087msgstr ""
5088
5089#: contrib/config-daemon.scm:872
5090#, fuzzy
5091msgid "Options for anonymous file sharing"
5092msgstr "Ermöglicht (anonymes) Filesharing"
5093
5094#: contrib/config-daemon.scm:891
5095#, fuzzy
5096msgid "Applications"
5097msgstr "_Optionen"
5098
5099#: contrib/config-daemon.scm:907
5100msgid "Is this machine unreachable behind a NAT?"
5101msgstr ""
5102
5103#: contrib/config-daemon.scm:908
5104msgid ""
5105"Set to YES if this machine is behind a NAT that limits connections from the "
5106"outside to the GNUnet port and that cannot be traversed using UPnP. Note "
5107"that if you have configured your NAT box to allow direct connections from "
5108"other machines to the GNUnet ports or if GNUnet can open ports using UPnP, "
5109"you should set the option to NO. Set this only to YES if other peers cannot "
5110"contact you directly. You can use 'make check' in src/transports/upnp/ to "
5111"find out if your NAT supports UPnP. You can also use gnunet-transport-check "
5112"with the '-p' option in order to determine which setting results in more "
5113"connections. Use YES only if you get no connections otherwise. Set to AUTO "
5114"to use YES if the local IP is belongs to a private IP network and NO "
5115"otherwise."
5116msgstr ""
5117
5118#: contrib/config-daemon.scm:919
5119msgid "Which port should be used by the TCP IPv4 transport?"
5120msgstr ""
5121
5122#: contrib/config-daemon.scm:931 contrib/config-daemon.scm:1024
5123#: contrib/config-daemon.scm:1174
5124msgid "Should we try to determine our external IP using UPnP?"
5125msgstr ""
5126
5127#: contrib/config-daemon.scm:943
5128msgid "Which IP(v4)s are not allowed to connect?"
5129msgstr ""
5130
5131#: contrib/config-daemon.scm:955
5132msgid ""
5133"Which IP(v4)s are allowed to connect? Leave empty to use the IP of your "
5134"primary network interface."
5135msgstr ""
5136
5137#: contrib/config-daemon.scm:967 contrib/config-daemon.scm:1222
5138msgid "Which IPv6s are not allowed to connect?"
5139msgstr ""
5140
5141#: contrib/config-daemon.scm:979 contrib/config-daemon.scm:1234
5142msgid ""
5143"Which IPv6s are allowed to connect? Leave empty to allow any IP to connect."
5144msgstr ""
5145
5146#: contrib/config-daemon.scm:992
5147msgid "TCP transport"
5148msgstr ""
5149
5150#: contrib/config-daemon.scm:1012
5151msgid "Which port should be used by the HTTP transport?"
5152msgstr ""
5153
5154#: contrib/config-daemon.scm:1036
5155msgid "Which is the external port of the HTTP transport?"
5156msgstr ""
5157
5158#: contrib/config-daemon.scm:1037
5159msgid ""
5160"Use this option if your firewall maps, say, port 80 to your real HTTP port. "
5161"This can be useful in making the HTTP messages appear even more legit "
5162"(without needing to run gnunetd as root due to the use of a privileged port)."
5163msgstr ""
5164
5165#: contrib/config-daemon.scm:1048
5166msgid "HTTP transport"
5167msgstr ""
5168
5169#: contrib/config-daemon.scm:1067
5170msgid "What is the maximum transfer unit for SMTP?"
5171msgstr ""
5172
5173#: contrib/config-daemon.scm:1079
5174msgid ""
5175"What is the maximum number of e-mails that gnunetd would be allowed to send "
5176"per hour?"
5177msgstr ""
5178
5179#: contrib/config-daemon.scm:1080
5180msgid "Use 0 for unlimited"
5181msgstr ""
5182
5183#: contrib/config-daemon.scm:1091
5184msgid "Which e-mail address should be used to send e-mail to this peer?"
5185msgstr ""
5186
5187#: contrib/config-daemon.scm:1092
5188msgid ""
5189"You must make sure that e-mail received at this address is forwarded to the "
5190"PIPE which is read by gnunetd. Use the FILTER option to filter e-mail with "
5191"procmail and the PIPE option to set the name of the pipe."
5192msgstr ""
5193
5194#: contrib/config-daemon.scm:1103
5195msgid ""
5196"Which header line should other peers include in e-mails to enable filtering?"
5197msgstr ""
5198
5199#: contrib/config-daemon.scm:1104
5200msgid ""
5201"You can specify a header line here which can then be used by procmail to "
5202"filter GNUnet e-mail from your inbox and forward it to gnunetd."
5203msgstr ""
5204
5205#: contrib/config-daemon.scm:1115
5206msgid "What is the filename of the pipe where gnunetd can read its e-mail?"
5207msgstr ""
5208
5209#: contrib/config-daemon.scm:1116
5210msgid "Have a look at contrib/dot-procmailrc for an example .procmailrc file."
5211msgstr ""
5212
5213#: contrib/config-daemon.scm:1127
5214msgid "What is the name and port of the server for outgoing e-mail?"
5215msgstr ""
5216
5217#: contrib/config-daemon.scm:1128
5218msgid "The basic format is HOSTNAME:PORT."
5219msgstr ""
5220
5221#: contrib/config-daemon.scm:1139
5222msgid "SMTP transport"
5223msgstr ""
5224
5225#: contrib/config-daemon.scm:1162
5226msgid "Which port should be used by the UDP IPv4 transport?"
5227msgstr ""
5228
5229#: contrib/config-daemon.scm:1186
5230msgid "What is the maximum transfer unit for UDP?"
5231msgstr ""
5232
5233#: contrib/config-daemon.scm:1198
5234msgid "Which IPs are not allowed to connect?"
5235msgstr ""
5236
5237#: contrib/config-daemon.scm:1210
5238msgid ""
5239"Which IPs are allowed to connect? Leave empty to allow connections from any "
5240"IP."
5241msgstr ""
5242
5243#: contrib/config-daemon.scm:1246
5244msgid "UDP transport"
5245msgstr ""
5246
5247#: contrib/config-daemon.scm:1268
5248#, fuzzy
5249msgid "Network interface"
5250msgstr "Netzwerkgerät:"
5251
5252#: contrib/config-daemon.scm:1280
5253msgid "External IP address (leave empty to try auto-detection)"
5254msgstr ""
5255
5256#: contrib/config-daemon.scm:1292
5257msgid "External IPv6 address (leave empty to try auto-detection)"
5258msgstr ""
5259
5260#: contrib/config-daemon.scm:1304
5261msgid "Transports"
5262msgstr ""
5263
5264#: contrib/config-daemon.scm:1326
5265msgid "What is the maximum number of bytes per second that we may receive?"
5266msgstr ""
5267
5268#: contrib/config-daemon.scm:1338
5269msgid "What is the maximum number of bytes per second that we may send?"
5270msgstr ""
5271
5272#: contrib/config-daemon.scm:1350
5273msgid "What is the maximum CPU load (percentage)?"
5274msgstr ""
5275
5276#: contrib/config-daemon.scm:1351
5277msgid ""
5278"The highest tolerable CPU load. Load here always refers to the total system "
5279"load, that is it includes CPU utilization by other processes. A value of 50 "
5280"means that once your 1 minute-load average goes over 50% non-idle, GNUnet "
5281"will try to reduce CPU consumption until the load goes under the threshold. "
5282"Reasonable values are typically between 50 and 100. Multiprocessors may use "
5283"values above 100."
5284msgstr ""
5285
5286#: contrib/config-daemon.scm:1362
5287msgid "What is the maximum IO load (permille)?"
5288msgstr ""
5289
5290#: contrib/config-daemon.scm:1364
5291msgid ""
5292"The highest tolerable IO load. Load here refers to the percentage of CPU "
5293"cycles wasted waiting for IO for the entire system, that is it includes disk "
5294"utilization by other processes. A value of 10 means that once the average "
5295"number of cycles wasted waiting for IO is more than 10% non-idle, GNUnet "
5296"will try to reduce IO until the load goes under the threshold. Reasonable "
5297"values are typically between 10 and 75."
5298msgstr ""
5299
5300#: contrib/config-daemon.scm:1375
5301msgid "What is the maximum CPU load (hard limit)?"
5302msgstr ""
5303
5304#: contrib/config-daemon.scm:1376
5305msgid ""
5306"The highest tolerable CPU load. This is the hard limit, so once it is "
5307"reached, gnunetd will start to massively drop data to reduce the load. Use "
5308"with caution."
5309msgstr ""
5310
5311#: contrib/config-daemon.scm:1387
5312msgid "What is the maximum upstream bandwidth (hard limit)?"
5313msgstr ""
5314
5315#: contrib/config-daemon.scm:1388
5316msgid ""
5317"The limit is given as a percentage of the MAXNETUPBPS limit. Use 100 to "
5318"have MAXNETUPBPS be the hard limit. Use zero for no limit."
5319msgstr ""
5320
5321#: contrib/config-daemon.scm:1400
5322msgid "What priority should gnunetd use to run?"
5323msgstr ""
5324
5325#: contrib/config-daemon.scm:1401
5326msgid ""
5327"You can specify priorities like NORMAL, ABOVE NORMAL, BELOW NORMAL, HIGH and "
5328"IDLE or a numerical integer value (man nice). The default is IDLE, which "
5329"should result in gnunetd only using resources that would otherwise be idle."
5330msgstr ""
5331
5332#: contrib/config-daemon.scm:1413
5333msgid "Should we disable random padding (experimental option)?"
5334msgstr ""
5335
5336#: contrib/config-daemon.scm:1425
5337msgid "Use basic bandwidth limitation? (YES/NO). If in doubt, say YES."
5338msgstr ""
5339
5340#: contrib/config-daemon.scm:1427
5341msgid ""
5342"Basic bandwidth limitation (YES) means simply that the bandwidth limits "
5343"specified apply to GNUnet and only to GNUnet. If set to YES, you simply "
5344"specify the maximum bandwidth (upstream and downstream) that GNUnet is "
5345"allowed to use and GNUnet will stick to those limitations. This is useful "
5346"if your overall bandwidth is so large that the limit is mostly used to "
5347"ensure that enough capacity is left for other applications. Even if you "
5348"want to dedicate your entire connection to GNUnet you should not set the "
5349"limits to values higher than what you have since GNUnet uses those limits to "
5350"determine for example the number of connections to establish (and it would "
5351"be inefficient if that computation yields a number that is far too high). \n"
5352"\n"
5353"While basic bandwidth limitation is simple and always works, there are some "
5354"situations where it is not perfect. Suppose you are running another "
5355"application which performs a larger download. During that particular time, "
5356"it would be nice if GNUnet would throttle its bandwidth consumption "
5357"(automatically) and resume using more bandwidth after the download is "
5358"complete. This is obviously advanced magic since GNUnet will have to "
5359"monitor the behavior of other applications. Another scenario is a monthly "
5360"cap on bandwidth imposed by your ISP, which you would want to ensure is "
5361"obeyed. Here, you may want GNUnet to monitor the traffic from other "
5362"applications to ensure that the combined long-term traffic is within the pre-"
5363"set bounds. Note that you should probably not set the bounds tightly since "
5364"GNUnet may observe that the bounds are about to be broken but would be "
5365"unable to stop other applications from continuing to use bandwidth.\n"
5366"\n"
5367"If either of these two scenarios applies, set BASICLIMITING to NO. Then set "
5368"the bandwidth limits to the COMBINED amount of traffic that is acceptable "
5369"for both GNUnet and other applications. GNUnet will then immediately "
5370"throttle bandwidth consumption if the short-term average is above the limit, "
5371"and it will also try to ensure that the long-term average is below the "
5372"limit. Note however that using NO can have the effect of GNUnet (almost) "
5373"ceasing operations after other applications perform high-volume downloads "
5374"that are beyond the defined limits. GNUnet would reduce consumption until "
5375"the long-term limits are again within bounds.\n"
5376"\n"
5377"NO only works on platforms where GNUnet can monitor the amount of traffic "
5378"that the local host puts out on the network. This is only implemented for "
5379"Linux and Win32. In order for the code to work, GNUnet needs to know the "
5380"specific network interface that is used for the external connection (after "
5381"all, the amount of traffic on loopback or on the LAN should never be counted "
5382"since it is irrelevant)."
5383msgstr ""
5384
5385#: contrib/config-daemon.scm:1444
5386#, fuzzy
5387msgid "Network interface to monitor"
5388msgstr "Netzwerkgerät:"
5389
5390#: contrib/config-daemon.scm:1445
5391msgid ""
5392"For which interfaces should we do accounting? GNUnet will evaluate the "
5393"total traffic (not only the GNUnet related traffic) and adjust its bandwidth "
5394"usage accordingly. You can currently only specify a single interface. GNUnet "
5395"will also use this interface to determine the IP to use. Typical values are "
5396"eth0, ppp0, eth1, wlan0, etc. 'ifconfig' will tell you what you have. "
5397"Never use 'lo', that just won't work. Under Windows, specify the index "
5398"number reported by 'gnunet-win-tool -n'."
5399msgstr ""
5400
5401#: contrib/config-daemon.scm:1456
5402#, fuzzy
5403msgid "Load management"
5404msgstr "Ungültige Kommandozeilen Parameter.\n"
5405
5406#: contrib/config-daemon.scm:1482 contrib/config-client.scm:413
5407msgid "Root node"
5408msgstr ""
5409
5410#: contrib/config-client.scm:153
5411msgid "Where should gnunet-clients write their logs?"
5412msgstr ""
5413
5414#: contrib/config-client.scm:185
5415msgid "On which machine and port is gnunetd running (for clients)?"
5416msgstr ""
5417
5418#: contrib/config-client.scm:186
5419#, fuzzy
5420msgid "This is equivalent to the -H option. The format is IP:PORT."
5421msgstr "Wert der Option anzeigen"
5422
5423#: contrib/config-client.scm:197
5424#, fuzzy
5425msgid "What is the path to the configuration file for gnunetd?"
5426msgstr ""
5427"Einen Wert aus der Konfigurationsdatei auf der Standardausgabe ausgeben"
5428
5429#: contrib/config-client.scm:198
5430msgid "This option is used when clients need to start gnunetd."
5431msgstr ""
5432
5433#: contrib/config-client.scm:210
5434#, fuzzy
5435msgid "General options"
5436msgstr "Weitere Einstellungen"
5437
5438#: contrib/config-client.scm:227
5439msgid "Do not add metadata listing the creation time for inserted content"
5440msgstr ""
5441
5442#: contrib/config-client.scm:239
5443msgid "Which non-default extractors should GNUnet use for keyword extractors"
5444msgstr ""
5445
5446#: contrib/config-client.scm:240
5447msgid ""
5448"Specify which additional extractor libraries should be used. gnunet-insert "
5449"uses libextractor to extract keywords from files. libextractor can be "
5450"dynamically extended to handle additional file formats. If you want to use "
5451"more than the default set of extractors, specify additional extractor "
5452"libraries here. The format is [[-]LIBRARYNAME[:[-]LIBRARYNAME]*].\n"
5453"\n"
5454"The default is to use filenames and to break larger words at spaces (and "
5455"underscores, etc.). This should be just fine for most people. The '-' "
5456"before a library name indicates that this should be executed last and makes "
5457"only sense for the split-library."
5458msgstr ""
5459
5460#: contrib/config-client.scm:253
5461msgid "How many entries should the URI DB table have?"
5462msgstr ""
5463
5464#: contrib/config-client.scm:254
5465msgid ""
5466"GNUnet uses two bytes per entry on the disk. This database is used to keep "
5467"track of how a particular URI has been used in the past. For example, "
5468"GNUnet may remember that a particular URI has been found in a search "
5469"previously or corresponds to a file uploaded by the user. This information "
5470"can then be used by user-interfaces to filter URI lists, such as search "
5471"results. If the database is full, older entries will be discarded. The "
5472"default value should be sufficient without causing undue disk utilization."
5473msgstr ""
5474
5475#: contrib/config-client.scm:265
5476msgid "Location of the file specifying metadata for the auto-share directory"
5477msgstr ""
5478
5479#: contrib/config-client.scm:277
5480msgid ""
5481"Location of the file with the PID of any running gnunet-auto-share daemon "
5482"process"
5483msgstr ""
5484
5485#: contrib/config-client.scm:289
5486msgid "Location of the log file for gnunet-auto-share"
5487msgstr ""
5488
5489#: contrib/config-client.scm:301
5490#, fuzzy
5491msgid "File-Sharing options"
5492msgstr "Alle Optionen anzeigen"
5493
5494#: contrib/config-client.scm:319
5495msgid "Which plugins should be loaded by gnunet-gtk?"
5496msgstr ""
5497
5498#: contrib/config-client.scm:320
5499msgid ""
5500"Load the about plugin for the about dialog. The daemon plugin allows "
5501"starting and stopping of gnunetd and displays information about gnunetd. "
5502"The fs plugin provides the file-sharing functionality. The stats plugin "
5503"displays various statistics about gnunetd."
5504msgstr ""
5505
5506#: contrib/config-client.scm:331
5507msgid "How frequently (in milli-seconds) should the statistics update?"
5508msgstr ""
5509
5510#: contrib/config-client.scm:332
5511msgid ""
5512"Each pixel in the stats dialog corresponds to the time interval specified "
5513"here."
5514msgstr ""
5515
5516#: contrib/config-client.scm:344
5517msgid "Do not show thumbnail previews from meta-data in search results"
5518msgstr ""
5519
5520#: contrib/config-client.scm:345
5521msgid ""
5522"This option is useful for people who maybe offended by some previews or use "
5523"gnunet-gtk at work and would like to avoid bad surprises."
5524msgstr ""
5525
5526#: contrib/config-client.scm:356
5527msgid "Do not show search results for files that were uploaded by us"
5528msgstr ""
5529
5530#: contrib/config-client.scm:357
5531msgid ""
5532"This option is useful to eliminate files that the user already has from the "
5533"search. Naturally, enabling this option maybe confusing because some "
5534"obviously expected search results would no longer show up. This option only "
5535"works if the URI_DB_SIZE option under FS is not zero (since the URI DB is "
5536"used to determine which files the user is sharing)"
5537msgstr ""
5538
5539#: contrib/config-client.scm:369
5540msgid "To which directory should gnunet-gtk save downloads to?"
5541msgstr ""
5542
5543#: contrib/config-client.scm:381
5544#, fuzzy
5545msgid "Options related to gnunet-gtk"
5546msgstr "Nicht verbunden zu gnunetd."
5547
5548#: contrib/config-client.scm:401
5549#, fuzzy
5550msgid "Full pathname of GNUnet client HOME directory"
5551msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n"
5552
5553#: contrib/config-client.scm:402
5554msgid "The directory for GNUnet files that belong to the user."
5555msgstr ""
5556
5557#~ msgid "Could not determine my public IPv6 address.\n"
5558#~ msgstr "Die öffentliche IPv6-Adresse konnte nicht ermittelt werden.\n"
5559
5560#~ msgid "`%s': unknown service: %s\n"
5561#~ msgstr "`%s': unbekannter Dienst: %s\n"
5562
5563#~ msgid "Failed to start transport service on port %d.\n"
5564#~ msgstr "Der Transportdienst auf Port %d konnte nicht gestartet werden.\n"
5565
5566#, fuzzy
5567#~ msgid "# bytes received via TCP6"
5568#~ msgstr "# Bytes empfangen über TCP"
5569
5570#, fuzzy
5571#~ msgid "# bytes sent via TCP6"
5572#~ msgstr "# Bytes gesendet über TCP"
5573
5574#, fuzzy
5575#~ msgid "# bytes dropped by TCP6 (outgoing)"
5576#~ msgstr "# Bytes verworfen von TCP (ausgehend)"
5577
5578#~ msgid "UDP6: Could not determine my public IPv6 address.\n"
5579#~ msgstr "UDP6: Öffentliche IPv6-Adresse konnte nicht ermittelt werden.\n"
5580
5581#, fuzzy
5582#~ msgid "# bytes received via UDP6"
5583#~ msgstr "# Bytes empfangen über UDP"
5584
5585#, fuzzy
5586#~ msgid "# bytes sent via UDP6"
5587#~ msgstr "# Bytes gesendet über UDP"
5588
5589#, fuzzy
5590#~ msgid "# bytes dropped by UDP6 (outgoing)"
5591#~ msgstr "# Bytes verworfen von UDP (outgoing)"
5592
5593#~ msgid "HTTP: Could not determine my public IP address.\n"
5594#~ msgstr "HTTP: öffentliche IP-Adresse konnte nicht ermittelt werden.\n"
5595
5596#, fuzzy
5597#~ msgid "Received malformed message instead of welcome message. Closing.\n"
5598#~ msgstr ""
5599#~ "Es wurde per TCP von einem anderen Knoten eine ungültige Nachricht (Größe "
5600#~ "%u) empfangen. Verbindung wird geschlossen.\n"
5601
5602#, fuzzy
5603#~ msgid "Received malformed message from tcp-peer connection. Closing.\n"
5604#~ msgstr ""
5605#~ "Es wurde per TCP von einem anderen Knoten eine ungültige Nachricht (Größe "
5606#~ "%u) empfangen. Verbindung wird geschlossen.\n"
5607
5608#, fuzzy
5609#~ msgid "TCP: Could not determine my public IP address.\n"
5610#~ msgstr "HTTP: öffentliche IP-Adresse konnte nicht ermittelt werden.\n"
5611
5612#~ msgid "Cannot connect to %u.%u.%u.%u:%u: %s\n"
5613#~ msgstr "Verbindung zu %u.%u.%u.%u:%u fehlgeschlagen: %s\n"
5614
5615#~ msgid "UDP: Could not determine my public IP address.\n"
5616#~ msgstr "UDP: öffentliche IP-Adresse konnte nicht ermittelt werden.\n"
5617
5618#~ msgid "Failed to send message of size %d via UDP to %u.%u.%u.%u:%u: %s\n"
5619#~ msgstr ""
5620#~ "Eine Nachricht der Größe %d konnte nicht per UDP an %u.%u.%u.%u:%u "
5621#~ "versendet werden: %s\n"
5622
5623#, fuzzy
5624#~ msgid "Received malformed message from udp-peer connection. Closing.\n"
5625#~ msgstr ""
5626#~ "Es wurde per TCP von einem anderen Knoten eine ungültige Nachricht (Größe "
5627#~ "%u) empfangen. Verbindung wird geschlossen.\n"
5628
5629#~ msgid "'%s(%s,%s)' succeeded\n"
5630#~ msgstr "'%s(%s,%s)' erfolgreich abgeschlossen\n"
5631
5632#~ msgid "'%s(%s,%s)' failed.\n"
5633#~ msgstr "'%s(%s,%s)' fehlgeschlagen.\n"
5634
5635#~ msgid ""
5636#~ "%s::%s - RPC %s:%p could not be unregistered: another callback registered "
5637#~ "under that name: %p\n"
5638#~ msgstr ""
5639#~ "%s::%s - RPC %s:%p konnte nicht unregistriert werden: ein anderer "
5640#~ "Callback ist unter diesem Namen registiert: %p\n"
5641
5642#~ msgid "%s::%s - RPC %s:%p could not be unregistered: not found\n"
5643#~ msgstr ""
5644#~ "%s::%s - RPC %s:%p konnte nicht unregistriert werden: nicht gefunden\n"
5645
5646#~ msgid "Invalid message of type %u received. Dropping.\n"
5647#~ msgstr ""
5648#~ "Ungültige Nachricht des Typs %u empfangen. Nachricht wird verworfen.\n"
5649
5650#~ msgid "Dropping RPC request %u: message malformed.\n"
5651#~ msgstr "RPC Anfrage %u wird verworfen: Nachricht ist beschädigt.\n"
5652
5653#~ msgid "`%s' called with timeout above 1 hour (bug?)\n"
5654#~ msgstr "`%s' mit einem Timeout von über einer Stunde aufgerufen (Fehler?)\n"
5655
5656#~ msgid "RPC not unregistered: %s:%p\n"
5657#~ msgstr "RPC nicht unregistriert: %s:%p\n"
5658
5659#~ msgid "RPC async reply invalid.\n"
5660#~ msgstr "RPC async Antwort ungültig.\n"
5661
5662#~ msgid "async RPC reply not received.\n"
5663#~ msgstr "async RPC Antwort nicht empfangen.\n"
5664
5665#~ msgid "GAP received invalid content from `%s'\n"
5666#~ msgstr "GAP hat ungültige Inhalte von `%s' empfangen.\n"
5667
5668#~ msgid ""
5669#~ "Cover traffic requested but traffic service not loaded. Rejecting "
5670#~ "request.\n"
5671#~ msgstr ""
5672#~ "Verdeckender Netzwerkverkehr angefordert, aber der Verkehrsdienst wurde "
5673#~ "nicht geladen. Anfrage wird abgelehnt.\n"
5674
5675#~ msgid "Cannot satisfy desired level of anonymity, ignoring request.\n"
5676#~ msgstr ""
5677#~ "Gewünschter Grad an Anonymität kann nicht erreicht werden, Anfrage wird "
5678#~ "ignoriert.\n"
5679
5680#~ msgid "# gap requests policy: immediate drop"
5681#~ msgstr "# gap Anfragen mit taktischer Entscheidung: sofortiges Verwerfen"
5682
5683#~ msgid "# gap requests policy: not routed"
5684#~ msgstr "# gap Anfragen mit taktischer Entscheidung: kein Routing"
5685
5686#~ msgid "# gap requests policy: not answered"
5687#~ msgstr "# gap Anfragen mit taktischer Entscheidung: nicht Antworten"
5688
5689#~ msgid "# gap requests processed: attempted add to RT"
5690#~ msgstr "# gap Anfragen verarbeitet: versucht, der RT hinzuzufügen"
5691
5692#~ msgid "# gap requests processed: local result"
5693#~ msgstr "# gap Anfragen verarbeitet: lokales Ergebnis"
5694
5695#~ msgid "# gap requests forwarded (counting each peer)"
5696#~ msgstr "#gap Anfragen weitergeleitet (jeder Knoten gezählt)"
5697
5698#~ msgid "# gap duplicate requests (pending)"
5699#~ msgstr "# gap doppelte Anfragen (unfertig)"
5700
5701#~ msgid "# gap duplicate requests that were re-tried"
5702#~ msgstr "# gap doppelte Anfragen, die wiederholt wurden"
5703
5704#~ msgid "# gap re-try ttl difference (cummulative)"
5705#~ msgstr "# gap Wiederholungs-TTL-Differenz (kummulativ)"
5706
5707#~ msgid "# gap reply duplicates"
5708#~ msgstr "#gap doppelte Antworten"
5709
5710#~ msgid "# gap routing slots currently in use"
5711#~ msgstr "# gap Routingschächte im Moment in Verwendung"
5712
5713#, fuzzy
5714#~ msgid "# gap rewards pending"
5715#~ msgstr "# gap doppelte Anfragen (unfertig)"
5716
5717#, fuzzy
5718#~ msgid "# gap response weights"
5719#~ msgstr "# gap falsche Antworten"
5720
5721#~ msgid ""
5722#~ "Traffic service failed to load; gap cannot ensure cover-traffic "
5723#~ "availability.\n"
5724#~ msgstr ""
5725#~ "Verkehrsdienst konnte nicht geladen werden, GAP kann keinen verdeckenden "
5726#~ "Netzwerkverkehr sicherstellen.\n"
5727
5728#~ msgid "`%s' registering handlers %d %d\n"
5729#~ msgstr "`%s' registriert Handler %d %d\n"
5730
5731#~ msgid ""
5732#~ "set interval for availability of updates to SECONDS (for namespace "
5733#~ "insertions only)"
5734#~ msgstr ""
5735#~ "Intervall der Verfügbarkeit von Updates auf SECONDS setzen (nur für das "
5736#~ "Einfügen in Namespaces)"
5737
5738#~ msgid ""
5739#~ "specifies this as an aperiodic but updated publication (for namespace "
5740#~ "insertions only)"
5741#~ msgstr ""
5742#~ "Dies als unregelmäßige aber aktualisierbare Veröffentlichung kennzeichnen "
5743#~ "(nur für das Einfügen in Namespaces)"
5744
5745#~ msgid "specify creation time for SBlock (see man-page for format)"
5746#~ msgstr "Erstellungszeit für den SBLOCK angeben (s. Manpage zum Format)"
5747
5748#~ msgid ""
5749#~ "ID of the previous version of the content (for namespace update only)"
5750#~ msgstr ""
5751#~ "ID der vorherigen Version des Inhalts (nur für das Einfügen in Namespaces)"
5752
5753#~ msgid "Parsing time failed. Use `%s' format.\n"
5754#~ msgstr "Das Parsen der Zeit schlug fehl. Verwenden Sie das `%s' Format.\n"
5755
5756#~ msgid "exit after receiving LIMIT results"
5757#~ msgstr "Abbrechen, nachdem LIMIT Ergebnisse empfangen wurden"
5758
5759#~ msgid "wait DELAY seconds for search results before aborting"
5760#~ msgstr "TIMEOUT Sekunden auf Suchergebnisse warten, bevor abgebrochen wird"
5761
5762#, fuzzy
5763#~ msgid "# FS currently tracked queries from clients"
5764#~ msgstr "# Client Trace-Antworten gesendet"
5765
5766#~ msgid "Indexed file disappeared, deleting block for query `%s'\n"
5767#~ msgstr ""
5768#~ "Indizierte Datei ist verschwunden, Block für Anfrage `%s' wird gelöscht\n"
5769
5770#~ msgid ""
5771#~ "Configuration file must specify directory for storage of FS data in "
5772#~ "section `%s' under `%s'.\n"
5773#~ msgstr ""
5774#~ "Die Konfigurationsdatei muss ein Verzeichnis für die Speicherung von FS "
5775#~ "Daten in der Sektion `%s' unter `%s' angeben.\n"
5776
5777#~ msgid ""
5778#~ "You must specify a postive number for `%s' in the configuration in "
5779#~ "section `%s'.\n"
5780#~ msgstr ""
5781#~ "Sie müssen für `%s' in der Sektion `%s' der Konfigurationsdatei eine "
5782#~ "positive Zahl angeben.\n"
5783
5784#, fuzzy
5785#~ msgid "# FS valid replies received"
5786#~ msgstr "# Bytes empfangen über TCP"
5787
5788#~ msgid "AND"
5789#~ msgstr "UND"
5790
5791#~ msgid "Error running search (no reason given)."
5792#~ msgstr "Das Starten der Suche schlug fehl (Ursache unbekannt)."
5793
5794#~ msgid "Download failed (no reason given)"
5795#~ msgstr "ECRS Download schlug fehl (Ursache unbekannt)."
5796
5797#~ msgid "Could not unlink temporary file `%s': %s\n"
5798#~ msgstr "Temporäre Datei `%s' konnte nicht gelöscht werden: %s\n"
5799
5800#~ msgid "Write(%d, %p, %d) failed: %s\n"
5801#~ msgstr "Write(%d, %p, %d) schlug fehl: %s\n"
5802
5803#~ msgid ""
5804#~ "Content `%s' seems to be not available on the network (tried %u times).\n"
5805#~ msgstr ""
5806#~ "Inhalt `%s' scheint im Netzwerk nicht verfügbar zu sein (%u mal "
5807#~ "versucht).\n"
5808
5809#~ msgid "Cannot create pseudonym `%s', file `%s' exists.\n"
5810#~ msgstr ""
5811#~ "Pseudonym `%s' kann nicht erstellt werden, da die Datei `%s' bereits "
5812#~ "existiert.\n"
5813
5814#~ msgid "Publication interval for periodic publication changed."
5815#~ msgstr ""
5816#~ "Veröffentlichungsintervall für periodische Veröffentlichung wurde "
5817#~ "geändert."
5818
5819#~ msgid ""
5820#~ "Publishing update for periodically updated content more than a week ahead "
5821#~ "of schedule.\n"
5822#~ msgstr ""
5823#~ "Veröffentlichungsdatum für periodisch aktualisierten Inhalt ist mehr als "
5824#~ "eine Woche früher als geplant.\n"
5825
5826#~ msgid "Message received from peer is invalid.\n"
5827#~ msgstr "Empfangene Nachricht ist ungültig.\n"
5828
5829#~ msgid "Message received from client is invalid\n"
5830#~ msgstr "Empfangene Client-Nachricht ist ungültig.\n"
5831
5832#~ msgid "Maximum number of chat clients reached.\n"
5833#~ msgstr "Maximale Anzahl an Chat Clients erreicht.\n"
5834
5835#~ msgid "Now %d of %d chat clients at this node.\n"
5836#~ msgstr "Jetzt sind %d von %d auf diesem Knoten.\n"
5837
5838#, fuzzy
5839#~ msgid "Invalid data in %s (NCS). Trying to fix (by deletion).\n"
5840#~ msgstr "Ungültige Daten in %s. Korrektur wird versucht (durch Löschung).\n"
5841
5842#, fuzzy
5843#~ msgid "`%s' failed at %s:%d with error: %s"
5844#~ msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n"
5845
5846#, fuzzy
5847#~ msgid "`%s' failed at %s:%d with error `%s' after %llums\n"
5848#~ msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n"
5849
5850#~ msgid "Trying to use file `%s' for MySQL configuration.\n"
5851#~ msgstr "Versuche, Datei `%s' für MySQL Konfiguration zu verwenden.\n"
5852
5853#~ msgid ""
5854#~ "Directory `%s' in directory `%s' does not match naming convention. "
5855#~ "Removed.\n"
5856#~ msgstr ""
5857#~ "Die Datei `%s' im Verzeichnis `%s' entspricht nicht der Namenskonvention. "
5858#~ "Datei wurde entfernt.\n"
5859
5860#~ msgid "Start GNUnet-testbed helper."
5861#~ msgstr "GNUnet-testbed Helfer starten."
5862
5863#~ msgid "Cannot connect to LOOPBACK port %d: %s\n"
5864#~ msgstr "Verbindung zum LOOPBACK port %d schlug fehl: %s\n"
5865
5866#~ msgid "Could not execute `%s': %s\n"
5867#~ msgstr "`%s' konnte nicht ausgeführt werden: %s\n"
5868
5869#~ msgid "No client service started. Trying again in 30 seconds.\n"
5870#~ msgstr "Kein Client Dienst gestartet. Erneuter Versuch in 30 Sekunden.\n"
5871
5872#~ msgid ""
5873#~ "Error (%s) binding the TCP listener to port %d. No proxy service "
5874#~ "started.\n"
5875#~ "Trying again in %d seconds...\n"
5876#~ msgstr ""
5877#~ "Fehler (%s) beim Binden des TCP Listeners an den Port %d. Der Proxy "
5878#~ "Dienst wurde nicht gestartet.\n"
5879#~ "Erneuter Versuch in %d Sekunden...\n"
5880
5881#~ msgid "Rejected unauthorized connection from %u.%u.%u.%u.\n"
5882#~ msgstr "Unauthorisierte Verbindung von %u.%u.%u.%u. wurde abgewiesen.\n"
5883
5884#~ msgid "Protocol violation on socket. Expected command.\n"
5885#~ msgstr "Protokollverletzung auf Socket. Kommando erwartet.\n"
5886
5887#~ msgid "Command `%s' not found!\n"
5888#~ msgstr "Kommando `%s' wurde nicht gefunden!\n"
5889
5890#~ msgid "Start GNUnet testbed controller."
5891#~ msgstr "GNUnet testbed Controller starten."
5892
5893#~ msgid "Malformed entry in the configuration in section %s under %s: %s\n"
5894#~ msgstr ""
5895#~ "Beschädigter Eintrag in der Konfigurationsdatei in Sektion %s unter %s: %"
5896#~ "s\n"
5897
5898#~ msgid "Could not send acknowledgement back to client.\n"
5899#~ msgstr "Bestätigung konnte nicht an Client zurück gesendet werden.\n"
5900
5901#~ msgid "Received unknown testbed message of type %u.\n"
5902#~ msgstr "Es wurde eine unbekannte Testbed Nachricht des Typs %u empfangen.\n"
5903
5904#~ msgid "size of `%s' message is too short. Ignoring.\n"
5905#~ msgstr "Größe der `%s' Nachricht ist zu kurz. Nachricht wird ignoriert.\n"
5906
5907#~ msgid "size of `%s' message is wrong. Ignoring.\n"
5908#~ msgstr "Größe der `%s' Nachricht ist falsch. Nachricht wird ignoriert.\n"
5909
5910#~ msgid "TESTBED could not generate hello message for protocol %u\n"
5911#~ msgstr ""
5912#~ "Das TESTBED konnte keine Hello Nachricht für das Protokoll %u erzeugen\n"
5913
5914#~ msgid "received invalid `%s' message\n"
5915#~ msgstr "ungültige `%s' Nachricht empfangen\n"
5916
5917#~ msgid "received invalid `%s' message (empty module name)\n"
5918#~ msgstr "ungültige `%s' Nachricht empfangen (leerer Modulname)\n"
5919
5920#~ msgid "loading module `%s' failed. Notifying client.\n"
5921#~ msgstr "das Laden von Modul `%s' schlug fehl. Client wird benachrichtigt.\n"
5922
5923#~ msgid "unloading module failed. Notifying client.\n"
5924#~ msgstr "das Entladen des Moduls schlug fehl. Client wird benachrichtigt.\n"
5925
5926#~ msgid "received invalid `%s' message: %s.\n"
5927#~ msgstr "ungültige `%s' Nachricht empfangen: %s.\n"
5928
5929#~ msgid "'..' is not allowed in file name (%s).\n"
5930#~ msgstr "'..' ist nicht erlaubt in einem Dateinamen (%s).\n"
5931
5932#~ msgid "Empty filename for UPLOAD_FILE message is invalid!\n"
5933#~ msgstr "Leerer Dateiname für UPLOAD_FILE Nachricht ist ungültig!\n"
5934
5935#~ msgid "Filename for UPLOAD_FILE message is not null-terminated (invalid!)\n"
5936#~ msgstr ""
5937#~ "Dateiname für UPLOAD_FILE Nachricht ist nicht Null-terminiert "
5938#~ "(ungültig!)\n"
5939
5940#~ msgid "Invalid message received at %s:%d."
5941#~ msgstr "Ungültige Nachricht empfangen bei %s:%d."
5942
5943#~ msgid "received invalid testbed message of size %u\n"
5944#~ msgstr "ungültige Testbed Nachricht der Größe %u empfangen\n"
5945
5946#~ msgid ""
5947#~ "Received testbed message of type %u but unexpected size %u, expected %u\n"
5948#~ msgstr ""
5949#~ "Empfangene Testbed Nachricht des Typs %u hat die unerwartete Größe %u, es "
5950#~ "wurde %u erwartet\n"
5951
5952#~ msgid "No testbed URL given, not registered.\n"
5953#~ msgstr ""
5954#~ "Keine Testbed URL angegeben, es wurde keine Registrierung vorgenommen.\n"
5955
5956#~ msgid "Could not resolve name of HTTP proxy `%s'.\n"
5957#~ msgstr "Der Name des HTTP Proxies `%s' konnte nicht aufgelöst werden.\n"
5958
5959#~ msgid "Invalid URL `%s' (must begin with `%s')\n"
5960#~ msgstr "Ungültige URL `%s' (muss mit `%s' beginnen)\n"
5961
5962#~ msgid "Malformed http URL: `%s' at `%s'. Testbed-client not registered.\n"
5963#~ msgstr ""
5964#~ "Beschädigte HTTP URL: `%s' bei `%s'. Testbed-Client wurde nicht "
5965#~ "registriert.\n"
5966
5967#~ msgid "Could not register testbed, host `%s' unknown\n"
5968#~ msgstr ""
5969#~ "Testbed konnte nicht registriert werden, Host `%s' ist nicht bekannt.\n"
5970
5971#~ msgid "Failed to send HTTP request to host `%s': %s\n"
5972#~ msgstr "HTTP Anfrage konnte nicht an Host `%s' gesendet werden: %s\n"
5973
5974#~ msgid "Failed so send HTTP request `%s' to host `%s': %s\n"
5975#~ msgstr "Fehler beim Senden der HTTP Anfrage `%s' an Host `%s': %s\n"
5976
5977#~ msgid "Exit register (error: no http response read).\n"
5978#~ msgstr "Abbruch der Registrierung (Fehler: keine HTTP Antwort gelesen).\n"
5979
5980#~ msgid "allows construction of a P2P-testbed (incomplete)"
5981#~ msgstr "Ermöglicht die Konstruktion einer P2P-Testumgebung (inkomplett)"
5982
5983#, fuzzy
5984#~ msgid "Failed to connect to %s:%u in %ds\n"
5985#~ msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n"
5986
5987#, fuzzy
5988#~ msgid "`%s' failed at %s:%d in %s with error: %s\n"
5989#~ msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n"
5990
5991#~ msgid "GNUnet configuration assistant"
5992#~ msgstr "GNUnet Konfigurationsassistent"
5993
5994#, fuzzy
5995#~ msgid ""
5996#~ "Welcome to GNUnet!\n"
5997#~ "\n"
5998#~ "This assistant will ask you a few basic questions in order to configure "
5999#~ "GNUnet.\n"
6000#~ "\n"
6001#~ "Please visit our homepage at\n"
6002#~ "\thttp://gnunet.org\n"
6003#~ "and join our community at\n"
6004#~ "\thttps://gnunet.org/drupal/\n"
6005#~ "\n"
6006#~ "Have a lot of fun,\n"
6007#~ "\n"
6008#~ "The GNUnet team"
6009#~ msgstr ""
6010#~ "Willkommen bei GNUnet!\n"
6011#~ "\n"
6012#~ "Dieser Assistent wird Ihnen einige grundlegende Fragen stellen, um GNUnet "
6013#~ "zu konfigurieren.\n"
6014#~ "\n"
6015#~ "Bitte besuchen Sie unsere Homepage\n"
6016#~ "\thttp://gnunet.org\n"
6017#~ "und schließen Sie sich unserer Community an:\n"
6018#~ "\thttps://gnunet.org/drupal/\n"
6019#~ "\n"
6020#~ "Viel Spaß,\n"
6021#~ "\n"
6022#~ "das GNUnet-Team"
6023
6024#~ msgid "Next"
6025#~ msgstr "Weiter"
6026
6027#~ msgid ""
6028#~ "Enter information about your network connection here.\n"
6029#~ "\n"
6030#~ "The \"Network interface\" is the device that connects your computer to "
6031#~ "the internet. This is usually a modem, an ISDN card or a network card in "
6032#~ "case you are using DSL.\n"
6033#~ "\n"
6034#~ "If your provider always assigns the same IP-Address to you (a \"static\" "
6035#~ "IP-Address), enter it into the \"IP-Address\" field. If your IP-Address "
6036#~ "changes every now and then (\"dynamic\" IP-Address) but there's a "
6037#~ "hostname that always points to your actual IP-Address (\"Dynamic DNS\"), "
6038#~ "you can also enter it here.\n"
6039#~ "If in doubt, leave the field empty. GNUnet will then try to determine "
6040#~ "your IP-Address.\n"
6041#~ "\n"
6042#~ "If you are connected to the internet through another computer doing SNAT, "
6043#~ "a router or a \"hardware firewall\" and other computers on the internet "
6044#~ "cannot connect to this computer, check the last option on this page. "
6045#~ "Leave it unchecked on direct connections through modems, ISDN cards and "
6046#~ "DNAT (also known as \"port forwarding\")."
6047#~ msgstr ""
6048#~ "Geben Sie hier Ihre Netzwerkinformationen ein.\n"
6049#~ "\n"
6050#~ "Das \"Netzwerkgerät\" ist das Gerät, das Ihren Computer mit dem Internet "
6051#~ "verbindet. Dies ist normalerweise ein Modem, eine ISDN-Karte oder eine "
6052#~ "Netzwerkkarte für den Fall, dass Sie DSL benutzen.\n"
6053#~ "\n"
6054#~ "Wenn Ihnen Ihr Provider immer die gleiche IP-Adresse zuweist (eine "
6055#~ "\"statische\" IP-Adresse), geben Sie diese in das \"IP-Adresse\"-Feld "
6056#~ "ein. Wenn Ihre IP-Adresse sich hin und wieder ändert (\"dynamische\" IP-"
6057#~ "Adresse), es jedoch einen Hostnamen gibt, der immer auf Ihre aktuelle IP-"
6058#~ "Adresse zeigt (\"Dynamisches DNS\"), so können Sie ihn auch eingeben.\n"
6059#~ "Im Zweifel lassen Sie das Feld leer. GNUnet wird dann versuchen, die IP-"
6060#~ "Adresse automatisch zu bestimmen.\n"
6061#~ "\n"
6062#~ "Wenn Sie nicht direkt mit dem Internet verbunden sind, sondern dies über "
6063#~ "einen anderen Rechner mit SNAT, einem Router oder einer \"Hardware "
6064#~ "Firewall\" geschieht und andere Computer im Internet keine Verbindung mit "
6065#~ "diesem Computer herstellen können, so aktivieren Sie die letzte Option "
6066#~ "auf dieser Seite. Lassen Sie sie jedoch deaktiviert, wenn Sie eine "
6067#~ "direkte Verbindung über ein Modem, eine ISDN-Karte oder einen anderen "
6068#~ "Rechner mit DNAT (auch bekannt als \"Port forwarding\") zum Internet "
6069#~ "haben."
6070
6071#~ msgid "Computer cannot receive inbound connections (SNAT/Firewall)"
6072#~ msgstr ""
6073#~ "Computer kann keine ankommenden Verbindungen akzeptieren (SNAT/Firewall)"
6074
6075#~ msgid "IP-Address/Hostname:"
6076#~ msgstr "IP-Adresse/Hostname:"
6077
6078#, fuzzy
6079#~ msgid "Network interface:"
6080#~ msgstr "Netzwerkgerät:"
6081
6082#, fuzzy
6083#~ msgid "Network connection"
6084#~ msgstr "GNUnet Konfiguration"
6085
6086#~ msgid ""
6087#~ "You can limit GNUnet's ressource usage here.\n"
6088#~ "\n"
6089#~ "\"Bandwidth limitation\" is how much data may be sent per second. If you "
6090#~ "have a flatrate you can set it to the maximum speed of your internet "
6091#~ "connection.\n"
6092#~ "\n"
6093#~ "The \"Max. CPU usage\" is the percentage of processor time GNUnet is "
6094#~ "allowed to use."
6095#~ msgstr ""
6096#~ "Hier können Sie GNUnet's Ressourcennutzung einschränken.\n"
6097#~ "\n"
6098#~ "\"Bandbreitenbeschränkung\" gibt an, wieviele Daten maximal pro Sekunde "
6099#~ "übetragen werden dürfen. Wenn Sie eine Flatrate haben, können Sie diese "
6100#~ "Werte auf die maximal erreichbare Geschwindigkeit Ihrer "
6101#~ "Internetverbindung setzen.\n"
6102#~ "\n"
6103#~ "Die \"Max. CPU Nutzung\" gibt den Prozentsatz an CPU-Zeit an, den GNUnet "
6104#~ "für sich verwenden darf."
6105
6106#~ msgid "Downstream (Bytes/s):"
6107#~ msgstr "Downstream (Bytes/s):"
6108
6109#~ msgid "Upstream (Bytes/s):"
6110#~ msgstr "Upstream (Bytes/s):"
6111
6112#~ msgid "Bandwidth limitation"
6113#~ msgstr "Bandbreitenbeschränkung"
6114
6115#~ msgid "Use denoted bandwidth for GNUnet"
6116#~ msgstr "Angegebene Bandbreite für GNUnet verwenden"
6117
6118#~ msgid "Share denoted bandwidth with other applications"
6119#~ msgstr "Angegebene Bandbreite mit anderen Anwendungen teilen"
6120
6121#~ msgid "Bandwidth sharing"
6122#~ msgstr "Aufteilung der Bandbreite"
6123
6124#~ msgid "Max. CPU usage (%):"
6125#~ msgstr "Max. CPU Nutzung (%):"
6126
6127#~ msgid "CPU usage"
6128#~ msgstr "CPU Nutzung"
6129
6130#~ msgid "Load limitation"
6131#~ msgstr "Lastbeschränkung"
6132
6133#~ msgid ""
6134#~ "GNUnet is able to store data from other peers in your datastore. This is "
6135#~ "useful if an adversary has access to your inserted content and you need "
6136#~ "to deny that the content is yours. With \"content migration\" on, the "
6137#~ "content could have \"migrated\" over the internet to your node without "
6138#~ "your knowledge.\n"
6139#~ "It also helps to spread popular content over different peers to enhance "
6140#~ "availability.\n"
6141#~ "\n"
6142#~ "The GNUnet datastore contains all data that GNUnet generates (index data, "
6143#~ "inserted and migrated content). Its maximum size can be specified below.\n"
6144#~ "\n"
6145#~ "If you are an experienced user, you may want to tweak your GNUnet "
6146#~ "installation using the enhanced configurator.\n"
6147#~ "\n"
6148#~ "After changing the configuration and/or updating GNUnet, it is sometimes "
6149#~ "required to run gnunet-update to update internal data structures. "
6150#~ "Depending on the changes made, this may take some time."
6151#~ msgstr ""
6152#~ "GNUnet ist in der Lage, Daten von anderen Knoten in Ihrem Datenspeicher "
6153#~ "zu speichern. Das ist nützlich, wenn ein Widersacher Zugriff auf Ihre "
6154#~ "eingefügten Inhalte erlangt und Sie abstreiten müssen, dass diese Daten "
6155#~ "Ihnen gehören. Mit \"Inhaltsmigration\" angeschaltet können die Inhalte "
6156#~ "über das Internet von einem anderen Knoten zu Ihrem Rechner ohne Ihr "
6157#~ "Wissen \"gewandert\" sein.\n"
6158#~ "Außerdem hilft es, beliebte Inhalte über verschiedene Netzteilnehmer zu "
6159#~ "verteilen, um so die Verfügbarkeit zu erhöhen.\n"
6160#~ "\n"
6161#~ "Der GNUnet Datenspeicher enthält alle Daten, die GNUnet erzeugt "
6162#~ "(Indexdaten, eingefügte und migrierte Inhalte). Seine maximale Größe kann "
6163#~ "unten angegeben werden.\n"
6164#~ "\n"
6165#~ "Wenn Sie ein fortgeschrittener Benutzer sind, möchten Sie vielleicht "
6166#~ "weitere Feinjustierungen an GNUnet über den \"erweiterten Konfigurator\" "
6167#~ "vornehmen.\n"
6168#~ "Nachdem die Konfiguration verändert und/oder GNUnet upgedated wurde ist "
6169#~ "es manchmal nötig, gnunet-update auszuführen, um interne Datenstrukturen "
6170#~ "zu aktualisieren. Abhängig von den gemachten Änderungen kann dies etwas "
6171#~ "Zeit in Anspruch nehmen."
6172
6173#~ msgid "Store migrated content"
6174#~ msgstr "Migrierte Inhalte speichern"
6175
6176#~ msgid "Maximum datastore size (MB):"
6177#~ msgstr "Maximale Größe des Datenspeichers (MB):"
6178
6179#~ msgid "Start the GNUnet background process on computer startup"
6180#~ msgstr ""
6181#~ "GNUnet Hintergrundprozeß beim Starten des Computers automatisch starten"
6182
6183#~ msgid "Open the enhanced configurator"
6184#~ msgstr "Erweiterten Konfigurator starten"
6185
6186#, fuzzy
6187#~ msgid "Run gnunet-update"
6188#~ msgstr "gnunet-update schlug fehlt!"
6189
6190#, fuzzy
6191#~ msgid "Other settings"
6192#~ msgstr "Weitere Einstellungen"
6193
6194#~ msgid "Finish"
6195#~ msgstr "Fertigstellen"
6196
6197#~ msgid ""
6198#~ "Define the user and the group owning the GNUnet service here.\n"
6199#~ "\n"
6200#~ "For security reasons, it is a good idea to let this setup create a new "
6201#~ "user account and a new group under which the GNUnet service is started at "
6202#~ "system startup.\n"
6203#~ "\n"
6204#~ "However, GNUnet may not be able to access files other than its own. This "
6205#~ "includes files you want to publish in GNUnet. You'll have to grant read "
6206#~ "permissions to the user specified below.\n"
6207#~ "\n"
6208#~ "Leave the fields empty to run GNUnet with system privileges."
6209#~ msgstr ""
6210#~ "Geben Sie den Benutzer und die Gruppe an, der der GNUnet Dienst gehören "
6211#~ "soll.\n"
6212#~ "\n"
6213#~ "Aus Sicherheitsgründen ist es eine gute Idee, dieses Setup ein neues "
6214#~ "Benutzerkonto und eine neue Gruppe anlegen zu lassen, unter der der "
6215#~ "GNUnet Dienst beim Systemstart läuft.\n"
6216#~ "\n"
6217#~ "Natürlich kann GNUnet dann nur auf seine eigenen Dateien zugreifen. Dies "
6218#~ "betrifft auch Dateien, die Sie im GNUnet veröffentlichen möchten. Sie "
6219#~ "müssen dann dem unten angegebenen Benutzerkonto zuerst Leseberechtigungen "
6220#~ "geben.\n"
6221#~ "\n"
6222#~ "Lassen Sie dieses Feld leer, wenn Sie GNUnet mit Systemprivilegien laufen "
6223#~ "lassen möchten."
6224
6225#~ msgid "User account:"
6226#~ msgstr "Benutzerkonto:"
6227
6228#~ msgid "Group:"
6229#~ msgstr "Gruppe:"
6230
6231#, fuzzy
6232#~ msgid "gnunet-setup"
6233#~ msgstr "gnunet-update ausführen"
6234
6235#, fuzzy
6236#~ msgid "Save configuration"
6237#~ msgstr "GNUnet Konfiguration"
6238
6239#, fuzzy
6240#~ msgid "Show copyright information for gnunet-setup."
6241#~ msgstr "Fehler beim Lesen von Informationen von gnunetd.\n"
6242
6243#, fuzzy
6244#~ msgid "About gnunet-setup"
6245#~ msgstr "gnunet-update ausführen"
6246
6247#, fuzzy
6248#~ msgid "This is the configuration tool for GNUnet."
6249#~ msgstr ""
6250#~ "Einen Wert aus der Konfigurationsdatei auf der Standardausgabe ausgeben"
6251
6252#~ msgid "Not for English ;-)"
6253#~ msgstr "Nils Durner and Christian Grothoff"
6254
6255#, fuzzy
6256#~ msgid "Description"
6257#~ msgstr "Frage"
6258
6259#, fuzzy
6260#~ msgid "Section"
6261#~ msgstr "Frage"
6262
6263#, fuzzy
6264#~ msgid "Option"
6265#~ msgstr "_Optionen"
6266
6267#~ msgid "Received invalid `%s' message from `%s'.\n"
6268#~ msgstr "Ungültige `%s' Anfrage von `%s' empfangen.\n"
6269
6270#~ msgid "TRACEKIT: routing table full, trace request dropped\n"
6271#~ msgstr "TRACEKIT: Routing-Tabelle ist voll, Trace-Anfrage wird verworfen\n"
6272
6273#~ msgid "TRACEKIT: received invalid `%s' message\n"
6274#~ msgstr "TRACEKIT: ungültige `%s' Nachricht empfangen\n"
6275
6276#~ msgid "Format specification invalid. Use 0 for user-readable, 1 for dot\n"
6277#~ msgstr ""
6278#~ "Formatangabe ungültig. Verwenden Sie 0 für menschen-lesbar und 1 für dot\n"
6279
6280#~ msgid "Peer `%s' did not report back.\n"
6281#~ msgstr "Knoten `%s' hat sich nicht zurückgemeldet.\n"
6282
6283#~ msgid "Could not send request to gnunetd.\n"
6284#~ msgstr "Anfrage konnte nicht an gnunetd gesendet werden.\n"
6285
6286#~ msgid ""
6287#~ "You must specify the name of a pipe for the SMTP transport in section `%"
6288#~ "s' under `%s'.\n"
6289#~ msgstr ""
6290#~ "Für den SMTP Transport müssen Sie den Namen einer Pipe in Sektion `%s', "
6291#~ "Eintrag `%s' eintragen.\n"
6292
6293#, fuzzy
6294#~ msgid "Failed to initialize libesmtp: %s.\n"
6295#~ msgstr "SQLite Datenbank konnte nicht initialisiert werden.\n"
6296
6297#~ msgid "Sending E-mail to `%s' failed.\n"
6298#~ msgstr "Das Senden einer E-Mail an `%s' schlug fehl.\n"
6299
6300#~ msgid "%.*s filter %s (SMTP)"
6301#~ msgstr "%.*s filter %s (SMTP)"
6302
6303#~ msgid "MTU for `%s' is probably too low (fragmentation not implemented!)\n"
6304#~ msgstr ""
6305#~ "MTU für `%s' ist möglicherweise zu gering (Fragmentierung ist nicht "
6306#~ "implementiert!)\n"
6307
6308#, fuzzy
6309#~ msgid "Network configuration: NAT"
6310#~ msgstr "GNUnet Konfiguration"
6311
6312#~ msgid ""
6313#~ "Is this machine behind NAT?\n"
6314#~ "\n"
6315#~ "If you are connected to the internet through another computer doing SNAT, "
6316#~ "a router or a \"hardware firewall\" and other computers on the internet "
6317#~ "cannot connect to this computer, say \"yes\" here. Answer \"no\" on "
6318#~ "direct connections through modems, ISDN cards and DNAT (also known as "
6319#~ "\"port forwarding\")."
6320#~ msgstr ""
6321#~ "Ist diese Maschine hinter NAT?\n"
6322#~ "\n"
6323#~ "Wenn Sie mit dem Internet über einen anderen Computer per SNAT, einem "
6324#~ "Router oder einer \"Hardware Firewall\" verbunden sind und andere "
6325#~ "Computer im Internet keine Verbindung zu diesem Computer herstellen "
6326#~ "können, so sagen Sie hier \"Ja\". Antworten Sie \"Nein\" bei direkten "
6327#~ "Verbindungen über Modem, ISDN-Karten und DNAT (auch bekannt als \"Port "
6328#~ "forwarding\")."
6329
6330#, fuzzy
6331#~ msgid "Configuration of the logging system"
6332#~ msgstr ""
6333#~ "Konfiguration oder die GNUnet Version hat sich geändert. Sie müssen `%s' "
6334#~ "ausführen!\n"
6335
6336#, fuzzy
6337#~ msgid "Run gnunetd as this user."
6338#~ msgstr "gnunet-update ausführen"
6339
6340#, fuzzy
6341#~ msgid "Run gnunetd during system startup?"
6342#~ msgstr "gnunet-update ausführen"
6343
6344#, fuzzy
6345#~ msgid "Path settings"
6346#~ msgstr "Weitere Einstellungen"
6347
6348#~ msgid "specify nickname"
6349#~ msgstr "Spitznamen angeben"
6350
6351#~ msgid "Start GNUnet chat client."
6352#~ msgstr "GNUnet chat client starten"
6353
6354#~ msgid "Could not connect to gnunetd.\n"
6355#~ msgstr "Verbindung zu gnunetd konnte nicht hergestellt werden.\n"
6356
6357#~ msgid "You must specify a nickname (use option `%s').\n"
6358#~ msgstr ""
6359#~ "Sie müssen einen Spitznamen angeben (verwenden Sie die Option `%s').\n"
6360
6361#~ msgid "Could not send join message to gnunetd\n"
6362#~ msgstr "'join' Nachricht konnte nicht an gnunetd gesendet werden.\n"
6363
6364#~ msgid "Could not send message to gnunetd\n"
6365#~ msgstr "Nachricht konnte nicht an gnunetd gesendet werden.\n"
6366
6367#~ msgid "mysql datastore"
6368#~ msgstr "mysql Datenspeicher"
6369
6370#, fuzzy
6371#~ msgid ""
6372#~ "`%s' failed at %s:%d with error: I/%s S/%s SC/%s SS/%s SSC/%s U/%s D/%s "
6373#~ "DG/%s\n"
6374#~ msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n"
6375
6376#~ msgid "Database failed to delete `%s'.\n"
6377#~ msgstr "Die Datenbank konnte `%s' nicht löschen.\n"
6378
6379#, fuzzy
6380#~ msgid "Error log:\n"
6381#~ msgstr "Fehler"
6382
6383#, fuzzy
6384#~ msgid "# bytes received via TCP-OLD"
6385#~ msgstr "# Bytes empfangen über TCP"
6386
6387#, fuzzy
6388#~ msgid "# bytes sent via TCP-OLD"
6389#~ msgstr "# Bytes gesendet über TCP"
6390
6391#, fuzzy
6392#~ msgid "# bytes dropped by TCP-OLD (outgoing)"
6393#~ msgstr "# Bytes verworfen von TCP (ausgehend)"
6394
6395#~ msgid "hello advertisement for protocol %d received.\n"
6396#~ msgstr "Hello Ankündigung für Protokoll %d empfangen.\n"
6397
6398#~ msgid "`%s' failed (%d, %u). Will not send PING.\n"
6399#~ msgstr "`%s' fehlgeschlagen (%d, %u). PING wird nicht gesendet.\n"
6400
6401#~ msgid "Removing hello from peer `%s' (expired %ds ago).\n"
6402#~ msgstr "Hello von Knoten `%s' wird entfernt (lief vor %ds ab).\n"
6403
6404#~ msgid "No reply received within %llums.\n"
6405#~ msgstr "Keine Antwort innerhalb %llums erhalten.\n"
6406
6407#~ msgid "Waiting for gnunetd to start (%u iterations left)...\n"
6408#~ msgstr "Warte auf den Start von gnunetd (%u Iterationen verbleiben)...\n"
6409
6410#, fuzzy
6411#~ msgid "Deleting expired content. This may take a while.\n"
6412#~ msgstr "Ein neuer Hostkey wird erzeugt (dies kann eine Weile dauern).\n"
6413
6414#~ msgid "User `%s' not known, cannot change UID to it.\n"
6415#~ msgstr ""
6416#~ "Benutzer `%s' ist nicht bekannt, UID kann nicht gewechselt werden.\n"
6417
6418#~ msgid ""
6419#~ "Expected welcome on http connection, got garbage. Closing connection.\n"
6420#~ msgstr ""
6421#~ "Es wurde eine Willkommensnachricht erwartet, tatsächlich wurde jedoch "
6422#~ "keine gesendet. HTTP-Verbindung wird geschlossen.\n"
6423
6424#~ msgid "%s: Rejected connection from blacklisted address %u.%u.%u.%u.\n"
6425#~ msgstr ""
6426#~ "%s: Abgewiesene Verbindung von schwarzgelisteter Adresse %u.%u.%u.%u.\n"
6427
6428#~ msgid ""
6429#~ "Could not bind the HTTP listener to port %d. No transport service "
6430#~ "started.\n"
6431#~ msgstr ""
6432#~ "HTTP-Listener konnte nicht an Port %d gebunden werden. Der Transport "
6433#~ "Dienst wurde nicht gestartet.\n"
6434
6435#~ msgid "Could not determine my public IP address.\n"
6436#~ msgstr "Öffentliche IP-Adresse konnte nicht ermittelt werden.\n"
6437
6438#~ msgid "Unexpected reply to `%s' operation.\n"
6439#~ msgstr "Unerwartete Antwort zu `%s' Operation.\n"
6440
6441#~ msgid "join table called NAME"
6442#~ msgstr "Tabelle NAME anschließen"
6443
6444#~ msgid "Malformed optional field `%s' received from peer `%s'.\n"
6445#~ msgstr "Ungültiges optionales Feld `%s' empfangen von Knoten `%s'.\n"
6446
6447#~ msgid "Could not find peer `%s' in routing table!\n"
6448#~ msgstr "Knoten `%s' konnte nicht in der Routing Tabelle gefunden werden!\n"
6449
6450#~ msgid "Received malformed response to `%s' from peer `%s'.\n"
6451#~ msgstr "Beschädigte Antwort auf `%s' von Knoten `%s' empfangen.\n"
6452
6453#~ msgid "Invalid response to `%s'.\n"
6454#~ msgstr "Ungültige Antwort auf `%s'.\n"
6455
6456#~ msgid "Malformed response to `%s' on master table.\n"
6457#~ msgstr "Beschädigte Antwort auf `%s' in Master Tabelle.\n"
6458
6459#~ msgid "Invalid response to `%s' from `%s'\n"
6460#~ msgstr "Ungültige Antwort auf `%s' von `%s'\n"
6461
6462#~ msgid "Received invalid RPC `%s'.\n"
6463#~ msgstr "Ungültiger RPC `%s' empfangen.\n"
6464
6465#~ msgid "RPC for `%s' received for table that we do not participate in!\n"
6466#~ msgstr ""
6467#~ "RPC für `%s' empfangen für eine Tabelle, an der wir nicht beteiligt "
6468#~ "sind!\n"
6469
6470#~ msgid "`%s' failed. Terminating connection to client.\n"
6471#~ msgstr "`%s' fehlgeschlagen. Beende Verbindung zu Client.\n"
6472
6473#~ msgid ""
6474#~ "`%s' called with cron job not in queue, adding. This may not be what you "
6475#~ "want.\n"
6476#~ msgstr ""
6477#~ "`%s' aufgerufen wobei Cron Job nicht Warteschlange ist. Er wird "
6478#~ "hinzugefügt. Das ist möglicherweise nicht, was Sie wollen.\n"
6479
6480#~ msgid ""
6481#~ "Share denoted bandwidth with other applications?\n"
6482#~ "\n"
6483#~ "Say \"yes\" here, if you don't want other network traffic to interfere "
6484#~ "with GNUnet's operation, but still wish to constrain GNUnet's bandwidth "
6485#~ "usage to values entered in the previous steps, or if you can't reliably "
6486#~ "measure the maximum capabilities of your connection. \"No\" can be very "
6487#~ "useful if other applications are causing a lot of traffic on your LAN. "
6488#~ "In this case, you do not want to limit the traffic that GNUnet can "
6489#~ "inflict on your internet connection whenever your high-speed LAN gets "
6490#~ "used (e.g. by NFS)."
6491#~ msgstr ""
6492#~ "Angegebene Bandbreite mit anderen Anwendungen teilen?\n"
6493#~ "\n"
6494#~ "Sagen Sie hier \"Ja\", wenn Sie nicht möchten, dass anderer "
6495#~ "Netzwerkverkehr GNUnets Funktion stört aber dennoch GNUnets Bandbreite "
6496#~ "gemäß den Angaben in den vorherigen Schritten einschränken möchten oder "
6497#~ "Sie die maximalen Möglichkeiten Ihrer Internetverbindung nicht "
6498#~ "zuverlässig messen können. \"Nein\" kann nützlich sein, wenn andere "
6499#~ "Anwendungen viel Netzwerkverkehr in Ihrem LAN verursachen. In diesem Fall "
6500#~ "möchten Sie nicht GNUnets Netzwerkverkehr über die Internetverbindung "
6501#~ "einschränken, wann immer Ihre Hochgeschwindigkeits-LAN-Verbindung "
6502#~ "verwendet wird (z.B. durch NFS)."
6503
6504#~ msgid "How much CPU (in %) may be used?"
6505#~ msgstr "Wieviel CPU (in %) darf verwendet werden?"
6506
6507#~ msgid ""
6508#~ "You can limit GNUnet's resource usage here.\n"
6509#~ "\n"
6510#~ "This is the percentage of processor time GNUnet is allowed to use."
6511#~ msgstr ""
6512#~ "Hier können Sie GNUnets Ressourcenverwendung einschränken.\n"
6513#~ "\n"
6514#~ "Dies ist der Prozentsatz an Prozessorzeit, den GNUnet verwenden darf."
6515
6516#~ msgid ""
6517#~ "Store migrated content?\n"
6518#~ "\n"
6519#~ "GNUnet is able to store data from other peers in your datastore. This is "
6520#~ "useful if an adversary has access to your inserted content and you need "
6521#~ "to deny that the content is yours. With \"content migration\" on, the "
6522#~ "content could have \"migrated\" over the internet to your node without "
6523#~ "your knowledge.\n"
6524#~ "It also helps to spread popular content over different peers to enhance "
6525#~ "availability."
6526#~ msgstr ""
6527#~ "Sollen migrierte Inhalte gespeichert werden?\n"
6528#~ "GNUnet ist in der Lage, Daten von anderen Knoten in Ihrem Datenspeicher "
6529#~ "zu speichern. Das ist nützlich, wenn ein Widersacher Zugriff auf Ihre "
6530#~ "eingefügten Inhalte erlangt und Sie abstreiten müssen, dass diese Daten "
6531#~ "Ihnen gehören. Ist die \"Inhaltsmigration\" angeschaltet, so können die "
6532#~ "Inhalte über das Internet von einem anderen Knoten zu Ihrem Rechner ohne "
6533#~ "Ihr Wissen \"gewandert\" sein.\n"
6534#~ "Außerdem hilft es, beliebte Inhalte über verschiedene Netzteilnehmer zu "
6535#~ "verteilen, um so die Verfügbarkeit zu erhöhen."
6536
6537#~ msgid ""
6538#~ "If you are an experienced user, you may want to tweak your GNUnet "
6539#~ "installation using the enhanced configurator.\n"
6540#~ "\n"
6541#~ "Do you want to start it after saving your configuration?"
6542#~ msgstr ""
6543#~ "Wenn Sie ein erfahrener Benutzer sind, so möchten Sie vielleicht Ihre "
6544#~ "GNUnet Installation über den erweiterten Konfigurator optimieren.\n"
6545#~ "\n"
6546#~ "Möchten Sie ihn starten, nachdem Ihre Konfiguration gespeichert wurde?"
6547
6548#~ msgid ""
6549#~ "Unable to save configuration file %s: %s.\n"
6550#~ "\n"
6551#~ "Try again?"
6552#~ msgstr ""
6553#~ "Konfigurationsdatei %s kann nicht gespeichert werden: %s.\n"
6554#~ "\n"
6555#~ "Soll es nochmals versucht werden?"
6556
6557#~ msgid "Failed to send `%s'. Closing connection.\n"
6558#~ msgstr "Fehler beim Senden von `%s'. Verbindung wird geschlossen.\n"
6559
6560#~ msgid "Received invalid `%s' request (size %d)\n"
6561#~ msgstr "Ungültige Anfrage `%s' empfangen (Größe %d)\n"
6562
6563#~ msgid "Received invalid `%s' request (wrong table)\n"
6564#~ msgstr "Ungültige Anfrage `%s' empfangen (falsche Tabelle)\n"
6565
6566#~ msgid "Received unknown request type %d at %s:%d\n"
6567#~ msgstr "Unbekannte Anfrageart %d empfangen bei %s:%d\n"
6568
6569#~ msgid "This client already participates in the given DHT!\n"
6570#~ msgstr "Dieser Client beteiligt sich bereits an der angegebenen DHT!\n"
6571
6572#~ msgid "Cannot leave DHT: table not known!\n"
6573#~ msgstr "DHT kann nicht verlassen werden: Tabelle unbekannt!\n"
6574
6575#~ msgid "gnunetd signaled error in response to `%s' message\n"
6576#~ msgstr "gnunetd gab in Bezug auf die `%s' Nachricht einen Fehler zurück.\n"
6577
6578#~ msgid "Failed to receive response to `%s' message from gnunetd\n"
6579#~ msgstr ""
6580#~ "Fehler beim Empfangen der Antwort von gnunetd auf die `%s' Nachricht\n"
6581
6582#~ msgid "Failed to send `%s' message to gnunetd\n"
6583#~ msgstr "Fehler beim Senden der `%s' Nachricht an gnunetd\n"
6584
6585#~ msgid "Join a DHT."
6586#~ msgstr "Einer DHT anschließen."
6587
6588#~ msgid "allow SIZE bytes of memory for the local table"
6589#~ msgstr "SIZE bytes an Speicher für die lokale Tabelle erlauben"
6590
6591#~ msgid "Call to `%s' returns %d.\n"
6592#~ msgstr "Aufruf von `%s' gibt %d zurück.\n"
6593
6594#~ msgid "Call to `%s' with key `%s'.\n"
6595#~ msgstr "Aufruf von `%s' mit Schlüssel `%s'.\n"
6596
6597#~ msgid "Call to `%s' with value '%.*s' (%d bytes).\n"
6598#~ msgstr "Aufruf von `%s' mit Wert '%.*s' (%d Bytes).\n"
6599
6600#~ msgid "Error joining DHT.\n"
6601#~ msgstr "Fehler beim Beitreten zu der DHT.\n"
6602
6603#~ msgid "Joined DHT. Press CTRL-C to leave.\n"
6604#~ msgstr "Der DHT beigetreten. Drücken Sie STRG-C, um sie zu verlassen.\n"
6605
6606#~ msgid "Error leaving DHT.\n"
6607#~ msgstr "Fehler beim Verlassen der DHT.\n"
6608
6609#~ msgid "`%s' failed: table not found!\n"
6610#~ msgstr "`%s' fehlgeschlagen: Tabelle nicht gefunden!\n"
6611
6612#~ msgid "sendAck failed. Terminating connection to client.\n"
6613#~ msgstr "sendAck fehlgeschlagen. Beende Verbindung zu Client.\n"
6614
6615#~ msgid "Unindex failed."
6616#~ msgstr "Deindizierung schlug fehl."
6617
6618#, fuzzy
6619#~ msgid "Upload failed (consult logs)."
6620#~ msgstr "ECRS Download schlug fehl (siehe Protokolldateien)."
6621
6622#~ msgid "Could not resolve name of SMTP server `%s': %s"
6623#~ msgstr "Der Name des SMTP servers `%s' konnte nicht aufgelöst werden: %s"
6624
6625#~ msgid "SMTP server send unexpected response at %s:%d.\n"
6626#~ msgstr "Der SMTP server sendete eine unerwartete Antwort bei %s:%d.\n"
6627
6628#~ msgid ""
6629#~ "SMTP server failed to respond with 250 confirmation code to `%s' "
6630#~ "request.\n"
6631#~ msgstr ""
6632#~ "SMTP Server antwortete nicht mit einem 250 Bestätigungscode auf eine `%s' "
6633#~ "Anfrage.\n"
6634
6635#~ msgid "Failed to send `%s' request to SMTP server.\n"
6636#~ msgstr "Fehler beim Senden einer `%s' Anfrage an den SMTP Server.\n"
6637
6638#~ msgid "query table called NAME"
6639#~ msgstr "Frage Tabelle mit dem Namen NAME ab"
6640
6641#~ msgid "No commands specified.\n"
6642#~ msgstr "Keine Kommandos angegeben.\n"
6643
6644#~ msgid "Superflous arguments (ignored).\n"
6645#~ msgstr "überflüssige Parameter (werden ignoriert).\n"
6646
6647#~ msgid "Query `%s' had no results.\n"
6648#~ msgstr "Abfrage `%s' hatte keine Ergebnisse.\n"
6649
6650#~ msgid "FSUI persistence: error restoring download\n"
6651#~ msgstr "FSUI Beständigkeit: Fehler beim Wiederherstellen des Downloads\n"
6652
6653#~ msgid "ECRS download suspending."
6654#~ msgstr "ECRS download wird eingefroren."
6655
6656#~ msgid "Upload failed."
6657#~ msgstr "Upload fehlgeschlagen."
6658
6659#~ msgid "Cannot upload directory without using recursion."
6660#~ msgstr ""
6661#~ "Verzeichnis kann nicht ohne die Verwendung von Rekursion hochgeladen "
6662#~ "werden."
6663
6664#, fuzzy
6665#~ msgid "Expected `%s' to be a regular file\n"
6666#~ msgstr "`%s' ist keine normale Datei.\n"
6667
6668#, fuzzy
6669#~ msgid "expected `%s' to be a directory!\n"
6670#~ msgstr "`%s' erwartet, dass `%s' ein Verzeichnis ist!\n"
6671
6672#~ msgid "Sorry, no help is available for this option.\n"
6673#~ msgstr "Sorry, für diese Option steht keine Hilfe zur Verfügung.\n"
6674
6675#~ msgid "Failed to obtain my (external) IPv6 address!\n"
6676#~ msgstr "Die öffentliche IPv6-Adresse konnte nicht ermittelt werden!\n"
6677
6678#~ msgid ""
6679#~ "Cannot determine port to bind to. Define in configuration file in "
6680#~ "section `%s' under `%s' or in `%s' under %s/%s.\n"
6681#~ msgstr ""
6682#~ "Der Port, an dem Verbindungen entgegengenommen werden sollen, konnte "
6683#~ "nicht ermittelt werden. Bitte definieren Sie ihn in der "
6684#~ "Konfigurationsdatei in der Sektion `%s' unter `%s' oder in `%s' unter %s/%"
6685#~ "s.\n"
6686
6687#~ msgid "Failed to bind to UDP6 port %d.\n"
6688#~ msgstr "Fehler beim Binden an UDP6 Port %d.\n"
6689
6690#, fuzzy
6691#~ msgid "UDP6: select returned, but ioctl reports %d bytes available!\n"
6692#~ msgstr ""
6693#~ "UDP: select kam zurück aber ioctl berichtet, dass 0 Bytes verfügbar "
6694#~ "sind!\n"
6695
6696#~ msgid "Received invalid UDP6 message from %s:%d, dropping.\n"
6697#~ msgstr ""
6698#~ "Ungültige UDP6 Nachricht von %s:%d empfangen, Nachricht wird ignoriert.\n"
6699
6700#~ msgid "Packet received from %s:%d (UDP6) failed format check."
6701#~ msgstr ""
6702#~ "Die Formatüberprüfung des Pakets, das von %s:%d (UDP6) empfangen wurde, "
6703#~ "schlug fehl."
6704
6705#~ msgid "%s: Rejected connection from blacklisted address %s.\n"
6706#~ msgstr "%s: Zurückgewiesene Verbindung von schwarzgelisteter Adresse %s.\n"
6707
6708#~ msgid ""
6709#~ "Expected welcome message on tcp connection, got garbage (%u, %u). "
6710#~ "Closing.\n"
6711#~ msgstr ""
6712#~ "Es wurde eine Willkommensnachricht erwartet, über die TCP Verbindung "
6713#~ "wurde aber keine gesendet (%u, %u). Verbindung wird geschlossen.\n"
6714
6715#, fuzzy
6716#~ msgid "UDP: select returned, but ioctl reports %d bytes available!\n"
6717#~ msgstr ""
6718#~ "UDP: select kam zurück aber ioctl berichtet, dass 0 Bytes verfügbar "
6719#~ "sind!\n"
6720
6721#~ msgid "Received invalid UDP message from %u.%u.%u.%u:%u, dropping.\n"
6722#~ msgstr ""
6723#~ "Es wurde eine ungültige UDP Nachricht von %u.%u.%u.%u:%u empfangen, "
6724#~ "Nachricht wird ignoriert.\n"
6725
6726#~ msgid "Packet received from %u.%u.%u.%u:%u (UDP) failed format check.\n"
6727#~ msgstr ""
6728#~ "Ein Paket empfangen von %u.%u.%u.%u:%u (UDP) hat ein ungültiges Format.\n"
6729
6730#~ msgid "Expected welcome message on tcp connection, got garbage. Closing.\n"
6731#~ msgstr ""
6732#~ "Es wurde eine Willkommensnachricht erwartet, über die TCP Verbindung "
6733#~ "wurde jedoch keine gesendet. Verbindung wird geschlossen.\n"
6734
6735#~ msgid ""
6736#~ "Received malformed message from tcp6-peer connection. Closing "
6737#~ "connection.\n"
6738#~ msgstr ""
6739#~ "über die TCP6-Verbindung zu einem anderen Knoten wurde eine ungültige "
6740#~ "Nachricht empfangen. Verbindung wird geschlossen.\n"
6741
6742#~ msgid "Network advertisements disabled by configuration!\n"
6743#~ msgstr "Netzwerkbekanntmachungen wurden per Konfiguration deaktiviert!\n"
6744
6745#~ msgid "Version mismatch (`%s' vs. '%*.s'), run gnunet-update!\n"
6746#~ msgstr ""
6747#~ "Versionen stimmen nicht überein (`%s' vs. '%*.s'), lassen Sie gnunet-"
6748#~ "update laufen!\n"
6749
6750#~ msgid ""
6751#~ "Configuration file must specify directory for storing FS data in section `"
6752#~ "%s' under `%s'.\n"
6753#~ msgstr ""
6754#~ "Die Konfigurationsdatei muss in der Sektion `%s' unter `%s' ein "
6755#~ "Verzeichnis angeben, in dem FS Daten gespeichert werden.\n"
6756
6757#~ msgid "Could not initialize libgnunetutil!\n"
6758#~ msgstr "Konnte libgnunetutil nicht initialisieren!\n"
6759
6760#~ msgid ""
6761#~ "Configuration file must specify a directory for GNUnet to store per-peer "
6762#~ "data under %s%s\n"
6763#~ msgstr ""
6764#~ "Die Konfigurationsdatei muss unter %s%s ein Verzeichnis angeben, in dem "
6765#~ "GNUnet knotenspezifische Daten speichern kann.\n"
6766
6767#~ msgid "%s `%s' returned no known hosts!\n"
6768#~ msgstr "%s `%s' ergab keine bekannten Knoten!\n"
6769
6770#~ msgid ""
6771#~ "Option `%s' not set in configuration in section `%s', setting to %dm.\n"
6772#~ msgstr ""
6773#~ "Option `%s' ist in der Konfigurationsdatei in der Sektion `%s' nicht "
6774#~ "gesetzt, sie wird auf %dm gesetzt.\n"
6775
6776#~ msgid ""
6777#~ "You should specify at least one transport service under option `%s' in "
6778#~ "section `%s'.\n"
6779#~ msgstr ""
6780#~ "Sie sollten mindestens einen Transport Dienst unter der Option `%s' in "
6781#~ "der Sektion `%s' angegeben.\n"
6782
6783#~ msgid ""
6784#~ "specify that the contents of the namespace are of the given MIMETYPE (use "
6785#~ "when creating a new pseudonym)"
6786#~ msgstr ""
6787#~ "Angeben, dass die Inhalte des Namespaces vom angegebenen MIMETYOE sind "
6788#~ "(zu verwenden, wenn ein neues Pseudonym erstellt wird)"
6789
6790#~ msgid ""
6791#~ "specify NAME to be the realname of the user controlling the namespace "
6792#~ "(use when creating a new pseudonym)"
6793#~ msgstr ""
6794#~ "NAME als den Realnamen des Benutzers angeben, der den Namespace verwaltet "
6795#~ "(zu verwenden, wenn ein neues Pseudonym erstellt wird)"
6796
6797#~ msgid ""
6798#~ "use DESCRIPTION to describe the content of the namespace (use when "
6799#~ "creating a new pseudonym)"
6800#~ msgstr ""
6801#~ "DESCRIPTION als Beschreibung der Inhalte des Namespaces verwenden (zu "
6802#~ "verwenden, wenn ein neues Pseudonym erstellt wird)"
6803
6804#~ msgid ""
6805#~ "specify the given URI as an address that contains more information about "
6806#~ "the namespace (use when creating a new pseudonym)"
6807#~ msgstr ""
6808#~ "die angegebene URI als die Adresse angeben, die weitere Informationen "
6809#~ "über den Namespace enthält (zu verwenden, wenn ein neues Pseudonym "
6810#~ "erstellt wird)"
6811
6812#~ msgid "Invalid argument: `%s'\n"
6813#~ msgstr "Ungültiger Parameter: `%s'\n"
6814
6815#~ msgid "Invalid arguments. Exiting.\n"
6816#~ msgstr "Ungültige Parameter. Abbruch.\n"
6817
6818#~ msgid "%8u of %8u bytes deleted."
6819#~ msgstr "%8u von %8u Bytes gelöscht."
6820
6821#~ msgid "specify the file to delete from GNUnet (obligatory, file must exist)"
6822#~ msgstr ""
6823#~ "vom GNUnet zu löschende Datei angeben (obgligatorisch, Datei muss "
6824#~ "existieren)"
6825
6826#~ msgid ""
6827#~ "Remove file from GNUnet. The specified file is not removed\n"
6828#~ "from the filesystem but just from the local GNUnet datastore."
6829#~ msgstr ""
6830#~ "Datei auf GNUnet löschen. Die angegebene Datei wird nicht aus dem "
6831#~ "Dateisystem gelöscht, sondern aus dem lokalen GNUnet Datenspeicher."
6832
6833#~ msgid "You must specify a filename (option -f)\n"
6834#~ msgstr "Sie müssen eine Datei angeben (Option -f)\n"
6835
6836#~ msgid ""
6837#~ "Error deleting file %s.\n"
6838#~ "Probably a few blocks were already missing from the database.\n"
6839#~ msgstr ""
6840#~ "Fehler beim Löschen der Datei %s.\n"
6841#~ "Möglicherweise fehlen bereits einige wenige Datenblöcke in der "
6842#~ "Datenbank.\n"
6843
6844#~ msgid "gnunet-directory [OPTIONS] [FILENAMES]"
6845#~ msgstr "gnunet-directory [OPTIONEN] [DATEINAMEN]"
6846
6847#~ msgid "process directories recursively"
6848#~ msgstr "Verzeichnisse rekursiv bearbeiten"
6849
6850#~ msgid "You must pass a positive number to the `%s' option.\n"
6851#~ msgstr "Sie müssen eine positive Zahl zu der Option `%s' übergeben.\n"
6852
6853#~ msgid "You must specify a list of files to insert.\n"
6854#~ msgstr "Sie müssen eine Liste von Dateien zum Einfügen angeben.\n"
6855
6856#~ msgid "Only one file or directory can be specified at a time.\n"
6857#~ msgstr "Nur eine Datei oder Verzeichnis kann auf einmal angegeben werden.\n"
6858
6859#~ msgid "You must specify a file or directory to upload.\n"
6860#~ msgstr "Sie müssen eine Datei oder Verzeichnis für den Upload angeben.\n"
6861
6862#~ msgid "set the desired LEVEL of receiver-anonymity"
6863#~ msgstr "Den Grad LEVEL der gewünschten Empfänger-Anonymität setzen"
6864
6865#~ msgid "Not enough arguments. You must specify a keyword or identifier.\n"
6866#~ msgstr ""
6867#~ "Nicht genügend Parameter. Sie müssen ein Schlüsselwort oder einen "
6868#~ "Bezeichner angeben.\n"
6869
6870#~ msgid "LEVEL"
6871#~ msgstr "GRAD"
6872
6873#~ msgid "FILENAME"
6874#~ msgstr "DATEINAME"
6875
6876#~ msgid "This search is already pending!\n"
6877#~ msgstr "Diese Suche läuft bereits!\n"
6878
6879#~ msgid ""
6880#~ "Configuration file must specify a directory for GNUnet to store per-peer "
6881#~ "data under %s%s.\n"
6882#~ msgstr ""
6883#~ "Die Konfigurationsdatei muss unter %s%s ein Verzeichnis für GNUnet "
6884#~ "angeben, in dem Knotenbezogene Daten gespeichert werden.\n"
6885
6886#~ msgid ""
6887#~ "Need to have list of friends in configuration under `%s' in section `%"
6888#~ "s'.\n"
6889#~ msgstr ""
6890#~ "Es muss eine Liste von Freunden in der Konfigurationsdatei unter `%s' in "
6891#~ "der Sektion `%s' angegeben werden.\n"
6892
6893#~ msgid "helptext for -t"
6894#~ msgstr "Hilfetext für -t"
6895
6896#~ msgid "Template for gnunet-clients."
6897#~ msgstr "Vorlage für gnunet-clients."
6898
6899#~ msgid "Invalid port \"%s\" in hostlist specification, trying port %d.\n"
6900#~ msgstr "Ungültiger Port \"%s\" in Angabe der Hostlist, versuche Port %d.\n"
6901
6902#~ msgid "Could not download list of peer contacts, host `%s' unknown.\n"
6903#~ msgstr ""
6904#~ "Die Liste mit Knotenkontakten konnte nicht heruntergeladen werden, Host `%"
6905#~ "s' ist unbekannt.\n"
6906
6907#~ msgid "`%s' to `%s' failed at %s:%d with error: %s\n"
6908#~ msgstr "`%s' an `%s' schlug fehl bei %s:%d mit dem Fehler: %s\n"
6909
6910#~ msgid "Parsing HTTP response for URL `%s' failed.\n"
6911#~ msgstr "Das Parsen der HTTP Antwort für die URL `%s' schlug fehl.\n"
6912
6913#~ msgid "Parsing hello from `%s' failed.\n"
6914#~ msgstr "Das Parsen des Hello von `%s' schlug fehl.\n"
6915
6916#~ msgid "Could not resolve name of HTTP proxy `%s'. Trying without a proxy.\n"
6917#~ msgstr ""
6918#~ "Der Name des HTTP Proxies `%s' konnte nicht aufgelöst werden. Es wird "
6919#~ "ohne Proxy versucht.\n"
6920
6921#~ msgid "Failed to query gnunetd about traffic conditions.\n"
6922#~ msgstr "Fehler beim Abfragen der Netzwerkverkehrsbedingungen von gnunetd.\n"
6923
6924#~ msgid "Did not receive reply from gnunetd about traffic conditions.\n"
6925#~ msgstr "Keine Antwort von gnunetd über die Netzwerkverkehrsbedingungen.\n"
6926
6927#, fuzzy
6928#~ msgid ""
6929#~ "Configuration file must specify directory for storing data in section `%"
6930#~ "s' under `%s'.\n"
6931#~ msgstr ""
6932#~ "Die Konfigurationsdatei muss in der Sektion `%s' unter `%s' ein "
6933#~ "Verzeichnis angeben, in dem FS Daten gespeichert werden.\n"
6934
6935#~ msgid ""
6936#~ "Configuration file must specify a directory for GNUnet to store per-peer "
6937#~ "data under %s\\%s.\n"
6938#~ msgstr ""
6939#~ "Die Konfigurationsdatei muss unter %s\\%s ein Verzeichnis für GNUnet "
6940#~ "angeben, in dem knotenbezogene Daten gespeichert werden.\n"
6941
6942#~ msgid "Option `%s' makes no sense without option `%s'."
6943#~ msgstr "Option `%s' macht keinen Sinn ohne die Option `%s'."
6944
6945#~ msgid "Invalid arguments: "
6946#~ msgstr "Ungültige Parameter: "
6947
6948#~ msgid ""
6949#~ "\n"
6950#~ "Exiting.\n"
6951#~ msgstr ""
6952#~ "\n"
6953#~ "Abbruch.\n"
6954
6955#~ msgid "No applications defined in configuration!\n"
6956#~ msgstr "In der Konfigurationsdatei wurden keine Anwendungen definiert!\n"
6957
6958#~ msgid "Updated data for %d applications.\n"
6959#~ msgstr "Daten für %d Anwendungen wurden aktualisiert.\n"
6960
6961#~ msgid "Could not write PID to file `%s': %s.\n"
6962#~ msgstr "PID konnte nicht in Datei `%s' geschrieben werden: %s.\n"
6963
6964#~ msgid "Invalid command-line arguments:\n"
6965#~ msgstr "Ungültige Kommandozeilen Parameter:\n"
6966
6967#~ msgid "Argument %d: `%s'\n"
6968#~ msgstr "Parameter %d: `%s'\n"
6969
6970#~ msgid "`%s' starting\n"
6971#~ msgstr "`%s' startet\n"
6972
6973#~ msgid "FATAL: Identity plugin not found!\n"
6974#~ msgstr "SCHWERWIEGEND: Identity Plugin wurde nicht gefunden!\n"
6975
6976#~ msgid "You must specify a non-empty set of transports to test!\n"
6977#~ msgstr ""
6978#~ "Sie müssen eine Menge an Transporten angeben, die getestet werden "
6979#~ "sollen!\n"
6980
6981#~ msgid "Available MODEs:\n"
6982#~ msgstr "Verfügbare MODEs:\n"
6983
6984#~ msgid " config\t\ttext-based configuration\n"
6985#~ msgstr " config\t\ttext-basierte Konfiguration\n"
6986
6987#~ msgid " menuconfig\ttext-based menu\n"
6988#~ msgstr "menuconfig\ttext-basiertes Menü\n"
6989
6990#~ msgid " wizard-curses\tBasic text-based graphical configuration\n"
6991#~ msgstr " wizard-curses\tEinfache text-basierte grafische Konfiguration\n"
6992
6993#~ msgid ""
6994#~ " wizard-gtk\tBasic GTK configuration\n"
6995#~ "\n"
6996#~ msgstr ""
6997#~ " wizard-gtk\tEinfache GTK Konfiguration\n"
6998#~ "\n"
6999
7000#~ msgid "gnunet-setup must have write-access to the configuration file `%s'\n"
7001#~ msgstr ""
7002#~ "gnunet-setup benötigt Schreibberechtigungen für die Konfigurationsdatei `%"
7003#~ "s'\n"
7004
7005#~ msgid ""
7006#~ "Can only run wizard to configure gnunetd.\n"
7007#~ "Did you forget the `%s' option?\n"
7008#~ msgstr ""
7009#~ "Der Assistent kann nur zur Einrichtung von gnunetd gestartet werden.\n"
7010#~ "Haben Sie die `%s'-Option vergessen?\n"
7011
7012#~ msgid "%s: symbol value `%s' invalid for %s\n"
7013#~ msgstr "%s: Symbolwert `%s' ist ungültig für %s\n"
7014
7015#~ msgid "Gtk GNUnet Configurator"
7016#~ msgstr "Gtk GNUnet Konfigurator"
7017
7018#~ msgid "_File"
7019#~ msgstr "_Datei"
7020
7021#~ msgid "Load a config file"
7022#~ msgstr "Eine Konfigurationsdatei laden"
7023
7024#~ msgid "_Load"
7025#~ msgstr "_öffnen"
7026
7027#~ msgid "Save the config in .config"
7028#~ msgstr "Die Konfiguration in .config speichern"
7029
7030#~ msgid "_Save"
7031#~ msgstr "_Speichern"
7032
7033#~ msgid "_Quit"
7034#~ msgstr "_Beenden"
7035
7036#~ msgid "Show _name"
7037#~ msgstr "_Name anzeigen"
7038
7039#~ msgid "Show range (Y/M/N)"
7040#~ msgstr "Bereich anzeigen (Y/M/N)"
7041
7042#~ msgid "Show _range"
7043#~ msgstr "_Bereich anzeigen"
7044
7045#~ msgid "Show _data"
7046#~ msgstr "_Daten anzeigen"
7047
7048#~ msgid "Show all _options"
7049#~ msgstr "Alle _Optionen anzeigen"
7050
7051#~ msgid "_Help"
7052#~ msgstr "_Hilfe"
7053
7054#~ msgid "_Introduction"
7055#~ msgstr "_Einführung"
7056
7057#~ msgid "Goes up of one level (single view)"
7058#~ msgstr "Bewegt sich eine Ebene nach oben (einfache Ansicht)"
7059
7060#~ msgid "Load"
7061#~ msgstr "Laden"
7062
7063#~ msgid "Save a config file"
7064#~ msgstr "Konfigurationsdatei speichern"
7065
7066#~ msgid "Save"
7067#~ msgstr "Speichern"
7068
7069#~ msgid "Single view"
7070#~ msgstr "Einfache Ansicht"
7071
7072#~ msgid "Single"
7073#~ msgstr "Einfach"
7074
7075#~ msgid "Split view"
7076#~ msgstr "Geteilte Ansicht"
7077
7078#~ msgid "Split"
7079#~ msgstr "Geteilt"
7080
7081#~ msgid "Full view"
7082#~ msgstr "Volle Ansicht"
7083
7084#~ msgid "Full"
7085#~ msgstr "Voll"
7086
7087#~ msgid "Collapse the whole tree in the right frame"
7088#~ msgstr "Den gesamten Baum im rechten Frame kollabieren"
7089
7090#~ msgid "Collapse"
7091#~ msgstr "Kollabieren"
7092
7093#~ msgid "Expand the whole tree in the right frame"
7094#~ msgstr "Den gesamten Baum im rechten Frame expandieren"
7095
7096#~ msgid "Expand"
7097#~ msgstr "Expandieren"
7098
7099#, fuzzy
7100#~ msgid "Introduction"
7101#~ msgstr "_Einführung"
7102
7103#~ msgid "inlining configration file `%s'\n"
7104#~ msgstr "Binde Konfigurationsdatei `%s' ein\n"
7105
7106#~ msgid ""
7107#~ "Configuration file not found. Please run GNUnet Setup (Client "
7108#~ "Configuration) first."
7109#~ msgstr ""
7110#~ "Die Konfigurationsdatei wurde nicht gefunden. Bitte führen Sie zuerst "
7111#~ "GNUnet Setup (Client Konfiguration) aus."
7112
7113#~ msgid "Configuration file `%s' not found. Run `gnunet-setup -d'!\n"
7114#~ msgstr ""
7115#~ "Konfigurationsdatei `%s' nicht gefunden. Bitte führen Sie `gnunet-setup -"
7116#~ "d' aus!\n"
7117
7118#~ msgid "Cron stopped\n"
7119#~ msgstr "Cron angehalten\n"
7120
7121#~ msgid "Shutdown complete.\n"
7122#~ msgstr "GNUnet wurde erfolgreich heruntergefahren.\n"
7123
7124#~ msgid "Caught signal %d.\n"
7125#~ msgstr "Signal %d empfangen.\n"
7126
7127#~ msgid "Invalid network notation (additional characters: `%s')."
7128#~ msgstr "Ungültige Netzwerk Notation (zusätzliche Zeichen: `%s')."
7129
7130#~ msgid "FAILURE"
7131#~ msgstr "FEHLSCHLAG"
7132
7133#~ msgid "MESSAGE"
7134#~ msgstr "MELDUNG"
7135
7136#~ msgid "CRON"
7137#~ msgstr "CRON"
7138
7139#~ msgid "EVERYTHING"
7140#~ msgstr "ALLES"
7141
7142#~ msgid "Invalid LOGLEVEL `%s' specified.\n"
7143#~ msgstr "Ungültiger LOGLEVEL `%s' angegeben.\n"
7144
7145#~ msgid "Failure at %s:%d.\n"
7146#~ msgstr "Fehler bei %s:%d.\n"
7147
7148#~ msgid ""
7149#~ "Cannot determine port of gnunetd server. Define in configuration file in "
7150#~ "section `%s' under `%s'.\n"
7151#~ msgstr ""
7152#~ "Der Port des gnunetd Servers konnte nicht ermittelt werden. Definieren "
7153#~ "Sie ihn in der Sektion `%s' unter `%s'.\n"
7154
7155#~ msgid ""
7156#~ "Usage: %s\n"
7157#~ "%s\n"
7158#~ "\n"
7159#~ msgstr ""
7160#~ "Verwendung: %s\n"
7161#~ "%s\n"
7162#~ "\n"
7163
7164#~ msgid "Invalid argument for `%s' at %s:%d.\n"
7165#~ msgstr "Ungültiger Parameter für `%s' bei %s:%d.\n"
7166
7167#~ msgid "g"
7168#~ msgstr "g"
7169
7170#~ msgid "t"
7171#~ msgstr "t"
7172
7173#, fuzzy
7174#~ msgid "unknown"
7175#~ msgstr "Unbekannter Fehler"
7176
7177#~ msgid "`%s' failed, other side closed connection.\n"
7178#~ msgstr ""
7179#~ "`%s' fehlgeschlagen, die andere Seite hat die Verbindung geschlossen\n"
7180
7181#~ msgid "Attempted path to `%s' was `%s'.\n"
7182#~ msgstr "Versuchter Pfad für `%s' war `%s'.\n"
7183
7184#~ msgid "set verbosity to LEVEL"
7185#~ msgstr "Umfang der Meldungen auf LEVEL setzen"
7186
7187#~ msgid "_License"
7188#~ msgstr "_Lizenz"
7189
7190#~ msgid "Sorry, no help available for this option yet."
7191#~ msgstr "Sorry, für diese Option steht noch keine Hilfe zur Verfügung"
7192
7193#~ msgid "Couldn't find pixmap file: %s"
7194#~ msgstr "Pixmapdatei %s konnte nicht gefunden werden"
7195
7196#~ msgid ""
7197#~ "Welcome to GNUnet!\n"
7198#~ "\n"
7199#~ "This assistant will ask you a few basic questions in order to configure "
7200#~ "GNUnet.\n"
7201#~ "\n"
7202#~ "Please visit our homepage at\n"
7203#~ "\thttp://www.gnunet.org\n"
7204#~ "and join our community at\n"
7205#~ "\thttp://www.gnunet.org/drupal/\n"
7206#~ "\n"
7207#~ "Have a lot of fun,\n"
7208#~ "\n"
7209#~ "the GNUnet team"
7210#~ msgstr ""
7211#~ "Willkommen bei GNUnet!\n"
7212#~ "\n"
7213#~ "Dieser Assistent wird Ihnen einige grundlegende Fragen stellen, um GNUnet "
7214#~ "zu konfigurieren.\n"
7215#~ "\n"
7216#~ "Bitte besuchen Sie unsere Homepage\n"
7217#~ "\thttp://gnunet.org\n"
7218#~ "und schließen Sie sich unserer Community an:\n"
7219#~ "\thttps://gnunet.org/drupal/\n"
7220#~ "\n"
7221#~ "Viel Spaß,\n"
7222#~ "\n"
7223#~ "das GNUnet-Team"
7224
7225#~ msgid ""
7226#~ "You must specify a directory for FS files in the configuration in section "
7227#~ "`%s' under `%s'."
7228#~ msgstr ""
7229#~ "Sie müssen ein Verzeichnis für FS Dateien in der Konfigurationsdatei in "
7230#~ "der Sektion `%s' unter `%s' angeben."
7231
7232#~ msgid "Invalid data in MySQL database. Please verify integrity!\n"
7233#~ msgstr ""
7234#~ "Ungültige Daten in der MySQL Datenbank. Bitte überprüfen Sie die "
7235#~ "Integrität!\n"
7236
7237#~ msgid "SQL Database corrupt, ignoring result.\n"
7238#~ msgstr "SQL Datenbank beschädigt, Ergebnis wird ignoriert.\n"
7239
7240#~ msgid "Invalid data in database. Please verify integrity!\n"
7241#~ msgstr ""
7242#~ "Es befinden sich ungültige Daten in Datenbank. Bitte überprüfen Sie die "
7243#~ "Integrität!\n"
7244
7245#~ msgid "menuconfig is not available\n"
7246#~ msgstr " menuconfig ist nicht verfügbar\n"
7247
7248#~ msgid "wizard-curses is not available\n"
7249#~ msgstr "wizard-curses ist nicht verfügbar\n"
7250
7251#~ msgid "wizard-gtk is not available\n"
7252#~ msgstr "wizard-gtk ist nicht verfügbar\n"
7253
7254#~ msgid "gconfig is not available\n"
7255#~ msgstr "gconfig ist nicht verfügbar\n"
7256
7257#~ msgid "Recursive download of directory `%s' at %llu of %llu bytes.\n"
7258#~ msgstr ""
7259#~ "Rekursiver Download des Verzeichnisses `%s' bei %llu von %llu Bytes.\n"
7260
7261#~ msgid ""
7262#~ "Indexing file `%s' failed. Check file permissions and consult your GNUnet "
7263#~ "server's logs.\n"
7264#~ msgstr ""
7265#~ "Indizierung der Datei `%s' schlug fehl. Bitte prüfen Sie die "
7266#~ "Dateiberechtigungen und ziehen Sie die Protokolldateien des GNUnet-"
7267#~ "Servers zu Rate.\n"
7268
7269#~ msgid "Show _debug info"
7270#~ msgstr "_Debug Informationen anzeigen"
7271
7272#~ msgid ""
7273#~ "USAGE: gnunet-setup MODULE\n"
7274#~ "\n"
7275#~ "MODULE\n"
7276#~ " recreate\trecreate configuration files\n"
7277#~ " config\t\ttext-based configuration\n"
7278#~ " menuconfig\ttext-based menu\n"
7279#~ " gconfig\tGTK configuration\n"
7280#~ " wizard-curses\tBasic text-based graphical configuration\n"
7281#~ " wizard-gtk\tBasic GTK configuration\n"
7282#~ "\n"
7283#~ msgstr ""
7284#~ "Verwendung: gnunet-setup MODUL\n"
7285#~ "\n"
7286#~ "MODUL\n"
7287#~ " recreate\tKonfigurationsdateien neu erzeugen\n"
7288#~ " config\t\tText-basierte Konfiguration\n"
7289#~ " menuconfig\tText-basiertes Menü\n"
7290#~ " gconfig\tGTK Konfiguration\n"
7291#~ " wizard-curses\tEinfache text-basierte grafische Konfiguration\n"
7292#~ " wizard-gtk\tEinfache GTK Konfiguration\n"
7293#~ "\n"
7294
7295#~ msgid "Please specify a path where the configuration files will be stored."
7296#~ msgstr ""
7297#~ "Bitte geben Sie den Pfad an, wohin die Konfigurationsdateien gespeichert "
7298#~ "werden."
7299
7300#~ msgid "# p2p trace replies sent"
7301#~ msgstr "# p2p Trace-Antworten gesendet"
7302
7303#~ msgid "Session with peer `%s' confirmed, but I cannot connect! (bug?)\n"
7304#~ msgstr ""
7305#~ "Sitzung mit Knoten `%s' ist bestätigt es kann jedoch nicht verbunden "
7306#~ "werden! (Bug?)\n"
7307
7308#~ msgid "LOGLEVEL not specified, that is not ok.\n"
7309#~ msgstr "LOGLEVEL wurde nicht angegeben, das ist nicht in Ordnung.\n"
7310
7311#~ msgid ""
7312#~ "Interfaces string (%s) in configuration section `%s' under `%s' is "
7313#~ "malformed.\n"
7314#~ msgstr ""
7315#~ "Geräteangabe (%s) in der Konfigurationssektion `%s' unter `%s' ist "
7316#~ "beschädigt.\n"
7317
7318#~ msgid ""
7319#~ "No network interfaces specified in the configuration file in section `%s' "
7320#~ "under `%s'.\n"
7321#~ msgstr ""
7322#~ "Es sind keine Netzwerkgeräte in der Konfigurationsdatei in der Sektion '%"
7323#~ "s' unter `%s' definiert.\n"
7324
7325#~ msgid "Failed to parse interface data `%s' output at %s:%d.\n"
7326#~ msgstr "Fehler beim Parsen der Gerätedaten `%s' Ausgabe bei %s:%d.\n"
7327
7328#~ msgid "Could not decoding file `%s' at %s:%d.\n"
7329#~ msgstr "Datei `%s' konnte nicht dekodiert werden bei %s:%d.\n"
7330
7331#~ msgid ""
7332#~ "Configuration file must specify directory for network identities in "
7333#~ "section %s under %s.\n"
7334#~ msgstr ""
7335#~ "Die Konfigurationsdatei muss in Sektion %s unter %s ein Verzeichnis für "
7336#~ "Identitäten angeben.\n"
7337
7338#~ msgid "Sender %u.%u.%u.%u is blacklisted, dropping message.\n"
7339#~ msgstr ""
7340#~ "Sender %u.%u.%u.%u steht auf schwarzer Liste, Nachricht wird ignoriert.\n"
7341
7342#~ msgid "Sender %s is blacklisted, dropping message.\n"
7343#~ msgstr "Sender %s steht auf schwarzer Liste, Nachricht wird ignoriert.\n"
7344
7345#~ msgid "Removed file `%s' containing invalid peer advertisement.\n"
7346#~ msgstr ""
7347#~ "Datei `%s' enthielt eine ungültige Knotenbekanntmachung und wurde "
7348#~ "entfernt.\n"
7349
7350#~ msgid "Removed invalid HELO file `%s'\n"
7351#~ msgstr "Ungültige HELO Datei `%s' wurde entfernt.\n"
7352
7353#~ msgid "Could not determine IP address of the local machine!\n"
7354#~ msgstr "IP-Adresse der lokalen Maschiene konnte nicht ermittelt werden!\n"
7355
7356#~ msgid "Could not determine IP(v6) address of the local machine!\n"
7357#~ msgstr ""
7358#~ "IP(v6)-Adresse der lokalen Maschiene konnte nicht ermittelt werden!\n"
7359
7360#~ msgid ""
7361#~ "Could not find IP(v4) for this host. Please provide the IP in the "
7362#~ "configuration file.\n"
7363#~ msgstr ""
7364#~ "IP(v4) dieses Hosts konnte nicht ermittelt werden. Bitte geben Sie die IP "
7365#~ "in der Konfigurationsdatei an.\n"
7366
7367#~ msgid ""
7368#~ "Could not find IP(v6) for this host. Please provide the IP in the "
7369#~ "configuration file.\n"
7370#~ msgstr ""
7371#~ "IP(v6) dieses Hosts konnte nicht ermittelt werden. Bitte geben Sie die IP "
7372#~ "in der Konfigurationsdatei an.\n"
7373
7374#~ msgid "Save _as"
7375#~ msgstr "Speichern _unter"
7376
7377#~ msgid "Save the config in a file"
7378#~ msgstr "Die Konfiguration in einer Datei speichern"
7379
7380#~ msgid "Error: can't open Service Control Manager: %s (%i)\n"
7381#~ msgstr "Fehler: der Dienstemanager konnte nicht geöffnet werden: %s (%i)\n"
7382
7383#~ msgid "Error: can't create service: %s (#%i)\n"
7384#~ msgstr "Fehler: Dienst konnte nicht erzeugt werden: %s (#%i)\n"
7385
7386#~ msgid "Failure at at %s:%d.\n"
7387#~ msgstr "Fehler bei %s:%d.\n"
diff --git a/po/en@boldquot.header b/po/en@boldquot.header
new file mode 100644
index 000000000..fedb6a06d
--- /dev/null
+++ b/po/en@boldquot.header
@@ -0,0 +1,25 @@
1# All this catalog "translates" are quotation characters.
2# The msgids must be ASCII and therefore cannot contain real quotation
3# characters, only substitutes like grave accent (0x60), apostrophe (0x27)
4# and double quote (0x22). These substitutes look strange; see
5# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html
6#
7# This catalog translates grave accent (0x60) and apostrophe (0x27) to
8# left single quotation mark (U+2018) and right single quotation mark (U+2019).
9# It also translates pairs of apostrophe (0x27) to
10# left single quotation mark (U+2018) and right single quotation mark (U+2019)
11# and pairs of quotation mark (0x22) to
12# left double quotation mark (U+201C) and right double quotation mark (U+201D).
13#
14# When output to an UTF-8 terminal, the quotation characters appear perfectly.
15# When output to an ISO-8859-1 terminal, the single quotation marks are
16# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to
17# grave/acute accent (by libiconv), and the double quotation marks are
18# transliterated to 0x22.
19# When output to an ASCII terminal, the single quotation marks are
20# transliterated to apostrophes, and the double quotation marks are
21# transliterated to 0x22.
22#
23# This catalog furthermore displays the text between the quotation marks in
24# bold face, assuming the VT100/XTerm escape sequences.
25#
diff --git a/po/en@quot.header b/po/en@quot.header
new file mode 100644
index 000000000..a9647fc35
--- /dev/null
+++ b/po/en@quot.header
@@ -0,0 +1,22 @@
1# All this catalog "translates" are quotation characters.
2# The msgids must be ASCII and therefore cannot contain real quotation
3# characters, only substitutes like grave accent (0x60), apostrophe (0x27)
4# and double quote (0x22). These substitutes look strange; see
5# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html
6#
7# This catalog translates grave accent (0x60) and apostrophe (0x27) to
8# left single quotation mark (U+2018) and right single quotation mark (U+2019).
9# It also translates pairs of apostrophe (0x27) to
10# left single quotation mark (U+2018) and right single quotation mark (U+2019)
11# and pairs of quotation mark (0x22) to
12# left double quotation mark (U+201C) and right double quotation mark (U+201D).
13#
14# When output to an UTF-8 terminal, the quotation characters appear perfectly.
15# When output to an ISO-8859-1 terminal, the single quotation marks are
16# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to
17# grave/acute accent (by libiconv), and the double quotation marks are
18# transliterated to 0x22.
19# When output to an ASCII terminal, the single quotation marks are
20# transliterated to apostrophes, and the double quotation marks are
21# transliterated to 0x22.
22#
diff --git a/po/es.gmo b/po/es.gmo
new file mode 100644
index 000000000..219b3b52e
--- /dev/null
+++ b/po/es.gmo
Binary files differ
diff --git a/po/es.po b/po/es.po
new file mode 100644
index 000000000..5620f68b9
--- /dev/null
+++ b/po/es.po
@@ -0,0 +1,6921 @@
1# Spanish translations for GNUnet package.
2#
3# This file is distributed under the same license as the GNUnet package.
4# Miguel Angel Arruga Vivas <miguel.13@telefonica.net>, 2006.
5#
6msgid ""
7msgstr ""
8"Project-Id-Version: GNUnet 0.7.0e\n"
9"Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n"
10"POT-Creation-Date: 2009-01-08 10:55-0700\n"
11"PO-Revision-Date: 2006-06-29 12:05+0200\n"
12"Last-Translator: Miguel Angel Arruga <miguel.13@telefonica.net>\n"
13"Language-Team: Spanish\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=(n != 1);\n"
18
19#: src/setup/ncurses/wizard_curs.c:72 src/setup/lib/wizard_util.c:155
20#: src/setup/lib/wizard_util.c:210
21msgid "Error"
22msgstr "Error"
23
24#: src/setup/ncurses/wizard_curs.c:80
25msgid "Help"
26msgstr "Ayuda"
27
28#: src/setup/ncurses/wizard_curs.c:87
29msgid "Error!"
30msgstr "¡Error!"
31
32#: src/setup/ncurses/wizard_curs.c:101 src/applications/vpn/cs.c:94
33msgid "No"
34msgstr "No"
35
36#: src/setup/ncurses/wizard_curs.c:102 src/applications/vpn/cs.c:94
37msgid "Yes"
38msgstr "Sí"
39
40#: src/setup/ncurses/wizard_curs.c:118 src/setup/ncurses/wizard_curs.c:183
41#: src/setup/ncurses/wizard_curs.c:299 src/setup/ncurses/mconf.c:189
42#: src/setup/ncurses/mconf.c:285 src/setup/ncurses/mconf.c:365
43#: src/setup/ncurses/mconf.c:456
44msgid "Internal error! (Choice invalid?)"
45msgstr ""
46
47#: src/setup/ncurses/wizard_curs.c:150
48#, fuzzy
49msgid "Abort"
50msgstr "_Acerca de"
51
52#: src/setup/ncurses/wizard_curs.c:151
53#, fuzzy
54msgid "Ok"
55msgstr "k"
56
57#: src/setup/ncurses/wizard_curs.c:218 src/setup/ncurses/wizard_curs.c:284
58#: src/setup/ncurses/wizard_curs.c:425
59msgid "GNUnet configuration"
60msgstr "Configuración de GNUnet"
61
62#: src/setup/ncurses/wizard_curs.c:220
63msgid ""
64"Welcome to GNUnet!\n"
65"\n"
66"This assistant will ask you a few basic questions in order to configure "
67"GNUnet.\n"
68"\n"
69"Please visit our homepage at\n"
70"\thttp://gnunet.org/\n"
71"and join our community at\n"
72"\thttp://gnunet.org/drupal/\n"
73"\n"
74"Have a lot of fun,\n"
75"\n"
76"the GNUnet team"
77msgstr ""
78"¡Bienvenido a GNUnet!\n"
79"\n"
80"Este asistente te preguntará unas cuestiones básicas para configurar "
81"GNUnet.\n"
82"\n"
83"Por favor, visita nuestra página en\n"
84"\thttp://gnunet.org/\n"
85"y únete a nuestra comunidad en \n"
86"\thttp://gnunet.org/drupal/\n"
87"\n"
88"Diviertete,\n"
89"\n"
90"el equipo de GNUnet"
91
92#: src/setup/ncurses/wizard_curs.c:286
93msgid ""
94"Choose the network interface that connects your computer to the internet "
95"from the list below."
96msgstr ""
97"Escoge la interfaz de red que conecta tu ordenador a Internet de la lista de "
98"abajo."
99
100#: src/setup/ncurses/wizard_curs.c:304 src/setup/ncurses/wizard_curs.c:318
101msgid ""
102"The \"Network interface\" is the device that connects your computer to the "
103"internet. This is usually a modem, an ISDN card or a network card in case "
104"you are using DSL."
105msgstr ""
106"La \"Interfaz de red\" es el dispositivo que conecta tu ordenador a "
107"Internet. Normalmente es un módem, una tarjeta de RDSI o una tarjeta de red "
108"en el caso de los xDSL como el ADSL."
109
110#: src/setup/ncurses/wizard_curs.c:315
111#, fuzzy
112msgid "Network configuration: interface"
113msgstr "Interfaz de red:"
114
115#: src/setup/ncurses/wizard_curs.c:317
116msgid ""
117"What is the name of the network interface that connects your computer to the "
118"Internet?"
119msgstr ""
120"¿Cuál es el nombre de la interfaz de red que conecta tu ordenador a Internet?"
121
122#: src/setup/ncurses/wizard_curs.c:328
123#, fuzzy
124msgid "Network configuration: IP"
125msgstr "Configuración de GNUnet"
126
127#: src/setup/ncurses/wizard_curs.c:330
128#, fuzzy
129msgid "What is this computer's public IP address or hostname?"
130msgstr ""
131"¿Cuál es es la dirección pública IP o el nombre del dominio de éste "
132"ordenador?\n"
133"\n"
134"En caso de duda, dejar este campo en blanco."
135
136#: src/setup/ncurses/wizard_curs.c:331
137#, fuzzy
138msgid ""
139"If your provider always assigns the same IP-Address to you (a \"static\" IP-"
140"Address), enter it into the \"IP-Address\" field. If your IP-Address changes "
141"every now and then (\"dynamic\" IP-Address) but there's a hostname that "
142"always points to your actual IP-Address (\"Dynamic DNS\"), you can also "
143"enter it here.\n"
144"If left empty, GNUnet will try to automatically detect the IP.\n"
145"You can specify a hostname, GNUnet will then use DNS to resolve it.\n"
146"If in doubt, leave this empty."
147msgstr ""
148"Si tu proveedor siempre te asigna la misma dirección IP (una IP \"estática"
149"\") introducela en el campo \"Dirección IP\". Si tu dirección IP cambia pero "
150"hay un nombre de dominio que siempre apunta a tu dirección IP actual (\"DNS "
151"dinámica\"), puedes introducirlo allí también.\n"
152"En caso de duda deja el campo en blanco. GNUnet intentará determinar tu "
153"dirección IP"
154
155#: src/setup/ncurses/wizard_curs.c:346
156#, fuzzy
157msgid "Bandwidth configuration: upload"
158msgstr "Configuración de GNUnet"
159
160#: src/setup/ncurses/wizard_curs.c:348
161#, fuzzy
162msgid "How much upstream bandwidth (in bytes/s) may be used?"
163msgstr "¿Cuánta subida (Bytes/s) será usada por GNUnet?"
164
165#: src/setup/ncurses/wizard_curs.c:349
166#, fuzzy
167msgid ""
168"You can limit GNUnet's resource usage here.\n"
169"\n"
170"The \"upstream\" is the data channel through which data is *sent* to the "
171"internet. The limit is the maximum amount which GNUnet is allowed to use. If "
172"you have a flatrate, you can set it to the maximum speed of your internet "
173"connection. You should not use a value that is higher than what your actual "
174"connection allows."
175msgstr ""
176"Puedes limitar el uso de recursos de GNUnet aquí.\n"
177"\n"
178"La \"subida\" es el canal de datos a través del cual los datos son "
179"*mandados* a Internet. El límite, o bien es el total máximo para este "
180"ordenador, o bien el que se le permita usar a GNUnet. Puedes especificar "
181"este valor más tarde. Si tienes una tarifa plana puedes configurarlo a la "
182"máxima velocidad de tu conexión a Internet."
183
184#: src/setup/ncurses/wizard_curs.c:361
185#, fuzzy
186msgid "Bandwidth configuration: download"
187msgstr "Configuración de GNUnet"
188
189#: src/setup/ncurses/wizard_curs.c:363
190#, fuzzy
191msgid "How much downstream bandwidth (in bytes/s) may be used?"
192msgstr "¿Cuánta bajada (Bytes/s) será usada por GNUnet?"
193
194#: src/setup/ncurses/wizard_curs.c:364
195#, fuzzy
196msgid ""
197"You can limit GNUnet's resource usage here.\n"
198"\n"
199"The \"downstream\" is the data channel through which data is *received* from "
200"the internet. The limit is the maximum amount which GNUnet is allowed to "
201"use. If you have a flatrate, you can set it to the maximum speed of your "
202"internet connection. You should not use a value that is higher than what "
203"your actual connection allows."
204msgstr ""
205"Puedes limitar el uso de recursos de GNUnet aquí.\n"
206"\n"
207"La \"bajada\" es el canal de datos a través del cuál los datos son "
208"*recibidos* de Internet. El límite, o bien es el total máximo de este "
209"ordenador, o bien el que se le permita usar a GNUnet. Puedes especificar "
210"este valor más tarde. Si tienes una tarifa plana puedes configurarlo a la "
211"máxima velocidad de tu conexión a Internet."
212
213#: src/setup/ncurses/wizard_curs.c:376
214#, fuzzy
215msgid "Quota configuration"
216msgstr "Configuración de GNUnet"
217
218#: src/setup/ncurses/wizard_curs.c:377
219msgid "What is the maximum size of the datastore in MB?"
220msgstr ""
221
222#: src/setup/ncurses/wizard_curs.c:378
223#, fuzzy
224msgid ""
225"The GNUnet datastore contains all content that GNUnet needs to store "
226"(indexed, inserted and migrated content)."
227msgstr ""
228"¿Cuál es el tamaño máximo de almacenamiento en MB?\n"
229"\n"
230"El almacenamiento de GNUnet contiene todos los datos que GNUnet genera "
231"(datos del índice, contenido insertado y migrado)."
232
233#: src/setup/ncurses/wizard_curs.c:390
234#, fuzzy
235msgid "Daemon configuration: user account"
236msgstr "Imposible crear la cuenta de usuario:"
237
238#: src/setup/ncurses/wizard_curs.c:391
239msgid "As which user should gnunetd be run?"
240msgstr ""
241
242#: src/setup/ncurses/wizard_curs.c:393
243#, fuzzy
244msgid ""
245"For security reasons, it is a good idea to let this setup create a new user "
246"account under which the GNUnet service is started at system startup.\n"
247"\n"
248"However, GNUnet may not be able to access files other than its own. This "
249"includes files you want to publish in GNUnet. You'll have to grant read "
250"permissions to the user specified below.\n"
251"\n"
252"Leave the field empty to run GNUnet with system privileges.\n"
253msgstr ""
254"Define el usuario bajo el que correrán los servicios de GNUnet.\n"
255"\n"
256"Por razones de seguridad, es una buena idea dejar que la configuración cree "
257"una nueva cuenta de usuario bajo el cual el servicio de GNUnet es arrancado "
258"al iniciar el sistema.\n"
259"\n"
260"Por consiguiente, GNUnet no tiene la posibilidad de acceder a otros ficheros "
261"que no sean los que posee. Ésto incluye los ficheros que quieras publicar en "
262"GNUnet. Tendrás que garantizar que el usuario especificado aquí posea "
263"permisos de lectura.\n"
264"\n"
265"Deja los campos vacíos para arrancar GNUnet con privilegios de sistema.\n"
266"Usuario de GNUnet:"
267
268#: src/setup/ncurses/wizard_curs.c:410
269msgid "Daemon configuration: group account"
270msgstr ""
271
272#: src/setup/ncurses/wizard_curs.c:411
273msgid "As which group should gnunetd be run?"
274msgstr ""
275
276#: src/setup/ncurses/wizard_curs.c:413
277#, fuzzy
278msgid ""
279"For security reasons, it is a good idea to let this setup create a new group "
280"for the chosen user account.\n"
281"\n"
282"You can also specify a already existent group here.\n"
283"\n"
284"Only members of this group will be allowed to start and stop the the GNUnet "
285"server and have access to GNUnet server data.\n"
286msgstr ""
287"Define el grupo bajo el que correrán los servicios de GNUnet aquí.\n"
288"\n"
289"Por razones de seguridad, es una buena idea dejar que la configuración cree "
290"un nuevo grupo para la cuenta de usuario creada.\n"
291"\n"
292"Puedes especificar un grupo ya existente aquí.\n"
293"\n"
294"Sólo los miembros de este grupo esta autorizados a arrancar y parar el "
295"servidor de GNUnet y tener acceso a los datos del servidor de GNUnet.\n"
296"\n"
297"Grupo de GNUnet:"
298
299#: src/setup/ncurses/wizard_curs.c:427
300msgid "Do you want to automatically launch GNUnet as a system service?"
301msgstr ""
302
303#: src/setup/ncurses/wizard_curs.c:429
304#, fuzzy
305msgid ""
306"If you say \"yes\" here, the GNUnet background process will be automatically "
307"started when you turn on your computer. If you say \"no\" here, you have to "
308"launch GNUnet yourself each time you want to use it."
309msgstr ""
310"¿Quieres arrancar GNUnet como un servicio de sistema?\n"
311"n\n"
312"Si dices \"sí\" aquí, el proceso en segundo plano de GNUnet sera "
313"automáticamente arrancado cuando enciendas tu ordenador. Si dices \"no\" "
314"aquí, tendrás que ejecutar GNUnet tu mismo cada vez que quieras usarlo."
315
316#: src/setup/ncurses/wizard_curs.c:452 src/setup/gtk/wizard_gtk.c:414
317#, c-format
318msgid "Unable to save configuration file `%s':"
319msgstr "Imposible guardar el fichero de configuración '%s':"
320
321#: src/setup/ncurses/wizard_curs.c:472
322#, fuzzy
323msgid "Unable to create user account for daemon."
324msgstr "Imposible crear la cuenta de usuario:"
325
326#: src/setup/ncurses/wizard_curs.c:483
327msgid "Unable to setup autostart for daemon."
328msgstr ""
329
330#: src/setup/ncurses/wizard_curs.c:498
331#, fuzzy
332msgid "Save configuration?"
333msgstr "Configuración de GNUnet"
334
335#: src/setup/ncurses/wizard_curs.c:499
336#, fuzzy
337msgid "Save configuration now?"
338msgstr "Configuración de GNUnet"
339
340#: src/setup/ncurses/wizard_curs.c:539 src/setup/ncurses/mconf.c:500
341#, fuzzy
342msgid "GNUnet Configuration"
343msgstr "Configuración de GNUnet"
344
345#: src/setup/ncurses/wizard_curs.c:543
346msgid "Back"
347msgstr "Atrás"
348
349#: src/setup/ncurses/mconf.c:96
350msgid "Exit"
351msgstr ""
352
353#: src/setup/ncurses/mconf.c:99
354msgid "Up"
355msgstr "Arriba"
356
357#: src/setup/ncurses/mconf.c:102
358msgid "Cancel"
359msgstr "Cancelar"
360
361#: src/setup/ncurses/mconf.c:221 src/setup/ncurses/mconf.c:408
362msgid "Internal error! (Value invalid?)"
363msgstr ""
364
365#: src/setup/ncurses/mconf.c:398
366msgid "Invalid input, expecting floating point value."
367msgstr ""
368
369#: src/setup/ncurses/mconf.c:439
370msgid "Invalid input, expecting integer."
371msgstr ""
372
373#: src/setup/ncurses/mconf.c:446
374msgid "Value is not in legal range."
375msgstr ""
376
377#: src/setup/ncurses/mconf.c:512 src/setup/text/conf.c:569
378#, fuzzy, c-format
379msgid "Configuration unchanged, no need to save.\n"
380msgstr ""
381"La configuración o la versión de GNUnet cambiaron. ¡Debes ejecutar '%s'!\n"
382
383#: src/setup/ncurses/mconf.c:518
384#, fuzzy
385msgid "Do you wish to save your new configuration?"
386msgstr "¿Quieres guardar tu configuración?"
387
388#: src/setup/ncurses/mconf.c:532
389#, fuzzy, c-format
390msgid ""
391"\n"
392"End of configuration.\n"
393msgstr " gconfig\tConfiguración GTK\n"
394
395#: src/setup/ncurses/mconf.c:537
396#, fuzzy, c-format
397msgid ""
398"\n"
399"Your configuration changes were NOT saved.\n"
400msgstr "Fichero de configuración '%s' creado.\n"
401
402#: src/setup/gnunet-win-tool.c:52
403msgid "list all network adapters"
404msgstr ""
405
406#: src/setup/gnunet-win-tool.c:55
407msgid "install GNUnet as Windows service"
408msgstr ""
409
410#: src/setup/gnunet-win-tool.c:58
411msgid "uninstall GNUnet service"
412msgstr ""
413
414#: src/setup/gnunet-win-tool.c:61
415msgid "increase the maximum number of TCP/IP connections"
416msgstr ""
417
418#: src/setup/gnunet-win-tool.c:64
419msgid "display a file's hash value"
420msgstr ""
421
422#: src/setup/gnunet-win-tool.c:125
423#, c-format
424msgid "GNUnet service installed successfully.\n"
425msgstr "Servicio de GNUnet instalado satisfactoriamente.\n"
426
427#: src/setup/gnunet-win-tool.c:128 src/setup/gnunet-win-tool.c:156
428#, c-format
429msgid "This version of Windows doesn't support services.\n"
430msgstr "Esta versión de Windows no soporta servicios.\n"
431
432#: src/setup/gnunet-win-tool.c:132 src/setup/gnunet-win-tool.c:160
433#, fuzzy, c-format
434msgid "Error: can't open Service Control Manager: %s\n"
435msgstr "Error: imposible abrir el Service Control Manager: &s\n"
436
437#: src/setup/gnunet-win-tool.c:137
438#, c-format
439msgid "Error: can't create service: %s\n"
440msgstr "Error: imposible crear el servicio: %s\n"
441
442#: src/setup/gnunet-win-tool.c:140 src/setup/gnunet-win-tool.c:172
443#, c-format
444msgid "Unknown error.\n"
445msgstr "Error desconocido.\n"
446
447#: src/setup/gnunet-win-tool.c:153
448#, c-format
449msgid "Service deleted.\n"
450msgstr "Servicio eliminado.\n"
451
452#: src/setup/gnunet-win-tool.c:165
453#, c-format
454msgid "Error: can't access service: %s\n"
455msgstr "Error: imposible acceder al servicio: %s\n"
456
457#: src/setup/gnunet-win-tool.c:169
458#, c-format
459msgid "Error: can't delete service: %s\n"
460msgstr "Error: imposible borrar el servicio: %s\n"
461
462#: src/setup/gtk/ngconf.c:389
463#, fuzzy
464msgid "Configuration saved."
465msgstr "Configuración de GNUnet"
466
467#: src/setup/gtk/ngconf.c:399
468#, fuzzy
469msgid "Failed to save configuration."
470msgstr "Imposible guardar la configuración"
471
472#: src/setup/gtk/ngconf.c:424
473#, fuzzy
474msgid "Configuration changed. Save?"
475msgstr ""
476"La configuración o la versión de GNUnet cambiaron. ¡Debes ejecutar '%s'!\n"
477
478#: src/setup/gtk/ngconf.c:437
479#, fuzzy
480msgid "Error saving configuration."
481msgstr "Imposible guardar la configuración"
482
483#: src/setup/gtk/wizard_gtk.c:141
484#, fuzzy
485msgid "(unknown connection)"
486msgstr "Conexión de red"
487
488#: src/setup/gtk/wizard_gtk.c:438
489#, fuzzy
490msgid "Do you want to save the new configuration?"
491msgstr "¿Quieres guardar tu configuración?"
492
493#: src/setup/gtk/wizard_gtk.c:470
494msgid "Unable to create user account:"
495msgstr "Imposible crear la cuenta de usuario:"
496
497#: src/setup/gtk/wizard_gtk.c:480
498msgid "Unable to change startup process:"
499msgstr "Imposible cambiar el proceso de arranque:"
500
501#: src/setup/gtk/wizard_gtk.c:495
502msgid ""
503"Running gnunet-update failed.\n"
504"This maybe due to insufficient permissions, please check your "
505"configuration.\n"
506"Finally, run gnunet-update manually."
507msgstr ""
508
509#: src/setup/gnunet-setup.c:65
510#, c-format
511msgid "Can only set one option per invocation.\n"
512msgstr ""
513
514#: src/setup/gnunet-setup.c:73
515#, c-format
516msgid ""
517"Invalid syntax, argument to 'set' must have the format SECTION:"
518"OPTION=VALUE.\n"
519msgstr ""
520
521#: src/setup/gnunet-setup.c:87
522#, c-format
523msgid "Can only display one option per invocation.\n"
524msgstr ""
525
526#: src/setup/gnunet-setup.c:94
527#, c-format
528msgid ""
529"Invalid syntax, argument to 'get' must have the format SECTION:OPTION.\n"
530msgstr ""
531
532#: src/setup/gnunet-setup.c:108
533msgid "generate configuration for gnunetd, the GNUnet daemon"
534msgstr "genera configuración para gnunetd, el demonio de GNUnet"
535
536#: src/setup/gnunet-setup.c:111 src/setup/gnunet-setup.c:127
537#: src/server/gnunet-update.c:268
538#, fuzzy
539msgid "print a value from the configuration file to stdout"
540msgstr "Imposible guardar el fichero de configuración '%s':"
541
542#: src/setup/gnunet-setup.c:113 src/setup/gnunet-setup.c:129
543msgid "Tool to setup GNUnet."
544msgstr "Herramienta de configuración de GNUnet."
545
546#: src/setup/gnunet-setup.c:115 src/setup/gnunet-setup.c:131
547#, fuzzy
548msgid "update a value in the configuration file"
549msgstr "Imposible guardar el fichero de configuración '%s':"
550
551#: src/setup/gnunet-setup.c:338
552#, fuzzy, c-format
553msgid "Too many arguments.\n"
554msgstr "Argumentos en la linea de comandos inválidos.\n"
555
556#: src/setup/gnunet-setup.c:344
557#, fuzzy
558msgid "No interface specified, using default.\n"
559msgstr "Ninguna interfaz especificada, usando la marcada por defecto\n"
560
561#: src/setup/gnunet-setup.c:392
562#, fuzzy, c-format
563msgid "Configuration file `%s' must be a filename (but is a directory).\n"
564msgstr ""
565"El fichero de configuración '%s' no ha sido encontrado. ¡Ejecute gnunet-"
566"setup!\n"
567
568#: src/setup/gnunet-setup.c:439
569#, fuzzy, c-format
570msgid "Undefined option.\n"
571msgstr "Otras configuraciones"
572
573#: src/setup/gnunet-setup.c:496
574#, fuzzy, c-format
575msgid "`%s' is not available.\n"
576msgstr "'%s' no esta disponible."
577
578#: src/setup/gnunet-setup.c:516
579#, fuzzy, c-format
580msgid "Unknown operation '%s'.\n"
581msgstr "Operación desconocida '%s'\n"
582
583#: src/setup/gnunet-setup.c:517 src/util/getopt/getopt.c:1072
584#, c-format
585msgid "Use --help to get a list of options.\n"
586msgstr "Usar --help para obtener una lista de opciones.\n"
587
588#: src/setup/text/conf.c:79
589#, fuzzy
590msgid "yes"
591msgstr "Bytes"
592
593#: src/setup/text/conf.c:80
594msgid "no"
595msgstr ""
596
597#: src/setup/text/conf.c:106
598#, c-format
599msgid "\tEnter yes (%s), no (%s) or help (%s): "
600msgstr ""
601
602#: src/setup/text/conf.c:115
603msgid "\tPossible choices:\n"
604msgstr ""
605
606#: src/setup/text/conf.c:123
607msgid "\tUse single space prefix to avoid conflicts with hotkeys!\n"
608msgstr ""
609
610#: src/setup/text/conf.c:125
611#, c-format
612msgid "\tEnter string (type '%s' for default value `%s'): "
613msgstr ""
614
615#: src/setup/text/conf.c:143
616#, c-format
617msgid "\t Enter choice (default is %c): "
618msgstr ""
619
620#: src/setup/text/conf.c:147
621#, c-format
622msgid "\tEnter floating point (type '%s' for default value %f): "
623msgstr ""
624
625#: src/setup/text/conf.c:153
626#, c-format
627msgid ""
628"\tEnter unsigned integer in interval [%llu,%llu] (type '%s' for default "
629"value %llu): "
630msgstr ""
631
632#: src/setup/text/conf.c:187
633#, c-format
634msgid "Yes\n"
635msgstr "Sí\n"
636
637#: src/setup/text/conf.c:192
638#, c-format
639msgid "No\n"
640msgstr "No\n"
641
642#: src/setup/text/conf.c:195 src/setup/text/conf.c:236
643#: src/setup/text/conf.c:266 src/setup/text/conf.c:329
644#: src/setup/text/conf.c:387
645#, c-format
646msgid "Help\n"
647msgstr "Ayuda\n"
648
649#: src/setup/text/conf.c:198 src/setup/text/conf.c:213
650#: src/setup/text/conf.c:276 src/setup/text/conf.c:307
651#: src/setup/text/conf.c:365
652#, fuzzy, c-format
653msgid "Abort\n"
654msgstr "_Acerca de"
655
656#: src/setup/text/conf.c:354 src/setup/text/conf.c:416
657#, c-format
658msgid ""
659"\n"
660"Invalid entry, try again (use '?' for help): "
661msgstr ""
662
663#: src/setup/text/conf.c:422
664#, c-format
665msgid "Unknown kind %x (internal error). Skipping option.\n"
666msgstr ""
667
668#: src/setup/text/conf.c:484
669msgid "\tDescend? (y/n/?) "
670msgstr ""
671
672#: src/setup/text/conf.c:493
673msgid "Aborted.\n"
674msgstr ""
675
676#: src/setup/text/conf.c:506
677#, fuzzy
678msgid "Invalid entry.\n"
679msgstr "Argumento no válido: '%s'\n"
680
681#: src/setup/text/conf.c:524
682#, c-format
683msgid "Unknown kind %x (internal error). Aborting.\n"
684msgstr ""
685
686#: src/setup/text/conf.c:556
687#, c-format
688msgid "You can always press ENTER to keep the current value.\n"
689msgstr ""
690
691#: src/setup/text/conf.c:557
692#, c-format
693msgid "Use the '%s' key to abort.\n"
694msgstr ""
695
696#: src/setup/text/conf.c:575
697#, c-format
698msgid ""
699"Save configuration? Answer 'y' for yes, 'n' for no, 'r' to repeat "
700"configuration. "
701msgstr ""
702
703#: src/setup/text/conf.c:590
704#, fuzzy, c-format
705msgid "Configuration was unchanged, no need to save.\n"
706msgstr ""
707"La configuración o la versión de GNUnet cambiaron. ¡Debes ejecutar '%s'!\n"
708
709#: src/setup/text/conf.c:599
710#, fuzzy, c-format
711msgid "Configuration file `%s' written.\n"
712msgstr "Fichero de configuración '%s' creado.\n"
713
714#: src/setup/lib/tree.c:191
715#, c-format
716msgid ""
717"Internal error: entry `%s' in section `%s' not found for visibility change!\n"
718msgstr ""
719
720#: src/setup/lib/wizard_util.c:126
721msgid "Can't open Service Control Manager"
722msgstr "Imposible abrir el Service Control Manager"
723
724#: src/setup/lib/wizard_util.c:132
725msgid "Can't create service"
726msgstr "Imposible crear el servicio"
727
728#: src/setup/lib/wizard_util.c:136
729msgid "Error changing the permissions of the GNUnet directory"
730msgstr "Error cambiando los permisos del directorio de GNUnet"
731
732#: src/setup/lib/wizard_util.c:141
733#, fuzzy
734msgid "Cannot write to the registry"
735msgstr "Imposible escribir en el registro"
736
737#: src/setup/lib/wizard_util.c:144
738msgid "Can't access the service"
739msgstr "Imposible acceder al servicio"
740
741#: src/setup/lib/wizard_util.c:147
742msgid "Can't delete the service"
743msgstr "Imposible borrar el servicio"
744
745#: src/setup/lib/wizard_util.c:150
746msgid "Unknown error"
747msgstr "Error desconocido"
748
749#: src/setup/lib/wizard_util.c:186
750msgid "This version of Windows does not support multiple users."
751msgstr "Esta versión de Windows no permite usuarios múltiples"
752
753#: src/setup/lib/wizard_util.c:190
754msgid "Error creating user"
755msgstr "Error creando usuario"
756
757#: src/setup/lib/wizard_util.c:194
758msgid "Error accessing local security policy"
759msgstr "Error accediendo a la política de seguridad local"
760
761#: src/setup/lib/wizard_util.c:199
762msgid "Error granting service right to user"
763msgstr "Error garantizando el servicio correcto al usuario"
764
765#: src/setup/lib/wizard_util.c:204
766msgid "Unknown error while creating a new user"
767msgstr "Error desconocido mientras se creaba un nuevo usuario"
768
769#: src/setup/lib/gns.c:297
770#, fuzzy, c-format
771msgid ""
772"Configuration does not satisfy constraints of configuration specification "
773"file `%s'!\n"
774msgstr ""
775"La configuración debe especificar un directorio para los datos FS en la "
776"sección '%s' bajo'%s'.\n"
777
778#: src/util/disk/storage.c:172
779#, fuzzy, c-format
780msgid "`%s' failed for drive `%s': %u\n"
781msgstr "'%s' falló para la unidad %s: %u\n"
782
783#: src/util/disk/storage.c:524
784#, fuzzy, c-format
785msgid "Expected `%s' to be a directory!\n"
786msgstr "¡'%s' se esperaba que '%s' fuera un directorio!\n"
787
788#: src/util/error/error.c:152
789#, c-format
790msgid "Message `%.*s' repeated %u times in the last %llus\n"
791msgstr ""
792
793#: src/util/error/error.c:254
794#, c-format
795msgid ""
796"\n"
797"Press any key to continue\n"
798msgstr ""
799
800#: src/util/error/error.c:336 src/util/error/error.c:371
801msgid "DEBUG"
802msgstr "DEPURACIÓN"
803
804#: src/util/error/error.c:338 src/util/error/error.c:373
805msgid "STATUS"
806msgstr ""
807
808#: src/util/error/error.c:340 src/util/error/error.c:377
809msgid "WARNING"
810msgstr "PELIGRO"
811
812#: src/util/error/error.c:342 src/util/error/error.c:379
813msgid "ERROR"
814msgstr "ERROR"
815
816#: src/util/error/error.c:344 src/util/error/error.c:381
817msgid "FATAL"
818msgstr "FATAL"
819
820#: src/util/error/error.c:346 src/util/error/error.c:383
821msgid "USER"
822msgstr ""
823
824#: src/util/error/error.c:348 src/util/error/error.c:385
825msgid "ADMIN"
826msgstr ""
827
828#: src/util/error/error.c:350 src/util/error/error.c:387
829msgid "DEVELOPER"
830msgstr ""
831
832#: src/util/error/error.c:352 src/util/error/error.c:389
833msgid "REQUEST"
834msgstr ""
835
836#: src/util/error/error.c:354 src/util/error/error.c:391
837msgid "BULK"
838msgstr ""
839
840#: src/util/error/error.c:356 src/util/error/error.c:393
841msgid "IMMEDIATE"
842msgstr ""
843
844#: src/util/error/error.c:358
845msgid "ALL"
846msgstr ""
847
848#: src/util/error/error.c:375
849msgid "INFO"
850msgstr "INFORMACIÓN"
851
852#: src/util/error/error.c:394
853msgid "NOTHING"
854msgstr "NADA"
855
856#: src/util/network_client/tcpio.c:98 src/util/network_client/tcpio.c:154
857msgid "Could not find valid value for HOST in section NETWORK.\n"
858msgstr ""
859
860#: src/util/network_client/tcpio.c:123
861#, fuzzy, c-format
862msgid "Syntax error in configuration entry HOST in section NETWORK: `%s'\n"
863msgstr ""
864"Error de sintaxis en el fichero de configuración '%s' en la linea %d.\n"
865
866#: src/util/network_client/tcpio.c:335
867#, fuzzy, c-format
868msgid "Error connecting to %s:%u. Is the daemon running?\n"
869msgstr "Imposible conectar a %u.%u.%u.%u:%u: %s\n"
870
871#: src/util/network_client/tcpio.c:398
872#, fuzzy, c-format
873msgid "Cannot connect to %s:%u: %s\n"
874msgstr "Imposible conectar a %u.%u.%u.%u:%u: %s\n"
875
876#: src/util/network_client/tcpio.c:636
877#, fuzzy
878msgid "Reading result from gnunetd failed, reply invalid!\n"
879msgstr "¡'%s' falló, respuesta no válida!\n"
880
881#: src/util/getopt/setoption.c:59
882#, c-format
883msgid ""
884"Setting option `%s' in section `%s' to `%s' when processing command line "
885"option `%s' was denied.\n"
886msgstr ""
887
888#: src/util/getopt/setoption.c:138 src/util/getopt/setoption.c:155
889#, c-format
890msgid "You must pass a number to the `%s' option.\n"
891msgstr "Tienes que introducir un número en la opción '%s'.\n"
892
893#: src/util/getopt/printhelp.c:49
894#, c-format
895msgid ""
896"Arguments mandatory for long options are also mandatory for short options.\n"
897msgstr ""
898
899#: src/util/getopt/getopt.c:684
900#, c-format
901msgid "%s: option `%s' is ambiguous\n"
902msgstr "%s: la opción '%s' es ambigua\n"
903
904#: src/util/getopt/getopt.c:710
905#, c-format
906msgid "%s: option `--%s' does not allow an argument\n"
907msgstr "%s: la opción '--%s' no permite un argumento\n"
908
909#: src/util/getopt/getopt.c:716
910#, c-format
911msgid "%s: option `%c%s' does not allow an argument\n"
912msgstr "%s: la opción '%c%s' no permite un argumento\n"
913
914#: src/util/getopt/getopt.c:737 src/util/getopt/getopt.c:909
915#, c-format
916msgid "%s: option `%s' requires an argument\n"
917msgstr "%s: la opción '%s' requiere un argumento\n"
918
919#: src/util/getopt/getopt.c:767
920#, c-format
921msgid "%s: unrecognized option `--%s'\n"
922msgstr "%s: opción no reconocida '--%s'\n"
923
924#: src/util/getopt/getopt.c:771
925#, c-format
926msgid "%s: unrecognized option `%c%s'\n"
927msgstr "%s: opción no reconocida '%c%s'\n"
928
929#: src/util/getopt/getopt.c:797
930#, c-format
931msgid "%s: illegal option -- %c\n"
932msgstr "%s: opción ilegal -- %c\n"
933
934#: src/util/getopt/getopt.c:799
935#, c-format
936msgid "%s: invalid option -- %c\n"
937msgstr "%s: opción no válida -- %c\n"
938
939#: src/util/getopt/getopt.c:828 src/util/getopt/getopt.c:958
940#, c-format
941msgid "%s: option requires an argument -- %c\n"
942msgstr "%s: la opción requiere un argumento --%c\n"
943
944#: src/util/getopt/getopt.c:876
945#, c-format
946msgid "%s: option `-W %s' is ambiguous\n"
947msgstr "%s: la opción '-W %s' es ambigua\n"
948
949#: src/util/getopt/getopt.c:894
950#, c-format
951msgid "%s: option `-W %s' does not allow an argument\n"
952msgstr "%s: la opción '-W %s' no permite un argumento\n"
953
954#: src/util/network/ip.c:96 src/util/network/ip.c:160 src/transports/ip.c:260
955#, fuzzy, c-format
956msgid "No interface specified in section `%s' under `%s'!\n"
957msgstr "Ninguna interfaz especificada, usando la marcada por defecto\n"
958
959#: src/util/network/ip.c:127 src/util/network/ip.c:246 src/transports/ip.c:291
960#, c-format
961msgid "Could not obtain IP for interface `%s' using `%s'.\n"
962msgstr "Imposible obtener IP para la interfaz '%s' usando '%s'.\n"
963
964#: src/util/network/ip.c:216
965#, fuzzy, c-format
966msgid ""
967"Could not find interface `%s' using `%s', trying to find another interface.\n"
968msgstr "Imposible obtener IP para la interfaz '%s' usando '%s'.\n"
969
970#: src/util/network/ip.c:295
971#, c-format
972msgid "Could not find an IP address for interface `%s'.\n"
973msgstr "Imposible obtener la dirección IP para la interfaz '%s'.\n"
974
975#: src/util/network/ip.c:306
976#, fuzzy, c-format
977msgid ""
978"There is more than one IP address specified for interface `%s'.\n"
979"GNUnet will use %s.\n"
980msgstr ""
981"Hay más de una dirección IP especificada para la interfaz '%s'.\n"
982"GNUnet usará %u.%u.%u.%u.\n"
983
984#: src/util/network/ip.c:330
985#, c-format
986msgid "Could not resolve `%s' to determine our IP address: %s\n"
987msgstr "Imposible resolver '%s' para determinar nuestra dirección IP: %s\n"
988
989#: src/util/network/ip.c:363
990#, fuzzy, c-format
991msgid "GNUnet now uses the IP address %s.\n"
992msgstr "GNUnet usa ahora la dirección IP %u.%u.%u.%u.\n"
993
994#: src/util/network/ipcheck.c:106 src/util/network/ipcheck.c:136
995#: src/util/network/ipcheck.c:186 src/util/network/ipcheck.c:211
996#: src/util/network/ipcheck.c:219
997#, c-format
998msgid "Invalid format for IP: `%s'\n"
999msgstr "Formato no válido para la IP: '%s'\n"
1000
1001#: src/util/network/ipcheck.c:167
1002#, c-format
1003msgid "Invalid network notation ('/%d' is not legal in IPv4 CIDR)."
1004msgstr "Notación de red no válida ('/%d' no es válido en IPv4 CIDR)."
1005
1006#: src/util/network/ipcheck.c:269
1007#, c-format
1008msgid "Invalid network notation (does not end with ';': `%s')\n"
1009msgstr "Notación de red no válida (no termina con ';': '%s')\n"
1010
1011#: src/util/network/ipcheck.c:306
1012#, fuzzy, c-format
1013msgid "Wrong format `%s' for netmask\n"
1014msgstr "Formato '%s' erróneo para la máscara de red: %s\n"
1015
1016#: src/util/network/ipcheck.c:338
1017#, fuzzy, c-format
1018msgid "Wrong format `%s' for network\n"
1019msgstr "Formato '%s' erróneo para la red: %s\n"
1020
1021#: src/util/network/dns.c:472
1022#, fuzzy, c-format
1023msgid "Could not resolve `%s' (%s): %s\n"
1024msgstr "Imposible resolver '%s': %s\n"
1025
1026#: src/util/network/dns.c:523 src/util/network/dns.c:591
1027#, c-format
1028msgid "Could not find IP of host `%s': %s\n"
1029msgstr "Imposible encontrar la IP del host '%s': %s\n"
1030
1031#: src/util/network/select.c:310
1032#, fuzzy
1033msgid "Received malformed message (too small) from connection. Closing.\n"
1034msgstr "Recibida respuesta anómala a'%s' del par '%s'.\n"
1035
1036#: src/util/network/select.c:495
1037#, c-format
1038msgid "select listen socket for `%s' not valid!\n"
1039msgstr ""
1040
1041#: src/util/config/config.c:296
1042#, c-format
1043msgid "Syntax error in configuration file `%s' at line %d.\n"
1044msgstr ""
1045"Error de sintaxis en el fichero de configuración '%s' en la linea %d.\n"
1046
1047#: src/util/config/config.c:592
1048#, c-format
1049msgid ""
1050"Configuration value '%llu' for '%s' in section '%s' is out of legal bounds [%"
1051"llu,%llu]\n"
1052msgstr ""
1053
1054#: src/util/config/config.c:602
1055#, c-format
1056msgid "Configuration value '%s' for '%s' in section '%s' should be a number\n"
1057msgstr ""
1058
1059#: src/util/config/config.c:688
1060#, c-format
1061msgid ""
1062"Configuration value '%s' for '%s' in section '%s' is not in set of legal "
1063"choices\n"
1064msgstr ""
1065
1066#: src/util/crypto/locking_gcrypt.c:80
1067#, c-format
1068msgid "libgcrypt has not the expected version (version %s is required).\n"
1069msgstr ""
1070"libgcrypt no está en la versión esperada (se necesita la versión %s).\n"
1071
1072#: src/util/crypto/symcipher_gcrypt.c:46 src/util/crypto/symcipher_gcrypt.c:53
1073#: src/util/crypto/hostkey_gcrypt.c:64 src/util/crypto/hostkey_gcrypt.c:71
1074#: src/util/loggers/file.c:271 src/util/loggers/file.c:289
1075#: src/applications/sqstore_sqlite/sqlite.c:45
1076#: src/applications/sqstore_sqlite/sqlite.c:52
1077#: src/applications/kvstore_sqlite/kv_sqlite.c:44
1078#: src/applications/kvstore_sqlite/kv_sqlite.c:51
1079#: src/applications/kvstore_mysql/kv_mysql.c:44
1080#: src/applications/kvstore_mysql/kv_mysql.c:51
1081#: src/applications/dstore_sqlite/dstore.c:94
1082#: src/applications/dstore_sqlite/dstore.c:101
1083#: src/applications/dstore_sqlite/dstore.c:222
1084#: src/applications/dstore_sqlite/dstore.c:259
1085#: src/applications/dstore_sqlite/dstore.c:285
1086#: src/applications/dstore_sqlite/dstore.c:345
1087#: src/applications/dstore_sqlite/dstore.c:366
1088#: src/applications/dstore_sqlite/dstore.c:378
1089#: src/applications/dstore_sqlite/dstore.c:407
1090#: src/applications/dstore_sqlite/dstore.c:511
1091#: src/applications/dstore_sqlite/dstore.c:555
1092#: src/include/gnunet_util_error.h:249 src/include/gnunet_util_error.h:256
1093#: src/include/gnunet_util_error.h:263
1094#, c-format
1095msgid "`%s' failed at %s:%d with error: %s\n"
1096msgstr "'%s' falló en %s: %d con el error: %s\n"
1097
1098#: src/util/crypto/hostkey_gcrypt.c:907
1099#, c-format
1100msgid "RSA signature verification failed at %s:%d: %s\n"
1101msgstr "La verificación de la firma RSA fallo en %s: %d: %s\n"
1102
1103#: src/util/os/user.c:108 src/util/os/user.c:125
1104#, fuzzy, c-format
1105msgid "`%s' returned with error code %u"
1106msgstr "'%s' falló con el código de error %s: %s"
1107
1108#: src/util/os/user.c:155 src/util/os/user.c:200
1109#, fuzzy, c-format
1110msgid "Cannot obtain information about user `%s': %s\n"
1111msgstr "Imposible guardar el fichero de configuración '%s': %s.\n"
1112
1113#: src/util/os/user.c:156
1114msgid "No such user"
1115msgstr ""
1116
1117#: src/util/os/user.c:171
1118#, c-format
1119msgid "Cannot change user/group to `%s': %s\n"
1120msgstr "Imposible cambiar el usuario/grupo a '%s': %s\n"
1121
1122#: src/util/os/semaphore.c:227
1123#, c-format
1124msgid "Can't create semaphore: %i"
1125msgstr "Imposible crear un semáforo: %i"
1126
1127#: src/util/os/cpustatus.c:464
1128msgid "Cannot query the CPU usage (Windows NT).\n"
1129msgstr ""
1130
1131#: src/util/os/cpustatus.c:487
1132msgid "Cannot query the CPU usage (Win 9x)\n"
1133msgstr ""
1134
1135#: src/util/os/dso.c:59
1136#, c-format
1137msgid "Initialization of plugin mechanism failed: %s!\n"
1138msgstr "¡El mecanismo de iniciación de los plugins falló: %s!\n"
1139
1140#: src/util/os/dso.c:120
1141#, fuzzy, c-format
1142msgid "`%s' failed for library `%s' with error: %s\n"
1143msgstr "'%s' falló en la biblioteca '%s' en %s:%d con un error: %s\n"
1144
1145#: src/util/os/dso.c:162
1146#, fuzzy, c-format
1147msgid "`%s' failed to resolve method '%s' with error: %s\n"
1148msgstr "'%s' falló al resolver el método '%s%s' en %s:%d con un error: %s\n"
1149
1150#: src/util/os/statuscalls.c:197 src/util/os/statuscalls.c:342
1151#, fuzzy, c-format
1152msgid "Failed to parse interface data from `%s'.\n"
1153msgstr "Falló al pasar los datos de la interfaz de '%s' de %s:%d.\n"
1154
1155#: src/util/os/statuscalls.c:390 src/util/os/statuscalls.c:400
1156#, c-format
1157msgid ""
1158"No network interfaces defined in configuration section `%s' under `%s'!\n"
1159msgstr ""
1160
1161#: src/util/os/osconfig.c:153
1162msgid "Setting open descriptor limit not supported.\n"
1163msgstr ""
1164
1165#: src/util/os/osconfig.c:463 src/util/os/osconfig.c:492
1166#, fuzzy, c-format
1167msgid "Command `%s' failed with error code %u\n"
1168msgstr "'%s' falló con el código de error %s: %s"
1169
1170#: src/util/os/priority.c:78
1171#, fuzzy, c-format
1172msgid "Invalid process priority `%s'\n"
1173msgstr "Respuesta inválida a '%s'.\n"
1174
1175#: src/util/threads/semaphore.c:168 src/util/threads/pthread.c:157
1176#: src/util/threads/mutex.c:146
1177#, c-format
1178msgid "Real-time delay violation (%llu ms) at %s:%u\n"
1179msgstr ""
1180
1181#: src/util/threads/pthread.c:169 src/util/threads/pthread.c:176
1182#: src/util/threads/pthread.c:182 src/util/threads/pthread.c:276
1183#, fuzzy, c-format
1184msgid "`%s' failed with error code %s: %s\n"
1185msgstr "'%s' falló con el código de error %s: %s"
1186
1187#: src/util/threads/pthread.c:188 src/util/threads/pthread.c:286
1188#, fuzzy, c-format
1189msgid "`%s' failed with error code %d: %s\n"
1190msgstr "'%s' falló con el código de error %d: %s"
1191
1192#: src/util/threads/mutex.c:155 src/util/threads/mutex.c:201
1193#, fuzzy, c-format
1194msgid "Invalid argument for `%s'.\n"
1195msgstr "Argumento no válido: '%s'\n"
1196
1197#: src/util/threads/mutex.c:160
1198#, c-format
1199msgid "Deadlock due to `%s'.\n"
1200msgstr ""
1201
1202#: src/util/threads/mutex.c:187
1203#, c-format
1204msgid "Lock acquired for too long (%llu ms) at %s:%u\n"
1205msgstr ""
1206
1207#: src/util/threads/mutex.c:207
1208#, fuzzy, c-format
1209msgid "Permission denied for `%s'.\n"
1210msgstr "Permiso denegado para '%s' en %s:%d.\n"
1211
1212#: src/util/boot/startup.c:259
1213#, fuzzy, c-format
1214msgid "Failed to run %s: %s %d\n"
1215msgstr "Fallo al conectar a gnunetd.\n"
1216
1217#: src/util/string/string.c:55
1218msgid "ms"
1219msgstr "ms"
1220
1221#: src/util/string/string.c:61
1222msgid "s"
1223msgstr "s"
1224
1225#: src/util/string/string.c:65
1226msgid "m"
1227msgstr "m"
1228
1229#: src/util/string/string.c:69
1230msgid "h"
1231msgstr "h"
1232
1233#: src/util/string/string.c:73
1234msgid " days"
1235msgstr " días"
1236
1237#: src/util/string/string.c:89
1238msgid "b"
1239msgstr "b"
1240
1241#: src/util/string/string.c:95
1242msgid "KiB"
1243msgstr "KiB"
1244
1245#: src/util/string/string.c:99
1246msgid "MiB"
1247msgstr "MiB"
1248
1249#: src/util/string/string.c:103
1250msgid "GiB"
1251msgstr "GiB"
1252
1253#: src/util/string/string.c:107
1254msgid "TiB"
1255msgstr "TiB"
1256
1257#: src/util/string/string.c:226
1258msgid "Failed to expand `$HOME': environment variable `HOME' not set"
1259msgstr ""
1260
1261#: src/util/loggers/file.c:229
1262#, fuzzy, c-format
1263msgid "Failed to open log-file `%s': %s\n"
1264msgstr "Fichero almacenado en '%s'.\n"
1265
1266#: src/util/loggers/file.c:250
1267msgid "GNUnet error log"
1268msgstr ""
1269
1270#: src/util/loggers/memory.c:72
1271msgid "Out of memory (for logging)\n"
1272msgstr ""
1273
1274#: src/util/pseudonym/names.c:79
1275#, fuzzy
1276msgid "no-name"
1277msgstr "Mostrar el nombre"
1278
1279#: src/applications/datastore/datastore.c:183
1280#: src/applications/datastore/datastore.c:199
1281#, c-format
1282msgid "Availability test failed for `%s' at %s:%d.\n"
1283msgstr "Test de disponibilidad fallido para '%s' en %s:%d.\n"
1284
1285#: src/applications/datastore/datastore.c:401
1286msgid "# requests filtered by bloom filter"
1287msgstr ""
1288
1289#: src/applications/datastore/datastore.c:403
1290msgid "# bloom filter false positives"
1291msgstr ""
1292
1293#: src/applications/datastore/datastore.c:406
1294#, fuzzy
1295msgid "# bytes allowed in datastore"
1296msgstr "# bytes en la base de datos"
1297
1298#: src/applications/datastore/datastore.c:423
1299msgid "Failed to load state service. Trying to do without.\n"
1300msgstr ""
1301
1302#: src/applications/datastore/datastore.c:529
1303#, c-format
1304msgid "Datastore conversion at approximately %u%%\n"
1305msgstr ""
1306
1307#: src/applications/datastore/datastore.c:576
1308#, fuzzy, c-format
1309msgid "Starting datastore conversion (this may take a while).\n"
1310msgstr "Creando nueva clave local (esto puede llevar un tiempo).\n"
1311
1312#: src/applications/datastore/datastore.c:584
1313#, c-format
1314msgid "Completed datastore conversion.\n"
1315msgstr ""
1316
1317#: src/applications/datastore/datastore.c:592
1318#, fuzzy
1319msgid "Failed to load sqstore service. Check your configuration!\n"
1320msgstr "Imposible guardar la configuración"
1321
1322#: src/applications/rpc/rpc.c:339
1323#, fuzzy, c-format
1324msgid ""
1325"%s:%d - RPC %s:%p could not be registered: another callback is already using "
1326"this name (%p)\n"
1327msgstr ""
1328"%s::%s - RPC %s:%p no pudo ser registrada: otro evento está actualmente "
1329"usando este nombre (%p)\n"
1330
1331#: src/applications/rpc/rpc.c:398
1332#, fuzzy, c-format
1333msgid "%s:%d - async RPC %s:%p could not be unregistered: not found\n"
1334msgstr "%s::%s RPC asíncrona %s:%p no pudo ser desregistrada: no encontrada\n"
1335
1336#: src/applications/rpc/rpc.c:951
1337#, c-format
1338msgid "`%s' registering handlers %d %d %d\n"
1339msgstr "'%s' registrando manejadores %d %d %d\n"
1340
1341#: src/applications/rpc/rpc.c:972
1342#, c-format
1343msgid "Failed to initialize `%s' service.\n"
1344msgstr "Falló al inicializar el servicio '%s'.\n"
1345
1346#: src/applications/tbench/tbenchtest.c:53
1347#, c-format
1348msgid "Using %u messages of size %u for %u times.\n"
1349msgstr "Usando %u mensajes de un tamaño de %u durante %u veces.\n"
1350
1351#: src/applications/tbench/tbenchtest.c:85
1352#, c-format
1353msgid "Times: max %16llu min %16llu mean %12.3f variance %12.3f\n"
1354msgstr ""
1355
1356#: src/applications/tbench/tbenchtest.c:89
1357#, c-format
1358msgid "Loss: max %16u min %16u mean %12.3f variance %12.3f\n"
1359msgstr ""
1360
1361#: src/applications/tbench/tbenchtest.c:95
1362#, c-format
1363msgid ""
1364"\n"
1365"Failed to receive reply from gnunetd.\n"
1366msgstr ""
1367"\n"
1368"Fallo al recibir la respuesta de gnunetd.\n"
1369
1370#: src/applications/tbench/tbenchtest.c:149
1371#, c-format
1372msgid "Running benchmark...\n"
1373msgstr ""
1374
1375#: src/applications/tbench/tbench.c:422
1376msgid "allows profiling of direct peer-to-peer connections"
1377msgstr ""
1378
1379#: src/applications/tbench/gnunet-tbench.c:63
1380#: src/applications/tracekit/gnunet-tracekit.c:302
1381msgid "Start GNUnet transport benchmarking tool."
1382msgstr ""
1383
1384#: src/applications/tbench/gnunet-tbench.c:65
1385msgid "output in gnuplot format"
1386msgstr "salida en formato de gnuplot"
1387
1388#: src/applications/tbench/gnunet-tbench.c:69
1389msgid "number of iterations"
1390msgstr "número de repeticiones"
1391
1392#: src/applications/tbench/gnunet-tbench.c:73
1393msgid "number of messages to use per iteration"
1394msgstr "número de mensajes a usar por iteración"
1395
1396#: src/applications/tbench/gnunet-tbench.c:76
1397msgid "receiver host identifier (ENC file name)"
1398msgstr ""
1399
1400#: src/applications/tbench/gnunet-tbench.c:79
1401msgid "message size"
1402msgstr "tamaño del mensaje"
1403
1404#: src/applications/tbench/gnunet-tbench.c:82
1405msgid "sleep for SPACE ms after each a message block"
1406msgstr "duerme durante SPACE ms después de cada bloque de mensajes"
1407
1408#: src/applications/tbench/gnunet-tbench.c:85
1409msgid "time to wait for the completion of an iteration (in ms)"
1410msgstr "tiempo para esperar hasta completar una iteración (en ms)"
1411
1412#: src/applications/tbench/gnunet-tbench.c:90
1413msgid "number of messages in a message block"
1414msgstr "número de mensajes en un bloque de mensajes"
1415
1416#: src/applications/tbench/gnunet-tbench.c:126
1417#: src/applications/tracekit/gnunet-tracekit.c:352
1418#: src/applications/tracekit/tracekittest.c:133
1419#: src/applications/template/gnunet-template.c:95
1420#: src/applications/stats/gnunet-stats.c:121
1421#: src/applications/vpn/gnunet-vpn.c:154
1422#, c-format
1423msgid "Error establishing connection with gnunetd.\n"
1424msgstr "Se produjo un error estableciendo conexión con gnunetd.\n"
1425
1426#: src/applications/tbench/gnunet-tbench.c:142
1427#, c-format
1428msgid "You must specify a receiver!\n"
1429msgstr "¡Debes especificar un receptor!\n"
1430
1431#: src/applications/tbench/gnunet-tbench.c:152
1432#, c-format
1433msgid "Invalid receiver peer ID specified (`%s' is not valid name).\n"
1434msgstr ""
1435"ID del par receptor especificada no válida ('%s' no es un nombre válido).\n"
1436
1437#: src/applications/tbench/gnunet-tbench.c:189
1438#, c-format
1439msgid "Time:\n"
1440msgstr "Tiempo:\n"
1441
1442#: src/applications/tbench/gnunet-tbench.c:190
1443#, c-format
1444msgid "\tmax %llums\n"
1445msgstr "\tmax %llums\n"
1446
1447#: src/applications/tbench/gnunet-tbench.c:191
1448#, c-format
1449msgid "\tmin %llums\n"
1450msgstr "\tmin %llums\n"
1451
1452#: src/applications/tbench/gnunet-tbench.c:192
1453#, c-format
1454msgid "\tmean %8.4fms\n"
1455msgstr "\tmean %8.4fms\n"
1456
1457#: src/applications/tbench/gnunet-tbench.c:193
1458#, c-format
1459msgid "\tvariance %8.4fms\n"
1460msgstr "\tvariance %8.4fms\n"
1461
1462#: src/applications/tbench/gnunet-tbench.c:195
1463#, c-format
1464msgid "Loss:\n"
1465msgstr "Perdido:\n"
1466
1467#: src/applications/tbench/gnunet-tbench.c:196
1468#, c-format
1469msgid "\tmax %u\n"
1470msgstr "\tmax %u\n"
1471
1472#: src/applications/tbench/gnunet-tbench.c:197
1473#, c-format
1474msgid "\tmin %u\n"
1475msgstr "\tmin %u\n"
1476
1477#: src/applications/tbench/gnunet-tbench.c:198
1478#, c-format
1479msgid "\tmean %8.4f\n"
1480msgstr "\tmean %8.4f\n"
1481
1482#: src/applications/tbench/gnunet-tbench.c:199
1483#, c-format
1484msgid "\tvariance %8.4f\n"
1485msgstr "\tvariance %8.4f\n"
1486
1487#: src/applications/tbench/gnunet-tbench.c:205
1488#, c-format
1489msgid "Output format not known, this should not happen.\n"
1490msgstr "El formato de salida es desconocido, ésto no debería pasar.\n"
1491
1492#: src/applications/tbench/gnunet-tbench.c:211
1493#, c-format
1494msgid ""
1495"\n"
1496"Did not receive the message from gnunetd. Is gnunetd running?\n"
1497msgstr ""
1498"\n"
1499"No se recibió el mensaje de gnunetd. ¿Está gnunetd ejecutandose?\n"
1500
1501#: src/applications/traffic/traffic.c:454
1502#, c-format
1503msgid "# bytes transmitted of type %d"
1504msgstr ""
1505
1506#: src/applications/traffic/traffic.c:470
1507#, c-format
1508msgid "# bytes received of type %d"
1509msgstr ""
1510
1511#: src/applications/traffic/traffic.c:489
1512#, fuzzy, c-format
1513msgid "# bytes received in plaintext of type %d"
1514msgstr "# bytes recibidos por TCP"
1515
1516#: src/applications/traffic/traffic.c:652
1517msgid "tracks bandwidth utilization by gnunetd"
1518msgstr ""
1519
1520#: src/applications/sqstore_sqlite/sqlite.c:218
1521#, fuzzy, c-format
1522msgid "Unable to initialize SQLite: %s.\n"
1523msgstr "Imposible inicializar SQLite.\n"
1524
1525#: src/applications/sqstore_sqlite/sqlite.c:434
1526#: src/applications/sqstore_sqlite/sqlite.c:469
1527#, c-format
1528msgid "Invalid data in %s. Trying to fix (by deletion).\n"
1529msgstr "Datos no válidos en %s. Intentando fijar (por borrado).\n"
1530
1531#: src/applications/sqstore_sqlite/sqlite.c:435
1532#: src/applications/sqstore_sqlite/sqlite.c:470
1533msgid "sqlite datastore"
1534msgstr "base de datos sqlite"
1535
1536#: src/applications/sqstore_sqlite/sqlite.c:1474
1537#: src/applications/sqstore_mysql/mysql.c:1078
1538msgid "# bytes in datastore"
1539msgstr "# bytes en la base de datos"
1540
1541#: src/applications/sqstore_sqlite/sqlite.c:1476
1542#, fuzzy
1543msgid "# bytes allocated by SQLite"
1544msgstr "# bytes en la base de datos"
1545
1546#: src/applications/sqstore_mysql/mysql.c:1085
1547#: src/applications/sqstore_mysql/mysql.c:1160
1548msgid ""
1549"Failed to load MySQL database module. Check that MySQL is running and "
1550"configured properly!\n"
1551msgstr ""
1552"Falló al cargar el modulo de la base de datos MySQL. ¡Comprueba que MySQL "
1553"esta ejecutandose y esta configurada correctamente!\n"
1554
1555#: src/applications/tracekit/gnunet-tracekit.c:104
1556#, c-format
1557msgid "`%s' connected to `%s'.\n"
1558msgstr "'%s' conectado a '%s'.\n"
1559
1560#: src/applications/tracekit/gnunet-tracekit.c:110
1561#: src/applications/tracekit/tracekittest.c:67
1562#, c-format
1563msgid "`%s' is not connected to any peer.\n"
1564msgstr "'%s' no esta conectado a ningún par.\n"
1565
1566#: src/applications/tracekit/gnunet-tracekit.c:295
1567msgid "probe network to the given DEPTH"
1568msgstr ""
1569
1570#: src/applications/tracekit/gnunet-tracekit.c:299
1571msgid ""
1572"specify output format; 0 for human readable output, 1 for dot, 2 for vcg"
1573msgstr ""
1574
1575#: src/applications/tracekit/gnunet-tracekit.c:306
1576#, fuzzy
1577msgid "use PRIORITY for the priority of the trace request"
1578msgstr "especifica la prioridad del contenido"
1579
1580#: src/applications/tracekit/gnunet-tracekit.c:310
1581msgid "wait DELAY seconds for replies"
1582msgstr ""
1583
1584#: src/applications/tracekit/gnunet-tracekit.c:344
1585#, c-format
1586msgid ""
1587"Format specification invalid. Use 0 for user-readable, 1 for dot, 2 for "
1588"vcg.\n"
1589msgstr ""
1590
1591#: src/applications/tracekit/tracekittest.c:60
1592#, fuzzy, c-format
1593msgid "`%.*s' connected to `%.*s'.\n"
1594msgstr "'%s' conectado a '%s'.\n"
1595
1596#: src/applications/tracekit/tracekit.c:440
1597msgid "allows mapping of the network topology"
1598msgstr ""
1599
1600#: src/applications/advertising/advertising_test.c:47
1601#: src/applications/hostlist/hostlisttest.c:40
1602#: src/applications/session/sessiontest.c:40
1603#: src/applications/session/sessiontest_nat_http.c:40
1604#: src/applications/session/sessiontest_nat.c:40
1605#: src/applications/stats/statistics.c:247
1606msgid "# of connected peers"
1607msgstr "# de pares conectados"
1608
1609#: src/applications/advertising/advertising.c:194
1610#, fuzzy, c-format
1611msgid "HELLO message from `%s' has an invalid signature. Dropping.\n"
1612msgstr "mensaje de saludo de '%s' inválido (firma inválida). Omitiendo.\n"
1613
1614#: src/applications/advertising/advertising.c:205
1615#, fuzzy
1616msgid "HELLO message has expiration too far in the future. Dropping.\n"
1617msgstr ""
1618"mensaje de saludo recibido inválido (tiempo superior al límite). Omitiendo.\n"
1619
1620#: src/applications/advertising/advertising.c:406
1621#, fuzzy
1622msgid "Could not send HELLO+PING, ping buffer full.\n"
1623msgstr "Imposible mandar ahora saludos+PING, buffer del ping lleno.\n"
1624
1625#: src/applications/advertising/advertising.c:429
1626msgid "Failed to create an advertisement for this peer. Will not send PING.\n"
1627msgstr ""
1628
1629#: src/applications/advertising/advertising.c:581
1630#, c-format
1631msgid "Advertising my transport %d to selected peers.\n"
1632msgstr "Anunciando mi transporte %d a los pares seleccionados.\n"
1633
1634#: src/applications/advertising/advertising.c:590
1635msgid ""
1636"Announcing ourselves pointless: no other peers are known to us so far.\n"
1637msgstr "Es inútil anunciarnos: no hay más pares que nos conozcan más allá.\n"
1638
1639#: src/applications/advertising/advertising.c:868
1640msgid "# Peer advertisements received"
1641msgstr "# Anuncios de los pares recibidos"
1642
1643#: src/applications/advertising/advertising.c:871
1644#, fuzzy
1645msgid "# Peer advertisements of type NAT received"
1646msgstr "# Anuncios de los pares recibidos"
1647
1648#: src/applications/advertising/advertising.c:874
1649#, fuzzy
1650msgid "# Peer advertisements confirmed via PONG"
1651msgstr "# Anuncios de los pares recibidos"
1652
1653#: src/applications/advertising/advertising.c:877
1654#, fuzzy
1655msgid "# Peer advertisements updating earlier HELLOs"
1656msgstr "# Anuncios de los pares recibidos"
1657
1658#: src/applications/advertising/advertising.c:880
1659#, fuzzy
1660msgid "# Peer advertisements discarded due to load"
1661msgstr "# Anuncios de los pares recibidos"
1662
1663#: src/applications/advertising/advertising.c:883
1664#, fuzzy
1665msgid "# Peer advertisements for unsupported transport"
1666msgstr "# Anuncios de los pares recibidos"
1667
1668#: src/applications/advertising/advertising.c:886
1669#, fuzzy
1670msgid "# Peer advertisements not confirmed due to ping busy"
1671msgstr "# Anuncios de los pares recibidos"
1672
1673#: src/applications/advertising/advertising.c:889
1674#, fuzzy
1675msgid "# Peer advertisements not confirmed due to lack of self ad"
1676msgstr "# Anuncios de los pares recibidos"
1677
1678#: src/applications/advertising/advertising.c:892
1679#, fuzzy
1680msgid "# Peer advertisements not confirmed due to send error"
1681msgstr "# Anuncios de los pares recibidos"
1682
1683#: src/applications/advertising/advertising.c:894
1684msgid "# Self advertisments transmitted"
1685msgstr "# Auto-anuncios transmitidos"
1686
1687#: src/applications/advertising/advertising.c:896
1688msgid "# Foreign advertisements forwarded"
1689msgstr "# Anuncios a extraños mandados"
1690
1691#: src/applications/advertising/advertising.c:898
1692#: src/applications/pingpong/pingpong.c:528
1693msgid "# plaintext PING messages sent"
1694msgstr "# mensajes de texto mandados por PING"
1695
1696#: src/applications/advertising/advertising.c:904
1697#: src/applications/session/connect.c:932
1698#, c-format
1699msgid "`%s' registering handler %d (plaintext and ciphertext)\n"
1700msgstr "'%s' registrando manejador %d (texto plano e hipertexto)\n"
1701
1702#: src/applications/advertising/advertising.c:922
1703msgid ""
1704"ensures that this peer is known by other peers and discovers other peers"
1705msgstr ""
1706"Asegura que este par es conocido por otros pares y descubre otros pares"
1707
1708#: src/applications/fragmentation/fragmentation.c:578
1709msgid "# messages defragmented"
1710msgstr "# mensajes defragmentados"
1711
1712#: src/applications/fragmentation/fragmentation.c:580
1713msgid "# messages fragmented"
1714msgstr "# mensajes fragmentados"
1715
1716#: src/applications/fragmentation/fragmentation.c:581
1717msgid "# fragments discarded"
1718msgstr "# fragmentos descartados"
1719
1720#: src/applications/fragmentation/fragmentation.c:592
1721#, c-format
1722msgid "`%s' registering handler %d\n"
1723msgstr "'%s' registrando manejador %d\n"
1724
1725#: src/applications/topology_default/topology.c:466
1726#, fuzzy, c-format
1727msgid "Could not read friends list `%s'\n"
1728msgstr "Imposible inicializar la aplicación '%s'\n"
1729
1730#: src/applications/topology_default/topology.c:485
1731#, c-format
1732msgid "Failed to read friends list from `%s'\n"
1733msgstr ""
1734
1735#: src/applications/topology_default/topology.c:505
1736msgid "Syntax error in topology specification, skipping bytes.\n"
1737msgstr ""
1738
1739#: src/applications/topology_default/topology.c:523
1740#, c-format
1741msgid "Syntax error in topology specification, skipping bytes `%s'.\n"
1742msgstr ""
1743
1744#: src/applications/topology_default/topology.c:535
1745msgid ""
1746"Fewer friends specified than required by minimum friend count. Will only "
1747"connect to friends.\n"
1748msgstr ""
1749
1750#: src/applications/topology_default/topology.c:543
1751msgid ""
1752"More friendly connections required than target total number of connections.\n"
1753msgstr ""
1754
1755#: src/applications/topology_default/topology.c:726
1756msgid "maintains GNUnet default mesh topology"
1757msgstr ""
1758
1759#: src/applications/chat/tools/gnunet-chat.c:107
1760msgid "anonymous"
1761msgstr ""
1762
1763#: src/applications/chat/tools/gnunet-chat.c:113
1764#, fuzzy, c-format
1765msgid "`%s' said: %s\n"
1766msgstr "'%s' %s falló: %s\n"
1767
1768#: src/applications/chat/tools/gnunet-chat.c:116
1769#: src/applications/chat/tools/gnunet-chat.c:119
1770#, fuzzy, c-format
1771msgid "`%s' said to you: %s\n"
1772msgstr "'%s' %s falló: %s\n"
1773
1774#: src/applications/chat/tools/gnunet-chat.c:122
1775#, fuzzy, c-format
1776msgid "`%s' said for sure: %s\n"
1777msgstr "'%s' %s falló: %s\n"
1778
1779#: src/applications/chat/tools/gnunet-chat.c:125
1780#, fuzzy, c-format
1781msgid "`%s' said to you for sure: %s\n"
1782msgstr "'%s' falló con el código de error %s: %s"
1783
1784#: src/applications/chat/tools/gnunet-chat.c:128
1785#, fuzzy, c-format
1786msgid "`%s' was confirmed that you received: %s\n"
1787msgstr "'%s' falló con el código de error %d: %s"
1788
1789#: src/applications/chat/tools/gnunet-chat.c:131
1790#, c-format
1791msgid "`%s' was confirmed that you and only you received: %s\n"
1792msgstr ""
1793
1794#: src/applications/chat/tools/gnunet-chat.c:134
1795#, c-format
1796msgid "`%s' was confirmed that you received from him or her: %s\n"
1797msgstr ""
1798
1799#: src/applications/chat/tools/gnunet-chat.c:139
1800#, c-format
1801msgid "`%s' was confirmed that you and only you received from him or her: %s\n"
1802msgstr ""
1803
1804#: src/applications/chat/tools/gnunet-chat.c:142
1805#, fuzzy, c-format
1806msgid "`%s' said off the record: %s\n"
1807msgstr "'%s' falló con el código de error %s: %s"
1808
1809#: src/applications/chat/tools/gnunet-chat.c:145
1810#, c-format
1811msgid "<%s> said using an unknown message type: %s\n"
1812msgstr ""
1813
1814#: src/applications/chat/tools/gnunet-chat.c:167
1815#, c-format
1816msgid "`%s' entered the room\n"
1817msgstr ""
1818
1819#: src/applications/chat/tools/gnunet-chat.c:167
1820#, c-format
1821msgid "`%s' left the room\n"
1822msgstr ""
1823
1824#: src/applications/chat/tools/gnunet-chat.c:239
1825#: src/applications/chat/tools/gnunet-chat.c:348
1826#, fuzzy, c-format
1827msgid "Failed to send message.\n"
1828msgstr "Falló al entregar el mensaje '%s'.\n"
1829
1830#: src/applications/chat/tools/gnunet-chat.c:265
1831#: src/applications/chat/tools/gnunet-chat.c:524
1832#, fuzzy, c-format
1833msgid "Joined room `%s' as user `%s'.\n"
1834msgstr "Respuesta inválida a '%s' del par '%s'.\n"
1835
1836#: src/applications/chat/tools/gnunet-chat.c:293
1837#, fuzzy, c-format
1838msgid "Changed username to `%s'.\n"
1839msgstr "Imposible cambiar el usuario/grupo a '%s': %s\n"
1840
1841#: src/applications/chat/tools/gnunet-chat.c:301
1842#, fuzzy, c-format
1843msgid "Unknown command `%s'.\n"
1844msgstr "Operación desconocida '%s'\n"
1845
1846#: src/applications/chat/tools/gnunet-chat.c:316
1847#, c-format
1848msgid "Syntax: /msg USERNAME MESSAGE"
1849msgstr ""
1850
1851#: src/applications/chat/tools/gnunet-chat.c:324
1852#, fuzzy, c-format
1853msgid "Unknown user `%s'\n"
1854msgstr "Operación desconocida '%s'\n"
1855
1856#: src/applications/chat/tools/gnunet-chat.c:339
1857#, c-format
1858msgid "User `%s' is currently not in the room!\n"
1859msgstr ""
1860
1861#: src/applications/chat/tools/gnunet-chat.c:361
1862#, fuzzy, c-format
1863msgid "Users in room `%s': "
1864msgstr "Fichero almacenado en '%s'.\n"
1865
1866#: src/applications/chat/tools/gnunet-chat.c:390
1867msgid ""
1868"Use `/join #roomname' to join a chat room. Joining a room will cause you to "
1869"leave the current room"
1870msgstr ""
1871
1872#: src/applications/chat/tools/gnunet-chat.c:393
1873msgid ""
1874"Use `/nick nickname' to change your nickname. This will cause you to leave "
1875"the current room and immediately rejoin it with the new name."
1876msgstr ""
1877
1878#: src/applications/chat/tools/gnunet-chat.c:396
1879msgid ""
1880"Use `/msg nickname message' to send a private message to the specified user"
1881msgstr ""
1882
1883#: src/applications/chat/tools/gnunet-chat.c:398
1884msgid "The `/notice' command is an alias for `/msg'"
1885msgstr ""
1886
1887#: src/applications/chat/tools/gnunet-chat.c:400
1888msgid "The `/query' command is an alias for `/msg'"
1889msgstr ""
1890
1891#: src/applications/chat/tools/gnunet-chat.c:402
1892msgid "Use `/quit' to terminate gnunet-chat"
1893msgstr ""
1894
1895#: src/applications/chat/tools/gnunet-chat.c:404
1896msgid "The `/leave' command is an alias for `/quit'"
1897msgstr ""
1898
1899#: src/applications/chat/tools/gnunet-chat.c:407
1900msgid "Use `/names' to list all of the current members in the chat room"
1901msgstr ""
1902
1903#: src/applications/chat/tools/gnunet-chat.c:409
1904msgid "Use `/help command' to get help for a specific command"
1905msgstr ""
1906
1907#: src/applications/chat/tools/gnunet-chat.c:457
1908msgid "Join a chat on GNUnet."
1909msgstr ""
1910
1911#: src/applications/chat/tools/gnunet-chat.c:461
1912msgid "set the nickname to use (required)"
1913msgstr ""
1914
1915#: src/applications/chat/tools/gnunet-chat.c:464
1916msgid "set the chat room to join"
1917msgstr ""
1918
1919#: src/applications/chat/tools/gnunet-chat.c:495
1920#, fuzzy, c-format
1921msgid "You must specify a nickname\n"
1922msgstr "¡Debes especificar un receptor!\n"
1923
1924#: src/applications/chat/tools/gnunet-chat.c:515
1925#, fuzzy, c-format
1926msgid "Failed to join room `%s'\n"
1927msgstr "Fichero almacenado en '%s'.\n"
1928
1929#: src/applications/chat/module/chat.c:325
1930#, fuzzy, c-format
1931msgid "`%s' registering CS handlers %d and %d\n"
1932msgstr "'%s' registrando manejadores %d y %d\n"
1933
1934#: src/applications/chat/module/chat.c:347
1935msgid "enables P2P-chat (incomplete)"
1936msgstr "Activa el chat P2P (incompleto)"
1937
1938#: src/applications/chat/lib/messaging.c:353
1939#: src/applications/identity/hostkey.c:122
1940#, fuzzy, c-format
1941msgid "Failed to access GNUnet home directory `%s'\n"
1942msgstr "Error en el formato del fichero (¿no es un directorio de GNUnet?)\n"
1943
1944#: src/applications/chat/lib/messaging.c:389
1945#, fuzzy, c-format
1946msgid "Existing key in file `%s' failed format check, creating new key.\n"
1947msgstr ""
1948"Se produjo un fallo al comprobar la clave local existente en el fichero '%"
1949"s', creando nueva clave local.\n"
1950
1951#: src/applications/chat/lib/messaging.c:399
1952#, fuzzy
1953msgid "Creating new key for this nickname (this may take a while).\n"
1954msgstr "Creando nueva clave local (esto puede llevar un tiempo).\n"
1955
1956#: src/applications/chat/lib/messaging.c:411
1957#, fuzzy
1958msgid "Done creating key.\n"
1959msgstr "Correcto al crear la clave local.\n"
1960
1961#: src/applications/dstore_mysql/dstore_mysql.c:471
1962#, fuzzy
1963msgid "Failed to initialize MySQL database connection for dstore.\n"
1964msgstr "Imposible inicializar SQLite.\n"
1965
1966#: src/applications/dstore_mysql/dstore_mysql.c:494
1967#: src/applications/dstore_sqlite/dstore.c:636
1968#, fuzzy
1969msgid "# bytes in dstore"
1970msgstr "# bytes en la base de datos"
1971
1972#: src/applications/dstore_mysql/dstore_mysql.c:496
1973#: src/applications/dstore_sqlite/dstore.c:638
1974#, fuzzy
1975msgid "# max bytes allowed in dstore"
1976msgstr "# bytes en la base de datos"
1977
1978#: src/applications/transport/transport.c:191
1979#, c-format
1980msgid ""
1981"Converting peer address to string failed, transport type %d not supported\n"
1982msgstr ""
1983
1984#: src/applications/transport/transport.c:246
1985#, c-format
1986msgid "Transport connection attempt failed, transport type %d not supported\n"
1987msgstr ""
1988
1989#: src/applications/transport/transport.c:299
1990#, c-format
1991msgid ""
1992"Transport failed to connect to peer `%s' (%u HELLOs known, none worked)\n"
1993msgstr ""
1994
1995#: src/applications/transport/transport.c:376
1996#, c-format
1997msgid "Transmission attempt failed, transport type %d unknown.\n"
1998msgstr ""
1999
2000#: src/applications/transport/transport.c:500
2001#, c-format
2002msgid "No transport of type %d known.\n"
2003msgstr ""
2004
2005#: src/applications/transport/transport.c:560
2006msgid "No transport succeeded in creating a hello!\n"
2007msgstr ""
2008
2009#: src/applications/transport/transport.c:761
2010#, fuzzy, c-format
2011msgid "Loading transports `%s'\n"
2012msgstr "Probando transporte(s) %s\n"
2013
2014#: src/applications/transport/transport.c:781
2015#, fuzzy, c-format
2016msgid "Could not load transport plugin `%s'\n"
2017msgstr "Imposible inicializar la aplicación '%s'\n"
2018
2019#: src/applications/transport/transport.c:795
2020#, c-format
2021msgid "Transport library `%s' did not provide required function '%s%s'.\n"
2022msgstr ""
2023"La biblioteca de transporte '%s' no provee la función '%s%s' requerida.\n"
2024
2025#: src/applications/transport/transport.c:824
2026#, fuzzy, c-format
2027msgid "Loaded transport `%s'\n"
2028msgstr "Transporte(s) disponible(s): %s\n"
2029
2030#: src/applications/transport/transport.c:836
2031#: src/server/gnunet-peer-info.c:252
2032#, c-format
2033msgid "I am peer `%s'.\n"
2034msgstr "Yo soy el par '%s'.\n"
2035
2036#: src/applications/dht/tools/dht_multipeer_test.c:80
2037#: src/applications/dht/tools/dht_twopeer_test.c:47
2038#: src/applications/dht/module/table.c:783
2039msgid "# dht connections"
2040msgstr ""
2041
2042#: src/applications/dht/tools/dht-query.c:54
2043#, fuzzy
2044msgid "Query (get KEY, put KEY VALUE) DHT table."
2045msgstr "Pregunta (coje KEY, pone KEY VALUE, borra KEY VALUE) a una tabla DHT."
2046
2047#: src/applications/dht/tools/dht-query.c:58
2048#, fuzzy
2049msgid "allow TIME ms to process a GET command"
2050msgstr "Reserva TIME ms para procesar cada comando"
2051
2052#: src/applications/dht/tools/dht-query.c:107
2053#, fuzzy, c-format
2054msgid "Issuing `%s(%s,%s)' command.\n"
2055msgstr "'%s(%s, %s)' falló.\n"
2056
2057#: src/applications/dht/tools/dht-query.c:142
2058#: src/applications/fs/tools/gnunet-auto-share.c:669
2059#, c-format
2060msgid "Failed to connect to gnunetd.\n"
2061msgstr "Fallo al conectar a gnunetd.\n"
2062
2063#: src/applications/dht/tools/dht-query.c:155
2064#, c-format
2065msgid "Command `%s' requires an argument (`%s').\n"
2066msgstr "El comando '%s' requiere un argumento ('%s').\n"
2067
2068#: src/applications/dht/tools/dht-query.c:172
2069#, c-format
2070msgid "Command `%s' requires two arguments (`%s' and `%s').\n"
2071msgstr "El comando '%s' requiere dos argumentos ('%s' y '%s').\n"
2072
2073#: src/applications/dht/tools/dht-query.c:183
2074#, c-format
2075msgid "Unsupported command `%s'. Aborting.\n"
2076msgstr "Comando inesperado '%s'. Abortando.\n"
2077
2078#: src/applications/dht/module/table.c:785
2079#, fuzzy
2080msgid "# dht discovery messages received"
2081msgstr "# mensajes PONG encriptados recibidos"
2082
2083#: src/applications/dht/module/table.c:787
2084msgid "# dht route host lookups performed"
2085msgstr ""
2086
2087#: src/applications/dht/module/table.c:789
2088#, fuzzy
2089msgid "# dht discovery messages sent"
2090msgstr "# mensajes PONG encriptados recibidos"
2091
2092#: src/applications/dht/module/routing.c:879
2093msgid "# dht replies routed"
2094msgstr ""
2095
2096#: src/applications/dht/module/routing.c:881
2097msgid "# dht requests routed"
2098msgstr ""
2099
2100#: src/applications/dht/module/routing.c:883
2101#, fuzzy
2102msgid "# dht get requests received"
2103msgstr "# mensajes PONG encriptados recibidos"
2104
2105#: src/applications/dht/module/routing.c:885
2106#, fuzzy
2107msgid "# dht put requests received"
2108msgstr "# bytes recibidos por TCP"
2109
2110#: src/applications/dht/module/routing.c:887
2111#, fuzzy
2112msgid "# dht results received"
2113msgstr "# bytes recibidos por TCP"
2114
2115#: src/applications/dht/module/routing.c:892
2116#, fuzzy, c-format
2117msgid "`%s' registering p2p handlers: %d %d %d\n"
2118msgstr "'%s' registrando manejadores %d %d %d\n"
2119
2120#: src/applications/dht/module/cs.c:122
2121#, c-format
2122msgid "`%s' failed. Terminating connection to client.\n"
2123msgstr "'%s' falló. Finalizando conexión con el cleinte.\n"
2124
2125#: src/applications/dht/module/cs.c:250
2126#, fuzzy, c-format
2127msgid "`%s' registering client handlers: %d %d\n"
2128msgstr "'%s' registrando un manejador de clientes %d\n"
2129
2130#: src/applications/dht/module/cs.c:273
2131msgid "Enables efficient non-anonymous routing"
2132msgstr ""
2133
2134#: src/applications/identity/hostkey.c:155
2135#, c-format
2136msgid ""
2137"Existing hostkey in file `%s' failed format check, creating new hostkey.\n"
2138msgstr ""
2139"Se produjo un fallo al comprobar la clave local existente en el fichero '%"
2140"s', creando nueva clave local.\n"
2141
2142#: src/applications/identity/hostkey.c:164
2143msgid "Creating new hostkey (this may take a while).\n"
2144msgstr "Creando nueva clave local (esto puede llevar un tiempo).\n"
2145
2146#: src/applications/identity/hostkey.c:176
2147msgid "Done creating hostkey.\n"
2148msgstr "Correcto al crear la clave local.\n"
2149
2150#: src/applications/identity/identity.c:333
2151#, c-format
2152msgid ""
2153"File `%s' in directory `%s' does not match naming convention. Removed.\n"
2154msgstr ""
2155"El fichero '%s' en el directorio '%s' no sigue la convención de nombres. "
2156"Eliminando.\n"
2157
2158#: src/applications/identity/identity.c:408
2159#, fuzzy, c-format
2160msgid "Still no peers found in `%s'!\n"
2161msgstr "¡Imposible descargar adecuadamente el servicio '%s'!\n"
2162
2163#: src/applications/identity/identity.c:731
2164#: src/applications/identity/identity.c:757
2165#, fuzzy, c-format
2166msgid "Removed file `%s' containing invalid HELLO data.\n"
2167msgstr "Borrando el fichero '%s' que contiene datos de saludo no válidos.\n"
2168
2169#: src/applications/identity/identity.c:809
2170#, c-format
2171msgid "Signature failed verification: peer `%s' not known.\n"
2172msgstr "La verificación de la firma falló: el par '%s' no es conocido.\n"
2173
2174#: src/applications/identity/identity.c:819
2175msgid "Signature failed verification: signature invalid.\n"
2176msgstr "Falló la verificación de la firma: firma no válida.\n"
2177
2178#: src/applications/identity/identity.c:935
2179#: src/applications/identity/identity.c:1058
2180#, c-format
2181msgid "Peer `%s' is currently strictly blacklisted (for another %llums).\n"
2182msgstr ""
2183
2184#: src/applications/identity/identity.c:1061
2185#, c-format
2186msgid "Peer `%s' is currently blacklisted (for another %llums).\n"
2187msgstr ""
2188
2189#: src/applications/pingpong/pingpong.c:134
2190#: src/applications/pingpong/pingpong.c:203
2191#: src/applications/pingpong/pingpong.c:273
2192#: src/applications/pingpong/pingpong.c:345
2193#, c-format
2194msgid "Received malformed `%s' message. Dropping.\n"
2195msgstr "Recibido el mensaje '%s' con un mal formato. Omitiendo.\n"
2196
2197#: src/applications/pingpong/pingpong.c:146
2198msgid "Received ping for another peer. Dropping.\n"
2199msgstr "Recibido ping de otro par. Omitiendo.\n"
2200
2201#: src/applications/pingpong/pingpong.c:215
2202#, fuzzy, c-format
2203msgid "Received PING from `%s' not destined for us!\n"
2204msgstr "¡Recibido PING no destinado a nosotros!\n"
2205
2206#: src/applications/pingpong/pingpong.c:315
2207#: src/applications/pingpong/pingpong.c:381
2208msgid ""
2209"Could not match PONG against any PING. Try increasing MAX_PING_PONG "
2210"constant.\n"
2211msgstr ""
2212
2213#: src/applications/pingpong/pingpong.c:425
2214msgid "Cannot create PING, table full. Try increasing MAX_PING_PONG.\n"
2215msgstr ""
2216
2217#: src/applications/pingpong/pingpong.c:518
2218msgid "# encrypted PONG messages received"
2219msgstr "# mensajes PONG encriptados recibidos"
2220
2221#: src/applications/pingpong/pingpong.c:520
2222msgid "# plaintext PONG messages received"
2223msgstr ""
2224
2225#: src/applications/pingpong/pingpong.c:522
2226msgid "# encrypted PING messages received"
2227msgstr ""
2228
2229#: src/applications/pingpong/pingpong.c:524
2230msgid "# PING messages created"
2231msgstr ""
2232
2233#: src/applications/pingpong/pingpong.c:526
2234#: src/applications/session/connect.c:926
2235msgid "# encrypted PONG messages sent"
2236msgstr ""
2237
2238#: src/applications/pingpong/pingpong.c:530
2239#: src/applications/session/connect.c:924
2240msgid "# encrypted PING messages sent"
2241msgstr ""
2242
2243#: src/applications/pingpong/pingpong.c:532
2244#, fuzzy
2245msgid "# plaintext PONG messages sent"
2246msgstr "# mensajes de texto mandados por PING"
2247
2248#: src/applications/pingpong/pingpong.c:536
2249#, fuzzy
2250msgid "# plaintext PONG transmissions failed"
2251msgstr "# mensajes de texto mandados por PING"
2252
2253#: src/applications/pingpong/pingpong.c:546
2254#, c-format
2255msgid "`%s' registering handlers %d %d (plaintext and ciphertext)\n"
2256msgstr "'%s' registrando manejadores %d %d (texto plano e hipertexto)\n"
2257
2258#: src/applications/hostlist/hostlist.c:165
2259#, fuzzy
2260msgid "# hostlist requests received"
2261msgstr "# mensajes PONG encriptados recibidos"
2262
2263#: src/applications/hostlist/hostlist.c:167
2264msgid "# hostlist HELLOs returned"
2265msgstr ""
2266
2267#: src/applications/hostlist/hostlist.c:169
2268msgid "# hostlist bytes returned"
2269msgstr ""
2270
2271#: src/applications/hostlist/hostlist.c:199
2272msgid "integrated HTTP hostlist server"
2273msgstr ""
2274
2275#: src/applications/session/connect.c:238
2276#, c-format
2277msgid "Session key from peer `%s' could not be verified.\n"
2278msgstr "La clave de sesión del par '%s' no pudo ser verificada.\n"
2279
2280#: src/applications/session/connect.c:282
2281#, fuzzy, c-format
2282msgid "Cannot encrypt sessionkey, peer `%s' not known!\n"
2283msgstr "¡Imposible encriptar la clave de sesión, otro par desconocido!\n"
2284
2285#: src/applications/session/connect.c:489
2286#, fuzzy, c-format
2287msgid "Could not create any HELLO for myself (have transports `%s')!\n"
2288msgstr "¡Imposible crear la clave local!\n"
2289
2290#: src/applications/session/connect.c:599
2291#, fuzzy, c-format
2292msgid "Session key received from peer `%s' has invalid format (discarded).\n"
2293msgstr "El mensaje recibido del par es inválido.\n"
2294
2295#: src/applications/session/connect.c:632
2296#, fuzzy, c-format
2297msgid "Session key received from peer `%s' is for `%s' and not for me!\n"
2298msgstr "El mensaje recibido del par es inválido.\n"
2299
2300#: src/applications/session/connect.c:659
2301#, c-format
2302msgid "Invalid `%s' message received from peer `%s'.\n"
2303msgstr "Mensaje '%s' inválido recibido del par '%s'.\n"
2304
2305#: src/applications/session/connect.c:670
2306#, c-format
2307msgid "setkey `%s' from `%s' fails CRC check (have: %u, want %u).\n"
2308msgstr ""
2309"el cambio de clave '%s' de '%s' falló al comprobar el CRC (dio: %u, esperado "
2310"%u).\n"
2311
2312#: src/applications/session/connect.c:728
2313#, fuzzy, c-format
2314msgid ""
2315"Error parsing encrypted session key from `%s', given message part size is "
2316"invalid.\n"
2317msgstr ""
2318"Error pasando la clave de sesión encriptada, el mensaje dado del tamaño de "
2319"las partes es inválido.\n"
2320
2321#: src/applications/session/connect.c:741
2322#, fuzzy, c-format
2323msgid "Unknown type in embedded message from `%s': %u (size: %u)\n"
2324msgstr "Tipo desconocido en el mensaje embebido: %u (tamaño: %u)\n"
2325
2326#: src/applications/session/connect.c:916
2327msgid "# session keys sent"
2328msgstr "# claves de la sesión mandadas"
2329
2330#: src/applications/session/connect.c:918
2331msgid "# session keys rejected"
2332msgstr "# claves de la sesión rechazadas"
2333
2334#: src/applications/session/connect.c:920
2335msgid "# session keys accepted"
2336msgstr "# claves de la sesión aceptadas"
2337
2338#: src/applications/session/connect.c:922
2339msgid "# sessions established"
2340msgstr "# sesiones establecidas"
2341
2342#: src/applications/fs/tools/gnunet-pseudonym.c:70
2343#: src/applications/fs/tools/gnunet-auto-share.c:199
2344#: src/applications/fs/tools/gnunet-insert.c:246
2345#: src/applications/fs/tools/gnunet-search.c:125
2346#: src/applications/fs/tools/gnunet-download.c:77
2347msgid "set the desired LEVEL of sender-anonymity"
2348msgstr "seleccione el NIVEL deseado de anonimato al enviar"
2349
2350#: src/applications/fs/tools/gnunet-pseudonym.c:73
2351msgid "automate creation of a namespace by starting a collection"
2352msgstr "creación automática de un espacio al empezar una colección"
2353
2354#: src/applications/fs/tools/gnunet-pseudonym.c:77
2355msgid "create a new pseudonym under the given NICKNAME"
2356msgstr "crea un nuevo pseudónimo bajo el APODO dado"
2357
2358#: src/applications/fs/tools/gnunet-pseudonym.c:80
2359msgid "delete the pseudonym with the given NICKNAME"
2360msgstr "borra el pseudónimo con el APODO dado"
2361
2362#: src/applications/fs/tools/gnunet-pseudonym.c:83
2363msgid "end automated building of a namespace (ends collection)"
2364msgstr ""
2365"finaliza la construcción automática de un espacio (finaliza la recolección)"
2366
2367#: src/applications/fs/tools/gnunet-pseudonym.c:85
2368msgid "Create new pseudonyms, delete pseudonyms or list existing pseudonyms."
2369msgstr ""
2370"Crea nuevos pseudónimos, borra pseudónimos o lista los pseudónimos "
2371"existentes."
2372
2373#: src/applications/fs/tools/gnunet-pseudonym.c:89
2374msgid ""
2375"use the given keyword to advertise the namespace (use when creating a new "
2376"pseudonym)"
2377msgstr ""
2378"usa la clave dada para anunciar el espacio (úsalo cuando crees un nuevo "
2379"pseudónimo)"
2380
2381#: src/applications/fs/tools/gnunet-pseudonym.c:92
2382#, fuzzy
2383msgid "specify metadata describing the namespace or collection"
2384msgstr ""
2385"finaliza la construcción automática de un espacio (finaliza la recolección)"
2386
2387#: src/applications/fs/tools/gnunet-pseudonym.c:96
2388msgid ""
2389"do not generate an advertisement for this namespace (use when creating a new "
2390"pseudonym)"
2391msgstr ""
2392"no genera un anuncio para este espacio (úsalo cuando crees un nuevo "
2393"pseudónimo)"
2394
2395#: src/applications/fs/tools/gnunet-pseudonym.c:99
2396msgid "do not list the pseudonyms from the pseudonym database"
2397msgstr "no listar los pseudónimos de la base de datos de pseudónimos"
2398
2399#: src/applications/fs/tools/gnunet-pseudonym.c:103
2400msgid ""
2401"specify IDENTIFIER to be the address of the entrypoint to content in the "
2402"namespace (use when creating a new pseudonym)"
2403msgstr ""
2404"especifica el IDENTIFIER para ser la dirección del punto de entrada al "
2405"contenido en el espacio (úsalo cuando crees un nuevo pseudónimo)"
2406
2407#: src/applications/fs/tools/gnunet-pseudonym.c:106
2408msgid "set the rating of a namespace"
2409msgstr "cambia la valoración de un espacio"
2410
2411#: src/applications/fs/tools/gnunet-pseudonym.c:141
2412#, c-format
2413msgid "Namespace `%s' has rating %d.\n"
2414msgstr "El espacio '%s' ha sido valorado con un %d.\n"
2415
2416#: src/applications/fs/tools/gnunet-pseudonym.c:143
2417#, c-format
2418msgid "Namespace `%s' (%s) has rating %d.\n"
2419msgstr "El espacio '%s' (%s) ha sido valorado con un %d.\n"
2420
2421#: src/applications/fs/tools/gnunet-pseudonym.c:175
2422#, c-format
2423msgid "\tRating (after update): %d\n"
2424msgstr "\tValoración (después de la actualización): %d\n"
2425
2426#: src/applications/fs/tools/gnunet-pseudonym.c:179
2427#: src/applications/fs/tools/gnunet-pseudonym.c:241
2428#: src/applications/fs/tools/gnunet-insert.c:101
2429#, fuzzy, c-format
2430msgid "\tUnknown namespace `%s'\n"
2431msgstr "Operación desconocida '%s'\n"
2432
2433#: src/applications/fs/tools/gnunet-pseudonym.c:217
2434#, c-format
2435msgid "Collection stopped.\n"
2436msgstr "Colección detenida.\n"
2437
2438#: src/applications/fs/tools/gnunet-pseudonym.c:219
2439#, c-format
2440msgid "Failed to stop collection (not active?).\n"
2441msgstr "Falló al parar la recolección (¿no está activa?).\n"
2442
2443#: src/applications/fs/tools/gnunet-pseudonym.c:230
2444#, c-format
2445msgid "Pseudonym `%s' deleted.\n"
2446msgstr "El pseudónimo '%s' fue borrado.\n"
2447
2448#: src/applications/fs/tools/gnunet-pseudonym.c:235
2449#, c-format
2450msgid "Error deleting pseudonym `%s' (does not exist?).\n"
2451msgstr "Error borrando el pseudónimo '%s' (¿no existe?).\n"
2452
2453#: src/applications/fs/tools/gnunet-pseudonym.c:256
2454#, fuzzy
2455msgid "Started collection.\n"
2456msgstr "Iniciada colección '%s'.\n"
2457
2458#: src/applications/fs/tools/gnunet-pseudonym.c:260
2459msgid "Failed to start collection.\n"
2460msgstr "Falló al comenzar la recolección.\n"
2461
2462#: src/applications/fs/tools/gnunet-pseudonym.c:296
2463#, fuzzy
2464msgid "Could not create namespace.\n"
2465msgstr "Imposible crear el espacio '%s' (¿existe?).\n"
2466
2467#: src/applications/fs/tools/gnunet-pseudonym.c:304
2468#, c-format
2469msgid "Namespace `%s' created (root: %s).\n"
2470msgstr "El espacio '%s' fue creado (root: %s).\n"
2471
2472#: src/applications/fs/tools/gnunet-pseudonym.c:321
2473#, fuzzy, c-format
2474msgid "You must specify a name for the collection (`%s' option).\n"
2475msgstr "Debes especificar un apodo (use la opción '%s').\n"
2476
2477#: src/applications/fs/tools/gnunet-pseudonym.c:329
2478#, c-format
2479msgid "Could not access namespace information.\n"
2480msgstr "Imposible acceder a la información del espacio.\n"
2481
2482#: src/applications/fs/tools/gnunet-directory.c:84
2483#, c-format
2484msgid "==> Directory `%s':\n"
2485msgstr "==> Directorio '%s':\n"
2486
2487#: src/applications/fs/tools/gnunet-directory.c:88
2488#, c-format
2489msgid "=\tError reading directory.\n"
2490msgstr "=\tError leyendo el directorio.\n"
2491
2492#: src/applications/fs/tools/gnunet-directory.c:118
2493#, c-format
2494msgid "File format error (not a GNUnet directory?)\n"
2495msgstr "Error en el formato del fichero (¿no es un directorio de GNUnet?)\n"
2496
2497#: src/applications/fs/tools/gnunet-directory.c:120
2498#, c-format
2499msgid "%d files found in directory.\n"
2500msgstr "%d ficheros encontrados en el directorio.\n"
2501
2502#: src/applications/fs/tools/gnunet-directory.c:135
2503msgid "Perform directory related operations."
2504msgstr "Realiza operaciones respecto al directorio."
2505
2506#: src/applications/fs/tools/gnunet-directory.c:138
2507msgid "remove all entries from the directory database and stop tracking URIs"
2508msgstr ""
2509"borra todas las entradas de la base de datos del directorio y detiene el "
2510"seguimiento de URIs"
2511
2512#: src/applications/fs/tools/gnunet-directory.c:142
2513msgid "list entries from the directory database"
2514msgstr "lista las entradas de la base de datos del directorio"
2515
2516#: src/applications/fs/tools/gnunet-directory.c:145
2517msgid "start tracking entries for the directory database"
2518msgstr "comienza a seguir las entradas de la base de datos del directorio"
2519
2520#: src/applications/fs/tools/gnunet-directory.c:168
2521#, c-format
2522msgid "Listed %d matching entries.\n"
2523msgstr "%d entradas encontradas.\n"
2524
2525#: src/applications/fs/tools/gnunet-auto-share.c:117
2526#, fuzzy, c-format
2527msgid "Upload of `%s' at %llu out of %llu bytes.\n"
2528msgstr "Descargado del fichero '%s' el %16llu de %16llu bytes(%8.3f kbps)\n"
2529
2530#: src/applications/fs/tools/gnunet-auto-share.c:130
2531#, fuzzy, c-format
2532msgid "Upload of `%s' complete, URI is `%s'.\n"
2533msgstr ""
2534"Subida de '%s' completada, la velocidad media de subida actual es %8.3f "
2535"kbps.\n"
2536
2537#: src/applications/fs/tools/gnunet-auto-share.c:139
2538#, fuzzy, c-format
2539msgid "Upload aborted.\n"
2540msgstr "Descarga abortada"
2541
2542#: src/applications/fs/tools/gnunet-auto-share.c:145
2543#, fuzzy, c-format
2544msgid "Error uploading file: %s\n"
2545msgstr ""
2546"\n"
2547"Error subiendo el fichero %s\n"
2548
2549#: src/applications/fs/tools/gnunet-auto-share.c:154
2550#, fuzzy, c-format
2551msgid "Starting upload of `%s'.\n"
2552msgstr "Iniciada colección '%s'.\n"
2553
2554#: src/applications/fs/tools/gnunet-auto-share.c:164
2555#, fuzzy, c-format
2556msgid "Uploading suspended.\n"
2557msgstr "¡Subida rechazada!"
2558
2559#: src/applications/fs/tools/gnunet-auto-share.c:179
2560#, fuzzy, c-format
2561msgid "Uploading `%s' resumed.\n"
2562msgstr "¡Subida rechazada!"
2563
2564#: src/applications/fs/tools/gnunet-auto-share.c:186
2565#, c-format
2566msgid "Unexpected event: %d\n"
2567msgstr ""
2568
2569#: src/applications/fs/tools/gnunet-auto-share.c:205
2570#, fuzzy
2571msgid ""
2572"run in debug mode; gnunet-auto-share will not daemonize and error messages "
2573"will be written to stderr instead of a logfile"
2574msgstr ""
2575"se ejecuta en modo de depuración; gnunetd no sera un demonio y los mensajes "
2576"de error serán escritos a través de stderr en vez de en un fichero de log"
2577
2578#: src/applications/fs/tools/gnunet-auto-share.c:211
2579#: src/applications/fs/tools/gnunet-insert.c:259
2580#, fuzzy
2581msgid ""
2582"do not use libextractor to add additional references to directory entries "
2583"and/or the published file"
2584msgstr ""
2585"usa libextractor para añadir referencias directas adicionales a las entradas "
2586"del directorio"
2587
2588#: src/applications/fs/tools/gnunet-auto-share.c:213
2589msgid "Automatically share a directory."
2590msgstr ""
2591
2592#: src/applications/fs/tools/gnunet-auto-share.c:216
2593#: src/applications/fs/tools/gnunet-insert.c:273
2594msgid ""
2595"add an additional keyword for all files and directories (this option can be "
2596"specified multiple times)"
2597msgstr ""
2598"añade una clave adicional para todos los ficheros y directorios (esta opción "
2599"puede ser especificada varias veces)"
2600
2601#: src/applications/fs/tools/gnunet-auto-share.c:221
2602#: src/applications/fs/tools/gnunet-insert.c:290
2603msgid "specify the priority of the content"
2604msgstr "especifica la prioridad del contenido"
2605
2606#: src/applications/fs/tools/gnunet-auto-share.c:468
2607#: src/applications/fs/tools/gnunet-auto-share.c:903
2608#, fuzzy, c-format
2609msgid "Could not access `%s': %s\n"
2610msgstr "Imposible ejecutar '%s': %s\n"
2611
2612#: src/applications/fs/tools/gnunet-auto-share.c:547
2613#, c-format
2614msgid "Unknown keyword type `%s' in metadata configuration\n"
2615msgstr ""
2616
2617#: src/applications/fs/tools/gnunet-auto-share.c:652
2618#, fuzzy, c-format
2619msgid "Failed to stop running gnunet-auto-share.\n"
2620msgstr "Fallo al conectar a gnunetd.\n"
2621
2622#: src/applications/fs/tools/gnunet-auto-share.c:918
2623#, c-format
2624msgid "Directory `%s' is already on the list of shared directories.\n"
2625msgstr ""
2626
2627#: src/applications/fs/tools/gnunet-auto-share.c:939
2628msgid ""
2629"The specified directories were added to the list of shared directories.\n"
2630msgstr ""
2631
2632#: src/applications/fs/tools/gnunet-auto-share.c:961
2633#, fuzzy, c-format
2634msgid "Could not open logfile `%s': %s\n"
2635msgstr "Fichero almacenado en '%s'.\n"
2636
2637#: src/applications/fs/tools/gnunet-insert.c:115
2638#, c-format
2639msgid "Created entry `%s' in namespace `%s'\n"
2640msgstr "Creada la entrada '%s' en el espacio '%s'\n"
2641
2642#: src/applications/fs/tools/gnunet-insert.c:120
2643#, c-format
2644msgid "Failed to add entry to namespace `%s' (does it exist?)\n"
2645msgstr "Fallo al añadir la entrada al espacio '%s' (¿existe?)\n"
2646
2647#: src/applications/fs/tools/gnunet-insert.c:135
2648#, c-format
2649msgid "Keywords for file `%s':\n"
2650msgstr "Claves para los ficheros '%s':\n"
2651
2652#: src/applications/fs/tools/gnunet-insert.c:144
2653msgid "filename"
2654msgstr ""
2655
2656#: src/applications/fs/tools/gnunet-insert.c:146
2657msgid "mimetype"
2658msgstr ""
2659
2660#: src/applications/fs/tools/gnunet-insert.c:186
2661#, fuzzy, c-format
2662msgid "%16llu of %16llu bytes inserted (estimating %6s to completion) - %s\n"
2663msgstr "%16llu de %16llu bytes insertados (%s estimado para completar)\n"
2664
2665#: src/applications/fs/tools/gnunet-insert.c:198
2666#, fuzzy, c-format
2667msgid "Upload of `%s' complete, %llu bytes took %llu seconds (%8.3f KiB/s).\n"
2668msgstr ""
2669"Subida de '%s' completada, %llu bytes tomaron %llu segundos (%8.3f kbps).\n"
2670
2671#: src/applications/fs/tools/gnunet-insert.c:209
2672#, c-format
2673msgid "File `%s' has URI: %s\n"
2674msgstr "El fichero '%s' tiene la URI: '%s'\n"
2675
2676#: src/applications/fs/tools/gnunet-insert.c:220
2677#, fuzzy, c-format
2678msgid ""
2679"\n"
2680"Upload aborted.\n"
2681msgstr "Descarga abortada"
2682
2683#: src/applications/fs/tools/gnunet-insert.c:225
2684#, fuzzy, c-format
2685msgid ""
2686"\n"
2687"Error uploading file: %s"
2688msgstr ""
2689"\n"
2690"Error subiendo el fichero %s\n"
2691
2692#: src/applications/fs/tools/gnunet-insert.c:234
2693#, c-format
2694msgid ""
2695"\n"
2696"Unexpected event: %d\n"
2697msgstr ""
2698
2699#: src/applications/fs/tools/gnunet-insert.c:250
2700msgid ""
2701"even if gnunetd is running on the local machine, force the creation of a "
2702"copy instead of making a link to the GNUnet share directory"
2703msgstr ""
2704"aunque gnunetd este corriendo en el ordenador local, fuerza la creación de "
2705"una copia en vez de hacer un enlace al directorio para compartir de GNUnet"
2706
2707#: src/applications/fs/tools/gnunet-insert.c:255
2708msgid "disable adding the creation time to the metadata of the uploaded file"
2709msgstr ""
2710
2711#: src/applications/fs/tools/gnunet-insert.c:263
2712msgid ""
2713"print list of extracted keywords that would be used, but do not perform "
2714"upload"
2715msgstr ""
2716"imprime la lista de las claves extraidas que podrían ser usadas, pero no "
2717"realiza la subida"
2718
2719#: src/applications/fs/tools/gnunet-insert.c:265
2720msgid "Make files available to GNUnet for sharing."
2721msgstr "Permite a GNUnet disponer de los ficheros para compartirlos."
2722
2723#: src/applications/fs/tools/gnunet-insert.c:269
2724msgid ""
2725"add an additional keyword for the top-level file or directory (this option "
2726"can be specified multiple times)"
2727msgstr ""
2728"añade una clave adicional para el fichero del nivel más alto o el directorio "
2729"(esta opción puede ser especificada varias veces)"
2730
2731#: src/applications/fs/tools/gnunet-insert.c:278
2732msgid "set the meta-data for the given TYPE to the given VALUE"
2733msgstr "cambia el meta-dato para el TIPO dado al VALOR dado"
2734
2735#: src/applications/fs/tools/gnunet-insert.c:281
2736msgid ""
2737"do not index, perform full insertion (stores entire file in encrypted form "
2738"in GNUnet database)"
2739msgstr ""
2740"no indexar, hacer inserciones totales (almacena el fichero entero de forma "
2741"encriptada en la base de datos de GNUnet)"
2742
2743#: src/applications/fs/tools/gnunet-insert.c:286
2744msgid ""
2745"specify ID of an updated version to be published in the future (for "
2746"namespace insertions only)"
2747msgstr ""
2748"especifica la ID de una versión actualizada para ser publicada en el futuro "
2749"(para inserciones en el espacio únicamente)"
2750
2751#: src/applications/fs/tools/gnunet-insert.c:294
2752msgid "publish the files under the pseudonym NAME (place file into namespace)"
2753msgstr ""
2754"publica los ficheros bajo el pseudónimo NOMBRE (coloca el fichero en el "
2755"espacio)"
2756
2757#: src/applications/fs/tools/gnunet-insert.c:297
2758msgid ""
2759"only simulte the process but do not do any actual publishing (useful to "
2760"compute URIs)"
2761msgstr ""
2762
2763#: src/applications/fs/tools/gnunet-insert.c:301
2764msgid ""
2765"set the ID of this version of the publication (for namespace insertions only)"
2766msgstr ""
2767"cambia la ID de esta versión de la publicación (para inserciones en el "
2768"espacio únicamente)"
2769
2770#: src/applications/fs/tools/gnunet-insert.c:305
2771msgid ""
2772"URI to be published (can be used instead of passing a file to add keywords "
2773"to the file with the respective URI)"
2774msgstr ""
2775
2776#: src/applications/fs/tools/gnunet-insert.c:342
2777#, fuzzy, c-format
2778msgid "You must specify one and only one filename for insertion.\n"
2779msgstr "Debes especificar uno y solo un fichero para desindexar.\n"
2780
2781#: src/applications/fs/tools/gnunet-insert.c:348
2782#, fuzzy, c-format
2783msgid "You must NOT specify an URI and a filename.\n"
2784msgstr "¡Debes especificar un receptor!\n"
2785
2786#: src/applications/fs/tools/gnunet-insert.c:354
2787#, c-format
2788msgid "Cannot extract metadata from a URI!\n"
2789msgstr ""
2790
2791#: src/applications/fs/tools/gnunet-insert.c:400
2792#, c-format
2793msgid "Could not access namespace `%s' (does not exist?).\n"
2794msgstr "Imposible acceder al espacio '%s' (¿no existe?).\n"
2795
2796#: src/applications/fs/tools/gnunet-insert.c:408
2797#, fuzzy, c-format
2798msgid "Option `%s' is required when using option `%s'.\n"
2799msgstr "La opción '%s' no tiene sentido sin la opción '%s'.\n"
2800
2801#: src/applications/fs/tools/gnunet-insert.c:419
2802#: src/applications/fs/tools/gnunet-insert.c:427
2803#, c-format
2804msgid "Option `%s' makes no sense without option `%s'.\n"
2805msgstr "La opción '%s' no tiene sentido sin la opción '%s'.\n"
2806
2807#: src/applications/fs/tools/gnunet-search.c:128
2808msgid "Search GNUnet for files."
2809msgstr "Buscar GNUnet en busca de ficheros."
2810
2811#: src/applications/fs/tools/gnunet-search.c:132
2812msgid "write encountered (decrypted) search results to FILENAME"
2813msgstr "escribe los resultados encontrados (desencriptados) a FILENAME"
2814
2815#: src/applications/fs/tools/gnunet-search.c:169
2816#, c-format
2817msgid "Error converting arguments to URI!\n"
2818msgstr "¡Se produjo un error al convertir los argumentos a una URI!\n"
2819
2820#: src/applications/fs/tools/gnunet-unindex.c:61
2821#, c-format
2822msgid ""
2823"%16llu of %16llu bytes unindexed (estimating %llu seconds to "
2824"completion) "
2825msgstr ""
2826"%16llu de %16llu bytes desindexados (estimados %llu segundos para "
2827"completar) "
2828
2829#: src/applications/fs/tools/gnunet-unindex.c:73
2830#, fuzzy, c-format
2831msgid ""
2832"\n"
2833"Unindexing of `%s' complete, %llu bytes took %llu seconds (%8.3f KiB/s).\n"
2834msgstr ""
2835"\n"
2836"El desindexado de '%s' se completó, %llu bytes tomaron %llu segundos (%8.3f "
2837"kbps).\n"
2838
2839#: src/applications/fs/tools/gnunet-unindex.c:88
2840#, c-format
2841msgid ""
2842"\n"
2843"Error unindexing file: %s\n"
2844msgstr ""
2845"\n"
2846"Error desindexando el fichero: %s\n"
2847
2848#: src/applications/fs/tools/gnunet-unindex.c:108
2849msgid "Unindex files."
2850msgstr "Desindexar los ficheros."
2851
2852#: src/applications/fs/tools/gnunet-unindex.c:145
2853#, fuzzy
2854msgid "Not enough arguments. You must specify a filename.\n"
2855msgstr ""
2856"Argumentos insuficientes. Debes especificar una URI de un fichero de GNUnet\n"
2857
2858#: src/applications/fs/tools/gnunet-unindex.c:163
2859#, c-format
2860msgid "`%s' failed. Is `%s' a file?\n"
2861msgstr "'%s' falló. ¿Es '%s' un fichero?\n"
2862
2863#: src/applications/fs/tools/gnunet-download.c:82
2864msgid ""
2865"download a GNUnet directory that has already been downloaded. Requires that "
2866"a filename of an existing file is specified instead of the URI. The "
2867"download will only download the top-level files in the directory unless the "
2868"`-R' option is also specified."
2869msgstr ""
2870
2871#: src/applications/fs/tools/gnunet-download.c:85
2872msgid "delete incomplete downloads (when aborted with CTRL-C)"
2873msgstr ""
2874
2875#: src/applications/fs/tools/gnunet-download.c:87
2876msgid "Download files from GNUnet."
2877msgstr "Descarga los ficheros de GNUnet"
2878
2879#: src/applications/fs/tools/gnunet-download.c:91
2880msgid "write the file to FILENAME"
2881msgstr "escribe el fichero al FICHERO"
2882
2883#: src/applications/fs/tools/gnunet-download.c:95
2884msgid "set the maximum number of parallel downloads that are allowed"
2885msgstr ""
2886
2887#: src/applications/fs/tools/gnunet-download.c:98
2888msgid "download a GNUnet directory recursively"
2889msgstr "descarga un directorio de GNUnet recursivamente"
2890
2891#: src/applications/fs/tools/gnunet-download.c:119
2892#, fuzzy, c-format
2893msgid "Download of file `%s' at %16llu out of %16llu bytes (%8.3f KiB/s)\n"
2894msgstr "Descargado del fichero '%s' el %16llu de %16llu bytes(%8.3f kbps)\n"
2895
2896#: src/applications/fs/tools/gnunet-download.c:133
2897#, fuzzy, c-format
2898msgid "Download aborted.\n"
2899msgstr "Descarga abortada"
2900
2901#: src/applications/fs/tools/gnunet-download.c:139
2902#, c-format
2903msgid "Error downloading: %s\n"
2904msgstr "Error descargando: %s\n"
2905
2906#: src/applications/fs/tools/gnunet-download.c:145
2907#, fuzzy, c-format
2908msgid "Download of file `%s' complete. Speed was %8.3f KiB per second.\n"
2909msgstr ""
2910"Descarga del fichero '%s' completada. La velocidad media fue %8.3fkilobytes "
2911"por segundo.\n"
2912
2913#: src/applications/fs/tools/gnunet-download.c:191
2914msgid "no name given"
2915msgstr ""
2916
2917#: src/applications/fs/tools/gnunet-download.c:197
2918#, fuzzy, c-format
2919msgid "Starting download `%s'\n"
2920msgstr "Iniciada colección '%s'.\n"
2921
2922#: src/applications/fs/tools/gnunet-download.c:239
2923msgid "Not enough arguments. You must specify a GNUnet file URI\n"
2924msgstr ""
2925"Argumentos insuficientes. Debes especificar una URI de un fichero de GNUnet\n"
2926
2927#: src/applications/fs/tools/gnunet-download.c:257
2928#, c-format
2929msgid "URI `%s' invalid for gnunet-download.\n"
2930msgstr "La URI '%s' no es válida para una descarga-de-gnunet.\n"
2931
2932#: src/applications/fs/tools/gnunet-download.c:300
2933#, fuzzy, c-format
2934msgid "No filename specified, using `%s' instead (for now).\n"
2935msgstr "Ningún nombre especificado para la tabla, usando '%s'.\n"
2936
2937#: src/applications/fs/tools/gnunet-download.c:342
2938#, fuzzy, c-format
2939msgid "Could not access gnunet-directory file `%s'\n"
2940msgstr "Imposible pasar el fichero de configuración '%s'.\n"
2941
2942#: src/applications/fs/tools/gnunet-download.c:363
2943#, fuzzy, c-format
2944msgid "Downloading %d files from directory `%s'.\n"
2945msgstr "Descarga los ficheros de GNUnet"
2946
2947#: src/applications/fs/tools/gnunet-download.c:366
2948#, fuzzy, c-format
2949msgid "Did not find any files in directory `%s'\n"
2950msgstr "Falló al actualizar los datos del módulo '%s'\n"
2951
2952#: src/applications/fs/tools/gnunet-download.c:404
2953#, c-format
2954msgid "File stored as `%s'.\n"
2955msgstr "Fichero almacenado en '%s'.\n"
2956
2957#: src/applications/fs/uritrack/file_info.c:98
2958msgid "Collecting file identifiers disabled.\n"
2959msgstr "Recolección de identificadores de fichero desactivada.\n"
2960
2961#: src/applications/fs/uritrack/file_info.c:377
2962#, c-format
2963msgid "Deleted corrupt URI database in `%s'."
2964msgstr "Borrada base de datos de URIs corrupta en '%s'."
2965
2966#: src/applications/fs/ecrs/upload.c:158
2967#, c-format
2968msgid "`%s' is not a file.\n"
2969msgstr "'%s' no es un fichero.\n"
2970
2971#: src/applications/fs/ecrs/upload.c:166
2972#, c-format
2973msgid "Cannot get size of file `%s'"
2974msgstr "Imposible determinar el tamaño del fichero '%s'"
2975
2976#: src/applications/fs/ecrs/upload.c:175
2977msgid "Failed to connect to gnunetd."
2978msgstr "Fallo al conectarse a gnunetd"
2979
2980#: src/applications/fs/ecrs/upload.c:187
2981#, c-format
2982msgid "Cannot hash `%s'.\n"
2983msgstr "Imposible hallar el hash de '%s'.\n"
2984
2985#: src/applications/fs/ecrs/upload.c:215
2986#, c-format
2987msgid "Initialization for indexing file `%s' failed.\n"
2988msgstr ""
2989"Durante la inicialización de la indexación del fichero '%s' se produjo un "
2990"fallo.\n"
2991
2992#: src/applications/fs/ecrs/upload.c:223
2993#, fuzzy, c-format
2994msgid "Indexing file `%s' failed. Suggestion: try to insert the file.\n"
2995msgstr "Indexación del fichero '%s' fallida. Intentando insertar fichero...\n"
2996
2997#: src/applications/fs/ecrs/upload.c:237
2998#, fuzzy, c-format
2999msgid "Cannot open file `%s': `%s'"
3000msgstr "Imposible abrir el fichero de configuración '%s'.\n"
3001
3002#: src/applications/fs/ecrs/upload.c:322
3003#, fuzzy, c-format
3004msgid "Indexing data of file `%s' failed at position %llu.\n"
3005msgstr "La indexación de los datos falló en la posición %i.\n"
3006
3007#: src/applications/fs/ecrs/helper.c:91
3008msgid "No keywords specified!\n"
3009msgstr "¡Ninguna clave especificada!\n"
3010
3011#: src/applications/fs/ecrs/helper.c:99
3012msgid "Number of double-quotes not balanced!\n"
3013msgstr ""
3014
3015#: src/applications/fs/ecrs/helper.c:398
3016#, c-format
3017msgid "Renaming of file `%s' to `%s' failed: %s\n"
3018msgstr "Al renombrar el fichero '%s' a '%s' se produjo un fallo: %s\n"
3019
3020#: src/applications/fs/ecrs/helper.c:408
3021#, c-format
3022msgid "Could not rename file `%s' to `%s': file exists\n"
3023msgstr "Imposible renombrar el fichero '%s' a '%s': el fichero ya existe\n"
3024
3025#: src/applications/fs/ecrs/parser.c:165
3026#, c-format
3027msgid ""
3028"Unknown metadata type in metadata option `%s'. Using metadata type "
3029"`unknown' instead.\n"
3030msgstr ""
3031"Tipo de metadatos desconocido en la opción de metadatos '%s'. Usando el "
3032"tipo de metadatos 'desconocido' en su lugar.\n"
3033
3034#: src/applications/fs/ecrs/search.c:152
3035msgid "CHK URI not allowed for search.\n"
3036msgstr "CHK URI no autorizado para buscar.\n"
3037
3038#: src/applications/fs/ecrs/search.c:207
3039msgid "LOC URI not allowed for search.\n"
3040msgstr "LOC URI no autorizado para buscar.\n"
3041
3042#: src/applications/fs/ecrs/namespace.c:365
3043#, c-format
3044msgid "File `%s' does not contain a pseudonym.\n"
3045msgstr "El fichero '%s' no contiene un pseudónimo.\n"
3046
3047#: src/applications/fs/ecrs/namespace.c:376
3048#, c-format
3049msgid "Format of pseudonym `%s' is invalid.\n"
3050msgstr "Formato del pseudónimo '%s' no es válido.\n"
3051
3052#: src/applications/fs/ecrs/namespace.c:535
3053#: src/applications/fs/ecrs/namespace.c:547
3054#: src/applications/fs/ecrs/namespace.c:559
3055#, fuzzy, c-format
3056msgid "Format of file `%s' is invalid, trying to remove.\n"
3057msgstr "El formato del fichero '%s' no es válido.\n"
3058
3059#: src/applications/fs/ecrs/download.c:599
3060msgid ""
3061"Decrypted content does not match key. This is either a bug or a maliciously "
3062"inserted file. Download aborted.\n"
3063msgstr ""
3064"El contenido desencriptado no encuentra una clave. Esto puede ser un bug o "
3065"un fichero introducido maliciosamente. Descarga abortada.\n"
3066
3067#: src/applications/fs/ecrs/download.c:609
3068msgid "IO error."
3069msgstr ""
3070
3071#: src/applications/fs/collection/collection.c:559
3072#: src/applications/fs/collection/collection.c:562
3073#, c-format
3074msgid "Revision %u"
3075msgstr ""
3076
3077#: src/applications/fs/fsui/upload.c:330
3078#, fuzzy
3079msgid "Application aborted."
3080msgstr "_Opciones"
3081
3082#: src/applications/fs/fsui/upload.c:344
3083#, fuzzy
3084msgid "Failed to create temporary directory."
3085msgstr "Error en el formato del fichero (¿no es un directorio de GNUnet?)\n"
3086
3087#: src/applications/fs/fsui/deserialize.c:927
3088#, c-format
3089msgid "FSUI state file `%s' had syntax error at offset %u.\n"
3090msgstr ""
3091"Fichero del estado de FSUI '%s' tiene un error de sintáxis en la asignación %"
3092"u.\n"
3093
3094#: src/applications/fs/fsui/unindex.c:114
3095msgid "Unindexing failed (no reason given)"
3096msgstr ""
3097
3098#: src/applications/fs/gap/plan.c:944
3099msgid "# gap requests total sent"
3100msgstr ""
3101
3102#: src/applications/fs/gap/plan.c:946
3103msgid "# gap content total planned"
3104msgstr ""
3105
3106#: src/applications/fs/gap/plan.c:948
3107msgid "# gap routes succeeded"
3108msgstr ""
3109
3110#: src/applications/fs/gap/plan.c:949
3111msgid "# trust spent"
3112msgstr ""
3113
3114#: src/applications/fs/gap/fs.c:157
3115msgid "Datastore full.\n"
3116msgstr ""
3117
3118#: src/applications/fs/gap/fs.c:831
3119msgid "# gap requests total received"
3120msgstr ""
3121
3122#: src/applications/fs/gap/fs.c:833
3123#, fuzzy
3124msgid "# gap requests dropped due to load"
3125msgstr "# Anuncios de los pares recibidos"
3126
3127#: src/applications/fs/gap/fs.c:835
3128msgid "# gap content total received"
3129msgstr ""
3130
3131#: src/applications/fs/gap/fs.c:837
3132msgid "# gap total trust awarded"
3133msgstr ""
3134
3135#: src/applications/fs/gap/fs.c:865
3136#, fuzzy, c-format
3137msgid ""
3138"`%s' registering client handlers %d %d %d %d %d %d %d %d and P2P handlers %d "
3139"%d\n"
3140msgstr "'%s' registrando manejadores de clientes %d %d %d %d %d %d %d %d %d\n"
3141
3142#: src/applications/fs/gap/fs.c:921
3143msgid "enables (anonymous) file-sharing"
3144msgstr "activa la compartición de ficheros anónima"
3145
3146#: src/applications/fs/gap/ondemand.c:173
3147#, c-format
3148msgid ""
3149"Because the file `%s' has been unavailable for 3 days it got removed from "
3150"your share. Please unindex files before deleting them as the index now "
3151"contains invalid references!\n"
3152msgstr ""
3153"El fichero '%s' se ha eliminado de tus compartidos porque no ha estado "
3154"disponible durante tres días. Por favor, desindexa los ficheros antes de "
3155"borrarlos porque eso causa que el índice tenga referencias no válidas.\n"
3156
3157#: src/applications/fs/gap/ondemand.c:451
3158msgid "Indexed content changed (does not match its hash).\n"
3159msgstr ""
3160
3161#: src/applications/fs/gap/ondemand.c:569
3162#, fuzzy, c-format
3163msgid ""
3164"Unindexed ODB block `%s' from offset %llu already missing from datastore.\n"
3165msgstr ""
3166"Bloque ODB '%s' desindexado del offset %llu perdido de la base de datos.\n"
3167
3168#: src/applications/fs/gap/pid_table.c:177
3169msgid "# distinct interned peer IDs in pid table"
3170msgstr ""
3171
3172#: src/applications/fs/gap/pid_table.c:180
3173msgid "# total RC of interned peer IDs in pid table"
3174msgstr ""
3175
3176#: src/applications/fs/gap/querymanager.c:708
3177#, fuzzy
3178msgid "# gap client queries received"
3179msgstr "# mensajes PONG encriptados recibidos"
3180
3181#: src/applications/fs/gap/querymanager.c:710
3182msgid "# gap replies sent to clients"
3183msgstr ""
3184
3185#: src/applications/fs/gap/querymanager.c:712
3186#, fuzzy
3187msgid "# gap client requests tracked"
3188msgstr "# mensajes PONG encriptados recibidos"
3189
3190#: src/applications/fs/gap/querymanager.c:714
3191#, fuzzy
3192msgid "# gap client requests injected"
3193msgstr "# mensajes PONG encriptados recibidos"
3194
3195#: src/applications/fs/gap/querymanager.c:717
3196msgid "# gap query bloomfilter resizing updates"
3197msgstr ""
3198
3199#: src/applications/fs/gap/migration.c:437
3200msgid "# blocks migrated"
3201msgstr "# blocks migrados"
3202
3203#: src/applications/fs/gap/migration.c:439
3204#, fuzzy
3205msgid "# blocks injected for migration"
3206msgstr "# blocks migrados"
3207
3208#: src/applications/fs/gap/migration.c:441
3209#, fuzzy
3210msgid "# blocks fetched for migration"
3211msgstr "# blocks migrados"
3212
3213#: src/applications/fs/gap/migration.c:443
3214#, fuzzy
3215msgid "# on-demand fetches for migration"
3216msgstr "# blocks migrados"
3217
3218#: src/applications/fs/gap/gap.c:694
3219msgid "# gap queries dropped (table full)"
3220msgstr ""
3221
3222#: src/applications/fs/gap/gap.c:696
3223msgid "# gap queries dropped (redundant)"
3224msgstr ""
3225
3226#: src/applications/fs/gap/gap.c:698
3227msgid "# gap queries routed"
3228msgstr ""
3229
3230#: src/applications/fs/gap/gap.c:700
3231msgid "# gap content found locally"
3232msgstr ""
3233
3234#: src/applications/fs/gap/gap.c:703
3235msgid "# gap queries refreshed existing record"
3236msgstr ""
3237
3238#: src/applications/fs/gap/gap.c:704
3239msgid "# trust earned"
3240msgstr ""
3241
3242#: src/applications/fs/gap/fs_dht.c:256
3243msgid "# blocks pushed into DHT"
3244msgstr ""
3245
3246#: src/applications/fs/gap/anonymity.c:56
3247msgid "Failed to get traffic stats.\n"
3248msgstr "Fallo en las estadísticas del tráfico.\n"
3249
3250#: src/applications/testing/remote.c:68
3251#, c-format
3252msgid "scp command is : %s \n"
3253msgstr ""
3254
3255#: src/applications/testing/remote.c:491
3256#, fuzzy, c-format
3257msgid "Friend list of %s:%d\n"
3258msgstr "Fallo al conectar a gnunetd.\n"
3259
3260#: src/applications/testing/remote.c:513
3261#, c-format
3262msgid "scp command for friend file copy is : %s \n"
3263msgstr ""
3264
3265#: src/applications/testing/remote.c:535
3266#, fuzzy, c-format
3267msgid "connecting peer %s:%d to peer %s:%d\n"
3268msgstr "Imposible conectar a %u.%u.%u.%u:%u: %s\n"
3269
3270#: src/applications/testing/remotetest.c:38
3271msgid "Set up multiple gnunetd daemons across multiple hosts."
3272msgstr ""
3273
3274#: src/applications/testing/remotetest.c:43
3275#, fuzzy
3276msgid "set number of daemons to start"
3277msgstr "número de mensajes a usar por iteración"
3278
3279#: src/applications/testing/testing.c:268
3280#: src/applications/testing/remotetopologies.c:367
3281#, fuzzy, c-format
3282msgid "Waiting for peers to connect"
3283msgstr "Esperando a los pares para conectar (%u ciclos restantes)...\n"
3284
3285#: src/applications/testing/remotetopologies.c:213
3286#, c-format
3287msgid "Connecting nodes in 2d torus topology: %u rows %u columns\n"
3288msgstr ""
3289
3290#: src/applications/testing/remotetopologies.c:491
3291#, fuzzy, c-format
3292msgid "Failed to establish connection with peers.\n"
3293msgstr "Se produjo un error estableciendo conexión con gnunetd.\n"
3294
3295#: src/applications/bootstrap_http/http.c:113
3296#, fuzzy, c-format
3297msgid "Bootstrap data obtained from `%s' is invalid.\n"
3298msgstr "Formato del pseudónimo '%s' no es válido.\n"
3299
3300#: src/applications/bootstrap_http/http.c:126
3301#: src/applications/bootstrap_http/http.c:277
3302#: src/applications/bootstrap_http/http.c:294
3303#: src/applications/bootstrap_http/http.c:333
3304#: src/applications/bootstrap_http/http.c:352
3305#: src/applications/bootstrap_http/http.c:365
3306#: src/applications/bootstrap_http/http.c:375
3307#: src/applications/bootstrap_http/http.c:385 src/transports/upnp/upnp.c:356
3308#: src/transports/upnp/upnp.c:541 src/transports/http.c:1085
3309#: src/transports/http.c:1209 src/transports/http.c:1377
3310#: src/transports/http.c:1777 src/transports/http.c:1827
3311#, fuzzy, c-format
3312msgid "%s failed at %s:%d: `%s'\n"
3313msgstr "'%s' falló en %s: %d con error: '%s'.\n"
3314
3315#: src/applications/bootstrap_http/http.c:185
3316msgid "No hostlist URL specified in configuration, will not bootstrap.\n"
3317msgstr ""
3318
3319#: src/applications/bootstrap_http/http.c:226
3320#, c-format
3321msgid "Bootstrapping using `%s'.\n"
3322msgstr ""
3323
3324#: src/applications/bootstrap_http/http.c:254
3325#, c-format
3326msgid "Trying to download hostlist from `%s'\n"
3327msgstr ""
3328
3329#: src/applications/bootstrap_http/http.c:391
3330#, fuzzy, c-format
3331msgid "Downloaded %llu bytes from `%s'.\n"
3332msgstr "Descarga los ficheros de GNUnet"
3333
3334#: src/applications/bootstrap_http/http.c:425
3335#, fuzzy
3336msgid "# HELLOs downloaded via http"
3337msgstr "# saludos descargados vía HTTP"
3338
3339#: src/applications/getoption/getoption.c:78
3340#, c-format
3341msgid "`%s' registering client handler %d\n"
3342msgstr "'%s' registrando un manejador de clientes %d\n"
3343
3344#: src/applications/getoption/getoption.c:88
3345msgid "allows clients to determine gnunetd's configuration"
3346msgstr "permite a los clientes determinar la configuración de gnunetd"
3347
3348#: src/applications/template/template.c:70
3349#, c-format
3350msgid "`%s' registering client handler %d and %d\n"
3351msgstr "'%s' registrando manejador de clientes %d y %d\n"
3352
3353#: src/applications/template/gnunet-template.c:42
3354msgid "Template description."
3355msgstr ""
3356
3357#: src/applications/stats/clientapi.c:331
3358msgid "Uptime (seconds)"
3359msgstr ""
3360
3361#: src/applications/stats/sqstats.c:151
3362msgid "# Any-Blocks"
3363msgstr ""
3364
3365#: src/applications/stats/sqstats.c:152
3366msgid "# DBlocks"
3367msgstr ""
3368
3369#: src/applications/stats/sqstats.c:153
3370msgid "# SBlocks"
3371msgstr ""
3372
3373#: src/applications/stats/sqstats.c:154
3374msgid "# KBlocks"
3375msgstr ""
3376
3377#: src/applications/stats/sqstats.c:155
3378msgid "# NBlocks"
3379msgstr ""
3380
3381#: src/applications/stats/sqstats.c:156
3382msgid "# KNBlocks"
3383msgstr ""
3384
3385#: src/applications/stats/sqstats.c:157
3386msgid "# OnDemand-Blocks"
3387msgstr ""
3388
3389#: src/applications/stats/sqstats.c:158
3390msgid "# Unknown-Blocks"
3391msgstr ""
3392
3393#: src/applications/stats/sqstats.c:159
3394msgid "# expired"
3395msgstr ""
3396
3397#: src/applications/stats/sqstats.c:160
3398msgid "# expire in 1h"
3399msgstr ""
3400
3401#: src/applications/stats/sqstats.c:161
3402msgid "# expire in 24h"
3403msgstr ""
3404
3405#: src/applications/stats/sqstats.c:162
3406msgid "# expire in 1 week"
3407msgstr ""
3408
3409#: src/applications/stats/sqstats.c:163
3410msgid "# expire in 1 month"
3411msgstr ""
3412
3413#: src/applications/stats/sqstats.c:164
3414msgid "# zero priority"
3415msgstr ""
3416
3417#: src/applications/stats/sqstats.c:165
3418msgid "# priority one"
3419msgstr ""
3420
3421#: src/applications/stats/sqstats.c:166
3422msgid "# priority larger than one"
3423msgstr ""
3424
3425#: src/applications/stats/sqstats.c:167
3426msgid "# no anonymity"
3427msgstr ""
3428
3429#: src/applications/stats/sqstats.c:168
3430msgid "# anonymity one"
3431msgstr ""
3432
3433#: src/applications/stats/sqstats.c:169
3434msgid "# anonymity larger than one"
3435msgstr ""
3436
3437#: src/applications/stats/statistics.c:238
3438#, fuzzy, no-c-format
3439msgid "% of allowed network load (up)"
3440msgstr "% de red permitida para la subida"
3441
3442#: src/applications/stats/statistics.c:240
3443#, fuzzy, no-c-format
3444msgid "% of allowed network load (down)"
3445msgstr "% de red permitida para bajada"
3446
3447#: src/applications/stats/statistics.c:243
3448#, fuzzy, no-c-format
3449msgid "% of allowed cpu load"
3450msgstr "% de CPU permitida para el uso"
3451
3452#: src/applications/stats/statistics.c:246
3453#, fuzzy, no-c-format
3454msgid "% of allowed io load"
3455msgstr "% de CPU permitida para el uso"
3456
3457#: src/applications/stats/statistics.c:249
3458msgid "# bytes of noise received"
3459msgstr "# bytes de ruido recibidos"
3460
3461#: src/applications/stats/statistics.c:251
3462msgid "# plibc handles"
3463msgstr ""
3464
3465#: src/applications/stats/statistics.c:441
3466#, fuzzy, c-format
3467msgid "`%s' registering client handlers %d %d %d and p2p handler %d\n"
3468msgstr "'%s' registrando manejadores de clientes %d %d %d %d %d %d %d %d %d\n"
3469
3470#: src/applications/stats/statistics.c:463
3471msgid "keeps statistics about gnunetd's operation"
3472msgstr ""
3473
3474#: src/applications/stats/gnunet-stats.c:61
3475#, c-format
3476msgid "Supported peer-to-peer messages:\n"
3477msgstr "Mensajes P2P soportados:\n"
3478
3479#: src/applications/stats/gnunet-stats.c:64
3480#, c-format
3481msgid "Supported client-server messages:\n"
3482msgstr "Mensajes cliente-servidor soportados:\n"
3483
3484#: src/applications/stats/gnunet-stats.c:83
3485#: src/applications/vpn/gnunet-vpn.c:59
3486msgid "Print statistics about GNUnet operations."
3487msgstr "Imprime estadísticas acerca de las operaciones de GNUnet."
3488
3489#: src/applications/stats/gnunet-stats.c:87
3490msgid "prints supported protocol messages"
3491msgstr "imprime los mensajes del protocolo"
3492
3493#: src/applications/stats/gnunet-stats.c:136
3494#, c-format
3495msgid "Error reading information from gnunetd.\n"
3496msgstr "Se produjo un error leyendo información de gnunetd.\n"
3497
3498#: src/applications/vpn/gnunet-vpn.c:63
3499msgid "Suppress display of asynchronous log messages"
3500msgstr ""
3501
3502#: src/applications/vpn/p2p.c:75
3503msgid "VPN IP src not anonymous. drop..\n"
3504msgstr ""
3505
3506#: src/applications/vpn/p2p.c:83
3507msgid "VPN IP not anonymous, drop.\n"
3508msgstr ""
3509
3510#: src/applications/vpn/p2p.c:92
3511msgid "VPN Received, not anonymous, drop.\n"
3512msgstr ""
3513
3514#: src/applications/vpn/p2p.c:97
3515#, fuzzy, c-format
3516msgid "VPN Received unknown IP version %d...\n"
3517msgstr "Recibida petición de tipo desconocido %d en %s: %d\n"
3518
3519#: src/applications/vpn/p2p.c:110
3520#, c-format
3521msgid "<- GNUnet(%d) : %s\n"
3522msgstr ""
3523
3524#: src/applications/vpn/p2p.c:139
3525msgid "Could not write the tunnelled IP to the OS... Did to setup a tunnel?\n"
3526msgstr ""
3527
3528#: src/applications/vpn/p2p.c:183
3529msgid "Receive route request\n"
3530msgstr ""
3531
3532#: src/applications/vpn/p2p.c:193
3533#, c-format
3534msgid "Prepare route announcement level %d\n"
3535msgstr ""
3536
3537#: src/applications/vpn/p2p.c:208
3538#, c-format
3539msgid "Send route announcement %d with route announce\n"
3540msgstr ""
3541
3542#: src/applications/vpn/p2p.c:217
3543#, c-format
3544msgid "Send outside table info %d\n"
3545msgstr ""
3546
3547#: src/applications/vpn/p2p.c:239
3548msgid "Receive route announce.\n"
3549msgstr ""
3550
3551#: src/applications/vpn/p2p.c:247
3552msgid "Going to try insert route into local table.\n"
3553msgstr ""
3554
3555#: src/applications/vpn/p2p.c:256
3556#, c-format
3557msgid "Inserting with hops %d\n"
3558msgstr ""
3559
3560#: src/applications/vpn/p2p.c:273
3561#, c-format
3562msgid "Request level %d from peer %d\n"
3563msgstr ""
3564
3565#: src/applications/vpn/p2p.c:300
3566#, c-format
3567msgid "Receive table limit on peer reached %d\n"
3568msgstr ""
3569
3570#: src/applications/vpn/vpn.c:180
3571#, c-format
3572msgid "Not storing route to myself from peer %d\n"
3573msgstr ""
3574
3575#: src/applications/vpn/vpn.c:194
3576#, c-format
3577msgid "Duplicate route to node from peer %d, choosing minimum hops"
3578msgstr ""
3579
3580#: src/applications/vpn/vpn.c:230
3581#, c-format
3582msgid "Inserting route from peer %d in route table at location %d\n"
3583msgstr ""
3584
3585#: src/applications/vpn/vpn.c:247
3586#, c-format
3587msgid "RFC4193 Frame length %d is too big for GNUnet!\n"
3588msgstr ""
3589
3590#: src/applications/vpn/vpn.c:254
3591#, c-format
3592msgid "RFC4193 Frame length %d too small\n"
3593msgstr ""
3594
3595#: src/applications/vpn/vpn.c:273
3596#, c-format
3597msgid "RFC4193 Ethertype %x and IP version %x do not match!\n"
3598msgstr ""
3599
3600#: src/applications/vpn/vpn.c:289
3601#, c-format
3602msgid "RFC4193 Going to try and make a tunnel in slot %d\n"
3603msgstr ""
3604
3605#: src/applications/vpn/vpn.c:295
3606#, fuzzy, c-format
3607msgid "Cannot open tunnel device: %s"
3608msgstr "Imposible abrir el fichero de configuración '%s'.\n"
3609
3610#: src/applications/vpn/vpn.c:331
3611#, c-format
3612msgid "RFC4193 Create skips gnu%d as we are already using it\n"
3613msgstr ""
3614
3615#: src/applications/vpn/vpn.c:346
3616#, c-format
3617msgid "Cannot set tunnel name to %s because of %s\n"
3618msgstr ""
3619
3620#: src/applications/vpn/vpn.c:356
3621#, c-format
3622msgid "Configured tunnel name to %s\n"
3623msgstr ""
3624
3625#: src/applications/vpn/vpn.c:398
3626#, c-format
3627msgid "Cannot get socket flags for gnu%d because %s\n"
3628msgstr ""
3629
3630#: src/applications/vpn/vpn.c:408
3631#, c-format
3632msgid "Cannot set socket flags for gnu%d because %s\n"
3633msgstr ""
3634
3635#: src/applications/vpn/vpn.c:418
3636#, c-format
3637msgid "Cannot set MTU for gnu%d because %s\n"
3638msgstr ""
3639
3640#: src/applications/vpn/vpn.c:426
3641#, c-format
3642msgid "Cannot get interface index for gnu%d because %s\n"
3643msgstr ""
3644
3645#: src/applications/vpn/vpn.c:440
3646#, c-format
3647msgid "IPv6 ifaddr gnu%d - %x:%x:%x:%x:%x:%x:%x:%x/%d\n"
3648msgstr ""
3649
3650#: src/applications/vpn/vpn.c:455
3651#, fuzzy, c-format
3652msgid "Cannot set interface IPv6 address for gnu%d because %s\n"
3653msgstr "Imposible obtener la dirección IP para la interfaz '%s'.\n"
3654
3655#: src/applications/vpn/vpn.c:471
3656#, c-format
3657msgid "IPv6 route gnu%d - destination %x:%x:%x:%x:%x:%x:%x:%x/%d\n"
3658msgstr ""
3659
3660#: src/applications/vpn/vpn.c:485
3661#, fuzzy, c-format
3662msgid "Cannot add route IPv6 address for gnu%s because %s\n"
3663msgstr "Imposible obtener la dirección IP para la interfaz '%s'.\n"
3664
3665#: src/applications/vpn/vpn.c:528
3666msgid ""
3667"RFC4193 We have run out of memory and so I can't store a tunnel for this "
3668"peer.\n"
3669msgstr ""
3670
3671#: src/applications/vpn/vpn.c:579
3672#, c-format
3673msgid "RFC4193 Thread running (frame %d tunnel %d f2f %d) ...\n"
3674msgstr ""
3675
3676#: src/applications/vpn/vpn.c:661
3677#, c-format
3678msgid "VPN dropping connection %x\n"
3679msgstr ""
3680
3681#: src/applications/vpn/vpn.c:670
3682#, c-format
3683msgid "VPN cannot drop connection %x\n"
3684msgstr ""
3685
3686#: src/applications/vpn/vpn.c:690
3687msgid "RFC4193 Thread exiting\n"
3688msgstr ""
3689
3690#: src/applications/vpn/vpn.c:712
3691msgid "realise alloc ram\n"
3692msgstr ""
3693
3694#: src/applications/vpn/vpn.c:735
3695msgid "realise add routes\n"
3696msgstr ""
3697
3698#: src/applications/vpn/vpn.c:849
3699msgid "realise copy table\n"
3700msgstr ""
3701
3702#: src/applications/vpn/vpn.c:898
3703#, fuzzy, c-format
3704msgid "`%s' initialising RFC4913 module %d and %d\n"
3705msgstr "'%s' registrando manejadores %d y %d\n"
3706
3707#: src/applications/vpn/vpn.c:903
3708#, c-format
3709msgid "RFC4193 my First 4 hex digits of host id are %x\n"
3710msgstr ""
3711
3712#: src/applications/vpn/vpn.c:942
3713#, fuzzy
3714msgid "enables IPv6 over GNUnet (incomplete)"
3715msgstr "Activa el chat P2P (incompleto)"
3716
3717#: src/applications/vpn/vpn.c:963
3718msgid "RFC4193 Waiting for tun thread to end\n"
3719msgstr ""
3720
3721#: src/applications/vpn/vpn.c:978
3722msgid "RFC4193 The tun thread has ended\n"
3723msgstr ""
3724
3725#: src/applications/vpn/vpn.c:996
3726#, c-format
3727msgid "RFC4193 Closing tunnel %d fd %d\n"
3728msgstr ""
3729
3730#: src/server/core.c:119 src/server/core.c:318
3731#, c-format
3732msgid "Configuration value `%s' under [MODULES] for `%s' is invalid!\n"
3733msgstr ""
3734
3735#: src/server/core.c:140
3736#, c-format
3737msgid "Application module `%s' already initialized!\n"
3738msgstr "¡El módulo de la aplicación '%s' ya esta inicializado!\n"
3739
3740#: src/server/core.c:194
3741#, c-format
3742msgid "Failed to load plugin `%s' at %s:%d. Unloading plugin.\n"
3743msgstr "Falló al cargar el plugin '%s' en %s:%d. Descargando plugin.\n"
3744
3745#: src/server/core.c:244
3746#, c-format
3747msgid "Could not shutdown `%s': application not loaded\n"
3748msgstr "Imposible apagar '%s': aplicación no cargada\n"
3749
3750#: src/server/core.c:255
3751#, c-format
3752msgid "Could not shutdown application `%s': not initialized\n"
3753msgstr "Imposible apagar la aplicación '%s': no inicializada\n"
3754
3755#: src/server/core.c:265
3756#, c-format
3757msgid "Could not find '%s%s' method in library `%s'.\n"
3758msgstr "Imposible encontrar el método '%s%s' en la biblioteca '%s'.\n"
3759
3760#: src/server/core.c:422
3761#, c-format
3762msgid "Could not release %p: service not loaded\n"
3763msgstr ""
3764
3765#: src/server/core.c:531
3766#, c-format
3767msgid "Could not properly shutdown application `%s'.\n"
3768msgstr "Imposible apagar la aplicación '%s' adecuadamente.\n"
3769
3770#: src/server/core.c:676
3771#, c-format
3772msgid "Could not properly unload service `%s'!\n"
3773msgstr "¡Imposible descargar adecuadamente el servicio '%s'!\n"
3774
3775#: src/server/gnunet-update.c:146
3776#, c-format
3777msgid "Updating data for module `%s'\n"
3778msgstr "Actualizando los datos del módulo '%s'\n"
3779
3780#: src/server/gnunet-update.c:151
3781#, c-format
3782msgid "Failed to update data for module `%s'\n"
3783msgstr "Falló al actualizar los datos del módulo '%s'\n"
3784
3785#: src/server/gnunet-update.c:225 src/server/gnunetd.c:124
3786#, fuzzy
3787msgid "Core initialization failed.\n"
3788msgstr "Conexión fallida\n"
3789
3790#: src/server/gnunet-update.c:270
3791msgid "Updates GNUnet datastructures after version change."
3792msgstr ""
3793
3794#: src/server/gnunet-update.c:274 src/server/gnunet-transport-check.c:376
3795msgid "run as user LOGIN"
3796msgstr "ejecuta como el usuario LOGIN"
3797
3798#: src/server/gnunet-update.c:278
3799msgid "run in client mode (for getting client configuration values)"
3800msgstr ""
3801
3802#: src/server/version.c:125
3803msgid ""
3804"Failed to determine filename used to store GNUnet version information!\n"
3805msgstr ""
3806
3807#: src/server/gnunetd.c:85
3808#, c-format
3809msgid "`%s' startup complete.\n"
3810msgstr "'%s' comienzo completo.\n"
3811
3812#: src/server/gnunetd.c:89
3813#, c-format
3814msgid "`%s' is shutting down.\n"
3815msgstr "'%s' se esta cerrando.\n"
3816
3817#: src/server/gnunetd.c:179
3818msgid ""
3819"run in debug mode; gnunetd will not daemonize and error messages will be "
3820"written to stderr instead of a logfile"
3821msgstr ""
3822"se ejecuta en modo de depuración; gnunetd no sera un demonio y los mensajes "
3823"de error serán escritos a través de stderr en vez de en un fichero de log"
3824
3825#: src/server/gnunetd.c:183
3826msgid "Starts the gnunetd daemon."
3827msgstr "Arranca el demonio de gnunetd."
3828
3829#: src/server/gnunetd.c:186
3830msgid "disable padding with random data (experimental)"
3831msgstr ""
3832
3833#: src/server/gnunetd.c:190
3834msgid "print all log messages to the console (only works together with -d)"
3835msgstr ""
3836
3837#: src/server/gnunetd.c:194
3838#, fuzzy
3839msgid "specify username as which gnunetd should run"
3840msgstr "especifica el host en el que gnunetd esta ejecutandose"
3841
3842#: src/server/gnunetd.c:275
3843#, c-format
3844msgid "Configuration or GNUnet version changed. You need to run `%s'!\n"
3845msgstr ""
3846"La configuración o la versión de GNUnet cambiaron. ¡Debes ejecutar '%s'!\n"
3847
3848#: src/server/tcpserver.c:121
3849#, c-format
3850msgid "The `%s' request received from client is malformed.\n"
3851msgstr "La petición '%s' recibida del cliente esta mal formada.\n"
3852
3853#: src/server/tcpserver.c:409
3854#, fuzzy, c-format
3855msgid "`%s' failed for port %d. Is gnunetd already running?\n"
3856msgstr ""
3857"'%s' falló para el puerto %d: %s. ¿Está gnunet ejecutandose actualmente?\n"
3858
3859#: src/server/tcpserver.c:487 src/server/tcpserver.c:512
3860#, c-format
3861msgid ""
3862"Malformed network specification in the configuration in section `%s' for "
3863"entry `%s': %s\n"
3864msgstr ""
3865
3866#: src/server/tcpserver.c:572
3867#, fuzzy, c-format
3868msgid "Registering failed, message type %d already in use.\n"
3869msgstr "%s falló, el mensaje del tipo %d ya está en uso.\n"
3870
3871#: src/server/startup.c:219
3872#, fuzzy, c-format
3873msgid "Unable to obtain filesystem information for `%s': %u\n"
3874msgstr "Imposible guardar el fichero de configuración '%s': %s.\n"
3875
3876#: src/server/startup.c:237
3877#, c-format
3878msgid ""
3879"Filesystem `%s' of partition `%s' is unknown. Please contact gnunet-"
3880"developers@gnu.org!"
3881msgstr ""
3882
3883#: src/server/startup.c:252
3884#, c-format
3885msgid ""
3886"Limiting datastore size to %llu GB, because the `%s' filesystem does not "
3887"support larger files. Please consider storing the database on a NTFS "
3888"partition!\n"
3889msgstr ""
3890
3891#: src/server/startup.c:291
3892#, c-format
3893msgid "Insufficient access permissions for `%s': %s\n"
3894msgstr ""
3895
3896#: src/server/gnunet-peer-info.c:55
3897msgid "Print information about GNUnet peers."
3898msgstr "Imprime información de los pares de GNUnet."
3899
3900#: src/server/gnunet-peer-info.c:59
3901msgid "don't resolve host names"
3902msgstr ""
3903
3904#: src/server/gnunet-peer-info.c:62
3905msgid "output only the identity strings"
3906msgstr ""
3907
3908#: src/server/gnunet-peer-info.c:65
3909msgid "output our own identity only"
3910msgstr ""
3911
3912#: src/server/gnunet-peer-info.c:130 src/server/gnunet-peer-info.c:164
3913#, c-format
3914msgid "Could not get address of peer `%s'.\n"
3915msgstr "Imposible obtener la dirección del par '%s'.\n"
3916
3917#: src/server/gnunet-peer-info.c:143
3918#, fuzzy, c-format
3919msgid "`%s' message invalid (signature invalid).\n"
3920msgstr "mensaje de saludo inválido (firma no válida).\n"
3921
3922#: src/server/gnunet-peer-info.c:168
3923#, fuzzy, c-format
3924msgid "Peer `%s' with trust %8u\n"
3925msgstr "Par '%s' con credibilidad %8u y dirección '%s'\n"
3926
3927#: src/server/gnunet-peer-info.c:175
3928#, c-format
3929msgid "Peer `%s' with trust %8u and address `%s'\n"
3930msgstr "Par '%s' con credibilidad %8u y dirección '%s'\n"
3931
3932#: src/server/connection.c:1313
3933#, c-format
3934msgid "`%s' selected %d out of %d messages (MTU: %d).\n"
3935msgstr ""
3936
3937#: src/server/connection.c:1323
3938#, c-format
3939msgid "Message details: %u: length %d, priority: %d\n"
3940msgstr "Detalles del mensaje: %u: longitud %d, prioridad: %d\n"
3941
3942#: src/server/connection.c:3129
3943#, c-format
3944msgid "Message from `%s' discarded: invalid format.\n"
3945msgstr "Mensaje de '%s' descartado: formato inválido.\n"
3946
3947#: src/server/connection.c:3218
3948#, c-format
3949msgid "Invalid sequence number %u <= %u, dropping message.\n"
3950msgstr "Secuencia de números no válida %u <= %u, omitiendo mensaje.\n"
3951
3952#: src/server/connection.c:3240
3953msgid "Message received more than one day old. Dropped.\n"
3954msgstr "Mensajes recibidos de mas de un día de antigüedad. Omitidos.\n"
3955
3956#: src/server/connection.c:3763
3957msgid "# outgoing messages dropped"
3958msgstr "# mensajes salientes omitidos"
3959
3960#: src/server/connection.c:3766
3961msgid "# bytes of outgoing messages dropped"
3962msgstr "# bytes de mensajes salientes omitidos"
3963
3964#: src/server/connection.c:3768
3965msgid "# connections closed (HANGUP sent)"
3966msgstr ""
3967
3968#: src/server/connection.c:3772
3969msgid "# connections closed (transport issue)"
3970msgstr ""
3971
3972#: src/server/connection.c:3775
3973msgid "# bytes encrypted"
3974msgstr "# bytes encriptados"
3975
3976#: src/server/connection.c:3779
3977#, fuzzy
3978msgid "# bytes transmitted"
3979msgstr "# bytes desencriptados"
3980
3981#: src/server/connection.c:3783
3982#, fuzzy
3983msgid "# bytes received"
3984msgstr "# bytes recibidos por TCP"
3985
3986#: src/server/connection.c:3785
3987msgid "# bytes decrypted"
3988msgstr "# bytes desencriptados"
3989
3990#: src/server/connection.c:3786
3991msgid "# bytes noise sent"
3992msgstr "# \"bytes-ruido\" mandados"
3993
3994#: src/server/connection.c:3789
3995msgid "# total bytes per second send limit"
3996msgstr ""
3997
3998#: src/server/connection.c:3792
3999#, fuzzy
4000msgid "# total bytes per second receive limit"
4001msgstr "# bytes de ruido recibidos"
4002
4003#: src/server/connection.c:3795
4004#, fuzzy
4005msgid "# total number of messages in send buffers"
4006msgstr "número de mensajes en un bloque de mensajes"
4007
4008#: src/server/connection.c:3798
4009#, fuzzy
4010msgid "# total number of bytes we were allowed to send but did not"
4011msgstr "número de mensajes en un bloque de mensajes"
4012
4013#: src/server/connection.c:3801
4014#, fuzzy
4015msgid "# total number of bytes we were allowed to sent"
4016msgstr "número de mensajes en un bloque de mensajes"
4017
4018#: src/server/connection.c:3804
4019msgid "# total number of bytes we are currently allowed to send"
4020msgstr ""
4021
4022#: src/server/connection.c:3807
4023msgid "# transports switched to stream transport"
4024msgstr ""
4025
4026#: src/server/connection.c:3810
4027msgid "# average connection lifetime (in ms)"
4028msgstr ""
4029
4030#: src/server/connection.c:3813
4031msgid "# conn. shutdown: other peer sent too much"
4032msgstr ""
4033
4034#: src/server/connection.c:3816
4035msgid "# conn. shutdown: we lacked bandwidth"
4036msgstr ""
4037
4038#: src/server/connection.c:3819
4039msgid "# conn. shutdown: other peer timed out"
4040msgstr ""
4041
4042#: src/server/connection.c:3822
4043msgid "# conn. shutdown: timed out during connect"
4044msgstr ""
4045
4046#: src/server/connection.c:3825
4047msgid "# conn. shutdown: other peer requested it"
4048msgstr ""
4049
4050#: src/server/handler.c:442
4051#, fuzzy, c-format
4052msgid "Received corrupt message from peer `%s' in %s:%d.\n"
4053msgstr "Recibido mensaje corrupto del par '%s' en %s:%d.\n"
4054
4055#: src/server/gnunet-transport-check.c:121
4056#, c-format
4057msgid "`%s': Could not create hello.\n"
4058msgstr "'%s': Imposible crear saludo.\n"
4059
4060#: src/server/gnunet-transport-check.c:129
4061#, c-format
4062msgid "`%s': Could not connect.\n"
4063msgstr "'%s': Imposible conectar.\n"
4064
4065#: src/server/gnunet-transport-check.c:163
4066#, c-format
4067msgid "`%s': Could not send.\n"
4068msgstr "'%s': Imposible mandar.\n"
4069
4070#: src/server/gnunet-transport-check.c:179
4071#, c-format
4072msgid "`%s': Did not receive message within %llu ms.\n"
4073msgstr "'%s': No se recibió el mensaje en %llu ms.\n"
4074
4075#: src/server/gnunet-transport-check.c:192
4076#, c-format
4077msgid "`%s': Could not disconnect.\n"
4078msgstr "'%s': Imposible desconectar.\n"
4079
4080#: src/server/gnunet-transport-check.c:200
4081#, fuzzy, c-format
4082msgid ""
4083"`%s' transport OK. It took %ums to transmit %llu messages of %llu bytes "
4084"each.\n"
4085msgstr ""
4086"Transporte '%s' OK. Tomó %ums transmitir %d mensajes de %d bytes cada uno.\n"
4087
4088#: src/server/gnunet-transport-check.c:231
4089#, c-format
4090msgid " Transport %d is not being tested\n"
4091msgstr " El transporte %d no esta siendo probado\n"
4092
4093#: src/server/gnunet-transport-check.c:261
4094#, c-format
4095msgid ""
4096"\n"
4097"Contacting `%s'."
4098msgstr ""
4099"\n"
4100"Contactando '%s'."
4101
4102#: src/server/gnunet-transport-check.c:286
4103#, c-format
4104msgid " Connection failed\n"
4105msgstr "Conexión fallida\n"
4106
4107#: src/server/gnunet-transport-check.c:292
4108#, c-format
4109msgid " Connection failed (bug?)\n"
4110msgstr "Conexión fallida (¿bug?)\n"
4111
4112#: src/server/gnunet-transport-check.c:330
4113#, c-format
4114msgid "Timeout after %llums.\n"
4115msgstr ""
4116
4117#: src/server/gnunet-transport-check.c:332
4118#, fuzzy, c-format
4119msgid "OK!\n"
4120msgstr "OK"
4121
4122#: src/server/gnunet-transport-check.c:357
4123msgid "Tool to test if GNUnet transport services are operational."
4124msgstr ""
4125
4126#: src/server/gnunet-transport-check.c:361
4127msgid "ping peers from HOSTLISTURL that match transports"
4128msgstr ""
4129
4130#: src/server/gnunet-transport-check.c:364
4131msgid "send COUNT messages"
4132msgstr "envia COUNT mensajes"
4133
4134#: src/server/gnunet-transport-check.c:367
4135msgid "send messages with SIZE bytes payload"
4136msgstr "manda mensajes con SIZE bytes payload"
4137
4138#: src/server/gnunet-transport-check.c:370
4139msgid "specifies which TRANSPORT should be tested"
4140msgstr ""
4141
4142#: src/server/gnunet-transport-check.c:373
4143msgid "specifies after how many MS to time-out"
4144msgstr ""
4145
4146#: src/server/gnunet-transport-check.c:381
4147msgid "repeat each test X times"
4148msgstr ""
4149
4150#: src/server/gnunet-transport-check.c:449
4151#, c-format
4152msgid "Testing transport(s) %s\n"
4153msgstr "Probando transporte(s) %s\n"
4154
4155#: src/server/gnunet-transport-check.c:451
4156#, c-format
4157msgid "Available transport(s): %s\n"
4158msgstr "Transporte(s) disponible(s): %s\n"
4159
4160#: src/server/gnunet-transport-check.c:501
4161#, c-format
4162msgid ""
4163"\n"
4164"%d out of %d peers contacted successfully (%d times transport unavailable).\n"
4165msgstr ""
4166
4167#: src/transports/common.c:370
4168#, c-format
4169msgid "Port is 0, will only send using %s.\n"
4170msgstr ""
4171
4172#: src/transports/smtp.c:367 src/transports/udp.c:107 src/transports/tcp.c:271
4173#: src/transports/tcp.c:291
4174#, fuzzy, c-format
4175msgid "Received malformed message via %s. Ignored.\n"
4176msgstr "Recibido el mensaje '%s' con un mal formato. Omitiendo.\n"
4177
4178#: src/transports/smtp.c:459
4179msgid "SMTP filter string to invalid, lacks ': '\n"
4180msgstr ""
4181
4182#: src/transports/smtp.c:469
4183#, c-format
4184msgid "SMTP filter string to long, capped to `%s'\n"
4185msgstr ""
4186
4187#: src/transports/smtp.c:564 src/transports/smtp.c:575
4188#: src/transports/smtp.c:589 src/transports/smtp.c:609
4189#: src/transports/smtp.c:634 src/transports/smtp.c:643
4190#: src/transports/smtp.c:657 src/transports/smtp.c:669
4191#, fuzzy, c-format
4192msgid "SMTP: `%s' failed: %s.\n"
4193msgstr "'%s' %s falló: %s\n"
4194
4195#: src/transports/smtp.c:814
4196msgid "No email-address specified, can not start SMTP transport.\n"
4197msgstr ""
4198
4199#: src/transports/smtp.c:831
4200#, fuzzy
4201msgid "# bytes received via SMTP"
4202msgstr "# bytes recibidos por TCP"
4203
4204#: src/transports/smtp.c:832
4205#, fuzzy
4206msgid "# bytes sent via SMTP"
4207msgstr "# bytes enviados por TCP"
4208
4209#: src/transports/smtp.c:834
4210#, fuzzy
4211msgid "# bytes dropped by SMTP (outgoing)"
4212msgstr "# bytes omitidos por TCP (salientes)"
4213
4214#: src/transports/upnp/upnp.c:431
4215#, fuzzy, c-format
4216msgid "%s failed for url `%s' and post-data `%s' at %s:%d: `%s'\n"
4217msgstr "'%s' falló en %s: %d con error: '%s'.\n"
4218
4219#: src/transports/upnp/upnp.c:476
4220#, c-format
4221msgid "upnp: NAT Returned IP: %s\n"
4222msgstr ""
4223
4224#: src/transports/http.c:2019 src/transports/tcp.c:811
4225#, c-format
4226msgid ""
4227"The UPnP service could not be loaded. To disable UPnP, set the configuration "
4228"option \"UPNP\" in section \"%s\" to \"NO\"\n"
4229msgstr ""
4230
4231#: src/transports/http.c:2028
4232msgid "# bytes received via HTTP"
4233msgstr "# bytes recibidos vía HTTP"
4234
4235#: src/transports/http.c:2029
4236msgid "# bytes sent via HTTP"
4237msgstr "# bytes mandados vía HTTP"
4238
4239#: src/transports/http.c:2031
4240msgid "# bytes dropped by HTTP (outgoing)"
4241msgstr "#bytes omitidos vía HTTP (salientes)"
4242
4243#: src/transports/http.c:2032
4244msgid "# HTTP GET issued"
4245msgstr ""
4246
4247#: src/transports/http.c:2034
4248#, fuzzy
4249msgid "# HTTP GET received"
4250msgstr "# bytes recibidos por TCP"
4251
4252#: src/transports/http.c:2035
4253msgid "# HTTP PUT issued"
4254msgstr ""
4255
4256#: src/transports/http.c:2037
4257#, fuzzy
4258msgid "# HTTP PUT received"
4259msgstr "# bytes recibidos por TCP"
4260
4261#: src/transports/http.c:2039
4262msgid "# HTTP select calls"
4263msgstr ""
4264
4265#: src/transports/http.c:2041
4266msgid "# HTTP send calls"
4267msgstr ""
4268
4269#: src/transports/http.c:2044
4270msgid "# HTTP curl send callbacks"
4271msgstr ""
4272
4273#: src/transports/http.c:2046
4274#, fuzzy
4275msgid "# HTTP curl receive callbacks"
4276msgstr "# bytes recibidos por TCP"
4277
4278#: src/transports/http.c:2048
4279msgid "# HTTP mhd access callbacks"
4280msgstr ""
4281
4282#: src/transports/http.c:2050
4283msgid "# HTTP mhd read callbacks"
4284msgstr ""
4285
4286#: src/transports/http.c:2052
4287msgid "# HTTP mhd close callbacks"
4288msgstr ""
4289
4290#: src/transports/http.c:2054
4291#, fuzzy
4292msgid "# HTTP connect calls"
4293msgstr "# de pares conectados"
4294
4295#: src/transports/ip.c:70 src/transports/ip.c:365
4296#, fuzzy, c-format
4297msgid "Failed to obtain my (external) %s address!\n"
4298msgstr "¡Falló al obtener mi dirección IP (externa)!\n"
4299
4300#: src/transports/udp.c:472 src/transports/tcp.c:728
4301#, fuzzy, c-format
4302msgid "Failed to bind to %s port %d.\n"
4303msgstr "Fallo al conectar a gnunetd.\n"
4304
4305#: src/transports/udp.c:538
4306#, c-format
4307msgid "MTU %llu for `%s' is probably too low!\n"
4308msgstr ""
4309
4310#: src/transports/udp.c:562
4311msgid "# bytes received via UDP"
4312msgstr "# bytes recibidos vía UDP"
4313
4314#: src/transports/udp.c:563
4315msgid "# bytes sent via UDP"
4316msgstr "# bytes enviados vía UDP"
4317
4318#: src/transports/udp.c:565
4319msgid "# bytes dropped by UDP (outgoing)"
4320msgstr "# bytes omitidos por UDP (salientes)"
4321
4322#: src/transports/udp.c:567
4323msgid "# UDP connections (right now)"
4324msgstr ""
4325
4326#: src/transports/tcp.c:821
4327msgid "# bytes received via TCP"
4328msgstr "# bytes recibidos por TCP"
4329
4330#: src/transports/tcp.c:822
4331msgid "# bytes sent via TCP"
4332msgstr "# bytes enviados por TCP"
4333
4334#: src/transports/tcp.c:824
4335msgid "# bytes dropped by TCP (outgoing)"
4336msgstr "# bytes omitidos por TCP (salientes)"
4337
4338#: src/include/gnunet_util_getopt.h:154
4339msgid "print this help"
4340msgstr "imprime esta ayuda"
4341
4342#: src/include/gnunet_util_getopt.h:163
4343msgid "print the version number"
4344msgstr "imprime el número de versión"
4345
4346#: src/include/gnunet_util_getopt.h:169
4347msgid "configure logging to use LOGLEVEL"
4348msgstr ""
4349
4350#: src/include/gnunet_util_getopt.h:175
4351msgid "be verbose"
4352msgstr ""
4353
4354#: src/include/gnunet_util_getopt.h:181
4355#, fuzzy
4356msgid "use configuration file FILENAME"
4357msgstr "usa el fichero de configuración FILENAME"
4358
4359#: src/include/gnunet_util_getopt.h:187
4360#, fuzzy
4361msgid "specify host on which gnunetd is running"
4362msgstr "especifica el host en el que gnunetd esta ejecutandose"
4363
4364#: src/include/gnunet_util_error.h:219 src/include/gnunet_util_error.h:224
4365#: src/include/gnunet_util_error.h:230 src/include/gnunet_util_error.h:232
4366#, fuzzy, c-format
4367msgid "Internal error: assertion failed at %s:%d.\n"
4368msgstr "La verificación de la firma RSA fallo en %s: %d: %s\n"
4369
4370#: src/include/gnunet_util_error.h:242
4371#, c-format
4372msgid ""
4373"External protocol violation: assertion failed at %s:%d (no need to panic, we "
4374"can handle this).\n"
4375msgstr ""
4376
4377#: src/include/gnunet_util_error.h:270 src/include/gnunet_util_error.h:277
4378#, fuzzy, c-format
4379msgid "`%s' failed on file `%s' at %s:%d with error: %s\n"
4380msgstr "'%s' falló en el fichero '%s' en %s: %d con el error: %s\n"
4381
4382#: contrib/config-daemon.scm:39 contrib/config-client.scm:40
4383#, fuzzy
4384msgid "No help available."
4385msgstr "'%s' no esta disponible."
4386
4387#: contrib/config-daemon.scm:42
4388msgid ""
4389"You can use 'make check' in src/transports/upnp/ to find out if your NAT "
4390"supports UPnP. You should disable this option if you are sure that you are "
4391"not behind a NAT. If your NAT box does not support UPnP, having this on "
4392"will not do much harm (only cost a small amount of resources)."
4393msgstr ""
4394
4395#: contrib/config-daemon.scm:54 contrib/config-client.scm:53
4396msgid "Prompt for development and/or incomplete code"
4397msgstr ""
4398
4399#: contrib/config-daemon.scm:56 contrib/config-client.scm:55
4400msgid ""
4401"If EXPERIMENTAL is set to NO, options for experimental code are not shown. "
4402"If in doubt, use NO.\n"
4403"\n"
4404"Some options apply to experimental code that maybe in a state of development "
4405"where the functionality, stability, or the level of testing is not yet high "
4406"enough for general use. These features are said to be of \"alpha\" "
4407"quality. If a feature is currently in alpha, uninformed use is discouraged "
4408"(since the developers then do not fancy \"Why doesn't this work?\" type "
4409"messages).\n"
4410"\n"
4411"However, active testing and qualified feedback of these features is always "
4412"welcome. Users should just be aware that alpha features may not meet the "
4413"normal level of reliability or it may fail to work in some special cases. "
4414"Bug reports are usually welcomed by the developers, but please read the "
4415"documents <file://README> and <http://gnunet.org/faq.php3> and use <https://"
4416"gnunet.org/mantis/> for how to report problems."
4417msgstr ""
4418
4419#: contrib/config-daemon.scm:71 contrib/config-client.scm:70
4420msgid "Show options for advanced users"
4421msgstr ""
4422
4423#: contrib/config-daemon.scm:73 contrib/config-client.scm:72
4424msgid ""
4425"These are options that maybe difficult to understand for the beginner. These "
4426"options typically refer to features that allow tweaking of the "
4427"installation. If in a hurry, say NO."
4428msgstr ""
4429
4430#: contrib/config-daemon.scm:84 contrib/config-client.scm:83
4431#, fuzzy
4432msgid "Show rarely used options"
4433msgstr "Mostrar todas las opciones"
4434
4435#: contrib/config-daemon.scm:86 contrib/config-client.scm:85
4436msgid ""
4437"These are options that hardly anyone actually needs. If you plan on doing "
4438"development on GNUnet, you may want to look into these. If in doubt or in a "
4439"hurry, say NO."
4440msgstr ""
4441
4442#: contrib/config-daemon.scm:97 contrib/config-client.scm:96
4443#, fuzzy
4444msgid "Meta-configuration"
4445msgstr "Configuración de GNUnet"
4446
4447#: contrib/config-daemon.scm:98 contrib/config-client.scm:97
4448msgid "Which level of configuration should be available"
4449msgstr ""
4450
4451#: contrib/config-daemon.scm:115
4452#, fuzzy
4453msgid "Full pathname of GNUnet HOME directory"
4454msgstr "Error en el formato del fichero (¿no es un directorio de GNUnet?)\n"
4455
4456#: contrib/config-daemon.scm:117
4457msgid ""
4458"This gives the root-directory of the GNUnet installation. Make sure there is "
4459"some space left in that directory. :-) Users inserting or indexing files "
4460"will be able to store data in this directory up to the (global) quota "
4461"specified below. Having a few gigabytes of free space is recommended."
4462msgstr ""
4463
4464#: contrib/config-daemon.scm:130
4465#, fuzzy
4466msgid "Full pathname of GNUnet directory for file-sharing data"
4467msgstr "Error en el formato del fichero (¿no es un directorio de GNUnet?)\n"
4468
4469#: contrib/config-daemon.scm:142
4470#, fuzzy
4471msgid "Full pathname to the directory with the key-value database"
4472msgstr "Error en el formato del fichero (¿no es un directorio de GNUnet?)\n"
4473
4474#: contrib/config-daemon.scm:143
4475msgid "Note that the kvstore is currently not used."
4476msgstr ""
4477
4478#: contrib/config-daemon.scm:154
4479#, fuzzy
4480msgid "Full pathname of GNUnet directory for indexed files symbolic links"
4481msgstr "Error en el formato del fichero (¿no es un directorio de GNUnet?)\n"
4482
4483#: contrib/config-daemon.scm:166
4484msgid "How many minutes should peer advertisements last?"
4485msgstr ""
4486
4487#: contrib/config-daemon.scm:168
4488msgid ""
4489"How many minutes is the current IP valid? (GNUnet will sign HELLO messages "
4490"with this expiration timeline. If you are on dialup, 60 (for 1 hour) is "
4491"suggested. If you have a static IP address, you may want to set this to a "
4492"large value (say 14400). The default is 1440 (1 day). If your IP changes "
4493"periodically, you will want to choose an expiry period smaller than the "
4494"frequency with which your IP changes."
4495msgstr ""
4496
4497#: contrib/config-daemon.scm:179
4498msgid "Where can GNUnet find an initial list of peers?"
4499msgstr ""
4500
4501#: contrib/config-daemon.scm:181
4502msgid ""
4503"GNUnet can automatically update the hostlist from the web. While GNUnet "
4504"internally communicates which hosts are online, it is typically a good idea "
4505"to get a fresh hostlist whenever gnunetd starts from the WEB. By setting "
4506"this option, you can specify from which server gnunetd should try to "
4507"download the hostlist. The default should be fine for now.\n"
4508"\t\t\n"
4509"The general format is a list of space-separated URLs. Each URL must have "
4510"the format http://HOSTNAME/FILENAME\n"
4511"\t\t\n"
4512"If you want to setup an alternate hostlist server, you must run a permanent "
4513"node and \"cat data/hosts/* > hostlist\" every few minutes to keep the list "
4514"up-to-date.\n"
4515"\t\t\n"
4516"If you do not specify a HOSTLISTURL, you must copy valid hostkeys to data/"
4517"hosts manually."
4518msgstr ""
4519
4520#: contrib/config-daemon.scm:198
4521msgid "HTTP Proxy Server"
4522msgstr ""
4523
4524#: contrib/config-daemon.scm:200
4525msgid ""
4526"If you have to use a proxy for outbound HTTP connections, specify the proxy "
4527"configuration here. Default is no proxy."
4528msgstr ""
4529
4530#: contrib/config-daemon.scm:212
4531msgid ""
4532"Name of the directory where gnunetd should store contact information about "
4533"peers"
4534msgstr ""
4535
4536#: contrib/config-daemon.scm:214
4537msgid ""
4538"Unless you want to share the directory directly using a webserver, the "
4539"default is most likely just fine."
4540msgstr ""
4541
4542#: contrib/config-daemon.scm:240 contrib/config-client.scm:140
4543msgid "How long should logs be kept?"
4544msgstr ""
4545
4546#: contrib/config-daemon.scm:242 contrib/config-client.scm:142
4547msgid ""
4548"How long should logs be kept? If you specify a value greater than zero, a "
4549"log is created each day with the date appended to its filename. These logs "
4550"are deleted after $KEEPLOG days.\tTo keep logs forever, set this value to 0."
4551msgstr ""
4552
4553#: contrib/config-daemon.scm:253
4554msgid ""
4555"What maximum number of open file descriptors should be requested from the OS?"
4556msgstr ""
4557
4558#: contrib/config-daemon.scm:255
4559msgid ""
4560"The default of 1024 should be fine for most systems. If your system can "
4561"support more, increasing the number might help support additional clients on "
4562"machines with plenty of bandwidth. For embedded systems, a smaller number "
4563"might be acceptable. A value of 0 will leave the descriptor limit "
4564"untouched. This option is mostly for OS X systems where the default is too "
4565"low. Note that if gnunetd cannot obtain the desired number of file "
4566"descriptors from the operating system, it will print a warning and try to "
4567"run with what it is given."
4568msgstr ""
4569
4570#: contrib/config-daemon.scm:266
4571msgid "Where should gnunetd write the logs?"
4572msgstr ""
4573
4574#: contrib/config-daemon.scm:278
4575msgid "Enable for extra-verbose logging."
4576msgstr ""
4577
4578#: contrib/config-daemon.scm:290 contrib/config-client.scm:165
4579msgid "Logging"
4580msgstr ""
4581
4582#: contrib/config-daemon.scm:291 contrib/config-client.scm:166
4583msgid "Specify which system messages should be logged how"
4584msgstr ""
4585
4586#: contrib/config-daemon.scm:296 contrib/config-client.scm:170
4587msgid "Logging of events for users"
4588msgstr ""
4589
4590#: contrib/config-daemon.scm:297 contrib/config-client.scm:171
4591msgid "Logging of events for the system administrator"
4592msgstr ""
4593
4594#: contrib/config-daemon.scm:309
4595msgid "Where should gnunetd write the PID?"
4596msgstr ""
4597
4598#: contrib/config-daemon.scm:310
4599msgid ""
4600"The default is no longer /var/run/gnunetd.pid since we could not delete the "
4601"file on shutdown at that location."
4602msgstr ""
4603
4604#: contrib/config-daemon.scm:322
4605msgid "As which user should gnunetd run?"
4606msgstr ""
4607
4608#: contrib/config-daemon.scm:324
4609msgid ""
4610"Empty means \"current user\". On computer startup, it is root/SYSTEM. Under "
4611"Windows, this setting affects the creation of a new system service only."
4612msgstr ""
4613
4614#: contrib/config-daemon.scm:337
4615msgid "Should gnunetd be automatically started when the system boots?"
4616msgstr ""
4617
4618#: contrib/config-daemon.scm:338
4619msgid ""
4620"Set to YES if gnunetd should be automatically started on boot. If this "
4621"option is set, gnunet-setup will install a script to start the daemon upon "
4622"completion. This option may not work on all systems."
4623msgstr ""
4624
4625#: contrib/config-daemon.scm:350
4626msgid "Which transport mechanisms should GNUnet use?"
4627msgstr ""
4628
4629#: contrib/config-daemon.scm:352
4630msgid ""
4631"Use a space-separated list of modules, e.g. \"udp smtp tcp\". The "
4632"available transports are udp, tcp, http, smtp and nat.\n"
4633"\t\t\n"
4634"Loading the 'nat' and 'tcp' modules is required for peers behind NAT boxes "
4635"that cannot directly be reached from the outside. Peers that are NOT behind "
4636"a NAT box and that want to *allow* peers that ARE behind a NAT box to "
4637"connect must ALSO load the 'nat' module. Note that the actual transfer will "
4638"always be via tcp initiated by the peer behind the NAT box. The nat "
4639"transport requires the use of tcp, http and/or smtp in addition to nat "
4640"itself."
4641msgstr ""
4642
4643#: contrib/config-daemon.scm:366
4644msgid "Which applications should gnunetd support?"
4645msgstr ""
4646
4647#: contrib/config-daemon.scm:368
4648msgid ""
4649"Whenever this option is changed, you MUST run gnunet-update. Currently, the "
4650"available applications are:\n"
4651"\n"
4652"advertising: advertises your peer to other peers. Without it, your peer will "
4653"not participate in informing peers about other peers. You should always "
4654"load this module.\n"
4655"\n"
4656"getoption: allows clients to query gnunetd about the values of various "
4657"configuration options. Many tools need this. You should always load this "
4658"module.\n"
4659"\n"
4660"stats: allows tools like gnunet-stats and gnunet-gtk to query gnunetd about "
4661"various statistics. This information is usually quite useful to diagnose "
4662"errors, hence it is recommended that you load this module.\n"
4663"\n"
4664"traffic: keeps track of how many messages were recently received and "
4665"transmitted. This information can then be used to establish how much cover "
4666"traffic is currently available. The amount of cover traffic becomes "
4667"important if you want to make anonymous requests with an anonymity level "
4668"that is greater than one. It is recommended that you load this module.\n"
4669"\n"
4670"fs: needed for anonymous file sharing. You should always load this module.\n"
4671"\n"
4672"hostlist: integrated hostlist HTTP server. Useful if you want to offer a "
4673"hostlist and running Apache would be overkill.\n"
4674"\n"
4675"chat: broadcast chat (demo-application, ALPHA quality).\tRequired for gnunet-"
4676"chat. Note that the current implementation of chat is not considered to be "
4677"secure.\n"
4678"\n"
4679"tbench: benchmark transport performance. Required for gnunet-tbench. Note "
4680"that tbench allows other users to abuse your resources.\n"
4681"\n"
4682"tracekit: topology visualization toolkit. Required for gnunet-tracekit. "
4683"Note that loading tracekit will make it slightly easier for an adversary to "
4684"compromise your anonymity."
4685msgstr ""
4686
4687#: contrib/config-daemon.scm:399
4688msgid "Disable client-server connections"
4689msgstr ""
4690
4691#: contrib/config-daemon.scm:400
4692msgid ""
4693"This option can be used to tell gnunetd not to open the client port. When "
4694"run like this, gnunetd will participate as a peer in the network but not "
4695"support any user interfaces. This may be useful for headless systems that "
4696"are never expected to have end-user interactions. Note that this will also "
4697"prevent you from running diagnostic tools like gnunet-stats!"
4698msgstr ""
4699
4700#: contrib/config-daemon.scm:412
4701msgid "YES disables IPv6 support, NO enables IPv6 support"
4702msgstr ""
4703
4704#: contrib/config-daemon.scm:413
4705msgid ""
4706"This option may be useful on peers where the kernel does not support IPv6. "
4707"You might also want to set this option if you do not have an IPv6 network "
4708"connection."
4709msgstr ""
4710
4711#: contrib/config-daemon.scm:425
4712msgid "Disable peer discovery"
4713msgstr ""
4714
4715#: contrib/config-daemon.scm:426
4716msgid ""
4717"The option 'PRIVATE-NETWORK' can be used to limit the connections of this "
4718"peer to peers of which the hostkey has been copied by hand to data/hosts; "
4719"if this option is given, GNUnet will not accept advertisements of peers that "
4720"the local node does not already know about. Note that in order for this "
4721"option to work, HOSTLISTURL should either not be set at all or be set to a "
4722"trusted peer that only advertises the private network. Also, the option does "
4723"NOT work at the moment if the NAT transport is loaded; for that, a couple of "
4724"lines above would need some minor editing :-)."
4725msgstr ""
4726
4727#: contrib/config-daemon.scm:437
4728msgid "Disable advertising this peer to other peers"
4729msgstr ""
4730
4731#: contrib/config-daemon.scm:449
4732#, fuzzy
4733msgid "Disable automatic establishment of connections"
4734msgstr "Se produjo un error estableciendo conexión con gnunetd.\n"
4735
4736#: contrib/config-daemon.scm:450
4737msgid ""
4738"If this option is enabled, GNUnet will not automatically establish "
4739"connections to other peers, but instead wait for applications to "
4740"specifically request connections to other peers (or for other peers to "
4741"connect to us)."
4742msgstr ""
4743
4744#: contrib/config-daemon.scm:461
4745msgid "Enable advertising of other peers by this peer"
4746msgstr ""
4747
4748#: contrib/config-daemon.scm:462
4749msgid ""
4750"This option may be useful during testing, but turning it off is dangerous! "
4751"If in any doubt, set it to YES (which is the default)."
4752msgstr ""
4753
4754#: contrib/config-daemon.scm:473
4755#, fuzzy
4756msgid "Port for communication with GNUnet user interfaces"
4757msgstr "Imprime información de los pares de GNUnet."
4758
4759#: contrib/config-daemon.scm:474
4760msgid ""
4761"Which is the client-server port that is used between gnunetd and the clients "
4762"(TCP only). You may firewall this port for non-local machines (but you do "
4763"not have to since GNUnet will perform access control and only allow "
4764"connections from machines that are listed under TRUSTED)."
4765msgstr ""
4766
4767#: contrib/config-daemon.scm:485
4768msgid "Port for the integrated hostlist HTTP server"
4769msgstr ""
4770
4771#: contrib/config-daemon.scm:497
4772msgid "IPv4 networks allowed to use gnunetd server"
4773msgstr ""
4774
4775#: contrib/config-daemon.scm:498 contrib/config-daemon.scm:510
4776msgid ""
4777"This option specifies which hosts are trusted enough to connect as clients "
4778"(to the TCP port). This is useful if you run gnunetd on one host of your "
4779"network and want to allow all other hosts to use this node as their server. "
4780"By default, this is set to 'loopback only'. The format is IP/NETMASK where "
4781"the IP is specified in dotted-decimal and the netmask either in CIDR "
4782"notation (/16) or in dotted decimal (255.255.0.0). Several entries must be "
4783"separated by a semicolon, spaces are not allowed."
4784msgstr ""
4785
4786#: contrib/config-daemon.scm:509
4787msgid "IPv6 networks allowed to use gnunetd server"
4788msgstr ""
4789
4790#: contrib/config-daemon.scm:522
4791msgid "Limit connections to the specfied set of peers."
4792msgstr ""
4793
4794#: contrib/config-daemon.scm:523
4795msgid ""
4796"If this option is not set, any peer is allowed to connect. If it is set, "
4797"only the specified peers are allowed. Specify the list of peer IDs (not IPs!)"
4798msgstr ""
4799
4800#: contrib/config-daemon.scm:534
4801#, fuzzy
4802msgid "Run gnunetd as this group."
4803msgstr "Ejecutar gnunet-update"
4804
4805#: contrib/config-daemon.scm:535
4806msgid ""
4807"When started as root, gnunetd will change permissions to the given group."
4808msgstr ""
4809
4810#: contrib/config-daemon.scm:546
4811msgid "Prevent the specfied set of peers from connecting."
4812msgstr ""
4813
4814#: contrib/config-daemon.scm:547
4815msgid ""
4816"If this option is not set, any peer is allowed to connect. If the ID of a "
4817"peer is listed here, connections from that peer will be refused. Specify "
4818"the list of peer IDs (not IPs!)"
4819msgstr ""
4820
4821#: contrib/config-daemon.scm:558
4822msgid "Topology Maintenance"
4823msgstr ""
4824
4825#: contrib/config-daemon.scm:559
4826msgid "Rarely used settings for peer advertisements and connections"
4827msgstr ""
4828
4829#: contrib/config-daemon.scm:579
4830#, fuzzy
4831msgid "General settings"
4832msgstr "Otras configuraciones"
4833
4834#: contrib/config-daemon.scm:580
4835msgid "Settings that change the behavior of GNUnet in general"
4836msgstr ""
4837
4838#: contrib/config-daemon.scm:607
4839msgid "Modules"
4840msgstr ""
4841
4842#: contrib/config-daemon.scm:608
4843msgid "Settings that select specific implementations for GNUnet modules"
4844msgstr ""
4845
4846#: contrib/config-daemon.scm:626
4847msgid "Fundamentals"
4848msgstr ""
4849
4850#: contrib/config-daemon.scm:646
4851msgid "Which database should be used?"
4852msgstr ""
4853
4854#: contrib/config-daemon.scm:648
4855msgid ""
4856"Which database should be used? The options are \"sqstore_sqlite\", "
4857"\"sqstore_postgres\" and \"sqstore_mysql\". You must run gnunet-update "
4858"after changing this value!\n"
4859"\t\t\t\n"
4860"In order to use MySQL or Postgres, you must configure the respective "
4861"database, which is relatively simple. Read the file doc/README.mysql or doc/"
4862"README.postgres for how to setup the respective database."
4863msgstr ""
4864
4865#: contrib/config-daemon.scm:661 contrib/config-daemon.scm:674
4866msgid "Which topology should be used?"
4867msgstr ""
4868
4869#: contrib/config-daemon.scm:662
4870msgid "Which database should be used for the temporary datastore of the DHT?"
4871msgstr ""
4872
4873#: contrib/config-daemon.scm:676
4874msgid ""
4875"Which topology should be used? The only option at the moment is "
4876"\"topology_default\""
4877msgstr ""
4878
4879#: contrib/config-daemon.scm:690
4880msgid ""
4881"The minimum number of connected friends before this peer is allowed to "
4882"connect to peers that are not listed as friends"
4883msgstr ""
4884
4885#: contrib/config-daemon.scm:691
4886msgid ""
4887"Note that this option does not guarantee that the peer will be able to "
4888"connect to the specified number of friends. Also, if the peer had connected "
4889"to a sufficient number of friends and then established non-friend "
4890"connections, some of the friends may drop out of the network, temporarily "
4891"resulting in having fewer than the specified number of friends connected "
4892"while being connected to non-friends. However, it is guaranteed that the "
4893"peer itself will never choose to drop a friend's connection if this would "
4894"result in dropping below the specified number of friends (unless that number "
4895"is higher than the overall connection target)."
4896msgstr ""
4897
4898#: contrib/config-daemon.scm:702
4899msgid ""
4900"If set to YES, the peer is only allowed to connect to other peers that are "
4901"explicitly specified as friends"
4902msgstr ""
4903
4904#: contrib/config-daemon.scm:703
4905msgid ""
4906"Use YES only if you have (trustworthy) friends that use GNUnet and are "
4907"afraid of establishing (direct) connections to unknown peers"
4908msgstr ""
4909
4910#: contrib/config-daemon.scm:714
4911msgid "List of friends for friend-to-friend topology"
4912msgstr ""
4913
4914#: contrib/config-daemon.scm:715
4915msgid ""
4916"Specifies the name of a file which contains a list of GNUnet peer IDs that "
4917"are friends. If used with the friend-to-friend topology, this will ensure "
4918"that GNUnet only connects to these peers (via any available transport)."
4919msgstr ""
4920
4921#: contrib/config-daemon.scm:726
4922msgid "Friend-to-Friend Topology Specification"
4923msgstr ""
4924
4925#: contrib/config-daemon.scm:727
4926#, fuzzy
4927msgid "Settings for restricting connections to friends"
4928msgstr "'%s' falló. Finalizando conexión con el cleinte.\n"
4929
4930#: contrib/config-daemon.scm:744
4931#, fuzzy
4932msgid "Name of the MySQL database GNUnet should use"
4933msgstr "Imposible inicializar SQLite.\n"
4934
4935#: contrib/config-daemon.scm:756
4936#, fuzzy
4937msgid "Configuration file that specifies the MySQL username and password"
4938msgstr ""
4939"La configuración o la versión de GNUnet cambiaron. ¡Debes ejecutar '%s'!\n"
4940
4941#: contrib/config-daemon.scm:768
4942#, fuzzy
4943msgid "Configuration of the MySQL database"
4944msgstr ""
4945"La configuración o la versión de GNUnet cambiaron. ¡Debes ejecutar '%s'!\n"
4946
4947#: contrib/config-daemon.scm:787
4948#, fuzzy
4949msgid "MB of diskspace GNUnet can use for anonymous file sharing"
4950msgstr "activa la compartición de ficheros anónima"
4951
4952#: contrib/config-daemon.scm:789
4953msgid ""
4954"How much disk space (MB) is GNUnet allowed to use for anonymous file "
4955"sharing? This does not take indexed files into account, only the space "
4956"directly used by GNUnet is accounted for. GNUnet will gather content from "
4957"the network if the current space-consumption is below the number given here "
4958"(and if content migration is allowed below).\n"
4959"\n"
4960"Note that if you change the quota, you need to run gnunet-update afterwards."
4961msgstr ""
4962
4963#: contrib/config-daemon.scm:803
4964#, fuzzy
4965msgid "Number of entries in the migration buffer"
4966msgstr "número de mensajes en un bloque de mensajes"
4967
4968#: contrib/config-daemon.scm:804
4969msgid ""
4970"Each entry uses about 32k of memory. More entries can reduce disk IO and "
4971"CPU usage at the expense of having gnunetd use more memory. Very large "
4972"values may again increase CPU usage. A value of 0 will prevent your peer "
4973"from sending unsolicited responses."
4974msgstr ""
4975
4976#: contrib/config-daemon.scm:816
4977msgid "Size of the routing table for anonymous routing."
4978msgstr ""
4979
4980#: contrib/config-daemon.scm:828
4981msgid "Size of the routing table for DHT routing."
4982msgstr ""
4983
4984#: contrib/config-daemon.scm:841
4985msgid "Allow migrating content to this peer."
4986msgstr ""
4987
4988#: contrib/config-daemon.scm:843
4989msgid ""
4990"If you say yes here, GNUnet will migrate content to your server, and you "
4991"will not be able to control what data is stored on your machine. \n"
4992"\t\t\t\n"
4993"If you activate it, you can claim for *all* the non-indexed (-n to gnunet-"
4994"insert) content that you did not know what it was even if an adversary takes "
4995"control of your machine. If you do not activate it, it is obvious that you "
4996"have knowledge of all the content that is hosted on your machine and thus "
4997"can be considered liable for it."
4998msgstr ""
4999
5000#: contrib/config-daemon.scm:857
5001#, fuzzy
5002msgid ""
5003"MB of diskspace GNUnet can use for caching DHT index data (the data will be "
5004"stored in /tmp)"
5005msgstr "activa la compartición de ficheros anónima"
5006
5007#: contrib/config-daemon.scm:858
5008msgid ""
5009"DHT index data is inherently small and expires comparatively quickly. It is "
5010"deleted whenever gnunetd is shut down.\n"
5011"\n"
5012"The size of the DSTORE QUOTA is specified in MB."
5013msgstr ""
5014
5015#: contrib/config-daemon.scm:872
5016#, fuzzy
5017msgid "Options for anonymous file sharing"
5018msgstr "activa la compartición de ficheros anónima"
5019
5020#: contrib/config-daemon.scm:891
5021#, fuzzy
5022msgid "Applications"
5023msgstr "_Opciones"
5024
5025#: contrib/config-daemon.scm:907
5026msgid "Is this machine unreachable behind a NAT?"
5027msgstr ""
5028
5029#: contrib/config-daemon.scm:908
5030msgid ""
5031"Set to YES if this machine is behind a NAT that limits connections from the "
5032"outside to the GNUnet port and that cannot be traversed using UPnP. Note "
5033"that if you have configured your NAT box to allow direct connections from "
5034"other machines to the GNUnet ports or if GNUnet can open ports using UPnP, "
5035"you should set the option to NO. Set this only to YES if other peers cannot "
5036"contact you directly. You can use 'make check' in src/transports/upnp/ to "
5037"find out if your NAT supports UPnP. You can also use gnunet-transport-check "
5038"with the '-p' option in order to determine which setting results in more "
5039"connections. Use YES only if you get no connections otherwise. Set to AUTO "
5040"to use YES if the local IP is belongs to a private IP network and NO "
5041"otherwise."
5042msgstr ""
5043
5044#: contrib/config-daemon.scm:919
5045msgid "Which port should be used by the TCP IPv4 transport?"
5046msgstr ""
5047
5048#: contrib/config-daemon.scm:931 contrib/config-daemon.scm:1024
5049#: contrib/config-daemon.scm:1174
5050msgid "Should we try to determine our external IP using UPnP?"
5051msgstr ""
5052
5053#: contrib/config-daemon.scm:943
5054msgid "Which IP(v4)s are not allowed to connect?"
5055msgstr ""
5056
5057#: contrib/config-daemon.scm:955
5058msgid ""
5059"Which IP(v4)s are allowed to connect? Leave empty to use the IP of your "
5060"primary network interface."
5061msgstr ""
5062
5063#: contrib/config-daemon.scm:967 contrib/config-daemon.scm:1222
5064msgid "Which IPv6s are not allowed to connect?"
5065msgstr ""
5066
5067#: contrib/config-daemon.scm:979 contrib/config-daemon.scm:1234
5068msgid ""
5069"Which IPv6s are allowed to connect? Leave empty to allow any IP to connect."
5070msgstr ""
5071
5072#: contrib/config-daemon.scm:992
5073msgid "TCP transport"
5074msgstr ""
5075
5076#: contrib/config-daemon.scm:1012
5077msgid "Which port should be used by the HTTP transport?"
5078msgstr ""
5079
5080#: contrib/config-daemon.scm:1036
5081msgid "Which is the external port of the HTTP transport?"
5082msgstr ""
5083
5084#: contrib/config-daemon.scm:1037
5085msgid ""
5086"Use this option if your firewall maps, say, port 80 to your real HTTP port. "
5087"This can be useful in making the HTTP messages appear even more legit "
5088"(without needing to run gnunetd as root due to the use of a privileged port)."
5089msgstr ""
5090
5091#: contrib/config-daemon.scm:1048
5092msgid "HTTP transport"
5093msgstr ""
5094
5095#: contrib/config-daemon.scm:1067
5096msgid "What is the maximum transfer unit for SMTP?"
5097msgstr ""
5098
5099#: contrib/config-daemon.scm:1079
5100msgid ""
5101"What is the maximum number of e-mails that gnunetd would be allowed to send "
5102"per hour?"
5103msgstr ""
5104
5105#: contrib/config-daemon.scm:1080
5106msgid "Use 0 for unlimited"
5107msgstr ""
5108
5109#: contrib/config-daemon.scm:1091
5110msgid "Which e-mail address should be used to send e-mail to this peer?"
5111msgstr ""
5112
5113#: contrib/config-daemon.scm:1092
5114msgid ""
5115"You must make sure that e-mail received at this address is forwarded to the "
5116"PIPE which is read by gnunetd. Use the FILTER option to filter e-mail with "
5117"procmail and the PIPE option to set the name of the pipe."
5118msgstr ""
5119
5120#: contrib/config-daemon.scm:1103
5121msgid ""
5122"Which header line should other peers include in e-mails to enable filtering?"
5123msgstr ""
5124
5125#: contrib/config-daemon.scm:1104
5126msgid ""
5127"You can specify a header line here which can then be used by procmail to "
5128"filter GNUnet e-mail from your inbox and forward it to gnunetd."
5129msgstr ""
5130
5131#: contrib/config-daemon.scm:1115
5132msgid "What is the filename of the pipe where gnunetd can read its e-mail?"
5133msgstr ""
5134
5135#: contrib/config-daemon.scm:1116
5136msgid "Have a look at contrib/dot-procmailrc for an example .procmailrc file."
5137msgstr ""
5138
5139#: contrib/config-daemon.scm:1127
5140msgid "What is the name and port of the server for outgoing e-mail?"
5141msgstr ""
5142
5143#: contrib/config-daemon.scm:1128
5144msgid "The basic format is HOSTNAME:PORT."
5145msgstr ""
5146
5147#: contrib/config-daemon.scm:1139
5148msgid "SMTP transport"
5149msgstr ""
5150
5151#: contrib/config-daemon.scm:1162
5152msgid "Which port should be used by the UDP IPv4 transport?"
5153msgstr ""
5154
5155#: contrib/config-daemon.scm:1186
5156msgid "What is the maximum transfer unit for UDP?"
5157msgstr ""
5158
5159#: contrib/config-daemon.scm:1198
5160msgid "Which IPs are not allowed to connect?"
5161msgstr ""
5162
5163#: contrib/config-daemon.scm:1210
5164msgid ""
5165"Which IPs are allowed to connect? Leave empty to allow connections from any "
5166"IP."
5167msgstr ""
5168
5169#: contrib/config-daemon.scm:1246
5170msgid "UDP transport"
5171msgstr ""
5172
5173#: contrib/config-daemon.scm:1268
5174#, fuzzy
5175msgid "Network interface"
5176msgstr "Interfaz de red:"
5177
5178#: contrib/config-daemon.scm:1280
5179msgid "External IP address (leave empty to try auto-detection)"
5180msgstr ""
5181
5182#: contrib/config-daemon.scm:1292
5183msgid "External IPv6 address (leave empty to try auto-detection)"
5184msgstr ""
5185
5186#: contrib/config-daemon.scm:1304
5187msgid "Transports"
5188msgstr ""
5189
5190#: contrib/config-daemon.scm:1326
5191msgid "What is the maximum number of bytes per second that we may receive?"
5192msgstr ""
5193
5194#: contrib/config-daemon.scm:1338
5195msgid "What is the maximum number of bytes per second that we may send?"
5196msgstr ""
5197
5198#: contrib/config-daemon.scm:1350
5199msgid "What is the maximum CPU load (percentage)?"
5200msgstr ""
5201
5202#: contrib/config-daemon.scm:1351
5203msgid ""
5204"The highest tolerable CPU load. Load here always refers to the total system "
5205"load, that is it includes CPU utilization by other processes. A value of 50 "
5206"means that once your 1 minute-load average goes over 50% non-idle, GNUnet "
5207"will try to reduce CPU consumption until the load goes under the threshold. "
5208"Reasonable values are typically between 50 and 100. Multiprocessors may use "
5209"values above 100."
5210msgstr ""
5211
5212#: contrib/config-daemon.scm:1362
5213msgid "What is the maximum IO load (permille)?"
5214msgstr ""
5215
5216#: contrib/config-daemon.scm:1364
5217msgid ""
5218"The highest tolerable IO load. Load here refers to the percentage of CPU "
5219"cycles wasted waiting for IO for the entire system, that is it includes disk "
5220"utilization by other processes. A value of 10 means that once the average "
5221"number of cycles wasted waiting for IO is more than 10% non-idle, GNUnet "
5222"will try to reduce IO until the load goes under the threshold. Reasonable "
5223"values are typically between 10 and 75."
5224msgstr ""
5225
5226#: contrib/config-daemon.scm:1375
5227msgid "What is the maximum CPU load (hard limit)?"
5228msgstr ""
5229
5230#: contrib/config-daemon.scm:1376
5231msgid ""
5232"The highest tolerable CPU load. This is the hard limit, so once it is "
5233"reached, gnunetd will start to massively drop data to reduce the load. Use "
5234"with caution."
5235msgstr ""
5236
5237#: contrib/config-daemon.scm:1387
5238msgid "What is the maximum upstream bandwidth (hard limit)?"
5239msgstr ""
5240
5241#: contrib/config-daemon.scm:1388
5242msgid ""
5243"The limit is given as a percentage of the MAXNETUPBPS limit. Use 100 to "
5244"have MAXNETUPBPS be the hard limit. Use zero for no limit."
5245msgstr ""
5246
5247#: contrib/config-daemon.scm:1400
5248msgid "What priority should gnunetd use to run?"
5249msgstr ""
5250
5251#: contrib/config-daemon.scm:1401
5252msgid ""
5253"You can specify priorities like NORMAL, ABOVE NORMAL, BELOW NORMAL, HIGH and "
5254"IDLE or a numerical integer value (man nice). The default is IDLE, which "
5255"should result in gnunetd only using resources that would otherwise be idle."
5256msgstr ""
5257
5258#: contrib/config-daemon.scm:1413
5259msgid "Should we disable random padding (experimental option)?"
5260msgstr ""
5261
5262#: contrib/config-daemon.scm:1425
5263msgid "Use basic bandwidth limitation? (YES/NO). If in doubt, say YES."
5264msgstr ""
5265
5266#: contrib/config-daemon.scm:1427
5267msgid ""
5268"Basic bandwidth limitation (YES) means simply that the bandwidth limits "
5269"specified apply to GNUnet and only to GNUnet. If set to YES, you simply "
5270"specify the maximum bandwidth (upstream and downstream) that GNUnet is "
5271"allowed to use and GNUnet will stick to those limitations. This is useful "
5272"if your overall bandwidth is so large that the limit is mostly used to "
5273"ensure that enough capacity is left for other applications. Even if you "
5274"want to dedicate your entire connection to GNUnet you should not set the "
5275"limits to values higher than what you have since GNUnet uses those limits to "
5276"determine for example the number of connections to establish (and it would "
5277"be inefficient if that computation yields a number that is far too high). \n"
5278"\n"
5279"While basic bandwidth limitation is simple and always works, there are some "
5280"situations where it is not perfect. Suppose you are running another "
5281"application which performs a larger download. During that particular time, "
5282"it would be nice if GNUnet would throttle its bandwidth consumption "
5283"(automatically) and resume using more bandwidth after the download is "
5284"complete. This is obviously advanced magic since GNUnet will have to "
5285"monitor the behavior of other applications. Another scenario is a monthly "
5286"cap on bandwidth imposed by your ISP, which you would want to ensure is "
5287"obeyed. Here, you may want GNUnet to monitor the traffic from other "
5288"applications to ensure that the combined long-term traffic is within the pre-"
5289"set bounds. Note that you should probably not set the bounds tightly since "
5290"GNUnet may observe that the bounds are about to be broken but would be "
5291"unable to stop other applications from continuing to use bandwidth.\n"
5292"\n"
5293"If either of these two scenarios applies, set BASICLIMITING to NO. Then set "
5294"the bandwidth limits to the COMBINED amount of traffic that is acceptable "
5295"for both GNUnet and other applications. GNUnet will then immediately "
5296"throttle bandwidth consumption if the short-term average is above the limit, "
5297"and it will also try to ensure that the long-term average is below the "
5298"limit. Note however that using NO can have the effect of GNUnet (almost) "
5299"ceasing operations after other applications perform high-volume downloads "
5300"that are beyond the defined limits. GNUnet would reduce consumption until "
5301"the long-term limits are again within bounds.\n"
5302"\n"
5303"NO only works on platforms where GNUnet can monitor the amount of traffic "
5304"that the local host puts out on the network. This is only implemented for "
5305"Linux and Win32. In order for the code to work, GNUnet needs to know the "
5306"specific network interface that is used for the external connection (after "
5307"all, the amount of traffic on loopback or on the LAN should never be counted "
5308"since it is irrelevant)."
5309msgstr ""
5310
5311#: contrib/config-daemon.scm:1444
5312#, fuzzy
5313msgid "Network interface to monitor"
5314msgstr "Interfaz de red:"
5315
5316#: contrib/config-daemon.scm:1445
5317msgid ""
5318"For which interfaces should we do accounting? GNUnet will evaluate the "
5319"total traffic (not only the GNUnet related traffic) and adjust its bandwidth "
5320"usage accordingly. You can currently only specify a single interface. GNUnet "
5321"will also use this interface to determine the IP to use. Typical values are "
5322"eth0, ppp0, eth1, wlan0, etc. 'ifconfig' will tell you what you have. "
5323"Never use 'lo', that just won't work. Under Windows, specify the index "
5324"number reported by 'gnunet-win-tool -n'."
5325msgstr ""
5326
5327#: contrib/config-daemon.scm:1456
5328#, fuzzy
5329msgid "Load management"
5330msgstr "Argumentos en la linea de comandos inválidos.\n"
5331
5332#: contrib/config-daemon.scm:1482 contrib/config-client.scm:413
5333msgid "Root node"
5334msgstr ""
5335
5336#: contrib/config-client.scm:153
5337msgid "Where should gnunet-clients write their logs?"
5338msgstr ""
5339
5340#: contrib/config-client.scm:185
5341msgid "On which machine and port is gnunetd running (for clients)?"
5342msgstr ""
5343
5344#: contrib/config-client.scm:186
5345#, fuzzy
5346msgid "This is equivalent to the -H option. The format is IP:PORT."
5347msgstr "Muestra el valor de la opción"
5348
5349#: contrib/config-client.scm:197
5350#, fuzzy
5351msgid "What is the path to the configuration file for gnunetd?"
5352msgstr "Esta es la herramienta de configuración de GNUnet."
5353
5354#: contrib/config-client.scm:198
5355msgid "This option is used when clients need to start gnunetd."
5356msgstr ""
5357
5358#: contrib/config-client.scm:210
5359#, fuzzy
5360msgid "General options"
5361msgstr "Otras configuraciones"
5362
5363#: contrib/config-client.scm:227
5364msgid "Do not add metadata listing the creation time for inserted content"
5365msgstr ""
5366
5367#: contrib/config-client.scm:239
5368msgid "Which non-default extractors should GNUnet use for keyword extractors"
5369msgstr ""
5370
5371#: contrib/config-client.scm:240
5372msgid ""
5373"Specify which additional extractor libraries should be used. gnunet-insert "
5374"uses libextractor to extract keywords from files. libextractor can be "
5375"dynamically extended to handle additional file formats. If you want to use "
5376"more than the default set of extractors, specify additional extractor "
5377"libraries here. The format is [[-]LIBRARYNAME[:[-]LIBRARYNAME]*].\n"
5378"\n"
5379"The default is to use filenames and to break larger words at spaces (and "
5380"underscores, etc.). This should be just fine for most people. The '-' "
5381"before a library name indicates that this should be executed last and makes "
5382"only sense for the split-library."
5383msgstr ""
5384
5385#: contrib/config-client.scm:253
5386msgid "How many entries should the URI DB table have?"
5387msgstr ""
5388
5389#: contrib/config-client.scm:254
5390msgid ""
5391"GNUnet uses two bytes per entry on the disk. This database is used to keep "
5392"track of how a particular URI has been used in the past. For example, "
5393"GNUnet may remember that a particular URI has been found in a search "
5394"previously or corresponds to a file uploaded by the user. This information "
5395"can then be used by user-interfaces to filter URI lists, such as search "
5396"results. If the database is full, older entries will be discarded. The "
5397"default value should be sufficient without causing undue disk utilization."
5398msgstr ""
5399
5400#: contrib/config-client.scm:265
5401msgid "Location of the file specifying metadata for the auto-share directory"
5402msgstr ""
5403
5404#: contrib/config-client.scm:277
5405msgid ""
5406"Location of the file with the PID of any running gnunet-auto-share daemon "
5407"process"
5408msgstr ""
5409
5410#: contrib/config-client.scm:289
5411msgid "Location of the log file for gnunet-auto-share"
5412msgstr ""
5413
5414#: contrib/config-client.scm:301
5415msgid "File-Sharing options"
5416msgstr ""
5417
5418#: contrib/config-client.scm:319
5419msgid "Which plugins should be loaded by gnunet-gtk?"
5420msgstr ""
5421
5422#: contrib/config-client.scm:320
5423msgid ""
5424"Load the about plugin for the about dialog. The daemon plugin allows "
5425"starting and stopping of gnunetd and displays information about gnunetd. "
5426"The fs plugin provides the file-sharing functionality. The stats plugin "
5427"displays various statistics about gnunetd."
5428msgstr ""
5429
5430#: contrib/config-client.scm:331
5431msgid "How frequently (in milli-seconds) should the statistics update?"
5432msgstr ""
5433
5434#: contrib/config-client.scm:332
5435msgid ""
5436"Each pixel in the stats dialog corresponds to the time interval specified "
5437"here."
5438msgstr ""
5439
5440#: contrib/config-client.scm:344
5441msgid "Do not show thumbnail previews from meta-data in search results"
5442msgstr ""
5443
5444#: contrib/config-client.scm:345
5445msgid ""
5446"This option is useful for people who maybe offended by some previews or use "
5447"gnunet-gtk at work and would like to avoid bad surprises."
5448msgstr ""
5449
5450#: contrib/config-client.scm:356
5451msgid "Do not show search results for files that were uploaded by us"
5452msgstr ""
5453
5454#: contrib/config-client.scm:357
5455msgid ""
5456"This option is useful to eliminate files that the user already has from the "
5457"search. Naturally, enabling this option maybe confusing because some "
5458"obviously expected search results would no longer show up. This option only "
5459"works if the URI_DB_SIZE option under FS is not zero (since the URI DB is "
5460"used to determine which files the user is sharing)"
5461msgstr ""
5462
5463#: contrib/config-client.scm:369
5464msgid "To which directory should gnunet-gtk save downloads to?"
5465msgstr ""
5466
5467#: contrib/config-client.scm:381
5468msgid "Options related to gnunet-gtk"
5469msgstr ""
5470
5471#: contrib/config-client.scm:401
5472#, fuzzy
5473msgid "Full pathname of GNUnet client HOME directory"
5474msgstr "Error en el formato del fichero (¿no es un directorio de GNUnet?)\n"
5475
5476#: contrib/config-client.scm:402
5477msgid "The directory for GNUnet files that belong to the user."
5478msgstr ""
5479
5480#, fuzzy
5481#~ msgid "Failed to connect to %s:%u in %ds\n"
5482#~ msgstr "Fallo al conectar a gnunetd.\n"
5483
5484#, fuzzy
5485#~ msgid "Failed to connect to %s:%u\n"
5486#~ msgstr "Fallo al conectar a gnunetd.\n"
5487
5488#, fuzzy
5489#~ msgid "`%s' failed at %s:%d in %s with error: %s\n"
5490#~ msgstr "'%s' falló en %s: %d con el error: %s\n"
5491
5492#, fuzzy
5493#~ msgid "`%s' failed at %s:%d with error: %s"
5494#~ msgstr "'%s' falló en %s: %d con el error: %s\n"
5495
5496#, fuzzy
5497#~ msgid "`%s' failed at %s:%d with error `%s' after %llums\n"
5498#~ msgstr "'%s' falló en %s: %d con el error: %s\n"
5499
5500#~ msgid "Trying to use file `%s' for MySQL configuration.\n"
5501#~ msgstr "Intentando usar el fichero '%s' para la configuración de MySQL.\n"
5502
5503#~ msgid "'%s(%s,%s)' succeeded\n"
5504#~ msgstr "'%s (%s, %s)' logrado satisfactoriamente\n"
5505
5506#~ msgid "'%s(%s,%s)' failed.\n"
5507#~ msgstr "'%s(%s, %s)' falló.\n"
5508
5509#, fuzzy
5510#~ msgid ""
5511#~ "Directory `%s' in directory `%s' does not match naming convention. "
5512#~ "Removed.\n"
5513#~ msgstr ""
5514#~ "El fichero '%s' en el directorio '%s' no sigue la convención de nombres. "
5515#~ "Eliminando.\n"
5516
5517#, fuzzy
5518#~ msgid "You must specify one and only one directory for sharing.\n"
5519#~ msgstr "Debes especificar uno y solo un fichero para desindexar.\n"
5520
5521#~ msgid ""
5522#~ "set interval for availability of updates to SECONDS (for namespace "
5523#~ "insertions only)"
5524#~ msgstr ""
5525#~ "cambia el intervalo de disponibilidad de las actualizaciones a SEGUNDOS "
5526#~ "(para inserciones en el espacio solamente)"
5527
5528#~ msgid ""
5529#~ "specifies this as an aperiodic but updated publication (for namespace "
5530#~ "insertions only)"
5531#~ msgstr ""
5532#~ "especifica esto como una aperiódica pero actualizada publicación (para "
5533#~ "inserciones en el espacio únicamente)"
5534
5535#~ msgid "specify creation time for SBlock (see man-page for format)"
5536#~ msgstr ""
5537#~ "especifica el tiempo para la creación de un Superbloque (vea la página "
5538#~ "del manual para el formato)"
5539
5540#~ msgid ""
5541#~ "ID of the previous version of the content (for namespace update only)"
5542#~ msgstr ""
5543#~ "ID de la versión previa del contenido (para actualizaciones del espacio "
5544#~ "únicamente)"
5545
5546#~ msgid "Parsing time failed. Use `%s' format.\n"
5547#~ msgstr "Se produjo un fallo al analizar el tiempo. Use el formato '%s'.\n"
5548
5549#, fuzzy
5550#~ msgid "File `%s' does not contain a pseudonym, trying to remove.\n"
5551#~ msgstr "El fichero '%s' no contiene un pseudónimo.\n"
5552
5553#~ msgid "Format of file `%s' is invalid.\n"
5554#~ msgstr "El formato del fichero '%s' no es válido.\n"
5555
5556#~ msgid "Publication interval for periodic publication changed."
5557#~ msgstr "Intervalo de publicación periódica cambiado."
5558
5559#~ msgid ""
5560#~ "Publishing update for periodically updated content more than a week ahead "
5561#~ "of schedule.\n"
5562#~ msgstr ""
5563#~ "publicaciones actualizadas para contenido actualizado periódicamente más "
5564#~ "de una semana antes de la tarea planificada.\n"
5565
5566#, fuzzy
5567#~ msgid "Received malformed message via TCP. Closing.\n"
5568#~ msgstr "Recibido el mensaje '%s' con un mal formato. Omitiendo.\n"
5569
5570#~ msgid "Cannot create pseudonym `%s', file `%s' exists.\n"
5571#~ msgstr "Imposible crear el pseudónimo '%s', el fichero '%s' ya existe.\n"
5572
5573#, fuzzy
5574#~ msgid "Error writing to socket.\n"
5575#~ msgstr "Error creando usuario"
5576
5577#~ msgid "GNUnet configuration assistant"
5578#~ msgstr "Asistente de configuración de GNUnet"
5579
5580#~ msgid ""
5581#~ "Welcome to GNUnet!\n"
5582#~ "\n"
5583#~ "This assistant will ask you a few basic questions in order to configure "
5584#~ "GNUnet.\n"
5585#~ "\n"
5586#~ "Please visit our homepage at\n"
5587#~ "\thttp://gnunet.org\n"
5588#~ "and join our community at\n"
5589#~ "\thttps://gnunet.org/drupal/\n"
5590#~ "\n"
5591#~ "Have a lot of fun,\n"
5592#~ "\n"
5593#~ "The GNUnet team"
5594#~ msgstr ""
5595#~ "¡Bienvenido a GNUnet!\n"
5596#~ "\n"
5597#~ "Este asistente le preguntará unos datos básicos para configurar GNUnet.\n"
5598#~ "\n"
5599#~ "Por favor, visite nuestra página en\n"
5600#~ "\thttps://gnunet.org/drupal/\n"
5601#~ "\n"
5602#~ "Diviertase,\n"
5603#~ "\n"
5604#~ "El equipo de GNUnet"
5605
5606#~ msgid "Next"
5607#~ msgstr "Siguiente"
5608
5609#~ msgid ""
5610#~ "Enter information about your network connection here.\n"
5611#~ "\n"
5612#~ "The \"Network interface\" is the device that connects your computer to "
5613#~ "the internet. This is usually a modem, an ISDN card or a network card in "
5614#~ "case you are using DSL.\n"
5615#~ "\n"
5616#~ "If your provider always assigns the same IP-Address to you (a \"static\" "
5617#~ "IP-Address), enter it into the \"IP-Address\" field. If your IP-Address "
5618#~ "changes every now and then (\"dynamic\" IP-Address) but there's a "
5619#~ "hostname that always points to your actual IP-Address (\"Dynamic DNS\"), "
5620#~ "you can also enter it here.\n"
5621#~ "If in doubt, leave the field empty. GNUnet will then try to determine "
5622#~ "your IP-Address.\n"
5623#~ "\n"
5624#~ "If you are connected to the internet through another computer doing SNAT, "
5625#~ "a router or a \"hardware firewall\" and other computers on the internet "
5626#~ "cannot connect to this computer, check the last option on this page. "
5627#~ "Leave it unchecked on direct connections through modems, ISDN cards and "
5628#~ "DNAT (also known as \"port forwarding\")."
5629#~ msgstr ""
5630#~ "Introduce información acerca de tu conexión aquí.\n"
5631#~ "\n"
5632#~ "La \"Interfaz de red\" es el dispositivo que conecta tu ordenador a "
5633#~ "Internet. Normalmente es un módem, una tarjeta de RDSI, un módem ADSL o "
5634#~ "una tarjeta de red en el caso de un router.\n"
5635#~ "\n"
5636#~ "Si tu proveedor siempre te da la misma dirección IP (una dirección IP "
5637#~ "\"estática\") introducelo en el campo \"Dirección IP\". Si tu dirección "
5638#~ "IP cambia (una dirección IP \"dinámica\") pero hay un nombre de dominio "
5639#~ "que siempre apunta a tu dirección IP actual (\"DNS dinámica\") también "
5640#~ "puedes introducirla aquí.\n"
5641#~ "En caso de duda deja el campo vacío. GNUnet intentara determinar tu "
5642#~ "dirección IP automaticamente.\n"
5643#~ "\n"
5644#~ "Si tu estas conectado a Internet a través de otro ordenador haciendo "
5645#~ "SNAT, a un router o a un \"cortafuegos de hardware\" y otros ordenadores "
5646#~ "no pueden conectar con tu ordenador marca la última opción en ésta "
5647#~ "página. Déjala sin marcar en conexiones directas a través de modems, "
5648#~ "tarjetas de RDSI y DNAT (también conocido como \"seguimiento de puertos"
5649#~ "\")."
5650
5651#~ msgid "Computer cannot receive inbound connections (SNAT/Firewall)"
5652#~ msgstr ""
5653#~ "El ordenador no puede recibir conexiones entrantes (SNAT/Cortafuegos)"
5654
5655#~ msgid "IP-Address/Hostname:"
5656#~ msgstr "Dirección IP/Nombre del dominio"
5657
5658#, fuzzy
5659#~ msgid "Network interface:"
5660#~ msgstr "Interfaz de red:"
5661
5662#, fuzzy
5663#~ msgid "Network connection"
5664#~ msgstr "Configuración de GNUnet"
5665
5666#~ msgid ""
5667#~ "You can limit GNUnet's ressource usage here.\n"
5668#~ "\n"
5669#~ "\"Bandwidth limitation\" is how much data may be sent per second. If you "
5670#~ "have a flatrate you can set it to the maximum speed of your internet "
5671#~ "connection.\n"
5672#~ "\n"
5673#~ "The \"Max. CPU usage\" is the percentage of processor time GNUnet is "
5674#~ "allowed to use."
5675#~ msgstr ""
5676#~ "Puedes limitar el uso de recursos de GNUnet aquí.\n"
5677#~ "\n"
5678#~ "\"Limitación de ancho de banda\" es cuantos datos pueden ser mandados por "
5679#~ "segundo. Si tienes una tarifa plana puedes seleccionar la velocidad "
5680#~ "máxima de tu conexión a Internet.\n"
5681#~ "\n"
5682#~ "El \"Uso máximo de CPU\" es el porcentaje del tiempo de procesado que "
5683#~ "GNUnet puede usar."
5684
5685#~ msgid "Downstream (Bytes/s):"
5686#~ msgstr "Bajada (Bytes/s):"
5687
5688#~ msgid "Upstream (Bytes/s):"
5689#~ msgstr "Subida (Bytes/s):"
5690
5691#~ msgid "Bandwidth limitation"
5692#~ msgstr "Limitación del ancho de banda"
5693
5694#~ msgid "Use denoted bandwidth for GNUnet"
5695#~ msgstr "Usa el ancho de banda marcado para GNUnet"
5696
5697#~ msgid "Share denoted bandwidth with other applications"
5698#~ msgstr "Comparte el ancho de banda marcado con otras aplicaciones"
5699
5700#~ msgid "Bandwidth sharing"
5701#~ msgstr "Ancho de banda compartido"
5702
5703#~ msgid "Max. CPU usage (%):"
5704#~ msgstr "Uso máximo de la CPU (%):"
5705
5706#~ msgid "CPU usage"
5707#~ msgstr "Uso de CPU"
5708
5709#~ msgid "Load limitation"
5710#~ msgstr "Limitación de carga"
5711
5712#~ msgid ""
5713#~ "GNUnet is able to store data from other peers in your datastore. This is "
5714#~ "useful if an adversary has access to your inserted content and you need "
5715#~ "to deny that the content is yours. With \"content migration\" on, the "
5716#~ "content could have \"migrated\" over the internet to your node without "
5717#~ "your knowledge.\n"
5718#~ "It also helps to spread popular content over different peers to enhance "
5719#~ "availability.\n"
5720#~ "\n"
5721#~ "The GNUnet datastore contains all data that GNUnet generates (index data, "
5722#~ "inserted and migrated content). Its maximum size can be specified below.\n"
5723#~ "\n"
5724#~ "If you are an experienced user, you may want to tweak your GNUnet "
5725#~ "installation using the enhanced configurator.\n"
5726#~ "\n"
5727#~ "After changing the configuration and/or updating GNUnet, it is sometimes "
5728#~ "required to run gnunet-update to update internal data structures. "
5729#~ "Depending on the changes made, this may take some time."
5730#~ msgstr ""
5731#~ "GNUnet es capaz de almacenar datos de otros pares en tu base de datos. "
5732#~ "Ésto es útil si un adversario tiene acceso a tu contenido y tu necesitas "
5733#~ "negar que ese contenido sea tuyo. Con la \"migración de contenido\" "
5734#~ "activada, tu contenido puede haber \"migrado\" por Internet hasta tu nodo "
5735#~ "sin tu conocimiento.\n"
5736#~ "Ésto también ayuda a difundir contenidos populares por diferentes pares "
5737#~ "para facilitar su disponibilidad.\n"
5738#~ "\n"
5739#~ "La base de datos de GNUnet contiene todos los datos que GNUnet genera "
5740#~ "(índices, contenido insertado y descargado). Su máximo tamaño puede ser "
5741#~ "especificado debajo.\n"
5742#~ "\n"
5743#~ "Si eres un usuario experimentado, puedes desear exprimir tu instalación "
5744#~ "de GNUnet usando la herramienta de configuración avanzada.\n"
5745#~ "\n"
5746#~ "Después de cambiar la configuración y/o actualizar GNUnet, a veces "
5747#~ "esnecesario ejecutar gnunet-update para actualizar las estructuras de "
5748#~ "datos internas. Dependiendo de los cambios que se hayan hecho, ésto podrá "
5749#~ "tomar algún tiempo."
5750
5751#~ msgid "Store migrated content"
5752#~ msgstr "Almacena contenido migrado"
5753
5754#~ msgid "Maximum datastore size (MB):"
5755#~ msgstr "Máximo tamaño de almacenamiento (MB):"
5756
5757#~ msgid "Start the GNUnet background process on computer startup"
5758#~ msgstr "Arranca el demonio de GNUnet al encender el ordenador"
5759
5760#~ msgid "Open the enhanced configurator"
5761#~ msgstr "Abre el editor de configuración avanzado"
5762
5763#, fuzzy
5764#~ msgid "Run gnunet-update"
5765#~ msgstr "¡gnunet-update falló!"
5766
5767#, fuzzy
5768#~ msgid "Other settings"
5769#~ msgstr "Otras configuraciones"
5770
5771#~ msgid "Finish"
5772#~ msgstr "Finalizar"
5773
5774#~ msgid ""
5775#~ "Define the user and the group owning the GNUnet service here.\n"
5776#~ "\n"
5777#~ "For security reasons, it is a good idea to let this setup create a new "
5778#~ "user account and a new group under which the GNUnet service is started at "
5779#~ "system startup.\n"
5780#~ "\n"
5781#~ "However, GNUnet may not be able to access files other than its own. This "
5782#~ "includes files you want to publish in GNUnet. You'll have to grant read "
5783#~ "permissions to the user specified below.\n"
5784#~ "\n"
5785#~ "Leave the fields empty to run GNUnet with system privileges."
5786#~ msgstr ""
5787#~ "Define el usuario y el grupo bajo el que correrán los servicios de GNUnet "
5788#~ "aquí.\n"
5789#~ "\n"
5790#~ "Por razones de seguridad, es una buena idea dejar que la configuración "
5791#~ "cree una nueva cuenta de usuario y un nuevo grupo bajo el cual el "
5792#~ "servicio de GNUnet es arrancado al iniciar el sistema.\n"
5793#~ "\n"
5794#~ "Por consiguiente, GNUnet no tiene la posibilidad de acceder a otros "
5795#~ "ficheros que no sean los que posee. Ésto incluye los ficheros que quieras "
5796#~ "publicar en GNUnet. Tendrás que garantizar que el usuario especificado "
5797#~ "aquí posea permisos de lectura.\n"
5798#~ "\n"
5799#~ "Deja los campos vacíos para arrancar GNUnet con privilegios de sistema."
5800
5801#~ msgid "User account:"
5802#~ msgstr "Cuenta de usuario:"
5803
5804#~ msgid "Group:"
5805#~ msgstr "Grupo:"
5806
5807#~ msgid "gnunet-setup"
5808#~ msgstr "gnunet-setup"
5809
5810#, fuzzy
5811#~ msgid "Save configuration"
5812#~ msgstr "Configuración de GNUnet"
5813
5814#, fuzzy
5815#~ msgid "Show copyright information for gnunet-setup."
5816#~ msgstr "Se produjo un error leyendo información de gnunetd.\n"
5817
5818#, fuzzy
5819#~ msgid "About gnunet-setup"
5820#~ msgstr "gnunet-setup"
5821
5822#, fuzzy
5823#~ msgid "(C) 2001-2007 Christian Grothoff (and other contributing authors)"
5824#~ msgstr ""
5825#~ "C) 2001-2006 Christian Grothoff (y otros autores que han contribuido)"
5826
5827#~ msgid "This is the configuration tool for GNUnet."
5828#~ msgstr "Esta es la herramienta de configuración de GNUnet."
5829
5830#~ msgid "Could not unlink temporary file `%s': %s\n"
5831#~ msgstr "Imposible desenlazar temporalmente el fichero '%s': %s\n"
5832
5833#~ msgid "Write(%d, %p, %d) failed: %s\n"
5834#~ msgstr "Escribiendo(%d, %p, %d) se produjo un fallo: %s\n"
5835
5836#~ msgid "AND"
5837#~ msgstr "Y"
5838
5839#, fuzzy
5840#~ msgid "Could not find IPv6 address of host `%s': %s\n"
5841#~ msgstr "Imposible encontrar la IP del host '%s': %s\n"
5842
5843#, fuzzy
5844#~ msgid "Error running search (no reason given)."
5845#~ msgstr "Se produjo un fallo al comenzar la búsqueda. Consulte los logs.\n"
5846
5847#, fuzzy
5848#~ msgid "Download failed (no reason given)"
5849#~ msgstr "La descarga del ERCS falló (vea los logs)."
5850
5851#~ msgid "Message received from client is invalid\n"
5852#~ msgstr "El mensaje recibido del cliente es inválido\n"
5853
5854#~ msgid "Maximum number of chat clients reached.\n"
5855#~ msgstr "Número máximo de clientes en el chat alcanzado.\n"
5856
5857#~ msgid "Now %d of %d chat clients at this node.\n"
5858#~ msgstr "Ahora hay %d de %d clientes de chat en este nodo.\n"
5859
5860#, fuzzy
5861#~ msgid "Invalid data in %s (NCS). Trying to fix (by deletion).\n"
5862#~ msgstr "Datos no válidos en %s. Intentando fijar (por borrado).\n"
5863
5864#~ msgid "HTTP: Could not determine my public IP address.\n"
5865#~ msgstr "HTTP: Imposible determinar mi dirección IP pública.\n"
5866
5867#~ msgid ""
5868#~ "%s::%s - RPC %s:%p could not be unregistered: another callback registered "
5869#~ "under that name: %p\n"
5870#~ msgstr ""
5871#~ "%s::%s - RPC %s:%p no pudo ser desregistrada: otro evento está "
5872#~ "actualmente registrado con este nombre (%p)\n"
5873
5874#~ msgid "%s::%s - RPC %s:%p could not be unregistered: not found\n"
5875#~ msgstr "%s::%s - RPC %s:%p no pudo ser desregistrada: no encontrada\n"
5876
5877#~ msgid "Invalid message of type %u received. Dropping.\n"
5878#~ msgstr "Mensaje no válido del tipo %u recibido. Omitiendo.\n"
5879
5880#~ msgid "Dropping RPC request %u: message malformed.\n"
5881#~ msgstr "Omitiendo la petición RPC %u: mensaje mal formado.\n"
5882
5883#~ msgid "`%s' called with timeout above 1 hour (bug?)\n"
5884#~ msgstr "'%s' fue llamada con un retraso de una hora(¿bug?)\n"
5885
5886#~ msgid "RPC not unregistered: %s:%p\n"
5887#~ msgstr "No fue desregistrada RPC: %s:%p\n"
5888
5889#~ msgid "RPC async reply invalid.\n"
5890#~ msgstr "RPC respuesta asíncrona no válida.\n"
5891
5892#~ msgid "async RPC reply not received.\n"
5893#~ msgstr "respuesta RPC asíncrona no recibida.\n"
5894
5895#~ msgid "Could not determine my public IPv6 address.\n"
5896#~ msgstr "Imposible determinar mi dirección IPv6 pública.\n"
5897
5898#~ msgid "`%s': unknown service: %s\n"
5899#~ msgstr "'%s': servicio desconocido: %s\n"
5900
5901#, fuzzy
5902#~ msgid "# bytes received via TCP6"
5903#~ msgstr "# bytes recibidos por TCP"
5904
5905#, fuzzy
5906#~ msgid "# bytes sent via TCP6"
5907#~ msgstr "# bytes enviados por TCP"
5908
5909#, fuzzy
5910#~ msgid "# bytes dropped by TCP6 (outgoing)"
5911#~ msgstr "# bytes omitidos por TCP (salientes)"
5912
5913#~ msgid "UDP6: Could not determine my public IPv6 address.\n"
5914#~ msgstr "UDP6: Imposible determinar mi dirección IPv6 pública.\n"
5915
5916#, fuzzy
5917#~ msgid "# bytes received via UDP6"
5918#~ msgstr "# bytes recibidos vía UDP"
5919
5920#, fuzzy
5921#~ msgid "# bytes sent via UDP6"
5922#~ msgstr "# bytes enviados vía UDP"
5923
5924#, fuzzy
5925#~ msgid "# bytes dropped by UDP6 (outgoing)"
5926#~ msgstr "# bytes omitidos por UDP (salientes)"
5927
5928#, fuzzy
5929#~ msgid "Received malformed message instead of welcome message. Closing.\n"
5930#~ msgstr "Recibido el mensaje '%s' con un mal formato. Omitiendo.\n"
5931
5932#, fuzzy
5933#~ msgid "Received malformed message from tcp-peer connection. Closing.\n"
5934#~ msgstr "Recibido el mensaje '%s' con un mal formato. Omitiendo.\n"
5935
5936#, fuzzy
5937#~ msgid "TCP: Could not determine my public IP address.\n"
5938#~ msgstr "HTTP: Imposible determinar mi dirección IP pública.\n"
5939
5940#~ msgid "Cannot connect to %u.%u.%u.%u:%u: %s\n"
5941#~ msgstr "Imposible conectar a %u.%u.%u.%u:%u: %s\n"
5942
5943#~ msgid "UDP: Could not determine my public IP address.\n"
5944#~ msgstr "UDP: Imposible determinar mi dirección IP pública.\n"
5945
5946#~ msgid "Failed to send message of size %d via UDP to %u.%u.%u.%u:%u: %s\n"
5947#~ msgstr ""
5948#~ "Falló al mandar el mensaje de tamaño %d a través de UDP a %u.%u.%u.%u:%u: "
5949#~ "%s\n"
5950
5951#, fuzzy
5952#~ msgid "Received malformed message from udp-peer connection. Closing.\n"
5953#~ msgstr "Recibido el mensaje '%s' con un mal formato. Omitiendo.\n"
5954
5955#~ msgid "exit after receiving LIMIT results"
5956#~ msgstr "sale después de recibir LIMIT resultados"
5957
5958#, fuzzy
5959#~ msgid "wait DELAY seconds for search results before aborting"
5960#~ msgstr "espera TIMEOUT segundos para buscar resultados después de abortar"
5961
5962#~ msgid "Message received from peer is invalid.\n"
5963#~ msgstr "El mensaje recibido del par es inválido.\n"
5964
5965#~ msgid "GAP received invalid content from `%s'\n"
5966#~ msgstr "GAP recibido contenido no válido de '%s'\n"
5967
5968#~ msgid "myself"
5969#~ msgstr "yo"
5970
5971#~ msgid ""
5972#~ "Cover traffic requested but traffic service not loaded. Rejecting "
5973#~ "request.\n"
5974#~ msgstr ""
5975#~ "Solicitada la cobertura de tráfico pero el servicio de tráfico no ha sido "
5976#~ "cargado. Rechazando la petición.\n"
5977
5978#~ msgid "Cannot satisfy desired level of anonymity, ignoring request.\n"
5979#~ msgstr ""
5980#~ "Imposible satisfacer el nivel deseado de anonimato, ignorando la "
5981#~ "petición.\n"
5982
5983#~ msgid "`%s' registering handlers %d %d\n"
5984#~ msgstr "'%s' registrando manejadores %d %d\n"
5985
5986#, fuzzy
5987#~ msgid "Indexed file disappeared, deleting block for query `%s'\n"
5988#~ msgstr ""
5989#~ "Fichero indexado desaparecido, borrando el bloque para preguntas '%s'\n"
5990
5991#~ msgid ""
5992#~ "Configuration file must specify directory for storage of FS data in "
5993#~ "section `%s' under `%s'.\n"
5994#~ msgstr ""
5995#~ "El fichero de configuración debe especificar un directorio para el "
5996#~ "almacenamiento de los datos de FS en la sección '%s' bajo '%s'.\n"
5997
5998#~ msgid ""
5999#~ "You must specify a postive number for `%s' in the configuration in "
6000#~ "section `%s'.\n"
6001#~ msgstr ""
6002#~ "Debes especificar un número positivo para '%s' en la configuración en la "
6003#~ "sección '%s'.\n"
6004
6005#, fuzzy
6006#~ msgid "# FS valid replies received"
6007#~ msgstr "# bytes recibidos por TCP"
6008
6009#~ msgid ""
6010#~ "Content `%s' seems to be not available on the network (tried %u times).\n"
6011#~ msgstr ""
6012#~ "El contenido '%s' parece no estar disponible en la red (intentado %u "
6013#~ "veces).\n"
6014
6015#, fuzzy
6016#~ msgid "Start GNUnet-testbed helper."
6017#~ msgstr "Arranca el cliente de chat de GNUnet"
6018
6019#~ msgid "Cannot connect to LOOPBACK port %d: %s\n"
6020#~ msgstr "Imposible conectar al puerto de LOOPBACK %d: %s\n"
6021
6022#~ msgid "No client service started. Trying again in 30 seconds.\n"
6023#~ msgstr ""
6024#~ "No hay ningún servicio de cliente ejecutandose. Se volverá a intentar en "
6025#~ "30 segundos.\n"
6026
6027#, fuzzy
6028#~ msgid ""
6029#~ "Error (%s) binding the TCP listener to port %d. No proxy service "
6030#~ "started.\n"
6031#~ "Trying again in %d seconds...\n"
6032#~ msgstr ""
6033#~ "No hay ningún servicio de cliente ejecutandose. Se volverá a intentar en "
6034#~ "30 segundos.\n"
6035
6036#~ msgid "Rejected unauthorized connection from %u.%u.%u.%u.\n"
6037#~ msgstr "Rechazada conexión no autorizada de %u.%u.%u.%u.\n"
6038
6039#~ msgid "Protocol violation on socket. Expected command.\n"
6040#~ msgstr "Violación del protocolo en el socket. Esperando comando.\n"
6041
6042#~ msgid "Command `%s' not found!\n"
6043#~ msgstr "¡Comando '%s' no encontrado!\n"
6044
6045#, fuzzy
6046#~ msgid "Start GNUnet testbed controller."
6047#~ msgstr "Arranca el cliente de chat de GNUnet"
6048
6049#~ msgid "Malformed entry in the configuration in section %s under %s: %s\n"
6050#~ msgstr ""
6051#~ "Entrada mal formada en la configuración en la sección %s bajo %s: %s\n"
6052
6053#, fuzzy
6054#~ msgid "Could not send acknowledgement back to client.\n"
6055#~ msgstr "Imposible mandar el mensaje a gnunetd\n"
6056
6057#~ msgid "size of `%s' message is too short. Ignoring.\n"
6058#~ msgstr "el tamaño del '%s' mensaje es demasiado corto. Ignorandolo.\n"
6059
6060#~ msgid "size of `%s' message is wrong. Ignoring.\n"
6061#~ msgstr "el tamaño del mensaje '%s' es erroneo. Se ignora.\n"
6062
6063#~ msgid "TESTBED could not generate hello message for protocol %u\n"
6064#~ msgstr ""
6065#~ "TESTBED no puede generar el mensaje de saludo para el protocolo %u\n"
6066
6067#~ msgid "received invalid `%s' message\n"
6068#~ msgstr "recibido mensaje '%s' no válido\n"
6069
6070#~ msgid "received invalid `%s' message (empty module name)\n"
6071#~ msgstr "recibido mensaje '%s' no válido (nombre del módulo vacío)\n"
6072
6073#~ msgid "loading module `%s' failed. Notifying client.\n"
6074#~ msgstr ""
6075#~ "se produjo un fallo al cargar el módulo '%s'. Notificando al cliente.\n"
6076
6077#~ msgid "unloading module failed. Notifying client.\n"
6078#~ msgstr ""
6079#~ "se produjo un fallo al descargar el módulo. Notificando al cliente.\n"
6080
6081#~ msgid "received invalid `%s' message: %s.\n"
6082#~ msgstr "recibido mensaje '%s' no válido: %s.\n"
6083
6084#~ msgid "'..' is not allowed in file name (%s).\n"
6085#~ msgstr "'..' no esta permitido en el nombre del fichero(%s).\n"
6086
6087#~ msgid "Empty filename for UPLOAD_FILE message is invalid!\n"
6088#~ msgstr ""
6089#~ "¡Nombre del fichero vacío para el mensaje UPLOAD_FILE es inválido!\n"
6090
6091#~ msgid "Filename for UPLOAD_FILE message is not null-terminated (invalid!)\n"
6092#~ msgstr ""
6093#~ "Nombre del fichero para el mensaje UPLOAD_FILE no esta terminado en null "
6094#~ "(¡inválido!)\n"
6095
6096#~ msgid "Invalid message received at %s:%d."
6097#~ msgstr "Mensaje inválido recibido en %s:%d."
6098
6099#, fuzzy
6100#~ msgid "received invalid testbed message of size %u\n"
6101#~ msgstr "recibido mensaje '%s' no válido: %s.\n"
6102
6103#~ msgid "Could not resolve name of HTTP proxy `%s'.\n"
6104#~ msgstr "Imposible resolver el nombre del proxy HTTP '%s'.\n"
6105
6106#~ msgid "Invalid URL `%s' (must begin with `%s')\n"
6107#~ msgstr "URL invalida '%s' (debe comenzar por '%s')\n"
6108
6109#, fuzzy
6110#~ msgid "Could not register testbed, host `%s' unknown\n"
6111#~ msgstr ""
6112#~ "Imposible descargar lista de contactos, servidor '%s' desconocido.\n"
6113
6114#~ msgid "Failed to send HTTP request to host `%s': %s\n"
6115#~ msgstr "Falló al mandar la petición HTTP al host '%s': %s\n"
6116
6117#~ msgid "Failed so send HTTP request `%s' to host `%s': %s\n"
6118#~ msgstr "Falló al mandar la petición HTTP '%s' al host '%s': %s\n"
6119
6120#~ msgid "Exit register (error: no http response read).\n"
6121#~ msgstr "Saliendo del registro (error: no se leyó una respuesta de http).\n"
6122
6123#, fuzzy
6124#~ msgid "Description"
6125#~ msgstr "Pregunta"
6126
6127#, fuzzy
6128#~ msgid "Section"
6129#~ msgstr "Pregunta"
6130
6131#, fuzzy
6132#~ msgid "Option"
6133#~ msgstr "_Opciones"
6134
6135#, fuzzy
6136#~ msgid "Failed to initialize libesmtp: %s.\n"
6137#~ msgstr "Imposible inicializar SQLite.\n"
6138
6139#~ msgid "Sending E-mail to `%s' failed.\n"
6140#~ msgstr "Enviando un correo electrónico a '%s' se produjo un fallo.\n"
6141
6142#, fuzzy
6143#~ msgid "Network configuration: NAT"
6144#~ msgstr "Configuración de GNUnet"
6145
6146#~ msgid ""
6147#~ "Is this machine behind NAT?\n"
6148#~ "\n"
6149#~ "If you are connected to the internet through another computer doing SNAT, "
6150#~ "a router or a \"hardware firewall\" and other computers on the internet "
6151#~ "cannot connect to this computer, say \"yes\" here. Answer \"no\" on "
6152#~ "direct connections through modems, ISDN cards and DNAT (also known as "
6153#~ "\"port forwarding\")."
6154#~ msgstr ""
6155#~ "¿Tu máquina esta detrás de un NAT?\n"
6156#~ "\n"
6157#~ "Si tu estás conectado a Internet a través de otro ordenador haciendo "
6158#~ "SNAT, un router o un \"cortafuegos de hardware\" y otros ordenadores no "
6159#~ "pueden conectarse al tuyo a través de Internet directamente, responde \"si"
6160#~ "\" aquí. Responde \"no\" en conexiones directas a través de módems, "
6161#~ "tarjetas de RDSI y DNAT (también conocido como \"seguimiento de puertos"
6162#~ "\")."
6163
6164#, fuzzy
6165#~ msgid "Configuration of the logging system"
6166#~ msgstr ""
6167#~ "La configuración o la versión de GNUnet cambiaron. ¡Debes ejecutar '%"
6168#~ "s'!\n"
6169
6170#, fuzzy
6171#~ msgid "Run gnunetd as this user."
6172#~ msgstr "Ejecutar gnunet-update"
6173
6174#, fuzzy
6175#~ msgid "Run gnunetd during system startup?"
6176#~ msgstr "Ejecutar gnunet-update"
6177
6178#, fuzzy
6179#~ msgid "Path settings"
6180#~ msgstr "Otras configuraciones"
6181
6182#~ msgid "specify nickname"
6183#~ msgstr "especifica el apodo"
6184
6185#~ msgid "Could not connect to gnunetd.\n"
6186#~ msgstr "Imposible conectar con gnunetd.\n"
6187
6188#~ msgid "You must specify a nickname (use option `%s').\n"
6189#~ msgstr "Debes especificar un apodo (use la opción '%s').\n"
6190
6191#~ msgid "Could not send join message to gnunetd\n"
6192#~ msgstr "Imposible mandar el mensaje a gnunetd\n"
6193
6194#~ msgid "mysql datastore"
6195#~ msgstr "base de datos mysql"
6196
6197#, fuzzy
6198#~ msgid ""
6199#~ "`%s' failed at %s:%d with error: I/%s S/%s SC/%s SS/%s SSC/%s U/%s D/%s "
6200#~ "DG/%s\n"
6201#~ msgstr "'%s' falló en %s: %d con el error: %s\n"
6202
6203#~ msgid "Database failed to delete `%s'.\n"
6204#~ msgstr "Falló al borrar de la base de datos %s.\n"
6205
6206#, fuzzy
6207#~ msgid "Error log:\n"
6208#~ msgstr "Error"
6209
6210#, fuzzy
6211#~ msgid "# bytes received via TCP-OLD"
6212#~ msgstr "# bytes recibidos por TCP"
6213
6214#, fuzzy
6215#~ msgid "# bytes sent via TCP-OLD"
6216#~ msgstr "# bytes enviados por TCP"
6217
6218#, fuzzy
6219#~ msgid "# bytes dropped by TCP-OLD (outgoing)"
6220#~ msgstr "# bytes omitidos por TCP (salientes)"
6221
6222#~ msgid "hello advertisement for protocol %d received.\n"
6223#~ msgstr "Inicio de comunicación del protocolo %d recibido.\n"
6224
6225#~ msgid "`%s' failed (%d, %u). Will not send PING.\n"
6226#~ msgstr "'%s' falló (%d, %u). No se mandará el PING.\n"
6227
6228#~ msgid "Removing hello from peer `%s' (expired %ds ago).\n"
6229#~ msgstr "Eliminando saludo del par '%s' (expiró hace %ds).\n"
6230
6231#~ msgid "No reply received within %llums.\n"
6232#~ msgstr "No se ha recibido una respuesta en %llums.\n"
6233
6234#~ msgid "Waiting for gnunetd to start (%u iterations left)...\n"
6235#~ msgstr "Esperando a gnunetd para empezar (%u ciclos restantes)...\n"
6236
6237#, fuzzy
6238#~ msgid "Deleting expired content. This may take a while.\n"
6239#~ msgstr "Creando nueva clave local (esto puede llevar un tiempo).\n"
6240
6241#~ msgid "User `%s' not known, cannot change UID to it.\n"
6242#~ msgstr "Usuario '%s' desconocido, imposible cambiar la UID a él.\n"
6243
6244#~ msgid ""
6245#~ "Expected welcome on http connection, got garbage. Closing connection.\n"
6246#~ msgstr ""
6247#~ "Esperada bienvenida en la conexión http, encontrada basura. Cerrando la "
6248#~ "conexión.\n"
6249
6250#~ msgid "%s: Rejected connection from blacklisted address %u.%u.%u.%u.\n"
6251#~ msgstr ""
6252#~ "%s: Conexión rechazada de una dirección de la \"lista negra\" %u.%u.%u.%"
6253#~ "u.\n"
6254
6255#~ msgid "Unexpected reply to `%s' operation.\n"
6256#~ msgstr "Respuesta inesperada a la operación '%s'.\n"
6257
6258#~ msgid "join table called NAME"
6259#~ msgstr "únete a la tabla llamada NAME"
6260
6261#~ msgid "Malformed optional field `%s' received from peer `%s'.\n"
6262#~ msgstr "Campo opcional anómalo '%s' recibido del par '%s'.\n"
6263
6264#~ msgid "Could not find peer `%s' in routing table!\n"
6265#~ msgstr "¡Imposible encontrar el par '%s' en la tabla de enrutado!\n"
6266
6267#~ msgid "Received malformed response to `%s' from peer `%s'.\n"
6268#~ msgstr "Recibida respuesta anómala a'%s' del par '%s'.\n"
6269
6270#~ msgid "Invalid response to `%s'.\n"
6271#~ msgstr "Respuesta inválida a '%s'.\n"
6272
6273#~ msgid "Malformed response to `%s' on master table.\n"
6274#~ msgstr "Respuesta anómala a '%s' en la tabla maestra.\n"
6275
6276#~ msgid "Invalid response to `%s' from `%s'\n"
6277#~ msgstr "Respuesta inválida a '%s' de '%s'\n"
6278
6279#~ msgid "Received invalid RPC `%s'.\n"
6280#~ msgstr "Recibido RPC '%s' inválida.\n"
6281
6282#~ msgid "RPC for `%s' received for table that we do not participate in!\n"
6283#~ msgstr "¡RPC para '%s' recibida de la tabla en la cual no participamos!\n"
6284
6285#~ msgid "`%s' failed. Terminating connection to client.\n"
6286#~ msgstr "'%s' falló. Finalizando conexión con el cliente.\n"
6287
6288#~ msgid ""
6289#~ "Share denoted bandwidth with other applications?\n"
6290#~ "\n"
6291#~ "Say \"yes\" here, if you don't want other network traffic to interfere "
6292#~ "with GNUnet's operation, but still wish to constrain GNUnet's bandwidth "
6293#~ "usage to values entered in the previous steps, or if you can't reliably "
6294#~ "measure the maximum capabilities of your connection. \"No\" can be very "
6295#~ "useful if other applications are causing a lot of traffic on your LAN. "
6296#~ "In this case, you do not want to limit the traffic that GNUnet can "
6297#~ "inflict on your internet connection whenever your high-speed LAN gets "
6298#~ "used (e.g. by NFS)."
6299#~ msgstr ""
6300#~ "¿Compartir el ancho de banda marcado con otras aplicaciones?\n"
6301#~ "\n"
6302#~ "Di \"sí\" aquí si no quieres que el resto del tráfico de la red no "
6303#~ "interfiera con las operaciones de GNUnet, pero aun quieres mantener el "
6304#~ "ancho de banda usado por GNUnet introducido en los pasos previos, o no "
6305#~ "puedes asegurar las máximas capacidades de tu conexión. \"No\" puede ser "
6306#~ "muy útil si otras aplicaciones crean mucho tráfico en tu LAN. En ese "
6307#~ "caso no quieres limitar el tráfico que GNUnet puede crear en tu conexión "
6308#~ "a Internet cuando una LAN de alta velocidad es usada (por ejemplo bajo "
6309#~ "NFS)."
6310
6311#~ msgid "How much CPU (in %) may be used?"
6312#~ msgstr "¿Cuánta CPU (en %) podrá ser usada?"
6313
6314#~ msgid ""
6315#~ "You can limit GNUnet's resource usage here.\n"
6316#~ "\n"
6317#~ "This is the percentage of processor time GNUnet is allowed to use."
6318#~ msgstr ""
6319#~ "Tu puedes limitar el uso de recursos de GNUnet aquí.\n"
6320#~ "\n"
6321#~ "Este es el porcentaje del tiempo del procesador que GNUnet puede usar."
6322
6323#~ msgid ""
6324#~ "Store migrated content?\n"
6325#~ "\n"
6326#~ "GNUnet is able to store data from other peers in your datastore. This is "
6327#~ "useful if an adversary has access to your inserted content and you need "
6328#~ "to deny that the content is yours. With \"content migration\" on, the "
6329#~ "content could have \"migrated\" over the internet to your node without "
6330#~ "your knowledge.\n"
6331#~ "It also helps to spread popular content over different peers to enhance "
6332#~ "availability."
6333#~ msgstr ""
6334#~ "¿Almacena el contenido migrado?\n"
6335#~ "\n"
6336#~ "GNUnet puede almacenar datos de otros pares en tu ordenador. Esto es muy "
6337#~ "útil si un adversario accede a tu contenido insertado y necesitas negar "
6338#~ "que dicho contenido sea tuyo. Con la \"migración de contenidos\" "
6339#~ "activada, el contenido puede haber \"migrado\" a través de internet a tu "
6340#~ "nodo sin tu conocimiento.\n"
6341#~ "Ésto también ayuda a repartir contenido popular a través de diferentes "
6342#~ "pares para aumentar la disponibilidad."
6343
6344#~ msgid ""
6345#~ "If you are an experienced user, you may want to tweak your GNUnet "
6346#~ "installation using the enhanced configurator.\n"
6347#~ "\n"
6348#~ "Do you want to start it after saving your configuration?"
6349#~ msgstr ""
6350#~ "Si eres un usuario experimentado, puedes desear exprimir tu instalación "
6351#~ "de GNUnet usando la herramienta de configuración avanzada.\n"
6352#~ "\n"
6353#~ "¿Quieres arrancarla después de guardar tu configuración?"
6354
6355#~ msgid ""
6356#~ "Unable to save configuration file %s: %s.\n"
6357#~ "\n"
6358#~ "Try again?"
6359#~ msgstr ""
6360#~ "Imposible guardar el fichero de configuración %s: %s.\n"
6361#~ "\n"
6362#~ "¿Intentar de nuevo?"
6363
6364#~ msgid "Failed to send `%s'. Closing connection.\n"
6365#~ msgstr "Fallo al mandar '%s'. Cerrando la conexión.\n"
6366
6367#~ msgid "Received invalid `%s' request (size %d)\n"
6368#~ msgstr "Recibida petición '%s' no válida (tamaño %d)\n"
6369
6370#~ msgid "Received invalid `%s' request (wrong table)\n"
6371#~ msgstr "Recibida petición '%s' no válida (tabla errónea)\n"
6372
6373#~ msgid "This client already participates in the given DHT!\n"
6374#~ msgstr "Este cliente ya participa en el DHT dado\n"
6375
6376#~ msgid "Cannot leave DHT: table not known!\n"
6377#~ msgstr "Imposible dejar DHT: ¡tabla no conocida!\n"
6378
6379#~ msgid "gnunetd signaled error in response to `%s' message\n"
6380#~ msgstr "gnunetd lanzó una señal de error en respuesta al mensaje '%s'\n"
6381
6382#~ msgid "Failed to receive response to `%s' message from gnunetd\n"
6383#~ msgstr "Falló al recibir la respuesta al mensaje '%s' de gnunetd\n"
6384
6385#~ msgid "Failed to send `%s' message to gnunetd\n"
6386#~ msgstr "Falló al mandar el mensaje '%s' a gnunetd\n"
6387
6388#~ msgid "Join a DHT."
6389#~ msgstr "Únete a DHT"
6390
6391#~ msgid "allow SIZE bytes of memory for the local table"
6392#~ msgstr "Reserva SIZE bytes de memoria para la tabla local"
6393
6394#~ msgid "Call to `%s' returns %d.\n"
6395#~ msgstr "La llamada a '%s' devuelve %d.\n"
6396
6397#~ msgid "Call to `%s' with key `%s'.\n"
6398#~ msgstr "Llamada a '%s' con la clave '%s'.\n"
6399
6400#~ msgid "Call to `%s' with value '%.*s' (%d bytes).\n"
6401#~ msgstr "Llama a '%s' con el valor '%.*s' (%d bytes).\n"
6402
6403#~ msgid "Error joining DHT.\n"
6404#~ msgstr "Error uniéndose a DHT.\n"
6405
6406#~ msgid "Joined DHT. Press CTRL-C to leave.\n"
6407#~ msgstr "Unido a DHT. Pulsa CTRL-C para abandonarlo.\n"
6408
6409#~ msgid "Error leaving DHT.\n"
6410#~ msgstr "Error abandonando DHT.\n"
6411
6412#~ msgid "`%s' failed: table not found!\n"
6413#~ msgstr "'%s' falló: ¡tabla no encontrada!\n"
6414
6415#~ msgid "sendAck failed. Terminating connection to client.\n"
6416#~ msgstr "sendAck falló. Finalizando conexión con el cliente.\n"
6417
6418#~ msgid "Unindex failed."
6419#~ msgstr "El desindexado falló"
6420
6421#, fuzzy
6422#~ msgid "Upload failed (consult logs)."
6423#~ msgstr "La descarga del ERCS falló (vea los logs)."
6424
6425#~ msgid "Could not resolve name of SMTP server `%s': %s"
6426#~ msgstr "Imposible resolver el nombre del servidor de SMTP '%s': %s"
6427
6428#~ msgid "query table called NAME"
6429#~ msgstr "pregunta a la tabla llamada NAME"
6430
6431#~ msgid "No commands specified.\n"
6432#~ msgstr "Ningún comando fue especificado.\n"
6433
6434#~ msgid "Superflous arguments (ignored).\n"
6435#~ msgstr "Argumentos superfluos (ignorados).\n"
6436
6437#~ msgid "Query `%s' had no results.\n"
6438#~ msgstr "La pregunta '%s' no tuvo resultados.\n"
6439
6440#~ msgid "FSUI persistence: error restoring download\n"
6441#~ msgstr "FSUI persistente: error restableciendo la descarga\n"
6442
6443#~ msgid "ECRS download suspending."
6444#~ msgstr "La descarga del ERCS fue suspendida."
6445
6446#~ msgid "Unexpected download state."
6447#~ msgstr "Estado de descarga inesperado."
6448
6449#~ msgid "Upload failed."
6450#~ msgstr "Subida fallida"
6451
6452#~ msgid "Cannot upload directory without using recursion."
6453#~ msgstr "Imposible compartir un directorio sin hacerlo recursivamente."
6454
6455#, fuzzy
6456#~ msgid "Expected `%s' to be a regular file\n"
6457#~ msgstr "'%s' no es un fichero regular.\n"
6458
6459#, fuzzy
6460#~ msgid "expected `%s' to be a directory!\n"
6461#~ msgstr "¡'%s' se esperaba que '%s' fuera un directorio!\n"
6462
6463#~ msgid "Sorry, no help is available for this option.\n"
6464#~ msgstr "Lo siento, no hay ayuda disponible para esta opción.\n"
6465
6466#~ msgid "Failed to obtain my (external) IPv6 address!\n"
6467#~ msgstr "¡Falló al obtener mi dirección IPv6 (externa)!\n"
6468
6469#~ msgid "Received invalid UDP6 message from %s:%d, dropping.\n"
6470#~ msgstr "Recibido mensaje UDP6 inválido de %s:%d, omitiendo.\n"
6471
6472#~ msgid "%s: Rejected connection from blacklisted address %s.\n"
6473#~ msgstr "%s: Conexión rechazada de una dirección de la \"lista negra\" %s.\n"
6474
6475#~ msgid "Received invalid UDP message from %u.%u.%u.%u:%u, dropping.\n"
6476#~ msgstr "Recibido mensaje UDP no válido del %u.%u.%u.%u:%u, omitiendo.\n"
6477
6478#~ msgid "Network advertisements disabled by configuration!\n"
6479#~ msgstr "¡Advertencias de la red desconectadas por configuración!\n"
6480
6481#~ msgid ""
6482#~ "Configuration file must specify directory for storing FS data in section `"
6483#~ "%s' under `%s'.\n"
6484#~ msgstr ""
6485#~ "El fichero de configuración debe especificar el directorio para almacenar "
6486#~ "los datos FS en la sección '%s' bajo '%s'.\n"
6487
6488#~ msgid "Could not initialize libgnunetutil!\n"
6489#~ msgstr "¡Imposible inicializar libgnunetutil!\n"
6490
6491#~ msgid ""
6492#~ "Configuration file must specify a directory for GNUnet to store per-peer "
6493#~ "data under %s%s\n"
6494#~ msgstr ""
6495#~ "El fichero de configuración debe especificar un directorio para que "
6496#~ "GNUnet almacene la información por-par bajo%s%s\n"
6497
6498#~ msgid "%s `%s' returned no known hosts!\n"
6499#~ msgstr "¡%s '%s' devolvió hosts desconocidos!\n"
6500
6501#~ msgid ""
6502#~ "specify that the contents of the namespace are of the given MIMETYPE (use "
6503#~ "when creating a new pseudonym)"
6504#~ msgstr ""
6505#~ "especifica que los contenidos del espacio son del MIMETYPE dado (úsalo "
6506#~ "cuando crees un nuevo pseudónimo)"
6507
6508#~ msgid ""
6509#~ "specify NAME to be the realname of the user controlling the namespace "
6510#~ "(use when creating a new pseudonym)"
6511#~ msgstr ""
6512#~ "especifica el NAME para ser el nombre real del usuario que controla el "
6513#~ "espacio (úsalo cuando crees un nuevo pseudónimo)"
6514
6515#~ msgid ""
6516#~ "use DESCRIPTION to describe the content of the namespace (use when "
6517#~ "creating a new pseudonym)"
6518#~ msgstr ""
6519#~ "usa la DESCRIPTION para describir el contenido del espacio (úsalo cuando "
6520#~ "crees un nuevo pseudónimo)"
6521
6522#~ msgid ""
6523#~ "specify the given URI as an address that contains more information about "
6524#~ "the namespace (use when creating a new pseudonym)"
6525#~ msgstr ""
6526#~ "especifica la URI dada como dirección que contiene mas información del "
6527#~ "espacio (úsalo cuando crees un nuevo pseudónimo)"
6528
6529#~ msgid "Invalid argument: `%s'\n"
6530#~ msgstr "Argumento no válido: '%s'\n"
6531
6532#~ msgid "Invalid arguments. Exiting.\n"
6533#~ msgstr "Argumentos no válidos. Saliendo.\n"
6534
6535#~ msgid "%8u of %8u bytes deleted."
6536#~ msgstr "%8u de %8u bytes borrados."
6537
6538#~ msgid "specify the file to delete from GNUnet (obligatory, file must exist)"
6539#~ msgstr ""
6540#~ "especifica el fichero a borrar de GNUnet (el fichero debe existir "
6541#~ "obligatoriamente)"
6542
6543#~ msgid ""
6544#~ "Remove file from GNUnet. The specified file is not removed\n"
6545#~ "from the filesystem but just from the local GNUnet datastore."
6546#~ msgstr ""
6547#~ "Borra el fichero de GNUnet. El fichero especificado no es borrado\n"
6548#~ "del sistema de ficheros, solamente de la base de datos local de GNUnet."
6549
6550#~ msgid "You must specify a filename (option -f)\n"
6551#~ msgstr "Debes especificar un fichero (opción -f)\n"
6552
6553#~ msgid ""
6554#~ "Error deleting file %s.\n"
6555#~ "Probably a few blocks were already missing from the database.\n"
6556#~ msgstr ""
6557#~ "Error borrando el fichero %s.\n"
6558#~ "Probablemente algunos bloques se hayan perdido de la base de datos.\n"
6559
6560#~ msgid "gnunet-directory [OPTIONS] [FILENAMES]"
6561#~ msgstr "directorio-de-gnunet [OPCIONES] [FICHEROS]"
6562
6563#~ msgid "process directories recursively"
6564#~ msgstr "procesa los directorios recursivamente"
6565
6566#~ msgid "You must pass a positive number to the `%s' option.\n"
6567#~ msgstr "Debes pasar un número positivo a la opción '%s'.\n"
6568
6569#~ msgid "You must specify a list of files to insert.\n"
6570#~ msgstr "Debes especificar una lista de ficheros a insertar.\n"
6571
6572#~ msgid "Only one file or directory can be specified at a time.\n"
6573#~ msgstr "Solo un fichero o un directorio puede ser especificado cada vez.\n"
6574
6575#~ msgid "You must specify a file or directory to upload.\n"
6576#~ msgstr "Debes especificar un fichero o directorio para subir.\n"
6577
6578#~ msgid "set the desired LEVEL of receiver-anonymity"
6579#~ msgstr "seleccione el NIVEL deseado de anonimidad-del-receptor"
6580
6581#~ msgid "Not enough arguments. You must specify a keyword or identifier.\n"
6582#~ msgstr ""
6583#~ "No hay suficientes argumentos. Debes especificar una clave o un "
6584#~ "identificador.\n"
6585
6586#~ msgid "LEVEL"
6587#~ msgstr "NIVEL"
6588
6589#~ msgid "FILENAME"
6590#~ msgstr "FICHERO"
6591
6592#~ msgid "This search is already pending!\n"
6593#~ msgstr "¡Esta búsqueda está aún pendiente!\n"
6594
6595#~ msgid ""
6596#~ "Configuration file must specify a directory for GNUnet to store per-peer "
6597#~ "data under %s%s.\n"
6598#~ msgstr ""
6599#~ "El fichero de configuración debe especificar un directorio para que "
6600#~ "GNUnet almacene la información por-par bajo %s%s.\n"
6601
6602#~ msgid "helptext for -t"
6603#~ msgstr "texto de ayuda para -t"
6604
6605#~ msgid "Template for gnunet-clients."
6606#~ msgstr "Plantilla para clientes-de-gnunet."
6607
6608#~ msgid "Invalid port \"%s\" in hostlist specification, trying port %d.\n"
6609#~ msgstr ""
6610#~ "Puerto inválido \"%s\" en la especificación de la lista local, probando "
6611#~ "el puerto %d.\n"
6612
6613#~ msgid "`%s' to `%s' failed at %s:%d with error: %s\n"
6614#~ msgstr "'%s' a '%s' falló en %s: %d con error %s\n"
6615
6616#~ msgid "Parsing HTTP response for URL `%s' failed.\n"
6617#~ msgstr "Analizando HTTP de la URL '%s' se produjo un fallo.\n"
6618
6619#~ msgid "Parsing hello from `%s' failed.\n"
6620#~ msgstr "Analizando saludo de '%s' se produjo un fallo.\n"
6621
6622#~ msgid "Could not resolve name of HTTP proxy `%s'. Trying without a proxy.\n"
6623#~ msgstr ""
6624#~ "Imposible resolver el nombre del proxy HTTP '%s'. Intentándolo sin un "
6625#~ "proxy.\n"
6626
6627#, fuzzy
6628#~ msgid ""
6629#~ "Configuration file must specify directory for storing data in section `%"
6630#~ "s' under `%s'.\n"
6631#~ msgstr ""
6632#~ "El fichero de configuración debe especificar el directorio para almacenar "
6633#~ "los datos FS en la sección '%s' bajo '%s'.\n"
6634
6635#~ msgid "Option `%s' makes no sense without option `%s'."
6636#~ msgstr "La opción '%s' no tiene ningún sentido sin la opción '%s'."
6637
6638#~ msgid "Invalid arguments: "
6639#~ msgstr "Argumentos inválidos: "
6640
6641#~ msgid ""
6642#~ "\n"
6643#~ "Exiting.\n"
6644#~ msgstr ""
6645#~ "\n"
6646#~ "Saliendo.\n"
6647
6648#~ msgid "No applications defined in configuration!\n"
6649#~ msgstr "¡Ninguna aplicación definida en la configuración!\n"
6650
6651#~ msgid "Updated data for %d applications.\n"
6652#~ msgstr "Actualizados los datos para %d aplicaciones.\n"
6653
6654#~ msgid "Could not write PID to file `%s': %s.\n"
6655#~ msgstr "Imposible escribir PID al fichero '%s': %s.\n"
6656
6657#~ msgid "Invalid command-line arguments:\n"
6658#~ msgstr "Argumentos en la linea de comandos inválidos:\n"
6659
6660#~ msgid "Argument %d: `%s'\n"
6661#~ msgstr "Argumento %d: '%s'\n"
6662
6663#~ msgid "`%s' starting\n"
6664#~ msgstr "'%s' comenzando\n"
6665
6666#~ msgid "FATAL: Identity plugin not found!\n"
6667#~ msgstr "FATAL: ¡Plugin de identidad no encontrado!\n"
6668
6669#~ msgid "Available MODEs:\n"
6670#~ msgstr "MODOs disponibles:\n"
6671
6672#~ msgid " config\t\ttext-based configuration\n"
6673#~ msgstr " configuración\t\tconfiguración basada en texto\n"
6674
6675#~ msgid " menuconfig\ttext-based menu\n"
6676#~ msgstr " menuconfig\tmenú basado en texto\n"
6677
6678#~ msgid " wizard-curses\tBasic text-based graphical configuration\n"
6679#~ msgstr ""
6680#~ " wizard-curses\t Configuración básica en modo gráfico pero basado en "
6681#~ "texto\n"
6682
6683#~ msgid ""
6684#~ " wizard-gtk\tBasic GTK configuration\n"
6685#~ "\n"
6686#~ msgstr ""
6687#~ " wizard-gtk\tConfiguración GTK básica\n"
6688#~ "\n"
6689
6690#~ msgid "gnunet-setup must have write-access to the configuration file `%s'\n"
6691#~ msgstr ""
6692#~ "gnunet-setup debe tener acceso de escritura al fichero de configuración '%"
6693#~ "s'\n"
6694
6695#, fuzzy
6696#~ msgid ""
6697#~ "Can only run wizard to configure gnunetd.\n"
6698#~ "Did you forget the `%s' option?\n"
6699#~ msgstr ""
6700#~ "Solo se puede arrancar wizard para configurar gnunetd.\n"
6701#~ "¿Te olvidaste de la opción %s'?\n"
6702
6703#~ msgid "%s: symbol value `%s' invalid for %s\n"
6704#~ msgstr "%s: valor del símbolo '%s' no válido para %s\n"
6705
6706#~ msgid "Gtk GNUnet Configurator"
6707#~ msgstr "Configurador Gtk de GNUnet"
6708
6709#~ msgid "_File"
6710#~ msgstr "_Fichero"
6711
6712#~ msgid "Load a config file"
6713#~ msgstr "Cargar un fichero de configuración"
6714
6715#~ msgid "_Load"
6716#~ msgstr "_Cargar"
6717
6718#~ msgid "Save the config in .config"
6719#~ msgstr "Guardar la configuración en .config"
6720
6721#~ msgid "_Save"
6722#~ msgstr "_Guardar"
6723
6724#~ msgid "_Quit"
6725#~ msgstr "_Salir"
6726
6727#~ msgid "Show _name"
6728#~ msgstr "Mostrar el _nombre"
6729
6730#~ msgid "Show range (Y/M/N)"
6731#~ msgstr "Muestra el rango (Y/M/N)"
6732
6733#~ msgid "Show _range"
6734#~ msgstr "Muestra el _rango"
6735
6736#~ msgid "Show _data"
6737#~ msgstr "Mostrar los _datos"
6738
6739#~ msgid "Show all _options"
6740#~ msgstr "Mostrar todas las _opciones"
6741
6742#~ msgid "_Help"
6743#~ msgstr "_Ayuda"
6744
6745#~ msgid "_Introduction"
6746#~ msgstr "_Introducción"
6747
6748#~ msgid "Goes up of one level (single view)"
6749#~ msgstr "Sube un nivel (vista única)"
6750
6751#~ msgid "Load"
6752#~ msgstr "Cargar"
6753
6754#~ msgid "Save a config file"
6755#~ msgstr "Guardar un fichero de configuración"
6756
6757#~ msgid "Save"
6758#~ msgstr "Guardar"
6759
6760#~ msgid "Single view"
6761#~ msgstr "Vista única"
6762
6763#~ msgid "Single"
6764#~ msgstr "Única"
6765
6766#~ msgid "Split view"
6767#~ msgstr "Vista doble"
6768
6769#~ msgid "Split"
6770#~ msgstr "Doble"
6771
6772#~ msgid "Full view"
6773#~ msgstr "Vista completa"
6774
6775#~ msgid "Full"
6776#~ msgstr "Completa"
6777
6778#~ msgid "Collapse the whole tree in the right frame"
6779#~ msgstr "Contraer el árbol completo en el lateral izquierdo"
6780
6781#~ msgid "Collapse"
6782#~ msgstr "Contraer"
6783
6784#~ msgid "Expand the whole tree in the right frame"
6785#~ msgstr "Expandir el árbol entero en el lateral izquierdo"
6786
6787#~ msgid "Expand"
6788#~ msgstr "Expandir"
6789
6790#~ msgid ""
6791#~ "This is GNUnet's configuration interface.\n"
6792#~ "\n"
6793#~ "GNUnet's options are separated into categories. You can browse them in "
6794#~ "the left tree. If you click on one of the categories, its options are "
6795#~ "shown above. \n"
6796#~ "\n"
6797#~ "To change the value of an option, simply click on its value and enter a "
6798#~ "new value. To get additional information about a specific option, click "
6799#~ "on its description."
6800#~ msgstr ""
6801#~ "Ésta es la interfaz de configuración de GNUnet.\n"
6802#~ "\n"
6803#~ "Las opciones de GNUnet están separadas en categorías. Tu puedes "
6804#~ "explorarlas en el árbol de la izquierda. Si pulsas en una de las "
6805#~ "categorías las opciones son mostradas encima.\n"
6806#~ "\n"
6807#~ "Para cambiar el valor de una opción, simplemente pulsa en su valor e "
6808#~ "introduce uno nuevo. Para obtener información adicional acerca de una "
6809#~ "opción específica, pulsa en su descripción."
6810
6811#~ msgid "Introduction"
6812#~ msgstr "Introducción"
6813
6814#, fuzzy
6815#~ msgid ""
6816#~ "Welcome to GNUnet Setup.\n"
6817#~ "\n"
6818#~ "For each option, a blank box indicates the feature is disabled, and "
6819#~ "checked one indicates it is enabled.\n"
6820#~ "If you do not see an option that you believe should be present, try "
6821#~ "turning on Show All Options under the Options menu.\n"
6822#~ "\n"
6823#~ "Although there is no cross reference yet to help you figure out what "
6824#~ "other options must be enabled to support the option you are interested "
6825#~ "in, you can still view the help of a grayed-out option.\n"
6826#~ "\n"
6827#~ "Toggling Show Debug Info under the Options menu will show the "
6828#~ "dependencies, which you can then match by examining other options."
6829#~ msgstr ""
6830#~ "Bienvenido a la configuración de GNUnet.\n"
6831#~ "\n"
6832#~ "Para cada opción una caja en blanco indica que la opción está desactivada "
6833#~ "y una marcada indica que está activada.\n"
6834#~ "Si no ves una opción que crees que debería estar presente, prueba "
6835#~ "activando la opción \"Mostrar todas las opciones\" en el menú de "
6836#~ "\"Opciones\".\n"
6837#~ "\n"
6838#~ "Although·there·is·no·cross·reference·yet·to·help·you·figure·out·what·other·options·must·be·enabled·to·support·the·option·you·are·interested·in,"
6839#~ "·you·can·still·view·the·help·of·a·grayed-out·option.\n"
6840#~ "\n"
6841#~ "Toggling·Show·Debug·Info·under·the·Options·menu·will·show·the·dependencies,"
6842#~ "·which·you·can·then·match·by·examining·other·options."
6843
6844#~ msgid ""
6845#~ "Configuration file not found. Please run GNUnet Setup (Client "
6846#~ "Configuration) first."
6847#~ msgstr ""
6848#~ "Fichero de configuración no encontrado. Por favor, ejecuta GNUnet Setup "
6849#~ "(Configuración del cliente) primero."
6850
6851#~ msgid "Configuration file `%s' not found. Run `gnunet-setup -d'!\n"
6852#~ msgstr ""
6853#~ "El·fichero·de·configuración·'%s'·no·ha·sido·encontrado.··¡Ejecute·'gnunet-"
6854#~ "setup -d'!\n"
6855
6856#~ msgid "Stopping cron\n"
6857#~ msgstr "Deteniendo cron\n"
6858
6859#~ msgid "Cron stopped\n"
6860#~ msgstr "Cron detenido\n"
6861
6862#~ msgid "Shutdown complete.\n"
6863#~ msgstr "Cierre completado.\n"
6864
6865#~ msgid "Caught signal %d.\n"
6866#~ msgstr "Cogida señal %d.\n"
6867
6868#~ msgid "Invalid network notation (additional characters: `%s')."
6869#~ msgstr "Notación de red no válida (caracteres adicionales: '%s')."
6870
6871#~ msgid "FAILURE"
6872#~ msgstr "FALLO"
6873
6874#~ msgid "MESSAGE"
6875#~ msgstr "MENSAJE"
6876
6877#~ msgid "CRON"
6878#~ msgstr "CRON"
6879
6880#~ msgid "EVERYTHING"
6881#~ msgstr "TODO"
6882
6883#~ msgid "Invalid LOGLEVEL `%s' specified.\n"
6884#~ msgstr "LOGLEVEL inválido '%s' especificado.\n"
6885
6886#~ msgid "Failure at %s:%d.\n"
6887#~ msgstr "Fallo en %s:%d.\n"
6888
6889#~ msgid ""
6890#~ "Cannot determine port of gnunetd server. Define in configuration file in "
6891#~ "section `%s' under `%s'.\n"
6892#~ msgstr ""
6893#~ "Imposible determinar el puerto del servidor de gnunetd. Defínelo en el "
6894#~ "fichero de configuración en la sección '%s' bajo '%s'.\n"
6895
6896#~ msgid ""
6897#~ "Usage: %s\n"
6898#~ "%s\n"
6899#~ "\n"
6900#~ msgstr ""
6901#~ "Uso: %s\n"
6902#~ "%s\n"
6903#~ "\n"
6904
6905#~ msgid "Invalid argument for `%s' at %s:%d.\n"
6906#~ msgstr "Argumento no válido para '%s' en %s:%d.\n"
6907
6908#~ msgid "g"
6909#~ msgstr "g"
6910
6911#~ msgid "t"
6912#~ msgstr "t"
6913
6914#~ msgid "unknown"
6915#~ msgstr "desconocido"
6916
6917#~ msgid "`%s' failed, other side closed connection.\n"
6918#~ msgstr "'%s' falló, conexión cerrada en el otro lado.\n"
6919
6920#~ msgid "Attempted path to `%s' was `%s'.\n"
6921#~ msgstr "La ruta esperada a '%s' fue '%s'.\n"
diff --git a/po/insert-header.sin b/po/insert-header.sin
new file mode 100644
index 000000000..b26de01f6
--- /dev/null
+++ b/po/insert-header.sin
@@ -0,0 +1,23 @@
1# Sed script that inserts the file called HEADER before the header entry.
2#
3# At each occurrence of a line starting with "msgid ", we execute the following
4# commands. At the first occurrence, insert the file. At the following
5# occurrences, do nothing. The distinction between the first and the following
6# occurrences is achieved by looking at the hold space.
7/^msgid /{
8x
9# Test if the hold space is empty.
10s/m/m/
11ta
12# Yes it was empty. First occurrence. Read the file.
13r HEADER
14# Output the file's contents by reading the next line. But don't lose the
15# current line while doing this.
16g
17N
18bb
19:a
20# The hold space was nonempty. Following occurrences. Do nothing.
21x
22:b
23}
diff --git a/po/quot.sed b/po/quot.sed
new file mode 100644
index 000000000..0122c4631
--- /dev/null
+++ b/po/quot.sed
@@ -0,0 +1,6 @@
1s/"\([^"]*\)"/“\1â€/g
2s/`\([^`']*\)'/‘\1’/g
3s/ '\([^`']*\)' / ‘\1’ /g
4s/ '\([^`']*\)'$/ ‘\1’/g
5s/^'\([^`']*\)' /‘\1’ /g
6s/“â€/""/g
diff --git a/po/remove-potcdate.sin b/po/remove-potcdate.sin
new file mode 100644
index 000000000..2436c49e7
--- /dev/null
+++ b/po/remove-potcdate.sin
@@ -0,0 +1,19 @@
1# Sed script that remove the POT-Creation-Date line in the header entry
2# from a POT file.
3#
4# The distinction between the first and the following occurrences of the
5# pattern is achieved by looking at the hold space.
6/^"POT-Creation-Date: .*"$/{
7x
8# Test if the hold space is empty.
9s/P/P/
10ta
11# Yes it was empty. First occurrence. Remove the line.
12g
13d
14bb
15:a
16# The hold space was nonempty. Following occurrences. Do nothing.
17x
18:b
19}
diff --git a/po/stamp-po b/po/stamp-po
new file mode 100644
index 000000000..9788f7023
--- /dev/null
+++ b/po/stamp-po
@@ -0,0 +1 @@
timestamp
diff --git a/po/sv.gmo b/po/sv.gmo
new file mode 100644
index 000000000..19593621a
--- /dev/null
+++ b/po/sv.gmo
Binary files differ
diff --git a/po/sv.po b/po/sv.po
new file mode 100644
index 000000000..93f941126
--- /dev/null
+++ b/po/sv.po
@@ -0,0 +1,5885 @@
1# Swedish translation of GNUnet.
2# Copyright (C) 2006 Free Software Foundation, Inc.
3# This file is distributed under the same license as the GNUnet package.
4# Daniel Nylander <po@danielnylander.se>, 2006.
5#
6msgid ""
7msgstr ""
8"Project-Id-Version: GNUnet 0.7.0b\n"
9"Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n"
10"POT-Creation-Date: 2009-01-08 10:55-0700\n"
11"PO-Revision-Date: 2006-01-21 17:16+0100\n"
12"Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
13"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=utf-8\n"
16"Content-Transfer-Encoding: 8bit\n"
17
18#: src/setup/ncurses/wizard_curs.c:72 src/setup/lib/wizard_util.c:155
19#: src/setup/lib/wizard_util.c:210
20msgid "Error"
21msgstr "Fel"
22
23#: src/setup/ncurses/wizard_curs.c:80
24msgid "Help"
25msgstr "Hjälp"
26
27#: src/setup/ncurses/wizard_curs.c:87
28#, fuzzy
29msgid "Error!"
30msgstr "Fel"
31
32#: src/setup/ncurses/wizard_curs.c:101 src/applications/vpn/cs.c:94
33msgid "No"
34msgstr "Nej"
35
36#: src/setup/ncurses/wizard_curs.c:102 src/applications/vpn/cs.c:94
37msgid "Yes"
38msgstr "Ja"
39
40#: src/setup/ncurses/wizard_curs.c:118 src/setup/ncurses/wizard_curs.c:183
41#: src/setup/ncurses/wizard_curs.c:299 src/setup/ncurses/mconf.c:189
42#: src/setup/ncurses/mconf.c:285 src/setup/ncurses/mconf.c:365
43#: src/setup/ncurses/mconf.c:456
44msgid "Internal error! (Choice invalid?)"
45msgstr ""
46
47#: src/setup/ncurses/wizard_curs.c:150
48#, fuzzy
49msgid "Abort"
50msgstr "_Om"
51
52#: src/setup/ncurses/wizard_curs.c:151
53#, fuzzy
54msgid "Ok"
55msgstr "k"
56
57#: src/setup/ncurses/wizard_curs.c:218 src/setup/ncurses/wizard_curs.c:284
58#: src/setup/ncurses/wizard_curs.c:425
59msgid "GNUnet configuration"
60msgstr "GNUnet-konfiguration"
61
62#: src/setup/ncurses/wizard_curs.c:220
63msgid ""
64"Welcome to GNUnet!\n"
65"\n"
66"This assistant will ask you a few basic questions in order to configure "
67"GNUnet.\n"
68"\n"
69"Please visit our homepage at\n"
70"\thttp://gnunet.org/\n"
71"and join our community at\n"
72"\thttp://gnunet.org/drupal/\n"
73"\n"
74"Have a lot of fun,\n"
75"\n"
76"the GNUnet team"
77msgstr ""
78"Välkommen till GNUnet!\n"
79"\n"
80"Denna assistant kommer att fråga dig några enkla frågor för att konfigurera "
81"GNUnet.\n"
82"\n"
83"Vänligen besök på webbplats på\n"
84"\thttp://gnunet.org/\n"
85"och gå med i vår gemenskap på\n"
86"\thttp://gnunet.org/drupal/\n"
87"\n"
88"Ha det så kul,\n"
89"\n"
90"the GNUnet team"
91
92#: src/setup/ncurses/wizard_curs.c:286
93msgid ""
94"Choose the network interface that connects your computer to the internet "
95"from the list below."
96msgstr ""
97
98#: src/setup/ncurses/wizard_curs.c:304 src/setup/ncurses/wizard_curs.c:318
99msgid ""
100"The \"Network interface\" is the device that connects your computer to the "
101"internet. This is usually a modem, an ISDN card or a network card in case "
102"you are using DSL."
103msgstr ""
104
105#: src/setup/ncurses/wizard_curs.c:315
106#, fuzzy
107msgid "Network configuration: interface"
108msgstr "Nätverksgränssnitt:"
109
110#: src/setup/ncurses/wizard_curs.c:317
111msgid ""
112"What is the name of the network interface that connects your computer to the "
113"Internet?"
114msgstr ""
115
116#: src/setup/ncurses/wizard_curs.c:328
117#, fuzzy
118msgid "Network configuration: IP"
119msgstr "GNUnet-konfiguration"
120
121#: src/setup/ncurses/wizard_curs.c:330
122msgid "What is this computer's public IP address or hostname?"
123msgstr ""
124
125#: src/setup/ncurses/wizard_curs.c:331
126msgid ""
127"If your provider always assigns the same IP-Address to you (a \"static\" IP-"
128"Address), enter it into the \"IP-Address\" field. If your IP-Address changes "
129"every now and then (\"dynamic\" IP-Address) but there's a hostname that "
130"always points to your actual IP-Address (\"Dynamic DNS\"), you can also "
131"enter it here.\n"
132"If left empty, GNUnet will try to automatically detect the IP.\n"
133"You can specify a hostname, GNUnet will then use DNS to resolve it.\n"
134"If in doubt, leave this empty."
135msgstr ""
136
137#: src/setup/ncurses/wizard_curs.c:346
138#, fuzzy
139msgid "Bandwidth configuration: upload"
140msgstr "GNUnet-konfiguration"
141
142#: src/setup/ncurses/wizard_curs.c:348
143#, fuzzy
144msgid "How much upstream bandwidth (in bytes/s) may be used?"
145msgstr "Hur mycket CPU (i %) får användas?"
146
147#: src/setup/ncurses/wizard_curs.c:349
148msgid ""
149"You can limit GNUnet's resource usage here.\n"
150"\n"
151"The \"upstream\" is the data channel through which data is *sent* to the "
152"internet. The limit is the maximum amount which GNUnet is allowed to use. If "
153"you have a flatrate, you can set it to the maximum speed of your internet "
154"connection. You should not use a value that is higher than what your actual "
155"connection allows."
156msgstr ""
157
158#: src/setup/ncurses/wizard_curs.c:361
159#, fuzzy
160msgid "Bandwidth configuration: download"
161msgstr "GNUnet-konfiguration"
162
163#: src/setup/ncurses/wizard_curs.c:363
164#, fuzzy
165msgid "How much downstream bandwidth (in bytes/s) may be used?"
166msgstr "Hur mycket CPU (i %) får användas?"
167
168#: src/setup/ncurses/wizard_curs.c:364
169msgid ""
170"You can limit GNUnet's resource usage here.\n"
171"\n"
172"The \"downstream\" is the data channel through which data is *received* from "
173"the internet. The limit is the maximum amount which GNUnet is allowed to "
174"use. If you have a flatrate, you can set it to the maximum speed of your "
175"internet connection. You should not use a value that is higher than what "
176"your actual connection allows."
177msgstr ""
178
179#: src/setup/ncurses/wizard_curs.c:376
180#, fuzzy
181msgid "Quota configuration"
182msgstr "GNUnet-konfiguration"
183
184#: src/setup/ncurses/wizard_curs.c:377
185msgid "What is the maximum size of the datastore in MB?"
186msgstr ""
187
188#: src/setup/ncurses/wizard_curs.c:378
189msgid ""
190"The GNUnet datastore contains all content that GNUnet needs to store "
191"(indexed, inserted and migrated content)."
192msgstr ""
193
194#: src/setup/ncurses/wizard_curs.c:390
195#, fuzzy
196msgid "Daemon configuration: user account"
197msgstr "Kunde inte skapa användarkonto:"
198
199#: src/setup/ncurses/wizard_curs.c:391
200msgid "As which user should gnunetd be run?"
201msgstr ""
202
203#: src/setup/ncurses/wizard_curs.c:393
204msgid ""
205"For security reasons, it is a good idea to let this setup create a new user "
206"account under which the GNUnet service is started at system startup.\n"
207"\n"
208"However, GNUnet may not be able to access files other than its own. This "
209"includes files you want to publish in GNUnet. You'll have to grant read "
210"permissions to the user specified below.\n"
211"\n"
212"Leave the field empty to run GNUnet with system privileges.\n"
213msgstr ""
214
215#: src/setup/ncurses/wizard_curs.c:410
216msgid "Daemon configuration: group account"
217msgstr ""
218
219#: src/setup/ncurses/wizard_curs.c:411
220msgid "As which group should gnunetd be run?"
221msgstr ""
222
223#: src/setup/ncurses/wizard_curs.c:413
224msgid ""
225"For security reasons, it is a good idea to let this setup create a new group "
226"for the chosen user account.\n"
227"\n"
228"You can also specify a already existent group here.\n"
229"\n"
230"Only members of this group will be allowed to start and stop the the GNUnet "
231"server and have access to GNUnet server data.\n"
232msgstr ""
233
234#: src/setup/ncurses/wizard_curs.c:427
235msgid "Do you want to automatically launch GNUnet as a system service?"
236msgstr ""
237
238#: src/setup/ncurses/wizard_curs.c:429
239msgid ""
240"If you say \"yes\" here, the GNUnet background process will be automatically "
241"started when you turn on your computer. If you say \"no\" here, you have to "
242"launch GNUnet yourself each time you want to use it."
243msgstr ""
244
245#: src/setup/ncurses/wizard_curs.c:452 src/setup/gtk/wizard_gtk.c:414
246#, c-format
247msgid "Unable to save configuration file `%s':"
248msgstr "Kunde inte spara konfigurationsfil \"%s\":"
249
250#: src/setup/ncurses/wizard_curs.c:472
251#, fuzzy
252msgid "Unable to create user account for daemon."
253msgstr "Kunde inte skapa användarkonto:"
254
255#: src/setup/ncurses/wizard_curs.c:483
256msgid "Unable to setup autostart for daemon."
257msgstr ""
258
259#: src/setup/ncurses/wizard_curs.c:498
260#, fuzzy
261msgid "Save configuration?"
262msgstr "GNUnet-konfiguration"
263
264#: src/setup/ncurses/wizard_curs.c:499
265#, fuzzy
266msgid "Save configuration now?"
267msgstr "GNUnet-konfiguration"
268
269#: src/setup/ncurses/wizard_curs.c:539 src/setup/ncurses/mconf.c:500
270#, fuzzy
271msgid "GNUnet Configuration"
272msgstr "GNUnet-konfiguration"
273
274#: src/setup/ncurses/wizard_curs.c:543
275msgid "Back"
276msgstr "Tillbaka"
277
278#: src/setup/ncurses/mconf.c:96
279msgid "Exit"
280msgstr ""
281
282#: src/setup/ncurses/mconf.c:99
283msgid "Up"
284msgstr "Upp"
285
286#: src/setup/ncurses/mconf.c:102
287msgid "Cancel"
288msgstr "Avbryt"
289
290#: src/setup/ncurses/mconf.c:221 src/setup/ncurses/mconf.c:408
291msgid "Internal error! (Value invalid?)"
292msgstr ""
293
294#: src/setup/ncurses/mconf.c:398
295msgid "Invalid input, expecting floating point value."
296msgstr ""
297
298#: src/setup/ncurses/mconf.c:439
299msgid "Invalid input, expecting integer."
300msgstr ""
301
302#: src/setup/ncurses/mconf.c:446
303msgid "Value is not in legal range."
304msgstr ""
305
306#: src/setup/ncurses/mconf.c:512 src/setup/text/conf.c:569
307#, fuzzy, c-format
308msgid "Configuration unchanged, no need to save.\n"
309msgstr ""
310"Konfiguration eller version av GNUnet ändrad. Du behöver köra \"%s\"!\n"
311
312#: src/setup/ncurses/mconf.c:518
313#, fuzzy
314msgid "Do you wish to save your new configuration?"
315msgstr "Vill du spara dina inställningar?"
316
317#: src/setup/ncurses/mconf.c:532
318#, fuzzy, c-format
319msgid ""
320"\n"
321"End of configuration.\n"
322msgstr " gconfig\tGTK-konfiguration\n"
323
324#: src/setup/ncurses/mconf.c:537
325#, c-format
326msgid ""
327"\n"
328"Your configuration changes were NOT saved.\n"
329msgstr ""
330
331#: src/setup/gnunet-win-tool.c:52
332msgid "list all network adapters"
333msgstr ""
334
335#: src/setup/gnunet-win-tool.c:55
336msgid "install GNUnet as Windows service"
337msgstr ""
338
339#: src/setup/gnunet-win-tool.c:58
340msgid "uninstall GNUnet service"
341msgstr ""
342
343#: src/setup/gnunet-win-tool.c:61
344msgid "increase the maximum number of TCP/IP connections"
345msgstr ""
346
347#: src/setup/gnunet-win-tool.c:64
348msgid "display a file's hash value"
349msgstr ""
350
351#: src/setup/gnunet-win-tool.c:125
352#, c-format
353msgid "GNUnet service installed successfully.\n"
354msgstr ""
355
356#: src/setup/gnunet-win-tool.c:128 src/setup/gnunet-win-tool.c:156
357#, c-format
358msgid "This version of Windows doesn't support services.\n"
359msgstr "Denna version av Windows har inte stöd för tjänster.\n"
360
361#: src/setup/gnunet-win-tool.c:132 src/setup/gnunet-win-tool.c:160
362#, c-format
363msgid "Error: can't open Service Control Manager: %s\n"
364msgstr ""
365
366#: src/setup/gnunet-win-tool.c:137
367#, c-format
368msgid "Error: can't create service: %s\n"
369msgstr "Fel: kan inte skapa tjänst: %s\n"
370
371#: src/setup/gnunet-win-tool.c:140 src/setup/gnunet-win-tool.c:172
372#, c-format
373msgid "Unknown error.\n"
374msgstr "Okänt fel.\n"
375
376#: src/setup/gnunet-win-tool.c:153
377#, c-format
378msgid "Service deleted.\n"
379msgstr "Tjänst borttagen.\n"
380
381#: src/setup/gnunet-win-tool.c:165
382#, c-format
383msgid "Error: can't access service: %s\n"
384msgstr ""
385
386#: src/setup/gnunet-win-tool.c:169
387#, c-format
388msgid "Error: can't delete service: %s\n"
389msgstr "Fel: kan inte ta bort tjänst: %s\n"
390
391#: src/setup/gtk/ngconf.c:389
392#, fuzzy
393msgid "Configuration saved."
394msgstr "Konfigurationsfil \"%s\" skapad.\n"
395
396#: src/setup/gtk/ngconf.c:399
397#, fuzzy
398msgid "Failed to save configuration."
399msgstr "Kunde inte spara konfiguration!"
400
401#: src/setup/gtk/ngconf.c:424
402#, fuzzy
403msgid "Configuration changed. Save?"
404msgstr "Konfigurationsfil \"%s\" skapad.\n"
405
406#: src/setup/gtk/ngconf.c:437
407#, fuzzy
408msgid "Error saving configuration."
409msgstr "Kunde inte spara konfiguration!"
410
411#: src/setup/gtk/wizard_gtk.c:141
412#, fuzzy
413msgid "(unknown connection)"
414msgstr "Nätverksanslutning"
415
416#: src/setup/gtk/wizard_gtk.c:438
417#, fuzzy
418msgid "Do you want to save the new configuration?"
419msgstr "Vill du spara dina inställningar?"
420
421#: src/setup/gtk/wizard_gtk.c:470
422msgid "Unable to create user account:"
423msgstr "Kunde inte skapa användarkonto:"
424
425#: src/setup/gtk/wizard_gtk.c:480
426msgid "Unable to change startup process:"
427msgstr ""
428
429#: src/setup/gtk/wizard_gtk.c:495
430msgid ""
431"Running gnunet-update failed.\n"
432"This maybe due to insufficient permissions, please check your "
433"configuration.\n"
434"Finally, run gnunet-update manually."
435msgstr ""
436
437#: src/setup/gnunet-setup.c:65
438#, c-format
439msgid "Can only set one option per invocation.\n"
440msgstr ""
441
442#: src/setup/gnunet-setup.c:73
443#, c-format
444msgid ""
445"Invalid syntax, argument to 'set' must have the format SECTION:"
446"OPTION=VALUE.\n"
447msgstr ""
448
449#: src/setup/gnunet-setup.c:87
450#, c-format
451msgid "Can only display one option per invocation.\n"
452msgstr ""
453
454#: src/setup/gnunet-setup.c:94
455#, c-format
456msgid ""
457"Invalid syntax, argument to 'get' must have the format SECTION:OPTION.\n"
458msgstr ""
459
460#: src/setup/gnunet-setup.c:108
461msgid "generate configuration for gnunetd, the GNUnet daemon"
462msgstr ""
463
464#: src/setup/gnunet-setup.c:111 src/setup/gnunet-setup.c:127
465#: src/server/gnunet-update.c:268
466msgid "print a value from the configuration file to stdout"
467msgstr "skriv ut ett värde från konfigurationsfilen till standard ut"
468
469#: src/setup/gnunet-setup.c:113 src/setup/gnunet-setup.c:129
470msgid "Tool to setup GNUnet."
471msgstr "Verktyg för att ställa in GNUnet."
472
473#: src/setup/gnunet-setup.c:115 src/setup/gnunet-setup.c:131
474#, fuzzy
475msgid "update a value in the configuration file"
476msgstr "skriv ut ett värde från konfigurationsfilen till standard ut"
477
478#: src/setup/gnunet-setup.c:338
479#, fuzzy, c-format
480msgid "Too many arguments.\n"
481msgstr "Ogiltiga kommandoradsargument.\n"
482
483#: src/setup/gnunet-setup.c:344
484#, fuzzy
485msgid "No interface specified, using default.\n"
486msgstr "Inget tabellnamn angivet, använder \"%s\".\n"
487
488#: src/setup/gnunet-setup.c:392
489#, fuzzy, c-format
490msgid "Configuration file `%s' must be a filename (but is a directory).\n"
491msgstr "Konfigurationsfil \"%s\" skapad.\n"
492
493#: src/setup/gnunet-setup.c:439
494#, c-format
495msgid "Undefined option.\n"
496msgstr ""
497
498#: src/setup/gnunet-setup.c:496
499#, fuzzy, c-format
500msgid "`%s' is not available.\n"
501msgstr "\"%s\" är inte tillgänglig."
502
503#: src/setup/gnunet-setup.c:516
504#, fuzzy, c-format
505msgid "Unknown operation '%s'.\n"
506msgstr "Okänd operation \"%s\"\n"
507
508#: src/setup/gnunet-setup.c:517 src/util/getopt/getopt.c:1072
509#, c-format
510msgid "Use --help to get a list of options.\n"
511msgstr "Använd --help för att få en lista på flaggor.\n"
512
513#: src/setup/text/conf.c:79
514#, fuzzy
515msgid "yes"
516msgstr "Ja"
517
518#: src/setup/text/conf.c:80
519msgid "no"
520msgstr ""
521
522#: src/setup/text/conf.c:106
523#, c-format
524msgid "\tEnter yes (%s), no (%s) or help (%s): "
525msgstr ""
526
527#: src/setup/text/conf.c:115
528msgid "\tPossible choices:\n"
529msgstr ""
530
531#: src/setup/text/conf.c:123
532msgid "\tUse single space prefix to avoid conflicts with hotkeys!\n"
533msgstr ""
534
535#: src/setup/text/conf.c:125
536#, c-format
537msgid "\tEnter string (type '%s' for default value `%s'): "
538msgstr ""
539
540#: src/setup/text/conf.c:143
541#, c-format
542msgid "\t Enter choice (default is %c): "
543msgstr ""
544
545#: src/setup/text/conf.c:147
546#, c-format
547msgid "\tEnter floating point (type '%s' for default value %f): "
548msgstr ""
549
550#: src/setup/text/conf.c:153
551#, c-format
552msgid ""
553"\tEnter unsigned integer in interval [%llu,%llu] (type '%s' for default "
554"value %llu): "
555msgstr ""
556
557#: src/setup/text/conf.c:187
558#, fuzzy, c-format
559msgid "Yes\n"
560msgstr "Ja"
561
562#: src/setup/text/conf.c:192
563#, fuzzy, c-format
564msgid "No\n"
565msgstr "Nej"
566
567#: src/setup/text/conf.c:195 src/setup/text/conf.c:236
568#: src/setup/text/conf.c:266 src/setup/text/conf.c:329
569#: src/setup/text/conf.c:387
570#, fuzzy, c-format
571msgid "Help\n"
572msgstr "Hjälp"
573
574#: src/setup/text/conf.c:198 src/setup/text/conf.c:213
575#: src/setup/text/conf.c:276 src/setup/text/conf.c:307
576#: src/setup/text/conf.c:365
577#, fuzzy, c-format
578msgid "Abort\n"
579msgstr "_Om"
580
581#: src/setup/text/conf.c:354 src/setup/text/conf.c:416
582#, c-format
583msgid ""
584"\n"
585"Invalid entry, try again (use '?' for help): "
586msgstr ""
587
588#: src/setup/text/conf.c:422
589#, c-format
590msgid "Unknown kind %x (internal error). Skipping option.\n"
591msgstr ""
592
593#: src/setup/text/conf.c:484
594msgid "\tDescend? (y/n/?) "
595msgstr ""
596
597#: src/setup/text/conf.c:493
598msgid "Aborted.\n"
599msgstr ""
600
601#: src/setup/text/conf.c:506
602#, fuzzy
603msgid "Invalid entry.\n"
604msgstr "Ogiltiga argument: "
605
606#: src/setup/text/conf.c:524
607#, c-format
608msgid "Unknown kind %x (internal error). Aborting.\n"
609msgstr ""
610
611#: src/setup/text/conf.c:556
612#, c-format
613msgid "You can always press ENTER to keep the current value.\n"
614msgstr ""
615
616#: src/setup/text/conf.c:557
617#, c-format
618msgid "Use the '%s' key to abort.\n"
619msgstr ""
620
621#: src/setup/text/conf.c:575
622#, c-format
623msgid ""
624"Save configuration? Answer 'y' for yes, 'n' for no, 'r' to repeat "
625"configuration. "
626msgstr ""
627
628#: src/setup/text/conf.c:590
629#, fuzzy, c-format
630msgid "Configuration was unchanged, no need to save.\n"
631msgstr ""
632"Konfiguration eller version av GNUnet ändrad. Du behöver köra \"%s\"!\n"
633
634#: src/setup/text/conf.c:599
635#, fuzzy, c-format
636msgid "Configuration file `%s' written.\n"
637msgstr "Konfigurationsfil \"%s\" skapad.\n"
638
639#: src/setup/lib/tree.c:191
640#, c-format
641msgid ""
642"Internal error: entry `%s' in section `%s' not found for visibility change!\n"
643msgstr ""
644
645#: src/setup/lib/wizard_util.c:126
646msgid "Can't open Service Control Manager"
647msgstr ""
648
649#: src/setup/lib/wizard_util.c:132
650msgid "Can't create service"
651msgstr "Kan inte skapa tjänst"
652
653#: src/setup/lib/wizard_util.c:136
654msgid "Error changing the permissions of the GNUnet directory"
655msgstr "Fel vid ändring av rättigheterna på GNUnet-katalogen"
656
657#: src/setup/lib/wizard_util.c:141
658#, fuzzy
659msgid "Cannot write to the registry"
660msgstr "Kan inte skriva till registret"
661
662#: src/setup/lib/wizard_util.c:144
663msgid "Can't access the service"
664msgstr "Kan inte tillgå tjänsten"
665
666#: src/setup/lib/wizard_util.c:147
667msgid "Can't delete the service"
668msgstr "Kan inte ta bort tjänsten"
669
670#: src/setup/lib/wizard_util.c:150
671msgid "Unknown error"
672msgstr "Okänt fel"
673
674#: src/setup/lib/wizard_util.c:186
675msgid "This version of Windows does not support multiple users."
676msgstr "Denna version för Windows har inte stöd för flera användare."
677
678#: src/setup/lib/wizard_util.c:190
679msgid "Error creating user"
680msgstr "Fel vid skapandet av användare"
681
682#: src/setup/lib/wizard_util.c:194
683msgid "Error accessing local security policy"
684msgstr "Fel vid åtkomst av lokal säkerhetspolicy"
685
686#: src/setup/lib/wizard_util.c:199
687msgid "Error granting service right to user"
688msgstr ""
689
690#: src/setup/lib/wizard_util.c:204
691msgid "Unknown error while creating a new user"
692msgstr "Okänt fel vid skapandet av ny användare"
693
694#: src/setup/lib/gns.c:297
695#, c-format
696msgid ""
697"Configuration does not satisfy constraints of configuration specification "
698"file `%s'!\n"
699msgstr ""
700
701# drive = hard drive ?
702#: src/util/disk/storage.c:172
703#, fuzzy, c-format
704msgid "`%s' failed for drive `%s': %u\n"
705msgstr "\"%s\" misslyckades för enhet %s: %u\n"
706
707#: src/util/disk/storage.c:524
708#, fuzzy, c-format
709msgid "Expected `%s' to be a directory!\n"
710msgstr "\"%s\" förväntade att \"%s\" skulle vara en katalog!\n"
711
712#: src/util/error/error.c:152
713#, c-format
714msgid "Message `%.*s' repeated %u times in the last %llus\n"
715msgstr ""
716
717#: src/util/error/error.c:254
718#, c-format
719msgid ""
720"\n"
721"Press any key to continue\n"
722msgstr ""
723
724#: src/util/error/error.c:336 src/util/error/error.c:371
725msgid "DEBUG"
726msgstr "FELSÖKNING"
727
728#: src/util/error/error.c:338 src/util/error/error.c:373
729msgid "STATUS"
730msgstr ""
731
732#: src/util/error/error.c:340 src/util/error/error.c:377
733msgid "WARNING"
734msgstr "VARNING"
735
736#: src/util/error/error.c:342 src/util/error/error.c:379
737msgid "ERROR"
738msgstr "FEL"
739
740#: src/util/error/error.c:344 src/util/error/error.c:381
741msgid "FATAL"
742msgstr "ÖDESDIGER"
743
744#: src/util/error/error.c:346 src/util/error/error.c:383
745msgid "USER"
746msgstr ""
747
748#: src/util/error/error.c:348 src/util/error/error.c:385
749msgid "ADMIN"
750msgstr ""
751
752#: src/util/error/error.c:350 src/util/error/error.c:387
753msgid "DEVELOPER"
754msgstr ""
755
756#: src/util/error/error.c:352 src/util/error/error.c:389
757msgid "REQUEST"
758msgstr ""
759
760#: src/util/error/error.c:354 src/util/error/error.c:391
761msgid "BULK"
762msgstr ""
763
764#: src/util/error/error.c:356 src/util/error/error.c:393
765msgid "IMMEDIATE"
766msgstr ""
767
768#: src/util/error/error.c:358
769msgid "ALL"
770msgstr ""
771
772#: src/util/error/error.c:375
773msgid "INFO"
774msgstr "INFO"
775
776#: src/util/error/error.c:394
777msgid "NOTHING"
778msgstr "INGET"
779
780#: src/util/network_client/tcpio.c:98 src/util/network_client/tcpio.c:154
781msgid "Could not find valid value for HOST in section NETWORK.\n"
782msgstr ""
783
784#: src/util/network_client/tcpio.c:123
785#, fuzzy, c-format
786msgid "Syntax error in configuration entry HOST in section NETWORK: `%s'\n"
787msgstr "Syntaxfel i konfigurationsfil \"%s\" på rad %d.\n"
788
789#: src/util/network_client/tcpio.c:335
790#, c-format
791msgid "Error connecting to %s:%u. Is the daemon running?\n"
792msgstr ""
793
794#: src/util/network_client/tcpio.c:398
795#, fuzzy, c-format
796msgid "Cannot connect to %s:%u: %s\n"
797msgstr "Kan inte ansluta till %u.%u.%u.%u:%u: %s\n"
798
799#: src/util/network_client/tcpio.c:636
800#, fuzzy
801msgid "Reading result from gnunetd failed, reply invalid!\n"
802msgstr "\"%s\" misslyckades, svar ogiltigt!\n"
803
804#: src/util/getopt/setoption.c:59
805#, c-format
806msgid ""
807"Setting option `%s' in section `%s' to `%s' when processing command line "
808"option `%s' was denied.\n"
809msgstr ""
810
811#: src/util/getopt/setoption.c:138 src/util/getopt/setoption.c:155
812#, c-format
813msgid "You must pass a number to the `%s' option.\n"
814msgstr "Du måste skicka med ett nummer till flaggan \"%s\".\n"
815
816#: src/util/getopt/printhelp.c:49
817#, c-format
818msgid ""
819"Arguments mandatory for long options are also mandatory for short options.\n"
820msgstr ""
821"Argument som är obligatoriska för långa flaggor är också obligatoriska för "
822"korta flaggor.\n"
823
824#: src/util/getopt/getopt.c:684
825#, c-format
826msgid "%s: option `%s' is ambiguous\n"
827msgstr "%s: flagga \"%s\" är tvetydig\n"
828
829#: src/util/getopt/getopt.c:710
830#, c-format
831msgid "%s: option `--%s' does not allow an argument\n"
832msgstr "%s: flagga \"--%s\" tillåter inte ett argument\n"
833
834#: src/util/getopt/getopt.c:716
835#, c-format
836msgid "%s: option `%c%s' does not allow an argument\n"
837msgstr "%s: flagga \"%c%s\" tillåter inte ett argument\n"
838
839#: src/util/getopt/getopt.c:737 src/util/getopt/getopt.c:909
840#, c-format
841msgid "%s: option `%s' requires an argument\n"
842msgstr "%s: flagga \"%s\" kräver ett argument\n"
843
844#: src/util/getopt/getopt.c:767
845#, c-format
846msgid "%s: unrecognized option `--%s'\n"
847msgstr "%s: okänd flagga \"--%s\"\n"
848
849#: src/util/getopt/getopt.c:771
850#, c-format
851msgid "%s: unrecognized option `%c%s'\n"
852msgstr "%s: okänd flagga \"%c%s\"\n"
853
854#: src/util/getopt/getopt.c:797
855#, c-format
856msgid "%s: illegal option -- %c\n"
857msgstr "%s: otillåten flagga -- %c\n"
858
859#: src/util/getopt/getopt.c:799
860#, c-format
861msgid "%s: invalid option -- %c\n"
862msgstr "%s: ogiltig flagga -- %c\n"
863
864#: src/util/getopt/getopt.c:828 src/util/getopt/getopt.c:958
865#, c-format
866msgid "%s: option requires an argument -- %c\n"
867msgstr "%s: flagga kräver ett argument -- %c\n"
868
869#: src/util/getopt/getopt.c:876
870#, c-format
871msgid "%s: option `-W %s' is ambiguous\n"
872msgstr "%s: flagga \"-W %s\" är tvetydig\n"
873
874#: src/util/getopt/getopt.c:894
875#, c-format
876msgid "%s: option `-W %s' does not allow an argument\n"
877msgstr "%s: flagga \"-W %s\" tillåter inte ett argument\n"
878
879#: src/util/network/ip.c:96 src/util/network/ip.c:160 src/transports/ip.c:260
880#, fuzzy, c-format
881msgid "No interface specified in section `%s' under `%s'!\n"
882msgstr ""
883"Inga nätverksgränssnitt angivna i konfigurationssektionen \"%s\" under \"%s"
884"\"!\n"
885
886#: src/util/network/ip.c:127 src/util/network/ip.c:246 src/transports/ip.c:291
887#, c-format
888msgid "Could not obtain IP for interface `%s' using `%s'.\n"
889msgstr ""
890
891#: src/util/network/ip.c:216
892#, c-format
893msgid ""
894"Could not find interface `%s' using `%s', trying to find another interface.\n"
895msgstr ""
896
897#: src/util/network/ip.c:295
898#, c-format
899msgid "Could not find an IP address for interface `%s'.\n"
900msgstr ""
901
902#: src/util/network/ip.c:306
903#, c-format
904msgid ""
905"There is more than one IP address specified for interface `%s'.\n"
906"GNUnet will use %s.\n"
907msgstr ""
908
909#: src/util/network/ip.c:330
910#, c-format
911msgid "Could not resolve `%s' to determine our IP address: %s\n"
912msgstr ""
913
914#: src/util/network/ip.c:363
915#, c-format
916msgid "GNUnet now uses the IP address %s.\n"
917msgstr ""
918
919#: src/util/network/ipcheck.c:106 src/util/network/ipcheck.c:136
920#: src/util/network/ipcheck.c:186 src/util/network/ipcheck.c:211
921#: src/util/network/ipcheck.c:219
922#, c-format
923msgid "Invalid format for IP: `%s'\n"
924msgstr "Ogiltigt format för IP: \"%s\"\n"
925
926#: src/util/network/ipcheck.c:167
927#, c-format
928msgid "Invalid network notation ('/%d' is not legal in IPv4 CIDR)."
929msgstr "Ogiltig nätverksnotation (\"/%d\" är inte giltig i IPv4 CIDR)."
930
931#: src/util/network/ipcheck.c:269
932#, c-format
933msgid "Invalid network notation (does not end with ';': `%s')\n"
934msgstr "Ogiltig nätverksnotation (slutar inte med \";\": \"%s\")\n"
935
936#: src/util/network/ipcheck.c:306
937#, fuzzy, c-format
938msgid "Wrong format `%s' for netmask\n"
939msgstr "Fel format \"%s\" för nätmask: %s\n"
940
941#: src/util/network/ipcheck.c:338
942#, fuzzy, c-format
943msgid "Wrong format `%s' for network\n"
944msgstr "Fel format \"%s\" för nätverk: %s\n"
945
946#: src/util/network/dns.c:472
947#, fuzzy, c-format
948msgid "Could not resolve `%s' (%s): %s\n"
949msgstr "Kunde inte slå upp \"%s\": %s\n"
950
951#: src/util/network/dns.c:523 src/util/network/dns.c:591
952#, c-format
953msgid "Could not find IP of host `%s': %s\n"
954msgstr ""
955
956#: src/util/network/select.c:310
957msgid "Received malformed message (too small) from connection. Closing.\n"
958msgstr ""
959
960#: src/util/network/select.c:495
961#, c-format
962msgid "select listen socket for `%s' not valid!\n"
963msgstr ""
964
965#: src/util/config/config.c:296
966#, c-format
967msgid "Syntax error in configuration file `%s' at line %d.\n"
968msgstr "Syntaxfel i konfigurationsfil \"%s\" på rad %d.\n"
969
970#: src/util/config/config.c:592
971#, c-format
972msgid ""
973"Configuration value '%llu' for '%s' in section '%s' is out of legal bounds [%"
974"llu,%llu]\n"
975msgstr ""
976
977#: src/util/config/config.c:602
978#, c-format
979msgid "Configuration value '%s' for '%s' in section '%s' should be a number\n"
980msgstr ""
981
982#: src/util/config/config.c:688
983#, c-format
984msgid ""
985"Configuration value '%s' for '%s' in section '%s' is not in set of legal "
986"choices\n"
987msgstr ""
988
989#: src/util/crypto/locking_gcrypt.c:80
990#, c-format
991msgid "libgcrypt has not the expected version (version %s is required).\n"
992msgstr "libgcrypt har inte den förväntande versionen (version %s krävs).\n"
993
994#: src/util/crypto/symcipher_gcrypt.c:46 src/util/crypto/symcipher_gcrypt.c:53
995#: src/util/crypto/hostkey_gcrypt.c:64 src/util/crypto/hostkey_gcrypt.c:71
996#: src/util/loggers/file.c:271 src/util/loggers/file.c:289
997#: src/applications/sqstore_sqlite/sqlite.c:45
998#: src/applications/sqstore_sqlite/sqlite.c:52
999#: src/applications/kvstore_sqlite/kv_sqlite.c:44
1000#: src/applications/kvstore_sqlite/kv_sqlite.c:51
1001#: src/applications/kvstore_mysql/kv_mysql.c:44
1002#: src/applications/kvstore_mysql/kv_mysql.c:51
1003#: src/applications/dstore_sqlite/dstore.c:94
1004#: src/applications/dstore_sqlite/dstore.c:101
1005#: src/applications/dstore_sqlite/dstore.c:222
1006#: src/applications/dstore_sqlite/dstore.c:259
1007#: src/applications/dstore_sqlite/dstore.c:285
1008#: src/applications/dstore_sqlite/dstore.c:345
1009#: src/applications/dstore_sqlite/dstore.c:366
1010#: src/applications/dstore_sqlite/dstore.c:378
1011#: src/applications/dstore_sqlite/dstore.c:407
1012#: src/applications/dstore_sqlite/dstore.c:511
1013#: src/applications/dstore_sqlite/dstore.c:555
1014#: src/include/gnunet_util_error.h:249 src/include/gnunet_util_error.h:256
1015#: src/include/gnunet_util_error.h:263
1016#, c-format
1017msgid "`%s' failed at %s:%d with error: %s\n"
1018msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n"
1019
1020#: src/util/crypto/hostkey_gcrypt.c:907
1021#, c-format
1022msgid "RSA signature verification failed at %s:%d: %s\n"
1023msgstr ""
1024
1025#: src/util/os/user.c:108 src/util/os/user.c:125
1026#, fuzzy, c-format
1027msgid "`%s' returned with error code %u"
1028msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n"
1029
1030#: src/util/os/user.c:155 src/util/os/user.c:200
1031#, fuzzy, c-format
1032msgid "Cannot obtain information about user `%s': %s\n"
1033msgstr "Kan inte öppna konfigurationsfil \"%s\".\n"
1034
1035#: src/util/os/user.c:156
1036msgid "No such user"
1037msgstr ""
1038
1039#: src/util/os/user.c:171
1040#, c-format
1041msgid "Cannot change user/group to `%s': %s\n"
1042msgstr "Kan inte ändra användare/grupp till \"%s\": %s\n"
1043
1044#: src/util/os/semaphore.c:227
1045#, c-format
1046msgid "Can't create semaphore: %i"
1047msgstr "Kan inte skapa semafor: %i"
1048
1049#: src/util/os/cpustatus.c:464
1050msgid "Cannot query the CPU usage (Windows NT).\n"
1051msgstr "Kan inte fråga efter CPU-användning (Windows NT).\n"
1052
1053#: src/util/os/cpustatus.c:487
1054msgid "Cannot query the CPU usage (Win 9x)\n"
1055msgstr "Kan inte fråga efter CPU-användning (Win 9x).\n"
1056
1057#: src/util/os/dso.c:59
1058#, c-format
1059msgid "Initialization of plugin mechanism failed: %s!\n"
1060msgstr "Initiering av insticksmekanism misslyckades: %s!\n"
1061
1062#: src/util/os/dso.c:120
1063#, fuzzy, c-format
1064msgid "`%s' failed for library `%s' with error: %s\n"
1065msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n"
1066
1067#: src/util/os/dso.c:162
1068#, fuzzy, c-format
1069msgid "`%s' failed to resolve method '%s' with error: %s\n"
1070msgstr "\"%s\" misslyckades för fil \"%s\" vid %s:%d med fel: %s\n"
1071
1072#: src/util/os/statuscalls.c:197 src/util/os/statuscalls.c:342
1073#, fuzzy, c-format
1074msgid "Failed to parse interface data from `%s'.\n"
1075msgstr "Misslyckades att läsa kompislista från \"%s\"\n"
1076
1077#: src/util/os/statuscalls.c:390 src/util/os/statuscalls.c:400
1078#, c-format
1079msgid ""
1080"No network interfaces defined in configuration section `%s' under `%s'!\n"
1081msgstr ""
1082"Inga nätverksgränssnitt angivna i konfigurationssektionen \"%s\" under \"%s"
1083"\"!\n"
1084
1085#: src/util/os/osconfig.c:153
1086msgid "Setting open descriptor limit not supported.\n"
1087msgstr ""
1088
1089#: src/util/os/osconfig.c:463 src/util/os/osconfig.c:492
1090#, fuzzy, c-format
1091msgid "Command `%s' failed with error code %u\n"
1092msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n"
1093
1094#: src/util/os/priority.c:78
1095#, fuzzy, c-format
1096msgid "Invalid process priority `%s'\n"
1097msgstr "Ogiltigt svar på \"%s\".\n"
1098
1099#: src/util/threads/semaphore.c:168 src/util/threads/pthread.c:157
1100#: src/util/threads/mutex.c:146
1101#, fuzzy, c-format
1102msgid "Real-time delay violation (%llu ms) at %s:%u\n"
1103msgstr "Icke-förväntad mycket stor allokering (%u byte) vid %s:%d!\n"
1104
1105#: src/util/threads/pthread.c:169 src/util/threads/pthread.c:176
1106#: src/util/threads/pthread.c:182 src/util/threads/pthread.c:276
1107#, fuzzy, c-format
1108msgid "`%s' failed with error code %s: %s\n"
1109msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n"
1110
1111#: src/util/threads/pthread.c:188 src/util/threads/pthread.c:286
1112#, fuzzy, c-format
1113msgid "`%s' failed with error code %d: %s\n"
1114msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n"
1115
1116#: src/util/threads/mutex.c:155 src/util/threads/mutex.c:201
1117#, fuzzy, c-format
1118msgid "Invalid argument for `%s'.\n"
1119msgstr "Ogiltigt argument: \"%s\"\n"
1120
1121#: src/util/threads/mutex.c:160
1122#, c-format
1123msgid "Deadlock due to `%s'.\n"
1124msgstr ""
1125
1126#: src/util/threads/mutex.c:187
1127#, c-format
1128msgid "Lock acquired for too long (%llu ms) at %s:%u\n"
1129msgstr ""
1130
1131#: src/util/threads/mutex.c:207
1132#, fuzzy, c-format
1133msgid "Permission denied for `%s'.\n"
1134msgstr "Åtkomst nekad för \"%s\" vid %s:%d.\n"
1135
1136#: src/util/boot/startup.c:259
1137#, fuzzy, c-format
1138msgid "Failed to run %s: %s %d\n"
1139msgstr "Fel vid %s:%d.\n"
1140
1141#: src/util/string/string.c:55
1142msgid "ms"
1143msgstr "ms"
1144
1145#: src/util/string/string.c:61
1146msgid "s"
1147msgstr "s"
1148
1149#: src/util/string/string.c:65
1150msgid "m"
1151msgstr "m"
1152
1153#: src/util/string/string.c:69
1154msgid "h"
1155msgstr "h"
1156
1157#: src/util/string/string.c:73
1158msgid " days"
1159msgstr " dagar"
1160
1161#: src/util/string/string.c:89
1162msgid "b"
1163msgstr "b"
1164
1165#: src/util/string/string.c:95
1166msgid "KiB"
1167msgstr ""
1168
1169#: src/util/string/string.c:99
1170msgid "MiB"
1171msgstr ""
1172
1173#: src/util/string/string.c:103
1174msgid "GiB"
1175msgstr ""
1176
1177#: src/util/string/string.c:107
1178msgid "TiB"
1179msgstr ""
1180
1181#: src/util/string/string.c:226
1182msgid "Failed to expand `$HOME': environment variable `HOME' not set"
1183msgstr ""
1184
1185#: src/util/loggers/file.c:229
1186#, fuzzy, c-format
1187msgid "Failed to open log-file `%s': %s\n"
1188msgstr "Misslyckades att leverera \"%s\" meddelande.\n"
1189
1190#: src/util/loggers/file.c:250
1191#, fuzzy
1192msgid "GNUnet error log"
1193msgstr "Spåra GNUnets nätverkstopologi."
1194
1195#: src/util/loggers/memory.c:72
1196msgid "Out of memory (for logging)\n"
1197msgstr ""
1198
1199#: src/util/pseudonym/names.c:79
1200#, fuzzy
1201msgid "no-name"
1202msgstr "Visa namn"
1203
1204#: src/applications/datastore/datastore.c:183
1205#: src/applications/datastore/datastore.c:199
1206#, c-format
1207msgid "Availability test failed for `%s' at %s:%d.\n"
1208msgstr "Tillgänglighetstest misslyckades för \"%s\" vid %s:%d.\n"
1209
1210#: src/applications/datastore/datastore.c:401
1211msgid "# requests filtered by bloom filter"
1212msgstr ""
1213
1214#: src/applications/datastore/datastore.c:403
1215msgid "# bloom filter false positives"
1216msgstr ""
1217
1218#: src/applications/datastore/datastore.c:406
1219msgid "# bytes allowed in datastore"
1220msgstr ""
1221
1222#: src/applications/datastore/datastore.c:423
1223msgid "Failed to load state service. Trying to do without.\n"
1224msgstr ""
1225
1226#: src/applications/datastore/datastore.c:529
1227#, c-format
1228msgid "Datastore conversion at approximately %u%%\n"
1229msgstr ""
1230
1231#: src/applications/datastore/datastore.c:576
1232#, fuzzy, c-format
1233msgid "Starting datastore conversion (this may take a while).\n"
1234msgstr "Skapar ny värdnyckel (det här kan ta en stund).\n"
1235
1236#: src/applications/datastore/datastore.c:584
1237#, c-format
1238msgid "Completed datastore conversion.\n"
1239msgstr ""
1240
1241#: src/applications/datastore/datastore.c:592
1242msgid "Failed to load sqstore service. Check your configuration!\n"
1243msgstr ""
1244
1245#: src/applications/rpc/rpc.c:339
1246#, fuzzy, c-format
1247msgid ""
1248"%s:%d - RPC %s:%p could not be registered: another callback is already using "
1249"this name (%p)\n"
1250msgstr "%s::%s - RPC %s:%p kunde inte avregistreras: hittades inte\n"
1251
1252#: src/applications/rpc/rpc.c:398
1253#, fuzzy, c-format
1254msgid "%s:%d - async RPC %s:%p could not be unregistered: not found\n"
1255msgstr "%s::%s - RPC %s:%p kunde inte avregistreras: hittades inte\n"
1256
1257#: src/applications/rpc/rpc.c:951
1258#, c-format
1259msgid "`%s' registering handlers %d %d %d\n"
1260msgstr "\"%s\" registrerar handtag %d %d %d\n"
1261
1262#: src/applications/rpc/rpc.c:972
1263#, c-format
1264msgid "Failed to initialize `%s' service.\n"
1265msgstr "Misslyckades att initiera tjänsten \"%s\".\n"
1266
1267#: src/applications/tbench/tbenchtest.c:53
1268#, c-format
1269msgid "Using %u messages of size %u for %u times.\n"
1270msgstr ""
1271
1272#: src/applications/tbench/tbenchtest.c:85
1273#, c-format
1274msgid "Times: max %16llu min %16llu mean %12.3f variance %12.3f\n"
1275msgstr ""
1276
1277#: src/applications/tbench/tbenchtest.c:89
1278#, c-format
1279msgid "Loss: max %16u min %16u mean %12.3f variance %12.3f\n"
1280msgstr ""
1281
1282#: src/applications/tbench/tbenchtest.c:95
1283#, c-format
1284msgid ""
1285"\n"
1286"Failed to receive reply from gnunetd.\n"
1287msgstr ""
1288
1289#: src/applications/tbench/tbenchtest.c:149
1290#, c-format
1291msgid "Running benchmark...\n"
1292msgstr ""
1293
1294#: src/applications/tbench/tbench.c:422
1295msgid "allows profiling of direct peer-to-peer connections"
1296msgstr ""
1297
1298#: src/applications/tbench/gnunet-tbench.c:63
1299#: src/applications/tracekit/gnunet-tracekit.c:302
1300msgid "Start GNUnet transport benchmarking tool."
1301msgstr ""
1302
1303#: src/applications/tbench/gnunet-tbench.c:65
1304msgid "output in gnuplot format"
1305msgstr "utdata i gnuplot-format"
1306
1307#: src/applications/tbench/gnunet-tbench.c:69
1308msgid "number of iterations"
1309msgstr "antal iterationer"
1310
1311#: src/applications/tbench/gnunet-tbench.c:73
1312msgid "number of messages to use per iteration"
1313msgstr "antal meddelanden att använda per iteration"
1314
1315#: src/applications/tbench/gnunet-tbench.c:76
1316msgid "receiver host identifier (ENC file name)"
1317msgstr ""
1318
1319#: src/applications/tbench/gnunet-tbench.c:79
1320msgid "message size"
1321msgstr "meddelandestorlek"
1322
1323#: src/applications/tbench/gnunet-tbench.c:82
1324msgid "sleep for SPACE ms after each a message block"
1325msgstr ""
1326
1327#: src/applications/tbench/gnunet-tbench.c:85
1328msgid "time to wait for the completion of an iteration (in ms)"
1329msgstr ""
1330
1331#: src/applications/tbench/gnunet-tbench.c:90
1332msgid "number of messages in a message block"
1333msgstr "antal meddelanden i ett meddelandeblock"
1334
1335#: src/applications/tbench/gnunet-tbench.c:126
1336#: src/applications/tracekit/gnunet-tracekit.c:352
1337#: src/applications/tracekit/tracekittest.c:133
1338#: src/applications/template/gnunet-template.c:95
1339#: src/applications/stats/gnunet-stats.c:121
1340#: src/applications/vpn/gnunet-vpn.c:154
1341#, c-format
1342msgid "Error establishing connection with gnunetd.\n"
1343msgstr ""
1344
1345#: src/applications/tbench/gnunet-tbench.c:142
1346#, c-format
1347msgid "You must specify a receiver!\n"
1348msgstr "Du måste ange en mottagare!\n"
1349
1350#: src/applications/tbench/gnunet-tbench.c:152
1351#, c-format
1352msgid "Invalid receiver peer ID specified (`%s' is not valid name).\n"
1353msgstr ""
1354
1355#: src/applications/tbench/gnunet-tbench.c:189
1356#, c-format
1357msgid "Time:\n"
1358msgstr "Tid:\n"
1359
1360#: src/applications/tbench/gnunet-tbench.c:190
1361#, c-format
1362msgid "\tmax %llums\n"
1363msgstr "\tmax %llums\n"
1364
1365#: src/applications/tbench/gnunet-tbench.c:191
1366#, c-format
1367msgid "\tmin %llums\n"
1368msgstr "\tmin %llums\n"
1369
1370#: src/applications/tbench/gnunet-tbench.c:192
1371#, c-format
1372msgid "\tmean %8.4fms\n"
1373msgstr ""
1374
1375#: src/applications/tbench/gnunet-tbench.c:193
1376#, c-format
1377msgid "\tvariance %8.4fms\n"
1378msgstr ""
1379
1380#: src/applications/tbench/gnunet-tbench.c:195
1381#, c-format
1382msgid "Loss:\n"
1383msgstr ""
1384
1385#: src/applications/tbench/gnunet-tbench.c:196
1386#, c-format
1387msgid "\tmax %u\n"
1388msgstr "\tmax %u\n"
1389
1390#: src/applications/tbench/gnunet-tbench.c:197
1391#, c-format
1392msgid "\tmin %u\n"
1393msgstr "\tmin %u\n"
1394
1395#: src/applications/tbench/gnunet-tbench.c:198
1396#, c-format
1397msgid "\tmean %8.4f\n"
1398msgstr ""
1399
1400#: src/applications/tbench/gnunet-tbench.c:199
1401#, c-format
1402msgid "\tvariance %8.4f\n"
1403msgstr ""
1404
1405#: src/applications/tbench/gnunet-tbench.c:205
1406#, c-format
1407msgid "Output format not known, this should not happen.\n"
1408msgstr "Utdataformat är inte känt, detta bör inte hända.\n"
1409
1410#: src/applications/tbench/gnunet-tbench.c:211
1411#, c-format
1412msgid ""
1413"\n"
1414"Did not receive the message from gnunetd. Is gnunetd running?\n"
1415msgstr ""
1416
1417#: src/applications/traffic/traffic.c:454
1418#, c-format
1419msgid "# bytes transmitted of type %d"
1420msgstr "# byte skickade av typen %d"
1421
1422#: src/applications/traffic/traffic.c:470
1423#, c-format
1424msgid "# bytes received of type %d"
1425msgstr "# byte mottagna av typen %d"
1426
1427#: src/applications/traffic/traffic.c:489
1428#, fuzzy, c-format
1429msgid "# bytes received in plaintext of type %d"
1430msgstr "# byte mottagna av typen %d"
1431
1432#: src/applications/traffic/traffic.c:652
1433msgid "tracks bandwidth utilization by gnunetd"
1434msgstr ""
1435
1436#: src/applications/sqstore_sqlite/sqlite.c:218
1437#, fuzzy, c-format
1438msgid "Unable to initialize SQLite: %s.\n"
1439msgstr "Kunde inte initiera SQLite.\n"
1440
1441#: src/applications/sqstore_sqlite/sqlite.c:434
1442#: src/applications/sqstore_sqlite/sqlite.c:469
1443#, c-format
1444msgid "Invalid data in %s. Trying to fix (by deletion).\n"
1445msgstr ""
1446
1447#: src/applications/sqstore_sqlite/sqlite.c:435
1448#: src/applications/sqstore_sqlite/sqlite.c:470
1449msgid "sqlite datastore"
1450msgstr ""
1451
1452#: src/applications/sqstore_sqlite/sqlite.c:1474
1453#: src/applications/sqstore_mysql/mysql.c:1078
1454msgid "# bytes in datastore"
1455msgstr ""
1456
1457#: src/applications/sqstore_sqlite/sqlite.c:1476
1458msgid "# bytes allocated by SQLite"
1459msgstr ""
1460
1461#: src/applications/sqstore_mysql/mysql.c:1085
1462#: src/applications/sqstore_mysql/mysql.c:1160
1463msgid ""
1464"Failed to load MySQL database module. Check that MySQL is running and "
1465"configured properly!\n"
1466msgstr ""
1467
1468#: src/applications/tracekit/gnunet-tracekit.c:104
1469#, c-format
1470msgid "`%s' connected to `%s'.\n"
1471msgstr "\"%s\" ansluten till \"%s\".\n"
1472
1473#: src/applications/tracekit/gnunet-tracekit.c:110
1474#: src/applications/tracekit/tracekittest.c:67
1475#, c-format
1476msgid "`%s' is not connected to any peer.\n"
1477msgstr "\"%s\" är inte ansluten till någon ändpunkt.\n"
1478
1479#: src/applications/tracekit/gnunet-tracekit.c:295
1480msgid "probe network to the given DEPTH"
1481msgstr ""
1482
1483#: src/applications/tracekit/gnunet-tracekit.c:299
1484msgid ""
1485"specify output format; 0 for human readable output, 1 for dot, 2 for vcg"
1486msgstr ""
1487
1488#: src/applications/tracekit/gnunet-tracekit.c:306
1489#, fuzzy
1490msgid "use PRIORITY for the priority of the trace request"
1491msgstr "ange prioritet för innehållet"
1492
1493#: src/applications/tracekit/gnunet-tracekit.c:310
1494msgid "wait DELAY seconds for replies"
1495msgstr ""
1496
1497#: src/applications/tracekit/gnunet-tracekit.c:344
1498#, c-format
1499msgid ""
1500"Format specification invalid. Use 0 for user-readable, 1 for dot, 2 for "
1501"vcg.\n"
1502msgstr ""
1503
1504#: src/applications/tracekit/tracekittest.c:60
1505#, fuzzy, c-format
1506msgid "`%.*s' connected to `%.*s'.\n"
1507msgstr "\"%s\" ansluten till \"%s\".\n"
1508
1509#: src/applications/tracekit/tracekit.c:440
1510msgid "allows mapping of the network topology"
1511msgstr "tillåter kartläggning av nätverkstopologin"
1512
1513#: src/applications/advertising/advertising_test.c:47
1514#: src/applications/hostlist/hostlisttest.c:40
1515#: src/applications/session/sessiontest.c:40
1516#: src/applications/session/sessiontest_nat_http.c:40
1517#: src/applications/session/sessiontest_nat.c:40
1518#: src/applications/stats/statistics.c:247
1519msgid "# of connected peers"
1520msgstr "# av anslutna parter"
1521
1522#: src/applications/advertising/advertising.c:194
1523#, fuzzy, c-format
1524msgid "HELLO message from `%s' has an invalid signature. Dropping.\n"
1525msgstr "Meddelande från \"%s\" kastades bort: ogiltigt format.\n"
1526
1527#: src/applications/advertising/advertising.c:205
1528msgid "HELLO message has expiration too far in the future. Dropping.\n"
1529msgstr ""
1530
1531#: src/applications/advertising/advertising.c:406
1532msgid "Could not send HELLO+PING, ping buffer full.\n"
1533msgstr ""
1534
1535#: src/applications/advertising/advertising.c:429
1536msgid "Failed to create an advertisement for this peer. Will not send PING.\n"
1537msgstr ""
1538
1539#: src/applications/advertising/advertising.c:581
1540#, c-format
1541msgid "Advertising my transport %d to selected peers.\n"
1542msgstr "Annonserar min transport %d till valda ändpunkter.\n"
1543
1544#: src/applications/advertising/advertising.c:590
1545msgid ""
1546"Announcing ourselves pointless: no other peers are known to us so far.\n"
1547msgstr ""
1548
1549#: src/applications/advertising/advertising.c:868
1550msgid "# Peer advertisements received"
1551msgstr ""
1552
1553#: src/applications/advertising/advertising.c:871
1554msgid "# Peer advertisements of type NAT received"
1555msgstr ""
1556
1557#: src/applications/advertising/advertising.c:874
1558msgid "# Peer advertisements confirmed via PONG"
1559msgstr ""
1560
1561#: src/applications/advertising/advertising.c:877
1562msgid "# Peer advertisements updating earlier HELLOs"
1563msgstr ""
1564
1565#: src/applications/advertising/advertising.c:880
1566#, fuzzy
1567msgid "# Peer advertisements discarded due to load"
1568msgstr "Nätverksannonsering avstängd i konfigurationen!\n"
1569
1570#: src/applications/advertising/advertising.c:883
1571msgid "# Peer advertisements for unsupported transport"
1572msgstr ""
1573
1574#: src/applications/advertising/advertising.c:886
1575msgid "# Peer advertisements not confirmed due to ping busy"
1576msgstr ""
1577
1578#: src/applications/advertising/advertising.c:889
1579msgid "# Peer advertisements not confirmed due to lack of self ad"
1580msgstr ""
1581
1582#: src/applications/advertising/advertising.c:892
1583msgid "# Peer advertisements not confirmed due to send error"
1584msgstr ""
1585
1586#: src/applications/advertising/advertising.c:894
1587msgid "# Self advertisments transmitted"
1588msgstr ""
1589
1590#: src/applications/advertising/advertising.c:896
1591msgid "# Foreign advertisements forwarded"
1592msgstr ""
1593
1594#: src/applications/advertising/advertising.c:898
1595#: src/applications/pingpong/pingpong.c:528
1596msgid "# plaintext PING messages sent"
1597msgstr "# PING-meddelanden i klartext skickade"
1598
1599#: src/applications/advertising/advertising.c:904
1600#: src/applications/session/connect.c:932
1601#, c-format
1602msgid "`%s' registering handler %d (plaintext and ciphertext)\n"
1603msgstr "\"%s\" registrerar handtag %d (klartext och kryptotext)\n"
1604
1605#: src/applications/advertising/advertising.c:922
1606msgid ""
1607"ensures that this peer is known by other peers and discovers other peers"
1608msgstr ""
1609
1610#: src/applications/fragmentation/fragmentation.c:578
1611msgid "# messages defragmented"
1612msgstr ""
1613
1614#: src/applications/fragmentation/fragmentation.c:580
1615msgid "# messages fragmented"
1616msgstr ""
1617
1618#: src/applications/fragmentation/fragmentation.c:581
1619msgid "# fragments discarded"
1620msgstr ""
1621
1622#: src/applications/fragmentation/fragmentation.c:592
1623#, c-format
1624msgid "`%s' registering handler %d\n"
1625msgstr "\"%s\" registrerar handtag %d\n"
1626
1627#: src/applications/topology_default/topology.c:466
1628#, fuzzy, c-format
1629msgid "Could not read friends list `%s'\n"
1630msgstr "Misslyckades att läsa kompislista från \"%s\"\n"
1631
1632#: src/applications/topology_default/topology.c:485
1633#, c-format
1634msgid "Failed to read friends list from `%s'\n"
1635msgstr "Misslyckades att läsa kompislista från \"%s\"\n"
1636
1637#: src/applications/topology_default/topology.c:505
1638msgid "Syntax error in topology specification, skipping bytes.\n"
1639msgstr ""
1640
1641#: src/applications/topology_default/topology.c:523
1642#, c-format
1643msgid "Syntax error in topology specification, skipping bytes `%s'.\n"
1644msgstr ""
1645
1646#: src/applications/topology_default/topology.c:535
1647msgid ""
1648"Fewer friends specified than required by minimum friend count. Will only "
1649"connect to friends.\n"
1650msgstr ""
1651
1652#: src/applications/topology_default/topology.c:543
1653msgid ""
1654"More friendly connections required than target total number of connections.\n"
1655msgstr ""
1656
1657#: src/applications/topology_default/topology.c:726
1658msgid "maintains GNUnet default mesh topology"
1659msgstr ""
1660
1661#: src/applications/chat/tools/gnunet-chat.c:107
1662msgid "anonymous"
1663msgstr ""
1664
1665#: src/applications/chat/tools/gnunet-chat.c:113
1666#, fuzzy, c-format
1667msgid "`%s' said: %s\n"
1668msgstr "\"%s\" %s misslyckades: %s\n"
1669
1670#: src/applications/chat/tools/gnunet-chat.c:116
1671#: src/applications/chat/tools/gnunet-chat.c:119
1672#, fuzzy, c-format
1673msgid "`%s' said to you: %s\n"
1674msgstr "\"%s\" %s misslyckades: %s\n"
1675
1676# drive = hard drive ?
1677#: src/applications/chat/tools/gnunet-chat.c:122
1678#, fuzzy, c-format
1679msgid "`%s' said for sure: %s\n"
1680msgstr "\"%s\" misslyckades för enhet %s: %u\n"
1681
1682# drive = hard drive ?
1683#: src/applications/chat/tools/gnunet-chat.c:125
1684#, fuzzy, c-format
1685msgid "`%s' said to you for sure: %s\n"
1686msgstr "\"%s\" misslyckades för enhet %s: %u\n"
1687
1688#: src/applications/chat/tools/gnunet-chat.c:128
1689#, c-format
1690msgid "`%s' was confirmed that you received: %s\n"
1691msgstr ""
1692
1693#: src/applications/chat/tools/gnunet-chat.c:131
1694#, c-format
1695msgid "`%s' was confirmed that you and only you received: %s\n"
1696msgstr ""
1697
1698#: src/applications/chat/tools/gnunet-chat.c:134
1699#, c-format
1700msgid "`%s' was confirmed that you received from him or her: %s\n"
1701msgstr ""
1702
1703#: src/applications/chat/tools/gnunet-chat.c:139
1704#, c-format
1705msgid "`%s' was confirmed that you and only you received from him or her: %s\n"
1706msgstr ""
1707
1708#: src/applications/chat/tools/gnunet-chat.c:142
1709#, fuzzy, c-format
1710msgid "`%s' said off the record: %s\n"
1711msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n"
1712
1713#: src/applications/chat/tools/gnunet-chat.c:145
1714#, c-format
1715msgid "<%s> said using an unknown message type: %s\n"
1716msgstr ""
1717
1718#: src/applications/chat/tools/gnunet-chat.c:167
1719#, c-format
1720msgid "`%s' entered the room\n"
1721msgstr ""
1722
1723#: src/applications/chat/tools/gnunet-chat.c:167
1724#, c-format
1725msgid "`%s' left the room\n"
1726msgstr ""
1727
1728#: src/applications/chat/tools/gnunet-chat.c:239
1729#: src/applications/chat/tools/gnunet-chat.c:348
1730#, fuzzy, c-format
1731msgid "Failed to send message.\n"
1732msgstr "Misslyckades att leverera \"%s\" meddelande.\n"
1733
1734#: src/applications/chat/tools/gnunet-chat.c:265
1735#: src/applications/chat/tools/gnunet-chat.c:524
1736#, fuzzy, c-format
1737msgid "Joined room `%s' as user `%s'.\n"
1738msgstr "Ogiltigt svar till \"%s\" från motpart \"%s\".\n"
1739
1740#: src/applications/chat/tools/gnunet-chat.c:293
1741#, fuzzy, c-format
1742msgid "Changed username to `%s'.\n"
1743msgstr "Kan inte ändra användare/grupp till \"%s\": %s\n"
1744
1745#: src/applications/chat/tools/gnunet-chat.c:301
1746#, fuzzy, c-format
1747msgid "Unknown command `%s'.\n"
1748msgstr "Okänd operation \"%s\"\n"
1749
1750#: src/applications/chat/tools/gnunet-chat.c:316
1751#, c-format
1752msgid "Syntax: /msg USERNAME MESSAGE"
1753msgstr ""
1754
1755#: src/applications/chat/tools/gnunet-chat.c:324
1756#, fuzzy, c-format
1757msgid "Unknown user `%s'\n"
1758msgstr "Okänd operation \"%s\"\n"
1759
1760#: src/applications/chat/tools/gnunet-chat.c:339
1761#, c-format
1762msgid "User `%s' is currently not in the room!\n"
1763msgstr ""
1764
1765#: src/applications/chat/tools/gnunet-chat.c:361
1766#, c-format
1767msgid "Users in room `%s': "
1768msgstr ""
1769
1770#: src/applications/chat/tools/gnunet-chat.c:390
1771msgid ""
1772"Use `/join #roomname' to join a chat room. Joining a room will cause you to "
1773"leave the current room"
1774msgstr ""
1775
1776#: src/applications/chat/tools/gnunet-chat.c:393
1777msgid ""
1778"Use `/nick nickname' to change your nickname. This will cause you to leave "
1779"the current room and immediately rejoin it with the new name."
1780msgstr ""
1781
1782#: src/applications/chat/tools/gnunet-chat.c:396
1783msgid ""
1784"Use `/msg nickname message' to send a private message to the specified user"
1785msgstr ""
1786
1787#: src/applications/chat/tools/gnunet-chat.c:398
1788msgid "The `/notice' command is an alias for `/msg'"
1789msgstr ""
1790
1791#: src/applications/chat/tools/gnunet-chat.c:400
1792msgid "The `/query' command is an alias for `/msg'"
1793msgstr ""
1794
1795#: src/applications/chat/tools/gnunet-chat.c:402
1796msgid "Use `/quit' to terminate gnunet-chat"
1797msgstr ""
1798
1799#: src/applications/chat/tools/gnunet-chat.c:404
1800msgid "The `/leave' command is an alias for `/quit'"
1801msgstr ""
1802
1803#: src/applications/chat/tools/gnunet-chat.c:407
1804msgid "Use `/names' to list all of the current members in the chat room"
1805msgstr ""
1806
1807#: src/applications/chat/tools/gnunet-chat.c:409
1808msgid "Use `/help command' to get help for a specific command"
1809msgstr ""
1810
1811#: src/applications/chat/tools/gnunet-chat.c:457
1812msgid "Join a chat on GNUnet."
1813msgstr ""
1814
1815#: src/applications/chat/tools/gnunet-chat.c:461
1816msgid "set the nickname to use (required)"
1817msgstr ""
1818
1819#: src/applications/chat/tools/gnunet-chat.c:464
1820msgid "set the chat room to join"
1821msgstr ""
1822
1823#: src/applications/chat/tools/gnunet-chat.c:495
1824#, fuzzy, c-format
1825msgid "You must specify a nickname\n"
1826msgstr "Du måste ange en mottagare!\n"
1827
1828#: src/applications/chat/tools/gnunet-chat.c:515
1829#, fuzzy, c-format
1830msgid "Failed to join room `%s'\n"
1831msgstr "Misslyckades att läsa kompislista från \"%s\"\n"
1832
1833#: src/applications/chat/module/chat.c:325
1834#, fuzzy, c-format
1835msgid "`%s' registering CS handlers %d and %d\n"
1836msgstr "\"%s\" registrerar handtagen %d och %d\n"
1837
1838#: src/applications/chat/module/chat.c:347
1839msgid "enables P2P-chat (incomplete)"
1840msgstr "aktiverar P2P-chatt (ej komplett)"
1841
1842#: src/applications/chat/lib/messaging.c:353
1843#: src/applications/identity/hostkey.c:122
1844#, fuzzy, c-format
1845msgid "Failed to access GNUnet home directory `%s'\n"
1846msgstr "Filformatsfel (inte en GNUnet-katalog?)\n"
1847
1848#: src/applications/chat/lib/messaging.c:389
1849#, fuzzy, c-format
1850msgid "Existing key in file `%s' failed format check, creating new key.\n"
1851msgstr ""
1852"Existerande värdnyckel i filen \"%s\" felade vid formatkontroll, skapar en "
1853"ny värdnyckel.\n"
1854
1855#: src/applications/chat/lib/messaging.c:399
1856#, fuzzy
1857msgid "Creating new key for this nickname (this may take a while).\n"
1858msgstr "Skapar ny värdnyckel (det här kan ta en stund).\n"
1859
1860#: src/applications/chat/lib/messaging.c:411
1861#, fuzzy
1862msgid "Done creating key.\n"
1863msgstr "Klar med skapandet av värdnyckel.\n"
1864
1865#: src/applications/dstore_mysql/dstore_mysql.c:471
1866msgid "Failed to initialize MySQL database connection for dstore.\n"
1867msgstr ""
1868
1869#: src/applications/dstore_mysql/dstore_mysql.c:494
1870#: src/applications/dstore_sqlite/dstore.c:636
1871#, fuzzy
1872msgid "# bytes in dstore"
1873msgstr "# byte krypterade"
1874
1875#: src/applications/dstore_mysql/dstore_mysql.c:496
1876#: src/applications/dstore_sqlite/dstore.c:638
1877msgid "# max bytes allowed in dstore"
1878msgstr ""
1879
1880#: src/applications/transport/transport.c:191
1881#, c-format
1882msgid ""
1883"Converting peer address to string failed, transport type %d not supported\n"
1884msgstr ""
1885
1886#: src/applications/transport/transport.c:246
1887#, c-format
1888msgid "Transport connection attempt failed, transport type %d not supported\n"
1889msgstr ""
1890
1891#: src/applications/transport/transport.c:299
1892#, c-format
1893msgid ""
1894"Transport failed to connect to peer `%s' (%u HELLOs known, none worked)\n"
1895msgstr ""
1896
1897#: src/applications/transport/transport.c:376
1898#, fuzzy, c-format
1899msgid "Transmission attempt failed, transport type %d unknown.\n"
1900msgstr "Ingen transport av typ %d är känd.\n"
1901
1902#: src/applications/transport/transport.c:500
1903#, c-format
1904msgid "No transport of type %d known.\n"
1905msgstr "Ingen transport av typ %d är känd.\n"
1906
1907#: src/applications/transport/transport.c:560
1908msgid "No transport succeeded in creating a hello!\n"
1909msgstr ""
1910
1911#: src/applications/transport/transport.c:761
1912#, fuzzy, c-format
1913msgid "Loading transports `%s'\n"
1914msgstr "Testar transport(er) %s\n"
1915
1916#: src/applications/transport/transport.c:781
1917#, fuzzy, c-format
1918msgid "Could not load transport plugin `%s'\n"
1919msgstr "Kunde inte slå upp \"%s\": %s\n"
1920
1921#: src/applications/transport/transport.c:795
1922#, c-format
1923msgid "Transport library `%s' did not provide required function '%s%s'.\n"
1924msgstr ""
1925
1926#: src/applications/transport/transport.c:824
1927#, fuzzy, c-format
1928msgid "Loaded transport `%s'\n"
1929msgstr "Tillgängliga transport(er): %s\n"
1930
1931#: src/applications/transport/transport.c:836
1932#: src/server/gnunet-peer-info.c:252
1933#, c-format
1934msgid "I am peer `%s'.\n"
1935msgstr "Jag är ändpunkt \"%s\".\n"
1936
1937#: src/applications/dht/tools/dht_multipeer_test.c:80
1938#: src/applications/dht/tools/dht_twopeer_test.c:47
1939#: src/applications/dht/module/table.c:783
1940#, fuzzy
1941msgid "# dht connections"
1942msgstr "Nätverksanslutning"
1943
1944#: src/applications/dht/tools/dht-query.c:54
1945msgid "Query (get KEY, put KEY VALUE) DHT table."
1946msgstr ""
1947
1948#: src/applications/dht/tools/dht-query.c:58
1949#, fuzzy
1950msgid "allow TIME ms to process a GET command"
1951msgstr "tillåt TID ms för behandling av varje kommando"
1952
1953#: src/applications/dht/tools/dht-query.c:107
1954#, fuzzy, c-format
1955msgid "Issuing `%s(%s,%s)' command.\n"
1956msgstr "\"%s(%s,%s)\" misslyckades.\n"
1957
1958#: src/applications/dht/tools/dht-query.c:142
1959#: src/applications/fs/tools/gnunet-auto-share.c:669
1960#, c-format
1961msgid "Failed to connect to gnunetd.\n"
1962msgstr "Misslyckades att ansluta till gnunetd.\n"
1963
1964#: src/applications/dht/tools/dht-query.c:155
1965#, c-format
1966msgid "Command `%s' requires an argument (`%s').\n"
1967msgstr "Kommando \"%s\" kräver ett argument (\"%s\").\n"
1968
1969#: src/applications/dht/tools/dht-query.c:172
1970#, c-format
1971msgid "Command `%s' requires two arguments (`%s' and `%s').\n"
1972msgstr "Kommando \"%s\" kräver två argument (\"%s\" och \"%s\").\n"
1973
1974#: src/applications/dht/tools/dht-query.c:183
1975#, c-format
1976msgid "Unsupported command `%s'. Aborting.\n"
1977msgstr "Kommando \"%s\" stöds ej. Avbryter.\n"
1978
1979#: src/applications/dht/module/table.c:785
1980#, fuzzy
1981msgid "# dht discovery messages received"
1982msgstr "# krypterade PONG-meddelanden mottagna"
1983
1984#: src/applications/dht/module/table.c:787
1985msgid "# dht route host lookups performed"
1986msgstr ""
1987
1988#: src/applications/dht/module/table.c:789
1989#, fuzzy
1990msgid "# dht discovery messages sent"
1991msgstr "# krypterade PONG-meddelanden skickade"
1992
1993#: src/applications/dht/module/routing.c:879
1994msgid "# dht replies routed"
1995msgstr ""
1996
1997#: src/applications/dht/module/routing.c:881
1998msgid "# dht requests routed"
1999msgstr ""
2000
2001#: src/applications/dht/module/routing.c:883
2002msgid "# dht get requests received"
2003msgstr ""
2004
2005#: src/applications/dht/module/routing.c:885
2006msgid "# dht put requests received"
2007msgstr ""
2008
2009#: src/applications/dht/module/routing.c:887
2010#, fuzzy
2011msgid "# dht results received"
2012msgstr "# byte mottogs via TCP"
2013
2014#: src/applications/dht/module/routing.c:892
2015#, fuzzy, c-format
2016msgid "`%s' registering p2p handlers: %d %d %d\n"
2017msgstr "\"%s\" registrerar handtag %d %d %d\n"
2018
2019#: src/applications/dht/module/cs.c:122
2020#, c-format
2021msgid "`%s' failed. Terminating connection to client.\n"
2022msgstr "\"%s\" misslyckades. Terminerar anslutning till klient.\n"
2023
2024#: src/applications/dht/module/cs.c:250
2025#, fuzzy, c-format
2026msgid "`%s' registering client handlers: %d %d\n"
2027msgstr "\"%s\" registrerar klienthandtag %d\n"
2028
2029#: src/applications/dht/module/cs.c:273
2030msgid "Enables efficient non-anonymous routing"
2031msgstr ""
2032
2033#: src/applications/identity/hostkey.c:155
2034#, c-format
2035msgid ""
2036"Existing hostkey in file `%s' failed format check, creating new hostkey.\n"
2037msgstr ""
2038"Existerande värdnyckel i filen \"%s\" felade vid formatkontroll, skapar en "
2039"ny värdnyckel.\n"
2040
2041#: src/applications/identity/hostkey.c:164
2042msgid "Creating new hostkey (this may take a while).\n"
2043msgstr "Skapar ny värdnyckel (det här kan ta en stund).\n"
2044
2045#: src/applications/identity/hostkey.c:176
2046msgid "Done creating hostkey.\n"
2047msgstr "Klar med skapandet av värdnyckel.\n"
2048
2049#: src/applications/identity/identity.c:333
2050#, c-format
2051msgid ""
2052"File `%s' in directory `%s' does not match naming convention. Removed.\n"
2053msgstr ""
2054
2055#: src/applications/identity/identity.c:408
2056#, c-format
2057msgid "Still no peers found in `%s'!\n"
2058msgstr ""
2059
2060#: src/applications/identity/identity.c:731
2061#: src/applications/identity/identity.c:757
2062#, c-format
2063msgid "Removed file `%s' containing invalid HELLO data.\n"
2064msgstr ""
2065
2066#: src/applications/identity/identity.c:809
2067#, c-format
2068msgid "Signature failed verification: peer `%s' not known.\n"
2069msgstr ""
2070
2071#: src/applications/identity/identity.c:819
2072msgid "Signature failed verification: signature invalid.\n"
2073msgstr ""
2074
2075#: src/applications/identity/identity.c:935
2076#: src/applications/identity/identity.c:1058
2077#, c-format
2078msgid "Peer `%s' is currently strictly blacklisted (for another %llums).\n"
2079msgstr ""
2080
2081#: src/applications/identity/identity.c:1061
2082#, c-format
2083msgid "Peer `%s' is currently blacklisted (for another %llums).\n"
2084msgstr ""
2085
2086#: src/applications/pingpong/pingpong.c:134
2087#: src/applications/pingpong/pingpong.c:203
2088#: src/applications/pingpong/pingpong.c:273
2089#: src/applications/pingpong/pingpong.c:345
2090#, c-format
2091msgid "Received malformed `%s' message. Dropping.\n"
2092msgstr ""
2093
2094#: src/applications/pingpong/pingpong.c:146
2095msgid "Received ping for another peer. Dropping.\n"
2096msgstr ""
2097
2098#: src/applications/pingpong/pingpong.c:215
2099#, fuzzy, c-format
2100msgid "Received PING from `%s' not destined for us!\n"
2101msgstr "Mottog PING som ej var ämnat för oss!\n"
2102
2103#: src/applications/pingpong/pingpong.c:315
2104#: src/applications/pingpong/pingpong.c:381
2105msgid ""
2106"Could not match PONG against any PING. Try increasing MAX_PING_PONG "
2107"constant.\n"
2108msgstr ""
2109
2110#: src/applications/pingpong/pingpong.c:425
2111msgid "Cannot create PING, table full. Try increasing MAX_PING_PONG.\n"
2112msgstr "Kan inte skapa PING, tabell är full. Försök att öka MAX_PING_PONG.\n"
2113
2114#: src/applications/pingpong/pingpong.c:518
2115msgid "# encrypted PONG messages received"
2116msgstr "# krypterade PONG-meddelanden mottagna"
2117
2118#: src/applications/pingpong/pingpong.c:520
2119msgid "# plaintext PONG messages received"
2120msgstr "# klartext PONG-meddelanden mottagna"
2121
2122#: src/applications/pingpong/pingpong.c:522
2123msgid "# encrypted PING messages received"
2124msgstr "# krypterade PING-meddelanden mottagna"
2125
2126#: src/applications/pingpong/pingpong.c:524
2127msgid "# PING messages created"
2128msgstr "# PING-meddelanden skapade"
2129
2130#: src/applications/pingpong/pingpong.c:526
2131#: src/applications/session/connect.c:926
2132msgid "# encrypted PONG messages sent"
2133msgstr "# krypterade PONG-meddelanden skickade"
2134
2135#: src/applications/pingpong/pingpong.c:530
2136#: src/applications/session/connect.c:924
2137msgid "# encrypted PING messages sent"
2138msgstr "# krypterade PING-meddelanden skickade"
2139
2140#: src/applications/pingpong/pingpong.c:532
2141#, fuzzy
2142msgid "# plaintext PONG messages sent"
2143msgstr "# PING-meddelanden i klartext skickade"
2144
2145#: src/applications/pingpong/pingpong.c:536
2146#, fuzzy
2147msgid "# plaintext PONG transmissions failed"
2148msgstr "# klartext PONG-meddelanden mottagna"
2149
2150#: src/applications/pingpong/pingpong.c:546
2151#, c-format
2152msgid "`%s' registering handlers %d %d (plaintext and ciphertext)\n"
2153msgstr "\"%s\" registrerar handtag %d %d (klartext och kryptotext)\n"
2154
2155#: src/applications/hostlist/hostlist.c:165
2156msgid "# hostlist requests received"
2157msgstr ""
2158
2159#: src/applications/hostlist/hostlist.c:167
2160msgid "# hostlist HELLOs returned"
2161msgstr ""
2162
2163#: src/applications/hostlist/hostlist.c:169
2164msgid "# hostlist bytes returned"
2165msgstr ""
2166
2167#: src/applications/hostlist/hostlist.c:199
2168msgid "integrated HTTP hostlist server"
2169msgstr ""
2170
2171#: src/applications/session/connect.c:238
2172#, c-format
2173msgid "Session key from peer `%s' could not be verified.\n"
2174msgstr ""
2175
2176#: src/applications/session/connect.c:282
2177#, fuzzy, c-format
2178msgid "Cannot encrypt sessionkey, peer `%s' not known!\n"
2179msgstr "Kan inte kryptera sessionsnyckel, andra parten är inte känd!\n"
2180
2181#: src/applications/session/connect.c:489
2182#, c-format
2183msgid "Could not create any HELLO for myself (have transports `%s')!\n"
2184msgstr ""
2185
2186#: src/applications/session/connect.c:599
2187#, fuzzy, c-format
2188msgid "Session key received from peer `%s' has invalid format (discarded).\n"
2189msgstr "Meddelande mottaget från motpart är ogiltig.\n"
2190
2191#: src/applications/session/connect.c:632
2192#, c-format
2193msgid "Session key received from peer `%s' is for `%s' and not for me!\n"
2194msgstr ""
2195
2196#: src/applications/session/connect.c:659
2197#, c-format
2198msgid "Invalid `%s' message received from peer `%s'.\n"
2199msgstr ""
2200
2201#: src/applications/session/connect.c:670
2202#, c-format
2203msgid "setkey `%s' from `%s' fails CRC check (have: %u, want %u).\n"
2204msgstr ""
2205
2206#: src/applications/session/connect.c:728
2207#, c-format
2208msgid ""
2209"Error parsing encrypted session key from `%s', given message part size is "
2210"invalid.\n"
2211msgstr ""
2212
2213#: src/applications/session/connect.c:741
2214#, c-format
2215msgid "Unknown type in embedded message from `%s': %u (size: %u)\n"
2216msgstr ""
2217
2218#: src/applications/session/connect.c:916
2219msgid "# session keys sent"
2220msgstr "# sessionsnycklar skickade"
2221
2222#: src/applications/session/connect.c:918
2223msgid "# session keys rejected"
2224msgstr "# sessionnycklar vägrade"
2225
2226#: src/applications/session/connect.c:920
2227msgid "# session keys accepted"
2228msgstr "# sessionsnycklar accepterade"
2229
2230#: src/applications/session/connect.c:922
2231msgid "# sessions established"
2232msgstr "# sessioner etablerade"
2233
2234#: src/applications/fs/tools/gnunet-pseudonym.c:70
2235#: src/applications/fs/tools/gnunet-auto-share.c:199
2236#: src/applications/fs/tools/gnunet-insert.c:246
2237#: src/applications/fs/tools/gnunet-search.c:125
2238#: src/applications/fs/tools/gnunet-download.c:77
2239msgid "set the desired LEVEL of sender-anonymity"
2240msgstr ""
2241
2242#: src/applications/fs/tools/gnunet-pseudonym.c:73
2243msgid "automate creation of a namespace by starting a collection"
2244msgstr ""
2245
2246#: src/applications/fs/tools/gnunet-pseudonym.c:77
2247msgid "create a new pseudonym under the given NICKNAME"
2248msgstr "skapa en ny pseudonym under angivet SMEKNAMN"
2249
2250#: src/applications/fs/tools/gnunet-pseudonym.c:80
2251msgid "delete the pseudonym with the given NICKNAME"
2252msgstr "ta bort pseudonymen med angivet SMEKNAMN"
2253
2254#: src/applications/fs/tools/gnunet-pseudonym.c:83
2255msgid "end automated building of a namespace (ends collection)"
2256msgstr ""
2257
2258#: src/applications/fs/tools/gnunet-pseudonym.c:85
2259msgid "Create new pseudonyms, delete pseudonyms or list existing pseudonyms."
2260msgstr ""
2261"Skapa nya pseudonymer, ta bort pseudonymer eller lista existerande "
2262"pseudonymer."
2263
2264#: src/applications/fs/tools/gnunet-pseudonym.c:89
2265msgid ""
2266"use the given keyword to advertise the namespace (use when creating a new "
2267"pseudonym)"
2268msgstr ""
2269
2270#: src/applications/fs/tools/gnunet-pseudonym.c:92
2271msgid "specify metadata describing the namespace or collection"
2272msgstr ""
2273
2274#: src/applications/fs/tools/gnunet-pseudonym.c:96
2275msgid ""
2276"do not generate an advertisement for this namespace (use when creating a new "
2277"pseudonym)"
2278msgstr ""
2279
2280#: src/applications/fs/tools/gnunet-pseudonym.c:99
2281msgid "do not list the pseudonyms from the pseudonym database"
2282msgstr ""
2283
2284#: src/applications/fs/tools/gnunet-pseudonym.c:103
2285msgid ""
2286"specify IDENTIFIER to be the address of the entrypoint to content in the "
2287"namespace (use when creating a new pseudonym)"
2288msgstr ""
2289
2290#: src/applications/fs/tools/gnunet-pseudonym.c:106
2291msgid "set the rating of a namespace"
2292msgstr ""
2293
2294#: src/applications/fs/tools/gnunet-pseudonym.c:141
2295#, c-format
2296msgid "Namespace `%s' has rating %d.\n"
2297msgstr ""
2298
2299#: src/applications/fs/tools/gnunet-pseudonym.c:143
2300#, c-format
2301msgid "Namespace `%s' (%s) has rating %d.\n"
2302msgstr ""
2303
2304#: src/applications/fs/tools/gnunet-pseudonym.c:175
2305#, c-format
2306msgid "\tRating (after update): %d\n"
2307msgstr ""
2308
2309#: src/applications/fs/tools/gnunet-pseudonym.c:179
2310#: src/applications/fs/tools/gnunet-pseudonym.c:241
2311#: src/applications/fs/tools/gnunet-insert.c:101
2312#, fuzzy, c-format
2313msgid "\tUnknown namespace `%s'\n"
2314msgstr "Okänd operation \"%s\"\n"
2315
2316#: src/applications/fs/tools/gnunet-pseudonym.c:217
2317#, c-format
2318msgid "Collection stopped.\n"
2319msgstr "Samling stoppad.\n"
2320
2321#: src/applications/fs/tools/gnunet-pseudonym.c:219
2322#, c-format
2323msgid "Failed to stop collection (not active?).\n"
2324msgstr "Misslyckades att stoppa samling (inte aktiv?).\n"
2325
2326#: src/applications/fs/tools/gnunet-pseudonym.c:230
2327#, c-format
2328msgid "Pseudonym `%s' deleted.\n"
2329msgstr "Pseudonym \"%s\" togs bort.\n"
2330
2331#: src/applications/fs/tools/gnunet-pseudonym.c:235
2332#, c-format
2333msgid "Error deleting pseudonym `%s' (does not exist?).\n"
2334msgstr "Fel vid borttagning av pseudonym \"%s\" (existerar den?).\n"
2335
2336#: src/applications/fs/tools/gnunet-pseudonym.c:256
2337#, fuzzy
2338msgid "Started collection.\n"
2339msgstr "Startade samling \"%s\".\n"
2340
2341#: src/applications/fs/tools/gnunet-pseudonym.c:260
2342msgid "Failed to start collection.\n"
2343msgstr "Misslyckades att starta samling.\n"
2344
2345#: src/applications/fs/tools/gnunet-pseudonym.c:296
2346#, fuzzy
2347msgid "Could not create namespace.\n"
2348msgstr "Kunde inte skapa namnrymd \"%s\" (existerar?).\n"
2349
2350#: src/applications/fs/tools/gnunet-pseudonym.c:304
2351#, c-format
2352msgid "Namespace `%s' created (root: %s).\n"
2353msgstr "Namnrymd \"%s\" skapad(rot: %s).\n"
2354
2355#: src/applications/fs/tools/gnunet-pseudonym.c:321
2356#, fuzzy, c-format
2357msgid "You must specify a name for the collection (`%s' option).\n"
2358msgstr "Du måste ange ett namn för PID-filen i sektion \"%s\" under \"%s\".\n"
2359
2360#: src/applications/fs/tools/gnunet-pseudonym.c:329
2361#, c-format
2362msgid "Could not access namespace information.\n"
2363msgstr "Kunde inte komma åt namnrymdsinformation.\n"
2364
2365#: src/applications/fs/tools/gnunet-directory.c:84
2366#, c-format
2367msgid "==> Directory `%s':\n"
2368msgstr "==> Katalog \"%s\":\n"
2369
2370#: src/applications/fs/tools/gnunet-directory.c:88
2371#, c-format
2372msgid "=\tError reading directory.\n"
2373msgstr "=\tFel vid läsning av katalog.\n"
2374
2375#: src/applications/fs/tools/gnunet-directory.c:118
2376#, c-format
2377msgid "File format error (not a GNUnet directory?)\n"
2378msgstr "Filformatsfel (inte en GNUnet-katalog?)\n"
2379
2380#: src/applications/fs/tools/gnunet-directory.c:120
2381#, c-format
2382msgid "%d files found in directory.\n"
2383msgstr "%d filer hittades i katalog.\n"
2384
2385#: src/applications/fs/tools/gnunet-directory.c:135
2386msgid "Perform directory related operations."
2387msgstr "Genomför katalogrelaterade operationer."
2388
2389#: src/applications/fs/tools/gnunet-directory.c:138
2390msgid "remove all entries from the directory database and stop tracking URIs"
2391msgstr ""
2392
2393#: src/applications/fs/tools/gnunet-directory.c:142
2394msgid "list entries from the directory database"
2395msgstr ""
2396
2397#: src/applications/fs/tools/gnunet-directory.c:145
2398msgid "start tracking entries for the directory database"
2399msgstr ""
2400
2401#: src/applications/fs/tools/gnunet-directory.c:168
2402#, c-format
2403msgid "Listed %d matching entries.\n"
2404msgstr "Listade %d matchande poster.\n"
2405
2406#: src/applications/fs/tools/gnunet-auto-share.c:117
2407#, fuzzy, c-format
2408msgid "Upload of `%s' at %llu out of %llu bytes.\n"
2409msgstr "Hämtning av fil \"%s\" vid %16llu av %16llu byte (%8.3f kbps)\n"
2410
2411#: src/applications/fs/tools/gnunet-auto-share.c:130
2412#, fuzzy, c-format
2413msgid "Upload of `%s' complete, URI is `%s'.\n"
2414msgstr ""
2415"Uppladdning av \"%s\" klar, aktuell genomsnittshastighet är %8.3f kbps.\n"
2416
2417#: src/applications/fs/tools/gnunet-auto-share.c:139
2418#, fuzzy, c-format
2419msgid "Upload aborted.\n"
2420msgstr "Nedladdning avbruten."
2421
2422#: src/applications/fs/tools/gnunet-auto-share.c:145
2423#, fuzzy, c-format
2424msgid "Error uploading file: %s\n"
2425msgstr ""
2426"\n"
2427"Fel vid uppladdning av fil: %s\n"
2428
2429#: src/applications/fs/tools/gnunet-auto-share.c:154
2430#, fuzzy, c-format
2431msgid "Starting upload of `%s'.\n"
2432msgstr "Startade samling \"%s\".\n"
2433
2434#: src/applications/fs/tools/gnunet-auto-share.c:164
2435#, fuzzy, c-format
2436msgid "Uploading suspended.\n"
2437msgstr "Uppladdning misslyckades.\n"
2438
2439#: src/applications/fs/tools/gnunet-auto-share.c:179
2440#, fuzzy, c-format
2441msgid "Uploading `%s' resumed.\n"
2442msgstr "Uppladdning vägrades!"
2443
2444#: src/applications/fs/tools/gnunet-auto-share.c:186
2445#, c-format
2446msgid "Unexpected event: %d\n"
2447msgstr ""
2448
2449#: src/applications/fs/tools/gnunet-auto-share.c:205
2450msgid ""
2451"run in debug mode; gnunet-auto-share will not daemonize and error messages "
2452"will be written to stderr instead of a logfile"
2453msgstr ""
2454
2455#: src/applications/fs/tools/gnunet-auto-share.c:211
2456#: src/applications/fs/tools/gnunet-insert.c:259
2457#, fuzzy
2458msgid ""
2459"do not use libextractor to add additional references to directory entries "
2460"and/or the published file"
2461msgstr ""
2462"använd libextractor för att lägga till ytterligare direktreferenser till "
2463"katalogposter"
2464
2465#: src/applications/fs/tools/gnunet-auto-share.c:213
2466msgid "Automatically share a directory."
2467msgstr ""
2468
2469#: src/applications/fs/tools/gnunet-auto-share.c:216
2470#: src/applications/fs/tools/gnunet-insert.c:273
2471msgid ""
2472"add an additional keyword for all files and directories (this option can be "
2473"specified multiple times)"
2474msgstr ""
2475
2476#: src/applications/fs/tools/gnunet-auto-share.c:221
2477#: src/applications/fs/tools/gnunet-insert.c:290
2478msgid "specify the priority of the content"
2479msgstr "ange prioritet för innehållet"
2480
2481#: src/applications/fs/tools/gnunet-auto-share.c:468
2482#: src/applications/fs/tools/gnunet-auto-share.c:903
2483#, fuzzy, c-format
2484msgid "Could not access `%s': %s\n"
2485msgstr "Kunde inte köra \"%s\": %s\n"
2486
2487#: src/applications/fs/tools/gnunet-auto-share.c:547
2488#, c-format
2489msgid "Unknown keyword type `%s' in metadata configuration\n"
2490msgstr ""
2491
2492#: src/applications/fs/tools/gnunet-auto-share.c:652
2493#, fuzzy, c-format
2494msgid "Failed to stop running gnunet-auto-share.\n"
2495msgstr "Misslyckades att ansluta till gnunetd.\n"
2496
2497#: src/applications/fs/tools/gnunet-auto-share.c:918
2498#, c-format
2499msgid "Directory `%s' is already on the list of shared directories.\n"
2500msgstr ""
2501
2502#: src/applications/fs/tools/gnunet-auto-share.c:939
2503msgid ""
2504"The specified directories were added to the list of shared directories.\n"
2505msgstr ""
2506
2507#: src/applications/fs/tools/gnunet-auto-share.c:961
2508#, fuzzy, c-format
2509msgid "Could not open logfile `%s': %s\n"
2510msgstr "Kunde inte slå upp \"%s\": %s\n"
2511
2512#: src/applications/fs/tools/gnunet-insert.c:115
2513#, c-format
2514msgid "Created entry `%s' in namespace `%s'\n"
2515msgstr "Skapade post \"%s\" i namnrymd \"%s\"\n"
2516
2517#: src/applications/fs/tools/gnunet-insert.c:120
2518#, c-format
2519msgid "Failed to add entry to namespace `%s' (does it exist?)\n"
2520msgstr ""
2521
2522#: src/applications/fs/tools/gnunet-insert.c:135
2523#, c-format
2524msgid "Keywords for file `%s':\n"
2525msgstr "Nyckelord för fil \"%s\":\n"
2526
2527#: src/applications/fs/tools/gnunet-insert.c:144
2528msgid "filename"
2529msgstr ""
2530
2531#: src/applications/fs/tools/gnunet-insert.c:146
2532msgid "mimetype"
2533msgstr ""
2534
2535#: src/applications/fs/tools/gnunet-insert.c:186
2536#, fuzzy, c-format
2537msgid "%16llu of %16llu bytes inserted (estimating %6s to completion) - %s\n"
2538msgstr "%16llu av %16llu byte inlagda (uppskattar %s till färdigställd)\n"
2539
2540#: src/applications/fs/tools/gnunet-insert.c:198
2541#, fuzzy, c-format
2542msgid "Upload of `%s' complete, %llu bytes took %llu seconds (%8.3f KiB/s).\n"
2543msgstr ""
2544"Uppladdning av \"%s\" klar, %llu byte tog %llu sekunder (%8.3f kbps).\n"
2545
2546#: src/applications/fs/tools/gnunet-insert.c:209
2547#, c-format
2548msgid "File `%s' has URI: %s\n"
2549msgstr "Fil \"%s\" har URI: %s\n"
2550
2551#: src/applications/fs/tools/gnunet-insert.c:220
2552#, fuzzy, c-format
2553msgid ""
2554"\n"
2555"Upload aborted.\n"
2556msgstr "Nedladdning avbruten."
2557
2558#: src/applications/fs/tools/gnunet-insert.c:225
2559#, fuzzy, c-format
2560msgid ""
2561"\n"
2562"Error uploading file: %s"
2563msgstr ""
2564"\n"
2565"Fel vid uppladdning av fil: %s\n"
2566
2567#: src/applications/fs/tools/gnunet-insert.c:234
2568#, c-format
2569msgid ""
2570"\n"
2571"Unexpected event: %d\n"
2572msgstr ""
2573
2574#: src/applications/fs/tools/gnunet-insert.c:250
2575msgid ""
2576"even if gnunetd is running on the local machine, force the creation of a "
2577"copy instead of making a link to the GNUnet share directory"
2578msgstr ""
2579"även om gnunetd körs på den lokala maskinen, tvinga fram skapandet av en "
2580"kopia istället för att göra en länk till GNUnets utdelade katalog"
2581
2582#: src/applications/fs/tools/gnunet-insert.c:255
2583msgid "disable adding the creation time to the metadata of the uploaded file"
2584msgstr ""
2585
2586#: src/applications/fs/tools/gnunet-insert.c:263
2587msgid ""
2588"print list of extracted keywords that would be used, but do not perform "
2589"upload"
2590msgstr ""
2591
2592#: src/applications/fs/tools/gnunet-insert.c:265
2593msgid "Make files available to GNUnet for sharing."
2594msgstr "Gör filer tillgängliga via utdelning till GNUnet."
2595
2596#: src/applications/fs/tools/gnunet-insert.c:269
2597msgid ""
2598"add an additional keyword for the top-level file or directory (this option "
2599"can be specified multiple times)"
2600msgstr ""
2601
2602#: src/applications/fs/tools/gnunet-insert.c:278
2603msgid "set the meta-data for the given TYPE to the given VALUE"
2604msgstr ""
2605
2606#: src/applications/fs/tools/gnunet-insert.c:281
2607msgid ""
2608"do not index, perform full insertion (stores entire file in encrypted form "
2609"in GNUnet database)"
2610msgstr ""
2611
2612#: src/applications/fs/tools/gnunet-insert.c:286
2613msgid ""
2614"specify ID of an updated version to be published in the future (for "
2615"namespace insertions only)"
2616msgstr ""
2617
2618#: src/applications/fs/tools/gnunet-insert.c:294
2619msgid "publish the files under the pseudonym NAME (place file into namespace)"
2620msgstr ""
2621
2622#: src/applications/fs/tools/gnunet-insert.c:297
2623msgid ""
2624"only simulte the process but do not do any actual publishing (useful to "
2625"compute URIs)"
2626msgstr ""
2627
2628#: src/applications/fs/tools/gnunet-insert.c:301
2629msgid ""
2630"set the ID of this version of the publication (for namespace insertions only)"
2631msgstr ""
2632
2633#: src/applications/fs/tools/gnunet-insert.c:305
2634msgid ""
2635"URI to be published (can be used instead of passing a file to add keywords "
2636"to the file with the respective URI)"
2637msgstr ""
2638
2639#: src/applications/fs/tools/gnunet-insert.c:342
2640#, fuzzy, c-format
2641msgid "You must specify one and only one filename for insertion.\n"
2642msgstr "Du måste ange en och endast en fil att avindexera.\n"
2643
2644#: src/applications/fs/tools/gnunet-insert.c:348
2645#, fuzzy, c-format
2646msgid "You must NOT specify an URI and a filename.\n"
2647msgstr "Du måste ange en och endast en fil att avindexera.\n"
2648
2649#: src/applications/fs/tools/gnunet-insert.c:354
2650#, c-format
2651msgid "Cannot extract metadata from a URI!\n"
2652msgstr ""
2653
2654#: src/applications/fs/tools/gnunet-insert.c:400
2655#, c-format
2656msgid "Could not access namespace `%s' (does not exist?).\n"
2657msgstr ""
2658
2659#: src/applications/fs/tools/gnunet-insert.c:408
2660#, fuzzy, c-format
2661msgid "Option `%s' is required when using option `%s'.\n"
2662msgstr "Kommando \"%s\" kräver ett argument (\"%s\").\n"
2663
2664#: src/applications/fs/tools/gnunet-insert.c:419
2665#: src/applications/fs/tools/gnunet-insert.c:427
2666#, c-format
2667msgid "Option `%s' makes no sense without option `%s'.\n"
2668msgstr ""
2669
2670#: src/applications/fs/tools/gnunet-search.c:128
2671msgid "Search GNUnet for files."
2672msgstr "Sök GNUnet efter filer."
2673
2674#: src/applications/fs/tools/gnunet-search.c:132
2675msgid "write encountered (decrypted) search results to FILENAME"
2676msgstr ""
2677
2678#: src/applications/fs/tools/gnunet-search.c:169
2679#, c-format
2680msgid "Error converting arguments to URI!\n"
2681msgstr ""
2682
2683#: src/applications/fs/tools/gnunet-unindex.c:61
2684#, c-format
2685msgid ""
2686"%16llu of %16llu bytes unindexed (estimating %llu seconds to "
2687"completion) "
2688msgstr ""
2689"%16llu av %16llu byte avindexerat (uppskattar %llu sekunder till "
2690"färdigställd) "
2691
2692#: src/applications/fs/tools/gnunet-unindex.c:73
2693#, fuzzy, c-format
2694msgid ""
2695"\n"
2696"Unindexing of `%s' complete, %llu bytes took %llu seconds (%8.3f KiB/s).\n"
2697msgstr ""
2698"\n"
2699"Avindexering av \"%s\" klar, %llu byte tog %llu sekunder (%8.3f kbps).\n"
2700
2701#: src/applications/fs/tools/gnunet-unindex.c:88
2702#, c-format
2703msgid ""
2704"\n"
2705"Error unindexing file: %s\n"
2706msgstr ""
2707"\n"
2708"Fel vid avindexering av fil: %s\n"
2709
2710#: src/applications/fs/tools/gnunet-unindex.c:108
2711msgid "Unindex files."
2712msgstr "Avindexera filer."
2713
2714#: src/applications/fs/tools/gnunet-unindex.c:145
2715#, fuzzy
2716msgid "Not enough arguments. You must specify a filename.\n"
2717msgstr ""
2718"Inte tillräckligt med argument. Du måste ange en URI till en GNUnet-fil\n"
2719
2720#: src/applications/fs/tools/gnunet-unindex.c:163
2721#, c-format
2722msgid "`%s' failed. Is `%s' a file?\n"
2723msgstr "\"%s\" misslyckades. Är \"%s\" en fil?\n"
2724
2725#: src/applications/fs/tools/gnunet-download.c:82
2726msgid ""
2727"download a GNUnet directory that has already been downloaded. Requires that "
2728"a filename of an existing file is specified instead of the URI. The "
2729"download will only download the top-level files in the directory unless the "
2730"`-R' option is also specified."
2731msgstr ""
2732
2733#: src/applications/fs/tools/gnunet-download.c:85
2734msgid "delete incomplete downloads (when aborted with CTRL-C)"
2735msgstr ""
2736
2737#: src/applications/fs/tools/gnunet-download.c:87
2738msgid "Download files from GNUnet."
2739msgstr "Ladda ner filer från GNUnet."
2740
2741#: src/applications/fs/tools/gnunet-download.c:91
2742msgid "write the file to FILENAME"
2743msgstr "skriv filen till FILNAMN"
2744
2745#: src/applications/fs/tools/gnunet-download.c:95
2746msgid "set the maximum number of parallel downloads that are allowed"
2747msgstr ""
2748
2749#: src/applications/fs/tools/gnunet-download.c:98
2750msgid "download a GNUnet directory recursively"
2751msgstr "hämta en GNUnet-katalog rekursivt"
2752
2753#: src/applications/fs/tools/gnunet-download.c:119
2754#, fuzzy, c-format
2755msgid "Download of file `%s' at %16llu out of %16llu bytes (%8.3f KiB/s)\n"
2756msgstr "Hämtning av fil \"%s\" vid %16llu av %16llu byte (%8.3f kbps)\n"
2757
2758#: src/applications/fs/tools/gnunet-download.c:133
2759#, fuzzy, c-format
2760msgid "Download aborted.\n"
2761msgstr "Nedladdning avbruten."
2762
2763#: src/applications/fs/tools/gnunet-download.c:139
2764#, c-format
2765msgid "Error downloading: %s\n"
2766msgstr "Fel vid nedladdning: %s\n"
2767
2768#: src/applications/fs/tools/gnunet-download.c:145
2769#, fuzzy, c-format
2770msgid "Download of file `%s' complete. Speed was %8.3f KiB per second.\n"
2771msgstr ""
2772"Hämtning av fil \"%s\" färdig. Hastigheten var %8.3f kilobyte per sekund.\n"
2773
2774#: src/applications/fs/tools/gnunet-download.c:191
2775msgid "no name given"
2776msgstr ""
2777
2778#: src/applications/fs/tools/gnunet-download.c:197
2779#, fuzzy, c-format
2780msgid "Starting download `%s'\n"
2781msgstr "Startade samling \"%s\".\n"
2782
2783#: src/applications/fs/tools/gnunet-download.c:239
2784msgid "Not enough arguments. You must specify a GNUnet file URI\n"
2785msgstr ""
2786"Inte tillräckligt med argument. Du måste ange en URI till en GNUnet-fil\n"
2787
2788#: src/applications/fs/tools/gnunet-download.c:257
2789#, c-format
2790msgid "URI `%s' invalid for gnunet-download.\n"
2791msgstr "URI \"%s\" ogiltig för gnunet-download.\n"
2792
2793#: src/applications/fs/tools/gnunet-download.c:300
2794#, fuzzy, c-format
2795msgid "No filename specified, using `%s' instead (for now).\n"
2796msgstr "Inget tabellnamn angivet, använder \"%s\".\n"
2797
2798#: src/applications/fs/tools/gnunet-download.c:342
2799#, fuzzy, c-format
2800msgid "Could not access gnunet-directory file `%s'\n"
2801msgstr "Kunde inte tolka konfigurationsfil \"%s\".\n"
2802
2803#: src/applications/fs/tools/gnunet-download.c:363
2804#, fuzzy, c-format
2805msgid "Downloading %d files from directory `%s'.\n"
2806msgstr "Ladda ner filer från GNUnet."
2807
2808#: src/applications/fs/tools/gnunet-download.c:366
2809#, fuzzy, c-format
2810msgid "Did not find any files in directory `%s'\n"
2811msgstr "%d filer hittades i katalog.\n"
2812
2813#: src/applications/fs/tools/gnunet-download.c:404
2814#, c-format
2815msgid "File stored as `%s'.\n"
2816msgstr "Fil lagrad som \"%s\".\n"
2817
2818#: src/applications/fs/uritrack/file_info.c:98
2819msgid "Collecting file identifiers disabled.\n"
2820msgstr ""
2821
2822#: src/applications/fs/uritrack/file_info.c:377
2823#, c-format
2824msgid "Deleted corrupt URI database in `%s'."
2825msgstr ""
2826
2827#: src/applications/fs/ecrs/upload.c:158
2828#, c-format
2829msgid "`%s' is not a file.\n"
2830msgstr "\"%s\" är inte en fil.\n"
2831
2832#: src/applications/fs/ecrs/upload.c:166
2833#, c-format
2834msgid "Cannot get size of file `%s'"
2835msgstr "Kan inte hämta storlek på fil \"%s\""
2836
2837#: src/applications/fs/ecrs/upload.c:175
2838#, fuzzy
2839msgid "Failed to connect to gnunetd."
2840msgstr "Misslyckades att ansluta till gnunetd.\n"
2841
2842#: src/applications/fs/ecrs/upload.c:187
2843#, c-format
2844msgid "Cannot hash `%s'.\n"
2845msgstr ""
2846
2847#: src/applications/fs/ecrs/upload.c:215
2848#, c-format
2849msgid "Initialization for indexing file `%s' failed.\n"
2850msgstr "Initiering av indexering av fil \"%s\" misslyckades.\n"
2851
2852#: src/applications/fs/ecrs/upload.c:223
2853#, fuzzy, c-format
2854msgid "Indexing file `%s' failed. Suggestion: try to insert the file.\n"
2855msgstr "Indexering av fil \"%s\" misslyckades. Försöker att infoga fil...\n"
2856
2857#: src/applications/fs/ecrs/upload.c:237
2858#, fuzzy, c-format
2859msgid "Cannot open file `%s': `%s'"
2860msgstr "Kan inte öppna konfigurationsfil \"%s\".\n"
2861
2862#: src/applications/fs/ecrs/upload.c:322
2863#, fuzzy, c-format
2864msgid "Indexing data of file `%s' failed at position %llu.\n"
2865msgstr "Indexering av data misslyckades vid position %i.\n"
2866
2867#: src/applications/fs/ecrs/helper.c:91
2868msgid "No keywords specified!\n"
2869msgstr "Inga nyckelord angivna!\n"
2870
2871#: src/applications/fs/ecrs/helper.c:99
2872msgid "Number of double-quotes not balanced!\n"
2873msgstr ""
2874
2875#: src/applications/fs/ecrs/helper.c:398
2876#, c-format
2877msgid "Renaming of file `%s' to `%s' failed: %s\n"
2878msgstr "Namnbyte på fil \"%s\" till \"%s\" misslyckades: %s\n"
2879
2880#: src/applications/fs/ecrs/helper.c:408
2881#, c-format
2882msgid "Could not rename file `%s' to `%s': file exists\n"
2883msgstr "Kunde inte byta namn på fil \"%s\" till \"%s\": filen existerar\n"
2884
2885#: src/applications/fs/ecrs/parser.c:165
2886#, c-format
2887msgid ""
2888"Unknown metadata type in metadata option `%s'. Using metadata type "
2889"`unknown' instead.\n"
2890msgstr ""
2891
2892#: src/applications/fs/ecrs/search.c:152
2893msgid "CHK URI not allowed for search.\n"
2894msgstr "CHK URI tillåts inte för sökning.\n"
2895
2896#: src/applications/fs/ecrs/search.c:207
2897msgid "LOC URI not allowed for search.\n"
2898msgstr "LOC URI tillåts inte för sökning.\n"
2899
2900#: src/applications/fs/ecrs/namespace.c:365
2901#, c-format
2902msgid "File `%s' does not contain a pseudonym.\n"
2903msgstr "Filen \"%s\" innehåller ingen pseudonym.\n"
2904
2905#: src/applications/fs/ecrs/namespace.c:376
2906#, c-format
2907msgid "Format of pseudonym `%s' is invalid.\n"
2908msgstr "Formatet på pseudonym \"%s\" är ogiltig.\n"
2909
2910#: src/applications/fs/ecrs/namespace.c:535
2911#: src/applications/fs/ecrs/namespace.c:547
2912#: src/applications/fs/ecrs/namespace.c:559
2913#, fuzzy, c-format
2914msgid "Format of file `%s' is invalid, trying to remove.\n"
2915msgstr "Formatet på filen \"%s\" är ogiltig.\n"
2916
2917#: src/applications/fs/ecrs/download.c:599
2918msgid ""
2919"Decrypted content does not match key. This is either a bug or a maliciously "
2920"inserted file. Download aborted.\n"
2921msgstr ""
2922"Dekrypterat innehåll stämmer inte med nyckeln. Det är antingen ett fel eller "
2923"en fil inlagd med onda avsikter. Hämtning avbruten.\n"
2924
2925#: src/applications/fs/ecrs/download.c:609
2926msgid "IO error."
2927msgstr ""
2928
2929#: src/applications/fs/collection/collection.c:559
2930#: src/applications/fs/collection/collection.c:562
2931#, c-format
2932msgid "Revision %u"
2933msgstr ""
2934
2935#: src/applications/fs/fsui/upload.c:330
2936msgid "Application aborted."
2937msgstr ""
2938
2939#: src/applications/fs/fsui/upload.c:344
2940msgid "Failed to create temporary directory."
2941msgstr ""
2942
2943#: src/applications/fs/fsui/deserialize.c:927
2944#, c-format
2945msgid "FSUI state file `%s' had syntax error at offset %u.\n"
2946msgstr ""
2947
2948#: src/applications/fs/fsui/unindex.c:114
2949msgid "Unindexing failed (no reason given)"
2950msgstr ""
2951
2952#: src/applications/fs/gap/plan.c:944
2953msgid "# gap requests total sent"
2954msgstr ""
2955
2956#: src/applications/fs/gap/plan.c:946
2957msgid "# gap content total planned"
2958msgstr ""
2959
2960#: src/applications/fs/gap/plan.c:948
2961msgid "# gap routes succeeded"
2962msgstr ""
2963
2964#: src/applications/fs/gap/plan.c:949
2965msgid "# trust spent"
2966msgstr ""
2967
2968#: src/applications/fs/gap/fs.c:157
2969msgid "Datastore full.\n"
2970msgstr ""
2971
2972#: src/applications/fs/gap/fs.c:831
2973msgid "# gap requests total received"
2974msgstr ""
2975
2976#: src/applications/fs/gap/fs.c:833
2977msgid "# gap requests dropped due to load"
2978msgstr ""
2979
2980#: src/applications/fs/gap/fs.c:835
2981msgid "# gap content total received"
2982msgstr ""
2983
2984#: src/applications/fs/gap/fs.c:837
2985msgid "# gap total trust awarded"
2986msgstr ""
2987
2988#: src/applications/fs/gap/fs.c:865
2989#, fuzzy, c-format
2990msgid ""
2991"`%s' registering client handlers %d %d %d %d %d %d %d %d and P2P handlers %d "
2992"%d\n"
2993msgstr "\"%s\" registrerar klienthandtagen %d och %d\n"
2994
2995#: src/applications/fs/gap/fs.c:921
2996msgid "enables (anonymous) file-sharing"
2997msgstr "aktiverar (anonym) fildelning"
2998
2999#: src/applications/fs/gap/ondemand.c:173
3000#, c-format
3001msgid ""
3002"Because the file `%s' has been unavailable for 3 days it got removed from "
3003"your share. Please unindex files before deleting them as the index now "
3004"contains invalid references!\n"
3005msgstr ""
3006
3007#: src/applications/fs/gap/ondemand.c:451
3008msgid "Indexed content changed (does not match its hash).\n"
3009msgstr ""
3010
3011#: src/applications/fs/gap/ondemand.c:569
3012#, c-format
3013msgid ""
3014"Unindexed ODB block `%s' from offset %llu already missing from datastore.\n"
3015msgstr ""
3016
3017#: src/applications/fs/gap/pid_table.c:177
3018msgid "# distinct interned peer IDs in pid table"
3019msgstr ""
3020
3021#: src/applications/fs/gap/pid_table.c:180
3022msgid "# total RC of interned peer IDs in pid table"
3023msgstr ""
3024
3025#: src/applications/fs/gap/querymanager.c:708
3026#, fuzzy
3027msgid "# gap client queries received"
3028msgstr "# klartext PONG-meddelanden mottagna"
3029
3030#: src/applications/fs/gap/querymanager.c:710
3031msgid "# gap replies sent to clients"
3032msgstr ""
3033
3034#: src/applications/fs/gap/querymanager.c:712
3035msgid "# gap client requests tracked"
3036msgstr ""
3037
3038#: src/applications/fs/gap/querymanager.c:714
3039msgid "# gap client requests injected"
3040msgstr ""
3041
3042#: src/applications/fs/gap/querymanager.c:717
3043msgid "# gap query bloomfilter resizing updates"
3044msgstr ""
3045
3046#: src/applications/fs/gap/migration.c:437
3047msgid "# blocks migrated"
3048msgstr ""
3049
3050#: src/applications/fs/gap/migration.c:439
3051msgid "# blocks injected for migration"
3052msgstr ""
3053
3054#: src/applications/fs/gap/migration.c:441
3055msgid "# blocks fetched for migration"
3056msgstr ""
3057
3058#: src/applications/fs/gap/migration.c:443
3059msgid "# on-demand fetches for migration"
3060msgstr ""
3061
3062#: src/applications/fs/gap/gap.c:694
3063msgid "# gap queries dropped (table full)"
3064msgstr ""
3065
3066#: src/applications/fs/gap/gap.c:696
3067msgid "# gap queries dropped (redundant)"
3068msgstr ""
3069
3070#: src/applications/fs/gap/gap.c:698
3071msgid "# gap queries routed"
3072msgstr ""
3073
3074#: src/applications/fs/gap/gap.c:700
3075msgid "# gap content found locally"
3076msgstr ""
3077
3078#: src/applications/fs/gap/gap.c:703
3079msgid "# gap queries refreshed existing record"
3080msgstr ""
3081
3082#: src/applications/fs/gap/gap.c:704
3083msgid "# trust earned"
3084msgstr ""
3085
3086#: src/applications/fs/gap/fs_dht.c:256
3087msgid "# blocks pushed into DHT"
3088msgstr ""
3089
3090#: src/applications/fs/gap/anonymity.c:56
3091msgid "Failed to get traffic stats.\n"
3092msgstr ""
3093
3094#: src/applications/testing/remote.c:68
3095#, c-format
3096msgid "scp command is : %s \n"
3097msgstr ""
3098
3099#: src/applications/testing/remote.c:491
3100#, fuzzy, c-format
3101msgid "Friend list of %s:%d\n"
3102msgstr "Fel vid %s:%d.\n"
3103
3104#: src/applications/testing/remote.c:513
3105#, c-format
3106msgid "scp command for friend file copy is : %s \n"
3107msgstr ""
3108
3109#: src/applications/testing/remote.c:535
3110#, c-format
3111msgid "connecting peer %s:%d to peer %s:%d\n"
3112msgstr ""
3113
3114#: src/applications/testing/remotetest.c:38
3115msgid "Set up multiple gnunetd daemons across multiple hosts."
3116msgstr ""
3117
3118#: src/applications/testing/remotetest.c:43
3119#, fuzzy
3120msgid "set number of daemons to start"
3121msgstr "antal meddelanden att använda per iteration"
3122
3123#: src/applications/testing/testing.c:268
3124#: src/applications/testing/remotetopologies.c:367
3125#, fuzzy, c-format
3126msgid "Waiting for peers to connect"
3127msgstr "Väntar på att motparter ska ansluta (%u iterationer kvar)...\n"
3128
3129#: src/applications/testing/remotetopologies.c:213
3130#, c-format
3131msgid "Connecting nodes in 2d torus topology: %u rows %u columns\n"
3132msgstr ""
3133
3134#: src/applications/testing/remotetopologies.c:491
3135#, fuzzy, c-format
3136msgid "Failed to establish connection with peers.\n"
3137msgstr "Misslyckades att starta samling.\n"
3138
3139#: src/applications/bootstrap_http/http.c:113
3140#, fuzzy, c-format
3141msgid "Bootstrap data obtained from `%s' is invalid.\n"
3142msgstr "Formatet på pseudonym \"%s\" är ogiltig.\n"
3143
3144#: src/applications/bootstrap_http/http.c:126
3145#: src/applications/bootstrap_http/http.c:277
3146#: src/applications/bootstrap_http/http.c:294
3147#: src/applications/bootstrap_http/http.c:333
3148#: src/applications/bootstrap_http/http.c:352
3149#: src/applications/bootstrap_http/http.c:365
3150#: src/applications/bootstrap_http/http.c:375
3151#: src/applications/bootstrap_http/http.c:385 src/transports/upnp/upnp.c:356
3152#: src/transports/upnp/upnp.c:541 src/transports/http.c:1085
3153#: src/transports/http.c:1209 src/transports/http.c:1377
3154#: src/transports/http.c:1777 src/transports/http.c:1827
3155#, fuzzy, c-format
3156msgid "%s failed at %s:%d: `%s'\n"
3157msgstr "\"%s\" misslyckades vid %s:%d med fel: \"%s\".\n"
3158
3159#: src/applications/bootstrap_http/http.c:185
3160msgid "No hostlist URL specified in configuration, will not bootstrap.\n"
3161msgstr ""
3162
3163#: src/applications/bootstrap_http/http.c:226
3164#, c-format
3165msgid "Bootstrapping using `%s'.\n"
3166msgstr ""
3167
3168#: src/applications/bootstrap_http/http.c:254
3169#, fuzzy, c-format
3170msgid "Trying to download hostlist from `%s'\n"
3171msgstr "Misslyckades att läsa kompislista från \"%s\"\n"
3172
3173#: src/applications/bootstrap_http/http.c:391
3174#, fuzzy, c-format
3175msgid "Downloaded %llu bytes from `%s'.\n"
3176msgstr "Ladda ner filer från GNUnet."
3177
3178#: src/applications/bootstrap_http/http.c:425
3179msgid "# HELLOs downloaded via http"
3180msgstr ""
3181
3182#: src/applications/getoption/getoption.c:78
3183#, c-format
3184msgid "`%s' registering client handler %d\n"
3185msgstr "\"%s\" registrerar klienthandtag %d\n"
3186
3187#: src/applications/getoption/getoption.c:88
3188msgid "allows clients to determine gnunetd's configuration"
3189msgstr "tillåter klienter att fastställa gnunetds konfiguration"
3190
3191#: src/applications/template/template.c:70
3192#, c-format
3193msgid "`%s' registering client handler %d and %d\n"
3194msgstr "\"%s\" registrerar klienthandtagen %d och %d\n"
3195
3196#: src/applications/template/gnunet-template.c:42
3197msgid "Template description."
3198msgstr ""
3199
3200#: src/applications/stats/clientapi.c:331
3201msgid "Uptime (seconds)"
3202msgstr "Upptid (sekunder)"
3203
3204#: src/applications/stats/sqstats.c:151
3205msgid "# Any-Blocks"
3206msgstr ""
3207
3208#: src/applications/stats/sqstats.c:152
3209msgid "# DBlocks"
3210msgstr ""
3211
3212#: src/applications/stats/sqstats.c:153
3213msgid "# SBlocks"
3214msgstr ""
3215
3216#: src/applications/stats/sqstats.c:154
3217msgid "# KBlocks"
3218msgstr ""
3219
3220#: src/applications/stats/sqstats.c:155
3221msgid "# NBlocks"
3222msgstr ""
3223
3224#: src/applications/stats/sqstats.c:156
3225msgid "# KNBlocks"
3226msgstr ""
3227
3228#: src/applications/stats/sqstats.c:157
3229msgid "# OnDemand-Blocks"
3230msgstr ""
3231
3232#: src/applications/stats/sqstats.c:158
3233msgid "# Unknown-Blocks"
3234msgstr ""
3235
3236#: src/applications/stats/sqstats.c:159
3237msgid "# expired"
3238msgstr ""
3239
3240#: src/applications/stats/sqstats.c:160
3241msgid "# expire in 1h"
3242msgstr ""
3243
3244#: src/applications/stats/sqstats.c:161
3245msgid "# expire in 24h"
3246msgstr ""
3247
3248#: src/applications/stats/sqstats.c:162
3249msgid "# expire in 1 week"
3250msgstr ""
3251
3252#: src/applications/stats/sqstats.c:163
3253msgid "# expire in 1 month"
3254msgstr ""
3255
3256#: src/applications/stats/sqstats.c:164
3257msgid "# zero priority"
3258msgstr ""
3259
3260#: src/applications/stats/sqstats.c:165
3261msgid "# priority one"
3262msgstr ""
3263
3264#: src/applications/stats/sqstats.c:166
3265msgid "# priority larger than one"
3266msgstr ""
3267
3268#: src/applications/stats/sqstats.c:167
3269msgid "# no anonymity"
3270msgstr ""
3271
3272#: src/applications/stats/sqstats.c:168
3273msgid "# anonymity one"
3274msgstr ""
3275
3276#: src/applications/stats/sqstats.c:169
3277msgid "# anonymity larger than one"
3278msgstr ""
3279
3280#: src/applications/stats/statistics.c:238
3281#, no-c-format
3282msgid "% of allowed network load (up)"
3283msgstr ""
3284
3285#: src/applications/stats/statistics.c:240
3286#, no-c-format
3287msgid "% of allowed network load (down)"
3288msgstr ""
3289
3290#: src/applications/stats/statistics.c:243
3291#, no-c-format
3292msgid "% of allowed cpu load"
3293msgstr ""
3294
3295#: src/applications/stats/statistics.c:246
3296#, no-c-format
3297msgid "% of allowed io load"
3298msgstr ""
3299
3300#: src/applications/stats/statistics.c:249
3301msgid "# bytes of noise received"
3302msgstr ""
3303
3304#: src/applications/stats/statistics.c:251
3305msgid "# plibc handles"
3306msgstr ""
3307
3308#: src/applications/stats/statistics.c:441
3309#, fuzzy, c-format
3310msgid "`%s' registering client handlers %d %d %d and p2p handler %d\n"
3311msgstr "\"%s\" registrerar klienthandtagen %d och %d\n"
3312
3313#: src/applications/stats/statistics.c:463
3314msgid "keeps statistics about gnunetd's operation"
3315msgstr "behåller statistik om gnunetds operation"
3316
3317#: src/applications/stats/gnunet-stats.c:61
3318#, c-format
3319msgid "Supported peer-to-peer messages:\n"
3320msgstr ""
3321
3322#: src/applications/stats/gnunet-stats.c:64
3323#, c-format
3324msgid "Supported client-server messages:\n"
3325msgstr ""
3326
3327#: src/applications/stats/gnunet-stats.c:83
3328#: src/applications/vpn/gnunet-vpn.c:59
3329msgid "Print statistics about GNUnet operations."
3330msgstr "Skriv ut statistik om GNUnet-operationer."
3331
3332#: src/applications/stats/gnunet-stats.c:87
3333msgid "prints supported protocol messages"
3334msgstr "skriver ut stödda protokollmeddelanden"
3335
3336#: src/applications/stats/gnunet-stats.c:136
3337#, c-format
3338msgid "Error reading information from gnunetd.\n"
3339msgstr ""
3340
3341#: src/applications/vpn/gnunet-vpn.c:63
3342msgid "Suppress display of asynchronous log messages"
3343msgstr ""
3344
3345#: src/applications/vpn/p2p.c:75
3346msgid "VPN IP src not anonymous. drop..\n"
3347msgstr ""
3348
3349#: src/applications/vpn/p2p.c:83
3350msgid "VPN IP not anonymous, drop.\n"
3351msgstr ""
3352
3353#: src/applications/vpn/p2p.c:92
3354msgid "VPN Received, not anonymous, drop.\n"
3355msgstr ""
3356
3357#: src/applications/vpn/p2p.c:97
3358#, c-format
3359msgid "VPN Received unknown IP version %d...\n"
3360msgstr ""
3361
3362#: src/applications/vpn/p2p.c:110
3363#, c-format
3364msgid "<- GNUnet(%d) : %s\n"
3365msgstr ""
3366
3367#: src/applications/vpn/p2p.c:139
3368msgid "Could not write the tunnelled IP to the OS... Did to setup a tunnel?\n"
3369msgstr ""
3370
3371#: src/applications/vpn/p2p.c:183
3372msgid "Receive route request\n"
3373msgstr ""
3374
3375#: src/applications/vpn/p2p.c:193
3376#, c-format
3377msgid "Prepare route announcement level %d\n"
3378msgstr ""
3379
3380#: src/applications/vpn/p2p.c:208
3381#, c-format
3382msgid "Send route announcement %d with route announce\n"
3383msgstr ""
3384
3385#: src/applications/vpn/p2p.c:217
3386#, c-format
3387msgid "Send outside table info %d\n"
3388msgstr ""
3389
3390#: src/applications/vpn/p2p.c:239
3391msgid "Receive route announce.\n"
3392msgstr ""
3393
3394#: src/applications/vpn/p2p.c:247
3395msgid "Going to try insert route into local table.\n"
3396msgstr ""
3397
3398#: src/applications/vpn/p2p.c:256
3399#, c-format
3400msgid "Inserting with hops %d\n"
3401msgstr ""
3402
3403#: src/applications/vpn/p2p.c:273
3404#, c-format
3405msgid "Request level %d from peer %d\n"
3406msgstr ""
3407
3408#: src/applications/vpn/p2p.c:300
3409#, c-format
3410msgid "Receive table limit on peer reached %d\n"
3411msgstr ""
3412
3413#: src/applications/vpn/vpn.c:180
3414#, c-format
3415msgid "Not storing route to myself from peer %d\n"
3416msgstr ""
3417
3418#: src/applications/vpn/vpn.c:194
3419#, c-format
3420msgid "Duplicate route to node from peer %d, choosing minimum hops"
3421msgstr ""
3422
3423#: src/applications/vpn/vpn.c:230
3424#, c-format
3425msgid "Inserting route from peer %d in route table at location %d\n"
3426msgstr ""
3427
3428#: src/applications/vpn/vpn.c:247
3429#, c-format
3430msgid "RFC4193 Frame length %d is too big for GNUnet!\n"
3431msgstr ""
3432
3433#: src/applications/vpn/vpn.c:254
3434#, c-format
3435msgid "RFC4193 Frame length %d too small\n"
3436msgstr ""
3437
3438#: src/applications/vpn/vpn.c:273
3439#, c-format
3440msgid "RFC4193 Ethertype %x and IP version %x do not match!\n"
3441msgstr ""
3442
3443#: src/applications/vpn/vpn.c:289
3444#, c-format
3445msgid "RFC4193 Going to try and make a tunnel in slot %d\n"
3446msgstr ""
3447
3448#: src/applications/vpn/vpn.c:295
3449#, fuzzy, c-format
3450msgid "Cannot open tunnel device: %s"
3451msgstr "Kan inte öppna konfigurationsfil \"%s\".\n"
3452
3453#: src/applications/vpn/vpn.c:331
3454#, c-format
3455msgid "RFC4193 Create skips gnu%d as we are already using it\n"
3456msgstr ""
3457
3458#: src/applications/vpn/vpn.c:346
3459#, c-format
3460msgid "Cannot set tunnel name to %s because of %s\n"
3461msgstr ""
3462
3463#: src/applications/vpn/vpn.c:356
3464#, c-format
3465msgid "Configured tunnel name to %s\n"
3466msgstr ""
3467
3468#: src/applications/vpn/vpn.c:398
3469#, c-format
3470msgid "Cannot get socket flags for gnu%d because %s\n"
3471msgstr ""
3472
3473#: src/applications/vpn/vpn.c:408
3474#, c-format
3475msgid "Cannot set socket flags for gnu%d because %s\n"
3476msgstr ""
3477
3478#: src/applications/vpn/vpn.c:418
3479#, c-format
3480msgid "Cannot set MTU for gnu%d because %s\n"
3481msgstr ""
3482
3483#: src/applications/vpn/vpn.c:426
3484#, c-format
3485msgid "Cannot get interface index for gnu%d because %s\n"
3486msgstr ""
3487
3488#: src/applications/vpn/vpn.c:440
3489#, c-format
3490msgid "IPv6 ifaddr gnu%d - %x:%x:%x:%x:%x:%x:%x:%x/%d\n"
3491msgstr ""
3492
3493#: src/applications/vpn/vpn.c:455
3494#, c-format
3495msgid "Cannot set interface IPv6 address for gnu%d because %s\n"
3496msgstr ""
3497
3498#: src/applications/vpn/vpn.c:471
3499#, c-format
3500msgid "IPv6 route gnu%d - destination %x:%x:%x:%x:%x:%x:%x:%x/%d\n"
3501msgstr ""
3502
3503#: src/applications/vpn/vpn.c:485
3504#, c-format
3505msgid "Cannot add route IPv6 address for gnu%s because %s\n"
3506msgstr ""
3507
3508#: src/applications/vpn/vpn.c:528
3509msgid ""
3510"RFC4193 We have run out of memory and so I can't store a tunnel for this "
3511"peer.\n"
3512msgstr ""
3513
3514#: src/applications/vpn/vpn.c:579
3515#, c-format
3516msgid "RFC4193 Thread running (frame %d tunnel %d f2f %d) ...\n"
3517msgstr ""
3518
3519#: src/applications/vpn/vpn.c:661
3520#, c-format
3521msgid "VPN dropping connection %x\n"
3522msgstr ""
3523
3524#: src/applications/vpn/vpn.c:670
3525#, c-format
3526msgid "VPN cannot drop connection %x\n"
3527msgstr ""
3528
3529#: src/applications/vpn/vpn.c:690
3530msgid "RFC4193 Thread exiting\n"
3531msgstr ""
3532
3533#: src/applications/vpn/vpn.c:712
3534msgid "realise alloc ram\n"
3535msgstr ""
3536
3537#: src/applications/vpn/vpn.c:735
3538msgid "realise add routes\n"
3539msgstr ""
3540
3541#: src/applications/vpn/vpn.c:849
3542msgid "realise copy table\n"
3543msgstr ""
3544
3545#: src/applications/vpn/vpn.c:898
3546#, fuzzy, c-format
3547msgid "`%s' initialising RFC4913 module %d and %d\n"
3548msgstr "\"%s\" registrerar handtagen %d och %d\n"
3549
3550#: src/applications/vpn/vpn.c:903
3551#, c-format
3552msgid "RFC4193 my First 4 hex digits of host id are %x\n"
3553msgstr ""
3554
3555#: src/applications/vpn/vpn.c:942
3556#, fuzzy
3557msgid "enables IPv6 over GNUnet (incomplete)"
3558msgstr "aktiverar P2P-chatt (ej komplett)"
3559
3560#: src/applications/vpn/vpn.c:963
3561msgid "RFC4193 Waiting for tun thread to end\n"
3562msgstr ""
3563
3564#: src/applications/vpn/vpn.c:978
3565msgid "RFC4193 The tun thread has ended\n"
3566msgstr ""
3567
3568#: src/applications/vpn/vpn.c:996
3569#, c-format
3570msgid "RFC4193 Closing tunnel %d fd %d\n"
3571msgstr ""
3572
3573#: src/server/core.c:119 src/server/core.c:318
3574#, c-format
3575msgid "Configuration value `%s' under [MODULES] for `%s' is invalid!\n"
3576msgstr ""
3577
3578#: src/server/core.c:140
3579#, c-format
3580msgid "Application module `%s' already initialized!\n"
3581msgstr ""
3582
3583#: src/server/core.c:194
3584#, c-format
3585msgid "Failed to load plugin `%s' at %s:%d. Unloading plugin.\n"
3586msgstr ""
3587
3588#: src/server/core.c:244
3589#, c-format
3590msgid "Could not shutdown `%s': application not loaded\n"
3591msgstr ""
3592
3593#: src/server/core.c:255
3594#, c-format
3595msgid "Could not shutdown application `%s': not initialized\n"
3596msgstr ""
3597
3598#: src/server/core.c:265
3599#, c-format
3600msgid "Could not find '%s%s' method in library `%s'.\n"
3601msgstr ""
3602
3603#: src/server/core.c:422
3604#, c-format
3605msgid "Could not release %p: service not loaded\n"
3606msgstr ""
3607
3608#: src/server/core.c:531
3609#, c-format
3610msgid "Could not properly shutdown application `%s'.\n"
3611msgstr ""
3612
3613#: src/server/core.c:676
3614#, c-format
3615msgid "Could not properly unload service `%s'!\n"
3616msgstr ""
3617
3618#: src/server/gnunet-update.c:146
3619#, c-format
3620msgid "Updating data for module `%s'\n"
3621msgstr "Uppdaterar data för modul \"%s\"\n"
3622
3623#: src/server/gnunet-update.c:151
3624#, c-format
3625msgid "Failed to update data for module `%s'\n"
3626msgstr ""
3627
3628#: src/server/gnunet-update.c:225 src/server/gnunetd.c:124
3629#, fuzzy
3630msgid "Core initialization failed.\n"
3631msgstr " Anslutning misslyckades\n"
3632
3633#: src/server/gnunet-update.c:270
3634msgid "Updates GNUnet datastructures after version change."
3635msgstr "Uppdaterar GNUnets datastruktur efter versionsändring."
3636
3637#: src/server/gnunet-update.c:274 src/server/gnunet-transport-check.c:376
3638msgid "run as user LOGIN"
3639msgstr "kör som användare LOGIN"
3640
3641#: src/server/gnunet-update.c:278
3642msgid "run in client mode (for getting client configuration values)"
3643msgstr "kör i klientläge (för att hämta värden från klientkonfiguration)"
3644
3645#: src/server/version.c:125
3646msgid ""
3647"Failed to determine filename used to store GNUnet version information!\n"
3648msgstr ""
3649
3650#: src/server/gnunetd.c:85
3651#, c-format
3652msgid "`%s' startup complete.\n"
3653msgstr "\"%s\" uppstart klar.\n"
3654
3655#: src/server/gnunetd.c:89
3656#, c-format
3657msgid "`%s' is shutting down.\n"
3658msgstr ""
3659
3660#: src/server/gnunetd.c:179
3661msgid ""
3662"run in debug mode; gnunetd will not daemonize and error messages will be "
3663"written to stderr instead of a logfile"
3664msgstr ""
3665
3666#: src/server/gnunetd.c:183
3667msgid "Starts the gnunetd daemon."
3668msgstr "Startar gnunetd-demonen."
3669
3670#: src/server/gnunetd.c:186
3671msgid "disable padding with random data (experimental)"
3672msgstr ""
3673
3674#: src/server/gnunetd.c:190
3675msgid "print all log messages to the console (only works together with -d)"
3676msgstr ""
3677
3678#: src/server/gnunetd.c:194
3679#, fuzzy
3680msgid "specify username as which gnunetd should run"
3681msgstr "ange värd på vilken gnunetd körs"
3682
3683#: src/server/gnunetd.c:275
3684#, c-format
3685msgid "Configuration or GNUnet version changed. You need to run `%s'!\n"
3686msgstr ""
3687"Konfiguration eller version av GNUnet ändrad. Du behöver köra \"%s\"!\n"
3688
3689#: src/server/tcpserver.c:121
3690#, c-format
3691msgid "The `%s' request received from client is malformed.\n"
3692msgstr ""
3693
3694#: src/server/tcpserver.c:409
3695#, fuzzy, c-format
3696msgid "`%s' failed for port %d. Is gnunetd already running?\n"
3697msgstr "\"%s\" misslyckades för port %d: %s. Körs verkligen gnunetd?\n"
3698
3699#: src/server/tcpserver.c:487 src/server/tcpserver.c:512
3700#, c-format
3701msgid ""
3702"Malformed network specification in the configuration in section `%s' for "
3703"entry `%s': %s\n"
3704msgstr ""
3705
3706#: src/server/tcpserver.c:572
3707#, c-format
3708msgid "Registering failed, message type %d already in use.\n"
3709msgstr ""
3710
3711#: src/server/startup.c:219
3712#, fuzzy, c-format
3713msgid "Unable to obtain filesystem information for `%s': %u\n"
3714msgstr "Kunde inte spara konfigurationsfil \"%s\":"
3715
3716#: src/server/startup.c:237
3717#, c-format
3718msgid ""
3719"Filesystem `%s' of partition `%s' is unknown. Please contact gnunet-"
3720"developers@gnu.org!"
3721msgstr ""
3722
3723#: src/server/startup.c:252
3724#, c-format
3725msgid ""
3726"Limiting datastore size to %llu GB, because the `%s' filesystem does not "
3727"support larger files. Please consider storing the database on a NTFS "
3728"partition!\n"
3729msgstr ""
3730
3731#: src/server/startup.c:291
3732#, c-format
3733msgid "Insufficient access permissions for `%s': %s\n"
3734msgstr ""
3735
3736#: src/server/gnunet-peer-info.c:55
3737msgid "Print information about GNUnet peers."
3738msgstr "Skriv ut information om GNUnets motparter."
3739
3740#: src/server/gnunet-peer-info.c:59
3741msgid "don't resolve host names"
3742msgstr ""
3743
3744#: src/server/gnunet-peer-info.c:62
3745msgid "output only the identity strings"
3746msgstr ""
3747
3748#: src/server/gnunet-peer-info.c:65
3749msgid "output our own identity only"
3750msgstr ""
3751
3752#: src/server/gnunet-peer-info.c:130 src/server/gnunet-peer-info.c:164
3753#, c-format
3754msgid "Could not get address of peer `%s'.\n"
3755msgstr ""
3756
3757#: src/server/gnunet-peer-info.c:143
3758#, fuzzy, c-format
3759msgid "`%s' message invalid (signature invalid).\n"
3760msgstr "\"%s\" misslyckades, svar ogiltigt!\n"
3761
3762#: src/server/gnunet-peer-info.c:168
3763#, fuzzy, c-format
3764msgid "Peer `%s' with trust %8u\n"
3765msgstr "Motpart \"%s\" med pålitlighet %8u och adress \"%s\"\n"
3766
3767#: src/server/gnunet-peer-info.c:175
3768#, c-format
3769msgid "Peer `%s' with trust %8u and address `%s'\n"
3770msgstr "Motpart \"%s\" med pålitlighet %8u och adress \"%s\"\n"
3771
3772#: src/server/connection.c:1313
3773#, c-format
3774msgid "`%s' selected %d out of %d messages (MTU: %d).\n"
3775msgstr "\"%s\" valda %d av %d meddelanden (MTU: %d).\n"
3776
3777#: src/server/connection.c:1323
3778#, c-format
3779msgid "Message details: %u: length %d, priority: %d\n"
3780msgstr "Detaljer om meddelande: %u: längd %d, prioritet: %d\n"
3781
3782#: src/server/connection.c:3129
3783#, c-format
3784msgid "Message from `%s' discarded: invalid format.\n"
3785msgstr "Meddelande från \"%s\" kastades bort: ogiltigt format.\n"
3786
3787#: src/server/connection.c:3218
3788#, c-format
3789msgid "Invalid sequence number %u <= %u, dropping message.\n"
3790msgstr ""
3791
3792#: src/server/connection.c:3240
3793msgid "Message received more than one day old. Dropped.\n"
3794msgstr ""
3795
3796#: src/server/connection.c:3763
3797msgid "# outgoing messages dropped"
3798msgstr ""
3799
3800#: src/server/connection.c:3766
3801msgid "# bytes of outgoing messages dropped"
3802msgstr ""
3803
3804#: src/server/connection.c:3768
3805msgid "# connections closed (HANGUP sent)"
3806msgstr ""
3807
3808#: src/server/connection.c:3772
3809msgid "# connections closed (transport issue)"
3810msgstr ""
3811
3812#: src/server/connection.c:3775
3813msgid "# bytes encrypted"
3814msgstr "# byte krypterade"
3815
3816#: src/server/connection.c:3779
3817#, fuzzy
3818msgid "# bytes transmitted"
3819msgstr "# byte skickade av typen %d"
3820
3821#: src/server/connection.c:3783
3822#, fuzzy
3823msgid "# bytes received"
3824msgstr "# byte mottogs via TCP"
3825
3826#: src/server/connection.c:3785
3827msgid "# bytes decrypted"
3828msgstr "# byte dekrypterade"
3829
3830#: src/server/connection.c:3786
3831msgid "# bytes noise sent"
3832msgstr ""
3833
3834#: src/server/connection.c:3789
3835msgid "# total bytes per second send limit"
3836msgstr ""
3837
3838#: src/server/connection.c:3792
3839msgid "# total bytes per second receive limit"
3840msgstr ""
3841
3842#: src/server/connection.c:3795
3843#, fuzzy
3844msgid "# total number of messages in send buffers"
3845msgstr "antal meddelanden i ett meddelandeblock"
3846
3847#: src/server/connection.c:3798
3848msgid "# total number of bytes we were allowed to send but did not"
3849msgstr ""
3850
3851#: src/server/connection.c:3801
3852msgid "# total number of bytes we were allowed to sent"
3853msgstr ""
3854
3855#: src/server/connection.c:3804
3856msgid "# total number of bytes we are currently allowed to send"
3857msgstr ""
3858
3859#: src/server/connection.c:3807
3860msgid "# transports switched to stream transport"
3861msgstr ""
3862
3863#: src/server/connection.c:3810
3864msgid "# average connection lifetime (in ms)"
3865msgstr ""
3866
3867#: src/server/connection.c:3813
3868msgid "# conn. shutdown: other peer sent too much"
3869msgstr ""
3870
3871#: src/server/connection.c:3816
3872msgid "# conn. shutdown: we lacked bandwidth"
3873msgstr ""
3874
3875#: src/server/connection.c:3819
3876msgid "# conn. shutdown: other peer timed out"
3877msgstr ""
3878
3879#: src/server/connection.c:3822
3880msgid "# conn. shutdown: timed out during connect"
3881msgstr ""
3882
3883#: src/server/connection.c:3825
3884msgid "# conn. shutdown: other peer requested it"
3885msgstr ""
3886
3887#: src/server/handler.c:442
3888#, fuzzy, c-format
3889msgid "Received corrupt message from peer `%s' in %s:%d.\n"
3890msgstr "Mottog skadat meddelande från motpart \"%s\"i %s:%d.\n"
3891
3892#: src/server/gnunet-transport-check.c:121
3893#, c-format
3894msgid "`%s': Could not create hello.\n"
3895msgstr ""
3896
3897#: src/server/gnunet-transport-check.c:129
3898#, c-format
3899msgid "`%s': Could not connect.\n"
3900msgstr "\"%s\": Kunde inte ansluta.\n"
3901
3902#: src/server/gnunet-transport-check.c:163
3903#, c-format
3904msgid "`%s': Could not send.\n"
3905msgstr "\"%s\": Kunde inte skicka.\n"
3906
3907#: src/server/gnunet-transport-check.c:179
3908#, c-format
3909msgid "`%s': Did not receive message within %llu ms.\n"
3910msgstr "\"%s\": Mottog inte meddelande inom %llu ms.\n"
3911
3912#: src/server/gnunet-transport-check.c:192
3913#, c-format
3914msgid "`%s': Could not disconnect.\n"
3915msgstr "\"%s\": Kunde inte koppla ned.\n"
3916
3917#: src/server/gnunet-transport-check.c:200
3918#, fuzzy, c-format
3919msgid ""
3920"`%s' transport OK. It took %ums to transmit %llu messages of %llu bytes "
3921"each.\n"
3922msgstr ""
3923"\"%s\" transport OK. Det tog %ums att överföra %d meddelanden på %d byte "
3924"styck.\n"
3925
3926#: src/server/gnunet-transport-check.c:231
3927#, fuzzy, c-format
3928msgid " Transport %d is not being tested\n"
3929msgstr " Transport %d ej tillgänglig\n"
3930
3931#: src/server/gnunet-transport-check.c:261
3932#, c-format
3933msgid ""
3934"\n"
3935"Contacting `%s'."
3936msgstr ""
3937"\n"
3938"Kontaktar \"%s\"."
3939
3940#: src/server/gnunet-transport-check.c:286
3941#, c-format
3942msgid " Connection failed\n"
3943msgstr " Anslutning misslyckades\n"
3944
3945#: src/server/gnunet-transport-check.c:292
3946#, c-format
3947msgid " Connection failed (bug?)\n"
3948msgstr " Anslutning misslyckades (fel?)\n"
3949
3950#: src/server/gnunet-transport-check.c:330
3951#, c-format
3952msgid "Timeout after %llums.\n"
3953msgstr ""
3954
3955#: src/server/gnunet-transport-check.c:332
3956#, fuzzy, c-format
3957msgid "OK!\n"
3958msgstr "OK"
3959
3960#: src/server/gnunet-transport-check.c:357
3961msgid "Tool to test if GNUnet transport services are operational."
3962msgstr ""
3963
3964#: src/server/gnunet-transport-check.c:361
3965msgid "ping peers from HOSTLISTURL that match transports"
3966msgstr ""
3967
3968#: src/server/gnunet-transport-check.c:364
3969msgid "send COUNT messages"
3970msgstr "skicka ANTAL meddelanden"
3971
3972#: src/server/gnunet-transport-check.c:367
3973msgid "send messages with SIZE bytes payload"
3974msgstr "skicka meddelanden med STORLEK bytes nyttolast"
3975
3976#: src/server/gnunet-transport-check.c:370
3977msgid "specifies which TRANSPORT should be tested"
3978msgstr "anger vilken TRANSPORT som ska testas"
3979
3980#: src/server/gnunet-transport-check.c:373
3981msgid "specifies after how many MS to time-out"
3982msgstr "anger timeout efter antal MS"
3983
3984#: src/server/gnunet-transport-check.c:381
3985msgid "repeat each test X times"
3986msgstr ""
3987
3988#: src/server/gnunet-transport-check.c:449
3989#, c-format
3990msgid "Testing transport(s) %s\n"
3991msgstr "Testar transport(er) %s\n"
3992
3993#: src/server/gnunet-transport-check.c:451
3994#, c-format
3995msgid "Available transport(s): %s\n"
3996msgstr "Tillgängliga transport(er): %s\n"
3997
3998#: src/server/gnunet-transport-check.c:501
3999#, c-format
4000msgid ""
4001"\n"
4002"%d out of %d peers contacted successfully (%d times transport unavailable).\n"
4003msgstr ""
4004
4005#: src/transports/common.c:370
4006#, c-format
4007msgid "Port is 0, will only send using %s.\n"
4008msgstr ""
4009
4010#: src/transports/smtp.c:367 src/transports/udp.c:107 src/transports/tcp.c:271
4011#: src/transports/tcp.c:291
4012#, fuzzy, c-format
4013msgid "Received malformed message via %s. Ignored.\n"
4014msgstr "Mottog ogiltigt \"%s\" meddelande från \"%s\".\n"
4015
4016# capped är inte ett bra ord IMHO
4017#: src/transports/smtp.c:459
4018#, fuzzy
4019msgid "SMTP filter string to invalid, lacks ': '\n"
4020msgstr "SMTP-filtersträng för lång, kapad till \"%s\"\n"
4021
4022# capped är inte ett bra ord IMHO
4023#: src/transports/smtp.c:469
4024#, c-format
4025msgid "SMTP filter string to long, capped to `%s'\n"
4026msgstr "SMTP-filtersträng för lång, kapad till \"%s\"\n"
4027
4028#: src/transports/smtp.c:564 src/transports/smtp.c:575
4029#: src/transports/smtp.c:589 src/transports/smtp.c:609
4030#: src/transports/smtp.c:634 src/transports/smtp.c:643
4031#: src/transports/smtp.c:657 src/transports/smtp.c:669
4032#, fuzzy, c-format
4033msgid "SMTP: `%s' failed: %s.\n"
4034msgstr "\"%s\" %s misslyckades: %s\n"
4035
4036#: src/transports/smtp.c:814
4037msgid "No email-address specified, can not start SMTP transport.\n"
4038msgstr ""
4039
4040#: src/transports/smtp.c:831
4041#, fuzzy
4042msgid "# bytes received via SMTP"
4043msgstr "# byte mottogs via TCP"
4044
4045#: src/transports/smtp.c:832
4046#, fuzzy
4047msgid "# bytes sent via SMTP"
4048msgstr "# byte skickades via TCP"
4049
4050#: src/transports/smtp.c:834
4051#, fuzzy
4052msgid "# bytes dropped by SMTP (outgoing)"
4053msgstr "# byte kastade via TCP (utgående)"
4054
4055#: src/transports/upnp/upnp.c:431
4056#, fuzzy, c-format
4057msgid "%s failed for url `%s' and post-data `%s' at %s:%d: `%s'\n"
4058msgstr "\"%s\" misslyckades för fil \"%s\" vid %s:%d med fel: %s\n"
4059
4060#: src/transports/upnp/upnp.c:476
4061#, c-format
4062msgid "upnp: NAT Returned IP: %s\n"
4063msgstr ""
4064
4065#: src/transports/http.c:2019 src/transports/tcp.c:811
4066#, c-format
4067msgid ""
4068"The UPnP service could not be loaded. To disable UPnP, set the configuration "
4069"option \"UPNP\" in section \"%s\" to \"NO\"\n"
4070msgstr ""
4071
4072#: src/transports/http.c:2028
4073msgid "# bytes received via HTTP"
4074msgstr "# byte mottagna via HTTP"
4075
4076#: src/transports/http.c:2029
4077msgid "# bytes sent via HTTP"
4078msgstr "# byte skickade via HTTP"
4079
4080#: src/transports/http.c:2031
4081msgid "# bytes dropped by HTTP (outgoing)"
4082msgstr "# byte kastade via HTTP (utgående)"
4083
4084#: src/transports/http.c:2032
4085msgid "# HTTP GET issued"
4086msgstr ""
4087
4088#: src/transports/http.c:2034
4089msgid "# HTTP GET received"
4090msgstr ""
4091
4092#: src/transports/http.c:2035
4093msgid "# HTTP PUT issued"
4094msgstr ""
4095
4096#: src/transports/http.c:2037
4097msgid "# HTTP PUT received"
4098msgstr ""
4099
4100#: src/transports/http.c:2039
4101msgid "# HTTP select calls"
4102msgstr ""
4103
4104#: src/transports/http.c:2041
4105msgid "# HTTP send calls"
4106msgstr ""
4107
4108#: src/transports/http.c:2044
4109msgid "# HTTP curl send callbacks"
4110msgstr ""
4111
4112#: src/transports/http.c:2046
4113msgid "# HTTP curl receive callbacks"
4114msgstr ""
4115
4116#: src/transports/http.c:2048
4117msgid "# HTTP mhd access callbacks"
4118msgstr ""
4119
4120#: src/transports/http.c:2050
4121msgid "# HTTP mhd read callbacks"
4122msgstr ""
4123
4124#: src/transports/http.c:2052
4125msgid "# HTTP mhd close callbacks"
4126msgstr ""
4127
4128#: src/transports/http.c:2054
4129#, fuzzy
4130msgid "# HTTP connect calls"
4131msgstr "# av anslutna parter"
4132
4133#: src/transports/ip.c:70 src/transports/ip.c:365
4134#, c-format
4135msgid "Failed to obtain my (external) %s address!\n"
4136msgstr ""
4137
4138#: src/transports/udp.c:472 src/transports/tcp.c:728
4139#, fuzzy, c-format
4140msgid "Failed to bind to %s port %d.\n"
4141msgstr "Misslyckades att binda till UDP-port %d.\n"
4142
4143#: src/transports/udp.c:538
4144#, c-format
4145msgid "MTU %llu for `%s' is probably too low!\n"
4146msgstr ""
4147
4148#: src/transports/udp.c:562
4149msgid "# bytes received via UDP"
4150msgstr "# byte mottagna via UDP"
4151
4152#: src/transports/udp.c:563
4153msgid "# bytes sent via UDP"
4154msgstr "# byte skickade via UDP"
4155
4156#: src/transports/udp.c:565
4157msgid "# bytes dropped by UDP (outgoing)"
4158msgstr "# byte kastade via UDP (utgående)"
4159
4160#: src/transports/udp.c:567
4161msgid "# UDP connections (right now)"
4162msgstr ""
4163
4164#: src/transports/tcp.c:821
4165msgid "# bytes received via TCP"
4166msgstr "# byte mottogs via TCP"
4167
4168#: src/transports/tcp.c:822
4169msgid "# bytes sent via TCP"
4170msgstr "# byte skickades via TCP"
4171
4172#: src/transports/tcp.c:824
4173msgid "# bytes dropped by TCP (outgoing)"
4174msgstr "# byte kastade via TCP (utgående)"
4175
4176#: src/include/gnunet_util_getopt.h:154
4177msgid "print this help"
4178msgstr "skriv ut denna hjälp"
4179
4180#: src/include/gnunet_util_getopt.h:163
4181msgid "print the version number"
4182msgstr "skriv ut versionsnummer"
4183
4184#: src/include/gnunet_util_getopt.h:169
4185msgid "configure logging to use LOGLEVEL"
4186msgstr ""
4187
4188#: src/include/gnunet_util_getopt.h:175
4189msgid "be verbose"
4190msgstr "var informativ"
4191
4192#: src/include/gnunet_util_getopt.h:181
4193msgid "use configuration file FILENAME"
4194msgstr "använd konfigurationsfil FILNAMN"
4195
4196#: src/include/gnunet_util_getopt.h:187
4197msgid "specify host on which gnunetd is running"
4198msgstr "ange värd på vilken gnunetd körs"
4199
4200#: src/include/gnunet_util_error.h:219 src/include/gnunet_util_error.h:224
4201#: src/include/gnunet_util_error.h:230 src/include/gnunet_util_error.h:232
4202#, c-format
4203msgid "Internal error: assertion failed at %s:%d.\n"
4204msgstr ""
4205
4206#: src/include/gnunet_util_error.h:242
4207#, c-format
4208msgid ""
4209"External protocol violation: assertion failed at %s:%d (no need to panic, we "
4210"can handle this).\n"
4211msgstr ""
4212
4213#: src/include/gnunet_util_error.h:270 src/include/gnunet_util_error.h:277
4214#, c-format
4215msgid "`%s' failed on file `%s' at %s:%d with error: %s\n"
4216msgstr "\"%s\" misslyckades för fil \"%s\" vid %s:%d med fel: %s\n"
4217
4218#: contrib/config-daemon.scm:39 contrib/config-client.scm:40
4219#, fuzzy
4220msgid "No help available."
4221msgstr "\"%s\" är inte tillgänglig."
4222
4223#: contrib/config-daemon.scm:42
4224msgid ""
4225"You can use 'make check' in src/transports/upnp/ to find out if your NAT "
4226"supports UPnP. You should disable this option if you are sure that you are "
4227"not behind a NAT. If your NAT box does not support UPnP, having this on "
4228"will not do much harm (only cost a small amount of resources)."
4229msgstr ""
4230
4231#: contrib/config-daemon.scm:54 contrib/config-client.scm:53
4232msgid "Prompt for development and/or incomplete code"
4233msgstr ""
4234
4235#: contrib/config-daemon.scm:56 contrib/config-client.scm:55
4236msgid ""
4237"If EXPERIMENTAL is set to NO, options for experimental code are not shown. "
4238"If in doubt, use NO.\n"
4239"\n"
4240"Some options apply to experimental code that maybe in a state of development "
4241"where the functionality, stability, or the level of testing is not yet high "
4242"enough for general use. These features are said to be of \"alpha\" "
4243"quality. If a feature is currently in alpha, uninformed use is discouraged "
4244"(since the developers then do not fancy \"Why doesn't this work?\" type "
4245"messages).\n"
4246"\n"
4247"However, active testing and qualified feedback of these features is always "
4248"welcome. Users should just be aware that alpha features may not meet the "
4249"normal level of reliability or it may fail to work in some special cases. "
4250"Bug reports are usually welcomed by the developers, but please read the "
4251"documents <file://README> and <http://gnunet.org/faq.php3> and use <https://"
4252"gnunet.org/mantis/> for how to report problems."
4253msgstr ""
4254
4255#: contrib/config-daemon.scm:71 contrib/config-client.scm:70
4256msgid "Show options for advanced users"
4257msgstr ""
4258
4259#: contrib/config-daemon.scm:73 contrib/config-client.scm:72
4260msgid ""
4261"These are options that maybe difficult to understand for the beginner. These "
4262"options typically refer to features that allow tweaking of the "
4263"installation. If in a hurry, say NO."
4264msgstr ""
4265
4266#: contrib/config-daemon.scm:84 contrib/config-client.scm:83
4267#, fuzzy
4268msgid "Show rarely used options"
4269msgstr "Visa alla alternativ"
4270
4271#: contrib/config-daemon.scm:86 contrib/config-client.scm:85
4272msgid ""
4273"These are options that hardly anyone actually needs. If you plan on doing "
4274"development on GNUnet, you may want to look into these. If in doubt or in a "
4275"hurry, say NO."
4276msgstr ""
4277
4278#: contrib/config-daemon.scm:97 contrib/config-client.scm:96
4279#, fuzzy
4280msgid "Meta-configuration"
4281msgstr "GNUnet-konfiguration"
4282
4283#: contrib/config-daemon.scm:98 contrib/config-client.scm:97
4284msgid "Which level of configuration should be available"
4285msgstr ""
4286
4287#: contrib/config-daemon.scm:115
4288#, fuzzy
4289msgid "Full pathname of GNUnet HOME directory"
4290msgstr "Filformatsfel (inte en GNUnet-katalog?)\n"
4291
4292#: contrib/config-daemon.scm:117
4293msgid ""
4294"This gives the root-directory of the GNUnet installation. Make sure there is "
4295"some space left in that directory. :-) Users inserting or indexing files "
4296"will be able to store data in this directory up to the (global) quota "
4297"specified below. Having a few gigabytes of free space is recommended."
4298msgstr ""
4299
4300#: contrib/config-daemon.scm:130
4301msgid "Full pathname of GNUnet directory for file-sharing data"
4302msgstr ""
4303
4304#: contrib/config-daemon.scm:142
4305msgid "Full pathname to the directory with the key-value database"
4306msgstr ""
4307
4308#: contrib/config-daemon.scm:143
4309msgid "Note that the kvstore is currently not used."
4310msgstr ""
4311
4312#: contrib/config-daemon.scm:154
4313msgid "Full pathname of GNUnet directory for indexed files symbolic links"
4314msgstr ""
4315
4316#: contrib/config-daemon.scm:166
4317msgid "How many minutes should peer advertisements last?"
4318msgstr ""
4319
4320#: contrib/config-daemon.scm:168
4321msgid ""
4322"How many minutes is the current IP valid? (GNUnet will sign HELLO messages "
4323"with this expiration timeline. If you are on dialup, 60 (for 1 hour) is "
4324"suggested. If you have a static IP address, you may want to set this to a "
4325"large value (say 14400). The default is 1440 (1 day). If your IP changes "
4326"periodically, you will want to choose an expiry period smaller than the "
4327"frequency with which your IP changes."
4328msgstr ""
4329
4330#: contrib/config-daemon.scm:179
4331msgid "Where can GNUnet find an initial list of peers?"
4332msgstr ""
4333
4334#: contrib/config-daemon.scm:181
4335msgid ""
4336"GNUnet can automatically update the hostlist from the web. While GNUnet "
4337"internally communicates which hosts are online, it is typically a good idea "
4338"to get a fresh hostlist whenever gnunetd starts from the WEB. By setting "
4339"this option, you can specify from which server gnunetd should try to "
4340"download the hostlist. The default should be fine for now.\n"
4341"\t\t\n"
4342"The general format is a list of space-separated URLs. Each URL must have "
4343"the format http://HOSTNAME/FILENAME\n"
4344"\t\t\n"
4345"If you want to setup an alternate hostlist server, you must run a permanent "
4346"node and \"cat data/hosts/* > hostlist\" every few minutes to keep the list "
4347"up-to-date.\n"
4348"\t\t\n"
4349"If you do not specify a HOSTLISTURL, you must copy valid hostkeys to data/"
4350"hosts manually."
4351msgstr ""
4352
4353#: contrib/config-daemon.scm:198
4354msgid "HTTP Proxy Server"
4355msgstr ""
4356
4357#: contrib/config-daemon.scm:200
4358msgid ""
4359"If you have to use a proxy for outbound HTTP connections, specify the proxy "
4360"configuration here. Default is no proxy."
4361msgstr ""
4362
4363#: contrib/config-daemon.scm:212
4364msgid ""
4365"Name of the directory where gnunetd should store contact information about "
4366"peers"
4367msgstr ""
4368
4369#: contrib/config-daemon.scm:214
4370msgid ""
4371"Unless you want to share the directory directly using a webserver, the "
4372"default is most likely just fine."
4373msgstr ""
4374
4375#: contrib/config-daemon.scm:240 contrib/config-client.scm:140
4376msgid "How long should logs be kept?"
4377msgstr ""
4378
4379#: contrib/config-daemon.scm:242 contrib/config-client.scm:142
4380msgid ""
4381"How long should logs be kept? If you specify a value greater than zero, a "
4382"log is created each day with the date appended to its filename. These logs "
4383"are deleted after $KEEPLOG days.\tTo keep logs forever, set this value to 0."
4384msgstr ""
4385
4386#: contrib/config-daemon.scm:253
4387msgid ""
4388"What maximum number of open file descriptors should be requested from the OS?"
4389msgstr ""
4390
4391#: contrib/config-daemon.scm:255
4392msgid ""
4393"The default of 1024 should be fine for most systems. If your system can "
4394"support more, increasing the number might help support additional clients on "
4395"machines with plenty of bandwidth. For embedded systems, a smaller number "
4396"might be acceptable. A value of 0 will leave the descriptor limit "
4397"untouched. This option is mostly for OS X systems where the default is too "
4398"low. Note that if gnunetd cannot obtain the desired number of file "
4399"descriptors from the operating system, it will print a warning and try to "
4400"run with what it is given."
4401msgstr ""
4402
4403#: contrib/config-daemon.scm:266
4404msgid "Where should gnunetd write the logs?"
4405msgstr ""
4406
4407#: contrib/config-daemon.scm:278
4408msgid "Enable for extra-verbose logging."
4409msgstr ""
4410
4411#: contrib/config-daemon.scm:290 contrib/config-client.scm:165
4412msgid "Logging"
4413msgstr ""
4414
4415#: contrib/config-daemon.scm:291 contrib/config-client.scm:166
4416msgid "Specify which system messages should be logged how"
4417msgstr ""
4418
4419#: contrib/config-daemon.scm:296 contrib/config-client.scm:170
4420msgid "Logging of events for users"
4421msgstr ""
4422
4423#: contrib/config-daemon.scm:297 contrib/config-client.scm:171
4424msgid "Logging of events for the system administrator"
4425msgstr ""
4426
4427#: contrib/config-daemon.scm:309
4428msgid "Where should gnunetd write the PID?"
4429msgstr ""
4430
4431#: contrib/config-daemon.scm:310
4432msgid ""
4433"The default is no longer /var/run/gnunetd.pid since we could not delete the "
4434"file on shutdown at that location."
4435msgstr ""
4436
4437#: contrib/config-daemon.scm:322
4438msgid "As which user should gnunetd run?"
4439msgstr ""
4440
4441#: contrib/config-daemon.scm:324
4442msgid ""
4443"Empty means \"current user\". On computer startup, it is root/SYSTEM. Under "
4444"Windows, this setting affects the creation of a new system service only."
4445msgstr ""
4446
4447#: contrib/config-daemon.scm:337
4448msgid "Should gnunetd be automatically started when the system boots?"
4449msgstr ""
4450
4451#: contrib/config-daemon.scm:338
4452msgid ""
4453"Set to YES if gnunetd should be automatically started on boot. If this "
4454"option is set, gnunet-setup will install a script to start the daemon upon "
4455"completion. This option may not work on all systems."
4456msgstr ""
4457
4458#: contrib/config-daemon.scm:350
4459msgid "Which transport mechanisms should GNUnet use?"
4460msgstr ""
4461
4462#: contrib/config-daemon.scm:352
4463msgid ""
4464"Use a space-separated list of modules, e.g. \"udp smtp tcp\". The "
4465"available transports are udp, tcp, http, smtp and nat.\n"
4466"\t\t\n"
4467"Loading the 'nat' and 'tcp' modules is required for peers behind NAT boxes "
4468"that cannot directly be reached from the outside. Peers that are NOT behind "
4469"a NAT box and that want to *allow* peers that ARE behind a NAT box to "
4470"connect must ALSO load the 'nat' module. Note that the actual transfer will "
4471"always be via tcp initiated by the peer behind the NAT box. The nat "
4472"transport requires the use of tcp, http and/or smtp in addition to nat "
4473"itself."
4474msgstr ""
4475
4476#: contrib/config-daemon.scm:366
4477msgid "Which applications should gnunetd support?"
4478msgstr ""
4479
4480#: contrib/config-daemon.scm:368
4481msgid ""
4482"Whenever this option is changed, you MUST run gnunet-update. Currently, the "
4483"available applications are:\n"
4484"\n"
4485"advertising: advertises your peer to other peers. Without it, your peer will "
4486"not participate in informing peers about other peers. You should always "
4487"load this module.\n"
4488"\n"
4489"getoption: allows clients to query gnunetd about the values of various "
4490"configuration options. Many tools need this. You should always load this "
4491"module.\n"
4492"\n"
4493"stats: allows tools like gnunet-stats and gnunet-gtk to query gnunetd about "
4494"various statistics. This information is usually quite useful to diagnose "
4495"errors, hence it is recommended that you load this module.\n"
4496"\n"
4497"traffic: keeps track of how many messages were recently received and "
4498"transmitted. This information can then be used to establish how much cover "
4499"traffic is currently available. The amount of cover traffic becomes "
4500"important if you want to make anonymous requests with an anonymity level "
4501"that is greater than one. It is recommended that you load this module.\n"
4502"\n"
4503"fs: needed for anonymous file sharing. You should always load this module.\n"
4504"\n"
4505"hostlist: integrated hostlist HTTP server. Useful if you want to offer a "
4506"hostlist and running Apache would be overkill.\n"
4507"\n"
4508"chat: broadcast chat (demo-application, ALPHA quality).\tRequired for gnunet-"
4509"chat. Note that the current implementation of chat is not considered to be "
4510"secure.\n"
4511"\n"
4512"tbench: benchmark transport performance. Required for gnunet-tbench. Note "
4513"that tbench allows other users to abuse your resources.\n"
4514"\n"
4515"tracekit: topology visualization toolkit. Required for gnunet-tracekit. "
4516"Note that loading tracekit will make it slightly easier for an adversary to "
4517"compromise your anonymity."
4518msgstr ""
4519
4520#: contrib/config-daemon.scm:399
4521msgid "Disable client-server connections"
4522msgstr ""
4523
4524#: contrib/config-daemon.scm:400
4525msgid ""
4526"This option can be used to tell gnunetd not to open the client port. When "
4527"run like this, gnunetd will participate as a peer in the network but not "
4528"support any user interfaces. This may be useful for headless systems that "
4529"are never expected to have end-user interactions. Note that this will also "
4530"prevent you from running diagnostic tools like gnunet-stats!"
4531msgstr ""
4532
4533#: contrib/config-daemon.scm:412
4534msgid "YES disables IPv6 support, NO enables IPv6 support"
4535msgstr ""
4536
4537#: contrib/config-daemon.scm:413
4538msgid ""
4539"This option may be useful on peers where the kernel does not support IPv6. "
4540"You might also want to set this option if you do not have an IPv6 network "
4541"connection."
4542msgstr ""
4543
4544#: contrib/config-daemon.scm:425
4545msgid "Disable peer discovery"
4546msgstr ""
4547
4548#: contrib/config-daemon.scm:426
4549msgid ""
4550"The option 'PRIVATE-NETWORK' can be used to limit the connections of this "
4551"peer to peers of which the hostkey has been copied by hand to data/hosts; "
4552"if this option is given, GNUnet will not accept advertisements of peers that "
4553"the local node does not already know about. Note that in order for this "
4554"option to work, HOSTLISTURL should either not be set at all or be set to a "
4555"trusted peer that only advertises the private network. Also, the option does "
4556"NOT work at the moment if the NAT transport is loaded; for that, a couple of "
4557"lines above would need some minor editing :-)."
4558msgstr ""
4559
4560#: contrib/config-daemon.scm:437
4561msgid "Disable advertising this peer to other peers"
4562msgstr ""
4563
4564#: contrib/config-daemon.scm:449
4565msgid "Disable automatic establishment of connections"
4566msgstr ""
4567
4568#: contrib/config-daemon.scm:450
4569msgid ""
4570"If this option is enabled, GNUnet will not automatically establish "
4571"connections to other peers, but instead wait for applications to "
4572"specifically request connections to other peers (or for other peers to "
4573"connect to us)."
4574msgstr ""
4575
4576#: contrib/config-daemon.scm:461
4577msgid "Enable advertising of other peers by this peer"
4578msgstr ""
4579
4580#: contrib/config-daemon.scm:462
4581msgid ""
4582"This option may be useful during testing, but turning it off is dangerous! "
4583"If in any doubt, set it to YES (which is the default)."
4584msgstr ""
4585
4586#: contrib/config-daemon.scm:473
4587#, fuzzy
4588msgid "Port for communication with GNUnet user interfaces"
4589msgstr "Skriv ut information om GNUnets motparter."
4590
4591#: contrib/config-daemon.scm:474
4592msgid ""
4593"Which is the client-server port that is used between gnunetd and the clients "
4594"(TCP only). You may firewall this port for non-local machines (but you do "
4595"not have to since GNUnet will perform access control and only allow "
4596"connections from machines that are listed under TRUSTED)."
4597msgstr ""
4598
4599#: contrib/config-daemon.scm:485
4600msgid "Port for the integrated hostlist HTTP server"
4601msgstr ""
4602
4603#: contrib/config-daemon.scm:497
4604msgid "IPv4 networks allowed to use gnunetd server"
4605msgstr ""
4606
4607#: contrib/config-daemon.scm:498 contrib/config-daemon.scm:510
4608msgid ""
4609"This option specifies which hosts are trusted enough to connect as clients "
4610"(to the TCP port). This is useful if you run gnunetd on one host of your "
4611"network and want to allow all other hosts to use this node as their server. "
4612"By default, this is set to 'loopback only'. The format is IP/NETMASK where "
4613"the IP is specified in dotted-decimal and the netmask either in CIDR "
4614"notation (/16) or in dotted decimal (255.255.0.0). Several entries must be "
4615"separated by a semicolon, spaces are not allowed."
4616msgstr ""
4617
4618#: contrib/config-daemon.scm:509
4619msgid "IPv6 networks allowed to use gnunetd server"
4620msgstr ""
4621
4622#: contrib/config-daemon.scm:522
4623msgid "Limit connections to the specfied set of peers."
4624msgstr ""
4625
4626#: contrib/config-daemon.scm:523
4627msgid ""
4628"If this option is not set, any peer is allowed to connect. If it is set, "
4629"only the specified peers are allowed. Specify the list of peer IDs (not IPs!)"
4630msgstr ""
4631
4632#: contrib/config-daemon.scm:534
4633#, fuzzy
4634msgid "Run gnunetd as this group."
4635msgstr "Kör gnunet-update"
4636
4637#: contrib/config-daemon.scm:535
4638msgid ""
4639"When started as root, gnunetd will change permissions to the given group."
4640msgstr ""
4641
4642#: contrib/config-daemon.scm:546
4643msgid "Prevent the specfied set of peers from connecting."
4644msgstr ""
4645
4646#: contrib/config-daemon.scm:547
4647msgid ""
4648"If this option is not set, any peer is allowed to connect. If the ID of a "
4649"peer is listed here, connections from that peer will be refused. Specify "
4650"the list of peer IDs (not IPs!)"
4651msgstr ""
4652
4653#: contrib/config-daemon.scm:558
4654msgid "Topology Maintenance"
4655msgstr ""
4656
4657#: contrib/config-daemon.scm:559
4658msgid "Rarely used settings for peer advertisements and connections"
4659msgstr ""
4660
4661#: contrib/config-daemon.scm:579
4662#, fuzzy
4663msgid "General settings"
4664msgstr "Andra inställningar"
4665
4666#: contrib/config-daemon.scm:580
4667msgid "Settings that change the behavior of GNUnet in general"
4668msgstr ""
4669
4670#: contrib/config-daemon.scm:607
4671msgid "Modules"
4672msgstr ""
4673
4674#: contrib/config-daemon.scm:608
4675msgid "Settings that select specific implementations for GNUnet modules"
4676msgstr ""
4677
4678#: contrib/config-daemon.scm:626
4679msgid "Fundamentals"
4680msgstr ""
4681
4682#: contrib/config-daemon.scm:646
4683msgid "Which database should be used?"
4684msgstr ""
4685
4686#: contrib/config-daemon.scm:648
4687msgid ""
4688"Which database should be used? The options are \"sqstore_sqlite\", "
4689"\"sqstore_postgres\" and \"sqstore_mysql\". You must run gnunet-update "
4690"after changing this value!\n"
4691"\t\t\t\n"
4692"In order to use MySQL or Postgres, you must configure the respective "
4693"database, which is relatively simple. Read the file doc/README.mysql or doc/"
4694"README.postgres for how to setup the respective database."
4695msgstr ""
4696
4697#: contrib/config-daemon.scm:661 contrib/config-daemon.scm:674
4698msgid "Which topology should be used?"
4699msgstr ""
4700
4701#: contrib/config-daemon.scm:662
4702msgid "Which database should be used for the temporary datastore of the DHT?"
4703msgstr ""
4704
4705#: contrib/config-daemon.scm:676
4706msgid ""
4707"Which topology should be used? The only option at the moment is "
4708"\"topology_default\""
4709msgstr ""
4710
4711#: contrib/config-daemon.scm:690
4712msgid ""
4713"The minimum number of connected friends before this peer is allowed to "
4714"connect to peers that are not listed as friends"
4715msgstr ""
4716
4717#: contrib/config-daemon.scm:691
4718msgid ""
4719"Note that this option does not guarantee that the peer will be able to "
4720"connect to the specified number of friends. Also, if the peer had connected "
4721"to a sufficient number of friends and then established non-friend "
4722"connections, some of the friends may drop out of the network, temporarily "
4723"resulting in having fewer than the specified number of friends connected "
4724"while being connected to non-friends. However, it is guaranteed that the "
4725"peer itself will never choose to drop a friend's connection if this would "
4726"result in dropping below the specified number of friends (unless that number "
4727"is higher than the overall connection target)."
4728msgstr ""
4729
4730#: contrib/config-daemon.scm:702
4731msgid ""
4732"If set to YES, the peer is only allowed to connect to other peers that are "
4733"explicitly specified as friends"
4734msgstr ""
4735
4736#: contrib/config-daemon.scm:703
4737msgid ""
4738"Use YES only if you have (trustworthy) friends that use GNUnet and are "
4739"afraid of establishing (direct) connections to unknown peers"
4740msgstr ""
4741
4742#: contrib/config-daemon.scm:714
4743msgid "List of friends for friend-to-friend topology"
4744msgstr ""
4745
4746#: contrib/config-daemon.scm:715
4747msgid ""
4748"Specifies the name of a file which contains a list of GNUnet peer IDs that "
4749"are friends. If used with the friend-to-friend topology, this will ensure "
4750"that GNUnet only connects to these peers (via any available transport)."
4751msgstr ""
4752
4753#: contrib/config-daemon.scm:726
4754msgid "Friend-to-Friend Topology Specification"
4755msgstr ""
4756
4757#: contrib/config-daemon.scm:727
4758#, fuzzy
4759msgid "Settings for restricting connections to friends"
4760msgstr "\"%s\" misslyckades. Terminerar anslutning till klient.\n"
4761
4762#: contrib/config-daemon.scm:744
4763msgid "Name of the MySQL database GNUnet should use"
4764msgstr ""
4765
4766#: contrib/config-daemon.scm:756
4767msgid "Configuration file that specifies the MySQL username and password"
4768msgstr ""
4769
4770#: contrib/config-daemon.scm:768
4771#, fuzzy
4772msgid "Configuration of the MySQL database"
4773msgstr "Konfigurationsfil \"%s\" skapad.\n"
4774
4775#: contrib/config-daemon.scm:787
4776msgid "MB of diskspace GNUnet can use for anonymous file sharing"
4777msgstr ""
4778
4779#: contrib/config-daemon.scm:789
4780msgid ""
4781"How much disk space (MB) is GNUnet allowed to use for anonymous file "
4782"sharing? This does not take indexed files into account, only the space "
4783"directly used by GNUnet is accounted for. GNUnet will gather content from "
4784"the network if the current space-consumption is below the number given here "
4785"(and if content migration is allowed below).\n"
4786"\n"
4787"Note that if you change the quota, you need to run gnunet-update afterwards."
4788msgstr ""
4789
4790#: contrib/config-daemon.scm:803
4791msgid "Number of entries in the migration buffer"
4792msgstr ""
4793
4794#: contrib/config-daemon.scm:804
4795msgid ""
4796"Each entry uses about 32k of memory. More entries can reduce disk IO and "
4797"CPU usage at the expense of having gnunetd use more memory. Very large "
4798"values may again increase CPU usage. A value of 0 will prevent your peer "
4799"from sending unsolicited responses."
4800msgstr ""
4801
4802#: contrib/config-daemon.scm:816
4803msgid "Size of the routing table for anonymous routing."
4804msgstr ""
4805
4806#: contrib/config-daemon.scm:828
4807msgid "Size of the routing table for DHT routing."
4808msgstr ""
4809
4810#: contrib/config-daemon.scm:841
4811msgid "Allow migrating content to this peer."
4812msgstr ""
4813
4814#: contrib/config-daemon.scm:843
4815msgid ""
4816"If you say yes here, GNUnet will migrate content to your server, and you "
4817"will not be able to control what data is stored on your machine. \n"
4818"\t\t\t\n"
4819"If you activate it, you can claim for *all* the non-indexed (-n to gnunet-"
4820"insert) content that you did not know what it was even if an adversary takes "
4821"control of your machine. If you do not activate it, it is obvious that you "
4822"have knowledge of all the content that is hosted on your machine and thus "
4823"can be considered liable for it."
4824msgstr ""
4825
4826#: contrib/config-daemon.scm:857
4827msgid ""
4828"MB of diskspace GNUnet can use for caching DHT index data (the data will be "
4829"stored in /tmp)"
4830msgstr ""
4831
4832#: contrib/config-daemon.scm:858
4833msgid ""
4834"DHT index data is inherently small and expires comparatively quickly. It is "
4835"deleted whenever gnunetd is shut down.\n"
4836"\n"
4837"The size of the DSTORE QUOTA is specified in MB."
4838msgstr ""
4839
4840#: contrib/config-daemon.scm:872
4841#, fuzzy
4842msgid "Options for anonymous file sharing"
4843msgstr "aktiverar (anonym) fildelning"
4844
4845#: contrib/config-daemon.scm:891
4846#, fuzzy
4847msgid "Applications"
4848msgstr "_Alternativ"
4849
4850#: contrib/config-daemon.scm:907
4851msgid "Is this machine unreachable behind a NAT?"
4852msgstr ""
4853
4854#: contrib/config-daemon.scm:908
4855msgid ""
4856"Set to YES if this machine is behind a NAT that limits connections from the "
4857"outside to the GNUnet port and that cannot be traversed using UPnP. Note "
4858"that if you have configured your NAT box to allow direct connections from "
4859"other machines to the GNUnet ports or if GNUnet can open ports using UPnP, "
4860"you should set the option to NO. Set this only to YES if other peers cannot "
4861"contact you directly. You can use 'make check' in src/transports/upnp/ to "
4862"find out if your NAT supports UPnP. You can also use gnunet-transport-check "
4863"with the '-p' option in order to determine which setting results in more "
4864"connections. Use YES only if you get no connections otherwise. Set to AUTO "
4865"to use YES if the local IP is belongs to a private IP network and NO "
4866"otherwise."
4867msgstr ""
4868
4869#: contrib/config-daemon.scm:919
4870msgid "Which port should be used by the TCP IPv4 transport?"
4871msgstr ""
4872
4873#: contrib/config-daemon.scm:931 contrib/config-daemon.scm:1024
4874#: contrib/config-daemon.scm:1174
4875msgid "Should we try to determine our external IP using UPnP?"
4876msgstr ""
4877
4878#: contrib/config-daemon.scm:943
4879msgid "Which IP(v4)s are not allowed to connect?"
4880msgstr ""
4881
4882#: contrib/config-daemon.scm:955
4883msgid ""
4884"Which IP(v4)s are allowed to connect? Leave empty to use the IP of your "
4885"primary network interface."
4886msgstr ""
4887
4888#: contrib/config-daemon.scm:967 contrib/config-daemon.scm:1222
4889msgid "Which IPv6s are not allowed to connect?"
4890msgstr ""
4891
4892#: contrib/config-daemon.scm:979 contrib/config-daemon.scm:1234
4893msgid ""
4894"Which IPv6s are allowed to connect? Leave empty to allow any IP to connect."
4895msgstr ""
4896
4897#: contrib/config-daemon.scm:992
4898msgid "TCP transport"
4899msgstr ""
4900
4901#: contrib/config-daemon.scm:1012
4902msgid "Which port should be used by the HTTP transport?"
4903msgstr ""
4904
4905#: contrib/config-daemon.scm:1036
4906msgid "Which is the external port of the HTTP transport?"
4907msgstr ""
4908
4909#: contrib/config-daemon.scm:1037
4910msgid ""
4911"Use this option if your firewall maps, say, port 80 to your real HTTP port. "
4912"This can be useful in making the HTTP messages appear even more legit "
4913"(without needing to run gnunetd as root due to the use of a privileged port)."
4914msgstr ""
4915
4916#: contrib/config-daemon.scm:1048
4917msgid "HTTP transport"
4918msgstr ""
4919
4920#: contrib/config-daemon.scm:1067
4921msgid "What is the maximum transfer unit for SMTP?"
4922msgstr ""
4923
4924#: contrib/config-daemon.scm:1079
4925msgid ""
4926"What is the maximum number of e-mails that gnunetd would be allowed to send "
4927"per hour?"
4928msgstr ""
4929
4930#: contrib/config-daemon.scm:1080
4931msgid "Use 0 for unlimited"
4932msgstr ""
4933
4934#: contrib/config-daemon.scm:1091
4935msgid "Which e-mail address should be used to send e-mail to this peer?"
4936msgstr ""
4937
4938#: contrib/config-daemon.scm:1092
4939msgid ""
4940"You must make sure that e-mail received at this address is forwarded to the "
4941"PIPE which is read by gnunetd. Use the FILTER option to filter e-mail with "
4942"procmail and the PIPE option to set the name of the pipe."
4943msgstr ""
4944
4945#: contrib/config-daemon.scm:1103
4946msgid ""
4947"Which header line should other peers include in e-mails to enable filtering?"
4948msgstr ""
4949
4950#: contrib/config-daemon.scm:1104
4951msgid ""
4952"You can specify a header line here which can then be used by procmail to "
4953"filter GNUnet e-mail from your inbox and forward it to gnunetd."
4954msgstr ""
4955
4956#: contrib/config-daemon.scm:1115
4957msgid "What is the filename of the pipe where gnunetd can read its e-mail?"
4958msgstr ""
4959
4960#: contrib/config-daemon.scm:1116
4961msgid "Have a look at contrib/dot-procmailrc for an example .procmailrc file."
4962msgstr ""
4963
4964#: contrib/config-daemon.scm:1127
4965msgid "What is the name and port of the server for outgoing e-mail?"
4966msgstr ""
4967
4968#: contrib/config-daemon.scm:1128
4969msgid "The basic format is HOSTNAME:PORT."
4970msgstr ""
4971
4972#: contrib/config-daemon.scm:1139
4973msgid "SMTP transport"
4974msgstr ""
4975
4976#: contrib/config-daemon.scm:1162
4977msgid "Which port should be used by the UDP IPv4 transport?"
4978msgstr ""
4979
4980#: contrib/config-daemon.scm:1186
4981msgid "What is the maximum transfer unit for UDP?"
4982msgstr ""
4983
4984#: contrib/config-daemon.scm:1198
4985msgid "Which IPs are not allowed to connect?"
4986msgstr ""
4987
4988#: contrib/config-daemon.scm:1210
4989msgid ""
4990"Which IPs are allowed to connect? Leave empty to allow connections from any "
4991"IP."
4992msgstr ""
4993
4994#: contrib/config-daemon.scm:1246
4995msgid "UDP transport"
4996msgstr ""
4997
4998#: contrib/config-daemon.scm:1268
4999#, fuzzy
5000msgid "Network interface"
5001msgstr "Nätverksgränssnitt:"
5002
5003#: contrib/config-daemon.scm:1280
5004msgid "External IP address (leave empty to try auto-detection)"
5005msgstr ""
5006
5007#: contrib/config-daemon.scm:1292
5008msgid "External IPv6 address (leave empty to try auto-detection)"
5009msgstr ""
5010
5011#: contrib/config-daemon.scm:1304
5012msgid "Transports"
5013msgstr ""
5014
5015#: contrib/config-daemon.scm:1326
5016msgid "What is the maximum number of bytes per second that we may receive?"
5017msgstr ""
5018
5019#: contrib/config-daemon.scm:1338
5020msgid "What is the maximum number of bytes per second that we may send?"
5021msgstr ""
5022
5023#: contrib/config-daemon.scm:1350
5024msgid "What is the maximum CPU load (percentage)?"
5025msgstr ""
5026
5027#: contrib/config-daemon.scm:1351
5028msgid ""
5029"The highest tolerable CPU load. Load here always refers to the total system "
5030"load, that is it includes CPU utilization by other processes. A value of 50 "
5031"means that once your 1 minute-load average goes over 50% non-idle, GNUnet "
5032"will try to reduce CPU consumption until the load goes under the threshold. "
5033"Reasonable values are typically between 50 and 100. Multiprocessors may use "
5034"values above 100."
5035msgstr ""
5036
5037#: contrib/config-daemon.scm:1362
5038msgid "What is the maximum IO load (permille)?"
5039msgstr ""
5040
5041#: contrib/config-daemon.scm:1364
5042msgid ""
5043"The highest tolerable IO load. Load here refers to the percentage of CPU "
5044"cycles wasted waiting for IO for the entire system, that is it includes disk "
5045"utilization by other processes. A value of 10 means that once the average "
5046"number of cycles wasted waiting for IO is more than 10% non-idle, GNUnet "
5047"will try to reduce IO until the load goes under the threshold. Reasonable "
5048"values are typically between 10 and 75."
5049msgstr ""
5050
5051#: contrib/config-daemon.scm:1375
5052msgid "What is the maximum CPU load (hard limit)?"
5053msgstr ""
5054
5055#: contrib/config-daemon.scm:1376
5056msgid ""
5057"The highest tolerable CPU load. This is the hard limit, so once it is "
5058"reached, gnunetd will start to massively drop data to reduce the load. Use "
5059"with caution."
5060msgstr ""
5061
5062#: contrib/config-daemon.scm:1387
5063msgid "What is the maximum upstream bandwidth (hard limit)?"
5064msgstr ""
5065
5066#: contrib/config-daemon.scm:1388
5067msgid ""
5068"The limit is given as a percentage of the MAXNETUPBPS limit. Use 100 to "
5069"have MAXNETUPBPS be the hard limit. Use zero for no limit."
5070msgstr ""
5071
5072#: contrib/config-daemon.scm:1400
5073msgid "What priority should gnunetd use to run?"
5074msgstr ""
5075
5076#: contrib/config-daemon.scm:1401
5077msgid ""
5078"You can specify priorities like NORMAL, ABOVE NORMAL, BELOW NORMAL, HIGH and "
5079"IDLE or a numerical integer value (man nice). The default is IDLE, which "
5080"should result in gnunetd only using resources that would otherwise be idle."
5081msgstr ""
5082
5083#: contrib/config-daemon.scm:1413
5084msgid "Should we disable random padding (experimental option)?"
5085msgstr ""
5086
5087#: contrib/config-daemon.scm:1425
5088msgid "Use basic bandwidth limitation? (YES/NO). If in doubt, say YES."
5089msgstr ""
5090
5091#: contrib/config-daemon.scm:1427
5092msgid ""
5093"Basic bandwidth limitation (YES) means simply that the bandwidth limits "
5094"specified apply to GNUnet and only to GNUnet. If set to YES, you simply "
5095"specify the maximum bandwidth (upstream and downstream) that GNUnet is "
5096"allowed to use and GNUnet will stick to those limitations. This is useful "
5097"if your overall bandwidth is so large that the limit is mostly used to "
5098"ensure that enough capacity is left for other applications. Even if you "
5099"want to dedicate your entire connection to GNUnet you should not set the "
5100"limits to values higher than what you have since GNUnet uses those limits to "
5101"determine for example the number of connections to establish (and it would "
5102"be inefficient if that computation yields a number that is far too high). \n"
5103"\n"
5104"While basic bandwidth limitation is simple and always works, there are some "
5105"situations where it is not perfect. Suppose you are running another "
5106"application which performs a larger download. During that particular time, "
5107"it would be nice if GNUnet would throttle its bandwidth consumption "
5108"(automatically) and resume using more bandwidth after the download is "
5109"complete. This is obviously advanced magic since GNUnet will have to "
5110"monitor the behavior of other applications. Another scenario is a monthly "
5111"cap on bandwidth imposed by your ISP, which you would want to ensure is "
5112"obeyed. Here, you may want GNUnet to monitor the traffic from other "
5113"applications to ensure that the combined long-term traffic is within the pre-"
5114"set bounds. Note that you should probably not set the bounds tightly since "
5115"GNUnet may observe that the bounds are about to be broken but would be "
5116"unable to stop other applications from continuing to use bandwidth.\n"
5117"\n"
5118"If either of these two scenarios applies, set BASICLIMITING to NO. Then set "
5119"the bandwidth limits to the COMBINED amount of traffic that is acceptable "
5120"for both GNUnet and other applications. GNUnet will then immediately "
5121"throttle bandwidth consumption if the short-term average is above the limit, "
5122"and it will also try to ensure that the long-term average is below the "
5123"limit. Note however that using NO can have the effect of GNUnet (almost) "
5124"ceasing operations after other applications perform high-volume downloads "
5125"that are beyond the defined limits. GNUnet would reduce consumption until "
5126"the long-term limits are again within bounds.\n"
5127"\n"
5128"NO only works on platforms where GNUnet can monitor the amount of traffic "
5129"that the local host puts out on the network. This is only implemented for "
5130"Linux and Win32. In order for the code to work, GNUnet needs to know the "
5131"specific network interface that is used for the external connection (after "
5132"all, the amount of traffic on loopback or on the LAN should never be counted "
5133"since it is irrelevant)."
5134msgstr ""
5135
5136#: contrib/config-daemon.scm:1444
5137#, fuzzy
5138msgid "Network interface to monitor"
5139msgstr "Nätverksgränssnitt:"
5140
5141#: contrib/config-daemon.scm:1445
5142msgid ""
5143"For which interfaces should we do accounting? GNUnet will evaluate the "
5144"total traffic (not only the GNUnet related traffic) and adjust its bandwidth "
5145"usage accordingly. You can currently only specify a single interface. GNUnet "
5146"will also use this interface to determine the IP to use. Typical values are "
5147"eth0, ppp0, eth1, wlan0, etc. 'ifconfig' will tell you what you have. "
5148"Never use 'lo', that just won't work. Under Windows, specify the index "
5149"number reported by 'gnunet-win-tool -n'."
5150msgstr ""
5151
5152#: contrib/config-daemon.scm:1456
5153msgid "Load management"
5154msgstr ""
5155
5156#: contrib/config-daemon.scm:1482 contrib/config-client.scm:413
5157msgid "Root node"
5158msgstr ""
5159
5160#: contrib/config-client.scm:153
5161msgid "Where should gnunet-clients write their logs?"
5162msgstr ""
5163
5164#: contrib/config-client.scm:185
5165msgid "On which machine and port is gnunetd running (for clients)?"
5166msgstr ""
5167
5168#: contrib/config-client.scm:186
5169msgid "This is equivalent to the -H option. The format is IP:PORT."
5170msgstr ""
5171
5172#: contrib/config-client.scm:197
5173#, fuzzy
5174msgid "What is the path to the configuration file for gnunetd?"
5175msgstr "skriv ut ett värde från konfigurationsfilen till standard ut"
5176
5177#: contrib/config-client.scm:198
5178msgid "This option is used when clients need to start gnunetd."
5179msgstr ""
5180
5181#: contrib/config-client.scm:210
5182#, fuzzy
5183msgid "General options"
5184msgstr "Visa alla alternativ"
5185
5186#: contrib/config-client.scm:227
5187msgid "Do not add metadata listing the creation time for inserted content"
5188msgstr ""
5189
5190#: contrib/config-client.scm:239
5191msgid "Which non-default extractors should GNUnet use for keyword extractors"
5192msgstr ""
5193
5194#: contrib/config-client.scm:240
5195msgid ""
5196"Specify which additional extractor libraries should be used. gnunet-insert "
5197"uses libextractor to extract keywords from files. libextractor can be "
5198"dynamically extended to handle additional file formats. If you want to use "
5199"more than the default set of extractors, specify additional extractor "
5200"libraries here. The format is [[-]LIBRARYNAME[:[-]LIBRARYNAME]*].\n"
5201"\n"
5202"The default is to use filenames and to break larger words at spaces (and "
5203"underscores, etc.). This should be just fine for most people. The '-' "
5204"before a library name indicates that this should be executed last and makes "
5205"only sense for the split-library."
5206msgstr ""
5207
5208#: contrib/config-client.scm:253
5209msgid "How many entries should the URI DB table have?"
5210msgstr ""
5211
5212#: contrib/config-client.scm:254
5213msgid ""
5214"GNUnet uses two bytes per entry on the disk. This database is used to keep "
5215"track of how a particular URI has been used in the past. For example, "
5216"GNUnet may remember that a particular URI has been found in a search "
5217"previously or corresponds to a file uploaded by the user. This information "
5218"can then be used by user-interfaces to filter URI lists, such as search "
5219"results. If the database is full, older entries will be discarded. The "
5220"default value should be sufficient without causing undue disk utilization."
5221msgstr ""
5222
5223#: contrib/config-client.scm:265
5224msgid "Location of the file specifying metadata for the auto-share directory"
5225msgstr ""
5226
5227#: contrib/config-client.scm:277
5228msgid ""
5229"Location of the file with the PID of any running gnunet-auto-share daemon "
5230"process"
5231msgstr ""
5232
5233#: contrib/config-client.scm:289
5234msgid "Location of the log file for gnunet-auto-share"
5235msgstr ""
5236
5237#: contrib/config-client.scm:301
5238#, fuzzy
5239msgid "File-Sharing options"
5240msgstr "Visa alla alternativ"
5241
5242#: contrib/config-client.scm:319
5243msgid "Which plugins should be loaded by gnunet-gtk?"
5244msgstr ""
5245
5246#: contrib/config-client.scm:320
5247msgid ""
5248"Load the about plugin for the about dialog. The daemon plugin allows "
5249"starting and stopping of gnunetd and displays information about gnunetd. "
5250"The fs plugin provides the file-sharing functionality. The stats plugin "
5251"displays various statistics about gnunetd."
5252msgstr ""
5253
5254#: contrib/config-client.scm:331
5255msgid "How frequently (in milli-seconds) should the statistics update?"
5256msgstr ""
5257
5258#: contrib/config-client.scm:332
5259msgid ""
5260"Each pixel in the stats dialog corresponds to the time interval specified "
5261"here."
5262msgstr ""
5263
5264#: contrib/config-client.scm:344
5265msgid "Do not show thumbnail previews from meta-data in search results"
5266msgstr ""
5267
5268#: contrib/config-client.scm:345
5269msgid ""
5270"This option is useful for people who maybe offended by some previews or use "
5271"gnunet-gtk at work and would like to avoid bad surprises."
5272msgstr ""
5273
5274#: contrib/config-client.scm:356
5275msgid "Do not show search results for files that were uploaded by us"
5276msgstr ""
5277
5278#: contrib/config-client.scm:357
5279msgid ""
5280"This option is useful to eliminate files that the user already has from the "
5281"search. Naturally, enabling this option maybe confusing because some "
5282"obviously expected search results would no longer show up. This option only "
5283"works if the URI_DB_SIZE option under FS is not zero (since the URI DB is "
5284"used to determine which files the user is sharing)"
5285msgstr ""
5286
5287#: contrib/config-client.scm:369
5288msgid "To which directory should gnunet-gtk save downloads to?"
5289msgstr ""
5290
5291#: contrib/config-client.scm:381
5292#, fuzzy
5293msgid "Options related to gnunet-gtk"
5294msgstr "Ej ansluten till gnunetd."
5295
5296#: contrib/config-client.scm:401
5297msgid "Full pathname of GNUnet client HOME directory"
5298msgstr ""
5299
5300#: contrib/config-client.scm:402
5301msgid "The directory for GNUnet files that belong to the user."
5302msgstr ""
5303
5304#~ msgid "`%s' failed (%d, %u). Will not send PING.\n"
5305#~ msgstr "\"%s\" misslyckades (%d, %u). Kommer inte skicka PING.\n"
5306
5307#~ msgid "Invalid URL `%s' (must begin with `%s')\n"
5308#~ msgstr "Ogiltig URL \"%s\" (måste börja med \"%s\")\n"
5309
5310#~ msgid "`%s' to `%s' failed at %s:%d with error: %s\n"
5311#~ msgstr "\"%s\" till \"%s\" misslyckades vid %s:%d med fel: %s\n"
5312
5313#~ msgid "Parsing HTTP response for URL `%s' failed.\n"
5314#~ msgstr "Tolkning av HTTP-svar för URL \"%s\" misslyckades.\n"
5315
5316#~ msgid "Could not resolve name of HTTP proxy `%s'. Trying without a proxy.\n"
5317#~ msgstr ""
5318#~ "Kunde inte slå upp namn för HTTP-proxy \"%s\". Försöker utan proxy.\n"
5319
5320#~ msgid "Message received from client is invalid\n"
5321#~ msgstr "Meddelande mottaget från klient är ogiltig.\n"
5322
5323#~ msgid "Maximum number of chat clients reached.\n"
5324#~ msgstr "Maximalt antal chattklienter uppnått.\n"
5325
5326#~ msgid "Now %d of %d chat clients at this node.\n"
5327#~ msgstr "Nu är det %d av %d chattklienter på den här noden.\n"
5328
5329#~ msgid "specify nickname"
5330#~ msgstr "ange smeknamn"
5331
5332#~ msgid "Start GNUnet chat client."
5333#~ msgstr "Starta GNUnets chattklient."
5334
5335#~ msgid "Could not connect to gnunetd.\n"
5336#~ msgstr "Kunde inte ansluta till gnunetd.\n"
5337
5338#~ msgid "You must specify a nickname (use option `%s').\n"
5339#~ msgstr "Du måste ange ett smeknamn (använd flagga \"%s\").\n"
5340
5341#~ msgid "Could not send message to gnunetd\n"
5342#~ msgstr "Kunde inte skicka meddelande till gnunetd\n"
5343
5344#~ msgid "Database failed to delete `%s'.\n"
5345#~ msgstr "Databas misslyckades att ta bort \"%s\".\n"
5346
5347#~ msgid "`%s' failed: table not found!\n"
5348#~ msgstr "\"%s\" misslyckades: tabell hittades inte!\n"
5349
5350#~ msgid "`%s' failed. Terminating connection to client.\n"
5351#~ msgstr "\"%s\" misslyckades. Terminerar anslutning till klient.\n"
5352
5353#~ msgid "sendAck failed. Terminating connection to client.\n"
5354#~ msgstr "sendAck misslyckades. Terminerar anslutning till klient.\n"
5355
5356#~ msgid "Could not find peer `%s' in routing table!\n"
5357#~ msgstr "Kunde inte hitta motpart \"%s\" i routingtabell!\n"
5358
5359#~ msgid "`%s' called with timeout above 1 hour (bug?)\n"
5360#~ msgstr "\"%s\" anropad med timeout över 1 timma (fel?)\n"
5361
5362#~ msgid "Invalid response to `%s' from `%s'\n"
5363#~ msgstr "Ogiltigt svar till \"%s\" från \"%s\"\n"
5364
5365#~ msgid "Received invalid RPC `%s'.\n"
5366#~ msgstr "Mottog ogiltig RPC \"%s\".\n"
5367
5368#~ msgid "allow SIZE bytes of memory for the local table"
5369#~ msgstr "tillåt STORLEK byte av minne för lokaltabellen"
5370
5371#~ msgid "Superflous arguments (ignored).\n"
5372#~ msgstr "Onödiga argument (ignorerade).\n"
5373
5374#~ msgid "Call to `%s' returns %d.\n"
5375#~ msgstr "Anrop till \"%s\" returnerade %d.\n"
5376
5377#~ msgid "Call to `%s' with key `%s'.\n"
5378#~ msgstr "Anrop till \"%s\" med nyckel \"%s\".\n"
5379
5380#~ msgid "Call to `%s' with value '%.*s' (%d bytes).\n"
5381#~ msgstr "Anrop till \"%s\" med värde \"%.*s\" (%d byte).\n"
5382
5383#~ msgid "Error leaving DHT.\n"
5384#~ msgstr "Fel vid lämning av DHT.\n"
5385
5386#~ msgid "query table called NAME"
5387#~ msgstr "fråga tabell kallad NAME"
5388
5389#~ msgid "No commands specified.\n"
5390#~ msgstr "Inga kommandon angivna.\n"
5391
5392#~ msgid "'%s(%s,%s)' succeeded\n"
5393#~ msgstr "\"%s(%s,%s)\" lyckades\n"
5394
5395#~ msgid "Failed to send `%s'. Closing connection.\n"
5396#~ msgstr "Misslyckades att skicka \"%s\". Stänger anslutning.\n"
5397
5398#~ msgid "Received invalid `%s' request (size %d)\n"
5399#~ msgstr "Mottog ogiltig \"%s\" begäran (storlek %d)\n"
5400
5401#~ msgid "Received invalid `%s' request (wrong table)\n"
5402#~ msgstr "Mottog ogiltig \"%s\" begäran (fel tabell)\n"
5403
5404#~ msgid "Received unknown request type %d at %s:%d\n"
5405#~ msgstr "Mottog okänd typ av begäran %d vid %s:%d\n"
5406
5407#~ msgid "gnunetd signaled error in response to `%s' message\n"
5408#~ msgstr "gnunetd signalerade fel i svar till \"%s\" meddelande\n"
5409
5410#~ msgid "Failed to receive response to `%s' message from gnunetd\n"
5411#~ msgstr "Misslyckades att ta emot svar till \"%s\" meddelande från gnunetd\n"
5412
5413#~ msgid "Failed to send `%s' message to gnunetd\n"
5414#~ msgstr "Misslyckades att skicka \"%s\" meddelande till gnunetd\n"
5415
5416#~ msgid "Unexpected reply to `%s' operation.\n"
5417#~ msgstr "Oväntat svar till \"%s\" operation.\n"
5418
5419#~ msgid "Waiting for gnunetd to start (%u iterations left)...\n"
5420#~ msgstr "Väntar på att gnunetd ska starta (%u iterationer kvar)...\n"
5421
5422#~ msgid "Write(%d, %p, %d) failed: %s\n"
5423#~ msgstr "Skrivning(%d, %p, %d) misslyckades: %s\n"
5424
5425#~ msgid "Cannot create pseudonym `%s', file `%s' exists.\n"
5426#~ msgstr "Kan inte skapa pseudonym \"%s\", filen \"%s\" existerar.\n"
5427
5428#~ msgid "AND"
5429#~ msgstr "OCH"
5430
5431#~ msgid "Publication interval for periodic publication changed."
5432#~ msgstr "Publiseringsintervall för periodisk publisering har ändrats."
5433
5434#~ msgid "Unindex failed."
5435#~ msgstr "Avindexering misslyckades."
5436
5437#~ msgid ""
5438#~ "You must specify a postive number for `%s' in the configuration in "
5439#~ "section `%s'.\n"
5440#~ msgstr ""
5441#~ "Du måste ange ett positivt nummer för \"%s\" i konfigurationen i sektion "
5442#~ "\"%s\".\n"
5443
5444#~ msgid "Indexed file disappeared, deleting block for query `%s'\n"
5445#~ msgstr "Indexerad fil försvann, tar bort block för fråga \"%s\"\n"
5446
5447#~ msgid "%8u of %8u bytes deleted."
5448#~ msgstr "%8u av %8u byte togs bort."
5449
5450#~ msgid "specify the file to delete from GNUnet (obligatory, file must exist)"
5451#~ msgstr ""
5452#~ "ange filen att ta bort från GNUnet (obligatorisk, filen måste existera)"
5453
5454#~ msgid ""
5455#~ "Remove file from GNUnet. The specified file is not removed\n"
5456#~ "from the filesystem but just from the local GNUnet datastore."
5457#~ msgstr ""
5458#~ "Ta bort fil från GNUnet. Den angivna filen tas inte bort från\n"
5459#~ "filsystemet utan bara från det lokala GNUnet-datalagret."
5460
5461#~ msgid "You must specify a filename (option -f)\n"
5462#~ msgstr "Du måste ange ett filnamn (flagga -f)\n"
5463
5464#~ msgid "gnunet-directory [OPTIONS] [FILENAMES]"
5465#~ msgstr "gnunet-directory [FLAGGOR] [FILNAMN]"
5466
5467#~ msgid "LEVEL"
5468#~ msgstr "NIVÃ…"
5469
5470#~ msgid "FILENAME"
5471#~ msgstr "FILNAMN"
5472
5473#~ msgid "process directories recursively"
5474#~ msgstr "bearbeta kataloger rekursivt"
5475
5476#~ msgid "You must specify a list of files to insert.\n"
5477#~ msgstr "Du måste ange en lista av filer att lägga in.\n"
5478
5479#~ msgid "Only one file or directory can be specified at a time.\n"
5480#~ msgstr "Endast en fil eller katalog kan anges samtidigt.\n"
5481
5482#~ msgid "You must specify a file or directory to upload.\n"
5483#~ msgstr "Du måste ange en fil eller katalog att ladda upp.\n"
5484
5485#~ msgid "Invalid arguments. Exiting.\n"
5486#~ msgstr "Ogiltiga argument. Avslutar.\n"
5487
5488#~ msgid "Not enough arguments. You must specify a keyword or identifier.\n"
5489#~ msgstr ""
5490#~ "Inte tillräckligt med argument. Du måste ange ett nyckelord eller "
5491#~ "identifierare.\n"
5492
5493#~ msgid "`%s' registering handlers %d %d\n"
5494#~ msgstr "\"%s\" registrerar handtag %d %d\n"
5495
5496#~ msgid ""
5497#~ "Configuration file must specify a directory for GNUnet to store per-peer "
5498#~ "data under %s%s\n"
5499#~ msgstr ""
5500#~ "Konfigurationsfil måste ange en katalog för GNUnet att lagra motpartsdata "
5501#~ "under %s%s\n"
5502
5503#~ msgid "Could not create hostkey!\n"
5504#~ msgstr "Kunde inte skapa värdnyckel!\n"
5505
5506#~ msgid "%s `%s' returned no known hosts!\n"
5507#~ msgstr "%s \"%s\" returnerade inga kända värdar!\n"
5508
5509#~ msgid "Trying to use file `%s' for MySQL configuration.\n"
5510#~ msgstr "Försöker använda fil \"%s\" för MySQL-konfiguration.\n"
5511
5512#~ msgid "Could not initialize libgnunetutil!\n"
5513#~ msgstr "Kunde inte initiera libgnunetutil!\n"
5514
5515#~ msgid "helptext for -t"
5516#~ msgstr "hjälptext för -t"
5517
5518#~ msgid "Template for gnunet-clients."
5519#~ msgstr "Mall för gnunet-clients."
5520
5521#~ msgid "Start GNUnet-testbed helper."
5522#~ msgstr "Starta hjälpprogrammet GNUnet-testbed."
5523
5524#~ msgid "Command `%s' not found!\n"
5525#~ msgstr "Kommando \"%s\" hittades inte!\n"
5526
5527#~ msgid "size of `%s' message is too short. Ignoring.\n"
5528#~ msgstr "storlek på \"%s\" meddelande är för litet. Ignorerar.\n"
5529
5530#~ msgid "size of `%s' message is wrong. Ignoring.\n"
5531#~ msgstr "storlek på \"%s\" meddelande är fel. Ignorerar.\n"
5532
5533#~ msgid "received invalid `%s' message\n"
5534#~ msgstr "mottog ogiltigt \"%s\" meddelande\n"
5535
5536#~ msgid "received invalid `%s' message: %s.\n"
5537#~ msgstr "mottog ogiltigt \"%s\" meddelande: %s.\n"
5538
5539#~ msgid "'..' is not allowed in file name (%s).\n"
5540#~ msgstr "\"..\" tillåts inte i filnamn (%s).\n"
5541
5542#~ msgid "Invalid message received at %s:%d."
5543#~ msgstr "Ogiltigt meddelande mottogs den %s:%d."
5544
5545#~ msgid "Could not resolve name of HTTP proxy `%s'.\n"
5546#~ msgstr "Kunde inte slå upp namn för HTTP-proxy \"%s\".\n"
5547
5548#~ msgid "Failed to send HTTP request to host `%s': %s\n"
5549#~ msgstr "Misslyckades att skicka HTTP-begäran till värd \"%s\": %s\n"
5550
5551#~ msgid "Failed so send HTTP request `%s' to host `%s': %s\n"
5552#~ msgstr "Misslyckades att skicka HTTP-begäran \"%s\" till värd \"%s\": %s\n"
5553
5554#~ msgid "Peer `%s' did not report back.\n"
5555#~ msgstr "Motpart \"%s\" rapporterade inte tillbaka.\n"
5556
5557#~ msgid "Could not send request to gnunetd.\n"
5558#~ msgstr "Kunde inte skicka begäran till gnunetd.\n"
5559
5560#~ msgid "%s: symbol value `%s' invalid for %s\n"
5561#~ msgstr "%s: symbolvärde \"%s\" ogiltigt för %s\n"
5562
5563#~ msgid "Sorry, no help is available for this option.\n"
5564#~ msgstr "Tyvärr, ingen hjälp är tillgänglig för den här flaggan.\n"
5565
5566#~ msgid "_File"
5567#~ msgstr "_Fil"
5568
5569#~ msgid "_Load"
5570#~ msgstr "_Läs in"
5571
5572#~ msgid "Load a config file"
5573#~ msgstr "Läs in en konfigurationsfil"
5574
5575#~ msgid "_Save"
5576#~ msgstr "_Spara"
5577
5578#~ msgid "Save the config in .config"
5579#~ msgstr "Spara konfigurationen i .config"
5580
5581#~ msgid "_Quit"
5582#~ msgstr "_Avsluta"
5583
5584#~ msgid "Show _name"
5585#~ msgstr "Visa _namn"
5586
5587#~ msgid "Show _range"
5588#~ msgstr "Visa _omfång"
5589
5590#~ msgid "Show range (Y/M/N)"
5591#~ msgstr "Visa omfång (Y/M/N)"
5592
5593#~ msgid "Show _data"
5594#~ msgstr "Visa _data"
5595
5596#~ msgid "Show value of the option"
5597#~ msgstr "Visa värde av alternativet"
5598
5599#~ msgid "Show all _options"
5600#~ msgstr "Visa alla a_lternativ"
5601
5602#~ msgid "_Help"
5603#~ msgstr "_Hjälp"
5604
5605#~ msgid "_Introduction"
5606#~ msgstr "_Introduktion"
5607
5608#~ msgid "_License"
5609#~ msgstr "_Licens"
5610
5611#~ msgid "Goes up of one level (single view)"
5612#~ msgstr "Går upp en nivå (enkel vy)"
5613
5614#~ msgid "Load"
5615#~ msgstr "Läs in"
5616
5617#~ msgid "Save a config file"
5618#~ msgstr "Spara en konfigurationsfil"
5619
5620#~ msgid "Save"
5621#~ msgstr "Spara"
5622
5623#~ msgid "Single view"
5624#~ msgstr "Enkel vy"
5625
5626#~ msgid "Single"
5627#~ msgstr "Enkel"
5628
5629#~ msgid "Split view"
5630#~ msgstr "Dela vy"
5631
5632#~ msgid "Split"
5633#~ msgstr "Dela"
5634
5635#~ msgid "Full view"
5636#~ msgstr "Full vy"
5637
5638#~ msgid "Full"
5639#~ msgstr "Full"
5640
5641#~ msgid "Collapse"
5642#~ msgstr "Fäll in"
5643
5644#~ msgid "Expand"
5645#~ msgstr "Expandera"
5646
5647#~ msgid "Sorry, no help available for this option yet."
5648#~ msgstr "Tyvärr, ingen hjälp tillgänglig för den här flaggan ännu."
5649
5650#~ msgid "Couldn't find pixmap file: %s"
5651#~ msgstr "Kunde inte htta bildfil: %s"
5652
5653#~ msgid "Available MODEs:\n"
5654#~ msgstr "Tillgängliga lägen:\n"
5655
5656#~ msgid " config\t\ttext-based configuration\n"
5657#~ msgstr " config\t\ttextbaserad konfiguration\n"
5658
5659#~ msgid " menuconfig\ttext-based menu\n"
5660#~ msgstr " menuconfig\ttextbaserad meny\n"
5661
5662#~ msgid " wizard-curses\tBasic text-based graphical configuration\n"
5663#~ msgstr " wizard-curses\tEnkel textbaserad grafisk konfiguration\n"
5664
5665#~ msgid ""
5666#~ " wizard-gtk\tBasic GTK configuration\n"
5667#~ "\n"
5668#~ msgstr ""
5669#~ " wizard-gtk\tEnkel GTK-konfiguration\n"
5670#~ "\n"
5671
5672#~ msgid "gnunet-setup must have write-access to the configuration file `%s'\n"
5673#~ msgstr ""
5674#~ "gnunet-setup måste ha skrivrättighet till konfigurationsfilen \"%s\"\n"
5675
5676#~ msgid ""
5677#~ "Can only run wizard to configure gnunetd.\n"
5678#~ "Did you forget the `%s' option?\n"
5679#~ msgstr ""
5680#~ "Kan endast köra vägvisaren för att konfigurera gnunetd.\n"
5681#~ "Glömde du flaggan \"%s\"?\n"
5682
5683#~ msgid ""
5684#~ "You can limit GNUnet's resource usage here.\n"
5685#~ "\n"
5686#~ "This is the percentage of processor time GNUnet is allowed to use."
5687#~ msgstr ""
5688#~ "Du kan begränsa GNUnets resursanvändning här.\n"
5689#~ "\n"
5690#~ "Det här är det procenttal som GNUnet tillåts använda av processortiden."
5691
5692#~ msgid ""
5693#~ "Welcome to GNUnet!\n"
5694#~ "\n"
5695#~ "This assistant will ask you a few basic questions in order to configure "
5696#~ "GNUnet.\n"
5697#~ "\n"
5698#~ "Please visit our homepage at\n"
5699#~ "\thttp://www.gnunet.org\n"
5700#~ "and join our community at\n"
5701#~ "\thttp://www.gnunet.org/drupal/\n"
5702#~ "\n"
5703#~ "Have a lot of fun,\n"
5704#~ "\n"
5705#~ "the GNUnet team"
5706#~ msgstr ""
5707#~ "Välkommen till GNUnet!\n"
5708#~ "\n"
5709#~ "Denna assistant kommer att fråga dig några enkla frågor för att "
5710#~ "konfigurera GNUnet.\n"
5711#~ "\n"
5712#~ "Besök på webbplats på\n"
5713#~ "\thttp://gnunet.org/\n"
5714#~ "och gå med i vår gemenskap på\n"
5715#~ "\thttp://www.gnunet.org/drupal/\n"
5716#~ "\n"
5717#~ "Ha det så kul,\n"
5718#~ "\n"
5719#~ "GNUnet-laget"
5720
5721#~ msgid "Next"
5722#~ msgstr "Nästa"
5723
5724#~ msgid "IP-Address/Hostname:"
5725#~ msgstr "IP-adress/Värdnamn:"
5726
5727#~ msgid "Bandwidth limitation"
5728#~ msgstr "Bandbreddsbegränsning"
5729
5730#~ msgid "Bandwidth sharing"
5731#~ msgstr "Bandbreddsdelning"
5732
5733#~ msgid "Max. CPU usage (%):"
5734#~ msgstr "Max. CPU-användning (%):"
5735
5736#~ msgid "CPU usage"
5737#~ msgstr "CPU-användning"
5738
5739#~ msgid "Finish"
5740#~ msgstr "Slutför"
5741
5742#~ msgid "Question"
5743#~ msgstr "Fråga"
5744
5745#~ msgid "Group:"
5746#~ msgstr "Grupp:"
5747
5748#~ msgid "User account:"
5749#~ msgstr "Användarkonto:"
5750
5751#~ msgid "gnunet-update failed!"
5752#~ msgstr "gnunet-update misslyckades!"
5753
5754#~ msgid "No applications defined in configuration!\n"
5755#~ msgstr "Inga applikationer definierade i konfiguration!\n"
5756
5757#~ msgid "No reply received within %llums.\n"
5758#~ msgstr "Inget svar mottaget inom %llums.\n"
5759
5760#~ msgid "You must specify a non-empty set of transports to test!\n"
5761#~ msgstr "Du måste ange en icke-tom uppsättning av transporter att testa!\n"
5762
5763#~ msgid ""
5764#~ "\n"
5765#~ "Exiting.\n"
5766#~ msgstr ""
5767#~ "\n"
5768#~ "Avslutar.\n"
5769
5770#~ msgid "Updated data for %d applications.\n"
5771#~ msgstr "Uppdaterade data för %d program.\n"
5772
5773#~ msgid "`%s' starting\n"
5774#~ msgstr "\"%s\" startar\n"
5775
5776#~ msgid "Invalid command-line arguments:\n"
5777#~ msgstr "Ogiltiga kommandoradsargument:\n"
5778
5779#~ msgid "Argument %d: `%s'\n"
5780#~ msgstr "Argument %d: \"%s\"\n"
5781
5782#~ msgid "%s: Rejected connection from blacklisted address %u.%u.%u.%u.\n"
5783#~ msgstr "%s: Vägrade anslutning från svartlistad adress %u.%u.%u.%u.\n"
5784
5785#~ msgid "HTTP: Could not determine my public IP address.\n"
5786#~ msgstr "HTTP: Kunde inte fastställa min publika IP-adress.\n"
5787
5788#~ msgid "Could not resolve name of SMTP server `%s': %s"
5789#~ msgstr "Kunde inte slå upp namnet för SMTP-server \"%s\": %s"
5790
5791#~ msgid ""
5792#~ "You must specify the name of a pipe for the SMTP transport in section `%"
5793#~ "s' under `%s'.\n"
5794#~ msgstr ""
5795#~ "Du måste ange ett namn på röret för SMTP-transporten i sektion \"%s\" "
5796#~ "under \"%s\".\n"
5797
5798#~ msgid "Sending E-mail to `%s' failed.\n"
5799#~ msgstr "Sändning av e-post till \"%s\" misslyckades.\n"
5800
5801#~ msgid "%.*s filter %s (SMTP)"
5802#~ msgstr "%.*s filter %s (SMTP)"
5803
5804#~ msgid "Could not determine my public IPv6 address.\n"
5805#~ msgstr "Kunde inte fastställa min publika IPv6-adress.\n"
5806
5807#~ msgid "`%s': unknown service: %s\n"
5808#~ msgstr "\"%s\": okänd tjänst: %s\n"
5809
5810#~ msgid "Failed to bind to UDP6 port %d.\n"
5811#~ msgstr "Misslyckades att binda till UDP6-port %d.\n"
5812
5813#~ msgid "Configuration file `%s' not found. Run gnunet-setup!\n"
5814#~ msgstr "Konfigurationsfil \"%s\" hittades inte. Kör gnunet-setup!\n"
5815
5816#~ msgid ""
5817#~ "Configuration file not found. Please run GNUnet Setup (Client "
5818#~ "Configuration) first."
5819#~ msgstr ""
5820#~ "Konfigurationsfil hittades inte. Vänligen kör konfigurationen för GNUnet "
5821#~ "(klientkonfiguration) först."
5822
5823#~ msgid "Configuration file `%s' not found. Run `gnunet-setup -d'!\n"
5824#~ msgstr "Konfigurationsfil \"%s\" hittades inte. Kör \"gnunet-setup -d\"!\n"
5825
5826#~ msgid "Cron stopped\n"
5827#~ msgstr "Cron stoppad\n"
5828
5829#~ msgid "Shutdown complete.\n"
5830#~ msgstr "Nedstängning klar.\n"
5831
5832#~ msgid "Caught signal %d.\n"
5833#~ msgstr "FÃ¥ngade signal %d.\n"
5834
5835#~ msgid "Invalid network notation (additional characters: `%s')."
5836#~ msgstr "Ogiltig nätverksnotation (ytterligare tecken: \"%s\")."
5837
5838#~ msgid "FAILURE"
5839#~ msgstr "MISSLYCKANDE"
5840
5841#~ msgid "MESSAGE"
5842#~ msgstr "MEDDELANDE"
5843
5844#~ msgid "CRON"
5845#~ msgstr "CRON"
5846
5847#~ msgid "EVERYTHING"
5848#~ msgstr "ALLT"
5849
5850#~ msgid "Invalid LOGLEVEL `%s' specified.\n"
5851#~ msgstr "Ogiltig LOGGNIVÃ… \"%s\" angiven.\n"
5852
5853#~ msgid ""
5854#~ "Usage: %s\n"
5855#~ "%s\n"
5856#~ "\n"
5857#~ msgstr ""
5858#~ "Användning: %s\n"
5859#~ "%s\n"
5860#~ "\n"
5861
5862#~ msgid ""
5863#~ "Configuration file must specify a directory for GNUnet to store per-peer "
5864#~ "data under %s\\%s.\n"
5865#~ msgstr ""
5866#~ "Konfigurationsfil måste ange en katalog för GNUnet att lagra motpartsdata "
5867#~ "under %s\\%s.\n"
5868
5869#~ msgid "`%s' is not a regular file.\n"
5870#~ msgstr "\"%s\" är inte en vanlig fil.\n"
5871
5872#~ msgid "g"
5873#~ msgstr "g"
5874
5875#~ msgid "t"
5876#~ msgstr "t"
5877
5878#~ msgid "`%s' failed, other side closed connection.\n"
5879#~ msgstr "\"%s\" misslyckades, andra sidan har stängt anslutningen.\n"
5880
5881#~ msgid "Attempted path to `%s' was `%s'.\n"
5882#~ msgstr "Försökt sökväg till \"%s\" var \"%s\".\n"
5883
5884#~ msgid "set verbosity to LEVEL"
5885#~ msgstr "sätt informationsnivå till NIVÅ"
diff --git a/po/update.pl b/po/update.pl
new file mode 100644
index 000000000..c7c34b612
--- /dev/null
+++ b/po/update.pl
@@ -0,0 +1,230 @@
1#!/usr/bin/perl -w
2
3# GNOME po update utility.
4# (C) 2000 The Free Software Foundation
5#
6# Author(s): Kenneth Christiansen
7# Patches: Björn Voigt <bjoern@cs.tu-berlin.de>
8
9
10$VERSION = "1.2.5 beta 2";
11$LANG = $ARGV[0];
12$PACKAGE = "GNUnet";
13
14if (! $LANG){
15 print "update.pl: missing file arguments\n";
16 print "Try `update.pl --help' for more information.\n";
17 exit;
18}
19
20if ($LANG=~/^-(.)*/){
21
22 if ("$LANG" eq "--version" || "$LANG" eq "-V"){
23 print "GNOME PO Updater $VERSION\n";
24 print "Written by Kenneth Christiansen <kenneth\@gnome.org>, 2000.\n\n";
25 print "Copyright (C) 2000 Free Software Foundation, Inc.\n";
26 print "This is free software; see the source for copying conditions. There is NO\n";
27 print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
28 exit;
29 }
30
31
32 elsif ($LANG eq "--help" || "$LANG" eq "-H"){
33 print "Usage: ./update.pl [OPTIONS] ...LANGCODE\n";
34 print "Updates pot files and merge them with the translations.\n\n";
35 print " -V, --version shows the version\n";
36 print " -H, --help shows this help page\n";
37 print " -P, --pot only generates the potfile\n";
38 print " -M, --maintain search for missing files in POTFILES.in\n";
39 print "\nExamples of use:\n";
40 print "update.sh --pot just creates a new pot file from the source\n";
41 print "update.sh da created new pot file and updated the da.po file\n\n";
42 print "Report bugs to <kenneth\@gnome.org>.\n";
43 exit;
44 }
45
46 elsif($LANG eq "--pot" || "$LANG" eq "-P"){
47
48 print "Building the $PACKAGE.pot ...";
49
50 $b="xgettext --default-domain\=$PACKAGE --directory\=\.\."
51 ." --add-comments --keyword\=\_ --keyword\=N\_"
52 ." --files-from\=\.\/POTFILES\.in ";
53 $b1="test \! -f $PACKAGE\.po \|\| \( rm -f \.\/$PACKAGE\.pot "
54 ."&& mv $PACKAGE\.po \.\/$PACKAGE\.pot \)";
55 if(($ret=system($b . " && " . $b1))==0) {
56 print "...done\n";
57 }
58 else {
59 print "...failed\n";
60 }
61
62 exit $ret;
63 }
64
65 elsif ($LANG eq "--maintain" || "$LANG" eq "-M"){
66
67 $a="find ../ -path ../intl -prune -o -print | egrep '.*\\.(c|y|cc|c++|h|gob)\$' ";
68
69 open(BUF2, "POTFILES.in") || die "update.pl: there's not POTFILES.in!!!\n";
70 print "Searching for missing _(\" \") entries and for deleted files...\n";
71 open(BUF1, "$a|");
72
73
74 @buf2 = <BUF2>;
75 @buf1 = <BUF1>;
76
77 if (-s "POTFILES.ignore") {
78 open FILE, "POTFILES.ignore";
79 while (<FILE>) {
80 if ($_=~/^[^#]/o) {
81 push @bup, $_;
82 }
83 }
84 print "POTFILES.ignore found! Ignoring files...\n";
85 @buf2 = (@bup, @buf2);
86 }
87
88 foreach my $file (@buf1) {
89 $cmd="xgettext -o - --omit-header --keyword=_ " .
90 "--keyword=N_ " . $file . " |";
91 open XGET, $cmd;
92 if(<XGET>) {
93 $file = unpack("x3 A*",$file) . "\n";
94 push @buff1, $file;
95 }
96 close XGET;
97# open FILE, "<$file";
98# while (<FILE>) {
99# if ($_=~/_\(\"/o || $_=~/ngettext\(\"/o){
100# $file = unpack("x3 A*",$file) . "\n";
101# push @buff1, $file;
102# last;
103# }
104# }
105 }
106
107 @bufff1 = sort (@buff1);
108
109 @bufff2 = sort (@buf2);
110
111 my %in2;
112 foreach (@bufff2) {
113 chomp;
114 $in2{$_} = 1;
115 }
116
117 my %in1;
118 foreach (@bufff1) {
119 chomp;
120 $in1{$_} = 1;
121 }
122
123 foreach (@bufff1) {
124 chomp;
125 if (!exists($in2{$_})) {
126 push @result, $_ . "\n";
127 }
128 }
129
130 foreach (@bufff2) {
131 chomp;
132 if (! -f "../" . $_) {
133 push @deletedfiles, $_ . "\n";
134 }
135 }
136
137 foreach (@bufff2) {
138 if (!exists($in1{$_})) {
139 push @noi18nfiles, $_ . "\n";
140 }
141 }
142
143 if(@result){
144 open OUT, ">POTFILES.in.missing";
145 print OUT @result;
146 print "\nHere are the missing files:\n\n", @result, "\n";
147 print "File POTFILES.in.missing is being placed in directory...\n";
148 print "Please add the files that should be ignored in POTFILES.ignore\n";
149 }
150 else{
151 unlink("POTFILES.in.missing");
152 }
153
154 if(@deletedfiles){
155 open OUT, ">POTFILES.in.deleted";
156 print OUT @deletedfiles;
157 print "\nHere are the deleted files:\n\n", @deletedfiles, "\n";
158 print "File POTFILES.in.deleted is being placed in directory...\n";
159 print "Please delete the files from POTFILES.in or POTFILES.ignore\n";
160 }
161 else{
162 unlink("POTFILES.in.deleted");
163 }
164
165 if(@noi18nfiles){
166 open OUT, ">POTFILES.in.noi18n";
167 print OUT @noi18nfiles;
168 print "\nHere are the files which currently have no i18n strings:\n\n",
169 @noi18nfiles, "\n";
170 print "File POTFILES.in.noi18n is being placed in directory...\n";
171 print "Please delete the files from POTFILES.in or POTFILES.ignore\n";
172 print "or ignore the files.\n";
173 }
174 else{
175 unlink("POTFILES.in.noi18n");
176 }
177
178 if( ! @result && ! @deletedfiles ) {
179 print "\nWell, it's all perfect! Congratulation!\n";
180 }
181 }
182
183
184 else{
185 print "update.pl: invalid option -- $LANG\n";
186 print "Try `update.pl --help' for more information.\n";
187 }
188 exit;
189 }
190
191elsif(-s "$LANG.po"){
192
193 print "Building the $PACKAGE.pot ...";
194
195 $c="xgettext --default-domain\=$PACKAGE --directory\=\.\."
196 ." --add-comments --keyword\=\_ --keyword\=N\_"
197 ." --files-from\=\.\/POTFILES\.in ";
198 $c1="test \! -f $PACKAGE\.po \|\| \( rm -f \.\/$PACKAGE\.pot "
199 ."&& mv $PACKAGE\.po \.\/$PACKAGE\.pot \)";
200
201 if(($ret=system($c . " && " . $c1))==0) {
202 print "...done\n";
203 }
204 else {
205 print "...failed\n";
206 }
207
208 if($ret==0) {
209 print "\nNow merging $LANG.po with $PACKAGE.pot, and creating an updated $LANG.po ...\n";
210
211
212 $d="if msgmerge $LANG.po $PACKAGE.pot -o $LANG.new.po; then " .
213 " mv -f $LANG.new.po $LANG.po; " .
214 " msgfmt --statistics -c -v -o /dev/null $LANG.po; " .
215 "else " .
216 " echo \"msgmerge failed!\"; " .
217 " rm -f $LANG.new.po; ".
218 "fi";
219
220 $ret=system($d);
221
222 exit $ret;
223 }
224}
225
226else{
227 print "update.pl: sorry $LANG.po does not exist!\n";
228 print "Try `update.pl --help' for more information.\n";
229 exit;
230}
diff --git a/po/vi.gmo b/po/vi.gmo
new file mode 100644
index 000000000..9bd0b0088
--- /dev/null
+++ b/po/vi.gmo
Binary files differ
diff --git a/po/vi.po b/po/vi.po
new file mode 100644
index 000000000..2d9c3c3fc
--- /dev/null
+++ b/po/vi.po
@@ -0,0 +1,5772 @@
1# Vietnamese translation for GNUnet.
2# Copyright © 2008 Christian Grothoff (msgids).
3# This file is distributed under the same license as the gnunet package.
4# Phan Vinh Thinh <teppi82@gmail.com>, 2005.
5# Clytie Siddall <clytie@riverland.net.au>, 2008.
6#
7msgid ""
8msgstr ""
9"Project-Id-Version: gnunet 0.8.0a\n"
10"Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n"
11"POT-Creation-Date: 2009-01-08 10:55-0700\n"
12"PO-Revision-Date: 2008-09-10 22:05+0930\n"
13"Last-Translator: Clytie Siddall <clytie@riverland.net.au>\n"
14"Language-Team: Vietnamese <vi-VN@googlegroups.com>\n"
15"MIME-Version: 1.0\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=1; plural=0;\n"
19"X-Generator: LocFactoryEditor 1.7b3\n"
20
21#: src/setup/ncurses/wizard_curs.c:72 src/setup/lib/wizard_util.c:155
22#: src/setup/lib/wizard_util.c:210
23msgid "Error"
24msgstr "Lá»—i"
25
26#: src/setup/ncurses/wizard_curs.c:80
27msgid "Help"
28msgstr "Trợ giúp"
29
30#: src/setup/ncurses/wizard_curs.c:87
31msgid "Error!"
32msgstr "Lá»—i !"
33
34#: src/setup/ncurses/wizard_curs.c:101 src/applications/vpn/cs.c:94
35msgid "No"
36msgstr "Không"
37
38#: src/setup/ncurses/wizard_curs.c:102 src/applications/vpn/cs.c:94
39msgid "Yes"
40msgstr "Có"
41
42#: src/setup/ncurses/wizard_curs.c:118 src/setup/ncurses/wizard_curs.c:183
43#: src/setup/ncurses/wizard_curs.c:299 src/setup/ncurses/mconf.c:189
44#: src/setup/ncurses/mconf.c:285 src/setup/ncurses/mconf.c:365
45#: src/setup/ncurses/mconf.c:456
46msgid "Internal error! (Choice invalid?)"
47msgstr "Lá»—i ná»™i bá»™ (sai chá»n ?)"
48
49#: src/setup/ncurses/wizard_curs.c:150
50msgid "Abort"
51msgstr "Hủy"
52
53#: src/setup/ncurses/wizard_curs.c:151
54msgid "Ok"
55msgstr "OK"
56
57#: src/setup/ncurses/wizard_curs.c:218 src/setup/ncurses/wizard_curs.c:284
58#: src/setup/ncurses/wizard_curs.c:425
59msgid "GNUnet configuration"
60msgstr "Cấu hình GNUnet"
61
62#: src/setup/ncurses/wizard_curs.c:220
63msgid ""
64"Welcome to GNUnet!\n"
65"\n"
66"This assistant will ask you a few basic questions in order to configure "
67"GNUnet.\n"
68"\n"
69"Please visit our homepage at\n"
70"\thttp://gnunet.org/\n"
71"and join our community at\n"
72"\thttp://gnunet.org/drupal/\n"
73"\n"
74"Have a lot of fun,\n"
75"\n"
76"the GNUnet team"
77msgstr ""
78"Xin chào mừng tới GNUnet !\n"
79"\n"
80"Trình giúp đỡ này sẽ há»i bạn vài câu cÆ¡ bản để cấu hình GNUnet.\n"
81"\n"
82"Xin hãy thăm trang chủ của chúng tôi tại\n"
83"\thttp://gnunet.org\n"
84"và tham gia cộng đồng tại\n"
85"\thttp://www.gnunet.org/drupal/\n"
86"\n"
87"Chúc có nhiá»u niá»m vui,\n"
88"\n"
89"Ä‘á»™i GNUnet"
90
91#: src/setup/ncurses/wizard_curs.c:286
92msgid ""
93"Choose the network interface that connects your computer to the internet "
94"from the list below."
95msgstr ""
96"Chá»n giao diện mạng kết nối máy tính tá»›i Internet từ danh sách dÆ°á»›i đây."
97
98#: src/setup/ncurses/wizard_curs.c:304 src/setup/ncurses/wizard_curs.c:318
99msgid ""
100"The \"Network interface\" is the device that connects your computer to the "
101"internet. This is usually a modem, an ISDN card or a network card in case "
102"you are using DSL."
103msgstr ""
104"« Giao diện mạng » là thiết bị kết nối máy tính vá»›i Internet. Äây thÆ°á»ng là "
105"má»™t bá»™ Ä‘iá»u giải, má»™t bo mạch ISDN hay má»™t bo mạch mạng nếu dùng DSL."
106
107#: src/setup/ncurses/wizard_curs.c:315
108msgid "Network configuration: interface"
109msgstr "Cấu hình mạng: giao diện"
110
111#: src/setup/ncurses/wizard_curs.c:317
112msgid ""
113"What is the name of the network interface that connects your computer to the "
114"Internet?"
115msgstr "Máy tính này kết nối tới Internet qua giao diện mạng tên nào?"
116
117#: src/setup/ncurses/wizard_curs.c:328
118msgid "Network configuration: IP"
119msgstr "Cấu hình mạng: IP"
120
121#: src/setup/ncurses/wizard_curs.c:330
122msgid "What is this computer's public IP address or hostname?"
123msgstr "Äịa chỉ IP công cá»™ng hoặc tên của máy tính này là gì?"
124
125#: src/setup/ncurses/wizard_curs.c:331
126msgid ""
127"If your provider always assigns the same IP-Address to you (a \"static\" IP-"
128"Address), enter it into the \"IP-Address\" field. If your IP-Address changes "
129"every now and then (\"dynamic\" IP-Address) but there's a hostname that "
130"always points to your actual IP-Address (\"Dynamic DNS\"), you can also "
131"enter it here.\n"
132"If left empty, GNUnet will try to automatically detect the IP.\n"
133"You can specify a hostname, GNUnet will then use DNS to resolve it.\n"
134"If in doubt, leave this empty."
135msgstr ""
136"Nếu nhà cung cấp luôn luôn gán cùng một địa chỉ IP (một địa chỉ IP « tĩnh »), "
137"thì hãy nhập địa chỉ đó vào vùng « Äịa chỉ IP ». Nếu địa chỉ IP thay đổi sau "
138"mỗi lần kết nối (địa chỉ IP « động ») nhưng có một tên máy luôn luôn chỉ tới "
139"địa chỉ IP thực của bạn (« DNS động »), thì cũng có thể nhập nó ở đây.\n"
140"Nếu không biết phải làm gì, thì hãy để trống. GNUnet sẽ thử tự động phát "
141"hiện địa chỉ IP.\n"
142"Bạn cũng có thể ghi rõ tên máy. Vì thế GNUnet sẽ dùng dịch vụ DNS để giải "
143"quyết nó."
144
145#: src/setup/ncurses/wizard_curs.c:346
146msgid "Bandwidth configuration: upload"
147msgstr "Cấu hình dải thông: tải lên"
148
149#: src/setup/ncurses/wizard_curs.c:348
150msgid "How much upstream bandwidth (in bytes/s) may be used?"
151msgstr "Dòng ra có thể dùng bao nhiêu byte?"
152
153#: src/setup/ncurses/wizard_curs.c:349
154msgid ""
155"You can limit GNUnet's resource usage here.\n"
156"\n"
157"The \"upstream\" is the data channel through which data is *sent* to the "
158"internet. The limit is the maximum amount which GNUnet is allowed to use. If "
159"you have a flatrate, you can set it to the maximum speed of your internet "
160"connection. You should not use a value that is higher than what your actual "
161"connection allows."
162msgstr ""
163"Có thể giới hạn sử dụng tài nguyên của GNUnet ở đây.\n"
164"\n"
165"« Dòng ra » (upstream) là kênh dữ liệu qua đó _gửi_ dữ liệu tới Internet. "
166"Giá»›i hạn là số tối Ä‘a được gán cho GNUnet. Nếu có tốc Ä‘á»™ Ä‘á»u, thì có thể đặt "
167"thành tốc độ kết nối Internet lớn nhất. Không nên đặt giá trị lớn hơn số "
168"được gán cho kết nối Internet của bạn."
169
170#: src/setup/ncurses/wizard_curs.c:361
171msgid "Bandwidth configuration: download"
172msgstr "Cấu hình dải thông: tải xuống"
173
174#: src/setup/ncurses/wizard_curs.c:363
175msgid "How much downstream bandwidth (in bytes/s) may be used?"
176msgstr "Dòng vào có thể dùng bao nhiêu byte?"
177
178#: src/setup/ncurses/wizard_curs.c:364
179msgid ""
180"You can limit GNUnet's resource usage here.\n"
181"\n"
182"The \"downstream\" is the data channel through which data is *received* from "
183"the internet. The limit is the maximum amount which GNUnet is allowed to "
184"use. If you have a flatrate, you can set it to the maximum speed of your "
185"internet connection. You should not use a value that is higher than what "
186"your actual connection allows."
187msgstr ""
188"Có thể giới hạn sử dụng tài nguyên của GNUnet ở đây.\n"
189"\n"
190"« Dòng vào » (downstream) là kênh dữ liệu qua đó _nhận_ dữ liệu từ Internet. "
191"Giá»›i hạn là số tối Ä‘a được gán cho GNUnet. Nếu có tốc Ä‘á»™ Ä‘á»u, thì có thể đặt "
192"thành tốc độ kết nối Internet lớn nhất. Không nên đặt giá trị lớn hơn số "
193"được gán cho kết nối Internet của bạn."
194
195#: src/setup/ncurses/wizard_curs.c:376
196msgid "Quota configuration"
197msgstr "Cấu hình hạn ngạch"
198
199#: src/setup/ncurses/wizard_curs.c:377
200msgid "What is the maximum size of the datastore in MB?"
201msgstr "Kho dữ liệu có kích cỡ tối đa (theo MB)?"
202
203#: src/setup/ncurses/wizard_curs.c:378
204msgid ""
205"The GNUnet datastore contains all content that GNUnet needs to store "
206"(indexed, inserted and migrated content)."
207msgstr ""
208"Kho dữ liệu GNUnet chứa tất cả các dữ liệu GNUnet cần cất giữ (dữ liệu chỉ "
209"mục, nội dung chèn và nhập vào)."
210
211#: src/setup/ncurses/wizard_curs.c:390
212msgid "Daemon configuration: user account"
213msgstr "Cấu hình trình ná»n: tài khoản ngÆ°á»i dùng"
214
215#: src/setup/ncurses/wizard_curs.c:391
216msgid "As which user should gnunetd be run?"
217msgstr "Trình ná»n gnunetd nên chạy vá»›i tÆ° cách ngÆ°á»i dùng nào?"
218
219#: src/setup/ncurses/wizard_curs.c:393
220msgid ""
221"For security reasons, it is a good idea to let this setup create a new user "
222"account under which the GNUnet service is started at system startup.\n"
223"\n"
224"However, GNUnet may not be able to access files other than its own. This "
225"includes files you want to publish in GNUnet. You'll have to grant read "
226"permissions to the user specified below.\n"
227"\n"
228"Leave the field empty to run GNUnet with system privileges.\n"
229msgstr ""
230"Vì lý do bảo mật, nên cho phép thiết lập này tạo má»™t tài khoản ngÆ°á»i dùng "
231"mới sở hữu dịch vụ GNUnet chạy mỗi khi khởi động máy tính.\n"
232"\n"
233"Tuy nhiên, GNUnet có thể không truy cập được tới các tập tin mà nó không sở "
234"hữu, bao gồm các tập tin ngÆ°á»i dùng muốn Ä‘Æ°a ra chia sẻ trong GNUnet. Sẽ cần "
235"cho phép ngÆ°á»i dùng chỉ ra dÆ°á»›i đây quyá»n Ä‘á»c chúng.\n"
236"\n"
237"Äể trống để chạy GNUnet vá»›i quyá»n hệ thống.\n"
238
239#: src/setup/ncurses/wizard_curs.c:410
240msgid "Daemon configuration: group account"
241msgstr "Cấu hình trình ná»n: tài khoản nhóm"
242
243#: src/setup/ncurses/wizard_curs.c:411
244msgid "As which group should gnunetd be run?"
245msgstr "gnunetd nên chạy như nhóm nào?"
246
247#: src/setup/ncurses/wizard_curs.c:413
248msgid ""
249"For security reasons, it is a good idea to let this setup create a new group "
250"for the chosen user account.\n"
251"\n"
252"You can also specify a already existent group here.\n"
253"\n"
254"Only members of this group will be allowed to start and stop the the GNUnet "
255"server and have access to GNUnet server data.\n"
256msgstr ""
257"Vì lý do bảo mật, nên để thiết lập này tạo má»™t nhóm má»›i cho tài khoản ngÆ°á»i "
258"dùng đã chá»n\n"
259"\n"
260"Cũng có thể chỉ ra một nhóm đã có.\n"
261"\n"
262"Chỉ thành viên của nhóm này má»›i có quyá»n chạy và dừng trình phục vụ GNUnet "
263"và có truy cập tới dữ liệu của trình phục vụ GNUnet.\n"
264
265#: src/setup/ncurses/wizard_curs.c:427
266msgid "Do you want to automatically launch GNUnet as a system service?"
267msgstr "Bạn có muốn tự động khởi chạy GNUnet như là dịch vụ hệ thống không?"
268
269#: src/setup/ncurses/wizard_curs.c:429
270msgid ""
271"If you say \"yes\" here, the GNUnet background process will be automatically "
272"started when you turn on your computer. If you say \"no\" here, you have to "
273"launch GNUnet yourself each time you want to use it."
274msgstr ""
275"Bật tùy chá»n này thì tiến trình GNUnet ná»n được tá»± Ä‘á»™ng khởi chạy má»—i lần mở "
276"máy tính. Không thì bạn cần phải tự khởi chạy GNUnet mỗi lần để sử dụng nó."
277
278#: src/setup/ncurses/wizard_curs.c:452 src/setup/gtk/wizard_gtk.c:414
279#, c-format
280msgid "Unable to save configuration file `%s':"
281msgstr "Không thể lưu tập tin cấu hình « %s »:"
282
283#: src/setup/ncurses/wizard_curs.c:472
284msgid "Unable to create user account for daemon."
285msgstr "Không thể tạo tài khoản ngÆ°á»i dùng cho trình ná»n."
286
287#: src/setup/ncurses/wizard_curs.c:483
288msgid "Unable to setup autostart for daemon."
289msgstr "Không thể thiết lập chức năng tá»± Ä‘á»™ng khởi chạy cho trình ná»n."
290
291#: src/setup/ncurses/wizard_curs.c:498
292msgid "Save configuration?"
293msgstr "Lưu cấu hình không?"
294
295#: src/setup/ncurses/wizard_curs.c:499
296msgid "Save configuration now?"
297msgstr "Lưu cấu hình ngay bây giỠkhông?"
298
299#: src/setup/ncurses/wizard_curs.c:539 src/setup/ncurses/mconf.c:500
300msgid "GNUnet Configuration"
301msgstr "Cấu hình GNUnet"
302
303#: src/setup/ncurses/wizard_curs.c:543
304msgid "Back"
305msgstr "Lùi"
306
307#: src/setup/ncurses/mconf.c:96
308msgid "Exit"
309msgstr "Thoát"
310
311#: src/setup/ncurses/mconf.c:99
312msgid "Up"
313msgstr "Lên"
314
315#: src/setup/ncurses/mconf.c:102
316msgid "Cancel"
317msgstr "Thôi"
318
319#: src/setup/ncurses/mconf.c:221 src/setup/ncurses/mconf.c:408
320msgid "Internal error! (Value invalid?)"
321msgstr "Lỗi nội bộ (giá trị sai ?)"
322
323#: src/setup/ncurses/mconf.c:398
324msgid "Invalid input, expecting floating point value."
325msgstr "Dữ liệu nhập sai, mong đợi giá trị chấm động."
326
327#: src/setup/ncurses/mconf.c:439
328msgid "Invalid input, expecting integer."
329msgstr "Dữ liệu nhập sai, mong đợi số nguyên."
330
331#: src/setup/ncurses/mconf.c:446
332msgid "Value is not in legal range."
333msgstr "Giá trị không nằm trong phạm vi được phép."
334
335#: src/setup/ncurses/mconf.c:512 src/setup/text/conf.c:569
336#, c-format
337msgid "Configuration unchanged, no need to save.\n"
338msgstr "Cấu hình chưa thay đổi thì không cần lưu lại.\n"
339
340#: src/setup/ncurses/mconf.c:518
341msgid "Do you wish to save your new configuration?"
342msgstr "Bạn có muốn lưu cấu hình mới không?"
343
344#: src/setup/ncurses/mconf.c:532
345#, c-format
346msgid ""
347"\n"
348"End of configuration.\n"
349msgstr ""
350"\n"
351"Kết thúc cấu hình.\n"
352
353#: src/setup/ncurses/mconf.c:537
354#, c-format
355msgid ""
356"\n"
357"Your configuration changes were NOT saved.\n"
358msgstr ""
359"\n"
360"CHƯA lưu các thay đổi trong cấu hình.\n"
361
362#: src/setup/gnunet-win-tool.c:52
363msgid "list all network adapters"
364msgstr "liệt kê má»i bá»™ tiếp hợp mạng"
365
366#: src/setup/gnunet-win-tool.c:55
367msgid "install GNUnet as Windows service"
368msgstr "cài đặt GNUnet như là một dịch vụ Windows"
369
370#: src/setup/gnunet-win-tool.c:58
371msgid "uninstall GNUnet service"
372msgstr "hủy cài đặt dịch vụ GNUnet"
373
374#: src/setup/gnunet-win-tool.c:61
375msgid "increase the maximum number of TCP/IP connections"
376msgstr "tăng sổ tối đa các kết nối TCP/IP"
377
378#: src/setup/gnunet-win-tool.c:64
379msgid "display a file's hash value"
380msgstr "hiển thị giá trị tổng kiểm của tập tin"
381
382#: src/setup/gnunet-win-tool.c:125
383#, c-format
384msgid "GNUnet service installed successfully.\n"
385msgstr "Dịch vụ GNUnet đã được cài đặt.\n"
386
387#: src/setup/gnunet-win-tool.c:128 src/setup/gnunet-win-tool.c:156
388#, c-format
389msgid "This version of Windows doesn't support services.\n"
390msgstr "Phiên bản Windows này không hỗ trợ dịch vụ.\n"
391
392#: src/setup/gnunet-win-tool.c:132 src/setup/gnunet-win-tool.c:160
393#, c-format
394msgid "Error: can't open Service Control Manager: %s\n"
395msgstr "Lá»—i: không thể mở Bá»™ Quản lý Äiá»u khiển Dịch vụ : %s\n"
396
397#: src/setup/gnunet-win-tool.c:137
398#, c-format
399msgid "Error: can't create service: %s\n"
400msgstr "Lỗi: không thể tạo dịch vụ : %s\n"
401
402#: src/setup/gnunet-win-tool.c:140 src/setup/gnunet-win-tool.c:172
403#, c-format
404msgid "Unknown error.\n"
405msgstr "Lỗi không rõ.\n"
406
407#: src/setup/gnunet-win-tool.c:153
408#, c-format
409msgid "Service deleted.\n"
410msgstr "Dịch vụ đã bị xoá.\n"
411
412#: src/setup/gnunet-win-tool.c:165
413#, c-format
414msgid "Error: can't access service: %s\n"
415msgstr "Lỗi: không thể truy cập đến dịch vụ : %s\n"
416
417#: src/setup/gnunet-win-tool.c:169
418#, c-format
419msgid "Error: can't delete service: %s\n"
420msgstr "Lỗi: không thể xoá dịch vụ : %s\n"
421
422#: src/setup/gtk/ngconf.c:389
423msgid "Configuration saved."
424msgstr "Cấu hình đã được lưu."
425
426#: src/setup/gtk/ngconf.c:399
427msgid "Failed to save configuration."
428msgstr "Lỗi lưu cấu hình."
429
430#: src/setup/gtk/ngconf.c:424
431msgid "Configuration changed. Save?"
432msgstr "Cấu hình bị thay đổi. Lưu ?"
433
434#: src/setup/gtk/ngconf.c:437
435msgid "Error saving configuration."
436msgstr "Gặp lỗi khi lưu cấu hình."
437
438#: src/setup/gtk/wizard_gtk.c:141
439msgid "(unknown connection)"
440msgstr "(không rõ kết nối)"
441
442#: src/setup/gtk/wizard_gtk.c:438
443msgid "Do you want to save the new configuration?"
444msgstr "Bạn có muốn lưu cấu hình mới này không?"
445
446#: src/setup/gtk/wizard_gtk.c:470
447msgid "Unable to create user account:"
448msgstr "Không thể tạo tài khoản ngÆ°á»i dùng:"
449
450#: src/setup/gtk/wizard_gtk.c:480
451msgid "Unable to change startup process:"
452msgstr "Không thể thay đổi tiến trình khởi chạy:"
453
454#: src/setup/gtk/wizard_gtk.c:495
455msgid ""
456"Running gnunet-update failed.\n"
457"This maybe due to insufficient permissions, please check your "
458"configuration.\n"
459"Finally, run gnunet-update manually."
460msgstr ""
461"Lỗi chạy tiến trình cập nhật gnunet-update.\n"
462"Äây có thể do không đủ quyá»n, hãy kiểm tra cấu hình.\n"
463"Cuối cùng, chạy gnunet-update thủ công."
464
465#: src/setup/gnunet-setup.c:65
466#, c-format
467msgid "Can only set one option per invocation.\n"
468msgstr "Chỉ có thể đặt má»™t tùy chá»n trong má»—i cuá»™c gá»i.\n"
469
470#: src/setup/gnunet-setup.c:73
471#, c-format
472msgid ""
473"Invalid syntax, argument to 'set' must have the format SECTION:"
474"OPTION=VALUE.\n"
475msgstr ""
476"Cú pháp sai, đối số tới « set » phải theo định dạng:\n"
477"PHẦN:TÙY_CHỌN­=GIÃ_TRỊ\n"
478
479#: src/setup/gnunet-setup.c:87
480#, c-format
481msgid "Can only display one option per invocation.\n"
482msgstr "Chỉ có thể hiển thị má»™t tùy chá»n trong má»—i cuá»™c gá»i.\n"
483
484#: src/setup/gnunet-setup.c:94
485#, c-format
486msgid ""
487"Invalid syntax, argument to 'get' must have the format SECTION:OPTION.\n"
488msgstr ""
489"Cú pháp sai, đối số tới « get » phải theo định dạng:\n"
490"PHẦN:TÙY_CHỌN\n"
491
492#: src/setup/gnunet-setup.c:108
493msgid "generate configuration for gnunetd, the GNUnet daemon"
494msgstr "tạo ra cấu hình cho gnunetd, trình ná»n GNUnet"
495
496#: src/setup/gnunet-setup.c:111 src/setup/gnunet-setup.c:127
497#: src/server/gnunet-update.c:268
498msgid "print a value from the configuration file to stdout"
499msgstr "in ra đầu ra tiêu chuẩn một giá trị từ tập tin cấu hình"
500
501#: src/setup/gnunet-setup.c:113 src/setup/gnunet-setup.c:129
502msgid "Tool to setup GNUnet."
503msgstr "Công cụ để thiết lập GNUnet."
504
505#: src/setup/gnunet-setup.c:115 src/setup/gnunet-setup.c:131
506msgid "update a value in the configuration file"
507msgstr "cập nhật một giá trị trong tập tin cấu hình"
508
509#: src/setup/gnunet-setup.c:338
510#, c-format
511msgid "Too many arguments.\n"
512msgstr "Quá nhiá»u đối số.\n"
513
514#: src/setup/gnunet-setup.c:344
515msgid "No interface specified, using default.\n"
516msgstr "Chưa xác định giao diện nên dùng mặc định.\n"
517
518#: src/setup/gnunet-setup.c:392
519#, c-format
520msgid "Configuration file `%s' must be a filename (but is a directory).\n"
521msgstr ""
522
523#: src/setup/gnunet-setup.c:439
524#, c-format
525msgid "Undefined option.\n"
526msgstr "Tùy chá»n không xác định.\n"
527
528#: src/setup/gnunet-setup.c:496
529#, c-format
530msgid "`%s' is not available.\n"
531msgstr "« %s » không sẵn sàng.\n"
532
533#: src/setup/gnunet-setup.c:516
534#, c-format
535msgid "Unknown operation '%s'.\n"
536msgstr "Không rõ thao tác « %s ».\n"
537
538#: src/setup/gnunet-setup.c:517 src/util/getopt/getopt.c:1072
539#, c-format
540msgid "Use --help to get a list of options.\n"
541msgstr ""
542"Hãy sá»­ dụng câu lệnh trợ giúp « --help » để xem danh sách các tùy chá»n.\n"
543
544#: src/setup/text/conf.c:79
545msgid "yes"
546msgstr "có"
547
548#: src/setup/text/conf.c:80
549msgid "no"
550msgstr "không"
551
552#: src/setup/text/conf.c:106
553#, c-format
554msgid "\tEnter yes (%s), no (%s) or help (%s): "
555msgstr "\tNhập có (%s), không (%s) hoặc trợ giúp (%s): "
556
557#: src/setup/text/conf.c:115
558msgid "\tPossible choices:\n"
559msgstr "\tLá»±a chá»n có thể:\n"
560
561#: src/setup/text/conf.c:123
562msgid "\tUse single space prefix to avoid conflicts with hotkeys!\n"
563msgstr "\tHãy dùng tiá»n tố má»™t dấu cách để tránh xung Ä‘á»™t vá»›i phím nóng.\n"
564
565#: src/setup/text/conf.c:125
566#, c-format
567msgid "\tEnter string (type '%s' for default value `%s'): "
568msgstr "\tNhập chuỗi (gõ « %s » cho giá trị mặc định « %s »): "
569
570#: src/setup/text/conf.c:143
571#, c-format
572msgid "\t Enter choice (default is %c): "
573msgstr "\t Nhập sá»± chá»n (mặc định là %c):"
574
575#: src/setup/text/conf.c:147
576#, c-format
577msgid "\tEnter floating point (type '%s' for default value %f): "
578msgstr "\tNhập chấm động (gõ « %s » cho giá trị mặc định %f): "
579
580#: src/setup/text/conf.c:153
581#, c-format
582msgid ""
583"\tEnter unsigned integer in interval [%llu,%llu] (type '%s' for default "
584"value %llu): "
585msgstr ""
586"\tNhập số nguyên không có dấu trong khoảng [%llu,%llu] (gõ « %s » cho giá trị "
587"mặc định %llu): "
588
589#: src/setup/text/conf.c:187
590#, c-format
591msgid "Yes\n"
592msgstr "Có\n"
593
594#: src/setup/text/conf.c:192
595#, c-format
596msgid "No\n"
597msgstr "Không\n"
598
599#: src/setup/text/conf.c:195 src/setup/text/conf.c:236
600#: src/setup/text/conf.c:266 src/setup/text/conf.c:329
601#: src/setup/text/conf.c:387
602#, c-format
603msgid "Help\n"
604msgstr "Trợ giúp\n"
605
606#: src/setup/text/conf.c:198 src/setup/text/conf.c:213
607#: src/setup/text/conf.c:276 src/setup/text/conf.c:307
608#: src/setup/text/conf.c:365
609#, c-format
610msgid "Abort\n"
611msgstr "Hủy bá»\n"
612
613#: src/setup/text/conf.c:354 src/setup/text/conf.c:416
614#, c-format
615msgid ""
616"\n"
617"Invalid entry, try again (use '?' for help): "
618msgstr ""
619"\n"
620"Dữ liệu nhập sai. Hãy thử lại (dùng « ? » để xem trợ giúp): "
621
622#: src/setup/text/conf.c:422
623#, c-format
624msgid "Unknown kind %x (internal error). Skipping option.\n"
625msgstr "Kiểu không rõ %x (lá»—i ná»™i bá»™). Äang bá» qua tùy chá»n.\n"
626
627#: src/setup/text/conf.c:484
628msgid "\tDescend? (y/n/?) "
629msgstr "\tGiảm dần ? (c/k?)"
630
631#: src/setup/text/conf.c:493
632msgid "Aborted.\n"
633msgstr "Bị hủy bá».\n"
634
635#: src/setup/text/conf.c:506
636msgid "Invalid entry.\n"
637msgstr "Dữ liệu nhập không hợp lệ.\n"
638
639#: src/setup/text/conf.c:524
640#, c-format
641msgid "Unknown kind %x (internal error). Aborting.\n"
642msgstr "Kiểu không rõ %x (lá»—i ná»™i bá»™). Äang hủy bá».\n"
643
644#: src/setup/text/conf.c:556
645#, c-format
646msgid "You can always press ENTER to keep the current value.\n"
647msgstr "Lúc nào bạn cũng có thể bấm phím Enter để giữ lại giá trị hiện có.\n"
648
649#: src/setup/text/conf.c:557
650#, c-format
651msgid "Use the '%s' key to abort.\n"
652msgstr "Dùng phím « %s » để hủy bá».\n"
653
654#: src/setup/text/conf.c:575
655#, c-format
656msgid ""
657"Save configuration? Answer 'y' for yes, 'n' for no, 'r' to repeat "
658"configuration. "
659msgstr ""
660"Lưu lại cấu hình không?\n"
661" • y\t\tcó\n"
662" • n\t\tkhông\n"
663" • r\t\tlặp lại cấu hình."
664
665#: src/setup/text/conf.c:590
666#, c-format
667msgid "Configuration was unchanged, no need to save.\n"
668msgstr "Cấu hình chưa thay đổi thì không cần lưu lại.\n"
669
670#: src/setup/text/conf.c:599
671#, c-format
672msgid "Configuration file `%s' written.\n"
673msgstr "Tập tin cấu hình « %s » đã được ghi.\n"
674
675#: src/setup/lib/tree.c:191
676#, c-format
677msgid ""
678"Internal error: entry `%s' in section `%s' not found for visibility change!\n"
679msgstr ""
680"Lỗi nội bộ : mục nhập « %s » trong phần « %s » không tìm thấy để thay đổi tình "
681"trạng hiển rõ.\n"
682
683#: src/setup/lib/wizard_util.c:126
684msgid "Can't open Service Control Manager"
685msgstr "Không thể mở Bá»™ Quản lý Äiá»u khiển Dịch vụ"
686
687#: src/setup/lib/wizard_util.c:132
688msgid "Can't create service"
689msgstr "Không thể tạo dịch vụ"
690
691#: src/setup/lib/wizard_util.c:136
692msgid "Error changing the permissions of the GNUnet directory"
693msgstr "Gặp lá»—i khi thay đổi quyá»n hạn của thÆ° mục GNUnet"
694
695#: src/setup/lib/wizard_util.c:141
696msgid "Cannot write to the registry"
697msgstr "Không thể ghi vào sổ đăng ký"
698
699#: src/setup/lib/wizard_util.c:144
700msgid "Can't access the service"
701msgstr "Không thể truy cập đến dịch vụ"
702
703#: src/setup/lib/wizard_util.c:147
704msgid "Can't delete the service"
705msgstr "Không thể xoá dịch vụ"
706
707#: src/setup/lib/wizard_util.c:150
708msgid "Unknown error"
709msgstr "Lỗi không rõ"
710
711#: src/setup/lib/wizard_util.c:186
712msgid "This version of Windows does not support multiple users."
713msgstr "Phiên bản Windows này không có há»— trợ Ä‘a ngÆ°á»i dùng."
714
715#: src/setup/lib/wizard_util.c:190
716msgid "Error creating user"
717msgstr "Gặp lá»—i khi tạo ngÆ°á»i dùng"
718
719#: src/setup/lib/wizard_util.c:194
720msgid "Error accessing local security policy"
721msgstr "Gặp lỗi khi truy cập đến chính sách bảo mật cục bộ"
722
723#: src/setup/lib/wizard_util.c:199
724msgid "Error granting service right to user"
725msgstr "Gặp lá»—i khi cấp quyá»n dịch vụ cho ngÆ°á»i dùng"
726
727#: src/setup/lib/wizard_util.c:204
728msgid "Unknown error while creating a new user"
729msgstr "Gặp lá»—i không rõ trong khi tạo má»™t ngÆ°á»i dùng má»›i"
730
731#: src/setup/lib/gns.c:297
732#, c-format
733msgid ""
734"Configuration does not satisfy constraints of configuration specification "
735"file `%s'!\n"
736msgstr ""
737"Cấu hình không thá»a mãn các ràng buá»™c của tập tin đặc tả cấu hình « %s ».\n"
738
739#: src/util/disk/storage.c:172
740#, c-format
741msgid "`%s' failed for drive `%s': %u\n"
742msgstr "« %s » thất bại cho ổ đĩa « %s »: %u\n"
743
744#: src/util/disk/storage.c:524
745#, c-format
746msgid "Expected `%s' to be a directory!\n"
747msgstr "Mong đợi « %s » là một thư mục.\n"
748
749#: src/util/error/error.c:152
750#, c-format
751msgid "Message `%.*s' repeated %u times in the last %llus\n"
752msgstr "Thông điệp « %.*s » đã lặp lại %u lần trong %llu giây trước\n"
753
754#: src/util/error/error.c:254
755#, c-format
756msgid ""
757"\n"
758"Press any key to continue\n"
759msgstr ""
760"\n"
761"Hãy bấm bất cứ phím nào để tiếp tục.\n"
762
763#: src/util/error/error.c:336 src/util/error/error.c:371
764msgid "DEBUG"
765msgstr "Gá»  Lá»–I"
766
767#: src/util/error/error.c:338 src/util/error/error.c:373
768msgid "STATUS"
769msgstr "TRẠNG THÃI"
770
771#: src/util/error/error.c:340 src/util/error/error.c:377
772msgid "WARNING"
773msgstr "CẢNH BÃO"
774
775#: src/util/error/error.c:342 src/util/error/error.c:379
776msgid "ERROR"
777msgstr "Lá»–I"
778
779#: src/util/error/error.c:344 src/util/error/error.c:381
780msgid "FATAL"
781msgstr "NGHIÊM TRỌNG"
782
783#: src/util/error/error.c:346 src/util/error/error.c:383
784msgid "USER"
785msgstr "NGƯỜI DÙNG"
786
787#: src/util/error/error.c:348 src/util/error/error.c:385
788msgid "ADMIN"
789msgstr "QUẢN TRỊ"
790
791#: src/util/error/error.c:350 src/util/error/error.c:387
792msgid "DEVELOPER"
793msgstr "NHÀ PHÃT TRIỂN"
794
795#: src/util/error/error.c:352 src/util/error/error.c:389
796msgid "REQUEST"
797msgstr "YÊU CẦU"
798
799#: src/util/error/error.c:354 src/util/error/error.c:391
800msgid "BULK"
801msgstr "HÀNG LOẠT"
802
803#: src/util/error/error.c:356 src/util/error/error.c:393
804msgid "IMMEDIATE"
805msgstr "NGAY"
806
807#: src/util/error/error.c:358
808msgid "ALL"
809msgstr "TẤT CẢ"
810
811#: src/util/error/error.c:375
812msgid "INFO"
813msgstr "TIN"
814
815#: src/util/error/error.c:394
816msgid "NOTHING"
817msgstr "KHÔNG GÌ"
818
819#: src/util/network_client/tcpio.c:98 src/util/network_client/tcpio.c:154
820#, fuzzy
821msgid "Could not find valid value for HOST in section NETWORK.\n"
822msgstr "Không tìm thấy giá trị đúng cho MÃY trong phần MẠNG."
823
824#: src/util/network_client/tcpio.c:123
825#, fuzzy, c-format
826msgid "Syntax error in configuration entry HOST in section NETWORK: `%s'\n"
827msgstr "Gặp lá»—i cú pháp trong mục nhập cấu hình MÃY trong phần MẠNG: « %s »"
828
829#: src/util/network_client/tcpio.c:335
830#, c-format
831msgid "Error connecting to %s:%u. Is the daemon running?\n"
832msgstr "Gặp lá»—i khi kết nối tá»›i %s:%u. Trình ná»n Ä‘ang chạy không?\n"
833
834#: src/util/network_client/tcpio.c:398
835#, c-format
836msgid "Cannot connect to %s:%u: %s\n"
837msgstr "Không thể kết nối tới %s:%u: %s\n"
838
839#: src/util/network_client/tcpio.c:636
840msgid "Reading result from gnunetd failed, reply invalid!\n"
841msgstr "Lá»—i Ä‘á»c kết quả từ gnunetd, đáp ứng không hợp lệ.\n"
842
843#: src/util/getopt/setoption.c:59
844#, c-format
845msgid ""
846"Setting option `%s' in section `%s' to `%s' when processing command line "
847"option `%s' was denied.\n"
848msgstr ""
849"Bị từ chối đặt tùy chá»n « %s » trong phần « %s » thành « %s » khi xá»­ lý tùy "
850"chá»n dòng lệnh « %s ».\n"
851
852#: src/util/getopt/setoption.c:138 src/util/getopt/setoption.c:155
853#, c-format
854msgid "You must pass a number to the `%s' option.\n"
855msgstr "Phải gá»­i má»™t con số cho tùy chá»n « %s ».\n"
856
857#: src/util/getopt/printhelp.c:49
858#, c-format
859msgid ""
860"Arguments mandatory for long options are also mandatory for short options.\n"
861msgstr ""
862"Má»i đối số bắt buá»™c phải sá»­ dụng vá»›i tùy chá»n dài cÅ©ng bắt buá»™c vá»›i tùy chá»n "
863"ngắn.\n"
864
865#: src/util/getopt/getopt.c:684
866#, c-format
867msgid "%s: option `%s' is ambiguous\n"
868msgstr "%s: tùy chá»n « %s » là mÆ¡ hồ\n"
869
870#: src/util/getopt/getopt.c:710
871#, c-format
872msgid "%s: option `--%s' does not allow an argument\n"
873msgstr "%s: tùy chá»n « --%s » không cho phép đối số\n"
874
875#: src/util/getopt/getopt.c:716
876#, c-format
877msgid "%s: option `%c%s' does not allow an argument\n"
878msgstr "%s: tùy chá»n « %c%s » không cho phép đối số\n"
879
880#: src/util/getopt/getopt.c:737 src/util/getopt/getopt.c:909
881#, c-format
882msgid "%s: option `%s' requires an argument\n"
883msgstr "%s: tùy chá»n « %s » cần thiết đối số\n"
884
885#: src/util/getopt/getopt.c:767
886#, c-format
887msgid "%s: unrecognized option `--%s'\n"
888msgstr "%s: không nhận ra tùy chá»n « --%s »\n"
889
890#: src/util/getopt/getopt.c:771
891#, c-format
892msgid "%s: unrecognized option `%c%s'\n"
893msgstr "%s: không nhận ra tùy chá»n « %c%s »\n"
894
895#: src/util/getopt/getopt.c:797
896#, c-format
897msgid "%s: illegal option -- %c\n"
898msgstr "%s: tùy chá»n không được phép -- %c\n"
899
900#: src/util/getopt/getopt.c:799
901#, c-format
902msgid "%s: invalid option -- %c\n"
903msgstr "%s: tùy chá»n không hợp lệ -- %c\n"
904
905#: src/util/getopt/getopt.c:828 src/util/getopt/getopt.c:958
906#, c-format
907msgid "%s: option requires an argument -- %c\n"
908msgstr "%s: tùy chá»n cần thiết đối số -- %c\n"
909
910#: src/util/getopt/getopt.c:876
911#, c-format
912msgid "%s: option `-W %s' is ambiguous\n"
913msgstr "%s: tùy chá»n « -W %s » là mÆ¡ hồ\n"
914
915#: src/util/getopt/getopt.c:894
916#, c-format
917msgid "%s: option `-W %s' does not allow an argument\n"
918msgstr "%s: tùy chá»n « -W %s » không cho phép đối số\n"
919
920#: src/util/network/ip.c:96 src/util/network/ip.c:160 src/transports/ip.c:260
921#, c-format
922msgid "No interface specified in section `%s' under `%s'!\n"
923msgstr ""
924"Không có giao diện mạng được xác định trong cấu hình phần « %s » dưới « %s ».\n"
925
926#: src/util/network/ip.c:127 src/util/network/ip.c:246 src/transports/ip.c:291
927#, c-format
928msgid "Could not obtain IP for interface `%s' using `%s'.\n"
929msgstr "Không thể lấy địa chỉ IP cho giao diện « %s », dùng « %s ».\n"
930
931#: src/util/network/ip.c:216
932#, c-format
933msgid ""
934"Could not find interface `%s' using `%s', trying to find another interface.\n"
935msgstr ""
936"Không tìm thấy giao diện « %s » trong « %s », đang thử tìm giao diện khác.\n"
937
938#: src/util/network/ip.c:295
939#, c-format
940msgid "Could not find an IP address for interface `%s'.\n"
941msgstr "Không tìm thấy một địa chỉ IP cho giao diện « %s ».\n"
942
943#: src/util/network/ip.c:306
944#, c-format
945msgid ""
946"There is more than one IP address specified for interface `%s'.\n"
947"GNUnet will use %s.\n"
948msgstr ""
949"Có vài địa chỉ IP chỉ ra cho giao diện « %s ».\n"
950"GNUnet sẽ dùng %s.\n"
951
952#: src/util/network/ip.c:330
953#, c-format
954msgid "Could not resolve `%s' to determine our IP address: %s\n"
955msgstr "Không thể giải quyết « %s » để quyết định địa chỉ IP của chúng ta: %s\n"
956
957#: src/util/network/ip.c:363
958#, c-format
959msgid "GNUnet now uses the IP address %s.\n"
960msgstr "GNUnet bây giỠsử dụng địa chỉ IP %s.\n"
961
962#: src/util/network/ipcheck.c:106 src/util/network/ipcheck.c:136
963#: src/util/network/ipcheck.c:186 src/util/network/ipcheck.c:211
964#: src/util/network/ipcheck.c:219
965#, c-format
966msgid "Invalid format for IP: `%s'\n"
967msgstr "Äịa chỉ IP định dạng sai: %s\n"
968
969#: src/util/network/ipcheck.c:167
970#, c-format
971msgid "Invalid network notation ('/%d' is not legal in IPv4 CIDR)."
972msgstr "Ký hiệu mạng sai (« /%d » không hợp lệ trong CIDR IPv4)."
973
974#: src/util/network/ipcheck.c:269
975#, c-format
976msgid "Invalid network notation (does not end with ';': `%s')\n"
977msgstr "Ký hiệu mạng sai (không kết thúc với « ; »: « %s »)\n"
978
979#: src/util/network/ipcheck.c:306
980#, fuzzy, c-format
981msgid "Wrong format `%s' for netmask\n"
982msgstr "Mặt nạ mạng có định dạng sai « %s »: %s\n"
983
984#: src/util/network/ipcheck.c:338
985#, fuzzy, c-format
986msgid "Wrong format `%s' for network\n"
987msgstr "Mạng có định dạng sai « %s »: %s\n"
988
989#: src/util/network/dns.c:472
990#, c-format
991msgid "Could not resolve `%s' (%s): %s\n"
992msgstr "Không thể giải quyết « %s » (%s): %s\n"
993
994#: src/util/network/dns.c:523 src/util/network/dns.c:591
995#, c-format
996msgid "Could not find IP of host `%s': %s\n"
997msgstr "Không tìm thấy địa chỉ IP của máy « %s »: %s\n"
998
999#: src/util/network/select.c:310
1000msgid "Received malformed message (too small) from connection. Closing.\n"
1001msgstr "Nhận được thông báo bị há»ng (quá nhá») từ kết nối. Äang đóng.\n"
1002
1003#: src/util/network/select.c:495
1004#, c-format
1005msgid "select listen socket for `%s' not valid!\n"
1006msgstr "sai chá»n ổ cắm lắng nghe cho « %s »\n"
1007
1008#: src/util/config/config.c:296
1009#, c-format
1010msgid "Syntax error in configuration file `%s' at line %d.\n"
1011msgstr "Gặp lỗi cú pháp trong tập tin cấu hình « %s » tại dòng %d.\n"
1012
1013#: src/util/config/config.c:592
1014#, c-format
1015msgid ""
1016"Configuration value '%llu' for '%s' in section '%s' is out of legal bounds [%"
1017"llu,%llu]\n"
1018msgstr ""
1019"Giá tri cấu hình « %llu » cho « %s » trong phần « %s » ở ngoại phạm vi được "
1020"phép [%llu,%llu]\n"
1021
1022#: src/util/config/config.c:602
1023#, c-format
1024msgid "Configuration value '%s' for '%s' in section '%s' should be a number\n"
1025msgstr "Giá trị cấu hình « %s » cho « %s » trong phần « %s » nên là con số\n"
1026
1027#: src/util/config/config.c:688
1028#, c-format
1029msgid ""
1030"Configuration value '%s' for '%s' in section '%s' is not in set of legal "
1031"choices\n"
1032msgstr ""
1033"Giá trị cấu hình « %s » cho « %s » trong phần « %s » không phải nằm trong tập "
1034"hợp các sá»± chá»n được phép\n"
1035
1036#: src/util/crypto/locking_gcrypt.c:80
1037#, c-format
1038msgid "libgcrypt has not the expected version (version %s is required).\n"
1039msgstr "libgcrypt không có phiên bản mong đợi (yêu cầu phiên bản %s).\n"
1040
1041#: src/util/crypto/symcipher_gcrypt.c:46 src/util/crypto/symcipher_gcrypt.c:53
1042#: src/util/crypto/hostkey_gcrypt.c:64 src/util/crypto/hostkey_gcrypt.c:71
1043#: src/util/loggers/file.c:271 src/util/loggers/file.c:289
1044#: src/applications/sqstore_sqlite/sqlite.c:45
1045#: src/applications/sqstore_sqlite/sqlite.c:52
1046#: src/applications/kvstore_sqlite/kv_sqlite.c:44
1047#: src/applications/kvstore_sqlite/kv_sqlite.c:51
1048#: src/applications/kvstore_mysql/kv_mysql.c:44
1049#: src/applications/kvstore_mysql/kv_mysql.c:51
1050#: src/applications/dstore_sqlite/dstore.c:94
1051#: src/applications/dstore_sqlite/dstore.c:101
1052#: src/applications/dstore_sqlite/dstore.c:222
1053#: src/applications/dstore_sqlite/dstore.c:259
1054#: src/applications/dstore_sqlite/dstore.c:285
1055#: src/applications/dstore_sqlite/dstore.c:345
1056#: src/applications/dstore_sqlite/dstore.c:366
1057#: src/applications/dstore_sqlite/dstore.c:378
1058#: src/applications/dstore_sqlite/dstore.c:407
1059#: src/applications/dstore_sqlite/dstore.c:511
1060#: src/applications/dstore_sqlite/dstore.c:555
1061#: src/include/gnunet_util_error.h:249 src/include/gnunet_util_error.h:256
1062#: src/include/gnunet_util_error.h:263
1063#, c-format
1064msgid "`%s' failed at %s:%d with error: %s\n"
1065msgstr "« %s » bị lỗi tại %s:%d với lỗi: %s\n"
1066
1067#: src/util/crypto/hostkey_gcrypt.c:907
1068#, c-format
1069msgid "RSA signature verification failed at %s:%d: %s\n"
1070msgstr "Lỗi thẩm tra chữ ký RSA tại %s:%d: %s\n"
1071
1072#: src/util/os/user.c:108 src/util/os/user.c:125
1073#, c-format
1074msgid "`%s' returned with error code %u"
1075msgstr "« %s » trả lại với mã lỗi %u"
1076
1077#: src/util/os/user.c:155 src/util/os/user.c:200
1078#, c-format
1079msgid "Cannot obtain information about user `%s': %s\n"
1080msgstr "Không thể lấy thông tin vá» ngÆ°á»i dùng « %s »: %s\n"
1081
1082#: src/util/os/user.c:156
1083msgid "No such user"
1084msgstr "Không có ngÆ°á»i dùng nhÆ° vậy"
1085
1086#: src/util/os/user.c:171
1087#, c-format
1088msgid "Cannot change user/group to `%s': %s\n"
1089msgstr "Không thể thay đổi ngÆ°á»i dùng/nhóm thành « %s »: %s\n"
1090
1091#: src/util/os/semaphore.c:227
1092#, c-format
1093msgid "Can't create semaphore: %i"
1094msgstr "Không thể tạo cỠhiệu : %i"
1095
1096#: src/util/os/cpustatus.c:464
1097msgid "Cannot query the CPU usage (Windows NT).\n"
1098msgstr "Không há»i được sá»± sá»­ dụng CPU (Windows NT).\n"
1099
1100#: src/util/os/cpustatus.c:487
1101msgid "Cannot query the CPU usage (Win 9x)\n"
1102msgstr "Không há»i được sá»± sá»­ dụng CPU (Windows 9x).\n"
1103
1104#: src/util/os/dso.c:59
1105#, c-format
1106msgid "Initialization of plugin mechanism failed: %s!\n"
1107msgstr "Lỗi sơ khởi cơ chế phần bổ sung: %s\n"
1108
1109#: src/util/os/dso.c:120
1110#, c-format
1111msgid "`%s' failed for library `%s' with error: %s\n"
1112msgstr "« %s » thất bại cho thư viện « %s » với lỗi: %s\n"
1113
1114#: src/util/os/dso.c:162
1115#, c-format
1116msgid "`%s' failed to resolve method '%s' with error: %s\n"
1117msgstr "« %s » không giải quyết được phương pháp « %s », với lỗi: %s\n"
1118
1119#: src/util/os/statuscalls.c:197 src/util/os/statuscalls.c:342
1120#, c-format
1121msgid "Failed to parse interface data from `%s'.\n"
1122msgstr "Lỗi phân tích dữ liệu giao diện từ « %s ».\n"
1123
1124#: src/util/os/statuscalls.c:390 src/util/os/statuscalls.c:400
1125#, c-format
1126msgid ""
1127"No network interfaces defined in configuration section `%s' under `%s'!\n"
1128msgstr ""
1129"Không có giao diện mạng được xác định trong cấu hình phần « %s » dưới « %s ».\n"
1130
1131#: src/util/os/osconfig.c:153
1132msgid "Setting open descriptor limit not supported.\n"
1133msgstr "Không hỗ trợ chức năng đặt giới hạn bộ mô tả còn mở.\n"
1134
1135#: src/util/os/osconfig.c:463 src/util/os/osconfig.c:492
1136#, c-format
1137msgid "Command `%s' failed with error code %u\n"
1138msgstr "Câu lệnh « %s » đã thất bại với mã lỗi %u\n"
1139
1140#: src/util/os/priority.c:78
1141#, c-format
1142msgid "Invalid process priority `%s'\n"
1143msgstr "Mức ưu tiên tiến trình không hợp lê « %s ».\n"
1144
1145#: src/util/threads/semaphore.c:168 src/util/threads/pthread.c:157
1146#: src/util/threads/mutex.c:146
1147#, c-format
1148msgid "Real-time delay violation (%llu ms) at %s:%u\n"
1149msgstr "Xâm phạm khoảng đợi thá»i gian thá»±c (%llu miligiây) tại %s:%u\n"
1150
1151#: src/util/threads/pthread.c:169 src/util/threads/pthread.c:176
1152#: src/util/threads/pthread.c:182 src/util/threads/pthread.c:276
1153#, c-format
1154msgid "`%s' failed with error code %s: %s\n"
1155msgstr "« %s » thất bại với mã lỗi %s: %s\n"
1156
1157#: src/util/threads/pthread.c:188 src/util/threads/pthread.c:286
1158#, c-format
1159msgid "`%s' failed with error code %d: %s\n"
1160msgstr "« %s » thất bại với mã lỗi %d: %s\n"
1161
1162#: src/util/threads/mutex.c:155 src/util/threads/mutex.c:201
1163#, c-format
1164msgid "Invalid argument for `%s'.\n"
1165msgstr "Äối số không hợp lệ cho « %s ».\n"
1166
1167#: src/util/threads/mutex.c:160
1168#, c-format
1169msgid "Deadlock due to `%s'.\n"
1170msgstr "Bế tắc do « %s ».\n"
1171
1172#: src/util/threads/mutex.c:187
1173#, c-format
1174msgid "Lock acquired for too long (%llu ms) at %s:%u\n"
1175msgstr "Khoá đặt được quá lâu (%llu miligiây) tại %s:%u\n"
1176
1177#: src/util/threads/mutex.c:207
1178#, c-format
1179msgid "Permission denied for `%s'.\n"
1180msgstr "Không đủ quyá»n cho « %s ».\n"
1181
1182#: src/util/boot/startup.c:259
1183#, c-format
1184msgid "Failed to run %s: %s %d\n"
1185msgstr "Lỗi chạy %s: %s %d\n"
1186
1187#: src/util/string/string.c:55
1188msgid "ms"
1189msgstr "mg"
1190
1191#: src/util/string/string.c:61
1192msgid "s"
1193msgstr "g"
1194
1195#: src/util/string/string.c:65
1196msgid "m"
1197msgstr "p"
1198
1199#: src/util/string/string.c:69
1200msgid "h"
1201msgstr "g"
1202
1203#: src/util/string/string.c:73
1204msgid " days"
1205msgstr " ngày"
1206
1207#: src/util/string/string.c:89
1208msgid "b"
1209msgstr "b"
1210
1211#: src/util/string/string.c:95
1212msgid "KiB"
1213msgstr "KiB"
1214
1215#: src/util/string/string.c:99
1216msgid "MiB"
1217msgstr "MiB"
1218
1219#: src/util/string/string.c:103
1220msgid "GiB"
1221msgstr "GiB"
1222
1223#: src/util/string/string.c:107
1224msgid "TiB"
1225msgstr "TiB"
1226
1227#: src/util/string/string.c:226
1228msgid "Failed to expand `$HOME': environment variable `HOME' not set"
1229msgstr "Lá»—i mở rá»™ng biến môi trÆ°á»ng « $HOME »: chÆ°a đặt biến môi trÆ°á»ng « HOME »"
1230
1231#: src/util/loggers/file.c:229
1232#, c-format
1233msgid "Failed to open log-file `%s': %s\n"
1234msgstr "Lỗi mở tập tin ghi sự kiện « %s »: %s\n"
1235
1236#: src/util/loggers/file.c:250
1237msgid "GNUnet error log"
1238msgstr "Bản ghi lỗi GNUnet"
1239
1240#: src/util/loggers/memory.c:72
1241msgid "Out of memory (for logging)\n"
1242msgstr "Tràn bộ nhớ (để ghi sự kiện)\n"
1243
1244#: src/util/pseudonym/names.c:79
1245msgid "no-name"
1246msgstr "không-tên"
1247
1248#: src/applications/datastore/datastore.c:183
1249#: src/applications/datastore/datastore.c:199
1250#, c-format
1251msgid "Availability test failed for `%s' at %s:%d.\n"
1252msgstr "Lỗi kiểm tra tình trạng sẵn sàng cho « %s » tại %s:%d.\n"
1253
1254#: src/applications/datastore/datastore.c:401
1255msgid "# requests filtered by bloom filter"
1256msgstr "# các yêu cầu được lá»c theo bá»™ lá»c bloom"
1257
1258#: src/applications/datastore/datastore.c:403
1259msgid "# bloom filter false positives"
1260msgstr "# các dÆ°Æ¡ng giả của bá»™ lá»c bloom"
1261
1262#: src/applications/datastore/datastore.c:406
1263msgid "# bytes allowed in datastore"
1264msgstr "# các byte được phép trong kho dữ liệu"
1265
1266#: src/applications/datastore/datastore.c:423
1267msgid "Failed to load state service. Trying to do without.\n"
1268msgstr "Lỗi nạp dịch vụ tình trạng. Không có nhưng vẫn đang thử tiếp tục.\n"
1269
1270#: src/applications/datastore/datastore.c:529
1271#, c-format
1272msgid "Datastore conversion at approximately %u%%\n"
1273msgstr "Chuyển đổi kho dữ liệu theo xấp xỉ %u%%\n"
1274
1275#: src/applications/datastore/datastore.c:576
1276#, c-format
1277msgid "Starting datastore conversion (this may take a while).\n"
1278msgstr "Äang bắt đầu chuyển đổi kho dữ liệu (có thể hÆ¡i lâu).\n"
1279
1280#: src/applications/datastore/datastore.c:584
1281#, c-format
1282msgid "Completed datastore conversion.\n"
1283msgstr "Hoàn tất chuyển đổi kho dữ liệu.\n"
1284
1285#: src/applications/datastore/datastore.c:592
1286msgid "Failed to load sqstore service. Check your configuration!\n"
1287msgstr "Lỗi nạp dịch vụ sqstore. Hãy kiểm tra lại cấu hình.\n"
1288
1289#: src/applications/rpc/rpc.c:339
1290#, c-format
1291msgid ""
1292"%s:%d - RPC %s:%p could not be registered: another callback is already using "
1293"this name (%p)\n"
1294msgstr ""
1295"%s:%d - RPC %s:%p không đăng ký được: má»™t cuá»™c gá»i ngược lại khác Ä‘ang dùng "
1296"tên này (%p)\n"
1297
1298#: src/applications/rpc/rpc.c:398
1299#, c-format
1300msgid "%s:%d - async RPC %s:%p could not be unregistered: not found\n"
1301msgstr ""
1302"%s:%d - RPC không đồng bộ %s:%p không hủy đăng ký được: không tìm thấy\n"
1303
1304#: src/applications/rpc/rpc.c:951
1305#, c-format
1306msgid "`%s' registering handlers %d %d %d\n"
1307msgstr "« %s » Ä‘ang đăng ký các trình Ä‘iá»u khiển %d %d %d\n"
1308
1309#: src/applications/rpc/rpc.c:972
1310#, c-format
1311msgid "Failed to initialize `%s' service.\n"
1312msgstr "Lỗi sơ khởi dịch vụ « %s ».\n"
1313
1314#: src/applications/tbench/tbenchtest.c:53
1315#, c-format
1316msgid "Using %u messages of size %u for %u times.\n"
1317msgstr "Sử dụng %u thông báo với kích cỡ %u trong %u lần.\n"
1318
1319#: src/applications/tbench/tbenchtest.c:85
1320#, c-format
1321msgid "Times: max %16llu min %16llu mean %12.3f variance %12.3f\n"
1322msgstr "Thá»i gian: đại %16llu tiểu %16llu t.bình %12.3f ph.sai %12.3f\n"
1323
1324#: src/applications/tbench/tbenchtest.c:89
1325#, c-format
1326msgid "Loss: max %16u min %16u mean %12.3f variance %12.3f\n"
1327msgstr "Mất: đại %16u tiểu %16u t.bình %12.3f ph.sai %12.3f\n"
1328
1329#: src/applications/tbench/tbenchtest.c:95
1330#, c-format
1331msgid ""
1332"\n"
1333"Failed to receive reply from gnunetd.\n"
1334msgstr ""
1335"\n"
1336"Không nhận được đáp ứng từ gnunetd.\n"
1337
1338#: src/applications/tbench/tbenchtest.c:149
1339#, c-format
1340msgid "Running benchmark...\n"
1341msgstr "Äang chạy tiến trình kiểm chuẩn...\n"
1342
1343#: src/applications/tbench/tbench.c:422
1344msgid "allows profiling of direct peer-to-peer connections"
1345msgstr "cho phép đo hiệu năng sử dụng của kết nối đồng đẳng trực tiếp"
1346
1347#: src/applications/tbench/gnunet-tbench.c:63
1348#: src/applications/tracekit/gnunet-tracekit.c:302
1349msgid "Start GNUnet transport benchmarking tool."
1350msgstr "Khởi chạy công cụ kiểm chuẩn truyá»n tải của GNUnet."
1351
1352#: src/applications/tbench/gnunet-tbench.c:65
1353msgid "output in gnuplot format"
1354msgstr "kết xuất theo định dạng gnuplot"
1355
1356#: src/applications/tbench/gnunet-tbench.c:69
1357msgid "number of iterations"
1358msgstr "số lần lặp lại"
1359
1360#: src/applications/tbench/gnunet-tbench.c:73
1361msgid "number of messages to use per iteration"
1362msgstr "số tin nhắn cần dùng mỗi lần lặp"
1363
1364#: src/applications/tbench/gnunet-tbench.c:76
1365msgid "receiver host identifier (ENC file name)"
1366msgstr "đồ nhận diện máy nhận (tên tập tin mã hoá)"
1367
1368#: src/applications/tbench/gnunet-tbench.c:79
1369msgid "message size"
1370msgstr "kích cỡ tin nhắn"
1371
1372#: src/applications/tbench/gnunet-tbench.c:82
1373msgid "sleep for SPACE ms after each a message block"
1374msgstr "ngủ KHOẢNG miligiây sau mỗi khối tin nhắn"
1375
1376#: src/applications/tbench/gnunet-tbench.c:85
1377msgid "time to wait for the completion of an iteration (in ms)"
1378msgstr "thá»i gian chá» sá»± hoàn thành của má»™t lần lặp (theo miligiây)"
1379
1380#: src/applications/tbench/gnunet-tbench.c:90
1381msgid "number of messages in a message block"
1382msgstr "số tin nhắn trong một khối tin nhắn"
1383
1384#: src/applications/tbench/gnunet-tbench.c:126
1385#: src/applications/tracekit/gnunet-tracekit.c:352
1386#: src/applications/tracekit/tracekittest.c:133
1387#: src/applications/template/gnunet-template.c:95
1388#: src/applications/stats/gnunet-stats.c:121
1389#: src/applications/vpn/gnunet-vpn.c:154
1390#, c-format
1391msgid "Error establishing connection with gnunetd.\n"
1392msgstr "Lỗi thiết lập kết nối đến gnunetd.\n"
1393
1394#: src/applications/tbench/gnunet-tbench.c:142
1395#, c-format
1396msgid "You must specify a receiver!\n"
1397msgstr "Phải ghi rõ một máy nhận.\n"
1398
1399#: src/applications/tbench/gnunet-tbench.c:152
1400#, c-format
1401msgid "Invalid receiver peer ID specified (`%s' is not valid name).\n"
1402msgstr "Chỉ ra mã số đồng đẳng nhận sai (« %s » không phải là một tên đúng).\n"
1403
1404#: src/applications/tbench/gnunet-tbench.c:189
1405#, c-format
1406msgid "Time:\n"
1407msgstr "Thá»i gian:\n"
1408
1409#: src/applications/tbench/gnunet-tbench.c:190
1410#, c-format
1411msgid "\tmax %llums\n"
1412msgstr "\tđại %llu mg\n"
1413
1414#: src/applications/tbench/gnunet-tbench.c:191
1415#, c-format
1416msgid "\tmin %llums\n"
1417msgstr "\ttiểu %llu mg\n"
1418
1419#: src/applications/tbench/gnunet-tbench.c:192
1420#, c-format
1421msgid "\tmean %8.4fms\n"
1422msgstr "\ttrung bình %8.4f mg\n"
1423
1424#: src/applications/tbench/gnunet-tbench.c:193
1425#, c-format
1426msgid "\tvariance %8.4fms\n"
1427msgstr "\tphÆ°Æ¡ng sai %8.4f mg\n"
1428
1429#: src/applications/tbench/gnunet-tbench.c:195
1430#, c-format
1431msgid "Loss:\n"
1432msgstr "Mất:\n"
1433
1434#: src/applications/tbench/gnunet-tbench.c:196
1435#, c-format
1436msgid "\tmax %u\n"
1437msgstr "\tđại %u\n"
1438
1439#: src/applications/tbench/gnunet-tbench.c:197
1440#, c-format
1441msgid "\tmin %u\n"
1442msgstr "\ttiểu %u\n"
1443
1444#: src/applications/tbench/gnunet-tbench.c:198
1445#, c-format
1446msgid "\tmean %8.4f\n"
1447msgstr "\tt.bình %8.4f\n"
1448
1449#: src/applications/tbench/gnunet-tbench.c:199
1450#, c-format
1451msgid "\tvariance %8.4f\n"
1452msgstr "\tph.sai %8.4f\n"
1453
1454#: src/applications/tbench/gnunet-tbench.c:205
1455#, c-format
1456msgid "Output format not known, this should not happen.\n"
1457msgstr "Äịnh dạng kết xuất không rõ, Ä‘iá»u này không nên xảy ra.\n"
1458
1459#: src/applications/tbench/gnunet-tbench.c:211
1460#, c-format
1461msgid ""
1462"\n"
1463"Did not receive the message from gnunetd. Is gnunetd running?\n"
1464msgstr ""
1465"\n"
1466"Không nhận được thông báo từ gnunetd. Trình ná»n gnunetd Ä‘ang chạy không?\n"
1467
1468#: src/applications/traffic/traffic.c:454
1469#, c-format
1470msgid "# bytes transmitted of type %d"
1471msgstr "# các byte kiểu %d được gửi "
1472
1473#: src/applications/traffic/traffic.c:470
1474#, c-format
1475msgid "# bytes received of type %d"
1476msgstr "# các byte kiểu %d được nhận"
1477
1478#: src/applications/traffic/traffic.c:489
1479#, c-format
1480msgid "# bytes received in plaintext of type %d"
1481msgstr "# các byte nhập thô kiểu %d được nhận"
1482
1483#: src/applications/traffic/traffic.c:652
1484msgid "tracks bandwidth utilization by gnunetd"
1485msgstr "theo dõi gnunetd sử dụng dải thông"
1486
1487#: src/applications/sqstore_sqlite/sqlite.c:218
1488#, c-format
1489msgid "Unable to initialize SQLite: %s.\n"
1490msgstr "Không thể sơ khởi SQLite: %s.\n"
1491
1492#: src/applications/sqstore_sqlite/sqlite.c:434
1493#: src/applications/sqstore_sqlite/sqlite.c:469
1494#, c-format
1495msgid "Invalid data in %s. Trying to fix (by deletion).\n"
1496msgstr "Dữ liệu sai trong %s. Äang thá»­ sá»­a chữa (bằng cách xoá).\n"
1497
1498#: src/applications/sqstore_sqlite/sqlite.c:435
1499#: src/applications/sqstore_sqlite/sqlite.c:470
1500msgid "sqlite datastore"
1501msgstr "kho dữ liệu sqlite"
1502
1503#: src/applications/sqstore_sqlite/sqlite.c:1474
1504#: src/applications/sqstore_mysql/mysql.c:1078
1505msgid "# bytes in datastore"
1506msgstr "# các byte trong kho dữ liệu"
1507
1508#: src/applications/sqstore_sqlite/sqlite.c:1476
1509#, fuzzy
1510msgid "# bytes allocated by SQLite"
1511msgstr "# các byte được phép trong kho dữ liệu"
1512
1513#: src/applications/sqstore_mysql/mysql.c:1085
1514#: src/applications/sqstore_mysql/mysql.c:1160
1515msgid ""
1516"Failed to load MySQL database module. Check that MySQL is running and "
1517"configured properly!\n"
1518msgstr ""
1519"Lỗi nạp mô-đun cơ sở dữ liệu MySQL. Hãy kiểm tra lại MySQL đang chạy và có "
1520"cấu hình đúng.\n"
1521
1522#: src/applications/tracekit/gnunet-tracekit.c:104
1523#, c-format
1524msgid "`%s' connected to `%s'.\n"
1525msgstr "« %s » được kết nối tới « %s ».\n"
1526
1527#: src/applications/tracekit/gnunet-tracekit.c:110
1528#: src/applications/tracekit/tracekittest.c:67
1529#, c-format
1530msgid "`%s' is not connected to any peer.\n"
1531msgstr "« %s » không phải được kết nối tới đồng đẳng nào.\n"
1532
1533#: src/applications/tracekit/gnunet-tracekit.c:295
1534msgid "probe network to the given DEPTH"
1535msgstr "dò mạng tới độ sâu SÂU đưa ra"
1536
1537#: src/applications/tracekit/gnunet-tracekit.c:299
1538msgid ""
1539"specify output format; 0 for human readable output, 1 for dot, 2 for vcg"
1540msgstr ""
1541"chỉ ra định dạng kết quả;\n"
1542" • 0\t\tkết xuất cho ngÆ°á»i Ä‘á»c được\n"
1543" • 1\t\tdấu chấm\n"
1544" • 2\t\tvcg"
1545
1546#: src/applications/tracekit/gnunet-tracekit.c:306
1547msgid "use PRIORITY for the priority of the trace request"
1548msgstr "dùng ƯU_TIÊN làm Æ°u tiên của yêu cầu tìm Ä‘Æ°á»ng"
1549
1550#: src/applications/tracekit/gnunet-tracekit.c:310
1551msgid "wait DELAY seconds for replies"
1552msgstr "đợi đáp ứng TRỄ giây"
1553
1554#: src/applications/tracekit/gnunet-tracekit.c:344
1555#, c-format
1556msgid ""
1557"Format specification invalid. Use 0 for user-readable, 1 for dot, 2 for "
1558"vcg.\n"
1559msgstr ""
1560"Äặt tả định dạng sai. Dùng:\n"
1561" • 0\t\tkết xuất cho ngÆ°á»i Ä‘á»c được\n"
1562" • 1\t\tdấu chấm\n"
1563" • 2\t\tvcg\n"
1564
1565#: src/applications/tracekit/tracekittest.c:60
1566#, c-format
1567msgid "`%.*s' connected to `%.*s'.\n"
1568msgstr "« %.*s » được kết nối tới « %.*s ».\n"
1569
1570#: src/applications/tracekit/tracekit.c:440
1571msgid "allows mapping of the network topology"
1572msgstr "cho phép ánh xạ địa hình của mạng"
1573
1574#: src/applications/advertising/advertising_test.c:47
1575#: src/applications/hostlist/hostlisttest.c:40
1576#: src/applications/session/sessiontest.c:40
1577#: src/applications/session/sessiontest_nat_http.c:40
1578#: src/applications/session/sessiontest_nat.c:40
1579#: src/applications/stats/statistics.c:247
1580msgid "# of connected peers"
1581msgstr "# của các đồng đẳng đã kết nối"
1582
1583#: src/applications/advertising/advertising.c:194
1584#, c-format
1585msgid "HELLO message from `%s' has an invalid signature. Dropping.\n"
1586msgstr "Thông báo HELLO từ « %s » có chữ ký sai. Äang bá» Ä‘i.\n"
1587
1588#: src/applications/advertising/advertising.c:205
1589msgid "HELLO message has expiration too far in the future. Dropping.\n"
1590msgstr "Thông báo HELLO hết hạn trong tÆ°Æ¡ng lai quá nhiá»u. Äang bá» Ä‘i.\n"
1591
1592#: src/applications/advertising/advertising.c:406
1593msgid "Could not send HELLO+PING, ping buffer full.\n"
1594msgstr "Không gửi được tín hiệu HELLO+PING, đầy bộ đệm ping.\n"
1595
1596#: src/applications/advertising/advertising.c:429
1597msgid "Failed to create an advertisement for this peer. Will not send PING.\n"
1598msgstr ""
1599"Không tạo được quảng cáo cho đồng đẳng này. Sẽ không gửi tín hiệu PING.\n"
1600
1601#: src/applications/advertising/advertising.c:581
1602#, c-format
1603msgid "Advertising my transport %d to selected peers.\n"
1604msgstr "Äang quảng cáo truyá»n tải %d của mình tá»›i các đồng đẳng đã chá»n.\n"
1605
1606#: src/applications/advertising/advertising.c:590
1607msgid ""
1608"Announcing ourselves pointless: no other peers are known to us so far.\n"
1609msgstr "Không có nghĩa khi tự thông báo : chưa biết đồng đẳng khác.\n"
1610
1611#: src/applications/advertising/advertising.c:868
1612msgid "# Peer advertisements received"
1613msgstr "# Các quảng cáo đồng đẳng được nhận"
1614
1615#: src/applications/advertising/advertising.c:871
1616msgid "# Peer advertisements of type NAT received"
1617msgstr "# Các quảng cáo đồng đẳng kiểu NAT được nhận"
1618
1619#: src/applications/advertising/advertising.c:874
1620msgid "# Peer advertisements confirmed via PONG"
1621msgstr "# Các quảng cáo đồng đẳng được xác nhận qua PONG"
1622
1623#: src/applications/advertising/advertising.c:877
1624msgid "# Peer advertisements updating earlier HELLOs"
1625msgstr "# Các quảng cáo đồng đẳng cập nhật tin hiệu HELLO trước"
1626
1627#: src/applications/advertising/advertising.c:880
1628msgid "# Peer advertisements discarded due to load"
1629msgstr "# Các quảng cáo đồng đẳng bị hủy do trá»ng tải"
1630
1631#: src/applications/advertising/advertising.c:883
1632msgid "# Peer advertisements for unsupported transport"
1633msgstr "# Các quảng cáo đồng đẳng cho truyá»n tải không được há»— trợ"
1634
1635#: src/applications/advertising/advertising.c:886
1636msgid "# Peer advertisements not confirmed due to ping busy"
1637msgstr "# Các quảng cáo đồng đẳng không được xác nhận do ping đang bận"
1638
1639#: src/applications/advertising/advertising.c:889
1640msgid "# Peer advertisements not confirmed due to lack of self ad"
1641msgstr "# Các quảng cáo đồng đẳng không được xác nhận do không tự quảng cáo"
1642
1643#: src/applications/advertising/advertising.c:892
1644msgid "# Peer advertisements not confirmed due to send error"
1645msgstr "# Các quảng cáo đồng đẳng không được xác nhận do lỗi gửi"
1646
1647#: src/applications/advertising/advertising.c:894
1648msgid "# Self advertisments transmitted"
1649msgstr "# Các tá»± quảng cáo được truyá»n"
1650
1651#: src/applications/advertising/advertising.c:896
1652msgid "# Foreign advertisements forwarded"
1653msgstr "# Các quảng cáo ngoại được chuyển tiếp"
1654
1655#: src/applications/advertising/advertising.c:898
1656#: src/applications/pingpong/pingpong.c:528
1657msgid "# plaintext PING messages sent"
1658msgstr "# các thông báo PING nhập thô được gửi"
1659
1660#: src/applications/advertising/advertising.c:904
1661#: src/applications/session/connect.c:932
1662#, c-format
1663msgid "`%s' registering handler %d (plaintext and ciphertext)\n"
1664msgstr "« %s » Ä‘ang đăng ký trình Ä‘iá»u khiển %d (nhập thô và văn bản mã hóa)\n"
1665
1666#: src/applications/advertising/advertising.c:922
1667msgid ""
1668"ensures that this peer is known by other peers and discovers other peers"
1669msgstr "đảm bảo là đồng đẳng này được biết bởi và phát hiện các đồng đẳng khác"
1670
1671#: src/applications/fragmentation/fragmentation.c:578
1672msgid "# messages defragmented"
1673msgstr "# các thông báo được chắp liá»n"
1674
1675#: src/applications/fragmentation/fragmentation.c:580
1676msgid "# messages fragmented"
1677msgstr "# các thông báo bị tế phân"
1678
1679#: src/applications/fragmentation/fragmentation.c:581
1680msgid "# fragments discarded"
1681msgstr "# các mảnh bị loại bá»"
1682
1683#: src/applications/fragmentation/fragmentation.c:592
1684#, c-format
1685msgid "`%s' registering handler %d\n"
1686msgstr "« %s » Ä‘ang đăng ký trình Ä‘iá»u khiển %d\n"
1687
1688#: src/applications/topology_default/topology.c:466
1689#, c-format
1690msgid "Could not read friends list `%s'\n"
1691msgstr "Không thể Ä‘á»c danh sách bạn bè « %s »\n"
1692
1693#: src/applications/topology_default/topology.c:485
1694#, c-format
1695msgid "Failed to read friends list from `%s'\n"
1696msgstr "Lá»—i Ä‘á»c danh sách bạn bè từ « %s »\n"
1697
1698#: src/applications/topology_default/topology.c:505
1699msgid "Syntax error in topology specification, skipping bytes.\n"
1700msgstr "Lá»—i cú pháp trong sá»± xác định địa hình há»c, Ä‘ang bá» qua các byte.\n"
1701
1702#: src/applications/topology_default/topology.c:523
1703#, c-format
1704msgid "Syntax error in topology specification, skipping bytes `%s'.\n"
1705msgstr ""
1706"Lá»—i cú pháp trong sá»± xác định địa hình há»c, Ä‘ang bá» qua các byte « %s ».\n"
1707
1708#: src/applications/topology_default/topology.c:535
1709msgid ""
1710"Fewer friends specified than required by minimum friend count. Will only "
1711"connect to friends.\n"
1712msgstr ""
1713"Xác định quá ít bạn bè (dưới số tối thiểu). Sẽ chỉ kết nối tới bạn bè.\n"
1714
1715#: src/applications/topology_default/topology.c:543
1716msgid ""
1717"More friendly connections required than target total number of connections.\n"
1718msgstr "Cần thiết nhiá»u kết nối bạn bè hÆ¡n tổng số kết nối đích.\n"
1719
1720#: src/applications/topology_default/topology.c:726
1721msgid "maintains GNUnet default mesh topology"
1722msgstr "bảo quản định hình mắc lưới mặc định của GNUnet"
1723
1724#: src/applications/chat/tools/gnunet-chat.c:107
1725msgid "anonymous"
1726msgstr "nặc danh"
1727
1728#: src/applications/chat/tools/gnunet-chat.c:113
1729#, c-format
1730msgid "`%s' said: %s\n"
1731msgstr "« %s » nói: %s\n"
1732
1733#: src/applications/chat/tools/gnunet-chat.c:116
1734#: src/applications/chat/tools/gnunet-chat.c:119
1735#, c-format
1736msgid "`%s' said to you: %s\n"
1737msgstr "« %s » nói cho bạn: %s\n"
1738
1739#: src/applications/chat/tools/gnunet-chat.c:122
1740#, c-format
1741msgid "`%s' said for sure: %s\n"
1742msgstr "« %s » nói thật: %s\n"
1743
1744#: src/applications/chat/tools/gnunet-chat.c:125
1745#, c-format
1746msgid "`%s' said to you for sure: %s\n"
1747msgstr "« %s » nói thật cho bạn: %s\n"
1748
1749#: src/applications/chat/tools/gnunet-chat.c:128
1750#, c-format
1751msgid "`%s' was confirmed that you received: %s\n"
1752msgstr "« %s » xác nhận bạn đã nhận được: %s\n"
1753
1754#: src/applications/chat/tools/gnunet-chat.c:131
1755#, c-format
1756msgid "`%s' was confirmed that you and only you received: %s\n"
1757msgstr "« %s » xác nhận mà chỉ bạn đã nhận được: %s\n"
1758
1759#: src/applications/chat/tools/gnunet-chat.c:134
1760#, c-format
1761msgid "`%s' was confirmed that you received from him or her: %s\n"
1762msgstr "« %s » xác nhận mà bạn đã nhận được từ hỠ: %s\n"
1763
1764#: src/applications/chat/tools/gnunet-chat.c:139
1765#, c-format
1766msgid "`%s' was confirmed that you and only you received from him or her: %s\n"
1767msgstr "« %s » xác nhận mà chỉ bạn đa nhận được từ hỠ: %s\n"
1768
1769#: src/applications/chat/tools/gnunet-chat.c:142
1770#, c-format
1771msgid "`%s' said off the record: %s\n"
1772msgstr "« %s » nói không chính thức: %s\n"
1773
1774#: src/applications/chat/tools/gnunet-chat.c:145
1775#, c-format
1776msgid "<%s> said using an unknown message type: %s\n"
1777msgstr "<%s> đã nói bằng một kiểu tin nhẳn không rõ : %s\n"
1778
1779#: src/applications/chat/tools/gnunet-chat.c:167
1780#, c-format
1781msgid "`%s' entered the room\n"
1782msgstr "« %s » vào phòng\n"
1783
1784#: src/applications/chat/tools/gnunet-chat.c:167
1785#, c-format
1786msgid "`%s' left the room\n"
1787msgstr "« %s » rá»i phòng\n"
1788
1789#: src/applications/chat/tools/gnunet-chat.c:239
1790#: src/applications/chat/tools/gnunet-chat.c:348
1791#, c-format
1792msgid "Failed to send message.\n"
1793msgstr "Lỗi gửi tin nhẳn.\n"
1794
1795#: src/applications/chat/tools/gnunet-chat.c:265
1796#: src/applications/chat/tools/gnunet-chat.c:524
1797#, c-format
1798msgid "Joined room `%s' as user `%s'.\n"
1799msgstr "Äã vào phòng « %s » là ngÆ°á»i dùng « %s ».\n"
1800
1801#: src/applications/chat/tools/gnunet-chat.c:293
1802#, c-format
1803msgid "Changed username to `%s'.\n"
1804msgstr "Äã thay đổi tên ngÆ°á»i dùng thành « %s ».\n"
1805
1806#: src/applications/chat/tools/gnunet-chat.c:301
1807#, c-format
1808msgid "Unknown command `%s'.\n"
1809msgstr "Không rõ câu lệnh « %s ».\n"
1810
1811#: src/applications/chat/tools/gnunet-chat.c:316
1812#, c-format
1813msgid "Syntax: /msg USERNAME MESSAGE"
1814msgstr "Cú pháp: /msg TÊN_NGƯỜI_DÙNG TIN_NHẲN"
1815
1816#: src/applications/chat/tools/gnunet-chat.c:324
1817#, c-format
1818msgid "Unknown user `%s'\n"
1819msgstr "Không rõ ngÆ°á»i dùng « %s »\n"
1820
1821#: src/applications/chat/tools/gnunet-chat.c:339
1822#, c-format
1823msgid "User `%s' is currently not in the room!\n"
1824msgstr "NgÆ°á»i dùng « %s » hiện thá»i không có trong phòng này.\n"
1825
1826#: src/applications/chat/tools/gnunet-chat.c:361
1827#, c-format
1828msgid "Users in room `%s': "
1829msgstr "NgÆ°á»i dùng trong phòng « %s »:"
1830
1831#: src/applications/chat/tools/gnunet-chat.c:390
1832msgid ""
1833"Use `/join #roomname' to join a chat room. Joining a room will cause you to "
1834"leave the current room"
1835msgstr ""
1836"Gõ chuỗi « /join #tên_phòng » để vào một phòng trò chuyện nào đó (việc này "
1837"cÅ©ng gây ra bạn ra khá»i phòng hiện tại)"
1838
1839#: src/applications/chat/tools/gnunet-chat.c:393
1840msgid ""
1841"Use `/nick nickname' to change your nickname. This will cause you to leave "
1842"the current room and immediately rejoin it with the new name."
1843msgstr ""
1844"Gõ chuỗi « /nick tên_hiệu » để thay đổi tên hiệu của mình (việc này cũng gây "
1845"ra bạn ra khá»i phòng hiện tại, sau đó vào lại ngay vá»›i tên má»›i)"
1846
1847#: src/applications/chat/tools/gnunet-chat.c:396
1848msgid ""
1849"Use `/msg nickname message' to send a private message to the specified user"
1850msgstr ""
1851"Gõ chuá»—i « /msg tên_hiệu tin_nhẳn » để gá»­i má»™t tin nhẳn riêng cho ngÆ°á»i dùng "
1852"có tên đó"
1853
1854#: src/applications/chat/tools/gnunet-chat.c:398
1855msgid "The `/notice' command is an alias for `/msg'"
1856msgstr "Lệnh « /notice » là một biệt hiệu cho « /msg »"
1857
1858#: src/applications/chat/tools/gnunet-chat.c:400
1859msgid "The `/query' command is an alias for `/msg'"
1860msgstr "Lệnh « /query » là một biệt hiệu cho « /msg »"
1861
1862#: src/applications/chat/tools/gnunet-chat.c:402
1863msgid "Use `/quit' to terminate gnunet-chat"
1864msgstr "Gõ chuá»—i « /quit » để thoát khá»i trình gnunet-chat"
1865
1866#: src/applications/chat/tools/gnunet-chat.c:404
1867msgid "The `/leave' command is an alias for `/quit'"
1868msgstr "Lệnh « /leave » là một biệt hiệu cho « /quit »"
1869
1870#: src/applications/chat/tools/gnunet-chat.c:407
1871msgid "Use `/names' to list all of the current members in the chat room"
1872msgstr ""
1873"Gõ chuá»—i « /names » để liệt kê tất cả các thành viên hiện thá»i trong phòng "
1874"trò chuyện đó"
1875
1876#: src/applications/chat/tools/gnunet-chat.c:409
1877msgid "Use `/help command' to get help for a specific command"
1878msgstr "Gõ chuỗi « /help LỆNH » để xem trợ giúp vỠlệnh đó"
1879
1880#: src/applications/chat/tools/gnunet-chat.c:457
1881msgid "Join a chat on GNUnet."
1882msgstr "Vào phòng trò chuyện trên GNUnet."
1883
1884#: src/applications/chat/tools/gnunet-chat.c:461
1885msgid "set the nickname to use (required)"
1886msgstr "đặt tên hiệu cần dùng (cần thiết)"
1887
1888#: src/applications/chat/tools/gnunet-chat.c:464
1889msgid "set the chat room to join"
1890msgstr "đặt phòng trò chuyện cần vào"
1891
1892#: src/applications/chat/tools/gnunet-chat.c:495
1893#, c-format
1894msgid "You must specify a nickname\n"
1895msgstr "Phải ghi rõ tên hiệu\n"
1896
1897#: src/applications/chat/tools/gnunet-chat.c:515
1898#, c-format
1899msgid "Failed to join room `%s'\n"
1900msgstr "Lỗi vào phòng « %s »\n"
1901
1902#: src/applications/chat/module/chat.c:325
1903#, c-format
1904msgid "`%s' registering CS handlers %d and %d\n"
1905msgstr "« %s » Ä‘ang đăng ký các trình Ä‘iá»u khiển CS %d và %d\n"
1906
1907#: src/applications/chat/module/chat.c:347
1908msgid "enables P2P-chat (incomplete)"
1909msgstr "hiệu lực trò chuyện giữa các đồng đẳng (chưa hoàn tất)"
1910
1911#: src/applications/chat/lib/messaging.c:353
1912#: src/applications/identity/hostkey.c:122
1913#, c-format
1914msgid "Failed to access GNUnet home directory `%s'\n"
1915msgstr "Lỗi truy cập đến thư mục nhà GNUnet « %s »\n"
1916
1917#: src/applications/chat/lib/messaging.c:389
1918#, c-format
1919msgid "Existing key in file `%s' failed format check, creating new key.\n"
1920msgstr ""
1921"Kiểm tra định dạng của chìa khóa đã có trong tập tin « %s » không thành công, "
1922"đang tạo chìa khóa máy mới.\n"
1923
1924#: src/applications/chat/lib/messaging.c:399
1925msgid "Creating new key for this nickname (this may take a while).\n"
1926msgstr "Äang tạo khoá má»›i cho tên hiệu này (có thể hÆ¡i lâu).\n"
1927
1928#: src/applications/chat/lib/messaging.c:411
1929msgid "Done creating key.\n"
1930msgstr "Hoàn thành tạo khoá.\n"
1931
1932#: src/applications/dstore_mysql/dstore_mysql.c:471
1933msgid "Failed to initialize MySQL database connection for dstore.\n"
1934msgstr "Lỗi sơ khởi kết nối cơ sở dữ liệu MySQL cho kho dữ liệu.\n"
1935
1936#: src/applications/dstore_mysql/dstore_mysql.c:494
1937#: src/applications/dstore_sqlite/dstore.c:636
1938msgid "# bytes in dstore"
1939msgstr "# các byte trong kho dữ liệu"
1940
1941#: src/applications/dstore_mysql/dstore_mysql.c:496
1942#: src/applications/dstore_sqlite/dstore.c:638
1943msgid "# max bytes allowed in dstore"
1944msgstr "# các byte được phép trong kho dữ liệu dstore"
1945
1946#: src/applications/transport/transport.c:191
1947#, c-format
1948msgid ""
1949"Converting peer address to string failed, transport type %d not supported\n"
1950msgstr ""
1951"Lá»—i chuyển đổi địa chỉ đồng đẳng sang chuá»—i, kiểu truyá»n tải %d không được "
1952"hỗ trợ\n"
1953
1954#: src/applications/transport/transport.c:246
1955#, c-format
1956msgid "Transport connection attempt failed, transport type %d not supported\n"
1957msgstr "Lá»—i thá»­ kết nối truyá»n tải, kiểu cÆ¡ chế truyá»n %d không được há»— trợ\n"
1958
1959#: src/applications/transport/transport.c:299
1960#, c-format
1961msgid ""
1962"Transport failed to connect to peer `%s' (%u HELLOs known, none worked)\n"
1963msgstr ""
1964"Truyá»n tải không kết nối được tá»›i đồng đẳng « %s » (đã biết %u tín hiệu "
1965"HELLO, mà không có tín hiệu nào hoạt động được)\n"
1966
1967#: src/applications/transport/transport.c:376
1968#, c-format
1969msgid "Transmission attempt failed, transport type %d unknown.\n"
1970msgstr "Lá»—i thá»­ gá»­i, kiểu truyá»n tải %d không được há»— trợ\n"
1971
1972#: src/applications/transport/transport.c:500
1973#, c-format
1974msgid "No transport of type %d known.\n"
1975msgstr "Không biết truyá»n tải nào kiểu %d.\n"
1976
1977#: src/applications/transport/transport.c:560
1978msgid "No transport succeeded in creating a hello!\n"
1979msgstr "Không có truyá»n tải nào đã tạo được má»™t tín hiệu HELLO.\n"
1980
1981#: src/applications/transport/transport.c:761
1982#, c-format
1983msgid "Loading transports `%s'\n"
1984msgstr "Äang nạp các truyá»n tải « %s »\n"
1985
1986#: src/applications/transport/transport.c:781
1987#, c-format
1988msgid "Could not load transport plugin `%s'\n"
1989msgstr "Không thể nạp phần bổ sung truyá»n tải « %s »\n"
1990
1991#: src/applications/transport/transport.c:795
1992#, c-format
1993msgid "Transport library `%s' did not provide required function '%s%s'.\n"
1994msgstr "ThÆ° viện truyá»n tải « %s » không cung cấp chức năng yêu cầu « %s%s ».\n"
1995
1996#: src/applications/transport/transport.c:824
1997#, c-format
1998msgid "Loaded transport `%s'\n"
1999msgstr "Äã nạp truyá»n tải « %s »\n"
2000
2001#: src/applications/transport/transport.c:836
2002#: src/server/gnunet-peer-info.c:252
2003#, c-format
2004msgid "I am peer `%s'.\n"
2005msgstr "Tôi là đồng đẳng « %s ».\n"
2006
2007#: src/applications/dht/tools/dht_multipeer_test.c:80
2008#: src/applications/dht/tools/dht_twopeer_test.c:47
2009#: src/applications/dht/module/table.c:783
2010msgid "# dht connections"
2011msgstr "# các kết nối dht"
2012
2013#: src/applications/dht/tools/dht-query.c:54
2014msgid "Query (get KEY, put KEY VALUE) DHT table."
2015msgstr "Há»i (nhận KHOÃ, gá»­i GIÃ_TRỊ_KHOÃ) bảng DHT."
2016
2017#: src/applications/dht/tools/dht-query.c:58
2018msgid "allow TIME ms to process a GET command"
2019msgstr "cho phép THỜI_GIAN mili giây để xử lý mỗi câu lệnh GET (lấy)"
2020
2021#: src/applications/dht/tools/dht-query.c:107
2022#, c-format
2023msgid "Issuing `%s(%s,%s)' command.\n"
2024msgstr "Äang cấp câu lệnh « %s(%s,%s) ».\n"
2025
2026#: src/applications/dht/tools/dht-query.c:142
2027#: src/applications/fs/tools/gnunet-auto-share.c:669
2028#, c-format
2029msgid "Failed to connect to gnunetd.\n"
2030msgstr "Lỗi kết nối đến gnunetd.\n"
2031
2032#: src/applications/dht/tools/dht-query.c:155
2033#, c-format
2034msgid "Command `%s' requires an argument (`%s').\n"
2035msgstr "Câu lệnh « %s » cần đến một đối số (« %s »).\n"
2036
2037#: src/applications/dht/tools/dht-query.c:172
2038#, c-format
2039msgid "Command `%s' requires two arguments (`%s' and `%s').\n"
2040msgstr "Câu lệnh « %s » cần đến hai đối số (« %s » và « %s »).\n"
2041
2042#: src/applications/dht/tools/dht-query.c:183
2043#, c-format
2044msgid "Unsupported command `%s'. Aborting.\n"
2045msgstr "Lệnh không được há»— trợ « %s ». Äang hủy bá».\n"
2046
2047#: src/applications/dht/module/table.c:785
2048msgid "# dht discovery messages received"
2049msgstr "# các thông báo phát hiện dht được nhận"
2050
2051#: src/applications/dht/module/table.c:787
2052msgid "# dht route host lookups performed"
2053msgstr "# các việc tra tìm Ä‘Æ°á»ng tá»›i máy dht được làm"
2054
2055#: src/applications/dht/module/table.c:789
2056msgid "# dht discovery messages sent"
2057msgstr "# các thông báo phát hiện dht được gửi"
2058
2059#: src/applications/dht/module/routing.c:879
2060msgid "# dht replies routed"
2061msgstr "# các đáp ứng dht được định tuyến"
2062
2063#: src/applications/dht/module/routing.c:881
2064msgid "# dht requests routed"
2065msgstr "# các yêu cầu dht được định tuyến"
2066
2067#: src/applications/dht/module/routing.c:883
2068msgid "# dht get requests received"
2069msgstr "# các yêu cầu get (lấy) dht được nhận"
2070
2071#: src/applications/dht/module/routing.c:885
2072msgid "# dht put requests received"
2073msgstr "# các yêu cầu put (gửi) dht được nhận"
2074
2075#: src/applications/dht/module/routing.c:887
2076msgid "# dht results received"
2077msgstr "# các kết quả dht được nhận"
2078
2079#: src/applications/dht/module/routing.c:892
2080#, c-format
2081msgid "`%s' registering p2p handlers: %d %d %d\n"
2082msgstr "« %s » Ä‘ang đăng ký các trình Ä‘iá»u khiển p2p: %d %d %d\n"
2083
2084#: src/applications/dht/module/cs.c:122
2085#, c-format
2086msgid "`%s' failed. Terminating connection to client.\n"
2087msgstr "« %s » bị lá»—i. Äang chấm dứt kết nối tá»›i máy khách.\n"
2088
2089#: src/applications/dht/module/cs.c:250
2090#, c-format
2091msgid "`%s' registering client handlers: %d %d\n"
2092msgstr "« %s » Ä‘ang đăng ký các trình Ä‘iá»u khiển máy khách: %d %d\n"
2093
2094#: src/applications/dht/module/cs.c:273
2095msgid "Enables efficient non-anonymous routing"
2096msgstr "Hiệu lực định tuyến khác nặc danh hiệu dụng"
2097
2098#: src/applications/identity/hostkey.c:155
2099#, c-format
2100msgid ""
2101"Existing hostkey in file `%s' failed format check, creating new hostkey.\n"
2102msgstr ""
2103"Kiểm tra định dạng của chìa khóa máy trong tập tin « %s » không thành công, "
2104"đang tạo chìa khóa máy mới.\n"
2105
2106#: src/applications/identity/hostkey.c:164
2107msgid "Creating new hostkey (this may take a while).\n"
2108msgstr "Äang tạo khoá máy má»›i (có thể hÆ¡i lâu).\n"
2109
2110#: src/applications/identity/hostkey.c:176
2111msgid "Done creating hostkey.\n"
2112msgstr "Hoàn thành tạo khoá máy.\n"
2113
2114#: src/applications/identity/identity.c:333
2115#, c-format
2116msgid ""
2117"File `%s' in directory `%s' does not match naming convention. Removed.\n"
2118msgstr ""
2119"Tập tin « %s » trong thÆ° mục « %s » không tùy theo quy Æ°á»›c đặt tên. Bị gỡ bá».\n"
2120
2121#: src/applications/identity/identity.c:408
2122#, c-format
2123msgid "Still no peers found in `%s'!\n"
2124msgstr "Vẫn còn không tìm thấy đồng đẳng trong « %s ».\n"
2125
2126#: src/applications/identity/identity.c:731
2127#: src/applications/identity/identity.c:757
2128#, c-format
2129msgid "Removed file `%s' containing invalid HELLO data.\n"
2130msgstr "Äã gỡ bá» tập tin « %s » chứa dữ liệu HELLO sai.\n"
2131
2132#: src/applications/identity/identity.c:809
2133#, c-format
2134msgid "Signature failed verification: peer `%s' not known.\n"
2135msgstr "Không thẩm tra được chữ ký: không rõ đồng đẳng « %s ».\n"
2136
2137#: src/applications/identity/identity.c:819
2138msgid "Signature failed verification: signature invalid.\n"
2139msgstr "Không thẩm tra được chữ ký: chữ ký sai.\n"
2140
2141#: src/applications/identity/identity.c:935
2142#: src/applications/identity/identity.c:1058
2143#, c-format
2144msgid "Peer `%s' is currently strictly blacklisted (for another %llums).\n"
2145msgstr ""
2146"Äồng đẳng « %s » hiện thá»i bị cấm hoàn toàn (trong %llu miligiây sau).\n"
2147
2148#: src/applications/identity/identity.c:1061
2149#, c-format
2150msgid "Peer `%s' is currently blacklisted (for another %llums).\n"
2151msgstr "Äồng đẳng « %s » hiện thá»i bị cấm (trong %llu miligiây sau).\n"
2152
2153#: src/applications/pingpong/pingpong.c:134
2154#: src/applications/pingpong/pingpong.c:203
2155#: src/applications/pingpong/pingpong.c:273
2156#: src/applications/pingpong/pingpong.c:345
2157#, c-format
2158msgid "Received malformed `%s' message. Dropping.\n"
2159msgstr "Nhận được thông báo « %s » bị há»ng. Äang bá» Ä‘i.\n"
2160
2161#: src/applications/pingpong/pingpong.c:146
2162msgid "Received ping for another peer. Dropping.\n"
2163msgstr "Nhận được tin hiệu ping cho đồng đẳng khác. Äang bá» Ä‘i.\n"
2164
2165#: src/applications/pingpong/pingpong.c:215
2166#, c-format
2167msgid "Received PING from `%s' not destined for us!\n"
2168msgstr "Nhận được PING « %s » không dành cho chúng ta.\n"
2169
2170#: src/applications/pingpong/pingpong.c:315
2171#: src/applications/pingpong/pingpong.c:381
2172msgid ""
2173"Could not match PONG against any PING. Try increasing MAX_PING_PONG "
2174"constant.\n"
2175msgstr ""
2176"Không tương ứng được PONG đối với bất kỳ PING. Hãy thử tăng hằng số "
2177"MAX_PING_PONG.\n"
2178
2179#: src/applications/pingpong/pingpong.c:425
2180msgid "Cannot create PING, table full. Try increasing MAX_PING_PONG.\n"
2181msgstr "Không tạo được PING, bảng đầy. Hãy thử tăng MAX_PING_PONG.\n"
2182
2183#: src/applications/pingpong/pingpong.c:518
2184msgid "# encrypted PONG messages received"
2185msgstr "# các thông báo PONG đã mật mã được nhận"
2186
2187#: src/applications/pingpong/pingpong.c:520
2188msgid "# plaintext PONG messages received"
2189msgstr "# các thông báo PONG nhập thô được nhận"
2190
2191#: src/applications/pingpong/pingpong.c:522
2192msgid "# encrypted PING messages received"
2193msgstr "# các thông báo PING đã mật mã được nhận"
2194
2195#: src/applications/pingpong/pingpong.c:524
2196msgid "# PING messages created"
2197msgstr "# các thông báo PING được tạo"
2198
2199#: src/applications/pingpong/pingpong.c:526
2200#: src/applications/session/connect.c:926
2201msgid "# encrypted PONG messages sent"
2202msgstr "# các thông báo PONG đã mật mã được gửi"
2203
2204#: src/applications/pingpong/pingpong.c:530
2205#: src/applications/session/connect.c:924
2206msgid "# encrypted PING messages sent"
2207msgstr "# các thông báo PING đã mật mã được gửi"
2208
2209#: src/applications/pingpong/pingpong.c:532
2210msgid "# plaintext PONG messages sent"
2211msgstr "# các thông báo PONG nhập thô được gửi"
2212
2213#: src/applications/pingpong/pingpong.c:536
2214msgid "# plaintext PONG transmissions failed"
2215msgstr "# các sá»± truyá»n PONG bị lá»—i"
2216
2217#: src/applications/pingpong/pingpong.c:546
2218#, c-format
2219msgid "`%s' registering handlers %d %d (plaintext and ciphertext)\n"
2220msgstr ""
2221"« %s » Ä‘ang đăng ký các trình Ä‘iá»u khiển %d %d (nhập thô và văn bản mã hóa)\n"
2222
2223#: src/applications/hostlist/hostlist.c:165
2224msgid "# hostlist requests received"
2225msgstr "# các yêu cầu danh sách máy được nhận"
2226
2227#: src/applications/hostlist/hostlist.c:167
2228msgid "# hostlist HELLOs returned"
2229msgstr "# các lá»i chào mừng HELLO danh sách máy được trả vá»"
2230
2231#: src/applications/hostlist/hostlist.c:169
2232msgid "# hostlist bytes returned"
2233msgstr "# các byte danh sách máy được trả vá»"
2234
2235#: src/applications/hostlist/hostlist.c:199
2236msgid "integrated HTTP hostlist server"
2237msgstr "trình phục vụ danh sách máy HTTP hợp nhất"
2238
2239#: src/applications/session/connect.c:238
2240#, c-format
2241msgid "Session key from peer `%s' could not be verified.\n"
2242msgstr "Khoá phiên chạy từ đồng đẳng « %s » không thể được thẩm tra.\n"
2243
2244#: src/applications/session/connect.c:282
2245#, c-format
2246msgid "Cannot encrypt sessionkey, peer `%s' not known!\n"
2247msgstr "Không thể mã hoá khoá phiên chạy, không rõ đồng đẳng « %s ».\n"
2248
2249#: src/applications/session/connect.c:489
2250#, c-format
2251msgid "Could not create any HELLO for myself (have transports `%s')!\n"
2252msgstr "Không thể tạo tín hiệu HELLO nào cho mình (có truyá»n tải « %s »).\n"
2253
2254#: src/applications/session/connect.c:599
2255#, c-format
2256msgid "Session key received from peer `%s' has invalid format (discarded).\n"
2257msgstr ""
2258"Khoá phiên chạy được nhận từ đồng đẳng « %s » có định dạng sai (bị hủy).\n"
2259
2260#: src/applications/session/connect.c:632
2261#, c-format
2262msgid "Session key received from peer `%s' is for `%s' and not for me!\n"
2263msgstr ""
2264"Khoá phiên chạy được nhận từ đồng đẳng « %s » dành cho « %s », không phải cho "
2265"tôi.\n"
2266
2267#: src/applications/session/connect.c:659
2268#, c-format
2269msgid "Invalid `%s' message received from peer `%s'.\n"
2270msgstr "Nhận được thông báo « %s » sai từ đồng đẳng « %s ».\n"
2271
2272#: src/applications/session/connect.c:670
2273#, c-format
2274msgid "setkey `%s' from `%s' fails CRC check (have: %u, want %u).\n"
2275msgstr ""
2276"Kiểm tra CRC setkey « %s » từ « %s » không thành công (có %u, còn muốn %u).\n"
2277
2278#: src/applications/session/connect.c:728
2279#, c-format
2280msgid ""
2281"Error parsing encrypted session key from `%s', given message part size is "
2282"invalid.\n"
2283msgstr ""
2284"Lỗi phân tích chìa khóa phiên chạy đã mã hóa từ « %s », kích cỡ của phần "
2285"thông báo đưa ra là sai.\n"
2286
2287#: src/applications/session/connect.c:741
2288#, c-format
2289msgid "Unknown type in embedded message from `%s': %u (size: %u)\n"
2290msgstr "Gặp kiểu không rõ trong thông báo nhúng từ « %s »: %u (kích cỡ : %u)\n"
2291
2292#: src/applications/session/connect.c:916
2293msgid "# session keys sent"
2294msgstr "# các khoá phiên chạy được gửi"
2295
2296#: src/applications/session/connect.c:918
2297msgid "# session keys rejected"
2298msgstr "# các khoá phiên chạy bị từ chối"
2299
2300#: src/applications/session/connect.c:920
2301msgid "# session keys accepted"
2302msgstr "# các khoá phiên chạy được chấp nhận"
2303
2304#: src/applications/session/connect.c:922
2305msgid "# sessions established"
2306msgstr "# các phiên chạy được thiết lập"
2307
2308#: src/applications/fs/tools/gnunet-pseudonym.c:70
2309#: src/applications/fs/tools/gnunet-auto-share.c:199
2310#: src/applications/fs/tools/gnunet-insert.c:246
2311#: src/applications/fs/tools/gnunet-search.c:125
2312#: src/applications/fs/tools/gnunet-download.c:77
2313msgid "set the desired LEVEL of sender-anonymity"
2314msgstr "đặt CẤP mong muốn của tình trạng nặc danh của ngÆ°á»i gá»­i"
2315
2316#: src/applications/fs/tools/gnunet-pseudonym.c:73
2317msgid "automate creation of a namespace by starting a collection"
2318msgstr "tự động tạo một không gian tên bằng cách bắt đầu một thu thập"
2319
2320#: src/applications/fs/tools/gnunet-pseudonym.c:77
2321msgid "create a new pseudonym under the given NICKNAME"
2322msgstr "tạo một biệt hiệu mới dưới TÊN_HIỆU đưa ra"
2323
2324#: src/applications/fs/tools/gnunet-pseudonym.c:80
2325msgid "delete the pseudonym with the given NICKNAME"
2326msgstr "xoá biệt hiệu có TÊN_HIỆU đã cho"
2327
2328#: src/applications/fs/tools/gnunet-pseudonym.c:83
2329msgid "end automated building of a namespace (ends collection)"
2330msgstr "kết thúc việc tự động xây dựng một không gian tên (kết thúc thu thập)"
2331
2332#: src/applications/fs/tools/gnunet-pseudonym.c:85
2333msgid "Create new pseudonyms, delete pseudonyms or list existing pseudonyms."
2334msgstr "Tạo biệt hiệu mới, xóa biệt hiệu hoặc liệt kê các biệt hiệu có."
2335
2336#: src/applications/fs/tools/gnunet-pseudonym.c:89
2337msgid ""
2338"use the given keyword to advertise the namespace (use when creating a new "
2339"pseudonym)"
2340msgstr ""
2341"sử dụng từ khóa đưa ra để quảng cáo không gian tên (dùng khi tạo một biệt "
2342"hiệu mới)"
2343
2344#: src/applications/fs/tools/gnunet-pseudonym.c:92
2345msgid "specify metadata describing the namespace or collection"
2346msgstr "ghi rõ siêu dữ liệu mô tả không gian tên (hoặc thu thập)"
2347
2348#: src/applications/fs/tools/gnunet-pseudonym.c:96
2349msgid ""
2350"do not generate an advertisement for this namespace (use when creating a new "
2351"pseudonym)"
2352msgstr ""
2353"đừng tạo ra một quảng cáo cho không gian tên này (dùng khi tạo một biệt hiệu "
2354"má»›i)"
2355
2356#: src/applications/fs/tools/gnunet-pseudonym.c:99
2357msgid "do not list the pseudonyms from the pseudonym database"
2358msgstr "không liệt kê các biệt hiệu từ cơ sở dữ liệu biệt hiệu"
2359
2360#: src/applications/fs/tools/gnunet-pseudonym.c:103
2361msgid ""
2362"specify IDENTIFIER to be the address of the entrypoint to content in the "
2363"namespace (use when creating a new pseudonym)"
2364msgstr ""
2365"ghi rõ BỘ_NHẬN_DIỆN là địa chỉ của điểm vào nội dung trong không gian tên "
2366"(dùng khi tạo một biệt hiệu mới)"
2367
2368#: src/applications/fs/tools/gnunet-pseudonym.c:106
2369msgid "set the rating of a namespace"
2370msgstr "đặt đánh giá của một không gian tên"
2371
2372#: src/applications/fs/tools/gnunet-pseudonym.c:141
2373#, c-format
2374msgid "Namespace `%s' has rating %d.\n"
2375msgstr "Không gian tên « %s » có đánh giá %d.\n"
2376
2377#: src/applications/fs/tools/gnunet-pseudonym.c:143
2378#, c-format
2379msgid "Namespace `%s' (%s) has rating %d.\n"
2380msgstr "Không gian tên « %s » (%s) có đánh giá %d.\n"
2381
2382#: src/applications/fs/tools/gnunet-pseudonym.c:175
2383#, c-format
2384msgid "\tRating (after update): %d\n"
2385msgstr "\tÄánh giá (sau khi cập nhật): %d\n"
2386
2387#: src/applications/fs/tools/gnunet-pseudonym.c:179
2388#: src/applications/fs/tools/gnunet-pseudonym.c:241
2389#: src/applications/fs/tools/gnunet-insert.c:101
2390#, c-format
2391msgid "\tUnknown namespace `%s'\n"
2392msgstr "\tKhông rõ miá»n tên « %s »\n"
2393
2394#: src/applications/fs/tools/gnunet-pseudonym.c:217
2395#, c-format
2396msgid "Collection stopped.\n"
2397msgstr "Thu thập bị dừng.\n"
2398
2399#: src/applications/fs/tools/gnunet-pseudonym.c:219
2400#, c-format
2401msgid "Failed to stop collection (not active?).\n"
2402msgstr "Lỗi dừng thu thập (không hoạt động ?).\n"
2403
2404#: src/applications/fs/tools/gnunet-pseudonym.c:230
2405#, c-format
2406msgid "Pseudonym `%s' deleted.\n"
2407msgstr "Biệt hiệu « %s » bị xoá.\n"
2408
2409#: src/applications/fs/tools/gnunet-pseudonym.c:235
2410#, c-format
2411msgid "Error deleting pseudonym `%s' (does not exist?).\n"
2412msgstr "Lỗ xoá biệt hiệu « %s » (không tồn tại ?).\n"
2413
2414#: src/applications/fs/tools/gnunet-pseudonym.c:256
2415msgid "Started collection.\n"
2416msgstr "Äã bắt đầu thu thập.\n"
2417
2418#: src/applications/fs/tools/gnunet-pseudonym.c:260
2419msgid "Failed to start collection.\n"
2420msgstr "Lỗi bắt đầu thu thập.\n"
2421
2422#: src/applications/fs/tools/gnunet-pseudonym.c:296
2423msgid "Could not create namespace.\n"
2424msgstr "Không thể tạo miá»n tên.\n"
2425
2426#: src/applications/fs/tools/gnunet-pseudonym.c:304
2427#, c-format
2428msgid "Namespace `%s' created (root: %s).\n"
2429msgstr "Äã tạo không gian tên « %s » (gốc: %s).\n"
2430
2431#: src/applications/fs/tools/gnunet-pseudonym.c:321
2432#, c-format
2433msgid "You must specify a name for the collection (`%s' option).\n"
2434msgstr "Bạn phải ghi rõ má»™t tên cho thu thập (tùy chá»n « %s »).\n"
2435
2436#: src/applications/fs/tools/gnunet-pseudonym.c:329
2437#, c-format
2438msgid "Could not access namespace information.\n"
2439msgstr "Không thể truy cập đến thông tin vỠkhông gian tên.\n"
2440
2441#: src/applications/fs/tools/gnunet-directory.c:84
2442#, c-format
2443msgid "==> Directory `%s':\n"
2444msgstr "==> Thư mục « %s »:\n"
2445
2446#: src/applications/fs/tools/gnunet-directory.c:88
2447#, c-format
2448msgid "=\tError reading directory.\n"
2449msgstr "=\tLá»—i Ä‘á»c thÆ° mục.\n"
2450
2451#: src/applications/fs/tools/gnunet-directory.c:118
2452#, c-format
2453msgid "File format error (not a GNUnet directory?)\n"
2454msgstr "Lỗi định dạng tập tin (không phải là thư mục GNUnet ?)\n"
2455
2456#: src/applications/fs/tools/gnunet-directory.c:120
2457#, c-format
2458msgid "%d files found in directory.\n"
2459msgstr "Tìm thấy %d tập tin trong thư mục.\n"
2460
2461#: src/applications/fs/tools/gnunet-directory.c:135
2462msgid "Perform directory related operations."
2463msgstr "Thực hiện các thao tác liên quan đến thư mục."
2464
2465#: src/applications/fs/tools/gnunet-directory.c:138
2466msgid "remove all entries from the directory database and stop tracking URIs"
2467msgstr ""
2468"gỡ bá» má»i mục nhập khá»i cÆ¡ sở dữ liệu thÆ° mục, và dừng theo dõi các địa chỉ "
2469"URI"
2470
2471#: src/applications/fs/tools/gnunet-directory.c:142
2472msgid "list entries from the directory database"
2473msgstr "liệt kê các mục nhập từ cơ sở dữ liệu thư mục"
2474
2475#: src/applications/fs/tools/gnunet-directory.c:145
2476msgid "start tracking entries for the directory database"
2477msgstr "bắt đầu theo dõi các mục nhập cho cơ sở dữ liệu thư mục"
2478
2479#: src/applications/fs/tools/gnunet-directory.c:168
2480#, c-format
2481msgid "Listed %d matching entries.\n"
2482msgstr "Äã liệt kê %d mục nhập tÆ°Æ¡ng ứng.\n"
2483
2484#: src/applications/fs/tools/gnunet-auto-share.c:117
2485#, c-format
2486msgid "Upload of `%s' at %llu out of %llu bytes.\n"
2487msgstr "Tải lên tập tin « %s » tại %llu trên %llu byte.\n"
2488
2489#: src/applications/fs/tools/gnunet-auto-share.c:130
2490#, c-format
2491msgid "Upload of `%s' complete, URI is `%s'.\n"
2492msgstr "Tải lên « %s » hoàn thành, địa chỉ URI là « %s ».\n"
2493
2494#: src/applications/fs/tools/gnunet-auto-share.c:139
2495#, c-format
2496msgid "Upload aborted.\n"
2497msgstr "Tải lên bị hủy bá».\n"
2498
2499#: src/applications/fs/tools/gnunet-auto-share.c:145
2500#, c-format
2501msgid "Error uploading file: %s\n"
2502msgstr "Gặp lỗi khi tải lên tập tin: %s\n"
2503
2504#: src/applications/fs/tools/gnunet-auto-share.c:154
2505#, c-format
2506msgid "Starting upload of `%s'.\n"
2507msgstr "Äang bắt đầu tài lên « %s ».\n"
2508
2509#: src/applications/fs/tools/gnunet-auto-share.c:164
2510#, c-format
2511msgid "Uploading suspended.\n"
2512msgstr "Tiến trình tải lên bị ngưng.\n"
2513
2514#: src/applications/fs/tools/gnunet-auto-share.c:179
2515#, c-format
2516msgid "Uploading `%s' resumed.\n"
2517msgstr "Tiến trình tải lên « %s » đã tiếp tục lại.\n"
2518
2519#: src/applications/fs/tools/gnunet-auto-share.c:186
2520#, c-format
2521msgid "Unexpected event: %d\n"
2522msgstr "Gặp sá»± kiện bất thÆ°á»ng: %d\n"
2523
2524#: src/applications/fs/tools/gnunet-auto-share.c:205
2525msgid ""
2526"run in debug mode; gnunet-auto-share will not daemonize and error messages "
2527"will be written to stderr instead of a logfile"
2528msgstr ""
2529"chạy trong chế độ tìm sửa lỗi; gnunet-auto-share sẽ không trở thành trình "
2530"ná»n và sẽ ghi thông báo lá»—i ra đầu lá»—i tiêu chuẩn thay vì vào má»™t tập tin "
2531"ghi sự kiện."
2532
2533#: src/applications/fs/tools/gnunet-auto-share.c:211
2534#: src/applications/fs/tools/gnunet-insert.c:259
2535msgid ""
2536"do not use libextractor to add additional references to directory entries "
2537"and/or the published file"
2538msgstr ""
2539"đừng dùng libextractor để thêm các tham chiếu bổ sung vào mục nhập thư mục "
2540"và/hay tập tin công bố"
2541
2542#: src/applications/fs/tools/gnunet-auto-share.c:213
2543msgid "Automatically share a directory."
2544msgstr "Tự động chia sẻ một thư mục."
2545
2546#: src/applications/fs/tools/gnunet-auto-share.c:216
2547#: src/applications/fs/tools/gnunet-insert.c:273
2548msgid ""
2549"add an additional keyword for all files and directories (this option can be "
2550"specified multiple times)"
2551msgstr ""
2552"thêm một từ khóa bổ sung cho tất cả tập tin và thư mục (có thể chỉ ra tùy "
2553"chá»n này nhiá»u lần)"
2554
2555#: src/applications/fs/tools/gnunet-auto-share.c:221
2556#: src/applications/fs/tools/gnunet-insert.c:290
2557msgid "specify the priority of the content"
2558msgstr "xác định mức ưu tiên của nội dung"
2559
2560#: src/applications/fs/tools/gnunet-auto-share.c:468
2561#: src/applications/fs/tools/gnunet-auto-share.c:903
2562#, c-format
2563msgid "Could not access `%s': %s\n"
2564msgstr "Không thể truy cập đến « %s »: %s\n"
2565
2566#: src/applications/fs/tools/gnunet-auto-share.c:547
2567#, c-format
2568msgid "Unknown keyword type `%s' in metadata configuration\n"
2569msgstr "Không rõ kiểu từ khoá « %s » trong cấu hình siêu dữ liệu\n"
2570
2571#: src/applications/fs/tools/gnunet-auto-share.c:652
2572#, c-format
2573msgid "Failed to stop running gnunet-auto-share.\n"
2574msgstr "Lỗi dừng chạy gnunet-auto-share.\n"
2575
2576#: src/applications/fs/tools/gnunet-auto-share.c:918
2577#, c-format
2578msgid "Directory `%s' is already on the list of shared directories.\n"
2579msgstr "Thư mục « %s » đã có trong danh sách các thư mục dùng chung.\n"
2580
2581#: src/applications/fs/tools/gnunet-auto-share.c:939
2582msgid ""
2583"The specified directories were added to the list of shared directories.\n"
2584msgstr ""
2585"Những thư mục đưa ra đã được thêm vào danh sách các thư mục dùng chung.\n"
2586
2587#: src/applications/fs/tools/gnunet-auto-share.c:961
2588#, c-format
2589msgid "Could not open logfile `%s': %s\n"
2590msgstr "Lỗi mở tập tin theo dõi « %s »: %s\n"
2591
2592#: src/applications/fs/tools/gnunet-insert.c:115
2593#, c-format
2594msgid "Created entry `%s' in namespace `%s'\n"
2595msgstr "Äã tạo mục nhập « %s » trong không gian tên « %s »\n"
2596
2597#: src/applications/fs/tools/gnunet-insert.c:120
2598#, c-format
2599msgid "Failed to add entry to namespace `%s' (does it exist?)\n"
2600msgstr "Lỗi thêm mục nhập vào không gian tên « %s » (có chưa ?)\n"
2601
2602#: src/applications/fs/tools/gnunet-insert.c:135
2603#, c-format
2604msgid "Keywords for file `%s':\n"
2605msgstr "Từ khoá cho tập tin « %s »:\n"
2606
2607#: src/applications/fs/tools/gnunet-insert.c:144
2608msgid "filename"
2609msgstr "tên tập tin"
2610
2611#: src/applications/fs/tools/gnunet-insert.c:146
2612msgid "mimetype"
2613msgstr "kiểu MIME"
2614
2615#: src/applications/fs/tools/gnunet-insert.c:186
2616#, c-format
2617msgid "%16llu of %16llu bytes inserted (estimating %6s to completion) - %s\n"
2618msgstr ""
2619"đã chèn %16llu trên %16llu byte (sẽ hoàn thành trong khoảng %6s giây) - %s\n"
2620
2621#: src/applications/fs/tools/gnunet-insert.c:198
2622#, c-format
2623msgid "Upload of `%s' complete, %llu bytes took %llu seconds (%8.3f KiB/s).\n"
2624msgstr ""
2625"Hoàn thành tải lên « %s », %llu byte trong %llu giây (%8.3f KiB/giây).\n"
2626
2627#: src/applications/fs/tools/gnunet-insert.c:209
2628#, c-format
2629msgid "File `%s' has URI: %s\n"
2630msgstr "Tập tin « %s » có URI: %s\n"
2631
2632#: src/applications/fs/tools/gnunet-insert.c:220
2633#, c-format
2634msgid ""
2635"\n"
2636"Upload aborted.\n"
2637msgstr ""
2638"\n"
2639"Tải lên bị hủy bá».\n"
2640
2641#: src/applications/fs/tools/gnunet-insert.c:225
2642#, c-format
2643msgid ""
2644"\n"
2645"Error uploading file: %s"
2646msgstr ""
2647"\n"
2648"Gặp lỗi khi tải lên tập tin: %s"
2649
2650#: src/applications/fs/tools/gnunet-insert.c:234
2651#, c-format
2652msgid ""
2653"\n"
2654"Unexpected event: %d\n"
2655msgstr ""
2656"\n"
2657"Gặp sá»± kiện bất thÆ°á»ng: %d\n"
2658
2659#: src/applications/fs/tools/gnunet-insert.c:250
2660msgid ""
2661"even if gnunetd is running on the local machine, force the creation of a "
2662"copy instead of making a link to the GNUnet share directory"
2663msgstr ""
2664"thậm chí nếu gnunetd đang chạy trên máy cục bộ, bắt buộc tạo một bản sao "
2665"thay vì tạo một liên kết đến thư mục chia sẻ của GNUnet"
2666
2667#: src/applications/fs/tools/gnunet-insert.c:255
2668msgid "disable adding the creation time to the metadata of the uploaded file"
2669msgstr "tắt thêm giỠtạo vào siêu dữ liệu của tập tin đã tải lên"
2670
2671#: src/applications/fs/tools/gnunet-insert.c:263
2672msgid ""
2673"print list of extracted keywords that would be used, but do not perform "
2674"upload"
2675msgstr ""
2676"in ra danh sách các từ khóa đã giải phóng cần sử dụng, nhưng không thực hiện "
2677"tải lên"
2678
2679#: src/applications/fs/tools/gnunet-insert.c:265
2680msgid "Make files available to GNUnet for sharing."
2681msgstr "Làm cho các tập tin sẵn sàng qua GNUnet để chia sẻ."
2682
2683#: src/applications/fs/tools/gnunet-insert.c:269
2684msgid ""
2685"add an additional keyword for the top-level file or directory (this option "
2686"can be specified multiple times)"
2687msgstr ""
2688"thêm một từ khoá bổ sung cho tập tin hoặc thư mục ở cấp đầu (có thể chỉ ra "
2689"tùy chá»n này nhiá»u lần)"
2690
2691#: src/applications/fs/tools/gnunet-insert.c:278
2692msgid "set the meta-data for the given TYPE to the given VALUE"
2693msgstr "đặt siêu dữ liệu cho KIỂU Ä‘Æ°a ra thành GIÃ_TRỊ chỉ ra"
2694
2695#: src/applications/fs/tools/gnunet-insert.c:281
2696msgid ""
2697"do not index, perform full insertion (stores entire file in encrypted form "
2698"in GNUnet database)"
2699msgstr ""
2700"không đánh chỉ mục, thực hiện việc chèn đầy đủ (chứa toàn bộ tập tin ở dạng "
2701"mã hóa trong cơ sở dữ liệu GNUnet)"
2702
2703#: src/applications/fs/tools/gnunet-insert.c:286
2704msgid ""
2705"specify ID of an updated version to be published in the future (for "
2706"namespace insertions only)"
2707msgstr ""
2708"chỉ ra mã số của một phiên bản đã cập nhật để công bố trong tương lai (chỉ "
2709"cho sự chèn không gian tên)"
2710
2711#: src/applications/fs/tools/gnunet-insert.c:294
2712msgid "publish the files under the pseudonym NAME (place file into namespace)"
2713msgstr ""
2714"công bố các tập tin dưới biệt hiệu TÊN (đặt tập tin vào không gian tên)"
2715
2716#: src/applications/fs/tools/gnunet-insert.c:297
2717msgid ""
2718"only simulte the process but do not do any actual publishing (useful to "
2719"compute URIs)"
2720msgstr ""
2721"chỉ mô phá»ng tiến trình, không thật công bố (có ích để tính địa chỉ URI)"
2722
2723#: src/applications/fs/tools/gnunet-insert.c:301
2724msgid ""
2725"set the ID of this version of the publication (for namespace insertions only)"
2726msgstr ""
2727"đặt mã số của phiên bản này của sự công bố (chỉ cho chèn không gian tên)"
2728
2729#: src/applications/fs/tools/gnunet-insert.c:305
2730msgid ""
2731"URI to be published (can be used instead of passing a file to add keywords "
2732"to the file with the respective URI)"
2733msgstr ""
2734"Äịa chỉ URI cần công bố (có thể được dùng thay vào gá»­i má»™t tập tin để thêm "
2735"từ khoá vào tập tin có địa chỉ URI tương ứng)"
2736
2737#: src/applications/fs/tools/gnunet-insert.c:342
2738#, c-format
2739msgid "You must specify one and only one filename for insertion.\n"
2740msgstr "Phải ghi rõ chỉ một tên tập tin để chèn.\n"
2741
2742#: src/applications/fs/tools/gnunet-insert.c:348
2743#, c-format
2744msgid "You must NOT specify an URI and a filename.\n"
2745msgstr "KHÔNG cho phép ghi rõ cả hai địa chỉ URI và tên tập tin.\n"
2746
2747#: src/applications/fs/tools/gnunet-insert.c:354
2748#, c-format
2749msgid "Cannot extract metadata from a URI!\n"
2750msgstr "Không thể trích siêu dữ liệu ra một địa chỉ URI.\n"
2751
2752#: src/applications/fs/tools/gnunet-insert.c:400
2753#, c-format
2754msgid "Could not access namespace `%s' (does not exist?).\n"
2755msgstr "Không thể truy cập đến không gian tên « %s » (không tồn tại ?).\n"
2756
2757#: src/applications/fs/tools/gnunet-insert.c:408
2758#, c-format
2759msgid "Option `%s' is required when using option `%s'.\n"
2760msgstr "Tùy chá»n « %s » cần thiết khi dùng tùy chá»n « %s ».\n"
2761
2762#: src/applications/fs/tools/gnunet-insert.c:419
2763#: src/applications/fs/tools/gnunet-insert.c:427
2764#, c-format
2765msgid "Option `%s' makes no sense without option `%s'.\n"
2766msgstr "Tùy chá»n « %s » không có nghÄ©a khi không có tùy chá»n « %s ».\n"
2767
2768#: src/applications/fs/tools/gnunet-search.c:128
2769msgid "Search GNUnet for files."
2770msgstr "Tìm tập tin trong GNUnet."
2771
2772#: src/applications/fs/tools/gnunet-search.c:132
2773msgid "write encountered (decrypted) search results to FILENAME"
2774msgstr "ghi kết quả tìm kiếm tìm thấy (đã giải mã) vào tập tin TÊN_TẬP_TIN"
2775
2776#: src/applications/fs/tools/gnunet-search.c:169
2777#, c-format
2778msgid "Error converting arguments to URI!\n"
2779msgstr "Gặp lỗi khi chuyển đổi các đối số sang URI.\n"
2780
2781#: src/applications/fs/tools/gnunet-unindex.c:61
2782#, c-format
2783msgid ""
2784"%16llu of %16llu bytes unindexed (estimating %llu seconds to "
2785"completion) "
2786msgstr ""
2787"Äã bá» chỉ mục %16llu trên %16llu byte (sẽ hoàn thành sau khoảng %llu "
2788"giây) "
2789
2790#: src/applications/fs/tools/gnunet-unindex.c:73
2791#, c-format
2792msgid ""
2793"\n"
2794"Unindexing of `%s' complete, %llu bytes took %llu seconds (%8.3f KiB/s).\n"
2795msgstr ""
2796"\n"
2797"Hoàn thành bỠchỉ mục của « %s », %llu byte sau %llu giây (%8.3f KiB/giây).\n"
2798
2799#: src/applications/fs/tools/gnunet-unindex.c:88
2800#, c-format
2801msgid ""
2802"\n"
2803"Error unindexing file: %s\n"
2804msgstr ""
2805"\n"
2806"Gặp lỗi khi bỠchỉ mục tập tin: %s\n"
2807
2808#: src/applications/fs/tools/gnunet-unindex.c:108
2809msgid "Unindex files."
2810msgstr "BỠchỉ mục tập tin."
2811
2812#: src/applications/fs/tools/gnunet-unindex.c:145
2813msgid "Not enough arguments. You must specify a filename.\n"
2814msgstr "Không đủ đối số. Phải xác định một tên tập tin.\n"
2815
2816#: src/applications/fs/tools/gnunet-unindex.c:163
2817#, c-format
2818msgid "`%s' failed. Is `%s' a file?\n"
2819msgstr "« %s » bị lỗi. « %s » là một tập tin phải không?\n"
2820
2821#: src/applications/fs/tools/gnunet-download.c:82
2822msgid ""
2823"download a GNUnet directory that has already been downloaded. Requires that "
2824"a filename of an existing file is specified instead of the URI. The "
2825"download will only download the top-level files in the directory unless the "
2826"`-R' option is also specified."
2827msgstr ""
2828"tải xuống một thư mục GNUnet đã được tải vỠtrước. Cần thiết ghi rõ tên tập "
2829"tin của một tập tin đã có, thay cho địa chỉ URI. Việc tải vỠsẽ chỉ tải vỠ"
2830"các tập tin cấp đầu của thÆ° mục, nếu không cÅ©ng Ä‘Æ°a ra tùy chá»n « -R »."
2831
2832#: src/applications/fs/tools/gnunet-download.c:85
2833msgid "delete incomplete downloads (when aborted with CTRL-C)"
2834msgstr "xoá việc tải vỠkhông hoàn thành (khi hủy bở dùng CTRL-C)"
2835
2836#: src/applications/fs/tools/gnunet-download.c:87
2837msgid "Download files from GNUnet."
2838msgstr "Tải tập tin xuống GNUnet."
2839
2840#: src/applications/fs/tools/gnunet-download.c:91
2841msgid "write the file to FILENAME"
2842msgstr "ghi tập tin vào TÊN_TẬP_TIN"
2843
2844#: src/applications/fs/tools/gnunet-download.c:95
2845msgid "set the maximum number of parallel downloads that are allowed"
2846msgstr "đặt số tối Ä‘a các việc tải xuống đồng thá»i được phép"
2847
2848#: src/applications/fs/tools/gnunet-download.c:98
2849msgid "download a GNUnet directory recursively"
2850msgstr "tải xuống đệ quy một thư mục GNUnet"
2851
2852#: src/applications/fs/tools/gnunet-download.c:119
2853#, c-format
2854msgid "Download of file `%s' at %16llu out of %16llu bytes (%8.3f KiB/s)\n"
2855msgstr "Tải xuống tập tin « %s » tại %16llu trên %16llu byte (%8.3f KiB/giây)\n"
2856
2857#: src/applications/fs/tools/gnunet-download.c:133
2858#, c-format
2859msgid "Download aborted.\n"
2860msgstr "Tiến trình tải xuống bị hủy bá».\n"
2861
2862#: src/applications/fs/tools/gnunet-download.c:139
2863#, c-format
2864msgid "Error downloading: %s\n"
2865msgstr "Gặp lỗi khi tải xuống: %s\n"
2866
2867#: src/applications/fs/tools/gnunet-download.c:145
2868#, c-format
2869msgid "Download of file `%s' complete. Speed was %8.3f KiB per second.\n"
2870msgstr "Hoàn thành tải xuống tập tin « %s ». Tốc độ là %8.3f KiB một giây.\n"
2871
2872#: src/applications/fs/tools/gnunet-download.c:191
2873msgid "no name given"
2874msgstr "chưa đưa ra tên"
2875
2876#: src/applications/fs/tools/gnunet-download.c:197
2877#, c-format
2878msgid "Starting download `%s'\n"
2879msgstr "Äang bắt đầu tài vỠ« %s »\n"
2880
2881#: src/applications/fs/tools/gnunet-download.c:239
2882msgid "Not enough arguments. You must specify a GNUnet file URI\n"
2883msgstr "Không đủ đối số. Phải ghi rõ một địa chỉ URI tập tin GNUnet\n"
2884
2885#: src/applications/fs/tools/gnunet-download.c:257
2886#, c-format
2887msgid "URI `%s' invalid for gnunet-download.\n"
2888msgstr "Sai URI « %s » cho gnunet-download.\n"
2889
2890#: src/applications/fs/tools/gnunet-download.c:300
2891#, c-format
2892msgid "No filename specified, using `%s' instead (for now).\n"
2893msgstr "Chưa ghi rõ tên tập tin, đang dùng « %s » để thay thế (lúc này).\n"
2894
2895#: src/applications/fs/tools/gnunet-download.c:342
2896#, c-format
2897msgid "Could not access gnunet-directory file `%s'\n"
2898msgstr "Không thể truy cập đến tập tin gnunet-directory « %s »\n"
2899
2900#: src/applications/fs/tools/gnunet-download.c:363
2901#, c-format
2902msgid "Downloading %d files from directory `%s'.\n"
2903msgstr "Äang tải %d tập tin xuống thÆ° mục « %s ».\n"
2904
2905#: src/applications/fs/tools/gnunet-download.c:366
2906#, c-format
2907msgid "Did not find any files in directory `%s'\n"
2908msgstr "Không tìm thấy tập tin nào trong thư mục « %s »\n"
2909
2910#: src/applications/fs/tools/gnunet-download.c:404
2911#, c-format
2912msgid "File stored as `%s'.\n"
2913msgstr "Tập tin được lưu dạng « %s ».\n"
2914
2915#: src/applications/fs/uritrack/file_info.c:98
2916msgid "Collecting file identifiers disabled.\n"
2917msgstr "Chức năng thu thập các đồ nhận diện tập tin đã bị tắt.\n"
2918
2919#: src/applications/fs/uritrack/file_info.c:377
2920#, c-format
2921msgid "Deleted corrupt URI database in `%s'."
2922msgstr "Äã xoá cÆ¡ sở dữ liệu địa chỉ URI bị há»ng trong « %s »."
2923
2924#: src/applications/fs/ecrs/upload.c:158
2925#, c-format
2926msgid "`%s' is not a file.\n"
2927msgstr "« %s » không phải là một tập tin.\n"
2928
2929#: src/applications/fs/ecrs/upload.c:166
2930#, c-format
2931msgid "Cannot get size of file `%s'"
2932msgstr "Không thể lấy kích cỡ của tập tin « %s »"
2933
2934#: src/applications/fs/ecrs/upload.c:175
2935msgid "Failed to connect to gnunetd."
2936msgstr "Không kết nối được đến trình ná»n gnunetd."
2937
2938#: src/applications/fs/ecrs/upload.c:187
2939#, c-format
2940msgid "Cannot hash `%s'.\n"
2941msgstr "Không thể tạo mẫu duy nhất đại diện cho « %s ».\n"
2942
2943#: src/applications/fs/ecrs/upload.c:215
2944#, c-format
2945msgid "Initialization for indexing file `%s' failed.\n"
2946msgstr "Lỗi sơ khởi tập tin đánh chỉ mục « %s ».\n"
2947
2948#: src/applications/fs/ecrs/upload.c:223
2949#, c-format
2950msgid "Indexing file `%s' failed. Suggestion: try to insert the file.\n"
2951msgstr "Lá»—i đánh chỉ mục tập tin « %s ». Äá» nghị: thá»­ chèn tập tin.\n"
2952
2953#: src/applications/fs/ecrs/upload.c:237
2954#, c-format
2955msgid "Cannot open file `%s': `%s'"
2956msgstr "Không thể mở tập tin « %s »: « %s »"
2957
2958#: src/applications/fs/ecrs/upload.c:322
2959#, c-format
2960msgid "Indexing data of file `%s' failed at position %llu.\n"
2961msgstr "Äánh chỉ mục dữ liệu của tập tin « %s » bị lá»—i tại vị tri %llu.\n"
2962
2963#: src/applications/fs/ecrs/helper.c:91
2964msgid "No keywords specified!\n"
2965msgstr "Chưa ghi rõ từ khoá.\n"
2966
2967#: src/applications/fs/ecrs/helper.c:99
2968msgid "Number of double-quotes not balanced!\n"
2969msgstr "Có dấu nháy kép thừa hay thiếu.\n"
2970
2971#: src/applications/fs/ecrs/helper.c:398
2972#, c-format
2973msgid "Renaming of file `%s' to `%s' failed: %s\n"
2974msgstr "Lỗi thay đổi tên của tập tin « %s » thành « %s »: %s\n"
2975
2976#: src/applications/fs/ecrs/helper.c:408
2977#, c-format
2978msgid "Could not rename file `%s' to `%s': file exists\n"
2979msgstr "Không thể thay đổi tên tập tin « %s » thành « %s »: tập tin đã có\n"
2980
2981#: src/applications/fs/ecrs/parser.c:165
2982#, c-format
2983msgid ""
2984"Unknown metadata type in metadata option `%s'. Using metadata type "
2985"`unknown' instead.\n"
2986msgstr ""
2987"Không rõ kiểu siêu dữ liệu trong tùy chá»n siêu dữ liệu « %s ». Äang ùng kiểu "
2988"siêu dữ liệu « không rõ » (unknown) để thay thế.\n"
2989
2990#: src/applications/fs/ecrs/search.c:152
2991msgid "CHK URI not allowed for search.\n"
2992msgstr "Không cho phép địa chỉ URI CHK khi tìm kiếm.\n"
2993
2994#: src/applications/fs/ecrs/search.c:207
2995msgid "LOC URI not allowed for search.\n"
2996msgstr "Không cho phép địa chỉ URI LOC khi tìm kiếm.\n"
2997
2998#: src/applications/fs/ecrs/namespace.c:365
2999#, c-format
3000msgid "File `%s' does not contain a pseudonym.\n"
3001msgstr "Tập tin « %s » không chứa biệt hiệu.\n"
3002
3003#: src/applications/fs/ecrs/namespace.c:376
3004#, c-format
3005msgid "Format of pseudonym `%s' is invalid.\n"
3006msgstr "Äịnh dạng của biệt hiệu « %s » là không hợp lệ.\n"
3007
3008#: src/applications/fs/ecrs/namespace.c:535
3009#: src/applications/fs/ecrs/namespace.c:547
3010#: src/applications/fs/ecrs/namespace.c:559
3011#, c-format
3012msgid "Format of file `%s' is invalid, trying to remove.\n"
3013msgstr "Äịnh dạng của tập tin « %s » là không hợp lệ nên thá»­ gỡ bá».\n"
3014
3015#: src/applications/fs/ecrs/download.c:599
3016msgid ""
3017"Decrypted content does not match key. This is either a bug or a maliciously "
3018"inserted file. Download aborted.\n"
3019msgstr ""
3020"Ná»™i dung đã giải mã không tÆ°Æ¡ng ứng chìa khóa. Äây là má»™t lá»—i hoặc má»™t tập "
3021"tin chèn vào vá»›i ý xấu. Tiến trình tải xuống bị hủy bá».\n"
3022
3023#: src/applications/fs/ecrs/download.c:609
3024msgid "IO error."
3025msgstr "Lá»—i VR."
3026
3027#: src/applications/fs/collection/collection.c:559
3028#: src/applications/fs/collection/collection.c:562
3029#, c-format
3030msgid "Revision %u"
3031msgstr "Bản sửa đổi %u"
3032
3033#: src/applications/fs/fsui/upload.c:330
3034msgid "Application aborted."
3035msgstr "Ứng dụng bị hủy bá»."
3036
3037#: src/applications/fs/fsui/upload.c:344
3038msgid "Failed to create temporary directory."
3039msgstr "Lá»—i tạo thÆ° mục tạm thá»i."
3040
3041#: src/applications/fs/fsui/deserialize.c:927
3042#, c-format
3043msgid "FSUI state file `%s' had syntax error at offset %u.\n"
3044msgstr "Tập tin tình trạng FSUI « %s » có lỗi cú pháp tại khoảng bù %u.\n"
3045
3046#: src/applications/fs/fsui/unindex.c:114
3047msgid "Unindexing failed (no reason given)"
3048msgstr "Lỗi bỠchỉ mục (không đưa ra lý do)."
3049
3050#: src/applications/fs/gap/plan.c:944
3051msgid "# gap requests total sent"
3052msgstr "# tổng số yêu cầu lỗ hổng được gửi"
3053
3054#: src/applications/fs/gap/plan.c:946
3055msgid "# gap content total planned"
3056msgstr "# tổng số nội dung lỗ hổng dự định"
3057
3058#: src/applications/fs/gap/plan.c:948
3059msgid "# gap routes succeeded"
3060msgstr "# tổng số định tuyến lỗ hổng thành công"
3061
3062#: src/applications/fs/gap/plan.c:949
3063msgid "# trust spent"
3064msgstr "# độ tin cậy được tiêu phí"
3065
3066#: src/applications/fs/gap/fs.c:157
3067msgid "Datastore full.\n"
3068msgstr "Kho dữ liệu đầy.\n"
3069
3070#: src/applications/fs/gap/fs.c:831
3071msgid "# gap requests total received"
3072msgstr "# tổng số yêu cầu lỗ hổng được nhận"
3073
3074#: src/applications/fs/gap/fs.c:833
3075msgid "# gap requests dropped due to load"
3076msgstr "# các yêu cầu lá»— hổng bị bá» do trá»ng tải"
3077
3078#: src/applications/fs/gap/fs.c:835
3079msgid "# gap content total received"
3080msgstr "# tổng số nội dung lỗ hổng được nhận"
3081
3082#: src/applications/fs/gap/fs.c:837
3083msgid "# gap total trust awarded"
3084msgstr "# tổng số tin cậy lỗ hổng được cấp"
3085
3086#: src/applications/fs/gap/fs.c:865
3087#, c-format
3088msgid ""
3089"`%s' registering client handlers %d %d %d %d %d %d %d %d and P2P handlers %d "
3090"%d\n"
3091msgstr ""
3092"« %s » Ä‘ang đăng ký các trình Ä‘iá»u khiển kiểu ứng dụng khách %d %d %d %d %d %"
3093"d %d %d và kiểu P2P %d %d\n"
3094
3095#: src/applications/fs/gap/fs.c:921
3096msgid "enables (anonymous) file-sharing"
3097msgstr "hiệu lực chia sẻ tập tin (nặc danh)"
3098
3099#: src/applications/fs/gap/ondemand.c:173
3100#, c-format
3101msgid ""
3102"Because the file `%s' has been unavailable for 3 days it got removed from "
3103"your share. Please unindex files before deleting them as the index now "
3104"contains invalid references!\n"
3105msgstr ""
3106"Vì không có tập tin « %s » trong 3 ngày nên đã xóa nó khá»i chia sẻ của bạn. "
3107"Xin hãy bá» chỉ mục các tập tin trÆ°á»›c khi xoá chúng vì chỉ mục hiện thá»i chứa "
3108"các tham chiếu sai.\n"
3109
3110#: src/applications/fs/gap/ondemand.c:451
3111msgid "Indexed content changed (does not match its hash).\n"
3112msgstr "Nội dung đánh chỉ mục bị thay đổi (không tương ứng với tổng kiểm).\n"
3113
3114#: src/applications/fs/gap/ondemand.c:569
3115#, c-format
3116msgid ""
3117"Unindexed ODB block `%s' from offset %llu already missing from datastore.\n"
3118msgstr ""
3119"Khối ODB đã bỠchỉ mục « %s » từ khoảng bù %llu đã không có trong kho dữ "
3120"liệu.\n"
3121
3122#: src/applications/fs/gap/pid_table.c:177
3123msgid "# distinct interned peer IDs in pid table"
3124msgstr "# các mã số đồng đẳng bị giam giữ riêng biệt trong bảng PID"
3125
3126#: src/applications/fs/gap/pid_table.c:180
3127msgid "# total RC of interned peer IDs in pid table"
3128msgstr "# tổng số RC của mã số đồng đẳng bị giam giữ trong bảng PID"
3129
3130#: src/applications/fs/gap/querymanager.c:708
3131msgid "# gap client queries received"
3132msgstr "# các yêu cầu khách lỗ hổng được nhận"
3133
3134#: src/applications/fs/gap/querymanager.c:710
3135msgid "# gap replies sent to clients"
3136msgstr "# các đáp ứng lỗ hổng được gửi cho trình/máy khách"
3137
3138#: src/applications/fs/gap/querymanager.c:712
3139msgid "# gap client requests tracked"
3140msgstr "# các yêu cầu máy/trình khách lỗ hổng được theo dõi"
3141
3142#: src/applications/fs/gap/querymanager.c:714
3143msgid "# gap client requests injected"
3144msgstr "# các yêu cầu máy/trình khách lỗ hổng được phun vào"
3145
3146#: src/applications/fs/gap/querymanager.c:717
3147msgid "# gap query bloomfilter resizing updates"
3148msgstr ""
3149"# các bản cập nhật thay đổi kích cỡ bá»™ lá»c bloomfilter truy vấn lá»— hổng"
3150
3151#: src/applications/fs/gap/migration.c:437
3152msgid "# blocks migrated"
3153msgstr "# các khối được nâng cấp"
3154
3155#: src/applications/fs/gap/migration.c:439
3156msgid "# blocks injected for migration"
3157msgstr "# các khối được phun vào để nâng cấp"
3158
3159#: src/applications/fs/gap/migration.c:441
3160msgid "# blocks fetched for migration"
3161msgstr "# các khối được lấy để nâng cấp"
3162
3163#: src/applications/fs/gap/migration.c:443
3164msgid "# on-demand fetches for migration"
3165msgstr "# các lần lấy theo yêu cầu để nâng cấp"
3166
3167#: src/applications/fs/gap/gap.c:694
3168msgid "# gap queries dropped (table full)"
3169msgstr "# các truy vấn lỗ hổng bị bỠ(bảng đầy)"
3170
3171#: src/applications/fs/gap/gap.c:696
3172msgid "# gap queries dropped (redundant)"
3173msgstr "# các truy vấn lỗ hổng bị bỠ(thừa)"
3174
3175#: src/applications/fs/gap/gap.c:698
3176msgid "# gap queries routed"
3177msgstr "# các truy vấn lỗ hổng được định tuyến"
3178
3179#: src/applications/fs/gap/gap.c:700
3180msgid "# gap content found locally"
3181msgstr "# nội dung lỗ hổng được tìm cục bộ"
3182
3183#: src/applications/fs/gap/gap.c:703
3184msgid "# gap queries refreshed existing record"
3185msgstr "# các truy vấn lỗ hổng đã cập nhật mục ghi đã có"
3186
3187#: src/applications/fs/gap/gap.c:704
3188msgid "# trust earned"
3189msgstr "# độ tin cậy giành được"
3190
3191#: src/applications/fs/gap/fs_dht.c:256
3192msgid "# blocks pushed into DHT"
3193msgstr "# các khối được đẩy vào DHT"
3194
3195#: src/applications/fs/gap/anonymity.c:56
3196msgid "Failed to get traffic stats.\n"
3197msgstr "Lá»—i lấy thông kê vá» truyá»n tải.\n"
3198
3199#: src/applications/testing/remote.c:68
3200#, c-format
3201msgid "scp command is : %s \n"
3202msgstr "Câu lệnh scp là: %s\n"
3203
3204#: src/applications/testing/remote.c:491
3205#, c-format
3206msgid "Friend list of %s:%d\n"
3207msgstr "Danh sách bạn bè của %s:%d\n"
3208
3209#: src/applications/testing/remote.c:513
3210#, c-format
3211msgid "scp command for friend file copy is : %s \n"
3212msgstr "Câu lệnh scp cho bản sao tập tin bạn bè là: %s\n"
3213
3214#: src/applications/testing/remote.c:535
3215#, c-format
3216msgid "connecting peer %s:%d to peer %s:%d\n"
3217msgstr "đang kết nối đồng đẳng %s:%d tới đồng đẳng %s:%d\n"
3218
3219#: src/applications/testing/remotetest.c:38
3220msgid "Set up multiple gnunetd daemons across multiple hosts."
3221msgstr "Thiết lập nhiá»u trình ná»n gnunetd qua nhiá»u máy khác nhau."
3222
3223#: src/applications/testing/remotetest.c:43
3224msgid "set number of daemons to start"
3225msgstr "đặt số trình ná»n cần khởi chạy"
3226
3227#: src/applications/testing/testing.c:268
3228#: src/applications/testing/remotetopologies.c:367
3229#, c-format
3230msgid "Waiting for peers to connect"
3231msgstr "Äang đợi các đồng đẳng kết nối"
3232
3233#: src/applications/testing/remotetopologies.c:213
3234#, c-format
3235msgid "Connecting nodes in 2d torus topology: %u rows %u columns\n"
3236msgstr ""
3237"Äang kết nối các Ä‘iểm nút theo địa hình há»c hình xuyến hai chiá»u: %u hàng, %"
3238"u cá»™t\n"
3239
3240#: src/applications/testing/remotetopologies.c:491
3241#, c-format
3242msgid "Failed to establish connection with peers.\n"
3243msgstr "Lỗi thiết lập kết nối với đồng đẳng.\n"
3244
3245#: src/applications/bootstrap_http/http.c:113
3246#, c-format
3247msgid "Bootstrap data obtained from `%s' is invalid.\n"
3248msgstr "Sai dữ liệu nạp và khởi động được lấy từ « %s ».\n"
3249
3250#: src/applications/bootstrap_http/http.c:126
3251#: src/applications/bootstrap_http/http.c:277
3252#: src/applications/bootstrap_http/http.c:294
3253#: src/applications/bootstrap_http/http.c:333
3254#: src/applications/bootstrap_http/http.c:352
3255#: src/applications/bootstrap_http/http.c:365
3256#: src/applications/bootstrap_http/http.c:375
3257#: src/applications/bootstrap_http/http.c:385 src/transports/upnp/upnp.c:356
3258#: src/transports/upnp/upnp.c:541 src/transports/http.c:1085
3259#: src/transports/http.c:1209 src/transports/http.c:1377
3260#: src/transports/http.c:1777 src/transports/http.c:1827
3261#, c-format
3262msgid "%s failed at %s:%d: `%s'\n"
3263msgstr "%s bị lỗi tại %s:%d: « %s »\n"
3264
3265#: src/applications/bootstrap_http/http.c:185
3266msgid "No hostlist URL specified in configuration, will not bootstrap.\n"
3267msgstr ""
3268"Chưa ghi rõ địa chỉ URL của danh sách các máy nên không nạp và khởi động.\n"
3269
3270#: src/applications/bootstrap_http/http.c:226
3271#, c-format
3272msgid "Bootstrapping using `%s'.\n"
3273msgstr "Äang nạp và khởi Ä‘á»™ng dùng « %s ».\n"
3274
3275#: src/applications/bootstrap_http/http.c:254
3276#, c-format
3277msgid "Trying to download hostlist from `%s'\n"
3278msgstr "Äang thá»­ tải danh sách các máy xuống « %s »\n"
3279
3280#: src/applications/bootstrap_http/http.c:391
3281#, c-format
3282msgid "Downloaded %llu bytes from `%s'.\n"
3283msgstr "Äã tải %llu byte xuống « %s ».\n"
3284
3285#: src/applications/bootstrap_http/http.c:425
3286msgid "# HELLOs downloaded via http"
3287msgstr "# các HELLO tải xuống qua HTTP"
3288
3289#: src/applications/getoption/getoption.c:78
3290#, c-format
3291msgid "`%s' registering client handler %d\n"
3292msgstr "« %s » Ä‘ang đăng ký trình Ä‘iá»u khiển máy khách %d\n"
3293
3294#: src/applications/getoption/getoption.c:88
3295msgid "allows clients to determine gnunetd's configuration"
3296msgstr "cho phép máy khách quyết định cấu hình của trình ná»n gnunetd."
3297
3298#: src/applications/template/template.c:70
3299#, c-format
3300msgid "`%s' registering client handler %d and %d\n"
3301msgstr "« %s » Ä‘ang đăng ký trình Ä‘iá»u khiển máy khách %d và %d\n"
3302
3303#: src/applications/template/gnunet-template.c:42
3304msgid "Template description."
3305msgstr "Mô tả mẫu."
3306
3307#: src/applications/stats/clientapi.c:331
3308msgid "Uptime (seconds)"
3309msgstr "Thá»i gian chạy (giây)"
3310
3311#: src/applications/stats/sqstats.c:151
3312msgid "# Any-Blocks"
3313msgstr "# Khối bất kỳ"
3314
3315#: src/applications/stats/sqstats.c:152
3316msgid "# DBlocks"
3317msgstr "# Khối D"
3318
3319#: src/applications/stats/sqstats.c:153
3320msgid "# SBlocks"
3321msgstr "# Khối S"
3322
3323#: src/applications/stats/sqstats.c:154
3324msgid "# KBlocks"
3325msgstr "# Khối K"
3326
3327#: src/applications/stats/sqstats.c:155
3328msgid "# NBlocks"
3329msgstr "# Khối N"
3330
3331#: src/applications/stats/sqstats.c:156
3332msgid "# KNBlocks"
3333msgstr "# Khối KN"
3334
3335#: src/applications/stats/sqstats.c:157
3336msgid "# OnDemand-Blocks"
3337msgstr "# Khối theo yêu cầu"
3338
3339#: src/applications/stats/sqstats.c:158
3340msgid "# Unknown-Blocks"
3341msgstr "# Khối không rõ"
3342
3343#: src/applications/stats/sqstats.c:159
3344msgid "# expired"
3345msgstr "# đã hết hạn"
3346
3347#: src/applications/stats/sqstats.c:160
3348msgid "# expire in 1h"
3349msgstr "# hết hạn trong 1 giá»"
3350
3351#: src/applications/stats/sqstats.c:161
3352msgid "# expire in 24h"
3353msgstr "# hết hạn trong 24 giá»"
3354
3355#: src/applications/stats/sqstats.c:162
3356msgid "# expire in 1 week"
3357msgstr "# hết hạn trong 1 tuần"
3358
3359#: src/applications/stats/sqstats.c:163
3360msgid "# expire in 1 month"
3361msgstr "# hết hạn trong 1 tháng"
3362
3363#: src/applications/stats/sqstats.c:164
3364msgid "# zero priority"
3365msgstr "# ưu tiên 0"
3366
3367#: src/applications/stats/sqstats.c:165
3368msgid "# priority one"
3369msgstr "# ưu tiên 1"
3370
3371#: src/applications/stats/sqstats.c:166
3372msgid "# priority larger than one"
3373msgstr "# ưu tiên >1"
3374
3375#: src/applications/stats/sqstats.c:167
3376msgid "# no anonymity"
3377msgstr "# nặc danh 0"
3378
3379#: src/applications/stats/sqstats.c:168
3380msgid "# anonymity one"
3381msgstr "# nặc danh 1"
3382
3383#: src/applications/stats/sqstats.c:169
3384msgid "# anonymity larger than one"
3385msgstr "# nặc danh >1"
3386
3387#: src/applications/stats/statistics.c:238
3388#, no-c-format
3389msgid "% of allowed network load (up)"
3390msgstr "% trá»ng tải mạng được phép (chạy)"
3391
3392#: src/applications/stats/statistics.c:240
3393#, no-c-format
3394msgid "% of allowed network load (down)"
3395msgstr "% trá»ng tải mạng được phép (không chạy)"
3396
3397#: src/applications/stats/statistics.c:243
3398#, no-c-format
3399msgid "% of allowed cpu load"
3400msgstr "% trá»ng tải CPU được phép"
3401
3402#: src/applications/stats/statistics.c:246
3403#, no-c-format
3404msgid "% of allowed io load"
3405msgstr "% trá»ng tải V/R được phép"
3406
3407#: src/applications/stats/statistics.c:249
3408msgid "# bytes of noise received"
3409msgstr "# các byte nhiễu được nhận"
3410
3411#: src/applications/stats/statistics.c:251
3412msgid "# plibc handles"
3413msgstr "# các bộ xử lý plibc"
3414
3415#: src/applications/stats/statistics.c:441
3416#, c-format
3417msgid "`%s' registering client handlers %d %d %d and p2p handler %d\n"
3418msgstr ""
3419"« %s » Ä‘ang đăng ký các trình Ä‘iá»u khiển máy khách %d %d %d và trình Ä‘iá»u "
3420"khiển đồng đẳng %d\n"
3421
3422#: src/applications/stats/statistics.c:463
3423msgid "keeps statistics about gnunetd's operation"
3424msgstr "tính thống kê vỠthao tác gnunetd"
3425
3426#: src/applications/stats/gnunet-stats.c:61
3427#, c-format
3428msgid "Supported peer-to-peer messages:\n"
3429msgstr "Thông báo đồng đẳng được hỗ trợ :\n"
3430
3431#: src/applications/stats/gnunet-stats.c:64
3432#, c-format
3433msgid "Supported client-server messages:\n"
3434msgstr "Thông báo máy khách-chủ được hỗ trợ :\n"
3435
3436#: src/applications/stats/gnunet-stats.c:83
3437#: src/applications/vpn/gnunet-vpn.c:59
3438msgid "Print statistics about GNUnet operations."
3439msgstr "In ra thống kê vỠcác thao tác GNUnet."
3440
3441#: src/applications/stats/gnunet-stats.c:87
3442msgid "prints supported protocol messages"
3443msgstr "in ra các thông báo giao thức được hỗ trợ"
3444
3445#: src/applications/stats/gnunet-stats.c:136
3446#, c-format
3447msgid "Error reading information from gnunetd.\n"
3448msgstr "Gặp lá»—i khi Ä‘á»c thông tin từ gnunetd.\n"
3449
3450#: src/applications/vpn/gnunet-vpn.c:63
3451msgid "Suppress display of asynchronous log messages"
3452msgstr "Thu hồi hiển thị các thông điệp ghi sự kiện không đồng bộ"
3453
3454#: src/applications/vpn/p2p.c:75
3455msgid "VPN IP src not anonymous. drop..\n"
3456msgstr "VPN Nguồn địa chỉ IP không phải nặc danh, bỠđi.\n"
3457
3458#: src/applications/vpn/p2p.c:83
3459msgid "VPN IP not anonymous, drop.\n"
3460msgstr "VPN Äịa chỉ IP không phải nặc danh, bá» Ä‘i.\n"
3461
3462#: src/applications/vpn/p2p.c:92
3463msgid "VPN Received, not anonymous, drop.\n"
3464msgstr "VPN Nhận được, không phải nặc danh, bỠđi.\n"
3465
3466#: src/applications/vpn/p2p.c:97
3467#, c-format
3468msgid "VPN Received unknown IP version %d...\n"
3469msgstr "VPN Nhận được phiên bản IP không rõ %d...\n"
3470
3471#: src/applications/vpn/p2p.c:110
3472#, c-format
3473msgid "<- GNUnet(%d) : %s\n"
3474msgstr "<- GNUnet(%d) : %s\n"
3475
3476#: src/applications/vpn/p2p.c:139
3477msgid "Could not write the tunnelled IP to the OS... Did to setup a tunnel?\n"
3478msgstr ""
3479"Không thể ghi vào HÄH địa chỉ IP theo Ä‘Æ°á»ng hầm... Äã làm để thiết lập má»™t "
3480"Ä‘Æ°á»ng hầm ?\n"
3481
3482#: src/applications/vpn/p2p.c:183
3483msgid "Receive route request\n"
3484msgstr "Nhận yêu cầu định tuyến\n"
3485
3486#: src/applications/vpn/p2p.c:193
3487#, c-format
3488msgid "Prepare route announcement level %d\n"
3489msgstr "Chuẩn bị thông cáo định tuyến cấp %d\n"
3490
3491#: src/applications/vpn/p2p.c:208
3492#, c-format
3493msgid "Send route announcement %d with route announce\n"
3494msgstr "Gá»­i thông cáo định tuyến %d vá»›i Ä‘Æ°á»ng đã báo\n"
3495
3496#: src/applications/vpn/p2p.c:217
3497#, c-format
3498msgid "Send outside table info %d\n"
3499msgstr "Gửi thông tin bảng bên ngoài %d\n"
3500
3501#: src/applications/vpn/p2p.c:239
3502msgid "Receive route announce.\n"
3503msgstr "Nhận thông cáo định tuyến.\n"
3504
3505#: src/applications/vpn/p2p.c:247
3506msgid "Going to try insert route into local table.\n"
3507msgstr "Sẽ thá»­ chèn Ä‘Æ°á»ng vào bảng cục bá»™.\n"
3508
3509#: src/applications/vpn/p2p.c:256
3510#, c-format
3511msgid "Inserting with hops %d\n"
3512msgstr "Äang chèn vá»›i số bÆ°á»›c nhảy %d\n"
3513
3514#: src/applications/vpn/p2p.c:273
3515#, c-format
3516msgid "Request level %d from peer %d\n"
3517msgstr "Yêu cầu cấp %d từ đồng đẳng %d\n"
3518
3519#: src/applications/vpn/p2p.c:300
3520#, c-format
3521msgid "Receive table limit on peer reached %d\n"
3522msgstr "Giới hạn bảng nhận trên đồng đẳng đã tới %d\n"
3523
3524#: src/applications/vpn/vpn.c:180
3525#, c-format
3526msgid "Not storing route to myself from peer %d\n"
3527msgstr "Không phải lÆ°u lại Ä‘Æ°á»ng đến máy này từ đồng đẳng %d\n"
3528
3529#: src/applications/vpn/vpn.c:194
3530#, c-format
3531msgid "Duplicate route to node from peer %d, choosing minimum hops"
3532msgstr ""
3533"ÄÆ°á»ng trùng đến nút từ đồng đẳng %d, Ä‘ang chá»n Ä‘Æ°á»ng có ít bÆ°á»›c nhảy hÆ¡n"
3534
3535#: src/applications/vpn/vpn.c:230
3536#, c-format
3537msgid "Inserting route from peer %d in route table at location %d\n"
3538msgstr "Äang chèn Ä‘Æ°á»ng từ đồng đẳng %d vào bảng định tuyến tại vị trí %d\n"
3539
3540#: src/applications/vpn/vpn.c:247
3541#, c-format
3542msgid "RFC4193 Frame length %d is too big for GNUnet!\n"
3543msgstr "RFC4193 Chiá»u dài khung %d quá lá»›n cho GNUnet!\n"
3544
3545#: src/applications/vpn/vpn.c:254
3546#, c-format
3547msgid "RFC4193 Frame length %d too small\n"
3548msgstr "RFC4193 Chiá»u dài khung %d quá nhá»\n"
3549
3550#: src/applications/vpn/vpn.c:273
3551#, c-format
3552msgid "RFC4193 Ethertype %x and IP version %x do not match!\n"
3553msgstr "RFC4193 Ethertype %x và phiên bản IP %x không tương ứng.\n"
3554
3555#: src/applications/vpn/vpn.c:289
3556#, c-format
3557msgid "RFC4193 Going to try and make a tunnel in slot %d\n"
3558msgstr "RFC4193 Sẽ thá»­ tạo má»™t Ä‘Æ°á»ng hầm trong khoảng %d\n"
3559
3560#: src/applications/vpn/vpn.c:295
3561#, fuzzy, c-format
3562msgid "Cannot open tunnel device: %s"
3563msgstr "Không thể mở thiết bị Ä‘Æ°á»ng hầm do %s"
3564
3565#: src/applications/vpn/vpn.c:331
3566#, c-format
3567msgid "RFC4193 Create skips gnu%d as we are already using it\n"
3568msgstr "RFC4193 Chức năng tạo sẽ nỠqua gnu%d vì chúng ta đang dùng nó\n"
3569
3570#: src/applications/vpn/vpn.c:346
3571#, c-format
3572msgid "Cannot set tunnel name to %s because of %s\n"
3573msgstr "không thể đặt tên Ä‘Æ°á»ng hầm thành %s do %s\n"
3574
3575#: src/applications/vpn/vpn.c:356
3576#, c-format
3577msgid "Configured tunnel name to %s\n"
3578msgstr "Tên Ä‘Æ°á»ng hầm đã được cấu hình thành %s\n"
3579
3580#: src/applications/vpn/vpn.c:398
3581#, c-format
3582msgid "Cannot get socket flags for gnu%d because %s\n"
3583msgstr "Không thể lấy các cỠổ cắm cho gnu%d do %s\n"
3584
3585#: src/applications/vpn/vpn.c:408
3586#, c-format
3587msgid "Cannot set socket flags for gnu%d because %s\n"
3588msgstr "Không thể đặt các cỠổ cắm cho gnu%d do %s\n"
3589
3590#: src/applications/vpn/vpn.c:418
3591#, c-format
3592msgid "Cannot set MTU for gnu%d because %s\n"
3593msgstr "Không thể đặt MTU cho gnu%d do %s\n"
3594
3595#: src/applications/vpn/vpn.c:426
3596#, c-format
3597msgid "Cannot get interface index for gnu%d because %s\n"
3598msgstr "Không thể lấy chủ mục giao diện cho gnu%d do %s\n"
3599
3600#: src/applications/vpn/vpn.c:440
3601#, c-format
3602msgid "IPv6 ifaddr gnu%d - %x:%x:%x:%x:%x:%x:%x:%x/%d\n"
3603msgstr "IPv6 ifaddr gnu%d - %x:%x:%x:%x:%x:%x:%x:%x/%d\n"
3604
3605#: src/applications/vpn/vpn.c:455
3606#, c-format
3607msgid "Cannot set interface IPv6 address for gnu%d because %s\n"
3608msgstr "Không thể đặt địa chỉ IPv6 của giao diện cho gnu%d do %s\n"
3609
3610#: src/applications/vpn/vpn.c:471
3611#, c-format
3612msgid "IPv6 route gnu%d - destination %x:%x:%x:%x:%x:%x:%x:%x/%d\n"
3613msgstr "ÄÆ°á»ng IPv6 gnu%d - đích đến %x:%x:%x:%x:%x:%x:%x:%x/%d\n"
3614
3615#: src/applications/vpn/vpn.c:485
3616#, c-format
3617msgid "Cannot add route IPv6 address for gnu%s because %s\n"
3618msgstr "Không thể thêm địa chỉ IPv6 của Ä‘Æ°á»ng cho gnu%s do %s\n"
3619
3620#: src/applications/vpn/vpn.c:528
3621msgid ""
3622"RFC4193 We have run out of memory and so I can't store a tunnel for this "
3623"peer.\n"
3624msgstr ""
3625"RFC4193 Tràn bá»™ nhá»› thì không thể cất giữ má»™t Ä‘Æ°á»ng hầm cho đồng đẳng này.\n"
3626
3627#: src/applications/vpn/vpn.c:579
3628#, c-format
3629msgid "RFC4193 Thread running (frame %d tunnel %d f2f %d) ...\n"
3630msgstr "RFC4193 Mạch Ä‘ang chạy (khung %d Ä‘Æ°á»ng hầm %d f2f %d) ...\n"
3631
3632#: src/applications/vpn/vpn.c:661
3633#, c-format
3634msgid "VPN dropping connection %x\n"
3635msgstr "VPN đang bỠđi kết nối %x\n"
3636
3637#: src/applications/vpn/vpn.c:670
3638#, c-format
3639msgid "VPN cannot drop connection %x\n"
3640msgstr "VPN không thể bỠđi kết nối %x\n"
3641
3642#: src/applications/vpn/vpn.c:690
3643msgid "RFC4193 Thread exiting\n"
3644msgstr "RFC4193 Mạch đang thoát\n"
3645
3646#: src/applications/vpn/vpn.c:712
3647msgid "realise alloc ram\n"
3648msgstr "realise cấp phát bộ nhớ RAM\n"
3649
3650#: src/applications/vpn/vpn.c:735
3651msgid "realise add routes\n"
3652msgstr "realise thêm Ä‘Æ°á»ng\n"
3653
3654#: src/applications/vpn/vpn.c:849
3655msgid "realise copy table\n"
3656msgstr "realise chép bảng\n"
3657
3658#: src/applications/vpn/vpn.c:898
3659#, c-format
3660msgid "`%s' initialising RFC4913 module %d and %d\n"
3661msgstr "« %s » đang sơ khởi mô-đun RFC4913 %d và %d\n"
3662
3663#: src/applications/vpn/vpn.c:903
3664#, c-format
3665msgid "RFC4193 my First 4 hex digits of host id are %x\n"
3666msgstr "RFC4193 my 4 chữ số thập lúc đầu tiên của mã số máy là %x\n"
3667
3668#: src/applications/vpn/vpn.c:942
3669msgid "enables IPv6 over GNUnet (incomplete)"
3670msgstr "hiệu lực IPv6 qua GNUnet (chưa hoàn tất)"
3671
3672#: src/applications/vpn/vpn.c:963
3673msgid "RFC4193 Waiting for tun thread to end\n"
3674msgstr "RFC4193 Äang đợi kết thúc mạch tun\n"
3675
3676#: src/applications/vpn/vpn.c:978
3677msgid "RFC4193 The tun thread has ended\n"
3678msgstr "RFC4193 Mạch tun đã kết thúc\n"
3679
3680#: src/applications/vpn/vpn.c:996
3681#, c-format
3682msgid "RFC4193 Closing tunnel %d fd %d\n"
3683msgstr "RFC4193 Äang đóng Ä‘Æ°á»ng hầm %d fd %d\n"
3684
3685#: src/server/core.c:119 src/server/core.c:318
3686#, c-format
3687msgid "Configuration value `%s' under [MODULES] for `%s' is invalid!\n"
3688msgstr "Sai giá trị cấu hình « %s » dÆ°á»›i [MÔ-ÄUN] cho « %s ».\n"
3689
3690#: src/server/core.c:140
3691#, c-format
3692msgid "Application module `%s' already initialized!\n"
3693msgstr "Mô-đun ứng dụng « %s » đã được sở khởi.\n"
3694
3695#: src/server/core.c:194
3696#, c-format
3697msgid "Failed to load plugin `%s' at %s:%d. Unloading plugin.\n"
3698msgstr "Lá»—i nạp phần bổ sung « %s » tại %s:%d. Äang hủy nạp phần bổ sung.\n"
3699
3700#: src/server/core.c:244
3701#, c-format
3702msgid "Could not shutdown `%s': application not loaded\n"
3703msgstr "Không thể tắt « %s »: chưa nạp ứng dụng\n"
3704
3705#: src/server/core.c:255
3706#, c-format
3707msgid "Could not shutdown application `%s': not initialized\n"
3708msgstr "Không thể tắt ứng dụng « %s »: chưa được sơ khởi\n"
3709
3710#: src/server/core.c:265
3711#, c-format
3712msgid "Could not find '%s%s' method in library `%s'.\n"
3713msgstr "Không tìm thấy phương pháp « %s%s » trong thư viện « %s ».\n"
3714
3715#: src/server/core.c:422
3716#, c-format
3717msgid "Could not release %p: service not loaded\n"
3718msgstr "Không thể giải phóng %p: chưa nạp dịch vụ\n"
3719
3720#: src/server/core.c:531
3721#, c-format
3722msgid "Could not properly shutdown application `%s'.\n"
3723msgstr "Không thể tắt đúng ứng dụng « %s ».\n"
3724
3725#: src/server/core.c:676
3726#, c-format
3727msgid "Could not properly unload service `%s'!\n"
3728msgstr "Không thể hủy nạp đúng dịch vụ « %s ».\n"
3729
3730#: src/server/gnunet-update.c:146
3731#, c-format
3732msgid "Updating data for module `%s'\n"
3733msgstr "Äang cập nhật dữ liệu cho mô-Ä‘un « %s »\n"
3734
3735#: src/server/gnunet-update.c:151
3736#, c-format
3737msgid "Failed to update data for module `%s'\n"
3738msgstr "Lỗi cập nhật dữ liệu cho mô-đun « %s »\n"
3739
3740#: src/server/gnunet-update.c:225 src/server/gnunetd.c:124
3741msgid "Core initialization failed.\n"
3742msgstr "Lỗi sơ khởi lõi.\n"
3743
3744#: src/server/gnunet-update.c:270
3745msgid "Updates GNUnet datastructures after version change."
3746msgstr "Cập nhật cấu trúc dữ liệu GNUnet sau khi thay đổi phiên bản."
3747
3748#: src/server/gnunet-update.c:274 src/server/gnunet-transport-check.c:376
3749msgid "run as user LOGIN"
3750msgstr "chạy dÆ°á»›i ngÆ°á»i dùng ÄÄ‚NG_NHẬP"
3751
3752#: src/server/gnunet-update.c:278
3753msgid "run in client mode (for getting client configuration values)"
3754msgstr "chạy trong chế độ khách (để lấy các giá trị cấu hình của máy khách)"
3755
3756#: src/server/version.c:125
3757msgid ""
3758"Failed to determine filename used to store GNUnet version information!\n"
3759msgstr ""
3760"Lỗi quyết định tên tập tin được dùng để chứa thông tin vỠphiên bản GNUnet.\n"
3761
3762#: src/server/gnunetd.c:85
3763#, c-format
3764msgid "`%s' startup complete.\n"
3765msgstr "Hoàn thành khởi chạy « %s ».\n"
3766
3767#: src/server/gnunetd.c:89
3768#, c-format
3769msgid "`%s' is shutting down.\n"
3770msgstr "« %s » đang tắt.\n"
3771
3772#: src/server/gnunetd.c:179
3773msgid ""
3774"run in debug mode; gnunetd will not daemonize and error messages will be "
3775"written to stderr instead of a logfile"
3776msgstr ""
3777"chạy trong chế Ä‘á»™ tìm sá»­a lá»—i; gnunetd sẽ không trở thành trình ná»n và sẽ "
3778"ghi thông báo lỗi ra đầu lỗi tiêu chuẩn thay vì vào một tập tin ghi sự kiện."
3779
3780#: src/server/gnunetd.c:183
3781msgid "Starts the gnunetd daemon."
3782msgstr "Khởi chạy trình ná»n gnunetd."
3783
3784#: src/server/gnunetd.c:186
3785msgid "disable padding with random data (experimental)"
3786msgstr "tắt đệm lót với dữ liệu ngẫu nhiên (vẫn thực nghiệm !)"
3787
3788#: src/server/gnunetd.c:190
3789msgid "print all log messages to the console (only works together with -d)"
3790msgstr ""
3791"in má»i thông Ä‘iệp ghi sá»± kiện ra bàn giao tiếp (chỉ hoạt Ä‘á»™ng tổ hợp vá»›i « -d "
3792"»)"
3793
3794#: src/server/gnunetd.c:194
3795msgid "specify username as which gnunetd should run"
3796msgstr "chỉ ra tên ngÆ°á»i dùng dÆ°á»›i đó cần chạy gnunetd"
3797
3798#: src/server/gnunetd.c:275
3799#, c-format
3800msgid "Configuration or GNUnet version changed. You need to run `%s'!\n"
3801msgstr ""
3802"Cấu hình hoặc phiên bản GNUnet bị thay đổi. NgÆ°á»i dùng cần chạy « %s ».\n"
3803
3804#: src/server/tcpserver.c:121
3805#, c-format
3806msgid "The `%s' request received from client is malformed.\n"
3807msgstr "Nhận được yêu cầu « %s » dạng sai từ máy khách.\n"
3808
3809#: src/server/tcpserver.c:409
3810#, c-format
3811msgid "`%s' failed for port %d. Is gnunetd already running?\n"
3812msgstr "« %s » bị lỗi cho cổng %d. Trình gnunetd có chạy chưa?\n"
3813
3814#: src/server/tcpserver.c:487 src/server/tcpserver.c:512
3815#, c-format
3816msgid ""
3817"Malformed network specification in the configuration in section `%s' for "
3818"entry `%s': %s\n"
3819msgstr ""
3820"Äặc tả mạng dạng sai trong cấu hình phần « %s » cho mục nhập « %s »: %s\n"
3821
3822#: src/server/tcpserver.c:572
3823#, c-format
3824msgid "Registering failed, message type %d already in use.\n"
3825msgstr "Lỗi đăng ký, thông điệp kiểu %d đang được dùng.\n"
3826
3827#: src/server/startup.c:219
3828#, c-format
3829msgid "Unable to obtain filesystem information for `%s': %u\n"
3830msgstr "Không thể đại được thông tin vỠhệ thống tập tin cho « %s »: %u\n"
3831
3832#: src/server/startup.c:237
3833#, c-format
3834msgid ""
3835"Filesystem `%s' of partition `%s' is unknown. Please contact gnunet-"
3836"developers@gnu.org!"
3837msgstr ""
3838"Hệ thống tập tin « %s » của phân vùng « %s » không rõ. Hãy liên lạc với các "
3839"nhà phát triển gnunet ở địa chỉ « gnunet-developers@gnu.org »."
3840
3841#: src/server/startup.c:252
3842#, c-format
3843msgid ""
3844"Limiting datastore size to %llu GB, because the `%s' filesystem does not "
3845"support larger files. Please consider storing the database on a NTFS "
3846"partition!\n"
3847msgstr ""
3848"Äang hạn chế kích cỡ kho dữ liệu thành %llu GB, vì hệ thống tập tin « %s » "
3849"không hỗ trợ tập tin lớn hơn đó. Khuyên bạn cất giữ cơ sở dữ liệu trong một "
3850"phiên bản kiểu NTFS.\n"
3851
3852#: src/server/startup.c:291
3853#, c-format
3854msgid "Insufficient access permissions for `%s': %s\n"
3855msgstr "Không đủ quyá»n truy cập cho « %s »: %s\n"
3856
3857#: src/server/gnunet-peer-info.c:55
3858msgid "Print information about GNUnet peers."
3859msgstr "In ra thông tin vỠcác đồng đẳng GNUnet."
3860
3861#: src/server/gnunet-peer-info.c:59
3862msgid "don't resolve host names"
3863msgstr "không quyết định các tên máy"
3864
3865#: src/server/gnunet-peer-info.c:62
3866msgid "output only the identity strings"
3867msgstr "chỉ xuất những chuỗi nhận diện"
3868
3869#: src/server/gnunet-peer-info.c:65
3870msgid "output our own identity only"
3871msgstr "chỉ xuất nhận diện mình"
3872
3873#: src/server/gnunet-peer-info.c:130 src/server/gnunet-peer-info.c:164
3874#, c-format
3875msgid "Could not get address of peer `%s'.\n"
3876msgstr "Không thể lấy địa chỉ của đồng đẳng « %s ».\n"
3877
3878#: src/server/gnunet-peer-info.c:143
3879#, c-format
3880msgid "`%s' message invalid (signature invalid).\n"
3881msgstr "Thông báo « %s » không hợp lệ (chữ ký sai).\n"
3882
3883#: src/server/gnunet-peer-info.c:168
3884#, c-format
3885msgid "Peer `%s' with trust %8u\n"
3886msgstr "Äồng đẳng « %s » có mức tin cậy %8u\n"
3887
3888#: src/server/gnunet-peer-info.c:175
3889#, c-format
3890msgid "Peer `%s' with trust %8u and address `%s'\n"
3891msgstr "Äồng đẳng « %s » có mức tin cậy %8u và địa chỉ « %s »\n"
3892
3893#: src/server/connection.c:1313
3894#, c-format
3895msgid "`%s' selected %d out of %d messages (MTU: %d).\n"
3896msgstr "« %s » đã chá»n %d trên %d thông báo (MTU: %d).\n"
3897
3898#: src/server/connection.c:1323
3899#, c-format
3900msgid "Message details: %u: length %d, priority: %d\n"
3901msgstr "Chi tiết vỠthông báo: %u: dài %d, ưu tiên: %d\n"
3902
3903#: src/server/connection.c:3129
3904#, c-format
3905msgid "Message from `%s' discarded: invalid format.\n"
3906msgstr "Thông báo từ « %s » bị hủy: định dạng sai.\n"
3907
3908#: src/server/connection.c:3218
3909#, c-format
3910msgid "Invalid sequence number %u <= %u, dropping message.\n"
3911msgstr "Sai số thứ tự dãy trong thông báo %u ≤ %u, đang loại bỠthông báo.\n"
3912
3913#: src/server/connection.c:3240
3914msgid "Message received more than one day old. Dropped.\n"
3915msgstr "Thông báo nhận được cÅ© hÆ¡n má»™t ngày. Äã loại bá».\n"
3916
3917#: src/server/connection.c:3763
3918msgid "# outgoing messages dropped"
3919msgstr "# các thông báo gá»­i Ä‘i bị loại bá»"
3920
3921#: src/server/connection.c:3766
3922msgid "# bytes of outgoing messages dropped"
3923msgstr "# các byte thông báo gá»­i Ä‘i bị loại bá»"
3924
3925#: src/server/connection.c:3768
3926msgid "# connections closed (HANGUP sent)"
3927msgstr "# các kết nối bị đóng (gửi tín hiệu ngừng nói HANGUP)"
3928
3929#: src/server/connection.c:3772
3930msgid "# connections closed (transport issue)"
3931msgstr "# các kết nối bị đóng (vấn Ä‘á» truyá»n tải)"
3932
3933#: src/server/connection.c:3775
3934msgid "# bytes encrypted"
3935msgstr "# các byte đã mã hoá"
3936
3937#: src/server/connection.c:3779
3938msgid "# bytes transmitted"
3939msgstr "# các byte được gửi"
3940
3941#: src/server/connection.c:3783
3942msgid "# bytes received"
3943msgstr "# các byte được nhận"
3944
3945#: src/server/connection.c:3785
3946msgid "# bytes decrypted"
3947msgstr "# các byte đã giải mã"
3948
3949#: src/server/connection.c:3786
3950msgid "# bytes noise sent"
3951msgstr "# các byte nhiễu được gửi"
3952
3953#: src/server/connection.c:3789
3954msgid "# total bytes per second send limit"
3955msgstr "# giới hạn tổng số byte mỗi giây"
3956
3957#: src/server/connection.c:3792
3958msgid "# total bytes per second receive limit"
3959msgstr "# giới hạn nhận tổng số byte mỗi giây"
3960
3961#: src/server/connection.c:3795
3962msgid "# total number of messages in send buffers"
3963msgstr "# tổng số thông báo trong bộ đệm gửi"
3964
3965#: src/server/connection.c:3798
3966msgid "# total number of bytes we were allowed to send but did not"
3967msgstr "# tổng số byte được phép gửi mà chưa"
3968
3969#: src/server/connection.c:3801
3970msgid "# total number of bytes we were allowed to sent"
3971msgstr "# tổng số byte được phép gửi"
3972
3973#: src/server/connection.c:3804
3974msgid "# total number of bytes we are currently allowed to send"
3975msgstr "# tổng số byte hiện thá»i được phép gá»­i"
3976
3977#: src/server/connection.c:3807
3978msgid "# transports switched to stream transport"
3979msgstr "# các truyá»n tải được chuyển sang truyá»n tải luồng"
3980
3981#: src/server/connection.c:3810
3982msgid "# average connection lifetime (in ms)"
3983msgstr "# thá»i gian trung bình còn kết nối (theo miligiây)"
3984
3985#: src/server/connection.c:3813
3986msgid "# conn. shutdown: other peer sent too much"
3987msgstr "# kết nối bị ngắt: đồng đẳng khác đã gá»­i quá nhiá»u"
3988
3989#: src/server/connection.c:3816
3990msgid "# conn. shutdown: we lacked bandwidth"
3991msgstr "# kết nối bị ngắt: không đủ băng thông."
3992
3993#: src/server/connection.c:3819
3994msgid "# conn. shutdown: other peer timed out"
3995msgstr "# kết nối bị ngắt: đồng đẳng khác quá hạn"
3996
3997#: src/server/connection.c:3822
3998msgid "# conn. shutdown: timed out during connect"
3999msgstr "# kết nối bị ngắt: quá hạn trong khi thiết lập kết nối"
4000
4001#: src/server/connection.c:3825
4002msgid "# conn. shutdown: other peer requested it"
4003msgstr "# kết nối bị ngắt: theo yêu cầu của đồng đẳng khác"
4004
4005#: src/server/handler.c:442
4006#, c-format
4007msgid "Received corrupt message from peer `%s' in %s:%d.\n"
4008msgstr "Nhận được thông báo bị há»ng từ đồng đẳng « %s » trong %s:%d.\n"
4009
4010#: src/server/gnunet-transport-check.c:121
4011#, c-format
4012msgid "`%s': Could not create hello.\n"
4013msgstr "« %s »: Không tạo được tín hiệu xin chào (hello).\n"
4014
4015#: src/server/gnunet-transport-check.c:129
4016#, c-format
4017msgid "`%s': Could not connect.\n"
4018msgstr "« %s »: Không thể kết nối.\n"
4019
4020#: src/server/gnunet-transport-check.c:163
4021#, c-format
4022msgid "`%s': Could not send.\n"
4023msgstr "« %s »: Không thể gửi.\n"
4024
4025#: src/server/gnunet-transport-check.c:179
4026#, c-format
4027msgid "`%s': Did not receive message within %llu ms.\n"
4028msgstr "« %s »: Chưa nhận thông báo sau %llu miligiây.\n"
4029
4030#: src/server/gnunet-transport-check.c:192
4031#, c-format
4032msgid "`%s': Could not disconnect.\n"
4033msgstr "« %s »: Không thể ngắt kết nối.\n"
4034
4035#: src/server/gnunet-transport-check.c:200
4036#, c-format
4037msgid ""
4038"`%s' transport OK. It took %ums to transmit %llu messages of %llu bytes "
4039"each.\n"
4040msgstr ""
4041"« %s » truyá»n tải OK. Cần %u miligiây để truyá»n Ä‘i %llu thông báo vá»›i %llu "
4042"byte mỗi cái.\n"
4043
4044#: src/server/gnunet-transport-check.c:231
4045#, c-format
4046msgid " Transport %d is not being tested\n"
4047msgstr " Truyá»n tải %d không Ä‘ang thá»­\n"
4048
4049#: src/server/gnunet-transport-check.c:261
4050#, c-format
4051msgid ""
4052"\n"
4053"Contacting `%s'."
4054msgstr ""
4055"\n"
4056"Äang liên lạc vá»›i « %s »."
4057
4058#: src/server/gnunet-transport-check.c:286
4059#, c-format
4060msgid " Connection failed\n"
4061msgstr " Lỗi kết nối\n"
4062
4063#: src/server/gnunet-transport-check.c:292
4064#, c-format
4065msgid " Connection failed (bug?)\n"
4066msgstr " Không kết nối được (lỗi ?)\n"
4067
4068#: src/server/gnunet-transport-check.c:330
4069#, c-format
4070msgid "Timeout after %llums.\n"
4071msgstr "Quá hạn sau %llu miligiây.\n"
4072
4073#: src/server/gnunet-transport-check.c:332
4074#, c-format
4075msgid "OK!\n"
4076msgstr "OK!\n"
4077
4078#: src/server/gnunet-transport-check.c:357
4079msgid "Tool to test if GNUnet transport services are operational."
4080msgstr ""
4081"Công cụ để thá»­ nghiệm xem dịch vụ truyá»n tải GNUnet có hoạt Ä‘á»™ng không."
4082
4083#: src/server/gnunet-transport-check.c:361
4084msgid "ping peers from HOSTLISTURL that match transports"
4085msgstr ""
4086"gửi tín hiệu ping cho các đồng đẳng từ HOSTLISTURL (danh sách máy theo URL) "
4087"tÆ°Æ¡ng ứng vá»›i truyá»n tải"
4088
4089#: src/server/gnunet-transport-check.c:364
4090msgid "send COUNT messages"
4091msgstr "gá»­i ÄẾM thông báo"
4092
4093#: src/server/gnunet-transport-check.c:367
4094msgid "send messages with SIZE bytes payload"
4095msgstr "gá»­i thông báo có KÃCH_Cá»  byte tải trá»ng"
4096
4097#: src/server/gnunet-transport-check.c:370
4098msgid "specifies which TRANSPORT should be tested"
4099msgstr "chỉ ra TRUYỀN_TẢI nào cần được thử nghiệm"
4100
4101#: src/server/gnunet-transport-check.c:373
4102msgid "specifies after how many MS to time-out"
4103msgstr "chỉ ra hết thá»i gian chá» sau bao nhiêu miligiay"
4104
4105#: src/server/gnunet-transport-check.c:381
4106msgid "repeat each test X times"
4107msgstr "lặp lại mỗi hàm thử X lần"
4108
4109#: src/server/gnunet-transport-check.c:449
4110#, c-format
4111msgid "Testing transport(s) %s\n"
4112msgstr "Äang thá»­ nghiệm (các) truyá»n tải %s\n"
4113
4114#: src/server/gnunet-transport-check.c:451
4115#, c-format
4116msgid "Available transport(s): %s\n"
4117msgstr "Các truyá»n tải sẵn sàng: %s\n"
4118
4119#: src/server/gnunet-transport-check.c:501
4120#, c-format
4121msgid ""
4122"\n"
4123"%d out of %d peers contacted successfully (%d times transport unavailable).\n"
4124msgstr ""
4125"\n"
4126"Äã liên lạc thành công vá»›i %d trên %d đồng đẳng (truyá»n tải không sẵn sàng %"
4127"d lần).\n"
4128
4129#: src/transports/common.c:370
4130#, c-format
4131msgid "Port is 0, will only send using %s.\n"
4132msgstr "Cổng là 0, chỉ sẽ gửi dùng %s.\n"
4133
4134#: src/transports/smtp.c:367 src/transports/udp.c:107 src/transports/tcp.c:271
4135#: src/transports/tcp.c:291
4136#, c-format
4137msgid "Received malformed message via %s. Ignored.\n"
4138msgstr "Nhận được thông báo dạng sai qua %s. Bị bỠqua.\n"
4139
4140#: src/transports/smtp.c:459
4141msgid "SMTP filter string to invalid, lacks ': '\n"
4142msgstr "Chuá»—i lá»c vào SMTP không hợp lệ, còn thiếu « : »\n"
4143
4144#: src/transports/smtp.c:469
4145#, c-format
4146msgid "SMTP filter string to long, capped to `%s'\n"
4147msgstr "Chuá»—i lá»c vào SMTP quá dài, tối Ä‘a « %s »\n"
4148
4149#: src/transports/smtp.c:564 src/transports/smtp.c:575
4150#: src/transports/smtp.c:589 src/transports/smtp.c:609
4151#: src/transports/smtp.c:634 src/transports/smtp.c:643
4152#: src/transports/smtp.c:657 src/transports/smtp.c:669
4153#, c-format
4154msgid "SMTP: `%s' failed: %s.\n"
4155msgstr "SMTP: « %s » bị lỗi: %s\n"
4156
4157#: src/transports/smtp.c:814
4158msgid "No email-address specified, can not start SMTP transport.\n"
4159msgstr "ChÆ°a ghi rõ địa chỉ thÆ° Ä‘iện tá»­ nên không tạo được truyá»n tải SMTP.\n"
4160
4161#: src/transports/smtp.c:831
4162msgid "# bytes received via SMTP"
4163msgstr "# các byte đã nhận qua SMTP"
4164
4165#: src/transports/smtp.c:832
4166msgid "# bytes sent via SMTP"
4167msgstr "# các byte đã gửi qua SMTP"
4168
4169#: src/transports/smtp.c:834
4170msgid "# bytes dropped by SMTP (outgoing)"
4171msgstr "# các byte loại đi bởi SMTP (đi ra)"
4172
4173#: src/transports/upnp/upnp.c:431
4174#, c-format
4175msgid "%s failed for url `%s' and post-data `%s' at %s:%d: `%s'\n"
4176msgstr ""
4177"%s bị lỗi đối với địa chỉ URL « %s » và dữ liệu cuối « %s » tại %s:%d: « %s »\n"
4178
4179#: src/transports/upnp/upnp.c:476
4180#, c-format
4181msgid "upnp: NAT Returned IP: %s\n"
4182msgstr "upnp: địa chỉ IP được NAT trả vá»: %s\n"
4183
4184#: src/transports/http.c:2019 src/transports/tcp.c:811
4185#, c-format
4186msgid ""
4187"The UPnP service could not be loaded. To disable UPnP, set the configuration "
4188"option \"UPNP\" in section \"%s\" to \"NO\"\n"
4189msgstr ""
4190"Dịch vụ UPnP không thể nạp được. Äể tắt UPnP, đặt tùy chá»n cấu hình « UPNP » "
4191"trong phần « %s » thành « NO » (không).\n"
4192
4193#: src/transports/http.c:2028
4194msgid "# bytes received via HTTP"
4195msgstr "# các byte đã nhận qua HTTP"
4196
4197#: src/transports/http.c:2029
4198msgid "# bytes sent via HTTP"
4199msgstr "# các byte đã gửi qua HTTP"
4200
4201#: src/transports/http.c:2031
4202msgid "# bytes dropped by HTTP (outgoing)"
4203msgstr "# các byte loại bỠbởi HTTP (đi ra)"
4204
4205#: src/transports/http.c:2032
4206msgid "# HTTP GET issued"
4207msgstr "# Tín hiệu HTTP GET được gửi"
4208
4209#: src/transports/http.c:2034
4210msgid "# HTTP GET received"
4211msgstr "# Tín hiệu HTTP GET được nhận"
4212
4213#: src/transports/http.c:2035
4214msgid "# HTTP PUT issued"
4215msgstr "# Tín hiệu HTTP PUT được gửi"
4216
4217#: src/transports/http.c:2037
4218msgid "# HTTP PUT received"
4219msgstr "# Tín hiệu HTTP PUT được nhận"
4220
4221#: src/transports/http.c:2039
4222msgid "# HTTP select calls"
4223msgstr "# các cuá»™c gá»i HTTP select (lá»±a chá»n)"
4224
4225#: src/transports/http.c:2041
4226msgid "# HTTP send calls"
4227msgstr "# các cuá»™c gá»i HTTP send (gá»­i)"
4228
4229#: src/transports/http.c:2044
4230msgid "# HTTP curl send callbacks"
4231msgstr "# các cuá»™c gá»i ngược HTTP curl send (hàm curl gá»­i)"
4232
4233#: src/transports/http.c:2046
4234msgid "# HTTP curl receive callbacks"
4235msgstr "# các cuá»™c gá»i ngược HTTP curl receive (hàm curl nhận)"
4236
4237#: src/transports/http.c:2048
4238msgid "# HTTP mhd access callbacks"
4239msgstr "# các cuá»™c gá»i ngược HTTP mhd access (hàm mhd truy cập)"
4240
4241#: src/transports/http.c:2050
4242msgid "# HTTP mhd read callbacks"
4243msgstr "# các cuá»™c gá»i ngược HTTP mhd read (hàm mhd Ä‘á»c)"
4244
4245#: src/transports/http.c:2052
4246msgid "# HTTP mhd close callbacks"
4247msgstr "# các cuá»™c gá»i ngược HTTP mhd close (hàm mhd đóng)"
4248
4249#: src/transports/http.c:2054
4250msgid "# HTTP connect calls"
4251msgstr "# các cuá»™c gá»i HTTP connect (kết nối)"
4252
4253#: src/transports/ip.c:70 src/transports/ip.c:365
4254#, c-format
4255msgid "Failed to obtain my (external) %s address!\n"
4256msgstr "Lỗi lấy địa chỉ %s (bên ngoài) của mình.\n"
4257
4258#: src/transports/udp.c:472 src/transports/tcp.c:728
4259#, c-format
4260msgid "Failed to bind to %s port %d.\n"
4261msgstr "Lỗi đóng kết đến cổng %s %d.\n"
4262
4263#: src/transports/udp.c:538
4264#, c-format
4265msgid "MTU %llu for `%s' is probably too low!\n"
4266msgstr "MTU %llu cho « %s » rất có thể quá thấp.\n"
4267
4268#: src/transports/udp.c:562
4269msgid "# bytes received via UDP"
4270msgstr "# các byte đã nhận qua UDP"
4271
4272#: src/transports/udp.c:563
4273msgid "# bytes sent via UDP"
4274msgstr "# các byte đã gửi qua UDP"
4275
4276#: src/transports/udp.c:565
4277msgid "# bytes dropped by UDP (outgoing)"
4278msgstr "# các byte loại bỠbởi UDP (đi ra)"
4279
4280#: src/transports/udp.c:567
4281msgid "# UDP connections (right now)"
4282msgstr "# các kết nối UDP (lúc này)"
4283
4284#: src/transports/tcp.c:821
4285msgid "# bytes received via TCP"
4286msgstr "# các byte đã nhận qua TCP"
4287
4288#: src/transports/tcp.c:822
4289msgid "# bytes sent via TCP"
4290msgstr "# các byte đã gừi qua TCP"
4291
4292#: src/transports/tcp.c:824
4293msgid "# bytes dropped by TCP (outgoing)"
4294msgstr "# các byte loại đi bởi TCP (đi ra)"
4295
4296#: src/include/gnunet_util_getopt.h:154
4297msgid "print this help"
4298msgstr "hiển thị trợ giúp này"
4299
4300#: src/include/gnunet_util_getopt.h:163
4301msgid "print the version number"
4302msgstr "hiển thị số thứ tự phiên bản"
4303
4304#: src/include/gnunet_util_getopt.h:169
4305msgid "configure logging to use LOGLEVEL"
4306msgstr "cấu hình chức năng ghi sự kiện để dùng CẤP_GHI_LƯU"
4307
4308#: src/include/gnunet_util_getopt.h:175
4309msgid "be verbose"
4310msgstr "xuất chi tiết"
4311
4312#: src/include/gnunet_util_getopt.h:181
4313msgid "use configuration file FILENAME"
4314msgstr "dùng tập tin cấu hình TÊN_TẬP_TIN"
4315
4316#: src/include/gnunet_util_getopt.h:187
4317msgid "specify host on which gnunetd is running"
4318msgstr "ghi rõ máy trên đó chạy trình ná»n gnunetd"
4319
4320#: src/include/gnunet_util_error.h:219 src/include/gnunet_util_error.h:224
4321#: src/include/gnunet_util_error.h:230 src/include/gnunet_util_error.h:232
4322#, c-format
4323msgid "Internal error: assertion failed at %s:%d.\n"
4324msgstr "Lỗi nội bộ : khẳng định không thành công tại %s:%d.\n"
4325
4326#: src/include/gnunet_util_error.h:242
4327#, c-format
4328msgid ""
4329"External protocol violation: assertion failed at %s:%d (no need to panic, we "
4330"can handle this).\n"
4331msgstr ""
4332"Xâm phạm giao thức bên ngoài: khẳng định không thành công tại %s:%d (đừng "
4333"lo, vẫn còn có thể sửa chữa).\n"
4334
4335#: src/include/gnunet_util_error.h:270 src/include/gnunet_util_error.h:277
4336#, c-format
4337msgid "`%s' failed on file `%s' at %s:%d with error: %s\n"
4338msgstr "« %s » thất bại ở tập tin « %s » tại %s:%d với lỗi: %s\n"
4339
4340#: contrib/config-daemon.scm:39 contrib/config-client.scm:40
4341msgid "No help available."
4342msgstr "Không có trợ giúp sẵn sàng."
4343
4344#: contrib/config-daemon.scm:42
4345msgid ""
4346"You can use 'make check' in src/transports/upnp/ to find out if your NAT "
4347"supports UPnP. You should disable this option if you are sure that you are "
4348"not behind a NAT. If your NAT box does not support UPnP, having this on "
4349"will not do much harm (only cost a small amount of resources)."
4350msgstr ""
4351"Bạn có thể dùng câu lệnh « make check » trong « src/transports/upnp » để tìm "
4352"biết nếu NAT đó hỗ trợ UPnP không. Chưa chắc nếu máy này nằm sau một NAT thì "
4353"bạn nên tắt tùy chá»n này. Nếu máy NAT đó không há»— trợ UPnP, việc bật tùy "
4354"chá»n này sẽ không rất vấn Ä‘á» gì (chỉ chiếm má»™t ít tài nguyên)."
4355
4356#: contrib/config-daemon.scm:54 contrib/config-client.scm:53
4357msgid "Prompt for development and/or incomplete code"
4358msgstr "Nhắc với mã vẫn phát triển và/hay mã chưa hoàn toàn"
4359
4360#: contrib/config-daemon.scm:56 contrib/config-client.scm:55
4361msgid ""
4362"If EXPERIMENTAL is set to NO, options for experimental code are not shown. "
4363"If in doubt, use NO.\n"
4364"\n"
4365"Some options apply to experimental code that maybe in a state of development "
4366"where the functionality, stability, or the level of testing is not yet high "
4367"enough for general use. These features are said to be of \"alpha\" "
4368"quality. If a feature is currently in alpha, uninformed use is discouraged "
4369"(since the developers then do not fancy \"Why doesn't this work?\" type "
4370"messages).\n"
4371"\n"
4372"However, active testing and qualified feedback of these features is always "
4373"welcome. Users should just be aware that alpha features may not meet the "
4374"normal level of reliability or it may fail to work in some special cases. "
4375"Bug reports are usually welcomed by the developers, but please read the "
4376"documents <file://README> and <http://gnunet.org/faq.php3> and use <https://"
4377"gnunet.org/mantis/> for how to report problems."
4378msgstr ""
4379"Nếu EXPERIMENTAL (thực nghiệm) được đặt thành NO (không) thì không hiển thị "
4380"tùy chá»n vá» mã vẫn thá»±c nghiệm. ChÆ°a chắc thì đặt NO.\n"
4381"\n"
4382"Má»™t số tùy chá»n nào đó có áp dụng cho mã thá»±c nghiệm, mà có thể vẫn còn được "
4383"phát triển thì chưa đầy đủ chức năng, ổn định hay đủ thử để sử dụng một cách "
4384"chung. Các tính năng này được nhãn là « alpha » (a). Nếu một tính năng vẫn là "
4385"alpha, khuyên ngÆ°á»i dùng bình thÆ°á»ng không dùng nó.\n"
4386"\n"
4387"Tùy nhiên, nếu bạn quen vá»›i tiến trình thá»­ và phản hồi, má»i bạn tham gia "
4388"(miá»…n là bạn hiểu được rằng phần má»m này có thể chÆ°a sẵn sàng sá»­ dụng vá»›i dữ "
4389"liệu quan trá»ng). Nhà phát triển má»i bạn gá»­i báo cáo lá»—i: xin hãy Ä‘á»c tài "
4390"liệu <file://README> và <http://gnunet.org/faq.php3>, sau đó dùng địa chỉ "
4391"<https://gnunet.org/mantis/> để thông báo vấn Ä‘á»."
4392
4393#: contrib/config-daemon.scm:71 contrib/config-client.scm:70
4394msgid "Show options for advanced users"
4395msgstr "Hiện tùy chá»n cấp cao"
4396
4397#: contrib/config-daemon.scm:73 contrib/config-client.scm:72
4398msgid ""
4399"These are options that maybe difficult to understand for the beginner. These "
4400"options typically refer to features that allow tweaking of the "
4401"installation. If in a hurry, say NO."
4402msgstr ""
4403"Tùy chá»n cấp này có thể khó hiểu cho ngÆ°á»i dùng bắt đầu sá»­ dụng máy tính. "
4404"Tùy chá»n kiểu này thÆ°á»ng tham chiếu đến tính năng cho phép Ä‘iá»u chỉnh bản "
4405"cài đặt. Vội thì đặt NO (không)."
4406
4407#: contrib/config-daemon.scm:84 contrib/config-client.scm:83
4408msgid "Show rarely used options"
4409msgstr "Hiện tùy chá»n ít dùng"
4410
4411#: contrib/config-daemon.scm:86 contrib/config-client.scm:85
4412msgid ""
4413"These are options that hardly anyone actually needs. If you plan on doing "
4414"development on GNUnet, you may want to look into these. If in doubt or in a "
4415"hurry, say NO."
4416msgstr ""
4417"Tùy chá»n này cần bởi rất ít ngÆ°á»i. Nếu bạn định phát triển qua GNUnet, có lẽ "
4418"tùy chá»n này có ích. Nếu không hay vá»™i, hãy đặt NO (không)."
4419
4420#: contrib/config-daemon.scm:97 contrib/config-client.scm:96
4421msgid "Meta-configuration"
4422msgstr "Siêu cấu hình"
4423
4424#: contrib/config-daemon.scm:98 contrib/config-client.scm:97
4425msgid "Which level of configuration should be available"
4426msgstr "Cấp cấu hình nên sẵn sàng"
4427
4428#: contrib/config-daemon.scm:115
4429msgid "Full pathname of GNUnet HOME directory"
4430msgstr "Tên Ä‘Æ°á»ng dẫn đầy đủ đến thÆ° mục HOME GNUnet"
4431
4432#: contrib/config-daemon.scm:117
4433msgid ""
4434"This gives the root-directory of the GNUnet installation. Make sure there is "
4435"some space left in that directory. :-) Users inserting or indexing files "
4436"will be able to store data in this directory up to the (global) quota "
4437"specified below. Having a few gigabytes of free space is recommended."
4438msgstr ""
4439"Äây Ä‘Æ°a ra thÆ° mục gốc của bản cài đặt GNUnet. Hãy kiểm tra xem vẫn còn có "
4440"sức chứa còn lại trong thư mục đó. :-)\n"
4441"NgÆ°á»i dùng cần chèn hay phụ lục tập tin thì có thể lÆ°u dữ liệu vào thÆ° mục "
4442"này đến hạn ngạch (toàn cục) được ghi rõ dưới đây. Khuyên có vài GB sức chứa "
4443"còn rảnh."
4444
4445#: contrib/config-daemon.scm:130
4446msgid "Full pathname of GNUnet directory for file-sharing data"
4447msgstr ""
4448"Tên Ä‘Æ°á»ng dẫn đầy đủ đến thÆ° mục GNUnet sẽ chứa dữ liệu chia sẻ tập tin"
4449
4450#: contrib/config-daemon.scm:142
4451msgid "Full pathname to the directory with the key-value database"
4452msgstr "Tên Ä‘Æ°á»ng dẫn đầy đủ đến thÆ° mục có cÆ¡ sở dữ liệu khoá-giá_trị "
4453
4454#: contrib/config-daemon.scm:143
4455msgid "Note that the kvstore is currently not used."
4456msgstr "Ghi chú rằng hiện thá»i không dùng kvstore. "
4457
4458#: contrib/config-daemon.scm:154
4459msgid "Full pathname of GNUnet directory for indexed files symbolic links"
4460msgstr ""
4461"Tên Ä‘Æ°á»ng dẫn đầy đủ đến thÆ° mục GNUnet sẽ chứa các liên kết tÆ°Æ¡ng trÆ°ng đến "
4462"tập tin phụ lục"
4463
4464#: contrib/config-daemon.scm:166
4465msgid "How many minutes should peer advertisements last?"
4466msgstr "Có nên quảng cáo đồng đẳnh trong mấy phút?"
4467
4468#: contrib/config-daemon.scm:168
4469msgid ""
4470"How many minutes is the current IP valid? (GNUnet will sign HELLO messages "
4471"with this expiration timeline. If you are on dialup, 60 (for 1 hour) is "
4472"suggested. If you have a static IP address, you may want to set this to a "
4473"large value (say 14400). The default is 1440 (1 day). If your IP changes "
4474"periodically, you will want to choose an expiry period smaller than the "
4475"frequency with which your IP changes."
4476msgstr ""
4477"Äịa chỉ IP hiện thá»i vẫn hợp lệ trong bao nhiêu phút? (GNUnet sẽ ký má»—i "
4478"thông Ä‘iệp HELLO dùng thá»i hạn này. Nếu bạn quay số để kết nối, khuyên dùng "
4479"60 (1 giá»). Nếu máy này có má»™t địa chỉ IP tÄ©nh, má»™t giá trị lá»›n hÆ¡n (v.d. "
4480"14400) có ích. Mặc định là 1440 (1 ngày). Nếu máy này có một địa chỉ IP thay "
4481"đổi theo định kỳ, khuyên bạn chá»n má»™t thá»i hạn ngắn hÆ¡n khoảng thá»i gian "
4482"giữa hai lần thay đổi địa chỉ IP."
4483
4484#: contrib/config-daemon.scm:179
4485msgid "Where can GNUnet find an initial list of peers?"
4486msgstr "GNUnet có thể tìm một danh sách các đồng đẳng đầu tiên ở đâu?"
4487
4488#: contrib/config-daemon.scm:181
4489msgid ""
4490"GNUnet can automatically update the hostlist from the web. While GNUnet "
4491"internally communicates which hosts are online, it is typically a good idea "
4492"to get a fresh hostlist whenever gnunetd starts from the WEB. By setting "
4493"this option, you can specify from which server gnunetd should try to "
4494"download the hostlist. The default should be fine for now.\n"
4495"\t\t\n"
4496"The general format is a list of space-separated URLs. Each URL must have "
4497"the format http://HOSTNAME/FILENAME\n"
4498"\t\t\n"
4499"If you want to setup an alternate hostlist server, you must run a permanent "
4500"node and \"cat data/hosts/* > hostlist\" every few minutes to keep the list "
4501"up-to-date.\n"
4502"\t\t\n"
4503"If you do not specify a HOSTLISTURL, you must copy valid hostkeys to data/"
4504"hosts manually."
4505msgstr ""
4506"GNUnet có khả năng tự động cập nhật danh sách các máy chủ từ Web. Dù GNUnet "
4507"liên lạc ná»™i bá»™ những máy này hiện thá»i trá»±c tuyến, thÆ°á»ng có ích để lấy má»™t "
4508"danh sách máy má»›i từ Web khi nào trình ná»n gnunetd khởi chạy. Bằng cách đặt "
4509"tùy chá»n này, bạn có thể ghi rõ gnunetd nên thá»­ tải danh sách máy xuống máy "
4510"phục vụ nào. Bây giỠgiá trị mặc định vẫn ổn.\n"
4511"\n"
4512"Äịnh dạng chung là má»™t danh sách các địa chỉ URL định giá»›i bằng dấu cách. "
4513"Mỗi địa chỉ URL nên có dạng « http://tên_máy/tên_tập_tin ».\n"
4514"\n"
4515"Muốn thiết lập một máy phục vụ danh sách máy xen kẽ thì bạn cần phải chạy "
4516"má»™t nút thông tin (node) bá»n bỉ, và chạy câu lệnh « cat data/hosts/* > "
4517"hostlist » sau mỗi vài phút để cập nhật danh sách.\n"
4518"\n"
4519"Nếu bạn không ghi rõ một HOSTLISTURL (địa chỉ URL của danh sách máy), bạn "
4520"cũng cần phải tự sao chép mỗi khoá máy hợp lệ vào « data/hosts »."
4521
4522#: contrib/config-daemon.scm:198
4523msgid "HTTP Proxy Server"
4524msgstr "Máy phục vụ ủy nhiệm HTTP"
4525
4526#: contrib/config-daemon.scm:200
4527msgid ""
4528"If you have to use a proxy for outbound HTTP connections, specify the proxy "
4529"configuration here. Default is no proxy."
4530msgstr ""
4531"Nếu bạn cần dùng một máy phục vụ ủy nhiệm cho kết nối HTTP đi ra, hãy ghi rõ "
4532"cấu hình ủy nhiệm ở đây. Mặc định là không dùng ủy nhiệm."
4533
4534#: contrib/config-daemon.scm:212
4535msgid ""
4536"Name of the directory where gnunetd should store contact information about "
4537"peers"
4538msgstr "Tên của thư mục vào đó gnunetd nên lưu thông tin liên lạc vỠđồng đẳng"
4539
4540#: contrib/config-daemon.scm:214
4541msgid ""
4542"Unless you want to share the directory directly using a webserver, the "
4543"default is most likely just fine."
4544msgstr ""
4545"Nếu bạn không muốn chia sẻ thư mục một cách trực tiếp dùng một máy phục vụ "
4546"Web, giá trị mặc định rất có thể ổn."
4547
4548#: contrib/config-daemon.scm:240 contrib/config-client.scm:140
4549msgid "How long should logs be kept?"
4550msgstr "Bao lâu nên giữ bản theo dõi?"
4551
4552#: contrib/config-daemon.scm:242 contrib/config-client.scm:142
4553msgid ""
4554"How long should logs be kept? If you specify a value greater than zero, a "
4555"log is created each day with the date appended to its filename. These logs "
4556"are deleted after $KEEPLOG days.\tTo keep logs forever, set this value to 0."
4557msgstr ""
4558"Bao lâu nên giữ sổ theo dõi (log)? Nếu bạn ghi rõ một giá trị hơn số không, "
4559"một sổ theo dõi được tạo hàng ngày với ngày tháng được phụ thêm vào tên tập "
4560"tin. Sổ theo dõi này bị xoá sau $KEEPLOG ngày.\tÄể không bao giá» xoá sổ theo "
4561"dõi, hãy đặt giá trị này thành 0."
4562
4563#: contrib/config-daemon.scm:253
4564msgid ""
4565"What maximum number of open file descriptors should be requested from the OS?"
4566msgstr ""
4567"Có nên yêu cầu từ hệ Ä‘iá»u hành bao nhiêu bá»™ mô tả tập tin còn mở (tối Ä‘a)?"
4568
4569#: contrib/config-daemon.scm:255
4570msgid ""
4571"The default of 1024 should be fine for most systems. If your system can "
4572"support more, increasing the number might help support additional clients on "
4573"machines with plenty of bandwidth. For embedded systems, a smaller number "
4574"might be acceptable. A value of 0 will leave the descriptor limit "
4575"untouched. This option is mostly for OS X systems where the default is too "
4576"low. Note that if gnunetd cannot obtain the desired number of file "
4577"descriptors from the operating system, it will print a warning and try to "
4578"run with what it is given."
4579msgstr ""
4580"Giá trị mặc định 1024 nên ổn cho phần lớn hệ thống. Nếu hệ thống này có khả "
4581"năng há»— trợ nhiá»u bá»™ mô tả tập tin hÆ¡n, má»™t số lá»›n hÆ¡n có thể giúp há»— trợ "
4582"các ứng dụng khách bổ sung trên máy có rất nhiá»u bảng thông. Äối vá»›i hệ "
4583"thống nhúng, một số nhỠhơn có thể ổn. Giá trị 0 sẽ không thay đổi giới hạn. "
4584"Tùy chá»n này thÆ°á»ng có ích trên hệ thống OSX (có giá trị mặc định quá thấp). "
4585"Ghi chú rằng nếu gnunetd không thể lấy số các bộ mô tả tập tin yêu cầu từ hệ "
4586"Ä‘iá»u hành, thì nó sẽ in ra má»™t cảnh báo và thá»­ chạy vá»›i số Ä‘Æ°a ra."
4587
4588#: contrib/config-daemon.scm:266
4589msgid "Where should gnunetd write the logs?"
4590msgstr "gnunetd nên ghi sổ theo dõi vào đâu?"
4591
4592#: contrib/config-daemon.scm:278
4593msgid "Enable for extra-verbose logging."
4594msgstr "Bật để theo dõi rất chi tiết hơn."
4595
4596#: contrib/config-daemon.scm:290 contrib/config-client.scm:165
4597msgid "Logging"
4598msgstr "Theo dõi"
4599
4600#: contrib/config-daemon.scm:291 contrib/config-client.scm:166
4601msgid "Specify which system messages should be logged how"
4602msgstr "Ghi rõ những thông điệp hệ thống nào nên được theo dõi như thế nào"
4603
4604#: contrib/config-daemon.scm:296 contrib/config-client.scm:170
4605msgid "Logging of events for users"
4606msgstr "Theo dõi sá»± kiện cho ngÆ°á»i dùng"
4607
4608#: contrib/config-daemon.scm:297 contrib/config-client.scm:171
4609msgid "Logging of events for the system administrator"
4610msgstr "Theo dõi sự kiện cho quản trị hệ thống"
4611
4612#: contrib/config-daemon.scm:309
4613msgid "Where should gnunetd write the PID?"
4614msgstr "gnunetd nên ghi PID vào đâu?"
4615
4616#: contrib/config-daemon.scm:310
4617msgid ""
4618"The default is no longer /var/run/gnunetd.pid since we could not delete the "
4619"file on shutdown at that location."
4620msgstr ""
4621"Giá trị mặc định không còn là « /var/run/gnunetd.pid » lại, vì không thể xoá "
4622"tập tin ở vị trí đó khi tắt máy."
4623
4624#: contrib/config-daemon.scm:322
4625msgid "As which user should gnunetd run?"
4626msgstr "gnunetd nên chạy dÆ°á»›i ngÆ°á»i dùng nào?"
4627
4628#: contrib/config-daemon.scm:324
4629msgid ""
4630"Empty means \"current user\". On computer startup, it is root/SYSTEM. Under "
4631"Windows, this setting affects the creation of a new system service only."
4632msgstr ""
4633"Trống có nghÄ©a là « ngÆ°á»i dùng hiện thá»i ». Khi máy khởi Ä‘á»™ng, nó là « root/"
4634"SYSTEM ». Dưới Windows, thiết lập này chỉ ảnh hưởng đến việc tạo một dịch vụ "
4635"hệ thống."
4636
4637#: contrib/config-daemon.scm:337
4638msgid "Should gnunetd be automatically started when the system boots?"
4639msgstr "Khi hệ thống khởi động, có nên tự động khởi chạy gnunetd không?"
4640
4641#: contrib/config-daemon.scm:338
4642msgid ""
4643"Set to YES if gnunetd should be automatically started on boot. If this "
4644"option is set, gnunet-setup will install a script to start the daemon upon "
4645"completion. This option may not work on all systems."
4646msgstr ""
4647"Äặt thành YES (có) nếu trình ná»n gnunetd nên tá»± Ä‘á»™ng được khởi chạy khi hệ "
4648"thống khởi Ä‘á»™ng. Nếu đặt tùy chá»n này thì tiến trình thiết lập gnunet-setup "
4649"sẽ cài đặt má»™t văn lệnh để khởi chạy trình ná»n này má»™t khi hoàn tất. Tùy "
4650"chá»n này có thể không hoạt Ä‘á»™ng đúng trên má»i hệ thống."
4651
4652#: contrib/config-daemon.scm:350
4653msgid "Which transport mechanisms should GNUnet use?"
4654msgstr "GNUnet nên dùng những cÆ¡ chế truyá»n nào?"
4655
4656#: contrib/config-daemon.scm:352
4657msgid ""
4658"Use a space-separated list of modules, e.g. \"udp smtp tcp\". The "
4659"available transports are udp, tcp, http, smtp and nat.\n"
4660"\t\t\n"
4661"Loading the 'nat' and 'tcp' modules is required for peers behind NAT boxes "
4662"that cannot directly be reached from the outside. Peers that are NOT behind "
4663"a NAT box and that want to *allow* peers that ARE behind a NAT box to "
4664"connect must ALSO load the 'nat' module. Note that the actual transfer will "
4665"always be via tcp initiated by the peer behind the NAT box. The nat "
4666"transport requires the use of tcp, http and/or smtp in addition to nat "
4667"itself."
4668msgstr ""
4669"Dùng một danh sách các mô-đun định giới bằng dấu cách, v.d. « udp smtp tcp ». "
4670"Những cÆ¡ chế truyá»n sẵn sàng: udp, tcp, http, smtp, nat.\n"
4671"\n"
4672"Nạp hai mô-đun « nat » và « tcp » cần thiết cho đồng đẳng nằm sau máy NAT mà "
4673"không tá»›i được từ bên ngoài. Äồng đẳng KHÔNG phải nằm sau máy NAT và muốn "
4674"_cho phép_ kết nối từ đồng đẳng mà CÓ phải nằm sau NAT thì CŨNG cần phải nạp "
4675"mô-Ä‘un « nat ». Ghi chú rằng việc truyá»n thật lúc nào cÅ©ng chạy qua tcp, được "
4676"sÆ¡ khởi bởi đồng đẳng nằm sau máy NAT. CÆ¡ chế truyá»n nat cÅ©ng cần thiết tcp, "
4677"http và/hay smtp thêm vào nat chính nó."
4678
4679#: contrib/config-daemon.scm:366
4680msgid "Which applications should gnunetd support?"
4681msgstr "gnunetd nên hỗ trợ những ứng dụng nào?"
4682
4683#: contrib/config-daemon.scm:368
4684msgid ""
4685"Whenever this option is changed, you MUST run gnunet-update. Currently, the "
4686"available applications are:\n"
4687"\n"
4688"advertising: advertises your peer to other peers. Without it, your peer will "
4689"not participate in informing peers about other peers. You should always "
4690"load this module.\n"
4691"\n"
4692"getoption: allows clients to query gnunetd about the values of various "
4693"configuration options. Many tools need this. You should always load this "
4694"module.\n"
4695"\n"
4696"stats: allows tools like gnunet-stats and gnunet-gtk to query gnunetd about "
4697"various statistics. This information is usually quite useful to diagnose "
4698"errors, hence it is recommended that you load this module.\n"
4699"\n"
4700"traffic: keeps track of how many messages were recently received and "
4701"transmitted. This information can then be used to establish how much cover "
4702"traffic is currently available. The amount of cover traffic becomes "
4703"important if you want to make anonymous requests with an anonymity level "
4704"that is greater than one. It is recommended that you load this module.\n"
4705"\n"
4706"fs: needed for anonymous file sharing. You should always load this module.\n"
4707"\n"
4708"hostlist: integrated hostlist HTTP server. Useful if you want to offer a "
4709"hostlist and running Apache would be overkill.\n"
4710"\n"
4711"chat: broadcast chat (demo-application, ALPHA quality).\tRequired for gnunet-"
4712"chat. Note that the current implementation of chat is not considered to be "
4713"secure.\n"
4714"\n"
4715"tbench: benchmark transport performance. Required for gnunet-tbench. Note "
4716"that tbench allows other users to abuse your resources.\n"
4717"\n"
4718"tracekit: topology visualization toolkit. Required for gnunet-tracekit. "
4719"Note that loading tracekit will make it slightly easier for an adversary to "
4720"compromise your anonymity."
4721msgstr ""
4722"Khi nào tùy chá»n này bị thay đổi, bạn CẦN PHẢI chạy tiến trình cập nhật "
4723"gnunet-update. Hiện thá»i có những ứng dụng sẵn sàng này:\n"
4724"\n"
4725" • advertising\tquảng cáo đồng đẳng này cho các đồng đẳng khác. Không có ứng "
4726"dụng này thì đồng đẳng này sẽ không tham gia hoạt động cho đồng đẳng biết vỠ"
4727"đồng đẳng khác. Lúc nào cũng nên nạp mô-đun này.\n"
4728"\n"
4729" • getoption\tcho phép ứng dụng khách há»i gnunetd vá» giá trị của má»™t số tùy "
4730"chá»n cấu hình nào đó. Rất nhiá»u công cụ cần chức năng này. Lúc nào cÅ©ng nên "
4731"nạp mô-đun này.\n"
4732"\n"
4733" • stats\tcho phép công cụ nhÆ° gnunet-stats và gnunet-gtk há»i gnunetd vá» má»™t "
4734"số thống kê nào đó. Thông tin này thÆ°á»ng hÆ¡i hữu ích để chẩn Ä‘oán lá»—i, do đó "
4735"khuyên bạn nạp mô-đun này.\n"
4736"\n"
4737" • traffic\ttheo dõi bao nhiêu tin nhẳn vừa nhận và gửi. Thông tin này thì "
4738"có thể được dùng để tính bao nhiêu giao thông trải ra hiện thá»i sẵn sàng. "
4739"Lượng giao thông trải ra trở thành quan trá»ng nếu bạn muốn gá»­i yêu cầu nặc "
4740"danh với một cấp nặc danh hơn một. Khuyên bạn nạp mô-đun này.\n"
4741"\n"
4742" • fs\tcần để chia sẻ tập tin một cách nặc danh. Lúc nào cũng nên nạp mô-đun "
4743"này.\n"
4744"\n"
4745" • hostlist\ttrình phục vụ HTTP danh sách máy thống nhất. Có ích nếu bạn "
4746"muốn cung cấp một danh sách máy, nhưng không muốn chạy Apache cho một công "
4747"việc rất nhỠnhư vậy.\n"
4748"\n"
4749" • chat\ttrò chuyện quảng bá (ứng dụng minh hoạ, vẫn ALPHA). Cần thiết cho "
4750"ứng dụng trò chuyện gnunet-chat. Ghi chú rằng bản thá»±c hiện chat hiện thá»i "
4751"chưa được xem là bảo mật.\n"
4752"\n"
4753" • tbench\tkiểm chuẩn hiệu suất truyá»n. Cần thiết cho gnunet-tbench. Ghi chú "
4754"rằng tbench cho phép ngÆ°á»i dùng khác lạm dụng các tài nguyên của bạn.\n"
4755"\n"
4756" • tracekit\tbá»™ công cụ mÆ°á»ng tượng địa hình. Cần thiết cho gnunet-tracekit. "
4757"Ghi chú rằng việc nạp tracekit sẽ làm cho má»™t ít dá»… hÆ¡n khi ngÆ°á»i dùng muốn "
4758"xâm nhập tình trạng nặc danh của bạn."
4759
4760#: contrib/config-daemon.scm:399
4761msgid "Disable client-server connections"
4762msgstr "Tắt má»i kết nối kiểu khách-máy_phục_vụ"
4763
4764#: contrib/config-daemon.scm:400
4765msgid ""
4766"This option can be used to tell gnunetd not to open the client port. When "
4767"run like this, gnunetd will participate as a peer in the network but not "
4768"support any user interfaces. This may be useful for headless systems that "
4769"are never expected to have end-user interactions. Note that this will also "
4770"prevent you from running diagnostic tools like gnunet-stats!"
4771msgstr ""
4772"Tùy chá»n này có thể được dùng để báo trình ná»n gnunetd không mở cổng cho ứng "
4773"dụng khách. Khi chạy bằng cách này, gnunetd sẽ tham gia là một đồng đẳng "
4774"trên mạng, còn không há»— trợ giao diện ngÆ°á»i dùng nào. Có thể hữu ích cho hệ "
4775"thống không cần màn hình mà không bao giá» nên tÆ°Æ¡ng tác vá»›i ngÆ°á»i dùng cuối "
4776"cùng. Ghi chú rằng tùy chá»n này cÅ©ng ngăn cản bạn chạy công cụ chẩn Ä‘oán nhÆ° "
4777"tiến trình thống kê gnunet-stats !"
4778
4779#: contrib/config-daemon.scm:412
4780msgid "YES disables IPv6 support, NO enables IPv6 support"
4781msgstr "YES hay NO thì tắt hay bật hỗ trợ IPv6"
4782
4783#: contrib/config-daemon.scm:413
4784msgid ""
4785"This option may be useful on peers where the kernel does not support IPv6. "
4786"You might also want to set this option if you do not have an IPv6 network "
4787"connection."
4788msgstr ""
4789"Tùy chá»n này có thể hữu ích trên đồng đẳng không có hạt nhân há»— trợ IPv6. "
4790"CÅ©ng có thể đặt tùy chá»n này nếu không có kết nối mạng kiểu IPv6."
4791
4792#: contrib/config-daemon.scm:425
4793msgid "Disable peer discovery"
4794msgstr "Tắt khám phá đồng đẳng"
4795
4796#: contrib/config-daemon.scm:426
4797msgid ""
4798"The option 'PRIVATE-NETWORK' can be used to limit the connections of this "
4799"peer to peers of which the hostkey has been copied by hand to data/hosts; "
4800"if this option is given, GNUnet will not accept advertisements of peers that "
4801"the local node does not already know about. Note that in order for this "
4802"option to work, HOSTLISTURL should either not be set at all or be set to a "
4803"trusted peer that only advertises the private network. Also, the option does "
4804"NOT work at the moment if the NAT transport is loaded; for that, a couple of "
4805"lines above would need some minor editing :-)."
4806msgstr ""
4807"Tùy chá»n « PRIVATE-NETWORK » có thể được dùng để hạn chế kết nối của đồng "
4808"đẳng này thành những đồng đẳng có khoá máy đã được sao chép bằng tay vào « "
4809"data/hosts »; nếu bật tùy chá»n này thì GNUnet sẽ không chấp nhận quảng cáo "
4810"vỠđồng đẳng không được nút cục bá»™ nhận ra. Ghi chú rằng tùy chá»n này cÅ©ng "
4811"cần HOSTLISTURL không đặt bằng cách nào cả hay có đặt thành một đồng đẳng "
4812"tin cậy mà chỉ quảng cáo mạng riêng. HÆ¡n nữa, tùy chá»n này KHÔNG hoạt Ä‘á»™ng "
4813"khi nào cÆ¡ chế trung NAT được nạp: để tránh trÆ°á»ng hợp đó, cÅ©ng cần phải "
4814"chỉnh sửa vài dòng bên trên. :-)"
4815
4816#: contrib/config-daemon.scm:437
4817msgid "Disable advertising this peer to other peers"
4818msgstr "Tắt quảng cáo máy này cho đồng đẳng khác"
4819
4820#: contrib/config-daemon.scm:449
4821msgid "Disable automatic establishment of connections"
4822msgstr "Tắt tự động thiết lập kết nối"
4823
4824#: contrib/config-daemon.scm:450
4825msgid ""
4826"If this option is enabled, GNUnet will not automatically establish "
4827"connections to other peers, but instead wait for applications to "
4828"specifically request connections to other peers (or for other peers to "
4829"connect to us)."
4830msgstr ""
4831"Bật tùy chá»n này thì GNUnet sẽ không tá»± Ä‘á»™ng thiết lập kết nối tá»›i đồng đẳng "
4832"khác, thay vào đó nó đợi ứng đụng yêu cầu dứt khoát kết nối tới đồng đẳng "
4833"khác (hoặc đợi đồng đẳng khác kết nối đến máy này)."
4834
4835#: contrib/config-daemon.scm:461
4836msgid "Enable advertising of other peers by this peer"
4837msgstr "Bật máy này quảng cáo đồng đẳng khác"
4838
4839#: contrib/config-daemon.scm:462
4840msgid ""
4841"This option may be useful during testing, but turning it off is dangerous! "
4842"If in any doubt, set it to YES (which is the default)."
4843msgstr ""
4844"Tùy chá»n này có thể hữu ích trong khi thá»­: trong má»i trÆ°á»ng hợp Ä‘á»u không "
4845"nên tắt nó ! Chưa chắc thì đặt nó thành YES (có) mà mặc định."
4846
4847#: contrib/config-daemon.scm:473
4848msgid "Port for communication with GNUnet user interfaces"
4849msgstr "Cổng để liên lạc vá»›i giao diện ngÆ°á»i dùng GNUnet"
4850
4851#: contrib/config-daemon.scm:474
4852msgid ""
4853"Which is the client-server port that is used between gnunetd and the clients "
4854"(TCP only). You may firewall this port for non-local machines (but you do "
4855"not have to since GNUnet will perform access control and only allow "
4856"connections from machines that are listed under TRUSTED)."
4857msgstr ""
4858"Trình ná»n gnunetd và các ứng dụng khách liên lạc (chỉ TCP) qua cổng khách-"
4859"phục_vụ nào? Bạn cÅ©ng có thể đặt bức tÆ°á»ng lá»­a giữa cổng này và các máy khác "
4860"cục bá»™, nhÆ°ng không cần phải vì GNUnet sẽ Ä‘iá»u khiển truy cập và chỉ cho "
4861"phép kết nối từ máy được liệt kê dưới TRUSTED (tin cậy). "
4862
4863#: contrib/config-daemon.scm:485
4864msgid "Port for the integrated hostlist HTTP server"
4865msgstr "Cổng cho trình phục vụ HTTP danh sách máy chủ thống nhất"
4866
4867#: contrib/config-daemon.scm:497
4868msgid "IPv4 networks allowed to use gnunetd server"
4869msgstr "Các mạng IPV4 được phép dùng trình phục vụ gnunetd"
4870
4871#: contrib/config-daemon.scm:498 contrib/config-daemon.scm:510
4872msgid ""
4873"This option specifies which hosts are trusted enough to connect as clients "
4874"(to the TCP port). This is useful if you run gnunetd on one host of your "
4875"network and want to allow all other hosts to use this node as their server. "
4876"By default, this is set to 'loopback only'. The format is IP/NETMASK where "
4877"the IP is specified in dotted-decimal and the netmask either in CIDR "
4878"notation (/16) or in dotted decimal (255.255.0.0). Several entries must be "
4879"separated by a semicolon, spaces are not allowed."
4880msgstr ""
4881"Tùy chá»n này ghi rõ những máy nào đủ tin cậy để kết nối là ứng dụng khách "
4882"(đến cổng TCP). Có ích nếu bạn chạy trình nên gnunetd trên một máy của mạng "
4883"cục bộ, cũng muốn các máy khác cùng mạng dùng nút này làm máy phục vụ. Mặc "
4884"định là tùy chá»n này được đặt thành « loopback only » (chỉ mạch ná»™i bá»™). Äịnh "
4885"dạng là IP/MẶT_NẠ_MẠNG mà địa chỉ IP được ghi rõ theo thập phân đánh chấm (v."
4886"d. 255.255.0.0), và mặt nạ mạng (netmask) theo hoặc cách ghi CIDR (v.d. "
4887"1/16) hoặc thập phân đánh chấm. Vài mục nhập nên định giới bằng dấu hai "
4888"chấm, cũng không cho phép khoảng cách."
4889
4890#: contrib/config-daemon.scm:509
4891msgid "IPv6 networks allowed to use gnunetd server"
4892msgstr "Các mạng IPv6 được phép dùng trình phục vụ gnunetd"
4893
4894#: contrib/config-daemon.scm:522
4895msgid "Limit connections to the specfied set of peers."
4896msgstr "Hạn chế kết nối thành tập hợp đồng đẳng được ghi rõ."
4897
4898#: contrib/config-daemon.scm:523
4899msgid ""
4900"If this option is not set, any peer is allowed to connect. If it is set, "
4901"only the specified peers are allowed. Specify the list of peer IDs (not IPs!)"
4902msgstr ""
4903"Không bật tùy chá»n này thì má»i đồng đẳng được phép kết nối. Nếu bật nó thì "
4904"chỉ cho phép những đồng đẳng đưa ra. Hãy ghi rõ danh sách các mã số đồng "
4905"đẳng, không phải địa chỉ IP !"
4906
4907#: contrib/config-daemon.scm:534
4908msgid "Run gnunetd as this group."
4909msgstr "Chạy gnunetd dưới nhóm này."
4910
4911#: contrib/config-daemon.scm:535
4912msgid ""
4913"When started as root, gnunetd will change permissions to the given group."
4914msgstr ""
4915"Khi khởi chạy bởi ngÆ°á»i chủ, trình ná»n gnunetd sẽ chuyển đổi quyá»n truy cập "
4916"sang nhóm đưa ra."
4917
4918#: contrib/config-daemon.scm:546
4919msgid "Prevent the specfied set of peers from connecting."
4920msgstr "Chặn kết nối từ tập hợp đồng đẳng được ghi rõ."
4921
4922#: contrib/config-daemon.scm:547
4923msgid ""
4924"If this option is not set, any peer is allowed to connect. If the ID of a "
4925"peer is listed here, connections from that peer will be refused. Specify "
4926"the list of peer IDs (not IPs!)"
4927msgstr ""
4928"Không bật tùy chá»n này thì má»i đồng đẳng Ä‘á»u được phép kết nối. Nếu mã số "
4929"của một đồng đẳng nào đó được liệt kê ở đây, thì kết nối từ máy đó bị từ "
4930"chối. Hãy ghi rõ danh sách các mã số đồng đẳng, không phải địa chỉ IP !"
4931
4932#: contrib/config-daemon.scm:558
4933msgid "Topology Maintenance"
4934msgstr "Duy trì địa hình"
4935
4936#: contrib/config-daemon.scm:559
4937msgid "Rarely used settings for peer advertisements and connections"
4938msgstr "Thiết lập ít dùng vỠquảng cáo và kết nối của đồng đẳng"
4939
4940#: contrib/config-daemon.scm:579
4941msgid "General settings"
4942msgstr "Thiết lập chung"
4943
4944#: contrib/config-daemon.scm:580
4945msgid "Settings that change the behavior of GNUnet in general"
4946msgstr "Thiết lập mà sửa đổi ứng xử chung của GNUnet"
4947
4948#: contrib/config-daemon.scm:607
4949msgid "Modules"
4950msgstr "Mô-đun"
4951
4952#: contrib/config-daemon.scm:608
4953msgid "Settings that select specific implementations for GNUnet modules"
4954msgstr "Thiết lập mà chá»n bản thá»±c hiện riêng cho mô-Ä‘un GNUnet"
4955
4956#: contrib/config-daemon.scm:626
4957msgid "Fundamentals"
4958msgstr "Cơ bản"
4959
4960#: contrib/config-daemon.scm:646
4961msgid "Which database should be used?"
4962msgstr "Có nên dùng cơ sở dữ liệu nào?"
4963
4964#: contrib/config-daemon.scm:648
4965#, fuzzy
4966msgid ""
4967"Which database should be used? The options are \"sqstore_sqlite\", "
4968"\"sqstore_postgres\" and \"sqstore_mysql\". You must run gnunet-update "
4969"after changing this value!\n"
4970"\t\t\t\n"
4971"In order to use MySQL or Postgres, you must configure the respective "
4972"database, which is relatively simple. Read the file doc/README.mysql or doc/"
4973"README.postgres for how to setup the respective database."
4974msgstr ""
4975"Có nên dùng cÆ¡ sở dữ liệu nào? Hai tùy chá»n là « sqstore_sqlite » và « "
4976"sqstore_mysql ». Sau khi thay đổi giá trị này thì cũng cần phải chạy tiến "
4977"trình cập nhật gnunet-update !\n"
4978"\n"
4979"Äể sá»­ dụng sqstore_mysql, bạn cÅ©ng cần phải cấu hình cÆ¡ sở dữ liệu MySQL: "
4980"má»™t công việc hÆ¡i Ä‘Æ¡n giản. Hãy Ä‘á»c tài liệu Äá»c Äi « doc/README.mysql » để "
4981"tìm biết thiết lập MySQL như thế nào."
4982
4983#: contrib/config-daemon.scm:661 contrib/config-daemon.scm:674
4984msgid "Which topology should be used?"
4985msgstr "Có nên địa hình nào?"
4986
4987#: contrib/config-daemon.scm:662
4988msgid "Which database should be used for the temporary datastore of the DHT?"
4989msgstr "Có nên dùng cÆ¡ sở dữ liệu nào làm kho dữ liệu tạm thá»i của DHT?"
4990
4991#: contrib/config-daemon.scm:676
4992msgid ""
4993"Which topology should be used? The only option at the moment is "
4994"\"topology_default\""
4995msgstr ""
4996"Có nên địa hình nào? Tùy chá»n duy nhất hiện thá»i là « topology_default »."
4997
4998#: contrib/config-daemon.scm:690
4999msgid ""
5000"The minimum number of connected friends before this peer is allowed to "
5001"connect to peers that are not listed as friends"
5002msgstr ""
5003"Số tối thiểu các bạn bè có kết nối trước khi đồng đẳng nay được phép kết nối "
5004"tới đồng đẳng lạ (không phải được liệt kê là bạn bè)"
5005
5006#: contrib/config-daemon.scm:691
5007msgid ""
5008"Note that this option does not guarantee that the peer will be able to "
5009"connect to the specified number of friends. Also, if the peer had connected "
5010"to a sufficient number of friends and then established non-friend "
5011"connections, some of the friends may drop out of the network, temporarily "
5012"resulting in having fewer than the specified number of friends connected "
5013"while being connected to non-friends. However, it is guaranteed that the "
5014"peer itself will never choose to drop a friend's connection if this would "
5015"result in dropping below the specified number of friends (unless that number "
5016"is higher than the overall connection target)."
5017msgstr ""
5018"Ghi chú rằng tùy chá»n này không đảm bảo rằng đồng đẳng sẽ kết nối được tá»›i "
5019"số các bạn bè đưa ra. Hơn nữa, nếu đồng đẳng có kết nối tới đủ bạn bè, sau "
5020"đó thiết lập kết nối khác bạn bè, thì má»™t số bạn bè có thể dứt khá»i mạng, "
5021"tạm thá»i có kết quả là quá ít bạn bè có kết nối trong khi kết nối tá»›i khác "
5022"bạn bè. Tuy nhiên đảm bảo rằng đồng đẳng chính nó không bao giá» chá»n ngắt "
5023"kết nối tới bạn bè nếu việc đó có kết quả là quá ít bán bè có kết nối (nếu "
5024"số đã đặt không phải lớn hơn đích kết nối toàn bộ)."
5025
5026#: contrib/config-daemon.scm:702
5027msgid ""
5028"If set to YES, the peer is only allowed to connect to other peers that are "
5029"explicitly specified as friends"
5030msgstr ""
5031"Bật tùy chá»n này (đặt YES) thì đồng đẳng chỉ được phép tá»›i đồng đẳng được "
5032"ghi rõ dứt khoát là bạn bè"
5033
5034#: contrib/config-daemon.scm:703
5035msgid ""
5036"Use YES only if you have (trustworthy) friends that use GNUnet and are "
5037"afraid of establishing (direct) connections to unknown peers"
5038msgstr ""
5039"Hãy đặt YES chỉ nếu bạn có bạn bè tin cậy có sử dụng GNUnet và không muốn "
5040"thiết lập kết nối trực tiếp tới đồng đẳng lạ"
5041
5042#: contrib/config-daemon.scm:714
5043msgid "List of friends for friend-to-friend topology"
5044msgstr "Danh sách bạn bè cho địa hình bạn-đến-bạn"
5045
5046#: contrib/config-daemon.scm:715
5047msgid ""
5048"Specifies the name of a file which contains a list of GNUnet peer IDs that "
5049"are friends. If used with the friend-to-friend topology, this will ensure "
5050"that GNUnet only connects to these peers (via any available transport)."
5051msgstr ""
5052"Ghi rõ tên của một tập tin chứa danh sách các mã số đồng đẳng GNUnet cũng là "
5053"bạn bè. Nếu dùng vá»›i địa hình bạn-đến-bạn, thì tùy chá»n này sẽ đảm bảo rằng "
5054"GNUnet chỉ kết nối tá»›i những đồng đẳng đó (qua bất cứ cÆ¡ chế truyá»n hoạt "
5055"động nào)."
5056
5057#: contrib/config-daemon.scm:726
5058msgid "Friend-to-Friend Topology Specification"
5059msgstr "Äặc tả địa hình bạn-đến-bạn"
5060
5061#: contrib/config-daemon.scm:727
5062msgid "Settings for restricting connections to friends"
5063msgstr "Thiết lập để hạn chế kết nối thành bạn bè"
5064
5065#: contrib/config-daemon.scm:744
5066msgid "Name of the MySQL database GNUnet should use"
5067msgstr "Tên của cơ sở dữ liệu MySQL mà GNUnet nên dùng"
5068
5069#: contrib/config-daemon.scm:756
5070msgid "Configuration file that specifies the MySQL username and password"
5071msgstr "Tập tin cấu hình mà ghi rõ tên ngÆ°á»i dùng và mật khẩu MySQL"
5072
5073#: contrib/config-daemon.scm:768
5074msgid "Configuration of the MySQL database"
5075msgstr "Cấu hình của cơ sở dữ liệu MySQL"
5076
5077#: contrib/config-daemon.scm:787
5078msgid "MB of diskspace GNUnet can use for anonymous file sharing"
5079msgstr "MB sức chứa trên đĩa cho GNUnet dùng để chia sẻ tập tin nặc danh"
5080
5081#: contrib/config-daemon.scm:789
5082msgid ""
5083"How much disk space (MB) is GNUnet allowed to use for anonymous file "
5084"sharing? This does not take indexed files into account, only the space "
5085"directly used by GNUnet is accounted for. GNUnet will gather content from "
5086"the network if the current space-consumption is below the number given here "
5087"(and if content migration is allowed below).\n"
5088"\n"
5089"Note that if you change the quota, you need to run gnunet-update afterwards."
5090msgstr ""
5091"Bao nhiêu sức chứa trên đĩa (theo MB) cho phép GNUnet dùng để chia sẻ tập "
5092"tin một cách nặc danh? Giá trị này không tính tập tin phụ lục, chỉ tính sức "
5093"chứa được GNUnet dùng trực tiếp. GNUnet sẽ tập hợp nội dung từ mạng nếu tiêu "
5094"thụ sức chứa hiện thá»i nhá» hÆ¡n số Ä‘Æ°a ra ở đây (và nếu chức năng nâng cấp "
5095"nội dung được phép bên dưới).\n"
5096"\n"
5097"Ghi chú rằng nếu bạn sửa đổi hạn ngạch này, sau đó cũng cần phải chạy tiến "
5098"trình cập nhật gnunet-update."
5099
5100#: contrib/config-daemon.scm:803
5101msgid "Number of entries in the migration buffer"
5102msgstr "Số các mục nhập trong vùng đệm nâng cấp"
5103
5104#: contrib/config-daemon.scm:804
5105msgid ""
5106"Each entry uses about 32k of memory. More entries can reduce disk IO and "
5107"CPU usage at the expense of having gnunetd use more memory. Very large "
5108"values may again increase CPU usage. A value of 0 will prevent your peer "
5109"from sending unsolicited responses."
5110msgstr ""
5111"Má»—i mục nhập chiếm khoảng 32k trong vùng nhá»›. Nhiá»u mục nhập hÆ¡n thì có thể "
5112"giảm VR của đĩa và sử dụng CPU, còn gnunetd chiếm vùng nhớ lớn hơn. Giá trị "
5113"rất lớn cũng có thể tăng sử dụng CPU. Giá trị 0 sẽ ngăn cản máy này đáp ứng "
5114"mà không yêu cầu."
5115
5116#: contrib/config-daemon.scm:816
5117msgid "Size of the routing table for anonymous routing."
5118msgstr "Kích cỡ của bảng định tuyến đối với định tuyến nặc danh."
5119
5120#: contrib/config-daemon.scm:828
5121msgid "Size of the routing table for DHT routing."
5122msgstr "Kích cỡ của bảng định tuyến đối với định tuyến DHT."
5123
5124#: contrib/config-daemon.scm:841
5125msgid "Allow migrating content to this peer."
5126msgstr "Cho phép nâng cấp nội dung lên máy này."
5127
5128#: contrib/config-daemon.scm:843
5129msgid ""
5130"If you say yes here, GNUnet will migrate content to your server, and you "
5131"will not be able to control what data is stored on your machine. \n"
5132"\t\t\t\n"
5133"If you activate it, you can claim for *all* the non-indexed (-n to gnunet-"
5134"insert) content that you did not know what it was even if an adversary takes "
5135"control of your machine. If you do not activate it, it is obvious that you "
5136"have knowledge of all the content that is hosted on your machine and thus "
5137"can be considered liable for it."
5138msgstr ""
5139"Bật tùy chá»n này thì GNUnet sẽ nâng cấp ná»™i dung đến máy phục vụ này, và bạn "
5140"không thể Ä‘iá»u khiển dữ liệu nào được giữ trên máy này.\n"
5141"\n"
5142"Tùy chá»n này cho phép ngÆ°á»i dùng từ chối trách nhiệm vá» ná»™i dung không phụ "
5143"lục (-n tá»›i gnunet-insert) nằm trong máy của mình, thậm chí nếu ngÆ°á»i khác "
5144"xâm nhập hệ thống. Không bật tùy chá»n này thì ngÆ°á»i dùng chịu trách nhiệm vá» "
5145"tất cả các nội dung trên máy của mình."
5146
5147#: contrib/config-daemon.scm:857
5148msgid ""
5149"MB of diskspace GNUnet can use for caching DHT index data (the data will be "
5150"stored in /tmp)"
5151msgstr ""
5152"MB sức chứa trên đĩa cho GNUnet dùng để lưu tạm dữ liệu phụ lục DHT (dữ liệu "
5153"được giữ trong /tmp)"
5154
5155#: contrib/config-daemon.scm:858
5156msgid ""
5157"DHT index data is inherently small and expires comparatively quickly. It is "
5158"deleted whenever gnunetd is shut down.\n"
5159"\n"
5160"The size of the DSTORE QUOTA is specified in MB."
5161msgstr ""
5162"Dữ liệu phụ lục DHT vốn đã nhỠvà hết hạn hơi nhanh. Nó bị xoá khi nào "
5163"gnunetd bị thoát.\n"
5164"\n"
5165"Kích cỡ của hạn ngạch kho dữ liệu (DSTORE QUOTA) được ghi rõ theo MB."
5166
5167#: contrib/config-daemon.scm:872
5168msgid "Options for anonymous file sharing"
5169msgstr "Tùy chá»n vá» chia sẻ tập tin nặc danh"
5170
5171#: contrib/config-daemon.scm:891
5172msgid "Applications"
5173msgstr "Ứng dụng"
5174
5175#: contrib/config-daemon.scm:907
5176msgid "Is this machine unreachable behind a NAT?"
5177msgstr "Máy này không tới được ở sau NAT không?"
5178
5179#: contrib/config-daemon.scm:908
5180msgid ""
5181"Set to YES if this machine is behind a NAT that limits connections from the "
5182"outside to the GNUnet port and that cannot be traversed using UPnP. Note "
5183"that if you have configured your NAT box to allow direct connections from "
5184"other machines to the GNUnet ports or if GNUnet can open ports using UPnP, "
5185"you should set the option to NO. Set this only to YES if other peers cannot "
5186"contact you directly. You can use 'make check' in src/transports/upnp/ to "
5187"find out if your NAT supports UPnP. You can also use gnunet-transport-check "
5188"with the '-p' option in order to determine which setting results in more "
5189"connections. Use YES only if you get no connections otherwise. Set to AUTO "
5190"to use YES if the local IP is belongs to a private IP network and NO "
5191"otherwise."
5192msgstr ""
5193"Äặt thành YES (có) nếu máy này nằm sau má»™t máy NAT mà hạn chế kết nối từ bên "
5194"ngoài đến cổng GNUnet và không thể đi qua được dùng UPnP. Ghi chú rằng nếu "
5195"bạn đã cấu hình máy NAT để cho phép kết nối trực tiếp từ máy khác đến cổng "
5196"GNUnet, hoặc nếu GNUnet có quyá»n mở cổng dùng UPnP, thì bạn nên đặt tùy chá»n "
5197"này thành NO (không). Chỉ đặt thành YES nếu đồng đẳng khác không thể liên "
5198"lạc với máy này một cách trực tiếp. Bạn cũng có thể sử dụng câu lệnh « make "
5199"check » (trong /src/transports/upnp) để tìm biết nếu NAT đó hỗ trợ UPnP "
5200"không. Bạn cÅ©ng có thể sá»­ dụng công cụ gnunet-transport-check vá»›i tùy chá»n « -"
5201"p » để quyết định thiết lập nào gây ra nhiá»u kết nối hÆ¡n. Äặt YES chỉ nếu "
5202"bạn không nhận kết nối bằng cách khác. Äặt thành AUTO (tá»± Ä‘á»™ng) để sá»­ dụng "
5203"YES nếu địa chỉ IP cục bộ thuộc vỠmột mạng IP riêng, không thì NO."
5204
5205#: contrib/config-daemon.scm:919
5206msgid "Which port should be used by the TCP IPv4 transport?"
5207msgstr "CÆ¡ chế truyá»n IPv4 TCP nên dùng cổng nào?"
5208
5209#: contrib/config-daemon.scm:931 contrib/config-daemon.scm:1024
5210#: contrib/config-daemon.scm:1174
5211msgid "Should we try to determine our external IP using UPnP?"
5212msgstr "Có nên thử quyết định địa chỉ IP bên ngoài của mình dùng UPnP không?"
5213
5214#: contrib/config-daemon.scm:943
5215msgid "Which IP(v4)s are not allowed to connect?"
5216msgstr "Những địa chỉ IP(v4) nào không có quyá»n kết nối?"
5217
5218#: contrib/config-daemon.scm:955
5219msgid ""
5220"Which IP(v4)s are allowed to connect? Leave empty to use the IP of your "
5221"primary network interface."
5222msgstr ""
5223"Những địa chỉ IP(v4) nào có quyá»n kết nối? Bá» trống để sá»­ dụng địa chỉ IP "
5224"của giao diện mạng chính."
5225
5226#: contrib/config-daemon.scm:967 contrib/config-daemon.scm:1222
5227msgid "Which IPv6s are not allowed to connect?"
5228msgstr "Những địa chỉ IPv6 nào không có quyá»n kết nối?"
5229
5230#: contrib/config-daemon.scm:979 contrib/config-daemon.scm:1234
5231msgid ""
5232"Which IPv6s are allowed to connect? Leave empty to allow any IP to connect."
5233msgstr ""
5234"Những địa chỉ IPv6 nào có quyá»n kết nối? Bá» trống để cho phép má»i địa chỉ IP "
5235"kết nối."
5236
5237#: contrib/config-daemon.scm:992
5238msgid "TCP transport"
5239msgstr "CÆ¡ chế truyá»n TCP"
5240
5241#: contrib/config-daemon.scm:1012
5242msgid "Which port should be used by the HTTP transport?"
5243msgstr "CÆ¡ chế truyá»n HTTP nên dùng cổng nào?"
5244
5245#: contrib/config-daemon.scm:1036
5246msgid "Which is the external port of the HTTP transport?"
5247msgstr "CÆ¡ chế truyá»n HTTP dùng cổng bên ngoài nào?"
5248
5249#: contrib/config-daemon.scm:1037
5250msgid ""
5251"Use this option if your firewall maps, say, port 80 to your real HTTP port. "
5252"This can be useful in making the HTTP messages appear even more legit "
5253"(without needing to run gnunetd as root due to the use of a privileged port)."
5254msgstr ""
5255"Hãy bật tùy chá»n này nếu bức tÆ°á»ng lá»­a ánh xạ, v.d. cổng 80 vá»›i cổng HTTP "
5256"thật. Có thể hữu ích để làm cho các thông điệp HTTP hình như ngay cả chính "
5257"đáng hÆ¡n (mà không cần chạy gnunetd dÆ°á»›i ngÆ°á»i chủ do dùng má»™t cổng có quyá»n "
5258"đặc biệt)."
5259
5260#: contrib/config-daemon.scm:1048
5261msgid "HTTP transport"
5262msgstr "CÆ¡ chế truyá»n HTTP"
5263
5264#: contrib/config-daemon.scm:1067
5265msgid "What is the maximum transfer unit for SMTP?"
5266msgstr "Äối vá»›i SMTP, Ä‘Æ¡n vị truyá»n tối Ä‘a là gì?"
5267
5268#: contrib/config-daemon.scm:1079
5269msgid ""
5270"What is the maximum number of e-mails that gnunetd would be allowed to send "
5271"per hour?"
5272msgstr "gnunetd có quyá»n gá»­i má»—i giá» bao nhiêu thÆ° Ä‘iện tá»­ (tối Ä‘a)?"
5273
5274#: contrib/config-daemon.scm:1080
5275msgid "Use 0 for unlimited"
5276msgstr "0 = vô hạn"
5277
5278#: contrib/config-daemon.scm:1091
5279msgid "Which e-mail address should be used to send e-mail to this peer?"
5280msgstr "Äể gá»­i thÆ° cho đồng đẳng này, có nên dùng địa chỉ thÆ° Ä‘iện tá»­ nào?"
5281
5282#: contrib/config-daemon.scm:1092
5283msgid ""
5284"You must make sure that e-mail received at this address is forwarded to the "
5285"PIPE which is read by gnunetd. Use the FILTER option to filter e-mail with "
5286"procmail and the PIPE option to set the name of the pipe."
5287msgstr ""
5288"Bạn cần phải đảm bảo rằng thư điện tử được nhận ở địa chỉ này thật được "
5289"chuyển tiếp tá»›i PIPE (ống dẫn) được gnunetd Ä‘á»c. Hãy dùng tùy chá»n FILTER "
5290"(lá»c) để lá»c thÆ° bằng procmail, và tùy chá»n PIPE để đặt tên của ống dẫn."
5291
5292#: contrib/config-daemon.scm:1103
5293msgid ""
5294"Which header line should other peers include in e-mails to enable filtering?"
5295msgstr "Äể hiệu lá»±c lá»c thÆ°, đồng đẳng khác nên ghi dòng đầu nào?"
5296
5297#: contrib/config-daemon.scm:1104
5298msgid ""
5299"You can specify a header line here which can then be used by procmail to "
5300"filter GNUnet e-mail from your inbox and forward it to gnunetd."
5301msgstr ""
5302"Ở đây thì bạn có dịp ghi rõ má»™t dòng đầu cho procmail dùng để lá»c thÆ° GNUnet "
5303"từ há»™p ThÆ° Äến của bạn và chuyển tiếp nó tá»›i gnunetd."
5304
5305#: contrib/config-daemon.scm:1115
5306msgid "What is the filename of the pipe where gnunetd can read its e-mail?"
5307msgstr "gnunetd có thể Ä‘á»c thÆ° qua ống dẫn có tên tập tin nào?"
5308
5309#: contrib/config-daemon.scm:1116
5310msgid "Have a look at contrib/dot-procmailrc for an example .procmailrc file."
5311msgstr "Xem « contrib/dot-procmailrc » để tìm một tập tin .procmailrc ví dụ."
5312
5313#: contrib/config-daemon.scm:1127
5314msgid "What is the name and port of the server for outgoing e-mail?"
5315msgstr "Máy phục vụ thư gửi ra có tên và cổng nào?"
5316
5317#: contrib/config-daemon.scm:1128
5318msgid "The basic format is HOSTNAME:PORT."
5319msgstr "Äịnh dạng cÆ¡ bản là « TÊN_MÃY:Cá»”NG »."
5320
5321#: contrib/config-daemon.scm:1139
5322msgid "SMTP transport"
5323msgstr "Cơ chế SMTP"
5324
5325#: contrib/config-daemon.scm:1162
5326msgid "Which port should be used by the UDP IPv4 transport?"
5327msgstr "CÆ¡ chế truyá»n IPv4 UDP nên dùng cổng nào?"
5328
5329#: contrib/config-daemon.scm:1186
5330msgid "What is the maximum transfer unit for UDP?"
5331msgstr "Äối vá»›i UDP, Ä‘Æ¡n vị truyá»n tối Ä‘a là gì?"
5332
5333#: contrib/config-daemon.scm:1198
5334msgid "Which IPs are not allowed to connect?"
5335msgstr "Những địa chỉ IP nào không có quyá»n kết nối?"
5336
5337#: contrib/config-daemon.scm:1210
5338msgid ""
5339"Which IPs are allowed to connect? Leave empty to allow connections from any "
5340"IP."
5341msgstr ""
5342"Những địa chỉ IP nào có quyá»n kết nối? Bá» trống để cho phép kết nối từ má»i "
5343"địa chỉ IP."
5344
5345#: contrib/config-daemon.scm:1246
5346msgid "UDP transport"
5347msgstr "CÆ¡ chế truyá»n UDP"
5348
5349#: contrib/config-daemon.scm:1268
5350msgid "Network interface"
5351msgstr "Giao diện mạng"
5352
5353#: contrib/config-daemon.scm:1280
5354msgid "External IP address (leave empty to try auto-detection)"
5355msgstr "Äịa chỉ IP bên ngoài (bá» trống để thá»­ tá»± Ä‘á»™ng phát hiện)"
5356
5357#: contrib/config-daemon.scm:1292
5358msgid "External IPv6 address (leave empty to try auto-detection)"
5359msgstr "Äịa chỉ IPv6 bên ngoài (bá» trống để thá»­ tá»± Ä‘á»™ng phát hiện)"
5360
5361#: contrib/config-daemon.scm:1304
5362msgid "Transports"
5363msgstr "CÆ¡ chế truyá»n"
5364
5365#: contrib/config-daemon.scm:1326
5366msgid "What is the maximum number of bytes per second that we may receive?"
5367msgstr "Có thể nhận bao nhiêu byte mỗi giây (tối đa)?"
5368
5369#: contrib/config-daemon.scm:1338
5370msgid "What is the maximum number of bytes per second that we may send?"
5371msgstr "Có thể gửi bao nhiêu byte mỗi giây (tối đa)?"
5372
5373#: contrib/config-daemon.scm:1350
5374msgid "What is the maximum CPU load (percentage)?"
5375msgstr "Tải trá»ng CPU tối Ä‘a là gì (theo phần trăm)?"
5376
5377#: contrib/config-daemon.scm:1351
5378msgid ""
5379"The highest tolerable CPU load. Load here always refers to the total system "
5380"load, that is it includes CPU utilization by other processes. A value of 50 "
5381"means that once your 1 minute-load average goes over 50% non-idle, GNUnet "
5382"will try to reduce CPU consumption until the load goes under the threshold. "
5383"Reasonable values are typically between 50 and 100. Multiprocessors may use "
5384"values above 100."
5385msgstr ""
5386"Tải trá»ng CPU cao nhất có thể. Ở đây thì tải trá»ng tham chiếu đến tổng số "
5387"tải trá»ng hệ thống, tức là nó cÅ©ng tính sá»­ dụng CPU của các tiến trình khác. "
5388"Giá trị 50 có nghÄ©a là má»™t khi tải trá»ng trung bình má»—i phút vượt quá 50% "
5389"không nghỉ, thì GNUnet thá»­ giảm sá»­ dụng CPU đến khi tải trá»ng nhá» hÆ¡n "
5390"ngưỡng. Giá trị hợp lý thÆ°á»ng nằm giữa 50 và 100. Máy Ä‘a bá»™ xá»­ lý có khả "
5391"năng sử dụng giá trị hơn 100."
5392
5393#: contrib/config-daemon.scm:1362
5394msgid "What is the maximum IO load (permille)?"
5395msgstr "Tải trá»ng VR tối Ä‘a là gì (theo phần nghìn)?"
5396
5397#: contrib/config-daemon.scm:1364
5398msgid ""
5399"The highest tolerable IO load. Load here refers to the percentage of CPU "
5400"cycles wasted waiting for IO for the entire system, that is it includes disk "
5401"utilization by other processes. A value of 10 means that once the average "
5402"number of cycles wasted waiting for IO is more than 10% non-idle, GNUnet "
5403"will try to reduce IO until the load goes under the threshold. Reasonable "
5404"values are typically between 10 and 75."
5405msgstr ""
5406"Tải trá»ng VR cao nhất có thể tha thứ được. Ở đây thì tải trá»ng tham chiếu "
5407"đến tỷ lệ phần trăm chu kỳ CPU bị phí khi đợi VR đối với toàn hệ thống, tức "
5408"là nó cũng tính sử dụng đĩa của các tiến trình khác. Giá trị 10 có nghĩa là "
5409"một khi số các chu kỳ trung bình bị phí khi đợi VR hơn 10% không nghỉ, "
5410"GNUnet sẽ thá»­ giảm VR đến khi tải trá»ng nhá» hÆ¡n ngưỡng. Giá trị hợp lý "
5411"thÆ°á»ng nằm giữa 10 và 75."
5412
5413#: contrib/config-daemon.scm:1375
5414msgid "What is the maximum CPU load (hard limit)?"
5415msgstr "Tải trá»ng CPU tối Ä‘a là gì (giá»›i hạn cứng)?"
5416
5417#: contrib/config-daemon.scm:1376
5418msgid ""
5419"The highest tolerable CPU load. This is the hard limit, so once it is "
5420"reached, gnunetd will start to massively drop data to reduce the load. Use "
5421"with caution."
5422msgstr ""
5423"Tải trá»ng CPU cao nhất có thể tha thứ được. Äây là giá»›i hạn cứng, do đó má»™t "
5424"khi tá»›i được, gnunetd sẽ bắt đầu bá» rất nhiá»u dữ liệu để giảm tải trá»ng. Hãy "
5425"sử dụng cẩn thận."
5426
5427#: contrib/config-daemon.scm:1387
5428msgid "What is the maximum upstream bandwidth (hard limit)?"
5429msgstr "Băng thông dòng ra tối đa là gì (giới hạn cứng)?"
5430
5431#: contrib/config-daemon.scm:1388
5432msgid ""
5433"The limit is given as a percentage of the MAXNETUPBPS limit. Use 100 to "
5434"have MAXNETUPBPS be the hard limit. Use zero for no limit."
5435msgstr ""
5436"Giới hạn được ghi rõ theo phần trăm của giới hạn MAXNETUPBPS. Dùng 100 để "
5437"đặt MAXNETUPBPS là giới hạn cứng. 0 = vô hạn."
5438
5439#: contrib/config-daemon.scm:1400
5440#, fuzzy
5441msgid "What priority should gnunetd use to run?"
5442msgstr "gnunetd nên chạy như nhóm nào?"
5443
5444#: contrib/config-daemon.scm:1401
5445msgid ""
5446"You can specify priorities like NORMAL, ABOVE NORMAL, BELOW NORMAL, HIGH and "
5447"IDLE or a numerical integer value (man nice). The default is IDLE, which "
5448"should result in gnunetd only using resources that would otherwise be idle."
5449msgstr ""
5450
5451#: contrib/config-daemon.scm:1413
5452msgid "Should we disable random padding (experimental option)?"
5453msgstr "Có nên tắt đệm ngẫu nhiên (tùy chá»n vẫn thá»±c nghiệm) không?"
5454
5455#: contrib/config-daemon.scm:1425
5456msgid "Use basic bandwidth limitation? (YES/NO). If in doubt, say YES."
5457msgstr ""
5458"Äặt giá»›i hạn băng thông cÆ¡ bản không? (YES/NO) ChÆ°a chắc thì đặt YES (có)."
5459
5460#: contrib/config-daemon.scm:1427
5461msgid ""
5462"Basic bandwidth limitation (YES) means simply that the bandwidth limits "
5463"specified apply to GNUnet and only to GNUnet. If set to YES, you simply "
5464"specify the maximum bandwidth (upstream and downstream) that GNUnet is "
5465"allowed to use and GNUnet will stick to those limitations. This is useful "
5466"if your overall bandwidth is so large that the limit is mostly used to "
5467"ensure that enough capacity is left for other applications. Even if you "
5468"want to dedicate your entire connection to GNUnet you should not set the "
5469"limits to values higher than what you have since GNUnet uses those limits to "
5470"determine for example the number of connections to establish (and it would "
5471"be inefficient if that computation yields a number that is far too high). \n"
5472"\n"
5473"While basic bandwidth limitation is simple and always works, there are some "
5474"situations where it is not perfect. Suppose you are running another "
5475"application which performs a larger download. During that particular time, "
5476"it would be nice if GNUnet would throttle its bandwidth consumption "
5477"(automatically) and resume using more bandwidth after the download is "
5478"complete. This is obviously advanced magic since GNUnet will have to "
5479"monitor the behavior of other applications. Another scenario is a monthly "
5480"cap on bandwidth imposed by your ISP, which you would want to ensure is "
5481"obeyed. Here, you may want GNUnet to monitor the traffic from other "
5482"applications to ensure that the combined long-term traffic is within the pre-"
5483"set bounds. Note that you should probably not set the bounds tightly since "
5484"GNUnet may observe that the bounds are about to be broken but would be "
5485"unable to stop other applications from continuing to use bandwidth.\n"
5486"\n"
5487"If either of these two scenarios applies, set BASICLIMITING to NO. Then set "
5488"the bandwidth limits to the COMBINED amount of traffic that is acceptable "
5489"for both GNUnet and other applications. GNUnet will then immediately "
5490"throttle bandwidth consumption if the short-term average is above the limit, "
5491"and it will also try to ensure that the long-term average is below the "
5492"limit. Note however that using NO can have the effect of GNUnet (almost) "
5493"ceasing operations after other applications perform high-volume downloads "
5494"that are beyond the defined limits. GNUnet would reduce consumption until "
5495"the long-term limits are again within bounds.\n"
5496"\n"
5497"NO only works on platforms where GNUnet can monitor the amount of traffic "
5498"that the local host puts out on the network. This is only implemented for "
5499"Linux and Win32. In order for the code to work, GNUnet needs to know the "
5500"specific network interface that is used for the external connection (after "
5501"all, the amount of traffic on loopback or on the LAN should never be counted "
5502"since it is irrelevant)."
5503msgstr ""
5504"Giới hạn băng thông cơ bản (YES) có nghĩa đơn giản là mỗi giới hạn băng "
5505"thông đưa ra chỉ áp dụng cho GNUnet. Nếu đặt thành YES (có) thì bạn đơn giản "
5506"chỉ ghi rõ băng thông tối đa (dòng ra và dòng vào) cho phép GNUnet dùng, và "
5507"GNUnet sẽ tuân theo những giới hạn đó. Có ích nếu băng thông toàn bộ lớn quá "
5508"đến mức là giá»›i hạn thÆ°á»ng dùng để đảm bảo đủ khả năng còn lại cho các ứng "
5509"dụng khác. Thậm chí nếu bạn muốn dành kết nối hoàn toàn cho GNUnet, không "
5510"nên đặt giới hạn thành giá trị cao hơn khả năng, vì GNUnet dùng giới hạn đó "
5511"để quyết định, ví dụ, số các kết nối nên thiết lập (không có hiệu quả nếu "
5512"phép tính có kết quả là quá lớn).\n"
5513"\n"
5514"Dù chức năng hạn chế băng thông cơ bản vẫn đơn giản và lúc nào cũng hoạt "
5515"Ä‘á»™ng được, trong má»™t số trÆ°á»ng hợp nào đó nó không phải hoàn toàn. Giả sá»­ "
5516"bạn đang chạy một ứng dụng khác mà thực hiện một công việc tải xuống lớn "
5517"hơn. Trong khi làm công việc đó, có ích nếu GNUnet giảm tiêu thụ băng thông "
5518"(một cách tự động), cũng tăng lại một khi công việc tải xuống đó đã chạy "
5519"xong. Chức năng này thực sự phức tạp, vì GNUnet phải theo dõi ứng xử của các "
5520"ứng dụng khác. Má»™t trÆ°á»ng hợp khác là má»™t ngưỡng băng thông hàng tháng được "
5521"nhà cung cấp dịch vụ Internet (ISP) Ä‘iá»u khiển: bạn muốn đảm bảo tuân theo "
5522"nó. Trong trÆ°á»ng hợp đó, bạn có thể muốn theo dõi tải cho mạng từ các ứng "
5523"dụng khác để đảm bảo rằng tổng số tải trá»ng lâu dài nằm dÆ°á»›i ngưỡng định "
5524"sẵn. Ghi chú rằng không nên đặt ngưỡng quá chặt chẽ vì GNUnet có thể phát "
5525"hiện ngưỡng sắp bị vượt quá nhưng không thể ngăn cản ứng dụng khác tiếp tục "
5526"chiếm băng thông.\n"
5527"\n"
5528"Nếu có má»™t của hai trÆ°á»ng hợp này, hãy đặt BASICLIMITING thành NO (không). "
5529"Sau đó thì đặt giá»›i hạn băng thông thành Tá»”NG Sá» tải trá»ng thoả đáng cho cả "
5530"hai GNUnet và ứng dụng khác. GNUnet thì giảm ngay tiêu thụ băng thông nếu "
5531"trung bình ngắn kỳ hơn giới hạn, nó cũng thử đảm bảo rằng trung bình lâu dài "
5532"dưới giới hạn. Tuy nhiên, ghi chú rằng việc đặt NO (không) có kết quả có thể "
5533"là GNUnet gần dừng hoạt động sau khi ứng dụng khác chạy công việc lớn mà "
5534"vượt quá giới hạn đã xác định. Lúc đó, GNUnet sẽ giảm tiêu thụ đến khi giới "
5535"hạn lâu dài lại nằm trong phạm vi đưa ra.\n"
5536"\n"
5537"Giá trị NO chỉ hoạt Ä‘á»™ng được trên ná»n tảng thích hợp vá»›i GNUnet theo dõi "
5538"tải cho mạng được máy cục bộ gửi. Chức năng này chỉ được thực hiện cho Linux "
5539"và Win32. Äể mà mã hoạt Ä‘á»™ng được, GNUnet cần biết giao diện mạng dứt khoát "
5540"dùng cho kết nối bên ngoài (thôi, lượng tải trá»ng trên mạch ná»™i bá»™ hay LAN "
5541"không bao giỠnên được đếm vì nó không thích đáng). "
5542
5543#: contrib/config-daemon.scm:1444
5544msgid "Network interface to monitor"
5545msgstr "Giao diện mạng cần theo dõi"
5546
5547#: contrib/config-daemon.scm:1445
5548msgid ""
5549"For which interfaces should we do accounting? GNUnet will evaluate the "
5550"total traffic (not only the GNUnet related traffic) and adjust its bandwidth "
5551"usage accordingly. You can currently only specify a single interface. GNUnet "
5552"will also use this interface to determine the IP to use. Typical values are "
5553"eth0, ppp0, eth1, wlan0, etc. 'ifconfig' will tell you what you have. "
5554"Never use 'lo', that just won't work. Under Windows, specify the index "
5555"number reported by 'gnunet-win-tool -n'."
5556msgstr ""
5557"Có nên tính đến những giao diện nào? GNUnet sẽ định giá tổng số tải trá»ng "
5558"(không phải chỉ tải trá»ng liên quan đến GNUnet) và Ä‘iá»u chỉnh sá»­ dụng băng "
5559"thông má»™t cách thích hợp. Hiện thá»i ngÆ°á»i dùng chỉ có thể ghi rõ má»™t giao "
5560"diện riêng lẻ. GNUnet sẽ cũng sử dụng giao doện này để quyết định địa chỉ IP "
5561"cần dùng. Giá trị thÆ°á»ng dùng: eth0, ppp0, eth1, wlan0, v.v. Lệnh « ifconfig "
5562"» sẽ hiển thị những giao diện sẵn sàng. Không bao giỠnên dùng « lo » vì nó "
5563"không hoạt động được. Dưới Windows, hãy ghi rõ số chỉ mục trả lại bởi câu "
5564"lệnh « gnunet-win-tool -n »."
5565
5566#: contrib/config-daemon.scm:1456
5567msgid "Load management"
5568msgstr "Quản lý tải trá»ng"
5569
5570#: contrib/config-daemon.scm:1482 contrib/config-client.scm:413
5571msgid "Root node"
5572msgstr "Nút gốc"
5573
5574#: contrib/config-client.scm:153
5575msgid "Where should gnunet-clients write their logs?"
5576msgstr "Ứng dụng khách gnunet-clients nên ghi sổ theo dõi vào đâu?"
5577
5578#: contrib/config-client.scm:185
5579msgid "On which machine and port is gnunetd running (for clients)?"
5580msgstr "gnunetd đang chạy trên máy và cổng nào (cho ứng dụng khách)?"
5581
5582#: contrib/config-client.scm:186
5583msgid "This is equivalent to the -H option. The format is IP:PORT."
5584msgstr "Äây tÆ°Æ¡ng Ä‘Æ°Æ¡ng vá»›i tùy chá»n « -H ». Äịnh dạng là « IP:Cá»”NG »."
5585
5586#: contrib/config-client.scm:197
5587msgid "What is the path to the configuration file for gnunetd?"
5588msgstr "Tập tin cấu hình gnunetd có Ä‘Æ°á»ng dẫn nào?"
5589
5590#: contrib/config-client.scm:198
5591msgid "This option is used when clients need to start gnunetd."
5592msgstr "Tùy chá»n này dùng khi ứng dụng khách cần khởi chạy gnunetd."
5593
5594#: contrib/config-client.scm:210
5595msgid "General options"
5596msgstr "Tùy chá»n chung"
5597
5598#: contrib/config-client.scm:227
5599msgid "Do not add metadata listing the creation time for inserted content"
5600msgstr ""
5601"Không nên thêm siêu dữ liệu mà ghi nhớ giỠtạo của nội dung được chèn vào"
5602
5603#: contrib/config-client.scm:239
5604msgid "Which non-default extractors should GNUnet use for keyword extractors"
5605msgstr ""
5606"Äối vá»›i bá»™ trích khác từ khoá, GNUnet nên dùng những bá»™ trích khác mặc định "
5607"nào?"
5608
5609#: contrib/config-client.scm:240
5610msgid ""
5611"Specify which additional extractor libraries should be used. gnunet-insert "
5612"uses libextractor to extract keywords from files. libextractor can be "
5613"dynamically extended to handle additional file formats. If you want to use "
5614"more than the default set of extractors, specify additional extractor "
5615"libraries here. The format is [[-]LIBRARYNAME[:[-]LIBRARYNAME]*].\n"
5616"\n"
5617"The default is to use filenames and to break larger words at spaces (and "
5618"underscores, etc.). This should be just fine for most people. The '-' "
5619"before a library name indicates that this should be executed last and makes "
5620"only sense for the split-library."
5621msgstr ""
5622"Ghi rõ những thư viện trích bổ sung nào nên dùng. Tiến trình chèn gnunet-"
5623"insert sá»­ dụng libextractor để trích các từ khoá khá»i tập tin. libextractor "
5624"cũng có thể mở rộng động để quản lý định dạng tập tin bổ sung. Muốn sử dụng "
5625"bộ trích bên ngoài tập hợp mặc định thì ghi rõ ở đây những thư viện trích bổ "
5626"sung. Äịnh dạng là « [[-]tên_thÆ°_viện[:[-]tên_thÆ°_viện]*] ».\n"
5627"\n"
5628"Mặc định là dùng tên tập tin, và ngắt từ lớn ở dấu cách, dấu gạch dưới v.v. "
5629"Äây nên ổn cho phần lá»›n ngÆ°á»i dùng. Dấu gạch nối « - » đằng trÆ°á»›c má»™t tên thÆ° "
5630"viện có ngụ ý nó nên được thực hiện cuối cùng, thích hợp chỉ cho split-"
5631"library."
5632
5633#: contrib/config-client.scm:253
5634msgid "How many entries should the URI DB table have?"
5635msgstr "Bảng DB URI nên chứa bao nhiêu mục nhập?"
5636
5637#: contrib/config-client.scm:254
5638msgid ""
5639"GNUnet uses two bytes per entry on the disk. This database is used to keep "
5640"track of how a particular URI has been used in the past. For example, "
5641"GNUnet may remember that a particular URI has been found in a search "
5642"previously or corresponds to a file uploaded by the user. This information "
5643"can then be used by user-interfaces to filter URI lists, such as search "
5644"results. If the database is full, older entries will be discarded. The "
5645"default value should be sufficient without causing undue disk utilization."
5646msgstr ""
5647"GNUnet dùng hai byte cho mỗi mục nhập trên đĩa. Cơ sở dữ liệu này dùng để "
5648"theo dõi một URI nào đó đã được sử dụng như thế nào. Ví dụ, GNUnet có thể "
5649"nhớ rằng một URI nào đó đã được phát hiện bằng một công việc tìm kiếm trước, "
5650"hay tÆ°Æ¡ng ứng vá»›i má»™t tập tin được ngÆ°á»i dùng tải lên. Thông tin này thì có "
5651"thể được dùng bởi giao diện ngÆ°á»i dùng để lá»c danh sách các URI, nhÆ° kết quả "
5652"tìm kiếm. Nếu cơ sở dữ liệu bị đầy thì hủy các mục nhập cũ. Giá trị mặc định "
5653"nên ổn mà không gây ra sử dụng đĩa một cách quá chừng."
5654
5655#: contrib/config-client.scm:265
5656msgid "Location of the file specifying metadata for the auto-share directory"
5657msgstr "Vị trí của tập tin ghi rõ siêu dữ liệu cho thư mục tự động chia sẻ"
5658
5659#: contrib/config-client.scm:277
5660msgid ""
5661"Location of the file with the PID of any running gnunet-auto-share daemon "
5662"process"
5663msgstr ""
5664"Vị trí của tập tin chứa PID của bất kỳ tiến trình ná»n gnunet-auto-share"
5665
5666#: contrib/config-client.scm:289
5667msgid "Location of the log file for gnunet-auto-share"
5668msgstr "Vị trí của tập tin theo dõi cho gnunet-auto-share"
5669
5670#: contrib/config-client.scm:301
5671msgid "File-Sharing options"
5672msgstr "Tùy chá»n chia sẻ tập tin"
5673
5674#: contrib/config-client.scm:319
5675msgid "Which plugins should be loaded by gnunet-gtk?"
5676msgstr "gnunet-gtk nên nạp những phần bổ sung nào?"
5677
5678#: contrib/config-client.scm:320
5679msgid ""
5680"Load the about plugin for the about dialog. The daemon plugin allows "
5681"starting and stopping of gnunetd and displays information about gnunetd. "
5682"The fs plugin provides the file-sharing functionality. The stats plugin "
5683"displays various statistics about gnunetd."
5684msgstr ""
5685"Nạp phần bổ sung about cho hộp thoại giới thiệu. Phần bổ sung daemon cho "
5686"phép khởi chạy và dừng chạy trình ná»n gnunetd, và hiển thị thông tin vá» "
5687"gnunetd. Phần bổ sung fs cung cấp chức năng chia sẻ tập tin. Phần bổ sung "
5688"stats hiển thị thống kê khác nhau vỠgnunetd."
5689
5690#: contrib/config-client.scm:331
5691msgid "How frequently (in milli-seconds) should the statistics update?"
5692msgstr "Thống kê có nên cập nhật thÆ°á»ng xuyên cỡ nào (theo mili-giây)?"
5693
5694#: contrib/config-client.scm:332
5695msgid ""
5696"Each pixel in the stats dialog corresponds to the time interval specified "
5697"here."
5698msgstr ""
5699"Má»—i Ä‘iểm ảnh trong há»™p thoại thống kê thì tÆ°Æ¡ng ứng vá»›i khoảng thá»i gian Ä‘Æ°a "
5700"ra ở đây."
5701
5702#: contrib/config-client.scm:344
5703msgid "Do not show thumbnail previews from meta-data in search results"
5704msgstr ""
5705"Không hiển thị ô xem thử ảnh mẫu từ siêu dữ liệu trong kết quả tìm kiếm"
5706
5707#: contrib/config-client.scm:345
5708msgid ""
5709"This option is useful for people who maybe offended by some previews or use "
5710"gnunet-gtk at work and would like to avoid bad surprises."
5711msgstr ""
5712"Tùy chá»n này có ích cho ngÆ°á»i dùng không thích má»™t số ô xem thá»­, hoặc sá»­ "
5713"dụng gnunet-gtk ở chỗ làm và muốn tránh sự ngạc nhiên xấu."
5714
5715#: contrib/config-client.scm:356
5716msgid "Do not show search results for files that were uploaded by us"
5717msgstr "Không hiển thị kết quả tìm kiếm cho tập tin được chúng ta tải lên"
5718
5719#: contrib/config-client.scm:357
5720msgid ""
5721"This option is useful to eliminate files that the user already has from the "
5722"search. Naturally, enabling this option maybe confusing because some "
5723"obviously expected search results would no longer show up. This option only "
5724"works if the URI_DB_SIZE option under FS is not zero (since the URI DB is "
5725"used to determine which files the user is sharing)"
5726msgstr ""
5727"Tùy chá»n này có ích để loại ra việc tìm kiếm những tập tin đã có trên máy "
5728"đó. Tất nhiên, bật tùy chá»n có thể gây ra bối rối vì má»™t số kết quả tìm kiếm "
5729"mong đợi sẽ không được hiển thị. Tùy chá»n này chỉ hoạt Ä‘á»™ng được nếu tùy "
5730"chá»n URI_DB_SIZE (kích cỡ cÆ¡ sở dữ liệu URI) dÆ°á»›i FS khác số không (vì cÆ¡ sở "
5731"dữ liệu URI được dùng để quyết định những tập tin được ngÆ°á»i dùng chia sẻ)"
5732
5733#: contrib/config-client.scm:369
5734msgid "To which directory should gnunet-gtk save downloads to?"
5735msgstr "gnunet-gtk nên lưu tập tin tải vỠvào thư mục nào?"
5736
5737#: contrib/config-client.scm:381
5738msgid "Options related to gnunet-gtk"
5739msgstr "Tùy chá»n liên quan đến gnunet-gtk"
5740
5741#: contrib/config-client.scm:401
5742msgid "Full pathname of GNUnet client HOME directory"
5743msgstr "Tên Ä‘Æ°á»ng dẫn đầy đủ đến thÆ° mục HOME khách GNUnet"
5744
5745#: contrib/config-client.scm:402
5746msgid "The directory for GNUnet files that belong to the user."
5747msgstr "ThÆ° mục chứa những tập tin GNUnet mà thuá»™c vá» ngÆ°á»i dùng."
5748
5749#~ msgid "Setting option `%s' in section `%s' to value `%s' was refused.\n"
5750#~ msgstr "Bị từ chối đặt tùy chá»n « %s » trong phần « %s » thành « %s ».\n"
5751
5752#~ msgid "`%s' failed at %s:%d with error: %s"
5753#~ msgstr "« %s » bị lỗi tại %s:%d với lỗi: %s"
5754
5755#~ msgid "`%s' failed at %s:%d with error `%s' after %llums\n"
5756#~ msgstr "« %s » bị lỗi tại %s:%d với lỗi:« %s » đẳng sau %llu miligiây\n"
5757
5758#~ msgid "Trying to use file `%s' for MySQL configuration.\n"
5759#~ msgstr "Äang thá»­ dùng tập tin « %s » cho cấu hình MySQL.\n"
5760
5761#~ msgid ""
5762#~ "Directory `%s' in directory `%s' does not match naming convention. "
5763#~ "Removed.\n"
5764#~ msgstr ""
5765#~ "Thư mục « %s » trong thư mục « %s » không tùy theo quy ước đặt tên. Bị gỡ "
5766#~ "bá».\n"
5767
5768#~ msgid "File `%s' does not contain a pseudonym, trying to remove.\n"
5769#~ msgstr "Tập tin « %s » không chứa biệt hiệu nên thá»­ gỡ bá».\n"
5770
5771#~ msgid "Format of file `%s' is invalid.\n"
5772#~ msgstr "Äịnh dạng của tập tin « %s » là không hợp lệ.\n"
diff --git a/pre-commit b/pre-commit
new file mode 100755
index 000000000..b733c44fa
--- /dev/null
+++ b/pre-commit
@@ -0,0 +1,17 @@
1#!/bin/sh
2# NOTE: "touch mydir/no-indent" to make the tree starting at mydir untouchable
3l=""
4for n in `find . -name "no-indent"`
5do
6 n=`dirname "$n"`
7 l="-and -not -path \"$n/*\" $l"
8done
9indent -nut `echo $l | xargs find . -name "*.c"`
10indent -nut `echo $l | xargs find . -name "*.h"`
11if test -x "`which 'dos2unix'`"
12then
13 dos2unix -ko `echo $l | xargs find . -name "*.c"`
14 dos2unix -ko `echo $l | xargs find . -name "*.h"`
15 rm `echo $l | xargs find . -name "*.?~"`
16fi
17
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 000000000..c8852ad04
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,17 @@
1#if WANT_FRAMEWORK
2# INTLEMU_SUBDIRS = intlemu
3#endif
4
5SUBDIRS = \
6 include $(INTLEMU_SUBDIRS) \
7 util \
8 arm \
9 fragmentation \
10 hello \
11 peerinfo \
12 resolver \
13 statistics \
14 template \
15 transport \
16 core
17
diff --git a/src/arm/Makefile.am b/src/arm/Makefile.am
new file mode 100644
index 000000000..65fa145ee
--- /dev/null
+++ b/src/arm/Makefile.am
@@ -0,0 +1,58 @@
1INCLUDES = -I$(top_srcdir)/src/include
2
3if MINGW
4 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
5endif
6
7if USE_COVERAGE
8 AM_CFLAGS = -fprofile-arcs -ftest-coverage
9endif
10
11lib_LTLIBRARIES = libgnunetarm.la
12
13libgnunetarm_la_SOURCES = \
14 arm_api.c arm.h
15libgnunetarm_la_LIBADD = \
16 $(top_builddir)/src/util/libgnunetutil.la \
17 $(GN_LIBINTL)
18libgnunetarm_la_LDFLAGS = \
19 $(GN_LIB_LDFLAGS) $(WINFLAGS) \
20 -version-info 0:0:0
21
22
23bin_PROGRAMS = \
24 gnunet-arm \
25 gnunet-service-arm
26
27gnunet_arm_SOURCES = \
28 gnunet-arm.c
29gnunet_arm_LDADD = \
30 $(top_builddir)/src/arm/libgnunetarm.la \
31 $(top_builddir)/src/util/libgnunetutil.la \
32 $(GN_LIBINTL)
33
34gnunet_service_arm_SOURCES = \
35 gnunet-service-arm.c
36gnunet_service_arm_LDADD = \
37 $(top_builddir)/src/util/libgnunetutil.la \
38 $(GN_LIBINTL)
39
40
41check_PROGRAMS = \
42 test_arm_api
43
44check_SCRIPTS = \
45 test_gnunet_arm.sh
46
47TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
48
49test_arm_api_SOURCES = \
50 test_arm_api.c
51test_arm_api_LDADD = \
52 $(top_builddir)/src/arm/libgnunetarm.la \
53 $(top_builddir)/src/resolver/libgnunetresolver.la \
54 $(top_builddir)/src/util/libgnunetutil.la
55
56
57EXTRA_DIST = \
58 test_arm_api_data.conf
diff --git a/src/arm/arm.h b/src/arm/arm.h
new file mode 100644
index 000000000..2293ec036
--- /dev/null
+++ b/src/arm/arm.h
@@ -0,0 +1,32 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 * @author Christian Grothoff
23 * @file arm/arm.h
24 */
25#ifndef ARM_H
26#define ARM_H
27
28#include "gnunet_common.h"
29
30#define DEBUG_ARM GNUNET_NO
31
32#endif
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c
new file mode 100644
index 000000000..c5bb15fd3
--- /dev/null
+++ b/src/arm/arm_api.c
@@ -0,0 +1,337 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 arm/arm_api.c
23 * @brief API for accessing the ARM service
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_arm_service.h"
28#include "gnunet_client_lib.h"
29#include "gnunet_getopt_lib.h"
30#include "gnunet_os_lib.h"
31#include "gnunet_protocols.h"
32#include "gnunet_server_lib.h"
33#include "arm.h"
34
35
36struct ArmContext
37{
38 GNUNET_ARM_Callback callback;
39 void *cls;
40 char *service_name;
41 struct GNUNET_CLIENT_Connection *client;
42 struct GNUNET_CONFIGURATION_Handle *cfg;
43 struct GNUNET_TIME_Absolute timeout;
44 uint16_t type;
45};
46
47
48static void
49arm_service_report (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
50{
51 struct ArmContext *pos = cls;
52 pid_t pid;
53 char *binary;
54 char *config;
55
56 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
57 {
58 if (pos->callback != NULL)
59 pos->callback (pos->cls, GNUNET_YES);
60 GNUNET_free (pos);
61 return;
62 }
63 binary = NULL;
64 config = NULL;
65 /* start service */
66 if ((GNUNET_OK !=
67 GNUNET_CONFIGURATION_get_value_filename (pos->cfg,
68 "arm",
69 "BINARY",
70 &binary)) ||
71 (GNUNET_OK !=
72 GNUNET_CONFIGURATION_get_value_filename (pos->cfg,
73 "arm", "CONFIG", &config)))
74 {
75 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
76 _("Configuration file or binary for ARM not known!\n"));
77 if (pos->callback != NULL)
78 pos->callback (pos->cls, GNUNET_SYSERR);
79 GNUNET_free_non_null (binary);
80 GNUNET_free (pos);
81 return;
82 }
83 pid = GNUNET_OS_start_process (binary, binary, "-d", "-c", config,
84#if DEBUG_ARM
85 "-L", "DEBUG",
86#endif
87 NULL);
88 GNUNET_free (binary);
89 GNUNET_free (config);
90 if (pid == -1)
91 {
92 if (pos->callback != NULL)
93 pos->callback (pos->cls, GNUNET_SYSERR);
94 GNUNET_free (pos);
95 return;
96 }
97 /* FIXME: consider checking again to see if it worked!? */
98 if (pos->callback != NULL)
99 pos->callback (pos->cls, GNUNET_YES);
100 GNUNET_free (pos);
101}
102
103
104static void
105handle_response (void *cls, const struct GNUNET_MessageHeader *msg)
106{
107 struct ArmContext *sc = cls;
108 int ret;
109
110 if (msg == NULL)
111 {
112 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
113 _("Error receiving response from ARM service\n"));
114 GNUNET_CLIENT_disconnect (sc->client);
115 if (sc->callback != NULL)
116 sc->callback (sc->cls, GNUNET_SYSERR);
117 GNUNET_free (sc);
118 return;
119 }
120#if DEBUG_ARM
121 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
122 _("Received response from ARM service\n"));
123#endif
124 switch (ntohs (msg->type))
125 {
126 case GNUNET_MESSAGE_TYPE_ARM_IS_UP:
127 ret = GNUNET_YES;
128 break;
129 case GNUNET_MESSAGE_TYPE_ARM_IS_DOWN:
130 ret = GNUNET_NO;
131 break;
132 default:
133 GNUNET_break (0);
134 ret = GNUNET_SYSERR;
135 }
136 GNUNET_CLIENT_disconnect (sc->client);
137 if (sc->callback != NULL)
138 sc->callback (sc->cls, ret);
139 GNUNET_free (sc);
140}
141
142
143static size_t
144send_service_msg (void *cls, size_t size, void *buf)
145{
146 struct ArmContext *sctx = cls;
147 struct GNUNET_MessageHeader *msg;
148 size_t slen;
149
150 if (buf == NULL)
151 {
152 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
153 _("Error while trying to transmit to ARM service\n"));
154 GNUNET_CLIENT_disconnect (sctx->client);
155 if (sctx->callback != NULL)
156 sctx->callback (sctx->cls, GNUNET_SYSERR);
157 GNUNET_free (sctx->service_name);
158 GNUNET_free (sctx);
159 return 0;
160 }
161#if DEBUG_ARM
162 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
163 _("Transmitting service request to ARM.\n"));
164#endif
165 slen = strlen (sctx->service_name) + 1;
166 GNUNET_assert (size >= slen);
167 msg = buf;
168 msg->size = htons (sizeof (struct GNUNET_MessageHeader) + slen);
169 msg->type = htons (sctx->type);
170 memcpy (&msg[1], sctx->service_name, slen);
171 GNUNET_free (sctx->service_name);
172 sctx->service_name = NULL;
173 GNUNET_CLIENT_receive (sctx->client,
174 &handle_response,
175 sctx,
176 GNUNET_TIME_absolute_get_remaining (sctx->timeout));
177 return slen + sizeof (struct GNUNET_MessageHeader);
178}
179
180
181/**
182 * Start or stop a service.
183 *
184 * @param service_name name of the service
185 * @param cfg configuration to use (needed to contact ARM;
186 * the ARM service may internally use a different
187 * configuration to determine how to start the service).
188 * @param sched scheduler to use
189 * @param timeout how long to wait before failing for good
190 * @param cb callback to invoke when service is ready
191 * @param cb_cls closure for callback
192 */
193static void
194change_service (const char *service_name,
195 struct GNUNET_CONFIGURATION_Handle *cfg,
196 struct GNUNET_SCHEDULER_Handle *sched,
197 struct GNUNET_TIME_Relative timeout,
198 GNUNET_ARM_Callback cb, void *cb_cls, uint16_t type)
199{
200 struct GNUNET_CLIENT_Connection *client;
201 struct ArmContext *sctx;
202 size_t slen;
203
204 slen = strlen (service_name) + 1;
205 if (slen + sizeof (struct GNUNET_MessageHeader) >
206 GNUNET_SERVER_MAX_MESSAGE_SIZE)
207 {
208 GNUNET_break (0);
209 if (cb != NULL)
210 cb (cb_cls, GNUNET_NO);
211 return;
212 }
213 client = GNUNET_CLIENT_connect (sched, "arm", cfg);
214 if (client == NULL)
215 {
216 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
217 _("Failed to connect to ARM service\n"));
218 if (cb != NULL)
219 cb (cb_cls, GNUNET_SYSERR);
220 return;
221 }
222#if DEBUG_ARM
223 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
224 _("ARM requests starting of service `%s'.\n"), service_name);
225#endif
226 sctx = GNUNET_malloc (sizeof (struct ArmContext));
227 sctx->callback = cb;
228 sctx->cls = cb_cls;
229 sctx->client = client;
230 sctx->service_name = GNUNET_strdup (service_name);
231 sctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
232 sctx->type = type;
233 if (NULL ==
234 GNUNET_CLIENT_notify_transmit_ready (client,
235 slen +
236 sizeof (struct
237 GNUNET_MessageHeader),
238 timeout, &send_service_msg, sctx))
239 {
240 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
241 _("Failed to transmit request to ARM service\n"));
242 GNUNET_free (sctx->service_name);
243 GNUNET_free (sctx);
244 if (cb != NULL)
245 cb (cb_cls, GNUNET_SYSERR);
246 GNUNET_CLIENT_disconnect (client);
247 return;
248 }
249}
250
251
252/**
253 * Start a service.
254 *
255 * @param service_name name of the service
256 * @param cfg configuration to use (needed to contact ARM;
257 * the ARM service may internally use a different
258 * configuration to determine how to start the service).
259 * @param sched scheduler to use
260 * @param timeout how long to wait before failing for good
261 * @param cb callback to invoke when service is ready
262 * @param cb_cls closure for callback
263 */
264void
265GNUNET_ARM_start_service (const char *service_name,
266 struct GNUNET_CONFIGURATION_Handle *cfg,
267 struct GNUNET_SCHEDULER_Handle *sched,
268 struct GNUNET_TIME_Relative timeout,
269 GNUNET_ARM_Callback cb, void *cb_cls)
270{
271 struct ArmContext *sctx;
272
273 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
274 _("Starting service `%s'\n"), service_name);
275 if (0 == strcmp ("arm", service_name))
276 {
277 sctx = GNUNET_malloc (sizeof (struct ArmContext));
278 sctx->callback = cb;
279 sctx->cls = cb_cls;
280 sctx->cfg = cfg;
281 GNUNET_CLIENT_service_test (sched,
282 "arm",
283 cfg, timeout, &arm_service_report, sctx);
284 return;
285 }
286 change_service (service_name,
287 cfg,
288 sched, timeout, cb, cb_cls, GNUNET_MESSAGE_TYPE_ARM_START);
289}
290
291
292
293
294/**
295 * Stop a service.
296 *
297 * @param service_name name of the service
298 * @param cfg configuration to use (needed to contact ARM;
299 * the ARM service may internally use a different
300 * configuration to determine how to start the service).
301 * @param sched scheduler to use
302 * @param timeout how long to wait before failing for good
303 * @param cb callback to invoke when service is ready
304 * @param cb_cls closure for callback
305 */
306void
307GNUNET_ARM_stop_service (const char *service_name,
308 struct GNUNET_CONFIGURATION_Handle *cfg,
309 struct GNUNET_SCHEDULER_Handle *sched,
310 struct GNUNET_TIME_Relative timeout,
311 GNUNET_ARM_Callback cb, void *cb_cls)
312{
313 struct GNUNET_CLIENT_Connection *client;
314
315 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
316 _("Stopping service `%s'\n"), service_name);
317 if (0 == strcmp ("arm", service_name))
318 {
319 client = GNUNET_CLIENT_connect (sched, "arm", cfg);
320 if (client == NULL)
321 {
322 if (cb != NULL)
323 cb (cb_cls, GNUNET_SYSERR);
324 return;
325 }
326 GNUNET_CLIENT_service_shutdown (client);
327 GNUNET_CLIENT_disconnect (client);
328 if (cb != NULL)
329 cb (cb_cls, GNUNET_NO);
330 return;
331 }
332 change_service (service_name,
333 cfg,
334 sched, timeout, cb, cb_cls, GNUNET_MESSAGE_TYPE_ARM_STOP);
335}
336
337/* end of arm_api.c */
diff --git a/src/arm/gnunet-arm.c b/src/arm/gnunet-arm.c
new file mode 100644
index 000000000..f8f5bc20f
--- /dev/null
+++ b/src/arm/gnunet-arm.c
@@ -0,0 +1,180 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 arm/gnunet-arm.c
23 * @brief arm for writing a tool
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_arm_service.h"
28#include "gnunet_client_lib.h"
29#include "gnunet_getopt_lib.h"
30#include "gnunet_program_lib.h"
31#include "gnunet_time_lib.h"
32
33/**
34 * Timeout for all operations.
35 */
36#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
37
38/**
39 * Set if we are to shutdown all services (including ARM).
40 */
41static int end;
42
43/**
44 * Set if we are to start default services (including ARM).
45 */
46static int start;
47
48/**
49 * Set to the name of a service to start.
50 */
51static char *init;
52
53/**
54 * Set to the name of a service to kill.
55 */
56static char *term;
57
58/**
59 * Set to the name of a service to test.
60 */
61static char *test;
62
63/**
64 * Final status code.
65 */
66static int ret;
67
68
69static void
70confirm_cb (void *cls, int success)
71{
72 const char *service = cls;
73 switch (success)
74 {
75 case GNUNET_OK:
76 fprintf (stdout, _("Service `%s' is now running.\n"), service);
77 break;
78 case GNUNET_NO:
79 fprintf (stdout, _("Service `%s' is not running.\n"), service);
80 break;
81 case GNUNET_SYSERR:
82 fprintf (stdout,
83 _("Error updating service `%s': ARM not running\n"), service);
84 break;
85 }
86}
87
88
89static void
90confirm_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
91{
92 const char *service = cls;
93
94 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
95 fprintf (stdout, _("Service `%s' is running.\n"), service);
96 else
97 fprintf (stdout, _("Service `%s' is not running.\n"), service);
98}
99
100
101/**
102 * Main function that will be run by the scheduler.
103 *
104 * @param cls closure
105 * @param sched the scheduler to use
106 * @param args remaining command-line arguments
107 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
108 * @param cfg configuration
109 */
110static void
111run (void *cls,
112 struct GNUNET_SCHEDULER_Handle *sched,
113 char *const *args,
114 const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *cfg)
115{
116 if (term != NULL)
117 {
118 GNUNET_ARM_stop_service (term, cfg, sched, TIMEOUT, &confirm_cb, term);
119 }
120 if (end)
121 {
122 GNUNET_ARM_stop_service ("arm",
123 cfg, sched, TIMEOUT, &confirm_cb, "arm");
124 }
125 if (start)
126 {
127 GNUNET_ARM_start_service ("arm",
128 cfg, sched, TIMEOUT, &confirm_cb, "arm");
129 }
130 if (init != NULL)
131 {
132 GNUNET_ARM_start_service (init, cfg, sched, TIMEOUT, &confirm_cb, init);
133 }
134 if (test != NULL)
135 {
136 GNUNET_CLIENT_service_test (sched,
137 test, cfg, TIMEOUT, &confirm_task, test);
138 }
139}
140
141
142/**
143 * gnunet-arm command line options
144 */
145static struct GNUNET_GETOPT_CommandLineOption options[] = {
146 {'e', "end", NULL, gettext_noop ("stop all GNUnet services"),
147 GNUNET_NO, &GNUNET_GETOPT_set_one, &end},
148 {'i', "init", "SERVICE", gettext_noop ("start a particular service"),
149 GNUNET_YES, &GNUNET_GETOPT_set_string, &init},
150 {'k', "kill", "SERVICE", gettext_noop ("stop a particular service"),
151 GNUNET_YES, &GNUNET_GETOPT_set_string, &term},
152 {'s', "start", NULL, gettext_noop ("start all GNUnet default services"),
153 GNUNET_NO, &GNUNET_GETOPT_set_one, &start},
154 {'t', "test", "SERVICE",
155 gettext_noop ("test if a particular service is running"),
156 GNUNET_YES, &GNUNET_GETOPT_set_string, &test},
157 GNUNET_GETOPT_OPTION_END
158};
159
160
161/**
162 * The main function to obtain arm from gnunetd.
163 *
164 * @param argc number of arguments from the command line
165 * @param argv command line arguments
166 * @return 0 ok, 1 on error
167 */
168int
169main (int argc, char *const *argv)
170{
171 return (GNUNET_OK ==
172 GNUNET_PROGRAM_run (argc,
173 argv,
174 "gnunet-arm",
175 gettext_noop
176 ("Control services and the Automated Restart Manager (ARM)"),
177 options, &run, NULL)) ? ret : 1;
178}
179
180/* end of gnunet-arm.c */
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c
new file mode 100644
index 000000000..97d507890
--- /dev/null
+++ b/src/arm/gnunet-service-arm.c
@@ -0,0 +1,712 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 arm/gnunet-service-arm.c
23 * @brief the automated restart manager service
24 * @author Christian Grothoff
25 *
26 * TODO:
27 * - multiple start-stop requests with RC>1 can result
28 * in UP/DOWN signals based on "pending" that are inaccurate...
29 * => have list of clients waiting for a resolution instead of
30 * giving instant (but incorrect) replies
31 * - code could go into restart-loop for a service
32 * if service crashes instantly -- need exponential back-off
33 * - need to test auto-restart code on configuration changes;
34 * - should refine restart code to check if *relevant* parts of the
35 * configuration were changed (anything in the section for the service)
36 * - should have a way to specify dependencies between services and
37 * manage restarts of groups of services
38 */
39#include "platform.h"
40#include "gnunet_client_lib.h"
41#include "gnunet_getopt_lib.h"
42#include "gnunet_os_lib.h"
43#include "gnunet_protocols.h"
44#include "gnunet_service_lib.h"
45#include "arm.h"
46
47
48/**
49 * Run maintenance every second.
50 */
51#define MAINT_FREQUENCY GNUNET_TIME_UNIT_SECONDS
52
53/**
54 * How long do we wait until we decide that a service
55 * did not start?
56 */
57#define CHECK_TIMEOUT GNUNET_TIME_UNIT_MINUTES
58
59struct ServiceList;
60
61typedef void (*CleanCallback) (void *cls, struct ServiceList * pos);
62
63/**
64 * List of our services.
65 */
66struct ServiceList
67{
68 /**
69 * This is a linked list.
70 */
71 struct ServiceList *next;
72
73 /**
74 * Name of the service.
75 */
76 char *name;
77
78 /**
79 * Name of the binary used.
80 */
81 char *binary;
82
83 /**
84 * Name of the configuration file used.
85 */
86 char *config;
87
88 /**
89 * Function to call upon kill completion (waitpid), NULL
90 * if we should simply restart the process.
91 */
92 CleanCallback kill_continuation;
93
94 /**
95 * Closure for kill_continuation.
96 */
97 void *kill_continuation_cls;
98
99 /**
100 * Process ID of the child.
101 */
102 pid_t pid;
103
104 /**
105 * Last time the config of this service was
106 * modified.
107 */
108 time_t mtime;
109
110 /**
111 * Reference counter (counts how many times we've been
112 * asked to start the service). We only actually stop
113 * it once rc hits zero.
114 */
115 unsigned int rc;
116
117};
118
119/**
120 * List of running services.
121 */
122static struct ServiceList *running;
123
124/**
125 * Our configuration
126 */
127static struct GNUNET_CONFIGURATION_Handle *cfg;
128
129/**
130 * Our scheduler.
131 */
132static struct GNUNET_SCHEDULER_Handle *sched;
133
134/**
135 * Command to prepend to each actual command.
136 */
137static char *prefix_command;
138
139
140static size_t
141write_result (void *cls, size_t size, void *buf)
142{
143 uint16_t *res = cls;
144 struct GNUNET_MessageHeader *msg;
145
146 if (buf == NULL)
147 return 0; /* error, not much we can do */
148 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
149 msg = buf;
150 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
151 msg->type = htons (*res);
152 GNUNET_free (res);
153 return sizeof (struct GNUNET_MessageHeader);
154}
155
156
157
158/**
159 * Signal our client that we will start or stop the
160 * service.
161 *
162 * @return NULL if it was not found
163 */
164static void
165signal_result (struct GNUNET_SERVER_Client *client,
166 const char *name, uint16_t result)
167{
168 uint16_t *res;
169
170#if DEBUG_ARM
171 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
172 "Telling client that service `%s' is now %s\n",
173 name,
174 result == GNUNET_MESSAGE_TYPE_ARM_IS_DOWN ? "down" : "up");
175#endif
176 res = GNUNET_malloc (sizeof (uint16_t));
177 *res = result;
178 GNUNET_SERVER_notify_transmit_ready (client,
179 sizeof (struct GNUNET_MessageHeader),
180 GNUNET_TIME_UNIT_FOREVER_REL,
181 &write_result, res);
182}
183
184
185/**
186 * Find the process with the given PID in the
187 * given list.
188 *
189 * @return NULL if it was not found
190 */
191static struct ServiceList *
192find_pid (pid_t pid)
193{
194 struct ServiceList *pos;
195
196 pos = running;
197 while (pos != NULL)
198 {
199 if (pos->pid == pid)
200 return pos;
201 pos = pos->next;
202 }
203 return NULL;
204}
205
206
207/**
208 * Find the process with the given service
209 * name in the given list, remove it and return it.
210 *
211 * @return NULL if it was not found
212 */
213static struct ServiceList *
214find_name (const char *name)
215{
216 struct ServiceList *pos;
217 struct ServiceList *prev;
218
219 pos = running;
220 prev = NULL;
221 while (pos != NULL)
222 {
223 if (0 == strcmp (pos->name, name))
224 {
225 if (prev == NULL)
226 running = pos->next;
227 else
228 prev->next = pos->next;
229 pos->next = NULL;
230 return pos;
231 }
232 prev = pos;
233 pos = pos->next;
234 }
235 return NULL;
236}
237
238
239static void
240free_entry (struct ServiceList *pos)
241{
242 GNUNET_free_non_null (pos->config);
243 GNUNET_free_non_null (pos->binary);
244 GNUNET_free (pos->name);
245 GNUNET_free (pos);
246}
247
248
249
250
251/**
252 * Actually start the process for the given service.
253 *
254 * @param sl identifies service to start
255 */
256static void
257start_process (struct ServiceList *sl)
258{
259 char *loprefix;
260 char **argv;
261 unsigned int argv_size;
262 char *lopos;
263 const char *firstarg;
264 int use_debug;
265
266 /* start service */
267 if (GNUNET_OK !=
268 GNUNET_CONFIGURATION_get_value_string (cfg,
269 sl->name, "PREFIX", &loprefix))
270 loprefix = GNUNET_strdup (prefix_command);
271 use_debug = GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "DEBUG");
272
273 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Starting service `%s'\n"), sl->name);
274#if DEBUG_ARM
275 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
276 "Starting service `%s' using binary `%s' and configuration `%s'\n",
277 sl->name, sl->binary, sl->config);
278#endif
279 argv_size = 5;
280 if (use_debug)
281 argv_size += 2;
282 lopos = loprefix;
283 while ('\0' != *lopos)
284 {
285 if (*lopos == ' ')
286 argv_size++;
287 lopos++;
288 }
289 firstarg = NULL;
290 argv = GNUNET_malloc (argv_size * sizeof (char *));
291 argv_size = 0;
292 lopos = loprefix;
293 while ('\0' != *lopos)
294 {
295 while (*lopos == ' ')
296 lopos++;
297 if (*lopos == '\0')
298 continue;
299 if (argv_size == 0)
300 firstarg = lopos;
301 argv[argv_size++] = lopos;
302 while (('\0' != *lopos) && (' ' != *lopos))
303 lopos++;
304 if ('\0' == *lopos)
305 continue;
306 *lopos = '\0';
307 lopos++;
308 }
309 if (argv_size == 0)
310 firstarg = sl->binary;
311 argv[argv_size++] = sl->binary;
312 argv[argv_size++] = "-c";
313 argv[argv_size++] = sl->config;
314 if (GNUNET_YES == use_debug)
315 {
316 argv[argv_size++] = "-L";
317 argv[argv_size++] = "DEBUG";
318 }
319 argv[argv_size++] = NULL;
320 sl->pid = GNUNET_OS_start_process_v (firstarg, argv);
321 GNUNET_free (argv);
322 GNUNET_free (loprefix);
323}
324
325
326/**
327 * Start the specified service.
328 */
329static void
330start_service (struct GNUNET_SERVER_Handle *server,
331 struct GNUNET_SERVER_Client *client, const char *servicename)
332{
333 struct ServiceList *sl;
334 char *binary;
335 char *config;
336 struct stat sbuf;
337 sl = find_name (servicename);
338 if (sl != NULL)
339 {
340 /* already running, just increment RC */
341 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
342 _("Service `%s' already running.\n"), servicename);
343 sl->rc++;
344 sl->next = running;
345 running = sl;
346 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP);
347 return;
348 }
349 if (GNUNET_OK !=
350 GNUNET_CONFIGURATION_get_value_string (cfg,
351 servicename, "BINARY", &binary))
352 {
353 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
354 _("Binary implementing service `%s' not known!\n"),
355 servicename);
356 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN);
357 return;
358 }
359 if ((GNUNET_OK !=
360 GNUNET_CONFIGURATION_get_value_filename (cfg,
361 servicename,
362 "CONFIG",
363 &config)) ||
364 (0 != STAT (config, &sbuf)))
365 {
366 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
367 _("Configuration file `%s' for service `%s' not known!\n"),
368 config, servicename);
369 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN);
370 GNUNET_free (binary);
371 return;
372 }
373 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
374 _("Preparing to start `%s'\n"), servicename);
375 sl = GNUNET_malloc (sizeof (struct ServiceList));
376 sl->name = GNUNET_strdup (servicename);
377 sl->next = running;
378 sl->rc = 1;
379 sl->binary = binary;
380 sl->config = config;
381 sl->mtime = sbuf.st_mtime;
382 running = sl;
383 start_process (sl);
384 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP);
385}
386
387
388static void
389free_and_signal (void *cls, struct ServiceList *pos)
390{
391 struct GNUNET_SERVER_Client *client = cls;
392 /* find_name will remove "pos" from the list! */
393 GNUNET_assert (pos == find_name (pos->name));
394 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Service `%s' stopped\n", pos->name);
395 signal_result (client, pos->name, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN);
396 GNUNET_SERVER_receive_done (client, GNUNET_OK);
397 GNUNET_SERVER_client_drop (client);
398 free_entry (pos);
399}
400
401
402/**
403 * Stop the specified service.
404 */
405static void
406stop_service (struct GNUNET_SERVER_Handle *server,
407 struct GNUNET_SERVER_Client *client, const char *servicename)
408{
409 struct ServiceList *pos;
410 struct GNUNET_CLIENT_Connection *sc;
411
412 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
413 "Preparing to stop `%s'\n", servicename);
414 pos = find_name (servicename);
415 if (pos->kill_continuation != NULL)
416 {
417 /* killing already in progress */
418 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN);
419 return;
420 }
421 if ((pos != NULL) && (pos->rc > 1))
422 {
423 /* RC>1, just decrement RC */
424 pos->rc--;
425 pos->next = running;
426 running = pos;
427 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP);
428 GNUNET_SERVER_receive_done (client, GNUNET_OK);
429 return;
430 }
431 if (pos != NULL)
432 {
433 if (0 != PLIBC_KILL (pos->pid, SIGTERM))
434 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
435 pos->next = running;
436 running = pos;
437 pos->kill_continuation = &free_and_signal;
438 pos->kill_continuation_cls = client;
439 GNUNET_SERVER_client_keep (client);
440 }
441 else
442 {
443 sc = GNUNET_CLIENT_connect (sched, servicename, cfg);
444 GNUNET_CLIENT_service_shutdown (sc);
445 GNUNET_CLIENT_disconnect (sc);
446 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN);
447 GNUNET_SERVER_receive_done (client, GNUNET_OK);
448 }
449}
450
451
452/**
453 * Handle START-message.
454 *
455 * @param cls closure (always NULL)
456 * @param server the server handling the message
457 * @param client identification of the client
458 * @param message the actual message
459 * @return GNUNET_OK to keep the connection open,
460 * GNUNET_SYSERR to close it (signal serious error)
461 */
462static void
463handle_start (void *cls,
464 struct GNUNET_SERVER_Handle *server,
465 struct GNUNET_SERVER_Client *client,
466 const struct GNUNET_MessageHeader *message)
467{
468 const char *servicename;
469 uint16_t size;
470
471 size = ntohs (message->size);
472 size -= sizeof (struct GNUNET_MessageHeader);
473 servicename = (const char *) &message[1];
474 if ((size == 0) || (servicename[size - 1] != '\0'))
475 {
476 GNUNET_break (0);
477 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
478 return;
479 }
480 start_service (server, client, servicename);
481 GNUNET_SERVER_receive_done (client, GNUNET_OK);
482}
483
484
485/**
486 * Handle STOP-message.
487 *
488 * @param cls closure (always NULL)
489 * @param server the server handling the message
490 * @param client identification of the client
491 * @param message the actual message
492 * @return GNUNET_OK to keep the connection open,
493 * GNUNET_SYSERR to close it (signal serious error)
494 */
495static void
496handle_stop (void *cls,
497 struct GNUNET_SERVER_Handle *server,
498 struct GNUNET_SERVER_Client *client,
499 const struct GNUNET_MessageHeader *message)
500{
501 const char *servicename;
502 uint16_t size;
503
504 size = ntohs (message->size);
505 size -= sizeof (struct GNUNET_MessageHeader);
506 servicename = (const char *) &message[1];
507 if ((size == 0) || (servicename[size - 1] != '\0'))
508 {
509 GNUNET_break (0);
510 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
511 return;
512 }
513 stop_service (server, client, servicename);
514}
515
516
517
518/**
519 * Background task doing maintenance.
520 *
521 * @param cls closure
522 * @param tc context
523 */
524static void
525maint (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
526{
527 struct ServiceList *pos;
528 pid_t pid;
529 int status;
530 const char *statstr;
531 int statcode;
532 struct stat sbuf;
533
534 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
535 {
536 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Stopping all services\n"));
537 while (NULL != (pos = running))
538 {
539 running = pos->next;
540 if (0 != PLIBC_KILL (pos->pid, SIGTERM))
541 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
542 if (pos->pid != waitpid (pos->pid, NULL, 0))
543 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
544 free_entry (pos);
545 }
546 return;
547 }
548 GNUNET_SCHEDULER_add_delayed (tc->sched,
549 GNUNET_YES,
550 GNUNET_SCHEDULER_PRIORITY_IDLE,
551 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
552 MAINT_FREQUENCY, &maint, cfg);
553
554 /* check for services that died (WAITPID) */
555 while (0 < (pid = waitpid (0, &status, WNOHANG)))
556 {
557 if (WIFSTOPPED (status) || WIFCONTINUED (status))
558 continue;
559 pos = find_pid (pid);
560 if (pos == NULL)
561 {
562 /* we killed the service */
563 continue;
564 }
565 if (WIFEXITED (status))
566 {
567 statstr = _( /* process termination method */ "exit");
568 statcode = WEXITSTATUS (status);
569 }
570 else if (WTERMSIG (status))
571 {
572 statstr = _( /* process termination method */ "signal");
573 statcode = WTERMSIG (status);
574 }
575 else
576 {
577 statstr = _( /* process termination method */ "unknown");
578 statcode = 0;
579 }
580 if (NULL != pos->kill_continuation)
581 {
582 pos->kill_continuation (pos->kill_continuation_cls, pos);
583 }
584 else
585 {
586 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
587 _
588 ("Service `%s' terminated with status %s/%d, will try to restart it!\n"),
589 pos->name, statstr, statcode);
590 /* schedule restart */
591 pos->pid = 0;
592 }
593 }
594
595 /* check for services that need to be restarted due to
596 configuration changes or because the last restart failed */
597 pos = running;
598 while (pos != NULL)
599 {
600 if ((0 == STAT (pos->config, &sbuf)) && (pos->mtime < sbuf.st_mtime))
601 {
602 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
603 _
604 ("Restarting service `%s' due to configuration file change.\n"));
605 if (0 != PLIBC_KILL (pos->pid, SIGTERM))
606 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
607 }
608 if (pos->pid == 0)
609 {
610 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
611 _("Restarting service `%s'.\n"), pos->name);
612 /* FIXME: should have some exponentially
613 increasing timer to avoid tight restart loops */
614 start_process (pos);
615 }
616 pos = pos->next;
617 }
618}
619
620
621/**
622 * List of handlers for the messages understood by this
623 * service.
624 */
625static struct GNUNET_SERVER_MessageHandler handlers[] = {
626 {&handle_start, NULL, GNUNET_MESSAGE_TYPE_ARM_START, 0},
627 {&handle_stop, NULL, GNUNET_MESSAGE_TYPE_ARM_STOP, 0},
628 {NULL, NULL, 0, 0}
629};
630
631
632/**
633 * Process arm requests.
634 *
635 * @param cls closure
636 * @param s scheduler to use
637 * @param server the initialized server
638 * @param c configuration to use
639 */
640static void
641run (void *cls,
642 struct GNUNET_SCHEDULER_Handle *s,
643 struct GNUNET_SERVER_Handle *server,
644 struct GNUNET_CONFIGURATION_Handle *c)
645{
646 char *defaultservices;
647 char *pos;
648
649 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Starting...\n");
650 cfg = c;
651 sched = s;
652 if (GNUNET_OK !=
653 GNUNET_CONFIGURATION_get_value_string (cfg,
654 "ARM",
655 "GLOBAL_PREFIX",
656 &prefix_command))
657 prefix_command = GNUNET_strdup ("");
658 /* start default services... */
659 if (GNUNET_OK ==
660 GNUNET_CONFIGURATION_get_value_string (cfg,
661 "ARM",
662 "DEFAULTSERVICES",
663 &defaultservices))
664 {
665#if DEBUG_ARM
666 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
667 "Starting default services `%s'\n", defaultservices);
668#endif
669 pos = strtok (defaultservices, " ");
670 while (pos != NULL)
671 {
672 start_service (server, NULL, pos);
673 pos = strtok (NULL, " ");
674 }
675 GNUNET_free (defaultservices);
676 }
677 else
678 {
679#if DEBUG_ARM
680 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
681 "No default services configured.\n");
682#endif
683 }
684
685 /* process client requests */
686 GNUNET_SERVER_add_handlers (server, handlers);
687
688 /* manage services */
689 GNUNET_SCHEDULER_add_delayed (sched,
690 GNUNET_YES,
691 GNUNET_SCHEDULER_PRIORITY_IDLE,
692 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
693 MAINT_FREQUENCY, &maint, NULL);
694}
695
696
697/**
698 * The main function for the arm service.
699 *
700 * @param argc number of arguments from the command line
701 * @param argv command line arguments
702 * @return 0 ok, 1 on error
703 */
704int
705main (int argc, char *const *argv)
706{
707 return (GNUNET_OK ==
708 GNUNET_SERVICE_run (argc,
709 argv, "arm", &run, NULL, NULL, NULL)) ? 0 : 1;
710}
711
712/* end of gnunet-service-arm.c */
diff --git a/src/arm/test_arm_api.c b/src/arm/test_arm_api.c
new file mode 100644
index 000000000..89f63d3ec
--- /dev/null
+++ b/src/arm/test_arm_api.c
@@ -0,0 +1,140 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 arm/test_arm_api.c
22 * @brief testcase for arm_api.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_arm_service.h"
27#include "gnunet_client_lib.h"
28#include "gnunet_configuration_lib.h"
29#include "gnunet_getopt_lib.h"
30#include "gnunet_program_lib.h"
31#include "gnunet_resolver_service.h"
32
33#define VERBOSE GNUNET_NO
34
35#define START_ARM GNUNET_YES
36
37#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
38
39static struct GNUNET_SCHEDULER_Handle *sched;
40
41static struct GNUNET_CONFIGURATION_Handle *cfg;
42
43static int ok = 1;
44
45static void
46dns_notify (void *cls, const struct sockaddr *addr, socklen_t addrlen)
47{
48 if (addr == NULL)
49 {
50 GNUNET_assert (ok == 0);
51#if START_ARM
52 GNUNET_ARM_stop_service ("arm", cfg, sched, TIMEOUT, NULL, NULL);
53#endif
54 return;
55 }
56 GNUNET_assert (addr != NULL);
57 ok = 0;
58}
59
60
61static void
62resolver_notify (void *cls, int success)
63{
64 GNUNET_assert (success == GNUNET_YES);
65 sleep (1); /* FIXME: that we need to do this is a problem... */
66 GNUNET_RESOLVER_ip_get (sched,
67 cfg,
68 "localhost", AF_INET, TIMEOUT, &dns_notify, NULL);
69}
70
71static void
72arm_notify (void *cls, int success)
73{
74 GNUNET_assert (success == GNUNET_YES);
75#if START_ARM
76 sleep (1); /* FIXME: that we need to do this is a problem... */
77#endif
78 GNUNET_ARM_start_service ("resolver",
79 cfg, sched, TIMEOUT, &resolver_notify, NULL);
80}
81
82
83static void
84task (void *cls,
85 struct GNUNET_SCHEDULER_Handle *s,
86 char *const *args,
87 const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *c)
88{
89 cfg = c;
90 sched = s;
91#if START_ARM
92 GNUNET_ARM_start_service ("arm", cfg, sched, TIMEOUT, &arm_notify, NULL);
93#else
94 arm_notify (NULL, GNUNET_YES);
95#endif
96}
97
98
99
100static int
101check ()
102{
103 char *const argv[] = {
104 "test-arm-api",
105 "-c", "test_arm_api_data.conf",
106#if VERBOSE
107 "-L", "DEBUG",
108#endif
109 NULL
110 };
111 struct GNUNET_GETOPT_CommandLineOption options[] = {
112 GNUNET_GETOPT_OPTION_END
113 };
114 GNUNET_assert (GNUNET_OK ==
115 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
116 argv,
117 "test-arm-api",
118 "nohelp", options, &task, NULL));
119 return ok;
120}
121
122int
123main (int argc, char *argv[])
124{
125 int ret;
126
127
128 GNUNET_log_setup ("test-arm-api",
129#if VERBOSE
130 "DEBUG",
131#else
132 "WARNING",
133#endif
134 NULL);
135 ret = check ();
136
137 return ret;
138}
139
140/* end of test_arm_api.c */
diff --git a/src/arm/test_arm_api_data.conf b/src/arm/test_arm_api_data.conf
new file mode 100644
index 000000000..b25924917
--- /dev/null
+++ b/src/arm/test_arm_api_data.conf
@@ -0,0 +1,7 @@
1[PATHS]
2SERVICEHOME = /tmp/test-gnunetd-arm/
3DEFAULTCONFIG = test_arm_api_data.conf
4
5[arm]
6PORT = 23354
7
diff --git a/src/arm/test_gnunet_arm.sh b/src/arm/test_gnunet_arm.sh
new file mode 100755
index 000000000..72f7a176b
--- /dev/null
+++ b/src/arm/test_gnunet_arm.sh
@@ -0,0 +1,117 @@
1#!/bin/bash
2
3rm -rf /tmp/test-gnunetd-arm/
4exe="./gnunet-arm -c test_arm_api_data.conf"
5base=/tmp/gnunet-test-arm
6#DEBUG="-L DEBUG"
7
8# ----------------------------------------------------------------------------------
9echo -n "TEST: Bad argument checking... "
10
11if $exe -x 2> /dev/null; then
12 echo "FAIL: error running $exe"
13 exit 1
14fi
15echo "PASS"
16
17# ----------------------------------------------------------------------------------
18echo -n "TEST: Start ARM... "
19
20if ! $exe $DEBUG -s > /dev/null ; then
21 echo "FAIL: error running $exe"
22 exit 1
23fi
24LINES=`ps ax | grep gnunet-service-arm | grep -v grep | wc -l`
25if test $LINES -eq 0; then
26 echo "FAIL: found $LINES gnunet-service-arm processes"
27 exit 1
28fi
29echo "PASS"
30
31# ----------------------------------------------------------------------------------
32echo -n "TEST: Start another service... "
33
34if ! $exe $DEBUG -i resolver > /dev/null ; then
35 echo "FAIL: error running $exe"
36 kill %%
37 exit 1
38fi
39sleep 1
40LINES=`ps ax | grep gnunet-service-resolver | grep -v grep | wc -l`
41if test $LINES -ne 1; then
42 echo "FAIL: unexpected output (got $LINES lines, wanted 1)"
43 $exe -e
44 exit 1
45fi
46echo "PASS"
47
48# ----------------------------------------------------------------------------------
49echo -n "TEST: Test -t on running service... "
50
51if ! $exe $DEBUG -t resolver > $base.out; then
52 echo "FAIL: error running $exe"
53 exit 1
54fi
55LINES=`cat $base.out | grep resolver | grep not | wc -l`
56if test $LINES -ne 0; then
57 echo "FAIL: unexpected output"
58 $exe -e
59 exit 1
60fi
61LINES=`cat $base.out | grep resolver | grep -v not | wc -l`
62if test $LINES -ne 1; then
63 echo "FAIL: unexpected output"
64 $exe -e
65 exit 1
66fi
67echo "PASS"
68
69# ----------------------------------------------------------------------------------
70echo -n "TEST: Stop a service... "
71
72if ! $exe $DEBUG -k resolver > /dev/null; then
73 echo "FAIL: error running $exe"
74 $exe -e
75 exit 1
76fi
77sleep 1
78LINES=`ps ax | grep gnunet-service-resolver | grep -v grep | wc -l`
79if test $LINES -ne 0; then
80 echo "FAIL: unexpected output"
81 $exe -e
82 exit 1
83fi
84echo "PASS"
85
86# ----------------------------------------------------------------------------------
87echo -n "TEST: Test -t on stopped service... "
88
89if ! $exe $DEBUG -t resolver > $base.out; then
90 echo "FAIL: error running $exe"
91 $exe -e
92 exit 1
93fi
94LINES=`cat $base.out | grep resolver | grep not | wc -l`
95if test $LINES -ne 1; then
96 echo "FAIL: unexpected output"
97 $exe -e
98 exit 1
99fi
100echo "PASS"
101
102# ----------------------------------------------------------------------------------
103echo -n "TEST: Stop ARM... "
104
105if ! $exe $DEBUG -e > /dev/null; then
106 echo "FAIL: error running $exe"
107 exit 1
108fi
109LINES=`ps ax | grep gnunet-service-arm | grep -v grep | wc -l`
110if test $LINES -ne 0; then
111 echo "FAIL: unexpected output"
112 exit 1
113fi
114echo "PASS"
115
116rm -rf /tmp/test-gnunetd-arm/
117rm -f $base.out
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
new file mode 100644
index 000000000..55ef757c2
--- /dev/null
+++ b/src/core/Makefile.am
@@ -0,0 +1,68 @@
1INCLUDES = -I$(top_srcdir)/src/include
2
3plugindir = $(libdir)/gnunet
4
5if MINGW
6 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
7endif
8
9if USE_COVERAGE
10 AM_CFLAGS = -fprofile-arcs -ftest-coverage
11endif
12
13
14lib_LTLIBRARIES = \
15 libgnunetcore.la
16
17libgnunetcore_la_SOURCES = \
18 core_api.c core.h
19libgnunetcore_la_LIBADD = \
20 $(top_builddir)/src/arm/libgnunetarm.la \
21 $(top_builddir)/src/util/libgnunetutil.la \
22 $(GN_LIBINTL)
23libgnunetcore_la_LDFLAGS = \
24 $(GN_LIB_LDFLAGS) $(WINFLAGS) \
25 -version-info 0:0:0
26
27
28bin_PROGRAMS = \
29 gnunet-service-core
30
31gnunet_service_core_SOURCES = \
32 gnunet-service-core.c
33gnunet_service_core_LDADD = \
34 $(top_builddir)/src/hello/libgnunethello.la \
35 $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
36 $(top_builddir)/src/transport/libgnunettransport.la \
37 $(top_builddir)/src/util/libgnunetutil.la \
38 $(GN_LIBINTL)
39
40
41check_PROGRAMS = \
42 test_core_api_start_only \
43 test_core_api
44
45TESTS = $(check_PROGRAMS)
46
47test_core_api_SOURCES = \
48 test_core_api.c
49test_core_api_LDADD = \
50 $(top_builddir)/src/arm/libgnunetarm.la \
51 $(top_builddir)/src/core/libgnunetcore.la \
52 $(top_builddir)/src/transport/libgnunettransport.la \
53 $(top_builddir)/src/util/libgnunetutil.la
54
55
56test_core_api_start_only_SOURCES = \
57 test_core_api_start_only.c
58test_core_api_start_only_LDADD = \
59 $(top_builddir)/src/arm/libgnunetarm.la \
60 $(top_builddir)/src/core/libgnunetcore.la \
61 $(top_builddir)/src/util/libgnunetutil.la
62
63
64EXTRA_DIST = \
65 test_core_api_data.conf \
66 test_core_api_peer1.conf \
67 test_core_api_peer2.conf
68
diff --git a/src/core/core.h b/src/core/core.h
new file mode 100644
index 000000000..840c7e143
--- /dev/null
+++ b/src/core/core.h
@@ -0,0 +1,308 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 core/core.h
23 * @brief common internal definitions for core service
24 * @author Christian Grothoff
25 */
26#include "gnunet_crypto_lib.h"
27#include "gnunet_time_lib.h"
28
29#define DEBUG_CORE GNUNET_NO
30
31/**
32 * Definition of bits in the InitMessage's options field that specify
33 * which events this client cares about. Note that inbound messages
34 * for handlers that were specifically registered are always
35 * transmitted to the client.
36 */
37#define GNUNET_CORE_OPTION_NOTHING 0
38#define GNUNET_CORE_OPTION_SEND_CONNECT 1
39#define GNUNET_CORE_OPTION_SEND_DISCONNECT 2
40#define GNUNET_CORE_OPTION_SEND_BFC 4
41#define GNUNET_CORE_OPTION_SEND_FULL_INBOUND 8
42#define GNUNET_CORE_OPTION_SEND_HDR_INBOUND 16
43#define GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND 32
44#define GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND 64
45
46
47/**
48 * Message transmitted core clients to gnunet-service-core
49 * to start the interaction. This header is followed by
50 * uint16_t type values specifying which messages this
51 * client is interested in.
52 */
53struct InitMessage
54{
55
56 /**
57 * Header with type GNUNET_MESSAGE_TYPE_CORE_INIT.
58 */
59 struct GNUNET_MessageHeader header;
60
61 /**
62 * Options, see GNUNET_CORE_OPTION_ values.
63 */
64 uint32_t options GNUNET_PACKED;
65
66};
67
68
69/**
70 * Message transmitted by the gnunet-service-core process
71 * to its clients in response to an INIT message.
72 */
73struct InitReplyMessage
74{
75
76 /**
77 * Header with type GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY
78 */
79 struct GNUNET_MessageHeader header;
80
81 /**
82 * Always zero.
83 */
84 uint32_t reserved GNUNET_PACKED;
85
86 /**
87 * Public key of the local peer.
88 */
89 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded publicKey;
90
91};
92
93
94/**
95 * Message sent by the service to clients to notify them
96 * about a peer connecting or disconnecting.
97 */
98struct ConnectNotifyMessage
99{
100 /**
101 * Header with type GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT
102 * or GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT.
103 */
104 struct GNUNET_MessageHeader header;
105
106 /**
107 * Available bandwidth to this peer; zero for disconnect.
108 * [TODO: currently set to hard-coded constant and hence
109 * not really useful, right?]
110 */
111 uint32_t bpm_available GNUNET_PACKED;
112
113 /**
114 * Identity of the connecting peer.
115 */
116 struct GNUNET_PeerIdentity peer;
117
118 /**
119 * Time of our last interaction with the peer; close
120 * to "now" for connect messages.
121 * [TODO: is this useful?]
122 */
123 struct GNUNET_TIME_AbsoluteNBO last_activity;
124
125};
126
127
128
129/**
130 * Message sent by the service to clients to notify them about
131 * messages being received or transmitted. This overall message is
132 * followed by the real message, or just the header of the real
133 * message (depending on the client's preferences). The receiver can
134 * tell if he got the full message or only a partial message by
135 * looking at the size field in the header of NotifyTrafficMessage and
136 * checking it with the size field in the message that follows.
137 */
138struct NotifyTrafficMessage
139{
140 /**
141 * Header with type GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND
142 * or GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND.
143 */
144 struct GNUNET_MessageHeader header;
145
146 /**
147 * Always zero.
148 */
149 uint32_t reserved GNUNET_PACKED;
150
151 /**
152 * Identity of the receiver or sender.
153 */
154 struct GNUNET_PeerIdentity peer;
155
156};
157
158
159/**
160 * Message sent to the core asking for configuration
161 * information and possibly preference changes.
162 */
163struct RequestConfigureMessage
164{
165 /**
166 * Header with type GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONFIGURE
167 */
168 struct GNUNET_MessageHeader header;
169
170 /**
171 * Always zero.
172 */
173 uint32_t reserved GNUNET_PACKED;
174
175 /**
176 * Limit the number of bytes of outbound traffic to this
177 * peer to at most the specified amount (naturally, the
178 * amount is also limited by the receiving peer).
179 */
180 uint32_t limit_outbound_bpm GNUNET_PACKED;
181
182 /**
183 * Number of bytes of inbound traffic to reserve, can
184 * be negative (to unreserve). NBO.
185 */
186 int32_t reserve_inbound GNUNET_PACKED;
187
188 /**
189 * Increment the current traffic preference for the given peer by
190 * the specified amont. The traffic preference is used to determine
191 * the share of bandwidth this peer will typcially be assigned.
192 */
193 double preference_change GNUNET_PACKED;
194
195 /**
196 * Identity of the peer being configured.
197 */
198 struct GNUNET_PeerIdentity peer;
199
200};
201
202
203/**
204 * Response from the core to a "RequestConfigureMessage"
205 * providing traffic status information for a peer.
206 */
207struct ConfigurationInfoMessage
208{
209 /**
210 * Header with type GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO
211 */
212 struct GNUNET_MessageHeader header;
213
214 /**
215 * Amount of traffic (inbound number of bytes) that was reserved in
216 * response to the configuration change request. Negative for
217 * "unreserved" bytes.
218 */
219 int32_t reserved_amount GNUNET_PACKED;
220
221 /**
222 * Available bandwidth in (in bytes per minute) for this peer.
223 * 0 if we have been disconnected.
224 */
225 uint32_t bpm_in GNUNET_PACKED;
226
227 /**
228 * Available bandwidth out (in bytes per minute) for this peer,
229 * 0 if we have been disconnected.
230 */
231 uint32_t bpm_out GNUNET_PACKED;
232
233 /**
234 * Latest transport latency estimate for the peer.
235 * FOREVER if we have been disconnected.
236 */
237 struct GNUNET_TIME_RelativeNBO latency;
238
239 /**
240 * Current traffic preference for the peer.
241 * 0 if we have been disconnected.
242 */
243 double preference;
244
245 /**
246 * Identity of the receiver or sender.
247 */
248 struct GNUNET_PeerIdentity peer;
249
250};
251
252
253/**
254 * Core asking a client to generate traffic for a particular
255 * target.
256 */
257struct SolicitTrafficMessage
258{
259 /**
260 * Header with type GNUNET_MESSAGE_TYPE_CORE_SOLICIT_TRAFFIC
261 * or GNUNET_MESSAGE_TYPE_CORE_RECV_OK
262 */
263 struct GNUNET_MessageHeader header;
264
265 /**
266 * Number of bytes of traffic being solicited.
267 */
268 uint32_t solicit_size GNUNET_PACKED;
269
270 /**
271 * Identity of the receiver or sender.
272 */
273 struct GNUNET_PeerIdentity peer;
274
275};
276
277
278/**
279 * Client asking core to transmit a particular message to
280 * a particular target. Does NOT have to be solicited.
281 */
282struct SendMessage
283{
284 /**
285 * Header with type GNUNET_MESSAGE_TYPE_CORE_SEND
286 */
287 struct GNUNET_MessageHeader header;
288
289 /**
290 * How important is this message?
291 */
292 uint32_t priority GNUNET_PACKED;
293
294 /**
295 * By what time would the sender really like to see this
296 * message transmitted?
297 */
298 struct GNUNET_TIME_AbsoluteNBO deadline;
299
300 /**
301 * Identity of the receiver or sender.
302 */
303 struct GNUNET_PeerIdentity peer;
304
305};
306
307
308/* end of core.h */
diff --git a/src/core/core_api.c b/src/core/core_api.c
new file mode 100644
index 000000000..10fa0ccdd
--- /dev/null
+++ b/src/core/core_api.c
@@ -0,0 +1,1071 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 core/core_api.c
23 * @brief core service; this is the main API for encrypted P2P
24 * communications
25 * @author Christian Grothoff
26 */
27#include "platform.h"
28#include "gnunet_core_service.h"
29#include "core.h"
30
31
32/**
33 * Context for the core service connection.
34 */
35struct GNUNET_CORE_Handle
36{
37
38 /**
39 * Our scheduler.
40 */
41 struct GNUNET_SCHEDULER_Handle *sched;
42
43 /**
44 * Configuration we're using.
45 */
46 struct GNUNET_CONFIGURATION_Handle *cfg;
47
48 /**
49 * Closure for the various callbacks.
50 */
51 void *cls;
52
53 /**
54 * Function to call once we've handshaked with the core service.
55 */
56 GNUNET_CORE_StartupCallback init;
57
58 /**
59 * Function to call whenever we're notified about a peer connecting.
60 */
61 GNUNET_CORE_ClientEventHandler connects;
62
63 /**
64 * Function to call whenever we're notified about a peer disconnecting.
65 */
66 GNUNET_CORE_ClientEventHandler disconnects;
67
68 /**
69 * Function to call whenever we're asked to generate traffic
70 * (data provided to be transmitted back to the service).
71 */
72 GNUNET_CORE_BufferFillCallback bfc;
73
74 /**
75 * Function to call whenever we receive an inbound message.
76 */
77 GNUNET_CORE_MessageCallback inbound_notify;
78
79 /**
80 * Function to call whenever we receive an outbound message.
81 */
82 GNUNET_CORE_MessageCallback outbound_notify;
83
84 /**
85 * Function handlers for messages of particular type.
86 */
87 const struct GNUNET_CORE_MessageHandler *handlers;
88
89 /**
90 * Our connection to the service.
91 */
92 struct GNUNET_CLIENT_Connection *client;
93
94 /**
95 * Handle for our current transmission request.
96 */
97 struct GNUNET_NETWORK_TransmitHandle *th;
98
99 /**
100 * Head of doubly-linked list of pending requests.
101 */
102 struct GNUNET_CORE_TransmitHandle *pending_head;
103
104 /**
105 * Tail of doubly-linked list of pending requests.
106 */
107 struct GNUNET_CORE_TransmitHandle *pending_tail;
108
109 /**
110 * Currently submitted request (or NULL)
111 */
112 struct GNUNET_CORE_TransmitHandle *submitted;
113
114 /**
115 * How long to wait until we time out the connection attempt?
116 */
117 struct GNUNET_TIME_Absolute startup_timeout;
118
119 /**
120 * ID of reconnect task (if any).
121 */
122 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
123
124 /**
125 * Number of entries in the handlers array.
126 */
127 unsigned int hcnt;
128
129 /**
130 * For inbound notifications without a specific handler, do
131 * we expect to only receive headers?
132 */
133 int inbound_hdr_only;
134
135 /**
136 * For outbound notifications without a specific handler, do
137 * we expect to only receive headers?
138 */
139 int outbound_hdr_only;
140
141 /**
142 * Are we currently disconnected and hence unable to forward
143 * requests?
144 */
145 int currently_down;
146};
147
148
149/**
150 * Handle for a transmission request.
151 */
152struct GNUNET_CORE_TransmitHandle
153{
154
155 /**
156 * We keep active transmit handles in a doubly-linked list.
157 */
158 struct GNUNET_CORE_TransmitHandle *next;
159
160 /**
161 * We keep active transmit handles in a doubly-linked list.
162 */
163 struct GNUNET_CORE_TransmitHandle *prev;
164
165 /**
166 * Corresponding core handle.
167 */
168 struct GNUNET_CORE_Handle *ch;
169
170 /**
171 * Function that will be called to get the actual request
172 * (once we are ready to transmit this request to the core).
173 * The function will be called with a NULL buffer to signal
174 * timeout.
175 */
176 GNUNET_NETWORK_TransmitReadyNotify get_message;
177
178 /**
179 * Closure for get_message.
180 */
181 void *get_message_cls;
182
183 /**
184 * If this entry is for a configuration request, pointer
185 * to the information callback; otherwise NULL.
186 */
187 GNUNET_CORE_PeerConfigurationInfoCallback info;
188
189 /**
190 * Closure for info.
191 */
192 void *info_cls;
193
194 /**
195 * If this entry is for a transmission request, pointer
196 * to the notify callback; otherwise NULL.
197 */
198 GNUNET_NETWORK_TransmitReadyNotify notify;
199
200 /**
201 * Closure for notify.
202 */
203 void *notify_cls;
204
205 /**
206 * Peer the request is about.
207 */
208 struct GNUNET_PeerIdentity peer;
209
210 /**
211 * Timeout for this handle.
212 */
213 struct GNUNET_TIME_Absolute timeout;
214
215 /**
216 * ID of timeout task.
217 */
218 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
219
220 /**
221 * How important is this message?
222 */
223 uint32_t priority;
224
225 /**
226 * Size of this request.
227 */
228 uint16_t msize;
229
230
231};
232
233
234/**
235 * Function called when we are ready to transmit our
236 * "START" message (or when this operation timed out).
237 *
238 * @param cls closure
239 * @param size number of bytes available in buf
240 * @param buf where the callee should write the message
241 * @return number of bytes written to buf
242 */
243static size_t transmit_start (void *cls, size_t size, void *buf);
244
245
246/**
247 * Our current client connection went down. Clean it up
248 * and try to reconnect!
249 */
250static void
251reconnect (struct GNUNET_CORE_Handle *h)
252{
253 GNUNET_CLIENT_disconnect (h->client);
254 h->currently_down = GNUNET_YES;
255 h->client = GNUNET_CLIENT_connect (h->sched, "core", h->cfg);
256 h->th = GNUNET_CLIENT_notify_transmit_ready (h->client,
257 sizeof (struct InitMessage) +
258 sizeof (uint16_t) * h->hcnt,
259 GNUNET_TIME_UNIT_SECONDS,
260 &transmit_start, h);
261}
262
263
264/**
265 * The given request hit its timeout. Remove from the
266 * doubly-linked list and call the respective continuation.
267 *
268 * @param cls the transmit handle of the request that timed out
269 * @param tc context, can be NULL (!)
270 */
271static void
272timeout_request (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
273{
274 struct GNUNET_CORE_TransmitHandle *th = cls;
275 struct GNUNET_CORE_Handle *h;
276
277 h = th->ch;
278 th->timeout_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
279 GNUNET_assert (0 == th->get_message (th->get_message_cls, 0, NULL));
280 GNUNET_CORE_notify_transmit_ready_cancel (th);
281}
282
283
284/**
285 * Function called when we are ready to transmit a request from our
286 * request list (or when this operation timed out).
287 *
288 * @param cls closure
289 * @param size number of bytes available in buf
290 * @param buf where the callee should write the message
291 * @return number of bytes written to buf
292 */
293static size_t
294request_start (void *cls, size_t size, void *buf)
295{
296 struct GNUNET_CORE_Handle *h = cls;
297 struct GNUNET_CORE_TransmitHandle *th;
298 size_t ret;
299
300 h->th = NULL;
301 th = h->pending_head;
302 if (buf == NULL)
303 {
304 timeout_request (th, NULL);
305 return 0;
306 }
307 /* create new timeout task (in case core takes too long to respond!) */
308 th->timeout_task = GNUNET_SCHEDULER_add_delayed (h->sched,
309 GNUNET_NO,
310 GNUNET_SCHEDULER_PRIORITY_KEEP,
311 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
312 GNUNET_TIME_absolute_get_remaining
313 (th->timeout),
314 &timeout_request, th);
315 /* remove th from doubly-linked pending list, move to submitted */
316 GNUNET_assert (th->prev == NULL);
317 h->pending_head = th->next;
318 if (th->next == NULL)
319 h->pending_tail = NULL;
320 else
321 th->next->prev = NULL;
322 GNUNET_assert (h->submitted == NULL);
323 h->submitted = th;
324 GNUNET_assert (size >= th->msize);
325 ret = th->get_message (th->get_message_cls, size, buf);
326 GNUNET_assert (ret <= size);
327 return ret;
328}
329
330
331/**
332 * Check the list of pending requests, send the next
333 * one to the core.
334 */
335static void
336trigger_next_request (struct GNUNET_CORE_Handle *h)
337{
338 struct GNUNET_CORE_TransmitHandle *th;
339 if (h->currently_down)
340 return; /* connection temporarily down */
341 if (NULL == (th = h->pending_head))
342 return; /* no requests pending */
343 GNUNET_assert (NULL == h->th);
344 GNUNET_SCHEDULER_cancel (h->sched, th->timeout_task);
345 th->timeout_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
346 h->th = GNUNET_CLIENT_notify_transmit_ready (h->client,
347 th->msize,
348 GNUNET_TIME_absolute_get_remaining
349 (th->timeout), &request_start,
350 h);
351}
352
353
354/**
355 * cls is a pointer to a 32 bit number followed by that
356 * amount of data. If possible, copy to buf and return
357 * number of bytes copied. Always free the buffer.
358 */
359static size_t
360copy_and_free (void *cls, size_t size, void *buf)
361{
362 char *cbuf = cls;
363 uint32_t have;
364
365 memcpy (&have, cbuf, sizeof (uint32_t));
366 if (have > size)
367 {
368 /* timeout / error case */
369 GNUNET_free (cbuf);
370 return 0;
371 }
372 memcpy (buf, cbuf + sizeof (uint32_t), have);
373 GNUNET_free (cbuf);
374 return have;
375}
376
377
378/**
379 * Call bfc callback to solicit traffic for the given peer.
380 */
381static void
382solicit_traffic (struct GNUNET_CORE_Handle *h,
383 const struct GNUNET_PeerIdentity *peer, uint32_t amount)
384{
385 char buf[amount];
386 size_t have;
387 char *cbuf;
388
389 have = h->bfc (h->cls, peer, buf, amount);
390 if (have == 0)
391 return;
392 GNUNET_assert (have >= sizeof (struct GNUNET_MessageHeader));
393 cbuf = GNUNET_malloc (have + sizeof (uint32_t));
394 memcpy (cbuf, &have, sizeof (uint32_t));
395 memcpy (cbuf + sizeof (uint32_t), buf, have);
396 GNUNET_CORE_notify_transmit_ready (h,
397 0,
398 GNUNET_TIME_UNIT_SECONDS,
399 peer, have, &copy_and_free, cbuf);
400}
401
402
403/**
404 * Handler for most messages received from the core.
405 */
406static void
407main_handler (void *cls, const struct GNUNET_MessageHeader *msg)
408{
409 struct GNUNET_CORE_Handle *h = cls;
410 unsigned int hpos;
411 const struct ConnectNotifyMessage *cnm;
412 const struct NotifyTrafficMessage *ntm;
413 const struct ConfigurationInfoMessage *cim;
414 const struct SolicitTrafficMessage *stm;
415 const struct GNUNET_MessageHeader *em;
416 uint16_t msize;
417 uint16_t et;
418 uint32_t ss;
419 const struct GNUNET_CORE_MessageHandler *mh;
420
421 if (msg == NULL)
422 {
423 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
424 _
425 ("Client was disconnected from core service, trying to reconnect.\n"));
426 reconnect (h);
427 return;
428 }
429 msize = ntohs (msg->size);
430 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
431 "Processing message of type %u and size %u from core service\n",
432 ntohs (msg->type), msize);
433 switch (ntohs (msg->type))
434 {
435 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT:
436 if (NULL == h->connects)
437 {
438 GNUNET_break (0);
439 break;
440 }
441 if (msize != sizeof (struct ConnectNotifyMessage))
442 {
443 GNUNET_break (0);
444 break;
445 }
446 cnm = (const struct ConnectNotifyMessage *) msg;
447 break;
448 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT:
449 if (NULL == h->disconnects)
450 {
451 GNUNET_break (0);
452 break;
453 }
454 if (msize != sizeof (struct ConnectNotifyMessage))
455 {
456 GNUNET_break (0);
457 break;
458 }
459 cnm = (const struct ConnectNotifyMessage *) msg;
460 break;
461 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND:
462 if (msize <
463 sizeof (struct NotifyTrafficMessage) +
464 sizeof (struct GNUNET_MessageHeader))
465 {
466 GNUNET_break (0);
467 break;
468 }
469 ntm = (const struct NotifyTrafficMessage *) msg;
470 em = (const struct GNUNET_MessageHeader *) &ntm[1];
471 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
472 "Received message of type %u from peer `%4s'\n",
473 ntohs (em->type), GNUNET_i2s (&ntm->peer));
474 if ((GNUNET_NO == h->inbound_hdr_only) &&
475 (msize != ntohs (em->size) + sizeof (struct NotifyTrafficMessage)))
476 {
477 GNUNET_break (0);
478 break;
479 }
480 et = ntohs (em->type);
481 for (hpos = 0; hpos < h->hcnt; hpos++)
482 {
483 mh = &h->handlers[hpos];
484 if (mh->type != et)
485 continue;
486 if ((mh->expected_size != ntohs (em->size)) &&
487 (mh->expected_size != 0))
488 {
489 GNUNET_break (0);
490 continue;
491 }
492 if (GNUNET_OK !=
493 h->handlers[hpos].callback (h->cls, &ntm->peer, em))
494 {
495 /* error in processing, disconnect ! */
496 reconnect (h);
497 return;
498 }
499 }
500 if (NULL != h->inbound_notify)
501 h->inbound_notify (h->cls, &ntm->peer, em);
502 break;
503 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND:
504 if (msize <
505 sizeof (struct NotifyTrafficMessage) +
506 sizeof (struct GNUNET_MessageHeader))
507 {
508 GNUNET_break (0);
509 break;
510 }
511 ntm = (const struct NotifyTrafficMessage *) msg;
512 em = (const struct GNUNET_MessageHeader *) &ntm[1];
513 if ((GNUNET_NO == h->outbound_hdr_only) &&
514 (msize != ntohs (em->size) + sizeof (struct NotifyTrafficMessage)))
515 {
516 GNUNET_break (0);
517 break;
518 }
519 if (NULL == h->outbound_notify)
520 {
521 GNUNET_break (0);
522 break;
523 }
524 h->outbound_notify (h->cls, &ntm->peer, em);
525 break;
526 case GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO:
527 if (msize != sizeof (struct ConfigurationInfoMessage))
528 {
529 GNUNET_break (0);
530 break;
531 }
532 if (NULL == h->submitted)
533 break;
534 cim = (const struct ConfigurationInfoMessage *) msg;
535
536 /* process configuration data */
537 if (h->submitted->info != NULL)
538 h->submitted->info (h->submitted->info_cls,
539 &h->submitted->peer,
540 ntohl (cim->bpm_in),
541 ntohl (cim->bpm_out),
542 GNUNET_TIME_relative_ntoh (cim->latency),
543 (int) ntohl (cim->reserved_amount),
544 cim->preference);
545 /* done, clean up! */
546 GNUNET_CORE_notify_transmit_ready_cancel (h->submitted);
547 trigger_next_request (h);
548 break;
549 case GNUNET_MESSAGE_TYPE_CORE_SOLICIT_TRAFFIC:
550 if (msize != sizeof (struct SolicitTrafficMessage))
551 {
552 GNUNET_break (0);
553 break;
554 }
555 stm = (const struct SolicitTrafficMessage *) msg;
556 if (NULL == h->bfc)
557 {
558 GNUNET_break (0);
559 break;
560 }
561 ss = ntohl (stm->solicit_size);
562 if ((ss > GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
563 (ss + sizeof (struct SendMessage) > GNUNET_SERVER_MAX_MESSAGE_SIZE))
564 {
565 GNUNET_break (0);
566 break;
567 }
568 solicit_traffic (h, &stm->peer, ss);
569 break;
570 default:
571 GNUNET_break (0);
572 break;
573 }
574 GNUNET_CLIENT_receive (h->client,
575 &main_handler, h, GNUNET_TIME_UNIT_FOREVER_REL);
576}
577
578
579
580/**
581 * Function called when we are ready to transmit our
582 * "START" message (or when this operation timed out).
583 *
584 * @param cls closure
585 * @param size number of bytes available in buf
586 * @param buf where the callee should write the message
587 * @return number of bytes written to buf
588 */
589static size_t transmit_start (void *cls, size_t size, void *buf);
590
591
592/**
593 * Function called on the first message received from
594 * the service (contains our public key, etc.).
595 * Should trigger calling the init callback
596 * and then start our regular message processing.
597 *
598 * @param cls closure
599 * @param msg message received, NULL on timeout or fatal error
600 */
601static void
602init_reply_handler (void *cls, const struct GNUNET_MessageHeader *msg)
603{
604 struct GNUNET_CORE_Handle *h = cls;
605 const struct InitReplyMessage *m;
606 GNUNET_CORE_StartupCallback init;
607 struct GNUNET_PeerIdentity my_identity;
608
609 if ((msg == NULL) ||
610 (ntohs (msg->size) != sizeof (struct InitReplyMessage)) ||
611 (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY))
612 {
613 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
614 _
615 ("Error connecting to core service (failed to receive `%s' message).\n"),
616 "INIT_REPLY");
617 GNUNET_break (msg == NULL);
618 transmit_start (h, 0, NULL);
619 return;
620 }
621 m = (const struct InitReplyMessage *) msg;
622 /* start our message processing loop */
623 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
624 _
625 ("Successfully connected to core service, starting processing loop.\n"));
626 h->currently_down = GNUNET_NO;
627 trigger_next_request (h);
628 GNUNET_CLIENT_receive (h->client,
629 &main_handler, h, GNUNET_TIME_UNIT_FOREVER_REL);
630 if (NULL != (init = h->init))
631 {
632 /* mark so we don't call init on reconnect */
633 h->init = NULL;
634 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
635 _("Successfully connected to core service.\n"));
636 GNUNET_CRYPTO_hash (&m->publicKey,
637 sizeof (struct
638 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
639 &my_identity.hashPubKey);
640 init (h->cls, h, &my_identity, &m->publicKey);
641 }
642}
643
644
645static void
646reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
647{
648 struct GNUNET_CORE_Handle *h = cls;
649 h->reconnect_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
650 reconnect (h);
651}
652
653
654/**
655 * Function called when we are ready to transmit our
656 * "START" message (or when this operation timed out).
657 *
658 * @param cls closure
659 * @param size number of bytes available in buf
660 * @param buf where the callee should write the message
661 * @return number of bytes written to buf
662 */
663static size_t
664transmit_start (void *cls, size_t size, void *buf)
665{
666 struct GNUNET_CORE_Handle *h = cls;
667 struct InitMessage *init;
668 uint16_t *ts;
669 uint16_t msize;
670 uint32_t opt;
671 unsigned int hpos;
672 struct GNUNET_TIME_Relative delay;
673
674 h->th = NULL;
675 if (size == 0)
676 {
677 if ((h->init == NULL) ||
678 (GNUNET_TIME_absolute_get ().value < h->startup_timeout.value))
679 {
680 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
681 _("Failed to connect to core service, retrying.\n"));
682 delay = GNUNET_TIME_absolute_get_remaining (h->startup_timeout);
683 if ((h->init == NULL) || (delay.value > 1000))
684 delay = GNUNET_TIME_UNIT_SECONDS;
685 if (h->init == NULL)
686 h->startup_timeout =
687 GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
688 h->reconnect_task =
689 GNUNET_SCHEDULER_add_delayed (h->sched, GNUNET_NO,
690 GNUNET_SCHEDULER_PRIORITY_IDLE,
691 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
692 delay, &reconnect_task, h);
693 return 0;
694 }
695 /* timeout on initial connect */
696 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
697 _("Failed to connect to core service, giving up.\n"));
698 h->init (h->cls, NULL, NULL, NULL);
699 GNUNET_CORE_disconnect (h);
700 return 0;
701 }
702 msize = h->hcnt * sizeof (uint16_t) + sizeof (struct InitMessage);
703 GNUNET_assert (size >= msize);
704 init = buf;
705 init->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT);
706 init->header.size = htons (msize);
707 opt = GNUNET_CORE_OPTION_NOTHING;
708 if (h->connects != NULL)
709 opt |= GNUNET_CORE_OPTION_SEND_CONNECT;
710 if (h->disconnects != NULL)
711 opt |= GNUNET_CORE_OPTION_SEND_DISCONNECT;
712 if (h->bfc != NULL)
713 opt |= GNUNET_CORE_OPTION_SEND_BFC;
714 if (h->inbound_notify != NULL)
715 {
716 if (h->inbound_hdr_only)
717 opt |= GNUNET_CORE_OPTION_SEND_HDR_INBOUND;
718 else
719 opt |= GNUNET_CORE_OPTION_SEND_FULL_INBOUND;
720 }
721 if (h->outbound_notify != NULL)
722 {
723 if (h->outbound_hdr_only)
724 opt |= GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND;
725 else
726 opt |= GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND;
727 }
728 init->options = htonl (opt);
729 ts = (uint16_t *) & init[1];
730 for (hpos = 0; hpos < h->hcnt; hpos++)
731 ts[hpos] = htons (h->handlers[hpos].type);
732 GNUNET_CLIENT_receive (h->client,
733 &init_reply_handler,
734 h,
735 GNUNET_TIME_absolute_get_remaining (h->
736 startup_timeout));
737 return sizeof (struct InitMessage) + h->hcnt * sizeof (uint16_t);
738}
739
740
741/**
742 * Connect to the core service. Note that the connection may
743 * complete (or fail) asynchronously.
744 *
745 * @param sched scheduler to use
746 * @param cfg configuration to use
747 * @param timeout after how long should we give up trying to connect to the core service?
748 * @param cls closure for the various callbacks that follow (including handlers in the handlers array)
749 * @param init callback to call on timeout or once we have successfully
750 * connected to the core service
751 * @param connects function to call on peer connect, can be NULL
752 * @param disconnects function to call on peer disconnect / timeout, can be NULL
753 * @param bfc function to call to fill up spare bandwidth, can be NULL
754 * @param inbound_notify function to call for all inbound messages, can be NULL
755 * @param inbound_hdr_only set to GNUNET_YES if inbound_notify will only read the
756 * GNUNET_MessageHeader and hence we do not need to give it the full message;
757 * can be used to improve efficiency, ignored if inbound_notify is NULLL
758 * @param outbound_notify function to call for all outbound messages, can be NULL
759 * @param outbound_hdr_only set to GNUNET_YES if outbound_notify will only read the
760 * GNUNET_MessageHeader and hence we do not need to give it the full message
761 * can be used to improve efficiency, ignored if outbound_notify is NULLL
762 * @param handlers callbacks for messages we care about, NULL-terminated
763 */
764void
765GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched,
766 struct GNUNET_CONFIGURATION_Handle *cfg,
767 struct GNUNET_TIME_Relative timeout,
768 void *cls,
769 GNUNET_CORE_StartupCallback init,
770 GNUNET_CORE_ClientEventHandler connects,
771 GNUNET_CORE_ClientEventHandler disconnects,
772 GNUNET_CORE_BufferFillCallback bfc,
773 GNUNET_CORE_MessageCallback inbound_notify,
774 int inbound_hdr_only,
775 GNUNET_CORE_MessageCallback outbound_notify,
776 int outbound_hdr_only,
777 const struct GNUNET_CORE_MessageHandler *handlers)
778{
779 struct GNUNET_CORE_Handle *h;
780
781 GNUNET_assert (init != NULL);
782 h = GNUNET_malloc (sizeof (struct GNUNET_CORE_Handle));
783 h->sched = sched;
784 h->cfg = cfg;
785 h->cls = cls;
786 h->init = init;
787 h->connects = connects;
788 h->disconnects = disconnects;
789 h->bfc = bfc;
790 h->inbound_notify = inbound_notify;
791 h->outbound_notify = outbound_notify;
792 h->inbound_hdr_only = inbound_hdr_only;
793 h->outbound_hdr_only = outbound_hdr_only;
794 h->handlers = handlers;
795 h->client = GNUNET_CLIENT_connect (sched, "core", cfg);
796 h->startup_timeout = GNUNET_TIME_relative_to_absolute (timeout);
797 h->hcnt = 0;
798 while (handlers[h->hcnt].callback != NULL)
799 h->hcnt++;
800 GNUNET_assert (h->hcnt <
801 (GNUNET_SERVER_MAX_MESSAGE_SIZE -
802 sizeof (struct InitMessage)) / sizeof (uint16_t));
803 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
804 "Trying to connect to core service in next %llu ms.\n",
805 timeout.value);
806 h->th =
807 GNUNET_CLIENT_notify_transmit_ready (h->client,
808 sizeof (struct InitMessage) +
809 sizeof (uint16_t) * h->hcnt, timeout,
810 &transmit_start, h);
811}
812
813
814/**
815 * Disconnect from the core service.
816 *
817 * @param handle connection to core to disconnect
818 */
819void
820GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle)
821{
822 if (handle->th != NULL)
823 GNUNET_NETWORK_notify_transmit_ready_cancel (handle->th);
824 if (handle->reconnect_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
825 GNUNET_SCHEDULER_cancel (handle->sched, handle->reconnect_task);
826 GNUNET_CLIENT_disconnect (handle->client);
827 GNUNET_free (handle);
828}
829
830
831/**
832 * Build the configure message.
833 */
834static size_t
835produce_configure_message (void *cls, size_t size, void *buf)
836{
837 struct GNUNET_CORE_TransmitHandle *th = cls;
838 struct GNUNET_CORE_Handle *ch = th->ch;
839
840 if (buf == NULL)
841 {
842 /* communicate handle timeout/error! */
843 if (th->info != NULL)
844 th->info (th->info_cls, NULL, 0, 0, GNUNET_TIME_UNIT_ZERO, 0, 0.0);
845 if (th->timeout_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
846 GNUNET_CORE_notify_transmit_ready_cancel (th);
847 if (ch->submitted == th)
848 ch->submitted = NULL;
849 trigger_next_request (ch);
850 return 0;
851 }
852 GNUNET_assert (size >= sizeof (struct RequestConfigureMessage));
853 memcpy (buf, &th[1], sizeof (struct RequestConfigureMessage));
854 if (th->prev == NULL)
855 ch->pending_head = th->next;
856 else
857 th->prev->next = th->next;
858 if (th->next == NULL)
859 ch->pending_tail = th->prev;
860 else
861 th->next->prev = th->prev;
862 GNUNET_assert (ch->submitted == NULL);
863 ch->submitted = th;
864 return sizeof (struct RequestConfigureMessage);
865}
866
867
868/**
869 * Obtain statistics and/or change preferences for the given peer.
870 *
871 * @param handle connection to core to use
872 * @param peer identifies the peer
873 * @param timeout after how long should we give up (and call "info" with NULL
874 * for "peer" to signal an error)?
875 * @param bpm_out set to the current bandwidth limit (sending) for this peer,
876 * caller should set "bpm_out" to "-1" to avoid changing
877 * the current value; otherwise "bpm_out" will be lowered to
878 * the specified value; passing a pointer to "0" can be used to force
879 * us to disconnect from the peer; "bpm_out" might not increase
880 * as specified since the upper bound is generally
881 * determined by the other peer!
882 * @param amount reserve N bytes for receiving, negative
883 * amounts can be used to undo a (recent) reservation;
884 * @param preference increase incoming traffic share preference by this amount;
885 * in the absence of "amount" reservations, we use this
886 * preference value to assign proportional bandwidth shares
887 * to all connected peers
888 * @param info function to call with the resulting configuration information
889 * @param info_cls closure for info
890 */
891void
892GNUNET_CORE_peer_configure (struct GNUNET_CORE_Handle *handle,
893 const struct GNUNET_PeerIdentity *peer,
894 struct GNUNET_TIME_Relative timeout,
895 unsigned int bpm_out,
896 int amount,
897 double preference,
898 GNUNET_CORE_PeerConfigurationInfoCallback info,
899 void *info_cls)
900{
901 struct RequestConfigureMessage *rcm;
902 struct GNUNET_CORE_TransmitHandle *th;
903
904 th = GNUNET_malloc (sizeof (struct GNUNET_CORE_TransmitHandle) +
905 sizeof (struct RequestConfigureMessage));
906 /* append to list */
907 th->prev = handle->pending_tail;
908 if (handle->pending_tail == NULL)
909 handle->pending_head = th;
910 else
911 handle->pending_tail->next = th;
912 th->ch = handle;
913 th->get_message = &produce_configure_message;
914 th->get_message_cls = th;
915 th->info = info;
916 th->info_cls = info_cls;
917 th->timeout = GNUNET_TIME_relative_to_absolute (timeout);
918 th->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->sched,
919 GNUNET_NO,
920 GNUNET_SCHEDULER_PRIORITY_KEEP,
921 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
922 timeout,
923 &timeout_request, th);
924 th->msize = sizeof (struct RequestConfigureMessage);
925 rcm = (struct RequestConfigureMessage *) &th[1];
926 rcm->header.size = htons (sizeof (struct RequestConfigureMessage));
927 rcm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONFIGURE);
928 rcm->reserved = htonl (0);
929 rcm->limit_outbound_bpm = htonl (bpm_out);
930 rcm->reserve_inbound = htonl (amount);
931 rcm->preference_change = preference;
932 rcm->peer = *peer;
933 if (handle->pending_head == th)
934 trigger_next_request (handle);
935}
936
937
938/**
939 * Build the message requesting data transmission.
940 */
941static size_t
942produce_send (void *cls, size_t size, void *buf)
943{
944 struct GNUNET_CORE_TransmitHandle *th = cls;
945 struct GNUNET_CORE_Handle *h;
946 struct SendMessage *sm;
947 size_t dt;
948 GNUNET_NETWORK_TransmitReadyNotify notify;
949 void *notify_cls;
950
951 h = th->ch;
952 if (buf == NULL)
953 {
954 /* timeout or error */
955 GNUNET_assert (0 == th->notify (th->notify_cls, 0, NULL));
956 if (th->timeout_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
957 GNUNET_CORE_notify_transmit_ready_cancel (th);
958 trigger_next_request (h);
959 return 0;
960 }
961 GNUNET_assert (th->timeout_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK);
962 sm = (struct SendMessage *) buf;
963 sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND);
964 sm->priority = htonl (th->priority);
965 sm->deadline = GNUNET_TIME_absolute_hton (th->timeout);
966 sm->peer = th->peer;
967 notify = th->notify;
968 notify_cls = th->notify_cls;
969 GNUNET_CORE_notify_transmit_ready_cancel (th);
970 trigger_next_request (h);
971 GNUNET_assert (size >= sizeof (struct SendMessage));
972 dt = notify (notify_cls, size - sizeof (struct SendMessage), &sm[1]);
973 sm->header.size = htons (dt + sizeof (struct SendMessage));
974 GNUNET_assert (dt + sizeof (struct SendMessage) < size);
975 return dt + sizeof (struct SendMessage);
976}
977
978
979/**
980 * Ask the core to call "notify" once it is ready to transmit the
981 * given number of bytes to the specified "target". If we are not yet
982 * connected to the specified peer, a call to this function will cause
983 * us to try to establish a connection.
984 *
985 * @param handle connection to core service
986 * @param priority how important is the message?
987 * @param maxdelay how long can the message wait?
988 * @param target who should receive the message,
989 * use NULL for this peer (loopback)
990 * @param notify_size how many bytes of buffer space does notify want?
991 * @param notify function to call when buffer space is available
992 * @param notify_cls closure for notify
993 * @return non-NULL if the notify callback was queued,
994 * NULL if we can not even queue the request (insufficient
995 * memory); if NULL is returned, "notify" will NOT be called.
996 */
997struct GNUNET_CORE_TransmitHandle *
998GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle,
999 unsigned int priority,
1000 struct GNUNET_TIME_Relative maxdelay,
1001 const struct GNUNET_PeerIdentity *target,
1002 size_t notify_size,
1003 GNUNET_NETWORK_TransmitReadyNotify notify,
1004 void *notify_cls)
1005{
1006 struct GNUNET_CORE_TransmitHandle *th;
1007
1008 GNUNET_assert (notify_size + sizeof (struct SendMessage) <
1009 GNUNET_SERVER_MAX_MESSAGE_SIZE);
1010 th = GNUNET_malloc (sizeof (struct GNUNET_CORE_TransmitHandle));
1011 th->ch = handle;
1012 /* append to list */
1013 th->prev = handle->pending_tail;
1014 if (handle->pending_tail == NULL)
1015 handle->pending_head = th;
1016 else
1017 handle->pending_tail->next = th;
1018 th->get_message = &produce_send;
1019 th->get_message_cls = th;
1020 th->notify = notify;
1021 th->notify_cls = notify_cls;
1022 th->peer = *target;
1023 th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay);
1024 th->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->sched,
1025 GNUNET_NO,
1026 GNUNET_SCHEDULER_PRIORITY_KEEP,
1027 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1028 maxdelay,
1029 &timeout_request, th);
1030 th->priority = priority;
1031 th->msize = sizeof (struct SendMessage) + notify_size;
1032 /* was the request queue previously empty? */
1033 if (handle->pending_head == th)
1034 trigger_next_request (handle);
1035 return NULL;
1036}
1037
1038
1039/**
1040 * Cancel the specified transmission-ready notification.
1041 *
1042 * @param h handle that was returned by "notify_transmit_ready".
1043 */
1044void
1045GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle
1046 *h)
1047{
1048 struct GNUNET_CORE_Handle *handle = h->ch;
1049
1050 if (handle->submitted == h)
1051 {
1052 handle->submitted = NULL;
1053 }
1054 else
1055 {
1056 if (h->prev == NULL)
1057 handle->pending_head = h->next;
1058 else
1059 h->prev->next = h->next;
1060 if (h->next == NULL)
1061 handle->pending_tail = h->prev;
1062 else
1063 h->next->prev = h->prev;
1064 }
1065 if (h->timeout_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
1066 GNUNET_SCHEDULER_cancel (handle->sched, h->timeout_task);
1067 GNUNET_free (h);
1068}
1069
1070
1071/* end of core_api.c */
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
new file mode 100644
index 000000000..e9e076bcc
--- /dev/null
+++ b/src/core/gnunet-service-core.c
@@ -0,0 +1,2859 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 core/gnunet-service-core.c
23 * @brief high-level P2P messaging
24 * @author Christian Grothoff
25 *
26 * TODO:
27 * TESTING:
28 * - write test for basic core functions:
29 * + connect to peer
30 * + transmit (encrypted) message [with handshake]
31 * + receive (encrypted) message, forward plaintext to clients
32 * POST-TESTING:
33 * - revisit API (which arguments are used, needed)?
34 * - add code to bound queue size when handling client's SEND message
35 * - add code to bound message queue size when passing messages to clients
36 * - add code to discard_expired_messages
37 * - add code to re-transmit key if first attempt failed
38 * + timeout on connect / key exchange, etc.
39 * + timeout for automatic re-try, etc.
40 * - add code to give up re-transmission of key if many attempts fail
41 * - add code to send PINGs if we are about to time-out otherwise
42 * ? add heuristic to do another send_key in "handle_set_key"
43 * in case previous attempt failed / didn't work / persist
44 * (but don't do it always to avoid storm of SET_KEY's going
45 * back and forth!) --- alternatively, add "status" field
46 * of the other peer to the set key message, that way we'd
47 * know for sure!
48 * - check that hostkey used by transport (for HELLOs) is the
49 * same as the hostkey that we are using!
50 * - free list of clients on exit
51 * - topology management:
52 * + bootstrapping (transport offer hello, plugins)
53 * + internal neighbour selection
54 * + update bandwidth usage statistics
55 * + bandwidth allocation (transport set quota)
56 * - optimize lookup (many O(n) list traversals
57 * could ideally be changed to O(1) hash map lookups)
58 */
59#include "platform.h"
60#include "gnunet_util_lib.h"
61#include "gnunet_hello_lib.h"
62#include "gnunet_peerinfo_service.h"
63#include "gnunet_protocols.h"
64#include "gnunet_signatures.h"
65#include "gnunet_transport_service.h"
66#include "core.h"
67
68
69/**
70 * Receive and send buffer windows grow over time. For
71 * how long can 'unused' bandwidth accumulate before we
72 * need to cap it? (specified in ms).
73 */
74#define MAX_WINDOW_TIME (5 * 60 * 1000)
75
76
77/**
78 * Amount of bytes per minute (in/out) to assume initially
79 * (before either peer has communicated any particular
80 * preference). Should be rather low.
81 */
82#define DEFAULT_BPM_IN_OUT 2048
83
84
85/**
86 * What is the maximum delay for a SET_KEY message?
87 */
88#define MAX_SET_KEY_DELAY GNUNET_TIME_UNIT_SECONDS
89
90
91/**
92 * What how long do we wait for SET_KEY confirmation initially?
93 */
94#define INITIAL_SET_KEY_RETRY_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
95
96
97/**
98 * What is the maximum delay for a PING message?
99 */
100#define MAX_PING_DELAY GNUNET_TIME_UNIT_SECONDS
101
102
103/**
104 * What is the maximum delay for a PONG message?
105 */
106#define MAX_PONG_DELAY GNUNET_TIME_UNIT_SECONDS
107
108
109/**
110 * What is the priority for a SET_KEY message?
111 */
112#define SET_KEY_PRIORITY 0xFFFFFF
113
114
115/**
116 * What is the priority for a PING message?
117 */
118#define PING_PRIORITY 0xFFFFFF
119
120
121/**
122 * What is the priority for a PONG message?
123 */
124#define PONG_PRIORITY 0xFFFFFF
125
126
127/**
128 * What is the maximum age of a message for us to consider
129 * processing it? Note that this looks at the timestamp used
130 * by the other peer, so clock skew between machines does
131 * come into play here. So this should be picked high enough
132 * so that a little bit of clock skew does not prevent peers
133 * from connecting to us.
134 */
135#define MAX_MESSAGE_AGE GNUNET_TIME_UNIT_DAYS
136
137
138/**
139 * What is the maximum size for encrypted messages? Note that this
140 * number imposes a clear limit on the maximum size of any message.
141 * Set to a value close to 64k but not so close that transports will
142 * have trouble with their headers.
143 */
144#define MAX_ENCRYPTED_MESSAGE_SIZE (63 * 1024)
145
146
147/**
148 * State machine for our P2P encryption handshake. Everyone starts in
149 * "DOWN", if we receive the other peer's key (other peer initiated)
150 * we start in state RECEIVED (since we will immediately send our
151 * own); otherwise we start in SENT. If we get back a PONG from
152 * within either state, we move up to CONFIRMED (the PONG will always
153 * be sent back encrypted with the key we sent to the other peer).
154 */
155enum PeerStateMachine
156{
157 PEER_STATE_DOWN,
158 PEER_STATE_KEY_SENT,
159 PEER_STATE_KEY_RECEIVED,
160 PEER_STATE_KEY_CONFIRMED
161};
162
163
164/**
165 * Number of bytes (at the beginning) of "struct EncryptedMessage"
166 * that are NOT encrypted.
167 */
168#define ENCRYPTED_HEADER_SIZE (sizeof(struct GNUNET_MessageHeader) + sizeof(uint32_t) + sizeof(GNUNET_HashCode))
169
170/**
171 * Encapsulation for encrypted messages exchanged between
172 * peers. Followed by the actual encrypted data.
173 */
174struct EncryptedMessage
175{
176 /**
177 * Message type is either CORE_ENCRYPTED_MESSAGE.
178 */
179 struct GNUNET_MessageHeader header;
180
181 /**
182 * Always zero.
183 */
184 uint32_t reserved GNUNET_PACKED;
185
186 /**
187 * Hash of the plaintext, used to verify message integrity;
188 * ALSO used as the IV for the symmetric cipher! Everything
189 * after this hash will be encrypted. ENCRYPTED_HEADER_SIZE
190 * must be set to the offset of the next field.
191 */
192 GNUNET_HashCode plaintext_hash;
193
194 /**
195 * Sequence number, in network byte order. This field
196 * must be the first encrypted/decrypted field and the
197 * first byte that is hashed for the plaintext hash.
198 */
199 uint32_t sequence_number GNUNET_PACKED;
200
201 /**
202 * Desired bandwidth (how much we should send to this
203 * peer / how much is the sender willing to receive),
204 * in bytes per minute.
205 */
206 uint32_t inbound_bpm_limit GNUNET_PACKED;
207
208 /**
209 * Timestamp. Used to prevent reply of ancient messages
210 * (recent messages are caught with the sequence number).
211 */
212 struct GNUNET_TIME_AbsoluteNBO timestamp;
213
214};
215
216/**
217 * We're sending an (encrypted) PING to the other peer to check if he
218 * can decrypt. The other peer should respond with a PONG with the
219 * same content, except this time encrypted with the receiver's key.
220 */
221struct PingMessage
222{
223 /**
224 * Message type is either CORE_PING or CORE_PONG.
225 */
226 struct GNUNET_MessageHeader header;
227
228 /**
229 * Random number chosen to make reply harder.
230 */
231 uint32_t challenge GNUNET_PACKED;
232
233 /**
234 * Intended target of the PING, used primarily to check
235 * that decryption actually worked.
236 */
237 struct GNUNET_PeerIdentity target;
238};
239
240
241/**
242 * Message transmitted to set (or update) a session key.
243 */
244struct SetKeyMessage
245{
246
247 /**
248 * Message type is either CORE_SET_KEY.
249 */
250 struct GNUNET_MessageHeader header;
251
252 /**
253 * Status of the sender (should be in "enum PeerStateMachine"), nbo.
254 */
255 int32_t sender_status GNUNET_PACKED;
256
257 /**
258 * Purpose of the signature, will be
259 * GNUNET_SIGNATURE_PURPOSE_SET_KEY.
260 */
261 struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
262
263 /**
264 * At what time was this key created?
265 */
266 struct GNUNET_TIME_AbsoluteNBO creation_time;
267
268 /**
269 * The encrypted session key.
270 */
271 struct GNUNET_CRYPTO_RsaEncryptedData encrypted_key;
272
273 /**
274 * Who is the intended recipient?
275 */
276 struct GNUNET_PeerIdentity target;
277
278 /**
279 * Signature of the stuff above (starting at purpose).
280 */
281 struct GNUNET_CRYPTO_RsaSignature signature;
282
283};
284
285
286/**
287 * Message waiting for transmission. This struct
288 * is followed by the actual content of the message.
289 */
290struct MessageEntry
291{
292
293 /**
294 * We keep messages in a linked list (for now).
295 */
296 struct MessageEntry *next;
297
298 /**
299 * By when are we supposed to transmit this message?
300 */
301 struct GNUNET_TIME_Absolute deadline;
302
303 /**
304 * How important is this message to us?
305 */
306 unsigned int priority;
307
308 /**
309 * How long is the message? (number of bytes following
310 * the "struct MessageEntry", but not including the
311 * size of "struct MessageEntry" itself!)
312 */
313 uint16_t size;
314
315 /**
316 * Was this message selected for transmission in the
317 * current round? GNUNET_YES or GNUNET_NO.
318 */
319 int16_t do_transmit;
320
321};
322
323
324struct Neighbour
325{
326 /**
327 * We keep neighbours in a linked list (for now).
328 */
329 struct Neighbour *next;
330
331 /**
332 * Unencrypted messages destined for this peer.
333 */
334 struct MessageEntry *messages;
335
336 /**
337 * Head of the batched, encrypted message queue (already ordered,
338 * transmit starting with the head).
339 */
340 struct MessageEntry *encrypted_head;
341
342 /**
343 * Tail of the batched, encrypted message queue (already ordered,
344 * append new messages to tail)
345 */
346 struct MessageEntry *encrypted_tail;
347
348 /**
349 * Handle for pending requests for transmission to this peer
350 * with the transport service. NULL if no request is pending.
351 */
352 struct GNUNET_TRANSPORT_TransmitHandle *th;
353
354 /**
355 * Public key of the neighbour, NULL if we don't have it yet.
356 */
357 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key;
358
359 /**
360 * We received a PING message before we got the "public_key"
361 * (or the SET_KEY). We keep it here until we have a key
362 * to decrypt it. NULL if no PING is pending.
363 */
364 struct PingMessage *pending_ping;
365
366 /**
367 * Identity of the neighbour.
368 */
369 struct GNUNET_PeerIdentity peer;
370
371 /**
372 * Key we use to encrypt our messages for the other peer
373 * (initialized by us when we do the handshake).
374 */
375 struct GNUNET_CRYPTO_AesSessionKey encrypt_key;
376
377 /**
378 * Key we use to decrypt messages from the other peer
379 * (given to us by the other peer during the handshake).
380 */
381 struct GNUNET_CRYPTO_AesSessionKey decrypt_key;
382
383 /**
384 * ID of task used for re-trying plaintext scheduling.
385 */
386 GNUNET_SCHEDULER_TaskIdentifier retry_plaintext_task;
387
388 /**
389 * ID of task used for re-trying SET_KEY and PING message.
390 */
391 GNUNET_SCHEDULER_TaskIdentifier retry_set_key_task;
392
393 /**
394 * At what time did we generate our encryption key?
395 */
396 struct GNUNET_TIME_Absolute encrypt_key_created;
397
398 /**
399 * At what time did the other peer generate the decryption key?
400 */
401 struct GNUNET_TIME_Absolute decrypt_key_created;
402
403 /**
404 * At what time did we initially establish (as in, complete session
405 * key handshake) this connection? Should be zero if status != KEY_CONFIRMED.
406 */
407 struct GNUNET_TIME_Absolute time_established;
408
409 /**
410 * At what time did we last receive an encrypted message from the
411 * other peer? Should be zero if status != KEY_CONFIRMED.
412 */
413 struct GNUNET_TIME_Absolute last_activity;
414
415 /**
416 * Last latency observed from this peer.
417 */
418 struct GNUNET_TIME_Relative last_latency;
419
420 /**
421 * At what frequency are we currently re-trying SET KEY messages?
422 */
423 struct GNUNET_TIME_Relative set_key_retry_frequency;
424
425 /**
426 * Time of our last update to the "available_send_window".
427 */
428 struct GNUNET_TIME_Absolute last_asw_update;
429
430 /**
431 * Time of our last update to the "available_recv_window".
432 */
433 struct GNUNET_TIME_Absolute last_arw_update;
434
435 /**
436 * Number of bytes that we are eligible to transmit to this
437 * peer at this point. Incremented every minute by max_out_bpm,
438 * bounded by max_bpm (no back-log larger than MAX_BUF_FACT minutes,
439 * bandwidth-hogs are sampled at a frequency of about 78s!);
440 * may get negative if we have VERY high priority content.
441 */
442 long long available_send_window;
443
444 /**
445 * How much downstream capacity of this peer has been reserved for
446 * our traffic? (Our clients can request that a certain amount of
447 * bandwidth is available for replies to them; this value is used to
448 * make sure that this reserved amount of bandwidth is actually
449 * available).
450 */
451 long long available_recv_window;
452
453 /**
454 * How valueable were the messages of this peer recently?
455 */
456 double current_preference;
457
458 /**
459 * Bit map indicating which of the 32 sequence numbers before the last
460 * were received (good for accepting out-of-order packets and
461 * estimating reliability of the connection)
462 */
463 unsigned int last_packets_bitmap;
464
465 /**
466 * Number of messages in the message queue for this peer.
467 */
468 unsigned int message_queue_size;
469
470 /**
471 * last sequence number received on this connection (highest)
472 */
473 uint32_t last_sequence_number_received;
474
475 /**
476 * last sequence number transmitted
477 */
478 uint32_t last_sequence_number_sent;
479
480 /**
481 * Available bandwidth in for this peer (current target).
482 */
483 uint32_t bpm_in;
484
485 /**
486 * Available bandwidth out for this peer (current target).
487 */
488 uint32_t bpm_out;
489
490 /**
491 * Internal bandwidth limit set for this peer (initially
492 * typcially set to "-1"). "bpm_out" is MAX of
493 * "bpm_out_internal_limit" and "bpm_out_external_limit".
494 */
495 uint32_t bpm_out_internal_limit;
496
497 /**
498 * External bandwidth limit set for this peer by the
499 * peer that we are communicating with. "bpm_out" is MAX of
500 * "bpm_out_internal_limit" and "bpm_out_external_limit".
501 */
502 uint32_t bpm_out_external_limit;
503
504 /**
505 * What was our PING challenge number?
506 */
507 uint32_t ping_challenge;
508
509 /**
510 * What is our connection status?
511 */
512 enum PeerStateMachine status;
513
514};
515
516
517/**
518 * Events are messages for clients. The struct
519 * itself is followed by the actual message.
520 */
521struct Event
522{
523 /**
524 * This is a linked list.
525 */
526 struct Event *next;
527
528 /**
529 * Size of the message.
530 */
531 size_t size;
532
533 /**
534 * Could this event be dropped if this queue
535 * is getting too large? (NOT YET USED!)
536 */
537 int can_drop;
538
539};
540
541
542/**
543 * Data structure for each client connected to the core service.
544 */
545struct Client
546{
547 /**
548 * Clients are kept in a linked list.
549 */
550 struct Client *next;
551
552 /**
553 * Handle for the client with the server API.
554 */
555 struct GNUNET_SERVER_Client *client_handle;
556
557 /**
558 * Linked list of messages we still need to deliver to
559 * this client.
560 */
561 struct Event *event_head;
562
563 /**
564 * Tail of the linked list of events.
565 */
566 struct Event *event_tail;
567
568 /**
569 * Current transmit handle, NULL if no transmission request
570 * is pending.
571 */
572 struct GNUNET_NETWORK_TransmitHandle *th;
573
574 /**
575 * Array of the types of messages this peer cares
576 * about (with "tcnt" entries). Allocated as part
577 * of this client struct, do not free!
578 */
579 uint16_t *types;
580
581 /**
582 * Options for messages this client cares about,
583 * see GNUNET_CORE_OPTION_ values.
584 */
585 uint32_t options;
586
587 /**
588 * Number of types of incoming messages this client
589 * specifically cares about. Size of the "types" array.
590 */
591 unsigned int tcnt;
592
593};
594
595
596/**
597 * Our public key.
598 */
599static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key;
600
601/**
602 * Our identity.
603 */
604static struct GNUNET_PeerIdentity my_identity;
605
606/**
607 * Our private key.
608 */
609static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key;
610
611/**
612 * Our scheduler.
613 */
614struct GNUNET_SCHEDULER_Handle *sched;
615
616/**
617 * Our configuration.
618 */
619struct GNUNET_CONFIGURATION_Handle *cfg;
620
621/**
622 * Our server.
623 */
624static struct GNUNET_SERVER_Handle *server;
625
626/**
627 * Transport service.
628 */
629static struct GNUNET_TRANSPORT_Handle *transport;
630
631/**
632 * We keep neighbours in a linked list (for now).
633 */
634static struct Neighbour *neighbours;
635
636/**
637 * Linked list of our clients.
638 */
639static struct Client *clients;
640
641
642/**
643 * Recalculate the number of bytes we expect to
644 * receive or transmit in a given window.
645 *
646 * @param window pointer to the byte counter (updated)
647 * @param ts pointer to the timestamp (updated)
648 * @param bpm number of bytes per minute that should
649 * be added to the window.
650 */
651static void
652update_window (long long *window,
653 struct GNUNET_TIME_Absolute *ts, unsigned int bpm)
654{
655 struct GNUNET_TIME_Relative since;
656
657 since = GNUNET_TIME_absolute_get_duration (*ts);
658 if (since.value < 60 * 1000)
659 return; /* not even a minute has passed */
660 *ts = GNUNET_TIME_absolute_get ();
661 *window += (bpm * since.value) / 60 / 1000;
662 if (*window > MAX_WINDOW_TIME * bpm)
663 *window = MAX_WINDOW_TIME * bpm;
664}
665
666
667/**
668 * Find the entry for the given neighbour.
669 *
670 * @param peer identity of the neighbour
671 * @return NULL if we are not connected, otherwise the
672 * neighbour's entry.
673 */
674static struct Neighbour *
675find_neighbour (const struct GNUNET_PeerIdentity *peer)
676{
677 struct Neighbour *ret;
678
679 ret = neighbours;
680 while ((ret != NULL) &&
681 (0 != memcmp (&ret->peer,
682 peer, sizeof (struct GNUNET_PeerIdentity))))
683 ret = ret->next;
684 return ret;
685}
686
687
688/**
689 * Find the entry for the given client.
690 *
691 * @param client handle for the client
692 * @return NULL if we are not connected, otherwise the
693 * client's struct.
694 */
695static struct Client *
696find_client (const struct GNUNET_SERVER_Client *client)
697{
698 struct Client *ret;
699
700 ret = clients;
701 while ((ret != NULL) && (client != ret->client_handle))
702 ret = ret->next;
703 return ret;
704}
705
706
707/**
708 * If necessary, initiate a request with the server to
709 * transmit messages from the queue of the given client.
710 * @param client who to transfer messages to
711 */
712static void request_transmit (struct Client *client);
713
714
715/**
716 * Client is ready to receive data, provide it.
717 * @param cls closure
718 * @param size number of bytes available in buf
719 * @param buf where the callee should write the message
720 * @return number of bytes written to buf
721 */
722static size_t
723do_client_transmit (void *cls, size_t size, void *buf)
724{
725 struct Client *client = cls;
726 struct Event *e;
727 char *tgt;
728 size_t ret;
729
730 client->th = NULL;
731 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
732 "Client ready to receive %u bytes.\n", size);
733 if (buf == NULL)
734 {
735 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
736 "Failed to transmit data to client (disconnect)?\n");
737 return 0; /* we'll surely get a disconnect soon... */
738 }
739 tgt = buf;
740 ret = 0;
741 while ((NULL != (e = client->event_head)) && (e->size <= size))
742 {
743 memcpy (&tgt[ret], &e[1], e->size);
744 size -= e->size;
745 ret += e->size;
746 client->event_head = e->next;
747 GNUNET_free (e);
748 }
749 GNUNET_assert (ret > 0);
750 if (client->event_head == NULL)
751 client->event_tail = NULL;
752 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
753 "Transmitting %u bytes to client\n", ret);
754 request_transmit (client);
755 return ret;
756}
757
758
759/**
760 * If necessary, initiate a request with the server to
761 * transmit messages from the queue of the given client.
762 * @param client who to transfer messages to
763 */
764static void
765request_transmit (struct Client *client)
766{
767
768 if (NULL != client->th)
769 return; /* already pending */
770 if (NULL == client->event_head)
771 return; /* no more events pending */
772 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
773 "Asking server to transmit %u bytes to client\n",
774 client->event_head->size);
775 client->th
776 = GNUNET_SERVER_notify_transmit_ready (client->client_handle,
777 client->event_head->size,
778 GNUNET_TIME_UNIT_FOREVER_REL,
779 &do_client_transmit, client);
780}
781
782
783/**
784 * Send a message to one of our clients.
785 * @param client target for the message
786 * @param msg message to transmit
787 * @param can_drop could this message be dropped if the
788 * client's queue is getting too large?
789 */
790static void
791send_to_client (struct Client *client,
792 const struct GNUNET_MessageHeader *msg, int can_drop)
793{
794 struct Event *e;
795 uint16_t msize;
796
797 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
798 "Preparing to send message of type %u to client.\n",
799 ntohs (msg->type));
800 msize = ntohs (msg->size);
801 e = GNUNET_malloc (sizeof (struct Event) + msize);
802 /* append */
803 if (client->event_tail != NULL)
804 client->event_tail->next = e;
805 else
806 client->event_head = e;
807 client->event_tail = e;
808 e->can_drop = can_drop;
809 e->size = msize;
810 memcpy (&e[1], msg, msize);
811 request_transmit (client);
812}
813
814
815/**
816 * Send a message to all of our current clients.
817 */
818static void
819send_to_all_clients (const struct GNUNET_MessageHeader *msg, int can_drop)
820{
821 struct Client *c;
822
823 c = clients;
824 while (c != NULL)
825 {
826 send_to_client (c, msg, can_drop);
827 c = c->next;
828 }
829}
830
831
832/**
833 * Handle CORE_INIT request.
834 */
835static void
836handle_client_init (void *cls,
837 struct GNUNET_SERVER_Handle *server,
838 struct GNUNET_SERVER_Client *client,
839 const struct GNUNET_MessageHeader *message)
840{
841 const struct InitMessage *im;
842 struct InitReplyMessage irm;
843 struct Client *c;
844 uint16_t msize;
845 const uint16_t *types;
846 struct Neighbour *n;
847 struct ConnectNotifyMessage cnm;
848
849 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
850 "Client connecting to core service with `%s' message\n",
851 "INIT");
852 /* check that we don't have an entry already */
853 c = clients;
854 while (c != NULL)
855 {
856 if (client == c->client_handle)
857 {
858 GNUNET_break (0);
859 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
860 return;
861 }
862 c = c->next;
863 }
864 msize = ntohs (message->size);
865 if (msize < sizeof (struct InitMessage))
866 {
867 GNUNET_break (0);
868 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
869 return;
870 }
871 im = (const struct InitMessage *) message;
872 types = (const uint16_t *) &im[1];
873 msize -= sizeof (struct InitMessage);
874 c = GNUNET_malloc (sizeof (struct Client) + msize);
875 c->client_handle = client;
876 c->next = clients;
877 clients = c;
878 memcpy (&c[1], types, msize);
879 c->types = (uint16_t *) & c[1];
880 c->options = ntohl (im->options);
881 c->tcnt = msize / sizeof (uint16_t);
882 /* send init reply message */
883 irm.header.size = htons (sizeof (struct InitReplyMessage));
884 irm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY);
885 irm.reserved = htonl (0);
886 memcpy (&irm.publicKey,
887 &my_public_key,
888 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
889 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
890 "Sending `%s' message to client.\n", "INIT_REPLY");
891 send_to_client (c, &irm.header, GNUNET_NO);
892 /* notify new client about existing neighbours */
893 cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
894 cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
895 n = neighbours;
896 while (n != NULL)
897 {
898 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
899 "Sending `%s' message to client.\n", "NOTIFY_CONNECT");
900 cnm.bpm_available = htonl (n->bpm_out);
901 cnm.last_activity = GNUNET_TIME_absolute_hton (n->last_activity);
902 cnm.peer = n->peer;
903 send_to_client (c, &cnm.header, GNUNET_NO);
904 n = n->next;
905 }
906 GNUNET_SERVER_receive_done (client, GNUNET_OK);
907}
908
909
910/**
911 * A client disconnected, clean up.
912 *
913 * @param cls closure
914 * @param client identification of the client
915 */
916static void
917handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
918{
919 struct Client *pos;
920 struct Client *prev;
921
922 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
923 "Client has disconnected from core service.\n");
924 prev = NULL;
925 pos = clients;
926 while (pos != NULL)
927 {
928 if (client == pos->client_handle)
929 {
930 if (prev == NULL)
931 clients = pos->next;
932 else
933 prev->next = pos->next;
934 if (pos->th != NULL)
935 GNUNET_NETWORK_notify_transmit_ready_cancel (pos->th);
936 GNUNET_free (pos);
937 return;
938 }
939 prev = pos;
940 pos = pos->next;
941 }
942 /* client never sent INIT */
943}
944
945
946/**
947 * Handle REQUEST_CONFIGURE request.
948 */
949static void
950handle_client_request_configure (void *cls,
951 struct GNUNET_SERVER_Handle *server,
952 struct GNUNET_SERVER_Client *client,
953 const struct GNUNET_MessageHeader *message)
954{
955 const struct RequestConfigureMessage *rcm;
956 struct Neighbour *n;
957 struct ConfigurationInfoMessage cim;
958 struct Client *c;
959 int reserv;
960
961 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
962 "Core service receives `%s' request.\n", "CONFIGURE");
963 rcm = (const struct RequestConfigureMessage *) message;
964 n = find_neighbour (&rcm->peer);
965 memset (&cim, 0, sizeof (cim));
966 if ((n != NULL) && (n->status == PEER_STATE_KEY_CONFIRMED))
967 {
968 n->bpm_out_internal_limit = ntohl (rcm->limit_outbound_bpm);
969 n->bpm_out = GNUNET_MAX (n->bpm_out_internal_limit,
970 n->bpm_out_external_limit);
971 reserv = ntohl (rcm->reserve_inbound);
972 if (reserv < 0)
973 {
974 n->available_recv_window += reserv;
975 }
976 else if (reserv > 0)
977 {
978 update_window (&n->available_recv_window,
979 &n->last_arw_update, n->bpm_in);
980 if (n->available_recv_window < reserv)
981 reserv = n->available_recv_window;
982 n->available_recv_window -= reserv;
983 }
984 n->current_preference += rcm->preference_change;
985 if (n->current_preference < 0)
986 n->current_preference = 0;
987 cim.reserved_amount = htonl (reserv);
988 cim.bpm_in = htonl (n->bpm_in);
989 cim.bpm_out = htonl (n->bpm_out);
990 cim.latency = GNUNET_TIME_relative_hton (n->last_latency);
991 cim.preference = n->current_preference;
992 }
993 cim.header.size = htons (sizeof (struct ConfigurationInfoMessage));
994 cim.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO);
995 cim.peer = rcm->peer;
996 c = find_client (client);
997 if (c == NULL)
998 {
999 GNUNET_break (0);
1000 return;
1001 }
1002 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1003 "Sending `%s' message to client.\n", "CONFIGURATION_INFO");
1004 send_to_client (c, &cim.header, GNUNET_NO);
1005}
1006
1007
1008/**
1009 * Check if we have encrypted messages for the specified neighbour
1010 * pending, and if so, check with the transport about sending them
1011 * out.
1012 *
1013 * @param n neighbour to check.
1014 */
1015static void process_encrypted_neighbour_queue (struct Neighbour *n);
1016
1017
1018/**
1019 * Function called when the transport service is ready to
1020 * receive an encrypted message for the respective peer
1021 *
1022 * @param cls neighbour to use message from
1023 * @param size number of bytes we can transmit
1024 * @param buf where to copy the message
1025 * @return number of bytes transmitted
1026 */
1027static size_t
1028notify_encrypted_transmit_ready (void *cls, size_t size, void *buf)
1029{
1030 struct Neighbour *n = cls;
1031 struct MessageEntry *m;
1032 size_t ret;
1033 char *cbuf;
1034
1035 n->th = NULL;
1036 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1037 "Transport ready to receive %u bytes for `%4s'\n",
1038 size, GNUNET_i2s (&n->peer));
1039 GNUNET_assert (NULL != (m = n->encrypted_head));
1040 n->encrypted_head = m->next;
1041 if (m->next == NULL)
1042 n->encrypted_tail = NULL;
1043 ret = 0;
1044 cbuf = buf;
1045 if (buf != NULL)
1046 {
1047 GNUNET_assert (size >= m->size);
1048 memcpy (cbuf, &m[1], m->size);
1049 ret = m->size;
1050 process_encrypted_neighbour_queue (n);
1051 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1052 "Copied message of type %u and size %u into transport buffer for `%4s'\n",
1053 ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
1054 ret, GNUNET_i2s (&n->peer));
1055 }
1056 else
1057 {
1058 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1059 "Transmission for message of type %u and size %u failed\n",
1060 ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
1061 m->size);
1062 }
1063 GNUNET_free (m);
1064 return ret;
1065}
1066
1067
1068/**
1069 * Check if we have plaintext messages for the specified neighbour
1070 * pending, and if so, consider batching and encrypting them (and
1071 * then trigger processing of the encrypted queue if needed).
1072 *
1073 * @param n neighbour to check.
1074 */
1075static void process_plaintext_neighbour_queue (struct Neighbour *n);
1076
1077
1078/**
1079 * Check if we have encrypted messages for the specified neighbour
1080 * pending, and if so, check with the transport about sending them
1081 * out.
1082 *
1083 * @param n neighbour to check.
1084 */
1085static void
1086process_encrypted_neighbour_queue (struct Neighbour *n)
1087{
1088 if (n->th != NULL)
1089 {
1090 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1091 "Asked to process encrypted queue, but request already pending.\n");
1092 return; /* already pending */
1093 }
1094 if (n->encrypted_head == NULL)
1095 {
1096 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1097 "Encrypted queue empty, trying plaintext queue instead.\n");
1098 process_plaintext_neighbour_queue (n);
1099 return;
1100 }
1101 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1102 "Asking transport for transmission of %u bytes to `%4s' in next %llu ms\n",
1103 n->encrypted_head->size,
1104 GNUNET_i2s (&n->peer),
1105 GNUNET_TIME_absolute_get_remaining (n->encrypted_head->
1106 deadline).value);
1107 n->th =
1108 GNUNET_TRANSPORT_notify_transmit_ready (transport, &n->peer,
1109 n->encrypted_head->size,
1110 GNUNET_TIME_absolute_get_remaining
1111 (n->encrypted_head->deadline),
1112 &notify_encrypted_transmit_ready,
1113 n);
1114 if (n->th == NULL)
1115 {
1116 /* message request too large (oops) */
1117 GNUNET_break (0);
1118 /* FIXME: handle error somehow! */
1119 }
1120}
1121
1122
1123/**
1124 * Decrypt size bytes from in and write the result to out. Use the
1125 * key for inbound traffic of the given neighbour. This function does
1126 * NOT do any integrity-checks on the result.
1127 *
1128 * @param n neighbour we are receiving from
1129 * @param iv initialization vector to use
1130 * @param in ciphertext
1131 * @param out plaintext
1132 * @param size size of in/out
1133 * @return GNUNET_OK on success
1134 */
1135static int
1136do_decrypt (struct Neighbour *n,
1137 const GNUNET_HashCode * iv,
1138 const void *in, void *out, size_t size)
1139{
1140 if (size != (uint16_t) size)
1141 {
1142 GNUNET_break (0);
1143 return GNUNET_NO;
1144 }
1145 if ((n->status != PEER_STATE_KEY_RECEIVED) &&
1146 (n->status != PEER_STATE_KEY_CONFIRMED))
1147 {
1148 GNUNET_break_op (0);
1149 return GNUNET_SYSERR;
1150 }
1151 if (size !=
1152 GNUNET_CRYPTO_aes_decrypt (&n->decrypt_key,
1153 in,
1154 (uint16_t) size,
1155 (const struct
1156 GNUNET_CRYPTO_AesInitializationVector *) iv,
1157 out))
1158 {
1159 GNUNET_break (0);
1160 return GNUNET_SYSERR;
1161 }
1162 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1163 "Decrypted %u bytes from `%4s' using key %u\n",
1164 size, GNUNET_i2s (&n->peer), n->decrypt_key.crc32);
1165 return GNUNET_OK;
1166}
1167
1168
1169/**
1170 * Encrypt size bytes from in and write the result to out. Use the
1171 * key for outbound traffic of the given neighbour.
1172 *
1173 * @param n neighbour we are sending to
1174 * @param iv initialization vector to use
1175 * @param in ciphertext
1176 * @param out plaintext
1177 * @param size size of in/out
1178 * @return GNUNET_OK on success
1179 */
1180static int
1181do_encrypt (struct Neighbour *n,
1182 const GNUNET_HashCode * iv,
1183 const void *in, void *out, size_t size)
1184{
1185 if (size != (uint16_t) size)
1186 {
1187 GNUNET_break (0);
1188 return GNUNET_NO;
1189 }
1190 GNUNET_assert (size ==
1191 GNUNET_CRYPTO_aes_encrypt (in,
1192 (uint16_t) size,
1193 &n->encrypt_key,
1194 (const struct
1195 GNUNET_CRYPTO_AesInitializationVector
1196 *) iv, out));
1197 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1198 "Encrypted %u bytes for `%4s' using key %u\n", size,
1199 GNUNET_i2s (&n->peer), n->encrypt_key.crc32);
1200 return GNUNET_OK;
1201}
1202
1203
1204/**
1205 * Select messages for transmission. This heuristic uses a combination
1206 * of earliest deadline first (EDF) scheduling (with bounded horizon)
1207 * and priority-based discard (in case no feasible schedule exist) and
1208 * speculative optimization (defer any kind of transmission until
1209 * we either create a batch of significant size, 25% of max, or until
1210 * we are close to a deadline). Furthermore, when scheduling the
1211 * heuristic also packs as many messages into the batch as possible,
1212 * starting with those with the earliest deadline. Yes, this is fun.
1213 *
1214 * @param n neighbour to select messages from
1215 * @param size number of bytes to select for transmission
1216 * @param retry_time set to the time when we should try again
1217 * (only valid if this function returns zero)
1218 * @return number of bytes selected, or 0 if we decided to
1219 * defer scheduling overall; in that case, retry_time is set.
1220 */
1221static size_t
1222select_messages (struct Neighbour *n,
1223 size_t size, struct GNUNET_TIME_Relative *retry_time)
1224{
1225 struct MessageEntry *pos;
1226 struct MessageEntry *min;
1227 struct MessageEntry *last;
1228 unsigned int min_prio;
1229 struct GNUNET_TIME_Absolute t;
1230 struct GNUNET_TIME_Absolute now;
1231 uint64_t delta;
1232 uint64_t avail;
1233 unsigned long long slack; /* how long could we wait before missing deadlines? */
1234 size_t off;
1235 int discard_low_prio;
1236
1237 GNUNET_assert (NULL != n->messages);
1238 now = GNUNET_TIME_absolute_get ();
1239 /* last entry in linked list of messages processed */
1240 last = NULL;
1241 /* should we remove the entry with the lowest
1242 priority from consideration for scheduling at the
1243 end of the loop? */
1244 discard_low_prio = GNUNET_YES;
1245 while (GNUNET_YES == discard_low_prio)
1246 {
1247 min = NULL;
1248 min_prio = -1;
1249 discard_low_prio = GNUNET_NO;
1250 /* number of bytes available for transmission at time "t" */
1251 avail = n->available_send_window;
1252 t = n->last_asw_update;
1253 /* how many bytes have we (hyptothetically) scheduled so far */
1254 off = 0;
1255 /* maximum time we can wait before transmitting anything
1256 and still make all of our deadlines */
1257 slack = -1;
1258
1259 pos = n->messages;
1260 /* note that we use "*2" here because we want to look
1261 a bit further into the future; much more makes no
1262 sense since new message might be scheduled in the
1263 meantime... */
1264 while ((pos != NULL) && (off < size * 2))
1265 {
1266 if (pos->do_transmit == GNUNET_YES)
1267 {
1268 /* already removed from consideration */
1269 pos = pos->next;
1270 continue;
1271 }
1272 if (discard_low_prio == GNUNET_NO)
1273 {
1274 delta = pos->deadline.value;
1275 if (delta < t.value)
1276 delta = 0;
1277 else
1278 delta = t.value - delta;
1279 avail += delta * n->bpm_out / 1000 / 60;
1280 if (avail < pos->size)
1281 {
1282 discard_low_prio = GNUNET_YES; /* we could not schedule this one! */
1283 }
1284 else
1285 {
1286 avail -= pos->size;
1287 /* update slack, considering both its absolute deadline
1288 and relative deadlines caused by other messages
1289 with their respective load */
1290 slack = GNUNET_MIN (slack, avail / n->bpm_out);
1291 if (pos->deadline.value < now.value)
1292 slack = 0;
1293 else
1294 slack =
1295 GNUNET_MIN (slack, pos->deadline.value - now.value);
1296 }
1297 }
1298 off += pos->size;
1299 t.value = GNUNET_MAX (pos->deadline.value, t.value);
1300 if (pos->priority <= min_prio)
1301 {
1302 /* update min for discard */
1303 min_prio = pos->priority;
1304 min = pos;
1305 }
1306 pos = pos->next;
1307 }
1308 if (discard_low_prio)
1309 {
1310 /* remove lowest-priority entry from consideration */
1311 min->do_transmit = GNUNET_YES; /* means: discard (for now) */
1312 }
1313 last = pos;
1314 }
1315 /* guard against sending "tiny" messages with large headers without
1316 urgent deadlines */
1317 if ((slack > 1000) && (size > 4 * off))
1318 {
1319 /* less than 25% of message would be filled with
1320 deadlines still being met if we delay by one
1321 second or more; so just wait for more data */
1322 retry_time->value = slack / 2;
1323 /* reset do_transmit values for next time */
1324 while (pos != last)
1325 {
1326 pos->do_transmit = GNUNET_NO;
1327 pos = pos->next;
1328 }
1329 return 0;
1330 }
1331 /* select marked messages (up to size) for transmission */
1332 off = 0;
1333 pos = n->messages;
1334 while (pos != last)
1335 {
1336 if ((pos->size <= size) && (pos->do_transmit == GNUNET_NO))
1337 {
1338 pos->do_transmit = GNUNET_YES; /* mark for transmission */
1339 off += pos->size;
1340 size -= pos->size;
1341 }
1342 else
1343 pos->do_transmit = GNUNET_NO; /* mark for not transmitting! */
1344 pos = pos->next;
1345 }
1346 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1347 "Selected %u bytes of plaintext messages for transmission to `%4s'.\n",
1348 off, GNUNET_i2s (&n->peer));
1349 return off;
1350}
1351
1352
1353/**
1354 * Batch multiple messages into a larger buffer.
1355 *
1356 * @param n neighbour to take messages from
1357 * @param buf target buffer
1358 * @param size size of buf
1359 * @param deadline set to transmission deadline for the result
1360 * @param retry_time set to the time when we should try again
1361 * (only valid if this function returns zero)
1362 * @param priority set to the priority of the batch
1363 * @return number of bytes written to buf (can be zero)
1364 */
1365static size_t
1366batch_message (struct Neighbour *n,
1367 char *buf,
1368 size_t size,
1369 struct GNUNET_TIME_Absolute *deadline,
1370 struct GNUNET_TIME_Relative *retry_time,
1371 unsigned int *priority)
1372{
1373 struct MessageEntry *pos;
1374 struct MessageEntry *prev;
1375 struct MessageEntry *next;
1376 size_t ret;
1377
1378 ret = 0;
1379 *priority = 0;
1380 *deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
1381 *retry_time = GNUNET_TIME_UNIT_FOREVER_REL;
1382 if (0 == select_messages (n, size, retry_time))
1383 {
1384 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1385 "No messages selected, will try again in %llu ms\n",
1386 retry_time->value);
1387 return 0;
1388 }
1389 pos = n->messages;
1390 prev = NULL;
1391 while ((pos != NULL) && (size >= sizeof (struct GNUNET_MessageHeader)))
1392 {
1393 next = pos->next;
1394 if (GNUNET_YES == pos->do_transmit)
1395 {
1396 GNUNET_assert (pos->size <= size);
1397 memcpy (&buf[ret], &pos[1], pos->size);
1398 ret += pos->size;
1399 size -= pos->size;
1400 *priority += pos->priority;
1401 deadline->value = GNUNET_MIN (deadline->value, pos->deadline.value);
1402 GNUNET_free (pos);
1403 if (prev == NULL)
1404 n->messages = next;
1405 else
1406 prev->next = next;
1407 }
1408 else
1409 {
1410 prev = pos;
1411 }
1412 pos = next;
1413 }
1414 return ret;
1415}
1416
1417
1418/**
1419 * Remove messages with deadlines that have long expired from
1420 * the queue.
1421 *
1422 * @param n neighbour to inspect
1423 */
1424static void
1425discard_expired_messages (struct Neighbour *n)
1426{
1427 /* FIXME */
1428}
1429
1430
1431/**
1432 * Signature of the main function of a task.
1433 *
1434 * @param cls closure
1435 * @param tc context information (why was this task triggered now)
1436 */
1437static void
1438retry_plaintext_processing (void *cls,
1439 const struct GNUNET_SCHEDULER_TaskContext *tc)
1440{
1441 struct Neighbour *n = cls;
1442
1443 n->retry_plaintext_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1444 process_plaintext_neighbour_queue (n);
1445}
1446
1447
1448/**
1449 * Send our key (and encrypted PING) to the other peer.
1450 *
1451 * @param n the other peer
1452 */
1453static void send_key (struct Neighbour *n);
1454
1455
1456/**
1457 * Check if we have plaintext messages for the specified neighbour
1458 * pending, and if so, consider batching and encrypting them (and
1459 * then trigger processing of the encrypted queue if needed).
1460 *
1461 * @param n neighbour to check.
1462 */
1463static void
1464process_plaintext_neighbour_queue (struct Neighbour *n)
1465{
1466 char pbuf[MAX_ENCRYPTED_MESSAGE_SIZE]; /* plaintext */
1467 size_t used;
1468 size_t esize;
1469 struct EncryptedMessage *em; /* encrypted message */
1470 struct EncryptedMessage *ph; /* plaintext header */
1471 struct MessageEntry *me;
1472 unsigned int priority;
1473 struct GNUNET_TIME_Absolute deadline;
1474 struct GNUNET_TIME_Relative retry_time;
1475
1476 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1477 "Processing plaintext message queue for `%4s', scheduling messages.\n",
1478 GNUNET_i2s (&n->peer));
1479 if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
1480 {
1481 GNUNET_SCHEDULER_cancel (sched, n->retry_plaintext_task);
1482 n->retry_plaintext_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1483 }
1484 switch (n->status)
1485 {
1486 case PEER_STATE_DOWN:
1487 send_key (n);
1488 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1489 "Not yet connected, deferring processing of plaintext messages.\n");
1490 return;
1491 case PEER_STATE_KEY_SENT:
1492 GNUNET_assert (n->retry_set_key_task !=
1493 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK);
1494 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1495 "Not yet connected, deferring processing of plaintext messages.\n");
1496 return;
1497 case PEER_STATE_KEY_RECEIVED:
1498 GNUNET_assert (n->retry_set_key_task !=
1499 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK);
1500 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1501 "Not yet connected, deferring processing of plaintext messages.\n");
1502 return;
1503 case PEER_STATE_KEY_CONFIRMED:
1504 /* ready to continue */
1505 break;
1506 }
1507 if (n->messages == NULL)
1508 {
1509 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1510 "Plaintext message queue is empty.\n");
1511 return; /* no pending messages */
1512 }
1513 discard_expired_messages (n);
1514 if (n->encrypted_head != NULL)
1515 {
1516 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1517 "Encrypted message queue is still full, delaying plaintext processing.\n");
1518 return; /* wait for messages already encrypted to be
1519 processed first! */
1520 }
1521 ph = (struct EncryptedMessage *) pbuf;
1522 deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
1523 priority = 0;
1524 used = sizeof (struct EncryptedMessage);
1525
1526 used += batch_message (n,
1527 &pbuf[used],
1528 MAX_ENCRYPTED_MESSAGE_SIZE - used,
1529 &deadline, &retry_time, &priority);
1530 if (used == sizeof (struct EncryptedMessage))
1531 {
1532 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1533 "No messages selected for processing at this time, will try again later.\n");
1534 /* no messages selected for sending, try again later... */
1535 n->retry_plaintext_task =
1536 GNUNET_SCHEDULER_add_delayed (sched,
1537 GNUNET_NO,
1538 GNUNET_SCHEDULER_PRIORITY_IDLE,
1539 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1540 retry_time,
1541 &retry_plaintext_processing, n);
1542 return;
1543 }
1544
1545 ph->sequence_number = htonl (++n->last_sequence_number_sent);
1546 ph->inbound_bpm_limit = htonl (n->bpm_in);
1547 ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
1548
1549 /* setup encryption message header */
1550 me = GNUNET_malloc (sizeof (struct MessageEntry) + used);
1551 me->deadline = deadline;
1552 me->priority = priority;
1553 me->size = used;
1554 em = (struct EncryptedMessage *) &me[1];
1555 em->header.size = htons (used);
1556 em->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE);
1557 em->reserved = htonl (0);
1558 esize = used - ENCRYPTED_HEADER_SIZE;
1559 GNUNET_CRYPTO_hash (&ph->sequence_number, esize, &em->plaintext_hash);
1560 /* encrypt */
1561 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1562 "Encrypting plaintext messages for transmission.\n");
1563 GNUNET_assert (GNUNET_OK ==
1564 do_encrypt (n,
1565 &em->plaintext_hash,
1566 &ph->sequence_number,
1567 &em->sequence_number, esize));
1568 /* append to transmission list */
1569 if (n->encrypted_tail == NULL)
1570 n->encrypted_head = me;
1571 else
1572 n->encrypted_tail->next = me;
1573 n->encrypted_tail = me;
1574 process_encrypted_neighbour_queue (n);
1575}
1576
1577
1578/**
1579 * Handle CORE_SEND request.
1580 */
1581static void
1582handle_client_send (void *cls,
1583 struct GNUNET_SERVER_Handle *server,
1584 struct GNUNET_SERVER_Client *client,
1585 const struct GNUNET_MessageHeader *message);
1586
1587
1588/**
1589 * Function called to notify us that we either succeeded
1590 * or failed to connect (at the transport level) to another
1591 * peer. We should either free the message we were asked
1592 * to transmit or re-try adding it to the queue.
1593 *
1594 * @param cls closure
1595 * @param size number of bytes available in buf
1596 * @param buf where the callee should write the message
1597 * @return number of bytes written to buf
1598 */
1599static size_t
1600send_connect_continuation (void *cls, size_t size, void *buf)
1601{
1602 struct SendMessage *sm = cls;
1603
1604 if (buf == NULL)
1605 {
1606 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1607 "Asked to send message to disconnected peer `%4s' and connection failed. Discarding message.\n",
1608 GNUNET_i2s (&sm->peer));
1609 GNUNET_free (sm);
1610 return 0;
1611 }
1612 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1613 "Connection to peer `%4s' succeeded, retrying original send request\n",
1614 GNUNET_i2s (&sm->peer));
1615 handle_client_send (NULL, NULL, NULL, &sm->header);
1616 GNUNET_free (sm);
1617 return 0;
1618}
1619
1620
1621/**
1622 * Handle CORE_SEND request.
1623 */
1624static void
1625handle_client_send (void *cls,
1626 struct GNUNET_SERVER_Handle *server,
1627 struct GNUNET_SERVER_Client *client,
1628 const struct GNUNET_MessageHeader *message)
1629{
1630 const struct SendMessage *sm;
1631 struct SendMessage *smc;
1632 const struct GNUNET_MessageHeader *mh;
1633 struct Neighbour *n;
1634 struct MessageEntry *pred;
1635 struct MessageEntry *pos;
1636 struct MessageEntry *e;
1637 uint16_t msize;
1638
1639 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1640 "Core service receives `%s' request.\n", "SEND");
1641 msize = ntohs (message->size);
1642 if (msize <
1643 sizeof (struct SendMessage) + sizeof (struct GNUNET_MessageHeader))
1644 {
1645 GNUNET_break (0);
1646 if (client != NULL)
1647 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1648 return;
1649 }
1650 sm = (const struct SendMessage *) message;
1651 msize -= sizeof (struct SendMessage);
1652 mh = (const struct GNUNET_MessageHeader *) &sm[1];
1653 if (msize != ntohs (mh->size))
1654 {
1655 GNUNET_break (0);
1656 if (client != NULL)
1657 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1658 return;
1659 }
1660 n = find_neighbour (&sm->peer);
1661 if (n == NULL)
1662 {
1663 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1664 "Not yet connected to `%4s', will try to establish connection\n",
1665 GNUNET_i2s (&sm->peer));
1666 msize += sizeof (struct SendMessage);
1667 /* ask transport to connect to the peer */
1668 /* FIXME: this code does not handle the
1669 case where we get multiple SendMessages before
1670 transport responds to this request;
1671 => need to track pending requests! */
1672 smc = GNUNET_malloc (msize);
1673 memcpy (smc, sm, msize);
1674 GNUNET_TRANSPORT_notify_transmit_ready (transport,
1675 &sm->peer,
1676 0,
1677 GNUNET_TIME_absolute_get_remaining
1678 (GNUNET_TIME_absolute_ntoh
1679 (sm->deadline)),
1680 &send_connect_continuation,
1681 smc);
1682 if (client != NULL)
1683 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1684 return;
1685 }
1686 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1687 "Core queues %u bytes of plaintext data for transmission to `%4s'.\n",
1688 msize, GNUNET_i2s (&sm->peer));
1689 /* FIXME: consider bounding queue size */
1690 e = GNUNET_malloc (sizeof (struct MessageEntry) + msize);
1691 e->deadline = GNUNET_TIME_absolute_ntoh (sm->deadline);
1692 e->priority = ntohl (sm->priority);
1693 e->size = msize;
1694 memcpy (&e[1], mh, msize);
1695
1696 /* insert, keep list sorted by deadline */
1697 pred = NULL;
1698 pos = n->messages;
1699 while ((pos != NULL) && (pos->deadline.value < e->deadline.value))
1700 {
1701 pred = pos;
1702 pos = pos->next;
1703 }
1704 if (pred == NULL)
1705 n->messages = e;
1706 else
1707 pred->next = e;
1708 e->next = pos;
1709
1710 /* consider scheduling now */
1711 process_plaintext_neighbour_queue (n);
1712 if (client != NULL)
1713 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1714}
1715
1716
1717/**
1718 * List of handlers for the messages understood by this
1719 * service.
1720 */
1721static struct GNUNET_SERVER_MessageHandler handlers[] = {
1722 {&handle_client_init, NULL,
1723 GNUNET_MESSAGE_TYPE_CORE_INIT, 0},
1724 {&handle_client_request_configure, NULL,
1725 GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONFIGURE,
1726 sizeof (struct RequestConfigureMessage)},
1727 {&handle_client_send, NULL,
1728 GNUNET_MESSAGE_TYPE_CORE_SEND, 0},
1729 {NULL, NULL, 0, 0}
1730};
1731
1732
1733/**
1734 * PEERINFO is giving us a HELLO for a peer. Add the
1735 * public key to the neighbour's struct and retry
1736 * send_key. Or, if we did not get a HELLO, just do
1737 * nothing.
1738 *
1739 * @param cls NULL
1740 * @param peer the peer for which this is the HELLO
1741 * @param hello HELLO message of that peer
1742 * @param trust amount of trust we currently have in that peer
1743 */
1744static void
1745process_hello_retry_send_key (void *cls,
1746 const struct GNUNET_PeerIdentity *peer,
1747 const struct GNUNET_HELLO_Message *hello,
1748 uint32_t trust)
1749{
1750 struct Neighbour *n;
1751
1752 if (peer == NULL)
1753 return;
1754 n = find_neighbour (peer);
1755 if (n == NULL)
1756 return;
1757 if (n->public_key != NULL)
1758 return;
1759 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1760 "Received new HELLO for `%4s', initiating key exchange.\n",
1761 GNUNET_i2s (peer));
1762 n->public_key =
1763 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
1764 if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
1765 {
1766 GNUNET_free (n->public_key);
1767 n->public_key = NULL;
1768 return;
1769 }
1770 send_key (n);
1771}
1772
1773
1774/**
1775 * Task that will retry "send_key" if our previous attempt failed
1776 * to yield a PONG.
1777 */
1778static void
1779set_key_retry_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1780{
1781 struct Neighbour *n = cls;
1782
1783 GNUNET_assert (n->status != PEER_STATE_KEY_CONFIRMED);
1784 n->retry_set_key_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1785 n->set_key_retry_frequency =
1786 GNUNET_TIME_relative_multiply (n->set_key_retry_frequency, 2);
1787 send_key (n);
1788}
1789
1790
1791/**
1792 * Send our key (and encrypted PING) to the other peer.
1793 *
1794 * @param n the other peer
1795 */
1796static void
1797send_key (struct Neighbour *n)
1798{
1799 struct SetKeyMessage *sm;
1800 struct MessageEntry *me;
1801 struct PingMessage pp;
1802 struct PingMessage *pm;
1803
1804 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1805 "Asked to perform key exchange with `%4s'.\n",
1806 GNUNET_i2s (&n->peer));
1807 if (n->public_key == NULL)
1808 {
1809 /* lookup n's public key, then try again */
1810 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1811 "Lacking public key for `%4s', trying to obtain one.\n",
1812 GNUNET_i2s (&n->peer));
1813 GNUNET_PEERINFO_for_all (cfg,
1814 sched,
1815 &n->peer,
1816 0,
1817 GNUNET_TIME_UNIT_MINUTES,
1818 &process_hello_retry_send_key, NULL);
1819 return;
1820 }
1821 /* first, set key message */
1822 me = GNUNET_malloc (sizeof (struct MessageEntry) +
1823 sizeof (struct SetKeyMessage));
1824 me->deadline = GNUNET_TIME_relative_to_absolute (MAX_SET_KEY_DELAY);
1825 me->priority = SET_KEY_PRIORITY;
1826 me->size = sizeof (struct SetKeyMessage);
1827 if (n->encrypted_head == NULL)
1828 n->encrypted_head = me;
1829 else
1830 n->encrypted_tail->next = me;
1831 n->encrypted_tail = me;
1832 sm = (struct SetKeyMessage *) &me[1];
1833 sm->header.size = htons (sizeof (struct SetKeyMessage));
1834 sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SET_KEY);
1835 sm->sender_status = htonl ((int32_t) ((n->status == PEER_STATE_DOWN) ?
1836 PEER_STATE_KEY_SENT : n->status));
1837 sm->purpose.size =
1838 htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
1839 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
1840 sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
1841 sizeof (struct GNUNET_PeerIdentity));
1842 sm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_KEY);
1843 sm->creation_time = GNUNET_TIME_absolute_hton (n->encrypt_key_created);
1844 sm->target = n->peer;
1845 GNUNET_assert (GNUNET_OK ==
1846 GNUNET_CRYPTO_rsa_encrypt (&n->encrypt_key,
1847 sizeof (struct
1848 GNUNET_CRYPTO_AesSessionKey),
1849 n->public_key,
1850 &sm->encrypted_key));
1851 GNUNET_assert (GNUNET_OK ==
1852 GNUNET_CRYPTO_rsa_sign (my_private_key, &sm->purpose,
1853 &sm->signature));
1854
1855 /* second, encrypted PING message */
1856 me = GNUNET_malloc (sizeof (struct MessageEntry) +
1857 sizeof (struct PingMessage));
1858 me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PING_DELAY);
1859 me->priority = PING_PRIORITY;
1860 me->size = sizeof (struct PingMessage);
1861 n->encrypted_tail->next = me;
1862 n->encrypted_tail = me;
1863 pm = (struct PingMessage *) &me[1];
1864 pm->header.size = htons (sizeof (struct PingMessage));
1865 pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
1866 pp.challenge = htonl (n->ping_challenge);
1867 pp.target = n->peer;
1868 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1869 "Encrypting `%s' and `%s' messages for `%4s'.\n",
1870 "SET_KEY", "PING", GNUNET_i2s (&n->peer));
1871 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1872 "Sending `%s' to `%4s' with challenge %u encrypted using key %u\n",
1873 "PING",
1874 GNUNET_i2s (&n->peer), n->ping_challenge, n->encrypt_key.crc32);
1875 do_encrypt (n,
1876 &n->peer.hashPubKey,
1877 &pp.challenge,
1878 &pm->challenge,
1879 sizeof (struct PingMessage) -
1880 sizeof (struct GNUNET_MessageHeader));
1881 /* update status */
1882 switch (n->status)
1883 {
1884 case PEER_STATE_DOWN:
1885 n->status = PEER_STATE_KEY_SENT;
1886 break;
1887 case PEER_STATE_KEY_SENT:
1888 break;
1889 case PEER_STATE_KEY_RECEIVED:
1890 break;
1891 case PEER_STATE_KEY_CONFIRMED:
1892 GNUNET_break (0);
1893 break;
1894 default:
1895 GNUNET_break (0);
1896 break;
1897 }
1898 /* trigger queue processing */
1899 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1900 "Triggering processing of encrypted message queue.\n");
1901 process_encrypted_neighbour_queue (n);
1902 if (n->status != PEER_STATE_KEY_CONFIRMED)
1903 n->retry_set_key_task
1904 = GNUNET_SCHEDULER_add_delayed (sched,
1905 GNUNET_NO,
1906 GNUNET_SCHEDULER_PRIORITY_KEEP,
1907 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1908 n->set_key_retry_frequency,
1909 &set_key_retry_task, n);
1910}
1911
1912
1913/**
1914 * We received a SET_KEY message. Validate and update
1915 * our key material and status.
1916 *
1917 * @param n the neighbour from which we received message m
1918 * @param m the set key message we received
1919 */
1920static void
1921handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m);
1922
1923
1924/**
1925 * PEERINFO is giving us a HELLO for a peer. Add the public key to
1926 * the neighbour's struct and retry handling the set_key message. Or,
1927 * if we did not get a HELLO, just free the set key message.
1928 *
1929 * @param cls pointer to the set key message
1930 * @param peer the peer for which this is the HELLO
1931 * @param hello HELLO message of that peer
1932 * @param trust amount of trust we currently have in that peer
1933 */
1934static void
1935process_hello_retry_handle_set_key (void *cls,
1936 const struct GNUNET_PeerIdentity *peer,
1937 const struct GNUNET_HELLO_Message *hello,
1938 uint32_t trust)
1939{
1940 struct SetKeyMessage *sm = cls;
1941 struct Neighbour *n;
1942
1943 if (peer == NULL)
1944 {
1945 GNUNET_free (sm);
1946 return;
1947 }
1948 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1949 "Looking for peer `%4s' to handle `%s' message.\n",
1950 GNUNET_i2s (peer), "SET_KEY");
1951 n = find_neighbour (peer);
1952 if (n == NULL)
1953 {
1954 GNUNET_break (0);
1955 return;
1956 }
1957 if (n->public_key != NULL)
1958 return; /* multiple HELLOs match!? */
1959 n->public_key =
1960 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
1961 if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
1962 {
1963 GNUNET_free (n->public_key);
1964 n->public_key = NULL;
1965 return;
1966 }
1967 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1968 "Received `%s' for `%4s', continuing processing of `%s' message.\n",
1969 "HELLO", GNUNET_i2s (peer), "SET_KEY");
1970 handle_set_key (n, sm);
1971}
1972
1973
1974/**
1975 * We received a PING message. Validate and transmit
1976 * PONG.
1977 *
1978 * @param n sender of the PING
1979 * @param m the encrypted PING message itself
1980 */
1981static void
1982handle_ping (struct Neighbour *n, const struct PingMessage *m)
1983{
1984 struct PingMessage t;
1985 struct PingMessage *tp;
1986 struct MessageEntry *me;
1987
1988 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1989 "Core service receives `%s' request from `%4s'.\n",
1990 "PING", GNUNET_i2s (&n->peer));
1991 if (GNUNET_OK !=
1992 do_decrypt (n,
1993 &my_identity.hashPubKey,
1994 &m->challenge,
1995 &t.challenge,
1996 sizeof (struct PingMessage) -
1997 sizeof (struct GNUNET_MessageHeader)))
1998 return;
1999 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2000 "Decrypted `%s' to `%4s' with challenge %u decrypted using key %u\n",
2001 "PING",
2002 GNUNET_i2s (&t.target),
2003 ntohl (t.challenge), n->decrypt_key.crc32);
2004 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2005 "Target of `%s' request is `%4s'.\n",
2006 "PING", GNUNET_i2s (&t.target));
2007 if (0 != memcmp (&t.target,
2008 &my_identity, sizeof (struct GNUNET_PeerIdentity)))
2009 {
2010 GNUNET_break_op (0);
2011 return;
2012 }
2013 me = GNUNET_malloc (sizeof (struct MessageEntry) +
2014 sizeof (struct PingMessage));
2015 if (n->encrypted_tail != NULL)
2016 n->encrypted_tail->next = me;
2017 else
2018 {
2019 n->encrypted_tail = me;
2020 n->encrypted_head = me;
2021 }
2022 me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PONG_DELAY);
2023 me->priority = PONG_PRIORITY;
2024 me->size = sizeof (struct PingMessage);
2025 tp = (struct PingMessage *) &me[1];
2026 tp->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG);
2027 tp->header.size = htons (sizeof (struct PingMessage));
2028 do_encrypt (n,
2029 &my_identity.hashPubKey,
2030 &t.challenge,
2031 &tp->challenge,
2032 sizeof (struct PingMessage) -
2033 sizeof (struct GNUNET_MessageHeader));
2034 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2035 "Encrypting `%s' with challenge %u using key %u\n", "PONG",
2036 ntohl (t.challenge), n->encrypt_key.crc32);
2037 /* trigger queue processing */
2038 process_encrypted_neighbour_queue (n);
2039}
2040
2041
2042/**
2043 * We received a SET_KEY message. Validate and update
2044 * our key material and status.
2045 *
2046 * @param n the neighbour from which we received message m
2047 * @param m the set key message we received
2048 */
2049static void
2050handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m)
2051{
2052 struct SetKeyMessage *m_cpy;
2053 struct GNUNET_TIME_Absolute t;
2054 struct GNUNET_CRYPTO_AesSessionKey k;
2055 struct PingMessage *ping;
2056 enum PeerStateMachine sender_status;
2057
2058 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2059 "Core service receives `%s' request from `%4s'.\n",
2060 "SET_KEY", GNUNET_i2s (&n->peer));
2061 if (n->public_key == NULL)
2062 {
2063 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2064 "Lacking public key for peer, trying to obtain one.\n");
2065 m_cpy = GNUNET_malloc (sizeof (struct SetKeyMessage));
2066 memcpy (m_cpy, m, sizeof (struct SetKeyMessage));
2067 /* lookup n's public key, then try again */
2068 GNUNET_PEERINFO_for_all (cfg,
2069 sched,
2070 &n->peer,
2071 0,
2072 GNUNET_TIME_UNIT_MINUTES,
2073 &process_hello_retry_handle_set_key, m_cpy);
2074 return;
2075 }
2076 if ((ntohl (m->purpose.size) !=
2077 sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
2078 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
2079 sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
2080 sizeof (struct GNUNET_PeerIdentity)) ||
2081 (GNUNET_OK !=
2082 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_SET_KEY,
2083 &m->purpose, &m->signature, n->public_key)))
2084 {
2085 /* invalid signature */
2086 GNUNET_break_op (0);
2087 return;
2088 }
2089 t = GNUNET_TIME_absolute_ntoh (m->creation_time);
2090 if (((n->status == PEER_STATE_KEY_RECEIVED) ||
2091 (n->status == PEER_STATE_KEY_CONFIRMED)) &&
2092 (t.value < n->decrypt_key_created.value))
2093 {
2094 /* this could rarely happen due to massive re-ordering of
2095 messages on the network level, but is most likely either
2096 a bug or some adversary messing with us. Report. */
2097 GNUNET_break_op (0);
2098 return;
2099 }
2100 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypting key material.\n");
2101 if ((GNUNET_CRYPTO_rsa_decrypt (my_private_key,
2102 &m->encrypted_key,
2103 &k,
2104 sizeof (struct GNUNET_CRYPTO_AesSessionKey))
2105 != sizeof (struct GNUNET_CRYPTO_AesSessionKey)) ||
2106 (GNUNET_OK != GNUNET_CRYPTO_aes_check_session_key (&k)))
2107 {
2108 /* failed to decrypt !? */
2109 GNUNET_break_op (0);
2110 return;
2111 }
2112
2113 n->decrypt_key = k;
2114 if (n->decrypt_key_created.value != t.value)
2115 {
2116 /* fresh key, reset sequence numbers */
2117 n->last_sequence_number_received = 0;
2118 n->last_packets_bitmap = 0;
2119 n->decrypt_key_created = t;
2120 }
2121 sender_status = (enum PeerStateMachine) ntohl (m->sender_status);
2122 switch (n->status)
2123 {
2124 case PEER_STATE_DOWN:
2125 n->status = PEER_STATE_KEY_RECEIVED;
2126 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2127 "Responding to `%s' with my own key.\n", "SET_KEY");
2128 send_key (n);
2129 break;
2130 case PEER_STATE_KEY_SENT:
2131 case PEER_STATE_KEY_RECEIVED:
2132 n->status = PEER_STATE_KEY_RECEIVED;
2133 if ((sender_status != PEER_STATE_KEY_RECEIVED) &&
2134 (sender_status != PEER_STATE_KEY_CONFIRMED))
2135 {
2136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2137 "Responding to `%s' with my own key (other peer has status %u).\n",
2138 "SET_KEY", sender_status);
2139 send_key (n);
2140 }
2141 break;
2142 case PEER_STATE_KEY_CONFIRMED:
2143 if ((sender_status != PEER_STATE_KEY_RECEIVED) &&
2144 (sender_status != PEER_STATE_KEY_CONFIRMED))
2145 {
2146 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2147 "Responding to `%s' with my own key (other peer has status %u), I was already fully up.\n",
2148 "SET_KEY", sender_status);
2149 send_key (n);
2150 }
2151 break;
2152 default:
2153 GNUNET_break (0);
2154 break;
2155 }
2156 if (n->pending_ping != NULL)
2157 {
2158 ping = n->pending_ping;
2159 n->pending_ping = NULL;
2160 handle_ping (n, ping);
2161 GNUNET_free (ping);
2162 }
2163}
2164
2165
2166/**
2167 * We received a PONG message. Validate and update
2168 * our status.
2169 *
2170 * @param n sender of the PONG
2171 * @param m the encrypted PONG message itself
2172 */
2173static void
2174handle_pong (struct Neighbour *n, const struct PingMessage *m)
2175{
2176 struct PingMessage t;
2177
2178 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2179 "Core service receives `%s' request from `%4s'.\n",
2180 "PONG", GNUNET_i2s (&n->peer));
2181 if (GNUNET_OK !=
2182 do_decrypt (n,
2183 &n->peer.hashPubKey,
2184 &m->challenge,
2185 &t.challenge,
2186 sizeof (struct PingMessage) -
2187 sizeof (struct GNUNET_MessageHeader)))
2188 return;
2189 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2190 "Decrypted `%s' from `%4s' with challenge %u using key %u\n",
2191 "PONG",
2192 GNUNET_i2s (&t.target),
2193 ntohl (t.challenge), n->decrypt_key.crc32);
2194 if ((0 != memcmp (&t.target,
2195 &n->peer,
2196 sizeof (struct GNUNET_PeerIdentity))) ||
2197 (n->ping_challenge != ntohl (t.challenge)))
2198 {
2199 /* PONG malformed */
2200 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2201 "Received malfromed `%s' wanted sender `%4s' with challenge %u\n",
2202 "PONG", GNUNET_i2s (&n->peer), n->ping_challenge);
2203 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2204 "Received malfromed `%s' received from `%4s' with challenge %u\n",
2205 "PONG", GNUNET_i2s (&t.target), ntohl (t.challenge));
2206 GNUNET_break_op (0);
2207 return;
2208 }
2209 switch (n->status)
2210 {
2211 case PEER_STATE_DOWN:
2212 GNUNET_break (0); /* should be impossible */
2213 return;
2214 case PEER_STATE_KEY_SENT:
2215 GNUNET_break (0); /* should be impossible, how did we decrypt? */
2216 return;
2217 case PEER_STATE_KEY_RECEIVED:
2218 n->status = PEER_STATE_KEY_CONFIRMED;
2219 if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
2220 {
2221 GNUNET_SCHEDULER_cancel (sched, n->retry_set_key_task);
2222 n->retry_set_key_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
2223 }
2224 process_encrypted_neighbour_queue (n);
2225 break;
2226 case PEER_STATE_KEY_CONFIRMED:
2227 /* duplicate PONG? */
2228 break;
2229 default:
2230 GNUNET_break (0);
2231 break;
2232 }
2233}
2234
2235
2236/**
2237 * Send a P2P message to a client.
2238 *
2239 * @param sender who sent us the message?
2240 * @param client who should we give the message to?
2241 * @param m contains the message to transmit
2242 * @param msize number of bytes in buf to transmit
2243 */
2244static void
2245send_p2p_message_to_client (struct Neighbour *sender,
2246 struct Client *client,
2247 const void *m, size_t msize)
2248{
2249 char buf[msize + sizeof (struct NotifyTrafficMessage)];
2250 struct NotifyTrafficMessage *ntm;
2251
2252 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2253 "Core service passes P2P message of type %u to client.\n",
2254 ntohs (((const struct GNUNET_MessageHeader *) m)->type));
2255 ntm = (struct NotifyTrafficMessage *) buf;
2256 ntm->header.size = htons (msize + sizeof (struct NotifyTrafficMessage));
2257 ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND);
2258 ntm->reserved = htonl (0);
2259 ntm->peer = sender->peer;
2260 memcpy (&ntm[1], m, msize);
2261 send_to_client (client, &ntm->header, GNUNET_YES);
2262}
2263
2264
2265/**
2266 * Deliver P2P message to interested clients.
2267 *
2268 * @param sender who sent us the message?
2269 * @param m the message
2270 * @param msize size of the message (including header)
2271 */
2272static void
2273deliver_message (struct Neighbour *sender,
2274 const struct GNUNET_MessageHeader *m, size_t msize)
2275{
2276 struct Client *cpos;
2277 uint16_t type;
2278 unsigned int tpos;
2279 int deliver_full;
2280
2281 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2282 "Passing decrypted P2P message to interested clients.\n");
2283 type = ntohs (m->type);
2284 cpos = clients;
2285 while (cpos != NULL)
2286 {
2287 deliver_full = GNUNET_NO;
2288 if (cpos->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)
2289 deliver_full = GNUNET_YES;
2290 else
2291 {
2292 for (tpos = 0; tpos < cpos->tcnt; tpos++)
2293 {
2294 if (type != cpos->types[tpos])
2295 continue;
2296 deliver_full = GNUNET_YES;
2297 break;
2298 }
2299 }
2300 if (GNUNET_YES == deliver_full)
2301 send_p2p_message_to_client (sender, cpos, m, msize);
2302 else if (cpos->options & GNUNET_CORE_OPTION_SEND_HDR_INBOUND)
2303 send_p2p_message_to_client (sender, cpos, m,
2304 sizeof (struct GNUNET_MessageHeader));
2305 cpos = cpos->next;
2306 }
2307}
2308
2309
2310/**
2311 * Align P2P message and then deliver to interested clients.
2312 *
2313 * @param sender who sent us the message?
2314 * @param buffer unaligned (!) buffer containing message
2315 * @param msize size of the message (including header)
2316 */
2317static void
2318align_and_deliver (struct Neighbour *sender, const char *buffer, size_t msize)
2319{
2320 char abuf[msize];
2321
2322 /* TODO: call to statistics? */
2323 memcpy (abuf, buffer, msize);
2324 deliver_message (sender, (const struct GNUNET_MessageHeader *) abuf, msize);
2325}
2326
2327
2328/**
2329 * Deliver P2P messages to interested clients.
2330 *
2331 * @param sender who sent us the message?
2332 * @param buffer buffer containing messages, can be modified
2333 * @param buffer_size size of the buffer (overall)
2334 * @param offset offset where messages in the buffer start
2335 */
2336static void
2337deliver_messages (struct Neighbour *sender,
2338 const char *buffer, size_t buffer_size, size_t offset)
2339{
2340 struct GNUNET_MessageHeader *mhp;
2341 struct GNUNET_MessageHeader mh;
2342 uint16_t msize;
2343 int need_align;
2344
2345 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2346 "Delivering %u bytes of plaintext to interested clients.\n",
2347 buffer_size);
2348 while (offset + sizeof (struct GNUNET_MessageHeader) <= buffer_size)
2349 {
2350 if (0 != offset % sizeof (uint16_t))
2351 {
2352 /* outch, need to copy to access header */
2353 memcpy (&mh, &buffer[offset], sizeof (struct GNUNET_MessageHeader));
2354 mhp = &mh;
2355 }
2356 else
2357 {
2358 /* can access header directly */
2359 mhp = (struct GNUNET_MessageHeader *) &buffer[offset];
2360 }
2361 msize = ntohs (mhp->size);
2362 if (msize + offset > buffer_size)
2363 {
2364 /* malformed message, header says it is larger than what
2365 would fit into the overall buffer */
2366 GNUNET_break_op (0);
2367 break;
2368 }
2369#if HAVE_UNALIGNED_64_ACCESS
2370 need_align = (0 != offset % 4) ? GNUNET_YES : GNUNET_NO;
2371#else
2372 need_align = (0 != offset % 8) ? GNUNET_YES : GNUNET_NO;
2373#endif
2374 if (GNUNET_YES == need_align)
2375 align_and_deliver (sender, &buffer[offset], msize);
2376 else
2377 deliver_message (sender,
2378 (const struct GNUNET_MessageHeader *)
2379 &buffer[offset], msize);
2380 offset += msize;
2381 }
2382}
2383
2384
2385/**
2386 * We received an encrypted message. Decrypt, validate and
2387 * pass on to the appropriate clients.
2388 */
2389static void
2390handle_encrypted_message (struct Neighbour *n,
2391 const struct EncryptedMessage *m)
2392{
2393 size_t size = ntohs (m->header.size);
2394 char buf[size];
2395 struct EncryptedMessage *pt; /* plaintext */
2396 GNUNET_HashCode ph;
2397 size_t off;
2398 uint32_t snum;
2399 struct GNUNET_TIME_Absolute t;
2400
2401 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2402 "Core service receives `%s' request from `%4s'.\n",
2403 "ENCRYPTED_MESSAGE", GNUNET_i2s (&n->peer));
2404 /* decrypt */
2405 if (GNUNET_OK !=
2406 do_decrypt (n,
2407 &m->plaintext_hash,
2408 &m->sequence_number,
2409 &buf[ENCRYPTED_HEADER_SIZE], size - ENCRYPTED_HEADER_SIZE))
2410 return;
2411 pt = (struct EncryptedMessage *) buf;
2412
2413 /* validate hash */
2414 GNUNET_CRYPTO_hash (&pt->sequence_number,
2415 size - ENCRYPTED_HEADER_SIZE, &ph);
2416 if (0 != memcmp (&ph, &m->plaintext_hash, sizeof (GNUNET_HashCode)))
2417 {
2418 /* checksum failed */
2419 GNUNET_break_op (0);
2420 return;
2421 }
2422
2423 /* validate sequence number */
2424 snum = ntohl (pt->sequence_number);
2425 if (n->last_sequence_number_received == snum)
2426 {
2427 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2428 "Received duplicate message, ignoring.\n");
2429 /* duplicate, ignore */
2430 return;
2431 }
2432 if ((n->last_sequence_number_received > snum) &&
2433 (n->last_sequence_number_received - snum > 32))
2434 {
2435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2436 "Received ancient out of sequence message, ignoring.\n");
2437 /* ancient out of sequence, ignore */
2438 return;
2439 }
2440 if (n->last_sequence_number_received > snum)
2441 {
2442 unsigned int rotbit =
2443 1 << (n->last_sequence_number_received - snum - 1);
2444 if ((n->last_packets_bitmap & rotbit) != 0)
2445 {
2446 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2447 "Received duplicate message, ignoring.\n");
2448 /* duplicate, ignore */
2449 return;
2450 }
2451 n->last_packets_bitmap |= rotbit;
2452 }
2453 if (n->last_sequence_number_received < snum)
2454 {
2455 n->last_packets_bitmap <<= (snum - n->last_sequence_number_received);
2456 n->last_sequence_number_received = snum;
2457 }
2458
2459 /* check timestamp */
2460 t = GNUNET_TIME_absolute_ntoh (pt->timestamp);
2461 if (GNUNET_TIME_absolute_get_duration (t).value > MAX_MESSAGE_AGE.value)
2462 {
2463 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2464 _
2465 ("Message received far too old (%llu ms). Content ignored.\n"),
2466 GNUNET_TIME_absolute_get_duration (t).value);
2467 return;
2468 }
2469
2470 /* process decrypted message(s) */
2471 n->bpm_out_external_limit = ntohl (pt->inbound_bpm_limit);
2472 n->bpm_out = GNUNET_MAX (n->bpm_out_external_limit,
2473 n->bpm_out_internal_limit);
2474 n->last_activity = GNUNET_TIME_absolute_get ();
2475 off = sizeof (struct EncryptedMessage);
2476 deliver_messages (n, buf, size, off);
2477}
2478
2479
2480/**
2481 * Function called by the transport for each received message.
2482 *
2483 * @param cls closure
2484 * @param latency estimated latency for communicating with the
2485 * given peer
2486 * @param peer (claimed) identity of the other peer
2487 * @param message the message
2488 */
2489static void
2490handle_transport_receive (void *cls,
2491 struct GNUNET_TIME_Relative latency,
2492 const struct GNUNET_PeerIdentity *peer,
2493 const struct GNUNET_MessageHeader *message)
2494{
2495 struct Neighbour *n;
2496 struct GNUNET_TIME_Absolute now;
2497 int up;
2498 uint16_t type;
2499 uint16_t size;
2500
2501 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2502 "Received message of type %u from `%4s', demultiplexing.\n",
2503 ntohs (message->type), GNUNET_i2s (peer));
2504 n = find_neighbour (peer);
2505 if (n == NULL)
2506 {
2507 GNUNET_break (0);
2508 return;
2509 }
2510 n->last_latency = latency;
2511 up = n->status == PEER_STATE_KEY_CONFIRMED;
2512 type = ntohs (message->type);
2513 size = ntohs (message->size);
2514 switch (type)
2515 {
2516 case GNUNET_MESSAGE_TYPE_CORE_SET_KEY:
2517 if (size != sizeof (struct SetKeyMessage))
2518 {
2519 GNUNET_break_op (0);
2520 return;
2521 }
2522 handle_set_key (n, (const struct SetKeyMessage *) message);
2523 break;
2524 case GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE:
2525 if (size < sizeof (struct EncryptedMessage) +
2526 sizeof (struct GNUNET_MessageHeader))
2527 {
2528 GNUNET_break_op (0);
2529 return;
2530 }
2531 if ((n->status != PEER_STATE_KEY_RECEIVED) &&
2532 (n->status != PEER_STATE_KEY_CONFIRMED))
2533 {
2534 GNUNET_break_op (0);
2535 return;
2536 }
2537 handle_encrypted_message (n, (const struct EncryptedMessage *) message);
2538 break;
2539 case GNUNET_MESSAGE_TYPE_CORE_PING:
2540 if (size != sizeof (struct PingMessage))
2541 {
2542 GNUNET_break_op (0);
2543 return;
2544 }
2545 if ((n->status != PEER_STATE_KEY_RECEIVED) &&
2546 (n->status != PEER_STATE_KEY_CONFIRMED))
2547 {
2548 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2549 "Core service receives `%s' request from `%4s' but have not processed key; marking as pending.\n",
2550 "PING", GNUNET_i2s (&n->peer));
2551 GNUNET_free_non_null (n->pending_ping);
2552 n->pending_ping = GNUNET_malloc (sizeof (struct PingMessage));
2553 memcpy (n->pending_ping, message, sizeof (struct PingMessage));
2554 return;
2555 }
2556 handle_ping (n, (const struct PingMessage *) message);
2557 break;
2558 case GNUNET_MESSAGE_TYPE_CORE_PONG:
2559 if (size != sizeof (struct PingMessage))
2560 {
2561 GNUNET_break_op (0);
2562 return;
2563 }
2564 if ((n->status != PEER_STATE_KEY_SENT) &&
2565 (n->status != PEER_STATE_KEY_RECEIVED) &&
2566 (n->status != PEER_STATE_KEY_CONFIRMED))
2567 {
2568 /* could not decrypt pong, oops! */
2569 GNUNET_break_op (0);
2570 return;
2571 }
2572 handle_pong (n, (const struct PingMessage *) message);
2573 break;
2574 default:
2575 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2576 _("Unsupported message of type %u received.\n"), type);
2577 return;
2578 }
2579 if (n->status == PEER_STATE_KEY_CONFIRMED)
2580 {
2581 now = GNUNET_TIME_absolute_get ();
2582 n->last_activity = now;
2583 if (!up)
2584 n->time_established = now;
2585 }
2586}
2587
2588
2589/**
2590 * Function called by transport to notify us that
2591 * a peer connected to us (on the network level).
2592 *
2593 * @param cls closure
2594 * @param peer the peer that connected
2595 * @param latency current latency of the connection
2596 */
2597static void
2598handle_transport_notify_connect (void *cls,
2599 const struct GNUNET_PeerIdentity *peer,
2600 struct GNUNET_TIME_Relative latency)
2601{
2602 struct Neighbour *n;
2603 struct GNUNET_TIME_Absolute now;
2604 struct ConnectNotifyMessage cnm;
2605
2606 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2607 "Received connection from `%4s'.\n", GNUNET_i2s (peer));
2608 n = find_neighbour (peer);
2609 if (n != NULL)
2610 {
2611 /* duplicate connect notification!? */
2612 GNUNET_break (0);
2613 return;
2614 }
2615 now = GNUNET_TIME_absolute_get ();
2616 n = GNUNET_malloc (sizeof (struct Neighbour));
2617 n->next = neighbours;
2618 neighbours = n;
2619 n->peer = *peer;
2620 n->last_latency = latency;
2621 GNUNET_CRYPTO_aes_create_session_key (&n->encrypt_key);
2622 n->encrypt_key_created = now;
2623 n->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
2624 n->last_asw_update = now;
2625 n->last_arw_update = now;
2626 n->bpm_in = DEFAULT_BPM_IN_OUT;
2627 n->bpm_out = DEFAULT_BPM_IN_OUT;
2628 n->bpm_out_internal_limit = (uint32_t) - 1;
2629 n->bpm_out_external_limit = DEFAULT_BPM_IN_OUT;
2630 n->ping_challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
2631 (uint32_t) - 1);
2632 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2633 "Created entry for new neighbour `%4s'.\n",
2634 GNUNET_i2s (&n->peer));
2635 cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
2636 cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
2637 cnm.bpm_available = htonl (DEFAULT_BPM_IN_OUT);
2638 cnm.peer = *peer;
2639 cnm.last_activity = GNUNET_TIME_absolute_hton (now);
2640 send_to_all_clients (&cnm.header, GNUNET_YES);
2641}
2642
2643
2644/**
2645 * Free the given entry for the neighbour (it has
2646 * already been removed from the list at this point).
2647 * @param n neighbour to free
2648 */
2649static void
2650free_neighbour (struct Neighbour *n)
2651{
2652 struct MessageEntry *m;
2653
2654 while (NULL != (m = n->messages))
2655 {
2656 n->messages = m->next;
2657 GNUNET_free (m);
2658 }
2659 while (NULL != (m = n->encrypted_head))
2660 {
2661 n->encrypted_head = m->next;
2662 GNUNET_free (m);
2663 }
2664 if (NULL != n->th)
2665 GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
2666 if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
2667 GNUNET_SCHEDULER_cancel (sched, n->retry_plaintext_task);
2668 if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
2669 GNUNET_SCHEDULER_cancel (sched, n->retry_set_key_task);
2670 GNUNET_free_non_null (n->public_key);
2671 GNUNET_free_non_null (n->pending_ping);
2672 GNUNET_free (n);
2673}
2674
2675
2676/**
2677 * Function called by transport telling us that a peer
2678 * disconnected.
2679 *
2680 * @param cls closure
2681 * @param peer the peer that disconnected
2682 */
2683static void
2684handle_transport_notify_disconnect (void *cls,
2685 const struct GNUNET_PeerIdentity *peer)
2686{
2687 struct ConnectNotifyMessage cnm;
2688 struct Neighbour *n;
2689 struct Neighbour *p;
2690
2691 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2692 "Peer `%4s' disconnected from us.\n", GNUNET_i2s (peer));
2693 p = NULL;
2694 n = neighbours;
2695 while ((n != NULL) &&
2696 (0 != memcmp (&n->peer, peer, sizeof (struct GNUNET_PeerIdentity))))
2697 {
2698 p = n;
2699 n = n->next;
2700 }
2701 if (n == NULL)
2702 {
2703 GNUNET_break (0);
2704 return;
2705 }
2706 if (p == NULL)
2707 neighbours = n->next;
2708 else
2709 p->next = n->next;
2710 cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
2711 cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT);
2712 cnm.bpm_available = htonl (0);
2713 cnm.peer = *peer;
2714 cnm.last_activity = GNUNET_TIME_absolute_hton (n->last_activity);
2715 send_to_all_clients (&cnm.header, GNUNET_YES);
2716 free_neighbour (n);
2717}
2718
2719
2720/**
2721 * Last task run during shutdown. Disconnects us from
2722 * the transport.
2723 */
2724static void
2725cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2726{
2727 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service shutting down.\n");
2728 GNUNET_assert (transport != NULL);
2729 GNUNET_TRANSPORT_disconnect (transport);
2730 transport = NULL;
2731}
2732
2733
2734/**
2735 * Initiate core service.
2736 *
2737 * @param cls closure
2738 * @param s scheduler to use
2739 * @param serv the initialized server
2740 * @param c configuration to use
2741 */
2742static void
2743run (void *cls,
2744 struct GNUNET_SCHEDULER_Handle *s,
2745 struct GNUNET_SERVER_Handle *serv, struct GNUNET_CONFIGURATION_Handle *c)
2746{
2747#if 0
2748 unsigned long long qin;
2749 unsigned long long qout;
2750 unsigned long long tneigh;
2751#endif
2752 char *keyfile;
2753
2754 sched = s;
2755 cfg = c;
2756 /* parse configuration */
2757 if (
2758#if 0
2759 (GNUNET_OK !=
2760 GNUNET_CONFIGURATION_get_value_number (c,
2761 "CORE",
2762 "XX",
2763 &qin)) ||
2764 (GNUNET_OK !=
2765 GNUNET_CONFIGURATION_get_value_number (c,
2766 "CORE",
2767 "YY",
2768 &qout)) ||
2769 (GNUNET_OK !=
2770 GNUNET_CONFIGURATION_get_value_number (c,
2771 "CORE",
2772 "ZZ_LIMIT", &tneigh)) ||
2773#endif
2774 (GNUNET_OK !=
2775 GNUNET_CONFIGURATION_get_value_filename (c,
2776 "GNUNETD",
2777 "HOSTKEY", &keyfile)))
2778 {
2779 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2780 _
2781 ("Core service is lacking key configuration settings. Exiting.\n"));
2782 GNUNET_SCHEDULER_shutdown (s);
2783 return;
2784 }
2785 my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
2786 GNUNET_free (keyfile);
2787 if (my_private_key == NULL)
2788 {
2789 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2790 _("Core service could not access hostkey. Exiting.\n"));
2791 GNUNET_SCHEDULER_shutdown (s);
2792 return;
2793 }
2794 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
2795 GNUNET_CRYPTO_hash (&my_public_key,
2796 sizeof (my_public_key), &my_identity.hashPubKey);
2797 /* setup notification */
2798 server = serv;
2799 GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
2800 /* setup transport connection */
2801 transport = GNUNET_TRANSPORT_connect (sched,
2802 cfg,
2803 NULL,
2804 &handle_transport_receive,
2805 &handle_transport_notify_connect,
2806 &handle_transport_notify_disconnect);
2807 GNUNET_assert (NULL != transport);
2808 GNUNET_SCHEDULER_add_delayed (sched,
2809 GNUNET_YES,
2810 GNUNET_SCHEDULER_PRIORITY_IDLE,
2811 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
2812 GNUNET_TIME_UNIT_FOREVER_REL,
2813 &cleaning_task, NULL);
2814 /* process client requests */
2815 GNUNET_SERVER_add_handlers (server, handlers);
2816 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2817 _("Core service of `%4s' ready.\n"), GNUNET_i2s (&my_identity));
2818}
2819
2820
2821/**
2822 * Function called during shutdown. Clean up our state.
2823 */
2824static void
2825cleanup (void *cls, struct GNUNET_CONFIGURATION_Handle *cfg)
2826{
2827 struct Neighbour *n;
2828
2829 if (my_private_key != NULL)
2830 GNUNET_CRYPTO_rsa_key_free (my_private_key);
2831 while (NULL != (n = neighbours))
2832 {
2833 neighbours = n->next;
2834 free_neighbour (n);
2835 }
2836 /*
2837 FIXME:
2838 - free clients
2839 */
2840}
2841
2842
2843/**
2844 * The main function for the transport service.
2845 *
2846 * @param argc number of arguments from the command line
2847 * @param argv command line arguments
2848 * @return 0 ok, 1 on error
2849 */
2850int
2851main (int argc, char *const *argv)
2852{
2853 return (GNUNET_OK ==
2854 GNUNET_SERVICE_run (argc,
2855 argv,
2856 "core", &run, NULL, &cleanup, NULL)) ? 0 : 1;
2857}
2858
2859/* end of gnunet-service-core.c */
diff --git a/src/core/test_core_api.c b/src/core/test_core_api.c
new file mode 100644
index 000000000..e1b3dcd0d
--- /dev/null
+++ b/src/core/test_core_api.c
@@ -0,0 +1,368 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 transport/test_core_api.c
22 * @brief testcase for core_api.c
23 *
24 * FIXME:
25 * - make sure connect callback is invoked properly as well!
26 */
27#include "platform.h"
28#include "gnunet_common.h"
29#include "gnunet_arm_service.h"
30#include "gnunet_core_service.h"
31#include "gnunet_getopt_lib.h"
32#include "gnunet_os_lib.h"
33#include "gnunet_program_lib.h"
34#include "gnunet_scheduler_lib.h"
35#include "gnunet_transport_service.h"
36
37#define VERBOSE GNUNET_NO
38
39#define START_ARM GNUNET_YES
40
41
42/**
43 * How long until we give up on transmitting the message?
44 */
45#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
46
47#define MTYPE 12345
48
49struct PeerContext
50{
51 struct GNUNET_CONFIGURATION_Handle *cfg;
52 struct GNUNET_CORE_Handle *ch;
53 struct GNUNET_PeerIdentity id; /* FIXME: this is always all-zeros! */
54 struct GNUNET_TRANSPORT_Handle *th;
55 struct GNUNET_MessageHeader *hello;
56#if START_ARM
57 pid_t arm_pid;
58#endif
59};
60
61static struct PeerContext p1;
62
63static struct PeerContext p2;
64
65static struct GNUNET_SCHEDULER_Handle *sched;
66
67static int ok;
68
69#if VERBOSE
70#define OKPP do { ok++; fprintf (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0)
71#else
72#define OKPP do { ok++; } while (0)
73#endif
74
75
76
77static void
78terminate_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
79{
80 GNUNET_assert (ok == 6);
81 GNUNET_CORE_disconnect (p1.ch);
82 GNUNET_CORE_disconnect (p2.ch);
83 GNUNET_TRANSPORT_disconnect (p1.th);
84 GNUNET_TRANSPORT_disconnect (p2.th);
85 GNUNET_ARM_stop_service ("core", p1.cfg, sched, TIMEOUT, NULL, NULL);
86 GNUNET_ARM_stop_service ("core", p2.cfg, sched, TIMEOUT, NULL, NULL);
87 ok = 0;
88}
89
90
91static void
92connect_notify (void *cls,
93 const struct GNUNET_PeerIdentity *peer,
94 unsigned int bpm, struct GNUNET_TIME_Absolute last_activity)
95{
96 GNUNET_assert ((ok == 5) || (ok == 6));
97 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
98 "Encrypted connection established to peer `%4s' (%u bpm)\n",
99 GNUNET_i2s (peer), bpm);
100}
101
102
103static void
104disconnect_notify (void *cls,
105 const struct GNUNET_PeerIdentity *peer,
106 unsigned int bpm,
107 struct GNUNET_TIME_Absolute last_activity)
108{
109 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
110 "Encrypted connection to `%4s' cut\n", GNUNET_i2s (peer));
111}
112
113
114static unsigned int
115bfc_callback (void *cls,
116 const struct GNUNET_PeerIdentity *receiver,
117 void *position, unsigned int padding)
118{
119 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
120 "Core requests data for `%4s', I have none.\n",
121 GNUNET_i2s (receiver));
122 return 0;
123}
124
125
126static int
127inbound_notify (void *cls,
128 const struct GNUNET_PeerIdentity *other,
129 const struct GNUNET_MessageHeader *message)
130{
131 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
132 "Core provides inbound data from `%4s'.\n", GNUNET_i2s (other));
133 return GNUNET_OK;
134}
135
136
137static int
138outbound_notify (void *cls,
139 const struct GNUNET_PeerIdentity *other,
140 const struct GNUNET_MessageHeader *message)
141{
142 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
143 "Core notifies about outbound data for `%4s'.\n",
144 GNUNET_i2s (other));
145 return GNUNET_OK;
146}
147
148
149static int
150process_mtype (void *cls,
151 const struct GNUNET_PeerIdentity *peer,
152 const struct GNUNET_MessageHeader *message)
153{
154 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
155 "Receiving message from `%4s'.\n", GNUNET_i2s (peer));
156 GNUNET_assert (ok == 5);
157 OKPP;
158 GNUNET_SCHEDULER_add_delayed (sched,
159 GNUNET_NO,
160 GNUNET_SCHEDULER_PRIORITY_KEEP,
161 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
162 GNUNET_TIME_UNIT_ZERO, &terminate_task, NULL);
163 return GNUNET_OK;
164}
165
166
167static struct GNUNET_CORE_MessageHandler handlers[] = {
168 {&process_mtype, MTYPE, sizeof (struct GNUNET_MessageHeader)},
169 {NULL, 0, 0}
170};
171
172
173static size_t
174transmit_ready (void *cls, size_t size, void *buf)
175{
176 struct PeerContext *p = cls;
177 struct GNUNET_MessageHeader *m;
178
179 GNUNET_assert (ok == 4);
180 OKPP;
181 GNUNET_assert (p == &p1);
182 GNUNET_assert (buf != NULL);
183 m = (struct GNUNET_MessageHeader *) buf;
184 m->type = htons (MTYPE);
185 m->size = htons (sizeof (struct GNUNET_MessageHeader));
186 return sizeof (struct GNUNET_MessageHeader);
187}
188
189
190
191static void
192init_notify (void *cls,
193 struct GNUNET_CORE_Handle *server,
194 const struct GNUNET_PeerIdentity *my_identity,
195 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
196{
197 struct PeerContext *p = cls;
198
199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
200 "Core connection to `%4s' established\n",
201 GNUNET_i2s (my_identity));
202 GNUNET_assert (server != NULL);
203 p->id = *my_identity;
204 p->ch = server;
205 if (cls == &p1)
206 {
207 GNUNET_assert (ok == 2);
208 OKPP;
209 /* connect p2 */
210 GNUNET_CORE_connect (sched,
211 p2.cfg,
212 TIMEOUT,
213 &p2,
214 &init_notify,
215 &connect_notify,
216 &disconnect_notify,
217 &bfc_callback,
218 &inbound_notify,
219 GNUNET_YES,
220 &outbound_notify, GNUNET_YES, handlers);
221 }
222 else
223 {
224 GNUNET_assert (ok == 3);
225 OKPP;
226 GNUNET_assert (cls == &p2);
227 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
228 "Asking core (1) for transmission to peer `%4s'\n",
229 GNUNET_i2s (&p2.id));
230 GNUNET_CORE_notify_transmit_ready (p1.ch,
231 0,
232 TIMEOUT,
233 &p2.id,
234 sizeof (struct GNUNET_MessageHeader),
235 &transmit_ready, &p1);
236
237 }
238}
239
240
241static void
242process_hello (void *cls,
243 struct GNUNET_TIME_Relative latency,
244 const struct GNUNET_PeerIdentity *peer,
245 const struct GNUNET_MessageHeader *message)
246{
247 struct PeerContext *p = cls;
248
249 GNUNET_assert (peer != NULL);
250 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
251 "Received (my) `%s' from transport service of `%4s'\n",
252 "HELLO", GNUNET_i2s (peer));
253 GNUNET_assert (message != NULL);
254 p->hello = GNUNET_malloc (ntohs (message->size));
255 memcpy (p->hello, message, ntohs (message->size));
256 if ((p == &p1) && (p2.th != NULL))
257 GNUNET_TRANSPORT_offer_hello (p2.th, message);
258 if ((p == &p2) && (p1.th != NULL))
259 GNUNET_TRANSPORT_offer_hello (p1.th, message);
260
261 if ((p == &p1) && (p2.hello != NULL))
262 GNUNET_TRANSPORT_offer_hello (p1.th, p2.hello);
263 if ((p == &p2) && (p1.hello != NULL))
264 GNUNET_TRANSPORT_offer_hello (p2.th, p1.hello);
265}
266
267
268
269static void
270setup_peer (struct PeerContext *p, const char *cfgname)
271{
272 p->cfg = GNUNET_CONFIGURATION_create ();
273#if START_ARM
274 p->arm_pid = GNUNET_OS_start_process ("gnunet-service-arm",
275 "gnunet-service-arm",
276#if VERBOSE
277 "-L", "DEBUG",
278#endif
279 "-c", cfgname, NULL);
280 sleep (1); /* allow ARM to start */
281#endif
282 GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
283 GNUNET_ARM_start_service ("core", p->cfg, sched, TIMEOUT, NULL, NULL);
284 p->th = GNUNET_TRANSPORT_connect (sched, p->cfg, p, NULL, NULL, NULL);
285 GNUNET_assert (p->th != NULL);
286 GNUNET_TRANSPORT_get_hello (p->th, TIMEOUT, &process_hello, p);
287}
288
289
290static void
291run (void *cls,
292 struct GNUNET_SCHEDULER_Handle *s,
293 char *const *args,
294 const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *cfg)
295{
296 GNUNET_assert (ok == 1);
297 OKPP;
298 sched = s;
299 setup_peer (&p1, "test_core_api_peer1.conf");
300 setup_peer (&p2, "test_core_api_peer2.conf");
301 GNUNET_CORE_connect (sched,
302 p1.cfg,
303 TIMEOUT,
304 &p1,
305 &init_notify,
306 &connect_notify,
307 &disconnect_notify,
308 &bfc_callback,
309 &inbound_notify,
310 GNUNET_YES, &outbound_notify, GNUNET_YES, handlers);
311}
312
313
314static void
315stop_arm (struct PeerContext *p)
316{
317#if START_ARM
318 if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
319 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
320 if (p->arm_pid != waitpid (p->arm_pid, NULL, 0))
321 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
322 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
323 "ARM process %u stopped\n", p->arm_pid);
324#endif
325 GNUNET_CONFIGURATION_destroy (p->cfg);
326}
327
328static int
329check ()
330{
331 char *const argv[] = { "test-core-api",
332 "-c",
333 "test_core_api_data.conf",
334#if VERBOSE
335 "-L", "DEBUG",
336#endif
337 NULL
338 };
339 struct GNUNET_GETOPT_CommandLineOption options[] = {
340 GNUNET_GETOPT_OPTION_END
341 };
342 sleep (1);
343 ok = 1;
344 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
345 argv, "test-core-api", "nohelp", options, &run, &ok);
346 stop_arm (&p1);
347 stop_arm (&p2);
348 return ok;
349}
350
351int
352main (int argc, char *argv[])
353{
354 int ret;
355
356 GNUNET_log_setup ("test-core-api",
357#if VERBOSE
358 "DEBUG",
359#else
360 "WARNING",
361#endif
362 NULL);
363 ret = check ();
364
365 return ret;
366}
367
368/* end of test_core_api.c */
diff --git a/src/core/test_core_api_data.conf b/src/core/test_core_api_data.conf
new file mode 100644
index 000000000..7a35faaf0
--- /dev/null
+++ b/src/core/test_core_api_data.conf
@@ -0,0 +1,27 @@
1[PATHS]
2SERVICEHOME = /tmp/test-gnunetd-core-master/
3
4[resolver]
5PORT = 2464
6
7[transport]
8PORT = 2465
9PLUGINS = tcp
10
11[arm]
12PORT = 2466
13
14[statistics]
15PORT = 2467
16
17[tcp]
18PORT = 2468
19
20[peerinfo]
21PORT = 2469
22
23[core]
24PORT = 2470
25
26[testing]
27WEAKRANDOM = YES
diff --git a/src/core/test_core_api_peer1.conf b/src/core/test_core_api_peer1.conf
new file mode 100644
index 000000000..fb060e3e6
--- /dev/null
+++ b/src/core/test_core_api_peer1.conf
@@ -0,0 +1,40 @@
1[PATHS]
2SERVICEHOME = /tmp/test-gnunetd-core-peer-1/
3DEFAULTCONFIG = test_core_api_peer1.conf
4
5[resolver]
6PORT = 12464
7#PREFIX = xterm -T resolver1 -e valgrind --tool=memcheck
8
9[transport]
10PORT = 12465
11PLUGINS = tcp
12#PREFIX = xterm -T transport1 -e
13#PREFIX = xterm -T transport1 -e valgrind --tool=memcheck
14#DEBUG = YES
15
16[arm]
17PORT = 12466
18#GLOBAL_PREFIX = xterm -e valgrind --tool=memcheck
19
20[statistics]
21PORT = 12467
22#PREFIX = xterm -T statistics1 -e valgrind --tool=memcheck
23
24[tcp]
25PORT = 12468
26
27[peerinfo]
28PORT = 12469
29#PREFIX = xterm -T peerinfo1 -e valgrind --tool=memcheck
30#PREFIX = xterm -T peerinfo1 -e
31
32[core]
33PORT = 12470
34#PREFIX = xterm -T core1 -e valgrind --tool=memcheck
35#PREFIX = xterm -T core1 -e gdb -x cmd --args
36#PREFIX = xterm -T core1 -e
37#DEBUG = YES
38
39[testing]
40WEAKRANDOM = YES
diff --git a/src/core/test_core_api_peer2.conf b/src/core/test_core_api_peer2.conf
new file mode 100644
index 000000000..e3862da0f
--- /dev/null
+++ b/src/core/test_core_api_peer2.conf
@@ -0,0 +1,39 @@
1[PATHS]
2SERVICEHOME = /tmp/test-gnunetd-core-peer-2/
3DEFAULTCONFIG = test_core_api_peer2.conf
4
5[resolver]
6PORT = 22464
7#PREFIX = xterm -T resolver2 -e valgrind --tool=memcheck
8
9[transport]
10PORT = 22465
11PLUGINS = tcp
12#PREFIX = xterm -T transport2 -e
13#PREFIX = xterm -T transport2 -e valgrind --tool=memcheck
14#DEBUG = YES
15
16[arm]
17PORT = 22466
18#GLOBAL_PREFIX = xterm -e valgrind --tool=memcheck
19
20[statistics]
21PORT = 22467
22#PREFIX = xterm -T statistics2 -e valgrind --tool=memcheck
23
24[tcp]
25PORT = 22468
26
27[peerinfo]
28PORT = 22469
29#PREFIX = xterm -T peerinfo2 -e valgrind --tool=memcheck
30#PREFIX = xterm -T peerinfo2 -e
31
32[core]
33PORT = 22470
34#PREFIX = xterm -T core2 -e
35#PREFIX = xterm -T core2 -e valgrind --tool=memcheck
36#DEBUG = YES
37
38[testing]
39WEAKRANDOM = YES
diff --git a/src/core/test_core_api_start_only.c b/src/core/test_core_api_start_only.c
new file mode 100644
index 000000000..dc4bfea98
--- /dev/null
+++ b/src/core/test_core_api_start_only.c
@@ -0,0 +1,257 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 transport/test_core_api_start_only.c
22 * @brief testcase for core_api.c that only starts two peers,
23 * connects to the core service and shuts down again
24 */
25#include "platform.h"
26#include "gnunet_common.h"
27#include "gnunet_arm_service.h"
28#include "gnunet_core_service.h"
29#include "gnunet_getopt_lib.h"
30#include "gnunet_os_lib.h"
31#include "gnunet_program_lib.h"
32#include "gnunet_scheduler_lib.h"
33
34#define VERBOSE GNUNET_NO
35
36#define START_ARM GNUNET_YES
37
38
39/**
40 * How long until we give up on transmitting the message?
41 */
42#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
43
44#define MTYPE 12345
45
46struct PeerContext
47{
48 struct GNUNET_CONFIGURATION_Handle *cfg;
49 struct GNUNET_CORE_Handle *ch;
50 struct GNUNET_PeerIdentity id;
51#if START_ARM
52 pid_t arm_pid;
53#endif
54};
55
56static struct PeerContext p1;
57
58static struct PeerContext p2;
59
60static struct GNUNET_SCHEDULER_Handle *sched;
61
62static int ok;
63
64#if VERBOSE
65#define OKPP do { ok++; fprintf (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0)
66#else
67#define OKPP do { ok++; } while (0)
68#endif
69
70
71
72static void
73connect_notify (void *cls,
74 const struct GNUNET_PeerIdentity *peer,
75 unsigned int bpm, struct GNUNET_TIME_Absolute last_activity)
76{
77}
78
79
80static void
81disconnect_notify (void *cls,
82 const struct GNUNET_PeerIdentity *peer,
83 unsigned int bpm,
84 struct GNUNET_TIME_Absolute last_activity)
85{
86}
87
88
89static unsigned int
90bfc_callback (void *cls,
91 const struct GNUNET_PeerIdentity *receiver,
92 void *position, unsigned int padding)
93{
94 return 0;
95}
96
97
98static int
99inbound_notify (void *cls,
100 const struct GNUNET_PeerIdentity *other,
101 const struct GNUNET_MessageHeader *message)
102{
103 return GNUNET_OK;
104}
105
106
107static int
108outbound_notify (void *cls,
109 const struct GNUNET_PeerIdentity *other,
110 const struct GNUNET_MessageHeader *message)
111{
112 return GNUNET_OK;
113}
114
115
116static struct GNUNET_CORE_MessageHandler handlers[] = {
117 {NULL, 0, 0}
118};
119
120
121
122static void
123init_notify (void *cls,
124 struct GNUNET_CORE_Handle *server,
125 const struct GNUNET_PeerIdentity *my_identity,
126 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
127{
128 struct PeerContext *p = cls;
129
130 GNUNET_assert (server != NULL);
131 p->ch = server;
132 if (cls == &p1)
133 {
134 /* connect p2 */
135 GNUNET_CORE_connect (sched,
136 p2.cfg,
137 TIMEOUT,
138 &p2,
139 &init_notify,
140 &connect_notify,
141 &disconnect_notify,
142 &bfc_callback,
143 &inbound_notify,
144 GNUNET_YES,
145 &outbound_notify, GNUNET_YES, handlers);
146 }
147 else
148 {
149 GNUNET_assert (cls == &p2);
150 GNUNET_CORE_disconnect (p1.ch);
151 GNUNET_CORE_disconnect (p2.ch);
152 GNUNET_ARM_stop_service ("core", p1.cfg, sched, TIMEOUT, NULL, NULL);
153 GNUNET_ARM_stop_service ("core", p2.cfg, sched, TIMEOUT, NULL, NULL);
154
155 ok = 0;
156 }
157}
158
159
160static void
161setup_peer (struct PeerContext *p, const char *cfgname)
162{
163 p->cfg = GNUNET_CONFIGURATION_create ();
164#if START_ARM
165 p->arm_pid = GNUNET_OS_start_process ("gnunet-service-arm",
166 "gnunet-service-arm",
167#if VERBOSE
168 "-L", "DEBUG",
169#endif
170 "-c", cfgname, NULL);
171 sleep (1); /* allow ARM to start */
172#endif
173 GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
174 GNUNET_ARM_start_service ("core", p->cfg, sched, TIMEOUT, NULL, NULL);
175}
176
177
178static void
179run (void *cls,
180 struct GNUNET_SCHEDULER_Handle *s,
181 char *const *args,
182 const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *cfg)
183{
184 GNUNET_assert (ok == 1);
185 OKPP;
186 sched = s;
187 setup_peer (&p1, "test_core_api_peer1.conf");
188 setup_peer (&p2, "test_core_api_peer2.conf");
189 GNUNET_CORE_connect (sched,
190 p1.cfg,
191 TIMEOUT,
192 &p1,
193 &init_notify,
194 &connect_notify,
195 &disconnect_notify,
196 &bfc_callback,
197 &inbound_notify,
198 GNUNET_YES, &outbound_notify, GNUNET_YES, handlers);
199}
200
201
202static void
203stop_arm (struct PeerContext *p)
204{
205#if START_ARM
206 if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
207 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
208 if (p->arm_pid != waitpid (p->arm_pid, NULL, 0))
209 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
210 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
211 "ARM process %u stopped\n", p->arm_pid);
212#endif
213 GNUNET_CONFIGURATION_destroy (p->cfg);
214}
215
216
217static int
218check ()
219{
220 char *const argv[] = { "test-core-api",
221 "-c",
222 "test_core_api_data.conf",
223#if VERBOSE
224 "-L", "DEBUG",
225#endif
226 NULL
227 };
228 struct GNUNET_GETOPT_CommandLineOption options[] = {
229 GNUNET_GETOPT_OPTION_END
230 };
231
232 ok = 1;
233 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
234 argv, "test-core-api", "nohelp", options, &run, &ok);
235 stop_arm (&p1);
236 stop_arm (&p2);
237 return ok;
238}
239
240int
241main (int argc, char *argv[])
242{
243 int ret;
244
245 GNUNET_log_setup ("test-core-api",
246#if VERBOSE
247 "DEBUG",
248#else
249 "WARNING",
250#endif
251 NULL);
252 ret = check ();
253
254 return ret;
255}
256
257/* end of test_core_api_start_only.c */
diff --git a/src/datastore/plugin_datastore.h b/src/datastore/plugin_datastore.h
new file mode 100644
index 000000000..b4dc87f9d
--- /dev/null
+++ b/src/datastore/plugin_datastore.h
@@ -0,0 +1,241 @@
1/*
2 This file is part of GNUnet
3 (C) 2009 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 2, 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 datastore/plugin_datastore.h
23 * @brief API for the database backend plugins.
24 * @author Christian Grothoff
25 *
26 * TODO:
27 * - consider defining enumeration or at least typedef
28 * for the type of "type" (instead of using uint32_t)
29 */
30#ifndef PLUGIN_DATASTORE_H
31#define PLUGIN_DATASTORE_H
32
33#include "gnunet_configuration_lib.h"
34#include "gnunet_scheduler_lib.h"
35#include "gnunet_datastore_service.h"
36
37/**
38 * The datastore service will pass a pointer to a struct
39 * of this type as the first and only argument to the
40 * entry point of each datastore plugin.
41 */
42struct GNUNET_DATASTORE_PluginEnvironment
43{
44 /**
45 * Configuration to use.
46 */
47 struct GNUNET_CONFIGURATION_Handle *cfg;
48
49 /**
50 * Scheduler to use.
51 */
52 struct GNUNET_SCHEDULER_Handle *sched;
53
54};
55
56
57/**
58 * Get an estimate of how much space the database is
59 * currently using.
60 * @return number of bytes used on disk
61 */
62typedef unsigned long long (*GNUNET_DATASTORE_GetSize) (void *cls);
63
64
65/**
66 * Store an item in the datastore.
67 *
68 * @param cls closure
69 * @param key key for the item
70 * @param size number of bytes in data
71 * @param data content stored
72 * @param type type of the content
73 * @param priority priority of the content
74 * @param anonymity anonymity-level for the content
75 * @param expiration expiration time for the content
76 */
77typedef void
78 (*GNUNET_DATASTORE_Put) (void *cls,
79 const GNUNET_HashCode * key,
80 uint32_t size,
81 const void *data,
82 unit32_t type,
83 uint32_t priority,
84 uint32_t anonymity,
85 struct GNUNET_TIME_Absolute expiration);
86
87
88/**
89 * Iterate over the results for a particular key
90 * in the datastore.
91 *
92 * @param cls closure
93 * @param key maybe NULL (to match all entries)
94 * @param vhash hash of the value, maybe NULL (to
95 * match all values that have the right key).
96 * Note that for DBlocks there is no difference
97 * betwen key and vhash, but for other blocks
98 * there may be!
99 * @param type entries of which type are relevant?
100 * Use 0 for any type.
101 * @param iter function to call on each matching value;
102 * will be called once with a NULL value at the end
103 * @param iter_cls closure for iter
104 */
105typedef void
106 (*GNUNET_DATASTORE_Get) (void *cls,
107 const GNUNET_HashCode * key,
108 const GNUNET_HashCode * vhash,
109 uint32_t type,
110 GNUNET_DATASTORE_Iterator iter, void *iter_cls);
111
112
113/**
114 * Update the priority for a particular key in the datastore. If
115 * the expiration time in value is different than the time found in
116 * the datastore, the higher value should be kept. For the
117 * anonymity level, the lower value is to be used. The specified
118 * priority should be added to the existing priority, ignoring the
119 * priority in value.
120 *
121 * Note that it is possible for multiple values to match this put.
122 * In that case, all of the respective values are updated.
123 *
124 * @param uid unique identifier of the datum
125 * @param delta by how much should the priority
126 * change? If priority + delta < 0 the
127 * priority should be set to 0 (never go
128 * negative).
129 * @param expire new expiration time should be the
130 * MAX of any existing expiration time and
131 * this value
132 */
133typedef void
134 (*GNUNET_DATASTORE_Update) (void *cls,
135 unsigned long long uid,
136 int delta, struct GNUNET_TIME_Absolute expire);
137
138
139/**
140 * Select a subset of the items in the datastore and call
141 * the given iterator for each of them.
142 *
143 * @param type entries of which type should be considered?
144 * Use 0 for any type.
145 * @param iter function to call on each matching value;
146 * will be called once with a NULL value at the end
147 * @param iter_cls closure for iter
148 */
149typedef void
150 (*GNUNET_DATASTORE_Selector) (void *cls,
151 uint32_t type,
152 GNUNET_DATASTORE_Iterator iter,
153 void *iter_cls);
154
155/**
156 * Drop database.
157 */
158typedef void (*GNUNET_DATASTORE_Drop) (void *cls);
159
160
161
162/**
163 * Each plugin is required to return a pointer to a struct of this
164 * type as the return value from its entry point.
165 */
166struct GNUNET_DATASTORE_PluginFunctions
167{
168
169 /**
170 * Closure to use for all of the following callbacks.
171 */
172 void *cls;
173
174 /**
175 * Get the current on-disk size of the SQ store. Estimates are
176 * fine, if that's the only thing available.
177 */
178 GNUNET_DATASTORE_GetSize size;
179
180 /**
181 * Function to store an item in the datastore.
182 */
183 GNUNET_DATASTORE_Put put;
184
185 /**
186 * Function to iterate over the results for a particular key
187 * in the datastore.
188 */
189 GNUNET_DATASTORE_Get get;
190
191 /**
192 * Update the priority for a particular key in the datastore. If
193 * the expiration time in value is different than the time found in
194 * the datastore, the higher value should be kept. For the
195 * anonymity level, the lower value is to be used. The specified
196 * priority should be added to the existing priority, ignoring the
197 * priority in value.
198 */
199 GNUNET_DATASTORE_Update update;
200
201 /**
202 * Iterate over the items in the datastore in ascending
203 * order of priority.
204 */
205 GNUNET_DATASTORE_Selector iter_low_priority;
206
207 /**
208 * Iterate over content with anonymity zero.
209 */
210 GNUNET_DATASTORE_Selector iter_zero_anonymity;
211
212 /**
213 * Iterate over the items in the datastore in ascending
214 * order of expiration time.
215 */
216 GNUNET_DATSTORE_Selector iter_ascending_expiration;
217
218 /**
219 * Iterate over the items in the datastore in migration
220 * order.
221 */
222 GNUNET_DATASTORE_Selector iter_migration_order;
223
224 /**
225 * Iterate over all the items in the datastore
226 * as fast as possible in a single transaction
227 * (can lock datastore while this happens, focus
228 * is on doing it fast).
229 */
230 GNUNET_DATASTORE_Selector iter_all_now;
231
232 /**
233 * Delete the database. The next operation is
234 * guaranteed to be unloading of the module.
235 */
236 GNUNET_DATASTORE_Drop drop;
237
238};
239
240
241#endif
diff --git a/src/fragmentation/Makefile.am b/src/fragmentation/Makefile.am
new file mode 100644
index 000000000..d3a47d920
--- /dev/null
+++ b/src/fragmentation/Makefile.am
@@ -0,0 +1,28 @@
1INCLUDES = -I$(top_srcdir)/src/include
2
3if MINGW
4 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
5endif
6
7if USE_COVERAGE
8 AM_CFLAGS = --coverage
9endif
10
11lib_LTLIBRARIES = libgnunetfragmentation.la
12
13libgnunetfragmentation_la_SOURCES = \
14 fragmentation.c
15libgnunetfragmentation_la_LIBADD = \
16 $(top_builddir)/src/util/libgnunetutil.la
17
18check_PROGRAMS = \
19 test_fragmentation
20
21TESTS = $(check_PROGRAMS)
22
23test_fragmentation_SOURCES = \
24 test_fragmentation.c
25test_fragmentation_LDADD = \
26 $(top_builddir)/src/fragmentation/libgnunetfragmentation.la \
27 $(top_builddir)/src/util/libgnunetutil.la
28
diff --git a/src/fragmentation/fragmentation.c b/src/fragmentation/fragmentation.c
new file mode 100644
index 000000000..9550663c7
--- /dev/null
+++ b/src/fragmentation/fragmentation.c
@@ -0,0 +1,702 @@
1/*
2 This file is part of GNUnet
3 (C) 2004, 2006, 2009 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 2, 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 fragmentation/fragmentation.c
22 * @brief fragmentation and defragmentation, this code allows
23 * sending and receiving messages that are larger than
24 * the MTU of the transport. Messages are still limited
25 * to a maximum size of 65535 bytes, which is a good
26 * idea because otherwise we may need ungainly fragmentation
27 * buffers. Each connected peer can have at most one
28 * fragmented packet at any given point in time (prevents
29 * DoS attacks). Fragmented messages that have not been
30 * completed after a certain amount of time are discarded.
31 * @author Christian Grothoff
32 */
33
34#include "platform.h"
35#include "gnunet_fragmentation_lib.h"
36
37/**
38 * Message fragment. This header is followed
39 * by the actual data of the fragment.
40 */
41struct Fragment
42{
43
44 struct GNUNET_MessageHeader header;
45
46 /**
47 * Fragment offset.
48 */
49 uint32_t off GNUNET_PACKED;
50
51 /**
52 * "unique" id for the fragment
53 */
54 uint64_t id GNUNET_PACKED;
55
56};
57
58
59/**
60 * Defragmentation context.
61 */
62struct GNUNET_FRAGMENT_Context
63{
64};
65
66
67/**
68 * Fragment an over-sized message.
69 *
70 * @param msg the message to fragment
71 * @param mtu the maximum message size
72 * @param proc function to call for each fragment
73 * @param proc_cls closure for proc
74 */
75void
76GNUNET_FRAGMENT_fragment (const struct GNUNET_MessageHeader *msg,
77 uint16_t mtu,
78 GNUNET_FRAGMENT_MessageProcessor proc,
79 void *proc_cls)
80{
81 GNUNET_assert (0);
82}
83
84
85/**
86 * Create a defragmentation context.
87 *
88 * @param stats statistics context
89 * @param proc function to call with defragmented messages
90 * @param proc_cls closure for proc
91 * @return the defragmentation context
92 */
93struct GNUNET_FRAGMENT_Context *
94GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats,
95 GNUNET_FRAGMENT_MessageProcessor proc,
96 void *proc_cls)
97{
98 return NULL;
99}
100
101
102/**
103 * Destroy the given defragmentation context.
104 */
105void
106GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *ctx)
107{
108 GNUNET_assert (0);
109}
110
111
112/**
113 * We have received a fragment. Process it.
114 *
115 * @param ctx the context
116 * @param sender who transmitted the fragment
117 * @param msg the message that was received
118 */
119void
120GNUNET_FRAGMENT_process (struct GNUNET_FRAGMENT_Context *ctx,
121 const struct GNUNET_PeerIdentity *sender,
122 const struct GNUNET_MessageHeader *msg)
123{
124 GNUNET_assert (0);
125}
126
127
128
129#if 0
130
131/**
132 * How many buckets does the fragment hash table
133 * have?
134 */
135#define DEFRAG_BUCKET_COUNT 16
136
137/**
138 * After how long do fragments time out?
139 */
140#ifndef DEFRAGMENTATION_TIMEOUT
141#define DEFRAGMENTATION_TIMEOUT (3 * GNUNET_CRON_MINUTES)
142#endif
143
144/**
145 * Entry in the linked list of fragments.
146 */
147typedef struct FL
148{
149 struct FL *link;
150 P2P_fragmentation_MESSAGE *frag;
151} FL;
152
153/**
154 * Entry in the GNUNET_hash table of fragments.
155 */
156typedef struct FC
157{
158 struct FC *next;
159 FL *head;
160 GNUNET_PeerIdentity sender;
161 int id;
162 GNUNET_CronTime ttl;
163} FC;
164
165#define FRAGSIZE(fl) ((ntohs(fl->frag->header.size)-sizeof(P2P_fragmentation_MESSAGE)))
166
167static GNUNET_CoreAPIForPlugins *coreAPI;
168
169static GNUNET_Stats_ServiceAPI *stats;
170
171static int stat_defragmented;
172
173static int stat_fragmented;
174
175static int stat_discarded;
176
177/**
178 * Hashtable *with* collision management!
179 */
180static FC *defragmentationCache[DEFRAG_BUCKET_COUNT];
181
182/**
183 * Lock for the defragmentation cache.
184 */
185static struct GNUNET_Mutex *defragCacheLock;
186
187static void
188freeFL (FL * fl, int c)
189{
190 while (fl != NULL)
191 {
192 FL *link = fl->link;
193 if (stats != NULL)
194 stats->change (stat_discarded, c);
195 GNUNET_free (fl->frag);
196 GNUNET_free (fl);
197 fl = link;
198 }
199}
200
201/**
202 * This cron job ensures that we purge buffers of fragments
203 * that have timed out. It can run in much longer intervals
204 * than the defragmentationCron, e.g. every 60s.
205 * <p>
206 * This method goes through the hashtable, finds entries that
207 * have timed out and removes them (and all the fragments that
208 * belong to the entry). It's a bit more complicated as the
209 * collision list is also collapsed.
210 */
211static void
212defragmentationPurgeCron (void *unused)
213{
214 int i;
215 FC *smf;
216 FC *next;
217 FC *last;
218
219 GNUNET_mutex_lock (defragCacheLock);
220 for (i = 0; i < DEFRAG_BUCKET_COUNT; i++)
221 {
222 last = NULL;
223 smf = defragmentationCache[i];
224 while (smf != NULL)
225 {
226 if (smf->ttl < GNUNET_get_time ())
227 {
228 /* free linked list of fragments */
229 freeFL (smf->head, 1);
230 next = smf->next;
231 GNUNET_free (smf);
232 if (last == NULL)
233 defragmentationCache[i] = next;
234 else
235 last->next = next;
236 smf = next;
237 }
238 else
239 {
240 last = smf;
241 smf = smf->next;
242 }
243 } /* while smf != NULL */
244 } /* for all buckets */
245 GNUNET_mutex_unlock (defragCacheLock);
246}
247
248/**
249 * Check if this fragment-list is complete. If yes, put it together,
250 * process and free all buffers. Does not free the pep
251 * itself (but sets the TTL to 0 to have the cron free it
252 * in the next iteration).
253 *
254 * @param pep the entry in the GNUNET_hash table
255 */
256static void
257checkComplete (FC * pep)
258{
259 FL *pos;
260 unsigned short off;
261 unsigned short len;
262 char *msg;
263
264 GNUNET_GE_ASSERT (NULL, pep != NULL);
265 pos = pep->head;
266 if (pos == NULL)
267 return;
268 len = ntohs (pos->frag->len);
269 if (len == 0)
270 goto CLEANUP; /* really bad error! */
271 off = 0;
272 while ((pos != NULL) && (ntohs (pos->frag->off) <= off))
273 {
274 if (off >= off + FRAGSIZE (pos))
275 goto CLEANUP; /* error! */
276 if (ntohs (pos->frag->off) + FRAGSIZE (pos) > off)
277 off = ntohs (pos->frag->off) + FRAGSIZE (pos);
278 else
279 goto CLEANUP; /* error! */
280 pos = pos->link;
281 }
282 if (off < len)
283 return; /* some fragment is still missing */
284
285 msg = GNUNET_malloc (len);
286 pos = pep->head;
287 while (pos != NULL)
288 {
289 memcpy (&msg[ntohs (pos->frag->off)], &pos->frag[1], FRAGSIZE (pos));
290 pos = pos->link;
291 }
292 if (stats != NULL)
293 stats->change (stat_defragmented, 1);
294#if 0
295 printf ("Finished defragmentation!\n");
296#endif
297 /* handle message! */
298 coreAPI->loopback_send (&pep->sender, msg, len, GNUNET_YES, NULL);
299 GNUNET_free (msg);
300CLEANUP:
301 /* free fragment buffers */
302 freeFL (pep->head, 0);
303 pep->head = NULL;
304 pep->ttl = 0;
305}
306
307/**
308 * See if the new fragment is a part of this entry and join them if
309 * yes. Return GNUNET_SYSERR if the fragments do not match. Return GNUNET_OK if
310 * the fragments do match and the fragment has been processed. The
311 * defragCacheLock is already acquired by the caller whenever this
312 * method is called.<p>
313 *
314 * @param entry the entry in the cache
315 * @param pep the new entry
316 * @param packet the ip part in the new entry
317 */
318static int
319tryJoin (FC * entry,
320 const GNUNET_PeerIdentity * sender,
321 const P2P_fragmentation_MESSAGE * packet)
322{
323 /* frame before ours; may end in the middle of
324 our frame or before it starts; NULL if we are
325 the earliest position we have received so far */
326 FL *before;
327 /* frame after ours; may start in the middle of
328 our frame or after it; NULL if we are the last
329 fragment we have received so far */
330 FL *after;
331 /* current position in the frame-list */
332 FL *pos;
333 /* the new entry that we're inserting */
334 FL *pep;
335 FL *tmp;
336 unsigned short end;
337
338 GNUNET_GE_ASSERT (NULL, entry != NULL);
339 if (0 != memcmp (sender, &entry->sender, sizeof (GNUNET_PeerIdentity)))
340 return GNUNET_SYSERR; /* wrong fragment list, try another! */
341 if (ntohl (packet->id) != entry->id)
342 return GNUNET_SYSERR; /* wrong fragment list, try another! */
343#if 0
344 printf ("Received fragment %u from %u to %u\n",
345 ntohl (packet->id),
346 ntohs (packet->off),
347 ntohs (packet->off) + ntohs (packet->header.size) -
348 sizeof (P2P_fragmentation_MESSAGE));
349#endif
350 pos = entry->head;
351 if ((pos != NULL) && (packet->len != pos->frag->len))
352 return GNUNET_SYSERR; /* wrong fragment size */
353
354 before = NULL;
355 /* find the before-frame */
356 while ((pos != NULL) && (ntohs (pos->frag->off) < ntohs (packet->off)))
357 {
358 before = pos;
359 pos = pos->link;
360 }
361
362 /* find the after-frame */
363 end =
364 ntohs (packet->off) + ntohs (packet->header.size) -
365 sizeof (P2P_fragmentation_MESSAGE);
366 if (end <= ntohs (packet->off))
367 {
368 GNUNET_GE_LOG (NULL,
369 GNUNET_GE_DEVELOPER | GNUNET_GE_DEBUG | GNUNET_GE_BULK,
370 "Received invalid fragment at %s:%d\n", __FILE__,
371 __LINE__);
372 return GNUNET_SYSERR; /* yuck! integer overflow! */
373 }
374
375 if (before != NULL)
376 after = before;
377 else
378 after = entry->head;
379 while ((after != NULL) && (ntohs (after->frag->off) < end))
380 after = after->link;
381
382 if ((before != NULL) && (before == after))
383 {
384 /* this implies after or before != NULL and thereby the new
385 fragment is redundant as it is fully enclosed in an earlier
386 fragment */
387 if (stats != NULL)
388 stats->change (stat_defragmented, 1);
389 return GNUNET_OK; /* drop, there is a packet that spans our range! */
390 }
391
392 if ((before != NULL) &&
393 (after != NULL) &&
394 ((htons (before->frag->off) +
395 FRAGSIZE (before)) >= htons (after->frag->off)))
396 {
397 /* this implies that the fragment that starts before us and the
398 fragment that comes after this one leave no space in the middle
399 or even overlap; thus we can drop this redundant piece */
400 if (stats != NULL)
401 stats->change (stat_defragmented, 1);
402 return GNUNET_OK;
403 }
404
405 /* allocate pep */
406 pep = GNUNET_malloc (sizeof (FC));
407 pep->frag = GNUNET_malloc (ntohs (packet->header.size));
408 memcpy (pep->frag, packet, ntohs (packet->header.size));
409 pep->link = NULL;
410
411 if (before == NULL)
412 {
413 pep->link = after;
414 pos = entry->head;
415 while (pos != after)
416 {
417 tmp = pos->link;
418 GNUNET_free (pos->frag);
419 GNUNET_free (pos);
420 pos = tmp;
421 }
422 entry->head = pep;
423 goto FINISH;
424 /* end of insert first */
425 }
426
427 if (after == NULL)
428 {
429 /* insert last: find the end, free everything after it */
430 freeFL (before->link, 1);
431 before->link = pep;
432 goto FINISH;
433 }
434
435 /* ok, we are filling the middle between two fragments; insert. If
436 there is anything else in the middle, it can be dropped as we're
437 bigger & cover that area as well */
438 /* free everything between before and after */
439 pos = before->link;
440 while (pos != after)
441 {
442 tmp = pos->link;
443 GNUNET_free (pos->frag);
444 GNUNET_free (pos);
445 pos = tmp;
446 }
447 before->link = pep;
448 pep->link = after;
449
450FINISH:
451 entry->ttl = GNUNET_get_time () + DEFRAGMENTATION_TIMEOUT;
452 checkComplete (entry);
453 return GNUNET_OK;
454}
455
456/**
457 * Defragment the given fragment and pass to handler once
458 * defragmentation is complete.
459 *
460 * @param frag the packet to defragment
461 * @return GNUNET_SYSERR if the fragment is invalid
462 */
463static int
464processFragment (const GNUNET_PeerIdentity * sender,
465 const GNUNET_MessageHeader * frag)
466{
467 unsigned int hash;
468 FC *smf;
469
470 if (ntohs (frag->size) < sizeof (P2P_fragmentation_MESSAGE))
471 return GNUNET_SYSERR;
472
473 GNUNET_mutex_lock (defragCacheLock);
474 hash = sender->hashPubKey.bits[0] % DEFRAG_BUCKET_COUNT;
475 smf = defragmentationCache[hash];
476 while (smf != NULL)
477 {
478 if (GNUNET_OK ==
479 tryJoin (smf, sender, (P2P_fragmentation_MESSAGE *) frag))
480 {
481 GNUNET_mutex_unlock (defragCacheLock);
482 return GNUNET_OK;
483 }
484 if (0 == memcmp (sender, &smf->sender, sizeof (GNUNET_PeerIdentity)))
485 {
486 freeFL (smf->head, 1);
487 break;
488 }
489 smf = smf->next;
490 }
491 if (smf == NULL)
492 {
493 smf = GNUNET_malloc (sizeof (FC));
494 smf->next = defragmentationCache[hash];
495 defragmentationCache[hash] = smf;
496 smf->ttl = GNUNET_get_time () + DEFRAGMENTATION_TIMEOUT;
497 smf->sender = *sender;
498 }
499 smf->id = ntohl (((P2P_fragmentation_MESSAGE *) frag)->id);
500 smf->head = GNUNET_malloc (sizeof (FL));
501 smf->head->link = NULL;
502 smf->head->frag = GNUNET_malloc (ntohs (frag->size));
503 memcpy (smf->head->frag, frag, ntohs (frag->size));
504
505 GNUNET_mutex_unlock (defragCacheLock);
506 return GNUNET_OK;
507}
508
509typedef struct
510{
511 GNUNET_PeerIdentity sender;
512 /* maximums size of each fragment */
513 unsigned short mtu;
514 /** how long is this message part expected to be? */
515 unsigned short len;
516 /** when did we intend to transmit? */
517 GNUNET_CronTime transmissionTime;
518} FragmentBMC;
519
520/**
521 * Send a message that had to be fragmented (right now!). First grabs
522 * the first part of the message (obtained from ctx->se) and stores
523 * that in a P2P_fragmentation_MESSAGE envelope. The remaining fragments are
524 * added to the send queue with GNUNET_EXTREME_PRIORITY (to ensure that they
525 * will be transmitted next). The logic here is that if the priority
526 * for the first fragment was sufficiently high, the priority should
527 * also have been sufficiently high for all of the other fragments (at
528 * this time) since they have the same priority. And we want to make
529 * sure that we send all of them since just sending the first fragment
530 * and then going to other messages of equal priority would not be
531 * such a great idea (i.e. would just waste bandwidth).
532 */
533static int
534fragmentBMC (void *buf, void *cls, unsigned short len)
535{
536 FragmentBMC *ctx = cls;
537 static int idGen = 0;
538 P2P_fragmentation_MESSAGE *frag;
539 unsigned int pos;
540 int id;
541 unsigned short mlen;
542
543 if ((len < ctx->mtu) || (buf == NULL))
544 {
545 GNUNET_free (ctx);
546 return GNUNET_SYSERR;
547 }
548 if (stats != NULL)
549 stats->change (stat_fragmented, 1);
550 id = (idGen++) + GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 512);
551 /* write first fragment to buf */
552 frag = (P2P_fragmentation_MESSAGE *) buf;
553 frag->header.size = htons (len);
554 frag->header.type = htons (GNUNET_P2P_PROTO_MESSAGE_FRAGMENT);
555 frag->id = id;
556 frag->off = htons (0);
557 frag->len = htons (ctx->len);
558 memcpy (&frag[1], &ctx[1], len - sizeof (P2P_fragmentation_MESSAGE));
559
560 /* create remaining fragments, add to queue! */
561 pos = len - sizeof (P2P_fragmentation_MESSAGE);
562 frag = GNUNET_malloc (ctx->mtu);
563 while (pos < ctx->len)
564 {
565 mlen = sizeof (P2P_fragmentation_MESSAGE) + ctx->len - pos;
566 if (mlen > ctx->mtu)
567 mlen = ctx->mtu;
568 GNUNET_GE_ASSERT (NULL, mlen > sizeof (P2P_fragmentation_MESSAGE));
569 frag->header.size = htons (mlen);
570 frag->header.type = htons (GNUNET_P2P_PROTO_MESSAGE_FRAGMENT);
571 frag->id = id;
572 frag->off = htons (pos);
573 frag->len = htons (ctx->len);
574 memcpy (&frag[1],
575 &((char *) (&ctx[1]))[pos],
576 mlen - sizeof (P2P_fragmentation_MESSAGE));
577 coreAPI->ciphertext_send (&ctx->sender,
578 &frag->header,
579 GNUNET_EXTREME_PRIORITY,
580 ctx->transmissionTime - GNUNET_get_time ());
581 pos += mlen - sizeof (P2P_fragmentation_MESSAGE);
582 }
583 GNUNET_GE_ASSERT (NULL, pos == ctx->len);
584 GNUNET_free (frag);
585 GNUNET_free (ctx);
586 return GNUNET_OK;
587}
588
589/**
590 * The given message must be fragmented. Produce a placeholder that
591 * corresponds to the first fragment. Once that fragment is scheduled
592 * for transmission, the placeholder should automatically add all of
593 * the other fragments (with very high priority).
594 */
595void
596fragment (const GNUNET_PeerIdentity * peer,
597 unsigned int mtu,
598 unsigned int prio,
599 unsigned int targetTime,
600 unsigned int len, GNUNET_BuildMessageCallback bmc, void *bmcClosure)
601{
602 FragmentBMC *fbmc;
603 int xlen;
604
605 GNUNET_GE_ASSERT (NULL, len > mtu);
606 GNUNET_GE_ASSERT (NULL, mtu > sizeof (P2P_fragmentation_MESSAGE));
607 fbmc = GNUNET_malloc (sizeof (FragmentBMC) + len);
608 fbmc->mtu = mtu;
609 fbmc->sender = *peer;
610 fbmc->transmissionTime = targetTime;
611 fbmc->len = len;
612 if (bmc == NULL)
613 {
614 memcpy (&fbmc[1], bmcClosure, len);
615 GNUNET_free (bmcClosure);
616 }
617 else
618 {
619 if (GNUNET_SYSERR == bmc (&fbmc[1], bmcClosure, len))
620 {
621 GNUNET_free (fbmc);
622 return;
623 }
624 }
625 xlen = mtu - sizeof (P2P_fragmentation_MESSAGE);
626 coreAPI->ciphertext_send_with_callback (peer, &fragmentBMC, fbmc, mtu, prio * xlen / len, /* compute new priority */
627 targetTime);
628}
629
630/**
631 * Initialize Fragmentation module.
632 */
633GNUNET_Fragmentation_ServiceAPI *
634provide_module_fragmentation (GNUNET_CoreAPIForPlugins * capi)
635{
636 static GNUNET_Fragmentation_ServiceAPI ret;
637 int i;
638
639 coreAPI = capi;
640 stats = coreAPI->service_request ("stats");
641 if (stats != NULL)
642 {
643 stat_defragmented =
644 stats->create (gettext_noop ("# messages defragmented"));
645 stat_fragmented =
646 stats->create (gettext_noop ("# messages fragmented"));
647 stat_discarded = stats->create (gettext_noop ("# fragments discarded"));
648 }
649 for (i = 0; i < DEFRAG_BUCKET_COUNT; i++)
650 defragmentationCache[i] = NULL;
651 defragCacheLock = GNUNET_mutex_create (GNUNET_NO);
652 GNUNET_cron_add_job (coreAPI->cron,
653 &defragmentationPurgeCron,
654 60 * GNUNET_CRON_SECONDS, 60 * GNUNET_CRON_SECONDS,
655 NULL);
656 GNUNET_GE_LOG (capi->ectx,
657 GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_REQUEST,
658 _("`%s' registering handler %d\n"), "fragmentation",
659 GNUNET_P2P_PROTO_MESSAGE_FRAGMENT);
660 capi->p2p_ciphertext_handler_register (GNUNET_P2P_PROTO_MESSAGE_FRAGMENT,
661 &processFragment);
662
663 ret.fragment = &fragment;
664 return &ret;
665}
666
667/**
668 * Shutdown fragmentation.
669 */
670void
671release_module_fragmentation ()
672{
673 int i;
674
675 coreAPI->p2p_ciphertext_handler_unregister
676 (GNUNET_P2P_PROTO_MESSAGE_FRAGMENT, &processFragment);
677 GNUNET_cron_del_job (coreAPI->cron, &defragmentationPurgeCron,
678 60 * GNUNET_CRON_SECONDS, NULL);
679 for (i = 0; i < DEFRAG_BUCKET_COUNT; i++)
680 {
681 FC *pos = defragmentationCache[i];
682 while (pos != NULL)
683 {
684 FC *next = pos->next;
685 freeFL (pos->head, 1);
686 GNUNET_free (pos);
687 pos = next;
688 }
689 }
690 if (stats != NULL)
691 {
692 coreAPI->service_release (stats);
693 stats = NULL;
694 }
695 GNUNET_mutex_destroy (defragCacheLock);
696 defragCacheLock = NULL;
697 coreAPI = NULL;
698}
699
700#endif
701
702/* end of fragmentation.c */
diff --git a/src/fragmentation/test_fragmentation.c b/src/fragmentation/test_fragmentation.c
new file mode 100644
index 000000000..e6e3e5d22
--- /dev/null
+++ b/src/fragmentation/test_fragmentation.c
@@ -0,0 +1,439 @@
1/*
2 This file is part of GNUnet
3 (C) 2004, 2009 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 2, 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 fragmentation/test_fragmentation.c
22 * @brief test for fragmentation.c
23 * @author Christian Grothoff
24 */
25
26/**
27 * Testcase for defragmentation code.
28 * We have testcases for:
29 * - 2 fragments, aligned, [0,16),[16,32)
30 * - n (50) fragments, [i*16,(i+1)*16)
31 * - n (50) fragments, [0,i*16) + [50*16,51*16)
32 * - n (100) fragments, inserted in interleaved order (holes in sequence)
33 * - holes in sequence
34 * - other overlaps
35 * - timeouts
36 * - multiple entries in GNUNET_hash-list
37 * - id collisions in GNUNET_hash-list
38 */
39
40#include "platform.h"
41#include "gnunet_fragmentation_lib.h"
42
43#if 0
44
45/* -- to speed up the testcases -- */
46#define DEFRAGMENTATION_TIMEOUT (1 * GNUNET_CRON_SECONDS)
47
48
49static GNUNET_PeerIdentity mySender;
50static char *myMsg;
51static unsigned short myMsgLen;
52
53/* static buffers to avoid lots of malloc/free */
54static char masterBuffer[65536];
55static char resultBuffer[65536];
56
57static void
58handleHelper (const GNUNET_PeerIdentity * sender,
59 const char *msg,
60 const unsigned int len, int wasEncrypted, GNUNET_TSession * ts)
61{
62 GNUNET_GE_ASSERT (NULL,
63 0 == memcmp (sender, &mySender,
64 sizeof (GNUNET_PeerIdentity)));
65 myMsg = resultBuffer;
66 memcpy (resultBuffer, msg, len);
67 myMsgLen = len;
68}
69
70/**
71 * Wait long enough to force all fragments to timeout.
72 */
73static void
74makeTimeout ()
75{
76 GNUNET_thread_sleep (DEFRAGMENTATION_TIMEOUT * 2);
77 defragmentationPurgeCron (NULL);
78}
79
80/**
81 * Create a fragment. The data-portion will be filled
82 * with a sequence of numbers from start+id to start+len-1+id.
83 *
84 * @param pep pointer to the ethernet frame/buffer
85 * @param ip pointer to the ip-header
86 * @param start starting-offset
87 * @param length of the data portion
88 * @param id the identity of the fragment
89 */
90static GNUNET_MessageHeader *
91makeFragment (unsigned short start,
92 unsigned short size, unsigned short tot, int id)
93{
94 P2P_fragmentation_MESSAGE *frag;
95 int i;
96
97 frag = (P2P_fragmentation_MESSAGE *) masterBuffer;
98 frag->id = htonl (id);
99 frag->off = htons (start);
100 frag->len = htons (tot);
101 frag->header.size = htons (sizeof (P2P_fragmentation_MESSAGE) + size);
102
103 for (i = 0; i < size; i++)
104 ((char *) &frag[1])[i] = (char) i + id + start;
105 return &frag->header;
106}
107
108/**
109 * Check that the packet received is what we expected to
110 * get.
111 * @param id the expected id
112 * @param len the expected length
113 */
114static void
115checkPacket (int id, unsigned int len)
116{
117 int i;
118
119 GNUNET_GE_ASSERT (NULL, myMsg != NULL);
120 GNUNET_GE_ASSERT (NULL, myMsgLen == len);
121 for (i = 0; i < len; i++)
122 GNUNET_GE_ASSERT (NULL, myMsg[i] == (char) (i + id));
123 myMsgLen = 0;
124 myMsg = NULL;
125}
126
127
128/* **************** actual testcases ***************** */
129
130static void
131testSimpleFragment ()
132{
133 GNUNET_MessageHeader *pep;
134
135 pep = makeFragment (0, 16, 32, 42);
136 processFragment (&mySender, pep);
137 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
138 pep = makeFragment (16, 16, 32, 42);
139 processFragment (&mySender, pep);
140 checkPacket (42, 32);
141}
142
143static void
144testSimpleFragmentTimeout ()
145{
146 GNUNET_MessageHeader *pep;
147
148 pep = makeFragment (0, 16, 32, 42);
149 processFragment (&mySender, pep);
150 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
151 makeTimeout ();
152 pep = makeFragment (16, 16, 32, 42);
153 processFragment (&mySender, pep);
154 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
155 pep = makeFragment (0, 16, 32, 42);
156 processFragment (&mySender, pep);
157 checkPacket (42, 32);
158}
159
160static void
161testSimpleFragmentReverse ()
162{
163 GNUNET_MessageHeader *pep;
164
165 pep = makeFragment (16, 16, 32, 42);
166 processFragment (&mySender, pep);
167 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
168 pep = makeFragment (0, 16, 32, 42);
169 processFragment (&mySender, pep);
170 checkPacket (42, 32);
171}
172
173static void
174testManyFragments ()
175{
176 GNUNET_MessageHeader *pep;
177 int i;
178
179 for (i = 0; i < 50; i++)
180 {
181 pep = makeFragment (i * 16, 16, 51 * 16, 42);
182 processFragment (&mySender, pep);
183 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
184 }
185 pep = makeFragment (50 * 16, 16, 51 * 16, 42);
186 processFragment (&mySender, pep);
187 checkPacket (42, 51 * 16);
188}
189
190static void
191testManyFragmentsMegaLarge ()
192{
193 GNUNET_MessageHeader *pep;
194 int i;
195
196 for (i = 0; i < 4000; i++)
197 {
198 pep = makeFragment (i * 16, 16, 4001 * 16, 42);
199 processFragment (&mySender, pep);
200 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
201 }
202 pep = makeFragment (4000 * 16, 16, 4001 * 16, 42);
203 processFragment (&mySender, pep);
204 checkPacket (42, 4001 * 16);
205}
206
207static void
208testLastFragmentEarly ()
209{
210 GNUNET_MessageHeader *pep;
211 int i;
212
213 for (i = 0; i < 5; i++)
214 {
215 pep = makeFragment (i * 16, 8, 6 * 16 + 8, 42);
216 processFragment (&mySender, pep);
217 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
218 }
219 pep = makeFragment (5 * 16, 24, 6 * 16 + 8, 42);
220 processFragment (&mySender, pep);
221 for (i = 0; i < 5; i++)
222 {
223 pep = makeFragment (i * 16 + 8, 8, 6 * 16 + 8, 42);
224 processFragment (&mySender, pep);
225 }
226 checkPacket (42, 6 * 16 + 8);
227}
228
229static void
230testManyInterleavedFragments ()
231{
232 GNUNET_MessageHeader *pep;
233 int i;
234
235 for (i = 0; i < 50; i++)
236 {
237 pep = makeFragment (i * 16, 8, 51 * 16 + 8, 42);
238 processFragment (&mySender, pep);
239 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
240 }
241 for (i = 0; i < 50; i++)
242 {
243 pep = makeFragment (i * 16 + 8, 8, 51 * 16 + 8, 42);
244 processFragment (&mySender, pep);
245 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
246 }
247 pep = makeFragment (50 * 16, 24, 51 * 16 + 8, 42);
248 processFragment (&mySender, pep);
249 checkPacket (42, 51 * 16 + 8);
250}
251
252static void
253testManyInterleavedOverlappingFragments ()
254{
255 GNUNET_MessageHeader *pep;
256 int i;
257
258 for (i = 0; i < 50; i++)
259 {
260 pep = makeFragment (i * 32, 16, 51 * 32, 42);
261 processFragment (&mySender, pep);
262 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
263 }
264 for (i = 0; i < 50; i++)
265 {
266 pep = makeFragment (i * 32 + 8, 24, 51 * 32, 42);
267 processFragment (&mySender, pep);
268 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
269 }
270 pep = makeFragment (50 * 32, 32, 51 * 32, 42);
271 processFragment (&mySender, pep);
272 checkPacket (42, 51 * 32);
273}
274
275static void
276testManyOverlappingFragments ()
277{
278 GNUNET_MessageHeader *pep;
279 int i;
280
281 for (i = 0; i < 50; i++)
282 {
283 pep = makeFragment (0, i * 16 + 16, 51 * 16, 42);
284 processFragment (&mySender, pep);
285 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
286 }
287 pep = makeFragment (50 * 16, 16, 51 * 16, 42);
288 processFragment (&mySender, pep);
289 checkPacket (42, 51 * 16);
290}
291
292static void
293testManyOverlappingFragmentsTimeout ()
294{
295 GNUNET_MessageHeader *pep;
296 int i;
297
298 for (i = 0; i < 50; i++)
299 {
300 pep = makeFragment (0, i * 16 + 16, 51 * 16 + 8, 42);
301 processFragment (&mySender, pep);
302 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
303 }
304 makeTimeout ();
305 pep = makeFragment (50 * 16, 24, 51 * 16 + 8, 42);
306 processFragment (&mySender, pep);
307 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
308 for (i = 0; i < 50; i++)
309 {
310 pep = makeFragment (0, i * 16 + 16, 51 * 16 + 8, 42);
311 processFragment (&mySender, pep);
312 }
313 checkPacket (42, 51 * 16 + 8);
314}
315
316static void
317testManyFragmentsMultiId ()
318{
319 GNUNET_MessageHeader *pep;
320 int i;
321 int id;
322
323 for (i = 0; i < 50; i++)
324 {
325 for (id = 0; id < DEFRAG_BUCKET_COUNT; id++)
326 {
327 pep = makeFragment (i * 16, 16, 51 * 16, id + 5);
328 mySender.hashPubKey.bits[0] = id;
329 processFragment (&mySender, pep);
330 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
331 }
332 }
333 for (id = 0; id < DEFRAG_BUCKET_COUNT; id++)
334 {
335 pep = makeFragment (50 * 16, 16, 51 * 16, id + 5);
336 mySender.hashPubKey.bits[0] = id;
337 processFragment (&mySender, pep);
338 checkPacket (id + 5, 51 * 16);
339 }
340}
341
342static void
343testManyFragmentsMultiIdCollisions ()
344{
345 GNUNET_MessageHeader *pep;
346 int i;
347 int id;
348
349 for (i = 0; i < 5; i++)
350 {
351 for (id = 0; id < DEFRAG_BUCKET_COUNT * 4; id++)
352 {
353 pep = makeFragment (i * 16, 16, 6 * 16, id + 5);
354 mySender.hashPubKey.bits[0] = id;
355 processFragment (&mySender, pep);
356 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
357 }
358 }
359 for (id = 0; id < DEFRAG_BUCKET_COUNT * 4; id++)
360 {
361 pep = makeFragment (5 * 16, 16, 6 * 16, id + 5);
362 mySender.hashPubKey.bits[0] = id;
363 processFragment (&mySender, pep);
364 checkPacket (id + 5, 6 * 16);
365 }
366}
367
368/* ************* driver ****************** */
369
370static int
371p2p_register_handler (const unsigned short type,
372 GNUNET_P2PRequestHandler callback)
373{
374 return GNUNET_OK;
375}
376
377static int
378p2p_unregister_handler (const unsigned short type,
379 GNUNET_P2PRequestHandler callback)
380{
381 return GNUNET_OK;
382}
383
384
385static void *
386request_service (const char *name)
387{
388 return NULL;
389}
390
391#endif
392
393int
394main (int argc, char *argv[])
395{
396 fprintf (stderr, "WARNING: testcase not yet ported to new API.\n");
397#if 0
398 GNUNET_CoreAPIForPlugins capi;
399
400 memset (&capi, 0, sizeof (GNUNET_CoreAPIForPlugins));
401 capi.cron = GNUNET_cron_create (NULL);
402 capi.loopback_send = &handleHelper;
403 capi.service_request = &request_service;
404 capi.p2p_ciphertext_handler_register = &p2p_register_handler;
405 capi.p2p_ciphertext_handler_unregister = &p2p_unregister_handler;
406 provide_module_fragmentation (&capi);
407
408 fprintf (stderr, ".");
409 testSimpleFragment ();
410 fprintf (stderr, ".");
411 testSimpleFragmentTimeout ();
412 fprintf (stderr, ".");
413 testSimpleFragmentReverse ();
414 fprintf (stderr, ".");
415 testManyFragments ();
416 fprintf (stderr, ".");
417 testManyFragmentsMegaLarge ();
418 fprintf (stderr, ".");
419 testManyFragmentsMultiId ();
420 fprintf (stderr, ".");
421
422 testManyInterleavedFragments ();
423 fprintf (stderr, ".");
424 testManyInterleavedOverlappingFragments ();
425 fprintf (stderr, ".");
426 testManyOverlappingFragments ();
427 fprintf (stderr, ".");
428 testManyOverlappingFragmentsTimeout ();
429 fprintf (stderr, ".");
430 testLastFragmentEarly ();
431 fprintf (stderr, ".");
432 testManyFragmentsMultiIdCollisions ();
433 fprintf (stderr, ".");
434 release_module_fragmentation ();
435 fprintf (stderr, "\n");
436 GNUNET_cron_destroy (capi.cron);
437#endif
438 return 0; /* testcase passed */
439}
diff --git a/src/hello/Makefile.am b/src/hello/Makefile.am
new file mode 100644
index 000000000..cffb7201c
--- /dev/null
+++ b/src/hello/Makefile.am
@@ -0,0 +1,28 @@
1INCLUDES = -I$(top_srcdir)/src/include
2
3if MINGW
4 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
5endif
6
7if USE_COVERAGE
8 AM_CFLAGS = --coverage
9endif
10
11lib_LTLIBRARIES = libgnunethello.la
12
13libgnunethello_la_SOURCES = \
14 hello.c
15libgnunethello_la_LIBADD = \
16 $(top_builddir)/src/util/libgnunetutil.la
17
18check_PROGRAMS = \
19 test_hello
20
21TESTS = $(check_PROGRAMS)
22
23test_hello_SOURCES = \
24 test_hello.c
25test_hello_LDADD = \
26 $(top_builddir)/src/hello/libgnunethello.la \
27 $(top_builddir)/src/util/libgnunetutil.la
28
diff --git a/src/hello/hello.c b/src/hello/hello.c
new file mode 100644
index 000000000..5a21bd41f
--- /dev/null
+++ b/src/hello/hello.c
@@ -0,0 +1,482 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 hello/hello.c
23 * @brief helper library for handling HELLOs
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_hello_lib.h"
28#include "gnunet_protocols.h"
29#include "gnunet_server_lib.h"
30
31/**
32 * A HELLO message is used to exchange information about
33 * transports with other peers. This struct is always
34 * followed by the actual network addresses which have
35 * the format:
36 *
37 * 1) transport-name (0-terminated)
38 * 2) address-length (uint32_t, network byte order; possibly
39 * unaligned!)
40 * 3) address expiration (GNUNET_TIME_AbsoluteNBO); possibly
41 * unaligned!)
42 * 4) address (address-length bytes; possibly unaligned!)
43 */
44struct GNUNET_HELLO_Message
45{
46 /**
47 * Type will be GNUNET_MESSAGE_TYPE_HELLO.
48 */
49 struct GNUNET_MessageHeader header;
50
51 /**
52 * Always zero (for alignment).
53 */
54 uint32_t reserved GNUNET_PACKED;
55
56 /**
57 * The public key of the peer.
58 */
59 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded publicKey;
60
61};
62
63
64/**
65 * Copy the given address information into
66 * the given buffer using the format of HELLOs.
67 *
68 * @param tname name of the transport plugin
69 * @param expiration expiration for the address
70 * @param addr the address
71 * @param addr_len length of the address in bytes
72 * @param target where to copy the address
73 * @param max maximum number of bytes to copy to target
74 * @return number of bytes copied, 0 if
75 * the target buffer was not big enough.
76 */
77size_t
78GNUNET_HELLO_add_address (const char *tname,
79 struct GNUNET_TIME_Absolute expiration,
80 const void *addr,
81 size_t addr_len, char *target, size_t max)
82{
83 uint32_t alen;
84 size_t slen;
85 struct GNUNET_TIME_AbsoluteNBO exp;
86
87 slen = strlen (tname) + 1;
88 if (slen + sizeof (uint32_t) + sizeof (struct GNUNET_TIME_AbsoluteNBO) +
89 addr_len > max)
90 return 0;
91 exp = GNUNET_TIME_absolute_hton (expiration);
92 alen = htonl ((uint32_t) addr_len);
93 memcpy (target, tname, slen);
94 memcpy (&target[slen], &alen, sizeof (uint32_t));
95 slen += sizeof (uint32_t);
96 memcpy (&target[slen], &exp, sizeof (struct GNUNET_TIME_AbsoluteNBO));
97 slen += sizeof (struct GNUNET_TIME_AbsoluteNBO);
98 memcpy (&target[slen], addr, addr_len);
99 slen += addr_len;
100 return slen;
101}
102
103
104/**
105 * Get the size of an address entry in a HELLO message.
106 *
107 * @param buf pointer to the start of the address entry
108 * @param max maximum size of the entry (end of buf)
109 * @param ralen set to the address length
110 * @return size of the entry, or 0 if max is not large enough
111 */
112static size_t
113get_hello_address_size (const char *buf, size_t max, uint32_t * ralen)
114{
115 const char *pos;
116 uint32_t alen;
117 size_t left;
118 size_t slen;
119
120 left = max;
121 pos = buf;
122 slen = 1;
123 while ((left > 0) && ('\0' != *pos))
124 {
125 left--;
126 pos++;
127 slen++;
128 }
129 if ('\0' != *pos)
130 {
131 /* 0-termination not found */
132 GNUNET_break_op (0);
133 return 0;
134 }
135 pos++;
136 if (left < sizeof (uint32_t) + sizeof (struct GNUNET_TIME_AbsoluteNBO))
137 {
138 /* not enough space for addrlen */
139 GNUNET_break_op (0);
140 return 0;
141 }
142 memcpy (&alen, pos, sizeof (uint32_t));
143 alen = ntohl (alen);
144 *ralen = alen;
145 slen += alen + sizeof (uint32_t) + sizeof (struct GNUNET_TIME_AbsoluteNBO);
146 if (max < slen)
147 {
148 /* not enough space for addr */
149 GNUNET_break_op (0);
150 return 0;
151 }
152 return slen;
153}
154
155
156/**
157 * Construct a HELLO message given the public key,
158 * expiration time and an iterator that spews the
159 * transport addresses.
160 *
161 * @return the hello message
162 */
163struct GNUNET_HELLO_Message *
164GNUNET_HELLO_create (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
165 *publicKey,
166 GNUNET_HELLO_GenerateAddressListCallback addrgen,
167 void *addrgen_cls)
168{
169 char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 256 -
170 sizeof (struct GNUNET_HELLO_Message)];
171 size_t max;
172 size_t used;
173 size_t ret;
174 struct GNUNET_HELLO_Message *hello;
175
176 max = sizeof (buffer);
177 used = 0;
178 while (0 != (ret = addrgen (addrgen_cls, max, &buffer[used])))
179 {
180 max -= ret;
181 used += ret;
182 }
183 hello = GNUNET_malloc (sizeof (struct GNUNET_HELLO_Message) + used);
184 hello->header.type = htons (GNUNET_MESSAGE_TYPE_HELLO);
185 hello->header.size = htons (sizeof (struct GNUNET_HELLO_Message) + used);
186 memcpy (&hello->publicKey, publicKey,
187 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
188 memcpy (&hello[1], buffer, used);
189 return hello;
190}
191
192
193/**
194 * Iterate over all of the addresses in the HELLO.
195 *
196 * @param msg HELLO to iterate over
197 * @param return_modified if a modified copy should be returned,
198 * otherwise NULL will be returned
199 * @param it iterator to call on each address
200 * @param it_cls closure for it
201 */
202struct GNUNET_HELLO_Message *
203GNUNET_HELLO_iterate_addresses (const struct GNUNET_HELLO_Message *msg,
204 int return_modified,
205 GNUNET_HELLO_AddressIterator it, void *it_cls)
206{
207 uint16_t msize;
208 struct GNUNET_HELLO_Message *ret;
209 const char *inptr;
210 size_t insize;
211 size_t esize;
212 size_t wpos;
213 char *woff;
214 uint32_t alen;
215 struct GNUNET_TIME_AbsoluteNBO expire;
216 int iret;
217
218 msize = GNUNET_HELLO_size (msg);
219 if ((msize < sizeof (struct GNUNET_HELLO_Message)) ||
220 (ntohs (msg->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
221 return NULL;
222 ret = NULL;
223 if (return_modified)
224 {
225 ret = GNUNET_malloc (msize);
226 memcpy (ret, msg, msize);
227 }
228 inptr = (const char *) &msg[1];
229 insize = msize - sizeof (struct GNUNET_HELLO_Message);
230 wpos = 0;
231 woff = (ret != NULL) ? (char *) &ret[1] : NULL;
232 while (insize > 0)
233 {
234 esize = get_hello_address_size (inptr, insize, &alen);
235 if (esize == 0)
236 {
237 GNUNET_break (0);
238 GNUNET_free_non_null (ret);
239 return NULL;
240 }
241 memcpy (&expire,
242 &inptr[esize - alen - sizeof (struct GNUNET_TIME_AbsoluteNBO)],
243 sizeof (struct GNUNET_TIME_AbsoluteNBO));
244 iret = it (it_cls,
245 inptr,
246 GNUNET_TIME_absolute_ntoh (expire),
247 &inptr[esize - alen], alen);
248 if (iret == GNUNET_SYSERR)
249 {
250 if (ret != NULL)
251 ret->header.size =
252 ntohs (sizeof (struct GNUNET_HELLO_Message) + wpos);
253 return ret;
254 }
255 if ((iret == GNUNET_OK) && (ret != NULL))
256 {
257 memcpy (woff, inptr, esize);
258 woff += esize;
259 wpos += esize;
260 }
261 insize -= esize;
262 inptr += esize;
263 }
264 if (ret != NULL)
265 ret->header.size = ntohs (sizeof (struct GNUNET_HELLO_Message) + wpos);
266 return ret;
267}
268
269
270struct ExpireContext
271{
272 const void *addr;
273 size_t addrlen;
274 int found;
275 struct GNUNET_TIME_Absolute expiration;
276};
277
278
279static int
280get_match_exp (void *cls,
281 const char *tname,
282 struct GNUNET_TIME_Absolute expiration,
283 const void *addr, size_t addrlen)
284{
285 struct ExpireContext *ec = cls;
286
287 if ((addrlen == ec->addrlen) && (0 == memcmp (addr, ec->addr, addrlen)))
288 {
289 ec->found = GNUNET_YES;
290 ec->expiration = expiration;
291 return GNUNET_SYSERR; /* done here */
292 }
293 return GNUNET_OK;
294}
295
296
297struct MergeContext
298{
299 const struct GNUNET_HELLO_Message *h1;
300 const struct GNUNET_HELLO_Message *h2;
301 const struct GNUNET_HELLO_Message *other;
302 char *buf;
303 size_t max;
304 size_t ret;
305 int take_equal;
306
307};
308
309
310static int
311copy_latest (void *cls,
312 const char *tname,
313 struct GNUNET_TIME_Absolute expiration,
314 const void *addr, size_t addrlen)
315{
316 struct MergeContext *mc = cls;
317 struct ExpireContext ec;
318
319 ec.addr = addr;
320 ec.addrlen = addrlen;
321 ec.found = GNUNET_NO;
322 GNUNET_HELLO_iterate_addresses (mc->other, GNUNET_NO, &get_match_exp, &ec);
323 if ((ec.found == GNUNET_NO) ||
324 ((ec.expiration.value < expiration.value) ||
325 ((ec.expiration.value == expiration.value) &&
326 (mc->take_equal == GNUNET_YES))))
327 mc->ret += GNUNET_HELLO_add_address (tname,
328 expiration,
329 addr,
330 addrlen,
331 &mc->buf[mc->ret],
332 mc->max - mc->ret);
333 return GNUNET_OK;
334}
335
336
337static size_t
338merge_addr (void *cls, size_t max, void *buf)
339{
340 struct MergeContext *mc = cls;
341
342 if (mc->h1 == NULL)
343 return 0;
344 mc->ret = 0;
345 mc->max = max;
346 mc->buf = buf;
347 mc->take_equal = GNUNET_NO;
348 mc->other = mc->h2;
349 GNUNET_HELLO_iterate_addresses (mc->h1, GNUNET_NO, &copy_latest, mc);
350 mc->take_equal = GNUNET_YES;
351 mc->other = mc->h1;
352 GNUNET_HELLO_iterate_addresses (mc->h2, GNUNET_NO, &copy_latest, mc);
353 mc->h1 = NULL;
354 return mc->ret;
355}
356
357
358/**
359 * Construct a HELLO message by merging the
360 * addresses in two existing HELLOs (which
361 * must be for the same peer).
362 *
363 * @param h1 first HELLO message
364 * @param h2 the second HELLO message
365 * @return the combined hello message
366 */
367struct GNUNET_HELLO_Message *
368GNUNET_HELLO_merge (const struct GNUNET_HELLO_Message *h1,
369 const struct GNUNET_HELLO_Message *h2)
370{
371 struct MergeContext mc = { h1, h2, NULL, NULL, 0, 0, 0 };
372
373 return GNUNET_HELLO_create (&h1->publicKey, &merge_addr, &mc);
374}
375
376
377struct DeltaContext
378{
379 struct GNUNET_TIME_Absolute expiration_limit;
380
381 GNUNET_HELLO_AddressIterator it;
382
383 void *it_cls;
384
385 const struct GNUNET_HELLO_Message *old_hello;
386};
387
388
389static int
390delta_match (void *cls,
391 const char *tname,
392 struct GNUNET_TIME_Absolute expiration,
393 const void *addr, size_t addrlen)
394{
395 struct DeltaContext *dc = cls;
396 int ret;
397 struct ExpireContext ec;
398
399 ec.addr = addr;
400 ec.addrlen = addrlen;
401 ec.found = GNUNET_NO;
402 GNUNET_HELLO_iterate_addresses (dc->old_hello,
403 GNUNET_NO, &get_match_exp, &ec);
404 if ((ec.found == GNUNET_YES) &&
405 ((ec.expiration.value > expiration.value) ||
406 (ec.expiration.value >= dc->expiration_limit.value)))
407 return GNUNET_YES; /* skip */
408 ret = dc->it (dc->it_cls, tname, expiration, addr, addrlen);
409 return ret;
410}
411
412
413/**
414 * Iterate over addresses in "new_hello" that
415 * are NOT already present in "old_hello".
416 *
417 * @param new_hello a HELLO message
418 * @param old_hello a HELLO message
419 * @param expiration_limit ignore addresses in old_hello
420 * that expired before the given time stamp
421 * @param it iterator to call on each address
422 * @param it_cls closure for it
423 */
424void
425GNUNET_HELLO_iterate_new_addresses (const struct GNUNET_HELLO_Message
426 *new_hello,
427 const struct GNUNET_HELLO_Message
428 *old_hello,
429 struct GNUNET_TIME_Absolute
430 expiration_limit,
431 GNUNET_HELLO_AddressIterator it,
432 void *it_cls)
433{
434 struct DeltaContext dc;
435
436 dc.expiration_limit = expiration_limit;
437 dc.it = it;
438 dc.it_cls = it_cls;
439 dc.old_hello = old_hello;
440 GNUNET_HELLO_iterate_addresses (new_hello, GNUNET_NO, &delta_match, &dc);
441}
442
443
444/**
445 * Return the size of the given HELLO message.
446 * @param hello to inspect
447 * @return the size, 0 if HELLO is invalid
448 */
449uint16_t
450GNUNET_HELLO_size (const struct GNUNET_HELLO_Message *hello)
451{
452 uint16_t ret = ntohs (hello->header.size);
453 if ((ret < sizeof (struct GNUNET_HELLO_Message)) ||
454 (ntohs (hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
455 return 0;
456 return ret;
457}
458
459
460/**
461 * Get the public key from a HELLO message.
462 *
463 * @param hello the hello message
464 * @param publicKey where to copy the public key information, can be NULL
465 * @return GNUNET_SYSERR if the HELLO was malformed
466 */
467int
468GNUNET_HELLO_get_key (const struct GNUNET_HELLO_Message *hello,
469 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
470 *publicKey)
471{
472 uint16_t ret = ntohs (hello->header.size);
473 if ((ret < sizeof (struct GNUNET_HELLO_Message)) ||
474 (ntohs (hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
475 return GNUNET_SYSERR;
476 *publicKey = hello->publicKey;
477 return GNUNET_OK;
478}
479
480
481
482/* end of hello.c */
diff --git a/src/hello/test_hello.c b/src/hello/test_hello.c
new file mode 100644
index 000000000..728afd63f
--- /dev/null
+++ b/src/hello/test_hello.c
@@ -0,0 +1,185 @@
1/*
2 This file is part of GNUnet
3 (C) 2009 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 2, 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 hello/test_hello.c
22 * @brief test for hello.c
23 * @author Christian Grothoff
24 */
25
26/**
27 * Testcase for HELLO code.
28 */
29#include "platform.h"
30#include "gnunet_hello_lib.h"
31
32#define DEBUG 0
33
34static size_t
35my_addr_gen (void *cls, size_t max, void *buf)
36{
37 unsigned int *i = cls;
38 size_t ret;
39
40#if DEBUG
41 fprintf (stderr, "DEBUG: my_addr_gen called with i = %d\n", *i);
42#endif
43 if (0 == *i)
44 return 0;
45 ret = GNUNET_HELLO_add_address ("test",
46 GNUNET_TIME_absolute_get (),
47 "address_information", *i, buf, max);
48 (*i)--;
49 return ret;
50}
51
52
53static int
54check_addr (void *cls,
55 const char *tname,
56 struct GNUNET_TIME_Absolute expiration,
57 const void *addr, size_t addrlen)
58{
59 unsigned int *i = cls;
60
61#if DEBUG
62 fprintf (stderr, "DEBUG: check_addr called with i = %d and addrlen = %u\n",
63 *i, addrlen);
64#endif
65 GNUNET_assert (addrlen > 0);
66 GNUNET_assert (*i & (1 << (addrlen - 1)));
67 *i -= (1 << (addrlen - 1));
68 GNUNET_assert (0 == strncmp ("address_information", addr, addrlen));
69 GNUNET_assert (0 == strcmp ("test", tname));
70 return GNUNET_OK;
71}
72
73
74static int
75remove_some (void *cls,
76 const char *tname,
77 struct GNUNET_TIME_Absolute expiration,
78 const void *addr, size_t addrlen)
79{
80 unsigned int *i = cls;
81
82#if DEBUG
83 fprintf (stderr, "DEBUG: remove_some called with i = %d and addrlen = %u\n",
84 *i, addrlen);
85#endif
86 GNUNET_assert (addrlen > 0);
87 if (*i & (1 << (addrlen - 1)))
88 {
89 *i -= (1 << (addrlen - 1));
90 return GNUNET_NO;
91 }
92 return GNUNET_OK;
93}
94
95
96int
97main (int argc, char *argv[])
98{
99 struct GNUNET_HELLO_Message *msg1;
100 struct GNUNET_HELLO_Message *msg2;
101 struct GNUNET_HELLO_Message *msg3;
102 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded publicKey;
103 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk;
104 struct GNUNET_TIME_Absolute startup_time;
105 int ok;
106 unsigned int i;
107
108 GNUNET_log_setup ("test-hello", "DEBUG", NULL);
109 startup_time = GNUNET_TIME_absolute_get ();
110 ok = 0;
111 memset (&publicKey, 42, sizeof (publicKey));
112 fprintf (stderr, "Testing HELLO creation (without addresses)...\n");
113 i = 0;
114 msg1 = GNUNET_HELLO_create (&publicKey, &my_addr_gen, &i);
115 GNUNET_assert (msg1 != NULL);
116 GNUNET_assert (0 < GNUNET_HELLO_size (msg1));
117
118 fprintf (stderr, "Testing address iteration (empty set)...\n");
119 GNUNET_assert (NULL ==
120 GNUNET_HELLO_iterate_addresses (msg1,
121 GNUNET_NO, &check_addr, &i));
122
123 fprintf (stderr, "Testing HELLO creation (with one address)...\n");
124 i = 1;
125 msg2 = GNUNET_HELLO_create (&publicKey, &my_addr_gen, &i);
126 GNUNET_assert (msg2 != NULL);
127 GNUNET_assert (GNUNET_HELLO_size (msg1) < GNUNET_HELLO_size (msg2));
128
129 fprintf (stderr, "Testing address iteration (one address)...\n");
130 i = 1;
131 GNUNET_assert (NULL ==
132 GNUNET_HELLO_iterate_addresses (msg2,
133 GNUNET_NO, &check_addr, &i));
134 GNUNET_assert (i == 0);
135
136 fprintf (stderr, "Testing get_key from HELLO...\n");
137 GNUNET_assert (GNUNET_OK == GNUNET_HELLO_get_key (msg2, &pk));
138 GNUNET_assert (0 == memcmp (&publicKey, &pk, sizeof (pk)));
139 GNUNET_free (msg1);
140
141 fprintf (stderr, "Testing HELLO creation (with two addresses)...\n");
142 i = 2;
143 msg3 = GNUNET_HELLO_create (&publicKey, &my_addr_gen, &i);
144 GNUNET_assert (msg3 != NULL);
145 GNUNET_assert (GNUNET_HELLO_size (msg2) < GNUNET_HELLO_size (msg3));
146
147 fprintf (stderr, "Testing address iteration (two addresses)...\n");
148 i = 3;
149 GNUNET_assert (NULL ==
150 GNUNET_HELLO_iterate_addresses (msg3,
151 GNUNET_NO, &check_addr, &i));
152 GNUNET_assert (i == 0);
153
154 fprintf (stderr, "Testing HELLO merge...\n");
155 msg1 = GNUNET_HELLO_merge (msg2, msg3);
156 GNUNET_assert (GNUNET_HELLO_size (msg1) == GNUNET_HELLO_size (msg3));
157
158 i = 3;
159 GNUNET_assert (NULL ==
160 GNUNET_HELLO_iterate_addresses (msg1,
161 GNUNET_NO, &check_addr, &i));
162 GNUNET_assert (i == 0);
163 GNUNET_free (msg1);
164
165 fprintf (stderr, "Testing address iteration to copy HELLO...\n");
166 i = 2;
167 msg1 = GNUNET_HELLO_iterate_addresses (msg3, GNUNET_YES, &remove_some, &i);
168 GNUNET_assert (msg1 != NULL);
169 GNUNET_assert (i == 0);
170 i = 1;
171 GNUNET_assert (NULL ==
172 GNUNET_HELLO_iterate_addresses (msg1,
173 GNUNET_NO, &check_addr, &i));
174 GNUNET_assert (i == 0);
175 GNUNET_free (msg1);
176
177 fprintf (stderr, "Testing delta address iteration...\n");
178 i = 2;
179 GNUNET_HELLO_iterate_new_addresses (msg3,
180 msg2, startup_time, &check_addr, &i);
181 GNUNET_assert (i == 0);
182 GNUNET_free (msg2);
183 GNUNET_free (msg3);
184 return 0; /* testcase passed */
185}
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
new file mode 100644
index 000000000..8c49690e7
--- /dev/null
+++ b/src/include/Makefile.am
@@ -0,0 +1,42 @@
1SUBDIRS = .
2
3EXTRA_DIST = \
4 gettext.h \
5 platform.h \
6 plibc.h \
7 winproc.h
8
9gnunetincludedir = $(includedir)/GNUnet
10
11nodist_gnunetinclude_HEADERS = \
12 gnunet_directories.h
13
14gnunetinclude_HEADERS = \
15 gnunet_arm_service.h \
16 gnunet_client_lib.h \
17 gnunet_common.h \
18 gnunet_configuration_lib.h \
19 gnunet_container_lib.h \
20 gnunet_core_service.h \
21 gnunet_crypto_lib.h \
22 gnunet_disk_lib.h \
23 gnunet_fragmentation_lib.h \
24 gnunet_getopt_lib.h \
25 gnunet_hello_lib.h \
26 gnunet_network_lib.h \
27 gnunet_peerinfo_service.h \
28 gnunet_program_lib.h \
29 gnunet_protocols.h \
30 gnunet_pseudonym_lib.h \
31 gnunet_resolver_service.h \
32 gnunet_scheduler_lib.h \
33 gnunet_server_lib.h \
34 gnunet_service_lib.h \
35 gnunet_signal_lib.h \
36 gnunet_signatures.h \
37 gnunet_statistics_service.h \
38 gnunet_strings_lib.h \
39 gnunet_time_lib.h \
40 gnunet_transport_service.h \
41 gnunet_upnp_service.h \
42 gnunet_util_lib.h
diff --git a/src/include/gettext.h b/src/include/gettext.h
new file mode 100644
index 000000000..c89197cfc
--- /dev/null
+++ b/src/include/gettext.h
@@ -0,0 +1,71 @@
1/* Convenience header for conditional use of GNU <libintl.h>.
2 Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published
6 by the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 USA. */
18
19#ifndef _LIBGETTEXT_H
20#define _LIBGETTEXT_H 1
21
22/* NLS can be disabled through the configure --disable-nls option. */
23#if ENABLE_NLS
24
25/* Get declarations of GNU message catalog functions. */
26# include <libintl.h>
27
28#else
29
30/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
31 chokes if dcgettext is defined as a macro. So include it now, to make
32 later inclusions of <locale.h> a NOP. We don't include <libintl.h>
33 as well because people using "gettext.h" will not include <libintl.h>,
34 and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
35 is GNUNET_OK. */
36#if defined(__sun)
37# include <locale.h>
38#endif
39
40/* Disabled NLS.
41 The casts to 'const char *' serve the purpose of producing warnings
42 for invalid uses of the value returned from these functions.
43 On pre-ANSI systems without 'const', the config.h file is supposed to
44 contain "#define const". */
45# define gettext(Msgid) ((const char *) (Msgid))
46# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
47# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
48# define ngettext(Msgid1, Msgid2, N) \
49 ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
50# define dngettext(Domainname, Msgid1, Msgid2, N) \
51 ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
52# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
53 ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
54/* slight modification here to avoid warnings: generate GNUNET_NO code,
55 not even the cast... */
56# define textdomain(Domainname)
57# define bindtextdomain(Domainname, Dirname)
58# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
59
60#endif
61
62/* A pseudo function call that serves as a marker for the automated
63 extraction of messages, but does not call gettext(). The run-time
64 translation is done at a different place in the code.
65 The argument, String, should be a literal string. Concatenated strings
66 and other string expressions won't work.
67 The macro's expansion is not parenthesized, so that it is suitable as
68 initializer for static 'char[]' or 'const char[]' variables. */
69#define gettext_noop(String) String
70
71#endif /* _LIBGETTEXT_H */
diff --git a/src/include/gnunet_arm_service.h b/src/include/gnunet_arm_service.h
new file mode 100644
index 000000000..012c27877
--- /dev/null
+++ b/src/include/gnunet_arm_service.h
@@ -0,0 +1,107 @@
1/*
2 This file is part of GNUnet
3 (C) 2009 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 2, 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 include/gnunet_arm_service.h
23 * @brief API to access gnunet-arm
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_ARM_SERVICE_H
28#define GNUNET_ARM_SERVICE_H
29
30#ifdef __cplusplus
31extern "C"
32{
33#if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38#include "gnunet_configuration_lib.h"
39#include "gnunet_scheduler_lib.h"
40#include "gnunet_time_lib.h"
41
42/**
43 * Version of the arm API.
44 */
45#define GNUNET_ARM_VERSION 0x00000000
46
47
48/**
49 * Callback function invoked when operation is complete.
50 *
51 * @param cls closure
52 * @param success GNUNET_YES if we think the service is running
53 * GNUNET_NO if we think the service is stopped
54 * GNUNET_SYSERR if we think ARM was not running
55 */
56typedef void (*GNUNET_ARM_Callback) (void *cls, int success);
57
58
59/**
60 * Start a service.
61 *
62 * @param service_name name of the service
63 * @param cfg configuration to use (needed to contact ARM;
64 * the ARM service may internally use a different
65 * configuration to determine how to start the service).
66 * @param sched scheduler to use
67 * @param timeout how long to wait before failing for good
68 * @param cb callback to invoke when service is ready
69 * @param cb_cls closure for callback
70 */
71void
72GNUNET_ARM_start_service (const char *service_name,
73 struct GNUNET_CONFIGURATION_Handle *cfg,
74 struct GNUNET_SCHEDULER_Handle *sched,
75 struct GNUNET_TIME_Relative timeout,
76 GNUNET_ARM_Callback cb, void *cb_cls);
77
78
79/**
80 * Stop a service.
81 *
82 * @param service_name name of the service
83 * @param cfg configuration to use (needed to contact ARM;
84 * the ARM service may internally use a different
85 * configuration to determine how to start the service).
86 * @param sched scheduler to use
87 * @param timeout how long to wait before failing for good
88 * @param cb callback to invoke when service is ready
89 * @param cb_cls closure for callback
90 */
91void
92GNUNET_ARM_stop_service (const char *service_name,
93 struct GNUNET_CONFIGURATION_Handle *cfg,
94 struct GNUNET_SCHEDULER_Handle *sched,
95 struct GNUNET_TIME_Relative timeout,
96 GNUNET_ARM_Callback cb, void *cb_cls);
97
98
99
100#if 0 /* keep Emacsens' auto-indent happy */
101{
102#endif
103#ifdef __cplusplus
104}
105#endif
106
107#endif
diff --git a/src/include/gnunet_client_lib.h b/src/include/gnunet_client_lib.h
new file mode 100644
index 000000000..6a77aa391
--- /dev/null
+++ b/src/include/gnunet_client_lib.h
@@ -0,0 +1,160 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 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 2, 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 include/gnunet_client_lib.h
23 * @brief functions related to accessing services
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_CLIENT_LIB_H
28#define GNUNET_CLIENT_LIB_H
29
30#ifdef __cplusplus
31extern "C"
32{
33#if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38#include "gnunet_common.h"
39#include "gnunet_configuration_lib.h"
40#include "gnunet_network_lib.h"
41#include "gnunet_scheduler_lib.h"
42#include "gnunet_time_lib.h"
43
44/**
45 * Opaque handle for a connection to a service.
46 */
47struct GNUNET_CLIENT_Connection;
48
49/**
50 * Get a connection with a service.
51 *
52 * @param sched scheduler to use
53 * @param service_name name of the service
54 * @param cfg configuration to use
55 * @return NULL on error (service unknown to configuration)
56 */
57struct GNUNET_CLIENT_Connection *GNUNET_CLIENT_connect (struct
58 GNUNET_SCHEDULER_Handle
59 *sched,
60 const char
61 *service_name,
62 struct
63 GNUNET_CONFIGURATION_Handle
64 *cfg);
65
66/**
67 * Destroy connection with the service. This will
68 * automatically cancel any pending "receive" request
69 * (however, the handler will *NOT* be called, not
70 * even with a NULL message).
71 */
72void GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock);
73
74/**
75 * Type of a function to call when we receive a message
76 * from the service.
77 *
78 * @param cls closure
79 * @param msg message received, NULL on timeout or fatal error
80 */
81typedef void (*GNUNET_CLIENT_MessageHandler) (void *cls,
82 const struct
83 GNUNET_MessageHeader * msg);
84
85/**
86 * Read from the service.
87 *
88 * @param sched scheduler to use
89 * @param sock the service
90 * @param handler function to call with the message
91 * @param cls closure for handler
92 * @param timeout how long to wait until timing out
93 */
94void GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock,
95 GNUNET_CLIENT_MessageHandler handler,
96 void *cls, struct GNUNET_TIME_Relative timeout);
97
98
99/**
100 * Ask the client to call us once the specified number of bytes
101 * are free in the transmission buffer. May call the notify
102 * method immediately if enough space is available.
103 *
104 * @param client connection to the service
105 * @param size number of bytes to send
106 * @param timeout after how long should we give up (and call
107 * notify with buf NULL and size 0)?
108 * @param notify function to call
109 * @param notify_cls closure for notify
110 * @return NULL if someone else is already waiting to be notified
111 * non-NULL if the notify callback was queued (can be used to cancel
112 * using GNUNET_NETWORK_notify_transmit_ready_cancel)
113 */
114struct GNUNET_NETWORK_TransmitHandle
115 *GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock,
116 size_t size,
117 struct GNUNET_TIME_Relative timeout,
118 GNUNET_NETWORK_TransmitReadyNotify
119 notify, void *notify_cls);
120
121
122/**
123 * Request that the service should shutdown.
124 * Afterwards, the connection should be disconnected.
125 *
126 * @param sched scheduler to use
127 * @param sock the socket connected to the service
128 */
129void GNUNET_CLIENT_service_shutdown (struct GNUNET_CLIENT_Connection *sock);
130
131
132/**
133 * Wait until the service is running.
134 *
135 * @param sched scheduler to use
136 * @param service name of the service to wait for
137 * @param cfg configuration to use
138 * @param timeout how long to wait at most in ms
139 * @param task task to run if service is running
140 * (reason will be "PREREQ_DONE" (service running)
141 * or "TIMEOUT" (service not known to be running))
142 * @param task_cls closure for task
143 */
144void GNUNET_CLIENT_service_test (struct GNUNET_SCHEDULER_Handle *sched,
145 const char *service,
146 struct GNUNET_CONFIGURATION_Handle *cfg,
147 struct GNUNET_TIME_Relative timeout,
148 GNUNET_SCHEDULER_Task task, void *task_cls);
149
150
151#if 0 /* keep Emacsens' auto-indent happy */
152{
153#endif
154#ifdef __cplusplus
155}
156#endif
157
158/* ifndef GNUNET_CLIENT_LIB_H */
159#endif
160/* end of gnunet_client_lib.h */
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h
new file mode 100644
index 000000000..61b572eb8
--- /dev/null
+++ b/src/include/gnunet_common.h
@@ -0,0 +1,469 @@
1/*
2 This file is part of GNUnet.
3 (C) 2006 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 2, 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 include/gnunet_common.h
23 * @brief commonly used definitions; globals in this file
24 * are exempt from the rule that the module name ("common")
25 * must be part of the symbol name.
26 *
27 * @author Christian Grothoff
28 * @author Nils Durner
29 */
30#ifndef GNUNET_COMMON_H
31#define GNUNET_COMMON_H
32
33/**
34 * Version of the API (for entire gnunetutil.so library).
35 */
36#define GNUNET_UTIL_VERSION 0x00000000
37
38/**
39 * Name used for "services" that are actually command-line
40 * programs invoked by the end user.
41 */
42#define GNUNET_CLIENT_SERVICE_NAME "client"
43
44/**
45 * Named constants for return values. The following
46 * invariants hold: "GNUNET_NO == 0" (to allow "if (GNUNET_NO)")
47 * "GNUNET_OK != GNUNET_SYSERR", "GNUNET_OK != GNUNET_NO", "GNUNET_NO != GNUNET_SYSERR"
48 * and finally "GNUNET_YES != GNUNET_NO".
49 */
50#define GNUNET_OK 1
51#define GNUNET_SYSERR -1
52#define GNUNET_YES 1
53#define GNUNET_NO 0
54
55#define GNUNET_MIN(a,b) (((a) < (b)) ? (a) : (b))
56
57#define GNUNET_MAX(a,b) (((a) > (b)) ? (a) : (b))
58
59/**
60 * gcc-ism to get packed structs.
61 */
62#define GNUNET_PACKED __attribute__((packed))
63
64
65/* ************************ super-general types *********************** */
66
67/**
68 * Header for all communications.
69 */
70struct GNUNET_MessageHeader
71{
72
73 /**
74 * The length of the struct (in bytes, including the length field itself)
75 */
76 uint16_t size GNUNET_PACKED;
77
78 /**
79 * The type of the message (XX_CS_PROTO_XXXX)
80 */
81 uint16_t type GNUNET_PACKED;
82
83};
84
85
86/**
87 * @brief 512-bit hashcode
88 */
89typedef struct
90{
91 uint32_t bits[512 / 8 / sizeof (uint32_t)]; /* = 16 */
92}
93GNUNET_HashCode;
94
95
96/**
97 * The identity of the host (basically the SHA-512 hashcode of
98 * it's public key).
99 */
100struct GNUNET_PeerIdentity
101{
102 GNUNET_HashCode hashPubKey GNUNET_PACKED;
103};
104
105
106/**
107 * Function called with a filename.
108 *
109 * @param filename complete filename (absolute path)
110 * @param cls closure
111 * @return GNUNET_OK to continue to iterate,
112 * GNUNET_SYSERR to abort iteration with error!
113 */
114typedef int (*GNUNET_FileNameCallback) (void *cls, const char *filename);
115
116
117/* ****************************** logging ***************************** */
118
119/**
120 * Types of errors.
121 */
122enum GNUNET_ErrorType
123{
124 GNUNET_ERROR_TYPE_ERROR = 1,
125 GNUNET_ERROR_TYPE_WARNING = 2,
126 GNUNET_ERROR_TYPE_INFO = 4,
127 GNUNET_ERROR_TYPE_DEBUG = 8,
128 GNUNET_ERROR_TYPE_INVALID = 16,
129 GNUNET_ERROR_TYPE_BULK = 32
130};
131
132/**
133 * User-defined handler for log messages.
134 *
135 * @param cls closure
136 * @param kind severeity
137 * @param component what component is issuing the message?
138 * @param date when was the message logged?
139 * @param message what is the message
140 */
141typedef void (*GNUNET_Logger) (void *cls,
142 enum GNUNET_ErrorType kind,
143 const char *component,
144 const char *date, const char *message);
145
146/**
147 * Main log function.
148 *
149 * @param kind how serious is the error?
150 * @param message what is the message (format string)
151 * @param ... arguments for format string
152 */
153void GNUNET_log (enum GNUNET_ErrorType kind, const char *message, ...);
154
155
156
157/**
158 * Log function that specifies an alternative component.
159 * This function should be used by plugins.
160 *
161 * @param kind how serious is the error?
162 * @param comp component responsible for generating the message
163 * @param message what is the message (format string)
164 * @param ... arguments for format string
165 */
166void
167GNUNET_log_from (enum GNUNET_ErrorType kind,
168 const char *comp, const char *message, ...);
169
170
171/**
172 * Ignore the next n calls to the log function.
173 *
174 * @param n number of log calls to ignore, use 0 to
175 * assert that the log skip counter is currently zero.
176 */
177void GNUNET_log_skip (unsigned int n);
178
179
180/**
181 * Setup logging.
182 *
183 * @param component default component to use
184 * @param loglevel what types of messages should be logged
185 * @param logfile change logging to logfile (use NULL to keep stderr)
186 * @return GNUNET_OK on success, GNUNET_SYSERR if logfile could not be opened
187 */
188int
189GNUNET_log_setup (const char *component,
190 const char *loglevel, const char *logfile);
191
192/**
193 * Add a custom logger.
194 *
195 * @param logger log function
196 * @param logger_cls closure for logger
197 */
198void GNUNET_logger_add (GNUNET_Logger logger, void *logger_cls);
199
200/**
201 * Remove a custom logger.
202 *
203 * @param logger log function
204 * @param logger_cls closure for logger
205 */
206void GNUNET_logger_remove (GNUNET_Logger logger, void *logger_cls);
207
208
209/**
210 * Convert a peer identity to a string (for printing debug messages).
211 * This is one of the very few calls in the entire API that is
212 * NOT reentrant!
213 *
214 * @param pid the peer identity
215 * @return string form of the pid; will be overwritten by next
216 * call to GNUNET_i2s.
217 */
218const char *GNUNET_i2s (const struct GNUNET_PeerIdentity *pid);
219
220/**
221 * Convert error type to string.
222 *
223 * @param kind type to convert
224 * @return string corresponding to the type
225 */
226const char *GNUNET_error_type_to_string (enum GNUNET_ErrorType kind);
227
228/**
229 * Use this for fatal errors that cannot be handled
230 */
231#define GNUNET_assert(cond) do { if (! (cond)) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Assertion failed at %s:%d.\n"), __FILE__, __LINE__); abort(); } } while(0)
232
233/**
234 * Use this for fatal errors that cannot be handled
235 */
236#define GNUNET_assert_at(cond, f, l) do { if (! (cond)) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Assertion failed at %s:%d.\n"), f, l); abort(); } } while(0)
237
238/**
239 * Use this for internal assertion violations that are
240 * not fatal (can be handled) but should not occur.
241 */
242#define GNUNET_break(cond) do { if (! (cond)) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Assertion failed at %s:%d.\n"), __FILE__, __LINE__); } } while(0)
243
244/**
245 * Use this for assertion violations caused by other
246 * peers (i.e. protocol violations). We do not want to
247 * confuse end-users (say, some other peer runs an
248 * older, broken or incompatible GNUnet version), but
249 * we still want to see these problems during
250 * development and testing. "OP == other peer".
251 */
252#define GNUNET_break_op(cond) do { if (! (cond)) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, _("External protocol violation detected at %s:%d.\n"), __FILE__, __LINE__); } } while(0)
253
254/**
255 * Log an error message at log-level 'level' that indicates
256 * a failure of the command 'cmd' with the message given
257 * by strerror(errno).
258 */
259#define GNUNET_log_strerror(level, cmd) do { GNUNET_log(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, STRERROR(errno)); } while(0)
260
261/**
262 * Log an error message at log-level 'level' that indicates
263 * a failure of the command 'cmd' with the message given
264 * by strerror(errno).
265 */
266#define GNUNET_log_strerror_file(level, cmd, filename) do { GNUNET_log(level, _("`%s' failed on file `%s' at %s:%d with error: %s\n"), cmd, filename,__FILE__, __LINE__, STRERROR(errno)); } while(0)
267
268/* ************************* endianess conversion ****************** */
269
270/**
271 * Convert a long-long to host-byte-order.
272 * @param n the value in network byte order
273 * @return the same value in host byte order
274 */
275unsigned long long GNUNET_ntohll (unsigned long long n);
276
277/**
278 * Convert a long long to network-byte-order.
279 * @param n the value in host byte order
280 * @return the same value in network byte order
281 */
282unsigned long long GNUNET_htonll (unsigned long long n);
283
284
285/* ************************* allocation functions ****************** */
286
287/**
288 * Maximum allocation with GNUNET_malloc macro.
289 */
290#define GNUNET_MAX_GNUNET_MALLOC_CHECKED (1024 * 1024 * 40)
291
292/**
293 * Wrapper around malloc. Allocates size bytes of memory.
294 * The memory will be zero'ed out.
295 *
296 * @param size the number of bytes to allocate, must be
297 * smaller than 40 MB.
298 * @return pointer to size bytes of memory
299 */
300#define GNUNET_malloc(size) GNUNET_xmalloc_(size, __FILE__, __LINE__)
301
302/**
303 * Wrapper around malloc. Allocates size bytes of memory.
304 * The memory will be zero'ed out.
305 *
306 * @param size the number of bytes to allocate
307 * @return pointer to size bytes of memory
308 */
309#define GNUNET_malloc_large(size) GNUNET_xmalloc_unchecked_(size, __FILE__, __LINE__)
310
311/**
312 * Wrapper around realloc. Rellocates size bytes of memory.
313 *
314 * @param ptr the pointer to reallocate
315 * @param size the number of bytes to reallocate
316 * @return pointer to size bytes of memory
317 */
318#define GNUNET_realloc(ptr, size) GNUNET_xrealloc_(ptr, size, __FILE__, __LINE__)
319
320/**
321 * Wrapper around free. Frees the memory referred to by ptr.
322 * Note that is is generally better to free memory that was
323 * allocated with GNUNET_array_grow using GNUNET_array_grow(mem, size, 0) instead of GNUNET_free.
324 *
325 * @param ptr location where to free the memory. ptr must have
326 * been returned by GNUNET_strdup, GNUNET_malloc or GNUNET_array_grow earlier.
327 */
328#define GNUNET_free(ptr) GNUNET_xfree_(ptr, __FILE__, __LINE__)
329
330/**
331 * Free the memory pointed to by ptr if ptr is not NULL.
332 * Equivalent to if (ptr!=null)GNUNET_free(ptr).
333 *
334 * @param ptr the location in memory to free
335 */
336#define GNUNET_free_non_null(ptr) do { void * __x__ = ptr; if (__x__ != NULL) { GNUNET_free(__x__); } } while(0)
337
338/**
339 * Wrapper around GNUNET_strdup. Makes a copy of the zero-terminated string
340 * pointed to by a.
341 *
342 * @param a pointer to a zero-terminated string
343 * @return a copy of the string including zero-termination
344 */
345#define GNUNET_strdup(a) GNUNET_xstrdup_(a,__FILE__,__LINE__)
346
347/**
348 * Grow a well-typed (!) array. This is a convenience
349 * method to grow a vector <tt>arr</tt> of size <tt>size</tt>
350 * to the new (target) size <tt>tsize</tt>.
351 * <p>
352 *
353 * Example (simple, well-typed stack):
354 *
355 * <pre>
356 * static struct foo * myVector = NULL;
357 * static int myVecLen = 0;
358 *
359 * static void push(struct foo * elem) {
360 * GNUNET_array_grow(myVector, myVecLen, myVecLen+1);
361 * memcpy(&myVector[myVecLen-1], elem, sizeof(struct foo));
362 * }
363 *
364 * static void pop(struct foo * elem) {
365 * if (myVecLen == 0) die();
366 * memcpy(elem, myVector[myVecLen-1], sizeof(struct foo));
367 * GNUNET_array_grow(myVector, myVecLen, myVecLen-1);
368 * }
369 * </pre>
370 *
371 * @param arr base-pointer of the vector, may be NULL if size is 0;
372 * will be updated to reflect the new address. The TYPE of
373 * arr is important since size is the number of elements and
374 * not the size in bytes
375 * @param size the number of elements in the existing vector (number
376 * of elements to copy over)
377 * @param tsize the target size for the resulting vector, use 0 to
378 * free the vector (then, arr will be NULL afterwards).
379 */
380#define GNUNET_array_grow(arr,size,tsize) GNUNET_xgrow_((void**)&arr, sizeof(arr[0]), &size, tsize, __FILE__, __LINE__)
381
382/**
383 * Append an element to a list (growing the
384 * list by one).
385 */
386#define GNUNET_array_append(arr,size,element) do { GNUNET_array_grow(arr,size,size+1); arr[size-1] = element; } while(0)
387
388/**
389 * Like snprintf, just aborts if the buffer is of insufficient size.
390 */
391int GNUNET_snprintf (char *buf, size_t size, const char *format, ...);
392
393/**
394 * Like asprintf, just portable.
395 */
396int GNUNET_asprintf (char **buf, const char *format, ...);
397
398
399/* ************** internal implementations, use macros above! ************** */
400
401/**
402 * Allocate memory. Checks the return value, aborts if no more
403 * memory is available. Don't use GNUNET_xmalloc_ directly. Use the
404 * GNUNET_malloc macro.
405 * The memory will be zero'ed out.
406 */
407void *GNUNET_xmalloc_ (size_t size, const char *filename, int linenumber);
408
409/**
410 * Allocate memory. This function does not check if the
411 * allocation request is within reasonable bounds, allowing
412 * allocations larger than 40 MB. If you don't expect the
413 * possibility of very large allocations, use GNUNET_malloc instead.
414 * The memory will be zero'ed out.
415 */
416void *GNUNET_xmalloc_unchecked_ (size_t size,
417 const char *filename, int linenumber);
418
419/**
420 * Reallocate memory. Checks the return value, aborts if no more
421 * memory is available.
422 */
423void *GNUNET_xrealloc_ (void *ptr,
424 const size_t n, const char *filename, int linenumber);
425
426/**
427 * Free memory. Merely a wrapper for the case that we
428 * want to keep track of allocations. Don't use GNUNET_xfree_
429 * directly. Use the GNUNET_free macro.
430 */
431void GNUNET_xfree_ (void *ptr, const char *filename, int linenumber);
432
433
434/**
435 * Dup a string. Don't call GNUNET_xstrdup_ directly. Use the GNUNET_strdup macro.
436 */
437char *GNUNET_xstrdup_ (const char *str, const char *filename, int linenumber);
438
439/**
440 * Grow an array, the new elements are zeroed out.
441 * Grows old by (*oldCount-newCount)*elementSize
442 * bytes and sets *oldCount to newCount.
443 *
444 * Don't call GNUNET_xgrow_ directly. Use the GNUNET_array_grow macro.
445 *
446 * @param old address of the pointer to the array
447 * *old may be NULL
448 * @param elementSize the size of the elements of the array
449 * @param oldCount address of the number of elements in the *old array
450 * @param newCount number of elements in the new array, may be 0 (then *old will be NULL afterwards)
451 */
452void GNUNET_xgrow_ (void **old,
453 size_t elementSize,
454 unsigned int *oldCount,
455 unsigned int newCount,
456 const char *filename, int linenumber);
457
458
459
460
461#if __STDC_VERSION__ < 199901L
462# if __GNUC__ >= 2
463# define __func__ __FUNCTION__
464# else
465# define __func__ "<unknown>"
466# endif
467#endif
468
469#endif /*GNUNET_COMMON_H_ */
diff --git a/src/include/gnunet_configuration_lib.h b/src/include/gnunet_configuration_lib.h
new file mode 100644
index 000000000..fefc6884a
--- /dev/null
+++ b/src/include/gnunet_configuration_lib.h
@@ -0,0 +1,238 @@
1/*
2 This file is part of GNUnet.
3 (C) 2006, 2008, 2009 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 2, 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 include/gnunet_configuration_lib.h
23 * @brief configuration API
24 *
25 * @author Christian Grothoff
26 */
27
28#ifndef GNUNET_CONFIGURATION_LIB_H
29#define GNUNET_CONFIGURATION_LIB_H
30
31
32#ifdef __cplusplus
33extern "C"
34{
35#if 0 /* keep Emacsens' auto-indent happy */
36}
37#endif
38#endif
39
40#include "gnunet_common.h"
41
42/**
43 * A configuration object.
44 */
45struct GNUNET_CONFIGURATION_Handle;
46
47/**
48 * Create a new configuration object.
49 *
50 * @param component name of responsible component
51 */
52struct GNUNET_CONFIGURATION_Handle *GNUNET_CONFIGURATION_create (void);
53
54/**
55 * Destroy configuration object.
56 */
57void GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg);
58
59/**
60 * Load configuration. This function will first parse the
61 * defaults and then parse the specific configuration file
62 * to overwrite the defaults.
63 *
64 * @param filename name of the configuration file
65 * @return GNUNET_OK on success, GNUNET_SYSERR on error
66 */
67int GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg,
68 const char *filename);
69
70/**
71 * Parse a configuration file, add all of the options in the
72 * file to the configuration environment.
73 * @return GNUNET_OK on success, GNUNET_SYSERR on error
74 */
75int GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg,
76 const char *filename);
77
78/**
79 * Write configuration file.
80 * @return GNUNET_OK on success, GNUNET_SYSERR on error
81 */
82int GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg,
83 const char *filename);
84
85/**
86 * Test if there are configuration options that were
87 * changed since the last save.
88 * @return GNUNET_NO if clean, GNUNET_YES if dirty, GNUNET_SYSERR on error (i.e. last save failed)
89 */
90int GNUNET_CONFIGURATION_is_dirty (struct GNUNET_CONFIGURATION_Handle *cfg);
91
92/**
93 * Get a configuration value that should be a number.
94 * @return GNUNET_OK on success, GNUNET_SYSERR on error
95 */
96int GNUNET_CONFIGURATION_get_value_number (struct GNUNET_CONFIGURATION_Handle
97 *cfg, const char *section,
98 const char *option,
99 unsigned long long *number);
100
101/**
102 * Test if we have a value for a particular option
103 * @return GNUNET_YES if so, GNUNET_NO if not.
104 */
105int GNUNET_CONFIGURATION_have_value (struct GNUNET_CONFIGURATION_Handle *cfg,
106 const char *section, const char *option);
107
108/**
109 * Get a configuration value that should be a string.
110 * @param value will be set to a freshly allocated configuration
111 * value, or NULL if option is not specified
112 * @return GNUNET_OK on success, GNUNET_SYSERR on error
113 */
114int GNUNET_CONFIGURATION_get_value_string (struct GNUNET_CONFIGURATION_Handle
115 *cfg, const char *section,
116 const char *option, char **value);
117
118/**
119 * Get a configuration value that should be the name of a file
120 * or directory.
121 *
122 * @param value will be set to a freshly allocated configuration
123 * value, or NULL if option is not specified
124 * @return GNUNET_OK on success, GNUNET_SYSERR on error
125 */
126int GNUNET_CONFIGURATION_get_value_filename (struct
127 GNUNET_CONFIGURATION_Handle *cfg,
128 const char *section,
129 const char *option,
130 char **value);
131
132/**
133 * Iterate over the set of filenames stored in a configuration value.
134 *
135 * @return number of filenames iterated over, -1 on error
136 */
137int GNUNET_CONFIGURATION_iterate_value_filenames (struct
138 GNUNET_CONFIGURATION_Handle
139 *cfg,
140 const char *section,
141 const char *option,
142 GNUNET_FileNameCallback
143 cb, void *cls);
144
145/**
146 * Get a configuration value that should be in a set of
147 * predefined strings
148 *
149 * @param choices NULL-terminated list of legal values
150 * @param value will be set to an entry in the legal list,
151 * or NULL if option is not specified and no default given
152 * @return GNUNET_OK on success, GNUNET_SYSERR on error
153 */
154int GNUNET_CONFIGURATION_get_value_choice (struct GNUNET_CONFIGURATION_Handle
155 *cfg, const char *section,
156 const char *option,
157 const char **choices,
158 const char **value);
159
160/**
161 * Get a configuration value that should be in a set of
162 * "YES" or "NO".
163 *
164 * @return GNUNET_YES, GNUNET_NO or if option has no valid value, GNUNET_SYSERR
165 */
166int GNUNET_CONFIGURATION_get_value_yesno (struct GNUNET_CONFIGURATION_Handle
167 *cfg, const char *section,
168 const char *option);
169
170/**
171 * Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR"
172 * where either in the "PATHS" section or the environtment
173 * "FOO" is set to "DIRECTORY".
174
175 * @param old string to $-expand (will be freed!)
176 * @return $-expanded string
177 */
178char *GNUNET_CONFIGURATION_expand_dollar (struct GNUNET_CONFIGURATION_Handle
179 *cfg, char *old);
180
181/**
182 * Set a configuration value that should be a number.
183 */
184void
185GNUNET_CONFIGURATION_set_value_number (struct GNUNET_CONFIGURATION_Handle
186 *cfg,
187 const char *section,
188 const char *option,
189 unsigned long long number);
190
191
192/**
193 * Set a configuration value that should be a string.
194 * @param value
195 */
196void
197GNUNET_CONFIGURATION_set_value_string (struct GNUNET_CONFIGURATION_Handle
198 *cfg,
199 const char *section,
200 const char *option, const char *value);
201
202/**
203 * Remove a filename from a configuration value that
204 * represents a list of filenames
205 *
206 * @param value filename to remove
207 * @return GNUNET_OK on success,
208 * GNUNET_SYSERR if the filename is not in the list
209 */
210int GNUNET_CONFIGURATION_remove_value_filename (struct
211 GNUNET_CONFIGURATION_Handle
212 *cfg,
213 const char *section,
214 const char *option,
215 const char *value);
216
217/**
218 * Append a filename to a configuration value that
219 * represents a list of filenames
220 *
221 * @param value filename to append
222 * @return GNUNET_OK on success,
223 * GNUNET_SYSERR if the filename already in the list
224 */
225int GNUNET_CONFIGURATION_append_value_filename (struct
226 GNUNET_CONFIGURATION_Handle
227 *cfg, const char *section,
228 const char *option,
229 const char *value);
230
231#if 0 /* keep Emacsens' auto-indent happy */
232{
233#endif
234#ifdef __cplusplus
235}
236#endif
237
238#endif
diff --git a/src/include/gnunet_container_lib.h b/src/include/gnunet_container_lib.h
new file mode 100644
index 000000000..255f68a89
--- /dev/null
+++ b/src/include/gnunet_container_lib.h
@@ -0,0 +1,784 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008 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 2, 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 include/gnunet_container_lib.h
23 * @brief container classes for GNUnet
24 *
25 * @author Christian Grothoff
26 * @author Nils Durner
27 */
28
29#ifndef GNUNET_CONTAINER_LIB_H
30#define GNUNET_CONTAINER_LIB_H
31
32/* add error and config prototypes */
33#include "gnunet_crypto_lib.h"
34#include <extractor.h>
35
36#ifdef __cplusplus
37extern "C"
38{
39#if 0 /* keep Emacsens' auto-indent happy */
40}
41#endif
42#endif
43
44
45/* ******************* bloomfilter ***************** */
46
47/**
48 * @brief bloomfilter representation (opaque)
49 */
50struct GNUNET_CONTAINER_BloomFilter;
51
52/**
53 * Iterator over HashCodes.
54 *
55 * @return GNUNET_YES if next was updated
56 * GNUNET_NO if there are no more entries
57 */
58typedef int (*GNUNET_HashCodeIterator) (GNUNET_HashCode * next, void *arg);
59
60/**
61 * Load a bloom-filter from a file.
62 * @param filename the name of the file (or the prefix)
63 * @param size the size of the bloom-filter (number of
64 * bytes of storage space to use)
65 * @param k the number of GNUNET_CRYPTO_hash-functions to apply per
66 * element (number of bits set per element in the set)
67 * @return the bloomfilter
68 */
69struct GNUNET_CONTAINER_BloomFilter *GNUNET_CONTAINER_bloomfilter_load (const
70 char
71 *filename,
72 unsigned
73 int
74 size,
75 unsigned
76 int
77 k);
78
79/**
80 * Create a bloom filter from raw bits.
81 *
82 * @param data the raw bits in memory (maybe NULL,
83 * in which case all bits should be considered
84 * to be zero).
85 * @param size the size of the bloom-filter (number of
86 * bytes of storage space to use); also size of data
87 * -- unless data is NULL. Must be a power of 2.
88 * @param k the number of GNUNET_CRYPTO_hash-functions to apply per
89 * element (number of bits set per element in the set)
90 * @return the bloomfilter
91 */
92struct GNUNET_CONTAINER_BloomFilter *GNUNET_CONTAINER_bloomfilter_init (const
93 char
94 *data,
95 unsigned
96 int
97 size,
98 unsigned
99 int
100 k);
101
102/**
103 * Copy the raw data of this bloomfilter into
104 * the given data array.
105 *
106 * @param data where to write the data
107 * @param size the size of the given data array
108 * @return GNUNET_SYSERR if the data array of the wrong size
109 */
110int GNUNET_CONTAINER_bloomfilter_get_raw_data (struct
111 GNUNET_CONTAINER_BloomFilter
112 *bf, char *data,
113 unsigned int size);
114
115/**
116 * Test if an element is in the filter.
117 * @param e the element
118 * @param bf the filter
119 * @return GNUNET_YES if the element is in the filter, GNUNET_NO if not
120 */
121int GNUNET_CONTAINER_bloomfilter_test (struct GNUNET_CONTAINER_BloomFilter
122 *bf, const GNUNET_HashCode * e);
123
124/**
125 * Add an element to the filter
126 * @param bf the filter
127 * @param e the element
128 */
129void GNUNET_CONTAINER_bloomfilter_add (struct GNUNET_CONTAINER_BloomFilter
130 *bf, const GNUNET_HashCode * e);
131
132/**
133 * Remove an element from the filter.
134 * @param bf the filter
135 * @param e the element to remove
136 */
137void GNUNET_CONTAINER_bloomfilter_remove (struct GNUNET_CONTAINER_BloomFilter
138 *bf, const GNUNET_HashCode * e);
139
140/**
141 * Free the space associcated with a filter
142 * in memory, flush to drive if needed (do not
143 * free the space on the drive)
144 * @param bf the filter
145 */
146void GNUNET_CONTAINER_bloomfilter_free (struct GNUNET_CONTAINER_BloomFilter
147 *bf);
148
149/**
150 * Reset a bloom filter to empty.
151 * @param bf the filter
152 */
153void GNUNET_CONTAINER_bloomfilter_clear (struct GNUNET_CONTAINER_BloomFilter
154 *bf);
155
156/**
157 * Or the entries of the given raw data array with the
158 * data of the given bloom filter. Assumes that
159 * the size of the data array and the current filter
160 * match.
161 * @param bf the filter
162 */
163int GNUNET_CONTAINER_bloomfilter_or (struct GNUNET_CONTAINER_BloomFilter *bf,
164 const char *data, unsigned int size);
165
166/**
167 * Resize a bloom filter. Note that this operation
168 * is pretty costly. Essentially, the bloom filter
169 * needs to be completely re-build.
170 *
171 * @param bf the filter
172 * @param iterator an iterator over all elements stored in the BF
173 * @param iterator_arg argument to the iterator function
174 * @param size the new size for the filter
175 * @param k the new number of GNUNET_CRYPTO_hash-function to apply per element
176 */
177void GNUNET_CONTAINER_bloomfilter_resize (struct GNUNET_CONTAINER_BloomFilter
178 *bf,
179 GNUNET_HashCodeIterator iterator,
180 void *iterator_arg,
181 unsigned int size, unsigned int k);
182
183/* ****************** metadata ******************* */
184
185/**
186 * Meta data to associate with a file, directory or namespace.
187 */
188struct GNUNET_CONTAINER_MetaData;
189
190/**
191 * Iterator over meta data.
192 * @return GNUNET_OK to continue to iterate, GNUNET_SYSERR to abort
193 */
194typedef int (*GNUNET_CONTAINER_MetaDataProcessor) (EXTRACTOR_KeywordType type,
195 const char *data,
196 void *closure);
197
198/**
199 * Create a fresh MetaData token.
200 */
201struct GNUNET_CONTAINER_MetaData *GNUNET_CONTAINER_meta_data_create (void);
202
203/**
204 * Duplicate a MetaData token.
205 */
206struct GNUNET_CONTAINER_MetaData *GNUNET_CONTAINER_meta_data_duplicate (const
207 struct
208 GNUNET_CONTAINER_MetaData
209 *meta);
210
211/**
212 * Free meta data.
213 */
214void GNUNET_CONTAINER_meta_data_destroy (struct GNUNET_CONTAINER_MetaData
215 *md);
216
217/**
218 * Test if two MDs are equal.
219 */
220int GNUNET_CONTAINER_meta_data_test_equal (const struct
221 GNUNET_CONTAINER_MetaData *md1,
222 const struct
223 GNUNET_CONTAINER_MetaData *md2);
224
225
226/**
227 * Extend metadata.
228 * @return GNUNET_OK on success, GNUNET_SYSERR if this entry already exists
229 */
230int GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md,
231 EXTRACTOR_KeywordType type,
232 const char *data);
233
234/**
235 * Remove an item.
236 * @return GNUNET_OK on success, GNUNET_SYSERR if the item does not exist in md
237 */
238int GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md,
239 EXTRACTOR_KeywordType type,
240 const char *data);
241
242/**
243 * Add the current time as the publication date
244 * to the meta-data.
245 */
246void GNUNET_CONTAINER_meta_data_add_publication_date (struct
247 GNUNET_CONTAINER_MetaData
248 *md);
249
250/**
251 * Iterate over MD entries, excluding thumbnails.
252 *
253 * @return number of entries
254 */
255int GNUNET_CONTAINER_meta_data_get_contents (const struct
256 GNUNET_CONTAINER_MetaData *md,
257 GNUNET_CONTAINER_MetaDataProcessor
258 iterator, void *closure);
259
260/**
261 * Get the first MD entry of the given type.
262 * @return NULL if we do not have any such entry,
263 * otherwise client is responsible for freeing the value!
264 */
265char *GNUNET_CONTAINER_meta_data_get_by_type (const struct
266 GNUNET_CONTAINER_MetaData *md,
267 EXTRACTOR_KeywordType type);
268
269/**
270 * Get the first matching MD entry of the given types.
271 * @paarm ... -1-terminated list of types
272 * @return NULL if we do not have any such entry,
273 * otherwise client is responsible for freeing the value!
274 */
275char *GNUNET_CONTAINER_meta_data_get_first_by_types (const struct
276 GNUNET_CONTAINER_MetaData
277 *md, ...);
278
279/**
280 * Get a thumbnail from the meta-data (if present).
281 *
282 * @param thumb will be set to the thumbnail data. Must be
283 * freed by the caller!
284 * @return number of bytes in thumbnail, 0 if not available
285 */
286size_t GNUNET_CONTAINER_meta_data_get_thumbnail (const struct
287 GNUNET_CONTAINER_MetaData
288 *md, unsigned char **thumb);
289
290/**
291 * Extract meta-data from a file.
292 *
293 * @return GNUNET_SYSERR on error, otherwise the number
294 * of meta-data items obtained
295 */
296int GNUNET_CONTAINER_meta_data_extract_from_file (struct
297 GNUNET_CONTAINER_MetaData
298 *md, const char *filename,
299 EXTRACTOR_ExtractorList *
300 extractors);
301
302enum GNUNET_CONTAINER_MetaDataSerializationOptions
303{
304 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL = GNUNET_NO,
305 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART = GNUNET_YES,
306 GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS = 2
307};
308
309
310
311/**
312 * Serialize meta-data to target.
313 *
314 * @param size maximum number of bytes available
315 * @param opt is it ok to just write SOME of the
316 * meta-data to match the size constraint,
317 * possibly discarding some data?
318 * @return number of bytes written on success,
319 * GNUNET_SYSERR on error (typically: not enough
320 * space)
321 */
322int GNUNET_CONTAINER_meta_data_serialize (const struct
323 GNUNET_CONTAINER_MetaData *md,
324 char *target, unsigned int size,
325 enum
326 GNUNET_CONTAINER_MetaDataSerializationOptions
327 opt);
328
329/**
330 * Compute size of the meta-data in
331 * serialized form.
332 * @param opt is it ok to just write SOME of the
333 * meta-data to match the size constraint,
334 * possibly discarding some data?
335 */
336unsigned int GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
337 GNUNET_CONTAINER_MetaData
338 *md,
339 enum
340 GNUNET_CONTAINER_MetaDataSerializationOptions
341 opt);
342
343/**
344 * Deserialize meta-data. Initializes md.
345 * @param size number of bytes available
346 * @return MD on success, NULL on error (i.e.
347 * bad format)
348 */
349struct GNUNET_CONTAINER_MetaData
350 *GNUNET_CONTAINER_meta_data_deserialize (const char *input,
351 unsigned int size);
352
353/**
354 * Does the meta-data claim that this is a directory?
355 * Checks if the mime-type is that of a GNUnet directory.
356 *
357 * @return GNUNET_YES if it is, GNUNET_NO if it is not, GNUNET_SYSERR if
358 * we have no mime-type information (treat as 'GNUNET_NO')
359 */
360int GNUNET_CONTAINER_meta_data_test_for_directory (const struct
361 GNUNET_CONTAINER_MetaData
362 *md);
363
364
365/* ******************************* HashMap **************************** */
366
367/**
368 * Opaque handle for a HashMap.
369 */
370struct GNUNET_CONTAINER_MultiHashMap;
371
372/**
373 * Options for storing values in the HashMap.
374 */
375enum GNUNET_CONTAINER_MultiHashMapOption
376{
377 /**
378 * If a value with the given key exists, replace it.
379 * Note that the old value would NOT be freed
380 * by replace (the application has to make sure that
381 * this happens if required).
382 */
383 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE,
384
385 /**
386 * Allow multiple values with the same key.
387 */
388 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE,
389
390 /**
391 * There must only be one value per key; storing
392 * a value should fail if a value under the same
393 * key already exists.
394 */
395 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY,
396
397 /**
398 * There must only be one value per key, but don't
399 * bother checking if a value already exists
400 * (faster than UNIQUE_ONLY; implemented just like
401 * MULTIPLE but this option documents better what
402 * is intended if UNIQUE is what is desired).
403 */
404 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
405};
406
407/**
408 * Iterator over HashCodes.
409 *
410 * @param key current key code
411 * @param value value in the hash map
412 * @param cls client-defined argument
413 * @return GNUNET_YES if we should continue to
414 * iterate,
415 * GNUNET_NO if not.
416 */
417typedef int (*GNUNET_CONTAINER_HashMapIterator) (const GNUNET_HashCode * key,
418 void *value, void *cls);
419
420
421/**
422 * Create a multi hash map.
423 *
424 * @param map the map
425 * @param len initial size (map will grow as needed)
426 * @return NULL on error
427 */
428struct GNUNET_CONTAINER_MultiHashMap
429 *GNUNET_CONTAINER_multihashmap_create (unsigned int len);
430
431/**
432 * Destroy a hash map. Will not free any values
433 * stored in the hash map!
434 *
435 * @param map the map
436 */
437void GNUNET_CONTAINER_multihashmap_destroy (struct
438 GNUNET_CONTAINER_MultiHashMap
439 *map);
440
441/**
442 * Given a key find a value in the
443 * map matching the key.
444 *
445 * @param map the map
446 * @param key what to look for
447 * @return NULL if no value was found; note that
448 * this is indistinguishable from values that just
449 * happen to be NULL; use "contains" to test for
450 * key-value pairs with value NULL
451 */
452void *GNUNET_CONTAINER_multihashmap_get (const struct
453 GNUNET_CONTAINER_MultiHashMap *map,
454 const GNUNET_HashCode * key);
455
456/**
457 * Remove the given key-value pair from the map.
458 * Note that if the key-value pair is in the map
459 * multiple times, only one of the pairs will be
460 * removed.
461 *
462 * @param map the map
463 * @param key key of the key-value pair
464 * @param value value of the key-value pair
465 * @return GNUNET_YES on success, GNUNET_NO if the key-value pair
466 * is not in the map
467 */
468int GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap
469 *map, const GNUNET_HashCode * key,
470 void *value);
471
472/**
473 * Remove all entries for the given key from the map.
474 * Note that the values would not be "freed".
475 *
476 * @param map the map
477 * @param key identifies values to be removed
478 * @return number of values removed
479 */
480int GNUNET_CONTAINER_multihashmap_remove_all (struct
481 GNUNET_CONTAINER_MultiHashMap
482 *map,
483 const GNUNET_HashCode * key);
484
485/**
486 * Check if the map contains any value under the given
487 * key (including values that are NULL).
488 *
489 * @param map the map
490 * @param key the key to test if a value exists for it
491 * @return GNUNET_YES if such a value exists,
492 * GNUNET_NO if not
493 */
494int GNUNET_CONTAINER_multihashmap_contains (const struct
495 GNUNET_CONTAINER_MultiHashMap
496 *map,
497 const GNUNET_HashCode * key);
498
499/**
500 * Store a key-value pair in the map.
501 *
502 * @param map the map
503 * @param key key to use
504 * @param value value to use
505 * @param opt options for put
506 * @return GNUNET_OK on success,
507 * GNUNET_NO if a value was replaced (with REPLACE)
508 * GNUNET_SYSERR if UNIQUE_ONLY was the option and the
509 * value already exists
510 */
511int GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap
512 *map, const GNUNET_HashCode * key,
513 void *value,
514 enum
515 GNUNET_CONTAINER_MultiHashMapOption
516 opt);
517
518/**
519 * Get the number of key-value pairs in the map.
520 *
521 * @param map the map
522 * @return the number of key value pairs
523 */
524unsigned int GNUNET_CONTAINER_multihashmap_size (const struct
525 GNUNET_CONTAINER_MultiHashMap
526 *map);
527
528
529/**
530 * Iterate over all entries in the map.
531 *
532 * @param map the map
533 * @param iterator function to call on each entry
534 * @param cls extra argument to it
535 * @return the number of key value pairs processed,
536 * GNUNET_SYSERR if it aborted iteration
537 */
538int GNUNET_CONTAINER_multihashmap_iterate (const struct
539 GNUNET_CONTAINER_MultiHashMap *map,
540 GNUNET_CONTAINER_HashMapIterator
541 iterator, void *cls);
542
543/**
544 * Iterate over all entries in the map
545 * that match a particular key.
546 *
547 * @param map the map
548 * @param key key that the entries must correspond to
549 * @param iterator function to call on each entry
550 * @param cls extra argument to it
551 * @return the number of key value pairs processed,
552 * GNUNET_SYSERR if it aborted iteration
553 */
554int GNUNET_CONTAINER_multihashmap_get_multiple (const struct
555 GNUNET_CONTAINER_MultiHashMap
556 *map,
557 const GNUNET_HashCode * key,
558 GNUNET_CONTAINER_HashMapIterator
559 iterator, void *cls);
560/**
561 * Returns the stored value of a random non-null entry
562 * in the hash table. Returns only the first value, does
563 * not go inside bucket linked list (yet). Runs with a
564 * worst case time of N, so it's not efficient in any way
565 * shape or form!!!!.
566 */
567void *GNUNET_CONTAINER_multihashmap_get_random (const struct
568 GNUNET_CONTAINER_MultiHashMap
569 *map);
570
571
572
573
574/* ******************** doubly-linked list *************** */
575
576/**
577 * Insert an element into a DLL. Assumes
578 * that head, tail and element are structs
579 * with prev and next fields.
580 */
581#define GNUNET_CONTAINER_DLL_insert(head,tail,element) \
582 (element)->next = (head); \
583 (element)->prev = NULL; \
584 if ((tail) == NULL) \
585 (tail) = element; \
586 else \
587 (head)->prev = element; \
588 (head) = (element);
589
590/**
591 * Insert an element into a DLL after the given other
592 * element. Insert at the head if the other
593 * element is NULL.
594 */
595#define GNUNET_CONTAINER_DLL_insert_after(head,tail,other,element) \
596 (element)->prev = (other); \
597 if (NULL == other) \
598 { \
599 (element)->next = (head); \
600 (head) = (element); \
601 } \
602 else \
603 { \
604 (element)->next = (other)->next; \
605 (other)->next = (element); \
606 } \
607 if (NULL == (element)->next) \
608 (tail) = (element); \
609 else \
610 (element)->next->prev = (element);
611
612
613
614
615/**
616 * Remove an element from a DLL. Assumes
617 * that head, tail and element are structs
618 * with prev and next fields.
619 */
620#define GNUNET_CONTAINER_DLL_remove(head,tail,element) \
621 if ((element)->prev == NULL) \
622 (head) = (element)->next; \
623 else \
624 (element)->prev->next = (element)->next; \
625 if ((element)->next == NULL) \
626 (tail) = (element)->prev; \
627 else \
628 (element)->next->prev = (element)->prev;
629
630
631
632/* ******************** Heap *************** */
633
634
635/**
636 * Cost by which elements in a heap can be ordered.
637 */
638typedef unsigned int GNUNET_CONTAINER_HeapCost;
639
640/*
641 * Heap type, either max or min. Hopefully makes the
642 * implementation more useful.
643 */
644enum GNUNET_CONTAINER_HeapOrder
645{
646 /**
647 * Heap with the maximum cost at the root.
648 */
649 GNUNET_CONTAINER_HEAP_ORDER_MAX,
650
651 /**
652 * Heap with the minimum cost at the root.
653 */
654 GNUNET_CONTAINER_HEAP_ORDER_MIN
655};
656
657/**
658 * Handle to a Heap.
659 */
660struct GNUNET_CONTAINER_Heap;
661
662/**
663 * Create a new heap.
664 *
665 * @param type should the minimum or the maximum element be the root
666 * @return NULL on error, otherwise a fresh heap
667 */
668struct GNUNET_CONTAINER_Heap *GNUNET_CONTAINER_heap_create (enum
669 GNUNET_CONTAINER_HeapOrder
670 type);
671
672/**
673 * Free a heap
674 *
675 * @param h heap to free.
676 */
677void GNUNET_CONTAINER_heap_destroy (struct GNUNET_CONTAINER_Heap *h);
678
679/**
680 * Function called on elements of a heap.
681 *
682 * @param cls closure
683 * @param element obj stored in heap
684 * @param cost cost of the element
685 * @return GNUNET_YES if we should continue to iterate,
686 * GNUNET_NO if not.
687 */
688typedef int (*GNUNET_CONTAINER_HeapIterator) (void *cls,
689 void *element,
690 GNUNET_CONTAINER_HeapCost cost);
691/**
692 * Iterate over all entries in the map.
693 *
694 * @param heap the heap
695 * @param iterator function to call on each entry
696 * @param iterator_cls closure for iterator
697 * @return number of items handled
698 * GNUNET_SYSERR if iteration was aborted by iterator
699 */
700int GNUNET_CONTAINER_heap_iterate (struct GNUNET_CONTAINER_Heap *heap,
701 GNUNET_CONTAINER_HeapIterator iterator,
702 void *iterator_cls);
703
704
705/**
706 * Inserts a new item into the heap, item is always neighbor now.
707 * @param heap the heap
708 */
709int
710GNUNET_CONTAINER_heap_insert (struct GNUNET_CONTAINER_Heap *heap,
711 void *element, GNUNET_CONTAINER_HeapCost cost);
712
713/**
714 * Removes root of the tree, is remove max if a max heap and remove min
715 * if a min heap, returns the data stored at the node.
716 *
717 * @param heap the heap
718 * @return NULL if the heap is empty
719 */
720void *GNUNET_CONTAINER_heap_remove_root (struct GNUNET_CONTAINER_Heap *heap);
721
722/**
723 * Returns element stored at root of tree, doesn't effect anything
724 *
725 * @param heap the heap
726 * @return NULL if the heap is empty
727 */
728void *GNUNET_CONTAINER_heap_peek (struct GNUNET_CONTAINER_Heap *heap);
729
730/**
731 * Removes any node from the tree based on the neighbor given, does
732 * not traverse the tree (backpointers) but may take more time due to
733 * percolation of nodes.
734 * @param heap the heap
735 */
736void *GNUNET_CONTAINER_heap_remove_node (struct GNUNET_CONTAINER_Heap *heap,
737 void *element);
738
739/**
740 * Updates the cost of any node in the tree
741 *
742 * @param heap the heap
743 * @param element the element for which the cost is updated
744 * @param new_cost new cost for the element
745 * @return WHAT?
746 */
747int
748GNUNET_CONTAINER_heap_update_cost (struct GNUNET_CONTAINER_Heap *heap,
749 void *element,
750 GNUNET_CONTAINER_HeapCost new_cost);
751
752/**
753 * Random walk of the tree, returns the data stored at the next random node
754 * in the walk. Calls callee with the data, or NULL if the tree is empty
755 * or some other problem crops up.
756 *
757 * @param heap the heap
758 * @return the next element from the random walk
759 */
760void *GNUNET_CONTAINER_heap_walk_get_next (struct GNUNET_CONTAINER_Heap
761 *heap);
762
763/**
764 * Returns the current size of the heap
765 *
766 * @param heap the heap to get the size of
767 * @return number of elements in the heap
768 */
769unsigned int
770GNUNET_CONTAINER_heap_get_size (struct GNUNET_CONTAINER_Heap *heap);
771
772
773
774#if 0 /* keep Emacsens' auto-indent happy */
775{
776#endif
777#ifdef __cplusplus
778}
779#endif
780
781
782/* ifndef GNUNET_CONTAINER_LIB_H */
783#endif
784/* end of gnunet_container_lib.h */
diff --git a/src/include/gnunet_core_service.h b/src/include/gnunet_core_service.h
new file mode 100644
index 000000000..8b75271b9
--- /dev/null
+++ b/src/include/gnunet_core_service.h
@@ -0,0 +1,323 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 include/gnunet_core_service.h
23 * @brief core service; this is the main API for encrypted P2P
24 * communications
25 * @author Christian Grothoff
26 */
27
28#ifndef GNUNET_CORE_SERVICE_H
29#define GNUNET_CORE_SERVICE_H
30
31#ifdef __cplusplus
32extern "C"
33{
34#if 0 /* keep Emacsens' auto-indent happy */
35}
36#endif
37#endif
38
39#include "gnunet_util_lib.h"
40
41/**
42 * Version number of GNUnet-core API.
43 */
44#define GNUNET_CORE_VERSION 0x00000000
45
46
47/**
48 * Opaque handle to the service.
49 */
50struct GNUNET_CORE_Handle;
51
52
53/**
54 * Method called whenever a given peer either connects or
55 * disconnects (or list of connections was requested).
56 *
57 * @param cls closure
58 * @param peer peer identity this notification is about
59 * @param bpm how much bandwidth is available
60 * (for sending) to this peer
61 * @param last_activity when did we last
62 * receive anything from this peer?
63 */
64typedef void (*GNUNET_CORE_ClientEventHandler) (void *cls,
65 const struct
66 GNUNET_PeerIdentity * peer,
67 unsigned int bpm,
68 struct GNUNET_TIME_Absolute
69 last_activity);
70
71
72/**
73 * Type of a send callback to fill up buffers.
74 *
75 * @param receiver the receiver of the message
76 * @param position is the reference to the
77 * first unused position in the buffer where GNUnet is building
78 * the message
79 * @param padding is the number of bytes left in that buffer.
80 * @return the number of bytes written to
81 * that buffer (must be a positive number).
82 */
83typedef unsigned int
84 (*GNUNET_CORE_BufferFillCallback) (void *cls,
85 const struct GNUNET_PeerIdentity *
86 receiver,
87 void *position, unsigned int padding);
88
89
90/**
91 * Functions with this signature are called whenever a message is
92 * received or transmitted.
93 *
94 * @param cls closure
95 * @param peer the other peer involved (sender or receiver, NULL
96 * for loopback messages where we are both sender and receiver)
97 * @param message the actual message
98 * @return GNUNET_OK to keep the connection open,
99 * GNUNET_SYSERR to close it (signal serious error)
100 */
101typedef int
102 (*GNUNET_CORE_MessageCallback) (void *cls,
103 const struct GNUNET_PeerIdentity * other,
104 const struct GNUNET_MessageHeader *
105 message);
106
107
108/**
109 * Message handler. Each struct specifies how to handle on particular
110 * type of message received.
111 */
112struct GNUNET_CORE_MessageHandler
113{
114 /**
115 * Function to call for messages of "type".
116 */
117 GNUNET_CORE_MessageCallback callback;
118
119 /**
120 * Type of the message this handler covers.
121 */
122 uint16_t type;
123
124 /**
125 * Expected size of messages of this type. Use 0 for variable-size.
126 * If non-zero, messages of the given type will be discarded if they
127 * do not have the right size.
128 */
129 uint16_t expected_size;
130
131};
132
133
134/**
135 * Function called after GNUNET_CORE_connect has succeeded
136 * (or failed for good). Note that the private key of the
137 * peer is intentionally not exposed here; if you need it,
138 * your process should try to read the private key file
139 * directly (which should work if you are authorized...).
140 *
141 * @param cls closure
142 * @param server handle to the server, NULL if we failed
143 * @param my_identity ID of this peer, NULL if we failed
144 * @param publicKey public key of this peer, NULL if we failed
145 */
146typedef void
147 (*GNUNET_CORE_StartupCallback) (void *cls,
148 struct GNUNET_CORE_Handle * server,
149 const struct GNUNET_PeerIdentity *
150 my_identity,
151 const struct
152 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *
153 publicKey);
154
155
156/**
157 * Connect to the core service. Note that the connection may
158 * complete (or fail) asynchronously.
159 *
160 * @param sched scheduler to use
161 * @param cfg configuration to use
162 * @param timeout after how long should we give up trying to connect to the core service?
163 * @param cls closure for the various callbacks that follow (including handlers in the handlers array)
164 * @param init callback to call on timeout or once we have successfully
165 * connected to the core service
166 * @param connects function to call on peer connect, can be NULL
167 * @param disconnects function to call on peer disconnect / timeout, can be NULL
168 * @param bfc function to call to fill up spare bandwidth, can be NULL
169 * @param inbound_notify function to call for all inbound messages, can be NULL
170 * @param inbound_hdr_only set to GNUNET_YES if inbound_notify will only read the
171 * GNUNET_MessageHeader and hence we do not need to give it the full message;
172 * can be used to improve efficiency, ignored if inbound_notify is NULLL
173 * @param outbound_notify function to call for all outbound messages, can be NULL
174 * @param outbound_hdr_only set to GNUNET_YES if outbound_notify will only read the
175 * GNUNET_MessageHeader and hence we do not need to give it the full message
176 * can be used to improve efficiency, ignored if outbound_notify is NULLL
177 * @param handlers callbacks for messages we care about, NULL-terminated
178 */
179void
180GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched,
181 struct GNUNET_CONFIGURATION_Handle *cfg,
182 struct GNUNET_TIME_Relative timeout,
183 void *cls,
184 GNUNET_CORE_StartupCallback init,
185 GNUNET_CORE_ClientEventHandler connects,
186 GNUNET_CORE_ClientEventHandler disconnects,
187 GNUNET_CORE_BufferFillCallback bfc,
188 GNUNET_CORE_MessageCallback inbound_notify,
189 int inbound_hdr_only,
190 GNUNET_CORE_MessageCallback outbound_notify,
191 int outbound_hdr_only,
192 const struct GNUNET_CORE_MessageHandler *handlers);
193
194
195/**
196 * Disconnect from the core service.
197 *
198 * @param handle connection to core to disconnect
199 */
200void GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle);
201
202
203/**
204 * Function called with statistics about the given peer.
205 *
206 * @param peer identifies the peer
207 * @param latency current latency estimate, "FOREVER" if we have been
208 * disconnected
209 * @param bpm_in set to the current bandwidth limit (receiving) for this peer
210 * @param bpm_out set to the current bandwidth limit (sending) for this peer
211 * @param amount set to the amount that was actually reserved or unreserved
212 * @param preference current traffic preference for the given peer
213 */
214typedef void
215 (*GNUNET_CORE_PeerConfigurationInfoCallback) (void *cls,
216 const struct
217 GNUNET_PeerIdentity * peer,
218 unsigned int bpm_in,
219 unsigned int bpm_out,
220 struct GNUNET_TIME_Relative
221 latency, int amount,
222 double preference);
223
224
225/**
226 * Obtain statistics and/or change preferences for the given peer.
227 *
228 * @param handle connection to core to use
229 * @param peer identifies the peer
230 * @param timeout after how long should we give up (and call "info" with NULL
231 * for "peer" to signal an error)?
232 * @param bpm_out set to the current bandwidth limit (sending) for this peer,
233 * caller should set "bpm_out" to "-1" to avoid changing
234 * the current value; otherwise "bpm_out" will be lowered to
235 * the specified value; passing a pointer to "0" can be used to force
236 * us to disconnect from the peer; "bpm_out" might not increase
237 * as specified since the upper bound is generally
238 * determined by the other peer!
239 * @param amount reserve N bytes for receiving, negative
240 * amounts can be used to undo a (recent) reservation;
241 * @param preference increase incoming traffic share preference by this amount;
242 * in the absence of "amount" reservations, we use this
243 * preference value to assign proportional bandwidth shares
244 * to all connected peers
245 * @param info function to call with the resulting configuration information
246 * @param info_cls closure for info
247 */
248void
249GNUNET_CORE_peer_configure (struct GNUNET_CORE_Handle *handle,
250 const struct GNUNET_PeerIdentity *peer,
251 struct GNUNET_TIME_Relative timeout,
252 unsigned int bpm_out,
253 int amount,
254 double preference,
255 GNUNET_CORE_PeerConfigurationInfoCallback info,
256 void *info_cls);
257
258
259/**
260 * Handle for a transmission request.
261 */
262struct GNUNET_CORE_TransmitHandle;
263
264
265/**
266 * Ask the core to call "notify" once it is ready to transmit the
267 * given number of bytes to the specified "target". If we are not yet
268 * connected to the specified peer, a call to this function will cause
269 * us to try to establish a connection.
270 *
271 * @param handle connection to core service
272 * @param priority how important is the message?
273 * @param maxdelay how long can the message wait?
274 * @param target who should receive the message,
275 * use NULL for this peer (loopback)
276 * @param notify_size how many bytes of buffer space does notify want?
277 * @param notify function to call when buffer space is available
278 * @param notify_cls closure for notify
279 * @return non-NULL if the notify callback was queued,
280 * NULL if we can not even queue the request (insufficient
281 * memory); if NULL is returned, "notify" will NOT be called.
282 */
283struct GNUNET_CORE_TransmitHandle *GNUNET_CORE_notify_transmit_ready (struct
284 GNUNET_CORE_Handle
285 *handle,
286 unsigned
287 int
288 priority,
289 struct
290 GNUNET_TIME_Relative
291 maxdelay,
292 const
293 struct
294 GNUNET_PeerIdentity
295 *target,
296 size_t
297 notify_size,
298 GNUNET_NETWORK_TransmitReadyNotify
299 notify,
300 void
301 *notify_cls);
302
303
304/**
305 * Cancel the specified transmission-ready notification.
306 *
307 * @param h handle that was returned by "notify_transmit_ready".
308 */
309void
310GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle
311 *h);
312
313
314#if 0 /* keep Emacsens' auto-indent happy */
315{
316#endif
317#ifdef __cplusplus
318}
319#endif
320
321/* ifndef GNUNET_CORE_SERVICE_H */
322#endif
323/* end of gnunet_core_service.h */
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
new file mode 100644
index 000000000..361d244e2
--- /dev/null
+++ b/src/include/gnunet_crypto_lib.h
@@ -0,0 +1,567 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 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 2, 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 include/gnunet_crypto_lib.h
23 * @brief cryptographic primitives for GNUnet
24 *
25 * @author Christian Grothoff
26 * @author Krista Bennett
27 * @author Gerd Knorr <kraxel@bytesex.org>
28 * @author Ioana Patrascu
29 * @author Tzvetan Horozov
30 */
31
32#ifndef GNUNET_CRYPTO_LIB_H
33#define GNUNET_CRYPTO_LIB_H
34
35#ifdef __cplusplus
36extern "C"
37{
38#if 0 /* keep Emacsens' auto-indent happy */
39}
40#endif
41#endif
42
43#include "gnunet_common.h"
44#include "gnunet_scheduler_lib.h"
45
46
47enum GNUNET_CRYPTO_Quality
48{
49 GNUNET_CRYPTO_QUALITY_WEAK,
50 GNUNET_CRYPTO_QUALITY_STRONG
51};
52
53
54/**
55 * @brief length of the sessionkey in bytes (256 BIT sessionkey)
56 */
57#define GNUNET_CRYPTO_AES_KEY_LENGTH (256/8)
58
59
60/**
61 * @brief Length of RSA encrypted data (2048 bit)
62 *
63 * We currently do not handle encryption of data
64 * that can not be done in a single call to the
65 * RSA methods (read: large chunks of data).
66 * We should never need that, as we can use
67 * the GNUNET_CRYPTO_hash for larger pieces of data for signing,
68 * and for encryption, we only need to encode sessionkeys!
69 */
70#define GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH 256
71
72
73/**
74 * Length of an RSA KEY (d,e,len), 2048 bit (=256 octests) key d, 2 byte e
75 */
76#define GNUNET_CRYPTO_RSA_KEY_LENGTH 258
77
78
79/**
80 * The private information of an RSA key pair.
81 */
82struct GNUNET_CRYPTO_RsaPrivateKey;
83
84
85/**
86 * @brief 0-terminated ASCII encoding of a GNUNET_HashCode.
87 */
88struct GNUNET_CRYPTO_HashAsciiEncoded
89{
90 unsigned char encoding[104];
91};
92
93
94
95/**
96 * @brief an RSA signature
97 */
98struct GNUNET_CRYPTO_RsaSignature
99{
100 unsigned char sig[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH];
101};
102
103
104/**
105 * @brief header of what an RSA signature signs
106 * this must be followed by "size - 8" bytes of
107 * the actual signed data
108 */
109struct GNUNET_CRYPTO_RsaSignaturePurpose
110{
111 /**
112 * How many bytes does this signature sign?
113 * (including this purpose header); in network
114 * byte order (!).
115 */
116 uint32_t size GNUNET_PACKED;
117
118 /**
119 * What does this signature vouch for? This
120 * must contain a GNUNET_SIGNATURE_PURPOSE_XXX
121 * constant (from gnunet_signatures.h). In
122 * network byte order!
123 */
124 uint32_t purpose GNUNET_PACKED;
125
126};
127
128
129/**
130 * @brief A public key.
131 */
132struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
133{
134 /**
135 * In big-endian, must be GNUNET_CRYPTO_RSA_KEY_LENGTH+4
136 */
137 uint16_t len GNUNET_PACKED;
138
139 /**
140 * Size of n in key; in big-endian!
141 */
142 uint16_t sizen GNUNET_PACKED;
143
144 /**
145 * The key itself, contains n followed by e.
146 */
147 unsigned char key[GNUNET_CRYPTO_RSA_KEY_LENGTH];
148
149 /**
150 * Padding (must be 0)
151 */
152 uint16_t padding GNUNET_PACKED;
153};
154
155
156/**
157 * RSA Encrypted data.
158 */
159struct GNUNET_CRYPTO_RsaEncryptedData
160{
161 unsigned char encoding[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH];
162};
163
164
165/**
166 * @brief type for session keys
167 */
168struct GNUNET_CRYPTO_AesSessionKey
169{
170 /**
171 * Actual key.
172 */
173 unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH];
174
175 /**
176 * checksum!
177 */
178 uint32_t crc32 GNUNET_PACKED;
179};
180
181
182/**
183 * @brief IV for sym cipher
184 *
185 * NOTE: must be smaller (!) in size than the
186 * GNUNET_HashCode.
187 */
188struct GNUNET_CRYPTO_AesInitializationVector
189{
190 unsigned char iv[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
191};
192
193
194/* **************** Functions and Macros ************* */
195
196
197/**
198 * Compute the CRC32 checksum for the first len
199 * bytes of the buffer.
200 *
201 * @param buf the data over which we're taking the CRC
202 * @param len the length of the buffer in bytes
203 * @return the resulting CRC32 checksum
204 */
205int GNUNET_CRYPTO_crc32_n (const void *buf, unsigned int len);
206
207
208/**
209 * Produce a random value.
210 *
211 * @param i the upper limit (exclusive) for the random number
212 * @return a random value in the interval [0,i[.
213 */
214unsigned int GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality,
215 unsigned int i);
216
217
218/**
219 * Random on unsigned 64-bit values. We break them down into signed
220 * 32-bit values and reassemble the 64-bit random value bit-wise.
221 */
222unsigned long long GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode,
223 unsigned long long u);
224
225
226/**
227 * Get an array with a random permutation of the
228 * numbers 0...n-1.
229 * @param mode GNUNET_CRYPTO_QUALITY_STRONG if the strong (but expensive) PRNG should be used, GNUNET_CRYPTO_QUALITY_WEAK otherwise
230 * @param n the size of the array
231 * @return the permutation array (allocated from heap)
232 */
233unsigned int *GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode,
234 unsigned int n);
235
236
237/**
238 * Create a new Session key.
239 */
240void GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey
241 *key);
242
243
244/**
245 * Check that a new session key is well-formed.
246 *
247 * @return GNUNET_OK if the key is valid
248 */
249int GNUNET_CRYPTO_aes_check_session_key (const struct
250 GNUNET_CRYPTO_AesSessionKey *key);
251
252
253/**
254 * Encrypt a block with the public key of another
255 * host that uses the same cyper.
256 *
257 * @param block the block to encrypt
258 * @param len the size of the block
259 * @param sessionkey the key used to encrypt
260 * @param iv the initialization vector to use, use INITVALUE
261 * for streams.
262 * @returns the size of the encrypted block, -1 for errors
263 */
264int GNUNET_CRYPTO_aes_encrypt (const void *block,
265 uint16_t len,
266 const struct GNUNET_CRYPTO_AesSessionKey
267 *sessionkey,
268 const struct
269 GNUNET_CRYPTO_AesInitializationVector *iv,
270 void *result);
271
272
273/**
274 * Decrypt a given block with the sessionkey.
275 *
276 * @param sessionkey the key used to decrypt
277 * @param block the data to decrypt, encoded as returned by encrypt
278 * @param size how big is the block?
279 * @param iv the initialization vector to use
280 * @param result address to store the result at
281 * @return -1 on failure, size of decrypted block on success
282 */
283int GNUNET_CRYPTO_aes_decrypt (const struct GNUNET_CRYPTO_AesSessionKey
284 *sessionkey, const void *block, uint16_t size,
285 const struct
286 GNUNET_CRYPTO_AesInitializationVector *iv,
287 void *result);
288
289
290/**
291 * Convert GNUNET_CRYPTO_hash to ASCII encoding.
292 * @param block the GNUNET_CRYPTO_hash code
293 * @param result where to store the encoding (struct GNUNET_CRYPTO_HashAsciiEncoded can be
294 * safely cast to char*, a '\0' termination is set).
295 */
296void GNUNET_CRYPTO_hash_to_enc (const GNUNET_HashCode * block,
297 struct GNUNET_CRYPTO_HashAsciiEncoded
298 *result);
299
300
301/**
302 * Convert ASCII encoding back to GNUNET_CRYPTO_hash
303 * @param enc the encoding
304 * @param result where to store the GNUNET_CRYPTO_hash code
305 * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding
306 */
307int GNUNET_CRYPTO_hash_from_string (const char *enc,
308 GNUNET_HashCode * result);
309
310
311/**
312 * Compute the distance between 2 hashcodes.
313 * The computation must be fast, not involve
314 * a.a or a.e (they're used elsewhere), and
315 * be somewhat consistent. And of course, the
316 * result should be a positive number.
317 * @return number between 0 and 65536
318 */
319unsigned int GNUNET_CRYPTO_hash_distance_u32 (const GNUNET_HashCode * a,
320 const GNUNET_HashCode * b);
321
322
323/**
324 * Hash block of given size.
325 * @param block the data to GNUNET_CRYPTO_hash, length is given as a second argument
326 * @param ret pointer to where to write the hashcode
327 */
328void GNUNET_CRYPTO_hash (const void *block, unsigned int size,
329 GNUNET_HashCode * ret);
330
331
332/**
333 * Function called once the hash computation over the
334 * specified file has completed.
335 *
336 * @param cls closure
337 * @param res resulting hash, NULL on error
338 */
339typedef void (*GNUNET_CRYPTO_HashCompletedCallback) (void *cls,
340 const GNUNET_HashCode *
341 res);
342
343
344/**
345 * Compute the hash of an entire file.
346 *
347 * @param sched scheduler to use
348 * @param priority scheduling priority to use
349 * @param run_on_shutdown should we complete even on shutdown?
350 * @param filename name of file to hash
351 * @param blocksize number of bytes to process in one task
352 * @param callback function to call upon completion
353 * @param callback_cls closure for callback
354 */
355void GNUNET_CRYPTO_hash_file (struct GNUNET_SCHEDULER_Handle *sched,
356 enum GNUNET_SCHEDULER_Priority priority,
357 int run_on_shutdown,
358 const char *filename,
359 size_t blocksize,
360 GNUNET_CRYPTO_HashCompletedCallback callback,
361 void *callback_cls);
362
363
364/**
365 * Create a random hash code.
366 */
367void GNUNET_CRYPTO_hash_create_random (GNUNET_HashCode * result);
368
369
370/**
371 * compute result(delta) = b - a
372 */
373void GNUNET_CRYPTO_hash_difference (const GNUNET_HashCode * a,
374 const GNUNET_HashCode * b,
375 GNUNET_HashCode * result);
376
377
378/**
379 * compute result(b) = a + delta
380 */
381void GNUNET_CRYPTO_hash_sum (const GNUNET_HashCode * a,
382 const GNUNET_HashCode * delta,
383 GNUNET_HashCode * result);
384
385
386/**
387 * compute result = a ^ b
388 */
389void GNUNET_CRYPTO_hash_xor (const GNUNET_HashCode * a,
390 const GNUNET_HashCode * b,
391 GNUNET_HashCode * result);
392
393
394/**
395 * Convert a hashcode into a key.
396 */
397void GNUNET_CRYPTO_hash_to_AES_key (const GNUNET_HashCode * hc,
398 struct GNUNET_CRYPTO_AesSessionKey *skey,
399 struct
400 GNUNET_CRYPTO_AesInitializationVector
401 *iv);
402
403
404/**
405 * Obtain a bit from a hashcode.
406 * @param code the GNUNET_CRYPTO_hash to index bit-wise
407 * @param bit index into the hashcode, [0...159]
408 * @return Bit \a bit from hashcode \a code, -1 for invalid index
409 */
410int GNUNET_CRYPTO_hash_get_bit (const GNUNET_HashCode * code,
411 unsigned int bit);
412
413
414/**
415 * Compare function for HashCodes, producing a total ordering
416 * of all hashcodes.
417 * @return 1 if h1 > h2, -1 if h1 < h2 and 0 if h1 == h2.
418 */
419int GNUNET_CRYPTO_hash_cmp (const GNUNET_HashCode * h1,
420 const GNUNET_HashCode * h2);
421
422
423/**
424 * Find out which of the two GNUNET_CRYPTO_hash codes is closer to target
425 * in the XOR metric (Kademlia).
426 * @return -1 if h1 is closer, 1 if h2 is closer and 0 if h1==h2.
427 */
428int GNUNET_CRYPTO_hash_xorcmp (const GNUNET_HashCode * h1,
429 const GNUNET_HashCode * h2,
430 const GNUNET_HashCode * target);
431
432
433/**
434 * Create a new private key. Caller must free return value.
435 */
436struct GNUNET_CRYPTO_RsaPrivateKey *GNUNET_CRYPTO_rsa_key_create (void);
437
438
439/**
440 * Create a new private key by reading it from a file. If the
441 * files does not exist, create a new key and write it to the
442 * file. Caller must free return value. Note that this function
443 * can not guarantee that another process might not be trying
444 * the same operation on the same file at the same time. The
445 * caller must somehow know that the file either already exists
446 * with a valid key OR be sure that no other process is calling
447 * this function at the same time. If the contents of the file
448 * are invalid the old file is deleted and a fresh key is
449 * created.
450 *
451 * @return new private key, NULL on error (for example,
452 * permission denied)
453 */
454struct GNUNET_CRYPTO_RsaPrivateKey
455 *GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename);
456
457
458/**
459 * Deterministically (!) create a private key using only the
460 * given HashCode as input to the PRNG.
461 */
462struct GNUNET_CRYPTO_RsaPrivateKey
463 *GNUNET_CRYPTO_rsa_key_create_from_hash (const GNUNET_HashCode * input);
464
465
466/**
467 * Free memory occupied by the private key.
468 * @param hostkey pointer to the memory to free
469 */
470void GNUNET_CRYPTO_rsa_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *hostkey);
471
472
473/**
474 * Extract the public key of the host.
475 * @param result where to write the result.
476 */
477void GNUNET_CRYPTO_rsa_key_get_public (const struct
478 GNUNET_CRYPTO_RsaPrivateKey *hostkey,
479 struct
480 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
481 *result);
482
483
484/**
485 * Encrypt a block with the public key of another host that uses the
486 * same cyper.
487 *
488 * @param block the block to encrypt
489 * @param size the size of block
490 * @param publicKey the encoded public key used to encrypt
491 * @param target where to store the encrypted block
492 * @returns GNUNET_SYSERR on error, GNUNET_OK if ok
493 */
494int GNUNET_CRYPTO_rsa_encrypt (const void *block,
495 uint16_t size,
496 const struct
497 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
498 *publicKey,
499 struct GNUNET_CRYPTO_RsaEncryptedData *target);
500
501
502/**
503 * Decrypt a given block with the hostkey.
504 *
505 * @param key the key to use
506 * @param block the data to decrypt, encoded as returned by encrypt, not consumed
507 * @param result pointer to a location where the result can be stored
508 * @param size how many bytes of a result are expected? Must be exact.
509 * @returns the size of the decrypted block (that is, size) or -1 on error
510 */
511int GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
512 const struct GNUNET_CRYPTO_RsaEncryptedData
513 *block, void *result, uint16_t size);
514
515
516/**
517 * Sign a given block.
518 *
519 * @param key private key to use for the signing
520 * @param purpose what to sign (size, purpose)
521 * @param result where to write the signature
522 * @return GNUNET_SYSERR on error, GNUNET_OK on success
523 */
524int GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
525 const struct GNUNET_CRYPTO_RsaSignaturePurpose
526 *purpose,
527 struct GNUNET_CRYPTO_RsaSignature *result);
528
529
530/**
531 * Verify signature. Note that the caller MUST have already
532 * checked that "validate->size" bytes are actually available.
533 *
534 * @param purpose what is the purpose that validate should have?
535 * @param validate block to validate (size, purpose, data)
536 * @param sig signature that is being validated
537 * @param publicKey public key of the signer
538 * @returns GNUNET_OK if ok, GNUNET_SYSERR if invalid
539 */
540int GNUNET_CRYPTO_rsa_verify (uint32_t purpose,
541 const struct GNUNET_CRYPTO_RsaSignaturePurpose
542 *validate,
543 const struct GNUNET_CRYPTO_RsaSignature *sig,
544 const struct
545 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
546 *publicKey);
547
548
549
550/**
551 * This function should only be called in testcases
552 * where strong entropy gathering is not desired
553 * (for example, for hostkey generation).
554 */
555void GNUNET_CRYPTO_random_disable_entropy_gathering (void);
556
557#if 0 /* keep Emacsens' auto-indent happy */
558{
559#endif
560#ifdef __cplusplus
561}
562#endif
563
564
565/* ifndef GNUNET_CRYPTO_LIB_H */
566#endif
567/* end of gnunet_crypto_lib.h */
diff --git a/src/include/gnunet_datastore_service.h b/src/include/gnunet_datastore_service.h
new file mode 100644
index 000000000..b20c6b100
--- /dev/null
+++ b/src/include/gnunet_datastore_service.h
@@ -0,0 +1,187 @@
1/*
2 This file is part of GNUnet
3 (C) 2004, 2005, 2006, 2007, 2009 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 2, 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 include/gnunet_datastore_service.h
23 * @brief API that can be used manage the
24 * datastore for files stored on a GNUnet node;
25 * note that the datastore is NOT responsible for
26 * on-demand encoding, that is achieved using
27 * a special kind of entry.
28 * @author Christian Grothoff
29 */
30
31#ifndef GNUNET_DATASTORE_SERVICE_H
32#define GNUNET_DATASTORE_SERVICE_H
33
34#include "gnunet_core.h"
35
36#ifdef __cplusplus
37extern "C"
38{
39#if 0 /* keep Emacsens' auto-indent happy */
40}
41#endif
42#endif
43
44
45/**
46 * Handle to the datastore service.
47 */
48struct GNUNET_DATASTORE_Handle;
49
50
51/**
52 * An iterator over a set of items stored in the datastore.
53 *
54 * @param cls closure
55 * @param key key for the content
56 * @param size number of bytes in data
57 * @param data content stored
58 * @param type type of the content
59 * @param priority priority of the content
60 * @param anonymity anonymity-level for the content
61 * @param expiration expiration time for the content
62 * @param uid unique identifier for the datum;
63 * maybe 0 if no unique identifier is available
64 *
65 * @return GNUNET_SYSERR to abort the iteration, GNUNET_OK to continue,
66 * GNUNET_NO to delete the item and continue (if supported)
67 */
68typedef int (*GNUNET_DATASTORE_Iterator) (void *cls,
69 const GNUNET_HashCode * key,
70 uint32_t size,
71 const void *data,
72 uint32_t type,
73 uint32_t priority,
74 uint32_t anonymity,
75 struct GNUNET_TIME_Absolute
76 expiration, unsigned long long uid);
77
78/**
79 * Connect to the datastore service.
80 *
81 * @param cfg configuration to use
82 * @param sched scheduler to use
83 * @return handle to use to access the service
84 */
85struct GNUNET_DATASTORE_Handle *GNUNET_DATASTORE_connect (struct
86 GNUNET_CONFIGURATION_Handle
87 *cfg,
88 struct
89 GNUNET_SCHEDULER_Handle
90 *sched);
91
92
93/**
94 * Disconnect from the datastore service (and free
95 * associated resources).
96 * @param h handle to the datastore
97 */
98void GNUNET_DATASTORE_disconnect (struct GNUNET_DATASTORE_Handle *h);
99
100
101/**
102 * Get the current on-disk size of the datastore.
103 * @param h handle to the datastore
104 * @return size estimate, -1 if datastore is not available (yet)
105 */
106unsigned long long GNUNET_DATASTORE_size (struct GNUNET_DATASTORE_Handle *h);
107
108
109/**
110 * Store an item in the datastore. If the item is already present,
111 * the priorities are summed up and the higher expiration time and
112 * lower anonymity level is used.
113 *
114 * @param h handle to the datastore
115 * @param key key for the value
116 * @param size number of bytes in data
117 * @param data content stored
118 * @param type type of the content
119 * @param priority priority of the content
120 * @param anonymity anonymity-level for the content
121 * @param expiration expiration time for the content
122 */
123void
124GNUNET_DATASTORE_put (struct GNUNET_DATASTORE_Handle *h,
125 const GNUNET_HashCode * key,
126 uint32_t size,
127 const void *data,
128 unit32_t type,
129 uint32_t priority,
130 uint32_t anonymity,
131 struct GNUNET_TIME_Absolute expiration);
132
133/**
134 * Iterate over the results for a particular key
135 * in the datastore.
136 *
137 * @param h handle to the datastore
138 * @param key maybe NULL (to match all entries)
139 * @param type desired type, 0 for any
140 * @param iter function to call on each matching value;
141 * will be called once with a NULL value at the end
142 * @param iter_cls closure for iter
143 */
144void
145GNUNET_DATASTORE_get (struct GNUNET_DATASTORE_Handle *h,
146 const GNUNET_HashCode * key,
147 uint32_t type,
148 GNUNET_DATASTORE_Iterator iter, void *iter_cls);
149
150
151/**
152 * Get a random value from the datastore.
153 *
154 * @param h handle to the datastore
155 * @param iter function to call on each matching value;
156 * will be called exactly once; if no values
157 * are available, the value will be NULL.
158 * @param iter_cls closure for iter
159 */
160void
161GNUNET_DATASTORE_get_random (struct GNUNET_DATASTORE_Handle *h,
162 GNUNET_DATASTORE_Iterator iter, void *iter_cls);
163
164
165/**
166 * Explicitly remove some content from the database.
167 *
168 * @param h handle to the datastore
169 * @param key key for the value
170 * @param size number of bytes in data
171 * @param data content stored
172 */
173void
174GNUNET_DATASTORE_remove (struct GNUNET_DATASTORE_Handle *h,
175 const GNUNET_HashCode * key,
176 uint32_t size, const void *data);
177
178
179#if 0 /* keep Emacsens' auto-indent happy */
180{
181#endif
182#ifdef __cplusplus
183}
184#endif
185
186/* end of gnunet_datastore_service.h */
187#endif
diff --git a/src/include/gnunet_directories.h.in b/src/include/gnunet_directories.h.in
new file mode 100644
index 000000000..b05b6d9ce
--- /dev/null
+++ b/src/include/gnunet_directories.h.in
@@ -0,0 +1,34 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006 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 2, 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 include/gnunet_directories.h
23 * @brief directories and files in GNUnet (default locations)
24 *
25 * @author Christian Grothoff
26 */
27
28#ifndef GNUNET_DIRECTORIES
29#define GNUNET_DIRECTORIES
30
31#define GNUNET_DEFAULT_CLIENT_CONFIG_FILE "@GN_USER_HOME_DIR@/gnunet.conf"
32#define GNUNET_DEFAULT_DAEMON_CONFIG_FILE "@GN_DAEMON_CONFIG_DIR@/gnunetd.conf"
33
34#endif
diff --git a/src/include/gnunet_disk_lib.h b/src/include/gnunet_disk_lib.h
new file mode 100644
index 000000000..3886be7c9
--- /dev/null
+++ b/src/include/gnunet_disk_lib.h
@@ -0,0 +1,279 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006 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 2, 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 include/gnunet_disk_lib.h
23 * @brief disk IO apis
24 */
25
26#ifndef GNUNET_DISK_LIB_H
27#define GNUNET_DISK_LIB_H
28
29#include "gnunet_configuration_lib.h"
30#include "gnunet_scheduler_lib.h"
31
32/* we need size_t, and since it can be both unsigned int
33 or unsigned long long, this IS platform dependent;
34 but "stdlib.h" should be portable 'enough' to be
35 unconditionally available... */
36#include <stdlib.h>
37
38#ifdef __cplusplus
39extern "C"
40{
41#if 0 /* keep Emacsens' auto-indent happy */
42}
43#endif
44#endif
45
46/**
47 * Get the number of blocks that are left on the partition that
48 * contains the given file (for normal users).
49 *
50 * @param part a file on the partition to check
51 * @return -1 on errors, otherwise the number of free blocks
52 */
53long GNUNET_DISK_get_blocks_available (const char *part);
54
55
56/**
57 * Check that fil corresponds to a filename
58 * (of a file that exists and that is not a directory).
59 *
60 * @returns GNUNET_YES if yes, GNUNET_NO if not a file, GNUNET_SYSERR if something
61 * else (will print an error message in that case, too).
62 */
63int GNUNET_DISK_file_test (const char *fil);
64
65
66/**
67 * Get the size of the file (or directory)
68 * of the given file (in bytes).
69 *
70 * @param includeSymLinks should symbolic links be
71 * included?
72 *
73 * @return GNUNET_OK on success, GNUNET_SYSERR on error
74 */
75int GNUNET_DISK_file_size (const char *filename,
76 unsigned long long *size, int includeSymLinks);
77
78
79/**
80 * Wrapper around "open()". Opens a file.
81 *
82 * @return file handle, -1 on error
83 */
84int GNUNET_DISK_file_open (const char *filename, int oflag, ...);
85
86
87/**
88 * Wrapper around "close()". Closes a file.
89 */
90void GNUNET_DISK_file_close (const char *filename, int fd);
91
92
93/**
94 * Read the contents of a binary file into a buffer.
95 * @param fileName the name of the file, not freed,
96 * must already be expanded!
97 * @param len the maximum number of bytes to read
98 * @param result the buffer to write the result to
99 * @return the number of bytes read on success, -1 on failure
100 */
101int GNUNET_DISK_file_read (const char *fileName, int len, void *result);
102
103
104/**
105 * Write a buffer to a file.
106 * @param fileName the name of the file, NOT freed!
107 * @param buffer the data to write
108 * @param n number of bytes to write
109 * @param mode the mode for file permissions
110 * @return GNUNET_OK on success, GNUNET_SYSERR on error
111 */
112int GNUNET_DISK_file_write (const char *fileName,
113 const void *buffer, unsigned int n,
114 const char *mode);
115
116
117/**
118 * Copy a file.
119 * @return GNUNET_OK on success, GNUNET_SYSERR on error
120 */
121int GNUNET_DISK_file_copy (const char *src, const char *dst);
122
123
124/**
125 * Scan a directory for files. The name of the directory
126 * must be expanded first (!).
127 *
128 * @param dirName the name of the directory
129 * @param callback the method to call for each file
130 * @param data argument to pass to callback
131 * @return the number of files found, -1 on error
132 */
133int GNUNET_DISK_directory_scan (const char *dirName,
134 GNUNET_FileNameCallback callback, void *data);
135
136
137/**
138 * Opaque handle used for iterating over a directory.
139 */
140struct GNUNET_DISK_DirectoryIterator;
141
142
143/**
144 * Function called to iterate over a directory.
145 *
146 * @param cls closure
147 * @param di argument to pass to "GNUNET_DISK_directory_iterator_next" to
148 * get called on the next entry (or finish cleanly)
149 * @param filename complete filename (absolute path)
150 * @param dirname directory name (absolute path)
151 */
152typedef void (*GNUNET_DISK_DirectoryIteratorCallback) (void *cls,
153 struct
154 GNUNET_DISK_DirectoryIterator
155 * di,
156 const char *filename,
157 const char *dirname);
158
159
160/**
161 * This function must be called during the DiskIteratorCallback
162 * (exactly once) to schedule the task to process the next
163 * filename in the directory (if there is one).
164 *
165 * @param iter opaque handle for the iterator
166 * @param can set to GNUNET_YES to terminate the iteration early
167 * @return GNUNET_YES if iteration will continue,
168 * GNUNET_NO if this was the last entry (and iteration is complete),
169 * GNUNET_SYSERR if "can" was YES
170 */
171int GNUNET_DISK_directory_iterator_next (struct GNUNET_DISK_DirectoryIterator
172 *iter, int can);
173
174
175/**
176 * Scan a directory for files using the scheduler to run a task for
177 * each entry. The name of the directory must be expanded first (!).
178 * If a scheduler does not need to be used, GNUNET_DISK_directory_scan
179 * may provide a simpler API.
180 *
181 * @param sched scheduler to use
182 * @param prio priority to use
183 * @param dirName the name of the directory
184 * @param callback the method to call for each file
185 * @param callback_cls closure for callback
186 */
187void GNUNET_DISK_directory_iterator_start (struct GNUNET_SCHEDULER_Handle
188 *sched,
189 enum GNUNET_SCHEDULER_Priority
190 prio, const char *dirName,
191 GNUNET_DISK_DirectoryIteratorCallback
192 callback, void *callback_cls);
193
194
195/**
196 * Create the directory structure for storing
197 * a file.
198 *
199 * @param filename name of a file in the directory
200 * @returns GNUNET_OK on success, GNUNET_SYSERR on failure,
201 * GNUNET_NO if directory exists but is not writeable
202 */
203int GNUNET_DISK_directory_create_for_file (const char *filename);
204
205
206/**
207 * Test if fil is a directory that can be accessed.
208 * Will not print an error message if the directory
209 * does not exist. Will log errors if GNUNET_SYSERR is
210 * returned.
211 *
212 * @return GNUNET_YES if yes, GNUNET_NO if does not exist, GNUNET_SYSERR
213 * on any error and if exists but not directory
214 */
215int GNUNET_DISK_directory_test (const char *fil);
216
217
218/**
219 * Remove all files in a directory (rm -rf). Call with
220 * caution.
221 *
222 * @param fileName the file to remove
223 * @return GNUNET_OK on success, GNUNET_SYSERR on error
224 */
225int GNUNET_DISK_directory_remove (const char *fileName);
226
227
228/**
229 * Implementation of "mkdir -p"
230 *
231 * @param dir the directory to create
232 * @returns GNUNET_SYSERR on failure, GNUNET_OK otherwise
233 */
234int GNUNET_DISK_directory_create (const char *dir);
235
236
237/**
238 * @brief Removes special characters as ':' from a filename.
239 * @param fn the filename to canonicalize
240 */
241void GNUNET_DISK_filename_canonicalize (char *fn);
242
243
244/**
245 * @brief Change owner of a file
246 * @param filename file to change
247 * @param user new owner of the file
248 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
249 */
250int GNUNET_DISK_file_change_owner (const char *filename, const char *user);
251
252
253/**
254 * Construct full path to a file inside of the private
255 * directory used by GNUnet. Also creates the corresponding
256 * directory. If the resulting name is supposed to be
257 * a directory, end the last argument in '/' (or pass
258 * DIR_SEPARATOR_STR as the last argument before NULL).
259 *
260 * @param serviceName name of the service asking
261 * @param varargs is NULL-terminated list of
262 * path components to append to the
263 * private directory name.
264 * @return the constructed filename
265 */
266char *GNUNET_DISK_get_home_filename (struct GNUNET_CONFIGURATION_Handle *cfg,
267 const char *serviceName, ...);
268
269#if 0 /* keep Emacsens' auto-indent happy */
270{
271#endif
272#ifdef __cplusplus
273}
274#endif
275
276
277/* ifndef GNUNET_DISK_LIB_H */
278#endif
279/* end of gnunet_disk_lib.h */
diff --git a/src/include/gnunet_fragmentation_lib.h b/src/include/gnunet_fragmentation_lib.h
new file mode 100644
index 000000000..5089fae6a
--- /dev/null
+++ b/src/include/gnunet_fragmentation_lib.h
@@ -0,0 +1,113 @@
1/*
2 This file is part of GNUnet
3 (C) 2009 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 2, 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 include/gnunet_fragmentation_lib.h
22 * @brief library to help fragment messages
23 * @author Christian Grothoff
24 */
25
26#ifndef GNUNET_FRAGMENTATION_LIB_H
27#define GNUNET_FRAGMENTATION_LIB_H
28
29#include "gnunet_common.h"
30#include "gnunet_statistics_service.h"
31
32#ifdef __cplusplus
33extern "C"
34{
35#if 0 /* keep Emacsens' auto-indent happy */
36}
37#endif
38#endif
39
40/**
41 * Function that is called with messages
42 * created by the fragmentation module.
43 *
44 * @param cls closure
45 * @param msg the message that was created
46 */
47typedef void (*GNUNET_FRAGMENT_MessageProcessor) (void *cls,
48 const struct
49 GNUNET_MessageHeader * msg);
50
51
52/**
53 * Fragment an over-sized message.
54 *
55 * @param msg the message to fragment
56 * @param mtu the maximum message size
57 * @param proc function to call for each fragment
58 * @param proc_cls closure for proc
59 */
60void GNUNET_FRAGMENT_fragment (const struct GNUNET_MessageHeader *msg,
61 uint16_t mtu,
62 GNUNET_FRAGMENT_MessageProcessor proc,
63 void *proc_cls);
64
65/**
66 * Defragmentation context.
67 */
68struct GNUNET_FRAGMENT_Context;
69
70/**
71 * Create a defragmentation context.
72 *
73 * @param stats statistics context
74 * @param proc function to call with defragmented messages
75 * @param proc_cls closure for proc
76 * @return the defragmentation context
77 */
78struct GNUNET_FRAGMENT_Context *GNUNET_FRAGMENT_context_create (struct
79 GNUNET_STATISTICS_Handle
80 *stats,
81 GNUNET_FRAGMENT_MessageProcessor
82 proc,
83 void
84 *proc_cls);
85
86
87/**
88 * Destroy the given defragmentation context.
89 */
90void GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *ctx);
91
92
93/**
94 * We have received a fragment. Process it.
95 *
96 * @param ctx the context
97 * @param sender who transmitted the fragment
98 * @param msg the message that was received
99 */
100void GNUNET_FRAGMENT_process (struct GNUNET_FRAGMENT_Context *ctx,
101 const struct GNUNET_PeerIdentity *sender,
102 const struct GNUNET_MessageHeader *msg);
103
104
105#if 0 /* keep Emacsens' auto-indent happy */
106{
107#endif
108#ifdef __cplusplus
109}
110#endif
111
112/* end of gnunet_fragmentation_lib.h */
113#endif
diff --git a/src/include/gnunet_getopt_lib.h b/src/include/gnunet_getopt_lib.h
new file mode 100644
index 000000000..722155568
--- /dev/null
+++ b/src/include/gnunet_getopt_lib.h
@@ -0,0 +1,251 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009 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 2, 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 include/gnunet_getopt_lib.h
23 * @brief command line parsing and --help formatting
24 *
25 * @author Christian Grothoff
26 */
27
28#ifndef GNUNET_GETOPT_LIB_H
29#define GNUNET_GETOPT_LIB_H
30
31#ifdef __cplusplus
32extern "C"
33{
34#if 0 /* keep Emacsens' auto-indent happy */
35}
36#endif
37#endif
38
39#include "gnunet_configuration_lib.h"
40
41/**
42 * @brief General context for command line processors.
43 */
44struct GNUNET_GETOPT_CommandLineProcessorContext
45{
46
47 /**
48 * Name of the application
49 */
50 const char *binaryName;
51
52 /**
53 * Name of application with option summary
54 */
55 const char *binaryOptions;
56
57 /**
58 * Array with all command line options.
59 */
60 const struct GNUNET_GETOPT_CommandLineOption *allOptions;
61
62 /**
63 * For configuration
64 */
65 struct GNUNET_CONFIGURATION_Handle *cfg;
66
67 /**
68 * Original command line
69 */
70 char *const *argv;
71
72 /**
73 * Total number of argv's.
74 */
75 unsigned int argc;
76
77 /**
78 * Current argument.
79 */
80 unsigned int currentArgument;
81
82};
83
84/**
85 * @brief Process a command line option
86 *
87 * @param ctx context for all options
88 * @param scls specific closure (for this processor)
89 * @param option long name of the option (i.e. "config" for --config)
90 * @param value argument, NULL if none was given
91 * @return GNUNET_OK to continue processing other options, GNUNET_SYSERR to abort
92 */
93typedef
94 int (*GNUNET_GETOPT_CommandLineOptionProcessor) (struct
95 GNUNET_GETOPT_CommandLineProcessorContext
96 * ctx, void *scls,
97 const char *option,
98 const char *value);
99
100/**
101 * @brief Definition of a command line option.
102 */
103struct GNUNET_GETOPT_CommandLineOption
104{
105
106 /**
107 * Short name of the option (use '\0' for none).
108 */
109 const char shortName;
110
111 /**
112 * Long name of the option (may not be NULL)
113 */
114 const char *name;
115
116 /**
117 * Name of the argument for the user in help text
118 */
119 const char *argumentHelp;
120
121 /**
122 * Help text for the option (description)
123 */
124 const char *description;
125
126 /**
127 * Is an argument required? 0: GNUNET_NO (includes optional), 1: GNUNET_YES.
128 */
129 int require_argument;
130
131 /**
132 * Handler for the option.
133 */
134 GNUNET_GETOPT_CommandLineOptionProcessor processor;
135
136 /**
137 * Specific closure to pass to the processor.
138 */
139 void *scls;
140
141};
142
143/**
144 * Macro defining the option to print the command line
145 * help text.
146 *
147 * @param about string with brief description of the application
148 */
149#define GNUNET_GETOPT_OPTION_HELP(about) \
150 { 'h', "help", (const char *) NULL, gettext_noop("print this help"), 0, &GNUNET_GETOPT_format_help_, (void *) about }
151
152/**
153 * Macro defining the option to print the version of
154 * the application
155 *
156 * @param version string with the version number
157 */
158#define GNUNET_GETOPT_OPTION_VERSION(version) \
159 { 'v', "version", (const char *) NULL, gettext_noop("print the version number"), 0, &GNUNET_GETOPT_print_version_, (void *) version }
160
161/**
162 * Get the log level
163 */
164#define GNUNET_GETOPT_OPTION_LOGFILE(logfn) \
165 { 'l', "logfile", "LOGFILE", gettext_noop("configure logging to write logs to LOGFILE"), 1, &GNUNET_GETOPT_set_string, (void *) logfn }
166
167/**
168 * Set the configuration option for logging.
169 */
170#define GNUNET_GETOPT_OPTION_LOGLEVEL(loglev) \
171 { 'L', "log", "LOGLEVEL", gettext_noop("configure logging to use LOGLEVEL"), 1, &GNUNET_GETOPT_set_string, (void *) loglev }
172
173/**
174 * Get number of verbose flags
175 */
176#define GNUNET_GETOPT_OPTION_VERBOSE(level) \
177 { 'V', "verbose", (const char *) NULL, gettext_noop("be verbose"), 0, &GNUNET_GETOPT_increment_value, (void *) level }
178
179/**
180 * Get configuration file name
181 */
182#define GNUNET_GETOPT_OPTION_CFG_FILE(fn) \
183 { 'c', "config", "FILENAME", gettext_noop("use configuration file FILENAME"), 1, &GNUNET_GETOPT_set_string, (void *) fn }
184
185/**
186 * Marker to end the list of options.
187 */
188#define GNUNET_GETOPT_OPTION_END \
189 { '\0', NULL, NULL, NULL, 0, NULL, NULL }
190
191/**
192 * Parse the command line.
193 *
194 * @param binaryName name of the binary / application with options
195 * @param cfg for storing/accessing configuration data
196 * @param allOptions defined options and handlers
197 * @param argc number of arguments
198 * @param argv actual arguments
199 * @return index into argv with first non-option
200 * argument, or GNUNET_SYSERR on error
201 */
202int GNUNET_GETOPT_run (const char *binaryName,
203 struct GNUNET_CONFIGURATION_Handle *cfg,
204 const struct GNUNET_GETOPT_CommandLineOption
205 *allOptions, unsigned int argc, char *const *argv);
206
207int GNUNET_GETOPT_set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext
208 *ctx, void *scls, const char *option,
209 const char *value);
210
211int GNUNET_GETOPT_set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext
212 *ctx, void *scls, const char *option,
213 const char *value);
214
215int GNUNET_GETOPT_set_one (struct GNUNET_GETOPT_CommandLineProcessorContext
216 *ctx, void *scls, const char *option,
217 const char *value);
218
219int GNUNET_GETOPT_set_string (struct GNUNET_GETOPT_CommandLineProcessorContext
220 *ctx, void *scls, const char *option,
221 const char *value);
222
223int
224GNUNET_GETOPT_increment_value (struct
225 GNUNET_GETOPT_CommandLineProcessorContext *ctx,
226 void *scls, const char *option,
227 const char *value);
228
229/* *************** internal prototypes - use macros above! ************* */
230
231int GNUNET_GETOPT_format_help_ (struct
232 GNUNET_GETOPT_CommandLineProcessorContext
233 *ctx, void *scls, const char *option,
234 const char *value);
235
236int GNUNET_GETOPT_print_version_ (struct
237 GNUNET_GETOPT_CommandLineProcessorContext
238 *ctx, void *scls, const char *option,
239 const char *value);
240
241#if 0 /* keep Emacsens' auto-indent happy */
242{
243#endif
244#ifdef __cplusplus
245}
246#endif
247
248
249/* ifndef GNUNET_GETOPT_LIB_H */
250#endif
251/* end of gnunet_getopt_lib.h */
diff --git a/src/include/gnunet_hello_lib.h b/src/include/gnunet_hello_lib.h
new file mode 100644
index 000000000..2ba6df6ab
--- /dev/null
+++ b/src/include/gnunet_hello_lib.h
@@ -0,0 +1,201 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006 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 2, 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 include/gnunet_hello_lib.h
23 * @brief helper library for handling HELLOs
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_HELLO_LIB_H
28#define GNUNET_HELLO_LIB_H
29
30#ifdef __cplusplus
31extern "C"
32{
33#if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38#include "gnunet_common.h"
39#include "gnunet_crypto_lib.h"
40
41/**
42 * A HELLO message is used to exchange information about
43 * transports with other peers. This struct is guaranteed
44 * to start with a "GNUNET_MessageHeader", everything else
45 * should be internal to the HELLO library.
46 */
47struct GNUNET_HELLO_Message;
48
49
50/**
51 * Copy the given address information into
52 * the given buffer using the format of HELLOs.
53 *
54 * @param tname name of the transport plugin
55 * @param expiration expiration for the address
56 * @param addr the address
57 * @param addr_len length of the address in bytes
58 * @param target where to copy the address
59 * @param max maximum number of bytes to copy to target
60 * @return number of bytes copied, 0 if
61 * the target buffer was not big enough.
62 */
63size_t
64GNUNET_HELLO_add_address (const char *tname,
65 struct GNUNET_TIME_Absolute expiration,
66 const void *addr,
67 size_t addr_len, char *target, size_t max);
68
69
70/**
71 * Callback function used to fill a buffer of max bytes with a list of
72 * addresses in the format used by HELLOs. Should use
73 * "GNUNET_HELLO_add_address" as a helper function.
74 *
75 * @param cls closure
76 * @param max maximum number of bytes that can be written to buf
77 * @param buf where to write the address information
78 * @return number of bytes written, 0 to signal the
79 * end of the iteration.
80 */
81typedef size_t
82 (*GNUNET_HELLO_GenerateAddressListCallback) (void *cls,
83 size_t max, void *buf);
84
85
86/**
87 * Construct a HELLO message given the public key,
88 * expiration time and an iterator that spews the
89 * transport addresses.
90 *
91 * @return the hello message
92 */
93struct GNUNET_HELLO_Message *GNUNET_HELLO_create (const struct
94 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
95 *publicKey,
96 GNUNET_HELLO_GenerateAddressListCallback
97 addrgen, void *addrgen_cls);
98
99
100/**
101 * Return the size of the given HELLO message.
102 * @param hello to inspect
103 * @return the size, 0 if HELLO is invalid
104 */
105uint16_t GNUNET_HELLO_size (const struct GNUNET_HELLO_Message *hello);
106
107
108/**
109 * Construct a HELLO message by merging the
110 * addresses in two existing HELLOs (which
111 * must be for the same peer).
112 *
113 * @param h1 first HELLO message
114 * @param h2 the second HELLO message
115 * @return the combined hello message
116 */
117struct GNUNET_HELLO_Message *GNUNET_HELLO_merge (const struct
118 GNUNET_HELLO_Message *h1,
119 const struct
120 GNUNET_HELLO_Message *h2);
121
122
123/**
124 * Iterator callback to go over all addresses.
125 *
126 * @param cls closure
127 * @param tname name of the transport
128 * @param expiration expiration time
129 * @param addr the address
130 * @param addrlen length of the address
131 * @return GNUNET_OK to keep the address,
132 * GNUNET_NO to delete it from the HELLO
133 * GNUNET_SYSERR to stop iterating (but keep current address)
134 */
135typedef int
136 (*GNUNET_HELLO_AddressIterator) (void *cls,
137 const char *tname,
138 struct GNUNET_TIME_Absolute expiration,
139 const void *addr, size_t addrlen);
140
141
142/**
143 * Iterate over all of the addresses in the HELLO.
144 *
145 * @param msg HELLO to iterate over; client does not need to
146 * have verified that msg is well-formed (beyond starting
147 * with a GNUNET_MessageHeader of the right type).
148 * @param return_modified if a modified copy should be returned,
149 * otherwise NULL will be returned
150 * @param it iterator to call on each address
151 * @param it_cls closure for it
152 */
153struct GNUNET_HELLO_Message *GNUNET_HELLO_iterate_addresses (const struct
154 GNUNET_HELLO_Message
155 *msg,
156 int
157 return_modified,
158 GNUNET_HELLO_AddressIterator
159 it,
160 void *it_cls);
161
162
163/**
164 * Iterate over addresses in "new_hello" that
165 * are NOT already present in "old_hello".
166 *
167 * @param new_hello a HELLO message
168 * @param old_hello a HELLO message
169 * @param expiration_limit ignore addresses in old_hello
170 * that expired before the given time stamp
171 * @param it iterator to call on each address
172 * @param it_cls closure for it
173 */
174void
175GNUNET_HELLO_iterate_new_addresses (const struct GNUNET_HELLO_Message
176 *new_hello,
177 const struct GNUNET_HELLO_Message
178 *old_hello,
179 struct GNUNET_TIME_Absolute
180 expiration_limit,
181 GNUNET_HELLO_AddressIterator it,
182 void *it_cls);
183
184
185/**
186 * Get the public key from a HELLO message.
187 *
188 * @param hello the hello message
189 * @param publicKey where to copy the public key information, can be NULL
190 * @return GNUNET_SYSERR if the HELLO was malformed
191 */
192int
193GNUNET_HELLO_get_key (const struct GNUNET_HELLO_Message *hello,
194 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
195 *publicKey);
196
197
198
199/* ifndef GNUNET_HELLO_LIB_H */
200#endif
201/* end of gnunet_hello_lib.h */
diff --git a/src/include/gnunet_network_lib.h b/src/include/gnunet_network_lib.h
new file mode 100644
index 000000000..8731eacec
--- /dev/null
+++ b/src/include/gnunet_network_lib.h
@@ -0,0 +1,308 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 include/gnunet_network_lib.h
23 * @brief basic, low-level TCP networking interface
24 * @author Christian Grothoff
25 */
26#ifndef GNUNET_NETWORK_LIB_H
27#define GNUNET_NETWORK_LIB_H
28
29#ifdef __cplusplus
30extern "C"
31{
32#if 0 /* keep Emacsens' auto-indent happy */
33}
34#endif
35#endif
36
37#include "gnunet_scheduler_lib.h"
38#include "gnunet_time_lib.h"
39
40/**
41 * Timeout we use on TCP connect before trying another
42 * result from the DNS resolver. 5s.
43 */
44#define GNUNET_NETWORK_CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
45
46/**
47 * @brief handle for a network socket
48 */
49struct GNUNET_NETWORK_SocketHandle;
50
51
52/**
53 * Function to call for access control checks.
54 *
55 * @param cls closure
56 * @param addr address
57 * @param addrlen length of address
58 * @return GNUNET_YES to allow, GNUNET_NO to deny, GNUNET_SYSERR
59 * for unknown address family (will be denied).
60 */
61typedef int (*GNUNET_NETWORK_AccessCheck) (void *cls,
62 const struct sockaddr * addr,
63 socklen_t addrlen);
64
65
66/**
67 * Callback function for data received from the network. Note that
68 * both "available" and "err" would be 0 if the read simply timed out.
69 *
70 * @param cls closure
71 * @param buf pointer to received data
72 * @param available number of bytes availabe in "buf",
73 * possibly 0 (on errors)
74 * @param addr address of the sender
75 * @param addrlen size of addr
76 * @param errCode value of errno (on errors receiving)
77 */
78typedef void (*GNUNET_NETWORK_Receiver) (void *cls,
79 const void *buf,
80 size_t available,
81 const struct sockaddr * addr,
82 socklen_t addrlen, int errCode);
83
84
85/**
86 * Create a socket handle by boxing an existing OS socket. The OS
87 * socket should henceforth be no longer used directly.
88 * GNUNET_socket_destroy will close it.
89 *
90 * @param sched scheduler to use
91 * @param osSocket existing socket to box
92 * @param maxbuf maximum write buffer size for the socket (use
93 * 0 for sockets that need no write buffers, such as listen sockets)
94 * @return the boxed socket handle
95 */
96struct GNUNET_NETWORK_SocketHandle
97 *GNUNET_NETWORK_socket_create_from_existing (struct GNUNET_SCHEDULER_Handle
98 *sched, int osSocket,
99 size_t maxbuf);
100
101
102/**
103 * Create a socket handle by accepting on a listen socket. This
104 * function may block if the listen socket has no connection ready.
105 *
106 * @param sched scheduler to use
107 * @param access function to use to check if access is allowed
108 * @param access_cls closure for access
109 * @param lsock listen socket
110 * @param maxbuf maximum write buffer size for the socket (use
111 * 0 for sockets that need no write buffers, such as listen sockets)
112 * @return the socket handle, NULL on error (for example, access refused)
113 */
114struct GNUNET_NETWORK_SocketHandle
115 *GNUNET_NETWORK_socket_create_from_accept (struct GNUNET_SCHEDULER_Handle
116 *sched,
117 GNUNET_NETWORK_AccessCheck
118 access, void *access_cls,
119 int lsock, size_t maxbuf);
120
121
122/**
123 * Create a socket handle by (asynchronously) connecting to a host.
124 * This function returns immediately, even if the connection has not
125 * yet been established. This function only creates TCP connections.
126 *
127 * @param sched scheduler to use
128 * @param hostname name of the host to connect to
129 * @param port port to connect to
130 * @param maxbuf maximum write buffer size for the socket (use
131 * 0 for sockets that need no write buffers, such as listen sockets)
132 * @return the socket handle
133 */
134struct GNUNET_NETWORK_SocketHandle
135 *GNUNET_NETWORK_socket_create_from_connect (struct GNUNET_SCHEDULER_Handle
136 *sched, const char *hostname,
137 uint16_t port, size_t maxbuf);
138
139
140
141/**
142 * Create a socket handle by (asynchronously) connecting to a host.
143 * This function returns immediately, even if the connection has not
144 * yet been established. This function only creates TCP connections.
145 *
146 * @param sched scheduler to use
147 * @param af_family address family to use
148 * @param serv_addr server address
149 * @param addrlen length of server address
150 * @param maxbuf maximum write buffer size for the socket (use
151 * 0 for sockets that need no write buffers, such as listen sockets)
152 * @return the socket handle
153 */
154struct GNUNET_NETWORK_SocketHandle
155 *GNUNET_NETWORK_socket_create_from_sockaddr (struct GNUNET_SCHEDULER_Handle
156 *sched, int af_family,
157 const struct sockaddr
158 *serv_addr, socklen_t addrlen,
159 size_t maxbuf);
160
161/**
162 * Check if socket is valid (no fatal errors have happened so far).
163 * Note that a socket that is still trying to connect is considered
164 * valid.
165 *
166 * @param sock socket to check
167 * @return GNUNET_YES if valid, GNUNET_NO otherwise
168 */
169int GNUNET_NETWORK_socket_check (struct GNUNET_NETWORK_SocketHandle *sock);
170
171
172/**
173 * Obtain the network address of the other party.
174 *
175 * @param sock the client to get the address for
176 * @param addr where to store the address
177 * @param addrlen where to store the length of the address
178 * @return GNUNET_OK on success
179 */
180int GNUNET_NETWORK_socket_get_address (struct GNUNET_NETWORK_SocketHandle
181 *sock, void **addr, size_t * addrlen);
182
183/**
184 * Close the socket and free associated resources. Pending
185 * transmissions are simply dropped. A pending receive call will be
186 * called with an error code of "EPIPE".
187 *
188 * @param sock socket to destroy
189 */
190void GNUNET_NETWORK_socket_destroy (struct GNUNET_NETWORK_SocketHandle *sock);
191
192
193/**
194 * Receive data from the given socket. Note that this function will
195 * call "receiver" asynchronously using the scheduler. It will
196 * "immediately" return. Note that there MUST only be one active
197 * receive call per socket at any given point in time (so do not
198 * call receive again until the receiver callback has been invoked).
199 *
200 * @param sock socket handle
201 * @param max maximum number of bytes to read
202 * @param timeout maximum amount of time to wait
203 * @param receiver function to call with received data
204 * @param receiver_cls closure for receiver
205 * @return scheduler task ID used for receiving, GNUNET_SCHEDULER_NO_PREREQUISITE_TASK on error
206 */
207GNUNET_SCHEDULER_TaskIdentifier
208GNUNET_NETWORK_receive (struct GNUNET_NETWORK_SocketHandle *sock,
209 size_t max,
210 struct GNUNET_TIME_Relative timeout,
211 GNUNET_NETWORK_Receiver receiver, void *receiver_cls);
212
213
214/**
215 * Cancel receive job on the given socket. Note that the
216 * receiver callback must not have been called yet in order
217 * for the cancellation to be valid.
218 *
219 * @param sock socket handle
220 * @param task task identifier returned from the receive call
221 * @return closure of the original receiver callback
222 */
223void *GNUNET_NETWORK_receive_cancel (struct GNUNET_NETWORK_SocketHandle *sock,
224 GNUNET_SCHEDULER_TaskIdentifier task);
225
226
227/**
228 * Function called to notify a client about the socket
229 * begin ready to queue more data. "buf" will be
230 * NULL and "size" zero if the socket was closed for
231 * writing in the meantime.
232 *
233 * @param cls closure
234 * @param size number of bytes available in buf
235 * @param buf where the callee should write the message
236 * @return number of bytes written to buf
237 */
238typedef size_t (*GNUNET_NETWORK_TransmitReadyNotify) (void *cls,
239 size_t size, void *buf);
240
241
242/**
243 * Opaque handle that can be used to cancel
244 * a transmit-ready notification.
245 */
246struct GNUNET_NETWORK_TransmitHandle;
247
248/**
249 * Ask the socket to call us once the specified number of bytes
250 * are free in the transmission buffer. May call the notify
251 * method immediately if enough space is available. Note that
252 * this function will abort if "size" is greater than
253 * "maxbuf" (as specified when the socket handle was created).
254 *
255 * Note that "notify" will be called either when enough
256 * buffer space is available OR when the socket is destroyed.
257 * The size parameter given to notify is guaranteed to be
258 * larger or equal to size if the buffer is ready, or zero
259 * if the socket was destroyed (or at least closed for
260 * writing). Finally, any time before 'notify' is called, a
261 * client may call "notify_transmit_ready_cancel" to cancel
262 * the transmission request.
263 *
264 * Only one transmission request can be scheduled at the same
265 * time. Notify will be run with the same scheduler priority
266 * as that of the caller.
267 *
268 * @param sock socket
269 * @param size number of bytes to send
270 * @param timeout after how long should we give up (and call
271 * notify with buf NULL and size 0)?
272 * @param notify function to call when buffer space is available
273 * @param notify_cls closure for notify
274 * @return non-NULL if the notify callback was queued,
275 * NULL if we are already going to notify someone else (busy)
276 */
277struct GNUNET_NETWORK_TransmitHandle
278 *GNUNET_NETWORK_notify_transmit_ready (struct GNUNET_NETWORK_SocketHandle
279 *sock, size_t size,
280 struct GNUNET_TIME_Relative timeout,
281 GNUNET_NETWORK_TransmitReadyNotify
282 notify, void *notify_cls);
283
284
285/**
286 * Cancel the specified transmission-ready
287 * notification.
288 *
289 * @param h handle for notification to cancel
290 */
291void
292GNUNET_NETWORK_notify_transmit_ready_cancel (struct
293 GNUNET_NETWORK_TransmitHandle
294 *h);
295
296
297
298#if 0 /* keep Emacsens' auto-indent happy */
299{
300#endif
301#ifdef __cplusplus
302}
303#endif
304
305
306/* ifndef GNUNET_NETWORK_LIB_H */
307#endif
308/* end of gnunet_network_lib.h */
diff --git a/src/include/gnunet_os_lib.h b/src/include/gnunet_os_lib.h
new file mode 100644
index 000000000..dfab4a747
--- /dev/null
+++ b/src/include/gnunet_os_lib.h
@@ -0,0 +1,158 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006 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 2, 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 include/gnunet_os_lib.h
23 * @brief low level process routines
24 * @author Christian Grothoff
25 * @author Krista Bennett
26 * @author Gerd Knorr <kraxel@bytesex.org>
27 * @author Ioana Patrascu
28 * @author Tzvetan Horozov
29 * @author Milan
30 */
31
32#ifndef GNUNET_OS_LIB_H
33#define GNUNET_OS_LIB_H
34
35#ifdef __cplusplus
36extern "C"
37{
38#if 0 /* keep Emacsens' auto-indent happy */
39}
40#endif
41#endif
42
43#include "gnunet_common.h"
44#include "gnunet_configuration_lib.h"
45#include "gnunet_scheduler_lib.h"
46
47
48/**
49 * Possible installation paths to request
50 */
51enum GNUNET_OS_InstallationPathKind
52{
53 GNUNET_OS_IPK_PREFIX,
54 GNUNET_OS_IPK_BINDIR,
55 GNUNET_OS_IPK_LIBDIR,
56 GNUNET_OS_IPK_DATADIR,
57 GNUNET_OS_IPK_LOCALEDIR,
58 GNUNET_OS_IPK_SELF_PREFIX
59};
60
61
62/**
63 * Get the path to a specific GNUnet installation directory or, with
64 * GNUNET_OS_IPK_SELF_PREFIX, the current running apps installation
65 * directory.
66 *
67 * @param dirkind what kind of directory is desired?
68 * @return a pointer to the dir path (to be freed by the caller)
69 */
70char *GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind
71 dirkind);
72
73
74/**
75 * Callback function invoked for each interface found.
76 *
77 * @param cls closure
78 * @param name name of the interface (can be NULL for unknown)
79 * @param isDefault is this presumably the default interface
80 * @param addr address of this interface (can be NULL for unknown or unassigned)
81 * @param addrlen length of the address
82 * @return GNUNET_OK to continue iteration, GNUNET_SYSERR to abort
83 */
84typedef int (*GNUNET_OS_NetworkInterfaceProcessor) (void *cls,
85 const char *name,
86 int isDefault,
87 const struct sockaddr *
88 addr, socklen_t addrlen);
89
90
91/**
92 * @brief Enumerate all network interfaces
93 * @param callback the callback function
94 */
95void GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor
96 proc, void *cls);
97
98/**
99 * Get the current CPU load.
100 *
101 * @param cfg to determine acceptable load level (LOAD::MAXCPULOAD)
102 * @return -1 on error, otherwise load value (between 0 and 100,
103 * (100 is equivalent to full load for one CPU)
104 */
105int GNUNET_OS_load_cpu_get (struct GNUNET_CONFIGURATION_Handle *cfg);
106
107/**
108 * Get the current IO load.
109 *
110 * @param cfg to determine acceptable load level (LOAD::MAXIOLOAD)
111 * @return -1 on error, otherwise load value (between 0 and 100,
112 * 100 means that we spend all of our cycles waiting for
113 * the disk)
114 */
115int GNUNET_OS_load_disk_get (struct GNUNET_CONFIGURATION_Handle *cfg);
116
117
118/**
119 * Set process priority
120 *
121 * @param proc id of the process
122 * @param prio priority value
123 * @return GNUNET_OK on success, GNUNET_SYSERR on error
124 */
125int GNUNET_OS_set_process_priority (pid_t proc,
126 enum GNUNET_SCHEDULER_Priority prio);
127
128
129/**
130 * Start a process.
131 *
132 * @param filename name of the binary
133 * @param ... NULL-terminated list of arguments to the process
134 * @return process ID of the new process, -1 on error
135 */
136pid_t GNUNET_OS_start_process (const char *filename, ...);
137
138/**
139 * Start a process.
140 *
141 * @param filename name of the binary
142 * @param argv NULL-terminated list of arguments to the process,
143 * including the process name as the first argument
144 * @return process ID of the new process, -1 on error
145 */
146pid_t GNUNET_OS_start_process_v (const char *filename, char *const argv[]);
147
148#if 0 /* keep Emacsens' auto-indent happy */
149{
150#endif
151#ifdef __cplusplus
152}
153#endif
154
155
156/* ifndef GNUNET_OS_LIB_H */
157#endif
158/* end of gnunet_os_lib.h */
diff --git a/src/include/gnunet_peerinfo_service.h b/src/include/gnunet_peerinfo_service.h
new file mode 100644
index 000000000..45c52c447
--- /dev/null
+++ b/src/include/gnunet_peerinfo_service.h
@@ -0,0 +1,111 @@
1/*
2 This file is part of GNUnet
3 (C) 2009 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 2, 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 include/gnunet_peerinfo_service.h
22 * @brief Code to maintain the list of currently known hosts
23 * (in memory structure of data/hosts) and their trust ratings
24 * (in memory structure of data/trust)
25 * @author Christian Grothoff
26 */
27
28#ifndef GNUNET_PEERINFO_SERVICE_H
29#define GNUNET_PEERINFO_SERVICE_H
30
31#include "gnunet_common.h"
32#include "gnunet_configuration_lib.h"
33#include "gnunet_crypto_lib.h"
34#include "gnunet_hello_lib.h"
35
36#ifdef __cplusplus
37extern "C"
38{
39#if 0 /* keep Emacsens' auto-indent happy */
40}
41#endif
42#endif
43
44
45/**
46 * Add a host to the persistent list.
47 *
48 * @param cfg configuration to use
49 * @param sched scheduler to use
50 * @param peer identity of the peer
51 * @param hello the verified (!) HELLO message
52 */
53void
54GNUNET_PEERINFO_add_peer (struct GNUNET_CONFIGURATION_Handle *cfg,
55 struct GNUNET_SCHEDULER_Handle *sched,
56 const struct GNUNET_PeerIdentity *peer,
57 const struct GNUNET_HELLO_Message *hello);
58
59/**
60 * Type of an iterator over the hosts. Note that each
61 * host will be called with each available protocol.
62 *
63 * @param cls closure
64 * @param peer id of the peer, NULL for last call
65 * @param hello hello message for the peer (can be NULL)
66 * @param trust amount of trust we have in the peer
67 */
68typedef void
69 (*GNUNET_PEERINFO_Processor) (void *cls,
70 const struct GNUNET_PeerIdentity * peer,
71 const struct GNUNET_HELLO_Message * hello,
72 uint32_t trust);
73
74
75/**
76 * Call a method for each known matching host and change
77 * its trust value. The method will be invoked once for
78 * each host and then finally once with a NULL pointer.
79 * Note that the last call can be triggered by timeout or
80 * by simply being done; however, the trust argument will
81 * be set to zero if we are done, 1 if we timed out and
82 * 2 for fatal error.
83 *
84 * @param cfg configuration to use
85 * @param sched scheduler to use
86 * @param peer restrict iteration to this peer only (can be NULL)
87 * @param trust_delta how much to change the trust in all matching peers
88 * @param timeout how long to wait until timing out
89 * @param callback the method to call for each peer
90 * @param callback_cls closure for callback
91 */
92void
93GNUNET_PEERINFO_for_all (struct GNUNET_CONFIGURATION_Handle *cfg,
94 struct GNUNET_SCHEDULER_Handle *sched,
95 const struct GNUNET_PeerIdentity *peer,
96 int trust_delta,
97 struct GNUNET_TIME_Relative timeout,
98 GNUNET_PEERINFO_Processor callback,
99 void *callback_cls);
100
101
102#if 0 /* keep Emacsens' auto-indent happy */
103{
104#endif
105#ifdef __cplusplus
106}
107#endif
108
109
110/* end of gnunet_peerinfo_service.h */
111#endif
diff --git a/src/include/gnunet_plugin_lib.h b/src/include/gnunet_plugin_lib.h
new file mode 100644
index 000000000..e4f603c4e
--- /dev/null
+++ b/src/include/gnunet_plugin_lib.h
@@ -0,0 +1,84 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006 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 2, 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 include/gnunet_plugin_lib.h
23 * @brief plugin loading and unloading
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_PLUGIN_LIB_H
28#define GNUNET_PLUGIN_LIB_H
29
30#ifdef __cplusplus
31extern "C"
32{
33#if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38#include "gnunet_common.h"
39#include "gnunet_configuration_lib.h"
40
41
42/**
43 * Signature of any function exported by a plugin.
44 */
45typedef void *(*GNUNET_PLUGIN_Callback) (void *arg);
46
47
48/**
49 * Setup plugin (runs the "init" callback and returns whatever "init"
50 * returned). If "init" returns NULL, the plugin is unloaded.
51 *
52 * Note that the library must export symbols called
53 * "library_name_init" and "library_name_done". These will be called
54 * when the library is loaded and unloaded respectively.
55 *
56 * @param library_name name of the plugin to load
57 * @param arg argument to the plugin initialization function
58 * @return whatever the initialization function returned
59 */
60void *GNUNET_PLUGIN_load (const char *library_name, void *arg);
61
62
63/**
64 * Unload plugin (runs the "done" callback and returns whatever "done"
65 * returned). The plugin is then unloaded.
66 *
67 * @param library_name name of the plugin to unload
68 * @param arg argument to the plugin shutdown function
69 * @return whatever the shutdown function returned
70 */
71void *GNUNET_PLUGIN_unload (const char *library_name, void *arg);
72
73
74#if 0 /* keep Emacsens' auto-indent happy */
75{
76#endif
77#ifdef __cplusplus
78}
79#endif
80
81
82/* ifndef GNUNET_PLUGIN_LIB_H */
83#endif
84/* end of gnunet_plugin_lib.h */
diff --git a/src/include/gnunet_program_lib.h b/src/include/gnunet_program_lib.h
new file mode 100644
index 000000000..fcd00b8ef
--- /dev/null
+++ b/src/include/gnunet_program_lib.h
@@ -0,0 +1,90 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 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 2, 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 include/gnunet_program_lib.h
23 * @brief functions related to starting programs
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_PROGRAM_LIB_H
28#define GNUNET_PROGRAM_LIB_H
29
30#ifdef __cplusplus
31extern "C"
32{
33#if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38#include "gnunet_configuration_lib.h"
39#include "gnunet_getopt_lib.h"
40#include "gnunet_scheduler_lib.h"
41
42/**
43 * Main function that will be run.
44 *
45 * @param cls closure
46 * @param sched the scheduler to use
47 * @param args remaining command-line arguments
48 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
49 * @param cfg configuration
50 */
51typedef void (*GNUNET_PROGRAM_Main) (void *cls,
52 struct GNUNET_SCHEDULER_Handle * sched,
53 char *const *args,
54 const char *cfgfile,
55 struct GNUNET_CONFIGURATION_Handle *
56 cfg);
57
58
59/**
60 * Run a standard GNUnet command startup sequence (initialize loggers
61 * and configuration, parse options).
62 *
63 * @param argc number of command line arguments
64 * @param argv command line arguments
65 * @param binaryName our expected name
66 * @param binaryHelp helptext for "-h" option (about the app)
67 * @param options command line options
68 * @param task main function to run
69 * @param task_cls closure for task
70 * @return GNUNET_SYSERR on error, GNUNET_OK on success
71 */
72int GNUNET_PROGRAM_run (int argc,
73 char *const *argv,
74 const char *binaryName,
75 const char *binaryHelp,
76 const struct GNUNET_GETOPT_CommandLineOption *options,
77 GNUNET_PROGRAM_Main task, void *task_cls);
78
79
80
81#if 0 /* keep Emacsens' auto-indent happy */
82{
83#endif
84#ifdef __cplusplus
85}
86#endif
87
88/* ifndef GNUNET_PROGRAM_LIB_H */
89#endif
90/* end of gnunet_program_lib.h */
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
new file mode 100644
index 000000000..c86ad83ce
--- /dev/null
+++ b/src/include/gnunet_protocols.h
@@ -0,0 +1,319 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 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 2, 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 include/gnunet_protocols.h
23 * @brief constants for network protocols
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_PROTOCOLS_H
28#define GNUNET_PROTOCOLS_H
29
30#ifdef __cplusplus
31extern "C"
32{
33#if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38/**
39 * Test if service is online.
40 */
41#define GNUNET_MESSAGE_TYPE_TEST 0
42
43/**
44 * Request service shutdown.
45 */
46#define GNUNET_MESSAGE_TYPE_SHUTDOWN 1
47
48
49/**
50 * Request DNS resolution.
51 */
52#define GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST 2
53
54/**
55 * Response to a DNS resolution request.
56 */
57#define GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE 3
58
59
60/**
61 * Set a statistical value.
62 */
63#define GNUNET_MESSAGE_TYPE_STATISTICS_SET 4
64
65/**
66 * Get a statistical value(s).
67 */
68#define GNUNET_MESSAGE_TYPE_STATISTICS_GET 5
69
70/**
71 * Response to a STATISTICS_GET message (with value).
72 */
73#define GNUNET_MESSAGE_TYPE_STATISTICS_VALUE 6
74
75/**
76 * Response to a STATISTICS_GET message (end of value stream).
77 */
78#define GNUNET_MESSAGE_TYPE_STATISTICS_END 7
79
80
81/**
82 * Request to ARM to start a service.
83 */
84#define GNUNET_MESSAGE_TYPE_ARM_START 8
85
86/**
87 * Request to ARM to stop a service.
88 */
89#define GNUNET_MESSAGE_TYPE_ARM_STOP 9
90
91/**
92 * Response from ARM: service is now up.
93 */
94#define GNUNET_MESSAGE_TYPE_ARM_IS_UP 10
95
96/**
97 * Response from ARM: service is now down.
98 * (failed to start it).
99 */
100#define GNUNET_MESSAGE_TYPE_ARM_IS_DOWN 11
101
102
103/**
104 * HELLO message used for communicating peer addresses.
105 * Managed by libgnunethello.
106 */
107#define GNUNET_MESSAGE_TYPE_HELLO 16
108
109/**
110 * FRAGMENT of a larger message.
111 * Managed by libgnunetfragment.
112 */
113#define GNUNET_MESSAGE_TYPE_FRAGMENT 18
114
115
116/**
117 * Message from the core saying that the transport
118 * server should start giving it messages. This
119 * should automatically trigger the transmission of
120 * a HELLO message.
121 */
122#define GNUNET_MESSAGE_TYPE_TRANSPORT_START 20
123
124/**
125 * Message from TRANSPORT notifying about a
126 * client that connected to us.
127 */
128#define GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT 21
129
130/**
131 * Message from TRANSPORT notifying about a
132 * client that disconnected from us.
133 */
134#define GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT 22
135
136/**
137 * Request to TRANSPORT to transmit a message.
138 */
139#define GNUNET_MESSAGE_TYPE_TRANSPORT_SEND 23
140
141/**
142 * Confirmation from TRANSPORT that message for
143 * transmission has been queued (and that the next
144 * message to this peer can now be passed to the
145 * service). Note that this confirmation does NOT
146 * imply that the message was fully transmitted.
147 */
148#define GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK 24
149
150/**
151 * Message from TRANSPORT notifying about a
152 * message that was received.
153 */
154#define GNUNET_MESSAGE_TYPE_TRANSPORT_RECV 25
155
156/**
157 * Message telling transport to limit its receive rate.
158 */
159#define GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA 26
160
161/**
162 * Message telling transport to try to connect to the
163 * given peer.
164 */
165#define GNUNET_MESSAGE_TYPE_TRANSPORT_TRY_CONNECT 27
166
167/**
168 * Request to other peer to confirm receipt.
169 */
170#define GNUNET_MESSAGE_TYPE_TRANSPORT_PING 28
171
172/**
173 * Message from other peer confirming receipt.
174 */
175#define GNUNET_MESSAGE_TYPE_TRANSPORT_PONG 29
176
177/**
178 * Response to another peer confirming that communication was
179 * established.
180 */
181#define GNUNET_MESSAGE_TYPE_TRANSPORT_ACK 30
182
183
184/**
185 * Request addition of a HELLO
186 */
187#define GNUNET_MESSAGE_TYPE_PEERINFO_ADD 32
188
189/**
190 * Request update and listing of a peer.
191 */
192#define GNUNET_MESSAGE_TYPE_PEERINFO_GET 33
193
194/**
195 * Request update and listing of all peers.
196 */
197#define GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL 34
198
199/**
200 * Information about one of the peers.
201 */
202#define GNUNET_MESSAGE_TYPE_PEERINFO_INFO 35
203
204/**
205 * End of information about other peers.
206 */
207#define GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END 36
208
209
210/**
211 * Welcome message between TCP transports.
212 */
213#define GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME 40
214
215/**
216 * Data message between TCP transports.
217 */
218#define GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_DATA 41
219
220
221/**
222 * Initial setup message from core client to core.
223 */
224#define GNUNET_MESSAGE_TYPE_CORE_INIT 64
225
226/**
227 * Response from core to core client to INIT message.
228 */
229#define GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY 65
230
231/**
232 * Notify clients about new peer-to-peer connections.
233 */
234#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT 66
235
236/**
237 * Notify clients about peer disconnecting.
238 */
239#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT 67
240
241/**
242 * Notify clients about incoming P2P messages.
243 */
244#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND 68
245
246/**
247 * Notify clients about outgoing P2P transmissions.
248 */
249#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND 69
250
251/**
252 * Request from client to "configure" P2P connection.
253 */
254#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONFIGURE 70
255
256/**
257 * Response from server about (possibly updated) P2P
258 * connection configuration.
259 */
260#define GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO 71
261
262/**
263 * Solicitation from server for transmission (may have
264 * been requested or also be transmitted without
265 * client's request).
266 */
267#define GNUNET_MESSAGE_TYPE_CORE_SOLICIT_TRAFFIC 72
268
269/**
270 * Response from client with message to transmit.
271 */
272#define GNUNET_MESSAGE_TYPE_CORE_SEND 73
273
274
275/**
276 * Session key exchange between peers.
277 */
278#define GNUNET_MESSAGE_TYPE_CORE_SET_KEY 80
279
280/**
281 * Encapsulation for an encrypted message between peers.
282 */
283#define GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE 81
284
285/**
286 * Check that other peer is alife (challenge).
287 */
288#define GNUNET_MESSAGE_TYPE_CORE_PING 82
289
290/**
291 * Confirmation that other peer is alife.
292 */
293#define GNUNET_MESSAGE_TYPE_CORE_PONG 83
294
295/**
296 * Request by the other peer to terminate the connection.
297 */
298#define GNUNET_MESSAGE_TYPE_CORE_HANGUP 84
299
300
301/*
302 TODO:
303 - DV
304 - DHT
305 - datastores
306 - applications (FS, VPN, CHAT, TRACEKIT, TBENCH)
307*/
308
309
310#if 0 /* keep Emacsens' auto-indent happy */
311{
312#endif
313#ifdef __cplusplus
314}
315#endif
316
317/* ifndef GNUNET_PROTOCOLS_H */
318#endif
319/* end of gnunet_protocols.h */
diff --git a/src/include/gnunet_pseudonym_lib.h b/src/include/gnunet_pseudonym_lib.h
new file mode 100644
index 000000000..0ee9ce7ac
--- /dev/null
+++ b/src/include/gnunet_pseudonym_lib.h
@@ -0,0 +1,125 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 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 2, 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 include/gnunet_pseudonym_lib.h
23 * @brief functions related to pseudonyms
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_PSEUDONYM_LIB_H
28#define GNUNET_PSEUDONYM_LIB_H
29
30#ifdef __cplusplus
31extern "C"
32{
33#if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38#include "gnunet_common.h"
39#include "gnunet_configuration_lib.h"
40#include "gnunet_container_lib.h"
41
42/**
43 * Iterator over all known pseudonyms.
44 *
45 * @param rating the local rating of the pseudonym
46 * @return GNUNET_OK to continue iteration, GNUNET_SYSERR to abort
47 */
48typedef int (*GNUNET_PSEUDONYM_Iterator) (void *cls,
49 const GNUNET_HashCode *
50 pseudonym,
51 const struct
52 GNUNET_CONTAINER_MetaData * md,
53 int rating);
54
55/**
56 * Change the ranking of a pseudonym.
57 *
58 * @param pseudonym id of the pseudonym
59 * @param delta by how much should the rating be changed?
60 * @return new rating of the namespace
61 */
62int GNUNET_PSEUDONYM_rank (struct GNUNET_CONFIGURATION_Handle *cfg,
63 const GNUNET_HashCode * pseudonym, int delta);
64
65/**
66 * Add a pseudonym to the set of known pseudonyms.
67 *
68 * @param pseudonym the pseudonym's identifier
69 */
70void GNUNET_PSEUDONYM_add (struct GNUNET_CONFIGURATION_Handle *cfg,
71 const GNUNET_HashCode * pseudo,
72 const struct GNUNET_CONTAINER_MetaData *meta);
73
74
75/**
76 * List all known pseudonyms.
77 */
78int GNUNET_PSEUDONYM_list_all (struct GNUNET_CONFIGURATION_Handle *cfg,
79 GNUNET_PSEUDONYM_Iterator iterator,
80 void *closure);
81
82/**
83 * Register callback to be invoked whenever we discover
84 * a new pseudonym.
85 */
86int GNUNET_PSEUDONYM_discovery_callback_register (struct
87 GNUNET_CONFIGURATION_Handle
88 *cfg,
89 GNUNET_PSEUDONYM_Iterator
90 iterator, void *closure);
91
92/**
93 * Unregister namespace discovery callback.
94 */
95int
96GNUNET_PSEUDONYM_discovery_callback_unregister (GNUNET_PSEUDONYM_Iterator
97 iterator, void *closure);
98
99/**
100 * Return the unique, human readable name for the given pseudonym.
101 *
102 * @return NULL on failure (should never happen)
103 */
104char *GNUNET_PSEUDONYM_id_to_name (struct GNUNET_CONFIGURATION_Handle *cfg,
105 const GNUNET_HashCode * pseudo);
106
107/**
108 * Get the pseudonym ID belonging to the given human readable name.
109 *
110 * @return GNUNET_OK on success
111 */
112int GNUNET_PSEUDONYM_name_to_id (struct GNUNET_CONFIGURATION_Handle *cfg,
113 const char *hname, GNUNET_HashCode * psid);
114
115
116#if 0 /* keep Emacsens' auto-indent happy */
117{
118#endif
119#ifdef __cplusplus
120}
121#endif
122
123/* ifndef GNUNET_PSEUDONYM_LIB_H */
124#endif
125/* end of gnunet_pseudonym_lib.h */
diff --git a/src/include/gnunet_resolver_service.h b/src/include/gnunet_resolver_service.h
new file mode 100644
index 000000000..ac7aebcc7
--- /dev/null
+++ b/src/include/gnunet_resolver_service.h
@@ -0,0 +1,135 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 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 2, 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 include/gnunet_resolver_service.h
23 * @brief functions related to doing DNS lookups
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_RESOLVER_SERVICE_H
28#define GNUNET_RESOLVER_SERVICE_H
29
30#ifdef __cplusplus
31extern "C"
32{
33#if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38#include "gnunet_configuration_lib.h"
39#include "gnunet_scheduler_lib.h"
40#include "gnunet_time_lib.h"
41
42
43/**
44 * Function called by the resolver for each address obtained from DNS.
45 *
46 * @param cls closure
47 * @param addr one of the addresses of the host, NULL for the last address
48 * @param addrlen length of the address
49 */
50typedef void (*GNUNET_RESOLVER_AddressCallback) (void *cls,
51 const struct sockaddr * addr,
52 socklen_t addrlen);
53
54
55/**
56 * Convert a string to one or more IP addresses.
57 *
58 * @param sched scheduler to use
59 * @param cfg configuration to use
60 * @param hostname the hostname to resolve
61 * @param domain AF_INET or AF_INET6; use AF_UNSPEC for "any"
62 * @param callback function to call with addresses
63 * @param cls closure for callback
64 * @param timeout how long to try resolving
65 */
66void
67GNUNET_RESOLVER_ip_get (struct GNUNET_SCHEDULER_Handle *sched,
68 struct GNUNET_CONFIGURATION_Handle *cfg,
69 const char *hostname,
70 int domain,
71 struct GNUNET_TIME_Relative timeout,
72 GNUNET_RESOLVER_AddressCallback callback, void *cls);
73
74
75/**
76 * Resolve our hostname to an IP address.
77 *
78 * @param sched scheduler to use
79 * @param cfg configuration to use
80 * @param domain AF_INET or AF_INET6; use AF_UNSPEC for "any"
81 * @param callback function to call with addresses
82 * @param cls closure for callback
83 * @param timeout how long to try resolving
84 */
85void
86GNUNET_RESOLVER_hostname_resolve (struct GNUNET_SCHEDULER_Handle *sched,
87 struct GNUNET_CONFIGURATION_Handle *cfg,
88 int domain,
89 struct GNUNET_TIME_Relative timeout,
90 GNUNET_RESOLVER_AddressCallback callback,
91 void *cls);
92
93
94/**
95 * Function called by the resolver for each hostname obtained from DNS.
96 *
97 * @param cls closure
98 * @param hostname one of the names for the host, NULL
99 * on the last call to the callback
100 */
101typedef void (*GNUNET_RESOLVER_HostnameCallback) (void *cls,
102 const char *hostname);
103
104
105/**
106 * Get an IP address as a string.
107 *
108 * @param sched scheduler to use
109 * @param cfg configuration to use
110 * @param sa host address
111 * @param salen length of host address
112 * @param do_resolve use GNUNET_NO to return numeric hostname
113 * @param timeout how long to try resolving
114 * @param callback function to call with hostnames
115 * @param cls closure for callback
116 */
117void GNUNET_RESOLVER_hostname_get (struct GNUNET_SCHEDULER_Handle *sched,
118 struct GNUNET_CONFIGURATION_Handle *cfg,
119 const struct sockaddr *sa,
120 socklen_t salen,
121 int do_resolve,
122 struct GNUNET_TIME_Relative timeout,
123 GNUNET_RESOLVER_HostnameCallback callback,
124 void *cls);
125
126#if 0 /* keep Emacsens' auto-indent happy */
127{
128#endif
129#ifdef __cplusplus
130}
131#endif
132
133/* ifndef GNUNET_RESOLVER_SERVICE_H */
134#endif
135/* end of gnunet_resolver_service.h */
diff --git a/src/include/gnunet_scheduler_lib.h b/src/include/gnunet_scheduler_lib.h
new file mode 100644
index 000000000..aa5830942
--- /dev/null
+++ b/src/include/gnunet_scheduler_lib.h
@@ -0,0 +1,442 @@
1/*
2 This file is part of GNUnet
3 (C) 2009 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 2, 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 include/gnunet_scheduler_lib.h
23 * @brief API to schedule computations using continuation passing style
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_SCHEDULER_LIB_H
28#define GNUNET_SCHEDULER_LIB_H
29
30#ifdef __cplusplus
31extern "C"
32{
33#if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38#include "gnunet_time_lib.h"
39
40
41/**
42 * Opaque handle for the scheduling service.
43 */
44struct GNUNET_SCHEDULER_Handle;
45
46
47/**
48 * Opaque reference to a task.
49 */
50typedef unsigned long long GNUNET_SCHEDULER_TaskIdentifier;
51
52
53/**
54 * Constant used to indicate that the scheduled
55 * task has no others as prerequisites.
56 */
57#define GNUNET_SCHEDULER_NO_PREREQUISITE_TASK ((GNUNET_SCHEDULER_TaskIdentifier) 0)
58
59/**
60 * Reasons why the schedule may have triggered
61 * the task now.
62 */
63enum GNUNET_SCHEDULER_Reason
64{
65 /**
66 * This is the very first task run during startup.
67 */
68 GNUNET_SCHEDULER_REASON_STARTUP = 0,
69
70 /**
71 * We are shutting down and are running all shutdown-related tasks
72 * (regardless of timeout, etc.).
73 */
74 GNUNET_SCHEDULER_REASON_SHUTDOWN = 1,
75
76 /**
77 * The specified timeout has expired.
78 * (also set if the delay given was 0).
79 */
80 GNUNET_SCHEDULER_REASON_TIMEOUT = 2,
81
82 /**
83 * The reading socket is ready.
84 */
85 GNUNET_SCHEDULER_REASON_READ_READY = 4,
86
87 /**
88 * The writing socket is ready.
89 */
90 GNUNET_SCHEDULER_REASON_WRITE_READY = 8,
91
92 /**
93 * The prerequisite task is done.
94 */
95 GNUNET_SCHEDULER_REASON_PREREQ_DONE = 16
96};
97
98
99/**
100 * Valid task priorities. Use these, do not
101 * pass random integers!
102 */
103enum GNUNET_SCHEDULER_Priority
104{
105 /**
106 * Run with the same priority as the current job.
107 */
108 GNUNET_SCHEDULER_PRIORITY_KEEP = 0,
109
110 /**
111 * Run when otherwise idle.
112 */
113 GNUNET_SCHEDULER_PRIORITY_IDLE = 1,
114
115 /**
116 * Run as background job (higher than idle,
117 * lower than default).
118 */
119 GNUNET_SCHEDULER_PRIORITY_BACKGROUND = 2,
120
121 /**
122 * Run with the default priority (normal
123 * P2P operations). Higher than BACKGROUND.
124 */
125 GNUNET_SCHEDULER_PRIORITY_DEFAULT = 3,
126
127 /**
128 * Run with high priority (important requests).
129 * Higher than DEFAULT.
130 */
131 GNUNET_SCHEDULER_PRIORITY_HIGH = 4,
132
133 /**
134 * Run with priority for interactive tasks.
135 * Higher than "HIGH".
136 */
137 GNUNET_SCHEDULER_PRIORITY_UI = 5,
138
139 /**
140 * Run with priority for urgent tasks. Use
141 * for things like aborts and shutdowns that
142 * need to preempt "UI"-level tasks.
143 * Higher than "UI".
144 */
145 GNUNET_SCHEDULER_PRIORITY_URGENT = 6,
146
147 /**
148 * Number of priorities (must be the last priority).
149 * This priority must not be used by clients.
150 */
151 GNUNET_SCHEDULER_PRIORITY_COUNT = 7
152};
153
154
155/**
156 * Context information passed to each scheduler task.
157 */
158struct GNUNET_SCHEDULER_TaskContext
159{
160
161 /**
162 * Scheduler running the task
163 */
164 struct GNUNET_SCHEDULER_Handle *sched;
165
166 /**
167 * Reason why the task is run now
168 */
169 enum GNUNET_SCHEDULER_Reason reason;
170
171 /**
172 * Set of file descriptors ready for reading;
173 * note that additional bits may be set
174 * that were not in the original request
175 */
176 const fd_set *read_ready;
177
178 /**
179 * Set of file descriptors ready for writing;
180 * note that additional bits may be set
181 * that were not in the original request.
182 */
183 const fd_set *write_ready;
184
185};
186
187
188/**
189 * Signature of the main function of a task.
190 *
191 * @param cls closure
192 * @param tc context information (why was this task triggered now)
193 */
194typedef void (*GNUNET_SCHEDULER_Task) (void *cls,
195 const struct
196 GNUNET_SCHEDULER_TaskContext * tc);
197
198
199/**
200 * Initialize and run scheduler. This function will return when
201 * either a shutdown was initiated (via signal) and all tasks marked
202 * to "run_on_shutdown" have been completed or when all tasks in
203 * general have been completed.
204 *
205 * @param task task to run immediately
206 * @param cls closure of task
207 */
208void GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *cls);
209
210
211/**
212 * Request the shutdown of a scheduler. This function can be used to
213 * stop a scheduler, for example from within the signal
214 * handler for signals causing shutdowns.
215 */
216void GNUNET_SCHEDULER_shutdown (struct GNUNET_SCHEDULER_Handle *sched);
217
218
219/**
220 * Get information about the current load of this scheduler. Use this
221 * function to determine if an elective task should be added or simply
222 * dropped (if the decision should be made based on the number of
223 * tasks ready to run).
224 *
225 * @param sched scheduler to query
226 * @param p priority-level to query, use KEEP to query the level
227 * of the current task, use COUNT to get the sum over
228 * all priority levels
229 * @return number of tasks pending right now
230 */
231unsigned int GNUNET_SCHEDULER_get_load (struct GNUNET_SCHEDULER_Handle *sched,
232 enum GNUNET_SCHEDULER_Priority p);
233
234
235/**
236 * Cancel the task with the specified identifier.
237 * The task must not yet have run.
238 *
239 * @param sched scheduler to use
240 * @param task id of the task to cancel
241 * @return the closure of the callback of the cancelled task
242 */
243void *GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Handle *sched,
244 GNUNET_SCHEDULER_TaskIdentifier task);
245
246
247/**
248 * Continue the current execution with the given function. This is
249 * similar to the other "add" functions except that there is no delay
250 * and the reason code can be specified.
251 *
252 * @param sched scheduler to use
253 * @param main main function of the task
254 * @param cls closure of task
255 * @param reason reason for task invocation
256 */
257void
258GNUNET_SCHEDULER_add_continuation (struct GNUNET_SCHEDULER_Handle *sched,
259 int run_on_shutdown,
260 GNUNET_SCHEDULER_Task main,
261 void *cls,
262 enum GNUNET_SCHEDULER_Reason reason);
263
264
265/**
266 * Schedule a new task to be run after the specified
267 * prerequisite task has completed.
268 *
269 * @param sched scheduler to use
270 * @param run_on_shutdown run on shutdown?
271 * @param prio how important is this task?
272 * @param prerequisite_task run this task after the task with the given
273 * task identifier completes (and any of our other
274 * conditions, such as delay, read or write-readyness
275 * are satisfied). Use GNUNET_SCHEDULER_NO_PREREQUISITE_TASK to not have any dependency
276 * on completion of other tasks.
277 * @param main main function of the task
278 * @param cls closure of task
279 * @return unique task identifier for the job
280 * only valid until "main" is started!
281 */
282GNUNET_SCHEDULER_TaskIdentifier
283GNUNET_SCHEDULER_add_after (struct GNUNET_SCHEDULER_Handle *sched,
284 int run_on_shutdown,
285 enum GNUNET_SCHEDULER_Priority prio,
286 GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
287 GNUNET_SCHEDULER_Task main, void *cls);
288
289
290/**
291 * Schedule a new task to be run with a specified delay. The task
292 * will be scheduled for execution once the delay has expired and the
293 * prerequisite task has completed.
294 *
295 * @param sched scheduler to use
296 * @param run_on_shutdown run on shutdown? You can use this
297 * argument to run a function only during shutdown
298 * by setting delay to -1. Set this
299 * argument to GNUNET_NO to skip this task if
300 * the user requested process termination.
301 * @param prio how important is this task?
302 * @param prerequisite_task run this task after the task with the given
303 * task identifier completes (and any of our other
304 * conditions, such as delay, read or write-readyness
305 * are satisfied). Use GNUNET_SCHEDULER_NO_PREREQUISITE_TASK to not have any dependency
306 * on completion of other tasks.
307 * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever"
308 * @param main main function of the task
309 * @param cls closure of task
310 * @return unique task identifier for the job
311 * only valid until "main" is started!
312 */
313GNUNET_SCHEDULER_TaskIdentifier
314GNUNET_SCHEDULER_add_delayed (struct GNUNET_SCHEDULER_Handle *sched,
315 int run_on_shutdown,
316 enum GNUNET_SCHEDULER_Priority prio,
317 GNUNET_SCHEDULER_TaskIdentifier
318 prerequisite_task,
319 struct GNUNET_TIME_Relative delay,
320 GNUNET_SCHEDULER_Task main, void *cls);
321
322
323/**
324 * Schedule a new task to be run with a specified delay or when the
325 * specified file descriptor is ready for reading. The delay can be
326 * used as a timeout on the socket being ready. The task will be
327 * scheduled for execution once either the delay has expired or the
328 * socket operation is ready.
329 *
330 * @param sched scheduler to use
331 * @param run_on_shutdown run on shutdown? Set this
332 * argument to GNUNET_NO to skip this task if
333 * the user requested process termination.
334 * @param prio how important is this task?
335 * @param prerequisite_task run this task after the task with the given
336 * task identifier completes (and any of our other
337 * conditions, such as delay, read or write-readyness
338 * are satisfied). Use GNUNET_SCHEDULER_NO_PREREQUISITE_TASK to not have any dependency
339 * on completion of other tasks.
340 * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever"
341 * @param rfd read file-descriptor
342 * @param main main function of the task
343 * @param cls closure of task
344 * @return unique task identifier for the job
345 * only valid until "main" is started!
346 */
347GNUNET_SCHEDULER_TaskIdentifier
348GNUNET_SCHEDULER_add_read (struct GNUNET_SCHEDULER_Handle *sched,
349 int run_on_shutdown,
350 enum GNUNET_SCHEDULER_Priority prio,
351 GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
352 struct GNUNET_TIME_Relative delay,
353 int rfd, GNUNET_SCHEDULER_Task main, void *cls);
354
355
356/**
357 * Schedule a new task to be run with a specified delay or when the
358 * specified file descriptor is ready for writing. The delay can be
359 * used as a timeout on the socket being ready. The task will be
360 * scheduled for execution once either the delay has expired or the
361 * socket operation is ready.
362 *
363 * @param sched scheduler to use
364 * @param run_on_shutdown run on shutdown? Set this
365 * argument to GNUNET_NO to skip this task if
366 * the user requested process termination.
367 * @param prio how important is this task?
368 * @param prerequisite_task run this task after the task with the given
369 * task identifier completes (and any of our other
370 * conditions, such as delay, read or write-readyness
371 * are satisfied). Use GNUNET_SCHEDULER_NO_PREREQUISITE_TASK to not have any dependency
372 * on completion of other tasks.
373 * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever"
374 * @param wfd write file-descriptor
375 * @param main main function of the task
376 * @param cls closure of task
377 * @return unique task identifier for the job
378 * only valid until "main" is started!
379 */
380GNUNET_SCHEDULER_TaskIdentifier
381GNUNET_SCHEDULER_add_write (struct GNUNET_SCHEDULER_Handle *sched,
382 int run_on_shutdown,
383 enum GNUNET_SCHEDULER_Priority prio,
384 GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
385 struct GNUNET_TIME_Relative delay,
386 int wfd, GNUNET_SCHEDULER_Task main, void *cls);
387
388
389/**
390 * Schedule a new task to be run with a specified delay or when any of
391 * the specified file descriptor sets is ready. The delay can be used
392 * as a timeout on the socket(s) being ready. The task will be
393 * scheduled for execution once either the delay has expired or any of
394 * the socket operations is ready. This is the most general
395 * function of the "add" family. Note that the "prerequisite_task"
396 * must be satisfied in addition to any of the other conditions. In
397 * other words, the task will be started when
398 * <code>
399 * (prerequisite-run)
400 * && (delay-ready
401 * || any-rs-ready
402 * || any-ws-ready
403 * || (shutdown-active && run-on-shutdown) )
404 * </code>
405 *
406 * @param sched scheduler to use
407 * @param run_on_shutdown run on shutdown? Set this
408 * argument to GNUNET_NO to skip this task if
409 * the user requested process termination.
410 * @param prio how important is this task?
411 * @param prerequisite_task run this task after the task with the given
412 * task identifier completes (and any of our other
413 * conditions, such as delay, read or write-readyness
414 * are satisfied). Use GNUNET_SCHEDULER_NO_PREREQUISITE_TASK to not have any dependency
415 * on completion of other tasks.
416 * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever"
417 * @param nfds highest-numbered file descriptor in any of the two sets plus one
418 * @param rs set of file descriptors we want to read (can be NULL)
419 * @param ws set of file descriptors we want to write (can be NULL)
420 * @param main main function of the task
421 * @param cls closure of task
422 * @return unique task identifier for the job
423 * only valid until "main" is started!
424 */
425GNUNET_SCHEDULER_TaskIdentifier
426GNUNET_SCHEDULER_add_select (struct GNUNET_SCHEDULER_Handle *sched,
427 int run_on_shutdown,
428 enum GNUNET_SCHEDULER_Priority prio,
429 GNUNET_SCHEDULER_TaskIdentifier
430 prerequisite_task,
431 struct GNUNET_TIME_Relative delay,
432 int nfds, const fd_set * rs, const fd_set * ws,
433 GNUNET_SCHEDULER_Task main, void *cls);
434
435#if 0 /* keep Emacsens' auto-indent happy */
436{
437#endif
438#ifdef __cplusplus
439}
440#endif
441
442#endif
diff --git a/src/include/gnunet_server_lib.h b/src/include/gnunet_server_lib.h
new file mode 100644
index 000000000..4e4f35e26
--- /dev/null
+++ b/src/include/gnunet_server_lib.h
@@ -0,0 +1,498 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 include/gnunet_server_lib.h
23 * @brief library for building GNUnet network servers
24 *
25 * @author Christian Grothoff
26 */
27
28#ifndef GNUNET_SERVER_LIB_H
29#define GNUNET_SERVER_LIB_H
30
31#ifdef __cplusplus
32extern "C"
33{
34#if 0 /* keep Emacsens' auto-indent happy */
35}
36#endif
37#endif
38
39#include "gnunet_common.h"
40#include "gnunet_network_lib.h"
41#include "gnunet_scheduler_lib.h"
42
43
44/**
45 * Largest supported message.
46 */
47#define GNUNET_SERVER_MAX_MESSAGE_SIZE 65536
48
49
50/**
51 * @brief handle for a server
52 */
53struct GNUNET_SERVER_Handle;
54
55
56/**
57 * @brief opaque handle for a client of the server
58 */
59struct GNUNET_SERVER_Client;
60
61
62/**
63 * Functions with this signature are called whenever a message is
64 * received.
65 *
66 * @param cls closure
67 * @param server the server handling the message
68 * @param client identification of the client
69 * @param message the actual message
70 */
71typedef void (*GNUNET_SERVER_MessageCallback) (void *cls,
72 struct GNUNET_SERVER_Handle *
73 server,
74 struct GNUNET_SERVER_Client *
75 client,
76 const struct
77 GNUNET_MessageHeader *
78 message);
79
80
81
82/**
83 * Message handler. Each struct specifies how to handle on particular
84 * type of message received.
85 */
86struct GNUNET_SERVER_MessageHandler
87{
88 /**
89 * Function to call for messages of "type".
90 */
91 GNUNET_SERVER_MessageCallback callback;
92
93 /**
94 * Closure argument for "callback".
95 */
96 void *callback_cls;
97
98 /**
99 * Type of the message this handler covers.
100 */
101 uint16_t type;
102
103 /**
104 * Expected size of messages of this type. Use 0 for
105 * variable-size. If non-zero, messages of the given
106 * type will be discarded (and the connection closed)
107 * if they do not have the right size.
108 */
109 uint16_t expected_size;
110
111};
112
113
114/**
115 * Create a new server.
116 *
117 * @param sched scheduler to use
118 * @param access function for access control
119 * @param access_cls closure for access
120 * @param serverAddr address to listen on (including port), use NULL
121 * for internal server (no listening)
122 * @param socklen length of serverAddr
123 * @param maxbuf maximum write buffer size for accepted sockets
124 * @param idle_timeout after how long should we timeout idle connections?
125 * @param require_found if YES, connections sending messages of unknown type
126 * will be closed
127 * @return handle for the new server, NULL on error
128 * (typically, "port" already in use)
129 */
130struct GNUNET_SERVER_Handle *GNUNET_SERVER_create (struct
131 GNUNET_SCHEDULER_Handle
132 *sched,
133 GNUNET_NETWORK_AccessCheck
134 access, void *access_cls,
135 const struct sockaddr
136 *serverAddr,
137 socklen_t socklen,
138 size_t maxbuf,
139 struct GNUNET_TIME_Relative
140 idle_timeout,
141 int require_found);
142
143
144/**
145 * Free resources held by this server.
146 */
147void GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s);
148
149
150/**
151 * Add additional handlers to an existing server.
152 *
153 * @param server the server to add handlers to
154 * @param handlers array of message handlers for
155 * incoming messages; the last entry must
156 * have "NULL" for the "callback"; multiple
157 * entries for the same type are allowed,
158 * they will be called in order of occurence.
159 * These handlers can be removed later;
160 * the handlers array must exist until removed
161 * (or server is destroyed).
162 */
163void
164GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
165 const struct GNUNET_SERVER_MessageHandler
166 *handlers);
167
168
169/**
170 * Notify us when the server has enough space to transmit
171 * a message of the given size to the given client.
172 *
173 * @param client client to transmit message to
174 * @param size requested amount of buffer space
175 * @param timeout after how long should we give up (and call
176 * notify with buf NULL and size 0)?
177 * @param callback function to call when space is available
178 * @param callback_cls closure for callback
179 * @return non-NULL if the notify callback was queued; can be used
180 * to cancel the request using
181 * GNUNET_NETWORK_notify_transmit_ready_cancel.
182 * NULL if we are already going to notify someone else (busy)
183 */
184struct GNUNET_NETWORK_TransmitHandle
185 *GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
186 size_t size,
187 struct GNUNET_TIME_Relative timeout,
188 GNUNET_NETWORK_TransmitReadyNotify
189 callback, void *callback_cls);
190
191
192/**
193 * Resume receiving from this client, we are done processing the
194 * current request. This function must be called from within each
195 * GNUNET_SERVER_MessageCallback (or its respective continuations).
196 *
197 * @param client client we were processing a message of
198 * @param success GNUNET_OK to keep the connection open and
199 * continue to receive
200 * GNUNET_SYSERR to close the connection (signal
201 * serious error)
202 */
203void
204GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success);
205
206
207/**
208 * Inject a message into the server, pretend it came
209 * from the specified client. Delivery of the message
210 * will happen instantly (if a handler is installed;
211 * otherwise the call does nothing).
212 *
213 * @param server the server receiving the message
214 * @param sender the "pretended" sender of the message
215 * can be NULL!
216 * @param message message to transmit
217 * @return GNUNET_OK if the message was OK and the
218 * connection can stay open
219 * GNUNET_SYSERR if the connection to the
220 * client should be shut down
221 */
222int
223GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
224 struct GNUNET_SERVER_Client *sender,
225 const struct GNUNET_MessageHeader *message);
226
227
228/**
229 * Add a TCP socket-based connection to the set of handles managed by
230 * this server. Use this function for outgoing (P2P) connections that
231 * we initiated (and where this server should process incoming
232 * messages).
233 *
234 * @param server the server to use
235 * @param connection the connection to manage (client must
236 * stop using this connection from now on)
237 * @return the client handle (client should call
238 * "client_drop" on the return value eventually)
239 */
240struct GNUNET_SERVER_Client *GNUNET_SERVER_connect_socket (struct
241 GNUNET_SERVER_Handle
242 *server,
243 struct
244 GNUNET_NETWORK_SocketHandle
245 *connection);
246
247
248/**
249 * Receive data from the given connection. This function should call
250 * "receiver" asynchronously using the scheduler. It must return
251 * "immediately".
252 *
253 * @param cls closure
254 * @param sched scheduler to use
255 * @param max maximum number of bytes to read
256 * @param timeout maximum amount of time to wait (use -1 for "forever")
257 * @param receiver function to call with received data
258 * @param receiver_cls closure for receiver
259 * @return task identifier that can be used to cancel the receive,
260 * GNUNET_SCHEDULER_NO_PREREQUISITE_TASK should be returned
261 * if the receiver function was already called
262 */
263typedef GNUNET_SCHEDULER_TaskIdentifier
264 (*GNUNET_SERVER_ReceiveCallback) (void *cls,
265 size_t max,
266 struct GNUNET_TIME_Relative timeout,
267 GNUNET_NETWORK_Receiver
268 receiver, void *receiver_cls);
269
270
271/**
272 * Cancel receive request.
273 *
274 * @param cls closure
275 * @param ti task identifier from the receive callback
276 */
277typedef void (*GNUNET_SERVER_ReceiveCancelCallback) (void *cls,
278 GNUNET_SCHEDULER_TaskIdentifier
279 ti);
280
281
282/**
283 * Notify us when the connection is ready to transmit size bytes.
284 *
285 * @param cls closure
286 * @param size number of bytes to be ready for sending
287 * @param timeout after how long should we give up (and call
288 * notify with buf NULL and size 0)?
289 * @param notify function to call
290 * @param notify_cls closure for notify
291 * @return a handle that can be used to cancel
292 * the transmission request or NULL if
293 * queueing a transmission request failed
294 */
295typedef void *(*GNUNET_SERVER_TransmitReadyCallback) (void *cls,
296 size_t size,
297 struct
298 GNUNET_TIME_Relative
299 timeout,
300 GNUNET_NETWORK_TransmitReadyNotify
301 notify,
302 void *notify_cls);
303
304
305/**
306 * Cancel an earlier transmit notification request.
307 *
308 * @param cls closure
309 * @param ctx handle that was returned by the TransmitReadyCallback
310 */
311typedef void (*GNUNET_SERVER_TransmitReadyCancelCallback) (void *cls,
312 void *ctx);
313
314
315/**
316 * Check if connection is still valid (no fatal errors have happened so far).
317 *
318 * @param cls closure
319 * @return GNUNET_YES if valid, GNUNET_NO otherwise
320 */
321typedef int (*GNUNET_SERVER_CheckCallback) (void *cls);
322
323
324/**
325 * Destroy this connection (free resources).
326 *
327 * @param cls closure
328 */
329typedef void (*GNUNET_SERVER_DestroyCallback) (void *cls);
330
331
332/**
333 * Add an arbitrary connection to the set of handles managed by this
334 * server. This can be used if a sending and receiving does not
335 * really go over the network (internal transmission) or for servers
336 * using UDP.
337 *
338 * @param server the server to use
339 * @param chandle opaque handle for the connection
340 * @param creceive receive function for the connection
341 * @param creceive_cancel cancel receive function for the connection
342 * @param cnotify transmit notification function for the connection
343 * @param cnotify_cancel transmit notification cancellation function for the connection
344 * @param ccheck function to test if the connection is still up
345 * @param cdestroy function to close and free the connection
346 * @return the client handle (client should call
347 * "client_drop" on the return value eventually)
348 */
349struct GNUNET_SERVER_Client *GNUNET_SERVER_connect_callback (struct
350 GNUNET_SERVER_Handle
351 *server,
352 void *chandle,
353 GNUNET_SERVER_ReceiveCallback
354 creceive,
355 GNUNET_SERVER_ReceiveCancelCallback
356 ccancel,
357 GNUNET_SERVER_TransmitReadyCallback
358 cnotify,
359 GNUNET_SERVER_TransmitReadyCancelCallback
360 cnotify_cancel,
361 GNUNET_SERVER_CheckCallback
362 ccheck,
363 GNUNET_SERVER_DestroyCallback
364 cdestroy);
365
366
367/**
368 * Notify the server that the given client handle should
369 * be kept (keeps the connection up if possible, increments
370 * the internal reference counter).
371 *
372 * @param client the client to keep
373 */
374void GNUNET_SERVER_client_keep (struct GNUNET_SERVER_Client *client);
375
376
377/**
378 * Notify the server that the given client handle is no
379 * longer required. Decrements the reference counter. If
380 * that counter reaches zero an inactive connection maybe
381 * closed.
382 *
383 * @param client the client to drop
384 */
385void GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client);
386
387
388/**
389 * Obtain the network address of the other party.
390 *
391 * @param client the client to get the address for
392 * @param addr where to store the address
393 * @param addrlen where to store the length of the address
394 * @return GNUNET_OK on success
395 */
396int GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client,
397 void **addr, size_t * addrlen);
398
399
400/**
401 * Functions with this signature are called whenever a client
402 * is disconnected on the network level.
403 *
404 * @param cls closure
405 * @param client identification of the client
406 */
407typedef void (*GNUNET_SERVER_DisconnectCallback) (void *cls,
408 struct GNUNET_SERVER_Client
409 * client);
410
411
412/**
413 * Ask the server to notify us whenever a client disconnects.
414 * This function is called whenever the actual network connection
415 * is closed; the reference count may be zero or larger than zero
416 * at this point.
417 *
418 * @param server the server manageing the clients
419 * @param callback function to call on disconnect
420 * @param callback_cls closure for callback
421 */
422void GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server,
423 GNUNET_SERVER_DisconnectCallback
424 callback, void *callback_cls);
425
426
427/**
428 * Ask the server to disconnect from the given client.
429 * This is the same as returning GNUNET_SYSERR from a message
430 * handler, except that it allows dropping of a client even
431 * when not handling a message from that client.
432 *
433 * @param client the client to disconnect from
434 */
435void GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client);
436
437
438/**
439 * The tansmit context is the key datastructure for a conveniance API
440 * used for transmission of complex results to the client followed
441 * ONLY by signaling receive_done with success or error
442 */
443struct GNUNET_SERVER_TransmitContext;
444
445
446/**
447 * Create a new transmission context for the
448 * given client.
449 *
450 * @param client client to create the context for.
451 * @return NULL on error
452 */
453struct GNUNET_SERVER_TransmitContext
454 *GNUNET_SERVER_transmit_context_create (struct GNUNET_SERVER_Client
455 *client);
456
457
458/**
459 * Append a message to the transmission context.
460 * All messages in the context will be sent by
461 * the transmit_context_run method.
462 *
463 * @param tc context to use
464 * @param data what to append to the result message
465 * @param length length of data
466 * @param type type of the message
467 */
468void
469GNUNET_SERVER_transmit_context_append (struct GNUNET_SERVER_TransmitContext
470 *tc, const void *data, size_t length,
471 uint16_t type);
472
473/**
474 * Execute a transmission context. If there is
475 * an error in the transmission, the receive_done
476 * method will be called with an error code (GNUNET_SYSERR),
477 * otherwise with GNUNET_OK.
478 *
479 * @param tc transmission context to use
480 * @param timeout when to time out and abort the transmission
481 */
482void
483GNUNET_SERVER_transmit_context_run (struct GNUNET_SERVER_TransmitContext *tc,
484 struct GNUNET_TIME_Relative timeout);
485
486
487
488#if 0 /* keep Emacsens' auto-indent happy */
489{
490#endif
491#ifdef __cplusplus
492}
493#endif
494
495
496/* ifndef GNUNET_SERVER_LIB_H */
497#endif
498/* end of gnunet_server_lib.h */
diff --git a/src/include/gnunet_service_lib.h b/src/include/gnunet_service_lib.h
new file mode 100644
index 000000000..dbfb2588b
--- /dev/null
+++ b/src/include/gnunet_service_lib.h
@@ -0,0 +1,140 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 include/gnunet_service_lib.h
23 * @brief functions related to starting services
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_SERVICE_LIB_H
28#define GNUNET_SERVICE_LIB_H
29
30#ifdef __cplusplus
31extern "C"
32{
33#if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38#include "gnunet_configuration_lib.h"
39#include "gnunet_server_lib.h"
40
41/**
42 * Function called by the service's run
43 * method to run service-specific setup code.
44 *
45 * @param cls closure
46 * @param sched scheduler to use
47 * @param server the initialized server
48 * @param cfg configuration to use
49 */
50typedef void (*GNUNET_SERVICE_Main) (void *cls,
51 struct GNUNET_SCHEDULER_Handle * sched,
52 struct GNUNET_SERVER_Handle * server,
53 struct GNUNET_CONFIGURATION_Handle *
54 cfg);
55
56
57/**
58 * Function called when the service shuts
59 * down to run service-specific teardown code.
60 *
61 * @param cls closure
62 * @param cfg configuration to use
63 */
64typedef void (*GNUNET_SERVICE_Term) (void *cls,
65 struct GNUNET_CONFIGURATION_Handle *
66 cfg);
67
68
69/**
70 * Run a standard GNUnet service startup sequence (initialize loggers
71 * and configuration, parse options).
72 *
73 * @param argc number of command line arguments
74 * @param argv command line arguments
75 * @param serviceName our service name
76 * @param task main task of the service
77 * @param task_cls closure for task
78 * @param term termination task of the service
79 * @param term_cls closure for term
80 * @return GNUNET_SYSERR on error, GNUNET_OK
81 * if we shutdown nicely
82 */
83int GNUNET_SERVICE_run (int argc,
84 char *const *argv,
85 const char *serviceName,
86 GNUNET_SERVICE_Main task,
87 void *task_cls,
88 GNUNET_SERVICE_Term term, void *term_cls);
89
90
91struct GNUNET_SERVICE_Context;
92
93/**
94 * Run a service startup sequence within an existing
95 * initialized system.
96 *
97 * @param serviceName our service name
98 * @param sched scheduler to use
99 * @param cfg configuration to use
100 * @return NULL on error, service handle
101 */
102struct GNUNET_SERVICE_Context *GNUNET_SERVICE_start (const char *serviceName,
103 struct
104 GNUNET_SCHEDULER_Handle
105 *sched,
106 struct
107 GNUNET_CONFIGURATION_Handle
108 *cfg);
109
110
111/**
112 * Obtain the server used by a service. Note that the server must NOT
113 * be destroyed by the caller.
114 *
115 * @param ctx the service context returned from the start function
116 * @return handle to the server for this service, NULL if there is none
117 */
118struct GNUNET_SERVER_Handle *GNUNET_SERVICE_get_server (struct
119 GNUNET_SERVICE_Context
120 *ctx);
121
122
123/**
124 * Stop a service that was started with "GNUNET_SERVICE_start".
125 *
126 * @param ctx the service context returned from the start function
127 */
128void GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Context *ctx);
129
130
131#if 0 /* keep Emacsens' auto-indent happy */
132{
133#endif
134#ifdef __cplusplus
135}
136#endif
137
138/* ifndef GNUNET_SERVICE_LIB_H */
139#endif
140/* end of gnunet_service_lib.h */
diff --git a/src/include/gnunet_signal_lib.h b/src/include/gnunet_signal_lib.h
new file mode 100644
index 000000000..af1ec0de4
--- /dev/null
+++ b/src/include/gnunet_signal_lib.h
@@ -0,0 +1,73 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 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 2, 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 include/gnunet_signal_lib.h
23 * @brief functions related to signals
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_SIGNAL_LIB_H
28#define GNUNET_SIGNAL_LIB_H
29
30#ifdef __cplusplus
31extern "C"
32{
33#if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38struct GNUNET_SIGNAL_Context;
39
40/**
41 * A signal handler. Since different OSes have different signatures
42 * for their handlers, the API only gives the most restrictive
43 * signature -- no arguments, no return value. Note that this will
44 * work even if the OS expects a function with arguments. However,
45 * the implementation must guarantee that this handler is not called
46 * for signals other than the one that it has been registered for.
47 */
48typedef void (*GNUNET_SIGNAL_Handler) (void);
49
50/**
51 * Install a signal handler that will be run if the
52 * given signal is received.
53 */
54struct GNUNET_SIGNAL_Context *GNUNET_SIGNAL_handler_install (int signal,
55 GNUNET_SIGNAL_Handler
56 handler);
57
58/**
59 * Uninstall a previously installed signal hander.
60 */
61void GNUNET_SIGNAL_handler_uninstall (struct GNUNET_SIGNAL_Context *ctx);
62
63
64#if 0 /* keep Emacsens' auto-indent happy */
65{
66#endif
67#ifdef __cplusplus
68}
69#endif
70
71/* ifndef GNUNET_SIGNAL_LIB_H */
72#endif
73/* end of gnunet_signal_lib.h */
diff --git a/src/include/gnunet_signatures.h b/src/include/gnunet_signatures.h
new file mode 100644
index 000000000..adb00c1ac
--- /dev/null
+++ b/src/include/gnunet_signatures.h
@@ -0,0 +1,77 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 include/gnunet_signatures.h
23 * @brief constants for network signatures
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_SIGNATURES_H
28#define GNUNET_SIGNATURES_H
29
30#ifdef __cplusplus
31extern "C"
32{
33#if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38/**
39 * Test signature, not valid for anything other than writing
40 * a test. (Note that the signature verification code will
41 * accept this value).
42 */
43#define GNUNET_SIGNATURE_PURPOSE_TEST 0
44
45/**
46 * Signature for confirming HELLOs.
47 */
48#define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_HELLO 1
49
50
51/**
52 * Purpose is to set a session key.
53 */
54#define GNUNET_SIGNATURE_PURPOSE_SET_KEY 2
55
56/**
57 * Signature for a namespace/pseudonym advertisement (by
58 * the namespace owner).
59 */
60#define GNUNET_SIGNATURE_PURPOSE_NAMESPACE_ADVERTISEMENT 3
61
62/**
63 *
64 */
65#define GNUNET_SIGNATURE_PURPOSE_RESOLVER_RESPONSE 3
66
67
68#if 0 /* keep Emacsens' auto-indent happy */
69{
70#endif
71#ifdef __cplusplus
72}
73#endif
74
75/* ifndef GNUNET_SIGNATURES_H */
76#endif
77/* end of gnunet_signatures.h */
diff --git a/src/include/gnunet_statistics_service.h b/src/include/gnunet_statistics_service.h
new file mode 100644
index 000000000..8dd11094c
--- /dev/null
+++ b/src/include/gnunet_statistics_service.h
@@ -0,0 +1,157 @@
1/*
2 This file is part of GNUnet
3 (C) 2009 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 2, 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 include/gnunet_statistics_service.h
23 * @brief API to create, modify and access statistics about
24 * the operation of GNUnet; all statistical values
25 * must be of type "unsigned long long".
26 * @author Christian Grothoff
27 */
28
29#ifndef GNUNET_STATISTICS_SERVICE_H
30#define GNUNET_STATISTICS_SERVICE_H
31
32#ifdef __cplusplus
33extern "C"
34{
35#if 0 /* keep Emacsens' auto-indent happy */
36}
37#endif
38#endif
39
40#include "gnunet_common.h"
41#include "gnunet_configuration_lib.h"
42#include "gnunet_scheduler_lib.h"
43
44/**
45 * Version of the statistics API.
46 */
47#define GNUNET_STATISTICS_VERSION 0x00000000
48
49/**
50 * Opaque handle for the statistics service.
51 */
52struct GNUNET_STATISTICS_Handle;
53
54/**
55 * Callback function to process statistic values.
56 *
57 * @param cls closure
58 * @param subsystem name of subsystem that created the statistic
59 * @param name the name of the datum
60 * @param value the current value
61 * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not
62 * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration
63 */
64typedef int (*GNUNET_STATISTICS_Iterator) (void *cls,
65 const char *subsystem,
66 const char *name,
67 unsigned long long value,
68 int is_persistent);
69
70/**
71 * Get handle for the statistics service.
72 *
73 * @param sched scheduler to use
74 * @param subsystem name of subsystem using the service
75 * @param cfg services configuration in use
76 * @return handle to use
77 */
78struct GNUNET_STATISTICS_Handle
79 *GNUNET_STATISTICS_create (struct GNUNET_SCHEDULER_Handle *sched,
80 const char *subsystem,
81 struct GNUNET_CONFIGURATION_Handle *cfg);
82
83
84/**
85 * Destroy a handle (free all state associated with
86 * it).
87 */
88void GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *handle);
89
90
91/**
92 * Continuation called by the "get_all" and "get" functions.
93 *
94 * @param cls closure
95 * @param success GNUNET_OK if statistics were
96 * successfully obtained, GNUNET_SYSERR if not.
97 */
98typedef void (*GNUNET_STATISTICS_Callback) (void *cls, int success);
99
100/**
101 * Get statistic from the peer.
102 *
103 * @param handle identification of the statistics service
104 * @param subsystem limit to the specified subsystem, NULL for our subsystem
105 * @param name name of the statistic value, NULL for all values
106 * @param timeout after how long should we give up (and call
107 * notify with buf NULL and size 0)?
108 * @param cont continuation to call when done (can be NULL)
109 * @param proc function to call on each value
110 * @param cls closure for proc and cont
111 */
112void
113GNUNET_STATISTICS_get (struct GNUNET_STATISTICS_Handle *handle,
114 const char *subsystem,
115 const char *name,
116 struct GNUNET_TIME_Relative timeout,
117 GNUNET_STATISTICS_Callback cont,
118 GNUNET_STATISTICS_Iterator proc, void *cls);
119
120/**
121 * Set statistic value for the peer. Will always use our
122 * subsystem (the argument used when "handle" was created).
123 *
124 * @param handle identification of the statistics service
125 * @param name name of the statistic value
126 * @param value new value to set
127 * @param make_persistent should the value be kept across restarts?
128 */
129void
130GNUNET_STATISTICS_set (struct GNUNET_STATISTICS_Handle *handle,
131 const char *name,
132 unsigned long long value, int make_persistent);
133
134/**
135 * Set statistic value for the peer. Will always use our
136 * subsystem (the argument used when "handle" was created).
137 *
138 * @param handle identification of the statistics service
139 * @param name name of the statistic value
140 * @param delta change in value (added to existing value)
141 * @param make_persistent should the value be kept across restarts?
142 */
143void
144GNUNET_STATISTICS_update (struct GNUNET_STATISTICS_Handle *handle,
145 const char *name,
146 long long delta, int make_persistent);
147
148
149
150#if 0 /* keep Emacsens' auto-indent happy */
151{
152#endif
153#ifdef __cplusplus
154}
155#endif
156
157#endif
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h
new file mode 100644
index 000000000..98d2ed396
--- /dev/null
+++ b/src/include/gnunet_strings_lib.h
@@ -0,0 +1,139 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 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 2, 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 include/gnunet_strings_lib.h
23 * @brief strings and string handling functions (including malloc
24 * and string tokenizing)
25 *
26 * @author Christian Grothoff
27 * @author Krista Bennett
28 * @author Gerd Knorr <kraxel@bytesex.org>
29 * @author Ioana Patrascu
30 * @author Tzvetan Horozov
31 */
32
33#ifndef GNUNET_STRINGS_LIB_H
34#define GNUNET_STRINGS_LIB_H
35
36/* we need size_t, and since it can be both unsigned int
37 or unsigned long long, this IS platform dependent;
38 but "stdlib.h" should be portable 'enough' to be
39 unconditionally available... */
40#include <stdlib.h>
41
42#ifdef __cplusplus
43extern "C"
44{
45#if 0 /* keep Emacsens' auto-indent happy */
46}
47#endif
48#endif
49
50#include "gnunet_time_lib.h"
51
52
53/**
54 * Convert a given filesize into a fancy human-readable format.
55 */
56char *GNUNET_STRINGS_byte_size_fancy (unsigned long long size);
57
58/**
59 * Convert the len characters long character sequence
60 * given in input that is in the given charset
61 * to UTF-8.
62 *
63 * @return the converted string (0-terminated)
64 */
65char *GNUNET_STRINGS_to_utf8 (const char *input,
66 size_t len, const char *charset);
67
68/**
69 * Complete filename (a la shell) from abbrevition.
70 *
71 * @param fil the name of the file, may contain ~/ or
72 * be relative to the current directory
73 * @returns the full file name,
74 * NULL is returned on error
75 */
76char *GNUNET_STRINGS_filename_expand (const char *fil);
77
78/**
79 * Fill a buffer of the given size with
80 * count 0-terminated strings (given as varargs).
81 * If "buffer" is NULL, only compute the amount of
82 * space required (sum of "strlen(arg)+1").
83 *
84 * Unlike using "snprintf" with "%s", this function
85 * will add 0-terminators after each string. The
86 * "GNUNET_string_buffer_tokenize" function can be
87 * used to parse the buffer back into individual
88 * strings.
89 *
90 * @return number of bytes written to the buffer
91 * (or number of bytes that would have been written)
92 */
93unsigned int GNUNET_STRINGS_buffer_fill (char *buffer,
94 unsigned int size,
95 unsigned int count, ...);
96
97/**
98 * Given a buffer of a given size, find "count"
99 * 0-terminated strings in the buffer and assign
100 * the count (varargs) of type "const char**" to the
101 * locations of the respective strings in the
102 * buffer.
103 *
104 * @param buffer the buffer to parse
105 * @param size size of the buffer
106 * @param count number of strings to locate
107 * @return offset of the character after the last 0-termination
108 * in the buffer, or 0 on error.
109 */
110unsigned int GNUNET_STRINGS_buffer_tokenize (const char *buffer,
111 unsigned int size,
112 unsigned int count, ...);
113
114
115
116/**
117 * "man ctime_r", except for GNUnet time; also, unlike ctime, the
118 * return value does not include the newline character.
119 */
120char *GNUNET_STRINGS_absolute_time_to_string (struct GNUNET_TIME_Absolute t);
121
122
123/**
124 * Give relative time in human-readable fancy format.
125 * @param delta time in milli seconds
126 */
127char *GNUNET_STRINGS_relative_time_to_string (struct GNUNET_TIME_Relative
128 delta);
129#if 0 /* keep Emacsens' auto-indent happy */
130{
131#endif
132#ifdef __cplusplus
133}
134#endif
135
136
137/* ifndef GNUNET_UTIL_STRING_H */
138#endif
139/* end of gnunet_util_string.h */
diff --git a/src/include/gnunet_time_lib.h b/src/include/gnunet_time_lib.h
new file mode 100644
index 000000000..4ce1e3f1e
--- /dev/null
+++ b/src/include/gnunet_time_lib.h
@@ -0,0 +1,246 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 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 2, 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 include/gnunet_time_lib.h
23 * @brief functions related to time
24 *
25 * @author Christian Grothoff
26 */
27
28#ifndef GNUNET_TIME_LIB_H
29#define GNUNET_TIME_LIB_H
30
31#ifdef __cplusplus
32extern "C"
33{
34#if 0 /* keep Emacsens' auto-indent happy */
35}
36#endif
37#endif
38
39#include "gnunet_common.h"
40
41/**
42 * Time for absolute times used by GNUnet, in milliseconds.
43 */
44struct GNUNET_TIME_Absolute
45{
46 uint64_t value;
47};
48
49/**
50 * Time for relative time used by GNUnet, in milliseconds.
51 * Always positive, so we can only refer to future time.
52 */
53struct GNUNET_TIME_Relative
54{
55 uint64_t value;
56};
57
58
59/**
60 * Time for relative time used by GNUnet, in milliseconds and in network byte order.
61 */
62struct GNUNET_TIME_RelativeNBO
63{
64 uint64_t value GNUNET_PACKED;
65};
66
67
68/**
69 * Time for absolute time used by GNUnet, in milliseconds and in network byte order.
70 */
71struct GNUNET_TIME_AbsoluteNBO
72{
73 uint64_t value GNUNET_PACKED;
74};
75
76/**
77 * @brief constants to specify time
78 */
79#define GNUNET_TIME_UNIT_ZERO GNUNET_TIME_relative_get_zero()
80#define GNUNET_TIME_UNIT_MILLISECONDS GNUNET_TIME_relative_get_unit()
81#define GNUNET_TIME_UNIT_SECONDS GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 1000)
82#define GNUNET_TIME_UNIT_MINUTES GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 60)
83#define GNUNET_TIME_UNIT_HOURS GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 60)
84#define GNUNET_TIME_UNIT_DAYS GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_HOURS, 24)
85#define GNUNET_TIME_UNIT_WEEKS GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_DAYS, 7)
86#define GNUNET_TIME_UNIT_MONTHS GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_DAYS, 30)
87#define GNUNET_TIME_UNIT_YEARS GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_DAYS, 365)
88
89/**
90 * Constant used to specify "forever". This constant
91 * will be treated specially in all time operations.
92 */
93#define GNUNET_TIME_UNIT_FOREVER_REL GNUNET_TIME_relative_get_forever ()
94
95/**
96 * Constant used to specify "forever". This constant
97 * will be treated specially in all time operations.
98 */
99#define GNUNET_TIME_UNIT_FOREVER_ABS GNUNET_TIME_absolute_get_forever ()
100
101/**
102 * Return relative time of 0ms.
103 */
104struct GNUNET_TIME_Relative GNUNET_TIME_relative_get_zero (void);
105
106/**
107 * Return relative time of 1ms.
108 */
109struct GNUNET_TIME_Relative GNUNET_TIME_relative_get_unit (void);
110
111/**
112 * Return "forever".
113 */
114struct GNUNET_TIME_Relative GNUNET_TIME_relative_get_forever (void);
115
116/**
117 * Return "forever".
118 */
119struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get_forever (void);
120
121/**
122 * Get the current time.
123 *
124 * @return the current time
125 */
126struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get (void);
127
128/**
129 * Convert relative time to an absolute time in the
130 * future.
131 *
132 * @return timestamp that is "rel" in the future, or FOREVER if rel==FOREVER (or if we would overflow)
133 */
134struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute (struct
135 GNUNET_TIME_Relative
136 rel);
137
138/**
139 * Given a timestamp in the future, how much time
140 * remains until then?
141 *
142 * @return future - now, or 0 if now >= future, or FOREVER if future==FOREVER.
143 */
144struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining (struct
145 GNUNET_TIME_Absolute
146 future);
147
148/**
149 * Compute the time difference between the given start and end times.
150 * Use this function instead of actual subtraction to ensure that
151 * "FOREVER" and overflows are handeled correctly.
152 *
153 * @return 0 if start >= end; FOREVER if end==FOREVER; otherwise end - start
154 */
155struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_difference (struct
156 GNUNET_TIME_Absolute
157 start,
158 struct
159 GNUNET_TIME_Absolute
160 end);
161
162/**
163 * Get the duration of an operation as the
164 * difference of the current time and the given start time "hence".
165 *
166 * @return aborts if hence==FOREVER, 0 if hence > now, otherwise now-hence.
167 */
168struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration (struct
169 GNUNET_TIME_Absolute
170 hence);
171
172
173/**
174 * Add a given relative duration to the
175 * given start time.
176 *
177 * @return FOREVER if either argument is FOREVER or on overflow; start+duration otherwise
178 */
179struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add (struct
180 GNUNET_TIME_Absolute
181 start,
182 struct
183 GNUNET_TIME_Relative
184 duration);
185
186/**
187 * Multiply relative time by a given factor.
188 *
189 * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
190 */
191struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply (struct
192 GNUNET_TIME_Relative
193 rel,
194 unsigned int
195 factor);
196
197/**
198 * Add relative times together.
199 *
200 * @return FOREVER if either argument is FOREVER or on overflow; a1+a2 otherwise
201 */
202struct GNUNET_TIME_Relative GNUNET_TIME_relative_add (struct
203 GNUNET_TIME_Relative a1,
204 struct
205 GNUNET_TIME_Relative
206 a2);
207
208
209/**
210 * Convert relative time to network byte order.
211 */
212struct GNUNET_TIME_RelativeNBO GNUNET_TIME_relative_hton (struct
213 GNUNET_TIME_Relative
214 a);
215
216/**
217 * Convert relative time from network byte order.
218 */
219struct GNUNET_TIME_Relative GNUNET_TIME_relative_ntoh (struct
220 GNUNET_TIME_RelativeNBO
221 a);
222
223/**
224 * Convert relative time to network byte order.
225 */
226struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton (struct
227 GNUNET_TIME_Absolute
228 a);
229
230/**
231 * Convert relative time from network byte order.
232 */
233struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh (struct
234 GNUNET_TIME_AbsoluteNBO
235 a);
236
237#if 0 /* keep Emacsens' auto-indent happy */
238{
239#endif
240#ifdef __cplusplus
241}
242#endif
243
244/* ifndef GNUNET_TIME_LIB_H */
245#endif
246/* end of gnunet_time_lib.h */
diff --git a/src/include/gnunet_transport_service.h b/src/include/gnunet_transport_service.h
new file mode 100644
index 000000000..25ca388a7
--- /dev/null
+++ b/src/include/gnunet_transport_service.h
@@ -0,0 +1,241 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 include/gnunet_transport_service.h
23 * @brief low-level P2P IO
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_TRANSPORT_SERVICE_H
28#define GNUNET_TRANSPORT_SERVICE_H
29
30#ifdef __cplusplus
31extern "C"
32{
33#if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38#include "gnunet_configuration_lib.h"
39#include "gnunet_crypto_lib.h"
40#include "gnunet_network_lib.h"
41#include "gnunet_scheduler_lib.h"
42#include "gnunet_time_lib.h"
43
44/**
45 * Version number of the transport API.
46 */
47#define GNUNET_TRANSPORT_VERSION 0x00000000
48
49/**
50 * Function called by the transport for each received message.
51 *
52 * @param cls closure
53 * @param latency estimated latency for communicating with the
54 * given peer
55 * @param peer (claimed) identity of the other peer
56 * @param message the message
57 */
58typedef void (*GNUNET_TRANSPORT_ReceiveCallback) (void *cls,
59 struct GNUNET_TIME_Relative
60 latency,
61 const struct
62 GNUNET_PeerIdentity * peer,
63 const struct
64 GNUNET_MessageHeader *
65 message);
66
67
68/**
69 * Opaque handle to the service.
70 */
71struct GNUNET_TRANSPORT_Handle;
72
73
74/**
75 * Function called to notify transport users that another
76 * peer connected to us.
77 *
78 * @param cls closure
79 * @param peer the peer that connected
80 * @param latency current latency of the connection
81 */
82typedef void
83 (*GNUNET_TRANSPORT_NotifyConnect) (void *cls,
84 const struct GNUNET_PeerIdentity * peer,
85 struct GNUNET_TIME_Relative latency);
86
87/**
88 * Function called to notify transport users that another
89 * peer disconnected from us.
90 *
91 * @param cls closure
92 * @param peer the peer that disconnected
93 */
94typedef void
95 (*GNUNET_TRANSPORT_NotifyDisconnect) (void *cls,
96 const struct GNUNET_PeerIdentity *
97 peer);
98
99
100/**
101 * Connect to the transport service. Note that the connection may
102 * complete (or fail) asynchronously.
103 *
104 * @param sched scheduler to use
105 * @param cfg configuration to use
106 * @param cls closure for the callbacks
107 * @param rec receive function to call
108 * @param nc function to call on connect events
109 * @param dc function to call on disconnect events
110 */
111struct GNUNET_TRANSPORT_Handle *GNUNET_TRANSPORT_connect (struct
112 GNUNET_SCHEDULER_Handle
113 *sched,
114 struct
115 GNUNET_CONFIGURATION_Handle
116 *cfg, void *cls,
117 GNUNET_TRANSPORT_ReceiveCallback
118 rec,
119 GNUNET_TRANSPORT_NotifyConnect
120 nc,
121 GNUNET_TRANSPORT_NotifyDisconnect
122 nd);
123
124
125/**
126 * Disconnect from the transport service.
127 */
128void GNUNET_TRANSPORT_disconnect (struct GNUNET_TRANSPORT_Handle *handle);
129
130
131/**
132 * Set the share of incoming/outgoing bandwidth for the given
133 * peer to the specified amount.
134 *
135 * @param handle connection to transport service
136 * @param target who's bandwidth quota is being changed
137 * @param quota_in incoming bandwidth quota in bytes per ms; 0 can
138 * be used to force all traffic to be discarded
139 * @param quota_out outgoing bandwidth quota in bytes per ms; 0 can
140 * be used to force all traffic to be discarded
141 * @param timeout how long to wait until signaling failure if
142 * we can not communicate the quota change
143 * @param cont continuation to call when done, will be called
144 * either with reason "TIMEOUT" or with reason "PREREQ_DONE"
145 * @param cont_cls closure for continuation
146 */
147void
148GNUNET_TRANSPORT_set_quota (struct GNUNET_TRANSPORT_Handle *handle,
149 const struct GNUNET_PeerIdentity *target,
150 uint32_t quota_in,
151 uint32_t quota_out,
152 struct GNUNET_TIME_Relative timeout,
153 GNUNET_SCHEDULER_Task cont, void *cont_cls);
154
155
156/**
157 * Opaque handle for a transmission-ready request.
158 */
159struct GNUNET_TRANSPORT_TransmitHandle;
160
161
162/**
163 * Check if we could queue a message of the given size for
164 * transmission. The transport service will take both its
165 * internal buffers and bandwidth limits imposed by the
166 * other peer into consideration when answering this query.
167 *
168 * @param handle connection to transport service
169 * @param target who should receive the message
170 * @param size how big is the message we want to transmit?
171 * @param timeout after how long should we give up (and call
172 * notify with buf NULL and size 0)?
173 * @param notify function to call when we are ready to
174 * send such a message
175 * @param notify_cls closure for notify
176 * @return NULL if someone else is already waiting to be notified
177 * non-NULL if the notify callback was queued (can be used to cancel
178 * using GNUNET_TRANSPORT_notify_transmit_ready_cancel)
179 */
180struct GNUNET_TRANSPORT_TransmitHandle
181 *GNUNET_TRANSPORT_notify_transmit_ready (struct GNUNET_TRANSPORT_Handle
182 *handle,
183 const struct GNUNET_PeerIdentity
184 *target, size_t size,
185 struct GNUNET_TIME_Relative
186 timeout,
187 GNUNET_NETWORK_TransmitReadyNotify
188 notify, void *notify_cls);
189
190
191/**
192 * Cancel the specified transmission-ready
193 * notification.
194 */
195void
196GNUNET_TRANSPORT_notify_transmit_ready_cancel (struct
197 GNUNET_TRANSPORT_TransmitHandle
198 *h);
199
200
201/**
202 * Obtain the HELLO message for this peer.
203 *
204 * @param handle connection to transport service
205 * @param timeout how long to wait for the HELLO
206 * @param rec function to call with the HELLO, sender will be our peer
207 * identity; message and sender will be NULL on timeout
208 * (handshake with transport service pending/failed).
209 * cost estimate will be 0.
210 * @param rec_cls closure for rec
211 */
212void
213GNUNET_TRANSPORT_get_hello (struct GNUNET_TRANSPORT_Handle *handle,
214 struct GNUNET_TIME_Relative timeout,
215 GNUNET_TRANSPORT_ReceiveCallback rec,
216 void *rec_cls);
217
218
219/**
220 * Offer the transport service the HELLO of another peer. Note that
221 * the transport service may just ignore this message if the HELLO is
222 * malformed or useless due to our local configuration.
223 *
224 * @param handle connection to transport service
225 * @param hello the hello message
226 */
227void
228GNUNET_TRANSPORT_offer_hello (struct GNUNET_TRANSPORT_Handle *handle,
229 const struct GNUNET_MessageHeader *hello);
230
231
232#if 0 /* keep Emacsens' auto-indent happy */
233{
234#endif
235#ifdef __cplusplus
236}
237#endif
238
239/* ifndef GNUNET_TRANSPORT_SERVICE_H */
240#endif
241/* end of gnunet_transport_service.h */
diff --git a/src/include/gnunet_upnp_service.h b/src/include/gnunet_upnp_service.h
new file mode 100644
index 000000000..758d5c598
--- /dev/null
+++ b/src/include/gnunet_upnp_service.h
@@ -0,0 +1,75 @@
1/*
2 This file is part of GNUnet
3 (C) 2006 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 2, 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 include/gnunet_upnp_service.h
23 * @brief API for UPnP access
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_UPNP_SERVICE_H
28#define GNUNET_UPNP_SERVICE_H
29
30#include "gnunet_resolver_service.h"
31
32#ifdef __cplusplus
33extern "C"
34{
35#if 0 /* keep Emacsens' auto-indent happy */
36}
37#endif
38#endif
39
40
41/**
42 * Get the external IP address for the local machine and
43 * install a port mapping if possible. The external port
44 * will be returned as part of the address.
45 *
46 * @param sched scheduler to use
47 * @param cfg configuration to use
48 * @param domain communication domain (i.e. PF_INET or PF_INET6)
49 * @param type communication semantics (SOCK_STREAM, SOCK_DGRAM)
50 * @param protocol protocol to use, 0 for default (see protocols(5))
51 * @param port port to map
52 * @param timeout after how long should we give up (and call
53 * notify with buf NULL and size 0)?
54 * @param callback function to call with the external address;
55 * function will be called with NULL on error
56 * @param cls closure for callback
57 */
58int GNUNET_UPNP_get_ip (struct GNUNET_SCHEDULER_Handle *sched,
59 struct GNUNET_CONFIGURATION_Handle *cfg,
60 int domain,
61 int type,
62 int protocol,
63 uint16_t port,
64 struct GNUNET_TIME_Relative timeout,
65 GNUNET_RESOLVER_AddressCallback callback, void *cls);
66
67
68#if 0 /* keep Emacsens' auto-indent happy */
69{
70#endif
71#ifdef __cplusplus
72}
73#endif
74
75#endif
diff --git a/src/include/gnunet_util_lib.h b/src/include/gnunet_util_lib.h
new file mode 100644
index 000000000..c152377c3
--- /dev/null
+++ b/src/include/gnunet_util_lib.h
@@ -0,0 +1,64 @@
1/*
2 This file is part of GNUnet
3 (C) 2009 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 2, 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 include/gnunet_util_lib.h
23 * @brief convenience header including all headers of subsystems in
24 * gnunet_util library
25 * @author Christian Grothoff
26 */
27
28#ifndef GNUNET_UTIL_LIB_H
29#define GNUNET_UTIL_LIB_H
30
31#ifdef __cplusplus
32extern "C"
33{
34#if 0 /* keep Emacsens' auto-indent happy */
35}
36#endif
37#endif
38
39#include "gnunet_common.h"
40#include "gnunet_client_lib.h"
41#include "gnunet_configuration_lib.h"
42#include "gnunet_container_lib.h"
43#include "gnunet_crypto_lib.h"
44#include "gnunet_disk_lib.h"
45#include "gnunet_getopt_lib.h"
46#include "gnunet_network_lib.h"
47#include "gnunet_program_lib.h"
48#include "gnunet_protocols.h"
49#include "gnunet_pseudonym_lib.h"
50#include "gnunet_scheduler_lib.h"
51#include "gnunet_server_lib.h"
52#include "gnunet_service_lib.h"
53#include "gnunet_signal_lib.h"
54#include "gnunet_strings_lib.h"
55#include "gnunet_time_lib.h"
56
57#if 0 /* keep Emacsens' auto-indent happy */
58{
59#endif
60#ifdef __cplusplus
61}
62#endif
63
64#endif
diff --git a/src/include/platform.h b/src/include/platform.h
new file mode 100644
index 000000000..07fbe0ee7
--- /dev/null
+++ b/src/include/platform.h
@@ -0,0 +1,221 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 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 2, 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 include/platform.h
23 * @brief plaform specifics
24 *
25 * @author Nils Durner
26 *
27 * This file should never be included by installed
28 * header files (thos starting with "gnunet_").
29 */
30
31#ifndef PLATFORM_H
32#define PLATFORM_H
33
34#ifndef HAVE_USED_CONFIG_H
35#define HAVE_USED_CONFIG_H
36#if HAVE_CONFIG_H
37#include "gnunet_config.h"
38#endif
39#endif
40
41#ifdef WINDOWS
42#define BREAKPOINT asm("int $3;");
43#else
44#define BREAKPOINT
45#endif
46
47#ifdef HAVE_SYS_TYPES_H
48#include <sys/types.h>
49#endif
50
51#define ALLOW_EXTRA_CHECKS GNUNET_NO
52
53/**
54 * For strptime (glibc2 needs this).
55 */
56#ifndef _XOPEN_SOURCE
57#define _XOPEN_SOURCE
58#endif
59
60#ifndef _REENTRANT
61#define _REENTRANT
62#endif
63
64/* configuration options */
65
66#define VERBOSE_STATS 0
67
68#ifdef CYGWIN
69#include <sys/reent.h>
70#define _REENT_ONLY
71#endif
72
73#ifdef CYGWIN
74#undef _REENT_ONLY
75#endif
76
77#ifdef _MSC_VER
78#include <Winsock2.h>
79#else
80#ifndef MINGW
81#include <netdb.h>
82#include <sys/socket.h>
83#include <netinet/in.h>
84#include <arpa/inet.h>
85#include <netinet/tcp.h>
86#include <pwd.h>
87#include <sys/ioctl.h>
88#include <sys/wait.h>
89#include <grp.h>
90#else
91#include "winproc.h"
92#endif
93#endif
94
95#include <string.h>
96#include <stdio.h>
97#include <stdlib.h>
98#include <stdarg.h>
99#include <errno.h>
100#include <signal.h>
101#ifndef _MSC_VER
102#include <unistd.h> /* KLB_FIX */
103#endif
104#include <sys/stat.h>
105#include <sys/types.h>
106#ifndef _MSC_VER
107#include <dirent.h> /* KLB_FIX */
108#endif
109#include <fcntl.h>
110#include <math.h>
111#if HAVE_SYS_PARAM_H
112#include <sys/param.h>
113#endif
114#if TIME_WITH_SYS_TIME
115#include <sys/time.h>
116#include <time.h>
117#else
118#if HAVE_SYS_TIME_H
119#include <sys/time.h>
120#else
121#include <time.h>
122#endif
123#endif
124
125#ifdef SOMEBSD
126#include <net/if.h>
127#endif
128#ifdef GNUNET_freeBSD
129#include <semaphore.h>
130#endif
131#ifdef OSX
132#include <dlfcn.h>
133#include <semaphore.h>
134#include <net/if.h>
135#endif
136#ifdef LINUX
137#include <net/if.h>
138#endif
139#ifdef SOLARIS
140#include <sys/sockio.h>
141#include <sys/loadavg.h>
142#include <semaphore.h>
143#endif
144#ifdef CYGWIN
145#include <windows.h>
146#include <cygwin/if.h>
147#endif
148#if HAVE_IFADDRS_H
149#include <ifaddrs.h>
150#endif
151#include <errno.h>
152#include <limits.h>
153
154#if HAVE_CTYPE_H
155#include <ctype.h>
156#endif
157#if HAVE_SYS_RESOURCE_H
158#include <sys/resource.h>
159#endif
160
161#include "plibc.h"
162
163#include <pthread.h>
164#include <locale.h>
165#ifndef FRAMEWORK_BUILD
166#include "gettext.h"
167/**
168 * GNU gettext support macro.
169 */
170#define _(String) dgettext("gnunet",String)
171#define LIBEXTRACTOR_GETTEXT_DOMAIN "libextractor"
172#else
173#include "libintlemu.h"
174#define _(String) dgettext("org.gnunet.gnunet",String)
175#define LIBEXTRACTOR_GETTEXT_DOMAIN "org.gnunet.libextractor"
176#endif
177
178#ifdef CYGWIN
179#define SIOCGIFCONF _IOW('s', 100, struct ifconf) /* get if list */
180#define SIOCGIFFLAGS _IOW('s', 101, struct ifreq) /* Get if flags */
181#define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */
182#endif
183
184#ifndef MINGW
185#include <sys/mman.h>
186#endif
187
188#ifdef FREEBSD
189#define __BYTE_ORDER BYTE_ORDER
190#define __BIG_ENDIAN BIG_ENDIAN
191#endif
192
193#ifdef OSX
194#define socklen_t unsigned int
195#define __BYTE_ORDER BYTE_ORDER
196#define __BIG_ENDIAN BIG_ENDIAN
197 /* not available on OS X, override configure */
198#undef HAVE_STAT64
199#undef HAVE_MREMAP
200#endif
201
202
203#if !HAVE_ATOLL
204long long atoll (const char *nptr);
205#endif
206
207#if ENABLE_NLS
208#include "langinfo.h"
209#endif
210
211#ifndef O_LARGEFILE
212#define O_LARGEFILE 0
213#endif
214
215#if defined(__sparc__)
216#define MAKE_UNALIGNED(val) ({ __typeof__((val)) __tmp; memmove(&__tmp, &(val), sizeof((val))); __tmp; })
217#else
218#define MAKE_UNALIGNED(val) val
219#endif
220
221#endif
diff --git a/src/include/plibc.h b/src/include/plibc.h
new file mode 100644
index 000000000..93ca012e1
--- /dev/null
+++ b/src/include/plibc.h
@@ -0,0 +1,582 @@
1/*
2 This file is part of PlibC.
3 (C) 2005, 2006, 2007, 2008 Nils Durner (and other contributing authors)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18*/
19
20/**
21 * @file include/plibc.h
22 * @brief PlibC header
23 * @attention This file is usually not installed under Unix,
24 * so ship it with your application
25 * @version $Revision: 1.46 $
26 */
27
28#ifndef _PLIBC_H_
29#define _PLIBC_H_
30
31#ifndef SIGALRM
32#define SIGALRM 14
33#endif /* */
34
35#ifdef __cplusplus
36extern "C"
37{
38
39#endif /* */
40
41#ifdef Q_OS_WIN32
42#define WINDOWS 1
43#endif /* */
44
45#define HAVE_PLIBC_FD 0
46
47#ifdef WINDOWS
48
49#if ENABLE_NLS
50#include "langinfo.h"
51#endif /* */
52
53#include <windows.h>
54#include <Ws2tcpip.h>
55#include <time.h>
56#include <stdio.h>
57#include <sys/types.h>
58#include <sys/stat.h>
59#include <dirent.h>
60#include <errno.h>
61#include <stdarg.h>
62
63#define __BYTE_ORDER BYTE_ORDER
64#define __BIG_ENDIAN BIG_ENDIAN
65
66/* Conflicts with our definitions */
67#define __G_WIN32_H__
68
69/* Convert LARGE_INTEGER to double */
70#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + \
71 (double) ((x).LowPart))
72#define socklen_t int
73#define ssize_t int
74#define off_t int
75#define int64_t long long
76#define int32_t long
77 struct stat64
78 {
79 _dev_t st_dev;
80 _ino_t st_ino;
81 _mode_t st_mode;
82 short st_nlink;
83 short st_uid;
84 short st_gid;
85 _dev_t st_rdev;
86 __int64 st_size;
87 __time64_t st_atime;
88 __time64_t st_mtime;
89 __time64_t st_ctime;
90 };
91
92#ifndef pid_t
93#define pid_t int
94#endif /* */
95
96#ifndef WEXITSTATUS
97#define WEXITSTATUS(status) (((status) & 0xff00) >> 8)
98#endif /* */
99
100/* Thanks to the Cygwin project */
101#define ENOCSI 43 /* No CSI structure available */
102#define EL2HLT 44 /* Level 2 halted */
103#ifndef EDEADLK
104#define EDEADLK 45 /* Deadlock condition */
105#endif /* */
106#ifndef ENOLCK
107#define ENOLCK 46 /* No record locks available */
108#endif /* */
109#define EBADE 50 /* Invalid exchange */
110#define EBADR 51 /* Invalid request descriptor */
111#define EXFULL 52 /* Exchange full */
112#define ENOANO 53 /* No anode */
113#define EBADRQC 54 /* Invalid request code */
114#define EBADSLT 55 /* Invalid slot */
115#ifndef EDEADLOCK
116#define EDEADLOCK EDEADLK /* File locking deadlock error */
117#endif /* */
118#define EBFONT 57 /* Bad font file fmt */
119#define ENOSTR 60 /* Device not a stream */
120#define ENODATA 61 /* No data (for no delay io) */
121#define ETIME 62 /* Timer expired */
122#define ENOSR 63 /* Out of streams resources */
123#define ENONET 64 /* Machine is not on the network */
124#define ENOPKG 65 /* Package not installed */
125#define EREMOTE 66 /* The object is remote */
126#define ENOLINK 67 /* The link has been severed */
127#define EADV 68 /* Advertise error */
128#define ESRMNT 69 /* Srmount error */
129#define ECOMM 70 /* Communication error on send */
130#define EPROTO 71 /* Protocol error */
131#define EMULTIHOP 74 /* Multihop attempted */
132#define ELBIN 75 /* Inode is remote (not really error) */
133#define EDOTDOT 76 /* Cross mount point (not really error) */
134#define EBADMSG 77 /* Trying to read unreadable message */
135#define ENOTUNIQ 80 /* Given log. name not unique */
136#define EBADFD 81 /* f.d. invalid for this operation */
137#define EREMCHG 82 /* Remote address changed */
138#define ELIBACC 83 /* Can't access a needed shared lib */
139#define ELIBBAD 84 /* Accessing a corrupted shared lib */
140#define ELIBSCN 85 /* .lib section in a.out corrupted */
141#define ELIBMAX 86 /* Attempting to link in too many libs */
142#define ELIBEXEC 87 /* Attempting to exec a shared library */
143#ifndef ENOSYS
144#define ENOSYS 88 /* Function not implemented */
145#endif /* */
146#define ENMFILE 89 /* No more files */
147#ifndef ENOTEMPTY
148#define ENOTEMPTY 90 /* Directory not empty */
149#endif /* */
150#ifndef ENAMETOOLONG
151#define ENAMETOOLONG 91 /* File or path name too long */
152#endif /* */
153#define ELOOP 92 /* Too many symbolic links */
154#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
155#define EPFNOSUPPORT 96 /* Protocol family not supported */
156#define ECONNRESET 104 /* Connection reset by peer */
157#define ENOBUFS 105 /* No buffer space available */
158#define EAFNOSUPPORT 106 /* Address family not supported by protocol family */
159#define EPROTOTYPE 107 /* Protocol wrong type for socket */
160#define ENOTSOCK 108 /* Socket operation on non-socket */
161#define ENOPROTOOPT 109 /* Protocol not available */
162#define ESHUTDOWN 110 /* Can't send after socket shutdown */
163#define ECONNREFUSED 111 /* Connection refused */
164#define EADDRINUSE 112 /* Address already in use */
165#define ECONNABORTED 113 /* Connection aborted */
166#define ENETUNREACH 114 /* Network is unreachable */
167#define ENETDOWN 115 /* Network interface is not configured */
168#ifndef ETIMEDOUT
169#define ETIMEDOUT 116 /* Connection timed out */
170#endif /* */
171#define EHOSTDOWN 117 /* Host is down */
172#define EHOSTUNREACH 118 /* Host is unreachable */
173#define EINPROGRESS 119 /* Connection already in progress */
174#define EALREADY 120 /* Socket already connected */
175#define EDESTADDRREQ 121 /* Destination address required */
176#define EMSGSIZE 122 /* Message too long */
177#define EPROTONOSUPPORT 123 /* Unknown protocol */
178#define ESOCKTNOSUPPORT 124 /* Socket type not supported */
179#define EADDRNOTAVAIL 125 /* Address not available */
180#define ENETRESET 126 /* Connection aborted by network */
181#define EISCONN 127 /* Socket is already connected */
182#define ENOTCONN 128 /* Socket is not connected */
183#define ETOOMANYREFS 129 /* Too many references: cannot splice */
184#define EPROCLIM 130 /* Too many processes */
185#define EUSERS 131 /* Too many users */
186#define EDQUOT 132 /* Disk quota exceeded */
187#define ESTALE 133 /* Unknown error */
188#ifndef ENOTSUP
189#define ENOTSUP 134 /* Not supported */
190#endif /* */
191#define ENOMEDIUM 135 /* No medium (in tape drive) */
192#define ENOSHARE 136 /* No such host or network path */
193#define ECASECLASH 137 /* Filename exists with different case */
194#define EWOULDBLOCK EAGAIN /* Operation would block */
195#define EOVERFLOW 139 /* Value too large for defined data type */
196
197#undef HOST_NOT_FOUND
198#define HOST_NOT_FOUND 1
199#undef TRY_AGAIN
200#define TRY_AGAIN 2
201#undef NO_RECOVERY
202#define NO_RECOVERY 3
203#undef NO_ADDRESS
204#define NO_ADDRESS 4
205
206#define PROT_READ 0x1
207#define PROT_WRITE 0x2
208#define MAP_SHARED 0x1
209#define MAP_PRIVATE 0x2 /* unsupported */
210#define MAP_FIXED 0x10
211#define MAP_FAILED ((void *)-1)
212 struct statfs
213 {
214 long f_type; /* type of filesystem (see below) */
215 long f_bsize; /* optimal transfer block size */
216 long f_blocks; /* total data blocks in file system */
217 long f_bfree; /* free blocks in fs */
218 long f_bavail; /* free blocks avail to non-superuser */
219 long f_files; /* total file nodes in file system */
220 long f_ffree; /* free file nodes in fs */
221 long f_fsid; /* file system id */
222 long f_namelen; /* maximum length of filenames */
223 long f_spare[6]; /* spare for later */
224 };
225 extern const struct in6_addr in6addr_any; /* :: */
226 extern const struct in6_addr in6addr_loopback; /* ::1 */
227
228/* Taken from the Wine project <http://www.winehq.org>
229 /wine/include/winternl.h */
230 enum SYSTEM_INFORMATION_CLASS
231 { SystemBasicInformation = 0, Unknown1, SystemPerformanceInformation = 2, SystemTimeOfDayInformation = 3, /* was SystemTimeInformation */
232 Unknown4, SystemProcessInformation =
233 5, Unknown6, Unknown7, SystemProcessorPerformanceInformation =
234 8, Unknown9, Unknown10, SystemDriverInformation, Unknown12,
235 Unknown13, Unknown14, Unknown15, SystemHandleList, Unknown17,
236 Unknown18, Unknown19, Unknown20, SystemCacheInformation,
237 Unknown22, SystemInterruptInformation =
238 23, SystemExceptionInformation =
239 33, SystemRegistryQuotaInformation = 37, SystemLookasideInformation = 45
240 };
241 typedef struct
242 {
243 LARGE_INTEGER IdleTime;
244 LARGE_INTEGER KernelTime;
245 LARGE_INTEGER UserTime;
246 LARGE_INTEGER Reserved1[2];
247 ULONG Reserved2;
248 } SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
249
250#define sleep(secs) (Sleep(secs * 1000))
251
252/*********************** statfs *****************************/
253/* fake block size */
254#define FAKED_BLOCK_SIZE 512
255
256/* linux-compatible values for fs type */
257#define MSDOS_SUPER_MAGIC 0x4d44
258#define NTFS_SUPER_MAGIC 0x5346544E
259
260/*********************** End of statfs ***********************/
261
262#define SHUT_RDWR SD_BOTH
263
264/* Operations for flock() */
265#define LOCK_SH 1 /* shared lock */
266#define LOCK_EX 2 /* exclusive lock */
267#define LOCK_NB 4 /* or'd with one of the above to prevent
268 blocking */
269#define LOCK_UN 8 /* remove lock */
270
271/* Not supported under MinGW */
272#define S_IRGRP 0
273#define S_IWGRP 0
274#define S_IROTH 0
275#define S_IXGRP 0
276#define S_IWOTH 0
277#define S_IXOTH 0
278#define S_ISUID 0
279#define S_ISGID 0
280#define S_ISVTX 0
281#define S_IRWXG 0
282#define S_IRWXO 0
283
284#define SHUT_WR SD_SEND
285#define SHUT_RD SD_RECEIVE
286#define SHUT_RDWR SD_BOTH
287
288#define SIGKILL 9
289#define SIGTERM 15
290
291#define SetErrnoFromWinError(e) _SetErrnoFromWinError(e, __FILE__, __LINE__)
292 BOOL _plibc_CreateShortcut (const char *pszSrc, const char *pszDest);
293 BOOL _plibc_DereferenceShortcut (char *pszShortcut);
294 char *plibc_ChooseDir (char *pszTitle, unsigned long ulFlags);
295 char *plibc_ChooseFile (char *pszTitle, unsigned long ulFlags);
296 long QueryRegistry (HKEY hMainKey, char *pszKey, char *pszSubKey,
297 char *pszBuffer, long *pdLength);
298 BOOL __win_IsHandleMarkedAsBlocking (SOCKET hHandle);
299 void __win_SetHandleBlockingMode (SOCKET s, BOOL bBlocking);
300 void __win_DiscardHandleBlockingMode (SOCKET s);
301 int _win_isSocketValid (int s);
302 int plibc_conv_to_win_path (const char *pszUnix, char *pszWindows);
303 unsigned plibc_get_handle_count ();
304 typedef void (*TPanicProc) (int, char *);
305 void plibc_set_panic_proc (TPanicProc proc);
306 int flock (int fd, int operation);
307 int fsync (int fildes);
308 int inet_pton (int af, const char *src, void *dst);
309 int inet_pton4 (const char *src, u_char * dst, int pton);
310
311#if USE_IPV6
312 int inet_pton6 (const char *src, u_char * dst);
313
314#endif /* */
315 int truncate (const char *fname, int distance);
316 int statfs (const char *path, struct statfs *buf);
317 const char *hstrerror (int err);
318 void gettimeofday (struct timeval *tp, void *tzp);
319 int mkstemp (char *tmplate);
320 char *strptime (const char *buf, const char *format, struct tm *tm);
321 char *ctime (const time_t * clock);
322 char *ctime_r (const time_t * clock, char *buf);
323 const char *inet_ntop (int af, const void *src, char *dst, size_t size);
324 int plibc_init (char *pszOrg, char *pszApp);
325 void plibc_shutdown ();
326 int plibc_initialized ();
327 int plibc_conv_to_win_path_ex (const char *pszUnix, char *pszWindows,
328 int derefLinks);
329 void _SetErrnoFromWinError (long lWinError, char *pszCaller, int iLine);
330 void SetErrnoFromWinsockError (long lWinError);
331 void SetHErrnoFromWinError (long lWinError);
332 void SetErrnoFromHRESULT (HRESULT hRes);
333 FILE *_win_fopen (const char *filename, const char *mode);
334 DIR *_win_opendir (const char *dirname);
335 int _win_open (const char *filename, int oflag, ...);
336
337#ifdef ENABLE_NLS
338 char *_win_bindtextdomain (const char *domainname, const char *dirname);
339
340#endif /* */
341 int _win_chdir (const char *path);
342 int _win_close (int fd);
343 int _win_creat (const char *path, mode_t mode);
344 int _win_fstat (int handle, struct stat *buffer);
345 int _win_ftruncate (int fildes, off_t length);
346 int _win_kill (pid_t pid, int sig);
347 int _win_pipe (int *phandles);
348 int _win_rmdir (const char *path);
349 int _win_access (const char *path, int mode);
350 int _win_chmod (const char *filename, int pmode);
351 char *realpath (const char *file_name, char *resolved_name);
352 long _win_random (void);
353 int _win_remove (const char *path);
354 int _win_rename (const char *oldname, const char *newname);
355 int _win_stat (const char *path, struct stat *buffer);
356 int _win_stat64 (const char *path, struct stat64 *buffer);
357 int _win_unlink (const char *filename);
358 int _win_write (int fildes, const void *buf, size_t nbyte);
359 int _win_read (int fildes, void *buf, size_t nbyte);
360 size_t _win_fwrite (const void *buffer, size_t size, size_t count,
361 FILE * stream);
362 size_t _win_fread (void *buffer, size_t size, size_t count, FILE * stream);
363 int _win_symlink (const char *path1, const char *path2);
364 void *_win_mmap (void *start, size_t len, int access, int flags, int fd,
365 unsigned long long offset);
366 int _win_munmap (void *start, size_t length);
367 int _win_lstat (const char *path, struct stat *buf);
368 int _win_lstat64 (const char *path, struct stat64 *buf);
369 int _win_readlink (const char *path, char *buf, size_t bufsize);
370 int _win_accept (SOCKET s, struct sockaddr *addr, int *addrlen);
371 int _win_printf (const char *format, ...);
372 int _win_fprintf (FILE * f, const char *format, ...);
373 int _win_vprintf (const char *format, va_list ap);
374 int _win_vfprintf (FILE * stream, const char *format, va_list arg_ptr);
375 int _win_vsprintf (char *dest, const char *format, va_list arg_ptr);
376 int _win_vsnprintf (char *str, size_t size, const char *format,
377 va_list arg_ptr);
378 int _win_snprintf (char *str, size_t size, const char *format, ...);
379 int _win_sprintf (char *dest, const char *format, ...);
380 int _win_vsscanf (const char *str, const char *format, va_list arg_ptr);
381 int _win_sscanf (const char *str, const char *format, ...);
382 int _win_vfscanf (FILE * stream, const char *format, va_list arg_ptr);
383 int _win_vscanf (const char *format, va_list arg_ptr);
384 int _win_scanf (const char *format, ...);
385 int _win_fscanf (FILE * stream, const char *format, ...);
386 pid_t _win_waitpid (pid_t pid, int *stat_loc, int options);
387 int _win_bind (SOCKET s, const struct sockaddr *name, int namelen);
388 int _win_connect (SOCKET s, const struct sockaddr *name, int namelen);
389 int _win_getpeername (SOCKET s, struct sockaddr *name, int *namelen);
390 int _win_getsockname (SOCKET s, struct sockaddr *name, int *namelen);
391 int _win_getsockopt (SOCKET s, int level, int optname, char *optval,
392 int *optlen);
393 int _win_listen (SOCKET s, int backlog);
394 int _win_recv (SOCKET s, char *buf, int len, int flags);
395 int _win_recvfrom (SOCKET s, void *buf, int len, int flags,
396 struct sockaddr *from, int *fromlen);
397 int _win_select (int max_fd, fd_set * rfds, fd_set * wfds, fd_set * efds,
398 const struct timeval *tv);
399 int _win_send (SOCKET s, const char *buf, int len, int flags);
400 int _win_sendto (SOCKET s, const char *buf, int len, int flags,
401 const struct sockaddr *to, int tolen);
402 int _win_setsockopt (SOCKET s, int level, int optname, const void *optval,
403 int optlen);
404 int _win_shutdown (SOCKET s, int how);
405 SOCKET _win_socket (int af, int type, int protocol);
406 struct hostent *_win_gethostbyaddr (const char *addr, int len, int type);
407 struct hostent *_win_gethostbyname (const char *name);
408 struct hostent *gethostbyname2 (const char *name, int af);
409 char *_win_strerror (int errnum);
410 int IsWinNT ();
411 char *index (const char *s, int c);
412
413#if !HAVE_STRNDUP
414 char *strndup (const char *s, size_t n);
415
416#endif /* */
417#if !HAVE_STRNLEN
418 size_t strnlen (const char *str, size_t maxlen);
419
420#endif /* */
421
422#define strcasecmp(a, b) stricmp(a, b)
423#define strncasecmp(a, b, c) strnicmp(a, b, c)
424
425#endif /* WINDOWS */
426
427#ifndef WINDOWS
428#define DIR_SEPARATOR '/'
429#define DIR_SEPARATOR_STR "/"
430#define PATH_SEPARATOR ';'
431#define PATH_SEPARATOR_STR ";"
432#define NEWLINE "\n"
433
434#ifdef ENABLE_NLS
435#define BINDTEXTDOMAIN(d, n) bindtextdomain(d, n)
436#endif /* */
437#define CREAT(p, m) creat(p, m)
438#undef FOPEN
439#define FOPEN(f, m) fopen(f, m)
440#define FTRUNCATE(f, l) ftruncate(f, l)
441#define OPENDIR(d) opendir(d)
442#define OPEN open
443#define CHDIR(d) chdir(d)
444#define CLOSE(f) close(f)
445#define LSEEK(f, o, w) lseek(f, o, w)
446#define RMDIR(f) rmdir(f)
447#define ACCESS(p, m) access(p, m)
448#define CHMOD(f, p) chmod(f, p)
449#define FSTAT(h, b) fstat(h, b)
450#define PLIBC_KILL(p, s) kill(p, s)
451#define PIPE(h) pipe(h)
452#define REMOVE(p) remove(p)
453#define RENAME(o, n) rename(o, n)
454#define STAT(p, b) stat(p, b)
455#define STAT64(p, b) stat64(p, b)
456#define UNLINK(f) unlink(f)
457#define WRITE(f, b, n) write(f, b, n)
458#define READ(f, b, n) read(f, b, n)
459#define GN_FREAD(b, s, c, f) fread(b, s, c, f)
460#define GN_FWRITE(b, s, c, f) fwrite(b, s, c, f)
461#define SYMLINK(a, b) symlink(a, b)
462#define MMAP(s, l, p, f, d, o) mmap(s, l, p, f, d, o)
463#define MUNMAP(s, l) munmap(s, l)
464#define STRERROR(i) strerror(i)
465#define RANDOM() random()
466#define READLINK(p, b, s) readlink(p, b, s)
467#define LSTAT(p, b) lstat(p, b)
468#define LSTAT64(p, b) lstat64(p, b)
469#define PRINTF printf
470#define FPRINTF fprintf
471#define VPRINTF(f, a) vprintf(f, a)
472#define VFPRINTF(s, f, a) vfprintf(s, f, a)
473#define VSPRINTF(d, f, a) vsprintf(d, f, a)
474#define VSNPRINTF(str, size, fmt, a) vsnprintf(str, size, fmt, a)
475#define _REAL_SNPRINTF snprintf
476#define SPRINTF sprintf
477#define VSSCANF(s, f, a) vsscanf(s, f, a)
478#define SSCANF sscanf
479#define VFSCANF(s, f, a) vfscanf(s, f, a)
480#define VSCANF(f, a) vscanf(f, a)
481#define SCANF scanf
482#define FSCANF fscanf
483#define WAITPID(p, s, o) waitpid(p, s, o)
484#define ACCEPT(s, a, l) accept(s, a, l)
485#define BIND(s, n, l) bind(s, n, l)
486#define CONNECT(s, n, l) connect(s, n, l)
487#define GETPEERNAME(s, n, l) getpeername(s, n, l)
488#define GETSOCKNAME(s, n, l) getsockname(s, n, l)
489#define GETSOCKOPT(s, l, o, v, p) getsockopt(s, l, o, v, p)
490#define LISTEN(s, b) listen(s, b)
491#define RECV(s, b, l, f) recv(s, b, l, f)
492#define RECVFROM(s, b, l, f, r, o) recvfrom(s, b, l, f, r, o)
493#define SELECT(n, r, w, e, t) select(n, r, w, e, t)
494#define SEND(s, b, l, f) send(s, b, l, f)
495#define SENDTO(s, b, l, f, o, n) sendto(s, b, l, f, o, n)
496#define SETSOCKOPT(s, l, o, v, n) setsockopt(s, l, o, v, n)
497#define SHUTDOWN(s, h) shutdown(s, h)
498#define SOCKET(a, t, p) socket(a, t, p)
499#define GETHOSTBYADDR(a, l, t) gethostbyname(a, l, t)
500#define GETHOSTBYNAME(n) gethostbyname(n)
501#else /* */
502#define DIR_SEPARATOR '\\'
503#define DIR_SEPARATOR_STR "\\"
504#define PATH_SEPARATOR ':'
505#define PATH_SEPARATOR_STR ":"
506#define NEWLINE "\r\n"
507
508#ifdef ENABLE_NLS
509#define BINDTEXTDOMAIN(d, n) _win_bindtextdomain(d, n)
510#endif /* */
511#define CREAT(p, m) _win_creat(p, m)
512#define FOPEN(f, m) _win_fopen(f, m)
513#define FTRUNCATE(f, l) _win_ftruncate(f, l)
514#define OPENDIR(d) _win_opendir(d)
515#define OPEN _win_open
516#define CHDIR(d) _win_chdir(d)
517#define CLOSE(f) _win_close(f)
518#define PLIBC_KILL(p, s) _win_kill(p, s)
519#define LSEEK(f, o, w) _win_lseek(f, o, w)
520#define FSTAT(h, b) _win_fstat(h, b)
521#define RMDIR(f) _win_rmdir(f)
522#define ACCESS(p, m) _win_access(p, m)
523#define CHMOD(f, p) _win_chmod(f, p)
524#define PIPE(h) _win_pipe(h)
525#define RANDOM() _win_random()
526#define REMOVE(p) _win_remove(p)
527#define RENAME(o, n) _win_rename(o, n)
528#define STAT(p, b) _win_stat(p, b)
529#define STAT64(p, b) _win_stat64(p, b)
530#define UNLINK(f) _win_unlink(f)
531#define WRITE(f, b, n) _win_write(f, b, n)
532#define READ(f, b, n) _win_read(f, b, n)
533#define GN_FREAD(b, s, c, f) _win_fread(b, s, c, f)
534#define GN_FWRITE(b, s, c, f) _win_fwrite(b, s, c, f)
535#define SYMLINK(a, b) _win_symlink(a, b)
536#define MMAP(s, l, p, f, d, o) _win_mmap(s, l, p, f, d, o)
537#define MUNMAP(s, l) _win_munmap(s, l)
538#define STRERROR(i) _win_strerror(i)
539#define READLINK(p, b, s) _win_readlink(p, b, s)
540#define LSTAT(p, b) _win_lstat(p, b)
541#define LSTAT64(p, b) _win_lstat64(p, b)
542#define PRINTF(f, ...) _win_printf(f , __VA_ARGS__)
543#define FPRINTF(fil, fmt, ...) _win_fprintf(fil, fmt, __VA_ARGS__)
544#define VPRINTF(f, a) _win_vprintf(f, a)
545#define VFPRINTF(s, f, a) _win_vfprintf(s, f, a)
546#define VSPRINTF(d, f, a) _win_vsprintf(d, f, a)
547#define VSNPRINTF(str, size, fmt, a) _win_vsnprintf(str, size, fmt, a)
548#define _REAL_SNPRINTF(str, size, fmt, ...) _win_snprintf(str, size, fmt, __VA_ARGS__)
549#define SPRINTF(d, f, ...) _win_sprintf(d, f, __VA_ARGS__)
550#define VSSCANF(s, f, a) _win_vsscanf(s, f, a)
551#define SSCANF(s, f, ...) _win_sscanf(s, f, __VA_ARGS__)
552#define VFSCANF(s, f, a) _win_vfscanf(s, f, a)
553#define VSCANF(f, a) _win_vscanf(f, a)
554#define SCANF(f, ...) _win_scanf(f, __VA_ARGS__)
555#define FSCANF(s, f, ...) _win_fscanf(s, f, __VA_ARGS__)
556#define WAITPID(p, s, o) _win_waitpid(p, s, o)
557#define ACCEPT(s, a, l) _win_accept(s, a, l)
558#define BIND(s, n, l) _win_bind(s, n, l)
559#define CONNECT(s, n, l) _win_connect(s, n, l)
560#define GETPEERNAME(s, n, l) _win_getpeername(s, n, l)
561#define GETSOCKNAME(s, n, l) _win_getsockname(s, n, l)
562#define GETSOCKOPT(s, l, o, v, p) _win_getsockopt(s, l, o, v, p)
563#define LISTEN(s, b) _win_listen(s, b)
564#define RECV(s, b, l, f) _win_recv(s, b, l, f)
565#define RECVFROM(s, b, l, f, r, o) _win_recvfrom(s, b, l, f, r, o)
566#define SELECT(n, r, w, e, t) _win_select(n, r, w, e, t)
567#define SEND(s, b, l, f) _win_send(s, b, l, f)
568#define SENDTO(s, b, l, f, o, n) _win_sendto(s, b, l, f, o, n)
569#define SETSOCKOPT(s, l, o, v, n) _win_setsockopt(s, l, o, v, n)
570#define SHUTDOWN(s, h) _win_shutdown(s, h)
571#define SOCKET(a, t, p) _win_socket(a, t, p)
572#define GETHOSTBYADDR(a, l, t) _win_gethostbyname(a, l, t)
573#define GETHOSTBYNAME(n) _win_gethostbyname(n)
574#endif /* */
575
576#ifdef __cplusplus
577}
578#endif /* */
579
580#endif //_PLIBC_H_
581
582/* end of plibc.h */
diff --git a/src/include/winproc.h b/src/include/winproc.h
new file mode 100644
index 000000000..a4a173a13
--- /dev/null
+++ b/src/include/winproc.h
@@ -0,0 +1,216 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005 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 2, 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 util/winproc.h
23 * @brief Definitions for MS Windows
24 * @author Nils Durner
25 **/
26
27#ifndef _WINPROC_H
28#define _WINPROC_H
29
30#include <io.h>
31#include <stdio.h>
32#include <sys/types.h>
33#include <sys/stat.h>
34#include <sys/timeb.h>
35#include <time.h>
36#include <dirent.h>
37#include <windows.h>
38#include <winsock.h>
39#include <winerror.h>
40#include <iphlpapi.h>
41#include <shlobj.h>
42#include <objbase.h>
43#include <sys/param.h> /* #define BYTE_ORDER */
44#include <Ntsecapi.h>
45#include <lm.h>
46#include <Aclapi.h>
47#include "gnunet_util.h"
48#include "platform.h"
49
50#ifdef __cplusplus
51extern "C"
52{
53#endif
54
55#ifndef MAX_NAME_LENGTH
56#define MAX_NAME_LENGTH 25
57#endif
58
59 typedef DWORD WINAPI (*TNtQuerySystemInformation) (int, PVOID, ULONG,
60 PULONG);
61 typedef DWORD WINAPI (*TGetIfEntry) (PMIB_IFROW pIfRow);
62 typedef DWORD WINAPI (*TGetIpAddrTable) (PMIB_IPADDRTABLE pIpAddrTable,
63 PULONG pdwSize, BOOL bOrder);
64 typedef DWORD WINAPI (*TGetIfTable) (PMIB_IFTABLE pIfTable, PULONG pdwSize,
65 BOOL bOrder);
66 typedef DWORD WINAPI (*TCreateHardLink) (LPCTSTR lpFileName,
67 LPCTSTR lpExistingFileName,
68 LPSECURITY_ATTRIBUTES
69 lpSecurityAttributes);
70 typedef SC_HANDLE WINAPI (*TOpenSCManager) (LPCTSTR lpMachineName,
71 LPCTSTR lpDatabaseName,
72 DWORD dwDesiredAccess);
73 typedef SC_HANDLE WINAPI (*TCreateService) (SC_HANDLE hSCManager,
74 LPCTSTR lpServiceName,
75 LPCTSTR lpDisplayName,
76 DWORD dwDesiredAccess,
77 DWORD dwServiceType,
78 DWORD dwStartType,
79 DWORD dwErrorControl,
80 LPCTSTR lpBinaryPathName,
81 LPCTSTR lpLoadOrderGroup,
82 LPDWORD lpdwTagId,
83 LPCTSTR lpDependencies,
84 LPCTSTR lpServiceStartName,
85 LPCTSTR lpPassword);
86 typedef BOOL WINAPI (*TCloseServiceHandle) (SC_HANDLE hSCObject);
87 typedef BOOL WINAPI (*TDeleteService) (SC_HANDLE hService);
88 typedef SERVICE_STATUS_HANDLE WINAPI (*TRegisterServiceCtrlHandler) (LPCTSTR
89 lpServiceName,
90 LPHANDLER_FUNCTION
91 lpHandlerProc);
92 typedef BOOL WINAPI (*TSetServiceStatus) (SERVICE_STATUS_HANDLE
93 hServiceStatus,
94 LPSERVICE_STATUS lpServiceStatus);
95 typedef BOOL WINAPI (*TStartServiceCtrlDispatcher) (const
96 LPSERVICE_TABLE_ENTRY
97 lpServiceTable);
98 typedef BOOL WINAPI (*TControlService) (SC_HANDLE hService, DWORD dwControl,
99 LPSERVICE_STATUS lpServiceStatus);
100 typedef SC_HANDLE WINAPI (*TOpenService) (SC_HANDLE hSCManager,
101 LPCTSTR lpServiceName,
102 DWORD dwDesiredAccess);
103 typedef DWORD WINAPI (*TGetBestInterface) (IPAddr dwDestAddr,
104 PDWORD pdwBestIfIndex);
105 typedef DWORD WINAPI (*TGetAdaptersInfo) (PIP_ADAPTER_INFO pAdapterInfo,
106 PULONG pOutBufLen);
107 typedef NET_API_STATUS WINAPI (*TNetUserAdd) (LPCWSTR, DWORD, PBYTE,
108 PDWORD);
109 typedef NET_API_STATUS WINAPI (*TNetUserSetInfo) (LPCWSTR servername,
110 LPCWSTR username,
111 DWORD level, LPBYTE buf,
112 LPDWORD parm_err);
113 typedef NTSTATUS NTAPI (*TLsaOpenPolicy) (PLSA_UNICODE_STRING,
114 PLSA_OBJECT_ATTRIBUTES,
115 ACCESS_MASK, PLSA_HANDLE);
116 typedef NTSTATUS NTAPI (*TLsaAddAccountRights) (LSA_HANDLE, PSID,
117 PLSA_UNICODE_STRING, ULONG);
118 typedef NTSTATUS NTAPI (*TLsaRemoveAccountRights) (LSA_HANDLE, PSID,
119 BOOLEAN,
120 PLSA_UNICODE_STRING,
121 ULONG);
122 typedef NTSTATUS NTAPI (*TLsaClose) (LSA_HANDLE);
123 typedef BOOL WINAPI (*TLookupAccountName) (LPCTSTR lpSystemName,
124 LPCTSTR lpAccountName, PSID Sid,
125 LPDWORD cbSid,
126 LPTSTR ReferencedDomainName,
127 LPDWORD cchReferencedDomainName,
128 PSID_NAME_USE peUse);
129
130 typedef BOOL WINAPI (*TGetFileSecurity) (LPCTSTR lpFileName,
131 SECURITY_INFORMATION
132 RequestedInformation,
133 PSECURITY_DESCRIPTOR
134 pSecurityDescriptor, DWORD nLength,
135 LPDWORD lpnLengthNeeded);
136 typedef BOOL WINAPI (*TInitializeSecurityDescriptor) (PSECURITY_DESCRIPTOR
137 pSecurityDescriptor,
138 DWORD dwRevision);
139 typedef BOOL WINAPI (*TGetSecurityDescriptorDacl) (PSECURITY_DESCRIPTOR
140 pSecurityDescriptor,
141 LPBOOL lpbDaclPresent,
142 PACL * pDacl,
143 LPBOOL lpbDaclDefaulted);
144 typedef BOOL WINAPI (*TGetAclInformation) (PACL pAcl,
145 LPVOID pAclInformation,
146 DWORD nAclInformationLength,
147 ACL_INFORMATION_CLASS
148 dwAclInformationClass);
149 typedef BOOL WINAPI (*TInitializeAcl) (PACL pAcl, DWORD nAclLength,
150 DWORD dwAclRevision);
151 typedef BOOL WINAPI (*TGetAce) (PACL pAcl, DWORD dwAceIndex, LPVOID * pAce);
152 typedef BOOL WINAPI (*TEqualSid) (PSID pSid1, PSID pSid2);
153 typedef BOOL WINAPI (*TAddAce) (PACL pAcl, DWORD dwAceRevision,
154 DWORD dwStartingAceIndex, LPVOID pAceList,
155 DWORD nAceListLength);
156 typedef BOOL WINAPI (*TAddAccessAllowedAce) (PACL pAcl, DWORD dwAceRevision,
157 DWORD AccessMask, PSID pSid);
158 typedef BOOL WINAPI (*TSetNamedSecurityInfo) (LPTSTR pObjectName,
159 SE_OBJECT_TYPE ObjectType,
160 SECURITY_INFORMATION
161 SecurityInfo, PSID psidOwner,
162 PSID psidGroup, PACL pDacl,
163 PACL pSacl);
164
165 extern TNtQuerySystemInformation GNNtQuerySystemInformation;
166 extern TGetIfEntry GNGetIfEntry;
167 extern TGetIpAddrTable GNGetIpAddrTable;
168 extern TGetIfTable GNGetIfTable;
169 extern TCreateHardLink GNCreateHardLink;
170 extern TOpenSCManager GNOpenSCManager;
171 extern TCreateService GNCreateService;
172 extern TCloseServiceHandle GNCloseServiceHandle;
173 extern TDeleteService GNDeleteService;
174 extern TRegisterServiceCtrlHandler GNRegisterServiceCtrlHandler;
175 extern TSetServiceStatus GNSetServiceStatus;
176 extern TStartServiceCtrlDispatcher GNStartServiceCtrlDispatcher;
177 extern TControlService GNControlService;
178 extern TOpenService GNOpenService;
179 extern TGetBestInterface GNGetBestInterface;
180 extern TGetAdaptersInfo GGetAdaptersInfo;
181 extern TNetUserAdd GNNetUserAdd;
182 extern TNetUserSetInfo GNNetUserSetInfo;
183 extern TLsaOpenPolicy GNLsaOpenPolicy;
184 extern TLsaAddAccountRights GNLsaAddAccountRights;
185 extern TLsaRemoveAccountRights GNLsaRemoveAccountRights;
186 extern TLsaClose GNLsaClose;
187 extern TLookupAccountName GNLookupAccountName;
188 extern TGetFileSecurity GNGetFileSecurity;
189 extern TInitializeSecurityDescriptor GNInitializeSecurityDescriptor;
190 extern TGetSecurityDescriptorDacl GNGetSecurityDescriptorDacl;
191 extern TGetAclInformation GNGetAclInformation;
192 extern TInitializeAcl GNInitializeAcl;
193 extern TGetAce GNGetAce;
194 extern TEqualSid GNEqualSid;
195 extern TAddAce GNAddAce;
196 extern TAddAccessAllowedAce GNAddAccessAllowedAce;
197 extern TSetNamedSecurityInfo GNSetNamedSecurityInfo;
198
199
200 BOOL CreateShortcut (const char *pszSrc, const char *pszDest);
201 BOOL DereferenceShortcut (char *pszShortcut);
202 long QueryRegistry (HKEY hMainKey, char *pszKey, char *pszSubKey,
203 char *pszBuffer, long *pdLength);
204 int ListNICs (void (*callback) (const char *, int, void *), void *cls);
205 BOOL AddPathAccessRights (char *lpszFileName, char *lpszAccountName,
206 DWORD dwAccessMask);
207 char *winErrorStr (const char *prefix, int dwErr);
208
209 void GNInitWinEnv ();
210 void GNShutdownWinEnv ();
211
212#ifdef __cplusplus
213}
214#endif
215
216#endif
diff --git a/src/peerinfo/Makefile.am b/src/peerinfo/Makefile.am
new file mode 100644
index 000000000..294ff5cca
--- /dev/null
+++ b/src/peerinfo/Makefile.am
@@ -0,0 +1,56 @@
1INCLUDES = -I$(top_srcdir)/src/include
2
3if MINGW
4 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols -lole32 -lshell32 -luuid -liconv -lstdc++ -lcomdlg32 -lgdi32
5endif
6
7if USE_COVERAGE
8 AM_CFLAGS = -fprofile-arcs -ftest-coverage
9endif
10
11lib_LTLIBRARIES = libgnunetpeerinfo.la
12
13libgnunetpeerinfo_la_SOURCES = \
14 peerinfo_api.c peerinfo.h
15libgnunetpeerinfo_la_LIBADD = \
16 $(top_builddir)/src/hello/libgnunethello.la \
17 $(top_builddir)/src/util/libgnunetutil.la
18libgnunetpeerinfo_la_LDFLAGS = \
19 $(GN_LIB_LDFLAGS) $(WINFLAGS) \
20 -version-info 0:0:0
21
22
23bin_PROGRAMS = \
24 gnunet-peerinfo \
25 gnunet-service-peerinfo
26
27gnunet_peerinfo_SOURCES = \
28 gnunet-peerinfo.c
29gnunet_peerinfo_LDADD = \
30 $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
31 $(top_builddir)/src/util/libgnunetutil.la
32
33gnunet_service_peerinfo_SOURCES = \
34 gnunet-service-peerinfo.c
35gnunet_service_peerinfo_LDADD = \
36 $(top_builddir)/src/hello/libgnunethello.la \
37 $(top_builddir)/src/util/libgnunetutil.la
38
39
40check_PROGRAMS = \
41 test_peerinfo_api
42
43TESTS = $(check_PROGRAMS) # $(check_SCRIPTS)
44
45test_peerinfo_api_SOURCES = \
46 test_peerinfo_api.c
47test_peerinfo_api_LDADD = \
48 $(top_builddir)/src/hello/libgnunethello.la \
49 $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
50 $(top_builddir)/src/util/libgnunetutil.la
51
52EXTRA_DIST = \
53 test_peerinfo_api_data.conf
54
55#check_SCRIPTS = \
56# test_gnunet_peerinfo.sh
diff --git a/src/peerinfo/gnunet-peerinfo.c b/src/peerinfo/gnunet-peerinfo.c
new file mode 100644
index 000000000..6c737c88a
--- /dev/null
+++ b/src/peerinfo/gnunet-peerinfo.c
@@ -0,0 +1,152 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2006, 2009 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 2, 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 peerinfo/gnunet-peerinfo.c
23 * @brief Print information about other known peers.
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_crypto_lib.h"
28#include "gnunet_configuration_lib.h"
29#include "gnunet_getopt_lib.h"
30#include "gnunet_peerinfo_service.h"
31#include "gnunet_program_lib.h"
32
33static int no_resolve;
34
35static int be_quiet;
36
37static int get_self;
38
39/**
40 * Print information about the peer.
41 * Currently prints the GNUNET_PeerIdentity, trust and the IP.
42 * Could of course do more (e.g. resolve via DNS).
43 */
44static void
45print_peer_info (void *cls,
46 const struct GNUNET_PeerIdentity *peer,
47 const struct GNUNET_HELLO_Message *hello, uint32_t trust)
48{
49 struct GNUNET_CRYPTO_HashAsciiEncoded enc;
50
51 /* FIXME: add printing of address information!
52 => need extended transport API! */
53 GNUNET_CRYPTO_hash_to_enc (&peer->hashPubKey, &enc);
54 if (be_quiet)
55 printf ("%s\n", (const char *) &enc);
56 else
57 printf (_("Peer `%s' with trust %8u\n"), (const char *) &enc, trust);
58}
59
60/**
61 * Main function that will be run by the scheduler.
62 *
63 * @param cls closure
64 * @param sched the scheduler to use
65 * @param args remaining command-line arguments
66 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
67 * @param cfg configuration
68 */
69static void
70run (void *cls,
71 struct GNUNET_SCHEDULER_Handle *sched,
72 char *const *args,
73 const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *cfg)
74{
75 struct GNUNET_CRYPTO_RsaPrivateKey *priv;
76 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
77 struct GNUNET_PeerIdentity pid;
78 struct GNUNET_CRYPTO_HashAsciiEncoded enc;
79 char *fn;
80
81 if (get_self != GNUNET_YES)
82 {
83 GNUNET_PEERINFO_for_all (cfg,
84 sched,
85 NULL,
86 0,
87 GNUNET_TIME_relative_multiply
88 (GNUNET_TIME_UNIT_SECONDS, 30),
89 &print_peer_info, NULL);
90 }
91 else
92 {
93 if (GNUNET_OK !=
94 GNUNET_CONFIGURATION_get_value_filename (cfg,
95 "GNUNET",
96 "HOSTKEYFILE", &fn))
97 return;
98 priv = GNUNET_CRYPTO_rsa_key_create_from_file (fn);
99 if (priv == NULL)
100 {
101 fprintf (stderr, _("Loading hostkey from `%s' failed.\n"), fn);
102 GNUNET_free (fn);
103 return;
104 }
105 GNUNET_free (fn);
106 GNUNET_CRYPTO_rsa_key_get_public (priv, &pub);
107 GNUNET_CRYPTO_rsa_key_free (priv);
108 GNUNET_CRYPTO_hash (&pub, sizeof (pub), &pid.hashPubKey);
109 GNUNET_CRYPTO_hash_to_enc (&pid.hashPubKey, &enc);
110 if (be_quiet)
111 printf ("%s\n", (char *) &enc);
112 else
113 printf (_("I am peer `%s'.\n"), (const char *) &enc);
114 }
115}
116
117
118/**
119 * gnunet-peerinfo command line options
120 */
121static struct GNUNET_GETOPT_CommandLineOption options[] = {
122 {'n', "numeric", NULL,
123 gettext_noop ("don't resolve host names"),
124 0, &GNUNET_GETOPT_set_one, &no_resolve},
125 {'q', "quiet", NULL,
126 gettext_noop ("output only the identity strings"),
127 0, &GNUNET_GETOPT_set_one, &be_quiet},
128 {'s', "self", NULL,
129 gettext_noop ("output our own identity only"),
130 0, &GNUNET_GETOPT_set_one, &get_self},
131 GNUNET_GETOPT_OPTION_END
132};
133
134/**
135 * The main function to obtain peer information.
136 *
137 * @param argc number of arguments from the command line
138 * @param argv command line arguments
139 * @return 0 ok, 1 on error
140 */
141int
142main (int argc, char *const *argv)
143{
144 return (GNUNET_OK ==
145 GNUNET_PROGRAM_run (argc,
146 argv,
147 "gnunet-peerinfo",
148 gettext_noop ("Print information about peers."),
149 options, &run, NULL)) ? 0 : 1;
150}
151
152/* end of gnunet-peerinfo.c */
diff --git a/src/peerinfo/gnunet-service-peerinfo.c b/src/peerinfo/gnunet-service-peerinfo.c
new file mode 100644
index 000000000..b81c7b6ee
--- /dev/null
+++ b/src/peerinfo/gnunet-service-peerinfo.c
@@ -0,0 +1,708 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2004, 2005, 2007, 2009 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 2, 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 peerinfo/gnunet-service-peerinfo.c
23 * @brief maintains list of known peers
24 *
25 * Code to maintain the list of currently known hosts (in memory
26 * structure of data/hosts/ and data/credit/).
27 *
28 * @author Christian Grothoff
29 */
30
31#include "platform.h"
32#include "gnunet_crypto_lib.h"
33#include "gnunet_disk_lib.h"
34#include "gnunet_hello_lib.h"
35#include "gnunet_protocols.h"
36#include "gnunet_service_lib.h"
37#include "peerinfo.h"
38
39/**
40 * How often do we scan the HOST_DIR for new entries?
41 */
42#define DATA_HOST_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
43
44/**
45 * How often do we flush trust values to disk?
46 */
47#define TRUST_FLUSH_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
48
49/**
50 * How often do we discard old entries in data/hosts/?
51 */
52#define DATA_HOST_CLEAN_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 60)
53
54/**
55 * In-memory cache of known hosts.
56 */
57struct HostEntry
58{
59
60 /**
61 * This is a linked list.
62 */
63 struct HostEntry *next;
64
65 /**
66 * Identity of the peer.
67 */
68 struct GNUNET_PeerIdentity identity;
69
70 /**
71 * Hello for the peer (can be NULL)
72 */
73 struct GNUNET_HELLO_Message *hello;
74
75 /**
76 * Trust rating for this peer
77 */
78 uint32_t trust;
79
80 /**
81 * Trust rating for this peer on disk.
82 */
83 uint32_t disk_trust;
84
85};
86
87/**
88 * The in-memory list of known hosts.
89 */
90static struct HostEntry *hosts;
91
92/**
93 * Directory where the hellos are stored in (data/hosts)
94 */
95static char *networkIdDirectory;
96
97/**
98 * Where do we store trust information?
99 */
100static char *trustDirectory;
101
102
103/**
104 * Address iterator that causes expired entries to be discarded.
105 *
106 * @param cls pointer to the current time
107 * @return GNUNET_NO if expiration smaller than the current time
108 */
109static int
110discard_expired (void *cls,
111 const char *tname,
112 struct GNUNET_TIME_Absolute expiration,
113 const void *addr, size_t addrlen)
114{
115 const struct GNUNET_TIME_Absolute *now = cls;
116 if (now->value > expiration.value)
117 return GNUNET_NO;
118 return GNUNET_OK;
119}
120
121
122/**
123 * Get the filename under which we would store the GNUNET_HELLO_Message
124 * for the given host and protocol.
125 * @return filename of the form DIRECTORY/HOSTID
126 */
127static char *
128get_host_filename (const struct GNUNET_PeerIdentity *id)
129{
130 struct GNUNET_CRYPTO_HashAsciiEncoded fil;
131 char *fn;
132
133 GNUNET_CRYPTO_hash_to_enc (&id->hashPubKey, &fil);
134 GNUNET_asprintf (&fn,
135 "%s%s%s", networkIdDirectory, DIR_SEPARATOR_STR, &fil);
136 return fn;
137}
138
139
140/**
141 * Get the filename under which we would store the GNUNET_HELLO_Message
142 * for the given host and protocol.
143 * @return filename of the form DIRECTORY/HOSTID
144 */
145static char *
146get_trust_filename (const struct GNUNET_PeerIdentity *id)
147{
148 struct GNUNET_CRYPTO_HashAsciiEncoded fil;
149 char *fn;
150
151 GNUNET_CRYPTO_hash_to_enc (&id->hashPubKey, &fil);
152 GNUNET_asprintf (&fn, "%s%s%s", trustDirectory, DIR_SEPARATOR_STR, &fil);
153 return fn;
154}
155
156/**
157 * Find the host entry for the given peer. Call
158 * only when synchronized!
159 * @return NULL if not found
160 */
161static struct HostEntry *
162lookup_host_entry (const struct GNUNET_PeerIdentity *id)
163{
164 struct HostEntry *pos;
165
166 pos = hosts;
167 while ((pos != NULL) &&
168 (0 !=
169 memcmp (id, &pos->identity, sizeof (struct GNUNET_PeerIdentity))))
170 pos = pos->next;
171 return pos;
172}
173
174
175/**
176 * Add a host to the list.
177 *
178 * @param identity the identity of the host
179 * @param protocol the protocol for the host
180 */
181static void
182add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity)
183{
184 struct HostEntry *entry;
185 char *fn;
186 uint32_t trust;
187 char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE];
188 const struct GNUNET_HELLO_Message *hello;
189 struct GNUNET_HELLO_Message *hello_clean;
190 int size;
191 struct GNUNET_TIME_Absolute now;
192
193 entry = lookup_host_entry (identity);
194 if (entry != NULL)
195 return;
196 entry = GNUNET_malloc (sizeof (struct HostEntry));
197 entry->identity = *identity;
198 fn = get_trust_filename (identity);
199 if ((GNUNET_DISK_file_test (fn) == GNUNET_YES) &&
200 (sizeof (trust) == GNUNET_DISK_file_read (fn, sizeof (trust), &trust)))
201 entry->disk_trust = entry->trust = ntohl (trust);
202 GNUNET_free (fn);
203
204 fn = get_host_filename (identity);
205 if (GNUNET_DISK_file_test (fn) == GNUNET_YES)
206 {
207 size = GNUNET_DISK_file_read (fn, sizeof (buffer), buffer);
208 hello = (const struct GNUNET_HELLO_Message *) buffer;
209 now = GNUNET_TIME_absolute_get ();
210 hello_clean = GNUNET_HELLO_iterate_addresses (hello,
211 GNUNET_YES,
212 &discard_expired, &now);
213 entry->hello = hello_clean;
214 }
215 GNUNET_free (fn);
216 entry->next = hosts;
217 hosts = entry;
218}
219
220
221/**
222 * Increase the host credit by a value.
223 *
224 * @param hostId is the identity of the host
225 * @param value is the int value by which the
226 * host credit is to be increased or decreased
227 * @returns the actual change in trust (positive or negative)
228 */
229static int
230change_host_trust (const struct GNUNET_PeerIdentity *hostId, int value)
231{
232 struct HostEntry *host;
233
234 if (value == 0)
235 return 0;
236 host = lookup_host_entry (hostId);
237 if (host == NULL)
238 {
239 add_host_to_known_hosts (hostId);
240 host = lookup_host_entry (hostId);
241 }
242 GNUNET_assert (host != NULL);
243 if (value > 0)
244 {
245 if (host->trust + value < host->trust)
246 {
247 value = ((uint32_t) - 1) - host->trust;
248 host->trust = (uint32_t) - 1; /* maximized */
249 }
250 else
251 host->trust += value;
252 }
253 else
254 {
255 if (host->trust < -value)
256 {
257 value = -host->trust;
258 host->trust = 0;
259 }
260 else
261 host->trust += value;
262 }
263 return value;
264}
265
266
267/**
268 * Remove a file that should not be there. LOG
269 * success or failure.
270 */
271static void
272remove_garbage (const char *fullname)
273{
274 if (0 == UNLINK (fullname))
275 GNUNET_log (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
276 _
277 ("File `%s' in directory `%s' does not match naming convention. "
278 "Removed.\n"), fullname, networkIdDirectory);
279 else
280 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR |
281 GNUNET_ERROR_TYPE_BULK, "unlink", fullname);
282}
283
284
285static int
286hosts_directory_scan_callback (void *cls, const char *fullname)
287{
288 unsigned int *matched = cls;
289 struct GNUNET_PeerIdentity identity;
290 const char *filename;
291
292 if (GNUNET_DISK_file_test (fullname) != GNUNET_YES)
293 return GNUNET_OK; /* ignore non-files */
294 if (strlen (fullname) < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))
295 {
296 remove_garbage (fullname);
297 return GNUNET_OK;
298 }
299 filename =
300 &fullname[strlen (fullname) -
301 sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1];
302 if (filename[-1] != DIR_SEPARATOR)
303 {
304 remove_garbage (fullname);
305 return GNUNET_OK;
306 }
307 if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (filename,
308 &identity.hashPubKey))
309 {
310 remove_garbage (fullname);
311 return GNUNET_OK;
312 }
313 (*matched)++;
314 add_host_to_known_hosts (&identity);
315 return GNUNET_OK;
316}
317
318
319/**
320 * Call this method periodically to scan data/hosts for new hosts.
321 */
322static void
323cron_scan_directory_data_hosts (void *cls,
324 const struct GNUNET_SCHEDULER_TaskContext *tc)
325{
326 static unsigned int retries;
327 unsigned int count;
328
329 count = 0;
330 GNUNET_DISK_directory_scan (networkIdDirectory,
331 &hosts_directory_scan_callback, &count);
332 if ((0 == count) && (0 == (++retries & 31)))
333 GNUNET_log (GNUNET_ERROR_TYPE_WARNING |
334 GNUNET_ERROR_TYPE_BULK,
335 _("Still no peers found in `%s'!\n"), networkIdDirectory);
336 GNUNET_SCHEDULER_add_delayed (tc->sched,
337 GNUNET_NO,
338 GNUNET_SCHEDULER_PRIORITY_KEEP,
339 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
340 DATA_HOST_FREQ,
341 &cron_scan_directory_data_hosts, NULL);
342}
343
344
345/**
346 * Bind a host address (hello) to a hostId.
347 *
348 * @param peer the peer for which this is a hello
349 * @param hello the verified (!) hello message
350 */
351static void
352bind_address (const struct GNUNET_PeerIdentity *peer,
353 const struct GNUNET_HELLO_Message *hello)
354{
355 char *fn;
356 struct HostEntry *host;
357 struct GNUNET_HELLO_Message *mrg;
358
359 add_host_to_known_hosts (peer);
360 host = lookup_host_entry (peer);
361 GNUNET_assert (host != NULL);
362 if (host->hello == NULL)
363 {
364 host->hello = GNUNET_malloc (GNUNET_HELLO_size (hello));
365 memcpy (host->hello, hello, GNUNET_HELLO_size (hello));
366 }
367 else
368 {
369 mrg = GNUNET_HELLO_merge (host->hello, hello);
370 GNUNET_free (host->hello);
371 host->hello = mrg;
372 }
373 fn = get_host_filename (peer);
374 GNUNET_DISK_file_write (fn, host->hello, GNUNET_HELLO_size (hello), "644");
375 GNUNET_free (fn);
376}
377
378
379/**
380 * Do transmit info either for only the host matching the given
381 * argument or for all known hosts and change their trust values by
382 * the given delta.
383 *
384 * @param only NULL to hit all hosts
385 */
386static void
387send_to_each_host (const struct GNUNET_PeerIdentity *only,
388 int trust_change,
389 struct GNUNET_SERVER_Client *client,
390 struct GNUNET_SERVER_Handle *server)
391{
392 struct HostEntry *pos;
393 struct InfoMessage *im;
394 const struct GNUNET_MessageHeader *end;
395 uint16_t hs;
396 char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE];
397 struct GNUNET_SERVER_TransmitContext *tc;
398
399 tc = GNUNET_SERVER_transmit_context_create (client);
400 pos = hosts;
401 while (pos != NULL)
402 {
403 if ((only == NULL) ||
404 (0 ==
405 memcmp (only, &pos->identity,
406 sizeof (struct GNUNET_PeerIdentity))))
407 {
408 change_host_trust (&pos->identity, trust_change);
409 hs = 0;
410 im = (struct InfoMessage *) buf;
411 if (pos->hello != NULL)
412 {
413 hs = GNUNET_HELLO_size (pos->hello);
414 GNUNET_assert (hs <
415 GNUNET_SERVER_MAX_MESSAGE_SIZE -
416 sizeof (struct InfoMessage));
417 memcpy (&im[1], pos->hello, hs);
418 }
419 im->trust = htonl (pos->trust);
420 im->peer = pos->identity;
421 end = &im->header;
422 GNUNET_SERVER_transmit_context_append (tc,
423 &end[1],
424 hs +
425 sizeof (struct InfoMessage) -
426 sizeof (struct
427 GNUNET_MessageHeader),
428 GNUNET_MESSAGE_TYPE_PEERINFO_INFO);
429 }
430 pos = pos->next;
431 }
432 GNUNET_SERVER_transmit_context_append (tc, NULL, 0,
433 GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END);
434 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
435}
436
437
438/**
439 * Write host-trust information to a file - flush the buffer entry!
440 * Assumes synchronized access.
441 */
442static void
443flush_trust (struct HostEntry *host)
444{
445 char *fn;
446 uint32_t trust;
447
448 if (host->trust == host->disk_trust)
449 return; /* unchanged */
450 fn = get_trust_filename (&host->identity);
451 if (host->trust == 0)
452 {
453 if ((0 != UNLINK (fn)) && (errno != ENOENT))
454 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING |
455 GNUNET_ERROR_TYPE_BULK, "unlink", fn);
456 }
457 else
458 {
459 trust = htonl (host->trust);
460 if (GNUNET_OK ==
461 GNUNET_DISK_file_write (fn, &trust, sizeof (uint32_t), "644"))
462 host->disk_trust = host->trust;
463 }
464 GNUNET_free (fn);
465}
466
467/**
468 * Call this method periodically to scan data/hosts for new hosts.
469 */
470static void
471cron_flush_trust (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
472{
473 struct HostEntry *pos;
474
475 pos = hosts;
476 while (pos != NULL)
477 {
478 flush_trust (pos);
479 pos = pos->next;
480 }
481 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
482 GNUNET_SCHEDULER_add_delayed (tc->sched,
483 GNUNET_YES,
484 GNUNET_SCHEDULER_PRIORITY_KEEP,
485 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
486 TRUST_FLUSH_FREQ, &cron_flush_trust, NULL);
487}
488
489
490/**
491 * @brief delete expired HELLO entries in data/hosts/
492 */
493static int
494discard_hosts_helper (void *cls, const char *fn)
495{
496 struct GNUNET_TIME_Absolute *now = cls;
497 char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE];
498 const struct GNUNET_HELLO_Message *hello;
499 struct GNUNET_HELLO_Message *new_hello;
500 int size;
501
502 size = GNUNET_DISK_file_read (fn, sizeof (buffer), buffer);
503 if ((size < sizeof (struct GNUNET_MessageHeader)) && (0 != UNLINK (fn)))
504 {
505 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING |
506 GNUNET_ERROR_TYPE_BULK, "unlink", fn);
507 return GNUNET_OK;
508 }
509 hello = (const struct GNUNET_HELLO_Message *) buffer;
510 new_hello = GNUNET_HELLO_iterate_addresses (hello,
511 GNUNET_YES,
512 &discard_expired, now);
513 if ((new_hello == NULL) && (0 != UNLINK (fn)))
514 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING |
515 GNUNET_ERROR_TYPE_BULK, "unlink", fn);
516 if (new_hello != NULL)
517 {
518 GNUNET_DISK_file_write (fn,
519 new_hello,
520 GNUNET_HELLO_size (new_hello), "644");
521 GNUNET_free (new_hello);
522 }
523 return GNUNET_OK;
524}
525
526
527/**
528 * Call this method periodically to scan data/hosts for new hosts.
529 */
530static void
531cron_clean_data_hosts (void *cls,
532 const struct GNUNET_SCHEDULER_TaskContext *tc)
533{
534 struct GNUNET_TIME_Absolute now;
535
536 now = GNUNET_TIME_absolute_get ();
537 GNUNET_DISK_directory_scan (networkIdDirectory,
538 &discard_hosts_helper, &now);
539
540 GNUNET_SCHEDULER_add_delayed (tc->sched,
541 GNUNET_NO,
542 GNUNET_SCHEDULER_PRIORITY_KEEP,
543 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
544 DATA_HOST_CLEAN_FREQ,
545 &cron_clean_data_hosts, NULL);
546}
547
548
549/**
550 * Handle ADD-message.
551 *
552 * @param cls closure
553 * @param server the server handling the message
554 * @param client identification of the client
555 * @param message the actual message
556 */
557static void
558handle_add (void *cls,
559 struct GNUNET_SERVER_Handle *server,
560 struct GNUNET_SERVER_Client *client,
561 const struct GNUNET_MessageHeader *message)
562{
563 const struct PeerAddMessage *pam;
564 const struct GNUNET_MessageHeader *hello;
565 uint16_t size;
566
567 size = ntohs (message->size);
568 if (size <
569 sizeof (struct PeerAddMessage) + sizeof (struct GNUNET_MessageHeader))
570 {
571 GNUNET_break (0);
572 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
573 return;
574 }
575 pam = (const struct PeerAddMessage *) message;
576 hello = (const struct GNUNET_MessageHeader *) &pam[1];
577 if (size != sizeof (struct PeerAddMessage) + ntohs (hello->size))
578 {
579 GNUNET_break (0);
580 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
581 return;
582 }
583 bind_address (&pam->peer, (const struct GNUNET_HELLO_Message *) hello);
584 GNUNET_SERVER_receive_done (client, GNUNET_OK);
585}
586
587
588/**
589 * Handle GET-message.
590 *
591 * @param cls closure
592 * @param server the server handling the message
593 * @param client identification of the client
594 * @param message the actual message
595 */
596static void
597handle_get (void *cls,
598 struct GNUNET_SERVER_Handle *server,
599 struct GNUNET_SERVER_Client *client,
600 const struct GNUNET_MessageHeader *message)
601{
602 const struct ListPeerMessage *lpm;
603
604 lpm = (const struct ListPeerMessage *) message;
605 send_to_each_host (&lpm->peer, ntohl (lpm->trust_change), client, server);
606}
607
608
609/**
610 * Handle GET-ALL-message.
611 *
612 * @param cls closure
613 * @param server the server handling the message
614 * @param client identification of the client
615 * @param message the actual message
616 */
617static void
618handle_get_all (void *cls,
619 struct GNUNET_SERVER_Handle *server,
620 struct GNUNET_SERVER_Client *client,
621 const struct GNUNET_MessageHeader *message)
622{
623 const struct ListAllPeersMessage *lpm;
624
625 lpm = (const struct ListAllPeersMessage *) message;
626 send_to_each_host (NULL, ntohl (lpm->trust_change), client, server);
627}
628
629
630/**
631 * List of handlers for the messages understood by this
632 * service.
633 */
634static struct GNUNET_SERVER_MessageHandler handlers[] = {
635 {&handle_add, NULL, GNUNET_MESSAGE_TYPE_PEERINFO_ADD, 0},
636 {&handle_get, NULL, GNUNET_MESSAGE_TYPE_PEERINFO_GET,
637 sizeof (struct ListPeerMessage)},
638 {&handle_get_all, NULL, GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL,
639 sizeof (struct ListAllPeersMessage)},
640 {NULL, NULL, 0, 0}
641};
642
643
644/**
645 * Process statistics requests.
646 *
647 * @param cls closure
648 * @param sched scheduler to use
649 * @param server the initialized server
650 * @param cfg configuration to use
651 */
652static void
653run (void *cls,
654 struct GNUNET_SCHEDULER_Handle *sched,
655 struct GNUNET_SERVER_Handle *server,
656 struct GNUNET_CONFIGURATION_Handle *cfg)
657{
658 GNUNET_assert (GNUNET_OK ==
659 GNUNET_CONFIGURATION_get_value_filename (cfg,
660 "peerinfo",
661 "HOSTS",
662 &networkIdDirectory));
663 GNUNET_assert (GNUNET_OK ==
664 GNUNET_CONFIGURATION_get_value_filename (cfg,
665 "peerinfo",
666 "TRUST",
667 &trustDirectory));
668 GNUNET_DISK_directory_create (networkIdDirectory);
669 GNUNET_DISK_directory_create (trustDirectory);
670 GNUNET_SCHEDULER_add_delayed (sched,
671 GNUNET_NO,
672 GNUNET_SCHEDULER_PRIORITY_IDLE,
673 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
674 GNUNET_TIME_UNIT_MILLISECONDS,
675 &cron_scan_directory_data_hosts, NULL);
676 GNUNET_SCHEDULER_add_delayed (sched,
677 GNUNET_YES,
678 GNUNET_SCHEDULER_PRIORITY_HIGH,
679 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
680 TRUST_FLUSH_FREQ, &cron_flush_trust, NULL);
681 GNUNET_SCHEDULER_add_delayed (sched,
682 GNUNET_NO,
683 GNUNET_SCHEDULER_PRIORITY_IDLE,
684 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
685 DATA_HOST_CLEAN_FREQ,
686 &cron_clean_data_hosts, NULL);
687 GNUNET_SERVER_add_handlers (server, handlers);
688}
689
690
691/**
692 * The main function for the statistics service.
693 *
694 * @param argc number of arguments from the command line
695 * @param argv command line arguments
696 * @return 0 ok, 1 on error
697 */
698int
699main (int argc, char *const *argv)
700{
701 return (GNUNET_OK ==
702 GNUNET_SERVICE_run (argc,
703 argv,
704 "peerinfo", &run, NULL, NULL, NULL)) ? 0 : 1;
705}
706
707
708/* end of gnunet-service-peerinfo.c */
diff --git a/src/peerinfo/peerinfo.h b/src/peerinfo/peerinfo.h
new file mode 100644
index 000000000..040b084e4
--- /dev/null
+++ b/src/peerinfo/peerinfo.h
@@ -0,0 +1,135 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 peerinfo/peerinfo.h
23 * @brief common internal definitions for peerinfo service
24 * @author Christian Grothoff
25 */
26#include "gnunet_crypto_lib.h"
27#include "gnunet_time_lib.h"
28#include "gnunet_peerinfo_service.h"
29
30
31/**
32 * Add the given peer to the list. This message
33 * is always followed by a verified HELLO message.
34 */
35struct PeerAddMessage
36{
37
38 /**
39 * Type will be GNUNET_MESSAGE_TYPE_PEERINFO_ADD
40 */
41 struct GNUNET_MessageHeader header;
42
43 /**
44 * Always zero.
45 */
46 uint32_t reserved GNUNET_PACKED;
47
48 /**
49 * For which peer do we provide a HELLO message here?
50 */
51 struct GNUNET_PeerIdentity peer;
52
53};
54
55
56/**
57 * Message requesting a listing of all known peers,
58 * possibly modified by the specified trust value
59 * and restricted to the specified peer identity.
60 */
61struct ListPeerMessage
62{
63
64 /**
65 * Type will be GNUNET_MESSAGE_TYPE_PEERINFO_GET
66 */
67 struct GNUNET_MessageHeader header;
68
69 /**
70 * How much to change the trust in each returned peer,
71 * in network byte order.
72 */
73 int32_t trust_change GNUNET_PACKED;
74
75 /**
76 * Restrict to peers with this identity (optional
77 * field, check header.size!).
78 */
79 struct GNUNET_PeerIdentity peer;
80
81};
82
83
84/**
85 * Message requesting a listing of all known peers,
86 * possibly modified by the specified trust value
87 * and restricted to the specified peer identity.
88 */
89struct ListAllPeersMessage
90{
91
92 /**
93 * Type will be GNUNET_MESSAGE_TYPE_PEERINFO_GET
94 */
95 struct GNUNET_MessageHeader header;
96
97 /**
98 * How much to change the trust in each returned peer,
99 * in network byte order.
100 */
101 int32_t trust_change GNUNET_PACKED;
102
103};
104
105
106/**
107 * Message used to inform the client about
108 * a particular peer; this message is optionally followed
109 * by a HELLO message for the respective peer (if available).
110 * Check the header.size field to see if a HELLO is
111 * present.
112 */
113struct InfoMessage
114{
115
116 /**
117 * Type will be GNUNET_MESSAGE_TYPE_PEERINFO_INFO
118 */
119 struct GNUNET_MessageHeader header;
120
121 /**
122 * Amount of trust we now have in the peer,
123 * in network byte order.
124 */
125 uint32_t trust GNUNET_PACKED;
126
127 /**
128 * About which peer are we talking here?
129 */
130 struct GNUNET_PeerIdentity peer;
131
132};
133
134
135/* end of peerinfo.h */
diff --git a/src/peerinfo/peerinfo_api.c b/src/peerinfo/peerinfo_api.c
new file mode 100644
index 000000000..ba5ade199
--- /dev/null
+++ b/src/peerinfo/peerinfo_api.c
@@ -0,0 +1,302 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2004, 2005, 2007, 2009 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 2, 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 peerinfo/peerinfo_api.c
23 * @brief API to access peerinfo service
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_client_lib.h"
28#include "gnunet_peerinfo_service.h"
29#include "gnunet_protocols.h"
30#include "gnunet_time_lib.h"
31#include "peerinfo.h"
32
33#define ADD_PEER_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
34
35
36struct CAFContext
37{
38 struct GNUNET_CLIENT_Connection *client;
39 struct GNUNET_MessageHeader *msg;
40};
41
42
43static size_t
44copy_and_free (void *cls, size_t size, void *buf)
45{
46 struct CAFContext *cc = cls;
47 struct GNUNET_MessageHeader *msg = cc->msg;
48 uint16_t msize;
49
50 if (buf == NULL)
51 {
52 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
53 _
54 ("Failed to transmit message of type %u to `%s' service.\n"),
55 ntohs (msg->type), "peerinfo");
56 GNUNET_free (msg);
57 GNUNET_CLIENT_disconnect (cc->client);
58 GNUNET_free (cc);
59 return 0;
60 }
61 msize = ntohs (msg->size);
62 GNUNET_assert (size >= msize);
63 memcpy (buf, msg, msize);
64 GNUNET_free (msg);
65 GNUNET_CLIENT_disconnect (cc->client);
66 GNUNET_free (cc);
67 return msize;
68}
69
70
71
72/**
73 * Add a host to the persistent list.
74 *
75 * @param cfg configuration to use
76 * @param sched scheduler to use
77 * @param peer identity of the peer
78 * @param hello the verified (!) HELLO message
79 * @param expiration when the HELLO will expire
80 */
81void
82GNUNET_PEERINFO_add_peer (struct GNUNET_CONFIGURATION_Handle *cfg,
83 struct GNUNET_SCHEDULER_Handle *sched,
84 const struct GNUNET_PeerIdentity *peer,
85 const struct GNUNET_HELLO_Message *hello)
86{
87 struct GNUNET_CLIENT_Connection *client;
88 struct PeerAddMessage *pam;
89 uint16_t hs;
90 struct CAFContext *cc;
91
92 client = GNUNET_CLIENT_connect (sched, "peerinfo", cfg);
93 if (client == NULL)
94 {
95 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
96 _("Could not connect to `%s' service.\n"), "peerinfo");
97 return;
98 }
99 hs = GNUNET_HELLO_size (hello);
100 pam = GNUNET_malloc (sizeof (struct PeerAddMessage) + hs);
101 pam->header.size = htons (hs + sizeof (struct PeerAddMessage));
102 pam->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_ADD);
103 memcpy (&pam->peer, peer, sizeof (struct GNUNET_PeerIdentity));
104 memcpy (&pam[1], hello, hs);
105 cc = GNUNET_malloc (sizeof (struct CAFContext));
106 cc->client = client;
107 cc->msg = &pam->header;
108 GNUNET_CLIENT_notify_transmit_ready (client,
109 ntohs (pam->header.size),
110 ADD_PEER_TIMEOUT, &copy_and_free, cc);
111}
112
113
114/**
115 * Context for the info handler.
116 */
117struct InfoContext
118{
119
120 /**
121 * Our connection to the PEERINFO service.
122 */
123 struct GNUNET_CLIENT_Connection *client;
124
125 /**
126 * Function to call with information.
127 */
128 GNUNET_PEERINFO_Processor callback;
129
130 /**
131 * Closure for callback.
132 */
133 void *callback_cls;
134
135 /**
136 * When should we time out?
137 */
138 struct GNUNET_TIME_Absolute timeout;
139
140};
141
142
143/**
144 * Type of a function to call when we receive a message
145 * from the service.
146 *
147 * @param cls closure
148 * @param msg message received, NULL on timeout or fatal error
149 */
150static void
151info_handler (void *cls, const struct GNUNET_MessageHeader *msg)
152{
153 struct InfoContext *ic = cls;
154 const struct InfoMessage *im;
155 const struct GNUNET_HELLO_Message *hello;
156 uint16_t ms;
157
158 if (msg == NULL)
159 {
160 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
161 _("Failed to receive response from `%s' service.\n"),
162 "peerinfo");
163 ic->callback (ic->callback_cls, NULL, NULL, 1);
164 GNUNET_CLIENT_disconnect (ic->client);
165 GNUNET_free (ic);
166 return;
167 }
168 if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END)
169 {
170 ic->callback (ic->callback_cls, NULL, NULL, 0);
171 GNUNET_CLIENT_disconnect (ic->client);
172 GNUNET_free (ic);
173 return;
174 }
175 ms = ntohs (msg->size);
176 if ((ms < sizeof (struct InfoMessage)) ||
177 (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_PEERINFO_INFO))
178 {
179 GNUNET_break (0);
180 ic->callback (ic->callback_cls, NULL, NULL, 2);
181 GNUNET_CLIENT_disconnect (ic->client);
182 GNUNET_free (ic);
183 return;
184 }
185 im = (const struct InfoMessage *) msg;
186 hello = NULL;
187 if (ms > sizeof (struct InfoMessage) + sizeof (struct GNUNET_MessageHeader))
188 {
189 hello = (const struct GNUNET_HELLO_Message *) &im[1];
190 if (ms != sizeof (struct InfoMessage) + GNUNET_HELLO_size (hello))
191 {
192 GNUNET_break (0);
193 ic->callback (ic->callback_cls, NULL, NULL, 2);
194 GNUNET_CLIENT_disconnect (ic->client);
195 GNUNET_free (ic);
196 return;
197 }
198 }
199 ic->callback (ic->callback_cls, &im->peer, hello, ntohl (im->trust));
200 GNUNET_CLIENT_receive (ic->client,
201 &info_handler,
202 ic,
203 GNUNET_TIME_absolute_get_remaining (ic->timeout));
204}
205
206
207static size_t
208copy_then_receive (void *cls, size_t size, void *buf)
209{
210 struct InfoContext *ic = cls;
211 const struct GNUNET_MessageHeader *msg =
212 (const struct GNUNET_MessageHeader *) &ic[1];
213 uint16_t msize;
214
215 if (buf == NULL)
216 {
217 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
218 _
219 ("Failed to transmit message of type %u to `%s' service.\n"),
220 ntohs (msg->type), "peerinfo");
221 ic->callback (ic->callback_cls, NULL, NULL, 1);
222 GNUNET_CLIENT_disconnect (ic->client);
223 GNUNET_free (ic);
224 return 0;
225 }
226 msize = ntohs (msg->size);
227 GNUNET_assert (size >= msize);
228 memcpy (buf, msg, msize);
229 GNUNET_CLIENT_receive (ic->client,
230 &info_handler,
231 ic,
232 GNUNET_TIME_absolute_get_remaining (ic->timeout));
233 return msize;
234}
235
236
237/**
238 * Call a method for each known matching host and change
239 * its trust value. The method will be invoked once for
240 * each host and then finally once with a NULL pointer.
241 * Note that the last call can be triggered by timeout or
242 * by simply being done; however, the trust argument will
243 * be set to zero if we are done and to 1 if we timed out.
244 *
245 * @param cfg configuration to use
246 * @param sched scheduler to use
247 * @param peer restrict iteration to this peer only (can be NULL)
248 * @param trust_delta how much to change the trust in all matching peers
249 * @param timeout how long to wait until timing out
250 * @param callback the method to call for each peer
251 * @param callback_cls closure for callback
252 */
253void
254GNUNET_PEERINFO_for_all (struct GNUNET_CONFIGURATION_Handle *cfg,
255 struct GNUNET_SCHEDULER_Handle *sched,
256 const struct GNUNET_PeerIdentity *peer,
257 int trust_delta,
258 struct GNUNET_TIME_Relative timeout,
259 GNUNET_PEERINFO_Processor callback,
260 void *callback_cls)
261{
262 struct GNUNET_CLIENT_Connection *client;
263 struct ListAllPeersMessage *lapm;
264 struct ListPeerMessage *lpm;
265 size_t hs;
266 struct InfoContext *ihc;
267
268 client = GNUNET_CLIENT_connect (sched, "peerinfo", cfg);
269 if (client == NULL)
270 {
271 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
272 _("Could not connect to `%s' service.\n"), "peerinfo");
273 callback (callback_cls, NULL, NULL, 2);
274 return;
275 }
276 ihc = GNUNET_malloc (sizeof (struct InfoContext) +
277 sizeof (struct ListPeerMessage));
278 ihc->client = client;
279 ihc->callback = callback;
280 ihc->callback_cls = callback_cls;
281 ihc->timeout = GNUNET_TIME_relative_to_absolute (timeout);
282 hs = 0;
283 if (peer == NULL)
284 {
285 lapm = (struct ListAllPeersMessage *) &ihc[1];
286 lapm->header.size = htons (hs = sizeof (struct ListAllPeersMessage));
287 lapm->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL);
288 lapm->trust_change = htonl (trust_delta);
289 }
290 else
291 {
292 lpm = (struct ListPeerMessage *) &ihc[1];
293 lpm->header.size = htons (hs = sizeof (struct ListPeerMessage));
294 lpm->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET);
295 lpm->trust_change = htonl (trust_delta);
296 memcpy (&lpm->peer, peer, sizeof (struct GNUNET_PeerIdentity));
297 }
298 GNUNET_CLIENT_notify_transmit_ready (client,
299 hs, timeout, &copy_then_receive, ihc);
300}
301
302/* end of peerinfo_api.c */
diff --git a/src/peerinfo/test_peerinfo_api.c b/src/peerinfo/test_peerinfo_api.c
new file mode 100644
index 000000000..e7d632fd5
--- /dev/null
+++ b/src/peerinfo/test_peerinfo_api.c
@@ -0,0 +1,175 @@
1/*
2 This file is part of GNUnet.
3 (C) 2004, 2009 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 2, 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 peerinfo/test_peerinfo_api.c
23 * @brief testcase for peerinfo_api.c
24 * @author Christian Grothoff
25 *
26 * TODO:
27 * - test merging of HELLOs (add same peer twice...)
28 */
29
30#include "platform.h"
31#include "gnunet_hello_lib.h"
32#include "gnunet_getopt_lib.h"
33#include "gnunet_os_lib.h"
34#include "gnunet_peerinfo_service.h"
35#include "gnunet_program_lib.h"
36#include "gnunet_time_lib.h"
37
38
39static int
40check_it (void *cls,
41 const char *tname,
42 struct GNUNET_TIME_Absolute expiration,
43 const void *addr, size_t addrlen)
44{
45 unsigned int *agc = cls;
46
47 if (addrlen > 0)
48 {
49 GNUNET_assert (0 == strcmp ("peerinfotest", tname));
50 GNUNET_assert (0 == strncmp ("Address", addr, addrlen));
51 (*agc) -= (1 << (addrlen - 1));
52 }
53 return GNUNET_OK;
54}
55
56
57static void
58process (void *cls,
59 const struct GNUNET_PeerIdentity *peer,
60 const struct GNUNET_HELLO_Message *hello, uint32_t trust)
61{
62 int *ok = cls;
63 unsigned int agc;
64
65 if (peer == NULL)
66 {
67 GNUNET_assert (peer == NULL);
68 GNUNET_assert (2 == *ok);
69 GNUNET_assert (trust == 0);
70 *ok = 0;
71 return;
72 }
73
74 if (hello != NULL)
75 {
76 GNUNET_assert (3 == *ok);
77 agc = 3;
78 GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &check_it, &agc);
79 GNUNET_assert (agc == 0);
80 *ok = 2;
81 }
82}
83
84
85static size_t
86address_generator (void *cls, size_t max, void *buf)
87{
88 size_t *agc = cls;
89 size_t ret;
90
91 if (0 == *agc)
92 return 0;
93 ret = GNUNET_HELLO_add_address ("peerinfotest",
94 GNUNET_TIME_relative_to_absolute
95 (GNUNET_TIME_UNIT_HOURS), "Address", *agc,
96 buf, max);
97 (*agc)--;
98 return ret;
99}
100
101
102static void
103run (void *cls,
104 struct GNUNET_SCHEDULER_Handle *sched,
105 char *const *args,
106 const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *cfg)
107{
108 struct GNUNET_HELLO_Message *hello;
109 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
110 size_t agc;
111 struct GNUNET_PeerIdentity pid;
112
113 memset (&pkey, 32, sizeof (pkey));
114 GNUNET_CRYPTO_hash (&pkey, sizeof (pkey), &pid.hashPubKey);
115 agc = 2;
116 hello = GNUNET_HELLO_create (&pkey, &address_generator, &agc);
117 GNUNET_assert (hello != NULL);
118 GNUNET_PEERINFO_add_peer (cfg, sched, &pid, hello);
119 GNUNET_PEERINFO_for_all (cfg,
120 sched,
121 NULL,
122 0,
123 GNUNET_TIME_relative_multiply
124 (GNUNET_TIME_UNIT_SECONDS, 15), &process, cls);
125 GNUNET_free (hello);
126}
127
128
129static int
130check ()
131{
132 int ok = 3;
133 pid_t pid;
134 char *const argv[] = { "test-peerinfo-api",
135 "-c",
136 "test_peerinfo_api_data.conf",
137#if DEBUG_PEERINFO
138 "-L", "DEBUG",
139#endif
140 NULL
141 };
142 struct GNUNET_GETOPT_CommandLineOption options[] = {
143 GNUNET_GETOPT_OPTION_END
144 };
145 pid = GNUNET_OS_start_process ("gnunet-service-peerinfo",
146 "gnunet-service-peerinfo",
147#if DEBUG_PEERINFO
148 "-L", "DEBUG",
149#endif
150 "-c", "test_peerinfo_api_data.conf", NULL);
151 sleep (1);
152 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
153 argv, "test-peerinfo-api", "nohelp",
154 options, &run, &ok);
155 if (0 != PLIBC_KILL (pid, SIGTERM))
156 {
157 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
158 ok = 1;
159 }
160 waitpid (pid, NULL, 0);
161 return ok;
162}
163
164
165int
166main (int argc, char *argv[])
167{
168 int ret = 0;
169
170 ret = check ();
171
172 return ret;
173}
174
175/* end of test_peerinfo_api.c */
diff --git a/src/peerinfo/test_peerinfo_api_data.conf b/src/peerinfo/test_peerinfo_api_data.conf
new file mode 100644
index 000000000..a81ffccb9
--- /dev/null
+++ b/src/peerinfo/test_peerinfo_api_data.conf
@@ -0,0 +1,5 @@
1[PATHS]
2SERVICEHOME = /tmp/test-gnunetd-peerinfo/
3
4[peerinfo]
5PORT = 22354
diff --git a/src/resolver/Makefile.am b/src/resolver/Makefile.am
new file mode 100644
index 000000000..20c07f4da
--- /dev/null
+++ b/src/resolver/Makefile.am
@@ -0,0 +1,46 @@
1INCLUDES = -I$(top_srcdir)/src/include
2
3if MINGW
4 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
5endif
6
7if USE_COVERAGE
8 AM_CFLAGS = -fprofile-arcs -ftest-coverage
9endif
10
11
12lib_LTLIBRARIES = libgnunetresolver.la
13
14libgnunetresolver_la_SOURCES = \
15 resolver_api.c resolver.h
16libgnunetresolver_la_LIBADD = \
17 $(top_builddir)/src/util/libgnunetutil.la \
18 $(GN_LIBINTL)
19libgnunetresolver_la_LDFLAGS = \
20 $(GN_LIB_LDFLAGS) $(WINFLAGS) \
21 -version-info 0:0:0
22
23
24bin_PROGRAMS = \
25 gnunet-service-resolver
26
27gnunet_service_resolver_SOURCES = \
28 gnunet-service-resolver.c
29gnunet_service_resolver_LDADD = \
30 $(top_builddir)/src/util/libgnunetutil.la \
31 $(GN_LIBINTL)
32
33
34check_PROGRAMS = \
35 test_resolver_api
36
37TESTS = $(check_PROGRAMS)
38
39test_resolver_api_SOURCES = \
40 test_resolver_api.c
41test_resolver_api_LDADD = \
42 $(top_builddir)/src/resolver/libgnunetresolver.la \
43 $(top_builddir)/src/util/libgnunetutil.la
44
45EXTRA_DIST = \
46 test_resolver_api_data.conf
diff --git a/src/resolver/gnunet-service-resolver.c b/src/resolver/gnunet-service-resolver.c
new file mode 100644
index 000000000..dbdecdfe5
--- /dev/null
+++ b/src/resolver/gnunet-service-resolver.c
@@ -0,0 +1,483 @@
1/*
2 This file is part of GNUnet.
3 (C) 2007, 2008, 2009 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 2, 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 resolver/gnunet-service-resolver.c
23 * @brief code to do DNS resolution
24 * @author Christian Grothoff
25 */
26
27#include <stdlib.h>
28#include "platform.h"
29#include "gnunet_disk_lib.h"
30#include "gnunet_getopt_lib.h"
31#include "gnunet_protocols.h"
32#include "gnunet_service_lib.h"
33#include "gnunet_statistics_service.h"
34#include "gnunet_strings_lib.h"
35#include "gnunet_time_lib.h"
36#include "resolver.h"
37
38
39struct IPCache
40{
41 struct IPCache *next;
42 char *addr;
43 struct sockaddr *sa;
44 struct GNUNET_TIME_Absolute last_refresh;
45 struct GNUNET_TIME_Absolute last_request;
46 unsigned int salen;
47};
48
49
50static struct IPCache *head;
51
52
53
54
55#if HAVE_GETNAMEINFO
56static void
57getnameinfo_resolve (struct IPCache *cache)
58{
59 char hostname[256];
60
61 if (0 == getnameinfo (cache->sa, cache->salen, hostname, 255, NULL, 0, 0))
62 cache->addr = GNUNET_strdup (hostname);
63}
64#endif
65
66
67#if HAVE_GETHOSTBYADDR
68static void
69gethostbyaddr_resolve (struct IPCache *cache)
70{
71 struct hostent *ent;
72
73 switch (cache->sa->sa_family)
74 {
75 case AF_INET:
76 ent = gethostbyaddr (&((struct sockaddr_in *) cache->sa)->sin_addr,
77 sizeof (struct in_addr), AF_INET);
78 break;
79 case AF_INET6:
80 ent = gethostbyaddr (&((struct sockaddr_in6 *) cache->sa)->sin6_addr,
81 sizeof (struct in6_addr), AF_INET6);
82 break;
83 default:
84 ent = NULL;
85 }
86 if (ent != NULL)
87 cache->addr = GNUNET_strdup (ent->h_name);
88}
89#endif
90
91
92static void
93cache_resolve (struct IPCache *cache)
94{
95#if HAVE_GETNAMEINFO
96 if (cache->addr == NULL)
97 getnameinfo_resolve (cache);
98#endif
99#if HAVE_GETHOSTBYADDR
100 if (cache->addr == NULL)
101 gethostbyaddr_resolve (cache);
102#endif
103}
104
105
106
107/**
108 * Get an IP address as a string (works for both IPv4 and IPv6). Note
109 * that the resolution happens asynchronously and that the first call
110 * may not immediately result in the FQN (but instead in a
111 * human-readable IP address).
112 *
113 * @param sa should be of type "struct sockaddr*"
114 */
115static void
116get_ip_as_string (struct GNUNET_SERVER_Client *client,
117 const struct sockaddr *sav, socklen_t salen)
118{
119 struct IPCache *cache;
120 struct IPCache *prev;
121 struct GNUNET_TIME_Absolute now;
122 struct GNUNET_SERVER_TransmitContext *tc;
123
124 if (salen < sizeof (struct sockaddr))
125 {
126 GNUNET_break (0);
127 return;
128 }
129 now = GNUNET_TIME_absolute_get ();
130 cache = head;
131 prev = NULL;
132 while ((cache != NULL) &&
133 ((cache->salen != salen) || (0 != memcmp (cache->sa, sav, salen))))
134 {
135 if (GNUNET_TIME_absolute_get_duration (cache->last_request).value <
136 60 * 60 * 1000)
137 {
138 if (prev != NULL)
139 {
140 prev->next = cache->next;
141 GNUNET_free_non_null (cache->addr);
142 GNUNET_free (cache->sa);
143 GNUNET_free (cache);
144 cache = prev->next;
145 }
146 else
147 {
148 head = cache->next;
149 GNUNET_free_non_null (cache->addr);
150 GNUNET_free (cache->sa);
151 GNUNET_free (cache);
152 cache = head;
153 }
154 continue;
155 }
156 prev = cache;
157 cache = cache->next;
158 }
159 if (cache != NULL)
160 {
161 cache->last_request = now;
162 if (GNUNET_TIME_absolute_get_duration (cache->last_request).value <
163 60 * 60 * 1000)
164 {
165 GNUNET_free_non_null (cache->addr);
166 cache->addr = NULL;
167 cache->salen = 0;
168 cache_resolve (cache);
169 }
170 }
171 else
172 {
173 cache = GNUNET_malloc (sizeof (struct IPCache));
174 cache->next = head;
175 cache->salen = salen;
176 cache->sa = GNUNET_malloc (salen);
177 memcpy (cache->sa, sav, salen);
178 cache->last_request = GNUNET_TIME_absolute_get ();
179 cache->last_refresh = GNUNET_TIME_absolute_get ();
180 cache->addr = NULL;
181 cache_resolve (cache);
182 head = cache;
183 }
184 tc = GNUNET_SERVER_transmit_context_create (client);
185 if (cache->addr != NULL)
186 GNUNET_SERVER_transmit_context_append (tc,
187 cache->addr,
188 strlen (cache->addr) + 1,
189 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
190 GNUNET_SERVER_transmit_context_append (tc, NULL, 0,
191 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
192 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
193}
194
195
196#if HAVE_GETADDRINFO
197static int
198getaddrinfo_resolve (struct GNUNET_SERVER_TransmitContext *tc,
199 const char *hostname, int domain)
200{
201 int s;
202 struct addrinfo hints;
203 struct addrinfo *result;
204 struct addrinfo *pos;
205
206 memset (&hints, 0, sizeof (struct addrinfo));
207// FIXME in PlibC
208#ifndef MINGW
209 hints.ai_family = domain;
210#else
211 hints.ai_family = AF_INET;
212#endif
213 hints.ai_socktype = SOCK_STREAM; /* go for TCP */
214
215 if (0 != (s = getaddrinfo (hostname, NULL, &hints, &result)))
216 {
217 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
218 _("Could not resolve `%s' (%s): %s\n"), hostname,
219 (domain ==
220 AF_INET) ? "IPv4" : ((domain ==
221 AF_INET6) ? "IPv6" : "any"),
222 gai_strerror (s));
223 if ((s == EAI_BADFLAGS) || (s == EAI_MEMORY) || (s == EAI_SYSTEM))
224 return GNUNET_NO; /* other function may still succeed */
225 return GNUNET_SYSERR;
226 }
227 if (result == NULL)
228 return GNUNET_SYSERR;
229 pos = result;
230 while (pos != NULL)
231 {
232 GNUNET_SERVER_transmit_context_append (tc,
233 result->ai_addr,
234 result->ai_addrlen,
235 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
236 pos = pos->ai_next;
237 }
238 freeaddrinfo (result);
239 return GNUNET_OK;
240}
241#endif
242
243#if HAVE_GETHOSTBYNAME2
244static int
245gethostbyname2_resolve (struct GNUNET_SERVER_TransmitContext *tc,
246 const char *hostname, int domain)
247{
248 struct hostent *hp;
249 struct sockaddr_in a4;
250 struct sockaddr_in6 a6;
251 int ret1;
252 int ret2;
253
254 if (domain == AF_UNSPEC)
255 {
256 ret1 = gethostbyname2_resolve (tc, hostname, AF_INET);
257 ret2 = gethostbyname2_resolve (tc, hostname, AF_INET6);
258 if ((ret1 == GNUNET_OK) || (ret2 == GNUNET_OK))
259 return GNUNET_OK;
260 if ((ret1 == GNUNET_SYSERR) || (ret2 == GNUNET_SYSERR))
261 return GNUNET_SYSERR;
262 return GNUNET_NO;
263 }
264 hp = gethostbyname2 (hostname, domain);
265 if (hp == NULL)
266 {
267 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
268 _("Could not find IP of host `%s': %s\n"),
269 hostname, hstrerror (h_errno));
270 return GNUNET_SYSERR;
271 }
272 GNUNET_assert (hp->h_addrtype == domain);
273 if (domain == AF_INET)
274 {
275 GNUNET_assert (hp->h_length == sizeof (struct in_addr));
276 memset (&a4, 0, sizeof (a4));
277 a4.sin_family = AF_INET;
278 memcpy (&a4.sin_addr, hp->h_addr_list[0], hp->h_length);
279 GNUNET_SERVER_transmit_context_append (tc,
280 &a4,
281 sizeof (a4),
282 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
283 }
284 else
285 {
286 GNUNET_assert (hp->h_length == sizeof (struct in6_addr));
287 memset (&a6, 0, sizeof (a6));
288 a6.sin6_family = AF_INET6;
289 memcpy (&a6.sin6_addr, hp->h_addr_list[0], hp->h_length);
290 GNUNET_SERVER_transmit_context_append (tc,
291 &a6,
292 sizeof (a6),
293 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
294 }
295 return GNUNET_OK;
296}
297#endif
298
299#if HAVE_GETHOSTBYNAME
300static int
301gethostbyname_resolve (struct GNUNET_SERVER_TransmitContext *tc,
302 const char *hostname)
303{
304 struct hostent *hp;
305 struct sockaddr_in addr;
306
307 hp = GETHOSTBYNAME (hostname);
308 if (hp == NULL)
309 {
310 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
311 _("Could not find IP of host `%s': %s\n"),
312 hostname, hstrerror (h_errno));
313 return GNUNET_SYSERR;
314 }
315 if (hp->h_addrtype != AF_INET)
316 {
317 GNUNET_break (0);
318 return GNUNET_SYSERR;
319 }
320 GNUNET_assert (hp->h_length == sizeof (struct in_addr));
321 memset (&addr, 0, sizeof (addr));
322 addr.sin_family = AF_INET;
323 memcpy (&addr.sin_addr, hp->h_addr_list[0], hp->h_length);
324 GNUNET_SERVER_transmit_context_append (tc,
325 &addr,
326 sizeof (addr),
327 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
328 return GNUNET_OK;
329}
330#endif
331
332
333/**
334 * Convert a string to an IP address.
335 *
336 * @param client where to send the IP address
337 * @param hostname the hostname to resolve
338 * @param domain AF_INET or AF_INET6; use AF_UNSPEC for "any"
339 */
340static void
341get_ip_from_hostname (struct GNUNET_SERVER_Client *client,
342 const char *hostname, int domain)
343{
344 int ret;
345 struct GNUNET_SERVER_TransmitContext *tc;
346
347 tc = GNUNET_SERVER_transmit_context_create (client);
348 ret = GNUNET_NO;
349#if HAVE_GETADDRINFO
350 if (ret == GNUNET_NO)
351 ret = getaddrinfo_resolve (tc, hostname, domain);
352#endif
353#if HAVE_GETHOSTBYNAME2
354 if (ret == GNUNET_NO)
355 ret = gethostbyname2_resolve (tc, hostname, domain);
356#endif
357#if HAVE_GETHOSTBYNAME
358 if ((ret == GNUNET_NO) && ((domain == AF_UNSPEC) || (domain == PF_INET)))
359 gethostbyname_resolve (tc, hostname);
360#endif
361 GNUNET_SERVER_transmit_context_append (tc, NULL, 0,
362 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
363 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
364}
365
366
367/**
368 * Handle GET-message.
369 *
370 * @param cls closure
371 * @param server the server handling the message
372 * @param client identification of the client
373 * @param message the actual message
374 */
375static void
376handle_get (void *cls,
377 struct GNUNET_SERVER_Handle *server,
378 struct GNUNET_SERVER_Client *client,
379 const struct GNUNET_MessageHeader *message)
380{
381 uint16_t msize;
382 const struct GNUNET_RESOLVER_GetMessage *msg;
383 const char *hostname;
384 uint16_t size;
385 int direction;
386 int domain;
387
388 msize = ntohs (message->size);
389 if (msize < sizeof (struct GNUNET_RESOLVER_GetMessage))
390 {
391 GNUNET_break (0);
392 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
393 return;
394 }
395 msg = (const struct GNUNET_RESOLVER_GetMessage *) message;
396 size = msize - sizeof (struct GNUNET_RESOLVER_GetMessage);
397 direction = ntohl (msg->direction);
398 domain = ntohl (msg->domain);
399 if (direction == GNUNET_NO)
400 {
401 /* IP from hostname */
402 hostname = (const char *) &msg[1];
403 if (hostname[size - 1] != '\0')
404 {
405 GNUNET_break (0);
406 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
407 return;
408 }
409#if DEBUG_RESOLVER
410 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
411 _("Resolver asked to look up `%s'.\n"), hostname);
412#endif
413 get_ip_from_hostname (client, hostname, domain);
414 }
415 else
416 {
417#if DEBUG_RESOLVER
418 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
419 _("Resolver asked to look up IP address.\n"));
420#endif
421 get_ip_as_string (client, (const struct sockaddr *) &msg[1], size);
422 }
423}
424
425
426/**
427 * List of handlers for the messages understood by this
428 * service.
429 */
430static struct GNUNET_SERVER_MessageHandler handlers[] = {
431 {&handle_get, NULL, GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST, 0},
432 {NULL, NULL, 0, 0}
433};
434
435
436/**
437 * Process statistics requests.
438 *
439 * @param cls closure
440 * @param sched scheduler to use
441 * @param server the initialized server
442 * @param cfg configuration to use
443 */
444static void
445run (void *cls,
446 struct GNUNET_SCHEDULER_Handle *sched,
447 struct GNUNET_SERVER_Handle *server,
448 struct GNUNET_CONFIGURATION_Handle *cfg)
449{
450 GNUNET_SERVER_add_handlers (server, handlers);
451}
452
453
454/**
455 * The main function for the resolver service.
456 *
457 * @param argc number of arguments from the command line
458 * @param argv command line arguments
459 * @return 0 ok, 1 on error
460 */
461int
462main (int argc, char *const *argv)
463{
464 int ret;
465 struct IPCache *pos;
466
467 ret = (GNUNET_OK ==
468 GNUNET_SERVICE_run (argc,
469 argv,
470 "resolver", &run, NULL, NULL, NULL)) ? 0 : 1;
471
472 while (head != NULL)
473 {
474 pos = head->next;
475 GNUNET_free_non_null (head->addr);
476 GNUNET_free (head->sa);
477 GNUNET_free (head);
478 head = pos;
479 }
480 return ret;
481}
482
483/* end of gnunet-service-resolver.c */
diff --git a/src/resolver/resolver.h b/src/resolver/resolver.h
new file mode 100644
index 000000000..31637f01d
--- /dev/null
+++ b/src/resolver/resolver.h
@@ -0,0 +1,63 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 * @author Christian Grothoff
23 * @file resolver/resolver.h
24 */
25#ifndef RESOLVER_H
26#define RESOLVER_H
27
28#include "gnunet_common.h"
29
30#define DEBUG_RESOLVER GNUNET_NO
31
32/**
33 * Request for the resolver. Followed by either
34 * the "struct sockaddr" or the 0-terminated hostname.
35 *
36 * The response will be one or more messages of type
37 * RESOLVER_RESPONSE, each with the message header
38 * immediately followed by the requested data
39 * (hostname or struct sockaddr, depending on direction).
40 * The last RESOLVER_RESPONSE will just be a header
41 * without any data (used to indicate the end of the list).
42 */
43struct GNUNET_RESOLVER_GetMessage
44{
45 /**
46 * Type: GNUNET_MESSAGE_TYPE_STATISTICS_VALUE
47 */
48 struct GNUNET_MessageHeader header;
49
50 /**
51 * GNUNET_YES to get hostname from IP,
52 * GNUNET_NO to get IP from hostname.
53 */
54 int32_t direction GNUNET_PACKED;
55
56 /**
57 * Domain to use (AF_INET, AF_INET6 or AF_UNSPEC).
58 */
59 int32_t domain GNUNET_PACKED;
60
61};
62
63#endif
diff --git a/src/resolver/resolver_api.c b/src/resolver/resolver_api.c
new file mode 100644
index 000000000..27358996a
--- /dev/null
+++ b/src/resolver/resolver_api.c
@@ -0,0 +1,468 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 resolver/resolver_api.c
23 * @brief resolver for writing a tool
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_getopt_lib.h"
28#include "gnunet_client_lib.h"
29#include "gnunet_protocols.h"
30#include "gnunet_resolver_service.h"
31#include "gnunet_server_lib.h"
32#include "resolver.h"
33
34
35struct GetAddressContext
36{
37 GNUNET_RESOLVER_AddressCallback callback;
38 void *cls;
39 struct GNUNET_RESOLVER_GetMessage *msg;
40 struct GNUNET_CLIENT_Connection *client;
41 struct GNUNET_TIME_Absolute timeout;
42};
43
44
45
46/**
47 * Convert IP address to string without DNS resolution.
48 */
49static char *
50no_resolve (const struct sockaddr *sa, socklen_t salen)
51{
52 char *ret;
53 char inet4[INET_ADDRSTRLEN];
54 char inet6[INET6_ADDRSTRLEN];
55
56 if (salen < sizeof (struct sockaddr))
57 return NULL;
58 switch (sa->sa_family)
59 {
60 case AF_INET:
61 if (salen != sizeof (struct sockaddr_in))
62 return NULL;
63 inet_ntop (AF_INET,
64 &((struct sockaddr_in *) sa)->sin_addr,
65 inet4, INET_ADDRSTRLEN);
66 ret = GNUNET_strdup (inet4);
67 break;
68 case AF_INET6:
69 if (salen != sizeof (struct sockaddr_in6))
70 return NULL;
71 inet_ntop (AF_INET6,
72 &((struct sockaddr_in6 *) sa)->sin6_addr,
73 inet6, INET6_ADDRSTRLEN);
74 ret = GNUNET_strdup (inet6);
75 break;
76 default:
77 ret = NULL;
78 break;
79 }
80 return ret;
81}
82
83
84static void
85handle_address_response (void *cls, const struct GNUNET_MessageHeader *msg)
86{
87 struct GetAddressContext *gac = cls;
88 uint16_t size;
89 const struct sockaddr *sa;
90 socklen_t salen;
91
92
93 if (msg == NULL)
94 {
95 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
96 _("Timeout trying to resolve hostname.\n"));
97 gac->callback (gac->cls, NULL, 0);
98 GNUNET_CLIENT_disconnect (gac->client);
99 GNUNET_free (gac);
100 return;
101 }
102 if (GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE != ntohs (msg->type))
103 {
104 GNUNET_break (0);
105 gac->callback (gac->cls, NULL, 0);
106 GNUNET_CLIENT_disconnect (gac->client);
107 GNUNET_free (gac);
108 return;
109 }
110
111 size = ntohs (msg->size);
112 if (size == sizeof (struct GNUNET_MessageHeader))
113 {
114#if DEBUG_RESOLVER
115 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
116 _("Received end message resolving hostname.\n"));
117#endif
118 gac->callback (gac->cls, NULL, 0);
119 GNUNET_CLIENT_disconnect (gac->client);
120 GNUNET_free (gac);
121 return;
122 }
123 sa = (const struct sockaddr *) &msg[1];
124 salen = size - sizeof (struct GNUNET_MessageHeader);
125 if (salen < sizeof (struct sockaddr))
126 {
127 GNUNET_break (0);
128 gac->callback (gac->cls, NULL, 0);
129 GNUNET_CLIENT_disconnect (gac->client);
130 GNUNET_free (gac);
131 return;
132 }
133#if DEBUG_RESOLVER
134 {
135 char *ips = no_resolve (sa, salen);
136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Resolver returns `%s'.\n"), ips);
137 GNUNET_free (ips);
138 }
139#endif
140 gac->callback (gac->cls, sa, salen);
141 GNUNET_CLIENT_receive (gac->client,
142 &handle_address_response,
143 gac,
144 GNUNET_TIME_absolute_get_remaining (gac->timeout));
145}
146
147
148static size_t
149transmit_get_ip (void *cls, size_t size, void *buf)
150{
151 struct GetAddressContext *actx = cls;
152 uint16_t ms;
153
154 if (buf == NULL)
155 {
156 /* timeout / error */
157 GNUNET_free (actx->msg);
158 actx->callback (actx->cls, NULL, 0);
159 GNUNET_CLIENT_disconnect (actx->client);
160 GNUNET_free (actx);
161 return 0;
162 }
163 ms = ntohs (actx->msg->header.size);
164 GNUNET_assert (size >= ms);
165 memcpy (buf, actx->msg, ms);
166 GNUNET_free (actx->msg);
167 actx->msg = NULL;
168 GNUNET_CLIENT_receive (actx->client,
169 &handle_address_response,
170 actx,
171 GNUNET_TIME_absolute_get_remaining (actx->timeout));
172 return ms;
173}
174
175
176
177/**
178 * Convert a string to one or more IP addresses.
179 *
180 * @param sched scheduler to use
181 * @param cfg configuration to use
182 * @param hostname the hostname to resolve
183 * @param domain AF_INET or AF_INET6; use AF_UNSPEC for "any"
184 * @param callback function to call with addresses
185 * @param cls closure for callback
186 * @param timeout how long to try resolving
187 */
188void
189GNUNET_RESOLVER_ip_get (struct GNUNET_SCHEDULER_Handle *sched,
190 struct GNUNET_CONFIGURATION_Handle *cfg,
191 const char *hostname,
192 int domain,
193 struct GNUNET_TIME_Relative timeout,
194 GNUNET_RESOLVER_AddressCallback callback, void *cls)
195{
196 struct GNUNET_CLIENT_Connection *client;
197 struct GNUNET_RESOLVER_GetMessage *msg;
198 struct GetAddressContext *actx;
199 size_t slen;
200
201 slen = strlen (hostname) + 1;
202 if (slen + sizeof (struct GNUNET_RESOLVER_GetMessage) >
203 GNUNET_SERVER_MAX_MESSAGE_SIZE)
204 {
205 GNUNET_break (0);
206 callback (cls, NULL, 0);
207 return;
208 }
209 client = GNUNET_CLIENT_connect (sched, "resolver", cfg);
210 if (client == NULL)
211 {
212 callback (cls, NULL, 0);
213 return;
214 }
215 msg = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_GetMessage) + slen);
216 msg->header.size =
217 htons (sizeof (struct GNUNET_RESOLVER_GetMessage) + slen);
218 msg->header.type = htons (GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST);
219 msg->direction = htonl (GNUNET_NO);
220 msg->domain = htonl (domain);
221 memcpy (&msg[1], hostname, slen);
222 actx = GNUNET_malloc (sizeof (struct GetAddressContext));
223 actx->callback = callback;
224 actx->cls = cls;
225 actx->client = client;
226 actx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
227 actx->msg = msg;
228
229#if DEBUG_RESOLVER
230 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
231 _("Resolver requests DNS resolution of hostname `%s'.\n"),
232 hostname);
233#endif
234 if (NULL ==
235 GNUNET_CLIENT_notify_transmit_ready (client,
236 slen +
237 sizeof (struct
238 GNUNET_RESOLVER_GetMessage),
239 timeout, &transmit_get_ip, actx))
240 {
241 GNUNET_free (msg);
242 GNUNET_free (actx);
243 callback (cls, NULL, 0);
244 GNUNET_CLIENT_disconnect (client);
245 return;
246 }
247}
248
249
250struct GetHostnameContext
251{
252 GNUNET_RESOLVER_HostnameCallback callback;
253 void *cls;
254 struct GNUNET_RESOLVER_GetMessage *msg;
255 struct GNUNET_CLIENT_Connection *client;
256 struct GNUNET_TIME_Absolute timeout;
257};
258
259
260static void
261handle_hostname_response (void *cls, const struct GNUNET_MessageHeader *msg)
262{
263 struct GetHostnameContext *ghc = cls;
264 uint16_t size;
265 const char *hostname;
266
267 if (msg == NULL)
268 {
269 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
270 _("Timeout trying to resolve IP address.\n"));
271 ghc->callback (ghc->cls, NULL);
272 GNUNET_CLIENT_disconnect (ghc->client);
273 GNUNET_free (ghc);
274 return;
275 }
276 size = ntohs (msg->size);
277 if (size == sizeof (struct GNUNET_MessageHeader))
278 {
279#if DEBUG_RESOLVER
280 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
281 _("Received end message resolving IP address.\n"));
282#endif
283 ghc->callback (ghc->cls, NULL);
284 GNUNET_CLIENT_disconnect (ghc->client);
285 GNUNET_free (ghc);
286 return;
287 }
288 hostname = (const char *) &msg[1];
289 if (hostname[size - sizeof (struct GNUNET_MessageHeader) - 1] != '\0')
290 {
291 GNUNET_break (0);
292 ghc->callback (ghc->cls, NULL);
293 GNUNET_CLIENT_disconnect (ghc->client);
294 GNUNET_free (ghc);
295 return;
296 }
297#if DEBUG_RESOLVER
298 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
299 _("Resolver returns `%s'.\n"), hostname);
300#endif
301 ghc->callback (ghc->cls, hostname);
302 GNUNET_CLIENT_receive (ghc->client,
303 &handle_hostname_response,
304 ghc,
305 GNUNET_TIME_absolute_get_remaining (ghc->timeout));
306}
307
308
309static size_t
310transmit_get_hostname (void *cls, size_t size, void *buf)
311{
312 struct GetHostnameContext *hctx = cls;
313 uint16_t msize;
314
315 if (buf == NULL)
316 {
317 GNUNET_free (hctx->msg);
318 hctx->callback (hctx->cls, NULL);
319 GNUNET_CLIENT_disconnect (hctx->client);
320 GNUNET_free (hctx);
321 return 0;
322 }
323 msize = ntohs (hctx->msg->header.size);
324 GNUNET_assert (size >= msize);
325 memcpy (buf, hctx->msg, msize);
326 GNUNET_free (hctx->msg);
327 hctx->msg = NULL;
328 GNUNET_CLIENT_receive (hctx->client,
329 &handle_hostname_response,
330 hctx,
331 GNUNET_TIME_absolute_get_remaining (hctx->timeout));
332 return msize;
333}
334
335
336
337
338/**
339 * Get an IP address as a string.
340 *
341 * @param sched scheduler to use
342 * @param cfg configuration to use
343 * @param sa host address
344 * @param salen length of host address
345 * @param do_resolve use GNUNET_NO to return numeric hostname
346 * @param timeout how long to try resolving
347 * @param callback function to call with hostnames
348 * @param cls closure for callback
349 */
350void
351GNUNET_RESOLVER_hostname_get (struct GNUNET_SCHEDULER_Handle *sched,
352 struct GNUNET_CONFIGURATION_Handle *cfg,
353 const struct sockaddr *sa,
354 socklen_t salen,
355 int do_resolve,
356 struct GNUNET_TIME_Relative timeout,
357 GNUNET_RESOLVER_HostnameCallback callback,
358 void *cls)
359{
360 char *result;
361 struct GNUNET_CLIENT_Connection *client;
362 struct GNUNET_RESOLVER_GetMessage *msg;
363 struct GetHostnameContext *hctx;
364
365 if (GNUNET_NO == do_resolve)
366 {
367 result = no_resolve (sa, salen);
368#if DEBUG_RESOLVER
369 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
370 _("Resolver returns `%s'.\n"), result);
371#endif
372 callback (cls, result);
373 if (result != NULL)
374 {
375 GNUNET_free (result);
376 callback (cls, NULL);
377 }
378 return;
379 }
380 if (salen + sizeof (struct GNUNET_RESOLVER_GetMessage) >
381 GNUNET_SERVER_MAX_MESSAGE_SIZE)
382 {
383 GNUNET_break (0);
384 callback (cls, NULL);
385 return;
386 }
387 client = GNUNET_CLIENT_connect (sched, "resolver", cfg);
388 if (client == NULL)
389 {
390 callback (cls, NULL);
391 return;
392 }
393 msg = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_GetMessage) + salen);
394 msg->header.size =
395 htons (sizeof (struct GNUNET_RESOLVER_GetMessage) + salen);
396 msg->header.type = htons (GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST);
397 msg->direction = htonl (GNUNET_YES);
398 msg->domain = htonl (sa->sa_family);
399 memcpy (&msg[1], sa, salen);
400#if DEBUG_RESOLVER
401 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
402 _("Resolver requests DNS resolution of IP address.\n"));
403#endif
404 hctx = GNUNET_malloc (sizeof (struct GetHostnameContext));
405 hctx->callback = callback;
406 hctx->cls = cls;
407 hctx->client = client;
408 hctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
409 hctx->msg = msg;
410 if (NULL ==
411 GNUNET_CLIENT_notify_transmit_ready (client,
412 sizeof (struct
413 GNUNET_RESOLVER_GetMessage)
414 + salen, timeout,
415 &transmit_get_hostname, hctx))
416 {
417 GNUNET_free (msg);
418 callback (cls, NULL);
419 GNUNET_CLIENT_disconnect (client);
420 GNUNET_free (hctx);
421 }
422}
423
424/**
425 * Maximum supported length of hostname
426 */
427#define MAX_HOSTNAME 1024
428
429
430/**
431 * Resolve our hostname to an IP address.
432 *
433 * @param sched scheduler to use
434 * @param cfg configuration to use
435 * @param domain AF_INET or AF_INET6; use AF_UNSPEC for "any"
436 * @param callback function to call with addresses
437 * @param cls closure for callback
438 * @param timeout how long to try resolving
439 */
440void
441GNUNET_RESOLVER_hostname_resolve (struct GNUNET_SCHEDULER_Handle *sched,
442 struct GNUNET_CONFIGURATION_Handle *cfg,
443 int domain,
444 struct GNUNET_TIME_Relative timeout,
445 GNUNET_RESOLVER_AddressCallback callback,
446 void *cls)
447{
448 char hostname[MAX_HOSTNAME];
449
450 if (0 != gethostname (hostname, sizeof (hostname) - 1))
451 {
452 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR |
453 GNUNET_ERROR_TYPE_BULK, "gethostname");
454 callback (cls, NULL, 0);
455 return;
456 }
457#if DEBUG_RESOLVER
458 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
459 _("Resolving our hostname `%s'\n"), hostname);
460#endif
461 GNUNET_RESOLVER_ip_get (sched,
462 cfg, hostname, domain, timeout, callback, cls);
463}
464
465
466
467
468/* end of resolver_api.c */
diff --git a/src/resolver/test_resolver_api.c b/src/resolver/test_resolver_api.c
new file mode 100644
index 000000000..240879d73
--- /dev/null
+++ b/src/resolver/test_resolver_api.c
@@ -0,0 +1,229 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 resolver/test_resolver_api.c
22 * @brief testcase for resolver_api.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_getopt_lib.h"
27#include "gnunet_os_lib.h"
28#include "gnunet_program_lib.h"
29#include "gnunet_scheduler_lib.h"
30#include "gnunet_resolver_service.h"
31#include "resolver.h"
32
33#define VERBOSE GNUNET_NO
34
35
36static void
37check_hostname (void *cls, const struct sockaddr *sa, socklen_t salen)
38{
39 char buf[INET6_ADDRSTRLEN];
40 int *ok = cls;
41
42 if (salen == 0)
43 {
44 (*ok) &= ~8;
45 return;
46 }
47 if (salen == sizeof (struct sockaddr_in))
48 {
49 struct sockaddr_in *in = (struct sockaddr_in *) sa;
50 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
51 _("Got IP address `%s' for our host.\n"),
52 inet_ntop (AF_INET, &in->sin_addr, buf, sizeof (buf)));
53 }
54 else if (salen == sizeof (struct sockaddr_in6))
55 {
56 struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) sa;
57 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
58 _("Got IP address `%s' for our host.\n"),
59 inet_ntop (AF_INET6, &in6->sin6_addr, buf, sizeof (buf)));
60 }
61 else
62 {
63 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
64 _("Got address of bogus length %u\n"), salen);
65 GNUNET_assert (0);
66 }
67}
68
69
70static void
71check_localhost_num (void *cls, const char *hostname)
72{
73 int *ok = cls;
74 if (hostname == NULL)
75 return;
76 if (0 == strcmp (hostname, "127.0.0.1"))
77 {
78#if DEBUG_RESOLVER
79 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
80 "Received correct hostname `%s'.\n", hostname);
81#endif
82 (*ok) &= ~4;
83 }
84 else
85 {
86#if DEBUG_RESOLVER
87 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
88 "Received invalid hostname `%s'.\n", hostname);
89#endif
90 GNUNET_break (0);
91 }
92}
93
94static void
95check_localhost (void *cls, const char *hostname)
96{
97 int *ok = cls;
98 if (hostname == NULL)
99 return;
100 if (0 == strcmp (hostname, "localhost"))
101 {
102#if DEBUG_RESOLVER
103 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
104 "Received correct hostname `%s'.\n", hostname);
105#endif
106 (*ok) &= ~2;
107 }
108 else
109 {
110#if DEBUG_RESOLVER
111 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
112 "Received invalid hostname `%s'.\n", hostname);
113#endif
114 GNUNET_break (0);
115 }
116}
117
118static void
119check_127 (void *cls, const struct sockaddr *sa, socklen_t salen)
120{
121 int *ok = cls;
122 const struct sockaddr_in *sai = (const struct sockaddr_in *) sa;
123
124 if (sa == NULL)
125 return;
126 GNUNET_assert (sizeof (struct sockaddr_in) == salen);
127 if (sai->sin_addr.s_addr == htonl (INADDR_LOOPBACK))
128 {
129#if DEBUG_RESOLVER
130 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received correct address.\n");
131#endif
132 (*ok) &= ~1;
133 }
134 else
135 {
136#if DEBUG_RESOLVER
137 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received incorrect address.\n");
138#endif
139 GNUNET_break (0);
140 }
141}
142
143static void
144run (void *cls,
145 struct GNUNET_SCHEDULER_Handle *sched,
146 char *const *args,
147 const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *cfg)
148{
149 struct sockaddr_in sa;
150 struct GNUNET_TIME_Relative timeout =
151 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
152 2500);
153 memset (&sa, 0, sizeof (sa));
154 sa.sin_family = AF_INET;
155 sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
156 GNUNET_RESOLVER_ip_get (sched,
157 cfg,
158 "localhost", AF_INET, timeout, &check_127, cls);
159 GNUNET_RESOLVER_hostname_get (sched,
160 cfg,
161 (const struct sockaddr *) &sa,
162 sizeof (struct sockaddr),
163 GNUNET_YES, timeout, &check_localhost, cls);
164 GNUNET_RESOLVER_hostname_get (sched,
165 cfg,
166 (const struct sockaddr *) &sa,
167 sizeof (struct sockaddr),
168 GNUNET_NO,
169 timeout, &check_localhost_num, cls);
170 GNUNET_RESOLVER_hostname_resolve (sched,
171 cfg,
172 AF_UNSPEC, timeout, &check_hostname, cls);
173}
174
175static int
176check ()
177{
178 int ok = 1 + 2 + 4 + 8;
179 pid_t pid;
180 char *const argv[] = { "test-resolver-api",
181 "-c",
182 "test_resolver_api_data.conf",
183#if VERBOSE
184 "-L", "DEBUG",
185#endif
186 NULL
187 };
188 struct GNUNET_GETOPT_CommandLineOption options[] = {
189 GNUNET_GETOPT_OPTION_END
190 };
191 pid = GNUNET_OS_start_process ("gnunet-service-resolver",
192 "gnunet-service-resolver",
193#if VERBOSE
194 "-L", "DEBUG",
195#endif
196 "-c", "test_resolver_api_data.conf", NULL);
197 sleep (1);
198 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
199 argv, "test-resolver-api", "nohelp",
200 options, &run, &ok);
201 if (0 != PLIBC_KILL (pid, SIGTERM))
202 {
203 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
204 ok = 1;
205 }
206 waitpid (pid, NULL, 0);
207 if (ok != 0)
208 fprintf (stderr, "Missed some resolutions: %u\n", ok);
209 return ok;
210}
211
212int
213main (int argc, char *argv[])
214{
215 int ret;
216
217 GNUNET_log_setup ("test-resolver-api",
218#if VERBOSE
219 "DEBUG",
220#else
221 "WARNING",
222#endif
223 NULL);
224 ret = check ();
225
226 return ret;
227}
228
229/* end of test_resolver_api.c */
diff --git a/src/resolver/test_resolver_api_data.conf b/src/resolver/test_resolver_api_data.conf
new file mode 100644
index 000000000..c31668117
--- /dev/null
+++ b/src/resolver/test_resolver_api_data.conf
@@ -0,0 +1,5 @@
1[PATHS]
2SERVICEHOME = /tmp/test-gnunetd-statistics/
3
4[resolver]
5PORT = 22354
diff --git a/src/statistics/Makefile.am b/src/statistics/Makefile.am
new file mode 100644
index 000000000..2ae254cbf
--- /dev/null
+++ b/src/statistics/Makefile.am
@@ -0,0 +1,59 @@
1INCLUDES = -I$(top_srcdir)/src/include
2
3if MINGW
4 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
5endif
6
7if USE_COVERAGE
8 AM_CFLAGS = -fprofile-arcs -ftest-coverage
9endif
10
11
12lib_LTLIBRARIES = libgnunetstatistics.la
13
14libgnunetstatistics_la_SOURCES = \
15 statistics_api.c statistics.h
16libgnunetstatistics_la_LIBADD = \
17 $(top_builddir)/src/util/libgnunetutil.la \
18 $(GN_LIBINTL)
19libgnunetstatistics_la_LDFLAGS = \
20 $(GN_LIB_LDFLAGS) $(WINFLAGS) \
21 -version-info 0:0:0
22
23
24bin_PROGRAMS = \
25 gnunet-statistics \
26 gnunet-service-statistics
27
28gnunet_statistics_SOURCES = \
29 gnunet-statistics.c
30gnunet_statistics_LDADD = \
31 $(top_builddir)/src/statistics/libgnunetstatistics.la \
32 $(top_builddir)/src/util/libgnunetutil.la \
33 $(GN_LIBINTL)
34
35gnunet_service_statistics_SOURCES = \
36 gnunet-service-statistics.c
37gnunet_service_statistics_LDADD = \
38 $(top_builddir)/src/statistics/libgnunetstatistics.la \
39 $(top_builddir)/src/util/libgnunetutil.la \
40 $(GN_LIBINTL)
41
42
43check_PROGRAMS = \
44 test_statistics_api
45
46TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
47
48test_statistics_api_SOURCES = \
49 test_statistics_api.c
50test_statistics_api_LDADD = \
51 $(top_builddir)/src/statistics/libgnunetstatistics.la \
52 $(top_builddir)/src/util/libgnunetutil.la
53
54EXTRA_DIST = \
55 test_statistics_api_data.conf
56
57check_SCRIPTS = \
58 test_gnunet_statistics.sh
59
diff --git a/src/statistics/gnunet-service-statistics.c b/src/statistics/gnunet-service-statistics.c
new file mode 100644
index 000000000..0e7b4853d
--- /dev/null
+++ b/src/statistics/gnunet-service-statistics.c
@@ -0,0 +1,470 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 statistics/gnunet-service-statistics.c
23 * @brief program that tracks statistics
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_disk_lib.h"
28#include "gnunet_getopt_lib.h"
29#include "gnunet_protocols.h"
30#include "gnunet_service_lib.h"
31#include "gnunet_statistics_service.h"
32#include "gnunet_strings_lib.h"
33#include "gnunet_time_lib.h"
34#include "statistics.h"
35
36/**
37 * Entry in the statistics list.
38 */
39struct StatsEntry
40{
41 /**
42 * This is a linked list.
43 */
44 struct StatsEntry *next;
45
46 /**
47 * Name of the service, points into the
48 * middle of msg.
49 */
50 const char *service;
51
52 /**
53 * Name for the value, points into
54 * the middle of msg.
55 */
56 const char *name;
57
58 /**
59 * Message that can be used to set this value,
60 * stored at the end of the memory used by
61 * this struct.
62 */
63 struct GNUNET_STATISTICS_SetMessage *msg;
64
65 /**
66 * Our value.
67 */
68 uint64_t value;
69
70 /**
71 * Unique ID.
72 */
73 uint32_t uid;
74
75 /**
76 * Is this value persistent?
77 */
78 int persistent;
79
80};
81
82/**
83 * Linked list of our active statistics.
84 */
85static struct StatsEntry *start;
86
87/**
88 * Counter used to generate unique values.
89 */
90static uint32_t uidgen;
91
92/**
93 * Load persistent values from disk. Disk format is
94 * exactly the same format that we also use for
95 * setting the values over the network.
96 */
97static void
98load (struct GNUNET_SERVER_Handle *server,
99 struct GNUNET_CONFIGURATION_Handle *cfg)
100{
101 char *fn;
102 int fd;
103 struct stat sb;
104 char *buf;
105 size_t off;
106 const struct GNUNET_MessageHeader *msg;
107
108 fn = GNUNET_DISK_get_home_filename (cfg,
109 "statistics", "statistics.data", NULL);
110 if (fn == NULL)
111 return;
112 if ((0 != stat (fn, &sb)) || (sb.st_size == 0))
113 {
114 GNUNET_free (fn);
115 return;
116 }
117 fd = GNUNET_DISK_file_open (fn, O_RDONLY);
118 if (fd == -1)
119 {
120 GNUNET_free (fn);
121 return;
122 }
123 buf = mmap (NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
124 if (MAP_FAILED == buf)
125 {
126 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "mmap", fn);
127 GNUNET_break (0 == CLOSE (fd));
128 GNUNET_free (fn);
129 return;
130 }
131 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
132 _("Loading %llu bytes of statistics from `%s'\n"),
133 (unsigned long long) sb.st_size, fn);
134 off = 0;
135 while (off + sizeof (struct GNUNET_MessageHeader) < sb.st_size)
136 {
137 msg = (const struct GNUNET_MessageHeader *) &buf[off];
138 if ((ntohs (msg->size) + off > sb.st_size) ||
139 (GNUNET_OK != GNUNET_SERVER_inject (server, NULL, msg)))
140 {
141 GNUNET_break (0);
142 break;
143 }
144 off += ntohs (msg->size);
145 }
146 GNUNET_break (0 == munmap (buf, sb.st_size));
147 GNUNET_break (0 == CLOSE (fd));
148 GNUNET_free (fn);
149}
150
151
152/**
153 * Write persistent statistics to disk.
154 *
155 * @param cls closure
156 * @param cfg configuration to use
157 */
158static void
159save (void *cls, struct GNUNET_CONFIGURATION_Handle *cfg)
160{
161 struct StatsEntry *pos;
162 char *fn;
163 int fd;
164 uint16_t size;
165 unsigned long long total;
166
167 fd = -1;
168 fn = GNUNET_DISK_get_home_filename (cfg,
169 "statistics", "statistics.data", NULL);
170 if (fn != NULL)
171 fd =
172 GNUNET_DISK_file_open (fn, O_WRONLY | O_CREAT | O_TRUNC,
173 S_IRUSR | S_IWUSR);
174 total = 0;
175 while (NULL != (pos = start))
176 {
177 start = pos->next;
178 if ((pos->persistent) && (fd != -1))
179 {
180 size = htons (pos->msg->header.size);
181 if (size != WRITE (fd, pos->msg, size))
182 {
183 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
184 "write", fn);
185 GNUNET_DISK_file_close (fn, fd);
186 fd = -1;
187 }
188 else
189 total += size;
190 }
191 GNUNET_free (pos);
192 }
193 if (fd != -1)
194 {
195 GNUNET_DISK_file_close (fn, fd);
196 if (total == 0)
197 GNUNET_break (0 == UNLINK (fn));
198 else
199 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
200 _("Wrote %llu bytes of statistics to `%s'\n"), total, fn);
201 }
202 GNUNET_free_non_null (fn);
203}
204
205
206/**
207 * Transmit the given stats value.
208 */
209static void
210transmit (struct GNUNET_SERVER_TransmitContext *tc,
211 const struct StatsEntry *e)
212{
213 struct GNUNET_STATISTICS_ReplyMessage *m;
214 struct GNUNET_MessageHeader *h;
215 size_t size;
216 uint16_t msize;
217
218 size =
219 sizeof (struct GNUNET_STATISTICS_ReplyMessage) + strlen (e->service) + 1 +
220 strlen (e->name) + 1;
221 GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
222 msize = size - sizeof (struct GNUNET_MessageHeader);
223 m = GNUNET_malloc (size);
224 m->uid = htonl (e->uid);
225 if (e->persistent)
226 m->uid |= htonl (GNUNET_STATISTICS_PERSIST_BIT);
227 m->value = GNUNET_htonll (e->value);
228 size -= sizeof (struct GNUNET_STATISTICS_ReplyMessage);
229 GNUNET_assert (size == GNUNET_STRINGS_buffer_fill ((char *) &m[1],
230 size,
231 2, e->service, e->name));
232#if DEBUG_STATISTICS
233 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
234 "Transmitting value for `%s:%s': %llu\n",
235 e->service, e->name, e->value);
236#endif
237 h = &m->header;
238 GNUNET_SERVER_transmit_context_append (tc,
239 &h[1],
240 msize,
241 GNUNET_MESSAGE_TYPE_STATISTICS_VALUE);
242 GNUNET_free (m);
243}
244
245
246/**
247 * Does this entry match the request?
248 */
249static int
250matches (const struct StatsEntry *e, const char *service, const char *name)
251{
252 return ((0 == strlen (service)) ||
253 (0 == strcmp (service, e->service)))
254 && ((0 == strlen (name)) || (0 == strcmp (name, e->name)));
255}
256
257
258/**
259 * Handle GET-message.
260 *
261 * @param cls closure
262 * @param server the server handling the message
263 * @param client identification of the client
264 * @param message the actual message
265 * @return GNUNET_OK to keep the connection open,
266 * GNUNET_SYSERR to close it (signal serious error)
267 */
268static void
269handle_get (void *cls,
270 struct GNUNET_SERVER_Handle *server,
271 struct GNUNET_SERVER_Client *client,
272 const struct GNUNET_MessageHeader *message)
273{
274 char *service;
275 char *name;
276 struct StatsEntry *pos;
277 struct GNUNET_SERVER_TransmitContext *tc;
278 size_t size;
279
280 size = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader);
281 if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
282 size, 2, &service, &name))
283 {
284 GNUNET_break (0);
285 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
286 return;
287 }
288#if DEBUG_STATISTICS
289 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
290 "Received request for statistics on `%s:%s'\n",
291 strlen (service) ? service : "*", strlen (name) ? name : "*");
292#endif
293 tc = GNUNET_SERVER_transmit_context_create (client);
294 pos = start;
295 while (pos != NULL)
296 {
297 if (matches (pos, service, name))
298 transmit (tc, pos);
299 pos = pos->next;
300 }
301 GNUNET_SERVER_transmit_context_append (tc, NULL, 0,
302 GNUNET_MESSAGE_TYPE_STATISTICS_END);
303 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
304}
305
306
307/**
308 * Handle SET-message.
309 *
310 * @param cls closure
311 * @param server the server handling the message
312 * @param client identification of the client
313 * @param message the actual message
314 */
315static void
316handle_set (void *cls,
317 struct GNUNET_SERVER_Handle *server,
318 struct GNUNET_SERVER_Client *client,
319 const struct GNUNET_MessageHeader *message)
320{
321 char *service;
322 char *name;
323 uint16_t msize;
324 uint16_t size;
325 const struct GNUNET_STATISTICS_SetMessage *msg;
326 struct StatsEntry *pos;
327 struct StatsEntry *prev;
328 uint32_t flags;
329 uint64_t value;
330 int64_t delta;
331
332 msize = ntohs (message->size);
333 if (msize < sizeof (struct GNUNET_STATISTICS_SetMessage))
334 {
335 GNUNET_break (0);
336 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
337 return;
338 }
339 size = msize - sizeof (struct GNUNET_STATISTICS_SetMessage);
340 msg = (const struct GNUNET_STATISTICS_SetMessage *) message;
341
342 if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &msg[1],
343 size, 2, &service, &name))
344 {
345 GNUNET_break (0);
346 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
347 return;
348 }
349#if DEBUG_STATISTICS
350 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
351 "Received request to update statistic on `%s:%s'\n",
352 service, name);
353#endif
354 flags = ntohl (msg->flags);
355 value = GNUNET_ntohll (msg->value);
356 pos = start;
357 prev = NULL;
358 while (pos != NULL)
359 {
360 if (matches (pos, service, name))
361 {
362 if ((flags & GNUNET_STATISTICS_SETFLAG_RELATIVE) == 0)
363 {
364 pos->value = value;
365 }
366 else
367 {
368 delta = (int64_t) value;
369 if ((delta < 0) && (pos->value < -delta))
370 {
371 pos->value = 0;
372 }
373 else
374 {
375 GNUNET_break ((delta <= 0) ||
376 (pos->value + delta > pos->value));
377 pos->value += delta;
378 }
379 }
380 pos->msg->value = GNUNET_htonll (pos->value);
381 pos->msg->flags = msg->flags;
382 pos->persistent =
383 (0 != (flags & GNUNET_STATISTICS_SETFLAG_PERSISTENT));
384 if (prev != NULL)
385 {
386 /* move to front for faster setting next time! */
387 prev->next = pos->next;
388 pos->next = start;
389 start = pos;
390 }
391#if DEBUG_STATISTICS
392 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
393 "Statistic `%s:%s' updated to value %llu.\n",
394 service, name, pos->value);
395#endif
396 GNUNET_SERVER_receive_done (client, GNUNET_OK);
397 return;
398 }
399 prev = pos;
400 pos = pos->next;
401 }
402 pos = GNUNET_malloc (sizeof (struct StatsEntry) + msize);
403 pos->next = start;
404 if (((flags & GNUNET_STATISTICS_SETFLAG_RELATIVE) == 0) ||
405 (0 < (int64_t) GNUNET_ntohll (msg->value)))
406 pos->value = GNUNET_ntohll (msg->value);
407 pos->uid = uidgen++;
408 pos->persistent = (0 != (flags & GNUNET_STATISTICS_SETFLAG_PERSISTENT));
409 pos->msg = (void *) &pos[1];
410 memcpy (pos->msg, message, ntohs (message->size));
411 pos->service = (const char *) &pos->msg[1];
412 pos->name = &pos->service[strlen (pos->service) + 1];
413
414 start = pos;
415#if DEBUG_STATISTICS
416 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
417 "New statistic on `%s:%s' with value %llu created.\n",
418 service, name, pos->value);
419#endif
420 GNUNET_SERVER_receive_done (client, GNUNET_OK);
421}
422
423
424/**
425 * List of handlers for the messages understood by this
426 * service.
427 */
428static struct GNUNET_SERVER_MessageHandler handlers[] = {
429 {&handle_set, NULL, GNUNET_MESSAGE_TYPE_STATISTICS_SET, 0},
430 {&handle_get, NULL, GNUNET_MESSAGE_TYPE_STATISTICS_GET, 0},
431 {NULL, NULL, 0, 0}
432};
433
434
435/**
436 * Process statistics requests.
437 *
438 * @param cls closure
439 * @param sched scheduler to use
440 * @param server the initialized server
441 * @param cfg configuration to use
442 */
443static void
444run (void *cls,
445 struct GNUNET_SCHEDULER_Handle *sched,
446 struct GNUNET_SERVER_Handle *server,
447 struct GNUNET_CONFIGURATION_Handle *cfg)
448{
449 GNUNET_SERVER_add_handlers (server, handlers);
450 load (server, cfg);
451}
452
453
454/**
455 * The main function for the statistics service.
456 *
457 * @param argc number of arguments from the command line
458 * @param argv command line arguments
459 * @return 0 ok, 1 on error
460 */
461int
462main (int argc, char *const *argv)
463{
464 return (GNUNET_OK ==
465 GNUNET_SERVICE_run (argc,
466 argv,
467 "statistics", &run, NULL, &save, NULL)) ? 0 : 1;
468}
469
470/* end of gnunet-service-statistics.c */
diff --git a/src/statistics/gnunet-statistics.c b/src/statistics/gnunet-statistics.c
new file mode 100644
index 000000000..bafb77c66
--- /dev/null
+++ b/src/statistics/gnunet-statistics.c
@@ -0,0 +1,179 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009 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 2, 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 statistics/gnunet-statistics.c
23 * @brief tool to obtain statistics
24 * @author Christian Grothoff
25 * @author Igor Wronsky
26 */
27#include "platform.h"
28#include "gnunet_getopt_lib.h"
29#include "gnunet_program_lib.h"
30#include "gnunet_statistics_service.h"
31#include "statistics.h"
32
33#define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
34
35/**
36 * Final status code.
37 */
38static int ret;
39
40/**
41 * Set to subsystem that we're going to get stats for (or NULL for all).
42 */
43static char *subsystem;
44
45/**
46 * Set to the specific stat value that we are after (or NULL for all).
47 */
48static char *name;
49
50/**
51 * Make the value that is being set persistent.
52 */
53static int persistent;
54
55/**
56 * Callback function to process statistic values.
57 *
58 * @param cls closure
59 * @param subsystem name of subsystem that created the statistic
60 * @param name the name of the datum
61 * @param value the current value
62 * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not
63 * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration
64 */
65static int
66printer (void *cls,
67 const char *subsystem,
68 const char *sname, unsigned long long value, int is_persistent)
69{
70 FPRINTF (stdout,
71 "%s%-20s %-40s: %16llu\n",
72 is_persistent ? "!" : " ", subsystem, _(sname), value);
73 return GNUNET_OK;
74}
75
76
77/**
78 * Function called last by the statistics code.
79 *
80 * @param cls closure
81 * @param success GNUNET_OK if statistics were
82 * successfully obtained, GNUNET_SYSERR if not.
83 */
84static void
85cleanup (void *cls, int success)
86{
87 struct GNUNET_STATISTICS_Handle *h = cls;
88
89 if (success != GNUNET_OK)
90 ret = 1;
91 if (h != NULL)
92 GNUNET_STATISTICS_destroy (h);
93}
94
95
96/**
97 * Main function that will be run by the scheduler.
98 *
99 * @param cls closure
100 * @param sched the scheduler to use
101 * @param args remaining command-line arguments
102 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
103 * @param cfg configuration
104 */
105static void
106run (void *cls,
107 struct GNUNET_SCHEDULER_Handle *sched,
108 char *const *args,
109 const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *cfg)
110{
111 struct GNUNET_STATISTICS_Handle *h;
112 unsigned long long val;
113
114 if (args[0] != NULL)
115 {
116 if ((1 != SSCANF (args[0], "%llu", &val)) ||
117 (subsystem == NULL) || (name == NULL))
118 {
119 FPRINTF (stderr, _("Invalid argument `%s'\n"), args[0]);
120 ret = 1;
121 return;
122 }
123 h = GNUNET_STATISTICS_create (sched, subsystem, cfg);
124 if (h == NULL)
125 {
126 ret = 1;
127 return;
128 }
129 GNUNET_STATISTICS_set (h, name, val, persistent);
130 GNUNET_STATISTICS_destroy (h);
131 return;
132 }
133 h = GNUNET_STATISTICS_create (sched, "gnunet-statistics", cfg);
134 if (h == NULL)
135 {
136 ret = 1;
137 return;
138 }
139 GNUNET_STATISTICS_get (h,
140 subsystem, name, GET_TIMEOUT, &cleanup, &printer, h);
141}
142
143/**
144 * gnunet-statistics command line options
145 */
146static struct GNUNET_GETOPT_CommandLineOption options[] = {
147 {'n', "name", "NAME",
148 gettext_noop ("limit output to statistcs for the given NAME"), 1,
149 &GNUNET_GETOPT_set_string, &name},
150 {'p', "persistent", NULL,
151 gettext_noop ("make the value being set persistent"), 0,
152 &GNUNET_GETOPT_set_one, &persistent},
153 {'s', "subsystem", "SUBSYSTEM",
154 gettext_noop ("limit output to the given SUBSYSTEM"), 1,
155 &GNUNET_GETOPT_set_string, &subsystem},
156 GNUNET_GETOPT_OPTION_END
157};
158
159
160/**
161 * The main function to obtain statistics in GNUnet.
162 *
163 * @param argc number of arguments from the command line
164 * @param argv command line arguments
165 * @return 0 ok, 1 on error
166 */
167int
168main (int argc, char *const *argv)
169{
170 return (GNUNET_OK ==
171 GNUNET_PROGRAM_run (argc,
172 argv,
173 "gnunet-statistics",
174 gettext_noop
175 ("Print statistics about GNUnet operations."),
176 options, &run, NULL)) ? ret : 1;
177}
178
179/* end of gnunet-statistics.c */
diff --git a/src/statistics/statistics.h b/src/statistics/statistics.h
new file mode 100644
index 000000000..6eedd4d34
--- /dev/null
+++ b/src/statistics/statistics.h
@@ -0,0 +1,94 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2009 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 2, 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 * @author Christian Grothoff
23 * @file statistics/statistics.h
24 */
25#ifndef STATISTICS_H
26#define STATISTICS_H
27
28#include "gnunet_common.h"
29
30#define DEBUG_STATISTICS 0
31
32/**
33 * Statistics message. Contains how long the system is up
34 * and one value.
35 *
36 * The struct is be followed by the service name and
37 * name of the statistic, both 0-terminated.
38 */
39struct GNUNET_STATISTICS_ReplyMessage
40{
41 /**
42 * Type: GNUNET_MESSAGE_TYPE_STATISTICS_VALUE
43 */
44 struct GNUNET_MessageHeader header;
45
46 /**
47 * Unique numerical identifier for the value (will
48 * not change during the same client-session). Highest
49 * bit will be set for persistent values.
50 */
51 uint32_t uid GNUNET_PACKED;
52
53 /**
54 * The value.
55 */
56 uint64_t value GNUNET_PACKED;
57
58};
59
60#define GNUNET_STATISTICS_PERSIST_BIT (1<<31)
61
62#define GNUNET_STATISTICS_SETFLAG_ABSOLUTE 0
63
64#define GNUNET_STATISTICS_SETFLAG_RELATIVE 1
65
66#define GNUNET_STATISTICS_SETFLAG_PERSISTENT 2
67
68/**
69 * Message to set a statistic. Followed
70 * by the subsystem name and the name of
71 * the statistic (each 0-terminated).
72 */
73struct GNUNET_STATISTICS_SetMessage
74{
75 /**
76 * Type: GNUNET_MESSAGE_TYPE_STATISTICS_SET
77 */
78 struct GNUNET_MessageHeader header;
79
80 /**
81 * 0 for absolute value, 1 for relative value; 2 to make persistent
82 * (see GNUNET_STATISTICS_SETFLAG_*).
83 */
84 uint32_t flags GNUNET_PACKED;
85
86 /**
87 * Value. Note that if this is a relative value, it will
88 * be signed even though the type given here is unsigned.
89 */
90 uint64_t value GNUNET_PACKED;
91
92};
93
94#endif
diff --git a/src/statistics/statistics_api.c b/src/statistics/statistics_api.c
new file mode 100644
index 000000000..f68cf9396
--- /dev/null
+++ b/src/statistics/statistics_api.c
@@ -0,0 +1,688 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 statistics/statistics_api.c
23 * @brief API of the statistics service
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_client_lib.h"
28#include "gnunet_protocols.h"
29#include "gnunet_server_lib.h"
30#include "gnunet_statistics_service.h"
31#include "gnunet_strings_lib.h"
32#include "statistics.h"
33
34#define SET_TRANSMIT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
35
36
37/**
38 * Types of actions.
39 */
40enum ActionType
41{
42 ACTION_GET,
43 ACTION_SET,
44 ACTION_UPDATE
45};
46
47
48/**
49 * Linked list of things we still need to do.
50 */
51struct ActionItem
52{
53 /**
54 * This is a linked list.
55 */
56 struct ActionItem *next;
57
58 /**
59 * What subsystem is this action about? (can be NULL)
60 */
61 char *subsystem;
62
63 /**
64 * What value is this action about? (can be NULL)
65 */
66 char *name;
67
68 /**
69 * Continuation to call once action is complete.
70 */
71 GNUNET_STATISTICS_Callback cont;
72
73 /**
74 * Function to call (for GET actions only).
75 */
76 GNUNET_STATISTICS_Iterator proc;
77
78 /**
79 * Closure for proc and cont.
80 */
81 void *cls;
82
83 /**
84 * Timeout for this action.
85 */
86 struct GNUNET_TIME_Absolute timeout;
87
88 /**
89 * Associated value.
90 */
91 unsigned long long value;
92
93 /**
94 * Flag for SET/UPDATE actions.
95 */
96 int make_persistent;
97
98 /**
99 * Has the current iteration been aborted; for GET actions.
100 */
101 int aborted;
102
103 /**
104 * Is this a GET, SET or UPDATE?
105 */
106 enum ActionType type;
107
108 /**
109 * Size of the message that we will be transmitting.
110 */
111 uint16_t msize;
112
113};
114
115
116/**
117 * Handle for the service.
118 */
119struct GNUNET_STATISTICS_Handle
120{
121 /**
122 * Our scheduler.
123 */
124 struct GNUNET_SCHEDULER_Handle *sched;
125
126 /**
127 * Name of our subsystem.
128 */
129 char *subsystem;
130
131 /**
132 * Configuration to use.
133 */
134 struct GNUNET_CONFIGURATION_Handle *cfg;
135
136 /**
137 * Socket (if available).
138 */
139 struct GNUNET_CLIENT_Connection *client;
140
141 /**
142 * Head of the linked list of pending actions (first action
143 * to be performed).
144 */
145 struct ActionItem *action_head;
146
147 /**
148 * Tail of the linked list of actions (for fast append).
149 */
150 struct ActionItem *action_tail;
151
152 /**
153 * Action we are currently busy with (action request has been
154 * transmitted, we're now receiving the response from the
155 * service).
156 */
157 struct ActionItem *current;
158
159 /**
160 * Should this handle be destroyed once we've processed
161 * all actions?
162 */
163 int do_destroy;
164
165};
166
167
168/**
169 * Try to (re)connect to the statistics service.
170 *
171 * @return GNUNET_YES on success, GNUNET_NO on failure.
172 */
173static int
174try_connect (struct GNUNET_STATISTICS_Handle *ret)
175{
176 if (ret->client != NULL)
177 return GNUNET_OK;
178 ret->client = GNUNET_CLIENT_connect (ret->sched, "statistics", ret->cfg);
179 if (ret->client != NULL)
180 return GNUNET_YES;
181 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
182 _("Failed to connect to statistics service!\n"));
183 return GNUNET_NO;
184}
185
186
187/**
188 * Free memory associated with the given action item.
189 */
190static void
191free_action_item (struct ActionItem *ai)
192{
193 GNUNET_free_non_null (ai->subsystem);
194 GNUNET_free_non_null (ai->name);
195 GNUNET_free (ai);
196}
197
198
199/**
200 * Get handle for the statistics service.
201 *
202 * @param subsystem name of subsystem using the service
203 * @param cfg services configuration in use
204 * @return handle to use
205 */
206struct GNUNET_STATISTICS_Handle *
207GNUNET_STATISTICS_create (struct GNUNET_SCHEDULER_Handle *sched,
208 const char *subsystem,
209 struct GNUNET_CONFIGURATION_Handle *cfg)
210{
211 struct GNUNET_STATISTICS_Handle *ret;
212
213 GNUNET_assert (subsystem != NULL);
214 GNUNET_assert (sched != NULL);
215 GNUNET_assert (cfg != NULL);
216 ret = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_Handle));
217 ret->sched = sched;
218 ret->cfg = cfg;
219 ret->subsystem = GNUNET_strdup (subsystem);
220 try_connect (ret);
221 return ret;
222}
223
224
225/**
226 * Actually free the handle.
227 */
228static void
229do_destroy (struct GNUNET_STATISTICS_Handle *h)
230{
231 GNUNET_assert (h->action_head == NULL);
232 GNUNET_assert (h->current == NULL);
233 if (h->client != NULL)
234 {
235 GNUNET_CLIENT_disconnect (h->client);
236 h->client = NULL;
237 }
238 GNUNET_free (h->subsystem);
239 GNUNET_free (h);
240}
241
242
243/**
244 * Destroy a handle (free all state associated with
245 * it).
246 */
247void
248GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *handle)
249{
250 GNUNET_assert (handle->do_destroy == GNUNET_NO);
251 if ((handle->action_head != NULL) || (handle->current != NULL))
252 {
253 handle->do_destroy = GNUNET_YES;
254 return;
255 }
256 do_destroy (handle);
257}
258
259
260/**
261 * Process the message.
262 *
263 * @return GNUNET_OK if the message was well-formed
264 */
265static int
266process_message (struct GNUNET_STATISTICS_Handle *h,
267 const struct GNUNET_MessageHeader *msg)
268{
269 char *service;
270 char *name;
271 const struct GNUNET_STATISTICS_ReplyMessage *smsg;
272 uint16_t size;
273
274 if (h->current->aborted)
275 return GNUNET_OK; /* don't bother */
276 size = ntohs (msg->size);
277 if (size < sizeof (struct GNUNET_STATISTICS_ReplyMessage))
278 {
279 GNUNET_break (0);
280 return GNUNET_SYSERR;
281 }
282 smsg = (const struct GNUNET_STATISTICS_ReplyMessage *) msg;
283 size -= sizeof (struct GNUNET_STATISTICS_ReplyMessage);
284 if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &smsg[1],
285 size, 2, &service, &name))
286 {
287 GNUNET_break (0);
288 return GNUNET_SYSERR;
289 }
290#if DEBUG_STATISTICS
291 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
292 "Received valid statistic on `%s:%s': %llu\n",
293 service, name, GNUNET_ntohll (smsg->value));
294#endif
295 if (GNUNET_OK !=
296 h->current->proc (h->current->cls,
297 service,
298 name,
299 GNUNET_ntohll (smsg->value),
300 0 !=
301 (ntohl (smsg->uid) & GNUNET_STATISTICS_PERSIST_BIT)))
302 {
303#if DEBUG_STATISTICS
304 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
305 "Processing of remaining statistics aborted by client.\n");
306#endif
307 h->current->aborted = GNUNET_YES;
308 }
309 return GNUNET_OK;
310}
311
312
313
314/**
315 * Schedule the next action to be performed.
316 */
317static void schedule_action (struct GNUNET_STATISTICS_Handle *h);
318
319
320/**
321 * GET processing is complete, tell client about it.
322 */
323static void
324finish (struct GNUNET_STATISTICS_Handle *h, int code)
325{
326 struct ActionItem *pos = h->current;
327 h->current = NULL;
328 schedule_action (h);
329 if (pos->cont != NULL)
330 pos->cont (pos->cls, code);
331 free_action_item (pos);
332}
333
334
335/**
336 * Function called with messages from stats service.
337 *
338 * @param cls closure
339 * @param msg message received, NULL on timeout or fatal error
340 */
341static void
342receive_stats (void *cls, const struct GNUNET_MessageHeader *msg)
343{
344 struct GNUNET_STATISTICS_Handle *h = cls;
345
346 if (msg == NULL)
347 {
348 GNUNET_CLIENT_disconnect (h->client);
349 h->client = NULL;
350 GNUNET_log (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
351 _
352 ("Error receiving statistics from service, is the service running?\n"));
353 finish (h, GNUNET_SYSERR);
354 return;
355 }
356 switch (ntohs (msg->type))
357 {
358 case GNUNET_MESSAGE_TYPE_STATISTICS_END:
359#if DEBUG_STATISTICS
360 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
361 "Received end of statistics marker\n");
362#endif
363 finish (h, GNUNET_OK);
364 return;
365 case GNUNET_MESSAGE_TYPE_STATISTICS_VALUE:
366 if (GNUNET_OK == process_message (h, msg))
367 {
368 /* finally, look for more! */
369 GNUNET_CLIENT_receive (h->client,
370 &receive_stats,
371 h,
372 GNUNET_TIME_absolute_get_remaining (h->
373 current->
374 timeout));
375 return;
376 }
377 GNUNET_break (0);
378 break;
379 default:
380 GNUNET_break (0);
381 break;
382 }
383 GNUNET_CLIENT_disconnect (h->client);
384 h->client = NULL;
385 finish (h, GNUNET_SYSERR);
386}
387
388
389/**
390 * Transmit a GET request (and if successful, start to receive
391 * the response).
392 */
393static size_t
394transmit_get (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
395{
396 struct GNUNET_MessageHeader *hdr;
397 size_t slen1;
398 size_t slen2;
399 uint16_t msize;
400
401 if (buf == NULL)
402 {
403 /* timeout / error */
404 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
405 _("Transmission of request for statistics failed!\n"));
406 finish (handle, GNUNET_SYSERR);
407 return 0;
408 }
409 slen1 = strlen (handle->current->subsystem) + 1;
410 slen2 = strlen (handle->current->name) + 1;
411 msize = slen1 + slen2 + sizeof (struct GNUNET_MessageHeader);
412 GNUNET_assert (msize <= size);
413 hdr = (struct GNUNET_MessageHeader *) buf;
414 hdr->size = htons (msize);
415 hdr->type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_GET);
416 GNUNET_assert (slen1 + slen2 ==
417 GNUNET_STRINGS_buffer_fill ((char *) &hdr[1],
418 slen1 + slen2,
419 2,
420 handle->current->subsystem,
421 handle->current->name));
422 GNUNET_CLIENT_receive (handle->client,
423 &receive_stats,
424 handle,
425 GNUNET_TIME_absolute_get_remaining (handle->current->
426 timeout));
427 return msize;
428}
429
430
431
432/**
433 * Transmit a SET/UPDATE request.
434 */
435static size_t
436transmit_set (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
437{
438 struct GNUNET_STATISTICS_SetMessage *r;
439 size_t slen;
440 size_t nlen;
441 size_t nsize;
442
443 if (NULL == buf)
444 {
445 finish (handle, GNUNET_SYSERR);
446 return 0;
447 }
448
449 slen = strlen (handle->current->subsystem) + 1;
450 nlen = strlen (handle->current->name) + 1;
451 nsize = sizeof (struct GNUNET_STATISTICS_SetMessage) + slen + nlen;
452 if (size < nsize)
453 {
454 GNUNET_break (0);
455 finish (handle, GNUNET_SYSERR);
456 return 0;
457 }
458 r = buf;
459 r->header.size = htons (nsize);
460 r->header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_SET);
461 r->flags = 0;
462 r->value = GNUNET_htonll (handle->current->value);
463 if (handle->current->make_persistent)
464 r->flags |= htonl (GNUNET_STATISTICS_SETFLAG_PERSISTENT);
465 if (handle->current->type == ACTION_UPDATE)
466 r->flags |= htonl (GNUNET_STATISTICS_SETFLAG_RELATIVE);
467 GNUNET_assert (slen + nlen ==
468 GNUNET_STRINGS_buffer_fill ((char *) &r[1],
469 slen + nlen,
470 2,
471 handle->current->subsystem,
472 handle->current->name));
473 finish (handle, GNUNET_OK);
474 return nsize;
475}
476
477
478static size_t
479transmit_action (void *cls, size_t size, void *buf)
480{
481 struct GNUNET_STATISTICS_Handle *handle = cls;
482 size_t ret;
483
484 switch (handle->current->type)
485 {
486 case ACTION_GET:
487 ret = transmit_get (handle, size, buf);
488 break;
489 case ACTION_SET:
490 case ACTION_UPDATE:
491 ret = transmit_set (handle, size, buf);
492 break;
493 }
494 return ret;
495}
496
497
498/**
499 * Schedule the next action to be performed.
500 */
501static void
502schedule_action (struct GNUNET_STATISTICS_Handle *h)
503{
504 struct GNUNET_TIME_Relative timeout;
505
506 if (h->current != NULL)
507 return; /* action already pending */
508 if (GNUNET_YES != try_connect (h))
509 {
510 finish (h, GNUNET_SYSERR);
511 return;
512 }
513
514 /* schedule next action */
515 h->current = h->action_head;
516 if (NULL == h->current)
517 {
518 /* no pending network action, check destroy! */
519 if (h->do_destroy != GNUNET_YES)
520 return;
521 do_destroy (h);
522 return;
523 }
524 h->action_head = h->action_head->next;
525 if (NULL == h->action_head)
526 h->action_tail = NULL;
527 h->current->next = NULL;
528
529 timeout = GNUNET_TIME_absolute_get_remaining (h->current->timeout);
530 if (NULL ==
531 GNUNET_CLIENT_notify_transmit_ready (h->client,
532 h->current->msize,
533 timeout, &transmit_action, h))
534 {
535 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
536 "Failed to transmit request to statistics service.\n");
537 finish (h, GNUNET_SYSERR);
538 }
539}
540
541
542static void
543insert_ai (struct GNUNET_STATISTICS_Handle *h, struct ActionItem *ai)
544{
545 if (h->action_tail == NULL)
546 {
547 h->action_head = ai;
548 h->action_tail = ai;
549 schedule_action (h);
550 }
551 else
552 {
553 h->action_tail->next = ai;
554 h->action_tail = ai;
555 }
556}
557
558
559/**
560 * Get statistic from the peer.
561 *
562 * @param handle identification of the statistics service
563 * @param subsystem limit to the specified subsystem, NULL for our subsystem
564 * @param name name of the statistic value, NULL for all values
565 * @param timeout after how long should we give up (and call
566 * cont with an error code)?
567 * @param cont continuation to call when done (can be NULL)
568 * @param proc function to call on each value
569 * @param cls closure for cont and proc
570 */
571void
572GNUNET_STATISTICS_get (struct GNUNET_STATISTICS_Handle *handle,
573 const char *subsystem,
574 const char *name,
575 struct GNUNET_TIME_Relative timeout,
576 GNUNET_STATISTICS_Callback cont,
577 GNUNET_STATISTICS_Iterator proc, void *cls)
578{
579 size_t slen1;
580 size_t slen2;
581 struct ActionItem *ai;
582
583 GNUNET_assert (handle != NULL);
584 GNUNET_assert (proc != NULL);
585 if (GNUNET_YES != try_connect (handle))
586 {
587 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
588 "Failed to connect to statistics service, can not get value `%s:%s'.\n",
589 strlen (subsystem) ? subsystem : "*",
590 strlen (name) ? name : "*");
591 cont (cls, GNUNET_SYSERR);
592 return;
593 }
594 if (subsystem == NULL)
595 subsystem = "";
596 if (name == NULL)
597 name = "";
598 slen1 = strlen (subsystem);
599 slen2 = strlen (name);
600 GNUNET_assert (slen1 + slen2 + sizeof (struct GNUNET_MessageHeader) <
601 GNUNET_SERVER_MAX_MESSAGE_SIZE);
602 ai = GNUNET_malloc (sizeof (struct ActionItem));
603 ai->subsystem = GNUNET_strdup (subsystem);
604 ai->name = GNUNET_strdup (name);
605 ai->cont = cont;
606 ai->proc = proc;
607 ai->cls = cls;
608 ai->timeout = GNUNET_TIME_relative_to_absolute (timeout);
609 ai->type = ACTION_GET;
610 ai->msize = slen1 + slen2 + sizeof (struct GNUNET_MessageHeader);
611 insert_ai (handle, ai);
612}
613
614
615static void
616add_setter_action (struct GNUNET_STATISTICS_Handle *h,
617 const char *name,
618 int make_persistent,
619 unsigned long long value, enum ActionType type)
620{
621 struct ActionItem *ai;
622 size_t slen;
623 size_t nlen;
624 size_t nsize;
625
626 GNUNET_assert (h != NULL);
627 GNUNET_assert (name != NULL);
628 if (GNUNET_YES != try_connect (h))
629 return;
630 slen = strlen (h->subsystem) + 1;
631 nlen = strlen (name) + 1;
632 nsize = sizeof (struct GNUNET_STATISTICS_SetMessage) + slen + nlen;
633 if (nsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
634 {
635 GNUNET_break (0);
636 return;
637 }
638 ai = GNUNET_malloc (sizeof (struct ActionItem));
639 ai->subsystem = GNUNET_strdup (h->subsystem);
640 ai->name = GNUNET_strdup (name);
641 ai->timeout = GNUNET_TIME_relative_to_absolute (SET_TRANSMIT_TIMEOUT);
642 ai->make_persistent = make_persistent;
643 ai->msize = nsize;
644 ai->value = value;
645 ai->type = type;
646 insert_ai (h, ai);
647 schedule_action (h);
648}
649
650
651/**
652 * Set statistic value for the peer. Will always use our
653 * subsystem (the argument used when "handle" was created).
654 *
655 * @param handle identification of the statistics service
656 * @param name name of the statistic value
657 * @param value new value to set
658 * @param make_persistent should the value be kept across restarts?
659 */
660void
661GNUNET_STATISTICS_set (struct GNUNET_STATISTICS_Handle *handle,
662 const char *name,
663 unsigned long long value, int make_persistent)
664{
665 add_setter_action (handle, name, make_persistent, value, ACTION_SET);
666}
667
668
669/**
670 * Set statistic value for the peer. Will always use our
671 * subsystem (the argument used when "handle" was created).
672 *
673 * @param handle identification of the statistics service
674 * @param name name of the statistic value
675 * @param delta change in value (added to existing value)
676 * @param make_persistent should the value be kept across restarts?
677 */
678void
679GNUNET_STATISTICS_update (struct GNUNET_STATISTICS_Handle *handle,
680 const char *name,
681 long long delta, int make_persistent)
682{
683 add_setter_action (handle, name, make_persistent,
684 (unsigned long long) delta, ACTION_UPDATE);
685}
686
687
688/* end of statistics_api.c */
diff --git a/src/statistics/test_gnunet_statistics.sh b/src/statistics/test_gnunet_statistics.sh
new file mode 100755
index 000000000..43f629f36
--- /dev/null
+++ b/src/statistics/test_gnunet_statistics.sh
@@ -0,0 +1,177 @@
1#!/bin/bash
2
3rm -rf /tmp/test-gnunetd-statistics/
4exe="./gnunet-statistics -c test_statistics_api_data.conf"
5base=/tmp/gnunet-test-statistics
6#DEBUG="-L DEBUG"
7# -----------------------------------
8echo -n "Preparing: Starting service..."
9./gnunet-service-statistics $DEBUG -c test_statistics_api_data.conf &
10sleep 1
11echo "DONE"
12
13# ----------------------------------------------------------------------------------
14echo -n "TEST: Bad argument checking..."
15
16if $exe -x 2> /dev/null; then
17 echo "FAIL: error running $exe"
18 kill %%
19 exit 1
20fi
21echo "PASS"
22
23# ----------------------------------------------------------------------------------
24echo -n "TEST: Set value..."
25
26if ! $exe $DEBUG -n test -s subsystem 42 ; then
27 echo "FAIL: error running $exe"
28 kill %%
29 exit 1
30fi
31echo "PASS"
32
33# ----------------------------------------------------------------------------------
34echo -n "TEST: Set another value..."
35
36if ! $exe $DEBUG -n other -s osystem 43 ; then
37 echo "FAIL: error running $exe"
38 kill %%
39 exit 1
40fi
41echo "PASS"
42
43# ----------------------------------------------------------------------------------
44echo -n "TEST: viewing all stats..."
45
46if ! $exe $DEBUG > $base.out; then
47 echo "FAIL: error running $exe"
48 kill %%
49 exit 1
50fi
51LINES=`cat $base.out | wc -l`
52if test $LINES -ne 2; then
53 echo "FAIL: unexpected output"
54 kill %%
55 exit 1
56fi
57echo "PASS"
58
59# ----------------------------------------------------------------------------------
60echo -n "TEST: viewing stats by name..."
61
62if ! $exe $DEBUG -n other > $base.out; then
63 echo "FAIL: error running $exe"
64 kill %%
65 exit 1
66fi
67LINES=`cat $base.out | grep 43 | wc -l`
68if test $LINES -ne 1; then
69 echo "FAIL: unexpected output"
70 kill %%
71 exit 1
72fi
73echo "PASS"
74
75# ----------------------------------------------------------------------------------
76echo -n "TEST: viewing stats by subsystem..."
77
78if ! $exe $DEBUG -s subsystem > $base.out; then
79 echo "FAIL: error running $exe"
80 kill %%
81 exit 1
82fi
83LINES=`cat $base.out | grep 42 | wc -l`
84if test $LINES -ne 1; then
85 echo "FAIL: unexpected output"
86 kill %%
87 exit 1
88fi
89echo "PASS"
90
91
92# ----------------------------------------------------------------------------------
93echo -n "TEST: Set persistent value..."
94
95if ! $exe $DEBUG -n lasting -s subsystem 40 -p; then
96 echo "FAIL: error running $exe"
97 kill %%
98 exit 1
99fi
100echo "PASS"
101
102# -----------------------------------
103echo -n "Restarting service..."
104sleep 1
105if ! kill %%;
106then
107 echo "FAIL: could not kill service"
108 kill %%
109 exit 1
110fi
111sleep 1
112./gnunet-service-statistics $DEBUG -c test_statistics_api_data.conf &
113sleep 1
114
115
116# ----------------------------------------------------------------------------------
117echo -n "TEST: checking persistence..."
118
119if ! $exe $DEBUG > $base.out; then
120 echo "FAIL: error running $exe"
121 kill %%
122 exit 1
123fi
124LINES=`cat $base.out | grep 40 | wc -l`
125if test $LINES -ne 1; then
126 echo "FAIL: unexpected output"
127 kill %%
128 exit 1
129fi
130echo "PASS"
131
132
133
134# ----------------------------------------------------------------------------------
135echo -n "TEST: Removing persistence..."
136
137if ! $exe $DEBUG -n lasting -s subsystem 40; then
138 echo "FAIL: error running $exe"
139 kill %%
140 exit 1
141fi
142echo "PASS"
143
144
145# -----------------------------------
146echo -n "Restarting service..."
147sleep 1
148if ! kill %%;
149then
150 echo "FAIL: could not kill service"
151 kill %%
152 exit 1
153fi
154sleep 1
155./gnunet-service-statistics $DEBUG -c test_statistics_api_data.conf &
156sleep 1
157
158
159# ----------------------------------------------------------------------------------
160echo -n "TEST: checking removed persistence..."
161
162if ! $exe $DEBUG > $base.out; then
163 echo "FAIL: error running $exe"
164 kill %%
165 exit 1
166fi
167LINES=`cat $base.out | grep 40 | wc -l`
168if test $LINES -ne 0; then
169 echo "FAIL: unexpected output"
170 kill %%
171 exit 1
172fi
173echo "PASS"
174
175kill %%
176rm -f $base.out
177rm -rf /tmp/test-gnunetd-statistics/
diff --git a/src/statistics/test_statistics_api.c b/src/statistics/test_statistics_api.c
new file mode 100644
index 000000000..7a39f54b6
--- /dev/null
+++ b/src/statistics/test_statistics_api.c
@@ -0,0 +1,177 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 statistics/test_statistics_api.c
22 * @brief testcase for statistics_api.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_getopt_lib.h"
27#include "gnunet_os_lib.h"
28#include "gnunet_program_lib.h"
29#include "gnunet_scheduler_lib.h"
30#include "gnunet_statistics_service.h"
31
32#define VERBOSE GNUNET_NO
33
34static int
35check_1 (void *cls,
36 const char *subsystem,
37 const char *name, unsigned long long value, int is_persistent)
38{
39 GNUNET_assert (0 == strcmp (name, "test-1"));
40 GNUNET_assert (0 == strcmp (subsystem, "test-statistics-api"));
41 GNUNET_assert (value == 1);
42 GNUNET_assert (is_persistent == GNUNET_NO);
43 return GNUNET_OK;
44}
45
46static int
47check_2 (void *cls,
48 const char *subsystem,
49 const char *name, unsigned long long value, int is_persistent)
50{
51 GNUNET_assert (0 == strcmp (name, "test-2"));
52 GNUNET_assert (0 == strcmp (subsystem, "test-statistics-api"));
53 GNUNET_assert (value == 2);
54 GNUNET_assert (is_persistent == GNUNET_NO);
55 return GNUNET_OK;
56}
57
58static int
59check_3 (void *cls,
60 const char *subsystem,
61 const char *name, unsigned long long value, int is_persistent)
62{
63 GNUNET_assert (0 == strcmp (name, "test-3"));
64 GNUNET_assert (0 == strcmp (subsystem, "test-statistics-api"));
65 GNUNET_assert (value == 3);
66 GNUNET_assert (is_persistent == GNUNET_YES);
67 return GNUNET_OK;
68}
69
70static struct GNUNET_STATISTICS_Handle *h;
71
72static void
73next_fin (void *cls, int success)
74{
75 int *ok = cls;
76
77 GNUNET_STATISTICS_destroy (h);
78 GNUNET_assert (success == GNUNET_OK);
79 *ok = 0;
80}
81
82static void
83next (void *cls, int success)
84{
85 GNUNET_assert (success == GNUNET_OK);
86 GNUNET_STATISTICS_get (h, NULL, "test-2",
87 GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, cls);
88}
89
90static void
91run (void *cls,
92 struct GNUNET_SCHEDULER_Handle *sched,
93 char *const *args,
94 const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *cfg)
95{
96
97 h = GNUNET_STATISTICS_create (sched, "test-statistics-api", cfg);
98 GNUNET_STATISTICS_set (h, "test-1", 1, GNUNET_NO);
99 GNUNET_STATISTICS_set (h, "test-2", 2, GNUNET_NO);
100 GNUNET_STATISTICS_set (h, "test-3", 2, GNUNET_NO);
101 GNUNET_STATISTICS_update (h, "test-3", 1, GNUNET_YES);
102 GNUNET_STATISTICS_get (h, NULL, "test-1",
103 GNUNET_TIME_UNIT_SECONDS, &next, &check_1, cls);
104}
105
106static void
107run_more (void *cls,
108 struct GNUNET_SCHEDULER_Handle *sched,
109 char *const *args,
110 const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *cfg)
111{
112 h = GNUNET_STATISTICS_create (sched, "test-statistics-api", cfg);
113 GNUNET_STATISTICS_get (h, NULL, "test-3",
114 GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_3, cls);
115}
116
117static int
118check ()
119{
120 int ok = 1;
121 pid_t pid;
122 char *const argv[] = { "test-statistics-api",
123 "-c",
124 "test_statistics_api_data.conf",
125 NULL
126 };
127 struct GNUNET_GETOPT_CommandLineOption options[] = {
128 GNUNET_GETOPT_OPTION_END
129 };
130 pid = GNUNET_OS_start_process ("gnunet-service-statistics",
131 "gnunet-service-statistics",
132#if DEBUG_STATISTICS
133 "-L", "DEBUG",
134#endif
135 "-c", "test_statistics_api_data.conf", NULL);
136 sleep (1);
137 GNUNET_PROGRAM_run (3, argv, "test-statistics-api", "nohelp",
138 options, &run, &ok);
139 if (0 != PLIBC_KILL (pid, SIGTERM))
140 {
141 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
142 ok = 1;
143 }
144 waitpid (pid, NULL, 0);
145 if (ok != 0)
146 return ok;
147 ok = 1;
148 /* restart to check persistence! */
149 pid = GNUNET_OS_start_process ("gnunet-service-statistics",
150 "gnunet-service-statistics",
151#if DEBUG_STATISTICS
152 "-L", "DEBUG",
153#endif
154 "-c", "test_statistics_api_data.conf", NULL);
155 sleep (1);
156 GNUNET_PROGRAM_run (3, argv, "test-statistics-api", "nohelp",
157 options, &run_more, &ok);
158 if (0 != PLIBC_KILL (pid, SIGTERM))
159 {
160 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
161 ok = 1;
162 }
163 waitpid (pid, NULL, 0);
164 return ok;
165}
166
167int
168main (int argc, char *argv[])
169{
170 int ret;
171
172 ret = check ();
173
174 return ret;
175}
176
177/* end of test_statistics_api.c */
diff --git a/src/statistics/test_statistics_api_data.conf b/src/statistics/test_statistics_api_data.conf
new file mode 100644
index 000000000..571a9b3e4
--- /dev/null
+++ b/src/statistics/test_statistics_api_data.conf
@@ -0,0 +1,5 @@
1[PATHS]
2SERVICEHOME = /tmp/test-gnunetd-statistics/
3
4[statistics]
5PORT = 22353
diff --git a/src/template/Makefile.am b/src/template/Makefile.am
new file mode 100644
index 000000000..47d6b4165
--- /dev/null
+++ b/src/template/Makefile.am
@@ -0,0 +1,37 @@
1INCLUDES = -I$(top_srcdir)/src/include
2
3if MINGW
4 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
5endif
6
7if USE_COVERAGE
8 AM_CFLAGS = -fprofile-arcs -ftest-coverage
9endif
10
11bin_PROGRAMS = \
12 gnunet-template \
13 gnunet-service-template
14
15gnunet_template_SOURCES = \
16 gnunet-template.c
17gnunet_template_LDADD = \
18 $(top_builddir)/src/util/libgnunetutil.la \
19 $(GN_LIBINTL)
20
21gnunet_service_template_SOURCES = \
22 gnunet-service-template.c
23gnunet_service_template_LDADD = \
24 $(top_builddir)/src/util/libgnunetutil.la \
25 $(GN_LIBINTL)
26
27
28check_PROGRAMS = \
29 test_template_api
30
31TESTS = $(check_PROGRAMS)
32
33test_template_api_SOURCES = \
34 test_template_api.c
35test_template_api_LDADD = \
36 $(top_builddir)/src/util/libgnunetutil.la
37
diff --git a/src/template/gnunet-service-template.c b/src/template/gnunet-service-template.c
new file mode 100644
index 000000000..c43d681d7
--- /dev/null
+++ b/src/template/gnunet-service-template.c
@@ -0,0 +1,87 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 template/gnunet-service-template.c
23 * @brief program that tracks template
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_getopt_lib.h"
28#include "gnunet_service_lib.h"
29
30/**
31 * Do cleanup here.
32 *
33 * @param cls closure
34 * @param cfg configuration to use
35 */
36static void
37finish (void *cls, struct GNUNET_CONFIGURATION_Handle *cfg)
38{
39 /* FIXME */
40}
41
42
43/**
44 * List of handlers for the messages understood by this
45 * service.
46 */
47static struct GNUNET_SERVER_MessageHandler handlers[] = {
48 /* FIXME: add handlers here! */
49 {NULL, NULL, 0, 0}
50};
51
52/**
53 * Process template requests.
54 *
55 * @param cls closure
56 * @param sched scheduler to use
57 * @param server the initialized server
58 * @param cfg configuration to use
59 */
60static void
61run (void *cls,
62 struct GNUNET_SCHEDULER_Handle *sched,
63 struct GNUNET_SERVER_Handle *server,
64 struct GNUNET_CONFIGURATION_Handle *cfg)
65{
66 /* FIXME: do setup here */
67 GNUNET_SERVER_add_handlers (server, handlers);
68}
69
70
71/**
72 * The main function for the template service.
73 *
74 * @param argc number of arguments from the command line
75 * @param argv command line arguments
76 * @return 0 ok, 1 on error
77 */
78int
79main (int argc, char *const *argv)
80{
81 return (GNUNET_OK ==
82 GNUNET_SERVICE_run (argc,
83 argv,
84 "template", &run, NULL, &finish, NULL)) ? 0 : 1;
85}
86
87/* end of gnunet-service-template.c */
diff --git a/src/template/gnunet-template.c b/src/template/gnunet-template.c
new file mode 100644
index 000000000..ea47c7f45
--- /dev/null
+++ b/src/template/gnunet-template.c
@@ -0,0 +1,81 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009 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 2, 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 template/gnunet-template.c
23 * @brief template for writing a tool
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_getopt_lib.h"
28#include "gnunet_program_lib.h"
29/* #include "gnunet_template_service.h" */
30
31/**
32 * Final status code.
33 */
34static int ret;
35
36/**
37 * Main function that will be run by the scheduler.
38 *
39 * @param cls closure
40 * @param sched the scheduler to use
41 * @param args remaining command-line arguments
42 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
43 * @param cfg configuration
44 */
45static void
46run (void *cls,
47 struct GNUNET_SCHEDULER_Handle *sched,
48 char *const *args,
49 const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *cfg)
50{
51 /* main code here */
52}
53
54/**
55 * gnunet-template command line options
56 */
57static struct GNUNET_GETOPT_CommandLineOption options[] = {
58 /* FIMXE: add options here */
59 GNUNET_GETOPT_OPTION_END
60};
61
62
63/**
64 * The main function to obtain template from gnunetd.
65 *
66 * @param argc number of arguments from the command line
67 * @param argv command line arguments
68 * @return 0 ok, 1 on error
69 */
70int
71main (int argc, char *const *argv)
72{
73 return (GNUNET_OK ==
74 GNUNET_PROGRAM_run (argc,
75 argv,
76 "gnunet-template",
77 gettext_noop ("help text"),
78 options, &run, NULL)) ? ret : 1;
79}
80
81/* end of gnunet-template.c */
diff --git a/src/template/test_template_api.c b/src/template/test_template_api.c
new file mode 100644
index 000000000..8d53a15da
--- /dev/null
+++ b/src/template/test_template_api.c
@@ -0,0 +1,45 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 template/test_template.c
22 * @brief testcase for template.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26
27#define VERBOSE GNUNET_NO
28
29static int
30check ()
31{
32 return 0;
33}
34
35int
36main (int argc, char *argv[])
37{
38 int ret;
39
40 ret = check ();
41
42 return ret;
43}
44
45/* end of test_template.c */
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
new file mode 100644
index 000000000..236dec7c4
--- /dev/null
+++ b/src/transport/Makefile.am
@@ -0,0 +1,84 @@
1INCLUDES = -I$(top_srcdir)/src/include
2
3plugindir = $(libdir)/gnunet
4
5if MINGW
6 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
7endif
8
9if USE_COVERAGE
10 AM_CFLAGS = -fprofile-arcs -ftest-coverage
11endif
12
13
14lib_LTLIBRARIES = \
15 libgnunettransport.la
16
17libgnunettransport_la_SOURCES = \
18 transport_api.c transport.h
19libgnunettransport_la_LIBADD = \
20 $(top_builddir)/src/arm/libgnunetarm.la \
21 $(top_builddir)/src/hello/libgnunethello.la \
22 $(top_builddir)/src/util/libgnunetutil.la \
23 $(GN_LIBINTL)
24libgnunettransport_la_LDFLAGS = \
25 $(GN_LIB_LDFLAGS) $(WINFLAGS) \
26 -version-info 0:0:0
27
28
29bin_PROGRAMS = \
30 gnunet-transport \
31 gnunet-service-transport
32
33gnunet_transport_SOURCES = \
34 gnunet-transport.c
35gnunet_transport_LDADD = \
36 $(top_builddir)/src/transport/libgnunettransport.la \
37 $(top_builddir)/src/util/libgnunetutil.la \
38 $(GN_LIBINTL)
39
40gnunet_service_transport_SOURCES = \
41 gnunet-service-transport.c
42gnunet_service_transport_LDADD = \
43 $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
44 $(top_builddir)/src/util/libgnunetutil.la \
45 $(GN_LIBINTL)
46
47
48
49plugin_LTLIBRARIES = \
50 libgnunet_plugin_transport_tcp.la \
51 libgnunet_plugin_transport_template.la
52# TODO: add udp, http, nat, etc.
53
54libgnunet_plugin_transport_tcp_la_SOURCES = \
55 plugin_transport_tcp.c
56libgnunet_plugin_transport_tcp_la_LIBADD = \
57 $(top_builddir)/src/resolver/libgnunetresolver.la \
58 $(top_builddir)/src/util/libgnunetutil.la
59libgnunet_plugin_transport_tcp_la_LDFLAGS = \
60 $(GN_PLUGIN_LDFLAGS)
61
62libgnunet_plugin_transport_template_la_SOURCES = \
63 plugin_transport_template.c
64libgnunet_plugin_transport_template_la_LDFLAGS = \
65 $(GN_PLUGIN_LDFLAGS)
66
67
68check_PROGRAMS = \
69 test_transport_api
70# TODO: add tests for tcp, udp, http, nat, etc.
71
72TESTS = $(check_PROGRAMS)
73
74test_transport_api_SOURCES = \
75 test_transport_api.c
76test_transport_api_LDADD = \
77 $(top_builddir)/src/transport/libgnunettransport.la \
78 $(top_builddir)/src/util/libgnunetutil.la
79
80
81EXTRA_DIST = \
82 test_transport_api_data.conf \
83 test_transport_api_peer1.conf \
84 test_transport_api_peer2.conf
diff --git a/src/transport/NOTES b/src/transport/NOTES
new file mode 100644
index 000000000..41404e1f9
--- /dev/null
+++ b/src/transport/NOTES
@@ -0,0 +1,46 @@
1KEY DESIGN CHOICES:
2 - who decides which connections to keep/create?
3 => higher level session/key management!
4 - who enforces things like F2F topology, etc?
5 => higher level session/key management!
6 - who tracks all known HELLOs & validates?
7 => We validate, PEERINFO tracks!
8 - who advertises our HELLO?
9 => us! (need background job; previously: advertising)
10 - who advertises other peers HELLOs?
11 => higher level (core?)
12 - who does bootstrapping?
13 => bootstrap service (external!)
14 - who enforces inbound bandwidth limits?
15 => transport-service and plugins! (previously: core);
16 either by limiting reads (TCP) or discarding packets
17 (transport-service)
18 - who enforces outbound bandwidth limits?
19 => transport_api!
20 - who decides outbound bandwidth limits?
21 => other peer, via core (need authenticated limits!)
22 - who decides inbound bandwidth limits?
23 => core / apps above core (need trust info)
24 - cost function for transports is latency estimate in ms
25 => plugin provides latency data, transport-service
26 selects plugin(s) for transmission
27 - who is responsible for fragmentation?
28 => plugins! (may use common shared library)
29 - should we require UDP to be reliable?
30 => NO. There are other places that may (rarely)
31 use messages that we can not fix
32 - how do we access the 50% of service that we need for TCP/UDP
33 from service.c without code replication or getting 50%
34 that we do not want (i.e. shutdown, pid-file-writing, etc.)
35 => use GNUNET_SERVICE_start/stop functions!
36 - At what level do we manage timeouts?
37 => At the plugin (TCP connections),
38 transport-service (neighbours) and
39 core (sessions) level!
40 => All plugins have to disconnect before service-level
41 disconnect occurs
42 => We can have a plugin-connection die, but the session
43 survives!
44 => We can have a session die (no further authenticated
45 communication) even if the plugin thinks it is still
46 up!
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
new file mode 100644
index 000000000..08745c378
--- /dev/null
+++ b/src/transport/gnunet-service-transport.c
@@ -0,0 +1,2852 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 transport/gnunet-service-transport.c
23 * @brief low-level P2P messaging
24 * @author Christian Grothoff
25 *
26 * TODO:
27 * - if we do not receive an ACK in response to our
28 * HELLO, retransmit HELLO!
29 */
30#include "platform.h"
31#include "gnunet_client_lib.h"
32#include "gnunet_getopt_lib.h"
33#include "gnunet_hello_lib.h"
34#include "gnunet_os_lib.h"
35#include "gnunet_peerinfo_service.h"
36#include "gnunet_plugin_lib.h"
37#include "gnunet_protocols.h"
38#include "gnunet_service_lib.h"
39#include "gnunet_signatures.h"
40#include "plugin_transport.h"
41#include "transport.h"
42
43/**
44 * How many messages can we have pending for a given client process
45 * before we start to drop incoming messages? We typically should
46 * have only one client and so this would be the primary buffer for
47 * messages, so the number should be chosen rather generously.
48 *
49 * The expectation here is that most of the time the queue is large
50 * enough so that a drop is virtually never required.
51 */
52#define MAX_PENDING 128
53
54/**
55 * How often should we try to reconnect to a peer using a particular
56 * transport plugin before giving up? Note that the plugin may be
57 * added back to the list after PLUGIN_RETRY_FREQUENCY expires.
58 */
59#define MAX_CONNECT_RETRY 3
60
61/**
62 * How often must a peer violate bandwidth quotas before we start
63 * to simply drop its messages?
64 */
65#define QUOTA_VIOLATION_DROP_THRESHOLD 100
66
67/**
68 * How long until a HELLO verification attempt should time out?
69 */
70#define HELLO_VERIFICATION_TIMEOUT GNUNET_TIME_UNIT_MINUTES
71
72/**
73 * How often do we re-add (cheaper) plugins to our list of plugins
74 * to try for a given connected peer?
75 */
76#define PLUGIN_RETRY_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
77
78/**
79 * After how long do we expire an address in a HELLO
80 * that we just validated? This value is also used
81 * for our own addresses when we create a HELLO.
82 */
83#define HELLO_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 12)
84
85/**
86 * After how long do we consider a connection to a peer dead
87 * if we don't receive messages from the peer?
88 */
89#define IDLE_CONNECTION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
90
91
92/**
93 * Entry in linked list of network addresses.
94 */
95struct AddressList
96{
97 /**
98 * This is a linked list.
99 */
100 struct AddressList *next;
101
102 /**
103 * The address, actually a pointer to the end
104 * of this struct. Do not free!
105 */
106 void *addr;
107
108 /**
109 * How long until we auto-expire this address (unless it is
110 * re-confirmed by the transport)?
111 */
112 struct GNUNET_TIME_Absolute expires;
113
114 /**
115 * Length of addr.
116 */
117 size_t addrlen;
118
119};
120
121
122/**
123 * Entry in linked list of all of our plugins.
124 */
125struct TransportPlugin
126{
127
128 /**
129 * This is a linked list.
130 */
131 struct TransportPlugin *next;
132
133 /**
134 * API of the transport as returned by the plugin's
135 * initialization function.
136 */
137 struct GNUNET_TRANSPORT_PluginFunctions *api;
138
139 /**
140 * Short name for the plugin (i.e. "tcp").
141 */
142 char *short_name;
143
144 /**
145 * Name of the library (i.e. "gnunet_plugin_transport_tcp").
146 */
147 char *lib_name;
148
149 /**
150 * List of our known addresses for this transport.
151 */
152 struct AddressList *addresses;
153
154 /**
155 * Environment this transport service is using
156 * for this plugin.
157 */
158 struct GNUNET_TRANSPORT_PluginEnvironment env;
159
160 /**
161 * ID of task that is used to clean up expired addresses.
162 */
163 GNUNET_SCHEDULER_TaskIdentifier address_update_task;
164
165
166 /**
167 * Set to GNUNET_YES if we need to scrap the existing
168 * list of "addresses" and start fresh when we receive
169 * the next address update from a transport. Set to
170 * GNUNET_NO if we should just add the new address
171 * to the list and wait for the commit call.
172 */
173 int rebuild;
174};
175
176struct NeighbourList;
177
178/**
179 * For each neighbour we keep a list of messages
180 * that we still want to transmit to the neighbour.
181 */
182struct MessageQueue
183{
184
185 /**
186 * This is a linked list.
187 */
188 struct MessageQueue *next;
189
190 /**
191 * The message we want to transmit.
192 */
193 struct GNUNET_MessageHeader *message;
194
195 /**
196 * Client responsible for queueing the message;
197 * used to check that a client has not two messages
198 * pending for the same target. Can be NULL.
199 */
200 struct TransportClient *client;
201
202 /**
203 * Neighbour this entry belongs to.
204 */
205 struct NeighbourList *neighbour;
206
207 /**
208 * Plugin that we used for the transmission.
209 * NULL until we scheduled a transmission.
210 */
211 struct TransportPlugin *plugin;
212
213 /**
214 * Internal message of the transport system that should not be
215 * included in the usual SEND-SEND_OK transmission confirmation
216 * traffic management scheme. Typically, "internal_msg" will
217 * be set whenever "client" is NULL (but it is not strictly
218 * required).
219 */
220 int internal_msg;
221
222};
223
224
225/**
226 * For a given Neighbour, which plugins are available
227 * to talk to this peer and what are their costs?
228 */
229struct ReadyList
230{
231
232 /**
233 * This is a linked list.
234 */
235 struct ReadyList *next;
236
237 /**
238 * Which of our transport plugins does this entry
239 * represent?
240 */
241 struct TransportPlugin *plugin;
242
243 /**
244 * Neighbour this entry belongs to.
245 */
246 struct NeighbourList *neighbour;
247
248 /**
249 * Opaque handle (specific to the plugin) for the
250 * connection to our target; can be NULL.
251 */
252 void *plugin_handle;
253
254 /**
255 * What was the last latency observed for this plugin
256 * and peer? Invalid if connected is GNUNET_NO.
257 */
258 struct GNUNET_TIME_Relative latency;
259
260 /**
261 * If we did not successfully transmit a message to the
262 * given peer via this connection during the specified
263 * time, we should consider the connection to be dead.
264 * This is used in the case that a TCP transport simply
265 * stalls writing to the stream but does not formerly
266 * get a signal that the other peer died.
267 */
268 struct GNUNET_TIME_Absolute timeout;
269
270 /**
271 * Is this plugin currently connected? The first time
272 * we transmit or send data to a peer via a particular
273 * plugin, we set this to GNUNET_YES. If we later get
274 * an error (disconnect notification or transmission
275 * failure), we set it back to GNUNET_NO. Each time the
276 * value is set to GNUNET_YES, we increment the
277 * "connect_attempts" counter. If that one reaches a
278 * particular threshold, we consider the plugin to not
279 * be working properly at this time for the given peer
280 * and remove it from the eligible list.
281 */
282 int connected;
283
284 /**
285 * How often have we tried to connect using this plugin?
286 */
287 unsigned int connect_attempts;
288
289 /**
290 * Is this plugin ready to transmit to the specific
291 * target? GNUNET_NO if not. Initially, all plugins
292 * are marked ready. If a transmission is in progress,
293 * "transmit_ready" is set to GNUNET_NO.
294 */
295 int transmit_ready;
296
297};
298
299
300/**
301 * Entry in linked list of all of our current neighbours.
302 */
303struct NeighbourList
304{
305
306 /**
307 * This is a linked list.
308 */
309 struct NeighbourList *next;
310
311 /**
312 * Which of our transports is connected to this peer
313 * and what is their status?
314 */
315 struct ReadyList *plugins;
316
317 /**
318 * List of messages we would like to send to this peer;
319 * must contain at most one message per client.
320 */
321 struct MessageQueue *messages;
322
323 /**
324 * Identity of this neighbour.
325 */
326 struct GNUNET_PeerIdentity id;
327
328 /**
329 * ID of task scheduled to run when this peer is about to
330 * time out (will free resources associated with the peer).
331 */
332 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
333
334 /**
335 * How long until we should consider this peer dead
336 * (if we don't receive another message in the
337 * meantime)?
338 */
339 struct GNUNET_TIME_Absolute peer_timeout;
340
341 /**
342 * At what time did we reset last_received last?
343 */
344 struct GNUNET_TIME_Absolute last_quota_update;
345
346 /**
347 * At what time should we try to again add plugins to
348 * our ready list?
349 */
350 struct GNUNET_TIME_Absolute retry_plugins_time;
351
352 /**
353 * How many bytes have we received since the "last_quota_update"
354 * timestamp?
355 */
356 uint64_t last_received;
357
358 /**
359 * Global quota for outbound traffic for the neighbour in bytes/ms.
360 */
361 uint32_t quota_in;
362
363 /**
364 * What is the latest version of our HELLO that we have
365 * sent to this neighbour?
366 */
367 unsigned int hello_version_sent;
368
369 /**
370 * How often has the other peer (recently) violated the
371 * inbound traffic limit? Incremented by 10 per violation,
372 * decremented by 1 per non-violation (for each
373 * time interval).
374 */
375 unsigned int quota_violation_count;
376
377 /**
378 * Have we seen an ACK from this neighbour in the past?
379 * (used to make up a fake ACK for clients connecting after
380 * the neighbour connected to us).
381 */
382 int saw_ack;
383
384};
385
386
387/**
388 * Linked list of messages to be transmitted to
389 * the client. Each entry is followed by the
390 * actual message.
391 */
392struct ClientMessageQueueEntry
393{
394 /**
395 * This is a linked list.
396 */
397 struct ClientMessageQueueEntry *next;
398};
399
400
401/**
402 * Client connected to the transport service.
403 */
404struct TransportClient
405{
406
407 /**
408 * This is a linked list.
409 */
410 struct TransportClient *next;
411
412 /**
413 * Handle to the client.
414 */
415 struct GNUNET_SERVER_Client *client;
416
417 /**
418 * Linked list of messages yet to be transmitted to
419 * the client.
420 */
421 struct ClientMessageQueueEntry *message_queue_head;
422
423 /**
424 * Tail of linked list of messages yet to be transmitted to the
425 * client.
426 */
427 struct ClientMessageQueueEntry *message_queue_tail;
428
429 /**
430 * Is a call to "transmit_send_continuation" pending? If so, we
431 * must not free this struct (even if the corresponding client
432 * disconnects) and instead only remove it from the linked list and
433 * set the "client" field to NULL.
434 */
435 int tcs_pending;
436
437 /**
438 * Length of the list of messages pending for this client.
439 */
440 unsigned int message_count;
441
442};
443
444
445/**
446 * Message used to ask a peer to validate receipt (to check an address
447 * from a HELLO). Followed by the address used. Note that the
448 * recipients response does not affirm that he has this address,
449 * only that he got the challenge message.
450 */
451struct ValidationChallengeMessage
452{
453
454 /**
455 * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_PING
456 */
457 struct GNUNET_MessageHeader header;
458
459 /**
460 * What are we signing and why?
461 */
462 struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
463
464 /**
465 * Random challenge number (in network byte order).
466 */
467 uint32_t challenge GNUNET_PACKED;
468
469 /**
470 * Who is the intended recipient?
471 */
472 struct GNUNET_PeerIdentity target;
473};
474
475
476/**
477 * Message used to validate a HELLO. If this was
478 * the right recipient, the response is a signature
479 * of the original validation request. The
480 * challenge is included in the confirmation to make
481 * matching of replies to requests possible.
482 */
483struct ValidationChallengeResponse
484{
485
486 /**
487 * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_PONG
488 */
489 struct GNUNET_MessageHeader header;
490
491 /**
492 * Random challenge number (in network byte order).
493 */
494 uint32_t challenge GNUNET_PACKED;
495
496 /**
497 * Who signed this message?
498 */
499 struct GNUNET_PeerIdentity sender;
500
501 /**
502 * Signature.
503 */
504 struct GNUNET_CRYPTO_RsaSignature signature;
505
506};
507
508
509/**
510 * For each HELLO, we may have to validate multiple addresses;
511 * each address gets its own request entry.
512 */
513struct ValidationAddress
514{
515 /**
516 * This is a linked list.
517 */
518 struct ValidationAddress *next;
519
520 /**
521 * Our challenge message. Points to after this
522 * struct, so this field should not be freed.
523 */
524 struct ValidationChallengeMessage *msg;
525
526 /**
527 * Name of the transport.
528 */
529 char *transport_name;
530
531 /**
532 * When should this validated address expire?
533 */
534 struct GNUNET_TIME_Absolute expiration;
535
536 /**
537 * Length of the address we are validating.
538 */
539 size_t addr_len;
540
541 /**
542 * Set to GNUNET_YES if the challenge was met,
543 * GNUNET_SYSERR if we know it failed, GNUNET_NO
544 * if we are waiting on a response.
545 */
546 int ok;
547};
548
549
550/**
551 * Entry in linked list of all HELLOs awaiting validation.
552 */
553struct ValidationList
554{
555
556 /**
557 * This is a linked list.
558 */
559 struct ValidationList *next;
560
561 /**
562 * Linked list with one entry per address from the HELLO
563 * that needs to be validated.
564 */
565 struct ValidationAddress *addresses;
566
567 /**
568 * The public key of the peer.
569 */
570 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded publicKey;
571
572 /**
573 * When does this record time-out? (assuming the
574 * challenge goes unanswered)
575 */
576 struct GNUNET_TIME_Absolute timeout;
577
578};
579
580
581/**
582 * HELLOs awaiting validation.
583 */
584static struct ValidationList *pending_validations;
585
586/**
587 * Our HELLO message.
588 */
589static struct GNUNET_HELLO_Message *our_hello;
590
591/**
592 * "version" of "our_hello". Used to see if a given
593 * neighbour has already been sent the latest version
594 * of our HELLO message.
595 */
596static unsigned int our_hello_version;
597
598/**
599 * Our public key.
600 */
601static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key;
602
603/**
604 * Our identity.
605 */
606static struct GNUNET_PeerIdentity my_identity;
607
608/**
609 * Our private key.
610 */
611static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key;
612
613/**
614 * Our scheduler.
615 */
616struct GNUNET_SCHEDULER_Handle *sched;
617
618/**
619 * Our configuration.
620 */
621struct GNUNET_CONFIGURATION_Handle *cfg;
622
623/**
624 * Linked list of all clients to this service.
625 */
626static struct TransportClient *clients;
627
628/**
629 * All loaded plugins.
630 */
631static struct TransportPlugin *plugins;
632
633/**
634 * Our server.
635 */
636static struct GNUNET_SERVER_Handle *server;
637
638/**
639 * All known neighbours and their HELLOs.
640 */
641static struct NeighbourList *neighbours;
642
643/**
644 * Default bandwidth quota for receiving for new peers in bytes/ms.
645 */
646static uint32_t default_quota_in;
647
648/**
649 * Default bandwidth quota for sending for new peers in bytes/ms.
650 */
651static uint32_t default_quota_out;
652
653/**
654 * Number of neighbours we'd like to have.
655 */
656static uint32_t max_connect_per_transport;
657
658
659/**
660 * Find an entry in the neighbour list for a particular peer.
661 *
662 * @return NULL if not found.
663 */
664static struct NeighbourList *
665find_neighbour (const struct GNUNET_PeerIdentity *key)
666{
667 struct NeighbourList *head = neighbours;
668 while ((head != NULL) &&
669 (0 != memcmp (key, &head->id, sizeof (struct GNUNET_PeerIdentity))))
670 head = head->next;
671 return head;
672}
673
674
675/**
676 * Find an entry in the transport list for a particular transport.
677 *
678 * @return NULL if not found.
679 */
680static struct TransportPlugin *
681find_transport (const char *short_name)
682{
683 struct TransportPlugin *head = plugins;
684 while ((head != NULL) && (0 != strcmp (short_name, head->short_name)))
685 head = head->next;
686 return head;
687}
688
689
690/**
691 * Update the quota values for the given neighbour now.
692 */
693static void
694update_quota (struct NeighbourList *n)
695{
696 struct GNUNET_TIME_Relative delta;
697 uint64_t allowed;
698 uint64_t remaining;
699
700 delta = GNUNET_TIME_absolute_get_duration (n->last_quota_update);
701 if (delta.value < MIN_QUOTA_REFRESH_TIME)
702 return; /* not enough time passed for doing quota update */
703 allowed = delta.value * n->quota_in;
704 if (n->last_received < allowed)
705 {
706 remaining = allowed - n->last_received;
707 if (n->quota_in > 0)
708 remaining /= n->quota_in;
709 else
710 remaining = 0;
711 if (remaining > MAX_BANDWIDTH_CARRY)
712 remaining = MAX_BANDWIDTH_CARRY;
713 n->last_received = 0;
714 n->last_quota_update = GNUNET_TIME_absolute_get ();
715 n->last_quota_update.value -= remaining;
716 if (n->quota_violation_count > 0)
717 n->quota_violation_count--;
718 }
719 else
720 {
721 n->last_received -= allowed;
722 n->last_quota_update = GNUNET_TIME_absolute_get ();
723 if (n->last_received > allowed)
724 {
725 /* more than twice the allowed rate! */
726 n->quota_violation_count += 10;
727 }
728 }
729}
730
731
732/**
733 * Function called to notify a client about the socket
734 * being ready to queue more data. "buf" will be
735 * NULL and "size" zero if the socket was closed for
736 * writing in the meantime.
737 *
738 * @param cls closure
739 * @param size number of bytes available in buf
740 * @param buf where the callee should write the message
741 * @return number of bytes written to buf
742 */
743static size_t
744transmit_to_client_callback (void *cls, size_t size, void *buf)
745{
746 struct TransportClient *client = cls;
747 struct ClientMessageQueueEntry *q;
748 uint16_t msize;
749 size_t tsize;
750 const struct GNUNET_MessageHeader *msg;
751 struct GNUNET_NETWORK_TransmitHandle *th;
752 char *cbuf;
753
754 if (buf == NULL)
755 {
756 /* fatal error with client, free message queue! */
757 while (NULL != (q = client->message_queue_head))
758 {
759 client->message_queue_head = q->next;
760 GNUNET_free (q);
761 }
762 client->message_queue_tail = NULL;
763 client->message_count = 0;
764 return 0;
765 }
766 cbuf = buf;
767 tsize = 0;
768 while (NULL != (q = client->message_queue_head))
769 {
770 msg = (const struct GNUNET_MessageHeader *) &q[1];
771 msize = ntohs (msg->size);
772 if (msize + tsize > size)
773 break;
774 client->message_queue_head = q->next;
775 if (q->next == NULL)
776 client->message_queue_tail = NULL;
777 memcpy (&cbuf[tsize], msg, msize);
778 tsize += msize;
779 GNUNET_free (q);
780 client->message_count--;
781 }
782 GNUNET_assert (tsize > 0);
783 if (NULL != q)
784 {
785 th = GNUNET_SERVER_notify_transmit_ready (client->client,
786 msize,
787 GNUNET_TIME_UNIT_FOREVER_REL,
788 &transmit_to_client_callback,
789 client);
790 GNUNET_assert (th != NULL);
791 }
792 return tsize;
793}
794
795
796/**
797 * Send the specified message to the specified client. Since multiple
798 * messages may be pending for the same client at a time, this code
799 * makes sure that no message is lost.
800 *
801 * @param client client to transmit the message to
802 * @param msg the message to send
803 * @param may_drop can this message be dropped if the
804 * message queue for this client is getting far too large?
805 */
806static void
807transmit_to_client (struct TransportClient *client,
808 const struct GNUNET_MessageHeader *msg, int may_drop)
809{
810 struct ClientMessageQueueEntry *q;
811 uint16_t msize;
812 struct GNUNET_NETWORK_TransmitHandle *th;
813
814 if ((client->message_count >= MAX_PENDING) && (GNUNET_YES == may_drop))
815 {
816 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
817 _
818 ("Dropping message, have %u messages pending (%u is the soft limit)\n"),
819 client->message_count, MAX_PENDING);
820 /* TODO: call to statistics... */
821 return;
822 }
823 client->message_count++;
824 msize = ntohs (msg->size);
825 q = GNUNET_malloc (sizeof (struct ClientMessageQueueEntry) + msize);
826 memcpy (&q[1], msg, msize);
827 /* append to message queue */
828 if (client->message_queue_tail == NULL)
829 {
830 client->message_queue_tail = q;
831 }
832 else
833 {
834 client->message_queue_tail->next = q;
835 client->message_queue_tail = q;
836 }
837 if (client->message_queue_head == NULL)
838 {
839 client->message_queue_head = q;
840 th = GNUNET_SERVER_notify_transmit_ready (client->client,
841 msize,
842 GNUNET_TIME_UNIT_FOREVER_REL,
843 &transmit_to_client_callback,
844 client);
845 GNUNET_assert (th != NULL);
846 }
847}
848
849
850/**
851 * Find alternative plugins for communication.
852 *
853 * @param neighbour for which neighbour should we try to find
854 * more plugins?
855 */
856static void
857try_alternative_plugins (struct NeighbourList *neighbour)
858{
859 struct ReadyList *rl;
860
861 if ((neighbour->plugins != NULL) &&
862 (neighbour->retry_plugins_time.value >
863 GNUNET_TIME_absolute_get ().value))
864 return; /* don't try right now */
865 neighbour->retry_plugins_time
866 = GNUNET_TIME_relative_to_absolute (PLUGIN_RETRY_FREQUENCY);
867
868 rl = neighbour->plugins;
869 while (rl != NULL)
870 {
871 if (rl->connect_attempts > 0)
872 rl->connect_attempts--; /* amnesty */
873 rl = rl->next;
874 }
875
876}
877
878
879/**
880 * Check the ready list for the given neighbour and
881 * if a plugin is ready for transmission (and if we
882 * have a message), do so!
883 *
884 * @param neighbour target peer for which to check the plugins
885 */
886static void try_transmission_to_peer (struct NeighbourList *neighbour);
887
888
889/**
890 * Function called by the GNUNET_TRANSPORT_TransmitFunction
891 * upon "completion" of a send request. This tells the API
892 * that it is now legal to send another message to the given
893 * peer.
894 *
895 * @param cls closure, identifies the entry on the
896 * message queue that was transmitted and the
897 * client responsible for queueing the message
898 * @param rl identifies plugin used for the transmission for
899 * this neighbour; needs to be re-enabled for
900 * future transmissions
901 * @param target the peer receiving the message
902 * @param result GNUNET_OK on success, if the transmission
903 * failed, we should not tell the client to transmit
904 * more messages
905 */
906static void
907transmit_send_continuation (void *cls,
908 struct ReadyList *rl,
909 const struct GNUNET_PeerIdentity *target,
910 int result)
911{
912 struct MessageQueue *mq = cls;
913 struct SendOkMessage send_ok_msg;
914 struct NeighbourList *n;
915
916 GNUNET_assert (mq != NULL);
917 n = mq->neighbour;
918 GNUNET_assert (0 ==
919 memcmp (&n->id, target,
920 sizeof (struct GNUNET_PeerIdentity)));
921 if (rl == NULL)
922 {
923 rl = n->plugins;
924 while ((rl != NULL) && (rl->plugin != mq->plugin))
925 rl = rl->next;
926 GNUNET_assert (rl != NULL);
927 }
928 if (result == GNUNET_OK)
929 rl->timeout = GNUNET_TIME_relative_to_absolute (IDLE_CONNECTION_TIMEOUT);
930 else
931 rl->connected = GNUNET_NO;
932 if (!mq->internal_msg)
933 rl->transmit_ready = GNUNET_YES;
934 if (mq->client != NULL)
935 {
936 send_ok_msg.header.size = htons (sizeof (send_ok_msg));
937 send_ok_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK);
938 send_ok_msg.success = htonl (result);
939 send_ok_msg.peer = n->id;
940 transmit_to_client (mq->client, &send_ok_msg.header, GNUNET_NO);
941 }
942 GNUNET_free (mq->message);
943 GNUNET_free (mq);
944 /* one plugin just became ready again, try transmitting
945 another message (if available) */
946 try_transmission_to_peer (n);
947}
948
949
950
951
952/**
953 * We could not use an existing (or validated) connection to
954 * talk to a peer. Try addresses that have not yet been
955 * validated.
956 *
957 * @param n neighbour we want to communicate with
958 * @return plugin ready to talk, or NULL if none is available
959 */
960static struct ReadyList *
961try_unvalidated_addresses (struct NeighbourList *n)
962{
963 struct ValidationList *vl;
964 struct ValidationAddress *va;
965 struct GNUNET_PeerIdentity id;
966 struct GNUNET_TIME_Absolute now;
967 unsigned int total;
968 unsigned int cnt;
969 struct ReadyList *rl;
970 struct TransportPlugin *plugin;
971
972#if DEBUG_TRANSPORT
973 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
974 "Trying to connect to `%4s' using unvalidated addresses\n",
975 GNUNET_i2s (&n->id));
976#endif
977 /* NOTE: this function needs to not only identify the
978 plugin but also setup "plugin_handle", binding it to the
979 right address using the plugin's "send_to" API */
980 now = GNUNET_TIME_absolute_get ();
981 vl = pending_validations;
982 while (vl != NULL)
983 {
984 GNUNET_CRYPTO_hash (&vl->publicKey,
985 sizeof (struct
986 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
987 &id.hashPubKey);
988 if (0 == memcmp (&id, &n->id, sizeof (struct GNUNET_PeerIdentity)))
989 break;
990 vl = vl->next;
991 }
992 if (vl == NULL)
993 {
994#if DEBUG_TRANSPORT
995 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
996 "No unvalidated address found for peer `%4s'\n",
997 GNUNET_i2s (&n->id));
998#endif
999 return NULL;
1000 }
1001 total = 0;
1002 cnt = 0;
1003 va = vl->addresses;
1004 while (va != NULL)
1005 {
1006 cnt++;
1007 if (va->expiration.value > now.value)
1008 total++;
1009 va = va->next;
1010 }
1011 if (total == 0)
1012 {
1013#if DEBUG_TRANSPORT
1014 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1015 "All %u unvalidated addresses for peer have expired\n",
1016 cnt);
1017#endif
1018 return NULL;
1019 }
1020 total = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, total);
1021 for (va = vl->addresses; va != NULL; va = va->next)
1022 {
1023 if (va->expiration.value <= now.value)
1024 continue;
1025 if (total > 0)
1026 {
1027 total--;
1028 continue;
1029 }
1030#if DEBUG_TRANSPORT
1031 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
1032 "Trying unvalidated address of `%s' transport\n",
1033 va->transport_name);
1034#endif
1035 plugin = find_transport (va->transport_name);
1036 if (plugin == NULL)
1037 {
1038 GNUNET_break (0);
1039 break;
1040 }
1041 rl = GNUNET_malloc (sizeof (struct ReadyList));
1042 rl->next = n->plugins;
1043 n->plugins = rl;
1044 rl->plugin = plugin;
1045 rl->plugin_handle = plugin->api->send_to (plugin->api->cls,
1046 &n->id,
1047 NULL,
1048 NULL,
1049 GNUNET_TIME_UNIT_ZERO,
1050 &va->msg[1], va->addr_len);
1051 rl->transmit_ready = GNUNET_YES;
1052 return rl;
1053 }
1054 return NULL;
1055}
1056
1057
1058/**
1059 * Check the ready list for the given neighbour and
1060 * if a plugin is ready for transmission (and if we
1061 * have a message), do so!
1062 */
1063static void
1064try_transmission_to_peer (struct NeighbourList *neighbour)
1065{
1066 struct ReadyList *pos;
1067 struct GNUNET_TIME_Relative min_latency;
1068 struct ReadyList *rl;
1069 struct MessageQueue *mq;
1070 struct GNUNET_TIME_Absolute now;
1071
1072 if (neighbour->messages == NULL)
1073 return; /* nothing to do */
1074 try_alternative_plugins (neighbour);
1075 min_latency = GNUNET_TIME_UNIT_FOREVER_REL;
1076 rl = NULL;
1077 mq = neighbour->messages;
1078 now = GNUNET_TIME_absolute_get ();
1079 pos = neighbour->plugins;
1080 while (pos != NULL)
1081 {
1082 /* set plugins that are inactive for a long time back to disconnected */
1083 if ((pos->timeout.value < now.value) && (pos->connected == GNUNET_YES))
1084 {
1085#if DEBUG_TRANSPORT
1086 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1087 "Marking long-time inactive connection to `%4s' as down.\n",
1088 GNUNET_i2s (&neighbour->id));
1089#endif
1090 pos->connected = GNUNET_NO;
1091 }
1092 if (((GNUNET_YES == pos->transmit_ready) ||
1093 (mq->internal_msg)) &&
1094 (pos->connect_attempts < MAX_CONNECT_RETRY) &&
1095 ((rl == NULL) || (min_latency.value > pos->latency.value)))
1096 {
1097 rl = pos;
1098 min_latency = pos->latency;
1099 }
1100 pos = pos->next;
1101 }
1102 if (rl == NULL)
1103 rl = try_unvalidated_addresses (neighbour);
1104 if (rl == NULL)
1105 {
1106#if DEBUG_TRANSPORT
1107 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1108 "No plugin ready to transmit message\n");
1109#endif
1110 return; /* nobody ready */
1111 }
1112 if (GNUNET_NO == rl->connected)
1113 {
1114 rl->connect_attempts++;
1115 rl->connected = GNUNET_YES;
1116 }
1117 neighbour->messages = mq->next;
1118 mq->plugin = rl->plugin;
1119 if (!mq->internal_msg)
1120 rl->transmit_ready = GNUNET_NO;
1121#if DEBUG_TRANSPORT
1122 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1123 "Giving message of type `%u' for `%4s' to plugin `%s'\n",
1124 ntohs (mq->message->type),
1125 GNUNET_i2s (&neighbour->id), rl->plugin->short_name);
1126#endif
1127 rl->plugin_handle
1128 = rl->plugin->api->send (rl->plugin->api->cls,
1129 rl->plugin_handle,
1130 rl,
1131 &neighbour->id,
1132 mq->message,
1133 IDLE_CONNECTION_TIMEOUT,
1134 &transmit_send_continuation, mq);
1135}
1136
1137
1138/**
1139 * Send the specified message to the specified peer.
1140 *
1141 * @param client source of the transmission request (can be NULL)
1142 * @param msg message to send
1143 * @param is_internal is this an internal message
1144 * @param neighbour handle to the neighbour for transmission
1145 */
1146static void
1147transmit_to_peer (struct TransportClient *client,
1148 const struct GNUNET_MessageHeader *msg,
1149 int is_internal, struct NeighbourList *neighbour)
1150{
1151 struct MessageQueue *mq;
1152 struct MessageQueue *mqe;
1153 struct GNUNET_MessageHeader *m;
1154
1155#if DEBUG_TRANSPORT
1156 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1157 _("Sending message of type %u to peer `%4s'\n"),
1158 ntohs (msg->type), GNUNET_i2s (&neighbour->id));
1159#endif
1160 if (client != NULL)
1161 {
1162 /* check for duplicate submission */
1163 mq = neighbour->messages;
1164 while (NULL != mq)
1165 {
1166 if (mq->client == client)
1167 {
1168 /* client transmitted to same peer twice
1169 before getting SendOk! */
1170 GNUNET_break (0);
1171 return;
1172 }
1173 mq = mq->next;
1174 }
1175 }
1176 mq = GNUNET_malloc (sizeof (struct MessageQueue));
1177 mq->client = client;
1178 m = GNUNET_malloc (ntohs (msg->size));
1179 memcpy (m, msg, ntohs (msg->size));
1180 mq->message = m;
1181 mq->neighbour = neighbour;
1182 mq->internal_msg = is_internal;
1183
1184 /* find tail */
1185 mqe = neighbour->messages;
1186 if (mqe != NULL)
1187 while (mqe->next != NULL)
1188 mqe = mqe->next;
1189 if (mqe == NULL)
1190 {
1191 /* new head */
1192 neighbour->messages = mq;
1193 try_transmission_to_peer (neighbour);
1194 }
1195 else
1196 {
1197 /* append */
1198 mqe->next = mq;
1199 }
1200}
1201
1202
1203struct GeneratorContext
1204{
1205 struct TransportPlugin *plug_pos;
1206 struct AddressList *addr_pos;
1207 struct GNUNET_TIME_Absolute expiration;
1208};
1209
1210
1211static size_t
1212address_generator (void *cls, size_t max, void *buf)
1213{
1214 struct GeneratorContext *gc = cls;
1215 size_t ret;
1216
1217 while ((gc->addr_pos == NULL) && (gc->plug_pos != NULL))
1218 {
1219 gc->plug_pos = gc->plug_pos->next;
1220 gc->addr_pos = (gc->plug_pos != NULL) ? gc->plug_pos->addresses : NULL;
1221 }
1222 if (NULL == gc->plug_pos)
1223 return 0;
1224 ret = GNUNET_HELLO_add_address (gc->plug_pos->short_name,
1225 gc->expiration,
1226 gc->addr_pos->addr,
1227 gc->addr_pos->addrlen, buf, max);
1228 gc->addr_pos = gc->addr_pos->next;
1229 return ret;
1230}
1231
1232
1233/**
1234 * Construct our HELLO message from all of the addresses of
1235 * all of the transports.
1236 */
1237static void
1238refresh_hello ()
1239{
1240 struct GNUNET_HELLO_Message *hello;
1241 struct TransportClient *cpos;
1242 struct NeighbourList *npos;
1243 struct GeneratorContext gc;
1244
1245#if DEBUG_TRANSPORT
1246 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
1247 "Refreshing my HELLO\n");
1248#endif
1249 gc.plug_pos = plugins;
1250 gc.addr_pos = plugins != NULL ? plugins->addresses : NULL;
1251 gc.expiration = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION);
1252 hello = GNUNET_HELLO_create (&my_public_key, &address_generator, &gc);
1253 cpos = clients;
1254 while (cpos != NULL)
1255 {
1256 transmit_to_client (cpos,
1257 (const struct GNUNET_MessageHeader *) hello,
1258 GNUNET_NO);
1259 cpos = cpos->next;
1260 }
1261
1262 GNUNET_free_non_null (our_hello);
1263 our_hello = hello;
1264 our_hello_version++;
1265 npos = neighbours;
1266 while (npos != NULL)
1267 {
1268 transmit_to_peer (NULL,
1269 (const struct GNUNET_MessageHeader *) our_hello,
1270 GNUNET_YES, npos);
1271 npos = npos->next;
1272 }
1273}
1274
1275
1276/**
1277 * Task used to clean up expired addresses for a plugin.
1278 *
1279 * @param cls closure
1280 * @param tc context
1281 */
1282static void
1283expire_address_task (void *cls,
1284 const struct GNUNET_SCHEDULER_TaskContext *tc);
1285
1286
1287/**
1288 * Update the list of addresses for this plugin,
1289 * expiring those that are past their expiration date.
1290 *
1291 * @param plugin addresses of which plugin should be recomputed?
1292 * @param fresh set to GNUNET_YES if a new address was added
1293 * and we need to regenerate the HELLO even if nobody
1294 * expired
1295 */
1296static void
1297update_addresses (struct TransportPlugin *plugin, int fresh)
1298{
1299 struct GNUNET_TIME_Relative min_remaining;
1300 struct GNUNET_TIME_Relative remaining;
1301 struct GNUNET_TIME_Absolute now;
1302 struct AddressList *pos;
1303 struct AddressList *prev;
1304 struct AddressList *next;
1305 int expired;
1306
1307 if (plugin->address_update_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
1308 GNUNET_SCHEDULER_cancel (plugin->env.sched, plugin->address_update_task);
1309 plugin->address_update_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1310 now = GNUNET_TIME_absolute_get ();
1311 min_remaining = GNUNET_TIME_UNIT_FOREVER_REL;
1312 expired = GNUNET_NO;
1313 prev = NULL;
1314 pos = plugin->addresses;
1315 while (pos != NULL)
1316 {
1317 next = pos->next;
1318 if (pos->expires.value < now.value)
1319 {
1320 expired = GNUNET_YES;
1321 if (prev == NULL)
1322 plugin->addresses = pos->next;
1323 else
1324 prev->next = pos->next;
1325 GNUNET_free (pos);
1326 }
1327 else
1328 {
1329 remaining = GNUNET_TIME_absolute_get_remaining (pos->expires);
1330 if (remaining.value < min_remaining.value)
1331 min_remaining = remaining;
1332 prev = pos;
1333 }
1334 pos = next;
1335 }
1336
1337 if (expired || fresh)
1338 refresh_hello ();
1339 if (min_remaining.value < GNUNET_TIME_UNIT_FOREVER_REL.value)
1340 plugin->address_update_task
1341 = GNUNET_SCHEDULER_add_delayed (plugin->env.sched,
1342 GNUNET_NO,
1343 GNUNET_SCHEDULER_PRIORITY_IDLE,
1344 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1345 min_remaining,
1346 &expire_address_task, plugin);
1347
1348}
1349
1350
1351/**
1352 * Task used to clean up expired addresses for a plugin.
1353 *
1354 * @param cls closure
1355 * @param tc context
1356 */
1357static void
1358expire_address_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1359{
1360 struct TransportPlugin *plugin = cls;
1361 plugin->address_update_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1362 update_addresses (plugin, GNUNET_NO);
1363}
1364
1365
1366/**
1367 * Function that must be called by each plugin to notify the
1368 * transport service about the addresses under which the transport
1369 * provided by the plugin can be reached.
1370 *
1371 * @param cls closure
1372 * @param name name of the transport that generated the address
1373 * @param addr one of the addresses of the host, NULL for the last address
1374 * the specific address format depends on the transport
1375 * @param addrlen length of the address
1376 * @param expires when should this address automatically expire?
1377 */
1378static void
1379plugin_env_notify_address (void *cls,
1380 const char *name,
1381 const void *addr,
1382 size_t addrlen,
1383 struct GNUNET_TIME_Relative expires)
1384{
1385 struct TransportPlugin *p = cls;
1386 struct AddressList *al;
1387 struct GNUNET_TIME_Absolute abex;
1388
1389#if DEBUG_TRANSPORT
1390 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1391 "Plugin `%s' informs us about a new address\n", name);
1392#endif
1393 abex = GNUNET_TIME_relative_to_absolute (expires);
1394 GNUNET_assert (p == find_transport (name));
1395
1396 al = p->addresses;
1397 while (al != NULL)
1398 {
1399 if ((addrlen == al->addrlen) && (0 == memcmp (addr, &al[1], addrlen)))
1400 {
1401 if (al->expires.value < abex.value)
1402 al->expires = abex;
1403 return;
1404 }
1405 al = al->next;
1406 }
1407 al = GNUNET_malloc (sizeof (struct AddressList) + addrlen);
1408 al->addr = &al[1];
1409 al->next = p->addresses;
1410 p->addresses = al;
1411 al->expires = abex;
1412 al->addrlen = addrlen;
1413 memcpy (&al[1], addr, addrlen);
1414 update_addresses (p, GNUNET_YES);
1415}
1416
1417
1418struct LookupHelloContext
1419{
1420 GNUNET_TRANSPORT_AddressCallback iterator;
1421
1422 void *iterator_cls;
1423};
1424
1425
1426static int
1427lookup_address_callback (void *cls,
1428 const char *tname,
1429 struct GNUNET_TIME_Absolute expiration,
1430 const void *addr, size_t addrlen)
1431{
1432 struct LookupHelloContext *lhc = cls;
1433 lhc->iterator (lhc->iterator_cls, tname, addr, addrlen);
1434 return GNUNET_OK;
1435}
1436
1437
1438static void
1439lookup_hello_callback (void *cls,
1440 const struct GNUNET_PeerIdentity *peer,
1441 const struct GNUNET_HELLO_Message *h, uint32_t trust)
1442{
1443 struct LookupHelloContext *lhc = cls;
1444
1445 if (peer == NULL)
1446 {
1447 lhc->iterator (lhc->iterator_cls, NULL, NULL, 0);
1448 GNUNET_free (lhc);
1449 return;
1450 }
1451 if (h == NULL)
1452 return;
1453 GNUNET_HELLO_iterate_addresses (h,
1454 GNUNET_NO, &lookup_address_callback, lhc);
1455}
1456
1457
1458/**
1459 * Function that allows a transport to query the known
1460 * network addresses for a given peer.
1461 *
1462 * @param cls closure
1463 * @param timeout after how long should we time out?
1464 * @param target which peer are we looking for?
1465 * @param iter function to call for each known address
1466 * @param iter_cls closure for iter
1467 */
1468static void
1469plugin_env_lookup_address (void *cls,
1470 struct GNUNET_TIME_Relative timeout,
1471 const struct GNUNET_PeerIdentity *target,
1472 GNUNET_TRANSPORT_AddressCallback iter,
1473 void *iter_cls)
1474{
1475 struct LookupHelloContext *lhc;
1476
1477 lhc = GNUNET_malloc (sizeof (struct LookupHelloContext));
1478 lhc->iterator = iter;
1479 lhc->iterator_cls = iter_cls;
1480 GNUNET_PEERINFO_for_all (cfg,
1481 sched,
1482 target, 0, timeout, &lookup_hello_callback, &lhc);
1483}
1484
1485
1486/**
1487 * Notify all of our clients about a peer connecting.
1488 */
1489static void
1490notify_clients_connect (const struct GNUNET_PeerIdentity *peer,
1491 struct GNUNET_TIME_Relative latency)
1492{
1493 struct ConnectInfoMessage cim;
1494 struct TransportClient *cpos;
1495
1496#if DEBUG_TRANSPORT
1497 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1498 "Informing clients about peer `%4s' connecting to us\n",
1499 GNUNET_i2s (peer));
1500#endif
1501 cim.header.size = htons (sizeof (struct ConnectInfoMessage));
1502 cim.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
1503 cim.quota_out = htonl (default_quota_out);
1504 cim.latency = GNUNET_TIME_relative_hton (latency);
1505 memcpy (&cim.id, peer, sizeof (struct GNUNET_PeerIdentity));
1506 cpos = clients;
1507 while (cpos != NULL)
1508 {
1509 transmit_to_client (cpos, &cim.header, GNUNET_NO);
1510 cpos = cpos->next;
1511 }
1512}
1513
1514
1515/**
1516 * Notify all of our clients about a peer disconnecting.
1517 */
1518static void
1519notify_clients_disconnect (const struct GNUNET_PeerIdentity *peer)
1520{
1521 struct DisconnectInfoMessage dim;
1522 struct TransportClient *cpos;
1523
1524#if DEBUG_TRANSPORT
1525 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1526 "Informing clients about peer `%4s' disconnecting\n",
1527 GNUNET_i2s (peer));
1528#endif
1529 dim.header.size = htons (sizeof (struct DisconnectInfoMessage));
1530 dim.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT);
1531 dim.reserved = htonl (0);
1532 memcpy (&dim.peer, peer, sizeof (struct GNUNET_PeerIdentity));
1533 cpos = clients;
1534 while (cpos != NULL)
1535 {
1536 transmit_to_client (cpos, &dim.header, GNUNET_NO);
1537 cpos = cpos->next;
1538 }
1539}
1540
1541
1542/**
1543 * Copy any validated addresses to buf.
1544 *
1545 * @return 0 once all addresses have been
1546 * returned
1547 */
1548static size_t
1549list_validated_addresses (void *cls, size_t max, void *buf)
1550{
1551 struct ValidationAddress **va = cls;
1552 size_t ret;
1553
1554 while ((NULL != *va) && ((*va)->ok != GNUNET_YES))
1555 *va = (*va)->next;
1556 if (NULL == *va)
1557 return 0;
1558 ret = GNUNET_HELLO_add_address ((*va)->transport_name,
1559 (*va)->expiration,
1560 &(*va)->msg[1], (*va)->addr_len, buf, max);
1561 *va = (*va)->next;
1562 return ret;
1563}
1564
1565
1566/**
1567 * HELLO validation cleanup task.
1568 */
1569static void
1570cleanup_validation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1571{
1572 struct ValidationAddress *va;
1573 struct ValidationList *pos;
1574 struct ValidationList *prev;
1575 struct GNUNET_TIME_Absolute now;
1576 struct GNUNET_HELLO_Message *hello;
1577 struct GNUNET_PeerIdentity pid;
1578
1579#if DEBUG_TRANSPORT
1580 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
1581 "HELLO validation cleanup background task running...\n");
1582#endif
1583 now = GNUNET_TIME_absolute_get ();
1584 prev = NULL;
1585 pos = pending_validations;
1586 while (pos != NULL)
1587 {
1588 if (pos->timeout.value < now.value)
1589 {
1590 if (prev == NULL)
1591 pending_validations = pos->next;
1592 else
1593 prev->next = pos->next;
1594 va = pos->addresses;
1595 hello = GNUNET_HELLO_create (&pos->publicKey,
1596 &list_validated_addresses, &va);
1597 GNUNET_CRYPTO_hash (&pos->publicKey,
1598 sizeof (struct
1599 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
1600 &pid.hashPubKey);
1601#if DEBUG_TRANSPORT
1602 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1603 "Creating persistent `%s' message for peer `%4s' based on confirmed addresses.\n",
1604 "HELLO", GNUNET_i2s (&pid));
1605#endif
1606 GNUNET_PEERINFO_add_peer (cfg, sched, &pid, hello);
1607 GNUNET_free (hello);
1608 while (NULL != (va = pos->addresses))
1609 {
1610 pos->addresses = va->next;
1611 GNUNET_free (va->transport_name);
1612 GNUNET_free (va);
1613 }
1614 GNUNET_free (pos);
1615 if (prev == NULL)
1616 pos = pending_validations;
1617 else
1618 pos = prev->next;
1619 continue;
1620 }
1621 prev = pos;
1622 pos = pos->next;
1623 }
1624
1625 /* finally, reschedule cleanup if needed; list is
1626 ordered by timeout, so we need the last element... */
1627 pos = pending_validations;
1628 while ((pos != NULL) && (pos->next != NULL))
1629 pos = pos->next;
1630 if (NULL != pos)
1631 GNUNET_SCHEDULER_add_delayed (sched,
1632 GNUNET_NO,
1633 GNUNET_SCHEDULER_PRIORITY_IDLE,
1634 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1635 GNUNET_TIME_absolute_get_remaining (pos->
1636 timeout),
1637 &cleanup_validation, NULL);
1638}
1639
1640
1641struct CheckHelloValidatedContext
1642{
1643 /**
1644 * Plugin for which we are validating.
1645 */
1646 struct TransportPlugin *plugin;
1647
1648 /**
1649 * Hello that we are validating.
1650 */
1651 struct GNUNET_HELLO_Message *hello;
1652
1653 /**
1654 * Validation list being build.
1655 */
1656 struct ValidationList *e;
1657};
1658
1659
1660/**
1661 * Append the given address to the list of entries
1662 * that need to be validated.
1663 */
1664static int
1665run_validation (void *cls,
1666 const char *tname,
1667 struct GNUNET_TIME_Absolute expiration,
1668 const void *addr, size_t addrlen)
1669{
1670 struct ValidationList *e = cls;
1671 struct TransportPlugin *tp;
1672 struct ValidationAddress *va;
1673 struct ValidationChallengeMessage *vcm;
1674
1675 tp = find_transport (tname);
1676 if (tp == NULL)
1677 {
1678 GNUNET_log (GNUNET_ERROR_TYPE_INFO |
1679 GNUNET_ERROR_TYPE_BULK,
1680 _
1681 ("Transport `%s' not loaded, will not try to validate peer address using this transport.\n"),
1682 tname);
1683 return GNUNET_OK;
1684 }
1685 va = GNUNET_malloc (sizeof (struct ValidationAddress) +
1686 sizeof (struct ValidationChallengeMessage) + addrlen);
1687 va->next = e->addresses;
1688 e->addresses = va;
1689 vcm = (struct ValidationChallengeMessage *) &va[1];
1690 va->msg = vcm;
1691 va->transport_name = GNUNET_strdup (tname);
1692 va->addr_len = addrlen;
1693 vcm->header.size =
1694 htons (sizeof (struct ValidationChallengeMessage) + addrlen);
1695 vcm->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PING);
1696 vcm->purpose.size =
1697 htonl (sizeof (struct ValidationChallengeMessage) + addrlen -
1698 sizeof (struct GNUNET_MessageHeader));
1699 vcm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_HELLO);
1700 vcm->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1701 (unsigned int) -1);
1702 /* Note: vcm->target is set in check_hello_validated */
1703 memcpy (&vcm[1], addr, addrlen);
1704 return GNUNET_OK;
1705}
1706
1707
1708/**
1709 * Check if addresses in validated hello "h" overlap with
1710 * those in "chvc->hello" and update "chvc->hello" accordingly,
1711 * removing those addresses that have already been validated.
1712 */
1713static void
1714check_hello_validated (void *cls,
1715 const struct GNUNET_PeerIdentity *peer,
1716 const struct GNUNET_HELLO_Message *h, uint32_t trust)
1717{
1718 struct CheckHelloValidatedContext *chvc = cls;
1719 struct ValidationAddress *va;
1720 struct TransportPlugin *tp;
1721 int first_call;
1722
1723 first_call = GNUNET_NO;
1724 if (chvc->e == NULL)
1725 {
1726 first_call = GNUNET_YES;
1727 chvc->e = GNUNET_malloc (sizeof (struct ValidationList));
1728 GNUNET_HELLO_get_key (h != NULL ? h : chvc->hello, &chvc->e->publicKey);
1729 chvc->e->timeout =
1730 GNUNET_TIME_relative_to_absolute (HELLO_VERIFICATION_TIMEOUT);
1731 chvc->e->next = pending_validations;
1732 pending_validations = chvc->e;
1733 }
1734 if (h != NULL)
1735 {
1736 GNUNET_HELLO_iterate_new_addresses (chvc->hello,
1737 h,
1738 GNUNET_TIME_absolute_get (),
1739 &run_validation, chvc->e);
1740 }
1741 else if (GNUNET_YES == first_call)
1742 {
1743 /* no existing HELLO, all addresses are new */
1744 GNUNET_HELLO_iterate_addresses (chvc->hello,
1745 GNUNET_NO, &run_validation, chvc->e);
1746 }
1747 if (h != NULL)
1748 return; /* wait for next call */
1749 /* finally, transmit validation attempts */
1750 va = chvc->e->addresses;
1751 while (va != NULL)
1752 {
1753 GNUNET_CRYPTO_hash (&chvc->e->publicKey,
1754 sizeof (struct
1755 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
1756 &va->msg->target.hashPubKey);
1757#if DEBUG_TRANSPORT
1758 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1759 "Establishing `%s' connection to validate `%s' of `%4s' (sending our `%s')\n",
1760 va->transport_name,
1761 "HELLO", GNUNET_i2s (&va->msg->target), "HELLO");
1762#endif
1763 tp = find_transport (va->transport_name);
1764 GNUNET_assert (tp != NULL);
1765 if (NULL ==
1766 tp->api->send_to (tp->api->cls,
1767 &va->msg->target,
1768 (const struct GNUNET_MessageHeader *) our_hello,
1769 &va->msg->header,
1770 HELLO_VERIFICATION_TIMEOUT,
1771 &va->msg[1], va->addr_len))
1772 va->ok = GNUNET_SYSERR;
1773 va = va->next;
1774 }
1775 if (chvc->e->next == NULL)
1776 GNUNET_SCHEDULER_add_delayed (sched,
1777 GNUNET_NO,
1778 GNUNET_SCHEDULER_PRIORITY_IDLE,
1779 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1780 GNUNET_TIME_absolute_get_remaining (chvc->
1781 e->
1782 timeout),
1783 &cleanup_validation, NULL);
1784 GNUNET_free (chvc);
1785}
1786
1787
1788/**
1789 * Process HELLO-message.
1790 *
1791 * @param plugin transport involved, may be NULL
1792 * @param message the actual message
1793 * @return GNUNET_OK if the HELLO was well-formed, GNUNET_SYSERR otherwise
1794 */
1795static int
1796process_hello (struct TransportPlugin *plugin,
1797 const struct GNUNET_MessageHeader *message)
1798{
1799 struct ValidationList *e;
1800 uint16_t hsize;
1801 struct GNUNET_PeerIdentity target;
1802 const struct GNUNET_HELLO_Message *hello;
1803 struct CheckHelloValidatedContext *chvc;
1804 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded publicKey;
1805
1806 hsize = ntohs (message->size);
1807 if ((ntohs (message->type) != GNUNET_MESSAGE_TYPE_HELLO) ||
1808 (hsize < sizeof (struct GNUNET_MessageHeader)))
1809 {
1810 GNUNET_break (0);
1811 return GNUNET_SYSERR;
1812 }
1813 /* first, check if load is too high */
1814 if (GNUNET_OS_load_cpu_get (cfg) > 100)
1815 {
1816 /* TODO: call to stats? */
1817 return GNUNET_OK;
1818 }
1819 hello = (const struct GNUNET_HELLO_Message *) message;
1820 if (GNUNET_OK != GNUNET_HELLO_get_key (hello, &publicKey))
1821 {
1822 GNUNET_break_op (0);
1823 return GNUNET_SYSERR;
1824 }
1825 GNUNET_CRYPTO_hash (&publicKey,
1826 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
1827 &target.hashPubKey);
1828#if DEBUG_TRANSPORT
1829 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1830 "Processing `%s' message for `%4s'\n",
1831 "HELLO", GNUNET_i2s (&target));
1832#endif
1833 /* check if a HELLO for this peer is already on the validation list */
1834 e = pending_validations;
1835 while (e != NULL)
1836 {
1837 if (0 == memcmp (&e->publicKey,
1838 &publicKey,
1839 sizeof (struct
1840 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))
1841 {
1842 /* TODO: call to stats? */
1843 return GNUNET_OK;
1844 }
1845 e = e->next;
1846 }
1847 chvc = GNUNET_malloc (sizeof (struct CheckHelloValidatedContext) + hsize);
1848 chvc->plugin = plugin;
1849 chvc->hello = (struct GNUNET_HELLO_Message *) &chvc[1];
1850 memcpy (chvc->hello, hello, hsize);
1851 /* finally, check if HELLO was previously validated
1852 (continuation will then schedule actual validation) */
1853 GNUNET_PEERINFO_for_all (cfg,
1854 sched,
1855 &target,
1856 0,
1857 HELLO_VERIFICATION_TIMEOUT,
1858 &check_hello_validated, chvc);
1859 return GNUNET_OK;
1860}
1861
1862
1863/**
1864 * Handle PING-message. If the plugin that gave us the message is
1865 * able to queue the PONG immediately, we only queue one PONG.
1866 * Otherwise we send at most TWO PONG messages, one via an unconfirmed
1867 * transport and one via a confirmed transport. Both addresses are
1868 * selected randomly among those available.
1869 *
1870 * @param plugin plugin that gave us the message
1871 * @param sender claimed sender of the PING
1872 * @param plugin_context context that might be used to send response
1873 * @param message the actual message
1874 */
1875static void
1876process_ping (struct TransportPlugin *plugin,
1877 const struct GNUNET_PeerIdentity *sender,
1878 void *plugin_context,
1879 const struct GNUNET_MessageHeader *message)
1880{
1881 const struct ValidationChallengeMessage *vcm;
1882 struct ValidationChallengeResponse vcr;
1883 uint16_t msize;
1884 struct NeighbourList *n;
1885
1886#if DEBUG_TRANSPORT
1887 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
1888 "Processing PING\n");
1889#endif
1890 msize = ntohs (message->size);
1891 if (msize < sizeof (struct ValidationChallengeMessage))
1892 {
1893 GNUNET_break_op (0);
1894 return;
1895 }
1896 vcm = (const struct ValidationChallengeMessage *) message;
1897 if (0 != memcmp (&vcm->target,
1898 &my_identity, sizeof (struct GNUNET_PeerIdentity)))
1899 {
1900 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1901 _("Received `%s' message not destined for me!\n"), "PING");
1902 /* TODO: call statistics */
1903 return;
1904 }
1905 if ((ntohl (vcm->purpose.size) !=
1906 msize - sizeof (struct GNUNET_MessageHeader))
1907 || (ntohl (vcm->purpose.purpose) !=
1908 GNUNET_SIGNATURE_PURPOSE_TRANSPORT_HELLO))
1909 {
1910 GNUNET_break_op (0);
1911 return;
1912 }
1913 msize -= sizeof (struct ValidationChallengeMessage);
1914 if (GNUNET_OK !=
1915 plugin->api->address_suggested (plugin->api->cls, &vcm[1], msize))
1916 {
1917 GNUNET_break_op (0);
1918 return;
1919 }
1920 vcr.header.size = htons (sizeof (struct ValidationChallengeResponse));
1921 vcr.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
1922 vcr.challenge = vcm->challenge;
1923 vcr.sender = my_identity;
1924 GNUNET_assert (GNUNET_OK ==
1925 GNUNET_CRYPTO_rsa_sign (my_private_key,
1926 &vcm->purpose, &vcr.signature));
1927#if EXTRA_CHECKS
1928 GNUNET_assert (GNUNET_OK ==
1929 GNUNET_CRYPTO_rsa_verify
1930 (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_HELLO, &vcm->purpose,
1931 &vcr.signature, &my_public_key));
1932#endif
1933#if DEBUG_TRANSPORT
1934 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
1935 "Trying to transmit PONG using inbound connection\n");
1936#endif
1937 n = find_neighbour (sender);
1938 transmit_to_peer (NULL, &vcr.header, GNUNET_YES, n);
1939}
1940
1941
1942/**
1943 * Handle PONG-message.
1944 *
1945 * @param message the actual message
1946 */
1947static void
1948process_pong (struct TransportPlugin *plugin,
1949 const struct GNUNET_MessageHeader *message)
1950{
1951 const struct ValidationChallengeResponse *vcr;
1952 struct ValidationList *pos;
1953 struct GNUNET_PeerIdentity peer;
1954 struct ValidationAddress *va;
1955 int all_done;
1956 int matched;
1957
1958#if DEBUG_TRANSPORT
1959 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
1960 "Processing PONG\n");
1961#endif
1962 vcr = (const struct ValidationChallengeResponse *) message;
1963 pos = pending_validations;
1964 while (pos != NULL)
1965 {
1966 GNUNET_CRYPTO_hash (&pos->publicKey,
1967 sizeof (struct
1968 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
1969 &peer.hashPubKey);
1970 if (0 ==
1971 memcmp (&peer, &vcr->sender, sizeof (struct GNUNET_PeerIdentity)))
1972 break;
1973 pos = pos->next;
1974 }
1975 if (pos == NULL)
1976 {
1977 /* TODO: call statistics (unmatched PONG) */
1978 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1979 _
1980 ("Received `%s' message but have no record of a matching `%s' message. Ignoring.\n"),
1981 "PONG", "PING");
1982 return;
1983 }
1984 all_done = GNUNET_YES;
1985 matched = GNUNET_NO;
1986 va = pos->addresses;
1987 while (va != NULL)
1988 {
1989 if (va->msg->challenge == vcr->challenge)
1990 {
1991 if (GNUNET_OK !=
1992 GNUNET_CRYPTO_rsa_verify
1993 (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_HELLO, &va->msg->purpose,
1994 &vcr->signature, &pos->publicKey))
1995 {
1996 /* this could rarely happen if we used the same
1997 challenge number for the peer for two different
1998 transports / addresses, but the likelihood is
1999 very small... */
2000 GNUNET_break_op (0);
2001 }
2002 else
2003 {
2004#if DEBUG_TRANSPORT
2005 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2006 "Confirmed validity of peer address.\n");
2007#endif
2008 va->ok = GNUNET_YES;
2009 va->expiration =
2010 GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION);
2011 matched = GNUNET_YES;
2012 }
2013 }
2014 if (va->ok != GNUNET_YES)
2015 all_done = GNUNET_NO;
2016 va = va->next;
2017 }
2018 if (GNUNET_NO == matched)
2019 {
2020 /* TODO: call statistics (unmatched PONG) */
2021 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2022 _
2023 ("Received `%s' message but have no record of a matching `%s' message. Ignoring.\n"),
2024 "PONG", "PING");
2025 }
2026 if (GNUNET_YES == all_done)
2027 {
2028 pos->timeout.value = 0;
2029 GNUNET_SCHEDULER_add_delayed (sched,
2030 GNUNET_NO,
2031 GNUNET_SCHEDULER_PRIORITY_IDLE,
2032 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
2033 GNUNET_TIME_UNIT_ZERO,
2034 &cleanup_validation, NULL);
2035 }
2036}
2037
2038
2039/**
2040 * The peer specified by the given neighbour has timed-out. Update
2041 * our state and do the necessary notifications. Also notifies
2042 * our clients that the neighbour is now officially gone.
2043 *
2044 * @param n the neighbour list entry for the peer
2045 */
2046static void
2047disconnect_neighbour (struct NeighbourList *n)
2048{
2049 struct ReadyList *rpos;
2050 struct NeighbourList *npos;
2051 struct NeighbourList *nprev;
2052 struct MessageQueue *mq;
2053
2054#if DEBUG_TRANSPORT
2055 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
2056 "Disconnecting from neighbour\n");
2057#endif
2058 /* remove n from neighbours list */
2059 nprev = NULL;
2060 npos = neighbours;
2061 while ((npos != NULL) && (npos != n))
2062 {
2063 nprev = npos;
2064 npos = npos->next;
2065 }
2066 GNUNET_assert (npos != NULL);
2067 if (nprev == NULL)
2068 neighbours = n->next;
2069 else
2070 nprev->next = n->next;
2071
2072 /* notify all clients about disconnect */
2073 notify_clients_disconnect (&n->id);
2074
2075 /* clean up all plugins, cancel connections & pending transmissions */
2076 while (NULL != (rpos = n->plugins))
2077 {
2078 n->plugins = rpos->next;
2079 GNUNET_assert (rpos->neighbour == n);
2080 rpos->plugin->api->cancel (rpos->plugin->api->cls,
2081 rpos->plugin_handle, rpos, &n->id);
2082 GNUNET_free (rpos);
2083 }
2084
2085 /* free all messages on the queue */
2086 while (NULL != (mq = n->messages))
2087 {
2088 n->messages = mq->next;
2089 GNUNET_assert (mq->neighbour == n);
2090 GNUNET_free (mq);
2091 }
2092
2093 /* finally, free n itself */
2094 GNUNET_free (n);
2095}
2096
2097
2098/**
2099 * Add an entry for each of our transport plugins
2100 * (that are able to send) to the list of plugins
2101 * for this neighbour.
2102 *
2103 * @param neighbour to initialize
2104 */
2105static void
2106add_plugins (struct NeighbourList *neighbour)
2107{
2108 struct TransportPlugin *tp;
2109 struct ReadyList *rl;
2110
2111 neighbour->retry_plugins_time
2112 = GNUNET_TIME_relative_to_absolute (PLUGIN_RETRY_FREQUENCY);
2113 tp = plugins;
2114 while (tp != NULL)
2115 {
2116 if (tp->api->send != NULL)
2117 {
2118 rl = GNUNET_malloc (sizeof (struct ReadyList));
2119 rl->next = neighbour->plugins;
2120 neighbour->plugins = rl;
2121 rl->plugin = tp;
2122 rl->neighbour = neighbour;
2123 rl->transmit_ready = GNUNET_YES;
2124 }
2125 tp = tp->next;
2126 }
2127}
2128
2129
2130static void
2131neighbour_timeout_task (void *cls,
2132 const struct GNUNET_SCHEDULER_TaskContext *tc)
2133{
2134 struct NeighbourList *n = cls;
2135
2136#if DEBUG_TRANSPORT
2137 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
2138 "Neighbour has timed out!\n");
2139#endif
2140 n->timeout_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
2141 disconnect_neighbour (n);
2142}
2143
2144
2145
2146/**
2147 * Create a fresh entry in our neighbour list for the given peer.
2148 * Will try to transmit our current HELLO to the new neighbour. Also
2149 * notifies our clients about the new "connection".
2150 *
2151 * @param peer the peer for which we create the entry
2152 * @return the new neighbour list entry
2153 */
2154static struct NeighbourList *
2155setup_new_neighbour (const struct GNUNET_PeerIdentity *peer)
2156{
2157 struct NeighbourList *n;
2158
2159#if DEBUG_TRANSPORT
2160 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
2161 "Setting up new neighbour `%4s', sending our HELLO to introduce ourselves\n",
2162 GNUNET_i2s (peer));
2163#endif
2164 GNUNET_assert (our_hello != NULL);
2165 n = GNUNET_malloc (sizeof (struct NeighbourList));
2166 n->next = neighbours;
2167 neighbours = n;
2168 n->id = *peer;
2169 n->last_quota_update = GNUNET_TIME_absolute_get ();
2170 n->peer_timeout =
2171 GNUNET_TIME_relative_to_absolute (IDLE_CONNECTION_TIMEOUT);
2172 n->quota_in = default_quota_in;
2173 add_plugins (n);
2174 n->hello_version_sent = our_hello_version;
2175 n->timeout_task = GNUNET_SCHEDULER_add_delayed (sched,
2176 GNUNET_NO,
2177 GNUNET_SCHEDULER_PRIORITY_IDLE,
2178 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
2179 IDLE_CONNECTION_TIMEOUT,
2180 &neighbour_timeout_task, n);
2181 transmit_to_peer (NULL,
2182 (const struct GNUNET_MessageHeader *) our_hello,
2183 GNUNET_YES, n);
2184 notify_clients_connect (peer, GNUNET_TIME_UNIT_FOREVER_REL);
2185 return n;
2186}
2187
2188
2189/**
2190 * Function called by the plugin for each received message.
2191 * Update data volumes, possibly notify plugins about
2192 * reducing the rate at which they read from the socket
2193 * and generally forward to our receive callback.
2194 *
2195 * @param plugin_context value to pass to this plugin
2196 * to respond to the given peer (use is optional,
2197 * but may speed up processing)
2198 * @param service_context value passed to the transport-service
2199 * to identify the neighbour; will be NULL on the first
2200 * call for a given peer
2201 * @param latency estimated latency for communicating with the
2202 * given peer
2203 * @param peer (claimed) identity of the other peer
2204 * @param message the message, NULL if peer was disconnected
2205 * @return the new service_context that the plugin should use
2206 * for future receive calls for messages from this
2207 * particular peer
2208 */
2209static struct ReadyList *
2210plugin_env_receive (void *cls,
2211 void *plugin_context,
2212 struct ReadyList *service_context,
2213 struct GNUNET_TIME_Relative latency,
2214 const struct GNUNET_PeerIdentity *peer,
2215 const struct GNUNET_MessageHeader *message)
2216{
2217 const struct GNUNET_MessageHeader ack = {
2218 htons (sizeof (struct GNUNET_MessageHeader)),
2219 htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ACK)
2220 };
2221 struct TransportPlugin *plugin = cls;
2222 struct TransportClient *cpos;
2223 struct InboundMessage *im;
2224 uint16_t msize;
2225 struct NeighbourList *n;
2226
2227 if (service_context != NULL)
2228 {
2229 n = service_context->neighbour;
2230 GNUNET_assert (n != NULL);
2231 }
2232 else
2233 {
2234 n = find_neighbour (peer);
2235 if (n == NULL)
2236 {
2237 if (message == NULL)
2238 return NULL; /* disconnect of peer already marked down */
2239 n = setup_new_neighbour (peer);
2240 }
2241 service_context = n->plugins;
2242 while ((service_context != NULL) && (plugin != service_context->plugin))
2243 service_context = service_context->next;
2244 GNUNET_assert ((plugin->api->send == NULL) ||
2245 (service_context != NULL));
2246 }
2247 if (message == NULL)
2248 {
2249 if ((service_context != NULL) &&
2250 (service_context->plugin_handle == plugin_context))
2251 {
2252 service_context->connected = GNUNET_NO;
2253 service_context->plugin_handle = NULL;
2254 }
2255 /* TODO: call stats */
2256 return NULL;
2257 }
2258#if DEBUG_TRANSPORT
2259 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
2260 "Processing message of type `%u' received by plugin...\n",
2261 ntohs (message->type));
2262#endif
2263 if (service_context != NULL)
2264 {
2265 if (service_context->connected == GNUNET_NO)
2266 {
2267 service_context->connected = GNUNET_YES;
2268 service_context->transmit_ready = GNUNET_YES;
2269 service_context->connect_attempts++;
2270 }
2271 service_context->timeout
2272 = GNUNET_TIME_relative_to_absolute (IDLE_CONNECTION_TIMEOUT);
2273 service_context->plugin_handle = plugin_context;
2274 service_context->latency = latency;
2275 }
2276 /* update traffic received amount ... */
2277 msize = ntohs (message->size);
2278 n->last_received += msize;
2279 GNUNET_SCHEDULER_cancel (sched, n->timeout_task);
2280 n->peer_timeout =
2281 GNUNET_TIME_relative_to_absolute (IDLE_CONNECTION_TIMEOUT);
2282 n->timeout_task =
2283 GNUNET_SCHEDULER_add_delayed (sched, GNUNET_NO,
2284 GNUNET_SCHEDULER_PRIORITY_IDLE,
2285 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
2286 IDLE_CONNECTION_TIMEOUT,
2287 &neighbour_timeout_task, n);
2288 update_quota (n);
2289 if (n->quota_violation_count > QUOTA_VIOLATION_DROP_THRESHOLD)
2290 {
2291 /* dropping message due to frequent inbound volume violations! */
2292 GNUNET_log (GNUNET_ERROR_TYPE_WARNING |
2293 GNUNET_ERROR_TYPE_BULK,
2294 _
2295 ("Dropping incoming message due to repeated bandwidth quota violations.\n"));
2296 /* TODO: call stats */
2297 return service_context;
2298 }
2299 switch (ntohs (message->type))
2300 {
2301 case GNUNET_MESSAGE_TYPE_HELLO:
2302#if DEBUG_TRANSPORT
2303 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2304 "Receiving `%s' message from other peer.\n", "HELLO");
2305#endif
2306 process_hello (plugin, message);
2307#if DEBUG_TRANSPORT
2308 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2309 "Sending `%s' message to connecting peer.\n", "ACK");
2310#endif
2311 transmit_to_peer (NULL, &ack, GNUNET_YES, n);
2312 break;
2313 case GNUNET_MESSAGE_TYPE_TRANSPORT_PING:
2314 process_ping (plugin, peer, plugin_context, message);
2315 break;
2316 case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG:
2317 process_pong (plugin, message);
2318 break;
2319 case GNUNET_MESSAGE_TYPE_TRANSPORT_ACK:
2320 n->saw_ack = GNUNET_YES;
2321 /* intentional fall-through! */
2322 default:
2323#if DEBUG_TRANSPORT
2324 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2325 "Received message of type %u from other peer, sending to all clients.\n",
2326 ntohs (message->type));
2327#endif
2328 /* transmit message to all clients */
2329 im = GNUNET_malloc (sizeof (struct InboundMessage) + msize);
2330 im->header.size = htons (sizeof (struct InboundMessage) + msize);
2331 im->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RECV);
2332 im->latency = GNUNET_TIME_relative_hton (latency);
2333 im->peer = *peer;
2334 memcpy (&im[1], message, msize);
2335
2336 cpos = clients;
2337 while (cpos != NULL)
2338 {
2339 transmit_to_client (cpos, &im->header, GNUNET_YES);
2340 cpos = cpos->next;
2341 }
2342 GNUNET_free (im);
2343 }
2344 return service_context;
2345}
2346
2347
2348/**
2349 * Handle START-message. This is the first message sent to us
2350 * by any client which causes us to add it to our list.
2351 *
2352 * @param cls closure (always NULL)
2353 * @param server the server handling the message
2354 * @param client identification of the client
2355 * @param message the actual message
2356 */
2357static void
2358handle_start (void *cls,
2359 struct GNUNET_SERVER_Handle *server,
2360 struct GNUNET_SERVER_Client *client,
2361 const struct GNUNET_MessageHeader *message)
2362{
2363 struct TransportClient *c;
2364 struct ConnectInfoMessage cim;
2365 struct NeighbourList *n;
2366 struct InboundMessage *im;
2367 struct GNUNET_MessageHeader *ack;
2368
2369#if DEBUG_TRANSPORT
2370 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2371 "Received `%s' request from client\n", "START");
2372#endif
2373 c = clients;
2374 while (c != NULL)
2375 {
2376 if (c->client == client)
2377 {
2378 /* client already on our list! */
2379 GNUNET_break (0);
2380 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2381 return;
2382 }
2383 c = c->next;
2384 }
2385 c = GNUNET_malloc (sizeof (struct TransportClient));
2386 c->next = clients;
2387 clients = c;
2388 c->client = client;
2389 if (our_hello != NULL)
2390 {
2391#if DEBUG_TRANSPORT
2392 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2393 "Sending our own HELLO to new client\n");
2394#endif
2395 transmit_to_client (c,
2396 (const struct GNUNET_MessageHeader *) our_hello,
2397 GNUNET_NO);
2398 /* tell new client about all existing connections */
2399 cim.header.size = htons (sizeof (struct ConnectInfoMessage));
2400 cim.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
2401 cim.quota_out = htonl (default_quota_out);
2402 cim.latency = GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_ZERO); /* FIXME? */
2403 im = GNUNET_malloc (sizeof (struct InboundMessage) +
2404 sizeof (struct GNUNET_MessageHeader));
2405 im->header.size = htons (sizeof (struct InboundMessage) +
2406 sizeof (struct GNUNET_MessageHeader));
2407 im->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RECV);
2408 im->latency = GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_ZERO); /* FIXME? */
2409 ack = (struct GNUNET_MessageHeader *) &im[1];
2410 ack->size = htons (sizeof (struct GNUNET_MessageHeader));
2411 ack->type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ACK);
2412 for (n = neighbours; n != NULL; n = n->next)
2413 {
2414 cim.id = n->id;
2415 transmit_to_client (c, &cim.header, GNUNET_NO);
2416 if (n->saw_ack)
2417 {
2418 im->peer = n->id;
2419 transmit_to_client (c, &im->header, GNUNET_NO);
2420 }
2421 }
2422 GNUNET_free (im);
2423 }
2424 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2425}
2426
2427
2428/**
2429 * Handle HELLO-message.
2430 *
2431 * @param cls closure (always NULL)
2432 * @param server the server handling the message
2433 * @param client identification of the client
2434 * @param message the actual message
2435 */
2436static void
2437handle_hello (void *cls,
2438 struct GNUNET_SERVER_Handle *server,
2439 struct GNUNET_SERVER_Client *client,
2440 const struct GNUNET_MessageHeader *message)
2441{
2442 int ret;
2443
2444#if DEBUG_TRANSPORT
2445 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2446 "Received `%s' request from client\n", "HELLO");
2447#endif
2448 ret = process_hello (NULL, message);
2449 GNUNET_SERVER_receive_done (client, ret);
2450}
2451
2452
2453/**
2454 * Handle SEND-message.
2455 *
2456 * @param cls closure (always NULL)
2457 * @param server the server handling the message
2458 * @param client identification of the client
2459 * @param message the actual message
2460 */
2461static void
2462handle_send (void *cls,
2463 struct GNUNET_SERVER_Handle *server,
2464 struct GNUNET_SERVER_Client *client,
2465 const struct GNUNET_MessageHeader *message)
2466{
2467 struct TransportClient *tc;
2468 struct NeighbourList *n;
2469 const struct OutboundMessage *obm;
2470 const struct GNUNET_MessageHeader *obmm;
2471 uint16_t size;
2472 uint16_t msize;
2473
2474 size = ntohs (message->size);
2475 if (size <
2476 sizeof (struct OutboundMessage) + sizeof (struct GNUNET_MessageHeader))
2477 {
2478 GNUNET_break (0);
2479 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2480 return;
2481 }
2482 obm = (const struct OutboundMessage *) message;
2483#if DEBUG_TRANSPORT
2484 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2485 "Received `%s' request from client with target `%4s'\n",
2486 "SEND", GNUNET_i2s (&obm->peer));
2487#endif
2488 obmm = (const struct GNUNET_MessageHeader *) &obm[1];
2489 msize = ntohs (obmm->size);
2490 if (size != msize + sizeof (struct OutboundMessage))
2491 {
2492 GNUNET_break (0);
2493 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2494 return;
2495 }
2496 n = find_neighbour (&obm->peer);
2497 if (n == NULL)
2498 n = setup_new_neighbour (&obm->peer);
2499 tc = clients;
2500 while ((tc != NULL) && (tc->client != client))
2501 tc = tc->next;
2502
2503#if DEBUG_TRANSPORT
2504 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2505 "Client asked to transmit %u-byte message of type %u to `%4s'\n",
2506 ntohs (obmm->size),
2507 ntohs (obmm->type), GNUNET_i2s (&obm->peer));
2508#endif
2509 transmit_to_peer (tc, obmm, GNUNET_NO, n);
2510 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2511}
2512
2513
2514/**
2515 * Handle SET_QUOTA-message.
2516 *
2517 * @param cls closure (always NULL)
2518 * @param server the server handling the message
2519 * @param client identification of the client
2520 * @param message the actual message
2521 */
2522static void
2523handle_set_quota (void *cls,
2524 struct GNUNET_SERVER_Handle *server,
2525 struct GNUNET_SERVER_Client *client,
2526 const struct GNUNET_MessageHeader *message)
2527{
2528 const struct QuotaSetMessage *qsm =
2529 (const struct QuotaSetMessage *) message;
2530 struct NeighbourList *n;
2531 struct TransportPlugin *p;
2532 struct ReadyList *rl;
2533
2534#if DEBUG_TRANSPORT
2535 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2536 "Received `%s' request from client for peer `%4s'\n",
2537 "SET_QUOTA", GNUNET_i2s (&qsm->peer));
2538#endif
2539 n = find_neighbour (&qsm->peer);
2540 if (n == NULL)
2541 {
2542 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2543 return;
2544 }
2545 update_quota (n);
2546 if (n->quota_in < ntohl (qsm->quota_in))
2547 n->last_quota_update = GNUNET_TIME_absolute_get ();
2548 n->quota_in = ntohl (qsm->quota_in);
2549 rl = n->plugins;
2550 while (rl != NULL)
2551 {
2552 p = rl->plugin;
2553 p->api->set_receive_quota (p->api->cls,
2554 &qsm->peer, ntohl (qsm->quota_in));
2555 rl = rl->next;
2556 }
2557 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2558}
2559
2560
2561/**
2562 * Handle TRY_CONNECT-message.
2563 *
2564 * @param cls closure (always NULL)
2565 * @param server the server handling the message
2566 * @param client identification of the client
2567 * @param message the actual message
2568 */
2569static void
2570handle_try_connect (void *cls,
2571 struct GNUNET_SERVER_Handle *server,
2572 struct GNUNET_SERVER_Client *client,
2573 const struct GNUNET_MessageHeader *message)
2574{
2575 const struct TryConnectMessage *tcm;
2576
2577 tcm = (const struct TryConnectMessage *) message;
2578#if DEBUG_TRANSPORT
2579 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2580 "Received `%s' request from client asking to connect to `%4s'\n",
2581 "TRY_CONNECT", GNUNET_i2s (&tcm->peer));
2582#endif
2583 if (NULL == find_neighbour (&tcm->peer))
2584 setup_new_neighbour (&tcm->peer);
2585 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2586}
2587
2588
2589/**
2590 * List of handlers for the messages understood by this
2591 * service.
2592 */
2593static struct GNUNET_SERVER_MessageHandler handlers[] = {
2594 {&handle_start, NULL,
2595 GNUNET_MESSAGE_TYPE_TRANSPORT_START, 0},
2596 {&handle_hello, NULL,
2597 GNUNET_MESSAGE_TYPE_HELLO, 0},
2598 {&handle_send, NULL,
2599 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND, 0},
2600 {&handle_set_quota, NULL,
2601 GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA, sizeof (struct QuotaSetMessage)},
2602 {&handle_try_connect, NULL,
2603 GNUNET_MESSAGE_TYPE_TRANSPORT_TRY_CONNECT,
2604 sizeof (struct TryConnectMessage)},
2605 {NULL, NULL, 0, 0}
2606};
2607
2608
2609/**
2610 * Setup the environment for this plugin.
2611 */
2612static void
2613create_environment (struct TransportPlugin *plug)
2614{
2615 plug->env.cfg = cfg;
2616 plug->env.sched = sched;
2617 plug->env.my_public_key = &my_public_key;
2618 plug->env.cls = plug;
2619 plug->env.receive = &plugin_env_receive;
2620 plug->env.lookup = &plugin_env_lookup_address;
2621 plug->env.notify_address = &plugin_env_notify_address;
2622 plug->env.default_quota_in = default_quota_in;
2623 plug->env.max_connections = max_connect_per_transport;
2624}
2625
2626
2627/**
2628 * Start the specified transport (load the plugin).
2629 */
2630static void
2631start_transport (struct GNUNET_SERVER_Handle *server, const char *name)
2632{
2633 struct TransportPlugin *plug;
2634 char *libname;
2635
2636 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2637 _("Loading `%s' transport plugin\n"), name);
2638 GNUNET_asprintf (&libname, "libgnunet_plugin_transport_%s", name);
2639 plug = GNUNET_malloc (sizeof (struct TransportPlugin));
2640 create_environment (plug);
2641 plug->short_name = GNUNET_strdup (name);
2642 plug->lib_name = libname;
2643 plug->next = plugins;
2644 plugins = plug;
2645 plug->api = GNUNET_PLUGIN_load (libname, &plug->env);
2646 if (plug->api == NULL)
2647 {
2648 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2649 _("Failed to load transport plugin for `%s'\n"), name);
2650 GNUNET_free (plug->short_name);
2651 plugins = plug->next;
2652 GNUNET_free (libname);
2653 GNUNET_free (plug);
2654 }
2655}
2656
2657
2658/**
2659 * Called whenever a client is disconnected. Frees our
2660 * resources associated with that client.
2661 *
2662 * @param cls closure
2663 * @param client identification of the client
2664 */
2665static void
2666client_disconnect_notification (void *cls,
2667 struct GNUNET_SERVER_Client *client)
2668{
2669 struct TransportClient *pos;
2670 struct TransportClient *prev;
2671 struct ClientMessageQueueEntry *mqe;
2672
2673#if DEBUG_TRANSPORT
2674 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
2675 "Client disconnected, cleaning up.\n");
2676#endif
2677 prev = NULL;
2678 pos = clients;
2679 while ((pos != NULL) && (pos->client != client))
2680 {
2681 prev = pos;
2682 pos = pos->next;
2683 }
2684 if (pos == NULL)
2685 return;
2686 while (NULL != (mqe = pos->message_queue_head))
2687 {
2688 pos->message_queue_head = mqe->next;
2689 GNUNET_free (mqe);
2690 }
2691 pos->message_queue_head = NULL;
2692 if (prev == NULL)
2693 clients = pos->next;
2694 else
2695 prev->next = pos->next;
2696 if (GNUNET_YES == pos->tcs_pending)
2697 {
2698 pos->client = NULL;
2699 return;
2700 }
2701 GNUNET_free (pos);
2702}
2703
2704
2705/**
2706 * Initiate transport service.
2707 *
2708 * @param cls closure
2709 * @param s scheduler to use
2710 * @param serv the initialized server
2711 * @param c configuration to use
2712 */
2713static void
2714run (void *cls,
2715 struct GNUNET_SCHEDULER_Handle *s,
2716 struct GNUNET_SERVER_Handle *serv, struct GNUNET_CONFIGURATION_Handle *c)
2717{
2718 char *plugs;
2719 char *pos;
2720 int no_transports;
2721 unsigned long long qin;
2722 unsigned long long qout;
2723 unsigned long long tneigh;
2724 char *keyfile;
2725
2726 sched = s;
2727 cfg = c;
2728 /* parse configuration */
2729 if ((GNUNET_OK !=
2730 GNUNET_CONFIGURATION_get_value_number (c,
2731 "TRANSPORT",
2732 "DEFAULT_QUOTA_IN",
2733 &qin)) ||
2734 (GNUNET_OK !=
2735 GNUNET_CONFIGURATION_get_value_number (c,
2736 "TRANSPORT",
2737 "DEFAULT_QUOTA_OUT",
2738 &qout)) ||
2739 (GNUNET_OK !=
2740 GNUNET_CONFIGURATION_get_value_number (c,
2741 "TRANSPORT",
2742 "NEIGHBOUR_LIMIT",
2743 &tneigh)) ||
2744 (GNUNET_OK !=
2745 GNUNET_CONFIGURATION_get_value_filename (c,
2746 "GNUNETD",
2747 "HOSTKEY", &keyfile)))
2748 {
2749 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2750 _
2751 ("Transport service is lacking key configuration settings. Exiting.\n"));
2752 GNUNET_SCHEDULER_shutdown (s);
2753 return;
2754 }
2755 max_connect_per_transport = (uint32_t) tneigh;
2756 default_quota_in = (uint32_t) qin;
2757 default_quota_out = (uint32_t) qout;
2758 my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
2759 GNUNET_free (keyfile);
2760 if (my_private_key == NULL)
2761 {
2762 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2763 _
2764 ("Transport service could not access hostkey. Exiting.\n"));
2765 GNUNET_SCHEDULER_shutdown (s);
2766 return;
2767 }
2768 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
2769 GNUNET_CRYPTO_hash (&my_public_key,
2770 sizeof (my_public_key), &my_identity.hashPubKey);
2771 /* setup notification */
2772 server = serv;
2773 GNUNET_SERVER_disconnect_notify (server,
2774 &client_disconnect_notification, NULL);
2775 /* load plugins... */
2776 no_transports = 1;
2777 if (GNUNET_OK ==
2778 GNUNET_CONFIGURATION_get_value_string (c,
2779 "TRANSPORT", "PLUGINS", &plugs))
2780 {
2781 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2782 _("Starting transport plugins `%s'\n"), plugs);
2783 pos = strtok (plugs, " ");
2784 while (pos != NULL)
2785 {
2786 start_transport (server, pos);
2787 no_transports = 0;
2788 pos = strtok (NULL, " ");
2789 }
2790 GNUNET_free (plugs);
2791 }
2792 if (no_transports)
2793 refresh_hello ();
2794 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Transport service ready.\n"));
2795 /* process client requests */
2796 GNUNET_SERVER_add_handlers (server, handlers);
2797}
2798
2799
2800/**
2801 * Function called when the service shuts
2802 * down. Unloads our plugins.
2803 *
2804 * @param cls closure
2805 * @param cfg configuration to use
2806 */
2807static void
2808unload_plugins (void *cls, struct GNUNET_CONFIGURATION_Handle *cfg)
2809{
2810 struct TransportPlugin *plug;
2811 struct AddressList *al;
2812
2813#if DEBUG_TRANSPORT
2814 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2815 "Transport service is unloading plugins...\n");
2816#endif
2817 while (NULL != (plug = plugins))
2818 {
2819 plugins = plug->next;
2820 GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api));
2821 GNUNET_free (plug->lib_name);
2822 GNUNET_free (plug->short_name);
2823 while (NULL != (al = plug->addresses))
2824 {
2825 plug->addresses = al->next;
2826 GNUNET_free (al);
2827 }
2828 GNUNET_free (plug);
2829 }
2830 if (my_private_key != NULL)
2831 GNUNET_CRYPTO_rsa_key_free (my_private_key);
2832}
2833
2834
2835/**
2836 * The main function for the transport service.
2837 *
2838 * @param argc number of arguments from the command line
2839 * @param argv command line arguments
2840 * @return 0 ok, 1 on error
2841 */
2842int
2843main (int argc, char *const *argv)
2844{
2845 return (GNUNET_OK ==
2846 GNUNET_SERVICE_run (argc,
2847 argv,
2848 "transport",
2849 &run, NULL, &unload_plugins, NULL)) ? 0 : 1;
2850}
2851
2852/* end of gnunet-service-transport.c */
diff --git a/src/transport/gnunet-transport.c b/src/transport/gnunet-transport.c
new file mode 100644
index 000000000..52475e3eb
--- /dev/null
+++ b/src/transport/gnunet-transport.c
@@ -0,0 +1,42 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 server/gnunet-transport.c
23 * @brief Tool to help configure the transports.
24 * @author Christian Grothoff
25 *
26 * This utility can be used to test if a transport mechanism for
27 * GNUnet is properly configured.
28 */
29
30#include "platform.h"
31#include "gnunet_program_lib.h"
32#include "gnunet_protocols.h"
33#include "gnunet_transport_service.h"
34
35int
36main (int argc, char *const *argv)
37{
38 return 0;
39}
40
41
42/* end of gnunet-transport.c */
diff --git a/src/transport/plugin_transport.h b/src/transport/plugin_transport.h
new file mode 100644
index 000000000..57df9affe
--- /dev/null
+++ b/src/transport/plugin_transport.h
@@ -0,0 +1,468 @@
1/*
2 This file is part of GNUnet
3 (C) 2009 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 2, 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 transport/plugin_transport.h
23 * @brief API for the transport services. This header
24 * specifies the struct that is given to the plugin's entry
25 * method and the other struct that must be returned.
26 * Note that the destructors of transport plugins will
27 * be given the value returned by the constructor
28 * and is expected to return a NULL pointer.
29 *
30 * TODO:
31 * - consider moving DATA message (latency measurement)
32 * to service; avoids encapsulation overheads and
33 * would enable latency measurements for non-bidi
34 * transports.
35 * -
36 *
37 * @author Christian Grothoff
38 */
39#ifndef PLUGIN_TRANSPORT_H
40#define PLUGIN_TRANSPORT_H
41
42#include "gnunet_configuration_lib.h"
43#include "gnunet_scheduler_lib.h"
44#include "gnunet_transport_service.h"
45
46/**
47 * Opaque internal context for a particular peer of the transport
48 * service. Plugins will be given a pointer to this type and, if
49 * cheaply possible, should pass this pointer back to the transport
50 * service whenever additional messages from the same peer are
51 * received.
52 */
53struct ReadyList;
54
55/**
56 * Function called by the transport for each received message.
57 * This function should also be called with "NULL" for the
58 * message to signal that the other peer disconnected.
59 *
60 * @param cls closure
61 * @param plugin_context value to pass to this plugin
62 * to respond to the given peer (use is optional,
63 * but may speed up processing)
64 * @param service_context value passed to the transport-service
65 * to identify the neighbour; will be NULL on the first
66 * call for a given peer
67 * @param latency estimated latency for communicating with the
68 * given peer; should be set to GNUNET_TIME_UNIT_FOREVER_REL
69 * until the transport has seen messages transmitted in
70 * BOTH directions (and hence been able to do an actual
71 * round-trip observation); a non-FOREVER latency is also used
72 * by the transport to know that communication in both directions
73 * using this one plugin actually works
74 * @param peer (claimed) identity of the other peer
75 * @param message the message, NULL if peer was disconnected
76 * @return the new service_context that the plugin should use
77 * for future receive calls for messages from this
78 * particular peer
79 */
80typedef struct ReadyList *
81 (*GNUNET_TRANSPORT_PluginReceiveCallback) (void *cls,
82 void *plugin_context,
83 struct ReadyList *
84 service_context,
85 struct GNUNET_TIME_Relative
86 latency,
87 const struct GNUNET_PeerIdentity
88 * peer,
89 const struct GNUNET_MessageHeader
90 * message);
91
92
93/**
94 * Function that will be called for each address the transport
95 * is aware that it might be reachable under.
96 *
97 * @param cls closure
98 * @param name name of the transport that generated the address
99 * @param addr one of the addresses of the host, NULL for the last address
100 * the specific address format depends on the transport
101 * @param addrlen length of the address
102 * @param expires when should this address automatically expire?
103 */
104typedef void (*GNUNET_TRANSPORT_AddressNotification) (void *cls,
105 const char *name,
106 const void *addr,
107 size_t addrlen,
108 struct
109 GNUNET_TIME_Relative
110 expires);
111
112
113/**
114 * Function that will be called for each address obtained from the HELLO.
115 *
116 * @param cls closure
117 * @param name name of the transport that generated the address
118 * @param addr one of the addresses of the host, NULL for the last address
119 * the specific address format depends on the transport
120 * @param addrlen length of the address
121 */
122typedef void (*GNUNET_TRANSPORT_AddressCallback) (void *cls,
123 const char *name,
124 const void *addr,
125 size_t addrlen);
126
127
128/**
129 * Function that allows a transport to query the known
130 * network addresses for a given peer.
131 *
132 * @param cls closure
133 * @param timeout after how long should we time out?
134 * @param target which peer are we looking for?
135 * @param iter function to call for each known address
136 * @param iter_cls closure for iter
137 */
138typedef void (*GNUNET_TRANSPORT_LookupAddress) (void *cls,
139 struct GNUNET_TIME_Relative
140 timeout,
141 const struct
142 GNUNET_PeerIdentity * target,
143 GNUNET_TRANSPORT_AddressCallback
144 iter, void *iter_cls);
145
146
147/**
148 * The transport service will pass a pointer to a struct
149 * of this type as the first and only argument to the
150 * entry point of each transport plugin.
151 */
152struct GNUNET_TRANSPORT_PluginEnvironment
153{
154 /**
155 * Configuration to use.
156 */
157 struct GNUNET_CONFIGURATION_Handle *cfg;
158
159 /**
160 * Scheduler to use.
161 */
162 struct GNUNET_SCHEDULER_Handle *sched;
163
164 /**
165 * Our public key.
166 */
167 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *my_public_key;
168
169 /**
170 * Closure for the various callbacks.
171 */
172 void *cls;
173
174 /**
175 * Function that should be called by the transport plugin
176 * whenever a message is received.
177 */
178 GNUNET_TRANSPORT_PluginReceiveCallback receive;
179
180 /**
181 * Address lookup function.
182 */
183 GNUNET_TRANSPORT_LookupAddress lookup;
184
185 /**
186 * Function that must be called by each plugin to notify the
187 * transport service about the addresses under which the transport
188 * provided by the plugin can be reached.
189 */
190 GNUNET_TRANSPORT_AddressNotification notify_address;
191
192 /**
193 * What is the default quota (in terms of incoming bytes per
194 * ms) for new connections?
195 */
196 uint32_t default_quota_in;
197
198 /**
199 * What is the maximum number of connections that this transport
200 * should allow? Transports that do not have sessions (such as
201 * UDP) can ignore this value.
202 */
203 uint32_t max_connections;
204
205};
206
207
208/**
209 * Function that can be used by the transport service to transmit
210 * a message using the plugin using a fresh connection (even if
211 * we already have a connection to this peer, this function is
212 * required to establish a new one).
213 *
214 * @param cls closure
215 * @param target who should receive this message
216 * @param msg1 first message to transmit
217 * @param msg2 second message to transmit (can be NULL)
218 * @param timeout how long should we try to transmit these?
219 * @param addrlen length of the address
220 * @param addr the address
221 * @return session instance if the transmission has been scheduled
222 * NULL if the address format is invalid
223 */
224typedef void *
225 (*GNUNET_TRANSPORT_TransmitToAddressFunction) (void *cls,
226 const struct
227 GNUNET_PeerIdentity * target,
228 const struct
229 GNUNET_MessageHeader * msg1,
230 const struct
231 GNUNET_MessageHeader * msg2,
232 struct GNUNET_TIME_Relative
233 timeout, const void *addr,
234 size_t addrlen);
235
236/**
237 * Function called by the GNUNET_TRANSPORT_TransmitFunction
238 * upon "completion".
239 *
240 * @param cls closure
241 * @param service_context value passed to the transport-service
242 * to identify the neighbour
243 * @param target who was the recipient of the message?
244 * @param result GNUNET_OK on success
245 * GNUNET_SYSERR if the target disconnected;
246 * disconnect will ALSO be signalled using
247 * the ReceiveCallback.
248 */
249typedef void
250 (*GNUNET_TRANSPORT_TransmitContinuation) (void *cls,
251 struct ReadyList *
252 service_context,
253 const struct GNUNET_PeerIdentity *
254 target, int result);
255
256/**
257 * Function that can be used by the transport service to transmit
258 * a message using the plugin. Note that in the case of a
259 * peer disconnecting, the continuation MUST be called
260 * prior to the disconnect notification itself. This function
261 * will be called with this peer's HELLO message to initiate
262 * a fresh connection to another peer.
263 *
264 * @param cls closure
265 * @param plugin_context value we were asked to pass to this plugin
266 * to respond to the given peer (use is optional,
267 * but may speed up processing), can be NULL
268 * @param service_context value passed to the transport-service
269 * to identify the neighbour; NULL is used to indicate
270 * an urgent message. If the urgent message can not be
271 * scheduled for immediate transmission, the plugin is to
272 * call the continuation with failure immediately
273 * @param target who should receive this message
274 * @param msg the message to transmit
275 * @param timeout how long to wait at most for the transmission
276 * @param cont continuation to call once the message has
277 * been transmitted (or if the transport is ready
278 * for the next transmission call; or if the
279 * peer disconnected...); can be NULL
280 * @param cont_cls closure for cont
281 * @return plugin_context that should be used next time for
282 * sending messages to the specified peer
283 */
284typedef void *
285 (*GNUNET_TRANSPORT_TransmitFunction) (void *cls,
286 void *plugin_context,
287 struct ReadyList * service_context,
288 const struct GNUNET_PeerIdentity *
289 target,
290 const struct GNUNET_MessageHeader *
291 msg,
292 struct GNUNET_TIME_Relative timeout,
293 GNUNET_TRANSPORT_TransmitContinuation
294 cont, void *cont_cls);
295
296
297/**
298 * Function that can be called to force a disconnect from the
299 * specified neighbour. This should also cancel all previously
300 * scheduled transmissions. Obviously the transmission may have been
301 * partially completed already, which is OK. The plugin is supposed
302 * to close the connection (if applicable) and no longer call the
303 * transmit continuation(s).
304 *
305 * Finally, plugin MUST NOT call the services's receive function to
306 * notify the service that the connection to the specified target was
307 * closed after a getting this call.
308 *
309 * @param cls closure
310 * @param plugin_context value we were asked to pass to this plugin
311 * to respond to the given peer (use is optional,
312 * but may speed up processing), can be NULL (if
313 * NULL was returned from the transmit function)
314 * @param service_context must correspond to the service context
315 * of the corresponding Transmit call; the plugin should
316 * not cancel a send call made with a different service
317 * context pointer! Never NULL.
318 * @param target peer for which the last transmission is
319 * to be cancelled
320 */
321typedef void
322 (*GNUNET_TRANSPORT_CancelFunction) (void *cls,
323 void *plugin_context,
324 struct ReadyList * service_context,
325 const struct GNUNET_PeerIdentity *
326 target);
327
328
329/**
330 * Function called by the pretty printer for the resolved address for
331 * each human-readable address obtained.
332 *
333 * @param cls closure
334 * @param hostname one of the names for the host, NULL
335 * on the last call to the callback
336 */
337typedef void (*GNUNET_TRANSPORT_AddressStringCallback) (void *cls,
338 const char *address);
339
340
341/**
342 * Convert the transports address to a nice, human-readable
343 * format.
344 *
345 * @param cls closure
346 * @param name name of the transport that generated the address
347 * @param addr one of the addresses of the host, NULL for the last address
348 * the specific address format depends on the transport
349 * @param addrlen length of the address
350 * @param numeric should (IP) addresses be displayed in numeric form?
351 * @param timeout after how long should we give up?
352 * @param asc function to call on each string
353 * @param asc_cls closure for asc
354 */
355typedef void
356 (*GNUNET_TRANSPORT_AddressPrettyPrinter) (void *cls,
357 const char *type,
358 const void *addr,
359 size_t addrlen,
360 int numeric,
361 struct GNUNET_TIME_Relative
362 timeout,
363 GNUNET_TRANSPORT_AddressStringCallback
364 asc, void *asc_cls);
365
366
367/**
368 * Set a quota for receiving data from the given peer; this is a
369 * per-transport limit. The transport should limit its read/select
370 * calls to stay below the quota (in terms of incoming data).
371 *
372 * @param cls closure
373 * @param peer the peer for whom the quota is given
374 * @param quota_in quota for receiving/sending data in bytes per ms
375 */
376typedef void
377 (*GNUNET_TRANSPORT_SetQuota) (void *cls,
378 const struct GNUNET_PeerIdentity * target,
379 uint32_t quota_in);
380
381
382/**
383 * Another peer has suggested an address for this
384 * peer and transport plugin. Check that this could be a valid
385 * address. If so, consider adding it to the list
386 * of addresses.
387 *
388 * @param addr pointer to the address
389 * @param addrlen length of addr
390 * @return GNUNET_OK if this is a plausible address for this peer
391 * and transport
392 */
393typedef int
394 (*GNUNET_TRANSPORT_SuggestAddress) (void *cls,
395 const void *addr, size_t addrlen);
396
397/**
398 * Each plugin is required to return a pointer to a struct of this
399 * type as the return value from its entry point.
400 */
401struct GNUNET_TRANSPORT_PluginFunctions
402{
403
404 /**
405 * Closure for all of the callbacks.
406 */
407 void *cls;
408
409 /**
410 * Function used to send a single message to a particular
411 * peer using the specified address. Used to validate
412 * HELLOs.
413 */
414 GNUNET_TRANSPORT_TransmitToAddressFunction send_to;
415
416 /**
417 * Function that the transport service will use to transmit data to
418 * another peer. May be null for plugins that only support
419 * receiving data. After this call, the plugin call the specified
420 * continuation with success or error before notifying us about the
421 * target having disconnected.
422 */
423 GNUNET_TRANSPORT_TransmitFunction send;
424
425 /**
426 * Function that can be used to force the plugin to disconnect
427 * from the given peer and cancel all previous transmissions
428 * (and their continuationc).
429 */
430 GNUNET_TRANSPORT_CancelFunction cancel;
431
432 /**
433 * Function to pretty-print addresses. NOTE: this function is not
434 * yet used by transport-service, but will be used in the future
435 * once the transport-API has been completed.
436 */
437 GNUNET_TRANSPORT_AddressPrettyPrinter address_pretty_printer;
438
439 /**
440 * Function that the transport service can use to try to enforce a
441 * quota for the number of bytes received via this transport.
442 * Transports that can not refuse incoming data (such as UDP)
443 * are free to ignore these calls.
444 */
445 GNUNET_TRANSPORT_SetQuota set_receive_quota;
446
447 /**
448 * Function that will be called if another peer suggested that
449 * we should use a particular address (since he is reaching
450 * us at that address) for this transport.
451 */
452 GNUNET_TRANSPORT_SuggestAddress address_suggested;
453
454 /**
455 * Relative cost of this transport compared to others. This
456 * is supposed to be a static cost estimate which determines
457 * which plugins should not even be attempted if other,
458 * cheaper transports are already working. The idea is that
459 * the costs have roughly this relationship:
460 * <pre>
461 * TCP < UDP < HTTP == HTTPS < SMTP
462 * </pre>
463 */
464 unsigned int cost_estimate;
465};
466
467
468#endif
diff --git a/src/transport/plugin_transport_http.c b/src/transport/plugin_transport_http.c
new file mode 100644
index 000000000..eb69f4386
--- /dev/null
+++ b/src/transport/plugin_transport_http.c
@@ -0,0 +1,2085 @@
1/*
2 This file is part of GNUnet
3 (C) 2003, 2004, 2005, 2006, 2007, 2008 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 2, 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 transports/http.c
23 * @brief Implementation of the HTTP transport service
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_util.h"
29#include "gnunet_protocols.h"
30#include "gnunet_transport.h"
31#include "gnunet_stats_service.h"
32#include "gnunet_upnp_service.h"
33#include <stdint.h>
34#include <microhttpd.h>
35#include <curl/curl.h>
36#include "ip.h"
37
38#define DEBUG_HTTP GNUNET_NO
39
40/**
41 * Disable GET (for debugging only!). Must be GNUNET_YES
42 * in production use!
43 */
44#define DO_GET GNUNET_YES
45
46/**
47 * After how much time of the core not being associated with a http
48 * connection anymore do we close it?
49 *
50 * Needs to be larger than SECONDS_INACTIVE_DROP in
51 * core's connection.s
52 */
53#define HTTP_TIMEOUT (600 * GNUNET_CRON_SECONDS)
54
55/**
56 * How often do we re-issue GET requests?
57 */
58#define HTTP_GET_REFRESH (5 * GNUNET_CRON_SECONDS)
59
60/**
61 * Default maximum size of the HTTP read and write buffer.
62 */
63#define HTTP_BUF_SIZE (64 * 1024)
64
65/**
66 * Text of the response sent back after the last bytes of a PUT
67 * request have been received (just to formally obey the HTTP
68 * protocol).
69 */
70#define HTTP_PUT_RESPONSE "Thank you!"
71
72#define MY_TRANSPORT_NAME "HTTP"
73#include "common.c"
74
75/**
76 * Client-side data per PUT request.
77 */
78struct HTTPPutData
79{
80 /**
81 * This is a linked list.
82 */
83 struct HTTPPutData *next;
84
85 /**
86 * Handle to our CURL request.
87 */
88 CURL *curl_put;
89
90 /**
91 * Last time we made progress with the PUT.
92 */
93 GNUNET_CronTime last_activity;
94
95 /**
96 * The message we are sending.
97 */
98 char *msg;
99
100 /**
101 * Size of msg.
102 */
103 unsigned int size;
104
105 /**
106 * Current position in msg.
107 */
108 unsigned int pos;
109
110 /**
111 * Are we done sending? Set to 1 after we
112 * completed sending and started to receive
113 * a response ("Thank you!") or once the
114 * timeout has been reached.
115 */
116 int done;
117
118};
119
120/**
121 * Server-side data per PUT request.
122 */
123struct MHDPutData
124{
125 /**
126 * This is a linked list.
127 */
128 struct MHDPutData *next;
129
130 /**
131 * MHD connection handle for this request.
132 */
133 struct MHD_Connection *session;
134
135 /**
136 * Last time we received data on this PUT
137 * connection.
138 */
139 GNUNET_CronTime last_activity;
140
141 /**
142 * Read buffer for the header (from PUT)
143 */
144 char rbuff1[sizeof (GNUNET_MessageHeader)];
145
146 /**
147 * The read buffer (used only receiving PUT data).
148 */
149 char *rbuff2;
150
151 /**
152 * Number of valid bytes in rbuff1
153 */
154 unsigned int rpos1;
155
156 /**
157 * Number of valid bytes in rbuff2
158 */
159 unsigned int rpos2;
160
161
162 /**
163 * Size of the rbuff2 buffer.
164 */
165 unsigned int rsize2;
166
167 /**
168 * Should we sent a response for this PUT yet?
169 */
170 int ready;
171
172 /**
173 * Have we sent a response for this PUT yet?
174 */
175 int done;
176
177};
178
179/**
180 * Server-side data for a GET request.
181 */
182struct MHDGetData
183{
184
185 /**
186 * This is a linked list.
187 */
188 struct MHDGetData *next;
189
190 /**
191 * MHD connection handle for this request.
192 */
193 struct MHD_Connection *session;
194
195 /**
196 * GET session response handle
197 */
198 struct MHD_Response *get;
199
200 /**
201 * My HTTP session.
202 */
203 struct HTTPSession *httpsession;
204
205 /**
206 * The write buffer (for sending GET response)
207 */
208 char *wbuff;
209
210 /**
211 * What was the last time we were able to
212 * transmit data using the current get handle?
213 */
214 GNUNET_CronTime last_get_activity;
215
216 /**
217 * Current write position in wbuff
218 */
219 unsigned int woff;
220
221 /**
222 * Number of valid bytes in wbuff (starting at woff)
223 */
224 unsigned int wpos;
225
226 /**
227 * Size of the write buffer.
228 */
229 unsigned int wsize;
230
231};
232
233/**
234 * Transport Session handle.
235 */
236typedef struct HTTPSession
237{
238
239 /**
240 * GNUNET_TSession for this session.
241 */
242 GNUNET_TSession *tsession;
243
244 /**
245 * To whom are we talking to.
246 */
247 GNUNET_PeerIdentity sender;
248
249 /**
250 * number of users of this session
251 */
252 unsigned int users;
253
254 /**
255 * Has this session been destroyed?
256 */
257 int destroyed;
258
259 /**
260 * Are we client or server? Determines which of the
261 * structs in the union below is being used for this
262 * connection!
263 */
264 int is_client;
265
266 /**
267 * Is MHD still using this session handle?
268 */
269 int is_mhd_active;
270
271 /**
272 * Data maintained for the http client-server connection
273 * (depends on if we are client or server).
274 */
275 union
276 {
277
278 struct
279 {
280 /**
281 * Active PUT requests (linked list).
282 */
283 struct MHDPutData *puts;
284
285#if DO_GET
286 /**
287 * Active GET requests (linked list; most
288 * recent received GET is the head of the list).
289 */
290 struct MHDGetData *gets;
291#endif
292
293 } server;
294
295 struct
296 {
297
298 /**
299 * Address of the other peer.
300 */
301 HostAddress address;
302
303#if DO_GET
304 /**
305 * Last time the GET was active.
306 */
307 GNUNET_CronTime last_get_activity;
308
309 /**
310 * What was the last time we were able to
311 * transmit data using the current get handle?
312 */
313 GNUNET_CronTime last_get_initiated;
314
315 /**
316 * GET operation
317 */
318 CURL *get;
319
320 /**
321 * Read buffer for the header (from GET).
322 */
323 char rbuff1[sizeof (GNUNET_MessageHeader)];
324
325 /**
326 * The read buffer (used only receiving GET data).
327 */
328 char *rbuff2;
329
330 /**
331 * Number of valid bytes in rbuff1
332 */
333 unsigned int rpos1;
334
335 /**
336 * Number of valid bytes in rbuff2
337 */
338 unsigned int rpos2;
339
340 /**
341 * Current size of the read buffer rbuff2.
342 */
343 unsigned int rsize2;
344#endif
345
346 /**
347 * URL of the get and put operations.
348 */
349 char *url;
350
351 /**
352 * Linked list of PUT operations.
353 */
354 struct HTTPPutData *puts;
355
356 } client;
357
358 } cs;
359
360} HTTPSession;
361
362/* *********** globals ************* */
363
364static int stat_bytesReceived;
365
366static int stat_bytesSent;
367
368static int stat_bytesDropped;
369
370static int stat_get_issued;
371
372static int stat_get_received;
373
374static int stat_put_issued;
375
376static int stat_put_received;
377
378static int stat_select_calls;
379
380static int stat_send_calls;
381
382static int stat_connect_calls;
383
384static int stat_curl_send_callbacks;
385
386static int stat_curl_receive_callbacks;
387
388static int stat_mhd_access_callbacks;
389
390static int stat_mhd_read_callbacks;
391
392static int stat_mhd_close_callbacks;
393
394static int stat_connect_calls;
395
396/**
397 * How many requests do we have currently pending
398 * (with libcurl)?
399 */
400static unsigned int http_requests_pending;
401
402static int signal_pipe[2];
403
404static char *proxy;
405
406/**
407 * Daemon for listening for new connections.
408 */
409static struct MHD_Daemon *mhd_daemon;
410
411/**
412 * Curl multi for managing client operations.
413 */
414static CURLM *curl_multi;
415
416/**
417 * Set to GNUNET_YES while the transport is running.
418 */
419static int http_running;
420
421/**
422 * Thread running libcurl activities.
423 */
424static struct GNUNET_ThreadHandle *curl_thread;
425
426/**
427 * Array of currently active HTTP sessions.
428 */
429static GNUNET_TSession **tsessions;
430
431/**
432 * Number of valid entries in tsessions.
433 */
434static unsigned int tsessionCount;
435
436/**
437 * Sie of the tsessions array.
438 */
439static unsigned int tsessionArrayLength;
440
441/**
442 * Lock for concurrent access to all structures used
443 * by http, including CURL.
444 */
445static struct GNUNET_Mutex *lock;
446
447
448/**
449 * Signal select thread that its selector
450 * set may have changed.
451 */
452static void
453signal_select ()
454{
455 static char c;
456 WRITE (signal_pipe[1], &c, sizeof (c));
457}
458
459/**
460 * Check if we are allowed to connect to the given IP.
461 */
462static int
463acceptPolicyCallback (void *cls,
464 const struct sockaddr *addr, socklen_t addr_len)
465{
466 if (GNUNET_NO != is_rejected_tester (addr, addr_len))
467 return MHD_NO;
468 return MHD_YES;
469}
470
471/**
472 * Disconnect from a remote node. May only be called
473 * on sessions that were acquired by the caller first.
474 * For the core, aquiration means to call associate or
475 * connect. The number of disconnects must match the
476 * number of calls to connect+associate.
477 *
478 * Sessions are actually discarded in cleanup_connections.
479 *
480 *
481 * @param tsession the session that is closed
482 * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
483 */
484static int
485httpDisconnect (GNUNET_TSession * tsession)
486{
487 HTTPSession *httpsession = tsession->internal;
488 if (httpsession == NULL)
489 {
490 GNUNET_free (tsession);
491 return GNUNET_OK;
492 }
493 GNUNET_mutex_lock (lock);
494 httpsession->users--;
495 GNUNET_mutex_unlock (lock);
496 return GNUNET_OK;
497}
498
499static void
500destroy_tsession (GNUNET_TSession * tsession)
501{
502 HTTPSession *httpsession = tsession->internal;
503 struct HTTPPutData *pos;
504 struct HTTPPutData *next;
505#if DO_GET
506 struct MHDGetData *gpos;
507 struct MHDGetData *gnext;
508#endif
509 struct MHD_Response *r;
510 int i;
511
512 GNUNET_mutex_lock (lock);
513 for (i = 0; i < tsessionCount; i++)
514 {
515 if (tsessions[i] == tsession)
516 {
517 tsessions[i] = tsessions[--tsessionCount];
518 break;
519 }
520 }
521 if (httpsession->is_client)
522 {
523#if DO_GET
524 curl_multi_remove_handle (curl_multi, httpsession->cs.client.get);
525 http_requests_pending--;
526 signal_select ();
527 curl_easy_cleanup (httpsession->cs.client.get);
528 GNUNET_array_grow (httpsession->cs.client.rbuff2,
529 httpsession->cs.client.rsize2, 0);
530#endif
531 GNUNET_free_non_null (httpsession->cs.client.url);
532 pos = httpsession->cs.client.puts;
533 while (pos != NULL)
534 {
535 next = pos->next;
536 curl_multi_remove_handle (curl_multi, pos->curl_put);
537 http_requests_pending--;
538 signal_select ();
539 curl_easy_cleanup (pos->curl_put);
540 GNUNET_free (pos->msg);
541 GNUNET_free (pos);
542 pos = next;
543 }
544 GNUNET_free (httpsession);
545 GNUNET_free (tsession);
546 }
547 else
548 {
549 httpsession->destroyed = GNUNET_YES;
550 GNUNET_GE_BREAK (NULL, httpsession->cs.server.puts == NULL);
551#if DO_GET
552 gpos = httpsession->cs.server.gets;
553 while (gpos != NULL)
554 {
555 GNUNET_array_grow (gpos->wbuff, gpos->wsize, 0);
556 r = gpos->get;
557 gpos->get = NULL;
558 gnext = gpos->next;
559 MHD_destroy_response (r);
560 gpos = gnext;
561 }
562 httpsession->cs.server.gets = NULL;
563#endif
564 GNUNET_free (httpsession->tsession);
565 GNUNET_free (httpsession);
566 }
567 GNUNET_mutex_unlock (lock);
568}
569
570/**
571 * MHD is done handling a request. Cleanup
572 * the respective transport state.
573 */
574static void
575requestCompletedCallback (void *unused,
576 struct MHD_Connection *session,
577 void **httpSessionCache)
578{
579 HTTPSession *httpsession = *httpSessionCache;
580 struct MHDPutData *pprev;
581 struct MHDPutData *ppos;
582#if DO_GET
583 struct MHDGetData *gprev;
584 struct MHDGetData *gpos;
585#endif
586
587 if (stats != NULL)
588 stats->change (stat_mhd_close_callbacks, 1);
589 if (httpsession == NULL)
590 return; /* oops */
591 GNUNET_GE_ASSERT (NULL, !httpsession->is_client);
592 pprev = NULL;
593 ppos = httpsession->cs.server.puts;
594 while (ppos != NULL)
595 {
596 if (ppos->session == session)
597 {
598 ppos->last_activity = 0;
599 signal_select ();
600 return;
601 }
602 pprev = ppos;
603 ppos = ppos->next;
604 }
605#if DO_GET
606 gprev = NULL;
607 gpos = httpsession->cs.server.gets;
608 while (gpos != NULL)
609 {
610 if (gpos->session == session)
611 {
612 gpos->last_get_activity = 0;
613 signal_select ();
614 return;
615 }
616 gprev = gpos;
617 gpos = gpos->next;
618 }
619#endif
620 httpsession->is_mhd_active--;
621}
622
623/**
624 * A (core) Session is to be associated with a transport session. The
625 * transport service may want to know in order to call back on the
626 * core if the connection is being closed. Associate can also be
627 * called to test if it would be possible to associate the session
628 * later, in this case the argument session is NULL. This can be used
629 * to test if the connection must be closed by the core or if the core
630 * can assume that it is going to be self-managed (if associate
631 * returns GNUNET_OK and session was NULL, the transport layer is responsible
632 * for eventually freeing resources associated with the tesession). If
633 * session is not NULL, the core takes responsbility for eventually
634 * calling disconnect.
635 *
636 * @param tsession the session handle passed along
637 * from the call to receive that was made by the transport
638 * layer
639 * @return GNUNET_OK if the session could be associated,
640 * GNUNET_SYSERR if not.
641 */
642static int
643httpAssociate (GNUNET_TSession * tsession)
644{
645 HTTPSession *httpSession;
646
647 if (tsession == NULL)
648 {
649 GNUNET_GE_BREAK (NULL, 0);
650 return GNUNET_SYSERR;
651 }
652 httpSession = tsession->internal;
653 GNUNET_mutex_lock (lock);
654 if (httpSession->destroyed == GNUNET_YES)
655 {
656 GNUNET_mutex_unlock (lock);
657 return GNUNET_SYSERR;
658 }
659 httpSession->users++;
660 GNUNET_mutex_unlock (lock);
661 return GNUNET_OK;
662}
663
664/**
665 * Add a new session to the array watched by the select thread. Grows
666 * the array if needed. If the caller wants to do anything useful
667 * with the return value, it must have the lock before
668 * calling. It is ok to call this function without holding lock if
669 * the return value is ignored.
670 */
671static unsigned int
672addTSession (GNUNET_TSession * tsession)
673{
674 unsigned int i;
675
676 GNUNET_mutex_lock (lock);
677 if (tsessionCount == tsessionArrayLength)
678 GNUNET_array_grow (tsessions, tsessionArrayLength,
679 tsessionArrayLength * 2);
680 i = tsessionCount;
681 tsessions[tsessionCount++] = tsession;
682 GNUNET_mutex_unlock (lock);
683 return i;
684}
685
686#if DO_GET
687/**
688 * Callback for processing GET requests if our side is the
689 * MHD HTTP server.
690 *
691 * @param cls the HTTP session
692 * @param pos read-offset in the stream
693 * @param buf where to write the data
694 * @param max how much data to write (at most)
695 * @return number of bytes written, 0 is allowed!
696 */
697static int
698contentReaderCallback (void *cls, uint64_t pos, char *buf, int max)
699{
700 struct MHDGetData *mgd = cls;
701
702 if (stats != NULL)
703 stats->change (stat_mhd_read_callbacks, 1);
704 GNUNET_mutex_lock (lock);
705 if (mgd->wpos < max)
706 max = mgd->wpos;
707 memcpy (buf, &mgd->wbuff[mgd->woff], max);
708 mgd->wpos -= max;
709 mgd->woff += max;
710 if (max > 0)
711 mgd->last_get_activity = GNUNET_get_time ();
712 if (mgd->wpos == 0)
713 mgd->woff = 0;
714 GNUNET_mutex_unlock (lock);
715#if DEBUG_HTTP
716 GNUNET_GE_LOG (coreAPI->ectx,
717 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
718 "HTTP returns %u bytes in MHD's GET handler.\n", max);
719#endif
720 if (stats != NULL)
721 stats->change (stat_bytesSent, max);
722 if ((max == 0) && (mgd->httpsession->cs.server.gets != mgd))
723 return -1; /* end of response (another GET replaces this one) */
724 return max;
725}
726#endif
727
728#if DO_GET
729/**
730 * Notification that libmicrohttpd no longer needs the
731 * response object.
732 */
733static void
734contentReaderFreeCallback (void *cls)
735{
736 struct MHDGetData *mgd = cls;
737
738 GNUNET_GE_ASSERT (NULL, mgd->get == NULL);
739 GNUNET_array_grow (mgd->wbuff, mgd->wsize, 0);
740 GNUNET_free (mgd);
741}
742#endif
743
744/**
745 * Process GET or PUT request received via MHD. For
746 * GET, queue response that will send back our pending
747 * messages. For PUT, process incoming data and send
748 * to GNUnet core. In either case, check if a session
749 * already exists and create a new one if not.
750 */
751static int
752accessHandlerCallback (void *cls,
753 struct MHD_Connection *session,
754 const char *url,
755 const char *method,
756 const char *version,
757 const char *upload_data,
758 size_t * upload_data_size, void **httpSessionCache)
759{
760 GNUNET_TSession *tsession;
761 struct MHDPutData *put;
762 struct MHDGetData *get;
763 HTTPSession *httpSession;
764 struct MHD_Response *response;
765 GNUNET_HashCode client;
766 int i;
767 unsigned int have;
768 GNUNET_MessageHeader *hdr;
769 GNUNET_TransportPacket *mp;
770 unsigned int cpy;
771 unsigned int poff;
772
773 if (stats != NULL)
774 stats->change (stat_mhd_access_callbacks, 1);
775#if DEBUG_HTTP
776 GNUNET_GE_LOG (coreAPI->ectx,
777 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
778 "HTTP/MHD receives `%s' request.\n", method);
779#endif
780 /* convert URL to sender peer id */
781 if ((strlen (url) < 2)
782 || (GNUNET_OK != GNUNET_enc_to_hash (&url[1], &client)))
783 {
784 /* invalid request */
785 /* GNUNET_GE_BREAK_OP (NULL, 0); -- this happens a lot, most likely
786 somebody scanning for MyDoom.X-opened backdoors */
787 return MHD_NO;
788 }
789
790 /* check if we already have a session for this */
791 httpSession = *httpSessionCache;
792 if (httpSession == NULL)
793 {
794 /* new http connection */
795 if (stats != NULL)
796 {
797 if (0 == strcasecmp (MHD_HTTP_METHOD_PUT, method))
798 stats->change (stat_put_received, 1);
799 else
800 stats->change (stat_get_received, 1);
801 }
802 GNUNET_mutex_lock (lock);
803 for (i = 0; i < tsessionCount; i++)
804 {
805 tsession = tsessions[i];
806 httpSession = tsession->internal;
807 if ((0 ==
808 memcmp (&httpSession->sender, &client,
809 sizeof (GNUNET_HashCode)))
810 && (httpSession->is_client == GNUNET_NO))
811 break;
812 tsession = NULL;
813 httpSession = NULL;
814 }
815 GNUNET_mutex_unlock (lock);
816 }
817 /* create new session if necessary */
818 if (httpSession == NULL)
819 {
820#if DEBUG_HTTP
821 GNUNET_GE_LOG (coreAPI->ectx,
822 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
823 "HTTP/MHD creates new session for request from `%s'.\n",
824 &url[1]);
825#endif
826 httpSession = GNUNET_malloc (sizeof (HTTPSession));
827 memset (httpSession, 0, sizeof (HTTPSession));
828 httpSession->sender.hashPubKey = client;
829 httpSession->users = 0; /* MHD */
830 tsession = GNUNET_malloc (sizeof (GNUNET_TSession));
831 memset (tsession, 0, sizeof (GNUNET_TSession));
832 tsession->ttype = GNUNET_TRANSPORT_PROTOCOL_NUMBER_HTTP;
833 tsession->internal = httpSession;
834 tsession->peer.hashPubKey = client;
835 httpSession->tsession = tsession;
836 addTSession (tsession);
837 }
838 if (*httpSessionCache == NULL)
839 {
840 httpSession->is_mhd_active++;
841 *httpSessionCache = httpSession;
842 }
843 GNUNET_mutex_lock (lock);
844#if DO_GET
845 if (0 == strcasecmp (MHD_HTTP_METHOD_GET, method))
846 {
847#if DEBUG_HTTP
848 GNUNET_GE_LOG (coreAPI->ectx,
849 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
850 "HTTP/MHD receives GET request from `%s'.\n", &url[1]);
851#endif
852
853 /* handle get; create response object if we do not
854 have one already */
855 get = GNUNET_malloc (sizeof (struct MHDGetData));
856 memset (get, 0, sizeof (struct MHDGetData));
857 get->next = httpSession->cs.server.gets;
858 httpSession->cs.server.gets = get;
859 get->session = session;
860 get->httpsession = httpSession;
861 get->last_get_activity = GNUNET_get_time ();
862 get->get = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
863 64 * 1024,
864 contentReaderCallback,
865 get,
866 contentReaderFreeCallback);
867 MHD_queue_response (session, MHD_HTTP_OK, get->get);
868 GNUNET_mutex_unlock (lock);
869 return MHD_YES;
870 }
871#endif
872 if (0 == strcasecmp (MHD_HTTP_METHOD_PUT, method))
873 {
874#if DEBUG_HTTP
875 GNUNET_GE_LOG (coreAPI->ectx,
876 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
877 "HTTP/MHD receives PUT request from `%s' with %u bytes.\n",
878 &url[1], *upload_data_size);
879#endif
880 put = httpSession->cs.server.puts;
881 while ((put != NULL) && (put->session != session))
882 put = put->next;
883 if (put == NULL)
884 {
885 put = GNUNET_malloc (sizeof (struct MHDPutData));
886 memset (put, 0, sizeof (struct MHDPutData));
887 put->next = httpSession->cs.server.puts;
888 httpSession->cs.server.puts = put;
889 put->session = session;
890 }
891 put->last_activity = GNUNET_get_time ();
892
893 /* handle put (upload_data!) */
894 poff = 0;
895 have = *upload_data_size;
896 if (stats != NULL)
897 stats->change (stat_bytesReceived, have);
898 *upload_data_size = 0; /* we will always process everything */
899 if ((have == 0) && (put->done == GNUNET_NO)
900 && (put->ready == GNUNET_YES))
901 {
902 put->done = GNUNET_YES;
903 /* end of upload, send response! */
904#if DEBUG_HTTP
905 GNUNET_GE_LOG (coreAPI->ectx,
906 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
907 "HTTP/MHD queues dummy response to completed PUT request.\n");
908#endif
909 response =
910 MHD_create_response_from_data (strlen (HTTP_PUT_RESPONSE),
911 HTTP_PUT_RESPONSE, MHD_NO, MHD_NO);
912 MHD_queue_response (session, MHD_HTTP_OK, response);
913 MHD_destroy_response (response);
914 GNUNET_mutex_unlock (lock);
915 return MHD_YES;
916 }
917 while (have > 0)
918 {
919 put->ready = GNUNET_NO;
920 if (put->rpos1 < sizeof (GNUNET_MessageHeader))
921 {
922 cpy = sizeof (GNUNET_MessageHeader) - put->rpos1;
923 if (cpy > have)
924 cpy = have;
925 memcpy (&put->rbuff1[put->rpos1], &upload_data[poff], cpy);
926 put->rpos1 += cpy;
927 have -= cpy;
928 poff += cpy;
929 put->rpos2 = 0;
930 }
931 if (put->rpos1 < sizeof (GNUNET_MessageHeader))
932 break;
933 hdr = (GNUNET_MessageHeader *) put->rbuff1;
934 GNUNET_array_grow (put->rbuff2,
935 put->rsize2,
936 ntohs (hdr->size) -
937 sizeof (GNUNET_MessageHeader));
938 if (put->rpos2 < ntohs (hdr->size) - sizeof (GNUNET_MessageHeader))
939 {
940 cpy =
941 ntohs (hdr->size) - sizeof (GNUNET_MessageHeader) -
942 put->rpos2;
943 if (cpy > have)
944 cpy = have;
945 memcpy (&put->rbuff2[put->rpos2], &upload_data[poff], cpy);
946 have -= cpy;
947 poff += cpy;
948 put->rpos2 += cpy;
949 }
950 if (put->rpos2 < ntohs (hdr->size) - sizeof (GNUNET_MessageHeader))
951 break;
952 mp = GNUNET_malloc (sizeof (GNUNET_TransportPacket));
953 mp->msg = put->rbuff2;
954 mp->sender = httpSession->sender;
955 mp->tsession = httpSession->tsession;
956 mp->size = ntohs (hdr->size) - sizeof (GNUNET_MessageHeader);
957#if DEBUG_HTTP
958 GNUNET_GE_LOG (coreAPI->ectx,
959 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
960 "HTTP/MHD passes %u bytes to core (received via PUT request).\n",
961 mp->size);
962#endif
963 coreAPI->receive (mp);
964 put->rbuff2 = NULL;
965 put->rpos2 = 0;
966 put->rsize2 = 0;
967 put->rpos1 = 0;
968 put->ready = GNUNET_YES;
969 }
970 GNUNET_mutex_unlock (lock);
971 return MHD_YES;
972 }
973 GNUNET_mutex_unlock (lock);
974 GNUNET_GE_BREAK_OP (NULL, 0); /* invalid request */
975 return MHD_NO;
976}
977
978#if DO_GET
979/**
980 * Process downloaded bits (from GET via CURL).
981 */
982static size_t
983receiveContentCallback (void *ptr, size_t size, size_t nmemb, void *ctx)
984{
985 HTTPSession *httpSession = ctx;
986 const char *inbuf = ptr;
987 size_t have = size * nmemb;
988 size_t poff = 0;
989 size_t cpy;
990 GNUNET_MessageHeader *hdr;
991 GNUNET_TransportPacket *mp;
992
993 if (stats != NULL)
994 stats->change (stat_curl_receive_callbacks, 1);
995 httpSession->cs.client.last_get_activity = GNUNET_get_time ();
996#if DEBUG_HTTP
997 GNUNET_GE_LOG (coreAPI->ectx,
998 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
999 "HTTP/CURL receives %u bytes as response to GET.\n",
1000 size * nmemb);
1001#endif
1002 while (have > 0)
1003 {
1004 if (httpSession->cs.client.rpos1 < sizeof (GNUNET_MessageHeader))
1005 {
1006 cpy = sizeof (GNUNET_MessageHeader) - httpSession->cs.client.rpos1;
1007 if (cpy > have)
1008 cpy = have;
1009 memcpy (&httpSession->cs.client.
1010 rbuff1[httpSession->cs.client.rpos1], &inbuf[poff], cpy);
1011 httpSession->cs.client.rpos1 += cpy;
1012 have -= cpy;
1013 poff += cpy;
1014 httpSession->cs.client.rpos2 = 0;
1015 }
1016 if (httpSession->cs.client.rpos1 < sizeof (GNUNET_MessageHeader))
1017 break;
1018 hdr = (GNUNET_MessageHeader *) httpSession->cs.client.rbuff1;
1019 GNUNET_array_grow (httpSession->cs.client.rbuff2,
1020 httpSession->cs.client.rsize2,
1021 ntohs (hdr->size) - sizeof (GNUNET_MessageHeader));
1022 if (httpSession->cs.client.rpos2 <
1023 ntohs (hdr->size) - sizeof (GNUNET_MessageHeader))
1024 {
1025 cpy =
1026 ntohs (hdr->size) - sizeof (GNUNET_MessageHeader) -
1027 httpSession->cs.client.rpos2;
1028 if (cpy > have)
1029 cpy = have;
1030 memcpy (&httpSession->cs.client.
1031 rbuff2[httpSession->cs.client.rpos2], &inbuf[poff], cpy);
1032 have -= cpy;
1033 poff += cpy;
1034 httpSession->cs.client.rpos2 += cpy;
1035 }
1036 if (httpSession->cs.client.rpos2 <
1037 ntohs (hdr->size) - sizeof (GNUNET_MessageHeader))
1038 break;
1039 mp = GNUNET_malloc (sizeof (GNUNET_TransportPacket));
1040 mp->msg = httpSession->cs.client.rbuff2;
1041 mp->sender = httpSession->sender;
1042 mp->tsession = httpSession->tsession;
1043 mp->size = ntohs (hdr->size) - sizeof (GNUNET_MessageHeader);
1044 coreAPI->receive (mp);
1045 httpSession->cs.client.rbuff2 = NULL;
1046 httpSession->cs.client.rpos2 = 0;
1047 httpSession->cs.client.rsize2 = 0;
1048 httpSession->cs.client.rpos1 = 0;
1049 }
1050 if (stats != NULL)
1051 stats->change (stat_bytesReceived, size * nmemb);
1052 return size * nmemb;
1053}
1054#endif
1055
1056/**
1057 * Provide bits for upload: we're using CURL for a PUT request
1058 * and now need to provide data from the message we are transmitting.
1059 */
1060static size_t
1061sendContentCallback (void *ptr, size_t size, size_t nmemb, void *ctx)
1062{
1063 struct HTTPPutData *put = ctx;
1064 size_t max = size * nmemb;
1065
1066 if (stats != NULL)
1067 stats->change (stat_curl_send_callbacks, 1);
1068 put->last_activity = GNUNET_get_time ();
1069 if (max > put->size - put->pos)
1070 max = put->size - put->pos;
1071 memcpy (ptr, &put->msg[put->pos], max);
1072 put->pos += max;
1073#if DEBUG_HTTP
1074 GNUNET_GE_LOG (coreAPI->ectx,
1075 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
1076 "HTTP/CURL sends %u bytes in PUT request.\n", max);
1077#endif
1078 if (stats != NULL)
1079 stats->change (stat_bytesSent, max);
1080 return max;
1081}
1082
1083#define CURL_EASY_SETOPT(c, a, b) do { ret = curl_easy_setopt(c, a, b); if (ret != CURLE_OK) GNUNET_GE_LOG(coreAPI->ectx, GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK, _("%s failed at %s:%d: `%s'\n"), "curl_easy_setopt", __FILE__, __LINE__, curl_easy_strerror(ret)); } while (0);
1084#define IP_BUF_LEN 128
1085
1086static void
1087create_session_url (HTTPSession * httpSession)
1088{
1089 char buf[IP_BUF_LEN];
1090 char *url;
1091 GNUNET_EncName enc;
1092 unsigned short available;
1093 const char *obr;
1094 const char *cbr;
1095 const HostAddress *haddr =
1096 (const HostAddress *) &httpSession->cs.client.address;
1097
1098 url = httpSession->cs.client.url;
1099 if (url == NULL)
1100 {
1101 GNUNET_hash_to_enc (&coreAPI->my_identity->hashPubKey, &enc);
1102 available = ntohs (haddr->availability) & available_protocols;
1103 if (available == (VERSION_AVAILABLE_IPV4 | VERSION_AVAILABLE_IPV6))
1104 {
1105 if (GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 2) == 0)
1106 available = VERSION_AVAILABLE_IPV4;
1107 else
1108 available = VERSION_AVAILABLE_IPV6;
1109 }
1110 if ((available & VERSION_AVAILABLE_IPV4) > 0)
1111 {
1112 if (NULL == inet_ntop (AF_INET, &haddr->ipv4, buf, IP_BUF_LEN))
1113 {
1114 /* log? */
1115 return;
1116 }
1117 obr = "";
1118 cbr = "";
1119 }
1120 else if ((available & VERSION_AVAILABLE_IPV6) > 0)
1121 {
1122 if (NULL == inet_ntop (AF_INET6, &haddr->ipv6, buf, IP_BUF_LEN))
1123 {
1124 /* log? */
1125 return;
1126 }
1127 obr = "[";
1128 cbr = "]";
1129 }
1130 else
1131 return; /* error */
1132 url = GNUNET_malloc (64 + sizeof (GNUNET_EncName) + strlen (buf));
1133 GNUNET_snprintf (url,
1134 64 + sizeof (GNUNET_EncName),
1135 "http://%s%s%s:%u/%s", obr, buf, cbr,
1136 ntohs (haddr->port), &enc);
1137 httpSession->cs.client.url = url;
1138 }
1139}
1140
1141#if DO_GET
1142/**
1143 * Try to do a GET on the other peer of the given
1144 * http session.
1145 *
1146 * @return GNUNET_OK on success, GNUNET_SYSERR on error
1147 */
1148static int
1149create_curl_get (HTTPSession * httpSession)
1150{
1151 CURL *curl_get;
1152 CURLcode ret;
1153 CURLMcode mret;
1154 GNUNET_CronTime now;
1155
1156 if (httpSession->cs.client.url == NULL)
1157 return GNUNET_SYSERR;
1158 curl_get = httpSession->cs.client.get;
1159 if (curl_get != NULL)
1160 {
1161 GNUNET_mutex_lock (lock);
1162 curl_multi_remove_handle (curl_multi, curl_get);
1163 http_requests_pending--;
1164 signal_select ();
1165 curl_easy_cleanup (curl_get);
1166 GNUNET_mutex_unlock (lock);
1167 httpSession->cs.client.get = NULL;
1168 }
1169 curl_get = curl_easy_init ();
1170 if (curl_get == NULL)
1171 return GNUNET_SYSERR;
1172 /* create GET */
1173 CURL_EASY_SETOPT (curl_get, CURLOPT_FAILONERROR, 1);
1174 CURL_EASY_SETOPT (curl_get, CURLOPT_URL, httpSession->cs.client.url);
1175 if (strlen (proxy) > 0)
1176 CURL_EASY_SETOPT (curl_get, CURLOPT_PROXY, proxy);
1177 CURL_EASY_SETOPT (curl_get, CURLOPT_BUFFERSIZE, 32 * 1024);
1178 if (0 == strncmp (httpSession->cs.client.url, "http", 4))
1179 CURL_EASY_SETOPT (curl_get, CURLOPT_USERAGENT, "GNUnet-http");
1180#if 0
1181 CURL_EASY_SETOPT (curl_get, CURLOPT_VERBOSE, 1);
1182#endif
1183 CURL_EASY_SETOPT (curl_get, CURLOPT_CONNECTTIMEOUT, 150L);
1184 /* NOTE: use of CONNECTTIMEOUT without also
1185 setting NOSIGNAL results in really weird
1186 crashes on my system! */
1187 CURL_EASY_SETOPT (curl_get, CURLOPT_NOSIGNAL, 1);
1188 CURL_EASY_SETOPT (curl_get, CURLOPT_TIMEOUT, 150L);
1189 CURL_EASY_SETOPT (curl_get, CURLOPT_WRITEFUNCTION, &receiveContentCallback);
1190 CURL_EASY_SETOPT (curl_get, CURLOPT_WRITEDATA, httpSession);
1191 CURL_EASY_SETOPT (curl_get, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
1192 if (ret != CURLE_OK)
1193 {
1194 curl_easy_cleanup (curl_get);
1195 return GNUNET_SYSERR;
1196 }
1197 GNUNET_mutex_lock (lock);
1198 mret = curl_multi_add_handle (curl_multi, curl_get);
1199 http_requests_pending++;
1200 GNUNET_mutex_unlock (lock);
1201 if (stats != NULL)
1202 stats->change (stat_get_issued, 1);
1203 if (mret != CURLM_OK)
1204 {
1205 GNUNET_GE_LOG (coreAPI->ectx,
1206 GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER |
1207 GNUNET_GE_BULK, _("%s failed at %s:%d: `%s'\n"),
1208 "curl_multi_add_handle", __FILE__, __LINE__,
1209 curl_multi_strerror (mret));
1210 curl_easy_cleanup (curl_get);
1211 return GNUNET_SYSERR;
1212 }
1213 signal_select ();
1214 now = GNUNET_get_time ();
1215 httpSession->cs.client.last_get_activity = now;
1216 httpSession->cs.client.get = curl_get;
1217 httpSession->cs.client.last_get_initiated = now;
1218#if DEBUG_HTTP
1219 GNUNET_GE_LOG (coreAPI->ectx,
1220 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
1221 "HTTP/CURL initiated GET request.\n");
1222#endif
1223 return GNUNET_OK;
1224}
1225#endif
1226
1227/**
1228 * Establish a connection to a remote node.
1229 *
1230 * @param hello the hello-Message for the target node
1231 * @param tsessionPtr the session handle that is set
1232 * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
1233 */
1234static int
1235httpConnect (const GNUNET_MessageHello * hello,
1236 GNUNET_TSession ** tsessionPtr, int may_reuse)
1237{
1238 const HostAddress *haddr = (const HostAddress *) &hello[1];
1239 GNUNET_TSession *tsession;
1240 HTTPSession *httpSession;
1241 int i;
1242
1243 if (stats != NULL)
1244 stats->change (stat_connect_calls, 1);
1245 /* check if we have a session pending for this peer */
1246 tsession = NULL;
1247 if (may_reuse)
1248 {
1249 GNUNET_mutex_lock (lock);
1250 for (i = 0; i < tsessionCount; i++)
1251 {
1252 if (0 == memcmp (&hello->senderIdentity,
1253 &tsessions[i]->peer, sizeof (GNUNET_PeerIdentity)))
1254 {
1255 tsession = tsessions[i];
1256 break;
1257 }
1258 }
1259 if ((tsession != NULL) && (GNUNET_OK == httpAssociate (tsession)))
1260 {
1261 *tsessionPtr = tsession;
1262 GNUNET_mutex_unlock (lock);
1263 return GNUNET_OK;
1264 }
1265 GNUNET_mutex_unlock (lock);
1266 }
1267 /* no session pending, initiate a new one! */
1268 httpSession = GNUNET_malloc (sizeof (HTTPSession));
1269 memset (httpSession, 0, sizeof (HTTPSession));
1270 httpSession->sender = hello->senderIdentity;
1271 httpSession->users = 1; /* us only, core has not seen this tsession! */
1272 httpSession->is_client = GNUNET_YES;
1273 httpSession->cs.client.address = *haddr;
1274 tsession = GNUNET_malloc (sizeof (GNUNET_TSession));
1275 memset (tsession, 0, sizeof (GNUNET_TSession));
1276 httpSession->tsession = tsession;
1277 tsession->ttype = GNUNET_TRANSPORT_PROTOCOL_NUMBER_HTTP;
1278 tsession->internal = httpSession;
1279 tsession->peer = hello->senderIdentity;
1280 create_session_url (httpSession);
1281#if DO_GET
1282 if (GNUNET_OK != create_curl_get (httpSession))
1283 {
1284 GNUNET_free (tsession);
1285 GNUNET_free (httpSession);
1286 return GNUNET_SYSERR;
1287 }
1288#endif
1289 /* PUTs will be created as needed */
1290 addTSession (tsession);
1291 *tsessionPtr = tsession;
1292#if DEBUG_HTTP
1293 GNUNET_GE_LOG (coreAPI->ectx,
1294 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
1295 "HTTP/CURL initiated connection to `%s'.\n",
1296 httpSession->cs.client.url);
1297#endif
1298 return GNUNET_OK;
1299}
1300
1301/**
1302 * We received the "Thank you!" response to a PUT.
1303 * Discard the data (not useful) and mark the PUT
1304 * operation as completed.
1305 */
1306static size_t
1307discardContentCallback (void *data, size_t size, size_t nmemb, void *put_cls)
1308{
1309 struct HTTPPutData *put = put_cls;
1310 /* this condition should pretty much always be
1311 true; just checking here in case the PUT
1312 response comes early somehow */
1313 if (put->pos == put->size)
1314 put->done = GNUNET_YES;
1315 return size * nmemb;
1316}
1317
1318/**
1319 * Create a new PUT request for the given PUT data.
1320 */
1321static int
1322create_curl_put (HTTPSession * httpSession, struct HTTPPutData *put)
1323{
1324 CURL *curl_put;
1325 CURLcode ret;
1326 CURLMcode mret;
1327 long size;
1328
1329 /* we should have initiated a GET earlier,
1330 so URL must not be NULL here */
1331 if (httpSession->cs.client.url == NULL)
1332 return GNUNET_SYSERR;
1333 curl_put = curl_easy_init ();
1334 if (curl_put == NULL)
1335 return GNUNET_SYSERR;
1336 CURL_EASY_SETOPT (curl_put, CURLOPT_FAILONERROR, 1);
1337 CURL_EASY_SETOPT (curl_put, CURLOPT_URL, httpSession->cs.client.url);
1338 if (strlen (proxy) > 0)
1339 CURL_EASY_SETOPT (curl_put, CURLOPT_PROXY, proxy);
1340 CURL_EASY_SETOPT (curl_put, CURLOPT_BUFFERSIZE, put->size);
1341 if (0 == strncmp (httpSession->cs.client.url, "http", 4))
1342 CURL_EASY_SETOPT (curl_put, CURLOPT_USERAGENT, "GNUnet-http");
1343 CURL_EASY_SETOPT (curl_put, CURLOPT_UPLOAD, 1);
1344#if 0
1345 CURL_EASY_SETOPT (curl_put, CURLOPT_VERBOSE, 1);
1346#endif
1347 CURL_EASY_SETOPT (curl_put, CURLOPT_CONNECTTIMEOUT, 150L);
1348 /* NOTE: use of CONNECTTIMEOUT without also
1349 setting NOSIGNAL results in really weird
1350 crashes on my system! */
1351 CURL_EASY_SETOPT (curl_put, CURLOPT_NOSIGNAL, 1);
1352 CURL_EASY_SETOPT (curl_put, CURLOPT_TIMEOUT, 150L);
1353 size = put->size;
1354 CURL_EASY_SETOPT (curl_put, CURLOPT_INFILESIZE, size);
1355 CURL_EASY_SETOPT (curl_put, CURLOPT_READFUNCTION, &sendContentCallback);
1356 CURL_EASY_SETOPT (curl_put, CURLOPT_READDATA, put);
1357 CURL_EASY_SETOPT (curl_put, CURLOPT_WRITEFUNCTION, &discardContentCallback);
1358 CURL_EASY_SETOPT (curl_put, CURLOPT_WRITEDATA, put);
1359 CURL_EASY_SETOPT (curl_put, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
1360 if (ret != CURLE_OK)
1361 {
1362 curl_easy_cleanup (curl_put);
1363 return GNUNET_SYSERR;
1364 }
1365 GNUNET_mutex_lock (lock);
1366 mret = curl_multi_add_handle (curl_multi, curl_put);
1367 http_requests_pending++;
1368 GNUNET_mutex_unlock (lock);
1369 if (stats != NULL)
1370 stats->change (stat_put_issued, 1);
1371 if (mret != CURLM_OK)
1372 {
1373 GNUNET_GE_LOG (coreAPI->ectx,
1374 GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER |
1375 GNUNET_GE_BULK, _("%s failed at %s:%d: `%s'\n"),
1376 "curl_multi_add_handle", __FILE__, __LINE__,
1377 curl_multi_strerror (mret));
1378 return GNUNET_SYSERR;
1379 }
1380 signal_select ();
1381 put->curl_put = curl_put;
1382#if DEBUG_HTTP
1383 GNUNET_GE_LOG (coreAPI->ectx,
1384 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
1385 "HTTP/CURL initiated PUT request to `%s'.\n",
1386 httpSession->cs.client.url);
1387#endif
1388 return GNUNET_OK;
1389}
1390
1391
1392/**
1393 * Test if the transport would even try to send
1394 * a message of the given size and importance
1395 * for the given session.<br>
1396 * This function is used to check if the core should
1397 * even bother to construct (and encrypt) this kind
1398 * of message.
1399 *
1400 * @return GNUNET_YES if the transport would try (i.e. queue
1401 * the message or call the OS to send),
1402 * GNUNET_NO if the transport would just drop the message,
1403 * GNUNET_SYSERR if the size/session is invalid
1404 */
1405static int
1406httpTestWouldTry (GNUNET_TSession * tsession, const unsigned int size,
1407 int important)
1408{
1409 HTTPSession *httpSession = tsession->internal;
1410 struct MHDGetData *get;
1411 int ret;
1412
1413 if (size >= GNUNET_MAX_BUFFER_SIZE - sizeof (GNUNET_MessageHeader))
1414 {
1415 GNUNET_GE_BREAK (coreAPI->ectx, 0);
1416 return GNUNET_SYSERR;
1417 }
1418 if (size == 0)
1419 {
1420 GNUNET_GE_BREAK (coreAPI->ectx, 0);
1421 return GNUNET_SYSERR;
1422 }
1423 if (httpSession->is_client)
1424 {
1425 /* client */
1426 if ((important != GNUNET_YES) && (httpSession->cs.client.puts != NULL))
1427 return GNUNET_NO;
1428 return GNUNET_YES;
1429 }
1430 else
1431 {
1432 /* server */
1433 GNUNET_mutex_lock (lock);
1434 get = httpSession->cs.server.gets;
1435 if (get == NULL)
1436 ret = GNUNET_NO;
1437 else
1438 {
1439 if (get->wsize == 0)
1440 ret = GNUNET_YES;
1441 else if ((get->wpos + size > get->wsize)
1442 && (important != GNUNET_YES))
1443 ret = GNUNET_NO;
1444 else
1445 ret = GNUNET_YES;
1446 }
1447 GNUNET_mutex_unlock (lock);
1448 return ret;
1449 }
1450}
1451
1452
1453/**
1454 * Send a message to the specified remote node.
1455 *
1456 * @param tsession the GNUNET_MessageHello identifying the remote node
1457 * @param msg the message
1458 * @param size the size of the message
1459 * @return GNUNET_SYSERR on error, GNUNET_OK on success, GNUNET_NO if queue is full
1460 */
1461static int
1462httpSend (GNUNET_TSession * tsession,
1463 const void *msg, unsigned int size, int important)
1464{
1465 HTTPSession *httpSession = tsession->internal;
1466 struct HTTPPutData *putData;
1467 GNUNET_MessageHeader *hdr;
1468#if DO_GET
1469 struct MHDGetData *getData;
1470 char *tmp;
1471#endif
1472
1473 if (stats != NULL)
1474 stats->change (stat_send_calls, 1);
1475 if (httpSession->is_client)
1476 {
1477 /* we need to do a PUT (we are the client) */
1478 if (size >= GNUNET_MAX_BUFFER_SIZE)
1479 return GNUNET_SYSERR;
1480 if (size == 0)
1481 {
1482 GNUNET_GE_BREAK (NULL, 0);
1483 return GNUNET_SYSERR;
1484 }
1485 if (important != GNUNET_YES)
1486 {
1487 GNUNET_mutex_lock (lock);
1488 if (httpSession->cs.client.puts != NULL)
1489 {
1490 /* do not queue more than one unimportant PUT at a time */
1491 signal_select (); /* do clean up now! */
1492 GNUNET_mutex_unlock (lock);
1493 if (stats != NULL)
1494 stats->change (stat_bytesDropped, size);
1495
1496 return GNUNET_NO;
1497 }
1498 GNUNET_mutex_unlock (lock);
1499 }
1500 putData = GNUNET_malloc (sizeof (struct HTTPPutData));
1501 memset (putData, 0, sizeof (struct HTTPPutData));
1502 putData->msg = GNUNET_malloc (size + sizeof (GNUNET_MessageHeader));
1503 hdr = (GNUNET_MessageHeader *) putData->msg;
1504 hdr->size = htons (size + sizeof (GNUNET_MessageHeader));
1505 hdr->type = htons (0);
1506 memcpy (&putData->msg[sizeof (GNUNET_MessageHeader)], msg, size);
1507 putData->size = size + sizeof (GNUNET_MessageHeader);
1508 putData->last_activity = GNUNET_get_time ();
1509 if (GNUNET_OK != create_curl_put (httpSession, putData))
1510 {
1511 GNUNET_free (putData->msg);
1512 GNUNET_free (putData);
1513 return GNUNET_SYSERR;
1514 }
1515 GNUNET_mutex_lock (lock);
1516 putData->next = httpSession->cs.client.puts;
1517 httpSession->cs.client.puts = putData;
1518 GNUNET_mutex_unlock (lock);
1519 return GNUNET_OK;
1520 }
1521
1522 /* httpSession->isClient == false, respond to a GET (we
1523 hopefully have one or will have one soon) */
1524#if DEBUG_HTTP
1525 GNUNET_GE_LOG (coreAPI->ectx,
1526 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
1527 "HTTP/MHD queues %u bytes to be sent as response to GET as soon as possible.\n",
1528 size);
1529#endif
1530#if DO_GET
1531 GNUNET_mutex_lock (lock);
1532 getData = httpSession->cs.server.gets;
1533 if (getData == NULL)
1534 {
1535 GNUNET_mutex_unlock (lock);
1536 return GNUNET_SYSERR;
1537 }
1538 if (getData->wsize == 0)
1539 GNUNET_array_grow (getData->wbuff, getData->wsize, HTTP_BUF_SIZE);
1540 size += sizeof (GNUNET_MessageHeader);
1541 if (getData->wpos + size > getData->wsize)
1542 {
1543 /* need to grow or discard */
1544 if (!important)
1545 {
1546 GNUNET_mutex_unlock (lock);
1547 return GNUNET_NO;
1548 }
1549 tmp = GNUNET_malloc (getData->wpos + size);
1550 memcpy (tmp, &getData->wbuff[getData->woff], getData->wpos);
1551 hdr = (GNUNET_MessageHeader *) & tmp[getData->wpos];
1552 hdr->type = htons (0);
1553 hdr->size = htons (size);
1554 memcpy (&hdr[1], msg, size - sizeof (GNUNET_MessageHeader));
1555 GNUNET_free (getData->wbuff);
1556 getData->wbuff = tmp;
1557 getData->wsize = getData->wpos + size;
1558 getData->woff = 0;
1559 getData->wpos = getData->wpos + size;
1560 }
1561 else
1562 {
1563 /* fits without growing */
1564 if (getData->wpos + getData->woff + size > getData->wsize)
1565 {
1566 /* need to compact first */
1567 memmove (getData->wbuff,
1568 &getData->wbuff[getData->woff], getData->wpos);
1569 getData->woff = 0;
1570 }
1571 /* append */
1572 hdr =
1573 (GNUNET_MessageHeader *) & getData->wbuff[getData->woff +
1574 getData->wpos];
1575 hdr->size = htons (size);
1576 hdr->type = htons (0);
1577 memcpy (&hdr[1], msg, size - sizeof (GNUNET_MessageHeader));
1578 getData->wpos += size;
1579 }
1580 signal_select ();
1581 GNUNET_mutex_unlock (lock);
1582#endif
1583 return GNUNET_OK;
1584}
1585
1586/**
1587 * Function called to cleanup dead connections
1588 * (completed PUTs, GETs that have timed out,
1589 * etc.). Also re-vives GETs that have timed out
1590 * if we are still interested in the connection.
1591 */
1592static void
1593cleanup_connections ()
1594{
1595 int i;
1596 HTTPSession *s;
1597 struct HTTPPutData *prev;
1598 struct HTTPPutData *pos;
1599 struct MHDPutData *mpos;
1600 struct MHDPutData *mprev;
1601#if DO_GET
1602 struct MHD_Response *r;
1603 struct MHDGetData *gpos;
1604 struct MHDGetData *gnext;
1605#endif
1606 GNUNET_CronTime now;
1607
1608 GNUNET_mutex_lock (lock);
1609 now = GNUNET_get_time ();
1610 for (i = 0; i < tsessionCount; i++)
1611 {
1612 s = tsessions[i]->internal;
1613 if (s->is_client)
1614 {
1615 if ((s->cs.client.puts == NULL) && (s->users == 0)
1616#if DO_GET
1617 && (s->cs.client.last_get_activity + HTTP_TIMEOUT < now)
1618#endif
1619 )
1620 {
1621#if DO_GET
1622#if DEBUG_HTTP
1623 GNUNET_GE_LOG (coreAPI->ectx,
1624 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST |
1625 GNUNET_GE_USER,
1626 "HTTP transport destroys old (%llu ms) unused client session\n",
1627 now - s->cs.client.last_get_activity);
1628#endif
1629#endif
1630 destroy_tsession (tsessions[i]);
1631 i--;
1632 continue;
1633 }
1634
1635 prev = NULL;
1636 pos = s->cs.client.puts;
1637 while (pos != NULL)
1638 {
1639 if (pos->last_activity + HTTP_TIMEOUT < now)
1640 pos->done = GNUNET_YES;
1641 if (pos->done)
1642 {
1643 if (prev == NULL)
1644 s->cs.client.puts = pos->next;
1645 else
1646 prev->next = pos->next;
1647 GNUNET_free (pos->msg);
1648 curl_multi_remove_handle (curl_multi, pos->curl_put);
1649 http_requests_pending--;
1650 signal_select ();
1651 curl_easy_cleanup (pos->curl_put);
1652 GNUNET_free (pos);
1653 if (prev == NULL)
1654 pos = s->cs.client.puts;
1655 else
1656 pos = prev->next;
1657 continue;
1658 }
1659 prev = pos;
1660 pos = pos->next;
1661 }
1662#if DO_GET
1663 if ((s->cs.client.last_get_activity + HTTP_TIMEOUT < now) &&
1664 ((s->users > 0) || (s->cs.client.puts != NULL)) &&
1665 ((s->cs.client.last_get_initiated + HTTP_GET_REFRESH > now) ||
1666 (s->cs.client.get == NULL)) &&
1667 ((s->cs.client.get == NULL) ||
1668 (s->cs.client.last_get_activity + HTTP_GET_REFRESH / 2 < now)))
1669 create_curl_get (s);
1670#endif
1671 }
1672 else
1673 {
1674 mpos = s->cs.server.puts;
1675 mprev = NULL;
1676 while (mpos != NULL)
1677 {
1678 if (mpos->last_activity == 0)
1679 {
1680 if (mprev == NULL)
1681 s->cs.server.puts = mpos->next;
1682 else
1683 mprev->next = mpos->next;
1684 GNUNET_array_grow (mpos->rbuff2, mpos->rsize2, 0);
1685 GNUNET_free (mpos);
1686 if (mprev == NULL)
1687 mpos = s->cs.server.puts;
1688 else
1689 mpos = mprev->next;
1690 continue;
1691 }
1692 mprev = mpos;
1693 mpos = mpos->next;
1694 }
1695
1696 /* ! s->is_client */
1697#if DO_GET
1698 gpos = s->cs.server.gets;
1699 while (gpos != NULL)
1700 {
1701 gnext = gpos->next;
1702 gpos->next = NULL;
1703 if ((gpos->last_get_activity + HTTP_TIMEOUT < now) ||
1704 (gpos != s->cs.server.gets))
1705 {
1706 if (gpos == s->cs.server.gets)
1707 s->cs.server.gets = NULL;
1708 r = gpos->get;
1709 gpos->get = NULL;
1710 MHD_destroy_response (r);
1711 }
1712 gpos = gnext;
1713 }
1714#endif
1715 if (
1716#if DO_GET
1717 (s->cs.server.gets == NULL) &&
1718#endif
1719 (s->is_mhd_active == 0) && (s->users == 0))
1720 {
1721#if DO_GET
1722#if DEBUG_HTTP
1723 GNUNET_GE_LOG (coreAPI->ectx,
1724 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST |
1725 GNUNET_GE_USER,
1726 "HTTP transport destroys unused server session\n");
1727#endif
1728#endif
1729 destroy_tsession (tsessions[i]);
1730 i--;
1731 continue;
1732 }
1733 }
1734 }
1735 GNUNET_mutex_unlock (lock);
1736}
1737
1738/**
1739 * Thread that runs the CURL and MHD requests.
1740 */
1741static void *
1742curl_runner (void *unused)
1743{
1744 CURLMcode mret;
1745 fd_set rs;
1746 fd_set ws;
1747 fd_set es;
1748 int max;
1749 struct timeval tv;
1750 int running;
1751 unsigned long long timeout;
1752 long ms;
1753 int have_tv;
1754 char buf[128]; /* for reading from pipe */
1755 int ret;
1756
1757#if DEBUG_HTTP
1758 GNUNET_GE_LOG (coreAPI->ectx,
1759 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
1760 "HTTP transport select thread started\n");
1761#endif
1762 while (GNUNET_YES == http_running)
1763 {
1764 max = 0;
1765 FD_ZERO (&rs);
1766 FD_ZERO (&ws);
1767 FD_ZERO (&es);
1768 GNUNET_mutex_lock (lock);
1769 mret = curl_multi_fdset (curl_multi, &rs, &ws, &es, &max);
1770 GNUNET_mutex_unlock (lock);
1771 if (mret != CURLM_OK)
1772 {
1773 GNUNET_GE_LOG (coreAPI->ectx,
1774 GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER |
1775 GNUNET_GE_BULK, _("%s failed at %s:%d: `%s'\n"),
1776 "curl_multi_fdset", __FILE__, __LINE__,
1777 curl_multi_strerror (mret));
1778 break;
1779 }
1780 if (mhd_daemon != NULL)
1781 MHD_get_fdset (mhd_daemon, &rs, &ws, &es, &max);
1782 timeout = 0;
1783 have_tv = MHD_NO;
1784 if (mhd_daemon != NULL)
1785 have_tv = MHD_get_timeout (mhd_daemon, &timeout);
1786 GNUNET_mutex_lock (lock);
1787 if ((CURLM_OK == curl_multi_timeout (curl_multi, &ms)) &&
1788 (ms != -1) && ((ms < timeout) || (have_tv == MHD_NO)))
1789 {
1790 timeout = ms;
1791 have_tv = MHD_YES;
1792 }
1793 GNUNET_mutex_unlock (lock);
1794 FD_SET (signal_pipe[0], &rs);
1795 if (max < signal_pipe[0])
1796 max = signal_pipe[0];
1797 tv.tv_sec = timeout / 1000;
1798 tv.tv_usec = (timeout % 1000) * 1000;
1799 if (stats != NULL)
1800 stats->change (stat_select_calls, 1);
1801 ret =
1802 SELECT (max + 1, &rs, &ws, &es, (have_tv == MHD_YES) ? &tv : NULL);
1803 if (ret == -1)
1804 {
1805 GNUNET_GE_LOG_STRERROR (coreAPI->ectx,
1806 GNUNET_GE_ERROR | GNUNET_GE_ADMIN |
1807 GNUNET_GE_DEVELOPER, "select");
1808 }
1809 if (GNUNET_YES != http_running)
1810 break;
1811 running = 0;
1812 do
1813 {
1814 GNUNET_mutex_lock (lock);
1815 mret = curl_multi_perform (curl_multi, &running);
1816 GNUNET_mutex_unlock (lock);
1817 }
1818 while ((mret == CURLM_CALL_MULTI_PERFORM)
1819 && (http_running == GNUNET_YES));
1820 if (FD_ISSET (signal_pipe[0], &rs))
1821 read (signal_pipe[0], buf, sizeof (buf));
1822 if ((mret != CURLM_OK) && (mret != CURLM_CALL_MULTI_PERFORM))
1823 GNUNET_GE_LOG (coreAPI->ectx,
1824 GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER |
1825 GNUNET_GE_BULK, _("%s failed at %s:%d: `%s'\n"),
1826 "curl_multi_perform", __FILE__, __LINE__,
1827 curl_multi_strerror (mret));
1828 if (mhd_daemon != NULL)
1829 MHD_run (mhd_daemon);
1830 cleanup_connections ();
1831 }
1832#if DEBUG_HTTP
1833 GNUNET_GE_LOG (coreAPI->ectx,
1834 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
1835 "HTTP transport select thread exits.\n");
1836#endif
1837 return NULL;
1838}
1839
1840
1841/**
1842 * Start the server process to receive inbound traffic.
1843 * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
1844 */
1845static int
1846startTransportServer ()
1847{
1848 unsigned short port;
1849
1850 if ((curl_multi != NULL) || (http_running == GNUNET_YES))
1851 return GNUNET_SYSERR;
1852 curl_multi = curl_multi_init ();
1853 if (curl_multi == NULL)
1854 return GNUNET_SYSERR;
1855 port = get_port ();
1856 if ((mhd_daemon == NULL) && (port != 0))
1857 {
1858 if (GNUNET_YES !=
1859 GNUNET_GC_get_configuration_value_yesno (cfg, "GNUNETD",
1860 "DISABLE-IPV6",
1861 GNUNET_YES))
1862 {
1863 mhd_daemon = MHD_start_daemon (MHD_USE_IPv6,
1864 port,
1865 &acceptPolicyCallback,
1866 NULL, &accessHandlerCallback, NULL,
1867 MHD_OPTION_CONNECTION_TIMEOUT,
1868 (unsigned int) HTTP_TIMEOUT,
1869 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
1870 (unsigned int) 1024 * 128,
1871 MHD_OPTION_CONNECTION_LIMIT,
1872 (unsigned int) 128,
1873 MHD_OPTION_PER_IP_CONNECTION_LIMIT,
1874 (unsigned int) 8,
1875 MHD_OPTION_NOTIFY_COMPLETED,
1876 &requestCompletedCallback, NULL,
1877 MHD_OPTION_END);
1878 }
1879 if (mhd_daemon == NULL)
1880 {
1881 /* try without IPv6 */
1882 mhd_daemon = MHD_start_daemon (MHD_NO_FLAG,
1883 port,
1884 &acceptPolicyCallback,
1885 NULL, &accessHandlerCallback, NULL,
1886 MHD_OPTION_CONNECTION_TIMEOUT,
1887 (unsigned int) HTTP_TIMEOUT,
1888 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
1889 (unsigned int) 1024 * 128,
1890 MHD_OPTION_CONNECTION_LIMIT,
1891 (unsigned int) 128,
1892 MHD_OPTION_PER_IP_CONNECTION_LIMIT,
1893 (unsigned int) 8,
1894 MHD_OPTION_NOTIFY_COMPLETED,
1895 &requestCompletedCallback, NULL,
1896 MHD_OPTION_END);
1897 }
1898 else
1899 {
1900 available_protocols |= VERSION_AVAILABLE_IPV6;
1901 }
1902 if (mhd_daemon != NULL)
1903 available_protocols |= VERSION_AVAILABLE_IPV4;
1904 }
1905 if (port == 0)
1906 {
1907 /* NAT */
1908 available_protocols |= VERSION_AVAILABLE_IPV4;
1909 if (GNUNET_YES !=
1910 GNUNET_GC_get_configuration_value_yesno (cfg, "GNUNETD",
1911 "DISABLE-IPV6",
1912 GNUNET_YES))
1913 available_protocols |= VERSION_AVAILABLE_IPV6;
1914 }
1915 if (0 != PIPE (signal_pipe))
1916 {
1917 MHD_stop_daemon (mhd_daemon);
1918 curl_multi_cleanup (curl_multi);
1919 curl_multi = NULL;
1920 mhd_daemon = NULL;
1921 return GNUNET_SYSERR;
1922 }
1923 GNUNET_pipe_make_nonblocking (coreAPI->ectx, signal_pipe[0]);
1924 GNUNET_pipe_make_nonblocking (coreAPI->ectx, signal_pipe[1]);
1925 http_running = GNUNET_YES;
1926 curl_thread = GNUNET_thread_create (&curl_runner, NULL, 32 * 1024);
1927 if (curl_thread == NULL)
1928 GNUNET_GE_DIE_STRERROR (coreAPI->ectx,
1929 GNUNET_GE_FATAL | GNUNET_GE_ADMIN |
1930 GNUNET_GE_IMMEDIATE, "pthread_create");
1931 return GNUNET_OK;
1932}
1933
1934/**
1935 * Shutdown the server process (stop receiving inbound
1936 * traffic). May be restarted later!
1937 */
1938static int
1939stopTransportServer ()
1940{
1941 void *unused;
1942 int i;
1943 HTTPSession *s;
1944
1945 if ((http_running == GNUNET_NO) || (curl_multi == NULL))
1946 return GNUNET_SYSERR;
1947 http_running = GNUNET_NO;
1948 signal_select ();
1949 GNUNET_thread_stop_sleep (curl_thread);
1950 GNUNET_thread_join (curl_thread, &unused);
1951 CLOSE (signal_pipe[0]);
1952 CLOSE (signal_pipe[1]);
1953 if (mhd_daemon != NULL)
1954 {
1955 MHD_stop_daemon (mhd_daemon);
1956 mhd_daemon = NULL;
1957 }
1958 cleanup_connections ();
1959 for (i = 0; i < tsessionCount; i++)
1960 {
1961 s = tsessions[i]->internal;
1962 if (s->users == 0)
1963 {
1964 destroy_tsession (tsessions[i]);
1965 i--;
1966 }
1967 }
1968 curl_multi_cleanup (curl_multi);
1969 curl_multi = NULL;
1970 return GNUNET_OK;
1971}
1972
1973/* ******************** public API ******************** */
1974
1975/**
1976 * The exported method. Makes the core api available
1977 * via a global and returns the udp transport API.
1978 */
1979GNUNET_TransportAPI *
1980inittransport_http (GNUNET_CoreAPIForTransport * core)
1981{
1982 GNUNET_GE_ASSERT (coreAPI->ectx, sizeof (HostAddress) == 24);
1983 coreAPI = core;
1984 cfg = coreAPI->cfg;
1985 lock = GNUNET_mutex_create (GNUNET_YES);
1986 if (0 != GNUNET_GC_attach_change_listener (coreAPI->cfg,
1987 &reload_configuration, NULL))
1988 {
1989 GNUNET_mutex_destroy (lock);
1990 lock = NULL;
1991 return NULL;
1992 }
1993 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
1994 {
1995 GNUNET_GE_BREAK (NULL, 0);
1996 GNUNET_GC_detach_change_listener (coreAPI->cfg, &reload_configuration,
1997 NULL);
1998 GNUNET_mutex_destroy (lock);
1999 lock = NULL;
2000 return NULL;
2001 }
2002 tsessionCount = 0;
2003 tsessionArrayLength = 0;
2004 GNUNET_array_grow (tsessions, tsessionArrayLength, 32);
2005 if (GNUNET_GC_get_configuration_value_yesno (coreAPI->cfg,
2006 "HTTP", "UPNP",
2007 GNUNET_YES) == GNUNET_YES)
2008 {
2009 upnp = coreAPI->service_request ("upnp");
2010
2011 if (upnp == NULL)
2012 {
2013 GNUNET_GE_LOG (coreAPI->ectx,
2014 GNUNET_GE_ERROR | GNUNET_GE_USER |
2015 GNUNET_GE_IMMEDIATE,
2016 _
2017 ("The UPnP service could not be loaded. To disable UPnP, set the "
2018 "configuration option \"UPNP\" in section \"%s\" to \"NO\"\n"),
2019 "HTTP");
2020 }
2021 }
2022 stats = coreAPI->service_request ("stats");
2023 if (stats != NULL)
2024 {
2025 stat_bytesReceived
2026 = stats->create (gettext_noop ("# bytes received via HTTP"));
2027 stat_bytesSent = stats->create (gettext_noop ("# bytes sent via HTTP"));
2028 stat_bytesDropped
2029 = stats->create (gettext_noop ("# bytes dropped by HTTP (outgoing)"));
2030 stat_get_issued = stats->create (gettext_noop ("# HTTP GET issued"));
2031 stat_get_received
2032 = stats->create (gettext_noop ("# HTTP GET received"));
2033 stat_put_issued = stats->create (gettext_noop ("# HTTP PUT issued"));
2034 stat_put_received
2035 = stats->create (gettext_noop ("# HTTP PUT received"));
2036 stat_select_calls
2037 = stats->create (gettext_noop ("# HTTP select calls"));
2038
2039 stat_send_calls = stats->create (gettext_noop ("# HTTP send calls"));
2040
2041 stat_curl_send_callbacks
2042 = stats->create (gettext_noop ("# HTTP curl send callbacks"));
2043 stat_curl_receive_callbacks
2044 = stats->create (gettext_noop ("# HTTP curl receive callbacks"));
2045 stat_mhd_access_callbacks
2046 = stats->create (gettext_noop ("# HTTP mhd access callbacks"));
2047 stat_mhd_read_callbacks
2048 = stats->create (gettext_noop ("# HTTP mhd read callbacks"));
2049 stat_mhd_close_callbacks
2050 = stats->create (gettext_noop ("# HTTP mhd close callbacks"));
2051 stat_connect_calls
2052 = stats->create (gettext_noop ("# HTTP connect calls"));
2053 }
2054 GNUNET_GC_get_configuration_value_string (coreAPI->cfg,
2055 "GNUNETD", "HTTP-PROXY", "",
2056 &proxy);
2057
2058 myAPI.protocol_number = GNUNET_TRANSPORT_PROTOCOL_NUMBER_HTTP;
2059 myAPI.mtu = 0;
2060 myAPI.cost = 20000; /* about equal to udp */
2061 myAPI.hello_verify = &verify_hello;
2062 myAPI.hello_create = &create_hello;
2063 myAPI.connect = &httpConnect;
2064 myAPI.associate = &httpAssociate;
2065 myAPI.send = &httpSend;
2066 myAPI.disconnect = &httpDisconnect;
2067 myAPI.server_start = &startTransportServer;
2068 myAPI.server_stop = &stopTransportServer;
2069 myAPI.hello_to_address = &hello_to_address;
2070 myAPI.send_now_test = &httpTestWouldTry;
2071
2072 return &myAPI;
2073}
2074
2075void
2076donetransport_http ()
2077{
2078 curl_global_cleanup ();
2079 GNUNET_free_non_null (proxy);
2080 proxy = NULL;
2081 GNUNET_array_grow (tsessions, tsessionArrayLength, 0);
2082 do_shutdown ();
2083}
2084
2085/* end of http.c */
diff --git a/src/transport/plugin_transport_smtp.c b/src/transport/plugin_transport_smtp.c
new file mode 100644
index 000000000..f7cc530e4
--- /dev/null
+++ b/src/transport/plugin_transport_smtp.c
@@ -0,0 +1,906 @@
1/*
2 This file is part of GNUnet
3 (C) 2003, 2004, 2005, 2006, 2007 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 2, 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 transports/smtp.c
23 * @brief Implementation of the SMTP transport service
24 * @author Christian Grothoff
25 * @author Renaldo Ferreira
26 */
27
28#include "platform.h"
29#include "gnunet_util.h"
30#include "gnunet_directories.h"
31#include "gnunet_protocols.h"
32#include "gnunet_transport.h"
33#include "gnunet_stats_service.h"
34#include <libesmtp.h>
35#include <signal.h>
36
37
38/**
39 * The default maximum size of each outbound SMTP message.
40 */
41#define SMTP_MESSAGE_SIZE 65528
42
43#define DEBUG_SMTP GNUNET_NO
44
45#define FILTER_STRING_SIZE 64
46
47/* how long can a line in base64 encoded
48 mime text be? (in characters, excluding "\n") */
49#define MAX_CHAR_PER_LINE 76
50
51#define EBUF_LEN 128
52
53/**
54 * Host-Address in a SMTP network.
55 */
56typedef struct
57{
58
59 /**
60 * Filter line that every sender must include in the E-mails such
61 * that the receiver can effectively filter out the GNUnet traffic
62 * from the E-mail.
63 */
64 char filter[FILTER_STRING_SIZE];
65
66 /**
67 * Claimed E-mail address of the sender.
68 * Format is "foo@bar.com" with null termination, padded to be
69 * of a multiple of 8 bytes long.
70 */
71 char senderAddress[0];
72
73} EmailAddress;
74
75/**
76 * Encapsulation of a GNUnet message in the SMTP mail body (before
77 * base64 encoding).
78 */
79typedef struct
80{
81 GNUNET_MessageHeader header;
82
83 /**
84 * What is the identity of the sender (GNUNET_hash of public key)
85 */
86 GNUNET_PeerIdentity sender;
87
88} SMTPMessage;
89
90/* *********** globals ************* */
91
92/**
93 * apis (our advertised API and the core api )
94 */
95static GNUNET_CoreAPIForTransport *coreAPI;
96
97static struct GNUNET_GE_Context *ectx;
98
99/**
100 * Thread that listens for inbound messages
101 */
102static struct GNUNET_ThreadHandle *dispatchThread;
103
104/**
105 * Flag to indicate that server has been shut down.
106 */
107static int smtp_shutdown = GNUNET_YES;
108
109/**
110 * Set to the SMTP server hostname (and port) for outgoing messages.
111 */
112static char *smtp_server_name;
113
114static char *pipename;
115
116/**
117 * Lock for uses of libesmtp (not thread-safe).
118 */
119static struct GNUNET_Mutex *lock;
120
121/**
122 * Old handler for SIGPIPE (kept to be able to restore).
123 */
124static struct sigaction old_handler;
125
126static char *email;
127
128static GNUNET_TransportAPI smtpAPI;
129
130static GNUNET_Stats_ServiceAPI *stats;
131
132static int stat_bytesReceived;
133
134static int stat_bytesSent;
135
136static int stat_bytesDropped;
137
138/**
139 * How many e-mails are we allowed to send per hour?
140 */
141static unsigned long long rate_limit;
142
143static GNUNET_CronTime last_transmission;
144
145/** ******************** Base64 encoding ***********/
146
147#define FILLCHAR '='
148static char *cvt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
149 "abcdefghijklmnopqrstuvwxyz" "0123456789+/";
150
151/**
152 * Encode into Base64.
153 *
154 * @param data the data to encode
155 * @param len the length of the input
156 * @param output where to write the output (*output should be NULL,
157 * is allocated)
158 * @return the size of the output
159 */
160static unsigned int
161base64_encode (const char *data, unsigned int len, char **output)
162{
163 unsigned int i;
164 char c;
165 unsigned int ret;
166 char *opt;
167
168/* (*output)[ret++] = '\r'; \*/
169#define CHECKLINE \
170 if ( (ret % MAX_CHAR_PER_LINE) == 0) { \
171 (*output)[ret++] = '\n'; \
172 }
173 ret = 0;
174 opt = GNUNET_malloc (2 + (((len * 4 / 3) + 8) * (MAX_CHAR_PER_LINE + 2)) /
175 MAX_CHAR_PER_LINE);
176 /* message must start with \r\n for libesmtp */
177 *output = opt;
178 opt[0] = '\r';
179 opt[1] = '\n';
180 ret += 2;
181 for (i = 0; i < len; ++i)
182 {
183 c = (data[i] >> 2) & 0x3f;
184 opt[ret++] = cvt[(int) c];
185 CHECKLINE;
186 c = (data[i] << 4) & 0x3f;
187 if (++i < len)
188 c |= (data[i] >> 4) & 0x0f;
189 opt[ret++] = cvt[(int) c];
190 CHECKLINE;
191 if (i < len)
192 {
193 c = (data[i] << 2) & 0x3f;
194 if (++i < len)
195 c |= (data[i] >> 6) & 0x03;
196 opt[ret++] = cvt[(int) c];
197 CHECKLINE;
198 }
199 else
200 {
201 ++i;
202 opt[ret++] = FILLCHAR;
203 CHECKLINE;
204 }
205 if (i < len)
206 {
207 c = data[i] & 0x3f;
208 opt[ret++] = cvt[(int) c];
209 CHECKLINE;
210 }
211 else
212 {
213 opt[ret++] = FILLCHAR;
214 CHECKLINE;
215 }
216 }
217 opt[ret++] = FILLCHAR;
218 return ret;
219}
220
221#define cvtfind(a)( (((a) >= 'A')&&((a) <= 'Z'))? (a)-'A'\
222 :(((a)>='a')&&((a)<='z')) ? (a)-'a'+26\
223 :(((a)>='0')&&((a)<='9')) ? (a)-'0'+52\
224 :((a) == '+') ? 62\
225 :((a) == '/') ? 63 : -1)
226/**
227 * Decode from Base64.
228 *
229 * @param data the data to encode
230 * @param len the length of the input
231 * @param output where to write the output (*output should be NULL,
232 * is allocated)
233 * @return the size of the output
234 */
235static unsigned int
236base64_decode (const char *data, unsigned int len, char **output)
237{
238 unsigned int i;
239 char c;
240 char c1;
241 unsigned int ret = 0;
242
243#define CHECK_CRLF while (data[i] == '\r' || data[i] == '\n') {\
244 GNUNET_GE_LOG(ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER, "ignoring CR/LF\n"); \
245 i++; \
246 if (i >= len) goto END; \
247 }
248
249 *output = GNUNET_malloc ((len * 3 / 4) + 8);
250#if DEBUG_SMTP
251 GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
252 "base64_decode decoding len=%d\n", len);
253#endif
254 for (i = 0; i < len; ++i)
255 {
256 CHECK_CRLF;
257 if (data[i] == FILLCHAR)
258 break;
259 c = (char) cvtfind (data[i]);
260 ++i;
261 CHECK_CRLF;
262 c1 = (char) cvtfind (data[i]);
263 c = (c << 2) | ((c1 >> 4) & 0x3);
264 (*output)[ret++] = c;
265 if (++i < len)
266 {
267 CHECK_CRLF;
268 c = data[i];
269 if (FILLCHAR == c)
270 break;
271 c = (char) cvtfind (c);
272 c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf);
273 (*output)[ret++] = c1;
274 }
275 if (++i < len)
276 {
277 CHECK_CRLF;
278 c1 = data[i];
279 if (FILLCHAR == c1)
280 break;
281
282 c1 = (char) cvtfind (c1);
283 c = ((c << 6) & 0xc0) | c1;
284 (*output)[ret++] = c;
285 }
286 }
287END:
288 return ret;
289}
290
291/* ********************* the real stuff ******************* */
292
293#define strAUTOncmp(a,b) strncmp(a,b,strlen(b))
294
295/**
296 * Listen to the pipe, decode messages and send to core.
297 */
298static void *
299listenAndDistribute (void *unused)
300{
301 char *line;
302 unsigned int linesize;
303 SMTPMessage *mp;
304 FILE *fdes;
305 char *retl;
306 char *out;
307 unsigned int size;
308 GNUNET_TransportPacket *coreMP;
309 int fd;
310 unsigned int pos;
311
312 linesize = ((GNUNET_MAX_BUFFER_SIZE * 4 / 3) + 8) * (MAX_CHAR_PER_LINE + 2) / MAX_CHAR_PER_LINE; /* maximum size of a line supported */
313 line = GNUNET_malloc (linesize + 2); /* 2 bytes for off-by-one errors, just to be safe... */
314
315#define READLINE(l,limit) \
316 do { retl = fgets(l, (limit), fdes); \
317 if ( (retl == NULL) || (smtp_shutdown == GNUNET_YES)) {\
318 goto END; \
319 }\
320 if (coreAPI->load_monitor != NULL) \
321 GNUNET_network_monitor_notify_transmission(coreAPI->load_monitor, GNUNET_ND_DOWNLOAD, strlen(retl)); \
322 } while (0)
323
324
325 while (smtp_shutdown == GNUNET_NO)
326 {
327 fd = OPEN (pipename, O_RDONLY | O_ASYNC);
328 if (fd == -1)
329 {
330 if (smtp_shutdown == GNUNET_NO)
331 GNUNET_thread_sleep (5 * GNUNET_CRON_SECONDS);
332 continue;
333 }
334 fdes = fdopen (fd, "r");
335 while (smtp_shutdown == GNUNET_NO)
336 {
337 /* skip until end of header */
338 do
339 {
340 READLINE (line, linesize);
341 }
342 while ((line[0] != '\r') && (line[0] != '\n')); /* expect newline */
343 READLINE (line, linesize); /* read base64 encoded message; decode, process */
344 pos = 0;
345 while (1)
346 {
347 pos = strlen (line) - 1; /* ignore new line */
348 READLINE (&line[pos], linesize - pos); /* read base64 encoded message; decode, process */
349 if ((line[pos] == '\r') || (line[pos] == '\n'))
350 break; /* empty line => end of message! */
351 }
352 size = base64_decode (line, pos, &out);
353 if (size < sizeof (SMTPMessage))
354 {
355 GNUNET_GE_BREAK (ectx, 0);
356 GNUNET_free (out);
357 goto END;
358 }
359
360 mp = (SMTPMessage *) & out[size - sizeof (SMTPMessage)];
361 if (ntohs (mp->header.size) != size)
362 {
363 GNUNET_GE_LOG (ectx,
364 GNUNET_GE_WARNING | GNUNET_GE_BULK |
365 GNUNET_GE_USER,
366 _
367 ("Received malformed message via %s. Ignored.\n"),
368 "SMTP");
369#if DEBUG_SMTP
370 GNUNET_GE_LOG (ectx,
371 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST |
372 GNUNET_GE_USER,
373 "Size returned by base64=%d, in the msg=%d.\n",
374 size, ntohl (mp->size));
375#endif
376 GNUNET_free (out);
377 goto END;
378 }
379 if (stats != NULL)
380 stats->change (stat_bytesReceived, size);
381 coreMP = GNUNET_malloc (sizeof (GNUNET_TransportPacket));
382 coreMP->msg = out;
383 coreMP->size = size - sizeof (SMTPMessage);
384 coreMP->tsession = NULL;
385 coreMP->sender = mp->sender;
386#if DEBUG_SMTP
387 GNUNET_GE_LOG (ectx,
388 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
389 "SMTP message passed to the core.\n");
390#endif
391
392 coreAPI->receive (coreMP);
393 }
394 END:
395#if DEBUG_SMTP
396 GNUNET_GE_LOG (ectx,
397 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
398 "SMTP message processed.\n");
399#endif
400 if (fdes != NULL)
401 fclose (fdes);
402 }
403 GNUNET_free (line);
404 return NULL;
405}
406
407/* *************** API implementation *************** */
408
409/**
410 * Verify that a hello-Message is correct (a node is reachable at that
411 * address). Since the reply will be asynchronous, a method must be
412 * called on success.
413 *
414 * @param hello the hello message to verify
415 * (the signature/crc have been verified before)
416 * @return GNUNET_OK on success, GNUNET_SYSERR on error
417 */
418static int
419api_verify_hello (const GNUNET_MessageHello * hello)
420{
421 const EmailAddress *maddr;
422
423 maddr = (const EmailAddress *) &hello[1];
424 if ((ntohs (hello->header.size) !=
425 sizeof (GNUNET_MessageHello) + ntohs (hello->senderAddressSize)) ||
426 (maddr->senderAddress[ntohs (hello->senderAddressSize) - 1 -
427 FILTER_STRING_SIZE] != '\0'))
428 {
429 GNUNET_GE_BREAK (ectx, 0);
430 return GNUNET_SYSERR; /* obviously invalid */
431 }
432 if (NULL == strstr (maddr->filter, ": "))
433 return GNUNET_SYSERR;
434 return GNUNET_OK;
435}
436
437/**
438 * Create a hello-Message for the current node. The hello is created
439 * without signature and without a timestamp. The GNUnet core will
440 * GNUNET_RSA_sign the message and add an expiration time.
441 *
442 * @return hello on success, NULL on error
443 */
444static GNUNET_MessageHello *
445api_create_hello ()
446{
447 GNUNET_MessageHello *msg;
448 char *filter;
449 EmailAddress *haddr;
450 int i;
451
452 GNUNET_GC_get_configuration_value_string (coreAPI->cfg,
453 "SMTP", "FILTER",
454 "X-mailer: GNUnet", &filter);
455 if (NULL == strstr (filter, ": "))
456 {
457 GNUNET_GE_LOG (ectx,
458 GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
459 _("SMTP filter string to invalid, lacks ': '\n"));
460 GNUNET_free (filter);
461 return NULL;
462 }
463
464 if (strlen (filter) > FILTER_STRING_SIZE)
465 {
466 filter[FILTER_STRING_SIZE] = '\0';
467 GNUNET_GE_LOG (ectx,
468 GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
469 _("SMTP filter string to long, capped to `%s'\n"),
470 filter);
471 }
472 i = (strlen (email) + 8) & (~7); /* make multiple of 8 */
473 msg =
474 GNUNET_malloc (sizeof (GNUNET_MessageHello) + sizeof (EmailAddress) + i);
475 memset (msg, 0, sizeof (GNUNET_MessageHello) + sizeof (EmailAddress) + i);
476 haddr = (EmailAddress *) & msg[1];
477 memset (&haddr->filter[0], 0, FILTER_STRING_SIZE);
478 strcpy (&haddr->filter[0], filter);
479 memcpy (&haddr->senderAddress[0], email, strlen (email) + 1);
480 msg->senderAddressSize = htons (strlen (email) + 1 + sizeof (EmailAddress));
481 msg->protocol = htons (GNUNET_TRANSPORT_PROTOCOL_NUMBER_SMTP);
482 msg->MTU = htonl (smtpAPI.mtu);
483 msg->header.size = htons (GNUNET_sizeof_hello (msg));
484 if (api_verify_hello (msg) == GNUNET_SYSERR)
485 GNUNET_GE_ASSERT (ectx, 0);
486 GNUNET_free (filter);
487 return msg;
488}
489
490struct GetMessageClosure
491{
492 unsigned int esize;
493 unsigned int pos;
494 char *ebody;
495};
496
497static const char *
498get_message (void **buf, int *len, void *cls)
499{
500 struct GetMessageClosure *gmc = cls;
501
502 *buf = NULL;
503 if (len == NULL)
504 {
505 gmc->pos = 0;
506 return NULL;
507 }
508 if (gmc->pos == gmc->esize)
509 return NULL; /* done */
510 *len = gmc->esize;
511 gmc->pos = gmc->esize;
512 return gmc->ebody;
513}
514
515/**
516 * Send a message to the specified remote node.
517 *
518 * @param tsession the GNUNET_MessageHello identifying the remote node
519 * @param message what to send
520 * @param size the size of the message
521 * @return GNUNET_SYSERR on error, GNUNET_OK on success
522 */
523static int
524api_send (GNUNET_TSession * tsession,
525 const void *msg, const unsigned int size, int important)
526{
527 const GNUNET_MessageHello *hello;
528 const EmailAddress *haddr;
529 char *m;
530 char *filter;
531 char *fvalue;
532 SMTPMessage *mp;
533 struct GetMessageClosure gm_cls;
534 smtp_session_t session;
535 smtp_message_t message;
536 smtp_recipient_t recipient;
537#define EBUF_LEN 128
538 char ebuf[EBUF_LEN];
539 GNUNET_CronTime now;
540
541 if (smtp_shutdown == GNUNET_YES)
542 return GNUNET_SYSERR;
543 if ((size == 0) || (size > smtpAPI.mtu))
544 {
545 GNUNET_GE_BREAK (ectx, 0);
546 return GNUNET_SYSERR;
547 }
548 now = GNUNET_get_time ();
549 if ((important != GNUNET_YES) &&
550 ((now - last_transmission) * rate_limit) < GNUNET_CRON_HOURS)
551 return GNUNET_NO; /* rate too high */
552 last_transmission = now;
553
554 hello = (const GNUNET_MessageHello *) tsession->internal;
555 if (hello == NULL)
556 return GNUNET_SYSERR;
557 GNUNET_mutex_lock (lock);
558 session = smtp_create_session ();
559 if (session == NULL)
560 {
561 GNUNET_GE_LOG (ectx,
562 GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER |
563 GNUNET_GE_IMMEDIATE,
564 _("SMTP: `%s' failed: %s.\n"),
565 "smtp_create_session",
566 smtp_strerror (smtp_errno (), ebuf, EBUF_LEN));
567 GNUNET_mutex_unlock (lock);
568 return GNUNET_SYSERR;
569 }
570 if (0 == smtp_set_server (session, smtp_server_name))
571 {
572 GNUNET_GE_LOG (ectx,
573 GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER |
574 GNUNET_GE_IMMEDIATE,
575 _("SMTP: `%s' failed: %s.\n"),
576 "smtp_set_server",
577 smtp_strerror (smtp_errno (), ebuf, EBUF_LEN));
578 smtp_destroy_session (session);
579 GNUNET_mutex_unlock (lock);
580 return GNUNET_SYSERR;
581 }
582 haddr = (const EmailAddress *) &hello[1];
583 message = smtp_add_message (session);
584 if (message == NULL)
585 {
586 GNUNET_GE_LOG (ectx,
587 GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER |
588 GNUNET_GE_BULK,
589 _("SMTP: `%s' failed: %s.\n"),
590 "smtp_add_message",
591 smtp_strerror (smtp_errno (), ebuf, EBUF_LEN));
592 smtp_destroy_session (session);
593 GNUNET_mutex_unlock (lock);
594 return GNUNET_SYSERR;
595 }
596 smtp_set_header (message, "To", NULL, haddr->senderAddress);
597 smtp_set_header (message, "From", NULL, email);
598
599 filter = GNUNET_strdup (haddr->filter);
600 fvalue = strstr (filter, ": ");
601 GNUNET_GE_ASSERT (NULL, NULL != fvalue);
602 fvalue[0] = '\0';
603 fvalue += 2;
604 if (0 == smtp_set_header (message, filter, fvalue))
605 {
606 GNUNET_GE_LOG (ectx,
607 GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER |
608 GNUNET_GE_BULK,
609 _("SMTP: `%s' failed: %s.\n"),
610 "smtp_set_header",
611 smtp_strerror (smtp_errno (), ebuf, EBUF_LEN));
612 smtp_destroy_session (session);
613 GNUNET_mutex_unlock (lock);
614 GNUNET_free (filter);
615 return GNUNET_SYSERR;
616 }
617 GNUNET_free (filter);
618 m = GNUNET_malloc (size + sizeof (SMTPMessage));
619 memcpy (m, msg, size);
620 mp = (SMTPMessage *) & m[size];
621 mp->header.size = htons (size + sizeof (SMTPMessage));
622 mp->header.type = htons (0);
623 mp->sender = *coreAPI->my_identity;
624 gm_cls.ebody = NULL;
625 gm_cls.pos = 0;
626 gm_cls.esize =
627 base64_encode (m, size + sizeof (SMTPMessage), &gm_cls.ebody);
628 GNUNET_free (m);
629 if (0 == smtp_size_set_estimate (message, gm_cls.esize))
630 {
631 GNUNET_GE_LOG (ectx,
632 GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER |
633 GNUNET_GE_BULK,
634 _("SMTP: `%s' failed: %s.\n"),
635 "smtp_size_set_estimate",
636 smtp_strerror (smtp_errno (), ebuf, EBUF_LEN));
637 }
638 if (0 == smtp_set_messagecb (message, &get_message, &gm_cls))
639 {
640 GNUNET_GE_LOG (ectx,
641 GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER |
642 GNUNET_GE_BULK,
643 _("SMTP: `%s' failed: %s.\n"),
644 "smtp_set_messagecb",
645 smtp_strerror (smtp_errno (), ebuf, EBUF_LEN));
646 smtp_destroy_session (session);
647 GNUNET_mutex_unlock (lock);
648 GNUNET_free (gm_cls.ebody);
649 return GNUNET_SYSERR;
650 }
651 recipient = smtp_add_recipient (message, haddr->senderAddress);
652 if (recipient == NULL)
653 {
654 GNUNET_GE_LOG (ectx,
655 GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER |
656 GNUNET_GE_BULK,
657 _("SMTP: `%s' failed: %s.\n"),
658 "smtp_add_recipient",
659 smtp_strerror (smtp_errno (), ebuf, EBUF_LEN));
660 smtp_destroy_session (session);
661 GNUNET_mutex_unlock (lock);
662 return GNUNET_SYSERR;
663 }
664 if (0 == smtp_start_session (session))
665 {
666 GNUNET_GE_LOG (ectx,
667 GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER |
668 GNUNET_GE_BULK,
669 _("SMTP: `%s' failed: %s.\n"),
670 "smtp_start_session",
671 smtp_strerror (smtp_errno (), ebuf, EBUF_LEN));
672 smtp_destroy_session (session);
673 GNUNET_mutex_unlock (lock);
674 GNUNET_free (gm_cls.ebody);
675 return GNUNET_SYSERR;
676 }
677 if (stats != NULL)
678 stats->change (stat_bytesSent, size);
679 if (coreAPI->load_monitor != NULL)
680 GNUNET_network_monitor_notify_transmission (coreAPI->load_monitor,
681 GNUNET_ND_UPLOAD,
682 gm_cls.esize);
683 smtp_message_reset_status (message); /* this is needed to plug a 28-byte/message memory leak in libesmtp */
684 smtp_destroy_session (session);
685 GNUNET_mutex_unlock (lock);
686 GNUNET_free (gm_cls.ebody);
687 return GNUNET_OK;
688}
689
690/**
691 * Establish a connection to a remote node.
692 * @param helo the hello-Message for the target node
693 * @param tsessionPtr the session handle that is to be set
694 * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
695 */
696static int
697api_connect (const GNUNET_MessageHello * hello,
698 GNUNET_TSession ** tsessionPtr, int may_reuse)
699{
700 GNUNET_TSession *tsession;
701
702 tsession = GNUNET_malloc (sizeof (GNUNET_TSession));
703 tsession->internal = GNUNET_malloc (GNUNET_sizeof_hello (hello));
704 tsession->peer = hello->senderIdentity;
705 memcpy (tsession->internal, hello, GNUNET_sizeof_hello (hello));
706 tsession->ttype = smtpAPI.protocol_number;
707 (*tsessionPtr) = tsession;
708 return GNUNET_OK;
709}
710
711/**
712 * Disconnect from a remote node.
713 *
714 * @param tsession the session that is closed
715 * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
716 */
717static int
718api_disconnect (GNUNET_TSession * tsession)
719{
720 if (tsession != NULL)
721 {
722 if (tsession->internal != NULL)
723 GNUNET_free (tsession->internal);
724 GNUNET_free (tsession);
725 }
726 return GNUNET_OK;
727}
728
729/**
730 * Start the server process to receive inbound traffic.
731 * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
732 */
733static int
734api_start_transport_server ()
735{
736 smtp_shutdown = GNUNET_NO;
737 /* initialize SMTP network */
738 dispatchThread =
739 GNUNET_thread_create (&listenAndDistribute, NULL, 1024 * 4);
740 if (dispatchThread == NULL)
741 {
742 GNUNET_GE_DIE_STRERROR (ectx,
743 GNUNET_GE_ADMIN | GNUNET_GE_BULK |
744 GNUNET_GE_FATAL, "pthread_create");
745 return GNUNET_SYSERR;
746 }
747 return GNUNET_OK;
748}
749
750/**
751 * Shutdown the server process (stop receiving inbound traffic). Maybe
752 * restarted later!
753 */
754static int
755api_stop_transport_server ()
756{
757 void *unused;
758
759 smtp_shutdown = GNUNET_YES;
760 GNUNET_thread_stop_sleep (dispatchThread);
761 GNUNET_thread_join (dispatchThread, &unused);
762 return GNUNET_OK;
763}
764
765/**
766 * Convert SMTP hello to an IP address (always fails).
767 */
768static int
769api_hello_to_address (const GNUNET_MessageHello * hello,
770 void **sa, unsigned int *sa_len)
771{
772 return GNUNET_SYSERR;
773}
774
775/**
776 * Always fails.
777 */
778static int
779api_associate (GNUNET_TSession * tsession)
780{
781 return GNUNET_SYSERR; /* SMTP connections can never be associated */
782}
783
784/**
785 * Always succeeds (for now; we should look at adding
786 * frequency limits to SMTP in the future!).
787 */
788static int
789api_test_would_try (GNUNET_TSession * tsession, const unsigned int size,
790 int important)
791{
792 return GNUNET_OK; /* we always try... */
793}
794
795/**
796 * The exported method. Makes the core api available via a global and
797 * returns the smtp transport API.
798 */
799GNUNET_TransportAPI *
800inittransport_smtp (GNUNET_CoreAPIForTransport * core)
801{
802
803
804 unsigned long long mtu;
805 struct sigaction sa;
806
807 coreAPI = core;
808 ectx = core->ectx;
809 if (!GNUNET_GC_have_configuration_value (coreAPI->cfg, "SMTP", "EMAIL"))
810 {
811 GNUNET_GE_LOG (ectx,
812 GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
813 _
814 ("No email-address specified, can not start SMTP transport.\n"));
815 return NULL;
816 }
817 GNUNET_GC_get_configuration_value_number (coreAPI->cfg,
818 "SMTP",
819 "MTU",
820 1200,
821 SMTP_MESSAGE_SIZE,
822 SMTP_MESSAGE_SIZE, &mtu);
823 GNUNET_GC_get_configuration_value_number (coreAPI->cfg,
824 "SMTP",
825 "RATELIMIT",
826 0, 0, 1024 * 1024, &rate_limit);
827 stats = coreAPI->service_request ("stats");
828 if (stats != NULL)
829 {
830 stat_bytesReceived
831 = stats->create (gettext_noop ("# bytes received via SMTP"));
832 stat_bytesSent = stats->create (gettext_noop ("# bytes sent via SMTP"));
833 stat_bytesDropped
834 = stats->create (gettext_noop ("# bytes dropped by SMTP (outgoing)"));
835 }
836 GNUNET_GC_get_configuration_value_filename (coreAPI->cfg,
837 "SMTP",
838 "PIPE",
839 GNUNET_DEFAULT_DAEMON_VAR_DIRECTORY
840 "/smtp-pipe", &pipename);
841 UNLINK (pipename);
842 if (0 != mkfifo (pipename, S_IWUSR | S_IRUSR | S_IWGRP | S_IWOTH))
843 {
844 GNUNET_GE_LOG_STRERROR (ectx,
845 GNUNET_GE_ADMIN | GNUNET_GE_BULK |
846 GNUNET_GE_FATAL, "mkfifo");
847 GNUNET_free (pipename);
848 coreAPI->service_release (stats);
849 stats = NULL;
850 return NULL;
851 }
852 /* we need to allow the mailer program to send us messages;
853 easiest done by giving it write permissions (see Mantis #1142) */
854 if (0 != chmod (pipename, S_IWUSR | S_IRUSR | S_IWGRP | S_IWOTH))
855 GNUNET_GE_LOG_STRERROR (ectx,
856 GNUNET_GE_ADMIN | GNUNET_GE_BULK |
857 GNUNET_GE_WARNING, "chmod");
858 GNUNET_GC_get_configuration_value_string (coreAPI->cfg,
859 "SMTP", "EMAIL", NULL, &email);
860 lock = GNUNET_mutex_create (GNUNET_NO);
861 GNUNET_GC_get_configuration_value_string (coreAPI->cfg,
862 "SMTP",
863 "SERVER",
864 "localhost:25",
865 &smtp_server_name);
866 sa.sa_handler = SIG_IGN;
867 sigemptyset (&sa.sa_mask);
868 sa.sa_flags = 0;
869 sigaction (SIGPIPE, &sa, &old_handler);
870
871 smtpAPI.protocol_number = GNUNET_TRANSPORT_PROTOCOL_NUMBER_SMTP;
872 smtpAPI.mtu = mtu - sizeof (SMTPMessage);
873 smtpAPI.cost = 50;
874 smtpAPI.hello_verify = &api_verify_hello;
875 smtpAPI.hello_create = &api_create_hello;
876 smtpAPI.connect = &api_connect;
877 smtpAPI.send = &api_send;
878 smtpAPI.associate = &api_associate;
879 smtpAPI.disconnect = &api_disconnect;
880 smtpAPI.server_start = &api_start_transport_server;
881 smtpAPI.server_stop = &api_stop_transport_server;
882 smtpAPI.hello_to_address = &api_hello_to_address;
883 smtpAPI.send_now_test = &api_test_would_try;
884 return &smtpAPI;
885}
886
887void
888donetransport_smtp ()
889{
890 sigaction (SIGPIPE, &old_handler, NULL);
891 GNUNET_free (smtp_server_name);
892 if (stats != NULL)
893 {
894 coreAPI->service_release (stats);
895 stats = NULL;
896 }
897 GNUNET_mutex_destroy (lock);
898 lock = NULL;
899 UNLINK (pipename);
900 GNUNET_free (pipename);
901 pipename = NULL;
902 GNUNET_free (email);
903 email = NULL;
904}
905
906/* end of smtp.c */
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c
new file mode 100644
index 000000000..c87056e71
--- /dev/null
+++ b/src/transport/plugin_transport_tcp.c
@@ -0,0 +1,1782 @@
1/*
2 This file is part of GNUnet
3 (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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 2, 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 transport/plugin_transport_tcp.c
23 * @brief Implementation of the TCP transport service
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_hello_lib.h"
29#include "gnunet_network_lib.h"
30#include "gnunet_os_lib.h"
31#include "gnunet_peerinfo_service.h"
32#include "gnunet_protocols.h"
33#include "gnunet_resolver_service.h"
34#include "gnunet_server_lib.h"
35#include "gnunet_service_lib.h"
36#include "gnunet_statistics_service.h"
37#include "gnunet_transport_service.h"
38#include "plugin_transport.h"
39#include "transport.h"
40
41#define DEBUG_TCP GNUNET_NO
42
43/**
44 * After how long do we expire an address that we
45 * learned from another peer if it is not reconfirmed
46 * by anyone?
47 */
48#define LEARNED_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 6)
49
50/**
51 * How long until we give up on transmitting the welcome message?
52 */
53#define WELCOME_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
54
55/**
56 * How long until we give up on transmitting the welcome message?
57 */
58#define HOSTNAME_RESOLVE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
59
60/**
61 * For how many messages back to we keep transmission times?
62 */
63#define ACK_LOG_SIZE 32
64
65/**
66 * Initial handshake message for a session. This header
67 * is followed by the address that the other peer used to
68 * connect to us (so that we may learn it) or the address
69 * that the other peer got from the accept call.
70 */
71struct WelcomeMessage
72{
73 struct GNUNET_MessageHeader header;
74
75 /**
76 * Identity of the node connecting (TCP client)
77 */
78 struct GNUNET_PeerIdentity clientIdentity;
79
80};
81
82
83/**
84 * Encapsulation for normal TCP traffic.
85 */
86struct DataMessage
87{
88 struct GNUNET_MessageHeader header;
89
90 /**
91 * For alignment.
92 */
93 uint32_t reserved GNUNET_PACKED;
94
95 /**
96 * Number of the last message that was received from the other peer.
97 */
98 uint64_t ack_in GNUNET_PACKED;
99
100 /**
101 * Number of this outgoing message.
102 */
103 uint64_t ack_out GNUNET_PACKED;
104
105 /**
106 * How long was sending this ack delayed by the other peer
107 * (estimate). The receiver of this message can use the delay
108 * between sending his message number 'ack' and receiving this ack
109 * minus the delay as an estimate of the round-trip time.
110 */
111 struct GNUNET_TIME_RelativeNBO delay;
112
113};
114
115
116/**
117 * Encapsulation of all of the state of the plugin.
118 */
119struct Plugin;
120
121
122/**
123 * Information kept for each message that is yet to
124 * be transmitted.
125 */
126struct PendingMessage
127{
128
129 /**
130 * This is a linked list.
131 */
132 struct PendingMessage *next;
133
134 /**
135 * The pending message, pointer to the end
136 * of this struct, do not free!
137 */
138 struct GNUNET_MessageHeader *msg;
139
140
141 /**
142 * Continuation function to call once the message
143 * has been sent. Can be NULL if there is no
144 * continuation to call.
145 */
146 GNUNET_TRANSPORT_TransmitContinuation transmit_cont;
147
148 /**
149 * Closure for transmit_cont.
150 */
151 void *transmit_cont_cls;
152
153 /**
154 * Timeout value for the pending message.
155 */
156 struct GNUNET_TIME_Absolute timeout;
157
158 /**
159 * GNUNET_YES if this is a welcome message;
160 * otherwise this should be a DATA message.
161 */
162 int is_welcome;
163
164};
165
166
167/**
168 * Session handle for TCP connections.
169 */
170struct Session
171{
172
173 /**
174 * Stored in a linked list.
175 */
176 struct Session *next;
177
178 /**
179 * Pointer to the global plugin struct.
180 */
181 struct Plugin *plugin;
182
183 /**
184 * The client (used to identify this connection)
185 */
186 struct GNUNET_SERVER_Client *client;
187
188 /**
189 * gnunet-service-transport context for this connection.
190 */
191 struct ReadyList *service_context;
192
193 /**
194 * Messages currently pending for transmission
195 * to this peer, if any.
196 */
197 struct PendingMessage *pending_messages;
198
199 /**
200 * Handle for pending transmission request.
201 */
202 struct GNUNET_NETWORK_TransmitHandle *transmit_handle;
203
204 /**
205 * To whom are we talking to (set to our identity
206 * if we are still waiting for the welcome message)
207 */
208 struct GNUNET_PeerIdentity target;
209
210 /**
211 * At what time did we reset last_received last?
212 */
213 struct GNUNET_TIME_Absolute last_quota_update;
214
215 /**
216 * Address of the other peer if WE initiated the connection
217 * (and hence can be sure what it is), otherwise NULL.
218 */
219 void *connect_addr;
220
221 /**
222 * How many bytes have we received since the "last_quota_update"
223 * timestamp?
224 */
225 uint64_t last_received;
226
227 /**
228 * Our current latency estimate (in ms).
229 */
230 double latency_estimate;
231
232 /**
233 * Time when we generated the last ACK_LOG_SIZE acks.
234 * (the "last" refers to the "out_msg_counter" here)
235 */
236 struct GNUNET_TIME_Absolute gen_time[ACK_LOG_SIZE];
237
238 /**
239 * Our current sequence number.
240 */
241 uint64_t out_msg_counter;
242
243 /**
244 * Highest received incoming sequence number.
245 */
246 uint64_t max_in_msg_counter;
247
248 /**
249 * Number of bytes per ms that this peer is allowed
250 * to send to us.
251 */
252 uint32_t quota_in;
253
254 /**
255 * Length of connect_addr, can be 0.
256 */
257 size_t connect_alen;
258
259 /**
260 * Are we still expecting the welcome message? (GNUNET_YES/GNUNET_NO)
261 */
262 int expecting_welcome;
263
264 /**
265 * Are we still trying to connect?
266 */
267 int still_connecting;
268
269};
270
271
272/**
273 * Encapsulation of all of the state of the plugin.
274 */
275struct Plugin
276{
277 /**
278 * Our environment.
279 */
280 struct GNUNET_TRANSPORT_PluginEnvironment *env;
281
282 /**
283 * The listen socket.
284 */
285 struct GNUNET_NETWORK_SocketHandle *lsock;
286
287 /**
288 * List of open TCP sessions.
289 */
290 struct Session *sessions;
291
292 /**
293 * Handle for the statistics service.
294 */
295 struct GNUNET_STATISTICS_Handle *statistics;
296
297 /**
298 * Handle to the network service.
299 */
300 struct GNUNET_SERVICE_Context *service;
301
302 /**
303 * Handle to the server for this service.
304 */
305 struct GNUNET_SERVER_Handle *server;
306
307 /**
308 * Copy of the handler array where the closures are
309 * set to this struct's instance.
310 */
311 struct GNUNET_SERVER_MessageHandler *handlers;
312
313 /**
314 * ID of task used to update our addresses when one expires.
315 */
316 GNUNET_SCHEDULER_TaskIdentifier address_update_task;
317
318 /**
319 * Port that we are actually listening on.
320 */
321 uint16_t open_port;
322
323 /**
324 * Port that the user said we would have visible to the
325 * rest of the world.
326 */
327 uint16_t adv_port;
328
329};
330
331
332/**
333 * Find the session handle for the given peer.
334 */
335static struct Session *
336find_session_by_target (struct Plugin *plugin,
337 const struct GNUNET_PeerIdentity *target)
338{
339 struct Session *ret;
340
341 ret = plugin->sessions;
342 while ((ret != NULL) &&
343 (0 != memcmp (target,
344 &ret->target, sizeof (struct GNUNET_PeerIdentity))))
345 ret = ret->next;
346 return ret;
347}
348
349
350/**
351 * Find the session handle for the given peer.
352 */
353static struct Session *
354find_session_by_client (struct Plugin *plugin,
355 const struct GNUNET_SERVER_Client *client)
356{
357 struct Session *ret;
358
359 ret = plugin->sessions;
360 while ((ret != NULL) && (client != ret->client))
361 ret = ret->next;
362 return ret;
363}
364
365
366/**
367 * Create a welcome message.
368 */
369static struct PendingMessage *
370create_welcome (size_t addrlen, const void *addr, struct Plugin *plugin)
371{
372 struct PendingMessage *pm;
373 struct WelcomeMessage *welcome;
374
375 pm = GNUNET_malloc (sizeof (struct PendingMessage) +
376 sizeof (struct WelcomeMessage) + addrlen);
377 pm->msg = (struct GNUNET_MessageHeader *) &pm[1];
378 welcome = (struct WelcomeMessage *) &pm[1];
379 welcome->header.size = htons (sizeof (struct WelcomeMessage) + addrlen);
380 welcome->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME);
381 GNUNET_CRYPTO_hash (plugin->env->my_public_key,
382 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
383 &welcome->clientIdentity.hashPubKey);
384 memcpy (&welcome[1], addr, addrlen);
385 pm->timeout = GNUNET_TIME_relative_to_absolute (WELCOME_TIMEOUT);
386 pm->is_welcome = GNUNET_YES;
387 return pm;
388}
389
390
391/**
392 * Create a new session using the specified address
393 * for the welcome message.
394 *
395 * @param plugin us
396 * @param target peer to connect to
397 * @param client client to use
398 * @param addrlen IPv4 or IPv6
399 * @param addr either struct sockaddr_in or struct sockaddr_in6
400 * @return NULL connection failed / invalid address
401 */
402static struct Session *
403create_session (struct Plugin *plugin,
404 const struct GNUNET_PeerIdentity *target,
405 struct GNUNET_SERVER_Client *client,
406 const void *addr, size_t addrlen)
407{
408 struct Session *ret;
409
410 ret = GNUNET_malloc (sizeof (struct Session));
411 ret->plugin = plugin;
412 ret->next = plugin->sessions;
413 plugin->sessions = ret;
414 ret->client = client;
415 ret->target = *target;
416 ret->last_quota_update = GNUNET_TIME_absolute_get ();
417 ret->quota_in = plugin->env->default_quota_in;
418 ret->expecting_welcome = GNUNET_YES;
419 ret->pending_messages = create_welcome (addrlen, addr, plugin);
420 return ret;
421}
422
423
424/**
425 * Create a new session connecting to the specified
426 * target at the specified address.
427 *
428 * @param plugin us
429 * @param target peer to connect to
430 * @param addrlen IPv4 or IPv6
431 * @param addr either struct sockaddr_in or struct sockaddr_in6
432 * @return NULL connection failed / invalid address
433 */
434static struct Session *
435connect_and_create_session (struct Plugin *plugin,
436 const struct GNUNET_PeerIdentity *target,
437 const void *addr, size_t addrlen)
438{
439 struct GNUNET_SERVER_Client *client;
440 struct GNUNET_NETWORK_SocketHandle *conn;
441 struct Session *session;
442 int af;
443 char buf[INET6_ADDRSTRLEN];
444 uint16_t port;
445
446 session = plugin->sessions;
447 while (session != NULL)
448 {
449 if ((0 == memcmp (target,
450 &session->target,
451 sizeof (struct GNUNET_PeerIdentity))) &&
452 (session->connect_alen == addrlen) &&
453 (0 == memcmp (session->connect_addr, addr, addrlen)))
454 return session; /* already exists! */
455 session = session->next;
456 }
457
458 if (addrlen == sizeof (struct sockaddr_in))
459 {
460 af = AF_INET;
461 inet_ntop (af,
462 &((struct sockaddr_in *) addr)->sin_addr, buf, sizeof (buf));
463 port = ntohs (((struct sockaddr_in *) addr)->sin_port);
464 }
465 else if (addrlen == sizeof (struct sockaddr_in6))
466 {
467 af = AF_INET6;
468 inet_ntop (af,
469 &((struct sockaddr_in6 *) addr)->sin6_addr,
470 buf, sizeof (buf));
471 port = ntohs (((struct sockaddr_in6 *) addr)->sin6_port);
472 }
473 else
474 {
475 GNUNET_break_op (0);
476 return NULL; /* invalid address */
477 }
478 conn = GNUNET_NETWORK_socket_create_from_sockaddr (plugin->env->sched,
479 af,
480 addr,
481 addrlen,
482 GNUNET_SERVER_MAX_MESSAGE_SIZE);
483 if (conn == NULL)
484 {
485#if DEBUG_TCP
486 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
487 "tcp",
488 "Failed to create connection to peer at `%s:%u'.\n",
489 buf, port);
490#endif
491 return NULL;
492 }
493 client = GNUNET_SERVER_connect_socket (plugin->server, conn);
494 GNUNET_assert (client != NULL);
495 session = create_session (plugin, target, client, addr, addrlen);
496 session->connect_alen = addrlen;
497 session->connect_addr = GNUNET_malloc (addrlen);
498 memcpy (session->connect_addr, addr, addrlen);
499#if DEBUG_TCP
500 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
501 "tcp",
502 "Creating new session %p with `%s:%u' based on `%s' request.\n",
503 session, buf, port, "send_to");
504#endif
505 return session;
506}
507
508
509/**
510 * If we have pending messages, ask the server to
511 * transmit them (schedule the respective tasks, etc.)
512 *
513 * @param session for which session should we do this
514 */
515static void process_pending_messages (struct Session *session);
516
517
518/**
519 * Function called to notify a client about the socket
520 * begin ready to queue more data. "buf" will be
521 * NULL and "size" zero if the socket was closed for
522 * writing in the meantime.
523 *
524 * @param cls closure
525 * @param size number of bytes available in buf
526 * @param buf where the callee should write the message
527 * @return number of bytes written to buf
528 */
529static size_t
530do_transmit (void *cls, size_t size, void *buf)
531{
532 struct Session *session = cls;
533 struct PendingMessage *pm;
534 char *cbuf;
535 uint16_t msize;
536 size_t ret;
537 struct DataMessage *dm;
538
539 session->transmit_handle = NULL;
540 if (buf == NULL)
541 {
542#if DEBUG_TCP
543 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
544 "tcp", "Timeout trying to transmit\n");
545#endif
546 /* timeout */
547 while (NULL != (pm = session->pending_messages))
548 {
549 session->pending_messages = pm->next;
550 if (pm->transmit_cont != NULL)
551 pm->transmit_cont (pm->transmit_cont_cls,
552 session->service_context,
553 &session->target, GNUNET_SYSERR);
554 GNUNET_free (pm);
555 }
556 return 0;
557 }
558 ret = 0;
559 cbuf = buf;
560 while (NULL != (pm = session->pending_messages))
561 {
562 if (pm->is_welcome)
563 {
564 if (size < (msize = htons (pm->msg->size)))
565 break;
566 memcpy (cbuf, pm->msg, msize);
567 cbuf += msize;
568 ret += msize;
569 size -= msize;
570 }
571 else
572 {
573 if (size <
574 sizeof (struct DataMessage) + (msize = htons (pm->msg->size)))
575 break;
576 dm = (struct DataMessage *) cbuf;
577 dm->header.size = htons (sizeof (struct DataMessage) + msize);
578 dm->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_DATA);
579 dm->ack_out = GNUNET_htonll (++session->out_msg_counter);
580 dm->ack_in = GNUNET_htonll (session->max_in_msg_counter);
581 cbuf += sizeof (struct DataMessage);
582 ret += sizeof (struct DataMessage);
583 size -= sizeof (struct DataMessage);
584 memcpy (cbuf, pm->msg, msize);
585 cbuf += msize;
586 ret += msize;
587 size -= msize;
588 }
589 session->pending_messages = pm->next;
590 if (pm->transmit_cont != NULL)
591 pm->transmit_cont (pm->transmit_cont_cls,
592 session->service_context,
593 &session->target, GNUNET_OK);
594 GNUNET_free (pm);
595 session->gen_time[session->out_msg_counter % ACK_LOG_SIZE]
596 = GNUNET_TIME_absolute_get ();
597 }
598 process_pending_messages (session);
599#if DEBUG_TCP || 1
600 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
601 "tcp", "Transmitting %u bytes\n", ret);
602#endif
603 return ret;
604}
605
606
607/**
608 * If we have pending messages, ask the server to
609 * transmit them (schedule the respective tasks, etc.)
610 *
611 * @param session for which session should we do this
612 */
613static void
614process_pending_messages (struct Session *session)
615{
616 GNUNET_assert (session->client != NULL);
617 if (session->pending_messages == NULL)
618 return;
619 if (session->transmit_handle != NULL)
620 return;
621 session->transmit_handle
622 = GNUNET_SERVER_notify_transmit_ready (session->client,
623 htons (session->pending_messages->
624 msg->size) +
625 (session->pending_messages->
626 is_welcome ? 0 : sizeof (struct
627 DataMessage)),
628 GNUNET_TIME_absolute_get_remaining
629 (session->pending_messages[0].
630 timeout), &do_transmit, session);
631}
632
633
634/**
635 * Function that can be used by the transport service to transmit
636 * a message using the plugin using a fresh connection (even if
637 * we already have a connection to this peer, this function is
638 * required to establish a new one).
639 *
640 * @param cls closure
641 * @param target who should receive this message
642 * @param msg1 first message to transmit
643 * @param msg2 second message to transmit (can be NULL)
644 * @param timeout how long should we try to transmit these?
645 * @param addrlen length of the address
646 * @param addr the address
647 * @return session if the transmission has been scheduled
648 * NULL if the address format is invalid
649 */
650static void *
651tcp_plugin_send_to (void *cls,
652 const struct GNUNET_PeerIdentity *target,
653 const struct GNUNET_MessageHeader *msg1,
654 const struct GNUNET_MessageHeader *msg2,
655 struct GNUNET_TIME_Relative timeout,
656 const void *addr, size_t addrlen)
657{
658 struct Plugin *plugin = cls;
659 struct Session *session;
660 struct PendingMessage *pl;
661 struct PendingMessage *pm;
662
663 session = connect_and_create_session (plugin, target, addr, addrlen);
664 if (session == NULL)
665 {
666#if DEBUG_TCP
667 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
668 "tcp", "Failed to create fresh session.\n");
669#endif
670 return NULL;
671 }
672 pl = NULL;
673 if (msg2 != NULL)
674 {
675 pm = GNUNET_malloc (sizeof (struct PendingMessage) +
676 ntohs (msg2->size));
677 pm->msg = (struct GNUNET_MessageHeader *) &pm[1];
678 memcpy (pm->msg, msg2, ntohs (msg2->size));
679 pm->timeout = GNUNET_TIME_relative_to_absolute (timeout);
680 pm->is_welcome = GNUNET_NO;
681 pl = pm;
682 }
683 if (msg1 != NULL)
684 {
685 pm = GNUNET_malloc (sizeof (struct PendingMessage) +
686 ntohs (msg1->size));
687 pm->msg = (struct GNUNET_MessageHeader *) &pm[1];
688 memcpy (pm->msg, msg1, ntohs (msg1->size));
689 pm->timeout = GNUNET_TIME_relative_to_absolute (timeout);
690 pm->is_welcome = GNUNET_NO;
691 pm->next = pl;
692 pl = pm;
693 }
694 /* append */
695 if (session->pending_messages != NULL)
696 {
697 pm = session->pending_messages;
698 while (pm->next != NULL)
699 pm = pm->next;
700 pm->next = pl;
701 }
702 else
703 {
704 session->pending_messages = pl;
705 }
706 process_pending_messages (session);
707 return session;
708}
709
710
711/**
712 * Functions with this signature are called whenever we need
713 * to close a session due to a disconnect or failure to
714 * establish a connection.
715 *
716 * @param session session to close down
717 */
718static void
719disconnect_session (struct Session *session)
720{
721 struct Session *prev;
722 struct Session *pos;
723 struct PendingMessage *pm;
724
725#if DEBUG_TCP
726 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
727 "tcp",
728 "Disconnecting from other peer (session %p).\n", session);
729#endif
730 /* remove from session list */
731 prev = NULL;
732 pos = session->plugin->sessions;
733 while (pos != session)
734 {
735 prev = pos;
736 pos = pos->next;
737 }
738 if (prev == NULL)
739 session->plugin->sessions = session->next;
740 else
741 prev->next = session->next;
742 /* clean up state */
743 if (session->client != NULL)
744 {
745#if DEBUG_TCP
746 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
747 "Disconnecting from client address %p\n", session->client);
748#endif
749 GNUNET_SERVER_client_drop (session->client);
750 session->client = NULL;
751 }
752 if (session->transmit_handle != NULL)
753 {
754 GNUNET_NETWORK_notify_transmit_ready_cancel (session->transmit_handle);
755 session->transmit_handle = NULL;
756 }
757 while (NULL != (pm = session->pending_messages))
758 {
759 session->pending_messages = pm->next;
760 if (NULL != pm->transmit_cont)
761 pm->transmit_cont (pm->transmit_cont_cls,
762 session->service_context,
763 &session->target, GNUNET_SYSERR);
764 GNUNET_free (pm);
765 }
766 /* notify transport service about disconnect */
767 session->plugin->env->receive (session->plugin->env->cls,
768 session,
769 session->service_context,
770 GNUNET_TIME_UNIT_ZERO,
771 &session->target, NULL);
772 GNUNET_free_non_null (session->connect_addr);
773 GNUNET_free (session);
774}
775
776
777/**
778 * Iterator callback to go over all addresses. If we get
779 * a TCP address, increment the counter
780 *
781 * @param cls closure, points to the counter
782 * @param tname name of the transport
783 * @param expiration expiration time
784 * @param addr the address
785 * @param addrlen length of the address
786 * @return GNUNET_OK to keep the address,
787 * GNUNET_NO to delete it from the HELLO
788 * GNUNET_SYSERR to stop iterating (but keep current address)
789 */
790static int
791count_tcp_addresses (void *cls,
792 const char *tname,
793 struct GNUNET_TIME_Absolute expiration,
794 const void *addr, size_t addrlen)
795{
796 unsigned int *counter = cls;
797
798 if (0 != strcmp (tname, "tcp"))
799 return GNUNET_OK; /* not one of ours */
800 (*counter)++;
801 return GNUNET_OK; /* failed to connect */
802}
803
804
805struct ConnectContext
806{
807 struct Plugin *plugin;
808
809 struct GNUNET_NETWORK_SocketHandle *sa;
810
811 struct PendingMessage *welcome;
812
813 unsigned int pos;
814};
815
816
817/**
818 * Iterator callback to go over all addresses. If we get
819 * the "pos" TCP address, try to connect to it.
820 *
821 * @param cls closure
822 * @param tname name of the transport
823 * @param expiration expiration time
824 * @param addrlen length of the address
825 * @param addr the address
826 * @return GNUNET_OK to keep the address,
827 * GNUNET_NO to delete it from the HELLO
828 * GNUNET_SYSERR to stop iterating (but keep current address)
829 */
830static int
831try_connect_to_address (void *cls,
832 const char *tname,
833 struct GNUNET_TIME_Absolute expiration,
834 const void *addr, size_t addrlen)
835{
836 struct ConnectContext *cc = cls;
837 int af;
838
839 if (0 != strcmp (tname, "tcp"))
840 return GNUNET_OK; /* not one of ours */
841 if (sizeof (struct sockaddr_in) == addrlen)
842 af = AF_INET;
843 else if (sizeof (struct sockaddr_in6) == addrlen)
844 af = AF_INET6;
845 else
846 {
847 /* not a valid address */
848 GNUNET_break (0);
849 return GNUNET_NO;
850 }
851 if (0 == cc->pos--)
852 {
853 cc->welcome = create_welcome (addrlen, addr, cc->plugin);
854 cc->sa =
855 GNUNET_NETWORK_socket_create_from_sockaddr (cc->plugin->env->sched,
856 af, addr, addrlen,
857 GNUNET_SERVER_MAX_MESSAGE_SIZE);
858#if DEBUG_TCP
859 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
860 "tcp", "Connected to other peer.\n");
861#endif
862 return GNUNET_SYSERR;
863 }
864 return GNUNET_OK; /* failed to connect */
865}
866
867
868/**
869 * Type of an iterator over the hosts. Note that each
870 * host will be called with each available protocol.
871 *
872 * @param cls closure
873 * @param peer id of the peer, NULL for last call
874 * @param hello hello message for the peer (can be NULL)
875 * @param trust amount of trust we have in the peer
876 */
877static void
878session_try_connect (void *cls,
879 const struct GNUNET_PeerIdentity *peer,
880 const struct GNUNET_HELLO_Message *hello, uint32_t trust)
881{
882 struct Session *session = cls;
883 unsigned int count;
884 struct ConnectContext cctx;
885 struct PendingMessage *pm;
886
887 if (peer == NULL)
888 {
889 /* last call, destroy session if we are still not
890 connected */
891 if (session->still_connecting == GNUNET_NO)
892 {
893#if DEBUG_TCP
894 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
895 "tcp",
896 "Connected to other peer, now processing messages.\n");
897#endif
898 process_pending_messages (session);
899 }
900 else
901 {
902#if DEBUG_TCP
903 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
904 "tcp",
905 "Failed to connect to other peer, now closing session.\n");
906#endif
907 disconnect_session (session);
908 }
909 return;
910 }
911 if ((hello == NULL) || (session->client != NULL))
912 {
913 GNUNET_break (0); /* should this ever happen!? */
914 return;
915 }
916 count = 0;
917 GNUNET_HELLO_iterate_addresses (hello,
918 GNUNET_NO, &count_tcp_addresses, &count);
919 if (count == 0)
920 {
921#if DEBUG_TCP
922 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
923 "tcp",
924 "Asked to connect, but have no addresses to try.\n");
925#endif
926 return;
927 }
928 cctx.plugin = session->plugin;
929 cctx.sa = NULL;
930 cctx.welcome = NULL;
931 cctx.pos = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, count);
932 GNUNET_HELLO_iterate_addresses (hello,
933 GNUNET_NO, &try_connect_to_address, &cctx);
934 if (cctx.sa == NULL)
935 {
936#if DEBUG_TCP
937 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
938 "tcp",
939 "Asked to connect, but all addresses failed.\n");
940#endif
941 GNUNET_free_non_null (cctx.welcome);
942 return;
943 }
944 session->client = GNUNET_SERVER_connect_socket (session->plugin->server,
945 cctx.sa);
946#if DEBUG_TCP
947 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
948 "Connected getting client address %p\n", session->client);
949#endif
950 if (session->client == NULL)
951 {
952 GNUNET_break (0); /* how could this happen? */
953 GNUNET_free_non_null (cctx.welcome);
954 return;
955 }
956 pm = cctx.welcome;
957 /* prepend (!) */
958 pm->next = session->pending_messages;
959 session->pending_messages = pm;
960 session->still_connecting = GNUNET_NO;
961#if DEBUG_TCP
962 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
963 "tcp",
964 "Connected to other peer, now sending `%s' message.\n",
965 "WELCOME");
966#endif
967}
968
969
970/**
971 * Function that can be used by the transport service to transmit
972 * a message using the plugin.
973 *
974 * @param cls closure
975 * @param plugin_context value we were asked to pass to this plugin
976 * to respond to the given peer (use is optional,
977 * but may speed up processing), can be NULL
978 * @param service_context value passed to the transport-service
979 * to identify the neighbour
980 * @param target who should receive this message
981 * @param msg the message to transmit
982 * @param cont continuation to call once the message has
983 * been transmitted (or if the transport is ready
984 * for the next transmission call; or if the
985 * peer disconnected...)
986 * @param cont_cls closure for cont
987 * @return plugin_context that should be used next time for
988 * sending messages to the specified peer
989 */
990static void *
991tcp_plugin_send (void *cls,
992 void *plugin_context,
993 struct ReadyList *service_context,
994 const struct GNUNET_PeerIdentity *target,
995 const struct GNUNET_MessageHeader *msg,
996 struct GNUNET_TIME_Relative timeout,
997 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
998{
999 struct Plugin *plugin = cls;
1000 struct Session *session = plugin_context;
1001 struct PendingMessage *pm;
1002 struct PendingMessage *pme;
1003
1004 if (session == NULL)
1005 session = find_session_by_target (plugin, target);
1006 pm = GNUNET_malloc (sizeof (struct PendingMessage) + ntohs (msg->size));
1007 pm->msg = (struct GNUNET_MessageHeader *) &pm[1];
1008 memcpy (pm->msg, msg, ntohs (msg->size));
1009 pm->timeout = GNUNET_TIME_relative_to_absolute (timeout);
1010 pm->transmit_cont = cont;
1011 pm->transmit_cont_cls = cont_cls;
1012 if (session == NULL)
1013 {
1014 session = GNUNET_malloc (sizeof (struct Session));
1015#if DEBUG_TCP
1016 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1017 "tcp",
1018 "Asked to transmit, creating fresh session %p.\n",
1019 session);
1020#endif
1021 session->next = plugin->sessions;
1022 plugin->sessions = session;
1023 session->plugin = plugin;
1024 session->target = *target;
1025 session->last_quota_update = GNUNET_TIME_absolute_get ();
1026 session->quota_in = plugin->env->default_quota_in;
1027 session->expecting_welcome = GNUNET_YES;
1028 session->still_connecting = GNUNET_YES;
1029 session->pending_messages = pm;
1030 GNUNET_PEERINFO_for_all (plugin->env->cfg,
1031 plugin->env->sched,
1032 target,
1033 0, timeout, &session_try_connect, session);
1034 return session;
1035 }
1036 GNUNET_assert (session != NULL);
1037 GNUNET_assert (session->still_connecting == GNUNET_NO);
1038 /* append pm to pending_messages list */
1039 pme = session->pending_messages;
1040 if (pme == NULL)
1041 {
1042 session->pending_messages = pm;
1043 }
1044 else
1045 {
1046 while (NULL != pme->next)
1047 pme = pme->next;
1048 pme->next = pm;
1049 }
1050#if DEBUG_TCP
1051 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1052 "tcp", "Asked to transmit, added message to list.\n");
1053#endif
1054 process_pending_messages (session);
1055 return session;
1056}
1057
1058
1059
1060/**
1061 * Function that can be called to force a disconnect from the
1062 * specified neighbour. This should also cancel all previously
1063 * scheduled transmissions. Obviously the transmission may have been
1064 * partially completed already, which is OK. The plugin is supposed
1065 * to close the connection (if applicable) and no longer call the
1066 * transmit continuation(s).
1067 *
1068 * Finally, plugin MUST NOT call the services's receive function to
1069 * notify the service that the connection to the specified target was
1070 * closed after a getting this call.
1071 *
1072 * @param cls closure
1073 * @param plugin_context value we were asked to pass to this plugin
1074 * to respond to the given peer (use is optional,
1075 * but may speed up processing), can be NULL (if
1076 * NULL was returned from the transmit function)
1077 * @param service_context must correspond to the service context
1078 * of the corresponding Transmit call; the plugin should
1079 * not cancel a send call made with a different service
1080 * context pointer! Never NULL.
1081 * @param target peer for which the last transmission is
1082 * to be cancelled
1083 */
1084static void
1085tcp_plugin_cancel (void *cls,
1086 void *plugin_context,
1087 struct ReadyList *service_context,
1088 const struct GNUNET_PeerIdentity *target)
1089{
1090 struct Plugin *plugin = cls;
1091 struct PendingMessage *pm;
1092 struct Session *session;
1093 struct Session *next;
1094
1095 session = plugin->sessions;
1096 while (session != NULL)
1097 {
1098 next = session->next;
1099 if (0 == memcmp (target,
1100 &session->target, sizeof (struct GNUNET_PeerIdentity)))
1101 {
1102 pm = session->pending_messages;
1103 while (pm != NULL)
1104 {
1105 pm->transmit_cont = NULL;
1106 pm->transmit_cont_cls = NULL;
1107 pm = pm->next;
1108 }
1109 session->service_context = NULL;
1110 GNUNET_SERVER_client_disconnect (session->client);
1111 /* rest of the clean-up of the session will be done as part of
1112 disconnect_notify which should be triggered any time now */
1113 }
1114 session = next;
1115 }
1116}
1117
1118
1119struct PrettyPrinterContext
1120{
1121 GNUNET_TRANSPORT_AddressStringCallback asc;
1122 void *asc_cls;
1123 uint16_t port;
1124};
1125
1126
1127/**
1128 * Append our port and forward the result.
1129 */
1130static void
1131append_port (void *cls, const char *hostname)
1132{
1133 struct PrettyPrinterContext *ppc = cls;
1134 char *ret;
1135
1136 if (hostname == NULL)
1137 {
1138 ppc->asc (ppc->asc_cls, NULL);
1139 GNUNET_free (ppc);
1140 return;
1141 }
1142 GNUNET_asprintf (&ret, "%s:%d", hostname, ppc->port);
1143 ppc->asc (ppc->asc_cls, ret);
1144 GNUNET_free (ret);
1145}
1146
1147
1148/**
1149 * Convert the transports address to a nice, human-readable
1150 * format.
1151 *
1152 * @param cls closure
1153 * @param name name of the transport that generated the address
1154 * @param addr one of the addresses of the host, NULL for the last address
1155 * the specific address format depends on the transport
1156 * @param addrlen length of the address
1157 * @param numeric should (IP) addresses be displayed in numeric form?
1158 * @param timeout after how long should we give up?
1159 * @param asc function to call on each string
1160 * @param asc_cls closure for asc
1161 */
1162static void
1163tcp_plugin_address_pretty_printer (void *cls,
1164 const char *type,
1165 const void *addr,
1166 size_t addrlen,
1167 int numeric,
1168 struct GNUNET_TIME_Relative timeout,
1169 GNUNET_TRANSPORT_AddressStringCallback asc,
1170 void *asc_cls)
1171{
1172 struct Plugin *plugin = cls;
1173 const struct sockaddr_in *v4;
1174 const struct sockaddr_in6 *v6;
1175 struct PrettyPrinterContext *ppc;
1176
1177 if ((addrlen != sizeof (struct sockaddr_in)) &&
1178 (addrlen != sizeof (struct sockaddr_in6)))
1179 {
1180 /* invalid address */
1181 GNUNET_break_op (0);
1182 asc (asc_cls, NULL);
1183 return;
1184 }
1185 ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext));
1186 ppc->asc = asc;
1187 ppc->asc_cls = asc_cls;
1188 if (addrlen == sizeof (struct sockaddr_in))
1189 {
1190 v4 = (const struct sockaddr_in *) addr;
1191 ppc->port = ntohs (v4->sin_port);
1192 }
1193 else
1194 {
1195 v6 = (const struct sockaddr_in6 *) addr;
1196 ppc->port = ntohs (v6->sin6_port);
1197
1198 }
1199 GNUNET_RESOLVER_hostname_get (plugin->env->sched,
1200 plugin->env->cfg,
1201 addr,
1202 addrlen,
1203 !numeric, timeout, &append_port, ppc);
1204}
1205
1206
1207/**
1208 * Update the last-received and bandwidth quota values
1209 * for this session.
1210 *
1211 * @param session session to update
1212 * @param force set to GNUNET_YES if we should update even
1213 * though the minimum refresh time has not yet expired
1214 */
1215static void
1216update_quota (struct Session *session, int force)
1217{
1218 struct GNUNET_TIME_Absolute now;
1219 unsigned long long delta;
1220 unsigned long long total_allowed;
1221 unsigned long long total_remaining;
1222
1223 now = GNUNET_TIME_absolute_get ();
1224 delta = now.value - session->last_quota_update.value;
1225 if ((delta < MIN_QUOTA_REFRESH_TIME) && (!force))
1226 return; /* too early, not enough data */
1227
1228 total_allowed = session->quota_in * delta;
1229 if (total_allowed > session->last_received)
1230 {
1231 /* got less than acceptable */
1232 total_remaining = total_allowed - session->last_received;
1233 session->last_received = 0;
1234 delta = total_remaining / session->quota_in; /* bonus seconds */
1235 if (delta > MAX_BANDWIDTH_CARRY)
1236 delta = MAX_BANDWIDTH_CARRY; /* limit amount of carry-over */
1237 }
1238 else
1239 {
1240 /* got more than acceptable */
1241 total_remaining = 0;
1242 session->last_received -= total_allowed;
1243 delta = 0;
1244 }
1245 session->last_quota_update.value = now.value - delta;
1246}
1247
1248
1249/**
1250 * Set a quota for receiving data from the given peer; this is a
1251 * per-transport limit. The transport should limit its read/select
1252 * calls to stay below the quota (in terms of incoming data).
1253 *
1254 * @param cls closure
1255 * @param peer the peer for whom the quota is given
1256 * @param quota_in quota for receiving/sending data in bytes per ms
1257 */
1258static void
1259tcp_plugin_set_receive_quota (void *cls,
1260 const struct GNUNET_PeerIdentity *target,
1261 uint32_t quota_in)
1262{
1263 struct Plugin *plugin = cls;
1264 struct Session *session;
1265
1266 session = find_session_by_target (plugin, target);
1267 if (session->quota_in != quota_in)
1268 {
1269 update_quota (session, GNUNET_YES);
1270 if (session->quota_in > quota_in)
1271 session->last_quota_update = GNUNET_TIME_absolute_get ();
1272 session->quota_in = quota_in;
1273 }
1274}
1275
1276
1277/**
1278 * Check if the given port is plausible (must be either
1279 * our listen port or our advertised port). If it is
1280 * neither, we return one of these two ports at random.
1281 *
1282 * @return either in_port or a more plausible port
1283 */
1284static uint16_t
1285check_port (struct Plugin *plugin, uint16_t in_port)
1286{
1287 if ((in_port == plugin->adv_port) || (in_port == plugin->open_port))
1288 return in_port;
1289 return (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1290 2) == 0)
1291 ? plugin->open_port : plugin->adv_port;
1292}
1293
1294
1295/**
1296 * Another peer has suggested an address for this
1297 * peer and transport plugin. Check that this could be a valid
1298 * address. If so, consider adding it to the list
1299 * of addresses.
1300 *
1301 * @param cls closure
1302 * @param addr pointer to the address
1303 * @param addrlen length of addr
1304 * @return GNUNET_OK if this is a plausible address for this peer
1305 * and transport
1306 */
1307static int
1308tcp_plugin_address_suggested (void *cls, const void *addr, size_t addrlen)
1309{
1310 struct Plugin *plugin = cls;
1311 char buf[sizeof (struct sockaddr_in6)];
1312 struct sockaddr_in *v4;
1313 struct sockaddr_in6 *v6;
1314 char dst[INET6_ADDRSTRLEN];
1315 uint16_t port;
1316
1317 if ((addrlen != sizeof (struct sockaddr_in)) &&
1318 (addrlen != sizeof (struct sockaddr_in6)))
1319 {
1320 GNUNET_break_op (0);
1321 return GNUNET_SYSERR;
1322 }
1323 memcpy (buf, addr, sizeof (struct sockaddr_in6));
1324 if (addrlen == sizeof (struct sockaddr_in))
1325 {
1326 v4 = (struct sockaddr_in *) buf;
1327 v4->sin_port = htons (check_port (plugin, ntohs (v4->sin_port)));
1328 inet_ntop (AF_INET, &v4->sin_addr, dst, sizeof (dst));
1329 port = ntohs (v4->sin_port);
1330 }
1331 else
1332 {
1333 v6 = (struct sockaddr_in6 *) buf;
1334 v6->sin6_port = htons (check_port (plugin, ntohs (v6->sin6_port)));
1335 inet_ntop (AF_INET6, &v6->sin6_addr, dst, sizeof (dst));
1336 port = ntohs (v6->sin6_port);
1337 }
1338#if DEBUG_TCP
1339 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1340 "tcp",
1341 "Informing transport service about my address `%s:%u'.\n",
1342 dst, port);
1343#endif
1344 plugin->env->notify_address (plugin->env->cls,
1345 "tcp",
1346 buf, addrlen, LEARNED_ADDRESS_EXPIRATION);
1347 return GNUNET_OK;
1348}
1349
1350
1351/**
1352 * We've received a welcome from this peer via TCP.
1353 * Possibly create a fresh client record and send back
1354 * our welcome.
1355 *
1356 * @param cls closure
1357 * @param server the server handling the message
1358 * @param client identification of the client
1359 * @param message the actual message
1360 */
1361static void
1362handle_tcp_welcome (void *cls,
1363 struct GNUNET_SERVER_Handle *server,
1364 struct GNUNET_SERVER_Client *client,
1365 const struct GNUNET_MessageHeader *message)
1366{
1367 struct Plugin *plugin = cls;
1368 struct Session *session_c;
1369 const struct WelcomeMessage *wm;
1370 uint16_t msize;
1371 uint32_t addrlen;
1372 size_t alen;
1373 void *vaddr;
1374 const struct sockaddr *addr;
1375
1376#if DEBUG_TCP
1377 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1378 "tcp",
1379 "Received `%s' message from %p.\n", "WELCOME", client);
1380#endif
1381 msize = ntohs (message->size);
1382 if (msize < sizeof (struct WelcomeMessage))
1383 {
1384 GNUNET_break_op (0);
1385 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1386 return;
1387 }
1388 wm = (const struct WelcomeMessage *) message;
1389 session_c = find_session_by_client (plugin, client);
1390 if (session_c == NULL)
1391 {
1392 vaddr = NULL;
1393 GNUNET_SERVER_client_get_address (client, &vaddr, &alen);
1394 GNUNET_SERVER_client_keep (client);
1395 session_c = create_session (plugin,
1396 &wm->clientIdentity, client, vaddr, alen);
1397#if DEBUG_TCP
1398 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1399 "tcp",
1400 "Creating new session %p for incoming `%s' message.\n",
1401 session_c, "WELCOME");
1402#endif
1403 GNUNET_free_non_null (vaddr);
1404 process_pending_messages (session_c);
1405 }
1406 session_c->expecting_welcome = GNUNET_NO;
1407 if (0 < (addrlen = msize - sizeof (struct WelcomeMessage)))
1408 {
1409 addr = (const struct sockaddr *) &wm[1];
1410 tcp_plugin_address_suggested (plugin, addr, addrlen);
1411 }
1412 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1413}
1414
1415
1416/**
1417 * Calculate how long we should delay reading from the TCP socket to
1418 * ensure that we stay within our bandwidth limits (push back).
1419 *
1420 * @param session for which client should this be calculated
1421 */
1422static struct GNUNET_TIME_Relative
1423calculate_throttle_delay (struct Session *session)
1424{
1425 struct GNUNET_TIME_Relative ret;
1426 struct GNUNET_TIME_Absolute now;
1427 uint64_t del;
1428 uint64_t avail;
1429 uint64_t excess;
1430
1431 now = GNUNET_TIME_absolute_get ();
1432 del = now.value - session->last_quota_update.value;
1433 if (del > MAX_BANDWIDTH_CARRY)
1434 {
1435 update_quota (session, GNUNET_YES);
1436 del = now.value - session->last_quota_update.value;
1437 GNUNET_assert (del <= MAX_BANDWIDTH_CARRY);
1438 }
1439 if (session->quota_in == 0)
1440 session->quota_in = 1; /* avoid divison by zero */
1441 avail = del * session->quota_in;
1442 if (avail > session->last_received)
1443 return GNUNET_TIME_UNIT_ZERO; /* can receive right now */
1444 excess = session->last_received - avail;
1445 ret.value = excess / session->quota_in;
1446 return ret;
1447}
1448
1449
1450/**
1451 * Task to signal the server that we can continue
1452 * receiving from the TCP client now.
1453 */
1454static void
1455delayed_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1456{
1457 struct Session *session = cls;
1458 GNUNET_SERVER_receive_done (session->client, GNUNET_OK);
1459}
1460
1461
1462/**
1463 * We've received data for this peer via TCP. Unbox,
1464 * compute latency and forward.
1465 *
1466 * @param cls closure
1467 * @param server the server handling the message
1468 * @param client identification of the client
1469 * @param message the actual message
1470 */
1471static void
1472handle_tcp_data (void *cls,
1473 struct GNUNET_SERVER_Handle *server,
1474 struct GNUNET_SERVER_Client *client,
1475 const struct GNUNET_MessageHeader *message)
1476{
1477 struct Plugin *plugin = cls;
1478 struct Session *session;
1479 const struct DataMessage *dm;
1480 uint16_t msize;
1481 const struct GNUNET_MessageHeader *msg;
1482 struct GNUNET_TIME_Relative latency;
1483 struct GNUNET_TIME_Absolute ttime;
1484 struct GNUNET_TIME_Absolute now;
1485 struct GNUNET_TIME_Relative delay;
1486 uint64_t ack_in;
1487
1488#if DEBUG_TCP
1489 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1490 "tcp", "Receiving data from other peer.\n");
1491#endif
1492 msize = ntohs (message->size);
1493 if ((msize <
1494 sizeof (struct DataMessage) + sizeof (struct GNUNET_MessageHeader)))
1495 {
1496 GNUNET_break_op (0);
1497 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1498 return;
1499 }
1500 session = find_session_by_client (plugin, client);
1501 if ((NULL == session) || (GNUNET_YES == session->expecting_welcome))
1502 {
1503 GNUNET_break_op (0);
1504 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1505 return;
1506 }
1507 dm = (const struct DataMessage *) message;
1508 session->max_in_msg_counter = GNUNET_MAX (session->max_in_msg_counter,
1509 GNUNET_ntohll (dm->ack_out));
1510 msg = (const struct GNUNET_MessageHeader *) &dm[1];
1511 if (msize != sizeof (struct DataMessage) + ntohs (msg->size))
1512 {
1513 GNUNET_break_op (0);
1514 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1515 return;
1516 }
1517 /* estimate latency */
1518 ack_in = GNUNET_ntohll (dm->ack_in);
1519 if ((ack_in <= session->out_msg_counter) &&
1520 (session->out_msg_counter - ack_in < ACK_LOG_SIZE))
1521 {
1522 delay = GNUNET_TIME_relative_ntoh (dm->delay);
1523 ttime = session->gen_time[ack_in % ACK_LOG_SIZE];
1524 now = GNUNET_TIME_absolute_get ();
1525 if (delay.value > now.value - ttime.value)
1526 delay.value = 0; /* not plausible */
1527 /* update (round-trip) latency using ageing; we
1528 use 7:1 so that we can reasonably quickly react
1529 to changes, but not so fast that latency is largely
1530 jitter... */
1531 session->latency_estimate
1532 = ((7 * session->latency_estimate) +
1533 (now.value - ttime.value - delay.value)) / 8;
1534 }
1535 latency.value = (uint64_t) session->latency_estimate;
1536 /* deliver on */
1537#if DEBUG_TCP
1538 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1539 "tcp",
1540 "Forwarding data of type %u to transport service.\n",
1541 ntohs (msg->type));
1542#endif
1543 session->service_context
1544 = plugin->env->receive (plugin->env->cls,
1545 session,
1546 session->service_context,
1547 latency, &session->target, msg);
1548 /* update bandwidth used */
1549 session->last_received += msize;
1550 update_quota (session, GNUNET_NO);
1551
1552 delay = calculate_throttle_delay (session);
1553 if (delay.value == 0)
1554 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1555 else
1556 GNUNET_SCHEDULER_add_delayed (session->plugin->env->sched,
1557 GNUNET_NO,
1558 GNUNET_SCHEDULER_PRIORITY_HIGH,
1559 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1560 delay, &delayed_done, session);
1561}
1562
1563
1564/**
1565 * Handlers for the various TCP messages.
1566 */
1567static struct GNUNET_SERVER_MessageHandler my_handlers[] = {
1568 {&handle_tcp_welcome, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME, 0},
1569 {&handle_tcp_data, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_DATA, 0},
1570 {NULL, NULL, 0, 0}
1571};
1572
1573
1574static void
1575create_tcp_handlers (struct Plugin *plugin)
1576{
1577 unsigned int i;
1578 plugin->handlers = GNUNET_malloc (sizeof (my_handlers));
1579 memcpy (plugin->handlers, my_handlers, sizeof (my_handlers));
1580 for (i = 0;
1581 i <
1582 sizeof (my_handlers) / sizeof (struct GNUNET_SERVER_MessageHandler);
1583 i++)
1584 plugin->handlers[i].callback_cls = plugin;
1585 GNUNET_SERVER_add_handlers (plugin->server, plugin->handlers);
1586}
1587
1588
1589/**
1590 * Functions with this signature are called whenever a peer
1591 * is disconnected on the network level.
1592 *
1593 * @param cls closure
1594 * @param client identification of the client
1595 */
1596static void
1597disconnect_notify (void *cls, struct GNUNET_SERVER_Client *client)
1598{
1599 struct Plugin *plugin = cls;
1600 struct Session *session;
1601
1602#if DEBUG_TCP
1603 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1604 "tcp",
1605 "Notified about network-level disconnect of client %p.\n",
1606 client);
1607#endif
1608 session = find_session_by_client (plugin, client);
1609 if (session == NULL)
1610 return; /* unknown, nothing to do */
1611#if DEBUG_TCP
1612 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1613 "tcp", "Will now destroy session %p.\n", session);
1614#endif
1615 disconnect_session (session);
1616}
1617
1618
1619/**
1620 * Add the IP of our network interface to the list of
1621 * our external IP addresses.
1622 */
1623static int
1624process_interfaces (void *cls,
1625 const char *name,
1626 int isDefault,
1627 const struct sockaddr *addr, socklen_t addrlen)
1628{
1629 struct Plugin *plugin = cls;
1630 char dst[INET6_ADDRSTRLEN];
1631 int af;
1632 struct sockaddr_in *v4;
1633 struct sockaddr_in6 *v6;
1634
1635 af = addr->sa_family;
1636 if (af == AF_INET)
1637 {
1638 v4 = (struct sockaddr_in *) addr;
1639 inet_ntop (AF_INET, &v4->sin_addr, dst, sizeof (dst));
1640 v4->sin_port = htons (plugin->adv_port);
1641 }
1642 else
1643 {
1644 GNUNET_assert (af == AF_INET6);
1645 v6 = (struct sockaddr_in6 *) addr;
1646 inet_ntop (AF_INET6, &v6->sin6_addr, dst, sizeof (dst));
1647 v6->sin6_port = htons (plugin->adv_port);
1648 }
1649 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO |
1650 GNUNET_ERROR_TYPE_BULK,
1651 "tcp", _("Found address `%s' (%s)\n"), dst, name);
1652 plugin->env->notify_address (plugin->env->cls,
1653 "tcp",
1654 addr, addrlen, GNUNET_TIME_UNIT_FOREVER_REL);
1655 return GNUNET_OK;
1656}
1657
1658
1659/**
1660 * Function called by the resolver for each address obtained from DNS
1661 * for our own hostname. Add the addresses to the list of our
1662 * external IP addresses.
1663 *
1664 * @param cls closure
1665 * @param addr one of the addresses of the host, NULL for the last address
1666 * @param addrlen length of the address
1667 */
1668static void
1669process_hostname_ips (void *cls,
1670 const struct sockaddr *addr, socklen_t addrlen)
1671{
1672 struct Plugin *plugin = cls;
1673
1674 if (addr == NULL)
1675 return;
1676 plugin->env->notify_address (plugin->env->cls,
1677 "tcp",
1678 addr, addrlen, GNUNET_TIME_UNIT_FOREVER_REL);
1679}
1680
1681
1682/**
1683 * Entry point for the plugin.
1684 */
1685void *
1686libgnunet_plugin_transport_tcp_init (void *cls)
1687{
1688 struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
1689 struct GNUNET_TRANSPORT_PluginFunctions *api;
1690 struct Plugin *plugin;
1691 struct GNUNET_SERVICE_Context *service;
1692 unsigned long long aport;
1693 unsigned long long bport;
1694
1695 service = GNUNET_SERVICE_start ("tcp", env->sched, env->cfg);
1696 if (service == NULL)
1697 {
1698 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
1699 "tcp",
1700 _
1701 ("Failed to start service for `%s' transport plugin.\n"),
1702 "tcp");
1703 return NULL;
1704 }
1705 aport = 0;
1706 if ((GNUNET_OK !=
1707 GNUNET_CONFIGURATION_get_value_number (env->cfg,
1708 "tcp",
1709 "PORT",
1710 &bport)) ||
1711 (bport > 65535) ||
1712 ((GNUNET_OK ==
1713 GNUNET_CONFIGURATION_get_value_number (env->cfg,
1714 "tcp",
1715 "ADVERTISED-PORT",
1716 &aport)) && (aport > 65535)))
1717 {
1718 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
1719 "tcp",
1720 _
1721 ("Require valid port number for service `%s' in configuration!\n"),
1722 "tcp");
1723 GNUNET_SERVICE_stop (service);
1724 return NULL;
1725 }
1726 if (aport == 0)
1727 aport = bport;
1728 plugin = GNUNET_malloc (sizeof (struct Plugin));
1729 plugin->open_port = bport;
1730 plugin->adv_port = aport;
1731 plugin->env = env;
1732 plugin->lsock = NULL;
1733 plugin->statistics = NULL;
1734 api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
1735 api->cls = plugin;
1736 api->send_to = &tcp_plugin_send_to;
1737 api->send = &tcp_plugin_send;
1738 api->cancel = &tcp_plugin_cancel;
1739 api->address_pretty_printer = &tcp_plugin_address_pretty_printer;
1740 api->set_receive_quota = &tcp_plugin_set_receive_quota;
1741 api->address_suggested = &tcp_plugin_address_suggested;
1742 api->cost_estimate = 42; /* TODO: ATS */
1743 plugin->service = service;
1744 plugin->server = GNUNET_SERVICE_get_server (service);
1745 create_tcp_handlers (plugin);
1746 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO,
1747 "tcp", _("TCP transport listening on port %u\n"), bport);
1748 if (aport != bport)
1749 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO,
1750 "tcp",
1751 _
1752 ("TCP transport advertises itself as being on port %u\n"),
1753 aport);
1754 GNUNET_SERVER_disconnect_notify (plugin->server, &disconnect_notify,
1755 plugin);
1756 GNUNET_OS_network_interfaces_list (&process_interfaces, plugin);
1757 GNUNET_RESOLVER_hostname_resolve (env->sched,
1758 env->cfg,
1759 AF_UNSPEC,
1760 HOSTNAME_RESOLVE_TIMEOUT,
1761 &process_hostname_ips, plugin);
1762 return api;
1763}
1764
1765
1766/**
1767 * Exit point from the plugin.
1768 */
1769void *
1770libgnunet_plugin_transport_tcp_done (void *cls)
1771{
1772 struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
1773 struct Plugin *plugin = api->cls;
1774
1775 GNUNET_SERVICE_stop (plugin->service);
1776 GNUNET_free (plugin->handlers);
1777 GNUNET_free (plugin);
1778 GNUNET_free (api);
1779 return NULL;
1780}
1781
1782/* end of plugin_transport_tcp.c */
diff --git a/src/transport/plugin_transport_template.c b/src/transport/plugin_transport_template.c
new file mode 100644
index 000000000..1c8b06c61
--- /dev/null
+++ b/src/transport/plugin_transport_template.c
@@ -0,0 +1,335 @@
1/*
2 This file is part of GNUnet
3 (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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 2, 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 transport/plugin_transport_template.c
23 * @brief template for a new transport service
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_protocols.h"
29#include "gnunet_network_lib.h"
30#include "gnunet_server_lib.h"
31#include "gnunet_service_lib.h"
32#include "gnunet_statistics_service.h"
33#include "gnunet_transport_service.h"
34#include "plugin_transport.h"
35
36#define DEBUG_TEMPLATE GNUNET_NO
37
38/**
39 * After how long do we expire an address that we
40 * learned from another peer if it is not reconfirmed
41 * by anyone?
42 */
43#define LEARNED_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 6)
44
45
46/**
47 * Encapsulation of all of the state of the plugin.
48 */
49struct Plugin;
50
51
52/**
53 * Session handle for connections.
54 */
55struct Session
56{
57
58 /**
59 * Stored in a linked list.
60 */
61 struct Session *next;
62
63 /**
64 * Pointer to the global plugin struct.
65 */
66 struct Plugin *plugin;
67
68 /**
69 * The client (used to identify this connection)
70 */
71 /* void *client; */
72
73 /**
74 * Continuation function to call once the transmission buffer
75 * has again space available. NULL if there is no
76 * continuation to call.
77 */
78 GNUNET_TRANSPORT_TransmitContinuation transmit_cont;
79
80 /**
81 * Closure for transmit_cont.
82 */
83 void *transmit_cont_cls;
84
85 /**
86 * To whom are we talking to (set to our identity
87 * if we are still waiting for the welcome message)
88 */
89 struct GNUNET_PeerIdentity sender;
90
91 /**
92 * At what time did we reset last_received last?
93 */
94 struct GNUNET_TIME_Absolute last_quota_update;
95
96 /**
97 * How many bytes have we received since the "last_quota_update"
98 * timestamp?
99 */
100 uint64_t last_received;
101
102 /**
103 * Number of bytes per ms that this peer is allowed
104 * to send to us.
105 */
106 uint32_t quota;
107
108};
109
110/**
111 * Encapsulation of all of the state of the plugin.
112 */
113struct Plugin
114{
115 /**
116 * Our environment.
117 */
118 struct GNUNET_TRANSPORT_PluginEnvironment *env;
119
120 /**
121 * List of open sessions.
122 */
123 struct Session *sessions;
124
125 /**
126 * Handle for the statistics service.
127 */
128 struct GNUNET_STATISTICS_Handle *statistics;
129
130};
131
132
133
134/**
135 * Function that can be used by the transport service to transmit
136 * a message using the plugin using a fresh connection (even if
137 * we already have a connection to this peer, this function is
138 * required to establish a new one).
139 *
140 * @param cls closure
141 * @param target who should receive this message
142 * @param msg1 first message to transmit
143 * @param msg2 second message to transmit (can be NULL)
144 * @param timeout how long until we give up?
145 * @param addr the address
146 * @param addrlen length of the address
147 * @return non-null session if the transmission has been scheduled
148 * NULL if the address format is invalid
149 */
150static void *
151template_plugin_send_to (void *cls,
152 const struct GNUNET_PeerIdentity *target,
153 const struct GNUNET_MessageHeader *msg1,
154 const struct GNUNET_MessageHeader *msg2,
155 struct GNUNET_TIME_Relative timeout,
156 const void *addr, size_t addrlen)
157{
158 // FIXME
159 return NULL;
160}
161
162
163/**
164 * Function that can be used by the transport service to transmit
165 * a message using the plugin.
166 *
167 * @param cls closure
168 * @param plugin_context value we were asked to pass to this plugin
169 * to respond to the given peer (use is optional,
170 * but may speed up processing), can be NULL
171 * @param service_context value passed to the transport-service
172 * to identify the neighbour
173 * @param target who should receive this message
174 * @param msg the message to transmit
175 * @param cont continuation to call once the message has
176 * been transmitted (or if the transport is ready
177 * for the next transmission call; or if the
178 * peer disconnected...)
179 * @param cont_cls closure for cont
180 * @return plugin_context that should be used next time for
181 * sending messages to the specified peer
182 */
183static void *
184template_plugin_send (void *cls,
185 void *plugin_context,
186 struct ReadyList *service_context,
187 const struct GNUNET_PeerIdentity *target,
188 const struct GNUNET_MessageHeader *msg,
189 struct GNUNET_TIME_Relative timeout,
190 GNUNET_TRANSPORT_TransmitContinuation cont,
191 void *cont_cls)
192{
193 // struct Plugin *plugin = cls;
194 return NULL;
195}
196
197
198
199/**
200 *
201 * @param cls closure
202 * @param plugin_context value we were asked to pass to this plugin
203 * to respond to the given peer (use is optional,
204 * but may speed up processing), can be NULL (if
205 * NULL was returned from the transmit function)
206 * @param service_context must correspond to the service context
207 * of the corresponding Transmit call; the plugin should
208 * not cancel a send call made with a different service
209 * context pointer! Never NULL.
210 * @param target peer for which the last transmission is
211 * to be cancelled
212 */
213static void
214template_plugin_cancel (void *cls,
215 void *plugin_context,
216 struct ReadyList *service_context,
217 const struct GNUNET_PeerIdentity *target)
218{
219 // struct Plugin *plugin = cls;
220 // FIXME
221}
222
223
224/**
225 * Convert the transports address to a nice, human-readable
226 * format.
227 *
228 * @param cls closure
229 * @param name name of the transport that generated the address
230 * @param addr one of the addresses of the host, NULL for the last address
231 * the specific address format depends on the transport
232 * @param addrlen length of the address
233 * @param numeric should (IP) addresses be displayed in numeric form?
234 * @param timeout after how long should we give up?
235 * @param asc function to call on each string
236 * @param asc_cls closure for asc
237 */
238static void
239template_plugin_address_pretty_printer (void *cls,
240 const char *type,
241 const void *addr,
242 size_t addrlen,
243 int numeric,
244 struct GNUNET_TIME_Relative timeout,
245 GNUNET_TRANSPORT_AddressStringCallback
246 asc, void *asc_cls)
247{
248 asc (asc_cls, NULL);
249}
250
251/**
252 * Set a quota for receiving data from the given peer; this is a
253 * per-transport limit. The transport should limit its read/select
254 * calls to stay below the quota (in terms of incoming data).
255 *
256 * @param cls closure
257 * @param peer the peer for whom the quota is given
258 * @param quota_in quota for receiving/sending data in bytes per ms
259 */
260static void
261template_plugin_set_receive_quota (void *cls,
262 const struct GNUNET_PeerIdentity *target,
263 uint32_t quota_in)
264{
265 // struct Plugin *plugin = cls;
266 // FIXME!
267}
268
269
270/**
271 * Another peer has suggested an address for this
272 * peer and transport plugin. Check that this could be a valid
273 * address. If so, consider adding it to the list
274 * of addresses.
275 *
276 * @param cls closure
277 * @param addr pointer to the address
278 * @param addrlen length of addr
279 * @return GNUNET_OK if this is a plausible address for this peer
280 * and transport
281 */
282static int
283template_plugin_address_suggested (void *cls,
284 const void *addr, size_t addrlen)
285{
286 // struct Plugin *plugin = cls;
287
288 /* check if the address is plausible; if so,
289 add it to our list! */
290 // FIXME!
291 return GNUNET_OK;
292}
293
294
295/**
296 * Entry point for the plugin.
297 */
298void *
299gnunet_plugin_transport_template_init (void *cls)
300{
301 struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
302 struct GNUNET_TRANSPORT_PluginFunctions *api;
303 struct Plugin *plugin;
304
305 plugin = GNUNET_malloc (sizeof (struct Plugin));
306 plugin->env = env;
307 plugin->statistics = NULL;
308 api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
309 api->cls = plugin;
310 api->send_to = &template_plugin_send_to;
311 api->send = &template_plugin_send;
312 api->cancel = &template_plugin_cancel;
313 api->address_pretty_printer = &template_plugin_address_pretty_printer;
314 api->set_receive_quota = &template_plugin_set_receive_quota;
315 api->address_suggested = &template_plugin_address_suggested;
316 api->cost_estimate = 42; // FIXME
317 return api;
318}
319
320
321/**
322 * Exit point from the plugin.
323 */
324void *
325gnunet_plugin_transport_template_done (void *cls)
326{
327 struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
328 struct Plugin *plugin = api->cls;
329
330 GNUNET_free (plugin);
331 GNUNET_free (api);
332 return NULL;
333}
334
335/* end of plugin_transport_template.c */
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
new file mode 100644
index 000000000..ccaf9fbd1
--- /dev/null
+++ b/src/transport/plugin_transport_udp.c
@@ -0,0 +1,592 @@
1/*
2 This file is part of GNUnet
3 (C) 2001, 2002, 2003, 2004, 2005, 2008 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 2, 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 transports/udp.c
23 * @brief Implementation of the UDP transport service
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_util.h"
29#include "gnunet_protocols.h"
30#include "gnunet_transport.h"
31#include "gnunet_stats_service.h"
32#include "gnunet_upnp_service.h"
33#include "ip.h"
34
35#define DEBUG_UDP GNUNET_YES
36
37/**
38 * The default maximum size of each outbound UDP message,
39 * optimal value for Ethernet (10 or 100 MBit).
40 */
41#define MESSAGE_SIZE 1472
42
43/**
44 * Message-Packet header.
45 */
46typedef struct
47{
48 /**
49 * size of the message, in bytes, including this header.
50 */
51 GNUNET_MessageHeader header;
52
53 /**
54 * What is the identity of the sender (GNUNET_hash of public key)
55 */
56 GNUNET_PeerIdentity sender;
57
58} UDPMessage;
59
60#define MY_TRANSPORT_NAME "UDP"
61#include "common.c"
62
63/* *********** globals ************* */
64
65static int stat_bytesReceived;
66
67static int stat_bytesSent;
68
69static int stat_bytesDropped;
70
71static int stat_udpConnected;
72
73/**
74 * thread that listens for inbound messages
75 */
76static struct GNUNET_SelectHandle *selector;
77
78/**
79 * the socket that we transmit all data with
80 */
81static struct GNUNET_SocketHandle *udp_sock;
82
83static struct GNUNET_LoadMonitor *load_monitor;
84
85
86/**
87 * The socket of session has data waiting, process!
88 *
89 * This function may only be called if the tcplock is
90 * already held by the caller.
91 */
92static int
93select_message_handler (void *mh_cls,
94 struct GNUNET_SelectHandle *sh,
95 struct GNUNET_SocketHandle *sock,
96 void *sock_ctx, const GNUNET_MessageHeader * msg)
97{
98 unsigned int len;
99 GNUNET_TransportPacket *mp;
100 const UDPMessage *um;
101
102 len = ntohs (msg->size);
103 if (len <= sizeof (UDPMessage))
104 {
105 GNUNET_GE_LOG (coreAPI->ectx,
106 GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK,
107 _("Received malformed message via %s. Ignored.\n"),
108 "UDP");
109 return GNUNET_SYSERR;
110 }
111 um = (const UDPMessage *) msg;
112 mp = GNUNET_malloc (sizeof (GNUNET_TransportPacket));
113 mp->msg = GNUNET_malloc (len - sizeof (UDPMessage));
114 memcpy (mp->msg, &um[1], len - sizeof (UDPMessage));
115 mp->sender = um->sender;
116 mp->size = len - sizeof (UDPMessage);
117 mp->tsession = NULL;
118 coreAPI->receive (mp);
119 if (stats != NULL)
120 stats->change (stat_bytesReceived, len);
121 return GNUNET_OK;
122}
123
124static void *
125select_accept_handler (void *ah_cls,
126 struct GNUNET_SelectHandle *sh,
127 struct GNUNET_SocketHandle *sock,
128 const void *addr, unsigned int addr_len)
129{
130 static int nonnullpointer;
131
132 if (GNUNET_NO != is_rejected_tester (addr, addr_len))
133 return NULL;
134 return &nonnullpointer;
135}
136
137/**
138 * Select has been forced to close a connection.
139 * Free the associated context.
140 */
141static void
142select_close_handler (void *ch_cls,
143 struct GNUNET_SelectHandle *sh,
144 struct GNUNET_SocketHandle *sock, void *sock_ctx)
145{
146 /* do nothing */
147}
148
149/**
150 * Establish a connection to a remote node.
151 *
152 * @param hello the hello-Message for the target node
153 * @param tsessionPtr the session handle that is to be set
154 * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
155 */
156static int
157udp_connect (const GNUNET_MessageHello * hello,
158 GNUNET_TSession ** tsessionPtr, int may_reuse)
159{
160 GNUNET_TSession *tsession;
161
162 tsession = GNUNET_malloc (sizeof (GNUNET_TSession));
163 memset (tsession, 0, sizeof (GNUNET_TSession));
164 tsession->internal = GNUNET_malloc (GNUNET_sizeof_hello (hello));
165 memcpy (tsession->internal, hello, GNUNET_sizeof_hello (hello));
166 tsession->ttype = myAPI.protocol_number;
167 tsession->peer = hello->senderIdentity;
168 *tsessionPtr = tsession;
169 if (stats != NULL)
170 stats->change (stat_udpConnected, 1);
171 return GNUNET_OK;
172}
173
174/**
175 * A (core) Session is to be associated with a transport session. The
176 * transport service may want to know in order to call back on the
177 * core if the connection is being closed.
178 *
179 * @param tsession the session handle passed along
180 * from the call to receive that was made by the transport
181 * layer
182 * @return GNUNET_OK if the session could be associated,
183 * GNUNET_SYSERR if not.
184 */
185int
186udp_associate (GNUNET_TSession * tsession)
187{
188 return GNUNET_SYSERR; /* UDP connections can never be associated */
189}
190
191/**
192 * Disconnect from a remote node.
193 *
194 * @param tsession the session that is closed
195 * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
196 */
197static int
198udp_disconnect (GNUNET_TSession * tsession)
199{
200 if (tsession != NULL)
201 {
202 if (tsession->internal != NULL)
203 GNUNET_free (tsession->internal);
204 GNUNET_free (tsession);
205 if (stats != NULL)
206 stats->change (stat_udpConnected, -1);
207 }
208 return GNUNET_OK;
209}
210
211/**
212 * Shutdown the server process (stop receiving inbound traffic). Maybe
213 * restarted later!
214 */
215static int
216udp_transport_server_stop ()
217{
218 GNUNET_GE_ASSERT (coreAPI->ectx, udp_sock != NULL);
219 if (selector != NULL)
220 {
221 GNUNET_select_destroy (selector);
222 selector = NULL;
223 }
224 GNUNET_socket_destroy (udp_sock);
225 udp_sock = NULL;
226 return GNUNET_OK;
227}
228
229/**
230 * Test if the transport would even try to send
231 * a message of the given size and importance
232 * for the given session.<br>
233 * This function is used to check if the core should
234 * even bother to construct (and encrypt) this kind
235 * of message.
236 *
237 * @return GNUNET_YES if the transport would try (i.e. queue
238 * the message or call the OS to send),
239 * GNUNET_NO if the transport would just drop the message,
240 * GNUNET_SYSERR if the size/session is invalid
241 */
242static int
243udp_test_would_try (GNUNET_TSession * tsession, unsigned int size,
244 int important)
245{
246 const GNUNET_MessageHello *hello;
247
248 if (udp_sock == NULL)
249 return GNUNET_SYSERR;
250 if (size == 0)
251 {
252 GNUNET_GE_BREAK (coreAPI->ectx, 0);
253 return GNUNET_SYSERR;
254 }
255 if (size > myAPI.mtu)
256 {
257 GNUNET_GE_BREAK (coreAPI->ectx, 0);
258 return GNUNET_SYSERR;
259 }
260 hello = (const GNUNET_MessageHello *) tsession->internal;
261 if (hello == NULL)
262 return GNUNET_SYSERR;
263 return GNUNET_YES;
264}
265
266/**
267 * Create a UDP socket. If possible, use IPv6, otherwise
268 * try IPv4. Update available_protocols accordingly.
269 */
270static int
271udp_create_socket ()
272{
273 int s;
274
275 available_protocols = VERSION_AVAILABLE_NONE;
276 s = -1;
277 if (GNUNET_YES !=
278 GNUNET_GC_get_configuration_value_yesno (cfg, "GNUNETD", "DISABLE-IPV6",
279 GNUNET_YES))
280 {
281#ifndef MINGW
282 s = SOCKET (PF_INET6, SOCK_DGRAM, 17);
283#else
284 s = win_ols_socket (PF_INET6, SOCK_DGRAM, 17);
285#endif
286 }
287 if (s < 0)
288 {
289#ifndef MINGW
290 s = SOCKET (PF_INET, SOCK_DGRAM, 17);
291#else
292 s = win_ols_socket (PF_INET, SOCK_DGRAM, 17);
293#endif
294 if (s < 0)
295 {
296 GNUNET_GE_LOG_STRERROR (coreAPI->ectx,
297 GNUNET_GE_ERROR | GNUNET_GE_ADMIN |
298 GNUNET_GE_BULK, "socket");
299 return GNUNET_SYSERR;
300 }
301 available_protocols = VERSION_AVAILABLE_IPV4;
302 }
303 else
304 {
305 available_protocols = VERSION_AVAILABLE_IPV6 | VERSION_AVAILABLE_IPV4;
306 }
307 return s;
308}
309
310/**
311 * Send a message to the specified remote node.
312 *
313 * @param tsession the GNUNET_MessageHello identifying the remote node
314 * @param message what to send
315 * @param size the size of the message
316 * @return GNUNET_SYSERR on error, GNUNET_OK on success
317 */
318static int
319udp_send (GNUNET_TSession * tsession,
320 const void *message, const unsigned int size, int important)
321{
322 const GNUNET_MessageHello *hello;
323 const HostAddress *haddr;
324 UDPMessage *mp;
325 struct sockaddr_in serverAddrv4;
326 struct sockaddr_in6 serverAddrv6;
327 struct sockaddr *serverAddr;
328 socklen_t addrlen;
329 unsigned short available;
330 int ok;
331 int ssize;
332 size_t sent;
333
334 GNUNET_GE_ASSERT (NULL, tsession != NULL);
335 if (udp_sock == NULL)
336 return GNUNET_SYSERR;
337 if (size == 0)
338 {
339 GNUNET_GE_BREAK (coreAPI->ectx, 0);
340 return GNUNET_SYSERR;
341 }
342 if (size > myAPI.mtu)
343 {
344 GNUNET_GE_BREAK (coreAPI->ectx, 0);
345 return GNUNET_SYSERR;
346 }
347 hello = (const GNUNET_MessageHello *) tsession->internal;
348 if (hello == NULL)
349 return GNUNET_SYSERR;
350
351 haddr = (const HostAddress *) &hello[1];
352 available = ntohs (haddr->availability) & available_protocols;
353 if (available == VERSION_AVAILABLE_NONE)
354 return GNUNET_SYSERR;
355 if (available == (VERSION_AVAILABLE_IPV4 | VERSION_AVAILABLE_IPV6))
356 {
357 if (GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 2) == 0)
358 available = VERSION_AVAILABLE_IPV4;
359 else
360 available = VERSION_AVAILABLE_IPV6;
361 }
362 ssize = size + sizeof (UDPMessage);
363 mp = GNUNET_malloc (ssize);
364 mp->header.size = htons (ssize);
365 mp->header.type = 0;
366 mp->sender = *(coreAPI->my_identity);
367 memcpy (&mp[1], message, size);
368 ok = GNUNET_SYSERR;
369
370 if ((available & VERSION_AVAILABLE_IPV4) > 0)
371 {
372 memset (&serverAddrv4, 0, sizeof (serverAddrv4));
373 serverAddrv4.sin_family = AF_INET;
374 serverAddrv4.sin_port = haddr->port;
375 memcpy (&serverAddrv4.sin_addr, &haddr->ipv4, sizeof (struct in_addr));
376 addrlen = sizeof (serverAddrv4);
377 serverAddr = (struct sockaddr *) &serverAddrv4;
378 }
379 else
380 {
381 memset (&serverAddrv6, 0, sizeof (serverAddrv6));
382 serverAddrv6.sin6_family = AF_INET;
383 serverAddrv6.sin6_port = haddr->port;
384 memcpy (&serverAddrv6.sin6_addr, &haddr->ipv6,
385 sizeof (struct in6_addr));
386 addrlen = sizeof (serverAddrv6);
387 serverAddr = (struct sockaddr *) &serverAddrv6;
388 }
389#ifndef MINGW
390 if (GNUNET_YES == GNUNET_socket_send_to (udp_sock,
391 GNUNET_NC_NONBLOCKING,
392 mp,
393 ssize, &sent,
394 (const char *) serverAddr,
395 addrlen))
396#else
397 sent =
398 win_ols_sendto (udp_sock, mp, ssize, (const char *) serverAddr, addrlen);
399 if (sent != SOCKET_ERROR)
400#endif
401 {
402 ok = GNUNET_OK;
403 if (stats != NULL)
404 stats->change (stat_bytesSent, sent);
405 }
406 else
407 {
408 if (stats != NULL)
409 stats->change (stat_bytesDropped, ssize);
410 }
411 GNUNET_free (mp);
412 return ok;
413}
414
415/**
416 * Start the server process to receive inbound traffic.
417 *
418 * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
419 */
420static int
421udp_transport_server_start ()
422{
423 struct sockaddr_in serverAddrv4;
424 struct sockaddr_in6 serverAddrv6;
425 struct sockaddr *serverAddr;
426 socklen_t addrlen;
427 int sock;
428 const int on = 1;
429 unsigned short port;
430
431 GNUNET_GE_ASSERT (coreAPI->ectx, selector == NULL);
432 /* initialize UDP network */
433 port = get_port ();
434 if (port != 0)
435 {
436 sock = udp_create_socket ();
437 if (sock < 0)
438 return GNUNET_SYSERR;
439 if (SETSOCKOPT (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
440 {
441 GNUNET_GE_DIE_STRERROR (coreAPI->ectx,
442 GNUNET_GE_FATAL | GNUNET_GE_ADMIN |
443 GNUNET_GE_IMMEDIATE, "setsockopt");
444 return GNUNET_SYSERR;
445 }
446 if (available_protocols == VERSION_AVAILABLE_IPV4)
447 {
448 memset (&serverAddrv4, 0, sizeof (serverAddrv4));
449 serverAddrv4.sin_family = AF_INET;
450 serverAddrv4.sin_addr.s_addr = INADDR_ANY;
451 serverAddrv4.sin_port = htons (port);
452 addrlen = sizeof (serverAddrv4);
453 serverAddr = (struct sockaddr *) &serverAddrv4;
454 }
455 else
456 {
457 memset (&serverAddrv6, 0, sizeof (serverAddrv6));
458 serverAddrv6.sin6_family = AF_INET6;
459 serverAddrv6.sin6_addr = in6addr_any;
460 serverAddrv6.sin6_port = htons (port);
461 addrlen = sizeof (serverAddrv6);
462 serverAddr = (struct sockaddr *) &serverAddrv6;
463 }
464 if (BIND (sock, serverAddr, addrlen) < 0)
465 {
466 GNUNET_GE_LOG_STRERROR (coreAPI->ectx,
467 GNUNET_GE_FATAL | GNUNET_GE_ADMIN |
468 GNUNET_GE_IMMEDIATE, "bind");
469 GNUNET_GE_LOG (coreAPI->ectx,
470 GNUNET_GE_FATAL | GNUNET_GE_ADMIN |
471 GNUNET_GE_IMMEDIATE,
472 _("Failed to bind to %s port %d.\n"),
473 MY_TRANSPORT_NAME, port);
474 if (0 != CLOSE (sock))
475 GNUNET_GE_LOG_STRERROR (coreAPI->ectx,
476 GNUNET_GE_ERROR | GNUNET_GE_USER |
477 GNUNET_GE_ADMIN | GNUNET_GE_BULK,
478 "close");
479 return GNUNET_SYSERR;
480 }
481 selector = GNUNET_select_create ("udp", GNUNET_YES, coreAPI->ectx, load_monitor, sock, addrlen, 0, /* timeout */
482 &select_message_handler,
483 NULL,
484 &select_accept_handler,
485 NULL,
486 &select_close_handler,
487 NULL, 64 * 1024,
488 16 /* max sockets */ );
489 if (selector == NULL)
490 return GNUNET_SYSERR;
491 }
492 sock = udp_create_socket ();
493 if (sock == -1)
494 {
495 GNUNET_GE_LOG_STRERROR (coreAPI->ectx,
496 GNUNET_GE_ERROR | GNUNET_GE_ADMIN |
497 GNUNET_GE_BULK, "socket");
498 GNUNET_select_destroy (selector);
499 selector = NULL;
500 return GNUNET_SYSERR;
501 }
502 udp_sock = GNUNET_socket_create (coreAPI->ectx, load_monitor, sock);
503 GNUNET_GE_ASSERT (coreAPI->ectx, udp_sock != NULL);
504 return GNUNET_OK;
505}
506
507/**
508 * The exported method. Makes the core api available via a global and
509 * returns the udp transport API.
510 */
511GNUNET_TransportAPI *
512inittransport_udp (GNUNET_CoreAPIForTransport * core)
513{
514 unsigned long long mtu;
515
516 cfg = core->cfg;
517 load_monitor = core->load_monitor;
518 GNUNET_GE_ASSERT (coreAPI->ectx, sizeof (UDPMessage) == 68);
519 GNUNET_GE_ASSERT (coreAPI->ectx, sizeof (HostAddress) == 24);
520 coreAPI = core;
521 if (-1 == GNUNET_GC_get_configuration_value_number (cfg,
522 "UDP",
523 "MTU",
524 sizeof (UDPMessage)
525 +
526 GNUNET_P2P_MESSAGE_OVERHEAD
527 +
528 sizeof
529 (GNUNET_MessageHeader) +
530 32, 65500,
531 MESSAGE_SIZE, &mtu))
532 {
533 return NULL;
534 }
535 if (mtu < 1200)
536 GNUNET_GE_LOG (coreAPI->ectx,
537 GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_IMMEDIATE,
538 _("MTU %llu for `%s' is probably too low!\n"), mtu, "UDP");
539 lock = GNUNET_mutex_create (GNUNET_NO);
540 if (0 !=
541 GNUNET_GC_attach_change_listener (cfg, &reload_configuration, NULL))
542 {
543 GNUNET_mutex_destroy (lock);
544 lock = NULL;
545 return NULL;
546 }
547 if (GNUNET_GC_get_configuration_value_yesno (cfg, "UDP", "UPNP", GNUNET_YES)
548 == GNUNET_YES)
549 {
550 upnp = coreAPI->service_request ("upnp");
551 if (upnp == NULL)
552 GNUNET_GE_LOG (coreAPI->ectx,
553 GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_IMMEDIATE,
554 "The UPnP service could not be loaded. To disable UPnP, set the "
555 "configuration option \"UPNP\" in section \"%s\" to \"NO\"\n",
556 "UDP");
557 }
558 stats = coreAPI->service_request ("stats");
559 if (stats != NULL)
560 {
561 stat_bytesReceived
562 = stats->create (gettext_noop ("# bytes received via UDP"));
563 stat_bytesSent = stats->create (gettext_noop ("# bytes sent via UDP"));
564 stat_bytesDropped
565 = stats->create (gettext_noop ("# bytes dropped by UDP (outgoing)"));
566 stat_udpConnected
567 = stats->create (gettext_noop ("# UDP connections (right now)"));
568 }
569 myAPI.protocol_number = GNUNET_TRANSPORT_PROTOCOL_NUMBER_UDP;
570 myAPI.mtu = mtu - sizeof (UDPMessage);
571 myAPI.cost = 20000;
572 myAPI.hello_verify = &verify_hello;
573 myAPI.hello_create = &create_hello;
574 myAPI.connect = &udp_connect;
575 myAPI.send = &udp_send;
576 myAPI.associate = &udp_associate;
577 myAPI.disconnect = &udp_disconnect;
578 myAPI.server_start = &udp_transport_server_start;
579 myAPI.server_stop = &udp_transport_server_stop;
580 myAPI.hello_to_address = &hello_to_address;
581 myAPI.send_now_test = &udp_test_would_try;
582
583 return &myAPI;
584}
585
586void
587donetransport_udp ()
588{
589 do_shutdown ();
590}
591
592/* end of udp.c */
diff --git a/src/transport/test_transport_api.c b/src/transport/test_transport_api.c
new file mode 100644
index 000000000..02c28b09c
--- /dev/null
+++ b/src/transport/test_transport_api.c
@@ -0,0 +1,305 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 transport/test_transport_api.c
22 * @brief testcase for transport_api.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_hello_lib.h"
27#include "gnunet_getopt_lib.h"
28#include "gnunet_os_lib.h"
29#include "gnunet_program_lib.h"
30#include "gnunet_scheduler_lib.h"
31#include "gnunet_transport_service.h"
32#include "transport.h"
33
34#define VERBOSE GNUNET_NO
35
36#define START_ARM GNUNET_YES
37
38/**
39 * How long until we give up on transmitting the message?
40 */
41#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
42
43#define MTYPE 12345
44
45struct PeerContext
46{
47 struct GNUNET_CONFIGURATION_Handle *cfg;
48 struct GNUNET_TRANSPORT_Handle *th;
49 struct GNUNET_PeerIdentity id;
50#if START_ARM
51 pid_t arm_pid;
52#endif
53};
54
55static struct PeerContext p1;
56
57static struct PeerContext p2;
58
59static struct GNUNET_SCHEDULER_Handle *sched;
60
61static int ok;
62
63#if VERBOSE
64#define OKPP do { ok++; fprintf (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0)
65#else
66#define OKPP do { ok++; } while (0)
67#endif
68
69
70static void
71end ()
72{
73 /* do work here */
74 GNUNET_assert (ok == 8);
75 GNUNET_TRANSPORT_disconnect (p1.th);
76 GNUNET_TRANSPORT_disconnect (p2.th);
77 ok = 0;
78}
79
80
81/**
82 * Function called by the transport for each received message.
83 *
84 * @param cls closure
85 * @param latency estimated latency for communicating with the
86 * given peer
87 * @param peer (claimed) identity of the other peer
88 * @param message the message
89 */
90static void
91notify_receive (void *cls,
92 struct GNUNET_TIME_Relative latency,
93 const struct GNUNET_PeerIdentity *peer,
94 const struct GNUNET_MessageHeader *message)
95{
96 GNUNET_assert (ok == 7);
97 OKPP;
98 GNUNET_assert (MTYPE == ntohs (message->type));
99 GNUNET_assert (sizeof (struct GNUNET_MessageHeader) ==
100 ntohs (message->size));
101 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message from peer (%p)!\n",
102 cls);
103 end ();
104}
105
106
107/**
108 * Function called to notify transport users that another
109 * peer connected to us.
110 *
111 * @param cls closure
112 * @param transport the transport service handle
113 * @param peer the peer that disconnected
114 * @param latency current latency of the connection
115 */
116static void
117notify_connect (void *cls,
118 const struct GNUNET_PeerIdentity *peer,
119 struct GNUNET_TIME_Relative latency)
120{
121 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer connected to us (%p)!\n", cls);
122 GNUNET_assert ((ok >= 1) && (ok <= 6));
123 OKPP;
124}
125
126
127/**
128 * Function called to notify transport users that another
129 * peer disconnected from us.
130 *
131 * @param cls closure
132 * @param transport the transport service handle
133 * @param peer the peer that disconnected
134 */
135static void
136notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
137{
138 GNUNET_assert (0);
139}
140
141
142static void
143setup_peer (struct PeerContext *p, const char *cfgname)
144{
145 p->cfg = GNUNET_CONFIGURATION_create ();
146#if START_ARM
147 p->arm_pid = GNUNET_OS_start_process ("gnunet-service-arm",
148 "gnunet-service-arm",
149#if VERBOSE
150 "-L", "DEBUG",
151#endif
152 "-c", cfgname, NULL);
153 sleep (1); /* allow ARM to start */
154#endif
155 GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
156 p->th = GNUNET_TRANSPORT_connect (sched, p->cfg,
157 p,
158 &notify_receive,
159 &notify_connect, &notify_disconnect);
160 GNUNET_assert (p->th != NULL);
161}
162
163
164static size_t
165notify_ready (void *cls, size_t size, void *buf)
166{
167 struct GNUNET_MessageHeader *hdr;
168
169 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
170 "Transmitting message to peer (%p) - %u!\n", cls, size);
171 GNUNET_assert (size >= 256);
172 GNUNET_assert ((ok >= 5) && (ok <= 6));
173 OKPP;
174 hdr = buf;
175 hdr->size = htons (sizeof (struct GNUNET_MessageHeader));
176 hdr->type = htons (MTYPE);
177 return sizeof (struct GNUNET_MessageHeader);
178}
179
180
181static void
182exchange_hello_last (void *cls,
183 struct GNUNET_TIME_Relative latency,
184 const struct GNUNET_PeerIdentity *peer,
185 const struct GNUNET_MessageHeader *message)
186{
187 struct PeerContext *me = cls;
188 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk;
189
190 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
191 "Exchanging HELLO with peer (%p)!\n", cls);
192 GNUNET_assert (ok >= 3);
193 OKPP;
194 GNUNET_assert (message != NULL);
195 GNUNET_assert (GNUNET_OK ==
196 GNUNET_HELLO_get_key ((const struct GNUNET_HELLO_Message *)
197 message, &pk));
198 GNUNET_CRYPTO_hash (&pk,
199 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
200 &me->id.hashPubKey);
201 GNUNET_TRANSPORT_offer_hello (p1.th, message);
202 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
203 "Finished exchanging HELLOs, now waiting for transmission!\n");
204 /* both HELLOs exchanged, get ready to test transmission! */
205 GNUNET_TRANSPORT_notify_transmit_ready (p1.th,
206 &p2.id,
207 256, TIMEOUT, &notify_ready, &p1);
208}
209
210
211static void
212exchange_hello (void *cls,
213 struct GNUNET_TIME_Relative latency,
214 const struct GNUNET_PeerIdentity *peer,
215 const struct GNUNET_MessageHeader *message)
216{
217 struct PeerContext *me = cls;
218 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk;
219
220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
221 "Exchanging HELLO with peer (%p)!\n", cls);
222 GNUNET_assert (ok >= 2);
223 OKPP;
224 GNUNET_assert (message != NULL);
225 GNUNET_assert (GNUNET_OK ==
226 GNUNET_HELLO_get_key ((const struct GNUNET_HELLO_Message *)
227 message, &pk));
228 GNUNET_CRYPTO_hash (&pk,
229 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
230 &me->id.hashPubKey);
231 GNUNET_TRANSPORT_get_hello (p2.th, GNUNET_TIME_UNIT_MINUTES,
232 &exchange_hello_last, &p2);
233}
234
235
236static void
237run (void *cls,
238 struct GNUNET_SCHEDULER_Handle *s,
239 char *const *args,
240 const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *cfg)
241{
242 GNUNET_assert (ok == 1);
243 OKPP;
244 sched = s;
245 setup_peer (&p1, "test_transport_api_peer1.conf");
246 setup_peer (&p2, "test_transport_api_peer2.conf");
247 GNUNET_TRANSPORT_get_hello (p1.th,
248 GNUNET_TIME_UNIT_MINUTES, &exchange_hello, &p1);
249}
250
251
252static void
253stop_arm (struct PeerContext *p)
254{
255#if START_ARM
256 if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
257 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
258 waitpid (p->arm_pid, NULL, 0);
259#endif
260 GNUNET_CONFIGURATION_destroy (p->cfg);
261}
262
263
264static int
265check ()
266{
267 char *const argv[] = { "test-transport-api",
268 "-c",
269 "test_transport_api_data.conf",
270#if VERBOSE
271 "-L", "DEBUG",
272#endif
273 NULL
274 };
275 struct GNUNET_GETOPT_CommandLineOption options[] = {
276 GNUNET_GETOPT_OPTION_END
277 };
278
279 ok = 1;
280 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
281 argv, "test-transport-api", "nohelp",
282 options, &run, &ok);
283 stop_arm (&p1);
284 stop_arm (&p2);
285 return ok;
286}
287
288int
289main (int argc, char *argv[])
290{
291 int ret;
292
293 GNUNET_log_setup ("test-transport-api",
294#if VERBOSE
295 "DEBUG",
296#else
297 "WARNING",
298#endif
299 NULL);
300 ret = check ();
301
302 return ret;
303}
304
305/* end of test_transport_api.c */
diff --git a/src/transport/test_transport_api_data.conf b/src/transport/test_transport_api_data.conf
new file mode 100644
index 000000000..0fa611350
--- /dev/null
+++ b/src/transport/test_transport_api_data.conf
@@ -0,0 +1,24 @@
1[PATHS]
2SERVICEHOME = /tmp/test-gnunetd-transport-master/
3
4[resolver]
5PORT = 2364
6
7[transport]
8PORT = 2365
9PLUGINS = tcp
10
11[arm]
12PORT = 2366
13
14[statistics]
15PORT = 2367
16
17[tcp]
18PORT = 2368
19
20[peerinfo]
21PORT = 2369
22
23[testing]
24WEAKRANDOM = YES
diff --git a/src/transport/test_transport_api_peer1.conf b/src/transport/test_transport_api_peer1.conf
new file mode 100644
index 000000000..dcc0ab4cf
--- /dev/null
+++ b/src/transport/test_transport_api_peer1.conf
@@ -0,0 +1,25 @@
1[PATHS]
2SERVICEHOME = /tmp/test-gnunetd-transport-peer-1/
3DEFAULTCONFIG = test_transport_api_peer1.conf
4
5[resolver]
6PORT = 12364
7
8[transport]
9PORT = 12365
10PLUGINS = tcp
11
12[arm]
13PORT = 12366
14
15[statistics]
16PORT = 12367
17
18[tcp]
19PORT = 12368
20
21[peerinfo]
22PORT = 12369
23
24[testing]
25WEAKRANDOM = YES
diff --git a/src/transport/test_transport_api_peer2.conf b/src/transport/test_transport_api_peer2.conf
new file mode 100644
index 000000000..8567c6ac8
--- /dev/null
+++ b/src/transport/test_transport_api_peer2.conf
@@ -0,0 +1,25 @@
1[PATHS]
2SERVICEHOME = /tmp/test-gnunetd-transport-peer-2/
3DEFAULTCONFIG = test_transport_api_peer2.conf
4
5[resolver]
6PORT = 22364
7
8[transport]
9PORT = 22365
10PLUGINS = tcp
11
12[arm]
13PORT = 22366
14
15[statistics]
16PORT = 22367
17
18[tcp]
19PORT = 22368
20
21[peerinfo]
22PORT = 22369
23
24[testing]
25WEAKRANDOM = YES
diff --git a/src/transport/transport.h b/src/transport/transport.h
new file mode 100644
index 000000000..8e1291005
--- /dev/null
+++ b/src/transport/transport.h
@@ -0,0 +1,238 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 transport/transport.h
23 * @brief common internal definitions for transport service
24 * @author Christian Grothoff
25 */
26#include "gnunet_crypto_lib.h"
27#include "gnunet_time_lib.h"
28#include "gnunet_transport_service.h"
29
30#define DEBUG_TRANSPORT GNUNET_NO
31
32/**
33 * For how long do we allow unused bandwidth
34 * from the past to carry over into the future? (in ms)
35 */
36#define MAX_BANDWIDTH_CARRY 5000
37
38/**
39 * How often do we (at most) do a full quota
40 * recalculation? (in ms)
41 */
42#define MIN_QUOTA_REFRESH_TIME 2000
43
44/**
45 * Message from the transport service to the library
46 * informing about neighbors.
47 */
48struct ConnectInfoMessage
49{
50
51 /**
52 * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT
53 */
54 struct GNUNET_MessageHeader header;
55
56 /**
57 * Current quota for outbound traffic in bytes/ms.
58 * (should be equal to system default)
59 */
60 uint32_t quota_out GNUNET_PACKED;
61
62 /**
63 * Latency estimate.
64 */
65 struct GNUNET_TIME_RelativeNBO latency;
66
67 /**
68 * Identity of the new neighbour.
69 */
70 struct GNUNET_PeerIdentity id;
71
72};
73
74
75/**
76 * Message from the transport service to the library
77 * informing about disconnects.
78 */
79struct DisconnectInfoMessage
80{
81
82 /**
83 * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT
84 */
85 struct GNUNET_MessageHeader header;
86
87 /**
88 * Reserved, always zero.
89 */
90 uint32_t reserved GNUNET_PACKED;
91
92 /**
93 * Who got disconnected?
94 */
95 struct GNUNET_PeerIdentity peer;
96
97};
98
99
100/**
101 * Message used to set a particular bandwidth quota. Send
102 * TO the service to set an incoming quota, send FROM the
103 * service to update an outgoing quota.
104 */
105struct QuotaSetMessage
106{
107
108 /**
109 * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_NEIGHBOUR_INFO
110 */
111 struct GNUNET_MessageHeader header;
112
113 /**
114 * Quota in bytes per ms, 0 to drop everything;
115 * in network byte order.
116 */
117 uint32_t quota_in GNUNET_PACKED;
118
119 /**
120 * About which peer are we talking here?
121 */
122 struct GNUNET_PeerIdentity peer;
123
124};
125
126
127/**
128 * Message used to ask the transport service to connect
129 * to a particular peer.
130 */
131struct TryConnectMessage
132{
133
134 /**
135 * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_TRY_CONNECT.
136 */
137 struct GNUNET_MessageHeader header;
138
139 /**
140 * Always zero.
141 */
142 uint32_t reserved GNUNET_PACKED;
143
144 /**
145 * About which peer are we talking here?
146 */
147 struct GNUNET_PeerIdentity peer;
148
149};
150
151/**
152 * Message used to notify the transport API about a message
153 * received from the network. The actual message follows.
154 */
155struct InboundMessage
156{
157
158 /**
159 * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_RECV
160 */
161 struct GNUNET_MessageHeader header;
162
163 /**
164 * Always zero.
165 */
166 uint32_t reserved GNUNET_PACKED;
167
168 /**
169 * Latency estimate.
170 */
171 struct GNUNET_TIME_RelativeNBO latency;
172
173 /**
174 * Which peer sent the message?
175 */
176 struct GNUNET_PeerIdentity peer;
177
178};
179
180
181/**
182 * Message used to notify the transport API that it can
183 * send another message to the transport service.
184 */
185struct SendOkMessage
186{
187
188 /**
189 * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK
190 */
191 struct GNUNET_MessageHeader header;
192
193 /**
194 * GNUNET_OK if the transmission succeeded,
195 * GNUNET_SYSERR if it failed (i.e. network disconnect);
196 * in either case, it is now OK for this client to
197 * send us another message for the given peer.
198 */
199 uint32_t success GNUNET_PACKED;
200
201 /**
202 * Which peer can send more now?
203 */
204 struct GNUNET_PeerIdentity peer;
205
206};
207
208
209/**
210 * Message used to notify the transport service about a message
211 * to be transmitted to another peer. The actual message follows.
212 */
213struct OutboundMessage
214{
215
216 /**
217 * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_SEND
218 */
219 struct GNUNET_MessageHeader header;
220
221 /**
222 * Always zero.
223 */
224 uint32_t reserved GNUNET_PACKED;
225
226 /**
227 * Which peer should receive the message?
228 */
229 struct GNUNET_PeerIdentity peer;
230
231};
232
233
234
235
236
237
238/* end of transport.h */
diff --git a/src/transport/transport_api.c b/src/transport/transport_api.c
new file mode 100644
index 000000000..d6d4e2a96
--- /dev/null
+++ b/src/transport/transport_api.c
@@ -0,0 +1,1863 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 transport/transport_api.c
23 * @brief library to access the low-level P2P IO service
24 * @author Christian Grothoff
25 *
26 * TODO:
27 * - set_quota with low bandwidth should cause peer
28 * disconnects (currently never does that) (MINOR)
29 */
30#include "platform.h"
31#include "gnunet_client_lib.h"
32#include "gnunet_arm_service.h"
33#include "gnunet_hello_lib.h"
34#include "gnunet_protocols.h"
35#include "gnunet_server_lib.h"
36#include "gnunet_time_lib.h"
37#include "gnunet_transport_service.h"
38#include "transport.h"
39
40/**
41 * After how long do we give up on transmitting a HELLO
42 * to the service?
43 */
44#define OFFER_HELLO_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
45
46/**
47 * How long should ARM wait when starting up the
48 * transport service before reporting back?
49 */
50#define START_SERVICE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
51
52/**
53 * How long should ARM wait when stopping the
54 * transport service before reporting back?
55 */
56#define STOP_SERVICE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
57
58/**
59 * Entry in linked list of all of our current neighbours.
60 */
61struct NeighbourList
62{
63
64 /**
65 * This is a linked list.
66 */
67 struct NeighbourList *next;
68
69 /**
70 * Active transmit handle, can be NULL. Used to move
71 * from ready to wait list on disconnect and to block
72 * two transmissions to the same peer from being scheduled
73 * at the same time.
74 */
75 struct GNUNET_TRANSPORT_TransmitHandle *transmit_handle;
76
77
78 /**
79 * Identity of this neighbour.
80 */
81 struct GNUNET_PeerIdentity id;
82
83 /**
84 * At what time did we reset last_sent last?
85 */
86 struct GNUNET_TIME_Absolute last_quota_update;
87
88 /**
89 * How many bytes have we sent since the "last_quota_update"
90 * timestamp?
91 */
92 uint64_t last_sent;
93
94 /**
95 * Global quota for outbound traffic to the neighbour in bytes/ms.
96 */
97 uint32_t quota_out;
98
99 /**
100 * Set to GNUNET_YES if we are currently allowed to
101 * transmit a message to the transport service for this
102 * peer, GNUNET_NO otherwise.
103 */
104 int transmit_ok;
105
106 /**
107 * Set to GNUNET_YES if we have received an ACK for the
108 * given peer. Peers that receive our HELLO always respond
109 * with an ACK to let us know that we are successfully
110 * communicating. Note that a PING can not be used for this
111 * since PINGs are only send if a HELLO address requires
112 * confirmation (and also, PINGs are not passed to the
113 * transport API itself).
114 */
115 int received_ack;
116
117};
118
119
120/**
121 * Linked list of requests from clients for our HELLO
122 * that were deferred.
123 */
124struct HelloWaitList
125{
126
127 /**
128 * This is a linked list.
129 */
130 struct HelloWaitList *next;
131
132 /**
133 * Reference back to our transport handle.
134 */
135 struct GNUNET_TRANSPORT_Handle *handle;
136
137 /**
138 * Callback to call once we got our HELLO.
139 */
140 GNUNET_TRANSPORT_ReceiveCallback rec;
141
142 /**
143 * Closure for rec.
144 */
145 void *rec_cls;
146
147 /**
148 * When to time out (call rec with NULL).
149 */
150 struct GNUNET_TIME_Absolute timeout;
151
152 /**
153 * Timeout task (used to trigger timeout,
154 * cancel if we get the HELLO in time).
155 */
156 GNUNET_SCHEDULER_TaskIdentifier task;
157
158
159};
160
161
162/**
163 * Opaque handle for a transmission-ready request.
164 */
165struct GNUNET_TRANSPORT_TransmitHandle
166{
167
168 /**
169 * We keep the transmit handles that are waiting for
170 * a transport-level connection in a doubly linked list.
171 */
172 struct GNUNET_TRANSPORT_TransmitHandle *next;
173
174 /**
175 * We keep the transmit handles that are waiting for
176 * a transport-level connection in a doubly linked list.
177 */
178 struct GNUNET_TRANSPORT_TransmitHandle *prev;
179
180 /**
181 * Handle of the main transport data structure.
182 */
183 struct GNUNET_TRANSPORT_Handle *handle;
184
185 /**
186 * Neighbour for this handle, can be NULL if the service
187 * is not yet connected to the target.
188 */
189 struct NeighbourList *neighbour;
190
191 /**
192 * Which peer is this transmission going to be for? All
193 * zeros if it is control-traffic to the service.
194 */
195 struct GNUNET_PeerIdentity target;
196
197 /**
198 * Function to call when notify_size bytes are available
199 * for transmission.
200 */
201 GNUNET_NETWORK_TransmitReadyNotify notify;
202
203 /**
204 * Closure for notify.
205 */
206 void *notify_cls;
207
208 /**
209 * transmit_ready task Id. The task is used to introduce
210 * the artificial delay that may be required to maintain
211 * the bandwidth limits.
212 */
213 GNUNET_SCHEDULER_TaskIdentifier notify_delay_task;
214
215 /**
216 * Timeout for this request.
217 */
218 struct GNUNET_TIME_Absolute timeout;
219
220 /**
221 * How many bytes is our notify callback waiting for?
222 */
223 size_t notify_size;
224
225};
226
227
228/**
229 * Handle for the transport service (includes all of the
230 * state for the transport service).
231 */
232struct GNUNET_TRANSPORT_Handle
233{
234
235 /**
236 * Closure for the callbacks.
237 */
238 void *cls;
239
240 /**
241 * Function to call for received data.
242 */
243 GNUNET_TRANSPORT_ReceiveCallback rec;
244
245 /**
246 * function to call on connect events
247 */
248 GNUNET_TRANSPORT_NotifyConnect nc_cb;
249
250 /**
251 * function to call on disconnect events
252 */
253 GNUNET_TRANSPORT_NotifyDisconnect nd_cb;
254
255 /**
256 * The current HELLO message for this peer. Updated
257 * whenever transports change their addresses.
258 */
259 struct GNUNET_HELLO_Message *my_hello;
260
261 /**
262 * My client connection to the transport service.
263 */
264 struct GNUNET_CLIENT_Connection *client;
265
266 /**
267 * Handle to our registration with the client for notification.
268 */
269 struct GNUNET_NETWORK_TransmitHandle *network_handle;
270
271 /**
272 * Linked list of transmit handles that are waiting for the
273 * transport to connect to the respective peer. When we
274 * receive notification that the transport connected to a
275 * peer, we go over this list and check if someone has already
276 * requested a transmission to the new peer; if so, we trigger
277 * the next step.
278 */
279 struct GNUNET_TRANSPORT_TransmitHandle *connect_wait_head;
280
281 /**
282 * Linked list of transmit handles that are waiting for the
283 * transport to be ready for transmission to the respective
284 * peer. When we
285 * receive notification that the transport disconnected from
286 * a peer, we go over this list and move the entry back to
287 * the connect_wait list.
288 */
289 struct GNUNET_TRANSPORT_TransmitHandle *connect_ready_head;
290
291 /**
292 * Linked list of pending requests for our HELLO.
293 */
294 struct HelloWaitList *hwl_head;
295
296 /**
297 * My scheduler.
298 */
299 struct GNUNET_SCHEDULER_Handle *sched;
300
301 /**
302 * My configuration.
303 */
304 struct GNUNET_CONFIGURATION_Handle *cfg;
305
306 /**
307 * Linked list of the current neighbours of this peer.
308 */
309 struct NeighbourList *neighbours;
310
311 /**
312 * ID of the task trying to reconnect to the
313 * service.
314 */
315 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
316
317 /**
318 * Delay until we try to reconnect.
319 */
320 struct GNUNET_TIME_Relative reconnect_delay;
321
322 /**
323 * Do we currently have a transmission pending?
324 * (schedule transmission was called but has not
325 * yet succeeded)?
326 */
327 int transmission_scheduled;
328};
329
330
331static struct NeighbourList *
332find_neighbour (struct GNUNET_TRANSPORT_Handle *h,
333 const struct GNUNET_PeerIdentity *peer)
334{
335 struct NeighbourList *pos;
336
337 pos = h->neighbours;
338 while ((pos != NULL) &&
339 (0 != memcmp (peer, &pos->id, sizeof (struct GNUNET_PeerIdentity))))
340 pos = pos->next;
341 return pos;
342}
343
344
345/**
346 * Schedule the task to send one message from the
347 * connect_ready list to the service.
348 */
349static void schedule_transmission (struct GNUNET_TRANSPORT_Handle *h);
350
351
352/**
353 * Transmit message to client...
354 */
355static size_t
356transport_notify_ready (void *cls, size_t size, void *buf)
357{
358 struct GNUNET_TRANSPORT_Handle *h = cls;
359 struct GNUNET_TRANSPORT_TransmitHandle *th;
360 struct NeighbourList *n;
361 size_t ret;
362 char *cbuf;
363
364#if DEBUG_TRANSPORT
365 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
366 "Ready to transmit %u bytes to transport service\n", size);
367#endif
368 h->network_handle = NULL;
369 h->transmission_scheduled = GNUNET_NO;
370 if (buf == NULL)
371 {
372 th = h->connect_ready_head;
373 if (th->next != NULL)
374 th->next->prev = NULL;
375 h->connect_ready_head = th->next;
376 if (NULL != (n = th->neighbour))
377 {
378 GNUNET_assert (n->transmit_handle == th);
379 n->transmit_handle = NULL;
380 }
381 GNUNET_assert (0 == th->notify (th->notify_cls, 0, NULL));
382 GNUNET_free (th);
383 return 0;
384 }
385 cbuf = buf;
386 ret = 0;
387 h->network_handle = NULL;
388 h->transmission_scheduled = GNUNET_NO;
389 do
390 {
391 th = h->connect_ready_head;
392 GNUNET_assert (th->notify_size <= size);
393 if (th->next != NULL)
394 th->next->prev = NULL;
395 h->connect_ready_head = th->next;
396 if (NULL != (n = th->neighbour))
397 {
398 GNUNET_assert (n->transmit_handle == th);
399 n->transmit_handle = NULL;
400 }
401 ret += th->notify (th->notify_cls, size, &cbuf[ret]);
402 GNUNET_free (th);
403 if (n != NULL)
404 n->last_sent += ret;
405 size -= ret;
406 }
407 while ((h->connect_ready_head != NULL) &&
408 (h->connect_ready_head->notify_size <= size));
409 if (h->connect_ready_head != NULL)
410 schedule_transmission (h);
411#if DEBUG_TRANSPORT
412 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
413 "Transmitting %u bytes to transport service\n", ret);
414#endif
415 return ret;
416}
417
418
419/**
420 * Schedule the task to send one message from the
421 * connect_ready list to the service.
422 */
423static void
424schedule_transmission (struct GNUNET_TRANSPORT_Handle *h)
425{
426 struct GNUNET_TRANSPORT_TransmitHandle *th;
427
428 GNUNET_assert (NULL == h->network_handle);
429 if (h->client == NULL)
430 {
431#if DEBUG_TRANSPORT
432 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
433 "Not yet connected to transport service, need to wait.\n");
434#endif
435 return;
436 }
437 th = h->connect_ready_head;
438 if (th == NULL)
439 {
440#if DEBUG_TRANSPORT
441 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
442 "Schedule transmission called, but no request is pending.\n");
443#endif
444 return;
445 }
446 h->transmission_scheduled = GNUNET_YES;
447#if DEBUG_TRANSPORT
448 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
449 "Asking client API for transmission of %u bytes\n",
450 th->notify_size);
451#endif
452 h->network_handle = GNUNET_CLIENT_notify_transmit_ready (h->client,
453 th->notify_size,
454 GNUNET_TIME_absolute_get_remaining
455 (th->timeout),
456 &transport_notify_ready,
457 h);
458 GNUNET_assert (NULL != h->network_handle);
459}
460
461
462/**
463 * Insert the given transmit handle in the given sorted
464 * doubly linked list based on timeout.
465 *
466 * @param head pointer to the head of the linked list
467 * @param th element to insert into the list
468 */
469static void
470insert_transmit_handle (struct GNUNET_TRANSPORT_TransmitHandle **head,
471 struct GNUNET_TRANSPORT_TransmitHandle *th)
472{
473 struct GNUNET_TRANSPORT_TransmitHandle *pos;
474 struct GNUNET_TRANSPORT_TransmitHandle *prev;
475
476 pos = *head;
477 prev = NULL;
478 while ((pos != NULL) && (pos->timeout.value < th->timeout.value))
479 {
480 prev = pos;
481 pos = pos->next;
482 }
483 if (prev == NULL)
484 {
485 th->next = *head;
486 if (th->next != NULL)
487 th->next->prev = th;
488 *head = th;
489 }
490 else
491 {
492 th->next = pos;
493 th->prev = prev;
494 prev->next = th;
495 if (pos != NULL)
496 pos->prev = th;
497 }
498}
499
500
501/**
502 * Queue control request for transmission to the transport
503 * service.
504 *
505 * @param size number of bytes to be transmitted
506 * @param at_head request must be added to the head of the queue
507 * (otherwise request will be appended)
508 * @param timeout how long this transmission can wait (at most)
509 * @param notify function to call to get the content
510 * @param notify_cls closure for notify
511 */
512static void
513schedule_control_transmit (struct GNUNET_TRANSPORT_Handle *h,
514 size_t size,
515 int at_head,
516 struct GNUNET_TIME_Relative timeout,
517 GNUNET_NETWORK_TransmitReadyNotify notify,
518 void *notify_cls)
519{
520 struct GNUNET_TRANSPORT_TransmitHandle *th;
521#if DEBUG_TRANSPORT
522 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
523 "Queueing %u bytes control transmission request.\n", size);
524#endif
525 th = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_TransmitHandle));
526 th->handle = h;
527 th->notify = notify;
528 th->notify_cls = notify_cls;
529 th->timeout = GNUNET_TIME_relative_to_absolute (timeout);
530 th->notify_size = size;
531 if (at_head)
532 {
533 th->next = h->connect_ready_head;
534 h->connect_ready_head = th;
535 if (th->next != NULL)
536 th->next->prev = th;
537 }
538 else
539 {
540 insert_transmit_handle (&h->connect_ready_head, th);
541 }
542 if (GNUNET_NO == h->transmission_scheduled)
543 schedule_transmission (h);
544}
545
546
547/**
548 * Update the quota values for the given neighbour now.
549 */
550static void
551update_quota (struct NeighbourList *n)
552{
553 struct GNUNET_TIME_Relative delta;
554 uint64_t allowed;
555 uint64_t remaining;
556
557 delta = GNUNET_TIME_absolute_get_duration (n->last_quota_update);
558 allowed = delta.value * n->quota_out;
559 if (n->last_sent < allowed)
560 {
561 remaining = allowed - n->last_sent;
562 if (n->quota_out > 0)
563 remaining /= n->quota_out;
564 else
565 remaining = 0;
566 if (remaining > MAX_BANDWIDTH_CARRY)
567 remaining = MAX_BANDWIDTH_CARRY;
568 n->last_sent = 0;
569 n->last_quota_update = GNUNET_TIME_absolute_get ();
570 n->last_quota_update.value -= remaining;
571 }
572 else
573 {
574 n->last_sent -= allowed;
575 n->last_quota_update = GNUNET_TIME_absolute_get ();
576 }
577}
578
579
580struct SetQuotaContext
581{
582 struct GNUNET_TRANSPORT_Handle *handle;
583
584 struct GNUNET_PeerIdentity target;
585
586 GNUNET_SCHEDULER_Task cont;
587
588 void *cont_cls;
589
590 struct GNUNET_TIME_Absolute timeout;
591
592 uint32_t quota_in;
593};
594
595
596static size_t
597send_set_quota (void *cls, size_t size, void *buf)
598{
599 struct SetQuotaContext *sqc = cls;
600 struct QuotaSetMessage *msg;
601
602 if (buf == NULL)
603 {
604 GNUNET_SCHEDULER_add_continuation (sqc->handle->sched,
605 GNUNET_NO,
606 sqc->cont,
607 sqc->cont_cls,
608 GNUNET_SCHEDULER_REASON_TIMEOUT);
609 GNUNET_free (sqc);
610 return 0;
611 }
612#if DEBUG_TRANSPORT
613 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
614 "Transmitting `%s' request with respect to `%4s'.\n",
615 "SET_QUOTA", GNUNET_i2s (&sqc->target));
616#endif
617 GNUNET_assert (size >= sizeof (struct QuotaSetMessage));
618 msg = buf;
619 msg->header.size = htons (sizeof (struct QuotaSetMessage));
620 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
621 msg->quota_in = htonl (sqc->quota_in);
622 memcpy (&msg->peer, &sqc->target, sizeof (struct GNUNET_PeerIdentity));
623 if (sqc->cont != NULL)
624 GNUNET_SCHEDULER_add_continuation (sqc->handle->sched,
625 GNUNET_NO,
626 sqc->cont,
627 sqc->cont_cls,
628 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
629 GNUNET_free (sqc);
630 return sizeof (struct QuotaSetMessage);
631}
632
633
634/**
635 * Set the share of incoming bandwidth for the given
636 * peer to the specified amount.
637 *
638 * @param handle connection to transport service
639 * @param target who's bandwidth quota is being changed
640 * @param quota_in incoming bandwidth quota in bytes per ms; 0 can
641 * be used to force all traffic to be discarded
642 * @param quota_out outgoing bandwidth quota in bytes per ms; 0 can
643 * be used to force all traffic to be discarded
644 * @param timeout how long to wait until signaling failure if
645 * we can not communicate the quota change
646 * @param cont continuation to call when done, will be called
647 * either with reason "TIMEOUT" or with reason "PREREQ_DONE"
648 * @param cont_cls closure for continuation
649 */
650void
651GNUNET_TRANSPORT_set_quota (struct GNUNET_TRANSPORT_Handle *handle,
652 const struct GNUNET_PeerIdentity *target,
653 uint32_t quota_in,
654 uint32_t quota_out,
655 struct GNUNET_TIME_Relative timeout,
656 GNUNET_SCHEDULER_Task cont, void *cont_cls)
657{
658 struct NeighbourList *n;
659 struct SetQuotaContext *sqc;
660
661 n = find_neighbour (handle, target);
662 if (n != NULL)
663 {
664 update_quota (n);
665 if (n->quota_out < quota_out)
666 n->last_quota_update = GNUNET_TIME_absolute_get ();
667 n->quota_out = quota_out;
668 }
669 sqc = GNUNET_malloc (sizeof (struct SetQuotaContext));
670 sqc->handle = handle;
671 sqc->target = *target;
672 sqc->cont = cont;
673 sqc->cont_cls = cont_cls;
674 sqc->timeout = GNUNET_TIME_relative_to_absolute (timeout);
675 sqc->quota_in = quota_in;
676 schedule_control_transmit (handle,
677 sizeof (struct QuotaSetMessage),
678 GNUNET_NO, timeout, &send_set_quota, sqc);
679}
680
681
682/**
683 * A "get_hello" request has timed out. Signal the client
684 * and clean up.
685 */
686static void
687hello_wait_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
688{
689 struct HelloWaitList *hwl = cls;
690 struct HelloWaitList *pos;
691 struct HelloWaitList *prev;
692
693 prev = NULL;
694 pos = hwl->handle->hwl_head;
695 while (pos != hwl)
696 {
697 GNUNET_assert (pos != NULL);
698 prev = pos;
699 pos = pos->next;
700 }
701 if (prev == NULL)
702 hwl->handle->hwl_head = hwl->next;
703 else
704 prev->next = hwl->next;
705 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
706 _("Timeout trying to obtain `%s' from transport service.\n"),
707 "HELLO");
708 /* signal timeout */
709 if (hwl->rec != NULL)
710 hwl->rec (hwl->rec_cls, GNUNET_TIME_UNIT_ZERO, NULL, NULL);
711 GNUNET_free (hwl);
712}
713
714
715/**
716 * Obtain the HELLO message for this peer.
717 *
718 * @param handle connection to transport service
719 * @param timeout how long to wait for the HELLO
720 * @param rec function to call with the HELLO, sender will be our peer
721 * identity; message and sender will be NULL on timeout
722 * (handshake with transport service pending/failed).
723 * cost estimate will be 0.
724 * @param rec_cls closure for rec
725 */
726void
727GNUNET_TRANSPORT_get_hello (struct GNUNET_TRANSPORT_Handle *handle,
728 struct GNUNET_TIME_Relative timeout,
729 GNUNET_TRANSPORT_ReceiveCallback rec,
730 void *rec_cls)
731{
732 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk;
733 struct GNUNET_PeerIdentity me;
734 struct HelloWaitList *hwl;
735
736 if (handle->my_hello == NULL)
737 {
738 hwl = GNUNET_malloc (sizeof (struct HelloWaitList));
739 hwl->next = handle->hwl_head;
740 handle->hwl_head = hwl;
741 hwl->handle = handle;
742 hwl->rec = rec;
743 hwl->rec_cls = rec_cls;
744 hwl->timeout = GNUNET_TIME_relative_to_absolute (timeout);
745 hwl->task = GNUNET_SCHEDULER_add_delayed (handle->sched,
746 GNUNET_YES,
747 GNUNET_SCHEDULER_PRIORITY_KEEP,
748 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
749 timeout,
750 &hello_wait_timeout, hwl);
751 return;
752 }
753 GNUNET_assert (GNUNET_OK == GNUNET_HELLO_get_key (handle->my_hello, &pk));
754 GNUNET_CRYPTO_hash (&pk,
755 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
756 &me.hashPubKey);
757
758 rec (rec_cls,
759 GNUNET_TIME_UNIT_ZERO,
760 &me, (const struct GNUNET_MessageHeader *) handle->my_hello);
761}
762
763
764static size_t
765send_hello (void *cls, size_t size, void *buf)
766{
767 struct GNUNET_MessageHeader *hello = cls;
768 uint16_t msize;
769
770 if (buf == NULL)
771 {
772#if DEBUG_TRANSPORT
773 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
774 "Timeout while trying to transmit `%s' request.\n",
775 "HELLO");
776#endif
777 GNUNET_free (hello);
778 return 0;
779 }
780#if DEBUG_TRANSPORT
781 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
782 "Transmitting `%s' request.\n", "HELLO");
783#endif
784 msize = ntohs (hello->size);
785 GNUNET_assert (size >= msize);
786 memcpy (buf, hello, msize);
787 GNUNET_free (hello);
788 return msize;
789}
790
791
792/**
793 * Offer the transport service the HELLO of another peer. Note that
794 * the transport service may just ignore this message if the HELLO is
795 * malformed or useless due to our local configuration.
796 *
797 * @param handle connection to transport service
798 * @param hello the hello message
799 */
800void
801GNUNET_TRANSPORT_offer_hello (struct GNUNET_TRANSPORT_Handle *handle,
802 const struct GNUNET_MessageHeader *hello)
803{
804 struct GNUNET_MessageHeader *hc;
805 uint16_t size;
806
807 if (handle->client == NULL)
808 {
809#if DEBUG_TRANSPORT
810 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
811 "Not connected to transport service, dropping offered HELLO\n");
812#endif
813 return;
814 }
815 GNUNET_break (ntohs (hello->type) == GNUNET_MESSAGE_TYPE_HELLO);
816 size = ntohs (hello->size);
817 GNUNET_break (size >= sizeof (struct GNUNET_MessageHeader));
818 hc = GNUNET_malloc (size);
819 memcpy (hc, hello, size);
820 schedule_control_transmit (handle,
821 size,
822 GNUNET_NO, OFFER_HELLO_TIMEOUT, &send_hello, hc);
823}
824
825
826/**
827 * Function we use for handling incoming messages.
828 */
829static void demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg);
830
831
832static size_t
833send_start (void *cls, size_t size, void *buf)
834{
835 struct GNUNET_MessageHeader *s = buf;
836
837 if (buf == NULL)
838 return 0;
839#if DEBUG_TRANSPORT
840 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
841 "Transmitting `%s' request.\n", "START");
842#endif
843 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
844 s->size = htons (sizeof (struct GNUNET_MessageHeader));
845 s->type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_START);
846 return sizeof (struct GNUNET_MessageHeader);
847}
848
849
850/**
851 * Try again to connect to transport service.
852 */
853static void
854reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
855{
856 struct GNUNET_TRANSPORT_Handle *h = cls;
857 struct GNUNET_TRANSPORT_TransmitHandle *pos;
858 struct NeighbourList *n;
859
860 while (NULL != (n = h->neighbours))
861 {
862 h->neighbours = n->next;
863 pos = n->transmit_handle;
864 if (pos != NULL)
865 {
866 pos->neighbour = NULL;
867 pos->next = h->connect_wait_head;
868 h->connect_wait_head = pos;
869 if (pos->next != NULL)
870 pos->next->prev = pos;
871 pos->prev = NULL;
872 }
873 GNUNET_free (n);
874 }
875 h->connect_ready_head = NULL;
876#if DEBUG_TRANSPORT
877 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to transport service.\n");
878#endif
879 GNUNET_assert (h->client == NULL);
880 h->reconnect_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
881 h->client = GNUNET_CLIENT_connect (h->sched, "transport", h->cfg);
882 GNUNET_assert (h->client != NULL);
883 /* make sure we don't send "START" twice,
884 remove existing entry from queue (if present) */
885 pos = h->connect_ready_head;
886 while (pos != NULL)
887 {
888 if (pos->notify == &send_start)
889 {
890 if (pos->prev == NULL)
891 h->connect_ready_head = pos->next;
892 else
893 pos->prev->next = pos->next;
894 if (pos->next != NULL)
895 pos->next->prev = pos->prev;
896 GNUNET_assert (pos->neighbour == NULL);
897 GNUNET_free (pos);
898 break;
899 }
900 pos = pos->next;
901 }
902 schedule_control_transmit (h,
903 sizeof (struct GNUNET_MessageHeader),
904 GNUNET_YES,
905 GNUNET_TIME_UNIT_FOREVER_REL, &send_start, NULL);
906 GNUNET_CLIENT_receive (h->client,
907 &demultiplexer, h, GNUNET_TIME_UNIT_FOREVER_REL);
908}
909
910
911/**
912 * Function that will schedule the job that will try
913 * to connect us again to the client.
914 */
915static void
916schedule_reconnect (struct GNUNET_TRANSPORT_Handle *h)
917{
918#if DEBUG_TRANSPORT
919 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
920 "Scheduling task to reconnect to transport service in %llu ms.\n",
921 h->reconnect_delay.value);
922#endif
923 GNUNET_assert (h->client == NULL);
924 GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_PREREQUISITE_TASK);
925 h->reconnect_task
926 = GNUNET_SCHEDULER_add_delayed (h->sched,
927 GNUNET_NO,
928 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
929 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
930 h->reconnect_delay, &reconnect, h);
931 h->reconnect_delay = GNUNET_TIME_UNIT_SECONDS;
932}
933
934
935/**
936 * Remove the given transmit handle from the wait list. Does NOT free
937 * it.
938 */
939static void
940remove_from_wait_list (struct GNUNET_TRANSPORT_TransmitHandle *th)
941{
942 if (th->prev == NULL)
943 th->handle->connect_wait_head = th->next;
944 else
945 th->prev->next = th->next;
946 if (th->next != NULL)
947 th->next->prev = th->prev;
948}
949
950
951/**
952 * We are connected to the respective peer, check the
953 * bandwidth limits and schedule the transmission.
954 */
955static void schedule_request (struct GNUNET_TRANSPORT_TransmitHandle *th);
956
957
958/**
959 * Function called by the scheduler when the timeout
960 * for bandwidth availablility for the target
961 * neighbour is reached.
962 */
963static void
964transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
965{
966 struct GNUNET_TRANSPORT_TransmitHandle *th = cls;
967
968 th->notify_delay_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
969 schedule_request (th);
970}
971
972
973/**
974 * Called when our transmit request timed out before any transport
975 * reported success connecting to the desired peer or before the
976 * transport was ready to receive. Signal error and free
977 * TransmitHandle.
978 */
979static void
980transmit_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
981{
982 struct GNUNET_TRANSPORT_TransmitHandle *th = cls;
983
984 if (th->neighbour != NULL)
985 th->neighbour->transmit_handle = NULL;
986#if DEBUG_TRANSPORT
987 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission request timed out.\n");
988#endif
989 th->notify_delay_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
990 remove_from_wait_list (th);
991 th->notify (th->notify_cls, 0, NULL);
992 GNUNET_free (th);
993}
994
995
996/**
997 * We are connected to the respective peer, check the
998 * bandwidth limits and schedule the transmission.
999 */
1000static void
1001schedule_request (struct GNUNET_TRANSPORT_TransmitHandle *th)
1002{
1003 struct GNUNET_TRANSPORT_Handle *h;
1004 struct GNUNET_TIME_Relative duration;
1005 struct NeighbourList *n;
1006 uint64_t available;
1007
1008 h = th->handle;
1009 n = th->neighbour;
1010 if (th->notify_delay_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
1011 {
1012 GNUNET_SCHEDULER_cancel (h->sched, th->notify_delay_task);
1013 th->notify_delay_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1014 }
1015 /* check outgoing quota */
1016 duration = GNUNET_TIME_absolute_get_duration (n->last_quota_update);
1017 if (duration.value > MIN_QUOTA_REFRESH_TIME)
1018 {
1019 update_quota (n);
1020 duration = GNUNET_TIME_absolute_get_duration (n->last_quota_update);
1021 }
1022 available = duration.value * n->quota_out;
1023 if (available < n->last_sent + th->notify_size)
1024 {
1025 /* calculate how much bandwidth we'd still need to
1026 accumulate and based on that how long we'll have
1027 to wait... */
1028 available = n->last_sent + th->notify_size - available;
1029 duration = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
1030 available / n->quota_out);
1031 if (th->timeout.value <
1032 GNUNET_TIME_relative_to_absolute (duration).value)
1033 {
1034 /* signal timeout! */
1035#if DEBUG_TRANSPORT
1036 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1037 "Would need %llu ms before bandwidth is available for delivery, that is too long. Signaling timeout.\n",
1038 duration.value);
1039#endif
1040 remove_from_wait_list (th);
1041 th->notify (th->notify_cls, 0, NULL);
1042 GNUNET_free (th);
1043 return;
1044 }
1045#if DEBUG_TRANSPORT
1046 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1047 "Need more bandwidth, delaying delivery by %llu ms\n",
1048 duration.value);
1049#endif
1050 th->notify_delay_task
1051 = GNUNET_SCHEDULER_add_delayed (h->sched,
1052 GNUNET_NO,
1053 GNUNET_SCHEDULER_PRIORITY_KEEP,
1054 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1055 duration, &transmit_ready, th);
1056 return;
1057 }
1058#if DEBUG_TRANSPORT
1059 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1060 "Bandwidth available for transmission to `%4s'\n",
1061 GNUNET_i2s (&n->id));
1062#endif
1063 if (GNUNET_NO == n->transmit_ok)
1064 {
1065 /* we may be ready, but transport service is not;
1066 wait for SendOkMessage or timeout */
1067#if DEBUG_TRANSPORT
1068 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1069 "Need to wait for transport service `%s' message\n",
1070 "SEND_OK");
1071#endif
1072 th->notify_delay_task
1073 = GNUNET_SCHEDULER_add_delayed (h->sched,
1074 GNUNET_NO,
1075 GNUNET_SCHEDULER_PRIORITY_KEEP,
1076 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1077 GNUNET_TIME_absolute_get_remaining
1078 (th->timeout), &transmit_timeout, th);
1079 return;
1080 }
1081 n->transmit_ok = GNUNET_NO;
1082 remove_from_wait_list (th);
1083#if DEBUG_TRANSPORT
1084 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Moving message to ready list\n");
1085#endif
1086 insert_transmit_handle (&h->connect_ready_head, th);
1087 if (GNUNET_NO == h->transmission_scheduled)
1088 schedule_transmission (h);
1089}
1090
1091
1092/**
1093 * Add neighbour to our list
1094 */
1095static void
1096add_neighbour (struct GNUNET_TRANSPORT_Handle *h,
1097 uint32_t quota_out,
1098 struct GNUNET_TIME_Relative latency,
1099 const struct GNUNET_PeerIdentity *pid)
1100{
1101 struct NeighbourList *n;
1102 struct GNUNET_TRANSPORT_TransmitHandle *prev;
1103 struct GNUNET_TRANSPORT_TransmitHandle *pos;
1104 struct GNUNET_TRANSPORT_TransmitHandle *next;
1105
1106 /* check for duplicates */
1107 if (NULL != find_neighbour (h, pid))
1108 {
1109 GNUNET_break (0);
1110 return;
1111 }
1112#if DEBUG_TRANSPORT
1113 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1114 "Creating entry for new neighbour `%4s'.\n", GNUNET_i2s (pid));
1115#endif
1116 n = GNUNET_malloc (sizeof (struct NeighbourList));
1117 n->id = *pid;
1118 n->last_quota_update = GNUNET_TIME_absolute_get ();
1119 n->quota_out = quota_out;
1120 n->next = h->neighbours;
1121 n->transmit_ok = GNUNET_YES;
1122 h->neighbours = n;
1123 if (h->nc_cb != NULL)
1124 h->nc_cb (h->cls, &n->id, latency);
1125 prev = NULL;
1126 pos = h->connect_wait_head;
1127 while (pos != NULL)
1128 {
1129 next = pos->next;
1130#if DEBUG_TRANSPORT
1131 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1132 "Found entry in connect_wait_head for `%4s'.\n",
1133 GNUNET_i2s (&pos->target));
1134#endif
1135 if (0 == memcmp (pid,
1136 &pos->target, sizeof (struct GNUNET_PeerIdentity)))
1137 {
1138#if DEBUG_TRANSPORT
1139 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1140 "Found pending request for new connection, will trigger now.\n");
1141#endif
1142 pos->neighbour = n;
1143 if (pos->notify_delay_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
1144 {
1145 GNUNET_SCHEDULER_cancel (h->sched, pos->notify_delay_task);
1146 pos->notify_delay_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1147 }
1148 GNUNET_assert (NULL == n->transmit_handle);
1149 n->transmit_handle = pos;
1150 if (GNUNET_YES == n->received_ack)
1151 {
1152#if DEBUG_TRANSPORT
1153 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1154 "`%s' already received, scheduling request\n",
1155 "ACK");
1156#endif
1157 schedule_request (pos);
1158 }
1159 else
1160 {
1161#if DEBUG_TRANSPORT
1162 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1163 "Still need to wait to receive `%s' message\n",
1164 "ACK");
1165#endif
1166 pos->notify_delay_task
1167 = GNUNET_SCHEDULER_add_delayed (h->sched,
1168 GNUNET_NO,
1169 GNUNET_SCHEDULER_PRIORITY_KEEP,
1170 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1171 GNUNET_TIME_absolute_get_remaining
1172 (pos->timeout),
1173 &transmit_timeout, pos);
1174 }
1175 if (prev == NULL)
1176 h->connect_wait_head = next;
1177 else
1178 prev->next = next;
1179 break;
1180 }
1181 prev = pos;
1182 pos = next;
1183 }
1184}
1185
1186
1187/**
1188 * Connect to the transport service. Note that the connection may
1189 * complete (or fail) asynchronously.
1190 *
1191
1192 * @param sched scheduler to use
1193 * @param cfg configuration to use
1194 * @param cls closure for the callbacks
1195 * @param rec receive function to call
1196 * @param nc function to call on connect events
1197 * @param dc function to call on disconnect events
1198 */
1199struct GNUNET_TRANSPORT_Handle *
1200GNUNET_TRANSPORT_connect (struct GNUNET_SCHEDULER_Handle *sched,
1201 struct GNUNET_CONFIGURATION_Handle *cfg,
1202 void *cls,
1203 GNUNET_TRANSPORT_ReceiveCallback rec,
1204 GNUNET_TRANSPORT_NotifyConnect nc,
1205 GNUNET_TRANSPORT_NotifyDisconnect nd)
1206{
1207 struct GNUNET_TRANSPORT_Handle *ret;
1208
1209 GNUNET_ARM_start_service ("peerinfo",
1210 cfg, sched, START_SERVICE_TIMEOUT, NULL, NULL);
1211 GNUNET_ARM_start_service ("transport",
1212 cfg, sched, START_SERVICE_TIMEOUT, NULL, NULL);
1213 ret = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_Handle));
1214 ret->sched = sched;
1215 ret->cfg = cfg;
1216 ret->cls = cls;
1217 ret->rec = rec;
1218 ret->nc_cb = nc;
1219 ret->nd_cb = nd;
1220 ret->reconnect_delay = GNUNET_TIME_UNIT_ZERO;
1221 schedule_reconnect (ret);
1222 return ret;
1223}
1224
1225
1226/**
1227 * These stop activities must be run in a fresh
1228 * scheduler that is NOT in shutdown mode.
1229 */
1230static void
1231stop_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1232{
1233 struct GNUNET_TRANSPORT_Handle *handle = cls;
1234 GNUNET_ARM_stop_service ("transport",
1235 handle->cfg,
1236 tc->sched, STOP_SERVICE_TIMEOUT, NULL, NULL);
1237 GNUNET_ARM_stop_service ("peerinfo",
1238 handle->cfg,
1239 tc->sched, STOP_SERVICE_TIMEOUT, NULL, NULL);
1240}
1241
1242
1243/**
1244 * Disconnect from the transport service.
1245 */
1246void
1247GNUNET_TRANSPORT_disconnect (struct GNUNET_TRANSPORT_Handle *handle)
1248{
1249 struct GNUNET_TRANSPORT_TransmitHandle *th;
1250 struct NeighbourList *n;
1251 struct HelloWaitList *hwl;
1252 struct GNUNET_CLIENT_Connection *client;
1253
1254#if DEBUG_TRANSPORT
1255 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transport disconnect called!\n");
1256#endif
1257 while (NULL != (th = handle->connect_ready_head))
1258 {
1259 handle->connect_ready_head = th->next;
1260 th->notify (th->notify_cls, 0, NULL);
1261 GNUNET_free (th);
1262 }
1263
1264 while (NULL != (th = handle->connect_wait_head))
1265 {
1266 handle->connect_wait_head = th->next;
1267 if (th->notify_delay_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
1268 {
1269 GNUNET_SCHEDULER_cancel (handle->sched, th->notify_delay_task);
1270 th->notify_delay_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1271 }
1272 th->notify (th->notify_cls, 0, NULL);
1273 GNUNET_free (th);
1274 }
1275 while (NULL != (n = handle->neighbours))
1276 {
1277 handle->neighbours = n->next;
1278 GNUNET_free (n);
1279 }
1280 while (NULL != (hwl = handle->hwl_head))
1281 {
1282 handle->hwl_head = hwl->next;
1283 GNUNET_SCHEDULER_cancel (handle->sched, hwl->task);
1284 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1285 _
1286 ("Disconnect while trying to obtain HELLO from transport service.\n"));
1287 if (hwl->rec != NULL)
1288 hwl->rec (hwl->rec_cls, GNUNET_TIME_UNIT_ZERO, NULL, NULL);
1289 GNUNET_free (hwl);
1290 }
1291 if (handle->reconnect_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
1292 {
1293 GNUNET_SCHEDULER_cancel (handle->sched, handle->reconnect_task);
1294 handle->reconnect_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1295 }
1296 GNUNET_free_non_null (handle->my_hello);
1297 handle->my_hello = NULL;
1298 GNUNET_SCHEDULER_run (&stop_task, handle);
1299 if (NULL != (client = handle->client))
1300 {
1301#if DEBUG_TRANSPORT
1302 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1303 "Disconnecting from transport service for good.\n");
1304#endif
1305 handle->client = NULL;
1306 GNUNET_CLIENT_disconnect (client);
1307 }
1308 if (client == NULL)
1309 GNUNET_free (handle);
1310}
1311
1312
1313/**
1314 * We're ready to transmit the request that the transport service
1315 * should connect to a new peer. In addition to sending the
1316 * request, schedule the next phase for the transmission processing
1317 * that caused the connect request in the first place.
1318 */
1319static size_t
1320request_connect (void *cls, size_t size, void *buf)
1321{
1322 struct GNUNET_TRANSPORT_TransmitHandle *th = cls;
1323 struct TryConnectMessage *tcm;
1324 struct GNUNET_TRANSPORT_Handle *h;
1325
1326 h = th->handle;
1327 if (buf == NULL)
1328 {
1329#if DEBUG_TRANSPORT
1330 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1331 "Failed to transmit connect request to service.\n");
1332#endif
1333 th->notify (th->notify_cls, 0, NULL);
1334 GNUNET_free (th);
1335 return 0;
1336 }
1337#if DEBUG_TRANSPORT
1338 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1339 "Transmitting `%s' message for `%4s'.\n",
1340 "TRY_CONNECT", GNUNET_i2s (&th->target));
1341#endif
1342 GNUNET_assert (size >= sizeof (struct TryConnectMessage));
1343 tcm = buf;
1344 tcm->header.size = htons (sizeof (struct TryConnectMessage));
1345 tcm->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TRY_CONNECT);
1346 tcm->reserved = htonl (0);
1347 memcpy (&tcm->peer, &th->target, sizeof (struct GNUNET_PeerIdentity));
1348 th->notify_delay_task
1349 = GNUNET_SCHEDULER_add_delayed (h->sched,
1350 GNUNET_NO,
1351 GNUNET_SCHEDULER_PRIORITY_KEEP,
1352 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1353 GNUNET_TIME_absolute_get_remaining (th->
1354 timeout),
1355 &transmit_timeout, th);
1356 insert_transmit_handle (&h->connect_wait_head, th);
1357 return sizeof (struct TryConnectMessage);
1358}
1359
1360
1361/**
1362 * Schedule a request to connect to the given
1363 * neighbour (and if successful, add the specified
1364 * handle to the wait list).
1365 */
1366static void
1367try_connect (struct GNUNET_TRANSPORT_TransmitHandle *th)
1368{
1369 schedule_control_transmit (th->handle,
1370 sizeof (struct TryConnectMessage),
1371 GNUNET_NO,
1372 GNUNET_TIME_absolute_get_remaining (th->timeout),
1373 &request_connect, th);
1374}
1375
1376
1377/**
1378 * Cancel a pending notify transmit task
1379 * and also remove the given transmit handle
1380 * from whatever list is on.
1381 */
1382static void
1383remove_from_any_list (struct GNUNET_TRANSPORT_TransmitHandle *th)
1384{
1385 struct GNUNET_TRANSPORT_Handle *h;
1386
1387 h = th->handle;
1388 if (th->notify_delay_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
1389 {
1390 GNUNET_SCHEDULER_cancel (h->sched, th->notify_delay_task);
1391 th->notify_delay_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1392 }
1393 if (th->prev == NULL)
1394 {
1395 if (th == h->connect_wait_head)
1396 h->connect_wait_head = th->next;
1397 else
1398 h->connect_ready_head = th->next;
1399 }
1400 else
1401 th->prev->next = th->next;
1402 if (th->next != NULL)
1403 th->next->prev = th->prev;
1404}
1405
1406
1407/**
1408 * Remove neighbour from our list
1409 */
1410static void
1411remove_neighbour (struct GNUNET_TRANSPORT_Handle *h,
1412 const struct GNUNET_PeerIdentity *peer)
1413{
1414 struct NeighbourList *prev;
1415 struct NeighbourList *pos;
1416 struct GNUNET_TRANSPORT_TransmitHandle *th;
1417
1418 prev = NULL;
1419 pos = h->neighbours;
1420 while ((pos != NULL) &&
1421 (0 != memcmp (peer, &pos->id, sizeof (struct GNUNET_PeerIdentity))))
1422 {
1423 prev = pos;
1424 pos = pos->next;
1425 }
1426 if (pos == NULL)
1427 {
1428 GNUNET_break (0);
1429 return;
1430 }
1431 if (prev == NULL)
1432 h->neighbours = pos->next;
1433 else
1434 prev->next = pos->next;
1435 if (NULL != (th = pos->transmit_handle))
1436 {
1437 pos->transmit_handle = NULL;
1438 th->neighbour = NULL;
1439 remove_from_any_list (th);
1440 try_connect (th);
1441 }
1442 if (h->nc_cb != NULL)
1443 h->nd_cb (h->cls, peer);
1444 GNUNET_free (pos);
1445}
1446
1447
1448/**
1449 * Type of a function to call when we receive a message
1450 * from the service.
1451 *
1452 * @param cls closure
1453 * @param msg message received, NULL on timeout or fatal error
1454 */
1455static void
1456demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg)
1457{
1458 struct GNUNET_TRANSPORT_Handle *h = cls;
1459 const struct DisconnectInfoMessage *dim;
1460 const struct ConnectInfoMessage *cim;
1461 const struct InboundMessage *im;
1462 const struct GNUNET_MessageHeader *imm;
1463 const struct SendOkMessage *okm;
1464 struct HelloWaitList *hwl;
1465 struct NeighbourList *n;
1466 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
1467 struct GNUNET_PeerIdentity me;
1468 uint16_t size;
1469
1470 if ((msg == NULL) || (h->client == NULL))
1471 {
1472 if (h->client != NULL)
1473 {
1474#if DEBUG_TRANSPORT
1475 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1476 "Error receiving from transport service, disconnecting temporarily.\n");
1477#endif
1478 if (h->network_handle != NULL)
1479 {
1480 GNUNET_NETWORK_notify_transmit_ready_cancel (h->network_handle);
1481 h->network_handle = NULL;
1482 h->transmission_scheduled = GNUNET_NO;
1483 }
1484 GNUNET_CLIENT_disconnect (h->client);
1485 h->client = NULL;
1486 schedule_reconnect (h);
1487 }
1488 else
1489 {
1490 /* shutdown initiated from 'GNUNET_TRANSPORT_disconnect',
1491 finish clean up work! */
1492 GNUNET_free (h);
1493 }
1494 return;
1495 }
1496 GNUNET_CLIENT_receive (h->client,
1497 &demultiplexer, h, GNUNET_TIME_UNIT_FOREVER_REL);
1498 size = ntohs (msg->size);
1499 switch (ntohs (msg->type))
1500 {
1501 case GNUNET_MESSAGE_TYPE_HELLO:
1502 if (GNUNET_OK !=
1503 GNUNET_HELLO_get_key ((const struct GNUNET_HELLO_Message *) msg,
1504 &pkey))
1505 {
1506 GNUNET_break (0);
1507 break;
1508 }
1509 GNUNET_CRYPTO_hash (&pkey,
1510 sizeof (struct
1511 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
1512 &me.hashPubKey);
1513#if DEBUG_TRANSPORT
1514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1515 "Receiving (my own) `%s' message, I am `%4s'.\n",
1516 "HELLO", GNUNET_i2s (&me));
1517#endif
1518 GNUNET_free_non_null (h->my_hello);
1519 h->my_hello = NULL;
1520 if (size < sizeof (struct GNUNET_MessageHeader))
1521 {
1522 GNUNET_break (0);
1523 break;
1524 }
1525 h->my_hello = GNUNET_malloc (size);
1526 memcpy (h->my_hello, msg, size);
1527 while (NULL != (hwl = h->hwl_head))
1528 {
1529 h->hwl_head = hwl->next;
1530 GNUNET_SCHEDULER_cancel (h->sched, hwl->task);
1531 GNUNET_TRANSPORT_get_hello (h,
1532 GNUNET_TIME_UNIT_ZERO,
1533 hwl->rec, hwl->rec_cls);
1534 GNUNET_free (hwl);
1535 }
1536 break;
1537 case GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT:
1538 if (size != sizeof (struct ConnectInfoMessage))
1539 {
1540 GNUNET_break (0);
1541 break;
1542 }
1543 cim = (const struct ConnectInfoMessage *) msg;
1544#if DEBUG_TRANSPORT
1545 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1546 "Receiving `%s' message for `%4s'.\n",
1547 "CONNECT", GNUNET_i2s (&cim->id));
1548#endif
1549 add_neighbour (h,
1550 ntohl (cim->quota_out),
1551 GNUNET_TIME_relative_ntoh (cim->latency), &cim->id);
1552 break;
1553 case GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT:
1554 if (size != sizeof (struct DisconnectInfoMessage))
1555 {
1556 GNUNET_break (0);
1557 break;
1558 }
1559 dim = (const struct DisconnectInfoMessage *) msg;
1560#if DEBUG_TRANSPORT
1561 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1562 "Receiving `%s' message for `%4s'.\n",
1563 "DISCONNECT", GNUNET_i2s (&dim->peer));
1564#endif
1565 remove_neighbour (h, &dim->peer);
1566 break;
1567 case GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK:
1568#if DEBUG_TRANSPORT
1569 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1570 "Receiving `%s' message.\n", "SEND_OK");
1571#endif
1572 if (size != sizeof (struct SendOkMessage))
1573 {
1574 GNUNET_break (0);
1575 break;
1576 }
1577 okm = (const struct SendOkMessage *) msg;
1578 n = find_neighbour (h, &okm->peer);
1579 GNUNET_assert (n != NULL);
1580 n->transmit_ok = GNUNET_YES;
1581 if (n->transmit_handle != NULL)
1582 {
1583#if DEBUG_TRANSPORT
1584 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1585 "Processing pending message\n");
1586#endif
1587 GNUNET_SCHEDULER_cancel (h->sched,
1588 n->transmit_handle->notify_delay_task);
1589 n->transmit_handle->notify_delay_task =
1590 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1591 GNUNET_assert (GNUNET_YES == n->received_ack);
1592 schedule_request (n->transmit_handle);
1593 }
1594 break;
1595 case GNUNET_MESSAGE_TYPE_TRANSPORT_RECV:
1596#if DEBUG_TRANSPORT
1597 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1598 "Receiving `%s' message.\n", "RECV");
1599#endif
1600 if (size <
1601 sizeof (struct InboundMessage) +
1602 sizeof (struct GNUNET_MessageHeader))
1603 {
1604 GNUNET_break (0);
1605 break;
1606 }
1607 im = (const struct InboundMessage *) msg;
1608 imm = (const struct GNUNET_MessageHeader *) &im[1];
1609 if (ntohs (imm->size) + sizeof (struct InboundMessage) != size)
1610 {
1611 GNUNET_break (0);
1612 break;
1613 }
1614 switch (ntohs (imm->type))
1615 {
1616 case GNUNET_MESSAGE_TYPE_TRANSPORT_ACK:
1617#if DEBUG_TRANSPORT
1618 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1619 "Receiving `%s' message from `%4s'.\n",
1620 "ACK", GNUNET_i2s (&im->peer));
1621#endif
1622 n = find_neighbour (h, &im->peer);
1623 if (n == NULL)
1624 {
1625 GNUNET_break (0);
1626 break;
1627 }
1628 if (n->received_ack == GNUNET_NO)
1629 {
1630 n->received_ack = GNUNET_YES;
1631 if (NULL != n->transmit_handle)
1632 {
1633#if DEBUG_TRANSPORT
1634 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1635 "Peer connected, scheduling delayed message for deliverery now.\n");
1636#endif
1637 schedule_request (n->transmit_handle);
1638 }
1639 }
1640 break;
1641 default:
1642#if DEBUG_TRANSPORT
1643 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1644 "Received message of type %u from `%4s'.\n",
1645 ntohs (imm->type), GNUNET_i2s (&im->peer));
1646#endif
1647 if (h->rec != NULL)
1648 h->rec (h->cls,
1649 GNUNET_TIME_relative_ntoh (im->latency), &im->peer, imm);
1650 break;
1651 }
1652 break;
1653 default:
1654 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1655 _
1656 ("Received unexpected message of type %u from `%4s' in %s:%u\n"),
1657 ntohs (msg->type), GNUNET_i2s (&im->peer), __FILE__,
1658 __LINE__);
1659 GNUNET_break (0);
1660 break;
1661 }
1662}
1663
1664
1665struct ClientTransmitWrapper
1666{
1667 GNUNET_NETWORK_TransmitReadyNotify notify;
1668 void *notify_cls;
1669 struct GNUNET_TRANSPORT_TransmitHandle *th;
1670};
1671
1672
1673/**
1674 * Transmit message of a client destined for another
1675 * peer to the service.
1676 */
1677static size_t
1678client_notify_wrapper (void *cls, size_t size, void *buf)
1679{
1680 struct ClientTransmitWrapper *ctw = cls;
1681 struct OutboundMessage *obm;
1682 struct GNUNET_MessageHeader *hdr;
1683 size_t ret;
1684
1685 if (size == 0)
1686 {
1687#if DEBUG_TRANSPORT
1688 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1689 "Transmission request could not be satisfied.\n");
1690#endif
1691 ret = ctw->notify (ctw->notify_cls, 0, NULL);
1692 GNUNET_assert (ret == 0);
1693 GNUNET_free (ctw);
1694 return 0;
1695 }
1696 GNUNET_assert (size >= sizeof (struct OutboundMessage));
1697 obm = buf;
1698 ret = ctw->notify (ctw->notify_cls,
1699 size - sizeof (struct OutboundMessage),
1700 (void *) &obm[1]);
1701 if (ret == 0)
1702 {
1703 /* Need to reset flag, no SEND means no SEND_OK! */
1704 ctw->th->neighbour->transmit_ok = GNUNET_YES;
1705 GNUNET_free (ctw);
1706 return 0;
1707 }
1708 GNUNET_assert (ret >= sizeof (struct GNUNET_MessageHeader));
1709 hdr = (struct GNUNET_MessageHeader *) &obm[1];
1710 GNUNET_assert (ntohs (hdr->size) == ret);
1711 GNUNET_assert (ret + sizeof (struct OutboundMessage) <
1712 GNUNET_SERVER_MAX_MESSAGE_SIZE);
1713#if DEBUG_TRANSPORT
1714 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1715 "Transmitting `%s' message with data for `%4s'\n",
1716 "SEND", GNUNET_i2s (&ctw->th->target));
1717#endif
1718 ret += sizeof (struct OutboundMessage);
1719 obm->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SEND);
1720 obm->header.size = htons (ret);
1721 obm->reserved = htonl (0);
1722 obm->peer = ctw->th->target;
1723 GNUNET_free (ctw);
1724 return ret;
1725}
1726
1727
1728
1729/**
1730 * Check if we could queue a message of the given size for
1731 * transmission. The transport service will take both its
1732 * internal buffers and bandwidth limits imposed by the
1733 * other peer into consideration when answering this query.
1734 *
1735 * @param handle connection to transport service
1736 * @param target who should receive the message
1737 * @param size how big is the message we want to transmit?
1738 * @param timeout after how long should we give up (and call
1739 * notify with buf NULL and size 0)?
1740 * @param notify function to call when we are ready to
1741 * send such a message
1742 * @param notify_cls closure for notify
1743 * @return NULL if someone else is already waiting to be notified
1744 * non-NULL if the notify callback was queued (can be used to cancel
1745 * using GNUNET_TRANSPORT_notify_transmit_ready_cancel)
1746 */
1747struct GNUNET_TRANSPORT_TransmitHandle *
1748GNUNET_TRANSPORT_notify_transmit_ready (struct GNUNET_TRANSPORT_Handle
1749 *handle,
1750 const struct GNUNET_PeerIdentity
1751 *target, size_t size,
1752 struct GNUNET_TIME_Relative timeout,
1753 GNUNET_NETWORK_TransmitReadyNotify
1754 notify, void *notify_cls)
1755{
1756 struct GNUNET_TRANSPORT_TransmitHandle *pos;
1757 struct GNUNET_TRANSPORT_TransmitHandle *th;
1758 struct NeighbourList *n;
1759 struct ClientTransmitWrapper *ctw;
1760
1761 if (size + sizeof (struct OutboundMessage) >=
1762 GNUNET_SERVER_MAX_MESSAGE_SIZE)
1763 return NULL;
1764#if DEBUG_TRANSPORT
1765 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1766 "Asking transport service for transmission of %u bytes to peer `%4s'.\n",
1767 size, GNUNET_i2s (target));
1768#endif
1769 n = find_neighbour (handle, target);
1770 ctw = GNUNET_malloc (sizeof (struct ClientTransmitWrapper));
1771 th = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_TransmitHandle));
1772 ctw->notify = notify;
1773 ctw->notify_cls = notify_cls;
1774 ctw->th = th;
1775 th->handle = handle;
1776 th->target = *target;
1777 th->notify = &client_notify_wrapper;
1778 th->notify_cls = ctw;
1779 th->notify_size = size + sizeof (struct OutboundMessage);
1780 th->timeout = GNUNET_TIME_relative_to_absolute (timeout);
1781 th->neighbour = n;
1782 if (NULL == n)
1783 {
1784#if DEBUG_TRANSPORT
1785 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1786 "Transmission request could not be satisfied (not yet connected), adding it to pending request list.\n");
1787#endif
1788 pos = handle->connect_wait_head;
1789 while (pos != NULL)
1790 {
1791 GNUNET_assert (0 != memcmp (target,
1792 &pos->target,
1793 sizeof (struct GNUNET_PeerIdentity)));
1794 pos = pos->next;
1795 }
1796#if DEBUG_TRANSPORT
1797 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1798 "Will now try to connect to `%4s'.\n", GNUNET_i2s (target));
1799#endif
1800 try_connect (th);
1801 }
1802 else
1803 {
1804#if DEBUG_TRANSPORT
1805 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1806 "Transmission request queued for transmission to transport service.\n");
1807#endif
1808 GNUNET_assert (NULL == n->transmit_handle);
1809 n->transmit_handle = th;
1810 if (GNUNET_YES == n->received_ack)
1811 {
1812#if DEBUG_TRANSPORT
1813 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1814 "Peer `%4s' is connected, scheduling for delivery now.\n",
1815 GNUNET_i2s (target));
1816#endif
1817 schedule_request (th);
1818 }
1819 else
1820 {
1821#if DEBUG_TRANSPORT
1822 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1823 "Connection to `%4s' is not yet confirmed connected, scheduling timeout (%llums) only.\n",
1824 GNUNET_i2s (target), timeout.value);
1825#endif
1826 th->notify_delay_task
1827 = GNUNET_SCHEDULER_add_delayed (handle->sched,
1828 GNUNET_NO,
1829 GNUNET_SCHEDULER_PRIORITY_KEEP,
1830 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1831 timeout, &transmit_timeout, th);
1832 }
1833 }
1834 return th;
1835}
1836
1837
1838/**
1839 * Cancel the specified transmission-ready
1840 * notification.
1841 */
1842void
1843GNUNET_TRANSPORT_notify_transmit_ready_cancel (struct
1844 GNUNET_TRANSPORT_TransmitHandle
1845 *th)
1846{
1847 struct GNUNET_TRANSPORT_Handle *h;
1848
1849 GNUNET_assert (th->notify == &client_notify_wrapper);
1850 remove_from_any_list (th);
1851 h = th->handle;
1852 if ((h->connect_ready_head == NULL) && (h->network_handle != NULL))
1853 {
1854 GNUNET_NETWORK_notify_transmit_ready_cancel (h->network_handle);
1855 h->network_handle = NULL;
1856 h->transmission_scheduled = GNUNET_NO;
1857 }
1858 GNUNET_free (th->notify_cls);
1859 GNUNET_free (th);
1860}
1861
1862
1863/* end of transport_api.c */
diff --git a/src/upnp/Makefile.am b/src/upnp/Makefile.am
new file mode 100644
index 000000000..02a2b139d
--- /dev/null
+++ b/src/upnp/Makefile.am
@@ -0,0 +1,59 @@
1INCLUDES = -I$(top_srcdir)/src/include
2
3if MINGW
4 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
5endif
6
7if USE_COVERAGE
8 AM_CFLAGS = -fprofile-arcs -ftest-coverage
9endif
10
11lib_LTLIBRARIES = libgnunetupnp.la
12
13libgnunetupnp_la_SOURCES = \
14 upnp.c upnp.h \
15 upnp_ip.c upnp_ip.h \
16 upnp_util.c upnp_util.h \
17 upnp_xmlnode.c upnp_xmlnode.h
18libgnunetupnp_la_CFLAGS = \
19 -I$(top_scrdir)/include \
20 @LIBCURL_CPPFLAGS@ @XML_CPPFLAGS@
21libgnunetupnp_la_LIBADD = \
22 $(top_builddir)/src/util/libgnunetutil.la \
23 $(GN_LIBINTL) @EXT_LIBS@ @XML_LIBS@ @LIBCURL@
24libgnunetupnp_la_LDFLAGS = \
25 $(GN_LIB_LDFLAGS) $(WINFLAGS) \
26 -version-info 0:0:0
27
28
29bin_PROGRAMS = \
30 gnunet-upnp \
31 gnunet-service-upnp
32
33gnunet_upnp_SOURCES = \
34 gnunet-upnp.c
35gnunet_upnp_LDADD = \
36 $(top_builddir)/src/upnp/libgnunetupnp.la \
37 $(top_builddir)/src/util/libgnunetutil.la \
38 $(GN_LIBINTL)
39
40gnunet_service_upnp_SOURCES = \
41 gnunet-service-upnp.c
42gnunet_service_upnp_LDADD = \
43 $(top_builddir)/src/util/libgnunetutil.la \
44 $(GN_LIBINTL)
45
46
47check_PROGRAMS = \
48 test_upnp
49
50TESTS = $(check_PROGRAMS)
51
52test_upnp_SOURCES = \
53 test_upnp.c
54test_upnp_LDADD = \
55 $(top_builddir)/src/transport/libgnunetupnp.la \
56 $(top_builddir)/src/util/libgnunetutil.la
57
58
59# EXTRA_DIST = test_upnp_data.conf
diff --git a/src/upnp/draft-cheshire-nat-pmp.txt b/src/upnp/draft-cheshire-nat-pmp.txt
new file mode 100644
index 000000000..727b5fad7
--- /dev/null
+++ b/src/upnp/draft-cheshire-nat-pmp.txt
@@ -0,0 +1,1160 @@
1Document: draft-cheshire-nat-pmp-02.txt Stuart Cheshire
2Internet-Draft Marc Krochmal
3Category: Standards Track Apple Computer, Inc.
4Expires 14th March 2007 Kiren Sekar
5 Sharpcast, Inc.
6 14th September 2006
7
8 NAT Port Mapping Protocol (NAT-PMP)
9
10 <draft-cheshire-nat-pmp-02.txt>
11
12Status of this Memo
13
14 By submitting this Internet-Draft, each author represents that any
15 applicable patent or other IPR claims of which he or she is aware
16 have been or will be disclosed, and any of which he or she becomes
17 aware will be disclosed, in accordance with Section 6 of BCP 79.
18 For the purposes of this document, the term "BCP 79" refers
19 exclusively to RFC 3979, "Intellectual Property Rights in IETF
20 Technology", published March 2005.
21
22 Internet-Drafts are working documents of the Internet Engineering
23 Task Force (IETF), its areas, and its working groups. Note that
24 other groups may also distribute working documents as Internet-
25 Drafts.
26
27 Internet-Drafts are draft documents valid for a maximum of six months
28 and may be updated, replaced, or obsoleted by other documents at any
29 time. It is inappropriate to use Internet-Drafts as reference
30 material or to cite them other than as "work in progress."
31
32 The list of current Internet-Drafts can be accessed at
33 http://www.ietf.org/1id-abstracts.html
34
35 The list of Internet-Draft Shadow Directories can be accessed at
36 http://www.ietf.org/shadow.html
37
38
39Abstract
40
41 This document describes a protocol for automating the process of
42 creating Network Address Translation (NAT) port mappings. Included
43 in the protocol is a method for retrieving the public IP address of
44 a NAT gateway, thus allowing a client to make this public IP address
45 and port number known to peers that may wish to communicate with it.
46 This protocol is implemented in current Apple products including
47 Mac OS X, Bonjour for Windows, and AirPort wireless base stations.
48
49
50
51
52
53
54
55
56
57
58Expires 14th March 2007 Cheshire, et al. [Page 1]
59
60Internet Draft NAT Port Mapping Protocol 14th September 2006
61
62
631. Introduction
64
65 Network Address Translation (NAT) is a method of sharing one public
66 internet address with a number of devices. This document is focused
67 on what "IP Network Address Translator (NAT) Terminology and
68 Considerations" [RFC 2663] calls "NAPTs" (Network Address/Port
69 Translators). A full description of NAT is beyond the scope of this
70 document. The following brief overview will cover the aspects
71 relevant to this port mapping protocol. For more information on
72 NAT, see "Traditional IP Network Address Translator" [RFC 3022].
73
74 NATs have one or more public IP addresses. A private network is set
75 up behind the NAT. Devices behind the NAT are assigned private
76 addresses and the private address of the NAT device is used as the
77 gateway.
78
79 When a packet from any device behind the NAT is sent to an address on
80 the public internet, the packet first passes through the NAT box. The
81 NAT box looks at the source port and address. In some cases, a NAT
82 will also keep track of the destination port and address. The NAT
83 then creates a mapping from the private address and private port to a
84 public address and public port if a mapping does not already exist.
85 The NAT box replaces the private address and port number in the
86 packet with the public entries from the mapping and sends the packet
87 on to the next gateway.
88
89 When a packet from any address on the internet is received on the
90 NAT's public side, the NAT will look up the destination port (public
91 port) in the list of mappings. If an entry is found, it will contain
92 the private address and port that the packet should be sent to. The
93 NAT gateway will then rewrite the destination address and port with
94 those from the mapping. The packet will then be forwarded to the new
95 destination addresses. If the packet did not match any mapping, the
96 packet will most likely be dropped. Various NATs implement different
97 strategies to handle this. The important thing to note is that if
98 there is no mapping, the NAT does not know which private address the
99 packet should be sent to.
100
101 Mappings are usually created automatically as a result of observing
102 outbound traffic. There are a few exceptions. Some NATs may allow
103 manually-created permanent mappings that map a public port to a
104 specific private IP address and port. Such a mapping allows incoming
105 connections to the device with that private address. Some NATs also
106 implement a default mapping where any inbound traffic that does not
107 match a mapping will always be forwarded to a specific private
108 address. Both types of mappings are usually set up manually through
109 some configuration tool.
110
111 Without these manually-created inbound port mappings, clients behind
112 the NAT would be unable to receive inbound connections, which
113 represents a loss of connectivity when compared to the original
114
115
116Expires 14th March 2007 Cheshire, et al. [Page 2]
117
118Internet Draft NAT Port Mapping Protocol 14th September 2006
119
120
121 Internet architecture [ETEAISD]. For those who view this loss of
122 connectivity as a bad thing, NAT-PMP allows clients to operate much
123 more like a host directly connected to the unrestricted public
124 Internet, with an unrestricted public IP address. NAT-PMP allows
125 client hosts to communicate with the NAT gateway to request the
126 creation of inbound mappings on demand. Having created a NAT mapping
127 to allow inbound connections, the client can then record its public
128 IP address and public port number in a public registry (e.g. the
129 world-wide Domain Name System) or otherwise make it accessible to
130 peers that wish to communicate with it.
131
132
1332. Conventions and Terminology Used in this Document
134
135 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
136 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
137 document are to be interpreted as described in "Key words for use in
138 RFCs to Indicate Requirement Levels" [RFC 2119].
139
140
1413. Protocol and Packet Format
142
143 NAT Port Mapping Protocol runs over UDP. Every packet starts with an
144 8 bit version followed by an 8 bit operation code.
145
146 This document specifies version 0 of the protocol. Any NAT-PMP
147 gateway implementing this version of the protocol, receiving a
148 packet with a version number other than 0, MUST return result code 1
149 (Unsupported Version).
150
151 Opcodes between 0 and 127 are client requests. Opcodes from 128 to
152 255 are server responses. Responses always contain a 16 bit result
153 code in network byte order. A result code of zero indicates success.
154 Responses also contain a 32 bit unsigned integer corresponding to the
155 number of seconds since the NAT gateway was rebooted or since its
156 port mapping state was reset.
157
158 This protocol SHOULD only be used when the client determines that
159 its primary IPv4 address is in one of the private IP address ranges
160 defined in "Address Allocation for Private Internets" [RFC 1918].
161 This includes the address ranges 10/8, 172.16/12, and 192.168/16.
162
163 Clients always send their Port Mapping Protocol requests to their
164 default gateway, as learned via DHCP [RFC 2131], or similar means.
165 This protocol is designed for small home networks, with a single
166 logical link (subnet) where the client's default gateway is also the
167 NAT translator for that network. For more complicated networks where
168 the NAT translator is some device other than the client's default
169 gateway, this protocol is not appropriate.
170
171
172
173
174Expires 14th March 2007 Cheshire, et al. [Page 3]
175
176Internet Draft NAT Port Mapping Protocol 14th September 2006
177
178
1793.1 Requests and Responses
180
181 NAT gateways are often low-cost devices, with limited memory and
182 CPU speed. For this reason, to avoid making excessive demands on
183 the NAT gateway, clients machines SHOULD NOT issue multiple requests
184 simultaneously in parallel. If a client needs to perform multiple
185 requests (e.g. on boot, wake from sleep, network connection, etc.)
186 it SHOULD queue them and issue them serially one at a time. Once the
187 NAT gateway responds to one request the client machine may issue the
188 next. In the case of a fast NAT gateway, the client may be able to
189 complete requests at a rate of hundreds per second. In the case of
190 a slow NAT gateway that takes perhaps half a second to respond to
191 a NAT-PMP request, the client SHOULD respect this and allow the
192 NAT gateway to operate at the pace it can manage, and not overload
193 it by issuing requests faster than the rate it's answering them.
194
195 To determine the puclic IP address or request a port mapping,
196 a NAT-PMP client sends its request packet to port 5351 of its
197 configured gateway address, and waits 250ms for a response. If no
198 NAT-PMP response is received from the gateway after 250ms, the client
199 retransmits its request and waits 500ms. The client SHOULD repeat
200 this process with the interval between attempts doubling each time.
201 If, after sending its 9th attempt (and then waiting for 64 seconds),
202 the client has still received no response, then it SHOULD conclude
203 that this gateway does not support NAT Port Mapping Protocol and
204 MAY log an error message indicating this fact. In addition, if the
205 NAT-PMP client receives an "ICMP Port Unreachable" message from the
206 gateway for port 5351 then it can skip any remaining retransmissions
207 and conclude immediately that the gateway does not support NAT-PMP.
208
209 As a performance optimization the client MAY record this information
210 and use it to suppress further attempts to use NAT-PMP, but the
211 client should not retain this information for too long. In
212 particular, any event that may indicate a potential change of gateway
213 or a change in gateway configuration (hardware link change
214 indication, change of gateway MAC address, acquisition of new DHCP
215 lease, receipt of NAT-PMP announcement packet from gateway, etc.)
216 should cause the client to discard its previous information regarding
217 the gateway's lack of NAT-PMP support, and send its next NAT-PMP
218 request packet normally.
219
220
2213.2 Determining the Public Address
222
223 To determine the public address, the client behind the NAT sends the
224 following UDP payload to port 5351 of the configured gateway address:
225
226 0 1
227 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
228 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
229 | Vers = 0 | OP = 0 |
230 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
231
232Expires 14th March 2007 Cheshire, et al. [Page 4]
233
234Internet Draft NAT Port Mapping Protocol 14th September 2006
235
236
237 A compatible NAT gateway MUST generate a response with the following
238 format:
239
240 0 1 2 3
241 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
242 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
243 | Vers = 0 | OP = 128 + 0 | Result Code |
244 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
245 | Seconds Since Start of Epoch |
246 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
247 | Public IP Address (a.b.c.d) |
248 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
249
250 This response indicates that the NAT gateway implements this version
251 of the protocol and returns the public IP address of the NAT gateway.
252 If the result code is non-zero, the value of Public IP Address is
253 undefined (MUST be set to zero on transmission, and MUST be ignored
254 on reception).
255
256 The NAT gateway MUST fill in the "Seconds Since Start of Epoch" field
257 with the time elapsed since its port mapping table was initialized on
258 startup or reset for any other reason (see Section 3.6 "Seconds Since
259 Start of Epoch").
260
261 Upon receiving the response packet, the client MUST check the source
262 IP address, and silently discard the packet if the address is not the
263 address of the gateway to which the request was sent.
264
265
2663.2.1 Announcing Address Changes
267
268 When the public IP address of the NAT changes, the NAT gateway MUST
269 send a gratuitous response to the link-local multicast address
270 224.0.0.1, port 5351 with the packet format above to notify clients
271 of the new public IP address. To accommodate packet loss, the
272 NAT gateway SHOULD multicast 10 address change notifications.
273 The interval between the first two notifications SHOULD be 250ms,
274 and the interval between each subsequent notification SHOULD double.
275
276 Upon receiving a gratuitous address change announcement packet,
277 the client MUST check the source IP address, and silently discard
278 the packet if the address is not the address of the client's
279 current configured gateway. This is to guard against inadvertent
280 misconfigurations where there may be more than one NAT gateway
281 active on the network.
282
283
284
285
286
287
288
289
290Expires 14th March 2007 Cheshire, et al. [Page 5]
291
292Internet Draft NAT Port Mapping Protocol 14th September 2006
293
294
2953.3 Creating a Mapping
296
297 To create a mapping, the client sends a UDP packet to port 5351
298 of the gateway's private IP address with the following format:
299
300 0 1 2 3
301 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
302 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
303 | Vers = 0 | OP = x | Reserved (MUST be zero) |
304 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
305 | Private Port | Requested Public Port |
306 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
307 | Requested Port Mapping Lifetime in Seconds |
308 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
309
310 Opcodes supported:
311 1 - Map UDP
312 2 - Map TCP
313
314 The Reserved field MUST be set to zero on transmission and MUST
315 be ignored on reception.
316
317 The Private Port is set to the local port on which the client is
318 listening.
319
320 The Requested Public Port SHOULD usually be set to the same value as
321 the local Private Port, or zero if the client has no preference for
322 what port is assigned. However, the gateway is not obliged to assign
323 the port requested, and may choose not to, either for policy reasons
324 (e.g. port 80 is reserved and clients may not request it) or because
325 that port has already been assigned to some other client. Because
326 of this, some product developers have questioned the value of having
327 the Requested Public Port field at all. The reason is for failure
328 recovery. Most low-cost home NAT gateways do not record temporary
329 port mappings in persistent storage, so if the gateway crashes or is
330 rebooted, all the mappings are lost. A renewal packet is formatted
331 identically to an initial mapping request packet, except that for
332 renewals the client sets the Requested Public Port field to the
333 port the gateway actually assigned, rather than the port the client
334 originally wanted. When a freshly-rebooted NAT gateway receives a
335 renewal packet from a client, it appears to the gateway just like
336 an ordinary initial request for a port mapping, except that in this
337 case the Requested Public Port is likely to be one that the NAT
338 gateway *is* willing to allocate (it allocated it to this client
339 right before the reboot, so it should presumably be willing to
340 allocate it again).
341
342 The RECOMMENDED Port Mapping Lifetime is 3600 seconds.
343
344
345
346
347
348Expires 14th March 2007 Cheshire, et al. [Page 6]
349
350Internet Draft NAT Port Mapping Protocol 14th September 2006
351
352
353 After sending the port mapping request, the client then waits for the
354 NAT gateway to respond. If after 250ms, the gateway doesn't respond,
355 the client SHOULD re-issue its request as described above in Section
356 3.1 "Requests and Responses".
357
358 The NAT gateway responds with the following packet format:
359
360 0 1 2 3
361 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
362 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
363 | Vers = 0 | OP = 128 + x | Result Code |
364 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
365 | Seconds Since Start of Epoch |
366 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
367 | Private Port | Mapped Public Port |
368 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
369 | Port Mapping Lifetime in Seconds |
370 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
371
372 The 'x' in the OP field MUST match what the client requested. Some
373 NAT gateways are incapable of creating a UDP port mapping without
374 also creating a corresponding TCP port mapping, and vice versa, and
375 these gateways MUST NOT implement NAT Port Mapping Protocol until
376 this deficiency is fixed. A NAT gateway which implements this
377 protocol MUST be able to create TCP-only and UDP-only port mappings.
378
379 If a NAT gateway silently creates a pair of mappings for a client
380 that only requested one mapping, then it may expose that client to
381 receiving inbound UDP packets or inbound TCP connection requests
382 that it did not ask for and does not want.
383
384 While a NAT gateway MUST NOT automatically create mappings for TCP
385 when the client requests UDP, and vice versa, the NAT gateway MUST
386 reserve the companion port so the same client can choose to map it
387 in the future. For example, if a client requests to map TCP port 80,
388 as long as the client maintains the lease for that TCP port mapping,
389 another client with a different IP address MUST NOT be able to
390 successfully acquire the mapping for UDP port 80.
391
392 The client normally requests the public port matching the private
393 port. If that public port is not available, the NAT gateway MUST
394 return a public port that is available or return an error code if
395 no ports are available.
396
397 The source address of the packet MUST be used for the private address
398 in the mapping. This protocol is not intended to facilitate one
399 device behind a NAT creating mappings for other devices. If there
400 are legacy devices that require inbound mappings, permanent mappings
401 can be created manually by the administrator, just as they are today.
402
403
404
405
406Expires 14th March 2007 Cheshire, et al. [Page 7]
407
408Internet Draft NAT Port Mapping Protocol 14th September 2006
409
410
411 If a mapping already exists for a given private port on a given local
412 client (whether that mapping was created explicitly using NAT-PMP,
413 implicitly as a result of an outgoing TCP SYN packet, or manually by
414 a human administrator) and that client requests another mapping for
415 the same private port (possibly requesting a different public port)
416 then the mapping request should succeed, returning the already-
417 assigned public port. This is necessary to handle the case where
418 a client requests a mapping with requested public port X, and is
419 granted a mapping with actual public port Y, but the acknowledgement
420 packet gets lost. When the client retransmits its mapping request,
421 it should get back the same positive acknowledgement as was sent (and
422 lost) the first time.
423
424 The NAT gateway SHOULD NOT accept mapping requests destined to the
425 NAT gateway's public IP address or received on its public network
426 interface. Only packets received on the private interface(s) with
427 a destination address matching the private address(es) of the NAT
428 gateway should be allowed.
429
430 The NAT gateway MUST fill in the "Seconds Since Start of Epoch" field
431 with the time elapsed since its port mapping table was initialized on
432 startup or reset for any other reason (see Section 3.6 "Seconds Since
433 Start of Epoch").
434
435 The Port Mapping Lifetime is an unsigned integer in seconds. The NAT
436 gateway MAY reduce the lifetime from what the client requested. The
437 NAT gateway SHOULD NOT offer a lease lifetime greater than that
438 requested by the client.
439
440 Upon receiving the response packet, the client MUST check the source
441 IP address, and silently discard the packet if the address is not the
442 address of the gateway to which the request was sent.
443
444 The client SHOULD begin trying to renew the mapping halfway to expiry
445 time, like DHCP. The renewal packet should look exactly the same as
446 a request packet, except that the client SHOULD set the requested
447 public port to what the NAT gateway previously mapped, not what the
448 client originally requested. As described above, this enables the
449 gateway to automatically recover its mapping state after a crash or
450 reboot.
451
452
4533.4 Destroying a Mapping
454
455 A mapping may be destroyed in a variety of ways. If a client fails
456 to renew a mapping, then when its lifetime expires the mapping MUST
457 be automatically deleted. In the common case where the gateway
458 device is a combined DHCP server and NAT gateway, when a client's
459 DHCP address lease expires, the gateway device MAY automatically
460 delete any mappings belonging to that client. Otherwise a new client
461 being assigned the same IP address could receive unexpected inbound
462
463
464Expires 14th March 2007 Cheshire, et al. [Page 8]
465
466Internet Draft NAT Port Mapping Protocol 14th September 2006
467
468
469 UDP packets or inbound TCP connection requests that it did not ask
470 for and does not want.
471
472 A client MAY also send an explicit packet to request deletion of a
473 mapping that is no longer needed. A client requests explicit
474 deletion of a mapping by sending a message to the NAT gateway
475 requesting the mapping, with the Requested Lifetime in Seconds set
476 to 0. The requested public port MUST be set to zero by the client
477 on sending, and MUST be ignored by the gateway on reception.
478
479 When a mapping is destroyed successfully as a result of the client
480 explicitly requesting the deletion, the NAT gateway MUST send a
481 response packet which is formatted as defined in section 3.3
482 "Creating a Mapping". The response MUST contain a result code of 0,
483 the private port as indicated in the deletion request, a public port
484 of 0, and a lifetime of 0. The NAT gateway MUST respond to a request
485 to destroy a mapping that does not exist as if the request were
486 successful. This is because of the case where the acknowledgement is
487 lost, and the client retransmits its request to delete the mapping.
488 In this case the second request to delete the mapping MUST return the
489 same response packet as the first request.
490
491 If the deletion request was unsuccessful, the response MUST contain a
492 non-zero result code and the requested mapping; the lifetime is
493 undefined (MUST be set to zero on transmission, and MUST be ignored
494 on reception). If the client attempts to delete a port mapping which
495 was manually assigned by some kind of configuration tool, the NAT
496 gateway MUST respond with a 'Not Authorized' error, result code 2.
497
498 When a mapping is destroyed as a result of its lifetime expiring or
499 for any other reason, if the NAT gateway's internal state indicates
500 that there are still active TCP connections traversing that now-
501 defunct mapping, then the NAT gateway SHOULD send appropriately-
502 constructed TCP RST (reset) packets both to the local client and to
503 the remote peer on the Internet to terminate that TCP connection.
504
505 A client can request the explicit deletion of all its UDP or TCP
506 mappings by sending the same deletion request to the NAT gateway
507 with public port, private port, and lifetime set to 0. A client MAY
508 choose to do this when it first acquires a new IP address in order to
509 protect itself from port mappings that were performed by a previous
510 owner of the IP address. After receiving such a deletion request,
511 the gateway MUST delete all its UDP or TCP port mappings (depending
512 on the opcode). The gateway responds to such a deletion request with
513 a response as described above, with the private port set to zero. If
514 the gateway is unable to delete a port mapping, for example, because
515 the mapping was manually configured by the administrator, the gateway
516 MUST still delete as many port mappings as possible, but respond with
517 a non-zero result code. The exact result code to return depends on
518 the cause of the failure. If the gateway is able to successfully
519 delete all port mappings as requested, it MUST respond with a result
520 code of 0.
521
522Expires 14th March 2007 Cheshire, et al. [Page 9]
523
524Internet Draft NAT Port Mapping Protocol 14th September 2006
525
526
5273.5 Result Codes
528
529 Currently defined result codes:
530 0 - Success
531 1 - Unsupported Version
532 2 - Not Authorized/Refused
533 (e.g. box supports mapping, but user has turned feature off)
534 3 - Network Failure
535 (e.g. NAT box itself has not obtained a DHCP lease)
536 4 - Out of resources
537 (NAT box cannot create any more mappings at this time)
538 5 - Unsupported opcode
539
540 If the result code is non-zero, the format of the packet following
541 the result code may be truncated. For example, if the client sends a
542 request to the server with an opcode of 17 and the server does not
543 recognize that opcode, the server SHOULD respond with a message where
544 the opcode is 17 + 128 and the result code is 5 (opcode not
545 supported). Since the server does not understand the format of
546 opcode 17, it may not know what to place after the result code. In
547 some cases, relevant data may follow the opcode to identify the
548 operation that failed. For example, a client may request a mapping
549 but that mapping may fail due to resource exhaustion. The server
550 SHOULD respond with the result code to indicate resource exhaustion
551 (4) followed by the requested port mapping so the client may identify
552 which operation failed.
553
554 Clients MUST be able to properly handle result codes not defined in
555 this document. Undefined results codes MUST be treated as fatal
556 errors of the request.
557
558
5593.6 Seconds Since Start of Epoch
560
561 Every packet sent by the NAT gateway includes a "Seconds since start
562 of epoch" field (SSSOE). If the NAT gateway resets or loses the
563 state of its port mapping table, due to reboot, power failure, or any
564 other reason, it MUST reset its epoch time and begin counting SSSOE
565 from 0 again. Whenever a client receives any packet from the NAT
566 gateway, either gratuitously or in response to a client request, the
567 client computes its own conservative estimate of the expected SSSOE
568 value by taking the SSSOE value in the last packet it received from
569 the gateway and adding 7/8 (87.5%) of the time elapsed since that
570 packet was received. If the SSSOE in the newly received packet is
571 less than the client's conservative estimate by more than one second,
572 then the client concludes that the NAT gateway has undergone a reboot
573 or other loss of port mapping state, and the client MUST immediately
574 renew all its active port mapping leases as described in Section 3.7
575 "Recreating Mappings On NAT Gateway Reboot".
576
577
578
579
580Expires 14th March 2007 Cheshire, et al. [Page 10]
581
582Internet Draft NAT Port Mapping Protocol 14th September 2006
583
584
5853.7 Recreating Mappings On NAT Gateway Reboot
586
587 The NAT gateway MAY store mappings in persistent storage so when it
588 is powered off or rebooted, it remembers the port mapping state of
589 the network.
590
591 However, maintaining this state is not essential for correct
592 operation. When the NAT gateway powers on or clears its port mapping
593 state as the result of a configuration change, it MUST reset the
594 epoch time and re-announce its IP address as described in Section
595 3.2.1 "Announcing Address Changes". Reception of this packet where
596 time has apparently gone backwards serves as a hint to clients
597 on the network that they SHOULD immediately send renewal packets
598 (to immediately recreate their mappings) instead of waiting until
599 the originally scheduled time for those renewals. Clients who miss
600 receiving those gateway announcement packets for any reason will
601 still renew their mappings at the originally scheduled time and cause
602 their mappings to be recreated; it will just take a little longer for
603 these clients.
604
605 A mapping renewal packet is formatted identically to an original
606 mapping request; from the point of view of the client it is a
607 renewal of an existing mapping, but from the point of view of the
608 freshly-rebooted NAT gateway it appears as a new mapping request.
609
610 This self-healing property of the protocol is very important.
611
612 The remarkable reliability of the Internet as a whole derives
613 in large part from the fact that important state is held in the
614 endpoints, not in the network itself [ETEAISD]. Power-cycling an
615 Ethernet switch results only in a brief interruption in the flow
616 of packets; established TCP connections through that switch are not
617 broken, merely delayed for a few seconds. Indeed, an old Ethernet
618 switch can even be replaced with a new one, and as long as the cables
619 are transferred over reasonably quickly, after the upgrade all the
620 TCP connections that were previously going though the old switch will
621 be unbroken and now going through the new one. The same is true of
622 IP routers, wireless base stations, etc. The one exception is NAT
623 gateways. Because the port mapping state is required for the NAT
624 gateway to know where to forward inbound packets, loss of that state
625 breaks connectivity through the NAT gateway. By allowing clients to
626 detect when this loss of NAT gateway state has occurred, and recreate
627 it on demand, we turn hard state in the network into soft state, and
628 allow it to be recovered automatically when needed.
629
630 Without this automatic recreation of soft state in the NAT gateway,
631 reliable long-term networking would not be achieved. As mentioned
632 above, the reliability of the Internet does not come from trying
633 to build a perfect network in which errors never happen, but from
634 accepting that in any sufficiently large system there will always be
635 some component somewhere that's failing, and designing mechanisms
636
637
638Expires 14th March 2007 Cheshire, et al. [Page 11]
639
640Internet Draft NAT Port Mapping Protocol 14th September 2006
641
642
643 that can handle those failures and recover. To illustrate this point
644 with an example, consider the following scenario: Imagine a network
645 security camera that has a web interface and accepts incoming
646 connections from web browser clients. Imagine this network security
647 camera uses NAT-PMP or a similar protocol to set up an inbound
648 port mapping in the NAT gateway so that it can receive incoming
649 connections from clients the other side of the NAT gateway.
650 Now, this camera may well operate for weeks, months, or even years.
651 During that time it's possible that the NAT gateway could experience
652 a power failure or be rebooted. The user could upgrade the NAT
653 gateway's firmware, or even replace the entire NAT gateway device
654 with a newer model. The general point is that if the camera operates
655 for a long enough period of time, some kind of disruption to the NAT
656 gateway becomes inevitable. The question is not whether the NAT
657 gateway will lose its port mappings, but when, and how often.
658 If the network camera and devices like it on the network can detect
659 when the NAT gateway has lost its port mappings, and recreate them
660 automatically, then these disruptions are self-correcting and
661 invisible to the end user. If, on the other hand, the disruptions are
662 not self-correcting, and after a NAT gateway reboot the user has to
663 manually reset or reboot all the other devices on the network too,
664 then these disruptions are *very* visible to the end user. This
665 aspect of the design is what makes the difference between a protocol
666 that keeps on working indefinitely over a time scale of months or
667 years, and a protocol that works in brief testing, but in the real
668 world is continually failing and requiring manual intervention to get
669 it going again.
670
671 When a client renews its port mappings as the result of receiving
672 a packet where the "Seconds since start of epoch" field (SSSOE)
673 indicates that a reboot or similar loss of state has occurred,
674 the client MUST first delay by a random amount of time selected
675 with uniform random distribution in the range 0 to 5 seconds, and
676 then send its first port mapping request. After that request is
677 acknowledged by the gateway, the client may then send its second
678 request, and so on, as rapidly as the gateway allows. The requests
679 SHOULD be issued serially, one at a time; the client SHOULD NOT issue
680 multiple requests simultaneously in parallel.
681
682 The discussion in this section focusses on recreating inbound port
683 mappings after loss of NAT gateway state, because that is the more
684 serious problem. Losing port mappings for outgoing connections
685 destroys those currently active connections, but does not prevent
686 clients from establishing new outgoing connections. In contrast,
687 losing inbound port mappings not only destroys all existing inbound
688 connections, but also prevents the reception of any new inbound
689 connections until the port mapping is recreated. Accordingly,
690 we consider recovery of inbound port mappings the more important
691 priority. However, clients that want outgoing connections to survive
692 a NAT gateway reboot can also achieve that using NAT-PMP. After
693 initiating an outbound TCP connection (which will cause the NAT
694
695
696Expires 14th March 2007 Cheshire, et al. [Page 12]
697
698Internet Draft NAT Port Mapping Protocol 14th September 2006
699
700
701 gateway to establish an implicit port mapping) the client should send
702 the NAT gateway a port mapping request for the source port of its TCP
703 connection, which will cause the NAT gateway to send a response
704 giving the public port it allocated for that mapping. The client can
705 then store this information, and use later to recreate the mapping
706 if it determines that the NAT gateway has lost its mapping state.
707
708
7093.8 NAT Gateways with NAT Function Disabled
710
711 Note that *only* devices currently acting in the role of NAT gateway
712 should participate in NAT-PMP protocol exchanges with clients.
713 A network device that is capable of NAT (and NAT-PMP), but is
714 currently configured not to perform that function, (e.g. it is
715 acting as a traditional IP router, forwarding packets without
716 modifying them), MUST NOT respond to NAT-PMP requests from clients,
717 or send spontaneous NAT-PMP address-change announcements.
718
719 In particular, a network device not currently acting in the role of
720 NAT gateway should not even respond to NAT-PMP requests by returning
721 an error code such as "2 - Not Authorized/Refused", since to do so
722 is misleading to clients -- it suggests that NAT port mapping is
723 necessary on this network for the client to successfully receive
724 inbound connections, but is not available because the administrator
725 has chosen to disable that functionality.
726
727 Clients should also be careful to avoid making unfounded assumptions,
728 such as the assumption that if the client has an IPv4 address in
729 one of the RFC 1918 private IP address ranges then that means
730 NAT necessarily must be in use. Net 10/8 has enough addresses
731 to build a private network with millions of hosts and thousands
732 of interconnected subnets, all without any use of NAT. Many
733 organizations have built such private networks that benefit from
734 using standard TCP/IP technology, but by choice do not connect
735 to the public Internet. The purpose of NAT-PMP is to mitigate some
736 of the damage caused by NAT. It would be an ironic and unwanted
737 side-effect of this protocol if it were to lead well-meaning but
738 misguided developers to create products that refuse to work on a
739 private network *unless* they can find a NAT gateway to talk to.
740 Consequently, a client finding that NAT-PMP is not available on its
741 network should not give up, but should proceed on the assumption
742 that the network may be a traditional routed IP network, with no
743 address translation being used. This assumption may not always be
744 true, but it is better than the alternative of falsely assuming
745 the worst and not even trying to use normal (non-NAT) IP networking.
746
747 If a network device not currently acting in the role of NAT gateway
748 receives UDP packets addressed to port 5351, it SHOULD respond
749 immediately with an "ICMP Port Unreachable" message to tell the
750 client that it needn't continue with timeouts and retransmissions,
751 and it should assume that NAT-PMP is not available and not needed
752 on this network.
753
754Expires 14th March 2007 Cheshire, et al. [Page 13]
755
756Internet Draft NAT Port Mapping Protocol 14th September 2006
757
758
7594. UNSAF Considerations
760
761 The document "IAB Considerations for UNSAF Across NAT" [RFC 3424]
762 covers a number of issues when working with NATs. RFC 3424 outlines
763 some requirements for any document that attempts to work around
764 problems associated with NATs. This section addresses those
765 requirements.
766
767
7684.1 Scope
769
770 This protocol addresses the needs of TCP and UDP transport peers that
771 are separated from the public internet by exactly one NAT. Such
772 peers must have access to some form of directory server for
773 registering the public IP address and port at which they can be
774 reached.
775
776
7774.2 Transition Plan
778
779 Any client making use of this protocol SHOULD implement IPv6 support.
780 If a client supports IPv6 and is running on a device with a global
781 IPv6 address, that IPv6 address SHOULD be preferred to the IPv4
782 public address using this NAT mapping protocol. In case other
783 clients do not have IPv6 connectivity, both the IPv4 and IPv6
784 addresses SHOULD be registered with whatever form of directory server
785 is used. Preference SHOULD be given to IPv6 addresses when
786 available. By implementing support for IPv6 and using this protocol
787 for IPv4, vendors can ship products today that will work under both
788 scenarios. As IPv6 is more widely deployed, clients of this protocol
789 following these recommendations will transparently make use of IPv6.
790
791
7924.3 Failure Cases
793
794 Aside from NATs that do not implement this protocol, there are a
795 number of situations where this protocol may not work.
796
797
7984.3.1 NAT Behind NAT
799
800 Some people's primary IP address, assigned by their ISP, may itself
801 be a NAT address. In addition, some people may have a public IP
802 address, but may then double NAT themselves, perhaps by choice or
803 perhaps by accident. Although it might be possible in principle for
804 one NAT gateway to recursively request a mapping from the next one,
805 this document does not advocate that and does not try to prescribe
806 how it would be done.
807
808 It would be a lot of work to implement nested NAT port mapping
809 correctly, and there are a number of reasons why the end result might
810
811
812Expires 14th March 2007 Cheshire, et al. [Page 14]
813
814Internet Draft NAT Port Mapping Protocol 14th September 2006
815
816
817 not be as useful as we might hope. Consider the case of an ISP that
818 offers each of its customers only a single NAT address. This ISP
819 could instead have chosen to provide each customer with a single
820 public IP address, or, if the ISP insists on running NAT, it could
821 have chosen to allow each customer a reasonable number of addresses,
822 enough for each customer device to have its own NAT address directly
823 from the ISP. If instead this ISP chooses to allow each customer
824 just one and only one NAT address, forcing said customer to run
825 nested NAT in order to use more than one device, it seems unlikely
826 that such an ISP would be so obliging as to provide a NAT service
827 that supports NAT Port Mapping Protocol. Supposing that such an ISP
828 did wish to offer its customers NAT service with NAT-PMP so as to
829 give them the ability to receive inbound connections, this ISP could
830 easily choose to allow each client to request a reasonable number of
831 DHCP addresses from that gateway. Remember that Net 10/8 [RFC 1918]
832 allows for over 16 million addresses, so NAT addresses are not in any
833 way in short supply. A single NAT gateway with 16 million available
834 addresses is likely to run out of packet forwarding capacity before
835 it runs out of private addresses to hand out. In this way the ISP
836 could offer single-level NAT with NAT-PMP, obviating the need to
837 support nested NAT-PMP. In addition, an ISP that is motivated to
838 provide their customers with unhindered access to the Internet by
839 allowing incoming as well as outgoing connections has better ways
840 to offer this service. Such an ISP could offer its customers real
841 public IP addresses instead of NAT addresses, or could even choose
842 to offer its customers full IPv6 connectivity, where no mapping or
843 translation is required at all.
844
845
8464.3.2 NATs with Multiple Public IP Addresses
847
848 If a NAT maps private addresses to multiple public addresses,
849 then it SHOULD pick one of those addresses as the one it will
850 support for inbound connections, and for the purposes of this
851 protocol it SHOULD act as if that address were its only address.
852
853
8544.3.3 NATs and Routed Private Networks
855
856 In some cases, a large network may be subnetted. Some sites
857 may install a NAT gateway and subnet the private network.
858 Such subnetting breaks this protocol because the router address
859 is not necessarily the address of the device performing NAT.
860
861 Addressing this problem is not a high priority. Any site with the
862 resources to set up such a configuration should have the resources to
863 add manual mappings or attain a range of globally unique addresses.
864
865 Not all NATs will support this protocol. In the case where a client
866 is run behind a NAT that does not support this protocol, the software
867 relying on the functionality of this protocol may be unusable.
868
869
870Expires 14th March 2007 Cheshire, et al. [Page 15]
871
872Internet Draft NAT Port Mapping Protocol 14th September 2006
873
874
8754.3.4 Communication Between Hosts Behind the Same NAT
876
877 NAT gateways supporting NAT-PMP should also implement "hairpin
878 translation". Hairpin translation means supporting communication
879 between two local clients being served by the same NAT gateway.
880
881 Suppose device A is listening on private address and port 10.0.0.2:80
882 for incoming connections. Using NAT-PMP, device A has obtained a
883 mapping to public address and port x.x.x.x:80, and has recorded this
884 public address and port in a public directory of some kind. For
885 example, it could have created a DNS SRV record containing this
886 information, and recorded it, using DNS Dynamic Update [RFC 3007], in
887 a publicly accessible DNS server. Suppose then that device B, behind
888 the same NAT gateway as device A, but unknowing or uncaring of this
889 fact, retrieves device A's DNS SRV record and attempts to open a TCP
890 connection to x.x.x.x:80. The outgoing packets addressed to this
891 public Internet address will be sent to the NAT gateway for
892 translation and forwarding. Having translated the source address and
893 port number on the outgoing packet, the NAT gateway needs to be smart
894 enough to recognize that the destination address is in fact itself,
895 and then feed this packet back into its packet reception engine, to
896 perform the destination port mapping lookup to translate and forward
897 this packet to device A at address and port 10.0.0.2:80.
898
8994.3.5 Non UDP/TCP Transport Traffic
900
901 Any communication over transport protocols other than TCP and UDP
902 will not be served by this protocol. Examples are Generic Routing
903 Encapsulation (GRE), Authentication Header (AH) and Encapsulating
904 Security Payload (ESP).
905
9064.4 Long Term Solution
907
908 As IPv6 is deployed, clients of this protocol supporting IPv6 will be
909 able to bypass this protocol and the NAT when communicating with
910 other IPv6 devices. In order to ensure this transition, any client
911 implementing this protocol SHOULD also implement IPv6 and use this
912 solution only when IPv6 is not available to both peers.
913
9144.5 Existing Deployed NATs
915
916 Existing deployed NATs will not support this protocol. This protocol
917 will only work with NATs that are upgraded to support it.
918
919
920
921
922
923
924
925
926
927
928Expires 14th March 2007 Cheshire, et al. [Page 16]
929
930Internet Draft NAT Port Mapping Protocol 14th September 2006
931
932
9335. Security Considerations
934
935 As discussed in section 3.2 "Determining the Public Address", only
936 clients on the private side of the NAT may create port mappings, and
937 only on behalf of themselves. By using IP address spoofing, it's
938 possible for one client to delete the port mappings of another
939 client. It's also possible for one client to create port mappings on
940 behalf of another client. The best way to deal with this
941 vulnerability is to use IPSec [RFC 2401].
942
943 Since allowing incoming connections is often a policy decision, any
944 NAT gateway implementing this protocol SHOULD have an administrative
945 mechanism to disable it.
946
947 Some people view the property that NATs block inbound connections as
948 a security benefit which is undermined by this protocol. The authors
949 of this document have a different point of view. In the days before
950 NAT, all hosts had unique public IP addresses, and had unhindered
951 ability to communicate with any other host on the Internet. When NAT
952 came along it broke this unhindered connectivity, relegating many
953 hosts to second-class status, unable to receive inbound connections.
954 This protocol goes some way to undo some of that damage. The purpose
955 of a NAT gateway should be to allow several hosts to share a single
956 address, not to simultaneously impede those host's ability to
957 communicate freely. Security is most properly provided by end-to-end
958 cryptographic security, and/or by explicit firewall functionality, as
959 appropriate. Blocking of certain connections should occur only as a
960 result of explicit and intentional firewall policy, not as an
961 accidental side-effect of some other technology.
962
963
9646. IANA Considerations
965
966 No IANA services are required by this document.
967
968
9697. Acknowledgments
970
971 The concepts described in this document have been explored, developed
972 and implemented with help from Bob Bradley, Josh Graessley, Rob
973 Newberry, Roger Pantos, John Saxton, and James Woodyatt.
974
975
9768. Deployment History
977
978 NAT-PMP client software first became available to the public
979 through Apple's Darwin Open Source code in August 2004.
980 NAT-PMP implementations began shipping to end users in large
981 volumes (i.e. millions) with the launch of Mac OS X 10.4 Tiger
982 and Bonjour for Windows 1.0 in April 2005.
983
984
985
986Expires 14th March 2007 Cheshire, et al. [Page 17]
987
988Internet Draft NAT Port Mapping Protocol 14th September 2006
989
990
991 The NAT-PMP client in Mac OS X 10.4 Tiger and Bonjour for Windows
992 exists as part of the mDNSResponder system service. When a client
993 advertises a service using Wide Area Bonjour [DNS-SD], and the
994 machine is behind a NAT-PMP-capable NAT gateway, then if the machine
995 is so configured, the mDNSResponder system service automatically uses
996 NAT-PMP to set up an inbound port mapping, and then records the
997 public IP address and port in the global DNS. Existing client
998 software using the existing Bonjour programming APIs [Bonjour]
999 gets this functionality automatically. The logic is that if client
1000 software publishes its information into the global DNS via Wide Area
1001 Bonjour service advertising, then it's reasonable to infer an
1002 expectation that this information should be usable by the peers
1003 retrieving it. Generally speaking, recording a private IP address
1004 like 10.0.0.2 in the public DNS is completely pointless because that
1005 address is not reachable from clients on the other side of the NAT
1006 gateway. In the case of a home user with a single computer directly
1007 connected to their Cable or DSL modem, with a single global IPv4
1008 address and no NAT gateway (a surprisingly common configuration),
1009 publishing that IP address into the global DNS is useful because that
1010 IP address is reachable. In contrast, a home user using a NAT gateway
1011 to share a single global IPv4 address between several computers loses
1012 this ability to receive inbound connections easily. This breaks many
1013 peer-to-peer collaborative applications, like the multi-user text
1014 editor SubEthaEdit [SEE]. Automatically creating the necessary
1015 inbound port mappings helps remedy this unintended side-effect of
1016 NAT.
1017
1018 The server side of the NAT-PMP protocol is implemented in Apple's
1019 "AirPort Extreme" and "AirPort Express" wireless base stations.
1020
1021
10229. Copyright Notice
1023
1024 Copyright (C) The Internet Society (2006).
1025
1026 This document is subject to the rights, licenses and restrictions
1027 contained in BCP 78, and except as set forth therein, the authors
1028 retain all their rights. For the purposes of this document,
1029 the term "BCP 78" refers exclusively to RFC 3978, "IETF Rights
1030 in Contributions", published March 2005.
1031
1032 This document and the information contained herein are provided on
1033 an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE
1034 REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE
1035 INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR
1036 IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
1037 THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
1038 WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
1039
1040
1041
1042
1043
1044Expires 14th March 2007 Cheshire, et al. [Page 18]
1045
1046Internet Draft NAT Port Mapping Protocol 14th September 2006
1047
1048
104910. Normative References
1050
1051 [RFC 1918] Y. Rekhter et.al., "Address Allocation for Private
1052 Internets", RFC 1918, February 1996.
1053
1054 [RFC 2119] RFC 2119 - Key words for use in RFCs to Indicate
1055 Requirement Levels
1056
1057
105811. Informative References
1059
1060 [Bonjour] Apple "Bonjour" <http://developer.apple.com/bonjour/>
1061
1062 [ETEAISD] J. Saltzer, D. Reed and D. Clark: "End-to-end arguments in
1063 system design", ACM Trans. Comp. Sys., 2(4):277-88, Nov.
1064 1984
1065
1066 [DNS-SD] Cheshire, S., and M. Krochmal, "DNS-Based Service
1067 Discovery", Internet-Draft (work in progress),
1068 draft-cheshire-dnsext-dns-sd-04.txt, August 2006.
1069
1070 [mDNS] Cheshire, S., and M. Krochmal, "Multicast DNS",
1071 Internet-Draft (work in progress),
1072 draft-cheshire-dnsext-multicastdns-06.txt, August 2006.
1073
1074 [RFC 2131] R. Droms, "Dynamic Host Configuration Protocol", RFC 2131,
1075 March 1997.
1076
1077 [RFC 2401] Atkinson, R. and S. Kent, "Security Architecture for the
1078 Internet Protocol", RFC 2401, November 1998.
1079
1080 [RFC 2663] Srisuresh, P. and M. Holdrege, "IP Network Address
1081 Translator (NAT) Terminology and Considerations", RFC
1082 2663, August 1999.
1083
1084 [RFC 3007] Wellington, B., "Simple Secure Domain Name System
1085 (DNS) Dynamic Update", RFC 3007, November 2000.
1086
1087 [SEE] <http://www.codingmonkeys.de/subethaedit/>
1088
1089 [RFC 3022] RFC 3022 - Network Address Translator
1090
1091 [RFC 3424] RFC 3424 - IAB Considerations for UNilateral Self-Address
1092 Fixing (UNSAF) Across Network Address Translation
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102Expires 14th March 2007 Cheshire, et al. [Page 19]
1103
1104Internet Draft NAT Port Mapping Protocol 14th September 2006
1105
1106
110712. Authors' Addresses
1108
1109 Stuart Cheshire
1110 Apple Computer, Inc.
1111 1 Infinite Loop
1112 Cupertino
1113 California 95014
1114 USA
1115
1116 Phone: +1 408 974 3207
1117 EMail: rfc [at] stuartcheshire [dot] org
1118
1119
1120 Marc Krochmal
1121 Apple Computer, Inc.
1122 1 Infinite Loop
1123 Cupertino
1124 California 95014
1125 USA
1126
1127 Phone: +1 408 974 4368
1128 EMail: marc [at] apple [dot] com
1129
1130
1131 Kiren Sekar
1132 Sharpcast, Inc.
1133 250 Cambridge Ave, Suite 101
1134 Palo Alto
1135 California 94306
1136 USA
1137
1138 Phone: +1 650 323 1960
1139 EMail: ksekar [at] sharpcast [dot] com
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160Expires 14th March 2007 Cheshire, et al. [Page 20]
diff --git a/src/upnp/test_upnp.c b/src/upnp/test_upnp.c
new file mode 100644
index 000000000..628b40d7c
--- /dev/null
+++ b/src/upnp/test_upnp.c
@@ -0,0 +1,110 @@
1/*
2 This file is part of GNUnet.
3 (C) 2006 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 2, 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 src/transports/upnp/upnptest.c
22 * @brief Testcase for UPnP
23 * @author Christian Grothoff
24 */
25
26#include "gnunet_util.h"
27#include "gnunet_upnp_service.h"
28#include "gnunet_core.h"
29#include "platform.h"
30
31
32
33int
34main (int argc, const char *argv[])
35{
36 static GNUNET_CoreAPIForPlugins capi;
37 struct GNUNET_GE_Context *ectx;
38 struct GNUNET_GC_Configuration *cfg;
39 struct in_addr addr;
40 int i;
41 GNUNET_UPnP_ServiceAPI *upnp;
42 struct GNUNET_PluginHandle *plug;
43 GNUNET_ServicePluginInitializationMethod init;
44 GNUNET_ServicePluginShutdownMethod done;
45 char ntop_buf[INET_ADDRSTRLEN];
46
47 ectx = GNUNET_GE_create_context_stderr (GNUNET_NO,
48 GNUNET_GE_WARNING | GNUNET_GE_ERROR
49 | GNUNET_GE_FATAL | GNUNET_GE_USER |
50 GNUNET_GE_ADMIN |
51 GNUNET_GE_DEVELOPER |
52 GNUNET_GE_IMMEDIATE |
53 GNUNET_GE_BULK);
54 GNUNET_GE_setDefaultContext (ectx);
55 cfg = GNUNET_GC_create ();
56 GNUNET_GE_ASSERT (ectx, cfg != NULL);
57 GNUNET_os_init (ectx);
58 capi.ectx = ectx;
59 capi.cfg = cfg;
60 plug = GNUNET_plugin_load (ectx, "libgnunet", "module_upnp");
61 if (plug == NULL)
62 {
63 GNUNET_GC_free (cfg);
64 GNUNET_GE_free_context (ectx);
65 return 1;
66 }
67 init = GNUNET_plugin_resolve_function (plug, "provide_", GNUNET_YES);
68 if (init == NULL)
69 {
70 GNUNET_plugin_unload (plug);
71 GNUNET_GC_free (cfg);
72 GNUNET_GE_free_context (ectx);
73 return 1;
74 }
75 upnp = init (&capi);
76 if (upnp == NULL)
77 {
78 GNUNET_plugin_unload (plug);
79 GNUNET_GC_free (cfg);
80 GNUNET_GE_free_context (ectx);
81 return 1;
82 }
83 for (i = 0; i < 10; i++)
84 {
85 if (GNUNET_shutdown_test () != GNUNET_NO)
86 break;
87 if (GNUNET_OK == upnp->get_ip (2086, "TCP", &addr))
88 {
89 printf ("UPnP returned external IP %s\n",
90 inet_ntop (AF_INET, &addr, ntop_buf, INET_ADDRSTRLEN));
91 }
92 else
93 {
94 /* we cannot be sure that there is a UPnP-capable
95 NAT-box out there, so test should not fail
96 just because of this! */
97 printf ("No UPnP response (yet).\n");
98 }
99 GNUNET_thread_sleep (2 * GNUNET_CRON_SECONDS);
100 }
101 done = GNUNET_plugin_resolve_function (plug, "release_", GNUNET_YES);
102 if (done != NULL)
103 done ();
104 GNUNET_plugin_unload (plug);
105 GNUNET_GC_free (cfg);
106 GNUNET_GE_free_context (ectx);
107 return 0;
108}
109
110/* end of upnptest.c */
diff --git a/src/upnp/upnp.c b/src/upnp/upnp.c
new file mode 100644
index 000000000..6dc4338a0
--- /dev/null
+++ b/src/upnp/upnp.c
@@ -0,0 +1,721 @@
1/**
2 * @file upnp.c UPnP Implementation
3 * @ingroup core
4 *
5 * gaim
6 *
7 * Gaim is the legal property of its developers, whose names are too numerous
8 * to list here. Please refer to the COPYRIGHT file distributed with this
9 * source distribution.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26#include "platform.h"
27#include "upnp_xmlnode.h"
28#include "upnp_util.h"
29#include "upnp.h"
30
31#include <curl/curl.h>
32
33#define TRUE GNUNET_YES
34#define FALSE GNUNET_NO
35#define g_return_if_fail(a) if(!(a)) return;
36#define g_return_val_if_fail(a, val) if(!(a)) return (val);
37
38#define HTTP_OK "200 OK"
39#define NUM_UDP_ATTEMPTS 2
40#define HTTPMU_HOST_ADDRESS "239.255.255.250"
41#define HTTPMU_HOST_PORT 1900
42#define SEARCH_REQUEST_DEVICE "urn:schemas-upnp-org:service:%s"
43#define SEARCH_REQUEST_STRING \
44 "M-SEARCH * HTTP/1.1\r\n" \
45 "MX: 2\r\n" \
46 "HOST: 239.255.255.250:1900\r\n" \
47 "MAN: \"ssdp:discover\"\r\n" \
48 "ST: urn:schemas-upnp-org:service:%s\r\n" \
49 "\r\n"
50#define WAN_IP_CONN_SERVICE "WANIPConnection:1"
51#define WAN_PPP_CONN_SERVICE "WANPPPConnection:1"
52#define HTTP_POST_SOAP_HEADER \
53 "SOAPACTION: \"urn:schemas-upnp-org:service:%s#%s\""
54#define HTTP_POST_SIZE_HEADER "CONTENT-LENGTH: %u"
55#define SOAP_ACTION \
56 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" \
57 "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" " \
58 "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n" \
59 "<s:Body>\r\n" \
60 "<u:%s xmlns:u=\"urn:schemas-upnp-org:service:%s\">\r\n" \
61 "%s" \
62 "</u:%s>\r\n" \
63 "</s:Body>\r\n" \
64 "</s:Envelope>"
65#define PORT_MAPPING_LEASE_TIME "0"
66#define PORT_MAPPING_DESCRIPTION "GNUNET_UPNP_PORT_FORWARD"
67#define ADD_PORT_MAPPING_PARAMS \
68 "<NewRemoteHost></NewRemoteHost>\r\n" \
69 "<NewExternalPort>%i</NewExternalPort>\r\n" \
70 "<NewProtocol>%s</NewProtocol>\r\n" \
71 "<NewInternalPort>%i</NewInternalPort>\r\n" \
72 "<NewInternalClient>%s</NewInternalClient>\r\n" \
73 "<NewEnabled>1</NewEnabled>\r\n" \
74 "<NewPortMappingDescription>" \
75 PORT_MAPPING_DESCRIPTION \
76 "</NewPortMappingDescription>\r\n" \
77 "<NewLeaseDuration>" \
78 PORT_MAPPING_LEASE_TIME \
79 "</NewLeaseDuration>\r\n"
80#define DELETE_PORT_MAPPING_PARAMS \
81 "<NewRemoteHost></NewRemoteHost>\r\n" \
82 "<NewExternalPort>%i</NewExternalPort>\r\n" \
83 "<NewProtocol>%s</NewProtocol>\r\n"
84
85typedef enum
86{
87 GAIM_UPNP_STATUS_UNDISCOVERED = -1,
88 GAIM_UPNP_STATUS_UNABLE_TO_DISCOVER,
89 GAIM_UPNP_STATUS_DISCOVERING,
90 GAIM_UPNP_STATUS_DISCOVERED
91} GaimUPnPStatus;
92
93typedef struct
94{
95 GaimUPnPStatus status;
96 char *control_url;
97 const char *service_type;
98 char publicip[16];
99} GaimUPnPControlInfo;
100
101typedef struct
102{
103 const char *service_type;
104 char *full_url;
105 char *buf;
106 unsigned int buf_len;
107 int sock;
108} UPnPDiscoveryData;
109
110static GaimUPnPControlInfo control_info = {
111 GAIM_UPNP_STATUS_UNDISCOVERED,
112 NULL,
113 NULL,
114 "",
115};
116
117/**
118 * This is the signature used for functions that act as a callback
119 * to CURL.
120 */
121typedef size_t (*GaimUtilFetchUrlCallback) (void *url_data,
122 size_t size,
123 size_t nmemb, void *user_data);
124
125
126
127static char *
128g_strstr_len (const char *haystack, int haystack_len, const char *needle)
129{
130 int i;
131
132 g_return_val_if_fail (haystack != NULL, NULL);
133 g_return_val_if_fail (needle != NULL, NULL);
134
135 if (haystack_len < 0)
136 return strstr (haystack, needle);
137 else
138 {
139 const char *p = haystack;
140 int needle_len = strlen (needle);
141 const char *end = haystack + haystack_len - needle_len;
142
143 if (needle_len == 0)
144 return (char *) haystack;
145
146 while (*p && p <= end)
147 {
148 for (i = 0; i < needle_len; i++)
149 if (p[i] != needle[i])
150 goto next;
151
152 return (char *) p;
153
154 next:
155 p++;
156 }
157 }
158
159 return NULL;
160}
161
162static int
163gaim_upnp_compare_device (const xmlnode * device, const char *deviceType)
164{
165 xmlnode *deviceTypeNode = xmlnode_get_child (device, "deviceType");
166 char *tmp;
167 int ret;
168
169 if (deviceTypeNode == NULL)
170 return FALSE;
171 tmp = xmlnode_get_data (deviceTypeNode);
172 ret = !strcasecmp (tmp, deviceType);
173 GNUNET_free (tmp);
174 return ret;
175}
176
177static int
178gaim_upnp_compare_service (const xmlnode * service, const char *serviceType)
179{
180 xmlnode *serviceTypeNode;
181 char *tmp;
182 int ret;
183
184 if (service == NULL)
185 return FALSE;
186 serviceTypeNode = xmlnode_get_child (service, "serviceType");
187 if (serviceTypeNode == NULL)
188 return FALSE;
189 tmp = xmlnode_get_data (serviceTypeNode);
190 ret = !strcasecmp (tmp, serviceType);
191 GNUNET_free (tmp);
192 return ret;
193}
194
195static char *
196gaim_upnp_parse_description_response (const char *httpResponse,
197 size_t len,
198 const char *httpURL,
199 const char *serviceType)
200{
201 char *xmlRoot, *baseURL, *controlURL, *service;
202 xmlnode *xmlRootNode, *serviceTypeNode, *controlURLNode, *baseURLNode;
203 char *tmp;
204
205 /* find the root of the xml document */
206 xmlRoot = g_strstr_len (httpResponse, len, "<root");
207 if (xmlRoot == NULL)
208 return NULL;
209 if (g_strstr_len (httpResponse, len, "</root") == NULL)
210 return NULL;
211
212 /* create the xml root node */
213 xmlRootNode = xmlnode_from_str (xmlRoot, len - (xmlRoot - httpResponse));
214 if (xmlRootNode == NULL)
215 return NULL;
216
217 /* get the baseURL of the device */
218 baseURLNode = xmlnode_get_child (xmlRootNode, "URLBase");
219 if (baseURLNode != NULL)
220 {
221 baseURL = xmlnode_get_data (baseURLNode);
222 }
223 else
224 {
225 baseURL = GNUNET_strdup (httpURL);
226 }
227
228 /* get the serviceType child that has the service type as its data */
229 /* get urn:schemas-upnp-org:device:InternetGatewayDevice:1 and its devicelist */
230 serviceTypeNode = xmlnode_get_child (xmlRootNode, "device");
231 while (!gaim_upnp_compare_device (serviceTypeNode,
232 "urn:schemas-upnp-org:device:InternetGatewayDevice:1")
233 && serviceTypeNode != NULL)
234 {
235 serviceTypeNode = xmlnode_get_next_twin (serviceTypeNode);
236 }
237 if (serviceTypeNode == NULL)
238 {
239 GNUNET_free (baseURL);
240 xmlnode_free (xmlRootNode);
241 return NULL;
242 }
243 serviceTypeNode = xmlnode_get_child (serviceTypeNode, "deviceList");
244 if (serviceTypeNode == NULL)
245 {
246 GNUNET_free (baseURL);
247 xmlnode_free (xmlRootNode);
248 return NULL;
249 }
250
251 /* get urn:schemas-upnp-org:device:WANDevice:1 and its devicelist */
252 serviceTypeNode = xmlnode_get_child (serviceTypeNode, "device");
253 while (!gaim_upnp_compare_device (serviceTypeNode,
254 "urn:schemas-upnp-org:device:WANDevice:1")
255 && serviceTypeNode != NULL)
256 {
257 serviceTypeNode = xmlnode_get_next_twin (serviceTypeNode);
258 }
259 if (serviceTypeNode == NULL)
260 {
261 GNUNET_free (baseURL);
262 xmlnode_free (xmlRootNode);
263 return NULL;
264 }
265 serviceTypeNode = xmlnode_get_child (serviceTypeNode, "deviceList");
266 if (serviceTypeNode == NULL)
267 {
268 GNUNET_free (baseURL);
269 xmlnode_free (xmlRootNode);
270 return NULL;
271 }
272
273 /* get urn:schemas-upnp-org:device:WANConnectionDevice:1 and its servicelist */
274 serviceTypeNode = xmlnode_get_child (serviceTypeNode, "device");
275 while (serviceTypeNode && !gaim_upnp_compare_device (serviceTypeNode,
276 "urn:schemas-upnp-org:device:WANConnectionDevice:1"))
277 {
278 serviceTypeNode = xmlnode_get_next_twin (serviceTypeNode);
279 }
280 if (serviceTypeNode == NULL)
281 {
282 GNUNET_free (baseURL);
283 xmlnode_free (xmlRootNode);
284 return NULL;
285 }
286 serviceTypeNode = xmlnode_get_child (serviceTypeNode, "serviceList");
287 if (serviceTypeNode == NULL)
288 {
289 GNUNET_free (baseURL);
290 xmlnode_free (xmlRootNode);
291 return NULL;
292 }
293
294 /* get the serviceType variable passed to this function */
295 service = g_strdup_printf (SEARCH_REQUEST_DEVICE, serviceType);
296 serviceTypeNode = xmlnode_get_child (serviceTypeNode, "service");
297 while (!gaim_upnp_compare_service (serviceTypeNode, service) &&
298 serviceTypeNode != NULL)
299 {
300 serviceTypeNode = xmlnode_get_next_twin (serviceTypeNode);
301 }
302
303 GNUNET_free (service);
304 if (serviceTypeNode == NULL)
305 {
306 GNUNET_free (baseURL);
307 xmlnode_free (xmlRootNode);
308 return NULL;
309 }
310
311 /* get the controlURL of the service */
312 if ((controlURLNode = xmlnode_get_child (serviceTypeNode,
313 "controlURL")) == NULL)
314 {
315 GNUNET_free (baseURL);
316 xmlnode_free (xmlRootNode);
317 return NULL;
318 }
319
320 tmp = xmlnode_get_data (controlURLNode);
321 if (baseURL && !gaim_str_has_prefix (tmp, "http://") &&
322 !gaim_str_has_prefix (tmp, "HTTP://"))
323 {
324 if (tmp[0] == '/')
325 {
326 size_t len;
327 const char *end;
328 /* absolute path */
329 end = strstr (&baseURL[strlen ("http://")], "/");
330 if (end == NULL)
331 len = strlen (&baseURL[strlen ("http://")]);
332 else
333 len = end - &baseURL[strlen ("http://")];
334 controlURL = g_strdup_printf ("http://%.*s%s",
335 len,
336 &baseURL[strlen ("http://")], tmp);
337 }
338 else
339 {
340 controlURL = g_strdup_printf ("%s%s", baseURL, tmp);
341 }
342 GNUNET_free (tmp);
343 }
344 else
345 {
346 controlURL = tmp;
347 }
348 GNUNET_free (baseURL);
349 xmlnode_free (xmlRootNode);
350
351 return controlURL;
352}
353
354#define CURL_EASY_SETOPT(c, a, b) do { ret = curl_easy_setopt(c, a, b); if (ret != CURLE_OK) GNUNET_log(GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, _("%s failed at %s:%d: `%s'\n"), "curl_easy_setopt", __FILE__, __LINE__, curl_easy_strerror(ret)); } while (0);
355
356/**
357 * Do the generic curl setup.
358 */
359static int
360setup_curl (const char *proxy, CURL * curl)
361{
362 int ret;
363
364 CURL_EASY_SETOPT (curl, CURLOPT_FAILONERROR, 1);
365 if (strlen (proxy) > 0)
366 CURL_EASY_SETOPT (curl, CURLOPT_PROXY, proxy);
367 CURL_EASY_SETOPT (curl, CURLOPT_BUFFERSIZE, 1024); /* a bit more than one HELLO */
368 CURL_EASY_SETOPT (curl, CURLOPT_CONNECTTIMEOUT, 150L);
369 /* NOTE: use of CONNECTTIMEOUT without also
370 setting NOSIGNAL results in really weird
371 crashes on my system! */
372 CURL_EASY_SETOPT (curl, CURLOPT_NOSIGNAL, 1);
373 return GNUNET_OK;
374}
375
376static int
377gaim_upnp_generate_action_message_and_send (const char *proxy,
378 const char *actionName,
379 const char *actionParams,
380 GaimUtilFetchUrlCallback cb,
381 void *cb_data)
382{
383 CURL *curl;
384 int ret;
385 char *soapHeader;
386 char *sizeHeader;
387 char *soapMessage;
388 struct curl_slist *headers = NULL;
389
390 GNUNET_assert (cb != NULL);
391 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
392 return GNUNET_SYSERR;
393 /* set the soap message */
394 soapMessage = g_strdup_printf (SOAP_ACTION,
395 actionName,
396 control_info.service_type,
397 actionParams, actionName);
398 soapHeader = g_strdup_printf (HTTP_POST_SOAP_HEADER,
399 control_info.service_type, actionName);
400 sizeHeader = g_strdup_printf (HTTP_POST_SIZE_HEADER, strlen (soapMessage));
401 curl = curl_easy_init ();
402 setup_curl (proxy, curl);
403 CURL_EASY_SETOPT (curl, CURLOPT_URL, control_info.control_url);
404 CURL_EASY_SETOPT (curl, CURLOPT_WRITEFUNCTION, cb);
405 CURL_EASY_SETOPT (curl, CURLOPT_WRITEDATA, cb_data);
406 CURL_EASY_SETOPT (curl, CURLOPT_POST, 1);
407 headers = curl_slist_append (headers,
408 "CONTENT-TYPE: text/xml ; charset=\"utf-8\"");
409 headers = curl_slist_append (headers, soapHeader);
410 headers = curl_slist_append (headers, sizeHeader);
411 CURL_EASY_SETOPT (curl, CURLOPT_HTTPHEADER, headers);
412 CURL_EASY_SETOPT (curl, CURLOPT_POSTFIELDS, soapMessage);
413 CURL_EASY_SETOPT (curl, CURLOPT_POSTFIELDSIZE, strlen (soapMessage));
414 CURL_EASY_SETOPT (curl, CURLOPT_MAXREDIRS, 1L);
415 CURL_EASY_SETOPT (curl, CURLOPT_CONNECTTIMEOUT, 1L);
416 CURL_EASY_SETOPT (curl, CURLOPT_TIMEOUT, 2L);
417 /* NOTE: use of CONNECTTIMEOUT without also
418 setting NOSIGNAL results in really weird
419 crashes on my system! */
420 CURL_EASY_SETOPT (curl, CURLOPT_NOSIGNAL, 1);
421 if (ret == CURLE_OK)
422 ret = curl_easy_perform (curl);
423#if 0
424 if (ret != CURLE_OK)
425 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
426 _
427 ("%s failed for url `%s' and post-data `%s' at %s:%d: `%s'\n"),
428 "curl_easy_perform", control_info.control_url, soapMessage,
429 __FILE__, __LINE__, curl_easy_strerror (ret));
430#endif
431 curl_slist_free_all (headers);
432 curl_easy_cleanup (curl);
433 curl_global_cleanup ();
434 GNUNET_free (sizeHeader);
435 GNUNET_free (soapMessage);
436 GNUNET_free (soapHeader);
437 if (ret != CURLE_OK)
438 return GNUNET_SYSERR;
439 return GNUNET_OK;
440}
441
442
443static size_t
444looked_up_public_ip_cb (void *url_data,
445 size_t size, size_t nmemb, void *user_data)
446{
447 UPnPDiscoveryData *dd = user_data;
448 size_t len = size * nmemb;
449 const char *temp;
450 const char *temp2;
451
452 if (len + dd->buf_len > 1024 * 1024 * 4)
453 return 0; /* refuse to process - too big! */
454 GNUNET_array_grow (dd->buf, dd->buf_len, dd->buf_len + len);
455 memcpy (&dd->buf[dd->buf_len - len], url_data, len);
456 if (dd->buf_len == 0)
457 return len;
458 /* extract the ip, or see if there is an error */
459 if ((temp = g_strstr_len (dd->buf,
460 dd->buf_len, "<NewExternalIPAddress")) == NULL)
461 return len;
462 if (!(temp = g_strstr_len (temp, dd->buf_len - (temp - dd->buf), ">")))
463 return len;
464 if (!(temp2 = g_strstr_len (temp, dd->buf_len - (temp - dd->buf), "<")))
465 return len;
466 memset (control_info.publicip, 0, sizeof (control_info.publicip));
467 if (temp2 - temp >= sizeof (control_info.publicip))
468 temp2 = temp + sizeof (control_info.publicip) - 1;
469 memcpy (control_info.publicip, temp + 1, temp2 - (temp + 1));
470 GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
471 _("upnp: NAT Returned IP: %s\n"), control_info.publicip);
472 return len;
473}
474
475
476static size_t
477ignore_response (void *url_data, size_t size, size_t nmemb, void *user_data)
478{
479 return size * nmemb;
480}
481
482/**
483 * Process downloaded bits of service description.
484 */
485static size_t
486upnp_parse_description_cb (void *httpResponse,
487 size_t size, size_t nmemb, void *user_data)
488{
489 UPnPDiscoveryData *dd = user_data;
490 size_t len = size * nmemb;
491 char *control_url = NULL;
492
493 if (len + dd->buf_len > 1024 * 1024 * 4)
494 return len; /* refuse to process - too big! */
495 GNUNET_array_grow (dd->buf, dd->buf_len, dd->buf_len + len);
496 memcpy (&dd->buf[dd->buf_len - len], httpResponse, len);
497 if (dd->buf_len > 0)
498 control_url = gaim_upnp_parse_description_response (dd->buf,
499 dd->buf_len,
500 dd->full_url,
501 dd->service_type);
502 control_info.status = control_url ? GAIM_UPNP_STATUS_DISCOVERED
503 : GAIM_UPNP_STATUS_UNABLE_TO_DISCOVER;
504 GNUNET_free_non_null (control_info.control_url);
505 control_info.control_url = control_url;
506 control_info.service_type = dd->service_type;
507 return len;
508}
509
510static int
511gaim_upnp_parse_description (char *proxy, UPnPDiscoveryData * dd)
512{
513 CURL *curl;
514 int ret;
515
516 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
517 return GNUNET_SYSERR;
518 curl = curl_easy_init ();
519 setup_curl (proxy, curl);
520 ret = CURLE_OK;
521 CURL_EASY_SETOPT (curl, CURLOPT_URL, dd->full_url);
522 CURL_EASY_SETOPT (curl, CURLOPT_WRITEFUNCTION, &upnp_parse_description_cb);
523 CURL_EASY_SETOPT (curl, CURLOPT_WRITEDATA, dd);
524 CURL_EASY_SETOPT (curl, CURLOPT_MAXREDIRS, 1L);
525 CURL_EASY_SETOPT (curl, CURLOPT_CONNECTTIMEOUT, 1L);
526 CURL_EASY_SETOPT (curl, CURLOPT_TIMEOUT, 2L);
527
528 /* NOTE: use of CONNECTTIMEOUT without also
529 setting NOSIGNAL results in really weird
530 crashes on my system! */
531 CURL_EASY_SETOPT (curl, CURLOPT_NOSIGNAL, 1);
532 ret = curl_easy_perform (curl);
533 if (ret != CURLE_OK)
534 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
535 _("%s failed at %s:%d: `%s'\n"),
536 "curl_easy_perform", __FILE__, __LINE__,
537 curl_easy_strerror (ret));
538 curl_easy_cleanup (curl);
539 curl_global_cleanup ();
540 if (control_info.control_url == NULL)
541 return GNUNET_SYSERR;
542 return GNUNET_OK;
543}
544
545int
546gaim_upnp_discover (struct GNUNET_CONFIGURATION_Handle *cfg, int sock)
547{
548 char *proxy;
549 socklen_t avail;
550 struct sockaddr_in server;
551 int retry_count;
552 char *sendMessage;
553 size_t totalSize;
554 int sentSuccess;
555 char buf[65536];
556 int buf_len;
557 const char *startDescURL;
558 const char *endDescURL;
559 int ret;
560 UPnPDiscoveryData dd;
561 struct sockaddr *sa;
562
563 memset (&dd, 0, sizeof (UPnPDiscoveryData));
564 if (control_info.status == GAIM_UPNP_STATUS_DISCOVERING)
565 return GNUNET_NO;
566 dd.sock = sock;
567 memset (&server, 0, sizeof (struct sockaddr_in));
568 server.sin_family = AF_INET;
569 avail = sizeof (struct sockaddr_in);
570 sa = (struct sockaddr *) &server;
571 if (GNUNET_OK !=
572 GNUNET_get_ip_from_hostname (HTTPMU_HOST_ADDRESS, AF_INET, &sa, &avail))
573 {
574 return GNUNET_SYSERR;
575 }
576 server.sin_port = htons (HTTPMU_HOST_PORT);
577 control_info.status = GAIM_UPNP_STATUS_DISCOVERING;
578
579 /* because we are sending over UDP, if there is a failure
580 we should retry the send NUM_UDP_ATTEMPTS times. Also,
581 try different requests for WANIPConnection and WANPPPConnection */
582 for (retry_count = 0; retry_count < NUM_UDP_ATTEMPTS; retry_count++)
583 {
584 sentSuccess = FALSE;
585 if ((retry_count % 2) == 0)
586 dd.service_type = WAN_IP_CONN_SERVICE;
587 else
588 dd.service_type = WAN_PPP_CONN_SERVICE;
589 sendMessage = g_strdup_printf (SEARCH_REQUEST_STRING, dd.service_type);
590 totalSize = strlen (sendMessage);
591 do
592 {
593 if (SENDTO (dd.sock,
594 sendMessage,
595 totalSize,
596 0,
597 (struct sockaddr *) &server,
598 sizeof (struct sockaddr_in)) == totalSize)
599 {
600 sentSuccess = TRUE;
601 break;
602 }
603 }
604 while (((errno == EINTR) || (errno == EAGAIN)) &&
605 (GNUNET_shutdown_test () == GNUNET_NO));
606 GNUNET_free (sendMessage);
607 if (sentSuccess)
608 break;
609 }
610 if (sentSuccess == FALSE)
611 return GNUNET_SYSERR;
612
613 /* try to read response */
614 do
615 {
616 buf_len = recv (dd.sock, buf, sizeof (buf) - 1, 0);
617 if (buf_len > 0)
618 {
619 buf[buf_len] = '\0';
620 break;
621 }
622 else if (errno != EINTR)
623 {
624 continue;
625 }
626 }
627 while ((errno == EINTR) && (GNUNET_shutdown_test () == GNUNET_NO));
628
629 /* parse the response, and see if it was a success */
630 if (g_strstr_len (buf, buf_len, HTTP_OK) == NULL)
631 return GNUNET_SYSERR;
632 if ((startDescURL = g_strstr_len (buf, buf_len, "http://")) == NULL)
633 return GNUNET_SYSERR;
634
635 endDescURL = g_strstr_len (startDescURL,
636 buf_len - (startDescURL - buf), "\r");
637 if (endDescURL == NULL)
638 endDescURL = g_strstr_len (startDescURL,
639 buf_len - (startDescURL - buf), "\n");
640 if (endDescURL == NULL)
641 return GNUNET_SYSERR;
642 if (endDescURL == startDescURL)
643 return GNUNET_SYSERR;
644 dd.full_url = GNUNET_strdup (startDescURL);
645 dd.full_url[endDescURL - startDescURL] = '\0';
646 proxy = NULL;
647 GNUNET_CONFIGURATION_get_value_string (cfg,
648 "GNUNETD", "HTTP-PROXY", &proxy);
649 ret = gaim_upnp_parse_description (proxy, &dd);
650 GNUNET_free (dd.full_url);
651 GNUNET_array_grow (dd.buf, dd.buf_len, 0);
652 if (ret == GNUNET_OK)
653 {
654 ret = gaim_upnp_generate_action_message_and_send (proxy,
655 "GetExternalIPAddress",
656 "",
657 looked_up_public_ip_cb,
658 &dd);
659 GNUNET_array_grow (dd.buf, dd.buf_len, 0);
660 }
661 GNUNET_free (proxy);
662 return ret;
663}
664
665const char *
666gaim_upnp_get_public_ip ()
667{
668 if ((control_info.status == GAIM_UPNP_STATUS_DISCOVERED)
669 && (strlen (control_info.publicip) > 0))
670 return control_info.publicip;
671 return NULL;
672}
673
674int
675gaim_upnp_change_port_mapping (struct GNUNET_CONFIGURATION_Handle *cfg,
676 int do_add,
677 unsigned short portmap, const char *protocol)
678{
679 const char *action_name;
680 char *action_params;
681 char *internal_ip;
682 char *proxy;
683 int ret;
684
685 if (control_info.status != GAIM_UPNP_STATUS_DISCOVERED)
686 return GNUNET_NO;
687 if (do_add)
688 {
689 internal_ip = GNUNET_upnp_get_internal_ip (cfg);
690 if (internal_ip == NULL)
691 {
692 gaim_debug_error ("upnp",
693 "gaim_upnp_set_port_mapping(): couldn't get local ip\n");
694 return GNUNET_NO;
695 }
696 action_name = "AddPortMapping";
697 action_params = g_strdup_printf (ADD_PORT_MAPPING_PARAMS,
698 portmap,
699 protocol, portmap, internal_ip);
700 GNUNET_free (internal_ip);
701 }
702 else
703 {
704 action_name = "DeletePortMapping";
705 action_params = g_strdup_printf (DELETE_PORT_MAPPING_PARAMS,
706 portmap, protocol);
707 }
708 proxy = NULL;
709 GNUNET_CONFIGURATION_get_value_string (cfg,
710 "GNUNETD", "HTTP-PROXY", &proxy);
711 ret =
712 gaim_upnp_generate_action_message_and_send (proxy, action_name,
713 action_params,
714 &ignore_response, NULL);
715
716 GNUNET_free (action_params);
717 GNUNET_free (proxy);
718 return ret;
719}
720
721/* end of upnp.c */
diff --git a/src/upnp/upnp.h b/src/upnp/upnp.h
new file mode 100644
index 000000000..1f99c5352
--- /dev/null
+++ b/src/upnp/upnp.h
@@ -0,0 +1,82 @@
1/**
2 * @file upnp.h Universal Plug N Play API
3 * @ingroup core
4 *
5 * gaim
6 *
7 * Gaim is the legal property of its developers, whose names are too numerous
8 * to list here. Please refer to the COPYRIGHT file distributed with this
9 * source distribution.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26#ifndef _GAIM_UPNP_H_
27#define _GAIM_UPNP_H_
28
29#include <libxml/parser.h>
30#include <string.h>
31#include "gnunet_util_lib.h"
32
33#ifdef __cplusplus
34extern "C"
35{
36#if 0 /* keep Emacsens' auto-indent happy */
37}
38#endif
39#endif
40
41/**
42 * Sends a discovery request to search for a UPnP enabled IGD that
43 * contains the WANIPConnection service that will allow us to receive the
44 * public IP address of the IGD, and control it for forwarding ports.
45 * The result will be cached for further use.
46 */
47int gaim_upnp_discover (struct GNUNET_CONFIGURATION_Handle *cfg, int sock);
48
49/**
50 * Gets the IP address from a UPnP enabled IGD that sits on the local
51 * network, so when getting the network IP, instead of returning the
52 * local network IP, the public IP is retrieved. This is a cached value from
53 * the time of the UPnP discovery.
54 *
55 * @return The IP address of the network, or NULL if something went wrong
56 */
57const char *gaim_upnp_get_public_ip (void);
58
59/**
60 * Maps Ports in a UPnP enabled IGD that sits on the local network to
61 * this gaim client. Essentially, this function takes care of the port
62 * forwarding so things like file transfers can work behind NAT firewalls
63 *
64 * @param portmap The port to map to this client
65 * @param protocol The protocol to map, either "TCP" or "UDP"
66 * @param do_add TRUE/GNUNET_YES to add, FALSE/GNUNET_NO to remove
67 * @param cb an optional callback function to be notified when the mapping
68 * addition is complete
69 * @param cb_data Extra data to be passed to the callback
70 */
71int gaim_upnp_change_port_mapping (struct GNUNET_CONFIGURATION_Handle *cfg,
72 int do_add,
73 uint16_t portmap, const char *protocol);
74
75#if 0 /* keep Emacsens' auto-indent happy */
76{
77#endif
78#ifdef __cplusplus
79}
80#endif
81
82#endif /* _GAIM_UPNP_H_ */
diff --git a/src/upnp/upnp_init.c b/src/upnp/upnp_init.c
new file mode 100644
index 000000000..3dc0d2b7c
--- /dev/null
+++ b/src/upnp/upnp_init.c
@@ -0,0 +1,208 @@
1/*
2 This file is part of GNUnet
3 (C) 2006 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 2, 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 src/transports/upnp/init.c
23 * @brief API for UPnP access
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_util.h"
29#include "upnp.h"
30#include "gnunet_upnp_service.h"
31#include "gnunet_core.h"
32
33static struct GNUNET_GE_Context *ectx;
34
35static struct GNUNET_GC_Configuration *cfg;
36
37static struct GNUNET_CronManager *cron;
38
39static struct GNUNET_Mutex *lock;
40
41typedef struct
42{
43 unsigned short port;
44 const char *proto;
45} PMap;
46
47static PMap *maps;
48
49static unsigned int maps_size;
50
51static struct GNUNET_ThreadHandle *discovery;
52
53static int discovery_socket;
54
55/**
56 * Obtain the public/external IP address.
57 *
58 * @return GNUNET_SYSERR on error, GNUNET_OK on success
59 */
60static int
61gnunet_upnp_get_public_ip (struct in_addr *address)
62{
63 const char *ip;
64 socklen_t socklen;
65 struct sockaddr *sa;
66 struct sockaddr_in s4;
67 int ret;
68
69 ip = gaim_upnp_get_public_ip ();
70 if (ip == NULL)
71 return GNUNET_SYSERR;
72 socklen = sizeof (struct sockaddr_in);
73 sa = (struct sockaddr *) &s4;
74 ret = GNUNET_get_ip_from_hostname (NULL, ip, AF_INET, &sa, &socklen);
75 if (ret == GNUNET_OK)
76 *address = s4.sin_addr;
77 return ret;
78}
79
80static void
81kill_discovery ()
82{
83 void *unused;
84
85 if (discovery != NULL)
86 {
87 SHUTDOWN (discovery_socket, SHUT_RDWR);
88 CLOSE (discovery_socket);
89 GNUNET_thread_join (discovery, &unused);
90 discovery = NULL;
91 }
92}
93
94static void *
95discover_thread ()
96{
97 gaim_upnp_discover (ectx, cfg, discovery_socket);
98 return NULL;
99}
100
101/**
102 * Periodically try to (re)discover UPnP access points.
103 */
104static void
105discover (void *unused)
106{
107 kill_discovery ();
108 discovery_socket = SOCKET (PF_INET, SOCK_DGRAM, 0);
109 if (discovery_socket == -1)
110 return;
111 discovery = GNUNET_thread_create (&discover_thread, NULL, 1024 * 128);
112}
113
114/**
115 * Periodically repeat our requests for port mappings.
116 */
117static void
118portmap (void *unused)
119{
120 unsigned int i;
121
122 GNUNET_mutex_lock (lock);
123 for (i = 0; i < maps_size; i++)
124 gaim_upnp_change_port_mapping (ectx,
125 cfg, GNUNET_NO, maps[i].port,
126 maps[i].proto);
127 GNUNET_mutex_unlock (lock);
128}
129
130
131/**
132 * Get the external IP address for the local machine.
133 *
134 * @return GNUNET_SYSERR on error, GNUNET_OK on success
135 */
136static int
137gnunet_upnp_get_ip (unsigned short port,
138 const char *protocol, struct in_addr *address)
139{
140 unsigned int i;
141
142 GNUNET_mutex_lock (lock);
143 for (i = 0; i < maps_size; i++)
144 if ((0 == strcmp (maps[i].proto, protocol)) && (maps[i].port == port))
145 break;
146 if (i == maps_size)
147 {
148 /* new entry! */
149 GNUNET_array_grow (maps, maps_size, maps_size + 1);
150 maps[i].proto = protocol;
151 maps[i].port = port;
152 gaim_upnp_change_port_mapping (ectx, cfg, GNUNET_YES, port, protocol);
153 }
154 GNUNET_mutex_unlock (lock);
155 return gnunet_upnp_get_public_ip (address);
156}
157
158
159/**
160 * Get the external IP address for the local machine.
161 */
162GNUNET_UPnP_ServiceAPI *
163provide_module_upnp (GNUNET_CoreAPIForPlugins * capi)
164{
165 static GNUNET_UPnP_ServiceAPI api;
166
167 ectx = capi->ectx;
168 cfg = capi->cfg;
169 cron = GNUNET_cron_create (ectx);
170 lock = GNUNET_mutex_create (GNUNET_NO);
171 GNUNET_cron_start (cron);
172 GNUNET_cron_add_job (cron, &discover, 0, 5 * GNUNET_CRON_MINUTES, NULL);
173 GNUNET_cron_add_job (cron, &portmap, 150 * GNUNET_CRON_SECONDS,
174 5 * GNUNET_CRON_MINUTES, NULL);
175 api.get_ip = gnunet_upnp_get_ip;
176 return &api;
177}
178
179/**
180 * Shutdown UPNP.
181 */
182int
183release_module_upnp ()
184{
185 unsigned int i;
186
187 if (cron == NULL)
188 return GNUNET_SYSERR; /* not loaded! */
189 for (i = 0; i < maps_size; i++)
190 gaim_upnp_change_port_mapping (ectx,
191 cfg, GNUNET_NO, maps[i].port,
192 maps[i].proto);
193 GNUNET_cron_stop (cron);
194 GNUNET_cron_del_job (cron, &discover, 5 * GNUNET_CRON_MINUTES, NULL);
195 GNUNET_cron_del_job (cron, &portmap, 5 * GNUNET_CRON_MINUTES, NULL);
196 GNUNET_cron_destroy (cron);
197 kill_discovery ();
198 cron = NULL;
199 GNUNET_mutex_destroy (lock);
200 lock = NULL;
201 GNUNET_array_grow (maps, maps_size, 0);
202 ectx = NULL;
203 cfg = NULL;
204 return GNUNET_OK;
205}
206
207
208/* end of init.c */
diff --git a/src/upnp/upnp_ip.c b/src/upnp/upnp_ip.c
new file mode 100644
index 000000000..3716fc671
--- /dev/null
+++ b/src/upnp/upnp_ip.c
@@ -0,0 +1,47 @@
1/*
2 This file is part of GNUnet.
3 (C) 2006, 2007 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 2, 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 transports/upnp/ip.c
23 * @brief code to determine the IP of the local machine
24 *
25 * @author Christian Grothoff
26 */
27
28#include <stdlib.h>
29#include "platform.h"
30#include "gnunet_util.h"
31#include "ip.h"
32
33/**
34 * Get the IP address for the local machine.
35 * @return NULL on error
36 */
37char *
38GNUNET_upnp_get_internal_ip (struct GNUNET_GC_Configuration *cfg,
39 struct GNUNET_GE_Context *ectx)
40{
41 struct in_addr address;
42
43 return GNUNET_get_local_ip (cfg, ectx, &address);
44}
45
46
47/* end of ip.c */
diff --git a/src/upnp/upnp_ip.h b/src/upnp/upnp_ip.h
new file mode 100644
index 000000000..adc06bbd5
--- /dev/null
+++ b/src/upnp/upnp_ip.h
@@ -0,0 +1,40 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005 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 2, 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 transports/upnp/ip.h
23 * @brief
24 *
25 * @author Christian Grothoff
26 */
27
28#ifndef IP_H
29#define IP_H
30
31
32/**
33 * Get the IP address for the local machine.
34 * @return NULL on error
35 */
36char *GNUNET_upnp_get_internal_ip (struct GNUNET_GC_Configuration *cfg,
37 struct GNUNET_GE_Context *ectx);
38
39
40#endif
diff --git a/src/upnp/upnp_util.c b/src/upnp/upnp_util.c
new file mode 100644
index 000000000..cef40b578
--- /dev/null
+++ b/src/upnp/upnp_util.c
@@ -0,0 +1,152 @@
1/*
2 * @file util.h Utility Functions
3 * @ingroup core
4 *
5 * Gaim is the legal property of its developers, whose names are too numerous
6 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * source distribution.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include "platform.h"
25#include "util.h"
26#include "gnunet_util.h"
27
28/* Returns a NULL-terminated string after unescaping an entity
29 * (eg. &amp;, &lt; &#38 etc.) starting at s. Returns NULL on failure.*/
30static char *
31detect_entity (const char *text, int *length)
32{
33 const char *pln;
34 int len;
35 int pound;
36 char b[7];
37 char *buf;
38
39 if (!text || *text != '&')
40 return NULL;
41
42#define IS_ENTITY(s) (!strncasecmp(text, s, (len = sizeof(s) - 1)))
43
44 if (IS_ENTITY ("&amp;"))
45 pln = "&";
46 else if (IS_ENTITY ("&lt;"))
47 pln = "<";
48 else if (IS_ENTITY ("&gt;"))
49 pln = ">";
50 else if (IS_ENTITY ("&nbsp;"))
51 pln = " ";
52 else if (IS_ENTITY ("&copy;"))
53 pln = "\302\251"; /* or use g_unichar_to_utf8(0xa9); */
54 else if (IS_ENTITY ("&quot;"))
55 pln = "\"";
56 else if (IS_ENTITY ("&reg;"))
57 pln = "\302\256"; /* or use g_unichar_to_utf8(0xae); */
58 else if (IS_ENTITY ("&apos;"))
59 pln = "\'";
60 else if (*(text + 1) == '#' && (sscanf (text, "&#%u;", &pound) == 1) &&
61 pound != 0 && *(text + 3 + (int) log10 (pound)) == ';')
62 {
63 buf = GNUNET_convert_string_to_utf8 (NULL,
64 (const char *) &pound,
65 2, "UNICODE");
66 if (strlen (buf) > 6)
67 buf[6] = '\0';
68 strcpy (b, buf);
69 pln = b;
70 GNUNET_free (buf);
71 len = 2;
72 while (isdigit ((int) text[len]))
73 len++;
74 if (text[len] == ';')
75 len++;
76 }
77 else
78 return NULL;
79
80 if (length)
81 *length = len;
82 return GNUNET_strdup (pln);
83}
84
85char *
86g_strdup_printf (const char *fmt, ...)
87{
88 size_t size;
89 char *buf;
90 va_list va;
91
92 va_start (va, fmt);
93 size = VSNPRINTF (NULL, 0, fmt, va) + 1;
94 va_end (va);
95 buf = GNUNET_malloc (size);
96 va_start (va, fmt);
97 VSNPRINTF (buf, size, fmt, va);
98 va_end (va);
99 return buf;
100}
101
102char *
103gaim_unescape_html (const char *html)
104{
105 if (html != NULL)
106 {
107 const char *c = html;
108 char *ret = GNUNET_strdup ("");
109 char *app;
110 while (*c)
111 {
112 int len;
113 char *ent;
114
115 if ((ent = detect_entity (c, &len)) != NULL)
116 {
117 app = g_strdup_printf ("%s%s", ret, ent);
118 GNUNET_free (ret);
119 ret = app;
120 c += len;
121 GNUNET_free (ent);
122 }
123 else if (!strncmp (c, "<br>", 4))
124 {
125 app = g_strdup_printf ("%s%s", ret, "\n");
126 GNUNET_free (ret);
127 ret = app;
128 c += 4;
129 }
130 else
131 {
132 app = g_strdup_printf ("%s%c", ret, *c);
133 GNUNET_free (ret);
134 ret = app;
135 c++;
136 }
137 }
138 return ret;
139 }
140 return NULL;
141}
142
143
144int
145gaim_str_has_prefix (const char *s, const char *p)
146{
147 if ((s == NULL) || (p == NULL))
148 return 0;
149 return !strncmp (s, p, strlen (p));
150}
151
152/* end of util.c */
diff --git a/src/upnp/upnp_util.h b/src/upnp/upnp_util.h
new file mode 100644
index 000000000..89a8d71cf
--- /dev/null
+++ b/src/upnp/upnp_util.h
@@ -0,0 +1,68 @@
1/**
2 * @file util.h Utility Functions
3 * @ingroup core
4 *
5 * gaim
6 *
7 * Gaim is the legal property of its developers, whose names are too numerous
8 * to list here. Please refer to the COPYRIGHT file distributed with this
9 * source distribution.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 * @todo Rename the functions so that they live somewhere in the gaim
26 * namespace.
27 */
28#ifndef _GAIM_UTIL_H_
29#define _GAIM_UTIL_H_
30
31#include <stdio.h>
32#include <string.h>
33
34#ifdef __cplusplus
35extern "C"
36{
37#endif
38
39/**
40 * Unescapes HTML entities to their literal characters.
41 * For example "&amp;" is replaced by '&' and so on.
42 * Actually only "&amp;", "&quot;", "&lt;" and "&gt;" are currently
43 * supported.
44 *
45 * @param html The string in which to unescape any HTML entities
46 *
47 * @return the text with HTML entities literalized
48 */
49 char *gaim_unescape_html (const char *html);
50
51/**
52 * Compares two strings to see if the first contains the second as
53 * a proper prefix.
54 *
55 * @param s The string to check.
56 * @param p The prefix in question.
57 *
58 * @return TRUE if p is a prefix of s, otherwise FALSE.
59 */
60 int gaim_str_has_prefix (const char *s, const char *p);
61
62 char *g_strdup_printf (const char *fmt, ...);
63
64#ifdef __cplusplus
65}
66#endif
67
68#endif
diff --git a/src/upnp/upnp_xmlnode.c b/src/upnp/upnp_xmlnode.c
new file mode 100644
index 000000000..b37528f00
--- /dev/null
+++ b/src/upnp/upnp_xmlnode.c
@@ -0,0 +1,487 @@
1/**
2 * @file xmlnode.c XML DOM functions
3 *
4 * gaim
5 *
6 * Gaim is the legal property of its developers, whose names are too numerous
7 * to list here. Please refer to the COPYRIGHT file distributed with this
8 * source distribution.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25/* A lot of this code at least resembles the code in libxode, but since
26 * libxode uses memory pools that we simply have no need for, I decided to
27 * write my own stuff. Also, re-writing this lets me be as lightweight
28 * as I want to be. Thank you libxode for giving me a good starting point */
29
30#include "platform.h"
31
32#include "util.h"
33#include "gnunet_util.h"
34#include "xmlnode.h"
35
36#include <libxml/parser.h>
37#include <string.h>
38
39
40#ifdef _WIN32
41# define NEWLINE_S "\r\n"
42#else
43# define NEWLINE_S "\n"
44#endif
45
46#define TRUE GNUNET_YES
47#define FALSE GNUNET_NO
48
49#define g_return_if_fail(a) if(!(a)) return;
50#define g_return_val_if_fail(a, val) if(!(a)) return (val);
51
52/**
53 * The valid types for an xmlnode
54 */
55typedef enum _XMLNodeType
56{
57 XMLNODE_TYPE_TAG, /**< Just a tag */
58 XMLNODE_TYPE_ATTRIB, /**< Has attributes */
59 XMLNODE_TYPE_DATA /**< Has data */
60} XMLNodeType;
61
62typedef struct
63{
64 xmlnode *current;
65 xmlnode **nodes;
66 unsigned int pos;
67 unsigned int size;
68} XMLNodePool;
69
70struct _xmlnode
71{
72 char *name; /**< The name of the node. */
73 char *xmlns; /**< The namespace of the node */
74 XMLNodeType type; /**< The type of the node. */
75 char *data; /**< The data for the node. */
76 size_t data_sz; /**< The size of the data. */
77 struct _xmlnode *parent; /**< The parent node or @c NULL.*/
78 struct _xmlnode *child; /**< The child node or @c NULL.*/
79 struct _xmlnode *lastchild; /**< The last child node or @c NULL.*/
80 struct _xmlnode *next; /**< The next node or @c NULL. */
81 XMLNodePool *pool;
82 int free_pool; /* set to GNUNET_YES for the root node, which must free the pool */
83};
84
85
86static void *
87g_memdup (const void *data, size_t s)
88{
89 void *ret;
90
91 ret = GNUNET_malloc (s);
92 memcpy (ret, data, s);
93 return ret;
94}
95
96static char *
97g_string_append_len (char *prefix, const void *data, size_t s)
98{
99 char *ret;
100
101 ret = g_strdup_printf ("%s%.*s", prefix, s, data);
102 GNUNET_free (prefix);
103 return ret;
104}
105
106static xmlnode *
107new_node (const char *name, XMLNodeType type, void *user_data)
108{
109 xmlnode *node = GNUNET_malloc (sizeof (xmlnode));
110
111 node->name = name == NULL ? NULL : GNUNET_strdup (name);
112 node->type = type;
113 node->pool = user_data;
114 if (node->pool->size == node->pool->pos)
115 GNUNET_array_grow (node->pool->nodes, node->pool->size,
116 node->pool->size * 2 + 64);
117 node->pool->nodes[node->pool->pos++] = node;
118 node->free_pool = 0;
119 return node;
120}
121
122static xmlnode *
123xmlnode_new (const char *name, void *user_data)
124{
125 g_return_val_if_fail (name != NULL, NULL);
126 return new_node (name, XMLNODE_TYPE_TAG, user_data);
127}
128
129static void
130xmlnode_insert_child (xmlnode * parent, xmlnode * child)
131{
132 g_return_if_fail (parent != NULL);
133 g_return_if_fail (child != NULL);
134
135 child->parent = parent;
136 if (parent->lastchild)
137 parent->lastchild->next = child;
138 else
139 parent->child = child;
140 parent->lastchild = child;
141}
142
143static xmlnode *
144xmlnode_new_child (xmlnode * parent, const char *name, void *user_data)
145{
146 xmlnode *node;
147
148 g_return_val_if_fail (parent != NULL, NULL);
149 g_return_val_if_fail (name != NULL, NULL);
150 node = new_node (name, XMLNODE_TYPE_TAG, user_data);
151 xmlnode_insert_child (parent, node);
152 return node;
153}
154
155static void
156xmlnode_insert_data (xmlnode * node,
157 const char *data, int size, void *user_data)
158{
159 xmlnode *child;
160 size_t real_size;
161
162 g_return_if_fail (node != NULL);
163 g_return_if_fail (data != NULL);
164 g_return_if_fail (size != 0);
165 real_size = size == -1 ? strlen (data) : size;
166 child = new_node (NULL, XMLNODE_TYPE_DATA, user_data);
167 child->data = g_memdup (data, real_size);
168 child->data_sz = real_size;
169 xmlnode_insert_child (node, child);
170}
171
172static void
173xmlnode_remove_attrib (xmlnode * node, const char *attr)
174{
175 xmlnode *attr_node, *sibling = NULL;
176
177 g_return_if_fail (node != NULL);
178 g_return_if_fail (attr != NULL);
179
180 for (attr_node = node->child; attr_node; attr_node = attr_node->next)
181 {
182 if (attr_node->type == XMLNODE_TYPE_ATTRIB &&
183 !strcmp (attr_node->name, attr))
184 {
185 if (node->child == attr_node)
186 {
187 node->child = attr_node->next;
188 }
189 else
190 {
191 sibling->next = attr_node->next;
192 }
193 if (node->lastchild == attr_node)
194 {
195 node->lastchild = sibling;
196 }
197 xmlnode_free (attr_node);
198 return;
199 }
200 sibling = attr_node;
201 }
202}
203
204static void
205xmlnode_set_attrib (xmlnode * node,
206 const char *attr, const char *value, void *user_data)
207{
208 xmlnode *attrib_node;
209
210 g_return_if_fail (node != NULL);
211 g_return_if_fail (attr != NULL);
212 g_return_if_fail (value != NULL);
213 xmlnode_remove_attrib (node, attr);
214 attrib_node = new_node (attr, XMLNODE_TYPE_ATTRIB, user_data);
215 attrib_node->data = GNUNET_strdup (value);
216 xmlnode_insert_child (node, attrib_node);
217}
218
219static void
220xmlnode_set_namespace (xmlnode * node, const char *xmlns)
221{
222 g_return_if_fail (node != NULL);
223 GNUNET_free_non_null (node->xmlns);
224 node->xmlns = GNUNET_strdup (xmlns);
225}
226
227static const char *
228xmlnode_get_namespace (xmlnode * node)
229{
230 g_return_val_if_fail (node != NULL, NULL);
231 return node->xmlns;
232}
233
234static void
235freePool (XMLNodePool * pool)
236{
237 unsigned int i;
238 xmlnode *x;
239
240 for (i = 0; i < pool->pos; i++)
241 {
242 x = pool->nodes[i];
243 GNUNET_free_non_null (x->name);
244 GNUNET_free_non_null (x->data);
245 GNUNET_free_non_null (x->xmlns);
246 GNUNET_free (x);
247 }
248 GNUNET_array_grow (pool->nodes, pool->size, 0);
249 GNUNET_free (pool);
250}
251
252void
253xmlnode_free (xmlnode * node)
254{
255 g_return_if_fail (node != NULL);
256 if (node->free_pool != GNUNET_YES)
257 return;
258 freePool (node->pool);
259}
260
261static xmlnode *
262xmlnode_get_child_with_namespace (const xmlnode * parent,
263 const char *name, const char *ns)
264{
265 xmlnode *x;
266 xmlnode *ret = NULL;
267 char *parent_name;
268 char *child_name;
269
270 if (parent == NULL)
271 return NULL;
272 if (name == NULL)
273 return NULL;
274
275 parent_name = GNUNET_strdup (name);
276 child_name = strstr (parent_name, "/");
277 if (child_name != NULL)
278 {
279 child_name[0] = '\0';
280 child_name++;
281 }
282
283 for (x = parent->child; x; x = x->next)
284 {
285 const char *xmlns = NULL;
286 if (ns)
287 xmlns = xmlnode_get_namespace (x);
288
289 if (x->type == XMLNODE_TYPE_TAG && name
290 && !strcmp (parent_name, x->name) && (!ns
291 || (xmlns
292 && !strcmp (ns, xmlns))))
293 {
294 ret = x;
295 break;
296 }
297 }
298
299 if (child_name && ret)
300 ret = xmlnode_get_child (ret, child_name);
301
302 GNUNET_free (parent_name);
303 return ret;
304}
305
306xmlnode *
307xmlnode_get_child (const xmlnode * parent, const char *name)
308{
309 return xmlnode_get_child_with_namespace (parent, name, NULL);
310}
311
312char *
313xmlnode_get_data (xmlnode * node)
314{
315 char *str = NULL;
316 xmlnode *c;
317
318 if (node == NULL)
319 return NULL;
320 for (c = node->child; c; c = c->next)
321 {
322 if (c->type == XMLNODE_TYPE_DATA)
323 {
324 if (!str)
325 str = GNUNET_strdup ("");
326 str = g_string_append_len (str, c->data, c->data_sz);
327 }
328 }
329 if (str == NULL)
330 return NULL;
331
332 return str;
333}
334
335static void
336xmlnode_parser_element_start_libxml (void *user_data,
337 const xmlChar * element_name,
338 const xmlChar * prefix,
339 const xmlChar * xmlns,
340 int nb_namespaces,
341 const xmlChar ** namespaces,
342 int nb_attributes,
343 int nb_defaulted,
344 const xmlChar ** attributes)
345{
346 XMLNodePool *xpd = user_data;
347 xmlnode *node;
348 int i;
349
350 if (!element_name)
351 return;
352 if (xpd->current)
353 node =
354 xmlnode_new_child (xpd->current, (const char *) element_name,
355 user_data);
356 else
357 node = xmlnode_new ((const char *) element_name, user_data);
358
359 xmlnode_set_namespace (node, (const char *) xmlns);
360
361 for (i = 0; i < nb_attributes * 5; i += 5)
362 {
363 char *txt;
364 int attrib_len = attributes[i + 4] - attributes[i + 3];
365 char *attrib = GNUNET_malloc (attrib_len + 1);
366 memcpy (attrib, attributes[i + 3], attrib_len);
367 attrib[attrib_len] = '\0';
368 txt = attrib;
369 attrib = gaim_unescape_html (txt);
370 GNUNET_free (txt);
371 xmlnode_set_attrib (node, (const char *) attributes[i], attrib,
372 user_data);
373 GNUNET_free (attrib);
374 }
375 xpd->current = node;
376}
377
378static void
379xmlnode_parser_element_end_libxml (void *user_data,
380 const xmlChar * element_name,
381 const xmlChar * prefix,
382 const xmlChar * xmlns)
383{
384 XMLNodePool *xpd = user_data;
385
386 if (!element_name || !xpd->current)
387 return;
388 if (xpd->current->parent)
389 {
390 if (!xmlStrcmp ((xmlChar *) xpd->current->name, element_name))
391 xpd->current = xpd->current->parent;
392 }
393}
394
395static void
396xmlnode_parser_element_text_libxml (void *user_data,
397 const xmlChar * text, int text_len)
398{
399 XMLNodePool *xpd = user_data;
400
401 if (!xpd->current || !text || !text_len)
402 return;
403 xmlnode_insert_data (xpd->current,
404 (const char *) text, text_len, user_data);
405}
406
407static xmlSAXHandler xmlnode_parser_libxml = {
408 .internalSubset = NULL,
409 .isStandalone = NULL,
410 .hasInternalSubset = NULL,
411 .hasExternalSubset = NULL,
412 .resolveEntity = NULL,
413 .getEntity = NULL,
414 .entityDecl = NULL,
415 .notationDecl = NULL,
416 .attributeDecl = NULL,
417 .elementDecl = NULL,
418 .unparsedEntityDecl = NULL,
419 .setDocumentLocator = NULL,
420 .startDocument = NULL,
421 .endDocument = NULL,
422 .startElement = NULL,
423 .endElement = NULL,
424 .reference = NULL,
425 .characters = xmlnode_parser_element_text_libxml,
426 .ignorableWhitespace = NULL,
427 .processingInstruction = NULL,
428 .comment = NULL,
429 .warning = NULL,
430 .error = NULL,
431 .fatalError = NULL,
432 .getParameterEntity = NULL,
433 .cdataBlock = NULL,
434 .externalSubset = NULL,
435 .initialized = XML_SAX2_MAGIC,
436 ._private = NULL,
437 .startElementNs = xmlnode_parser_element_start_libxml,
438 .endElementNs = xmlnode_parser_element_end_libxml,
439 .serror = NULL
440};
441
442xmlnode *
443xmlnode_from_str (const char *str, int size)
444{
445 XMLNodePool *xpd;
446 xmlnode *ret;
447 size_t real_size;
448
449 g_return_val_if_fail (str != NULL, NULL);
450
451 real_size = size < 0 ? strlen (str) : size;
452 xpd = GNUNET_malloc (sizeof (XMLNodePool));
453 memset (xpd, 0, sizeof (XMLNodePool));
454 if (xmlSAXUserParseMemory (&xmlnode_parser_libxml, xpd, str, real_size) < 0)
455 {
456 freePool (xpd);
457 return NULL;
458 }
459 ret = xpd->current;
460 ret->free_pool = GNUNET_YES;
461 return ret;
462}
463
464xmlnode *
465xmlnode_get_next_twin (xmlnode * node)
466{
467 xmlnode *sibling;
468 const char *ns = xmlnode_get_namespace (node);
469
470 g_return_val_if_fail (node != NULL, NULL);
471 g_return_val_if_fail (node->type == XMLNODE_TYPE_TAG, NULL);
472
473 for (sibling = node->next; sibling; sibling = sibling->next)
474 {
475 const char *xmlns = NULL;
476 if (ns)
477 xmlns = xmlnode_get_namespace (sibling);
478
479 if (sibling->type == XMLNODE_TYPE_TAG
480 && !strcmp (node->name, sibling->name) && (!ns
481 || (xmlns
482 && !strcmp (ns,
483 xmlns))))
484 return sibling;
485 }
486 return NULL;
487}
diff --git a/src/upnp/upnp_xmlnode.h b/src/upnp/upnp_xmlnode.h
new file mode 100644
index 000000000..199975e37
--- /dev/null
+++ b/src/upnp/upnp_xmlnode.h
@@ -0,0 +1,92 @@
1/**
2 * @file xmlnode.h XML DOM functions
3 * @ingroup core
4 *
5 * gaim
6 *
7 * Gaim is the legal property of its developers, whose names are too numerous
8 * to list here. Please refer to the COPYRIGHT file distributed with this
9 * source distribution.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25#ifndef _GGAIM_XMLNODE_H_
26#define _GGAIM_XMLNODE_H_
27
28
29#ifdef __cplusplus
30extern "C"
31{
32#endif
33
34/**
35 * An xmlnode.
36 */
37 typedef struct _xmlnode xmlnode;
38
39/**
40 * Gets a child node named name.
41 *
42 * @param parent The parent node.
43 * @param name The child's name.
44 *
45 * @return The child or NULL.
46 */
47 xmlnode *xmlnode_get_child (const xmlnode * parent, const char *name);
48
49/**
50 * Gets the next node with the same name as node.
51 *
52 * @param node The node of a twin to find.
53 *
54 * @return The twin of node or NULL.
55 */
56 xmlnode *xmlnode_get_next_twin (xmlnode * node);
57
58/**
59 * Gets data from a node.
60 *
61 * @param node The node to get data from.
62 *
63 * @return The data from the node. You must g_free
64 * this string when finished using it.
65 */
66 char *xmlnode_get_data (xmlnode * node);
67
68/**
69 * Creates a node from a string of XML. Calling this on the
70 * root node of an XML document will parse the entire document
71 * into a tree of nodes, and return the xmlnode of the root.
72 *
73 * @param str The string of xml.
74 * @param size The size of the string, or -1 if @a str is
75 * NUL-terminated.
76 *
77 * @return The new node.
78 */
79 xmlnode *xmlnode_from_str (const char *str, int size);
80
81/**
82 * Frees a node and all of it's children.
83 *
84 * @param node The node to free.
85 */
86 void xmlnode_free (xmlnode * node);
87
88#ifdef __cplusplus
89}
90#endif
91
92#endif /* _GAIM_XMLNODE_H_ */
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
new file mode 100644
index 000000000..a90b2b793
--- /dev/null
+++ b/src/util/Makefile.am
@@ -0,0 +1,308 @@
1INCLUDES = -I$(top_srcdir)/src/include
2
3plugindir = $(libdir)/gnunet
4
5if MINGW
6 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols -lole32 -lshell32 -luuid -liconv -lstdc++ -lcomdlg32 -lgdi32
7endif
8
9if USE_COVERAGE
10 AM_CFLAGS = --coverage
11endif
12
13lib_LTLIBRARIES = libgnunetutil.la
14
15libgnunetutil_la_SOURCES = \
16 client.c \
17 common_allocation.c \
18 common_endian.c \
19 common_gettext.c \
20 common_logging.c \
21 configuration.c \
22 container_bloomfilter.c \
23 container_meta_data.c \
24 container_multihashmap.c \
25 crypto_aes.c \
26 crypto_crc.c \
27 crypto_hash.c \
28 crypto_ksk.c \
29 crypto_random.c \
30 crypto_rsa.c \
31 disk.c \
32 getopt.c \
33 getopt_helpers.c \
34 network.c \
35 os_installation.c \
36 os_load.c \
37 os_network.c \
38 os_priority.c \
39 plugin.c \
40 program.c \
41 pseudonym.c \
42 scheduler.c \
43 server.c \
44 server_tc.c \
45 service.c \
46 signal.c \
47 strings.c \
48 time.c
49
50
51libgnunetutil_la_LIBADD = \
52 $(GCLIBADD) \
53 $(LIBGCRYPT_LIBS) \
54 -lgmp -lltdl -lz -lextractor
55
56libgnunetutil_la_LDFLAGS = \
57 $(GN_LIB_LDFLAGS) $(WINFLAGS) \
58 -version-info 4:0:0
59
60
61plugin_LTLIBRARIES = \
62 libgnunet_plugin_test.la
63
64libgnunet_plugin_test_la_SOURCES = \
65 test_plugin_plug.c
66libgnunet_plugin_test_la_LDFLAGS = \
67 $(GN_PLUGIN_LDFLAGS)
68
69
70check_PROGRAMS = \
71 test_client \
72 test_common_allocation \
73 test_common_endian \
74 test_common_logging \
75 test_configuration \
76 test_container_bloomfilter \
77 test_container_meta_data \
78 test_container_multihashmap \
79 test_crypto_aes \
80 test_crypto_aes_weak \
81 test_crypto_crc \
82 test_crypto_hash \
83 test_crypto_ksk \
84 test_crypto_random \
85 test_crypto_rsa \
86 test_disk \
87 test_getopt \
88 test_network \
89 test_network_addressing \
90 test_network_receive_cancel \
91 test_network_timeout \
92 test_network_timeout_no_connect \
93 test_network_transmit_cancel \
94 test_os_load \
95 test_os_network \
96 test_os_priority \
97 test_plugin \
98 test_program \
99 test_pseudonym \
100 test_scheduler \
101 test_scheduler_delay \
102 test_server \
103 test_server_disconnect \
104 test_server_with_client \
105 test_service \
106 test_strings \
107 test_time \
108 perf_crypto_hash
109
110TESTS = $(check_PROGRAMS)
111
112test_client_SOURCES = \
113 test_client.c
114test_client_LDADD = \
115 $(top_builddir)/src/util/libgnunetutil.la
116
117test_common_allocation_SOURCES = \
118 test_common_allocation.c
119test_common_allocation_LDADD = \
120 $(top_builddir)/src/util/libgnunetutil.la
121
122test_common_endian_SOURCES = \
123 test_common_endian.c
124test_common_endian_LDADD = \
125 $(top_builddir)/src/util/libgnunetutil.la
126
127test_common_logging_SOURCES = \
128 test_common_logging.c
129test_common_logging_LDADD = \
130 $(top_builddir)/src/util/libgnunetutil.la
131
132test_configuration_SOURCES = \
133 test_configuration.c
134test_configuration_LDADD = \
135 $(top_builddir)/src/util/libgnunetutil.la
136
137test_container_bloomfilter_SOURCES = \
138 test_container_bloomfilter.c
139test_container_bloomfilter_LDADD = \
140 $(top_builddir)/src/util/libgnunetutil.la
141
142test_container_meta_data_SOURCES = \
143 test_container_meta_data.c
144test_container_meta_data_LDADD = \
145 $(top_builddir)/src/util/libgnunetutil.la
146
147test_container_multihashmap_SOURCES = \
148 test_container_multihashmap.c
149test_container_multihashmap_LDADD = \
150 $(top_builddir)/src/util/libgnunetutil.la
151
152test_crypto_aes_SOURCES = \
153 test_crypto_aes.c
154test_crypto_aes_LDADD = \
155 $(top_builddir)/src/util/libgnunetutil.la
156
157test_crypto_aes_weak_SOURCES = \
158 test_crypto_aes_weak.c
159test_crypto_aes_weak_LDADD = \
160 $(top_builddir)/src/util/libgnunetutil.la
161
162test_crypto_crc_SOURCES = \
163 test_crypto_crc.c
164test_crypto_crc_LDADD = \
165 $(top_builddir)/src/util/libgnunetutil.la
166
167test_crypto_hash_SOURCES = \
168 test_crypto_hash.c
169test_crypto_hash_LDADD = \
170 $(top_builddir)/src/util/libgnunetutil.la
171
172test_crypto_ksk_SOURCES = \
173 test_crypto_ksk.c
174test_crypto_ksk_LDADD = \
175 $(top_builddir)/src/util/libgnunetutil.la
176
177test_crypto_random_SOURCES = \
178 test_crypto_random.c
179test_crypto_random_LDADD = \
180 $(top_builddir)/src/util/libgnunetutil.la
181
182test_crypto_rsa_SOURCES = \
183 test_crypto_rsa.c
184test_crypto_rsa_LDADD = \
185 $(top_builddir)/src/util/libgnunetutil.la
186
187test_disk_SOURCES = \
188 test_disk.c
189test_disk_LDADD = \
190 $(top_builddir)/src/util/libgnunetutil.la
191
192test_getopt_SOURCES = \
193 test_getopt.c
194test_getopt_LDADD = \
195 $(top_builddir)/src/util/libgnunetutil.la
196
197test_network_SOURCES = \
198 test_network.c
199test_network_LDADD = \
200 $(top_builddir)/src/util/libgnunetutil.la
201
202test_network_addressing_SOURCES = \
203 test_network_addressing.c
204test_network_addressing_LDADD = \
205 $(top_builddir)/src/util/libgnunetutil.la
206
207test_network_receive_cancel_SOURCES = \
208 test_network_receive_cancel.c
209test_network_receive_cancel_LDADD = \
210 $(top_builddir)/src/util/libgnunetutil.la
211
212test_network_timeout_SOURCES = \
213 test_network_timeout.c
214test_network_timeout_LDADD = \
215 $(top_builddir)/src/util/libgnunetutil.la
216
217test_network_timeout_no_connect_SOURCES = \
218 test_network_timeout_no_connect.c
219test_network_timeout_no_connect_LDADD = \
220 $(top_builddir)/src/util/libgnunetutil.la
221
222test_network_transmit_cancel_SOURCES = \
223 test_network_transmit_cancel.c
224test_network_transmit_cancel_LDADD = \
225 $(top_builddir)/src/util/libgnunetutil.la
226
227test_os_load_SOURCES = \
228 test_os_load.c
229test_os_load_LDADD = \
230 $(top_builddir)/src/util/libgnunetutil.la
231
232test_os_network_SOURCES = \
233 test_os_network.c
234test_os_network_LDADD = \
235 $(top_builddir)/src/util/libgnunetutil.la
236
237test_os_priority_SOURCES = \
238 test_os_priority.c
239test_os_priority_LDADD = \
240 $(top_builddir)/src/util/libgnunetutil.la
241
242test_plugin_SOURCES = \
243 test_plugin.c
244test_plugin_LDADD = \
245 $(top_builddir)/src/util/libgnunetutil.la
246
247test_program_SOURCES = \
248 test_program.c
249test_program_LDADD = \
250 $(top_builddir)/src/util/libgnunetutil.la
251
252test_pseudonym_SOURCES = \
253 test_pseudonym.c
254test_pseudonym_LDADD = \
255 $(top_builddir)/src/util/libgnunetutil.la
256
257test_scheduler_SOURCES = \
258 test_scheduler.c
259test_scheduler_LDADD = \
260 $(top_builddir)/src/util/libgnunetutil.la
261
262test_scheduler_delay_SOURCES = \
263 test_scheduler_delay.c
264test_scheduler_delay_LDADD = \
265 $(top_builddir)/src/util/libgnunetutil.la
266
267test_server_SOURCES = \
268 test_server.c
269test_server_LDADD = \
270 $(top_builddir)/src/util/libgnunetutil.la
271
272test_server_disconnect_SOURCES = \
273 test_server_disconnect.c
274test_server_disconnect_LDADD = \
275 $(top_builddir)/src/util/libgnunetutil.la
276
277test_server_with_client_SOURCES = \
278 test_server_with_client.c
279test_server_with_client_LDADD = \
280 $(top_builddir)/src/util/libgnunetutil.la
281
282test_service_SOURCES = \
283 test_service.c
284test_service_LDADD = \
285 $(top_builddir)/src/util/libgnunetutil.la
286
287test_strings_SOURCES = \
288 test_strings.c
289test_strings_LDADD = \
290 $(top_builddir)/src/util/libgnunetutil.la
291
292test_time_SOURCES = \
293 test_time.c
294test_time_LDADD = \
295 $(top_builddir)/src/util/libgnunetutil.la
296
297perf_crypto_hash_SOURCES = \
298 perf_crypto_hash.c
299perf_crypto_hash_LDADD = \
300 $(top_builddir)/src/util/libgnunetutil.la
301
302
303EXTRA_DIST = \
304 test_configuration_data.conf \
305 test_container_meta_data_image.jpg \
306 test_program_data.conf \
307 test_pseudonym_data.conf \
308 test_service_data.conf
diff --git a/src/util/client.c b/src/util/client.c
new file mode 100644
index 000000000..9dd70f266
--- /dev/null
+++ b/src/util/client.c
@@ -0,0 +1,526 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2006, 2008, 2009 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 2, 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 util/client.c
23 * @brief code for access to services
24 * @author Christian Grothoff
25 *
26 * Generic TCP code for reliable, record-oriented TCP
27 * connections between clients and service providers.
28 */
29
30#include "platform.h"
31#include "gnunet_common.h"
32#include "gnunet_client_lib.h"
33#include "gnunet_protocols.h"
34#include "gnunet_server_lib.h"
35#include "gnunet_scheduler_lib.h"
36
37#define DEBUG_CLIENT GNUNET_NO
38
39/**
40 * Struct to refer to a GNUnet TCP connection.
41 * This is more than just a socket because if the server
42 * drops the connection, the client automatically tries
43 * to reconnect (and for that needs connection information).
44 */
45struct GNUNET_CLIENT_Connection
46{
47
48 /**
49 * the socket handle, NULL if not live
50 */
51 struct GNUNET_NETWORK_SocketHandle *sock;
52
53 /**
54 * Our scheduler.
55 */
56 struct GNUNET_SCHEDULER_Handle *sched;
57
58 /**
59 * Name of the service we interact with.
60 */
61 char *service_name;
62
63 /**
64 * ID of task used for receiving.
65 */
66 GNUNET_SCHEDULER_TaskIdentifier receiver_task;
67
68 /**
69 * Handler for current receiver task.
70 */
71 GNUNET_CLIENT_MessageHandler receiver_handler;
72
73 /**
74 * Closure for receiver_handler.
75 */
76 void *receiver_handler_cls;
77
78 /**
79 * Handler for service test completion (NULL unless in service_test)
80 */
81 GNUNET_SCHEDULER_Task test_cb;
82
83 /**
84 * Closure for test_cb (NULL unless in service_test)
85 */
86 void *test_cb_cls;
87
88 /**
89 * Buffer for received message.
90 */
91 char *received_buf;
92
93 /**
94 * Timeout for receiving a response (absolute time).
95 */
96 struct GNUNET_TIME_Absolute receive_timeout;
97
98 /**
99 * Number of bytes in received_buf that are valid.
100 */
101 size_t received_pos;
102
103 /**
104 * Size of received_buf.
105 */
106 size_t received_size;
107
108 /**
109 * Do we have a complete response in received_buf?
110 */
111 int msg_complete;
112
113};
114
115
116/**
117 * Get a connection with a service.
118 *
119 * @param sched scheduler to use
120 * @param service_name name of the service
121 * @param cfg configuration to use
122 * @return NULL on error (service unknown to configuration)
123 */
124struct GNUNET_CLIENT_Connection *
125GNUNET_CLIENT_connect (struct GNUNET_SCHEDULER_Handle *sched,
126 const char *service_name,
127 struct GNUNET_CONFIGURATION_Handle *cfg)
128{
129 struct GNUNET_CLIENT_Connection *ret;
130 struct GNUNET_NETWORK_SocketHandle *sock;
131 char *hostname;
132 unsigned long long port;
133
134 if ((GNUNET_OK !=
135 GNUNET_CONFIGURATION_get_value_number (cfg,
136 service_name,
137 "PORT",
138 &port)) ||
139 (port > 65535) ||
140 (GNUNET_OK !=
141 GNUNET_CONFIGURATION_get_value_string (cfg,
142 service_name,
143 "HOSTNAME", &hostname)))
144 {
145 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
146 "Could not determine valid hostname and port for service `%s' from configuration.\n",
147 service_name);
148 return NULL;
149 }
150 sock = GNUNET_NETWORK_socket_create_from_connect (sched,
151 hostname,
152 port,
153 GNUNET_SERVER_MAX_MESSAGE_SIZE);
154 GNUNET_free (hostname);
155 if (sock == NULL)
156 return NULL;
157 ret = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_Connection));
158 ret->sock = sock;
159 ret->sched = sched;
160 ret->service_name = GNUNET_strdup (service_name);
161 return ret;
162}
163
164
165/**
166 * Receiver task has completed, free rest of client
167 * data structures.
168 */
169static void
170finish_cleanup (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
171{
172 struct GNUNET_CLIENT_Connection *sock = cls;
173
174 GNUNET_array_grow (sock->received_buf, sock->received_size, 0);
175 GNUNET_free (sock->service_name);
176 GNUNET_free (sock);
177}
178
179
180/**
181 * Destroy connection with the service.
182 */
183void
184GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock)
185{
186 GNUNET_assert (sock->sock != NULL);
187 GNUNET_NETWORK_socket_destroy (sock->sock);
188 sock->sock = NULL;
189 sock->receiver_handler = NULL;
190 GNUNET_SCHEDULER_add_after (sock->sched,
191 GNUNET_YES,
192 GNUNET_SCHEDULER_PRIORITY_KEEP,
193 sock->receiver_task, &finish_cleanup, sock);
194}
195
196
197/**
198 * check if message is complete
199 */
200static void
201check_complete (struct GNUNET_CLIENT_Connection *conn)
202{
203 if ((conn->received_pos >= sizeof (struct GNUNET_MessageHeader)) &&
204 (conn->received_pos >=
205 ntohs (((const struct GNUNET_MessageHeader *) conn->received_buf)->
206 size)))
207 conn->msg_complete = GNUNET_YES;
208}
209
210
211/**
212 * Callback function for data received from the network. Note that
213 * both "available" and "err" would be 0 if the read simply timed out.
214 *
215 * @param cls closure
216 * @param buf pointer to received data
217 * @param available number of bytes availabe in "buf",
218 * possibly 0 (on errors)
219 * @param addr address of the sender
220 * @param addrlen size of addr
221 * @param errCode value of errno (on errors receiving)
222 */
223static void
224receive_helper (void *cls,
225 const void *buf,
226 size_t available,
227 const struct sockaddr *addr, socklen_t addrlen, int errCode)
228{
229 struct GNUNET_CLIENT_Connection *conn = cls;
230 struct GNUNET_TIME_Relative remaining;
231
232 GNUNET_assert (conn->msg_complete == GNUNET_NO);
233 conn->receiver_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
234
235 if ((available == 0) || (conn->sock == NULL) || (errCode != 0))
236 {
237 /* signal timeout! */
238 if (conn->receiver_handler != NULL)
239 {
240 conn->receiver_handler (conn->receiver_handler_cls, NULL);
241 conn->receiver_handler = NULL;
242 }
243 return;
244 }
245
246 /* FIXME: optimize for common fast case where buf contains the
247 entire message and we need no copying... */
248
249
250 /* slow path: append to array */
251 if (conn->received_size < conn->received_pos + available)
252 GNUNET_array_grow (conn->received_buf,
253 conn->received_size, conn->received_pos + available);
254 memcpy (&conn->received_buf[conn->received_pos], buf, available);
255 conn->received_pos += available;
256 check_complete (conn);
257 /* check for timeout */
258 remaining = GNUNET_TIME_absolute_get_remaining (conn->receive_timeout);
259 if (remaining.value == 0)
260 {
261 /* signal timeout! */
262 conn->receiver_handler (conn->receiver_handler_cls, NULL);
263 return;
264 }
265 /* back to receive -- either for more data or to call callback! */
266 GNUNET_CLIENT_receive (conn,
267 conn->receiver_handler,
268 conn->receiver_handler_cls, remaining);
269}
270
271
272/**
273 * Continuation to call the receive callback.
274 */
275static void
276receive_task (void *scls, const struct GNUNET_SCHEDULER_TaskContext *tc)
277{
278 struct GNUNET_CLIENT_Connection *sock = scls;
279 const struct GNUNET_MessageHeader *cmsg;
280 struct GNUNET_MessageHeader *msg;
281 GNUNET_CLIENT_MessageHandler handler = sock->receiver_handler;
282 void *cls = sock->receiver_handler_cls;
283 uint16_t msize;
284
285 GNUNET_assert (GNUNET_YES == sock->msg_complete);
286 sock->receiver_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
287 cmsg = (const struct GNUNET_MessageHeader *) sock->received_buf;
288 msize = ntohs (cmsg->size);
289 GNUNET_assert (sock->received_pos >= msize);
290 msg = GNUNET_malloc (msize);
291 memcpy (msg, cmsg, msize);
292 memmove (sock->received_buf,
293 &sock->received_buf[msize], sock->received_pos - msize);
294 sock->received_pos -= msize;
295 sock->msg_complete = GNUNET_NO;
296 sock->receiver_handler = NULL;
297 check_complete (sock);
298 handler (cls, msg);
299 GNUNET_free (msg);
300}
301
302
303/**
304 * Read from the service.
305 *
306 * @param sched scheduler to use
307 * @param sock the service
308 * @param handler function to call with the message
309 * @param cls closure for handler
310 * @param timeout how long to wait until timing out
311 */
312void
313GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock,
314 GNUNET_CLIENT_MessageHandler handler,
315 void *cls, struct GNUNET_TIME_Relative timeout)
316{
317 if (sock->sock == NULL)
318 {
319 /* already disconnected, fail instantly! */
320 GNUNET_break (0); /* this should not happen in well-written code! */
321 handler (cls, NULL);
322 return;
323 }
324 GNUNET_assert (sock->receiver_task ==
325 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK);
326 sock->receiver_handler = handler;
327 sock->receiver_handler_cls = cls;
328 sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout);
329 if (GNUNET_YES == sock->msg_complete)
330 sock->receiver_task = GNUNET_SCHEDULER_add_after (sock->sched,
331 GNUNET_YES,
332 GNUNET_SCHEDULER_PRIORITY_KEEP,
333 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
334 &receive_task, sock);
335 else
336 sock->receiver_task = GNUNET_NETWORK_receive (sock->sock,
337 GNUNET_SERVER_MAX_MESSAGE_SIZE,
338 timeout,
339 &receive_helper, sock);
340}
341
342
343static size_t
344write_shutdown (void *cls, size_t size, void *buf)
345{
346 struct GNUNET_MessageHeader *msg;
347
348 if (size < sizeof (struct GNUNET_MessageHeader))
349 return 0; /* client disconnected */
350 msg = (struct GNUNET_MessageHeader *) buf;
351 msg->type = htons (GNUNET_MESSAGE_TYPE_SHUTDOWN);
352 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
353 return sizeof (struct GNUNET_MessageHeader);
354}
355
356
357/**
358 * Request that the service should shutdown.
359 * Afterwards, the connection should be disconnected.
360 *
361 * @param sched scheduler to use
362 * @param sock the socket connected to the service
363 */
364void
365GNUNET_CLIENT_service_shutdown (struct GNUNET_CLIENT_Connection *sock)
366{
367 GNUNET_NETWORK_notify_transmit_ready (sock->sock,
368 sizeof (struct GNUNET_MessageHeader),
369 GNUNET_TIME_UNIT_FOREVER_REL,
370 &write_shutdown, NULL);
371}
372
373
374/**
375 * Report service unavailable.
376 */
377static void
378service_test_error (struct GNUNET_SCHEDULER_Handle *s,
379 GNUNET_SCHEDULER_Task task, void *task_cls)
380{
381 GNUNET_SCHEDULER_add_continuation (s,
382 GNUNET_YES,
383 task,
384 task_cls,
385 GNUNET_SCHEDULER_REASON_TIMEOUT);
386}
387
388
389/**
390 * Receive confirmation from test, service is up.
391 *
392 * @param cls closure
393 * @param msg message received, NULL on timeout or fatal error
394 */
395static void
396confirm_handler (void *cls, const struct GNUNET_MessageHeader *msg)
397{
398 struct GNUNET_CLIENT_Connection *conn = cls;
399 /* We may want to consider looking at the reply in more
400 detail in the future, for example, is this the
401 correct service? FIXME! */
402 if (msg != NULL)
403 {
404#if DEBUG_CLIENT
405 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
406 "Received confirmation that service is running.\n");
407#endif
408 GNUNET_SCHEDULER_add_continuation (conn->sched,
409 GNUNET_YES,
410 conn->test_cb,
411 conn->test_cb_cls,
412 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
413 }
414 else
415 {
416 service_test_error (conn->sched, conn->test_cb, conn->test_cb_cls);
417 }
418 GNUNET_CLIENT_disconnect (conn);
419}
420
421
422static size_t
423write_test (void *cls, size_t size, void *buf)
424{
425 struct GNUNET_MessageHeader *msg;
426
427 if (size < sizeof (struct GNUNET_MessageHeader))
428 {
429#if DEBUG_CLIENT
430 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
431 _("Failure to transmit TEST request.\n"));
432#endif
433 return 0; /* client disconnected */
434 }
435#if DEBUG_CLIENT
436 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Transmitting TEST request.\n"));
437#endif
438 msg = (struct GNUNET_MessageHeader *) buf;
439 msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
440 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
441 return sizeof (struct GNUNET_MessageHeader);
442}
443
444
445/**
446 * Wait until the service is running.
447 *
448 * @param sched scheduler to use
449 * @param service name of the service to wait for
450 * @param cfg configuration to use
451 * @param timeout how long to wait at most in ms
452 * @param task task to run if service is running
453 * (reason will be "PREREQ_DONE" (service running)
454 * or "TIMEOUT" (service not known to be running))
455 * @param task_cls closure for task
456 */
457void
458GNUNET_CLIENT_service_test (struct GNUNET_SCHEDULER_Handle *sched,
459 const char *service,
460 struct GNUNET_CONFIGURATION_Handle *cfg,
461 struct GNUNET_TIME_Relative timeout,
462 GNUNET_SCHEDULER_Task task, void *task_cls)
463{
464 struct GNUNET_CLIENT_Connection *conn;
465
466#if DEBUG_CLIENT
467 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
468 "Testing if service `%s' is running.\n", service);
469#endif
470 conn = GNUNET_CLIENT_connect (sched, service, cfg);
471 if (conn == NULL)
472 {
473 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
474 _
475 ("Could not connect to service `%s', must not be running.\n"),
476 service);
477 service_test_error (sched, task, task_cls);
478 return;
479 }
480 conn->test_cb = task;
481 conn->test_cb_cls = task_cls;
482 if (NULL ==
483 GNUNET_NETWORK_notify_transmit_ready (conn->sock,
484 sizeof (struct
485 GNUNET_MessageHeader),
486 timeout, &write_test, NULL))
487 {
488 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
489 _("Failure to transmit request to service `%s'\n"),
490 service);
491 service_test_error (sched, task, task_cls);
492 GNUNET_CLIENT_disconnect (conn);
493 return;
494 }
495 GNUNET_CLIENT_receive (conn, &confirm_handler, conn, timeout);
496}
497
498
499/**
500 * Ask the client to call us once the specified number of bytes
501 * are free in the transmission buffer. May call the notify
502 * method immediately if enough space is available.
503 *
504 * @param client connection to the service
505 * @param size number of bytes to send
506 * @param timeout after how long should we give up (and call
507 * notify with buf NULL and size 0)?
508 * @param notify function to call
509 * @param notify_cls closure for notify
510 * @return NULL if our buffer will never hold size bytes,
511 * a handle if the notify callback was queued (can be used to cancel)
512 */
513struct GNUNET_NETWORK_TransmitHandle *
514GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock,
515 size_t size,
516 struct GNUNET_TIME_Relative timeout,
517 GNUNET_NETWORK_TransmitReadyNotify
518 notify, void *notify_cls)
519{
520 return GNUNET_NETWORK_notify_transmit_ready (sock->sock,
521 size,
522 timeout, notify, notify_cls);
523}
524
525
526/* end of client.c */
diff --git a/src/util/common_allocation.c b/src/util/common_allocation.c
new file mode 100644
index 000000000..9fabb3a32
--- /dev/null
+++ b/src/util/common_allocation.c
@@ -0,0 +1,206 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2005, 2006 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 2, 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 util/memory/common_allocation.c
23 * @brief wrapper around malloc/free
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_common.h"
29
30#ifndef INT_MAX
31#define INT_MAX 0x7FFFFFFF
32#endif
33
34/**
35 * Allocate memory. Checks the return value, aborts if no more
36 * memory is available.
37 *
38 * @param size how many bytes of memory to allocate, do NOT use
39 * this function (or GNUNET_malloc) to allocate more than several MB
40 * of memory, if you are possibly needing a very large chunk use
41 * GNUNET_xmalloc_unchecked_ instead.
42 * @param filename where in the code was the call to GNUNET_array_grow
43 * @param linenumber where in the code was the call to GNUNET_array_grow
44 * @return pointer to size bytes of memory
45 */
46void *
47GNUNET_xmalloc_ (size_t size, const char *filename, int linenumber)
48{
49 /* As a security precaution, we generally do not allow very large
50 allocations using the default 'GNUNET_malloc' macro */
51 GNUNET_assert_at (size <= GNUNET_MAX_GNUNET_MALLOC_CHECKED, filename,
52 linenumber);
53 return GNUNET_xmalloc_unchecked_ (size, filename, linenumber);
54}
55
56void *
57GNUNET_xmalloc_unchecked_ (size_t size, const char *filename, int linenumber)
58{
59 void *result;
60
61 GNUNET_assert_at (size < INT_MAX, filename, linenumber);
62 result = malloc (size);
63 if (result == NULL)
64 {
65 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "malloc");
66 abort ();
67 }
68 memset (result, 0, size);
69 return result;
70}
71
72/**
73 * Reallocate memory. Checks the return value, aborts if no more
74 * memory is available.
75 *
76 * @ptr the pointer to reallocate
77 * @param size how many bytes of memory to allocate, do NOT use
78 * this function (or GNUNET_malloc) to allocate more than several MB
79 * of memory
80 * @param filename where in the code was the call to GNUNET_realloc
81 * @param linenumber where in the code was the call to GNUNET_realloc
82 * @return pointer to size bytes of memory
83 */
84void *
85GNUNET_xrealloc_ (void *ptr,
86 const size_t n, const char *filename, int linenumber)
87{
88 ptr = realloc (ptr, n);
89 if (!ptr)
90 {
91 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "realloc");
92 abort ();
93 }
94 return ptr;
95}
96
97/**
98 * Free memory. Merely a wrapper for the case that we
99 * want to keep track of allocations.
100 *
101 * @param ptr the pointer to free
102 * @param filename where in the code was the call to GNUNET_array_grow
103 * @param linenumber where in the code was the call to GNUNET_array_grow
104 */
105void
106GNUNET_xfree_ (void *ptr, const char *filename, int linenumber)
107{
108 GNUNET_assert_at (ptr != NULL, filename, linenumber);
109 free (ptr);
110}
111
112/**
113 * Dup a string (same semantics as strdup).
114 *
115 * @param str the string to dup
116 * @param filename where in the code was the call to GNUNET_array_grow
117 * @param linenumber where in the code was the call to GNUNET_array_grow
118 * @return strdup(str)
119 */
120char *
121GNUNET_xstrdup_ (const char *str, const char *filename, int linenumber)
122{
123 char *res;
124
125 GNUNET_assert_at (str != NULL, filename, linenumber);
126 res = GNUNET_xmalloc_ (strlen (str) + 1, filename, linenumber);
127 memcpy (res, str, strlen (str) + 1);
128 return res;
129}
130
131/**
132 * Grow an array. Grows old by (*oldCount-newCount)*elementSize bytes
133 * and sets *oldCount to newCount.
134 *
135 * @param old address of the pointer to the array
136 * *old may be NULL
137 * @param elementSize the size of the elements of the array
138 * @param oldCount address of the number of elements in the *old array
139 * @param newCount number of elements in the new array, may be 0
140 * @param filename where in the code was the call to GNUNET_array_grow
141 * @param linenumber where in the code was the call to GNUNET_array_grow
142 */
143void
144GNUNET_xgrow_ (void **old,
145 size_t elementSize,
146 unsigned int *oldCount,
147 unsigned int newCount, const char *filename, int linenumber)
148{
149 void *tmp;
150 size_t size;
151
152 GNUNET_assert_at (INT_MAX / elementSize > newCount, filename, linenumber);
153 size = newCount * elementSize;
154 if (size == 0)
155 {
156 tmp = NULL;
157 }
158 else
159 {
160 tmp = GNUNET_xmalloc_ (size, filename, linenumber);
161 memset (tmp, 0, size); /* client code should not rely on this, though... */
162 if (*oldCount > newCount)
163 *oldCount = newCount; /* shrink is also allowed! */
164 memcpy (tmp, *old, elementSize * (*oldCount));
165 }
166
167 if (*old != NULL)
168 {
169 GNUNET_xfree_ (*old, filename, linenumber);
170 }
171 *old = tmp;
172 *oldCount = newCount;
173}
174
175
176int
177GNUNET_asprintf (char **buf, const char *format, ...)
178{
179 int ret;
180 va_list args;
181
182 va_start (args, format);
183 ret = VSNPRINTF (NULL, 0, format, args);
184 va_end (args);
185 *buf = GNUNET_malloc (ret + 1);
186 va_start (args, format);
187 ret = VSPRINTF (*buf, format, args);
188 va_end (args);
189 return ret;
190}
191
192int
193GNUNET_snprintf (char *buf, size_t size, const char *format, ...)
194{
195 int ret;
196 va_list args;
197
198 va_start (args, format);
199 ret = VSNPRINTF (buf, size, format, args);
200 va_end (args);
201 GNUNET_assert (ret <= size);
202 return ret;
203}
204
205
206/* end of common_allocation.c */
diff --git a/src/util/common_endian.c b/src/util/common_endian.c
new file mode 100644
index 000000000..223144c40
--- /dev/null
+++ b/src/util/common_endian.c
@@ -0,0 +1,52 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2006 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 2, 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 util/common_endian.c
23 * @brief endian conversion helpers
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_common.h"
29
30unsigned long long
31GNUNET_ntohll (unsigned long long n)
32{
33#if __BYTE_ORDER == __BIG_ENDIAN
34 return n;
35#else
36 return (((unsigned long long) ntohl (n)) << 32) + ntohl (n >> 32);
37#endif
38}
39
40unsigned long long
41GNUNET_htonll (unsigned long long n)
42{
43#if __BYTE_ORDER == __BIG_ENDIAN
44 return n;
45#else
46 return (((unsigned long long) htonl (n)) << 32) + htonl (n >> 32);
47#endif
48}
49
50
51
52/* end of common_endian.c */
diff --git a/src/util/common_gettext.c b/src/util/common_gettext.c
new file mode 100644
index 000000000..ad347e160
--- /dev/null
+++ b/src/util/common_gettext.c
@@ -0,0 +1,42 @@
1/*
2 This file is part of GNUnet.
3 (C) 2008 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 2, 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 util/common_gettext.c
23 * @brief gettext init routine
24 * @author Heikki Lindholm
25 */
26#include "platform.h"
27#include "gnunet_common.h"
28#include "gnunet_os_lib.h"
29
30void __attribute__ ((constructor)) GNUNET_util_generic_ltdl_init ()
31{
32#if ENABLE_NLS
33 char *path;
34
35 path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LOCALEDIR);
36 if (path != NULL)
37 {
38 BINDTEXTDOMAIN ("GNUnet", path);
39 GNUNET_free (path);
40 }
41#endif
42}
diff --git a/src/util/common_logging.c b/src/util/common_logging.c
new file mode 100644
index 000000000..4068ed94b
--- /dev/null
+++ b/src/util/common_logging.c
@@ -0,0 +1,401 @@
1/*
2 This file is part of GNUnet.
3 (C) 2006, 2008, 2009 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 2, 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 util/common_logging.c
23 * @brief error handling API
24 *
25 * @author Christian Grothoff
26 */
27#include "platform.h"
28#include "gnunet_common.h"
29#include "gnunet_crypto_lib.h"
30#include "gnunet_strings_lib.h"
31#include "gnunet_time_lib.h"
32
33/**
34 * After how many seconds do we always print
35 * that "message X was repeated N times"? Use 12h.
36 */
37#define BULK_DELAY_THRESHOLD (12 * 60 * 60 * 1000)
38
39/**
40 * After how many repetitions do we always print
41 * that "message X was repeated N times"? (even if
42 * we have not yet reached the delay threshold)
43 */
44#define BULK_REPEAT_THRESHOLD 1000
45
46/**
47 * How many characters do we use for matching of
48 * bulk messages?
49 */
50#define BULK_TRACK_SIZE 256
51
52/**
53 * How many characters can a date/time string
54 * be at most?
55 */
56#define DATE_STR_SIZE 64
57
58/**
59 * Linked list of active loggers.
60 */
61struct CustomLogger
62{
63 /**
64 * This is a linked list.
65 */
66 struct CustomLogger *next;
67
68 /**
69 * Log function.
70 */
71 GNUNET_Logger logger;
72
73 /**
74 * Closure for logger.
75 */
76 void *logger_cls;
77};
78
79/**
80 * The last "bulk" error message that we have been logging.
81 * Note that this message maybe truncated to the first BULK_TRACK_SIZE
82 * characters, in which case it is NOT 0-terminated!
83 */
84static char last_bulk[BULK_TRACK_SIZE];
85
86/**
87 * Type of the last bulk message.
88 */
89static enum GNUNET_ErrorType last_bulk_kind;
90
91/**
92 * Time of the last bulk error message (0 for none)
93 */
94static struct GNUNET_TIME_Absolute last_bulk_time;
95
96/**
97 * Number of times that bulk message has been repeated since.
98 */
99static unsigned int last_bulk_repeat;
100
101/**
102 * Component when the last bulk was logged.
103 */
104static const char *last_bulk_comp;
105
106/**
107 * Running component.
108 */
109static const char *component;
110
111/**
112 * Minimum log level.
113 */
114static enum GNUNET_ErrorType min_level;
115
116/**
117 * Linked list of our custom loggres.
118 */
119static struct CustomLogger *loggers;
120
121/**
122 * Number of log calls to ignore.
123 */
124static unsigned int skip_log;
125
126/**
127 * Convert a textual description of a loglevel
128 * to the respective GNUNET_GE_KIND.
129 * @returns GNUNET_GE_INVALID if log does not parse
130 */
131static enum GNUNET_ErrorType
132get_type (const char *log)
133{
134 if (0 == strcasecmp (log, _("DEBUG")))
135 return GNUNET_ERROR_TYPE_DEBUG;
136 if (0 == strcasecmp (log, _("INFO")))
137 return GNUNET_ERROR_TYPE_INFO;
138 if (0 == strcasecmp (log, _("WARNING")))
139 return GNUNET_ERROR_TYPE_WARNING;
140 if (0 == strcasecmp (log, _("ERROR")))
141 return GNUNET_ERROR_TYPE_ERROR;
142 return GNUNET_ERROR_TYPE_INVALID;
143}
144
145/**
146 * Setup logging.
147 *
148 * @param comp default component to use
149 * @param loglevel what types of messages should be logged
150 */
151int
152GNUNET_log_setup (const char *comp, const char *loglevel, const char *logfile)
153{
154 FILE *altlog;
155
156 component = comp;
157 min_level = get_type (loglevel);
158 if (logfile == NULL)
159 return GNUNET_OK;
160 altlog = fopen (logfile, "a");
161 if (altlog == NULL)
162 {
163 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", logfile);
164 return GNUNET_SYSERR;
165 }
166 if (stderr != NULL)
167 fclose (stderr);
168 stderr = altlog;
169 return GNUNET_OK;
170}
171
172/**
173 * Add a custom logger.
174 *
175 * @param logger log function
176 * @param logger_cls closure for logger
177 */
178void
179GNUNET_logger_add (GNUNET_Logger logger, void *logger_cls)
180{
181 struct CustomLogger *entry;
182
183 entry = GNUNET_malloc (sizeof (struct CustomLogger));
184 entry->logger = logger;
185 entry->logger_cls = logger_cls;
186 entry->next = loggers;
187 loggers = entry;
188}
189
190/**
191 * Remove a custom logger.
192 *
193 * @param logger log function
194 * @param logger_cls closure for logger
195 */
196void
197GNUNET_logger_remove (GNUNET_Logger logger, void *logger_cls)
198{
199 struct CustomLogger *pos;
200 struct CustomLogger *prev;
201
202 prev = NULL;
203 pos = loggers;
204 while ((pos != NULL) &&
205 ((pos->logger != logger) || (pos->logger_cls != logger_cls)))
206 {
207 prev = pos;
208 pos = pos->next;
209 }
210 GNUNET_assert (pos != NULL);
211 if (prev == NULL)
212 loggers = pos->next;
213 else
214 prev->next = pos->next;
215 GNUNET_free (pos);
216}
217
218static void
219output_message (enum GNUNET_ErrorType kind,
220 const char *comp, const char *datestr, const char *msg)
221{
222 struct CustomLogger *pos;
223 if (stderr != NULL)
224 fprintf (stderr, "%s %s %s %s", datestr, comp,
225 GNUNET_error_type_to_string (kind), msg);
226 pos = loggers;
227 while (pos != NULL)
228 {
229 pos->logger (pos->logger_cls, kind, comp, datestr, msg);
230 pos = pos->next;
231 }
232}
233
234static void
235flush_bulk (const char *datestr)
236{
237 char msg[DATE_STR_SIZE + BULK_TRACK_SIZE + 256];
238 int rev;
239 char *last;
240 char *ft;
241
242 if ((last_bulk_time.value == 0) || (last_bulk_repeat == 0))
243 return;
244 rev = 0;
245 last = memchr (last_bulk, '\0', BULK_TRACK_SIZE);
246 if (last == NULL)
247 last = &last_bulk[BULK_TRACK_SIZE - 1];
248 else if (last != last_bulk)
249 last--;
250 if (last[0] == '\n')
251 {
252 rev = 1;
253 last[0] = '\0';
254 }
255 ft =
256 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration
257 (last_bulk_time));
258 snprintf (msg, sizeof (msg),
259 _("Message `%.*s' repeated %u times in the last %s\n"),
260 BULK_TRACK_SIZE, last_bulk, last_bulk_repeat, ft);
261 GNUNET_free (ft);
262 if (rev == 1)
263 last[0] = '\n';
264 output_message (last_bulk_kind, last_bulk_comp, datestr, msg);
265 last_bulk_time = GNUNET_TIME_absolute_get ();
266 last_bulk_repeat = 0;
267}
268
269
270/**
271 * Ignore the next n calls to the log function.
272 *
273 * @param n number of log calls to ignore
274 */
275void
276GNUNET_log_skip (unsigned int n)
277{
278 int ok;
279
280 if (n == 0)
281 {
282 ok = (0 == skip_log);
283 skip_log = 0;
284 GNUNET_assert (ok);
285 }
286 skip_log += n;
287}
288
289
290static void
291mylog (enum GNUNET_ErrorType kind,
292 const char *comp, const char *message, va_list va)
293{
294 char date[DATE_STR_SIZE];
295 time_t timetmp;
296 struct tm *tmptr;
297 size_t size;
298 char *buf;
299 va_list vacp;
300
301 if (skip_log > 0)
302 {
303 skip_log--;
304 return;
305 }
306 if ((kind & (~GNUNET_ERROR_TYPE_BULK)) > min_level)
307 return;
308 va_copy (vacp, va);
309 size = VSNPRINTF (NULL, 0, message, vacp) + 1;
310 va_end (vacp);
311 buf = malloc (size);
312 if (buf == NULL)
313 return; /* oops */
314 VSNPRINTF (buf, size, message, va);
315 time (&timetmp);
316 memset (date, 0, DATE_STR_SIZE);
317 tmptr = localtime (&timetmp);
318 strftime (date, DATE_STR_SIZE, "%b %d %H:%M:%S", tmptr);
319 if ((0 != (kind & GNUNET_ERROR_TYPE_BULK)) &&
320 (last_bulk_time.value != 0) &&
321 (0 == strncmp (buf, last_bulk, sizeof (last_bulk))))
322 {
323 last_bulk_repeat++;
324 if ((GNUNET_TIME_absolute_get_duration (last_bulk_time).value >
325 BULK_DELAY_THRESHOLD)
326 || (last_bulk_repeat > BULK_REPEAT_THRESHOLD))
327 flush_bulk (date);
328 free (buf);
329 return;
330 }
331 flush_bulk (date);
332 strncpy (last_bulk, buf, sizeof (last_bulk));
333 last_bulk_repeat = 0;
334 last_bulk_kind = kind;
335 last_bulk_time = GNUNET_TIME_absolute_get ();
336 last_bulk_comp = comp;
337 output_message (kind, comp, date, buf);
338 free (buf);
339}
340
341
342void
343GNUNET_log (enum GNUNET_ErrorType kind, const char *message, ...)
344{
345 va_list va;
346 va_start (va, message);
347 mylog (kind, component, message, va);
348 va_end (va);
349}
350
351
352void
353GNUNET_log_from (enum GNUNET_ErrorType kind,
354 const char *comp, const char *message, ...)
355{
356 va_list va;
357 va_start (va, message);
358 mylog (kind, comp, message, va);
359 va_end (va);
360}
361
362
363/**
364 * Convert KIND to String
365 */
366const char *
367GNUNET_error_type_to_string (enum GNUNET_ErrorType kind)
368{
369 if ((kind & GNUNET_ERROR_TYPE_ERROR) > 0)
370 return _("ERROR");
371 if ((kind & GNUNET_ERROR_TYPE_WARNING) > 0)
372 return _("WARNING");
373 if ((kind & GNUNET_ERROR_TYPE_INFO) > 0)
374 return _("INFO");
375 if ((kind & GNUNET_ERROR_TYPE_DEBUG) > 0)
376 return _("DEBUG");
377 return _("INVALID");
378}
379
380
381/**
382 * Convert a peer identity to a string (for printing debug messages).
383 * This is one of the very few calls in the entire API that is
384 * NOT reentrant!
385 *
386 * @param pid the peer identity
387 * @return string form of the pid; will be overwritten by next
388 * call to GNUNET_i2s.
389 */
390const char *
391GNUNET_i2s (const struct GNUNET_PeerIdentity *pid)
392{
393 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
394 GNUNET_CRYPTO_hash_to_enc (&pid->hashPubKey, &ret);
395 ret.encoding[4] = '\0';
396 return (const char *) ret.encoding;
397}
398
399
400
401/* end of common_logging.c */
diff --git a/src/util/configuration.c b/src/util/configuration.c
new file mode 100644
index 000000000..4413b0377
--- /dev/null
+++ b/src/util/configuration.c
@@ -0,0 +1,848 @@
1/*
2 This file is part of GNUnet.
3 (C) 2006, 2007, 2008, 2009 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 2, 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 src/util/configuration.c
23 * @brief configuration management
24 *
25 * @author Christian Grothoff
26 */
27
28#include "platform.h"
29#include "gnunet_common.h"
30#include "gnunet_configuration_lib.h"
31#include "gnunet_crypto_lib.h"
32#include "gnunet_disk_lib.h"
33#include "gnunet_os_lib.h"
34#include "gnunet_strings_lib.h"
35
36/**
37 * @brief configuration entry
38 */
39struct ConfigEntry
40{
41
42 /**
43 * This is a linked list.
44 */
45 struct ConfigEntry *next;
46
47 /**
48 * key for this entry
49 */
50 char *key;
51
52 /**
53 * current, commited value
54 */
55 char *val;
56};
57
58/**
59 * @brief configuration section
60 */
61struct ConfigSection
62{
63 /**
64 * This is a linked list.
65 */
66 struct ConfigSection *next;
67
68 /**
69 * entries in the section
70 */
71 struct ConfigEntry *entries;
72
73 /**
74 * name of the section
75 */
76 char *name;
77};
78
79/**
80 * @brief configuration data
81 */
82struct GNUNET_CONFIGURATION_Handle
83{
84 /**
85 * Configuration sections.
86 */
87 struct ConfigSection *sections;
88
89 /**
90 * Modification indication since last save
91 * GNUNET_NO if clean, GNUNET_YES if dirty,
92 * GNUNET_SYSERR on error (i.e. last save failed)
93 */
94 int dirty;
95
96};
97
98/**
99 * Create a GNUNET_CONFIGURATION_Configuration.
100 */
101struct GNUNET_CONFIGURATION_Handle *
102GNUNET_CONFIGURATION_create ()
103{
104 return GNUNET_malloc (sizeof (struct GNUNET_CONFIGURATION_Handle));
105}
106
107void
108GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg)
109{
110 struct ConfigSection *sec;
111 struct ConfigEntry *ent;
112
113 while (NULL != (sec = cfg->sections))
114 {
115 cfg->sections = sec->next;
116 while (NULL != (ent = sec->entries))
117 {
118 sec->entries = ent->next;
119 GNUNET_free (ent->key);
120 GNUNET_free_non_null (ent->val);
121 GNUNET_free (ent);
122 }
123 GNUNET_free (sec->name);
124 GNUNET_free (sec);
125 }
126 GNUNET_free (cfg);
127}
128
129int
130GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg,
131 const char *filename)
132{
133 int dirty;
134 char line[256];
135 char tag[64];
136 char value[192];
137 FILE *fp;
138 unsigned int nr;
139 int i;
140 int emptyline;
141 int ret;
142 char *section;
143 char *fn;
144
145 fn = GNUNET_STRINGS_filename_expand (filename);
146 dirty = cfg->dirty; /* back up value! */
147 if (NULL == (fp = FOPEN (fn, "r")))
148 {
149 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fopen", fn);
150 GNUNET_free (fn);
151 return GNUNET_SYSERR;
152 }
153 GNUNET_free (fn);
154 ret = GNUNET_OK;
155 section = GNUNET_strdup ("");
156 memset (line, 0, 256);
157 nr = 0;
158 while (NULL != fgets (line, 255, fp))
159 {
160 nr++;
161 for (i = 0; i < 255; i++)
162 if (line[i] == '\t')
163 line[i] = ' ';
164 if (line[0] == '\n' || line[0] == '#' || line[0] == '%' ||
165 line[0] == '\r')
166 continue;
167 emptyline = 1;
168 for (i = 0; (i < 255 && line[i] != 0); i++)
169 if (line[i] != ' ' && line[i] != '\n' && line[i] != '\r')
170 emptyline = 0;
171 if (emptyline == 1)
172 continue;
173 /* remove tailing whitespace */
174 for (i = strlen (line) - 1; (i >= 0) && (isspace (line[i])); i--)
175 line[i] = '\0';
176 if (1 == sscanf (line, "@INLINE@ %191[^\n]", value))
177 {
178 /* @INLINE@ value */
179 if (0 != GNUNET_CONFIGURATION_parse (cfg, value))
180 ret = GNUNET_SYSERR; /* failed to parse included config */
181 }
182 else if (1 == sscanf (line, "[%99[^]]]", value))
183 {
184 /* [value] */
185 GNUNET_free (section);
186 section = GNUNET_strdup (value);
187 }
188 else if (2 == sscanf (line, " %63[^= ] = %191[^\n]", tag, value))
189 {
190 /* tag = value */
191 /* Strip LF */
192 i = strlen (value) - 1;
193 while ((i >= 0) && (isspace (value[i])))
194 value[i--] = '\0';
195 /* remove quotes */
196 i = 0;
197 if (value[0] == '"')
198 {
199 i = 1;
200 while ((value[i] != '\0') && (value[i] != '"'))
201 i++;
202 if (value[i] == '"')
203 {
204 value[i] = '\0';
205 i = 1;
206 }
207 else
208 i = 0;
209 }
210 GNUNET_CONFIGURATION_set_value_string (cfg,
211 section, tag, &value[i]);
212 }
213 else if (1 == sscanf (line, " %63[^= ] =[^\n]", tag))
214 {
215 /* tag = */
216 GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, "");
217 }
218 else
219 {
220 /* parse error */
221 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
222 _
223 ("Syntax error in configuration file `%s' at line %u.\n"),
224 filename, nr);
225 ret = GNUNET_SYSERR;
226 break;
227 }
228 }
229 GNUNET_assert (0 == fclose (fp));
230 /* restore dirty flag - anything we set in the meantime
231 came from disk */
232 cfg->dirty = dirty;
233 GNUNET_free (section);
234 return ret;
235}
236
237int
238GNUNET_CONFIGURATION_test_dirty (struct GNUNET_CONFIGURATION_Handle *cfg)
239{
240 return cfg->dirty;
241}
242
243int
244GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *data,
245 const char *filename)
246{
247 struct ConfigSection *sec;
248 struct ConfigEntry *ent;
249 FILE *fp;
250 int error;
251 char *fn;
252 char *val;
253 char *pos;
254
255 fn = GNUNET_STRINGS_filename_expand (filename);
256 GNUNET_DISK_directory_create_for_file (fn);
257 if (NULL == (fp = FOPEN (fn, "w")))
258 {
259 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fopen", fn);
260 GNUNET_free (fn);
261 return GNUNET_SYSERR;
262 }
263 GNUNET_free (fn);
264 error = 0;
265 sec = data->sections;
266 while (sec != NULL)
267 {
268 if (0 > fprintf (fp, "[%s]\n", sec->name))
269 {
270 error = 1;
271 break;
272 }
273 ent = sec->entries;
274 while (ent != NULL)
275 {
276 if (ent->val != NULL)
277 {
278 val = GNUNET_malloc (strlen (ent->val) * 2 + 1);
279 strcpy (val, ent->val);
280 while (NULL != (pos = strstr (val, "\n")))
281 {
282 memmove (&pos[2], &pos[1], strlen (&pos[1]));
283 pos[0] = '\\';
284 pos[1] = 'n';
285 }
286 if (0 > fprintf (fp, "%s = %s\n", ent->key, val))
287 {
288 error = 1;
289 GNUNET_free (val);
290 break;
291 }
292 GNUNET_free (val);
293 }
294 ent = ent->next;
295 }
296 if (error != 0)
297 break;
298 if (0 > fprintf (fp, "\n"))
299 {
300 error = 1;
301 break;
302 }
303 sec = sec->next;
304 }
305 if (error != 0)
306 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fprintf", filename);
307 GNUNET_assert (0 == fclose (fp));
308 if (error != 0)
309 {
310 data->dirty = GNUNET_SYSERR; /* last write failed */
311 return GNUNET_SYSERR;
312 }
313 data->dirty = GNUNET_NO; /* last write succeeded */
314 return GNUNET_OK;
315}
316
317
318static struct ConfigSection *
319findSection (struct GNUNET_CONFIGURATION_Handle *data, const char *section)
320{
321 struct ConfigSection *pos;
322
323 pos = data->sections;
324 while ((pos != NULL) && (0 != strcasecmp (section, pos->name)))
325 pos = pos->next;
326 return pos;
327}
328
329
330static struct ConfigEntry *
331findEntry (struct GNUNET_CONFIGURATION_Handle *data,
332 const char *section, const char *key)
333{
334 struct ConfigSection *sec;
335 struct ConfigEntry *pos;
336
337 sec = findSection (data, section);
338 if (sec == NULL)
339 return NULL;
340 pos = sec->entries;
341 while ((pos != NULL) && (0 != strcasecmp (key, pos->key)))
342 pos = pos->next;
343 return pos;
344}
345
346void
347GNUNET_CONFIGURATION_set_value_string (struct GNUNET_CONFIGURATION_Handle
348 *data,
349 const char *section,
350 const char *option, const char *value)
351{
352 struct ConfigSection *sec;
353 struct ConfigEntry *e;
354
355 e = findEntry (data, section, option);
356 if (e != NULL)
357 {
358 GNUNET_free_non_null (e->val);
359 e->val = GNUNET_strdup (value);
360 return;
361 }
362 sec = findSection (data, section);
363 if (sec == NULL)
364 {
365 sec = GNUNET_malloc (sizeof (struct ConfigSection));
366 sec->name = GNUNET_strdup (section);
367 sec->next = data->sections;
368 data->sections = sec;
369 }
370 e = GNUNET_malloc (sizeof (struct ConfigEntry));
371 e->key = GNUNET_strdup (option);
372 e->val = GNUNET_strdup (value);
373 e->next = sec->entries;
374 sec->entries = e;
375}
376
377void
378GNUNET_CONFIGURATION_set_value_number (struct GNUNET_CONFIGURATION_Handle
379 *cfg, const char *section,
380 const char *option,
381 unsigned long long number)
382{
383 char s[64];
384 GNUNET_snprintf (s, 64, "%llu", number);
385 GNUNET_CONFIGURATION_set_value_string (cfg, section, option, s);
386}
387
388int
389GNUNET_CONFIGURATION_get_value_number (struct GNUNET_CONFIGURATION_Handle
390 *cfg, const char *section,
391 const char *option,
392 unsigned long long *number)
393{
394 struct ConfigEntry *e;
395
396 e = findEntry (cfg, section, option);
397 if (e == NULL)
398 return GNUNET_SYSERR;
399 if (1 != SSCANF (e->val, "%llu", number))
400 return GNUNET_SYSERR;
401 return GNUNET_OK;
402}
403
404int
405GNUNET_CONFIGURATION_get_value_string (struct GNUNET_CONFIGURATION_Handle
406 *cfg, const char *section,
407 const char *option, char **value)
408{
409 struct ConfigEntry *e;
410
411 e = findEntry (cfg, section, option);
412 if ((e == NULL) || (e->val == NULL))
413 {
414 *value = NULL;
415 return GNUNET_SYSERR;
416 }
417 *value = GNUNET_strdup (e->val);
418 return GNUNET_OK;
419}
420
421int
422GNUNET_CONFIGURATION_get_value_choice (struct GNUNET_CONFIGURATION_Handle
423 *cfg, const char *section,
424 const char *option,
425 const char **choices,
426 const char **value)
427{
428 struct ConfigEntry *e;
429 int i;
430
431 e = findEntry (cfg, section, option);
432 if (e == NULL)
433 return GNUNET_SYSERR;
434 i = 0;
435 while (choices[i] != NULL)
436 {
437 if (0 == strcasecmp (choices[i], e->val))
438 break;
439 i++;
440 }
441 if (choices[i] == NULL)
442 {
443 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
444 _("Configuration value '%s' for '%s'"
445 " in section '%s' is not in set of legal choices\n"),
446 e->val, option, section);
447 return GNUNET_SYSERR;
448 }
449 *value = choices[i];
450 return GNUNET_OK;
451}
452
453/**
454 * Test if we have a value for a particular option
455 * @return GNUNET_YES if so, GNUNET_NO if not.
456 */
457int
458GNUNET_CONFIGURATION_have_value (struct GNUNET_CONFIGURATION_Handle *cfg,
459 const char *section, const char *option)
460{
461 struct ConfigEntry *e;
462 if ((NULL == (e = findEntry (cfg, section, option))) || (e->val == NULL))
463 return GNUNET_NO;
464 return GNUNET_YES;
465}
466
467/**
468 * Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR"
469 * where either in the "PATHS" section or the environtment
470 * "FOO" is set to "DIRECTORY".
471 *
472 * @param old string to $-expand (will be freed!)
473 * @return $-expanded string
474 */
475char *
476GNUNET_CONFIGURATION_expand_dollar (struct GNUNET_CONFIGURATION_Handle *cfg,
477 char *orig)
478{
479 int i;
480 char *prefix;
481 char *result;
482 const char *post;
483 const char *env;
484
485 if (orig[0] != '$')
486 return orig;
487 i = 0;
488 while ((orig[i] != '/') && (orig[i] != '\\') && (orig[i] != '\0'))
489 i++;
490 if (orig[i] == '\0')
491 {
492 post = "";
493 }
494 else
495 {
496 orig[i] = '\0';
497 post = &orig[i + 1];
498 }
499 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
500 "PATHS",
501 &orig[1], &prefix))
502 {
503 if (NULL == (env = getenv (&orig[1])))
504 {
505 orig[i] = DIR_SEPARATOR;
506 return orig;
507 }
508 prefix = GNUNET_strdup (env);
509 }
510 result = GNUNET_malloc (strlen (prefix) + strlen (post) + 2);
511 strcpy (result, prefix);
512 if ((strlen (prefix) == 0) ||
513 ((prefix[strlen (prefix) - 1] != DIR_SEPARATOR) && (strlen (post) > 0)))
514 strcat (result, DIR_SEPARATOR_STR);
515 strcat (result, post);
516 GNUNET_free (prefix);
517 GNUNET_free (orig);
518 return result;
519}
520
521/**
522 * Get a configuration value that should be a string.
523 * @param value will be set to a freshly allocated configuration
524 * value, or NULL if option is not specified
525 * @return GNUNET_OK on success, GNUNET_SYSERR on error
526 */
527int
528GNUNET_CONFIGURATION_get_value_filename (struct GNUNET_CONFIGURATION_Handle
529 *data, const char *section,
530 const char *option, char **value)
531{
532 int ret;
533 char *tmp;
534
535 tmp = NULL;
536 ret = GNUNET_CONFIGURATION_get_value_string (data, section, option, &tmp);
537 if (ret == GNUNET_SYSERR)
538 return ret;
539 if (tmp != NULL)
540 {
541 tmp = GNUNET_CONFIGURATION_expand_dollar (data, tmp);
542 *value = GNUNET_STRINGS_filename_expand (tmp);
543 GNUNET_free (tmp);
544 }
545 else
546 {
547 *value = NULL;
548 }
549 return ret;
550}
551
552/**
553 * Get a configuration value that should be in a set of
554 * "GNUNET_YES" or "GNUNET_NO".
555 *
556 * @return GNUNET_YES, GNUNET_NO or GNUNET_SYSERR
557 */
558int
559GNUNET_CONFIGURATION_get_value_yesno (struct GNUNET_CONFIGURATION_Handle *cfg,
560 const char *section, const char *option)
561{
562 static const char *yesno[] = { "YES", "NO", NULL };
563 const char *val;
564 int ret;
565
566 ret = GNUNET_CONFIGURATION_get_value_choice (cfg,
567 section, option, yesno, &val);
568 if (ret == GNUNET_SYSERR)
569 return ret;
570 if (val == yesno[0])
571 return GNUNET_YES;
572 return GNUNET_NO;
573}
574
575
576/**
577 * Iterate over the set of filenames stored in a configuration value.
578 *
579 * @return number of filenames iterated over, -1 on error
580 */
581int
582GNUNET_CONFIGURATION_iterate_value_filenames (struct
583 GNUNET_CONFIGURATION_Handle
584 *cfg, const char *section,
585 const char *option,
586 GNUNET_FileNameCallback cb,
587 void *cls)
588{
589 char *list;
590 char *pos;
591 char *end;
592 char old;
593 int ret;
594
595 if (GNUNET_OK !=
596 GNUNET_CONFIGURATION_get_value_string (cfg, section, option, &list))
597 return 0;
598 GNUNET_assert (list != NULL);
599 ret = 0;
600 pos = list;
601 while (1)
602 {
603 while (pos[0] == ' ')
604 pos++;
605 if (strlen (pos) == 0)
606 break;
607 end = pos + 1;
608 while ((end[0] != ' ') && (end[0] != '\0'))
609 {
610 if (end[0] == '\\')
611 {
612 switch (end[1])
613 {
614 case '\\':
615 case ' ':
616 memmove (end, &end[1], strlen (&end[1]) + 1);
617 case '\0':
618 /* illegal, but just keep it */
619 break;
620 default:
621 /* illegal, but just ignore that there was a '/' */
622 break;
623 }
624 }
625 end++;
626 }
627 old = end[0];
628 end[0] = '\0';
629 if (strlen (pos) > 0)
630 {
631 ret++;
632 if ((cb != NULL) && (GNUNET_OK != cb (cls, pos)))
633 {
634 ret = GNUNET_SYSERR;
635 break;
636 }
637 }
638 if (old == '\0')
639 break;
640 pos = end + 1;
641 }
642 GNUNET_free (list);
643 return ret;
644}
645
646static char *
647escape_name (const char *value)
648{
649 char *escaped;
650 const char *rpos;
651 char *wpos;
652
653 escaped = GNUNET_malloc (strlen (value) * 2 + 1);
654 memset (escaped, 0, strlen (value) * 2 + 1);
655 rpos = value;
656 wpos = escaped;
657 while (rpos[0] != '\0')
658 {
659 switch (rpos[0])
660 {
661 case '\\':
662 case ' ':
663 wpos[0] = '\\';
664 wpos[1] = rpos[0];
665 wpos += 2;
666 break;
667 default:
668 wpos[0] = rpos[0];
669 wpos++;
670 }
671 rpos++;
672 }
673 return escaped;
674}
675
676static int
677test_match (void *cls, const char *fn)
678{
679 const char *of = cls;
680 return (0 == strcmp (of, fn)) ? GNUNET_SYSERR : GNUNET_OK;
681}
682
683/**
684 * Append a filename to a configuration value that
685 * represents a list of filenames
686 *
687 * @param value filename to append
688 * @return GNUNET_OK on success,
689 * GNUNET_NO if the filename already in the list
690 * GNUNET_SYSERR on error
691 */
692int
693GNUNET_CONFIGURATION_append_value_filename (struct GNUNET_CONFIGURATION_Handle
694 *cfg,
695 const char *section,
696 const char *option,
697 const char *value)
698{
699 char *escaped;
700 char *old;
701 char *nw;
702
703 if (GNUNET_SYSERR
704 == GNUNET_CONFIGURATION_iterate_value_filenames (cfg,
705 section,
706 option,
707 &test_match,
708 (void *) value))
709 return GNUNET_NO; /* already exists */
710 if (GNUNET_OK !=
711 GNUNET_CONFIGURATION_get_value_string (cfg, section, option, &old))
712 old = GNUNET_strdup ("");
713 escaped = escape_name (value);
714 nw = GNUNET_malloc (strlen (old) + strlen (escaped) + 2);
715 strcpy (nw, old);
716 strcat (nw, " ");
717 strcat (nw, escaped);
718 GNUNET_CONFIGURATION_set_value_string (cfg, section, option, nw);
719 GNUNET_free (old);
720 GNUNET_free (nw);
721 GNUNET_free (escaped);
722 return GNUNET_OK;
723}
724
725
726/**
727 * Remove a filename from a configuration value that
728 * represents a list of filenames
729 *
730 * @param value filename to remove
731 * @return GNUNET_OK on success,
732 * GNUNET_NO if the filename is not in the list,
733 * GNUNET_SYSERR on error
734 */
735int
736GNUNET_CONFIGURATION_remove_value_filename (struct GNUNET_CONFIGURATION_Handle
737 *cfg,
738 const char *section,
739 const char *option,
740 const char *value)
741{
742 char *list;
743 char *pos;
744 char *end;
745 char *match;
746 char old;
747 int ret;
748
749 if (GNUNET_OK !=
750 GNUNET_CONFIGURATION_get_value_string (cfg, section, option, &list))
751 return GNUNET_NO;
752 match = escape_name (value);
753 ret = 0;
754 pos = list;
755 while (1)
756 {
757 while (pos[0] == ' ')
758 pos++;
759 if (strlen (pos) == 0)
760 break;
761 end = pos + 1;
762 while ((end[0] != ' ') && (end[0] != '\0'))
763 {
764 if (end[0] == '\\')
765 {
766 switch (end[1])
767 {
768 case '\\':
769 case ' ':
770 end++;
771 break;
772 case '\0':
773 /* illegal, but just keep it */
774 break;
775 default:
776 /* illegal, but just ignore that there was a '/' */
777 break;
778 }
779 }
780 end++;
781 }
782 old = end[0];
783 end[0] = '\0';
784 if (strlen (pos) > 0)
785 {
786 if (0 == strcmp (pos, match))
787 {
788 memmove (pos, &end[1], strlen (&end[1]) + 1);
789
790 if (pos != list)
791 pos[-1] = ' '; /* previously changed to "\0" */
792 GNUNET_CONFIGURATION_set_value_string (cfg,
793 section, option, list);
794 GNUNET_free (list);
795 GNUNET_free (match);
796 return GNUNET_OK;
797 }
798 }
799 if (old == '\0')
800 break;
801 pos = end + 1;
802 }
803 GNUNET_free (list);
804 GNUNET_free (match);
805 return GNUNET_NO;
806}
807
808
809/**
810 * Load configuration (starts with defaults, then loads
811 * system-specific configuration).
812 */
813int
814GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg,
815 const char *cfgfn)
816{
817 char *baseconfig;
818 char *ipath;
819
820 ipath = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
821 if (ipath == NULL)
822 return GNUNET_SYSERR;
823 baseconfig = NULL;
824 GNUNET_asprintf (&baseconfig,
825 "%s%s%s", ipath, DIR_SEPARATOR_STR, "defaults.conf");
826 GNUNET_free (ipath);
827 if ((GNUNET_OK !=
828 GNUNET_CONFIGURATION_parse (cfg, baseconfig)) ||
829 (!((cfgfn == NULL) ||
830 (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, cfgfn)))))
831 {
832 GNUNET_free (baseconfig);
833 return GNUNET_SYSERR;
834 }
835 GNUNET_free (baseconfig);
836 if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg,
837 "TESTING",
838 "WEAKRANDOM")) &&
839 (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (cfg,
840 "TESTING",
841 "WEAKRANDOM")))
842 GNUNET_CRYPTO_random_disable_entropy_gathering ();
843 return GNUNET_OK;
844}
845
846
847
848/* end of configuration.c */
diff --git a/src/util/container_bloomfilter.c b/src/util/container_bloomfilter.c
new file mode 100644
index 000000000..8b76ef8dc
--- /dev/null
+++ b/src/util/container_bloomfilter.c
@@ -0,0 +1,677 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2006, 2008 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 2, 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 util/container_bloomfilter.c
22 * @brief data structure used to reduce disk accesses.
23 *
24 * The idea basically: Create a signature for each element in the
25 * database. Add those signatures to a bit array. When doing a lookup,
26 * check if the bit array matches the signature of the requested
27 * element. If yes, address the disk, otherwise return 'not found'.
28 *
29 * A property of the bloom filter is that sometimes we will have
30 * a match even if the element is not on the disk (then we do
31 * an unnecessary disk access), but what's most important is that
32 * we never get a single "false negative".
33 *
34 * To be able to delete entries from the bloom filter, we maintain
35 * a 4 bit counter in the file on the drive (we still use only one
36 * bit in memory).
37 *
38 * @author Igor Wronsky
39 * @author Christian Grothoff
40 */
41
42#include "platform.h"
43#include "gnunet_common.h"
44#include "gnunet_container_lib.h"
45#include "gnunet_disk_lib.h"
46
47struct GNUNET_CONTAINER_BloomFilter
48{
49
50 /**
51 * The actual bloomfilter bit array
52 */
53 char *bitArray;
54
55 /**
56 * Filename of the filter
57 */
58 char *filename;
59
60 /**
61 * The bit counter file on disk
62 */
63 int fd;
64
65 /**
66 * How many bits we set for each stored element
67 */
68 unsigned int addressesPerElement;
69
70 /**
71 * Size of bitArray in bytes
72 */
73 unsigned int bitArraySize;
74
75};
76
77
78/**
79 * Sets a bit active in the bitArray. Increment bit-specific
80 * usage counter on disk only if below 4bit max (==15).
81 *
82 * @param bitArray memory area to set the bit in
83 * @param bitIdx which bit to set
84 */
85static void
86setBit (char *bitArray, unsigned int bitIdx)
87{
88 unsigned int arraySlot;
89 unsigned int targetBit;
90
91 arraySlot = bitIdx / 8;
92 targetBit = (1L << (bitIdx % 8));
93 bitArray[arraySlot] |= targetBit;
94}
95
96/**
97 * Clears a bit from bitArray. Bit is cleared from the array
98 * only if the respective usage counter on the disk hits/is zero.
99 *
100 * @param bitArray memory area to set the bit in
101 * @param bitIdx which bit to unset
102 */
103static void
104clearBit (char *bitArray, unsigned int bitIdx)
105{
106 unsigned int slot;
107 unsigned int targetBit;
108
109 slot = bitIdx / 8;
110 targetBit = (1L << (bitIdx % 8));
111 bitArray[slot] = bitArray[slot] & (~targetBit);
112}
113
114/**
115 * Checks if a bit is active in the bitArray
116 *
117 * @param bitArray memory area to set the bit in
118 * @param bitIdx which bit to test
119 * @return GNUNET_YES if the bit is set, GNUNET_NO if not.
120 */
121static int
122testBit (char *bitArray, unsigned int bitIdx)
123{
124 unsigned int slot;
125 unsigned int targetBit;
126
127 slot = bitIdx / 8;
128 targetBit = (1L << (bitIdx % 8));
129 if (bitArray[slot] & targetBit)
130 return GNUNET_YES;
131 else
132 return GNUNET_NO;
133}
134
135/**
136 * Sets a bit active in the bitArray and increments
137 * bit-specific usage counter on disk (but only if
138 * the counter was below 4 bit max (==15)).
139 *
140 * @param bitArray memory area to set the bit in
141 * @param bitIdx which bit to test
142 * @param fd A file to keep the 4 bit address usage counters in
143 */
144static void
145incrementBit (char *bitArray, unsigned int bitIdx, int fd)
146{
147 unsigned int fileSlot;
148 unsigned char value;
149 unsigned int high;
150 unsigned int low;
151 unsigned int targetLoc;
152
153 setBit (bitArray, bitIdx);
154 if (fd == -1)
155 return;
156 /* Update the counter file on disk */
157 fileSlot = bitIdx / 2;
158 targetLoc = bitIdx % 2;
159
160 GNUNET_assert (fileSlot == (unsigned int) LSEEK (fd, fileSlot, SEEK_SET));
161 if (1 != READ (fd, &value, 1))
162 value = 0;
163 low = value & 0xF;
164 high = (value & (~0xF)) >> 4;
165
166 if (targetLoc == 0)
167 {
168 if (low < 0xF)
169 low++;
170 }
171 else
172 {
173 if (high < 0xF)
174 high++;
175 }
176 value = ((high << 4) | low);
177 GNUNET_assert (fileSlot == (unsigned int) LSEEK (fd, fileSlot, SEEK_SET));
178 GNUNET_assert (1 == WRITE (fd, &value, 1));
179}
180
181/**
182 * Clears a bit from bitArray if the respective usage
183 * counter on the disk hits/is zero.
184 *
185 * @param bitArray memory area to set the bit in
186 * @param bitIdx which bit to test
187 * @param fd A file to keep the 4bit address usage counters in
188 */
189static void
190decrementBit (char *bitArray, unsigned int bitIdx, int fd)
191{
192 unsigned int fileSlot;
193 unsigned char value;
194 unsigned int high;
195 unsigned int low;
196 unsigned int targetLoc;
197
198 if (fd == -1)
199 return; /* cannot decrement! */
200 /* Each char slot in the counter file holds two 4 bit counters */
201 fileSlot = bitIdx / 2;
202 targetLoc = bitIdx % 2;
203 LSEEK (fd, fileSlot, SEEK_SET);
204 if (1 != READ (fd, &value, 1))
205 value = 0;
206 low = value & 0xF;
207 high = (value & 0xF0) >> 4;
208
209 /* decrement, but once we have reached the max, never go back! */
210 if (targetLoc == 0)
211 {
212 if ((low > 0) && (low < 0xF))
213 low--;
214 if (low == 0)
215 {
216 clearBit (bitArray, bitIdx);
217 }
218 }
219 else
220 {
221 if ((high > 0) && (high < 0xF))
222 high--;
223 if (high == 0)
224 {
225 clearBit (bitArray, bitIdx);
226 }
227 }
228 value = ((high << 4) | low);
229 LSEEK (fd, fileSlot, SEEK_SET);
230 GNUNET_assert (1 == WRITE (fd, &value, 1));
231}
232
233#define BUFFSIZE 65536
234
235/**
236 * Creates a file filled with zeroes
237 *
238 * @param fd the file handle
239 * @param size the size of the file
240 * @return GNUNET_OK if created ok, GNUNET_SYSERR otherwise
241 */
242static int
243makeEmptyFile (int fd, unsigned int size)
244{
245 char *buffer;
246 unsigned int bytesleft = size;
247 int res = 0;
248
249 if (fd == -1)
250 return GNUNET_SYSERR;
251 buffer = GNUNET_malloc (BUFFSIZE);
252 memset (buffer, 0, BUFFSIZE);
253 LSEEK (fd, 0, SEEK_SET);
254
255 while (bytesleft > 0)
256 {
257 if (bytesleft > BUFFSIZE)
258 {
259 res = WRITE (fd, buffer, BUFFSIZE);
260 bytesleft -= BUFFSIZE;
261 }
262 else
263 {
264 res = WRITE (fd, buffer, bytesleft);
265 bytesleft = 0;
266 }
267 GNUNET_assert (res != -1);
268 }
269 GNUNET_free (buffer);
270 return GNUNET_OK;
271}
272
273/* ************** GNUNET_CONTAINER_BloomFilter GNUNET_CRYPTO_hash iterator ********* */
274
275/**
276 * Iterator (callback) method to be called by the
277 * bloomfilter iterator on each bit that is to be
278 * set or tested for the key.
279 *
280 * @param bf the filter to manipulate
281 * @param bit the current bit
282 * @param additional context specific argument
283 */
284typedef void (*BitIterator) (struct GNUNET_CONTAINER_BloomFilter * bf,
285 unsigned int bit, void *arg);
286
287/**
288 * Call an iterator for each bit that the bloomfilter
289 * must test or set for this element.
290 *
291 * @param bf the filter
292 * @param callback the method to call
293 * @param arg extra argument to callback
294 * @param key the key for which we iterate over the BF bits
295 */
296static void
297iterateBits (struct GNUNET_CONTAINER_BloomFilter *bf,
298 BitIterator callback, void *arg, const GNUNET_HashCode * key)
299{
300 GNUNET_HashCode tmp[2];
301 int bitCount;
302 int round;
303 unsigned int slot = 0;
304
305 bitCount = bf->addressesPerElement;
306 memcpy (&tmp[0], key, sizeof (GNUNET_HashCode));
307 round = 0;
308 while (bitCount > 0)
309 {
310 while (slot < (sizeof (GNUNET_HashCode) / sizeof (unsigned int)))
311 {
312 callback (bf,
313 (((unsigned int *) &tmp[round & 1])[slot]) &
314 ((bf->bitArraySize * 8) - 1), arg);
315 slot++;
316 bitCount--;
317 if (bitCount == 0)
318 break;
319 }
320 if (bitCount > 0)
321 {
322 GNUNET_CRYPTO_hash (&tmp[round & 1], sizeof (GNUNET_HashCode),
323 &tmp[(round + 1) & 1]);
324 round++;
325 slot = 0;
326 }
327 }
328}
329
330/**
331 * Callback: increment bit
332 *
333 * @param bf the filter to manipulate
334 * @param bit the bit to increment
335 * @param arg not used
336 */
337static void
338incrementBitCallback (struct GNUNET_CONTAINER_BloomFilter *bf,
339 unsigned int bit, void *arg)
340{
341 incrementBit (bf->bitArray, bit, bf->fd);
342}
343
344/**
345 * Callback: decrement bit
346 *
347 * @param bf the filter to manipulate
348 * @param bit the bit to decrement
349 * @param arg not used
350 */
351static void
352decrementBitCallback (struct GNUNET_CONTAINER_BloomFilter *bf,
353 unsigned int bit, void *arg)
354{
355 decrementBit (bf->bitArray, bit, bf->fd);
356}
357
358/**
359 * Callback: test if all bits are set
360 *
361 * @param bf the filter
362 * @param bit the bit to test
363 * @param arg pointer set to GNUNET_NO if bit is not set
364 */
365static void
366testBitCallback (struct GNUNET_CONTAINER_BloomFilter *bf, unsigned int bit,
367 void *cls)
368{
369 int *arg = cls;
370 if (GNUNET_NO == testBit (bf->bitArray, bit))
371 *arg = GNUNET_NO;
372}
373
374/* *********************** INTERFACE **************** */
375
376/**
377 * Load a bloom-filter from a file.
378 *
379 * @param filename the name of the file (or the prefix)
380 * @param size the size of the bloom-filter (number of
381 * bytes of storage space to use)
382 * @param k the number of GNUNET_CRYPTO_hash-functions to apply per
383 * element (number of bits set per element in the set)
384 * @return the bloomfilter
385 */
386struct GNUNET_CONTAINER_BloomFilter *
387GNUNET_CONTAINER_bloomfilter_load (const char *filename, unsigned int size,
388 unsigned int k)
389{
390 struct GNUNET_CONTAINER_BloomFilter *bf;
391 char *rbuff;
392 unsigned int pos;
393 int i;
394 unsigned int ui;
395
396 if ((k == 0) || (size == 0))
397 return NULL;
398 if (size < BUFFSIZE)
399 size = BUFFSIZE;
400 ui = 1;
401 while (ui < size)
402 ui *= 2;
403 size = ui; /* make sure it's a power of 2 */
404
405 bf = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_BloomFilter));
406 /* Try to open a bloomfilter file */
407 if (filename != NULL)
408 {
409#ifndef _MSC_VER
410 bf->fd = GNUNET_DISK_file_open (filename, O_RDWR | O_CREAT,
411 S_IRUSR | S_IWUSR);
412#else
413 bf->fd = GNUNET_DISK_file_open (filename,
414 O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
415#endif
416 if (-1 == bf->fd)
417 {
418 GNUNET_free (bf);
419 return NULL;
420 }
421 bf->filename = GNUNET_strdup (filename);
422 }
423 else
424 {
425 bf->fd = -1;
426 bf->filename = NULL;
427 }
428 /* Alloc block */
429 bf->bitArray = GNUNET_malloc_large (size);
430 bf->bitArraySize = size;
431 bf->addressesPerElement = k;
432 memset (bf->bitArray, 0, bf->bitArraySize);
433
434 if (bf->fd != -1)
435 {
436 /* Read from the file what bits we can */
437 rbuff = GNUNET_malloc (BUFFSIZE);
438 pos = 0;
439 while (pos < size * 8)
440 {
441 int res;
442
443 res = READ (bf->fd, rbuff, BUFFSIZE);
444 if (res == 0)
445 break; /* is ok! we just did not use that many bits yet */
446 for (i = 0; i < res; i++)
447 {
448 if ((rbuff[i] & 0x0F) != 0)
449 setBit (bf->bitArray, pos + i * 2);
450 if ((rbuff[i] & 0xF0) != 0)
451 setBit (bf->bitArray, pos + i * 2 + 1);
452 }
453 if (res < BUFFSIZE)
454 break;
455 pos += BUFFSIZE * 2; /* 2 bits per byte in the buffer */
456 }
457 GNUNET_free (rbuff);
458 }
459 return bf;
460}
461
462
463/**
464 * Create a bloom filter from raw bits.
465 *
466 * @param data the raw bits in memory (maybe NULL,
467 * in which case all bits should be considered
468 * to be zero).
469 * @param size the size of the bloom-filter (number of
470 * bytes of storage space to use); also size of data
471 * -- unless data is NULL
472 * @param k the number of GNUNET_CRYPTO_hash-functions to apply per
473 * element (number of bits set per element in the set)
474 * @return the bloomfilter
475 */
476struct GNUNET_CONTAINER_BloomFilter *
477GNUNET_CONTAINER_bloomfilter_init (const char *data, unsigned int size,
478 unsigned int k)
479{
480 struct GNUNET_CONTAINER_BloomFilter *bf;
481 unsigned int ui;
482
483 if ((k == 0) || (size == 0))
484 return NULL;
485 ui = 1;
486 while (ui < size)
487 ui *= 2;
488 if (size != ui)
489 {
490 GNUNET_break (0);
491 return NULL;
492 }
493 bf = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_BloomFilter));
494 bf->fd = -1;
495 bf->filename = NULL;
496 bf->bitArray = GNUNET_malloc_large (size);
497 bf->bitArraySize = size;
498 bf->addressesPerElement = k;
499 if (data != NULL)
500 memcpy (bf->bitArray, data, size);
501 else
502 memset (bf->bitArray, 0, bf->bitArraySize);
503 return bf;
504}
505
506
507/**
508 * Copy the raw data of this bloomfilter into
509 * the given data array.
510 *
511 * @param data where to write the data
512 * @param size the size of the given data array
513 * @return GNUNET_SYSERR if the data array is not big enough
514 */
515int
516GNUNET_CONTAINER_bloomfilter_get_raw_data (struct GNUNET_CONTAINER_BloomFilter
517 *bf, char *data, unsigned int size)
518{
519 if (NULL == bf)
520 return GNUNET_SYSERR;
521
522 if (bf->bitArraySize != size)
523 return GNUNET_SYSERR;
524 memcpy (data, bf->bitArray, size);
525 return GNUNET_OK;
526}
527
528/**
529 * Free the space associated with a filter
530 * in memory, flush to drive if needed (do not
531 * free the space on the drive)
532 *
533 * @param bf the filter
534 */
535void
536GNUNET_CONTAINER_bloomfilter_free (struct GNUNET_CONTAINER_BloomFilter *bf)
537{
538 if (NULL == bf)
539 return;
540 if (bf->fd != -1)
541 GNUNET_DISK_file_close (bf->filename, bf->fd);
542 GNUNET_free_non_null (bf->filename);
543 GNUNET_free (bf->bitArray);
544 GNUNET_free (bf);
545}
546
547/**
548 * Reset a bloom filter to empty. Clears the file on disk.
549 *
550 * @param bf the filter
551 */
552void
553GNUNET_CONTAINER_bloomfilter_clear (struct GNUNET_CONTAINER_BloomFilter *bf)
554{
555 if (NULL == bf)
556 return;
557
558 memset (bf->bitArray, 0, bf->bitArraySize);
559 if (bf->fd != -1)
560 makeEmptyFile (bf->fd, bf->bitArraySize * 4);
561}
562
563
564/**
565 * Test if an element is in the filter.
566 *
567 * @param e the element
568 * @param bf the filter
569 * @return GNUNET_YES if the element is in the filter, GNUNET_NO if not
570 */
571int
572GNUNET_CONTAINER_bloomfilter_test (struct GNUNET_CONTAINER_BloomFilter *bf,
573 const GNUNET_HashCode * e)
574{
575 int res;
576
577 if (NULL == bf)
578 return GNUNET_YES;
579 res = GNUNET_YES;
580 iterateBits (bf, &testBitCallback, &res, e);
581 return res;
582}
583
584/**
585 * Add an element to the filter
586 *
587 * @param bf the filter
588 * @param e the element
589 */
590void
591GNUNET_CONTAINER_bloomfilter_add (struct GNUNET_CONTAINER_BloomFilter *bf,
592 const GNUNET_HashCode * e)
593{
594
595 if (NULL == bf)
596 return;
597 iterateBits (bf, &incrementBitCallback, NULL, e);
598}
599
600
601/**
602 * Or the entries of the given raw data array with the
603 * data of the given bloom filter. Assumes that
604 * the size of the data array and the current filter
605 * match.
606 * @param bf the filter
607 */
608int
609GNUNET_CONTAINER_bloomfilter_or (struct GNUNET_CONTAINER_BloomFilter *bf,
610 const char *data, unsigned int size)
611{
612 unsigned int i;
613
614 if (NULL == bf)
615 return GNUNET_YES;
616 if (bf->bitArraySize != size)
617 return GNUNET_SYSERR;
618 /* FIXME: we could do this 4-8x faster by
619 going over int/long arrays */
620 for (i = 0; i < size; i++)
621 bf->bitArray[i] |= data[i];
622 return GNUNET_OK;
623}
624
625/**
626 * Remove an element from the filter.
627 *
628 * @param bf the filter
629 * @param e the element to remove
630 */
631void
632GNUNET_CONTAINER_bloomfilter_remove (struct GNUNET_CONTAINER_BloomFilter *bf,
633 const GNUNET_HashCode * e)
634{
635 if (NULL == bf)
636 return;
637 if (bf->fd == -1)
638 return;
639 iterateBits (bf, &decrementBitCallback, NULL, e);
640}
641
642/**
643 * Resize a bloom filter. Note that this operation
644 * is pretty costly. Essentially, the bloom filter
645 * needs to be completely re-build.
646 *
647 * @param bf the filter
648 * @param iterator an iterator over all elements stored in the BF
649 * @param iterator_arg argument to the iterator function
650 * @param size the new size for the filter
651 * @param k the new number of GNUNET_CRYPTO_hash-function to apply per element
652 */
653void
654GNUNET_CONTAINER_bloomfilter_resize (struct GNUNET_CONTAINER_BloomFilter *bf,
655 GNUNET_HashCodeIterator iterator,
656 void *iterator_arg, unsigned int size,
657 unsigned int k)
658{
659 GNUNET_HashCode hc;
660 unsigned int i;
661
662 GNUNET_free (bf->bitArray);
663 i = 1;
664 while (i < size)
665 i *= 2;
666 size = i; /* make sure it's a power of 2 */
667
668 bf->bitArraySize = size;
669 bf->bitArray = GNUNET_malloc (size);
670 memset (bf->bitArray, 0, bf->bitArraySize);
671 if (bf->fd != -1)
672 makeEmptyFile (bf->fd, bf->bitArraySize * 4);
673 while (GNUNET_YES == iterator (&hc, iterator_arg))
674 GNUNET_CONTAINER_bloomfilter_add (bf, &hc);
675}
676
677/* end of container_bloomfilter.c */
diff --git a/src/util/container_heap.c b/src/util/container_heap.c
new file mode 100644
index 000000000..1e7077c80
--- /dev/null
+++ b/src/util/container_heap.c
@@ -0,0 +1,533 @@
1/*
2 This file is part of GNUnet.
3 (C) 2008 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 2, 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 * @author Nathan Evans
23 * @file util/container_heap.c
24 * @brief Implementation of heap operations
25 */
26
27#include "platform.h"
28#include "gnunet_protocols.h"
29#include "gnunet_util.h"
30#include "gnunet_util_containers.h"
31
32/*
33 * Struct that is stored in hashmap, pointers to
34 * locations in min_heap and max_heap.
35 */
36struct GNUNET_CONTAINER_heap_info
37{
38 struct GNUNET_CONTAINER_heap_node *min_loc;
39
40 struct GNUNET_CONTAINER_heap_node *max_loc;
41
42};
43
44/*
45 * Generic heap node structure, contains pointer to parent
46 * left child, right child, and actual neighbor.
47 */
48struct GNUNET_CONTAINER_heap_node
49{
50 struct GNUNET_CONTAINER_heap_node *parent;
51
52 struct GNUNET_CONTAINER_heap_node *left_child;
53
54 struct GNUNET_CONTAINER_heap_node *right_child;
55
56 GNUNET_CONTAINER_HeapCost cost;
57
58 void *element;
59
60};
61
62struct GNUNET_CONTAINER_Heap
63{
64 unsigned int size;
65
66 unsigned int max_size;
67
68 enum type;
69
70 struct GNUNET_CONTAINER_heap_node *root;
71
72 struct GNUNET_CONTAINER_heap_node *traversal_pos;
73
74};
75
76void
77internal_print (struct GNUNET_CONTAINER_heap_node *root)
78{
79 fprintf (stdout, "%d\n", root->cost);
80 if (root->left_child != NULL)
81 {
82 fprintf (stdout, "LEFT of %d\n", root->cost);
83 internal_print (root->left_child);
84 }
85 if (root->right_child != NULL)
86 {
87 fprintf (stdout, "RIGHT of %d\n", root->cost);
88 internal_print (root->right_child);
89 }
90}
91
92void
93printTree (struct GNUNET_CONTAINER_Heap *root)
94{
95 internal_print (root->root);
96}
97
98struct GNUNET_CONTAINER_Heap *
99GNUNET_CONTAINER_heap_create (enum type)
100{
101 struct GNUNET_CONTAINER_Heap *heap;
102 heap = malloc (sizeof (struct GNUNET_CONTAINER_Heap));
103 heap->max_size = -1;
104 heap->type = type;
105 heap->root = NULL;
106 heap->traversal_pos = NULL;
107 heap->size = 0;
108
109 return heap;
110}
111
112void
113GNUNET_CONTAINER_heap_destroy (struct GNUNET_CONTAINER_Heap *heap)
114{
115 void *unused;
116 while (heap->size > 0)
117 {
118 unused = GNUNET_CONTAINER_heap_remove_root (heap);
119 }
120
121 GNUNET_free (heap);
122 return;
123}
124
125struct GNUNET_CONTAINER_heap_node *
126find_element (struct GNUNET_CONTAINER_heap_node *node, void *element)
127{
128 struct GNUNET_CONTAINER_heap_node *ret;
129 ret = NULL;
130 if ((node != NULL) && (node->element == element))
131 {
132 ret = node;
133 }
134
135 if ((ret == NULL) && (node->left_child != NULL))
136 {
137 ret = find_element (node->left_child, element);
138 }
139
140 if ((ret == NULL) && (node->right_child != NULL))
141 {
142 ret = find_element (node->right_child, element);
143 }
144
145 return ret;
146}
147
148static struct GNUNET_CONTAINER_heap_node *
149getNextPos (struct GNUNET_CONTAINER_Heap *root)
150{
151 struct GNUNET_CONTAINER_heap_node *ret;
152 struct GNUNET_CONTAINER_heap_node *parent;
153 int pos;
154 int depth;
155 int i;
156
157 ret = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_heap_node));
158 pos = root->size + 1;
159 depth = (int) log2 (pos);
160 ret->left_child = NULL;
161 ret->right_child = NULL;
162
163 if (depth == 0)
164 {
165 ret->parent = NULL;
166 root->root = ret;
167 }
168 else
169 {
170 parent = root->root;
171 for (i = depth; i > 1; i--)
172 {
173 if (((pos / (1 << (i - 1))) % 2) == 0)
174 parent = parent->left_child;
175 else
176 parent = parent->right_child;
177 }
178
179 ret->parent = parent;
180 if ((pos % 2) == 0)
181 parent->left_child = ret;
182 else
183 parent->right_child = ret;
184
185 }
186
187 return ret;
188
189}
190
191static struct GNUNET_CONTAINER_heap_node *
192getPos (struct GNUNET_CONTAINER_Heap *root, unsigned int pos)
193{
194 struct GNUNET_CONTAINER_heap_node *ret;
195
196 int depth;
197 int i;
198
199 depth = (int) log2 (pos);
200 ret = NULL;
201 if (pos > root->size)
202 {
203 return ret;
204 }
205 else
206 {
207 ret = root->root;
208 for (i = depth; i > 0; i--)
209 {
210 if (((pos / (1 << (i - 1))) % 2) == 0)
211 ret = ret->left_child;
212 else
213 ret = ret->right_child;
214 }
215 }
216
217 return ret;
218
219}
220
221void
222swapNodes (struct GNUNET_CONTAINER_heap_node *first,
223 struct GNUNET_CONTAINER_heap_node *second,
224 struct GNUNET_CONTAINER_Heap *root)
225{
226 void *temp_element;
227 GNUNET_CONTAINER_HeapCost temp_cost;
228
229 temp_element = first->element;
230 temp_cost = first->cost;
231 first->element = second->element;
232 first->cost = second->cost;
233 second->element = temp_element;
234 second->cost = temp_cost;
235
236/*
237 * I still worry that there is some good reason for
238 * elements being location aware... but it eludes me
239 * for the moment...
240 if ((root->type == GNUNET_DV_MAX_HEAP))
241 {
242 first->neighbor->max_loc = first;
243 second->neighbor->max_loc = second;
244 }
245 else if ((root->type == GNUNET_DV_MIN_HEAP))
246 {
247 first->neighbor->min_loc = first;
248 second->neighbor->min_loc = second;
249 }
250*/
251 return;
252}
253
254void
255percolateHeap (struct GNUNET_CONTAINER_heap_node *pos,
256 struct GNUNET_CONTAINER_Heap *root)
257{
258
259 while ((pos->parent != NULL) &&
260 (((root->type == GNUNET_CONTAINER_HEAP_ORDER_MAX)
261 && (pos->parent->cost < pos->cost))
262 || ((root->type == GNUNET_CONTAINER_HEAP_ORDER_MIN)
263 && (pos->parent->cost > pos->cost))))
264 {
265 swapNodes (pos, pos->parent, root);
266 pos = pos->parent;
267 }
268
269 return;
270}
271
272
273
274void
275percolateDownHeap (struct GNUNET_CONTAINER_heap_node *pos,
276 struct GNUNET_CONTAINER_Heap *root)
277{
278 struct GNUNET_CONTAINER_heap_node *switchNeighbor;
279
280 switchNeighbor = pos;
281
282 if ((root->type == GNUNET_CONTAINER_HEAP_ORDER_MAX))
283 {
284 if ((pos->left_child != NULL)
285 && (pos->left_child->cost > switchNeighbor->cost))
286 {
287 switchNeighbor = pos->left_child;
288 }
289
290 if ((pos->right_child != NULL)
291 && (pos->right_child->cost > switchNeighbor->cost))
292 {
293 switchNeighbor = pos->right_child;
294 }
295 }
296 else if ((root->type == GNUNET_CONTAINER_HEAP_ORDER_MIN))
297 {
298 if ((pos->left_child != NULL)
299 && (pos->left_child->cost < switchNeighbor->cost))
300 {
301 switchNeighbor = pos->left_child;
302 }
303
304 if ((pos->right_child != NULL)
305 && (pos->right_child->cost < switchNeighbor->cost))
306 {
307 switchNeighbor = pos->right_child;
308 }
309 }
310
311 if (switchNeighbor != pos)
312 {
313 swapNodes (switchNeighbor, pos, root);
314 percolateDownHeap (switchNeighbor, root);
315 }
316
317 return;
318}
319
320void *
321GNUNET_CONTAINER_heap_remove_node (struct GNUNET_CONTAINER_Heap *root,
322 void *element)
323{
324 void *ret;
325 struct GNUNET_CONTAINER_heap_node *del_node;
326 struct GNUNET_CONTAINER_heap_node *last;
327 GNUNET_CONTAINER_HeapCost old_cost;
328
329 del_node = NULL;
330 del_node = find_element (root->root, element);
331
332 if (del_node == NULL)
333 return NULL;
334
335 ret = del_node->element;
336 last = getPos (root, root->size);
337
338 old_cost = del_node->cost;
339 del_node->element = last->element;
340 del_node->cost = last->cost;
341
342 if (last->parent->left_child == last)
343 last->parent->left_child = NULL;
344 if (last->parent->right_child == last)
345 last->parent->right_child = NULL;
346
347 if (root->traversal_pos == last)
348 {
349 root->traversal_pos = root->root;
350 }
351 GNUNET_free (last);
352 root->size--;
353
354 if (del_node->cost > old_cost)
355 {
356 if (root->type == GNUNET_CONTAINER_HEAP_ORDER_MAX)
357 percolateHeap (del_node, root);
358 else if (root->type == GNUNET_CONTAINER_HEAP_ORDER_MIN)
359 percolateDownHeap (del_node, root);
360 }
361 else if (del_node->cost < old_cost)
362 {
363 if (root->type == GNUNET_CONTAINER_HEAP_ORDER_MAX)
364 percolateDownHeap (del_node, root);
365 else if (root->type == GNUNET_CONTAINER_HEAP_ORDER_MIN)
366 percolateHeap (del_node, root);
367 }
368
369 return ret;
370}
371
372int
373GNUNET_CONTAINER_heap_insert (struct GNUNET_CONTAINER_Heap *root,
374 void *element, GNUNET_CONTAINER_HeapCost cost)
375{
376 struct GNUNET_CONTAINER_heap_node *new_pos;
377 int ret;
378 ret = GNUNET_YES;
379
380 if (root->max_size > root->size)
381 {
382 new_pos = getNextPos (root);
383 new_pos->element = element;
384 new_pos->cost = cost;
385 root->size++;
386 /*We no longer can tolerate pointers between heaps :( */
387 /*if (root->type == GNUNET_DV_MIN_HEAP)
388 new_pos->neighbor->min_loc = new_pos;
389 else if (root->type == GNUNET_DV_MAX_HEAP)
390 new_pos->neighbor->max_loc = new_pos; */
391
392 percolateHeap (new_pos, root);
393 }
394 else
395 {
396 ret = GNUNET_NO;
397 }
398
399 return ret;
400}
401
402void *
403GNUNET_CONTAINER_heap_remove_root (struct GNUNET_CONTAINER_Heap *root)
404{
405 void *ret;
406 struct GNUNET_CONTAINER_heap_node *root_node;
407 struct GNUNET_CONTAINER_heap_node *last;
408
409 root_node = root->root;
410 ret = root_node->element;
411 last = getPos (root, root->size);
412
413 if (last->parent->left_child == last)
414 last->parent->left_child = NULL;
415 else if (last->parent->right_child == last)
416 last->parent->right_child = NULL;
417
418 root_node->element = last->element;
419 root_node->cost = last->cost;
420
421 if (root->traversal_pos == last)
422 {
423 root->traversal_pos = root->root;
424 }
425
426 GNUNET_free (last);
427 root->size--;
428 percolateDownHeap (root->root, root);
429 return ret;
430}
431
432static int
433updatedCost (struct GNUNET_CONTAINER_Heap *root,
434 struct GNUNET_CONTAINER_heap_node *node)
435{
436 struct GNUNET_CONTAINER_heap_node *parent;
437
438 if (node == NULL)
439 return GNUNET_SYSERR;
440
441 parent = node->parent;
442
443 if ((root->type == GNUNET_CONTAINER_HEAP_ORDER_MAX) && (parent != NULL)
444 && (node->cost > parent->cost))
445 percolateHeap (node, root);
446 else if ((root->type == GNUNET_CONTAINER_HEAP_ORDER_MIN) && (parent != NULL)
447 && (node->cost < parent->cost))
448 percolateHeap (node, root);
449 else if (root->type == GNUNET_CONTAINER_HEAP_ORDER_MAX)
450 percolateDownHeap (node, root);
451 else if (root->type == GNUNET_CONTAINER_HEAP_ORDER_MIN)
452 percolateDownHeap (node, root);
453
454 return GNUNET_YES;
455}
456
457
458int
459GNUNET_CONTAINER_heap_update_cost (struct GNUNET_CONTAINER_Heap *root,
460 void *element,
461 GNUNET_CONTAINER_HeapCost new_cost)
462{
463 struct GNUNET_CONTAINER_heap_node *node;
464 int ret = GNUNET_YES;
465 node = find_element (root->root, element);
466 if (node == NULL)
467 return GNUNET_NO;
468
469 node->cost = new_cost;
470 ret = updatedCost (root, node);
471 return ret;
472}
473
474void
475internal_iterator (struct GNUNET_CONTAINER_Heap *root,
476 struct GNUNET_CONTAINER_heap_node *node,
477 GNUNET_CONTAINER_HeapIterator iterator, void *cls)
478{
479 if (node == NULL)
480 return;
481 internal_iterator (root, node->left_child, iterator, cls);
482 internal_iterator (root, node->right_child, iterator, cls);
483 iterator (node->element, node->cost, root, cls);
484}
485
486int
487GNUNET_CONTAINER_heap_iterate (struct GNUNET_CONTAINER_Heap *heap,
488 GNUNET_CONTAINER_HeapIterator iterator,
489 void *cls)
490{
491 internal_iterator (heap, heap->root, iterator, cls);
492 return GNUNET_OK;
493}
494
495void *
496GNUNET_CONTAINER_heap_walk_get_next (struct GNUNET_CONTAINER_Heap *root)
497{
498 unsigned int choice;
499 void *element;
500
501 if ((root->traversal_pos == NULL) && (root->root != NULL))
502 {
503 root->traversal_pos = root->root;
504 }
505
506 if (root->traversal_pos == NULL)
507 return NULL;
508
509 element = root->traversal_pos->element;
510
511 choice = GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 2);
512
513 switch (choice)
514 {
515 case 1:
516 root->traversal_pos = root->traversal_pos->right_child;
517 break;
518 case 0:
519 root->traversal_pos = root->traversal_pos->left_child;
520 break;
521 }
522
523 return element;
524
525}
526
527unsigned int
528GNUNET_CONTAINER_heap_get_size (struct GNUNET_CONTAINER_Heap *heap)
529{
530 return heap->size;
531}
532
533/* end of heap.c */
diff --git a/src/util/container_meta_data.c b/src/util/container_meta_data.c
new file mode 100644
index 000000000..b79de57d2
--- /dev/null
+++ b/src/util/container_meta_data.c
@@ -0,0 +1,721 @@
1/*
2 This file is part of GNUnet.
3 (C) 2003, 2004, 2005, 2006, 2008, 2009 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 2, 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 util/container_meta_data.c
23 * @brief Storing of meta data
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_common.h"
29#include "gnunet_container_lib.h"
30#include "gnunet_strings_lib.h"
31#include "gnunet_time_lib.h"
32#include <extractor.h>
33#include <zlib.h>
34
35#define EXTRA_CHECKS ALLOW_EXTRA_CHECKS
36
37struct Item
38{
39 EXTRACTOR_KeywordType type;
40 char *data;
41};
42
43/**
44 * Meta data to associate with a file, directory or namespace.
45 */
46struct GNUNET_CONTAINER_MetaData
47{
48 uint32_t itemCount;
49 struct Item *items;
50};
51
52/**
53 * Create a fresh struct CONTAINER_MetaData token.
54 */
55struct GNUNET_CONTAINER_MetaData *
56GNUNET_CONTAINER_meta_data_create ()
57{
58 struct GNUNET_CONTAINER_MetaData *ret;
59 ret = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_MetaData));
60 ret->items = NULL;
61 ret->itemCount = 0;
62 return ret;
63}
64
65/**
66 * Free meta data.
67 */
68void
69GNUNET_CONTAINER_meta_data_destroy (struct GNUNET_CONTAINER_MetaData *md)
70{
71 int i;
72
73 if (md == NULL)
74 return;
75 for (i = 0; i < md->itemCount; i++)
76 GNUNET_free (md->items[i].data);
77 GNUNET_array_grow (md->items, md->itemCount, 0);
78 GNUNET_free (md);
79}
80
81/**
82 * Add the current time as the publication date
83 * to the meta-data.
84 */
85void
86GNUNET_CONTAINER_meta_data_add_publication_date (struct
87 GNUNET_CONTAINER_MetaData
88 *md)
89{
90 char *dat;
91 struct GNUNET_TIME_Absolute t;
92
93 t = GNUNET_TIME_absolute_get ();
94 GNUNET_CONTAINER_meta_data_delete (md, EXTRACTOR_PUBLICATION_DATE, NULL);
95 dat = GNUNET_STRINGS_absolute_time_to_string (t);
96 GNUNET_CONTAINER_meta_data_insert (md, EXTRACTOR_PUBLICATION_DATE, dat);
97 GNUNET_free (dat);
98}
99
100/**
101 * Extend metadata.
102 * @return GNUNET_OK on success, GNUNET_SYSERR if this entry already exists
103 */
104int
105GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md,
106 EXTRACTOR_KeywordType type,
107 const char *data)
108{
109 uint32_t idx;
110 char *p;
111
112 GNUNET_assert (data != NULL);
113 for (idx = 0; idx < md->itemCount; idx++)
114 {
115 if ((md->items[idx].type == type) &&
116 (0 == strcmp (md->items[idx].data, data)))
117 return GNUNET_SYSERR;
118 }
119 idx = md->itemCount;
120 GNUNET_array_grow (md->items, md->itemCount, md->itemCount + 1);
121 md->items[idx].type = type;
122 md->items[idx].data = p = GNUNET_strdup (data);
123
124 /* change OS native dir separators to unix '/' and others to '_' */
125 if (type == EXTRACTOR_FILENAME)
126 {
127 while (*p != '\0')
128 {
129 if (*p == DIR_SEPARATOR)
130 *p = '/';
131 else if (*p == '\\')
132 *p = '_';
133 p++;
134 }
135 }
136
137 return GNUNET_OK;
138}
139
140/**
141 * Remove an item.
142 * @return GNUNET_OK on success, GNUNET_SYSERR if the item does not exist in md
143 */
144int
145GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md,
146 EXTRACTOR_KeywordType type,
147 const char *data)
148{
149 uint32_t idx;
150 int ret = GNUNET_SYSERR;
151 for (idx = 0; idx < md->itemCount; idx++)
152 {
153 if ((md->items[idx].type == type) &&
154 ((data == NULL) || (0 == strcmp (md->items[idx].data, data))))
155 {
156 GNUNET_free (md->items[idx].data);
157 md->items[idx] = md->items[md->itemCount - 1];
158 GNUNET_array_grow (md->items, md->itemCount, md->itemCount - 1);
159 if (data == NULL)
160 {
161 ret = GNUNET_OK;
162 continue;
163 }
164 return GNUNET_OK;
165 }
166 }
167 return ret;
168}
169
170/**
171 * Iterate over MD entries, excluding thumbnails.
172 *
173 * @return number of entries
174 */
175int
176GNUNET_CONTAINER_meta_data_get_contents (const struct
177 GNUNET_CONTAINER_MetaData *md,
178 GNUNET_CONTAINER_MetaDataProcessor
179 iterator, void *closure)
180{
181 uint32_t i;
182 uint32_t sub;
183
184 sub = 0;
185 for (i = 0; i < md->itemCount; i++)
186 {
187 if (!EXTRACTOR_isBinaryType (md->items[i].type))
188 {
189 if ((iterator != NULL) &&
190 (GNUNET_OK != iterator (md->items[i].type,
191 md->items[i].data, closure)))
192 return GNUNET_SYSERR;
193 }
194 else
195 sub++;
196 }
197 return (int) (md->itemCount - sub);
198}
199
200/**
201 * Iterate over MD entries
202 *
203 * @return number of entries
204 */
205char *
206GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData
207 *md, EXTRACTOR_KeywordType type)
208{
209 uint32_t i;
210
211 for (i = 0; i < md->itemCount; i++)
212 if (type == md->items[i].type)
213 return GNUNET_strdup (md->items[i].data);
214 return NULL;
215}
216
217/**
218 * Iterate over MD entries
219 *
220 * @return number of entries
221 */
222char *
223GNUNET_CONTAINER_meta_data_get_first_by_types (const struct
224 GNUNET_CONTAINER_MetaData *md,
225 ...)
226{
227 char *ret;
228 va_list args;
229 EXTRACTOR_KeywordType type;
230
231 ret = NULL;
232 va_start (args, md);
233 while (1)
234 {
235 type = va_arg (args, EXTRACTOR_KeywordType);
236 if (type == -1)
237 break;
238 ret = GNUNET_CONTAINER_meta_data_get_by_type (md, type);
239 if (ret != NULL)
240 break;
241 }
242 va_end (args);
243 return ret;
244}
245
246/**
247 * Get a thumbnail from the meta-data (if present).
248 *
249 * @param thumb will be set to the thumbnail data. Must be
250 * freed by the caller!
251 * @return number of bytes in thumbnail, 0 if not available
252 */
253size_t
254GNUNET_CONTAINER_meta_data_get_thumbnail (const struct
255 GNUNET_CONTAINER_MetaData * md,
256 unsigned char **thumb)
257{
258 char *encoded;
259 int ret;
260 size_t size;
261
262 encoded =
263 GNUNET_CONTAINER_meta_data_get_by_type (md, EXTRACTOR_THUMBNAIL_DATA);
264 if (encoded == NULL)
265 return 0;
266 if (strlen (encoded) == 0)
267 {
268 GNUNET_free (encoded);
269 return 0; /* invalid */
270 }
271 *thumb = NULL;
272 ret = EXTRACTOR_binaryDecode (encoded, thumb, &size);
273 GNUNET_free (encoded);
274 if (ret != 0)
275 return 0;
276 return size;
277}
278
279/**
280 * Duplicate struct GNUNET_CONTAINER_MetaData.
281 */
282struct GNUNET_CONTAINER_MetaData *
283GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData
284 *md)
285{
286 uint32_t i;
287 struct GNUNET_CONTAINER_MetaData *ret;
288
289 if (md == NULL)
290 return NULL;
291 ret = GNUNET_CONTAINER_meta_data_create ();
292 for (i = 0; i < md->itemCount; i++)
293 GNUNET_CONTAINER_meta_data_insert (ret, md->items[i].type,
294 md->items[i].data);
295 return ret;
296}
297
298/**
299 * Extract meta-data from a file.
300 *
301 * @return GNUNET_SYSERR on error, otherwise the number
302 * of meta-data items obtained
303 */
304int
305GNUNET_CONTAINER_meta_data_extract_from_file (struct GNUNET_CONTAINER_MetaData
306 *md, const char *filename,
307 EXTRACTOR_ExtractorList *
308 extractors)
309{
310 EXTRACTOR_KeywordList *head;
311 EXTRACTOR_KeywordList *pos;
312 int ret;
313
314 if (filename == NULL)
315 return GNUNET_SYSERR;
316 if (extractors == NULL)
317 return 0;
318 head = EXTRACTOR_getKeywords (extractors, filename);
319 head = EXTRACTOR_removeDuplicateKeywords (head,
320 EXTRACTOR_DUPLICATES_REMOVE_UNKNOWN);
321 pos = head;
322 ret = 0;
323 while (pos != NULL)
324 {
325 if (GNUNET_OK ==
326 GNUNET_CONTAINER_meta_data_insert (md, pos->keywordType,
327 pos->keyword))
328 ret++;
329 pos = pos->next;
330 }
331 EXTRACTOR_freeKeywords (head);
332 return ret;
333}
334
335static unsigned int
336tryCompression (char *data, unsigned int oldSize)
337{
338 char *tmp;
339 uLongf dlen;
340
341#ifdef compressBound
342 dlen = compressBound (oldSize);
343#else
344 dlen = oldSize + (oldSize / 100) + 20;
345 /* documentation says 100.1% oldSize + 12 bytes, but we
346 should be able to overshoot by more to be safe */
347#endif
348 tmp = GNUNET_malloc (dlen);
349 if (Z_OK == compress2 ((Bytef *) tmp,
350 &dlen, (const Bytef *) data, oldSize, 9))
351 {
352 if (dlen < oldSize)
353 {
354 memcpy (data, tmp, dlen);
355 GNUNET_free (tmp);
356 return dlen;
357 }
358 }
359 GNUNET_free (tmp);
360 return oldSize;
361}
362
363/**
364 * Decompress input, return the decompressed data
365 * as output, set outputSize to the number of bytes
366 * that were found.
367 *
368 * @return NULL on error
369 */
370static char *
371decompress (const char *input,
372 unsigned int inputSize, unsigned int outputSize)
373{
374 char *output;
375 uLongf olen;
376
377 olen = outputSize;
378 output = GNUNET_malloc (olen);
379 if (Z_OK == uncompress ((Bytef *) output,
380 &olen, (const Bytef *) input, inputSize))
381 {
382 return output;
383 }
384 else
385 {
386 GNUNET_free (output);
387 return NULL;
388 }
389}
390
391/**
392 * Flag in 'version' that indicates compressed meta-data.
393 */
394#define HEADER_COMPRESSED 0x80000000
395
396/**
397 * Bits in 'version' that give the version number.
398 */
399#define HEADER_VERSION_MASK 0x7FFFFFFF
400
401struct MetaDataHeader
402{
403 /**
404 * The version of the MD serialization.
405 * The highest bit is used to indicate
406 * compression.
407 *
408 * Version 0 is the current version;
409 * Version is 1 for a NULL pointer.
410 * Other version numbers are not yet defined.
411 */
412 uint32_t version;
413
414 /**
415 * How many MD entries are there?
416 */
417 uint32_t entries;
418
419 /**
420 * Size of the MD (decompressed)
421 */
422 uint32_t size;
423
424 /**
425 * This is followed by 'entries' values of type 'unsigned int' that
426 * correspond to EXTRACTOR_KeywordTypes. After that, the meta-data
427 * keywords follow (0-terminated). The MD block always ends with
428 * 0-termination, padding with 0 until a multiple of 8 bytes.
429 */
430
431};
432
433/**
434 * Serialize meta-data to target.
435 *
436 * @param size maximum number of bytes available
437 * @param part is it ok to just write SOME of the
438 * meta-data to match the size constraint,
439 * possibly discarding some data?
440 * @return number of bytes written on success,
441 * GNUNET_SYSERR on error (typically: not enough
442 * space)
443 */
444int
445GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData
446 *md, char *target, unsigned int max,
447 enum
448 GNUNET_CONTAINER_MetaDataSerializationOptions
449 part)
450{
451 struct MetaDataHeader *hdr;
452 size_t size;
453 size_t pos;
454 uint32_t i;
455 size_t len;
456 uint32_t ic;
457
458 if (max < sizeof (struct MetaDataHeader))
459 return GNUNET_SYSERR; /* far too small */
460 ic = md ? md->itemCount : 0;
461 hdr = NULL;
462 while (1)
463 {
464 size = sizeof (struct MetaDataHeader);
465 size += sizeof (unsigned int) * ic;
466 for (i = 0; i < ic; i++)
467 size += 1 + strlen (md->items[i].data);
468 while (size % 8 != 0)
469 size++;
470 hdr = GNUNET_malloc (size);
471 hdr->version = htonl (md == NULL ? 1 : 0);
472 hdr->entries = htonl (ic);
473 for (i = 0; i < ic; i++)
474 ((unsigned int *) &hdr[1])[i] =
475 htonl ((unsigned int) md->items[i].type);
476 pos = sizeof (struct MetaDataHeader);
477 pos += sizeof (unsigned int) * ic;
478 for (i = 0; i < ic; i++)
479 {
480 len = strlen (md->items[i].data) + 1;
481 memcpy (&((char *) hdr)[pos], md->items[i].data, len);
482 pos += len;
483 }
484
485 hdr->size = htonl (size);
486 if ((part & GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS) == 0)
487 {
488 pos = tryCompression ((char *) &hdr[1],
489 size - sizeof (struct MetaDataHeader));
490 }
491 else
492 {
493 pos = size - sizeof (struct MetaDataHeader);
494 }
495 if (pos < size - sizeof (struct MetaDataHeader))
496 {
497 hdr->version = htonl (HEADER_COMPRESSED);
498 size = pos + sizeof (struct MetaDataHeader);
499 }
500 if (size <= max)
501 break;
502 GNUNET_free (hdr);
503 hdr = NULL;
504
505 if ((part & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART) == 0)
506 {
507 return GNUNET_SYSERR; /* does not fit! */
508 }
509 /* partial serialization ok, try again with less meta-data */
510 if (size > 2 * max)
511 ic = ic * 2 / 3; /* still far too big, make big reductions */
512 else
513 ic--; /* small steps, we're close */
514 }
515 GNUNET_assert (size <= max);
516 memcpy (target, hdr, size);
517 GNUNET_free (hdr);
518 /* extra check: deserialize! */
519#if EXTRA_CHECKS
520 {
521 struct GNUNET_CONTAINER_MetaData *mdx;
522 mdx = GNUNET_CONTAINER_meta_data_deserialize (target, size);
523 GNUNET_assert (NULL != mdx);
524 GNUNET_CONTAINER_meta_data_destroy (mdx);
525 }
526#endif
527 return size;
528}
529
530/**
531 * Estimate (!) the size of the meta-data in
532 * serialized form. The estimate MAY be higher
533 * than what is strictly needed.
534 */
535unsigned int
536GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
537 GNUNET_CONTAINER_MetaData *md,
538 enum
539 GNUNET_CONTAINER_MetaDataSerializationOptions
540 part)
541{
542 struct MetaDataHeader *hdr;
543 size_t size;
544 size_t pos;
545 uint32_t i;
546 size_t len;
547 uint32_t ic;
548
549 ic = md ? md->itemCount : 0;
550 size = sizeof (struct MetaDataHeader);
551 size += sizeof (unsigned int) * ic;
552 for (i = 0; i < ic; i++)
553 size += 1 + strlen (md->items[i].data);
554 while (size % 8 != 0)
555 size++;
556 hdr = GNUNET_malloc (size);
557 hdr->version = htonl (md == NULL ? 1 : 0);
558 hdr->entries = htonl (ic);
559 for (i = 0; i < ic; i++)
560 ((unsigned int *) &hdr[1])[i] = htonl ((unsigned int) md->items[i].type);
561 pos = sizeof (struct MetaDataHeader);
562 pos += sizeof (unsigned int) * ic;
563 for (i = 0; i < ic; i++)
564 {
565 len = strlen (md->items[i].data) + 1;
566 memcpy (&((char *) hdr)[pos], md->items[i].data, len);
567 pos += len;
568 }
569 if ((part & GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS) == 0)
570 {
571 pos =
572 tryCompression ((char *) &hdr[1],
573 size - sizeof (struct MetaDataHeader));
574 }
575 else
576 {
577 pos = size - sizeof (struct MetaDataHeader);
578 }
579 if (pos < size - sizeof (struct MetaDataHeader))
580 size = pos + sizeof (struct MetaDataHeader);
581 GNUNET_free (hdr);
582 return size;
583}
584
585/**
586 * Deserialize meta-data. Initializes md.
587 * @param size number of bytes available
588 * @return MD on success, NULL on error (i.e.
589 * bad format)
590 */
591struct GNUNET_CONTAINER_MetaData *
592GNUNET_CONTAINER_meta_data_deserialize (const char *input, unsigned int size)
593{
594 struct GNUNET_CONTAINER_MetaData *md;
595 const struct MetaDataHeader *hdr;
596 uint32_t ic;
597 char *data;
598 const char *cdata;
599 uint32_t dataSize;
600 int compressed;
601 int i;
602 unsigned int pos;
603 int len;
604 uint32_t version;
605
606 if (size < sizeof (struct MetaDataHeader))
607 return NULL;
608 hdr = (const struct MetaDataHeader *) input;
609 version = ntohl (MAKE_UNALIGNED (hdr->version)) & HEADER_VERSION_MASK;
610 if (version == 1)
611 return NULL; /* null pointer */
612 if (version != 0)
613 {
614 GNUNET_break_op (0); /* unsupported version */
615 return NULL;
616 }
617 ic = ntohl (MAKE_UNALIGNED (hdr->entries));
618 compressed =
619 (ntohl (MAKE_UNALIGNED (hdr->version)) & HEADER_COMPRESSED) != 0;
620 if (compressed)
621 {
622 dataSize =
623 ntohl (MAKE_UNALIGNED (hdr->size)) - sizeof (struct MetaDataHeader);
624 if (dataSize > 2 * 1042 * 1024)
625 {
626 GNUNET_break (0);
627 return NULL; /* only 2 MB allowed [to make sure we don't blow
628 our memory limit because of a mal-formed
629 message... ] */
630 }
631 data =
632 decompress ((const char *) &input[sizeof (struct MetaDataHeader)],
633 size - sizeof (struct MetaDataHeader), dataSize);
634 if (data == NULL)
635 {
636 GNUNET_break_op (0);
637 return NULL;
638 }
639 cdata = data;
640 }
641 else
642 {
643 data = NULL;
644 cdata = (const char *) &hdr[1];
645 dataSize = size - sizeof (struct MetaDataHeader);
646 if (size != ntohl (MAKE_UNALIGNED (hdr->size)))
647 {
648 GNUNET_break (0);
649 return NULL;
650 }
651 }
652
653 if ((sizeof (unsigned int) * ic + ic) > dataSize)
654 {
655 GNUNET_break (0);
656 goto FAILURE;
657 }
658 if ((ic > 0) && (cdata[dataSize - 1] != '\0'))
659 {
660 GNUNET_break (0);
661 goto FAILURE;
662 }
663
664 md = GNUNET_CONTAINER_meta_data_create ();
665 GNUNET_array_grow (md->items, md->itemCount, ic);
666 i = 0;
667 pos = sizeof (unsigned int) * ic;
668 while ((pos < dataSize) && (i < ic))
669 {
670 len = strlen (&cdata[pos]) + 1;
671 md->items[i].type = (EXTRACTOR_KeywordType)
672 ntohl (MAKE_UNALIGNED (((const unsigned int *) cdata)[i]));
673 md->items[i].data = GNUNET_strdup (&cdata[pos]);
674 pos += len;
675 i++;
676 }
677 if (i < ic)
678 { /* oops */
679 GNUNET_CONTAINER_meta_data_destroy (md);
680 goto FAILURE;
681 }
682 GNUNET_free_non_null (data);
683 return md;
684FAILURE:
685 GNUNET_free_non_null (data);
686 return NULL; /* size too small */
687}
688
689/**
690 * Test if two MDs are equal.
691 */
692int
693GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData
694 *md1,
695 const struct GNUNET_CONTAINER_MetaData
696 *md2)
697{
698 uint32_t i;
699 uint32_t j;
700 int found;
701
702 if (md1->itemCount != md2->itemCount)
703 return GNUNET_NO;
704 for (i = 0; i < md1->itemCount; i++)
705 {
706 found = GNUNET_NO;
707 for (j = 0; j < md2->itemCount; j++)
708 if ((md1->items[i].type == md2->items[j].type) &&
709 (0 == strcmp (md1->items[i].data, md2->items[j].data)))
710 {
711 found = GNUNET_YES;
712 break;
713 }
714 if (found == GNUNET_NO)
715 return GNUNET_NO;
716 }
717 return GNUNET_YES;
718}
719
720
721/* end of container_meta_data.c */
diff --git a/src/util/container_multihashmap.c b/src/util/container_multihashmap.c
new file mode 100644
index 000000000..a84955eb3
--- /dev/null
+++ b/src/util/container_multihashmap.c
@@ -0,0 +1,334 @@
1/*
2 This file is part of GNUnet.
3 (C) 2008 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 2, 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 util/container_multihashmap.c
22 * @brief hash map where the same key maybe present multiple times
23 * @author Christian Grothoff
24 */
25
26#include "platform.h"
27#include "gnunet_common.h"
28#include "gnunet_container_lib.h"
29#include "gnunet_crypto_lib.h"
30
31struct MapEntry
32{
33 GNUNET_HashCode key;
34 void *value;
35 struct MapEntry *next;
36};
37
38struct GNUNET_CONTAINER_MultiHashMap
39{
40
41 struct MapEntry **map;
42
43 unsigned int size;
44
45 unsigned int map_length;
46};
47
48struct GNUNET_CONTAINER_MultiHashMap *
49GNUNET_CONTAINER_multihashmap_create (unsigned int len)
50{
51 struct GNUNET_CONTAINER_MultiHashMap *ret;
52
53 ret = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_MultiHashMap));
54 ret->size = 0;
55 ret->map = GNUNET_malloc (len * sizeof (struct MapEntry *));
56 memset (ret->map, 0, len * sizeof (struct MapEntry *));
57 ret->map_length = len;
58 return ret;
59}
60
61void
62GNUNET_CONTAINER_multihashmap_destroy (struct GNUNET_CONTAINER_MultiHashMap
63 *map)
64{
65 unsigned int i;
66 struct MapEntry *e;
67
68 for (i = 0; i < map->map_length; i++)
69 {
70 while (NULL != (e = map->map[i]))
71 {
72 map->map[i] = e->next;
73 GNUNET_free (e);
74 }
75 }
76 GNUNET_free (map->map);
77 GNUNET_free (map);
78}
79
80static unsigned int
81idx_of (const struct GNUNET_CONTAINER_MultiHashMap *m,
82 const GNUNET_HashCode * key)
83{
84 return (*(unsigned int *) key) % m->map_length;
85}
86
87unsigned int
88GNUNET_CONTAINER_multihashmap_size (const struct GNUNET_CONTAINER_MultiHashMap
89 *map)
90{
91 return map->size;
92}
93
94void *
95GNUNET_CONTAINER_multihashmap_get (const struct GNUNET_CONTAINER_MultiHashMap
96 *map, const GNUNET_HashCode * key)
97{
98 struct MapEntry *e;
99
100 e = map->map[idx_of (map, key)];
101 while (e != NULL)
102 {
103 if (0 == memcmp (key, &e->key, sizeof (GNUNET_HashCode)))
104 return e->value;
105 e = e->next;
106 }
107 return NULL;
108}
109
110int
111GNUNET_CONTAINER_multihashmap_iterate (const struct
112 GNUNET_CONTAINER_MultiHashMap *map,
113 GNUNET_CONTAINER_HashMapIterator it,
114 void *cls)
115{
116 int count;
117 unsigned int i;
118 struct MapEntry *e;
119
120 count = 0;
121 for (i = 0; i < map->map_length; i++)
122 {
123 e = map->map[i];
124 while (e != NULL)
125 {
126 if ((NULL != it) && (GNUNET_OK != it (&e->key, e->value, cls)))
127 return GNUNET_SYSERR;
128 count++;
129 e = e->next;
130 }
131 }
132 return count;
133}
134
135int
136GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap
137 *map, const GNUNET_HashCode * key,
138 void *value)
139{
140 struct MapEntry *e;
141 struct MapEntry *p;
142 unsigned int i;
143
144 i = idx_of (map, key);
145 p = NULL;
146 e = map->map[i];
147 while (e != NULL)
148 {
149 if ((0 == memcmp (key, &e->key, sizeof (GNUNET_HashCode))) &&
150 (value == e->value))
151 {
152 if (p == NULL)
153 map->map[i] = e->next;
154 else
155 p->next = e->next;
156 GNUNET_free (e);
157 map->size--;
158 return GNUNET_YES;
159 }
160 p = e;
161 e = e->next;
162 }
163 return GNUNET_NO;
164}
165
166int
167GNUNET_CONTAINER_multihashmap_remove_all (struct GNUNET_CONTAINER_MultiHashMap
168 *map, const GNUNET_HashCode * key)
169{
170 struct MapEntry *e;
171 struct MapEntry *p;
172 unsigned int i;
173 int ret;
174
175 ret = 0;
176 i = idx_of (map, key);
177 p = NULL;
178 e = map->map[i];
179 while (e != NULL)
180 {
181 if (0 == memcmp (key, &e->key, sizeof (GNUNET_HashCode)))
182 {
183 if (p == NULL)
184 map->map[i] = e->next;
185 else
186 p->next = e->next;
187 GNUNET_free (e);
188 map->size--;
189 if (p == NULL)
190 e = map->map[i];
191 else
192 e = p->next;
193 ret++;
194 }
195 else
196 {
197 p = e;
198 e = e->next;
199 }
200 }
201 return ret;
202}
203
204int
205GNUNET_CONTAINER_multihashmap_contains (const struct
206 GNUNET_CONTAINER_MultiHashMap *map,
207 const GNUNET_HashCode * key)
208{
209 struct MapEntry *e;
210 unsigned int i;
211
212 i = idx_of (map, key);
213 e = map->map[i];
214 while (e != NULL)
215 {
216 if (0 == memcmp (key, &e->key, sizeof (GNUNET_HashCode)))
217 return GNUNET_YES;
218 e = e->next;
219 }
220 return GNUNET_NO;
221}
222
223static void
224grow (struct GNUNET_CONTAINER_MultiHashMap *map)
225{
226 struct MapEntry **old;
227 struct MapEntry *e;
228 unsigned int i;
229 unsigned int l;
230
231 old = map->map;
232 l = map->map_length;
233 map->map_length *= 2;
234 map->map = GNUNET_malloc (sizeof (struct MapEntry *) * map->map_length);
235 memset (map->map, 0, sizeof (struct MapEntry *) * map->map_length);
236 for (i = 0; i < l; i++)
237 {
238 while (NULL != (e = old[i]))
239 {
240 old[i] = e->next;
241 e->next = map->map[idx_of (map, &e->key)];
242 map->map[idx_of (map, &e->key)] = e;
243 }
244 }
245 GNUNET_free (old);
246}
247
248int
249GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap *map,
250 const GNUNET_HashCode * key,
251 void *value,
252 enum GNUNET_CONTAINER_MultiHashMapOption
253 opt)
254{
255 struct MapEntry *e;
256 unsigned int i;
257
258 i = idx_of (map, key);
259 if ((opt != GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE) &&
260 (opt != GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
261 {
262 e = map->map[i];
263 while (e != NULL)
264 {
265 if ((0 == memcmp (key, &e->key, sizeof (GNUNET_HashCode))) &&
266 (value == e->value))
267 {
268 if (opt == GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)
269 return GNUNET_SYSERR;
270 e->value = value;
271 return GNUNET_NO;
272 }
273 e = e->next;
274 }
275 }
276 if (map->size / 3 > map->map_length / 4)
277 grow (map);
278 e = GNUNET_malloc (sizeof (struct MapEntry));
279 e->key = *key;
280 e->value = value;
281 e->next = map->map[i];
282 map->map[i] = e;
283 map->size++;
284 return GNUNET_OK;
285}
286
287int
288GNUNET_CONTAINER_multihashmap_get_multiple (const struct
289 GNUNET_CONTAINER_MultiHashMap
290 *map, const GNUNET_HashCode * key,
291 GNUNET_CONTAINER_HashMapIterator
292 it, void *cls)
293{
294 int count;
295 struct MapEntry *e;
296
297 count = 0;
298 e = map->map[idx_of (map, key)];
299 while (e != NULL)
300 {
301 if (0 == memcmp (key, &e->key, sizeof (GNUNET_HashCode)))
302 {
303 if ((it != NULL) && (GNUNET_OK != it (&e->key, e->value, cls)))
304 return GNUNET_SYSERR;
305 count++;
306 }
307 e = e->next;
308 }
309 return count;
310}
311
312void *
313GNUNET_CONTAINER_multihashmap_get_random (const struct
314 GNUNET_CONTAINER_MultiHashMap *map)
315{
316 unsigned int rand;
317 struct MapEntry *e;
318 e = NULL;
319
320 if (map->size == 0)
321 return NULL;
322
323 while (e == NULL)
324 {
325 rand =
326 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
327 map->map_length);
328 e = map->map[rand];
329 }
330
331 return e->value;
332}
333
334/* end of multihashmap.c */
diff --git a/src/util/crypto_aes.c b/src/util/crypto_aes.c
new file mode 100644
index 000000000..28a65dfca
--- /dev/null
+++ b/src/util/crypto_aes.c
@@ -0,0 +1,148 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006 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 2, 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 util/crypto_aes.c
23 * @brief Symmetric encryption services.
24 * @author Christian Grothoff
25 * @author Ioana Patrascu
26 */
27
28#include "platform.h"
29#include "gnunet_common.h"
30#include "gnunet_crypto_lib.h"
31#include <gcrypt.h>
32
33/**
34 * Create a new SessionKey (for AES-256).
35 */
36void
37GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey *key)
38{
39 gcry_randomize (&key->key[0], GNUNET_CRYPTO_AES_KEY_LENGTH,
40 GCRY_STRONG_RANDOM);
41 key->crc32 =
42 htonl (GNUNET_CRYPTO_crc32_n (key, GNUNET_CRYPTO_AES_KEY_LENGTH));
43}
44
45/**
46 * Check that a new session key is well-formed.
47 *
48 * @return GNUNET_OK if the key is valid
49 */
50int
51GNUNET_CRYPTO_aes_check_session_key (const struct GNUNET_CRYPTO_AesSessionKey
52 *key)
53{
54 uint32_t crc;
55
56 crc = GNUNET_CRYPTO_crc32_n (key, GNUNET_CRYPTO_AES_KEY_LENGTH);
57 if (ntohl (key->crc32) == crc)
58 return GNUNET_OK;
59 GNUNET_break (0);
60 return GNUNET_SYSERR;
61}
62
63
64/**
65 * Encrypt a block with the public key of another
66 * host that uses the same cyper.
67 * @param block the block to encrypt
68 * @param len the size of the block
69 * @param sessionkey the key used to encrypt
70 * @param iv the initialization vector to use, use INITVALUE
71 * for streams.
72 * @param result the output parameter in which to store the encrypted result
73 * @returns the size of the encrypted block, -1 for errors
74 */
75int
76GNUNET_CRYPTO_aes_encrypt (const void *block,
77 uint16_t len,
78 const struct GNUNET_CRYPTO_AesSessionKey
79 *sessionkey,
80 const struct GNUNET_CRYPTO_AesInitializationVector
81 *iv, void *result)
82{
83 gcry_cipher_hd_t handle;
84 int rc;
85
86 if (sessionkey->crc32 !=
87 htonl (GNUNET_CRYPTO_crc32_n
88 (sessionkey, GNUNET_CRYPTO_AES_KEY_LENGTH)))
89 {
90 GNUNET_break (0);
91 return GNUNET_SYSERR;
92 }
93 GNUNET_assert (0 == gcry_cipher_open (&handle,
94 GCRY_CIPHER_AES256,
95 GCRY_CIPHER_MODE_CFB, 0));
96 rc = gcry_cipher_setkey (handle, sessionkey, GNUNET_CRYPTO_AES_KEY_LENGTH);
97 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
98 rc =
99 gcry_cipher_setiv (handle, iv,
100 sizeof (struct GNUNET_CRYPTO_AesInitializationVector));
101 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
102 GNUNET_assert (0 == gcry_cipher_encrypt (handle, result, len, block, len));
103 gcry_cipher_close (handle);
104 return len;
105}
106
107/**
108 * Decrypt a given block with the sessionkey.
109 * @param sessionkey the key used to decrypt
110 * @param block the data to decrypt, encoded as returned by encrypt
111 * @param size the size of the block to decrypt
112 * @param iv the initialization vector to use, use INITVALUE
113 * for streams.
114 * @param result address to store the result at
115 * @return -1 on failure, size of decrypted block on success
116 */
117int
118GNUNET_CRYPTO_aes_decrypt (const struct GNUNET_CRYPTO_AesSessionKey
119 *sessionkey, const void *block, uint16_t size,
120 const struct GNUNET_CRYPTO_AesInitializationVector
121 *iv, void *result)
122{
123 gcry_cipher_hd_t handle;
124 int rc;
125
126 if (sessionkey->crc32 !=
127 htonl (GNUNET_CRYPTO_crc32_n
128 (sessionkey, GNUNET_CRYPTO_AES_KEY_LENGTH)))
129 {
130 GNUNET_break (0);
131 return GNUNET_SYSERR;
132 }
133 GNUNET_assert (0 == gcry_cipher_open (&handle,
134 GCRY_CIPHER_AES256,
135 GCRY_CIPHER_MODE_CFB, 0));
136 rc = gcry_cipher_setkey (handle, sessionkey, GNUNET_CRYPTO_AES_KEY_LENGTH);
137 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
138 rc =
139 gcry_cipher_setiv (handle, iv,
140 sizeof (struct GNUNET_CRYPTO_AesInitializationVector));
141 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
142 GNUNET_assert (0 ==
143 gcry_cipher_decrypt (handle, result, size, block, size));
144 gcry_cipher_close (handle);
145 return size;
146}
147
148/* end of crypto_aes.c */
diff --git a/src/util/crypto_crc.c b/src/util/crypto_crc.c
new file mode 100644
index 000000000..35d1e2576
--- /dev/null
+++ b/src/util/crypto_crc.c
@@ -0,0 +1,106 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2006 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 2, 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 For the actual CRC code:
21 Copyright abandoned; this code is in the public domain.
22 Provided to GNUnet by peter@horizon.com
23*/
24
25/**
26 * @file util/crypto_crc.c
27 * @brief implementation of CRC32
28 * @author Christian Grothoff
29 */
30
31#include "platform.h"
32#include "gnunet_common.h"
33#include "gnunet_crypto_lib.h"
34
35/* Avoid wasting space on 8-byte longs. */
36#if UINT_MAX >= 0xffffffff
37typedef unsigned int uLong;
38#elif ULONG_MAX >= 0xffffffff
39typedef unsigned long uLong;
40#else
41#error This compiler is not ANSI-compliant!
42#endif
43
44#define Z_NULL 0
45
46
47#define POLYNOMIAL (uLong)0xedb88320
48static uLong crc_table[256];
49
50/*
51 * This routine writes each crc_table entry exactly once,
52 * with the ccorrect final value. Thus, it is safe to call
53 * even on a table that someone else is using concurrently.
54 */
55void __attribute__ ((constructor)) GNUNET_CRYPTO_crc_init ()
56{
57 unsigned int i, j;
58 uLong h = 1;
59 crc_table[0] = 0;
60 for (i = 128; i; i >>= 1)
61 {
62 h = (h >> 1) ^ ((h & 1) ? POLYNOMIAL : 0);
63 /* h is now crc_table[i] */
64 for (j = 0; j < 256; j += 2 * i)
65 crc_table[i + j] = crc_table[j] ^ h;
66 }
67}
68
69/*
70 * This computes the standard preset and inverted CRC, as used
71 * by most networking standards. Start by passing in an initial
72 * chaining value of 0, and then pass in the return value from the
73 * previous crc32() call. The final return value is the CRC.
74 * Note that this is a little-endian CRC, which is best used with
75 * data transmitted lsbit-first, and it should, itself, be appended
76 * to data in little-endian byte and bit order to preserve the
77 * property of detecting all burst errors of length 32 bits or less.
78 */
79static uLong
80crc32 (uLong crc, const char *buf, size_t len)
81{
82 GNUNET_assert (crc_table[255] != 0);
83 crc ^= 0xffffffff;
84 while (len--)
85 crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
86 return crc ^ 0xffffffff;
87}
88
89
90/**
91 * Compute the CRC32 checksum for the first len bytes of the buffer.
92 *
93 * @param buf the data over which we're taking the CRC
94 * @param len the length of the buffer
95 * @return the resulting CRC32 checksum
96 */
97int
98GNUNET_CRYPTO_crc32_n (const void *buf, unsigned int len)
99{
100 uLong crc;
101 crc = crc32 (0L, Z_NULL, 0);
102 crc = crc32 (crc, (char *) buf, len);
103 return crc;
104}
105
106/* end of crc32.c */
diff --git a/src/util/crypto_hash.c b/src/util/crypto_hash.c
new file mode 100644
index 000000000..139496eac
--- /dev/null
+++ b/src/util/crypto_hash.c
@@ -0,0 +1,791 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009 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 2, 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 SHA-512 code by Jean-Luc Cooke <jlcooke@certainkey.com>
21
22 Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
23 Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
24 Copyright (c) 2003 Kyle McMartin <kyle@debian.org>
25*/
26
27/**
28 * @file util/crypto_hash.c
29 * @brief SHA-512 GNUNET_CRYPTO_hash related functions
30 * @author Christian Grothoff
31 */
32
33#include "platform.h"
34#include "gnunet_common.h"
35#include "gnunet_crypto_lib.h"
36#include "gnunet_disk_lib.h"
37
38#define SHA512_DIGEST_SIZE 64
39#define SHA512_HMAC_BLOCK_SIZE 128
40
41struct sha512_ctx
42{
43 unsigned long long state[8];
44 unsigned int count[4];
45 unsigned char buf[128];
46};
47
48static unsigned long long
49Ch (unsigned long long x, unsigned long long y, unsigned long long z)
50{
51 return z ^ (x & (y ^ z));
52}
53
54static unsigned long long
55Maj (unsigned long long x, unsigned long long y, unsigned long long z)
56{
57 return (x & y) | (z & (x | y));
58}
59
60static unsigned long long
61RORu64 (unsigned long long x, unsigned long long y)
62{
63 return (x >> y) | (x << (64 - y));
64}
65
66const unsigned long long sha512_K[80] = {
67 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
68 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
69 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
70 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
71 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
72 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
73 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
74 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
75 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
76 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
77 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
78 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
79 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
80 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
81 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
82 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
83 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
84 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
85 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
86 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
87 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
88 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
89 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
90 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
91 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
92 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
93 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
94};
95
96#define e0(x) (RORu64(x,28) ^ RORu64(x,34) ^ RORu64(x,39))
97#define e1(x) (RORu64(x,14) ^ RORu64(x,18) ^ RORu64(x,41))
98#define s0(x) (RORu64(x, 1) ^ RORu64(x, 8) ^ (x >> 7))
99#define s1(x) (RORu64(x,19) ^ RORu64(x,61) ^ (x >> 6))
100
101/* H* initial state for SHA-512 */
102#define H0 0x6a09e667f3bcc908ULL
103#define H1 0xbb67ae8584caa73bULL
104#define H2 0x3c6ef372fe94f82bULL
105#define H3 0xa54ff53a5f1d36f1ULL
106#define H4 0x510e527fade682d1ULL
107#define H5 0x9b05688c2b3e6c1fULL
108#define H6 0x1f83d9abfb41bd6bULL
109#define H7 0x5be0cd19137e2179ULL
110
111/* H'* initial state for SHA-384 */
112#define HP0 0xcbbb9d5dc1059ed8ULL
113#define HP1 0x629a292a367cd507ULL
114#define HP2 0x9159015a3070dd17ULL
115#define HP3 0x152fecd8f70e5939ULL
116#define HP4 0x67332667ffc00b31ULL
117#define HP5 0x8eb44a8768581511ULL
118#define HP6 0xdb0c2e0d64f98fa7ULL
119#define HP7 0x47b5481dbefa4fa4ULL
120
121#define LOAD_OP(t1, I, W, input) \
122 t1 = input[(8*I) ] & 0xff;\
123 t1 <<= 8;\
124 t1 |= input[(8*I)+1] & 0xff;\
125 t1 <<= 8;\
126 t1 |= input[(8*I)+2] & 0xff;\
127 t1 <<= 8;\
128 t1 |= input[(8*I)+3] & 0xff;\
129 t1 <<= 8;\
130 t1 |= input[(8*I)+4] & 0xff;\
131 t1 <<= 8;\
132 t1 |= input[(8*I)+5] & 0xff;\
133 t1 <<= 8;\
134 t1 |= input[(8*I)+6] & 0xff;\
135 t1 <<= 8;\
136 t1 |= input[(8*I)+7] & 0xff;\
137 W[I] = t1;
138
139
140#define BLEND_OP(I, W) \
141 W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
142
143static void
144sha512_transform (unsigned long long *state, const unsigned char *input)
145{
146 unsigned long long a, b, c, d, e, f, g, h, t1, t2;
147 unsigned long long W[80];
148 unsigned long long t0;
149 int i;
150
151 /* load the input */
152 for (i = 0; i < 16; i++)
153 {
154 LOAD_OP (t0, i, W, input);
155 }
156
157 for (i = 16; i < 80; i++)
158 {
159 BLEND_OP (i, W);
160 }
161
162 /* load the state into our registers */
163 a = state[0];
164 b = state[1];
165 c = state[2];
166 d = state[3];
167 e = state[4];
168 f = state[5];
169 g = state[6];
170 h = state[7];
171
172 /* now iterate */
173 for (i = 0; i < 80; i += 8)
174 {
175 t1 = h + e1 (e) + Ch (e, f, g) + sha512_K[i] + W[i];
176 t2 = e0 (a) + Maj (a, b, c);
177 d += t1;
178 h = t1 + t2;
179 t1 = g + e1 (d) + Ch (d, e, f) + sha512_K[i + 1] + W[i + 1];
180 t2 = e0 (h) + Maj (h, a, b);
181 c += t1;
182 g = t1 + t2;
183 t1 = f + e1 (c) + Ch (c, d, e) + sha512_K[i + 2] + W[i + 2];
184 t2 = e0 (g) + Maj (g, h, a);
185 b += t1;
186 f = t1 + t2;
187 t1 = e + e1 (b) + Ch (b, c, d) + sha512_K[i + 3] + W[i + 3];
188 t2 = e0 (f) + Maj (f, g, h);
189 a += t1;
190 e = t1 + t2;
191 t1 = d + e1 (a) + Ch (a, b, c) + sha512_K[i + 4] + W[i + 4];
192 t2 = e0 (e) + Maj (e, f, g);
193 h += t1;
194 d = t1 + t2;
195 t1 = c + e1 (h) + Ch (h, a, b) + sha512_K[i + 5] + W[i + 5];
196 t2 = e0 (d) + Maj (d, e, f);
197 g += t1;
198 c = t1 + t2;
199 t1 = b + e1 (g) + Ch (g, h, a) + sha512_K[i + 6] + W[i + 6];
200 t2 = e0 (c) + Maj (c, d, e);
201 f += t1;
202 b = t1 + t2;
203 t1 = a + e1 (f) + Ch (f, g, h) + sha512_K[i + 7] + W[i + 7];
204 t2 = e0 (b) + Maj (b, c, d);
205 e += t1;
206 a = t1 + t2;
207 }
208
209 state[0] += a;
210 state[1] += b;
211 state[2] += c;
212 state[3] += d;
213 state[4] += e;
214 state[5] += f;
215 state[6] += g;
216 state[7] += h;
217
218 /* erase our data */
219 a = b = c = d = e = f = g = h = t1 = t2 = 0;
220 memset (W, 0, 80 * sizeof (unsigned long long));
221}
222
223static void
224sha512_init (struct sha512_ctx *sctx)
225{
226 sctx->state[0] = H0;
227 sctx->state[1] = H1;
228 sctx->state[2] = H2;
229 sctx->state[3] = H3;
230 sctx->state[4] = H4;
231 sctx->state[5] = H5;
232 sctx->state[6] = H6;
233 sctx->state[7] = H7;
234 sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0;
235 memset (sctx->buf, 0, sizeof (sctx->buf));
236}
237
238static void
239sha512_update (struct sha512_ctx *sctx,
240 const unsigned char *data, unsigned int len)
241{
242 unsigned int i, index, part_len;
243
244 /* Compute number of bytes mod 128 */
245 index = (unsigned int) ((sctx->count[0] >> 3) & 0x7F);
246
247 /* Update number of bits */
248 if ((sctx->count[0] += (len << 3)) < (len << 3))
249 {
250 if ((sctx->count[1] += 1) < 1)
251 if ((sctx->count[2] += 1) < 1)
252 sctx->count[3]++;
253 sctx->count[1] += (len >> 29);
254 }
255
256 part_len = 128 - index;
257
258 /* Transform as many times as possible. */
259 if (len >= part_len)
260 {
261 memcpy (&sctx->buf[index], data, part_len);
262 sha512_transform (sctx->state, sctx->buf);
263
264 for (i = part_len; i + 127 < len; i += 128)
265 sha512_transform (sctx->state, &data[i]);
266
267 index = 0;
268 }
269 else
270 {
271 i = 0;
272 }
273
274 /* Buffer remaining input */
275 memcpy (&sctx->buf[index], &data[i], len - i);
276}
277
278static void
279sha512_final (struct sha512_ctx *sctx, unsigned char *hash)
280{
281 static unsigned char padding[128] = { 0x80, };
282
283 unsigned int t;
284 unsigned long long t2;
285 unsigned char bits[128];
286 unsigned int index, pad_len;
287 int i, j;
288
289 index = pad_len = t = i = j = 0;
290 t2 = 0;
291
292 /* Save number of bits */
293 t = sctx->count[0];
294 bits[15] = t;
295 t >>= 8;
296 bits[14] = t;
297 t >>= 8;
298 bits[13] = t;
299 t >>= 8;
300 bits[12] = t;
301 t = sctx->count[1];
302 bits[11] = t;
303 t >>= 8;
304 bits[10] = t;
305 t >>= 8;
306 bits[9] = t;
307 t >>= 8;
308 bits[8] = t;
309 t = sctx->count[2];
310 bits[7] = t;
311 t >>= 8;
312 bits[6] = t;
313 t >>= 8;
314 bits[5] = t;
315 t >>= 8;
316 bits[4] = t;
317 t = sctx->count[3];
318 bits[3] = t;
319 t >>= 8;
320 bits[2] = t;
321 t >>= 8;
322 bits[1] = t;
323 t >>= 8;
324 bits[0] = t;
325
326 /* Pad out to 112 mod 128. */
327 index = (sctx->count[0] >> 3) & 0x7f;
328 pad_len = (index < 112) ? (112 - index) : ((128 + 112) - index);
329 sha512_update (sctx, padding, pad_len);
330
331 /* Append length (before padding) */
332 sha512_update (sctx, bits, 16);
333
334 /* Store state in digest */
335 for (i = j = 0; i < 8; i++, j += 8)
336 {
337 t2 = sctx->state[i];
338 hash[j + 7] = (char) t2 & 0xff;
339 t2 >>= 8;
340 hash[j + 6] = (char) t2 & 0xff;
341 t2 >>= 8;
342 hash[j + 5] = (char) t2 & 0xff;
343 t2 >>= 8;
344 hash[j + 4] = (char) t2 & 0xff;
345 t2 >>= 8;
346 hash[j + 3] = (char) t2 & 0xff;
347 t2 >>= 8;
348 hash[j + 2] = (char) t2 & 0xff;
349 t2 >>= 8;
350 hash[j + 1] = (char) t2 & 0xff;
351 t2 >>= 8;
352 hash[j] = (char) t2 & 0xff;
353 }
354
355 /* Zeroize sensitive information. */
356 memset (sctx, 0, sizeof (struct sha512_ctx));
357}
358
359/**
360 * Hash block of given size.
361 *
362 * @param block the data to GNUNET_CRYPTO_hash, length is given as a second argument
363 * @param size the length of the data to GNUNET_CRYPTO_hash
364 * @param ret pointer to where to write the hashcode
365 */
366void
367GNUNET_CRYPTO_hash (const void *block, unsigned int size,
368 GNUNET_HashCode * ret)
369{
370 struct sha512_ctx ctx;
371
372 sha512_init (&ctx);
373 sha512_update (&ctx, block, size);
374 sha512_final (&ctx, (unsigned char *) ret);
375}
376
377
378/**
379 * Context used when hashing a file.
380 */
381struct FileHashContext
382{
383
384 /**
385 * Function to call upon completion.
386 */
387 GNUNET_CRYPTO_HashCompletedCallback callback;
388
389 /**
390 * Closure for callback.
391 */
392 void *callback_cls;
393
394 /**
395 * IO buffer.
396 */
397 unsigned char *buffer;
398
399 /**
400 * Name of the file we are hashing.
401 */
402 char *filename;
403
404 /**
405 * Cummulated hash.
406 */
407 struct sha512_ctx hctx;
408
409 /**
410 * Blocksize.
411 */
412 size_t bsize;
413
414 /**
415 * Size of the file.
416 */
417 unsigned long long fsize;
418
419 /**
420 * Current offset.
421 */
422 unsigned long long offset;
423
424 /**
425 * Run on shutdown?
426 */
427 int run_on_shutdown;
428
429 /**
430 * File descriptor.
431 */
432 int fd;
433
434};
435
436
437/**
438 * Report result of hash computation to callback
439 * and free associated resources.
440 */
441static void
442file_hash_finish (struct FileHashContext *fhc, const GNUNET_HashCode * res)
443{
444 fhc->callback (fhc->callback_cls, res);
445 GNUNET_free (fhc->filename);
446 if (fhc->fd != -1)
447 GNUNET_break (0 == CLOSE (fhc->fd));
448 GNUNET_free (fhc); /* also frees fhc->buffer */
449}
450
451
452/**
453 * File hashing task.
454 *
455 * @param cls closure
456 * @param tc context
457 */
458static void
459file_hash_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
460{
461 struct FileHashContext *fhc = cls;
462 GNUNET_HashCode res;
463 size_t delta;
464
465 GNUNET_assert (fhc->offset < fhc->fsize);
466 delta = fhc->bsize;
467 if (fhc->fsize - fhc->offset < delta)
468 delta = fhc->fsize - fhc->offset;
469 if (delta != READ (fhc->fd, fhc->buffer, delta))
470 {
471 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
472 "read", fhc->filename);
473 file_hash_finish (fhc, NULL);
474 return;
475 }
476 sha512_update (&fhc->hctx, fhc->buffer, delta);
477 fhc->offset += delta;
478 if (fhc->offset == fhc->fsize)
479 {
480 sha512_final (&fhc->hctx, (unsigned char *) &res);
481 file_hash_finish (fhc, &res);
482 return;
483 }
484 GNUNET_SCHEDULER_add_after (tc->sched,
485 fhc->run_on_shutdown,
486 GNUNET_SCHEDULER_PRIORITY_KEEP,
487 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
488 &file_hash_task, fhc);
489}
490
491
492/**
493 * Compute the hash of an entire file.
494 *
495 * @param sched scheduler to use
496 * @param priority scheduling priority to use
497 * @param run_on_shutdown should we complete even on shutdown?
498 * @param filename name of file to hash
499 * @param blocksize number of bytes to process in one task
500 * @param callback function to call upon completion
501 * @param callback_cls closure for callback
502 */
503void
504GNUNET_CRYPTO_hash_file (struct GNUNET_SCHEDULER_Handle *sched,
505 enum GNUNET_SCHEDULER_Priority priority,
506 int run_on_shutdown,
507 const char *filename,
508 size_t blocksize,
509 GNUNET_CRYPTO_HashCompletedCallback callback,
510 void *callback_cls)
511{
512 struct FileHashContext *fhc;
513
514 GNUNET_assert (blocksize > 0);
515 fhc = GNUNET_malloc (sizeof (struct FileHashContext) + blocksize);
516 fhc->callback = callback;
517 fhc->callback_cls = callback_cls;
518 fhc->buffer = (unsigned char *) &fhc[1];
519 fhc->filename = GNUNET_strdup (filename);
520 fhc->fd = -1;
521 sha512_init (&fhc->hctx);
522 fhc->bsize = blocksize;
523 if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fhc->fsize, GNUNET_NO))
524 {
525 file_hash_finish (fhc, NULL);
526 return;
527 }
528 fhc->run_on_shutdown = run_on_shutdown;
529 fhc->fd = GNUNET_DISK_file_open (filename, O_RDONLY | O_LARGEFILE);
530 if (fhc->fd == -1)
531 {
532 file_hash_finish (fhc, NULL);
533 return;
534 }
535 GNUNET_SCHEDULER_add_after (sched,
536 run_on_shutdown,
537 priority,
538 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
539 &file_hash_task, fhc);
540}
541
542
543/* ***************** binary-ASCII encoding *************** */
544
545/**
546 * 32 characters for encoding (GNUNET_CRYPTO_hash => 32 characters)
547 */
548static char *encTable__ = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
549
550static unsigned int
551getValue__ (unsigned char a)
552{
553 if ((a >= '0') && (a <= '9'))
554 return a - '0';
555 if ((a >= 'A') && (a <= 'V'))
556 return (a - 'A' + 10);
557 return -1;
558}
559
560/**
561 * Convert GNUNET_CRYPTO_hash to ASCII encoding. The ASCII encoding is rather
562 * GNUnet specific. It was chosen such that it only uses characters
563 * in [0-9A-V], can be produced without complex arithmetics and uses a
564 * small number of characters. The GNUnet encoding uses 102
565 * characters plus a null terminator.
566 *
567 * @param block the GNUNET_CRYPTO_hash code
568 * @param result where to store the encoding (struct GNUNET_CRYPTO_HashAsciiEncoded can be
569 * safely cast to char*, a '\0' termination is set).
570 */
571void
572GNUNET_CRYPTO_hash_to_enc (const GNUNET_HashCode * block,
573 struct GNUNET_CRYPTO_HashAsciiEncoded *result)
574{
575 unsigned int wpos;
576 unsigned int rpos;
577 unsigned int bits;
578 unsigned int vbit;
579
580 GNUNET_assert (block != NULL);
581 GNUNET_assert (result != NULL);
582 vbit = 0;
583 wpos = 0;
584 rpos = 0;
585 bits = 0;
586 while ((rpos < sizeof (GNUNET_HashCode)) || (vbit > 0))
587 {
588 if ((rpos < sizeof (GNUNET_HashCode)) && (vbit < 5))
589 {
590 bits = (bits << 8) | ((unsigned char *) block)[rpos++]; /* eat 8 more bits */
591 vbit += 8;
592 }
593 if (vbit < 5)
594 {
595 bits <<= (5 - vbit); /* zero-padding */
596 GNUNET_assert (vbit == 2); /* padding by 3: 512+3 mod 5 == 0 */
597 vbit = 5;
598 }
599 GNUNET_assert (wpos <
600 sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1);
601 result->encoding[wpos++] = encTable__[(bits >> (vbit - 5)) & 31];
602 vbit -= 5;
603 }
604 GNUNET_assert (wpos == sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1);
605 GNUNET_assert (vbit == 0);
606 result->encoding[wpos] = '\0';
607}
608
609/**
610 * Convert ASCII encoding back to GNUNET_CRYPTO_hash
611 *
612 * @param enc the encoding
613 * @param result where to store the GNUNET_CRYPTO_hash code
614 * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding
615 */
616int
617GNUNET_CRYPTO_hash_from_string (const char *enc, GNUNET_HashCode * result)
618{
619 unsigned int rpos;
620 unsigned int wpos;
621 unsigned int bits;
622 unsigned int vbit;
623
624 if (strlen (enc) != sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1)
625 return GNUNET_SYSERR;
626
627 vbit = 2; /* padding! */
628 wpos = sizeof (GNUNET_HashCode);
629 rpos = sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1;
630 bits = getValue__ (enc[--rpos]) >> 3;
631 while (wpos > 0)
632 {
633 GNUNET_assert (rpos > 0);
634 bits = (getValue__ (enc[--rpos]) << vbit) | bits;
635 vbit += 5;
636 if (vbit >= 8)
637 {
638 ((unsigned char *) result)[--wpos] = (unsigned char) bits;
639 bits >>= 8;
640 vbit -= 8;
641 }
642 }
643 GNUNET_assert (rpos == 0);
644 GNUNET_assert (vbit == 0);
645 return GNUNET_OK;
646}
647
648/**
649 * Compute the distance between 2 hashcodes. The computation must be
650 * fast, not involve bits[0] or bits[4] (they're used elsewhere), and be
651 * somewhat consistent. And of course, the result should be a positive
652 * number.
653 *
654 * @returns a positive number which is a measure for
655 * hashcode proximity.
656 */
657unsigned int
658GNUNET_CRYPTO_hash_distance_u32 (const GNUNET_HashCode * a,
659 const GNUNET_HashCode * b)
660{
661 unsigned int x1 = (a->bits[1] - b->bits[1]) >> 16;
662 unsigned int x2 = (b->bits[1] - a->bits[1]) >> 16;
663 return (x1 * x2);
664}
665
666void
667GNUNET_CRYPTO_hash_create_random (GNUNET_HashCode * result)
668{
669 int i;
670 for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0;
671 i--)
672 result->bits[i] = rand ();
673}
674
675void
676GNUNET_CRYPTO_hash_difference (const GNUNET_HashCode * a,
677 const GNUNET_HashCode * b,
678 GNUNET_HashCode * result)
679{
680 int i;
681 for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0;
682 i--)
683 result->bits[i] = b->bits[i] - a->bits[i];
684}
685
686void
687GNUNET_CRYPTO_hash_sum (const GNUNET_HashCode * a,
688 const GNUNET_HashCode * delta,
689 GNUNET_HashCode * result)
690{
691 int i;
692 for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0;
693 i--)
694 result->bits[i] = delta->bits[i] + a->bits[i];
695}
696
697void
698GNUNET_CRYPTO_hash_xor (const GNUNET_HashCode * a,
699 const GNUNET_HashCode * b, GNUNET_HashCode * result)
700{
701 int i;
702 for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0;
703 i--)
704 result->bits[i] = a->bits[i] ^ b->bits[i];
705}
706
707/**
708 * Convert a hashcode into a key.
709 */
710void
711GNUNET_CRYPTO_hash_to_AES_key (const GNUNET_HashCode * hc,
712 struct GNUNET_CRYPTO_AesSessionKey *skey,
713 struct GNUNET_CRYPTO_AesInitializationVector
714 *iv)
715{
716 GNUNET_assert (sizeof (GNUNET_HashCode) >=
717 GNUNET_CRYPTO_AES_KEY_LENGTH +
718 sizeof (struct GNUNET_CRYPTO_AesInitializationVector));
719 memcpy (skey, hc, GNUNET_CRYPTO_AES_KEY_LENGTH);
720 skey->crc32 =
721 htonl (GNUNET_CRYPTO_crc32_n (skey, GNUNET_CRYPTO_AES_KEY_LENGTH));
722 memcpy (iv, &((char *) hc)[GNUNET_CRYPTO_AES_KEY_LENGTH],
723 sizeof (struct GNUNET_CRYPTO_AesInitializationVector));
724}
725
726/**
727 * Obtain a bit from a hashcode.
728 * @param code the GNUNET_CRYPTO_hash to index bit-wise
729 * @param bit index into the hashcode, [0...511]
730 * @return Bit \a bit from hashcode \a code, -1 for invalid index
731 */
732int
733GNUNET_CRYPTO_hash_get_bit (const GNUNET_HashCode * code, unsigned int bit)
734{
735 GNUNET_assert (bit < 8 * sizeof (GNUNET_HashCode));
736 return (((unsigned char *) code)[bit >> 3] & (1 << (bit & 7))) > 0;
737}
738
739/**
740 * Compare function for HashCodes, producing a total ordering
741 * of all hashcodes.
742 * @return 1 if h1 > h2, -1 if h1 < h2 and 0 if h1 == h2.
743 */
744int
745GNUNET_CRYPTO_hash_cmp (const GNUNET_HashCode * h1,
746 const GNUNET_HashCode * h2)
747{
748 unsigned int *i1;
749 unsigned int *i2;
750 int i;
751
752 i1 = (unsigned int *) h1;
753 i2 = (unsigned int *) h2;
754 for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0;
755 i--)
756 {
757 if (i1[i] > i2[i])
758 return 1;
759 if (i1[i] < i2[i])
760 return -1;
761 }
762 return 0;
763}
764
765/**
766 * Find out which of the two GNUNET_CRYPTO_hash codes is closer to target
767 * in the XOR metric (Kademlia).
768 * @return -1 if h1 is closer, 1 if h2 is closer and 0 if h1==h2.
769 */
770int
771GNUNET_CRYPTO_hash_xorcmp (const GNUNET_HashCode * h1,
772 const GNUNET_HashCode * h2,
773 const GNUNET_HashCode * target)
774{
775 int i;
776 unsigned int d1;
777 unsigned int d2;
778
779 for (i = sizeof (GNUNET_HashCode) / sizeof (unsigned int) - 1; i >= 0; i--)
780 {
781 d1 = ((unsigned int *) h1)[i] ^ ((unsigned int *) target)[i];
782 d2 = ((unsigned int *) h2)[i] ^ ((unsigned int *) target)[i];
783 if (d1 > d2)
784 return 1;
785 else if (d1 < d2)
786 return -1;
787 }
788 return 0;
789}
790
791/* end of hashing.c */
diff --git a/src/util/crypto_ksk.c b/src/util/crypto_ksk.c
new file mode 100644
index 000000000..c3461ae61
--- /dev/null
+++ b/src/util/crypto_ksk.c
@@ -0,0 +1,791 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 1994, 1996, 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
4 Copyright (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
5
6 GNUnet is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 2, or (at your
9 option) any later version.
10
11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNUnet; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20
21 Note: This code is based on code from libgcrypt
22 The code was adapted for GNUnet to support RSA-key generation
23 based on weak, pseudo-random keys. Do NOT use to generate
24 ordinary RSA keys!
25*/
26
27
28/**
29 * @file util/crypto_ksk.c
30 * @brief implementation of RSA-Key generation for KBlocks
31 * (do NOT use for pseudonyms or hostkeys!)
32 * @author Christian Grothoff
33 */
34
35#include "platform.h"
36#include "gnunet_common.h"
37#include "gnunet_crypto_lib.h"
38#include <gmp.h>
39#include <gcrypt.h>
40
41/**
42 * Log an error message at log-level 'level' that indicates
43 * a failure of the command 'cmd' with the message given
44 * by gcry_strerror(rc).
45 */
46#define LOG_GCRY(level, cmd, rc) do { GNUNET_log(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0);
47
48
49typedef struct
50{
51 mpz_t n; /* public modulus */
52 mpz_t e; /* public exponent */
53 mpz_t d; /* exponent */
54 mpz_t p; /* prime p. */
55 mpz_t q; /* prime q. */
56 mpz_t u; /* inverse of p mod q. */
57} KBlock_secret_key;
58
59/**
60 * The private information of an RSA key pair.
61 * NOTE: this must match the definition in crypto_rsa.c
62 */
63struct GNUNET_CRYPTO_RsaPrivateKey
64{
65 gcry_sexp_t sexp;
66};
67
68
69/* Note: 2 is not included because it can be tested more easily by
70 looking at bit 0. The last entry in this list is marked by a zero */
71static uint16_t small_prime_numbers[] = {
72 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
73 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
74 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
75 157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
76 211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
77 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
78 331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
79 389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
80 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
81 509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
82 587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
83 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
84 709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
85 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
86 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
87 919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
88 991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
89 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
90 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
91 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
92 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
93 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
94 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
95 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
96 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
97 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
98 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
99 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
100 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
101 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
102 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
103 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
104 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
105 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
106 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
107 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
108 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
109 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
110 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
111 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
112 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
113 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
114 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
115 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
116 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
117 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
118 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
119 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
120 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
121 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
122 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
123 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
124 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
125 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
126 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
127 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
128 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
129 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
130 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
131 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
132 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
133 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
134 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
135 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
136 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
137 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
138 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
139 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
140 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
141 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
142 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
143 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
144 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
145 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
146 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
147 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
148 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
149 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
150 4957, 4967, 4969, 4973, 4987, 4993, 4999,
151 0
152};
153
154#define DIM(v) (sizeof(v)/sizeof((v)[0]))
155static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1;
156
157
158 static unsigned int
159 get_nbits (mpz_t a)
160{
161 return mpz_sizeinbase (a, 2);
162}
163
164/**
165 * Count the number of zerobits at the low end of A
166 */
167static unsigned int
168get_trailing_zeros (mpz_t a)
169{
170 unsigned int count = 0;
171 unsigned int nbits = get_nbits (a);
172
173 while ((mpz_tstbit (a, count)) && (count < nbits))
174 count++;
175 return count;
176}
177
178/**
179 * Set bit N of A. and clear all bits above
180 */
181static void
182set_highbit (mpz_t a, unsigned int n)
183{
184 unsigned int nbits;
185
186 nbits = get_nbits (a);
187 while (nbits > n)
188 mpz_clrbit (a, nbits--);
189 mpz_setbit (a, n);
190}
191
192static void
193mpz_randomize (mpz_t n, unsigned int nbits, GNUNET_HashCode * rnd)
194{
195 GNUNET_HashCode *tmp;
196 int cnt;
197 int i;
198
199 cnt = (nbits / sizeof (GNUNET_HashCode) / 8) + 1;
200 tmp = GNUNET_malloc (sizeof (GNUNET_HashCode) * cnt);
201
202 tmp[0] = *rnd;
203 for (i = 0; i < cnt - 1; i++)
204 {
205 GNUNET_CRYPTO_hash (&tmp[i], sizeof (GNUNET_HashCode), &tmp[i + 1]);
206 }
207 *rnd = tmp[cnt - 1];
208 mpz_import (n, cnt * sizeof (GNUNET_HashCode) / sizeof (unsigned int),
209 1, sizeof (unsigned int), 1, 0, tmp);
210 GNUNET_free (tmp);
211 i = get_nbits (n);
212 while (i > nbits)
213 mpz_clrbit (n, i--);
214}
215
216/**
217 * Return true if n is probably a prime
218 */
219static int
220is_prime (mpz_t n, int steps, GNUNET_HashCode * hc)
221{
222 mpz_t x;
223 mpz_t y;
224 mpz_t z;
225 mpz_t nminus1;
226 mpz_t a2;
227 mpz_t q;
228 unsigned int i, j, k;
229 int rc = 0;
230 unsigned int nbits;
231
232 mpz_init (x);
233 mpz_init (y);
234 mpz_init (z);
235 mpz_init (nminus1);
236 mpz_init_set_ui (a2, 2);
237 nbits = get_nbits (n);
238 mpz_sub_ui (nminus1, n, 1);
239
240 /* Find q and k, so that n = 1 + 2^k * q . */
241 mpz_init_set (q, nminus1);
242 k = get_trailing_zeros (q);
243 mpz_tdiv_q_2exp (q, q, k);
244
245 for (i = 0; i < steps; i++)
246 {
247 if (!i)
248 {
249 mpz_set_ui (x, 2);
250 }
251 else
252 {
253 mpz_randomize (x, nbits, hc);
254
255 /* Make sure that the number is smaller than the prime and
256 keep the randomness of the high bit. */
257 if (mpz_tstbit (x, nbits - 2))
258 {
259 set_highbit (x, nbits - 2); /* Clear all higher bits. */
260 }
261 else
262 {
263 set_highbit (x, nbits - 2);
264 mpz_clrbit (x, nbits - 2);
265 }
266 GNUNET_assert (mpz_cmp (x, nminus1) < 0 && mpz_cmp_ui (x, 1) > 0);
267 }
268 mpz_powm (y, x, q, n);
269 if (mpz_cmp_ui (y, 1) && mpz_cmp (y, nminus1))
270 {
271 for (j = 1; j < k && mpz_cmp (y, nminus1); j++)
272 {
273 mpz_powm (y, y, a2, n);
274 if (!mpz_cmp_ui (y, 1))
275 goto leave; /* Not a prime. */
276 }
277 if (mpz_cmp (y, nminus1))
278 goto leave; /* Not a prime. */
279 }
280 }
281 rc = 1; /* May be a prime. */
282
283leave:
284 mpz_clear (x);
285 mpz_clear (y);
286 mpz_clear (z);
287 mpz_clear (nminus1);
288 mpz_clear (q);
289 mpz_clear (a2);
290
291 return rc;
292}
293
294static void
295gen_prime (mpz_t ptest, unsigned int nbits, GNUNET_HashCode * hc)
296{
297 mpz_t prime, pminus1, val_2, val_3, result;
298 int i;
299 unsigned x, step;
300 int *mods;
301 mpz_t tmp;
302
303 GNUNET_assert (nbits >= 16);
304
305 mods = GNUNET_malloc (no_of_small_prime_numbers * sizeof (*mods));
306 /* Make nbits fit into mpz_t implementation. */
307 mpz_init_set_ui (val_2, 2);
308 mpz_init_set_ui (val_3, 3);
309 mpz_init (prime);
310 mpz_init (result);
311 mpz_init (pminus1);
312 mpz_init (ptest);
313 while (1)
314 {
315 /* generate a random number */
316 mpz_randomize (prime, nbits, hc);
317 /* Set high order bit to 1, set low order bit to 1. If we are
318 generating a secret prime we are most probably doing that
319 for RSA, to make sure that the modulus does have the
320 requested key size we set the 2 high order bits. */
321 set_highbit (prime, nbits - 1);
322 mpz_setbit (prime, nbits - 2);
323 mpz_setbit (prime, 0);
324
325 /* Calculate all remainders. */
326 mpz_init (tmp);
327 for (i = 0; (x = small_prime_numbers[i]); i++)
328 mods[i] = mpz_fdiv_r_ui (tmp, prime, x);
329 mpz_clear (tmp);
330 /* Now try some primes starting with prime. */
331 for (step = 0; step < 20000; step += 2)
332 {
333 /* Check against all the small primes we have in mods. */
334 for (i = 0; (x = small_prime_numbers[i]); i++)
335 {
336 while (mods[i] + step >= x)
337 mods[i] -= x;
338 if (!(mods[i] + step))
339 break;
340 }
341 if (x)
342 continue; /* Found a multiple of an already known prime. */
343
344 mpz_add_ui (ptest, prime, step);
345 if (!mpz_tstbit (ptest, nbits - 2))
346 break;
347
348 /* Do a fast Fermat test now. */
349 mpz_sub_ui (pminus1, ptest, 1);
350 mpz_powm (result, val_2, pminus1, ptest);
351 if ((!mpz_cmp_ui (result, 1)) && (is_prime (ptest, 5, hc)))
352 {
353 /* Got it. */
354 mpz_clear (val_2);
355 mpz_clear (val_3);
356 mpz_clear (result);
357 mpz_clear (pminus1);
358 mpz_clear (prime);
359 GNUNET_free (mods);
360 return;
361 }
362 }
363 }
364}
365
366/**
367 * Find the greatest common divisor G of A and B.
368 * Return: 1 if this 1, 0 in all other cases
369 */
370static int
371test_gcd (mpz_t g, mpz_t xa, mpz_t xb)
372{
373 mpz_t a, b;
374
375 mpz_init_set (a, xa);
376 mpz_init_set (b, xb);
377
378 /* TAOCP Vol II, 4.5.2, Algorithm A */
379 while (mpz_cmp_ui (b, 0))
380 {
381 mpz_fdiv_r (g, a, b); /* g used as temorary variable */
382 mpz_set (a, b);
383 mpz_set (b, g);
384 }
385 mpz_set (g, a);
386
387 mpz_clear (a);
388 mpz_clear (b);
389 return (0 == mpz_cmp_ui (g, 1));
390}
391
392/**
393 * Generate a key pair with a key of size NBITS.
394 * @param sk where to store the key
395 * @param nbits the number of bits to use
396 * @param hc the HC to use for PRNG (modified!)
397 */
398static void
399generate_kblock_key (KBlock_secret_key * sk,
400 unsigned int nbits, GNUNET_HashCode * hc)
401{
402 mpz_t t1, t2;
403 mpz_t phi; /* helper: (p-1)(q-1) */
404 mpz_t g;
405 mpz_t f;
406
407 /* make sure that nbits is even so that we generate p, q of equal size */
408 if ((nbits & 1))
409 nbits++;
410
411 mpz_init_set_ui (sk->e, 257);
412 mpz_init (sk->n);
413 mpz_init (sk->p);
414 mpz_init (sk->q);
415 mpz_init (sk->d);
416 mpz_init (sk->u);
417
418 mpz_init (t1);
419 mpz_init (t2);
420 mpz_init (phi);
421 mpz_init (g);
422 mpz_init (f);
423
424 do
425 {
426 do
427 {
428 mpz_clear (sk->p);
429 mpz_clear (sk->q);
430 gen_prime (sk->p, nbits / 2, hc);
431 gen_prime (sk->q, nbits / 2, hc);
432
433 if (mpz_cmp (sk->p, sk->q) > 0) /* p shall be smaller than q (for calc of u) */
434 mpz_swap (sk->p, sk->q);
435 /* calculate the modulus */
436 mpz_mul (sk->n, sk->p, sk->q);
437 }
438 while (get_nbits (sk->n) != nbits);
439
440 /* calculate Euler totient: phi = (p-1)(q-1) */
441 mpz_sub_ui (t1, sk->p, 1);
442 mpz_sub_ui (t2, sk->q, 1);
443 mpz_mul (phi, t1, t2);
444 mpz_gcd (g, t1, t2);
445 mpz_fdiv_q (f, phi, g);
446
447 while (0 == test_gcd (t1, sk->e, phi))
448 { /* (while gcd is not 1) */
449 mpz_add_ui (sk->e, sk->e, 2);
450 }
451
452 /* calculate the secret key d = e^1 mod phi */
453 }
454 while ((0 == mpz_invert (sk->d, sk->e, f)) ||
455 (0 == mpz_invert (sk->u, sk->p, sk->q)));
456
457 mpz_clear (t1);
458 mpz_clear (t2);
459 mpz_clear (phi);
460 mpz_clear (f);
461 mpz_clear (g);
462}
463
464
465/**
466 * Internal representation of the private key.
467 */
468struct KskRsaPrivateKeyBinaryEncoded
469{
470 /**
471 * Total size of the structure, in bytes, in big-endian!
472 */
473 uint16_t len GNUNET_PACKED;
474 uint16_t sizen GNUNET_PACKED; /* in big-endian! */
475 uint16_t sizee GNUNET_PACKED; /* in big-endian! */
476 uint16_t sized GNUNET_PACKED; /* in big-endian! */
477 uint16_t sizep GNUNET_PACKED; /* in big-endian! */
478 uint16_t sizeq GNUNET_PACKED; /* in big-endian! */
479 uint16_t sizedmp1 GNUNET_PACKED; /* in big-endian! */
480 uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */
481 /* followed by the actual values */
482};
483
484
485/**
486 * Deterministically (!) create a hostkey using only the
487 * given HashCode as input to the PRNG.
488 */
489static struct KskRsaPrivateKeyBinaryEncoded *
490makeKblockKeyInternal (const GNUNET_HashCode * hc)
491{
492 KBlock_secret_key sk;
493 GNUNET_HashCode hx;
494 void *pbu[6];
495 mpz_t *pkv[6];
496 size_t sizes[6];
497 struct KskRsaPrivateKeyBinaryEncoded *retval;
498 int i;
499 size_t size;
500
501 hx = *hc;
502 generate_kblock_key (&sk, 1024, /* at least 10x as fast than 2048 bits
503 -- we simply cannot afford 2048 bits
504 even on modern hardware, and especially
505 not since clearly a dictionary attack
506 will still be much cheaper
507 than breaking a 1024 bit RSA key.
508 If an adversary can spend the time to
509 break a 1024 bit RSA key just to forge
510 a signature -- SO BE IT. [ CG, 6/2005 ] */
511 &hx);
512 pkv[0] = &sk.n;
513 pkv[1] = &sk.e;
514 pkv[2] = &sk.d;
515 pkv[3] = &sk.p;
516 pkv[4] = &sk.q;
517 pkv[5] = &sk.u;
518 size = sizeof (struct KskRsaPrivateKeyBinaryEncoded);
519 for (i = 0; i < 6; i++)
520 {
521 pbu[i] = mpz_export (NULL, &sizes[i], 1, /* most significant word first */
522 1, /* unit is bytes */
523 1, /* big endian */
524 0, /* nails */
525 *pkv[i]);
526 size += sizes[i];
527 }
528 GNUNET_assert (size < 65536);
529 retval = GNUNET_malloc (size);
530 retval->len = htons (size);
531 i = 0;
532 retval->sizen = htons (sizes[0]);
533 memcpy (&((char *) &retval[1])[i], pbu[0], sizes[0]);
534 i += sizes[0];
535 retval->sizee = htons (sizes[1]);
536 memcpy (&((char *) &retval[1])[i], pbu[1], sizes[1]);
537 i += sizes[1];
538 retval->sized = htons (sizes[2]);
539 memcpy (&((char *) &retval[1])[i], pbu[2], sizes[2]);
540 i += sizes[2];
541 /* swap p and q! */
542 retval->sizep = htons (sizes[4]);
543 memcpy (&((char *) &retval[1])[i], pbu[4], sizes[4]);
544 i += sizes[4];
545 retval->sizeq = htons (sizes[3]);
546 memcpy (&((char *) &retval[1])[i], pbu[3], sizes[3]);
547 i += sizes[3];
548 retval->sizedmp1 = htons (0);
549 retval->sizedmq1 = htons (0);
550 memcpy (&((char *) &retval[1])[i], pbu[5], sizes[5]);
551 for (i = 0; i < 6; i++)
552 {
553 mpz_clear (*pkv[i]);
554 free (pbu[i]);
555 }
556 return retval;
557}
558
559
560/**
561 * Decode the internal format into the format used
562 * by libgcrypt.
563 */
564static struct GNUNET_CRYPTO_RsaPrivateKey *
565ksk_decode_key (const struct KskRsaPrivateKeyBinaryEncoded *encoding)
566{
567 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
568 gcry_sexp_t res;
569 gcry_mpi_t n, e, d, p, q, u;
570 int rc;
571 size_t size;
572 int pos;
573
574 pos = 0;
575 size = ntohs (encoding->sizen);
576 rc = gcry_mpi_scan (&n,
577 GCRYMPI_FMT_USG,
578 &((const unsigned char *) (&encoding[1]))[pos],
579 size, &size);
580 pos += ntohs (encoding->sizen);
581 if (rc)
582 {
583 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
584 return NULL;
585 }
586 size = ntohs (encoding->sizee);
587 rc = gcry_mpi_scan (&e,
588 GCRYMPI_FMT_USG,
589 &((const unsigned char *) (&encoding[1]))[pos],
590 size, &size);
591 pos += ntohs (encoding->sizee);
592 if (rc)
593 {
594 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
595 gcry_mpi_release (n);
596 return NULL;
597 }
598 size = ntohs (encoding->sized);
599 rc = gcry_mpi_scan (&d,
600 GCRYMPI_FMT_USG,
601 &((const unsigned char *) (&encoding[1]))[pos],
602 size, &size);
603 pos += ntohs (encoding->sized);
604 if (rc)
605 {
606 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
607 gcry_mpi_release (n);
608 gcry_mpi_release (e);
609 return NULL;
610 }
611 /* swap p and q! */
612 size = ntohs (encoding->sizep);
613 if (size > 0)
614 {
615 rc = gcry_mpi_scan (&q,
616 GCRYMPI_FMT_USG,
617 &((const unsigned char *) (&encoding[1]))[pos],
618 size, &size);
619 pos += ntohs (encoding->sizep);
620 if (rc)
621 {
622 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
623 gcry_mpi_release (n);
624 gcry_mpi_release (e);
625 gcry_mpi_release (d);
626 return NULL;
627 }
628 }
629 else
630 q = NULL;
631 size = ntohs (encoding->sizeq);
632 if (size > 0)
633 {
634 rc = gcry_mpi_scan (&p,
635 GCRYMPI_FMT_USG,
636 &((const unsigned char *) (&encoding[1]))[pos],
637 size, &size);
638 pos += ntohs (encoding->sizeq);
639 if (rc)
640 {
641 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
642 gcry_mpi_release (n);
643 gcry_mpi_release (e);
644 gcry_mpi_release (d);
645 if (q != NULL)
646 gcry_mpi_release (q);
647 return NULL;
648 }
649 }
650 else
651 p = NULL;
652 pos += ntohs (encoding->sizedmp1);
653 pos += ntohs (encoding->sizedmq1);
654 size =
655 ntohs (encoding->len) - sizeof (struct KskRsaPrivateKeyBinaryEncoded) -
656 pos;
657 if (size > 0)
658 {
659 rc = gcry_mpi_scan (&u,
660 GCRYMPI_FMT_USG,
661 &((const unsigned char *) (&encoding[1]))[pos],
662 size, &size);
663 if (rc)
664 {
665 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
666 gcry_mpi_release (n);
667 gcry_mpi_release (e);
668 gcry_mpi_release (d);
669 if (p != NULL)
670 gcry_mpi_release (p);
671 if (q != NULL)
672 gcry_mpi_release (q);
673 return NULL;
674 }
675 }
676 else
677 u = NULL;
678
679 if ((p != NULL) && (q != NULL) && (u != NULL))
680 {
681 rc = gcry_sexp_build (&res, &size, /* erroff */
682 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",
683 n, e, d, p, q, u);
684 }
685 else
686 {
687 if ((p != NULL) && (q != NULL))
688 {
689 rc = gcry_sexp_build (&res, &size, /* erroff */
690 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
691 n, e, d, p, q);
692 }
693 else
694 {
695 rc = gcry_sexp_build (&res, &size, /* erroff */
696 "(private-key(rsa(n %m)(e %m)(d %m)))",
697 n, e, d);
698 }
699 }
700 gcry_mpi_release (n);
701 gcry_mpi_release (e);
702 gcry_mpi_release (d);
703 if (p != NULL)
704 gcry_mpi_release (p);
705 if (q != NULL)
706 gcry_mpi_release (q);
707 if (u != NULL)
708 gcry_mpi_release (u);
709
710 if (rc)
711 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
712#if EXTRA_CHECKS
713 if (gcry_pk_testkey (res))
714 {
715 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
716 return NULL;
717 }
718#endif
719 ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey));
720 ret->sexp = res;
721 return ret;
722}
723
724
725
726
727typedef struct
728{
729 GNUNET_HashCode hc;
730 struct KskRsaPrivateKeyBinaryEncoded *pke;
731} KBlockKeyCacheLine;
732
733static KBlockKeyCacheLine **cache;
734static unsigned int cacheSize;
735
736/**
737 * Deterministically (!) create a hostkey using only the
738 * given HashCode as input to the PRNG.
739 */
740struct GNUNET_CRYPTO_RsaPrivateKey *
741GNUNET_CRYPTO_rsa_key_create_from_hash (const GNUNET_HashCode * hc)
742{
743 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
744 KBlockKeyCacheLine *line;
745 int i;
746
747 for (i = 0; i < cacheSize; i++)
748 {
749 if (0 == memcmp (hc, &cache[i]->hc, sizeof (GNUNET_HashCode)))
750 {
751 ret = ksk_decode_key (cache[i]->pke);
752 return ret;
753 }
754 }
755
756 line = GNUNET_malloc (sizeof (KBlockKeyCacheLine));
757 line->hc = *hc;
758 line->pke = makeKblockKeyInternal (hc);
759 GNUNET_array_grow (cache, cacheSize, cacheSize + 1);
760 cache[cacheSize - 1] = line;
761 return ksk_decode_key (line->pke);
762}
763
764void __attribute__ ((constructor)) GNUNET_CRYPTO_ksk_init ()
765{
766 gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
767 if (!gcry_check_version (GCRYPT_VERSION))
768 {
769 fprintf (stderr,
770 _
771 ("libgcrypt has not the expected version (version %s is required).\n"),
772 GCRYPT_VERSION);
773 abort ();
774 }
775#ifdef gcry_fast_random_poll
776 gcry_fast_random_poll ();
777#endif
778}
779
780void __attribute__ ((destructor)) GNUNET_CRYPTO_ksk_fini ()
781{
782 int i;
783 for (i = 0; i < cacheSize; i++)
784 {
785 GNUNET_free (cache[i]->pke);
786 GNUNET_free (cache[i]);
787 }
788 GNUNET_array_grow (cache, cacheSize, 0);
789}
790
791/* end of kblockkey.c */
diff --git a/src/util/crypto_random.c b/src/util/crypto_random.c
new file mode 100644
index 000000000..3f7ac4dd3
--- /dev/null
+++ b/src/util/crypto_random.c
@@ -0,0 +1,136 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006 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 2, 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/**
23 * @file util/crypto_random.c
24 * @brief functions to gather random numbers
25 * @author Christian Grothoff
26 */
27#include "platform.h"
28#include "gnunet_common.h"
29#include "gnunet_crypto_lib.h"
30#include <gcrypt.h>
31
32/**
33 * @return a random value in the interval [0,i[.
34 */
35unsigned int
36GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, unsigned int i)
37{
38#ifdef gcry_fast_random_poll
39 static unsigned int invokeCount;
40#endif
41 unsigned int ret;
42
43 GNUNET_assert (i > 0);
44
45 if (mode == GNUNET_CRYPTO_QUALITY_STRONG)
46 {
47 /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */
48#ifdef gcry_fast_random_poll
49 if ((invokeCount++ % 256) == 0)
50 gcry_fast_random_poll ();
51#endif
52 ret = rand (); /* in case gcry_randomize fails,
53 we at least get a pseudo-
54 random number this way */
55 gcry_randomize ((unsigned char *) &ret,
56 sizeof (unsigned int), GCRY_STRONG_RANDOM);
57 return ret % i;
58 }
59 else
60 {
61 ret = i * ((double) RANDOM () / RAND_MAX);
62 if (ret >= i)
63 ret = i - 1;
64 return ret;
65 }
66}
67
68
69/**
70 * Get an array with a random permutation of the
71 * numbers 0...n-1.
72 * @param mode GNUNET_RANDOM_QUALITY_STRONG if the strong (but expensive)
73 * PRNG should be used, GNUNET_RANDOM_QUALITY_WEAK otherwise
74 * @param n the size of the array
75 * @return the permutation array (allocated from heap)
76 */
77unsigned int *
78GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, unsigned int n)
79{
80 unsigned int *ret;
81 unsigned int i;
82 unsigned int tmp;
83 unsigned int x;
84
85 GNUNET_assert (n > 0);
86 ret = GNUNET_malloc (n * sizeof (int));
87 for (i = 0; i < n; i++)
88 ret[i] = i;
89 for (i = 0; i < n; i++)
90 {
91 x = GNUNET_CRYPTO_random_u32 (mode, n);
92 tmp = ret[x];
93 ret[x] = ret[i];
94 ret[i] = tmp;
95 }
96 return ret;
97}
98
99/**
100 * Random on unsigned 64-bit values.
101 */
102unsigned long long
103GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode,
104 unsigned long long u)
105{
106 unsigned long long ret;
107
108 GNUNET_assert (u > 0);
109 if (mode == GNUNET_CRYPTO_QUALITY_STRONG)
110 {
111 gcry_randomize ((unsigned char *) &ret,
112 sizeof (unsigned long long), GCRY_STRONG_RANDOM);
113 return ret % u;
114 }
115 else
116 {
117 ret = u * ((double) RANDOM () / RAND_MAX);
118 if (ret >= u)
119 ret = u - 1;
120 return ret;
121 }
122}
123
124/**
125 * This function should only be called in testcases
126 * where strong entropy gathering is not desired
127 * (for example, for hostkey generation).
128 */
129void
130GNUNET_CRYPTO_random_disable_entropy_gathering ()
131{
132 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
133}
134
135
136/* end of crypto_random.c */
diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c
new file mode 100644
index 000000000..b61729e06
--- /dev/null
+++ b/src/util/crypto_rsa.c
@@ -0,0 +1,948 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009 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 2, 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 util/crypto_rsa.c
23 * @brief public key cryptography (RSA) with libgcrypt
24 * @author Christian Grothoff
25 *
26 * Note that the code locks often needlessly on the gcrypt-locking api.
27 * One would think that simple MPI operations should not require locking
28 * (since only global operations on the random pool must be locked,
29 * strictly speaking). But libgcrypt does sometimes require locking in
30 * unexpected places, so the safe solution is to always lock even if it
31 * is not required. The performance impact is minimal anyway.
32 */
33
34#include "platform.h"
35#include <gcrypt.h>
36#include "gnunet_common.h"
37#include "gnunet_crypto_lib.h"
38#include "gnunet_disk_lib.h"
39
40/**
41 * The private information of an RSA key pair.
42 * NOTE: this must match the definition in crypto_ksk.c
43 */
44struct GNUNET_CRYPTO_RsaPrivateKey
45{
46 gcry_sexp_t sexp;
47};
48
49
50/**
51 * GNUnet mandates a certain format for the encoding
52 * of private RSA key information that is provided
53 * by the RSA implementations. This format is used
54 * to serialize a private RSA key (typically when
55 * writing it to disk).
56 */
57struct RsaPrivateKeyBinaryEncoded
58{
59 /**
60 * Total size of the structure, in bytes, in big-endian!
61 */
62 uint16_t len GNUNET_PACKED;
63 uint16_t sizen GNUNET_PACKED; /* in big-endian! */
64 uint16_t sizee GNUNET_PACKED; /* in big-endian! */
65 uint16_t sized GNUNET_PACKED; /* in big-endian! */
66 uint16_t sizep GNUNET_PACKED; /* in big-endian! */
67 uint16_t sizeq GNUNET_PACKED; /* in big-endian! */
68 uint16_t sizedmp1 GNUNET_PACKED; /* in big-endian! */
69 uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */
70 /* followed by the actual values */
71};
72
73
74#define HOSTKEY_LEN 2048
75
76#define EXTRA_CHECKS ALLOW_EXTRA_CHECKS
77
78
79/**
80 * Log an error message at log-level 'level' that indicates
81 * a failure of the command 'cmd' with the message given
82 * by gcry_strerror(rc).
83 */
84#define LOG_GCRY(level, cmd, rc) do { GNUNET_log(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0);
85
86/**
87 * If target != size, move target bytes to the
88 * end of the size-sized buffer and zero out the
89 * first target-size bytes.
90 */
91static void
92adjust (unsigned char *buf, size_t size, size_t target)
93{
94 if (size < target)
95 {
96 memmove (&buf[target - size], buf, size);
97 memset (buf, 0, target - size);
98 }
99}
100
101/**
102 * This HostKey implementation uses RSA.
103 */
104struct GNUNET_CRYPTO_RsaPrivateKey *
105GNUNET_CRYPTO_rsa_key_create ()
106{
107 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
108 gcry_sexp_t s_key;
109 gcry_sexp_t s_keyparam;
110
111 GNUNET_assert (0 == gcry_sexp_build (&s_keyparam,
112 NULL,
113 "(genkey(rsa(nbits %d)(rsa-use-e 3:257)))",
114 HOSTKEY_LEN));
115 GNUNET_assert (0 == gcry_pk_genkey (&s_key, s_keyparam));
116 gcry_sexp_release (s_keyparam);
117#if EXTRA_CHECKS
118 GNUNET_assert (0 == gcry_pk_testkey (s_key));
119#endif
120 ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey));
121 ret->sexp = s_key;
122 return ret;
123}
124
125/**
126 * Free memory occupied by hostkey
127 */
128void
129GNUNET_CRYPTO_rsa_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
130{
131 gcry_sexp_release (hostkey->sexp);
132 GNUNET_free (hostkey);
133}
134
135static int
136key_from_sexp (gcry_mpi_t * array,
137 gcry_sexp_t sexp, const char *topname, const char *elems)
138{
139 gcry_sexp_t list, l2;
140 const char *s;
141 int i, idx;
142
143 list = gcry_sexp_find_token (sexp, topname, 0);
144 if (!list)
145 {
146 return 1;
147 }
148 l2 = gcry_sexp_cadr (list);
149 gcry_sexp_release (list);
150 list = l2;
151 if (!list)
152 {
153 return 2;
154 }
155
156 idx = 0;
157 for (s = elems; *s; s++, idx++)
158 {
159 l2 = gcry_sexp_find_token (list, s, 1);
160 if (!l2)
161 {
162 for (i = 0; i < idx; i++)
163 {
164 gcry_free (array[i]);
165 array[i] = NULL;
166 }
167 gcry_sexp_release (list);
168 return 3; /* required parameter not found */
169 }
170 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
171 gcry_sexp_release (l2);
172 if (!array[idx])
173 {
174 for (i = 0; i < idx; i++)
175 {
176 gcry_free (array[i]);
177 array[i] = NULL;
178 }
179 gcry_sexp_release (list);
180 return 4; /* required parameter is invalid */
181 }
182 }
183 gcry_sexp_release (list);
184 return 0;
185}
186
187/**
188 * Extract the public key of the host.
189 * @param hostkey the hostkey to extract into the result.
190 * @param result where to write the result.
191 */
192void
193GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey
194 *hostkey,
195 struct
196 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
197 *result)
198{
199 gcry_mpi_t skey[2];
200 size_t size;
201 int rc;
202
203 rc = key_from_sexp (skey, hostkey->sexp, "public-key", "ne");
204 if (rc)
205 rc = key_from_sexp (skey, hostkey->sexp, "private-key", "ne");
206 if (rc)
207 rc = key_from_sexp (skey, hostkey->sexp, "rsa", "ne");
208 GNUNET_assert (0 == rc);
209 result->len =
210 htons (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) -
211 sizeof (result->padding));
212 result->sizen = htons (GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH);
213 result->padding = 0;
214 size = GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH;
215 GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG,
216 &result->key[0], size, &size, skey[0]));
217 adjust (&result->key[0], size, GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH);
218 size =
219 GNUNET_CRYPTO_RSA_KEY_LENGTH - GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH;
220 GNUNET_assert (0 ==
221 gcry_mpi_print (GCRYMPI_FMT_USG,
222 &result->
223 key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH],
224 size, &size, skey[1]));
225 adjust (&result->key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH], size,
226 GNUNET_CRYPTO_RSA_KEY_LENGTH -
227 GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH);
228 gcry_mpi_release (skey[0]);
229 gcry_mpi_release (skey[1]);
230}
231
232
233/**
234 * Internal: publicKey => RSA-Key.
235 *
236 * Note that the return type is not actually a private
237 * key but rather an sexpression for the public key!
238 */
239static struct GNUNET_CRYPTO_RsaPrivateKey *
240public2PrivateKey (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
241 *publicKey)
242{
243 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
244 gcry_sexp_t result;
245 gcry_mpi_t n;
246 gcry_mpi_t e;
247 size_t size;
248 size_t erroff;
249 int rc;
250
251 if ((ntohs (publicKey->sizen) != GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH) ||
252 (ntohs (publicKey->len) !=
253 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) -
254 sizeof (publicKey->padding)))
255 {
256 GNUNET_break (0);
257 return NULL;
258 }
259 size = GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH;
260 rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG, &publicKey->key[0], size, &size);
261 if (rc)
262 {
263 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
264 return NULL;
265 }
266 size =
267 GNUNET_CRYPTO_RSA_KEY_LENGTH - GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH;
268 rc =
269 gcry_mpi_scan (&e, GCRYMPI_FMT_USG,
270 &publicKey->key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH],
271 size, &size);
272 if (rc)
273 {
274 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
275 gcry_mpi_release (n);
276 return NULL;
277 }
278 rc = gcry_sexp_build (&result,
279 &erroff, "(public-key(rsa(n %m)(e %m)))", n, e);
280 gcry_mpi_release (n);
281 gcry_mpi_release (e);
282 if (rc)
283 {
284 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); /* erroff gives more info */
285 return NULL;
286 }
287 ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey));
288 ret->sexp = result;
289 return ret;
290}
291
292
293/**
294 * Encode the private key in a format suitable for
295 * storing it into a file.
296 * @returns encoding of the private key.
297 * The first 4 bytes give the size of the array, as usual.
298 */
299static struct RsaPrivateKeyBinaryEncoded *
300rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
301{
302 struct RsaPrivateKeyBinaryEncoded *retval;
303 gcry_mpi_t pkv[6];
304 void *pbu[6];
305 size_t sizes[6];
306 int rc;
307 int i;
308 int size;
309
310#if EXTRA_CHECKS
311 if (gcry_pk_testkey (hostkey->sexp))
312 {
313 GNUNET_break (0);
314 return NULL;
315 }
316#endif
317
318 memset (pkv, 0, sizeof (gcry_mpi_t) * 6);
319 rc = key_from_sexp (pkv, hostkey->sexp, "private-key", "nedpqu");
320 if (rc)
321 rc = key_from_sexp (pkv, hostkey->sexp, "rsa", "nedpqu");
322 if (rc)
323 rc = key_from_sexp (pkv, hostkey->sexp, "private-key", "nedpq");
324 if (rc)
325 rc = key_from_sexp (pkv, hostkey->sexp, "rsa", "nedpq");
326 if (rc)
327 rc = key_from_sexp (pkv, hostkey->sexp, "private-key", "ned");
328 if (rc)
329 rc = key_from_sexp (pkv, hostkey->sexp, "rsa", "ned");
330 GNUNET_assert (0 == rc);
331 size = sizeof (struct RsaPrivateKeyBinaryEncoded);
332 for (i = 0; i < 6; i++)
333 {
334 if (pkv[i] != NULL)
335 {
336 GNUNET_assert (0 == gcry_mpi_aprint (GCRYMPI_FMT_USG,
337 (unsigned char **) &pbu[i],
338 &sizes[i], pkv[i]));
339 size += sizes[i];
340 }
341 else
342 {
343 pbu[i] = NULL;
344 sizes[i] = 0;
345 }
346 }
347 GNUNET_assert (size < 65536);
348 retval = GNUNET_malloc (size);
349 retval->len = htons (size);
350 i = 0;
351 retval->sizen = htons (sizes[0]);
352 memcpy (&((char *) (&retval[1]))[i], pbu[0], sizes[0]);
353 i += sizes[0];
354 retval->sizee = htons (sizes[1]);
355 memcpy (&((char *) (&retval[1]))[i], pbu[1], sizes[1]);
356 i += sizes[1];
357 retval->sized = htons (sizes[2]);
358 memcpy (&((char *) (&retval[1]))[i], pbu[2], sizes[2]);
359 i += sizes[2];
360 /* swap p and q! */
361 retval->sizep = htons (sizes[4]);
362 memcpy (&((char *) (&retval[1]))[i], pbu[4], sizes[4]);
363 i += sizes[4];
364 retval->sizeq = htons (sizes[3]);
365 memcpy (&((char *) (&retval[1]))[i], pbu[3], sizes[3]);
366 i += sizes[3];
367 retval->sizedmp1 = htons (0);
368 retval->sizedmq1 = htons (0);
369 memcpy (&((char *) (&retval[1]))[i], pbu[5], sizes[5]);
370 for (i = 0; i < 6; i++)
371 {
372 if (pkv[i] != NULL)
373 gcry_mpi_release (pkv[i]);
374 if (pbu[i] != NULL)
375 free (pbu[i]);
376 }
377 return retval;
378}
379
380/**
381 * Decode the private key from the file-format back
382 * to the "normal", internal format.
383 */
384static struct GNUNET_CRYPTO_RsaPrivateKey *
385rsa_decode_key (const struct RsaPrivateKeyBinaryEncoded *encoding)
386{
387 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
388 gcry_sexp_t res;
389 gcry_mpi_t n, e, d, p, q, u;
390 int rc;
391 size_t size;
392 int pos;
393
394 pos = 0;
395 size = ntohs (encoding->sizen);
396 rc = gcry_mpi_scan (&n,
397 GCRYMPI_FMT_USG,
398 &((const unsigned char *) (&encoding[1]))[pos],
399 size, &size);
400 pos += ntohs (encoding->sizen);
401 if (rc)
402 {
403 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
404 return NULL;
405 }
406 size = ntohs (encoding->sizee);
407 rc = gcry_mpi_scan (&e,
408 GCRYMPI_FMT_USG,
409 &((const unsigned char *) (&encoding[1]))[pos],
410 size, &size);
411 pos += ntohs (encoding->sizee);
412 if (rc)
413 {
414 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
415 gcry_mpi_release (n);
416 return NULL;
417 }
418 size = ntohs (encoding->sized);
419 rc = gcry_mpi_scan (&d,
420 GCRYMPI_FMT_USG,
421 &((const unsigned char *) (&encoding[1]))[pos],
422 size, &size);
423 pos += ntohs (encoding->sized);
424 if (rc)
425 {
426 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
427 gcry_mpi_release (n);
428 gcry_mpi_release (e);
429 return NULL;
430 }
431 /* swap p and q! */
432 size = ntohs (encoding->sizep);
433 if (size > 0)
434 {
435 rc = gcry_mpi_scan (&q,
436 GCRYMPI_FMT_USG,
437 &((const unsigned char *) (&encoding[1]))[pos],
438 size, &size);
439 pos += ntohs (encoding->sizep);
440 if (rc)
441 {
442 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
443 gcry_mpi_release (n);
444 gcry_mpi_release (e);
445 gcry_mpi_release (d);
446 return NULL;
447 }
448 }
449 else
450 q = NULL;
451 size = ntohs (encoding->sizeq);
452 if (size > 0)
453 {
454 rc = gcry_mpi_scan (&p,
455 GCRYMPI_FMT_USG,
456 &((const unsigned char *) (&encoding[1]))[pos],
457 size, &size);
458 pos += ntohs (encoding->sizeq);
459 if (rc)
460 {
461 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
462 gcry_mpi_release (n);
463 gcry_mpi_release (e);
464 gcry_mpi_release (d);
465 if (q != NULL)
466 gcry_mpi_release (q);
467 return NULL;
468 }
469 }
470 else
471 p = NULL;
472 pos += ntohs (encoding->sizedmp1);
473 pos += ntohs (encoding->sizedmq1);
474 size =
475 ntohs (encoding->len) - sizeof (struct RsaPrivateKeyBinaryEncoded) - pos;
476 if (size > 0)
477 {
478 rc = gcry_mpi_scan (&u,
479 GCRYMPI_FMT_USG,
480 &((const unsigned char *) (&encoding[1]))[pos],
481 size, &size);
482 if (rc)
483 {
484 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
485 gcry_mpi_release (n);
486 gcry_mpi_release (e);
487 gcry_mpi_release (d);
488 if (p != NULL)
489 gcry_mpi_release (p);
490 if (q != NULL)
491 gcry_mpi_release (q);
492 return NULL;
493 }
494 }
495 else
496 u = NULL;
497
498 if ((p != NULL) && (q != NULL) && (u != NULL))
499 {
500 rc = gcry_sexp_build (&res, &size, /* erroff */
501 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",
502 n, e, d, p, q, u);
503 }
504 else
505 {
506 if ((p != NULL) && (q != NULL))
507 {
508 rc = gcry_sexp_build (&res, &size, /* erroff */
509 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
510 n, e, d, p, q);
511 }
512 else
513 {
514 rc = gcry_sexp_build (&res, &size, /* erroff */
515 "(private-key(rsa(n %m)(e %m)(d %m)))",
516 n, e, d);
517 }
518 }
519 gcry_mpi_release (n);
520 gcry_mpi_release (e);
521 gcry_mpi_release (d);
522 if (p != NULL)
523 gcry_mpi_release (p);
524 if (q != NULL)
525 gcry_mpi_release (q);
526 if (u != NULL)
527 gcry_mpi_release (u);
528
529 if (rc)
530 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
531#if EXTRA_CHECKS
532 if (gcry_pk_testkey (res))
533 {
534 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
535 return NULL;
536 }
537#endif
538 ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey));
539 ret->sexp = res;
540 return ret;
541}
542
543
544/**
545 * Create a new private key by reading it from a file. If the
546 * files does not exist, create a new key and write it to the
547 * file. Caller must free return value. Note that this function
548 * can not guarantee that another process might not be trying
549 * the same operation on the same file at the same time. The
550 * caller must somehow know that the file either already exists
551 * with a valid key OR be sure that no other process is calling
552 * this function at the same time. If the contents of the file
553 * are invalid the old file is deleted and a fresh key is
554 * created.
555 *
556 * @return new private key, NULL on error (for example,
557 * permission denied)
558 */
559struct GNUNET_CRYPTO_RsaPrivateKey *
560GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
561{
562 struct flock fl;
563 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
564 struct RsaPrivateKeyBinaryEncoded *enc;
565 struct stat sbuf;
566 uint16_t len;
567 int fd;
568 unsigned int cnt;
569 int ec;
570
571 if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename))
572 return NULL;
573 while (0 != STAT (filename, &sbuf))
574 {
575 fd = open (filename, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
576 if (-1 == fd)
577 {
578 if (errno == EEXIST)
579 continue;
580 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
581 "open", filename);
582 return NULL;
583 }
584 memset (&fl, 0, sizeof (struct flock));
585 fl.l_type = F_WRLCK;
586 fl.l_whence = SEEK_SET;
587 fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
588 cnt = 0;
589 while (0 != fcntl (fd, F_SETLK, &fl))
590 {
591 sleep (1);
592 if (0 == ++cnt % 10)
593 {
594 ec = errno;
595 fl.l_type = F_GETLK;
596 fcntl (fd, F_GETLK, &fl);
597 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
598 _
599 ("Could not aquire lock on file `%s' due to process %u: %s...\n"),
600 filename, fl.l_pid, STRERROR (errno));
601 }
602 memset (&fl, 0, sizeof (struct flock));
603 fl.l_type = F_WRLCK;
604 fl.l_whence = SEEK_SET;
605 fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
606 }
607 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
608 _("Creating a new private key. This may take a while.\n"));
609 ret = GNUNET_CRYPTO_rsa_key_create ();
610 GNUNET_assert (ret != NULL);
611 enc = rsa_encode_key (ret);
612 GNUNET_assert (enc != NULL);
613 GNUNET_assert (ntohs (enc->len) == WRITE (fd, enc, ntohs (enc->len)));
614 GNUNET_free (enc);
615 fdatasync (fd);
616 memset (&fl, 0, sizeof (struct flock));
617 fl.l_type = F_UNLCK;
618 fl.l_whence = SEEK_SET;
619 fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
620 cnt = 0;
621 if (0 != fcntl (fd, F_SETLK, &fl))
622 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
623 "fcntl", filename);
624 GNUNET_assert (0 == CLOSE (fd));
625 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
626 _("Stored new private key in `%s'.\n"), filename);
627 return ret;
628 }
629 /* hostkey file exists already, read it! */
630 fd = open (filename, O_RDONLY);
631 if (-1 == fd)
632 {
633 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", filename);
634 return NULL;
635 }
636 cnt = 0;
637 while (1)
638 {
639 memset (&fl, 0, sizeof (struct flock));
640 fl.l_type = F_RDLCK;
641 fl.l_whence = SEEK_SET;
642 fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
643 if (0 != fcntl (fd, F_SETLK, &fl))
644 {
645 if (0 == ++cnt % 10)
646 {
647 ec = errno;
648 fl.l_type = F_GETLK;
649 fcntl (fd, F_GETLK, &fl);
650 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
651 _
652 ("Could not aquire lock on file `%s' due to process %u: %s...\n"),
653 filename, fl.l_pid, STRERROR (errno));
654 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
655 _
656 ("This may be ok if someone is currently generating a hostkey.\n"));
657 }
658 sleep (1);
659 continue;
660 }
661 if (0 != STAT (filename, &sbuf))
662 {
663 /* eh, what!? File we opened is now gone!? */
664 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
665 "stat", filename);
666 memset (&fl, 0, sizeof (struct flock));
667 fl.l_type = F_UNLCK;
668 fl.l_whence = SEEK_SET;
669 fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
670 if (0 != fcntl (fd, F_SETLK, &fl))
671 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
672 "fcntl", filename);
673 GNUNET_assert (0 == CLOSE (fd));
674 return NULL;
675 }
676 if (sbuf.st_size < sizeof (struct RsaPrivateKeyBinaryEncoded))
677 {
678 /* maybe we got the read lock before the hostkey generating
679 process had a chance to get the write lock; give it up! */
680 memset (&fl, 0, sizeof (struct flock));
681 fl.l_type = F_UNLCK;
682 fl.l_whence = SEEK_SET;
683 fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
684 if (0 != fcntl (fd, F_SETLK, &fl))
685 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
686 "fcntl", filename);
687 if (0 == ++cnt % 10)
688 {
689 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
690 _
691 ("When trying to read hostkey file `%s' I found %u bytes but I need at least %u.\n"),
692 filename, (unsigned int) sbuf.st_size,
693 (unsigned int) sizeof (struct
694 RsaPrivateKeyBinaryEncoded));
695 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
696 _
697 ("This may be ok if someone is currently generating a hostkey.\n"));
698 }
699 sleep (2); /* wait a bit longer! */
700 continue;
701 }
702 break;
703 }
704 enc = GNUNET_malloc (sbuf.st_size);
705 GNUNET_assert (sbuf.st_size == READ (fd, enc, sbuf.st_size));
706 len = ntohs (enc->len);
707 if ((len != sbuf.st_size) || (NULL == (ret = rsa_decode_key (enc))))
708 {
709 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
710 _
711 ("File `%s' does not contain a valid private key. You should delete it.\n"),
712 filename);
713 GNUNET_free (enc);
714 }
715 memset (&fl, 0, sizeof (struct flock));
716 fl.l_type = F_UNLCK;
717 fl.l_whence = SEEK_SET;
718 fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
719 if (0 != fcntl (fd, F_SETLK, &fl))
720 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
721 GNUNET_assert (0 == CLOSE (fd));
722 return ret;
723}
724
725
726/**
727 * Encrypt a block with the public key of another host that uses the
728 * same cyper.
729 *
730 * @param block the block to encrypt
731 * @param size the size of block
732 * @param publicKey the encoded public key used to encrypt
733 * @param target where to store the encrypted block
734 * @returns GNUNET_SYSERR on error, GNUNET_OK if ok
735 */
736int
737GNUNET_CRYPTO_rsa_encrypt (const void *block,
738 uint16_t size,
739 const struct
740 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey,
741 struct GNUNET_CRYPTO_RsaEncryptedData *target)
742{
743 gcry_sexp_t result;
744 gcry_sexp_t data;
745 struct GNUNET_CRYPTO_RsaPrivateKey *pubkey;
746 gcry_mpi_t val;
747 gcry_mpi_t rval;
748 size_t isize;
749 size_t erroff;
750
751 GNUNET_assert (size <= sizeof (GNUNET_HashCode));
752 pubkey = public2PrivateKey (publicKey);
753 isize = size;
754 GNUNET_assert (0 ==
755 gcry_mpi_scan (&val, GCRYMPI_FMT_USG, block, isize, &isize));
756 GNUNET_assert (0 ==
757 gcry_sexp_build (&data, &erroff,
758 "(data (flags pkcs1)(value %m))", val));
759 gcry_mpi_release (val);
760 GNUNET_assert (0 == gcry_pk_encrypt (&result, data, pubkey->sexp));
761 gcry_sexp_release (data);
762 GNUNET_CRYPTO_rsa_key_free (pubkey);
763
764 GNUNET_assert (0 == key_from_sexp (&rval, result, "rsa", "a"));
765 gcry_sexp_release (result);
766 isize = sizeof (struct GNUNET_CRYPTO_RsaEncryptedData);
767 GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG,
768 (unsigned char *) target, isize, &isize,
769 rval));
770 gcry_mpi_release (rval);
771 adjust (&target->encoding[0], isize,
772 sizeof (struct GNUNET_CRYPTO_RsaEncryptedData));
773 return GNUNET_OK;
774}
775
776/**
777 * Decrypt a given block with the hostkey.
778 *
779 * @param hostkey the hostkey with which to decrypt this block
780 * @param block the data to decrypt, encoded as returned by encrypt
781 * @param result pointer to a location where the result can be stored
782 * @param max the maximum number of bits to store for the result, if
783 * the decrypted block is bigger, an error is returned
784 * @returns the size of the decrypted block, -1 on error
785 */
786int
787GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey,
788 const struct GNUNET_CRYPTO_RsaEncryptedData *block,
789 void *result, uint16_t max)
790{
791 gcry_sexp_t resultsexp;
792 gcry_sexp_t data;
793 size_t erroff;
794 size_t size;
795 gcry_mpi_t val;
796 unsigned char *endp;
797 unsigned char *tmp;
798
799#if EXTRA_CHECKS
800 GNUNET_assert (0 == gcry_pk_testkey (hostkey->sexp));
801#endif
802 size = sizeof (struct GNUNET_CRYPTO_RsaEncryptedData);
803 GNUNET_assert (0 == gcry_mpi_scan (&val,
804 GCRYMPI_FMT_USG, &block->encoding[0],
805 size, &size));
806 GNUNET_assert (0 ==
807 gcry_sexp_build (&data, &erroff,
808 "(enc-val(flags)(rsa(a %m)))", val));
809 gcry_mpi_release (val);
810 GNUNET_assert (0 == gcry_pk_decrypt (&resultsexp, data, hostkey->sexp));
811 gcry_sexp_release (data);
812 /* resultsexp has format "(value %m)" */
813 GNUNET_assert (NULL !=
814 (val = gcry_sexp_nth_mpi (resultsexp, 1, GCRYMPI_FMT_USG)));
815 gcry_sexp_release (resultsexp);
816 tmp = GNUNET_malloc (max + HOSTKEY_LEN / 8);
817 size = max + HOSTKEY_LEN / 8;
818 GNUNET_assert (0 ==
819 gcry_mpi_print (GCRYMPI_FMT_USG, tmp, size, &size, val));
820 gcry_mpi_release (val);
821 endp = tmp;
822 endp += (size - max);
823 size = max;
824 memcpy (result, endp, size);
825 GNUNET_free (tmp);
826 return size;
827}
828
829
830/**
831 * Sign a given block.
832 *
833 * @param hostkey private key to use for the signing
834 * @param purpose what to sign (size, purpose)
835 * @param result where to write the signature
836 * @return GNUNET_SYSERR on error, GNUNET_OK on success
837 */
838int
839GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey,
840 const struct GNUNET_CRYPTO_RsaSignaturePurpose
841 *purpose, struct GNUNET_CRYPTO_RsaSignature *sig)
842{
843 gcry_sexp_t result;
844 gcry_sexp_t data;
845 size_t ssize;
846 gcry_mpi_t rval;
847 GNUNET_HashCode hc;
848 char *buff;
849 int bufSize;
850
851 GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc);
852#define FORMATSTRING "(4:data(5:flags5:pkcs1)(4:hash6:sha51264:0123456789012345678901234567890123456789012345678901234567890123))"
853 bufSize = strlen (FORMATSTRING) + 1;
854 buff = GNUNET_malloc (bufSize);
855 memcpy (buff, FORMATSTRING, bufSize);
856 memcpy (&buff
857 [bufSize -
858 strlen
859 ("0123456789012345678901234567890123456789012345678901234567890123))")
860 - 1], &hc, sizeof (GNUNET_HashCode));
861 GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0));
862 GNUNET_free (buff);
863 GNUNET_assert (0 == gcry_pk_sign (&result, data, hostkey->sexp));
864 gcry_sexp_release (data);
865 GNUNET_assert (0 == key_from_sexp (&rval, result, "rsa", "s"));
866 gcry_sexp_release (result);
867 ssize = sizeof (struct GNUNET_CRYPTO_RsaSignature);
868 GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG,
869 (unsigned char *) sig, ssize, &ssize,
870 rval));
871 gcry_mpi_release (rval);
872 adjust (sig->sig, ssize, sizeof (struct GNUNET_CRYPTO_RsaSignature));
873 return GNUNET_OK;
874}
875
876
877/**
878 * Verify signature.
879 *
880 * @param purpose what is the purpose that the signature should have?
881 * @param validate block to validate (size, purpose, data)
882 * @param sig signature that is being validated
883 * @param publicKey public key of the signer
884 * @returns GNUNET_OK if ok, GNUNET_SYSERR if invalid
885 */
886int
887GNUNET_CRYPTO_rsa_verify (uint32_t purpose,
888 const struct GNUNET_CRYPTO_RsaSignaturePurpose
889 *validate,
890 const struct GNUNET_CRYPTO_RsaSignature *sig,
891 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
892 *publicKey)
893{
894 gcry_sexp_t data;
895 gcry_sexp_t sigdata;
896 size_t size;
897 gcry_mpi_t val;
898 struct GNUNET_CRYPTO_RsaPrivateKey *hostkey;
899 GNUNET_HashCode hc;
900 char *buff;
901 int bufSize;
902 size_t erroff;
903 int rc;
904
905 if (purpose != ntohl (validate->purpose))
906 return GNUNET_SYSERR; /* purpose mismatch */
907 GNUNET_CRYPTO_hash (validate, ntohl (validate->size), &hc);
908 size = sizeof (struct GNUNET_CRYPTO_RsaSignature);
909 GNUNET_assert (0 == gcry_mpi_scan (&val,
910 GCRYMPI_FMT_USG,
911 (const unsigned char *) sig, size,
912 &size));
913 GNUNET_assert (0 ==
914 gcry_sexp_build (&sigdata, &erroff, "(sig-val(rsa(s %m)))",
915 val));
916 gcry_mpi_release (val);
917 bufSize = strlen (FORMATSTRING) + 1;
918 buff = GNUNET_malloc (bufSize);
919 memcpy (buff, FORMATSTRING, bufSize);
920 memcpy (&buff[strlen (FORMATSTRING) -
921 strlen
922 ("0123456789012345678901234567890123456789012345678901234567890123))")],
923 &hc, sizeof (GNUNET_HashCode));
924 GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0));
925 GNUNET_free (buff);
926 hostkey = public2PrivateKey (publicKey);
927 if (hostkey == NULL)
928 {
929 gcry_sexp_release (data);
930 gcry_sexp_release (sigdata);
931 return GNUNET_SYSERR;
932 }
933 rc = gcry_pk_verify (sigdata, data, hostkey->sexp);
934 GNUNET_CRYPTO_rsa_key_free (hostkey);
935 gcry_sexp_release (data);
936 gcry_sexp_release (sigdata);
937 if (rc)
938 {
939 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
940 _("RSA signature verification failed at %s:%d: %s\n"),
941 __FILE__, __LINE__, gcry_strerror (rc));
942 return GNUNET_SYSERR;
943 }
944 return GNUNET_OK;
945}
946
947
948/* end of crypto_rsa.c */
diff --git a/src/util/disk.c b/src/util/disk.c
new file mode 100644
index 000000000..f0fe9341b
--- /dev/null
+++ b/src/util/disk.c
@@ -0,0 +1,954 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2005, 2006 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 2, 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 util/disk.c
23 * @brief disk IO convenience methods
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_common.h"
29#include "gnunet_directories.h"
30#include "gnunet_disk_lib.h"
31#include "gnunet_scheduler_lib.h"
32#include "gnunet_strings_lib.h"
33
34
35#if LINUX || CYGWIN
36#include <sys/vfs.h>
37#else
38#ifdef SOMEBSD
39#include <sys/param.h>
40#include <sys/mount.h>
41#else
42#ifdef OSX
43#include <sys/param.h>
44#include <sys/mount.h>
45#else
46#ifdef SOLARIS
47#include <sys/types.h>
48#include <sys/statvfs.h>
49#else
50#ifdef MINGW
51#define _IFMT 0170000 /* type of file */
52#define _IFLNK 0120000 /* symbolic link */
53#define S_ISLNK(m) (((m)&_IFMT) == _IFLNK)
54#else
55#error PORT-ME: need to port statfs (how much space is left on the drive?)
56#endif
57#endif
58#endif
59#endif
60#endif
61
62#ifndef SOMEBSD
63#ifndef WINDOWS
64#ifndef OSX
65#include <wordexp.h>
66#endif
67#endif
68#endif
69
70typedef struct
71{
72 unsigned long long total;
73 int include_sym_links;
74} GetFileSizeData;
75
76static int
77getSizeRec (void *ptr, const char *fn)
78{
79 GetFileSizeData *gfsd = ptr;
80#ifdef HAVE_STAT64
81 struct stat64 buf;
82#else
83 struct stat buf;
84#endif
85
86#ifdef HAVE_STAT64
87 if (0 != STAT64 (fn, &buf))
88 {
89 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "stat64", fn);
90 return GNUNET_SYSERR;
91 }
92#else
93 if (0 != STAT (fn, &buf))
94 {
95 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "stat", fn);
96 return GNUNET_SYSERR;
97 }
98#endif
99 if ((!S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES))
100 gfsd->total += buf.st_size;
101 if ((S_ISDIR (buf.st_mode)) &&
102 (0 == ACCESS (fn, X_OK)) &&
103 ((!S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES)))
104 {
105 if (GNUNET_SYSERR == GNUNET_DISK_directory_scan (fn, &getSizeRec, gfsd))
106 return GNUNET_SYSERR;
107 }
108 return GNUNET_OK;
109}
110
111/**
112 * Get the size of the file (or directory)
113 * of the given file (in bytes).
114 *
115 * @return GNUNET_SYSERR on error, GNUNET_OK on success
116 */
117int
118GNUNET_DISK_file_size (const char *filename,
119 unsigned long long *size, int includeSymLinks)
120{
121 GetFileSizeData gfsd;
122 int ret;
123
124 GNUNET_assert (size != NULL);
125 gfsd.total = 0;
126 gfsd.include_sym_links = includeSymLinks;
127 ret = getSizeRec (&gfsd, filename);
128 *size = gfsd.total;
129 return ret;
130}
131
132/**
133 * Get the number of blocks that are left on the partition that
134 * contains the given file (for normal users).
135 *
136 * @param part a file on the partition to check
137 * @return -1 on errors, otherwise the number of free blocks
138 */
139long
140GNUNET_DISK_get_blocks_available (const char *part)
141{
142#ifdef SOLARIS
143 struct statvfs buf;
144
145 if (0 != statvfs (part, &buf))
146 {
147 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "statfs", part);
148 return -1;
149 }
150 return buf.f_bavail;
151#elif MINGW
152 DWORD dwDummy;
153 DWORD dwBlocks;
154 char szDrive[4];
155
156 memcpy (szDrive, part, 3);
157 szDrive[3] = 0;
158 if (!GetDiskFreeSpace (szDrive, &dwDummy, &dwDummy, &dwBlocks, &dwDummy))
159 {
160 GNUNET_GE_LOG (GNUNET_ERROR_TYPE_WARNING,
161 _("`%s' failed for drive `%s': %u\n"),
162 "GetDiskFreeSpace", szDrive, GetLastError ());
163
164 return -1;
165 }
166 return dwBlocks;
167#else
168 struct statfs s;
169 if (0 != statfs (part, &s))
170 {
171 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "statfs", part);
172 return -1;
173 }
174 return s.f_bavail;
175#endif
176}
177
178/**
179 * Test if fil is a directory.
180 *
181 * @return GNUNET_YES if yes, GNUNET_NO if not, GNUNET_SYSERR if it
182 * does not exist
183 */
184int
185GNUNET_DISK_directory_test (const char *fil)
186{
187 struct stat filestat;
188 int ret;
189
190 ret = STAT (fil, &filestat);
191 if (ret != 0)
192 {
193 if (errno != ENOENT)
194 {
195 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "stat", fil);
196 return GNUNET_SYSERR;
197 }
198 return GNUNET_NO;
199 }
200 if (!S_ISDIR (filestat.st_mode))
201 return GNUNET_NO;
202 if (ACCESS (fil, R_OK | X_OK) < 0)
203 {
204 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "access", fil);
205 return GNUNET_SYSERR;
206 }
207 return GNUNET_YES;
208}
209
210/**
211 * Check that fil corresponds to a filename
212 * (of a file that exists and that is not a directory).
213 * @returns GNUNET_YES if yes, GNUNET_NO if not a file, GNUNET_SYSERR if something
214 * else (will print an error message in that case, too).
215 */
216int
217GNUNET_DISK_file_test (const char *fil)
218{
219 struct stat filestat;
220 int ret;
221 char *rdir;
222
223 rdir = GNUNET_STRINGS_filename_expand (fil);
224 if (rdir == NULL)
225 return GNUNET_SYSERR;
226
227 ret = STAT (rdir, &filestat);
228 if (ret != 0)
229 {
230 if (errno != ENOENT)
231 {
232 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "stat", rdir);
233 GNUNET_free (rdir);
234 return GNUNET_SYSERR;
235 }
236 GNUNET_free (rdir);
237 return GNUNET_NO;
238 }
239 if (!S_ISREG (filestat.st_mode))
240 {
241 GNUNET_free (rdir);
242 return GNUNET_NO;
243 }
244 if (ACCESS (rdir, R_OK) < 0)
245 {
246 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "access", rdir);
247 GNUNET_free (rdir);
248 return GNUNET_SYSERR;
249 }
250 GNUNET_free (rdir);
251 return GNUNET_YES;
252}
253
254/**
255 * Implementation of "mkdir -p"
256 * @param dir the directory to create
257 * @returns GNUNET_OK on success, GNUNET_SYSERR on failure
258 */
259int
260GNUNET_DISK_directory_create (const char *dir)
261{
262 char *rdir;
263 int len;
264 int pos;
265 int ret = GNUNET_OK;
266
267 rdir = GNUNET_STRINGS_filename_expand (dir);
268 if (rdir == NULL)
269 return GNUNET_SYSERR;
270
271 len = strlen (rdir);
272#ifndef MINGW
273 pos = 1; /* skip heading '/' */
274#else
275 /* Local or Network path? */
276 if (strncmp (rdir, "\\\\", 2) == 0)
277 {
278 pos = 2;
279 while (rdir[pos])
280 {
281 if (rdir[pos] == '\\')
282 {
283 pos++;
284 break;
285 }
286 pos++;
287 }
288 }
289 else
290 {
291 pos = 3; /* strlen("C:\\") */
292 }
293#endif
294 while (pos <= len)
295 {
296 if ((rdir[pos] == DIR_SEPARATOR) || (pos == len))
297 {
298 rdir[pos] = '\0';
299 ret = GNUNET_DISK_directory_test (rdir);
300 if (ret == GNUNET_SYSERR)
301 {
302 GNUNET_free (rdir);
303 return GNUNET_SYSERR;
304 }
305 if (ret == GNUNET_NO)
306 {
307#ifndef MINGW
308 ret = mkdir (rdir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); /* 755 */
309#else
310 ret = mkdir (rdir);
311#endif
312 if ((ret != 0) && (errno != EEXIST))
313 {
314 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "mkdir",
315 rdir);
316 GNUNET_free (rdir);
317 return GNUNET_SYSERR;
318 }
319 }
320 rdir[pos] = DIR_SEPARATOR;
321 }
322 pos++;
323 }
324 GNUNET_free (rdir);
325 return GNUNET_OK;
326}
327
328
329/**
330 * Create the directory structure for storing
331 * a file.
332 *
333 * @param filename name of a file in the directory
334 * @returns GNUNET_OK on success,
335 * GNUNET_SYSERR on failure,
336 * GNUNET_NO if the directory
337 * exists but is not writeable for us
338 */
339int
340GNUNET_DISK_directory_create_for_file (const char *dir)
341{
342 char *rdir;
343 int len;
344 int ret;
345
346 rdir = GNUNET_STRINGS_filename_expand (dir);
347 if (rdir == NULL)
348 return GNUNET_SYSERR;
349 len = strlen (rdir);
350 while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
351 len--;
352 rdir[len] = '\0';
353 ret = GNUNET_DISK_directory_create (rdir);
354 if ((ret == GNUNET_OK) && (0 != ACCESS (rdir, W_OK)))
355 ret = GNUNET_NO;
356 GNUNET_free (rdir);
357 return ret;
358}
359
360/**
361 * Read the contents of a binary file into a buffer.
362 * @param fileName the name of the file, not freed,
363 * must already be expanded!
364 * @param len the maximum number of bytes to read
365 * @param result the buffer to write the result to
366 * @return the number of bytes read on success, -1 on failure
367 */
368int
369GNUNET_DISK_file_read (const char *fileName, int len, void *result)
370{
371 /* open file, must exist, open read only */
372 int handle;
373 int size;
374
375 GNUNET_assert (fileName != NULL);
376 GNUNET_assert (len > 0);
377 if (len == 0)
378 return 0;
379 GNUNET_assert (result != NULL);
380 handle = GNUNET_DISK_file_open (fileName, O_RDONLY, S_IRUSR);
381 if (handle < 0)
382 return -1;
383 size = READ (handle, result, len);
384 GNUNET_DISK_file_close (fileName, handle);
385 return size;
386}
387
388
389/**
390 * Convert string to value ('755' for chmod-call)
391 */
392static int
393atoo (const char *s)
394{
395 int n = 0;
396
397 while (('0' <= *s) && (*s < '8'))
398 {
399 n <<= 3;
400 n += *s++ - '0';
401 }
402 return n;
403}
404
405/**
406 * Write a buffer to a file.
407 * @param fileName the name of the file, NOT freed!
408 * @param buffer the data to write
409 * @param n number of bytes to write
410 * @param mode permissions to set on the file
411 * @return GNUNET_OK on success, GNUNET_SYSERR on error
412 */
413int
414GNUNET_DISK_file_write (const char *fileName,
415 const void *buffer, unsigned int n, const char *mode)
416{
417 int handle;
418 char *fn;
419
420 /* open file, open with 600, create if not
421 present, otherwise overwrite */
422 GNUNET_assert (fileName != NULL);
423 fn = GNUNET_STRINGS_filename_expand (fileName);
424 handle = GNUNET_DISK_file_open (fn, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
425 if (handle == -1)
426 {
427 GNUNET_free (fn);
428 return GNUNET_SYSERR;
429 }
430 GNUNET_assert ((n == 0) || (buffer != NULL));
431 /* write the buffer take length from the beginning */
432 if (n != WRITE (handle, buffer, n))
433 {
434 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", fn);
435 GNUNET_DISK_file_close (fn, handle);
436 GNUNET_free (fn);
437 return GNUNET_SYSERR;
438 }
439 GNUNET_DISK_file_close (fn, handle);
440 if (0 != CHMOD (fn, atoo (mode)))
441 {
442 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "chmod", fn);
443 }
444 GNUNET_free (fn);
445 return GNUNET_OK;
446}
447
448/**
449 * Scan a directory for files. The name of the directory
450 * must be expanded first (!).
451 * @param dirName the name of the directory
452 * @param callback the method to call for each file,
453 * can be NULL, in that case, we only count
454 * @param data argument to pass to callback
455 * @return the number of files found, GNUNET_SYSERR on error or
456 * ieration aborted by callback returning GNUNET_SYSERR
457 */
458int
459GNUNET_DISK_directory_scan (const char *dirName,
460 GNUNET_FileNameCallback callback, void *data)
461{
462 DIR *dinfo;
463 struct dirent *finfo;
464 struct stat istat;
465 int count = 0;
466 char *name;
467 char *dname;
468 unsigned int name_len;
469 unsigned int n_size;
470
471 GNUNET_assert (dirName != NULL);
472 dname = GNUNET_STRINGS_filename_expand (dirName);
473 while ((strlen (dname) > 0) && (dname[strlen (dname) - 1] == DIR_SEPARATOR))
474 dname[strlen (dname) - 1] = '\0';
475 if (0 != STAT (dname, &istat))
476 {
477 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "stat", dname);
478 GNUNET_free (dname);
479 return GNUNET_SYSERR;
480 }
481 if (!S_ISDIR (istat.st_mode))
482 {
483 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
484 _("Expected `%s' to be a directory!\n"), dirName);
485 GNUNET_free (dname);
486 return GNUNET_SYSERR;
487 }
488 errno = 0;
489 dinfo = OPENDIR (dname);
490 if ((errno == EACCES) || (dinfo == NULL))
491 {
492 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "opendir", dname);
493 if (dinfo != NULL)
494 closedir (dinfo);
495 GNUNET_free (dname);
496 return GNUNET_SYSERR;
497 }
498 name_len = 256;
499 n_size = strlen (dname) + name_len + 2;
500 name = GNUNET_malloc (n_size);
501 while ((finfo = readdir (dinfo)) != NULL)
502 {
503 if ((0 == strcmp (finfo->d_name, ".")) ||
504 (0 == strcmp (finfo->d_name, "..")))
505 continue;
506 if (callback != NULL)
507 {
508 if (name_len < strlen (finfo->d_name))
509 {
510 GNUNET_free (name);
511 name_len = strlen (finfo->d_name);
512 n_size = strlen (dname) + name_len + 2;
513 name = GNUNET_malloc (n_size);
514 }
515 /* dname can end in "/" only if dname == "/";
516 if dname does not end in "/", we need to add
517 a "/" (otherwise, we must not!) */
518 GNUNET_snprintf (name,
519 n_size,
520 "%s%s%s",
521 dname,
522 (strcmp (dname, DIR_SEPARATOR_STR) ==
523 0) ? "" : DIR_SEPARATOR_STR, finfo->d_name);
524 if (GNUNET_OK != callback (data, name))
525 {
526 closedir (dinfo);
527 GNUNET_free (name);
528 GNUNET_free (dname);
529 return GNUNET_SYSERR;
530 }
531 }
532 count++;
533 }
534 closedir (dinfo);
535 GNUNET_free (name);
536 GNUNET_free (dname);
537 return count;
538}
539
540
541/**
542 * Opaque handle used for iterating over a directory.
543 */
544struct GNUNET_DISK_DirectoryIterator
545{
546 /**
547 * Our scheduler.
548 */
549 struct GNUNET_SCHEDULER_Handle *sched;
550
551 /**
552 * Function to call on directory entries.
553 */
554 GNUNET_DISK_DirectoryIteratorCallback callback;
555
556 /**
557 * Closure for callback.
558 */
559 void *callback_cls;
560
561 /**
562 * Reference to directory.
563 */
564 DIR *directory;
565
566 /**
567 * Directory name.
568 */
569 char *dirname;
570
571 /**
572 * Next filename to process.
573 */
574 char *next_name;
575
576 /**
577 * Our priority.
578 */
579 enum GNUNET_SCHEDULER_Priority priority;
580
581};
582
583
584/**
585 * Task used by the directory iterator.
586 */
587static void
588directory_iterator_task (void *cls,
589 const struct GNUNET_SCHEDULER_TaskContext *tc)
590{
591 struct GNUNET_DISK_DirectoryIterator *iter = cls;
592 char *name;
593
594 name = iter->next_name;
595 GNUNET_assert (name != NULL);
596 iter->next_name = NULL;
597 iter->callback (iter->callback_cls, iter, name, iter->dirname);
598 GNUNET_free (name);
599}
600
601
602/**
603 * This function must be called during the DiskIteratorCallback
604 * (exactly once) to schedule the task to process the next
605 * filename in the directory (if there is one).
606 *
607 * @param iter opaque handle for the iterator
608 * @param can set to GNUNET_YES to terminate the iteration early
609 * @return GNUNET_YES if iteration will continue,
610 * GNUNET_NO if this was the last entry (and iteration is complete),
611 * GNUNET_SYSERR if abort was YES
612 */
613int
614GNUNET_DISK_directory_iterator_next (struct GNUNET_DISK_DirectoryIterator
615 *iter, int can)
616{
617 struct dirent *finfo;
618
619 GNUNET_assert (iter->next_name == NULL);
620 if (can == GNUNET_YES)
621 {
622 closedir (iter->directory);
623 GNUNET_free (iter->dirname);
624 GNUNET_free (iter);
625 return GNUNET_SYSERR;
626 }
627 while (NULL != (finfo = readdir (iter->directory)))
628 {
629 if ((0 == strcmp (finfo->d_name, ".")) ||
630 (0 == strcmp (finfo->d_name, "..")))
631 continue;
632 GNUNET_asprintf (&iter->next_name,
633 "%s%s%s",
634 iter->dirname, DIR_SEPARATOR_STR, finfo->d_name);
635 break;
636 }
637 if (finfo == NULL)
638 {
639 GNUNET_DISK_directory_iterator_next (iter, GNUNET_YES);
640 return GNUNET_NO;
641 }
642 GNUNET_SCHEDULER_add_after (iter->sched,
643 GNUNET_YES,
644 iter->priority,
645 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
646 &directory_iterator_task, iter);
647 return GNUNET_YES;
648}
649
650
651/**
652 * Scan a directory for files using the scheduler to run a task for
653 * each entry. The name of the directory must be expanded first (!).
654 * If a scheduler does not need to be used, GNUNET_DISK_directory_scan
655 * may provide a simpler API.
656 *
657 * @param sched scheduler to use
658 * @param prio priority to use
659 * @param dirName the name of the directory
660 * @param callback the method to call for each file
661 * @param callback_cls closure for callback
662 */
663void
664GNUNET_DISK_directory_iterator_start (struct GNUNET_SCHEDULER_Handle *sched,
665 enum GNUNET_SCHEDULER_Priority prio,
666 const char *dirName,
667 GNUNET_DISK_DirectoryIteratorCallback
668 callback, void *callback_cls)
669{
670 struct GNUNET_DISK_DirectoryIterator *di;
671
672 di = GNUNET_malloc (sizeof (struct GNUNET_DISK_DirectoryIterator));
673 di->sched = sched;
674 di->callback = callback;
675 di->callback_cls = callback_cls;
676 di->directory = OPENDIR (dirName);
677 di->dirname = GNUNET_strdup (dirName);
678 di->priority = prio;
679 GNUNET_DISK_directory_iterator_next (di, GNUNET_NO);
680}
681
682
683static int
684remove_helper (void *unused, const char *fn)
685{
686 GNUNET_DISK_directory_remove (fn);
687 return GNUNET_OK;
688}
689
690/**
691 * Remove all files in a directory (rm -rf). Call with
692 * caution.
693 *
694 *
695 * @param fileName the file to remove
696 * @return GNUNET_OK on success, GNUNET_SYSERR on error
697 */
698int
699GNUNET_DISK_directory_remove (const char *fileName)
700{
701 struct stat istat;
702
703 if (0 != LSTAT (fileName, &istat))
704 return GNUNET_NO; /* file may not exist... */
705 if (UNLINK (fileName) == 0)
706 return GNUNET_OK;
707 if ((errno != EISDIR) &&
708 /* EISDIR is not sufficient in all cases, e.g.
709 sticky /tmp directory may result in EPERM on BSD.
710 So we also explicitly check "isDirectory" */
711 (GNUNET_YES != GNUNET_DISK_directory_test (fileName)))
712 {
713 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "rmdir", fileName);
714 return GNUNET_SYSERR;
715 }
716 if (GNUNET_SYSERR ==
717 GNUNET_DISK_directory_scan (fileName, remove_helper, NULL))
718 return GNUNET_SYSERR;
719 if (0 != RMDIR (fileName))
720 {
721 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "rmdir", fileName);
722 return GNUNET_SYSERR;
723 }
724 return GNUNET_OK;
725}
726
727void
728GNUNET_DISK_file_close (const char *filename, int fd)
729{
730 if (0 != CLOSE (fd))
731 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "close", filename);
732}
733
734int
735GNUNET_DISK_file_open (const char *filename, int oflag, ...)
736{
737 char *fn;
738 int mode;
739 int ret;
740#ifdef MINGW
741 char szFile[_MAX_PATH + 1];
742 long lRet;
743
744 if ((lRet = plibc_conv_to_win_path (filename, szFile)) != ERROR_SUCCESS)
745 {
746 errno = ENOENT;
747 SetLastError (lRet);
748 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
749 "plibc_conv_to_win_path", filename);
750 return -1;
751 }
752 fn = GNUNET_strdup (szFile);
753#else
754 fn = GNUNET_STRINGS_filename_expand (filename);
755#endif
756 if (oflag & O_CREAT)
757 {
758 va_list arg;
759 va_start (arg, oflag);
760 mode = va_arg (arg, int);
761 va_end (arg);
762 }
763 else
764 {
765 mode = 0;
766 }
767#ifdef MINGW
768 /* set binary mode */
769 oflag |= O_BINARY;
770#endif
771 ret = OPEN (fn, oflag, mode);
772 if (ret == -1)
773 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "open", fn);
774 GNUNET_free (fn);
775 return ret;
776}
777
778#define COPY_BLK_SIZE 65536
779
780/**
781 * Copy a file.
782 * @return GNUNET_OK on success, GNUNET_SYSERR on error
783 */
784int
785GNUNET_DISK_file_copy (const char *src, const char *dst)
786{
787 char *buf;
788 unsigned long long pos;
789 unsigned long long size;
790 unsigned long long len;
791 int in;
792 int out;
793
794 if (GNUNET_OK != GNUNET_DISK_file_size (src, &size, GNUNET_YES))
795 return GNUNET_SYSERR;
796 pos = 0;
797 in = GNUNET_DISK_file_open (src, O_RDONLY | O_LARGEFILE);
798 if (in == -1)
799 return GNUNET_SYSERR;
800 out = GNUNET_DISK_file_open (dst,
801 O_LARGEFILE | O_WRONLY | O_CREAT | O_EXCL,
802 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
803 if (out == -1)
804 {
805 GNUNET_DISK_file_close (src, in);
806 return GNUNET_SYSERR;
807 }
808 buf = GNUNET_malloc (COPY_BLK_SIZE);
809 while (pos < size)
810 {
811 len = COPY_BLK_SIZE;
812 if (len > size - pos)
813 len = size - pos;
814 if (len != READ (in, buf, len))
815 goto FAIL;
816 if (len != WRITE (out, buf, len))
817 goto FAIL;
818 pos += len;
819 }
820 GNUNET_free (buf);
821 GNUNET_DISK_file_close (src, in);
822 GNUNET_DISK_file_close (dst, out);
823 return GNUNET_OK;
824FAIL:
825 GNUNET_free (buf);
826 GNUNET_DISK_file_close (src, in);
827 GNUNET_DISK_file_close (dst, out);
828 return GNUNET_SYSERR;
829}
830
831
832/**
833 * @brief Removes special characters as ':' from a filename.
834 * @param fn the filename to canonicalize
835 */
836void
837GNUNET_DISK_filename_canonicalize (char *fn)
838{
839 char *idx;
840 char c;
841
842 idx = fn;
843 while (*idx)
844 {
845 c = *idx;
846
847 if (c == '/' || c == '\\' || c == ':' || c == '*' || c == '?' ||
848 c == '"' || c == '<' || c == '>' || c == '|')
849 {
850 *idx = '_';
851 }
852
853 idx++;
854 }
855}
856
857
858
859/**
860 * @brief Change owner of a file
861 */
862int
863GNUNET_DISK_file_change_owner (const char *filename, const char *user)
864{
865#ifndef MINGW
866 struct passwd *pws;
867
868 pws = getpwnam (user);
869 if (pws == NULL)
870 {
871 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
872 _("Cannot obtain information about user `%s': %s\n"),
873 user, STRERROR (errno));
874 return GNUNET_SYSERR;
875 }
876 if (0 != chown (filename, pws->pw_uid, pws->pw_gid))
877 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "chown", filename);
878#endif
879 return GNUNET_OK;
880}
881
882
883/**
884 * Construct full path to a file inside of the private
885 * directory used by GNUnet. Also creates the corresponding
886 * directory. If the resulting name is supposed to be
887 * a directory, end the last argument in '/' (or pass
888 * DIR_SEPARATOR_STR as the last argument before NULL).
889 *
890 * @param serviceName name of the service
891 * @param varargs is NULL-terminated list of
892 * path components to append to the
893 * private directory name.
894 * @return the constructed filename
895 */
896char *
897GNUNET_DISK_get_home_filename (struct GNUNET_CONFIGURATION_Handle *cfg,
898 const char *serviceName, ...)
899{
900 const char *c;
901 char *pfx;
902 char *ret;
903 va_list ap;
904 unsigned int needed;
905
906 if (GNUNET_OK !=
907 GNUNET_CONFIGURATION_get_value_filename (cfg,
908 serviceName, "HOME", &pfx))
909 return NULL;
910 if (pfx == NULL)
911 {
912 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
913 _("No `%s' specified for service `%s' in configuration.\n"),
914 "HOME", serviceName);
915 return NULL;
916 }
917 needed = strlen (pfx) + 2;
918 if ((pfx[strlen (pfx) - 1] != '/') && (pfx[strlen (pfx) - 1] != '\\'))
919 needed++;
920 va_start (ap, serviceName);
921 while (1)
922 {
923 c = va_arg (ap, const char *);
924 if (c == NULL)
925 break;
926 needed += strlen (c);
927 if ((c[strlen (c) - 1] != '/') && (c[strlen (c) - 1] != '\\'))
928 needed++;
929 }
930 va_end (ap);
931 ret = GNUNET_malloc (needed);
932 strcpy (ret, pfx);
933 GNUNET_free (pfx);
934 va_start (ap, serviceName);
935 while (1)
936 {
937 c = va_arg (ap, const char *);
938 if (c == NULL)
939 break;
940 if ((c[strlen (c) - 1] != '/') && (c[strlen (c) - 1] != '\\'))
941 strcat (ret, DIR_SEPARATOR_STR);
942 strcat (ret, c);
943 }
944 va_end (ap);
945 if ((ret[strlen (ret) - 1] != '/') && (ret[strlen (ret) - 1] != '\\'))
946 GNUNET_DISK_directory_create_for_file (ret);
947 else
948 GNUNET_DISK_directory_create (ret);
949 return ret;
950}
951
952
953
954/* end of disk.c */
diff --git a/src/util/getopt.c b/src/util/getopt.c
new file mode 100644
index 000000000..e069e76f7
--- /dev/null
+++ b/src/util/getopt.c
@@ -0,0 +1,1077 @@
1/* Getopt for GNU.
2 NOTE: getopt is now part of the C library, so if you don't know what
3 "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
4 before changing it!
5
6 Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97
7 Free Software Foundation, Inc.
8
9NOTE: The canonical source of this file is maintained with the GNU C Library.
10Bugs can be reported to bug-glibc@prep.ai.mit.edu.
11
12This program is free software; you can redistribute it and/or modify it
13under the terms of the GNU General Public License as published by the
14Free Software Foundation; either version 2, or (at your option) any
15later version.
16
17This program is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU General Public License for more details.
21
22You should have received a copy of the GNU General Public License
23along with this program; if not, write to the Free Software
24Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25USA.
26
27
28This code was heavily modified for GNUnet.
29Copyright (C) 2006 Christian Grothoff
30*/
31
32/**
33 * @file util/getopt.c
34 * @brief GNU style option parsing
35 *
36 * TODO: get rid of statics (make reentrant) and
37 * replace main GNU getopt parser with one that
38 * actually fits our API.
39 */
40
41#include "platform.h"
42#include "gnunet_common.h"
43#include "gnunet_getopt_lib.h"
44
45#ifdef VMS
46# include <unixlib.h>
47# if HAVE_STRING_H - 0
48# include <string.h>
49# endif
50#endif
51
52#if defined (WIN32) && !defined (__CYGWIN32__)
53/* It's not Unix, really. See? Capital letters. */
54# include <windows.h>
55# define getpid() GetCurrentProcessId()
56#endif
57
58#ifndef _
59/* This is for other GNU distributions with internationalized messages.
60 When compiling libc, the _ macro is predefined. */
61# ifdef HAVE_LIBINTL_H
62# include <libintl.h>
63# define _(msgid) gettext (msgid)
64# else
65# define _(msgid) (msgid)
66# endif
67#endif
68
69/* Describe the long-named options requested by the application.
70 The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
71 of `struct GNoption' terminated by an element containing a name which is
72 zero.
73
74 The field `has_arg' is:
75 no_argument (or 0) if the option does not take an argument,
76 required_argument (or 1) if the option requires an argument,
77 optional_argument (or 2) if the option takes an optional argument.
78
79 If the field `flag' is not NULL, it points to a variable that is set
80 to the value given in the field `val' when the option is found, but
81 left unchanged if the option is not found.
82
83 To have a long-named option do something other than set an `int' to
84 a compiled-in constant, such as set a value from `GNoptarg', set the
85 option's `flag' field to zero and its `val' field to a nonzero
86 value (the equivalent single-letter option character, if there is
87 one). For long options that have a zero `flag' field, `getopt'
88 returns the contents of the `val' field. */
89
90struct GNoption
91{
92 const char *name;
93 /* has_arg can't be an enum because some compilers complain about
94 type mismatches in all the code that assumes it is an int. */
95 int has_arg;
96 int *flag;
97 int val;
98};
99
100
101/* This version of `getopt' appears to the caller like standard Unix `getopt'
102 but it behaves differently for the user, since it allows the user
103 to intersperse the options with the other arguments.
104
105 As `getopt' works, it permutes the elements of ARGV so that,
106 when it is done, all the options precede everything else. Thus
107 all application programs are extended to handle flexible argument order.
108
109 Setting the environment variable POSIXLY_CORRECT disables permutation.
110 Then the behavior is completely standard.
111
112 GNU application programs can use a third alternative mode in which
113 they can distinguish the relative order of options and other arguments. */
114
115/* For communication from `getopt' to the caller.
116 When `getopt' finds an option that takes an argument,
117 the argument value is returned here.
118 Also, when `ordering' is RETURN_IN_ORDER,
119 each non-option ARGV-element is returned here. */
120
121static char *GNoptarg = NULL;
122
123/* Index in ARGV of the next element to be scanned.
124 This is used for communication to and from the caller
125 and for communication between successive calls to `getopt'.
126
127 On entry to `getopt', zero means this is the first call; initialize.
128
129 When `getopt' returns -1, this is the index of the first of the
130 non-option elements that the caller should itself scan.
131
132 Otherwise, `GNoptind' communicates from one call to the next
133 how much of ARGV has been scanned so far. */
134
135/* 1003.2 says this must be 1 before any call. */
136static int GNoptind = 1;
137
138/* Formerly, initialization of getopt depended on GNoptind==0, which
139 causes problems with re-calling getopt as programs generally don't
140 know that. */
141
142static int __getopt_initialized = 0;
143
144/* The next char to be scanned in the option-element
145 in which the last option character we returned was found.
146 This allows us to pick up the scan where we left off.
147
148 If this is zero, or a null string, it means resume the scan
149 by advancing to the next ARGV-element. */
150
151static char *nextchar;
152
153/* Callers store zero here to inhibit the error message
154 for unrecognized options. */
155
156static int GNopterr = 1;
157
158/* Set to an option character which was unrecognized.
159 This must be initialized on some systems to avoid linking in the
160 system's own getopt implementation. */
161
162static int GNoptopt = '?';
163
164/* Describe how to deal with options that follow non-option ARGV-elements.
165
166 If the caller did not specify anything,
167 the default is REQUIRE_ORDER if the environment variable
168 POSIXLY_CORRECT is defined, PERMUTE otherwise.
169
170 REQUIRE_ORDER means don't recognize them as options;
171 stop option processing when the first non-option is seen.
172 This is what Unix does.
173 This mode of operation is selected by either setting the environment
174 variable POSIXLY_CORRECT, or using `+' as the first character
175 of the list of option characters.
176
177 PERMUTE is the default. We GNUNET_CRYPTO_random_permute the contents of ARGV as we scan,
178 so that eventually all the non-options are at the end. This allows options
179 to be given in any order, even with programs that were not written to
180 expect this.
181
182 RETURN_IN_ORDER is an option available to programs that were written
183 to expect GNoptions and other ARGV-elements in any order and that care about
184 the ordering of the two. We describe each non-option ARGV-element
185 as if it were the argument of an option with character code 1.
186 Using `-' as the first character of the list of option characters
187 selects this mode of operation.
188
189 The special argument `--' forces an end of option-scanning regardless
190 of the value of `ordering'. In the case of RETURN_IN_ORDER, only
191 `--' can cause `getopt' to return -1 with `GNoptind' != ARGC. */
192
193static enum
194{
195 REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
196} ordering;
197
198/* Value of POSIXLY_CORRECT environment variable. */
199static char *posixly_correct;
200
201#ifdef __GNU_LIBRARY__
202/* We want to avoid inclusion of string.h with non-GNU libraries
203 because there are many ways it can cause trouble.
204 On some systems, it contains special magic macros that don't work
205 in GCC. */
206#include <string.h>
207#define my_index strchr
208#else
209
210/* Avoid depending on library functions or files
211 whose names are inconsistent. */
212
213char *getenv ();
214
215static char *
216my_index (str, chr)
217 const char *str;
218 int chr;
219{
220 while (*str)
221 {
222 if (*str == chr)
223 return (char *) str;
224 str++;
225 }
226 return 0;
227}
228
229/* If using GCC, we can safely declare strlen this way.
230 If not using GCC, it is ok not to declare it. */
231#ifdef __GNUC__
232/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
233 That was relevant to code that was here before. */
234#if !defined (__STDC__) || !__STDC__
235/* gcc with -traditional declares the built-in strlen to return int,
236 and has done so at least since version 2.4.5. -- rms. */
237extern int strlen (const char *);
238#endif /* not __STDC__ */
239#endif /* __GNUC__ */
240
241#endif /* not __GNU_LIBRARY__ */
242
243/* Handle permutation of arguments. */
244
245/* Describe the part of ARGV that contains non-options that have
246 been skipped. `first_nonopt' is the index in ARGV of the first of them;
247 `last_nonopt' is the index after the last of them. */
248
249static int first_nonopt;
250static int last_nonopt;
251
252#ifdef _LIBC
253/* Bash 2.0 gives us an environment variable containing flags
254 indicating ARGV elements that should not be considered arguments. */
255
256/* Defined in getopt_init.c */
257extern char *__getopt_nonoption_flags;
258
259static int nonoption_flags_max_len;
260static int nonoption_flags_len;
261
262static int original_argc;
263static char *const *original_argv;
264
265extern pid_t __libc_pid;
266
267/* Make sure the environment variable bash 2.0 puts in the environment
268 is valid for the getopt call we must make sure that the ARGV passed
269 to getopt is that one passed to the process. */
270static void
271 __attribute__ ((unused)) store_args_and_env (int argc, char *const *argv)
272{
273 /* XXX This is no good solution. We should rather copy the args so
274 that we can compare them later. But we must not use malloc(3). */
275 original_argc = argc;
276 original_argv = argv;
277}
278
279text_set_element (__libc_subinit, store_args_and_env);
280
281# define SWAP_FLAGS(ch1, ch2) \
282 if (nonoption_flags_len > 0) \
283 { \
284 char __tmp = __getopt_nonoption_flags[ch1]; \
285 __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
286 __getopt_nonoption_flags[ch2] = __tmp; \
287 }
288#else /* !_LIBC */
289# define SWAP_FLAGS(ch1, ch2)
290#endif /* _LIBC */
291
292/* Exchange two adjacent subsequences of ARGV.
293 One subsequence is elements [first_nonopt,last_nonopt)
294 which contains all the non-options that have been skipped so far.
295 The other is elements [last_nonopt,GNoptind), which contains all
296 the options processed since those non-options were skipped.
297
298 `first_nonopt' and `last_nonopt' are relocated so that they describe
299 the new indices of the non-options in ARGV after they are moved. */
300
301#if defined (__STDC__) && __STDC__
302static void exchange (char **);
303#endif
304
305static void
306exchange (argv)
307 char **argv;
308{
309 int bottom = first_nonopt;
310 int middle = last_nonopt;
311 int top = GNoptind;
312 char *tem;
313
314 /* Exchange the shorter segment with the far end of the longer segment.
315 That puts the shorter segment into the right place.
316 It leaves the longer segment in the right place overall,
317 but it consists of two parts that need to be swapped next. */
318
319#ifdef _LIBC
320 /* First make sure the handling of the `__getopt_nonoption_flags'
321 string can work normally. Our top argument must be in the range
322 of the string. */
323 if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
324 {
325 /* We must extend the array. The user plays games with us and
326 presents new arguments. */
327 char *new_str = malloc (top + 1);
328 if (new_str == NULL)
329 nonoption_flags_len = nonoption_flags_max_len = 0;
330 else
331 {
332 memcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len);
333 memset (&new_str[nonoption_flags_max_len], '\0',
334 top + 1 - nonoption_flags_max_len);
335 nonoption_flags_max_len = top + 1;
336 __getopt_nonoption_flags = new_str;
337 }
338 }
339#endif
340
341 while (top > middle && middle > bottom)
342 {
343 if (top - middle > middle - bottom)
344 {
345 /* Bottom segment is the short one. */
346 int len = middle - bottom;
347 register int i;
348
349 /* Swap it with the top part of the top segment. */
350 for (i = 0; i < len; i++)
351 {
352 tem = argv[bottom + i];
353 argv[bottom + i] = argv[top - (middle - bottom) + i];
354 argv[top - (middle - bottom) + i] = tem;
355 SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
356 }
357 /* Exclude the moved bottom segment from further swapping. */
358 top -= len;
359 }
360 else
361 {
362 /* Top segment is the short one. */
363 int len = top - middle;
364 register int i;
365
366 /* Swap it with the bottom part of the bottom segment. */
367 for (i = 0; i < len; i++)
368 {
369 tem = argv[bottom + i];
370 argv[bottom + i] = argv[middle + i];
371 argv[middle + i] = tem;
372 SWAP_FLAGS (bottom + i, middle + i);
373 }
374 /* Exclude the moved top segment from further swapping. */
375 bottom += len;
376 }
377 }
378
379 /* Update records for the slots the non-options now occupy. */
380
381 first_nonopt += (GNoptind - last_nonopt);
382 last_nonopt = GNoptind;
383}
384
385/* Initialize the internal data when the first call is made. */
386
387#if defined (__STDC__) && __STDC__
388static const char *_getopt_initialize (int, char *const *, const char *);
389#endif
390static const char *
391_getopt_initialize (argc, argv, optstring)
392 int argc;
393 char *const *argv;
394 const char *optstring;
395{
396 /* Start processing options with ARGV-element 1 (since ARGV-element 0
397 is the program name); the sequence of previously skipped
398 non-option ARGV-elements is empty. */
399
400 first_nonopt = last_nonopt = GNoptind;
401
402 nextchar = NULL;
403
404 posixly_correct = getenv ("POSIXLY_CORRECT");
405
406 /* Determine how to handle the ordering of options and nonoptions. */
407
408 if (optstring[0] == '-')
409 {
410 ordering = RETURN_IN_ORDER;
411 ++optstring;
412 }
413 else if (optstring[0] == '+')
414 {
415 ordering = REQUIRE_ORDER;
416 ++optstring;
417 }
418 else if (posixly_correct != NULL)
419 ordering = REQUIRE_ORDER;
420 else
421 ordering = PERMUTE;
422
423#ifdef _LIBC
424 if (posixly_correct == NULL
425 && argc == original_argc && argv == original_argv)
426 {
427 if (nonoption_flags_max_len == 0)
428 {
429 if (__getopt_nonoption_flags == NULL
430 || __getopt_nonoption_flags[0] == '\0')
431 nonoption_flags_max_len = -1;
432 else
433 {
434 const char *orig_str = __getopt_nonoption_flags;
435 int len = nonoption_flags_max_len = strlen (orig_str);
436 if (nonoption_flags_max_len < argc)
437 nonoption_flags_max_len = argc;
438 __getopt_nonoption_flags =
439 (char *) malloc (nonoption_flags_max_len);
440 if (__getopt_nonoption_flags == NULL)
441 nonoption_flags_max_len = -1;
442 else
443 {
444 memcpy (__getopt_nonoption_flags, orig_str, len);
445 memset (&__getopt_nonoption_flags[len], '\0',
446 nonoption_flags_max_len - len);
447 }
448 }
449 }
450 nonoption_flags_len = nonoption_flags_max_len;
451 }
452 else
453 nonoption_flags_len = 0;
454#endif
455
456 return optstring;
457}
458
459/* Scan elements of ARGV (whose length is ARGC) for option characters
460 given in OPTSTRING.
461
462 If an element of ARGV starts with '-', and is not exactly "-" or "--",
463 then it is an option element. The characters of this element
464 (aside from the initial '-') are option characters. If `getopt'
465 is called repeatedly, it returns successively each of the option characters
466 from each of the option elements.
467
468 If `getopt' finds another option character, it returns that character,
469 updating `GNoptind' and `nextchar' so that the next call to `getopt' can
470 resume the scan with the following option character or ARGV-element.
471
472 If there are no more option characters, `getopt' returns -1.
473 Then `GNoptind' is the index in ARGV of the first ARGV-element
474 that is not an option. (The ARGV-elements have been permuted
475 so that those that are not options now come last.)
476
477 OPTSTRING is a string containing the legitimate option characters.
478 If an option character is seen that is not listed in OPTSTRING,
479 return '?' after printing an error message. If you set `GNopterr' to
480 zero, the error message is suppressed but we still return '?'.
481
482 If a char in OPTSTRING is followed by a colon, that means it wants an arg,
483 so the following text in the same ARGV-element, or the text of the following
484 ARGV-element, is returned in `GNoptarg'. Two colons mean an option that
485 wants an optional arg; if there is text in the current ARGV-element,
486 it is returned in `GNoptarg', otherwise `GNoptarg' is set to zero.
487
488 If OPTSTRING starts with `-' or `+', it requests different methods of
489 handling the non-option ARGV-elements.
490 See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
491
492 Long-named options begin with `--' instead of `-'.
493 Their names may be abbreviated as long as the abbreviation is unique
494 or is an exact match for some defined option. If they have an
495 argument, it follows the option name in the same ARGV-element, separated
496 from the option name by a `=', or else the in next ARGV-element.
497 When `getopt' finds a long-named option, it returns 0 if that option's
498 `flag' field is nonzero, the value of the option's `val' field
499 if the `flag' field is zero.
500
501 The elements of ARGV aren't really const, because we GNUNET_CRYPTO_random_permute them.
502 But we pretend they're const in the prototype to be compatible
503 with other systems.
504
505 LONGOPTS is a vector of `struct GNoption' terminated by an
506 element containing a name which is zero.
507
508 LONGIND returns the index in LONGOPT of the long-named option found.
509 It is only valid when a long-named option has been found by the most
510 recent call.
511
512 If LONG_ONLY is nonzero, '-' as well as '--' can introduce
513 long-named options. */
514
515static int
516GN_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
517 int argc;
518 char *const *argv;
519 const char *optstring;
520 const struct GNoption *longopts;
521 int *longind;
522 int long_only;
523{
524 GNoptarg = NULL;
525
526 if (GNoptind == 0 || !__getopt_initialized)
527 {
528 if (GNoptind == 0)
529 GNoptind = 1; /* Don't scan ARGV[0], the program name. */
530 optstring = _getopt_initialize (argc, argv, optstring);
531 __getopt_initialized = 1;
532 }
533
534 /* Test whether ARGV[GNoptind] points to a non-option argument.
535 Either it does not have option syntax, or there is an environment flag
536 from the shell indicating it is not an option. The later information
537 is only used when the used in the GNU libc. */
538#ifdef _LIBC
539#define NONOPTION_P (argv[GNoptind][0] != '-' || argv[GNoptind][1] == '\0' \
540 || (GNoptind < nonoption_flags_len \
541 && __getopt_nonoption_flags[GNoptind] == '1'))
542#else
543#define NONOPTION_P (argv[GNoptind][0] != '-' || argv[GNoptind][1] == '\0')
544#endif
545
546 if (nextchar == NULL || *nextchar == '\0')
547 {
548 /* Advance to the next ARGV-element. */
549
550 /* Give FIRST_NONOPT & LAST_NONOPT rational values if GNoptind has been
551 moved back by the user (who may also have changed the arguments). */
552 if (last_nonopt > GNoptind)
553 last_nonopt = GNoptind;
554 if (first_nonopt > GNoptind)
555 first_nonopt = GNoptind;
556
557 if (ordering == PERMUTE)
558 {
559 /* If we have just processed some options following some non-options,
560 exchange them so that the options come first. */
561
562 if (first_nonopt != last_nonopt && last_nonopt != GNoptind)
563 exchange ((char **) argv);
564 else if (last_nonopt != GNoptind)
565 first_nonopt = GNoptind;
566
567 /* Skip any additional non-options
568 and extend the range of non-options previously skipped. */
569
570 while (GNoptind < argc && NONOPTION_P)
571 GNoptind++;
572 last_nonopt = GNoptind;
573 }
574
575 /* The special ARGV-element `--' means premature end of options.
576 Skip it like a null option,
577 then exchange with previous non-options as if it were an option,
578 then skip everything else like a non-option. */
579 if (GNoptind != argc && !strcmp (argv[GNoptind], "--"))
580 {
581 GNoptind++;
582
583 if (first_nonopt != last_nonopt && last_nonopt != GNoptind)
584 exchange ((char **) argv);
585 else if (first_nonopt == last_nonopt)
586 first_nonopt = GNoptind;
587 last_nonopt = argc;
588
589 GNoptind = argc;
590 }
591
592 /* If we have done all the ARGV-elements, stop the scan
593 and back over any non-options that we skipped and permuted. */
594
595 if (GNoptind == argc)
596 {
597 /* Set the next-arg-index to point at the non-options
598 that we previously skipped, so the caller will digest them. */
599 if (first_nonopt != last_nonopt)
600 GNoptind = first_nonopt;
601 return -1;
602 }
603
604 /* If we have come to a non-option and did not permute it,
605 either stop the scan or describe it to the caller and pass it by. */
606
607 if (NONOPTION_P)
608 {
609 if (ordering == REQUIRE_ORDER)
610 return -1;
611 GNoptarg = argv[GNoptind++];
612 return 1;
613 }
614
615 /* We have found another option-ARGV-element.
616 Skip the initial punctuation. */
617
618 nextchar = (argv[GNoptind] + 1
619 + (longopts != NULL && argv[GNoptind][1] == '-'));
620 }
621
622 /* Decode the current option-ARGV-element. */
623
624 /* Check whether the ARGV-element is a long option.
625
626 If long_only and the ARGV-element has the form "-f", where f is
627 a valid short option, don't consider it an abbreviated form of
628 a long option that starts with f. Otherwise there would be no
629 way to give the -f short option.
630
631 On the other hand, if there's a long option "fubar" and
632 the ARGV-element is "-fu", do consider that an abbreviation of
633 the long option, just like "--fu", and not "-f" with arg "u".
634
635 This distinction seems to be the most useful approach. */
636
637 if (longopts != NULL
638 && (argv[GNoptind][1] == '-'
639 || (long_only
640 && (argv[GNoptind][2]
641 || !my_index (optstring, argv[GNoptind][1])))))
642 {
643 char *nameend;
644 const struct GNoption *p;
645 const struct GNoption *pfound = NULL;
646 int exact = 0;
647 int ambig = 0;
648 int indfound = -1;
649 int option_index;
650
651 for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
652 /* Do nothing. */ ;
653
654 /* Test all long options for either exact match
655 or abbreviated matches. */
656 for (p = longopts, option_index = 0; p->name; p++, option_index++)
657 if (!strncmp (p->name, nextchar, nameend - nextchar))
658 {
659 if ((unsigned int) (nameend - nextchar)
660 == (unsigned int) strlen (p->name))
661 {
662 /* Exact match found. */
663 pfound = p;
664 indfound = option_index;
665 exact = 1;
666 break;
667 }
668 else if (pfound == NULL)
669 {
670 /* First nonexact match found. */
671 pfound = p;
672 indfound = option_index;
673 }
674 else
675 /* Second or later nonexact match found. */
676 ambig = 1;
677 }
678
679 if (ambig && !exact)
680 {
681 if (GNopterr)
682 fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
683 argv[0], argv[GNoptind]);
684 nextchar += strlen (nextchar);
685 GNoptind++;
686 GNoptopt = 0;
687 return '?';
688 }
689
690 if (pfound != NULL)
691 {
692 option_index = indfound;
693 GNoptind++;
694 if (*nameend)
695 {
696 /* Don't test has_arg with >, because some C compilers don't
697 allow it to be used on enums. */
698 if (pfound->has_arg)
699 GNoptarg = nameend + 1;
700 else
701 {
702 if (GNopterr)
703 {
704 if (argv[GNoptind - 1][1] == '-')
705 /* --option */
706 fprintf (stderr,
707 _
708 ("%s: option `--%s' does not allow an argument\n"),
709 argv[0], pfound->name);
710 else
711 /* +option or -option */
712 fprintf (stderr,
713 _
714 ("%s: option `%c%s' does not allow an argument\n"),
715 argv[0], argv[GNoptind - 1][0],
716 pfound->name);
717 }
718 nextchar += strlen (nextchar);
719
720 GNoptopt = pfound->val;
721 return '?';
722 }
723 }
724 else if (pfound->has_arg == 1)
725 {
726 if (GNoptind < argc)
727 {
728 GNoptarg = argv[GNoptind++];
729 }
730 else
731 {
732 if (GNopterr)
733 {
734 fprintf (stderr,
735 _("%s: option `%s' requires an argument\n"),
736 argv[0], argv[GNoptind - 1]);
737 }
738 nextchar += strlen (nextchar);
739 GNoptopt = pfound->val;
740 return (optstring[0] == ':') ? ':' : '?';
741 }
742 }
743 nextchar += strlen (nextchar);
744 if (longind != NULL)
745 *longind = option_index;
746 if (pfound->flag)
747 {
748 *(pfound->flag) = pfound->val;
749 return 0;
750 }
751 return pfound->val;
752 }
753
754 /* Can't find it as a long option. If this is not getopt_long_only,
755 or the option starts with '--' or is not a valid short
756 option, then it's an error.
757 Otherwise interpret it as a short option. */
758 if (!long_only || argv[GNoptind][1] == '-'
759 || my_index (optstring, *nextchar) == NULL)
760 {
761 if (GNopterr)
762 {
763 if (argv[GNoptind][1] == '-')
764 /* --option */
765 fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
766 argv[0], nextchar);
767 else
768 /* +option or -option */
769 fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
770 argv[0], argv[GNoptind][0], nextchar);
771 }
772 nextchar = (char *) "";
773 GNoptind++;
774 GNoptopt = 0;
775 return '?';
776 }
777 }
778
779 /* Look at and handle the next short option-character. */
780
781 {
782 char c = *nextchar++;
783 char *temp = my_index (optstring, c);
784
785 /* Increment `GNoptind' when we start to process its last character. */
786 if (*nextchar == '\0')
787 ++GNoptind;
788
789 if (temp == NULL || c == ':')
790 {
791 if (GNopterr)
792 {
793 if (posixly_correct)
794 /* 1003.2 specifies the format of this message. */
795 fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
796 else
797 fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
798 }
799 GNoptopt = c;
800 return '?';
801 }
802 /* Convenience. Treat POSIX -W foo same as long option --foo */
803 if (temp[0] == 'W' && temp[1] == ';')
804 {
805 char *nameend;
806 const struct GNoption *p;
807 const struct GNoption *pfound = NULL;
808 int exact = 0;
809 int ambig = 0;
810 int indfound = 0;
811 int option_index;
812
813 /* This is an option that requires an argument. */
814 if (*nextchar != '\0')
815 {
816 GNoptarg = nextchar;
817 /* If we end this ARGV-element by taking the rest as an arg,
818 we must advance to the next element now. */
819 GNoptind++;
820 }
821 else if (GNoptind == argc)
822 {
823 if (GNopterr)
824 {
825 /* 1003.2 specifies the format of this message. */
826 fprintf (stderr, _("%s: option requires an argument -- %c\n"),
827 argv[0], c);
828 }
829 GNoptopt = c;
830 if (optstring[0] == ':')
831 c = ':';
832 else
833 c = '?';
834 return c;
835 }
836 else
837 /* We already incremented `GNoptind' once;
838 increment it again when taking next ARGV-elt as argument. */
839 GNoptarg = argv[GNoptind++];
840
841 /* GNoptarg is now the argument, see if it's in the
842 table of longopts. */
843
844 for (nextchar = nameend = GNoptarg; *nameend && *nameend != '=';
845 nameend++)
846 /* Do nothing. */ ;
847
848 /* Test all long options for either exact match
849 or abbreviated matches. */
850 for (p = longopts, option_index = 0; p->name; p++, option_index++)
851 if (!strncmp (p->name, nextchar, nameend - nextchar))
852 {
853 if ((unsigned int) (nameend - nextchar) == strlen (p->name))
854 {
855 /* Exact match found. */
856 pfound = p;
857 indfound = option_index;
858 exact = 1;
859 break;
860 }
861 else if (pfound == NULL)
862 {
863 /* First nonexact match found. */
864 pfound = p;
865 indfound = option_index;
866 }
867 else
868 /* Second or later nonexact match found. */
869 ambig = 1;
870 }
871 if (ambig && !exact)
872 {
873 if (GNopterr)
874 fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
875 argv[0], argv[GNoptind]);
876 nextchar += strlen (nextchar);
877 GNoptind++;
878 return '?';
879 }
880 if (pfound != NULL)
881 {
882 option_index = indfound;
883 if (*nameend)
884 {
885 /* Don't test has_arg with >, because some C compilers don't
886 allow it to be used on enums. */
887 if (pfound->has_arg)
888 GNoptarg = nameend + 1;
889 else
890 {
891 if (GNopterr)
892 fprintf (stderr, _("\
893%s: option `-W %s' does not allow an argument\n"), argv[0], pfound->name);
894
895 nextchar += strlen (nextchar);
896 return '?';
897 }
898 }
899 else if (pfound->has_arg == 1)
900 {
901 if (GNoptind < argc)
902 GNoptarg = argv[GNoptind++];
903 else
904 {
905 if (GNopterr)
906 fprintf (stderr,
907 _("%s: option `%s' requires an argument\n"),
908 argv[0], argv[GNoptind - 1]);
909 nextchar += strlen (nextchar);
910 return optstring[0] == ':' ? ':' : '?';
911 }
912 }
913 nextchar += strlen (nextchar);
914 if (longind != NULL)
915 *longind = option_index;
916 if (pfound->flag)
917 {
918 *(pfound->flag) = pfound->val;
919 return 0;
920 }
921 return pfound->val;
922 }
923 nextchar = NULL;
924 return 'W'; /* Let the application handle it. */
925 }
926 if (temp[1] == ':')
927 {
928 if (temp[2] == ':')
929 {
930 /* This is an option that accepts an argument optionally. */
931 if (*nextchar != '\0')
932 {
933 GNoptarg = nextchar;
934 GNoptind++;
935 }
936 else
937 GNoptarg = NULL;
938 nextchar = NULL;
939 }
940 else
941 {
942 /* This is an option that requires an argument. */
943 if (*nextchar != '\0')
944 {
945 GNoptarg = nextchar;
946 /* If we end this ARGV-element by taking the rest as an arg,
947 we must advance to the next element now. */
948 GNoptind++;
949 }
950 else if (GNoptind == argc)
951 {
952 if (GNopterr)
953 {
954 /* 1003.2 specifies the format of this message. */
955 fprintf (stderr,
956 _("%s: option requires an argument -- %c\n"),
957 argv[0], c);
958 }
959 GNoptopt = c;
960 if (optstring[0] == ':')
961 c = ':';
962 else
963 c = '?';
964 }
965 else
966 /* We already incremented `GNoptind' once;
967 increment it again when taking next ARGV-elt as argument. */
968 GNoptarg = argv[GNoptind++];
969 nextchar = NULL;
970 }
971 }
972 return c;
973 }
974}
975
976static int
977GNgetopt_long (int argc,
978 char *const *argv,
979 const char *options,
980 const struct GNoption *long_options, int *opt_index)
981{
982 return GN_getopt_internal (argc, argv, options, long_options, opt_index, 0);
983}
984
985/* ******************** now the GNUnet specific modifications... ********************* */
986
987/**
988 * Parse the command line.
989 *
990 * @param binaryName name of the binary / application with options
991 * @param cfg for storing/accessing configuration data
992 * @param allOptions defined options and handlers
993 * @param argc number of arguments
994 * @param argv actual arguments
995 * @return index into argv with first non-option
996 * argument, or -1 on error
997 */
998int
999GNUNET_GETOPT_run (const char *binaryOptions,
1000 struct GNUNET_CONFIGURATION_Handle *cfg,
1001 const struct GNUNET_GETOPT_CommandLineOption *allOptions,
1002 unsigned int argc, char *const *argv)
1003{
1004 struct GNoption *long_options;
1005 struct GNUNET_GETOPT_CommandLineProcessorContext clpc;
1006 int count;
1007 int i;
1008 char *shorts;
1009 int spos;
1010 int cont;
1011 int c;
1012
1013 GNUNET_assert (argc > 0);
1014 GNoptind = 0;
1015 clpc.binaryName = argv[0];
1016 clpc.binaryOptions = binaryOptions;
1017 clpc.allOptions = allOptions;
1018 clpc.argv = argv;
1019 clpc.argc = argc;
1020 clpc.cfg = cfg;
1021 count = 0;
1022 while (allOptions[count].name != NULL)
1023 count++;
1024 long_options = GNUNET_malloc (sizeof (struct GNoption) * (count + 1));
1025 shorts = GNUNET_malloc (count * 2 + 1);
1026 spos = 0;
1027 for (i = 0; i < count; i++)
1028 {
1029 long_options[i].name = allOptions[i].name;
1030 long_options[i].has_arg = allOptions[i].require_argument;
1031 long_options[i].flag = NULL;
1032 long_options[i].val = allOptions[i].shortName;
1033 shorts[spos++] = allOptions[i].shortName;
1034 if (allOptions[i].require_argument != 0)
1035 shorts[spos++] = ':';
1036 }
1037 long_options[count].name = NULL;
1038 long_options[count].has_arg = 0;
1039 long_options[count].flag = NULL;
1040 long_options[count].val = '\0';
1041 shorts[spos++] = '\0';
1042 cont = GNUNET_OK;
1043 /* main getopt loop */
1044 while (cont == GNUNET_OK)
1045 {
1046 int option_index = 0;
1047 c = GNgetopt_long (argc, argv, shorts, long_options, &option_index);
1048
1049 if (c == GNUNET_SYSERR)
1050 break; /* No more flags to process */
1051
1052 for (i = 0; i < count; i++)
1053 {
1054 clpc.currentArgument = GNoptind - 1;
1055 if ((char) c == allOptions[i].shortName)
1056 {
1057 cont = allOptions[i].processor (&clpc,
1058 allOptions[i].scls,
1059 allOptions[i].name, GNoptarg);
1060 break;
1061 }
1062 }
1063 if (i == count)
1064 {
1065 fprintf (stderr, _("Use --help to get a list of options.\n"));
1066 cont = GNUNET_SYSERR;
1067 }
1068 }
1069
1070 GNUNET_free (shorts);
1071 GNUNET_free (long_options);
1072 if (cont == GNUNET_SYSERR)
1073 return GNUNET_SYSERR;
1074 return GNoptind;
1075}
1076
1077/* end of getopt.c */
diff --git a/src/util/getopt_helpers.c b/src/util/getopt_helpers.c
new file mode 100644
index 000000000..3aea5d102
--- /dev/null
+++ b/src/util/getopt_helpers.c
@@ -0,0 +1,200 @@
1/*
2 This file is part of GNUnet
3 (C) 2006 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 2, 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 src/util/getopt_helpers.c
23 * @brief implements command line that sets option
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_common.h"
29#include "gnunet_getopt_lib.h"
30
31
32int
33GNUNET_GETOPT_print_version_ (struct GNUNET_GETOPT_CommandLineProcessorContext
34 *ctx, void *scls, const char *option,
35 const char *value)
36{
37 const char *version = scls;
38
39 printf ("%s v%s\n", ctx->binaryName, version);
40 return GNUNET_SYSERR;
41}
42
43
44
45#define BORDER 29
46
47int
48GNUNET_GETOPT_format_help_ (struct GNUNET_GETOPT_CommandLineProcessorContext
49 *ctx, void *scls, const char *option,
50 const char *value)
51{
52 const char *about = scls;
53 int slen;
54 int i;
55 int j;
56 int ml;
57 int p;
58 char *scp;
59 const char *trans;
60 const struct GNUNET_GETOPT_CommandLineOption *opt;
61
62 printf ("%s\n%s\n", ctx->binaryOptions, gettext (about));
63 printf (_
64 ("Arguments mandatory for long options are also mandatory for short options.\n"));
65 slen = 0;
66 i = 0;
67 opt = ctx->allOptions;
68 while (opt[i].description != NULL)
69 {
70 if (opt[i].shortName == '\0')
71 printf (" ");
72 else
73 printf (" -%c, ", opt[i].shortName);
74 printf ("--%s", opt[i].name);
75 slen = 8 + strlen (opt[i].name);
76 if (opt[i].argumentHelp != NULL)
77 {
78 printf ("=%s", opt[i].argumentHelp);
79 slen += 1 + strlen (opt[i].argumentHelp);
80 }
81 if (slen > BORDER)
82 {
83 printf ("\n%*s", BORDER, "");
84 slen = BORDER;
85 }
86 if (slen < BORDER)
87 {
88 printf ("%*s", BORDER - slen, "");
89 slen = BORDER;
90 }
91 trans = gettext (opt[i].description);
92 ml = strlen (trans);
93 p = 0;
94 OUTER:
95 while (ml - p > 78 - slen)
96 {
97 for (j = p + 78 - slen; j > p; j--)
98 {
99 if (isspace (trans[j]))
100 {
101 scp = GNUNET_malloc (j - p + 1);
102 memcpy (scp, &trans[p], j - p);
103 scp[j - p] = '\0';
104 printf ("%s\n%*s", scp, BORDER + 2, "");
105 GNUNET_free (scp);
106 p = j + 1;
107 slen = BORDER + 2;
108 goto OUTER;
109 }
110 }
111 /* could not find space to break line */
112 scp = GNUNET_malloc (78 - slen + 1);
113 memcpy (scp, &trans[p], 78 - slen);
114 scp[78 - slen] = '\0';
115 printf ("%s\n%*s", scp, BORDER + 2, "");
116 GNUNET_free (scp);
117 slen = BORDER + 2;
118 p = p + 78 - slen;
119 }
120 /* print rest */
121 if (p < ml)
122 printf ("%s\n", &trans[p]);
123 if (strlen (trans) == 0)
124 printf ("\n");
125 i++;
126 }
127 printf ("Report bugs to gnunet-developers@gnu.org.\n"
128 "GNUnet home page: http://www.gnu.org/software/gnunet/\n"
129 "General help using GNU software: http://www.gnu.org/gethelp/\n");
130 return GNUNET_SYSERR;
131}
132
133
134int
135GNUNET_GETOPT_increment_value (struct
136 GNUNET_GETOPT_CommandLineProcessorContext *ctx,
137 void *scls, const char *cmdLineOption,
138 const char *value)
139{
140 int *val = scls;
141 (*val)++;
142 return GNUNET_OK;
143}
144
145int
146GNUNET_GETOPT_set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
147 void *scls, const char *option, const char *value)
148{
149 int *val = scls;
150 *val = 1;
151 return GNUNET_OK;
152}
153
154int
155GNUNET_GETOPT_set_string (struct GNUNET_GETOPT_CommandLineProcessorContext
156 *ctx, void *scls, const char *option,
157 const char *value)
158{
159 char **val = scls;
160
161 GNUNET_assert (value != NULL);
162 if (NULL != *val)
163 GNUNET_free (*val);
164 *val = GNUNET_strdup (value);
165 return GNUNET_OK;
166}
167
168int
169GNUNET_GETOPT_set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext
170 *ctx, void *scls, const char *option,
171 const char *value)
172{
173 unsigned long long *val = scls;
174 if (1 != SSCANF (value, "%llu", val))
175 {
176 fprintf (stderr,
177 _("You must pass a number to the `%s' option.\n"), "-X");
178 return GNUNET_SYSERR;
179 }
180 return GNUNET_OK;
181}
182
183
184int
185GNUNET_GETOPT_set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
186 void *scls, const char *option, const char *value)
187{
188 unsigned int *val = scls;
189
190 if (1 != SSCANF (value, "%u", val))
191 {
192 fprintf (stderr,
193 _("You must pass a number to the `%s' option.\n"), "-X");
194 return GNUNET_SYSERR;
195 }
196 return GNUNET_OK;
197}
198
199
200/* end of getopt_helpers.c */
diff --git a/src/util/network.c b/src/util/network.c
new file mode 100644
index 000000000..22c1ca632
--- /dev/null
+++ b/src/util/network.c
@@ -0,0 +1,1239 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/network/network.c
23 * @brief basic, low-level TCP networking interface
24 * @author Christian Grothoff
25 *
26 * This code is rather complex. Only modify it if you
27 * 1) Have a NEW testcase showing that the new code
28 * is needed and correct
29 * 2) All EXISTING testcases pass with the new code
30 * These rules should apply in general, but for this
31 * module they are VERY, VERY important.
32 *
33 * TODO:
34 * - can we merge receive_ready and receive_again?
35 * - can we integrate the nth.timeout_task with the write_task's timeout?
36 */
37
38#include "platform.h"
39#include "gnunet_common.h"
40#include "gnunet_network_lib.h"
41#include "gnunet_scheduler_lib.h"
42
43#define DEBUG_NETWORK GNUNET_NO
44
45struct GNUNET_NETWORK_TransmitHandle
46{
47
48 /**
49 * Function to call if the send buffer has notify_size
50 * bytes available.
51 */
52 GNUNET_NETWORK_TransmitReadyNotify notify_ready;
53
54 /**
55 * Closure for notify_ready.
56 */
57 void *notify_ready_cls;
58
59 /**
60 * Our socket handle.
61 */
62 struct GNUNET_NETWORK_SocketHandle *sh;
63
64 /**
65 * Timeout for receiving (in absolute time).
66 */
67 struct GNUNET_TIME_Absolute transmit_timeout;
68
69 /**
70 * Task called on timeout.
71 */
72 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
73
74 /**
75 * At what number of bytes available in the
76 * write buffer should the notify method be called?
77 */
78 size_t notify_size;
79
80};
81
82/**
83 * @brief handle for a network socket
84 */
85struct GNUNET_NETWORK_SocketHandle
86{
87
88 /**
89 * Scheduler that was used for the connect task.
90 */
91 struct GNUNET_SCHEDULER_Handle *sched;
92
93 /**
94 * Address information for connect (may be NULL).
95 */
96 struct addrinfo *ai;
97
98 /**
99 * Index for the next struct addrinfo for connect attempts (may be NULL)
100 */
101 struct addrinfo *ai_pos;
102
103 /**
104 * Network address of the other end-point, may be NULL.
105 */
106 struct sockaddr *addr;
107
108 /**
109 * Pointer to our write buffer.
110 */
111 char *write_buffer;
112
113 /**
114 * Size of our write buffer.
115 */
116 size_t write_buffer_size;
117
118 /**
119 * Current write-offset in write buffer (where
120 * would we write next).
121 */
122 size_t write_buffer_off;
123
124 /**
125 * Current read-offset in write buffer (how many
126 * bytes have already been send).
127 */
128 size_t write_buffer_pos;
129
130 /**
131 * Length of addr.
132 */
133 socklen_t addrlen;
134
135 /**
136 * Connect task that we may need to wait for.
137 */
138 GNUNET_SCHEDULER_TaskIdentifier connect_task;
139
140 /**
141 * Read task that we may need to wait for.
142 */
143 GNUNET_SCHEDULER_TaskIdentifier read_task;
144
145 /**
146 * Write task that we may need to wait for.
147 */
148 GNUNET_SCHEDULER_TaskIdentifier write_task;
149
150 /**
151 * The handle we return for GNUNET_NETWORK_notify_transmit_ready.
152 */
153 struct GNUNET_NETWORK_TransmitHandle nth;
154
155 /**
156 * Underlying OS's socket, set to -1 after fatal errors.
157 */
158 int sock;
159
160 /**
161 * Port to connect to.
162 */
163 uint16_t port;
164
165 /**
166 * Function to call on data received, NULL
167 * if no receive is pending.
168 */
169 GNUNET_NETWORK_Receiver receiver;
170
171 /**
172 * Closure for receiver.
173 */
174 void *receiver_cls;
175
176 /**
177 * Timeout for receiving (in absolute time).
178 */
179 struct GNUNET_TIME_Absolute receive_timeout;
180
181 /**
182 * Maximum number of bytes to read
183 * (for receiving).
184 */
185 size_t max;
186
187};
188
189
190/**
191 * Create a socket handle by boxing an existing OS socket. The OS
192 * socket should henceforth be no longer used directly.
193 * GNUNET_socket_destroy will close it.
194 *
195 * @param sched scheduler to use
196 * @param osSocket existing socket to box
197 * @param maxbuf maximum write buffer size for the socket (use
198 * 0 for sockets that need no write buffers, such as listen sockets)
199 * @return the boxed socket handle
200 */
201struct GNUNET_NETWORK_SocketHandle *
202GNUNET_NETWORK_socket_create_from_existing (struct GNUNET_SCHEDULER_Handle
203 *sched, int osSocket,
204 size_t maxbuf)
205{
206 struct GNUNET_NETWORK_SocketHandle *ret;
207 ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_SocketHandle) + maxbuf);
208 ret->write_buffer = (char *) &ret[1];
209 ret->write_buffer_size = maxbuf;
210 ret->sock = osSocket;
211 ret->sched = sched;
212 return ret;
213}
214
215
216/**
217 * Create a socket handle by accepting on a listen socket. This
218 * function may block if the listen socket has no connection ready.
219 *
220 * @param sched scheduler to use
221 * @param access function to use to check if access is allowed
222 * @param access_cls closure for access
223 * @param lsock listen socket
224 * @param maxbuf maximum write buffer size for the socket (use
225 * 0 for sockets that need no write buffers, such as listen sockets)
226 * @return the socket handle, NULL on error
227 */
228struct GNUNET_NETWORK_SocketHandle *
229GNUNET_NETWORK_socket_create_from_accept (struct GNUNET_SCHEDULER_Handle
230 *sched,
231 GNUNET_NETWORK_AccessCheck access,
232 void *access_cls, int lsock,
233 size_t maxbuf)
234{
235 struct GNUNET_NETWORK_SocketHandle *ret;
236 char addr[32];
237 char msg[INET6_ADDRSTRLEN];
238 socklen_t addrlen;
239 int fam;
240 int fd;
241 int aret;
242 struct sockaddr_in *v4;
243 struct sockaddr_in6 *v6;
244 struct sockaddr *sa;
245 void *uaddr;
246
247 addrlen = sizeof (addr);
248 fd = accept (lsock, (struct sockaddr *) &addr, &addrlen);
249 if (fd == -1)
250 {
251 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept");
252 return NULL;
253 }
254 if (0 != fcntl (fd, F_SETFD, fcntl (fd, F_GETFD) | FD_CLOEXEC))
255 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
256 "fcntl");
257 if (addrlen > sizeof (addr))
258 {
259 GNUNET_break (0);
260 GNUNET_break (0 == CLOSE (fd));
261 return NULL;
262 }
263
264 sa = (struct sockaddr *) addr;
265 v6 = (struct sockaddr_in6 *) addr;
266 if ((sa->sa_family == AF_INET6) && (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr)))
267 {
268 /* convert to V4 address */
269 v4 = GNUNET_malloc (sizeof (struct sockaddr_in));
270 memset (v4, 0, sizeof (struct sockaddr_in));
271 v4->sin_family = AF_INET;
272 memcpy (&v4->sin_addr,
273 &((char *) &v6->sin6_addr)[sizeof (struct in6_addr) -
274 sizeof (struct in_addr)],
275 sizeof (struct in_addr));
276 v4->sin_port = v6->sin6_port;
277 uaddr = v4;
278 addrlen = sizeof (struct sockaddr_in);
279 }
280 else
281 {
282 uaddr = GNUNET_malloc (addrlen);
283 memcpy (uaddr, addr, addrlen);
284 }
285
286 if ((access != NULL) &&
287 (GNUNET_YES != (aret = access (access_cls, uaddr, addrlen))))
288 {
289 if (aret == GNUNET_NO)
290 {
291 fam = ((struct sockaddr *) addr)->sa_family;
292 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
293 _("Access denied to `%s'\n"),
294 inet_ntop (fam,
295 (fam == AF_INET6)
296 ? (const void *) &((struct sockaddr_in6 *)
297 &addr)->
298 sin6_addr : (const void *)
299 &((struct sockaddr_in *) &addr)->sin_addr,
300 msg, sizeof (msg)));
301 }
302 GNUNET_break (0 == SHUTDOWN (fd, SHUT_RDWR));
303 GNUNET_break (0 == CLOSE (fd));
304 GNUNET_free (uaddr);
305 return NULL;
306 }
307 ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_SocketHandle) + maxbuf);
308 ret->write_buffer = (char *) &ret[1];
309 ret->write_buffer_size = maxbuf;
310 ret->addr = uaddr;
311 ret->addrlen = addrlen;
312 ret->sock = fd;
313 ret->sched = sched;
314 return ret;
315}
316
317/**
318 * Obtain the network address of the other party.
319 *
320 * @param sock the client to get the address for
321 * @param addr where to store the address
322 * @param addrlen where to store the length of the address
323 * @return GNUNET_OK on success
324 */
325int
326GNUNET_NETWORK_socket_get_address (struct GNUNET_NETWORK_SocketHandle *sock,
327 void **addr, size_t * addrlen)
328{
329 if ((sock->addr == NULL) || (sock->addrlen == 0))
330 return GNUNET_NO;
331 *addr = GNUNET_malloc (sock->addrlen);
332 memcpy (*addr, sock->addr, sock->addrlen);
333 *addrlen = sock->addrlen;
334 return GNUNET_OK;
335}
336
337
338/**
339 * Set if a socket should use blocking or non-blocking IO.
340 *
341 * @return GNUNET_OK on success, GNUNET_SYSERR on error
342 */
343static int
344socket_set_blocking (int handle, int doBlock)
345{
346#if MINGW
347 u_long mode;
348 mode = !doBlock;
349#if HAVE_PLIBC_FD
350 if (ioctlsocket (plibc_fd_get_handle (handle), FIONBIO, &mode) ==
351 SOCKET_ERROR)
352 {
353 SetErrnoFromWinsockError (WSAGetLastError ());
354 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "ioctlsocket");
355 return GNUNET_SYSERR;
356 }
357#else
358 if (ioctlsocket (handle, FIONBIO, &mode) == SOCKET_ERROR)
359 {
360 SetErrnoFromWinsockError (WSAGetLastError ());
361 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "ioctlsocket");
362 return GNUNET_SYSERR;
363 }
364#endif
365 /* store the blocking mode */
366#if HAVE_PLIBC_FD
367 plibc_fd_set_blocking (handle, doBlock);
368#else
369 __win_SetHandleBlockingMode (handle, doBlock);
370#endif
371 return GNUNET_OK;
372
373#else
374 /* not MINGW */
375 int flags = fcntl (handle, F_GETFL);
376 if (flags == -1)
377 {
378 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "fcntl");
379 return GNUNET_SYSERR;
380 }
381 if (doBlock)
382 flags &= ~O_NONBLOCK;
383 else
384 flags |= O_NONBLOCK;
385 if (0 != fcntl (handle, F_SETFL, flags))
386 {
387 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "fcntl");
388 return GNUNET_SYSERR;
389 }
390 return GNUNET_OK;
391#endif
392}
393
394
395/**
396 * Initiate asynchronous TCP connect request.
397 *
398 * @param sock what socket to connect
399 * @return GNUNET_SYSERR error (no more addresses to try)
400 */
401static int
402try_connect (struct GNUNET_NETWORK_SocketHandle *sock)
403{
404 int s;
405
406 if (sock->addr != NULL)
407 {
408 GNUNET_free (sock->addr);
409 sock->addr = NULL;
410 sock->addrlen = 0;
411 }
412 while (1)
413 {
414 if (sock->ai_pos == NULL)
415 {
416 /* no more addresses to try, fatal! */
417 return GNUNET_SYSERR;
418 }
419 switch (sock->ai_pos->ai_family)
420 {
421 case AF_INET:
422 ((struct sockaddr_in *) sock->ai_pos->ai_addr)->sin_port =
423 htons (sock->port);
424 break;
425 case AF_INET6:
426 ((struct sockaddr_in6 *) sock->ai_pos->ai_addr)->sin6_port =
427 htons (sock->port);
428 break;
429 default:
430 sock->ai_pos = sock->ai_pos->ai_next;
431 continue;
432 }
433 s = SOCKET (sock->ai_pos->ai_family, SOCK_STREAM, 0);
434 if (s == -1)
435 {
436 /* maybe unsupported address family, try next */
437 GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "socket");
438 sock->ai_pos = sock->ai_pos->ai_next;
439 continue;
440 }
441 if (0 != fcntl (s, F_SETFD, fcntl (s, F_GETFD) | FD_CLOEXEC))
442 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
443 "fcntl");
444 if (GNUNET_SYSERR == socket_set_blocking (s, GNUNET_NO))
445 {
446 /* we'll treat this one as fatal */
447 GNUNET_break (0 == CLOSE (s));
448 return GNUNET_SYSERR;
449 }
450 if ((0 != CONNECT (s,
451 sock->ai_pos->ai_addr,
452 sock->ai_pos->ai_addrlen)) && (errno != EINPROGRESS))
453 {
454 /* maybe refused / unsupported address, try next */
455 GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "connect");
456 GNUNET_break (0 == CLOSE (s));
457 continue;
458 }
459 break;
460 }
461 /* got one! copy address information! */
462 sock->addrlen = sock->ai_pos->ai_addrlen;
463 sock->addr = GNUNET_malloc (sock->addrlen);
464 memcpy (sock->addr, sock->ai_pos->ai_addr, sock->addrlen);
465 sock->ai_pos = sock->ai_pos->ai_next;
466 sock->sock = s;
467 return GNUNET_OK;
468}
469
470
471/**
472 * Scheduler let us know that we're either ready to
473 * write on the socket OR connect timed out. Do the
474 * right thing.
475 */
476static void
477connect_continuation (void *cls,
478 const struct GNUNET_SCHEDULER_TaskContext *tc)
479{
480 struct GNUNET_NETWORK_SocketHandle *sock = cls;
481 unsigned int len;
482 int error;
483
484 /* nobody needs to wait for us anymore... */
485 sock->connect_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
486 /* Note: write-ready does NOT mean connect succeeded,
487 we need to use getsockopt to be sure */
488 len = sizeof (error);
489 errno = 0;
490 error = 0;
491 if ((0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ||
492 (0 != getsockopt (sock->sock, SOL_SOCKET, SO_ERROR, &error, &len)) ||
493 (error != 0) || (errno != 0))
494 {
495 /* connect failed / timed out */
496 GNUNET_break (0 == CLOSE (sock->sock));
497 sock->sock = -1;
498 if (GNUNET_SYSERR == try_connect (sock))
499 {
500 /* failed for good */
501 GNUNET_break (sock->ai_pos == NULL);
502 freeaddrinfo (sock->ai);
503 sock->ai = NULL;
504 return;
505 }
506 sock->connect_task = GNUNET_SCHEDULER_add_write (tc->sched, GNUNET_NO, /* abort on shutdown */
507 GNUNET_SCHEDULER_PRIORITY_KEEP,
508 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
509 GNUNET_NETWORK_CONNECT_RETRY_TIMEOUT,
510 sock->sock,
511 &connect_continuation,
512 sock);
513 return;
514 }
515 /* connect succeeded! clean up "ai" */
516#if DEBUG_NETWORK
517 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection succeeded!\n");
518#endif
519 freeaddrinfo (sock->ai);
520 sock->ai_pos = NULL;
521 sock->ai = NULL;
522}
523
524
525/**
526 * Create a socket handle by (asynchronously) connecting to a host.
527 * This function returns immediately, even if the connection has not
528 * yet been established. This function only creates TCP connections.
529 *
530 * @param sched scheduler to use
531 * @param hostname name of the host to connect to
532 * @param port port to connect to
533 * @param maxbuf maximum write buffer size for the socket (use
534 * 0 for sockets that need no write buffers, such as listen sockets)
535 * @return the socket handle
536 */
537struct GNUNET_NETWORK_SocketHandle *
538GNUNET_NETWORK_socket_create_from_connect (struct GNUNET_SCHEDULER_Handle
539 *sched, const char *hostname,
540 uint16_t port, size_t maxbuf)
541{
542 struct GNUNET_NETWORK_SocketHandle *ret;
543 struct addrinfo hints;
544 int ec;
545
546 ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_SocketHandle) + maxbuf);
547 ret->sock = -1;
548 ret->sched = sched;
549 ret->write_buffer = (char *) &ret[1];
550 ret->write_buffer_size = maxbuf;
551 ret->port = port;
552 memset (&hints, 0, sizeof (hints));
553 hints.ai_family = AF_UNSPEC;
554 hints.ai_socktype = SOCK_STREAM;
555 if (0 != (ec = getaddrinfo (hostname, NULL, &hints, &ret->ai)))
556 {
557 GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
558 "`%s' failed for hostname `%s': %s\n",
559 "getaddrinfo", hostname, gai_strerror (ec));
560 GNUNET_free (ret);
561 return NULL;
562 }
563 ret->ai_pos = ret->ai;
564 if (GNUNET_SYSERR == try_connect (ret))
565 {
566 freeaddrinfo (ret->ai);
567 GNUNET_free (ret);
568 return NULL;
569 }
570 ret->connect_task = GNUNET_SCHEDULER_add_write (sched, GNUNET_NO, /* abort on shutdown */
571 GNUNET_SCHEDULER_PRIORITY_KEEP,
572 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
573 GNUNET_NETWORK_CONNECT_RETRY_TIMEOUT,
574 ret->sock,
575 &connect_continuation, ret);
576 return ret;
577
578}
579
580
581/**
582 * Create a socket handle by (asynchronously) connecting to a host.
583 * This function returns immediately, even if the connection has not
584 * yet been established. This function only creates TCP connections.
585 *
586 * @param sched scheduler to use
587 * @param af_family address family to use
588 * @param serv_addr server address
589 * @param addrlen length of server address
590 * @param maxbuf maximum write buffer size for the socket (use
591 * 0 for sockets that need no write buffers, such as listen sockets)
592 * @return the socket handle
593 */
594struct GNUNET_NETWORK_SocketHandle *
595GNUNET_NETWORK_socket_create_from_sockaddr (struct GNUNET_SCHEDULER_Handle
596 *sched, int af_family,
597 const struct sockaddr *serv_addr,
598 socklen_t addrlen, size_t maxbuf)
599{
600 int s;
601
602 s = SOCKET (af_family, SOCK_STREAM, 0);
603 if (s == -1)
604 {
605 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING |
606 GNUNET_ERROR_TYPE_BULK, "socket");
607 return NULL;
608 }
609 if (0 != fcntl (s, F_SETFD, fcntl (s, F_GETFD) | FD_CLOEXEC))
610 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
611 "fcntl");
612 if (GNUNET_SYSERR == socket_set_blocking (s, GNUNET_NO))
613 {
614 /* we'll treat this one as fatal */
615 GNUNET_break (0 == CLOSE (s));
616 return NULL;
617 }
618 if ((0 != CONNECT (s, serv_addr, addrlen)) && (errno != EINPROGRESS))
619 {
620 /* maybe refused / unsupported address, try next */
621 GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "connect");
622 GNUNET_break (0 == CLOSE (s));
623 return NULL;
624 }
625 return GNUNET_NETWORK_socket_create_from_existing (sched, s, maxbuf);
626}
627
628
629/**
630 * Check if socket is valid (no fatal errors have happened so far).
631 * Note that a socket that is still trying to connect is considered
632 * valid.
633 *
634 * @param sock socket to check
635 * @return GNUNET_YES if valid, GNUNET_NO otherwise
636 */
637int
638GNUNET_NETWORK_socket_check (struct GNUNET_NETWORK_SocketHandle *sock)
639{
640 if (sock->ai != NULL)
641 return GNUNET_YES; /* still trying to connect */
642 return (sock->sock == -1) ? GNUNET_NO : GNUNET_YES;
643}
644
645
646/**
647 * Scheduler let us know that the connect task is finished (or was
648 * cancelled due to shutdown). Now really clean up.
649 */
650static void
651destroy_continuation (void *cls,
652 const struct GNUNET_SCHEDULER_TaskContext *tc)
653{
654 struct GNUNET_NETWORK_SocketHandle *sock = cls;
655 GNUNET_NETWORK_TransmitReadyNotify notify;
656
657 if (sock->write_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
658 {
659#if DEBUG_NETWORK
660 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
661 "Destroy code waiting for writes to complete.\n");
662#endif
663 GNUNET_SCHEDULER_add_after (sock->sched,
664 GNUNET_YES,
665 GNUNET_SCHEDULER_PRIORITY_KEEP,
666 sock->write_task,
667 &destroy_continuation, sock);
668 return;
669 }
670 if (sock->sock != -1)
671 {
672#if DEBUG_NETWORK
673 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down socket.\n");
674#endif
675 SHUTDOWN (sock->sock, SHUT_RDWR);
676 }
677 if (sock->read_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
678 {
679#if DEBUG_NETWORK
680 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
681 "Destroy code waiting for receive to complete.\n");
682#endif
683 GNUNET_SCHEDULER_add_after (sock->sched,
684 GNUNET_YES,
685 GNUNET_SCHEDULER_PRIORITY_KEEP,
686 sock->read_task,
687 &destroy_continuation, sock);
688 return;
689 }
690 if (NULL != (notify = sock->nth.notify_ready))
691 {
692 sock->nth.notify_ready = NULL;
693 notify (sock->nth.notify_ready_cls, 0, NULL);
694 if (sock->nth.timeout_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
695 {
696 GNUNET_SCHEDULER_cancel (sock->sched, sock->nth.timeout_task);
697 sock->nth.timeout_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
698 }
699 }
700 if (sock->sock != -1)
701 {
702#if DEBUG_NETWORK
703 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Closing socket.\n");
704#endif
705 GNUNET_break (0 == CLOSE (sock->sock));
706 }
707 GNUNET_free_non_null (sock->addr);
708 if (sock->ai != NULL)
709 freeaddrinfo (sock->ai);
710 GNUNET_free (sock);
711}
712
713
714/**
715 * Close the socket and free associated resources. Pending
716 * transmissions are simply dropped. A pending receive call will be
717 * called with an error code of "EPIPE".
718 *
719 * @param sock socket to destroy
720 */
721void
722GNUNET_NETWORK_socket_destroy (struct GNUNET_NETWORK_SocketHandle *sock)
723{
724#if DEBUG_NETWORK
725 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
726 "Network asked to destroy socket %p\n", sock);
727#endif
728 if (sock->write_buffer_off == 0)
729 sock->ai_pos = NULL; /* if we're still trying to connect and have
730 no message pending, stop trying! */
731 GNUNET_assert (sock->sched != NULL);
732 GNUNET_SCHEDULER_add_after (sock->sched,
733 GNUNET_YES,
734 GNUNET_SCHEDULER_PRIORITY_KEEP,
735 sock->connect_task,
736 &destroy_continuation, sock);
737}
738
739/**
740 * Tell the receiver callback that a timeout was reached.
741 */
742static void
743signal_timeout (struct GNUNET_NETWORK_SocketHandle *sh)
744{
745 GNUNET_NETWORK_Receiver receiver;
746
747#if DEBUG_NETWORK
748 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
749 "Network signals timeout to receiver!\n");
750#endif
751 GNUNET_assert (NULL != (receiver = sh->receiver));
752 sh->receiver = NULL;
753 receiver (sh->receiver_cls, NULL, 0, NULL, 0, 0);
754}
755
756
757/**
758 * Tell the receiver callback that we had an IO error.
759 */
760static void
761signal_error (struct GNUNET_NETWORK_SocketHandle *sh, int errcode)
762{
763 GNUNET_NETWORK_Receiver receiver;
764 GNUNET_assert (NULL != (receiver = sh->receiver));
765 sh->receiver = NULL;
766 receiver (sh->receiver_cls, NULL, 0, sh->addr, sh->addrlen, errcode);
767}
768
769
770/**
771 * This function is called once we either timeout
772 * or have data ready to read.
773 */
774static void
775receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
776{
777 struct GNUNET_NETWORK_SocketHandle *sh = cls;
778 struct GNUNET_TIME_Absolute now;
779 char buffer[sh->max];
780 ssize_t ret;
781 GNUNET_NETWORK_Receiver receiver;
782
783 sh->read_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
784 now = GNUNET_TIME_absolute_get ();
785 if ((now.value > sh->receive_timeout.value) ||
786 (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) ||
787 (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)))
788 {
789#if DEBUG_NETWORK
790 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
791 "Receive encounters error: timeout...\n");
792#endif
793 signal_timeout (sh);
794 return;
795 }
796 if (sh->sock == -1)
797 {
798 /* connect failed for good */
799#if DEBUG_NETWORK
800 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
801 "Receive encounters error, socket closed...\n");
802#endif
803 signal_error (sh, ECONNREFUSED);
804 return;
805 }
806 GNUNET_assert (FD_ISSET (sh->sock, tc->read_ready));
807RETRY:
808 ret = RECV (sh->sock, buffer, sh->max, MSG_DONTWAIT);
809 if (ret == -1)
810 {
811 if (errno == EINTR)
812 goto RETRY;
813#if DEBUG_NETWORK
814 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
815 "Error receiving: %s\n", STRERROR (errno));
816#endif
817 signal_error (sh, errno);
818 return;
819 }
820#if DEBUG_NETWORK
821 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
822 "Receive got %d bytes from OS!\n", ret);
823#endif
824 GNUNET_assert (NULL != (receiver = sh->receiver));
825 sh->receiver = NULL;
826 receiver (sh->receiver_cls, buffer, ret, sh->addr, sh->addrlen, 0);
827}
828
829
830/**
831 * This function is called after establishing a connection either has
832 * succeeded or timed out. Note that it is possible that the attempt
833 * timed out and that we're immediately retrying. If we are retrying,
834 * we need to wait again (or timeout); if we succeeded, we need to
835 * wait for data (or timeout).
836 */
837static void
838receive_again (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
839{
840 struct GNUNET_NETWORK_SocketHandle *sh = cls;
841 struct GNUNET_TIME_Absolute now;
842
843 sh->read_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
844 if ((sh->sock == -1) &&
845 (sh->connect_task == GNUNET_SCHEDULER_NO_PREREQUISITE_TASK))
846 {
847 /* not connected and no longer trying */
848#if DEBUG_NETWORK
849 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
850 "Receive encounters error, socket closed...\n");
851#endif
852 signal_error (sh, ECONNREFUSED);
853 return;
854 }
855 now = GNUNET_TIME_absolute_get ();
856 if ((now.value > sh->receive_timeout.value) ||
857 (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)))
858 {
859#if DEBUG_NETWORK
860 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
861 "Receive encounters error: timeout...\n");
862#endif
863 signal_timeout (sh);
864 return;
865 }
866 if (sh->connect_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
867 {
868 /* connect was retried */
869#if DEBUG_NETWORK
870 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
871 "Receive still waits on connect...\n");
872#endif
873 sh->read_task = GNUNET_SCHEDULER_add_after (tc->sched,
874 GNUNET_YES,
875 GNUNET_SCHEDULER_PRIORITY_KEEP,
876 sh->connect_task,
877 &receive_again, sh);
878 }
879 else
880 {
881 /* connect succeeded, wait for data! */
882#if DEBUG_NETWORK
883 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
884 "Receive now waits for socket...\n");
885#endif
886 sh->read_task = GNUNET_SCHEDULER_add_read (tc->sched,
887 GNUNET_YES,
888 GNUNET_SCHEDULER_PRIORITY_KEEP,
889 sh->connect_task,
890 GNUNET_TIME_absolute_get_remaining
891 (sh->receive_timeout),
892 sh->sock, &receive_ready,
893 sh);
894 }
895}
896
897
898/**
899 * Receive data from the given socket. Note that this function will
900 * call "receiver" asynchronously using the scheduler. It will
901 * "immediately" return. Note that there MUST only be one active
902 * receive call per socket at any given point in time (so do not
903 * call receive again until the receiver callback has been invoked).
904 *
905 * @param sched scheduler to use
906 * @param sock socket handle
907 * @param max maximum number of bytes to read
908 * @param timeout maximum amount of time to wait (use -1 for "forever")
909 * @param receiver function to call with received data
910 * @param receiver_cls closure for receiver
911 * @return scheduler task ID used for receiving, GNUNET_SCHEDULER_NO_PREREQUISITE_TASK on error
912 */
913GNUNET_SCHEDULER_TaskIdentifier
914GNUNET_NETWORK_receive (struct GNUNET_NETWORK_SocketHandle *sock,
915 size_t max,
916 struct GNUNET_TIME_Relative timeout,
917 GNUNET_NETWORK_Receiver receiver, void *receiver_cls)
918{
919 struct GNUNET_SCHEDULER_TaskContext tc;
920#if DEBUG_NETWORK
921 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
922 "Network asked to receive from socket...\n");
923#endif
924 GNUNET_assert ((sock->read_task == GNUNET_SCHEDULER_NO_PREREQUISITE_TASK) &&
925 (sock->receiver == NULL));
926 sock->receiver = receiver;
927 sock->receiver_cls = receiver_cls;
928 sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout);
929 sock->max = max;
930 memset (&tc, 0, sizeof (tc));
931 tc.sched = sock->sched;
932 tc.reason = GNUNET_SCHEDULER_REASON_PREREQ_DONE;
933 receive_again (sock, &tc);
934 return sock->read_task;
935}
936
937
938/**
939 * Cancel receive job on the given socket. Note that the
940 * receiver callback must not have been called yet in order
941 * for the cancellation to be valid.
942 *
943 * @param sock socket handle
944 * @param task task identifier returned from the receive call
945 * @return closure of the original receiver callback
946 */
947void *
948GNUNET_NETWORK_receive_cancel (struct GNUNET_NETWORK_SocketHandle *sock,
949 GNUNET_SCHEDULER_TaskIdentifier task)
950{
951 GNUNET_assert (sock->read_task == task);
952 GNUNET_assert (sock == GNUNET_SCHEDULER_cancel (sock->sched, task));
953 sock->read_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
954 sock->receiver = NULL;
955 return sock->receiver_cls;
956}
957
958
959/**
960 * Try to call the transmit notify method (check if we do
961 * have enough space available first)!
962 *
963 * @param sock socket for which we should do this processing
964 * @return GNUNET_YES if we were able to call notify
965 */
966static int
967process_notify (struct GNUNET_NETWORK_SocketHandle *sock)
968{
969 size_t used;
970 size_t avail;
971 size_t size;
972 GNUNET_NETWORK_TransmitReadyNotify notify;
973
974 GNUNET_assert (sock->write_task == GNUNET_SCHEDULER_NO_PREREQUISITE_TASK);
975 if (NULL == (notify = sock->nth.notify_ready))
976 return GNUNET_NO;
977 used = sock->write_buffer_off - sock->write_buffer_pos;
978 avail = sock->write_buffer_size - used;
979 size = sock->nth.notify_size;
980 if (sock->nth.notify_size > avail)
981 return GNUNET_NO;
982 sock->nth.notify_ready = NULL;
983 if (sock->nth.timeout_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
984 {
985 GNUNET_SCHEDULER_cancel (sock->sched, sock->nth.timeout_task);
986 sock->nth.timeout_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
987 }
988 if (sock->write_buffer_size - sock->write_buffer_off < size)
989 {
990 /* need to compact */
991 memmove (sock->write_buffer,
992 &sock->write_buffer[sock->write_buffer_pos], used);
993 sock->write_buffer_off -= sock->write_buffer_pos;
994 sock->write_buffer_pos = 0;
995 }
996 GNUNET_assert (sock->write_buffer_size - sock->write_buffer_off >= size);
997 size = notify (sock->nth.notify_ready_cls,
998 sock->write_buffer_size - sock->write_buffer_off,
999 &sock->write_buffer[sock->write_buffer_off]);
1000 sock->write_buffer_off += size;
1001 return GNUNET_YES;
1002}
1003
1004
1005/**
1006 * Task invoked by the scheduler when a call to transmit
1007 * is timing out (we never got enough buffer space to call
1008 * the callback function before the specified timeout
1009 * expired).
1010 *
1011 * This task notifies the client about the timeout.
1012 */
1013static void
1014transmit_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1015{
1016 struct GNUNET_NETWORK_SocketHandle *sock = cls;
1017 GNUNET_NETWORK_TransmitReadyNotify notify;
1018
1019#if DEBUG_NETWORK
1020 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmit fails, time out reached.\n");
1021#endif
1022 notify = sock->nth.notify_ready;
1023 sock->nth.notify_ready = NULL;
1024 notify (sock->nth.notify_ready_cls, 0, NULL);
1025}
1026
1027
1028static void
1029transmit_error (struct GNUNET_NETWORK_SocketHandle *sock)
1030{
1031 if (sock->nth.notify_ready == NULL)
1032 return; /* nobody to tell about it */
1033 if (sock->nth.timeout_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
1034 {
1035 GNUNET_SCHEDULER_cancel (sock->sched, sock->nth.timeout_task);
1036 sock->nth.timeout_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1037 }
1038 transmit_timeout (sock, NULL);
1039}
1040
1041
1042/**
1043 * See if we are now connected. If not, wait longer for
1044 * connect to succeed. If connected, we should be able
1045 * to write now as well, unless we timed out.
1046 */
1047static void
1048transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1049{
1050 struct GNUNET_NETWORK_SocketHandle *sock = cls;
1051 ssize_t ret;
1052 size_t have;
1053
1054#if DEBUG_NETWORK
1055 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1056 "Transmit ready called --- will try to send\n");
1057#endif
1058 GNUNET_assert (sock->write_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK);
1059 sock->write_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1060 if (sock->connect_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
1061 {
1062 /* still waiting for connect */
1063#if DEBUG_NETWORK
1064 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1065 "Transmission still waiting for connect...\n");
1066#endif
1067 GNUNET_assert (sock->write_task ==
1068 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK);
1069 sock->write_task =
1070 GNUNET_SCHEDULER_add_delayed (tc->sched, GNUNET_NO,
1071 GNUNET_SCHEDULER_PRIORITY_KEEP,
1072 sock->connect_task,
1073 GNUNET_TIME_UNIT_ZERO, &transmit_ready,
1074 sock);
1075 return;
1076 }
1077 if (sock->sock == -1)
1078 {
1079 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1080 _
1081 ("Did not transmit request, socket closed or connect failed.\n"));
1082 transmit_error (sock);
1083 return; /* connect failed for good, we're finished */
1084 }
1085 if ((tc->write_ready == NULL) || (!FD_ISSET (sock->sock, tc->write_ready)))
1086 {
1087#if DEBUG_NETWORK
1088 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1089 "Socket not yet ready for writing, will wait for that.\n");
1090#endif
1091 goto SCHEDULE_WRITE;
1092 }
1093 GNUNET_assert (sock->write_buffer_off >= sock->write_buffer_pos);
1094 process_notify (sock);
1095 have = sock->write_buffer_off - sock->write_buffer_pos;
1096 if (have == 0)
1097 {
1098#if DEBUG_NETWORK
1099 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No data ready for writing.\n");
1100#endif
1101 return;
1102 }
1103RETRY:
1104 ret = SEND (sock->sock,
1105 &sock->write_buffer[sock->write_buffer_pos],
1106 have, MSG_DONTWAIT | MSG_NOSIGNAL);
1107 if (ret == -1)
1108 {
1109 if (errno == EINTR)
1110 goto RETRY;
1111#if DEBUG_NETWORK
1112 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "send");
1113#endif
1114 SHUTDOWN (sock->sock, SHUT_RDWR);
1115 GNUNET_break (0 == CLOSE (sock->sock));
1116 sock->sock = -1;
1117 transmit_error (sock);
1118 return;
1119 }
1120#if DEBUG_NETWORK
1121 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitted %d bytes to OS\n", ret);
1122#endif
1123 sock->write_buffer_pos += ret;
1124 if (sock->write_buffer_pos == sock->write_buffer_off)
1125 {
1126 /* transmitted all pending data */
1127 sock->write_buffer_pos = 0;
1128 sock->write_buffer_off = 0;
1129#if DEBUG_NETWORK
1130 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1131 "Transmission buffer now empty.\n", ret);
1132#endif
1133 }
1134 if ((sock->write_buffer_off == 0) && (NULL == sock->nth.notify_ready))
1135 return; /* all data sent! */
1136 /* not done writing, schedule more */
1137#if DEBUG_NETWORK
1138 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1139 "More data ready for transmission, scheduling task again!\n");
1140#endif
1141SCHEDULE_WRITE:
1142 if (sock->write_task == GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
1143 sock->write_task =
1144 GNUNET_SCHEDULER_add_write (tc->sched,
1145 GNUNET_NO,
1146 GNUNET_SCHEDULER_PRIORITY_KEEP,
1147 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1148 GNUNET_TIME_UNIT_FOREVER_REL,
1149 sock->sock, &transmit_ready, sock);
1150}
1151
1152
1153/**
1154 * Ask the socket to call us once the specified number of bytes
1155 * are free in the transmission buffer. May call the notify
1156 * method immediately if enough space is available.
1157 *
1158 * @param sock socket
1159 * @param size number of bytes to send
1160 * @param timeout after how long should we give up (and call
1161 * notify with buf NULL and size 0)?
1162 * @param notify function to call
1163 * @param notify_cls closure for notify
1164 * @return non-NULL if the notify callback was queued,
1165 * NULL if we are already going to notify someone else (busy)
1166 */
1167struct GNUNET_NETWORK_TransmitHandle *
1168GNUNET_NETWORK_notify_transmit_ready (struct GNUNET_NETWORK_SocketHandle
1169 *sock, size_t size,
1170 struct GNUNET_TIME_Relative timeout,
1171 GNUNET_NETWORK_TransmitReadyNotify
1172 notify, void *notify_cls)
1173{
1174 if (sock->nth.notify_ready != NULL)
1175 return NULL;
1176 GNUNET_assert (notify != NULL);
1177 GNUNET_assert (sock->write_buffer_size >= size);
1178
1179 if ((sock->sock == -1) &&
1180 (sock->connect_task == GNUNET_SCHEDULER_NO_PREREQUISITE_TASK))
1181 {
1182#if DEBUG_NETWORK
1183 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1184 "Transmit fails, connection failed.\n");
1185#endif
1186 notify (notify_cls, 0, NULL);
1187 return &sock->nth;
1188 }
1189 GNUNET_assert (sock->write_buffer_off <= sock->write_buffer_size);
1190 GNUNET_assert (sock->write_buffer_pos <= sock->write_buffer_size);
1191 GNUNET_assert (sock->write_buffer_pos <= sock->write_buffer_off);
1192 sock->nth.notify_ready = notify;
1193 sock->nth.notify_ready_cls = notify_cls;
1194 sock->nth.sh = sock;
1195 sock->nth.notify_size = size;
1196 sock->nth.transmit_timeout = GNUNET_TIME_relative_to_absolute (timeout);
1197 sock->nth.timeout_task = GNUNET_SCHEDULER_add_delayed (sock->sched,
1198 GNUNET_NO,
1199 GNUNET_SCHEDULER_PRIORITY_KEEP,
1200 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1201 timeout,
1202 &transmit_timeout,
1203 sock);
1204#if DEBUG_NETWORK
1205 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1206 "Scheduling asynchronous transmission once connect is done...\n");
1207#endif
1208 if (sock->write_task == GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
1209 sock->write_task = GNUNET_SCHEDULER_add_delayed (sock->sched,
1210 GNUNET_NO,
1211 GNUNET_SCHEDULER_PRIORITY_KEEP,
1212 sock->connect_task,
1213 GNUNET_TIME_UNIT_ZERO,
1214 &transmit_ready, sock);
1215 return &sock->nth;
1216}
1217
1218
1219/**
1220 * Cancel the specified transmission-ready
1221 * notification.
1222 */
1223void
1224GNUNET_NETWORK_notify_transmit_ready_cancel (struct
1225 GNUNET_NETWORK_TransmitHandle *h)
1226{
1227 GNUNET_assert (h->notify_ready != NULL);
1228 GNUNET_SCHEDULER_cancel (h->sh->sched, h->timeout_task);
1229 h->timeout_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1230 h->notify_ready = NULL;
1231}
1232
1233
1234#if 0 /* keep Emacsens' auto-indent happy */
1235{
1236#endif
1237#ifdef __cplusplus
1238}
1239#endif
diff --git a/src/util/os_installation.c b/src/util/os_installation.c
new file mode 100644
index 000000000..201095544
--- /dev/null
+++ b/src/util/os_installation.c
@@ -0,0 +1,443 @@
1/*
2 This file is part of GNUnet.
3 (C) 2006 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 2, 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 src/util/os_installation.c
23 * @brief get paths used by the program
24 * @author Milan
25 */
26
27#ifdef __cplusplus
28extern "C"
29{
30#if 0 /* keep Emacsens' auto-indent happy */
31}
32#endif
33#endif
34
35#include <sys/stat.h>
36#include <stdlib.h>
37#include <string.h>
38#include <unistd.h>
39
40#include "platform.h"
41#include "gnunet_common.h"
42#include "gnunet_configuration_lib.h"
43#include "gnunet_disk_lib.h"
44#include "gnunet_os_lib.h"
45#if OSX
46#include <mach-o/ldsyms.h>
47#include <mach-o/dyld.h>
48#endif
49
50#if LINUX
51/**
52 * Try to determine path by reading /proc/PID/exe
53 */
54static char *
55get_path_from_proc_maps ()
56{
57 char fn[64];
58 char *line;
59 char *dir;
60 FILE *f;
61
62 GNUNET_snprintf (fn, 64, "/proc/%u/maps", getpid ());
63 line = GNUNET_malloc (1024);
64 dir = GNUNET_malloc (1024);
65 f = fopen (fn, "r");
66 if (f != NULL)
67 {
68 while (NULL != fgets (line, 1024, f))
69 {
70 if ((1 == sscanf (line,
71 "%*x-%*x %*c%*c%*c%*c %*x %*2u:%*2u %*u%*[ ]%s",
72 dir)) && (NULL != strstr (dir, "libgnunetutil")))
73 {
74 strstr (dir, "libgnunetutil")[0] = '\0';
75 fclose (f);
76 GNUNET_free (line);
77 return dir;
78 }
79 }
80 fclose (f);
81 }
82 GNUNET_free (dir);
83 GNUNET_free (line);
84 return NULL;
85}
86
87/**
88 * Try to determine path by reading /proc/PID/exe
89 */
90static char *
91get_path_from_proc_exe ()
92{
93 char fn[64];
94 char *lnk;
95 size_t size;
96
97 GNUNET_snprintf (fn, 64, "/proc/%u/exe", getpid ());
98 lnk = GNUNET_malloc (1024);
99 size = readlink (fn, lnk, 1023);
100 if ((size == 0) || (size >= 1024))
101 {
102 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "readlink", fn);
103 GNUNET_free (lnk);
104 return NULL;
105 }
106 lnk[size] = '\0';
107 while ((lnk[size] != '/') && (size > 0))
108 size--;
109 if ((size < 4) || (lnk[size - 4] != '/'))
110 {
111 /* not installed in "/bin/" -- binary path probably useless */
112 GNUNET_free (lnk);
113 return NULL;
114 }
115 lnk[size] = '\0';
116 return lnk;
117}
118#endif
119
120#if WINDOWS
121/**
122 * Try to determine path with win32-specific function
123 */
124static char *
125get_path_from_module_filename ()
126{
127 char *path;
128 char *idx;
129
130 path = GNUNET_malloc (4097);
131 GetModuleFileName (NULL, path, 4096);
132 idx = path + strlen (path);
133 while ((idx > path) && (*idx != '\\') && (*idx != '/'))
134 idx--;
135 *idx = '\0';
136 return path;
137}
138#endif
139
140#if OSX
141typedef int (*MyNSGetExecutablePathProto) (char *buf, size_t * bufsize);
142
143static char *
144get_path_from_NSGetExecutablePath ()
145{
146 static char zero = '\0';
147 char *path;
148 size_t len;
149 MyNSGetExecutablePathProto func;
150 int ret;
151
152 path = NULL;
153 func =
154 (MyNSGetExecutablePathProto) dlsym (RTLD_DEFAULT, "_NSGetExecutablePath");
155 if (!func)
156 return NULL;
157 path = &zero;
158 len = 0;
159 /* get the path len, including the trailing \0 */
160 func (path, &len);
161 if (len == 0)
162 return NULL;
163 path = GNUNET_malloc (len);
164 ret = func (path, &len);
165 if (ret != 0)
166 {
167 GNUNET_free (path);
168 return NULL;
169 }
170 len = strlen (path);
171 while ((path[len] != '/') && (len > 0))
172 len--;
173 path[len] = '\0';
174 return path;
175}
176
177static char *
178get_path_from_dyld_image ()
179{
180 const char *path;
181 char *p, *s;
182 int i;
183 int c;
184
185 p = NULL;
186 c = _dyld_image_count ();
187 for (i = 0; i < c; i++)
188 {
189 if (_dyld_get_image_header (i) == &_mh_dylib_header)
190 {
191 path = _dyld_get_image_name (i);
192 if (path != NULL && strlen (path) > 0)
193 {
194 p = strdup (path);
195 s = p + strlen (p);
196 while ((s > p) && (*s != '/'))
197 s--;
198 s++;
199 *s = '\0';
200 }
201 break;
202 }
203 }
204 return p;
205}
206#endif
207
208static char *
209get_path_from_PATH ()
210{
211 char *path;
212 char *pos;
213 char *end;
214 char *buf;
215 const char *p;
216 size_t size;
217
218 p = getenv ("PATH");
219 if (p == NULL)
220 return NULL;
221 path = GNUNET_strdup (p); /* because we write on it */
222 buf = GNUNET_malloc (strlen (path) + 20);
223 size = strlen (path);
224 pos = path;
225
226 while (NULL != (end = strchr (pos, ':')))
227 {
228 *end = '\0';
229 sprintf (buf, "%s/%s", pos, "gnunetd");
230 if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
231 {
232 pos = GNUNET_strdup (pos);
233 GNUNET_free (buf);
234 GNUNET_free (path);
235 return pos;
236 }
237 pos = end + 1;
238 }
239 sprintf (buf, "%s/%s", pos, "gnunetd");
240 if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
241 {
242 pos = GNUNET_strdup (pos);
243 GNUNET_free (buf);
244 GNUNET_free (path);
245 return pos;
246 }
247 GNUNET_free (buf);
248 GNUNET_free (path);
249 return NULL;
250}
251
252static char *
253get_path_from_GNUNET_PREFIX ()
254{
255 const char *p;
256
257 p = getenv ("GNUNET_PREFIX");
258 if (p != NULL)
259 return GNUNET_strdup (p);
260 return NULL;
261}
262
263/*
264 * @brief get the path to GNUnet bin/ or lib/, prefering the lib/ path
265 * @author Milan
266 *
267 * @return a pointer to the executable path, or NULL on error
268 */
269static char *
270os_get_gnunet_path ()
271{
272 char *ret;
273
274 ret = get_path_from_GNUNET_PREFIX ();
275 if (ret != NULL)
276 return ret;
277#if LINUX
278 ret = get_path_from_proc_maps ();
279 if (ret != NULL)
280 return ret;
281 ret = get_path_from_proc_exe ();
282 if (ret != NULL)
283 return ret;
284#endif
285#if WINDOWS
286 ret = get_path_from_module_filename ();
287 if (ret != NULL)
288 return ret;
289#endif
290#if OSX
291 ret = get_path_from_dyld_image ();
292 if (ret != NULL)
293 return ret;
294 ret = get_path_from_NSGetExecutablePath ();
295 if (ret != NULL)
296 return ret;
297#endif
298 ret = get_path_from_PATH ();
299 if (ret != NULL)
300 return ret;
301 /* other attempts here */
302 return NULL;
303}
304
305/*
306 * @brief get the path to current app's bin/
307 * @author Milan
308 *
309 * @return a pointer to the executable path, or NULL on error
310 */
311static char *
312os_get_exec_path ()
313{
314 char *ret;
315
316#if LINUX
317 ret = get_path_from_proc_exe ();
318 if (ret != NULL)
319 return ret;
320#endif
321#if WINDOWS
322 ret = get_path_from_module_filename ();
323 if (ret != NULL)
324 return ret;
325#endif
326#if OSX
327 ret = get_path_from_NSGetExecutablePath ();
328 if (ret != NULL)
329 return ret;
330#endif
331 /* other attempts here */
332 return NULL;
333}
334
335
336
337/**
338 * @brief get the path to a specific GNUnet installation directory or,
339 * with GNUNET_IPK_SELF_PREFIX, the current running apps installation directory
340 * @author Milan
341 * @return a pointer to the dir path (to be freed by the caller)
342 */
343char *
344GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind)
345{
346 size_t n;
347 const char *dirname;
348 char *execpath = NULL;
349 char *tmp;
350 int isbasedir;
351
352 /* if wanted, try to get the current app's bin/ */
353 if (dirkind == GNUNET_OS_IPK_SELF_PREFIX)
354 execpath = os_get_exec_path ();
355
356 /* try to get GNUnet's bin/ or lib/, or if previous was unsuccessful some
357 * guess for the current app */
358 if (execpath == NULL)
359 execpath = os_get_gnunet_path ();
360
361 if (execpath == NULL)
362 return NULL;
363
364 n = strlen (execpath);
365 if (n == 0)
366 {
367 /* should never happen, but better safe than sorry */
368 GNUNET_free (execpath);
369 return NULL;
370 }
371 /* remove filename itself */
372 while ((n > 1) && (execpath[n - 1] == DIR_SEPARATOR))
373 execpath[--n] = '\0';
374
375 isbasedir = 1;
376 if ((n > 5) &&
377 ((0 == strcasecmp (&execpath[n - 5], "lib32")) ||
378 (0 == strcasecmp (&execpath[n - 5], "lib64"))))
379 {
380 if (dirkind != GNUNET_OS_IPK_LIBDIR)
381 {
382 /* strip '/lib32' or '/lib64' */
383 execpath[n - 5] = '\0';
384 n -= 5;
385 }
386 else
387 isbasedir = 0;
388 }
389 else if ((n > 3) &&
390 ((0 == strcasecmp (&execpath[n - 3], "bin")) ||
391 (0 == strcasecmp (&execpath[n - 3], "lib"))))
392 {
393 /* strip '/bin' or '/lib' */
394 execpath[n - 3] = '\0';
395 n -= 3;
396 }
397 /* in case this was a directory named foo-bin, remove "foo-" */
398 while ((n > 1) && (execpath[n - 1] == DIR_SEPARATOR))
399 execpath[--n] = '\0';
400 switch (dirkind)
401 {
402 case GNUNET_OS_IPK_PREFIX:
403 case GNUNET_OS_IPK_SELF_PREFIX:
404 dirname = DIR_SEPARATOR_STR;
405 break;
406 case GNUNET_OS_IPK_BINDIR:
407 dirname = DIR_SEPARATOR_STR "bin" DIR_SEPARATOR_STR;
408 break;
409 case GNUNET_OS_IPK_LIBDIR:
410 if (isbasedir)
411 dirname =
412 DIR_SEPARATOR_STR "lib" DIR_SEPARATOR_STR "gnunet"
413 DIR_SEPARATOR_STR;
414 else
415 dirname = DIR_SEPARATOR_STR "gnunet" DIR_SEPARATOR_STR;
416 break;
417 case GNUNET_OS_IPK_DATADIR:
418 dirname =
419 DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR "gnunet"
420 DIR_SEPARATOR_STR;
421 break;
422 case GNUNET_OS_IPK_LOCALEDIR:
423 dirname =
424 DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR "locale"
425 DIR_SEPARATOR_STR;
426 break;
427 default:
428 GNUNET_free (execpath);
429 return NULL;
430 }
431 tmp = GNUNET_malloc (strlen (execpath) + strlen (dirname) + 1);
432 sprintf (tmp, "%s%s", execpath, dirname);
433 GNUNET_free (execpath);
434 return tmp;
435}
436
437#if 0 /* keep Emacsens' auto-indent happy */
438{
439#endif
440#ifdef __cplusplus
441}
442#endif
443/* end of installpath.c */
diff --git a/src/util/os_load.c b/src/util/os_load.c
new file mode 100644
index 000000000..d1115e33f
--- /dev/null
+++ b/src/util/os_load.c
@@ -0,0 +1,653 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2005, 2006 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 2, 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 util/os_load_cpu.c
23 * @brief calls to determine current CPU load
24 * @author Tzvetan Horozov
25 * @author Christian Grothoff
26 * @author Igor Wronsky
27 * @author Alex Harper (OS X portion)
28 */
29
30#include "platform.h"
31#include "gnunet_common.h"
32#include "gnunet_os_lib.h"
33#include "gnunet_strings_lib.h"
34
35#if SOLARIS
36#if HAVE_KSTAT_H
37#include <kstat.h>
38#endif
39#if HAVE_SYS_SYSINFO_H
40#include <sys/sysinfo.h>
41#endif
42#if HAVE_KVM_H
43#include <kvm.h>
44#endif
45#endif
46#if SOMEBSD
47#if HAVE_KVM_H
48#include <kvm.h>
49#endif
50#endif
51
52#ifdef OSX
53#include <mach/mach.h>
54
55static processor_cpu_load_info_t prev_cpu_load;
56#endif
57
58#define DEBUG_STATUSCALLS GNUNET_NO
59
60#ifdef LINUX
61static FILE *proc_stat;
62#endif
63
64/**
65 * Current CPU load, as percentage of CPU cycles not idle or
66 * blocked on IO.
67 */
68static int currentCPULoad;
69
70static double agedCPULoad = -1;
71
72/**
73 * Current IO load, as percentage of CPU cycles blocked on IO.
74 */
75static int currentIOLoad;
76
77static double agedIOLoad = -1;
78
79#ifdef OSX
80static int
81initMachCpuStats ()
82{
83 unsigned int cpu_count;
84 processor_cpu_load_info_t cpu_load;
85 mach_msg_type_number_t cpu_msg_count;
86 kern_return_t kret;
87 int i, j;
88
89 kret = host_processor_info (mach_host_self (),
90 PROCESSOR_CPU_LOAD_INFO,
91 &cpu_count,
92 (processor_info_array_t *) & cpu_load,
93 &cpu_msg_count);
94 if (kret != KERN_SUCCESS)
95 {
96 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
97 "host_processor_info failed.");
98 return GNUNET_SYSERR;
99 }
100 prev_cpu_load = GNUNET_malloc (cpu_count * sizeof (*prev_cpu_load));
101 for (i = 0; i < cpu_count; i++)
102 {
103 for (j = 0; j < CPU_STATE_MAX; j++)
104 {
105 prev_cpu_load[i].cpu_ticks[j] = cpu_load[i].cpu_ticks[j];
106 }
107 }
108 vm_deallocate (mach_task_self (),
109 (vm_address_t) cpu_load,
110 (vm_size_t) (cpu_msg_count * sizeof (*cpu_load)));
111 return GNUNET_OK;
112}
113#endif
114
115/**
116 * Update the currentCPU and currentIO load values.
117 *
118 * Before its first invocation the method initStatusCalls() must be called.
119 * If there is an error the method returns -1.
120 */
121static int
122updateUsage ()
123{
124 currentIOLoad = -1;
125 currentCPULoad = -1;
126#ifdef LINUX
127 /* under linux, first try %idle/usage using /proc/stat;
128 if that does not work, disable /proc/stat for the future
129 by closing the file and use the next-best method. */
130 if (proc_stat != NULL)
131 {
132 static unsigned long long last_cpu_results[5] = { 0, 0, 0, 0, 0 };
133 static int have_last_cpu = GNUNET_NO;
134 int ret;
135 char line[256];
136 unsigned long long user_read, system_read, nice_read, idle_read,
137 iowait_read;
138 unsigned long long user, system, nice, idle, iowait;
139 unsigned long long usage_time = 0, total_time = 1;
140
141 /* Get the first line with the data */
142 rewind (proc_stat);
143 fflush (proc_stat);
144 if (NULL == fgets (line, 256, proc_stat))
145 {
146 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR |
147 GNUNET_ERROR_TYPE_BULK,
148 "fgets", "/proc/stat");
149 fclose (proc_stat);
150 proc_stat = NULL; /* don't try again */
151 }
152 else
153 {
154 iowait_read = 0;
155 ret = sscanf (line, "%*s %llu %llu %llu %llu %llu",
156 &user_read,
157 &system_read, &nice_read, &idle_read, &iowait_read);
158 if (ret < 4)
159 {
160 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR |
161 GNUNET_ERROR_TYPE_BULK,
162 "fgets-sscanf", "/proc/stat");
163 fclose (proc_stat);
164 proc_stat = NULL; /* don't try again */
165 have_last_cpu = GNUNET_NO;
166 }
167 else
168 {
169 /* Store the current usage */
170 user = user_read - last_cpu_results[0];
171 system = system_read - last_cpu_results[1];
172 nice = nice_read - last_cpu_results[2];
173 idle = idle_read - last_cpu_results[3];
174 iowait = iowait_read - last_cpu_results[4];
175 /* Calculate the % usage */
176 usage_time = user + system + nice;
177 total_time = usage_time + idle + iowait;
178 if ((total_time > 0) && (have_last_cpu == GNUNET_YES))
179 {
180 currentCPULoad = (int) (100L * usage_time / total_time);
181 if (ret > 4)
182 currentIOLoad = (int) (100L * iowait / total_time);
183 else
184 currentIOLoad = -1; /* 2.4 kernel */
185 }
186 /* Store the values for the next calculation */
187 last_cpu_results[0] = user_read;
188 last_cpu_results[1] = system_read;
189 last_cpu_results[2] = nice_read;
190 last_cpu_results[3] = idle_read;
191 last_cpu_results[4] = iowait_read;
192 have_last_cpu = GNUNET_YES;
193 return GNUNET_OK;
194 }
195 }
196 }
197#endif
198
199#ifdef OSX
200 {
201 unsigned int cpu_count;
202 processor_cpu_load_info_t cpu_load;
203 mach_msg_type_number_t cpu_msg_count;
204 unsigned long long t_sys, t_user, t_nice, t_idle, t_total;
205 unsigned long long t_idle_all, t_total_all;
206 kern_return_t kret;
207 int i, j;
208
209 t_idle_all = t_total_all = 0;
210 kret = host_processor_info (mach_host_self (), PROCESSOR_CPU_LOAD_INFO,
211 &cpu_count,
212 (processor_info_array_t *) & cpu_load,
213 &cpu_msg_count);
214 if (kret == KERN_SUCCESS)
215 {
216 for (i = 0; i < cpu_count; i++)
217 {
218 if (cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM] >=
219 prev_cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM])
220 {
221 t_sys = cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM] -
222 prev_cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM];
223 }
224 else
225 {
226 t_sys = cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM] +
227 (ULONG_MAX - prev_cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM] +
228 1);
229 }
230
231 if (cpu_load[i].cpu_ticks[CPU_STATE_USER] >=
232 prev_cpu_load[i].cpu_ticks[CPU_STATE_USER])
233 {
234 t_user = cpu_load[i].cpu_ticks[CPU_STATE_USER] -
235 prev_cpu_load[i].cpu_ticks[CPU_STATE_USER];
236 }
237 else
238 {
239 t_user = cpu_load[i].cpu_ticks[CPU_STATE_USER] +
240 (ULONG_MAX - prev_cpu_load[i].cpu_ticks[CPU_STATE_USER] +
241 1);
242 }
243
244 if (cpu_load[i].cpu_ticks[CPU_STATE_NICE] >=
245 prev_cpu_load[i].cpu_ticks[CPU_STATE_NICE])
246 {
247 t_nice = cpu_load[i].cpu_ticks[CPU_STATE_NICE] -
248 prev_cpu_load[i].cpu_ticks[CPU_STATE_NICE];
249 }
250 else
251 {
252 t_nice = cpu_load[i].cpu_ticks[CPU_STATE_NICE] +
253 (ULONG_MAX - prev_cpu_load[i].cpu_ticks[CPU_STATE_NICE] +
254 1);
255 }
256
257 if (cpu_load[i].cpu_ticks[CPU_STATE_IDLE] >=
258 prev_cpu_load[i].cpu_ticks[CPU_STATE_IDLE])
259 {
260 t_idle = cpu_load[i].cpu_ticks[CPU_STATE_IDLE] -
261 prev_cpu_load[i].cpu_ticks[CPU_STATE_IDLE];
262 }
263 else
264 {
265 t_idle = cpu_load[i].cpu_ticks[CPU_STATE_IDLE] +
266 (ULONG_MAX - prev_cpu_load[i].cpu_ticks[CPU_STATE_IDLE] +
267 1);
268 }
269 t_total = t_sys + t_user + t_nice + t_idle;
270 t_idle_all += t_idle;
271 t_total_all += t_total;
272 }
273 for (i = 0; i < cpu_count; i++)
274 {
275 for (j = 0; j < CPU_STATE_MAX; j++)
276 {
277 prev_cpu_load[i].cpu_ticks[j] = cpu_load[i].cpu_ticks[j];
278 }
279 }
280 if (t_total_all > 0)
281 currentCPULoad = 100 - (100 * t_idle_all) / t_total_all;
282 else
283 currentCPULoad = -1;
284 vm_deallocate (mach_task_self (),
285 (vm_address_t) cpu_load,
286 (vm_size_t) (cpu_msg_count * sizeof (*cpu_load)));
287 currentIOLoad = -1; /* FIXME-OSX! */
288 return GNUNET_OK;
289 }
290 else
291 {
292 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
293 "host_processor_info failed.");
294 return GNUNET_SYSERR;
295 }
296 }
297#endif
298 /* try kstat (Solaris only) */
299#if SOLARIS && HAVE_KSTAT_H && HAVE_SYS_SYSINFO_H
300 {
301 static long long last_idlecount;
302 static long long last_totalcount;
303 static int kstat_once; /* if open fails, don't keep
304 trying */
305 kstat_ctl_t *kc;
306 kstat_t *khelper;
307 long long idlecount;
308 long long totalcount;
309 long long deltaidle;
310 long long deltatotal;
311
312 if (kstat_once == 1)
313 goto ABORT_KSTAT;
314 kc = kstat_open ();
315 if (kc == NULL)
316 {
317 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
318 "kstat_open");
319 goto ABORT_KSTAT;
320 }
321
322 idlecount = 0;
323 totalcount = 0;
324 for (khelper = kc->kc_chain; khelper != NULL; khelper = khelper->ks_next)
325 {
326 cpu_stat_t stats;
327
328 if (0 != strncmp (khelper->ks_name, "cpu_stat", strlen ("cpu_stat")))
329 continue;
330 if (khelper->ks_data_size > sizeof (cpu_stat_t))
331 continue; /* better save then sorry! */
332 if (-1 != kstat_read (kc, khelper, &stats))
333 {
334 idlecount += stats.cpu_sysinfo.cpu[CPU_IDLE];
335 totalcount
336 += stats.cpu_sysinfo.cpu[CPU_IDLE] +
337 stats.cpu_sysinfo.cpu[CPU_USER] +
338 stats.cpu_sysinfo.cpu[CPU_KERNEL] +
339 stats.cpu_sysinfo.cpu[CPU_WAIT];
340 }
341 }
342 if (0 != kstat_close (kc))
343 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
344 "kstat_close");
345 if ((idlecount == 0) && (totalcount == 0))
346 goto ABORT_KSTAT; /* no stats found => abort */
347 deltaidle = idlecount - last_idlecount;
348 deltatotal = totalcount - last_totalcount;
349 if ((deltatotal > 0) && (last_totalcount > 0))
350 {
351 currentCPULoad = (unsigned int) (100.0 * deltaidle / deltatotal);
352 if (currentCPULoad > 100)
353 currentCPULoad = 100; /* odd */
354 if (currentCPULoad < 0)
355 currentCPULoad = 0; /* odd */
356 currentCPULoad = 100 - currentCPULoad; /* computed idle-load before! */
357 }
358 else
359 currentCPULoad = -1;
360 currentIOLoad = -1; /* FIXME-SOLARIS! */
361 last_idlecount = idlecount;
362 last_totalcount = totalcount;
363 return GNUNET_OK;
364 ABORT_KSTAT:
365 kstat_once = 1; /* failed, don't try again */
366 return GNUNET_SYSERR;
367 }
368#endif
369
370 /* insert methods better than getloadavg for
371 other platforms HERE! */
372
373 /* ok, maybe we have getloadavg on this platform */
374#if HAVE_GETLOADAVG
375 {
376 static int warnOnce = 0;
377 double loadavg;
378 if (1 != getloadavg (&loadavg, 1))
379 {
380 /* only warn once, if there is a problem with
381 getloadavg, we're going to hit it frequently... */
382 if (warnOnce == 0)
383 {
384 warnOnce = 1;
385 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "getloadavg");
386 }
387 return GNUNET_SYSERR;
388 }
389 else
390 {
391 /* success with getloadavg */
392 currentCPULoad = (int) (100 * loadavg);
393 currentIOLoad = -1; /* FIXME */
394 return GNUNET_OK;
395 }
396 }
397#endif
398
399#if MINGW
400 /* Win NT? */
401 if (GNNtQuerySystemInformation)
402 {
403 static double dLastKernel;
404 static double dLastIdle;
405 static double dLastUser;
406 double dKernel;
407 double dIdle;
408 double dUser;
409 double dDiffKernel;
410 double dDiffIdle;
411 double dDiffUser;
412 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION theInfo;
413
414 if (GNNtQuerySystemInformation (SystemProcessorPerformanceInformation,
415 &theInfo,
416 sizeof (theInfo), NULL) == NO_ERROR)
417 {
418 /* PORT-ME MINGW: Multi-processor? */
419 dKernel = Li2Double (theInfo.KernelTime);
420 dIdle = Li2Double (theInfo.IdleTime);
421 dUser = Li2Double (theInfo.UserTime);
422 dDiffKernel = dKernel - dLastKernel;
423 dDiffIdle = dIdle - dLastIdle;
424 dDiffUser = dUser - dLastUser;
425
426 if (((dDiffKernel + dDiffUser) > 0) &&
427 (dLastIdle + dLastKernel + dLastUser > 0))
428 currentCPULoad =
429 100.0 - (dDiffIdle / (dDiffKernel + dDiffUser)) * 100.0;
430 else
431 currentCPULoad = -1; /* don't know (yet) */
432
433 dLastKernel = dKernel;
434 dLastIdle = dIdle;
435 dLastUser = dUser;
436
437 currentIOLoad = -1; /* FIXME-MINGW */
438 return GNUNET_OK;
439 }
440 else
441 {
442 /* only warn once, if there is a problem with
443 NtQuery..., we're going to hit it frequently... */
444 static int once;
445 if (once == 0)
446 {
447 once = 1;
448 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
449 _("Cannot query the CPU usage (Windows NT).\n"));
450 }
451 return GNUNET_SYSERR;
452 }
453 }
454 else
455 { /* Win 9x */
456 HKEY hKey;
457 DWORD dwDataSize, dwType, dwDummy;
458
459 /* Start query */
460 if (RegOpenKeyEx (HKEY_DYN_DATA,
461 "PerfStats\\StartSrv",
462 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS)
463 {
464 /* only warn once */
465 static int once = 0;
466 if (once == 0)
467 {
468 once = 1;
469 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
470 _("Cannot query the CPU usage (Win 9x)\n"));
471 }
472 }
473
474 RegOpenKeyEx (HKEY_DYN_DATA,
475 "PerfStats\\StartStat", 0, KEY_ALL_ACCESS, &hKey);
476 dwDataSize = sizeof (dwDummy);
477 RegQueryValueEx (hKey,
478 "KERNEL\\CPUUsage",
479 NULL, &dwType, (LPBYTE) & dwDummy, &dwDataSize);
480 RegCloseKey (hKey);
481
482 /* Get CPU usage */
483 RegOpenKeyEx (HKEY_DYN_DATA,
484 "PerfStats\\StatData", 0, KEY_ALL_ACCESS, &hKey);
485 dwDataSize = sizeof (currentCPULoad);
486 RegQueryValueEx (hKey,
487 "KERNEL\\CPUUsage",
488 NULL, &dwType, (LPBYTE) & currentCPULoad, &dwDataSize);
489 RegCloseKey (hKey);
490 currentIOLoad = -1; /* FIXME-MINGW! */
491
492 /* Stop query */
493 RegOpenKeyEx (HKEY_DYN_DATA,
494 "PerfStats\\StopStat", 0, KEY_ALL_ACCESS, &hKey);
495 RegOpenKeyEx (HKEY_DYN_DATA,
496 "PerfStats\\StopSrv", 0, KEY_ALL_ACCESS, &hKey);
497 dwDataSize = sizeof (dwDummy);
498 RegQueryValueEx (hKey,
499 "KERNEL\\CPUUsage",
500 NULL, &dwType, (LPBYTE) & dwDummy, &dwDataSize);
501 RegCloseKey (hKey);
502
503 return GNUNET_OK;
504 }
505#endif
506
507 /* loadaverage not defined and no platform
508 specific alternative defined
509 => default: error
510 */
511 return GNUNET_SYSERR;
512}
513
514/**
515 * Update load values (if enough time has expired),
516 * including computation of averages. Code assumes
517 * that lock has already been obtained.
518 */
519static void
520updateAgedLoad (struct GNUNET_CONFIGURATION_Handle *cfg)
521{
522 static struct GNUNET_TIME_Absolute lastCall;
523
524 if ((agedCPULoad == -1)
525 || (GNUNET_TIME_absolute_get_duration (lastCall).value > 500))
526 {
527 /* use smoothing, but do NOT update lastRet at frequencies higher
528 than 500ms; this makes the smoothing (mostly) independent from
529 the frequency at which getCPULoad is called (and we don't spend
530 more time measuring CPU than actually computing something). */
531 lastCall = GNUNET_TIME_absolute_get ();
532 updateUsage ();
533 if (currentCPULoad == -1)
534 {
535 agedCPULoad = -1;
536 }
537 else
538 {
539 if (agedCPULoad == -1)
540 {
541 agedCPULoad = currentCPULoad;
542 }
543 else
544 {
545 /* for CPU, we don't do the 'fast increase' since CPU is much
546 more jitterish to begin with */
547 agedCPULoad = (agedCPULoad * 31 + currentCPULoad) / 32;
548 }
549 }
550 if (currentIOLoad == -1)
551 {
552 agedIOLoad = -1;
553 }
554 else
555 {
556 if (agedIOLoad == -1)
557 {
558 agedIOLoad = currentIOLoad;
559 }
560 else
561 {
562 /* for IO, we don't do the 'fast increase' since IO is much
563 more jitterish to begin with */
564 agedIOLoad = (agedIOLoad * 31 + currentIOLoad) / 32;
565 }
566 }
567 }
568}
569
570/**
571 * Get the load of the CPU relative to what is allowed.
572 * @return the CPU load as a percentage of allowed
573 * (100 is equivalent to full load)
574 */
575int
576GNUNET_OS_load_cpu_get (struct GNUNET_CONFIGURATION_Handle *cfg)
577{
578 unsigned long long maxCPULoad;
579 int ret;
580
581 updateAgedLoad (cfg);
582 ret = agedCPULoad;
583 if (ret == -1)
584 return -1;
585 if (GNUNET_OK !=
586 GNUNET_CONFIGURATION_get_value_number (cfg, "LOAD", "MAXCPULOAD",
587 &maxCPULoad))
588 return GNUNET_SYSERR;
589 return (100 * ret) / maxCPULoad;
590}
591
592
593/**
594 * Get the load of the CPU relative to what is allowed.
595 * @return the CPU load as a percentage of allowed
596 * (100 is equivalent to full load)
597 */
598int
599GNUNET_OS_load_disk_get (struct GNUNET_CONFIGURATION_Handle *cfg)
600{
601 unsigned long long maxIOLoad;
602 int ret;
603
604 updateAgedLoad (cfg);
605 ret = agedIOLoad;
606 if (ret == -1)
607 return -1;
608 if (-1 ==
609 GNUNET_CONFIGURATION_get_value_number (cfg, "LOAD", "MAXIOLOAD",
610 &maxIOLoad))
611 return GNUNET_SYSERR;
612 return (100 * ret) / maxIOLoad;
613}
614
615/**
616 * The following method is called in order to initialize the status calls
617 * routines. After that it is safe to call each of the status calls separately
618 * @return GNUNET_OK on success and GNUNET_SYSERR on error (or calls errexit).
619 */
620void __attribute__ ((constructor)) GNUNET_cpustats_ltdl_init ()
621{
622#ifdef LINUX
623 proc_stat = fopen ("/proc/stat", "r");
624 if (NULL == proc_stat)
625 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", "/proc/stat");
626#elif OSX
627 initMachCpuStats ();
628#elif MINGW
629 InitWinEnv (NULL);
630#endif
631 updateUsage (); /* initialize */
632}
633
634/**
635 * Shutdown the status calls module.
636 */
637void __attribute__ ((destructor)) GNUNET_cpustats_ltdl_fini ()
638{
639#ifdef LINUX
640 if (proc_stat != NULL)
641 {
642 fclose (proc_stat);
643 proc_stat = NULL;
644 }
645#elif OSX
646 GNUNET_free_non_null (prev_cpu_load);
647#elif MINGW
648 ShutdownWinEnv ();
649#endif
650}
651
652
653/* end of os_load_cpu.c */
diff --git a/src/util/os_network.c b/src/util/os_network.c
new file mode 100644
index 000000000..cb5ccb12a
--- /dev/null
+++ b/src/util/os_network.c
@@ -0,0 +1,286 @@
1/*
2 This file is part of GNUnet.
3 (C) 2004, 2005, 2006 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 2, 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/**
23 * @file util/os_network.c
24 * @brief function to determine available network interfaces
25 * @author Nils Durner
26 * @author Heikki Lindholm
27 * @author Jake Dust
28 */
29
30#include "platform.h"
31#include "gnunet_common.h"
32#include "gnunet_os_lib.h"
33
34/**
35 * @brief Enumerate all network interfaces
36 * @param callback the callback function
37 */
38void
39GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc,
40 void *cls)
41{
42#ifdef MINGW
43 PMIB_IFTABLE pTable;
44 PMIB_IPADDRTABLE pAddrTable;
45 DWORD dwIfIdx, dwExternalNIC;
46 IPAddr theIP;
47
48 /* Determine our external NIC */
49 theIP = inet_addr ("192.0.34.166"); /* www.example.com */
50 if ((!GNGetBestInterface) ||
51 (GNGetBestInterface (theIP, &dwExternalNIC) != NO_ERROR))
52 {
53 dwExternalNIC = 0;
54 }
55
56 /* Enumerate NICs */
57 EnumNICs (&pTable, &pAddrTable);
58
59 if (pTable)
60 {
61 for (dwIfIdx = 0; dwIfIdx <= pTable->dwNumEntries; dwIfIdx++)
62 {
63 char szEntry[1001];
64 DWORD dwIP = 0;
65 int iItm;
66 PIP_ADAPTER_INFO pAdapterInfo;
67 PIP_ADAPTER_INFO pAdapter = NULL;
68 DWORD dwRetVal = 0;
69
70 /* Get IP-Address */
71 int i;
72 for (i = 0; i < pAddrTable->dwNumEntries; i++)
73 {
74 if (pAddrTable->table[i].dwIndex ==
75 pTable->table[dwIfIdx].dwIndex)
76 {
77 dwIP = pAddrTable->table[i].dwAddr;
78 break;
79 }
80 }
81
82 if (dwIP)
83 {
84 BYTE bPhysAddr[MAXLEN_PHYSADDR];
85 char *pszIfName = NULL;
86 char dst[INET_ADDRSTRLEN];
87
88 /* Get friendly interface name */
89 pAdapterInfo =
90 (IP_ADAPTER_INFO *) malloc (sizeof (IP_ADAPTER_INFO));
91 ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);
92
93 /* Make an initial call to GetAdaptersInfo to get
94 the necessary size into the ulOutBufLen variable */
95 if (GGetAdaptersInfo (pAdapterInfo, &ulOutBufLen) ==
96 ERROR_BUFFER_OVERFLOW)
97 {
98 free (pAdapterInfo);
99 pAdapterInfo = (IP_ADAPTER_INFO *) malloc (ulOutBufLen);
100 }
101
102 if ((dwRetVal =
103 GGetAdaptersInfo (pAdapterInfo, &ulOutBufLen)) == NO_ERROR)
104 {
105 pAdapter = pAdapterInfo;
106 while (pAdapter)
107 {
108 if (pTable->table[dwIfIdx].dwIndex == pAdapter->Index)
109 {
110 char szKey[251];
111 long lLen = 250;
112
113 sprintf (szKey,
114 "SYSTEM\\CurrentControlSet\\Control\\Network\\"
115 "{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection",
116 pAdapter->AdapterName);
117 pszIfName = (char *) malloc (251);
118 if (QueryRegistry
119 (HKEY_LOCAL_MACHINE, szKey, "Name", pszIfName,
120 &lLen) != ERROR_SUCCESS)
121 {
122 free (pszIfName);
123 pszIfName = NULL;
124 }
125 }
126 pAdapter = pAdapter->Next;
127 }
128 }
129 free (pAdapterInfo);
130
131 /* Set entry */
132 memset (bPhysAddr, 0, MAXLEN_PHYSADDR);
133 memcpy (bPhysAddr,
134 pTable->table[dwIfIdx].bPhysAddr,
135 pTable->table[dwIfIdx].dwPhysAddrLen);
136
137 snprintf (szEntry, 1000, "%s (%s - %I64u)",
138 pszIfName ? pszIfName : (char *) pTable->
139 table[dwIfIdx].bDescr, inet_ntop (AF_INET, &dwIP, dst,
140 INET_ADDRSTRLEN),
141 *((unsigned long long *) bPhysAddr));
142 szEntry[1000] = 0;
143
144 if (pszIfName)
145 free (pszIfName);
146
147 if (GNUNET_OK !=
148 proc (cls,
149 szEntry,
150 pAddrTable->table[dwIfIdx].dwIndex == dwExternalNIC,
151 NULL /* FIXME: pass actual IP address! */ ,
152 0))
153 break;
154 }
155 }
156 GlobalFree (pAddrTable);
157 GlobalFree (pTable);
158 }
159
160 return GNUNET_YES;
161
162#elif HAVE_GETIFADDRS && HAVE_FREEIFADDRS
163
164 struct ifaddrs *ifa_first;
165 socklen_t alen;
166
167 if (getifaddrs (&ifa_first) == 0)
168 {
169 struct ifaddrs *ifa_ptr;
170
171 ifa_ptr = ifa_first;
172 for (ifa_ptr = ifa_first; ifa_ptr != NULL; ifa_ptr = ifa_ptr->ifa_next)
173 {
174 if (ifa_ptr->ifa_name != NULL &&
175 ifa_ptr->ifa_addr != NULL && (ifa_ptr->ifa_flags & IFF_UP) != 0)
176 {
177 if ((ifa_ptr->ifa_addr->sa_family != AF_INET) &&
178 (ifa_ptr->ifa_addr->sa_family != AF_INET6))
179 continue;
180 if (ifa_ptr->ifa_addr->sa_family == AF_INET)
181 alen = sizeof (struct sockaddr_in);
182 else
183 alen = sizeof (struct sockaddr_in6);
184 if (GNUNET_OK != proc (cls,
185 ifa_ptr->ifa_name,
186 0 == strcmp (ifa_ptr->ifa_name,
187 GNUNET_DEFAULT_INTERFACE),
188 ifa_ptr->ifa_addr, alen))
189 break;
190 }
191 }
192 freeifaddrs (ifa_first);
193 }
194#else
195 char line[1024];
196 const char *start;
197 char ifc[12];
198 char addrstr[128];
199 FILE *f;
200 int have_ifc;
201 struct sockaddr_in a4;
202 struct sockaddr_in6 a6;
203 struct in_addr v4;
204 struct in6_addr v6;
205
206 if (system ("ifconfig -a > /dev/null 2> /dev/null"))
207 if (system ("/sbin/ifconfig -a > /dev/null 2> /dev/null") == 0)
208 f = popen ("/sbin/ifconfig -a 2> /dev/null", "r");
209 else
210 f = NULL;
211 else
212 f = popen ("ifconfig -a 2> /dev/null", "r");
213 if (!f)
214 {
215 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING |
216 GNUNET_ERROR_TYPE_BULK, "popen", "ifconfig");
217 return;
218 }
219
220 have_ifc = GNUNET_NO;
221 ifc[11] = '\0';
222 while (NULL != fgets (line, sizeof (line), f))
223 {
224 if (strlen (line) == 0)
225 {
226 have_ifc = GNUNET_NO;
227 continue;
228 }
229 if (!isspace (line[0]))
230 {
231 have_ifc =
232 (1 == SSCANF (line, "%11s", ifc)) ? GNUNET_YES : GNUNET_NO;
233 /* would end with ':' on OSX, fix it! */
234 if (ifc[strlen (ifc) - 1] == ':')
235 ifc[strlen (ifc) - 1] = '\0';
236 continue;
237 }
238 if (!have_ifc)
239 continue; /* strange input, hope for the best */
240 start = line;
241 while (('\0' != *start) && (isspace (*start)))
242 start++;
243 if ( /* Linux */
244 (1 == SSCANF (start, "inet addr:%127s", addrstr)) ||
245 (1 == SSCANF (start, "inet6 addr:%127s", addrstr)) ||
246 /* Solaris, OS X */
247 (1 == SSCANF (start, "inet %127s", addrstr)) ||
248 (1 == SSCANF (start, "inet6 %127s", addrstr)))
249 {
250 /* IPv4 */
251 if (1 == inet_pton (AF_INET, addrstr, &v4))
252 {
253 memset (&a4, 0, sizeof (a4));
254 a4.sin_family = AF_INET;
255 a4.sin_addr = v4;
256 if (GNUNET_OK !=
257 proc (cls,
258 ifc,
259 0 == strcmp (ifc, GNUNET_DEFAULT_INTERFACE),
260 (const struct sockaddr *) &a4, sizeof (a4)))
261 break;
262 continue;
263 }
264 /* IPv6 */
265 if (1 == inet_pton (AF_INET6, addrstr, &v6))
266 {
267 memset (&a6, 0, sizeof (a6));
268 a6.sin6_family = AF_INET6;
269 a6.sin6_addr = v6;
270 fprintf (stderr, "procing %s\n", addrstr);
271 if (GNUNET_OK !=
272 proc (cls,
273 ifc,
274 0 == strcmp (ifc, GNUNET_DEFAULT_INTERFACE),
275 (const struct sockaddr *) &a6, sizeof (a6)))
276 break;
277 continue;
278 }
279 }
280 }
281 pclose (f);
282#endif
283}
284
285
286/* end of os_network.c */
diff --git a/src/util/os_priority.c b/src/util/os_priority.c
new file mode 100644
index 000000000..7862d68e9
--- /dev/null
+++ b/src/util/os_priority.c
@@ -0,0 +1,186 @@
1/*
2 This file is part of GNUnet
3 (C) 2002, 2003, 2004, 2005, 2006 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 2, 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 util/os/priority.c
23 * @brief Methods to set process priority
24 * @author Nils Durner
25 */
26
27#include "platform.h"
28#include "gnunet_common.h"
29#include "gnunet_os_lib.h"
30
31/**
32 * Set our process priority
33 */
34int
35GNUNET_OS_set_process_priority (pid_t proc,
36 enum GNUNET_SCHEDULER_Priority eprio)
37{
38 int prio = 0;
39
40 GNUNET_assert (eprio < GNUNET_SCHEDULER_PRIORITY_COUNT);
41 if (eprio == GNUNET_SCHEDULER_PRIORITY_KEEP)
42 return GNUNET_OK;
43 /* convert to MINGW/Unix values */
44 switch (eprio)
45 {
46 case GNUNET_SCHEDULER_PRIORITY_DEFAULT:
47#ifdef MINGW
48 prio = NORMAL_PRIORITY_CLASS;
49#else
50 prio = 0;
51#endif
52 break;
53 case GNUNET_SCHEDULER_PRIORITY_HIGH:
54#ifdef MINGW
55 prio = ABOVE_NORMAL_PRIORITY_CLASS;
56#else
57 prio = -5;
58#endif
59 break;
60 case GNUNET_SCHEDULER_PRIORITY_BACKGROUND:
61#ifdef MINGW
62 prio = BELOW_NORMAL_PRIORITY_CLASS;
63#else
64 prio = 10;
65#endif
66 break;
67 case GNUNET_SCHEDULER_PRIORITY_UI:
68 case GNUNET_SCHEDULER_PRIORITY_URGENT:
69#ifdef MINGW
70 prio = HIGH_PRIORITY_CLASS;
71#else
72 prio = -10;
73#endif
74 break;
75 case GNUNET_SCHEDULER_PRIORITY_IDLE:
76#ifdef MINGW
77 prio = IDLE_PRIORITY_CLASS;
78#else
79 prio = 19;
80#endif
81 break;
82 default:
83 GNUNET_assert (0);
84 return GNUNET_SYSERR;
85 }
86 /* Set process priority */
87#ifdef MINGW
88 SetPriorityClass (GetCurrentProcess (), prio);
89#else
90 if (proc == getpid ())
91 {
92 errno = 0;
93 if ((-1 == nice (prio)) && (errno != 0))
94 {
95 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING |
96 GNUNET_ERROR_TYPE_BULK, "nice");
97 return GNUNET_SYSERR;
98 }
99 }
100 else
101 {
102 if (0 != setpriority (PRIO_PROCESS, proc, prio))
103
104 {
105 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING |
106 GNUNET_ERROR_TYPE_BULK, "setpriority");
107 return GNUNET_SYSERR;
108 }
109 }
110#endif
111 return GNUNET_OK;
112}
113
114
115
116/**
117 * Start a process.
118 *
119 * @param filename name of the binary
120 * @param ... NULL-terminated list of arguments to the process
121 * @return process ID of the new process, -1 on error
122 */
123pid_t
124GNUNET_OS_start_process (const char *filename, ...)
125{
126 pid_t ret;
127 char **argv;
128 va_list ap;
129 int argc;
130
131 ret = fork ();
132 if (ret != 0)
133 {
134 if (ret == -1)
135 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
136 return ret;
137 }
138 argc = 0;
139 va_start (ap, filename);
140 while (NULL != va_arg (ap, char *))
141 argc++;
142 va_end (ap);
143 argv = GNUNET_malloc (sizeof (char *) * (argc + 1));
144 argc = 0;
145 va_start (ap, filename);
146 while (NULL != (argv[argc] = va_arg (ap, char *)))
147 argc++;
148 va_end (ap);
149 execvp (filename, argv);
150 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename);
151 exit (1);
152}
153
154
155
156
157/**
158 * Start a process.
159 *
160 * @param filename name of the binary
161 * @param argv NULL-terminated list of arguments to the process
162 * @return process ID of the new process, -1 on error
163 */
164pid_t
165GNUNET_OS_start_process_v (const char *filename, char *const argv[])
166{
167 pid_t ret;
168
169 ret = fork ();
170 if (ret != 0)
171 {
172 if (ret == -1)
173 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
174 return ret;
175 }
176 execvp (filename, argv);
177 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename);
178 exit (1);
179}
180
181
182
183
184
185
186/* end of os_priority.c */
diff --git a/src/util/perf_crypto_hash.c b/src/util/perf_crypto_hash.c
new file mode 100644
index 000000000..a6f6ba340
--- /dev/null
+++ b/src/util/perf_crypto_hash.c
@@ -0,0 +1,64 @@
1/*
2 This file is part of GNUnet.
3 (C) 2002, 2003, 2004, 2006 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 2, 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 * @author Christian Grothoff
23 * @file util/perf_crypto_hash.c
24 * @brief measure performance of hash function
25 */
26#include "platform.h"
27#include "gnunet_common.h"
28#include "gnunet_crypto_lib.h"
29#include "gnunet_time_lib.h"
30
31static void
32perfHash ()
33{
34 GNUNET_HashCode hc1;
35 GNUNET_HashCode hc2;
36 GNUNET_HashCode hc3;
37 int i;
38 char *buf;
39
40 buf = GNUNET_malloc (1024 * 64);
41 memset (buf, 1, 1024 * 64);
42 GNUNET_CRYPTO_hash ("foo", 3, &hc1);
43 for (i = 0; i < 1024; i++)
44 {
45 GNUNET_CRYPTO_hash (&hc1, sizeof (GNUNET_HashCode), &hc2);
46 GNUNET_CRYPTO_hash (&hc2, sizeof (GNUNET_HashCode), &hc1);
47 GNUNET_CRYPTO_hash (buf, 1024 * 64, &hc3);
48 }
49 GNUNET_free (buf);
50}
51
52int
53main (int argc, char *argv[])
54{
55 struct GNUNET_TIME_Absolute start;
56
57 start = GNUNET_TIME_absolute_get ();
58 perfHash ();
59 printf ("Hash perf took %llu ms\n",
60 GNUNET_TIME_absolute_get_duration (start).value);
61 return 0;
62}
63
64/* end of hashperf.c */
diff --git a/src/util/plugin.c b/src/util/plugin.c
new file mode 100644
index 000000000..d26a343c7
--- /dev/null
+++ b/src/util/plugin.c
@@ -0,0 +1,243 @@
1/*
2 This file is part of GNUnet
3 (C) 2002, 2003, 2004, 2005, 2006, 2009 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 2, 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 util/plugin.c
23 * @brief Methods to access plugins
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include <libltdl/ltdl.h>
29#include "gnunet_common.h"
30#include "gnunet_os_lib.h"
31#include "gnunet_plugin_lib.h"
32
33/**
34 * Linked list of active plugins.
35 */
36struct PluginList
37{
38 /**
39 * This is a linked list.
40 */
41 struct PluginList *next;
42
43 /**
44 * Name of the library.
45 */
46 char *name;
47
48 /**
49 * System handle.
50 */
51 void *handle;
52};
53
54
55/**
56 * Libtool search path before we started.
57 */
58static char *old_dlsearchpath;
59
60
61/**
62 * List of plugins we have loaded.
63 */
64static struct PluginList *plugins;
65
66
67/**
68 * Setup libtool paths.
69 */
70void __attribute__ ((constructor)) GNUNET_PLUGIN_init ()
71{
72 int err;
73 const char *opath;
74 char *path;
75 char *cpath;
76
77#ifdef MINGW
78 InitWinEnv (NULL);
79#endif
80
81 err = lt_dlinit ();
82 if (err > 0)
83 {
84 fprintf (stderr,
85 _("Initialization of plugin mechanism failed: %s!\n"),
86 lt_dlerror ());
87 return;
88 }
89 opath = lt_dlgetsearchpath ();
90 if (opath != NULL)
91 old_dlsearchpath = GNUNET_strdup (opath);
92 path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR);
93 if (path != NULL)
94 {
95 if (opath != NULL)
96 {
97 cpath = GNUNET_malloc (strlen (path) + strlen (opath) + 4);
98 strcpy (cpath, opath);
99 strcat (cpath, ":");
100 strcat (cpath, path);
101 lt_dlsetsearchpath (cpath);
102 GNUNET_free (path);
103 GNUNET_free (cpath);
104 }
105 else
106 {
107 lt_dlsetsearchpath (path);
108 GNUNET_free (path);
109 }
110 }
111}
112
113
114/**
115 * Shutdown libtool.
116 */
117void __attribute__ ((destructor)) GNUNET_PLUGIN_fini ()
118{
119 lt_dlsetsearchpath (old_dlsearchpath);
120 if (old_dlsearchpath != NULL)
121 {
122 GNUNET_free (old_dlsearchpath);
123 old_dlsearchpath = NULL;
124 }
125
126#ifdef MINGW
127 ShutdownWinEnv ();
128#endif
129
130 lt_dlexit ();
131}
132
133
134/**
135 * Lookup a function in the plugin.
136 */
137static GNUNET_PLUGIN_Callback
138resolve_function (struct PluginList *plug, const char *name)
139{
140 char *initName;
141 void *mptr;
142
143 GNUNET_asprintf (&initName, "_%s_%s", plug->name, name);
144 mptr = lt_dlsym (plug->handle, &initName[1]);
145 if (mptr == NULL)
146 mptr = lt_dlsym (plug->handle, initName);
147 if (mptr == NULL)
148 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
149 _("`%s' failed to resolve method '%s' with error: %s\n"),
150 "lt_dlsym", &initName[1], lt_dlerror ());
151 GNUNET_free (initName);
152 return mptr;
153}
154
155
156/**
157 * Setup plugin (runs the "init" callback and returns whatever "init"
158 * returned). If "init" returns NULL, the plugin is unloaded.
159 *
160 * Note that the library must export symbols called
161 * "library_name_init" and "library_name_done". These will be called
162 * when the library is loaded and unloaded respectively.
163 *
164 * @param library_name name of the plugin to load
165 * @param arg argument to the plugin initialization function
166 * @return whatever the initialization function returned
167 */
168void *
169GNUNET_PLUGIN_load (const char *library_name, void *arg)
170{
171 void *libhandle;
172 struct PluginList *plug;
173 GNUNET_PLUGIN_Callback init;
174 void *ret;
175
176 libhandle = lt_dlopenext (library_name);
177 if (libhandle == NULL)
178 {
179 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
180 _("`%s' failed for library `%s' with error: %s\n"),
181 "lt_dlopenext", library_name, lt_dlerror ());
182 return NULL;
183 }
184 plug = GNUNET_malloc (sizeof (struct PluginList));
185 plug->handle = libhandle;
186 plug->name = GNUNET_strdup (library_name);
187 plug->next = plugins;
188 plugins = plug;
189 init = resolve_function (plug, "init");
190 if ((init == NULL) || (NULL == (ret = init (arg))))
191 {
192 GNUNET_free (plug->name);
193 plugins = plug->next;
194 GNUNET_free (plug);
195 return NULL;
196 }
197 return ret;
198}
199
200
201/**
202 * Unload plugin (runs the "done" callback and returns whatever "done"
203 * returned). The plugin is then unloaded.
204 *
205 * @param library_name name of the plugin to unload
206 * @param arg argument to the plugin shutdown function
207 * @return whatever the shutdown function returned
208 */
209void *
210GNUNET_PLUGIN_unload (const char *library_name, void *arg)
211{
212 struct PluginList *pos;
213 struct PluginList *prev;
214 GNUNET_PLUGIN_Callback done;
215 void *ret;
216
217 prev = NULL;
218 pos = plugins;
219 while ((pos != NULL) && (0 != strcmp (pos->name, library_name)))
220 {
221 prev = pos;
222 pos = pos->next;
223 }
224 if (pos == NULL)
225 return NULL;
226
227 done = resolve_function (pos, "done");
228 ret = NULL;
229 if (done != NULL)
230 ret = done (arg);
231 if (prev == NULL)
232 plugins = pos->next;
233 else
234 prev->next = pos->next;
235 // lt_dlclose (pos->handle);
236 GNUNET_free (pos->name);
237 GNUNET_free (pos);
238 return ret;
239}
240
241
242
243/* end of plugin.c */
diff --git a/src/util/program.c b/src/util/program.c
new file mode 100644
index 000000000..c8ebfc4eb
--- /dev/null
+++ b/src/util/program.c
@@ -0,0 +1,202 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/program.c
23 * @brief standard code for GNUnet startup and shutdown
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_common.h"
29#include "gnunet_configuration_lib.h"
30#include "gnunet_crypto_lib.h"
31#include "gnunet_directories.h"
32#include "gnunet_getopt_lib.h"
33#include "gnunet_os_lib.h"
34#include "gnunet_program_lib.h"
35#include "gnunet_scheduler_lib.h"
36#include <gcrypt.h>
37
38/**
39 * Context for the command.
40 */
41struct CommandContext
42{
43 /**
44 * Argv argument.
45 */
46 char *const *args;
47
48 /**
49 * Name of the configuration file used, can be NULL!
50 */
51 char *cfgfile;
52
53 /**
54 * Main function to run.
55 */
56 GNUNET_PROGRAM_Main task;
57
58 /**
59 * Closure for task.
60 */
61 void *task_cls;
62
63 /**
64 * Configuration to use.
65 */
66 struct GNUNET_CONFIGURATION_Handle *cfg;
67
68};
69
70
71/**
72 * Initial task called by the scheduler for each
73 * program. Runs the program-specific main task.
74 */
75static void
76program_main (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
77{
78 struct CommandContext *cc = cls;
79
80 cc->task (cc->task_cls, tc->sched, cc->args, cc->cfgfile, cc->cfg);
81}
82
83
84/**
85 * Compare function for 'qsort' to sort command-line arguments by the
86 * short option.
87 */
88static int
89cmd_sorter (const void *a1, const void *a2)
90{
91 const struct GNUNET_GETOPT_CommandLineOption *c1 = a1;
92 const struct GNUNET_GETOPT_CommandLineOption *c2 = a2;
93 if (toupper (c1->shortName) > toupper (c2->shortName))
94 return 1;
95 if (toupper (c1->shortName) < toupper (c2->shortName))
96 return -1;
97 if (c1->shortName > c2->shortName)
98 return 1;
99 if (c1->shortName < c2->shortName)
100 return -1;
101 return 0;
102}
103
104
105/**
106 * Run a standard GNUnet command startup sequence (initialize loggers
107 * and configuration, parse options).
108 *
109 * @param argc number of command line arguments
110 * @param argv command line arguments
111 * @param binaryName our expected name
112 * @param options command line options
113 * @param task main function to run
114 * @param task_cls closure for task
115 * @return GNUNET_SYSERR on error, GNUNET_OK on success
116 */
117int
118GNUNET_PROGRAM_run (int argc,
119 char *const *argv,
120 const char *binaryName,
121 const char *binaryHelp,
122 const struct GNUNET_GETOPT_CommandLineOption *options,
123 GNUNET_PROGRAM_Main task, void *task_cls)
124{
125 struct CommandContext cc;
126 char *path;
127 char *loglev;
128 int ret;
129 unsigned int cnt;
130 struct GNUNET_GETOPT_CommandLineOption defoptions[] = {
131 GNUNET_GETOPT_OPTION_CFG_FILE (&cc.cfgfile),
132 GNUNET_GETOPT_OPTION_HELP (binaryHelp),
133 GNUNET_GETOPT_OPTION_LOGLEVEL (&loglev),
134 GNUNET_GETOPT_OPTION_VERSION (PACKAGE_VERSION)
135 };
136 struct GNUNET_GETOPT_CommandLineOption *allopts;
137
138 memset (&cc, 0, sizeof (cc));
139 loglev = NULL;
140 cc.task = task;
141 cc.task_cls = task_cls;
142 cc.cfg = GNUNET_CONFIGURATION_create ();
143
144 /* prepare */
145#if ENABLE_NLS
146 setlocale (LC_ALL, "");
147 path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LOCALEDIR);
148 if (path != NULL)
149 {
150 BINDTEXTDOMAIN ("GNUnet", path);
151 GNUNET_free (path);
152 }
153 textdomain ("GNUnet");
154#endif
155 cnt = 0;
156 while (options[cnt].name != NULL)
157 cnt++;
158 allopts =
159 GNUNET_malloc ((cnt +
160 1) * sizeof (struct GNUNET_GETOPT_CommandLineOption) +
161 sizeof (defoptions));
162 memcpy (allopts, defoptions, sizeof (defoptions));
163 memcpy (&allopts
164 [sizeof (defoptions) /
165 sizeof (struct GNUNET_GETOPT_CommandLineOption)], options,
166 (cnt + 1) * sizeof (struct GNUNET_GETOPT_CommandLineOption));
167 cnt +=
168 sizeof (defoptions) / sizeof (struct GNUNET_GETOPT_CommandLineOption);
169 qsort (allopts, cnt, sizeof (struct GNUNET_GETOPT_CommandLineOption),
170 &cmd_sorter);
171 loglev = GNUNET_strdup ("WARNING");
172 if ((-1 == (ret = GNUNET_GETOPT_run (binaryName,
173 cc.cfg,
174 allopts,
175 (unsigned int) argc, argv))) ||
176 ((GNUNET_OK !=
177 GNUNET_log_setup (binaryName,
178 loglev,
179 NULL)) ||
180 (GNUNET_OK != GNUNET_CONFIGURATION_load (cc.cfg, cc.cfgfile))))
181
182 {
183 GNUNET_free_non_null (cc.cfgfile);
184 GNUNET_free (loglev);
185 GNUNET_free (allopts);
186 return GNUNET_SYSERR;
187 }
188 GNUNET_free (allopts);
189
190 /* run */
191 cc.args = &argv[ret];
192 GNUNET_SCHEDULER_run (&program_main, &cc);
193
194 /* clean up */
195 GNUNET_CONFIGURATION_destroy (cc.cfg);
196 GNUNET_free_non_null (cc.cfgfile);
197 GNUNET_free (loglev);
198 return GNUNET_OK;
199}
200
201
202/* end of program.c */
diff --git a/src/util/pseudonym.c b/src/util/pseudonym.c
new file mode 100644
index 000000000..6d9146613
--- /dev/null
+++ b/src/util/pseudonym.c
@@ -0,0 +1,545 @@
1/*
2 This file is part of GNUnet
3 (C) 2003, 2004, 2005, 2006, 2007, 2008 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 2, 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 util/pseudonym.c
23 * @brief helper functions
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_common.h"
29#include "gnunet_container_lib.h"
30#include "gnunet_disk_lib.h"
31#include "gnunet_pseudonym_lib.h"
32
33#define PS_METADATA_DIR DIR_SEPARATOR_STR "data" DIR_SEPARATOR_STR "pseudonyms/metadata" DIR_SEPARATOR_STR
34#define PS_NAMES_DIR DIR_SEPARATOR_STR "data" DIR_SEPARATOR_STR "pseudonyms/names" DIR_SEPARATOR_STR
35
36struct DiscoveryCallback
37{
38 struct DiscoveryCallback *next;
39 GNUNET_PSEUDONYM_Iterator callback;
40 void *closure;
41};
42
43static struct DiscoveryCallback *head;
44
45/**
46 * Internal notification about new tracked URI.
47 */
48static void
49internal_notify (const GNUNET_HashCode * id,
50 const struct GNUNET_CONTAINER_MetaData *md, int rating)
51{
52 struct DiscoveryCallback *pos;
53
54 pos = head;
55 while (pos != NULL)
56 {
57 pos->callback (pos->closure, id, md, rating);
58 pos = pos->next;
59 }
60}
61
62/**
63 * Register callback to be invoked whenever we discover
64 * a new pseudonym.
65 */
66int
67GNUNET_PSEUDONYM_discovery_callback_register (struct
68 GNUNET_CONFIGURATION_Handle
69 *cfg,
70 GNUNET_PSEUDONYM_Iterator
71 iterator, void *closure)
72{
73 struct DiscoveryCallback *list;
74
75 list = GNUNET_malloc (sizeof (struct DiscoveryCallback));
76 list->callback = iterator;
77 list->closure = closure;
78 list->next = head;
79 head = list;
80 GNUNET_PSEUDONYM_list_all (cfg, iterator, closure);
81 return GNUNET_OK;
82}
83
84/**
85 * Unregister pseudonym discovery callback.
86 */
87int
88GNUNET_PSEUDONYM_discovery_callback_unregister (GNUNET_PSEUDONYM_Iterator
89 iterator, void *closure)
90{
91 struct DiscoveryCallback *prev;
92 struct DiscoveryCallback *pos;
93
94 prev = NULL;
95 pos = head;
96 while ((pos != NULL) &&
97 ((pos->callback != iterator) || (pos->closure != closure)))
98 {
99 prev = pos;
100 pos = pos->next;
101 }
102 if (pos == NULL)
103 return GNUNET_SYSERR;
104 if (prev == NULL)
105 head = pos->next;
106 else
107 prev->next = pos->next;
108 GNUNET_free (pos);
109 return GNUNET_OK;
110}
111
112
113/**
114 * Get the filename (or directory name) for the given
115 * pseudonym identifier and directory prefix.
116 */
117static char *
118get_data_filename (struct GNUNET_CONFIGURATION_Handle
119 *cfg, const char *prefix, const GNUNET_HashCode * psid)
120{
121 struct GNUNET_CRYPTO_HashAsciiEncoded enc;
122
123 if (psid != NULL)
124 GNUNET_CRYPTO_hash_to_enc (psid, &enc);
125 return GNUNET_DISK_get_home_filename (cfg,
126 GNUNET_CLIENT_SERVICE_NAME,
127 prefix,
128 (psid ==
129 NULL) ? NULL : (const char *) &enc,
130 NULL);
131}
132
133static void
134write_pseudonym_info (struct GNUNET_CONFIGURATION_Handle *cfg,
135 const GNUNET_HashCode * nsid,
136 const struct GNUNET_CONTAINER_MetaData *meta,
137 int32_t ranking, const char *ns_name)
138{
139 unsigned int size;
140 unsigned int tag;
141 unsigned int off;
142 char *buf;
143 char *fn;
144
145 fn = get_data_filename (cfg, PS_METADATA_DIR, nsid);
146 GNUNET_assert (fn != NULL);
147 size = GNUNET_CONTAINER_meta_data_get_serialized_size (meta,
148 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);
149 tag = size + sizeof (int) + 1;
150 off = 0;
151 if (ns_name != NULL)
152 {
153 off = strlen (ns_name);
154 tag += off;
155 }
156 buf = GNUNET_malloc (tag);
157 ((int *) buf)[0] = htonl (ranking); /* ranking */
158 if (ns_name != NULL)
159 {
160 memcpy (&buf[sizeof (int)], ns_name, off + 1);
161 }
162 else
163 {
164 buf[sizeof (int)] = '\0';
165 }
166 GNUNET_assert
167 (size == GNUNET_CONTAINER_meta_data_serialize (meta,
168 &buf[sizeof
169 (int) +
170 off + 1],
171 size,
172 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL));
173 GNUNET_DISK_file_write (fn, buf, tag, "660");
174 GNUNET_free (fn);
175 GNUNET_free (buf);
176 /* create entry for pseudonym name in names */
177 GNUNET_free_non_null (GNUNET_PSEUDONYM_id_to_name (cfg, nsid));
178}
179
180static int
181read_info (struct GNUNET_CONFIGURATION_Handle *cfg,
182 const GNUNET_HashCode * nsid,
183 struct GNUNET_CONTAINER_MetaData **meta,
184 int32_t * ranking, char **ns_name)
185{
186 unsigned long long len;
187 unsigned int size;
188 unsigned int zend;
189 struct stat sbuf;
190 char *buf;
191 char *fn;
192
193 if (meta != NULL)
194 *meta = NULL;
195 if (ns_name != NULL)
196 *ns_name = NULL;
197 fn = get_data_filename (cfg, PS_METADATA_DIR, nsid);
198 GNUNET_assert (fn != NULL);
199
200 if ((0 != STAT (fn, &sbuf))
201 || (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES)))
202 {
203 GNUNET_free (fn);
204 return GNUNET_SYSERR;
205 }
206 if (len <= sizeof (int) + 1)
207 {
208 GNUNET_free (fn);
209 return GNUNET_SYSERR;
210 }
211 if (len > 16 * 1024 * 1024)
212 {
213 /* too big, must be invalid! remove! */
214 GNUNET_break (0);
215 if (0 != UNLINK (fn))
216 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn);
217 GNUNET_free (fn);
218 return GNUNET_SYSERR;
219 }
220 buf = GNUNET_malloc (len);
221 if (len != GNUNET_DISK_file_read (fn, len, buf))
222 {
223 GNUNET_free (buf);
224 GNUNET_free (fn);
225 return GNUNET_SYSERR;
226 }
227 if (ranking != NULL)
228 *ranking = ntohl (((int *) buf)[0]);
229 zend = sizeof (int);
230 while ((zend < len) && (buf[zend] != '\0'))
231 zend++;
232 if (zend == len)
233 {
234 GNUNET_free (buf);
235 GNUNET_free (fn);
236 return GNUNET_SYSERR;
237 }
238 if (ns_name != NULL)
239 {
240 if (zend != sizeof (int))
241 *ns_name = GNUNET_strdup (&buf[sizeof (int)]);
242 else
243 *ns_name = NULL;
244 }
245 zend++;
246 size = len - zend;
247 if (meta != NULL)
248 {
249 *meta = GNUNET_CONTAINER_meta_data_deserialize (&buf[zend], size);
250 if ((*meta) == NULL)
251 {
252 /* invalid data! remove! */
253 GNUNET_break (0);
254 if (0 != UNLINK (fn))
255 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
256 "unlink", fn);
257 GNUNET_free (buf);
258 GNUNET_free (fn);
259 return GNUNET_SYSERR;
260 }
261 }
262 GNUNET_free (fn);
263 GNUNET_free (buf);
264 return GNUNET_OK;
265}
266
267
268
269/**
270 * Return the unique, human readable name for the given namespace.
271 *
272 * @return NULL on failure (should never happen)
273 */
274char *
275GNUNET_PSEUDONYM_id_to_name (struct GNUNET_CONFIGURATION_Handle *cfg,
276 const GNUNET_HashCode * nsid)
277{
278 struct GNUNET_CONTAINER_MetaData *meta;
279 char *name;
280 GNUNET_HashCode nh;
281 char *fn;
282 unsigned long long len;
283 int fd;
284 unsigned int i;
285 unsigned int idx;
286 char *ret;
287 struct stat sbuf;
288
289 meta = NULL;
290 name = NULL;
291 if (GNUNET_OK == read_info (cfg, nsid, &meta, NULL, &name))
292 {
293 if ((meta != NULL) && (name == NULL))
294 name = GNUNET_CONTAINER_meta_data_get_first_by_types (meta,
295 EXTRACTOR_TITLE,
296 EXTRACTOR_FILENAME,
297 EXTRACTOR_DESCRIPTION,
298 EXTRACTOR_SUBJECT,
299 EXTRACTOR_PUBLISHER,
300 EXTRACTOR_AUTHOR,
301 EXTRACTOR_COMMENT,
302 EXTRACTOR_SUMMARY,
303 EXTRACTOR_OWNER,
304 -1);
305 if (meta != NULL)
306 {
307 GNUNET_CONTAINER_meta_data_destroy (meta);
308 meta = NULL;
309 }
310 }
311 if (name == NULL)
312 name = GNUNET_strdup (_("no-name"));
313 GNUNET_CRYPTO_hash (name, strlen (name), &nh);
314 fn = get_data_filename (cfg, PS_NAMES_DIR, &nh);
315 GNUNET_assert (fn != NULL);
316
317 len = 0;
318 if (0 == STAT (fn, &sbuf))
319 GNUNET_DISK_file_size (fn, &len, GNUNET_YES);
320 fd = GNUNET_DISK_file_open (fn, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
321 i = 0;
322 idx = -1;
323 while ((len >= sizeof (GNUNET_HashCode)) &&
324 (sizeof (GNUNET_HashCode)
325 == READ (fd, &nh, sizeof (GNUNET_HashCode))))
326 {
327 if (0 == memcmp (&nh, nsid, sizeof (GNUNET_HashCode)))
328 {
329 idx = i;
330 break;
331 }
332 i++;
333 len -= sizeof (GNUNET_HashCode);
334 }
335 if (idx == -1)
336 {
337 idx = i;
338 if (sizeof (GNUNET_HashCode) !=
339 WRITE (fd, nsid, sizeof (GNUNET_HashCode)))
340 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", fn);
341 }
342 CLOSE (fd);
343 ret = GNUNET_malloc (strlen (name) + 32);
344 GNUNET_snprintf (ret, strlen (name) + 32, "%s-%u", name, idx);
345 GNUNET_free (name);
346 GNUNET_free (fn);
347 return ret;
348}
349
350/**
351 * Get the namespace ID belonging to the given namespace name.
352 *
353 * @return GNUNET_OK on success
354 */
355int
356GNUNET_PSEUDONYM_name_to_id (struct GNUNET_CONFIGURATION_Handle *cfg,
357 const char *ns_uname, GNUNET_HashCode * nsid)
358{
359 size_t slen;
360 unsigned long long len;
361 unsigned int idx;
362 char *name;
363 GNUNET_HashCode nh;
364 char *fn;
365 int fd;
366
367 idx = -1;
368 slen = strlen (ns_uname);
369 while ((slen > 0) && (1 != sscanf (&ns_uname[slen - 1], "-%u", &idx)))
370 slen--;
371 if (slen == 0)
372 return GNUNET_SYSERR;
373 name = GNUNET_strdup (ns_uname);
374 name[slen - 1] = '\0';
375 GNUNET_CRYPTO_hash (name, strlen (name), &nh);
376 GNUNET_free (name);
377 fn = get_data_filename (cfg, PS_NAMES_DIR, &nh);
378 GNUNET_assert (fn != NULL);
379
380 if ((GNUNET_OK != GNUNET_DISK_file_test (fn) ||
381 (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES))) ||
382 ((idx + 1) * sizeof (GNUNET_HashCode) > len))
383 {
384 GNUNET_free (fn);
385 return GNUNET_SYSERR;
386 }
387 fd = GNUNET_DISK_file_open (fn, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
388 GNUNET_free (fn);
389 LSEEK (fd, idx * sizeof (GNUNET_HashCode), SEEK_SET);
390 if (sizeof (GNUNET_HashCode) != READ (fd, nsid, sizeof (GNUNET_HashCode)))
391 {
392 CLOSE (fd);
393 return GNUNET_SYSERR;
394 }
395 CLOSE (fd);
396 return GNUNET_OK;
397}
398
399
400
401
402struct ListPseudonymClosure
403{
404 GNUNET_PSEUDONYM_Iterator iterator;
405 void *closure;
406 struct GNUNET_CONFIGURATION_Handle *cfg;
407};
408
409static int
410list_pseudonym_helper (void *cls, const char *fullname)
411{
412 struct ListPseudonymClosure *c = cls;
413 int ret;
414 GNUNET_HashCode id;
415 int rating;
416 struct GNUNET_CONTAINER_MetaData *meta;
417 const char *fn;
418
419 if (strlen (fullname) < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))
420 return GNUNET_OK;
421 fn =
422 &fullname[strlen (fullname) + 1 -
423 sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)];
424 if (fn[-1] != DIR_SEPARATOR)
425 return GNUNET_OK;
426 ret = GNUNET_OK;
427 if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (fn, &id))
428 return GNUNET_OK; /* invalid name */
429 if (GNUNET_OK != read_info (c->cfg, &id, &meta, &rating, NULL))
430 return GNUNET_OK; /* ignore entry */
431 if (c->iterator != NULL)
432 ret = c->iterator (c->closure, &id, meta, rating);
433 GNUNET_CONTAINER_meta_data_destroy (meta);
434 return ret;
435}
436
437/**
438 * List all available pseudonyms.
439 */
440int
441GNUNET_PSEUDONYM_list_all (struct GNUNET_CONFIGURATION_Handle *cfg,
442 GNUNET_PSEUDONYM_Iterator iterator, void *closure)
443{
444 struct ListPseudonymClosure cls;
445 char *fn;
446 int ret;
447
448 cls.iterator = iterator;
449 cls.closure = closure;
450 cls.cfg = cfg;
451 fn = get_data_filename (cfg, PS_METADATA_DIR, NULL);
452 GNUNET_assert (fn != NULL);
453 GNUNET_DISK_directory_create (fn);
454 ret = GNUNET_DISK_directory_scan (fn, &list_pseudonym_helper, &cls);
455 GNUNET_free (fn);
456 return ret;
457}
458
459/**
460 * Change the ranking of a pseudonym.
461 *
462 * @param nsid id of the pseudonym
463 * @param delta by how much should the rating be
464 * changed?
465 * @return new rating of the pseudonym
466 */
467int
468GNUNET_PSEUDONYM_rank (struct GNUNET_CONFIGURATION_Handle *cfg,
469 const GNUNET_HashCode * nsid, int delta)
470{
471 struct GNUNET_CONTAINER_MetaData *meta;
472 int ret;
473 int32_t ranking;
474 char *name;
475
476 name = NULL;
477 ret = read_info (cfg, nsid, &meta, &ranking, &name);
478 if (ret == GNUNET_SYSERR)
479 {
480 ranking = 0;
481 meta = GNUNET_CONTAINER_meta_data_create ();
482 }
483 ranking += delta;
484 write_pseudonym_info (cfg, nsid, meta, ranking, name);
485 GNUNET_CONTAINER_meta_data_destroy (meta);
486 GNUNET_free_non_null (name);
487 return ranking;
488}
489
490/**
491 * Insert metadata into existing MD record (passed as cls).
492 */
493static int
494merge_meta_helper (EXTRACTOR_KeywordType type, const char *data, void *cls)
495{
496 struct GNUNET_CONTAINER_MetaData *meta = cls;
497 GNUNET_CONTAINER_meta_data_insert (meta, type, data);
498 return GNUNET_OK;
499}
500
501
502
503/**
504 * Add a pseudonym to the set of known pseudonyms.
505 * For all pseudonym advertisements that we discover
506 * FSUI should automatically call this function.
507 *
508 * @param id the pseudonym identifier
509 */
510void
511GNUNET_PSEUDONYM_add (struct GNUNET_CONFIGURATION_Handle *cfg,
512 const GNUNET_HashCode * id,
513 const struct GNUNET_CONTAINER_MetaData *meta)
514{
515 char *name;
516 int32_t ranking;
517 struct GNUNET_CONTAINER_MetaData *old;
518 char *fn;
519 struct stat sbuf;
520
521 ranking = 0;
522 fn = get_data_filename (cfg, PS_METADATA_DIR, id);
523 GNUNET_assert (fn != NULL);
524
525 if ((0 == STAT (fn, &sbuf)) &&
526 (GNUNET_OK == read_info (cfg, id, &old, &ranking, &name)))
527 {
528 GNUNET_CONTAINER_meta_data_get_contents (meta, &merge_meta_helper, old);
529 write_pseudonym_info (cfg, id, old, ranking, name);
530 GNUNET_CONTAINER_meta_data_destroy (old);
531 GNUNET_free_non_null (name);
532 }
533 else
534 {
535 write_pseudonym_info (cfg, id, meta, ranking, NULL);
536 }
537 GNUNET_free (fn);
538 internal_notify (id, meta, ranking);
539}
540
541
542
543
544
545/* end of pseudonym.c */
diff --git a/src/util/scheduler.c b/src/util/scheduler.c
new file mode 100644
index 000000000..0d30910e0
--- /dev/null
+++ b/src/util/scheduler.c
@@ -0,0 +1,886 @@
1/*
2 This file is part of GNUnet
3 (C) 2009 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 2, 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 util/scheduler/scheduler.c
23 * @brief schedule computations using continuation passing style
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_common.h"
28#include "gnunet_scheduler_lib.h"
29#include "gnunet_signal_lib.h"
30#include "gnunet_time_lib.h"
31
32/**
33 * Linked list of pending tasks.
34 */
35struct Task
36{
37 /**
38 * This is a linked list.
39 */
40 struct Task *next;
41
42 /**
43 * Function to run when ready.
44 */
45 GNUNET_SCHEDULER_Task callback;
46
47 /**
48 * Closure for the callback.
49 */
50 void *callback_cls;
51
52 /**
53 * Set of file descriptors this task is waiting
54 * for for reading. Once ready, this is updated
55 * to reflect the set of file descriptors ready
56 * for operation.
57 */
58 fd_set read_set;
59
60 /**
61 * Set of file descriptors this task is waiting
62 * for for writing. Once ready, this is updated
63 * to reflect the set of file descriptors ready
64 * for operation.
65 */
66 fd_set write_set;
67
68 /**
69 * Unique task identifier.
70 */
71 GNUNET_SCHEDULER_TaskIdentifier id;
72
73 /**
74 * Identifier of a prerequisite task.
75 */
76 GNUNET_SCHEDULER_TaskIdentifier prereq_id;
77
78 /**
79 * Absolute timeout value for the task, or
80 * GNUNET_TIME_UNIT_FOREVER_ABS for "no timeout".
81 */
82 struct GNUNET_TIME_Absolute timeout;
83
84 /**
85 * Why is the task ready? Set after task is added to ready queue.
86 * Initially set to zero. All reasons that have already been
87 * satisfied (i.e. read or write ready) will be set over time.
88 */
89 enum GNUNET_SCHEDULER_Reason reason;
90
91 /**
92 * Task priority.
93 */
94 enum GNUNET_SCHEDULER_Priority priority;
95
96 /**
97 * highest-numbered file descriptor in read_set or write_set plus one
98 */
99 int nfds;
100
101 /**
102 * Should this task be run on shutdown?
103 */
104 int run_on_shutdown;
105
106};
107
108
109/**
110 * Handle for the scheduling service.
111 */
112struct GNUNET_SCHEDULER_Handle
113{
114
115 /**
116 * List of tasks waiting for an event.
117 */
118 struct Task *pending;
119
120 /**
121 * List of tasks ready to run right now,
122 * grouped by importance.
123 */
124 struct Task *ready[GNUNET_SCHEDULER_PRIORITY_COUNT];
125
126 /**
127 * Identity of the last task queued. Incremented for each task to
128 * generate a unique task ID (it is virtually impossible to start
129 * more than 2^64 tasks during the lifetime of a process).
130 */
131 GNUNET_SCHEDULER_TaskIdentifier last_id;
132
133 /**
134 * Highest number so that all tasks with smaller identifiers
135 * have already completed. Also the lowest number of a task
136 * still waiting to be executed.
137 */
138 GNUNET_SCHEDULER_TaskIdentifier lowest_pending_id;
139
140 /**
141 * GNUNET_NO if we are running normally,
142 * GNUNET_YES if we are in shutdown mode.
143 */
144 int shutdown;
145
146 /**
147 * Number of tasks on the ready list.
148 */
149 unsigned int ready_count;
150
151 /**
152 * Priority of the task running right now. Only
153 * valid while a task is running.
154 */
155 enum GNUNET_SCHEDULER_Priority current_priority;
156
157};
158
159
160/**
161 * Check that the given priority is legal (and return it).
162 */
163static enum GNUNET_SCHEDULER_Priority
164check_priority (enum GNUNET_SCHEDULER_Priority p)
165{
166 if ((p >= 0) && (p < GNUNET_SCHEDULER_PRIORITY_COUNT))
167 return p;
168 GNUNET_assert (0);
169 return 0; /* make compiler happy */
170}
171
172
173/**
174 * Update the timeout value so that it is smaller than min.
175 */
176static void
177update_timeout (struct timeval *tv, struct GNUNET_TIME_Relative min)
178{
179 if (((tv->tv_sec * 1000) + (tv->tv_usec / 1000)) > min.value)
180 {
181 tv->tv_sec = min.value / 1000;
182 tv->tv_usec = (min.value - tv->tv_sec * 1000) * 1000;
183 }
184}
185
186
187/**
188 * Set the given file descriptor bit in the given set and update max
189 * to the maximum of the existing max and fd+1.
190 */
191static void
192set_fd (int fd, int *max, fd_set * set)
193{
194 if (*max <= fd)
195 *max = fd + 1;
196 FD_SET (fd, set);
197}
198
199
200/**
201 * Is a task with this identifier still pending? Also updates
202 * "lowest_pending_id" as a side-effect (for faster checks in the
203 * future), but only if the return value is "GNUNET_NO" (and
204 * the "lowest_pending_id" check failed).
205 *
206 * @return GNUNET_YES if so, GNUNET_NO if not
207 */
208static int
209is_pending (struct GNUNET_SCHEDULER_Handle *sched,
210 GNUNET_SCHEDULER_TaskIdentifier id)
211{
212 struct Task *pos;
213 enum GNUNET_SCHEDULER_Priority p;
214 GNUNET_SCHEDULER_TaskIdentifier min;
215
216 if (id < sched->lowest_pending_id)
217 return GNUNET_NO;
218 min = -1; /* maximum value */
219 pos = sched->pending;
220 while (pos != NULL)
221 {
222 if (pos->id == id)
223 return GNUNET_YES;
224 if (pos->id < min)
225 min = pos->id;
226 pos = pos->next;
227 }
228 for (p = 0; p < GNUNET_SCHEDULER_PRIORITY_COUNT; p++)
229 {
230 pos = sched->ready[p];
231 while (pos != NULL)
232 {
233 if (pos->id == id)
234 return GNUNET_YES;
235 if (pos->id < min)
236 min = pos->id;
237 pos = pos->next;
238 }
239 }
240 sched->lowest_pending_id = min;
241 return GNUNET_NO;
242}
243
244
245/**
246 * Update all sets and timeout for select.
247 */
248static void
249update_sets (struct GNUNET_SCHEDULER_Handle *sched,
250 int *max, fd_set * rs, fd_set * ws, struct timeval *tv)
251{
252 int i;
253 struct Task *pos;
254
255 pos = sched->pending;
256 while (pos != NULL)
257 {
258 if ((pos->prereq_id != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK) &&
259 (GNUNET_YES == is_pending (sched, pos->prereq_id)))
260 {
261 pos = pos->next;
262 continue;
263 }
264
265 if (pos->timeout.value != GNUNET_TIME_UNIT_FOREVER_ABS.value)
266 update_timeout (tv,
267 GNUNET_TIME_absolute_get_remaining (pos->timeout));
268 for (i = 0; i < pos->nfds; i++)
269 {
270 if (FD_ISSET (i, &pos->read_set))
271 set_fd (i, max, rs);
272 if (FD_ISSET (i, &pos->write_set))
273 set_fd (i, max, ws);
274 }
275 pos = pos->next;
276 }
277}
278
279
280/**
281 * Check if the ready set overlaps with the set we want to have ready.
282 * If so, update the want set (set all FDs that are ready). If not,
283 * return GNUNET_NO.
284 *
285 * @param maxfd highest FD that needs to be checked.
286 * @return GNUNET_YES if there was some overlap
287 */
288static int
289set_overlaps (const fd_set * ready, fd_set * want, int maxfd)
290{
291 int i;
292
293 for (i = 0; i < maxfd; i++)
294 if (FD_ISSET (i, want) && FD_ISSET (i, ready))
295 {
296 /* copy all over (yes, there maybe unrelated bits,
297 but this should not hurt well-written clients) */
298 memcpy (want, ready, sizeof (fd_set));
299 return GNUNET_YES;
300 }
301 return GNUNET_NO;
302}
303
304
305/**
306 * Check if the given task is eligible to run now.
307 * Also set the reason why it is eligible.
308 *
309 * @return GNUNET_YES if we can run it, GNUNET_NO if not.
310 */
311static int
312is_ready (struct GNUNET_SCHEDULER_Handle *sched,
313 struct Task *task,
314 struct GNUNET_TIME_Absolute now,
315 const fd_set * rs, const fd_set * ws)
316{
317 if ((GNUNET_NO == task->run_on_shutdown) && (GNUNET_YES == sched->shutdown))
318 return GNUNET_NO;
319 if ((GNUNET_YES == task->run_on_shutdown) &&
320 (GNUNET_YES == sched->shutdown))
321 task->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN;
322 if (now.value >= task->timeout.value)
323 task->reason |= GNUNET_SCHEDULER_REASON_TIMEOUT;
324 if ((0 == (task->reason & GNUNET_SCHEDULER_REASON_READ_READY)) &&
325 (rs != NULL) && (set_overlaps (rs, &task->read_set, task->nfds)))
326 task->reason |= GNUNET_SCHEDULER_REASON_READ_READY;
327 if ((0 == (task->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) &&
328 (ws != NULL) && (set_overlaps (ws, &task->write_set, task->nfds)))
329 task->reason |= GNUNET_SCHEDULER_REASON_WRITE_READY;
330 if (task->reason == 0)
331 return GNUNET_NO; /* not ready */
332 if (task->prereq_id != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
333 {
334 if (GNUNET_YES == is_pending (sched, task->prereq_id))
335 return GNUNET_NO; /* prereq waiting */
336 task->reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE;
337 }
338 return GNUNET_YES;
339}
340
341
342/**
343 * Put a task that is ready for execution into the ready queue.
344 */
345static void
346queue_ready_task (struct GNUNET_SCHEDULER_Handle *handle, struct Task *task)
347{
348 task->next = handle->ready[check_priority (task->priority)];
349 handle->ready[check_priority (task->priority)] = task;
350 handle->ready_count++;
351}
352
353
354/**
355 * Check which tasks are ready and move them
356 * to the respective ready queue.
357 */
358static void
359check_ready (struct GNUNET_SCHEDULER_Handle *handle,
360 const fd_set * rs, const fd_set * ws)
361{
362 struct Task *pos;
363 struct Task *prev;
364 struct Task *next;
365 struct GNUNET_TIME_Absolute now;
366
367 now = GNUNET_TIME_absolute_get ();
368 prev = NULL;
369 pos = handle->pending;
370 while (pos != NULL)
371 {
372 next = pos->next;
373 if (GNUNET_YES == is_ready (handle, pos, now, rs, ws))
374 {
375 if (prev == NULL)
376 handle->pending = next;
377 else
378 prev->next = next;
379 queue_ready_task (handle, pos);
380 pos = next;
381 continue;
382 }
383 prev = pos;
384 pos = next;
385 }
386}
387
388
389/**
390 * Run at least one task in the highest-priority queue that is not
391 * empty. Keep running tasks until we are either no longer running
392 * "URGENT" tasks or until we have at least one "pending" task (which
393 * may become ready, hence we should select on it). Naturally, if
394 * there are no more ready tasks, we also return.
395 */
396static void
397run_ready (struct GNUNET_SCHEDULER_Handle *sched)
398{
399 enum GNUNET_SCHEDULER_Priority p;
400 struct Task *pos;
401 struct GNUNET_SCHEDULER_TaskContext tc;
402
403 do
404 {
405 if (sched->ready_count == 0)
406 return;
407 GNUNET_assert (sched->ready[GNUNET_SCHEDULER_PRIORITY_KEEP] == NULL);
408 /* yes, p>0 is correct, 0 is "KEEP" which should
409 always be an empty queue (see assertion)! */
410 for (p = GNUNET_SCHEDULER_PRIORITY_COUNT - 1; p > 0; p--)
411 {
412 pos = sched->ready[p];
413 if (pos != NULL)
414 break;
415 }
416 GNUNET_assert (pos != NULL); /* ready_count wrong? */
417 sched->ready[p] = pos->next;
418 sched->ready_count--;
419 sched->current_priority = p;
420 GNUNET_assert (pos->priority == p);
421 tc.sched = sched;
422 tc.reason = pos->reason;
423 tc.read_ready = &pos->read_set;
424 tc.write_ready = &pos->write_set;
425 pos->callback (pos->callback_cls, &tc);
426 GNUNET_free (pos);
427 }
428 while ((sched->pending == NULL) || (p == GNUNET_SCHEDULER_PRIORITY_URGENT));
429}
430
431
432/**
433 * Have we (ever) received a SIGINT/TERM/QUIT/HUP?
434 */
435static volatile int sig_shutdown;
436
437
438/**
439 * Signal handler called for signals that should cause us to shutdown.
440 */
441static void
442sighandler_shutdown ()
443{
444 sig_shutdown = 1;
445}
446
447
448/**
449 * Initialize a scheduler using this thread. This function will
450 * return when either a shutdown was initiated (via signal) and all
451 * tasks marked to "run_on_shutdown" have been completed or when all
452 * tasks in general have been completed.
453 *
454 * @param task task to run immediately
455 * @param cls closure of task
456 */
457void
458GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *cls)
459{
460 struct GNUNET_SCHEDULER_Handle sched;
461 fd_set rs;
462 fd_set ws;
463 int max;
464 struct timeval tv;
465 int ret;
466 struct GNUNET_SIGNAL_Context *shc_int;
467 struct GNUNET_SIGNAL_Context *shc_term;
468 struct GNUNET_SIGNAL_Context *shc_quit;
469 struct GNUNET_SIGNAL_Context *shc_hup;
470 struct Task *tpos;
471
472 sig_shutdown = 0;
473 shc_int = GNUNET_SIGNAL_handler_install (SIGINT, &sighandler_shutdown);
474 shc_term = GNUNET_SIGNAL_handler_install (SIGTERM, &sighandler_shutdown);
475 shc_quit = GNUNET_SIGNAL_handler_install (SIGQUIT, &sighandler_shutdown);
476 shc_hup = GNUNET_SIGNAL_handler_install (SIGHUP, &sighandler_shutdown);
477 memset (&sched, 0, sizeof (sched));
478 sched.current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT;
479 GNUNET_SCHEDULER_add_continuation (&sched,
480 GNUNET_YES,
481 task,
482 cls, GNUNET_SCHEDULER_REASON_STARTUP);
483 while ((GNUNET_NO == sched.shutdown) &&
484 (!sig_shutdown) &&
485 ((sched.pending != NULL) || (sched.ready_count > 0)))
486 {
487 FD_ZERO (&rs);
488 FD_ZERO (&ws);
489 max = 0;
490 tv.tv_sec = 0x7FFFFFFF;
491 tv.tv_usec = 0;
492 if (sched.ready_count > 0)
493 {
494 /* no blocking, more work already ready! */
495 tv.tv_sec = 0;
496 tv.tv_usec = 0;
497 }
498 update_sets (&sched, &max, &rs, &ws, &tv);
499 ret = SELECT (max, &rs, &ws, NULL, &tv);
500 if (ret == -1)
501 {
502 if (errno == EINTR)
503 continue;
504 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "select");
505 break;
506 }
507 check_ready (&sched, &rs, &ws);
508 run_ready (&sched);
509 }
510 if (sig_shutdown)
511 sched.shutdown = GNUNET_YES;
512 GNUNET_SIGNAL_handler_uninstall (shc_int);
513 GNUNET_SIGNAL_handler_uninstall (shc_term);
514 GNUNET_SIGNAL_handler_uninstall (shc_quit);
515 GNUNET_SIGNAL_handler_uninstall (shc_hup);
516 do
517 {
518 run_ready (&sched);
519 check_ready (&sched, NULL, NULL);
520 }
521 while (sched.ready_count > 0);
522 while (NULL != (tpos = sched.pending))
523 {
524 sched.pending = tpos->next;
525 GNUNET_free (tpos);
526 }
527}
528
529
530/**
531 * Request the shutdown of a scheduler. This function can be used to
532 * stop a scheduling thread when created with the
533 * "GNUNET_SCHEDULER_init_thread" function or from within the signal
534 * handler for signals causing shutdowns.
535 */
536void
537GNUNET_SCHEDULER_shutdown (struct GNUNET_SCHEDULER_Handle *sched)
538{
539 sched->shutdown = GNUNET_YES;
540}
541
542
543/**
544 * Get information about the current load of this scheduler. Use this
545 * function to determine if an elective task should be added or simply
546 * dropped (if the decision should be made based on the number of
547 * tasks ready to run).
548 *
549 * @param sched scheduler to query
550 * @return number of tasks pending right now
551 */
552unsigned int
553GNUNET_SCHEDULER_get_load (struct GNUNET_SCHEDULER_Handle *sched,
554 enum GNUNET_SCHEDULER_Priority p)
555{
556 struct Task *pos;
557 unsigned int ret;
558
559 if (p == GNUNET_SCHEDULER_PRIORITY_COUNT)
560 return sched->ready_count;
561 if (p == GNUNET_SCHEDULER_PRIORITY_KEEP)
562 p = sched->current_priority;
563 ret = 0;
564 pos = sched->ready[p];
565 while (pos != NULL)
566 {
567 pos = pos->next;
568 ret++;
569 }
570 return ret;
571}
572
573
574/**
575 * Cancel the task with the specified identifier.
576 * The task must not yet have run.
577 *
578 * @param sched scheduler to use
579 * @param task id of the task to cancel
580 */
581void *
582GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Handle *sched,
583 GNUNET_SCHEDULER_TaskIdentifier task)
584{
585 struct Task *t;
586 struct Task *prev;
587 enum GNUNET_SCHEDULER_Priority p;
588 void *ret;
589
590 prev = NULL;
591 t = sched->pending;
592 while (t != NULL)
593 {
594 if (t->id == task)
595 break;
596 prev = t;
597 t = t->next;
598 }
599 p = 0;
600 while (t == NULL)
601 {
602 p++;
603 GNUNET_assert (p < GNUNET_SCHEDULER_PRIORITY_COUNT);
604 prev = NULL;
605 t = sched->ready[p];
606 while (t != NULL)
607 {
608 if (t->id == task)
609 {
610 sched->ready_count--;
611 break;
612 }
613 prev = t;
614 t = t->next;
615 }
616 }
617 if (prev == NULL)
618 {
619 if (p == 0)
620 sched->pending = t->next;
621 else
622 sched->ready[p] = t->next;
623 }
624 else
625 prev->next = t->next;
626 ret = t->callback_cls;
627 GNUNET_free (t);
628 return ret;
629}
630
631
632/**
633 * Continue the current execution with the given function. This is
634 * similar to the other "add" functions except that there is no delay
635 * and the reason code can be specified.
636 *
637 * @param sched scheduler to use
638 * @param main main function of the task
639 * @param cls closure of task
640 * @param reason reason for task invocation
641 */
642void
643GNUNET_SCHEDULER_add_continuation (struct GNUNET_SCHEDULER_Handle *sched,
644 int run_on_shutdown,
645 GNUNET_SCHEDULER_Task main,
646 void *cls,
647 enum GNUNET_SCHEDULER_Reason reason)
648{
649 struct Task *task;
650
651 task = GNUNET_malloc (sizeof (struct Task));
652 task->callback = main;
653 task->callback_cls = cls;
654 task->id = ++sched->last_id;
655 task->reason = reason;
656 task->priority = sched->current_priority;
657 task->run_on_shutdown = run_on_shutdown;
658 queue_ready_task (sched, task);
659}
660
661
662/**
663 * Schedule a new task to be run after the specified
664 * prerequisite task has completed.
665 *
666 * @param sched scheduler to use
667 * @param run_on_shutdown run on shutdown?
668 * @param prio how important is this task?
669 * @param prerequisite_task run this task after the task with the given
670 * task identifier completes (and any of our other
671 * conditions, such as delay, read or write-readyness
672 * are satisfied). Use GNUNET_SCHEDULER_NO_PREREQUISITE_TASK to not have any dependency
673 * on completion of other tasks.
674 * @param main main function of the task
675 * @param cls closure of task
676 * @return unique task identifier for the job
677 * only valid until "main" is started!
678 */
679GNUNET_SCHEDULER_TaskIdentifier
680GNUNET_SCHEDULER_add_after (struct GNUNET_SCHEDULER_Handle *sched,
681 int run_on_shutdown,
682 enum GNUNET_SCHEDULER_Priority prio,
683 GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
684 GNUNET_SCHEDULER_Task main, void *cls)
685{
686 return GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio,
687 prerequisite_task,
688 GNUNET_TIME_UNIT_ZERO,
689 0, NULL, NULL, main, cls);
690}
691
692
693/**
694 * Schedule a new task to be run with a specified delay. The task
695 * will be scheduled for execution once the delay has expired and the
696 * prerequisite task has completed.
697 *
698 * @param sched scheduler to use
699 * @param run_on_shutdown run on shutdown? You can use this
700 * argument to run a function only during shutdown
701 * by setting delay to -1. Set this
702 * argument to GNUNET_NO to skip this task if
703 * the user requested process termination.
704 * @param prio how important is this task?
705 * @param prerequisite_task run this task after the task with the given
706 * task identifier completes (and any of our other
707 * conditions, such as delay, read or write-readyness
708 * are satisfied). Use GNUNET_SCHEDULER_NO_PREREQUISITE_TASK to not have any dependency
709 * on completion of other tasks.
710 * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever"
711 * @param main main function of the task
712 * @param cls closure of task
713 * @return unique task identifier for the job
714 * only valid until "main" is started!
715 */
716GNUNET_SCHEDULER_TaskIdentifier
717GNUNET_SCHEDULER_add_delayed (struct GNUNET_SCHEDULER_Handle * sched,
718 int run_on_shutdown,
719 enum GNUNET_SCHEDULER_Priority prio,
720 GNUNET_SCHEDULER_TaskIdentifier
721 prerequisite_task,
722 struct GNUNET_TIME_Relative delay,
723 GNUNET_SCHEDULER_Task main, void *cls)
724{
725 return GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio,
726 prerequisite_task, delay,
727 0, NULL, NULL, main, cls);
728}
729
730
731/**
732 * Schedule a new task to be run with a specified delay or when the
733 * specified file descriptor is ready for reading. The delay can be
734 * used as a timeout on the socket being ready. The task will be
735 * scheduled for execution once either the delay has expired or the
736 * socket operation is ready.
737 *
738 * @param sched scheduler to use
739 * @param run_on_shutdown run on shutdown? Set this
740 * argument to GNUNET_NO to skip this task if
741 * the user requested process termination.
742 * @param prio how important is this task?
743 * @param prerequisite_task run this task after the task with the given
744 * task identifier completes (and any of our other
745 * conditions, such as delay, read or write-readyness
746 * are satisfied). Use GNUNET_SCHEDULER_NO_PREREQUISITE_TASK to not have any dependency
747 * on completion of other tasks.
748 * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever"
749 * @param rfd read file-descriptor
750 * @param main main function of the task
751 * @param cls closure of task
752 * @return unique task identifier for the job
753 * only valid until "main" is started!
754 */
755GNUNET_SCHEDULER_TaskIdentifier
756GNUNET_SCHEDULER_add_read (struct GNUNET_SCHEDULER_Handle * sched,
757 int run_on_shutdown,
758 enum GNUNET_SCHEDULER_Priority prio,
759 GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
760 struct GNUNET_TIME_Relative delay,
761 int rfd, GNUNET_SCHEDULER_Task main, void *cls)
762{
763 fd_set rs;
764
765 GNUNET_assert (rfd >= 0);
766 FD_ZERO (&rs);
767 FD_SET (rfd, &rs);
768 return GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio,
769 prerequisite_task, delay,
770 rfd + 1, &rs, NULL, main, cls);
771}
772
773
774/**
775 * Schedule a new task to be run with a specified delay or when the
776 * specified file descriptor is ready for writing. The delay can be
777 * used as a timeout on the socket being ready. The task will be
778 * scheduled for execution once either the delay has expired or the
779 * socket operation is ready.
780 *
781 * @param sched scheduler to use
782 * @param run_on_shutdown run on shutdown? Set this
783 * argument to GNUNET_NO to skip this task if
784 * the user requested process termination.
785 * @param prio how important is this task?
786 * @param prerequisite_task run this task after the task with the given
787 * task identifier completes (and any of our other
788 * conditions, such as delay, read or write-readyness
789 * are satisfied). Use GNUNET_SCHEDULER_NO_PREREQUISITE_TASK to not have any dependency
790 * on completion of other tasks.
791 * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever"
792 * @param wfd write file-descriptor
793 * @param main main function of the task
794 * @param cls closure of task
795 * @return unique task identifier for the job
796 * only valid until "main" is started!
797 */
798GNUNET_SCHEDULER_TaskIdentifier
799GNUNET_SCHEDULER_add_write (struct GNUNET_SCHEDULER_Handle * sched,
800 int run_on_shutdown,
801 enum GNUNET_SCHEDULER_Priority prio,
802 GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
803 struct GNUNET_TIME_Relative delay,
804 int wfd, GNUNET_SCHEDULER_Task main, void *cls)
805{
806 fd_set ws;
807
808 GNUNET_assert (wfd >= 0);
809 FD_ZERO (&ws);
810 FD_SET (wfd, &ws);
811 return GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio,
812 prerequisite_task, delay,
813 wfd + 1, NULL, &ws, main, cls);
814}
815
816
817/**
818 * Schedule a new task to be run with a specified delay or when any of
819 * the specified file descriptor sets is ready. The delay can be used
820 * as a timeout on the socket(s) being ready. The task will be
821 * scheduled for execution once either the delay has expired or any of
822 * the socket operations is ready. This is the most general
823 * function of the "add" family. Note that the "prerequisite_task"
824 * must be satisfied in addition to any of the other conditions. In
825 * other words, the task will be started when
826 * <code>
827 * (prerequisite-run)
828 * && (delay-ready
829 * || any-rs-ready
830 * || any-ws-ready
831 * || (shutdown-active && run-on-shutdown) )
832 * </code>
833 *
834 * @param sched scheduler to use
835 * @param run_on_shutdown run on shutdown? Set this
836 * argument to GNUNET_NO to skip this task if
837 * the user requested process termination.
838 * @param prio how important is this task?
839 * @param prerequisite_task run this task after the task with the given
840 * task identifier completes (and any of our other
841 * conditions, such as delay, read or write-readyness
842 * are satisfied). Use GNUNET_SCHEDULER_NO_PREREQUISITE_TASK to not have any dependency
843 * on completion of other tasks.
844 * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever"
845 * @param nfds highest-numbered file descriptor in any of the two sets plus one
846 * @param rs set of file descriptors we want to read (can be NULL)
847 * @param ws set of file descriptors we want to write (can be NULL)
848 * @param main main function of the task
849 * @param cls closure of task
850 * @return unique task identifier for the job
851 * only valid until "main" is started!
852 */
853GNUNET_SCHEDULER_TaskIdentifier
854GNUNET_SCHEDULER_add_select (struct GNUNET_SCHEDULER_Handle * sched,
855 int run_on_shutdown,
856 enum GNUNET_SCHEDULER_Priority prio,
857 GNUNET_SCHEDULER_TaskIdentifier
858 prerequisite_task,
859 struct GNUNET_TIME_Relative delay,
860 int nfds, const fd_set * rs, const fd_set * ws,
861 GNUNET_SCHEDULER_Task main, void *cls)
862{
863 struct Task *task;
864
865 task = GNUNET_malloc (sizeof (struct Task));
866 task->callback = main;
867 task->callback_cls = cls;
868 if ((rs != NULL) && (nfds > 0))
869 memcpy (&task->read_set, rs, sizeof (fd_set));
870 if ((ws != NULL) && (nfds > 0))
871 memcpy (&task->write_set, ws, sizeof (fd_set));
872 task->id = ++sched->last_id;
873 task->prereq_id = prerequisite_task;
874 task->timeout = GNUNET_TIME_relative_to_absolute (delay);
875 task->priority =
876 check_priority ((prio ==
877 GNUNET_SCHEDULER_PRIORITY_KEEP) ? sched->
878 current_priority : prio);
879 task->nfds = nfds;
880 task->run_on_shutdown = run_on_shutdown;
881 task->next = sched->pending;
882 sched->pending = task;
883 return task->id;
884}
885
886/* end of scheduler.c */
diff --git a/src/util/server.c b/src/util/server.c
new file mode 100644
index 000000000..91bc8cc7a
--- /dev/null
+++ b/src/util/server.c
@@ -0,0 +1,1091 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/server.c
23 * @brief library for building GNUnet network servers
24 * @author Christian Grothoff
25 *
26 * TODO:
27 * - fix inefficient memmove in message processing
28 */
29
30#include "platform.h"
31#include "gnunet_common.h"
32#include "gnunet_network_lib.h"
33#include "gnunet_scheduler_lib.h"
34#include "gnunet_server_lib.h"
35#include "gnunet_time_lib.h"
36
37/**
38 * List of arrays of message handlers.
39 */
40struct HandlerList
41{
42 /**
43 * This is a linked list.
44 */
45 struct HandlerList *next;
46
47 /**
48 * NULL-terminated array of handlers.
49 */
50 const struct GNUNET_SERVER_MessageHandler *handlers;
51};
52
53
54/**
55 * List of arrays of message handlers.
56 */
57struct NotifyList
58{
59 /**
60 * This is a linked list.
61 */
62 struct NotifyList *next;
63
64 /**
65 * Function to call.
66 */
67 GNUNET_SERVER_DisconnectCallback callback;
68
69 /**
70 * Closure for callback.
71 */
72 void *callback_cls;
73};
74
75
76/**
77 * @brief handle for a server
78 */
79struct GNUNET_SERVER_Handle
80{
81 /**
82 * My scheduler.
83 */
84 struct GNUNET_SCHEDULER_Handle *sched;
85
86 /**
87 * List of handlers for incoming messages.
88 */
89 struct HandlerList *handlers;
90
91 /**
92 * List of our current clients.
93 */
94 struct GNUNET_SERVER_Client *clients;
95
96 /**
97 * Linked list of functions to call on disconnects by clients.
98 */
99 struct NotifyList *disconnect_notify_list;
100
101 /**
102 * Function to call for access control.
103 */
104 GNUNET_NETWORK_AccessCheck access;
105
106 /**
107 * Closure for access.
108 */
109 void *access_cls;
110
111 /**
112 * After how long should an idle connection time
113 * out (on write).
114 */
115 struct GNUNET_TIME_Relative idle_timeout;
116
117 /**
118 * maximum write buffer size for accepted sockets
119 */
120 size_t maxbuf;
121
122 /**
123 * Pipe used to signal shutdown of the server.
124 */
125 int shutpipe[2];
126
127 /**
128 * Socket used to listen for new connections. Set to
129 * "-1" by GNUNET_SERVER_destroy to initiate shutdown.
130 */
131 int listen_socket;
132
133 /**
134 * Set to GNUNET_YES if we are shutting down.
135 */
136 int do_shutdown;
137
138 /**
139 * Do we ignore messages of types that we do not
140 * understand or do we require that a handler
141 * is found (and if not kill the connection)?
142 */
143 int require_found;
144
145};
146
147
148/**
149 * @brief handle for a client of the server
150 */
151struct GNUNET_SERVER_Client
152{
153
154 /**
155 * Size of the buffer for incoming data. Should be
156 * first so we get nice alignment.
157 */
158 char incoming_buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE];
159
160 /**
161 * This is a linked list.
162 */
163 struct GNUNET_SERVER_Client *next;
164
165 /**
166 * Server that this client belongs to.
167 */
168 struct GNUNET_SERVER_Handle *server;
169
170 /**
171 * Client closure for callbacks.
172 */
173 void *client_closure;
174
175 /**
176 * Callback to receive from client.
177 */
178 GNUNET_SERVER_ReceiveCallback receive;
179
180 /**
181 * Callback to cancel receive from client.
182 */
183 GNUNET_SERVER_ReceiveCancelCallback receive_cancel;
184
185 /**
186 * Callback to ask about transmit-ready notification.
187 */
188 GNUNET_SERVER_TransmitReadyCallback notify_transmit_ready;
189
190 /**
191 * Callback to ask about transmit-ready notification.
192 */
193 GNUNET_SERVER_TransmitReadyCancelCallback notify_transmit_ready_cancel;
194
195 /**
196 * Callback to check if client is still valid.
197 */
198 GNUNET_SERVER_CheckCallback check;
199
200 /**
201 * Callback to destroy client.
202 */
203 GNUNET_SERVER_DestroyCallback destroy;
204
205 /**
206 * Side-buffer for incoming data used when processing
207 * is suspended.
208 */
209 char *side_buf;
210
211 /**
212 * Number of bytes in the side buffer.
213 */
214 size_t side_buf_size;
215
216 /**
217 * Last activity on this socket (used to time it out
218 * if reference_count == 0).
219 */
220 struct GNUNET_TIME_Absolute last_activity;
221
222 /**
223 * Current task identifier for the receive call
224 * (or GNUNET_SCHEDULER_NO_PREREQUISITE_TASK for none).
225 */
226 GNUNET_SCHEDULER_TaskIdentifier my_receive;
227
228 /**
229 * How many bytes in the "incoming_buffer" are currently
230 * valid? (starting at offset 0).
231 */
232 size_t receive_pos;
233
234 /**
235 * Number of external entities with a reference to
236 * this client object.
237 */
238 unsigned int reference_count;
239
240 /**
241 * Was processing if incoming messages suspended while
242 * we were still processing data already received?
243 * This is a counter saying how often processing was
244 * suspended (once per handler invoked).
245 */
246 unsigned int suspended;
247
248 /**
249 * Are we currently in the "process_client_buffer" function (and
250 * will hence restart the receive job on exit if suspended == 0 once
251 * we are done?). If this is set, then "receive_done" will
252 * essentially only decrement suspended; if this is not set, then
253 * "receive_done" may need to restart the receive process (either
254 * from the side-buffer or via select/recv).
255 */
256 int in_process_client_buffer;
257
258 /**
259 * We're about to close down this client due to some serious
260 * error.
261 */
262 int shutdown_now;
263
264};
265
266
267/**
268 * Server has been asked to shutdown, free resources.
269 */
270static void
271destroy_server (struct GNUNET_SERVER_Handle *server)
272{
273 struct GNUNET_SERVER_Client *pos;
274 struct HandlerList *hpos;
275 struct NotifyList *npos;
276
277 GNUNET_assert (server->listen_socket == -1);
278 GNUNET_break (0 == CLOSE (server->shutpipe[0]));
279 GNUNET_break (0 == CLOSE (server->shutpipe[1]));
280 while (server->clients != NULL)
281 {
282 pos = server->clients;
283 server->clients = pos->next;
284 pos->server = NULL;
285 }
286 while (NULL != (hpos = server->handlers))
287 {
288 server->handlers = hpos->next;
289 GNUNET_free (hpos);
290 }
291 while (NULL != (npos = server->disconnect_notify_list))
292 {
293 server->disconnect_notify_list = npos->next;
294 GNUNET_free (npos);
295 }
296 GNUNET_free (server);
297}
298
299
300/**
301 * Scheduler says our listen socket is ready.
302 * Process it!
303 */
304static void
305process_listen_socket (void *cls,
306 const struct GNUNET_SCHEDULER_TaskContext *tc)
307{
308 struct GNUNET_SERVER_Handle *server = cls;
309 struct GNUNET_NETWORK_SocketHandle *sock;
310 struct GNUNET_SERVER_Client *client;
311 fd_set r;
312
313 if ((server->do_shutdown) ||
314 ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0))
315 {
316 /* shutdown was initiated */
317 GNUNET_assert (server->listen_socket != -1);
318 GNUNET_break (0 == CLOSE (server->listen_socket));
319 server->listen_socket = -1;
320 if (server->do_shutdown)
321 destroy_server (server);
322 return;
323 }
324 GNUNET_assert (FD_ISSET (server->listen_socket, tc->read_ready));
325 GNUNET_assert (!FD_ISSET (server->shutpipe[0], tc->read_ready));
326 sock = GNUNET_NETWORK_socket_create_from_accept (tc->sched,
327 server->access,
328 server->access_cls,
329 server->listen_socket,
330 server->maxbuf);
331 if (sock != NULL)
332 {
333 client = GNUNET_SERVER_connect_socket (server, sock);
334 /* decrement reference count, we don't keep "client" alive */
335 GNUNET_SERVER_client_drop (client);
336 }
337 /* listen for more! */
338 FD_ZERO (&r);
339 FD_SET (server->listen_socket, &r);
340 FD_SET (server->shutpipe[0], &r);
341 GNUNET_SCHEDULER_add_select (server->sched,
342 GNUNET_YES,
343 GNUNET_SCHEDULER_PRIORITY_HIGH,
344 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
345 GNUNET_TIME_UNIT_FOREVER_REL,
346 GNUNET_MAX (server->listen_socket,
347 server->shutpipe[0]) + 1, &r, NULL,
348 &process_listen_socket, server);
349}
350
351
352/**
353 * Create and initialize a listen socket for the server.
354 *
355 * @return -1 on error, otherwise the listen socket
356 */
357static int
358open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
359{
360 const static int on = 1;
361 int fd;
362 uint16_t port;
363
364 switch (serverAddr->sa_family)
365 {
366 case AF_INET:
367 port = ntohs (((const struct sockaddr_in *) serverAddr)->sin_port);
368 break;
369 case AF_INET6:
370 port = ntohs (((const struct sockaddr_in6 *) serverAddr)->sin6_port);
371 break;
372 default:
373 GNUNET_break (0);
374 return -1;
375 }
376 fd = SOCKET (serverAddr->sa_family, SOCK_STREAM, 0);
377 if (fd < 0)
378 {
379 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
380 return -1;
381 }
382 if (0 != fcntl (fd, F_SETFD, fcntl (fd, F_GETFD) | FD_CLOEXEC))
383 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
384 "fcntl");
385 if (SETSOCKOPT (fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
386 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
387 "setsockopt");
388 /* bind the socket */
389 if (BIND (fd, serverAddr, socklen) < 0)
390 {
391 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
392 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
393 _
394 ("`%s' failed for port %d. Is the service already running?\n"),
395 "bind", port);
396 GNUNET_break (0 == CLOSE (fd));
397 return -1;
398 }
399 if (0 != LISTEN (fd, 5))
400 {
401 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen");
402 GNUNET_break (0 == CLOSE (fd));
403 return -1;
404 }
405 return fd;
406}
407
408
409/**
410 * Create a new server.
411 *
412 * @param sched scheduler to use
413 * @param access function for access control
414 * @param access_cls closure for access
415 * @param serverAddr address to listen on (including port), use NULL
416 * for internal server (no listening)
417 * @param socklen length of serverAddr
418 * @param maxbuf maximum write buffer size for accepted sockets
419 * @param idle_timeout after how long should we timeout idle connections?
420 * @param require_found if YES, connections sending messages of unknown type
421 * will be closed
422 * @return handle for the new server, NULL on error
423 * (typically, "port" already in use)
424 */
425struct GNUNET_SERVER_Handle *
426GNUNET_SERVER_create (struct GNUNET_SCHEDULER_Handle *sched,
427 GNUNET_NETWORK_AccessCheck access,
428 void *access_cls,
429 const struct sockaddr *serverAddr,
430 socklen_t socklen,
431 size_t maxbuf,
432 struct GNUNET_TIME_Relative
433 idle_timeout, int require_found)
434{
435 struct GNUNET_SERVER_Handle *ret;
436 int lsock;
437 fd_set r;
438
439 lsock = -2;
440 if (serverAddr != NULL)
441 {
442 lsock = open_listen_socket (serverAddr, socklen);
443 if (lsock == -1)
444 return NULL;
445 }
446 ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle));
447 if (0 != PIPE (ret->shutpipe))
448 {
449 GNUNET_break (0 == CLOSE (lsock));
450 GNUNET_free (ret);
451 return NULL;
452 }
453 ret->sched = sched;
454 ret->maxbuf = maxbuf;
455 ret->idle_timeout = idle_timeout;
456 ret->listen_socket = lsock;
457 ret->access = access;
458 ret->access_cls = access_cls;
459 ret->require_found = require_found;
460 if (lsock >= 0)
461 {
462 FD_ZERO (&r);
463 FD_SET (ret->listen_socket, &r);
464 FD_SET (ret->shutpipe[0], &r);
465 GNUNET_SCHEDULER_add_select (sched,
466 GNUNET_YES,
467 GNUNET_SCHEDULER_PRIORITY_HIGH,
468 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
469 GNUNET_TIME_UNIT_FOREVER_REL,
470 GNUNET_MAX (ret->listen_socket,
471 ret->shutpipe[0]) + 1, &r,
472 NULL, &process_listen_socket, ret);
473 }
474 return ret;
475}
476
477
478/**
479 * Free resources held by this server.
480 */
481void
482GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s)
483{
484 static char c;
485
486 GNUNET_assert (s->do_shutdown == GNUNET_NO);
487 s->do_shutdown = GNUNET_YES;
488 if (s->listen_socket == -1)
489 destroy_server (s);
490 else
491 GNUNET_break (1 == WRITE (s->shutpipe[1], &c, 1));
492}
493
494
495/**
496 * Add additional handlers to an existing server.
497 *
498 * @param server the server to add handlers to
499 * @param handlers array of message handlers for
500 * incoming messages; the last entry must
501 * have "NULL" for the "callback"; multiple
502 * entries for the same type are allowed,
503 * they will be called in order of occurence.
504 * These handlers can be removed later;
505 * the handlers array must exist until removed
506 * (or server is destroyed).
507 */
508void
509GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
510 const struct GNUNET_SERVER_MessageHandler
511 *handlers)
512{
513 struct HandlerList *p;
514
515 p = GNUNET_malloc (sizeof (struct HandlerList));
516 p->handlers = handlers;
517 p->next = server->handlers;
518 server->handlers = p;
519}
520
521
522/**
523 * Inject a message into the server, pretend it came
524 * from the specified client. Delivery of the message
525 * will happen instantly (if a handler is installed;
526 * otherwise the call does nothing).
527 *
528 * @param server the server receiving the message
529 * @param sender the "pretended" sender of the message
530 * can be NULL!
531 * @param message message to transmit
532 * @return GNUNET_OK if the message was OK and the
533 * connection can stay open
534 * GNUNET_SYSERR if the connection to the
535 * client should be shut down
536 */
537int
538GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
539 struct GNUNET_SERVER_Client *sender,
540 const struct GNUNET_MessageHeader *message)
541{
542 struct HandlerList *pos;
543 const struct GNUNET_SERVER_MessageHandler *mh;
544 unsigned int i;
545 uint16_t type;
546 uint16_t size;
547 int found;
548
549 type = ntohs (message->type);
550 size = ntohs (message->size);
551 pos = server->handlers;
552 found = GNUNET_NO;
553 while (pos != NULL)
554 {
555 i = 0;
556 while (pos->handlers[i].callback != NULL)
557 {
558 mh = &pos->handlers[i];
559 if (mh->type == type)
560 {
561 if ((mh->expected_size != 0) && (mh->expected_size != size))
562 {
563 GNUNET_break_op (0);
564 return GNUNET_SYSERR;
565 }
566 if (sender != NULL)
567 sender->suspended++;
568 mh->callback (mh->callback_cls, server, sender, message);
569 found = GNUNET_YES;
570 }
571 i++;
572 }
573 pos = pos->next;
574 }
575 if (found == GNUNET_NO)
576 {
577 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
578 _("Received message of unknown type %d\n"), type);
579 if (server->require_found == GNUNET_YES)
580 return GNUNET_SYSERR;
581 }
582 return GNUNET_OK;
583}
584
585
586/**
587 * We're finished with this client and especially its input
588 * processing. If the RC is zero, free all resources otherwise wait
589 * until RC hits zero to do so.
590 */
591static void
592shutdown_incoming_processing (struct GNUNET_SERVER_Client *client)
593{
594 struct GNUNET_SERVER_Client *prev;
595 struct GNUNET_SERVER_Client *pos;
596 struct GNUNET_SERVER_Handle *server;
597 struct NotifyList *n;
598 unsigned int rc;
599
600 GNUNET_assert (client->my_receive == GNUNET_SCHEDULER_NO_PREREQUISITE_TASK);
601 rc = client->reference_count;
602 if (client->server != NULL)
603 {
604 server = client->server;
605 client->server = NULL;
606 prev = NULL;
607 pos = server->clients;
608 while ((pos != NULL) && (pos != client))
609 {
610 prev = pos;
611 pos = pos->next;
612 }
613 GNUNET_assert (pos != NULL);
614 if (prev == NULL)
615 server->clients = pos->next;
616 else
617 prev->next = pos->next;
618 n = server->disconnect_notify_list;
619 while (n != NULL)
620 {
621 n->callback (n->callback_cls, client);
622 n = n->next;
623 }
624 }
625 /* wait for RC to hit zero, then free */
626 if (rc > 0)
627 return;
628 client->destroy (client->client_closure);
629 GNUNET_free (client);
630}
631
632
633static void
634process_client_buffer (struct GNUNET_SERVER_Client *client)
635{
636 struct GNUNET_SERVER_Handle *server;
637 const struct GNUNET_MessageHeader *hdr;
638 size_t msize;
639
640 client->in_process_client_buffer = GNUNET_YES;
641 server = client->server;
642 while ((client->receive_pos >= sizeof (struct GNUNET_MessageHeader)) &&
643 (0 == client->suspended) && (GNUNET_YES != client->shutdown_now))
644 {
645 hdr = (const struct GNUNET_MessageHeader *) &client->incoming_buffer;
646 msize = ntohs (hdr->size);
647 if (msize > client->receive_pos)
648 break;
649 if ((msize < sizeof (struct GNUNET_MessageHeader)) ||
650 (GNUNET_OK != GNUNET_SERVER_inject (server, client, hdr)))
651 {
652 client->in_process_client_buffer = GNUNET_NO;
653 shutdown_incoming_processing (client);
654 return;
655 }
656 /* FIXME: this is highly inefficient; we should
657 try to avoid this if the new base address is
658 already nicely aligned. See old handler code... */
659 memmove (client->incoming_buffer,
660 &client->incoming_buffer[msize], client->receive_pos - msize);
661 client->receive_pos -= msize;
662 }
663 client->in_process_client_buffer = GNUNET_NO;
664 if (GNUNET_YES == client->shutdown_now)
665 shutdown_incoming_processing (client);
666}
667
668
669/**
670 * We are receiving an incoming message. Process it.
671 */
672static void
673process_incoming (void *cls,
674 const void *buf,
675 size_t available,
676 const struct sockaddr *addr, socklen_t addrlen, int errCode)
677{
678 struct GNUNET_SERVER_Client *client = cls;
679 struct GNUNET_SERVER_Handle *server = client->server;
680 const char *cbuf = buf;
681 size_t maxcpy;
682
683 client->my_receive = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
684 if ((buf == NULL) ||
685 (available == 0) ||
686 (errCode != 0) ||
687 (server == NULL) ||
688 (client->shutdown_now == GNUNET_YES) ||
689 (GNUNET_YES != client->check (client->client_closure)))
690 {
691 /* other side closed connection, error connecting, etc. */
692 shutdown_incoming_processing (client);
693 return;
694 }
695 GNUNET_SERVER_client_keep (client);
696 client->last_activity = GNUNET_TIME_absolute_get ();
697 /* process data (if available) */
698 while (available > 0)
699 {
700 maxcpy = available;
701 if (maxcpy > sizeof (client->incoming_buffer) - client->receive_pos)
702 maxcpy = sizeof (client->incoming_buffer) - client->receive_pos;
703 memcpy (&client->incoming_buffer[client->receive_pos], cbuf, maxcpy);
704 client->receive_pos += maxcpy;
705 cbuf += maxcpy;
706 available -= maxcpy;
707 if (0 < client->suspended)
708 {
709 if (available > 0)
710 {
711 client->side_buf_size = available;
712 client->side_buf = GNUNET_malloc (available);
713 memcpy (client->side_buf, cbuf, available);
714 available = 0;
715 }
716 break; /* do not run next client iteration! */
717 }
718 process_client_buffer (client);
719 }
720 GNUNET_assert (available == 0);
721 if ((client->suspended == 0) &&
722 (GNUNET_YES != client->shutdown_now) && (client->server != NULL))
723 {
724 /* Finally, keep receiving! */
725 client->my_receive = client->receive (client->client_closure,
726 GNUNET_SERVER_MAX_MESSAGE_SIZE,
727 server->idle_timeout,
728 &process_incoming, client);
729 }
730 if (GNUNET_YES == client->shutdown_now)
731 shutdown_incoming_processing (client);
732 GNUNET_SERVER_client_drop (client);
733}
734
735
736static void
737restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
738{
739 struct GNUNET_SERVER_Client *client = cls;
740
741 process_client_buffer (client);
742 if (0 == client->suspended)
743 client->my_receive = client->receive (client->client_closure,
744 GNUNET_SERVER_MAX_MESSAGE_SIZE,
745 client->server->idle_timeout,
746 &process_incoming, client);
747}
748
749
750/**
751 * Add a client to the set of our clients and
752 * start receiving.
753 */
754static void
755add_client (struct GNUNET_SERVER_Handle *server,
756 struct GNUNET_SERVER_Client *client)
757{
758 client->server = server;
759 client->last_activity = GNUNET_TIME_absolute_get ();
760 client->next = server->clients;
761 server->clients = client;
762 client->my_receive = client->receive (client->client_closure,
763 GNUNET_SERVER_MAX_MESSAGE_SIZE,
764 server->idle_timeout,
765 &process_incoming, client);
766}
767
768static GNUNET_SCHEDULER_TaskIdentifier
769sock_receive (void *cls,
770 size_t max,
771 struct GNUNET_TIME_Relative timeout,
772 GNUNET_NETWORK_Receiver receiver, void *receiver_cls)
773{
774 return GNUNET_NETWORK_receive (cls, max, timeout, receiver, receiver_cls);
775}
776
777static void
778sock_receive_cancel (void *cls, GNUNET_SCHEDULER_TaskIdentifier ti)
779{
780 GNUNET_NETWORK_receive_cancel (cls, ti);
781}
782
783
784static void *
785sock_notify_transmit_ready (void *cls,
786 size_t size,
787 struct GNUNET_TIME_Relative timeout,
788 GNUNET_NETWORK_TransmitReadyNotify notify,
789 void *notify_cls)
790{
791 return GNUNET_NETWORK_notify_transmit_ready (cls, size, timeout, notify,
792 notify_cls);
793}
794
795
796static void
797sock_notify_transmit_ready_cancel (void *cls, void *h)
798{
799 GNUNET_NETWORK_notify_transmit_ready_cancel (h);
800}
801
802
803/**
804 * Check if socket is still valid (no fatal errors have happened so far).
805 *
806 * @param cls the socket
807 * @return GNUNET_YES if valid, GNUNET_NO otherwise
808 */
809static int
810sock_check (void *cls)
811{
812 return GNUNET_NETWORK_socket_check (cls);
813}
814
815
816/**
817 * Destroy this socket (free resources).
818 *
819 * @param cls the socket
820 */
821static void
822sock_destroy (void *cls)
823{
824 GNUNET_NETWORK_socket_destroy (cls);
825}
826
827
828/**
829 * Add a TCP socket-based connection to the set of handles managed by
830 * this server. Use this function for outgoing (P2P) connections that
831 * we initiated (and where this server should process incoming
832 * messages).
833 *
834 * @param server the server to use
835 * @param connection the connection to manage (client must
836 * stop using this connection from now on)
837 * @return the client handle (client should call
838 * "client_drop" on the return value eventually)
839 */
840struct GNUNET_SERVER_Client *
841GNUNET_SERVER_connect_socket (struct
842 GNUNET_SERVER_Handle
843 *server,
844 struct GNUNET_NETWORK_SocketHandle *connection)
845{
846 struct GNUNET_SERVER_Client *client;
847
848 client = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Client));
849 client->client_closure = connection;
850 client->receive = &sock_receive;
851 client->receive_cancel = &sock_receive_cancel;
852 client->notify_transmit_ready = &sock_notify_transmit_ready;
853 client->notify_transmit_ready_cancel = &sock_notify_transmit_ready_cancel;
854 client->check = &sock_check;
855 client->destroy = &sock_destroy;
856 client->reference_count = 1;
857 add_client (server, client);
858 return client;
859}
860
861
862/**
863 * Add an arbitrary connection to the set of handles managed by this
864 * server. This can be used if a sending and receiving does not
865 * really go over the network (internal transmission) or for servers
866 * using UDP.
867 *
868 * @param server the server to use
869 * @param chandle opaque handle for the connection
870 * @param creceive receive function for the connection
871 * @param ccancel cancel receive function for the connection
872 * @param cnotify transmit notification function for the connection
873 * @param cnotify_cancel transmit notification cancellation function for the connection
874 * @param ccheck function to test if the connection is still up
875 * @param cdestroy function to close and free the connection
876 * @return the client handle (client should call
877 * "client_drop" on the return value eventually)
878 */
879struct GNUNET_SERVER_Client *
880GNUNET_SERVER_connect_callback (struct
881 GNUNET_SERVER_Handle
882 *server,
883 void *chandle,
884 GNUNET_SERVER_ReceiveCallback
885 creceive,
886 GNUNET_SERVER_ReceiveCancelCallback
887 ccancel,
888 GNUNET_SERVER_TransmitReadyCallback
889 cnotify,
890 GNUNET_SERVER_TransmitReadyCancelCallback
891 cnotify_cancel,
892 GNUNET_SERVER_CheckCallback
893 ccheck,
894 GNUNET_SERVER_DestroyCallback cdestroy)
895{
896 struct GNUNET_SERVER_Client *client;
897
898 client = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Client));
899 client->client_closure = chandle;
900 client->receive = creceive;
901 client->receive_cancel = ccancel;
902 client->notify_transmit_ready = cnotify;
903 client->notify_transmit_ready_cancel = cnotify_cancel;
904 client->check = ccheck;
905 client->destroy = cdestroy;
906 client->reference_count = 1;
907 add_client (server, client);
908 return client;
909}
910
911
912/**
913 * Notify the server that the given client handle should
914 * be kept (keeps the connection up if possible, increments
915 * the internal reference counter).
916 *
917 * @param client the client to keep
918 */
919void
920GNUNET_SERVER_client_keep (struct GNUNET_SERVER_Client *client)
921{
922 client->reference_count++;
923}
924
925
926/**
927 * Notify the server that the given client handle is no
928 * longer required. Decrements the reference counter. If
929 * that counter reaches zero an inactive connection maybe
930 * closed.
931 *
932 * @param client the client to drop
933 */
934void
935GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client)
936{
937 GNUNET_assert (client->reference_count > 0);
938 client->reference_count--;
939 if ((client->server == NULL) && (client->reference_count == 0))
940 shutdown_incoming_processing (client);
941}
942
943
944/**
945 * Obtain the network address of the other party.
946 *
947 * @param client the client to get the address for
948 * @param addr where to store the address
949 * @param addrlen where to store the length of the address
950 * @return GNUNET_OK on success
951 */
952int
953GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client,
954 void **addr, size_t * addrlen)
955{
956 if (client->receive != &sock_receive)
957 return GNUNET_SYSERR; /* not a network client */
958 return GNUNET_NETWORK_socket_get_address (client->client_closure,
959 addr, addrlen);
960}
961
962
963/**
964 * Ask the server to notify us whenever a client disconnects.
965 * This function is called whenever the actual network connection
966 * is closed; the reference count may be zero or larger than zero
967 * at this point.
968 *
969 * @param server the server manageing the clients
970 * @param callback function to call on disconnect
971 * @param callback_cls closure for callback
972 */
973void
974GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server,
975 GNUNET_SERVER_DisconnectCallback callback,
976 void *callback_cls)
977{
978 struct NotifyList *n;
979
980 n = GNUNET_malloc (sizeof (struct NotifyList));
981 n->callback = callback;
982 n->callback_cls = callback_cls;
983 n->next = server->disconnect_notify_list;
984 server->disconnect_notify_list = n;
985}
986
987
988/**
989 * Ask the server to disconnect from the given client.
990 * This is the same as returning GNUNET_SYSERR from a message
991 * handler, except that it allows dropping of a client even
992 * when not handling a message from that client.
993 *
994 * @param client the client to disconnect from
995 */
996void
997GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
998{
999 if (client->server == NULL)
1000 return; /* already disconnected */
1001 GNUNET_assert (client->my_receive != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK);
1002 client->receive_cancel (client->client_closure, client->my_receive);
1003 client->my_receive = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1004 shutdown_incoming_processing (client);
1005}
1006
1007
1008/**
1009 * Notify us when the server has enough space to transmit
1010 * a message of the given size to the given client.
1011 *
1012 * @param server the server to use
1013 * @param client client to transmit message to
1014 * @param size requested amount of buffer space
1015 * @param timeout after how long should we give up (and call
1016 * notify with buf NULL and size 0)?
1017 * @param callback function to call when space is available
1018 * @param callback_cls closure for callback
1019 * @return non-NULL if the notify callback was queued; can be used
1020 * to cancel the request using
1021 * GNUNET_NETWORK_notify_transmit_ready_cancel.
1022 * NULL if we are already going to notify someone else (busy)
1023 */
1024struct GNUNET_NETWORK_TransmitHandle *
1025GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
1026 size_t size,
1027 struct GNUNET_TIME_Relative timeout,
1028 GNUNET_NETWORK_TransmitReadyNotify
1029 callback, void *callback_cls)
1030{
1031 return client->notify_transmit_ready (client->client_closure,
1032 size,
1033 timeout, callback, callback_cls);
1034}
1035
1036
1037/**
1038 * Resume receiving from this client, we are done processing the
1039 * current request. This function must be called from within each
1040 * GNUNET_SERVER_MessageCallback (or its respective continuations).
1041 *
1042 * @param client client we were processing a message of
1043 * @param success GNUNET_OK to keep the connection open and
1044 * continue to receive
1045 * GNUNET_SYSERR to close the connection (signal
1046 * serious error)
1047 */
1048void
1049GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success)
1050{
1051 char *sb;
1052
1053 if (client == NULL)
1054 return;
1055 GNUNET_assert (client->suspended > 0);
1056 client->suspended--;
1057 if (success != GNUNET_OK)
1058 client->shutdown_now = GNUNET_YES;
1059 if (client->suspended > 0)
1060 return;
1061 if (client->in_process_client_buffer == GNUNET_YES)
1062 return;
1063 if (client->side_buf_size > 0)
1064 {
1065 /* resume processing from side-buf */
1066 sb = client->side_buf;
1067 client->side_buf = NULL;
1068 /* this will also resume the receive job */
1069 if (GNUNET_YES != client->shutdown_now)
1070 process_incoming (client, sb, client->side_buf_size, NULL, 0, 0);
1071 else
1072 shutdown_incoming_processing (client);
1073 /* finally, free the side-buf */
1074 GNUNET_free (sb);
1075 return;
1076 }
1077 /* resume receive job */
1078 if (GNUNET_YES != client->shutdown_now)
1079 {
1080 GNUNET_SCHEDULER_add_continuation (client->server->sched,
1081 GNUNET_NO,
1082 &restart_processing,
1083 client,
1084 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
1085 return;
1086 }
1087 shutdown_incoming_processing (client);
1088}
1089
1090
1091/* end of server.c */
diff --git a/src/util/server_tc.c b/src/util/server_tc.c
new file mode 100644
index 000000000..dc51e1433
--- /dev/null
+++ b/src/util/server_tc.c
@@ -0,0 +1,198 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/server_tc.c
23 * @brief convenience functions for transmission of
24 * complex responses as a server
25 * @author Christian Grothoff
26 */
27
28#include "platform.h"
29#include "gnunet_common.h"
30#include "gnunet_network_lib.h"
31#include "gnunet_scheduler_lib.h"
32#include "gnunet_server_lib.h"
33#include "gnunet_time_lib.h"
34
35
36
37/**
38 * How much buffer space do we want to have at least
39 * before transmitting another increment?
40 */
41#define MIN_BLOCK_SIZE 128
42
43
44
45struct GNUNET_SERVER_TransmitContext
46{
47 /**
48 * Which client are we transmitting to?
49 */
50 struct GNUNET_SERVER_Client *client;
51
52 /**
53 * Transmission buffer. (current offset for writing).
54 */
55 char *buf;
56
57 /**
58 * Number of bytes in buf.
59 */
60 size_t total;
61
62 /**
63 * Offset for writing in buf.
64 */
65 size_t off;
66
67 /**
68 * Timeout for this request.
69 */
70 struct GNUNET_TIME_Absolute timeout;
71};
72
73
74/**
75 * Helper function for incremental transmission of the response.
76 */
77static size_t
78transmit_response (void *cls, size_t size, void *buf)
79{
80 struct GNUNET_SERVER_TransmitContext *tc = cls;
81 size_t msize;
82 if (buf == NULL)
83 {
84 GNUNET_SERVER_receive_done (tc->client, GNUNET_SYSERR);
85 GNUNET_free_non_null (tc->buf);
86 GNUNET_free (tc);
87 return 0;
88 }
89 if (tc->total - tc->off > size)
90 msize = size;
91 else
92 msize = tc->total - tc->off;
93 memcpy (buf, &tc->buf[tc->off], msize);
94 tc->off += msize;
95 if (tc->total == tc->off)
96 {
97 GNUNET_SERVER_receive_done (tc->client, GNUNET_OK);
98 GNUNET_free_non_null (tc->buf);
99 GNUNET_free (tc);
100 }
101 else
102 {
103 if (NULL == GNUNET_SERVER_notify_transmit_ready (tc->client,
104 GNUNET_MIN
105 (MIN_BLOCK_SIZE,
106 tc->total - tc->off),
107 GNUNET_TIME_absolute_get_remaining
108 (tc->timeout),
109 &transmit_response,
110 tc))
111 {
112 GNUNET_break (0);
113 GNUNET_SERVER_receive_done (tc->client, GNUNET_SYSERR);
114 GNUNET_free_non_null (tc->buf);
115 GNUNET_free (tc);
116 }
117 }
118 return msize;
119}
120
121
122/**
123 * Create a new transmission context for the
124 * given client.
125 *
126 * @param client client to create the context for.
127 * @return NULL on error
128 */
129struct GNUNET_SERVER_TransmitContext *
130GNUNET_SERVER_transmit_context_create (struct GNUNET_SERVER_Client *client)
131{
132 struct GNUNET_SERVER_TransmitContext *tc;
133
134 GNUNET_assert (client != NULL);
135 tc = GNUNET_malloc (sizeof (struct GNUNET_SERVER_TransmitContext));
136 tc->client = client;
137 return tc;
138}
139
140
141/**
142 * Append a message to the transmission context.
143 * All messages in the context will be sent by
144 * the transmit_context_run method.
145 *
146 * @param tc context to use
147 * @param data what to append to the result message
148 * @param length length of data
149 * @param type type of the message
150 */
151void
152GNUNET_SERVER_transmit_context_append (struct GNUNET_SERVER_TransmitContext
153 *tc, const void *data, size_t length,
154 uint16_t type)
155{
156 struct GNUNET_MessageHeader *msg;
157 size_t size;
158
159 GNUNET_assert (length < GNUNET_SERVER_MAX_MESSAGE_SIZE);
160 size = length + sizeof (struct GNUNET_MessageHeader);
161 GNUNET_assert (size > length);
162 tc->buf = GNUNET_realloc (tc->buf, tc->total + size);
163 msg = (struct GNUNET_MessageHeader *) &tc->buf[tc->total];
164 tc->total += size;
165 msg->size = htons (size);
166 msg->type = htons (type);
167 memcpy (&msg[1], data, length);
168}
169
170
171/**
172 * Execute a transmission context. If there is
173 * an error in the transmission, the receive_done
174 * method will be called with an error code (GNUNET_SYSERR),
175 * otherwise with GNUNET_OK.
176 *
177 * @param tc transmission context to use
178 * @param timeout when to time out and abort the transmission
179 */
180void
181GNUNET_SERVER_transmit_context_run (struct GNUNET_SERVER_TransmitContext *tc,
182 struct GNUNET_TIME_Relative timeout)
183{
184 tc->timeout = GNUNET_TIME_relative_to_absolute (timeout);
185 if (NULL ==
186 GNUNET_SERVER_notify_transmit_ready (tc->client,
187 GNUNET_MIN (MIN_BLOCK_SIZE,
188 tc->total), timeout,
189 &transmit_response, tc))
190 {
191 GNUNET_break (0);
192 GNUNET_SERVER_receive_done (tc->client, GNUNET_SYSERR);
193 GNUNET_free_non_null (tc->buf);
194 GNUNET_free (tc);
195 }
196}
197
198/* end of server_tc.c */
diff --git a/src/util/service.c b/src/util/service.c
new file mode 100644
index 000000000..af71db692
--- /dev/null
+++ b/src/util/service.c
@@ -0,0 +1,1451 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/service.c
23 * @brief functions related to starting services
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_common.h"
28#include "gnunet_configuration_lib.h"
29#include "gnunet_crypto_lib.h"
30#include "gnunet_directories.h"
31#include "gnunet_disk_lib.h"
32#include "gnunet_getopt_lib.h"
33#include "gnunet_os_lib.h"
34#include "gnunet_protocols.h"
35#include "gnunet_server_lib.h"
36#include "gnunet_service_lib.h"
37
38/* ******************* access control ******************** */
39
40/**
41 * @brief IPV4 network in CIDR notation.
42 */
43struct IPv4NetworkSet
44{
45 struct in_addr network;
46 struct in_addr netmask;
47};
48
49/**
50 * @brief network in CIDR notation for IPV6.
51 */
52struct IPv6NetworkSet
53{
54 struct in6_addr network;
55 struct in6_addr netmask;
56};
57
58
59/**
60 * Parse a network specification. The argument specifies
61 * a list of networks. The format is
62 * <tt>[network/netmask;]*</tt> (no whitespace, must be terminated
63 * with a semicolon). The network must be given in dotted-decimal
64 * notation. The netmask can be given in CIDR notation (/16) or
65 * in dotted-decimal (/255.255.0.0).
66 * <p>
67 * @param routeList a string specifying the forbidden networks
68 * @return the converted list, NULL if the synatx is flawed
69 */
70static struct IPv4NetworkSet *
71parse_ipv4_specification (const char *routeList)
72{
73 unsigned int count;
74 unsigned int i;
75 unsigned int j;
76 unsigned int len;
77 int cnt;
78 unsigned int pos;
79 unsigned int temps[8];
80 int slash;
81 struct IPv4NetworkSet *result;
82
83 if (routeList == NULL)
84 return NULL;
85 len = strlen (routeList);
86 if (len == 0)
87 return NULL;
88 count = 0;
89 for (i = 0; i < len; i++)
90 if (routeList[i] == ';')
91 count++;
92 result = GNUNET_malloc (sizeof (struct IPv4NetworkSet) * (count + 1));
93 /* add termination */
94 memset (result, 0, sizeof (struct IPv4NetworkSet) * (count + 1));
95 i = 0;
96 pos = 0;
97 while (i < count)
98 {
99 cnt = sscanf (&routeList[pos],
100 "%u.%u.%u.%u/%u.%u.%u.%u;",
101 &temps[0],
102 &temps[1],
103 &temps[2],
104 &temps[3], &temps[4], &temps[5], &temps[6], &temps[7]);
105 if (cnt == 8)
106 {
107 for (j = 0; j < 8; j++)
108 if (temps[j] > 0xFF)
109 {
110 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
111 _("Invalid format for IP: `%s'\n"),
112 &routeList[pos]);
113 GNUNET_free (result);
114 return NULL;
115 }
116 result[i].network.s_addr
117 =
118 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
119 temps[3]);
120 result[i].netmask.s_addr =
121 htonl ((temps[4] << 24) + (temps[5] << 16) + (temps[6] << 8) +
122 temps[7]);
123 while (routeList[pos] != ';')
124 pos++;
125 pos++;
126 i++;
127 continue;
128 }
129 /* try second notation */
130 cnt = sscanf (&routeList[pos],
131 "%u.%u.%u.%u/%u;",
132 &temps[0], &temps[1], &temps[2], &temps[3], &slash);
133 if (cnt == 5)
134 {
135 for (j = 0; j < 4; j++)
136 if (temps[j] > 0xFF)
137 {
138 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
139 _("Invalid format for IP: `%s'\n"),
140 &routeList[pos]);
141 GNUNET_free (result);
142 return NULL;
143 }
144 result[i].network.s_addr
145 =
146 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
147 temps[3]);
148 if ((slash <= 32) && (slash >= 0))
149 {
150 result[i].netmask.s_addr = 0;
151 while (slash > 0)
152 {
153 result[i].netmask.s_addr
154 = (result[i].netmask.s_addr >> 1) + 0x80000000;
155 slash--;
156 }
157 result[i].netmask.s_addr = htonl (result[i].netmask.s_addr);
158 while (routeList[pos] != ';')
159 pos++;
160 pos++;
161 i++;
162 continue;
163 }
164 else
165 {
166 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
167 _
168 ("Invalid network notation ('/%d' is not legal in IPv4 CIDR)."),
169 slash);
170 GNUNET_free (result);
171 return NULL; /* error */
172 }
173 }
174 /* try third notation */
175 slash = 32;
176 cnt = sscanf (&routeList[pos],
177 "%u.%u.%u.%u;",
178 &temps[0], &temps[1], &temps[2], &temps[3]);
179 if (cnt == 4)
180 {
181 for (j = 0; j < 4; j++)
182 if (temps[j] > 0xFF)
183 {
184 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
185 _("Invalid format for IP: `%s'\n"),
186 &routeList[pos]);
187 GNUNET_free (result);
188 return NULL;
189 }
190 result[i].network.s_addr
191 =
192 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
193 temps[3]);
194 result[i].netmask.s_addr = 0;
195 while (slash > 0)
196 {
197 result[i].netmask.s_addr
198 = (result[i].netmask.s_addr >> 1) + 0x80000000;
199 slash--;
200 }
201 result[i].netmask.s_addr = htonl (result[i].netmask.s_addr);
202 while (routeList[pos] != ';')
203 pos++;
204 pos++;
205 i++;
206 continue;
207 }
208 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
209 _("Invalid format for IP: `%s'\n"), &routeList[pos]);
210 GNUNET_free (result);
211 return NULL; /* error */
212 }
213 if (pos < strlen (routeList))
214 {
215 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
216 _("Invalid format for IP: `%s'\n"), &routeList[pos]);
217 GNUNET_free (result);
218 return NULL; /* oops */
219 }
220 return result; /* ok */
221}
222
223
224/**
225 * Parse a network specification. The argument specifies
226 * a list of networks. The format is
227 * <tt>[network/netmask;]*</tt> (no whitespace, must be terminated
228 * with a semicolon). The network must be given in colon-hex
229 * notation. The netmask must be given in CIDR notation (/16) or
230 * can be omitted to specify a single host.
231 * <p>
232 * @param routeList a string specifying the forbidden networks
233 * @return the converted list, NULL if the synatx is flawed
234 */
235static struct IPv6NetworkSet *
236parse_ipv6_specification (const char *routeListX)
237{
238 unsigned int count;
239 unsigned int i;
240 unsigned int len;
241 unsigned int pos;
242 int start;
243 int slash;
244 int ret;
245 char *routeList;
246 struct IPv6NetworkSet *result;
247 unsigned int bits;
248 unsigned int off;
249 int save;
250
251 if (routeListX == NULL)
252 return NULL;
253 len = strlen (routeListX);
254 if (len == 0)
255 return NULL;
256 routeList = GNUNET_strdup (routeListX);
257 count = 0;
258 for (i = 0; i < len; i++)
259 if (routeList[i] == ';')
260 count++;
261 if (routeList[len - 1] != ';')
262 {
263 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
264 _
265 ("Invalid network notation (does not end with ';': `%s')\n"),
266 routeList);
267 GNUNET_free (routeList);
268 return NULL;
269 }
270
271 result = GNUNET_malloc (sizeof (struct IPv6NetworkSet) * (count + 1));
272 memset (result, 0, sizeof (struct IPv6NetworkSet) * (count + 1));
273 i = 0;
274 pos = 0;
275 while (i < count)
276 {
277 start = pos;
278 while (routeList[pos] != ';')
279 pos++;
280 slash = pos;
281 while ((slash >= start) && (routeList[slash] != '/'))
282 slash--;
283 if (slash < start)
284 {
285 memset (&result[i].netmask, 0xFF, sizeof (struct in6_addr));
286 slash = pos;
287 }
288 else
289 {
290 routeList[pos] = '\0';
291 ret = inet_pton (AF_INET6,
292 &routeList[slash + 1], &result[i].netmask);
293 if (ret <= 0)
294 {
295 save = errno;
296 if ((1 != SSCANF (&routeList[slash + 1],
297 "%u", &bits)) || (bits >= 128))
298 {
299 if (ret == 0)
300 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
301 _("Wrong format `%s' for netmask\n"),
302 &routeList[slash + 1]);
303 else
304 {
305 errno = save;
306 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
307 "inet_pton");
308 }
309 GNUNET_free (result);
310 GNUNET_free (routeList);
311 return NULL;
312 }
313 off = 0;
314 while (bits > 8)
315 {
316 result[i].netmask.s6_addr[off++] = 0xFF;
317 bits -= 8;
318 }
319 while (bits > 0)
320 {
321 result[i].netmask.s6_addr[off]
322 = (result[i].netmask.s6_addr[off] >> 1) + 0x80;
323 bits--;
324 }
325 }
326 }
327 routeList[slash] = '\0';
328 ret = inet_pton (AF_INET6, &routeList[start], &result[i].network);
329 if (ret <= 0)
330 {
331 if (ret == 0)
332 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
333 _("Wrong format `%s' for network\n"),
334 &routeList[slash + 1]);
335 else
336 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "inet_pton");
337 GNUNET_free (result);
338 GNUNET_free (routeList);
339 return NULL;
340 }
341 pos++;
342 i++;
343 }
344 GNUNET_free (routeList);
345 return result;
346}
347
348
349/**
350 * Check if the given IP address is in the list of IP addresses.
351 *
352 * @param list a list of networks
353 * @param ip the IP to check (in network byte order)
354 * @return GNUNET_NO if the IP is not in the list, GNUNET_YES if it it is
355 */
356static int
357check_ipv4_listed (const struct IPv4NetworkSet *list,
358 const struct in_addr *add)
359{
360 int i;
361
362 i = 0;
363 if (list == NULL)
364 return GNUNET_NO;
365
366 while ((list[i].network.s_addr != 0) || (list[i].netmask.s_addr != 0))
367 {
368 if ((add->s_addr & list[i].netmask.s_addr) ==
369 (list[i].network.s_addr & list[i].netmask.s_addr))
370 return GNUNET_YES;
371 i++;
372 }
373 return GNUNET_NO;
374}
375
376/**
377 * Check if the given IP address is in the list of IP addresses.
378 *
379 * @param list a list of networks
380 * @param ip the IP to check (in network byte order)
381 * @return GNUNET_NO if the IP is not in the list, GNUNET_YES if it it is
382 */
383static int
384check_ipv6_listed (const struct IPv6NetworkSet *list,
385 const struct in6_addr *ip)
386{
387 unsigned int i;
388 unsigned int j;
389 struct in6_addr zero;
390
391 if (list == NULL)
392 return GNUNET_NO;
393
394 memset (&zero, 0, sizeof (struct in6_addr));
395 i = 0;
396NEXT:
397 while (memcmp (&zero, &list[i].network, sizeof (struct in6_addr)) != 0)
398 {
399 for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++)
400 if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
401 (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
402 {
403 i++;
404 goto NEXT;
405 }
406 return GNUNET_YES;
407 }
408 return GNUNET_NO;
409}
410
411
412/* ****************** service struct ****************** */
413
414
415/**
416 * Context for "service_task".
417 */
418struct GNUNET_SERVICE_Context
419{
420 /**
421 * Our configuration.
422 */
423 struct GNUNET_CONFIGURATION_Handle *cfg;
424
425 /**
426 * Handle for the server.
427 */
428 struct GNUNET_SERVER_Handle *server;
429
430 /**
431 * Scheduler for the server.
432 */
433 struct GNUNET_SCHEDULER_Handle *sched;
434
435 /**
436 * Address to bind to.
437 */
438 struct sockaddr *addr;
439
440 /**
441 * Name of our service.
442 */
443 const char *serviceName;
444
445 /**
446 * Main service-specific task to run.
447 */
448 GNUNET_SERVICE_Main task;
449
450 /**
451 * Closure for task.
452 */
453 void *task_cls;
454
455 /**
456 * IPv4 addresses that are not allowed to connect.
457 */
458 struct IPv4NetworkSet *v4_denied;
459
460 /**
461 * IPv6 addresses that are not allowed to connect.
462 */
463 struct IPv6NetworkSet *v6_denied;
464
465 /**
466 * IPv4 addresses that are allowed to connect (if not
467 * set, all are allowed).
468 */
469 struct IPv4NetworkSet *v4_allowed;
470
471 /**
472 * IPv6 addresses that are allowed to connect (if not
473 * set, all are allowed).
474 */
475 struct IPv6NetworkSet *v6_allowed;
476
477 /**
478 * My (default) message handlers. Adjusted copy
479 * of "defhandlers".
480 */
481 struct GNUNET_SERVER_MessageHandler *my_handlers;
482
483 /**
484 * Idle timeout for server.
485 */
486 struct GNUNET_TIME_Relative timeout;
487
488 /**
489 * Maximum buffer size for the server.
490 */
491 size_t maxbuf;
492
493 /**
494 * Overall success/failure of the service start.
495 */
496 int ret;
497
498 /**
499 * If we are daemonizing, this FD is set to the
500 * pipe to the parent. Send '.' if we started
501 * ok, '!' if not. -1 if we are not daemonizing.
502 */
503 int ready_confirm_fd;
504
505 /**
506 * Do we close connections if we receive messages
507 * for which we have no handler?
508 */
509 int require_found;
510
511 /**
512 * Can clients ask us to initiate a shutdown?
513 */
514 int allow_shutdown;
515
516 /**
517 * Length of addr.
518 */
519 socklen_t addrlen;
520
521};
522
523
524/* ****************** message handlers ****************** */
525
526static size_t
527write_test (void *cls, size_t size, void *buf)
528{
529 struct GNUNET_SERVER_Client *client = cls;
530 struct GNUNET_MessageHeader *msg;
531
532 if (size < sizeof (struct GNUNET_MessageHeader))
533 {
534 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
535 return 0; /* client disconnected */
536 }
537 msg = (struct GNUNET_MessageHeader *) buf;
538 msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
539 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
540 GNUNET_SERVER_receive_done (client, GNUNET_OK);
541 return sizeof (struct GNUNET_MessageHeader);
542}
543
544/**
545 * Handler for TEST message.
546 *
547 * @param cls closure (refers to service)
548 * @param server the server handling the message
549 * @param client identification of the client
550 * @param message the actual message
551 */
552static void
553handle_test (void *cls,
554 struct GNUNET_SERVER_Handle *server,
555 struct GNUNET_SERVER_Client *client,
556 const struct GNUNET_MessageHeader *message)
557{
558 /* simply bounce message back to acknowledge */
559 if (NULL == GNUNET_SERVER_notify_transmit_ready (client,
560 sizeof (struct
561 GNUNET_MessageHeader),
562 GNUNET_TIME_UNIT_FOREVER_REL,
563 &write_test, client))
564 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
565}
566
567
568/**
569 * Handler for SHUTDOWN message.
570 *
571 * @param cls closure (refers to service)
572 * @param server the server handling the message
573 * @param client identification of the client
574 * @param message the actual message
575 */
576static void
577handle_shutdown (void *cls,
578 struct GNUNET_SERVER_Handle *server,
579 struct GNUNET_SERVER_Client *client,
580 const struct GNUNET_MessageHeader *message)
581{
582 struct GNUNET_SERVICE_Context *service = cls;
583 if (!service->allow_shutdown)
584 {
585 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
586 _
587 ("Received shutdown request, but configured to ignore!\n"));
588 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
589 return;
590 }
591 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
592 _("Initiating shutdown as requested by client.\n"));
593 GNUNET_assert (service->sched != NULL);
594 GNUNET_SCHEDULER_shutdown (service->sched);
595 GNUNET_SERVER_receive_done (client, GNUNET_OK);
596}
597
598
599/**
600 * Default handlers for all services. Will be copied and the
601 * "callback_cls" fields will be replaced with the specific service
602 * struct.
603 */
604static const struct GNUNET_SERVER_MessageHandler defhandlers[] = {
605 {&handle_test, NULL, GNUNET_MESSAGE_TYPE_TEST,
606 sizeof (struct GNUNET_MessageHeader)},
607 {&handle_shutdown, NULL, GNUNET_MESSAGE_TYPE_SHUTDOWN,
608 sizeof (struct GNUNET_MessageHeader)},
609 {NULL, NULL, 0, 0}
610};
611
612
613
614/* ****************** service core routines ************** */
615
616
617/**
618 * Check if access to the service is allowed from the given address.
619 */
620static int
621check_access (void *cls, const struct sockaddr *addr, socklen_t addrlen)
622{
623 struct GNUNET_SERVICE_Context *sctx = cls;
624 const struct sockaddr_in *i4;
625 const struct sockaddr_in6 *i6;
626 int ret;
627 char buf[INET6_ADDRSTRLEN];
628 uint16_t port;
629
630 switch (addr->sa_family)
631 {
632 case AF_INET:
633 GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
634 i4 = (const struct sockaddr_in *) addr;
635 port = ntohs (i4->sin_port);
636 ret = ((sctx->v4_allowed == NULL) ||
637 (check_ipv4_listed (sctx->v4_allowed,
638 &i4->sin_addr)))
639 && ((sctx->v4_denied == NULL) ||
640 (!check_ipv4_listed (sctx->v4_denied, &i4->sin_addr)));
641 if (ret != GNUNET_OK)
642 inet_ntop (AF_INET, &i4->sin_addr, buf, sizeof (buf));
643 break;
644 case AF_INET6:
645 GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
646 i6 = (const struct sockaddr_in6 *) addr;
647 port = ntohs (i6->sin6_port);
648 ret = ((sctx->v6_allowed == NULL) ||
649 (check_ipv6_listed (sctx->v6_allowed,
650 &i6->sin6_addr)))
651 && ((sctx->v6_denied == NULL) ||
652 (!check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr)));
653 if (ret != GNUNET_OK)
654 inet_ntop (AF_INET6, &i6->sin6_addr, buf, sizeof (buf));
655 break;
656 default:
657 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
658 _("Unknown address family %d\n"), addr->sa_family);
659 return GNUNET_SYSERR;
660 }
661 if (ret != GNUNET_OK)
662 {
663 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
664 _("Access from `%s:%u' denied to service `%s'\n"),
665 buf, port, sctx->serviceName);
666 }
667 return ret;
668}
669
670
671/**
672 * Get the name of the file where we will
673 * write the PID of the service.
674 */
675static char *
676get_pid_file_name (struct GNUNET_SERVICE_Context *sctx)
677{
678
679 char *pif;
680
681 if (GNUNET_OK !=
682 GNUNET_CONFIGURATION_get_value_filename (sctx->cfg,
683 sctx->serviceName,
684 "PIDFILE", &pif))
685 return NULL;
686 return pif;
687}
688
689
690/**
691 * Parse an IPv4 access control list.
692 */
693static int
694process_acl4 (struct IPv4NetworkSet **ret,
695 struct GNUNET_SERVICE_Context *sctx, const char *option)
696{
697 char *opt;
698
699 if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->serviceName, option))
700 return GNUNET_OK;
701 GNUNET_break (GNUNET_OK ==
702 GNUNET_CONFIGURATION_get_value_string (sctx->cfg,
703 sctx->serviceName,
704 option, &opt));
705 if (NULL == (*ret = parse_ipv4_specification (opt)))
706 {
707 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
708 _
709 ("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
710 opt, sctx->serviceName, option);
711 GNUNET_free (opt);
712 return GNUNET_SYSERR;
713 }
714 GNUNET_free (opt);
715 return GNUNET_OK;
716}
717
718
719/**
720 * Parse an IPv4 access control list.
721 */
722static int
723process_acl6 (struct IPv6NetworkSet **ret,
724 struct GNUNET_SERVICE_Context *sctx, const char *option)
725{
726 char *opt;
727 if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->serviceName, option))
728 return GNUNET_OK;
729 GNUNET_break (GNUNET_OK ==
730 GNUNET_CONFIGURATION_get_value_string (sctx->cfg,
731 sctx->serviceName,
732 option, &opt));
733 if (NULL == (*ret = parse_ipv6_specification (opt)))
734 {
735 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
736 _
737 ("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
738 opt, sctx->serviceName, option);
739 GNUNET_free (opt);
740 return GNUNET_SYSERR;
741 }
742 GNUNET_free (opt);
743 return GNUNET_OK;
744}
745
746
747/**
748 * Setup addr, addrlen, maxbuf, idle_timeout
749 * based on configuration!
750 *
751 * Configuration must specify a "PORT". It may
752 * specify:
753 * - TIMEOUT (after how many ms does an inactive service timeout);
754 * - MAXBUF (maximum incoming message size supported)
755 * - DISABLEV6 (disable support for IPv6, otherwise we use dual-stack)
756 * - ALLOW_SHUTDOWN (allow clients to shutdown this service)
757 * - BINDTO (hostname or IP address to bind to, otherwise we take everything)
758 * - ACCEPT_FROM (only allow connections from specified IPv4 subnets)
759 * - ACCEPT_FROM6 (only allow connections from specified IPv6 subnets)
760 * - REJECT_FROM (disallow allow connections from specified IPv4 subnets)
761 * - REJECT_FROM6 (disallow allow connections from specified IPv6 subnets)
762 *
763 * @return GNUNET_OK if configuration succeeded
764 */
765static int
766setup_service (struct GNUNET_SERVICE_Context *sctx)
767{
768 unsigned long long maxbuf;
769 unsigned long long idleout;
770 char *hostname;
771 unsigned long long port;
772 int disablev6;
773 struct addrinfo hints;
774 struct addrinfo *res;
775 struct addrinfo *pos;
776 int ret;
777 int tolerant;
778
779 if (GNUNET_CONFIGURATION_have_value (sctx->cfg,
780 sctx->serviceName, "TIMEOUT"))
781 {
782 if (GNUNET_OK !=
783 GNUNET_CONFIGURATION_get_value_number (sctx->cfg,
784 sctx->serviceName,
785 "TIMEOUT", &idleout))
786 return GNUNET_SYSERR;
787
788 sctx->timeout.value = idleout;
789 }
790 else
791 sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
792 if (GNUNET_CONFIGURATION_have_value (sctx->cfg,
793 sctx->serviceName, "MAXBUF"))
794 {
795 if (GNUNET_OK !=
796 GNUNET_CONFIGURATION_get_value_number (sctx->cfg,
797 sctx->serviceName,
798 "MAXBUF", &maxbuf))
799 return GNUNET_SYSERR;
800 }
801 else
802 maxbuf = GNUNET_SERVER_MAX_MESSAGE_SIZE;
803 if (GNUNET_CONFIGURATION_have_value (sctx->cfg,
804 sctx->serviceName, "DISABLEV6"))
805 {
806 if (GNUNET_SYSERR ==
807 (disablev6 = GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg,
808 sctx->
809 serviceName,
810 "DISABLEV6")))
811 return GNUNET_SYSERR;
812 }
813 else
814 disablev6 = GNUNET_NO;
815 if (GNUNET_CONFIGURATION_have_value (sctx->cfg,
816 sctx->serviceName, "ALLOW_SHUTDOWN"))
817 {
818 if (GNUNET_SYSERR ==
819 (sctx->allow_shutdown =
820 GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->serviceName,
821 "ALLOW_SHUTDOWN")))
822 return GNUNET_SYSERR;
823 }
824 else
825 sctx->allow_shutdown = GNUNET_NO;
826
827 if (!disablev6)
828 {
829 /* probe IPv6 support */
830 ret = SOCKET (PF_INET6, SOCK_STREAM, 0);
831 if (ret == -1)
832 {
833 if ((errno == ENOBUFS) ||
834 (errno == ENOMEM) || (errno == ENFILE) || (errno == EACCES))
835 {
836 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
837 return GNUNET_SYSERR;
838 }
839 ret = SOCKET (PF_INET, SOCK_STREAM, 0);
840 if (ret != -1)
841 {
842 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
843 _
844 ("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
845 sctx->serviceName, strerror (errno));
846 disablev6 = GNUNET_YES;
847 }
848 }
849 if (ret != -1)
850 GNUNET_break (0 == CLOSE (ret));
851 }
852
853
854
855 if (GNUNET_CONFIGURATION_have_value (sctx->cfg,
856 sctx->serviceName, "TOLERANT"))
857 {
858 if (GNUNET_SYSERR ==
859 (tolerant = GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg,
860 sctx->serviceName,
861 "TOLERANT")))
862 return GNUNET_SYSERR;
863 }
864 else
865 tolerant = GNUNET_NO;
866 sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
867
868
869 if ((GNUNET_OK !=
870 GNUNET_CONFIGURATION_get_value_number (sctx->cfg,
871 sctx->serviceName,
872 "PORT",
873 &port)) || (port > 65535))
874 {
875 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
876 _
877 ("Require valid port number for service `%s' in configuration!\n"),
878 sctx->serviceName);
879 return GNUNET_SYSERR;
880 }
881 if (GNUNET_CONFIGURATION_have_value (sctx->cfg,
882 sctx->serviceName, "BINDTO"))
883 {
884 GNUNET_break (GNUNET_OK ==
885 GNUNET_CONFIGURATION_get_value_string (sctx->cfg,
886 sctx->serviceName,
887 "BINDTO",
888 &hostname));
889 }
890 else
891 hostname = NULL;
892
893 if (hostname != NULL)
894 {
895 memset (&hints, 0, sizeof (struct addrinfo));
896 if (disablev6)
897 hints.ai_family = AF_INET;
898 if ((0 != (ret = getaddrinfo (hostname,
899 NULL, &hints, &res))) || (res == NULL))
900 {
901 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
902 _("Failed to resolve `%s': %s\n"),
903 hostname, gai_strerror (ret));
904 GNUNET_free (hostname);
905 return GNUNET_SYSERR;
906 }
907 pos = res;
908 while ((NULL != pos) &&
909 (((disablev6) &&
910 (pos->ai_family != AF_INET)) ||
911 ((pos->ai_family != AF_INET) && (pos->ai_family != AF_INET6))))
912 pos = pos->ai_next;
913 if (pos == NULL)
914 {
915 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
916 _("Failed to find IPv4 address for `%s'.\n"), hostname);
917 freeaddrinfo (res);
918 GNUNET_free (hostname);
919 return GNUNET_SYSERR;
920 }
921 GNUNET_free (hostname);
922 if (pos->ai_family == AF_INET)
923 {
924 GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in));
925 sctx->addrlen = pos->ai_addrlen;
926 sctx->addr = GNUNET_malloc (sctx->addrlen);
927 memcpy (sctx->addr, res->ai_addr, sctx->addrlen);
928 ((struct sockaddr_in *) sctx->addr)->sin_port = htons (port);
929 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
930 _
931 ("Configured to bind to %s address; %s connections to this service will fail!\n"),
932 "IPv4", "IPv6");
933 }
934 else
935 {
936 GNUNET_assert (pos->ai_family == AF_INET6);
937 GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in6));
938 sctx->addrlen = pos->ai_addrlen;
939 sctx->addr = GNUNET_malloc (sctx->addrlen);
940 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
941 _
942 ("Configured to bind to %s address; %s connections to this service will fail!\n"),
943 "IPv6", "IPv4");
944 ((struct sockaddr_in6 *) sctx->addr)->sin6_port = htons (port);
945 }
946 freeaddrinfo (res);
947 }
948 else
949 {
950 /* will bind against everything, just set port */
951 if (disablev6)
952 {
953 /* V4-only */
954 sctx->addrlen = sizeof (struct sockaddr_in6);
955 sctx->addr = GNUNET_malloc (sctx->addrlen);
956 ((struct sockaddr_in *) sctx->addr)->sin_family = AF_INET;
957 ((struct sockaddr_in *) sctx->addr)->sin_port = htons (port);
958 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
959 _
960 ("Configured to bind to %s address; %s connections to this service will fail!\n"),
961 "IPv4", "IPv6");
962 }
963 else
964 {
965 /* dual stack */
966 sctx->addrlen = sizeof (struct sockaddr_in6);
967 sctx->addr = GNUNET_malloc (sctx->addrlen);
968 ((struct sockaddr_in6 *) sctx->addr)->sin6_family = AF_INET6;
969 ((struct sockaddr_in6 *) sctx->addr)->sin6_port = htons (port);
970 }
971 }
972 sctx->maxbuf = (size_t) maxbuf;
973 if (sctx->maxbuf != maxbuf)
974 {
975 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
976 _
977 ("Value in configuration for `%s' and service `%s' too large!\n"),
978 "MAXBUF", sctx->serviceName);
979 return GNUNET_SYSERR;
980 }
981
982
983 if ((GNUNET_OK !=
984 process_acl4 (&sctx->v4_denied,
985 sctx,
986 "REJECT_FROM")) ||
987 (GNUNET_OK !=
988 process_acl4 (&sctx->v4_allowed,
989 sctx,
990 "ACCEPT_FROM")) ||
991 (GNUNET_OK !=
992 process_acl6 (&sctx->v6_denied,
993 sctx,
994 "REJECT_FROM6")) ||
995 (GNUNET_OK != process_acl6 (&sctx->v6_allowed, sctx, "ACCEPT_FROM6")))
996 return GNUNET_SYSERR;
997 return GNUNET_OK;
998}
999
1000
1001/**
1002 * Get the name of the user that'll be used
1003 * to provide the service.
1004 */
1005static char *
1006get_user_name (struct GNUNET_SERVICE_Context *sctx)
1007{
1008
1009 char *un;
1010
1011 if (GNUNET_OK !=
1012 GNUNET_CONFIGURATION_get_value_filename (sctx->cfg,
1013 sctx->serviceName,
1014 "USERNAME", &un))
1015 return NULL;
1016 return un;
1017}
1018
1019/**
1020 * Write PID file.
1021 */
1022static int
1023write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid)
1024{
1025 FILE *pidfd;
1026 char *pif;
1027 char *user;
1028 char *rdir;
1029 int len;
1030
1031 if (NULL == (pif = get_pid_file_name (sctx)))
1032 return GNUNET_OK; /* no file desired */
1033 user = get_user_name (sctx);
1034 rdir = GNUNET_strdup (pif);
1035 len = strlen (rdir);
1036 while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
1037 len--;
1038 rdir[len] = '\0';
1039 if (0 != ACCESS (rdir, F_OK))
1040 {
1041 /* we get to create a directory -- and claim it
1042 as ours! */
1043 GNUNET_DISK_directory_create (rdir);
1044 if ((user != NULL) && (0 < strlen (user)))
1045 GNUNET_DISK_file_change_owner (rdir, user);
1046 }
1047 if (0 != ACCESS (rdir, W_OK | X_OK))
1048 {
1049 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "access", rdir);
1050 GNUNET_free (rdir);
1051 GNUNET_free_non_null (user);
1052 GNUNET_free (pif);
1053 return GNUNET_SYSERR;
1054 }
1055 GNUNET_free (rdir);
1056 pidfd = FOPEN (pif, "w");
1057 if (pidfd == NULL)
1058 {
1059 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", pif);
1060 GNUNET_free (pif);
1061 GNUNET_free_non_null (user);
1062 return GNUNET_SYSERR;
1063 }
1064 if (0 > FPRINTF (pidfd, "%u", pid))
1065 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fprintf", pif);
1066 GNUNET_break (0 == fclose (pidfd));
1067 if ((user != NULL) && (0 < strlen (user)))
1068 GNUNET_DISK_file_change_owner (pif, user);
1069 GNUNET_free_non_null (user);
1070 GNUNET_free (pif);
1071 return GNUNET_OK;
1072}
1073
1074
1075/**
1076 * Initial task for the service.
1077 */
1078static void
1079service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1080{
1081 struct GNUNET_SERVICE_Context *sctx = cls;
1082 unsigned int i;
1083
1084 sctx->sched = tc->sched;
1085 sctx->server = GNUNET_SERVER_create (tc->sched,
1086 &check_access,
1087 sctx,
1088 sctx->addr,
1089 sctx->addrlen,
1090 sctx->maxbuf,
1091 sctx->timeout, sctx->require_found);
1092 if (sctx->server == NULL)
1093 {
1094 sctx->ret = GNUNET_SYSERR;
1095 return;
1096 }
1097 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
1098 memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
1099 i = 0;
1100 while ((sctx->my_handlers[i].callback != NULL))
1101 sctx->my_handlers[i++].callback_cls = sctx;
1102 GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers);
1103 if (sctx->ready_confirm_fd != -1)
1104 {
1105 GNUNET_break (1 == WRITE (sctx->ready_confirm_fd, ".", 1));
1106 GNUNET_break (0 == CLOSE (sctx->ready_confirm_fd));
1107 sctx->ready_confirm_fd = -1;
1108 write_pid_file (sctx, getpid ());
1109 }
1110
1111 sctx->task (sctx->task_cls, tc->sched, sctx->server, sctx->cfg);
1112}
1113
1114
1115/**
1116 * Detach from terminal.
1117 */
1118static int
1119detach_terminal (struct GNUNET_SERVICE_Context *sctx)
1120{
1121 pid_t pid;
1122 int nullfd;
1123 int filedes[2];
1124
1125#ifndef MINGW
1126 if (0 != PIPE (filedes))
1127 {
1128 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "pipe");
1129 return GNUNET_SYSERR;
1130 }
1131 pid = fork ();
1132 if (pid < 0)
1133 {
1134 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
1135 return GNUNET_SYSERR;
1136 }
1137 if (pid != 0)
1138 {
1139 /* Parent */
1140 char c;
1141
1142 GNUNET_break (0 == CLOSE (filedes[1]));
1143 c = 'X';
1144 if (1 != READ (filedes[0], &c, sizeof (char)))
1145 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "read");
1146 fflush (stdout);
1147 switch (c)
1148 {
1149 case '.':
1150 exit (0);
1151 case 'I':
1152 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1153 _("Service process failed to initialize\n"));
1154 break;
1155 case 'S':
1156 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1157 _
1158 ("Service process could not initialize server function\n"));
1159 break;
1160 case 'X':
1161 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1162 _("Service process failed to report status\n"));
1163 break;
1164 }
1165 exit (1); /* child reported error */
1166 }
1167 GNUNET_break (0 == CLOSE (0));
1168 GNUNET_break (0 == CLOSE (1));
1169 GNUNET_break (0 == CLOSE (filedes[0]));
1170 nullfd = GNUNET_DISK_file_open ("/dev/null", O_RDWR | O_APPEND);
1171 if (nullfd < 0)
1172 return GNUNET_SYSERR;
1173 /* set stdin/stdout to /dev/null */
1174 if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0))
1175 {
1176 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "dup2");
1177 return GNUNET_SYSERR;
1178 }
1179 /* Detach from controlling terminal */
1180 pid = setsid ();
1181 if (pid == -1)
1182 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "setsid");
1183 sctx->ready_confirm_fd = filedes[1];
1184#else
1185 /* FIXME: we probably need to do something else
1186 elsewhere in order to fork the process itself... */
1187 FreeConsole ();
1188#endif
1189 return GNUNET_OK;
1190}
1191
1192
1193/**
1194 * Set user ID.
1195 */
1196static int
1197set_user_id (struct GNUNET_SERVICE_Context *sctx)
1198{
1199 char *user;
1200
1201 if (NULL == (user = get_user_name (sctx)))
1202 return GNUNET_OK; /* keep */
1203#ifndef MINGW
1204 struct passwd *pws;
1205
1206 errno = 0;
1207 pws = getpwnam (user);
1208 if (pws == NULL)
1209 {
1210 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1211 _("Cannot obtain information about user `%s': %s\n"),
1212 user, errno == 0 ? _("No such user") : STRERROR (errno));
1213 GNUNET_free (user);
1214 return GNUNET_SYSERR;
1215 }
1216 if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) ||
1217#if HAVE_INITGROUPS
1218 (0 != initgroups (user, pws->pw_gid)) ||
1219#endif
1220 (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid)))
1221 {
1222 if ((0 != setregid (pws->pw_gid, pws->pw_gid)) ||
1223 (0 != setreuid (pws->pw_uid, pws->pw_uid)))
1224 {
1225 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1226 _("Cannot change user/group to `%s': %s\n"), user,
1227 STRERROR (errno));
1228 GNUNET_free (user);
1229 return GNUNET_SYSERR;
1230 }
1231 }
1232#endif
1233 GNUNET_free (user);
1234 return GNUNET_OK;
1235}
1236
1237
1238/**
1239 * Delete the PID file that was created by our parent.
1240 */
1241static void
1242pid_file_delete (struct GNUNET_SERVICE_Context *sctx)
1243{
1244 char *pif = get_pid_file_name (sctx);
1245 if (pif == NULL)
1246 return; /* no PID file */
1247 if (0 != UNLINK (pif))
1248 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", pif);
1249 GNUNET_free (pif);
1250}
1251
1252/**
1253 * Run a standard GNUnet service startup sequence (initialize loggers
1254 * and configuration, parse options).
1255 *
1256 * @param argc number of command line arguments
1257 * @param argv command line arguments
1258 * @param serviceName our service name
1259 * @param task main task of the service
1260 * @param task_cls closure for task
1261 * @param term termination task of the service
1262 * @param term_cls closure for term
1263 * @return GNUNET_SYSERR on error, GNUNET_OK
1264 * if we shutdown nicely
1265 */
1266int
1267GNUNET_SERVICE_run (int argc,
1268 char *const *argv,
1269 const char *serviceName,
1270 GNUNET_SERVICE_Main task,
1271 void *task_cls, GNUNET_SERVICE_Term term, void *term_cls)
1272{
1273 char *cfg_fn;
1274 char *loglev;
1275 char *logfile;
1276 int do_daemonize;
1277 struct GNUNET_SERVICE_Context sctx;
1278 struct GNUNET_GETOPT_CommandLineOption service_options[] = {
1279 GNUNET_GETOPT_OPTION_CFG_FILE (&cfg_fn),
1280 {'d', "daemonize", NULL,
1281 gettext_noop ("do daemonize (detach from terminal)"), 0,
1282 GNUNET_GETOPT_set_one, &do_daemonize},
1283 GNUNET_GETOPT_OPTION_HELP (serviceName),
1284 GNUNET_GETOPT_OPTION_LOGLEVEL (&loglev),
1285 GNUNET_GETOPT_OPTION_LOGFILE (&logfile),
1286 GNUNET_GETOPT_OPTION_VERSION (PACKAGE_VERSION),
1287 GNUNET_GETOPT_OPTION_END
1288 };
1289 do_daemonize = 0;
1290 logfile = NULL;
1291 loglev = GNUNET_strdup ("WARNING");
1292 cfg_fn = GNUNET_strdup (GNUNET_DEFAULT_DAEMON_CONFIG_FILE);
1293 memset (&sctx, 0, sizeof (sctx));
1294 sctx.ready_confirm_fd = -1;
1295 sctx.ret = GNUNET_OK;
1296 sctx.timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1297 sctx.maxbuf = GNUNET_SERVER_MAX_MESSAGE_SIZE;
1298 sctx.task = task;
1299 sctx.serviceName = serviceName;
1300 sctx.cfg = GNUNET_CONFIGURATION_create ();
1301 /* setup subsystems */
1302 if ((GNUNET_SYSERR ==
1303 GNUNET_GETOPT_run (serviceName,
1304 sctx.cfg,
1305 service_options,
1306 argc,
1307 argv)) ||
1308 (GNUNET_OK !=
1309 GNUNET_log_setup (serviceName, loglev, logfile)) ||
1310 (GNUNET_OK !=
1311 GNUNET_CONFIGURATION_load (sctx.cfg, cfg_fn)) ||
1312 (GNUNET_OK !=
1313 setup_service (&sctx)) ||
1314 ((do_daemonize == 1) &&
1315 (GNUNET_OK != detach_terminal (&sctx))) ||
1316 (GNUNET_OK != set_user_id (&sctx)))
1317 {
1318 if (sctx.ready_confirm_fd != -1)
1319 {
1320 if (1 != WRITE (sctx.ready_confirm_fd, "I", 1))
1321 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "write");
1322 GNUNET_break (0 == CLOSE (sctx.ready_confirm_fd));
1323 }
1324 GNUNET_CONFIGURATION_destroy (sctx.cfg);
1325 GNUNET_free_non_null (sctx.addr);
1326 GNUNET_free_non_null (logfile);
1327 GNUNET_free (loglev);
1328 GNUNET_free (cfg_fn);
1329 GNUNET_free_non_null (sctx.v4_denied);
1330 GNUNET_free_non_null (sctx.v6_denied);
1331 GNUNET_free_non_null (sctx.v4_allowed);
1332 GNUNET_free_non_null (sctx.v6_allowed);
1333 return GNUNET_SYSERR;
1334 }
1335
1336 /* actually run service */
1337 GNUNET_SCHEDULER_run (&service_task, &sctx);
1338 if (sctx.ready_confirm_fd != -1)
1339 {
1340 if (1 != WRITE (sctx.ready_confirm_fd, "S", 1))
1341 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "write");
1342 GNUNET_break (0 == CLOSE (sctx.ready_confirm_fd));
1343 }
1344
1345 /* shutdown */
1346 if (term != NULL)
1347 term (term_cls, sctx.cfg);
1348 if ((do_daemonize == 1) && (sctx.server != NULL))
1349 pid_file_delete (&sctx);
1350 if (sctx.server != NULL)
1351 GNUNET_SERVER_destroy (sctx.server);
1352 GNUNET_free_non_null (sctx.my_handlers);
1353 GNUNET_CONFIGURATION_destroy (sctx.cfg);
1354 GNUNET_free_non_null (sctx.addr);
1355 GNUNET_free_non_null (logfile);
1356 GNUNET_free (loglev);
1357 GNUNET_free (cfg_fn);
1358 GNUNET_free_non_null (sctx.v4_denied);
1359 GNUNET_free_non_null (sctx.v6_denied);
1360 GNUNET_free_non_null (sctx.v4_allowed);
1361 GNUNET_free_non_null (sctx.v6_allowed);
1362 return sctx.ret;
1363}
1364
1365
1366/**
1367 * Run a service startup sequence within an existing
1368 * initialized system.
1369 *
1370 * @param serviceName our service name
1371 * @param sched scheduler to use
1372 * @param cfg configuration to use
1373 * @return NULL on error, service handle
1374 */
1375struct GNUNET_SERVICE_Context *
1376GNUNET_SERVICE_start (const char *serviceName,
1377 struct GNUNET_SCHEDULER_Handle *sched,
1378 struct GNUNET_CONFIGURATION_Handle *cfg)
1379{
1380 int i;
1381 struct GNUNET_SERVICE_Context *sctx;
1382
1383 sctx = GNUNET_malloc (sizeof (struct GNUNET_SERVICE_Context));
1384 sctx->ready_confirm_fd = -1; /* no daemonizing */
1385 sctx->ret = GNUNET_OK;
1386 sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1387 sctx->maxbuf = GNUNET_SERVER_MAX_MESSAGE_SIZE;
1388 sctx->serviceName = serviceName;
1389 sctx->cfg = cfg;
1390 sctx->sched = sched;
1391
1392 /* setup subsystems */
1393 if ((GNUNET_OK != setup_service (sctx)) ||
1394 (NULL == (sctx->server = GNUNET_SERVER_create (sched,
1395 &check_access,
1396 sctx,
1397 sctx->addr,
1398 sctx->addrlen,
1399 sctx->maxbuf,
1400 sctx->timeout,
1401 sctx->require_found))))
1402 {
1403 GNUNET_SERVICE_stop (sctx);
1404 return NULL;
1405 }
1406 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
1407 memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
1408 i = 0;
1409 while ((sctx->my_handlers[i].callback != NULL))
1410 sctx->my_handlers[i++].callback_cls = sctx;
1411 GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers);
1412
1413
1414 return sctx;
1415}
1416
1417/**
1418 * Obtain the server used by a service. Note that the server must NOT
1419 * be destroyed by the caller.
1420 *
1421 * @param ctx the service context returned from the start function
1422 * @return handle to the server for this service, NULL if there is none
1423 */
1424struct GNUNET_SERVER_Handle *
1425GNUNET_SERVICE_get_server (struct GNUNET_SERVICE_Context *ctx)
1426{
1427 return ctx->server;
1428}
1429
1430
1431/**
1432 * Stop a service that was started with "GNUNET_SERVICE_start".
1433 *
1434 * @param ctx the service context returned from the start function
1435 */
1436void
1437GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Context *sctx)
1438{
1439 if (NULL != sctx->server)
1440 GNUNET_SERVER_destroy (sctx->server);
1441 GNUNET_free_non_null (sctx->my_handlers);
1442 GNUNET_free_non_null (sctx->addr);
1443 GNUNET_free_non_null (sctx->v4_denied);
1444 GNUNET_free_non_null (sctx->v6_denied);
1445 GNUNET_free_non_null (sctx->v4_allowed);
1446 GNUNET_free_non_null (sctx->v6_allowed);
1447 GNUNET_free (sctx);
1448}
1449
1450
1451/* end of service.c */
diff --git a/src/util/signal.c b/src/util/signal.c
new file mode 100644
index 000000000..478551ca2
--- /dev/null
+++ b/src/util/signal.c
@@ -0,0 +1,76 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2006 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 2, 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 util/signal.c
23 * @brief code for installing and uninstalling signal handlers
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_common.h"
29#include "gnunet_signal_lib.h"
30
31struct GNUNET_SIGNAL_Context
32{
33 int sig;
34
35 GNUNET_SIGNAL_Handler method;
36
37#ifndef MINGW
38 struct sigaction oldsig;
39#endif
40};
41
42struct GNUNET_SIGNAL_Context *
43GNUNET_SIGNAL_handler_install (int signal, GNUNET_SIGNAL_Handler handler)
44{
45 struct GNUNET_SIGNAL_Context *ret;
46#ifndef MINGW
47 struct sigaction sig;
48#endif
49
50 ret = GNUNET_malloc (sizeof (struct GNUNET_SIGNAL_Context));
51 ret->sig = signal;
52 ret->method = handler;
53#ifndef MINGW
54 sig.sa_handler = (void *) handler;
55 sigemptyset (&sig.sa_mask);
56#ifdef SA_INTERRUPT
57 sig.sa_flags = SA_INTERRUPT; /* SunOS */
58#else
59 sig.sa_flags = SA_RESTART;
60#endif
61 sigaction (signal, &sig, &ret->oldsig);
62#endif
63 return ret;
64}
65
66void
67GNUNET_SIGNAL_handler_uninstall (struct GNUNET_SIGNAL_Context *ctx)
68{
69#ifndef MINGW
70 struct sigaction sig;
71
72 sigemptyset (&sig.sa_mask);
73 sigaction (ctx->sig, &ctx->oldsig, &sig);
74#endif
75 GNUNET_free (ctx);
76}
diff --git a/src/util/strings.c b/src/util/strings.c
new file mode 100644
index 000000000..18f6582e8
--- /dev/null
+++ b/src/util/strings.c
@@ -0,0 +1,396 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005, 2006 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 2, 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 util/strings.c
23 * @brief string functions
24 * @author Nils Durner
25 * @author Christian Grothoff
26 */
27
28#include "platform.h"
29#if HAVE_ICONV_H
30#include <iconv.h>
31#endif
32#include "gnunet_common.h"
33#include "gnunet_strings_lib.h"
34
35
36/**
37 * Fill a buffer of the given size with
38 * count 0-terminated strings (given as varargs).
39 * If "buffer" is NULL, only compute the amount of
40 * space required (sum of "strlen(arg)+1").
41 *
42 * Unlike using "snprintf" with "%s", this function
43 * will add 0-terminators after each string. The
44 * "GNUNET_string_buffer_tokenize" function can be
45 * used to parse the buffer back into individual
46 * strings.
47 *
48 * @return number of bytes written to the buffer
49 * (or number of bytes that would have been written)
50 */
51unsigned int
52GNUNET_STRINGS_buffer_fill (char *buffer,
53 unsigned int size, unsigned int count, ...)
54{
55 unsigned int needed;
56 unsigned int slen;
57 const char *s;
58 va_list ap;
59
60 needed = 0;
61 va_start (ap, count);
62 while (count > 0)
63 {
64 s = va_arg (ap, const char *);
65 slen = strlen (s) + 1;
66 if (buffer != NULL)
67 {
68 GNUNET_assert (needed + slen <= size);
69 memcpy (&buffer[needed], s, slen);
70 }
71 needed += slen;
72 count--;
73 }
74 va_end (ap);
75 return needed;
76}
77
78
79/**
80 * Given a buffer of a given size, find "count"
81 * 0-terminated strings in the buffer and assign
82 * the count (varargs) of type "const char**" to the
83 * locations of the respective strings in the
84 * buffer.
85 *
86 * @param buffer the buffer to parse
87 * @param size size of the buffer
88 * @param count number of strings to locate
89 * @return offset of the character after the last 0-termination
90 * in the buffer, or 0 on error.
91 */
92unsigned int
93GNUNET_STRINGS_buffer_tokenize (const char *buffer,
94 unsigned int size, unsigned int count, ...)
95{
96 unsigned int start;
97 unsigned int needed;
98 const char **r;
99 va_list ap;
100
101 needed = 0;
102 va_start (ap, count);
103 while (count > 0)
104 {
105 r = va_arg (ap, const char **);
106 start = needed;
107 while ((needed < size) && (buffer[needed] != '\0'))
108 needed++;
109 if (needed == size)
110 {
111 va_end (ap);
112 return 0; /* error */
113 }
114 *r = &buffer[start];
115 needed++; /* skip 0-termination */
116 count--;
117 }
118 va_end (ap);
119 return needed;
120}
121
122
123/**
124 * Convert a given filesize into a fancy human-readable format.
125 */
126char *
127GNUNET_STRINGS_byte_size_fancy (unsigned long long size)
128{
129 const char *unit = _( /* size unit */ "b");
130 char *ret;
131
132 if (size > 5 * 1024)
133 {
134 size = size / 1024;
135 unit = _( /* size unit */ "KiB");
136 if (size > 5 * 1024)
137 {
138 size = size / 1024;
139 unit = _( /* size unit */ "MiB");
140 if (size > 5 * 1024)
141 {
142 size = size / 1024;
143 unit = _( /* size unit */ "GiB");
144 if (size > 5 * 1024)
145 {
146 size = size / 1024;
147 unit = _( /* size unit */ "TiB");
148 }
149 }
150 }
151 }
152 ret = GNUNET_malloc (32);
153 GNUNET_snprintf (ret, 32, "%llu%s", size, unit);
154 return ret;
155}
156
157
158/**
159 * Convert the len characters long character sequence
160 * given in input that is in the given charset
161 * to UTF-8.
162 * @return the converted string (0-terminated),
163 * if conversion fails, a copy of the orignal
164 * string is returned.
165 */
166char *
167GNUNET_STRINGS_to_utf8 (const char *input, size_t len, const char *charset)
168{
169 char *ret;
170#if ENABLE_NLS && HAVE_ICONV
171 size_t tmpSize;
172 size_t finSize;
173 char *tmp;
174 char *itmp;
175 iconv_t cd;
176
177 cd = iconv_open ("UTF-8", charset);
178 if (cd == (iconv_t) - 1)
179 {
180 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "iconv_open");
181 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
182 _("Character set requested was `%s'\n"), charset);
183 ret = GNUNET_malloc (len + 1);
184 memcpy (ret, input, len);
185 ret[len] = '\0';
186 return ret;
187 }
188 tmpSize = 3 * len + 4;
189 tmp = GNUNET_malloc (tmpSize);
190 itmp = tmp;
191 finSize = tmpSize;
192 if (iconv (cd, (char **) &input, &len, &itmp, &finSize) == (size_t) - 1)
193 {
194 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "iconv");
195 iconv_close (cd);
196 GNUNET_free (tmp);
197 ret = GNUNET_malloc (len + 1);
198 memcpy (ret, input, len);
199 ret[len] = '\0';
200 return ret;
201 }
202 ret = GNUNET_malloc (tmpSize - finSize + 1);
203 memcpy (ret, tmp, tmpSize - finSize);
204 ret[tmpSize - finSize] = '\0';
205 GNUNET_free (tmp);
206 if (0 != iconv_close (cd))
207 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "iconv_close");
208 return ret;
209#else
210 ret = GNUNET_malloc (len + 1);
211 memcpy (ret, input, len);
212 ret[len] = '\0';
213 return ret;
214#endif
215}
216
217
218/**
219 * Complete filename (a la shell) from abbrevition.
220 * @param fil the name of the file, may contain ~/ or
221 * be relative to the current directory
222 * @returns the full file name,
223 * NULL is returned on error
224 */
225char *
226GNUNET_STRINGS_filename_expand (const char *fil)
227{
228 char *buffer;
229#ifndef MINGW
230 size_t len;
231 size_t n;
232 char *fm;
233 const char *fil_ptr;
234#else
235 char *fn;
236 long lRet;
237#endif
238
239 if (fil == NULL)
240 return NULL;
241
242#ifndef MINGW
243 if (fil[0] == DIR_SEPARATOR)
244 /* absolute path, just copy */
245 return GNUNET_strdup (fil);
246 if (fil[0] == '~')
247 {
248 fm = getenv ("HOME");
249 if (fm == NULL)
250 {
251 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
252 _
253 ("Failed to expand `$HOME': environment variable `HOME' not set"));
254 return NULL;
255 }
256 fm = GNUNET_strdup (fm);
257 /* do not copy '~' */
258 fil_ptr = fil + 1;
259
260 /* skip over dir seperator to be consistent */
261 if (fil_ptr[0] == DIR_SEPARATOR)
262 fil_ptr++;
263 }
264 else
265 {
266 /* relative path */
267 fil_ptr = fil;
268 len = 512;
269 fm = NULL;
270 while (1)
271 {
272 buffer = GNUNET_malloc (len);
273 if (getcwd (buffer, len) != NULL)
274 {
275 fm = buffer;
276 break;
277 }
278 if ((errno == ERANGE) && (len < 1024 * 1024 * 4))
279 {
280 len *= 2;
281 GNUNET_free (buffer);
282 continue;
283 }
284 GNUNET_free (buffer);
285 break;
286 }
287 if (fm == NULL)
288 {
289 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "getcwd");
290 buffer = getenv ("PWD"); /* alternative */
291 if (buffer != NULL)
292 fm = GNUNET_strdup (buffer);
293 }
294 if (fm == NULL)
295 fm = GNUNET_strdup ("./"); /* give up */
296 }
297 n = strlen (fm) + 1 + strlen (fil_ptr) + 1;
298 buffer = GNUNET_malloc (n);
299 GNUNET_snprintf (buffer, n, "%s%s%s",
300 fm,
301 (fm[strlen (fm) - 1] ==
302 DIR_SEPARATOR) ? "" : DIR_SEPARATOR_STR, fil_ptr);
303 GNUNET_free (fm);
304 return buffer;
305#else
306 fn = GNUNET_malloc (MAX_PATH + 1);
307
308 if ((lRet = plibc_conv_to_win_path (fil, fn)) != ERROR_SUCCESS)
309 {
310 SetErrnoFromWinError (lRet);
311 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
312 "plibc_conv_to_win_path");
313 return NULL;
314 }
315 /* is the path relative? */
316 if ((strncmp (fn + 1, ":\\", 2) != 0) && (strncmp (fn, "\\\\", 2) != 0))
317 {
318 char szCurDir[MAX_PATH + 1];
319 lRet = GetCurrentDirectory (MAX_PATH + 1, szCurDir);
320 if (lRet + strlen (fn) + 1 > (MAX_PATH + 1))
321 {
322 SetErrnoFromWinError (ERROR_BUFFER_OVERFLOW);
323 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
324 "GetCurrentDirectory");
325 return NULL;
326 }
327 buffer = GNUNET_malloc (MAX_PATH + 1);
328 GNUNET_snprintf (buffer, MAX_PATH + 1, "%s\\%s", szCurDir, fn);
329 GNUNET_free (fn);
330 fn = buffer;
331 }
332
333 return fn;
334#endif
335}
336
337
338/**
339 * Give relative time in human-readable fancy format.
340 * @param delta time in milli seconds
341 */
342char *
343GNUNET_STRINGS_relative_time_to_string (struct GNUNET_TIME_Relative del)
344{
345 const char *unit = _( /* time unit */ "ms");
346 char *ret;
347 uint64_t delta = del.value;
348
349 if (delta > 5 * 1000)
350 {
351 delta = delta / 1000;
352 unit = _( /* time unit */ "s");
353 if (delta > 5 * 60)
354 {
355 delta = delta / 60;
356 unit = _( /* time unit */ "m");
357 if (delta > 5 * 60)
358 {
359 delta = delta / 60;
360 unit = _( /* time unit */ "h");
361 if (delta > 5 * 24)
362 {
363 delta = delta / 24;
364 unit = _( /* time unit */ " days");
365 }
366 }
367 }
368 }
369 GNUNET_asprintf (&ret, "%llu%s", delta, unit);
370 return ret;
371}
372
373
374/**
375 * "man ctime_r", except for GNUnet time; also, unlike ctime, the
376 * return value does not include the newline character.
377 */
378char *
379GNUNET_STRINGS_absolute_time_to_string (struct GNUNET_TIME_Absolute t)
380{
381 time_t tt;
382 char *ret;
383
384 tt = t.value / 1000;
385#ifdef ctime_r
386 ret = ctime_r (&tt, GNUNET_malloc (32));
387#else
388 ret = GNUNET_strdup (ctime (&tt));
389#endif
390 ret[strlen (ret) - 1] = '\0';
391 return ret;
392}
393
394
395
396/* end of strings.c */
diff --git a/src/util/test_client.c b/src/util/test_client.c
new file mode 100644
index 000000000..5c2e552e9
--- /dev/null
+++ b/src/util/test_client.c
@@ -0,0 +1,195 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_client.c
22 * @brief tests for client.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_client_lib.h"
27#include "gnunet_configuration_lib.h"
28#include "gnunet_scheduler_lib.h"
29#include "gnunet_server_lib.h"
30#include "gnunet_time_lib.h"
31
32#define VERBOSE GNUNET_NO
33
34#define PORT 14325
35
36#define MYNAME "test_client"
37
38static struct GNUNET_CLIENT_Connection *client;
39
40static struct GNUNET_SERVER_Handle *server;
41
42static struct GNUNET_CONFIGURATION_Handle *cfg;
43
44#define MY_TYPE 130
45
46struct CopyContext
47{
48 struct GNUNET_SERVER_Client *client;
49 struct GNUNET_MessageHeader *cpy;
50};
51
52static size_t
53copy_msg (void *cls, size_t size, void *buf)
54{
55 struct CopyContext *ctx = cls;
56 struct GNUNET_MessageHeader *cpy = ctx->cpy;
57
58 GNUNET_assert (sizeof (struct GNUNET_MessageHeader) == ntohs (cpy->size));
59 GNUNET_assert (size >= ntohs (cpy->size));
60 memcpy (buf, cpy, ntohs (cpy->size));
61 GNUNET_SERVER_receive_done (ctx->client, GNUNET_OK);
62 GNUNET_free (cpy);
63 GNUNET_free (ctx);
64 return sizeof (struct GNUNET_MessageHeader);
65}
66
67
68/**
69 * Callback that just bounces the message back to the sender.
70 */
71static void
72echo_cb (void *cls,
73 struct GNUNET_SERVER_Handle *server,
74 struct GNUNET_SERVER_Client *client,
75 const struct GNUNET_MessageHeader *message)
76{
77 struct CopyContext *cc;
78 struct GNUNET_MessageHeader *cpy;
79
80 GNUNET_assert (sizeof (struct GNUNET_MessageHeader) ==
81 ntohs (message->size));
82 cc = GNUNET_malloc (sizeof (struct CopyContext));
83 cc->client = client;
84 cpy = GNUNET_malloc (ntohs (message->size));
85 memcpy (cpy, message, ntohs (message->size));
86 cc->cpy = cpy;
87 GNUNET_assert (NULL !=
88 GNUNET_SERVER_notify_transmit_ready (client,
89 ntohs (message->size),
90 GNUNET_TIME_UNIT_SECONDS,
91 &copy_msg, cc));
92}
93
94
95static struct GNUNET_SERVER_MessageHandler handlers[] = {
96 {&echo_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)},
97 {NULL, NULL, 0, 0}
98};
99
100
101static void
102recv_bounce (void *cls, const struct GNUNET_MessageHeader *got)
103{
104 int *ok = cls;
105 struct GNUNET_MessageHeader msg;
106
107 GNUNET_assert (got != NULL); /* timeout */
108 msg.type = htons (MY_TYPE);
109 msg.size = htons (sizeof (msg));
110 GNUNET_assert (0 == memcmp (got, &msg, sizeof (msg)));
111 GNUNET_CLIENT_disconnect (client);
112 client = NULL;
113 GNUNET_SERVER_destroy (server);
114 server = NULL;
115 *ok = 0;
116}
117
118
119static size_t
120make_msg (void *cls, size_t size, void *buf)
121{
122 struct GNUNET_MessageHeader *msg = buf;
123 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
124 msg->type = htons (MY_TYPE);
125 msg->size = htons (sizeof (msg));
126 return sizeof (struct GNUNET_MessageHeader);
127}
128
129
130static void
131task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
132{
133 struct sockaddr_in sa;
134
135 memset (&sa, 0, sizeof (sa));
136 sa.sin_family = AF_INET;
137 sa.sin_port = htons (PORT);
138 server = GNUNET_SERVER_create (tc->sched,
139 NULL,
140 NULL,
141 (const struct sockaddr *) &sa,
142 sizeof (sa),
143 1024,
144 GNUNET_TIME_relative_multiply
145 (GNUNET_TIME_UNIT_MILLISECONDS, 250),
146 GNUNET_NO);
147 GNUNET_assert (server != NULL);
148 handlers[0].callback_cls = cls;
149 handlers[1].callback_cls = cls;
150 GNUNET_SERVER_add_handlers (server, handlers);
151 client = GNUNET_CLIENT_connect (tc->sched, MYNAME, cfg);
152 GNUNET_assert (client != NULL);
153 GNUNET_assert (NULL !=
154 GNUNET_CLIENT_notify_transmit_ready (client,
155 sizeof (struct
156 GNUNET_MessageHeader),
157 GNUNET_TIME_UNIT_SECONDS,
158 &make_msg, NULL));
159 GNUNET_CLIENT_receive (client, &recv_bounce, cls,
160 GNUNET_TIME_relative_multiply
161 (GNUNET_TIME_UNIT_MILLISECONDS, 250));
162}
163
164
165/**
166 * Main method, starts scheduler with task1,
167 * checks that "ok" is correct at the end.
168 */
169static int
170check ()
171{
172 int ok;
173
174 cfg = GNUNET_CONFIGURATION_create ();
175 GNUNET_CONFIGURATION_set_value_number (cfg, MYNAME, "PORT", PORT);
176 GNUNET_CONFIGURATION_set_value_string (cfg,
177 MYNAME, "HOSTNAME", "localhost");
178 ok = 1;
179 GNUNET_SCHEDULER_run (&task, &ok);
180 GNUNET_CONFIGURATION_destroy (cfg);
181 return ok;
182}
183
184int
185main (int argc, char *argv[])
186{
187 int ret = 0;
188
189 GNUNET_log_setup ("test_client", "WARNING", NULL);
190 ret += check ();
191
192 return ret;
193}
194
195/* end of test_client.c */
diff --git a/src/util/test_common_allocation.c b/src/util/test_common_allocation.c
new file mode 100644
index 000000000..76c7dc8a3
--- /dev/null
+++ b/src/util/test_common_allocation.c
@@ -0,0 +1,112 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2005, 2006 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 2, 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 util/test_common_allocation.c
23 * @brief testcase for common_allocation.c
24 */
25#include "platform.h"
26#include "gnunet_common.h"
27
28static int
29check ()
30{
31#define MAX_TESTVAL 1024
32 char *ptrs[MAX_TESTVAL];
33 int i;
34 int j;
35 int k;
36 unsigned int ui;
37
38 /* GNUNET_malloc/GNUNET_free test */
39 k = 352; /* random start value */
40 for (i = 1; i < MAX_TESTVAL; i++)
41 {
42 ptrs[i] = GNUNET_malloc (i);
43 for (j = 0; j < i; j++)
44 ptrs[i][j] = k++;
45 }
46
47 for (i = MAX_TESTVAL - 1; i >= 1; i--)
48 {
49 for (j = i - 1; j >= 0; j--)
50 if (ptrs[i][j] != (char) --k)
51 return 1;
52 GNUNET_free (ptrs[i]);
53 }
54
55 /* GNUNET_free_non_null test */
56 GNUNET_free_non_null (NULL);
57 GNUNET_free_non_null (GNUNET_malloc (4));
58
59 /* GNUNET_strdup tests */
60 ptrs[0] = GNUNET_strdup ("bar");
61 if (0 != strcmp (ptrs[0], "bar"))
62 return 3;
63 /* now realloc */
64 ptrs[0] = GNUNET_realloc (ptrs[0], 12);
65 strcpy (ptrs[0], "Hello World");
66
67 GNUNET_free (ptrs[0]);
68 GNUNET_asprintf (&ptrs[0], "%s %s", "Hello", "World");
69 GNUNET_assert (strlen (ptrs[0]) == 11);
70 GNUNET_free (ptrs[0]);
71
72 /* GNUNET_array_grow tests */
73 ptrs[0] = NULL;
74 ui = 0;
75 GNUNET_array_grow (ptrs[0], ui, 42);
76 if (ui != 42)
77 return 4;
78 GNUNET_array_grow (ptrs[0], ui, 22);
79 if (ui != 22)
80 return 5;
81 for (j = 0; j < 22; j++)
82 ptrs[0][j] = j;
83 GNUNET_array_grow (ptrs[0], ui, 32);
84 for (j = 0; j < 22; j++)
85 if (ptrs[0][j] != j)
86 return 6;
87 for (j = 22; j < 32; j++)
88 if (ptrs[0][j] != 0)
89 return 7;
90 GNUNET_array_grow (ptrs[0], ui, 0);
91 if (i != 0)
92 return 8;
93 if (ptrs[0] != NULL)
94 return 9;
95
96
97 return 0;
98}
99
100int
101main (int argc, char *argv[])
102{
103 int ret;
104
105 GNUNET_log_setup ("test-common-allocation", "WARNING", NULL);
106 ret = check ();
107 if (ret != 0)
108 fprintf (stderr, "ERROR %d.\n", ret);
109 return ret;
110}
111
112/* end of test_common_allocation.c */
diff --git a/src/util/test_common_endian.c b/src/util/test_common_endian.c
new file mode 100644
index 000000000..43f163902
--- /dev/null
+++ b/src/util/test_common_endian.c
@@ -0,0 +1,42 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_common_endian.c
22 * @brief testcase for common_endian.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26
27#define CHECK(n) if (n != GNUNET_htonll(GNUNET_ntohll(n))) return 1;
28
29int
30main (int argc, char *argv[])
31{
32 GNUNET_log_setup ("test-common-endian", "WARNING", NULL);
33 CHECK (1);
34 CHECK (0x12345678);
35 CHECK (123456789012345LL);
36 if ((0x1234567890ABCDEFLL !=
37 GNUNET_htonll (0xEFCDAB9078563412LL)) && 42 != htonl (42))
38 return 1;
39 return 0;
40}
41
42/* end of test_common_endian.c */
diff --git a/src/util/test_common_logging.c b/src/util/test_common_logging.c
new file mode 100644
index 000000000..eb337aac4
--- /dev/null
+++ b/src/util/test_common_logging.c
@@ -0,0 +1,100 @@
1/*
2 This file is part of GNUnet.
3 (C) 2008 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 2, 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 util/test_common_logging.c
23 * @brief testcase for the logging module
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_common.h"
28
29static void
30my_log (void *ctx, enum GNUNET_ErrorType kind,
31 const char *component, const char *date, const char *msg)
32{
33 unsigned int *c = ctx;
34 (*c)++;
35}
36
37
38
39int
40main (int argc, char *argv[])
41{
42 unsigned int failureCount = 0;
43 unsigned int logs = 0;
44
45 fclose (stderr);
46 stderr = NULL;
47 GNUNET_logger_add (&my_log, &logs);
48 GNUNET_logger_add (&my_log, &logs);
49 GNUNET_log (GNUNET_ERROR_TYPE_BULK, "Testing...\n");
50 GNUNET_log (GNUNET_ERROR_TYPE_BULK, "Testing...\n");
51 GNUNET_log (GNUNET_ERROR_TYPE_BULK, "Testing...\n");
52 GNUNET_log (GNUNET_ERROR_TYPE_BULK, "Testing...\n");
53 GNUNET_log (GNUNET_ERROR_TYPE_BULK, "Testing...\n");
54 GNUNET_log (GNUNET_ERROR_TYPE_BULK, "Testing...\n");
55 GNUNET_logger_remove (&my_log, &logs);
56 GNUNET_log (GNUNET_ERROR_TYPE_BULK, "Flusher...\n");
57 /* the last 6 calls should be merged (repated bulk messages!) */
58 GNUNET_logger_remove (&my_log, &logs);
59 if (logs != 4)
60 {
61 fprintf (stdout, "Expected 4 log calls, got %u\n", logs);
62 failureCount++;
63 }
64 GNUNET_break (0 ==
65 strcmp (_("ERROR"),
66 GNUNET_error_type_to_string
67 (GNUNET_ERROR_TYPE_ERROR)));
68 GNUNET_break (0 ==
69 strcmp (_("WARNING"),
70 GNUNET_error_type_to_string
71 (GNUNET_ERROR_TYPE_WARNING)));
72 GNUNET_break (0 ==
73 strcmp (_("INFO"),
74 GNUNET_error_type_to_string
75 (GNUNET_ERROR_TYPE_INFO)));
76 GNUNET_break (0 ==
77 strcmp (_("DEBUG"),
78 GNUNET_error_type_to_string
79 (GNUNET_ERROR_TYPE_DEBUG)));
80 GNUNET_log_setup ("test_common_logging", "WARNING", "/dev/null");
81 logs = 0;
82 GNUNET_logger_add (&my_log, &logs);
83 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Checker...\n");
84 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Drop me...\n");
85 GNUNET_logger_remove (&my_log, &logs);
86 if (logs != 1)
87 {
88 fprintf (stdout, "Expected 1 log call, got %u\n", logs);
89 failureCount++;
90 }
91
92 if (failureCount != 0)
93 {
94 fprintf (stdout, "%u TESTS FAILED!\n", failureCount);
95 return -1;
96 }
97 return 0;
98} /* end of main */
99
100/* end of test_common_logging.c */
diff --git a/src/util/test_configuration.c b/src/util/test_configuration.c
new file mode 100644
index 000000000..2f37c684c
--- /dev/null
+++ b/src/util/test_configuration.c
@@ -0,0 +1,229 @@
1/*
2 This file is part of GNUnet.
3 (C) 2003, 2004, 2005, 2006, 2007 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 2, 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 util/test_configuration.c
22 * @brief Test that the configuration module works.
23 * @author Christian Grothoff
24 */
25
26#include "platform.h"
27#include "gnunet_common.h"
28#include "gnunet_configuration_lib.h"
29
30static struct GNUNET_CONFIGURATION_Handle *cfg;
31
32static int
33testConfig ()
34{
35 char *c;
36 unsigned long long l;
37
38 if (GNUNET_OK !=
39 GNUNET_CONFIGURATION_get_value_string (cfg, "test", "b", &c))
40 return 1;
41 if (0 != strcmp ("b", c))
42 {
43 fprintf (stderr, "Got `%s'\n", c);
44 GNUNET_free (c);
45 return 2;
46 }
47 GNUNET_free (c);
48 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
49 "test", "five", &l))
50 return 3;
51 if (5 != l)
52 return 4;
53 GNUNET_CONFIGURATION_set_value_string (cfg, "more", "c", "YES");
54 if (GNUNET_NO == GNUNET_CONFIGURATION_get_value_yesno (cfg, "more", "c"))
55 return 5;
56 GNUNET_CONFIGURATION_set_value_number (cfg, "NUMBERS", "TEN", 10);
57 if (GNUNET_OK !=
58 GNUNET_CONFIGURATION_get_value_string (cfg, "NUMBERS", "TEN", &c))
59 return 6;
60 if (0 != strcmp (c, "10"))
61 {
62 GNUNET_free (c);
63 return 7;
64 }
65 GNUNET_free (c);
66
67 if (GNUNET_OK !=
68 GNUNET_CONFIGURATION_get_value_filename (cfg, "last", "test", &c))
69 return 8;
70 if (0 != strcmp (c, "/hello/world"))
71 {
72 GNUNET_free (c);
73 return 9;
74 }
75 GNUNET_free (c);
76
77 return 0;
78}
79
80static const char *want[] = {
81 "/Hello",
82 "/File Name",
83 "/World",
84 NULL,
85 NULL,
86};
87
88static int
89check (void *data, const char *fn)
90{
91 int *idx = data;
92
93 if (0 == strcmp (want[*idx], fn))
94 {
95 (*idx)++;
96 return GNUNET_OK;
97 }
98 return GNUNET_SYSERR;
99}
100
101static int
102testConfigFilenames ()
103{
104 int idx;
105
106 idx = 0;
107 if (3 != GNUNET_CONFIGURATION_iterate_value_filenames (cfg,
108 "FILENAMES",
109 "test",
110 &check, &idx))
111 return 8;
112 if (idx != 3)
113 return 16;
114 if (GNUNET_OK !=
115 GNUNET_CONFIGURATION_remove_value_filename (cfg,
116 "FILENAMES",
117 "test", "/File Name"))
118 return 24;
119
120 if (GNUNET_NO !=
121 GNUNET_CONFIGURATION_remove_value_filename (cfg,
122 "FILENAMES",
123 "test", "/File Name"))
124 return 32;
125 if (GNUNET_NO !=
126 GNUNET_CONFIGURATION_remove_value_filename (cfg,
127 "FILENAMES",
128 "test", "Stuff"))
129 return 40;
130
131 if (GNUNET_NO !=
132 GNUNET_CONFIGURATION_append_value_filename (cfg,
133 "FILENAMES",
134 "test", "/Hello"))
135 return 48;
136 if (GNUNET_NO !=
137 GNUNET_CONFIGURATION_append_value_filename (cfg,
138 "FILENAMES",
139 "test", "/World"))
140 return 56;
141
142 if (GNUNET_YES !=
143 GNUNET_CONFIGURATION_append_value_filename (cfg,
144 "FILENAMES",
145 "test", "/File 1"))
146 return 64;
147
148 if (GNUNET_YES !=
149 GNUNET_CONFIGURATION_append_value_filename (cfg,
150 "FILENAMES",
151 "test", "/File 2"))
152 return 72;
153
154 idx = 0;
155 want[1] = "/World";
156 want[2] = "/File 1";
157 want[3] = "/File 2";
158 if (4 != GNUNET_CONFIGURATION_iterate_value_filenames (cfg,
159 "FILENAMES",
160 "test",
161 &check, &idx))
162 return 80;
163 if (idx != 4)
164 return 88;
165 return 0;
166}
167
168int
169main (int argc, char *argv[])
170{
171 int failureCount = 0;
172 char *c;
173
174 GNUNET_log_setup ("test_configuration", "WARNING", NULL);
175 cfg = GNUNET_CONFIGURATION_create ();
176 GNUNET_assert (cfg != NULL);
177 if (GNUNET_OK !=
178 GNUNET_CONFIGURATION_parse (cfg, "test_configuration_data.conf"))
179 {
180 fprintf (stderr, "Failed to parse configuration file\n");
181 GNUNET_CONFIGURATION_destroy (cfg);
182 return 1;
183 }
184 failureCount += testConfig ();
185 failureCount += 2 * testConfigFilenames ();
186
187 if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, "/tmp/gnunet-test.conf"))
188 {
189 fprintf (stderr, "Failed to write configuration file\n");
190 GNUNET_CONFIGURATION_destroy (cfg);
191 return 1;
192 }
193 GNUNET_CONFIGURATION_destroy (cfg);
194 GNUNET_assert (0 == UNLINK ("/tmp/gnunet-test.conf"));
195
196 cfg = GNUNET_CONFIGURATION_create ();
197 if (GNUNET_OK !=
198 GNUNET_CONFIGURATION_load (cfg, "test_configuration_data.conf"))
199 {
200 GNUNET_break (0);
201 GNUNET_CONFIGURATION_destroy (cfg);
202 return 1;
203 }
204 if ((GNUNET_OK !=
205 GNUNET_CONFIGURATION_get_value_string (cfg, "TESTING", "WEAKRANDOM",
206 &c))
207 || (0 != strcmp (c, "YES")))
208 {
209 GNUNET_CONFIGURATION_destroy (cfg);
210 return 1;
211 }
212 GNUNET_free (c);
213 if ((GNUNET_OK !=
214 GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", "SERVICEHOME",
215 &c))
216 || (0 != strcmp (c, "/var/lib/gnunet/")))
217 {
218 GNUNET_CONFIGURATION_destroy (cfg);
219 return 1;
220 }
221 GNUNET_free (c);
222 GNUNET_CONFIGURATION_destroy (cfg);
223 if (failureCount != 0)
224 {
225 fprintf (stderr, "Test failed: %u\n", failureCount);
226 return 1;
227 }
228 return 0;
229}
diff --git a/src/util/test_configuration_data.conf b/src/util/test_configuration_data.conf
new file mode 100644
index 000000000..52b6b8220
--- /dev/null
+++ b/src/util/test_configuration_data.conf
@@ -0,0 +1,30 @@
1[PATHS]
2SUBST=/hello
3
4[GNUNET]
5SUBST=hello
6GNUNET_HOME=/tmp
7
8[test]
9a=a
10b=b
11five=5
12
13[more]
14c=c
15five=42
16
17
18[last]
19test = $SUBST/world
20boom = "1 2 3 testing"
21trailing = YES
22
23[FILENAMES]
24test = "/Hello /File\ Name /World"
25
26
27[TESTING]
28WEAKRANDOM = YES
29
30
diff --git a/src/util/test_container_bloomfilter.c b/src/util/test_container_bloomfilter.c
new file mode 100644
index 000000000..9beb11298
--- /dev/null
+++ b/src/util/test_container_bloomfilter.c
@@ -0,0 +1,246 @@
1/*
2 This file is part of GNUnet.
3 (C) 2004, 2009 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 2, 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 util/test_container_bloomfilter.c
22 * @brief Testcase for the bloomfilter.
23 * @author Christian Grothoff
24 * @author Igor Wronsky
25 */
26
27#include "platform.h"
28#include "gnunet_common.h"
29#include "gnunet_container_lib.h"
30
31#define K 4
32#define SIZE 65536
33#define TESTFILE "/tmp/bloomtest.dat"
34
35/**
36 * Generate a random hashcode.
37 */
38static void
39nextHC (GNUNET_HashCode * hc)
40{
41 GNUNET_CRYPTO_hash_create_random (hc);
42}
43
44static int
45add_iterator (GNUNET_HashCode * next, void *arg)
46{
47 int *ret = arg;
48 GNUNET_HashCode pos;
49
50 if (0 == (*ret)--)
51 return GNUNET_NO;
52 nextHC (&pos);
53 *next = pos;
54 return GNUNET_YES;
55}
56
57int
58main (int argc, char *argv[])
59{
60 struct GNUNET_CONTAINER_BloomFilter *bf;
61 struct GNUNET_CONTAINER_BloomFilter *bfi;
62 GNUNET_HashCode tmp;
63 int i;
64 int ok1;
65 int ok2;
66 int falseok;
67 char buf[SIZE];
68 struct stat sbuf;
69
70 GNUNET_log_setup ("test-container-bloomfilter", "WARNING", NULL);
71 srand (1);
72 if (0 == stat (TESTFILE, &sbuf))
73 if (0 != UNLINK (TESTFILE))
74 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "unlink", TESTFILE);
75 bf = GNUNET_CONTAINER_bloomfilter_load (TESTFILE, SIZE, K);
76
77 for (i = 0; i < 200; i++)
78 {
79 nextHC (&tmp);
80 GNUNET_CONTAINER_bloomfilter_add (bf, &tmp);
81 }
82 srand (1);
83 ok1 = 0;
84 for (i = 0; i < 200; i++)
85 {
86 nextHC (&tmp);
87 if (GNUNET_CONTAINER_bloomfilter_test (bf, &tmp) == GNUNET_YES)
88 ok1++;
89 }
90 if (ok1 != 200)
91 {
92 printf ("Got %d elements out of"
93 "200 expected after insertion.\n", ok1);
94 GNUNET_CONTAINER_bloomfilter_free (bf);
95 return -1;
96 }
97 if (GNUNET_OK != GNUNET_CONTAINER_bloomfilter_get_raw_data (bf, buf, SIZE))
98 {
99 GNUNET_CONTAINER_bloomfilter_free (bf);
100 return -1;
101 }
102
103 GNUNET_CONTAINER_bloomfilter_free (bf);
104
105 bf = GNUNET_CONTAINER_bloomfilter_load (TESTFILE, SIZE, K);
106 GNUNET_assert (bf != NULL);
107 bfi = GNUNET_CONTAINER_bloomfilter_init (buf, SIZE, K);
108 GNUNET_assert (bfi != NULL);
109
110 srand (1);
111 ok1 = 0;
112 ok2 = 0;
113 for (i = 0; i < 200; i++)
114 {
115 nextHC (&tmp);
116 if (GNUNET_CONTAINER_bloomfilter_test (bf, &tmp) == GNUNET_YES)
117 ok1++;
118 if (GNUNET_CONTAINER_bloomfilter_test (bfi, &tmp) == GNUNET_YES)
119 ok2++;
120 }
121 if (ok1 != 200)
122 {
123 printf ("Got %d elements out of 200 "
124 "expected after reloading.\n", ok1);
125 GNUNET_CONTAINER_bloomfilter_free (bf);
126 GNUNET_CONTAINER_bloomfilter_free (bfi);
127 return -1;
128 }
129
130 if (ok2 != 200)
131 {
132 printf ("Got %d elements out of 200 "
133 "expected after initialization.\n", ok2);
134 GNUNET_CONTAINER_bloomfilter_free (bf);
135 GNUNET_CONTAINER_bloomfilter_free (bfi);
136 return -1;
137 }
138
139 srand (1);
140 for (i = 0; i < 100; i++)
141 {
142 nextHC (&tmp);
143 GNUNET_CONTAINER_bloomfilter_remove (bf, &tmp);
144 GNUNET_CONTAINER_bloomfilter_remove (bfi, &tmp);
145 }
146
147 srand (1);
148
149 ok1 = 0;
150 ok2 = 0;
151 for (i = 0; i < 200; i++)
152 {
153 nextHC (&tmp);
154 if (GNUNET_CONTAINER_bloomfilter_test (bf, &tmp) == GNUNET_YES)
155 ok1++;
156 if (GNUNET_CONTAINER_bloomfilter_test (bfi, &tmp) == GNUNET_YES)
157 ok2++;
158 }
159
160 if (ok1 != 100)
161 {
162 printf ("Expected 100 elements in loaded filter"
163 " after adding 200 and deleting 100, got %d\n", ok1);
164 GNUNET_CONTAINER_bloomfilter_free (bf);
165 GNUNET_CONTAINER_bloomfilter_free (bfi);
166 return -1;
167 }
168 if (ok2 != 200)
169 {
170 printf ("Expected 200 elements in initialized filter"
171 " after adding 200 and deleting 100 "
172 "(which should do nothing for a filter not backed by a file), got %d\n",
173 ok2);
174 GNUNET_CONTAINER_bloomfilter_free (bf);
175 GNUNET_CONTAINER_bloomfilter_free (bfi);
176 return -1;
177 }
178
179 srand (3);
180
181 GNUNET_CONTAINER_bloomfilter_clear (bf);
182 falseok = 0;
183 for (i = 0; i < 1000; i++)
184 {
185 nextHC (&tmp);
186 if (GNUNET_CONTAINER_bloomfilter_test (bf, &tmp) == GNUNET_YES)
187 falseok++;
188 }
189 if (falseok > 0)
190 {
191 GNUNET_CONTAINER_bloomfilter_free (bf);
192 GNUNET_CONTAINER_bloomfilter_free (bfi);
193 return -1;
194 }
195
196 if (GNUNET_OK != GNUNET_CONTAINER_bloomfilter_or (bf, buf, SIZE))
197 {
198 GNUNET_CONTAINER_bloomfilter_free (bf);
199 GNUNET_CONTAINER_bloomfilter_free (bfi);
200 return -1;
201 }
202
203 srand (2);
204 i = 20;
205 GNUNET_CONTAINER_bloomfilter_resize (bfi, &add_iterator, &i, SIZE * 2, K);
206
207 srand (2);
208 i = 20;
209 GNUNET_CONTAINER_bloomfilter_resize (bf, &add_iterator, &i, SIZE * 2, K);
210 srand (2);
211
212 ok1 = 0;
213 ok2 = 0;
214 for (i = 0; i < 20; i++)
215 {
216 nextHC (&tmp);
217 if (GNUNET_CONTAINER_bloomfilter_test (bf, &tmp) == GNUNET_YES)
218 ok1++;
219 if (GNUNET_CONTAINER_bloomfilter_test (bfi, &tmp) == GNUNET_YES)
220 ok2++;
221 }
222
223 if (ok1 != 20)
224 {
225 printf ("Expected 20 elements in resized file-backed filter"
226 " after adding 20, got %d\n", ok1);
227 GNUNET_CONTAINER_bloomfilter_free (bf);
228 GNUNET_CONTAINER_bloomfilter_free (bfi);
229 return -1;
230 }
231 if (ok2 != 20)
232 {
233 printf ("Expected 20 elements in resized filter"
234 " after adding 20, got %d\n", ok2);
235 GNUNET_CONTAINER_bloomfilter_free (bf);
236 GNUNET_CONTAINER_bloomfilter_free (bfi);
237 return -1;
238 }
239
240
241 GNUNET_CONTAINER_bloomfilter_free (bf);
242 GNUNET_CONTAINER_bloomfilter_free (bfi);
243
244 GNUNET_break (0 == UNLINK (TESTFILE));
245 return 0;
246}
diff --git a/src/util/test_container_heap.c b/src/util/test_container_heap.c
new file mode 100644
index 000000000..511589af5
--- /dev/null
+++ b/src/util/test_container_heap.c
@@ -0,0 +1,112 @@
1/*
2 This file is part of GNUnet.
3 (C) 2008 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 2, 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 * @author Nathan Evans
23 * @file util/containers/heaptest.c
24 * @brief Test of heap operations
25 */
26
27#include "gnunet_util.h"
28#include "gnunet_util_containers.h"
29#include "dv.h"
30
31static int
32iterator_callback (void *element, GNUNET_CONTAINER_HeapCost cost,
33 struct GNUNET_CONTAINER_Heap *root, void *cls)
34{
35 struct GNUNET_dv_neighbor *node;
36 node = (struct GNUNET_dv_neighbor *) element;
37 fprintf (stdout, "%d\n", node->cost);
38 //fprintf (stdout, "%d\n", ((struct GNUNET_dv_neighbor *)element)->cost);
39
40 return GNUNET_OK;
41}
42
43
44int
45main (int argc, char **argv)
46{
47 struct GNUNET_CONTAINER_Heap *myHeap;
48 struct GNUNET_dv_neighbor *neighbor1;
49 struct GNUNET_dv_neighbor *neighbor2;
50 struct GNUNET_dv_neighbor *neighbor3;
51 struct GNUNET_dv_neighbor *neighbor4;
52 struct GNUNET_dv_neighbor *neighbor5;
53 struct GNUNET_dv_neighbor *neighbor6;
54
55 GNUNET_log_setup ("test-container-heap", "WARNING", NULL);
56
57 myHeap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MAX);
58
59 neighbor1 = malloc (sizeof (struct GNUNET_dv_neighbor));
60 neighbor2 = malloc (sizeof (struct GNUNET_dv_neighbor));
61 neighbor3 = malloc (sizeof (struct GNUNET_dv_neighbor));
62 neighbor4 = malloc (sizeof (struct GNUNET_dv_neighbor));
63 neighbor5 = malloc (sizeof (struct GNUNET_dv_neighbor));
64 neighbor6 = malloc (sizeof (struct GNUNET_dv_neighbor));
65
66 neighbor1->cost = 60;
67 neighbor2->cost = 50;
68 neighbor3->cost = 70;
69 neighbor4->cost = 120;
70 neighbor5->cost = 100;
71 neighbor6->cost = 30;
72
73 GNUNET_CONTAINER_heap_insert (myHeap, neighbor1, neighbor1->cost);
74 GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
75
76 fprintf (stdout, "\n");
77 GNUNET_CONTAINER_heap_insert (myHeap, neighbor2, neighbor2->cost);
78
79 GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
80 fprintf (stdout, "\n");
81 GNUNET_CONTAINER_heap_insert (myHeap, neighbor3, neighbor3->cost);
82
83 GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
84 fprintf (stdout, "\n");
85 GNUNET_CONTAINER_heap_insert (myHeap, neighbor4, neighbor4->cost);
86
87 GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
88 fprintf (stdout, "\n");
89 GNUNET_CONTAINER_heap_insert (myHeap, neighbor5, neighbor5->cost);
90
91 GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
92 fprintf (stdout, "\n");
93 GNUNET_CONTAINER_heap_insert (myHeap, neighbor6, neighbor6->cost);
94
95 GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
96 fprintf (stdout, "\n");
97 GNUNET_CONTAINER_heap_remove_node (myHeap, neighbor5);
98
99 GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
100 fprintf (stdout, "\n");
101 GNUNET_CONTAINER_heap_remove_root (myHeap);
102
103 GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
104 fprintf (stdout, "\n");
105 GNUNET_CONTAINER_heap_update_cost (myHeap, neighbor6, 200);
106
107 GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
108 fprintf (stdout, "\n");
109 return 0;
110}
111
112/* end of heaptest.c */
diff --git a/src/util/test_container_meta_data.c b/src/util/test_container_meta_data.c
new file mode 100644
index 000000000..17ef79161
--- /dev/null
+++ b/src/util/test_container_meta_data.c
@@ -0,0 +1,262 @@
1/*
2 This file is part of GNUnet.
3 (C) 2003, 2004, 2006, 2009 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 2, 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 util/test_container_meta_data.c
23 * @brief Test for container_meta_data.c
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_common.h"
29#include "gnunet_container_lib.h"
30
31#define ABORT(m) { fprintf(stderr, "Error at %s:%d\n", __FILE__, __LINE__); if (m != NULL) GNUNET_CONTAINER_meta_data_destroy(m); return 1; }
32
33static int
34testMeta (int i)
35{
36 struct GNUNET_CONTAINER_MetaData *m;
37 char *val;
38 int j;
39 unsigned int size;
40
41 m = GNUNET_CONTAINER_meta_data_create ();
42 if (GNUNET_OK !=
43 GNUNET_CONTAINER_meta_data_insert (m, EXTRACTOR_TITLE, "TestTitle"))
44 ABORT (m);
45 if (GNUNET_OK !=
46 GNUNET_CONTAINER_meta_data_insert (m, EXTRACTOR_AUTHOR, "TestTitle"))
47 ABORT (m);
48 if (GNUNET_OK == GNUNET_CONTAINER_meta_data_insert (m, EXTRACTOR_TITLE, "TestTitle")) /* dup! */
49 ABORT (m);
50 if (GNUNET_OK == GNUNET_CONTAINER_meta_data_insert (m, EXTRACTOR_AUTHOR, "TestTitle")) /* dup! */
51 ABORT (m);
52 if (2 != GNUNET_CONTAINER_meta_data_get_contents (m, NULL, NULL))
53 ABORT (m);
54 if (GNUNET_OK !=
55 GNUNET_CONTAINER_meta_data_delete (m, EXTRACTOR_AUTHOR, "TestTitle"))
56 ABORT (m);
57 if (GNUNET_OK == GNUNET_CONTAINER_meta_data_delete (m, EXTRACTOR_AUTHOR, "TestTitle")) /* already gone */
58 ABORT (m);
59 if (1 != GNUNET_CONTAINER_meta_data_get_contents (m, NULL, NULL))
60 ABORT (m);
61 if (GNUNET_OK !=
62 GNUNET_CONTAINER_meta_data_delete (m, EXTRACTOR_TITLE, "TestTitle"))
63 ABORT (m);
64 if (GNUNET_OK == GNUNET_CONTAINER_meta_data_delete (m, EXTRACTOR_TITLE, "TestTitle")) /* already gone */
65 ABORT (m);
66 if (0 != GNUNET_CONTAINER_meta_data_get_contents (m, NULL, NULL))
67 ABORT (m);
68 val = GNUNET_malloc (256);
69 for (j = 0; j < i; j++)
70 {
71 GNUNET_snprintf (val, 256, "%s.%d",
72 "A teststring that should compress well.", j);
73 if (GNUNET_OK !=
74 GNUNET_CONTAINER_meta_data_insert (m, EXTRACTOR_UNKNOWN, val))
75 {
76 GNUNET_free (val);
77 ABORT (m);
78 }
79 }
80 GNUNET_free (val);
81 if (i != GNUNET_CONTAINER_meta_data_get_contents (m, NULL, NULL))
82 ABORT (m);
83
84 size =
85 GNUNET_CONTAINER_meta_data_get_serialized_size (m,
86 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);
87 val = GNUNET_malloc (size);
88 if (size != GNUNET_CONTAINER_meta_data_serialize (m, val, size,
89 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL))
90 {
91 GNUNET_free (val);
92 ABORT (m);
93 }
94 GNUNET_CONTAINER_meta_data_destroy (m);
95 m = GNUNET_CONTAINER_meta_data_deserialize (val, size);
96 GNUNET_free (val);
97 if (m == NULL)
98 ABORT (m);
99 val = GNUNET_malloc (256);
100 for (j = 0; j < i; j++)
101 {
102 GNUNET_snprintf (val, 256, "%s.%d",
103 "A teststring that should compress well.", j);
104 if (GNUNET_OK !=
105 GNUNET_CONTAINER_meta_data_delete (m, EXTRACTOR_UNKNOWN, val))
106 {
107 GNUNET_free (val);
108 ABORT (m);
109 }
110 }
111 GNUNET_free (val);
112 if (0 != GNUNET_CONTAINER_meta_data_get_contents (m, NULL, NULL))
113 {
114 ABORT (m);
115 }
116 GNUNET_CONTAINER_meta_data_destroy (m);
117 return 0;
118}
119
120int
121testMetaMore (int i)
122{
123 struct GNUNET_CONTAINER_MetaData *meta;
124 int q;
125 char txt[128];
126 char *data;
127 unsigned long long size;
128
129 meta = GNUNET_CONTAINER_meta_data_create ();
130 for (q = 0; q <= i; q++)
131 {
132 GNUNET_snprintf (txt, 128, "%u -- %u\n", i, q);
133 GNUNET_CONTAINER_meta_data_insert (meta,
134 q %
135 EXTRACTOR_getHighestKeywordTypeNumber
136 (), txt);
137 }
138 size =
139 GNUNET_CONTAINER_meta_data_get_serialized_size (meta,
140 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);
141 data = GNUNET_malloc (size * 4);
142 if (size != GNUNET_CONTAINER_meta_data_serialize (meta,
143 data, size * 4,
144 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL))
145 {
146 GNUNET_free (data);
147 ABORT (meta);
148 }
149 GNUNET_CONTAINER_meta_data_destroy (meta);
150 GNUNET_free (data);
151 return 0;
152}
153
154static int
155testMetaLink ()
156{
157 struct GNUNET_CONTAINER_MetaData *m;
158 char *val;
159 unsigned int size;
160
161 m = GNUNET_CONTAINER_meta_data_create ();
162 if (GNUNET_OK !=
163 GNUNET_CONTAINER_meta_data_insert (m, EXTRACTOR_UNKNOWN, "link"))
164 ABORT (m);
165 if (GNUNET_OK !=
166 GNUNET_CONTAINER_meta_data_insert (m, EXTRACTOR_FILENAME,
167 "lib-link.m4"))
168 ABORT (m);
169 size =
170 GNUNET_CONTAINER_meta_data_get_serialized_size (m,
171 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);
172 val = GNUNET_malloc (size);
173 if (size != GNUNET_CONTAINER_meta_data_serialize (m, val, size,
174 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL))
175 {
176 GNUNET_free (val);
177 ABORT (m);
178 }
179 GNUNET_CONTAINER_meta_data_destroy (m);
180 m = GNUNET_CONTAINER_meta_data_deserialize (val, size);
181 GNUNET_free (val);
182 if (m == NULL)
183 ABORT (m);
184 GNUNET_CONTAINER_meta_data_destroy (m);
185 return 0;
186}
187
188
189static int
190testThumbnail ()
191{
192 struct GNUNET_CONTAINER_MetaData *m;
193 struct GNUNET_CONTAINER_MetaData *d;
194 EXTRACTOR_ExtractorList *ex;
195 unsigned char *thumb;
196 size_t size;
197 char *date;
198
199 ex = EXTRACTOR_loadConfigLibraries (NULL, "libextractor_thumbnail");
200 if (ex == NULL)
201 {
202 fprintf (stderr,
203 "Test incomplete, have no thumbnail extractor available.\n");
204 return 0; /* can not test, no thumbnailer */
205 }
206 ex = EXTRACTOR_loadConfigLibraries (ex, "libextractor_mime");
207 m = GNUNET_CONTAINER_meta_data_create ();
208 if (3 != GNUNET_CONTAINER_meta_data_extract_from_file (m,
209 "test_container_meta_data_image.jpg",
210 ex))
211 {
212 GNUNET_break (0);
213 EXTRACTOR_removeAll (ex);
214 GNUNET_CONTAINER_meta_data_destroy (m);
215 return 1;
216 }
217 EXTRACTOR_removeAll (ex);
218 d = GNUNET_CONTAINER_meta_data_duplicate (m);
219 GNUNET_CONTAINER_meta_data_destroy (m);
220 size = GNUNET_CONTAINER_meta_data_get_thumbnail (d, &thumb);
221 if (size == 0)
222 {
223 GNUNET_break (0);
224 GNUNET_CONTAINER_meta_data_destroy (d);
225 return 1;
226 }
227 GNUNET_free (thumb);
228 GNUNET_CONTAINER_meta_data_add_publication_date (d);
229 date = GNUNET_CONTAINER_meta_data_get_by_type (d,
230 EXTRACTOR_PUBLICATION_DATE);
231 if (date == NULL)
232 {
233 GNUNET_break (0);
234 GNUNET_CONTAINER_meta_data_destroy (d);
235 return 1;
236 }
237 GNUNET_free (date);
238 GNUNET_CONTAINER_meta_data_destroy (d);
239 return 0;
240}
241
242
243int
244main (int argc, char *argv[])
245{
246 int failureCount = 0;
247 int i;
248
249 GNUNET_log_setup ("test-container-meta-data", "WARNING", NULL);
250 for (i = 0; i < 255; i++)
251 failureCount += testMeta (i);
252 for (i = 1; i < 255; i++)
253 failureCount += testMetaMore (i);
254 failureCount += testMetaLink ();
255 failureCount += testThumbnail ();
256
257 if (failureCount != 0)
258 return 1;
259 return 0;
260}
261
262/* end of metatest.c */
diff --git a/src/util/test_container_meta_data_image.jpg b/src/util/test_container_meta_data_image.jpg
new file mode 100644
index 000000000..3d1ba3307
--- /dev/null
+++ b/src/util/test_container_meta_data_image.jpg
Binary files differ
diff --git a/src/util/test_container_multihashmap.c b/src/util/test_container_multihashmap.c
new file mode 100644
index 000000000..e92ab49ba
--- /dev/null
+++ b/src/util/test_container_multihashmap.c
@@ -0,0 +1,113 @@
1/*
2 This file is part of GNUnet.
3 (C) 2008 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 2, 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 util/test_container_multihashmap.c
23 * @brief Test for container_multihashmap.c
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_common.h"
29#include "gnunet_container_lib.h"
30
31#define ABORT() { fprintf(stderr, "Error at %s:%d\n", __FILE__, __LINE__); if (m != NULL) GNUNET_CONTAINER_multihashmap_destroy(m); return 1; }
32#define CHECK(c) { if (! (c)) ABORT(); }
33
34static int
35testMap (int i)
36{
37 struct GNUNET_CONTAINER_MultiHashMap *m;
38 GNUNET_HashCode k1;
39 GNUNET_HashCode k2;
40 int j;
41 void *r;
42
43 CHECK (NULL != (m = GNUNET_CONTAINER_multihashmap_create (i)));
44 memset (&k1, 0, sizeof (k1));
45 memset (&k2, 1, sizeof (k2));
46 CHECK (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (m, &k1));
47 CHECK (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (m, &k2));
48 CHECK (GNUNET_NO == GNUNET_CONTAINER_multihashmap_remove (m, &k1, NULL));
49 CHECK (GNUNET_NO == GNUNET_CONTAINER_multihashmap_remove (m, &k2, NULL));
50 CHECK (NULL == GNUNET_CONTAINER_multihashmap_get (m, &k1));
51 CHECK (NULL == GNUNET_CONTAINER_multihashmap_get (m, &k2));
52 CHECK (0 == GNUNET_CONTAINER_multihashmap_remove_all (m, &k1));
53 CHECK (0 == GNUNET_CONTAINER_multihashmap_size (m));
54 CHECK (0 == GNUNET_CONTAINER_multihashmap_iterate (m, NULL, NULL));
55 CHECK (0 ==
56 GNUNET_CONTAINER_multihashmap_get_multiple (m, &k1, NULL, NULL));
57
58 CHECK (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (m,
59 &k1,
60 "v1",
61 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE));
62 CHECK (1 == GNUNET_CONTAINER_multihashmap_size (m));
63 CHECK (0 == strcmp ("v1", GNUNET_CONTAINER_multihashmap_get (m, &k1)));
64 CHECK (GNUNET_NO == GNUNET_CONTAINER_multihashmap_put (m,
65 &k1,
66 "v1",
67 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE));
68 CHECK (1 == GNUNET_CONTAINER_multihashmap_size (m));
69 CHECK (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (m,
70 &k1,
71 "v2",
72 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
73 CHECK (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (m,
74 &k1,
75 "v3",
76 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
77 CHECK (3 == GNUNET_CONTAINER_multihashmap_size (m));
78 CHECK (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (m, &k1, "v3"));
79 CHECK (2 == GNUNET_CONTAINER_multihashmap_size (m));
80 CHECK (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (m, &k1));
81 CHECK (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (m, &k2));
82 CHECK (2 ==
83 GNUNET_CONTAINER_multihashmap_get_multiple (m, &k1, NULL, NULL));
84 CHECK (0 ==
85 GNUNET_CONTAINER_multihashmap_get_multiple (m, &k2, NULL, NULL));
86 CHECK (2 == GNUNET_CONTAINER_multihashmap_iterate (m, NULL, NULL));
87 r = GNUNET_CONTAINER_multihashmap_get_random (m);
88 CHECK (0 == strcmp (r, "v1") || 0 == strcmp (r, "v2"));
89 CHECK (2 == GNUNET_CONTAINER_multihashmap_remove_all (m, &k1));
90 for (j = 0; j < 1024; j++)
91 CHECK (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (m,
92 &k1,
93 "v2",
94 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
95 GNUNET_CONTAINER_multihashmap_destroy (m);
96 return 0;
97}
98
99int
100main (int argc, char *argv[])
101{
102 int failureCount = 0;
103 int i;
104
105 GNUNET_log_setup ("test-container-multihashmap", "WARNING", NULL);
106 for (i = 1; i < 255; i++)
107 failureCount += testMap (i);
108 if (failureCount != 0)
109 return 1;
110 return 0;
111}
112
113/* end of maptest.c */
diff --git a/src/util/test_crypto_aes.c b/src/util/test_crypto_aes.c
new file mode 100644
index 000000000..cdae243e0
--- /dev/null
+++ b/src/util/test_crypto_aes.c
@@ -0,0 +1,180 @@
1/*
2 This file is part of GNUnet.
3 (C) 2002, 2003, 2004, 2006 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 2, 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 * @author Christian Grothoff
23 * @file util/test_crypto_aes.c
24 * @brief test for AES ciphers
25 */
26#include "platform.h"
27#include "gnunet_common.h"
28#include "gnunet_crypto_lib.h"
29
30#define TESTSTRING "Hello World!"
31#define INITVALUE "InitializationVectorValue"
32
33static int
34testSymcipher ()
35{
36 struct GNUNET_CRYPTO_AesSessionKey key;
37 char result[100];
38 int size;
39 char res[100];
40
41 GNUNET_CRYPTO_aes_create_session_key (&key);
42 size = GNUNET_CRYPTO_aes_encrypt (TESTSTRING,
43 strlen (TESTSTRING) + 1,
44 &key,
45 (const struct
46 GNUNET_CRYPTO_AesInitializationVector *)
47 INITVALUE, result);
48 if (size == -1)
49 {
50 printf ("symciphertest failed: encryptBlock returned %d\n", size);
51 return 1;
52 }
53 size = GNUNET_CRYPTO_aes_decrypt (&key,
54 result, size,
55 (const struct
56 GNUNET_CRYPTO_AesInitializationVector *)
57 INITVALUE, res);
58 if (strlen (TESTSTRING) + 1 != size)
59 {
60 printf ("symciphertest failed: decryptBlock returned %d\n", size);
61 return 1;
62 }
63 if (0 != strcmp (res, TESTSTRING))
64 {
65 printf ("symciphertest failed: %s != %s\n", res, TESTSTRING);
66 return 1;
67 }
68 else
69 return 0;
70}
71
72int
73verifyCrypto ()
74{
75 struct GNUNET_CRYPTO_AesSessionKey key;
76 char result[GNUNET_CRYPTO_AES_KEY_LENGTH];
77 char *res;
78 int ret;
79
80 unsigned char plain[] =
81 { 29, 128, 192, 253, 74, 171, 38, 187, 84, 219, 76, 76, 209, 118, 33, 249,
82 172, 124, 96, 9, 157, 110, 8, 215, 200, 63, 69, 230, 157, 104, 247, 164
83 };
84 unsigned char raw_key[] =
85 { 106, 74, 209, 88, 145, 55, 189, 135, 125, 180, 225, 108, 183, 54, 25,
86 169, 129, 188, 131, 75, 227, 245, 105, 10, 225, 15, 115, 159, 148, 184,
87 34, 191
88 };
89 unsigned char encrresult[] =
90 { 167, 102, 230, 233, 127, 195, 176, 107, 17, 91, 199, 127, 96, 113, 75,
91 195, 245, 217, 61, 236, 159, 165, 103, 121, 203, 99, 202, 41, 23, 222, 25,
92 102, 1
93 };
94
95 res = NULL;
96 ret = 0;
97
98 memcpy (key.key, raw_key, GNUNET_CRYPTO_AES_KEY_LENGTH);
99 key.crc32 =
100 htonl (GNUNET_CRYPTO_crc32_n (&key, GNUNET_CRYPTO_AES_KEY_LENGTH));
101
102 if (ntohl (key.crc32) != (unsigned int) 38125195LL)
103 {
104 printf ("Static key has different CRC: %u - %u\n",
105 ntohl (key.crc32), key.crc32);
106
107 ret = 1;
108 goto error;
109 }
110
111 if (GNUNET_CRYPTO_AES_KEY_LENGTH !=
112 GNUNET_CRYPTO_aes_encrypt (plain,
113 GNUNET_CRYPTO_AES_KEY_LENGTH,
114 &key,
115 (const struct
116 GNUNET_CRYPTO_AesInitializationVector *)
117 "testtesttesttest", result))
118 {
119 printf ("Wrong return value from encrypt block.\n");
120 ret = 1;
121 goto error;
122 }
123
124 if (memcmp (encrresult, result, GNUNET_CRYPTO_AES_KEY_LENGTH) != 0)
125 {
126 printf ("Encrypted result wrong.\n");
127 ret = 1;
128 goto error;
129 }
130
131 res = GNUNET_malloc (GNUNET_CRYPTO_AES_KEY_LENGTH);
132
133 if (GNUNET_CRYPTO_AES_KEY_LENGTH !=
134 GNUNET_CRYPTO_aes_decrypt (&key,
135 result,
136 GNUNET_CRYPTO_AES_KEY_LENGTH,
137 (const struct
138 GNUNET_CRYPTO_AesInitializationVector *)
139 "testtesttesttest", res))
140 {
141 printf ("Wrong return value from decrypt block.\n");
142 ret = 1;
143 goto error;
144 }
145
146 if (memcmp (res, plain, GNUNET_CRYPTO_AES_KEY_LENGTH) != 0)
147 {
148 printf ("Decrypted result does not match input.\n");
149
150 ret = 1;
151 }
152
153error:
154
155 GNUNET_free_non_null (res);
156
157 return ret;
158}
159
160int
161main (int argc, char *argv[])
162{
163 int failureCount = 0;
164
165 GNUNET_log_setup ("test-crypto-aes", "WARNING", NULL);
166 GNUNET_CRYPTO_random_disable_entropy_gathering ();
167 GNUNET_assert (strlen (INITVALUE) >
168 sizeof (struct GNUNET_CRYPTO_AesInitializationVector));
169 failureCount += testSymcipher ();
170 failureCount += verifyCrypto ();
171
172 if (failureCount != 0)
173 {
174 printf ("%d TESTS FAILED!\n", failureCount);
175 return -1;
176 }
177 return 0;
178}
179
180/* end of test_crypto_aes.c */
diff --git a/src/util/test_crypto_aes_weak.c b/src/util/test_crypto_aes_weak.c
new file mode 100644
index 000000000..27ee57968
--- /dev/null
+++ b/src/util/test_crypto_aes_weak.c
@@ -0,0 +1,203 @@
1/*
2 This file is part of GNUnet.
3 (C) 2003, 2004, 2005, 2006 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 2, 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/**
23 * @author Krista Bennett
24 * @author Christian Grothoff
25 * @file util/test_crypto_aes_weak.c
26 * @brief AES weak key test.
27 */
28#include "platform.h"
29#include "gnunet_common.h"
30#include "gnunet_crypto_lib.h"
31#include <gcrypt.h>
32
33#define MAX_WEAK_KEY_TRIALS 100000
34#define GENERATE_WEAK_KEYS GNUNET_NO
35#define WEAK_KEY_TESTSTRING "I hate weak keys."
36
37static void
38printWeakKey (struct GNUNET_CRYPTO_AesSessionKey *key)
39{
40 int i;
41 for (i = 0; i < GNUNET_CRYPTO_AES_KEY_LENGTH; i++)
42 {
43 printf ("%x ", (int) (key->key[i]));
44 }
45}
46
47static int
48testWeakKey ()
49{
50 char result[100];
51 char res[100];
52 int size;
53 struct GNUNET_CRYPTO_AesSessionKey weak_key;
54 struct GNUNET_CRYPTO_AesInitializationVector INITVALUE;
55
56 memset (&INITVALUE, 42,
57 sizeof (struct GNUNET_CRYPTO_AesInitializationVector));
58 /* sorry, this is not a weak key -- I don't have
59 any at the moment! */
60 weak_key.key[0] = (char) (0x4c);
61 weak_key.key[1] = (char) (0x31);
62 weak_key.key[2] = (char) (0xc6);
63 weak_key.key[3] = (char) (0x2b);
64 weak_key.key[4] = (char) (0xc1);
65 weak_key.key[5] = (char) (0x5f);
66 weak_key.key[6] = (char) (0x4d);
67 weak_key.key[7] = (char) (0x1f);
68 weak_key.key[8] = (char) (0x31);
69 weak_key.key[9] = (char) (0xaa);
70 weak_key.key[10] = (char) (0x12);
71 weak_key.key[11] = (char) (0x2e);
72 weak_key.key[12] = (char) (0xb7);
73 weak_key.key[13] = (char) (0x82);
74 weak_key.key[14] = (char) (0xc0);
75 weak_key.key[15] = (char) (0xb6);
76 weak_key.key[16] = (char) (0x4d);
77 weak_key.key[17] = (char) (0x1f);
78 weak_key.key[18] = (char) (0x31);
79 weak_key.key[19] = (char) (0xaa);
80 weak_key.key[20] = (char) (0x4c);
81 weak_key.key[21] = (char) (0x31);
82 weak_key.key[22] = (char) (0xc6);
83 weak_key.key[23] = (char) (0x2b);
84 weak_key.key[24] = (char) (0xc1);
85 weak_key.key[25] = (char) (0x5f);
86 weak_key.key[26] = (char) (0x4d);
87 weak_key.key[27] = (char) (0x1f);
88 weak_key.key[28] = (char) (0x31);
89 weak_key.key[29] = (char) (0xaa);
90 weak_key.key[30] = (char) (0xaa);
91 weak_key.key[31] = (char) (0xaa);
92 /* memset(&weak_key, 0, 32); */
93 weak_key.crc32 =
94 htonl (GNUNET_CRYPTO_crc32_n (&weak_key, GNUNET_CRYPTO_AES_KEY_LENGTH));
95
96 size = GNUNET_CRYPTO_aes_encrypt (WEAK_KEY_TESTSTRING,
97 strlen (WEAK_KEY_TESTSTRING) + 1,
98 &weak_key, &INITVALUE, result);
99
100 if (size == -1)
101 {
102 GNUNET_break (0);
103 return 1;
104 }
105
106 size = GNUNET_CRYPTO_aes_decrypt (&weak_key, result, size, &INITVALUE, res);
107
108 if ((strlen (WEAK_KEY_TESTSTRING) + 1) != size)
109 {
110 GNUNET_break (0);
111 return 1;
112 }
113 if (0 != strcmp (res, WEAK_KEY_TESTSTRING))
114 {
115 GNUNET_break (0);
116 return 1;
117 }
118 else
119 return 0;
120}
121
122static int
123getWeakKeys ()
124{
125 struct GNUNET_CRYPTO_AesSessionKey sessionkey;
126 int number_of_weak_keys = 0;
127 int number_of_runs;
128
129 gcry_cipher_hd_t handle;
130 int rc;
131
132 for (number_of_runs = 0; number_of_runs < MAX_WEAK_KEY_TRIALS;
133 number_of_runs++)
134 {
135
136 if (number_of_runs % 1000 == 0)
137 fprintf (stderr, ".");
138 /*printf("Got to run number %d.\n", number_of_runs); */
139 GNUNET_CRYPTO_aes_create_session_key (&sessionkey);
140
141 rc = gcry_cipher_open (&handle,
142 GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB, 0);
143
144 if (rc)
145 {
146 printf ("testweakkey: gcry_cipher_open failed on trial %d. %s\n",
147 number_of_runs, gcry_strerror (rc));
148 rc = 0;
149 continue;
150 }
151
152 rc =
153 gcry_cipher_setkey (handle, &sessionkey,
154 GNUNET_CRYPTO_AES_KEY_LENGTH);
155
156 if ((char) rc == GPG_ERR_WEAK_KEY)
157 {
158 printf ("\nWeak key (in hex): ");
159 printWeakKey (&sessionkey);
160 printf ("\n");
161 number_of_weak_keys++;
162 }
163 else if (rc)
164 {
165 printf ("\nUnexpected error generating keys. Error is %s\n",
166 gcry_strerror (rc));
167 }
168
169 gcry_cipher_close (handle);
170
171 }
172
173 return number_of_weak_keys;
174}
175
176int
177main (int argc, char *argv[])
178{
179 int weak_keys;
180
181 GNUNET_log_setup ("test-crypto-aes-weak", "WARNING", NULL);
182 GNUNET_CRYPTO_random_disable_entropy_gathering ();
183 if (GENERATE_WEAK_KEYS)
184 {
185 weak_keys = getWeakKeys ();
186
187 if (weak_keys == 0)
188 {
189 printf ("\nNo weak keys found in %d runs.\n", MAX_WEAK_KEY_TRIALS);
190 }
191 else
192 {
193 printf ("\n%d weak keys found in %d runs.\n",
194 weak_keys, MAX_WEAK_KEY_TRIALS);
195 }
196 }
197
198 if (testWeakKey () != 0)
199 return -1;
200 return 0;
201}
202
203/* end of weakkeytest.c */
diff --git a/src/util/test_crypto_crc.c b/src/util/test_crypto_crc.c
new file mode 100644
index 000000000..d1505516b
--- /dev/null
+++ b/src/util/test_crypto_crc.c
@@ -0,0 +1,221 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2006 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 2, 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 For the actual CRC code:
21 Copyright abandoned; this code is in the public domain.
22 Provided to GNUnet by peter@horizon.com
23*/
24
25/**
26 * @file util/test_crypto_crc.c
27 * @brief testcase for crypto_crc.c
28 */
29#include "platform.h"
30#include "gnunet_common.h"
31#include "gnunet_crypto_lib.h"
32
33static int expected[] = {
34 -1223996378, 929797997, -1048047323, 1791081351, -425765913, 2138425902,
35 82584863, 1939615314, 1806463044, -1505003452, 1878277636, -997353517,
36 201238705, 1723258694, -1107452366, -344562561, -1102247383, 1973035265,
37 715213337, -1886586005, 2021214515, -1387332962, 593019378, -571088044,
38 1412577760, 412164558, -1626111170, 1556494863, -289796528, -850404775,
39 2066714587, -911838105, -1426027382, 499684507, -835420055, 1817119454,
40 -1221795958, 1516966784, -1038806877, -2115880691, 532627620, 1984437415,
41 -396341583, -1345366324, -590766745, -1801923449, 1752427988, -386896390,
42 453906317, 1552589433, -858925718, 1160445643, -740188079, -486609040,
43 1102529269, -515846212, -1614217202, 1572162207, 943558923, -467330358,
44 -1870764193, 1477005328, -793029208, -888983175, -696956020, 842706021,
45 1642390067, -805889494, 1284862057, 1562545388, 2091626273, 1852404553,
46 -2076508101, 370903003, 1186422975, 1936085227, 769358463, 180401058,
47 2032612572, -105461719, -1119935472, 617249831, 1169304728, 1771205256,
48 -2042554284, 653270859, -918610713, 336081663, -913685370, 1962213744,
49 -505406126, -838622649, -1141518710, 893143582, -1330296611, 122119483,
50 1111564496, 688811976, 1016241049, -1803438473, 359630107, 1034798954,
51 -581359286, 1590946527, -389997034, 2020318460, 1695967527, -464069727,
52 -862641495, -1405012109, -771244841, 738226150, -1035328134, -933945474,
53 1254965774, 1661863830, -884127998, 1800460481, 814702567, -1214068102,
54 -541120421, 1898656429, -236825530, 1505866267, 1252462132, -981007520,
55 1502096471, -2134644056, 483221797, 1276403836, 541133290, -1234093967,
56 350748780, 257941070, 1030457090, 434988890, -1098135432, -1000556640,
57 -577128022, 644806294, -787536281, -1288346343, 998079404, 1259353935,
58 955771631, -958377466, 1746756252, 451579658, 1913409243, -952026299,
59 -1556035958, -830279881, 834744289, -1878491428, 700000962, -1027245802,
60 1393574384, -1260409147, -841420884, 892132797, 1494730226, -1649181766,
61 1651097838, -1041807403, -1916675721, -1324525963, 157405899, -655788033,
62 -1943555237, -79747022, 339721623, -138341083, 1111902411, -435322914,
63 -533294200, -190220608, -1718346014, -1631301894, 1706265243, 745533899,
64 1351941230, 1803009594, -1218191958, 1467751062, 84368433, -711251880,
65 1699423788, -768792716, 846639904, 2103267723, -2095288070, -440571408,
66 -362144485, 2020468971, 352105963, -849211036, -1272592429, 1743440467,
67 2020667861, -1649992312, 172682343, 816705364, -1990206923, 902689869,
68 -298510060, 164207498, 190378213, 242531543, 113383268, 304810777,
69 -1081099373, 819221134, -1100982926, -855941239, 1091308887, -934548124,
70 520508733, -1381763773, -491593287, -2143492665, 700894653, -2049034808,
71 -160942046, -2009323577, 1464245054, 1584746011, -768646852, -993282698,
72 1265838699, -1873820824, 575704373, -986682955, 1270688416, 88587481,
73 -1723991633, -409928242, 866669946, -483811323, -181759253, -963525431,
74 -1686612238, -1663460076, -1128449775, -1368922329, 122318131, 795862385,
75 528576131, -19927090, 1369299478, 1285665642, -738964611, 1328292127,
76 552041252, -1431494354, -1205275362, 42768297, -1329537238, -449177266,
77 943925221, 987016465, -945138414, -270064876, 1650366626, -369252552,
78 582030210, -1229235374, 147901387, -517510506, -1609742888, -1086838308,
79 1391998445, -313975512, -613392078, 855706229, 1475706341, -1112105406,
80 2032001400, 1565777625, 2030937777, 435522421, 1823527907, -691390605,
81 -827253664, 1057171580, -314146639, -630099999, -1347514552, 478716232,
82 -1533658804, -1425371979, 761987780, 1560243817, -1945893959, 1205759225,
83 -959343783, -576742354, -154125407, -1158108776, 1183788580, 1354198127,
84 -1534207721, -823991517, -170534462, -912524170, 1858513573, 467072185,
85 2091040157, -1765027018, -1659401643, -1173890143, -1912754057, -84568053,
86 2010781784, -921970156, 944508352, -922040609, 1055102010, 1018688871,
87 -1186761311, -2012263648, 1311654161, 277659086, 2029602288, 1127061510,
88 1029452642, 285677123, -188521091, -641039012, 653836416, -805916340,
89 -1644860596, 1352872213, 691634876, -1477113308, -748430369, 1030697363,
90 -2007864449, -1196662616, 1313997192, 177342476, -566676450, -1118618118,
91 1697953104, 344671484, -1489783116, -889507873, 1259591310, -716567168,
92 2116447062, 324368527, 1789366816, 1558930442, 1950250221, -785460151,
93 1174714258, -430047304, -859487565, -580633932, 607732845, -1128150220,
94 1544355315, 1460298016, -1771194297, 1215703690, 277231808, -416020628,
95 -418936577, -1724839216, 404731389, 1058730508, -1508366681, 229883053,
96 -572310243, 1883189553, 931286849, 1659300867, -94236383, -241524462,
97 548020458, -302406981, 579986475, 73468197, -984957614, 1554382245,
98 2084807492, -1456802798, -1105192593, 629440327, -16313961, -2102585261,
99 1873675206, 161035128, 1497033351, 1990150811, -499405222, 304019482,
100 41935663, -805987182, -571699268, 1748462913, 2096239823, -116359807,
101 -1871127553, -1074832534, -1558866192, 231353861, 2122854560, -2102323721,
102 -281462361, -343403210, -673268171, 1776058383, 1581561150, 2059580579,
103 768848632, 1347190372, -1701705879, 245282007, -563267886, -592558289,
104 1662399958, 1390406821, -1522485580, -706446863, 2069516289, -301855859,
105 -778346387, -1454093198, 1249083752, -1760506745, 262193320, 630751125,
106 -1495939124, -29980580, -1989626563, 659039376, -329477132, -1003507166,
107 -1322549020, 358606508, -2052572059, 1848014133, 1826958586, -1004948862,
108 -1775370541, 2134177912, -1739214473, 1892700918, 926629675, -1042761322,
109 2020075900, 606370962, -1256609305, 117577265, -586848924, 191368285,
110 1653535275, -1329269701, -375879127, -1089901406, 1206489978, 534223924,
111 -1042752982, -1178316881, -445594741, -1501682065, -1598136839,
112 -467688289, 750784023, 1781080461, 1729380226, 16906088, 862168532,
113 -2037752683, 1455274138, -1491220107, 1058323960, 1711530558, 1355062750,
114 227640096, 396568027, -173579098, -408975801, -993618329, -1470751562,
115 371076647, 209563718, 2015405719, -723460281, -1423934420, -2089643958,
116 353260489, 2084264341, -792676687, 701391030, -1440658244, 1479321011,
117 1907822880, 1232524257, -256712289, 401077577, 621808069, 868263613,
118 1244930119, 2020996902, 117483907, 1341376744, -1936988014, -445200547,
119 -843751811, -435291191, 1041695743, 476132726, -1226874735, -1436046747,
120 -297047422, 1739645396, 1948680937, -718144374, 1141983978, 1673650568,
121 -197244350, 1604464002, 1424069853, -485626505, 1708710014, -849136541,
122 1573778103, 530360999, 1777767203, 1376958336, -1088364352, 1826167753,
123 742735448, -1386211659, -1991323164, -444115655, -443055378, -1586901006,
124 -1741686587, 1925818034, -2118916824, 803890920, -1481793154, 992278937,
125 1302616410, 444517030, 1393144770, -2025632978, 1902300505, -1683582981,
126 800654133, 873850324, -619580878, -2002070410, -2024936385, 1978986634,
127 2012024264, 675768872, 389435615, -867217540, 231209167, -303917385,
128 1445676969, -1385982721, 1310476490, 580273453, -160600202, -1330895874,
129 487110497, 1124384798, 227637416, -1829783306, 1014818058, -1336870683,
130 -1042199518, -468525587, -1186267363, -472843891, 1215617600, -2056648329,
131 -873216891, 156780951, -1883246047, -842549253, -717684332, 760531638,
132 1074787431, 786267513, 814031289, -561255343, -110302255, -1837376592,
133 989669060, -81350614, 546038730, 222899882, 1298746805, 1791615733,
134 1565630269, 1516024174, 421691479, 1860326051, -1973359550, 1854393443,
135 -1401468528, -158562295, 1509929255, -124024738, -462937489, 259890715,
136 -1515121317, -289511197, -913738664, 698079062, -1631229382, -507275144,
137 1897739663, -1118192766, -1687033399, 61405556, -1913606579, -473308896,
138 -259107170, -576944609, -1689355510, 322156799, 545090192, 127425176,
139 -1815211748, -2070235628, -1172529316, 599259550, -910906653, 1797380363,
140 -938649427, 142991392, 504559631, 1208867355, -807699247, -616021271,
141 -254935281, -57151221, -1095534993, 1998380318, 1772459584, 713271407,
142 -1197898266, 808881935, -308133481, -1314455137, 284321772, -743117625,
143 -1622364240, -1667535152, 118713606, 1053615347, -2072876023, -178189072,
144 -828319551, 2047304928, -1311435786, -1970672907, -747972100, 86806159,
145 -436088421, 1464645587, 735840899, 32600466, -190473426, -735703440,
146 482872155, 475662392, -713681085, 1424078728, -150668609, -1137197868,
147 -1682762563, -48035649, 1143959866, -1542015129, 284920371, -1587695586,
148 -625236551, -753893357, -433976266, -1329796037, -1636712478, 1686783454,
149 27839146, 1748631474, -879528256, 2057796026, 773734654, 112269667,
150 -2011541314, 1517797297, -1943171794, 268166111, -1037010413, -1945824504,
151 -1672323792, 306260758, -692968628, -701704965, -462980996, 939188824,
152 553289792, 1790245000, 2093793129, -658085781, -186055037, -2130433650,
153 -1013235433, 1190870089, -2126586963, -1509655742, -1291895256,
154 -1427857845, 309538950, 388316741, 259659733, -1895092434, 110126220,
155 -170175575, -419430224, -696234084, -832170948, -353431720, -797675726,
156 -1644136054, 715163272, -1305904349, -145786463, -99586244, -695450446,
157 -871327102, -725496060, 952863853, -688441983, -1729929460, -103732092,
158 1059054528, 568873585, -982665223, -128672783, 2099418320, 1508239336,
159 -2089480835, -390935727, 664306522, -1607364342, -163246802, -1121295140,
160 -128375779, -615694409, -2079391797, 760542037, 677761593, -750117849,
161 -1060525080, 2128437080, 525250908, 1987657172, 2032530557, -2011247936,
162 1942775263, 1681562788, 688229491, -803856505, 684707948, 1308988965,
163 1455480037, 790659611, 1557968784, -383203149, -361510986, -742575828,
164 558837193, -1214977424, 1253274105, -119513513, -993964385, -33438767,
165 -177452803, 1186928041, -2073533871, 1188528559, 1896514695, 1200128512,
166 1930588755, -1914141443, 1534656032, -1192989829, -1848274656, -220848455,
167 1001806509, 1298797392, 1533031884, -1912322446, 1705583815, 1568094347,
168 -1397640627, 807828512, -1852996497, -1529733505, -1575634185,
169 -1280270160, -1567624159, -1861904922, 1276738579, 1163432999, 626879833,
170 316942006, -1871138342, 1341039701, 1595907877, 1950911580, 1634717748,
171 1071476055, -809354290, -1161553341, -2081621710, -2085557943, 19360224,
172 322135580, -698485151, 1267663094, -233890834, -126361189, -1426257522,
173 1094007921, 500179855, -283548002, -1678987343, 1946999943, 1489410849,
174 2089571262, 1430799093, 1961848046, -99462663, -552833264, 1168700661,
175 -1783882181, 2089196401, 1092839657, 914488673, 80263859, -2140947098,
176 -726384741, -1022448237, 2113887675, 1485770846, -112922517, 1995461466,
177 774613726, 944068011, 1521975359, 289086919, -386920759, -1960513175,
178 358460021, -238698524, -1913640563, -1000324864, 1731755224, -1271586254,
179 -1917469655, 2134162829, -828097534, -1089292503, -1514835999, 1682931514,
180 -482307169, 2110243841, 115744834, -2038340170, 65889188, -539445712,
181 -1713206408, -1842396726, -1659545588, -909558923, 860164922, 1328713040,
182 1044007120, -2103807103, -1073990344, -1312783785, -884980824, -705318011,
183 -1263408788, -2032228692, -1732844111, -1813827156, 1462566279,
184 1179250845, 1732421772, 604429013, -92284336, -1192166516, 304654351,
185 1998552034, -1802461575, -1802704071, -1704833934, -976264396, 1005840702,
186 2108843914, 1363909309, 843040834, -1039625241, 1285007226, 91610001,
187 418426329, 678422358, -945360697, -440008081, -1053091357, 425719777,
188 -1372778676, 591912153, 1229089037, -56663158, 2140251400, 830257037,
189 763914157, 175610373, -2105655963, -1040826150, 1174443038, 339290593,
190 346618443, -180504100, -1363190515, 210620018, 1028894425, 573529714,
191 698460117, 136999397, 1015621712, -1401813739, -297990684, -1820934845,
192 -1299093313, 1299361369, -366522415, 91527707, 1113466178, -956229484,
193 22204763, -1394374195, -1912666711, -1453789804, 1613408399, -169509567,
194 1350520309, 540761213, -2086682848, 1095131491, -812787911, 1860108594,
195 -1121378737, -1667252487, -486084366, 166519760, 1609891237, 728218405,
196 291075010, 646168382, 108462277, -1616661910, 1016600360, 2099958568,
197 27934736, 183821196, 13660496, -805589719, 936068730, -439037934,
198 1414622584, 215845485, -1352304469, -1817427526, -1318710977, -110207199,
199 228524335, 1704746590, 998293651, -1521016702, -641956531, -2089808167,
200 2094404052, -1446381065, -662186492, 1670154584, 9637833, 493925511,
201 660047318, 1197537103, 1696017374, -204994399, -1104145601, -852330465,
202 -1936369658, -829716674, -1255255217, 1264013799, 1642611772, -652520861,
203 777247164, 2028895987, -1424241853, -54367829, -1940161761, -1802831079,
204 -449405299, 838242661, -323055438, 794295411, -136989378, -446686673,
205 -421252799, -16777216,
206};
207
208int
209main (int argc, char *argv[])
210{
211 char buf[1024];
212 int i;
213
214 GNUNET_log_setup ("test-crypto-crc", "WARNING", NULL);
215 for (i = 0; i < 1024; i++)
216 buf[i] = (char) i;
217 for (i = 0; i < 1024; i++)
218 if (expected[i] != GNUNET_CRYPTO_crc32_n (&buf[i], 1024 - i))
219 return 1;
220 return 0;
221}
diff --git a/src/util/test_crypto_hash.c b/src/util/test_crypto_hash.c
new file mode 100644
index 000000000..a22a0e16a
--- /dev/null
+++ b/src/util/test_crypto_hash.c
@@ -0,0 +1,165 @@
1/*
2 This file is part of GNUnet.
3 (C) 2002, 2003, 2004, 2006, 2009 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 2, 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 * @author Christian Grothoff
23 * @file util/test_crypto_hash.c
24 * @brief Test for crypto_hash.c
25 */
26#include "platform.h"
27#include "gnunet_common.h"
28#include "gnunet_crypto_lib.h"
29#include "gnunet_scheduler_lib.h"
30
31static char block[65536];
32
33#define FILENAME "testblock.dat"
34
35static int
36test (int number)
37{
38 GNUNET_HashCode h1;
39 GNUNET_HashCode h2;
40 struct GNUNET_CRYPTO_HashAsciiEncoded enc;
41
42 memset (&h1, number, sizeof (GNUNET_HashCode));
43 GNUNET_CRYPTO_hash_to_enc (&h1, &enc);
44 if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char *) &enc, &h2))
45 {
46 printf ("enc2hash failed!\n");
47 return 1;
48 }
49 if (0 != memcmp (&h1, &h2, sizeof (GNUNET_HashCode)))
50 return 1;
51 return 0;
52}
53
54static int
55testEncoding ()
56{
57 int i;
58 for (i = 0; i < 255; i++)
59 if (0 != test (i))
60 return 1;
61 return 0;
62}
63
64static int
65testArithmetic ()
66{
67 static struct GNUNET_CRYPTO_AesSessionKey zskey;
68 static struct GNUNET_CRYPTO_AesInitializationVector ziv;
69 GNUNET_HashCode h1;
70 GNUNET_HashCode h2;
71 GNUNET_HashCode d;
72 GNUNET_HashCode s;
73 struct GNUNET_CRYPTO_AesSessionKey skey;
74 struct GNUNET_CRYPTO_AesInitializationVector iv;
75
76 GNUNET_CRYPTO_hash_create_random (&h1);
77 GNUNET_CRYPTO_hash_create_random (&h2);
78 if (GNUNET_CRYPTO_hash_distance_u32 (&h1, &h2) !=
79 GNUNET_CRYPTO_hash_distance_u32 (&h2, &h1))
80 return 1;
81 GNUNET_CRYPTO_hash_difference (&h1, &h2, &d);
82 GNUNET_CRYPTO_hash_sum (&h1, &d, &s);
83 if (0 != GNUNET_CRYPTO_hash_cmp (&s, &h2))
84 return 1;
85 GNUNET_CRYPTO_hash_xor (&h1, &h2, &d);
86 GNUNET_CRYPTO_hash_xor (&h1, &d, &s);
87 if (0 != GNUNET_CRYPTO_hash_cmp (&s, &h2))
88 return 1;
89 if (0 != GNUNET_CRYPTO_hash_xorcmp (&s, &h2, &h1))
90 return 1;
91 if (-1 != GNUNET_CRYPTO_hash_xorcmp (&h1, &h2, &h1))
92 return 1;
93 if (1 != GNUNET_CRYPTO_hash_xorcmp (&h1, &h2, &h2))
94 return 1;
95 memset (&d, 0xF0, sizeof (d));
96 if (0 != GNUNET_CRYPTO_hash_get_bit (&d, 3))
97 return 1;
98 if (1 != GNUNET_CRYPTO_hash_get_bit (&d, 6))
99 return 1;
100 memset (&d, 0, sizeof (d));
101 GNUNET_CRYPTO_hash_to_AES_key (&d, &skey, &iv);
102 if ((0 != memcmp (&skey, &zskey, sizeof (skey) - sizeof (unsigned int))) ||
103 (0 != memcmp (&iv, &ziv, sizeof (iv))))
104 return 1;
105 return 0;
106}
107
108static void
109finished_task (void *cls, const GNUNET_HashCode * res)
110{
111 int *ret = cls;
112 GNUNET_HashCode want;
113
114 GNUNET_CRYPTO_hash (block, sizeof (block), &want);
115 if (0 != memcmp (res, &want, sizeof (want)))
116 *ret = 2;
117 else
118 *ret = 0;
119}
120
121
122static void
123file_hasher (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
124{
125 GNUNET_CRYPTO_hash_file (tc->sched,
126 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
127 GNUNET_NO, FILENAME, 1024, &finished_task, cls);
128}
129
130
131static int
132testFileHash ()
133{
134 int ret;
135 FILE *f;
136
137 memset (block, 42, sizeof (block) / 2);
138 memset (&block[sizeof (block) / 2], 43, sizeof (block) / 2);
139 GNUNET_assert (NULL != (f = fopen (FILENAME, "w+")));
140 GNUNET_break (sizeof (block) == fwrite (block, 1, sizeof (block), f));
141 GNUNET_break (0 == fclose (f));
142 ret = 1;
143 GNUNET_SCHEDULER_run (&file_hasher, &ret);
144 GNUNET_break (0 == UNLINK (FILENAME));
145 return ret;
146}
147
148
149int
150main (int argc, char *argv[])
151{
152 int failureCount = 0;
153 int i;
154
155 GNUNET_log_setup ("test-crypto-hash", "WARNING", NULL);
156 for (i = 0; i < 10; i++)
157 failureCount += testEncoding ();
158 failureCount += testArithmetic ();
159 failureCount += testFileHash ();
160 if (failureCount != 0)
161 return 1;
162 return 0;
163}
164
165/* end of hashingtest.c */
diff --git a/src/util/test_crypto_ksk.c b/src/util/test_crypto_ksk.c
new file mode 100644
index 000000000..c8555b5de
--- /dev/null
+++ b/src/util/test_crypto_ksk.c
@@ -0,0 +1,220 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2004, 2005, 2006 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 2, 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 util/test_crypto_ksk.c
23 * @brief testcase for util/crypto_ksk.c
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_common.h"
28#include "gnunet_crypto_lib.h"
29#include "gnunet_signatures.h"
30#include "gnunet_time_lib.h"
31
32#define TESTSTRING "Hello World\0"
33#define MAX_TESTVAL 20
34#define UNIQUE_ITER 6
35#define ITER 25
36
37
38static int
39testMultiKey (const char *word)
40{
41 GNUNET_HashCode in;
42 struct GNUNET_CRYPTO_RsaPrivateKey *hostkey;
43 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
44 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey1;
45 int i;
46
47 fprintf (stderr, "Testing KBlock key uniqueness (%s) ", word);
48 GNUNET_CRYPTO_hash (word, strlen (word), &in);
49 hostkey = GNUNET_CRYPTO_rsa_key_create_from_hash (&in);
50 if (hostkey == NULL)
51 {
52 GNUNET_break (0);
53 return GNUNET_SYSERR;
54 }
55 GNUNET_CRYPTO_rsa_key_get_public (hostkey, &pkey);
56 /*
57 for (i=0;i<sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded);i++)
58 printf("%02x", ((unsigned char*) &pkey)[i]);
59 printf("\n"); */
60 GNUNET_CRYPTO_rsa_key_free (hostkey);
61 for (i = 0; i < UNIQUE_ITER; i++)
62 {
63 fprintf (stderr, ".");
64 hostkey = GNUNET_CRYPTO_rsa_key_create_from_hash (&in);
65 if (hostkey == NULL)
66 {
67 GNUNET_break (0);
68 fprintf (stderr, " ERROR\n");
69 return GNUNET_SYSERR;
70 }
71 GNUNET_CRYPTO_rsa_key_get_public (hostkey, &pkey1);
72 GNUNET_CRYPTO_rsa_key_free (hostkey);
73 if (0 !=
74 memcmp (&pkey, &pkey1,
75 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))
76 {
77 GNUNET_break (0);
78 fprintf (stderr, " ERROR\n");
79 return GNUNET_SYSERR;
80 }
81 }
82 fprintf (stderr, " OK\n");
83 return GNUNET_OK;
84}
85
86
87static int
88testEncryptDecrypt (struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
89{
90 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
91 struct GNUNET_CRYPTO_RsaEncryptedData target;
92 char result[MAX_TESTVAL];
93 int i;
94 struct GNUNET_TIME_Absolute start;
95 int ok;
96
97 fprintf (stderr, "W");
98 GNUNET_CRYPTO_rsa_key_get_public (hostkey, &pkey);
99
100 ok = 0;
101 start = GNUNET_TIME_absolute_get ();
102 for (i = 0; i < ITER; i++)
103 {
104 fprintf (stderr, ".");
105 if (GNUNET_SYSERR == GNUNET_CRYPTO_rsa_encrypt (TESTSTRING,
106 strlen (TESTSTRING) + 1,
107 &pkey, &target))
108 {
109 fprintf (stderr, "GNUNET_CRYPTO_rsa_encrypt returned SYSERR\n");
110 ok++;
111 continue;
112 }
113 if (-1 == GNUNET_CRYPTO_rsa_decrypt (hostkey,
114 &target, result,
115 strlen (TESTSTRING) + 1))
116 {
117 fprintf (stderr, "GNUNET_CRYPTO_rsa_decrypt returned SYSERR\n");
118 ok++;
119 continue;
120 }
121 if (strncmp (TESTSTRING, result, strlen (TESTSTRING)) != 0)
122 {
123 printf ("%s != %.*s - testEncryptDecrypt failed!\n",
124 TESTSTRING, MAX_TESTVAL, result);
125 ok++;
126 continue;
127 }
128 }
129 printf ("%d RSA encrypt/decrypt operations %llums (%d failures)\n",
130 ITER,
131 (unsigned long long) GNUNET_TIME_absolute_get_duration (start).
132 value, ok);
133 if (ok == 0)
134 return GNUNET_OK;
135 else
136 return GNUNET_SYSERR;
137}
138
139static int
140testSignVerify (struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
141{
142 struct GNUNET_CRYPTO_RsaSignature sig;
143 struct GNUNET_CRYPTO_RsaSignaturePurpose purp;
144 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
145 int i;
146 struct GNUNET_TIME_Absolute start;
147 int ok = GNUNET_OK;
148
149 fprintf (stderr, "W");
150 GNUNET_CRYPTO_rsa_key_get_public (hostkey, &pkey);
151 start = GNUNET_TIME_absolute_get ();
152 purp.size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose));
153 purp.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);
154 for (i = 0; i < ITER; i++)
155 {
156 fprintf (stderr, ".");
157 if (GNUNET_SYSERR == GNUNET_CRYPTO_rsa_sign (hostkey, &purp, &sig))
158 {
159 fprintf (stderr, "GNUNET_CRYPTO_rsa_sign returned SYSERR\n");
160 ok = GNUNET_SYSERR;
161 continue;
162 }
163 if (GNUNET_SYSERR ==
164 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TEST,
165 &purp, &sig, &pkey))
166 {
167 printf ("GNUNET_CRYPTO_rsa_verify failed!\n");
168 ok = GNUNET_SYSERR;
169 continue;
170 }
171 if (GNUNET_SYSERR !=
172 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_HELLO,
173 &purp, &sig, &pkey))
174 {
175 printf ("GNUNET_CRYPTO_rsa_verify failed to fail!\n");
176 ok = GNUNET_SYSERR;
177 continue;
178 }
179 }
180 printf ("%d RSA sign/verify operations %llums\n",
181 ITER,
182 (unsigned long long) GNUNET_TIME_absolute_get_duration (start).
183 value);
184 return ok;
185}
186
187
188int
189main (int argc, char *argv[])
190{
191 int failureCount = 0;
192 GNUNET_HashCode in;
193 struct GNUNET_CRYPTO_RsaPrivateKey *hostkey;
194
195 GNUNET_log_setup ("test-crypto-ksk", "WARNING", NULL);
196 GNUNET_CRYPTO_hash_create_random (&in);
197 hostkey = GNUNET_CRYPTO_rsa_key_create_from_hash (&in);
198 if (hostkey == NULL)
199 {
200 printf ("\nGNUNET_CRYPTO_rsa_key_create_from_hash failed!\n");
201 return 1;
202 }
203
204 if (GNUNET_OK != testMultiKey ("foo"))
205 failureCount++;
206 if (GNUNET_OK != testMultiKey ("bar"))
207 failureCount++;
208 if (GNUNET_OK != testEncryptDecrypt (hostkey))
209 failureCount++;
210 if (GNUNET_OK != testSignVerify (hostkey))
211 failureCount++;
212 GNUNET_CRYPTO_rsa_key_free (hostkey);
213
214 if (failureCount != 0)
215 {
216 printf ("\n\n%d TESTS FAILED!\n\n", failureCount);
217 return -1;
218 }
219 return 0;
220}
diff --git a/src/util/test_crypto_random.c b/src/util/test_crypto_random.c
new file mode 100644
index 000000000..e237c14a4
--- /dev/null
+++ b/src/util/test_crypto_random.c
@@ -0,0 +1,71 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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/**
23 * @file util/test_crypto_random.c
24 * @brief testcase for crypto_random.c
25 */
26#include "platform.h"
27#include "gnunet_common.h"
28#include "gnunet_crypto_lib.h"
29
30static int
31test (enum GNUNET_CRYPTO_Quality mode)
32{
33
34 int buf[1024];
35 unsigned int *b2;
36 int i;
37 unsigned long long n;
38
39 for (i = 0; i < 1024; i++)
40 GNUNET_break (1024 > (buf[i] = GNUNET_CRYPTO_random_u32 (mode, 1024)));
41 for (i = 0; i < 10; i++)
42 {
43 b2 = GNUNET_CRYPTO_random_permute (mode, 1024);
44 if (0 == memcmp (b2, buf, sizeof (buf)))
45 {
46 fprintf (stderr, "!");
47 GNUNET_free (b2);
48 continue;
49 }
50 GNUNET_free (b2);
51 break;
52 }
53 if (i == 10)
54 return 1; /* virtually impossible... */
55
56 for (n = 10; n < 1024LL * 1024LL * 1024LL; n *= 10)
57 GNUNET_break (n > GNUNET_CRYPTO_random_u64 (mode, n));
58 return 0;
59}
60
61int
62main (int argc, char *argv[])
63{
64 GNUNET_log_setup ("test-crypto-random", "WARNING", NULL);
65 if (0 != test (GNUNET_CRYPTO_QUALITY_WEAK))
66 return 1;
67 if (0 != test (GNUNET_CRYPTO_QUALITY_STRONG))
68 return 1;
69
70 return 0;
71}
diff --git a/src/util/test_crypto_rsa.c b/src/util/test_crypto_rsa.c
new file mode 100644
index 000000000..e71decca8
--- /dev/null
+++ b/src/util/test_crypto_rsa.c
@@ -0,0 +1,335 @@
1/*
2 This file is part of GNUnet.
3 (C) 2002, 2003, 2004, 2006, 2009 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 2, 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 util/test_crypto_rsa.c
23 * @brief testcase for RSA public key crypto
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_common.h"
28#include "gnunet_crypto_lib.h"
29#include "gnunet_signatures.h"
30#include "gnunet_time_lib.h"
31
32#define TESTSTRING "Hello World\0"
33#define MAX_TESTVAL sizeof(struct GNUNET_CRYPTO_AesSessionKey)
34#define ITER 25
35#define KEYFILE "/tmp/test-gnunet-crypto-rsa.key"
36
37#define PERF GNUNET_YES
38
39static int
40testEncryptDecrypt ()
41{
42 struct GNUNET_CRYPTO_RsaPrivateKey *hostkey;
43 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
44 struct GNUNET_CRYPTO_RsaEncryptedData target;
45 char result[MAX_TESTVAL];
46 int i;
47 struct GNUNET_TIME_Absolute start;
48 int ok;
49
50 fprintf (stderr, "W");
51 hostkey = GNUNET_CRYPTO_rsa_key_create ();
52 GNUNET_CRYPTO_rsa_key_get_public (hostkey, &pkey);
53
54 ok = 0;
55 start = GNUNET_TIME_absolute_get ();
56 for (i = 0; i < ITER; i++)
57 {
58 fprintf (stderr, ".");
59 if (GNUNET_SYSERR == GNUNET_CRYPTO_rsa_encrypt (TESTSTRING,
60 strlen (TESTSTRING) + 1,
61 &pkey, &target))
62 {
63 fprintf (stderr, "GNUNET_CRYPTO_rsa_encrypt returned SYSERR\n");
64 ok++;
65 continue;
66 }
67 if (-1 == GNUNET_CRYPTO_rsa_decrypt (hostkey,
68 &target, result,
69 strlen (TESTSTRING) + 1))
70 {
71 fprintf (stderr, "GNUNET_CRYPTO_rsa_decrypt returned SYSERR\n");
72 ok++;
73 continue;
74
75 }
76 if (strncmp (TESTSTRING, result, strlen (TESTSTRING)) != 0)
77 {
78 printf ("%s != %.*s - testEncryptDecrypt failed!\n",
79 TESTSTRING, MAX_TESTVAL, result);
80 ok++;
81 continue;
82 }
83 }
84 printf ("%d RSA encrypt/decrypt operations %llums (%d failures)\n",
85 ITER,
86 (unsigned long long) GNUNET_TIME_absolute_get_duration (start).
87 value, ok);
88 GNUNET_CRYPTO_rsa_key_free (hostkey);
89 if (ok == 0)
90 return GNUNET_OK;
91 else
92 return GNUNET_SYSERR;
93}
94
95#if PERF
96static int
97testEncryptPerformance ()
98{
99 struct GNUNET_CRYPTO_RsaPrivateKey *hostkey;
100 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
101 struct GNUNET_CRYPTO_RsaEncryptedData target;
102 int i;
103 struct GNUNET_TIME_Absolute start;
104 int ok;
105
106 fprintf (stderr, "W");
107 hostkey = GNUNET_CRYPTO_rsa_key_create ();
108 GNUNET_CRYPTO_rsa_key_get_public (hostkey, &pkey);
109
110 ok = 0;
111 start = GNUNET_TIME_absolute_get ();
112 for (i = 0; i < ITER; i++)
113 {
114 fprintf (stderr, ".");
115 if (GNUNET_SYSERR == GNUNET_CRYPTO_rsa_encrypt (TESTSTRING,
116 strlen (TESTSTRING) + 1,
117 &pkey, &target))
118 {
119 fprintf (stderr, "GNUNET_CRYPTO_rsa_encrypt returned SYSERR\n");
120 ok++;
121 continue;
122 }
123 }
124 printf ("%d RSA encrypt operations %llu ms (%d failures)\n",
125 ITER,
126 (unsigned long long) GNUNET_TIME_absolute_get_duration (start).
127 value, ok);
128 GNUNET_CRYPTO_rsa_key_free (hostkey);
129 if (ok != 0)
130 return GNUNET_SYSERR;
131 return GNUNET_OK;
132}
133#endif
134
135static int
136testEncryptDecryptSK ()
137{
138 struct GNUNET_CRYPTO_RsaPrivateKey *hostkey;
139 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
140 struct GNUNET_CRYPTO_RsaEncryptedData target;
141 struct GNUNET_CRYPTO_AesSessionKey insk;
142 struct GNUNET_CRYPTO_AesSessionKey outsk;
143 int i;
144 struct GNUNET_TIME_Absolute start;
145 int ok;
146
147 fprintf (stderr, "W");
148 hostkey = GNUNET_CRYPTO_rsa_key_create ();
149 GNUNET_CRYPTO_rsa_key_get_public (hostkey, &pkey);
150
151 ok = 0;
152 start = GNUNET_TIME_absolute_get ();
153 for (i = 0; i < ITER; i++)
154 {
155 fprintf (stderr, ".");
156 GNUNET_CRYPTO_aes_create_session_key (&insk);
157 if (GNUNET_SYSERR == GNUNET_CRYPTO_rsa_encrypt (&insk,
158 sizeof (struct
159 GNUNET_CRYPTO_AesSessionKey),
160 &pkey, &target))
161 {
162 fprintf (stderr, "GNUNET_CRYPTO_rsa_encrypt returned SYSERR\n");
163 ok++;
164 continue;
165 }
166 if (-1 == GNUNET_CRYPTO_rsa_decrypt (hostkey,
167 &target, &outsk,
168 sizeof (struct
169 GNUNET_CRYPTO_AesSessionKey)))
170 {
171 fprintf (stderr, "GNUNET_CRYPTO_rsa_decrypt returned SYSERR\n");
172 ok++;
173 continue;
174 }
175 if (0 !=
176 memcmp (&insk, &outsk, sizeof (struct GNUNET_CRYPTO_AesSessionKey)))
177 {
178 printf ("testEncryptDecryptSK failed!\n");
179 ok++;
180 continue;
181 }
182 }
183 printf ("%d RSA encrypt/decrypt SK operations %llus (%d failures)\n",
184 ITER,
185 (unsigned long long) GNUNET_TIME_absolute_get_duration (start).
186 value, ok);
187 GNUNET_CRYPTO_rsa_key_free (hostkey);
188 if (ok != 0)
189 return GNUNET_SYSERR;
190 return GNUNET_OK;
191}
192
193
194static int
195testSignVerify ()
196{
197 struct GNUNET_CRYPTO_RsaPrivateKey *hostkey;
198 struct GNUNET_CRYPTO_RsaSignature sig;
199 struct GNUNET_CRYPTO_RsaSignaturePurpose purp;
200 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
201 int i;
202 struct GNUNET_TIME_Absolute start;
203 int ok = GNUNET_OK;
204
205 fprintf (stderr, "W");
206 hostkey = GNUNET_CRYPTO_rsa_key_create ();
207 GNUNET_CRYPTO_rsa_key_get_public (hostkey, &pkey);
208 start = GNUNET_TIME_absolute_get ();
209 purp.size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose));
210 purp.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);
211
212 for (i = 0; i < ITER; i++)
213 {
214 fprintf (stderr, ".");
215 if (GNUNET_SYSERR == GNUNET_CRYPTO_rsa_sign (hostkey, &purp, &sig))
216 {
217 fprintf (stderr, "GNUNET_CRYPTO_rsa_sign returned SYSERR\n");
218 ok = GNUNET_SYSERR;
219 continue;
220 }
221 if (GNUNET_SYSERR ==
222 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TEST,
223 &purp, &sig, &pkey))
224 {
225 printf ("GNUNET_CRYPTO_rsa_verify failed!\n");
226 ok = GNUNET_SYSERR;
227 continue;
228 }
229 if (GNUNET_SYSERR !=
230 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_HELLO,
231 &purp, &sig, &pkey))
232 {
233 printf ("GNUNET_CRYPTO_rsa_verify failed to fail!\n");
234 ok = GNUNET_SYSERR;
235 continue;
236 }
237 }
238 printf ("%d RSA sign/verify operations %llums\n",
239 ITER,
240 (unsigned long long) GNUNET_TIME_absolute_get_duration (start).
241 value);
242 GNUNET_CRYPTO_rsa_key_free (hostkey);
243 return ok;
244}
245
246
247#if PERF
248static int
249testSignPerformance ()
250{
251 struct GNUNET_CRYPTO_RsaPrivateKey *hostkey;
252 struct GNUNET_CRYPTO_RsaSignaturePurpose purp;
253 struct GNUNET_CRYPTO_RsaSignature sig;
254 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
255 int i;
256 struct GNUNET_TIME_Absolute start;
257 int ok = GNUNET_OK;
258
259 purp.size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose));
260 purp.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);
261 fprintf (stderr, "W");
262 hostkey = GNUNET_CRYPTO_rsa_key_create ();
263 GNUNET_CRYPTO_rsa_key_get_public (hostkey, &pkey);
264 start = GNUNET_TIME_absolute_get ();
265 for (i = 0; i < ITER; i++)
266 {
267 fprintf (stderr, ".");
268 if (GNUNET_SYSERR == GNUNET_CRYPTO_rsa_sign (hostkey, &purp, &sig))
269 {
270 fprintf (stderr, "GNUNET_CRYPTO_rsa_sign returned SYSERR\n");
271 ok = GNUNET_SYSERR;
272 continue;
273 }
274 }
275 printf ("%d RSA sign operations %llu ms\n", ITER,
276 GNUNET_TIME_absolute_get_duration (start).value);
277 GNUNET_CRYPTO_rsa_key_free (hostkey);
278 return ok;
279}
280#endif
281
282
283static int
284testCreateFromFile ()
285{
286 struct GNUNET_CRYPTO_RsaPrivateKey *key;
287 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded p1;
288 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded p2;
289
290 key = GNUNET_CRYPTO_rsa_key_create_from_file (KEYFILE);
291 GNUNET_CRYPTO_rsa_key_get_public (key, &p1);
292 GNUNET_CRYPTO_rsa_key_free (key);
293 key = GNUNET_CRYPTO_rsa_key_create_from_file (KEYFILE);
294 GNUNET_CRYPTO_rsa_key_get_public (key, &p2);
295 GNUNET_assert (0 == memcmp (&p1, &p2, sizeof (p1)));
296 GNUNET_CRYPTO_rsa_key_free (key);
297 GNUNET_assert (0 == UNLINK (KEYFILE));
298 key = GNUNET_CRYPTO_rsa_key_create_from_file (KEYFILE);
299 GNUNET_CRYPTO_rsa_key_get_public (key, &p2);
300 GNUNET_assert (0 != memcmp (&p1, &p2, sizeof (p1)));
301 GNUNET_CRYPTO_rsa_key_free (key);
302 GNUNET_assert (0 == UNLINK (KEYFILE));
303 return GNUNET_OK;
304}
305
306
307int
308main (int argc, char *argv[])
309{
310 int failureCount = 0;
311
312 GNUNET_log_setup ("test-crypto-rsa", "WARNING", NULL);
313 GNUNET_CRYPTO_random_disable_entropy_gathering ();
314 if (GNUNET_OK != testCreateFromFile ())
315 failureCount++;
316#if PERF
317 if (GNUNET_OK != testEncryptPerformance ())
318 failureCount++;
319 if (GNUNET_OK != testSignPerformance ())
320 failureCount++;
321#endif
322 if (GNUNET_OK != testEncryptDecryptSK ())
323 failureCount++;
324 if (GNUNET_OK != testEncryptDecrypt ())
325 failureCount++;
326 if (GNUNET_OK != testSignVerify ())
327 failureCount++;
328
329 if (failureCount != 0)
330 {
331 printf ("\n\n%d TESTS FAILED!\n\n", failureCount);
332 return -1;
333 }
334 return 0;
335} /* end of main */
diff --git a/src/util/test_disk.c b/src/util/test_disk.c
new file mode 100644
index 000000000..0d385afa7
--- /dev/null
+++ b/src/util/test_disk.c
@@ -0,0 +1,274 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2005, 2006 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 2, 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 util/test_disk.c
23 * @brief testcase for the storage module
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_common.h"
28#include "gnunet_disk_lib.h"
29#include "gnunet_scheduler_lib.h"
30
31#define TESTSTRING "Hello World\0"
32
33static int
34testReadWrite ()
35{
36 char tmp[100 + 1];
37 int ret;
38
39 if (GNUNET_OK !=
40 GNUNET_DISK_file_write (".testfile", TESTSTRING, strlen (TESTSTRING),
41 "644"))
42 return 1;
43 if (GNUNET_OK != GNUNET_DISK_file_test (".testfile"))
44 return 1;
45 ret = GNUNET_DISK_file_read (".testfile", sizeof (tmp) - 1, tmp);
46 if (ret < 0)
47 {
48 fprintf (stderr,
49 "Error reading file `%s' in testReadWrite\n", ".testfile");
50 return 1;
51 }
52 tmp[ret] = '\0';
53 if (0 != memcmp (tmp, TESTSTRING, strlen (TESTSTRING) + 1))
54 {
55 fprintf (stderr,
56 "Error in testReadWrite: *%s* != *%s* for file %s\n",
57 tmp, TESTSTRING, ".testfile");
58 return 1;
59 }
60 GNUNET_DISK_file_copy (".testfile", ".testfile2");
61 memset (tmp, 0, sizeof (tmp));
62 ret = GNUNET_DISK_file_read (".testfile2", sizeof (tmp) - 1, tmp);
63 if (ret < 0)
64 {
65 fprintf (stderr,
66 "Error reading file `%s' in testReadWrite\n", ".testfile2");
67 return 1;
68 }
69 tmp[ret] = '\0';
70 if (0 != memcmp (tmp, TESTSTRING, strlen (TESTSTRING) + 1))
71 {
72 fprintf (stderr,
73 "Error in testReadWrite: *%s* != *%s* for file %s\n",
74 tmp, TESTSTRING, ".testfile2");
75 return 1;
76 }
77
78 GNUNET_break (0 == UNLINK (".testfile"));
79 GNUNET_break (0 == UNLINK (".testfile2"));
80 if (GNUNET_NO != GNUNET_DISK_file_test (".testfile"))
81 return 1;
82
83 return 0;
84}
85
86static int
87testOpenClose ()
88{
89 int fd;
90 unsigned long long size;
91 long avail;
92
93 fd = GNUNET_DISK_file_open (".testfile",
94 O_RDWR | O_CREAT, S_IWUSR | S_IRUSR);
95 GNUNET_assert (-1 != fd);
96 GNUNET_break (5 == WRITE (fd, "Hello", 5));
97 GNUNET_DISK_file_close (".testfile", fd);
98 GNUNET_break (GNUNET_OK ==
99 GNUNET_DISK_file_size (".testfile", &size, GNUNET_NO));
100 if (size != 5)
101 return 1;
102 GNUNET_break (0 == UNLINK (".testfile"));
103
104 /* test that avail goes down as we fill the disk... */
105 GNUNET_log_skip (1);
106 avail = GNUNET_DISK_get_blocks_available (".testfile");
107 GNUNET_log_skip (0);
108 fd = GNUNET_DISK_file_open (".testfile",
109 O_RDWR | O_CREAT, S_IWUSR | S_IRUSR);
110 GNUNET_assert (-1 != fd);
111 while ((avail == GNUNET_DISK_get_blocks_available (".testfile")) &&
112 (avail != -1))
113 if (16 != WRITE (fd, "HelloWorld123456", 16))
114 {
115 GNUNET_DISK_file_close (".testfile", fd);
116 GNUNET_break (0 == UNLINK (".testfile"));
117 return 1;
118 }
119 GNUNET_DISK_file_close (".testfile", fd);
120 GNUNET_break (0 == UNLINK (".testfile"));
121
122 return 0;
123}
124
125static int ok;
126
127static int
128scan_callback (void *want, const char *filename)
129{
130 if (NULL != strstr (filename, want))
131 ok++;
132 return GNUNET_OK;
133}
134
135static int
136testDirScan ()
137{
138 if (GNUNET_OK != GNUNET_DISK_directory_create ("test/entry"))
139 return 1;
140 if (GNUNET_OK != GNUNET_DISK_directory_create ("test/entry_more"))
141 return 1;
142 GNUNET_DISK_directory_scan ("test", &scan_callback, "test/entry");
143 if (GNUNET_OK != GNUNET_DISK_directory_remove ("test"))
144 return 1;
145 if (ok < 2)
146 return 1;
147 return 0;
148}
149
150static void
151iter_callback (void *cls,
152 struct GNUNET_DISK_DirectoryIterator *di,
153 const char *filename, const char *dirname)
154{
155 int *i = cls;
156 (*i)++;
157 GNUNET_DISK_directory_iterator_next (di, GNUNET_NO);
158}
159
160static void
161iter_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
162{
163 GNUNET_DISK_directory_iterator_start (tc->sched,
164 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
165 "test", &iter_callback, cls);
166}
167
168static int
169testDirIter ()
170{
171 int i;
172
173 i = 0;
174 if (GNUNET_OK != GNUNET_DISK_directory_create ("test/entry"))
175 return 1;
176 if (GNUNET_OK != GNUNET_DISK_directory_create ("test/entry_many"))
177 return 1;
178 if (GNUNET_OK != GNUNET_DISK_directory_create ("test/entry_more"))
179 return 1;
180 GNUNET_SCHEDULER_run (&iter_task, &i);
181 if (GNUNET_OK != GNUNET_DISK_directory_remove ("test"))
182 return 1;
183 if (i < 3)
184 return 1;
185 return 0;
186}
187
188
189static int
190testGetHome ()
191{
192 struct GNUNET_CONFIGURATION_Handle *cfg;
193 char *fn;
194 int ret;
195
196 cfg = GNUNET_CONFIGURATION_create ();
197 GNUNET_assert (cfg != NULL);
198 GNUNET_CONFIGURATION_set_value_string (cfg, "service", "HOME",
199 "/tmp/a/b/c");
200 fn = GNUNET_DISK_get_home_filename (cfg, "service", "d", "e", NULL);
201 GNUNET_assert (fn != NULL);
202 GNUNET_CONFIGURATION_destroy (cfg);
203 ret = strcmp ("/tmp/a/b/c/d/e", fn);
204 GNUNET_free (fn);
205 return ret;
206}
207
208static int
209testCanonicalize ()
210{
211 char *fn = GNUNET_strdup ("ab?><|cd*ef:/g\"");
212 GNUNET_DISK_filename_canonicalize (fn);
213 if (0 != strcmp (fn, "ab____cd_ef__g_"))
214 {
215 GNUNET_free (fn);
216 return 1;
217 }
218 GNUNET_free (fn);
219 return 0;
220}
221
222static int
223testChangeOwner ()
224{
225 GNUNET_log_skip (1);
226 if (GNUNET_OK == GNUNET_DISK_file_change_owner ("/dev/null", "unknownuser"))
227 return 1;
228 return 0;
229}
230
231static int
232testDirMani ()
233{
234 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file ("test/ing"))
235 return 1;
236 if (GNUNET_NO != GNUNET_DISK_file_test ("test"))
237 return 1;
238 if (GNUNET_NO != GNUNET_DISK_file_test ("test/ing"))
239 return 1;
240 if (GNUNET_OK != GNUNET_DISK_directory_remove ("test"))
241 return 1;
242 if (GNUNET_OK != GNUNET_DISK_directory_create ("test"))
243 return 1;
244 if (GNUNET_YES != GNUNET_DISK_directory_test ("test"))
245 return 1;
246 if (GNUNET_OK != GNUNET_DISK_directory_remove ("test"))
247 return 1;
248
249
250 return 0;
251}
252
253
254int
255main (int argc, char *argv[])
256{
257 unsigned int failureCount = 0;
258
259 GNUNET_log_setup ("test-disk", "WARNING", NULL);
260 failureCount += testReadWrite ();
261 failureCount += testOpenClose ();
262 failureCount += testDirScan ();
263 failureCount += testDirIter ();
264 failureCount += testGetHome ();
265 failureCount += testCanonicalize ();
266 failureCount += testChangeOwner ();
267 failureCount += testDirMani ();
268 if (failureCount != 0)
269 {
270 fprintf (stderr, "\n%u TESTS FAILED!\n", failureCount);
271 return -1;
272 }
273 return 0;
274} /* end of main */
diff --git a/src/util/test_getopt.c b/src/util/test_getopt.c
new file mode 100644
index 000000000..89e7be863
--- /dev/null
+++ b/src/util/test_getopt.c
@@ -0,0 +1,239 @@
1/*
2 This file is part of GNUnet.
3 (C) 2003, 2004, 2005, 2006, 2009 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 2, 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 util/test_getopt.c
22 * @brief testcase for util/getopt.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_configuration_lib.h"
27#include "gnunet_getopt_lib.h"
28
29#define VERBOSE 0
30
31static int
32testMinimal ()
33{
34 struct GNUNET_CONFIGURATION_Handle *cfg;
35 char *const emptyargv[] = {
36 "test",
37 NULL
38 };
39 const struct GNUNET_GETOPT_CommandLineOption emptyoptionlist[] = {
40 GNUNET_GETOPT_OPTION_END
41 };
42
43 cfg = GNUNET_CONFIGURATION_create ();
44 if (1 != GNUNET_GETOPT_run ("test", cfg, emptyoptionlist, 1, emptyargv))
45 {
46 GNUNET_CONFIGURATION_destroy (cfg);
47 return 1;
48 }
49 GNUNET_CONFIGURATION_destroy (cfg);
50
51 return 0;
52}
53
54static int
55testVerbose ()
56{
57 struct GNUNET_CONFIGURATION_Handle *cfg;
58 char *const myargv[] = {
59 "test",
60 "-V",
61 "-V",
62 "more",
63 NULL
64 };
65 unsigned int vflags = 0;
66 const struct GNUNET_GETOPT_CommandLineOption verboseoptionlist[] = {
67 GNUNET_GETOPT_OPTION_VERBOSE (&vflags),
68 GNUNET_GETOPT_OPTION_END
69 };
70
71 cfg = GNUNET_CONFIGURATION_create ();
72 if (3 != GNUNET_GETOPT_run ("test", cfg, verboseoptionlist, 4, myargv))
73 {
74 GNUNET_break (0);
75 GNUNET_CONFIGURATION_destroy (cfg);
76 return 1;
77 }
78 GNUNET_CONFIGURATION_destroy (cfg);
79 if (vflags != 2)
80 {
81 GNUNET_break (0);
82 return 1;
83 }
84 return 0;
85}
86
87static int
88testVersion ()
89{
90 struct GNUNET_CONFIGURATION_Handle *cfg;
91 char *const myargv[] = {
92 "test_getopt",
93 "-v",
94 NULL
95 };
96 const struct GNUNET_GETOPT_CommandLineOption versionoptionlist[] = {
97 GNUNET_GETOPT_OPTION_VERSION (PACKAGE_VERSION),
98 GNUNET_GETOPT_OPTION_END
99 };
100
101 cfg = GNUNET_CONFIGURATION_create ();
102 if (-1 != GNUNET_GETOPT_run ("test_getopt",
103 cfg, versionoptionlist, 2, myargv))
104 {
105 GNUNET_break (0);
106 GNUNET_CONFIGURATION_destroy (cfg);
107 return 1;
108 }
109 GNUNET_CONFIGURATION_destroy (cfg);
110 return 0;
111}
112
113static int
114testAbout ()
115{
116 struct GNUNET_CONFIGURATION_Handle *cfg;
117 char *const myargv[] = {
118 "test_getopt",
119 "-h",
120 NULL
121 };
122 const struct GNUNET_GETOPT_CommandLineOption aboutoptionlist[] = {
123 GNUNET_GETOPT_OPTION_HELP ("Testing"),
124 GNUNET_GETOPT_OPTION_END
125 };
126
127 cfg = GNUNET_CONFIGURATION_create ();
128 if (-1 != GNUNET_GETOPT_run ("test_getopt",
129 cfg, aboutoptionlist, 2, myargv))
130 {
131 GNUNET_break (0);
132 GNUNET_CONFIGURATION_destroy (cfg);
133 return 1;
134 }
135 GNUNET_CONFIGURATION_destroy (cfg);
136 return 0;
137}
138
139static int
140testLogOpts ()
141{
142 struct GNUNET_CONFIGURATION_Handle *cfg;
143 char *const myargv[] = {
144 "test_getopt",
145 "-l", "filename",
146 "-L", "WARNING",
147 NULL
148 };
149 char *level = GNUNET_strdup ("stuff");
150 char *fn = NULL;
151 const struct GNUNET_GETOPT_CommandLineOption logoptionlist[] = {
152 GNUNET_GETOPT_OPTION_LOGFILE (&fn),
153 GNUNET_GETOPT_OPTION_LOGLEVEL (&level),
154 GNUNET_GETOPT_OPTION_END
155 };
156
157 cfg = GNUNET_CONFIGURATION_create ();
158 if (5 != GNUNET_GETOPT_run ("test_getopt", cfg, logoptionlist, 5, myargv))
159 {
160 GNUNET_break (0);
161 GNUNET_CONFIGURATION_destroy (cfg);
162 return 1;
163 }
164 GNUNET_assert (fn != NULL);
165 GNUNET_CONFIGURATION_destroy (cfg);
166 if ((0 != strcmp (level, "WARNING")) || (0 != strcmp (fn, "filename")))
167 {
168 GNUNET_break (0);
169 GNUNET_free (level);
170 GNUNET_free (fn);
171 return 1;
172 }
173 GNUNET_free (level);
174 GNUNET_free (fn);
175 return 0;
176}
177
178static int
179testFlagNum ()
180{
181 struct GNUNET_CONFIGURATION_Handle *cfg;
182 char *const myargv[] = {
183 "test_getopt",
184 "-f",
185 "-n", "42",
186 "-N", "42",
187 NULL
188 };
189 int flag = 0;
190 unsigned int num = 0;
191 unsigned long long lnum = 0;
192 const struct GNUNET_GETOPT_CommandLineOption logoptionlist[] = {
193 {'f', "--flag", NULL, "helptext", 0, &GNUNET_GETOPT_set_one,
194 (void *) &flag},
195 {'n', "--num", "ARG", "helptext", 1, &GNUNET_GETOPT_set_uint,
196 (void *) &num},
197 {'N', "--lnum", "ARG", "helptext", 1, &GNUNET_GETOPT_set_ulong,
198 (void *) &lnum},
199 GNUNET_GETOPT_OPTION_END
200 };
201
202 cfg = GNUNET_CONFIGURATION_create ();
203 if (6 != GNUNET_GETOPT_run ("test_getopt", cfg, logoptionlist, 6, myargv))
204 {
205 GNUNET_break (0);
206 GNUNET_CONFIGURATION_destroy (cfg);
207 return 1;
208 }
209 GNUNET_CONFIGURATION_destroy (cfg);
210 if ((1 != flag) || (42 != num) || (42 != lnum))
211 {
212 GNUNET_break (0);
213 return 1;
214 }
215 return 0;
216}
217
218int
219main (int argc, char *argv[])
220{
221 int errCnt = 0;
222
223 GNUNET_log_setup ("test_getopt", "WARNING", NULL);
224 /* suppress output from -h, -v options */
225 GNUNET_break (0 == CLOSE (1));
226 if (0 != testMinimal ())
227 errCnt++;
228 if (0 != testVerbose ())
229 errCnt++;
230 if (0 != testVersion ())
231 errCnt++;
232 if (0 != testAbout ())
233 errCnt++;
234 if (0 != testLogOpts ())
235 errCnt++;
236 if (0 != testFlagNum ())
237 errCnt++;
238 return errCnt;
239}
diff --git a/src/util/test_network.c b/src/util/test_network.c
new file mode 100644
index 000000000..377ec836f
--- /dev/null
+++ b/src/util/test_network.c
@@ -0,0 +1,209 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_network.c
22 * @brief tests for network.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_network_lib.h"
27#include "gnunet_scheduler_lib.h"
28#include "gnunet_time_lib.h"
29
30#define VERBOSE GNUNET_NO
31
32#define PORT 12435
33
34
35static struct GNUNET_NETWORK_SocketHandle *csock;
36
37static struct GNUNET_NETWORK_SocketHandle *asock;
38
39static struct GNUNET_NETWORK_SocketHandle *lsock;
40
41static size_t sofar;
42
43static int ls;
44
45
46
47/**
48 * Create and initialize a listen socket for the server.
49 *
50 * @return -1 on error, otherwise the listen socket
51 */
52static int
53open_listen_socket ()
54{
55 const static int on = 1;
56 struct sockaddr_in sa;
57 int fd;
58
59 memset (&sa, 0, sizeof (sa));
60 sa.sin_port = htons (PORT);
61 fd = SOCKET (AF_INET, SOCK_STREAM, 0);
62 GNUNET_assert (fd >= 0);
63 if (SETSOCKOPT (fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
64 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
65 "setsockopt");
66 GNUNET_assert (BIND (fd, &sa, sizeof (sa)) >= 0);
67 LISTEN (fd, 5);
68 return fd;
69}
70
71static void
72receive_check (void *cls,
73 const void *buf,
74 size_t available,
75 const struct sockaddr *addr, socklen_t addrlen, int errCode)
76{
77 int *ok = cls;
78
79#if VERBOSE
80 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receive validates incoming data\n");
81#endif
82 GNUNET_assert (buf != NULL); /* no timeout */
83 if (0 == memcmp (&"Hello World"[sofar], buf, available))
84 sofar += available;
85 if (sofar < 12)
86 {
87#if VERBOSE
88 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receive needs more data\n");
89#endif
90 GNUNET_NETWORK_receive (asock,
91 1024,
92 GNUNET_TIME_relative_multiply
93 (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check,
94 cls);
95 }
96 else
97 {
98#if VERBOSE
99 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
100 "Receive closes accepted socket\n");
101#endif
102 *ok = 0;
103 GNUNET_NETWORK_socket_destroy (asock);
104 }
105}
106
107
108static void
109run_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
110{
111#if VERBOSE
112 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test accepts connection\n");
113#endif
114 asock = GNUNET_NETWORK_socket_create_from_accept (tc->sched,
115 NULL, NULL, ls, 1024);
116 GNUNET_assert (asock != NULL);
117 GNUNET_assert (GNUNET_YES == GNUNET_NETWORK_socket_check (asock));
118#if VERBOSE
119 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test destroys listen socket\n");
120#endif
121 GNUNET_NETWORK_socket_destroy (lsock);
122#if VERBOSE
123 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
124 "Test asks to receive on accepted socket\n");
125#endif
126 GNUNET_NETWORK_receive (asock,
127 1024,
128 GNUNET_TIME_relative_multiply
129 (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check, cls);
130}
131
132static size_t
133make_hello (void *cls, size_t size, void *buf)
134{
135#if VERBOSE
136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
137 "Test prepares to transmit on connect socket\n");
138#endif
139 GNUNET_assert (size >= 12);
140 strcpy ((char *) buf, "Hello World");
141 return 12;
142}
143
144static void
145task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
146{
147 ls = open_listen_socket ();
148 lsock = GNUNET_NETWORK_socket_create_from_existing (tc->sched, ls, 0);
149 GNUNET_assert (lsock != NULL);
150 csock = GNUNET_NETWORK_socket_create_from_connect (tc->sched,
151 "localhost", PORT, 1024);
152 GNUNET_assert (csock != NULL);
153#if VERBOSE
154 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test asks for write notification\n");
155#endif
156 GNUNET_assert (NULL !=
157 GNUNET_NETWORK_notify_transmit_ready (csock,
158 12,
159 GNUNET_TIME_UNIT_SECONDS,
160 &make_hello, NULL));
161#if VERBOSE
162 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test destroys client socket\n");
163#endif
164 GNUNET_NETWORK_socket_destroy (csock);
165#if VERBOSE
166 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test prepares to accept\n");
167#endif
168 GNUNET_SCHEDULER_add_read (tc->sched,
169 GNUNET_NO,
170 GNUNET_SCHEDULER_PRIORITY_HIGH,
171 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
172 GNUNET_TIME_UNIT_FOREVER_REL,
173 ls, &run_accept, cls);
174}
175
176
177/**
178 * Main method, starts scheduler with task ,
179 * checks that "ok" is correct at the end.
180 */
181static int
182check ()
183{
184 int ok;
185
186 ok = 1;
187 GNUNET_SCHEDULER_run (&task, &ok);
188 return ok;
189}
190
191
192
193int
194main (int argc, char *argv[])
195{
196 int ret = 0;
197
198 GNUNET_log_setup ("test_network",
199#if VERBOSE
200 "DEBUG",
201#else
202 "WARNING",
203#endif
204 NULL);
205 ret += check ();
206 return ret;
207}
208
209/* end of test_network.c */
diff --git a/src/util/test_network_addressing.c b/src/util/test_network_addressing.c
new file mode 100644
index 000000000..8312b721f
--- /dev/null
+++ b/src/util/test_network_addressing.c
@@ -0,0 +1,193 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_network_addressing.c
22 * @brief tests for network.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_network_lib.h"
27#include "gnunet_scheduler_lib.h"
28#include "gnunet_time_lib.h"
29
30#define VERBOSE GNUNET_NO
31
32#define PORT 12435
33
34
35static struct GNUNET_NETWORK_SocketHandle *csock;
36
37static struct GNUNET_NETWORK_SocketHandle *asock;
38
39static struct GNUNET_NETWORK_SocketHandle *lsock;
40
41static size_t sofar;
42
43static int ls;
44
45
46
47/**
48 * Create and initialize a listen socket for the server.
49 *
50 * @return -1 on error, otherwise the listen socket
51 */
52static int
53open_listen_socket ()
54{
55 const static int on = 1;
56 struct sockaddr_in sa;
57 int fd;
58
59 memset (&sa, 0, sizeof (sa));
60 sa.sin_port = htons (PORT);
61 fd = SOCKET (AF_INET, SOCK_STREAM, 0);
62 GNUNET_assert (fd >= 0);
63 if (SETSOCKOPT (fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
64 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
65 "setsockopt");
66 GNUNET_assert (BIND (fd, &sa, sizeof (sa)) >= 0);
67 LISTEN (fd, 5);
68 return fd;
69}
70
71
72static void
73receive_check (void *cls,
74 const void *buf,
75 size_t available,
76 const struct sockaddr *addr, socklen_t addrlen, int errCode)
77{
78 int *ok = cls;
79
80 GNUNET_assert (buf != NULL); /* no timeout */
81 if (0 == memcmp (&"Hello World"[sofar], buf, available))
82 sofar += available;
83 if (sofar < 12)
84 {
85 GNUNET_NETWORK_receive (asock,
86 1024,
87 GNUNET_TIME_relative_multiply
88 (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check,
89 cls);
90 }
91 else
92 {
93 *ok = 0;
94 GNUNET_NETWORK_socket_destroy (asock);
95 }
96}
97
98
99static void
100run_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
101{
102 void *addr;
103 size_t alen;
104 struct sockaddr_in *v4;
105 struct sockaddr_in expect;
106
107 asock = GNUNET_NETWORK_socket_create_from_accept (tc->sched,
108 NULL, NULL, ls, 1024);
109 GNUNET_assert (asock != NULL);
110 GNUNET_assert (GNUNET_YES == GNUNET_NETWORK_socket_check (asock));
111 GNUNET_assert (GNUNET_OK ==
112 GNUNET_NETWORK_socket_get_address (asock, &addr, &alen));
113 GNUNET_assert (alen == sizeof (struct sockaddr_in));
114 v4 = addr;
115 memset (&expect, 0, sizeof (expect));
116 expect.sin_family = AF_INET;
117 expect.sin_port = v4->sin_port;
118 expect.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
119 GNUNET_assert (0 == memcmp (&expect, v4, alen));
120 GNUNET_NETWORK_socket_destroy (lsock);
121 GNUNET_NETWORK_receive (asock,
122 1024,
123 GNUNET_TIME_relative_multiply
124 (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check, cls);
125}
126
127static size_t
128make_hello (void *cls, size_t size, void *buf)
129{
130 GNUNET_assert (size >= 12);
131 strcpy ((char *) buf, "Hello World");
132 return 12;
133}
134
135static void
136task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
137{
138 struct sockaddr_in v4;
139 ls = open_listen_socket ();
140 lsock = GNUNET_NETWORK_socket_create_from_existing (tc->sched, ls, 0);
141 GNUNET_assert (lsock != NULL);
142
143 v4.sin_family = AF_INET;
144 v4.sin_port = htons (PORT);
145 v4.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
146 csock = GNUNET_NETWORK_socket_create_from_sockaddr (tc->sched,
147 AF_INET,
148 (const struct sockaddr
149 *) &v4, sizeof (v4),
150 1024);
151 GNUNET_assert (csock != NULL);
152 GNUNET_assert (NULL !=
153 GNUNET_NETWORK_notify_transmit_ready (csock,
154 12,
155 GNUNET_TIME_UNIT_SECONDS,
156 &make_hello, NULL));
157 GNUNET_NETWORK_socket_destroy (csock);
158 GNUNET_SCHEDULER_add_read (tc->sched,
159 GNUNET_NO,
160 GNUNET_SCHEDULER_PRIORITY_HIGH,
161 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
162 GNUNET_TIME_UNIT_FOREVER_REL,
163 ls, &run_accept, cls);
164}
165
166
167/**
168 * Main method, starts scheduler with task ,
169 * checks that "ok" is correct at the end.
170 */
171static int
172check ()
173{
174 int ok;
175
176 ok = 1;
177 GNUNET_SCHEDULER_run (&task, &ok);
178 return ok;
179}
180
181
182
183int
184main (int argc, char *argv[])
185{
186 int ret = 0;
187
188 GNUNET_log_setup ("test_network_addressing", "WARNING", NULL);
189 ret += check ();
190 return ret;
191}
192
193/* end of test_network_addressing.c */
diff --git a/src/util/test_network_receive_cancel.c b/src/util/test_network_receive_cancel.c
new file mode 100644
index 000000000..e22e24d8c
--- /dev/null
+++ b/src/util/test_network_receive_cancel.c
@@ -0,0 +1,164 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_network_receive_cancel.c
22 * @brief tests for network.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_network_lib.h"
27#include "gnunet_scheduler_lib.h"
28#include "gnunet_time_lib.h"
29
30#define VERBOSE GNUNET_NO
31
32#define PORT 12435
33
34
35static struct GNUNET_NETWORK_SocketHandle *csock;
36
37static struct GNUNET_NETWORK_SocketHandle *asock;
38
39static struct GNUNET_NETWORK_SocketHandle *lsock;
40
41static int ls;
42
43static GNUNET_SCHEDULER_TaskIdentifier receive_task;
44
45
46
47
48/**
49 * Create and initialize a listen socket for the server.
50 *
51 * @return -1 on error, otherwise the listen socket
52 */
53static int
54open_listen_socket ()
55{
56 const static int on = 1;
57 struct sockaddr_in sa;
58 int fd;
59
60 memset (&sa, 0, sizeof (sa));
61 sa.sin_port = htons (PORT);
62 fd = SOCKET (AF_INET, SOCK_STREAM, 0);
63 GNUNET_assert (fd >= 0);
64 if (SETSOCKOPT (fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
65 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
66 "setsockopt");
67 GNUNET_assert (BIND (fd, &sa, sizeof (sa)) >= 0);
68 LISTEN (fd, 5);
69 return fd;
70}
71
72
73
74static void
75dead_receive (void *cls,
76 const void *buf,
77 size_t available,
78 const struct sockaddr *addr, socklen_t addrlen, int errCode)
79{
80 GNUNET_assert (0);
81}
82
83
84static void
85run_accept_cancel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
86{
87
88 asock = GNUNET_NETWORK_socket_create_from_accept (tc->sched,
89 NULL, NULL, ls, 1024);
90 GNUNET_assert (asock != NULL);
91 GNUNET_assert (GNUNET_YES == GNUNET_NETWORK_socket_check (asock));
92 GNUNET_NETWORK_socket_destroy (lsock);
93 receive_task
94 = GNUNET_NETWORK_receive (asock,
95 1024,
96 GNUNET_TIME_relative_multiply
97 (GNUNET_TIME_UNIT_SECONDS, 5), &dead_receive,
98 cls);
99}
100
101
102static void
103receive_cancel_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
104{
105 int *ok = cls;
106 GNUNET_NETWORK_receive_cancel (asock, receive_task);
107 GNUNET_NETWORK_socket_destroy (csock);
108 GNUNET_NETWORK_socket_destroy (asock);
109 *ok = 0;
110}
111
112
113
114static void
115task_receive_cancel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
116{
117 ls = open_listen_socket ();
118 lsock = GNUNET_NETWORK_socket_create_from_existing (tc->sched, ls, 0);
119 GNUNET_assert (lsock != NULL);
120 csock = GNUNET_NETWORK_socket_create_from_connect (tc->sched,
121 "localhost", PORT, 1024);
122 GNUNET_assert (csock != NULL);
123 GNUNET_SCHEDULER_add_read (tc->sched,
124 GNUNET_NO,
125 GNUNET_SCHEDULER_PRIORITY_HIGH,
126 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
127 GNUNET_TIME_UNIT_FOREVER_REL,
128 ls, &run_accept_cancel, cls);
129 GNUNET_SCHEDULER_add_delayed (tc->sched,
130 GNUNET_NO,
131 GNUNET_SCHEDULER_PRIORITY_KEEP,
132 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
133 GNUNET_TIME_UNIT_SECONDS,
134 &receive_cancel_task, cls);
135}
136
137
138
139/**
140 * Main method, starts scheduler with task_timeout.
141 */
142static int
143check_receive_cancel ()
144{
145 int ok;
146
147 ok = 1;
148 GNUNET_SCHEDULER_run (&task_receive_cancel, &ok);
149 return ok;
150}
151
152
153int
154main (int argc, char *argv[])
155{
156 int ret = 0;
157
158 GNUNET_log_setup ("test_network_receive_cancel", "WARNING", NULL);
159 ret += check_receive_cancel ();
160
161 return ret;
162}
163
164/* end of test_network.c */
diff --git a/src/util/test_network_timeout.c b/src/util/test_network_timeout.c
new file mode 100644
index 000000000..2c2f6f9f2
--- /dev/null
+++ b/src/util/test_network_timeout.c
@@ -0,0 +1,144 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_network_timeout.c
22 * @brief tests for network.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_network_lib.h"
27#include "gnunet_scheduler_lib.h"
28#include "gnunet_time_lib.h"
29
30#define VERBOSE GNUNET_NO
31
32#define PORT 12435
33
34static struct GNUNET_NETWORK_SocketHandle *csock;
35
36static struct GNUNET_NETWORK_SocketHandle *lsock;
37
38static int ls;
39
40
41/**
42 * Create and initialize a listen socket for the server.
43 *
44 * @return -1 on error, otherwise the listen socket
45 */
46static int
47open_listen_socket ()
48{
49 const static int on = 1;
50 struct sockaddr_in sa;
51 int fd;
52
53 memset (&sa, 0, sizeof (sa));
54 sa.sin_port = htons (PORT);
55 fd = SOCKET (AF_INET, SOCK_STREAM, 0);
56 GNUNET_assert (fd >= 0);
57 if (SETSOCKOPT (fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
58 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
59 "setsockopt");
60 GNUNET_assert (BIND (fd, &sa, sizeof (sa)) >= 0);
61 LISTEN (fd, 5);
62 return fd;
63}
64
65
66static size_t
67send_kilo (void *cls, size_t size, void *buf)
68{
69 int *ok = cls;
70 if (size == 0)
71 {
72#if VERBOSE
73 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got the desired timeout!\n");
74#endif
75 GNUNET_assert (buf == NULL);
76 *ok = 0;
77 GNUNET_NETWORK_socket_destroy (lsock);
78 GNUNET_NETWORK_socket_destroy (csock);
79 return 0;
80 }
81#if VERBOSE
82 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending kilo to fill buffer.\n");
83#endif
84 GNUNET_assert (size >= 1024);
85 memset (buf, 42, 1024);
86
87 GNUNET_assert (NULL !=
88 GNUNET_NETWORK_notify_transmit_ready (csock,
89 1024,
90 GNUNET_TIME_UNIT_SECONDS,
91 &send_kilo, cls));
92 return 1024;
93}
94
95
96static void
97task_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
98{
99
100 ls = open_listen_socket ();
101 lsock = GNUNET_NETWORK_socket_create_from_existing (tc->sched, ls, 0);
102 GNUNET_assert (lsock != NULL);
103 csock = GNUNET_NETWORK_socket_create_from_connect (tc->sched,
104 "localhost", PORT, 1024);
105 GNUNET_assert (csock != NULL);
106 GNUNET_assert (NULL !=
107 GNUNET_NETWORK_notify_transmit_ready (csock,
108 1024,
109 GNUNET_TIME_UNIT_SECONDS,
110 &send_kilo, cls));
111}
112
113
114
115/**
116 * Main method, starts scheduler with task_timeout.
117 */
118static int
119check_timeout ()
120{
121 int ok;
122
123 ok = 1;
124 GNUNET_SCHEDULER_run (&task_timeout, &ok);
125 return ok;
126}
127
128int
129main (int argc, char *argv[])
130{
131 int ret = 0;
132
133 GNUNET_log_setup ("test_network_timeout",
134#if VERBOSE
135 "DEBUG",
136#else
137 "WARNING",
138#endif
139 NULL);
140 ret += check_timeout ();
141 return ret;
142}
143
144/* end of test_network_timeout.c */
diff --git a/src/util/test_network_timeout_no_connect.c b/src/util/test_network_timeout_no_connect.c
new file mode 100644
index 000000000..fd5e82dcd
--- /dev/null
+++ b/src/util/test_network_timeout_no_connect.c
@@ -0,0 +1,95 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_network_timeout.c
22 * @brief tests for network.c, doing timeout which connect failure
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_network_lib.h"
27#include "gnunet_scheduler_lib.h"
28#include "gnunet_time_lib.h"
29
30#define VERBOSE GNUNET_NO
31
32#define PORT 13425
33
34static struct GNUNET_NETWORK_SocketHandle *csock;
35
36static size_t
37handle_timeout (void *cls, size_t size, void *buf)
38{
39 int *ok = cls;
40#if VERBOSE
41 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received timeout signal.\n");
42#endif
43
44 GNUNET_assert (size == 0);
45 GNUNET_assert (buf == NULL);
46 *ok = 0;
47 return 0;
48}
49
50
51static void
52task_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
53{
54 csock = GNUNET_NETWORK_socket_create_from_connect (tc->sched,
55 "localhost", PORT, 1024);
56 GNUNET_assert (csock != NULL);
57 GNUNET_assert (NULL !=
58 GNUNET_NETWORK_notify_transmit_ready (csock,
59 1024,
60 GNUNET_TIME_UNIT_SECONDS,
61 &handle_timeout, cls));
62}
63
64
65
66/**
67 * Main method, starts scheduler with task_timeout.
68 */
69static int
70check_timeout ()
71{
72 int ok;
73
74 ok = 1;
75 GNUNET_SCHEDULER_run (&task_timeout, &ok);
76 return ok;
77}
78
79int
80main (int argc, char *argv[])
81{
82 int ret = 0;
83
84 GNUNET_log_setup ("test_network_timeout_no_connect",
85#if VERBOSE
86 "DEBUG",
87#else
88 "WARNING",
89#endif
90 NULL);
91 ret += check_timeout ();
92 return ret;
93}
94
95/* end of test_network_timeout_no_connect.c */
diff --git a/src/util/test_network_transmit_cancel.c b/src/util/test_network_transmit_cancel.c
new file mode 100644
index 000000000..29732d202
--- /dev/null
+++ b/src/util/test_network_transmit_cancel.c
@@ -0,0 +1,97 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_network_transmit_cancel.c
22 * @brief tests for network.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_network_lib.h"
27#include "gnunet_scheduler_lib.h"
28#include "gnunet_time_lib.h"
29
30#define VERBOSE GNUNET_YES
31
32#define PORT 12435
33
34
35static size_t
36not_run (void *cls, size_t size, void *buf)
37{
38 GNUNET_assert (0);
39 return 0;
40}
41
42
43static void
44task_transmit_cancel (void *cls,
45 const struct GNUNET_SCHEDULER_TaskContext *tc)
46{
47 int *ok = cls;
48 struct GNUNET_NETWORK_TransmitHandle *th;
49 struct GNUNET_NETWORK_SocketHandle *csock;
50
51 csock = GNUNET_NETWORK_socket_create_from_connect (tc->sched,
52 "localhost", PORT, 1024);
53 GNUNET_assert (csock != NULL);
54 th = GNUNET_NETWORK_notify_transmit_ready (csock,
55 12,
56 GNUNET_TIME_UNIT_MINUTES,
57 &not_run, cls);
58 GNUNET_NETWORK_notify_transmit_ready_cancel (th);
59 GNUNET_NETWORK_socket_destroy (csock);
60 *ok = 0;
61}
62
63
64
65
66/**
67 * Main method, starts scheduler with task_timeout.
68 */
69static int
70check_transmit_cancel ()
71{
72 int ok;
73
74 ok = 1;
75 GNUNET_SCHEDULER_run (&task_transmit_cancel, &ok);
76 return ok;
77}
78
79
80int
81main (int argc, char *argv[])
82{
83 int ret = 0;
84
85 GNUNET_log_setup ("test_network_transmit_cancel",
86#if VERBOSE
87 "DEBUG",
88#else
89 "WARNING",
90#endif
91 NULL);
92 ret += check_transmit_cancel ();
93
94 return ret;
95}
96
97/* end of test_network_transmit_cancel.c */
diff --git a/src/util/test_os_load.c b/src/util/test_os_load.c
new file mode 100644
index 000000000..2f82f60c7
--- /dev/null
+++ b/src/util/test_os_load.c
@@ -0,0 +1,182 @@
1/*
2 This file is part of GNUnet.
3 (C) 2003, 2004, 2005, 2006, 2009 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 2, 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 util/test_os_load.c
22 * @brief testcase for util/os_load.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_configuration_lib.h"
27#include "gnunet_crypto_lib.h"
28#include "gnunet_disk_lib.h"
29#include "gnunet_os_lib.h"
30#include "gnunet_time_lib.h"
31
32#define VERBOSE 0
33
34static int
35testcpu ()
36{
37 static long k;
38 int ret;
39 struct GNUNET_TIME_Absolute start;
40 struct GNUNET_CONFIGURATION_Handle *cfg;
41
42 fprintf (stderr, "CPU load test, this may take a while.");
43 cfg = GNUNET_CONFIGURATION_create ();
44 GNUNET_assert (cfg != NULL);
45 /* need to run each phase for more than 10s since
46 statuscalls only refreshes that often... */
47 GNUNET_CONFIGURATION_set_value_number (cfg, "LOAD", "MAXCPULOAD", 100);
48 GNUNET_OS_load_cpu_get (cfg);
49 start = GNUNET_TIME_absolute_get ();
50 while ((GNUNET_TIME_absolute_get_duration (start).value < 120 * 1000) &&
51 (0 != GNUNET_OS_load_cpu_get (cfg)))
52 sleep (1);
53 start = GNUNET_TIME_absolute_get ();
54 ret = GNUNET_OS_load_cpu_get (cfg);
55 if (ret > 10)
56 {
57 fprintf (stderr,
58 "\nWARNING: base load too high (%d) to run CPU load test.\n",
59 ret);
60 GNUNET_CONFIGURATION_destroy (cfg);
61 return 0;
62 }
63 if (ret == -1)
64 {
65 fprintf (stderr, "\nWARNING: CPU load determination not supported.\n");
66 GNUNET_CONFIGURATION_destroy (cfg);
67 return 0;
68 }
69 while (GNUNET_TIME_absolute_get_duration (start).value < 60 * 1000)
70 {
71 k++; /* do some processing to drive load up */
72 if (ret < GNUNET_OS_load_cpu_get (cfg))
73 break;
74 }
75 if (ret >= GNUNET_OS_load_cpu_get (cfg))
76 {
77 fprintf (stderr,
78 "\nbusy loop failed to increase CPU load: %d >= %d.",
79 ret, GNUNET_OS_load_cpu_get (cfg));
80 ret = 1;
81 }
82 else
83 {
84#if VERBOSE
85 fprintf (stderr,
86 "\nbusy loop increased CPU load: %d < %d.",
87 ret, GNUNET_OS_load_cpu_get (cfg));
88#endif
89 ret = 0;
90 }
91 fprintf (stderr, "\n");
92
93
94 GNUNET_CONFIGURATION_destroy (cfg);
95 return ret;
96}
97
98static int
99testdisk ()
100{
101 int ret;
102 int fd;
103 char buf[65536];
104 struct GNUNET_TIME_Absolute start;
105 struct GNUNET_CONFIGURATION_Handle *cfg;
106
107 fprintf (stderr, "IO load test, this may take a while.");
108 cfg = GNUNET_CONFIGURATION_create ();
109 GNUNET_assert (cfg != NULL);
110 /* need to run each phase for more than 10s since
111 statuscalls only refreshes that often... */
112 GNUNET_CONFIGURATION_set_value_number (cfg, "LOAD", "MAXIOLOAD", 100);
113 GNUNET_OS_load_disk_get (cfg);
114 start = GNUNET_TIME_absolute_get ();
115 while ((GNUNET_TIME_absolute_get_duration (start).value < 12 * 1000) &&
116 (0 != GNUNET_OS_load_disk_get (cfg)))
117 sleep (1);
118 start = GNUNET_TIME_absolute_get ();
119 ret = GNUNET_OS_load_disk_get (cfg);
120 if (ret > 10)
121 {
122 fprintf (stderr,
123 "WARNING: base load too high (%d) to run IO load test.\n",
124 ret);
125 GNUNET_CONFIGURATION_destroy (cfg);
126 return 0;
127 }
128 if (ret == -1)
129 {
130 fprintf (stderr, "WARNING: IO load determination not supported.\n");
131 GNUNET_CONFIGURATION_destroy (cfg);
132 return 0;
133 }
134 memset (buf, 42, sizeof (buf));
135 fd =
136 GNUNET_DISK_file_open (".loadfile", O_WRONLY | O_CREAT,
137 S_IRUSR | S_IWUSR);
138 GNUNET_assert (fd != -1);
139 while (GNUNET_TIME_absolute_get_duration (start).value < 60 * 1000)
140 {
141 LSEEK (fd, GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
142 1024 * 1024 * 1024), SEEK_SET);
143 GNUNET_assert (sizeof (buf) == WRITE (fd, buf, sizeof (buf)));
144 fsync (fd);
145 if (ret < GNUNET_OS_load_disk_get (cfg))
146 break;
147 }
148 GNUNET_break (0 == CLOSE (fd));
149 GNUNET_break (0 == UNLINK (".loadfile"));
150 if (ret >= GNUNET_OS_load_disk_get (cfg))
151 {
152 fprintf (stderr,
153 "\nbusy loop failed to increase IO load: %d >= %d.",
154 ret, GNUNET_OS_load_disk_get (cfg));
155 ret = 1;
156 }
157 else
158 {
159#if VERBOSE
160 fprintf (stderr,
161 "\nbusy loop increased disk load: %d < %d.",
162 ret, GNUNET_OS_load_disk_get (cfg));
163#endif
164 ret = 0;
165 }
166 fprintf (stderr, "\n");
167 GNUNET_CONFIGURATION_destroy (cfg);
168 return 0;
169}
170
171int
172main (int argc, char *argv[])
173{
174 int errCnt = 0;
175
176 GNUNET_log_setup ("test-os-load", "WARNING", NULL);
177 if (0 != testcpu ())
178 errCnt++;
179 if (0 != testdisk ())
180 errCnt++;
181 return errCnt;
182}
diff --git a/src/util/test_os_network.c b/src/util/test_os_network.c
new file mode 100644
index 000000000..ca57765da
--- /dev/null
+++ b/src/util/test_os_network.c
@@ -0,0 +1,73 @@
1/*
2 This file is part of GNUnet.
3 (C) 2003, 2004, 2005, 2006, 2009 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 2, 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 util/test_os_network.c
22 * @brief testcase for util/os_network.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_configuration_lib.h"
27#include "gnunet_os_lib.h"
28
29#define VERBOSE 0
30
31/**
32 * Check if the address we got is IPv4 or IPv6 loopback (which should
33 * be present on all systems at all times); if so, set ok to 0
34 * (success).
35 */
36static int
37proc (void *cls,
38 const char *name,
39 int isDefault, const struct sockaddr *addr, socklen_t addrlen)
40{
41 int *ok = cls;
42 char buf[INET6_ADDRSTRLEN];
43
44 inet_ntop (addr->sa_family,
45 (addr->sa_family == AF_INET) ?
46 (void *) &((struct sockaddr_in *) addr)->sin_addr :
47 (void *) &((struct sockaddr_in6 *) addr)->sin6_addr,
48 buf, sizeof (buf));
49 if ((0 == strcmp ("::1", buf)) || (0 == strcmp ("127.0.0.1", buf)))
50 *ok = 0;
51 return GNUNET_OK;
52}
53
54static int
55testifcs ()
56{
57 int ret;
58
59 ret = 1;
60 GNUNET_OS_network_interfaces_list (&proc, &ret);
61 return ret;
62}
63
64int
65main (int argc, char *argv[])
66{
67 int errCnt = 0;
68
69 GNUNET_log_setup ("test-os-network", "WARNING", NULL);
70 if (0 != testifcs ())
71 errCnt++;
72 return errCnt;
73}
diff --git a/src/util/test_os_priority.c b/src/util/test_os_priority.c
new file mode 100644
index 000000000..8284af5b8
--- /dev/null
+++ b/src/util/test_os_priority.c
@@ -0,0 +1,61 @@
1/*
2 This file is part of GNUnet.
3 (C) 2003, 2004, 2005, 2006, 2009 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 2, 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 util/test_os_priority.c
22 * @brief testcase for util/os_priority.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_os_lib.h"
27
28#define VERBOSE 0
29
30static int
31testprio ()
32{
33 pid_t child;
34 if (GNUNET_OK !=
35 GNUNET_OS_set_process_priority (getpid (),
36 GNUNET_SCHEDULER_PRIORITY_DEFAULT))
37 return 1;
38#ifndef MINGW
39 child = fork ();
40 if (child == 0)
41 {
42 sleep (10);
43 exit (0);
44 }
45 if (GNUNET_OK !=
46 GNUNET_OS_set_process_priority (child, GNUNET_SCHEDULER_PRIORITY_IDLE))
47 return 1;
48#endif
49 return 0;
50}
51
52int
53main (int argc, char *argv[])
54{
55 int errCnt = 0;
56
57 GNUNET_log_setup ("test_os_priority", "WARNING", NULL);
58 if (0 != testprio ())
59 errCnt++;
60 return errCnt;
61}
diff --git a/src/util/test_plugin.c b/src/util/test_plugin.c
new file mode 100644
index 000000000..22bf78b92
--- /dev/null
+++ b/src/util/test_plugin.c
@@ -0,0 +1,64 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_plugin.c
22 * @brief testcase for plugin.c
23 */
24#include "platform.h"
25#include "gnunet_plugin_lib.h"
26
27#define VERBOSE GNUNET_NO
28
29static int
30check ()
31{
32 void *ret;
33
34 GNUNET_log_skip (1);
35 ret = GNUNET_PLUGIN_load ("libgnunet_plugin_missing", NULL);
36 GNUNET_log_skip (0);
37 if (ret != NULL)
38 return 1;
39 ret = GNUNET_PLUGIN_load ("libgnunet_plugin_test", "in");
40 if (ret == NULL)
41 return 1;
42 if (0 != strcmp (ret, "Hello"))
43 return 2;
44 ret = GNUNET_PLUGIN_unload ("libgnunet_plugin_test", "out");
45 if (ret == NULL)
46 return 3;
47 if (0 != strcmp (ret, "World"))
48 return 4;
49 free (ret);
50 return 0;
51}
52
53int
54main (int argc, char *argv[])
55{
56 int ret;
57
58 GNUNET_log_setup ("test-plugin", "WARNING", NULL);
59 ret = check ();
60
61 return ret;
62}
63
64/* end of test_plugin.c */
diff --git a/src/util/test_plugin_plug.c b/src/util/test_plugin_plug.c
new file mode 100644
index 000000000..ca4bef277
--- /dev/null
+++ b/src/util/test_plugin_plug.c
@@ -0,0 +1,42 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_plugin_plug.c
22 * @brief plugin for testing
23 */
24#include "platform.h"
25
26void *
27libgnunet_plugin_test_init (void *arg)
28{
29 if (0 == strcmp (arg, "in"))
30 return "Hello";
31 return NULL;
32}
33
34void *
35libgnunet_plugin_test_done (void *arg)
36{
37 if (0 == strcmp (arg, "out"))
38 return strdup ("World");
39 return NULL;
40}
41
42/* end of test_plugin_plug.c */
diff --git a/src/util/test_program.c b/src/util/test_program.c
new file mode 100644
index 000000000..dee602e2a
--- /dev/null
+++ b/src/util/test_program.c
@@ -0,0 +1,94 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_program.c
22 * @brief tests for program.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_program_lib.h"
27#include "gnunet_scheduler_lib.h"
28#include "gnunet_time_lib.h"
29
30static int setme;
31
32static struct GNUNET_GETOPT_CommandLineOption options[] = {
33 {'n', "name", NULL, "description", 0, &GNUNET_GETOPT_set_one, &setme},
34 GNUNET_GETOPT_OPTION_END
35};
36
37/**
38 * Main function that will be run.
39 */
40static void
41runner (void *cls,
42 struct GNUNET_SCHEDULER_Handle *sched,
43 char *const *args,
44 const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *cfg)
45{
46 int *ok = cls;
47 GNUNET_assert (setme == 1);
48 GNUNET_assert (sched != NULL);
49 GNUNET_assert (0 == strcmp (args[0], "extra"));
50 GNUNET_assert (args[1] == NULL);
51 GNUNET_assert (0 == strcmp (cfgfile, "test_program_data.conf"));
52
53 *ok = 0;
54}
55
56
57/**
58 * Main method, starts scheduler with task1,
59 * checks that "ok" is correct at the end.
60 */
61static int
62check ()
63{
64 int ok = 1;
65 char *const argv[] = {
66 "test_program",
67 "-c",
68 "test_program_data.conf",
69 "-L",
70 "WARNING",
71 "-n",
72 "extra",
73 NULL
74 };
75 GNUNET_assert (GNUNET_OK ==
76 GNUNET_PROGRAM_run (7,
77 argv,
78 "test_program",
79 "A test", options, &runner, &ok));
80 return ok;
81}
82
83int
84main (int argc, char *argv[])
85{
86 int ret = 0;
87
88 GNUNET_log_setup ("test_program", "WARNING", NULL);
89 ret += check ();
90
91 return ret;
92}
93
94/* end of test_program.c */
diff --git a/src/util/test_program_data.conf b/src/util/test_program_data.conf
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/util/test_program_data.conf
diff --git a/src/util/test_pseudonym.c b/src/util/test_pseudonym.c
new file mode 100644
index 000000000..6d31c8a07
--- /dev/null
+++ b/src/util/test_pseudonym.c
@@ -0,0 +1,138 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005, 2006, 2008, 2009 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 2, 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 util/test_pseudonym.c
23 * @brief testcase for pseudonym.c
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_common.h"
29#include "gnunet_container_lib.h"
30#include "gnunet_crypto_lib.h"
31#include "gnunet_disk_lib.h"
32#include "gnunet_pseudonym_lib.h"
33
34#define CHECK(a) if (!(a)) { ok = GNUNET_NO; GNUNET_break(0); goto FAILURE; }
35
36static struct GNUNET_CONTAINER_MetaData *meta;
37
38static GNUNET_HashCode id1;
39
40static int
41iter (void *cls,
42 const GNUNET_HashCode *
43 pseudonym, const struct GNUNET_CONTAINER_MetaData *md, int rating)
44{
45 int *ok = cls;
46
47 if ((0 == memcmp (pseudonym,
48 &id1,
49 sizeof (GNUNET_HashCode))) &&
50 (!GNUNET_CONTAINER_meta_data_test_equal (md, meta)))
51 {
52 *ok = GNUNET_NO;
53 GNUNET_break (0);
54 }
55 return GNUNET_OK;
56}
57
58static int
59noti_callback (void *cls,
60 const GNUNET_HashCode *
61 pseudonym,
62 const struct GNUNET_CONTAINER_MetaData *md, int rating)
63{
64 int *ret = cls;
65 (*ret)++;
66 return GNUNET_OK;
67}
68
69
70int
71main (int argc, char *argv[])
72{
73 int ok;
74 GNUNET_HashCode rid1;
75 GNUNET_HashCode id2;
76 GNUNET_HashCode rid2;
77 int old;
78 int newVal;
79 struct GNUNET_CONFIGURATION_Handle *cfg;
80 char *name1;
81 char *name2;
82 int notiCount;
83
84 GNUNET_log_setup ("test-psuedonym", "WARNING", NULL);
85 ok = GNUNET_YES;
86 GNUNET_CRYPTO_random_disable_entropy_gathering ();
87 GNUNET_DISK_directory_remove ("/tmp/gnunet-pseudonym-test");
88 cfg = GNUNET_CONFIGURATION_create ();
89 if (-1 == GNUNET_CONFIGURATION_parse (cfg, "test_pseudonym_data.conf"))
90 {
91 GNUNET_CONFIGURATION_destroy (cfg);
92 GNUNET_break (0);
93 return -1;
94 }
95 notiCount = 0;
96 GNUNET_PSEUDONYM_discovery_callback_register (cfg,
97 &noti_callback, &notiCount);
98 /* ACTUAL TEST CODE */
99 old = GNUNET_PSEUDONYM_list_all (cfg, NULL, NULL);
100 meta = GNUNET_CONTAINER_meta_data_create ();
101 GNUNET_CONTAINER_meta_data_insert (meta, EXTRACTOR_TITLE, "test");
102 GNUNET_CRYPTO_hash_create_random (&id1);
103 GNUNET_PSEUDONYM_add (cfg, &id1, meta);
104 CHECK (notiCount == 1);
105 GNUNET_PSEUDONYM_add (cfg, &id1, meta);
106 CHECK (notiCount == 2);
107 newVal = GNUNET_PSEUDONYM_list_all (cfg, &iter, &ok);
108 CHECK (old < newVal);
109 old = newVal;
110 GNUNET_CRYPTO_hash_create_random (&id2);
111 GNUNET_PSEUDONYM_add (cfg, &id2, meta);
112 CHECK (notiCount == 3);
113 newVal = GNUNET_PSEUDONYM_list_all (cfg, &iter, &ok);
114 CHECK (old < newVal);
115 name2 = GNUNET_PSEUDONYM_id_to_name (cfg, &id2);
116 CHECK (name2 != NULL);
117 name1 = GNUNET_PSEUDONYM_id_to_name (cfg, &id1);
118 CHECK (name1 != NULL);
119 CHECK (0 != strcmp (name1, name2));
120 CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name2, &rid2));
121 CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name1, &rid1));
122 CHECK (0 == memcmp (&id1, &rid1, sizeof (GNUNET_HashCode)));
123 CHECK (0 == memcmp (&id2, &rid2, sizeof (GNUNET_HashCode)));
124 CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 0));
125 CHECK (5 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5));
126 CHECK (-5 == GNUNET_PSEUDONYM_rank (cfg, &id1, -10));
127 CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5));
128 GNUNET_free (name1);
129 GNUNET_free (name2);
130 /* END OF TEST CODE */
131FAILURE:
132 GNUNET_PSEUDONYM_discovery_callback_unregister (&noti_callback, &notiCount);
133 GNUNET_CONTAINER_meta_data_destroy (meta);
134 GNUNET_CONFIGURATION_destroy (cfg);
135 return (ok == GNUNET_YES) ? 0 : 1;
136}
137
138/* end of test_pseudoynm.c */
diff --git a/src/util/test_pseudonym_data.conf b/src/util/test_pseudonym_data.conf
new file mode 100644
index 000000000..fd2048586
--- /dev/null
+++ b/src/util/test_pseudonym_data.conf
@@ -0,0 +1,8 @@
1# General settings
2[client]
3HOME = "/tmp/gnunet-pseudonym-test"
4
5[TESTING]
6WEAKRANDOM = YES
7
8
diff --git a/src/util/test_scheduler.c b/src/util/test_scheduler.c
new file mode 100644
index 000000000..fe15e987b
--- /dev/null
+++ b/src/util/test_scheduler.c
@@ -0,0 +1,263 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_scheduler.c
22 * @brief tests for the scheduler
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_scheduler_lib.h"
27#include "gnunet_time_lib.h"
28
29#define VERBOSE GNUNET_NO
30
31static void
32task2 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
33{
34 int *ok = cls;
35 GNUNET_assert (2 == *ok);
36 (*ok) = 3;
37}
38
39static void
40task3 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
41{
42 int *ok = cls;
43 /* t4 should be ready (albeit with lower priority) */
44 GNUNET_assert (1 == GNUNET_SCHEDULER_get_load (tc->sched,
45 GNUNET_SCHEDULER_PRIORITY_COUNT));
46 GNUNET_assert (3 == *ok);
47 (*ok) = 4;
48}
49
50static void
51task4 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
52{
53 int *ok = cls;
54 GNUNET_assert (4 == *ok);
55 (*ok) = 5;
56}
57
58static int fds[2];
59
60
61static void
62taskWrt (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
63{
64 static char c;
65 int *ok = cls;
66 GNUNET_assert (6 == *ok);
67 GNUNET_assert (FD_ISSET (fds[1], tc->write_ready));
68 (*ok) = 7;
69 GNUNET_assert (1 == WRITE (fds[1], &c, 1));
70 GNUNET_break (0 == CLOSE (fds[1]));
71}
72
73
74static void
75taskNeverRun (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
76{
77 GNUNET_assert (0);
78}
79
80static void
81taskLast (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
82{
83 int *ok = cls;
84 /* t4 should be ready (albeit with lower priority) */
85 GNUNET_assert (8 == *ok);
86 (*ok) = 0;
87}
88
89static void
90taskRd (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
91{
92 static char c;
93 int *ok = cls;
94 GNUNET_assert (7 == *ok);
95 GNUNET_assert (FD_ISSET (fds[0], tc->read_ready));
96 GNUNET_assert (1 == READ (fds[0], &c, 1));
97 GNUNET_break (0 == CLOSE (fds[0]));
98 (*ok) = 8;
99 GNUNET_SCHEDULER_add_after (tc->sched,
100 GNUNET_NO,
101 GNUNET_SCHEDULER_PRIORITY_UI,
102 0, &taskNeverRun, NULL);
103 GNUNET_SCHEDULER_add_after (tc->sched,
104 GNUNET_YES,
105 GNUNET_SCHEDULER_PRIORITY_IDLE,
106 0, &taskLast, cls);
107 GNUNET_SCHEDULER_shutdown (tc->sched);
108}
109
110
111static void
112task5 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
113{
114 int *ok = cls;
115 GNUNET_assert (5 == *ok);
116 (*ok) = 6;
117 GNUNET_assert (0 == pipe (fds));
118 GNUNET_SCHEDULER_add_read (tc->sched,
119 GNUNET_NO,
120 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
121 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
122 GNUNET_TIME_UNIT_FOREVER_REL,
123 fds[0], &taskRd, cls);
124 GNUNET_SCHEDULER_add_write (tc->sched,
125 GNUNET_NO,
126 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
127 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
128 GNUNET_TIME_UNIT_FOREVER_REL,
129 fds[1], &taskWrt, cls);
130}
131
132
133static void
134task1 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
135{
136 int *ok = cls;
137 GNUNET_SCHEDULER_TaskIdentifier t2;
138 GNUNET_SCHEDULER_TaskIdentifier t3;
139 GNUNET_SCHEDULER_TaskIdentifier t4;
140
141 GNUNET_assert (1 == *ok);
142 (*ok) = 2;
143 /* t2 will go first -- prereq for all */
144 t2 = GNUNET_SCHEDULER_add_after (tc->sched,
145 GNUNET_NO,
146 GNUNET_SCHEDULER_PRIORITY_IDLE,
147 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
148 &task2, cls);
149 /* t3 will go before t4: higher priority */
150 t4 = GNUNET_SCHEDULER_add_after (tc->sched,
151 GNUNET_NO,
152 GNUNET_SCHEDULER_PRIORITY_IDLE,
153 t2, &task4, cls);
154 t3 = GNUNET_SCHEDULER_add_delayed (tc->sched,
155 GNUNET_NO,
156 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
157 t2,
158 GNUNET_TIME_relative_get_zero (),
159 &task3, cls);
160 /* t4 will go first: lower prio, but prereq! */
161 GNUNET_SCHEDULER_add_after (tc->sched,
162 GNUNET_NO,
163 GNUNET_SCHEDULER_PRIORITY_UI, t4, &task5, cls);
164}
165
166
167
168/**
169 * Main method, starts scheduler with task1,
170 * checks that "ok" is correct at the end.
171 */
172static int
173check ()
174{
175 int ok;
176
177 ok = 1;
178 GNUNET_SCHEDULER_run (&task1, &ok);
179 return ok;
180}
181
182
183static void
184taskSig (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
185{
186 int *ok = cls;
187 GNUNET_assert (1 == *ok);
188 *ok = 8;
189 GNUNET_SCHEDULER_add_after (tc->sched,
190 GNUNET_NO,
191 GNUNET_SCHEDULER_PRIORITY_UI,
192 0, &taskNeverRun, NULL);
193 GNUNET_SCHEDULER_add_after (tc->sched,
194 GNUNET_YES,
195 GNUNET_SCHEDULER_PRIORITY_UI,
196 0, &taskLast, cls);
197 GNUNET_break (0 == PLIBC_KILL (getpid (), SIGTERM));
198}
199
200
201/**
202 * Main method, starts scheduler with task1,
203 * checks that "ok" is correct at the end.
204 */
205static int
206checkSignal ()
207{
208 int ok;
209
210 ok = 1;
211 GNUNET_SCHEDULER_run (&taskSig, &ok);
212 return ok;
213}
214
215
216
217
218static void
219taskCancel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
220{
221 int *ok = cls;
222
223 GNUNET_assert (1 == *ok);
224 *ok = 0;
225 GNUNET_SCHEDULER_cancel (tc->sched,
226 GNUNET_SCHEDULER_add_after (tc->sched,
227 GNUNET_NO,
228 GNUNET_SCHEDULER_PRIORITY_UI,
229 0,
230 &taskNeverRun, NULL));
231}
232
233
234/**
235 * Main method, starts scheduler with task1,
236 * checks that "ok" is correct at the end.
237 */
238static int
239checkCancel ()
240{
241 int ok;
242
243 ok = 1;
244 GNUNET_SCHEDULER_run (&taskCancel, &ok);
245 return ok;
246}
247
248
249
250int
251main (int argc, char *argv[])
252{
253 int ret = 0;
254
255 GNUNET_log_setup ("test_scheduler", "WARNING", NULL);
256 ret += check ();
257 ret += checkSignal ();
258 ret += checkCancel ();
259
260 return ret;
261}
262
263/* end of test_scheduler.c */
diff --git a/src/util/test_scheduler_delay.c b/src/util/test_scheduler_delay.c
new file mode 100644
index 000000000..76cbf94d8
--- /dev/null
+++ b/src/util/test_scheduler_delay.c
@@ -0,0 +1,107 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2006 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 2, 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 util/test_scheduler_delay.c
22 * @brief testcase for delay of scheduler, measures how
23 * precise the timers are. Expect values between 10 and 20 ms on
24 * modern machines.
25 */
26#include "platform.h"
27#include "gnunet_common.h"
28#include "gnunet_scheduler_lib.h"
29#include "gnunet_time_lib.h"
30
31#define VERBOSE GNUNET_NO
32
33static struct GNUNET_TIME_Absolute target;
34
35static int i;
36
37static unsigned long long cumDelta;
38
39#define INCR 47
40
41#define MAXV 1500
42
43/**
44 * Signature of the main function of a task.
45 *
46 * @param cls closure
47 * @param tc context
48 */
49static void
50test_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
51{
52 struct GNUNET_TIME_Absolute now;
53
54 now = GNUNET_TIME_absolute_get ();
55 if (now.value > target.value)
56 cumDelta += (now.value - target.value);
57 else
58 cumDelta += (target.value - now.value);
59 target =
60 GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply
61 (GNUNET_TIME_UNIT_MILLISECONDS, i));
62 fprintf (stderr, ".");
63 if (i > MAXV)
64 {
65 fprintf (stderr, "\n");
66 return;
67 }
68 GNUNET_SCHEDULER_add_delayed (tc->sched,
69 GNUNET_NO,
70 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
71 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
72 GNUNET_TIME_relative_multiply
73 (GNUNET_TIME_UNIT_MILLISECONDS, i),
74 &test_task, NULL);
75 i += INCR;
76}
77
78static int
79check ()
80{
81 target = GNUNET_TIME_absolute_get ();
82 GNUNET_SCHEDULER_run (&test_task, NULL);
83 FPRINTF (stdout,
84 "Sleep precision: %llu ms. ", cumDelta / 1000 / (MAXV / INCR));
85 if (cumDelta <= 10 * MAXV / INCR)
86 fprintf (stdout, "Timer precision is excellent.\n");
87 else if (cumDelta <= 50 * MAXV / INCR) /* 50 ms average deviation */
88 fprintf (stdout, "Timer precision is good.\n");
89 else if (cumDelta > 250 * MAXV / INCR)
90 fprintf (stdout, "Timer precision is awful.\n");
91 else
92 fprintf (stdout, "Timer precision is acceptable.\n");
93 return 0;
94}
95
96int
97main (int argc, char *argv[])
98{
99 int ret;
100
101 GNUNET_log_setup ("test-scheduler-delay", "WARNING", NULL);
102 ret = check ();
103
104 return ret;
105}
106
107/* end of test_scheduler_delay.c */
diff --git a/src/util/test_server.c b/src/util/test_server.c
new file mode 100644
index 000000000..e3df0b456
--- /dev/null
+++ b/src/util/test_server.c
@@ -0,0 +1,287 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_server.c
22 * @brief tests for server.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_scheduler_lib.h"
27#include "gnunet_server_lib.h"
28#include "gnunet_time_lib.h"
29
30#define VERBOSE GNUNET_NO
31
32#define PORT 12435
33
34#define MY_TYPE 128
35#define MY_TYPE2 129
36
37static struct GNUNET_SERVER_Handle *server;
38
39static struct GNUNET_SCHEDULER_Handle *sched;
40
41static void
42recv_fin_cb (void *cls,
43 struct GNUNET_SERVER_Handle *server,
44 struct GNUNET_SERVER_Client *client,
45 const struct GNUNET_MessageHeader *message)
46{
47 int *ok = cls;
48 GNUNET_assert (2 == *ok);
49 GNUNET_SERVER_receive_done (client, GNUNET_OK);
50 *ok = 3;
51}
52
53struct SignalTimeoutContext
54{
55 GNUNET_NETWORK_Receiver cb;
56 void *cb_cls;
57};
58
59
60static void
61signal_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
62{
63 struct SignalTimeoutContext *stctx = cls;
64
65 stctx->cb (stctx->cb_cls, NULL, 0, NULL, 0, 0);
66 GNUNET_free (stctx);
67}
68
69
70static GNUNET_SCHEDULER_TaskIdentifier
71my_receive (void *cls,
72 size_t max,
73 struct GNUNET_TIME_Relative timeout,
74 GNUNET_NETWORK_Receiver receiver, void *receiver_cls)
75{
76 int *ok = cls;
77 struct GNUNET_MessageHeader msg;
78 struct SignalTimeoutContext *stctx;
79 GNUNET_SCHEDULER_TaskIdentifier ret;
80
81 ret = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
82 switch (*ok)
83 {
84 case 1:
85 *ok = 2; /* report success */
86 msg.type = htons (MY_TYPE2);
87 msg.size = htons (sizeof (msg));
88 receiver (receiver_cls, &msg, sizeof (msg), NULL, 0, 0);
89 break;
90 case 3:
91 /* called after first receive instantly
92 produced a reply;
93 schedule receiver call with timeout
94 after timeout expires! */
95 *ok = 4;
96 stctx = GNUNET_malloc (sizeof (struct SignalTimeoutContext));
97 stctx->cb = receiver;
98 stctx->cb_cls = receiver_cls;
99 ret = GNUNET_SCHEDULER_add_delayed (sched,
100 GNUNET_NO,
101 GNUNET_SCHEDULER_PRIORITY_KEEP,
102 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
103 timeout, &signal_timeout, stctx);
104 break;
105 default:
106 GNUNET_assert (0);
107 }
108 return ret;
109}
110
111
112static void
113my_cancel (void *cls, GNUNET_SCHEDULER_TaskIdentifier ti)
114{
115 GNUNET_SCHEDULER_cancel (sched, ti);
116}
117
118static void *
119my_transmit_ready_cb (void *cls,
120 size_t size,
121 struct GNUNET_TIME_Relative timeout,
122 GNUNET_NETWORK_TransmitReadyNotify notify,
123 void *notify_cls)
124{
125 static int non_null_addr;
126 int *ok = cls;
127 char buf[size];
128 struct GNUNET_MessageHeader msg;
129
130 GNUNET_assert (4 == *ok);
131 GNUNET_assert (size == sizeof (struct GNUNET_MessageHeader));
132 notify (notify_cls, size, buf);
133 msg.type = htons (MY_TYPE);
134 msg.size = htons (sizeof (msg));
135 GNUNET_assert (0 == memcmp (&msg, buf, size));
136 *ok = 5; /* report success */
137 return &non_null_addr;
138}
139
140
141static void
142my_transmit_ready_cancel_cb (void *cls, void *ctx)
143{
144 GNUNET_assert (0);
145}
146
147
148static int
149my_check (void *cls)
150{
151 return GNUNET_YES;
152}
153
154
155static void my_destroy (void *cls);
156
157
158struct CopyContext
159{
160 struct GNUNET_SERVER_Client *client;
161 struct GNUNET_MessageHeader *cpy;
162};
163
164static size_t
165copy_msg (void *cls, size_t size, void *buf)
166{
167 struct CopyContext *ctx = cls;
168 struct GNUNET_MessageHeader *cpy = ctx->cpy;
169 GNUNET_assert (sizeof (struct GNUNET_MessageHeader) == ntohs (cpy->size));
170 GNUNET_assert (size >= ntohs (cpy->size));
171 memcpy (buf, cpy, ntohs (cpy->size));
172 GNUNET_free (cpy);
173 GNUNET_free (ctx);
174 return sizeof (struct GNUNET_MessageHeader);
175}
176
177
178static void
179recv_cb (void *cls,
180 struct GNUNET_SERVER_Handle *server,
181 struct GNUNET_SERVER_Client *argclient,
182 const struct GNUNET_MessageHeader *message)
183{
184 struct GNUNET_SERVER_Client *client;
185 struct CopyContext *cc;
186 struct GNUNET_MessageHeader *cpy;
187
188 GNUNET_assert (argclient == NULL);
189 GNUNET_assert (sizeof (struct GNUNET_MessageHeader) ==
190 ntohs (message->size));
191 GNUNET_assert (MY_TYPE == ntohs (message->type));
192 client = GNUNET_SERVER_connect_callback (server,
193 cls,
194 &my_receive,
195 &my_cancel,
196 &my_transmit_ready_cb,
197 &my_transmit_ready_cancel_cb,
198 &my_check, &my_destroy);
199 cc = GNUNET_malloc (sizeof (struct CopyContext));
200 cc->client = client;
201 cpy = GNUNET_malloc (ntohs (message->size));
202 memcpy (cpy, message, ntohs (message->size));
203 cc->cpy = cpy;
204 GNUNET_assert (NULL !=
205 GNUNET_SERVER_notify_transmit_ready (client,
206 ntohs (message->size),
207 GNUNET_TIME_UNIT_SECONDS,
208 &copy_msg, cc));
209 GNUNET_SERVER_client_drop (client);
210}
211
212
213static struct GNUNET_SERVER_MessageHandler handlers[] = {
214 {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)},
215 {&recv_fin_cb, NULL, MY_TYPE2, sizeof (struct GNUNET_MessageHeader)},
216 {NULL, NULL, 0, 0}
217};
218
219
220static void
221my_destroy (void *cls)
222{
223 int *ok = cls;
224 GNUNET_assert (5 == *ok);
225 *ok = 0; /* report success */
226 /* this will cause us to terminate */
227 GNUNET_SERVER_destroy (server);
228}
229
230
231static void
232task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
233{
234 struct sockaddr_in sa;
235 struct GNUNET_MessageHeader msg;
236
237 sched = tc->sched;
238 memset (&sa, 0, sizeof (sa));
239 sa.sin_family = AF_INET;
240 sa.sin_port = htons (PORT);
241 server = GNUNET_SERVER_create (tc->sched,
242 NULL,
243 NULL,
244 (const struct sockaddr *) &sa,
245 sizeof (sa),
246 1024,
247 GNUNET_TIME_relative_multiply
248 (GNUNET_TIME_UNIT_MILLISECONDS, 250),
249 GNUNET_NO);
250 GNUNET_assert (server != NULL);
251 handlers[0].callback_cls = cls;
252 handlers[1].callback_cls = cls;
253 GNUNET_SERVER_add_handlers (server, handlers);
254 msg.type = htons (MY_TYPE);
255 msg.size = htons (sizeof (msg));
256 GNUNET_SERVER_inject (server, NULL, &msg);
257 memset (&msg, 0, sizeof (msg));
258}
259
260
261/**
262 * Main method, starts scheduler with task1,
263 * checks that "ok" is correct at the end.
264 */
265static int
266check ()
267{
268 int ok;
269
270 ok = 1;
271 GNUNET_SCHEDULER_run (&task, &ok);
272 return ok;
273}
274
275
276int
277main (int argc, char *argv[])
278{
279 int ret = 0;
280
281 GNUNET_log_setup ("test_server", "WARNING", NULL);
282 ret += check ();
283
284 return ret;
285}
286
287/* end of test_server.c */
diff --git a/src/util/test_server_disconnect.c b/src/util/test_server_disconnect.c
new file mode 100644
index 000000000..60604b35c
--- /dev/null
+++ b/src/util/test_server_disconnect.c
@@ -0,0 +1,241 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_server_disconnect.c
22 * @brief tests for server.c and client.c,
23 * specifically client_disconnect
24 */
25#include "platform.h"
26#include "gnunet_common.h"
27#include "gnunet_scheduler_lib.h"
28#include "gnunet_client_lib.h"
29#include "gnunet_server_lib.h"
30#include "gnunet_time_lib.h"
31
32#define VERBOSE GNUNET_NO
33
34#define PORT 22335
35
36#define MY_TYPE 128
37
38
39static struct GNUNET_SERVER_Handle *server;
40
41static struct GNUNET_CLIENT_Connection *client;
42
43static struct GNUNET_SCHEDULER_Handle *sched;
44
45static struct GNUNET_CONFIGURATION_Handle *cfg;
46
47static int ok;
48
49static void
50send_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
51{
52 struct GNUNET_SERVER_Client *argclient = cls;
53 GNUNET_assert (ok == 3);
54 ok++;
55 GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
56}
57
58static void
59server_disconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
60{
61 struct GNUNET_SERVER_Client *argclient = cls;
62 GNUNET_assert (ok == 5);
63 ok++;
64 GNUNET_SERVER_client_disconnect (argclient);
65}
66
67
68static void
69recv_cb (void *cls,
70 struct GNUNET_SERVER_Handle *server,
71 struct GNUNET_SERVER_Client *argclient,
72 const struct GNUNET_MessageHeader *message)
73{
74 void *addr;
75 size_t addrlen;
76 struct sockaddr_in sa;
77 struct sockaddr_in *have;
78
79 GNUNET_assert (GNUNET_OK ==
80 GNUNET_SERVER_client_get_address (argclient,
81 &addr, &addrlen));
82
83 GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
84 have = addr;
85 memset (&sa, 0, sizeof (sa));
86 sa.sin_family = AF_INET;
87 sa.sin_port = have->sin_port;
88 sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
89 GNUNET_assert (0 == memcmp (&sa, addr, addrlen));
90 GNUNET_free (addr);
91 switch (ok)
92 {
93 case 2:
94 ok++;
95 GNUNET_SCHEDULER_add_delayed (sched,
96 GNUNET_YES,
97 GNUNET_SCHEDULER_PRIORITY_KEEP,
98 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
99 GNUNET_TIME_relative_multiply
100 (GNUNET_TIME_UNIT_MILLISECONDS, 50),
101 &send_done, argclient);
102 break;
103 case 4:
104 ok++;
105 GNUNET_SCHEDULER_add_delayed (sched,
106 GNUNET_YES,
107 GNUNET_SCHEDULER_PRIORITY_KEEP,
108 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
109 GNUNET_TIME_relative_multiply
110 (GNUNET_TIME_UNIT_MILLISECONDS, 50),
111 &server_disconnect, argclient);
112 GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
113 break;
114 default:
115 GNUNET_assert (0);
116 }
117
118}
119
120static void
121disconnect_notify (void *cls, const struct GNUNET_MessageHeader *msg)
122{
123 GNUNET_assert (msg == NULL);
124 GNUNET_assert (ok == 7);
125 ok = 0;
126 GNUNET_CLIENT_disconnect (client);
127 GNUNET_SCHEDULER_shutdown (sched);
128 GNUNET_CONFIGURATION_destroy (cfg);
129}
130
131
132/**
133 * Functions with this signature are called whenever a client
134 * is disconnected on the network level.
135 *
136 * @param cls closure
137 * @param client identification of the client
138 */
139static void
140notify_disconnect (void *cls, struct GNUNET_SERVER_Client *clientarg)
141{
142 GNUNET_assert (ok == 6);
143 ok++;
144 GNUNET_CLIENT_receive (client,
145 &disconnect_notify,
146 NULL, GNUNET_TIME_UNIT_FOREVER_REL);
147}
148
149
150static size_t
151notify_ready (void *cls, size_t size, void *buf)
152{
153 struct GNUNET_MessageHeader *msg;
154
155 GNUNET_assert (size >= 256);
156 GNUNET_assert (1 == ok);
157 ok++;
158 msg = buf;
159 msg->type = htons (MY_TYPE);
160 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
161 msg++;
162 msg->type = htons (MY_TYPE);
163 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
164 return 2 * sizeof (struct GNUNET_MessageHeader);
165}
166
167
168static struct GNUNET_SERVER_MessageHandler handlers[] = {
169 {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)},
170 {NULL, NULL, 0, 0}
171};
172
173
174static void
175task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
176{
177 struct sockaddr_in sa;
178
179 sched = tc->sched;
180 memset (&sa, 0, sizeof (sa));
181 sa.sin_family = AF_INET;
182 sa.sin_port = htons (PORT);
183 server = GNUNET_SERVER_create (tc->sched,
184 NULL,
185 NULL,
186 (const struct sockaddr *) &sa,
187 sizeof (sa),
188 1024,
189 GNUNET_TIME_relative_multiply
190 (GNUNET_TIME_UNIT_MILLISECONDS, 250),
191 GNUNET_NO);
192 GNUNET_assert (server != NULL);
193 handlers[0].callback_cls = cls;
194 GNUNET_SERVER_add_handlers (server, handlers);
195 GNUNET_SERVER_disconnect_notify (server, &notify_disconnect, cls);
196 cfg = GNUNET_CONFIGURATION_create ();
197 GNUNET_CONFIGURATION_set_value_number (cfg, "test", "PORT", PORT);
198 GNUNET_CONFIGURATION_set_value_string (cfg, "test", "HOSTNAME",
199 "localhost");
200 client = GNUNET_CLIENT_connect (tc->sched, "test", cfg);
201 GNUNET_assert (client != NULL);
202 GNUNET_CLIENT_notify_transmit_ready (client,
203 256,
204 GNUNET_TIME_relative_multiply
205 (GNUNET_TIME_UNIT_MILLISECONDS, 250),
206 &notify_ready, NULL);
207}
208
209
210/**
211 * Main method, starts scheduler with task1,
212 * checks that "ok" is correct at the end.
213 */
214static int
215check ()
216{
217
218 ok = 1;
219 GNUNET_SCHEDULER_run (&task, NULL);
220 return ok;
221}
222
223
224int
225main (int argc, char *argv[])
226{
227 int ret = 0;
228
229 GNUNET_log_setup ("test_server_disconnect",
230#if VERBOSE
231 "DEBUG",
232#else
233 "WARNING",
234#endif
235 NULL);
236 ret += check ();
237
238 return ret;
239}
240
241/* end of test_server_disconnect.c */
diff --git a/src/util/test_server_with_client.c b/src/util/test_server_with_client.c
new file mode 100644
index 000000000..4ca2b5bc3
--- /dev/null
+++ b/src/util/test_server_with_client.c
@@ -0,0 +1,215 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_server_with_client.c
22 * @brief tests for server.c and client.c,
23 * specifically disconnect_notify,
24 * client_get_address and receive_done (resume processing)
25 */
26#include "platform.h"
27#include "gnunet_common.h"
28#include "gnunet_scheduler_lib.h"
29#include "gnunet_client_lib.h"
30#include "gnunet_server_lib.h"
31#include "gnunet_time_lib.h"
32
33#define VERBOSE GNUNET_NO
34
35#define PORT 22335
36
37#define MY_TYPE 128
38
39
40static struct GNUNET_SERVER_Handle *server;
41
42static struct GNUNET_CLIENT_Connection *client;
43
44static struct GNUNET_SCHEDULER_Handle *sched;
45
46static struct GNUNET_CONFIGURATION_Handle *cfg;
47
48static int ok;
49
50static void
51send_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
52{
53 struct GNUNET_SERVER_Client *argclient = cls;
54 GNUNET_assert (ok == 3);
55 ok++;
56 GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
57}
58
59
60static void
61recv_cb (void *cls,
62 struct GNUNET_SERVER_Handle *server,
63 struct GNUNET_SERVER_Client *argclient,
64 const struct GNUNET_MessageHeader *message)
65{
66 void *addr;
67 size_t addrlen;
68 struct sockaddr_in sa;
69 struct sockaddr_in *have;
70
71 GNUNET_assert (GNUNET_OK ==
72 GNUNET_SERVER_client_get_address (argclient,
73 &addr, &addrlen));
74
75 GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
76 have = addr;
77 memset (&sa, 0, sizeof (sa));
78 sa.sin_family = AF_INET;
79 sa.sin_port = have->sin_port;
80 sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
81 GNUNET_assert (0 == memcmp (&sa, addr, addrlen));
82 GNUNET_free (addr);
83 switch (ok)
84 {
85 case 2:
86 ok++;
87 GNUNET_SCHEDULER_add_delayed (sched,
88 GNUNET_YES,
89 GNUNET_SCHEDULER_PRIORITY_KEEP,
90 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
91 GNUNET_TIME_relative_multiply
92 (GNUNET_TIME_UNIT_MILLISECONDS, 50),
93 &send_done, argclient);
94 break;
95 case 4:
96 ok++;
97 GNUNET_CLIENT_disconnect (client);
98 GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
99 break;
100 default:
101 GNUNET_assert (0);
102 }
103
104}
105
106
107/**
108 * Functions with this signature are called whenever a client
109 * is disconnected on the network level.
110 *
111 * @param cls closure
112 * @param client identification of the client
113 */
114static void
115notify_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
116{
117 GNUNET_assert (ok == 5);
118 ok = 0;
119 GNUNET_SCHEDULER_shutdown (sched);
120 GNUNET_CONFIGURATION_destroy (cfg);
121}
122
123
124static size_t
125notify_ready (void *cls, size_t size, void *buf)
126{
127 struct GNUNET_MessageHeader *msg;
128
129 GNUNET_assert (size >= 256);
130 GNUNET_assert (1 == ok);
131 ok++;
132 msg = buf;
133 msg->type = htons (MY_TYPE);
134 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
135 msg++;
136 msg->type = htons (MY_TYPE);
137 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
138 return 2 * sizeof (struct GNUNET_MessageHeader);
139}
140
141
142static struct GNUNET_SERVER_MessageHandler handlers[] = {
143 {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)},
144 {NULL, NULL, 0, 0}
145};
146
147
148static void
149task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
150{
151 struct sockaddr_in sa;
152
153 sched = tc->sched;
154 memset (&sa, 0, sizeof (sa));
155 sa.sin_family = AF_INET;
156 sa.sin_port = htons (PORT);
157 server = GNUNET_SERVER_create (tc->sched,
158 NULL,
159 NULL,
160 (const struct sockaddr *) &sa,
161 sizeof (sa),
162 1024,
163 GNUNET_TIME_relative_multiply
164 (GNUNET_TIME_UNIT_MILLISECONDS, 250),
165 GNUNET_NO);
166 GNUNET_assert (server != NULL);
167 handlers[0].callback_cls = cls;
168 GNUNET_SERVER_add_handlers (server, handlers);
169 GNUNET_SERVER_disconnect_notify (server, &notify_disconnect, cls);
170 cfg = GNUNET_CONFIGURATION_create ();
171 GNUNET_CONFIGURATION_set_value_number (cfg, "test", "PORT", PORT);
172 GNUNET_CONFIGURATION_set_value_string (cfg, "test", "HOSTNAME",
173 "localhost");
174 client = GNUNET_CLIENT_connect (tc->sched, "test", cfg);
175 GNUNET_assert (client != NULL);
176 GNUNET_CLIENT_notify_transmit_ready (client,
177 256,
178 GNUNET_TIME_relative_multiply
179 (GNUNET_TIME_UNIT_MILLISECONDS, 250),
180 &notify_ready, NULL);
181}
182
183
184/**
185 * Main method, starts scheduler with task1,
186 * checks that "ok" is correct at the end.
187 */
188static int
189check ()
190{
191
192 ok = 1;
193 GNUNET_SCHEDULER_run (&task, NULL);
194 return ok;
195}
196
197
198int
199main (int argc, char *argv[])
200{
201 int ret = 0;
202
203 GNUNET_log_setup ("test_server_with_client",
204#if VERBOSE
205 "DEBUG",
206#else
207 "WARNING",
208#endif
209 NULL);
210 ret += check ();
211
212 return ret;
213}
214
215/* end of test_server_with_client.c */
diff --git a/src/util/test_service.c b/src/util/test_service.c
new file mode 100644
index 000000000..b5cf0805e
--- /dev/null
+++ b/src/util/test_service.c
@@ -0,0 +1,337 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_service.c
22 * @brief tests for service.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_client_lib.h"
27#include "gnunet_getopt_lib.h"
28#include "gnunet_program_lib.h"
29#include "gnunet_service_lib.h"
30#include "gnunet_scheduler_lib.h"
31#include "gnunet_time_lib.h"
32
33#define VERBOSE GNUNET_NO
34
35#define PORT 12435
36
37#define MY_TYPE 256
38
39static struct GNUNET_SCHEDULER_Handle *sched;
40
41static struct GNUNET_SERVICE_Context *sctx;
42
43static void
44end_it (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
45{
46 struct GNUNET_CLIENT_Connection *client = cls;
47
48 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down service\n");
49 GNUNET_CLIENT_service_shutdown (client);
50 GNUNET_CLIENT_disconnect (client);
51 if (sctx != NULL)
52 GNUNET_SERVICE_stop (sctx);
53}
54
55
56static size_t
57build_msg (void *cls, size_t size, void *buf)
58{
59 struct GNUNET_CLIENT_Connection *client = cls;
60 struct GNUNET_MessageHeader *msg = buf;
61
62 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client connected, transmitting\n");
63 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
64 msg->type = htons (MY_TYPE);
65 msg->size = htons (sizeof (msg));
66 GNUNET_SCHEDULER_add_continuation (sched,
67 GNUNET_YES,
68 &end_it,
69 client,
70 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
71 return sizeof (struct GNUNET_MessageHeader);
72}
73
74static void
75ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
76{
77 struct GNUNET_CONFIGURATION_Handle *cfg = cls;
78 struct GNUNET_CLIENT_Connection *client;
79
80 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service confirmed running\n");
81 sched = tc->sched;
82 GNUNET_assert (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE));
83 client = GNUNET_CLIENT_connect (tc->sched, "test_service", cfg);
84 GNUNET_assert (client != NULL);
85 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
86 "Client connecting, waiting to transmit\n");
87 GNUNET_CLIENT_notify_transmit_ready (client,
88 sizeof (struct GNUNET_MessageHeader),
89 GNUNET_TIME_UNIT_SECONDS,
90 &build_msg, client);
91}
92
93static void
94recv_cb (void *cls,
95 struct GNUNET_SERVER_Handle *server,
96 struct GNUNET_SERVER_Client *client,
97 const struct GNUNET_MessageHeader *message)
98{
99 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receiving client message...\n");
100 GNUNET_SERVER_receive_done (client, GNUNET_OK);
101}
102
103static struct GNUNET_SERVER_MessageHandler myhandlers[] = {
104 {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)},
105 {NULL, NULL, 0, 0}
106};
107
108static void
109runner (void *cls,
110 struct GNUNET_SCHEDULER_Handle *sched,
111 struct GNUNET_SERVER_Handle *server,
112 struct GNUNET_CONFIGURATION_Handle *cfg)
113{
114 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service initializing\n");
115 GNUNET_SERVER_add_handlers (server, myhandlers);
116 GNUNET_CLIENT_service_test (sched,
117 "test_service",
118 cfg, GNUNET_TIME_UNIT_SECONDS, &ready, cfg);
119}
120
121static void
122term (void *cls, struct GNUNET_CONFIGURATION_Handle *cfg)
123{
124 int *ok = cls;
125 *ok = 0;
126}
127
128/**
129 * Main method, starts scheduler with task1,
130 * checks that "ok" is correct at the end.
131 */
132static int
133check ()
134{
135 int ok = 1;
136 char *const argv[] = {
137 "test_service",
138 "-c",
139 "test_service_data.conf",
140 "-L",
141#if VERBOSE
142 "DEBUG",
143#else
144 "WARNING",
145#endif
146 NULL
147 };
148 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting service\n");
149 GNUNET_assert (GNUNET_OK ==
150 GNUNET_SERVICE_run (5,
151 argv,
152 "test_service",
153 &runner, &ok, &term, &ok));
154 GNUNET_assert (0 == ok);
155 return ok;
156}
157
158static void
159ready6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
160{
161 struct GNUNET_CONFIGURATION_Handle *cfg = cls;
162 struct GNUNET_CLIENT_Connection *client;
163
164 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "V6 ready\n");
165 sched = tc->sched;
166 GNUNET_assert (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE));
167 client = GNUNET_CLIENT_connect (tc->sched, "test_service6", cfg);
168 GNUNET_assert (client != NULL);
169 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "V6 client connected\n");
170 GNUNET_CLIENT_notify_transmit_ready (client,
171 sizeof (struct GNUNET_MessageHeader),
172 GNUNET_TIME_UNIT_SECONDS,
173 &build_msg, client);
174}
175
176static void
177runner6 (void *cls,
178 struct GNUNET_SCHEDULER_Handle *sched,
179 struct GNUNET_SERVER_Handle *server,
180 struct GNUNET_CONFIGURATION_Handle *cfg)
181{
182 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initializing v6 service\n");
183 GNUNET_SERVER_add_handlers (server, myhandlers);
184 GNUNET_CLIENT_service_test (sched,
185 "test_service6",
186 cfg, GNUNET_TIME_UNIT_SECONDS, &ready6, cfg);
187}
188
189/**
190 * Main method, starts scheduler with task1,
191 * checks that "ok" is correct at the end.
192 */
193static int
194check6 ()
195{
196 int ok = 1;
197 char *const argv[] = {
198 "test_service6",
199 "-c",
200 "test_service_data.conf",
201 "-L",
202#if VERBOSE
203 "DEBUG",
204#else
205 "WARNING",
206#endif
207 NULL
208 };
209 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting v6 service\n");
210 GNUNET_assert (GNUNET_OK ==
211 GNUNET_SERVICE_run (5,
212 argv,
213 "test_service6",
214 &runner6, &ok, &term, &ok));
215 GNUNET_assert (0 == ok);
216 return ok;
217}
218
219
220/**
221 * Main method, starts scheduler with task1,
222 * checks that "ok" is correct at the end.
223 */
224static int
225check6d ()
226{
227 int ok = 1;
228 char *const argv[] = {
229 "test_service6",
230 "-c",
231 "test_service_data.conf",
232 "-L",
233#if VERBOSE
234 "DEBUG",
235#else
236 "WARNING",
237#endif
238 "-d",
239 NULL
240 };
241 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting V6 as daemon\n");
242 GNUNET_assert (GNUNET_OK ==
243 GNUNET_SERVICE_run (6,
244 argv,
245 "test_service6",
246 &runner6, &ok, &term, &ok));
247 GNUNET_break (0 == ok);
248 return ok;
249}
250
251
252static void
253start_stop_main (void *cls,
254 struct GNUNET_SCHEDULER_Handle *sched,
255 char *const *args,
256 const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *cfg)
257{
258 int *ret = cls;
259 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
260 "Starting service using start method\n");
261 sctx = GNUNET_SERVICE_start ("test_service", sched, cfg);
262 runner (cls, sched, GNUNET_SERVICE_get_server (sctx), cfg);
263 *ret = 0;
264}
265
266
267static int
268check_start_stop ()
269{
270 char *const argv[] = {
271 "test-service-program",
272 "-c",
273 "test_service_data.conf",
274 "-L",
275#if VERBOSE
276 "DEBUG",
277#else
278 "WARNING",
279#endif
280 NULL
281 };
282 const struct GNUNET_GETOPT_CommandLineOption options[] = {
283 GNUNET_GETOPT_OPTION_END
284 };
285 int ret = 1;
286 GNUNET_assert (GNUNET_OK ==
287 GNUNET_PROGRAM_run (5,
288 argv,
289 "test-service-program",
290 "no help",
291 options, &start_stop_main, &ret));
292
293 GNUNET_break (0 == ret);
294 return ret;
295}
296
297
298int
299main (int argc, char *argv[])
300{
301 int ret = 0;
302 int s;
303
304 GNUNET_log_setup ("test-service",
305#if VERBOSE
306 "DEBUG",
307#else
308 "WARNING",
309#endif
310 NULL);
311 ret += check ();
312 ret += check ();
313 s = SOCKET (PF_INET6, SOCK_STREAM, 0);
314 if (s == -1)
315 {
316 if ((errno == ENOBUFS) ||
317 (errno == ENOMEM) || (errno == ENFILE) || (errno == EACCES))
318 {
319 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
320 return 1;
321 }
322 fprintf (stderr,
323 "IPv6 support seems to not be available (%s), not testing it!\n",
324 strerror (errno));
325 }
326 else
327 {
328 GNUNET_break (0 == CLOSE (s));
329 ret += check6 ();
330 ret += check6d (); /* with daemonization */
331 }
332 ret += check_start_stop ();
333
334 return ret;
335}
336
337/* end of test_service.c */
diff --git a/src/util/test_service_data.conf b/src/util/test_service_data.conf
new file mode 100644
index 000000000..92c723619
--- /dev/null
+++ b/src/util/test_service_data.conf
@@ -0,0 +1,26 @@
1[test_service]
2PORT=12435
3BINDTO=localhost
4PIDFILE=/tmp/test-service.pid
5TIMEOUT=30000
6MAXBUF=1024
7DISABLEV6=NO
8ACCEPT_FROM=127.0.0.1;
9REJECT_FROM=1.2.3.0/15;4.5.0.0/8;6.7.8.9/255.255.255.0;
10ACCEPT_FROM6=::1;
11REJECT_FROM6=AB:CD:EF::00;AB:CD::00/40;
12HOSTNAME=localhost
13ALLOW_SHUTDOWN=YES
14
15[test_service6]
16PORT=12435
17PIDFILE=/tmp/test-service.pid
18TIMEOUT=30000
19MAXBUF=1024
20DISABLEV6=NO
21ACCEPT_FROM=127.0.0.1;
22REJECT_FROM=1.2.3.0/15;4.5.0.0/8;6.7.8.9/255.255.255.0;
23ACCEPT_FROM6=::1;
24REJECT_FROM6=AB:CD:EF::00;AB:CD::00/40;
25HOSTNAME=::1
26ALLOW_SHUTDOWN=YES
diff --git a/src/util/test_strings.c b/src/util/test_strings.c
new file mode 100644
index 000000000..be166e629
--- /dev/null
+++ b/src/util/test_strings.c
@@ -0,0 +1,111 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 util/test_strings.c
22 * @brief testcase for strings.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_strings_lib.h"
27
28#define VERBOSE GNUNET_NO
29
30#define WANT(a,b) if (0 != strcmp(a,b)) { fprintf(stderr, "Got `%s', wanted `%s'\n", b, a); GNUNET_free(b); GNUNET_break(0); return 1;} else { GNUNET_free (b); }
31#define WANTB(a,b,l) if (0 != memcmp(a,b,l)) { GNUNET_break(0); return 1;} else { }
32
33static int
34check ()
35{
36 char buf[128];
37 char *r;
38 char *b;
39 struct GNUNET_TIME_Absolute at;
40
41 sprintf (buf, "4%s", _( /* size unit */ "b"));
42 b = GNUNET_STRINGS_byte_size_fancy (4);
43 WANT (buf, b);
44 sprintf (buf, "10%s", _( /* size unit */ "KiB"));
45 b = GNUNET_STRINGS_byte_size_fancy (10240);
46 WANT (buf, b);
47 sprintf (buf, "10%s", _( /* size unit */ "TiB"));
48 b = GNUNET_STRINGS_byte_size_fancy (10240LL * 1024LL * 1024LL * 1024LL);
49 WANT (buf, b);
50 sprintf (buf, "4%s", _( /* time unit */ "ms"));
51 b =
52 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_relative_multiply
53 (GNUNET_TIME_UNIT_MILLISECONDS,
54 4));
55 WANT (buf, b);
56 sprintf (buf, "7%s", _( /* time unit */ "s"));
57 b =
58 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_relative_multiply
59 (GNUNET_TIME_UNIT_MILLISECONDS,
60 7 * 1000));
61 WANT (buf, b);
62 sprintf (buf, "7%s", _( /* time unit */ "h"));
63 b =
64 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_relative_multiply
65 (GNUNET_TIME_UNIT_MILLISECONDS,
66 7 * 60 * 60 * 1000));
67 WANT (buf, b);
68 sprintf (buf, "%s%s", getenv ("HOME"), DIR_SEPARATOR_STR);
69 b = GNUNET_STRINGS_filename_expand ("~");
70 WANT (buf, b);
71 GNUNET_STRINGS_buffer_fill (buf, sizeof (buf), 3, "a", "btx", "c");
72 WANTB ("a\0btx\0c", buf, 8);
73 if (6 != GNUNET_STRINGS_buffer_tokenize (buf, sizeof (buf), 2, &r, &b))
74 return 1;
75 r = GNUNET_strdup (r);
76 WANT ("a", r);
77 b = GNUNET_strdup (b);
78 WANT ("btx", b);
79 if (0 != GNUNET_STRINGS_buffer_tokenize (buf, 2, 2, &r, &b))
80 return 1;
81 at.value = 5000;
82 r = GNUNET_STRINGS_absolute_time_to_string (at);
83 /* r should be something like "Wed Dec 31 17:00:05 1969"
84 where the details of the day and hour depend on the timezone;
85 however, the "0:05 19" should always be there; hence: */
86 if (NULL == strstr (r, "0:05 19"))
87 {
88 fprintf (stderr, "Got %s\n", r);
89 GNUNET_break (0);
90 GNUNET_free (r);
91 return 1;
92 }
93 b = GNUNET_STRINGS_to_utf8 ("TEST", 4, "ASCII");
94 WANT ("TEST", b);
95 b = GNUNET_STRINGS_to_utf8 ("TEST", 4, "unknown");
96 WANT ("TEST", b);
97 GNUNET_free (r);
98 return 0;
99}
100
101int
102main (int argc, char *argv[])
103{
104 int ret;
105
106 GNUNET_log_setup ("test_strings", "ERROR", NULL);
107 ret = check ();
108 return ret;
109}
110
111/* end of test_strings.c */
diff --git a/src/util/test_time.c b/src/util/test_time.c
new file mode 100644
index 000000000..9505952c2
--- /dev/null
+++ b/src/util/test_time.c
@@ -0,0 +1,122 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2006, 2009 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 2, 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 util/test_time.c
22 * @brief testcase for time.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_time_lib.h"
27
28#define VERBOSE GNUNET_NO
29
30static int
31check ()
32{
33 struct GNUNET_TIME_Absolute now;
34 struct GNUNET_TIME_AbsoluteNBO nown;
35 struct GNUNET_TIME_Absolute future;
36 struct GNUNET_TIME_Absolute past;
37 struct GNUNET_TIME_Absolute last;
38 struct GNUNET_TIME_Relative rel;
39 struct GNUNET_TIME_RelativeNBO reln;
40 unsigned int i;
41
42 last = now = GNUNET_TIME_absolute_get ();
43 while (now.value == last.value)
44 now = GNUNET_TIME_absolute_get ();
45 GNUNET_assert (now.value > last.value);
46
47 /* test overflow checking in multiply */
48 rel = GNUNET_TIME_UNIT_SECONDS;
49 GNUNET_log_skip (1);
50 for (i = 0; i < 55; i++)
51 rel = GNUNET_TIME_relative_multiply (rel, 2);
52 GNUNET_log_skip (0);
53 GNUNET_assert (rel.value == GNUNET_TIME_UNIT_FOREVER_REL.value);
54
55 /* test infinity-check for relative to absolute */
56 last = GNUNET_TIME_relative_to_absolute (rel);
57 GNUNET_assert (last.value == GNUNET_TIME_UNIT_FOREVER_ABS.value);
58
59 /* check overflow for r2a */
60 rel.value = ((uint64_t) - 1LL) - 1024;
61 GNUNET_log_skip (1);
62 last = GNUNET_TIME_relative_to_absolute (rel);
63 GNUNET_log_skip (0);
64 GNUNET_assert (last.value == GNUNET_TIME_UNIT_FOREVER_ABS.value);
65
66 /* check overflow for relative add */
67 GNUNET_log_skip (1);
68 rel = GNUNET_TIME_relative_add (rel, rel);
69 GNUNET_log_skip (0);
70 GNUNET_assert (rel.value == GNUNET_TIME_UNIT_FOREVER_REL.value);
71
72 /* check relation check in get_duration */
73 future.value = now.value + 1000000;
74 GNUNET_assert (GNUNET_TIME_absolute_get_difference (now, future).value ==
75 1000000);
76 GNUNET_assert (GNUNET_TIME_absolute_get_difference (future, now).value ==
77 0);
78
79 past.value = now.value - 1000000;
80 rel = GNUNET_TIME_absolute_get_duration (future);
81 GNUNET_assert (rel.value == 0);
82 rel = GNUNET_TIME_absolute_get_duration (past);
83 GNUNET_assert (rel.value >= 1000000);
84
85 /* check get remaining */
86 rel = GNUNET_TIME_absolute_get_remaining (now);
87 GNUNET_assert (rel.value == 0);
88 rel = GNUNET_TIME_absolute_get_remaining (past);
89 GNUNET_assert (rel.value == 0);
90 rel = GNUNET_TIME_absolute_get_remaining (future);
91 GNUNET_assert (rel.value > 0);
92 GNUNET_assert (rel.value <= 1000000);
93
94 /* check endianess */
95 reln = GNUNET_TIME_relative_hton (rel);
96 GNUNET_assert (rel.value == GNUNET_TIME_relative_ntoh (reln).value);
97 nown = GNUNET_TIME_absolute_hton (now);
98 GNUNET_assert (now.value == GNUNET_TIME_absolute_ntoh (nown).value);
99
100 /* check absolute addition */
101 future = GNUNET_TIME_absolute_add (now, GNUNET_TIME_UNIT_SECONDS);
102 GNUNET_assert (future.value == now.value + 1000);
103
104 /* check zero */
105 future = GNUNET_TIME_absolute_add (now, GNUNET_TIME_UNIT_ZERO);
106 GNUNET_assert (future.value == now.value);
107
108 return 0;
109}
110
111int
112main (int argc, char *argv[])
113{
114 int ret;
115
116 GNUNET_log_setup ("test-time", "WARNING", NULL);
117 ret = check ();
118
119 return ret;
120}
121
122/* end of test_time.c */
diff --git a/src/util/time.c b/src/util/time.c
new file mode 100644
index 000000000..3ae472561
--- /dev/null
+++ b/src/util/time.c
@@ -0,0 +1,286 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2006, 2009 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 2, 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 util/time.c
23 * @author Christian Grothoff
24 * @brief functions for handling time and time arithmetic
25 */
26#include "platform.h"
27#include "gnunet_time_lib.h"
28
29
30/**
31 * Get the current time (works just as "time", just that we use the
32 * unit of time that the cron-jobs use (and is 64 bit)).
33 *
34 * @return the current time
35 */
36struct GNUNET_TIME_Absolute
37GNUNET_TIME_absolute_get ()
38{
39 struct GNUNET_TIME_Absolute ret;
40 struct timeval tv;
41
42 gettimeofday (&tv, NULL);
43 ret.value = tv.tv_sec * 1000 + tv.tv_usec / 1000;
44 return ret;
45}
46
47
48/**
49 * Return relative time of 0ms.
50 */
51struct GNUNET_TIME_Relative
52GNUNET_TIME_relative_get_zero ()
53{
54 static struct GNUNET_TIME_Relative zero;
55 return zero;
56}
57
58/**
59 * Return relative time of 1ms.
60 */
61struct GNUNET_TIME_Relative
62GNUNET_TIME_relative_get_unit ()
63{
64 static struct GNUNET_TIME_Relative one = { 1 };
65 return one;
66}
67
68/**
69 * Return "forever".
70 */
71struct GNUNET_TIME_Relative
72GNUNET_TIME_relative_get_forever ()
73{
74 static struct GNUNET_TIME_Relative forever = { (uint64_t) - 1LL };
75 return forever;
76}
77
78/**
79 * Return "forever".
80 */
81struct GNUNET_TIME_Absolute
82GNUNET_TIME_absolute_get_forever ()
83{
84 static struct GNUNET_TIME_Absolute forever = { (uint64_t) - 1LL };
85 return forever;
86}
87
88/**
89 * Convert relative time to an absolute time in the
90 * future.
91 *
92 * @return timestamp that is "rel" in the future, or FOREVER if rel==FOREVER (or if we would overflow)
93 */
94struct GNUNET_TIME_Absolute
95GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel)
96{
97 struct GNUNET_TIME_Absolute ret;
98 if (rel.value == (uint64_t) - 1LL)
99 return GNUNET_TIME_absolute_get_forever ();
100 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
101 if (rel.value + now.value < rel.value)
102 {
103 GNUNET_break (0); /* overflow... */
104 return GNUNET_TIME_absolute_get_forever ();
105 }
106 ret.value = rel.value + now.value;
107 return ret;
108}
109
110/**
111 * Given a timestamp in the future, how much time
112 * remains until then?
113 *
114 * @return future - now, or 0 if now >= future, or FOREVER if future==FOREVER.
115 */
116struct GNUNET_TIME_Relative
117GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future)
118{
119 struct GNUNET_TIME_Relative ret;
120 if (future.value == (uint64_t) - 1LL)
121 return GNUNET_TIME_relative_get_forever ();
122 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
123 if (now.value > future.value)
124 return GNUNET_TIME_relative_get_zero ();
125 ret.value = future.value - now.value;
126 return ret;
127}
128
129/**
130 * Compute the time difference between the given start and end times.
131 * Use this function instead of actual subtraction to ensure that
132 * "FOREVER" and overflows are handeled correctly.
133 *
134 * @return 0 if start >= end; FOREVER if end==FOREVER; otherwise end - start
135 */
136struct GNUNET_TIME_Relative
137GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start,
138 struct GNUNET_TIME_Absolute end)
139{
140 struct GNUNET_TIME_Relative ret;
141 if (end.value == (uint64_t) - 1LL)
142 return GNUNET_TIME_relative_get_forever ();
143 if (end.value < start.value)
144 return GNUNET_TIME_relative_get_zero ();
145 ret.value = end.value - start.value;
146 return ret;
147}
148
149/**
150 * Get the duration of an operation as the
151 * difference of the current time and the given start time "hence".
152 *
153 * @return aborts if hence==FOREVER, 0 if hence > now, otherwise now-hence.
154 */
155struct GNUNET_TIME_Relative
156GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute hence)
157{
158 struct GNUNET_TIME_Absolute now;
159 struct GNUNET_TIME_Relative ret;
160
161 now = GNUNET_TIME_absolute_get ();
162 GNUNET_assert (hence.value != (uint64_t) - 1LL);
163 if (hence.value > now.value)
164 return GNUNET_TIME_relative_get_zero ();
165 ret.value = now.value - hence.value;
166 return ret;
167}
168
169
170/**
171 * Add a given relative duration to the
172 * given start time.
173 *
174 * @return FOREVER if either argument is FOREVER or on overflow; start+duration otherwise
175 */
176struct GNUNET_TIME_Absolute
177GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start,
178 struct GNUNET_TIME_Relative duration)
179{
180 struct GNUNET_TIME_Absolute ret;
181
182 if ((start.value == (uint64_t) - 1LL) ||
183 (duration.value == (uint64_t) - 1LL))
184 return GNUNET_TIME_absolute_get_forever ();
185 if (start.value + duration.value < start.value)
186 {
187 GNUNET_break (0);
188 return GNUNET_TIME_absolute_get_forever ();
189 }
190 ret.value = start.value + duration.value;
191 return ret;
192}
193
194/**
195 * Multiply relative time by a given factor.
196 *
197 * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
198 */
199struct GNUNET_TIME_Relative
200GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
201 unsigned int factor)
202{
203 struct GNUNET_TIME_Relative ret;
204 if (factor == 0)
205 return GNUNET_TIME_relative_get_zero ();
206 ret.value = rel.value * factor;
207 if (ret.value / factor != rel.value)
208 {
209 GNUNET_break (0);
210 return GNUNET_TIME_relative_get_forever ();
211 }
212 return ret;
213}
214
215/**
216 * Add relative times together.
217 *
218 * @return FOREVER if either argument is FOREVER or on overflow; a1+a2 otherwise
219 */
220struct GNUNET_TIME_Relative
221GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1,
222 struct GNUNET_TIME_Relative a2)
223{
224 struct GNUNET_TIME_Relative ret;
225
226 if ((a1.value == (uint64_t) - 1LL) || (a2.value == (uint64_t) - 1LL))
227 return GNUNET_TIME_relative_get_forever ();
228 if (a1.value + a2.value < a1.value)
229 {
230 GNUNET_break (0);
231 return GNUNET_TIME_relative_get_forever ();
232 }
233 ret.value = a1.value + a2.value;
234 return ret;
235}
236
237
238/**
239 * Convert relative time to network byte order.
240 */
241struct GNUNET_TIME_RelativeNBO
242GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a)
243{
244 struct GNUNET_TIME_RelativeNBO ret;
245 ret.value = GNUNET_htonll (a.value);
246 return ret;
247}
248
249/**
250 * Convert relative time from network byte order.
251 */
252struct GNUNET_TIME_Relative
253GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a)
254{
255 struct GNUNET_TIME_Relative ret;
256 ret.value = GNUNET_ntohll (a.value);
257 return ret;
258
259}
260
261/**
262 * Convert absolute time to network byte order.
263 */
264struct GNUNET_TIME_AbsoluteNBO
265GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a)
266{
267 struct GNUNET_TIME_AbsoluteNBO ret;
268 ret.value = GNUNET_htonll (a.value);
269 return ret;
270}
271
272/**
273 * Convert absolute time from network byte order.
274 */
275struct GNUNET_TIME_Absolute
276GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
277{
278 struct GNUNET_TIME_Absolute ret;
279 ret.value = GNUNET_ntohll (a.value);
280 return ret;
281
282}
283
284
285
286/* end of time.c */