static void ClientThread(void *arg)
{
    PRFileDesc *sock;
    PRNetAddr addr;
    PRUint16 port = (PRUint16) arg;
    char buf[1024];
    char *bufPtr;
    PRInt32 nbytes;
    PRInt32 ntotal;
    PRInt32 nexpected;

    sock = PR_NewTCPSocket();
    if (NULL == sock) {
        fprintf(stderr, "PR_NewTCPSocket failed\n");
        exit(1);
    }
    if (PR_InitializeNetAddr(PR_IpAddrLoopback, port, &addr) == PR_FAILURE) {
        fprintf(stderr, "PR_InitializeNetAddr failed\n");
        exit(1);
    }
    if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
        fprintf(stderr, "PR_Connect failed\n");
        exit(1);
    }
    ntotal = 0;
    bufPtr = buf;
    while ((nbytes = PR_Read(sock, bufPtr, sizeof(buf)-ntotal)) > 0) {
        ntotal += nbytes;
        bufPtr += nbytes;
    }
    if (-1 == nbytes) {
        fprintf(stderr, "PR_Read failed\n");
        exit(1);
    }
    nexpected = HEADER_LEN+TRAILER_LEN+TRAILER_LEN+HEADER_LEN+HEADER_LEN;
    if (ntotal != nexpected) {
        fprintf(stderr, "total bytes read should be %d but is %d\n",
                nexpected, ntotal);
        exit(1);
    }
    if (memcmp(buf, HEADER_STR TRAILER_STR TRAILER_STR HEADER_STR HEADER_STR,
            nexpected) != 0) {
        fprintf(stderr, "wrong data is received\n");
        exit(1);
    }
    if (PR_Close(sock) == PR_FAILURE) {
        fprintf(stderr, "PR_Close failed\n");
        exit(1);
    }
}
//-----------------------------------------------------------------------------
// FcgiServerChannel::connect
//-----------------------------------------------------------------------------
PRStatus FcgiServerChannel::connect(PRIntervalTime timeoutVal)
{
    // Try to connect
#ifdef XP_WIN32
    if (config->udsName) {
        PRBool pipeBusy = PR_TRUE;
        while(pipeBusy) {
            HANDLE newFd = CreateFile(config->procInfo.bindPath,   // pipe name
                               GENERIC_READ | GENERIC_WRITE, // read and write access
                               FILE_SHARE_WRITE | FILE_SHARE_READ,              // sharing
                               NULL,           // default security attributes
                               OPEN_ALWAYS,  // opens existing pipe or creates a new one
                               FILE_FLAG_OVERLAPPED,              // default attributes
                               NULL);          // no template file


            // Break if the pipe handle is valid.
            if (newFd != INVALID_HANDLE_VALUE) {
                fd = PR_ImportFile((int)newFd);
                return PR_SUCCESS;
            }

            if (!WaitNamedPipe(config->procInfo.bindPath, PR_IntervalToMilliseconds(timeoutVal))) {
                 return PR_FAILURE;
            }

            if (GetLastError() != ERROR_PIPE_BUSY) {
                pipeBusy = PR_FALSE;
            }
        }

        return PR_FAILURE;

    } else {
#endif // XP_WIN32
    if (!fd)
        return PR_FAILURE;

    PRStatus rv = PR_Connect(fd, &(config->procInfo.addr), timeoutVal);
    return rv;

#ifdef XP_WIN32
    }
#endif // XP_WIN32

}
Esempio n. 3
0
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;
}
Esempio n. 4
0
int
main (int argc, char *argv[])
{
    if (argc != 3) {
        return 1;
    }

    PRFileDesc* socket = PR_NewTCPSocket();
    PRNetAddr   addr; initAddr(&addr, argv[1], atoi(argv[2]));
    PR_Connect(socket, &addr, PR_INTERVAL_NO_TIMEOUT);

    char* string = (char*) malloc(10*sizeof(char));
    PR_Recv(socket, string, 10, 0, PR_INTERVAL_NO_TIMEOUT);
    string[10] = 0;
    printf("%s\n", string);

    PR_Close(socket);

}
Esempio n. 5
0
PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod,
			const PRNetAddr *addr, PRJobFn fn, void * arg, PRBool joinable)
{
	PRStatus rv;
	PRErrorCode err;

	rv = PR_Connect(iod->socket, addr, PR_INTERVAL_NO_WAIT);
	if ((rv == PR_FAILURE) && ((err = PR_GetError()) == PR_IN_PROGRESS_ERROR)){
		/* connection pending */
		return(queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_CONNECT));
	} else {
		/*
		 * connection succeeded or failed; add to jobq right away
		 */
		if (rv == PR_FAILURE)
			iod->error = err;
		else
			iod->error = 0;
		return(PR_QueueJob(tpool, fn, arg, joinable));
	}
}
Esempio n. 6
0
static void
clientThreadFunc(void *arg)
{
    PRUintn port = (PRUintn) arg;
    PRFileDesc *sock;
    PRNetAddr addr;
    char buf[128];
    int i;

    addr.inet.family = AF_INET;
    addr.inet.port = PR_htons((PRUint16)port);
    addr.inet.ip = PR_htonl(INADDR_LOOPBACK);
    PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.port);

    for (i = 0; i < 5; i++) {
	sock = PR_NewTCPSocket();
        PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
	PR_Write(sock, buf, sizeof(buf));
	PR_Close(sock);
    }
}
Esempio n. 7
0
void SslSocket::connect(const std::string& host, uint16_t port) const
{
    std::stringstream namestream;
    namestream << host << ":" << port;
    connectname = namestream.str();

    void* arg = SslOptions::global.certName.empty() ? 0 : const_cast<char*>(SslOptions::global.certName.c_str());
    NSS_CHECK(SSL_GetClientAuthDataHook(socket, NSS_GetClientAuthData, arg));
    NSS_CHECK(SSL_SetURL(socket, host.data()));

    char hostBuffer[PR_NETDB_BUF_SIZE];
    PRHostEnt hostEntry;
    PR_CHECK(PR_GetHostByName(host.data(), hostBuffer, PR_NETDB_BUF_SIZE, &hostEntry));
    PRNetAddr address;
    int value = PR_EnumerateHostEnt(0, &hostEntry, port, &address);
    if (value < 0) {
        throw Exception(QPID_MSG("Error getting address for host: " << ErrorString()));
    } else if (value == 0) {
        throw Exception(QPID_MSG("Could not resolve address for host."));
    }
    PR_CHECK(PR_Connect(socket, &address, PR_INTERVAL_NO_TIMEOUT));
}
Esempio n. 8
0
/*
 * TransmitFile_Client
 *    Client Thread
 */
static void
TransmitFile_Client(void *arg)
{
    PRFileDesc *sockfd;
    union PRNetAddr netaddr;
    char *small_buf, *large_buf;
    Client_Param *cp = (Client_Param *) arg;

    small_buf = (char*)PR_Malloc(SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE);
    if (small_buf == NULL) {
        fprintf(stderr,"prsocket_test: failed to alloc buffer\n");
        failed_already=1;
        return;
    }
    large_buf = (char*)PR_Malloc(LARGE_FILE_SIZE);
    if (large_buf == NULL) {
        fprintf(stderr,"prsocket_test: failed to alloc buffer\n");
        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;

    if ((sockfd = PR_NewTCPSocket()) == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n");
        failed_already=1;
        return;
    }

    if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){
        fprintf(stderr,"prsocket_test: PR_Connect failed\n");
        failed_already=1;
        return;
    }
    /*
     * read the small file and verify the data
     */
    if (readn(sockfd, small_buf, SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE)
        != (SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE)) {
        fprintf(stderr,
            "prsocket_test: TransmitFile_Client failed to receive file\n");
        failed_already=1;
        return;
    }
#ifdef XP_UNIX
    if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){
        fprintf(stderr,
            "prsocket_test: TransmitFile_Client ERROR - small file header data corruption\n");
        failed_already=1;
        return;
    }
    if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE,
        SMALL_FILE_SIZE) != 0) {
        fprintf(stderr,
            "prsocket_test: TransmitFile_Client ERROR - small file data corruption\n");
        failed_already=1;
        return;
    }
#endif
    /*
     * read the large file and verify the data
     */
    if (readn(sockfd, large_buf, LARGE_FILE_SIZE) != LARGE_FILE_SIZE) {
        fprintf(stderr,
            "prsocket_test: TransmitFile_Client failed to receive file\n");
        failed_already=1;
        return;
    }
