GNUnet  0.10.x
Data Structures | Macros | Typedefs | Functions | Variables
w32nsp.c File Reference

W32 integration for GNS. More...

#include <stdint.h>
#include <ws2tcpip.h>
#include <ws2spi.h>
#include <windows.h>
#include <nspapi.h>
#include "w32resolver.h"
#include <initguid.h>
#include "gnunet_w32nsp_lib.h"
Include dependency graph for w32nsp.c:

Go to the source code of this file.

Data Structures

struct  record
 
struct  _NSP_ROUTINE_XP
 

Macros

#define VERBOSE   0
 
#define DEBUGLOG(s, ...)
 
#define WINDOWS   1
 
#define MINGW   1
 
#define NSPAPI_VERSION_MAJOR   4
 
#define NSPAPI_VERSION_MINOR   4
 
#define UnmarshallPtr(ptr, ptrtype, base)
 

Typedefs

typedef INT(WSPAPI * LPNSPIOCTL) (HANDLE, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPWSACOMPLETION, LPWSATHREADID)
 
typedef struct _NSP_ROUTINE_XP NSP_ROUTINE_XP
 

Functions

static int resize_records ()
 
static int add_record (SOCKET s, const wchar_t *name, DWORD flags)
 
static SOCKET connect_to_dns_resolver ()
 
static int send_name_to_ip_request (LPWSAQUERYSETW lpqsRestrictions, LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags, SOCKET *resolver)
 
static int WSPAPI NSPCleanup (LPGUID lpProviderId)
 
BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
 
static int WSPAPI GNUNET_W32NSP_LookupServiceBegin (LPGUID lpProviderId, LPWSAQUERYSETW lpqsRestrictions, LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags, LPHANDLE lphLookup)
 
static void UnmarshallWSAQUERYSETW (LPWSAQUERYSETW req)
 
static int WSAAPI GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags, LPDWORD lpdwBufferLength, LPWSAQUERYSETW lpqsResults)
 
static int WSPAPI GNUNET_W32NSP_LookupServiceEnd (HANDLE hLookup)
 
static int WSAAPI GNUNET_W32NSP_SetService (LPGUID lpProviderId, LPWSASERVICECLASSINFOW lpServiceClassInfo, LPWSAQUERYSETW lpqsRegInfo, WSAESETSERVICEOP essOperation, DWORD dwControlFlags)
 
static int WSAAPI GNUNET_W32NSP_InstallServiceClass (LPGUID lpProviderId, LPWSASERVICECLASSINFOW lpServiceClassInfo)
 
static int WSAAPI GNUNET_W32NSP_RemoveServiceClass (LPGUID lpProviderId, LPGUID lpServiceClassId)
 
static int WSAAPI GNUNET_W32NSP_GetServiceClassInfo (LPGUID lpProviderId, LPDWORD lpdwBufSize, LPWSASERVICECLASSINFOW lpServiceClassInfo)
 
static int WSAAPI GNUNET_W32NSP_Ioctl (HANDLE hLookup, DWORD dwControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned, LPWSACOMPLETION lpCompletion, LPWSATHREADID lpThreadId)
 
int WSAAPI GNUNET_W32NSP_NSPStartup (LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines)
 This function is called by Winsock to hook up our provider. More...
 

Variables

static CRITICAL_SECTION records_cs
 
static struct recordrecords = NULL
 
static size_t records_len = 0
 
static size_t records_size = 0
 

Detailed Description

W32 integration for GNS.

Author
LRN

Definition in file w32nsp.c.

Macro Definition Documentation

◆ VERBOSE

#define VERBOSE   0

Definition at line 29 of file w32nsp.c.

◆ DEBUGLOG

#define DEBUGLOG (   s,
  ... 
)

◆ WINDOWS

#define WINDOWS   1

Definition at line 44 of file w32nsp.c.

Referenced by mktemp_name().

◆ MINGW

#define MINGW   1

Definition at line 45 of file w32nsp.c.

◆ NSPAPI_VERSION_MAJOR

#define NSPAPI_VERSION_MAJOR   4

Definition at line 78 of file w32nsp.c.

Referenced by GNUNET_W32NSP_NSPStartup().

◆ NSPAPI_VERSION_MINOR

#define NSPAPI_VERSION_MINOR   4

Definition at line 79 of file w32nsp.c.

Referenced by GNUNET_W32NSP_NSPStartup().

◆ UnmarshallPtr

#define UnmarshallPtr (   ptr,
  ptrtype,
  base 
)
Value:
if (ptr) \
ptr = (ptrtype *) (base + (uintptr_t) ptr)

Definition at line 351 of file w32nsp.c.

