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

📄 pgpsockets.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	Copyright (C) 1997 Network Associates Inc. and affiliated companies.
	All rights reserved.
	
	
	
	$Id: pgpSockets.c,v 1.25.6.2 1999/06/04 23:33:17 heller Exp $
____________________________________________________________________________*/

#if PGP_WIN32
# include <windows.h>
# include <winsock.h>
# include "PGPsdkNetworkLibPriv.h"
#else
# include <stdio.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <netdb.h>
# include <errno.h>
# include <unistd.h>
# include <stdlib.h>
#endif

#include "pgpConfig.h"
#include "pgpPubTypes.h"
#include "pgpMem.h"
#include "pgpEncode.h"
#include "pgpBinaryTree.h"
#include "pgpRMWOLock.h"

#include "pgpSockets.h"

/* Unix specific things */
#if PGP_UNIX
# define FAR
# define SOCKET_ERROR -1
# define closesocket(x) close((x))
# define ioctlsocket(a,b,c) ioctl((a),(b),(c))
typedef int		SOCKET;
#if PGP_UNIX_LINUX || PGP_UNIX_HPUX
int gethostname (char * name, size_t namelen);
#else
int gethostname (char * name, int namelen);
#endif /* PGP_UNIX_LINUX */
#endif

/* Windows specific things */
#if PGP_WIN32
 static PGPInt32		sIdleEventHandlerIndex = 0;
 static PGPInt32		sIdleEventHandlerDataIndex = 0;
 BOOL WINAPI SocketsBlockingHook();
 static PGPRMWOLock		sIdleEventHandlerLock;
#endif

static PGPInt32				sNumberOfInits = 0;
static PGPMemoryMgrRef		sMemoryMgr = kInvalidPGPMemoryMgrRef;

static PGPBinaryTreeRef		sErrorMap = kInvalidPGPBinaryTreeRef;
static PGPBinaryTreeRef		sTLSMap = kInvalidPGPBinaryTreeRef;

static PGPRMWOLock			sTLSMapLock;

void		InitErrorMap(void);
PGPError	MapPGPSocketsError(PGPError inErr);
PGPInt32	PGPSocketsTLSReceive(void * inData, void * outBuffer,
					 PGPInt32 inBufferSize);
PGPInt32	PGPSocketsTLSSend(void * inData, const void * inBuffer,
				  PGPInt32 inBufferLength);


PGPError
PGPSocketsInit()
{
	PGPError	err = kPGPError_NoErr;

#if PGP_WIN32
	WSADATA	wsaData;
	EnterCriticalSection(&gSocketsInitMutex);
#endif
	
	if (sNumberOfInits == 0) {

#if PGP_WIN32	
		InitializePGPRMWOLock(&sIdleEventHandlerLock);
#endif	
		InitializePGPRMWOLock(&sTLSMapLock);
		err = PGPNewMemoryMgr(0, &sMemoryMgr);
		if (err != kPGPError_NoErr) {
			goto done;
		}
		err = PGPNewBinaryTree(sMemoryMgr, &sErrorMap);
		if (err != kPGPError_NoErr) {
			goto done;
		}
		err = PGPNewBinaryTree(sMemoryMgr, &sTLSMap);
		if (err != kPGPError_NoErr) {
			goto done;
		}
	
#if PGP_WIN32	
		(void) PGPThreadKeyCreate(&sIdleEventHandlerIndex, NULL);
		if (PGPThreadSetSpecific(sIdleEventHandlerIndex, NULL)) {
			err = kPGPError_UnknownError;
			goto done;
		}
		(void) PGPThreadKeyCreate(&sIdleEventHandlerDataIndex, NULL);
		if (PGPThreadSetSpecific(sIdleEventHandlerDataIndex, NULL)) {
			err = kPGPError_UnknownError;
			goto done;
		}
#endif
	
	InitErrorMap();
	
#if PGP_WIN32	
	err = WSAStartup(MAKEWORD(1,1), &wsaData);
	if (err != 0) {
		err = MapPGPSocketsError(err);
		goto done;
	}
#endif
	
	}
	sNumberOfInits++;
	
 done:
#if PGP_WIN32
	LeaveCriticalSection(&gSocketsInitMutex);
#endif	
	return err;
}