#ifdef XP_UNIX
    if (memcmp(large_file_addr, large_buf, LARGE_FILE_SIZE) != 0) {
        fprintf(stderr,
            "prsocket_test: TransmitFile_Client ERROR - large file data corruption\n");
        failed_already=1;
        return;
    }
#endif
    PR_DELETE(small_buf);
    PR_DELETE(large_buf);
    PR_Close(sockfd);

    /*
     * 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(("TransmitFile_Client [0x%lx] exiting\n", PR_GetCurrentThread()));
}
Esempio n. 9
0
/*
 * TCP_Client
 *    Client Thread
 *    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;


    bytes = cp->datalen;
    out_buf = PR_NEW(buffer);
    if (out_buf == NULL) {
        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
        failed_already=1;
        return;
    }
    in_buf = PR_NEW(buffer);
    if (in_buf == NULL) {
        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
        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_NewTCPSocket()) == NULL) {
            fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n");
            failed_already=1;
            return;
        }

        if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){
            fprintf(stderr,"prsocket_test: PR_Connect failed\n");
            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,"prsocket_test: ERROR - TCP_Client:writen\n");
                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,"prsocket_test: ERROR - TCP_Client:readn\n");
                failed_already=1;
                return;
            }
            /*
             * verify the data read
             */
            if (memcmp(in_buf->data, out_buf->data, bytes) != 0) {
                fprintf(stderr,"prsocket_test: ERROR - data corruption\n");
                failed_already=1;
                return;
            }
        }
        /*
         * shutdown reads and writes
         */
        if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) {
            fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n");
            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 [0x%x] exiting\n", PR_GetCurrentThread()));
}
Esempio n. 10
0
/*
 * UDP_Client
 *    Client Thread
 *    Create a socket and bind an address 
 *    Communicate with 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
 */