Referenced by UnmarshallWSAQUERYSETW().

Typedef Documentation

◆ LPNSPIOCTL

typedef INT(WSPAPI * LPNSPIOCTL) (HANDLE, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPWSACOMPLETION, LPWSATHREADID)

Definition at line 148 of file w32nsp.c.

◆ NSP_ROUTINE_XP

Function Documentation

◆ resize_records()

static int resize_records ( )
static

Definition at line 97 of file w32nsp.c.

References GNUNET_memcpy, records_len, and records_size.

Referenced by add_record().

98 {
99  size_t new_size = records_len > 0 ? records_len * 2 : 5;
100  struct record *new_records = malloc (new_size * sizeof (struct record));
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 }
static struct record * records
Definition: w32nsp.c:92
Definition: w32nsp.c:83
#define GNUNET_memcpy(dst, src, n)
static size_t records_len
Definition: w32nsp.c:93
static size_t records_size
Definition: w32nsp.c:94
Here is the caller graph for this function:

◆ add_record()

static int add_record ( SOCKET  s,
const wchar_t *  name,
DWORD  flags 
)
static

Definition at line 115 of file w32nsp.c.

References record::buf, record::flags, record::name, records_len, res, resize_records(), record::s, and record::state.

Referenced by GNUNET_W32NSP_LookupServiceBegin().

116 {
117  int res = 1;
118  int i;
119  int empty = -1;
120  //EnterCriticalSection (&records_cs);
121  for (i = 0; i < records_len; i++)
122  if (records[i].state == 0)
123  break;
124  empty = i;
125  if (i == records_len)
126  {
127  res = resize_records ();
128  if (res)
129  empty = records_len++;
130  }
131  if (res)
132  {
133  struct record r;
134  r.s = s;
135  r.flags = flags;
136  r.name = (wchar_t *) name;
137  r.state = 1;
138  r.buf = NULL;
139  if (name)
140  r.name = wcsdup (name);
141  records[empty] = r;
142  }
143  //LeaveCriticalSection (&records_cs);
144  return res;
145 }
static struct record * records
Definition: w32nsp.c:92
DWORD flags
Definition: w32nsp.c:86
Definition: w32nsp.c:83
SOCKET s
Definition: w32nsp.c:85
enum State state
current state of profiling
static int resize_records()
Definition: w32nsp.c:97
static int res
const char * name
static size_t records_len
Definition: w32nsp.c:93
Here is the call graph for this function:
Here is the caller graph for this function:

◆ connect_to_dns_resolver()

static SOCKET connect_to_dns_resolver ( )
static

Definition at line 165 of file w32nsp.c.

References INVALID_SOCKET, ret, and SOCKET.

Referenced by GNUNET_W32NSP_NSPStartup(), and send_name_to_ip_request().

166 {
167  struct sockaddr_in addr;
168  SOCKET r;
169  int ret;
170 
171  r = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
172  if (INVALID_SOCKET == r)
173  {
174  SetLastError (16004);
175  return r;
176  }
177 
178  addr.sin_family = AF_INET;
179  addr.sin_port = htons (5353); /* TCP 5353 is not registered; UDP 5353 is */
180  addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
181 
182  ret = connect (r, (struct sockaddr *) &addr, sizeof (addr));
183  if (SOCKET_ERROR == ret)
184  {
185  DWORD err = GetLastError ();
186  closesocket (r);
187  SetLastError (err);
188  SetLastError (16005);
189  r = INVALID_SOCKET;
190  }
191  return r;
192 }
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define INVALID_SOCKET
Definition: network.c:39
#define SOCKET(a, t, p)
Definition: plibc.h:711
Here is the caller graph for this function:

◆ send_name_to_ip_request()

static int send_name_to_ip_request ( LPWSAQUERYSETW  lpqsRestrictions,
LPWSASERVICECLASSINFOW  lpServiceClassInfo,
DWORD  dwControlFlags,
SOCKET resolver 
)
static

Definition at line 195 of file w32nsp.c.

References GNUNET_W32RESOLVER_GetMessage::af, record::buf, connect_to_dns_resolver(), DEBUGLOG, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST, GNUNET_W32RESOLVER_GetMessage::header, INVALID_SOCKET, msg, ret, GNUNET_W32RESOLVER_GetMessage::sc_data1, GNUNET_W32RESOLVER_GetMessage::sc_data2, GNUNET_W32RESOLVER_GetMessage::sc_data3, GNUNET_W32RESOLVER_GetMessage::sc_data4, size, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by GNUNET_W32NSP_LookupServiceBegin().

