예제 #1
0
void
SpdyStream::GenerateDataFrameHeader(PRUint32 dataLength, bool lastFrame)
{
  LOG3(("SpdyStream::GenerateDataFrameHeader %p len=%d last=%d",
        this, dataLength, lastFrame));

  NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
  NS_ABORT_IF_FALSE(!mTxInlineFrameSize, "inline frame not empty");
  NS_ABORT_IF_FALSE(!mTxInlineFrameSent, "inline partial send not 0");
  NS_ABORT_IF_FALSE(!mTxStreamFrameSize, "stream frame not empty");
  NS_ABORT_IF_FALSE(!mTxStreamFrameSent, "stream partial send not 0");
  NS_ABORT_IF_FALSE(!(dataLength & 0xff000000), "datalength > 24 bits");
  
  (reinterpret_cast<PRUint32 *>(mTxInlineFrame.get()))[0] = PR_htonl(mStreamID);
  (reinterpret_cast<PRUint32 *>(mTxInlineFrame.get()))[1] =
    PR_htonl(dataLength);
  
  NS_ABORT_IF_FALSE(!(mTxInlineFrame[0] & 0x80),
                    "control bit set unexpectedly");
  NS_ABORT_IF_FALSE(!mTxInlineFrame[4], "flag bits set unexpectedly");
  
  mTxInlineFrameSize = 8;
  mTxStreamFrameSize = dataLength;

  if (lastFrame) {
    mTxInlineFrame[4] |= SpdySession::kFlag_Data_FIN;
    if (dataLength)
      mSentFinOnData = 1;
  }
}
/* copied from nsProtocolProxyService.cpp --- we should share this! */
static void
proxy_MaskIPv6Addr(PRIPv6Addr &addr, PRUint16 mask_len)
{
  if (mask_len == 128)
    return;

  if (mask_len > 96) {
    addr.pr_s6_addr32[3] = PR_htonl(
            PR_ntohl(addr.pr_s6_addr32[3]) & (~0L << (128 - mask_len)));
  }
  else if (mask_len > 64) {
    addr.pr_s6_addr32[3] = 0;
    addr.pr_s6_addr32[2] = PR_htonl(
            PR_ntohl(addr.pr_s6_addr32[2]) & (~0L << (96 - mask_len)));
  }
  else if (mask_len > 32) {
    addr.pr_s6_addr32[3] = 0;
    addr.pr_s6_addr32[2] = 0;
    addr.pr_s6_addr32[1] = PR_htonl(
            PR_ntohl(addr.pr_s6_addr32[1]) & (~0L << (64 - mask_len)));
  }
  else {
    addr.pr_s6_addr32[3] = 0;
    addr.pr_s6_addr32[2] = 0;
    addr.pr_s6_addr32[1] = 0;
    addr.pr_s6_addr32[0] = PR_htonl(
            PR_ntohl(addr.pr_s6_addr32[0]) & (~0L << (32 - mask_len)));
  }
}
예제 #3
0
nsresult
CacheFileMetadata::WriteMetadata(uint32_t aOffset,
                                 CacheFileMetadataListener *aListener)
{
  LOG(("CacheFileMetadata::WriteMetadata() [this=%p, offset=%d, listener=%p]",
       this, aOffset, aListener));

  MOZ_ASSERT(!mListener);
  MOZ_ASSERT(!mWriteBuf);
  MOZ_ASSERT(!mKeyIsHash);

  nsresult rv;

  mIsDirty = false;

  mWriteBuf = static_cast<char *>(moz_xmalloc(sizeof(uint32_t) +
                mHashCount * sizeof(CacheHashUtils::Hash16_t) +
                sizeof(CacheFileMetadataHeader) + mKey.Length() + 1 +
                mElementsSize + sizeof(uint32_t)));

  char *p = mWriteBuf + sizeof(uint32_t);
  memcpy(p, mHashArray, mHashCount * sizeof(CacheHashUtils::Hash16_t));
  p += mHashCount * sizeof(CacheHashUtils::Hash16_t);
  memcpy(p, &mMetaHdr, sizeof(CacheFileMetadataHeader));
  p += sizeof(CacheFileMetadataHeader);
  memcpy(p, mKey.get(), mKey.Length());
  p += mKey.Length();
  *p = 0;
  p++;
  memcpy(p, mBuf, mElementsSize);
  p += mElementsSize;

  CacheHashUtils::Hash32_t hash;
  hash = CacheHashUtils::Hash(mWriteBuf + sizeof(uint32_t),
                              p - mWriteBuf - sizeof(uint32_t));
  *reinterpret_cast<uint32_t *>(mWriteBuf) = PR_htonl(hash);

  *reinterpret_cast<uint32_t *>(p) = PR_htonl(aOffset);
  p += sizeof(uint32_t);

  mListener = aListener;
  rv = CacheFileIOManager::Write(mHandle, aOffset, mWriteBuf, p - mWriteBuf,
                                 true, this);
  if (NS_FAILED(rv)) {
    LOG(("CacheFileMetadata::WriteMetadata() - CacheFileIOManager::Write() "
         "failed synchronously. [this=%p, rv=0x%08x]", this, rv));

    mListener = nullptr;
    free(mWriteBuf);
    mWriteBuf = nullptr;
    NS_ENSURE_SUCCESS(rv, rv);
  }

  DoMemoryReport(MemoryUsage());

  return NS_OK;
}
static void PR_CALLBACK
clientThreadFunc(void *arg)
{
    PRUintn port = (PRUintn) arg;
    PRFileDesc *sock;
    PRNetAddr addr;
    char buf[128];
    int i;
    PRStatus sts;
    PRInt32 n;

    addr.inet.family = PR_AF_INET;
    addr.inet.port = PR_htons((PRUint16)port);
    addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
    memset(buf, 0, sizeof(buf));
    PR_snprintf(buf, sizeof(buf), "%hu", port);

    for (i = 0; i < NUM_ITERATIONS; i++) {
	sock = PR_NewTCPSocket();
	PR_ASSERT(sock != NULL);
	
    sts = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
	PR_ASSERT(sts == PR_SUCCESS);

	n = PR_Write(sock, buf, sizeof(buf));
	PR_ASSERT(n >= 0);

	sts = PR_Close(sock);
	PR_ASSERT(sts == PR_SUCCESS);
    }
}
예제 #5
0
PRFileDesc *
ServerSetup(void)
{
    PRFileDesc *listenSocket;
    PRNetAddr serverAddr;
    PRThread *WorkerThread;

    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
        if (debug_mode) printf("\tServer error creating listen socket\n");
		else failed_already=1;
        return NULL;
    }

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

    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
        if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
                PR_GetOSError());
		else failed_already=1;
        PR_Close(listenSocket);
        return NULL;
    }

    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
        if (debug_mode) printf("\tServer error listening to server socket\n");
		else failed_already=1;
        PR_Close(listenSocket);

        return NULL;
    }

    /* Create Clients */
    workerThreads = 0;
    workerThreadsBusy = 0;

    workerThreadsLock = PR_NewLock();

    WorkerThread = PR_CreateThread(
                      PR_SYSTEM_THREAD,
                      WorkerThreadFunc,
                      listenSocket,
                      PR_PRIORITY_NORMAL,
                      ServerScope,
                      PR_UNJOINABLE_THREAD,
                      STACKSIZE);

    if (!WorkerThread) {
        if (debug_mode) printf("error creating working thread\n");
        PR_Close(listenSocket);
        return NULL;
    }
    PR_AtomicIncrement(&workerThreads);
    if (debug_mode) DPRINTF("\tServer created primordial worker thread\n");

    return listenSocket;
}
예제 #6
0
UDPPusher::UDPPusher(const char *filename, unsigned port)
    : mFile(fopen(filename, "rb")),
      mFirstTimeMs(0),
      mFirstTimeUs(0) {
    CHECK(mFile != NULL);

    mSocket = PR_OpenUDPSocket(PR_AF_INET);
    if (!mSocket) {
        TRESPASS();
    }

    NetworkActivityMonitor::AttachIOLayer(mSocket);

    PRNetAddr addr;
    addr.inet.family = PR_AF_INET;
    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
    addr.inet.port = PR_htons(0);

    CHECK_EQ(PR_SUCCESS, PR_Bind(mSocket, &addr));

    mRemoteAddr.inet.family = PR_AF_INET;
    mRemoteAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
    mRemoteAddr.inet.port = PR_htons(port);
}
예제 #7
0
PRStatus
nsSOCKSSocketInfo::WriteV4ConnectRequest()
{
    PRNetAddr *addr = &mDestinationAddr;
    int32_t proxy_resolve;

    NS_ABORT_IF_FALSE(mState == SOCKS_CONNECTING_TO_PROXY,
                      "Invalid state!");
    
    proxy_resolve = mFlags & nsISocketProvider::PROXY_RESOLVES_HOST;

    mDataLength = 0;
    mState = SOCKS4_WRITE_CONNECT_REQUEST;

    LOGDEBUG(("socks4: sending connection request (socks4a resolve? %s)",
             proxy_resolve? "yes" : "no"));

    // Send a SOCKS 4 connect request.
    WriteUint8(0x04); // version -- 4
    WriteUint8(0x01); // command -- connect
    WriteNetPort(addr);
    if (proxy_resolve) {
        // Add the full name, null-terminated, to the request
        // according to SOCKS 4a. A fake IP address, with the first
        // four bytes set to 0 and the last byte set to something other
        // than 0, is used to notify the proxy that this is a SOCKS 4a
        // request. This request type works for Tor and perhaps others.
        WriteUint32(PR_htonl(0x00000001)); // Fake IP
        WriteUint8(0x00); // Send an emtpy username
        if (mDestinationHost.Length() > MAX_HOSTNAME_LEN) {
            LOGERROR(("socks4: destination host name is too long!"));
            HandshakeFinished(PR_BAD_ADDRESS_ERROR);
            return PR_FAILURE;
        }
        WriteString(mDestinationHost); // Hostname
        WriteUint8(0x00);
    } else if (PR_NetAddrFamily(addr) == PR_AF_INET) {
        WriteNetAddr(addr); // Add the IPv4 address
        WriteUint8(0x00); // Send an emtpy username
    } else if (PR_NetAddrFamily(addr) == PR_AF_INET6) {
        LOGERROR(("socks: SOCKS 4 can't handle IPv6 addresses!"));
        HandshakeFinished(PR_BAD_ADDRESS_ERROR);
        return PR_FAILURE;
    }

    return PR_SUCCESS;
}
예제 #8
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);
    }
}
예제 #9
0
/*
 * TransmitFile Server
 *    Server Thread
 *    Bind an address to a socket and listen for incoming connections
 *    Create worker threads to service clients
 */
