⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 net_tcp.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************
*																			*
*						cryptlib TCP/IP Interface Routines					*
*						Copyright Peter Gutmann 1998-2003					*
*																			*
****************************************************************************/

#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#if defined( INC_ALL )
  #include "crypt.h"
  #include "stream.h"
#elif defined( INC_CHILD )
  #include "../crypt.h"
  #include "../misc/stream.h"
#else
  #include "crypt.h"
  #include "misc/stream.h"
#endif /* Compiler-specific includes */

#ifdef USE_TCP

#ifdef __BEOS__
  /* If we're building under BeOS the system may have the new(er) BONE
     (BeOs Network Environment) network stack that didn't quite make it into
	 BeOS v5 before the demise of Be Inc but was leaked after Be folded, as
	 was the experimental/developmental Dano release of BeOS, which would
	 have become BeOS 5.1 and also has a newer network stack.  In order to
	 detect this we have to pull in sys/socket.h before we try anything
	 else */
  #include <sys/socket.h>
#endif /* __BEOS__ */

#if defined( __WINDOWS__ )
  #include <winsock2.h>
  #include <ws2tcpip.h>
  #if defined( _MSC_VER ) && ( _MSC_VER > 1300 )
	/* VC++ 7 and newer have IPv6 support included in ws2tcpip.h, VC++ 6
	   can have it bolted-on using the IPv6 Technology Preview but it's
	   not present by default.  In addition the Tech.Preview is quite buggy
	   and unstable, leaking handles and memory and in some cases leading to
	   runaway memory consumption that locks up the machine if the process
	   isn't killed in time, so we don't want to encourage its use */
	 /* #include <tpipv6.h> */	/* From IPv6 Tech.Preview */
  #endif /* VC++ 7 and newer */
  #if defined( _MSC_VER ) && ( _MSC_VER > 1300 )
	/* VC++ 7 and newer have DNS headers */
	#include <windns.h>
  #else
	/* windns.h is quite new and many people don't have it yet, not helped
	   by the fact that it's also changed over time.  For example,
	   DnsRecordListFree() has also been DnsFreeRecordList() and DnsFree()
	   at various times, with the parameters changing to match.  Because of
	   this, we have to define our own (very cut-down) subset of what's in
	   there here.  We define PIP4_ARRAY as a void * since it's only used to
	   specify optional DNS servers to query, we never need this so we just
	   set the parameter to NULL.  As with the DnsXXX functions, PIP4_ARRAY
	   has changed over time.  It was known as PIP_ARRAY in the original
	   VC++ .NET release, but was renamed PIP4_ARRAY for .NET 2003, although
	   some MSDN entries still refer to PIP_ARRAY even in the 2003 version */
	typedef LONG DNS_STATUS;
	typedef void *PIP4_ARRAY;
	typedef DWORD IP4_ADDRESS;
	typedef enum { DnsFreeFlat, DnsFreeRecordList } DNS_FREE_TYPE;
	typedef enum { DnsConfigPrimaryDomainName_W, DnsConfigPrimaryDomainName_A,
				   DnsConfigPrimaryDomainName_UTF8, DnsConfigAdapterDomainName_W,
				   DnsConfigAdapterDomainName_A, DnsConfigAdapterDomainName_UTF8,
				   DnsConfigDnsServerList, DnsConfigSearchList,
				   DnsConfigAdapterInfo, DnsConfigPrimaryHostNameRegistrationEnabled,
				   DnsConfigAdapterHostNameRegistrationEnabled,
				   DnsConfigAddressRegistrationMaxCount, DnsConfigHostName_W,
				   DnsConfigHostName_A, DnsConfigHostName_UTF8,
				   DnsConfigFullHostName_W, DnsConfigFullHostName_A,
				   DnsConfigFullHostName_UTF8 } DNS_CONFIG_TYPE;
	#define DNS_TYPE_A				1
	#define DNS_TYPE_PTR			12
	#define DNS_TYPE_SRV			33
	#define DNS_QUERY_STANDARD		0
	#define DNS_QUERY_BYPASS_CACHE	8
	typedef struct {
		DWORD Section : 2;
		DWORD Delete : 1;
		DWORD CharSet : 2;
		DWORD Unused : 3;
		DWORD Reserved : 24;
		} DNS_RECORD_FLAGS;
	typedef struct {
		IP4_ADDRESS IpAddress;
		} DNS_A_DATA, *PDNS_A_DATA;
	typedef struct {
		LPTSTR pNameHost;
		} DNS_PTR_DATA, *PDNS_PTR_DATA;
	typedef struct {
		LPTSTR pNameTarget;
		WORD wPriority;
		WORD wWeight;
		WORD wPort;
		WORD Pad;
		} DNS_SRV_DATA, *PDNS_SRV_DATA;
	typedef struct _DnsRecord {
		struct _DnsRecord *pNext;
		LPTSTR pName;
		WORD wType;
		WORD wDataLength;
		union {
			DWORD DW;
			DNS_RECORD_FLAGS S;
		} Flags;
		DWORD dwTtl;
		DWORD dwReserved;
		union {
			DNS_A_DATA A;
			DNS_PTR_DATA PTR, Ptr,
						 NS, Ns,
						 CNAME, Cname,
						 MB, Mb,
						 MD, Md,
						 MF, Mf,
						 MG, Mg,
						 MR, Mr;
	#if 0
			DNS_MINFO_DATA MINFO, Minfo,
						   RP, Rp;
			DNS_MX_DATA MX, Mx,
						AFSDB, Afsdb,
						RT, Rt;
			DNS_TXT_DATA HINFO, Hinfo,
						 ISDN, Isdn,
						 TXT, Txt,
						 X25;
			DNS_NULL_DATA Null;
			DNS_WKS_DATA WKS, Wks;
			DNS_AAAA_DATA AAAA;
			DNS_KEY_DATA KEY, Key;
			DNS_SIG_DATA SIG, Sig;
			DNS_ATMA_DATA ATMA, Atma;
			DNS_NXT_DATA NXT, Nxt;
	#endif /* 0 */
			DNS_SRV_DATA SRV, Srv;
	#if 0
			DNS_TKEY_DATA TKEY, Tkey;
			DNS_TSIG_DATA TSIG, Tsig;
			DNS_WINS_DATA WINS, Wins;
			DNS_WINSR_DATA WINSR, WinsR,
						   NBSTAT, Nbstat;
	#endif /* 0 */
			} Data;
		} DNS_RECORD, *PDNS_RECORD;
  #endif /* 0 */

  /* For backwards-compatibility purposes, wspiapi.h overrides the new
     address/name-handling functions introduced for IPv6 with complex
	 macros that substitute inline function calls that try and dynamically
	 load different libraries depending on the Windows version and call
	 various helper functions to provide the same service.  Since we
	 dynamically load the required libraries, we don't need any of this
	 complexity, so we undefine the macros in order to make our own ones
	 work */
  #ifdef getaddrinfo
	#undef freeaddrinfo
	#undef getaddrinfo
	#undef getnameinfo
  #endif /* getaddrinfo defined as macros in wspiapi.h */