198 {
200  int af4 = 0;
201  int af6 = 0;
202  char *buf;
203  int ret = 1;
204  int i;
205  size_t size = sizeof (struct GNUNET_W32RESOLVER_GetMessage);
206  size_t namelen = 0;
207  if (lpqsRestrictions->lpszServiceInstanceName)
208  namelen = sizeof (wchar_t) * (wcslen (lpqsRestrictions->lpszServiceInstanceName) + 1);
209  size += namelen;
210  buf = malloc (size);
211  msg = (struct GNUNET_W32RESOLVER_GetMessage *) buf;
212  msg->header.size = htons (size);
214  if (lpqsRestrictions->dwNumberOfProtocols > 0)
215  {
216  int i;
217  for (i = 0; i < lpqsRestrictions->dwNumberOfProtocols; i++)
218  {
219  if (lpqsRestrictions->lpafpProtocols[0].iAddressFamily == AF_INET)
220  af4 = 1;
221  if (lpqsRestrictions->lpafpProtocols[0].iAddressFamily == AF_INET6)
222  af6 = 1;
223  }
224  }
225  if (af4 && !af6)
226  msg->af = htonl (AF_INET);
227  else if (af6 && !af4)
228  msg->af = htonl (AF_INET6);
229  else
230  msg->af = htonl (AF_UNSPEC);
231  if (lpqsRestrictions->lpszServiceInstanceName)
232  GNUNET_memcpy (&msg[1], lpqsRestrictions->lpszServiceInstanceName, namelen);
233  msg->sc_data1 = htonl (lpqsRestrictions->lpServiceClassId->Data1);
234  msg->sc_data2 = htons (lpqsRestrictions->lpServiceClassId->Data2);
235  msg->sc_data3 = htons (lpqsRestrictions->lpServiceClassId->Data3);
236  for (i = 0; i < 8; i++)
237  msg->sc_data4[i] = lpqsRestrictions->lpServiceClassId->Data4[i];
239  if (*resolver != INVALID_SOCKET)
240  {
241  if (size != send (*resolver, buf, size, 0))
242  {
243 #if VERBOSE
244  DWORD err = GetLastError ();
245 #endif
246  closesocket (*resolver);
248  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to send request: %lu\n", err);
249  SetLastError (WSATRY_AGAIN);
250  ret = 0;
251  }
252  }
253  else
254  ret = 0;
255  free (buf);
256  return ret;
257 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_OS_Process * resolver
Resolver process handle.
static SOCKET connect_to_dns_resolver()
Definition: w32nsp.c:165
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static int ret
Final status code.
Definition: gnunet-arm.c:89
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_memcpy(dst, src, n)
#define DEBUGLOG(s,...)
Definition: w32nsp.c:31
#define INVALID_SOCKET
Definition: network.c:39
Request for the resolver.
Definition: w32resolver.h:53
static char buf[2048]
#define GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST
Request DNS resolution.
Definition: w32resolver.h:35
static unsigned int size
Size of the "table".
Definition: peer.c:67
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST.
Definition: w32resolver.h:58
Here is the call graph for this function:
Here is the caller graph for this function:

◆ NSPCleanup()

static int WSPAPI NSPCleanup ( LPGUID  lpProviderId)
static

Definition at line 260 of file w32nsp.c.

References DEBUGLOG.

Referenced by GNUNET_W32NSP_NSPStartup().

261 {
262  DEBUGLOG ("NSPCleanup\n");
263  if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
264  {
265  return NO_ERROR;
266  }
267  SetLastError (WSAEINVALIDPROVIDER);
268  return SOCKET_ERROR;
269 }
#define DEBUGLOG(s,...)
Definition: w32nsp.c:31
Here is the caller graph for this function:

◆ DllMain()

BOOL WINAPI DllMain ( HINSTANCE  hinstDLL,
DWORD  fdwReason,
LPVOID  lpvReserved 
)

Definition at line 272 of file w32nsp.c.

References records_cs.

Referenced by GNUNET_OS_init().

273 {
274  switch (fdwReason)
275  {
276  case DLL_PROCESS_ATTACH:
277  if (!InitializeCriticalSectionAndSpinCount (&records_cs, 0x00000400))
278  {
279  return FALSE;
280  }
281  break;
282  case DLL_THREAD_ATTACH:
283  break;
284  case DLL_THREAD_DETACH:
285  break;
286  case DLL_PROCESS_DETACH:
287  DeleteCriticalSection (&records_cs);
288  break;
289  }
290  return TRUE;
291 }
static CRITICAL_SECTION records_cs
Definition: w32nsp.c:81
Here is the caller graph for this function:

◆ GNUNET_W32NSP_LookupServiceBegin()

static int WSPAPI GNUNET_W32NSP_LookupServiceBegin ( LPGUID  lpProviderId,
LPWSAQUERYSETW  lpqsRestrictions,
LPWSASERVICECLASSINFOW  lpServiceClassInfo,
DWORD  dwControlFlags,
LPHANDLE  lphLookup 
)
static

Definition at line 297 of file w32nsp.c.

References add_record(), DEBUGLOG, len, record::s, send_name_to_ip_request(), and SOCKET.

Referenced by GNUNET_W32NSP_NSPStartup().

300 {
301  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin\n");
302  if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
303  {
304  SOCKET s;
305  if (lpqsRestrictions->dwNameSpace != NS_DNS && lpqsRestrictions->dwNameSpace != NS_ALL)
306  {
307  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong namespace\n");
308  SetLastError (WSAEINVAL);
309  return SOCKET_ERROR;
310  }
311  if (lpqsRestrictions->lpszServiceInstanceName != NULL)
312  {
313  wchar_t *s = lpqsRestrictions->lpszServiceInstanceName;
314  size_t len = wcslen (s);
315  if (len >= 5 && wcscmp (&s[len - 5], L".zkey") == 0)
316  {
317  }
318  else if (len >= 4 && wcscmp (&s[len - 4], L".gnu") == 0)
319  {
320  }
321  else
322  {
323  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: unsupported TLD\n");
324  SetLastError (WSAEINVAL);
325  return SOCKET_ERROR;
326  }
327  }
328 
329  if (send_name_to_ip_request (lpqsRestrictions,
330  lpServiceClassInfo, dwControlFlags, &s))
331  {
332  if (!(add_record (s, lpqsRestrictions->lpszServiceInstanceName, dwControlFlags)))
333  {
334  DWORD err = GetLastError ();
335  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to add a record\n");
336  closesocket (s);
337  SetLastError (err);
338  return SOCKET_ERROR;
339  }
340  *lphLookup = (HANDLE) s;
341  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: OK (%lu)\n", GetLastError ());
342  return NO_ERROR;
343  }
344  return SOCKET_ERROR;
345  }
346  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong provider\n");
347  SetLastError (WSAEINVALIDPROVIDER);
348  return SOCKET_ERROR;
349 }
#define DEBUGLOG(s,...)
Definition: w32nsp.c:31
#define SOCKET(a, t, p)
Definition: plibc.h:711
static int send_name_to_ip_request(LPWSAQUERYSETW lpqsRestrictions, LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags, SOCKET *resolver)
Definition: w32nsp.c:195
static int add_record(SOCKET s, const wchar_t *name, DWORD flags)
Definition: w32nsp.c:115
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ UnmarshallWSAQUERYSETW()

static void UnmarshallWSAQUERYSETW ( LPWSAQUERYSETW  req)
static

Definition at line 356 of file w32nsp.c.

References UnmarshallPtr.

Referenced by GNUNET_W32NSP_LookupServiceNext().

357 {
358  int i;
359  char *base = (char *) req;
360  UnmarshallPtr (req->lpszServiceInstanceName, wchar_t, base);
361  UnmarshallPtr (req->lpServiceClassId, GUID, base);
362  UnmarshallPtr (req->lpVersion, WSAVERSION, base);
363  UnmarshallPtr (req->lpszComment, wchar_t, base);
364  UnmarshallPtr (req->lpNSProviderId, GUID, base);
365  UnmarshallPtr (req->lpszContext, wchar_t, base);
366  UnmarshallPtr (req->lpafpProtocols, AFPROTOCOLS, base);
367  UnmarshallPtr (req->lpszQueryString, wchar_t, base);
368  UnmarshallPtr (req->lpcsaBuffer, CSADDR_INFO, base);
369  for (i = 0; i < req->dwNumberOfCsAddrs; i++)
370  {
371  UnmarshallPtr (req->lpcsaBuffer[i].LocalAddr.lpSockaddr, SOCKADDR, base);
372  UnmarshallPtr (req->lpcsaBuffer[i].RemoteAddr.lpSockaddr, SOCKADDR, base);
373  }
374  UnmarshallPtr (req->lpBlob, BLOB, base);
375  if (req->lpBlob)
376  UnmarshallPtr (req->lpBlob->pBlobData, BYTE, base);
377 }
#define UnmarshallPtr(ptr, ptrtype, base)
Definition: w32nsp.c:351
Here is the caller graph for this function:

◆ GNUNET_W32NSP_LookupServiceNext()

static int WSAAPI GNUNET_W32NSP_LookupServiceNext ( HANDLE  hLookup,
DWORD  dwControlFlags,
LPDWORD  lpdwBufferLength,
LPWSAQUERYSETW  lpqsResults 
)
static

Definition at line 380 of file w32nsp.c.

References record::buf, DEBUGLOG, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE, records_len, record::s, GNUNET_MessageHeader::size, SOCKET, record::state, t, GNUNET_MessageHeader::type, and UnmarshallWSAQUERYSETW().

Referenced by GNUNET_W32NSP_NSPStartup().

382 {
383  /*DWORD effective_flags;*/
384  int i;
385  struct GNUNET_MessageHeader header = {0, 0};
386  int rec = -1;
387  int rc;
388  int to_receive;
389  int t;
390  char *buf;
391 
392  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext\n");
393  //EnterCriticalSection (&records_cs);
394  for (i = 0; i < records_len; i++)
395  {
396  if (records[i].s == (SOCKET) hLookup)
397  {
398  rec = i;
399  break;
400  }
401  }
402  if (rec == -1)
403  {
404  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: invalid handle\n");
405  SetLastError (WSA_INVALID_HANDLE);
406  //LeaveCriticalSection (&records_cs);
407  return SOCKET_ERROR;
408  }
409  if (records[rec].state & 4)
410  {
411  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: session is closed\n");
412  SetLastError (WSA_E_NO_MORE);
413  //LeaveCriticalSection (&records_cs);
414  return SOCKET_ERROR;
415  }
416  /*effective_flags = dwControlFlags & records[rec].flags;*/
417  if (records[rec].buf)
418  {
419  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: checking buffer\n");
420  header = *((struct GNUNET_MessageHeader *) records[rec].buf);
421  if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))
422  {
423  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");
424  SetLastError (WSAEFAULT);
425  //LeaveCriticalSection (&records_cs);
426  return SOCKET_ERROR;
427  }
428  GNUNET_memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)records[rec].buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
429  free (records[rec].buf);
430  records[rec].buf = NULL;
431  //LeaveCriticalSection (&records_cs);
432  UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);
433  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK (from buffer)\n");
434  return NO_ERROR;
435  }
436  records[rec].state |= 8;
437  //LeaveCriticalSection (&records_cs);
438  to_receive = sizeof (header);
439  rc = 0;
440 #if VERBOSE
441  {
442  unsigned long have;
443  int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
444  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: reading %d bytes as a header from %p, %lu bytes available\n", to_receive, hLookup, have);
445  }
446 #endif
447  while (to_receive > 0)
448  {
449  t = recv ((SOCKET) hLookup, &((char *) &header)[rc], to_receive, 0);
450  if (t > 0)
451  {
452  rc += t;
453  to_receive -= t;
454  }
455  else
456  break;
457  }
458 #if VERBOSE
459  {
460  unsigned long have;
461  int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
462  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: read %d bytes as a header from %p, %lu bytes available\n", rc, hLookup, have);
463  }
464 #endif
465  //EnterCriticalSection (&records_cs);
466  records[rec].state &= ~8;
467  if (rc != sizeof (header))
468  {
469  if (records[rec].state & 2)
470  {
471  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: call cancelled\n");
472  SetLastError (WSA_E_CANCELLED);
473  }
474  else
475  {
476  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);
477  SetLastError (WSA_E_NO_MORE);
478  }
479  records[rec].state |= 4;
480  //LeaveCriticalSection (&records_cs);
481  return SOCKET_ERROR;
482  }
483  records[rec].state &= ~8;
484  header.type = ntohs (header.type);
485  header.size = ntohs (header.size);
486  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: header type %d, header size %u\n", header.type, header.size);
489  header.size == sizeof (header)))
490  {
491  records[rec].state |= 4;
493  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: header type is wrong\n");
494  else
495  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: empty header - no data\n");
496  //LeaveCriticalSection (&records_cs);
497  SetLastError (WSA_E_NO_MORE);
498  return SOCKET_ERROR;
499  }
500  buf = malloc (header.size);
501  if (buf == NULL)
502  {
503  records[rec].state |= 4;
504  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: malloc() failed\n");
505  //LeaveCriticalSection (&records_cs);
506  SetLastError (WSA_E_NO_MORE);
507  return SOCKET_ERROR;
508  }
509  records[rec].state |= 8;
510  //LeaveCriticalSection (&records_cs);
511  GNUNET_memcpy (buf, &header, sizeof (header));
512  to_receive = header.size - sizeof (header);
513  rc = 0;
514 #if VERBOSE
515  {
516  unsigned long have;
517  int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
518  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: reading %d bytes as a body from %p, %lu bytes available\n", to_receive, hLookup, have);
519  }
520 #endif
521  while (to_receive > 0)
522  {
523  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: recv (%d)\n", to_receive);
524  t = recv ((SOCKET) hLookup, &((char *) &((struct GNUNET_MessageHeader *) buf)[1])[rc], to_receive, 0);
525  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: recv returned %d\n", t);
526  if (t > 0)
527  {
528  rc += t;
529  to_receive -= t;
530  }
531  else
532  break;
533  }
534 #if VERBOSE
535  {
536  unsigned long have;
537  int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
538  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: read %d bytes as a body from %p, %lu bytes available\n", rc, hLookup, have);
539  }
540 #endif
541  //EnterCriticalSection (&records_cs);
542  records[rec].state &= ~8;
543  if (rc != header.size - sizeof (header))
544  {
545  free (buf);
546  if (records[rec].state & 2)
547  {
548  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: call cancelled\n");
549  SetLastError (WSA_E_CANCELLED);
550  }
551  else
552  {
553  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);
554  SetLastError (WSA_E_NO_MORE);
555  }
556  records[rec].state |= 4;
557  //LeaveCriticalSection (&records_cs);
558  return SOCKET_ERROR;
559  }
560  if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))
561  {
562  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");
563  SetLastError (WSAEFAULT);
564  records[rec].buf = buf;
565  //LeaveCriticalSection (&records_cs);
566  return SOCKET_ERROR;
567  }
568  //LeaveCriticalSection (&records_cs);
569  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: writing %d bytes into result buffer\n", header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
570  GNUNET_memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
571  free (buf);
572  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK\n");
573  UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);
574  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: returning (%lu)\n", GetLastError ());
575  return NO_ERROR;
576 }
static struct record * records
Definition: w32nsp.c:92
static struct GNUNET_SCHEDULER_Task * t
Main task.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static void UnmarshallWSAQUERYSETW(LPWSAQUERYSETW req)
Definition: w32nsp.c:356
char * buf
Definition: w32nsp.c:88
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
enum State state
current state of profiling
#define GNUNET_memcpy(dst, src, n)
#define DEBUGLOG(s,...)
Definition: w32nsp.c:31
#define SOCKET(a, t, p)
Definition: plibc.h:711
Request for the resolver.
Definition: w32resolver.h:53
static char buf[2048]
uint8_t state
Definition: w32nsp.c:87
static size_t records_len
Definition: w32nsp.c:93
Header for all communications.
#define GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE
Response to a DNS resolution request.
Definition: w32resolver.h:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_W32NSP_LookupServiceEnd()