void
PGPSocketsCleanup()
{
#if PGP_WIN32
	EnterCriticalSection(&gSocketsInitMutex);
#endif
	
	sNumberOfInits--;
	if (sNumberOfInits == 0) {
#if PGP_WIN32
		WSACleanup();
#endif	
		if (PGPBinaryTreeRefIsValid(sTLSMap)) {
			PGPRMWOLockStartWriting(&sTLSMapLock);
			PGPDisposeBinaryTree(sTLSMap);
			sTLSMap = kInvalidPGPBinaryTreeRef;
			PGPRMWOLockStopWriting(&sTLSMapLock);
		}
		if (PGPBinaryTreeRefIsValid(sErrorMap)) {
			PGPDisposeBinaryTree(sErrorMap);
			sErrorMap = kInvalidPGPBinaryTreeRef;
		}
		if (PGPMemoryMgrRefIsValid(sMemoryMgr)) {
			PGPFreeMemoryMgr(sMemoryMgr);
			sMemoryMgr = kInvalidPGPMemoryMgrRef;
		}
	
#if PGP_WIN32	
		PGPThreadKeyDelete(sIdleEventHandlerIndex);
		sIdleEventHandlerIndex = 0;
		PGPThreadKeyDelete(sIdleEventHandlerDataIndex);
		sIdleEventHandlerDataIndex = 0;
		DeletePGPRMWOLock(&sIdleEventHandlerLock);
#endif
	
		DeletePGPRMWOLock(&sTLSMapLock);
	} else if (sNumberOfInits < 0) {
		sNumberOfInits = 0;
	}

#if PGP_WIN32
	LeaveCriticalSection(&gSocketsInitMutex);
#endif	
}



PGPSocketRef
PGPOpenSocket(
	PGPInt32	inAddressFamily,
	PGPInt32	inSocketType,
	PGPInt32	inSocketProtocol)
{
	return (PGPSocketRef) socket(inAddressFamily, inSocketType,
								 inSocketProtocol);
}




PGPInt32
PGPCloseSocket(
	PGPSocketRef	inSocketRef)
{
	PGPUserValue	unused;
	
	PGPRMWOLockStartWriting(&sTLSMapLock);
	PGPDisposeNode(sTLSMap, (PGPInt32) inSocketRef, &unused);
	PGPRMWOLockStopWriting(&sTLSMapLock);
	return closesocket((SOCKET) inSocketRef);
}



PGPInt32
PGPBindSocket(
	PGPSocketRef				inSocketRef,
	const PGPSocketAddress *	inAddress,
	PGPInt32					inAddressLength)
{
	return bind((SOCKET) inSocketRef,
				(struct sockaddr *) inAddress,
				inAddressLength);
}



PGPInt32
PGPConnect(
	PGPSocketRef				inSocketRef,
	const PGPSocketAddress *	inServerAddress,
	PGPInt32					inAddressLength)
{
	return connect((SOCKET) inSocketRef,
				   (struct sockaddr *) inServerAddress,
				   inAddressLength);
}



PGPInt32
PGPSend(
	PGPSocketRef	inSocketRef,
	const void *	inBuffer,
	PGPInt32		inBufferLength,
	PGPInt32		inFlags)
{
	PGPInt32			result = kPGPSockets_Error;
	PGPError			pgpError;
	PGPtlsSessionRef	tlsSession;
	
	PGPRMWOLockStartReading(&sTLSMapLock);
	pgpError = PGPFindNode(sTLSMap, (PGPInt32) inSocketRef,
						   (PGPUserValue*)&tlsSession);
	PGPRMWOLockStopReading(&sTLSMapLock);
	if (IsntPGPError(pgpError)) {
		pgpError = PGPtlsSend(tlsSession,
							  inBuffer,
							  inBufferLength);
		if (IsntPGPError(pgpError)) {
			result = inBufferLength;
		}
		else if( pgpError == kPGPError_TLSUnexpectedClose )
		{
			result = 0;
		}
		else
		{
#if PGP_WIN32		
			WSASetLastError(pgpError);
#else
			errno = pgpError;
#endif		
		}
	} else {
		result = send((SOCKET) inSocketRef,
					  (char*)inBuffer,
					  inBufferLength,
					  inFlags);
	}
	
	return result;
}



PGPInt32
PGPWrite(
	PGPSocketRef	inSocketRef,
	const void *	inBuffer,
	PGPInt32		inBufferLength)
{
	return PGPSend(inSocketRef, inBuffer, inBufferLength, kPGPSendFlagNone);
}



PGPInt32
PGPSendTo(
	PGPSocketRef		inSocketRef,
	const void *		inBuffer,
	PGPInt32			inBufferLength,
	PGPInt32			inFlags,
	PGPSocketAddress *	inAddress,
	PGPInt32			inAddressLength)
{
	return sendto((SOCKET) inSocketRef,
				  (char *) inBuffer,
				  inBufferLength,
				  inFlags,
				  (struct sockaddr *) inAddress,
				  inAddressLength);
}



PGPInt32
PGPReceive(
	PGPSocketRef	inSocketRef,
	void *			outBuffer,
	PGPInt32		inBufferSize,
	PGPInt32		inFlags)
{
	PGPInt32			result = kPGPSockets_Error;
	PGPError			pgpError;
	PGPtlsSessionRef	tlsSession;
	PGPSize				bufferSize = inBufferSize;
	
	PGPRMWOLockStartReading(&sTLSMapLock);
	pgpError = PGPFindNode(sTLSMap, (PGPInt32) inSocketRef,
						   (PGPUserValue*) &tlsSession);
	PGPRMWOLockStopReading(&sTLSMapLock);
	if (IsntPGPError(pgpError)) {
		pgpError = PGPtlsReceive(tlsSession,
								 outBuffer,
								 &bufferSize);
		if (IsntPGPError(pgpError)) {
			result = bufferSize;
		}
		else if( pgpError == kPGPError_TLSUnexpectedClose )
		{
			result = 0;
		}
		else
		{
#if PGP_WIN32		
			WSASetLastError(pgpError);
#else
			errno = pgpError;
#endif		
		}
	} else {
		result = recv((SOCKET) inSocketRef,
					  (char *) outBuffer,
					  inBufferSize,
					  inFlags);
	}
	
	return result;
}



PGPInt32
PGPRead(
	PGPSocketRef	inSocketRef,
	void *			outBuffer,
	PGPInt32		inBufferSize)
{
	return PGPReceive(inSocketRef,
					  outBuffer,
					  inBufferSize,
					  kPGPReceiveFlagNone);
}



PGPInt32
PGPReceiveFrom(
	PGPSocketRef		inSocketRef,
	void *				outBuffer,
	PGPInt32			inBufferSize,
	PGPInt32			inFlags,
	PGPSocketAddress *	outAddress,
	PGPInt32 *			ioAddressLength)
{
	return recvfrom(	(SOCKET) inSocketRef,
						(char *) outBuffer,
						inBufferSize,
						inFlags,
						(struct sockaddr *) outAddress,
						ioAddressLength);
}



PGPInt32
PGPListen(
	PGPSocketRef	inSocketRef,
	PGPInt32		inMaxBacklog)
{
	return listen((SOCKET) inSocketRef, inMaxBacklog);
}



PGPSocketRef
PGPAccept(
	PGPSocketRef		inSocketRef,
	PGPSocketAddress *	outAddress,
	PGPInt32 *			ioAddressLength)
{
	return (PGPSocketRef) accept(	(SOCKET) inSocketRef,
									(struct sockaddr FAR *) outAddress,
									ioAddressLength);
}


