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 (_win_socket s, const wchar_t *name, DWORD flags)
 
static _win_socket connect_to_dns_resolver ()
 
static int send_name_to_ip_request (LPWSAQUERYSETW lpqsRestrictions, LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags, _win_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.

◆ 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 356 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 149 of file w32nsp.c.

◆ NSP_ROUTINE_XP

Function Documentation

◆ resize_records()

static int resize_records ( )
static

Definition at line 96 of file w32nsp.c.

References GNUNET_memcpy, records_len, and records_size.

Referenced by add_record().

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 }
static struct record * records
Definition: w32nsp.c:91
Definition: w32nsp.c:83
#define GNUNET_memcpy(dst, src, n)
static size_t records_len
Definition: w32nsp.c:92
static size_t records_size
Definition: w32nsp.c:93
Here is the caller graph for this function:

◆ add_record()

static int add_record ( _win_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 
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 }
static struct record * records
Definition: w32nsp.c:91
DWORD flags
Definition: w32nsp.c:85
Definition: w32nsp.c:83
enum State state
current state of profiling
static int resize_records()
Definition: w32nsp.c:96
_win_socket s
Definition: w32nsp.c:84
static int res
const char * name
static size_t records_len
Definition: w32nsp.c:92
Here is the call graph for this function:
Here is the caller graph for this function:

◆ connect_to_dns_resolver()

static _win_socket connect_to_dns_resolver ( )
static

Definition at line 166 of file w32nsp.c.

References INVALID_SOCKET, and ret.

Referenced by GNUNET_W32NSP_NSPStartup(), and send_name_to_ip_request().

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 }
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define INVALID_SOCKET
Definition: network.c:39
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,
_win_socket *  resolver 
)
static

Definition at line 196 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().

199 {
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);
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];
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);
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 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static _win_socket connect_to_dns_resolver()
Definition: w32nsp.c:166
struct GNUNET_OS_Process * resolver
Resolver process handle.
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:66
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST.
Definition: w32resolver.h:57
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 262 of file w32nsp.c.

References DEBUGLOG.

Referenced by GNUNET_W32NSP_NSPStartup().

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 }
#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 274 of file w32nsp.c.

References records_cs.

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 }
static CRITICAL_SECTION records_cs
Definition: w32nsp.c:81

◆ GNUNET_W32NSP_LookupServiceBegin()

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

Definition at line 302 of file w32nsp.c.

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

Referenced by GNUNET_W32NSP_NSPStartup().

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 }
#define DEBUGLOG(s,...)
Definition: w32nsp.c:31
static int send_name_to_ip_request(LPWSAQUERYSETW lpqsRestrictions, LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags, _win_socket *resolver)
Definition: w32nsp.c:196
static int add_record(_win_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 361 of file w32nsp.c.

References UnmarshallPtr.

Referenced by GNUNET_W32NSP_LookupServiceNext().

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 }
#define UnmarshallPtr(ptr, ptrtype, base)
Definition: w32nsp.c:356
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 386 of file w32nsp.c.

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

Referenced by GNUNET_W32NSP_NSPStartup().

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);
495  header.size == sizeof(header)))
496  {
497  records[rec].state |= 4;
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 }
static struct record * records
Definition: w32nsp.c:91
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:361
char * buf
Definition: w32nsp.c:87
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
Request for the resolver.
Definition: w32resolver.h:53
static char buf[2048]
uint8_t state
Definition: w32nsp.c:86
static size_t records_len
Definition: w32nsp.c:92
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 585 of file w32nsp.c.

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

Referenced by GNUNET_W32NSP_NSPStartup().

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 }
static struct record * records
Definition: w32nsp.c:91
char * buf
Definition: w32nsp.c:87
enum State state
current state of profiling
#define DEBUGLOG(s,...)
Definition: w32nsp.c:31
static char buf[2048]
uint8_t state
Definition: w32nsp.c:86
const char * name
static size_t records_len
Definition: w32nsp.c:92
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 627 of file w32nsp.c.

References DEBUGLOG.

Referenced by GNUNET_W32NSP_NSPStartup().

630 {
631  DEBUGLOG("GNUNET_W32NSP_SetService\n");
632  SetLastError(WSAEOPNOTSUPP);
633  return SOCKET_ERROR;
634 }
#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 637 of file w32nsp.c.

References DEBUGLOG.

Referenced by GNUNET_W32NSP_NSPStartup().

639 {
640  DEBUGLOG("GNUNET_W32NSP_InstallServiceClass\n");
641  SetLastError(WSAEOPNOTSUPP);
642  return SOCKET_ERROR;
643 }
#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 647 of file w32nsp.c.

References DEBUGLOG.

Referenced by GNUNET_W32NSP_NSPStartup().

648 {
649  DEBUGLOG("GNUNET_W32NSP_RemoveServiceClass\n");
650  SetLastError(WSAEOPNOTSUPP);
651  return SOCKET_ERROR;
652 }
#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 655 of file w32nsp.c.

References DEBUGLOG.

Referenced by GNUNET_W32NSP_NSPStartup().

657 {
658  DEBUGLOG("GNUNET_W32NSP_GetServiceClassInfo\n");
659  SetLastError(WSAEOPNOTSUPP);
660  return SOCKET_ERROR;
661 }
#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 664 of file w32nsp.c.

References DEBUGLOG.

Referenced by GNUNET_W32NSP_NSPStartup().

668 {
669  DEBUGLOG("GNUNET_W32NSP_Ioctl\n");
670  SetLastError(WSAEOPNOTSUPP);
671  return SOCKET_ERROR;
672 }
#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 680 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().

681 {
682  if (IsEqualGUID(lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
683  {
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 }
#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:627
static _win_socket connect_to_dns_resolver()
Definition: w32nsp.c:166
static int WSPAPI GNUNET_W32NSP_LookupServiceEnd(HANDLE hLookup)
Definition: w32nsp.c:585
static int WSAAPI GNUNET_W32NSP_LookupServiceNext(HANDLE hLookup, DWORD dwControlFlags, LPDWORD lpdwBufferLength, LPWSAQUERYSETW lpqsResults)
Definition: w32nsp.c:386
static int WSAAPI GNUNET_W32NSP_GetServiceClassInfo(LPGUID lpProviderId, LPDWORD lpdwBufSize, LPWSASERVICECLASSINFOW lpServiceClassInfo)
Definition: w32nsp.c:655
static int WSAAPI GNUNET_W32NSP_InstallServiceClass(LPGUID lpProviderId, LPWSASERVICECLASSINFOW lpServiceClassInfo)
Definition: w32nsp.c:637
static int WSPAPI NSPCleanup(LPGUID lpProviderId)
Definition: w32nsp.c:262
static int WSAAPI GNUNET_W32NSP_RemoveServiceClass(LPGUID lpProviderId, LPGUID lpServiceClassId)
Definition: w32nsp.c:647
static int WSPAPI GNUNET_W32NSP_LookupServiceBegin(LPGUID lpProviderId, LPWSAQUERYSETW lpqsRestrictions, LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags, LPHANDLE lphLookup)
Definition: w32nsp.c:302
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:664
#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 91 of file w32nsp.c.

◆ records_len

size_t records_len = 0
static

◆ records_size

size_t records_size = 0
static

Definition at line 93 of file w32nsp.c.

Referenced by resize_records().