static int WSPAPI GNUNET_W32NSP_LookupServiceEnd ( HANDLE  hLookup)
static

Definition at line 579 of file w32nsp.c.

References record::buf, DEBUGLOG, record::name, records_len, record::s, SOCKET, and record::state.

Referenced by GNUNET_W32NSP_NSPStartup().

580 {
581  int i;
582  int rec = -1;
583 
584  DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd\n");
585  //EnterCriticalSection (&records_cs);
586  for (i = 0; i < records_len; i++)
587  {
588  if (records[i].s == (SOCKET) hLookup)
589  {
590  rec = i;
591  break;
592  }
593  }
594  if (rec == -1)
595  {
596  SetLastError (WSA_INVALID_HANDLE);
597  //LeaveCriticalSection (&records_cs);
598  DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd: invalid handle\n");
599  return SOCKET_ERROR;
600  }
601  records[rec].state |= 2;
602  closesocket (records[rec].s);
603  while (records[rec].state & 8)
604  {
605  //LeaveCriticalSection (&records_cs);
606  Sleep (10);
607  //EnterCriticalSection (&records_cs);
608  }
609  if (records[rec].buf)
610  free (records[rec].buf);
611  records[rec].buf = NULL;
612  records[rec].state = 0;
613  if (records[rec].name)
614  free (records[rec].name);
615  //LeaveCriticalSection (&records_cs);
616  DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd: OK\n");
617  return NO_ERROR;
618 }
static struct record * records
Definition: w32nsp.c:92
char * buf
Definition: w32nsp.c:88
enum State state
current state of profiling
#define DEBUGLOG(s,...)
Definition: w32nsp.c:31
#define SOCKET(a, t, p)
Definition: plibc.h:711
static char buf[2048]
uint8_t state
Definition: w32nsp.c:87
const char * name
static size_t records_len
Definition: w32nsp.c:93
Here is the caller graph for this function:

◆ GNUNET_W32NSP_SetService()

static int WSAAPI GNUNET_W32NSP_SetService ( LPGUID  lpProviderId,
LPWSASERVICECLASSINFOW  lpServiceClassInfo,
LPWSAQUERYSETW  lpqsRegInfo,
WSAESETSERVICEOP  essOperation,
DWORD  dwControlFlags 
)
static

Definition at line 621 of file w32nsp.c.

References DEBUGLOG.

Referenced by GNUNET_W32NSP_NSPStartup().

624 {
625  DEBUGLOG ("GNUNET_W32NSP_SetService\n");
626  SetLastError (WSAEOPNOTSUPP);
627  return SOCKET_ERROR;
628 }
#define DEBUGLOG(s,...)
Definition: w32nsp.c:31
Here is the caller graph for this function:

◆ GNUNET_W32NSP_InstallServiceClass()

static int WSAAPI GNUNET_W32NSP_InstallServiceClass ( LPGUID  lpProviderId,
LPWSASERVICECLASSINFOW  lpServiceClassInfo 
)
static

Definition at line 631 of file w32nsp.c.

References DEBUGLOG.

Referenced by GNUNET_W32NSP_NSPStartup().

633 {
634  DEBUGLOG ("GNUNET_W32NSP_InstallServiceClass\n");
635  SetLastError (WSAEOPNOTSUPP);
636  return SOCKET_ERROR;
637 }
#define DEBUGLOG(s,...)
Definition: w32nsp.c:31
Here is the caller graph for this function:

◆ GNUNET_W32NSP_RemoveServiceClass()

static int WSAAPI GNUNET_W32NSP_RemoveServiceClass ( LPGUID  lpProviderId,
LPGUID  lpServiceClassId 
)
static

Definition at line 641 of file w32nsp.c.

References DEBUGLOG.

Referenced by GNUNET_W32NSP_NSPStartup().

642 {
643  DEBUGLOG ("GNUNET_W32NSP_RemoveServiceClass\n");
644  SetLastError (WSAEOPNOTSUPP);
645  return SOCKET_ERROR;
646 }
#define DEBUGLOG(s,...)
Definition: w32nsp.c:31
Here is the caller graph for this function:

◆ GNUNET_W32NSP_GetServiceClassInfo()

static int WSAAPI GNUNET_W32NSP_GetServiceClassInfo ( LPGUID  lpProviderId,
LPDWORD  lpdwBufSize,
LPWSASERVICECLASSINFOW  lpServiceClassInfo 
)
static

Definition at line 649 of file w32nsp.c.

References DEBUGLOG.

Referenced by GNUNET_W32NSP_NSPStartup().

651 {
652  DEBUGLOG ("GNUNET_W32NSP_GetServiceClassInfo\n");
653  SetLastError (WSAEOPNOTSUPP);
654  return SOCKET_ERROR;
655 }
#define DEBUGLOG(s,...)
Definition: w32nsp.c:31
Here is the caller graph for this function:

◆ GNUNET_W32NSP_Ioctl()

static int WSAAPI GNUNET_W32NSP_Ioctl ( HANDLE  hLookup,
DWORD  dwControlCode,
LPVOID  lpvInBuffer,
DWORD  cbInBuffer,
LPVOID  lpvOutBuffer,
DWORD  cbOutBuffer,
LPDWORD  lpcbBytesReturned,
LPWSACOMPLETION  lpCompletion,
LPWSATHREADID  lpThreadId 
)
static

Definition at line 658 of file w32nsp.c.

References DEBUGLOG.

Referenced by GNUNET_W32NSP_NSPStartup().

662 {
663  DEBUGLOG ("GNUNET_W32NSP_Ioctl\n");
664  SetLastError (WSAEOPNOTSUPP);
665  return SOCKET_ERROR;
666 }
#define DEBUGLOG(s,...)
Definition: w32nsp.c:31
Here is the caller graph for this function:

◆ GNUNET_W32NSP_NSPStartup()

int WSAAPI GNUNET_W32NSP_NSPStartup ( LPGUID  lpProviderId,
LPNSP_ROUTINE  lpnspRoutines 
)

This function is called by Winsock to hook up our provider.

It is the only function that [should be/is] exported by the provider. All other routines are passed as pointers in lpnspRoutines.

Definition at line 674 of file w32nsp.c.

References connect_to_dns_resolver(), GNUNET_W32NSP_GetServiceClassInfo(), GNUNET_W32NSP_InstallServiceClass(), GNUNET_W32NSP_Ioctl(), GNUNET_W32NSP_LookupServiceBegin(), GNUNET_W32NSP_LookupServiceEnd(), GNUNET_W32NSP_LookupServiceNext(), GNUNET_W32NSP_RemoveServiceClass(), GNUNET_W32NSP_SetService(), NSPAPI_VERSION_MAJOR, NSPAPI_VERSION_MINOR, and NSPCleanup().