static void PR_CALLBACK
UDP_Client(void *arg)
{
    Client_Param *cp = (Client_Param *) arg;
    PRFileDesc *sockfd;
    buffer *in_buf, *out_buf;
    union PRNetAddr netaddr;
    PRInt32 bytes, i, rv;


    bytes = cp->datalen;
    out_buf = PR_NEW(buffer);
    if (out_buf == NULL) {
        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
        failed_already=1;
        return;
    }
    in_buf = PR_NEW(buffer);
    if (in_buf == NULL) {
        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
        failed_already=1;
        return;
    }
    if ((sockfd = PR_NewUDPSocket()) == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewUDPSocket failed\n");
        failed_already=1;
        return;
    }

    /*
     * bind an address for the client, let the system chose the port
     * number
     */
    memset(&netaddr, 0 , sizeof(netaddr));
    netaddr.inet.family = AF_INET;
    netaddr.inet.ip = PR_htonl(INADDR_ANY);
    netaddr.inet.port = PR_htons(0);
    if (PR_Bind(sockfd, &netaddr) < 0) {
        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
        perror("PR_Bind");
        return;
    }

    if (PR_GetSockName(sockfd, &netaddr) < 0) {
        fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
        failed_already=1;
        return;
    }

    DPRINTF(("PR_Bind: UDP Client netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
        netaddr.inet.ip, netaddr.inet.port));

    netaddr.inet.family = cp->server_addr.inet.family;
    netaddr.inet.port = cp->server_addr.inet.port;
    netaddr.inet.ip = cp->server_addr.inet.ip;

    if (cp->udp_connect) {
        if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){
            fprintf(stderr,"prsocket_test: PR_Connect failed\n");
            failed_already=1;
            return;
        }
    }

    for (i = 0; i < num_udp_datagrams_per_client; i++) {
        /*
         * fill in random data
         */
        DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx bytes = 0x%lx\n",
            PR_GetCurrentThread(), out_buf->data, bytes));
        memset(out_buf->data, ((PRInt32) (&netaddr)) + i, bytes);
        /*
         * write to server
         */
        if (cp->udp_connect)
            rv = PR_Send(sockfd, out_buf->data, bytes, 0,
                PR_INTERVAL_NO_TIMEOUT);
        else
            rv = PR_SendTo(sockfd, out_buf->data, bytes, 0, &netaddr,
                PR_INTERVAL_NO_TIMEOUT);
        if (rv != bytes) {
            return;
        }
        DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n",
            PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data))));
        if (cp->udp_connect)
            rv = PR_Recv(sockfd, in_buf->data, bytes, 0,
                PR_INTERVAL_NO_TIMEOUT);
        else
            rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr,
                PR_INTERVAL_NO_TIMEOUT);
        if (rv != bytes) {
            return;
        }
        DPRINTF(("UDP_Client [0x%lx]: in_buf = 0x%lx in_buf[0] = 0x%lx\n",
            PR_GetCurrentThread(), in_buf, (*((int *) in_buf->data))));
        /*
         * verify the data read
         */
        if (memcmp(in_buf->data, out_buf->data, bytes) != 0) {
            fprintf(stderr,"prsocket_test: ERROR - UDP data corruption\n");
            failed_already=1;
            return;
        }
    }
    PR_Close(sockfd);

    PR_DELETE(in_buf);
    PR_DELETE(out_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);
    PR_DELETE(cp);
    DPRINTF(("UDP_Client [0x%x] exiting\n", PR_GetCurrentThread()));
}
void
ClientThreadFunc(void *unused)
{
    PRNetAddr serverAddr;
    PRFileDesc *clientSocket;
    char *sendBuf;
    char *recvBuf;
    PRInt32 rv;
    PRInt32 bytesNeeded;

    sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char));
    if (!sendBuf)
        if (debug_mode) printf("\tClient could not malloc space!?\n");
    recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char));
    if (!recvBuf)
        if (debug_mode) printf("\tClient could not malloc space!?\n");

    memset(&serverAddr, 0, sizeof(PRNetAddr));
    serverAddr.inet.family = PR_AF_INET;
    serverAddr.inet.port = PR_htons(PORT);
    serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);

    while(numRequests > 0) {

        if ( (numRequests % 10) == 0 )
            if (debug_mode) printf(".");
        if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests);

        clientSocket = PR_NewTCPSocket();
        if (!clientSocket) {
            if (debug_mode) printf("Client error creating socket: OS error %d\n",
		    PR_GetOSError());
            continue;
        }

        if (debug_mode) DPRINTF("\tClient connecting\n");

        rv = PR_Connect(clientSocket, 
                        &serverAddr,
                        PR_INTERVAL_NO_TIMEOUT);
        if (!clientSocket) {
            if (debug_mode) printf("\tClient error connecting\n");
            continue;
        }

        if (debug_mode) DPRINTF("\tClient connected\n");

        rv = PR_Send(clientSocket, 
                     sendBuf, 
                     _client_data, 
                     0, 
                     PR_INTERVAL_NO_TIMEOUT);
        if (rv != _client_data) {
            if (debug_mode) printf("Client error sending data (%d)\n", rv);
            PR_Close(clientSocket);
            continue;
        }

        if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv);

        bytesNeeded = _server_data;
        while(bytesNeeded) {
            rv = PR_Recv(clientSocket, 
                         recvBuf, 
                         bytesNeeded, 
                         0, 
                         PR_INTERVAL_NO_TIMEOUT);
            if (rv <= 0) {
                if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", 
                    rv, (_server_data - bytesNeeded), _server_data);
                break;
            }
            if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv);
            bytesNeeded -= rv;
        }

        PR_Close(clientSocket);
 
        PR_AtomicDecrement(&numRequests);
    }

    PR_EnterMonitor(clientMonitor);
    --numClients;
    PR_Notify(clientMonitor);
    PR_ExitMonitor(clientMonitor);

    PR_DELETE(sendBuf);
    PR_DELETE(recvBuf);
}
Esempio n. 12
0
static void PR_CALLBACK Clientel(void *arg)
{
    PRStatus rv;
    PRFileDesc *xport;
    PRInt32 bytes, sampled;
    PRIntervalTime now, interval;
    PRBool do_display = PR_FALSE;
    Shared *shared = (Shared*)arg;
    char *buffer = (char*)PR_Malloc(buffer_size);
    PRNetAddr *server_address = &shared->server_address;
    PRIntervalTime connect_timeout = PR_SecondsToInterval(5);
    PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL);

    PR_fprintf(err, "Client connecting to ");
    (void)PrintAddress(server_address);

    do
    {
        xport = PR_Socket(domain, PR_SOCK_STREAM, protocol);
        if (NULL == xport)
        {
            PL_FPrintError(err, "PR_Socket");
            return;
        }

        if (xport_buffer != -1)
        {
            PRSocketOptionData data;
            data.option = PR_SockOpt_RecvBufferSize;
            data.value.recv_buffer_size = (PRSize)xport_buffer;
            rv = PR_SetSocketOption(xport, &data);
            if (PR_FAILURE == rv)
                PL_FPrintError(err, "PR_SetSocketOption - ignored");
            data.option = PR_SockOpt_SendBufferSize;
            data.value.send_buffer_size = (PRSize)xport_buffer;
            rv = PR_SetSocketOption(xport, &data);
            if (PR_FAILURE == rv)
                PL_FPrintError(err, "PR_SetSocketOption - ignored");
        }

        rv = PR_Connect(xport, server_address, connect_timeout);
        if (PR_FAILURE == rv)
        {
            PL_FPrintError(err, "PR_Connect");
            if (PR_IO_TIMEOUT_ERROR != PR_GetError())
                PR_Sleep(connect_timeout);
            PR_Close(xport);  /* delete it and start over */
        }
    } while (PR_FAILURE == rv);

    do
    {
        bytes = PR_Recv(
            xport, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT);
        PR_Lock(shared->ml);
        now = PR_IntervalNow();
        shared->sampled += bytes;
        interval = now - shared->timein;
        if (interval > sampling_interval)
        {
            sampled = shared->sampled;
            shared->timein = now;
            shared->sampled = 0;
            do_display = PR_TRUE;
        }
        PR_Unlock(shared->ml);

        if (do_display)
        {
            PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval);
            PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate);
            do_display = PR_FALSE;
        }

    } while (bytes > 0);
}  /* Clientel */
Esempio n. 13
0
int FileSSL_main(int argc, char * argv[])
{
    bool isServer = true;
    
    SECStatus rv = SECSuccess;

    
    char buffer[32] = {0};
    

    PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
    
    PK11_SetPasswordFunc(GetModulePassword);
    rv = NSS_Initialize(GetSystemDBDir(),
                        "", "",
                        "secmod.db", 0);
    
    
    rv = SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE);
    rv = SSL_OptionSetDefault(SSL_SOCKS, PR_TRUE);
    rv = SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_TRUE);
    rv = SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_TRUE);
    rv = SSL_OptionSetDefault(SSL_ENABLE_FDX, PR_TRUE);
    
    rv = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE);
    
    rv = NSS_SetDomesticPolicy();
    rv = NSS_SetExportPolicy();
    rv = NSS_SetFrancePolicy();
    //    rv = SSL_CipherPolicySet();
    
    
    
    SSL_ClearSessionCache();
    
    rv = SSL_ConfigServerSessionIDCache(10, 30 , 30, ".");
    
    
    PRFileDesc * socket = PR_NewTCPSocket();
    
    socket = SSL_ImportFD(NULL,socket);
    
    
    
    if (isServer) {
        
        CERTCertDBHandle *certHandle;
        
        certHandle = CERT_GetDefaultCertDB();
        
        char * nickname = "itrus Certificate DB:2013-11-15 12:44:10";/*nickname*/
        
        CERTCertificate* cert = NULL;
        cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, nickname);
        
        
        SECKEYPrivateKey *prvKey = NULL;
        
        prvKey = PK11_FindKeyByAnyCert(cert, NULL);
        
        rv = SSL_ConfigSecureServer(socket, cert,prvKey,ssl_kea_rsa);
        
        
        PRNetAddr netAddr;
        
        PRNetAddr netAddrLocal;
        
        
        rv = PR_InitializeNetAddr(0, 8888, &netAddr);
        
        
        rv = PR_StringToNetAddr("127.0.0.1", &netAddrLocal);
        
        rv = PR_Bind(socket,&netAddr);
        rv = PR_Listen(socket, 100);
        
        
        while (1) {
            PRFileDesc * client = PR_Accept(socket, &netAddr, 6000000);
            PRNetAddr addr;
            
            
            rv = PR_GetSockName(client, &addr);
            
            rv = SSL_ForceHandshake(client);
            
            
            rv = PR_Write(client,"123", 4);
            
            sleep(1);
        }
        
    }
    else
    {
        rv = SSL_SetURL(socket, "127.0.0.1");
        
        PRNetAddr netAddr;
        
        PRNetAddr netAddrLocal;
        
        
        rv = PR_InitializeNetAddr(0, 8888, &netAddr);
        
        
        rv = PR_StringToNetAddr("127.0.0.1", &netAddrLocal);
        
        //        rv = PR_GetHostByName();
        //        PR_EnumerateHostEnt
        rv = PR_Connect(socket,&netAddr, 300000);
        
        rv = SSL_AuthCertificateHook(socket, OwnAuthCertHandler, NULL);
        
        rv = SSL_ForceHandshake(socket);
        
        while (1) {
            rv = PR_Read(socket,buffer, 32);
            
            sleep(1);
        }
        
    }
    
    
    return 0;
}
/* make the connection.
*/
static SECStatus
do_connect(PRNetAddr *addr)
{
  PRFileDesc *sslSocket;
  PRStatus    prStatus;
#if 0
  PRHostEnt   hostEntry;
  char        buffer[PR_NETDB_BUF_SIZE];
  PRIntn      hostenum;
#endif
  SECStatus   secStatus;

  secStatus = SECSuccess;

  /* Set up SSL secure socket. */
  sslSocket = setupSSLSocket();
  if (sslSocket == NULL)
    return SECFailure;

#if 0 /* no client authentication */
  secStatus = SSL_SetPKCS11PinArg(sslSocket, password);
  if (secStatus != SECSuccess)
    goto done;
#endif

  secStatus = SSL_SetURL(sslSocket, hostName);
  if (secStatus != SECSuccess)
    goto done;

#if 0 /* Already done */
  /* Prepare and setup network connection. */
  prStatus = PR_GetHostByName(hostName, buffer, sizeof(buffer), &hostEntry);
  if (prStatus != PR_SUCCESS)
    {
      secStatus = SECFailure;
      goto done;
    }

  hostenum = PR_EnumerateHostEnt(0, &hostEntry, port, addr);
  if (hostenum == -1)
    {
      secStatus = SECFailure;
      goto done;
    }
#endif
  prStatus = PR_Connect(sslSocket, addr, PR_INTERVAL_NO_TIMEOUT);
  if (prStatus != PR_SUCCESS)
    {
      secStatus = SECFailure;
      goto done;
    }

  /* Established SSL connection, ready to send data. */
  secStatus = SSL_ResetHandshake(sslSocket, /* asServer */ PR_FALSE);
  if (secStatus != SECSuccess)
    goto done;

  /* This is normally done automatically on the first I/O operation,
     but doing it here catches any authentication problems early.  */
  secStatus = SSL_ForceHandshake(sslSocket);
  if (secStatus != SECSuccess)
    goto done;

  secStatus = handle_connection(sslSocket);
  if (secStatus != SECSuccess)
    goto done;

 done:
  prStatus = PR_Close(sslSocket);
  return secStatus;
}
static void PR_CALLBACK Client(void *arg)
{
    PRStatus rv;
    PRIntn index;
    char buffer[1024];
    PRFileDesc *fd = NULL;
    PRUintn clipping = DEFAULT_CLIPPING;
    PRThread *me = PR_GetCurrentThread();
    CSClient_t *client = (CSClient_t*)arg;
    CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t);
    PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_CLIENT_TIMEOUT);


    for (index = 0; index < sizeof(buffer); ++index)
        buffer[index] = (char)index;

    client->started = PR_IntervalNow();

    PR_Lock(client->ml);
    client->state = cs_run;
    PR_NotifyCondVar(client->stateChange);
    PR_Unlock(client->ml);

    TimeOfDayMessage("Client started at", me);

    while (cs_run == client->state)
    {
        PRInt32 bytes, descbytes, filebytes, netbytes;

        (void)PR_NetAddrToString(&client->serverAddress, buffer, sizeof(buffer));
        TEST_LOG(cltsrv_log_file, TEST_LOG_INFO, 
            ("\tClient(0x%p): connecting to server at %s\n", me, buffer));

        fd = PR_Socket(domain, SOCK_STREAM, protocol);
        TEST_ASSERT(NULL != fd);
        rv = PR_Connect(fd, &client->serverAddress, timeout);
        if (PR_FAILURE == rv)
        {
            TEST_LOG(
                cltsrv_log_file, TEST_LOG_ERROR,
                ("\tClient(0x%p): conection failed (%d, %d)\n",
                me, PR_GetError(), PR_GetOSError()));
            goto aborted;
        }

        memset(descriptor, 0, sizeof(*descriptor));
        descriptor->size = PR_htonl(descbytes = rand() % clipping);
        PR_snprintf(
            descriptor->filename, sizeof(descriptor->filename),
            "CS%p%p-%p.dat", client->started, me, client->operations);
        TEST_LOG(
            cltsrv_log_file, TEST_LOG_VERBOSE,
            ("\tClient(0x%p): sending descriptor for %u bytes\n", me, descbytes));
        bytes = PR_Send(
            fd, descriptor, sizeof(*descriptor), SEND_FLAGS, timeout);
        if (sizeof(CSDescriptor_t) != bytes)
        {
            if (Aborted(PR_FAILURE)) goto aborted;
            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
            {
                TEST_LOG(
                    cltsrv_log_file, TEST_LOG_ERROR,
                    ("\tClient(0x%p): send descriptor timeout\n", me));
                goto retry;
            }
        }
        TEST_ASSERT(sizeof(*descriptor) == bytes);

        netbytes = 0;
        while (netbytes < descbytes)
        {
            filebytes = sizeof(buffer);
            if ((descbytes - netbytes) < filebytes)
                filebytes = descbytes - netbytes;
            TEST_LOG(
                cltsrv_log_file, TEST_LOG_VERBOSE,
                ("\tClient(0x%p): sending %d bytes\n", me, filebytes));
            bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout);
            if (filebytes != bytes)
            {
                if (Aborted(PR_FAILURE)) goto aborted;
                if (PR_IO_TIMEOUT_ERROR == PR_GetError())
                {
                    TEST_LOG(
                        cltsrv_log_file, TEST_LOG_ERROR,
                        ("\tClient(0x%p): send data timeout\n", me));
                    goto retry;
                }
            }
            TEST_ASSERT(bytes == filebytes);
            netbytes += bytes;
        }
        filebytes = 0;
        while (filebytes < descbytes)
        {
            netbytes = sizeof(buffer);
            if ((descbytes - filebytes) < netbytes)
                netbytes = descbytes - filebytes;
            TEST_LOG(
                cltsrv_log_file, TEST_LOG_VERBOSE,
                ("\tClient(0x%p): receiving %d bytes\n", me, netbytes));
            bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout);
            if (-1 == bytes)
            {
                if (Aborted(PR_FAILURE))
                {
                    TEST_LOG(
                        cltsrv_log_file, TEST_LOG_ERROR,
                        ("\tClient(0x%p): receive data aborted\n", me));
                    goto aborted;
                }
                else if (PR_IO_TIMEOUT_ERROR == PR_GetError())
                    TEST_LOG(
                        cltsrv_log_file, TEST_LOG_ERROR,
                        ("\tClient(0x%p): receive data timeout\n", me));
				else
                    TEST_LOG(
                        cltsrv_log_file, TEST_LOG_ERROR,
                        ("\tClient(0x%p): receive error (%d, %d)\n",
						me, PR_GetError(), PR_GetOSError()));
                goto retry;
           }
            if (0 == bytes)
            {
                TEST_LOG(
                    cltsrv_log_file, TEST_LOG_ERROR,
                    ("\t\tClient(0x%p): unexpected end of stream\n",
                    PR_GetCurrentThread()));
                break;
            }
            filebytes += bytes;
        }

        rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
        if (Aborted(rv)) goto aborted;
        TEST_ASSERT(PR_SUCCESS == rv);
retry:
        (void)PR_Close(fd); fd = NULL;
        TEST_LOG(
            cltsrv_log_file, TEST_LOG_INFO,
            ("\tClient(0x%p): disconnected from server\n", me));

        PR_Lock(client->ml);
        client->operations += 1;
        client->bytesTransferred += 2 * descbytes;
        rv = PR_WaitCondVar(client->stateChange, rand() % clipping);
        PR_Unlock(client->ml);
        if (Aborted(rv)) break;
    }

aborted:
    client->stopped = PR_IntervalNow();

    PR_ClearInterrupt();
    if (NULL != fd) rv = PR_Close(fd);

    PR_Lock(client->ml);
    client->state = cs_exit;
    PR_NotifyCondVar(client->stateChange);
    PR_Unlock(client->ml);
    PR_DELETE(descriptor);
    TEST_LOG(
        cltsrv_log_file, TEST_LOG_ALWAYS,
        ("\tClient(0x%p): stopped after %u operations and %u bytes\n",
        PR_GetCurrentThread(), client->operations, client->bytesTransferred));

}  /* Client */
Esempio n. 16
0
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;
}
/* 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);
    }
}
Esempio n. 18
0
JNIEXPORT void JNICALL
Java_org_mozilla_jss_ssl_SSLSocket_socketConnect
    (JNIEnv *env, jobject self, jbyteArray addrBA, jstring hostname, jint port)
{
    JSSL_SocketData *sock;
    PRNetAddr addr;
    jbyte *addrBAelems = NULL;
    PRStatus status;
    int stat;
    const char *hostnameStr=NULL;

    if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) {
        /* exception was thrown */
        goto finish;
    }

    /*
     * setup the PRNetAddr structure
     */
    addr.inet.family = AF_INET;
    addr.inet.port = htons(port);
    PR_ASSERT(sizeof(addr.inet.ip) == 4);
    PR_ASSERT( (*env)->GetArrayLength(env, addrBA) == 4);
    addrBAelems = (*env)->GetByteArrayElements(env, addrBA, NULL);
    if( addrBAelems == NULL ) {
        ASSERT_OUTOFMEM(env);
        goto finish;
    }
    memcpy(&addr.inet.ip, addrBAelems, 4);

    /*
     * Tell SSL the URL we think we want to connect to.
     * This prevents man-in-the-middle attacks.
     */
    hostnameStr = (*env)->GetStringUTFChars(env, hostname, NULL);
    if( hostnameStr == NULL ) goto finish;
    stat = SSL_SetURL(sock->fd, (char*)hostnameStr);
    if( stat != 0 ) {
        JSSL_throwSSLSocketException(env, "Failed to set the SSL URL");
        goto finish;
    }

    /*
     * make the connect call
     */
    status = PR_Connect(sock->fd, &addr, PR_INTERVAL_NO_TIMEOUT);
    if( status != PR_SUCCESS) {
        JSSL_throwSSLSocketException(env, "Unable to connect");
        goto finish;
    }

finish:
    /* This method should never be called on a Java socket wrapper. */
    PR_ASSERT( sock==NULL || sock->jsockPriv==NULL);

    if( hostnameStr != NULL ) {
        (*env)->ReleaseStringUTFChars(env, hostname, hostnameStr);
    }
    if( addrBAelems != NULL ) {
        (*env)->ReleaseByteArrayElements(env, addrBA, addrBAelems, JNI_ABORT);
    }
}
Esempio n. 19
0
static void PR_CALLBACK Client(void *arg)
{
    PRStatus rv;
    PRIntn mits;
    PRInt32 ready;
    PRUint8 buffer[100];
    PRPollDesc polldesc;
    PRIntn empty_flags = 0;
    PRIntn bytes_read, bytes_sent;
    PRFileDesc *stack = (PRFileDesc*)arg;

    /* Initialize the buffer so that Purify won't complain */
    memset(buffer, 0, sizeof(buffer));

    rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT);
    if ((PR_FAILURE == rv) && (PR_IN_PROGRESS_ERROR == PR_GetError()))
    {
        if (verbosity > quiet)
            PR_fprintf(logFile, "Client connect 'in progress'\n");
        do
        {
            polldesc.fd = stack;
            polldesc.out_flags = 0;
            polldesc.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
            ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
            if ((1 != ready)  /* if not 1, then we're dead */
            || (0 == (polldesc.in_flags & polldesc.out_flags)))
                { PR_NOT_REACHED("Whoa!"); break; }
            if (verbosity > quiet)
                PR_fprintf(
                    logFile, "Client connect 'in progress' [0x%x]\n",
                    polldesc.out_flags);
            rv = PR_GetConnectStatus(&polldesc);
            if ((PR_FAILURE == rv)
            && (PR_IN_PROGRESS_ERROR != PR_GetError())) break;
        } while (PR_FAILURE == rv);
    }
    PR_ASSERT(PR_SUCCESS == rv);
    if (verbosity > chatty)
        PR_fprintf(logFile, "Client created connection\n");

    for (mits = 0; mits < minor_iterations; ++mits)
    {
        bytes_sent = 0;
        if (verbosity > quiet)
            PR_fprintf(logFile, "Client sending %d bytes\n", sizeof(buffer));
        do
        {
            if (verbosity > chatty)
                PR_fprintf(
                    logFile, "Client sending %d bytes\n",
                    sizeof(buffer) - bytes_sent);
            ready = PR_Send(
                stack, buffer + bytes_sent, sizeof(buffer) - bytes_sent,
                empty_flags, PR_INTERVAL_NO_TIMEOUT);
            if (verbosity > chatty)
                PR_fprintf(logFile, "Client send status [%d]\n", ready);
            if (0 < ready) bytes_sent += ready;
            else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
            {
                polldesc.fd = stack;
                polldesc.out_flags = 0;
                polldesc.in_flags = PR_POLL_WRITE;
                ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
                if ((1 != ready)  /* if not 1, then we're dead */
                || (0 == (polldesc.in_flags & polldesc.out_flags)))
                    { PR_NOT_REACHED("Whoa!"); break; }
            }
            else break;
        } while (bytes_sent < sizeof(buffer));
        PR_ASSERT(sizeof(buffer) == bytes_sent);

        bytes_read = 0;
        do
        {
            if (verbosity > chatty)
                PR_fprintf(
                    logFile, "Client receiving %d bytes\n",
                    bytes_sent - bytes_read);
            ready = PR_Recv(
                stack, buffer + bytes_read, bytes_sent - bytes_read,
                empty_flags, PR_INTERVAL_NO_TIMEOUT);
            if (verbosity > chatty)
                PR_fprintf(
                    logFile, "Client receive status [%d]\n", ready);
            if (0 < ready) bytes_read += ready;
            else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
            {
                polldesc.fd = stack;
                polldesc.out_flags = 0;
                polldesc.in_flags = PR_POLL_READ;
                ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
                if ((1 != ready)  /* if not 1, then we're dead */
                || (0 == (polldesc.in_flags & polldesc.out_flags)))
                    { PR_NOT_REACHED("Whoa!"); break; }
            }
            else break;
        } while (bytes_read < bytes_sent);
        if (verbosity > chatty)
            PR_fprintf(logFile, "Client received %d bytes\n", bytes_read);
        PR_ASSERT(bytes_read == bytes_sent);
    }

    if (verbosity > quiet)
        PR_fprintf(logFile, "Client shutting down stack\n");
    
    rv = PR_Shutdown(stack, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);
}  /* Client */
Esempio n. 20
0
int main(int argc, char **argv)
{
    PRHostEnt he;
    char buf[1024];
    PRNetAddr addr;
    PRFileDesc *sock;
    PRPollDesc pd;
    PRStatus rv;
    PRSocketOptionData optData;
    PRIntn n;

#ifdef XP_MAC
	int index;
	PRIntervalTime timeout;
	SetupMacPrintfLog("nbconn.log");
	for (index=0; index<4; index++) {
	argv[1] = hosts[index];
	timeout = PR_INTERVAL_NO_TIMEOUT;
	if (index == 3)
		timeout = PR_SecondsToInterval(10UL);
#endif

    PR_STDIO_INIT();
#ifndef XP_MAC
    if (argc != 2) {
        fprintf(stderr, "Usage: nbconn <hostname>\n");
        exit(1);
    }
#endif

    if (PR_GetHostByName(argv[1], buf, sizeof(buf), &he) == PR_FAILURE) {
        printf( "Unknown host: %s\n", buf);
        exit(1);
    } else {
        printf( "host: %s\n", buf);
    }
    PR_EnumerateHostEnt(0, &he, 80, &addr);

    sock = PR_NewTCPSocket();
    optData.option = PR_SockOpt_Nonblocking;
    optData.value.non_blocking = PR_TRUE;
    PR_SetSocketOption(sock, &optData);
    rv = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
    if (rv == PR_FAILURE && PR_GetError() == PR_IN_PROGRESS_ERROR) {
        printf( "Connect in progress\n");
    }

    pd.fd = sock;
    pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
#ifndef XP_MAC
    n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
#else
    n = PR_Poll(&pd, 1, timeout);
#endif
    if (n == -1) {
        printf( "PR_Poll failed\n");
        exit(1);
    }
    printf( "PR_Poll returns %d\n", n);
    if (pd.out_flags & PR_POLL_READ) {
        printf( "PR_POLL_READ\n");
    }
    if (pd.out_flags & PR_POLL_WRITE) {
        printf( "PR_POLL_WRITE\n");
    }
    if (pd.out_flags & PR_POLL_EXCEPT) {
        printf( "PR_POLL_EXCEPT\n");
    }
    if (pd.out_flags & PR_POLL_ERR) {
        printf( "PR_POLL_ERR\n");
    }
    if (pd.out_flags & PR_POLL_NVAL) {
        printf( "PR_POLL_NVAL\n");
    }

    if (PR_GetConnectStatus(&pd) == PR_SUCCESS) {
        printf("PR_GetConnectStatus: connect succeeded\n");
        /* Mac and Win16 have trouble printing to the console. */
#if !defined(XP_MAC) && !defined(WIN16)
        PR_Write(sock, "GET /\r\n\r\n", 9);
        PR_Shutdown(sock, PR_SHUTDOWN_SEND);
        pd.in_flags = PR_POLL_READ;
        while (1) {
            n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
            printf( "poll returns %d\n", n);
            n = PR_Read(sock, buf, sizeof(buf));
            printf( "read returns %d\n", n);
            if (n <= 0) {
                break;
            }
            PR_Write(PR_STDOUT, buf, n);
        }
#endif
    } else {
        if (PR_GetError() == PR_IN_PROGRESS_ERROR) {
            printf( "PR_GetConnectStatus: connect still in progress\n");
            exit(1);
        }
        printf( "PR_GetConnectStatus: connect failed: (%ld, %ld)\n",
                PR_GetError(), PR_GetOSError());
    }
    PR_Close(sock);
#ifdef XP_MAC
	} /* end of for loop */
#endif

    printf( "PASS\n");
    return 0;
}
Esempio n. 21
0
static void PR_CALLBACK
ClientThread(void *_action)
{
    PRInt32 action = * (PRInt32 *) _action;
    PRInt32 iterations = count;
    PRFileDesc *sock = NULL;

    serverAddr.inet.family = AF_INET;
    serverAddr.inet.port = PR_htons(BASE_PORT);
    serverAddr.inet.ip = PR_htonl(INADDR_LOOPBACK);

    for (; iterations--;) {
        PRInt32 rv;
        char buf[CLIENT_DATA];

        sock = PR_NewTCPSocket();
        if (!sock) {
            if (!debug_mode)
                failed_already=1;
            else    
                printf("client: unable to create socket\n");
            return;
        }

        if (action != CLIENT_TIMEOUT_ACCEPT) {

            if ((rv = PR_Connect(sock, &serverAddr,
                timeoutTime)) < 0) {
                if (!debug_mode)
                    failed_already=1;
                else    
                    printf(
                        "client: unable to connect to server (%ld, %ld, %ld, %ld)\n",
                        iterations, rv, PR_GetError(),
                        PR_GetOSError());
                goto ErrorExit;
            }

            if (action != CLIENT_TIMEOUT_SEND) {
                if ((rv = PR_Send(sock, buf, CLIENT_DATA,
                    0, timeoutTime))< 0) {
                    if (!debug_mode)
                        failed_already=1;
                    else    
                        printf("client: unable to send to server (%d, %ld, %ld)\n",
                            CLIENT_DATA, rv,
                            PR_GetError());
                	goto ErrorExit;
                }
            } else {
                PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS+
                    1));
            }
        } else {
            PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS+
                1));
        }
        if (debug_mode)
            printf(".");
        PR_Close(sock);
    }
    if (debug_mode)
        printf("\n");

ErrorExit:
	if (sock != NULL)
        PR_Close(sock);
}
/* one copy of this function is launched in a separate thread for each
** connection to be made.
*/
SECStatus
do_connects(void *a, int connection)
{
	PRNetAddr  *addr = (PRNetAddr *)a;
	PRFileDesc *sslSocket;
	PRHostEnt   hostEntry;
	char        buffer[PR_NETDB_BUF_SIZE];
	PRStatus    prStatus;
	PRIntn      hostenum;
	PRInt32    ip;
	SECStatus   secStatus;

	/* Set up SSL secure socket. */
	sslSocket = setupSSLSocket(addr);
	if (sslSocket == NULL) {
		errWarn("setupSSLSocket");
		return SECFailure;
	}

	secStatus = SSL_SetPKCS11PinArg(sslSocket, &pwdata);
	if (secStatus != SECSuccess) {
		errWarn("SSL_SetPKCS11PinArg");
		return secStatus;
	}

	secStatus = SSL_SetURL(sslSocket, hostName);
	if (secStatus != SECSuccess) {
		errWarn("SSL_SetURL");
		return secStatus;
	}

	/* Prepare and setup network connection. */
	prStatus = PR_GetHostByName(hostName, buffer, sizeof(buffer), &hostEntry);
	if (prStatus != PR_SUCCESS) {
		errWarn("PR_GetHostByName");
		return SECFailure;
	}

	hostenum = PR_EnumerateHostEnt(0, &hostEntry, port, addr);
	if (hostenum == -1) {
		errWarn("PR_EnumerateHostEnt");
		return SECFailure;
	}

 	ip = PR_ntohl(addr->inet.ip);
	fprintf(stderr,
	 	"Connecting to host %s (addr %d.%d.%d.%d) on port %d\n",
			hostName, BYTE(3,ip), BYTE(2,ip), BYTE(1,ip), 
			BYTE(0,ip), PR_ntohs(addr->inet.port)); 

	prStatus = PR_Connect(sslSocket, addr, PR_INTERVAL_NO_TIMEOUT);
	if (prStatus != PR_SUCCESS) {
		errWarn("PR_Connect");
		return SECFailure;
	}

	/* Established SSL connection, ready to send data. */
#if 0
	secStatus = SSL_ForceHandshake(sslSocket);
	if (secStatus != SECSuccess) {
		errWarn("SSL_ForceHandshake");
		return secStatus;
	}
#endif

	secStatus = SSL_ResetHandshake(sslSocket, /* asServer */ PR_FALSE);
	if (secStatus != SECSuccess) {
		errWarn("SSL_ResetHandshake");
		prStatus = PR_Close(sslSocket);
		if (prStatus != PR_SUCCESS) {
			errWarn("PR_Close");
		}
		return secStatus;
	}

	secStatus = handle_connection(sslSocket, connection);
	if (secStatus != SECSuccess) {
		/* error already printed out in handle_connection */
		/* errWarn("handle_connection"); */
		prStatus = PR_Close(sslSocket);
		if (prStatus != PR_SUCCESS) {
			errWarn("PR_Close");
		}
		return secStatus;
	}

	PR_Close(sslSocket);
	return SECSuccess;
}
Esempio n. 23
0
/** Create socket and connect to it.
  @param hostname Hostname to connect
  @param port Port name/number to connect
  @param mode Connection mode. Bit-array of MODE_NO_SSL, MODE_IP6MODE, MODE_IP4MODE.
  @return NULL on error, otherwise connected socket.
*/
static PRFileDesc *create_connected_socket(char *hostname,int port,int mode) {
  PRAddrInfo *addr_info;
  void *addr_iter;
  PRNetAddr addr;
  PRFileDesc *localsocket;
  int can_exit,valid_socket;
  PRUint16 af_spec;

  localsocket=NULL;

  addr_info=NULL;

  af_spec=PR_AF_UNSPEC;

  if (!(mode&MODE_IP6MODE)) af_spec=PR_AF_INET;

  addr_info=PR_GetAddrInfoByName(hostname,af_spec,PR_AI_ADDRCONFIG);

  if (addr_info == NULL) {
    print_nspr_error();
    return NULL;
  }

  /*We have socket -> enumerate and try to connect*/
  addr_iter=NULL;
  can_exit=0;
  valid_socket=0;

  while (!can_exit) {
    addr_iter=PR_EnumerateAddrInfo(addr_iter,addr_info,port,&addr);

    if (addr_iter==NULL) {
      can_exit=1;
    } else {
      if ((PR_NetAddrFamily(&addr)==PR_AF_INET && (mode&MODE_IP4MODE)) ||
          (PR_NetAddrFamily(&addr)==PR_AF_INET6 && (mode&MODE_IP6MODE))) {
        /*Type of address is what user want, try to create socket and make connection*/

        /*Create socket*/
        localsocket=create_socket(!(mode&MODE_NO_SSL),(PR_NetAddrFamily(&addr)==PR_AF_INET6));

        if (localsocket) {
          /*Try to connect*/
          if (PR_Connect(localsocket,&addr,PR_INTERVAL_NO_TIMEOUT)==PR_SUCCESS) {
            /*Force handshake*/
            if ((!(mode&MODE_NO_SSL)) && SSL_ForceHandshake(localsocket)!=SECSuccess) {
              /*Handhake failure -> fail*/
              print_nspr_error();
              if (PR_Close(localsocket)!=PR_SUCCESS) {
                print_nspr_error();
                can_exit=1;
              }
              localsocket=NULL;
            }

            /*Socket is connected -> we can return it*/
            can_exit=1;
          } else {
            /*Try another address*/
            if (PR_Close(localsocket)!=PR_SUCCESS) {
              print_nspr_error();
              can_exit=1;
            }
            localsocket=NULL;
          }
        }
      }
    }
  }

  if (!localsocket) {
    /*Socket is unvalid -> we don't found any usable address*/
    fprintf(stderr,"Can't connect to host %s on port %d!\n",hostname,port);
  }

  PR_FreeAddrInfo(addr_info);

  return localsocket;
}
Esempio n. 24
0
static void PR_CALLBACK
clientThreadFunc(void *arg)
{
    PRUintn port = (PRUintn)arg;
    PRFileDesc *sock;
    PRNetAddr addr;
    char buf[CHUNK_SIZE];
    int i;
    PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME);
    PRIntn optval = 1;
    PRStatus retVal;
    PRInt32 nBytes;

    addr.inet.family = AF_INET;
    addr.inet.port = PR_htons((PRUint16)port);
    addr.inet.ip = PR_htonl(INADDR_LOOPBACK);
    PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.ip);

    /* time 1 */
    PR_Sleep(unitTime);
    sock = PR_NewTCPSocket();
    PR_SetSockOpt(sock, PR_SockOpt_Nonblocking, &optval, sizeof(optval));
    retVal = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
    if (retVal == PR_FAILURE && PR_GetError() == PR_IN_PROGRESS_ERROR) {
#if !defined(USE_PR_SELECT)
	PRPollDesc pd;
	PRInt32 n;
	fprintf(stderr, "connect: EWOULDBLOCK, good\n");
	pd.fd = sock;
	pd.in_flags = PR_POLL_WRITE;
	n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
	PR_ASSERT(n == 1);
        PR_ASSERT(pd.out_flags == PR_POLL_WRITE);
#else
        PR_fd_set writeSet;
        PRInt32 n;
        fprintf(stderr, "connect: EWOULDBLOCK, good\n");
        PR_FD_ZERO(&writeSet);
        PR_FD_SET(sock, &writeSet);
        n = PR_Select(0, NULL, &writeSet, NULL, PR_INTERVAL_NO_TIMEOUT);
        PR_ASSERT(n == 1);
        PR_ASSERT(PR_FD_ISSET(sock, &writeSet));
#endif
    }
    printf("client connected\n");
    fflush(stdout);

    /* time 4, 7, 11, etc. */
    for (i = 0; i < NUMBER_ROUNDS; i++) {
        PR_Sleep(3 * unitTime);
    	nBytes = PR_Write(sock, buf, sizeof(buf));
	    if (nBytes == -1) {
	    if (PR_GetError() == PR_WOULD_BLOCK_ERROR) {
		fprintf(stderr, "write: EWOULDBLOCK\n");
		exit(1);
            } else {
		fprintf(stderr, "write: failed\n");
            }
	}
	printf("client sent %d bytes\n", nBytes);
	fflush(stdout);
    }

    PR_Close(sock);
}
Esempio n. 25
0
int FileSSLDoublePoint_main(char * strUserPin, char * strNickName)
{
#if 1
    int isServer = 0;
    
    SECStatus rv = SECSuccess;
    
    
    char * buffer = malloc(1024 * 1024);
    
    
    PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
    
    PK11_SetPasswordFunc(GetModulePassword);
    rv = NSS_Initialize(GetSystemDBDir(),
                        "", "",
                        "secmod.db", 0);
    
    
    rv = SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE);
    rv = SSL_OptionSetDefault(SSL_SOCKS, PR_TRUE);
    rv = SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_TRUE);
    rv = SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_TRUE);
    rv = SSL_OptionSetDefault(SSL_ENABLE_FDX, PR_TRUE);
    
    rv = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE);
    
    rv = NSS_SetDomesticPolicy();
    rv = NSS_SetExportPolicy();
    rv = NSS_SetFrancePolicy();
    //    rv = SSL_CipherPolicySet();
    
    
    
    SSL_ClearSessionCache();
    
    rv = SSL_ConfigServerSessionIDCache(10, 30 , 30, ".");
    
    
    PRFileDesc * tcp_socket = PR_NewTCPSocket();
    
    PRFileDesc * ssl_socket = SSL_ImportFD(NULL,tcp_socket);
    
    if (isServer) {
        
        CERTCertDBHandle *certHandle;
        
        certHandle = CERT_GetDefaultCertDB();
        
        char * nickname = "4914afeedee988071490b98f1120ddac_e73f20c7-176d-4342-ac89-ea7c00bb570a";/*nickname*/
        
        CERTCertificate* cert = NULL;
        cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, nickname);
        
        
        SECKEYPrivateKey *prvKey = NULL;
        
        prvKey = PK11_FindKeyByAnyCert(cert, NULL);
        
        rv = SSL_ConfigSecureServer(ssl_socket, cert,prvKey,ssl_kea_rsa);
        
        
        PRNetAddr netAddr;
        
        PRNetAddr netAddrLocal;
        
        
        rv = PR_InitializeNetAddr(0, 8888, &netAddr);
        
        
        rv = PR_StringToNetAddr("127.0.0.1", &netAddrLocal);
        
        rv = PR_Bind(tcp_socket,&netAddr);
        rv = PR_Listen(tcp_socket, 100);
        
        
        while (1) {
            PRFileDesc * client = PR_Accept(tcp_socket, &netAddr, 6000000);
            PRNetAddr addr;
            
            
            rv = PR_GetSockName(client, &addr);
            
            rv = SSL_ForceHandshake(client);
            
            
            rv = PR_Write(client,"123", 4);
            
            sleep(1);
        }
        
    }
    else
    {
        rv = SSL_AuthCertificateHook(ssl_socket, OwnAuthCertHandler, NULL);
        char * nickname = "nickname";/*nickname*/
        
        rv = SSL_SetURL(ssl_socket, "192.168.18.22");
        
        char * str = malloc(1024) ;

		memset(str, 0, 1024);
        
        strcpy(str ,"GET /test/test2.html HTTP/1.1\r\n");//注意\r\n为回车换行
        //        str = [str stringByAppendingString:@"Accept-Language: zh-cn\r\n"];
        //        str = [str stringByAppendingString:@"Connection: Keep-Alive\r\n"];
        //str = [str stringByAppendingString:@"Host: 192.168.0.106\r\n"];
        strcat(str ,"Host: 192.168.18.22:8443\r\n");
        //        str = [str stringByAppendingString:@"Content-Length: 0\r\n"];
        strcat(str ,"\r\n");
        //        str = [str stringByAppendingString:@"userName=liqiangqiang&password=new_andy\r\n"];
        //        str = [str stringByAppendingString:@"\r\n"];
        
        PRNetAddr netAddr;
        
        
        rv = PR_StringToNetAddr("192.168.18.22", &netAddr);
        
        rv = PR_InitializeNetAddr(0, 8443, &netAddr);
        
        //        rv = PR_GetHostByName();
        //        PR_EnumerateHostEnt
        
        
        rv = PR_Connect(tcp_socket,&netAddr, 300000);

		FILE_LOG_NUMBER("/sdcard/ssl.log", rv);

        rv = SSL_GetClientAuthDataHook(ssl_socket,NSS_GetClientAuthData,strNickName);

		FILE_LOG_NUMBER("/sdcard/ssl.log", rv);
        
        rv = SSL_ForceHandshake(ssl_socket);
        
		FILE_LOG_NUMBER("/sdcard/ssl.log", rv);
        
        rv = PR_Write(tcp_socket, str, strlen(str));
        
		FILE_LOG_NUMBER("/sdcard/ssl.log", rv);

        rv = PR_Read(tcp_socket,buffer, 1024 * 1024);

		FILE_LOG_NUMBER("/sdcard/ssl.log", rv);
        
        FILE * file = fopen("/sdcard/ssl_read.txt", "wb");
        
        //fwrite(buffer, 1, rv, file);

        //rv = PR_Read(tcp_socket,buffer, 1024 * 1024);
        
        fwrite(buffer, 1, rv, file);
        
        fclose(file);
        
        sleep(1);
        
        
        rv = SSL_InvalidateSession(ssl_socket);
        
        rv = PR_Shutdown(tcp_socket, PR_SHUTDOWN_BOTH);
        
        rv = PR_Close(tcp_socket);
        
        rv = ssl_FreeSessionCacheLocks();
        
        rv = NSS_Shutdown();
        
    }
#endif
    
    return 0;
}
PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *f[])
{
#ifdef XP_UNIX
	PRInt32 rv, osfd[2];

	if (!_pr_initialized) _PR_ImplicitInitialization();

	rv = _PR_MD_SOCKETPAIR(AF_UNIX, SOCK_STREAM, 0, osfd);
	if (rv == -1) {
		return PR_FAILURE;
	}

	f[0] = PR_AllocFileDesc(osfd[0], PR_GetTCPMethods());
	if (!f[0]) {
		_PR_MD_CLOSE_SOCKET(osfd[0]);
		_PR_MD_CLOSE_SOCKET(osfd[1]);
		/* PR_AllocFileDesc() has invoked PR_SetError(). */
		return PR_FAILURE;
	}
	f[1] = PR_AllocFileDesc(osfd[1], PR_GetTCPMethods());
	if (!f[1]) {
		PR_Close(f[0]);
		_PR_MD_CLOSE_SOCKET(osfd[1]);
		/* PR_AllocFileDesc() has invoked PR_SetError(). */
		return PR_FAILURE;
	}
	_PR_MD_MAKE_NONBLOCK(f[0]);
	_PR_MD_INIT_FD_INHERITABLE(f[0], PR_FALSE);
	_PR_MD_MAKE_NONBLOCK(f[1]);
	_PR_MD_INIT_FD_INHERITABLE(f[1], PR_FALSE);
	return PR_SUCCESS;
#elif defined(WINNT)
    /*
     * A socket pair is often used for interprocess communication,
     * so we need to make sure neither socket is associated with
     * the I/O completion port; otherwise it can't be used by a
     * child process.
     *
     * The default implementation below cannot be used for NT
     * because PR_Accept would have associated the I/O completion
     * port with the listening and accepted sockets.
     */
    SOCKET listenSock;
    SOCKET osfd[2];
    struct sockaddr_in selfAddr, peerAddr;
    int addrLen;

    if (!_pr_initialized) _PR_ImplicitInitialization();

    osfd[0] = osfd[1] = INVALID_SOCKET;
    listenSock = socket(AF_INET, SOCK_STREAM, 0);
    if (listenSock == INVALID_SOCKET) {
        goto failed;
    }
    selfAddr.sin_family = AF_INET;
    selfAddr.sin_port = 0;
    selfAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* BugZilla: 35408 */
    addrLen = sizeof(selfAddr);
    if (bind(listenSock, (struct sockaddr *) &selfAddr,
            addrLen) == SOCKET_ERROR) {
        goto failed;
    }
    if (getsockname(listenSock, (struct sockaddr *) &selfAddr,
            &addrLen) == SOCKET_ERROR) {
        goto failed;
    }
    if (listen(listenSock, 5) == SOCKET_ERROR) {
        goto failed;
    }
    osfd[0] = socket(AF_INET, SOCK_STREAM, 0);
    if (osfd[0] == INVALID_SOCKET) {
        goto failed;
    }
    selfAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

    /*
     * Only a thread is used to do the connect and accept.
     * I am relying on the fact that connect returns
     * successfully as soon as the connect request is put
     * into the listen queue (but before accept is called).
     * This is the behavior of the BSD socket code.  If
     * connect does not return until accept is called, we
     * will need to create another thread to call connect.
     */
    if (connect(osfd[0], (struct sockaddr *) &selfAddr,
            addrLen) == SOCKET_ERROR) {
        goto failed;
    }
    /*
     * A malicious local process may connect to the listening
     * socket, so we need to verify that the accepted connection
     * is made from our own socket osfd[0].
     */
    if (getsockname(osfd[0], (struct sockaddr *) &selfAddr,
            &addrLen) == SOCKET_ERROR) {
        goto failed;
    }
    osfd[1] = accept(listenSock, (struct sockaddr *) &peerAddr, &addrLen);
    if (osfd[1] == INVALID_SOCKET) {
        goto failed;
    }
    if (peerAddr.sin_port != selfAddr.sin_port) {
        /* the connection we accepted is not from osfd[0] */
        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
        goto failed;
    }
    closesocket(listenSock);

    f[0] = PR_AllocFileDesc(osfd[0], PR_GetTCPMethods());
    if (!f[0]) {
        closesocket(osfd[0]);
        closesocket(osfd[1]);
        /* PR_AllocFileDesc() has invoked PR_SetError(). */
        return PR_FAILURE;
    }
    f[1] = PR_AllocFileDesc(osfd[1], PR_GetTCPMethods());
    if (!f[1]) {
        PR_Close(f[0]);
        closesocket(osfd[1]);
        /* PR_AllocFileDesc() has invoked PR_SetError(). */
        return PR_FAILURE;
    }
    _PR_MD_INIT_FD_INHERITABLE(f[0], PR_FALSE);
    _PR_MD_INIT_FD_INHERITABLE(f[1], PR_FALSE);
    return PR_SUCCESS;

failed:
    if (listenSock != INVALID_SOCKET) {
        closesocket(listenSock);
    }
    if (osfd[0] != INVALID_SOCKET) {
        closesocket(osfd[0]);
    }
    if (osfd[1] != INVALID_SOCKET) {
        closesocket(osfd[1]);
    }
    return PR_FAILURE;
#else /* not Unix or NT */
    /*
     * default implementation
     */
    PRFileDesc *listenSock;
    PRNetAddr selfAddr, peerAddr;
    PRUint16 port;

    f[0] = f[1] = NULL;
    listenSock = PR_NewTCPSocket();
    if (listenSock == NULL) {
        goto failed;
    }
    PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr); /* BugZilla: 35408 */
    if (PR_Bind(listenSock, &selfAddr) == PR_FAILURE) {
        goto failed;
    }
    if (PR_GetSockName(listenSock, &selfAddr) == PR_FAILURE) {
        goto failed;
    }
    port = ntohs(selfAddr.inet.port);
    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
        goto failed;
    }
    f[0] = PR_NewTCPSocket();
    if (f[0] == NULL) {
        goto failed;
    }
#ifdef _PR_CONNECT_DOES_NOT_BIND
    /*
     * If connect does not implicitly bind the socket (e.g., on
     * BeOS), we have to bind the socket so that we can get its
     * port with getsockname later.
     */
    PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr);
    if (PR_Bind(f[0], &selfAddr) == PR_FAILURE) {
        goto failed;
    }
#endif
    PR_InitializeNetAddr(PR_IpAddrLoopback, port, &selfAddr);

    /*
     * Only a thread is used to do the connect and accept.
     * I am relying on the fact that PR_Connect returns
     * successfully as soon as the connect request is put
     * into the listen queue (but before PR_Accept is called).
     * This is the behavior of the BSD socket code.  If
     * connect does not return until accept is called, we
     * will need to create another thread to call connect.
     */
    if (PR_Connect(f[0], &selfAddr, PR_INTERVAL_NO_TIMEOUT)
            == PR_FAILURE) {
        goto failed;
    }
    /*
     * A malicious local process may connect to the listening
     * socket, so we need to verify that the accepted connection
     * is made from our own socket f[0].
     */
    if (PR_GetSockName(f[0], &selfAddr) == PR_FAILURE) {
        goto failed;
    }
    f[1] = PR_Accept(listenSock, &peerAddr, PR_INTERVAL_NO_TIMEOUT);
    if (f[1] == NULL) {
        goto failed;
    }
    if (peerAddr.inet.port != selfAddr.inet.port) {
        /* the connection we accepted is not from f[0] */
        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
        goto failed;
    }
    PR_Close(listenSock);
    return PR_SUCCESS;

failed:
    if (listenSock) {
        PR_Close(listenSock);
    }
    if (f[0]) {
        PR_Close(f[0]);
    }
    if (f[1]) {
        PR_Close(f[1]);
    }
    return PR_FAILURE;
#endif
}
int main(int argc, char **argv)
{
    PRHostEnt hostentry;
    char buf[PR_NETDB_BUF_SIZE];
    PRNetAddr addr;
    PRFileDesc *socket = NULL, *file = NULL;
    PRIntn cmdSize;
    char host[HOST_SIZE];
    char port[PORT_SIZE];
    char path[PATH_SIZE];
    char line[LINE_SIZE];
    int exitStatus = 0;
    PRBool endOfHeader = PR_FALSE;
    char *url;
    char *fileName = NULL;
    PRUint32 fileSize;

    if (argc != 2 && argc != 4) {
	PrintUsage();
	exit(1);
    }

    if (argc == 2) {
	/*
	 * case 1: httpget url
	 */
	url = argv[1];
    } else {
	if (strcmp(argv[1], "-o") == 0) {
	    /*
	     * case 2: httpget -o outputfile url
	     */
	    fileName = argv[2];
	    url = argv[3];
        } else {
	    /*
	     * case 3: httpget url -o outputfile
	     */
	    url = argv[1];
	    if (strcmp(argv[2], "-o") != 0) {
		PrintUsage();
		exit(1);
            }
	    fileName = argv[3];
	}
    }

    if (ParseURL(url, host, sizeof(host), port, sizeof(port),
	    path, sizeof(path)) == PR_FAILURE) {
	exit(1);
    }

    if (PR_GetHostByName(host, buf, sizeof(buf), &hostentry)
	    == PR_FAILURE) {
        fprintf(stderr, "httpget: unknown host name: %s\n", host);
	exit(1);
    }

    addr.inet.family = PR_AF_INET;
    addr.inet.port = PR_htons((short) atoi(port));
    addr.inet.ip = *((PRUint32 *) hostentry.h_addr_list[0]);

    socket = PR_NewTCPSocket();
    if (socket == NULL) {
	fprintf(stderr, "httpget: cannot create new tcp socket\n");
	exit(1);
    }

    if (PR_Connect(socket, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
	fprintf(stderr, "httpget: cannot connect to http server\n");
	exitStatus = 1;
	goto done;
    }

    if (fileName == NULL) {
	file = PR_STDOUT;
    } else {
        file = PR_Open(fileName, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE,
		00777);
        if (file == NULL) {
	    fprintf(stderr, "httpget: cannot open file %s: (%d, %d)\n",
		    fileName, PR_GetError(), PR_GetOSError());
	    exitStatus = 1;
	    goto done;
	}
    }

    cmdSize = PR_snprintf(buf, sizeof(buf), "GET %s HTTP/1.0\r\n\r\n", path);
    PR_ASSERT(cmdSize == (PRIntn) strlen("GET  HTTP/1.0\r\n\r\n")
            + (PRIntn) strlen(path));
    if (PR_Write(socket, buf, cmdSize) != cmdSize) {
	fprintf(stderr, "httpget: cannot write to http server\n");
	exitStatus = 1;
	goto done;
    }

    if (ReadLine(socket, line, sizeof(line)) <= 0) {
	fprintf(stderr, "httpget: cannot read line from http server\n");
	exitStatus = 1;
	goto done;
    }

    /* HTTP response: 200 == OK */
    if (strstr(line, "200") == NULL) {
	fprintf(stderr, "httpget: %s\n", line);
	exitStatus = 1;
	goto done;
    }

    while (ReadLine(socket, line, sizeof(line)) > 0) {
	if (line[0] == '\n') {
	    endOfHeader = PR_TRUE;
	    break;
	}
	if (strncmp(line, "Content-Length", 14) == 0
		|| strncmp(line, "Content-length", 14) == 0) {
	    char *p = line + 14;

	    while (*p == ' ' || *p == '\t') {
		p++;
	    }
	    if (*p != ':') {
		continue;
            }
	    p++;
	    while (*p == ' ' || *p == '\t') {
		p++;
	    }
	    fileSize = 0;
	    while ('0' <= *p && *p <= '9') {
		fileSize = 10 * fileSize + (*p - '0');
		p++;
            }
	}
    }
    if (endOfHeader == PR_FALSE) {
	fprintf(stderr, "httpget: cannot read line from http server\n");
	exitStatus = 1;
	goto done;
    }

    if (fileName == NULL || fileSize == 0) {
        FetchFile(socket, file);
    } else {
	FastFetchFile(socket, file, fileSize);
    }

done:
    if (socket) PR_Close(socket);
    if (file) PR_Close(file);
    PR_Cleanup();
    return exitStatus;
}