PGPInt32
PGPSelect(
	PGPInt32			inNumSetCount,
	PGPSocketSet *		ioReadSet,
	PGPSocketSet *		ioWriteSet,
	PGPSocketSet *		ioErrorSet,
	const PGPSocketsTimeValue *	inTimeout)
{
	PGPUInt16			i;
	PGPError			pgpError;
	PGPtlsSessionRef	tlsSession;

#ifndef PGP_MACINTOSH

	/* Check to see if any TLS sockets are present in the Read set.  If so, */
	/*   and there's still buffered data, use that instead of sitting on */
	/*   select. */
	if (ioReadSet != NULL) {
		PGPRMWOLockStartReading(&sTLSMapLock);
#ifdef PGP_WIN32
		for (i = 0; i < ioReadSet->fd_count; i++) {
			if (PGPSOCKETSET_ISSET(ioReadSet->fd_array[i], ioReadSet)) {
				pgpError = PGPFindNode(sTLSMap, 
									   (PGPInt32) ioReadSet->fd_array[i],
								   	   (PGPUserValue*)&tlsSession);
#elif defined(PGP_UNIX)
		for (i = 0; i < inNumSetCount; i++) {
			if (PGPSOCKETSET_ISSET(i, ioReadSet)) {
				pgpError = PGPFindNode(sTLSMap, (PGPInt32) i,
								   (PGPUserValue*)&tlsSession);
#endif
				if (IsntPGPError(pgpError) 
					&& PGPtlsReceiveBufferSize(tlsSession) > 0) {

					PGPRMWOLockStopReading(&sTLSMapLock);
					PGPSOCKETSET_ZERO(ioReadSet);
					if (ioWriteSet != NULL)
						PGPSOCKETSET_ZERO(ioWriteSet);
					if (ioErrorSet != NULL)
						PGPSOCKETSET_ZERO(ioErrorSet);
					PGPSOCKETSET_SET(i, ioReadSet);
					return 1;
				}
			}
		}
		PGPRMWOLockStopReading(&sTLSMapLock);
	}
#endif

	return select(inNumSetCount,
				  (fd_set *) ioReadSet,
				  (fd_set *) ioWriteSet,
				  (fd_set *) ioErrorSet,
				  (struct timeval *) inTimeout);
}


#if PGP_WIN32
PGPInt32
__PGPSocketsIsSet(
	PGPSocketRef	inSocketRef,
	PGPSocketSet *	inSocketSet)
{
	PGPInt16 	result = 0;
	PGPUInt16	i;
	
	for (i = 0; i < inSocketSet->fd_count; i++) {
		if (inSocketSet->fd_array[i] == (SOCKET) inSocketRef) {
			result = 1;
			break;
		}
	}
	
	return result;
}
#endif


PGPHostEntry *
PGPGetHostByName(
	const char * inName)
{
	struct hostent *hjet = 0;
	
	hjet = gethostbyname(inName);
	
	return (PGPHostEntry *) hjet;
}



PGPHostEntry *
PGPGetHostByAddress(
	const char *	inAddress,
	PGPInt32		inLength,
	PGPInt32		inType)
{
	return (PGPHostEntry *) gethostbyaddr(inAddress, inLength, inType);
}



PGPInt32
PGPGetHostName(
	char *		outName,
	PGPInt32	inNameLength)
{
	return gethostname(outName, inNameLength);
}



PGPProtocolEntry *
PGPGetProtocolByName(
	const char *	inName)
{
	return (PGPProtocolEntry *) getprotobyname(inName);
}



PGPProtocolEntry *
PGPGetProtocolByNumber(
	PGPInt32	inNumber)
{
	return (PGPProtocolEntry *) getprotobynumber(inNumber);
}



PGPServiceEntry *
PGPGetServiceByName(
	const char *	inName,
	const char *	inProtocol)

⌨️ 快捷键说明

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