diff options
author | ng0 <ng0@n0.is> | 2019-09-10 16:59:32 +0000 |
---|---|---|
committer | ng0 <ng0@n0.is> | 2019-09-10 16:59:32 +0000 |
commit | 04b6df21cd281e8cd540139f8d9ae85defc1961c (patch) | |
tree | 6357199445df8d5c0c631bc8f10aef838b1f9f1e /src/gns | |
parent | 483b0139a218a5f8a8311bda3eb23bcd88f57688 (diff) | |
download | gnunet-04b6df21cd281e8cd540139f8d9ae85defc1961c.tar.gz gnunet-04b6df21cd281e8cd540139f8d9ae85defc1961c.zip |
remove CYGWIN codeblocks, drop vendored Windows openvpn, drop win32 specific files.
configures and builds okay.
testsuite wasn't checked, will be checked.
diff including the plibc removal is now around 14370 lines of code less.
Diffstat (limited to 'src/gns')
-rw-r--r-- | src/gns/Makefile.am | 60 | ||||
-rw-r--r-- | src/gns/gns-helper-service-w32.conf | 4 | ||||
-rw-r--r-- | src/gns/gnunet-gns-helper-service-w32.c | 803 | ||||
-rw-r--r-- | src/gns/nss/Makefile.am | 5 | ||||
-rw-r--r-- | src/gns/w32nsp-install.c | 143 | ||||
-rw-r--r-- | src/gns/w32nsp-resolve.c | 464 | ||||
-rw-r--r-- | src/gns/w32nsp-uninstall.c | 31 | ||||
-rw-r--r-- | src/gns/w32nsp.c | 711 | ||||
-rw-r--r-- | src/gns/w32nsp.def | 2 |
9 files changed, 10 insertions, 2213 deletions
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am index 0d38cb51e..4a152a6df 100644 --- a/src/gns/Makefile.am +++ b/src/gns/Makefile.am | |||
@@ -15,7 +15,6 @@ EXTRA_DIST = \ | |||
15 | test_gns_lookup.conf \ | 15 | test_gns_lookup.conf \ |
16 | test_gns_proxy.conf \ | 16 | test_gns_proxy.conf \ |
17 | test_gns_simple_lookup.conf \ | 17 | test_gns_simple_lookup.conf \ |
18 | gns-helper-service-w32.conf \ | ||
19 | w32nsp.def \ | 18 | w32nsp.def \ |
20 | openssl.cnf \ | 19 | openssl.cnf \ |
21 | gnunet-gns-proxy-setup-ca.in \ | 20 | gnunet-gns-proxy-setup-ca.in \ |
@@ -25,14 +24,6 @@ EXTRA_DIST = \ | |||
25 | $(check_SCRIPTS) \ | 24 | $(check_SCRIPTS) \ |
26 | $(pkgdata_DATA) | 25 | $(pkgdata_DATA) |
27 | 26 | ||
28 | if MINGW | ||
29 | WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols | ||
30 | DO_W32_HELPER = gnunet-gns-helper-service-w32 | ||
31 | DO_W32_NSP = libw32nsp.la | ||
32 | DO_W32_NSPTOOLS = w32nsp-install w32nsp-uninstall w32nsp-resolve | ||
33 | DO_W32_HS_CONF = gns-helper-service-w32.conf | ||
34 | DO_NONPOSIX_GNSIMPORT = gnunet-gns-import | ||
35 | endif | ||
36 | USE_VPN = $(top_builddir)/src/vpn/libgnunetvpn.la | 27 | USE_VPN = $(top_builddir)/src/vpn/libgnunetvpn.la |
37 | 28 | ||
38 | if USE_COVERAGE | 29 | if USE_COVERAGE |
@@ -46,11 +37,9 @@ libexecdir= $(pkglibdir)/libexec/ | |||
46 | plugindir = $(libdir)/gnunet | 37 | plugindir = $(libdir)/gnunet |
47 | 38 | ||
48 | pkgcfg_DATA = \ | 39 | pkgcfg_DATA = \ |
49 | gns.conf \ | 40 | gns.conf |
50 | $(DO_W32_HS_CONF) | ||
51 | 41 | ||
52 | lib_LTLIBRARIES = \ | 42 | lib_LTLIBRARIES = \ |
53 | $(DO_W32_NSP) \ | ||
54 | libgnunetgns.la | 43 | libgnunetgns.la |
55 | 44 | ||
56 | 45 | ||
@@ -73,12 +62,9 @@ endif | |||
73 | libexec_PROGRAMS = \ | 62 | libexec_PROGRAMS = \ |
74 | gnunet-service-gns \ | 63 | gnunet-service-gns \ |
75 | gnunet-dns2gns \ | 64 | gnunet-dns2gns \ |
76 | $(DO_W32_HELPER) \ | ||
77 | $(DO_PROXY) | 65 | $(DO_PROXY) |
78 | 66 | ||
79 | bin_PROGRAMS = \ | 67 | bin_PROGRAMS = \ |
80 | $(DO_W32_NSPTOOLS) \ | ||
81 | $(DO_NONPOSIX_GNSIMPORT) \ | ||
82 | gnunet-gns | 68 | gnunet-gns |
83 | 69 | ||
84 | noinst_PROGRAMS = \ | 70 | noinst_PROGRAMS = \ |
@@ -199,35 +185,15 @@ test_gns_proxy_LDADD = $(MHD_LIBS) $(LIB_GNURL) -lgnutls \ | |||
199 | $(GN_LIBINTL) | 185 | $(GN_LIBINTL) |
200 | test_gns_proxy_CFLAGS = $(MHD_CFLAGS) $(CPP_GNURL) $(AM_CFLAGS) | 186 | test_gns_proxy_CFLAGS = $(MHD_CFLAGS) $(CPP_GNURL) $(AM_CFLAGS) |
201 | 187 | ||
202 | gnunet_gns_helper_service_w32_SOURCES = \ | 188 | #gnunet_gns_import_SOURCES = \ |
203 | gnunet-gns-helper-service-w32.c | 189 | # gnunet-gns-import.c |
204 | gnunet_gns_helper_service_w32_LDADD = \ | 190 | #gnunet_gns_import_LDADD = \ |
205 | libgnunetgns.la \ | 191 | # $(top_builddir)/src/identity/libgnunetidentity.la \ |
206 | $(top_builddir)/src/identity/libgnunetidentity.la \ | 192 | # $(top_builddir)/src/namestore/libgnunetnamestore.la \ |
207 | $(top_builddir)/src/util/libgnunetutil.la \ | 193 | # $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ |
208 | $(GN_LIBINTL) | 194 | # $(top_builddir)/src/util/libgnunetutil.la \ |
209 | 195 | # $(GN_LIBINTL) | |
210 | gnunet_gns_import_SOURCES = \ | ||
211 | gnunet-gns-import.c | ||
212 | gnunet_gns_import_LDADD = \ | ||
213 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
214 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | ||
215 | $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ | ||
216 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
217 | $(GN_LIBINTL) | ||
218 | |||
219 | 196 | ||
220 | w32nsp_install_SOURCES = \ | ||
221 | w32nsp-install.c | ||
222 | w32nsp_install_LDADD = -lws2_32 | ||
223 | |||
224 | w32nsp_uninstall_SOURCES = \ | ||
225 | w32nsp-uninstall.c | ||
226 | w32nsp_uninstall_LDADD = -lws2_32 | ||
227 | |||
228 | w32nsp_resolve_SOURCES = \ | ||
229 | w32nsp-resolve.c | ||
230 | w32nsp_resolve_LDADD = -lws2_32 | ||
231 | 197 | ||
232 | gnunet_service_gns_SOURCES = \ | 198 | gnunet_service_gns_SOURCES = \ |
233 | gnunet-service-gns.c gnunet-service-gns.h \ | 199 | gnunet-service-gns.c gnunet-service-gns.h \ |
@@ -247,14 +213,6 @@ gnunet_service_gns_LDADD = \ | |||
247 | $(GN_LIBINTL) | 213 | $(GN_LIBINTL) |
248 | 214 | ||
249 | 215 | ||
250 | libw32nsp_la_SOURCES = \ | ||
251 | w32nsp.c | ||
252 | libw32nsp_la_LIBADD = \ | ||
253 | -lole32 -lws2_32 | ||
254 | libw32nsp_la_LDFLAGS = \ | ||
255 | -export-symbols $(top_srcdir)/src/gns/w32nsp.def \ | ||
256 | -no-undefined -static-libgcc | ||
257 | |||
258 | libgnunetgns_la_SOURCES = \ | 216 | libgnunetgns_la_SOURCES = \ |
259 | gns_api.c gns_api.h \ | 217 | gns_api.c gns_api.h \ |
260 | gns_tld_api.c gns.h | 218 | gns_tld_api.c gns.h |
diff --git a/src/gns/gns-helper-service-w32.conf b/src/gns/gns-helper-service-w32.conf deleted file mode 100644 index a7b9fdd70..000000000 --- a/src/gns/gns-helper-service-w32.conf +++ /dev/null | |||
@@ -1,4 +0,0 @@ | |||
1 | [gns-helper-service-w32] | ||
2 | START_ON_DEMAND = YES | ||
3 | BINARY = gnunet-gns-helper-service-w32 | ||
4 | PORT = 5353 | ||
diff --git a/src/gns/gnunet-gns-helper-service-w32.c b/src/gns/gnunet-gns-helper-service-w32.c deleted file mode 100644 index 4c4803556..000000000 --- a/src/gns/gnunet-gns-helper-service-w32.c +++ /dev/null | |||
@@ -1,803 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012, 2017 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /** | ||
21 | * @file gnunet-gns-helper-service-w32.c | ||
22 | * @brief an intermediary service to access distributed GNS | ||
23 | * @author Christian Grothoff | ||
24 | * @author LRN | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include <gnunet_util_lib.h> | ||
28 | #include <gnunet_identity_service.h> | ||
29 | #include <gnunet_dnsparser_lib.h> | ||
30 | #include <gnunet_namestore_service.h> | ||
31 | #include <gnunet_gns_service.h> | ||
32 | #include <initguid.h> | ||
33 | #include "gnunet_w32nsp_lib.h" | ||
34 | #include "w32resolver.h" | ||
35 | #include <nspapi.h> | ||
36 | #include <unistr.h> | ||
37 | |||
38 | #define DEFINE_DNS_GUID(a, x) DEFINE_GUID(a, 0x00090035, 0x0000, x, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46) | ||
39 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_A, 0x0001); | ||
40 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_NS, 0x0002); | ||
41 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_CNAME, 0x0005); | ||
42 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_SOA, 0x0006); | ||
43 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_PTR, 0x000c); | ||
44 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_MX, 0x000f); | ||
45 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_TEXT, 0x0010); | ||
46 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_AAAA, 0x001c); | ||
47 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_SRV, 0x0021); | ||
48 | DEFINE_GUID(SVCID_HOSTNAME, 0x0002a800, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); | ||
49 | DEFINE_GUID(SVCID_INET_HOSTADDRBYNAME, 0x0002a803, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); | ||
50 | |||
51 | |||
52 | struct request { | ||
53 | /** | ||
54 | * We keep these in a doubly-linked list (for cleanup). | ||
55 | */ | ||
56 | struct request *next; | ||
57 | |||
58 | /** | ||
59 | * We keep these in a doubly-linked list (for cleanup). | ||
60 | */ | ||
61 | struct request *prev; | ||
62 | |||
63 | /** | ||
64 | * Client that issued the request | ||
65 | */ | ||
66 | struct GNUNET_SERVICE_Client *client; | ||
67 | |||
68 | GUID sc; | ||
69 | |||
70 | int af; | ||
71 | |||
72 | wchar_t *name; | ||
73 | |||
74 | char *u8name; | ||
75 | |||
76 | struct GNUNET_GNS_LookupRequest *lookup_request; | ||
77 | }; | ||
78 | |||
79 | |||
80 | /** | ||
81 | * Head of the doubly-linked list (for cleanup). | ||
82 | */ | ||
83 | static struct request *rq_head; | ||
84 | |||
85 | /** | ||
86 | * Tail of the doubly-linked list (for cleanup). | ||
87 | */ | ||
88 | static struct request *rq_tail; | ||
89 | |||
90 | /** | ||
91 | * Handle to GNS service. | ||
92 | */ | ||
93 | static struct GNUNET_GNS_Handle *gns; | ||
94 | |||
95 | /** | ||
96 | * Active operation on identity service. | ||
97 | */ | ||
98 | static struct GNUNET_IDENTITY_Operation *id_op; | ||
99 | |||
100 | /** | ||
101 | * Handle for identity service. | ||
102 | */ | ||
103 | static struct GNUNET_IDENTITY_Handle *identity; | ||
104 | |||
105 | /** | ||
106 | * Public key of the gns-master ego | ||
107 | */ | ||
108 | static struct GNUNET_CRYPTO_EcdsaPublicKey gns_master_pubkey; | ||
109 | |||
110 | /** | ||
111 | * Set to 1 once egos are obtained. | ||
112 | */ | ||
113 | static int got_egos; | ||
114 | |||
115 | |||
116 | /** | ||
117 | * Task run on shutdown. Cleans up everything. | ||
118 | * | ||
119 | * @param cls unused | ||
120 | */ | ||
121 | static void | ||
122 | do_shutdown(void *cls) | ||
123 | { | ||
124 | struct request *rq; | ||
125 | |||
126 | if (NULL != id_op) | ||
127 | { | ||
128 | GNUNET_IDENTITY_cancel(id_op); | ||
129 | id_op = NULL; | ||
130 | } | ||
131 | if (NULL != identity) | ||
132 | { | ||
133 | GNUNET_IDENTITY_disconnect(identity); | ||
134 | identity = NULL; | ||
135 | } | ||
136 | while (NULL != (rq = rq_head)) | ||
137 | { | ||
138 | if (NULL != rq->lookup_request) | ||
139 | GNUNET_GNS_lookup_cancel(rq->lookup_request); | ||
140 | GNUNET_CONTAINER_DLL_remove(rq_head, | ||
141 | rq_tail, | ||
142 | rq); | ||
143 | GNUNET_free_non_null(rq->name); | ||
144 | if (rq->u8name) | ||
145 | free(rq->u8name); | ||
146 | GNUNET_free(rq); | ||
147 | } | ||
148 | if (NULL != gns) | ||
149 | { | ||
150 | GNUNET_GNS_disconnect(gns); | ||
151 | gns = NULL; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | |||
156 | #define MarshallPtr(ptr, base, type) \ | ||
157 | if (ptr) \ | ||
158 | ptr = (type *) ((char *)ptr - (char *)base) | ||
159 | |||
160 | |||
161 | void | ||
162 | MarshallWSAQUERYSETW(WSAQUERYSETW *qs, GUID *sc) | ||
163 | { | ||
164 | MarshallPtr(qs->lpszServiceInstanceName, qs, wchar_t); | ||
165 | MarshallPtr(qs->lpServiceClassId, qs, GUID); | ||
166 | MarshallPtr(qs->lpVersion, qs, WSAVERSION); | ||
167 | MarshallPtr(qs->lpNSProviderId, qs, GUID); | ||
168 | MarshallPtr(qs->lpszContext, qs, wchar_t); | ||
169 | MarshallPtr(qs->lpafpProtocols, qs, AFPROTOCOLS); | ||
170 | MarshallPtr(qs->lpszQueryString, qs, wchar_t); | ||
171 | for (int i = 0; i < qs->dwNumberOfCsAddrs; i++) | ||
172 | { | ||
173 | MarshallPtr(qs->lpcsaBuffer[i].LocalAddr.lpSockaddr, qs, SOCKADDR); | ||
174 | MarshallPtr(qs->lpcsaBuffer[i].RemoteAddr.lpSockaddr, qs, SOCKADDR); | ||
175 | } | ||
176 | MarshallPtr(qs->lpcsaBuffer, qs, CSADDR_INFO); | ||
177 | if (IsEqualGUID(&SVCID_INET_HOSTADDRBYNAME, sc) && qs->lpBlob != NULL && qs->lpBlob->pBlobData != NULL) | ||
178 | { | ||
179 | struct hostent *he; | ||
180 | |||
181 | he = (struct hostent *)qs->lpBlob->pBlobData; | ||
182 | for (int i = 0; he->h_aliases[i] != NULL; i++) | ||
183 | MarshallPtr(he->h_aliases[i], he, char); | ||
184 | MarshallPtr(he->h_aliases, he, char *); | ||
185 | MarshallPtr(he->h_name, he, char); | ||
186 | for (int i = 0; he->h_addr_list[i] != NULL; i++) | ||
187 | MarshallPtr(he->h_addr_list[i], he, void); | ||
188 | MarshallPtr(he->h_addr_list, he, char *); | ||
189 | MarshallPtr(qs->lpBlob->pBlobData, qs, void); | ||
190 | } | ||
191 | MarshallPtr(qs->lpBlob, qs, BLOB); | ||
192 | } | ||
193 | |||
194 | |||
195 | static void | ||
196 | process_lookup_result(void *cls, | ||
197 | uint32_t rd_count, | ||
198 | const struct GNUNET_GNSRECORD_Data *rd) | ||
199 | { | ||
200 | struct request *rq = cls; | ||
201 | int i, j, csanum; | ||
202 | struct GNUNET_W32RESOLVER_GetMessage *msg; | ||
203 | struct GNUNET_MQ_Envelope *msg_env; | ||
204 | struct GNUNET_MessageHeader *msgend; | ||
205 | struct GNUNET_MQ_Envelope *msgend_env; | ||
206 | WSAQUERYSETW *qs; | ||
207 | size_t size; | ||
208 | size_t size_recalc; | ||
209 | char *ptr; | ||
210 | size_t blobsize = 0; | ||
211 | size_t blobaddrcount = 0; | ||
212 | |||
213 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
214 | "Got lookup result with count %u for rq %p with client %p\n", | ||
215 | rd_count, | ||
216 | rq, | ||
217 | rq->client); | ||
218 | rq->lookup_request = NULL; | ||
219 | |||
220 | if (0 == rd_count) | ||
221 | { | ||
222 | msgend_env = GNUNET_MQ_msg(msgend, GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE); | ||
223 | GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(rq->client), | ||
224 | msgend_env); | ||
225 | GNUNET_CONTAINER_DLL_remove(rq_head, | ||
226 | rq_tail, | ||
227 | rq); | ||
228 | GNUNET_free_non_null(rq->name); | ||
229 | if (rq->u8name) | ||
230 | free(rq->u8name); | ||
231 | GNUNET_free(rq); | ||
232 | return; | ||
233 | } | ||
234 | |||
235 | size = sizeof(struct GNUNET_W32RESOLVER_GetMessage) + sizeof(WSAQUERYSETW); | ||
236 | size += (wcslen(rq->name) + 1) * sizeof(wchar_t); | ||
237 | size += sizeof(GUID); | ||
238 | /* lpszComment ? a TXT record? */ | ||
239 | size += sizeof(GUID); | ||
240 | /* lpszContext ? Not sure what it is */ | ||
241 | csanum = 0; | ||
242 | for (i = 0; i < rd_count; i++) | ||
243 | { | ||
244 | switch (rd[i].record_type) | ||
245 | { | ||
246 | case GNUNET_DNSPARSER_TYPE_A: | ||
247 | if (rd[i].data_size != sizeof(struct in_addr)) | ||
248 | continue; | ||
249 | size += sizeof(CSADDR_INFO) + sizeof(struct sockaddr_in) * 2; | ||
250 | csanum++; | ||
251 | break; | ||
252 | |||
253 | case GNUNET_DNSPARSER_TYPE_AAAA: | ||
254 | if (rd[i].data_size != sizeof(struct in6_addr)) | ||
255 | continue; | ||
256 | size += sizeof(CSADDR_INFO) + sizeof(struct sockaddr_in6) * 2; | ||
257 | csanum++; | ||
258 | break; | ||
259 | } | ||
260 | } | ||
261 | if (IsEqualGUID(&SVCID_INET_HOSTADDRBYNAME, &rq->sc)) | ||
262 | { | ||
263 | size += sizeof(BLOB); | ||
264 | blobsize += sizeof(struct hostent); | ||
265 | blobsize += strlen(rq->u8name) + 1; | ||
266 | blobsize += sizeof(void *); /* For aliases */ | ||
267 | blobsize += sizeof(void *); /* For addresses */ | ||
268 | for (i = 0; i < rd_count; i++) | ||
269 | { | ||
270 | if ((rq->af == AF_INET || rq->af == AF_UNSPEC) && rd[i].record_type == GNUNET_DNSPARSER_TYPE_A) | ||
271 | { | ||
272 | blobsize += sizeof(void *); | ||
273 | blobsize += sizeof(struct in_addr); | ||
274 | blobaddrcount++; | ||
275 | } | ||
276 | else if (rq->af == AF_INET6 && rd[i].record_type == GNUNET_DNSPARSER_TYPE_AAAA) | ||
277 | { | ||
278 | blobsize += sizeof(void *); | ||
279 | blobsize += sizeof(struct in6_addr); | ||
280 | blobaddrcount++; | ||
281 | } | ||
282 | } | ||
283 | size += blobsize; | ||
284 | } | ||
285 | size_recalc = sizeof(struct GNUNET_W32RESOLVER_GetMessage) + sizeof(WSAQUERYSETW); | ||
286 | msg_env = GNUNET_MQ_msg_extra(msg, | ||
287 | size - sizeof(struct GNUNET_MessageHeader), | ||
288 | GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE); | ||
289 | msg->af = htonl(rq->af); | ||
290 | msg->sc_data1 = htonl(rq->sc.Data1); | ||
291 | msg->sc_data2 = htons(rq->sc.Data2); | ||
292 | msg->sc_data3 = htons(rq->sc.Data3); | ||
293 | for (i = 0; i < 8; i++) | ||
294 | msg->sc_data4[i] = rq->sc.Data4[i]; | ||
295 | qs = (WSAQUERYSETW *)&msg[1]; | ||
296 | ptr = (char *)&qs[1]; | ||
297 | GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg)); | ||
298 | qs->dwSize = sizeof(WSAQUERYSETW); | ||
299 | qs->lpszServiceInstanceName = (wchar_t *)ptr; | ||
300 | ptr += (wcslen(rq->name) + 1) * sizeof(wchar_t); | ||
301 | size_recalc += (wcslen(rq->name) + 1) * sizeof(wchar_t); | ||
302 | GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg)); | ||
303 | wcscpy(qs->lpszServiceInstanceName, rq->name); | ||
304 | qs->lpServiceClassId = (GUID *)ptr; | ||
305 | ptr += sizeof(GUID); | ||
306 | size_recalc += sizeof(GUID); | ||
307 | GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg)); | ||
308 | GNUNET_memcpy(qs->lpServiceClassId, &rq->sc, sizeof(GUID)); | ||
309 | qs->lpVersion = NULL; | ||
310 | qs->dwNameSpace = NS_DNS; | ||
311 | qs->lpNSProviderId = (GUID *)ptr; | ||
312 | ptr += sizeof(GUID); | ||
313 | size_recalc += sizeof(GUID); | ||
314 | GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg)); | ||
315 | GNUNET_memcpy(qs->lpNSProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS, sizeof(GUID)); | ||
316 | qs->lpszContext = NULL; | ||
317 | qs->dwNumberOfProtocols = 0; | ||
318 | qs->lpafpProtocols = NULL; | ||
319 | /* Don't bother with this... */ | ||
320 | qs->lpszQueryString = NULL; | ||
321 | qs->dwNumberOfCsAddrs = rd_count; | ||
322 | qs->lpcsaBuffer = (CSADDR_INFO *)ptr; | ||
323 | ptr += sizeof(CSADDR_INFO) * csanum; | ||
324 | j = 0; | ||
325 | for (i = 0; i < rd_count; i++) | ||
326 | { | ||
327 | switch (rd[i].record_type) | ||
328 | { | ||
329 | case GNUNET_DNSPARSER_TYPE_A: | ||
330 | if (rd[i].data_size != sizeof(struct in_addr)) | ||
331 | continue; | ||
332 | qs->lpcsaBuffer[j].iSocketType = SOCK_STREAM; | ||
333 | qs->lpcsaBuffer[j].iProtocol = IPPROTO_TCP; | ||
334 | |||
335 | qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength = sizeof(struct sockaddr_in); | ||
336 | qs->lpcsaBuffer[j].LocalAddr.lpSockaddr = (SOCKADDR *)ptr; | ||
337 | ptr += qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength; | ||
338 | memset(qs->lpcsaBuffer[j].LocalAddr.lpSockaddr, 0, qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength); | ||
339 | ((struct sockaddr_in *)qs->lpcsaBuffer[j].LocalAddr.lpSockaddr)->sin_family = AF_INET; | ||
340 | |||
341 | qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength = sizeof(struct sockaddr_in); | ||
342 | qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr = (SOCKADDR *)ptr; | ||
343 | ptr += qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength; | ||
344 | memset(qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr, 0, qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength); | ||
345 | ((struct sockaddr_in *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin_family = AF_INET; | ||
346 | ((struct sockaddr_in *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin_port = htonl(53); /* Don't ask why it's 53 */ | ||
347 | ((struct sockaddr_in *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin_addr = *(struct in_addr *)rd[i].data; | ||
348 | size_recalc += sizeof(CSADDR_INFO) + sizeof(struct sockaddr_in) * 2; | ||
349 | j++; | ||
350 | break; | ||
351 | |||
352 | case GNUNET_DNSPARSER_TYPE_AAAA: | ||
353 | if (rd[i].data_size != sizeof(struct in6_addr)) | ||
354 | continue; | ||
355 | qs->lpcsaBuffer[j].iSocketType = SOCK_STREAM; | ||
356 | qs->lpcsaBuffer[j].iProtocol = IPPROTO_TCP; | ||
357 | |||
358 | qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength = sizeof(struct sockaddr_in6); | ||
359 | qs->lpcsaBuffer[j].LocalAddr.lpSockaddr = (SOCKADDR *)ptr; | ||
360 | ptr += qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength; | ||
361 | memset(qs->lpcsaBuffer[j].LocalAddr.lpSockaddr, 0, qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength); | ||
362 | ((struct sockaddr_in6 *)qs->lpcsaBuffer[j].LocalAddr.lpSockaddr)->sin6_family = AF_INET6; | ||
363 | |||
364 | qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength = sizeof(struct sockaddr_in6); | ||
365 | qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr = (SOCKADDR *)ptr; | ||
366 | ptr += qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength; | ||
367 | memset(qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr, 0, qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength); | ||
368 | ((struct sockaddr_in6 *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin6_family = AF_INET6; | ||
369 | ((struct sockaddr_in6 *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin6_port = htonl(53); /* Don't ask why it's 53 */ | ||
370 | ((struct sockaddr_in6 *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin6_addr = *(struct in6_addr *)rd[i].data; | ||
371 | size_recalc += sizeof(CSADDR_INFO) + sizeof(struct sockaddr_in6) * 2; | ||
372 | j++; | ||
373 | break; | ||
374 | |||
375 | default: | ||
376 | break; | ||
377 | } | ||
378 | } | ||
379 | GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg)); | ||
380 | qs->dwOutputFlags = 0; | ||
381 | if (IsEqualGUID(&SVCID_INET_HOSTADDRBYNAME, &rq->sc)) | ||
382 | { | ||
383 | struct hostent *he; | ||
384 | qs->lpBlob = (BLOB *)ptr; | ||
385 | ptr += sizeof(BLOB); | ||
386 | |||
387 | size_recalc += sizeof(BLOB); | ||
388 | GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg)); | ||
389 | |||
390 | qs->lpBlob->cbSize = blobsize; | ||
391 | qs->lpBlob->pBlobData = (BYTE *)ptr; | ||
392 | ptr += sizeof(struct hostent); | ||
393 | |||
394 | size_recalc += sizeof(struct hostent); | ||
395 | GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg)); | ||
396 | |||
397 | he = (struct hostent *)qs->lpBlob->pBlobData; | ||
398 | he->h_name = (char *)ptr; | ||
399 | ptr += strlen(rq->u8name) + 1; | ||
400 | |||
401 | size_recalc += strlen(rq->u8name) + 1; | ||
402 | GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg)); | ||
403 | |||
404 | strcpy(he->h_name, rq->u8name); | ||
405 | he->h_aliases = (char **)ptr; | ||
406 | ptr += sizeof(void *); | ||
407 | |||
408 | size_recalc += sizeof(void *); /* For aliases */ | ||
409 | GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg)); | ||
410 | |||
411 | he->h_aliases[0] = NULL; | ||
412 | he->h_addrtype = rq->af; | ||
413 | he->h_length = rq->af == AF_INET || rq->af == AF_UNSPEC ? sizeof(struct in_addr) : sizeof(struct in6_addr); | ||
414 | he->h_addr_list = (char **)ptr; | ||
415 | ptr += sizeof(void *) * (blobaddrcount + 1); | ||
416 | |||
417 | size_recalc += sizeof(void *) * (blobaddrcount + 1); /* For addresses */ | ||
418 | GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg)); | ||
419 | |||
420 | j = 0; | ||
421 | for (i = 0; i < rd_count; i++) | ||
422 | { | ||
423 | if ((rq->af == AF_INET || rq->af == AF_UNSPEC) && | ||
424 | rd[i].record_type == GNUNET_DNSPARSER_TYPE_A) | ||
425 | { | ||
426 | he->h_addr_list[j] = (char *)ptr; | ||
427 | ptr += sizeof(struct in_addr); | ||
428 | |||
429 | size_recalc += sizeof(struct in_addr); | ||
430 | GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg)); | ||
431 | |||
432 | GNUNET_memcpy(he->h_addr_list[j], rd[i].data, sizeof(struct in_addr)); | ||
433 | j++; | ||
434 | } | ||
435 | else if (rq->af == AF_INET6 && rd[i].record_type == GNUNET_DNSPARSER_TYPE_AAAA) | ||
436 | { | ||
437 | he->h_addr_list[j] = (char *)ptr; | ||
438 | ptr += sizeof(struct in6_addr); | ||
439 | |||
440 | size_recalc += sizeof(struct in6_addr); | ||
441 | GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg)); | ||
442 | |||
443 | GNUNET_memcpy(he->h_addr_list[j], rd[i].data, sizeof(struct in6_addr)); | ||
444 | j++; | ||
445 | } | ||
446 | } | ||
447 | he->h_addr_list[j] = NULL; | ||
448 | } | ||
449 | msgend_env = GNUNET_MQ_msg(msgend, GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE); | ||
450 | |||
451 | if ((char *)ptr - (char *)msg != size || size_recalc != size || size_recalc != ((char *)ptr - (char *)msg)) | ||
452 | { | ||
453 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
454 | "Error in WSAQUERYSETW size calc: expected %u, got %lu (recalc %u)\n", | ||
455 | size, | ||
456 | (unsigned long)((char *)ptr - (char *)msg), | ||
457 | size_recalc); | ||
458 | } | ||
459 | MarshallWSAQUERYSETW(qs, &rq->sc); | ||
460 | GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(rq->client), | ||
461 | msg_env); | ||
462 | GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(rq->client), | ||
463 | msgend_env); | ||
464 | GNUNET_CONTAINER_DLL_remove(rq_head, | ||
465 | rq_tail, | ||
466 | rq); | ||
467 | GNUNET_free_non_null(rq->name); | ||
468 | if (rq->u8name) | ||
469 | free(rq->u8name); | ||
470 | GNUNET_free(rq); | ||
471 | } | ||
472 | |||
473 | |||
474 | static void | ||
475 | get_ip_from_hostname(struct GNUNET_SERVICE_Client *client, | ||
476 | const wchar_t *name, | ||
477 | int af, | ||
478 | GUID sc) | ||
479 | { | ||
480 | struct request *rq; | ||
481 | char *hostname; | ||
482 | size_t strl; | ||
483 | size_t namelen; | ||
484 | uint32_t rtype; | ||
485 | |||
486 | if (IsEqualGUID(&SVCID_DNS_TYPE_A, &sc)) | ||
487 | rtype = GNUNET_DNSPARSER_TYPE_A; | ||
488 | else if (IsEqualGUID(&SVCID_DNS_TYPE_NS, &sc)) | ||
489 | rtype = GNUNET_DNSPARSER_TYPE_NS; | ||
490 | else if (IsEqualGUID(&SVCID_DNS_TYPE_CNAME, &sc)) | ||
491 | rtype = GNUNET_DNSPARSER_TYPE_CNAME; | ||
492 | else if (IsEqualGUID(&SVCID_DNS_TYPE_SOA, &sc)) | ||
493 | rtype = GNUNET_DNSPARSER_TYPE_SOA; | ||
494 | else if (IsEqualGUID(&SVCID_DNS_TYPE_PTR, &sc)) | ||
495 | rtype = GNUNET_DNSPARSER_TYPE_PTR; | ||
496 | else if (IsEqualGUID(&SVCID_DNS_TYPE_MX, &sc)) | ||
497 | rtype = GNUNET_DNSPARSER_TYPE_MX; | ||
498 | else if (IsEqualGUID(&SVCID_DNS_TYPE_TEXT, &sc)) | ||
499 | rtype = GNUNET_DNSPARSER_TYPE_TXT; | ||
500 | else if (IsEqualGUID(&SVCID_DNS_TYPE_AAAA, &sc)) | ||
501 | rtype = GNUNET_DNSPARSER_TYPE_AAAA; | ||
502 | else if (IsEqualGUID(&SVCID_DNS_TYPE_SRV, &sc)) | ||
503 | rtype = GNUNET_DNSPARSER_TYPE_SRV; | ||
504 | else if (IsEqualGUID(&SVCID_INET_HOSTADDRBYNAME, &sc)) | ||
505 | rtype = GNUNET_DNSPARSER_TYPE_A; | ||
506 | else | ||
507 | { | ||
508 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
509 | "Unknown GUID: %08lX-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n", | ||
510 | sc.Data1, | ||
511 | sc.Data2, | ||
512 | sc.Data3, | ||
513 | sc.Data4[0], | ||
514 | sc.Data4[1], | ||
515 | sc.Data4[2], | ||
516 | sc.Data4[3], | ||
517 | sc.Data4[4], | ||
518 | sc.Data4[5], | ||
519 | sc.Data4[6], | ||
520 | sc.Data4[7]); | ||
521 | GNUNET_SERVICE_client_drop(client); | ||
522 | return; | ||
523 | } | ||
524 | |||
525 | if (name) | ||
526 | namelen = wcslen(name); | ||
527 | else | ||
528 | namelen = 0; | ||
529 | if (namelen > 0) | ||
530 | hostname = (char *)u16_to_u8(name, namelen + 1, NULL, &strl); | ||
531 | else | ||
532 | hostname = NULL; | ||
533 | |||
534 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
535 | "W32 DNS resolver asked to look up %s for `%s'.\n", | ||
536 | af == AF_INET ? "IPv4" : af == AF_INET6 ? "IPv6" : "anything", | ||
537 | hostname); | ||
538 | |||
539 | rq = GNUNET_new(struct request); | ||
540 | rq->sc = sc; | ||
541 | rq->client = client; | ||
542 | rq->af = af; | ||
543 | if (rq->af != AF_INET && rq->af != AF_INET6) | ||
544 | rq->af = AF_INET; | ||
545 | if (namelen) | ||
546 | { | ||
547 | rq->name = GNUNET_malloc((namelen + 1) * sizeof(wchar_t)); | ||
548 | GNUNET_memcpy(rq->name, | ||
549 | name, | ||
550 | (namelen + 1) * sizeof(wchar_t)); | ||
551 | rq->u8name = hostname; | ||
552 | } | ||
553 | |||
554 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
555 | "Launching a lookup for client %p with rq %p\n", | ||
556 | client, | ||
557 | rq); | ||
558 | rq->lookup_request = GNUNET_GNS_lookup(gns, | ||
559 | hostname, | ||
560 | &gns_master_pubkey, | ||
561 | rtype, | ||
562 | GNUNET_NO /* Use DHT */, | ||
563 | &process_lookup_result, | ||
564 | rq); | ||
565 | if (NULL != rq->lookup_request) | ||
566 | { | ||
567 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
568 | "Lookup launched, waiting for a reply\n"); | ||
569 | GNUNET_SERVICE_client_continue(client); | ||
570 | GNUNET_CONTAINER_DLL_insert(rq_head, | ||
571 | rq_tail, | ||
572 | rq); | ||
573 | } | ||
574 | else | ||
575 | { | ||
576 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
577 | "Lookup was not launched, disconnecting the client\n"); | ||
578 | GNUNET_free_non_null(rq->name); | ||
579 | if (rq->u8name) | ||
580 | free(rq->u8name); | ||
581 | GNUNET_free(rq); | ||
582 | GNUNET_SERVICE_client_drop(client); | ||
583 | } | ||
584 | } | ||
585 | |||
586 | |||
587 | /** | ||
588 | * Check GET-message. | ||
589 | * | ||
590 | * @param cls identification of the client | ||
591 | * @param msg the actual message | ||
592 | * @return #GNUNET_OK if @a msg is well-formed | ||
593 | */ | ||
594 | static int | ||
595 | check_get(void *cls, | ||
596 | const struct GNUNET_W32RESOLVER_GetMessage *msg) | ||
597 | { | ||
598 | uint16_t size; | ||
599 | const wchar_t *hostname; | ||
600 | |||
601 | if (!got_egos) | ||
602 | { | ||
603 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
604 | _("Not ready to process requests, lacking ego data\n")); | ||
605 | return GNUNET_SYSERR; | ||
606 | } | ||
607 | size = ntohs(msg->header.size) - sizeof(struct GNUNET_W32RESOLVER_GetMessage); | ||
608 | hostname = (const wchar_t *)&msg[1]; | ||
609 | if (hostname[size / 2 - 1] != L'\0') | ||
610 | { | ||
611 | GNUNET_break(0); | ||
612 | return GNUNET_SYSERR; | ||
613 | } | ||
614 | return GNUNET_OK; | ||
615 | } | ||
616 | |||
617 | |||
618 | /** | ||
619 | * Handle GET-message. | ||
620 | * | ||
621 | * @param cls identification of the client | ||
622 | * @param msg the actual message | ||
623 | */ | ||
624 | static void | ||
625 | handle_get(void *cls, | ||
626 | const struct GNUNET_W32RESOLVER_GetMessage *msg) | ||
627 | { | ||
628 | struct GNUNET_SERVICE_Client *client = cls; | ||
629 | GUID sc; | ||
630 | uint16_t size; | ||
631 | const wchar_t *hostname; | ||
632 | int af; | ||
633 | |||
634 | size = ntohs(msg->header.size) - sizeof(struct GNUNET_W32RESOLVER_GetMessage); | ||
635 | af = ntohl(msg->af); | ||
636 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
637 | "Got NBO GUID: %08X-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n", | ||
638 | msg->sc_data1, | ||
639 | msg->sc_data2, | ||
640 | msg->sc_data3, | ||
641 | msg->sc_data4[0], | ||
642 | msg->sc_data4[1], | ||
643 | msg->sc_data4[2], | ||
644 | msg->sc_data4[3], | ||
645 | msg->sc_data4[4], | ||
646 | msg->sc_data4[5], | ||
647 | msg->sc_data4[6], | ||
648 | msg->sc_data4[7]); | ||
649 | sc.Data1 = ntohl(msg->sc_data1); | ||
650 | sc.Data2 = ntohs(msg->sc_data2); | ||
651 | sc.Data3 = ntohs(msg->sc_data3); | ||
652 | for (int i = 0; i < 8; i++) | ||
653 | sc.Data4[i] = msg->sc_data4[i]; | ||
654 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
655 | "Got GUID: %08lX-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n", | ||
656 | sc.Data1, | ||
657 | sc.Data2, | ||
658 | sc.Data3, | ||
659 | sc.Data4[0], | ||
660 | sc.Data4[1], | ||
661 | sc.Data4[2], | ||
662 | sc.Data4[3], | ||
663 | sc.Data4[4], | ||
664 | sc.Data4[5], | ||
665 | sc.Data4[6], | ||
666 | sc.Data4[7]); | ||
667 | hostname = (const wchar_t *)&msg[1]; | ||
668 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
669 | "Name of %u bytes (last word is 0x%0X): %*S\n", | ||
670 | size, | ||
671 | hostname[size / 2 - 2], | ||
672 | size / 2, | ||
673 | hostname); | ||
674 | get_ip_from_hostname(client, | ||
675 | hostname, | ||
676 | af, | ||
677 | sc); | ||
678 | } | ||
679 | |||
680 | |||
681 | /** | ||
682 | * Method called to with the ego we are to use for the lookup, | ||
683 | * when the ego is the one for the default master zone. | ||
684 | * | ||
685 | * @param cls closure (NULL, unused) | ||
686 | * @param ego ego handle, NULL if not found | ||
687 | * @param ctx context for application to store data for this ego | ||
688 | * (during the lifetime of this process, initially NULL) | ||
689 | * @param name name assigned by the user for this ego, | ||
690 | * NULL if the user just deleted the ego and it | ||
691 | * must thus no longer be used | ||
692 | */ | ||
693 | static void | ||
694 | identity_master_cb(void *cls, | ||
695 | struct GNUNET_IDENTITY_Ego *ego, | ||
696 | void **ctx, | ||
697 | const char *name) | ||
698 | { | ||
699 | id_op = NULL; | ||
700 | if (NULL == ego) | ||
701 | { | ||
702 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
703 | _("Ego for `gns-master' not found, cannot perform lookup. Did you run gnunet-gns-import.sh?\n")); | ||
704 | GNUNET_SCHEDULER_shutdown(); | ||
705 | return; | ||
706 | } | ||
707 | GNUNET_IDENTITY_ego_get_public_key(ego, | ||
708 | &gns_master_pubkey); | ||
709 | got_egos = 1; | ||
710 | } | ||
711 | |||
712 | |||
713 | /** | ||
714 | * Start up gns-helper-w32 service. | ||
715 | * | ||
716 | * @param cls closure | ||
717 | * @param cfg configuration to use | ||
718 | * @param service the initialized service | ||
719 | */ | ||
720 | static void | ||
721 | run(void *cls, | ||
722 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
723 | struct GNUNET_SERVICE_Handle *service) | ||
724 | { | ||
725 | gns = GNUNET_GNS_connect(cfg); | ||
726 | if (NULL == gns) | ||
727 | { | ||
728 | fprintf(stderr, | ||
729 | _("Failed to connect to GNS\n")); | ||
730 | GNUNET_SCHEDULER_shutdown(); | ||
731 | return; | ||
732 | } | ||
733 | GNUNET_SCHEDULER_add_shutdown(&do_shutdown, | ||
734 | NULL); | ||
735 | identity = GNUNET_IDENTITY_connect(cfg, | ||
736 | NULL, | ||
737 | NULL); | ||
738 | if (NULL == identity) | ||
739 | { | ||
740 | fprintf(stderr, | ||
741 | _("Failed to connect to identity service\n")); | ||
742 | GNUNET_SCHEDULER_shutdown(); | ||
743 | return; | ||
744 | } | ||
745 | id_op = GNUNET_IDENTITY_get(identity, | ||
746 | "gns-master", | ||
747 | &identity_master_cb, | ||
748 | NULL); | ||
749 | GNUNET_assert(NULL != id_op); | ||
750 | } | ||
751 | |||
752 | |||
753 | /** | ||
754 | * Handle client connecting to the service. | ||
755 | * | ||
756 | * @param cls NULL | ||
757 | * @param client the new client | ||
758 | * @param mq the message queue of @a client | ||
759 | * @return @a client | ||
760 | */ | ||
761 | static void * | ||
762 | client_connect_cb(void *cls, | ||
763 | struct GNUNET_SERVICE_Client *client, | ||
764 | struct GNUNET_MQ_Handle *mq) | ||
765 | { | ||
766 | return client; | ||
767 | } | ||
768 | |||
769 | |||
770 | /** | ||
771 | * Callback called when a client disconnected from the service | ||
772 | * | ||
773 | * @param cls closure for the service | ||
774 | * @param c the client that disconnected | ||
775 | * @param internal_cls should be equal to @a c | ||
776 | */ | ||
777 | static void | ||
778 | client_disconnect_cb(void *cls, | ||
779 | struct GNUNET_SERVICE_Client *client, | ||
780 | void *internal_cls) | ||
781 | { | ||
782 | GNUNET_assert(internal_cls == client); | ||
783 | } | ||
784 | |||
785 | |||
786 | /** | ||
787 | * Define "main" method using service macro. | ||
788 | */ | ||
789 | GNUNET_SERVICE_MAIN | ||
790 | ("gns-helper-service-w32", | ||
791 | GNUNET_SERVICE_OPTION_NONE, | ||
792 | &run, | ||
793 | &client_connect_cb, | ||
794 | &client_disconnect_cb, | ||
795 | NULL, | ||
796 | GNUNET_MQ_hd_var_size(get, | ||
797 | GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST, | ||
798 | struct GNUNET_W32RESOLVER_GetMessage, | ||
799 | NULL), | ||
800 | GNUNET_MQ_handler_end()); | ||
801 | |||
802 | |||
803 | /* end of gnunet-gns-helper-service-w32.c */ | ||
diff --git a/src/gns/nss/Makefile.am b/src/gns/nss/Makefile.am index 5d42f777f..f4a12ddee 100644 --- a/src/gns/nss/Makefile.am +++ b/src/gns/nss/Makefile.am | |||
@@ -18,18 +18,16 @@ | |||
18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 | 18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 |
19 | # USA. | 19 | # USA. |
20 | 20 | ||
21 | EXTRA_DIST = map-file | 21 | EXTRA_DIST = map-file |
22 | 22 | ||
23 | AM_LDFLAGS=-avoid-version -module -export-dynamic | 23 | AM_LDFLAGS=-avoid-version -module -export-dynamic |
24 | 24 | ||
25 | nssdir = $(libdir)/gnunet/nss | 25 | nssdir = $(libdir)/gnunet/nss |
26 | 26 | ||
27 | if !MINGW | ||
28 | nss_LTLIBRARIES = \ | 27 | nss_LTLIBRARIES = \ |
29 | libnss_gns.la \ | 28 | libnss_gns.la \ |
30 | libnss_gns4.la \ | 29 | libnss_gns4.la \ |
31 | libnss_gns6.la | 30 | libnss_gns6.la |
32 | endif | ||
33 | 31 | ||
34 | sources = nss_gns_query.h nss_gns_query.c | 32 | sources = nss_gns_query.h nss_gns_query.c |
35 | 33 | ||
@@ -45,4 +43,3 @@ libnss_gns4_la_LDFLAGS=$(libnss_gns_la_LDFLAGS) | |||
45 | libnss_gns6_la_SOURCES=$(libnss_gns_la_SOURCES) | 43 | libnss_gns6_la_SOURCES=$(libnss_gns_la_SOURCES) |
46 | libnss_gns6_la_CFLAGS=$(libnss_gns_la_CFLAGS) -DNSS_IPV6_ONLY=1 | 44 | libnss_gns6_la_CFLAGS=$(libnss_gns_la_CFLAGS) -DNSS_IPV6_ONLY=1 |
47 | libnss_gns6_la_LDFLAGS=$(libnss_gns_la_LDFLAGS) | 45 | libnss_gns6_la_LDFLAGS=$(libnss_gns_la_LDFLAGS) |
48 | |||
diff --git a/src/gns/w32nsp-install.c b/src/gns/w32nsp-install.c deleted file mode 100644 index 2674359fb..000000000 --- a/src/gns/w32nsp-install.c +++ /dev/null | |||
@@ -1,143 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /** | ||
21 | * @file gns/w32nsp-install.c | ||
22 | * @brief W32 integration installer for GNS | ||
23 | * @author LRN | ||
24 | */ | ||
25 | |||
26 | #include <ws2spi.h> | ||
27 | #include <windows.h> | ||
28 | #include <nspapi.h> | ||
29 | #include <initguid.h> | ||
30 | #include "gnunet_w32nsp_lib.h" | ||
31 | #include <stdio.h> | ||
32 | |||
33 | int | ||
34 | main(int argc, char **argv) | ||
35 | { | ||
36 | int ret; | ||
37 | int r = 1; | ||
38 | WSADATA wsd; | ||
39 | GUID id = GNUNET_NAMESPACE_PROVIDER_DNS; | ||
40 | wchar_t *cmdl; | ||
41 | int wargc; | ||
42 | wchar_t **wargv; | ||
43 | /* Allocate a 4K buffer to retrieve all the namespace providers */ | ||
44 | DWORD dwInitialBufferLen = 4096; | ||
45 | DWORD dwBufferLen; | ||
46 | WSANAMESPACE_INFO *pi; | ||
47 | int p_count; | ||
48 | int i; | ||
49 | |||
50 | if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) | ||
51 | { | ||
52 | fprintf(stderr, "WSAStartup () failed: %lu\n", GetLastError()); | ||
53 | return 5; | ||
54 | } | ||
55 | |||
56 | dwBufferLen = dwInitialBufferLen; | ||
57 | pi = malloc(dwBufferLen); | ||
58 | if (NULL == pi) | ||
59 | { | ||
60 | fprintf(stderr, "malloc (%lu) failed: %d\n", dwBufferLen, errno); | ||
61 | WSACleanup(); | ||
62 | return 6; | ||
63 | } | ||
64 | p_count = WSAEnumNameSpaceProviders(&dwBufferLen, pi); | ||
65 | if (SOCKET_ERROR == p_count) | ||
66 | { | ||
67 | DWORD err = GetLastError(); | ||
68 | if (WSAEFAULT == err && dwBufferLen != dwInitialBufferLen) | ||
69 | { | ||
70 | free(pi); | ||
71 | |||
72 | pi = malloc(dwBufferLen); | ||
73 | if (pi == NULL) | ||
74 | { | ||
75 | fprintf(stderr, "malloc (%lu) failed: %d\n", dwBufferLen, errno); | ||
76 | WSACleanup(); | ||
77 | return 6; | ||
78 | } | ||
79 | |||
80 | p_count = WSAEnumNameSpaceProviders(&dwBufferLen, pi); | ||
81 | if (SOCKET_ERROR == p_count) | ||
82 | { | ||
83 | fprintf(stderr, "WSAEnumNameSpaceProviders (&%lu, %p) failed: %lu\n", dwBufferLen, pi, GetLastError()); | ||
84 | free(pi); | ||
85 | WSACleanup(); | ||
86 | return 7; | ||
87 | } | ||
88 | } | ||
89 | else | ||
90 | { | ||
91 | fprintf(stderr, "WSAEnumNameSpaceProviders (&%lu, %p) failed: %lu\n", dwBufferLen, pi, GetLastError()); | ||
92 | free(pi); | ||
93 | WSACleanup(); | ||
94 | return 8; | ||
95 | } | ||
96 | } | ||
97 | for (i = 0; i < p_count; i++) | ||
98 | { | ||
99 | if (IsEqualGUID(&pi[i].NSProviderId, &id)) | ||
100 | { | ||
101 | fprintf(stderr, "GNUnet DNS provider is already installed\n"); | ||
102 | free(pi); | ||
103 | WSACleanup(); | ||
104 | return 0; | ||
105 | } | ||
106 | } | ||
107 | free(pi); | ||
108 | |||
109 | cmdl = GetCommandLineW(); | ||
110 | if (cmdl == NULL) | ||
111 | { | ||
112 | WSACleanup(); | ||
113 | return 2; | ||
114 | } | ||
115 | wargv = CommandLineToArgvW(cmdl, &wargc); | ||
116 | if (wargv == NULL) | ||
117 | { | ||
118 | WSACleanup(); | ||
119 | return 3; | ||
120 | } | ||
121 | r = 4; | ||
122 | |||
123 | if (wargc == 2) | ||
124 | { | ||
125 | ret = WSCInstallNameSpace(L"GNUnet DNS provider", wargv[1], NS_DNS, 0, &id); | ||
126 | if (ret == NO_ERROR) | ||
127 | { | ||
128 | fprintf(stderr, "Installed GNUnet DNS provider\n"); | ||
129 | r = 0; | ||
130 | } | ||
131 | else | ||
132 | { | ||
133 | r = 1; | ||
134 | fprintf(stderr, | ||
135 | "WSCInstallNameSpace (L\"GNUnet DNS provider\", \"%S\", %d, 0, %p) failed: %lu\n", | ||
136 | wargv[1], NS_DNS, &id, GetLastError()); | ||
137 | } | ||
138 | } | ||
139 | else | ||
140 | fprintf(stderr, "Usage: %S <path-to-libw32nsp>\n", wargv[0]); | ||
141 | WSACleanup(); | ||
142 | return r; | ||
143 | } | ||
diff --git a/src/gns/w32nsp-resolve.c b/src/gns/w32nsp-resolve.c deleted file mode 100644 index ad0fd3586..000000000 --- a/src/gns/w32nsp-resolve.c +++ /dev/null | |||
@@ -1,464 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /** | ||
21 | * @file gns/w32nsp-resolve.c | ||
22 | * @brief W32 integration for GNS | ||
23 | * @author LRN | ||
24 | */ | ||
25 | /* Instead of including gnunet_common.h */ | ||
26 | #define GNUNET_memcpy(dst, src, n) do { if (0 != n) { (void)memcpy(dst, src, n); } } while (0) | ||
27 | |||
28 | #include <ws2tcpip.h> | ||
29 | #include <windows.h> | ||
30 | #include <nspapi.h> | ||
31 | #include <ws2spi.h> | ||
32 | #include <nspapi.h> | ||
33 | #include <initguid.h> | ||
34 | #include "gnunet_w32nsp_lib.h" | ||
35 | #include <stdio.h> | ||
36 | |||
37 | typedef int (WSPAPI *LPNSPSTARTUP)(LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines); | ||
38 | |||
39 | GUID host = { 0x0002a800, 0, 0, { 0xC0, 0, 0, 0, 0, 0, 0, 0x46 } }; | ||
40 | GUID ip4 = { 0x00090035, 0, 1, { 0xc0, 0, 0, 0, 0, 0, 0, 0x046 } }; | ||
41 | GUID ip6 = { 0x00090035, 0, 0x001c, { 0xc0, 0, 0, 0, 0, 0, 0, 0x046 } }; | ||
42 | |||
43 | DEFINE_GUID(W32_DNS, 0x22059D40, 0x7E9E, 0x11CF, 0xAE, 0x5A, 0x00, 0xAA, 0x00, 0xA7, 0x11, 0x2B); | ||
44 | |||
45 | #define DEFINE_DNS_GUID(a, x) DEFINE_GUID(a, 0x00090035, 0x0000, x, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46) | ||
46 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_A, 0x0001); | ||
47 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_NS, 0x0002); | ||
48 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_CNAME, 0x0005); | ||
49 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_SOA, 0x0006); | ||
50 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_PTR, 0x000c); | ||
51 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_MX, 0x000f); | ||
52 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_TEXT, 0x0010); | ||
53 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_AAAA, 0x001c); | ||
54 | DEFINE_DNS_GUID(SVCID_DNS_TYPE_SRV, 0x0021); | ||
55 | DEFINE_GUID(SVCID_HOSTNAME, 0x0002a800, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); | ||
56 | DEFINE_GUID(SVCID_INET_HOSTADDRBYNAME, 0x0002a803, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); | ||
57 | |||
58 | // | ||
59 | // Utility to turn a list of offsets into a list of addresses. Used | ||
60 | // to convert structures returned as BLOBs. | ||
61 | // | ||
62 | |||
63 | VOID | ||
64 | FixList(PCHAR ** List, PCHAR Base) | ||
65 | { | ||
66 | if (*List) | ||
67 | { | ||
68 | PCHAR * Addr; | ||
69 | |||
70 | Addr = *List = (PCHAR *)(((DWORD)*List + Base)); | ||
71 | while (*Addr) | ||
72 | { | ||
73 | *Addr = (PCHAR)(((DWORD)*Addr + Base)); | ||
74 | Addr++; | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | |||
79 | |||
80 | // | ||
81 | // Routine to convert a hostent returned in a BLOB to one with | ||
82 | // usable pointers. The structure is converted in-place. | ||
83 | // | ||
84 | VOID | ||
85 | UnpackHostEnt(struct hostent * hostent) | ||
86 | { | ||
87 | PCHAR pch; | ||
88 | |||
89 | pch = (PCHAR)hostent; | ||
90 | |||
91 | if (hostent->h_name) | ||
92 | { | ||
93 | hostent->h_name = (PCHAR)((DWORD)hostent->h_name + pch); | ||
94 | } | ||
95 | FixList(&hostent->h_aliases, pch); | ||
96 | FixList(&hostent->h_addr_list, pch); | ||
97 | } | ||
98 | |||
99 | |||
100 | static void | ||
101 | print_hostent(struct hostent *he) | ||
102 | { | ||
103 | int i; | ||
104 | char **pAlias; | ||
105 | |||
106 | printf("\tOfficial name: %s\n", he->h_name); | ||
107 | for (i = 0, pAlias = he->h_aliases; *pAlias != 0; pAlias++) | ||
108 | { | ||
109 | printf("\tAlternate name #%d: %s\n", ++i, *pAlias); | ||
110 | } | ||
111 | printf("\tAddress type: "); | ||
112 | switch (he->h_addrtype) | ||
113 | { | ||
114 | case AF_INET: | ||
115 | printf("AF_INET\n"); | ||
116 | break; | ||
117 | |||
118 | case AF_INET6: | ||
119 | printf("AF_INET6\n"); | ||
120 | break; | ||
121 | |||
122 | case AF_NETBIOS: | ||
123 | printf("AF_NETBIOS\n"); | ||
124 | break; | ||
125 | |||
126 | default: | ||
127 | printf(" %d\n", he->h_addrtype); | ||
128 | break; | ||
129 | } | ||
130 | printf("\tAddress length: %d\n", he->h_length); | ||
131 | |||
132 | if (he->h_addrtype == AF_INET) | ||
133 | { | ||
134 | struct sockaddr_in addr; | ||
135 | memset(&addr, 0, sizeof(addr)); | ||
136 | addr.sin_family = AF_INET; | ||
137 | addr.sin_port = 0; | ||
138 | i = 0; | ||
139 | while (he->h_addr_list[i] != 0) | ||
140 | { | ||
141 | char buf[1024]; | ||
142 | DWORD buflen = 1024; | ||
143 | addr.sin_addr = *(struct in_addr *)he->h_addr_list[i++]; | ||
144 | if (NO_ERROR == WSAAddressToStringA((LPSOCKADDR)&addr, sizeof(addr), NULL, buf, &buflen)) | ||
145 | printf("\tIPv4 Address #%d: %s\n", i, buf); | ||
146 | else | ||
147 | printf("\tIPv4 Address #%d: Can't convert: %lu\n", i, GetLastError()); | ||
148 | } | ||
149 | } | ||
150 | else if (he->h_addrtype == AF_INET6) | ||
151 | { | ||
152 | struct sockaddr_in6 addr; | ||
153 | memset(&addr, 0, sizeof(addr)); | ||
154 | addr.sin6_family = AF_INET6; | ||
155 | addr.sin6_port = 0; | ||
156 | i = 0; | ||
157 | while (he->h_addr_list[i] != 0) | ||
158 | { | ||
159 | char buf[1024]; | ||
160 | DWORD buflen = 1024; | ||
161 | addr.sin6_addr = *(struct in6_addr *)he->h_addr_list[i++]; | ||
162 | if (NO_ERROR == WSAAddressToStringA((LPSOCKADDR)&addr, sizeof(addr), NULL, buf, &buflen)) | ||
163 | printf("\tIPv6 Address #%d: %s\n", i, buf); | ||
164 | else | ||
165 | printf("\tIPv6 Address #%d: Can't convert: %lu\n", i, GetLastError()); | ||
166 | } | ||
167 | } | ||
168 | } | ||
169 | |||
170 | |||
171 | int | ||
172 | main(int argc, char **argv) | ||
173 | { | ||
174 | int ret; | ||
175 | int r = 1; | ||
176 | WSADATA wsd; | ||
177 | GUID prov; | ||
178 | GUID sc; | ||
179 | wchar_t *cmdl; | ||
180 | int wargc; | ||
181 | wchar_t **wargv; | ||
182 | |||
183 | if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) | ||
184 | { | ||
185 | fprintf(stderr, "WSAStartup() failed: %lu\n", GetLastError()); | ||
186 | return 5; | ||
187 | } | ||
188 | |||
189 | cmdl = GetCommandLineW(); | ||
190 | if (cmdl == NULL) | ||
191 | { | ||
192 | WSACleanup(); | ||
193 | return 2; | ||
194 | } | ||
195 | wargv = CommandLineToArgvW(cmdl, &wargc); | ||
196 | if (wargv == NULL) | ||
197 | { | ||
198 | WSACleanup(); | ||
199 | return 3; | ||
200 | } | ||
201 | r = 4; | ||
202 | |||
203 | if (wargc == 5) | ||
204 | { | ||
205 | if (wcscmp(wargv[1], L"A") == 0) | ||
206 | sc = SVCID_DNS_TYPE_A; | ||
207 | else if (wcscmp(wargv[1], L"AAAA") == 0) | ||
208 | sc = SVCID_DNS_TYPE_AAAA; | ||
209 | else if (wcscmp(wargv[1], L"name") == 0) | ||
210 | sc = SVCID_HOSTNAME; | ||
211 | else if (wcscmp(wargv[1], L"addr") == 0) | ||
212 | sc = SVCID_INET_HOSTADDRBYNAME; | ||
213 | else | ||
214 | wargc -= 1; | ||
215 | if (wcscmp(wargv[4], L"mswdns") == 0) | ||
216 | prov = W32_DNS; | ||
217 | else if (wcscmp(wargv[4], L"gnunetdns") == 0) | ||
218 | prov = GNUNET_NAMESPACE_PROVIDER_DNS; | ||
219 | else | ||
220 | wargc -= 1; | ||
221 | } | ||
222 | else if (wargc == 3) | ||
223 | { | ||
224 | } | ||
225 | else | ||
226 | { | ||
227 | fprintf(stderr, "Usage: %S <record type> <service name> <NSP library path> <NSP id>\n" | ||
228 | "record type - one of the following: A | AAAA | name | addr\n" | ||
229 | "service name - a string to resolve; \" \" (a space) means 'blank'\n" | ||
230 | "NSP library path - path to libw32nsp\n" | ||
231 | "NSP id - one of the following: mswdns | gnunetdns\n", | ||
232 | wargv[0]); | ||
233 | } | ||
234 | |||
235 | if (wargc == 5) | ||
236 | { | ||
237 | HMODULE nsp; | ||
238 | |||
239 | nsp = LoadLibraryW(wargv[3]); | ||
240 | if (nsp == NULL) | ||
241 | { | ||
242 | fprintf(stderr, "Failed to load library `%S'\n", wargv[3]); | ||
243 | } | ||
244 | else | ||
245 | { | ||
246 | LPNSPSTARTUP startup = (LPNSPSTARTUP)GetProcAddress(nsp, "NSPStartup"); | ||
247 | if (startup == NULL) | ||
248 | startup = (LPNSPSTARTUP)GetProcAddress(nsp, "NSPStartup@8"); | ||
249 | if (startup != NULL) | ||
250 | { | ||
251 | NSP_ROUTINE api; | ||
252 | api.cbSize = sizeof(api); | ||
253 | ret = startup(&prov, &api); | ||
254 | if (NO_ERROR != ret) | ||
255 | fprintf(stderr, "startup failed: %lu\n", GetLastError()); | ||
256 | else | ||
257 | { | ||
258 | HANDLE lookup; | ||
259 | WSAQUERYSETW search; | ||
260 | char buf[4096]; | ||
261 | WSAQUERYSETW *result = (WSAQUERYSETW *)buf; | ||
262 | DWORD resultsize; | ||
263 | DWORD err; | ||
264 | memset(&search, 0, sizeof(search)); | ||
265 | search.dwSize = sizeof(search); | ||
266 | search.lpszServiceInstanceName = (wcscmp(wargv[2], L" ") == 0) ? NULL : wargv[2]; | ||
267 | search.lpServiceClassId = ≻ | ||
268 | search.lpNSProviderId = &prov; | ||
269 | search.dwNameSpace = NS_ALL; | ||
270 | ret = api.NSPLookupServiceBegin(&prov, &search, NULL, LUP_RETURN_ALL, &lookup); | ||
271 | if (ret != NO_ERROR) | ||
272 | { | ||
273 | fprintf(stderr, "lookup start failed\n"); | ||
274 | } | ||
275 | else | ||
276 | { | ||
277 | resultsize = 4096; | ||
278 | ret = api.NSPLookupServiceNext(lookup, LUP_RETURN_ALL, &resultsize, result); | ||
279 | err = GetLastError(); | ||
280 | if (ret != NO_ERROR) | ||
281 | { | ||
282 | fprintf(stderr, "lookup next failed: %lu\n", err); | ||
283 | } | ||
284 | else | ||
285 | { | ||
286 | int i; | ||
287 | printf("Got result:\n"); | ||
288 | printf(" lpszServiceInstanceName: %S\n", result->lpszServiceInstanceName ? result->lpszServiceInstanceName : L"NULL"); | ||
289 | if (result->lpServiceClassId) | ||
290 | printf(" lpServiceClassId: { 0x%08lX,0x%04X,0x%04X, { 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X } }\n", | ||
291 | result->lpServiceClassId->Data1, result->lpServiceClassId->Data2, result->lpServiceClassId->Data3, result->lpServiceClassId->Data4[0], | ||
292 | result->lpServiceClassId->Data4[1], result->lpServiceClassId->Data4[2], result->lpServiceClassId->Data4[3], result->lpServiceClassId->Data4[4], | ||
293 | result->lpServiceClassId->Data4[5], result->lpServiceClassId->Data4[6], result->lpServiceClassId->Data4[7]); | ||
294 | else | ||
295 | printf(" lpServiceClassId: NULL\n"); | ||
296 | if (result->lpVersion) | ||
297 | printf(" lpVersion: 0x%08lX, %d\n", result->lpVersion->dwVersion, result->lpVersion->ecHow); | ||
298 | else | ||
299 | printf(" lpVersion: NULL\n"); | ||
300 | printf(" lpszComment: %S\n", result->lpszComment ? result->lpszComment : L"NULL"); | ||
301 | printf(" dwNameSpace: %lu\n", result->dwNameSpace); | ||
302 | if (result->lpNSProviderId) | ||
303 | printf(" lpNSProviderId: { 0x%08lX,0x%04X,0x%04X, { 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X } }\n", | ||
304 | result->lpNSProviderId->Data1, result->lpNSProviderId->Data2, result->lpNSProviderId->Data3, result->lpNSProviderId->Data4[0], | ||
305 | result->lpNSProviderId->Data4[1], result->lpNSProviderId->Data4[2], result->lpNSProviderId->Data4[3], result->lpNSProviderId->Data4[4], | ||
306 | result->lpNSProviderId->Data4[5], result->lpNSProviderId->Data4[6], result->lpNSProviderId->Data4[7]); | ||
307 | else | ||
308 | printf(" lpNSProviderId: NULL\n"); | ||
309 | printf(" lpszContext: %S\n", result->lpszContext ? result->lpszContext : L"NULL"); | ||
310 | printf(" dwNumberOfProtocols: %lu\n", result->dwNumberOfProtocols); | ||
311 | printf(" lpszQueryString: %S\n", result->lpszQueryString ? result->lpszQueryString : L"NULL"); | ||
312 | printf(" dwNumberOfCsAddrs: %lu\n", result->dwNumberOfCsAddrs); | ||
313 | for (i = 0; i < result->dwNumberOfCsAddrs; i++) | ||
314 | { | ||
315 | switch (result->lpcsaBuffer[i].iSocketType) | ||
316 | { | ||
317 | case SOCK_STREAM: | ||
318 | printf(" %d: iSocketType = SOCK_STREAM\n", i); | ||
319 | break; | ||
320 | |||
321 | case SOCK_DGRAM: | ||
322 | printf(" %d: iSocketType = SOCK_DGRAM\n", i); | ||
323 | break; | ||
324 | |||
325 | default: | ||
326 | printf(" %d: iSocketType = %d\n", i, result->lpcsaBuffer[i].iSocketType); | ||
327 | } | ||
328 | switch (result->lpcsaBuffer[i].iProtocol) | ||
329 | { | ||
330 | case IPPROTO_TCP: | ||
331 | printf(" %d: iProtocol = IPPROTO_TCP\n", i); | ||
332 | break; | ||
333 | |||
334 | case IPPROTO_UDP: | ||
335 | printf(" %d: iProtocol = IPPROTO_UDP\n", i); | ||
336 | break; | ||
337 | |||
338 | default: | ||
339 | printf(" %d: iProtocol = %d\n", i, result->lpcsaBuffer[i].iProtocol); | ||
340 | } | ||
341 | switch (result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family) | ||
342 | { | ||
343 | case AF_INET: | ||
344 | printf(" %d: loc family = AF_INET\n", i); | ||
345 | break; | ||
346 | |||
347 | case AF_INET6: | ||
348 | printf(" %d: loc family = AF_INET6\n", i); | ||
349 | break; | ||
350 | |||
351 | default: | ||
352 | printf(" %d: loc family = %hu\n", i, result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family); | ||
353 | } | ||
354 | switch (result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family) | ||
355 | { | ||
356 | case AF_INET: | ||
357 | printf(" %d: rem family = AF_INET\n", i); | ||
358 | break; | ||
359 | |||
360 | case AF_INET6: | ||
361 | printf(" %d: rem family = AF_INET6\n", i); | ||
362 | break; | ||
363 | |||
364 | default: | ||
365 | printf(" %d: rem family = %hu\n", i, result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family); | ||
366 | } | ||
367 | char buf[1024]; | ||
368 | DWORD buflen = 1024; | ||
369 | if (NO_ERROR == WSAAddressToStringA(result->lpcsaBuffer[i].LocalAddr.lpSockaddr, result->lpcsaBuffer[i].LocalAddr.iSockaddrLength, NULL, buf, &buflen)) | ||
370 | printf("\tLocal Address #%d: %s\n", i, buf); | ||
371 | else | ||
372 | printf("\tLocal Address #%d: Can't convert: %lu\n", i, GetLastError()); | ||
373 | buflen = 1024; | ||
374 | if (NO_ERROR == WSAAddressToStringA(result->lpcsaBuffer[i].RemoteAddr.lpSockaddr, result->lpcsaBuffer[i].RemoteAddr.iSockaddrLength, NULL, buf, &buflen)) | ||
375 | printf("\tRemote Address #%d: %s\n", i, buf); | ||
376 | else | ||
377 | printf("\tRemote Address #%d: Can't convert: %lu\n", i, GetLastError()); | ||
378 | } | ||
379 | printf(" dwOutputFlags: 0x%08lX\n", result->dwOutputFlags); | ||
380 | printf(" lpBlob: 0x%p\n", result->lpBlob); | ||
381 | if (result->lpBlob) | ||
382 | { | ||
383 | struct hostent *he = malloc(result->lpBlob->cbSize); | ||
384 | if (he != NULL) | ||
385 | { | ||
386 | GNUNET_memcpy(he, result->lpBlob->pBlobData, result->lpBlob->cbSize); | ||
387 | UnpackHostEnt(he); | ||
388 | print_hostent(he); | ||
389 | free(he); | ||
390 | } | ||
391 | } | ||
392 | } | ||
393 | ret = api.NSPLookupServiceEnd(lookup); | ||
394 | if (ret != NO_ERROR) | ||
395 | printf("NSPLookupServiceEnd() failed: %lu\n", GetLastError()); | ||
396 | } | ||
397 | api.NSPCleanup(&prov); | ||
398 | } | ||
399 | } | ||
400 | FreeLibrary(nsp); | ||
401 | } | ||
402 | } | ||
403 | else if (wargc == 3) | ||
404 | { | ||
405 | int s; | ||
406 | ADDRINFOW hints; | ||
407 | ADDRINFOW *result; | ||
408 | ADDRINFOW *pos; | ||
409 | |||
410 | memset(&hints, 0, sizeof(struct addrinfo)); | ||
411 | hints.ai_family = AF_UNSPEC; | ||
412 | hints.ai_socktype = SOCK_STREAM; | ||
413 | |||
414 | if (0 != (s = GetAddrInfoW(wargv[2], NULL, &hints, &result))) | ||
415 | { | ||
416 | fprintf(stderr, "Cound not resolve `%S' using GetAddrInfoW: %lu\n", | ||
417 | wargv[2], GetLastError()); | ||
418 | } | ||
419 | else | ||
420 | { | ||
421 | for (pos = result; pos != NULL; pos = pos->ai_next) | ||
422 | { | ||
423 | wchar_t tmpbuf[1024]; | ||
424 | DWORD buflen = 1024; | ||
425 | if (0 == WSAAddressToStringW(pos->ai_addr, pos->ai_addrlen, NULL, tmpbuf, &buflen)) | ||
426 | fprintf(stderr, "Result:\n" | ||
427 | " flags: 0x%X\n" | ||
428 | " family: 0x%X\n" | ||
429 | " socktype: 0x%X\n" | ||
430 | " protocol: 0x%X\n" | ||
431 | " addrlen: %u\n" | ||
432 | " addr: %S\n" | ||
433 | " canonname: %S\n", | ||
434 | pos->ai_flags, | ||
435 | pos->ai_family, | ||
436 | pos->ai_socktype, | ||
437 | pos->ai_protocol, | ||
438 | pos->ai_addrlen, | ||
439 | tmpbuf, | ||
440 | pos->ai_canonname); | ||
441 | else | ||
442 | fprintf(stderr, "Result:\n" | ||
443 | " flags: 0x%X\n" | ||
444 | " family: 0x%X\n" | ||
445 | " socktype: 0x%X\n" | ||
446 | " protocol: 0x%X\n" | ||
447 | " addrlen: %u\n" | ||
448 | " addr: %S\n" | ||
449 | " canonname: %S\n", | ||
450 | pos->ai_flags, | ||
451 | pos->ai_family, | ||
452 | pos->ai_socktype, | ||
453 | pos->ai_protocol, | ||
454 | pos->ai_addrlen, | ||
455 | L"<can't stringify>", | ||
456 | pos->ai_canonname); | ||
457 | } | ||
458 | if (NULL != result) | ||
459 | FreeAddrInfoW(result); | ||
460 | } | ||
461 | } | ||
462 | WSACleanup(); | ||
463 | return r; | ||
464 | } | ||
diff --git a/src/gns/w32nsp-uninstall.c b/src/gns/w32nsp-uninstall.c deleted file mode 100644 index f5031f341..000000000 --- a/src/gns/w32nsp-uninstall.c +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | #include <ws2spi.h> | ||
2 | #include <windows.h> | ||
3 | #include <nspapi.h> | ||
4 | #include <initguid.h> | ||
5 | #include "gnunet_w32nsp_lib.h" | ||
6 | #include <stdio.h> | ||
7 | |||
8 | int | ||
9 | main(int argc, char **argv) | ||
10 | { | ||
11 | int ret; | ||
12 | GUID id = GNUNET_NAMESPACE_PROVIDER_DNS; | ||
13 | WSADATA wsd; | ||
14 | |||
15 | if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) | ||
16 | { | ||
17 | fprintf(stderr, "WSAStartup () failed: %lu\n", GetLastError()); | ||
18 | return 5; | ||
19 | } | ||
20 | |||
21 | ret = WSCUnInstallNameSpace(&id); | ||
22 | if (ret == NO_ERROR) | ||
23 | { | ||
24 | fprintf(stderr, "Uninstalled GNUnet DNS provider\n"); | ||
25 | WSACleanup(); | ||
26 | return 0; | ||
27 | } | ||
28 | fprintf(stderr, "WSCUnInstallNameSpace () failed: %lu\n", GetLastError()); | ||
29 | WSACleanup(); | ||
30 | return 1; | ||
31 | } \ No newline at end of file | ||
diff --git a/src/gns/w32nsp.c b/src/gns/w32nsp.c deleted file mode 100644 index 3de4452f0..000000000 --- a/src/gns/w32nsp.c +++ /dev/null | |||
@@ -1,711 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /** | ||
21 | * @file gns/w32nsp.c | ||
22 | * @brief W32 integration for GNS | ||
23 | * @author LRN | ||
24 | */ | ||
25 | /* This code is partially based upon samples from the book | ||
26 | * "Network Programming For Microsoft Windows, 2Nd Edition". | ||
27 | */ | ||
28 | |||
29 | #define VERBOSE 0 | ||
30 | #if !VERBOSE | ||
31 | # define DEBUGLOG(s, ...) | ||
32 | #endif | ||
33 | #if VERBOSE | ||
34 | # define __printf__ printf | ||
35 | # define DEBUGLOG(s, ...) printf(s, ## __VA_ARGS__) | ||
36 | #endif | ||
37 | |||
38 | #include <stdint.h> | ||
39 | #include <ws2tcpip.h> | ||
40 | #include <ws2spi.h> | ||
41 | #include <windows.h> | ||
42 | #include <nspapi.h> | ||
43 | |||
44 | #define WINDOWS 1 | ||
45 | #define MINGW 1 | ||
46 | #ifndef __BYTE_ORDER | ||
47 | #ifdef _BYTE_ORDER | ||
48 | #define __BYTE_ORDER _BYTE_ORDER | ||
49 | #else | ||
50 | #ifdef BYTE_ORDER | ||
51 | #define __BYTE_ORDER BYTE_ORDER | ||
52 | #endif | ||
53 | #endif | ||
54 | #endif | ||
55 | #ifndef __BIG_ENDIAN | ||
56 | #ifdef _BIG_ENDIAN | ||
57 | #define __BIG_ENDIAN _BIG_ENDIAN | ||
58 | #else | ||
59 | #ifdef BIG_ENDIAN | ||
60 | #define __BIG_ENDIAN BIG_ENDIAN | ||
61 | #endif | ||
62 | #endif | ||
63 | #endif | ||
64 | #ifndef __LITTLE_ENDIAN | ||
65 | #ifdef _LITTLE_ENDIAN | ||
66 | #define __LITTLE_ENDIAN _LITTLE_ENDIAN | ||
67 | #else | ||
68 | #ifdef LITTLE_ENDIAN | ||
69 | #define __LITTLE_ENDIAN LITTLE_ENDIAN | ||
70 | #endif | ||
71 | #endif | ||
72 | #endif | ||
73 | #include "w32resolver.h" | ||
74 | #include <initguid.h> | ||
75 | #include "gnunet_w32nsp_lib.h" | ||
76 | #undef INITGUID | ||
77 | |||
78 | #define NSPAPI_VERSION_MAJOR 4 | ||
79 | #define NSPAPI_VERSION_MINOR 4 | ||
80 | |||
81 | static CRITICAL_SECTION records_cs; | ||
82 | |||
83 | struct record { | ||
84 | _win_socket s; | ||
85 | DWORD flags; | ||
86 | uint8_t state; | ||
87 | char *buf; | ||
88 | wchar_t *name; | ||
89 | }; | ||
90 | |||
91 | static struct record *records = NULL; | ||
92 | static size_t records_len = 0; | ||
93 | static size_t records_size = 0; | ||
94 | |||
95 | static int | ||
96 | resize_records() | ||
97 | { | ||
98 | size_t new_size = records_len > 0 ? records_len * 2 : 5; | ||
99 | struct record *new_records = malloc(new_size * sizeof(struct record)); | ||
100 | |||
101 | if (new_records == NULL) | ||
102 | { | ||
103 | SetLastError(WSA_NOT_ENOUGH_MEMORY); | ||
104 | return 0; | ||
105 | } | ||
106 | GNUNET_memcpy(new_records, records, records_len * sizeof(struct record)); | ||
107 | memset(&new_records[records_len], 0, sizeof(struct record) * (new_size - records_len)); | ||
108 | records_size = new_size; | ||
109 | free(records); | ||
110 | records = new_records; | ||
111 | return 1; | ||
112 | } | ||
113 | |||
114 | static int | ||
115 | add_record(_win_socket s, const wchar_t *name, DWORD flags) | ||
116 | { | ||
117 | int res = 1; | ||
118 | int i; | ||
119 | int empty = -1; | ||
120 | |||
121 | //EnterCriticalSection (&records_cs); | ||
122 | for (i = 0; i < records_len; i++) | ||
123 | if (records[i].state == 0) | ||
124 | break; | ||
125 | empty = i; | ||
126 | if (i == records_len) | ||
127 | { | ||
128 | res = resize_records(); | ||
129 | if (res) | ||
130 | empty = records_len++; | ||
131 | } | ||
132 | if (res) | ||
133 | { | ||
134 | struct record r; | ||
135 | r.s = s; | ||
136 | r.flags = flags; | ||
137 | r.name = (wchar_t *)name; | ||
138 | r.state = 1; | ||
139 | r.buf = NULL; | ||
140 | if (name) | ||
141 | r.name = wcsdup(name); | ||
142 | records[empty] = r; | ||
143 | } | ||
144 | //LeaveCriticalSection (&records_cs); | ||
145 | return res; | ||
146 | } | ||
147 | |||
148 | /* These are not defined by mingw.org headers at the moment*/ | ||
149 | typedef INT (WSPAPI *LPNSPIOCTL)(HANDLE, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPWSACOMPLETION, LPWSATHREADID); | ||
150 | typedef struct _NSP_ROUTINE_XP { | ||
151 | DWORD cbSize; | ||
152 | DWORD dwMajorVersion; | ||
153 | DWORD dwMinorVersion; | ||
154 | LPNSPCLEANUP NSPCleanup; | ||
155 | LPNSPLOOKUPSERVICEBEGIN NSPLookupServiceBegin; | ||
156 | LPNSPLOOKUPSERVICENEXT NSPLookupServiceNext; | ||
157 | LPNSPLOOKUPSERVICEEND NSPLookupServiceEnd; | ||
158 | LPNSPSETSERVICE NSPSetService; | ||
159 | LPNSPINSTALLSERVICECLASS NSPInstallServiceClass; | ||
160 | LPNSPREMOVESERVICECLASS NSPRemoveServiceClass; | ||
161 | LPNSPGETSERVICECLASSINFO NSPGetServiceClassInfo; | ||
162 | LPNSPIOCTL NSPIoctl; | ||
163 | } NSP_ROUTINE_XP; | ||
164 | |||
165 | static _win_socket | ||
166 | connect_to_dns_resolver() | ||
167 | { | ||
168 | struct sockaddr_in addr; | ||
169 | _win_socket r; | ||
170 | int ret; | ||
171 | |||
172 | r = _win_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | ||
173 | if (INVALID_SOCKET == r) | ||
174 | { | ||
175 | SetLastError(16004); | ||
176 | return r; | ||
177 | } | ||
178 | |||
179 | addr.sin_family = AF_INET; | ||
180 | addr.sin_port = htons(5353); /* TCP 5353 is not registered; UDP 5353 is */ | ||
181 | addr.sin_addr.s_addr = inet_addr("127.0.0.1"); | ||
182 | |||
183 | ret = _win_connect(r, (struct sockaddr *)&addr, sizeof(addr)); | ||
184 | if (SOCKET_ERROR == ret) | ||
185 | { | ||
186 | DWORD err = GetLastError(); | ||
187 | closesocket(r); | ||
188 | SetLastError(err); | ||
189 | SetLastError(16005); | ||
190 | r = INVALID_SOCKET; | ||
191 | } | ||
192 | return r; | ||
193 | } | ||
194 | |||
195 | static int | ||
196 | send_name_to_ip_request(LPWSAQUERYSETW lpqsRestrictions, | ||
197 | LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags, | ||
198 | _win_socket *resolver) | ||
199 | { | ||
200 | struct GNUNET_W32RESOLVER_GetMessage *msg; | ||
201 | int af4 = 0; | ||
202 | int af6 = 0; | ||
203 | char *buf; | ||
204 | int ret = 1; | ||
205 | int i; | ||
206 | size_t size = sizeof(struct GNUNET_W32RESOLVER_GetMessage); | ||
207 | size_t namelen = 0; | ||
208 | |||
209 | if (lpqsRestrictions->lpszServiceInstanceName) | ||
210 | namelen = sizeof(wchar_t) * (wcslen(lpqsRestrictions->lpszServiceInstanceName) + 1); | ||
211 | size += namelen; | ||
212 | buf = malloc(size); | ||
213 | msg = (struct GNUNET_W32RESOLVER_GetMessage *)buf; | ||
214 | msg->header.size = htons(size); | ||
215 | msg->header.type = htons(GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST); | ||
216 | if (lpqsRestrictions->dwNumberOfProtocols > 0) | ||
217 | { | ||
218 | int i; | ||
219 | for (i = 0; i < lpqsRestrictions->dwNumberOfProtocols; i++) | ||
220 | { | ||
221 | if (lpqsRestrictions->lpafpProtocols[0].iAddressFamily == AF_INET) | ||
222 | af4 = 1; | ||
223 | if (lpqsRestrictions->lpafpProtocols[0].iAddressFamily == AF_INET6) | ||
224 | af6 = 1; | ||
225 | } | ||
226 | } | ||
227 | if (af4 && !af6) | ||
228 | msg->af = htonl(AF_INET); | ||
229 | else if (af6 && !af4) | ||
230 | msg->af = htonl(AF_INET6); | ||
231 | else | ||
232 | msg->af = htonl(AF_UNSPEC); | ||
233 | if (lpqsRestrictions->lpszServiceInstanceName) | ||
234 | GNUNET_memcpy(&msg[1], lpqsRestrictions->lpszServiceInstanceName, namelen); | ||
235 | msg->sc_data1 = htonl(lpqsRestrictions->lpServiceClassId->Data1); | ||
236 | msg->sc_data2 = htons(lpqsRestrictions->lpServiceClassId->Data2); | ||
237 | msg->sc_data3 = htons(lpqsRestrictions->lpServiceClassId->Data3); | ||
238 | for (i = 0; i < 8; i++) | ||
239 | msg->sc_data4[i] = lpqsRestrictions->lpServiceClassId->Data4[i]; | ||
240 | *resolver = connect_to_dns_resolver(); | ||
241 | if (*resolver != INVALID_SOCKET) | ||
242 | { | ||
243 | if (size != send(*resolver, buf, size, 0)) | ||
244 | { | ||
245 | #if VERBOSE | ||
246 | DWORD err = GetLastError(); | ||
247 | #endif | ||
248 | closesocket(*resolver); | ||
249 | *resolver = INVALID_SOCKET; | ||
250 | DEBUGLOG("GNUNET_W32NSP_LookupServiceBegin: failed to send request: %lu\n", err); | ||
251 | SetLastError(WSATRY_AGAIN); | ||
252 | ret = 0; | ||
253 | } | ||
254 | } | ||
255 | else | ||
256 | ret = 0; | ||
257 | free(buf); | ||
258 | return ret; | ||
259 | } | ||
260 | |||
261 | static int WSPAPI | ||
262 | NSPCleanup(LPGUID lpProviderId) | ||
263 | { | ||
264 | DEBUGLOG("NSPCleanup\n"); | ||
265 | if (IsEqualGUID(lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS)) | ||
266 | { | ||
267 | return NO_ERROR; | ||
268 | } | ||
269 | SetLastError(WSAEINVALIDPROVIDER); | ||
270 | return SOCKET_ERROR; | ||
271 | } | ||
272 | |||
273 | BOOL WINAPI | ||
274 | DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) | ||
275 | { | ||
276 | switch (fdwReason) | ||
277 | { | ||
278 | case DLL_PROCESS_ATTACH: | ||
279 | if (!InitializeCriticalSectionAndSpinCount(&records_cs, 0x00000400)) | ||
280 | { | ||
281 | return FALSE; | ||
282 | } | ||
283 | break; | ||
284 | |||
285 | case DLL_THREAD_ATTACH: | ||
286 | break; | ||
287 | |||
288 | case DLL_THREAD_DETACH: | ||
289 | break; | ||
290 | |||
291 | case DLL_PROCESS_DETACH: | ||
292 | DeleteCriticalSection(&records_cs); | ||
293 | break; | ||
294 | } | ||
295 | return TRUE; | ||
296 | } | ||
297 | |||
298 | |||
299 | |||
300 | |||
301 | static int WSPAPI | ||
302 | GNUNET_W32NSP_LookupServiceBegin(LPGUID lpProviderId, LPWSAQUERYSETW lpqsRestrictions, | ||
303 | LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags, | ||
304 | LPHANDLE lphLookup) | ||
305 | { | ||
306 | DEBUGLOG("GNUNET_W32NSP_LookupServiceBegin\n"); | ||
307 | if (IsEqualGUID(lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS)) | ||
308 | { | ||
309 | SOCKET s; | ||
310 | if (lpqsRestrictions->dwNameSpace != NS_DNS && lpqsRestrictions->dwNameSpace != NS_ALL) | ||
311 | { | ||
312 | DEBUGLOG("GNUNET_W32NSP_LookupServiceBegin: wrong namespace\n"); | ||
313 | SetLastError(WSAEINVAL); | ||
314 | return SOCKET_ERROR; | ||
315 | } | ||
316 | if (lpqsRestrictions->lpszServiceInstanceName != NULL) | ||
317 | { | ||
318 | wchar_t *s = lpqsRestrictions->lpszServiceInstanceName; | ||
319 | size_t len = wcslen(s); | ||
320 | if (len >= 5 && wcscmp(&s[len - 5], L".zkey") == 0) | ||
321 | { | ||
322 | } | ||
323 | else if (len >= 4 && wcscmp(&s[len - 4], L".gnu") == 0) | ||
324 | { | ||
325 | } | ||
326 | else | ||
327 | { | ||
328 | DEBUGLOG("GNUNET_W32NSP_LookupServiceBegin: unsupported TLD\n"); | ||
329 | SetLastError(WSAEINVAL); | ||
330 | return SOCKET_ERROR; | ||
331 | } | ||
332 | } | ||
333 | |||
334 | if (send_name_to_ip_request(lpqsRestrictions, | ||
335 | lpServiceClassInfo, dwControlFlags, &s)) | ||
336 | { | ||
337 | if (!(add_record(s, lpqsRestrictions->lpszServiceInstanceName, dwControlFlags))) | ||
338 | { | ||
339 | DWORD err = GetLastError(); | ||
340 | DEBUGLOG("GNUNET_W32NSP_LookupServiceBegin: failed to add a record\n"); | ||
341 | closesocket(s); | ||
342 | SetLastError(err); | ||
343 | return SOCKET_ERROR; | ||
344 | } | ||
345 | *lphLookup = (HANDLE)s; | ||
346 | DEBUGLOG("GNUNET_W32NSP_LookupServiceBegin: OK (%lu)\n", GetLastError()); | ||
347 | return NO_ERROR; | ||
348 | } | ||
349 | return SOCKET_ERROR; | ||
350 | } | ||
351 | DEBUGLOG("GNUNET_W32NSP_LookupServiceBegin: wrong provider\n"); | ||
352 | SetLastError(WSAEINVALIDPROVIDER); | ||
353 | return SOCKET_ERROR; | ||
354 | } | ||
355 | |||
356 | #define UnmarshallPtr(ptr, ptrtype, base) \ | ||
357 | if (ptr) \ | ||
358 | ptr = (ptrtype *) (base + (uintptr_t)ptr) | ||
359 | |||
360 | static void | ||
361 | UnmarshallWSAQUERYSETW(LPWSAQUERYSETW req) | ||
362 | { | ||
363 | int i; | ||
364 | char *base = (char *)req; | ||
365 | |||
366 | UnmarshallPtr(req->lpszServiceInstanceName, wchar_t, base); | ||
367 | UnmarshallPtr(req->lpServiceClassId, GUID, base); | ||
368 | UnmarshallPtr(req->lpVersion, WSAVERSION, base); | ||
369 | UnmarshallPtr(req->lpszComment, wchar_t, base); | ||
370 | UnmarshallPtr(req->lpNSProviderId, GUID, base); | ||
371 | UnmarshallPtr(req->lpszContext, wchar_t, base); | ||
372 | UnmarshallPtr(req->lpafpProtocols, AFPROTOCOLS, base); | ||
373 | UnmarshallPtr(req->lpszQueryString, wchar_t, base); | ||
374 | UnmarshallPtr(req->lpcsaBuffer, CSADDR_INFO, base); | ||
375 | for (i = 0; i < req->dwNumberOfCsAddrs; i++) | ||
376 | { | ||
377 | UnmarshallPtr(req->lpcsaBuffer[i].LocalAddr.lpSockaddr, SOCKADDR, base); | ||
378 | UnmarshallPtr(req->lpcsaBuffer[i].RemoteAddr.lpSockaddr, SOCKADDR, base); | ||
379 | } | ||
380 | UnmarshallPtr(req->lpBlob, BLOB, base); | ||
381 | if (req->lpBlob) | ||
382 | UnmarshallPtr(req->lpBlob->pBlobData, BYTE, base); | ||
383 | } | ||
384 | |||
385 | static int WSAAPI | ||
386 | GNUNET_W32NSP_LookupServiceNext(HANDLE hLookup, DWORD dwControlFlags, | ||
387 | LPDWORD lpdwBufferLength, LPWSAQUERYSETW lpqsResults) | ||
388 | { | ||
389 | /*DWORD effective_flags;*/ | ||
390 | int i; | ||
391 | struct GNUNET_MessageHeader header = { 0, 0 }; | ||
392 | int rec = -1; | ||
393 | int rc; | ||
394 | int to_receive; | ||
395 | int t; | ||
396 | char *buf; | ||
397 | |||
398 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext\n"); | ||
399 | //EnterCriticalSection (&records_cs); | ||
400 | for (i = 0; i < records_len; i++) | ||
401 | { | ||
402 | if (records[i].s == (_win_socket)hLookup) | ||
403 | { | ||
404 | rec = i; | ||
405 | break; | ||
406 | } | ||
407 | } | ||
408 | if (rec == -1) | ||
409 | { | ||
410 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: invalid handle\n"); | ||
411 | SetLastError(WSA_INVALID_HANDLE); | ||
412 | //LeaveCriticalSection (&records_cs); | ||
413 | return SOCKET_ERROR; | ||
414 | } | ||
415 | if (records[rec].state & 4) | ||
416 | { | ||
417 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: session is closed\n"); | ||
418 | SetLastError(WSA_E_NO_MORE); | ||
419 | //LeaveCriticalSection (&records_cs); | ||
420 | return SOCKET_ERROR; | ||
421 | } | ||
422 | /*effective_flags = dwControlFlags & records[rec].flags;*/ | ||
423 | if (records[rec].buf) | ||
424 | { | ||
425 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: checking buffer\n"); | ||
426 | header = *((struct GNUNET_MessageHeader *)records[rec].buf); | ||
427 | if (*lpdwBufferLength < header.size - sizeof(struct GNUNET_W32RESOLVER_GetMessage)) | ||
428 | { | ||
429 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n"); | ||
430 | SetLastError(WSAEFAULT); | ||
431 | //LeaveCriticalSection (&records_cs); | ||
432 | return SOCKET_ERROR; | ||
433 | } | ||
434 | GNUNET_memcpy(lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)records[rec].buf)[1], header.size - sizeof(struct GNUNET_W32RESOLVER_GetMessage)); | ||
435 | free(records[rec].buf); | ||
436 | records[rec].buf = NULL; | ||
437 | //LeaveCriticalSection (&records_cs); | ||
438 | UnmarshallWSAQUERYSETW((LPWSAQUERYSETW)lpqsResults); | ||
439 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: OK (from buffer)\n"); | ||
440 | return NO_ERROR; | ||
441 | } | ||
442 | records[rec].state |= 8; | ||
443 | //LeaveCriticalSection (&records_cs); | ||
444 | to_receive = sizeof(header); | ||
445 | rc = 0; | ||
446 | #if VERBOSE | ||
447 | { | ||
448 | unsigned long have; | ||
449 | int ior = ioctlsocket((_win_socket)hLookup, FIONREAD, &have); | ||
450 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: reading %d bytes as a header from %p, %lu bytes available\n", to_receive, hLookup, have); | ||
451 | } | ||
452 | #endif | ||
453 | while (to_receive > 0) | ||
454 | { | ||
455 | t = recv((_win_socket)hLookup, &((char *)&header)[rc], to_receive, 0); | ||
456 | if (t > 0) | ||
457 | { | ||
458 | rc += t; | ||
459 | to_receive -= t; | ||
460 | } | ||
461 | else | ||
462 | break; | ||
463 | } | ||
464 | #if VERBOSE | ||
465 | { | ||
466 | unsigned long have; | ||
467 | int ior = ioctlsocket((_win_socket)hLookup, FIONREAD, &have); | ||
468 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: read %d bytes as a header from %p, %lu bytes available\n", rc, hLookup, have); | ||
469 | } | ||
470 | #endif | ||
471 | //EnterCriticalSection (&records_cs); | ||
472 | records[rec].state &= ~8; | ||
473 | if (rc != sizeof(header)) | ||
474 | { | ||
475 | if (records[rec].state & 2) | ||
476 | { | ||
477 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: call cancelled\n"); | ||
478 | SetLastError(WSA_E_CANCELLED); | ||
479 | } | ||
480 | else | ||
481 | { | ||
482 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: failed to receive enough data for a header (rc %d != %u, state is 0x%0X)\n", rc, sizeof(header), records[rec].state); | ||
483 | SetLastError(WSA_E_NO_MORE); | ||
484 | } | ||
485 | records[rec].state |= 4; | ||
486 | //LeaveCriticalSection (&records_cs); | ||
487 | return SOCKET_ERROR; | ||
488 | } | ||
489 | records[rec].state &= ~8; | ||
490 | header.type = ntohs(header.type); | ||
491 | header.size = ntohs(header.size); | ||
492 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: header type %d, header size %u\n", header.type, header.size); | ||
493 | if (header.type != GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE || | ||
494 | (header.type == GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE && | ||
495 | header.size == sizeof(header))) | ||
496 | { | ||
497 | records[rec].state |= 4; | ||
498 | if (header.type != GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE) | ||
499 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: header type is wrong\n"); | ||
500 | else | ||
501 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: empty header - no data\n"); | ||
502 | //LeaveCriticalSection (&records_cs); | ||
503 | SetLastError(WSA_E_NO_MORE); | ||
504 | return SOCKET_ERROR; | ||
505 | } | ||
506 | buf = malloc(header.size); | ||
507 | if (buf == NULL) | ||
508 | { | ||
509 | records[rec].state |= 4; | ||
510 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: malloc() failed\n"); | ||
511 | //LeaveCriticalSection (&records_cs); | ||
512 | SetLastError(WSA_E_NO_MORE); | ||
513 | return SOCKET_ERROR; | ||
514 | } | ||
515 | records[rec].state |= 8; | ||
516 | //LeaveCriticalSection (&records_cs); | ||
517 | GNUNET_memcpy(buf, &header, sizeof(header)); | ||
518 | to_receive = header.size - sizeof(header); | ||
519 | rc = 0; | ||
520 | #if VERBOSE | ||
521 | { | ||
522 | unsigned long have; | ||
523 | int ior = ioctlsocket((_win_socket)hLookup, FIONREAD, &have); | ||
524 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: reading %d bytes as a body from %p, %lu bytes available\n", to_receive, hLookup, have); | ||
525 | } | ||
526 | #endif | ||
527 | while (to_receive > 0) | ||
528 | { | ||
529 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: recv (%d)\n", to_receive); | ||
530 | t = recv((_win_socket)hLookup, &((char *)&((struct GNUNET_MessageHeader *)buf)[1])[rc], to_receive, 0); | ||
531 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: recv returned %d\n", t); | ||
532 | if (t > 0) | ||
533 | { | ||
534 | rc += t; | ||
535 | to_receive -= t; | ||
536 | } | ||
537 | else | ||
538 | break; | ||
539 | } | ||
540 | #if VERBOSE | ||
541 | { | ||
542 | unsigned long have; | ||
543 | int ior = ioctlsocket((_win_socket)hLookup, FIONREAD, &have); | ||
544 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: read %d bytes as a body from %p, %lu bytes available\n", rc, hLookup, have); | ||
545 | } | ||
546 | #endif | ||
547 | //EnterCriticalSection (&records_cs); | ||
548 | records[rec].state &= ~8; | ||
549 | if (rc != header.size - sizeof(header)) | ||
550 | { | ||
551 | free(buf); | ||
552 | if (records[rec].state & 2) | ||
553 | { | ||
554 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: call cancelled\n"); | ||
555 | SetLastError(WSA_E_CANCELLED); | ||
556 | } | ||
557 | else | ||
558 | { | ||
559 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: failed to receive enough data for the rest (rc %d != %d, state is 0x%0X)\n", rc, header.size - sizeof(header), records[rec].state); | ||
560 | SetLastError(WSA_E_NO_MORE); | ||
561 | } | ||
562 | records[rec].state |= 4; | ||
563 | //LeaveCriticalSection (&records_cs); | ||
564 | return SOCKET_ERROR; | ||
565 | } | ||
566 | if (*lpdwBufferLength < header.size - sizeof(struct GNUNET_W32RESOLVER_GetMessage)) | ||
567 | { | ||
568 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n"); | ||
569 | SetLastError(WSAEFAULT); | ||
570 | records[rec].buf = buf; | ||
571 | //LeaveCriticalSection (&records_cs); | ||
572 | return SOCKET_ERROR; | ||
573 | } | ||
574 | //LeaveCriticalSection (&records_cs); | ||
575 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: writing %d bytes into result buffer\n", header.size - sizeof(struct GNUNET_W32RESOLVER_GetMessage)); | ||
576 | GNUNET_memcpy(lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)buf)[1], header.size - sizeof(struct GNUNET_W32RESOLVER_GetMessage)); | ||
577 | free(buf); | ||
578 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: OK\n"); | ||
579 | UnmarshallWSAQUERYSETW((LPWSAQUERYSETW)lpqsResults); | ||
580 | DEBUGLOG("GNUNET_W32NSP_LookupServiceNext: returning (%lu)\n", GetLastError()); | ||
581 | return NO_ERROR; | ||
582 | } | ||
583 | |||
584 | static int WSPAPI | ||
585 | GNUNET_W32NSP_LookupServiceEnd(HANDLE hLookup) | ||
586 | { | ||
587 | int i; | ||
588 | int rec = -1; | ||
589 | |||
590 | DEBUGLOG("GNUNET_W32NSP_LookupServiceEnd\n"); | ||
591 | //EnterCriticalSection (&records_cs); | ||
592 | for (i = 0; i < records_len; i++) | ||
593 | { | ||
594 | if (records[i].s == (_win_socket)hLookup) | ||
595 | { | ||
596 | rec = i; | ||
597 | break; | ||
598 | } | ||
599 | } | ||
600 | if (rec == -1) | ||
601 | { | ||
602 | SetLastError(WSA_INVALID_HANDLE); | ||
603 | //LeaveCriticalSection (&records_cs); | ||
604 | DEBUGLOG("GNUNET_W32NSP_LookupServiceEnd: invalid handle\n"); | ||
605 | return SOCKET_ERROR; | ||
606 | } | ||
607 | records[rec].state |= 2; | ||
608 | closesocket(records[rec].s); | ||
609 | while (records[rec].state & 8) | ||
610 | { | ||
611 | //LeaveCriticalSection (&records_cs); | ||
612 | Sleep(10); | ||
613 | //EnterCriticalSection (&records_cs); | ||
614 | } | ||
615 | if (records[rec].buf) | ||
616 | free(records[rec].buf); | ||
617 | records[rec].buf = NULL; | ||
618 | records[rec].state = 0; | ||
619 | if (records[rec].name) | ||
620 | free(records[rec].name); | ||
621 | //LeaveCriticalSection (&records_cs); | ||
622 | DEBUGLOG("GNUNET_W32NSP_LookupServiceEnd: OK\n"); | ||
623 | return NO_ERROR; | ||
624 | } | ||
625 | |||
626 | static int WSAAPI | ||
627 | GNUNET_W32NSP_SetService(LPGUID lpProviderId, | ||
628 | LPWSASERVICECLASSINFOW lpServiceClassInfo, LPWSAQUERYSETW lpqsRegInfo, | ||
629 | WSAESETSERVICEOP essOperation, DWORD dwControlFlags) | ||
630 | { | ||
631 | DEBUGLOG("GNUNET_W32NSP_SetService\n"); | ||
632 | SetLastError(WSAEOPNOTSUPP); | ||
633 | return SOCKET_ERROR; | ||
634 | } | ||
635 | |||
636 | static int WSAAPI | ||
637 | GNUNET_W32NSP_InstallServiceClass(LPGUID lpProviderId, | ||
638 | LPWSASERVICECLASSINFOW lpServiceClassInfo) | ||
639 | { | ||
640 | DEBUGLOG("GNUNET_W32NSP_InstallServiceClass\n"); | ||
641 | SetLastError(WSAEOPNOTSUPP); | ||
642 | return SOCKET_ERROR; | ||
643 | } | ||
644 | |||
645 | |||
646 | static int WSAAPI | ||
647 | GNUNET_W32NSP_RemoveServiceClass(LPGUID lpProviderId, LPGUID lpServiceClassId) | ||
648 | { | ||
649 | DEBUGLOG("GNUNET_W32NSP_RemoveServiceClass\n"); | ||
650 | SetLastError(WSAEOPNOTSUPP); | ||
651 | return SOCKET_ERROR; | ||
652 | } | ||
653 | |||
654 | static int WSAAPI | ||
655 | GNUNET_W32NSP_GetServiceClassInfo(LPGUID lpProviderId, LPDWORD lpdwBufSize, | ||
656 | LPWSASERVICECLASSINFOW lpServiceClassInfo) | ||
657 | { | ||
658 | DEBUGLOG("GNUNET_W32NSP_GetServiceClassInfo\n"); | ||
659 | SetLastError(WSAEOPNOTSUPP); | ||
660 | return SOCKET_ERROR; | ||
661 | } | ||
662 | |||
663 | static int WSAAPI | ||
664 | GNUNET_W32NSP_Ioctl(HANDLE hLookup, DWORD dwControlCode, LPVOID lpvInBuffer, | ||
665 | DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, | ||
666 | LPDWORD lpcbBytesReturned, LPWSACOMPLETION lpCompletion, | ||
667 | LPWSATHREADID lpThreadId) | ||
668 | { | ||
669 | DEBUGLOG("GNUNET_W32NSP_Ioctl\n"); | ||
670 | SetLastError(WSAEOPNOTSUPP); | ||
671 | return SOCKET_ERROR; | ||
672 | } | ||
673 | |||
674 | /** | ||
675 | * This function is called by Winsock to hook up our provider. | ||
676 | * It is the only function that [should be/is] exported by the | ||
677 | * provider. All other routines are passed as pointers in lpnspRoutines. | ||
678 | */ | ||
679 | int WSAAPI | ||
680 | GNUNET_W32NSP_NSPStartup(LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines) | ||
681 | { | ||
682 | if (IsEqualGUID(lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS)) | ||
683 | { | ||
684 | if (!connect_to_dns_resolver()) | ||
685 | { | ||
686 | return SOCKET_ERROR; | ||
687 | } | ||
688 | /* This assumes that NSP_ROUTINE struct doesn't have a NSPIoctl member. | ||
689 | * If it does, you need to use FIELD_OFFSET() macro to get offset of NSPIoctl | ||
690 | * and use that offset as cbSize. | ||
691 | */ | ||
692 | lpnspRoutines->cbSize = sizeof(NSP_ROUTINE); | ||
693 | |||
694 | lpnspRoutines->dwMajorVersion = NSPAPI_VERSION_MAJOR; | ||
695 | lpnspRoutines->dwMinorVersion = NSPAPI_VERSION_MINOR; | ||
696 | lpnspRoutines->NSPCleanup = NSPCleanup; | ||
697 | lpnspRoutines->NSPLookupServiceBegin = GNUNET_W32NSP_LookupServiceBegin; | ||
698 | lpnspRoutines->NSPLookupServiceNext = GNUNET_W32NSP_LookupServiceNext; | ||
699 | lpnspRoutines->NSPLookupServiceEnd = GNUNET_W32NSP_LookupServiceEnd; | ||
700 | lpnspRoutines->NSPSetService = GNUNET_W32NSP_SetService; | ||
701 | lpnspRoutines->NSPInstallServiceClass = GNUNET_W32NSP_InstallServiceClass; | ||
702 | lpnspRoutines->NSPRemoveServiceClass = GNUNET_W32NSP_RemoveServiceClass; | ||
703 | lpnspRoutines->NSPGetServiceClassInfo = GNUNET_W32NSP_GetServiceClassInfo; | ||
704 | /*((NSP_ROUTINE_XP *) lpnspRoutines)->NSPIoctl = GNUNET_W32NSP_Ioctl;*/ | ||
705 | lpnspRoutines->NSPIoctl = GNUNET_W32NSP_Ioctl; | ||
706 | return NO_ERROR; | ||
707 | } | ||
708 | SetLastError(WSAEINVALIDPROVIDER); | ||
709 | return SOCKET_ERROR; | ||
710 | } | ||
711 | |||
diff --git a/src/gns/w32nsp.def b/src/gns/w32nsp.def deleted file mode 100644 index 6bd28b283..000000000 --- a/src/gns/w32nsp.def +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | EXPORTS | ||
2 | NSPStartup=GNUNET_W32NSP_NSPStartup | ||