void ChannelUnixCreateFd(int const fd, TChannel ** const channelPP, struct abyss_unix_chaninfo ** const channelInfoPP, const char ** const errorP) { struct sockaddr peerAddr; socklen_t peerAddrLen; int rc; peerAddrLen = sizeof(peerAddrLen); rc = getpeername(fd, &peerAddr, &peerAddrLen); if (rc != 0) { if (errno == ENOTCONN) xmlrpc_asprintf(errorP, "Socket on file descriptor %d is not in " "connected state.", fd); else xmlrpc_asprintf(errorP, "getpeername() failed on fd %d. " "errno=%d (%s)", fd, errno, strerror(errno)); } else { makeChannelInfo(channelInfoPP, peerAddr, peerAddrLen, errorP); if (!*errorP) { makeChannelFromFd(fd, channelPP, errorP); if (*errorP) free(*channelInfoPP); } } }
static void createChannelForAccept(int const acceptedFd, struct sockaddr const peerAddr, TChannel ** const channelPP, void ** const channelInfoPP, const char ** const errorP) { /*---------------------------------------------------------------------------- Make a channel object (TChannel) out of a socket just created by accept() on a listening socket -- i.e. a socket for a client connection. 'acceptedFd' is the file descriptor of the socket. 'peerAddr' is the address of the client, from accept(). -----------------------------------------------------------------------------*/ struct abyss_unix_chaninfo * channelInfoP; makeChannelInfo(&channelInfoP, peerAddr, sizeof(peerAddr), errorP); if (!*errorP) { struct socketUnix * acceptedSocketP; MALLOCVAR(acceptedSocketP); if (!acceptedSocketP) xmlrpc_asprintf(errorP, "Unable to allocate memory"); else { acceptedSocketP->fd = acceptedFd; acceptedSocketP->userSuppliedFd = FALSE; initInterruptPipe(&acceptedSocketP->interruptPipe, errorP); if (!*errorP) { TChannel * channelP; ChannelCreate(&channelVtbl, acceptedSocketP, &channelP); if (!channelP) xmlrpc_asprintf(errorP, "Failed to create TChannel object."); else { *errorP = NULL; *channelPP = channelP; *channelInfoPP = channelInfoP; } if (*errorP) termInterruptPipe(acceptedSocketP->interruptPipe); } if (*errorP) free(acceptedSocketP); } if (*errorP) free(channelInfoP); } }
void ChannelOpensslCreateSsl(SSL * const sslP, TChannel ** const channelPP, struct abyss_openssl_chaninfo ** const channelInfoPP, const char ** const errorP) { assert(sslP); makeChannelInfo(channelInfoPP, sslP, errorP); if (!*errorP) { makeChannelFromSsl(ssl, channelPP, errorP); if (*errorP) { free(*channelInfoPP); } } }
static void createChannelForAccept(int const acceptedWinsock, struct sockaddr const peerAddr, TChannel ** const channelPP, void ** const channelInfoPP, const char ** const errorP) { struct abyss_win_chaninfo * channelInfoP; makeChannelInfo(&channelInfoP, peerAddr, sizeof(peerAddr), errorP); if (!*errorP) { struct socketWin * acceptedSocketP; MALLOCVAR(acceptedSocketP); if (!acceptedSocketP) xmlrpc_asprintf(errorP, "Unable to allocate memory"); else { TChannel * channelP; acceptedSocketP->winsock = acceptedWinsock; acceptedSocketP->userSuppliedWinsock = FALSE; acceptedSocketP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL); ChannelCreate(&channelVtbl, acceptedSocketP, &channelP); if (!channelP) xmlrpc_asprintf(errorP, "Failed to create TChannel object."); else { *errorP = NULL; *channelPP = channelP; *channelInfoPP = channelInfoP; } if (*errorP) { CloseHandle(acceptedSocketP->interruptEvent); free(acceptedSocketP); } } } }
void ChannelWinCreateWinsock(SOCKET const fd, TChannel ** const channelPP, struct abyss_win_chaninfo ** const channelInfoPP, const char ** const errorP) { struct sockaddr peerAddr; socklen_t peerAddrLen; int rc; peerAddrLen = sizeof(peerAddr); rc = getpeername(fd, &peerAddr, &peerAddrLen); if (rc != 0) { int const lastError = WSAGetLastError(); if (lastError == WSAENOTCONN) { /* NOTE: This specific string 'not in connected' is required by one of the rpctest suite items, in abyss.c (line 186), hence the separation of the error messages in this case ... */ xmlrpc_asprintf(errorP, "Socket on file descriptor %d " "is not in connected state. WSAERROR = %d (%s)", fd, lastError, getWSAError(lastError)); } else xmlrpc_asprintf(errorP, "getpeername() failed. WSAERROR = %d (%s)", lastError, getWSAError(lastError)); } else { makeChannelInfo(channelInfoPP, peerAddr, peerAddrLen, errorP); if (!*errorP) { makeChannelFromWinsock(fd, channelPP, errorP); if (*errorP) free(*channelInfoPP); } } }