/*
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
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.
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
*/
/**
* @file gns/w32nsp.c
* "Network Programming For Microsoft Windows, 2Nd Edition".
*/
+#define VERBOSE 0
+#if !VERBOSE
+# define DEBUGLOG(s, ...)
+#endif
+#if VERBOSE
+# define __printf__ printf
+# define DEBUGLOG(s, ...) printf (s, ##__VA_ARGS__)
+#endif
+
#include <stdint.h>
#include <ws2tcpip.h>
#include <ws2spi.h>
#include <windows.h>
#include <nspapi.h>
-#if 1
-# define DEBUGLOG(s, ...)
-#endif
-#if 0
-# define DEBUGLOG(s, ...) printf (s, ##__VA_ARGS__)
-#endif
-
#define WINDOWS 1
#define MINGW 1
#ifndef __BYTE_ORDER
#endif
#endif
#include "w32resolver.h"
-#define INITGUID
+#include <initguid.h>
#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
-
static CRITICAL_SECTION records_cs;
struct record
return res;
}
-static 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 {
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)
{
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);
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)
else
{
DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: unsupported TLD\n");
- SetLastError (WSANO_DATA);
+ SetLastError (WSAEINVAL);
return SOCKET_ERROR;
}
}
GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,
LPDWORD lpdwBufferLength, LPWSAQUERYSETW lpqsResults)
{
- DWORD effective_flags;
+ /*DWORD effective_flags;*/
int i;
struct GNUNET_MessageHeader header = {0, 0};
int rec = -1;
//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)
+ if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))
{
- free (records[rec].buf);
- records[rec].buf = NULL;
- }
- else
- {
- 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;
}
+ 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);
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))
}
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;
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;
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;
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))
}
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;
return SOCKET_ERROR;
}
//LeaveCriticalSection (&records_cs);
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: writing %d bytes into result buffer\n", header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
free (buf);
DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK\n");
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);