Ejemplo n.º 1
0
NS_IMETHODIMP
HttpBaseChannel::GetLocalPort(int32_t* port)
{
  NS_ENSURE_ARG_POINTER(port);

  if (mSelfAddr.raw.family == PR_AF_INET) {
    *port = (int32_t)PR_ntohs(mSelfAddr.inet.port);
  }
  else if (mSelfAddr.raw.family == PR_AF_INET6) {
    *port = (int32_t)PR_ntohs(mSelfAddr.ipv6.port);
  }
  else
    return NS_ERROR_NOT_AVAILABLE;

  return NS_OK;
}
// Used to return connection info to Dashboard.cpp
void
nsSocketTransportService::AnalyzeConnection(nsTArray<SocketInfo> *data,
        struct SocketContext *context, bool aActive)
{
    if (context->mHandler->mIsPrivate)
        return;
    PRFileDesc *aFD = context->mFD;

    PRFileDesc *idLayer = PR_GetIdentitiesLayer(aFD, PR_NSPR_IO_LAYER);

    NS_ENSURE_TRUE_VOID(idLayer);

    bool tcp = PR_GetDescType(idLayer) == PR_DESC_SOCKET_TCP;

    PRNetAddr peer_addr;
    PR_GetPeerName(aFD, &peer_addr);

    char host[64] = {0};
    PR_NetAddrToString(&peer_addr, host, sizeof(host));

    uint16_t port;
    if (peer_addr.raw.family == PR_AF_INET)
        port = peer_addr.inet.port;
    else
        port = peer_addr.ipv6.port;
    port = PR_ntohs(port);
    uint64_t sent = context->mHandler->ByteCountSent();
    uint64_t received = context->mHandler->ByteCountReceived();
    SocketInfo info = { nsCString(host), sent, received, port, aActive, tcp };

    data->AppendElement(info);
}
int main(int argc, char **argv)
{
    PRFileDesc *listenSock;
    PRThread *clientThread;
    PRThread *serverThread;
    PRNetAddr addr;
    PRThreadScope scope = PR_GLOBAL_THREAD;

    listenSock = PR_NewTCPSocket();
    if (NULL == listenSock) {
        fprintf(stderr, "PR_NewTCPSocket failed\n");
        exit(1);
    }
    if (PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr) == PR_FAILURE) {
        fprintf(stderr, "PR_InitializeNetAddr failed\n");
        exit(1);
    }
    if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
        fprintf(stderr, "PR_Bind failed\n");
        exit(1);
    }
    /* Find out what port number we are bound to. */
    if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
        fprintf(stderr, "PR_GetSockName failed\n");
        exit(1);
    }
    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
        fprintf(stderr, "PR_Listen failed\n");
        exit(1);
    }

    clientThread = PR_CreateThread(PR_USER_THREAD,
            ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)),
            PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0);
    if (NULL == clientThread) {
        fprintf(stderr, "PR_CreateThread failed\n");
        exit(1);
    }
    serverThread = PR_CreateThread(PR_USER_THREAD,
            ServerThread, listenSock,
            PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0);
    if (NULL == serverThread) {
        fprintf(stderr, "PR_CreateThread failed\n");
        exit(1);
    }
    if (PR_JoinThread(clientThread) == PR_FAILURE) {
        fprintf(stderr, "PR_JoinThread failed\n");
        exit(1);
    }
    if (PR_JoinThread(serverThread) == PR_FAILURE) {
        fprintf(stderr, "PR_JoinThread failed\n");
        exit(1);
    }
    if (PR_Close(listenSock) == PR_FAILURE) {
        fprintf(stderr, "PR_Close failed\n");
        exit(1);
    }
    printf("PASS\n");
    return 0;
}
NS_IMETHODIMP
HttpBaseChannel::GetRemotePort(PRInt32* port)
{
  NS_ENSURE_ARG_POINTER(port);

  if (mPeerAddr.raw.family == PR_AF_INET) {
    *port = (PRInt32)PR_ntohs(mPeerAddr.inet.port);
  }
  else if (mPeerAddr.raw.family == PR_AF_INET6) {
    *port = (PRInt32)PR_ntohs(mPeerAddr.ipv6.port);
  }
  else
    return NS_ERROR_NOT_AVAILABLE;

  return NS_OK;
}
Ejemplo n.º 5
0
PRStatus
nsSOCKSSocketInfo::ConnectToProxy(PRFileDesc *fd)
{
    PRStatus status;
    nsresult rv;

    NS_ABORT_IF_FALSE(mState == SOCKS_DNS_COMPLETE,
                      "Must have DNS to make connection!");

    if (NS_FAILED(mLookupStatus)) {
        PR_SetError(PR_BAD_ADDRESS_ERROR, 0);
        return PR_FAILURE;
    }

    // Try socks5 if the destination addrress is IPv6
    if (mVersion == 4 &&
        PR_NetAddrFamily(&mDestinationAddr) == PR_AF_INET6) {
        mVersion = 5;
    }

    int32_t addresses = 0;
    do {
        if (addresses++)
            mDnsRec->ReportUnusable(mProxyPort);
        
        rv = mDnsRec->GetNextAddr(mProxyPort, &mInternalProxyAddr);
        // No more addresses to try? If so, we'll need to bail
        if (NS_FAILED(rv)) {
            LOGERROR(("socks: unable to connect to SOCKS proxy, %s",
                     mProxyHost.get()));
            return PR_FAILURE;
        }

#if defined(PR_LOGGING)
        char buf[64];
        PR_NetAddrToString(&mInternalProxyAddr, buf, sizeof(buf));
        LOGDEBUG(("socks: trying proxy server, %s:%hu",
                 buf, PR_ntohs(PR_NetAddrInetPort(&mInternalProxyAddr))));
#endif
        PRNetAddr proxy = mInternalProxyAddr;
        FixupAddressFamily(fd, &proxy);
        status = fd->lower->methods->connect(fd->lower, &proxy, mTimeout);
        if (status != PR_SUCCESS) {
            PRErrorCode c = PR_GetError();
            // If EINPROGRESS, return now and check back later after polling
            if (c == PR_WOULD_BLOCK_ERROR || c == PR_IN_PROGRESS_ERROR) {
                mState = SOCKS_CONNECTING_TO_PROXY;
                return status;
            }
        }
    } while (status != PR_SUCCESS);

    // Connected now, start SOCKS
    if (mVersion == 4)
        return WriteV4ConnectRequest();
    return WriteV5AuthRequest();
}
Ejemplo n.º 6
0
static PRStatus PrintAddress(const PRNetAddr* address)
{
    char buffer[ADDR_BUFFER];
    PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer));
    if (PR_SUCCESS == rv)
        PR_fprintf(err, "%s:%u\n", buffer, PR_ntohs(address->inet.port));
    else PL_FPrintError(err, "PR_NetAddrToString");
    return rv;
}  /* PrintAddress */
Ejemplo n.º 7
0
std::string
addrStr(PRNetAddr addr)
{
  std::stringstream ss;
  char s[32];
  PR_NetAddrToString(&addr, s, 32);
  ss << s;
  if (addr.inet.port)
    ss << ":" << PR_ntohs(addr.inet.port);
  return ss.str();
}
Ejemplo n.º 8
0
NS_IMETHODIMP
nsServerSocket::GetPort(PRInt32 *aResult)
{
  // no need to enter the lock here
  PRUint16 port;
  if (mAddr.raw.family == PR_AF_INET)
    port = mAddr.inet.port;
  else
    port = mAddr.ipv6.port;
  *aResult = (PRInt32) PR_ntohs(port);
  return NS_OK;
}
int main(int argc, char **argv)
{
    PRFileDesc *listenSock;
    PRNetAddr addr;
    PRUint16 port;

    listenSock = PR_OpenTCPSocket(PR_AF_INET6);
    if (NULL == listenSock) {
        fprintf(stderr, "PR_OpenTCPSocket failed\n");
        exit(1);
    }
    memset(&addr, 0, sizeof(addr));
    if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) {
        fprintf(stderr, "PR_SetNetAddr failed\n");
        exit(1);
    }
    if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
        fprintf(stderr, "PR_Bind failed\n");
        exit(1);
    }
    if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
        fprintf(stderr, "PR_GetSockName failed\n");
        exit(1);
    }
    port = PR_ntohs(addr.ipv6.port);
    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
        fprintf(stderr, "PR_Listen failed\n");
        exit(1);
    }

    fprintf(stderr, "Running the test with local threads\n");
    RunTest(PR_LOCAL_THREAD, listenSock, port);
    fprintf(stderr, "Running the test with global threads\n");
    RunTest(PR_GLOBAL_THREAD, listenSock, port);

    if (PR_Close(listenSock) == PR_FAILURE) {
        fprintf(stderr, "PR_Close failed\n");
        exit(1);
    }
    printf("PASS\n");
    return 0;
}
Ejemplo n.º 10
0
/** Compares the common name specified in the subject DN for a certificate
  * with a specified hostname.
  */
