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; }
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; }
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; }
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())); } }
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; }
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; }
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; }
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; }
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); }
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 */
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); }
NSAPI_PUBLIC int net_listen(SYS_NETFD s, int backlog) { return PR_Listen(s, backlog)==PR_FAILURE?IO_ERROR: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; }
/* * 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())); }
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() */
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; }
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); }
/* * 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; }
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 */
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; }
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 */
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 }
// 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; } } } }