#elif defined( __BEOS__ ) && !defined( BONE_VERSION )
  #include <errno.h>
  #include <fcntl.h>
  #include <netdb.h>
  #include <socket.h>

  /* BeOS doesn't define any of the PF_xxx's, howewever it does defines
     some of the AF_xxx equivalents, since these are synonyms we just
	 define the PF_xxx's ourselves */
  #define PF_UNSPEC					0
  #define PF_INET					AF_INET

  /* BeOS doesn't define in_*_t's */
  #define in_addr_t					u_long
  #define in_port_t					u_short

  /* BeOS doesn't define NO_ADDRESS, but NO_DATA is a synonym for this */
  #define NO_ADDRESS				NO_DATA

  /* BeOS doesn't support checking for anything except readability in
	 select() and only supports one or two socket options, so we define
	 our own versions of these functions that no-op out unsupported
	 options */
  #define select( sockets, readFD, writeFD, exceptFD, timeout ) \
		  my_select( sockets, readFD, writeFD, exceptFD, timeout )
  #define getsockopt( socket, level, optname, optval, optlen ) \
		  my_getsockopt( socket, level, optname, optval, optlen )
  #define setsockopt( socket, level, optname, optval, optlen ) \
		  my_setsockopt( socket, level, optname, optval, optlen )

  /* The following options would be required, but aren't provided by BeOS.
     If you're building under a newer BeOS version that supports these
     options, you'll also need to update my_set/setsockopt() to no longer
     no-op them out */
  #define SO_ERROR					-1
  #define TCP_NODELAY				-1