SECStatus
CERT_VerifyCertName(const CERTCertificate *cert, const char *hostname)
{
    LOG_DEBUG(">> CERT_VerifyCertName: %s", hostname);
    static SECStatus (*VerifyCertName)(CERTCertificate *cert,
                                       const char *hostname) = NULL;
    if (!VerifyCertName)
        VerifyCertName = getfunc("CERT_VerifyCertName", LIBNSS3);
    if (!VerifyCertName)
        return SECFailure;

    SECStatus ret = VerifyCertName(cert, hostname);
    LOG_DEBUG(">>> result = %d", ret);

    PATROL_init();
    if (!cfg.loaded)
        PATROL_get_config(&cfg);

    PRNetAddr addr;
    if (PR_SUCCESS != PR_GetPeerName(nss_fd, &addr))
        return ret;

    PatrolData *chain = NULL;
    size_t chain_len
        = PATROL_NSS_convert_chain(CERT_GetCertChainFromCert(cert, PR_Now(),
                                                             certUsageSSLCA),
                                   &chain);

    PatrolRC pret = PATROL_check(&cfg, chain, chain_len, PATROL_CERT_X509,
                                 ret == SECSuccess ? PATROL_OK : PATROL_ERROR,
                                 hostname, 0, "tcp", // FIXME
                                 PR_ntohs((addr.raw.family == PR_AF_INET6)
                                          ? addr.ipv6.port : addr.inet.port));
    LOG_DEBUG(">>> patrol result = %d", pret);

    free(chain);
    PATROL_deinit();

    return pret == PATROL_OK ? SECSuccess : SECFailure;
}
Ejemplo n.º 11
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;

}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
int write_stats_dump(PRFileDesc *fd, StatsHeaderNode *hdr)
{
    int i = 0;
    StatsManager::lockStatsData();
    const StatsHeader *hdrStats = &hdr->hdrStats;

    // Version
    PR_fprintf(fd, "\n%s\n", hdrStats->versionServer);

    // Uptime
    char buffer[25];
    PRExplodedTime tm;
    PR_ExplodeTime(hdrStats->timeStarted, PR_LocalTimeParameters, &tm);
    PR_FormatTimeUSEnglish(buffer, sizeof(buffer), "%c", &tm);
    PR_fprintf(fd, "\nServer started %s\n", buffer);
    {
        StatsProcessNode *process = hdr->process;
        while (process) {
            const StatsProcessSlot *procStats = &process->procStats;
            PR_ExplodeTime(procStats->timeStarted, PR_LocalTimeParameters, &tm);
            PR_FormatTimeUSEnglish(buffer, sizeof(buffer), "%c", &tm);
            PR_fprintf(fd, "Process %d started %s\n", procStats->pid, buffer);
            process = process->next;
        }
    }

    // ConnectionQueue
    {
        StatsConnectionQueueSlot connqueues;
        memset(&connqueues, 0, sizeof(connqueues));

        // Accumulate connection queue buckets for every process
        StatsProcessNode *process = hdr->process;
        while (process) {
            StatsConnectionQueueNode *connQueueNode = process->connQueue;
            while (connQueueNode) {
                const StatsConnectionQueueSlot *connqueue = &connQueueNode->connQueueStats;
                connqueues.countQueued += connqueue->countQueued;
                connqueues.peakQueued += connqueue->peakQueued;
                connqueues.maxQueued += connqueue->maxQueued;
                connqueues.countOverflows += connqueue->countOverflows;
                connqueues.countTotalQueued += connqueue->countTotalQueued;
                connqueues.ticksTotalQueued += connqueue->ticksTotalQueued;
                connqueues.countTotalConnections += connqueue->countTotalConnections;
                connqueues.countQueued1MinuteAverage += connqueue->countQueued1MinuteAverage;
                connqueues.countQueued5MinuteAverage += connqueue->countQueued5MinuteAverage;
                connqueues.countQueued15MinuteAverage += connqueue->countQueued15MinuteAverage;
                connQueueNode = connQueueNode->next;
            }
            process = process->next;
        }

        PRFloat64 count = (PRInt64)connqueues.countTotalQueued;
        PRFloat64 ticks = (PRInt64)connqueues.ticksTotalQueued;
        if (count < 1.0)
            count = 1.0;

        PR_fprintf(fd,
                   "\nConnectionQueue:\n"
                   "-----------------------------------------\n"
                   "Current/Peak/Limit Queue Length            %d/%d/%d\n"
                   "Total Connections Queued                   %llu\n"
                   "Average Queue Length (1, 5, 15 minutes)    %4.2f, %4.2f, %4.2f\n"
                   "Average Queueing Delay                     %.2f milliseconds\n",
                   connqueues.countQueued, connqueues.peakQueued, connqueues.maxQueued,
                   connqueues.countTotalQueued,
                   connqueues.countQueued1MinuteAverage,
                   connqueues.countQueued5MinuteAverage,
                   connqueues.countQueued15MinuteAverage,
                   ticks / count / hdrStats->ticksPerSecond * 1000.0);
    }

    // Listen sockets
    {
        StatsProcessNode *process = hdr->process;
        StatsListenNode *lsNode = (process) ? process->ls : 0;
        while (lsNode) {
            StatsListenSlot *ls = &lsNode->lsStats;
            PRNetAddr addr;
            memcpy(&addr, &ls->address, sizeof(ls->address));
            char szAddress[512];
            memset(szAddress, 0, sizeof(szAddress));
            net_addr_to_string(&addr, szAddress, sizeof(szAddress)-1);
            PR_fprintf(fd, 
                       "\nListenSocket %s:\n"
                       "------------------------\n"
                       "Address                   %s://%s:%hu\n"
                       "Acceptor Threads          %d\n"
                       "Default Virtual Server    %s\n",
                       ls->id,
                       ls->flagSecure ? "https" : "http",
                       szAddress,
                       PR_ntohs(ls->address.inet.port),
                       ls->countAcceptors,
                       ls->defaultVsId
                    );
            lsNode = lsNode->next;
        }
    }

    // Keepalive Info
    {
        StatsKeepaliveBucket keepalives;
        memset(&keepalives, 0, sizeof(keepalives));

        // Accumulate keepalive buckets for every process
        StatsProcessNode *process = hdr->process;
        while (process) {
            StatsKeepaliveBucket *procKeepAlive = NULL;
            procKeepAlive = &process->procStats.keepAliveBucket;
            StatsManagerUtil::accumulateKeepAlive(&keepalives, procKeepAlive);
            process = process->next;
        }

        PR_fprintf(fd,
                   "\nKeepAliveInfo:\n"
                   "--------------------\n"
                   "KeepAliveCount        %lu/%lu\n"
                   "KeepAliveHits         %llu\n"
                   "KeepAliveFlushes      %llu\n"
                   "KeepAliveRefusals     %llu\n"
                   "KeepAliveTimeouts     %llu\n"
                   "KeepAliveTimeout      %lu seconds\n",
                   keepalives.countConnections,
                   keepalives.maxConnections,
                   keepalives.countHits,
                   keepalives.countFlushes,
                   keepalives.countRefusals,
                   keepalives.countTimeouts,
                   keepalives.secondsTimeout);
    }

    // Session Creation Info
    {
        PRUint32 countThreads = 0;
        PRUint32 countBusy = 0;
        PRUint32 countKeepAlive = 0;
        PRUint32 countKeepAliveThreads = 0;

        // Count the number of active threads
        StatsProcessNode *process = hdr->process;
        while (process) {
            StatsProcessSlot *procStats = &process->procStats;
            if (procStats->mode != STATS_PROCESS_EMPTY) {
                StatsThreadNode *thread = process->thread;
                while (thread) {
                    const StatsThreadSlot *threadStats = &thread->threadStats;
                    if (threadStats->mode != STATS_THREAD_EMPTY) {
                        countThreads++;
                        if (threadStats->mode == STATS_THREAD_KEEPALIVE) {
                            countKeepAlive++;
                        } else if (threadStats->mode != STATS_THREAD_IDLE) {
                            countBusy++;
                        }
                    }
                    thread = thread->next;
                }
            }
            // Get number of keepalive threads
            StatsKeepaliveBucket *procKeepAlive = NULL;
            procKeepAlive = &process->procStats.keepAliveBucket;
            countKeepAliveThreads += procKeepAlive->numThreads;

            process = process->next;
        }

        PR_fprintf(fd, 
                   "\nSessionCreationInfo:\n"
                   "------------------------\n"
                   "Active Sessions           %lu\n"
                   "Keep-Alive Sessions       %lu\n"
                   "Total Sessions Created    %lu/%lu\n",
                   countBusy,
                   countKeepAlive,
                   countThreads, (hdrStats->maxThreads * hdrStats->maxProcs + countKeepAliveThreads));
    }

    // Cache Info
    {
        StatsCacheBucket caches;
        memset(&caches, 0, sizeof(caches));

        // Accumulate cache buckets for every process
        StatsProcessNode *process = hdr->process;
        while (process) {
            StatsCacheBucket *procCache = NULL;
            procCache = &process->procStats.cacheBucket;
            StatsManagerUtil::accumulateCache(&caches, procCache);
            process = process->next;
        }

        if (caches.flagEnabled) {
            PR_fprintf(fd,
                       "\nCacheInfo:\n"
                       "-----------------------\n");

            PRInt64 fileLookups = caches.countHits + caches.countMisses;

            PR_fprintf(fd,
                       "File Cache Enabled       yes\n"
                       "File Cache Entries       %lu/%lu\n"
                       "File Cache Hit Ratio     %llu/%lld (%6.2f%%)\n"
                       "Maximum Age              %d\n",
                       caches.countEntries,
                       caches.maxEntries,
                       caches.countHits,
                       fileLookups,
                       percent(caches.countHits, fileLookups),
                       caches.secondsMaxAge);

            PRInt64 accelRequests = caches.countAcceleratableRequests + caches.countUnacceleratableRequests;
            PRInt64 accelResponses = caches.countAcceleratableResponses + caches.countUnacceleratableResponses;
            PRInt64 accelLookups = caches.countAcceleratorHits + caches.countAcceleratorMisses;

            PR_fprintf(fd,
                       "Accelerator Entries      %lu/%lu\n"
                       "Acceleratable Requests   %llu/%lld (%6.2f%%)\n"
                       "Acceleratable Responses  %llu/%lld (%6.2f%%)\n"
                       "Accelerator Hit Ratio    %llu/%lld (%6.2f%%)\n",
                       caches.countAcceleratorEntries,
                       caches.maxEntries,
                       caches.countAcceleratableRequests,
                       accelRequests,
                       percent(caches.countAcceleratableRequests, accelRequests),
                       caches.countAcceleratableResponses,
                       accelResponses,
                       percent(caches.countAcceleratableResponses, accelResponses),
                       caches.countAcceleratorHits,
                       accelLookups,
                       percent(caches.countAcceleratorHits, accelLookups));
        } else {
            PR_fprintf(fd, "\nServer cache disabled\n");
        }
    }

    // Thread pool info
    {
        StatsThreadPoolBucket pools[FUNC_MAXPOOLS];
        const char *names[FUNC_MAXPOOLS];
        memset(pools, 0, sizeof(pools));
        memset(names, 0, sizeof(names));

        // Accumulate thread pool buckets for every process
        StatsProcessNode *process = hdr->process;
        while (process) {
            StatsThreadPoolNode *pool = process->threadPool;
            for (i = 0; pool && (i < FUNC_MAXPOOLS); i++) {
                StatsManagerUtil::accumulateThreadPool(&pools[i],
                                                       &pool->threadPoolStats);
                names[i] = STATS_GET_NAME(&pool->threadPoolStats);
                pool = pool->next;
            }
            process = process->next;
        }

        int poolFlag = 0;

        for (i = 0; i < FUNC_MAXPOOLS; i++)
        {
            if (names[i]) {
                if (!poolFlag)
                {
                    poolFlag = 1;
                    PR_fprintf(fd,
                               "\nNative pools:\n"
                               "----------------------------\n");
                }

                PR_fprintf(fd,
                           "%s:\n"
                           "Idle/Peak/Limit               %lu/%lu/%lu\n"
                           "Work Queue Length/Peak/Limit  %lu/%lu/%lu\n",
                           names[i],
                           pools[i].countThreadsIdle, 
                           pools[i].countThreads, 
                           pools[i].maxThreads,
                           pools[i].countQueued, 
                           pools[i].peakQueued, 
                           pools[i].maxQueued);
            }
        }
    }

    // DNS info
    {
        StatsDnsBucket dnss;
        memset(&dnss, 0, sizeof(dnss));

        // Accumulate DNS buckets for every process
        StatsProcessNode *process = hdr->process;
        while (process) {
            StatsManagerUtil::accumulateDNS(&dnss,
                                            &process->procStats.dnsBucket);
            process = process->next;
        }

        if (dnss.flagCacheEnabled) {
            PRUint32 totalhits = dnss.countCacheMisses + dnss.countCacheHits;
            float hitratio;

            if (totalhits > 0.0)
                hitratio = (float)dnss.countCacheHits / (float)totalhits;
            else
                hitratio = 0.0;
            
            PR_fprintf(fd, 
                       "\nDNSCacheInfo:\n"
                       "------------------\n"
                       "enabled             yes\n"
                       "CacheEntries        %lu/%lu\n"
                       "HitRatio            %lu/%lu (%6.2f%%)\n",
                       dnss.countCacheEntries,
                       dnss.maxCacheEntries,
                       dnss.countCacheHits,
                       totalhits,
                       hitratio * 100.0);
        } else {
            PR_fprintf(fd, "\nServer DNS cache disabled\n");
        }

        if (dnss.flagAsyncEnabled) {
            PR_fprintf(fd, 
                       "\nAsyncDNS Data:\n"
                       "------------------\n"
                       "enabled             yes\n"
                       "NameLookups         %lu\n"
                       "AddrLookups         %lu\n"
                       "LookupsInProgress   %lu\n",
                       dnss.countAsyncNameLookups,
                       dnss.countAsyncAddrLookups,
                       dnss.countAsyncLookupsInProgress);
        } else {
            PR_fprintf(fd, "\nAsync DNS disabled\n");
        }
    }

    // NSAPI Profile Info
    if (hdrStats->maxProfileBuckets) {
        int i;

        StatsProfileBucket *profiles = new StatsProfileBucket[hdrStats->maxProfileBuckets];
        const char **names = new const char*[hdrStats->maxProfileBuckets];
        const char **descs = new const char*[hdrStats->maxProfileBuckets];
        memset(profiles, 0, sizeof(profiles[0]) * hdrStats->maxProfileBuckets);
        memset(names, 0, sizeof(names[0]) * hdrStats->maxProfileBuckets);
        memset(descs, 0, sizeof(descs[0]) * hdrStats->maxProfileBuckets);

        // Accumulate profiles for every thread
        StatsProcessNode *process = hdr->process;
        while (process) {
            StatsThreadNode *thread = process->thread;
            while (thread) {
                StatsProfileNode *profile = thread->profile;
                for (i = 0; i < hdrStats->maxProfileBuckets; i++) {
                    StatsManagerUtil::accumulateProfile(&profiles[i],
                                                        &profile->profileStats);
                    names[i] = STATS_GET_NAME(&profile->profileStats);
                    descs[i] = STATS_GET_DESCRIPTION(&profile->profileStats);
                    profile = profile->next;
                }
                thread = thread->next;
            }
            process = process->next;
        }

        PRInt64 tr = profiles[STATS_PROFILE_ALL].countRequests;
        PRInt64 tc = profiles[STATS_PROFILE_ALL].countCalls;
        float td = (float)(PRInt64)profiles[STATS_PROFILE_ALL].ticksDispatch;
        float tf = (float)(PRInt64)profiles[STATS_PROFILE_ALL].ticksFunction;
        td /= hdrStats->ticksPerSecond;
        tf /= hdrStats->ticksPerSecond;
        float tt = td + tf;

        PR_fprintf(fd, 
                   "\nPerformance Counters:\n"
                   "------------------------------------------------\n"
                   "                           Average         Total      Percent\n\n"
                   "Total number of requests:             %10llu\n"
                   "Request processing time:   %7.4f  %12.4f\n",
                   tr,
                   (tr > 0) ? (tt / (float)tr) : 0, tt);

        for (i = hdrStats->maxProfileBuckets-1; i >= STATS_PROFILE_DEFAULT; i--) {
            PRInt64 r = profiles[i].countRequests;
            PRInt64 c = profiles[i].countCalls;
            const char *name = names[i];

            // Don't display cache-bucket if it's empty.  This is a predefined
            // bucket that stored NSAPI accelerator cache statistics in
            // previous versions of the server.
            if (!c && i == STATS_PROFILE_CACHE && !strcmp(name, "cache-bucket")) {
                continue;
            }

            float d = (float)(PRInt64)profiles[i].ticksDispatch;
            float f = (float)(PRInt64)profiles[i].ticksFunction;
            d /= hdrStats->ticksPerSecond;
            f /= hdrStats->ticksPerSecond;
            float t = d + f;

            PR_fprintf(fd, 
                       "\n%s (%s)\n"
                       "Number of Requests:                 %12llu    (%6.2f%%)\n"
                       "Number of Invocations:              %12llu    (%6.2f%%)\n"
                       "Latency:                   %7.4f  %12.4f    (%6.2f%%)\n"
                       "Function Processing Time:  %7.4f  %12.4f    (%6.2f%%)\n"
                       "Total Response Time:       %7.4f  %12.4f    (%6.2f%%)\n",
                       name, SAFESTRING(descs[i]),
                       r, (tr > 0) ? (100.0 * r / (PRFloat64) tr) : 0,
                       c, (tc > 0) ? (100.0 * c / (PRFloat64) tc) : 0,
                       (r > 0)? (d / r): 0, d, (tt > 0)? (100 * d / tt): 0,
                       (r > 0)? (f / r): 0, f, (tt > 0)? (100 * f / tt): 0,
                       (r > 0)? (t / r): 0, t, (tt > 0)? (100 * t / tt): 0);
        }

        delete[] profiles;
        delete[] names;
        delete[] descs;

    } else {
        PR_fprintf(fd, "\nPerformance Statistics disabled\n");
    }

    // Session info
    {
        StatsProcessNode *process;
        int x;
        int y;

        // Count the number of rows in our session table
        int nr = 0;
        for (process = hdr->process; process; process = process->next) {
            StatsThreadNode *thread;
            for (thread = process->thread; thread; thread = thread->next)
                nr++;
        }

        SessionRow *rows = new SessionRow[nr];

        PRTime now = PR_Now();

        // Collect stats from each session
        y = 0;
        for (process = hdr->process; process; process = process->next) {
            StatsThreadNode *thread;
            for (thread = process->thread; thread; thread = thread->next) {
                thread->lock();

                PRUint32 mode = thread->threadStats.mode;
                if (mode != STATS_THREAD_EMPTY && mode != STATS_THREAD_IDLE &&
                    mode != STATS_THREAD_KEEPALIVE) {
                    rows[y].columns[SESSION_COLUMN_PROCESS].printf("%u", process->procStats.pid);
                    rows[y].columns[SESSION_COLUMN_STATUS] = StatsManager::getMode(&thread->threadStats);

                    char addr[NET_ADDR_STRING_SIZE];
                    net_addr_to_string(&thread->threadStats.addressClient, addr, sizeof(addr));
                    rows[y].columns[SESSION_COLUMN_CLIENT] = addr;

                    rows[y].timeRequestStarted = thread->threadStats.timeRequestStarted;
                    if (rows[y].timeRequestStarted != 0) {
                        PRTime microseconds = now - rows[y].timeRequestStarted;
                        int seconds = (microseconds + PR_USEC_PER_SEC/2) / PR_USEC_PER_SEC;
                        rows[y].columns[SESSION_COLUMN_AGE].printf("%d", seconds);
                    }

                    rows[y].columns[SESSION_COLUMN_VS] = thread->threadStats.vsId;
                    rows[y].columns[SESSION_COLUMN_METHOD] = thread->threadStats.requestBucket.method;
                    rows[y].columns[SESSION_COLUMN_URI] = thread->threadStats.requestBucket.uri;
                    rows[y].columns[SESSION_COLUMN_FUNCTION] = STATS_GET_FUNCTION_NAME(&thread->threadStats);

                    y++;
                }

                thread->unlock();
            }
        }

        // We'll only display stats for active sessions
        PR_ASSERT(y <= nr);
        nr = y;

        // Each column is at least as wide as its label
        int widths[SESSION_COLUMN_COUNT];
        for (x = 0; x < SESSION_COLUMN_COUNT; x++)
            widths[x] = session_column_labels[x].length();

        // Ensure each column is wide enough to fit its largest value
        for (y = 0; y < nr; y++) {
            for (x = 0; x < SESSION_COLUMN_COUNT; x++) {
                if (widths[x] < rows[y].columns[x].length())
                    widths[x] = rows[y].columns[x].length();
            }
        }

        // Leave at least 2 spaces between columns
        for (x = 0; x < SESSION_COLUMN_COUNT - 1; x++)
            widths[x] += 2;

        // Calculate total line width and individual column offsets
        int width = 0;
        int offsets[SESSION_COLUMN_COUNT];
        for (x = 0 ; x < SESSION_COLUMN_COUNT; x++) {
            offsets[x] = width;
            width += widths[x];
        }

        char *line = (char *) malloc(width + sizeof('\n'));

        // Output table heading and column labels
        PR_fprintf(fd, "\nSessions:\n");
        memset(line, '-', width);
        line[width] = '\n';
        PR_Write(fd, line, width + sizeof('\n'));
        PR_Write(fd, line, format_session(line, offsets, session_column_labels));
        PR_Write(fd, "\n", 1);

        // Sort rows by age
        const SessionRow **sorted = new const SessionRow *[nr];
        for (y = 0; y < nr; y++)
            sorted[y] = &rows[y];
        qsort(sorted, nr, sizeof(sorted[0]), &session_cmp);

        // Output individual rows
        for (y = 0; y < nr; y++)
            PR_Write(fd, line, format_session(line, offsets, sorted[y]->columns));

        delete [] sorted;

        free(line);

        delete [] rows;
    }

    StatsManager::unlockStatsData();
    return REQ_PROCEED;
}
Ejemplo n.º 14
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;
}
/* one copy of this function is launched in a separate thread for each
** connection to be made.
*/
SECStatus
do_connects(void *a, int connection)
{
	PRNetAddr  *addr = (PRNetAddr *)a;
	PRFileDesc *sslSocket;
	PRHostEnt   hostEntry;
	char        buffer[PR_NETDB_BUF_SIZE];
	PRStatus    prStatus;
	PRIntn      hostenum;
	PRInt32    ip;
	SECStatus   secStatus;

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

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

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

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

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

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

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

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

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

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

	PR_Close(sslSocket);
	return SECSuccess;
}
Ejemplo n.º 16
0
/*
 * TCP Server
 *    Server binds an address to a socket, starts a client process and
 *	  listens for incoming connections.
 *    Each client connects to the server and sends a chunk of data
 *    Starts a Serve_Client job for each incoming connection, to read
 *    the data from the client and send it back to the client, unmodified.
 *    Each client checks that data received from server is same as the
 *    data it sent to the server.
 *	  Finally, the threadpool is shutdown
 */
