📄 pgpsockets.c
字号:
/*____________________________________________________________________________
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 + -