#elif ( defined( __BEOS__ ) && defined( BONE_VERSION ) ) || \
	  defined ( __SYMBIAN32__ ) || defined( __TANDEMOSS__ ) || \
	  defined( __UNIX__ )
  /* C_IN is a cryptlib.h value which is also defined in some versions of
     netdb.h, so we have to undefine it before we include any network
	 header files */
  #undef C_IN
  #include <errno.h>
  #include <fcntl.h>
  #include <netdb.h>
  #if defined( __APPLE__ ) || defined( __BEOS__ ) || \
	  defined( __bsdi__ ) || defined( __FreeBSD__ ) || \
	  defined( __hpux ) || defined( __MVS__ ) || \
	  defined( __OpenBSD__ ) || \
	  ( defined( sun ) && OSVERSION <= 5 ) || \
	  defined( __SYMBIAN32__ ) || defined( __VMCMS__ )
	#include <netinet/in.h>
  #endif /* OS x || BeOS || *BSDs || PHUX || SunOS 4.x/2.5.x || Symbian OS */
  #include <arpa/inet.h>
  #if defined( __APPLE__ ) && !defined( BIND_8_COMPAT )
	/* In OS X 10.3 (Panther), Apple broke the bind interface by changing the
	   BIND_4_COMPAT define to BIND_8_COMPAT ("Apple reinvented the wheel and
	   made it square" is one of the more polite comments on this change).
	   In order to get things to work, we have to define BIND_8_COMPAT here,
	   which forces the inclusion of nameser_compat.h when we include
	   nameser.h.  All (non-Apple) systems automatically define BIND_4_COMPAT
	   to force this inclusion, since Bind9 support (in the form of anything
	   other than the installed binaries) is still pretty rare */
	#define BIND_8_COMPAT
  #endif /* Mac OS X without backwards-compatibility bind define */
  #ifndef __SYMBIAN32__
	#include <arpa/nameser.h>
  #endif /* Symbian OS */
  #if defined( __MVS__ ) || defined( __VMCMS__ )
	/* The following have conflicting definitions in xti.h */
	#undef T_NULL
	#undef T_UNSPEC
  #endif /* MVS || VM */
  /* netinet/tcp.h is a BSD-ism, but all Unixen seem to use this even if
     XPG4 and SUS say it should be in xti.h */
  #if !defined( __MVS__ )
	#include <netinet/tcp.h>
  #endif /* !MVS */
  #ifndef __SYMBIAN32__
	#include <resolv.h>
  #endif /* Symbian OS */
  #ifndef TCP_NODELAY
	#include <xti.h>
	#if defined( __MVS__ ) || defined( __VMCMS__ )
	  /* The following have conflicting definitions in nameser.h */
	  #undef T_NULL
	  #undef T_UNSPEC
	#endif /* MVS || VM */
  #endif /* TCP_NODELAY */
  #ifdef __SCO_VERSION__
	#include <signal.h>
	#ifndef SIGIO
	  #include <sys/signal.h>
	#endif /* SIGIO not defined in signal.h - only from SCO */
  #endif /* UnixWare/SCO */
  #ifdef _AIX
	#include <sys/select.h>
  #endif /* Aches */
  #include <sys/socket.h>
  #include <sys/time.h>
  #include <sys/types.h>