static void PR_CALLBACK
TCP_Server(void *arg)
{
    PRThreadPool *tp = (PRThreadPool *) arg;
    Server_Param *sp;
    PRFileDesc *sockfd;
    PRNetAddr netaddr;
	PRMonitor *sc_mon;
	PRJob *jobp;
	int i;
	PRStatus rval;

    /*
     * Create a tcp socket
     */
    if ((sockfd = PR_NewTCPSocket()) == NULL) {
        fprintf(stderr,"%s: PR_NewTCPSocket failed\n", program_name);
        return;
    }
    memset(&netaddr, 0 , sizeof(netaddr));
    netaddr.inet.family = PR_AF_INET;
    netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
    netaddr.inet.ip = PR_htonl(PR_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,"%s: ERROR - PR_Bind failed\n", program_name);
        perror("PR_Bind");
        failed_already=1;
        return;
    }

    if (PR_Listen(sockfd, 32) < 0) {
        fprintf(stderr,"%s: ERROR - PR_Listen failed\n", program_name);
        failed_already=1;
        return;
    }

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

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

	sp = PR_NEW(Server_Param);
	if (sp == NULL) {
		fprintf(stderr,"%s: PR_NEW failed\n", program_name);
		failed_already=1;
		return;
	}
	sp->iod.socket = sockfd;
	sp->iod.timeout = PR_SecondsToInterval(60);
	sp->datalen = tcp_mesg_size;
	sp->exit_mon = sc_mon;
	sp->job_counterp = &job_counter;
	sp->conn_counter = 0;
	sp->tp = tp;
	sp->netaddr = netaddr;

	/* create and cancel an io job */
	jobp = PR_QueueJob_Accept(tp, &sp->iod, TCP_Server_Accept, sp,
							PR_FALSE);
	PR_ASSERT(NULL != jobp);
	rval = PR_CancelJob(jobp);
	PR_ASSERT(PR_SUCCESS == rval);

	/*
	 * create the client process
	 */
	{
#define MAX_ARGS 4
		char *argv[MAX_ARGS + 1];
		int index = 0;
		char port[32];
        char path[1024 + sizeof("/thrpool_client")];

        getcwd(path, sizeof(path));

        (void)strcat(path, "/thrpool_client");
#ifdef XP_PC
        (void)strcat(path, ".exe");
#endif
        argv[index++] = path;
		sprintf(port,"%d",PR_ntohs(netaddr.inet.port));
        if (_debug_on)
        {
            argv[index++] = "-d";
            argv[index++] = "-p";
            argv[index++] = port;
            argv[index++] = NULL;
        } else {
            argv[index++] = "-p";
            argv[index++] = port;
			argv[index++] = NULL;
		}
		PR_ASSERT(MAX_ARGS >= (index - 1));
        
        DPRINTF(("creating client process %s ...\n", path));
        if (PR_FAILURE == PR_CreateProcessDetached(path, argv, NULL, NULL)) {
        	fprintf(stderr,
				"thrpool_server: ERROR - PR_CreateProcessDetached failed\n");
        	failed_already=1;
        	return;
		}
	}

    sc_mon = PR_NewMonitor();
    if (sc_mon == NULL) {
        fprintf(stderr,"%s: PR_NewMonitor failed\n", program_name);
        failed_already=1;
        return;
    }

	sp->iod.socket = sockfd;
	sp->iod.timeout = PR_SecondsToInterval(60);
	sp->datalen = tcp_mesg_size;
	sp->exit_mon = sc_mon;
	sp->job_counterp = &job_counter;
	sp->conn_counter = 0;
	sp->tp = tp;
	sp->netaddr = netaddr;

	/* create and cancel a timer job */
	jobp = PR_QueueJob_Timer(tp, PR_MillisecondsToInterval(5000),
						print_stats, sp, PR_FALSE);
	PR_ASSERT(NULL != jobp);
	rval = PR_CancelJob(jobp);
	PR_ASSERT(PR_SUCCESS == rval);

    DPRINTF(("TCP_Server: Accepting connections \n"));

	jobp = PR_QueueJob_Accept(tp, &sp->iod, TCP_Server_Accept, sp,
							PR_FALSE);
	PR_ASSERT(NULL != jobp);
	return;
}
Ejemplo n.º 17
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()));
}
Ejemplo n.º 18
0
int main(int argc, char **argv)
{
    PRFileDesc *listenSock1, *listenSock2;
    PRFileDesc *fds0[10], *fds1[10], **fds, **other_fds;
    PRIntn nfds;
    PRUint16 listenPort1, listenPort2;
    PRNetAddr addr;
    PR_fd_set readFdSet;
    char buf[128];
    PRThread *clientThread;
    PRInt32 retVal;
    PRIntn i, j;

	/* 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.  \n");
		printf(" 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");
	failed_already=1;
	goto exit_now;
    }
    addr.inet.family = AF_INET;
    addr.inet.ip = PR_htonl(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 = AF_INET;
    addr.inet.ip = PR_htonl(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);

    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");
	failed_already=1;
	goto exit_now;
    }

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

    if (debug_mode) {
		printf("Two client threads are created.  Each of them will\n");
		printf("send data to one of the two 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");
	}
    /* set up the fd array */
    fds = fds0;
    other_fds = fds1;
    fds[0] = listenSock1;
    fds[1] = listenSock2;
    nfds = 2;
    /* Set up the fd set */
    PR_FD_ZERO(&readFdSet);
    PR_FD_SET(listenSock1, &readFdSet);
    PR_FD_SET(listenSock2, &readFdSet);

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

	retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
		PR_INTERVAL_NO_TIMEOUT);
	PR_ASSERT(retVal != 0);  /* no timeout */
	if (retVal == -1) {
	    fprintf(stderr, "PR_Select failed (%d, %d)\n", PR_GetError(),
		    PR_GetOSError());
	failed_already=1;
	    goto exit_now;
	}

	nextIndex = 2;
	/* the two listening sockets */
	for (j = 0; j < 2; j++) {
	    other_fds[j] = fds[j];
	    if (PR_FD_ISSET(fds[j], &readFdSet)) {
		PRFileDesc *sock;

		nEvents++;
		sock = PR_Accept(fds[j], NULL, PR_INTERVAL_NO_TIMEOUT);
		if (sock == NULL) {
		    fprintf(stderr, "PR_Accept() failed\n");
		failed_already=1;
		    goto exit_now;
		}
		other_fds[nextIndex] = sock;
		PR_FD_SET(sock, &readFdSet);
		nextIndex++;
	    }
	    PR_FD_SET(fds[j], &readFdSet);
	}

	for (j = 2; j < nfds; j++) {
	    if (PR_FD_ISSET(fds[j], &readFdSet)) {
		PRInt32 nBytes;

		PR_FD_CLR(fds[j], &readFdSet);
		nEvents++;
		nBytes = PR_Read(fds[j], buf, sizeof(buf));
		if (nBytes == -1) {
		    fprintf(stderr, "PR_Read() failed\n");
		failed_already=1;
		    goto exit_now;
		}
		/* Just to be safe */
		buf[127] = '\0';
		PR_Close(fds[j]);
		if (debug_mode) printf("The server received \"%s\" from a client\n", buf);
	    } else {
		PR_FD_SET(fds[j], &readFdSet);
		other_fds[nextIndex] = fds[j];
		nextIndex++;
	    }
	}

	PR_ASSERT(retVal == nEvents);
	/* swap */
	tmp = fds;
	fds = other_fds;
	other_fds = tmp;
	nfds = nextIndex;
	i += nEvents;
    }

    if (debug_mode) printf("Test passed\n");

    PR_Cleanup();
	goto exit_now;