static void
TransmitFile_Server(void *arg)
{
    PRThread **t = NULL;  /* an array of PRThread pointers */
    Server_Param *sp = (Server_Param *) arg;
    Serve_Client_Param *scp;
    PRFileDesc *sockfd = NULL, *newsockfd;
    PRNetAddr netaddr;
    PRInt32 i;
    PRThreadScope scope;

    t = (PRThread**)PR_MALLOC(num_transmitfile_clients * sizeof(PRThread *));
    if (t == NULL) {
        fprintf(stderr, "prsocket_test: run out of memory\n");
        failed_already=1;
        goto exit;
    }
    /*
     * Create a tcp socket
     */
    if ((sockfd = PR_NewTCPSocket()) == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n");
        failed_already=1;
        goto exit;
    }
    memset(&netaddr, 0 , sizeof(netaddr));
    netaddr.inet.family = AF_INET;
    netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
    netaddr.inet.ip = PR_htonl(INADDR_ANY);
    /*
     * try a few times to bind server's address, if addresses are in
     * use
     */
    i = 0;
    while (PR_Bind(sockfd, &netaddr) < 0) {
        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
            netaddr.inet.port += 2;
            if (i++ < SERVER_MAX_BIND_COUNT)
                continue;
        }
        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
        failed_already=1;
        perror("PR_Bind");
        goto exit;
    }

    if (PR_Listen(sockfd, 32) < 0) {
        fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n");
        failed_already=1;
        goto exit;
    }

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

    DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
        netaddr.inet.ip, netaddr.inet.port));
    tcp_server_addr.inet.family = netaddr.inet.family;
    tcp_server_addr.inet.port = netaddr.inet.port;
    tcp_server_addr.inet.ip = netaddr.inet.ip;

    /*
     * Wake up parent thread because server address is bound and made
     * available in the global variable 'tcp_server_addr'
     */
    PR_PostSem(sp->addr_sem);

    for (i = 0; i < num_transmitfile_clients ; i++) {

        if ((newsockfd = PR_Accept(sockfd, &netaddr,
            PR_INTERVAL_NO_TIMEOUT)) == NULL) {
            fprintf(stderr,
                "prsocket_test: ERROR - PR_Accept failed\n");
            failed_already=1;
            goto exit;
        }
        scp = PR_NEW(Serve_Client_Param);
        if (scp == NULL) {
            fprintf(stderr,"prsocket_test: PR_NEW failed\n");
            failed_already=1;
            goto exit;
        }

        /*
         * Start a Serve_Client thread for each incoming connection
         */
        scp->sockfd = newsockfd;
        scp->datalen = sp->datalen;

        /*
         * create LOCAL and GLOBAL threads alternately
         */
        if (i & 1)
            scope = PR_LOCAL_THREAD;
        else
            scope = PR_GLOBAL_THREAD;
        t[i] = PR_CreateThread(PR_USER_THREAD,
            Serve_TransmitFile_Client, (void *)scp, 
            PR_PRIORITY_NORMAL,
            scope,
            PR_JOINABLE_THREAD,
            0);
        if (t[i] == NULL) {
            fprintf(stderr,
                "prsocket_test: PR_CreateThread failed\n");
            failed_already=1;
            goto exit;
        }
        DPRINTF(("TransmitFile_Server: Created Serve_TransmitFile_Client = 0x%lx\n", t));
    }

    /*
     * Wait for all the worker threads to end, so that we know
     * they are no longer using the small and large file fd's.
     */

    for (i = 0; i < num_transmitfile_clients; i++) {
        PR_JoinThread(t[i]);
    }

exit:
    if (t) {
        PR_DELETE(t);
    }
    if (sockfd) {
        PR_Close(sockfd);
    }

    /*
     * Decrement exit_counter and notify parent thread
     */

    PR_EnterMonitor(sp->exit_mon);
    --(*sp->exit_counter);
    PR_Notify(sp->exit_mon);
    PR_ExitMonitor(sp->exit_mon);
    DPRINTF(("TransmitFile_Server [0x%lx] 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);
}
void
WorkerThreadFunc(void *_listenSock)
{
    PRFileDesc *listenSock = (PRFileDesc *)_listenSock;
    PRInt32 bytesRead;
    PRInt32 bytesWritten;
    char *dataBuf;
    char *sendBuf;

    if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
            _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32);
    dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32);
    if (!dataBuf)
        if (debug_mode) printf("\tServer could not malloc space!?\n");
    sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char));
    if (!sendBuf)
        if (debug_mode) printf("\tServer could not malloc space!?\n");

    if (debug_mode) DPRINTF("\tServer worker thread running\n");

    while(1) {
        PRInt32 bytesToRead = _client_data;
        PRInt32 bytesToWrite = _server_data;
        PRFileDesc *newSock;
        PRNetAddr *rAddr;
        PRInt32 loops = 0;

        loops++;

        if (debug_mode) DPRINTF("\tServer thread going into accept\n");

        bytesRead = PR_AcceptRead(listenSock, 
                                  &newSock,
                                  &rAddr,
                                  dataBuf,
                                  bytesToRead,
                                  PR_INTERVAL_NO_TIMEOUT);

        if (bytesRead < 0) {
            if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead);
            continue;
        }

        if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead);
        
        PR_AtomicIncrement(&workerThreadsBusy);
#ifdef SYMBIAN
        if (workerThreadsBusy == workerThreads && workerThreads<1) {
#else
        if (workerThreadsBusy == workerThreads) {
#endif
            PR_Lock(workerThreadsLock);
            if (workerThreadsBusy == workerThreads) {
                PRThread *WorkerThread;

                WorkerThread = PR_CreateThread(
                                  PR_SYSTEM_THREAD,
                                  WorkerThreadFunc,
                                  listenSock,
                                  PR_PRIORITY_NORMAL,
                                  ServerScope,
                                  PR_UNJOINABLE_THREAD,
                                  THREAD_STACKSIZE);

                if (!WorkerThread) {
                    if (debug_mode) printf("Error creating client thread %d\n", workerThreads);
                } else {
                    PR_AtomicIncrement(&workerThreads);
                    if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads);
                }
            }
            PR_Unlock(workerThreadsLock);
        }
 
        bytesToRead -= bytesRead;
        while (bytesToRead) {
            bytesRead = PR_Recv(newSock, 
                                dataBuf, 
                                bytesToRead, 
                                0, 
                                PR_INTERVAL_NO_TIMEOUT);
            if (bytesRead < 0) {
                if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead);
                continue;
            }
            if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead);
        }

        bytesWritten = PR_Send(newSock,
                               sendBuf, 
                               bytesToWrite, 
                               0, 
                               PR_INTERVAL_NO_TIMEOUT);
        if (bytesWritten != _server_data) {
            if (debug_mode) printf("\tError sending data to client (%d, %d)\n", 
                bytesWritten, PR_GetOSError());
        } else {
            if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten);
        }

        PR_Close(newSock);
        PR_AtomicDecrement(&workerThreadsBusy);
    }
}