#endif /* OS-specific includes and defines */

/* Now that we've included all of the networking headers, try and guess
   whether this is an IPv6-enabled system.  We can detect this by the
   existence of definitions for the EAI_xxx return values from
   getaddrinfo().  Note that we can't safely detect it using the more
   obvious AF_INET6 since many headers defined this in anticipation of IPv6
   long before the remaining code support was present */

#if defined( EAI_BADFLAGS ) && defined( EAI_NONAME )
  #define IPv6
#endif /* getaddrinfo() return values defined */

/* BeOS with the BONE network stack has the necessary IPv6 defines but no
   actual IPv6 support, so we disable it again */

#if defined( __BEOS__ ) && defined( BONE_VERSION ) && defined( IPv6 )
  #undef IPv6
#endif /* BeOS with BONE */

/* The size of a (v4) IP address and the number of IP addresses we try to
   connect to for a given host, used if we're providing a enumated (IPv4-
   only) getaddrinfo() */

#define IP_ADDR_SIZE	4
#define IP_ADDR_COUNT	16

/* Portability defines */

#ifdef __WINDOWS__
  #define isBadSocket( socket )		( ( socket ) == INVALID_SOCKET )
  #define isSocketError( status )	( ( status ) == SOCKET_ERROR )
  #define isBadAddress( address )	( ( address ) == INADDR_NONE )
  #define isNonblockWarning()		( WSAGetLastError() == WSAEWOULDBLOCK )

  #define getErrorCode()			WSAGetLastError()
  #define getHostErrorCode()		WSAGetLastError()

  /* Windows doesn't define in_*_t's */
  #define in_addr_t					u_long
  #define in_port_t					u_short

  /* Size parameters are int (== size_t) */
  #define SIZE_TYPE					int
#else
  #define INVALID_SOCKET			-1
  #define isBadSocket( socket )		( ( socket ) == -1 )
  #define isSocketError( status )	( ( status ) == -1 )
  #define isBadAddress( address )	( ( address ) == ( in_addr_t ) -1 )
  #if defined( __SYMBIAN32__ )
	/* Symbian OS doesn't support nonblocking I/O */
	#define isNonblockWarning()		0
  #elif defined( __BEOS__ )
	#if defined( BONE_VERSION )
	  /* BONE returns "Operation now in progress" */
	  #define isNonblockWarning()	( errno == EWOULDBLOCK || \
									  errno == 0x80007024 )
	#else
	  /* BeOS, even though it supposedly doesn't support nonblocking
	     sockets, can return EWOULDBLOCK */
	  #define isNonblockWarning()	( errno == EWOULDBLOCK )
	#endif /* BeOS with/without BONE */
  #else
	#define isNonblockWarning()		( errno == EINPROGRESS )
  #endif /* Symbian OS vs.other OSes */

  #define getErrorCode()			errno
  #if ( defined( __MVS__ ) && defined( _OPEN_THREADS ) )
	/* MVS converts this into a hidden function in the presence of threads,
	   but not transparently like other systems */
	#define getHostErrorCode()		( *__h_errno() )
  #else
	#define getHostErrorCode()		h_errno
  #endif /* MVS */

  /* AIX doesn't define sockaddr_storage in its IPv6 headers so we define a
	 placeholder equivalent here */
  #if defined( IPv6 ) && defined( _AIX ) && OSVERSION <= 5
	struct sockaddr_storage {
		union {
			struct sockaddr_in6 bigSockaddrStruct;
			char padding[ 128 ];
			};
		};
  #endif /* AIX IPv6 versions without sockaddr_storage */

  /* The generic sockaddr struct used to reserve storage for protocol-
     specific sockaddr structs.  The IPv4 equivalent is given further
	 down in the IPv6-mapping definitions */
  #ifdef IPv6
	#define SOCKADDR_STORAGE		struct sockaddr_storage

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -