static PRFileDesc *PushNewLayers(PRFileDesc *stack) { PRDescIdentity tmp_identity; PRFileDesc *layer; PRStatus rv; /* push a dummy layer */ tmp_identity = PR_GetUniqueIdentity("Dummy 1"); layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods()); rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); if (verbosity > quiet) PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); PR_ASSERT(PR_SUCCESS == rv); /* push a data procesing layer */ layer = PR_CreateIOLayerStub(identity, &myMethods); rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); if (verbosity > quiet) PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); PR_ASSERT(PR_SUCCESS == rv); /* push another dummy layer */ tmp_identity = PR_GetUniqueIdentity("Dummy 2"); layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods()); rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); if (verbosity > quiet) PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); PR_ASSERT(PR_SUCCESS == rv); return stack; } /* PushLayer */
static inline NamedPipeInfo* GetNamedPipeInfo(PRFileDesc* aFd) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); MOZ_DIAGNOSTIC_ASSERT(aFd); MOZ_DIAGNOSTIC_ASSERT(aFd->secret); MOZ_DIAGNOSTIC_ASSERT(PR_GetLayersIdentity(aFd) == nsNamedPipeLayerIdentity); if (!aFd || !aFd->secret || PR_GetLayersIdentity(aFd) != nsNamedPipeLayerIdentity) { LOG_NPIO_ERROR("cannot get named pipe info"); return nullptr; } return reinterpret_cast<NamedPipeInfo*>(aFd->secret); }
static PRFileDesc *PushLayer(PRFileDesc *stack) { PRFileDesc *layer = PR_CreateIOLayerStub(identity, &myMethods); PRStatus rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); if (verbosity > quiet) PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); PR_ASSERT(PR_SUCCESS == rv); return stack; } /* PushLayer */
static PRStatus nsSOCKSIOLayerClose(PRFileDesc *fd) { nsSOCKSSocketInfo * info = (nsSOCKSSocketInfo*) fd->secret; PRDescIdentity id = PR_GetLayersIdentity(fd); if (info && id == nsSOCKSIOLayerIdentity) { NS_RELEASE(info); fd->identity = PR_INVALID_IO_LAYER; } return fd->lower->methods->close(fd->lower); }
static PRStatus nsNamedPipeClose(PRFileDesc* aFd) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); if (aFd->secret && PR_GetLayersIdentity(aFd) == nsNamedPipeLayerIdentity) { RefPtr<NamedPipeInfo> info = dont_AddRef(GetNamedPipeInfo(aFd)); info->Disconnect(); aFd->secret = nullptr; aFd->identity = PR_INVALID_IO_LAYER; } MOZ_ASSERT(!aFd->lower); PR_DELETE(aFd); return PR_SUCCESS; }
static PRStatus PR_CALLBACK nsWINCESSLIOLayerClose(PRFileDesc *fd) { nsWINCESSLSocketInfo * info = (nsWINCESSLSocketInfo*) fd->secret; PRDescIdentity id = PR_GetLayersIdentity(fd); if (info && id == nsWINCESSLIOLayerIdentity) { NS_RELEASE(info); fd->identity = PR_INVALID_IO_LAYER; } // closesocket(info->mSocket); // NS_RELEASE(info); // fd->secret = nsnull; return PR_SUCCESS; }
// add SOCKS IO layer to an existing socket nsresult nsSOCKSIOLayerAddToSocket(int32_t family, const char *host, int32_t port, const char *proxyHost, int32_t proxyPort, int32_t socksVersion, uint32_t flags, PRFileDesc *fd, nsISupports** info) { NS_ENSURE_TRUE((socksVersion == 4) || (socksVersion == 5), NS_ERROR_NOT_INITIALIZED); if (firstTime) { //XXX hack until NSPR provides an official way to detect system IPv6 // support (bug 388519) PRFileDesc *tmpfd = PR_OpenTCPSocket(PR_AF_INET6); if (!tmpfd) { ipv6Supported = false; } else { // If the system does not support IPv6, NSPR will push // IPv6-to-IPv4 emulation layer onto the native layer ipv6Supported = PR_GetIdentitiesLayer(tmpfd, PR_NSPR_IO_LAYER) == tmpfd; PR_Close(tmpfd); } nsSOCKSIOLayerIdentity = PR_GetUniqueIdentity("SOCKS layer"); nsSOCKSIOLayerMethods = *PR_GetDefaultIOMethods(); nsSOCKSIOLayerMethods.connect = nsSOCKSIOLayerConnect; nsSOCKSIOLayerMethods.connectcontinue = nsSOCKSIOLayerConnectContinue; nsSOCKSIOLayerMethods.poll = nsSOCKSIOLayerPoll; nsSOCKSIOLayerMethods.bind = nsSOCKSIOLayerBind; nsSOCKSIOLayerMethods.acceptread = nsSOCKSIOLayerAcceptRead; nsSOCKSIOLayerMethods.getsockname = nsSOCKSIOLayerGetName; nsSOCKSIOLayerMethods.getpeername = nsSOCKSIOLayerGetPeerName; nsSOCKSIOLayerMethods.accept = nsSOCKSIOLayerAccept; nsSOCKSIOLayerMethods.listen = nsSOCKSIOLayerListen; nsSOCKSIOLayerMethods.close = nsSOCKSIOLayerClose; firstTime = false; #if defined(PR_LOGGING) gSOCKSLog = PR_NewLogModule("SOCKS"); #endif } LOGDEBUG(("Entering nsSOCKSIOLayerAddToSocket().")); PRFileDesc * layer; PRStatus rv; layer = PR_CreateIOLayerStub(nsSOCKSIOLayerIdentity, &nsSOCKSIOLayerMethods); if (! layer) { LOGERROR(("PR_CreateIOLayerStub() failed.")); return NS_ERROR_FAILURE; } nsSOCKSSocketInfo * infoObject = new nsSOCKSSocketInfo(); if (!infoObject) { // clean up IOLayerStub LOGERROR(("Failed to create nsSOCKSSocketInfo().")); PR_DELETE(layer); return NS_ERROR_FAILURE; } NS_ADDREF(infoObject); infoObject->Init(socksVersion, family, proxyHost, proxyPort, host, flags); layer->secret = (PRFilePrivate*) infoObject; rv = PR_PushIOLayer(fd, PR_GetLayersIdentity(fd), layer); if (rv == PR_FAILURE) { LOGERROR(("PR_PushIOLayer() failed. rv = %x.", rv)); NS_RELEASE(infoObject); PR_DELETE(layer); return NS_ERROR_FAILURE; } *info = static_cast<nsISOCKSSocketInfo*>(infoObject); NS_ADDREF(*info); return NS_OK; }
NS_IMETHODIMP nsWINCESSLSocketProvider::NewSocket(PRInt32 family, const char *host, PRInt32 port, const char *proxyHost, PRInt32 proxyPort, PRUint32 flags, PRFileDesc **result, nsISupports **socksInfo) { static PRBool firstTime = PR_TRUE; if (firstTime) { nsWINCESSLIOLayerIdentity = PR_GetUniqueIdentity("WINCESSL layer"); nsWINCESSLIOLayerMethods = *PR_GetDefaultIOMethods(); nsWINCESSLIOLayerMethods.connect = nsWINCESSLIOLayerConnect; nsWINCESSLIOLayerMethods.close = nsWINCESSLIOLayerClose; nsWINCESSLIOLayerMethods.available = nsWINCESSLIOLayerAvailable; nsWINCESSLIOLayerMethods.write = nsWINCESSLIOLayerWrite; nsWINCESSLIOLayerMethods.read = nsWINCESSLIOLayerRead; nsWINCESSLIOLayerMethods.poll = nsWINCESSLIOLayerPoll; firstTime = PR_FALSE; } PRFileDesc *fd = PR_OpenTCPSocket(family); if (!fd) return NS_ERROR_OUT_OF_MEMORY; PRFileDesc * layer; PRStatus rv; layer = PR_CreateIOLayerStub(nsWINCESSLIOLayerIdentity, &nsWINCESSLIOLayerMethods); if (! layer) return NS_ERROR_UNEXPECTED; nsWINCESSLSocketInfo * infoObject = new nsWINCESSLSocketInfo(); if (!infoObject) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(infoObject); layer->secret = (PRFilePrivate*) infoObject; rv = PR_PushIOLayer(fd, PR_GetLayersIdentity(fd), layer); if (NS_FAILED(rv)) return NS_ERROR_UNEXPECTED; nsresult initrv = infoObject->Init(host, proxyHost, proxyPort); if (NS_FAILED(initrv)) { MessageBox(0, "Can not create ssl socket.", "Can not create ssl socket.", MB_APPLMODAL | MB_TOPMOST | MB_SETFOREGROUND); return NS_ERROR_FAILURE; } *result = fd; *socksInfo = (nsISupports*) (nsITransportSecurityInfo*) infoObject; return NS_OK; }