PRFileDesc *
ServerSetup(void)
{
    PRFileDesc *listenSocket;
    PRSocketOptionData sockOpt;
    PRNetAddr serverAddr;
    PRThread *WorkerThread;

    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
        if (debug_mode) printf("\tServer error creating listen socket\n");
		else failed_already=1;
        return NULL;
    }

    sockOpt.option = PR_SockOpt_Reuseaddr;
    sockOpt.value.reuse_addr = PR_TRUE;
    if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) {
        if (debug_mode) printf("\tServer error setting socket option: OS error %d\n",
                PR_GetOSError());
		else failed_already=1;
        PR_Close(listenSocket);
        return NULL;
    }

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

    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
        if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
                PR_GetOSError());
		else failed_already=1;
        PR_Close(listenSocket);
        return NULL;
    }

    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
        if (debug_mode) printf("\tServer error listening to server socket\n");
		else failed_already=1;
        PR_Close(listenSocket);

        return NULL;
    }

    /* Create Clients */
    workerThreads = 0;
    workerThreadsBusy = 0;

    workerThreadsLock = PR_NewLock();

    WorkerThread = PR_CreateThread(
                      PR_SYSTEM_THREAD,
                      WorkerThreadFunc,
                      listenSocket,
                      PR_PRIORITY_NORMAL,
                      ServerScope,
                      PR_UNJOINABLE_THREAD,
                      THREAD_STACKSIZE);

    if (!WorkerThread) {
        if (debug_mode) printf("error creating working thread\n");
        PR_Close(listenSocket);
        return NULL;
    }
    PR_AtomicIncrement(&workerThreads);
    if (debug_mode) DPRINTF("\tServer created primordial worker thread\n");

    return listenSocket;
}
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 */
예제 #13
0
nsresult
SpdyStream::ParseHttpRequestHeaders(const char *buf,
                                    PRUint32 avail,
                                    PRUint32 *countUsed)
{
  // Returns NS_OK even if the headers are incomplete
  // set mSynFrameComplete flag if they are complete

  NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
  NS_ABORT_IF_FALSE(mUpstreamState == GENERATING_SYN_STREAM, "wrong state");

  LOG3(("SpdyStream::ParseHttpRequestHeaders %p avail=%d state=%x",
        this, avail, mUpstreamState));

  mFlatHttpRequestHeaders.Append(buf, avail);

  // We can use the simple double crlf because firefox is the
  // only client we are parsing
  PRInt32 endHeader = mFlatHttpRequestHeaders.Find("\r\n\r\n");
  
  if (endHeader == -1) {
    // We don't have all the headers yet
    LOG3(("SpdyStream::ParseHttpRequestHeaders %p "
          "Need more header bytes. Len = %d",
          this, mFlatHttpRequestHeaders.Length()));
    *countUsed = avail;
    return NS_OK;
  }
           
  // We have recvd all the headers, trim the local
  // buffer of the final empty line, and set countUsed to reflect
  // the whole header has been consumed.
  PRUint32 oldLen = mFlatHttpRequestHeaders.Length();
  mFlatHttpRequestHeaders.SetLength(endHeader + 2);
  *countUsed = avail - (oldLen - endHeader) + 4;
  mSynFrameComplete = 1;

  // It is now OK to assign a streamID that we are assured will
  // be monotonically increasing amongst syn-streams on this
  // session
  mStreamID = mSession->RegisterStreamID(this);
  NS_ABORT_IF_FALSE(mStreamID & 1,
                    "Spdy Stream Channel ID must be odd");

  if (mStreamID >= 0x80000000) {
    // streamID must fit in 31 bits. This is theoretically possible
    // because stream ID assignment is asynchronous to stream creation
    // because of the protocol requirement that the ID in syn-stream
    // be monotonically increasing. In reality this is really not possible
    // because new streams stop being added to a session with 0x10000000 / 2
    // IDs still available and no race condition is going to bridge that gap,
    // so we can be comfortable on just erroring out for correctness in that
    // case.
    LOG3(("Stream assigned out of range ID: 0x%X", mStreamID));
    return NS_ERROR_UNEXPECTED;
  }

  // Now we need to convert the flat http headers into a set
  // of SPDY headers..  writing to mTxInlineFrame{sz}

  mTxInlineFrame[0] = SpdySession::kFlag_Control;
  mTxInlineFrame[1] = 2;                          /* version */
  mTxInlineFrame[2] = 0;
  mTxInlineFrame[3] = SpdySession::CONTROL_TYPE_SYN_STREAM;
  // 4 to 7 are length and flags, we'll fill that in later
  
  PRUint32 networkOrderID = PR_htonl(mStreamID);
  memcpy(mTxInlineFrame + 8, &networkOrderID, 4);
  
  // this is the associated-to field, which is not used sending
  // from the client in the http binding
  memset (mTxInlineFrame + 12, 0, 4);

  // Priority flags are the C0 mask of byte 16.
  // From low to high: 00 40 80 C0
  // higher raw priority values are actually less important
  //
  // The other 6 bits of 16 are unused. Spdy/3 will expand
  // priority to 4 bits.
  //
  // When Spdy/3 implements WINDOW_UPDATE the lowest priority
  // streams over a threshold (32?) should be given tiny
  // receive windows, separate from their spdy priority
  //
  if (mPriority >= nsISupportsPriority::PRIORITY_LOW)
    mTxInlineFrame[16] = SpdySession::kPri00;
  else if (mPriority >= nsISupportsPriority::PRIORITY_NORMAL)
    mTxInlineFrame[16] = SpdySession::kPri01;
  else if (mPriority >= nsISupportsPriority::PRIORITY_HIGH)
    mTxInlineFrame[16] = SpdySession::kPri02;
  else
    mTxInlineFrame[16] = SpdySession::kPri03;

  mTxInlineFrame[17] = 0;                         /* unused */
  
//  nsCString methodHeader;
//  mTransaction->RequestHead()->Method()->ToUTF8String(methodHeader);
  const char *methodHeader = mTransaction->RequestHead()->Method().get();

  nsCString hostHeader;
  mTransaction->RequestHead()->GetHeader(nsHttp::Host, hostHeader);

  nsCString versionHeader;
  if (mTransaction->RequestHead()->Version() == NS_HTTP_VERSION_1_1)
    versionHeader = NS_LITERAL_CSTRING("HTTP/1.1");
  else
    versionHeader = NS_LITERAL_CSTRING("HTTP/1.0");

  nsClassHashtable<nsCStringHashKey, nsCString> hdrHash;
  
  // use mRequestHead() to get a sense of how big to make the hash,
  // even though we are parsing the actual text stream because
  // it is legit to append headers.
  hdrHash.Init(1 + (mTransaction->RequestHead()->Headers().Count() * 2));
  
  const char *beginBuffer = mFlatHttpRequestHeaders.BeginReading();

  // need to hash all the headers together to remove duplicates, special
  // headers, etc..

  PRInt32 crlfIndex = mFlatHttpRequestHeaders.Find("\r\n");
  while (true) {
    PRInt32 startIndex = crlfIndex + 2;

    crlfIndex = mFlatHttpRequestHeaders.Find("\r\n", false, startIndex);
    if (crlfIndex == -1)
      break;
    
    PRInt32 colonIndex = mFlatHttpRequestHeaders.Find(":", false, startIndex,
                                                      crlfIndex - startIndex);
    if (colonIndex == -1)
      break;
    
    nsDependentCSubstring name = Substring(beginBuffer + startIndex,
                                           beginBuffer + colonIndex);
    // all header names are lower case in spdy
    ToLowerCase(name);

    if (name.Equals("method") ||
        name.Equals("version") ||
        name.Equals("scheme") ||
        name.Equals("keep-alive") ||
        name.Equals("accept-encoding") ||
        name.Equals("te") ||
        name.Equals("connection") ||
        name.Equals("proxy-connection") ||
        name.Equals("url"))
      continue;
    
    nsCString *val = hdrHash.Get(name);
    if (!val) {
      val = new nsCString();
      hdrHash.Put(name, val);
    }

    PRInt32 valueIndex = colonIndex + 1;
    while (valueIndex < crlfIndex && beginBuffer[valueIndex] == ' ')
      ++valueIndex;
    
    nsDependentCSubstring v = Substring(beginBuffer + valueIndex,
                                        beginBuffer + crlfIndex);
    if (!val->IsEmpty())
      val->Append(static_cast<char>(0));
    val->Append(v);

    if (name.Equals("content-length")) {
      PRInt64 len;
      if (nsHttp::ParseInt64(val->get(), nsnull, &len))
        mRequestBodyLen = len;
    }
  }
  
  mTxInlineFrameSize = 18;

  LOG3(("http request headers to encode are: \n%s",
        mFlatHttpRequestHeaders.get()));

  // The header block length
  PRUint16 count = hdrHash.Count() + 4; /* method, scheme, url, version */
  CompressToFrame(count);

  // method, scheme, url, and version headers for request line

  CompressToFrame(NS_LITERAL_CSTRING("method"));
  CompressToFrame(methodHeader, strlen(methodHeader));
  CompressToFrame(NS_LITERAL_CSTRING("scheme"));
  CompressToFrame(NS_LITERAL_CSTRING("https"));
  CompressToFrame(NS_LITERAL_CSTRING("url"));
  CompressToFrame(mTransaction->RequestHead()->RequestURI());
  CompressToFrame(NS_LITERAL_CSTRING("version"));
  CompressToFrame(versionHeader);
  
  hdrHash.Enumerate(hdrHashEnumerate, this);
  CompressFlushFrame();
  
  // 4 to 7 are length and flags, which we can now fill in
  (reinterpret_cast<PRUint32 *>(mTxInlineFrame.get()))[1] =
    PR_htonl(mTxInlineFrameSize - 8);

  NS_ABORT_IF_FALSE(!mTxInlineFrame[4],
                    "Size greater than 24 bits");
  
  // For methods other than POST and PUT, we will set the fin bit
  // right on the syn stream packet.

  if (mTransaction->RequestHead()->Method() != nsHttp::Post &&
      mTransaction->RequestHead()->Method() != nsHttp::Put) {
    mSentFinOnData = 1;
    mTxInlineFrame[4] = SpdySession::kFlag_Data_FIN;
  }

  Telemetry::Accumulate(Telemetry::SPDY_SYN_SIZE, mTxInlineFrameSize - 18);

  // The size of the input headers is approximate
  PRUint32 ratio =
    (mTxInlineFrameSize - 18) * 100 /
    (11 + mTransaction->RequestHead()->RequestURI().Length() +
     mFlatHttpRequestHeaders.Length());
  
  Telemetry::Accumulate(Telemetry::SPDY_SYN_RATIO, ratio);
  return NS_OK;
}
예제 #14
0
/*
 * UDP Server
 *    Server Thread
 *    Bind an address to a socket, read data from clients and send data
 *    back to clients
 */
static void PR_CALLBACK
UDP_Server(void *arg)
{
    Server_Param *sp = (Server_Param *) arg;
    PRFileDesc *sockfd;
    buffer *in_buf;
    PRNetAddr netaddr;
    PRInt32 bytes, i, rv;


    bytes = sp->datalen;
    /*
     * Create a udp socket
     */
    if ((sockfd = PR_NewUDPSocket()) == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewUDPSocket failed\n");
        failed_already=1;
        return;
    }
    memset(&netaddr, 0 , sizeof(netaddr));
    netaddr.inet.family = AF_INET;
    netaddr.inet.port = PR_htons(UDP_SERVER_PORT);
    netaddr.inet.ip = PR_htonl(INADDR_ANY);
    /*
     * try a few times to bind server's address, if addresses are in
     * use
     */
    i = 0;
    while (PR_Bind(sockfd, &netaddr) < 0) {
        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
            netaddr.inet.port += 2;
            if (i++ < SERVER_MAX_BIND_COUNT)
                continue;
        }
        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
        perror("PR_Bind");
        failed_already=1;
        return;
    }

    if (PR_GetSockName(sockfd, &netaddr) < 0) {
        fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
        failed_already=1;
        return;
    }
    if (netaddr.inet.port != PR_htons(UDP_SERVER_PORT)) {
        fprintf(stderr,"prsocket_test: ERROR - tried to bind to UDP "
            "port %hu, but was bound to port %hu\n",
            UDP_SERVER_PORT, PR_ntohs(netaddr.inet.port));
        failed_already=1;
        return;
    }

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

    /*
     * We can't use the IP address returned by PR_GetSockName in
         * netaddr.inet.ip because netaddr.inet.ip is returned
         * as 0 (= INADDR_ANY).
     */

    udp_server_addr.inet.ip = PR_htonl(INADDR_LOOPBACK);

    /*
     * Wake up parent thread because server address is bound and made
     * available in the global variable 'udp_server_addr'
     */
    PR_PostSem(sp->addr_sem);

    bytes = sp->datalen;
    in_buf = PR_NEW(buffer);
    if (in_buf == NULL) {
        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
        failed_already=1;
        return;
    }
    /*
     * Receive datagrams from clients and send them back, unmodified, to the
     * clients
     */
    memset(&netaddr, 0 , sizeof(netaddr));
    for (i = 0; i < (num_udp_clients * num_udp_datagrams_per_client); i++) {
        DPRINTF(("UDP_Server: calling PR_RecvFrom client  - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n",
            netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data,
            in_buf->data[0]));

        rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr,
            PR_INTERVAL_NO_TIMEOUT);
        DPRINTF(("UDP_Server: PR_RecvFrom client  - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n",
            netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data,
            in_buf->data[0]));
        if (rv != bytes) {
            return;
        }
        rv = PR_SendTo(sockfd, in_buf->data, bytes, 0, &netaddr,
            PR_INTERVAL_NO_TIMEOUT);
        if (rv != bytes) {
            return;
        }
    }

    PR_DELETE(in_buf);

    /*
     * Decrement exit_counter and notify parent thread
     */
    PR_EnterMonitor(sp->exit_mon);
    --(*sp->exit_counter);
    PR_Notify(sp->exit_mon);
    PR_ExitMonitor(sp->exit_mon);
    DPRINTF(("UDP_Server [0x%x] exiting\n", PR_GetCurrentThread()));
}
예제 #15
0
static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
{
    PRFileDesc *listenSock, *sock;
    PRUint16 listenPort;
    PRNetAddr addr;
    char buf[CHUNK_SIZE];
    PRThread *clientThread;
    PRInt32 retVal;
    PRIntn optval = 1;
    PRIntn i;
    PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME);

