bool ProxyAutoConfig::SrcAddress(const NetAddr *remoteAddress, nsCString &localAddress) { PRFileDesc *fd; fd = PR_OpenUDPSocket(remoteAddress->raw.family); if (!fd) return false; PRNetAddr prRemoteAddress; NetAddrToPRNetAddr(remoteAddress, &prRemoteAddress); if (PR_Connect(fd, &prRemoteAddress, 0) != PR_SUCCESS) { PR_Close(fd); return false; } PRNetAddr localName; if (PR_GetSockName(fd, &localName) != PR_SUCCESS) { PR_Close(fd); return false; } PR_Close(fd); char dottedDecimal[128]; if (PR_NetAddrToString(&localName, dottedDecimal, sizeof(dottedDecimal)) != PR_SUCCESS) return false; localAddress.Assign(dottedDecimal); return true; }
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; }
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; }
/* * 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())); }
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; }
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; }
/* * UDP_Client * Client Thread * Create a socket and bind an address * Communicate with the server at the address specified in the argument. * Fill in a buffer, write data to server, read it back and check * for data corruption. * Close the socket */ static void PR_CALLBACK UDP_Client(void *arg) { Client_Param *cp = (Client_Param *) arg; PRFileDesc *sockfd; buffer *in_buf, *out_buf; union PRNetAddr netaddr; PRInt32 bytes, i, rv; bytes = cp->datalen; out_buf = PR_NEW(buffer); if (out_buf == NULL) { fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); failed_already=1; return; } in_buf = PR_NEW(buffer); if (in_buf == NULL) { fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); failed_already=1; return; } if ((sockfd = PR_NewUDPSocket()) == NULL) { fprintf(stderr,"prsocket_test: PR_NewUDPSocket failed\n"); failed_already=1; return; } /* * bind an address for the client, let the system chose the port * number */ memset(&netaddr, 0 , sizeof(netaddr)); netaddr.inet.family = AF_INET; netaddr.inet.ip = PR_htonl(INADDR_ANY); netaddr.inet.port = PR_htons(0); if (PR_Bind(sockfd, &netaddr) < 0) { fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); perror("PR_Bind"); return; } if (PR_GetSockName(sockfd, &netaddr) < 0) { fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); failed_already=1; return; } DPRINTF(("PR_Bind: UDP Client netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", netaddr.inet.ip, netaddr.inet.port)); netaddr.inet.family = cp->server_addr.inet.family; netaddr.inet.port = cp->server_addr.inet.port; netaddr.inet.ip = cp->server_addr.inet.ip; if (cp->udp_connect) { if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ fprintf(stderr,"prsocket_test: PR_Connect failed\n"); failed_already=1; return; } } for (i = 0; i < num_udp_datagrams_per_client; i++) { /* * fill in random data */ DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx bytes = 0x%lx\n", PR_GetCurrentThread(), out_buf->data, bytes)); memset(out_buf->data, ((PRInt32) (&netaddr)) + i, bytes); /* * write to server */ if (cp->udp_connect) rv = PR_Send(sockfd, out_buf->data, bytes, 0, PR_INTERVAL_NO_TIMEOUT); else rv = PR_SendTo(sockfd, out_buf->data, bytes, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT); if (rv != bytes) { return; } DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n", PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data)))); if (cp->udp_connect) rv = PR_Recv(sockfd, in_buf->data, bytes, 0, PR_INTERVAL_NO_TIMEOUT); else rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT); if (rv != bytes) { return; } DPRINTF(("UDP_Client [0x%lx]: in_buf = 0x%lx in_buf[0] = 0x%lx\n", PR_GetCurrentThread(), in_buf, (*((int *) in_buf->data)))); /* * verify the data read */ if (memcmp(in_buf->data, out_buf->data, bytes) != 0) { fprintf(stderr,"prsocket_test: ERROR - UDP data corruption\n"); failed_already=1; return; } } PR_Close(sockfd); PR_DELETE(in_buf); PR_DELETE(out_buf); /* * Decrement exit_counter and notify parent thread */ PR_EnterMonitor(cp->exit_mon); --(*cp->exit_counter); PR_Notify(cp->exit_mon); PR_ExitMonitor(cp->exit_mon); PR_DELETE(cp); DPRINTF(("UDP_Client [0x%x] exiting\n", PR_GetCurrentThread())); }
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; }
int main(int argc, char **argv) { PRFileDesc *listenSock1 = NULL, *listenSock2 = NULL; PRUint16 listenPort1, listenPort2; PRNetAddr addr; char buf[128]; PRThread *clientThread; PRPollDesc pds0[20], pds1[20], *pds, *other_pds; PRIntn npds; PRInt32 retVal; PRIntn i, j; PRSocketOptionData optval; /* The command line argument: -d is used to determine if the test is being run in debug mode. The regress tool requires only one line output:PASS or FAIL. All of the printfs associated with this test has been handled with a if (debug_mode) test. Usage: test_name -d */ PLOptStatus os; PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { if (PL_OPT_BAD == os) continue; switch (opt->option) { case 'd': /* debug mode */ debug_mode = 1; break; default: break; } } PL_DestroyOptState(opt); /* main test */ PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); PR_STDIO_INIT(); if (debug_mode) { printf("This program tests PR_Poll with sockets.\n"); printf("Normal operation are tested.\n\n"); } /* Create two listening sockets */ if ((listenSock1 = PR_NewTCPSocket()) == NULL) { fprintf(stderr, "Can't create a new TCP socket\n"); failed_already=1; goto exit_now; } memset(&addr, 0, sizeof(addr)); addr.inet.family = PR_AF_INET; addr.inet.ip = PR_htonl(PR_INADDR_ANY); addr.inet.port = PR_htons(0); if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { fprintf(stderr, "Can't bind socket\n"); failed_already=1; goto exit_now; } if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { fprintf(stderr, "PR_GetSockName failed\n"); failed_already=1; goto exit_now; } listenPort1 = PR_ntohs(addr.inet.port); optval.option = PR_SockOpt_Nonblocking; optval.value.non_blocking = PR_TRUE; PR_SetSocketOption(listenSock1, &optval); if (PR_Listen(listenSock1, 5) == PR_FAILURE) { fprintf(stderr, "Can't listen on a socket\n"); failed_already=1; goto exit_now; } if ((listenSock2 = PR_NewTCPSocket()) == NULL) { fprintf(stderr, "Can't create a new TCP socket\n"); failed_already=1; goto exit_now; } addr.inet.family = PR_AF_INET; addr.inet.ip = PR_htonl(PR_INADDR_ANY); addr.inet.port = PR_htons(0); if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { fprintf(stderr, "Can't bind socket\n"); failed_already=1; goto exit_now; } if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { fprintf(stderr, "PR_GetSockName failed\n"); failed_already=1; goto exit_now; } listenPort2 = PR_ntohs(addr.inet.port); PR_SetSocketOption(listenSock2, &optval); if (PR_Listen(listenSock2, 5) == PR_FAILURE) { fprintf(stderr, "Can't listen on a socket\n"); failed_already=1; goto exit_now; } PR_snprintf(buf, sizeof(buf), "The server thread is listening on ports %hu and %hu\n\n", listenPort1, listenPort2); if (debug_mode) printf("%s", buf); /* Set up the poll descriptor array */ pds = pds0; other_pds = pds1; memset(pds, 0, sizeof(pds)); pds[0].fd = listenSock1; pds[0].in_flags = PR_POLL_READ; pds[1].fd = listenSock2; pds[1].in_flags = PR_POLL_READ; /* Add some unused entries to test if they are ignored by PR_Poll() */ memset(&pds[2], 0, sizeof(pds[2])); memset(&pds[3], 0, sizeof(pds[3])); memset(&pds[4], 0, sizeof(pds[4])); npds = 5; clientThread = PR_CreateThread(PR_USER_THREAD, clientThreadFunc, (void *) listenPort1, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); if (clientThread == NULL) { fprintf(stderr, "can't create thread\n"); failed_already=1; goto exit_now; } clientThread = PR_CreateThread(PR_USER_THREAD, clientThreadFunc, (void *) listenPort2, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); if (clientThread == NULL) { fprintf(stderr, "can't create thread\n"); failed_already=1; goto exit_now; } if (debug_mode) { printf("Two client threads are created. Each of them will\n"); printf("send data to one of the two ports the server is listening on.\n"); printf("The data they send is the port number. Each of them send\n"); printf("the data five times, so you should see ten lines below,\n"); printf("interleaved in an arbitrary order.\n"); } /* two clients, three events per iteration: accept, read, close */ i = 0; while (i < 2 * 3 * NUM_ITERATIONS) { PRPollDesc *tmp; int nextIndex; int nEvents = 0; retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT); PR_ASSERT(retVal != 0); /* no timeout */ if (retVal == -1) { fprintf(stderr, "PR_Poll failed\n"); failed_already=1; goto exit_now; } nextIndex = 2; /* the two listening sockets */ for (j = 0; j < 2; j++) { other_pds[j] = pds[j]; PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0 && (pds[j].out_flags & PR_POLL_EXCEPT) == 0); if (pds[j].out_flags & PR_POLL_READ) { PRFileDesc *sock; nEvents++; sock = PR_Accept(pds[j].fd, NULL, PR_INTERVAL_NO_TIMEOUT); if (sock == NULL) { fprintf(stderr, "PR_Accept() failed\n"); failed_already=1; goto exit_now; } other_pds[nextIndex].fd = sock; other_pds[nextIndex].in_flags = PR_POLL_READ; nextIndex++; } else if (pds[j].out_flags & PR_POLL_ERR) { fprintf(stderr, "PR_Poll() indicates that an fd has error\n"); failed_already=1; goto exit_now; } else if (pds[j].out_flags & PR_POLL_NVAL) { fprintf(stderr, "PR_Poll() indicates that fd %d is invalid\n", PR_FileDesc2NativeHandle(pds[j].fd)); failed_already=1; goto exit_now; } } for (j = 2; j < npds; j++) { if (NULL == pds[j].fd) { /* * Keep the unused entries in the poll descriptor array * for testing purposes. */ other_pds[nextIndex] = pds[j]; nextIndex++; continue; } PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0 && (pds[j].out_flags & PR_POLL_EXCEPT) == 0); if (pds[j].out_flags & PR_POLL_READ) { PRInt32 nAvail; PRInt32 nRead; nEvents++; nAvail = PR_Available(pds[j].fd); nRead = PR_Read(pds[j].fd, buf, sizeof(buf)); PR_ASSERT(nAvail == nRead); if (nRead == -1) { fprintf(stderr, "PR_Read() failed\n"); failed_already=1; goto exit_now; } else if (nRead == 0) { PR_Close(pds[j].fd); continue; } else { /* Just to be safe */ buf[127] = '\0'; if (debug_mode) printf("The server received \"%s\" from a client\n", buf); } } else if (pds[j].out_flags & PR_POLL_ERR) { fprintf(stderr, "PR_Poll() indicates that an fd has error\n"); failed_already=1; goto exit_now; } else if (pds[j].out_flags & PR_POLL_NVAL) { fprintf(stderr, "PR_Poll() indicates that an fd is invalid\n"); failed_already=1; goto exit_now; } other_pds[nextIndex] = pds[j]; nextIndex++; } PR_ASSERT(retVal == nEvents); /* swap */ tmp = pds; pds = other_pds; other_pds = tmp; npds = nextIndex; i += nEvents; } if (debug_mode) printf("Tests passed\n"); exit_now: if (listenSock1) { PR_Close(listenSock1); } if (listenSock2) { PR_Close(listenSock2); } PR_Cleanup(); if(failed_already) return 1; else return 0; }
int main(int argc, char **argv) { PRFileDesc *listenSock1, *listenSock2; PRFileDesc *fds0[10], *fds1[10], **fds, **other_fds; PRIntn nfds; PRUint16 listenPort1, listenPort2; PRNetAddr addr; PR_fd_set readFdSet; char buf[128]; PRThread *clientThread; PRInt32 retVal; PRIntn i, j; /* The command line argument: -d is used to determine if the test is being run in debug mode. The regress tool requires only one line output:PASS or FAIL. All of the printfs associated with this test has been handled with a if (debug_mode) test. Usage: test_name -d */ PLOptStatus os; PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { if (PL_OPT_BAD == os) continue; switch (opt->option) { case 'd': /* debug mode */ debug_mode = 1; break; default: break; } } PL_DestroyOptState(opt); /* main test */ PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); PR_STDIO_INIT(); if (debug_mode) { printf("This program tests PR_Select with sockets. \n"); printf(" Normal operation are tested.\n\n"); } /* Create two listening sockets */ if ((listenSock1 = PR_NewTCPSocket()) == NULL) { fprintf(stderr, "Can't create a new TCP socket\n"); failed_already=1; goto exit_now; } addr.inet.family = AF_INET; addr.inet.ip = PR_htonl(INADDR_ANY); addr.inet.port = PR_htons(0); if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { fprintf(stderr, "Can't bind socket\n"); failed_already=1; goto exit_now; } if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { fprintf(stderr, "PR_GetSockName failed\n"); failed_already=1; goto exit_now; } listenPort1 = PR_ntohs(addr.inet.port); if (PR_Listen(listenSock1, 5) == PR_FAILURE) { fprintf(stderr, "Can't listen on a socket\n"); failed_already=1; goto exit_now; } if ((listenSock2 = PR_NewTCPSocket()) == NULL) { fprintf(stderr, "Can't create a new TCP socket\n"); failed_already=1; goto exit_now; } addr.inet.family = AF_INET; addr.inet.ip = PR_htonl(INADDR_ANY); addr.inet.port = PR_htons(0); if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { fprintf(stderr, "Can't bind socket\n"); failed_already=1; goto exit_now; } if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { fprintf(stderr, "PR_GetSockName failed\n"); failed_already=1; goto exit_now; } listenPort2 = PR_ntohs(addr.inet.port); if (PR_Listen(listenSock2, 5) == PR_FAILURE) { fprintf(stderr, "Can't listen on a socket\n"); failed_already=1; goto exit_now; } PR_snprintf(buf, sizeof(buf), "The server thread is listening on ports %hu and %hu\n\n", listenPort1, listenPort2); if (debug_mode) printf("%s", buf); clientThread = PR_CreateThread(PR_USER_THREAD, clientThreadFunc, (void *) listenPort1, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); if (clientThread == NULL) { fprintf(stderr, "can't create thread\n"); failed_already=1; goto exit_now; } clientThread = PR_CreateThread(PR_USER_THREAD, clientThreadFunc, (void *) listenPort2, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); if (clientThread == NULL) { fprintf(stderr, "can't create thread\n"); failed_already=1; goto exit_now; } if (debug_mode) { printf("Two client threads are created. Each of them will\n"); printf("send data to one of the two ports the server is listening on.\n"); printf("The data they send is the port number. Each of them send\n"); printf("the data five times, so you should see ten lines below,\n"); printf("interleaved in an arbitrary order.\n"); } /* set up the fd array */ fds = fds0; other_fds = fds1; fds[0] = listenSock1; fds[1] = listenSock2; nfds = 2; /* Set up the fd set */ PR_FD_ZERO(&readFdSet); PR_FD_SET(listenSock1, &readFdSet); PR_FD_SET(listenSock2, &readFdSet); /* 20 events total */ i = 0; while (i < 20) { PRFileDesc **tmp; int nextIndex; int nEvents = 0; retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL, PR_INTERVAL_NO_TIMEOUT); PR_ASSERT(retVal != 0); /* no timeout */ if (retVal == -1) { fprintf(stderr, "PR_Select failed (%d, %d)\n", PR_GetError(), PR_GetOSError()); failed_already=1; goto exit_now; } nextIndex = 2; /* the two listening sockets */ for (j = 0; j < 2; j++) { other_fds[j] = fds[j]; if (PR_FD_ISSET(fds[j], &readFdSet)) { PRFileDesc *sock; nEvents++; sock = PR_Accept(fds[j], NULL, PR_INTERVAL_NO_TIMEOUT); if (sock == NULL) { fprintf(stderr, "PR_Accept() failed\n"); failed_already=1; goto exit_now; } other_fds[nextIndex] = sock; PR_FD_SET(sock, &readFdSet); nextIndex++; } PR_FD_SET(fds[j], &readFdSet); } for (j = 2; j < nfds; j++) { if (PR_FD_ISSET(fds[j], &readFdSet)) { PRInt32 nBytes; PR_FD_CLR(fds[j], &readFdSet); nEvents++; nBytes = PR_Read(fds[j], buf, sizeof(buf)); if (nBytes == -1) { fprintf(stderr, "PR_Read() failed\n"); failed_already=1; goto exit_now; } /* Just to be safe */ buf[127] = '\0'; PR_Close(fds[j]); if (debug_mode) printf("The server received \"%s\" from a client\n", buf); } else { PR_FD_SET(fds[j], &readFdSet); other_fds[nextIndex] = fds[j]; nextIndex++; } } PR_ASSERT(retVal == nEvents); /* swap */ tmp = fds; fds = other_fds; other_fds = tmp; nfds = nextIndex; i += nEvents; } if (debug_mode) printf("Test passed\n"); PR_Cleanup(); goto exit_now; exit_now: if(failed_already) return 1; else return 0; }
int FileSSLDoublePoint_main(char * strUserPin, char * strNickName) { #if 1 int isServer = 0; SECStatus rv = SECSuccess; char * buffer = malloc(1024 * 1024); PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); PK11_SetPasswordFunc(GetModulePassword); rv = NSS_Initialize(GetSystemDBDir(), "", "", "secmod.db", 0); rv = SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE); rv = SSL_OptionSetDefault(SSL_SOCKS, PR_TRUE); rv = SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_TRUE); rv = SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_TRUE); rv = SSL_OptionSetDefault(SSL_ENABLE_FDX, PR_TRUE); rv = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE); rv = NSS_SetDomesticPolicy(); rv = NSS_SetExportPolicy(); rv = NSS_SetFrancePolicy(); // rv = SSL_CipherPolicySet(); SSL_ClearSessionCache(); rv = SSL_ConfigServerSessionIDCache(10, 30 , 30, "."); PRFileDesc * tcp_socket = PR_NewTCPSocket(); PRFileDesc * ssl_socket = SSL_ImportFD(NULL,tcp_socket); if (isServer) { CERTCertDBHandle *certHandle; certHandle = CERT_GetDefaultCertDB(); char * nickname = "4914afeedee988071490b98f1120ddac_e73f20c7-176d-4342-ac89-ea7c00bb570a";/*nickname*/ CERTCertificate* cert = NULL; cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, nickname); SECKEYPrivateKey *prvKey = NULL; prvKey = PK11_FindKeyByAnyCert(cert, NULL); rv = SSL_ConfigSecureServer(ssl_socket, cert,prvKey,ssl_kea_rsa); PRNetAddr netAddr; PRNetAddr netAddrLocal; rv = PR_InitializeNetAddr(0, 8888, &netAddr); rv = PR_StringToNetAddr("127.0.0.1", &netAddrLocal); rv = PR_Bind(tcp_socket,&netAddr); rv = PR_Listen(tcp_socket, 100); while (1) { PRFileDesc * client = PR_Accept(tcp_socket, &netAddr, 6000000); PRNetAddr addr; rv = PR_GetSockName(client, &addr); rv = SSL_ForceHandshake(client); rv = PR_Write(client,"123", 4); sleep(1); } } else { rv = SSL_AuthCertificateHook(ssl_socket, OwnAuthCertHandler, NULL); char * nickname = "nickname";/*nickname*/ rv = SSL_SetURL(ssl_socket, "192.168.18.22"); char * str = malloc(1024) ; memset(str, 0, 1024); strcpy(str ,"GET /test/test2.html HTTP/1.1\r\n");//注意\r\n为回车换行 // str = [str stringByAppendingString:@"Accept-Language: zh-cn\r\n"]; // str = [str stringByAppendingString:@"Connection: Keep-Alive\r\n"]; //str = [str stringByAppendingString:@"Host: 192.168.0.106\r\n"]; strcat(str ,"Host: 192.168.18.22:8443\r\n"); // str = [str stringByAppendingString:@"Content-Length: 0\r\n"]; strcat(str ,"\r\n"); // str = [str stringByAppendingString:@"userName=liqiangqiang&password=new_andy\r\n"]; // str = [str stringByAppendingString:@"\r\n"]; PRNetAddr netAddr; rv = PR_StringToNetAddr("192.168.18.22", &netAddr); rv = PR_InitializeNetAddr(0, 8443, &netAddr); // rv = PR_GetHostByName(); // PR_EnumerateHostEnt rv = PR_Connect(tcp_socket,&netAddr, 300000); FILE_LOG_NUMBER("/sdcard/ssl.log", rv); rv = SSL_GetClientAuthDataHook(ssl_socket,NSS_GetClientAuthData,strNickName); FILE_LOG_NUMBER("/sdcard/ssl.log", rv); rv = SSL_ForceHandshake(ssl_socket); FILE_LOG_NUMBER("/sdcard/ssl.log", rv); rv = PR_Write(tcp_socket, str, strlen(str)); FILE_LOG_NUMBER("/sdcard/ssl.log", rv); rv = PR_Read(tcp_socket,buffer, 1024 * 1024); FILE_LOG_NUMBER("/sdcard/ssl.log", rv); FILE * file = fopen("/sdcard/ssl_read.txt", "wb"); //fwrite(buffer, 1, rv, file); //rv = PR_Read(tcp_socket,buffer, 1024 * 1024); fwrite(buffer, 1, rv, file); fclose(file); sleep(1); rv = SSL_InvalidateSession(ssl_socket); rv = PR_Shutdown(tcp_socket, PR_SHUTDOWN_BOTH); rv = PR_Close(tcp_socket); rv = ssl_FreeSessionCacheLocks(); rv = NSS_Shutdown(); } #endif return 0; }
/* * TCP Server * Server binds an address to a socket, starts a client process and * listens for incoming connections. * Each client connects to the server and sends a chunk of data * Starts a Serve_Client job for each incoming connection, to read * the data from the client and send it back to the client, unmodified. * Each client checks that data received from server is same as the * data it sent to the server. * Finally, the threadpool is shutdown */ static void PR_CALLBACK TCP_Server(void *arg) { PRThreadPool *tp = (PRThreadPool *) arg; Server_Param *sp; PRFileDesc *sockfd; PRNetAddr netaddr; PRMonitor *sc_mon; PRJob *jobp; int i; PRStatus rval; /* * Create a tcp socket */ if ((sockfd = PR_NewTCPSocket()) == NULL) { fprintf(stderr,"%s: PR_NewTCPSocket failed\n", program_name); return; } memset(&netaddr, 0 , sizeof(netaddr)); netaddr.inet.family = PR_AF_INET; netaddr.inet.port = PR_htons(TCP_SERVER_PORT); netaddr.inet.ip = PR_htonl(PR_INADDR_ANY); /* * try a few times to bind server's address, if addresses are in * use */ i = 0; while (PR_Bind(sockfd, &netaddr) < 0) { if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { netaddr.inet.port += 2; if (i++ < SERVER_MAX_BIND_COUNT) continue; } fprintf(stderr,"%s: ERROR - PR_Bind failed\n", program_name); perror("PR_Bind"); failed_already=1; return; } if (PR_Listen(sockfd, 32) < 0) { fprintf(stderr,"%s: ERROR - PR_Listen failed\n", program_name); failed_already=1; return; } if (PR_GetSockName(sockfd, &netaddr) < 0) { fprintf(stderr,"%s: ERROR - PR_GetSockName failed\n", program_name); failed_already=1; return; } DPRINTF(( "TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", netaddr.inet.ip, netaddr.inet.port)); sp = PR_NEW(Server_Param); if (sp == NULL) { fprintf(stderr,"%s: PR_NEW failed\n", program_name); failed_already=1; return; } sp->iod.socket = sockfd; sp->iod.timeout = PR_SecondsToInterval(60); sp->datalen = tcp_mesg_size; sp->exit_mon = sc_mon; sp->job_counterp = &job_counter; sp->conn_counter = 0; sp->tp = tp; sp->netaddr = netaddr; /* create and cancel an io job */ jobp = PR_QueueJob_Accept(tp, &sp->iod, TCP_Server_Accept, sp, PR_FALSE); PR_ASSERT(NULL != jobp); rval = PR_CancelJob(jobp); PR_ASSERT(PR_SUCCESS == rval); /* * create the client process */ { #define MAX_ARGS 4 char *argv[MAX_ARGS + 1]; int index = 0; char port[32]; char path[1024 + sizeof("/thrpool_client")]; getcwd(path, sizeof(path)); (void)strcat(path, "/thrpool_client"); #ifdef XP_PC (void)strcat(path, ".exe"); #endif argv[index++] = path; sprintf(port,"%d",PR_ntohs(netaddr.inet.port)); if (_debug_on) { argv[index++] = "-d"; argv[index++] = "-p"; argv[index++] = port; argv[index++] = NULL; } else { argv[index++] = "-p"; argv[index++] = port; argv[index++] = NULL; } PR_ASSERT(MAX_ARGS >= (index - 1)); DPRINTF(("creating client process %s ...\n", path)); if (PR_FAILURE == PR_CreateProcessDetached(path, argv, NULL, NULL)) { fprintf(stderr, "thrpool_server: ERROR - PR_CreateProcessDetached failed\n"); failed_already=1; return; } } sc_mon = PR_NewMonitor(); if (sc_mon == NULL) { fprintf(stderr,"%s: PR_NewMonitor failed\n", program_name); failed_already=1; return; } sp->iod.socket = sockfd; sp->iod.timeout = PR_SecondsToInterval(60); sp->datalen = tcp_mesg_size; sp->exit_mon = sc_mon; sp->job_counterp = &job_counter; sp->conn_counter = 0; sp->tp = tp; sp->netaddr = netaddr; /* create and cancel a timer job */ jobp = PR_QueueJob_Timer(tp, PR_MillisecondsToInterval(5000), print_stats, sp, PR_FALSE); PR_ASSERT(NULL != jobp); rval = PR_CancelJob(jobp); PR_ASSERT(PR_SUCCESS == rval); DPRINTF(("TCP_Server: Accepting connections \n")); jobp = PR_QueueJob_Accept(tp, &sp->iod, TCP_Server_Accept, sp, PR_FALSE); PR_ASSERT(NULL != jobp); return; }
int FileSSL_main(int argc, char * argv[]) { bool isServer = true; SECStatus rv = SECSuccess; char buffer[32] = {0}; PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); PK11_SetPasswordFunc(GetModulePassword); rv = NSS_Initialize(GetSystemDBDir(), "", "", "secmod.db", 0); rv = SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE); rv = SSL_OptionSetDefault(SSL_SOCKS, PR_TRUE); rv = SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_TRUE); rv = SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_TRUE); rv = SSL_OptionSetDefault(SSL_ENABLE_FDX, PR_TRUE); rv = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE); rv = NSS_SetDomesticPolicy(); rv = NSS_SetExportPolicy(); rv = NSS_SetFrancePolicy(); // rv = SSL_CipherPolicySet(); SSL_ClearSessionCache(); rv = SSL_ConfigServerSessionIDCache(10, 30 , 30, "."); PRFileDesc * socket = PR_NewTCPSocket(); socket = SSL_ImportFD(NULL,socket); if (isServer) { CERTCertDBHandle *certHandle; certHandle = CERT_GetDefaultCertDB(); char * nickname = "itrus Certificate DB:2013-11-15 12:44:10";/*nickname*/ CERTCertificate* cert = NULL; cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, nickname); SECKEYPrivateKey *prvKey = NULL; prvKey = PK11_FindKeyByAnyCert(cert, NULL); rv = SSL_ConfigSecureServer(socket, cert,prvKey,ssl_kea_rsa); PRNetAddr netAddr; PRNetAddr netAddrLocal; rv = PR_InitializeNetAddr(0, 8888, &netAddr); rv = PR_StringToNetAddr("127.0.0.1", &netAddrLocal); rv = PR_Bind(socket,&netAddr); rv = PR_Listen(socket, 100); while (1) { PRFileDesc * client = PR_Accept(socket, &netAddr, 6000000); PRNetAddr addr; rv = PR_GetSockName(client, &addr); rv = SSL_ForceHandshake(client); rv = PR_Write(client,"123", 4); sleep(1); } } else { rv = SSL_SetURL(socket, "127.0.0.1"); PRNetAddr netAddr; PRNetAddr netAddrLocal; rv = PR_InitializeNetAddr(0, 8888, &netAddr); rv = PR_StringToNetAddr("127.0.0.1", &netAddrLocal); // rv = PR_GetHostByName(); // PR_EnumerateHostEnt rv = PR_Connect(socket,&netAddr, 300000); rv = SSL_AuthCertificateHook(socket, OwnAuthCertHandler, NULL); rv = SSL_ForceHandshake(socket); while (1) { rv = PR_Read(socket,buffer, 32); sleep(1); } } return 0; }
/* * 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())); }
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; }
/* * UDP Server * Server Thread * Bind an address to a socket, read data from clients and send data * back to clients */ static void PR_CALLBACK UDP_Server(void *arg) { Server_Param *sp = (Server_Param *) arg; PRFileDesc *sockfd; buffer *in_buf; PRNetAddr netaddr; PRInt32 bytes, i, rv; bytes = sp->datalen; /* * Create a udp socket */ if ((sockfd = PR_NewUDPSocket()) == NULL) { fprintf(stderr,"prsocket_test: PR_NewUDPSocket failed\n"); failed_already=1; return; } memset(&netaddr, 0 , sizeof(netaddr)); netaddr.inet.family = AF_INET; netaddr.inet.port = PR_htons(UDP_SERVER_PORT); netaddr.inet.ip = PR_htonl(INADDR_ANY); /* * try a few times to bind server's address, if addresses are in * use */ i = 0; while (PR_Bind(sockfd, &netaddr) < 0) { if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { netaddr.inet.port += 2; if (i++ < SERVER_MAX_BIND_COUNT) continue; } fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); perror("PR_Bind"); failed_already=1; return; } if (PR_GetSockName(sockfd, &netaddr) < 0) { fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); failed_already=1; return; } if (netaddr.inet.port != PR_htons(UDP_SERVER_PORT)) { fprintf(stderr,"prsocket_test: ERROR - tried to bind to UDP " "port %hu, but was bound to port %hu\n", UDP_SERVER_PORT, PR_ntohs(netaddr.inet.port)); failed_already=1; return; } DPRINTF(("PR_Bind: UDP Server netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", netaddr.inet.ip, netaddr.inet.port)); udp_server_addr = netaddr; /* * We can't use the IP address returned by PR_GetSockName in * netaddr.inet.ip because netaddr.inet.ip is returned * as 0 (= INADDR_ANY). */ udp_server_addr.inet.ip = PR_htonl(INADDR_LOOPBACK); /* * Wake up parent thread because server address is bound and made * available in the global variable 'udp_server_addr' */ PR_PostSem(sp->addr_sem); bytes = sp->datalen; in_buf = PR_NEW(buffer); if (in_buf == NULL) { fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); failed_already=1; return; } /* * Receive datagrams from clients and send them back, unmodified, to the * clients */ memset(&netaddr, 0 , sizeof(netaddr)); for (i = 0; i < (num_udp_clients * num_udp_datagrams_per_client); i++) { DPRINTF(("UDP_Server: calling PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n", netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data, in_buf->data[0])); rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT); DPRINTF(("UDP_Server: PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n", netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data, in_buf->data[0])); if (rv != bytes) { return; } rv = PR_SendTo(sockfd, in_buf->data, bytes, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT); if (rv != bytes) { return; } } PR_DELETE(in_buf); /* * Decrement exit_counter and notify parent thread */ PR_EnterMonitor(sp->exit_mon); --(*sp->exit_counter); PR_Notify(sp->exit_mon); PR_ExitMonitor(sp->exit_mon); DPRINTF(("UDP_Server [0x%x] exiting\n", PR_GetCurrentThread())); }
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; }
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; }
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; }
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 }
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; }
// nr_socket APIs (as member functions) int NrSocket::create(nr_transport_addr *addr) { int r,_status; PRStatus status; PRNetAddr naddr; nsresult rv; nsCOMPtr<nsISocketTransportService> stservice = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); if (!NS_SUCCEEDED(rv)) { ABORT(R_INTERNAL); } if((r=nr_transport_addr_to_praddr(addr, &naddr))) ABORT(r); switch (addr->protocol) { case IPPROTO_UDP: if (!(fd_ = PR_NewUDPSocket())) { r_log(LOG_GENERIC,LOG_CRIT,"Couldn't create socket"); ABORT(R_INTERNAL); } break; case IPPROTO_TCP: if (!(fd_ = PR_NewTCPSocket())) { r_log(LOG_GENERIC,LOG_CRIT,"Couldn't create socket"); ABORT(R_INTERNAL); } break; default: ABORT(R_INTERNAL); } status = PR_Bind(fd_, &naddr); if (status != PR_SUCCESS) { r_log(LOG_GENERIC,LOG_CRIT,"Couldn't bind socket to address %s", addr->as_string); ABORT(R_INTERNAL); } r_log(LOG_GENERIC,LOG_DEBUG,"Creating socket %p with addr %s", fd_, addr->as_string); nr_transport_addr_copy(&my_addr_,addr); /* If we have a wildcard port, patch up the addr */ if(nr_transport_addr_is_wildcard(addr)){ status = PR_GetSockName(fd_, &naddr); if (status != PR_SUCCESS){ r_log(LOG_GENERIC, LOG_CRIT, "Couldn't get sock name for socket"); ABORT(R_INTERNAL); } if((r=nr_praddr_to_transport_addr(&naddr,&my_addr_,addr->protocol,1))) ABORT(r); } // Set nonblocking PRSocketOptionData option; option.option = PR_SockOpt_Nonblocking; option.value.non_blocking = PR_TRUE; status = PR_SetSocketOption(fd_, &option); if (status != PR_SUCCESS) { r_log(LOG_GENERIC, LOG_CRIT, "Couldn't make socket nonblocking"); ABORT(R_INTERNAL); } // Remember our thread. ststhread_ = do_QueryInterface(stservice, &rv); if (!NS_SUCCEEDED(rv)) ABORT(R_INTERNAL); // Finally, register with the STS rv = stservice->AttachSocket(fd_, this); if (!NS_SUCCEEDED(rv)) { ABORT(R_INTERNAL); } _status = 0; abort: return(_status); }
int main(int argc, char **argv) { PRFileDesc *listenSock1, *listenSock2; PRFileDesc *badFD; PRUint16 listenPort1, listenPort2; PRNetAddr addr; PR_fd_set readFdSet; char buf[128]; PRInt32 retVal; /* The command line argument: -d is used to determine if the test is being run in debug mode. The regress tool requires only one line output:PASS or FAIL. All of the printfs associated with this test has been handled with a if (debug_mode) test. Usage: test_name -d */ PLOptStatus os; PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { if (PL_OPT_BAD == os) continue; switch (opt->option) { case 'd': /* debug mode */ debug_mode = 1; break; default: break; } } PL_DestroyOptState(opt); /* main test */ PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); PR_STDIO_INIT(); if (debug_mode) { printf("This program tests PR_Select with sockets. Error\n"); printf("reporting operations are tested.\n\n"); } /* Create two listening sockets */ if ((listenSock1 = PR_NewTCPSocket()) == NULL) { fprintf(stderr, "Can't create a new TCP socket\n"); failed_already=1; goto exit_now; } addr.inet.family = AF_INET; addr.inet.ip = PR_htonl(INADDR_ANY); addr.inet.port = PR_htons(0); if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { fprintf(stderr, "Can't bind socket\n"); failed_already=1; goto exit_now; } if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { fprintf(stderr, "PR_GetSockName failed\n"); failed_already=1; goto exit_now; } listenPort1 = PR_ntohs(addr.inet.port); if (PR_Listen(listenSock1, 5) == PR_FAILURE) { fprintf(stderr, "Can't listen on a socket\n"); failed_already=1; goto exit_now; } if ((listenSock2 = PR_NewTCPSocket()) == NULL) { fprintf(stderr, "Can't create a new TCP socket\n"); failed_already=1; goto exit_now; } addr.inet.family = AF_INET; addr.inet.ip = PR_htonl(INADDR_ANY); addr.inet.port = PR_htons(0); if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { fprintf(stderr, "Can't bind socket\n"); failed_already=1; goto exit_now; } if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { fprintf(stderr, "PR_GetSockName failed\n"); failed_already=1; goto exit_now; } listenPort2 = PR_ntohs(addr.inet.port); if (PR_Listen(listenSock2, 5) == PR_FAILURE) { fprintf(stderr, "Can't listen on a socket\n"); failed_already=1; goto exit_now; } PR_snprintf(buf, sizeof(buf), "The server thread is listening on ports %hu and %hu\n\n", listenPort1, listenPort2); if (debug_mode) printf("%s", buf); /* Set up the fd set */ PR_FD_ZERO(&readFdSet); PR_FD_SET(listenSock1, &readFdSet); PR_FD_SET(listenSock2, &readFdSet); /* Testing bad fd */ if (debug_mode) printf("PR_Select should detect a bad file descriptor\n"); if ((badFD = PR_NewTCPSocket()) == NULL) { fprintf(stderr, "Can't create a TCP socket\n"); failed_already=1; goto exit_now; } PR_FD_SET(badFD, &readFdSet); /* * Make the fd invalid */ #if defined(XP_UNIX) close(PR_FileDesc2NativeHandle(badFD)); #elif defined(XP_OS2) soclose(PR_FileDesc2NativeHandle(badFD)); #elif defined(WIN32) || defined(WIN16) closesocket(PR_FileDesc2NativeHandle(badFD)); #else #error "Unknown architecture" #endif retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL, PR_INTERVAL_NO_TIMEOUT); if (retVal != -1 || PR_GetError() != PR_BAD_DESCRIPTOR_ERROR) { fprintf(stderr, "Failed to detect the bad fd: " "PR_Select returns %d\n", retVal); if (retVal == -1) { fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(), PR_GetOSError()); failed_already=1; } goto exit_now; } if (debug_mode) printf("PR_Select detected a bad fd. Test passed.\n\n"); PR_FD_CLR(badFD, &readFdSet); PR_Cleanup(); goto exit_now; exit_now: if(failed_already) return 1; else return 0; }