📄 pgpsockets.c
字号:
PGPInt32 inNumber)
{
return (PGPProtocolEntry *) getprotobynumber(inNumber);
}
PGPServiceEntry *
PGPGetServiceByName(
const char * inName,
const char * inProtocol)
{
return (PGPServiceEntry *) getservbyname(inName, inProtocol);
}
PGPServiceEntry *
PGPGetServiceByPort(
PGPInt32 inPort,
const char * inProtocol)
{
return (PGPServiceEntry *) getservbyport(inPort, inProtocol);
}
PGPInt32
PGPGetSocketName(
PGPSocketRef inSocketRef,
PGPSocketAddress * outName,
PGPInt32 * ioNameLength)
{
return getsockname( (SOCKET) inSocketRef,
(struct sockaddr *) outName,
ioNameLength);
}
PGPInt32
PGPGetPeerName(
PGPSocketRef inSocketRef,
PGPSocketAddress * outName,
PGPInt32 * ioNameLength)
{
return getpeername( (SOCKET) inSocketRef,
(struct sockaddr *) outName,
ioNameLength);
}
PGPUInt32
PGPDottedToInternetAddress(
const char * inAddress)
{
return inet_addr(inAddress);
}
char *
PGPInternetAddressToDottedString(
PGPInternetAddress inAddress)
{
return inet_ntoa(*((struct in_addr *) &inAddress));
}
PGPInt32
PGPIOControlSocket(
PGPSocketRef inSocketRef,
PGPInt32 inCommand,
PGPUInt32 * ioParam)
{
return ioctlsocket((SOCKET) inSocketRef,
inCommand,
(unsigned long*)ioParam);
}
PGPInt32
PGPGetSocketOptions(
PGPSocketRef inSocketRef,
PGPInt32 inLevel,
PGPInt32 inOptionName,
char * outOptionValue,
PGPInt32 * ioOptionLength)
{
return getsockopt( (SOCKET) inSocketRef,
inLevel,
inOptionName,
outOptionValue,
ioOptionLength);
}
PGPInt32
PGPSetSocketOptions(
PGPSocketRef inSocketRef,
PGPInt32 inLevel,
PGPInt32 inOptionName,
const char * inOptionValue,
PGPInt32 inOptionLength)
{
return setsockopt((SOCKET) inSocketRef,
inLevel,
inOptionName,
inOptionValue,
inOptionLength);
}
PGPError
PGPSocketsEstablishTLSSession(
PGPSocketRef inSocketRef,
PGPtlsSessionRef inTLSSession)
{
PGPError err;
int optval;
int optlen = sizeof(optval);
if (getsockopt((SOCKET) inSocketRef,
SOL_SOCKET,
SO_TYPE,
(char *) &optval,
&optlen) == SOCKET_ERROR) {
err = PGPGetLastSocketsError();
} else if (optval != SOCK_STREAM) {
err = kPGPError_SocketsOperationNotSupported;
} else {
err = PGPtlsSetReceiveCallback( inTLSSession,
PGPSocketsTLSReceive,
inSocketRef);
if (err == kPGPError_NoErr) {
err = PGPtlsSetSendCallback(inTLSSession,
PGPSocketsTLSSend,
inSocketRef);
if (err == kPGPError_NoErr) {
PGPSocketAddressInternet address;
int addressLen = sizeof(address);
err = getpeername((SOCKET) inSocketRef,
(struct sockaddr *) &address,
&addressLen);
if (err == SOCKET_ERROR) {
err = PGPGetLastSocketsError();
} else {
err = PGPtlsSetRemoteUniqueID(inTLSSession,
address.sin_addr.s_addr);
if (err == kPGPError_NoErr) {
err = PGPtlsHandshake(inTLSSession);
if (err == kPGPError_NoErr) {
PGPRMWOLockStartWriting(&sTLSMapLock);
err = PGPAddNode(sTLSMap,
(PGPInt32) inSocketRef,
inTLSSession);
PGPRMWOLockStopWriting(&sTLSMapLock);
} else if (err == kPGPError_TLSUnexpectedClose) {
err = PGPGetLastSocketsError();
if (err == kPGPError_NoErr) {
err = kPGPError_TLSUnexpectedClose;
}
}
}
}
}
}
}
return err;
}
PGPInt32
PGPSocketsTLSReceive(
void * inData,
void * outBuffer,
PGPInt32 inBufferSize)
{
/*
return recv((SOCKET) inData,
(char *) outBuffer,
inBufferSize,
kPGPReceiveFlagNone);
*/
int rc, err = 0;
rc = recv((SOCKET) inData,
(char *) outBuffer,
inBufferSize,
kPGPReceiveFlagNone);
err = errno;
return rc;
}
PGPInt32
PGPSocketsTLSSend(
void * inData,
const void * inBuffer,
PGPInt32 inBufferLength)
{
return send((SOCKET) inData,
(const char *) inBuffer,
inBufferLength,
kPGPSendFlagNone);
}
PGPError
PGPGetLastSocketsError(void)
{
#if PGP_WIN32
return MapPGPSocketsError(WSAGetLastError());
#else
return MapPGPSocketsError(errno);
#endif
}
#if PGP_WIN32
PGPError
PGPSetSocketsIdleEventHandler(
PGPEventHandlerProcPtr inCallback,
PGPUserValue inUserData)
{
PGPRMWOLockStartWriting(&sIdleEventHandlerLock);
if (!PGPThreadSetSpecific(sIdleEventHandlerIndex, inCallback)) {
if (!PGPThreadSetSpecific(sIdleEventHandlerDataIndex, inUserData)) {
if (inCallback != NULL) {
WSASetBlockingHook(SocketsBlockingHook);
} else {
WSAUnhookBlockingHook();
}
} else {
(void) PGPThreadSetSpecific(sIdleEventHandlerIndex, NULL);
}
}
PGPRMWOLockStopWriting(&sIdleEventHandlerLock);
return kPGPError_NoErr;
}
PGPError
PGPGetSocketsIdleEventHandler(
PGPEventHandlerProcPtr * outCallback,
PGPUserValue * outUserData)
{
PGPRMWOLockStartReading(&sIdleEventHandlerLock);
(void) PGPThreadGetSpecific(sIdleEventHandlerIndex, (void *) outCallback);
(void) PGPThreadGetSpecific(sIdleEventHandlerDataIndex,
outUserData);
PGPRMWOLockStopReading(&sIdleEventHandlerLock);
return kPGPError_NoErr;
}
struct SThreadContext {
PGPEventHandlerProcPtr callback;
PGPUserValue callbackData;
};
PGPError
PGPSocketsCreateThreadStorage(
PGPSocketsThreadStorageRef * outPreviousStorage)
{
PGPError err = kPGPError_NoErr;
struct SThreadContext * context = NULL;
PGPValidatePtr(outPreviousStorage);
*outPreviousStorage = NULL;
context = malloc(sizeof(struct SThreadContext));
if (context != NULL) {
err = PGPGetSocketsIdleEventHandler(&context->callback,
&context->callbackData);
} else {
err = kPGPError_OutOfMemory;
}
if (IsPGPError(err) && (context != NULL)) {
free(context);
} else {
*outPreviousStorage = (PGPSocketsThreadStorageRef) context;
}
return err;
}
PGPError
PGPSocketsDisposeThreadStorage(
PGPSocketsThreadStorageRef inPreviousStorage)
{
PGPError err = kPGPError_NoErr;
if (inPreviousStorage != NULL) {
err = PGPSetSocketsIdleEventHandler(
((struct SThreadContext *) inPreviousStorage)->callback,
((struct SThreadContext *) inPreviousStorage)->callbackData);
free(inPreviousStorage);
}
return err;
}
#else /* !PGP_Win32 */
PGPError
PGPSetSocketsIdleEventHandler(
PGPEventHandlerProcPtr inCallback,
PGPUserValue inUserData)
{
(void) inCallback;
(void) inUserData;
return kPGPError_NoErr;
}
PGPError
PGPGetSocketsIdleEventHandler(
PGPEventHandlerProcPtr * outCallback,
PGPUserValue * outUserData)
{
*outUserData = NULL;
*outCallback = NULL;
return kPGPError_NoErr;
}
PGPError
PGPSocketsCreateThreadStorage(
PGPSocketsThreadStorageRef * outPreviousStorage)
{
PGPValidatePtr(outPreviousStorage);
*outPreviousStorage = NULL;
return kPGPError_NoErr;
}
PGPError
PGPSocketsDisposeThreadStorage(
PGPSocketsThreadStorageRef inPreviousStorage)
{
(void) inPreviousStorage;
return kPGPError_NoErr;
}
#endif /* PGP_WIN32 */
PGPError
MapPGPSocketsError(
PGPError inErr)
{
PGPError result = kPGPError_UnknownError;
PGPError pgpError;
PGPError tempError;
if ((inErr > kPGPError_FirstError) && (inErr < kPGPError_Last)) {
result = inErr;
} else {
pgpError = PGPFindNode(sErrorMap, inErr, (PGPUserValue *) &tempError);
if (pgpError == kPGPError_NoErr) {
result = tempError;
}
}
return result;
}
void
InitErrorMap()
{
PGPAddNode(sErrorMap, 0, (PGPUserValue) kPGPError_NoErr);
#if PGP_WIN32
PGPAddNode(sErrorMap, WSANOTINITIALISED,
(PGPUserValue) kPGPError_SocketsNotInitialized);
PGPAddNode(sErrorMap, WSAENETDOWN,
(PGPUserValue) kPGPError_SocketsNetworkDown);
PGPAddNode(sErrorMap, WSAEFAULT,
(PGPUserValue) kPGPError_BadParams);
PGPAddNode(sErrorMap, WSAEINPROGRESS,
(PGPUserValue) kPGPError_SocketsInProgress);
PGPAddNode(sErrorMap, WSAEINVAL,
(PGPUserValue) kPGPError_SocketsNotBound);
PGPAddNode(sErrorMap, WSAENOBUFS,
(PGPUserValue) kPGPError_OutOfMemory);
PGPAddNode(sErrorMap, WSAENOTSOCK,
(PGPUserValue) kPGPError_SocketsNotASocket);
PGPAddNode(sErrorMap, WSAEOPNOTSUPP,
(PGPUserValue) kPGPError_SocketsOperationNotSupported);
PGPAddNode(sErrorMap, WSAEADDRINUSE,
(PGPUserValue) kPGPError_SocketsAddressInUse);
PGPAddNode(sErrorMap, WSAEAFNOSUPPORT,
(PGPUserValue) kPGPError_SocketsAddressFamilyNotSupported);
PGPAddNode(sErrorMap, WSAEADDRNOTAVAIL,
(PGPUserValue) kPGPError_SocketsAddressNotAvailable);
PGPAddNode(sErrorMap, WSAECONNREFUSED,
(PGPUserValue) kPGPError_SocketsNotConnected);
PGPAddNode(sErrorMap, WSAEDESTADDRREQ,
(PGPUserValue) kPGPError_BadParams);
PGPAddNode(sErrorMap, WSAEISCONN,
(PGPUserValue) kPGPError_SocketsAlreadyConnected);
PGPAddNode(sErrorMap, WSAENETUNREACH,
(PGPUserValue) kPGPError_SocketsNetworkDown);
PGPAddNode(sErrorMap, WSAETIMEDOUT,
(PGPUserValue) kPGPError_SocketsTimedOut);
PGPAddNode(sErrorMap, WSAENOPROTOOPT,
(PGPUserValue) kPGPError_BadParams);
PGPAddNode(sErrorMap, WSAEMSGSIZE,
(PGPUserValue) kPGPError_SocketsBufferOverflow);
PGPAddNode(sErrorMap, WSAECONNABORTED,
(PGPUserValue) kPGPError_SocketsNotConnected);
PGPAddNode(sErrorMap, WSAECONNRESET,
(PGPUserValue) kPGPError_SocketsNotConnected);
PGPAddNode(sErrorMap, WSAENETRESET,
(PGPUserValue) kPGPError_SocketsNotConnected);
PGPAddNode(sErrorMap, WSAEPROTONOSUPPORT,
(PGPUserValue) kPGPError_SocketsProtocolNotSupported);
PGPAddNode(sErrorMap, WSAEPROTOTYPE,
(PGPUserValue) kPGPError_SocketsProtocolNotSupported);
PGPAddNode(sErrorMap, WSAESOCKTNOSUPPORT,
(PGPUserValue) kPGPError_BadParams);
PGPAddNode(sErrorMap, WSASYSNOTREADY,
(PGPUserValue) kPGPError_SocketsNetworkDown);
PGPAddNode(sErrorMap, WSAVERNOTSUPPORTED,
(PGPUserValue) kPGPError_BadParams);
PGPAddNode(sErrorMap, WSAHOST_NOT_FOUND,
(PGPUserValue) kPGPError_SocketsHostNotFound);
PGPAddNode(sErrorMap, WSATRY_AGAIN,
(PGPUserValue) kPGPError_SocketsDomainServerError);
PGPAddNode(sErrorMap, WSANO_RECOVERY,
(PGPUserValue) kPGPError_SocketsDomainServerError);
PGPAddNode(sErrorMap, WSANO_DATA,
(PGPUserValue) kPGPError_SocketsDomainServerError);
#endif
#if PGP_UNIX
PGPAddNode(sErrorMap, ENETDOWN,
(PGPUserValue) kPGPError_SocketsNetworkDown);
PGPAddNode(sErrorMap, EFAULT,
(PGPUserValue) kPGPError_BadParams);
PGPAddNode(sErrorMap, EINPROGRESS,
(PGPUserValue) kPGPError_SocketsInProgress);
PGPAddNode(sErrorMap, EINVAL,
(PGPUserValue) kPGPError_SocketsNotBound);
PGPAddNode(sErrorMap, ENOBUFS,
(PGPUserValue) kPGPError_OutOfMemory);
PGPAddNode(sErrorMap, ENOTSOCK,
(PGPUserValue) kPGPError_SocketsNotASocket);
PGPAddNode(sErrorMap, EOPNOTSUPP,
(PGPUserValue) kPGPError_SocketsOperationNotSupported);
PGPAddNode(sErrorMap, EADDRINUSE,
(PGPUserValue) kPGPError_SocketsAddressInUse);
PGPAddNode(sErrorMap, EAFNOSUPPORT,
(PGPUserValue) kPGPError_SocketsAddressFamilyNotSupported);
PGPAddNode(sErrorMap, EADDRNOTAVAIL,
(PGPUserValue) kPGPError_SocketsAddressNotAvailable);
PGPAddNode(sErrorMap, ECONNREFUSED,
(PGPUserValue) kPGPError_SocketsNotConnected);
PGPAddNode(sErrorMap, EDESTADDRREQ,
(PGPUserValue) kPGPError_BadParams);
PGPAddNode(sErrorMap, EISCONN,
(PGPUserValue) kPGPError_SocketsAlreadyConnected);
PGPAddNode(sErrorMap, ENETUNREACH,
(PGPUserValue) kPGPError_SocketsNetworkDown);
PGPAddNode(sErrorMap, ETIMEDOUT,
(PGPUserValue) kPGPError_SocketsTimedOut);
PGPAddNode(sErrorMap, ENOPROTOOPT,
(PGPUserValue) kPGPError_BadParams);
PGPAddNode(sErrorMap, EMSGSIZE,
(PGPUserValue) kPGPError_SocketsBufferOverflow);
PGPAddNode(sErrorMap, ECONNABORTED,
(PGPUserValue) kPGPError_SocketsNotConnected);
PGPAddNode(sErrorMap, ECONNRESET,
(PGPUserValue) kPGPError_SocketsNotConnected);
PGPAddNode(sErrorMap, ENETRESET,
(PGPUserValue) kPGPError_SocketsNotConnected);
PGPAddNode(sErrorMap, EPROTONOSUPPORT,
(PGPUserValue) kPGPError_SocketsProtocolNotSupported);
PGPAddNode(sErrorMap, EPROTOTYPE,
(PGPUserValue) kPGPError_SocketsProtocolNotSupported);
PGPAddNode(sErrorMap, ESOCKTNOSUPPORT,
(PGPUserValue) kPGPError_BadParams);
PGPAddNode(sErrorMap, HOST_NOT_FOUND,
(PGPUserValue) kPGPError_SocketsHostNotFound);
PGPAddNode(sErrorMap, TRY_AGAIN,
(PGPUserValue) kPGPError_SocketsDomainServerError);
PGPAddNode(sErrorMap, NO_RECOVERY,
(PGPUserValue) kPGPError_SocketsDomainServerError);
PGPAddNode(sErrorMap, NO_DATA,
(PGPUserValue) kPGPError_SocketsDomainServerError);
#endif
}
#if PGP_WIN32
BOOL WINAPI
SocketsBlockingHook()
{
PGPEventHandlerProcPtr eventHandler = NULL;
PGPUserValue userValue;
PGPError pgpError;
PGPRMWOLockStartReading(&sIdleEventHandlerLock);
(void) PGPThreadGetSpecific(sIdleEventHandlerIndex, (void**)&eventHandler);
(void) PGPThreadGetSpecific(sIdleEventHandlerDataIndex, &userValue);
PGPRMWOLockStopReading(&sIdleEventHandlerLock);
if (eventHandler != NULL) {
PGPEvent theEvent;
pgpClearMemory(&theEvent, sizeof(theEvent));
theEvent.type = kPGPEvent_SocketsIdleEvent;
pgpError = eventHandler(NULL, &theEvent, userValue);
if (IsPGPError(pgpError)) {
WSACancelBlockingCall();
}
}
return FALSE;
}
#endif /* PGP_WIN32 */
#if PGP_WORDSLITTLEENDIAN
/*
* This fancy int flipping is needed for maximum compatability with 64-bit
* machines, which don't always do the right thing in ntohl, or htonl
* This code correctly flips a 32 bit number on all platforms.
*/
PGPInt32
PGPHostToNetLong(PGPInt32 x)
{
unsigned int y = x;
unsigned char *s = (unsigned char *)&y;
return ((int)s[0]) << 24 | ((int)s[1]) << 16
| ((int)s[2]) << 8 | ((int)s[3]);
}
PGPInt16
PGPHostToNetShort(PGPInt16 x)
{
return htons(x);
}
PGPInt32
PGPNetToHostLong(PGPInt32 x)
{
unsigned int y = x;
unsigned char *s = (unsigned char *)&y;
return ((int)s[0]) << 24 | ((int)s[1]) << 16
| ((int)s[2]) << 8 | ((int)s[3]);
}
PGPInt16
PGPNetToHostShort(PGPInt16 x)
{
return ntohs(x);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -