X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fgns%2Fw32nsp.c;h=082319ffef24b88b60030fc8438cf6cd77d69025;hb=4df7069dcd17ac39c786ee6f21455c96e6a6dbf4;hp=6e58353a355be90e24c7a35e4f22456af0314c34;hpb=5e756a09598021c6bb22cdbe1b0ac1011679ec0a;p=oweals%2Fgnunet.git
diff --git a/src/gns/w32nsp.c b/src/gns/w32nsp.c
index 6e58353a3..082319ffe 100644
--- a/src/gns/w32nsp.c
+++ b/src/gns/w32nsp.c
@@ -1,21 +1,19 @@
/*
This file is part of GNUnet.
- (C) 2012 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2012 GNUnet e.V.
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
GNUnet is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
*/
/**
* @file gns/w32nsp.c
@@ -26,20 +24,21 @@
* "Network Programming For Microsoft Windows, 2Nd Edition".
*/
-#define INITGUID
-#include
-#include
-#include
-#include
-#include
-
-#if 1
+#define VERBOSE 0
+#if !VERBOSE
# define DEBUGLOG(s, ...)
#endif
-#if 0
+#if VERBOSE
+# define __printf__ printf
# define DEBUGLOG(s, ...) printf (s, ##__VA_ARGS__)
#endif
+#include
+#include
+#include
+#include
+#include
+
#define WINDOWS 1
#define MINGW 1
#ifndef __BYTE_ORDER
@@ -69,32 +68,15 @@
#endif
#endif
#endif
-#include "gnunet_w32nsp_lib.h"
#include "w32resolver.h"
+#include
+#include "gnunet_w32nsp_lib.h"
+#undef INITGUID
#define NSPAPI_VERSION_MAJOR 4
#define NSPAPI_VERSION_MINOR 4
-#define REPLY_LIFETIME 60*5
-
-#define STATE_BEGIN 0x01
-#define STATE_END 0x02
-#define STATE_REPLY 0x04
-#define STATE_GHBN 0x08
-
-uint64_t
-GNUNET_htonll (uint64_t n)
-{
-#if __BYTE_ORDER == __BIG_ENDIAN
- return n;
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
- return (((uint64_t) htonl (n)) << 32) + htonl (n >> 32);
-#else
- #error byteorder undefined
-#endif
-}
-
-CRITICAL_SECTION records_cs;
+static CRITICAL_SECTION records_cs;
struct record
{
@@ -109,7 +91,7 @@ static struct record *records = NULL;
static size_t records_len = 0;
static size_t records_size = 0;
-int
+static int
resize_records ()
{
size_t new_size = records_len > 0 ? records_len * 2 : 5;
@@ -119,7 +101,7 @@ resize_records ()
SetLastError (WSA_NOT_ENOUGH_MEMORY);
return 0;
}
- memcpy (new_records, records, records_len * sizeof (struct record));
+ GNUNET_memcpy (new_records, records, records_len * sizeof (struct record));
memset (&new_records[records_len], 0, sizeof (struct record) * (new_size - records_len));
records_size = new_size;
free (records);
@@ -127,7 +109,7 @@ resize_records ()
return 1;
}
-int
+static int
add_record (SOCKET s, const wchar_t *name, DWORD flags)
{
int res = 1;
@@ -160,14 +142,6 @@ add_record (SOCKET s, const wchar_t *name, DWORD flags)
return res;
}
-void
-free_record (int i)
-{
- if (records[i].name)
- free (records[i].name);
- records[i].state = 0;
-}
-
/* These are not defined by mingw.org headers at the moment*/
typedef INT (WSPAPI *LPNSPIOCTL) (HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LPDWORD,LPWSACOMPLETION,LPWSATHREADID);
typedef struct _NSP_ROUTINE_XP {
@@ -226,7 +200,6 @@ send_name_to_ip_request (LPWSAQUERYSETW lpqsRestrictions,
char *buf;
int ret = 1;
int i;
- uint32_t id;
size_t size = sizeof (struct GNUNET_W32RESOLVER_GetMessage);
size_t namelen = 0;
if (lpqsRestrictions->lpszServiceInstanceName)
@@ -254,20 +227,20 @@ send_name_to_ip_request (LPWSAQUERYSETW lpqsRestrictions,
else
msg->af = htonl (AF_UNSPEC);
if (lpqsRestrictions->lpszServiceInstanceName)
- memcpy (&msg[1], lpqsRestrictions->lpszServiceInstanceName, namelen);
+ GNUNET_memcpy (&msg[1], lpqsRestrictions->lpszServiceInstanceName, namelen);
msg->sc_data1 = htonl (lpqsRestrictions->lpServiceClassId->Data1);
msg->sc_data2 = htons (lpqsRestrictions->lpServiceClassId->Data2);
msg->sc_data3 = htons (lpqsRestrictions->lpServiceClassId->Data3);
- msg->sc_data4 = 0;
for (i = 0; i < 8; i++)
- msg->sc_data4 |= ((uint64_t) lpqsRestrictions->lpServiceClassId->Data4[i]) << ((7 - i) * 8);
- msg->sc_data4 = GNUNET_htonll (msg->sc_data4);
+ msg->sc_data4[i] = lpqsRestrictions->lpServiceClassId->Data4[i];
*resolver = connect_to_dns_resolver ();
if (*resolver != INVALID_SOCKET)
{
if (size != send (*resolver, buf, size, 0))
{
+#if VERBOSE
DWORD err = GetLastError ();
+#endif
closesocket (*resolver);
*resolver = INVALID_SOCKET;
DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to send request: %lu\n", err);
@@ -281,7 +254,7 @@ send_name_to_ip_request (LPWSAQUERYSETW lpqsRestrictions,
return ret;
}
-int WSPAPI
+static int WSPAPI
NSPCleanup (LPGUID lpProviderId)
{
DEBUGLOG ("NSPCleanup\n");
@@ -318,7 +291,7 @@ DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
-int WSPAPI
+static int WSPAPI
GNUNET_W32NSP_LookupServiceBegin (LPGUID lpProviderId, LPWSAQUERYSETW lpqsRestrictions,
LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags,
LPHANDLE lphLookup)
@@ -330,23 +303,23 @@ GNUNET_W32NSP_LookupServiceBegin (LPGUID lpProviderId, LPWSAQUERYSETW lpqsRestri
if (lpqsRestrictions->dwNameSpace != NS_DNS && lpqsRestrictions->dwNameSpace != NS_ALL)
{
DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong namespace\n");
- SetLastError (WSANO_DATA);
+ SetLastError (WSAEINVAL);
return SOCKET_ERROR;
}
if (lpqsRestrictions->lpszServiceInstanceName != NULL)
{
wchar_t *s = lpqsRestrictions->lpszServiceInstanceName;
size_t len = wcslen (s);
- if (len >= 4 && wcscmp (&s[len - 4], L"zkey") == 0)
+ if (len >= 5 && wcscmp (&s[len - 5], L".zkey") == 0)
{
}
- else if (len >= 4 && wcscmp (&s[len - 4], L"gads") == 0)
+ else if (len >= 4 && wcscmp (&s[len - 4], L".gnu") == 0)
{
}
else
{
DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: unsupported TLD\n");
- SetLastError (WSANO_DATA);
+ SetLastError (WSAEINVAL);
return SOCKET_ERROR;
}
}
@@ -377,7 +350,7 @@ GNUNET_W32NSP_LookupServiceBegin (LPGUID lpProviderId, LPWSAQUERYSETW lpqsRestri
if (ptr) \
ptr = (ptrtype *) (base + (uintptr_t) ptr)
-void
+static void
UnmarshallWSAQUERYSETW (LPWSAQUERYSETW req)
{
int i;
@@ -401,11 +374,11 @@ UnmarshallWSAQUERYSETW (LPWSAQUERYSETW req)
UnmarshallPtr (req->lpBlob->pBlobData, BYTE, base);
}
-int WSAAPI
+static int WSAAPI
GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,
- LPDWORD lpdwBufferLength, LPWSAQUERYSET lpqsResults)
+ LPDWORD lpdwBufferLength, LPWSAQUERYSETW lpqsResults)
{
- DWORD effective_flags;
+ /*DWORD effective_flags;*/
int i;
struct GNUNET_MessageHeader header = {0, 0};
int rec = -1;
@@ -438,37 +411,37 @@ GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,
//LeaveCriticalSection (&records_cs);
return SOCKET_ERROR;
}
- effective_flags = dwControlFlags & records[rec].flags;
+ /*effective_flags = dwControlFlags & records[rec].flags;*/
if (records[rec].buf)
{
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: checking buffer\n");
header = *((struct GNUNET_MessageHeader *) records[rec].buf);
- if (dwControlFlags & LUP_FLUSHCACHE)
- {
- free (records[rec].buf);
- records[rec].buf = NULL;
- }
- else
+ if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))
{
- if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))
- {
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");
- SetLastError (WSAEFAULT);
- //LeaveCriticalSection (&records_cs);
- return SOCKET_ERROR;
- }
- memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)records[rec].buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
- free (records[rec].buf);
- records[rec].buf = NULL;
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");
+ SetLastError (WSAEFAULT);
//LeaveCriticalSection (&records_cs);
- UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK (from buffer)\n");
- return NO_ERROR;
+ return SOCKET_ERROR;
}
+ GNUNET_memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)records[rec].buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
+ free (records[rec].buf);
+ records[rec].buf = NULL;
+ //LeaveCriticalSection (&records_cs);
+ UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK (from buffer)\n");
+ return NO_ERROR;
}
records[rec].state |= 8;
//LeaveCriticalSection (&records_cs);
to_receive = sizeof (header);
rc = 0;
+#if VERBOSE
+ {
+ unsigned long have;
+ int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: reading %d bytes as a header from %p, %lu bytes available\n", to_receive, hLookup, have);
+ }
+#endif
while (to_receive > 0)
{
t = recv ((SOCKET) hLookup, &((char *) &header)[rc], to_receive, 0);
@@ -480,6 +453,13 @@ GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,
else
break;
}
+#if VERBOSE
+ {
+ unsigned long have;
+ int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: read %d bytes as a header from %p, %lu bytes available\n", rc, hLookup, have);
+ }
+#endif
//EnterCriticalSection (&records_cs);
records[rec].state &= ~8;
if (rc != sizeof (header))
@@ -491,7 +471,7 @@ GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,
}
else
{
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: failed to receive enough data\n");
+ 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);
SetLastError (WSA_E_NO_MORE);
}
records[rec].state |= 4;
@@ -501,12 +481,16 @@ GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,
records[rec].state &= ~8;
header.type = ntohs (header.type);
header.size = ntohs (header.size);
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: header type %d, header size %u\n", header.type, header.size);
if (header.type != GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE ||
(header.type == GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE &&
header.size == sizeof (header)))
{
records[rec].state |= 4;
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: header is wrong or type is wrong or no data\n");
+ if (header.type != GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE)
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: header type is wrong\n");
+ else
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: empty header - no data\n");
//LeaveCriticalSection (&records_cs);
SetLastError (WSA_E_NO_MORE);
return SOCKET_ERROR;
@@ -522,12 +506,21 @@ GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,
}
records[rec].state |= 8;
//LeaveCriticalSection (&records_cs);
- memcpy (buf, &header, sizeof (header));
+ GNUNET_memcpy (buf, &header, sizeof (header));
to_receive = header.size - sizeof (header);
rc = 0;
+#if VERBOSE
+ {
+ unsigned long have;
+ int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: reading %d bytes as a body from %p, %lu bytes available\n", to_receive, hLookup, have);
+ }
+#endif
while (to_receive > 0)
{
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: recv (%d)\n", to_receive);
t = recv ((SOCKET) hLookup, &((char *) &((struct GNUNET_MessageHeader *) buf)[1])[rc], to_receive, 0);
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: recv returned %d\n", t);
if (t > 0)
{
rc += t;
@@ -536,6 +529,13 @@ GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,
else
break;
}
+#if VERBOSE
+ {
+ unsigned long have;
+ int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: read %d bytes as a body from %p, %lu bytes available\n", rc, hLookup, have);
+ }
+#endif
//EnterCriticalSection (&records_cs);
records[rec].state &= ~8;
if (rc != header.size - sizeof (header))
@@ -548,7 +548,7 @@ GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,
}
else
{
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: failed to receive enough data\n");
+ 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);
SetLastError (WSA_E_NO_MORE);
}
records[rec].state |= 4;
@@ -564,7 +564,8 @@ GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,
return SOCKET_ERROR;
}
//LeaveCriticalSection (&records_cs);
- memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: writing %d bytes into result buffer\n", header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
+ GNUNET_memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
free (buf);
DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK\n");
UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);
@@ -572,15 +573,11 @@ GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,
return NO_ERROR;
}
-int WSPAPI
+static int WSPAPI
GNUNET_W32NSP_LookupServiceEnd (HANDLE hLookup)
{
- DWORD effective_flags;
int i;
- struct GNUNET_MessageHeader header = {0, 0};
int rec = -1;
- int rc;
- char *buf;
DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd\n");
//EnterCriticalSection (&records_cs);
@@ -618,7 +615,7 @@ GNUNET_W32NSP_LookupServiceEnd (HANDLE hLookup)
return NO_ERROR;
}
-int WSAAPI
+static int WSAAPI
GNUNET_W32NSP_SetService (LPGUID lpProviderId,
LPWSASERVICECLASSINFOW lpServiceClassInfo, LPWSAQUERYSETW lpqsRegInfo,
WSAESETSERVICEOP essOperation, DWORD dwControlFlags)
@@ -628,7 +625,7 @@ GNUNET_W32NSP_SetService (LPGUID lpProviderId,
return SOCKET_ERROR;
}
-int WSAAPI
+static int WSAAPI
GNUNET_W32NSP_InstallServiceClass (LPGUID lpProviderId,
LPWSASERVICECLASSINFOW lpServiceClassInfo)
{
@@ -638,7 +635,7 @@ GNUNET_W32NSP_InstallServiceClass (LPGUID lpProviderId,
}
-int WSAAPI
+static int WSAAPI
GNUNET_W32NSP_RemoveServiceClass (LPGUID lpProviderId, LPGUID lpServiceClassId)
{
DEBUGLOG ("GNUNET_W32NSP_RemoveServiceClass\n");
@@ -646,7 +643,7 @@ GNUNET_W32NSP_RemoveServiceClass (LPGUID lpProviderId, LPGUID lpServiceClassId)
return SOCKET_ERROR;
}
-int WSAAPI
+static int WSAAPI
GNUNET_W32NSP_GetServiceClassInfo (LPGUID lpProviderId, LPDWORD lpdwBufSize,
LPWSASERVICECLASSINFOW lpServiceClassInfo)
{
@@ -655,7 +652,7 @@ GNUNET_W32NSP_GetServiceClassInfo (LPGUID lpProviderId, LPDWORD lpdwBufSize,
return SOCKET_ERROR;
}
-int WSAAPI
+static int WSAAPI
GNUNET_W32NSP_Ioctl (HANDLE hLookup, DWORD dwControlCode, LPVOID lpvInBuffer,
DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer,
LPDWORD lpcbBytesReturned, LPWSACOMPLETION lpCompletion,
@@ -671,8 +668,8 @@ GNUNET_W32NSP_Ioctl (HANDLE hLookup, DWORD dwControlCode, LPVOID lpvInBuffer,
* It is the only function that [should be/is] exported by the
* provider. All other routines are passed as pointers in lpnspRoutines.
*/
-int WSPAPI
-NSPStartup (LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines)
+int WSAAPI
+GNUNET_W32NSP_NSPStartup (LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines)
{
if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
{
@@ -684,7 +681,7 @@ NSPStartup (LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines)
* If it does, you need to use FIELD_OFFSET() macro to get offset of NSPIoctl
* and use that offset as cbSize.
*/
- lpnspRoutines->cbSize = sizeof(NSP_ROUTINE_XP);
+ lpnspRoutines->cbSize = sizeof(NSP_ROUTINE);
lpnspRoutines->dwMajorVersion = NSPAPI_VERSION_MAJOR;
lpnspRoutines->dwMinorVersion = NSPAPI_VERSION_MINOR;
@@ -696,7 +693,8 @@ NSPStartup (LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines)
lpnspRoutines->NSPInstallServiceClass = GNUNET_W32NSP_InstallServiceClass;
lpnspRoutines->NSPRemoveServiceClass = GNUNET_W32NSP_RemoveServiceClass;
lpnspRoutines->NSPGetServiceClassInfo = GNUNET_W32NSP_GetServiceClassInfo;
- ((NSP_ROUTINE_XP *) lpnspRoutines)->NSPIoctl = GNUNET_W32NSP_Ioctl;
+ /*((NSP_ROUTINE_XP *) lpnspRoutines)->NSPIoctl = GNUNET_W32NSP_Ioctl;*/
+ lpnspRoutines->NSPIoctl = GNUNET_W32NSP_Ioctl;
return NO_ERROR;
}
SetLastError (WSAEINVALIDPROVIDER);