#ifdef XP_MAC
	SetupMacPrintfLog("nonblock.log");
#endif

    /* Create a listening socket */
    if ((listenSock = PR_NewTCPSocket()) == NULL) {
	fprintf(stderr, "Can't create a new TCP socket\n");
	exit(1);
    }
    addr.inet.family = AF_INET;
    addr.inet.ip = PR_htonl(INADDR_ANY);
    addr.inet.port = PR_htons(0);
    if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
	fprintf(stderr, "Can't bind socket\n");
	exit(1);
    }
    if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
	fprintf(stderr, "PR_GetSockName failed\n");
	exit(1);
    }
    listenPort = PR_ntohs(addr.inet.port);
    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
	fprintf(stderr, "Can't listen on a socket\n");
	exit(1);
    }

    PR_snprintf(buf, sizeof(buf),
	    "The server thread is listening on port %hu\n\n",
	    listenPort);
    printf("%s", buf);

    clientThread = PR_CreateThread(PR_USER_THREAD,
	    clientThreadFunc, (void *) listenPort,
	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
	    PR_UNJOINABLE_THREAD, 0);
    if (clientThread == NULL) {
	fprintf(stderr, "can't create thread\n");
	exit(1);
    }

    printf("client thread created.\n");

    PR_SetSockOpt(listenSock, PR_SockOpt_Nonblocking, &optval,
	sizeof(PRIntn));
    /* time 0 */
    sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
    if (sock != NULL || PR_GetError() != PR_WOULD_BLOCK_ERROR) {
        PL_PrintError("First Accept\n");
        fprintf(stderr, "First PR_Accept() xxx\n" );
		    exit(1);
    }
    printf("accept: EWOULDBLOCK, good\n");
    fflush(stdout);
    /* time 2 */
    PR_Sleep(2 * unitTime);
    sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
    if (sock == NULL) {
        PL_PrintError("Second Accept\n");
        fprintf(stderr, "Second PR_Accept() failed: (%d, %d)\n",
                PR_GetError(), PR_GetOSError());
		    exit(1);
    }
    printf("accept: succeeded, good\n");
    fflush(stdout);
    PR_Close(listenSock);

    PR_SetSockOpt(sock, PR_SockOpt_Nonblocking, &optval, sizeof(PRIntn));

    /* time 3, 5, 6, 8, etc. */
    for (i = 0; i < NUMBER_ROUNDS; i++) {
	PR_Sleep(unitTime);
	retVal = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
	if (retVal != -1 || PR_GetError() != PR_WOULD_BLOCK_ERROR) {
        PL_PrintError("First Receive:\n");
	    fprintf(stderr, "First PR_Recv: retVal: %ld, Error: %ld\n",
            retVal, PR_GetError());
	    exit(1);
        }
	printf("read: EWOULDBLOCK, good\n");
	fflush(stdout);
	PR_Sleep(2 * unitTime);
	retVal = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
	if (retVal != CHUNK_SIZE) {
        PL_PrintError("Second Receive:\n");
	    fprintf(stderr, "Second PR_Recv: retVal: %ld, Error: %ld\n", 
            retVal, PR_GetError());
	    exit(1);
        }
	printf("read: %d bytes, good\n", retVal);
	fflush(stdout);
    }
    PR_Close(sock);

    printf("All tests finished\n");
    printf("PASS\n");
    return 0;
}
예제 #16
0
static PRInt32
TCP_Socket_Client_Server_Test(void)
{
    int i;
    PRThread *t;
    PRThreadScope scope;
    PRSemaphore *server_sem;
    Server_Param *sparamp;
    Client_Param *cparamp;
    PRMonitor *mon2;
    PRInt32    datalen;


    datalen = tcp_mesg_size;
    thread_count = 0;
    /*
     * start the server thread
     */
    sparamp = PR_NEW(Server_Param);
    if (sparamp == NULL) {
        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
        failed_already=1;
        return -1;
    }
    server_sem = PR_NewSem(0);
    if (server_sem == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewSem failed\n");
        failed_already=1;
        return -1;
    }
    mon2 = PR_NewMonitor();
    if (mon2 == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n");
        failed_already=1;
        return -1;
    }
    PR_EnterMonitor(mon2);

    sparamp->addr_sem = server_sem;
    sparamp->exit_mon = mon2;
    sparamp->exit_counter = &thread_count;
    sparamp->datalen = datalen;
    t = PR_CreateThread(PR_USER_THREAD,
        TCP_Server, (void *)sparamp, 
        PR_PRIORITY_NORMAL,
        PR_LOCAL_THREAD,
        PR_UNJOINABLE_THREAD,
        0);
    if (t == NULL) {
        fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
        failed_already=1;
        return -1;
    }
    DPRINTF(("Created TCP server = 0x%lx\n", t));
    thread_count++;

    /*
     * wait till the server address is setup
     */
    PR_WaitSem(server_sem);

    /*
     * Now start a bunch of client threads
     */

    cparamp = PR_NEW(Client_Param);
    if (cparamp == NULL) {
        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
        failed_already=1;
        return -1;
    }
    cparamp->server_addr = tcp_server_addr;
    cparamp->server_addr.inet.ip = PR_htonl(INADDR_LOOPBACK);
    cparamp->exit_mon = mon2;
    cparamp->exit_counter = &thread_count;
    cparamp->datalen = datalen;
    for (i = 0; i < num_tcp_clients; i++) {
        /*
         * Every other thread is a LOCAL/GLOBAL thread
         */
        if (i & 1)
            scope = PR_LOCAL_THREAD;
        else
            scope = PR_GLOBAL_THREAD;
        t = PR_CreateThread(PR_USER_THREAD,
            TCP_Client, (void *) cparamp,
            PR_PRIORITY_NORMAL,
            scope,
            PR_UNJOINABLE_THREAD,
            0);
        if (t == NULL) {
            fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
            failed_already=1;
            return -1;
        }
        DPRINTF(("Created TCP client = 0x%lx\n", t));
        thread_count++;
    }
    /* Wait for server and client threads to exit */
    while (thread_count) {
        PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
        DPRINTF(("TCP Server - thread_count  = %d\n", thread_count));
    }
    PR_ExitMonitor(mon2);
    printf("%30s","TCP_Socket_Client_Server_Test:");
    printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l,
        num_tcp_clients, num_tcp_connections_per_client);
    printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":",
        num_tcp_mesgs_per_connection, tcp_mesg_size);

    return 0;
}
int main(int argc, char **argv)
{
    PRFileDesc *listenSock1, *listenSock2;
    PRFileDesc *badFD;
    PRUint16 listenPort1, listenPort2;
    PRNetAddr addr;
    char buf[BUF_SIZE];
    PRThread *clientThread;
    PRPollDesc pds0[10], pds1[10], *pds, *other_pds;
    PRIntn npds;
    PRInt32 retVal;
    PRInt32 rv;
    PROsfd sd;
    struct sockaddr_in saddr;
    PRIntn saddr_len;
    PRUint16 listenPort3;
    PRFileDesc *socket_poll_fd;
    PRIntn i, j;

    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
    PR_STDIO_INIT();

    printf("This program tests PR_Poll with sockets.\n");
    printf("Timeout, error reporting, and normal operation are tested.\n\n");

    /* Create two listening sockets */
    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
	fprintf(stderr, "Can't create a new TCP socket\n");
	exit(1);
    }
    addr.inet.family = PR_AF_INET;
    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
    addr.inet.port = PR_htons(0);
    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
	fprintf(stderr, "Can't bind socket\n");
	exit(1);
    }
    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
	fprintf(stderr, "PR_GetSockName failed\n");
	exit(1);
    }
    listenPort1 = PR_ntohs(addr.inet.port);
    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
	fprintf(stderr, "Can't listen on a socket\n");
	exit(1);
    }

    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
	fprintf(stderr, "Can't create a new TCP socket\n");
	exit(1);
    }
    addr.inet.family = PR_AF_INET;
    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
    addr.inet.port = PR_htons(0);
    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
	fprintf(stderr, "Can't bind socket\n");
	exit(1);
    }
    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
	fprintf(stderr, "PR_GetSockName failed\n");
	exit(1);
    }
    listenPort2 = PR_ntohs(addr.inet.port);
    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
	fprintf(stderr, "Can't listen on a socket\n");
	exit(1);
    }
    /* Set up the poll descriptor array */
    pds = pds0;
    other_pds = pds1;
    memset(pds, 0, sizeof(pds));
	npds = 0;
    pds[npds].fd = listenSock1;
    pds[npds].in_flags = PR_POLL_READ;
	npds++;
    pds[npds].fd = listenSock2;
    pds[npds].in_flags = PR_POLL_READ;
	npds++;

	sd = socket(AF_INET, SOCK_STREAM, 0);
	PR_ASSERT(sd >= 0);
	memset((char *) &saddr, 0, sizeof(saddr));
	saddr.sin_family = AF_INET;
	saddr.sin_addr.s_addr = htonl(INADDR_ANY);
	saddr.sin_port = htons(0);

	rv = bind(sd, (struct sockaddr *)&saddr, sizeof(saddr));
	PR_ASSERT(rv == 0);
	saddr_len = sizeof(saddr);
	rv = getsockname(sd, (struct sockaddr *) &saddr, &saddr_len);
	PR_ASSERT(rv == 0);
    listenPort3 = ntohs(saddr.sin_port);

	rv = listen(sd, 5);
	PR_ASSERT(rv == 0);
    pds[npds].fd = socket_poll_fd = PR_CreateSocketPollFd(sd);
	PR_ASSERT(pds[npds].fd);
    pds[npds].in_flags = PR_POLL_READ;
    npds++;
    PR_snprintf(buf, sizeof(buf),
	    "The server thread is listening on ports %hu, %hu and %hu\n\n",
	    listenPort1, listenPort2, listenPort3);
    printf("%s", buf);

    /* Testing timeout */
    printf("PR_Poll should time out in 5 seconds\n");
    retVal = PR_Poll(pds, npds, PR_SecondsToInterval(5));
    if (retVal != 0) {
	PR_snprintf(buf, sizeof(buf),
		"PR_Poll should time out and return 0, but it returns %ld\n",
		retVal);
	fprintf(stderr, "%s", buf);
	exit(1);
    }
    printf("PR_Poll timed out.  Test passed.\n\n");

    /* Testing bad fd */
    printf("PR_Poll should detect a bad file descriptor\n");
    if ((badFD = PR_NewTCPSocket()) == NULL) {
	fprintf(stderr, "Can't create a TCP socket\n");
	exit(1);
    }

    pds[npds].fd = badFD;
    pds[npds].in_flags = PR_POLL_READ;
    npds++;
    PR_Close(badFD);  /* make the fd bad */
#if 0
    retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT);
    if (retVal != 1 || (unsigned short) pds[2].out_flags != PR_POLL_NVAL) {
	fprintf(stderr, "Failed to detect the bad fd: "
		"PR_Poll returns %d, out_flags is 0x%hx\n",
		retVal, pds[npds - 1].out_flags);
	exit(1);
    }
    printf("PR_Poll detected the bad fd.  Test passed.\n\n");
#endif
    npds--;

    clientThread = PR_CreateThread(PR_USER_THREAD,
	    clientThreadFunc, (void *) listenPort1,
	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
	    PR_UNJOINABLE_THREAD, 0);
    if (clientThread == NULL) {
	fprintf(stderr, "can't create thread\n");
	exit(1);
    }

    clientThread = PR_CreateThread(PR_USER_THREAD,
	    clientThreadFunc, (void *) listenPort2,
	    PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
	    PR_UNJOINABLE_THREAD, 0);
    if (clientThread == NULL) {
	fprintf(stderr, "can't create thread\n");
	exit(1);
    }

    clientThread = PR_CreateThread(PR_USER_THREAD,
	    clientThreadFunc, (void *) listenPort3,
	    PR_PRIORITY_NORMAL, PR_GLOBAL_BOUND_THREAD,
	    PR_UNJOINABLE_THREAD, 0);
    if (clientThread == NULL) {
	fprintf(stderr, "can't create thread\n");
	exit(1);
    }


    printf("Three client threads are created.  Each of them will\n");
    printf("send data to one of the three ports the server is listening on.\n");
    printf("The data they send is the port number.  Each of them send\n");
    printf("the data five times, so you should see ten lines below,\n");
    printf("interleaved in an arbitrary order.\n");

    /* 30 events total */
    i = 0;
    while (i < 30) {
		PRPollDesc *tmp;
		int nextIndex;
		int nEvents = 0;

		retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT);
		PR_ASSERT(retVal != 0);  /* no timeout */
		if (retVal == -1) {
			fprintf(stderr, "PR_Poll failed\n");
			exit(1);
		}

		nextIndex = 3;
		/* the three listening sockets */
		for (j = 0; j < 3; j++) {
			other_pds[j] = pds[j];
			PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0
				&& (pds[j].out_flags & PR_POLL_EXCEPT) == 0);
			if (pds[j].out_flags & PR_POLL_READ) {
				PRFileDesc *sock;

				nEvents++;
				if (j == 2) {
					PROsfd newsd;
					newsd = accept(PR_FileDesc2NativeHandle(pds[j].fd), NULL, 0);
					if (newsd == -1) {
						fprintf(stderr, "accept() failed\n");
						exit(1);
					}
					other_pds[nextIndex].fd  = PR_CreateSocketPollFd(newsd);
					PR_ASSERT(other_pds[nextIndex].fd);
					other_pds[nextIndex].in_flags = PR_POLL_READ;
				} else {
					sock = PR_Accept(pds[j].fd, NULL, PR_INTERVAL_NO_TIMEOUT);
					if (sock == NULL) {
						fprintf(stderr, "PR_Accept() failed\n");
						exit(1);
					}
					other_pds[nextIndex].fd = sock;
					other_pds[nextIndex].in_flags = PR_POLL_READ;
				}
				nextIndex++;
			} else if (pds[j].out_flags & PR_POLL_ERR) {
				fprintf(stderr, "PR_Poll() indicates that an fd has error\n");
				exit(1);
			} else if (pds[j].out_flags & PR_POLL_NVAL) {
				fprintf(stderr, "PR_Poll() indicates that fd %d is invalid\n",
					PR_FileDesc2NativeHandle(pds[j].fd));
				exit(1);
			}
		}

		for (j = 3; j < npds; j++) {
			PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0
				&& (pds[j].out_flags & PR_POLL_EXCEPT) == 0);
			if (pds[j].out_flags & PR_POLL_READ) {
				PRInt32 nBytes;

				nEvents++;
				/* XXX: This call is a hack and should be fixed */
				if (PR_GetDescType(pds[j].fd) == (PRDescType) 0) {
					nBytes = recv(PR_FileDesc2NativeHandle(pds[j].fd), buf,
										sizeof(buf), 0);
					if (nBytes == -1) {
						fprintf(stderr, "recv() failed\n");
						exit(1);
					}
					printf("Server read %d bytes from native fd %d\n",nBytes,
										PR_FileDesc2NativeHandle(pds[j].fd));
#ifdef WIN32
					closesocket((SOCKET)PR_FileDesc2NativeHandle(pds[j].fd));
#else
					close(PR_FileDesc2NativeHandle(pds[j].fd));
#endif
					PR_DestroySocketPollFd(pds[j].fd);
				} else {
					nBytes = PR_Read(pds[j].fd, buf, sizeof(buf));
					if (nBytes == -1) {
						fprintf(stderr, "PR_Read() failed\n");
						exit(1);
					}
					PR_Close(pds[j].fd);
				}
				/* Just to be safe */
				buf[BUF_SIZE - 1] = '\0';
				printf("The server received \"%s\" from a client\n", buf);
			} else if (pds[j].out_flags & PR_POLL_ERR) {
				fprintf(stderr, "PR_Poll() indicates that an fd has error\n");
				exit(1);
			} else if (pds[j].out_flags & PR_POLL_NVAL) {
				fprintf(stderr, "PR_Poll() indicates that an fd is invalid\n");
				exit(1);
			} else {
				other_pds[nextIndex] = pds[j];
				nextIndex++;
			}
		}

		PR_ASSERT(retVal == nEvents);
		/* swap */
		tmp = pds;
		pds = other_pds;
		other_pds = tmp;
		npds = nextIndex;
		i += nEvents;
    }
    PR_DestroySocketPollFd(socket_poll_fd);

    printf("All tests finished\n");
    PR_Cleanup();
    return 0;
}
예제 #18
0
static void NativeSelectTest(void)
{
    PRFileDesc *listenSocket;
    PRNetAddr serverAddr;

    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
        if (debug_mode) printf("\tServer error creating listen socket\n");
        return;
    }

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

    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
        if (debug_mode) printf("\tServer error binding to server address\n");
        PR_Close(listenSocket);
        return;
    }

    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
        if (debug_mode) printf("\tServer error listening to server socket\n");
        PR_Close(listenSocket);
        return;
    }
    if (debug_mode) printf("Listening on port %d\n", PORT);

    {
        PRIntn osfd;
        char buf[11];
        fd_set rdset;
        PRNetAddr rAddr;
        PRFileDesc *newSock;
        struct timeval timeout;
        PRInt32 bytesRead, rv, loops = 0;

        loops++;

        if (debug_mode) printf("Going into accept\n"); 

        newSock = PR_Accept(listenSocket, &rAddr, PR_INTERVAL_NO_TIMEOUT);

	if (newSock) {
            if (debug_mode) printf("Got connection!\n");
        } else {
	    if (debug_mode) printf("PR_Accept failed: error code %d\n", PR_GetError());
		else Test_Result (FAIL);
        }

        osfd = PR_FileDesc2NativeHandle(newSock);
        FD_ZERO(&rdset);
        FD_SET(osfd, &rdset);

        if (debug_mode) printf("Going into select \n");


        timeout.tv_sec = 2; timeout.tv_usec = 0;
        rv = select(osfd + 1, &rdset, NULL, NULL, &timeout);

        if (debug_mode) printf("return from select is %d\n", rv);

        if (FD_ISSET(osfd, &rdset)) {
            if (debug_mode)
                printf("I can't believe it- the socket is ready okay!\n");
        } else {
            if (debug_mode) printf("Damn; the select test failed...\n");
			else Test_Result (FAIL);
        }

        strcpy(buf, "XXXXXXXXXX");
        bytesRead = PR_Recv(newSock, buf, 10, 0, PR_INTERVAL_NO_TIMEOUT);
	buf[10] = '\0';

        if (debug_mode) printf("Recv completed with %d bytes, %s\n", bytesRead, buf);

        PR_Close(newSock);
    }

}  /* NativeSelectTest */
예제 #19
0
int main()
{
    union {
        PRUint16 s;
        PRUint32 l;
        PRUint64 ll;
        unsigned char bytes[8];
    } un;

    un.s = s_h;
    printf("%u %u\n",
        un.bytes[0], un.bytes[1]);
    un.s = PR_htons(un.s);
    printf("%u %u\n",
        un.bytes[0], un.bytes[1]);
    if (memcmp(un.bytes, bytes_n, 2)) {
        fprintf(stderr, "PR_htons failed\n");
        exit(1);
    }
    un.s = PR_ntohs(un.s);
    printf("%u %u\n",
        un.bytes[0], un.bytes[1]);
    if (un.s != s_h) {
        fprintf(stderr, "PR_ntohs failed\n");
        exit(1);
    }

    un.l = l_h;
    printf("%u %u %u %u\n",
        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]);
    un.l = PR_htonl(un.l);
    printf("%u %u %u %u\n",
        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]);
    if (memcmp(un.bytes, bytes_n, 4)) {
        fprintf(stderr, "PR_htonl failed\n");
        exit(1);
    }
    un.l = PR_ntohl(un.l);
    printf("%u %u %u %u\n",
        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]);
    if (un.l != l_h) {
        fprintf(stderr, "PR_ntohl failed\n");
        exit(1);
    }

    un.ll = ll_h;
    printf("%u %u %u %u %u %u %u %u\n",
        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3],
        un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]);
    un.ll = PR_htonll(un.ll);
    printf("%u %u %u %u %u %u %u %u\n",
        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3],
        un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]);
    if (memcmp(un.bytes, bytes_n, 8)) {
        fprintf(stderr, "PR_htonll failed\n");
        exit(1);
    }
    un.ll = PR_ntohll(un.ll);
    printf("%u %u %u %u %u %u %u %u\n",
        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3],
        un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]);
    if (LL_NE(un.ll, ll_h)) {
        fprintf(stderr, "PR_ntohll failed\n");
        exit(1);
    }

    printf("PASS\n");
    return 0;
}
void 
thread_main(void *_info)
{
    threadInfo *info = (threadInfo *)_info;
    PRNetAddr listenAddr;
    PRNetAddr clientAddr;
    PRFileDesc *listenSock = NULL;
    PRFileDesc *clientSock;
    PRStatus rv;
 
    if (debug_mode) printf("thread %d is alive\n", info->id);

    listenSock = PR_NewTCPSocket();
    if (!listenSock) {
        if (debug_mode) printf("unable to create listen socket\n");
        goto dead;
    }
  
    listenAddr.inet.family = AF_INET;
    listenAddr.inet.port = PR_htons(BASE_PORT + info->id);
    listenAddr.inet.ip = PR_htonl(INADDR_ANY);
    rv = PR_Bind(listenSock, &listenAddr);
    if (rv == PR_FAILURE) {
        if (debug_mode) printf("unable to bind\n");
        goto dead;
    }

    rv = PR_Listen(listenSock, 4);
    if (rv == PR_FAILURE) {
        if (debug_mode) printf("unable to listen\n");
        goto dead;
    }

    if (debug_mode) printf("thread %d going into accept for %d seconds\n", 
        info->id, info->accept_timeout + info->id);

    clientSock = PR_Accept(listenSock, &clientAddr, PR_SecondsToInterval(info->accept_timeout +info->id));

    if (clientSock == NULL) {
        if (PR_GetError() == PR_IO_TIMEOUT_ERROR) 
            if (debug_mode) {
				printf("PR_Accept() timeout worked!\n");
                printf("TEST FAILED! PR_Accept() returned error %d\n",
								   PR_GetError());
			}
			else failed_already=1;
    } else {
        if (debug_mode) printf ("TEST FAILED! PR_Accept() succeeded?\n");
		else failed_already=1;
	PR_Close(clientSock);
    }

dead:
    if (listenSock) {
	PR_Close(listenSock);
    }
    PR_Lock(info->dead_lock);
    (*info->alive)--;
    PR_NotifyCondVar(info->dead_cv);
    PR_Unlock(info->dead_lock);

    if (debug_mode) printf("thread %d is dead\n", info->id);
}
예제 #21
0
static void 
RunTest(PRInt32 acceptType, PRInt32 clientAction)
{

    /* First bind to the socket */
    listenSock = PR_NewTCPSocket();
    if (!listenSock) {
        if (!debug_mode)
            failed_already=1;
        else    
            printf("unable to create listen socket\n");
        return;
    }
    listenAddr.inet.family = AF_INET;
    listenAddr.inet.port = PR_htons(BASE_PORT);
    listenAddr.inet.ip = PR_htonl(INADDR_ANY);
    rv = PR_Bind(listenSock, &listenAddr);
    if (rv == PR_FAILURE) {
        if (!debug_mode)
            failed_already=1;
        else    
            printf("unable to bind\n");
        return;
    }

    rv = PR_Listen(listenSock, 100);
    if (rv == PR_FAILURE) {
        if (!debug_mode)
            failed_already=1;
        else    
            printf("unable to listen\n");
        return;
    }

    clientCommand = clientAction;
    clientThread = PR_CreateThread(PR_USER_THREAD, ClientThread,
        (void *)&clientCommand, PR_PRIORITY_NORMAL, thread_scope,
        PR_JOINABLE_THREAD, 0);
    if (!clientThread) {
        if (!debug_mode)
            failed_already=1;
        else    
            printf("error creating client thread\n");
        return;
    }

    iterations = count;
    for (;iterations--;) {
        switch (acceptType) {
        case ACCEPT_NORMAL:
            clientSock = PR_Accept(listenSock, &clientAddr,
                timeoutTime);
            switch(clientAction) {
            case CLIENT_TIMEOUT_ACCEPT:
                TEST_ASSERT(clientSock == 0);
                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
                break;
            case CLIENT_NORMAL:
                TEST_ASSERT(clientSock);
                bytesRead = PR_Recv(clientSock,
                    buf,  CLIENT_DATA,  0,  timeoutTime);
                TEST_ASSERT(bytesRead == CLIENT_DATA);
                break;
            case CLIENT_TIMEOUT_SEND:
                TEST_ASSERT(clientSock);
                bytesRead = PR_Recv(clientSock,
                    buf,  CLIENT_DATA,  0,  timeoutTime);
                TEST_ASSERT(bytesRead == -1);
                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
                break;
            }
            break;
        case ACCEPT_READ:
            status = PR_AcceptRead(listenSock, &clientSock,
                &raddr, buf, CLIENT_DATA, timeoutTime);
            switch(clientAction) {
            case CLIENT_TIMEOUT_ACCEPT:
                /* Invalid test case */
                TEST_ASSERT(0);
                break;
            case CLIENT_NORMAL:
                TEST_ASSERT(clientSock);
                TEST_ASSERT(status == CLIENT_DATA);
                break;
            case CLIENT_TIMEOUT_SEND:
                TEST_ASSERT(status == -1);
                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
                break;
            }
            break;
#ifdef WINNT
        case ACCEPT_FAST:
            clientSock = PR_NTFast_Accept(listenSock,
                &clientAddr, timeoutTime);
            switch(clientAction) {
            case CLIENT_TIMEOUT_ACCEPT:
                TEST_ASSERT(clientSock == 0);
                if (debug_mode)
                    printf("PR_GetError is %ld\n",
                        PR_GetError());
                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
                break;
            case CLIENT_NORMAL:
                TEST_ASSERT(clientSock);
                bytesRead = PR_Recv(clientSock,
                    buf,  CLIENT_DATA,  0,  timeoutTime);
                TEST_ASSERT(bytesRead == CLIENT_DATA);
                break;
            case CLIENT_TIMEOUT_SEND:
                TEST_ASSERT(clientSock);
                bytesRead = PR_Recv(clientSock,
                    buf,  CLIENT_DATA,  0,  timeoutTime);
                TEST_ASSERT(bytesRead == -1);
                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
                break;
            }
            break;
            break;
        case ACCEPT_READ_FAST:
            status = PR_NTFast_AcceptRead(listenSock,
                &clientSock, &raddr, buf, 4096, timeoutTime);
            switch(clientAction) {
            case CLIENT_TIMEOUT_ACCEPT:
                /* Invalid test case */
                TEST_ASSERT(0);
                break;
            case CLIENT_NORMAL:
                TEST_ASSERT(clientSock);
                TEST_ASSERT(status == CLIENT_DATA);
                break;
            case CLIENT_TIMEOUT_SEND:
                TEST_ASSERT(clientSock);
                TEST_ASSERT(status == -1);
                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
                break;
            }
            break;
        case ACCEPT_READ_FAST_CB:
            status = PR_NTFast_AcceptRead_WithTimeoutCallback(
                listenSock, &clientSock, &raddr, buf, 4096,
                timeoutTime, timeout_callback, (void *)CALLBACK_MAGIC);
            switch(clientAction) {
            case CLIENT_TIMEOUT_ACCEPT:
                /* Invalid test case */
                TEST_ASSERT(0);
                break;
            case CLIENT_NORMAL:
                TEST_ASSERT(clientSock);
                TEST_ASSERT(status == CLIENT_DATA);
                break;
            case CLIENT_TIMEOUT_SEND:
                if (debug_mode)
                    printf("clientSock = 0x%8.8lx\n",
                        clientSock);
                TEST_ASSERT(clientSock);
                TEST_ASSERT(status == -1);
                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
                break;
            }
            break;
#endif
        }
        if (clientSock != NULL) {
            PR_Close(clientSock);
            clientSock = NULL;
        }
    }
    PR_Close(listenSock);

    PR_JoinThread(clientThread);
}
예제 #22
0
/*
 * Socket_Misc_Test    - test miscellaneous functions 
 *    
 */
static PRInt32
Socket_Misc_Test(void)
{
    PRIntn i, rv = 0, bytes, count, len;
    PRThread *t;
    PRThreadScope scope;
    PRSemaphore *server_sem;
    Server_Param *sparamp;
    Client_Param *cparamp;
    PRMonitor *mon2;
    PRInt32    datalen;

    /*
 * We deliberately pick a buffer size that is not a nice multiple
 * of 1024.
 */
#define TRANSMITFILE_BUF_SIZE    (4 * 1024 - 11)

    typedef struct {
        char    data[TRANSMITFILE_BUF_SIZE];
    } file_buf;
    file_buf *buf = NULL;

    /*
     * create file(s) to be transmitted
     */
    if ((PR_MkDir(TEST_DIR, 0777)) < 0) {
        printf("prsocket_test failed to create dir %s\n",TEST_DIR);
        failed_already=1;
        return -1;
    }

    small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777);

    if (small_file_fd == NULL) {
        fprintf(stderr,"prsocket_test failed to create/open file %s\n",
            SMALL_FILE_NAME);
        failed_already=1;
        rv = -1;
        goto done;
    }
    buf = PR_NEW(file_buf);
    if (buf == NULL) {
        fprintf(stderr,"prsocket_test failed to allocate buffer\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    /*
     * fill in random data
     */
    for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) {
        buf->data[i] = i;
    }
    count = 0;
    do {
        len = (SMALL_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ?
            TRANSMITFILE_BUF_SIZE : (SMALL_FILE_SIZE - count);
        bytes = PR_Write(small_file_fd, buf->data, len);
        if (bytes <= 0) {
            fprintf(stderr,
                "prsocket_test failed to write to file %s\n",
                SMALL_FILE_NAME);
            failed_already=1;
            rv = -1;
            goto done;
        }
        count += bytes;
    } while (count < SMALL_FILE_SIZE);
#ifdef XP_UNIX
    /*
     * map the small file; used in checking for data corruption
     */
    small_file_addr = mmap(0, SMALL_FILE_SIZE, PROT_READ,
        MAP_PRIVATE, small_file_fd->secret->md.osfd, 0);
    if (small_file_addr == (void *) -1) {
        fprintf(stderr,"prsocket_test failed to mmap file %s\n",
            SMALL_FILE_NAME);
        failed_already=1;
        rv = -1;
        goto done;
    }
#endif
    /*
     * header for small file
     */
    small_file_header = PR_MALLOC(SMALL_FILE_HEADER_SIZE);
    if (small_file_header == NULL) {
        fprintf(stderr,"prsocket_test failed to malloc header file\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    memset(small_file_header, (int) PR_IntervalNow(),
        SMALL_FILE_HEADER_SIZE);
    /*
     * setup large file
     */
    large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777);

    if (large_file_fd == NULL) {
        fprintf(stderr,"prsocket_test failed to create/open file %s\n",
            LARGE_FILE_NAME);
        failed_already=1;
        rv = -1;
        goto done;
    }
    /*
     * fill in random data
     */
    for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) {
        buf->data[i] = i;
    }
    count = 0;
    do {
        len = (LARGE_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ?
            TRANSMITFILE_BUF_SIZE : (LARGE_FILE_SIZE - count);
        bytes = PR_Write(large_file_fd, buf->data, len);
        if (bytes <= 0) {
            fprintf(stderr,
                "prsocket_test failed to write to file %s: (%ld, %ld)\n",
                LARGE_FILE_NAME,
                PR_GetError(), PR_GetOSError());
            failed_already=1;
            rv = -1;
            goto done;
        }
        count += bytes;
    } while (count < LARGE_FILE_SIZE);
#ifdef XP_UNIX
    /*
     * map the large file; used in checking for data corruption
     */
    large_file_addr = mmap(0, LARGE_FILE_SIZE, PROT_READ,
        MAP_PRIVATE, large_file_fd->secret->md.osfd, 0);
    if (large_file_addr == (void *) -1) {
        fprintf(stderr,"prsocket_test failed to mmap file %s\n",
            LARGE_FILE_NAME);
        failed_already=1;
        rv = -1;
        goto done;
    }
#endif
    datalen = tcp_mesg_size;
    thread_count = 0;
    /*
     * start the server thread
     */
    sparamp = PR_NEW(Server_Param);
    if (sparamp == NULL) {
        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    server_sem = PR_NewSem(0);
    if (server_sem == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewSem failed\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    mon2 = PR_NewMonitor();
    if (mon2 == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    PR_EnterMonitor(mon2);

    sparamp->addr_sem = server_sem;
    sparamp->exit_mon = mon2;
    sparamp->exit_counter = &thread_count;
    sparamp->datalen = datalen;
    t = PR_CreateThread(PR_USER_THREAD,
        TransmitFile_Server, (void *)sparamp, 
        PR_PRIORITY_NORMAL,
        PR_LOCAL_THREAD,
        PR_UNJOINABLE_THREAD,
        0);
    if (t == NULL) {
        fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    DPRINTF(("Created TCP server = 0x%x\n", t));
    thread_count++;

    /*
     * wait till the server address is setup
     */
    PR_WaitSem(server_sem);

    /*
     * Now start a bunch of client threads
     */

    cparamp = PR_NEW(Client_Param);
    if (cparamp == NULL) {
        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    cparamp->server_addr = tcp_server_addr;
    cparamp->server_addr.inet.ip = PR_htonl(INADDR_LOOPBACK);
    cparamp->exit_mon = mon2;
    cparamp->exit_counter = &thread_count;
    cparamp->datalen = datalen;
    for (i = 0; i < num_transmitfile_clients; i++) {
        /*
         * Every other thread is a LOCAL/GLOBAL thread
         */
        if (i & 1)
            scope = PR_GLOBAL_THREAD;
        else
            scope = PR_LOCAL_THREAD;
        t = PR_CreateThread(PR_USER_THREAD,
            TransmitFile_Client, (void *) cparamp,
            PR_PRIORITY_NORMAL,
            scope,
            PR_UNJOINABLE_THREAD,
            0);
        if (t == NULL) {
            fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
            rv = -1;
            failed_already=1;
            goto done;
        }
        DPRINTF(("Created TransmitFile client = 0x%lx\n", t));
        thread_count++;
    }
    /* Wait for server and client threads to exit */
    while (thread_count) {
        PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
        DPRINTF(("Socket_Misc_Test - thread_count  = %d\n", thread_count));
    }
    PR_ExitMonitor(mon2);
done:
    if (buf) {
        PR_DELETE(buf);
    }
#ifdef XP_UNIX
    munmap(small_file_addr, SMALL_FILE_SIZE);
    munmap(large_file_addr, LARGE_FILE_SIZE);
#endif
    PR_Close(small_file_fd);
    PR_Close(large_file_fd);
    if ((PR_Delete(SMALL_FILE_NAME)) == PR_FAILURE) {
        fprintf(stderr,"prsocket_test: failed to unlink file %s\n",
            SMALL_FILE_NAME);
        failed_already=1;
    }
    if ((PR_Delete(LARGE_FILE_NAME)) == PR_FAILURE) {
        fprintf(stderr,"prsocket_test: failed to unlink file %s\n",
            LARGE_FILE_NAME);
        failed_already=1;
    }
    if ((PR_RmDir(TEST_DIR)) == PR_FAILURE) {
        fprintf(stderr,"prsocket_test failed to rmdir %s: (%ld, %ld)\n",
            TEST_DIR, PR_GetError(), PR_GetOSError());
        failed_already=1;
    }

    printf("%-29s%s","Socket_Misc_Test",":");
    printf("%2d Server %2d Clients\n",1, num_transmitfile_clients);
    printf("%30s Sizes of Transmitted Files  - %4d KB, %2d MB \n",":",
        SMALL_FILE_SIZE/1024, LARGE_FILE_SIZE/(1024 * 1024));


    return rv;
}
예제 #23
0
/*
 * TCP Server
 *    Server Thread
 *    Bind an address to a socket and listen for incoming connections
 *    Start a Serve_Client thread for each incoming connection.
 */
static void PR_CALLBACK
TCP_Server(void *arg)
{
    PRThread *t;
    Server_Param *sp = (Server_Param *) arg;
    Serve_Client_Param *scp;
    PRFileDesc *sockfd, *newsockfd;
    PRNetAddr netaddr;
    PRInt32 i;
    /*
     * Create a tcp socket
     */
    if ((sockfd = PR_NewTCPSocket()) == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n");
        goto exit;
    }
    memset(&netaddr, 0 , sizeof(netaddr));
    netaddr.inet.family = AF_INET;
    netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
    netaddr.inet.ip = PR_htonl(INADDR_ANY);
    /*
     * try a few times to bind server's address, if addresses are in
     * use
     */
    i = 0;
    while (PR_Bind(sockfd, &netaddr) < 0) {
        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
            netaddr.inet.port += 2;
            if (i++ < SERVER_MAX_BIND_COUNT)
                continue;
        }
        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
        perror("PR_Bind");
        failed_already=1;
        goto exit;
    }

    if (PR_Listen(sockfd, 32) < 0) {
        fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n");
        failed_already=1;
        goto exit;
    }

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

    DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
        netaddr.inet.ip, netaddr.inet.port));
    tcp_server_addr.inet.family = netaddr.inet.family;
    tcp_server_addr.inet.port = netaddr.inet.port;
    tcp_server_addr.inet.ip = netaddr.inet.ip;

    /*
     * Wake up parent thread because server address is bound and made
     * available in the global variable 'tcp_server_addr'
     */
    PR_PostSem(sp->addr_sem);

    for (i = 0; i < (num_tcp_clients * num_tcp_connections_per_client); i++) {

        if ((newsockfd = PR_Accept(sockfd, &netaddr,
            PR_INTERVAL_NO_TIMEOUT)) == NULL) {
            fprintf(stderr,"prsocket_test: ERROR - PR_Accept failed\n");
            goto exit;
        }
        scp = PR_NEW(Serve_Client_Param);
        if (scp == NULL) {
            fprintf(stderr,"prsocket_test: PR_NEW failed\n");
            goto exit;
        }

        /*
         * Start a Serve_Client thread for each incoming connection
         */
        scp->sockfd = newsockfd;
        scp->datalen = sp->datalen;

        t = PR_CreateThread(PR_USER_THREAD,
            Serve_Client, (void *)scp, 
            PR_PRIORITY_NORMAL,
            PR_LOCAL_THREAD,
            PR_UNJOINABLE_THREAD,
            0);
        if (t == NULL) {
            fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
            failed_already=1;
            goto exit;
        }
        DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", t));
    }

exit:
    if (sockfd) {
        PR_Close(sockfd);
    }

    /*
     * Decrement exit_counter and notify parent thread
     */

    PR_EnterMonitor(sp->exit_mon);
    --(*sp->exit_counter);
    PR_Notify(sp->exit_mon);
    PR_ExitMonitor(sp->exit_mon);
    DPRINTF(("TCP_Server [0x%lx] exiting\n", PR_GetCurrentThread()));
}
예제 #24
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);
}
예제 #25
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()));
}
예제 #26
0
static NSSLOWKEYPrivateKey *
lg_mkSecretKeyRep(const CK_ATTRIBUTE *templ,
                  CK_ULONG count, CK_KEY_TYPE key_type,
                  SECItem *pubkey, SDB *sdbpw)
{
    NSSLOWKEYPrivateKey *privKey = 0;
    PLArenaPool *arena = 0;
    CK_KEY_TYPE keyType;
    PRUint32 keyTypeStorage;
    SECItem keyTypeItem;
    CK_RV crv;
    SECStatus rv;
    static unsigned char derZero[1] = { 0 };

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }

    privKey = (NSSLOWKEYPrivateKey *)
        PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPrivateKey));
    if (privKey == NULL) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }

    privKey->arena = arena;

    /* Secret keys are represented in the database as "fake" RSA keys.
     * The RSA key is marked as a secret key representation by setting the
     * public exponent field to 0, which is an invalid RSA exponent.
     * The other fields are set as follows:
     *   modulus - CKA_ID value for the secret key
     *   private exponent - CKA_VALUE (the key itself)
     *   coefficient - CKA_KEY_TYPE, which indicates what encryption algorithm
     *      is used for the key.
     *   all others - set to integer 0
     */
    privKey->keyType = NSSLOWKEYRSAKey;

    /* The modulus is set to the key id of the symmetric key */
    privKey->u.rsa.modulus.data =
        (unsigned char *)PORT_ArenaAlloc(arena, pubkey->len);
    if (privKey->u.rsa.modulus.data == NULL) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }
    privKey->u.rsa.modulus.len = pubkey->len;
    PORT_Memcpy(privKey->u.rsa.modulus.data, pubkey->data, pubkey->len);

    /* The public exponent is set to 0 to indicate a special key */
    privKey->u.rsa.publicExponent.len = sizeof derZero;
    privKey->u.rsa.publicExponent.data = derZero;

    /* The private exponent is the actual key value */
    crv = lg_PrivAttr2SecItem(arena, CKA_VALUE, templ, count,
                              &privKey->u.rsa.privateExponent, sdbpw);
    if (crv != CKR_OK)
        goto loser;

    /* All other fields empty - needs testing */
    privKey->u.rsa.prime1.len = sizeof derZero;
    privKey->u.rsa.prime1.data = derZero;

    privKey->u.rsa.prime2.len = sizeof derZero;
    privKey->u.rsa.prime2.data = derZero;

    privKey->u.rsa.exponent1.len = sizeof derZero;
    privKey->u.rsa.exponent1.data = derZero;

    privKey->u.rsa.exponent2.len = sizeof derZero;
    privKey->u.rsa.exponent2.data = derZero;

    /* Coeficient set to KEY_TYPE */
    crv = lg_GetULongAttribute(CKA_KEY_TYPE, templ, count, &keyType);
    if (crv != CKR_OK)
        goto loser;
    /* on 64 bit platforms, we still want to store 32 bits of keyType (This is
     * safe since the PKCS #11 defines for all types are 32 bits or less). */
    keyTypeStorage = (PRUint32)keyType;
    keyTypeStorage = PR_htonl(keyTypeStorage);
    keyTypeItem.data = (unsigned char *)&keyTypeStorage;
    keyTypeItem.len = sizeof(keyTypeStorage);
    rv = SECITEM_CopyItem(arena, &privKey->u.rsa.coefficient, &keyTypeItem);
    if (rv != SECSuccess) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }

    /* Private key version field set normally for compatibility */
    rv = DER_SetUInteger(privKey->arena,
                         &privKey->u.rsa.version, NSSLOWKEY_VERSION);
    if (rv != SECSuccess) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }

loser:
    if (crv != CKR_OK) {
        PORT_FreeArena(arena, PR_FALSE);
        privKey = 0;
    }

    return privKey;
}
예제 #27
0
int main(int argc, char **argv)
#endif
{
    PRFileDesc *listenSock1, *listenSock2;
    PRUint16 listenPort1, listenPort2;
    PRNetAddr addr;
    PR_fd_set readFdSet;
    char buf[128];
    PRInt32 retVal;

	/* The command line argument: -d is used to determine if the test is being run
	in debug mode. The regress tool requires only one line output:PASS or FAIL.
	All of the printfs associated with this test has been handled with a if (debug_mode)
	test.
	Usage: test_name -d
	*/
	PLOptStatus os;
	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
		if (PL_OPT_BAD == os) continue;
        switch (opt->option)
        {
        case 'd':  /* debug mode */
			debug_mode = 1;
            break;
         default:
            break;
        }
    }
	PL_DestroyOptState(opt);

 /* main test */
	
    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
    PR_STDIO_INIT();

    if (debug_mode) {
		printf("This program tests PR_Select with sockets.  Timeout \n");
		printf("operations are tested.\n\n");
	}

    /* Create two listening sockets */
    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
	fprintf(stderr, "Can't create a new TCP socket\n");
	failed_already=1;
	goto exit_now;
    }
    addr.inet.family = PR_AF_INET;
    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
    addr.inet.port = PR_htons(0);
    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
	fprintf(stderr, "Can't bind socket\n");
	failed_already=1;
	goto exit_now;
    }
    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
	fprintf(stderr, "PR_GetSockName failed\n");
	failed_already=1;
	goto exit_now;
    }
    listenPort1 = PR_ntohs(addr.inet.port);
    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
	fprintf(stderr, "Can't listen on a socket\n");
	failed_already=1;
	goto exit_now;
    }

    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
	fprintf(stderr, "Can't create a new TCP socket\n");
	failed_already=1;
	goto exit_now;
    }
    addr.inet.family = PR_AF_INET;
    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
    addr.inet.port = PR_htons(0);
    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
	fprintf(stderr, "Can't bind socket\n");
	failed_already=1;
	goto exit_now;
    }
    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
	fprintf(stderr, "PR_GetSockName failed\n");
	failed_already=1;
	goto exit_now;
    }
    listenPort2 = PR_ntohs(addr.inet.port);
    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
	fprintf(stderr, "Can't listen on a socket\n");
	failed_already=1;
	goto exit_now;
    }
    PR_snprintf(buf, sizeof(buf),
	    "The server thread is listening on ports %hu and %hu\n\n",
	    listenPort1, listenPort2);
    if (debug_mode) printf("%s", buf);

    /* Set up the fd set */
    PR_FD_ZERO(&readFdSet);
    PR_FD_SET(listenSock1, &readFdSet);
    PR_FD_SET(listenSock2, &readFdSet);

    /* Testing timeout */
    if (debug_mode) printf("PR_Select should time out in 5 seconds\n");
    retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
	    PR_SecondsToInterval(5));
    if (retVal != 0) {
	PR_snprintf(buf, sizeof(buf),
		"PR_Select should time out and return 0, but it returns %ld\n",
		retVal);
	fprintf(stderr, "%s", buf);
	if (retVal == -1) {
	    fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(),
		    PR_GetOSError());
			failed_already=1;
	}
	goto exit_now;
    }
    if (debug_mode) printf("PR_Select timed out.  Test passed.\n\n");

    PR_Cleanup();

