NS_IMETHODIMP nsSOCKSSocketProvider::NewSocket(PRInt32 family, const char *host, PRInt32 port, const char *proxyHost, PRInt32 proxyPort, PRUint32 flags, PRFileDesc **result, nsISupports **socksInfo) { PRFileDesc *sock; sock = PR_OpenTCPSocket(family); if (!sock) return NS_ERROR_OUT_OF_MEMORY; nsresult rv = nsSOCKSIOLayerAddToSocket(family, host, port, proxyHost, proxyPort, mVersion, flags, sock, socksInfo); if (NS_SUCCEEDED(rv)) { *result = sock; return NS_OK; } return NS_ERROR_SOCKET_CREATE_FAILED; }
void nsSOCKSSocketInfo::FixupAddressFamily(PRFileDesc *fd, PRNetAddr *proxy) { int32_t proxyFamily = PR_NetAddrFamily(&mInternalProxyAddr); // Do nothing if the address family is already matched if (proxyFamily == mDestinationFamily) { return; } // If the system does not support IPv6 and the proxy address is IPv6, // We can do nothing here. if (proxyFamily == PR_AF_INET6 && !ipv6Supported) { return; } // If the system does not support IPv6 and the destination address is // IPv6, convert IPv4 address to IPv4-mapped IPv6 address to satisfy // the emulation layer if (mDestinationFamily == PR_AF_INET6 && !ipv6Supported) { proxy->ipv6.family = PR_AF_INET6; proxy->ipv6.port = mInternalProxyAddr.inet.port; uint8_t *proxyp = proxy->ipv6.ip.pr_s6_addr; memset(proxyp, 0, 10); memset(proxyp + 10, 0xff, 2); memcpy(proxyp + 12,(char *) &mInternalProxyAddr.inet.ip, 4); // mDestinationFamily should not be updated return; } // Get an OS native handle from a specified FileDesc PROsfd osfd = PR_FileDesc2NativeHandle(fd); if (osfd == -1) { return; } // Create a new FileDesc with a specified family PRFileDesc *tmpfd = PR_OpenTCPSocket(proxyFamily); if (!tmpfd) { return; } PROsfd newsd = PR_FileDesc2NativeHandle(tmpfd); if (newsd == -1) { PR_Close(tmpfd); return; } // Must succeed because PR_FileDesc2NativeHandle succeeded fd = PR_GetIdentitiesLayer(fd, PR_NSPR_IO_LAYER); MOZ_ASSERT(fd); // Swap OS native handles PR_ChangeFileDescNativeHandle(fd, newsd); PR_ChangeFileDescNativeHandle(tmpfd, osfd); // Close temporary FileDesc which is now associated with // old OS native handle PR_Close(tmpfd); mDestinationFamily = proxyFamily; }
nsresult TryConnect(PRFileDesc **result) { PRFileDesc *fd; PRNetAddr addr; PRSocketOptionData opt; nsresult rv = NS_ERROR_FAILURE; fd = PR_OpenTCPSocket(PR_AF_LOCAL); if (!fd) goto end; addr.local.family = PR_AF_LOCAL; IPC_GetDefaultSocketPath(addr.local.path, sizeof(addr.local.path)); // blocking connect... will fail if no one is listening. if (PR_Connect(fd, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) goto end; #ifdef VBOX if (PR_GetEnv("TESTBOX_UUID")) fprintf(stderr, "IPC socket path: %s\n", addr.local.path); LogRel(("IPC socket path: %s\n", addr.local.path)); #endif // make socket non-blocking opt.option = PR_SockOpt_Nonblocking; opt.value.non_blocking = PR_TRUE; PR_SetSocketOption(fd, &opt); // do some security checks on connection socket... if (DoSecurityCheck(fd, addr.local.path) != PR_SUCCESS) goto end; *result = fd; return NS_OK; end: if (fd) PR_Close(fd); return rv; }
int main(int argc, char **argv) { PRFileDesc *listenSock; PRNetAddr addr; PRUint16 port; listenSock = PR_OpenTCPSocket(PR_AF_INET6); if (NULL == listenSock) { fprintf(stderr, "PR_OpenTCPSocket failed\n"); exit(1); } memset(&addr, 0, sizeof(addr)); if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) { fprintf(stderr, "PR_SetNetAddr failed\n"); exit(1); } if (PR_Bind(listenSock, &addr) == PR_FAILURE) { fprintf(stderr, "PR_Bind failed\n"); exit(1); } if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) { fprintf(stderr, "PR_GetSockName failed\n"); exit(1); } port = PR_ntohs(addr.ipv6.port); if (PR_Listen(listenSock, 5) == PR_FAILURE) { fprintf(stderr, "PR_Listen failed\n"); exit(1); } fprintf(stderr, "Running the test with local threads\n"); RunTest(PR_LOCAL_THREAD, listenSock, port); fprintf(stderr, "Running the test with global threads\n"); RunTest(PR_GLOBAL_THREAD, listenSock, port); if (PR_Close(listenSock) == PR_FAILURE) { fprintf(stderr, "PR_Close failed\n"); exit(1); } printf("PASS\n"); return 0; }
/** Create socket. If ssl is >0, socket is ssl enabled. @param ssl Enable ssl (Client, SSL2+3, no TLS, compatible hello) if PR_TRUE, otherwise no. @param ipv6 New socket will be IPv4 if this value is 0, otherwise it will be ipv6 @return NULL on error, otherwise socket. */ static PRFileDesc *create_socket(int ssl,int ipv6) { PRFileDesc *res_socket; res_socket=PR_OpenTCPSocket((ipv6?PR_AF_INET6:PR_AF_INET)); if (res_socket==NULL) { print_nspr_error(); return NULL; } if (!ssl) return res_socket; if (!(res_socket=SSL_ImportFD(NULL,res_socket))) { print_nspr_error(); return NULL; } if ((SSL_OptionSet(res_socket,SSL_SECURITY,ssl)!=SECSuccess) || (SSL_OptionSet(res_socket,SSL_HANDSHAKE_AS_SERVER,PR_FALSE)!=SECSuccess) || (SSL_OptionSet(res_socket,SSL_HANDSHAKE_AS_CLIENT,PR_TRUE)!=SECSuccess) || (SSL_OptionSet(res_socket,SSL_ENABLE_SSL2,ssl)!=SECSuccess) || (SSL_OptionSet(res_socket,SSL_ENABLE_SSL3,ssl)!=SECSuccess) || (SSL_OptionSet(res_socket,SSL_ENABLE_TLS,PR_FALSE)!=SECSuccess) || (SSL_OptionSet(res_socket,SSL_V2_COMPATIBLE_HELLO,ssl)!=SECSuccess) || (SSL_SetPKCS11PinArg(res_socket,NULL)==-1) || (SSL_AuthCertificateHook(res_socket,SSL_AuthCertificate,CERT_GetDefaultCertDB())!=SECSuccess) || (SSL_BadCertHook(res_socket,nss_bad_cert_hook,NULL)!=SECSuccess)) { print_nspr_error(); if (PR_Close(res_socket)!=PR_SUCCESS) { print_nspr_error(); } return NULL; } return res_socket; }
void nsSocketTransportService::ProbeMaxCount() { NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); if (mProbedMaxCount) return; mProbedMaxCount = true; // Allocate and test a PR_Poll up to the gMaxCount number of unconnected // sockets. See bug 692260 - windows should be able to handle 1000 sockets // in select() without a problem, but LSPs have been known to balk at lower // numbers. (64 in the bug). // Allocate struct PRPollDesc pfd[SOCKET_LIMIT_TARGET]; uint32_t numAllocated = 0; for (uint32_t index = 0 ; index < gMaxCount; ++index) { pfd[index].in_flags = PR_POLL_READ | PR_POLL_WRITE | PR_POLL_EXCEPT; pfd[index].out_flags = 0; pfd[index].fd = PR_OpenTCPSocket(PR_AF_INET); if (!pfd[index].fd) { SOCKET_LOG(("Socket Limit Test index %d failed\n", index)); if (index < SOCKET_LIMIT_MIN) gMaxCount = SOCKET_LIMIT_MIN; else gMaxCount = index; break; } ++numAllocated; } // Test PR_STATIC_ASSERT(SOCKET_LIMIT_MIN >= 32U); while (gMaxCount <= numAllocated) { int32_t rv = PR_Poll(pfd, gMaxCount, PR_MillisecondsToInterval(0)); SOCKET_LOG(("Socket Limit Test poll() size=%d rv=%d\n", gMaxCount, rv)); if (rv >= 0) break; SOCKET_LOG(("Socket Limit Test poll confirmationSize=%d rv=%d error=%d\n", gMaxCount, rv, PR_GetError())); gMaxCount -= 32; if (gMaxCount <= SOCKET_LIMIT_MIN) { gMaxCount = SOCKET_LIMIT_MIN; break; } } // Free for (uint32_t index = 0 ; index < numAllocated; ++index) if (pfd[index].fd) PR_Close(pfd[index].fd); Telemetry::Accumulate(Telemetry::NETWORK_PROBE_MAXCOUNT, gMaxCount); SOCKET_LOG(("Socket Limit Test max was confirmed at %d\n", gMaxCount)); }
static bool NewTCPSocketPair(PRFileDesc *fd[]) { // this is a replacement for PR_NewTCPSocketPair that manually // sets the recv buffer to 64K. A windows bug (1248358) // can result in using an incompatible rwin and window // scale option on localhost pipes if not set before connect. PRFileDesc *listener = nullptr; PRFileDesc *writer = nullptr; PRFileDesc *reader = nullptr; PRSocketOptionData recvBufferOpt; recvBufferOpt.option = PR_SockOpt_RecvBufferSize; recvBufferOpt.value.recv_buffer_size = 65535; PRSocketOptionData nodelayOpt; nodelayOpt.option = PR_SockOpt_NoDelay; nodelayOpt.value.no_delay = true; PRSocketOptionData noblockOpt; noblockOpt.option = PR_SockOpt_Nonblocking; noblockOpt.value.non_blocking = true; listener = PR_OpenTCPSocket(PR_AF_INET); if (!listener) { goto failed; } PR_SetSocketOption(listener, &recvBufferOpt); PR_SetSocketOption(listener, &nodelayOpt); PRNetAddr listenAddr; memset(&listenAddr, 0, sizeof(listenAddr)); if ((PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &listenAddr) == PR_FAILURE) || (PR_Bind(listener, &listenAddr) == PR_FAILURE) || (PR_GetSockName(listener, &listenAddr) == PR_FAILURE) || // learn the dynamic port (PR_Listen(listener, 5) == PR_FAILURE)) { goto failed; } writer = PR_OpenTCPSocket(PR_AF_INET); if (!writer) { goto failed; } PR_SetSocketOption(writer, &recvBufferOpt); PR_SetSocketOption(writer, &nodelayOpt); PR_SetSocketOption(writer, &noblockOpt); PRNetAddr writerAddr; if (PR_InitializeNetAddr(PR_IpAddrLoopback, ntohs(listenAddr.inet.port), &writerAddr) == PR_FAILURE) { goto failed; } if (PR_Connect(writer, &writerAddr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { if ((PR_GetError() != PR_IN_PROGRESS_ERROR) || (PR_ConnectContinue(writer, PR_POLL_WRITE) == PR_FAILURE)) { goto failed; } } reader = PR_Accept(listener, &listenAddr, PR_INTERVAL_NO_TIMEOUT); if (!reader) { goto failed; } PR_SetSocketOption(reader, &recvBufferOpt); PR_SetSocketOption(reader, &nodelayOpt); PR_SetSocketOption(reader, &noblockOpt); PR_Close(listener); fd[0] = reader; fd[1] = writer; return true; failed: if (listener) { PR_Close(listener); } if (reader) { PR_Close(reader); } if (writer) { PR_Close(writer); } return false; }
// 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 nsServerSocket::InitWithAddress(const PRNetAddr *aAddr, int32_t aBackLog) { NS_ENSURE_TRUE(mFD == nullptr, NS_ERROR_ALREADY_INITIALIZED); nsresult rv; // // configure listening socket... // mFD = PR_OpenTCPSocket(aAddr->raw.family); if (!mFD) { NS_WARNING("unable to create server socket"); return ErrorAccordingToNSPR(PR_GetError()); } PRSocketOptionData opt; opt.option = PR_SockOpt_Reuseaddr; opt.value.reuse_addr = true; PR_SetSocketOption(mFD, &opt); opt.option = PR_SockOpt_Nonblocking; opt.value.non_blocking = true; PR_SetSocketOption(mFD, &opt); if (PR_Bind(mFD, aAddr) != PR_SUCCESS) { NS_WARNING("failed to bind socket"); goto fail; } if (aBackLog < 0) aBackLog = 5; // seems like a reasonable default if (PR_Listen(mFD, aBackLog) != PR_SUCCESS) { NS_WARNING("cannot listen on socket"); goto fail; } // get the resulting socket address, which may be different than what // we passed to bind. if (PR_GetSockName(mFD, &mAddr) != PR_SUCCESS) { NS_WARNING("cannot get socket name"); goto fail; } // Set any additional socket defaults needed by child classes rv = SetSocketDefaults(); if (NS_WARN_IF(NS_FAILED(rv))) { goto fail; } // wait until AsyncListen is called before polling the socket for // client connections. return NS_OK; fail: rv = ErrorAccordingToNSPR(PR_GetError()); Close(); return rv; }
NS_IMETHODIMP nsServerSocket::InitWithAddress(const PRNetAddr *aAddr, PRInt32 aBackLog) { NS_ENSURE_TRUE(mFD == nsnull, NS_ERROR_ALREADY_INITIALIZED); if (!mLock) { mLock = PR_NewLock(); if (!mLock) return NS_ERROR_OUT_OF_MEMORY; } // // configure listening socket... // mFD = PR_OpenTCPSocket(aAddr->raw.family); if (!mFD) { NS_WARNING("unable to create server socket"); return NS_ERROR_FAILURE; } PRSocketOptionData opt; opt.option = PR_SockOpt_Reuseaddr; opt.value.reuse_addr = PR_TRUE; PR_SetSocketOption(mFD, &opt); opt.option = PR_SockOpt_Nonblocking; opt.value.non_blocking = PR_TRUE; PR_SetSocketOption(mFD, &opt); if (PR_Bind(mFD, aAddr) != PR_SUCCESS) { NS_WARNING("failed to bind socket"); goto fail; } if (aBackLog < 0) aBackLog = 5; // seems like a reasonable default if (PR_Listen(mFD, aBackLog) != PR_SUCCESS) { NS_WARNING("cannot listen on socket"); goto fail; } // get the resulting socket address, which may be different than what // we passed to bind. if (PR_GetSockName(mFD, &mAddr) != PR_SUCCESS) { NS_WARNING("cannot get socket name"); goto fail; } // wait until AsyncListen is called before polling the socket for // client connections. return NS_OK; fail: Close(); return NS_ERROR_FAILURE; }
/* Non-blocking I/O */ static void ClientNB(void *arg) { PRFileDesc *sock; PRSocketOptionData opt; PRUint16 port = (PRUint16) arg; PRNetAddr addr; char buf[BUFFER_SIZE]; PRPollDesc pd; PRInt32 npds; PRInt32 nbytes; int i; int j; sock = PR_OpenTCPSocket(PR_AF_INET6); if (NULL == sock) { fprintf(stderr, "PR_OpenTCPSocket failed\n"); exit(1); } opt.option = PR_SockOpt_Nonblocking; opt.value.non_blocking = PR_TRUE; if (PR_SetSocketOption(sock, &opt) == PR_FAILURE) { fprintf(stderr, "PR_SetSocketOption failed\n"); exit(1); } memset(&addr, 0, sizeof(addr)); if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6, port, &addr) == PR_FAILURE) { fprintf(stderr, "PR_SetNetAddr failed\n"); exit(1); } if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { if (PR_GetError() != PR_IN_PROGRESS_ERROR) { fprintf(stderr, "PR_Connect failed\n"); exit(1); } pd.fd = sock; pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); if (-1 == npds) { fprintf(stderr, "PR_Poll failed\n"); exit(1); } if (1 != npds) { fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds); exit(1); } if (PR_GetConnectStatus(&pd) == PR_FAILURE) { fprintf(stderr, "PR_GetConnectStatus failed\n"); exit(1); } } for (i = 0; i < iterations; i++) { PR_Sleep(PR_SecondsToInterval(1)); memset(buf, 2*i, send_amount[i]); while ((nbytes = PR_Send(sock, buf, send_amount[i], 0, PR_INTERVAL_NO_TIMEOUT)) == -1) { if (PR_GetError() != PR_WOULD_BLOCK_ERROR) { fprintf(stderr, "PR_Send failed\n"); exit(1); } pd.fd = sock; pd.in_flags = PR_POLL_WRITE; npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); if (-1 == npds) { fprintf(stderr, "PR_Poll failed\n"); exit(1); } if (1 != npds) { fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds); exit(1); } } if (send_amount[i] != nbytes) { fprintf(stderr, "PR_Send returned %d, absurd!\n", nbytes); exit(1); } memset(buf, 0, sizeof(buf)); while ((nbytes = PR_Recv(sock, buf, recv_amount[i], PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT)) == -1) { if (PR_GetError() != PR_WOULD_BLOCK_ERROR) { fprintf(stderr, "PR_Recv failed\n"); exit(1); } pd.fd = sock; pd.in_flags = PR_POLL_READ; npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); if (-1 == npds) { fprintf(stderr, "PR_Poll failed\n"); exit(1); } if (1 != npds) { fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds); exit(1); } } if (send_amount[i] != nbytes) { fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); exit(1); } for (j = 0; j < nbytes; j++) { if (buf[j] != 2*i+1) { fprintf(stderr, "byte %d should be %d but is %d\n", j, 2*i+1, buf[j]); exit(1); } } fprintf(stderr, "client: peeked expected data\n"); memset(buf, 0, sizeof(buf)); nbytes = PR_Recv(sock, buf, recv_amount[i], PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT); if (-1 == nbytes) { fprintf(stderr, "PR_Recv failed\n"); exit(1); } if (send_amount[i] != nbytes) { fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); exit(1); } for (j = 0; j < nbytes; j++) { if (buf[j] != 2*i+1) { fprintf(stderr, "byte %d should be %d but is %d\n", j, 2*i+1, buf[j]); exit(1); } } fprintf(stderr, "client: peeked expected data\n"); memset(buf, 0, sizeof(buf)); nbytes = PR_Recv(sock, buf, recv_amount[i], 0, PR_INTERVAL_NO_TIMEOUT); if (-1 == nbytes) { fprintf(stderr, "PR_Recv failed\n"); exit(1); } if (send_amount[i] != nbytes) { fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); exit(1); } for (j = 0; j < nbytes; j++) { if (buf[j] != 2*i+1) { fprintf(stderr, "byte %d should be %d but is %d\n", j, 2*i+1, buf[j]); exit(1); } } fprintf(stderr, "client: received expected data\n"); } if (PR_Close(sock) == PR_FAILURE) { fprintf(stderr, "PR_Close failed\n"); exit(1); } }
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; }
/* * TCP_Client * Client job * Connect to the server at the address specified in the argument. * Fill in a buffer, write data to server, read it back and check * for data corruption. * Close the socket for server connection */ static void PR_CALLBACK TCP_Client(void *arg) { Client_Param *cp = (Client_Param *) arg; PRFileDesc *sockfd; buffer *in_buf, *out_buf; union PRNetAddr netaddr; PRInt32 bytes, i, j; DPRINTF(("TCP client started\n")); bytes = cp->datalen; out_buf = PR_NEW(buffer); if (out_buf == NULL) { fprintf(stderr,"%s: failed to alloc buffer struct\n", program_name); failed_already=1; return; } in_buf = PR_NEW(buffer); if (in_buf == NULL) { fprintf(stderr,"%s: failed to alloc buffer struct\n", program_name); failed_already=1; return; } netaddr.inet.family = cp->server_addr.inet.family; netaddr.inet.port = cp->server_addr.inet.port; netaddr.inet.ip = cp->server_addr.inet.ip; for (i = 0; i < num_tcp_connections_per_client; i++) { if ((sockfd = PR_OpenTCPSocket(PR_AF_INET)) == NULL) { fprintf(stderr,"%s: PR_OpenTCPSocket failed\n", program_name); failed_already=1; return; } DPRINTF(("TCP client connecting to server:%d\n", server_port)); if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ fprintf(stderr, "PR_Connect failed: (%ld, %ld)\n", PR_GetError(), PR_GetOSError()); failed_already=1; return; } for (j = 0; j < num_tcp_mesgs_per_connection; j++) { /* * fill in random data */ memset(out_buf->data, ((PRInt32) (&netaddr)) + i + j, bytes); /* * write to server */ if (writen(sockfd, out_buf->data, bytes) < bytes) { fprintf(stderr,"%s: ERROR - TCP_Client:writen\n", program_name); failed_already=1; return; } /* DPRINTF(("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n", PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data)))); */ if (readn(sockfd, in_buf->data, bytes) < bytes) { fprintf(stderr,"%s: ERROR - TCP_Client:readn\n", program_name); failed_already=1; return; } /* * verify the data read */ if (memcmp(in_buf->data, out_buf->data, bytes) != 0) { fprintf(stderr,"%s: ERROR - data corruption\n", program_name); failed_already=1; return; } } /* * shutdown reads and writes */ if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) { fprintf(stderr,"%s: ERROR - PR_Shutdown\n", program_name); failed_already=1; } PR_Close(sockfd); } PR_DELETE(out_buf); PR_DELETE(in_buf); /* * Decrement exit_counter and notify parent thread */ PR_EnterMonitor(cp->exit_mon); --(*cp->exit_counter); PR_Notify(cp->exit_mon); PR_ExitMonitor(cp->exit_mon); DPRINTF(("TCP_Client exiting\n")); }