diff options
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 | ||