exit_now:
	if(failed_already)	
		return 1;
	else
		return 0;
}
예제 #28
0
int main(int argc, char **argv)
{
    PRFileDesc *listenSock1 = NULL, *listenSock2 = NULL;
    PRUint16 listenPort1, listenPort2;
    PRNetAddr addr;
    char buf[128];
    PRPollDesc pds0[10], pds1[10], *pds, *other_pds;
    PRIntn npds;
    PRInt32 retVal;

	/* The command line argument: -d is used to determine if the test is being run
	in debug mode. The regress tool requires only one line output:PASS or FAIL.
	All of the printfs associated with this test has been handled with a if (debug_mode)
	test.
	Usage: test_name -d
	*/
	PLOptStatus os;
	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
		if (PL_OPT_BAD == os) continue;
        switch (opt->option)
        {
        case 'd':  /* debug mode */
			debug_mode = 1;
            break;
         default:
            break;
        }
    }
	PL_DestroyOptState(opt);

 /* main test */
	
    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
    PR_STDIO_INIT();

    if (debug_mode) {
		printf("This program tests PR_Poll with sockets.\n");
		printf("Timeout is tested.\n\n");
	}

    /* Create two listening sockets */
    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
	fprintf(stderr, "Can't create a new TCP socket\n");
	if (!debug_mode)  failed_already=1;
	goto exit_now;
    }
    memset(&addr, 0, sizeof(addr));
    addr.inet.family = PR_AF_INET;
    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
    addr.inet.port = PR_htons(0);
    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
	fprintf(stderr, "Can't bind socket\n");
	if (!debug_mode)  failed_already=1;
	goto exit_now;
    }
    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
	fprintf(stderr, "PR_GetSockName failed\n");
	if (!debug_mode)  failed_already=1;
	goto exit_now;
    }
    listenPort1 = PR_ntohs(addr.inet.port);
    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
	fprintf(stderr, "Can't listen on a socket\n");
	if (!debug_mode)  failed_already=1;
	goto exit_now;
    }

    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
	fprintf(stderr, "Can't create a new TCP socket\n");
	if (!debug_mode)  failed_already=1;	
	goto exit_now;
    }
    addr.inet.family = PR_AF_INET;
    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
    addr.inet.port = PR_htons(0);
    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
	fprintf(stderr, "Can't bind socket\n");
	if (!debug_mode)  failed_already=1;	
	goto exit_now;
    }
    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
	fprintf(stderr, "PR_GetSockName failed\n");
	if (!debug_mode)  failed_already=1;	
	goto exit_now;
    }
    listenPort2 = PR_ntohs(addr.inet.port);
    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
	fprintf(stderr, "Can't listen on a socket\n");
	if (!debug_mode)  failed_already=1;	
	goto exit_now;
    }
    PR_snprintf(buf, sizeof(buf),
	    "The server thread is listening on ports %hu and %hu\n\n",
	    listenPort1, listenPort2);
    if (debug_mode) printf("%s", buf);

    /* Set up the poll descriptor array */
    pds = pds0;
    other_pds = pds1;
    memset(pds, 0, sizeof(pds));
    pds[0].fd = listenSock1;
    pds[0].in_flags = PR_POLL_READ;
    pds[1].fd = listenSock2;
    pds[1].in_flags = PR_POLL_READ;
    npds = 2;

    /* Testing timeout */
    if (debug_mode) printf("PR_Poll should time out in 5 seconds\n");
    retVal = PR_Poll(pds, npds, PR_SecondsToInterval(5));
    if (retVal != 0) {
	PR_snprintf(buf, sizeof(buf),
		"PR_Poll should time out and return 0, but it returns %ld\n",
		retVal);
	fprintf(stderr, "%s", buf);
	if (!debug_mode)  failed_already=1;	
	goto exit_now;
    }
    if (debug_mode) printf("PR_Poll timed out.  Test passed.\n\n");

exit_now:

    if (listenSock1) {
        PR_Close(listenSock1);
    }
    if (listenSock2) {
        PR_Close(listenSock2);
    }

    PR_Cleanup();

	if(failed_already)	
		return 1;
	else
		return 0;

}
예제 #29
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);
}
static void PollThread(void *arg)
{
    PRIntervalTime timeout = (PRIntervalTime) arg;
    PRIntervalTime elapsed;
#if defined(XP_UNIX) || defined(WIN32)
    PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout);
    PRInt32 elapsed_msecs;
#endif
#if defined(XP_UNIX)
    struct timeval end_time_tv;
#endif
#if defined(WIN32) && !defined(WINCE)
    struct _timeb end_time_tb;
#endif
    PRFileDesc *sock;
    PRNetAddr addr;
    PRPollDesc pd;
    PRIntn rv;

    sock = PR_NewTCPSocket();
    if (sock == NULL) {
        fprintf(stderr, "PR_NewTCPSocket failed\n");
        exit(1);
    }
    memset(&addr, 0, sizeof(addr));
    addr.inet.family = PR_AF_INET;
    addr.inet.port = 0;
    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
    if (PR_Bind(sock, &addr) == PR_FAILURE) {
        fprintf(stderr, "PR_Bind failed\n");
        exit(1);
    }
    if (PR_Listen(sock, 5) == PR_FAILURE) {
        fprintf(stderr, "PR_Listen failed\n");
        exit(1);
    }
    pd.fd = sock;
    pd.in_flags = PR_POLL_READ;
    rv = PR_Poll(&pd, 1, timeout);
    if (rv != 0) {
        fprintf(stderr, "PR_Poll did not time out\n");
        exit(1);
    }
    elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time);
    if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) {
        fprintf(stderr, "timeout wrong\n");
        exit(1);
    }
#if defined(XP_UNIX)
    gettimeofday(&end_time_tv, NULL);
    elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec)
            + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000;
#endif
#if defined(WIN32)
#if defined(WINCE)
    elapsed_msecs = GetTickCount() - start_time_tick;
#else
    _ftime(&end_time_tb);
    elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time)
            + (end_time_tb.millitm - start_time_tb.millitm);
#endif
#endif
#if defined(XP_UNIX) || defined(WIN32)
    if (elapsed_msecs + tolerance_msecs < timeout_msecs
            || elapsed_msecs > timeout_msecs + tolerance_msecs) {
        fprintf(stderr, "timeout wrong\n");
        exit(1);
    }
#endif
    if (PR_Close(sock) == PR_FAILURE) {
        fprintf(stderr, "PR_Close failed\n");
        exit(1);
    }
    if (debug_mode) {
        fprintf(stderr, "Poll thread (scope %d) done\n",
                PR_GetThreadScope(PR_GetCurrentThread()));
    }
}