exit_now:
	if(failed_already)	
		return 1;
	else
		return 0;
}
int main(int argc, char **argv)
{
    PRFileDesc *listenSock1 = NULL, *listenSock2 = NULL;
    PRUint16 listenPort1, listenPort2;
    PRNetAddr addr;
    char buf[128];
    PRThread *clientThread;
    PRPollDesc pds0[20], pds1[20], *pds, *other_pds;
    PRIntn npds;
    PRInt32 retVal;
    PRIntn i, j;
    PRSocketOptionData optval;

	/* 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("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");
	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");
	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);
    optval.option = PR_SockOpt_Nonblocking;
    optval.value.non_blocking = PR_TRUE;
    PR_SetSocketOption(listenSock1, &optval);
    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);
    PR_SetSocketOption(listenSock2, &optval);
    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 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;
    /* Add some unused entries to test if they are ignored by PR_Poll() */
    memset(&pds[2], 0, sizeof(pds[2]));
    memset(&pds[3], 0, sizeof(pds[3]));
    memset(&pds[4], 0, sizeof(pds[4]));
    npds = 5;

    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");
	failed_already=1;	
	goto exit_now;
    }

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

    if (debug_mode) {
		printf("Two client threads are created.  Each of them will\n");
		printf("send data to one of the two 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");
	}

    /* two clients, three events per iteration: accept, read, close */
    i = 0;
    while (i < 2 * 3 * NUM_ITERATIONS) {
	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");
		failed_already=1;			
	    goto exit_now;
	}

	nextIndex = 2;
	/* the two listening sockets */
	for (j = 0; j < 2; 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++;
		sock = PR_Accept(pds[j].fd, NULL, PR_INTERVAL_NO_TIMEOUT);
		if (sock == NULL) {
		    fprintf(stderr, "PR_Accept() failed\n");
			failed_already=1;	
		    goto exit_now;
		}
		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");
		failed_already=1;	
		goto exit_now;
	    } 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));
		failed_already=1;	
		goto exit_now;
	    }
	}

	for (j = 2; j < npds; j++) {
            if (NULL == pds[j].fd) {
                /*
                 * Keep the unused entries in the poll descriptor array
                 * for testing purposes.
                 */
                other_pds[nextIndex] = pds[j];
                nextIndex++;
                continue;
            }

	    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 nAvail;
		PRInt32 nRead;

		nEvents++;
                nAvail = PR_Available(pds[j].fd);
		nRead = PR_Read(pds[j].fd, buf, sizeof(buf));
                PR_ASSERT(nAvail == nRead);
		if (nRead == -1) {
		    fprintf(stderr, "PR_Read() failed\n");
			failed_already=1;	
		    goto exit_now;
                } else if (nRead == 0) {
                    PR_Close(pds[j].fd);
                    continue;
                } else {
                    /* Just to be safe */
                    buf[127] = '\0';
                    if (debug_mode) 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");
		failed_already=1;			
		goto exit_now;
	    } else if (pds[j].out_flags & PR_POLL_NVAL) {
		fprintf(stderr, "PR_Poll() indicates that an fd is invalid\n");
		failed_already=1;			
		goto exit_now;
	    }
            other_pds[nextIndex] = pds[j];
            nextIndex++;
	}

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

    if (debug_mode) printf("Tests passed\n");

exit_now:

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

    PR_Cleanup();
	
	if(failed_already)	
		return 1;
	else
		return 0;

}
Ejemplo n.º 20
0
CacheHashUtils::Hash16_t
CacheFileMetadata::GetHash(uint32_t aIndex)
{
  MOZ_ASSERT(aIndex < mHashCount);
  return PR_ntohs(mHashArray[aIndex]);
}
Ejemplo n.º 21
0
int main(int argc, char **argv)
{
    PRFileDesc *listenSock1, *listenSock2;
    PRFileDesc *badFD;
    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("error reporting is  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 = AF_INET;
    addr.inet.ip = PR_htonl(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 = AF_INET;
    addr.inet.ip = PR_htonl(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 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 bad fd */
    if (debug_mode) printf("PR_Poll should detect a bad file descriptor\n");
    if ((badFD = PR_NewTCPSocket()) == NULL) {
	fprintf(stderr, "Can't create a TCP socket\n");
	goto exit_now;
    }

    pds[2].fd = badFD;
    pds[2].in_flags = PR_POLL_READ;
    npds = 3;

    if (PR_CreateThread(PR_USER_THREAD, ClientThreadFunc,
            badFD, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
            PR_UNJOINABLE_THREAD, 0) == NULL) {
        fprintf(stderr, "cannot create thread\n");
        exit(1);
    }

    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[2].out_flags);
	failed_already=1;
	goto exit_now;
    }
    if (debug_mode) printf("PR_Poll detected the bad fd.  Test passed.\n\n");
    PR_Cleanup();
	goto exit_now;
exit_now:
	if(failed_already)
		return 1;
	else
		return 0;
}
Ejemplo n.º 22
0
int main(int argc, char **argv)
{
    PRFileDesc *listenSock1, *listenSock2;
    PRFileDesc *badFD;
    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.  Error\n");
		printf("reporting 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 = AF_INET;
    addr.inet.ip = PR_htonl(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 = AF_INET;
    addr.inet.ip = PR_htonl(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 bad fd */
    if (debug_mode) printf("PR_Select should detect a bad file descriptor\n");
    if ((badFD = PR_NewTCPSocket()) == NULL) {
	fprintf(stderr, "Can't create a TCP socket\n");
	failed_already=1;
	goto exit_now;
    }

    PR_FD_SET(badFD, &readFdSet);
    /*
     * Make the fd invalid
     */
#if defined(XP_UNIX)
    close(PR_FileDesc2NativeHandle(badFD));
#elif defined(XP_OS2)
    soclose(PR_FileDesc2NativeHandle(badFD));
#elif defined(WIN32) || defined(WIN16)
    closesocket(PR_FileDesc2NativeHandle(badFD));
#else
#error "Unknown architecture"
#endif

    retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
	    PR_INTERVAL_NO_TIMEOUT);
    if (retVal != -1 || PR_GetError() != PR_BAD_DESCRIPTOR_ERROR) {
	fprintf(stderr, "Failed to detect the bad fd: "
		"PR_Select returns %d\n", retVal);
	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 detected a bad fd.  Test passed.\n\n");
	PR_FD_CLR(badFD, &readFdSet);

	PR_Cleanup();
	goto exit_now;
exit_now:
	if(failed_already)	
		return 1;
	else
		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;
}
Ejemplo n.º 24
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;
}