cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
tcp.h
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib TCP/IP Interface Header *
4 * Copyright Peter Gutmann 1998-2007 *
5 * *
6 ****************************************************************************/
7 
8 #ifdef USE_TCP
9 
10 /****************************************************************************
11 * *
12 * AMX *
13 * *
14 ****************************************************************************/
15 
16 #ifdef __AMX__
17 
18 #include <kn_sock.h>
19 
20 /* All KwikNet functions have kn_ prefix, to use the standard sockets API
21  names we have to redefine them to the usual names */
22 
23 #define accept kn_accept
24 #define bind kn_bind
25 #define closesocket kn_close
26 #define connect kn_connect
27 #define getsockopt kn_getsockopt
28 #define listen kn_listen
29 #define recv kn_recv
30 #define select kn_select
31 #define send kn_send
32 #define setsockopt kn_setsockopt
33 #define shutdown kn_shutdown
34 #define socket kn_socket
35 
36 #endif /* AMX */
37 
38 /****************************************************************************
39 * *
40 * BeOS *
41 * *
42 ****************************************************************************/
43 
44 /* If we're building under BeOS the system may have the new(er) BONE (BeOs
45  Network Environment) network stack. This didn't quite make it into BeOS
46  v5 before the demise of Be Inc but was leaked after Be folded, as was the
47  experimental/developmental Dano release of BeOS, which would have become
48  BeOS 5.1 and also has a newer network stack. In order to detect this we
49  have to pull in sys/socket.h before we try anything else */
50 
51 #ifdef __BEOS__
52  #include <sys/socket.h>
53 #endif /* __BEOS__ */
54 
55 /* If we're using the original (rather minimal) BeOS TCP/IP stack, we have
56  to provide a customised interface for it rather than using the same one
57  as the generic Unix/BSD interface */
58 
59 #if defined( __BEOS__ ) && !defined( BONE_VERSION )
60 
61 #include <errno.h>
62 #include <fcntl.h>
63 #include <netdb.h>
64 #include <socket.h>
65 
66 /* BeOS doesn't define any of the PF_xxx's, howewever it does defines
67  some of the AF_xxx equivalents, since these are synonyms we just define
68  the PF_xxx's ourselves */
69 
70 #define PF_UNSPEC 0
71 #define PF_INET AF_INET
72 
73 /* BeOS doesn't define in_*_t's */
74 
75 #define in_addr_t u_long
76 #define in_port_t u_short
77 
78 /* BeOS doesn't define NO_ADDRESS, but NO_DATA is a synonym for this */
79 
80 #define NO_ADDRESS NO_DATA
81 
82 /* BeOS doesn't support checking for anything except readability in select()
83  and only supports one or two socket options, so we define our own
84  versions of these functions that no-op out unsupported options */
85 
86 #define select( sockets, readFD, writeFD, exceptFD, timeout ) \
87  my_select( sockets, readFD, writeFD, exceptFD, timeout )
88 #define getsockopt( socket, level, optname, optval, optlen ) \
89  my_getsockopt( socket, level, optname, optval, optlen )
90 #define setsockopt( socket, level, optname, optval, optlen ) \
91  my_setsockopt( socket, level, optname, optval, optlen )
92 
93 /* The following options would be required, but aren't provided by BeOS. If
94  you're building under a newer BeOS version that supports these options,
95  you'll also need to update my_set/setsockopt() to no longer no-op them
96  out */
97 
98 #define SO_ERROR -1
99 #define TCP_NODELAY -1
100 
101 /****************************************************************************
102 * *
103 * ThreadX *
104 * *
105 ****************************************************************************/
106 
107 #elif defined( __THREADX__ )
108 
109 /* ThreadX doesn't have native socket support, there is a ThreadX component
110  called NetX but everyone seems to use assorted non-ThreadX network
111  stacks. The following is a representative entry for Treck's network
112  stack */
113 
114 #include "r:/temp/trsocket.h"
115 
116 #undef USE_DNSSRV
117 #undef __WINDOWS__
118 
119 /* Some versions of the Treck stack don't support all IPv6 options */
120 
121 #ifndef NI_NUMERICSERV
122  #define NI_NUMERICSERV 0 /* Unnecessary for Treck stack */
123 #endif /* !NI_NUMERICSERV */
124 
125 /* The Treck stack doesn't implement IPV6_V6ONLY (needed for getsockopt()),
126  the following define gives it an out-of-range value that results in
127  getsockopt() failing, so the operation is skipped */
128 
129 #ifndef IPV6_V6ONLY
130  #define IPV6_V6ONLY 5000
131 #endif /* !IPV6_V6ONLY */
132 
133 /* Like Windows, Treck uses special names for close() and ioctl() to avoid
134  conflicts with standard system calls, and defines special functions for
135  obtaining error information rather than using a static errno-type
136  value */
137 
138 #define closesocket tfClose
139 #define ioctlsocket tfIoctl
140 #define getErrorCode() tfGetSocketError( netStream->netSocket )
141 #define getHostErrorCode() tfGetSocketError( netStream->netSocket )
142 
143 /* Map Treck's nonstandard error names to more standard ones */
144 
145 #ifndef EADDRNOTAVAIL
146  #define EADDRNOTAVAIL TM_EADDRNOTAVAIL
147  #define EAGAIN TM_EAGAIN
148  #define ECONNABORTED TM_ECONNABORTED
149  #define ECONNREFUSED TM_ECONNREFUSED
150  #define ECONNRESET TM_ECONNRESET
151  #define EINPROGRESS TM_EINPROGRESS
152  #define EINTR TM_EINTR
153  #define EMFILE TM_EMFILE
154  #define EMSGSIZE TM_EMSGSIZE
155  #define ENETUNREACH TM_ENETUNREACH
156  #define ENOBUFS TM_ENOBUFS
157  #define ENOTCONN TM_ENOTCONN
158  #define ETIMEDOUT TM_ETIMEDOUT
159  #define HOST_NOT_FOUND TM_DNS_ENAME_ERROR
160  #define NO_ADDRESS TM_DNS_EANSWER
161  #define NO_DATA TM_DNS_EANSWER /* No equivalent in Treck stack */
162  #define TRY_AGAIN TM_EAGAIN
163 #endif /* Standard error names not defined */
164 
165 /****************************************************************************
166 * *
167 * uITRON *
168 * *
169 ****************************************************************************/
170 
171 #elif defined( __ITRON__ )
172 
173 /* uITRON has a TCP/IP API but it doesn't seem to be widely used, and the
174  only available documentation is in Japanese. If you need TCP/IP support
175  under uITRON and have an implementation available, you can add the
176  appropriate interface by replacing net_tcp.c and net_dns.c with the
177  equivalent uITRON API glue code */
178 
179 #error You need to set up the TCP/IP headers and interface in net_tcp.c/net_dns.c
180 
181 /****************************************************************************
182 * *
183 * Unix and Unix-compatible Systems *
184 * *
185 ****************************************************************************/
186 
187 /* Guardian sockets originally couldn't handle nonblocking I/O like standard
188  BSD sockets, but required the use of a special non-blocking socket type
189  (nowait sockets) and the use of AWAITIOX() on the I/O tag returned from
190  the nowait socket call, since the async state was tied to this rather
191  than to the socket handle. One of the early G06 releases added select()
192  support, although even the latest documentation still claims that
193  select() isn't supported. To avoid having to support two completely
194  different interfaces, we use the more recent (and BSD standard) select()
195  interface. Anyone running this code on old systems will have to add
196  wrappers for the necessary socket_nw()/accept_nw()/AWAITIOX() calls */
197 
198 #elif ( defined( __BEOS__ ) && defined( BONE_VERSION ) ) || \
199  defined( __ECOS__ ) || defined( __MVS__ ) || \
200  defined( __PALMOS__ ) || defined( __RTEMS__ ) || \
201  defined ( __SYMBIAN32__ ) || defined( __TANDEM_NSK__ ) || \
202  defined( __TANDEM_OSS__ ) || defined( __UNIX__ )
203 
204 /* C_IN is a cryptlib.h value which is also defined in some versions of
205  netdb.h, so we have to undefine it before we include any network header
206  files */
207 
208 #undef C_IN
209 
210 /* PHUX and Tandem OSS have broken networking headers that require manually
211  defining _XOPEN_SOURCE_EXTENDED in order for various function prototypes
212  to be enabled. The Tandem variant of this problem has all the function
213  prototypes for the NSK target and a comment by the 'else' that follows
214  saying that it's for the OSS target, but then an ifdef for
215  _XOPEN_SOURCE_EXTENDED that prevents it from being enabled unless
216  _XOPEN_SOURCE_EXTENDED is also defined */
217 
218 #if ( defined( __hpux ) && ( OSVERSION >= 10 ) ) || defined( _OSS_TARGET )
219  #define _XOPEN_SOURCE_EXTENDED 1
220 #endif /* Workaround for inconsistent networking headers */
221 
222 /* In OS X 10.3 (Panther), Apple broke the bind interface by changing the
223  BIND_4_COMPAT define to BIND_8_COMPAT ("Apple reinvented the wheel and
224  made it square" is one of the more polite comments on this change). In
225  order to get things to work, we have to define BIND_8_COMPAT here, which
226  forces the inclusion of nameser_compat.h when we include nameser.h. All
227  (non-Apple) systems automatically define BIND_4_COMPAT to force this
228  inclusion, since Bind9 support (in the form of anything other than the
229  installed binaries) is still pretty rare */
230 
231 #if defined( __APPLE__ ) && !defined( BIND_8_COMPAT )
232  #define BIND_8_COMPAT
233 #endif /* Mac OS X without backwards-compatibility bind define */
234 
235 #include <errno.h>
236 #include <fcntl.h>
237 #include <netdb.h>
238 #if defined( __APPLE__ ) || defined( __BEOS__ ) || defined( __bsdi__ ) || \
239  defined( __FreeBSD__ ) || defined( __hpux ) || defined( __MVS__ ) || \
240  defined( __NetBSD__ ) || defined( __OpenBSD__ ) || defined( __QNX__ ) || \
241  ( defined( sun ) && OSVERSION <= 5 ) || defined( __SYMBIAN32__ ) || \
242  defined( __VMCMS__ )
243  #include <netinet/in.h>
244 #endif /* OS x || BeOS || *BSDs || PHUX || SunOS 4.x/2.5.x || Symbian OS */
245 #include <arpa/inet.h>
246 #if !( defined( __CYGWIN__ ) || defined( __PALMOS__ ) || \
247  defined( __SYMBIAN32__ ) || defined( USE_EMBEDDED_OS ) )
248  #include <arpa/nameser.h>
249 #endif /* Cygwin || Symbian OS */
250 #if defined( __MVS__ ) || defined( __VMCMS__ )
251  /* The following have conflicting definitions in xti.h */
252  #undef T_NULL
253  #undef T_UNSPEC
254 #endif /* MVS || VM */
255 #if !defined( __MVS__ )
256  /* netinet/tcp.h is a BSD-ism, but all Unixen seem to use this even if
257  XPG4 and SUS say it should be in xti.h */
258  #include <netinet/tcp.h>
259 #endif /* !MVS */
260 #if !( defined( __CYGWIN__ ) || defined( __PALMOS__ ) || \
261  defined( __SYMBIAN32__ ) || defined( USE_EMBEDDED_OS ) )
262  #include <resolv.h>
263 #endif /* Cygwin || Symbian OS */
264 #if !defined( TCP_NODELAY ) && !defined( USE_EMBEDDED_OS )
265  #include <xti.h>
266  #if defined( __MVS__ ) || defined( __VMCMS__ )
267  /* The following have conflicting definitions in nameser.h */
268  #undef T_NULL
269  #undef T_UNSPEC
270  #endif /* MVS || VM */
271 #endif /* TCP_NODELAY */
272 #ifdef __SCO_VERSION__
273  #include <signal.h>
274  #ifndef SIGIO
275  #include <sys/signal.h>
276  #endif /* SIGIO not defined in signal.h - only from SCO */
277 #endif /* UnixWare/SCO */
278 #if defined( _AIX ) || defined( __PALMOS__ ) || defined( __QNX__ )
279  #include <sys/select.h>
280 #endif /* Aches || Palm OS || QNX */
281 #include <sys/socket.h>
282 #include <sys/time.h>
283 #include <sys/types.h>
284 #ifdef __PALMOS__
285  /* Needed for close(). unistd.h, which contains this, is normally
286  included by default in Unix environments, but isn't for PalmOS */
287  #include <unistd.h>
288 #endif /* Palm OS */
289 
290 /* AIX and SCO don't define sockaddr_storage in their IPv6 headers so we
291  define a placeholder equivalent here */
292 
293 #if defined( IPv6 ) && \
294  ( ( defined( _AIX ) && OSVERSION <= 5 ) || defined( __SCO_VERSION__ ) )
295  struct sockaddr_storage {
296  union {
297  struct sockaddr_in6 bigSockaddrStruct;
298  char padding[ 128 ];
299  } dummyMember;
300  };
301 #endif /* IPv6 versions without sockaddr_storage */
302 
303 /* PHUX generally doesn't define h_errno, we have to be careful here since
304  later versions may use macros to get around threading issues so we check
305  for the existence of a macro with the given name before defining our own
306  version */
307 
308 #if defined( __hpux ) && !defined( h_errno )
309  /* Usually missing from netdb.h */
310  extern int h_errno;
311 #endif /* PHUX && !h_errno */
312 
313 /****************************************************************************
314 * *
315 * VxWorks *
316 * *
317 ****************************************************************************/
318 
319 #elif defined( __VXWORKS__ )
320 
321 /* VxWorks includes a (somewhat minimal) BSD sockets implementation, if
322  you're using a newer, enhanced implementation or a third-party
323  alternative with more complete functionality (and less bugs), you can use
324  the generic Unix headers and defines further down */
325 
326 #include <socket.h>
327 #include <selectLib.h>
328 
329 /****************************************************************************
330 * *
331 * Windows *
332 * *
333 ****************************************************************************/
334 
335 #elif defined( __WINDOWS__ )
336 
337 /* Winsock2 wasn't available until VC++/eVC++ 4.0 so if we're running an
338  older version we have to use the Winsock1 interface */
339 
340 #if defined( _MSC_VER ) && ( _MSC_VER <= 800 ) || \
341  defined( __WINCE__ ) && ( _WIN32_WCE < 400 )
342  #include <winsock.h>
343 #else
344  #include <winsock2.h>
345  #include <ws2tcpip.h>
346 #endif /* Older WinCE vs. newer WinCE and Win32 */
347 
348 /* VC++ 7 and newer have IPv6 support included in ws2tcpip.h, VC++ 6 can
349  have it bolted-on using the IPv6 Technology Preview but it's not present
350  by default. In addition the Tech.Preview is quite buggy and unstable,
351  leaking handles and memory and in some cases leading to runaway memory
352  consumption that locks up the machine if the process isn't killed in
353  time, so we don't want to encourage its use */
354 
355 #if defined( _MSC_VER ) && ( _MSC_VER > 1300 )
356  /* #include <tpipv6.h> */ /* From IPv6 Tech.Preview */
357 #endif /* VC++ 7 and newer */
358 
359 /* VC++ 7 and newer have DNS headers, for older versions (or for builds
360  using the DDK) we have to define the necessary types and constants
361  ourselves */
362 
363 #if defined( _MSC_VER ) && ( _MSC_VER > 1300 ) && !defined( WIN_DDK )
364  #include <windns.h>
365 #elif defined( _MSC_VER ) && ( _MSC_VER > 800 )
366  /* windns.h is quite new and many people don't have it yet, not helped by
367  the fact that it's also changed over time. For example,
368  DnsRecordListFree() has also been DnsFreeRecordList() and DnsFree() at
369  various times, with the parameters changing to match. Because of this,
370  we have to define our own (very cut-down) subset of what's in there
371  here. We define PIP4_ARRAY as a void * since it's only used to specify
372  optional DNS servers to query, we never need this so we just set the
373  parameter to NULL. As with the DnsXXX functions, PIP4_ARRAY has
374  changed over time. It was known as PIP_ARRAY in the original VC++ .NET
375  release, but was renamed PIP4_ARRAY for .NET 2003, although some MSDN
376  entries still refer to PIP_ARRAY even in the 2003 version */
377  typedef LONG DNS_STATUS;
378  typedef void *PIP4_ARRAY;
379  typedef DWORD IP4_ADDRESS;
380  typedef enum { DnsFreeFlat, DnsFreeRecordList } DNS_FREE_TYPE;
381  typedef enum { DnsConfigPrimaryDomainName_W, DnsConfigPrimaryDomainName_A,
382  DnsConfigPrimaryDomainName_UTF8, DnsConfigAdapterDomainName_W,
383  DnsConfigAdapterDomainName_A, DnsConfigAdapterDomainName_UTF8,
384  DnsConfigDnsServerList, DnsConfigSearchList,
385  DnsConfigAdapterInfo, DnsConfigPrimaryHostNameRegistrationEnabled,
386  DnsConfigAdapterHostNameRegistrationEnabled,
387  DnsConfigAddressRegistrationMaxCount, DnsConfigHostName_W,
388  DnsConfigHostName_A, DnsConfigHostName_UTF8,
389  DnsConfigFullHostName_W, DnsConfigFullHostName_A,
390  DnsConfigFullHostName_UTF8 } DNS_CONFIG_TYPE;
391  #define DNS_TYPE_A 1
392  #define DNS_TYPE_PTR 12
393  #define DNS_TYPE_SRV 33
394  #define DNS_QUERY_STANDARD 0
395  #define DNS_QUERY_BYPASS_CACHE 8
396  typedef struct {
397  /* Technically these are DWORDs, but only integers are allowed for
398  bitfields. This is OK in this case because sizeof( int ) ==
399  sizeof( DWORD ) */
400  unsigned int Section : 2;
401  unsigned int Delete : 1;
402  unsigned int CharSet : 2;
403  unsigned int Unused : 3;
404  unsigned int Reserved : 24;
405  } DNS_RECORD_FLAGS;
406  typedef struct {
407  IP4_ADDRESS IpAddress;
408  } DNS_A_DATA, *PDNS_A_DATA;
409  typedef struct {
410  LPTSTR pNameHost;
411  } DNS_PTR_DATA, *PDNS_PTR_DATA;
412  typedef struct {
413  LPTSTR pNameTarget;
414  WORD wPriority;
415  WORD wWeight;
416  WORD wPort;
417  WORD Pad;
418  } DNS_SRV_DATA, *PDNS_SRV_DATA;
419  typedef struct _DnsRecord {
420  struct _DnsRecord *pNext;
421  LPTSTR pName;
422  WORD wType;
423  WORD wDataLength;
424  union {
425  DWORD DW;
426  DNS_RECORD_FLAGS S;
427  } Flags;
428  DWORD dwTtl;
429  DWORD dwReserved;
430  union {
431  DNS_A_DATA A;
432  DNS_PTR_DATA PTR, Ptr,
433  NS, Ns,
434  CNAME, Cname,
435  MB, Mb,
436  MD, Md,
437  MF, Mf,
438  MG, Mg,
439  MR, Mr;
440  #if 0
441  DNS_MINFO_DATA MINFO, Minfo,
442  RP, Rp;
443  DNS_MX_DATA MX, Mx,
444  AFSDB, Afsdb,
445  RT, Rt;
446  DNS_TXT_DATA HINFO, Hinfo,
447  ISDN, Isdn,
448  TXT, Txt,
449  X25;
450  DNS_NULL_DATA Null;
451  DNS_WKS_DATA WKS, Wks;
452  DNS_AAAA_DATA AAAA;
453  DNS_KEY_DATA KEY, Key;
454  DNS_SIG_DATA SIG, Sig;
455  DNS_ATMA_DATA ATMA, Atma;
456  DNS_NXT_DATA NXT, Nxt;
457  #endif /* 0 */
458  DNS_SRV_DATA SRV, Srv;
459  #if 0
460  DNS_TKEY_DATA TKEY, Tkey;
461  DNS_TSIG_DATA TSIG, Tsig;
462  DNS_WINS_DATA WINS, Wins;
463  DNS_WINSR_DATA WINSR, WinsR,
464  NBSTAT, Nbstat;
465  #endif /* 0 */
466  } Data;
467  } DNS_RECORD, *PDNS_RECORD;
468 #endif /* VC++ 7 and newer vs. older versions */
469 
470 /* For backwards-compatibility purposes, wspiapi.h overrides the new address/
471  name-handling functions introduced for IPv6 with complex macros that
472  substitute inline function calls that try and dynamically load different
473  libraries depending on the Windows version and call various helper
474  functions to provide the same service. Since we dynamically load the
475  required libraries, we don't need any of this complexity, so we undefine
476  the macros in order to make our own ones work */
477 
478 #ifdef getaddrinfo
479  #undef freeaddrinfo
480  #undef getaddrinfo
481  #undef getnameinfo
482 #endif /* getaddrinfo defined as macros in wspiapi.h */
483 
484 /* Set up the appropriate calling convention for the Winsock API */
485 
486 #if defined( WSAAPI )
487  #define SOCKET_API WSAAPI
488 #elif defined( WINSOCKAPI )
489  #define SOCKET_API WINSOCKAPI
490 #else
491  #define SOCKET_API FAR PASCAL
492 #endif /* WSAAPI */
493 
494 /****************************************************************************
495 * *
496 * Other Systems *
497 * *
498 ****************************************************************************/
499 
500 #else
501 
502 #error You need to set up OS-specific networking include handling in net_tcp.h
503 
504 #endif /* OS-specific includes and defines */
505 
506 /****************************************************************************
507 * *
508 * General/Portability Defines *
509 * *
510 ****************************************************************************/
511 
512 /* Now that we've included all of the networking headers, try and guess
513  whether this is an IPv6-enabled system. We can detect this by the
514  existence of definitions for the EAI_xxx return values from
515  getaddrinfo(). Note that we can't safely detect it using the more
516  obvious AF_INET6 since many headers defined this in anticipation of IPv6
517  long before the remaining code support was present */
518 
519 #if defined( EAI_BADFLAGS ) && defined( EAI_NONAME )
520  #define IPv6
521 #endif /* getaddrinfo() return values defined */
522 
523 /* BeOS with the BONE network stack has the necessary IPv6 defines but no
524  actual IPv6 support, so we disable it again */
525 
526 #if defined( __BEOS__ ) && defined( BONE_VERSION ) && defined( IPv6 )
527  #undef IPv6
528 #endif /* BeOS with BONE */
529 
530 /* The size of a (v4) IP address and the number of IP addresses that we try
531  to connect to for a given host, used if we're providing an emulated
532  (IPv4-only) getaddrinfo() */
533 
534 #define IP_ADDR_SIZE 4
535 #define IP_ADDR_COUNT 16
536 
537 /* Test for common socket errors. For isBadSocket() we don't just compare
538  the socket to INVALID_SOCKET but perform a proper range check both to
539  catch any problems with buggy implementations that may return something
540  other than -1 to indicate an error, and because we're going to use the
541  value in FD_xyz() macros which often don't perform any range checking,
542  and a value outside the range 0...FD_SETSIZE can cause segfaults and
543  other problems. In addition we exclude stdin/stdout/stderr if they're
544  present, since a socket with these handle values is somewhat suspicious,
545  The one exception to this is Windows sockets, which don't use a Berkeley-
546  type bitflag representation and therefore don't have the range problems
547  that the Berkeley implementation does */
548 
549 #ifndef __WINDOWS__
550  #define INVALID_SOCKET -1
551 #endif /* __WINDOWS__ */
552 #if defined( __WINDOWS__ )
553  #define isBadSocket( socket ) ( ( socket ) <= 0 )
554 #elif defined( STDERR_FILENO )
555  #define isBadSocket( socket ) ( ( socket ) <= STDERR_FILENO || \
556  ( socket ) >= FD_SETSIZE )
557 #else
558  #define isBadSocket( socket ) ( ( socket ) <= 0 || \
559  ( socket ) >= FD_SETSIZE )
560 #endif /* STDERR_FILENO */
561 #ifdef __WINDOWS__
562  #define isSocketError( status ) ( ( status ) == SOCKET_ERROR )
563  #define isBadAddress( address ) ( ( address ) == INADDR_NONE )
564 #else
565  #define isSocketError( status ) ( ( status ) == -1 )
566  #define isBadAddress( address ) ( ( address ) == ( in_addr_t ) -1 )
567 #endif /* Windows vs. other systems */
568 #if defined( __SYMBIAN32__ )
569  /* Symbian OS doesn't support nonblocking I/O */
570  #define isNonblockWarning() 0
571 #elif defined( __BEOS__ )
572  #if defined( BONE_VERSION )
573  /* BONE returns "Operation now in progress" */
574  #define isNonblockWarning() ( errno == EWOULDBLOCK || \
575  errno == 0x80007024 )
576  #else
577  /* BeOS, even though it supposedly doesn't support nonblocking
578  sockets, can return EWOULDBLOCK */
579  #define isNonblockWarning() ( errno == EWOULDBLOCK )
580  #endif /* BeOS with/without BONE */
581 #elif defined( __WINDOWS__ )
582  #define isNonblockWarning() ( WSAGetLastError() == WSAEWOULDBLOCK )
583 #else
584  #define isNonblockWarning() ( errno == EINPROGRESS )
585 #endif /* OS-specific socket error handling */
586 
587 /* Error code handling */
588 
589 #if defined( __WINDOWS__ )
590  #define getErrorCode() WSAGetLastError()
591  #define getHostErrorCode() WSAGetLastError()
592 #elif !defined( getErrorCode )
593  #define getErrorCode() errno
594  #if ( defined( __MVS__ ) && defined( _OPEN_THREADS ) )
595  /* MVS converts this into a hidden function in the presence of threads,
596  but not transparently like other systems */
597  #define getHostErrorCode() ( *__h_errno() )
598  #else
599  #define getHostErrorCode() h_errno
600  #endif /* MVS */
601 #endif /* OS-specific error code handling */
602 
603 /* Windows and BeOS use a distinct socket handle type and require the use of
604  separate closesocket() and ioctlsocket() functions because socket handles
605  aren't the same as standard Windows/BeOS handles */
606 
607 #ifdef SOCKET
608  /* MP-RAS has already defined this */
609  #undef SOCKET
610 #endif /* SOCKET */
611 #define SOCKET int
612 #if !defined( __WINDOWS__ ) && !defined( closesocket )
613  #if !defined( __BEOS__ ) || \
614  ( defined( __BEOS__ ) && defined( BONE_VERSION ) )
615  #define closesocket close
616  #endif /* BeOS without BONE */
617  #define ioctlsocket ioctl
618 #endif /* OS-specific portability defines */
619 
620 /* The generic sockaddr struct used to reserve storage for protocol-specific
621  sockaddr structs. The IPv4 equivalent is given further down in the IPv6-
622  mapping definitions */
623 
624 #ifdef IPv6
625  #define SOCKADDR_STORAGE struct sockaddr_storage
626 #endif /* IPv6 */
627 
628 /* Many systems don't define the in_*_t's */
629 
630 #if defined( __APPLE__ ) || defined( __BEOS__ ) || \
631  defined( __bsdi__ ) || defined( _CRAY ) || \
632  defined( __CYGWIN__ ) || defined( __FreeBSD__ ) || \
633  defined( __hpux ) || defined( __linux__ ) || \
634  defined( __NetBSD__ ) || defined( __OpenBSD__ ) || \
635  defined( __QNX__ ) || ( defined( sun ) && OSVERSION <= 5 ) || \
636  defined( __WINDOWS__ )
637  #ifndef in_addr_t
638  #define in_addr_t u_long
639  #define in_port_t u_short
640  #endif /* in_addr_t */
641 #endif /* Older Unixen without in_*_t's */
642 
643 /* The handling of size parameters to socket functions is, as with most
644  things Unix, subject to random portability problems. The traditional
645  BSD sockets API used int for size parameters to socket functions, Posix
646  decided it'd be better to use size_t, but then people complained that
647  this wasn't binary-compatible with existing usage because on 64-bit
648  systems size_t != int. Instead of changing it back to int, Posix defined
649  a new type, socklen_t, which may or may not be an int. So some systems
650  have int, some have size_t, some have socklen_t defined to int, and some
651  have socklen_t defined to something else. PHUX, as usual, is
652  particularly bad, defaulting to the BSD form with int unless you define
653  _XOPEN_SOURCE_EXTENDED, in which case you get socklen_t but it's mapped
654  to size_t without any change in the sockets API, which still expects int
655  (the PHUX select() has a similar problem, see the comment in
656  random/unix.c).
657 
658  To resolve this, we try and use socklen_t if we detect its presence,
659  otherwise we use int where we know it's safe to do so, and failing that
660  we fall back to size_t */
661 
662 #if defined( socklen_t ) || defined( __socklen_t_defined )
663  #define SIZE_TYPE socklen_t
664 #elif defined( __APPLE__ ) || defined( __BEOS__ ) || defined( _CRAY ) || \
665  defined( __WINDOWS__ )
666  #define SIZE_TYPE int
667 #else
668  #define SIZE_TYPE size_t
669 #endif /* Different size types */
670 
671 /* The Bind namespace (via nameser.h) was cleaned up between the old (widely-
672  used) Bind4 API and the newer (little-used) Bind8/9 one. In order to
673  handle both, we use the newer definitions, but map them back to the Bind4
674  forms if required. The only thing this doesn't give us is the HEADER
675  struct, which seems to have no equivalent in Bind8/9 */
676 
677 #ifndef NS_PACKETSZ
678  #define NS_PACKETSZ PACKETSZ
679  #define NS_HFIXEDSZ HFIXEDSZ
680  #define NS_RRFIXEDSZ RRFIXEDSZ
681  #define NS_QFIXEDSZ QFIXEDSZ
682 #endif /* Bind8 names */
683 
684 /* Older versions of QNX don't define HFIXEDSZ either */
685 
686 #if defined( __QNX__ ) && ( OSVERSION <= 4 )
687  #define HFIXEDSZ 12
688 #endif /* QNX 4.x */
689 
690 /* Values defined in some environments but not in others. MSG_NOSIGNAL is
691  used to avoid SIGPIPEs on writes if the other side closes the connection,
692  if it's not implemented in this environment we just clear the flag */
693 
694 #ifndef SHUT_WR
695  #define SHUT_WR 1
696 #endif /* SHUT_WR */
697 #ifndef MSG_NOSIGNAL
698  #define MSG_NOSIGNAL 0
699 #endif /* MSG_NOSIGNAL */
700 
701 /* For some connections that involve long-running sessions we need to be
702  able to gracefully recover from local errors such as an interrupted system
703  call, and remote errors such as the remote process or host crashing and
704  restarting, which we can do by closing and re-opening the connection. The
705  various situations are:
706 
707  Local error:
708  Retry the call on EAGAIN or EINTR
709 
710  Process crashes and restarts:
711  Write: Remote host sends a RST in response to an attempt to continue
712  a TCP session that it doesn't remember, which is reported
713  locally as the dreaded (if you ssh or NNTP to remote hosts a
714  lot) connection reset by peer error.
715  Read: Remote host sends a FIN, we read 0 bytes.
716 
717  Network problem:
718  Write: Data is re-sent, if a read is pending it returns ETIMEDOUT,
719  otherwise write returns EPIPE or SIGPIPE (although we try
720  and avoid the latter using MSG_NOSIGNAL). Some
721  implementations may also return ENETUNREACH or EHOSTUNREACH
722  if they receive the right ICMP information.
723  Read: See above, without the write sematics.
724 
725  Host crashes and restarts:
726  Write: Looks like a network outage until the host is restarted, then
727  gets an EPIPE/SIGPIPE.
728  Read: As for write, but gets a ECONNRESET.
729 
730  The following macros check for various non-fatal/recoverable error
731  conditions, in the future we may want to address some of the others listed
732  above as well. A restartable error is a local error for which we can
733  retry the call, a recoverable error is a remote error for which we would
734  need to re-establish the connection. Note that any version of Winsock
735  newer than the 16-bit ones shouldn't give us an EINPROGRESS, however some
736  early stacks would still give this on occasions such as when another
737  thread was doing (blocking) name resolution, and even with the very latest
738  versions this is still something that can cause problems for other
739  threads */
740 
741 #ifdef __WINDOWS__
742  #define isRecoverableError( status ) ( ( status ) == WSAECONNRESET )
743  #define isRestartableError() ( WSAGetLastError() == WSAEWOULDBLOCK || \
744  WSAGetLastError() == WSAEINPROGRESS )
745  #define isTimeoutError() ( WSAGetLastError() == WSAETIMEDOUT )
746 #else
747  #define isRecoverableError( status ) ( ( status ) == ECONNRESET )
748  #define isRestartableError() ( errno == EINTR || errno == EAGAIN )
749  #define isTimeoutError() ( errno == ETIMEDOUT )
750 #endif /* OS-specific status codes */
751 
752 /****************************************************************************
753 * *
754 * Resolver Defines *
755 * *
756 ****************************************************************************/
757 
758 /* BeOS with the BONE network stack has just enough IPv6 defines present to
759  be awkward, so we temporarily re-enable IPv6 and then use a BONE-specific
760  subset of IPv6 defines further on */
761 
762 #if defined( __BEOS__ ) && defined( BONE_VERSION )
763  #define IPv6
764 #endif /* BeOS with BONE */
765 
766 /* IPv6 emulation functions used to provide a single consistent interface */
767 
768 #ifndef IPv6
769  /* The addrinfo struct used by getaddrinfo() */
770  struct addrinfo {
771  int ai_flags; /* AI_PASSIVE, NI_NUMERICHOST */
772  int ai_family; /* PF_INET */
773  int ai_socktype; /* SOCK_STREAM */
774  int ai_protocol; /* IPPROTO_TCP */
775  size_t ai_addrlen; /* Length of ai_addr */
776  char *ai_canonname; /* CNAME for nodename */
777  ARRAY_FIXED( ai_addrlen ) \
778  struct sockaddr *ai_addr; /* IPv4 or IPv6 sockaddr */
779  struct addrinfo *ai_next; /* Next addrinfo structure list */
780  };
781 
782  /* The generic sockaddr struct used to reserve storage for protocol-
783  specific sockaddr structs. This isn't quite right but since all
784  we're using it for is to reserve storage (we never actually look
785  inside it) it's OK to use here */
786  typedef char SOCKADDR_STORAGE[ 128 ];
787 
788  /* getaddrinfo() flags and values */
789  #define AI_PASSIVE 0x1 /* Flag for hints are for getaddrinfo() */
790 
791  /* getnameinfo() flags and values. We have to use slightly different
792  values for these under Windows because Windows uses different values
793  for these than anyone else, and even if we're not on an explicitly
794  IPv6-enabled system we could still end up dynamically pulling in the
795  required libraries, so we need to ensure that we're using the same flag
796  values that Windows does */
797  #ifdef __WINDOWS__
798  #define NI_NUMERICHOST 0x2 /* Return numeric form of host addr.*/
799  #define NI_NUMERICSERV 0x8 /* Return numeric form of host port */
800  #else
801  #define NI_NUMERICHOST 0x1 /* Return numeric form of host addr.*/
802  #define NI_NUMERICSERV 0x2 /* Return numeric form of host port */
803  #endif /* __WINDOWS__ */
804 
805  /* get/setsockopt() flags and values. Again, we have to use slightly
806  different values for Windows in some cases */
807  #define IPPROTO_IPV6 41 /* IPv6 */
808  #ifdef __WINDOWS__
809  #define IPV6_V6ONLY 27 /* Force dual stack to use only IPv6 */
810  #else
811  #define IPV6_V6ONLY 26 /* Force dual stack to use only IPv6 */
812  #endif /* __WINDOWS__ */
813 
814  /* If there's no getaddrinfo() available and we're not using dynamic
815  linking, use an emulation of the function */
816  #ifndef __WINDOWS__
817  #define getaddrinfo my_getaddrinfo
818  #define freeaddrinfo my_freeaddrinfo
819  #define getnameinfo my_getnameinfo
820 
821  static int my_getaddrinfo( const char *nodename, const char *servname,
822  const struct addrinfo *hints,
823  struct addrinfo **res );
824  static void my_freeaddrinfo( struct addrinfo *ai );
825  static int my_getnameinfo( const struct sockaddr *sa, SIZE_TYPE salen,
826  char *node, SIZE_TYPE nodelen,
827  char *service, SIZE_TYPE servicelen,
828  int flags );
829 
830  /* Windows uses the Pascal calling convention for these functions, we
831  hide this behind a define that becomes a no-op on non-Windows
832  systems */
833  #define SOCKET_API
834  #endif /* __WINDOWS__ */
835 #else
836  /* IPV6_V6ONLY isn't universally defined under Windows even if IPv6
837  support is available. This occurs for some x86-64 builds (although
838  strangely it is present for straight x86 builds), and also for older
839  WinCE builds, in which case we have to explicitly define it
840  ourselves */
841  #if defined( __WINDOWS__ ) && !defined( IPV6_V6ONLY ) && \
842  ( defined( _M_X64 ) || defined( __WINCE__ ) )
843  #define IPV6_V6ONLY 27 /* Force dual stack to use only IPv6 */
844  #endif /* Some Windows build environments */
845 #endif /* IPv6 */
846 
847 /* A subset of the above for BeOS with the BONE network stack. See the
848  full IPv6 version above for descriptions of the entries */
849 
850 #if defined( __BEOS__ ) && defined( BONE_VERSION )
851  #undef IPv6 /* We really don't do IPv6 */
852 
853  typedef char SOCKADDR_STORAGE[ 128 ];
854 
855  #define getaddrinfo my_getaddrinfo
856  #define freeaddrinfo my_freeaddrinfo
857  #define getnameinfo my_getnameinfo
858 
859  static int my_getaddrinfo( const char *nodename, const char *servname,
860  const struct addrinfo *hints,
861  struct addrinfo **res );
862  static void my_freeaddrinfo( struct addrinfo *ai );
863  static int my_getnameinfo( const struct sockaddr *sa, SIZE_TYPE salen,
864  char *node, SIZE_TYPE nodelen,
865  char *service, SIZE_TYPE servicelen,
866  int flags );
867 #endif /* BeOS with BONE */
868 
869 /* Values defined in some environments but not in others. T_SRV and
870  NS_SRVFIXEDSZ are used for DNS SRV lookups. Newer versions of bind use a
871  ns_t_srv enum for T_SRV but since we can't autodetect this via the
872  preprocessor we always define T_SRV ourselves */
873 
874 #ifndef T_SRV
875  #define T_SRV 33
876 #endif /* !T_SRV */
877 #ifndef NS_SRVFIXEDSZ
878  #define NS_SRVFIXEDSZ ( NS_RRFIXEDSZ + 6 )
879 #endif /* !NS_SRVFIXEDSZ */
880 #ifndef AI_ADDRCONFIG
881  #define AI_ADDRCONFIG 0
882 #endif /* !AI_ADDRCONFIG */
883 #ifndef AI_NUMERICSERV
884  #define AI_NUMERICSERV 0
885 #endif /* !AI_NUMERICSERV */
886 
887 /* gethostbyname is a problem function because the standard version is non-
888  thread-safe due to the use of static internal storage to contain the
889  returned host info. Some OSes (Windows, PHUX >= 11.0, OSF/1 >= 4.0,
890  Aches >= 4.3) don't have a problem with this because they use thread
891  local storage, but others either require the use of nonstandard _r
892  variants or simply don't handle it at all. To make it even more
893  entertaining, there are at least three different variations of the _r
894  form:
895 
896  Linux (and glibc systems in general, but not BeOS with BONE):
897 
898  int gethostbyname_r( const char *name, struct hostent *result_buf,
899  char *buf, size_t buflen, struct hostent **result,
900  int *h_errnop);
901 
902  Slowaris >= 2.5.1, IRIX >= 6.5, QNX:
903 
904  struct hostent *gethostbyname_r( const char *name,
905  struct hostent *result, char *buffer,
906  int buflen, int *h_errnop );
907 
908  OSF/1, Aches (deprecated, see above):
909 
910  int gethostbyname_r( const char *name, struct hostent *hptr,
911  struct hostent_data *hdptr );
912 
913  To work around this mess, we define macros for thread-safe versions of
914  gethostbyname that can be retargeted to the appropriate function as
915  required */
916 
917 #if defined( USE_THREADS ) && defined( __GLIBC__ ) && ( __GLIBC__ >= 2 ) && \
918  ( !defined( __BEOS__ ) || !defined( BONE_VERSION ) )
919  #define gethostbyname_vars() \
920  char hostBuf[ 4096 ]; \
921  struct hostent hostEnt;
922  #define gethostbyname_threadsafe( hostName, hostEntPtr, hostErrno ) \
923  if( gethostbyname_r( hostName, &hostEnt, hostBuf, 4096, &hostEntPtr, &hostErrno ) < 0 ) \
924  hostEntPtr = NULL
925 #elif defined( USE_THREADS ) && \
926  ( ( defined( sun ) && OSVERSION > 4 ) || \
927  ( defined( __sgi ) && OSVERSION >= 6 ) || defined( __QNX__ ) )
928  #define gethostbyname_vars() \
929  char hostBuf[ 4096 ]; \
930  struct hostent hostEnt;
931  #define gethostbyname_threadsafe( hostName, hostEntPtr, hostErrno ) \
932  hostEntPtr = gethostbyname_r( hostName, &hostEnt, hostBuf, 4096, &hostErrno )
933 #else
934  #define gethostbyname_vars()
935  #define gethostbyname_threadsafe( hostName, hostEntPtr, hostErrno ) \
936  hostEntPtr = gethostbyname( hostName ); \
937  hostErrno = h_errno;
938 #endif /* Various gethostbyname variants */
939 
940 /****************************************************************************
941 * *
942 * Non-blocking I/O Defines *
943 * *
944 ****************************************************************************/
945 
946 /* The traditional way to set a descriptor to nonblocking mode was an
947  ioctl with FIONBIO, however Posix prefers the O_NONBLOCK flag for fcntl
948  so we use this if it's available.
949 
950  Unfortunately if we haven't got the fcntl() interface available there's
951  no way to determine whether a socket is non-blocking or not, which is
952  particularly troublesome for Windows where we need to ensure that the
953  socket is blocking in order to avoid Winsock bugs with nonblocking
954  sockets. Although WSAIoctl() would appear to provide an interface for
955  obtaining the nonblocking status, it doesn't provide any more
956  functionality than ioctlsocket(), returning an error if we try and read
957  the FIONBIO value.
958 
959  If we're just using this as a basic valid-socket check we could also use
960  ( GetFileType( ( HANDLE ) stream->netSocket ) == FILE_TYPE_PIPE ) ? 0 : \
961  WSAEBADF to check that it's a socket, but there's a bug under all Win9x
962  versions for which GetFileType() on a socket returns FILE_TYPE_UNKNOWN,
963  so we can't reliably detect a socket with this. In any case though
964  ioctlsocket() will return WSAENOTSOCK if it's not a socket, so this is
965  covered by the default handling anyway.
966 
967  The best that we can do in this case is to force the socket to be
968  blocking, which somewhat voids the guarantee that we leave the socket as
969  we found it, but OTOH if we've been passed an invalid socket the caller
970  will have to abort and fix the problem anyway, so changing the socket
971  state isn't such a big deal.
972 
973  BeOS is even worse, not only is there no way to determine whether a
974  socket is blocking or not, it'll also quite happily perform socket
975  functions like setsockopt() on a file descriptor (for example stdout),
976  so we can't even use this as a check for socket validity as it is under
977  other OSes. Because of this the check socket function will always
978  indicate that something vaguely handle-like is a valid socket.
979 
980  When we get the nonblocking status, if there's an error getting the
981  status we report it as a non-blocking socket, which results in the socket
982  being reported as invalid, the same as if it were a a genuine non-
983  blocking socket.
984 
985  If we're using the ioctlsocket() interface we make the argument an
986  unsigned long, in most cases this is a 'void *' but under Windows it's
987  an 'unsigned long *' so we use the most restrictive type */
988 
989 #if defined( F_GETFL ) && defined( F_SETFL ) && defined( O_NONBLOCK )
990  #define getSocketNonblockingStatus( socket, value ) \
991  { \
992  value = fcntl( socket, F_GETFL, 0 ); \
993  value = ( isSocketError( value ) || ( value & O_NONBLOCK ) ) ? \
994  TRUE : FALSE; \
995  }
996  #define setSocketNonblocking( socket ) \
997  { \
998  const int flags = fcntl( socket, F_GETFL, 0 ); \
999  fcntl( socket, F_SETFL, flags | O_NONBLOCK ); \
1000  }
1001  #define setSocketBlocking( socket ) \
1002  { \
1003  const int flags = fcntl( socket, F_GETFL, 0 ); \
1004  fcntl( socket, F_SETFL, flags & ~O_NONBLOCK ); \
1005  }
1006 #elif defined( FIONBIO )
1007  #define getSocketNonblockingStatus( socket, value ) \
1008  { \
1009  unsigned long nonBlock = FALSE; \
1010  value = ioctlsocket( socket, FIONBIO, &nonBlock ); \
1011  value = isSocketError( value ) ? TRUE : FALSE; \
1012  }
1013  #define setSocketNonblocking( socket ) \
1014  { \
1015  unsigned long nonBlock = TRUE; \
1016  ioctlsocket( socket, FIONBIO, &nonBlock ); \
1017  }
1018  #define setSocketBlocking( socket ) \
1019  { \
1020  unsigned long nonBlock = FALSE; \
1021  ioctlsocket( socket, FIONBIO, &nonBlock ); \
1022  }
1023 #elif defined( __AMX__ ) || defined( __BEOS__ )
1024  #define getSocketNonblockingStatus( socket, value ) \
1025  { \
1026  int nonBlock = FALSE; \
1027  setsockopt( socket, SOL_SOCKET, SO_NONBLOCK, &nonBlock, sizeof( int ) ); \
1028  }
1029  #define setSocketNonblocking( socket ) \
1030  { \
1031  int nonBlock = TRUE; \
1032  setsockopt( socket, SOL_SOCKET, SO_NONBLOCK, &nonBlock, sizeof( int ) ); \
1033  }
1034  #define setSocketBlocking( socket ) \
1035  { \
1036  int nonBlock = FALSE; \
1037  setsockopt( socket, SOL_SOCKET, SO_NONBLOCK, &nonBlock, sizeof( int ) ); \
1038  }
1039 #elif defined( __SYMBIAN32__ )
1040  /* Symbian OS doesn't support nonblocking I/O */
1041  #define getSocketNonblockingStatus( socket, value ) value = 0
1042  #define setSocketNonblocking( socket )
1043  #define setSocketBlocking( socket )
1044 #else
1045  #error Need to create macros to handle nonblocking I/O
1046 #endif /* Handling of blocking/nonblocking sockets */
1047 
1048 /****************************************************************************
1049 * *
1050 * Misc.Functions and Defines *
1051 * *
1052 ****************************************************************************/
1053 
1054 /* DNS dynamic-binding init/shutdown functions */
1055 
1056 #ifdef __WINDOWS__
1057  CHECK_RETVAL \
1058  int initDNS( const INSTANCE_HANDLE hTCP, const INSTANCE_HANDLE hAddr );
1059  void endDNS( const INSTANCE_HANDLE hTCP );
1060  #ifdef USE_DNSSRV
1061  CHECK_RETVAL \
1062  int initDNSSRV( const INSTANCE_HANDLE hTCP );
1063  void endDNSSRV( const INSTANCE_HANDLE hTCP );
1064  #else
1065  #define initDNSSRV( hTCP ) CRYPT_ERROR
1066  #define endDNSSRV( hTCP )
1067  #endif /* USE_DNSSRV */
1068 #endif /* __WINDOWS__ */
1069 
1070 /* Prototypes for functions in dns.c */
1071 
1072 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
1073 int getAddressInfo( INOUT NET_STREAM_INFO *netStream,
1074  OUT_PTR struct addrinfo **addrInfoPtrPtr,
1075  IN_BUFFER_OPT( nameLen ) const char *name,
1076  IN_LENGTH_Z const int nameLen,
1077  IN_PORT const int port, const BOOLEAN isServer );
1078 STDC_NONNULL_ARG( ( 1 ) ) \
1079 void freeAddressInfo( struct addrinfo *addrInfoPtr );
1080 STDC_NONNULL_ARG( ( 1, 3, 5, 6 ) ) \
1081 void getNameInfo( IN_BUFFER( sockAddrLen ) const void *sockAddr,
1082  IN_LENGTH_SHORT_MIN( 8 ) const int sockAddrLen,
1083  OUT_BUFFER( addressMaxLen, *addressLen ) \
1084  char *address, IN_LENGTH_DNS const int addressMaxLen,
1085  OUT_LENGTH_DNS_Z int *addressLen,
1086  OUT_PORT_Z int *port );
1087 
1088 /* Prototypes for functions in dns_srv.c */
1089 
1090 #ifdef USE_DNSSRV
1091  CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4, 5 ) ) \
1092  int findHostInfo( INOUT NET_STREAM_INFO *netStream,
1093  OUT_BUFFER_FIXED( hostNameMaxLen ) char *hostName,
1094  IN_LENGTH_DNS const int hostNameMaxLen,
1095  OUT_PORT_Z int *hostPort,
1096  IN_BUFFER( nameLen ) const char *name,
1097  IN_LENGTH_DNS const int nameLen );
1098 #else
1099  /* If there's no DNS support available in the OS there's not much that we
1100  can do to handle automatic host detection. Setting hostPort as a side-
1101  effect is necessary because the #define otherwise no-ops it out,
1102  leading to declared-but-not-used warnings from some compilers */
1103  #define findHostInfo( netStream, hostName, hostNameLen, hostPort, name, nameLen ) \
1104  setSocketError( netStream, "DNS SRV services not available", 30, \
1105  CRYPT_ERROR_NOTAVAIL, FALSE ); \
1106  memset( hostName, 0, min( 16, hostNameLen ) ); \
1107  *( hostPort ) = 0
1108 #endif /* USE_DNSSRV */
1109 
1110 /* Prototypes for functions in tcp.c */
1111 
1112 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
1113 int getSocketError( NET_STREAM_INFO *netStream,
1114  IN_ERROR const int status,
1115  OUT_INT_Z int *socketErrorCode );
1116 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
1117 int getHostError( NET_STREAM_INFO *netStream, IN_ERROR const int status );
1118 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
1119 int setSocketError( INOUT NET_STREAM_INFO *netStream,
1120  IN_BUFFER( errorMessageLength ) const char *errorMessage,
1121  IN_LENGTH_ERRORMESSAGE const int errorMessageLength,
1122  IN_ERROR const int status, const BOOLEAN isFatal );
1123 
1124 #endif /* USE_TCP */