diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/transport/Makefile.am | 84 | ||||
-rw-r--r-- | src/transport/plugin_transport_udp.c | 2 | ||||
-rw-r--r-- | src/transport/plugin_transport_unix.c | 1155 | ||||
-rw-r--r-- | src/transport/test_quota_compliance.c | 25 | ||||
-rw-r--r-- | src/transport/test_quota_compliance_unix_peer1.conf | 104 | ||||
-rw-r--r-- | src/transport/test_quota_compliance_unix_peer2.conf | 102 | ||||
-rw-r--r-- | src/transport/test_transport_api.c | 12 | ||||
-rw-r--r-- | src/transport/test_transport_api_reliability.c | 24 | ||||
-rw-r--r-- | src/transport/test_transport_api_unix_peer1.conf | 110 | ||||
-rw-r--r-- | src/transport/test_transport_api_unix_peer2.conf | 108 | ||||
-rw-r--r-- | src/transport/test_transport_api_unreliability.c | 922 |
11 files changed, 2632 insertions, 16 deletions
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index 0498408f2..c3b90cc9d 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am | |||
@@ -43,6 +43,10 @@ endif | |||
43 | endif | 43 | endif |
44 | 44 | ||
45 | if LINUX | 45 | if LINUX |
46 | UNIX_PLUGIN_LA = libgnunet_plugin_transport_unix.la | ||
47 | UNIX_PLUGIN_TEST = test_transport_api_unix | ||
48 | UNIX_REL_TEST = test_transport_api_unreliability_unix | ||
49 | UNIX_QUOTA_TEST = test_quota_compliance_unix | ||
46 | NATBIN = gnunet-nat-server gnunet-nat-client | 50 | NATBIN = gnunet-nat-server gnunet-nat-client |
47 | install-exec-hook: | 51 | install-exec-hook: |
48 | chown root $(bindir)/gnunet-nat-server $(bindir)/gnunet-nat-client $(bindir)/gnunet-wlan || true | 52 | chown root $(bindir)/gnunet-nat-server $(bindir)/gnunet-nat-client $(bindir)/gnunet-wlan || true |
@@ -114,6 +118,7 @@ gnunet_service_transport_DEPENDENCIES = \ | |||
114 | plugin_LTLIBRARIES = \ | 118 | plugin_LTLIBRARIES = \ |
115 | libgnunet_plugin_transport_tcp.la \ | 119 | libgnunet_plugin_transport_tcp.la \ |
116 | libgnunet_plugin_transport_udp.la \ | 120 | libgnunet_plugin_transport_udp.la \ |
121 | $(UNIX_PLUGIN_LA) \ | ||
117 | $(HTTP_PLUGIN_LA) \ | 122 | $(HTTP_PLUGIN_LA) \ |
118 | $(HTTPS_PLUGIN_LA) \ | 123 | $(HTTPS_PLUGIN_LA) \ |
119 | $(WLAN_PLUGIN_LA) \ | 124 | $(WLAN_PLUGIN_LA) \ |
@@ -157,16 +162,16 @@ libgnunet_plugin_transport_udp_la_LIBADD = \ | |||
157 | $(top_builddir)/src/util/libgnunetutil.la | 162 | $(top_builddir)/src/util/libgnunetutil.la |
158 | libgnunet_plugin_transport_udp_la_LDFLAGS = \ | 163 | libgnunet_plugin_transport_udp_la_LDFLAGS = \ |
159 | $(GN_PLUGIN_LDFLAGS) | 164 | $(GN_PLUGIN_LDFLAGS) |
160 | 165 | ||
161 | #libgnunet_plugin_transport_udp_nat_la_SOURCES = \ | 166 | libgnunet_plugin_transport_unix_la_SOURCES = \ |
162 | # plugin_transport_udp_nat.c | 167 | plugin_transport_unix.c |
163 | #libgnunet_plugin_transport_udp_nat_la_LIBADD = \ | 168 | libgnunet_plugin_transport_unix_la_LIBADD = \ |
164 | # $(top_builddir)/src/hello/libgnunethello.la \ | 169 | $(top_builddir)/src/hello/libgnunethello.la \ |
165 | # $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 170 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
166 | # $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ | 171 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ |
167 | # $(top_builddir)/src/util/libgnunetutil.la | 172 | $(top_builddir)/src/util/libgnunetutil.la |
168 | #libgnunet_plugin_transport_udp_nat_la_LDFLAGS = \ | 173 | libgnunet_plugin_transport_unix_la_LDFLAGS = \ |
169 | # $(GN_PLUGIN_LDFLAGS) | 174 | $(GN_PLUGIN_LDFLAGS) |
170 | 175 | ||
171 | libgnunet_plugin_transport_http_la_SOURCES = \ | 176 | libgnunet_plugin_transport_http_la_SOURCES = \ |
172 | plugin_transport_http.c | 177 | plugin_transport_http.c |
@@ -199,6 +204,7 @@ check_PROGRAMS = \ | |||
199 | test_transport_api_tcp \ | 204 | test_transport_api_tcp \ |
200 | test_transport_api_tcp_nat \ | 205 | test_transport_api_tcp_nat \ |
201 | test_transport_api_udp \ | 206 | test_transport_api_udp \ |
207 | $(UNIX_PLUGIN_TEST) \ | ||
202 | test_transport_api_udp_nat \ | 208 | test_transport_api_udp_nat \ |
203 | $(HTTP_PLUGIN_TEST) \ | 209 | $(HTTP_PLUGIN_TEST) \ |
204 | $(HTTP_API_TEST) \ | 210 | $(HTTP_API_TEST) \ |
@@ -208,13 +214,16 @@ check_PROGRAMS = \ | |||
208 | test_transport_api_multi \ | 214 | test_transport_api_multi \ |
209 | test_transport_api_reliability_tcp \ | 215 | test_transport_api_reliability_tcp \ |
210 | test_transport_api_reliability_tcp_nat \ | 216 | test_transport_api_reliability_tcp_nat \ |
211 | test_transport_api_reliability_udp \ | 217 | test_transport_api_unreliability_udp \ |
218 | test_transport_api_unreliability_unix \ | ||
219 | $(UNIX_REL_TEST) \ | ||
212 | $(HTTP_REL_TEST) \ | 220 | $(HTTP_REL_TEST) \ |
213 | $(HTTPS_REL_TEST) \ | 221 | $(HTTPS_REL_TEST) \ |
214 | test_quota_compliance_tcp \ | 222 | test_quota_compliance_tcp \ |
215 | test_quota_compliance_tcp_asymmetric_recv_constant \ | 223 | test_quota_compliance_tcp_asymmetric_recv_constant \ |
216 | test_quota_compliance_udp \ | 224 | test_quota_compliance_udp \ |
217 | test_quota_compliance_udp_asymmetric_recv_constant \ | 225 | test_quota_compliance_udp_asymmetric_recv_constant \ |
226 | $(UNIX_QUOTA_TEST) \ | ||
218 | $(HTTP_QUOTA_TEST) \ | 227 | $(HTTP_QUOTA_TEST) \ |
219 | $(HTTPS_QUOTA_TEST) | 228 | $(HTTPS_QUOTA_TEST) |
220 | # TODO: add tests for nat, etc. | 229 | # TODO: add tests for nat, etc. |
@@ -224,6 +233,7 @@ TESTS = \ | |||
224 | test_transport_api_tcp \ | 233 | test_transport_api_tcp \ |
225 | test_transport_api_tcp_nat \ | 234 | test_transport_api_tcp_nat \ |
226 | test_transport_api_udp \ | 235 | test_transport_api_udp \ |
236 | $(UNIX_PLUGIN_TEST) \ | ||
227 | test_transport_api_udp_nat \ | 237 | test_transport_api_udp_nat \ |
228 | $(HTTP_PLUGIN_TEST) \ | 238 | $(HTTP_PLUGIN_TEST) \ |
229 | $(HTTP_API_TEST) \ | 239 | $(HTTP_API_TEST) \ |
@@ -233,12 +243,15 @@ TESTS = \ | |||
233 | test_transport_api_multi \ | 243 | test_transport_api_multi \ |
234 | test_transport_api_reliability_tcp \ | 244 | test_transport_api_reliability_tcp \ |
235 | test_transport_api_reliability_tcp_nat \ | 245 | test_transport_api_reliability_tcp_nat \ |
246 | test_transport_api_unreliability_udp \ | ||
247 | test_transport_api_unreliability_unix \ | ||
236 | $(HTTP_REL_TEST) \ | 248 | $(HTTP_REL_TEST) \ |
237 | $(HTTPS_REL_TEST) \ | 249 | $(HTTPS_REL_TEST) \ |
238 | test_quota_compliance_tcp \ | 250 | test_quota_compliance_tcp \ |
239 | test_quota_compliance_tcp_asymmetric_recv_constant \ | 251 | test_quota_compliance_tcp_asymmetric_recv_constant \ |
240 | test_quota_compliance_udp \ | 252 | test_quota_compliance_udp \ |
241 | test_quota_compliance_udp_asymmetric_recv_constant \ | 253 | test_quota_compliance_udp_asymmetric_recv_constant \ |
254 | $(UNIX_QUOTA_TEST) \ | ||
242 | $(HTTP_QUOTA_TEST) \ | 255 | $(HTTP_QUOTA_TEST) \ |
243 | $(HTTPS_QUOTA_TEST) | 256 | $(HTTPS_QUOTA_TEST) |
244 | endif | 257 | endif |
@@ -271,19 +284,31 @@ test_transport_api_reliability_udp_SOURCES = \ | |||
271 | test_transport_api_reliability.c | 284 | test_transport_api_reliability.c |
272 | test_transport_api_reliability_udp_LDADD = \ | 285 | test_transport_api_reliability_udp_LDADD = \ |
273 | $(top_builddir)/src/transport/libgnunettransport.la \ | 286 | $(top_builddir)/src/transport/libgnunettransport.la \ |
274 | $(top_builddir)/src/util/libgnunetutil.la | 287 | $(top_builddir)/src/util/libgnunetutil.la |
288 | |||
289 | test_transport_api_reliability_unix_SOURCES = \ | ||
290 | test_transport_api_reliability.c | ||
291 | test_transport_api_reliability_unix_LDADD = \ | ||
292 | $(top_builddir)/src/transport/libgnunettransport.la \ | ||
293 | $(top_builddir)/src/util/libgnunetutil.la | ||
275 | 294 | ||
276 | test_transport_api_udp_SOURCES = \ | 295 | test_transport_api_udp_SOURCES = \ |
277 | test_transport_api.c | 296 | test_transport_api.c |
278 | test_transport_api_udp_LDADD = \ | 297 | test_transport_api_udp_LDADD = \ |
279 | $(top_builddir)/src/transport/libgnunettransport.la \ | 298 | $(top_builddir)/src/transport/libgnunettransport.la \ |
280 | $(top_builddir)/src/util/libgnunetutil.la | 299 | $(top_builddir)/src/util/libgnunetutil.la |
281 | 300 | ||
282 | test_transport_api_udp_nat_SOURCES = \ | 301 | test_transport_api_udp_nat_SOURCES = \ |
283 | test_transport_api.c | 302 | test_transport_api.c |
284 | test_transport_api_udp_nat_LDADD = \ | 303 | test_transport_api_udp_nat_LDADD = \ |
285 | $(top_builddir)/src/transport/libgnunettransport.la \ | 304 | $(top_builddir)/src/transport/libgnunettransport.la \ |
286 | $(top_builddir)/src/util/libgnunetutil.la | 305 | $(top_builddir)/src/util/libgnunetutil.la |
306 | |||
307 | test_transport_api_unix_SOURCES = \ | ||
308 | test_transport_api.c | ||
309 | test_transport_api_unix_LDADD = \ | ||
310 | $(top_builddir)/src/transport/libgnunettransport.la \ | ||
311 | $(top_builddir)/src/util/libgnunetutil.la | ||
287 | 312 | ||
288 | test_plugin_transport_http_SOURCES = \ | 313 | test_plugin_transport_http_SOURCES = \ |
289 | test_plugin_transport_http.c | 314 | test_plugin_transport_http.c |
@@ -324,6 +349,18 @@ test_transport_api_reliability_https_SOURCES = \ | |||
324 | test_transport_api_reliability_https_LDADD = \ | 349 | test_transport_api_reliability_https_LDADD = \ |
325 | $(top_builddir)/src/transport/libgnunettransport.la \ | 350 | $(top_builddir)/src/transport/libgnunettransport.la \ |
326 | $(top_builddir)/src/util/libgnunetutil.la | 351 | $(top_builddir)/src/util/libgnunetutil.la |
352 | |||
353 | test_transport_api_unreliability_unix_SOURCES = \ | ||
354 | test_transport_api_unreliability.c | ||
355 | test_transport_api_unreliability_unix_LDADD = \ | ||
356 | $(top_builddir)/src/transport/libgnunettransport.la \ | ||
357 | $(top_builddir)/src/util/libgnunetutil.la | ||
358 | |||
359 | test_transport_api_unreliability_udp_SOURCES = \ | ||
360 | test_transport_api_unreliability.c | ||
361 | test_transport_api_unreliability_udp_LDADD = \ | ||
362 | $(top_builddir)/src/transport/libgnunettransport.la \ | ||
363 | $(top_builddir)/src/util/libgnunetutil.la | ||
327 | 364 | ||
328 | if HAVE_PCAP | 365 | if HAVE_PCAP |
329 | if LINUX | 366 | if LINUX |
@@ -407,6 +444,19 @@ test_quota_compliance_udp_asymmetric_recv_constant_LDADD = \ | |||
407 | # $(top_builddir)/src/transport/libgnunettransport.la \ | 444 | # $(top_builddir)/src/transport/libgnunettransport.la \ |
408 | # $(top_builddir)/src/util/libgnunetutil.la | 445 | # $(top_builddir)/src/util/libgnunetutil.la |
409 | 446 | ||
447 | test_quota_compliance_unix_SOURCES = \ | ||
448 | test_quota_compliance.c | ||
449 | test_quota_compliance_unix_LDADD = \ | ||
450 | $(top_builddir)/src/transport/libgnunettransport.la \ | ||
451 | $(top_builddir)/src/util/libgnunetutil.la | ||
452 | |||
453 | test_quota_compliance_unix_asymmetric_recv_constant_SOURCES = \ | ||
454 | test_quota_compliance.c | ||
455 | test_quota_compliance_unix_asymmetric_recv_constant_LDADD = \ | ||
456 | $(top_builddir)/src/transport/libgnunettransport.la \ | ||
457 | $(top_builddir)/src/util/libgnunetutil.la | ||
458 | |||
459 | |||
410 | test_transport_api_multi_SOURCES = \ | 460 | test_transport_api_multi_SOURCES = \ |
411 | test_transport_api.c | 461 | test_transport_api.c |
412 | test_transport_api_multi_LDADD = \ | 462 | test_transport_api_multi_LDADD = \ |
@@ -419,6 +469,8 @@ EXTRA_DIST = \ | |||
419 | test_transport_api_tcp_peer2.conf \ | 469 | test_transport_api_tcp_peer2.conf \ |
420 | test_transport_api_udp_peer1.conf \ | 470 | test_transport_api_udp_peer1.conf \ |
421 | test_transport_api_udp_peer2.conf \ | 471 | test_transport_api_udp_peer2.conf \ |
472 | test_transport_api_unix_peer1.conf \ | ||
473 | test_transport_api_unix_peer2.conf \ | ||
422 | test_transport_api_udp_nat_peer1.conf \ | 474 | test_transport_api_udp_nat_peer1.conf \ |
423 | test_transport_api_udp_nat_peer2.conf \ | 475 | test_transport_api_udp_nat_peer2.conf \ |
424 | test_transport_api_tcp_nat_peer1.conf \ | 476 | test_transport_api_tcp_nat_peer1.conf \ |
@@ -446,4 +498,6 @@ EXTRA_DIST = \ | |||
446 | test_quota_compliance_https_peer1.conf \ | 498 | test_quota_compliance_https_peer1.conf \ |
447 | test_quota_compliance_https_peer2.conf \ | 499 | test_quota_compliance_https_peer2.conf \ |
448 | test_quota_compliance_udp_peer1.conf \ | 500 | test_quota_compliance_udp_peer1.conf \ |
449 | test_quota_compliance_udp_peer2.conf | 501 | test_quota_compliance_udp_peer2.conf \ |
502 | test_quota_compliance_unix_peer1.conf \ | ||
503 | test_quota_compliance_unix_peer2.conf | ||
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index 21f2b17d7..ca6bbe138 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c | |||
@@ -662,6 +662,8 @@ udp_real_send (void *cls, | |||
662 | GNUNET_NETWORK_socket_sendto (send_handle, message, ssize, | 662 | GNUNET_NETWORK_socket_sendto (send_handle, message, ssize, |
663 | sb, | 663 | sb, |
664 | sbs); | 664 | sbs); |
665 | if (GNUNET_SYSERR == sent) | ||
666 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_DEBUG, "sendto"); | ||
665 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 667 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
666 | "UDP transmit %u-byte message to %s (%d: %s)\n", | 668 | "UDP transmit %u-byte message to %s (%d: %s)\n", |
667 | (unsigned int) ssize, | 669 | (unsigned int) ssize, |
diff --git a/src/transport/plugin_transport_unix.c b/src/transport/plugin_transport_unix.c new file mode 100644 index 000000000..4d08a252b --- /dev/null +++ b/src/transport/plugin_transport_unix.c | |||
@@ -0,0 +1,1155 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | (C) 2010 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file transport/plugin_transport_unix.c | ||
23 | * @brief Transport plugin using unix domain sockets (!) | ||
24 | * Clearly, can only be used locally on Unix/Linux hosts... | ||
25 | * ONLY INTENDED FOR TESTING!!! | ||
26 | * @author Christian Grothoff | ||
27 | * @author Nathan Evans | ||
28 | */ | ||
29 | |||
30 | #include "platform.h" | ||
31 | #include "gnunet_hello_lib.h" | ||
32 | #include "gnunet_connection_lib.h" | ||
33 | #include "gnunet_container_lib.h" | ||
34 | #include "gnunet_os_lib.h" | ||
35 | #include "gnunet_peerinfo_service.h" | ||
36 | #include "gnunet_protocols.h" | ||
37 | #include "gnunet_resolver_service.h" | ||
38 | #include "gnunet_server_lib.h" | ||
39 | #include "gnunet_signatures.h" | ||
40 | #include "gnunet_statistics_service.h" | ||
41 | #include "gnunet_transport_service.h" | ||
42 | #include "gnunet_transport_plugin.h" | ||
43 | #include "transport.h" | ||
44 | |||
45 | #define DEBUG_UNIX GNUNET_YES | ||
46 | |||
47 | #define MAX_PROBES 20 | ||
48 | |||
49 | /* | ||
50 | * Transport cost to peer, always 1 for UNIX (direct connection) | ||
51 | */ | ||
52 | #define UNIX_DIRECT_DISTANCE 1 | ||
53 | |||
54 | #define DEFAULT_NAT_PORT 0 | ||
55 | |||
56 | /** | ||
57 | * How long until we give up on transmitting the welcome message? | ||
58 | */ | ||
59 | #define HOSTNAME_RESOLVE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | ||
60 | |||
61 | /** | ||
62 | * Starting port for listening and sending, eventually a config value | ||
63 | */ | ||
64 | #define UNIX_NAT_DEFAULT_PORT 22086 | ||
65 | |||
66 | /** | ||
67 | * UNIX Message-Packet header. | ||
68 | */ | ||
69 | struct UNIXMessage | ||
70 | { | ||
71 | /** | ||
72 | * Message header. | ||
73 | */ | ||
74 | struct GNUNET_MessageHeader header; | ||
75 | |||
76 | /** | ||
77 | * What is the identity of the sender (GNUNET_hash of public key) | ||
78 | */ | ||
79 | struct GNUNET_PeerIdentity sender; | ||
80 | |||
81 | }; | ||
82 | |||
83 | /** | ||
84 | * Network format for IPv4 addresses. | ||
85 | */ | ||
86 | struct IPv4UdpAddress | ||
87 | { | ||
88 | /** | ||
89 | * IPv4 address, in network byte order. | ||
90 | */ | ||
91 | uint32_t ipv4_addr GNUNET_PACKED; | ||
92 | |||
93 | /** | ||
94 | * Port number, in network byte order. | ||
95 | */ | ||
96 | uint16_t u_port GNUNET_PACKED; | ||
97 | }; | ||
98 | |||
99 | |||
100 | /** | ||
101 | * Network format for IPv6 addresses. | ||
102 | */ | ||
103 | struct IPv6UdpAddress | ||
104 | { | ||
105 | /** | ||
106 | * IPv6 address. | ||
107 | */ | ||
108 | struct in6_addr ipv6_addr GNUNET_PACKED; | ||
109 | |||
110 | /** | ||
111 | * Port number, in network byte order. | ||
112 | */ | ||
113 | uint16_t u6_port GNUNET_PACKED; | ||
114 | }; | ||
115 | |||
116 | /* Forward definition */ | ||
117 | struct Plugin; | ||
118 | |||
119 | struct PrettyPrinterContext | ||
120 | { | ||
121 | GNUNET_TRANSPORT_AddressStringCallback asc; | ||
122 | void *asc_cls; | ||
123 | uint16_t port; | ||
124 | }; | ||
125 | |||
126 | struct RetrySendContext | ||
127 | { | ||
128 | |||
129 | /** | ||
130 | * Main plugin handle. | ||
131 | */ | ||
132 | struct Plugin *plugin; | ||
133 | |||
134 | /** | ||
135 | * Address of recipient. | ||
136 | */ | ||
137 | char *addr; | ||
138 | |||
139 | /** | ||
140 | * Length of address. | ||
141 | */ | ||
142 | ssize_t addrlen; | ||
143 | |||
144 | /** | ||
145 | * Message to send. | ||
146 | */ | ||
147 | char *msg; | ||
148 | |||
149 | /** | ||
150 | * Size of the message. | ||
151 | */ | ||
152 | int msg_size; | ||
153 | |||
154 | /** | ||
155 | * Handle to send message out on. | ||
156 | */ | ||
157 | struct GNUNET_NETWORK_Handle *send_handle; | ||
158 | |||
159 | /** | ||
160 | * Continuation to call on success or | ||
161 | * timeout. | ||
162 | */ | ||
163 | GNUNET_TRANSPORT_TransmitContinuation cont; | ||
164 | |||
165 | /** | ||
166 | * Closure for continuation. | ||
167 | */ | ||
168 | void *cont_cls; | ||
169 | |||
170 | /** | ||
171 | * The peer the message is destined for. | ||
172 | */ | ||
173 | struct GNUNET_PeerIdentity target; | ||
174 | |||
175 | /** | ||
176 | * How long before not retrying any longer. | ||
177 | */ | ||
178 | struct GNUNET_TIME_Absolute timeout; | ||
179 | |||
180 | /** | ||
181 | * How long the last message was delayed. | ||
182 | */ | ||
183 | struct GNUNET_TIME_Relative delay; | ||
184 | |||
185 | /** | ||
186 | * The actual retry task. | ||
187 | */ | ||
188 | GNUNET_SCHEDULER_TaskIdentifier retry_task; | ||
189 | |||
190 | /** | ||
191 | * The priority of the message. | ||
192 | */ | ||
193 | unsigned int priority; | ||
194 | }; | ||
195 | |||
196 | /** | ||
197 | * Local network addresses (actual unix path follows). | ||
198 | */ | ||
199 | struct LocalAddrList | ||
200 | { | ||
201 | |||
202 | /** | ||
203 | * This is a doubly linked list. | ||
204 | */ | ||
205 | struct LocalAddrList *next; | ||
206 | |||
207 | /** | ||
208 | * This is a doubly linked list. | ||
209 | */ | ||
210 | struct LocalAddrList *prev; | ||
211 | |||
212 | /** | ||
213 | * Number of bytes of the address that follow | ||
214 | */ | ||
215 | size_t size; | ||
216 | |||
217 | }; | ||
218 | |||
219 | |||
220 | /** | ||
221 | * UNIX NAT "Session" | ||
222 | */ | ||
223 | struct PeerSession | ||
224 | { | ||
225 | |||
226 | /** | ||
227 | * Stored in a linked list. | ||
228 | */ | ||
229 | struct PeerSession *next; | ||
230 | |||
231 | /** | ||
232 | * Pointer to the global plugin struct. | ||
233 | */ | ||
234 | struct Plugin *plugin; | ||
235 | |||
236 | /** | ||
237 | * To whom are we talking to (set to our identity | ||
238 | * if we are still waiting for the welcome message) | ||
239 | */ | ||
240 | struct GNUNET_PeerIdentity target; | ||
241 | |||
242 | /** | ||
243 | * Address of the other peer (either based on our 'connect' | ||
244 | * call or on our 'accept' call). | ||
245 | */ | ||
246 | void *connect_addr; | ||
247 | |||
248 | /** | ||
249 | * Length of connect_addr. | ||
250 | */ | ||
251 | size_t connect_alen; | ||
252 | |||
253 | /** | ||
254 | * Are we still expecting the welcome message? (GNUNET_YES/GNUNET_NO) | ||
255 | */ | ||
256 | int expecting_welcome; | ||
257 | |||
258 | /** | ||
259 | * From which socket do we need to send to this peer? | ||
260 | */ | ||
261 | struct GNUNET_NETWORK_Handle *sock; | ||
262 | |||
263 | /* | ||
264 | * Queue of messages for this peer, in the case that | ||
265 | * we have to await a connection... | ||
266 | */ | ||
267 | struct MessageQueue *messages; | ||
268 | |||
269 | }; | ||
270 | |||
271 | /** | ||
272 | * Information we keep for each of our listen sockets. | ||
273 | */ | ||
274 | struct UNIX_Sock_Info | ||
275 | { | ||
276 | /** | ||
277 | * The network handle | ||
278 | */ | ||
279 | struct GNUNET_NETWORK_Handle *desc; | ||
280 | |||
281 | /** | ||
282 | * The port we bound to | ||
283 | */ | ||
284 | uint16_t port; | ||
285 | }; | ||
286 | |||
287 | |||
288 | /** | ||
289 | * Encapsulation of all of the state of the plugin. | ||
290 | */ | ||
291 | struct Plugin | ||
292 | { | ||
293 | /** | ||
294 | * Our environment. | ||
295 | */ | ||
296 | struct GNUNET_TRANSPORT_PluginEnvironment *env; | ||
297 | |||
298 | /* | ||
299 | * Session of peers with whom we are currently connected | ||
300 | */ | ||
301 | struct PeerSession *sessions; | ||
302 | |||
303 | /** | ||
304 | * ID of task used to update our addresses when one expires. | ||
305 | */ | ||
306 | GNUNET_SCHEDULER_TaskIdentifier address_update_task; | ||
307 | |||
308 | /** | ||
309 | * ID of select task | ||
310 | */ | ||
311 | GNUNET_SCHEDULER_TaskIdentifier select_task; | ||
312 | |||
313 | /** | ||
314 | * Integer to append to unix domain socket. | ||
315 | */ | ||
316 | uint16_t port; | ||
317 | |||
318 | /** | ||
319 | * List of our IP addresses. | ||
320 | */ | ||
321 | struct LocalAddrList *lal_head; | ||
322 | |||
323 | /** | ||
324 | * Tail of our IP address list. | ||
325 | */ | ||
326 | struct LocalAddrList *lal_tail; | ||
327 | |||
328 | /** | ||
329 | * FD Read set | ||
330 | */ | ||
331 | struct GNUNET_NETWORK_FDSet *rs; | ||
332 | |||
333 | /** | ||
334 | * socket that we transmit all data with | ||
335 | */ | ||
336 | struct UNIX_Sock_Info unix_sock; | ||
337 | |||
338 | /** | ||
339 | * Path of our unix domain socket (/tmp/unix-plugin-PORT) | ||
340 | */ | ||
341 | char *unix_socket_path; | ||
342 | |||
343 | }; | ||
344 | |||
345 | |||
346 | /** | ||
347 | * Disconnect from a remote node. Clean up session if we have one for this peer | ||
348 | * | ||
349 | * @param cls closure for this call (should be handle to Plugin) | ||
350 | * @param target the peeridentity of the peer to disconnect | ||
351 | * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed | ||
352 | */ | ||
353 | void | ||
354 | unix_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) | ||
355 | { | ||
356 | /** TODO: Implement! */ | ||
357 | return; | ||
358 | } | ||
359 | |||
360 | /** | ||
361 | * Shutdown the server process (stop receiving inbound traffic). Maybe | ||
362 | * restarted later! | ||
363 | * | ||
364 | * @param cls Handle to the plugin for this transport | ||
365 | * | ||
366 | * @return returns the number of sockets successfully closed, | ||
367 | * should equal the number of sockets successfully opened | ||
368 | */ | ||
369 | static int | ||
370 | unix_transport_server_stop (void *cls) | ||
371 | { | ||
372 | struct Plugin *plugin = cls; | ||
373 | |||
374 | if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK) | ||
375 | { | ||
376 | GNUNET_SCHEDULER_cancel (plugin->select_task); | ||
377 | plugin->select_task = GNUNET_SCHEDULER_NO_TASK; | ||
378 | } | ||
379 | |||
380 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->unix_sock.desc)); | ||
381 | plugin->unix_sock.desc = NULL; | ||
382 | |||
383 | return GNUNET_OK; | ||
384 | } | ||
385 | |||
386 | |||
387 | struct PeerSession * | ||
388 | find_session (struct Plugin *plugin, | ||
389 | const struct GNUNET_PeerIdentity *peer) | ||
390 | { | ||
391 | struct PeerSession *pos; | ||
392 | |||
393 | pos = plugin->sessions; | ||
394 | while (pos != NULL) | ||
395 | { | ||
396 | if (memcmp(&pos->target, peer, sizeof(struct GNUNET_PeerIdentity)) == 0) | ||
397 | return pos; | ||
398 | pos = pos->next; | ||
399 | } | ||
400 | |||
401 | return pos; | ||
402 | } | ||
403 | |||
404 | /* Forward Declaration */ | ||
405 | static ssize_t | ||
406 | unix_real_send (void *cls, | ||
407 | struct RetrySendContext *incoming_retry_context, | ||
408 | struct GNUNET_NETWORK_Handle *send_handle, | ||
409 | const struct GNUNET_PeerIdentity *target, | ||
410 | const char *msgbuf, | ||
411 | size_t msgbuf_size, | ||
412 | unsigned int priority, | ||
413 | struct GNUNET_TIME_Relative timeout, | ||
414 | const void *addr, | ||
415 | size_t addrlen, | ||
416 | GNUNET_TRANSPORT_TransmitContinuation cont, | ||
417 | void *cont_cls); | ||
418 | |||
419 | /** | ||
420 | * Retry sending a message. | ||
421 | * | ||
422 | * @param cls closure a struct RetrySendContext | ||
423 | * @param tc context information | ||
424 | */ | ||
425 | void retry_send_message (void *cls, | ||
426 | const struct GNUNET_SCHEDULER_TaskContext * tc) | ||
427 | { | ||
428 | struct RetrySendContext *retry_ctx = cls; | ||
429 | |||
430 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | ||
431 | return; | ||
432 | unix_real_send (retry_ctx->plugin, | ||
433 | retry_ctx, | ||
434 | retry_ctx->send_handle, | ||
435 | &retry_ctx->target, | ||
436 | retry_ctx->msg, | ||
437 | retry_ctx->msg_size, | ||
438 | retry_ctx->priority, | ||
439 | GNUNET_TIME_absolute_get_remaining (retry_ctx->timeout), | ||
440 | retry_ctx->addr, | ||
441 | retry_ctx->addrlen, | ||
442 | retry_ctx->cont, | ||
443 | retry_ctx->cont_cls); | ||
444 | return; | ||
445 | } | ||
446 | |||
447 | /** | ||
448 | * Actually send out the message, assume we've got the address and | ||
449 | * send_handle squared away! | ||
450 | * | ||
451 | * @param cls closure | ||
452 | * @param incoming_retry_context the retry context to use | ||
453 | * @param send_handle which handle to send message on | ||
454 | * @param target who should receive this message (ignored by UNIX) | ||
455 | * @param msgbuf one or more GNUNET_MessageHeader(s) strung together | ||
456 | * @param msgbuf_size the size of the msgbuf to send | ||
457 | * @param priority how important is the message (ignored by UNIX) | ||
458 | * @param timeout when should we time out (give up) if we can not transmit? | ||
459 | * @param addr the addr to send the message to, needs to be a sockaddr for us | ||
460 | * @param addrlen the len of addr | ||
461 | * @param cont continuation to call once the message has | ||
462 | * been transmitted (or if the transport is ready | ||
463 | * for the next transmission call; or if the | ||
464 | * peer disconnected...) | ||
465 | * @param cont_cls closure for cont | ||
466 | * | ||
467 | * @return the number of bytes written, -1 on errors | ||
468 | */ | ||
469 | static ssize_t | ||
470 | unix_real_send (void *cls, | ||
471 | struct RetrySendContext *incoming_retry_context, | ||
472 | struct GNUNET_NETWORK_Handle *send_handle, | ||
473 | const struct GNUNET_PeerIdentity *target, | ||
474 | const char *msgbuf, | ||
475 | size_t msgbuf_size, | ||
476 | unsigned int priority, | ||
477 | struct GNUNET_TIME_Relative timeout, | ||
478 | const void *addr, | ||
479 | size_t addrlen, | ||
480 | GNUNET_TRANSPORT_TransmitContinuation cont, | ||
481 | void *cont_cls) | ||
482 | { | ||
483 | struct Plugin *plugin = cls; | ||
484 | struct UNIXMessage *message; | ||
485 | struct RetrySendContext *retry_ctx; | ||
486 | int ssize; | ||
487 | ssize_t sent; | ||
488 | const void *sb; | ||
489 | size_t sbs; | ||
490 | struct sockaddr_un *un; | ||
491 | size_t slen; | ||
492 | |||
493 | if (send_handle == NULL) | ||
494 | { | ||
495 | #if DEBUG_UNIX | ||
496 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
497 | "unix_real_send with send_handle NULL!\n"); | ||
498 | #endif | ||
499 | /* failed to open send socket for AF */ | ||
500 | if (cont != NULL) | ||
501 | cont (cont_cls, target, GNUNET_SYSERR); | ||
502 | return 0; | ||
503 | } | ||
504 | if ((addr == NULL) || (addrlen == 0)) | ||
505 | { | ||
506 | #if DEBUG_UNIX | ||
507 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
508 | "unix_real_send called without address, returning!\n"); | ||
509 | #endif | ||
510 | if (cont != NULL) | ||
511 | cont (cont_cls, target, GNUNET_SYSERR); | ||
512 | return 0; /* Can never send if we don't have an address!! */ | ||
513 | } | ||
514 | |||
515 | /* Build the message to be sent */ | ||
516 | message = GNUNET_malloc (sizeof (struct UNIXMessage) + msgbuf_size); | ||
517 | ssize = sizeof (struct UNIXMessage) + msgbuf_size; | ||
518 | |||
519 | message->header.size = htons (ssize); | ||
520 | message->header.type = htons (0); | ||
521 | memcpy (&message->sender, plugin->env->my_identity, | ||
522 | sizeof (struct GNUNET_PeerIdentity)); | ||
523 | memcpy (&message[1], msgbuf, msgbuf_size); | ||
524 | |||
525 | un = GNUNET_malloc (sizeof (struct sockaddr_un)); | ||
526 | un->sun_family = AF_UNIX; | ||
527 | slen = strlen (addr) + 1; | ||
528 | sent = 0; | ||
529 | GNUNET_assert(slen < sizeof(un->sun_path)); | ||
530 | memcpy (un->sun_path, addr, slen); | ||
531 | un->sun_path[slen] = '\0'; | ||
532 | #if LINUX | ||
533 | un->sun_path[0] = '\0'; | ||
534 | #endif | ||
535 | slen += sizeof (sa_family_t); | ||
536 | sb = (struct sockaddr*) un; | ||
537 | sbs = slen; | ||
538 | |||
539 | sent = GNUNET_NETWORK_socket_sendto(send_handle, message, ssize, sb, sbs); | ||
540 | |||
541 | if (GNUNET_SYSERR == sent) | ||
542 | { | ||
543 | if (incoming_retry_context == NULL) | ||
544 | { | ||
545 | retry_ctx = GNUNET_malloc(sizeof(struct RetrySendContext)); | ||
546 | retry_ctx->addr = GNUNET_malloc(addrlen); | ||
547 | retry_ctx->msg = GNUNET_malloc(msgbuf_size); | ||
548 | retry_ctx->plugin = plugin; | ||
549 | memcpy(retry_ctx->addr, addr, addrlen); | ||
550 | memcpy(retry_ctx->msg, msgbuf, msgbuf_size); | ||
551 | retry_ctx->msg_size = msgbuf_size; | ||
552 | retry_ctx->addrlen = addrlen; | ||
553 | retry_ctx->send_handle = send_handle; | ||
554 | retry_ctx->cont = cont; | ||
555 | retry_ctx->cont_cls = cont_cls; | ||
556 | retry_ctx->priority = priority; | ||
557 | retry_ctx->timeout = GNUNET_TIME_relative_to_absolute(timeout); | ||
558 | memcpy(&retry_ctx->target, target, sizeof(struct GNUNET_PeerIdentity)); | ||
559 | retry_ctx->delay = GNUNET_TIME_UNIT_MILLISECONDS; | ||
560 | } | ||
561 | else | ||
562 | { | ||
563 | retry_ctx = incoming_retry_context; | ||
564 | retry_ctx->delay = GNUNET_TIME_relative_multiply(retry_ctx->delay, 2); | ||
565 | } | ||
566 | retry_ctx->retry_task = GNUNET_SCHEDULER_add_delayed(retry_ctx->delay, &retry_send_message, retry_ctx); | ||
567 | #if DETAILS | ||
568 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Error when trying to send %d byte message to %s\n", retry_ctx->msg_size, &un->sun_path[1]); | ||
569 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
570 | "UNIX transmit %u-byte message to %s (%d: %s)\n", | ||
571 | (unsigned int) ssize, | ||
572 | GNUNET_a2s (sb, sbs), | ||
573 | (int) sent, | ||
574 | (sent < 0) ? STRERROR (errno) : "ok"); | ||
575 | #endif | ||
576 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "send"); | ||
577 | return ssize; | ||
578 | } | ||
579 | if (incoming_retry_context != NULL) | ||
580 | { | ||
581 | GNUNET_free(incoming_retry_context->msg); | ||
582 | GNUNET_free(incoming_retry_context->addr); | ||
583 | GNUNET_free(incoming_retry_context); | ||
584 | } | ||
585 | #if DEBUG_UNIX | ||
586 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
587 | "UNIX transmit %u-byte message to %s (%d: %s)\n", | ||
588 | (unsigned int) ssize, | ||
589 | GNUNET_a2s (sb, sbs), | ||
590 | (int) sent, | ||
591 | (sent < 0) ? STRERROR (errno) : "ok"); | ||
592 | #endif | ||
593 | if (cont != NULL) | ||
594 | { | ||
595 | if (sent == GNUNET_SYSERR) | ||
596 | cont (cont_cls, target, GNUNET_SYSERR); | ||
597 | else | ||
598 | { | ||
599 | cont (cont_cls, target, GNUNET_OK); | ||
600 | } | ||
601 | } | ||
602 | |||
603 | GNUNET_free (message); | ||
604 | return sent; | ||
605 | } | ||
606 | |||
607 | |||
608 | /** | ||
609 | * Function that can be used by the transport service to transmit | ||
610 | * a message using the plugin. | ||
611 | * | ||
612 | * @param cls closure | ||
613 | * @param target who should receive this message (ignored by UNIX) | ||
614 | * @param msgbuf one or more GNUNET_MessageHeader(s) strung together | ||
615 | * @param msgbuf_size the size of the msgbuf to send | ||
616 | * @param priority how important is the message (ignored by UNIX) | ||
617 | * @param timeout when should we time out (give up) if we can not transmit? | ||
618 | * @param session identifier used for this session (can be NULL) | ||
619 | * @param addr the addr to send the message to, needs to be a sockaddr for us | ||
620 | * @param addrlen the len of addr | ||
621 | * @param force_address not used, we had better have an address to send to | ||
622 | * because we are stateless!! | ||
623 | * @param cont continuation to call once the message has | ||
624 | * been transmitted (or if the transport is ready | ||
625 | * for the next transmission call; or if the | ||
626 | * peer disconnected...) | ||
627 | * @param cont_cls closure for cont | ||
628 | * | ||
629 | * @return the number of bytes written (may return 0 and the message can | ||
630 | * still be transmitted later!) | ||
631 | */ | ||
632 | static ssize_t | ||
633 | unix_plugin_send (void *cls, | ||
634 | const struct GNUNET_PeerIdentity *target, | ||
635 | const char *msgbuf, | ||
636 | size_t msgbuf_size, | ||
637 | unsigned int priority, | ||
638 | struct GNUNET_TIME_Relative timeout, | ||
639 | struct Session *session, | ||
640 | const void *addr, | ||
641 | size_t addrlen, | ||
642 | int force_address, | ||
643 | GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) | ||
644 | { | ||
645 | struct Plugin *plugin = cls; | ||
646 | ssize_t sent; | ||
647 | |||
648 | if (force_address == GNUNET_SYSERR) | ||
649 | return GNUNET_SYSERR; | ||
650 | GNUNET_assert (NULL == session); | ||
651 | |||
652 | #if DEBUG_UNIX | ||
653 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Asked to send message to `%s'\n", (char *)addr); | ||
654 | #endif | ||
655 | sent = unix_real_send(cls, | ||
656 | NULL, | ||
657 | plugin->unix_sock.desc, | ||
658 | target, | ||
659 | msgbuf, msgbuf_size, | ||
660 | priority, timeout, addr, addrlen, | ||
661 | cont, cont_cls); | ||
662 | #if DEBUG_UNIX | ||
663 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sent %d bytes to `%s'\n", sent, (char *)addr); | ||
664 | #endif | ||
665 | if (sent == GNUNET_SYSERR) | ||
666 | return 0; | ||
667 | return sent; | ||
668 | } | ||
669 | |||
670 | |||
671 | static void | ||
672 | add_to_address_list (struct Plugin *plugin, | ||
673 | const void *arg, | ||
674 | size_t arg_size) | ||
675 | { | ||
676 | struct LocalAddrList *lal; | ||
677 | |||
678 | lal = plugin->lal_head; | ||
679 | while (NULL != lal) | ||
680 | { | ||
681 | if ( (lal->size == arg_size) && | ||
682 | (0 == memcmp (&lal[1], arg, arg_size)) ) | ||
683 | return; | ||
684 | lal = lal->next; | ||
685 | } | ||
686 | lal = GNUNET_malloc (sizeof (struct LocalAddrList) + arg_size); | ||
687 | lal->size = arg_size; | ||
688 | memcpy (&lal[1], arg, arg_size); | ||
689 | GNUNET_CONTAINER_DLL_insert (plugin->lal_head, | ||
690 | plugin->lal_tail, | ||
691 | lal); | ||
692 | } | ||
693 | |||
694 | |||
695 | /** | ||
696 | * Demultiplexer for UNIX messages | ||
697 | * | ||
698 | * @param plugin the main plugin for this transport | ||
699 | * @param sender from which peer the message was received | ||
700 | * @param currhdr pointer to the header of the message | ||
701 | * @param sender_addr the address from which the message was received | ||
702 | * @param fromlen the length of the address | ||
703 | */ | ||
704 | static void | ||
705 | unix_demultiplexer(struct Plugin *plugin, | ||
706 | struct GNUNET_PeerIdentity *sender, | ||
707 | const struct GNUNET_MessageHeader *currhdr, | ||
708 | const struct sockaddr_un *un, | ||
709 | size_t fromlen) | ||
710 | { | ||
711 | struct GNUNET_TRANSPORT_ATS_Information distance[2]; | ||
712 | |||
713 | distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE); | ||
714 | distance[0].value = htonl (UNIX_DIRECT_DISTANCE); | ||
715 | distance[1].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); | ||
716 | distance[1].value = htonl (0); | ||
717 | |||
718 | GNUNET_assert(fromlen >= sizeof(struct sockaddr_un)); | ||
719 | |||
720 | #if DEBUG_UNIX | ||
721 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received message from %s\n", un->sun_path); | ||
722 | #endif | ||
723 | plugin->env->receive (plugin->env->cls, sender, currhdr, | ||
724 | (const struct GNUNET_TRANSPORT_ATS_Information *) &distance, 2, | ||
725 | NULL, un->sun_path, strlen(un->sun_path) + 1); | ||
726 | } | ||
727 | |||
728 | |||
729 | /* | ||
730 | * @param cls the plugin handle | ||
731 | * @param tc the scheduling context (for rescheduling this function again) | ||
732 | * | ||
733 | * We have been notified that our writeset has something to read. We don't | ||
734 | * know which socket needs to be read, so we have to check each one | ||
735 | * Then reschedule this function to be called again once more is available. | ||
736 | * | ||
737 | */ | ||
738 | static void | ||
739 | unix_plugin_select (void *cls, | ||
740 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
741 | { | ||
742 | struct Plugin *plugin = cls; | ||
743 | char buf[65536]; | ||
744 | struct UNIXMessage *msg; | ||
745 | struct GNUNET_PeerIdentity sender; | ||
746 | //socklen_t fromlen; | ||
747 | struct sockaddr_un un; | ||
748 | socklen_t addrlen; | ||
749 | ssize_t ret; | ||
750 | int offset; | ||
751 | int tsize; | ||
752 | char *msgbuf; | ||
753 | const struct GNUNET_MessageHeader *currhdr; | ||
754 | uint16_t csize; | ||
755 | |||
756 | plugin->select_task = GNUNET_SCHEDULER_NO_TASK; | ||
757 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | ||
758 | return; | ||
759 | |||
760 | addrlen = sizeof(un); | ||
761 | memset(&un, 0, sizeof(un)); | ||
762 | GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->unix_sock.desc)); | ||
763 | ret = | ||
764 | GNUNET_NETWORK_socket_recvfrom (plugin->unix_sock.desc, buf, sizeof (buf), | ||
765 | (struct sockaddr *)&un, &addrlen); | ||
766 | |||
767 | if (ret == GNUNET_SYSERR) | ||
768 | { | ||
769 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "recvfrom"); | ||
770 | plugin->select_task = | ||
771 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
772 | GNUNET_SCHEDULER_NO_TASK, | ||
773 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs, | ||
774 | NULL, &unix_plugin_select, plugin); | ||
775 | return; | ||
776 | } | ||
777 | else | ||
778 | { | ||
779 | #if LINUX | ||
780 | un.sun_path[0] = '/'; | ||
781 | #endif | ||
782 | #if DEBUG_UNIX | ||
783 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Read %d bytes from socket %s\n", ret, &un.sun_path[0]); | ||
784 | #endif | ||
785 | } | ||
786 | |||
787 | GNUNET_assert (AF_UNIX == (un.sun_family)); | ||
788 | |||
789 | msg = (struct UNIXMessage *) buf; | ||
790 | csize = ntohs (msg->header.size); | ||
791 | if ( (csize < sizeof (struct UNIXMessage)) || | ||
792 | (csize > ret) ) | ||
793 | { | ||
794 | GNUNET_break_op (0); | ||
795 | plugin->select_task = | ||
796 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
797 | GNUNET_SCHEDULER_NO_TASK, | ||
798 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs, | ||
799 | NULL, &unix_plugin_select, plugin); | ||
800 | return; | ||
801 | } | ||
802 | msgbuf = (char *)&msg[1]; | ||
803 | memcpy (&sender, &msg->sender, sizeof (struct GNUNET_PeerIdentity)); | ||
804 | offset = 0; | ||
805 | tsize = csize - sizeof (struct UNIXMessage); | ||
806 | while (offset + sizeof (struct GNUNET_MessageHeader) <= tsize) | ||
807 | { | ||
808 | currhdr = (struct GNUNET_MessageHeader *)&msgbuf[offset]; | ||
809 | csize = ntohs (currhdr->size); | ||
810 | if ( (csize < sizeof (struct GNUNET_MessageHeader)) || | ||
811 | (csize > tsize - offset) ) | ||
812 | { | ||
813 | GNUNET_break_op (0); | ||
814 | break; | ||
815 | } | ||
816 | unix_demultiplexer(plugin, &sender, currhdr, | ||
817 | &un, sizeof(un)); | ||
818 | offset += csize; | ||
819 | } | ||
820 | plugin->select_task = | ||
821 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
822 | GNUNET_SCHEDULER_NO_TASK, | ||
823 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs, | ||
824 | NULL, &unix_plugin_select, plugin); | ||
825 | } | ||
826 | |||
827 | /** | ||
828 | * Create a slew of UNIX sockets. If possible, use IPv6 and IPv4. | ||
829 | * | ||
830 | * @param cls closure for server start, should be a struct Plugin * | ||
831 | * @return number of sockets created or GNUNET_SYSERR on error | ||
832 | */ | ||
833 | static int | ||
834 | unix_transport_server_start (void *cls) | ||
835 | { | ||
836 | struct Plugin *plugin = cls; | ||
837 | |||
838 | struct sockaddr *serverAddr; | ||
839 | socklen_t addrlen; | ||
840 | int sockets_created; | ||
841 | struct sockaddr_un *un; | ||
842 | size_t slen; | ||
843 | |||
844 | un = GNUNET_malloc (sizeof (struct sockaddr_un)); | ||
845 | un->sun_family = AF_UNIX; | ||
846 | slen = strlen (plugin->unix_socket_path) + 1; | ||
847 | |||
848 | GNUNET_assert(slen < sizeof(un->sun_path)); | ||
849 | memcpy (un->sun_path, plugin->unix_socket_path, slen); | ||
850 | un->sun_path[slen] = '\0'; | ||
851 | slen += sizeof (sa_family_t); | ||
852 | serverAddr = (struct sockaddr*) un; | ||
853 | addrlen = slen; | ||
854 | sockets_created = 0; | ||
855 | #if LINUX | ||
856 | un->sun_path[0] = '\0'; | ||
857 | #endif | ||
858 | |||
859 | plugin->unix_sock.desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0); | ||
860 | if (NULL == plugin->unix_sock.desc) | ||
861 | { | ||
862 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "socket"); | ||
863 | } | ||
864 | else | ||
865 | { | ||
866 | if (GNUNET_NETWORK_socket_bind (plugin->unix_sock.desc, serverAddr, addrlen) != | ||
867 | GNUNET_OK) | ||
868 | { | ||
869 | #if DEBUG_UNIX | ||
870 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
871 | "UNIX Binding failed!\n"); | ||
872 | #endif | ||
873 | } | ||
874 | else | ||
875 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Bound to `%s'\n", &un->sun_path[0]); | ||
876 | if (plugin->unix_sock.desc != NULL) | ||
877 | sockets_created++; | ||
878 | } | ||
879 | |||
880 | plugin->rs = GNUNET_NETWORK_fdset_create (); | ||
881 | GNUNET_NETWORK_fdset_zero (plugin->rs); | ||
882 | GNUNET_NETWORK_fdset_set (plugin->rs, | ||
883 | plugin->unix_sock.desc); | ||
884 | |||
885 | plugin->select_task = | ||
886 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
887 | GNUNET_SCHEDULER_NO_TASK, | ||
888 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs, | ||
889 | NULL, &unix_plugin_select, plugin); | ||
890 | return sockets_created; | ||
891 | } | ||
892 | |||
893 | |||
894 | /** | ||
895 | * Function that will be called to check if a binary address for this | ||
896 | * plugin is well-formed and corresponds to an address for THIS peer | ||
897 | * (as per our configuration). Naturally, if absolutely necessary, | ||
898 | * plugins can be a bit conservative in their answer, but in general | ||
899 | * plugins should make sure that the address does not redirect | ||
900 | * traffic to a 3rd party that might try to man-in-the-middle our | ||
901 | * traffic. | ||
902 | * | ||
903 | * @param cls closure, should be our handle to the Plugin | ||
904 | * @param addr pointer to the address | ||
905 | * @param addrlen length of addr | ||
906 | * @return GNUNET_OK if this is a plausible address for this peer | ||
907 | * and transport, GNUNET_SYSERR if not | ||
908 | * | ||
909 | */ | ||
910 | static int | ||
911 | unix_check_address (void *cls, | ||
912 | const void *addr, | ||
913 | size_t addrlen) | ||
914 | { | ||
915 | |||
916 | #if DEBUG_UNIX | ||
917 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
918 | "Informing transport service about my address `%s'\n", | ||
919 | (char *)addr); | ||
920 | #endif | ||
921 | return GNUNET_OK; | ||
922 | } | ||
923 | |||
924 | |||
925 | /** | ||
926 | * Append our port and forward the result. | ||
927 | */ | ||
928 | static void | ||
929 | append_port (void *cls, const char *hostname) | ||
930 | { | ||
931 | struct PrettyPrinterContext *ppc = cls; | ||
932 | char *ret; | ||
933 | |||
934 | if (hostname == NULL) | ||
935 | { | ||
936 | ppc->asc (ppc->asc_cls, NULL); | ||
937 | GNUNET_free (ppc); | ||
938 | return; | ||
939 | } | ||
940 | GNUNET_asprintf (&ret, "%s:%d", hostname, ppc->port); | ||
941 | ppc->asc (ppc->asc_cls, ret); | ||
942 | GNUNET_free (ret); | ||
943 | } | ||
944 | |||
945 | |||
946 | /** | ||
947 | * Convert the transports address to a nice, human-readable | ||
948 | * format. | ||
949 | * | ||
950 | * @param cls closure | ||
951 | * @param type name of the transport that generated the address | ||
952 | * @param addr one of the addresses of the host, NULL for the last address | ||
953 | * the specific address format depends on the transport | ||
954 | * @param addrlen length of the address | ||
955 | * @param numeric should (IP) addresses be displayed in numeric form? | ||
956 | * @param timeout after how long should we give up? | ||
957 | * @param asc function to call on each string | ||
958 | * @param asc_cls closure for asc | ||
959 | */ | ||
960 | static void | ||
961 | unix_plugin_address_pretty_printer (void *cls, | ||
962 | const char *type, | ||
963 | const void *addr, | ||
964 | size_t addrlen, | ||
965 | int numeric, | ||
966 | struct GNUNET_TIME_Relative timeout, | ||
967 | GNUNET_TRANSPORT_AddressStringCallback asc, | ||
968 | void *asc_cls) | ||
969 | { | ||
970 | struct Plugin *plugin = cls; | ||
971 | struct PrettyPrinterContext *ppc; | ||
972 | const void *sb; | ||
973 | size_t sbs; | ||
974 | struct sockaddr_in a4; | ||
975 | struct sockaddr_in6 a6; | ||
976 | const struct IPv4UdpAddress *u4; | ||
977 | const struct IPv6UdpAddress *u6; | ||
978 | uint16_t port; | ||
979 | |||
980 | if (addrlen == sizeof (struct IPv6UdpAddress)) | ||
981 | { | ||
982 | u6 = addr; | ||
983 | memset (&a6, 0, sizeof (a6)); | ||
984 | a6.sin6_family = AF_INET6; | ||
985 | a6.sin6_port = u6->u6_port; | ||
986 | memcpy (&a6.sin6_addr, | ||
987 | &u6->ipv6_addr, | ||
988 | sizeof (struct in6_addr)); | ||
989 | port = ntohs (u6->u6_port); | ||
990 | sb = &a6; | ||
991 | sbs = sizeof (a6); | ||
992 | } | ||
993 | else if (addrlen == sizeof (struct IPv4UdpAddress)) | ||
994 | { | ||
995 | u4 = addr; | ||
996 | memset (&a4, 0, sizeof (a4)); | ||
997 | a4.sin_family = AF_INET; | ||
998 | a4.sin_port = u4->u_port; | ||
999 | a4.sin_addr.s_addr = u4->ipv4_addr; | ||
1000 | port = ntohs (u4->u_port); | ||
1001 | sb = &a4; | ||
1002 | sbs = sizeof (a4); | ||
1003 | } | ||
1004 | else | ||
1005 | { | ||
1006 | /* invalid address */ | ||
1007 | GNUNET_break_op (0); | ||
1008 | asc (asc_cls, NULL); | ||
1009 | return; | ||
1010 | } | ||
1011 | ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext)); | ||
1012 | ppc->asc = asc; | ||
1013 | ppc->asc_cls = asc_cls; | ||
1014 | ppc->port = port; | ||
1015 | GNUNET_RESOLVER_hostname_get (plugin->env->cfg, | ||
1016 | sb, | ||
1017 | sbs, | ||
1018 | !numeric, timeout, &append_port, ppc); | ||
1019 | } | ||
1020 | |||
1021 | /** | ||
1022 | * Function called for a quick conversion of the binary address to | ||
1023 | * a numeric address. Note that the caller must not free the | ||
1024 | * address and that the next call to this function is allowed | ||
1025 | * to override the address again. | ||
1026 | * | ||
1027 | * @param cls closure | ||
1028 | * @param addr binary address | ||
1029 | * @param addrlen length of the address | ||
1030 | * @return string representing the same address | ||
1031 | */ | ||
1032 | static const char* | ||
1033 | unix_address_to_string (void *cls, | ||
1034 | const void *addr, | ||
1035 | size_t addrlen) | ||
1036 | { | ||
1037 | static char rbuf[INET6_ADDRSTRLEN + 10]; | ||
1038 | char buf[INET6_ADDRSTRLEN]; | ||
1039 | const void *sb; | ||
1040 | struct in_addr a4; | ||
1041 | struct in6_addr a6; | ||
1042 | const struct IPv4UdpAddress *t4; | ||
1043 | const struct IPv6UdpAddress *t6; | ||
1044 | int af; | ||
1045 | uint16_t port; | ||
1046 | |||
1047 | if (addrlen == sizeof (struct IPv6UdpAddress)) | ||
1048 | { | ||
1049 | t6 = addr; | ||
1050 | af = AF_INET6; | ||
1051 | port = ntohs (t6->u6_port); | ||
1052 | memcpy (&a6, &t6->ipv6_addr, sizeof (a6)); | ||
1053 | sb = &a6; | ||
1054 | } | ||
1055 | else if (addrlen == sizeof (struct IPv4UdpAddress)) | ||
1056 | { | ||
1057 | t4 = addr; | ||
1058 | af = AF_INET; | ||
1059 | port = ntohs (t4->u_port); | ||
1060 | memcpy (&a4, &t4->ipv4_addr, sizeof (a4)); | ||
1061 | sb = &a4; | ||
1062 | } | ||
1063 | else | ||
1064 | return NULL; | ||
1065 | inet_ntop (af, sb, buf, INET6_ADDRSTRLEN); | ||
1066 | GNUNET_snprintf (rbuf, | ||
1067 | sizeof (rbuf), | ||
1068 | "%s:%u", | ||
1069 | buf, | ||
1070 | port); | ||
1071 | return rbuf; | ||
1072 | } | ||
1073 | |||
1074 | /** | ||
1075 | * The exported method. Makes the core api available via a global and | ||
1076 | * returns the unix transport API. | ||
1077 | */ | ||
1078 | void * | ||
1079 | libgnunet_plugin_transport_unix_init (void *cls) | ||
1080 | { | ||
1081 | struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; | ||
1082 | unsigned long long port; | ||
1083 | struct GNUNET_TRANSPORT_PluginFunctions *api; | ||
1084 | struct Plugin *plugin; | ||
1085 | int sockets_created; | ||
1086 | |||
1087 | if (GNUNET_OK != | ||
1088 | GNUNET_CONFIGURATION_get_value_number (env->cfg, | ||
1089 | "transport-unix", | ||
1090 | "PORT", | ||
1091 | &port)) | ||
1092 | port = UNIX_NAT_DEFAULT_PORT; | ||
1093 | else if (port > 65535) | ||
1094 | { | ||
1095 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1096 | _("Given `%s' option is out of range: %llu > %u\n"), | ||
1097 | "PORT", | ||
1098 | port, | ||
1099 | 65535); | ||
1100 | return NULL; | ||
1101 | } | ||
1102 | |||
1103 | |||
1104 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | ||
1105 | plugin->port = port; | ||
1106 | plugin->env = env; | ||
1107 | GNUNET_asprintf(&plugin->unix_socket_path, "/tmp/unix-plugin-sock.%d", plugin->port); | ||
1108 | |||
1109 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | ||
1110 | api->cls = plugin; | ||
1111 | |||
1112 | api->send = &unix_plugin_send; | ||
1113 | api->disconnect = &unix_disconnect; | ||
1114 | api->address_pretty_printer = &unix_plugin_address_pretty_printer; | ||
1115 | api->address_to_string = &unix_address_to_string; | ||
1116 | api->check_address = &unix_check_address; | ||
1117 | |||
1118 | add_to_address_list (plugin, plugin->unix_socket_path, strlen(plugin->unix_socket_path) + 1); | ||
1119 | |||
1120 | sockets_created = unix_transport_server_start (plugin); | ||
1121 | if (sockets_created == 0) | ||
1122 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1123 | _("Failed to open UNIX sockets\n")); | ||
1124 | |||
1125 | plugin->env->notify_address(plugin->env->cls, | ||
1126 | "unix", | ||
1127 | plugin->unix_socket_path, | ||
1128 | strlen(plugin->unix_socket_path) + 1, | ||
1129 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
1130 | return api; | ||
1131 | } | ||
1132 | |||
1133 | void * | ||
1134 | libgnunet_plugin_transport_unix_done (void *cls) | ||
1135 | { | ||
1136 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | ||
1137 | struct Plugin *plugin = api->cls; | ||
1138 | struct LocalAddrList *lal; | ||
1139 | |||
1140 | unix_transport_server_stop (plugin); | ||
1141 | |||
1142 | GNUNET_NETWORK_fdset_destroy (plugin->rs); | ||
1143 | while (NULL != (lal = plugin->lal_head)) | ||
1144 | { | ||
1145 | GNUNET_CONTAINER_DLL_remove (plugin->lal_head, | ||
1146 | plugin->lal_tail, | ||
1147 | lal); | ||
1148 | GNUNET_free (lal); | ||
1149 | } | ||
1150 | GNUNET_free (plugin); | ||
1151 | GNUNET_free (api); | ||
1152 | return NULL; | ||
1153 | } | ||
1154 | |||
1155 | /* end of plugin_transport_unix.c */ | ||
diff --git a/src/transport/test_quota_compliance.c b/src/transport/test_quota_compliance.c index 767ada25e..20a9b1f15 100644 --- a/src/transport/test_quota_compliance.c +++ b/src/transport/test_quota_compliance.c | |||
@@ -139,6 +139,7 @@ static int is_tcp_nat; | |||
139 | static int is_http; | 139 | static int is_http; |
140 | static int is_https; | 140 | static int is_https; |
141 | static int is_udp; | 141 | static int is_udp; |
142 | static int is_unix; | ||
142 | static int is_asymmetric_send_constant; | 143 | static int is_asymmetric_send_constant; |
143 | static int is_asymmetric_recv_constant; | 144 | static int is_asymmetric_recv_constant; |
144 | 145 | ||
@@ -731,6 +732,17 @@ run (void *cls, | |||
731 | setup_peer (&p1, "test_quota_compliance_udp_peer1.conf"); | 732 | setup_peer (&p1, "test_quota_compliance_udp_peer1.conf"); |
732 | setup_peer (&p2, "test_quota_compliance_udp_peer2.conf"); | 733 | setup_peer (&p2, "test_quota_compliance_udp_peer2.conf"); |
733 | } | 734 | } |
735 | else if (is_unix) | ||
736 | { | ||
737 | if (is_asymmetric_recv_constant == GNUNET_YES) | ||
738 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (receiver quota constant) for UNIX transport plugin\n"); | ||
739 | else if (is_asymmetric_send_constant == GNUNET_YES) | ||
740 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric quota compliance (sender quota constant) for UNIX transport plugin\n"); | ||
741 | else | ||
742 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing symmetric quota compliance for UNIX transport plugin\n"); | ||
743 | setup_peer (&p1, "test_quota_compliance_unix_peer1.conf"); | ||
744 | setup_peer (&p2, "test_quota_compliance_unix_peer2.conf"); | ||
745 | } | ||
734 | else if (is_tcp_nat) | 746 | else if (is_tcp_nat) |
735 | { | 747 | { |
736 | if (is_asymmetric_recv_constant == GNUNET_YES) | 748 | if (is_asymmetric_recv_constant == GNUNET_YES) |
@@ -777,6 +789,10 @@ main (int argc, char *argv[]) | |||
777 | { | 789 | { |
778 | is_udp = GNUNET_YES; | 790 | is_udp = GNUNET_YES; |
779 | } | 791 | } |
792 | else if (strstr(argv[0], "unix") != NULL) | ||
793 | { | ||
794 | is_unix = GNUNET_YES; | ||
795 | } | ||
780 | 796 | ||
781 | if (strstr(argv[0], "asymmetric_recv") != NULL) | 797 | if (strstr(argv[0], "asymmetric_recv") != NULL) |
782 | { | 798 | { |
@@ -810,6 +826,15 @@ main (int argc, char *argv[]) | |||
810 | else | 826 | else |
811 | GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","udp","symmetric"); | 827 | GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","udp","symmetric"); |
812 | } | 828 | } |
829 | else if (is_unix == GNUNET_YES) | ||
830 | { | ||
831 | if (is_asymmetric_recv_constant == GNUNET_YES) | ||
832 | GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","unix","asymmetric_recv_constant"); | ||
833 | else if (is_asymmetric_send_constant == GNUNET_YES) | ||
834 | GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","unix","asymmetric_send_constant"); | ||
835 | else | ||
836 | GNUNET_asprintf(&logger, "test-quota-compliance-%s-%s","unix","symmetric"); | ||
837 | } | ||
813 | else if (is_http == GNUNET_YES) | 838 | else if (is_http == GNUNET_YES) |
814 | { | 839 | { |
815 | if (is_asymmetric_recv_constant == GNUNET_YES) | 840 | if (is_asymmetric_recv_constant == GNUNET_YES) |
diff --git a/src/transport/test_quota_compliance_unix_peer1.conf b/src/transport/test_quota_compliance_unix_peer1.conf new file mode 100644 index 000000000..ff8ef0537 --- /dev/null +++ b/src/transport/test_quota_compliance_unix_peer1.conf | |||
@@ -0,0 +1,104 @@ | |||
1 | [PATHS] | ||
2 | SERVICEHOME = /tmp/test_quota_compliance_peer1/ | ||
3 | DEFAULTCONFIG = test_quota_compliance_unix_peer1.conf | ||
4 | |||
5 | [fs] | ||
6 | AUTOSTART = NO | ||
7 | |||
8 | [datastore] | ||
9 | AUTOSTART = NO | ||
10 | |||
11 | [hostlist] | ||
12 | HTTP-PROXY = | ||
13 | SERVERS = http://gnunet.org:8080/ | ||
14 | OPTIONS = -b | ||
15 | BINARY = gnunet-daemon-hostlist | ||
16 | CONFIG = $DEFAULTCONFIG | ||
17 | HOME = $SERVICEHOME | ||
18 | HOSTNAME = localhost | ||
19 | HTTPPORT = 8080 | ||
20 | |||
21 | [topology] | ||
22 | BINARY = gnunet-daemon-topology | ||
23 | CONFIG = $DEFAULTCONFIG | ||
24 | FRIENDS = $SERVICEHOME/friends | ||
25 | TARGET-CONNECTION-COUNT = 16 | ||
26 | AUTOCONNECT = YES | ||
27 | FRIENDS-ONLY = NO | ||
28 | MINIMUM-FRIENDS = 0 | ||
29 | |||
30 | [core] | ||
31 | AUTOSTART = NO | ||
32 | |||
33 | [transport-unix] | ||
34 | PORT = 4368 | ||
35 | |||
36 | |||
37 | [transport] | ||
38 | plugins = unix | ||
39 | #DEBUG = YES | ||
40 | PREFIX = | ||
41 | ACCEPT_FROM6 = ::1; | ||
42 | ACCEPT_FROM = 127.0.0.1; | ||
43 | NEIGHBOUR_LIMIT = 50 | ||
44 | BINARY = gnunet-service-transport | ||
45 | CONFIG = $DEFAULTCONFIG | ||
46 | HOME = $SERVICEHOME | ||
47 | HOSTNAME = localhost | ||
48 | PORT = 4091 | ||
49 | UNIXPATH = /tmp/test_quota_compliance_unix_transport_peer1.sock | ||
50 | |||
51 | [peerinfo] | ||
52 | TRUST = $SERVICEHOME/data/credit/ | ||
53 | HOSTS = $SERVICEHOME/data/hosts/ | ||
54 | ACCEPT_FROM6 = ::1; | ||
55 | ACCEPT_FROM = 127.0.0.1; | ||
56 | BINARY = gnunet-service-peerinfo | ||
57 | CONFIG = $DEFAULTCONFIG | ||
58 | HOME = $SERVICEHOME | ||
59 | HOSTNAME = localhost | ||
60 | PORT = 4090 | ||
61 | UNIXPATH = /tmp/test_quota_compliance_unix_peerinfo_peer1.sock | ||
62 | |||
63 | [resolver] | ||
64 | ACCEPT_FROM6 = ::1; | ||
65 | ACCEPT_FROM = 127.0.0.1; | ||
66 | BINARY = gnunet-service-resolver | ||
67 | CONFIG = $DEFAULTCONFIG | ||
68 | HOME = $SERVICEHOME | ||
69 | HOSTNAME = localhost | ||
70 | PORT = 4089 | ||
71 | UNIXPATH = /tmp/test_quota_compliance_unix_resolver_peer1.sock | ||
72 | |||
73 | [statistics] | ||
74 | ACCEPT_FROM6 = ::1; | ||
75 | ACCEPT_FROM = 127.0.0.1; | ||
76 | BINARY = gnunet-service-statistics | ||
77 | CONFIG = $DEFAULTCONFIG | ||
78 | HOME = $SERVICEHOME | ||
79 | HOSTNAME = localhost | ||
80 | PORT = 4088 | ||
81 | UNIXPATH = /tmp/test_quota_compliance_unix_statistics_peer1.sock | ||
82 | |||
83 | [arm] | ||
84 | DEFAULTSERVICES = | ||
85 | ACCEPT_FROM6 = ::1; | ||
86 | ACCEPT_FROM = 127.0.0.1; | ||
87 | BINARY = gnunet-service-arm | ||
88 | CONFIG = $DEFAULTCONFIG | ||
89 | HOME = $SERVICEHOME | ||
90 | HOSTNAME = localhost | ||
91 | PORT = 4087 | ||
92 | UNIXPATH = /tmp/test_quota_compliance_unix_arm_peer1.sock | ||
93 | |||
94 | [TESTING] | ||
95 | WEAKRANDOM = YES | ||
96 | |||
97 | [gnunetd] | ||
98 | HOSTKEY = $SERVICEHOME/.hostkey | ||
99 | |||
100 | |||
101 | [dht] | ||
102 | AUTOSTART = NO | ||
103 | |||
104 | |||
diff --git a/src/transport/test_quota_compliance_unix_peer2.conf b/src/transport/test_quota_compliance_unix_peer2.conf new file mode 100644 index 000000000..7be68cbbe --- /dev/null +++ b/src/transport/test_quota_compliance_unix_peer2.conf | |||
@@ -0,0 +1,102 @@ | |||
1 | [PATHS] | ||
2 | SERVICEHOME = /tmp/test_quota_compliance_peer2 | ||
3 | DEFAULTCONFIG = test_quota_compliance_unix_peer2.conf | ||
4 | |||
5 | [transport-unix] | ||
6 | PORT = 3368 | ||
7 | [fs] | ||
8 | AUTOSTART = NO | ||
9 | |||
10 | [datastore] | ||
11 | AUTOSTART = NO | ||
12 | |||
13 | [hostlist] | ||
14 | HTTP-PROXY = | ||
15 | SERVERS = http://gnunet.org:8080/ | ||
16 | OPTIONS = -b | ||
17 | BINARY = gnunet-daemon-hostlist | ||
18 | CONFIG = $DEFAULTCONFIG | ||
19 | HOME = $SERVICEHOME | ||
20 | HOSTNAME = localhost | ||
21 | HTTPPORT = 8080 | ||
22 | |||
23 | [topology] | ||
24 | BINARY = gnunet-daemon-topology | ||
25 | CONFIG = $DEFAULTCONFIG | ||
26 | FRIENDS = $SERVICEHOME/friends | ||
27 | TARGET-CONNECTION-COUNT = 16 | ||
28 | AUTOCONNECT = YES | ||
29 | FRIENDS-ONLY = NO | ||
30 | MINIMUM-FRIENDS = 0 | ||
31 | |||
32 | [core] | ||
33 | AUTOSTART = NO | ||
34 | |||
35 | [transport] | ||
36 | plugins = unix | ||
37 | #DEBUG = YES | ||
38 | PREFIX = | ||
39 | ACCEPT_FROM6 = ::1; | ||
40 | ACCEPT_FROM = 127.0.0.1; | ||
41 | NEIGHBOUR_LIMIT = 50 | ||
42 | BINARY = gnunet-service-transport | ||
43 | CONFIG = $DEFAULTCONFIG | ||
44 | HOME = $SERVICEHOME | ||
45 | HOSTNAME = localhost | ||
46 | PORT = 3091 | ||
47 | UNIXPATH = /tmp/test_quota_compliance_unix_transport_peer2.sock | ||
48 | |||
49 | [peerinfo] | ||
50 | TRUST = $SERVICEHOME/data/credit/ | ||
51 | HOSTS = $SERVICEHOME/data/hosts/ | ||
52 | ACCEPT_FROM6 = ::1; | ||
53 | ACCEPT_FROM = 127.0.0.1; | ||
54 | BINARY = gnunet-service-peerinfo | ||
55 | CONFIG = $DEFAULTCONFIG | ||
56 | HOME = $SERVICEHOME | ||
57 | HOSTNAME = localhost | ||
58 | PORT = 3090 | ||
59 | UNIXPATH = /tmp/test_quota_compliance_unix_peerinfo_peer2.sock | ||
60 | |||
61 | [resolver] | ||
62 | ACCEPT_FROM6 = ::1; | ||
63 | ACCEPT_FROM = 127.0.0.1; | ||
64 | BINARY = gnunet-service-resolver | ||
65 | CONFIG = $DEFAULTCONFIG | ||
66 | HOME = $SERVICEHOME | ||
67 | HOSTNAME = localhost | ||
68 | PORT = 3089 | ||
69 | UNIXPATH = /tmp/test_quota_compliance_unix_resolver_peer2.sock | ||
70 | |||
71 | [statistics] | ||
72 | ACCEPT_FROM6 = ::1; | ||
73 | ACCEPT_FROM = 127.0.0.1; | ||
74 | BINARY = gnunet-service-statistics | ||
75 | CONFIG = $DEFAULTCONFIG | ||
76 | HOME = $SERVICEHOME | ||
77 | HOSTNAME = localhost | ||
78 | PORT = 3088 | ||
79 | UNIXPATH = /tmp/test_quota_compliance_unix_statistics_peer2.sock | ||
80 | |||
81 | [arm] | ||
82 | DEFAULTSERVICES = | ||
83 | ACCEPT_FROM6 = ::1; | ||
84 | ACCEPT_FROM = 127.0.0.1; | ||
85 | BINARY = gnunet-service-arm | ||
86 | CONFIG = $DEFAULTCONFIG | ||
87 | HOME = $SERVICEHOME | ||
88 | HOSTNAME = localhost | ||
89 | PORT = 3087 | ||
90 | UNIXPATH = /tmp/test_quota_compliance_unix_arm_peer2.sock | ||
91 | |||
92 | [TESTING] | ||
93 | WEAKRANDOM = YES | ||
94 | |||
95 | [gnunetd] | ||
96 | HOSTKEY = $SERVICEHOME/.hostkey | ||
97 | |||
98 | |||
99 | [dht] | ||
100 | AUTOSTART = NO | ||
101 | |||
102 | |||
diff --git a/src/transport/test_transport_api.c b/src/transport/test_transport_api.c index 3b528d84d..60cb7866f 100644 --- a/src/transport/test_transport_api.c +++ b/src/transport/test_transport_api.c | |||
@@ -76,6 +76,8 @@ static int is_tcp_nat; | |||
76 | 76 | ||
77 | static int is_udp; | 77 | static int is_udp; |
78 | 78 | ||
79 | static int is_unix; | ||
80 | |||
79 | static int is_udp_nat; | 81 | static int is_udp_nat; |
80 | 82 | ||
81 | static int is_http; | 83 | static int is_http; |
@@ -369,6 +371,12 @@ run (void *cls, | |||
369 | setup_peer (&p1, "test_transport_api_udp_peer1.conf"); | 371 | setup_peer (&p1, "test_transport_api_udp_peer1.conf"); |
370 | setup_peer (&p2, "test_transport_api_udp_peer2.conf"); | 372 | setup_peer (&p2, "test_transport_api_udp_peer2.conf"); |
371 | } | 373 | } |
374 | if (is_unix) | ||
375 | { | ||
376 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Using unix domain socket transport\n"); | ||
377 | setup_peer (&p1, "test_transport_api_unix_peer1.conf"); | ||
378 | setup_peer (&p2, "test_transport_api_unix_peer2.conf"); | ||
379 | } | ||
372 | if (is_multi_protocol) | 380 | if (is_multi_protocol) |
373 | { | 381 | { |
374 | setup_peer (&p1, "test_transport_api_multi_peer1.conf"); | 382 | setup_peer (&p1, "test_transport_api_multi_peer1.conf"); |
@@ -634,6 +642,10 @@ main (int argc, char *argv[]) | |||
634 | { | 642 | { |
635 | is_udp = GNUNET_YES; | 643 | is_udp = GNUNET_YES; |
636 | } | 644 | } |
645 | else if (strstr(argv[0], "unix") != NULL) | ||
646 | { | ||
647 | is_unix = GNUNET_YES; | ||
648 | } | ||
637 | else if (strstr(argv[0], "https") != NULL) | 649 | else if (strstr(argv[0], "https") != NULL) |
638 | { | 650 | { |
639 | is_https = GNUNET_YES; | 651 | is_https = GNUNET_YES; |
diff --git a/src/transport/test_transport_api_reliability.c b/src/transport/test_transport_api_reliability.c index 414a8cdd6..306e88ed8 100644 --- a/src/transport/test_transport_api_reliability.c +++ b/src/transport/test_transport_api_reliability.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "gnunet_scheduler_lib.h" | 34 | #include "gnunet_scheduler_lib.h" |
35 | #include "gnunet_server_lib.h" | 35 | #include "gnunet_server_lib.h" |
36 | #include "gnunet_transport_service.h" | 36 | #include "gnunet_transport_service.h" |
37 | #include "gauger.h" | ||
37 | #include "transport.h" | 38 | #include "transport.h" |
38 | 39 | ||
39 | #define VERBOSE GNUNET_NO | 40 | #define VERBOSE GNUNET_NO |
@@ -82,6 +83,8 @@ static int is_https; | |||
82 | 83 | ||
83 | static int is_udp; | 84 | static int is_udp; |
84 | 85 | ||
86 | static int is_unix; | ||
87 | |||
85 | static int connected; | 88 | static int connected; |
86 | 89 | ||
87 | static unsigned long long total_bytes; | 90 | static unsigned long long total_bytes; |
@@ -95,7 +98,7 @@ static char * cert_file_p1; | |||
95 | 98 | ||
96 | static char * key_file_p2; | 99 | static char * key_file_p2; |
97 | static char * cert_file_p2; | 100 | static char * cert_file_p2; |
98 | 101 | static char *test_name; | |
99 | static int msg_scheduled; | 102 | static int msg_scheduled; |
100 | static int msg_sent; | 103 | static int msg_sent; |
101 | static int msg_recv_expected; | 104 | static int msg_recv_expected; |
@@ -113,6 +116,7 @@ static void | |||
113 | end () | 116 | end () |
114 | { | 117 | { |
115 | unsigned long long delta; | 118 | unsigned long long delta; |
119 | char *value_name; | ||
116 | 120 | ||
117 | GNUNET_SCHEDULER_cancel (die_task); | 121 | GNUNET_SCHEDULER_cancel (die_task); |
118 | die_task = GNUNET_SCHEDULER_NO_TASK; | 122 | die_task = GNUNET_SCHEDULER_NO_TASK; |
@@ -129,6 +133,9 @@ end () | |||
129 | fprintf (stderr, | 133 | fprintf (stderr, |
130 | "\nThroughput was %llu kb/s\n", | 134 | "\nThroughput was %llu kb/s\n", |
131 | total_bytes * 1000 / 1024 / delta); | 135 | total_bytes * 1000 / 1024 / delta); |
136 | GNUNET_asprintf(&value_name, "reliable_kbs_%s", test_name); | ||
137 | GAUGER (value_name, (int)(total_bytes * 1000 / 1024 /delta)); | ||
138 | GNUNET_free(value_name); | ||
132 | ok = 0; | 139 | ok = 0; |
133 | 140 | ||
134 | } | 141 | } |
@@ -665,6 +672,11 @@ run (void *cls, | |||
665 | setup_peer (&p1, "test_transport_api_udp_peer1.conf"); | 672 | setup_peer (&p1, "test_transport_api_udp_peer1.conf"); |
666 | setup_peer (&p2, "test_transport_api_udp_peer2.conf"); | 673 | setup_peer (&p2, "test_transport_api_udp_peer2.conf"); |
667 | } | 674 | } |
675 | else if (is_unix) | ||
676 | { | ||
677 | setup_peer (&p1, "test_transport_api_unix_peer1.conf"); | ||
678 | setup_peer (&p2, "test_transport_api_unix_peer2.conf"); | ||
679 | } | ||
668 | else if (is_tcp_nat) | 680 | else if (is_tcp_nat) |
669 | { | 681 | { |
670 | setup_peer (&p1, "test_transport_api_tcp_nat_peer1.conf"); | 682 | setup_peer (&p1, "test_transport_api_tcp_nat_peer1.conf"); |
@@ -768,22 +780,32 @@ main (int argc, char *argv[]) | |||
768 | if (strstr(argv[0], "tcp_nat") != NULL) | 780 | if (strstr(argv[0], "tcp_nat") != NULL) |
769 | { | 781 | { |
770 | is_tcp_nat = GNUNET_YES; | 782 | is_tcp_nat = GNUNET_YES; |
783 | GNUNET_asprintf(&test_name, "tcp_nat"); | ||
771 | } | 784 | } |
772 | else if (strstr(argv[0], "tcp") != NULL) | 785 | else if (strstr(argv[0], "tcp") != NULL) |
773 | { | 786 | { |
774 | is_tcp = GNUNET_YES; | 787 | is_tcp = GNUNET_YES; |
788 | GNUNET_asprintf(&test_name, "tcp"); | ||
775 | } | 789 | } |
776 | else if (strstr(argv[0], "https") != NULL) | 790 | else if (strstr(argv[0], "https") != NULL) |
777 | { | 791 | { |
778 | is_https = GNUNET_YES; | 792 | is_https = GNUNET_YES; |
793 | GNUNET_asprintf(&test_name, "https"); | ||
779 | } | 794 | } |
780 | else if (strstr(argv[0], "http") != NULL) | 795 | else if (strstr(argv[0], "http") != NULL) |
781 | { | 796 | { |
782 | is_http = GNUNET_YES; | 797 | is_http = GNUNET_YES; |
798 | GNUNET_asprintf(&test_name, "http"); | ||
783 | } | 799 | } |
784 | else if (strstr(argv[0], "udp") != NULL) | 800 | else if (strstr(argv[0], "udp") != NULL) |
785 | { | 801 | { |
786 | is_udp = GNUNET_YES; | 802 | is_udp = GNUNET_YES; |
803 | GNUNET_asprintf(&test_name, "udp"); | ||
804 | } | ||
805 | else if (strstr(argv[0], "unix") != NULL) | ||
806 | { | ||
807 | is_unix = GNUNET_YES; | ||
808 | GNUNET_asprintf(&test_name, "unix"); | ||
787 | } | 809 | } |
788 | GNUNET_log_setup ("test-transport-api-reliability", | 810 | GNUNET_log_setup ("test-transport-api-reliability", |
789 | #if VERBOSE | 811 | #if VERBOSE |
diff --git a/src/transport/test_transport_api_unix_peer1.conf b/src/transport/test_transport_api_unix_peer1.conf new file mode 100644 index 000000000..e1e5a7f57 --- /dev/null +++ b/src/transport/test_transport_api_unix_peer1.conf | |||
@@ -0,0 +1,110 @@ | |||
1 | [transport-unix] | ||
2 | PORT = 12368 | ||
3 | |||
4 | [fs] | ||
5 | AUTOSTART = NO | ||
6 | |||
7 | [datastore] | ||
8 | AUTOSTART = NO | ||
9 | |||
10 | [core] | ||
11 | AUTOSTART = NO | ||
12 | |||
13 | [hostlist] | ||
14 | HTTP-PROXY = | ||
15 | SERVERS = http://gnunet.org:8080/ | ||
16 | OPTIONS = -b | ||
17 | BINARY = gnunet-daemon-hostlist | ||
18 | CONFIG = $DEFAULTCONFIG | ||
19 | HOME = $SERVICEHOME | ||
20 | HOSTNAME = localhost | ||
21 | HTTPPORT = 8080 | ||
22 | |||
23 | [topology] | ||
24 | BINARY = gnunet-daemon-topology | ||
25 | CONFIG = $DEFAULTCONFIG | ||
26 | FRIENDS = $SERVICEHOME/friends | ||
27 | TARGET-CONNECTION-COUNT = 16 | ||
28 | AUTOCONNECT = YES | ||
29 | FRIENDS-ONLY = NO | ||
30 | MINIMUM-FRIENDS = 0 | ||
31 | |||
32 | [core] | ||
33 | AUTOSTART = NO | ||
34 | |||
35 | [transport] | ||
36 | PLUGINS = unix | ||
37 | #DEBUG = YES | ||
38 | ACCEPT_FROM6 = ::1; | ||
39 | ACCEPT_FROM = 127.0.0.1; | ||
40 | NEIGHBOUR_LIMIT = 50 | ||
41 | BINARY = gnunet-service-transport | ||
42 | CONFIG = $DEFAULTCONFIG | ||
43 | HOME = $SERVICEHOME | ||
44 | HOSTNAME = localhost | ||
45 | PORT = 12365 | ||
46 | UNIXPATH = /tmp/gnunet-p1-service-transport.sock | ||
47 | |||
48 | |||
49 | [peerinfo] | ||
50 | TRUST = $SERVICEHOME/data/credit/ | ||
51 | HOSTS = $SERVICEHOME/data/hosts/ | ||
52 | ACCEPT_FROM6 = ::1; | ||
53 | ACCEPT_FROM = 127.0.0.1; | ||
54 | BINARY = gnunet-service-peerinfo | ||
55 | CONFIG = $DEFAULTCONFIG | ||
56 | HOME = $SERVICEHOME | ||
57 | HOSTNAME = localhost | ||
58 | PORT = 12369 | ||
59 | UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock | ||
60 | |||
61 | [resolver] | ||
62 | ACCEPT_FROM6 = ::1; | ||
63 | ACCEPT_FROM = 127.0.0.1; | ||
64 | BINARY = gnunet-service-resolver | ||
65 | CONFIG = $DEFAULTCONFIG | ||
66 | HOME = $SERVICEHOME | ||
67 | HOSTNAME = localhost | ||
68 | PORT = 12364 | ||
69 | UNIXPATH = /tmp/gnunet-p1-service-resolver.sock | ||
70 | |||
71 | [statistics] | ||
72 | ACCEPT_FROM6 = ::1; | ||
73 | ACCEPT_FROM = 127.0.0.1; | ||
74 | BINARY = gnunet-service-statistics | ||
75 | CONFIG = $DEFAULTCONFIG | ||
76 | HOME = $SERVICEHOME | ||
77 | HOSTNAME = localhost | ||
78 | PORT = 12367 | ||
79 | UNIXPATH = /tmp/gnunet-p1-service-statistics.sock | ||
80 | |||
81 | [arm] | ||
82 | DEFAULTSERVICES = | ||
83 | ACCEPT_FROM6 = ::1; | ||
84 | ACCEPT_FROM = 127.0.0.1; | ||
85 | BINARY = gnunet-service-arm | ||
86 | CONFIG = $DEFAULTCONFIG | ||
87 | HOME = $SERVICEHOME | ||
88 | HOSTNAME = localhost | ||
89 | PORT = 12366 | ||
90 | UNIXPATH = /tmp/gnunet-p1-service-arm.sock | ||
91 | |||
92 | [transport-tcp] | ||
93 | TIMEOUT = 300000 | ||
94 | PORT = 12368 | ||
95 | |||
96 | [TESTING] | ||
97 | WEAKRANDOM = YES | ||
98 | |||
99 | [gnunetd] | ||
100 | HOSTKEY = $SERVICEHOME/.hostkey | ||
101 | |||
102 | [PATHS] | ||
103 | DEFAULTCONFIG = test_transport_api_unix_peer1.conf | ||
104 | SERVICEHOME = /tmp/test-gnunetd-transport-peer-1/ | ||
105 | |||
106 | |||
107 | [dht] | ||
108 | AUTOSTART = NO | ||
109 | |||
110 | |||
diff --git a/src/transport/test_transport_api_unix_peer2.conf b/src/transport/test_transport_api_unix_peer2.conf new file mode 100644 index 000000000..c297ef20e --- /dev/null +++ b/src/transport/test_transport_api_unix_peer2.conf | |||
@@ -0,0 +1,108 @@ | |||
1 | [transport-unix] | ||
2 | PORT = 22368 | ||
3 | |||
4 | [fs] | ||
5 | AUTOSTART = NO | ||
6 | |||
7 | [datastore] | ||
8 | AUTOSTART = NO | ||
9 | |||
10 | [core] | ||
11 | AUTOSTART = NO | ||
12 | |||
13 | [hostlist] | ||
14 | HTTP-PROXY = | ||
15 | SERVERS = http://gnunet.org:8080/ | ||
16 | OPTIONS = -b | ||
17 | BINARY = gnunet-daemon-hostlist | ||
18 | CONFIG = $DEFAULTCONFIG | ||
19 | HOME = $SERVICEHOME | ||
20 | HOSTNAME = localhost | ||
21 | HTTPPORT = 8080 | ||
22 | |||
23 | [topology] | ||
24 | BINARY = gnunet-daemon-topology | ||
25 | CONFIG = $DEFAULTCONFIG | ||
26 | FRIENDS = $SERVICEHOME/friends | ||
27 | TARGET-CONNECTION-COUNT = 16 | ||
28 | AUTOCONNECT = YES | ||
29 | FRIENDS-ONLY = NO | ||
30 | MINIMUM-FRIENDS = 0 | ||
31 | |||
32 | [transport] | ||
33 | PLUGINS = unix | ||
34 | #DEBUG = YES | ||
35 | PREFIX = | ||
36 | ACCEPT_FROM6 = ::1; | ||
37 | ACCEPT_FROM = 127.0.0.1; | ||
38 | NEIGHBOUR_LIMIT = 50 | ||
39 | BINARY = gnunet-service-transport | ||
40 | CONFIG = $DEFAULTCONFIG | ||
41 | HOME = $SERVICEHOME | ||
42 | HOSTNAME = localhost | ||
43 | PORT = 22365 | ||
44 | UNIXPATH = /tmp/gnunet-p2-service-transport.sock | ||
45 | #PREFIX = valgrind --track-origins=yes --leak-check=full --log-file=valgrind_udp_peer2.log | ||
46 | |||
47 | [peerinfo] | ||
48 | TRUST = $SERVICEHOME/data/credit/ | ||
49 | HOSTS = $SERVICEHOME/data/hosts/ | ||
50 | ACCEPT_FROM6 = ::1; | ||
51 | ACCEPT_FROM = 127.0.0.1; | ||
52 | BINARY = gnunet-service-peerinfo | ||
53 | CONFIG = $DEFAULTCONFIG | ||
54 | HOME = $SERVICEHOME | ||
55 | HOSTNAME = localhost | ||
56 | PORT = 22369 | ||
57 | UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock | ||
58 | |||
59 | [resolver] | ||
60 | ACCEPT_FROM6 = ::1; | ||
61 | ACCEPT_FROM = 127.0.0.1; | ||
62 | BINARY = gnunet-service-resolver | ||
63 | CONFIG = $DEFAULTCONFIG | ||
64 | HOME = $SERVICEHOME | ||
65 | HOSTNAME = localhost | ||
66 | PORT = 22364 | ||
67 | UNIXPATH = /tmp/gnunet-p2-service-resolver.sock | ||
68 | |||
69 | [statistics] | ||
70 | ACCEPT_FROM6 = ::1; | ||
71 | ACCEPT_FROM = 127.0.0.1; | ||
72 | BINARY = gnunet-service-statistics | ||
73 | CONFIG = $DEFAULTCONFIG | ||
74 | HOME = $SERVICEHOME | ||
75 | HOSTNAME = localhost | ||
76 | PORT = 22367 | ||
77 | UNIXPATH = /tmp/gnunet-p2-service-statistics.sock | ||
78 | |||
79 | [arm] | ||
80 | DEFAULTSERVICES = | ||
81 | ACCEPT_FROM6 = ::1; | ||
82 | ACCEPT_FROM = 127.0.0.1; | ||
83 | BINARY = gnunet-service-arm | ||
84 | CONFIG = $DEFAULTCONFIG | ||
85 | HOME = $SERVICEHOME | ||
86 | HOSTNAME = localhost | ||
87 | PORT = 22366 | ||
88 | UNIXPATH = /tmp/gnunet-p2-service-arm.sock | ||
89 | |||
90 | [transport-tcp] | ||
91 | TIMEOUT = 300000 | ||
92 | PORT = 22368 | ||
93 | |||
94 | [TESTING] | ||
95 | WEAKRANDOM = YES | ||
96 | |||
97 | [gnunetd] | ||
98 | HOSTKEY = $SERVICEHOME/.hostkey | ||
99 | |||
100 | [PATHS] | ||
101 | DEFAULTCONFIG = test_transport_api_unix_peer2.conf | ||
102 | SERVICEHOME = /tmp/test-gnunetd-transport-peer-2/ | ||
103 | |||
104 | |||
105 | [dht] | ||
106 | AUTOSTART = NO | ||
107 | |||
108 | |||
diff --git a/src/transport/test_transport_api_unreliability.c b/src/transport/test_transport_api_unreliability.c new file mode 100644 index 000000000..caafdbc5d --- /dev/null +++ b/src/transport/test_transport_api_unreliability.c | |||
@@ -0,0 +1,922 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2009, 2010 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file transport/test_transport_api_unreliability.c | ||
22 | * @brief test case for transports; ensures messages get | ||
23 | * through, regardless of order | ||
24 | * | ||
25 | * This test case serves as a base for unreliable | ||
26 | * transport test cases to check that the transports | ||
27 | * achieve reliable message delivery. | ||
28 | */ | ||
29 | #include "platform.h" | ||
30 | #include "gnunet_common.h" | ||
31 | #include "gnunet_hello_lib.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 "gnunet_server_lib.h" | ||
37 | #include "gnunet_transport_service.h" | ||
38 | #include "gauger.h" | ||
39 | #include "transport.h" | ||
40 | |||
41 | #define VERBOSE GNUNET_NO | ||
42 | |||
43 | #define VERBOSE_ARM GNUNET_NO | ||
44 | |||
45 | #define START_ARM GNUNET_YES | ||
46 | |||
47 | /** | ||
48 | * Note that this value must not significantly exceed | ||
49 | * 'MAX_PENDING' in 'gnunet-service-transport.c', otherwise | ||
50 | * messages may be dropped even for a reliable transport. | ||
51 | */ | ||
52 | #define TOTAL_MSGS (80000 * 3) /* Total messages should be divisible by 8, so we can make a nice bitmap */ | ||
53 | |||
54 | /** | ||
55 | * How long until we give up on transmitting the message? | ||
56 | */ | ||
57 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1500) | ||
58 | |||
59 | #define UNRELIABLE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) | ||
60 | |||
61 | #define MTYPE 12345 | ||
62 | |||
63 | struct PeerContext | ||
64 | { | ||
65 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
66 | struct GNUNET_TRANSPORT_Handle *th; | ||
67 | struct GNUNET_PeerIdentity id; | ||
68 | #if START_ARM | ||
69 | struct GNUNET_OS_Process *arm_proc; | ||
70 | #endif | ||
71 | }; | ||
72 | |||
73 | static struct PeerContext p1; | ||
74 | |||
75 | static struct PeerContext p2; | ||
76 | |||
77 | static int ok; | ||
78 | |||
79 | static int is_tcp; | ||
80 | |||
81 | static int is_tcp_nat; | ||
82 | |||
83 | static int is_http; | ||
84 | |||
85 | static int is_https; | ||
86 | |||
87 | static int is_udp; | ||
88 | |||
89 | static int is_unix; | ||
90 | |||
91 | static int connected; | ||
92 | |||
93 | static unsigned long long total_bytes; | ||
94 | |||
95 | static struct GNUNET_TIME_Absolute start_time; | ||
96 | |||
97 | static GNUNET_SCHEDULER_TaskIdentifier die_task; | ||
98 | |||
99 | static char *key_file_p1; | ||
100 | static char *cert_file_p1; | ||
101 | |||
102 | static char *key_file_p2; | ||
103 | static char *cert_file_p2; | ||
104 | |||
105 | static char *test_name; | ||
106 | |||
107 | static char bitmap[TOTAL_MSGS / 8]; | ||
108 | |||
109 | static int msg_scheduled; | ||
110 | static int msg_sent; | ||
111 | static int msg_recv_expected; | ||
112 | static int msg_recv; | ||
113 | static struct GNUNET_TRANSPORT_TransmitHandle * transmit_handle; | ||
114 | |||
115 | #if VERBOSE | ||
116 | #define OKPP do { ok++; fprintf (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0) | ||
117 | #else | ||
118 | #define OKPP do { ok++; } while (0) | ||
119 | #endif | ||
120 | |||
121 | /** | ||
122 | * Sets a bit active in the bitmap. | ||
123 | * | ||
124 | * @param bitIdx which bit to set | ||
125 | */ | ||
126 | static void | ||
127 | set_bit (unsigned int bitIdx) | ||
128 | { | ||
129 | size_t arraySlot; | ||
130 | unsigned int targetBit; | ||
131 | if (bitIdx > sizeof(bitmap) * 8) | ||
132 | { | ||
133 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "setting bit %d of %d(!)\n", bitIdx, sizeof(bitmap) * 8); | ||
134 | return; | ||
135 | } | ||
136 | GNUNET_assert(bitIdx < sizeof(bitmap) * 8); | ||
137 | arraySlot = bitIdx / 8; | ||
138 | targetBit = (1L << (bitIdx % 8)); | ||
139 | bitmap[arraySlot] |= targetBit; | ||
140 | } | ||
141 | |||
142 | /** | ||
143 | * Obtain a bit from bitmap. | ||
144 | * @param map the bitmap | ||
145 | * @param bit index from bitmap | ||
146 | * | ||
147 | * @return Bit \a bit from hashcode \a code | ||
148 | */ | ||
149 | int | ||
150 | get_bit (const char *map, unsigned int bit) | ||
151 | { | ||
152 | if (bit >= TOTAL_MSGS) | ||
153 | { | ||
154 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "get bit %d of %d(!?!?)\n", bit, sizeof(bitmap) * 8); | ||
155 | return 0; | ||
156 | } | ||
157 | return ((map)[bit >> 3] & (1 << (bit & 7))) > 0; | ||
158 | } | ||
159 | |||
160 | static void | ||
161 | end () | ||
162 | { | ||
163 | unsigned long long delta; | ||
164 | int i; | ||
165 | int result; | ||
166 | char *value_name; | ||
167 | |||
168 | result = 0; | ||
169 | for (i = 0; i < TOTAL_MSGS; i++) | ||
170 | { | ||
171 | if (get_bit(bitmap, i) == 0) | ||
172 | { | ||
173 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Did not receive message %d\n", i); | ||
174 | result = -1; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | GNUNET_SCHEDULER_cancel (die_task); | ||
179 | die_task = GNUNET_SCHEDULER_NO_TASK; | ||
180 | #if VERBOSE | ||
181 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transports!\n"); | ||
182 | #endif | ||
183 | GNUNET_TRANSPORT_disconnect (p1.th); | ||
184 | GNUNET_TRANSPORT_disconnect (p2.th); | ||
185 | #if VERBOSE | ||
186 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
187 | "Transports disconnected, returning success!\n"); | ||
188 | #endif | ||
189 | delta = GNUNET_TIME_absolute_get_duration (start_time).rel_value; | ||
190 | GNUNET_asprintf(&value_name, "unreliable_kbs_%s", test_name); | ||
191 | GAUGER (value_name, (int)(total_bytes * 1000 / 1024 /delta)); | ||
192 | GNUNET_free(value_name); | ||
193 | fprintf (stderr, | ||
194 | "\nThroughput was %llu kb/s\n", | ||
195 | total_bytes * 1000 / 1024 / delta); | ||
196 | ok = result; | ||
197 | |||
198 | } | ||
199 | |||
200 | static void | ||
201 | end_unreliably () | ||
202 | { | ||
203 | unsigned long long delta; | ||
204 | int i; | ||
205 | int num_failed; | ||
206 | char *value_name; | ||
207 | num_failed = 0; | ||
208 | for (i = 0; i < TOTAL_MSGS; i++) | ||
209 | { | ||
210 | if (get_bit(bitmap, i) == 0) | ||
211 | { | ||
212 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Did not receive message %d\n", i); | ||
213 | num_failed++; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | die_task = GNUNET_SCHEDULER_NO_TASK; | ||
218 | #if VERBOSE | ||
219 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transports!\n"); | ||
220 | #endif | ||
221 | GNUNET_TRANSPORT_disconnect (p1.th); | ||
222 | GNUNET_TRANSPORT_disconnect (p2.th); | ||
223 | #if VERBOSE | ||
224 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
225 | "Transports disconnected, returning success!\n"); | ||
226 | #endif | ||
227 | delta = GNUNET_TIME_absolute_get_duration (start_time).rel_value; | ||
228 | fprintf (stderr, | ||
229 | "\nThroughput was %llu kb/s\n", | ||
230 | total_bytes * 1000 / 1024 / delta); | ||
231 | GNUNET_asprintf(&value_name, "unreliable_kbs_%s", test_name); | ||
232 | GAUGER (value_name, (int)(total_bytes * 1000 / 1024 /delta)); | ||
233 | GNUNET_free(value_name); | ||
234 | GNUNET_asprintf(&value_name, "unreliable_failed_%s", test_name); | ||
235 | GAUGER (value_name, (int)num_failed); | ||
236 | GNUNET_free(value_name); | ||
237 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Had %d failed messages!\n", num_failed); | ||
238 | ok = 0; | ||
239 | |||
240 | } | ||
241 | |||
242 | |||
243 | |||
244 | static void | ||
245 | stop_arm (struct PeerContext *p) | ||
246 | { | ||
247 | #if START_ARM | ||
248 | if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) | ||
249 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); | ||
250 | GNUNET_OS_process_wait (p->arm_proc); | ||
251 | GNUNET_OS_process_close (p->arm_proc); | ||
252 | p->arm_proc = NULL; | ||
253 | #endif | ||
254 | GNUNET_CONFIGURATION_destroy (p->cfg); | ||
255 | } | ||
256 | |||
257 | |||
258 | static void | ||
259 | end_badly (void *cls, | ||
260 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
261 | { | ||
262 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
263 | "Reliability failed: \nLast message sent %u \nNext message scheduled %u\nLast message received %u\nMessage expected %u \n ", msg_sent, msg_scheduled, msg_recv, msg_recv_expected); | ||
264 | GNUNET_break (0); | ||
265 | GNUNET_TRANSPORT_disconnect (p1.th); | ||
266 | GNUNET_TRANSPORT_disconnect (p2.th); | ||
267 | ok = 1; | ||
268 | } | ||
269 | |||
270 | |||
271 | struct TestMessage | ||
272 | { | ||
273 | struct GNUNET_MessageHeader header; | ||
274 | uint32_t num; | ||
275 | }; | ||
276 | |||
277 | |||
278 | static unsigned int | ||
279 | get_size (unsigned int iter) | ||
280 | { | ||
281 | unsigned int ret; | ||
282 | |||
283 | if (iter < 60000) | ||
284 | return iter + sizeof (struct TestMessage); | ||
285 | ret = (iter * iter * iter); | ||
286 | return sizeof (struct TestMessage) + (ret % 60000); | ||
287 | } | ||
288 | |||
289 | |||
290 | static void | ||
291 | notify_receive (void *cls, | ||
292 | const struct GNUNET_PeerIdentity *peer, | ||
293 | const struct GNUNET_MessageHeader *message, | ||
294 | const struct GNUNET_TRANSPORT_ATS_Information *ats, | ||
295 | uint32_t ats_count) | ||
296 | { | ||
297 | static int n; | ||
298 | unsigned int s; | ||
299 | char cbuf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; | ||
300 | const struct TestMessage *hdr; | ||
301 | |||
302 | hdr = (const struct TestMessage*) message; | ||
303 | |||
304 | if (MTYPE != ntohs (message->type)) | ||
305 | return; | ||
306 | msg_recv_expected = n; | ||
307 | msg_recv = ntohl(hdr->num); | ||
308 | s = get_size (ntohl(hdr->num)); | ||
309 | |||
310 | if (ntohs (message->size) != s) | ||
311 | { | ||
312 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
313 | "Expected message %u of size %u, got %u bytes of message %u\n", | ||
314 | ntohl(hdr->num), s, | ||
315 | ntohs (message->size), | ||
316 | ntohl (hdr->num)); | ||
317 | GNUNET_SCHEDULER_cancel (die_task); | ||
318 | die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL); | ||
319 | return; | ||
320 | } | ||
321 | |||
322 | memset (cbuf, ntohl(hdr->num), s - sizeof (struct TestMessage)); | ||
323 | if (0 != memcmp (cbuf, | ||
324 | &hdr[1], | ||
325 | s - sizeof (struct TestMessage))) | ||
326 | { | ||
327 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
328 | "Expected message %u with bits %u, but body did not match\n", | ||
329 | ntohl(hdr->num), (unsigned char) n); | ||
330 | GNUNET_SCHEDULER_cancel (die_task); | ||
331 | die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL); | ||
332 | return; | ||
333 | } | ||
334 | #if VERBOSE | ||
335 | if (ntohl(hdr->num) % 5 == 0) | ||
336 | { | ||
337 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
338 | "Got message %u of size %u\n", | ||
339 | ntohl (hdr->num), | ||
340 | ntohs (message->size)); | ||
341 | } | ||
342 | #endif | ||
343 | n++; | ||
344 | set_bit(ntohl(hdr->num)); | ||
345 | if (0 == (n % (5000))) | ||
346 | { | ||
347 | fprintf (stderr, "."); | ||
348 | GNUNET_SCHEDULER_cancel (die_task); | ||
349 | die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | ||
350 | &end_badly, | ||
351 | NULL); | ||
352 | } | ||
353 | if (n == TOTAL_MSGS) | ||
354 | end (); | ||
355 | } | ||
356 | |||
357 | |||
358 | static size_t | ||
359 | notify_ready (void *cls, size_t size, void *buf) | ||
360 | { | ||
361 | static int n; | ||
362 | char *cbuf = buf; | ||
363 | struct TestMessage hdr; | ||
364 | unsigned int s; | ||
365 | unsigned int ret; | ||
366 | |||
367 | if (buf == NULL) | ||
368 | { | ||
369 | GNUNET_break (0); | ||
370 | ok = 42; | ||
371 | return 0; | ||
372 | } | ||
373 | ret = 0; | ||
374 | s = get_size (n); | ||
375 | GNUNET_assert (size >= s); | ||
376 | GNUNET_assert (buf != NULL); | ||
377 | cbuf = buf; | ||
378 | do | ||
379 | { | ||
380 | hdr.header.size = htons (s); | ||
381 | hdr.header.type = htons (MTYPE); | ||
382 | hdr.num = htonl (n); | ||
383 | msg_sent = n; | ||
384 | memcpy (&cbuf[ret], &hdr, sizeof (struct TestMessage)); | ||
385 | ret += sizeof (struct TestMessage); | ||
386 | memset (&cbuf[ret], n, s - sizeof (struct TestMessage)); | ||
387 | ret += s - sizeof (struct TestMessage); | ||
388 | #if VERBOSE | ||
389 | if (n % 5000 == 0) | ||
390 | { | ||
391 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
392 | "Sending message %u of size %u\n", | ||
393 | n, | ||
394 | s); | ||
395 | } | ||
396 | #endif | ||
397 | n++; | ||
398 | s = get_size (n); | ||
399 | if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16)) | ||
400 | break; /* sometimes pack buffer full, sometimes not */ | ||
401 | } | ||
402 | while (size - ret >= s); | ||
403 | if (n < TOTAL_MSGS) | ||
404 | { | ||
405 | GNUNET_TRANSPORT_notify_transmit_ready (p2.th, | ||
406 | &p1.id, | ||
407 | s, 0, TIMEOUT, | ||
408 | ¬ify_ready, | ||
409 | NULL); | ||
410 | msg_scheduled = n; | ||
411 | } | ||
412 | else | ||
413 | { | ||
414 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "All messages scheduled to be sent!!\n"); | ||
415 | GNUNET_SCHEDULER_cancel(die_task); | ||
416 | die_task = GNUNET_SCHEDULER_add_delayed (UNRELIABLE_TIMEOUT, &end_unreliably, NULL); | ||
417 | } | ||
418 | if (n % 5000 == 0) | ||
419 | { | ||
420 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
421 | "Returning total message block of size %u\n", | ||
422 | ret); | ||
423 | } | ||
424 | total_bytes += ret; | ||
425 | return ret; | ||
426 | } | ||
427 | |||
428 | |||
429 | static void | ||
430 | notify_connect (void *cls, | ||
431 | const struct GNUNET_PeerIdentity *peer, | ||
432 | const struct GNUNET_TRANSPORT_ATS_Information *ats, | ||
433 | uint32_t ats_count) | ||
434 | { | ||
435 | if (cls == &p1) | ||
436 | { | ||
437 | GNUNET_TRANSPORT_set_quota (p1.th, | ||
438 | &p2.id, | ||
439 | GNUNET_BANDWIDTH_value_init (1024 * 1024 * 1024), | ||
440 | GNUNET_BANDWIDTH_value_init (1024 * 1024 * 1024), | ||
441 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
442 | NULL, NULL); | ||
443 | start_time = GNUNET_TIME_absolute_get (); | ||
444 | connected++; | ||
445 | } | ||
446 | else | ||
447 | { | ||
448 | GNUNET_TRANSPORT_set_quota (p2.th, | ||
449 | &p1.id, | ||
450 | GNUNET_BANDWIDTH_value_init (1024 * 1024 * 1024), | ||
451 | GNUNET_BANDWIDTH_value_init (1024 * 1024 * 1024), | ||
452 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
453 | NULL, NULL); | ||
454 | connected++; | ||
455 | } | ||
456 | |||
457 | if (connected == 2) | ||
458 | { | ||
459 | |||
460 | if ((transmit_handle!=NULL) && (cls == NULL)) | ||
461 | GNUNET_TRANSPORT_notify_transmit_ready_cancel(transmit_handle); | ||
462 | if ((transmit_handle!=NULL) && (cls == &transmit_handle)) | ||
463 | transmit_handle=NULL; | ||
464 | GNUNET_TRANSPORT_notify_transmit_ready (p2.th, | ||
465 | &p1.id, | ||
466 | get_size (0), 0, TIMEOUT, | ||
467 | ¬ify_ready, | ||
468 | NULL); | ||
469 | } | ||
470 | #if VERBOSE | ||
471 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
472 | "Peer `%4s' connected to us (%p)!\n", GNUNET_i2s (peer), cls); | ||
473 | #endif | ||
474 | } | ||
475 | |||
476 | |||
477 | static void | ||
478 | notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) | ||
479 | { | ||
480 | #if VERBOSE | ||
481 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
482 | "Peer `%4s' disconnected (%p)!\n", | ||
483 | GNUNET_i2s (peer), cls); | ||
484 | #endif | ||
485 | } | ||
486 | |||
487 | |||
488 | static void | ||
489 | setup_peer (struct PeerContext *p, const char *cfgname) | ||
490 | { | ||
491 | p->cfg = GNUNET_CONFIGURATION_create (); | ||
492 | #if START_ARM | ||
493 | p->arm_proc = GNUNET_OS_start_process (NULL, NULL, | ||
494 | "gnunet-service-arm", | ||
495 | "gnunet-service-arm", | ||
496 | #if VERBOSE_ARM | ||
497 | "-L", "DEBUG", | ||
498 | #endif | ||
499 | "-c", cfgname, NULL); | ||
500 | #endif | ||
501 | GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); | ||
502 | |||
503 | if (is_https) | ||
504 | { | ||
505 | struct stat sbuf; | ||
506 | if (p==&p1) | ||
507 | { | ||
508 | if (GNUNET_CONFIGURATION_have_value (p->cfg, | ||
509 | "transport-https", "KEY_FILE")) | ||
510 | GNUNET_CONFIGURATION_get_value_string (p->cfg, "transport-https", "KEY_FILE", &key_file_p1); | ||
511 | if (key_file_p1 == NULL) | ||
512 | GNUNET_asprintf(&key_file_p1,"https_p1.key"); | ||
513 | if (0 == stat (key_file_p1, &sbuf )) | ||
514 | { | ||
515 | if (0 == remove(key_file_p1)) | ||
516 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Successfully removed existing private key file `%s'\n",key_file_p1); | ||
517 | else | ||
518 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to remove private key file `%s'\n",key_file_p1); | ||
519 | } | ||
520 | if (GNUNET_CONFIGURATION_have_value (p->cfg,"transport-https", "CERT_FILE")) | ||
521 | GNUNET_CONFIGURATION_get_value_string (p->cfg, "transport-https", "CERT_FILE", &cert_file_p1); | ||
522 | if (cert_file_p1 == NULL) | ||
523 | GNUNET_asprintf(&cert_file_p1,"https_p1.cert"); | ||
524 | if (0 == stat (cert_file_p1, &sbuf )) | ||
525 | { | ||
526 | if (0 == remove(cert_file_p1)) | ||
527 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Successfully removed existing certificate file `%s'\n",cert_file_p1); | ||
528 | else | ||
529 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to remove existing certificate file `%s'\n",cert_file_p1); | ||
530 | } | ||
531 | } | ||
532 | else if (p==&p2) | ||
533 | { | ||
534 | if (GNUNET_CONFIGURATION_have_value (p->cfg, | ||
535 | "transport-https", "KEY_FILE")) | ||
536 | GNUNET_CONFIGURATION_get_value_string (p->cfg, "transport-https", "KEY_FILE", &key_file_p2); | ||
537 | if (key_file_p2 == NULL) | ||
538 | GNUNET_asprintf(&key_file_p2,"https_p2.key"); | ||
539 | if (0 == stat (key_file_p2, &sbuf )) | ||
540 | { | ||
541 | if (0 == remove(key_file_p2)) | ||
542 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Successfully removed existing private key file `%s'\n",key_file_p2); | ||
543 | else | ||
544 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to remove private key file `%s'\n",key_file_p2); | ||
545 | } | ||
546 | if (GNUNET_CONFIGURATION_have_value (p->cfg,"transport-https", "CERT_FILE")) | ||
547 | GNUNET_CONFIGURATION_get_value_string (p->cfg, "transport-https", "CERT_FILE", &cert_file_p2); | ||
548 | if (cert_file_p2 == NULL) | ||
549 | GNUNET_asprintf(&cert_file_p2,"https_p2.cert"); | ||
550 | if (0 == stat (cert_file_p2, &sbuf )) | ||
551 | { | ||
552 | if (0 == remove(cert_file_p2)) | ||
553 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Successfully removed existing certificate file `%s'\n",cert_file_p2); | ||
554 | else | ||
555 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to remove existing certificate file `%s'\n",cert_file_p2); | ||
556 | } | ||
557 | } | ||
558 | } | ||
559 | |||
560 | p->th = GNUNET_TRANSPORT_connect (p->cfg, NULL, | ||
561 | p, | ||
562 | ¬ify_receive, | ||
563 | ¬ify_connect, | ||
564 | ¬ify_disconnect); | ||
565 | GNUNET_assert (p->th != NULL); | ||
566 | } | ||
567 | |||
568 | static size_t | ||
569 | notify_ready_connect (void *cls, size_t size, void *buf) | ||
570 | { | ||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | static void | ||
575 | exchange_hello_last (void *cls, | ||
576 | const struct GNUNET_MessageHeader *message) | ||
577 | { | ||
578 | struct PeerContext *me = cls; | ||
579 | transmit_handle = NULL; | ||
580 | GNUNET_TRANSPORT_get_hello_cancel (p2.th, &exchange_hello_last, me); | ||
581 | #if VERBOSE | ||
582 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
583 | "Exchanging HELLO with peer (%p)!\n", cls); | ||
584 | #endif | ||
585 | GNUNET_assert (ok >= 3); | ||
586 | OKPP; | ||
587 | GNUNET_assert (message != NULL); | ||
588 | GNUNET_assert (GNUNET_OK == | ||
589 | GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) | ||
590 | message, &me->id)); | ||
591 | |||
592 | GNUNET_assert(NULL != (transmit_handle = GNUNET_TRANSPORT_notify_transmit_ready (p2.th, | ||
593 | &p1.id, | ||
594 | sizeof (struct GNUNET_MessageHeader), 0, | ||
595 | TIMEOUT, | ||
596 | ¬ify_ready_connect, | ||
597 | &transmit_handle))); | ||
598 | |||
599 | /* both HELLOs exchanged, get ready to test transmission! */ | ||
600 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
601 | "Finished exchanging HELLOs, now waiting for transmission!\n"); | ||
602 | } | ||
603 | |||
604 | |||
605 | static void | ||
606 | exchange_hello (void *cls, | ||
607 | const struct GNUNET_MessageHeader *message) | ||
608 | { | ||
609 | struct PeerContext *me = cls; | ||
610 | |||
611 | GNUNET_TRANSPORT_get_hello_cancel (p1.th, &exchange_hello, me); | ||
612 | #if VERBOSE | ||
613 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
614 | "Exchanging HELLO with peer (%p)!\n", cls); | ||
615 | #endif | ||
616 | GNUNET_assert (ok >= 2); | ||
617 | OKPP; | ||
618 | GNUNET_assert (message != NULL); | ||
619 | GNUNET_assert (GNUNET_OK == | ||
620 | GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) | ||
621 | message, &me->id)); | ||
622 | |||
623 | #if VERBOSE | ||
624 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
625 | "Received HELLO size %d\n", | ||
626 | GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); | ||
627 | #endif | ||
628 | GNUNET_TRANSPORT_offer_hello (p2.th, message); | ||
629 | GNUNET_TRANSPORT_get_hello (p2.th, &exchange_hello_last, &p2); | ||
630 | } | ||
631 | |||
632 | /** | ||
633 | * Return the actual path to a file found in the current | ||
634 | * PATH environment variable. | ||
635 | * | ||
636 | * @param binary the name of the file to find | ||
637 | */ | ||
638 | static char * | ||
639 | get_path_from_PATH (char *binary) | ||
640 | { | ||
641 | char *path; | ||
642 | char *pos; | ||
643 | char *end; | ||
644 | char *buf; | ||
645 | const char *p; | ||
646 | |||
647 | p = getenv ("PATH"); | ||
648 | if (p == NULL) | ||
649 | { | ||
650 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
651 | _("PATH environment variable is unset.\n")); | ||
652 | return NULL; | ||
653 | } | ||
654 | path = GNUNET_strdup (p); /* because we write on it */ | ||
655 | buf = GNUNET_malloc (strlen (path) + 20); | ||
656 | pos = path; | ||
657 | |||
658 | while (NULL != (end = strchr (pos, PATH_SEPARATOR))) | ||
659 | { | ||
660 | *end = '\0'; | ||
661 | sprintf (buf, "%s/%s", pos, binary); | ||
662 | if (GNUNET_DISK_file_test (buf) == GNUNET_YES) | ||
663 | { | ||
664 | GNUNET_free (path); | ||
665 | return buf; | ||
666 | } | ||
667 | pos = end + 1; | ||
668 | } | ||
669 | sprintf (buf, "%s/%s", pos, binary); | ||
670 | if (GNUNET_DISK_file_test (buf) == GNUNET_YES) | ||
671 | { | ||
672 | GNUNET_free (path); | ||
673 | return buf; | ||
674 | } | ||
675 | GNUNET_free (buf); | ||
676 | GNUNET_free (path); | ||
677 | return NULL; | ||
678 | } | ||
679 | |||
680 | /** | ||
681 | * Check whether the suid bit is set on a file. | ||
682 | * Attempts to find the file using the current | ||
683 | * PATH environment variable as a search path. | ||
684 | * | ||
685 | * @param binary the name of the file to check | ||
686 | * | ||
687 | * @return GNUNET_YES if the binary is found and | ||
688 | * can be run properly, GNUNET_NO otherwise | ||
689 | */ | ||
690 | static int | ||
691 | check_gnunet_nat_binary(char *binary) | ||
692 | { | ||
693 | struct stat statbuf; | ||
694 | char *p; | ||
695 | #ifdef MINGW | ||
696 | SOCKET rawsock; | ||
697 | #endif | ||
698 | |||
699 | #ifdef MINGW | ||
700 | char *binaryexe; | ||
701 | GNUNET_asprintf (&binaryexe, "%s.exe", binary); | ||
702 | p = get_path_from_PATH (binaryexe); | ||
703 | free (binaryexe); | ||
704 | #else | ||
705 | p = get_path_from_PATH (binary); | ||
706 | #endif | ||
707 | if (p == NULL) | ||
708 | { | ||
709 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
710 | _("Could not find binary `%s' in PATH!\n"), | ||
711 | binary); | ||
712 | return GNUNET_NO; | ||
713 | } | ||
714 | if (0 != STAT (p, &statbuf)) | ||
715 | { | ||
716 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
717 | _("stat (%s) failed: %s\n"), | ||
718 | p, | ||
719 | STRERROR (errno)); | ||
720 | GNUNET_free (p); | ||
721 | return GNUNET_SYSERR; | ||
722 | } | ||
723 | GNUNET_free (p); | ||
724 | #ifndef MINGW | ||
725 | if ( (0 != (statbuf.st_mode & S_ISUID)) && | ||
726 | (statbuf.st_uid == 0) ) | ||
727 | return GNUNET_YES; | ||
728 | return GNUNET_NO; | ||
729 | #else | ||
730 | rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); | ||
731 | if (INVALID_SOCKET == rawsock) | ||
732 | { | ||
733 | DWORD err = GetLastError (); | ||
734 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
735 | "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) have failed! GLE = %d\n", err); | ||
736 | return GNUNET_NO; /* not running as administrator */ | ||
737 | } | ||
738 | closesocket (rawsock); | ||
739 | return GNUNET_YES; | ||
740 | #endif | ||
741 | } | ||
742 | |||
743 | static void | ||
744 | run (void *cls, | ||
745 | char *const *args, | ||
746 | const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
747 | { | ||
748 | GNUNET_assert (ok == 1); | ||
749 | OKPP; | ||
750 | die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | ||
751 | &end_badly, | ||
752 | NULL); | ||
753 | if (is_tcp) | ||
754 | { | ||
755 | setup_peer (&p1, "test_transport_api_tcp_peer1.conf"); | ||
756 | setup_peer (&p2, "test_transport_api_tcp_peer2.conf"); | ||
757 | } | ||
758 | else if (is_http) | ||
759 | { | ||
760 | setup_peer (&p1, "test_transport_api_rel_http_peer1.conf"); | ||
761 | setup_peer (&p2, "test_transport_api_rel_http_peer2.conf"); | ||
762 | } | ||
763 | else if (is_https) | ||
764 | { | ||
765 | setup_peer (&p1, "test_transport_api_rel_https_peer1.conf"); | ||
766 | setup_peer (&p2, "test_transport_api_rel_https_peer2.conf"); | ||
767 | } | ||
768 | else if (is_udp) | ||
769 | { | ||
770 | setup_peer (&p1, "test_transport_api_udp_peer1.conf"); | ||
771 | setup_peer (&p2, "test_transport_api_udp_peer2.conf"); | ||
772 | } | ||
773 | else if (is_unix) | ||
774 | { | ||
775 | setup_peer (&p1, "test_transport_api_unix_peer1.conf"); | ||
776 | setup_peer (&p2, "test_transport_api_unix_peer2.conf"); | ||
777 | } | ||
778 | else if (is_tcp_nat) | ||
779 | { | ||
780 | setup_peer (&p1, "test_transport_api_tcp_nat_peer1.conf"); | ||
781 | setup_peer (&p2, "test_transport_api_tcp_nat_peer2.conf"); | ||
782 | } | ||
783 | else | ||
784 | GNUNET_assert (0); | ||
785 | GNUNET_assert(p1.th != NULL); | ||
786 | GNUNET_assert(p2.th != NULL); | ||
787 | GNUNET_TRANSPORT_get_hello (p1.th, &exchange_hello, &p1); | ||
788 | } | ||
789 | |||
790 | |||
791 | static int | ||
792 | check () | ||
793 | { | ||
794 | char *const argv[] = { "test-transport-api-reliability", | ||
795 | "-c", | ||
796 | "test_transport_api_data.conf", | ||
797 | #if VERBOSE | ||
798 | "-L", "DEBUG", | ||
799 | #endif | ||
800 | NULL | ||
801 | }; | ||
802 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
803 | GNUNET_GETOPT_OPTION_END | ||
804 | }; | ||
805 | |||
806 | #if WRITECONFIG | ||
807 | setTransportOptions("test_transport_api_data.conf"); | ||
808 | #endif | ||
809 | ok = 1; | ||
810 | |||
811 | if ((GNUNET_YES == is_tcp_nat) && (check_gnunet_nat_binary("gnunet-nat-server") != GNUNET_YES)) | ||
812 | { | ||
813 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Not running NAT test case, binaries not properly installed.\n"); | ||
814 | return 0; | ||
815 | } | ||
816 | |||
817 | GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, | ||
818 | argv, "test-transport-api-reliability", "nohelp", | ||
819 | options, &run, &ok); | ||
820 | stop_arm (&p1); | ||
821 | stop_arm (&p2); | ||
822 | |||
823 | if (is_https) | ||
824 | { | ||
825 | struct stat sbuf; | ||
826 | if (0 == stat (cert_file_p1, &sbuf )) | ||
827 | { | ||
828 | if (0 == remove(cert_file_p1)) | ||
829 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully removed existing certificate file `%s'\n",cert_file_p1); | ||
830 | else | ||
831 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to remove certfile `%s'\n",cert_file_p1); | ||
832 | } | ||
833 | |||
834 | if (0 == stat (key_file_p1, &sbuf )) | ||
835 | { | ||
836 | if (0 == remove(key_file_p1)) | ||
837 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully removed private key file `%s'\n",key_file_p1); | ||
838 | else | ||
839 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to private key file `%s'\n",key_file_p1); | ||
840 | } | ||
841 | |||
842 | if (0 == stat (cert_file_p2, &sbuf )) | ||
843 | { | ||
844 | if (0 == remove(cert_file_p2)) | ||
845 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully removed existing certificate file `%s'\n",cert_file_p2); | ||
846 | else | ||
847 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to remove certfile `%s'\n",cert_file_p2); | ||
848 | } | ||
849 | |||
850 | if (0 == stat (key_file_p2, &sbuf )) | ||
851 | { | ||
852 | if (0 == remove(key_file_p2)) | ||
853 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully removed private key file `%s'\n",key_file_p2); | ||
854 | else | ||
855 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to private key file `%s'\n",key_file_p2); | ||
856 | } | ||
857 | GNUNET_free(key_file_p1); | ||
858 | GNUNET_free(key_file_p2); | ||
859 | GNUNET_free(cert_file_p1); | ||
860 | GNUNET_free(cert_file_p2); | ||
861 | } | ||
862 | |||
863 | return ok; | ||
864 | } | ||
865 | |||
866 | |||
867 | int | ||
868 | main (int argc, char *argv[]) | ||
869 | { | ||
870 | int ret; | ||
871 | #ifdef MINGW | ||
872 | return GNUNET_SYSERR; | ||
873 | #endif | ||
874 | |||
875 | GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-1"); | ||
876 | GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-2"); | ||
877 | |||
878 | if (strstr(argv[0], "tcp_nat") != NULL) | ||
879 | { | ||
880 | is_tcp_nat = GNUNET_YES; | ||
881 | GNUNET_asprintf(&test_name, "tcp_nat"); | ||
882 | } | ||
883 | else if (strstr(argv[0], "tcp") != NULL) | ||
884 | { | ||
885 | is_tcp = GNUNET_YES; | ||
886 | GNUNET_asprintf(&test_name, "tcp"); | ||
887 | } | ||
888 | else if (strstr(argv[0], "https") != NULL) | ||
889 | { | ||
890 | is_https = GNUNET_YES; | ||
891 | GNUNET_asprintf(&test_name, "https"); | ||
892 | } | ||
893 | else if (strstr(argv[0], "http") != NULL) | ||
894 | { | ||
895 | is_http = GNUNET_YES; | ||
896 | GNUNET_asprintf(&test_name, "http"); | ||
897 | } | ||
898 | else if (strstr(argv[0], "udp") != NULL) | ||
899 | { | ||
900 | is_udp = GNUNET_YES; | ||
901 | GNUNET_asprintf(&test_name, "udp"); | ||
902 | } | ||
903 | else if (strstr(argv[0], "unix") != NULL) | ||
904 | { | ||
905 | is_unix = GNUNET_YES; | ||
906 | GNUNET_asprintf(&test_name, "unix"); | ||
907 | } | ||
908 | GNUNET_log_setup ("test-transport-api-reliability", | ||
909 | #if VERBOSE | ||
910 | "DEBUG", | ||
911 | #else | ||
912 | "WARNING", | ||
913 | #endif | ||
914 | NULL); | ||
915 | ret = check (); | ||
916 | GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-1"); | ||
917 | GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-2"); | ||
918 | GNUNET_free_non_null(test_name); | ||
919 | return ret; | ||
920 | } | ||
921 | |||
922 | /* end of test_transport_api_reliability.c */ | ||