675 {
676  if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
677  {
678  if (!connect_to_dns_resolver ())
679  {
680  return SOCKET_ERROR;
681  }
682  /* This assumes that NSP_ROUTINE struct doesn't have a NSPIoctl member.
683  * If it does, you need to use FIELD_OFFSET() macro to get offset of NSPIoctl
684  * and use that offset as cbSize.
685  */
686  lpnspRoutines->cbSize = sizeof(NSP_ROUTINE);
687 
688  lpnspRoutines->dwMajorVersion = NSPAPI_VERSION_MAJOR;
689  lpnspRoutines->dwMinorVersion = NSPAPI_VERSION_MINOR;
690  lpnspRoutines->NSPCleanup = NSPCleanup;
691  lpnspRoutines->NSPLookupServiceBegin = GNUNET_W32NSP_LookupServiceBegin;
692  lpnspRoutines->NSPLookupServiceNext = GNUNET_W32NSP_LookupServiceNext;
693  lpnspRoutines->NSPLookupServiceEnd = GNUNET_W32NSP_LookupServiceEnd;
694  lpnspRoutines->NSPSetService = GNUNET_W32NSP_SetService;
695  lpnspRoutines->NSPInstallServiceClass = GNUNET_W32NSP_InstallServiceClass;
696  lpnspRoutines->NSPRemoveServiceClass = GNUNET_W32NSP_RemoveServiceClass;
697  lpnspRoutines->NSPGetServiceClassInfo = GNUNET_W32NSP_GetServiceClassInfo;
698  /*((NSP_ROUTINE_XP *) lpnspRoutines)->NSPIoctl = GNUNET_W32NSP_Ioctl;*/
699  lpnspRoutines->NSPIoctl = GNUNET_W32NSP_Ioctl;
700  return NO_ERROR;
701  }
702  SetLastError (WSAEINVALIDPROVIDER);
703  return SOCKET_ERROR;
704 }
#define NSPAPI_VERSION_MAJOR
Definition: w32nsp.c:78
static int WSAAPI GNUNET_W32NSP_SetService(LPGUID lpProviderId, LPWSASERVICECLASSINFOW lpServiceClassInfo, LPWSAQUERYSETW lpqsRegInfo, WSAESETSERVICEOP essOperation, DWORD dwControlFlags)
Definition: w32nsp.c:621
static int WSPAPI GNUNET_W32NSP_LookupServiceEnd(HANDLE hLookup)
Definition: w32nsp.c:579
static int WSAAPI GNUNET_W32NSP_LookupServiceNext(HANDLE hLookup, DWORD dwControlFlags, LPDWORD lpdwBufferLength, LPWSAQUERYSETW lpqsResults)
Definition: w32nsp.c:380
static int WSAAPI GNUNET_W32NSP_GetServiceClassInfo(LPGUID lpProviderId, LPDWORD lpdwBufSize, LPWSASERVICECLASSINFOW lpServiceClassInfo)
Definition: w32nsp.c:649
static SOCKET connect_to_dns_resolver()
Definition: w32nsp.c:165
static int WSAAPI GNUNET_W32NSP_InstallServiceClass(LPGUID lpProviderId, LPWSASERVICECLASSINFOW lpServiceClassInfo)
Definition: w32nsp.c:631
static int WSPAPI NSPCleanup(LPGUID lpProviderId)
Definition: w32nsp.c:260
static int WSAAPI GNUNET_W32NSP_RemoveServiceClass(LPGUID lpProviderId, LPGUID lpServiceClassId)
Definition: w32nsp.c:641
static int WSPAPI GNUNET_W32NSP_LookupServiceBegin(LPGUID lpProviderId, LPWSAQUERYSETW lpqsRestrictions, LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags, LPHANDLE lphLookup)
Definition: w32nsp.c:297
static int WSAAPI GNUNET_W32NSP_Ioctl(HANDLE hLookup, DWORD dwControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned, LPWSACOMPLETION lpCompletion, LPWSATHREADID lpThreadId)
Definition: w32nsp.c:658
#define NSPAPI_VERSION_MINOR
Definition: w32nsp.c:79
Here is the call graph for this function:

Variable Documentation

◆ records_cs

CRITICAL_SECTION records_cs
static

Definition at line 81 of file w32nsp.c.

Referenced by DllMain().

◆ records

struct record* records = NULL
static

Definition at line 92 of file w32nsp.c.

◆ records_len

size_t records_len = 0
static

◆ records_size

size_t records_size = 0
static

Definition at line 94 of file w32nsp.c.

Referenced by resize_records().