1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-06 00:13:33 +00:00

Added domain socket support on Linux and MacOS

This commit is contained in:
Bryan Roe
2019-01-11 12:37:59 -08:00
parent b8928208d7
commit eaff1c25e4
3 changed files with 210 additions and 55 deletions

View File

@@ -31,6 +31,11 @@ limitations under the License.
#include "ILibAsyncServerSocket.h"
#include "ILibAsyncSocket.h"
#ifdef _POSIX
#include <sys/socket.h>
#include <sys/un.h>
#endif
#define DEBUGSTATEMENT(x)
#define INET_SOCKADDR_LENGTH(x) ((x==AF_INET6?sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in)))
@@ -621,6 +626,10 @@ ILibAsyncServerSocket_ServerModule ILibCreateAsyncServerSocketModuleWithMemoryEx
struct ILibAsyncServerSocketModule *RetVal;
struct sockaddr_in6 localAddress;
#ifdef WIN32
if (local->sa_family == AF_UNIX) { return(NULL); } // NOT YET SUPPORTED on Windows
#endif
// Instantiate a new AsyncServer module
RetVal = (struct ILibAsyncServerSocketModule*)ILibChain_Link_Allocate(sizeof(struct ILibAsyncServerSocketModule), ServerUserMappedMemorySize);
@@ -636,14 +645,24 @@ ILibAsyncServerSocket_ServerModule ILibCreateAsyncServerSocketModuleWithMemoryEx
RetVal->MaxConnection = MaxConnections;
RetVal->AsyncSockets = (void**)malloc(MaxConnections * sizeof(void*));
if (RetVal->AsyncSockets == NULL) { free(RetVal); ILIBMARKPOSITION(253); return NULL; }
RetVal->portNumber = ntohs(((struct sockaddr_in6*)local)->sin6_port);
RetVal->initialPortNumber = RetVal->portNumber;
// Get our listening socket
if ((RetVal->ListenSocket = socket(((struct sockaddr_in6*)local)->sin6_family, SOCK_STREAM, IPPROTO_TCP)) == -1) { free(RetVal->AsyncSockets); free(RetVal); return 0; }
if (local->sa_family == AF_UNIX)
{
// Get our IPC socket
if ((RetVal->ListenSocket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { free(RetVal->AsyncSockets); free(RetVal); return 0; }
}
else
{
RetVal->portNumber = ntohs(((struct sockaddr_in6*)local)->sin6_port);
RetVal->initialPortNumber = RetVal->portNumber;
// Setup the IPv6 & IPv4 support on same socket
if (((struct sockaddr_in6*)local)->sin6_family == AF_INET6) if (setsockopt(RetVal->ListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&off, sizeof(off)) != 0) ILIBCRITICALERREXIT(253);
// Get our listening socket
if ((RetVal->ListenSocket = socket(((struct sockaddr_in6*)local)->sin6_family, SOCK_STREAM, IPPROTO_TCP)) == -1) { free(RetVal->AsyncSockets); free(RetVal); return 0; }
// Setup the IPv6 & IPv4 support on same socket
if (((struct sockaddr_in6*)local)->sin6_family == AF_INET6) if (setsockopt(RetVal->ListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&off, sizeof(off)) != 0) ILIBCRITICALERREXIT(253);
}
#ifdef SO_NOSIGPIPE
setsockopt(RetVal->ListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&ra, sizeof(int)); // Turn off SIGPIPE if writing to disconnected socket
@@ -656,22 +675,31 @@ ILibAsyncServerSocket_ServerModule ILibCreateAsyncServerSocketModuleWithMemoryEx
// On Linux. Setting the re-use on a TCP socket allows reuse of the socket even in timeout state. Allows for fast stop/start (Not a problem on Windows).
if (setsockopt(RetVal->ListenSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&ra, sizeof(int)) != 0) ILIBCRITICALERREXIT(253);
#endif
// Bind the socket
#if defined(WIN32)
if (bind(RetVal->ListenSocket, local, INET_SOCKADDR_LENGTH(((struct sockaddr_in6*)local)->sin6_family)) != 0) { closesocket(RetVal->ListenSocket); free(RetVal->AsyncSockets); free(RetVal); return 0; }
#else
if (bind(RetVal->ListenSocket, local, INET_SOCKADDR_LENGTH(((struct sockaddr_in6*)local)->sin6_family)) != 0) { close(RetVal->ListenSocket); free(RetVal->AsyncSockets); free(RetVal); return 0; }
if (local->sa_family == AF_UNIX)
{
if (bind(RetVal->ListenSocket, local, SUN_LEN((struct sockaddr_un*)local)) != 0) { close(RetVal->ListenSocket); free(RetVal->AsyncSockets); free(RetVal); return 0; }
}
else
{
if (bind(RetVal->ListenSocket, local, INET_SOCKADDR_LENGTH(((struct sockaddr_in6*)local)->sin6_family)) != 0) { close(RetVal->ListenSocket); free(RetVal->AsyncSockets); free(RetVal); return 0; }
}
#endif
// Fetch the local port number
#if defined(WINSOCK2)
getsockname(RetVal->ListenSocket, (struct sockaddr*)&localAddress, (int*)&receivingAddressLength);
#else
getsockname(RetVal->ListenSocket, (struct sockaddr*)&localAddress, (socklen_t*)&receivingAddressLength);
if (local->sa_family != AF_UNIX) { getsockname(RetVal->ListenSocket, (struct sockaddr*)&localAddress, (socklen_t*)&receivingAddressLength); }
#endif
if (localAddress.sin6_family == AF_INET6) RetVal->portNumber = ntohs(localAddress.sin6_port); else RetVal->portNumber = ntohs(((struct sockaddr_in*)&localAddress)->sin_port);
if (local->sa_family != AF_UNIX)
{
if (localAddress.sin6_family == AF_INET6) RetVal->portNumber = ntohs(localAddress.sin6_port); else RetVal->portNumber = ntohs(((struct sockaddr_in*)&localAddress)->sin_port);
}
// Create our socket pool
for(i = 0; i < MaxConnections; ++i)
{
@@ -710,7 +738,11 @@ void ILibAsyncServerSocket_GetLocal(ILibAsyncServerSocket_ServerModule ServerSoc
socklen_t ssize = (socklen_t)addrLen;
if (getsockname(((struct ILibAsyncServerSocketModule*)ServerSocketModule)->ListenSocket, addr, &ssize) != 0)
{
((struct sockaddr_in6*)addr)->sin6_family = AF_UNSPEC;
ssize = (socklen_t)sizeof(struct sockaddr_in);
if (getsockname(((struct ILibAsyncServerSocketModule*)ServerSocketModule)->ListenSocket, addr, &ssize) != 0)
{
((struct sockaddr_in6*)addr)->sin6_family = AF_UNSPEC;
}
}
}
/*! \fn ILibAsyncServerSocket_GetPortNumber(ILibAsyncServerSocket_ServerModule ServerSocketModule)

View File

@@ -47,6 +47,15 @@ limitations under the License.
#include "ILibAsyncSocket.h"
#include "ILibRemoteLogging.h"
#ifdef _DEBUG
#include "ILibCrypto.h"
#endif
#ifdef _POSIX
#include <sys/socket.h>
#include <sys/un.h>
#endif
#ifndef MICROSTACK_NOTLS
#include <openssl/err.h>
#include <openssl/ssl.h>
@@ -121,6 +130,9 @@ typedef struct ILibAsyncSocketModule
unsigned int PendingBytesToSend;
unsigned int TotalBytesSent;
#ifdef _POSIX
struct sockaddr_un DomainAddress;
#endif
// The IPv4/IPv6 compliant address of the remote endpoint. We are not going to be using IPv6 all the time,
@@ -353,8 +365,10 @@ void ILibAsyncSocket_Destroy(void *socketModule)
// If this is an SSL socket, free the SSL state
if (module->ssl != NULL)
{
SSL_TRACE1("SSL_free()");
SSL_free(module->ssl); // Frees SSL session and BIO buffer at the same time
module->ssl = NULL;
SSL_TRACE2("SSL_free()");
}
#endif
@@ -548,7 +562,9 @@ ILibAsyncSocket_SendStatus ILibAsyncSocket_SendTo_MultiWrite(ILibAsyncSocket_Soc
bufferLen = va_arg(vlist, int);
UserFree = va_arg(vlist, ILibAsyncSocket_MemoryOwnership);
SSL_TRACE1("SSL_write()");
SSL_write(module->ssl, buffer, bufferLen);
SSL_TRACE2("SSL_write()");
if (UserFree == ILibAsyncSocket_MemoryOwnership_CHAIN) { free(buffer); }
}
va_end(vlist);
@@ -669,7 +685,7 @@ ILibAsyncSocket_SendStatus ILibAsyncSocket_SendTo_MultiWrite(ILibAsyncSocket_Soc
else if (module->PendingSend_Tail == NULL && module->FinConnect != 0)
{
// No pending data, so we can try to send now
if (remoteAddress == NULL)
if (remoteAddress == NULL || remoteAddress->sa_family == AF_UNIX)
{
// Set MSG_NOSIGNAL since we don't want to get Broken Pipe signals in Linux, ignored if Windows.
bytesSent = send(module->internalSocket, buffer, bufferLen, MSG_NOSIGNAL);
@@ -754,11 +770,13 @@ void ILibAsyncSocket_Disconnect(ILibAsyncSocket_SocketModule socketModule)
wasssl = module->ssl;
if (module->ssl != NULL)
{
SSL_TRACE1("ILibAsyncSocket_Disconnect()");
SSL_shutdown(module->ssl);
sem_post(&(module->SendLock));
SSL_free(module->ssl); // Frees SSL session and both BIO buffers at the same time
sem_wait(&(module->SendLock));
module->ssl = NULL;
SSL_TRACE2("ILibAsyncSocket_Disconnect()");
}
#endif
@@ -826,7 +844,7 @@ void ILibAsyncSocket_Disconnect(ILibAsyncSocket_SocketModule socketModule)
*/
void ILibAsyncSocket_ConnectTo(void* socketModule, struct sockaddr *localInterface, struct sockaddr *remoteInterface, ILibAsyncSocket_OnInterrupt InterruptPtr, void *user)
{
int flags = 1;
int flags = 1, v;
char *tmp;
struct ILibAsyncSocketModule *module = (struct ILibAsyncSocketModule*)socketModule;
struct sockaddr_in6 any;
@@ -841,9 +859,22 @@ void ILibAsyncSocket_ConnectTo(void* socketModule, struct sockaddr *localInterfa
memset(&(module->RemoteAddress), 0, sizeof(struct sockaddr_in6));
memset(&(module->LocalAddress) , 0, sizeof(struct sockaddr_in6));
memset(&(module->SourceAddress), 0, sizeof(struct sockaddr_in6));
#ifdef _POSIX
memset(&(module->DomainAddress), 0, sizeof(struct sockaddr_un));
#endif
// Setup
memcpy_s(&(module->RemoteAddress), sizeof(struct sockaddr_in6), remoteInterface, INET_SOCKADDR_LENGTH(remoteInterface->sa_family));
if (remoteInterface->sa_family == AF_UNIX)
{
#ifdef _POSIX
memcpy_s(&(module->DomainAddress), sizeof(struct sockaddr_un), remoteInterface, sizeof(struct sockaddr_un));
#endif
module->RemoteAddress.sin6_family = AF_UNIX;
}
else
{
memcpy_s(&(module->RemoteAddress), sizeof(struct sockaddr_in6), remoteInterface, INET_SOCKADDR_LENGTH(remoteInterface->sa_family));
}
module->PendingBytesToSend = 0;
module->TotalBytesSent = 0;
module->PAUSE = 0;
@@ -854,7 +885,7 @@ void ILibAsyncSocket_ConnectTo(void* socketModule, struct sockaddr *localInterfa
module->MallocSize = module->InitialSize;
// If localInterface is NULL, we will assume INADDRANY - IPv4/IPv6 based on remote address
if (localInterface == NULL)
if (localInterface == NULL && module->RemoteAddress.sin6_family != AF_UNIX)
{
memset(&any, 0, sizeof(struct sockaddr_in6));
#ifdef MICROSTACK_PROXY
@@ -867,12 +898,22 @@ void ILibAsyncSocket_ConnectTo(void* socketModule, struct sockaddr *localInterfa
// The local port should always be zero
#ifdef _DEBUG
if (localInterface->sa_family == AF_INET && ((struct sockaddr_in*)localInterface)->sin_port != 0) { PRINTERROR(); ILIBCRITICALEXIT(253); }
if (localInterface->sa_family == AF_INET6 && ((struct sockaddr_in6*)localInterface)->sin6_port != 0) { PRINTERROR(); ILIBCRITICALEXIT(253); }
if (localInterface != NULL)
{
if (localInterface->sa_family == AF_INET && ((struct sockaddr_in*)localInterface)->sin_port != 0) { PRINTERROR(); ILIBCRITICALEXIT(253); }
if (localInterface->sa_family == AF_INET6 && ((struct sockaddr_in6*)localInterface)->sin6_port != 0) { PRINTERROR(); ILIBCRITICALEXIT(253); }
}
#endif
// Allocate a new socket
if ((module->internalSocket = ILibGetSocket(localInterface, SOCK_STREAM, IPPROTO_TCP)) == 0) { ILIBCRITICALEXIT(253); return; }
if (module->RemoteAddress.sin6_family != AF_UNIX)
{
if ((module->internalSocket = ILibGetSocket(localInterface, SOCK_STREAM, IPPROTO_TCP)) == 0) { ILIBCRITICALEXIT(253); return; }
}
else
{
if ((int)(module->internalSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { ILIBCRITICALEXIT(253); return; }
}
// Initialise the buffer pointers, since no data is in them yet.
module->FinConnect = 0;
@@ -882,8 +923,11 @@ void ILibAsyncSocket_ConnectTo(void* socketModule, struct sockaddr *localInterfa
module->BeginPointer = 0;
module->EndPointer = 0;
// Turn on keep-alives for the socket
if (setsockopt(module->internalSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&flags, sizeof(flags)) != 0) ILIBCRITICALERREXIT(253);
if (module->RemoteAddress.sin6_family != AF_UNIX)
{
// Turn on keep-alives for the socket
if (setsockopt(module->internalSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&flags, sizeof(flags)) != 0) ILIBCRITICALERREXIT(253);
}
// Set the socket to non-blocking mode, because we need to play nice and share the MicroStack thread
#if defined(_WIN32_WCE) || defined(WIN32)
@@ -895,9 +939,9 @@ void ILibAsyncSocket_ConnectTo(void* socketModule, struct sockaddr *localInterfa
// Connect the socket, and force the chain to unblock, since the select statement doesn't have us in the fdset yet.
#ifdef MICROSTACK_PROXY
if (module->ProxyAddress.sin6_family != 0)
if (module->ProxyAddress.sin6_family != 0 && module->RemoteAddress.sin6_family != AF_UNIX)
{
if (connect(module->internalSocket, (struct sockaddr*)&(module->ProxyAddress), INET_SOCKADDR_LENGTH(module->ProxyAddress.sin6_family)) != -1)
if ((v=connect(module->internalSocket, (struct sockaddr*)&(module->ProxyAddress), INET_SOCKADDR_LENGTH(module->ProxyAddress.sin6_family))) != -1)
{
// Connect failed. Set a short time and call disconnect.
module->FinConnect = -1;
@@ -907,17 +951,32 @@ void ILibAsyncSocket_ConnectTo(void* socketModule, struct sockaddr *localInterfa
}
else
#endif
if (connect(module->internalSocket, (struct sockaddr*)remoteInterface, INET_SOCKADDR_LENGTH(remoteInterface->sa_family)) != -1)
{
// Connect failed. Set a short time and call disconnect.
module->FinConnect = -1;
ILibLifeTime_Add(module->LifeTime, socketModule, 0, &ILibAsyncSocket_Disconnect, NULL);
return;
}
if (module->RemoteAddress.sin6_family != AF_UNIX)
{
if ((v=connect(module->internalSocket, (struct sockaddr*)remoteInterface, INET_SOCKADDR_LENGTH(remoteInterface->sa_family))) != -1)
{
// Connect failed. Set a short time and call disconnect.
module->FinConnect = -1;
ILibLifeTime_Add(module->LifeTime, socketModule, 0, &ILibAsyncSocket_Disconnect, NULL);
return;
}
}
else
{
#ifdef _POSIX
if ((v=connect(module->internalSocket, (struct sockaddr *)&(module->DomainAddress), SUN_LEN(&(module->DomainAddress)))) < 0)
#endif
{
// Connect failed. Set a short time and call disconnect.
module->FinConnect = -1;
ILibLifeTime_Add(module->LifeTime, socketModule, 0, &ILibAsyncSocket_Disconnect, NULL);
return;
}
}
#ifdef _DEBUG
#ifdef _POSIX
if (errno != EINPROGRESS) // The result of the connect should always be "WOULD BLOCK" on Linux. But sometimes this fails.
if (v != 0 && errno != EINPROGRESS) // The result of the connect should always be "WOULD BLOCK" on Linux. But sometimes this fails.
{
// This happens when the interface is no longer available. Disconnect socket.
module->FinConnect = -1;
@@ -1060,6 +1119,7 @@ void ILibProcessAsyncSocket(struct ILibAsyncSocketModule *Reader, int pendingRea
#ifdef MICROSTACK_TLS_DETECT
if (Reader->ssl != NULL && Reader->TLSChecked == 0)
{
#ifndef __APPLE__
bytesReceived = recv(Reader->internalSocket, Reader->buffer, Reader->MallocSize, MSG_PEEK | MSG_NOSIGNAL);
if (ILibAsyncSocket_TLSDetect(Reader, Reader->buffer, 0, bytesReceived) == 0)
{
@@ -1070,6 +1130,7 @@ void ILibProcessAsyncSocket(struct ILibAsyncSocketModule *Reader, int pendingRea
if (Reader->OnConnect != NULL) Reader->OnConnect(Reader, -1, Reader->user);
}
}
#endif
Reader->TLSChecked = 1;
}
#endif
@@ -1082,18 +1143,32 @@ void ILibProcessAsyncSocket(struct ILibAsyncSocketModule *Reader, int pendingRea
if (Reader->ssl != NULL)
{
BIO_clear_retry_flags(Reader->readBio);
#if defined(WINSOCK2)
bytesReceived = recvfrom(Reader->internalSocket, Reader->readBioBuffer_mem + Reader->readBioBuffer->length, (int)(Reader->readBioBuffer->max - Reader->readBioBuffer->length), 0, (struct sockaddr*)&(Reader->SourceAddress), (int*)&len);
if (Reader->RemoteAddress.sin6_family == AF_UNIX)
{
bytesReceived = recv(Reader->internalSocket, Reader->readBioBuffer_mem + Reader->readBioBuffer->length, (int)(Reader->readBioBuffer->max - Reader->readBioBuffer->length), 0);
}
else
{
bytesReceived = recvfrom(Reader->internalSocket, Reader->readBioBuffer_mem + Reader->readBioBuffer->length, (int)(Reader->readBioBuffer->max - Reader->readBioBuffer->length), 0, (struct sockaddr*)&(Reader->SourceAddress), (int*)&len);
}
#else
bytesReceived = (int)recvfrom(Reader->internalSocket, Reader->readBioBuffer->data + Reader->readBioBuffer->length, (int)(Reader->readBioBuffer->max - Reader->readBioBuffer->length), 0, (struct sockaddr*)&(Reader->SourceAddress), (socklen_t*)&len);
if (Reader->RemoteAddress.sin6_family == AF_UNIX)
{
bytesReceived = (int)recv(Reader->internalSocket, Reader->readBioBuffer->data + Reader->readBioBuffer->length, (int)(Reader->readBioBuffer->max - Reader->readBioBuffer->length), 0);
}
else
{
bytesReceived = (int)recvfrom(Reader->internalSocket, Reader->readBioBuffer->data + Reader->readBioBuffer->length, (int)(Reader->readBioBuffer->max - Reader->readBioBuffer->length), 0, (struct sockaddr*)&(Reader->SourceAddress), (socklen_t*)&len);
}
#endif
if (bytesReceived > 0)
{
Reader->readBioBuffer->length += bytesReceived;
if (Reader->TLSHandshakeCompleted == 0)
{
switch ((sslerror=SSL_do_handshake(Reader->ssl)))
SSL_TRACE1("SSL_handshake()");
switch ((sslerror = SSL_do_handshake(Reader->ssl)))
{
case 0:
// Handshake Failed!
@@ -1108,6 +1183,9 @@ void ILibProcessAsyncSocket(struct ILibAsyncSocketModule *Reader, int pendingRea
if (Reader->OnConnect != NULL)
{
Reader->OnConnect(Reader, -1, Reader->user);
#ifdef _DEBUG
//util_savekeys(Reader->ssl); // SAVES TLS PRIVATE KEYS - WARNING: !!! THIS CODE SHOULD ALWAYS BE COMMENTED OUT !!!!
#endif
}
ILibAsyncSocket_ProcessEncryptedBuffer(Reader);
break;
@@ -1125,9 +1203,11 @@ void ILibProcessAsyncSocket(struct ILibAsyncSocketModule *Reader, int pendingRea
}
break;
}
SSL_TRACE2("SSL_handshake()");
}
else
{
SSL_TRACE1("SSL_read()");
while ((j = SSL_read(Reader->ssl, Reader->buffer + Reader->EndPointer, Reader->MallocSize - Reader->EndPointer))>0)
{
// We got new TLS Data
@@ -1154,6 +1234,7 @@ void ILibProcessAsyncSocket(struct ILibAsyncSocketModule *Reader, int pendingRea
ILibAsyncSocket_ProcessEncryptedBuffer(Reader);
}
}
SSL_TRACE2("SSL_read()");
}
}
if (Reader->readBioBuffer->length == 0)
@@ -1166,12 +1247,29 @@ void ILibProcessAsyncSocket(struct ILibAsyncSocketModule *Reader, int pendingRea
#endif
{
#if defined(WINSOCK2)
bytesReceived = recvfrom(Reader->internalSocket, Reader->buffer + Reader->EndPointer, Reader->MallocSize - Reader->EndPointer, 0, (struct sockaddr*)&(Reader->SourceAddress), (int*)&len);
if (Reader->RemoteAddress.sin6_family == AF_UNIX)
{
bytesReceived = recv(Reader->internalSocket, Reader->buffer + Reader->EndPointer, Reader->MallocSize - Reader->EndPointer, 0);
}
else
{
bytesReceived = recvfrom(Reader->internalSocket, Reader->buffer + Reader->EndPointer, Reader->MallocSize - Reader->EndPointer, 0, (struct sockaddr*)&(Reader->SourceAddress), (int*)&len);
}
#else
bytesReceived = (int)recvfrom(Reader->internalSocket, Reader->buffer + Reader->EndPointer, Reader->MallocSize - Reader->EndPointer, 0, (struct sockaddr*)&(Reader->SourceAddress), (socklen_t*)&len);
if (Reader->RemoteAddress.sin6_family == AF_UNIX)
{
bytesReceived = (int)recv(Reader->internalSocket, Reader->buffer + Reader->EndPointer, Reader->MallocSize - Reader->EndPointer, 0);
}
else
{
bytesReceived = (int)recvfrom(Reader->internalSocket, Reader->buffer + Reader->EndPointer, Reader->MallocSize - Reader->EndPointer, 0, (struct sockaddr*)&(Reader->SourceAddress), (socklen_t*)&len);
}
#endif
ILib6to4((struct sockaddr*)&(Reader->SourceAddress));
ILibRemoteLogging_printf(ILibChainGetLogger(Reader->Transport.ChainLink.ParentChain), ILibRemoteLogging_Modules_Microstack_AsyncSocket, ILibRemoteLogging_Flags_VerbosityLevel_2, "AsyncSocket[%p] recv returned %d", (void*)Reader, bytesReceived);
if (Reader->RemoteAddress.sin6_family != AF_UNIX)
{
ILib6to4((struct sockaddr*)&(Reader->SourceAddress));
ILibRemoteLogging_printf(ILibChainGetLogger(Reader->Transport.ChainLink.ParentChain), ILibRemoteLogging_Modules_Microstack_AsyncSocket, ILibRemoteLogging_Flags_VerbosityLevel_2, "AsyncSocket[%p] recv returned %d", (void*)Reader, bytesReceived);
}
if (bytesReceived > 0)
{
@@ -1481,8 +1579,10 @@ void ILibAsyncSocket_PrivateShutdown(void* socketModule)
#ifndef MICROSTACK_NOTLS
if ((wasssl = module->ssl) != NULL)
{
SSL_TRACE1("ILibAsyncSocket_PrivateShutdown()");
SSL_free(module->ssl); // Frees SSL session and BIO buffer at the same time
module->ssl = NULL;
SSL_TRACE2("ILibAsyncSocket_PrivateShutdown()");
}
#endif
@@ -1568,7 +1668,7 @@ void ILibAsyncSocket_PostSelect(void* socketModule, int slct, fd_set *readset, f
{
serr = 1;
}
else
else if(fd_read!=0)
{
// Fetch the socket error code
#if defined(WINSOCK2)
@@ -1580,12 +1680,13 @@ void ILibAsyncSocket_PostSelect(void* socketModule, int slct, fd_set *readset, f
#ifdef MICROSTACK_PROXY
// Handle proxy, we need to read the proxy response, all of it and not a byte more.
if (module->FinConnect == 1 && module->ProxyState == 1 && serr == 0 && fd_read != 0)
if (module->FinConnect == 1 && module->ProxyState == 1 && serr == 0 && fd_read != 0 && module->RemoteAddress.sin6_family != AF_UNIX)
{
char *ptr1, *ptr2;
int len2, len3;
int len2;
int slen = sizeof(struct sockaddr_in6);
serr = 555; // Fake proxy error
len2 = recv(module->internalSocket, ILibScratchPad2, 1024, MSG_PEEK | MSG_NOSIGNAL); // Klockwork says this could block, but it can't, becuase socket was set to nonblock
len2 = recvfrom(module->internalSocket, ILibScratchPad2, 1024, 0, (struct sockaddr*)&(module->SourceAddress), (socklen_t*)&slen);
if (len2 > 0 && len2 < 1024)
{
ILibScratchPad2[len2] = 0;
@@ -1593,8 +1694,6 @@ void ILibAsyncSocket_PostSelect(void* socketModule, int slct, fd_set *readset, f
ptr2 = strstr(ILibScratchPad2, " 200 ");
if (ptr1 != NULL && ptr2 != NULL && ptr2 < ptr1)
{
len3 = (int)((ptr1 + 4) - ILibScratchPad2);
recv(module->internalSocket, ILibScratchPad2, len3, MSG_NOSIGNAL);
module->FinConnect = 0; // Let pretend we never connected, this will trigger all the connection stuff.
module->ProxyState = 2; // Move the proxy connection state forward.
serr = 0; // Proxy connected collectly.
@@ -1625,11 +1724,14 @@ void ILibAsyncSocket_PostSelect(void* socketModule, int slct, fd_set *readset, f
{
// Connected
len = sizeof(struct sockaddr_in6);
if (module->RemoteAddress.sin6_family != AF_UNIX)
{
#if defined(WINSOCK2)
getsockname(module->internalSocket, (struct sockaddr*)(&module->LocalAddress), (int*)&len);
getsockname(module->internalSocket, (struct sockaddr*)(&module->LocalAddress), (int*)&len);
#else
getsockname(module->internalSocket, (struct sockaddr*)(&module->LocalAddress), (socklen_t*)&len);
getsockname(module->internalSocket, (struct sockaddr*)(&module->LocalAddress), (socklen_t*)&len);
#endif
}
module->FinConnect = 1;
module->PAUSE = 0;
@@ -1644,7 +1746,7 @@ void ILibAsyncSocket_PostSelect(void* socketModule, int slct, fd_set *readset, f
// If this is a proxy connection, send the proxy connect header now.
#ifdef MICROSTACK_PROXY
if (module->ProxyAddress.sin6_family != 0 && module->ProxyState == 0)
if (module->ProxyAddress.sin6_family != 0 && module->ProxyState == 0 && module->RemoteAddress.sin6_family != AF_UNIX)
{
int len2;
ILibInet_ntop((int)(module->RemoteAddress.sin6_family), (void*)&(((struct sockaddr_in*)&(module->RemoteAddress))->sin_addr), ILibScratchPad, 4096);
@@ -1727,7 +1829,7 @@ void ILibAsyncSocket_PostSelect(void* socketModule, int slct, fd_set *readset, f
SEM_TRACK(AsyncSocket_TrackLock("ILibAsyncSocket_PostSelect", 1, module);)
sem_wait(&(module->SendLock));
// Write Handling
if (module->FinConnect > 0 && module->internalSocket != ~0 && fd_write != 0 && module->PendingSend_Head != NULL)
if (module->FinConnect > 0 && module->internalSocket != ~0 && fd_write != 0 && module->PendingSend_Head != NULL && (module->ProxyState != 1))
{
//
// Keep trying to send data, until we are told we can't
@@ -1788,7 +1890,7 @@ void ILibAsyncSocket_PostSelect(void* socketModule, int slct, fd_set *readset, f
else
#endif
{
if (module->PendingSend_Head->remoteAddress.sin6_family == 0)
if (module->PendingSend_Head->remoteAddress.sin6_family == 0 || module->PendingSend_Head->remoteAddress.sin6_family == AF_UNIX)
{
bytesSent = (int)send(module->internalSocket, module->PendingSend_Head->buffer + module->PendingSend_Head->bytesSent, module->PendingSend_Head->bufferSize - module->PendingSend_Head->bytesSent, MSG_NOSIGNAL); // Klocwork reports that this could block while holding a lock... This socket has been set to O_NONBLOCK, so that will never happen
}
@@ -2001,6 +2103,7 @@ SSL* ILibAsyncSocket_SetSSLContextEx(ILibAsyncSocket_SocketModule socketModule,
#ifdef MICROSTACK_TLS_DETECT
module->TLSChecked = server == ILibAsyncSocket_TLS_Mode_Server_with_TLSDetectLogic ? 0 : 1;
#endif
SSL_TRACE1("SetSSLContextEx()");
module->ssl = SSL_new(ssl_ctx);
module->TLSHandshakeCompleted = 0;
module->readBio = BIO_new_mem_buf(module->readBioBuffer_mem, (int)sizeof(module->readBioBuffer_mem));
@@ -2027,6 +2130,7 @@ SSL* ILibAsyncSocket_SetSSLContextEx(ILibAsyncSocket_SocketModule socketModule,
{
SSL_set_accept_state(module->ssl); // Setup server SSL state
}
SSL_TRACE2("SetSSLContextEx()");
return(module->ssl);
}
}
@@ -2118,6 +2222,11 @@ void ILibAsyncSocket_UseThisSocket(ILibAsyncSocket_SocketModule socketModule, in
#endif
}
int ILibAsyncSocket_IsDomainSocket(ILibAsyncSocket_SocketModule socketModule)
{
return(((struct ILibAsyncSocketModule*)socketModule)->RemoteAddress.sin6_family == AF_UNIX ? 1 : 0);
}
/*! \fn ILibAsyncSocket_GetRemoteInterface(ILibAsyncSocket_SocketModule socketModule)
\brief Returns the Remote Interface of a connected session
\param socketModule The ILibAsyncSocket to query
@@ -2154,10 +2263,14 @@ int ILibAsyncSocket_GetLocalInterface(ILibAsyncSocket_SocketModule socketModule,
}
else
{
#if defined(WINSOCK2)
#if defined(WIN32)
getsockname(module->internalSocket, localAddress, (int*)&receivingAddressLength);
#else
getsockname(module->internalSocket, localAddress, (socklen_t*)&receivingAddressLength);
if (getsockname(module->internalSocket, localAddress, (socklen_t*)&receivingAddressLength) < 0)
{
receivingAddressLength = sizeof(struct sockaddr_in);
if (getsockname(module->internalSocket, localAddress, (socklen_t*)&receivingAddressLength) < 0) { receivingAddressLength = 0; }
}
#endif
return receivingAddressLength;
}
@@ -2322,8 +2435,13 @@ int ILibAsyncSocket_TLS_WasHandshakeError(ILibAsyncSocket_SocketModule socketMod
*/
X509 *ILibAsyncSocket_SslGetCert(ILibAsyncSocket_SocketModule socketModule)
{
X509 *ret;
SSL_TRACE1("ILibAsyncSocket_SslGetCert()");
struct ILibAsyncSocketModule *sm = (struct ILibAsyncSocketModule*)socketModule;
return SSL_get_peer_certificate(sm->ssl);
ret = SSL_get_peer_certificate(sm->ssl);
SSL_TRACE2("ILibAsyncSocket_SslGetCert()");
return(ret);
}
//! Get's the Cert Chain presented by the Peer
@@ -2335,7 +2453,11 @@ X509 *ILibAsyncSocket_SslGetCert(ILibAsyncSocket_SocketModule socketModule)
*/
STACK_OF(X509) *ILibAsyncSocket_SslGetCerts(ILibAsyncSocket_SocketModule socketModule)
{
STACK_OF(X509) *ret;
SSL_TRACE1("ILibAsyncSocket_SslGetCerts()");
struct ILibAsyncSocketModule *sm = (struct ILibAsyncSocketModule*)socketModule;
return SSL_get_peer_cert_chain(sm->ssl);
ret = SSL_get_peer_cert_chain(sm->ssl);
SSL_TRACE2("ILibAsyncSocket_SslGetCerts()");
return (ret);
}
#endif

View File

@@ -225,6 +225,7 @@ int ILibAsyncSocket_IsFree(ILibAsyncSocket_SocketModule socketModule);
int ILibAsyncSocket_IsConnected(ILibAsyncSocket_SocketModule socketModule);
int ILibAsyncSocket_GetLocalInterface(ILibAsyncSocket_SocketModule socketModule, struct sockaddr *localAddress);
int ILibAsyncSocket_GetRemoteInterface(ILibAsyncSocket_SocketModule socketModule, struct sockaddr *remoteAddress);
int ILibAsyncSocket_IsDomainSocket(ILibAsyncSocket_SocketModule socketModule);
unsigned short ILibAsyncSocket_GetLocalPort(ILibAsyncSocket_SocketModule socketModule);
void ILibAsyncSocket_Resume(ILibAsyncSocket_SocketModule socketModule);