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;
}
Esempio n. 2
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;
}
Esempio n. 3
0
static void Server(void)
{
    PRStatus rv;
    PRNetAddr server_address, client_address;
    PRFileDesc *xport = PR_Socket(domain, PR_SOCK_STREAM, protocol);

    if (NULL == xport)
    {
        PL_FPrintError(err, "PR_Socket");
        return;
    }

    rv = PR_InitializeNetAddr(PR_IpAddrAny, PORT_NUMBER, &server_address);
    if (PR_FAILURE == rv) PL_FPrintError(err, "PR_InitializeNetAddr");
    else
    {
        rv = PR_Bind(xport, &server_address);
        if (PR_FAILURE == rv) PL_FPrintError(err, "PR_Bind");
        else
        {
            PRFileDesc *client;
            rv = PR_Listen(xport, 10);
            PR_fprintf(err, "Server listening on ");
            (void)PrintAddress(&server_address);
            do
            {
                client = PR_Accept(
                    xport, &client_address, PR_INTERVAL_NO_TIMEOUT);
                if (NULL == client) PL_FPrintError(err, "PR_Accept");
                else
                {
                    PR_fprintf(err, "Server accepting from ");
                    (void)PrintAddress(&client_address);
                    shared->threads += 1;
                    (void)PR_CreateThread(
                        PR_USER_THREAD, Servette, client,
                        PR_PRIORITY_NORMAL, thread_scope,
                        PR_UNJOINABLE_THREAD, 8 * 1024);
                }
            } while (PR_TRUE);

        }
    }
}  /* Server */
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;
}
Esempio n. 5
0
int ConfigServerSocket() {

  /* Set up Net address to bind to 'any' */
  int r;
 
  r = PR_InitializeNetAddr(PR_IpAddrAny,0,&svr.na);
  if (PR_SUCCESS != r) return Error(2);

  
  r = PR_Bind(svr.r,&svr.na);     /* bind to an IP address */
  if (PR_SUCCESS != r) return Error(3);


  r = PR_Listen(svr.r,5);
  if (PR_SUCCESS != r) return Error(4);


  r = PR_GetSockName(svr.r,&svr.na);
  if (PR_SUCCESS != r) return Error(5);
  return r;
}
static void PR_CALLBACK Server(void *arg)
{
    PRStatus rv;
    PRNetAddr serverAddress;
    PRThread *me = PR_GetCurrentThread();
    CSServer_t *server = (CSServer_t*)arg;
    PRSocketOptionData sockOpt;

    server->listener = PR_Socket(domain, SOCK_STREAM, protocol);

    sockOpt.option = PR_SockOpt_Reuseaddr;
    sockOpt.value.reuse_addr = PR_TRUE;
    rv = PR_SetSocketOption(server->listener, &sockOpt);
    TEST_ASSERT(PR_SUCCESS == rv);

    memset(&serverAddress, 0, sizeof(serverAddress));
	if (PR_AF_INET6 != domain)
		rv = PR_InitializeNetAddr(PR_IpAddrAny, DEFAULT_PORT, &serverAddress);
	else
		rv = PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, DEFAULT_PORT,
													&serverAddress);
    rv = PR_Bind(server->listener, &serverAddress);
    TEST_ASSERT(PR_SUCCESS == rv);

    rv = PR_Listen(server->listener, server->backlog);
    TEST_ASSERT(PR_SUCCESS == rv);

    server->started = PR_IntervalNow();
    TimeOfDayMessage("Server started at", me);

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

    /*
    ** Create the first worker (actually, a thread that accepts
    ** connections and then processes the work load as needed).
    ** From this point on, additional worker threads are created
    ** as they are needed by existing worker threads.
    */
    rv = CreateWorker(server, &server->pool);
    TEST_ASSERT(PR_SUCCESS == rv);

    /*
    ** From here on this thread is merely hanging around as the contact
    ** point for the main test driver. It's just waiting for the driver
    ** to declare the test complete.
    */
    TEST_LOG(
        cltsrv_log_file, TEST_LOG_VERBOSE,
        ("\tServer(0x%p): waiting for state change\n", me));

    PR_Lock(server->ml);
    while ((cs_run == server->state) && !Aborted(rv))
    {
        rv = PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
    }
    PR_Unlock(server->ml);
    PR_ClearInterrupt();

    TEST_LOG(
        cltsrv_log_file, TEST_LOG_INFO,
        ("\tServer(0x%p): shutting down workers\n", me));

    /*
    ** Get all the worker threads to exit. They know how to
    ** clean up after themselves, so this is just a matter of
    ** waiting for clorine in the pool to take effect. During
    ** this stage we're ignoring interrupts.
    */
    server->workers.minimum = server->workers.maximum = 0;

    PR_Lock(server->ml);
    while (!PR_CLIST_IS_EMPTY(&server->list))
    {
        PRCList *head = PR_LIST_HEAD(&server->list);
        CSWorker_t *worker = (CSWorker_t*)head;
        TEST_LOG(
            cltsrv_log_file, TEST_LOG_VERBOSE,
            ("\tServer(0x%p): interrupting worker(0x%p)\n", me, worker));
        rv = PR_Interrupt(worker->thread);
        TEST_ASSERT(PR_SUCCESS == rv);
        PR_REMOVE_AND_INIT_LINK(head);
    }

    while (server->pool.workers > 0)
    {
        TEST_LOG(
            cltsrv_log_file, TEST_LOG_NOTICE,
            ("\tServer(0x%p): waiting for %u workers to exit\n",
            me, server->pool.workers));
        (void)PR_WaitCondVar(server->pool.exiting, PR_INTERVAL_NO_TIMEOUT);
    }

    server->state = cs_exit;
    PR_NotifyCondVar(server->stateChange);
    PR_Unlock(server->ml);

    TEST_LOG(
        cltsrv_log_file, TEST_LOG_ALWAYS,
        ("\tServer(0x%p): stopped after %u operations and %u bytes\n",
        me, server->operations, server->bytesTransferred));

    if (NULL != server->listener) PR_Close(server->listener);
    server->stopped = PR_IntervalNow();

}  /* Server */
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()));
    }
}
Esempio n. 8
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;
}
Esempio n. 9
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;
}
Esempio n. 10
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;
}
Esempio n. 11
0
PRFileDesc *
getBoundListenSocket(unsigned short port)
{
    PRFileDesc *       listen_sock;
    int                listenQueueDepth = 5 + (2 * maxThreads);
    PRStatus	       prStatus;
    PRNetAddr          addr;
    PRSocketOptionData opt;

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

    listen_sock = PR_NewTCPSocket();
    if (listen_sock == NULL) {
	errExit("PR_NewTCPSocket");
    }

    opt.option = PR_SockOpt_Nonblocking;
    opt.value.non_blocking = PR_FALSE;
    prStatus = PR_SetSocketOption(listen_sock, &opt);
    if (prStatus < 0) {
        PR_Close(listen_sock);
	errExit("PR_SetSocketOption(PR_SockOpt_Nonblocking)");
    }

    opt.option=PR_SockOpt_Reuseaddr;
    opt.value.reuse_addr = PR_TRUE;
    prStatus = PR_SetSocketOption(listen_sock, &opt);
    if (prStatus < 0) {
        PR_Close(listen_sock);
	errExit("PR_SetSocketOption(PR_SockOpt_Reuseaddr)");
    }

#ifndef WIN95
    /* Set PR_SockOpt_Linger because it helps prevent a server bind issue
     * after clean shutdown . See bug 331413 .
     * Don't do it in the WIN95 build configuration because clean shutdown is
     * not implemented, and PR_SockOpt_Linger causes a hang in ssl.sh .
     * See bug 332348 */
    opt.option=PR_SockOpt_Linger;
    opt.value.linger.polarity = PR_TRUE;
    opt.value.linger.linger = PR_SecondsToInterval(1);
    prStatus = PR_SetSocketOption(listen_sock, &opt);
    if (prStatus < 0) {
        PR_Close(listen_sock);
        errExit("PR_SetSocketOption(PR_SockOpt_Linger)");
    }
#endif

    prStatus = PR_Bind(listen_sock, &addr);
    if (prStatus < 0) {
        PR_Close(listen_sock);
	errExit("PR_Bind");
    }

    prStatus = PR_Listen(listen_sock, listenQueueDepth);
    if (prStatus < 0) {
        PR_Close(listen_sock);
	errExit("PR_Listen");
    }
    return listen_sock;
}
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;
}
Esempio n. 13
0
int
main(int argc, char * const argv[])
{
    struct qnetd_instance instance;
    struct qnetd_advanced_settings advanced_settings;
    char *host_addr;
    uint16_t host_port;
    int foreground;
    int debug_log;
    int bump_log_priority;
    enum tlv_tls_supported tls_supported;
    int client_cert_required;
    size_t max_clients;
    PRIntn address_family;
    int lock_file;
    int another_instance_running;

    if (qnetd_advanced_settings_init(&advanced_settings) != 0) {
        errx(1, "Can't alloc memory for advanced settings");
    }

    cli_parse(argc, argv, &host_addr, &host_port, &foreground, &debug_log, &bump_log_priority,
              &tls_supported, &client_cert_required, &max_clients, &address_family, &advanced_settings);

    if (foreground) {
        qnetd_log_init(QNETD_LOG_TARGET_STDERR);
    } else {
        qnetd_log_init(QNETD_LOG_TARGET_SYSLOG);
    }

    qnetd_log_set_debug(debug_log);
    qnetd_log_set_priority_bump(bump_log_priority);

    /*
     * Daemonize
     */
    if (!foreground) {
        utils_tty_detach();
    }

    if ((lock_file = utils_flock(advanced_settings.lock_file, getpid(),
                                 &another_instance_running)) == -1) {
        if (another_instance_running) {
            qnetd_log(LOG_ERR, "Another instance is running");
        } else {
            qnetd_log_err(LOG_ERR, "Can't acquire lock");
        }

        exit(1);
    }

    qnetd_log(LOG_DEBUG, "Initializing nss");
    if (nss_sock_init_nss((tls_supported != TLV_TLS_UNSUPPORTED ?
                           advanced_settings.nss_db_dir : NULL)) != 0) {
        qnetd_err_nss();
    }

    if (SSL_ConfigServerSessionIDCache(0, 0, 0, NULL) != SECSuccess) {
        qnetd_err_nss();
    }

    if (qnetd_instance_init(&instance, tls_supported, client_cert_required,
                            max_clients, &advanced_settings) == -1) {
        qnetd_log(LOG_ERR, "Can't initialize qnetd");
        exit(1);
    }
    instance.host_addr = host_addr;
    instance.host_port = host_port;

    if (tls_supported != TLV_TLS_UNSUPPORTED && qnetd_instance_init_certs(&instance) == -1) {
        qnetd_err_nss();
    }

    qnetd_log(LOG_DEBUG, "Initializing local socket");
    if (qnetd_ipc_init(&instance) != 0) {
        return (1);
    }

    qnetd_log(LOG_DEBUG, "Creating listening socket");
    instance.server.socket = nss_sock_create_listen_socket(instance.host_addr,
                             instance.host_port, address_family);
    if (instance.server.socket == NULL) {
        qnetd_err_nss();
    }

    if (nss_sock_set_non_blocking(instance.server.socket) != 0) {
        qnetd_err_nss();
    }

    if (PR_Listen(instance.server.socket, instance.advanced_settings->listen_backlog) !=
            PR_SUCCESS) {
        qnetd_err_nss();
    }

    global_instance = &instance;
    signal_handlers_register();

    qnetd_log(LOG_DEBUG, "Registering algorithms");
    if (qnetd_algorithm_register_all() != 0) {
        exit(1);
    }

    qnetd_log(LOG_DEBUG, "QNetd ready to provide service");
    /*
     * MAIN LOOP
     */
    while (qnetd_poll(&instance) == 0) {
    }

    /*
     * Cleanup
     */
    qnetd_ipc_destroy(&instance);

    if (PR_Close(instance.server.socket) != PR_SUCCESS) {
        qnetd_warn_nss();
    }

    CERT_DestroyCertificate(instance.server.cert);
    SECKEY_DestroyPrivateKey(instance.server.private_key);

    SSL_ClearSessionCache();

    SSL_ShutdownServerSessionIDCache();

    qnetd_instance_destroy(&instance);

    qnetd_advanced_settings_destroy(&advanced_settings);

    if (NSS_Shutdown() != SECSuccess) {
        qnetd_warn_nss();
    }

    if (PR_Cleanup() != PR_SUCCESS) {
        qnetd_warn_nss();
    }

    qnetd_log_close();

    return (0);
}
Esempio n. 14
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 */
Esempio n. 15
0
int
StartServer(const char *nssCertDBDir, SSLSNISocketConfig sniSocketConfig,
            void *sniSocketConfigArg)
{
  const char *debugLevel = PR_GetEnv("MOZ_TLS_SERVER_DEBUG_LEVEL");
  if (debugLevel) {
    int level = atoi(debugLevel);
    switch (level) {
      case DEBUG_ERRORS: gDebugLevel = DEBUG_ERRORS; break;
      case DEBUG_WARNINGS: gDebugLevel = DEBUG_WARNINGS; break;
      case DEBUG_VERBOSE: gDebugLevel = DEBUG_VERBOSE; break;
      default:
        PrintPRError("invalid MOZ_TLS_SERVER_DEBUG_LEVEL");
        return 1;
    }
  }

  const char *callbackPort = PR_GetEnv("MOZ_TLS_SERVER_CALLBACK_PORT");
  if (callbackPort) {
    gCallbackPort = atoi(callbackPort);
  }

  if (InitializeNSS(nssCertDBDir) != SECSuccess) {
    PR_fprintf(PR_STDERR, "InitializeNSS failed");
    return 1;
  }

  if (NSS_SetDomesticPolicy() != SECSuccess) {
    PrintPRError("NSS_SetDomesticPolicy failed");
    return 1;
  }

  if (SSL_ConfigServerSessionIDCache(0, 0, 0, nullptr) != SECSuccess) {
    PrintPRError("SSL_ConfigServerSessionIDCache failed");
    return 1;
  }

  UniquePRFileDesc serverSocket(PR_NewTCPSocket());
  if (!serverSocket) {
    PrintPRError("PR_NewTCPSocket failed");
    return 1;
  }

  PRSocketOptionData socketOption;
  socketOption.option = PR_SockOpt_Reuseaddr;
  socketOption.value.reuse_addr = true;
  PR_SetSocketOption(serverSocket.get(), &socketOption);

  PRNetAddr serverAddr;
  PR_InitializeNetAddr(PR_IpAddrLoopback, LISTEN_PORT, &serverAddr);
  if (PR_Bind(serverSocket.get(), &serverAddr) != PR_SUCCESS) {
    PrintPRError("PR_Bind failed");
    return 1;
  }

  if (PR_Listen(serverSocket.get(), 1) != PR_SUCCESS) {
    PrintPRError("PR_Listen failed");
    return 1;
  }

  UniquePRFileDesc rawModelSocket(PR_NewTCPSocket());
  if (!rawModelSocket) {
    PrintPRError("PR_NewTCPSocket failed for rawModelSocket");
    return 1;
  }

  UniquePRFileDesc modelSocket(SSL_ImportFD(nullptr, rawModelSocket.release()));
  if (!modelSocket) {
    PrintPRError("SSL_ImportFD of rawModelSocket failed");
    return 1;
  }

  if (SSL_SNISocketConfigHook(modelSocket.get(), sniSocketConfig,
                              sniSocketConfigArg) != SECSuccess) {
    PrintPRError("SSL_SNISocketConfigHook failed");
    return 1;
  }

  // We have to configure the server with a certificate, but it's not one
  // we're actually going to end up using. In the SNI callback, we pick
  // the right certificate for the connection.
  if (ConfigSecureServerWithNamedCert(modelSocket.get(), DEFAULT_CERT_NICKNAME,
                                      nullptr, nullptr) != SECSuccess) {
    return 1;
  }

  if (gCallbackPort != 0) {
    if (DoCallback()) {
      return 1;
    }
  }

  while (true) {
    PRNetAddr clientAddr;
    PRFileDesc* clientSocket = PR_Accept(serverSocket.get(), &clientAddr,
                                         PR_INTERVAL_NO_TIMEOUT);
    HandleConnection(clientSocket, modelSocket);
  }

  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);
}
Esempio n. 17
0
NSAPI_PUBLIC int net_listen(SYS_NETFD s, int backlog)
{
    return PR_Listen(s, backlog)==PR_FAILURE?IO_ERROR:0;
}
Esempio n. 18
0
static bool NewTCPSocketPair(PRFileDesc *fd[])
{
  // this is a replacement for PR_NewTCPSocketPair that manually
  // sets the recv buffer to 64K. A windows bug (1248358)
  // can result in using an incompatible rwin and window
  // scale option on localhost pipes if not set before connect.

  PRFileDesc *listener = nullptr;
  PRFileDesc *writer = nullptr;
  PRFileDesc *reader = nullptr;
  PRSocketOptionData recvBufferOpt;
  recvBufferOpt.option = PR_SockOpt_RecvBufferSize;
  recvBufferOpt.value.recv_buffer_size = 65535;

  PRSocketOptionData nodelayOpt;
  nodelayOpt.option = PR_SockOpt_NoDelay;
  nodelayOpt.value.no_delay = true;

  PRSocketOptionData noblockOpt;
  noblockOpt.option = PR_SockOpt_Nonblocking;
  noblockOpt.value.non_blocking = true;

  listener = PR_OpenTCPSocket(PR_AF_INET);
  if (!listener) {
    goto failed;
  }
  PR_SetSocketOption(listener, &recvBufferOpt);
  PR_SetSocketOption(listener, &nodelayOpt);

  PRNetAddr listenAddr;
  memset(&listenAddr, 0, sizeof(listenAddr));
  if ((PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &listenAddr) == PR_FAILURE) ||
      (PR_Bind(listener, &listenAddr) == PR_FAILURE) ||
      (PR_GetSockName(listener, &listenAddr) == PR_FAILURE) || // learn the dynamic port
      (PR_Listen(listener, 5) == PR_FAILURE)) {
    goto failed;
  }

  writer = PR_OpenTCPSocket(PR_AF_INET);
  if (!writer) {
    goto failed;
  }
  PR_SetSocketOption(writer, &recvBufferOpt);
  PR_SetSocketOption(writer, &nodelayOpt);
  PR_SetSocketOption(writer, &noblockOpt);
  PRNetAddr writerAddr;
  if (PR_InitializeNetAddr(PR_IpAddrLoopback, ntohs(listenAddr.inet.port), &writerAddr) == PR_FAILURE) {
    goto failed;
  }

  if (PR_Connect(writer, &writerAddr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
    if ((PR_GetError() != PR_IN_PROGRESS_ERROR) ||
        (PR_ConnectContinue(writer, PR_POLL_WRITE) == PR_FAILURE)) {
      goto failed;
    }
  }

  reader = PR_Accept(listener, &listenAddr, PR_INTERVAL_NO_TIMEOUT);
  if (!reader) {
    goto failed;
  }
  PR_SetSocketOption(reader, &recvBufferOpt);
  PR_SetSocketOption(reader, &nodelayOpt);
  PR_SetSocketOption(reader, &noblockOpt);
  PR_Close(listener);

  fd[0] = reader;
  fd[1] = writer;
  return true;

failed:
  if (listener) {
    PR_Close(listener);
  }
  if (reader) {
    PR_Close(reader);
  }
  if (writer) {
    PR_Close(writer);
  }
  return false;
}
Esempio n. 19
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()));
}
Esempio n. 20
0
PRIntn main(PRIntn argc, char *argv[])
{
    PRThread *tJitter;
    PRThread *tAccept;
    PRThread *tConnect;
    PRStatus rv;
    /* This test if valid for WinNT only! */

#if !defined(WINNT)
    return 0;
#endif

    {
        /*
        ** Get command line options
        */
        PLOptStatus os;
        PLOptState *opt = PL_CreateOptState(argc, argv, "hdrvj:");

	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
        {
		    if (PL_OPT_BAD == os) continue;
            switch (opt->option)
            {
            case 'd':  /* debug */
                debug = 1;
			    msgLevel = PR_LOG_ERROR;
                break;
            case 'v':  /* verbose mode */
                verbose = 1;
			    msgLevel = PR_LOG_DEBUG;
                break;
            case 'j':
                jitter = atoi(opt->value);
                if ( jitter == 0)
                    jitter = JITTER_DEFAULT;
                break;
            case 'r':
                resume = PR_TRUE;
                break;
            case 'h':  /* help message */
			    Help();
                break;
             default:
                break;
            }
        }
	    PL_DestroyOptState(opt);
    }

    lm = PR_NewLogModule("Test");       /* Initialize logging */

    /* set concurrency */
    PR_SetConcurrency( 4 );

    /* setup thread synchronization mechanics */
    ml = PR_NewLock();
    cv = PR_NewCondVar( ml );

    /* setup a tcp socket */
    memset(&listenAddr, 0, sizeof(listenAddr));
    rv = PR_InitializeNetAddr(PR_IpAddrAny, BASE_PORT, &listenAddr);
    PR_ASSERT( PR_SUCCESS == rv );

    listenSock = PR_NewTCPSocket();
    PR_ASSERT( listenSock );

    rv = PR_Bind( listenSock, &listenAddr);
    PR_ASSERT( PR_SUCCESS == rv );

    rv = PR_Listen( listenSock, 5 );
    PR_ASSERT( PR_SUCCESS == rv );

    /* open a file for writing, provoke bug */
    file1 = PR_Open("xxxTestFile", PR_CREATE_FILE | PR_RDWR, 666);

    /* create Connect thread */
    tConnect = PR_CreateThread(
        PR_USER_THREAD, ConnectThread, NULL,
        PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
        PR_JOINABLE_THREAD, 0 );
    PR_ASSERT( tConnect );

    /* create jitter off thread */
    tJitter = PR_CreateThread(
        PR_USER_THREAD, JitterThread, NULL,
        PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
        PR_JOINABLE_THREAD, 0 );
    PR_ASSERT( tJitter );

    /* create acceptread thread */
    tAccept = PR_CreateThread(
        PR_USER_THREAD, AcceptThread, NULL,
        PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
        PR_JOINABLE_THREAD, 0 );
    PR_ASSERT( tAccept );

    /* wait for all threads to quit, then terminate gracefully */
    PR_JoinThread( tConnect );
    PR_JoinThread( tAccept );
    PR_JoinThread( tJitter );
    PR_Close( listenSock );
    PR_DestroyCondVar(cv);
    PR_DestroyLock(ml);
    PR_Close( file1 );
    PR_Delete( "xxxTestFile");

    /* test return and exit */
    if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS");
    return( (failed_already == PR_TRUE )? 1 : 0 );
}  /* main() */
Esempio n. 21
0
NS_IMETHODIMP
nsServerSocket::InitWithAddress(const PRNetAddr *aAddr, PRInt32 aBackLog)
{
  NS_ENSURE_TRUE(mFD == nsnull, NS_ERROR_ALREADY_INITIALIZED);

  if (!mLock)
  {
    mLock = PR_NewLock();
    if (!mLock)
      return NS_ERROR_OUT_OF_MEMORY;
  }

  //
  // configure listening socket...
  //

  mFD = PR_OpenTCPSocket(aAddr->raw.family);
  if (!mFD)
  {
    NS_WARNING("unable to create server socket");
    return NS_ERROR_FAILURE;
  }

  PRSocketOptionData opt;

  opt.option = PR_SockOpt_Reuseaddr;
  opt.value.reuse_addr = PR_TRUE;
  PR_SetSocketOption(mFD, &opt);

  opt.option = PR_SockOpt_Nonblocking;
  opt.value.non_blocking = PR_TRUE;
  PR_SetSocketOption(mFD, &opt);

  if (PR_Bind(mFD, aAddr) != PR_SUCCESS)
  {
    NS_WARNING("failed to bind socket");
    goto fail;
  }

  if (aBackLog < 0)
    aBackLog = 5; // seems like a reasonable default

  if (PR_Listen(mFD, aBackLog) != PR_SUCCESS)
  {
    NS_WARNING("cannot listen on socket");
    goto fail;
  }

  // get the resulting socket address, which may be different than what
  // we passed to bind.
  if (PR_GetSockName(mFD, &mAddr) != PR_SUCCESS)
  {
    NS_WARNING("cannot get socket name");
    goto fail;
  }

  // wait until AsyncListen is called before polling the socket for
  // client connections.
  return NS_OK;

fail:
  Close();
  return NS_ERROR_FAILURE;
}
Esempio n. 22
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);
}
Esempio n. 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()));
}
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;
}
Esempio n. 25
0
static void AcceptingThread(void *arg)
{
    PRStatus rv;
    PRInt32 bytes;
    PRSize buf_size = BUF_SIZE;
    PRUint8 buf[BUF_SIZE + (2 * sizeof(PRNetAddr)) + 32];
    PRNetAddr *accept_addr, *listen_addr = (PRNetAddr*)arg;
    PRFileDesc *accept_sock, *listen_sock = PR_NewTCPSocket();
    PRFileDesc *layer;
    PRSocketOptionData sock_opt;

    if (NULL == listen_sock)
    {
        PL_FPrintError(err_out, "PR_NewTCPSocket (server) failed");
        PR_ProcessExit(1);        
    }
    layer = PR_CreateIOLayerStub(emu_layer_ident, &emu_layer_methods);
    if (NULL == layer)
    {
        PL_FPrintError(err_out, "PR_CreateIOLayerStub (server) failed");
        PR_ProcessExit(1);        
    }
    if (PR_PushIOLayer(listen_sock, PR_TOP_IO_LAYER, layer) == PR_FAILURE)
    {
        PL_FPrintError(err_out, "PR_PushIOLayer (server) failed");
        PR_ProcessExit(1);        
    }
    sock_opt.option = PR_SockOpt_Reuseaddr;
    sock_opt.value.reuse_addr = PR_TRUE;
    rv = PR_SetSocketOption(listen_sock, &sock_opt);
    if (PR_FAILURE == rv)
    {
        PL_FPrintError(err_out, "PR_SetSocketOption (server) failed");
        PR_ProcessExit(1);        
    }
    rv = PR_Bind(listen_sock, listen_addr);
    if (PR_FAILURE == rv)
    {
        PL_FPrintError(err_out, "PR_Bind (server) failed");
        PR_ProcessExit(1);        
    }
    rv = PR_Listen(listen_sock, 10);
    if (PR_FAILURE == rv)
    {
        PL_FPrintError(err_out, "PR_Listen (server) failed");
        PR_ProcessExit(1);        
    }
    bytes = PR_AcceptRead(
        listen_sock, &accept_sock, &accept_addr, buf, buf_size, accept_timeout);

    if (-1 == bytes) PL_FPrintError(err_out, "PR_AcceptRead (server) failed");
    else
    {
        PrintAddress(accept_addr);
        PR_fprintf(
            std_out, "(Server) read [0x%p..0x%p) %s\n",
            buf, &buf[BUF_SIZE], buf);
        bytes = PR_Write(accept_sock, buf, bytes);
        rv = PR_Shutdown(accept_sock, PR_SHUTDOWN_BOTH);
        if (PR_FAILURE == rv)
            PL_FPrintError(err_out, "PR_Shutdown (server) failed");
    }

    if (-1 != bytes)
    {
        rv = PR_Close(accept_sock);
        if (PR_FAILURE == rv)
            PL_FPrintError(err_out, "PR_Close (server) failed");
    }

    rv = PR_Close(listen_sock);
    if (PR_FAILURE == rv)
        PL_FPrintError(err_out, "PR_Close (server) failed");
}  /* AcceptingThread */
Esempio n. 26
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;

}
Esempio n. 27
0
PRIntn main(PRIntn argc, char **argv)
{
    PRStatus rv;
    PRIntn mits;
    PLOptStatus os;
    PRFileDesc *client, *service;
    PRFileDesc *client_stack, *service_stack;
    PRNetAddr any_address;
    const char *server_name = NULL;
    const PRIOMethods *stubMethods;
    PRThread *client_thread, *server_thread;
    PRThreadScope thread_scope = PR_LOCAL_THREAD;
    PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:");
    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
        if (PL_OPT_BAD == os) continue;
        switch (opt->option)
        {
        case 0:
            server_name = opt->value;
            break;
        case 'd':  /* debug mode */
            if (verbosity < noisy)
                verbosity = ChangeVerbosity(verbosity, 1);
            break;
        case 'q':  /* debug mode */
            if (verbosity > silent)
                verbosity = ChangeVerbosity(verbosity, -1);
            break;
        case 'G':  /* use global threads */
            thread_scope = PR_GLOBAL_THREAD;
            break;
        case 'C':  /* number of threads waiting */
            major_iterations = atoi(opt->value);
            break;
        case 'c':  /* number of client threads */
            minor_iterations = atoi(opt->value);
            break;
        case 'p':  /* default port */
            default_port = atoi(opt->value);
            break;
        default:
            break;
        }
    }
    PL_DestroyOptState(opt);
    PR_STDIO_INIT();

    logFile = PR_GetSpecialFD(PR_StandardError);

    identity = PR_GetUniqueIdentity("Dummy");
    stubMethods = PR_GetDefaultIOMethods();

    /*
    ** The protocol we're going to implement is one where in order to initiate
    ** a send, the sender must first solicit permission. Therefore, every
    ** send is really a send - receive - send sequence.
    */
    myMethods = *stubMethods;  /* first get the entire batch */
    myMethods.recv = MyRecv;  /* then override the ones we care about */
    myMethods.send = MySend;  /* then override the ones we care about */

    if (NULL == server_name)
        rv = PR_InitializeNetAddr(
            PR_IpAddrLoopback, default_port, &server_address);
    else
    {
        rv = PR_StringToNetAddr(server_name, &server_address);
        PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_InitializeNetAddr(
            PR_IpAddrNull, default_port, &server_address);
    }
    PR_ASSERT(PR_SUCCESS == rv);

    /* one type w/o layering */

    mits = minor_iterations;
    while (major_iterations-- > 0)
    {
        if (verbosity > silent)
            PR_fprintf(logFile, "Beginning non-layered test\n");
        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
        PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);

        minor_iterations = mits;
        server_thread = PR_CreateThread(
            PR_USER_THREAD, Server, service,
            PR_PRIORITY_HIGH, thread_scope,
            PR_JOINABLE_THREAD, 16 * 1024);
        PR_ASSERT(NULL != server_thread);

        client_thread = PR_CreateThread(
            PR_USER_THREAD, Client, client,
            PR_PRIORITY_NORMAL, thread_scope,
            PR_JOINABLE_THREAD, 16 * 1024);
        PR_ASSERT(NULL != client_thread);

        rv = PR_JoinThread(client_thread);
        PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_JoinThread(server_thread);
        PR_ASSERT(PR_SUCCESS == rv);

        rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
        if (verbosity > silent)
            PR_fprintf(logFile, "Ending non-layered test\n");

        /* with layering */
        if (verbosity > silent)
            PR_fprintf(logFile, "Beginning layered test\n");
        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
        PushLayer(client);
        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
        PushLayer(service);
        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
        PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);

        minor_iterations = mits;
        server_thread = PR_CreateThread(
            PR_USER_THREAD, Server, service,
            PR_PRIORITY_HIGH, thread_scope,
            PR_JOINABLE_THREAD, 16 * 1024);
        PR_ASSERT(NULL != server_thread);

        client_thread = PR_CreateThread(
            PR_USER_THREAD, Client, client,
            PR_PRIORITY_NORMAL, thread_scope,
            PR_JOINABLE_THREAD, 16 * 1024);
        PR_ASSERT(NULL != client_thread);

        rv = PR_JoinThread(client_thread);
        PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_JoinThread(server_thread);
        PR_ASSERT(PR_SUCCESS == rv);

        rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
        /* with layering, using new style stack */
        if (verbosity > silent)
            PR_fprintf(logFile,
							"Beginning layered test with new style stack\n");
        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
    	client_stack = PR_CreateIOLayer(client);
        PushNewLayers(client_stack);
        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
    	service_stack = PR_CreateIOLayer(service);
        PushNewLayers(service_stack);
        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
        PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);

        minor_iterations = mits;
        server_thread = PR_CreateThread(
            PR_USER_THREAD, Server, service_stack,
            PR_PRIORITY_HIGH, thread_scope,
            PR_JOINABLE_THREAD, 16 * 1024);
        PR_ASSERT(NULL != server_thread);

        client_thread = PR_CreateThread(
            PR_USER_THREAD, Client, client_stack,
            PR_PRIORITY_NORMAL, thread_scope,
            PR_JOINABLE_THREAD, 16 * 1024);
        PR_ASSERT(NULL != client_thread);

        rv = PR_JoinThread(client_thread);
        PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_JoinThread(server_thread);
        PR_ASSERT(PR_SUCCESS == rv);

        rv = PR_Close(client_stack); PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Close(service_stack); PR_ASSERT(PR_SUCCESS == rv);
        if (verbosity > silent)
            PR_fprintf(logFile, "Ending layered test\n");
    }
    return 0;
}  /* main */
Esempio n. 28
0
NS_IMETHODIMP
nsServerSocket::InitWithAddress(const PRNetAddr *aAddr, int32_t aBackLog)
{
  NS_ENSURE_TRUE(mFD == nullptr, NS_ERROR_ALREADY_INITIALIZED);
  nsresult rv;

  //
  // configure listening socket...
  //

  mFD = PR_OpenTCPSocket(aAddr->raw.family);
  if (!mFD)
  {
    NS_WARNING("unable to create server socket");
    return ErrorAccordingToNSPR(PR_GetError());
  }

  PRSocketOptionData opt;

  opt.option = PR_SockOpt_Reuseaddr;
  opt.value.reuse_addr = true;
  PR_SetSocketOption(mFD, &opt);

  opt.option = PR_SockOpt_Nonblocking;
  opt.value.non_blocking = true;
  PR_SetSocketOption(mFD, &opt);

  if (PR_Bind(mFD, aAddr) != PR_SUCCESS)
  {
    NS_WARNING("failed to bind socket");
    goto fail;
  }

  if (aBackLog < 0)
    aBackLog = 5; // seems like a reasonable default

  if (PR_Listen(mFD, aBackLog) != PR_SUCCESS)
  {
    NS_WARNING("cannot listen on socket");
    goto fail;
  }

  // get the resulting socket address, which may be different than what
  // we passed to bind.
  if (PR_GetSockName(mFD, &mAddr) != PR_SUCCESS)
  {
    NS_WARNING("cannot get socket name");
    goto fail;
  }

  // Set any additional socket defaults needed by child classes
  rv = SetSocketDefaults();
  if (NS_WARN_IF(NS_FAILED(rv))) {
    goto fail;
  }

  // wait until AsyncListen is called before polling the socket for
  // client connections.
  return NS_OK;

fail:
  rv = ErrorAccordingToNSPR(PR_GetError());
  Close();
  return rv;
}
PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *f[])
{
#ifdef XP_UNIX
	PRInt32 rv, osfd[2];

	if (!_pr_initialized) _PR_ImplicitInitialization();

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

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

    if (!_pr_initialized) _PR_ImplicitInitialization();

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

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

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

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

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

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

failed:
    if (listenSock) {
        PR_Close(listenSock);
    }
    if (f[0]) {
        PR_Close(f[0]);
    }
    if (f[1]) {
        PR_Close(f[1]);
    }
    return PR_FAILURE;
#endif
}
Esempio n. 30
0
// Constructor
OsTLSServerSocket::OsTLSServerSocket(int connectionQueueSize,
                                     int serverPort,
                                     UtlString certNickname,
                                     UtlString certPassword,
                                     UtlString dbLocation,
                                     const UtlString bindAddress)
   : OsServerSocket(connectionQueueSize,serverPort, bindAddress.data(), false),
     mCertNickname(certNickname),
     mCertPassword(certPassword),
     mDbLocation(dbLocation),
     mpMozillaSSLSocket(NULL),
     mpCert(NULL),
     mpPrivKey(NULL),
     mTlsInitCode(TLS_INIT_SUCCESS)
{
    PRSocketOptionData      socketOption;
    PRStatus                prStatus;
    SECStatus secStatus;
    
    // import the newly created socket into NSS, and set the PRFileDesc.
    if (socketDescriptor > OS_INVALID_SOCKET_DESCRIPTOR)
    {
        /* Call the NSPR initialization routines. */
        PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);

        /* Set the cert database password callback. */
        PK11_SetPasswordFunc(OsTLS::PasswordCallback);

        secStatus = NSS_Init(dbLocation.data());
        if (secStatus != SECSuccess)
        {
            mTlsInitCode = TLS_INIT_DATABASE_FAILURE;
            return ;
        }

        /* Set the policy for this server (REQUIRED - no default). */
        secStatus = NSS_SetExportPolicy();
        if (secStatus != SECSuccess)
        {
            mTlsInitCode = TLS_INIT_DATABASE_FAILURE;
            return ;
        }

        /* Get own certificate and private key. */
        mpCert = PK11_FindCertFromNickname((char*) certNickname.data(), (void*)certPassword.data());
        if (mpCert == NULL)
        {
            return ;
        }
            
        unsigned char* szPwd = (unsigned char*) PR_Malloc(certPassword.length()+ 1);
        strncpy((char*)szPwd, certPassword.data(), certPassword.length()+1);
        mpPrivKey = PK11_FindKeyByAnyCert(mpCert, (void*)szPwd);
        if (mpPrivKey == NULL)
        {
            mTlsInitCode = TLS_INIT_BAD_PASSWORD;
            // probably a wrong password
            return ;
        }

        /* Configure the server's cache for a multi-process application
        * using default timeout values (24 hrs) and directory location (/tmp). 
        */
        SSL_ConfigMPServerSIDCache(256, 0, 0, NULL);

        mpMozillaSSLSocket = PR_ImportTCPSocket(socketDescriptor);

        if (!mpMozillaSSLSocket)
        {
            mTlsInitCode = TLS_INIT_TCP_IMPORT_FAILURE;
        }
        else
        {
            /* Make the socket blocking. */
            socketOption.option                 = PR_SockOpt_Nonblocking;
            socketOption.value.non_blocking = PR_FALSE;

            prStatus = PR_SetSocketOption(mpMozillaSSLSocket, &socketOption);
            if (prStatus != PR_SUCCESS)
            {
                mTlsInitCode = TLS_INIT_NSS_FAILURE;
                return;
            }
            
            secStatus = SSL_CipherPrefSetDefault(SSL_RSA_WITH_NULL_MD5, PR_TRUE);
            if (secStatus != SECSuccess)
            {
                mTlsInitCode = TLS_INIT_NSS_FAILURE;
                return;
            }            
            
            PRNetAddr addr;
            /* Configure the network connection. */
            addr.inet.family = PR_AF_INET;
            addr.inet.ip     = inet_addr(bindAddress.data());
            addr.inet.port   = PR_htons(serverPort);

            /* Bind the address to the listener socket. */
            prStatus = PR_Bind(mpMozillaSSLSocket, &addr);
            if (prStatus != PR_SUCCESS)
            {
                mTlsInitCode = TLS_INIT_NSS_FAILURE;
                return;
            }
 
            /* Listen for connection on the socket.  The second argument is
            * the maximum size of the queue for pending connections.
            */
            prStatus = PR_Listen(mpMozillaSSLSocket, connectionQueueSize);
            if (prStatus != PR_SUCCESS)
            {
                mTlsInitCode = TLS_INIT_NSS_FAILURE;
                return;
            }
        }            
    }        
}