am_status_t Connection::read(char *buffer, std::size_t& bufferLen) { am_status_t status = AM_SUCCESS; PRInt32 bytesRead; PRInt32 bytesToRead; if (bufferLen > static_cast<std::size_t>(MAX_READ_WRITE_LEN)) { bytesToRead = MAX_READ_WRITE_LEN; } else { bytesToRead = static_cast<PRInt32>(bufferLen); } bytesRead = PR_Recv(socket, buffer, bytesToRead, 0, receive_timeout); if (bytesRead < 0) { status = AM_NSPR_ERROR; PRErrorCode error = PR_GetError(); Log::log(Log::ALL_MODULES, Log::LOG_ERROR, "Connection::read(): NSPR Error while reading data:%d", PR_GetError()); if (error == PR_IO_TIMEOUT_ERROR || error == PR_CONNECT_RESET_ERROR || error == PR_CONNECT_REFUSED_ERROR || error == PR_NETWORK_DOWN_ERROR || error == PR_NETWORK_UNREACHABLE_ERROR || error == PR_HOST_UNREACHABLE_ERROR) { throw NSPRException("Connection::read()", "PR_Recv"); } } else { bufferLen = static_cast<std::size_t>(bytesRead); } return status; }
static void PR_CALLBACK Client(void *arg) { PRStatus rv; PRUint8 buffer[100]; PRIntn empty_flags = 0; PRIntn bytes_read, bytes_sent; PRFileDesc *stack = (PRFileDesc*)arg; /* Initialize the buffer so that Purify won't complain */ memset(buffer, 0, sizeof(buffer)); rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT); PR_ASSERT(PR_SUCCESS == rv); while (minor_iterations-- > 0) { bytes_sent = PR_Send( stack, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT); PR_ASSERT(sizeof(buffer) == bytes_sent); if (verbosity > chatty) PR_fprintf(logFile, "Client sending %d bytes\n", bytes_sent); bytes_read = PR_Recv( stack, buffer, bytes_sent, empty_flags, PR_INTERVAL_NO_TIMEOUT); if (verbosity > chatty) PR_fprintf(logFile, "Client receiving %d bytes\n", bytes_read); PR_ASSERT(bytes_read == bytes_sent); } if (verbosity > quiet) PR_fprintf(logFile, "Client shutting down stack\n"); rv = PR_Shutdown(stack, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv); } /* Client */
// returns 0 on success, non-zero on error int DoCallback() { UniquePRFileDesc socket(PR_NewTCPSocket()); if (!socket) { PrintPRError("PR_NewTCPSocket failed"); return 1; } PRNetAddr addr; PR_InitializeNetAddr(PR_IpAddrLoopback, gCallbackPort, &addr); if (PR_Connect(socket.get(), &addr, PR_INTERVAL_NO_TIMEOUT) != PR_SUCCESS) { PrintPRError("PR_Connect failed"); return 1; } const char *request = "GET / HTTP/1.0\r\n\r\n"; SendAll(socket.get(), request, strlen(request)); char buf[4096]; memset(buf, 0, sizeof(buf)); int32_t bytesRead = PR_Recv(socket.get(), buf, sizeof(buf) - 1, 0, PR_INTERVAL_NO_TIMEOUT); if (bytesRead < 0) { PrintPRError("PR_Recv failed 1"); return 1; } if (bytesRead == 0) { fprintf(stderr, "PR_Recv eof 1\n"); return 1; } fprintf(stderr, "%s\n", buf); return 0; }
/* * If the read would block we return -1 and set 'wouldblock' to TRUE. * Otherwise we return the amount of data read. Other errors should return -1 * and set 'wouldblock' to FALSE. */ ssize_t Curl_nss_recv(struct connectdata * conn, /* connection data */ int num, /* socketindex */ char *buf, /* store read data here */ size_t buffersize, /* max amount to read */ bool * wouldblock) { ssize_t nread; struct SessionHandle *data = conn->data; PRInt32 timeout; if(data->set.timeout) timeout = PR_SecondsToInterval((PRUint32)data->set.timeout); else timeout = PR_MillisecondsToInterval(DEFAULT_CONNECT_TIMEOUT); nread = PR_Recv(conn->ssl[num].handle, buf, (int)buffersize, 0, timeout); *wouldblock = FALSE; if(nread < 0) { /* failed SSL read */ PRInt32 err = PR_GetError(); if(err == PR_WOULD_BLOCK_ERROR) { *wouldblock = TRUE; return -1; /* basically EWOULDBLOCK */ } if(err == PR_IO_TIMEOUT_ERROR) { failf(data, "SSL connection timeout"); return CURLE_OPERATION_TIMEDOUT; } failf(conn->data, "SSL read: errno %d", err); return -1; } return nread; }
static ssize_t nss_recv(struct connectdata * conn, /* connection data */ int num, /* socketindex */ char *buf, /* store read data here */ size_t buffersize, /* max amount to read */ CURLcode *curlcode) { ssize_t nread; nread = PR_Recv(conn->ssl[num].handle, buf, (int)buffersize, 0, -1); if(nread < 0) { /* failed SSL read */ PRInt32 err = PR_GetError(); if(err == PR_WOULD_BLOCK_ERROR) *curlcode = CURLE_AGAIN; else if(handle_cc_error(err, conn->data)) *curlcode = CURLE_SSL_CERTPROBLEM; else { failf(conn->data, "SSL read: errno %d", err); *curlcode = CURLE_RECV_ERROR; } return -1; } return nread; }
PR_IMPLEMENT(PRInt32) PR_EmulateAcceptRead( PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout) { PRInt32 rv = -1; PRNetAddr remote; PRFileDesc *accepted = NULL; /* ** The timeout does not apply to the accept portion of the ** operation - it waits indefinitely. */ accepted = PR_Accept(sd, &remote, PR_INTERVAL_NO_TIMEOUT); if (NULL == accepted) return rv; rv = PR_Recv(accepted, buf, amount, 0, timeout); if (rv >= 0) { /* copy the new info out where caller can see it */ #define AMASK ((PRPtrdiff)7) /* mask for alignment of PRNetAddr */ PRPtrdiff aligned = (PRPtrdiff)buf + amount + AMASK; *raddr = (PRNetAddr*)(aligned & ~AMASK); memcpy(*raddr, &remote, PR_NETADDR_SIZE(&remote)); *nd = accepted; return rv; } PR_Close(accepted); return rv; }
static ssize_t nss_recv(struct connectdata * conn, /* connection data */ int num, /* socketindex */ char *buf, /* store read data here */ size_t buffersize, /* max amount to read */ CURLcode *curlcode) { ssize_t nread; nread = PR_Recv(conn->ssl[num].handle, buf, (int)buffersize, 0, -1); if(nread < 0) { /* failed SSL read */ PRInt32 err = PR_GetError(); if(err == PR_WOULD_BLOCK_ERROR) *curlcode = CURLE_AGAIN; else { /* print the error number and error string */ const char *err_name = nss_error_to_name(err); infof(conn->data, "SSL read: errno %d (%s)\n", err, err_name); /* print a human-readable message describing the error if available */ nss_print_error_message(conn->data, err); *curlcode = (is_cc_error(err)) ? CURLE_SSL_CERTPROBLEM : CURLE_RECV_ERROR; } return -1; } return nread; }
static void ConnectingThread(void *arg) { PRInt32 nbytes; #ifdef SYMBIAN char buf[256]; #else char buf[1024]; #endif PRFileDesc *sock; PRNetAddr peer_addr, *addr; addr = (PRNetAddr*)arg; sock = PR_NewTCPSocket(); if (sock == NULL) { PL_FPrintError(err_out, "PR_NewTCPSocket (client) failed"); PR_ProcessExit(1); } if (PR_Connect(sock, addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { PL_FPrintError(err_out, "PR_Connect (client) failed"); PR_ProcessExit(1); } if (PR_GetPeerName(sock, &peer_addr) == PR_FAILURE) { PL_FPrintError(err_out, "PR_GetPeerName (client) failed"); PR_ProcessExit(1); } /* ** Then wait between the connection coming up and sending the expected ** data. At some point in time, the server should fail due to a timeou ** on the AcceptRead() operation, which according to the document is ** only due to the read() portion. */ PR_Sleep(write_dally); nbytes = PR_Send(sock, GET, sizeof(GET), 0, PR_INTERVAL_NO_TIMEOUT); if (nbytes == -1) PL_FPrintError(err_out, "PR_Send (client) failed"); nbytes = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT); if (nbytes == -1) PL_FPrintError(err_out, "PR_Recv (client) failed"); else { PR_fprintf(std_out, "PR_Recv (client) succeeded: %d bytes\n", nbytes); buf[sizeof(buf) - 1] = '\0'; PR_fprintf(std_out, "%s\n", buf); } if (PR_FAILURE == PR_Shutdown(sock, PR_SHUTDOWN_BOTH)) PL_FPrintError(err_out, "PR_Shutdown (client) failed"); if (PR_FAILURE == PR_Close(sock)) PL_FPrintError(err_out, "PR_Close (client) failed"); return; } /* ConnectingThread */
NSAPI_PUBLIC int net_read(SYS_NETFD fd, void *buf, int sz, int timeout) { int rv; rv = PR_Recv(fd, buf, sz, 0, net_nsapi_timeout_to_nspr_interval(timeout)); #ifdef XP_WIN32 if (rv < 0) { INTnet_cancelIO(fd); } #endif return rv; }
void TransportLayerDtls::PacketReceived(TransportLayer* layer, const unsigned char *data, size_t len) { CheckThread(); MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "PacketReceived(" << len << ")"); if (state_ != TS_CONNECTING && state_ != TS_OPEN) { MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Discarding packet in inappropriate state"); return; } nspr_io_adapter_->PacketReceived(data, len); // If we're still connecting, try to handshake if (state_ == TS_CONNECTING) { Handshake(); } // Now try a recv if we're open, since there might be data left if (state_ == TS_OPEN) { // nICEr uses a 9216 bytes buffer to allow support for jumbo frames unsigned char buf[9216]; int32_t rv; // One packet might contain several DTLS packets do { rv = PR_Recv(ssl_fd_, buf, sizeof(buf), 0, PR_INTERVAL_NO_WAIT); if (rv > 0) { // We have data MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Read " << rv << " bytes from NSS"); SignalPacketReceived(this, buf, rv); } else if (rv == 0) { TL_SET_STATE(TS_CLOSED); } else { int32_t err = PR_GetError(); if (err == PR_WOULD_BLOCK_ERROR) { // This gets ignored MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Receive would have blocked"); } else { MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "NSS Error " << err); TL_SET_STATE(TS_ERROR); } } } while (rv > 0); } }
/* * This function uses SSL_peek to determine connection status. * * Return codes: * 1 means the connection is still in place * 0 means the connection has been closed * -1 means the connection status is unknown */ int Curl_nss_check_cxn(struct connectdata *conn) { int rc; char buf; rc = PR_Recv(conn->ssl[FIRSTSOCKET].handle, (void *)&buf, 1, PR_MSG_PEEK, PR_SecondsToInterval(1)); if(rc > 0) return 1; /* connection still in place */ if(rc == 0) return 0; /* connection has been closed */ return -1; /* connection status unknown */ }
int main (int argc, char *argv[]) { if (argc != 3) { return 1; } PRFileDesc* socket = PR_NewTCPSocket(); PRNetAddr addr; initAddr(&addr, argv[1], atoi(argv[2])); PR_Connect(socket, &addr, PR_INTERVAL_NO_TIMEOUT); char* string = (char*) malloc(10*sizeof(char)); PR_Recv(socket, string, 10, 0, PR_INTERVAL_NO_TIMEOUT); string[10] = 0; printf("%s\n", string); PR_Close(socket); }
nsresult ReadRequest(Connection *aConn) { int32_t bytesRead = PR_Recv(aConn->mSocket, &aConn->mByte, 1, 0, PR_INTERVAL_NO_TIMEOUT); if (bytesRead < 0) { PrintPRError("PR_Recv failed"); return NS_ERROR_FAILURE; } else if (bytesRead == 0) { PR_SetError(PR_IO_ERROR, 0); PrintPRError("PR_Recv EOF in ReadRequest"); return NS_ERROR_FAILURE; } else { if (gDebugLevel >= DEBUG_VERBOSE) { fprintf(stderr, "read '0x%hhx'\n", aConn->mByte); } } return NS_OK; }
static void serve_client_read(void *arg) { Session *sp = (Session *) arg; int rem; int bytes; int offset; PRFileDesc *sockfd; char *buf; PRJob *jobp; PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT; sockfd = sp->iod.socket; buf = sp->in_buf->data; PR_ASSERT(sp->msg_num < num_tcp_mesgs_per_connection); PR_ASSERT(sp->bytes_read < sp->bytes); offset = sp->bytes_read; rem = sp->bytes - offset; bytes = PR_Recv(sockfd, buf + offset, rem, 0, timeout); if (bytes < 0) { return; } sp->bytes_read += bytes; sp->iod.timeout = PR_SecondsToInterval(60); if (sp->bytes_read < sp->bytes) { jobp = PR_QueueJob_Read(sp->tp, &sp->iod, serve_client_read, sp, PR_FALSE); PR_ASSERT(NULL != jobp); return; } PR_ASSERT(sp->bytes_read == sp->bytes); DPRINTF(("serve_client: read complete, msg(%d) \n", sp->msg_num)); sp->iod.timeout = PR_SecondsToInterval(60); jobp = PR_QueueJob_Write(sp->tp, &sp->iod, serve_client_write, sp, PR_FALSE); PR_ASSERT(NULL != jobp); return; }
PRBool RecvBuf::_getBytes(int size) { _curPos = 0; _curSize = PR_Recv((PRFileDesc*)_socket, _buf, _allocSize, 0, Engine::globaltimeout); if (_curSize <= 0) { #ifdef DEBUG printerror("PR_Recv"); #endif return PR_FALSE; }; Logger::logError(LOGTRACE, "RECV %s", _buf); return PR_TRUE; };
/* * readn * read data from sockfd into buf */ static PRInt32 readn(PRFileDesc *sockfd, char *buf, int len) { int rem; int bytes; int offset = 0; for (rem=len; rem; offset += bytes, rem -= bytes) { DPRINTF(("thread = 0x%lx: calling PR_Recv, bytes = %d\n", PR_GetCurrentThread(), rem)); bytes = PR_Recv(sockfd, buf + offset, rem, 0, PR_INTERVAL_NO_TIMEOUT); DPRINTF(("thread = 0x%lx: returning from PR_Recv, bytes = %d\n", PR_GetCurrentThread(), bytes)); if (bytes <= 0) return -1; } return len; }
void TransportLayerDtls::PacketReceived(TransportLayer* layer, const unsigned char *data, size_t len) { CheckThread(); MOZ_MTLOG(PR_LOG_DEBUG, LAYER_INFO << "PacketReceived(" << len << ")"); if (state_ != TS_CONNECTING && state_ != TS_OPEN) { MOZ_MTLOG(PR_LOG_DEBUG, LAYER_INFO << "Discarding packet in inappropriate state"); return; } nspr_io_adapter_->PacketReceived(data, len); // If we're still connecting, try to handshake if (state_ == TS_CONNECTING) { Handshake(); } // Now try a recv if we're open, since there might be data left if (state_ == TS_OPEN) { unsigned char buf[2000]; int32_t rv = PR_Recv(ssl_fd_, buf, sizeof(buf), 0, PR_INTERVAL_NO_WAIT); if (rv > 0) { // We have data MOZ_MTLOG(PR_LOG_DEBUG, LAYER_INFO << "Read " << rv << " bytes from NSS"); SignalPacketReceived(this, buf, rv); } else if (rv == 0) { SetState(TS_CLOSED); } else { int32_t err = PR_GetError(); if (err == PR_WOULD_BLOCK_ERROR) { // This gets ignored MOZ_MTLOG(PR_LOG_NOTICE, LAYER_INFO << "Would have blocked"); } else { MOZ_MTLOG(PR_LOG_NOTICE, LAYER_INFO << "NSS Error " << err); SetState(TS_ERROR); } } } }
struct wpabuf * tls_connection_decrypt(void *tls_ctx, struct tls_connection *conn, const struct wpabuf *in_data) { PRInt32 res; struct wpabuf *out; wpa_printf(MSG_DEBUG, "NSS: decrypt %d bytes", (int) wpabuf_len(in_data)); if (conn->pull_buf) { wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in " "pull_buf", __func__, (unsigned long) conn->pull_buf_len); os_free(conn->pull_buf); } conn->pull_buf = os_malloc(wpabuf_len(in_data)); if (conn->pull_buf == NULL) return NULL; os_memcpy(conn->pull_buf, wpabuf_head(in_data), wpabuf_len(in_data)); conn->pull_buf_offset = conn->pull_buf; conn->pull_buf_len = wpabuf_len(in_data); /* * Even though we try to disable TLS compression, it is possible that * this cannot be done with all TLS libraries. Add extra buffer space * to handle the possibility of the decrypted data being longer than * input data. */ out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); if (out == NULL) return NULL; res = PR_Recv(conn->fd, wpabuf_mhead(out), wpabuf_size(out), 0, 0); wpa_printf(MSG_DEBUG, "NSS: PR_Recv: %d", res); if (res < 0) { wpabuf_free(out); return NULL; } wpabuf_put(out, res); return out; }
static PRInt32 _udt_recv(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout) { uint32_t dummy_data; PRUdtSocketDesc* desc = (PRUdtSocketDesc*)(fd->secret); if (desc->sign_cnt != desc->rd_cnt) { PR_Recv(desc->sock_pair0, (char*)&dummy_data, sizeof(dummy_data), 0, 0); PR_AtomicIncrement(&desc->rd_cnt); } // peek is not supported in udt if(PR_MSG_PEEK & flags) return PR_WOULD_BLOCK_ERROR; int rc = udt_recv(desc->udtfd, (char*)buf, amount, 0); if(rc < 0) { int udterrcode = udt_getErrorCode(); if ((UDT_ERRECONNLOST == udterrcode) || (UDT_ERRENOCONN == udterrcode)) { PR_Close(desc->sock_pair1); //rc = 0; } } return rc; }
static void PR_CALLBACK Server(void *arg) { PRStatus rv; PRUint8 buffer[100]; PRFileDesc *service; PRUintn empty_flags = 0; PRIntn bytes_read, bytes_sent; PRFileDesc *stack = (PRFileDesc*)arg; PRNetAddr client_address; service = PR_Accept(stack, &client_address, PR_INTERVAL_NO_TIMEOUT); if (verbosity > quiet) PR_fprintf(logFile, "Server accepting connection\n"); do { bytes_read = PR_Recv( service, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT); if (0 != bytes_read) { if (verbosity > chatty) PR_fprintf(logFile, "Server receiving %d bytes\n", bytes_read); PR_ASSERT(bytes_read > 0); bytes_sent = PR_Send( service, buffer, bytes_read, empty_flags, PR_INTERVAL_NO_TIMEOUT); if (verbosity > chatty) PR_fprintf(logFile, "Server sending %d bytes\n", bytes_sent); PR_ASSERT(bytes_read == bytes_sent); } } while (0 != bytes_read); if (verbosity > quiet) PR_fprintf(logFile, "Server shutting down and closing stack\n"); rv = PR_Shutdown(service, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); } /* Server */
/* * If the read would block we return -1 and set 'wouldblock' to TRUE. * Otherwise we return the amount of data read. Other errors should return -1 * and set 'wouldblock' to FALSE. */ ssize_t Curl_nss_recv(struct connectdata * conn, /* connection data */ int num, /* socketindex */ char *buf, /* store read data here */ size_t buffersize, /* max amount to read */ bool * wouldblock) { ssize_t nread; nread = PR_Recv(conn->ssl[num].handle, buf, (int)buffersize, 0, -1); *wouldblock = FALSE; if(nread < 0) { /* failed SSL read */ PRInt32 err = PR_GetError(); if(err == PR_WOULD_BLOCK_ERROR) { *wouldblock = TRUE; return -1; /* basically EWOULDBLOCK */ } failf(conn->data, "SSL read: errno %d", err); return -1; } return nread; }
/* * _PR_EmulateAcceptRead * * Accept an incoming connection on sd, set *nd to point to the * newly accepted socket, read 'amount' bytes from the accepted * socket. * * buf is a buffer of length = (amount + sizeof(PRNetAddr)) * *raddr points to the PRNetAddr of the accepted connection upon * return * * return number of bytes read or -1 on error * */ PRInt32 _PR_EmulateAcceptRead(PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout) { PRInt32 rv; PRFileDesc *newsockfd; PRNetAddr remote; PRIntervalTime start, elapsed; if (PR_INTERVAL_NO_TIMEOUT != timeout) { start = PR_IntervalNow(); } if ((newsockfd = PR_Accept(sd, &remote, timeout)) == NULL) { return -1; } if (PR_INTERVAL_NO_TIMEOUT != timeout) { elapsed = (PRIntervalTime) (PR_IntervalNow() - start); if (elapsed > timeout) { PR_SetError(PR_IO_TIMEOUT_ERROR, 0); goto failed; } else { timeout = timeout - elapsed; } } rv = PR_Recv(newsockfd, buf, amount, 0, timeout); if (rv >= 0) { *nd = newsockfd; *raddr = (PRNetAddr *)((char *) buf + amount); memcpy(*raddr, &remote, PR_NETADDR_SIZE(&remote)); return rv; } failed: PR_Close(newsockfd); return -1; }
static PRInt32 _udt_read(PRFileDesc *fd, void *buf, PRInt32 amount) { UDTSOCKET s = get_socket_from_fd(fd); uint32_t dummy_data; int rc = 0; PRUdtSocketDesc* desc = (PRUdtSocketDesc*)(fd->secret); if (desc->sign_cnt != desc->rd_cnt) { PR_Recv(desc->sock_pair0, (char*)&dummy_data, sizeof(dummy_data), 0, 0); PR_AtomicIncrement(&desc->rd_cnt); } rc = udt_recv(s, (char*)buf, amount, 0); if(rc < 0) { int udterrcode = udt_getErrorCode(); if (UDT_ERRECONNLOST == udterrcode) { rc = 0; PR_Close(desc->sock_pair0); PR_Close(desc->sock_pair1); } else if (UDT_ERRENOCONN == udterrcode) { rc = 0; PR_Close(desc->sock_pair0); PR_Close(desc->sock_pair1); } } return rc; }
void ClientThreadFunc(void *unused) { PRNetAddr serverAddr; PRFileDesc *clientSocket; char *sendBuf; char *recvBuf; PRInt32 rv; PRInt32 bytesNeeded; sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char)); if (!sendBuf) if (debug_mode) printf("\tClient could not malloc space!?\n"); recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char)); if (!recvBuf) if (debug_mode) printf("\tClient could not malloc space!?\n"); memset(&serverAddr, 0, sizeof(PRNetAddr)); serverAddr.inet.family = PR_AF_INET; serverAddr.inet.port = PR_htons(PORT); serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); while(numRequests > 0) { if ( (numRequests % 10) == 0 ) if (debug_mode) printf("."); if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests); clientSocket = PR_NewTCPSocket(); if (!clientSocket) { if (debug_mode) printf("Client error creating socket: OS error %d\n", PR_GetOSError()); continue; } if (debug_mode) DPRINTF("\tClient connecting\n"); rv = PR_Connect(clientSocket, &serverAddr, PR_INTERVAL_NO_TIMEOUT); if (!clientSocket) { if (debug_mode) printf("\tClient error connecting\n"); continue; } if (debug_mode) DPRINTF("\tClient connected\n"); rv = PR_Send(clientSocket, sendBuf, _client_data, 0, PR_INTERVAL_NO_TIMEOUT); if (rv != _client_data) { if (debug_mode) printf("Client error sending data (%d)\n", rv); PR_Close(clientSocket); continue; } if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv); bytesNeeded = _server_data; while(bytesNeeded) { rv = PR_Recv(clientSocket, recvBuf, bytesNeeded, 0, PR_INTERVAL_NO_TIMEOUT); if (rv <= 0) { if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", rv, (_server_data - bytesNeeded), _server_data); break; } if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv); bytesNeeded -= rv; } PR_Close(clientSocket); PR_AtomicDecrement(&numRequests); } PR_EnterMonitor(clientMonitor); --numClients; PR_Notify(clientMonitor); PR_ExitMonitor(clientMonitor); PR_DELETE(sendBuf); PR_DELETE(recvBuf); }
void Resolver :: ar_receive() { char ar_rcvbuf[HFIXEDSZ + MAXPACKET]; HEADER* hptr = NULL; /* Name Server query header */ DNSSession* session = NULL; int rc = 0; datapacket* newpkt = NULL; unsigned int id = 0; if (ar_vc) rc = PR_Recv(afd, ar_rcvbuf, HFIXEDSZ+MAXPACKET, 0, PR_INTERVAL_NO_TIMEOUT); else rc = PR_Read(afd, ar_rcvbuf, HFIXEDSZ+MAXPACKET); ar_reinfo.re_replies++; /* Create a reslist_pkt_t to queue against the reslist */ newpkt = new datapacket(); PR_ASSERT(newpkt); newpkt->next = NULL; if (rc >0) { // packet received /* * Wakeup corresponding thread. */ hptr = (HEADER *)ar_rcvbuf; /* * convert things to be in the right order. */ id = ntohs(hptr->id); /* * response for an id which we have already received an answer for * just ignore this response. */ session = DNShash.lookup(id); if (!session) { delete(newpkt); /* Request no longer in queue, so just return. */ return; } newpkt->buflen = rc; memset(newpkt, 0, HFIXEDSZ + MAXPACKET); memcpy(newpkt, ar_rcvbuf, rc); } else { // no packet received newpkt->buflen = 0; } // Append new data packet to end of known data packets session->reslist_add_pkt(newpkt); session->setStatus(DNS_RCVD); // Wakeup corresponding thread. DNShash.remove(session); // remove this completed session from the hash table session->complete(); }
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())); }
static void PR_CALLBACK Clientel(void *arg) { PRStatus rv; PRFileDesc *xport; PRInt32 bytes, sampled; PRIntervalTime now, interval; PRBool do_display = PR_FALSE; Shared *shared = (Shared*)arg; char *buffer = (char*)PR_Malloc(buffer_size); PRNetAddr *server_address = &shared->server_address; PRIntervalTime connect_timeout = PR_SecondsToInterval(5); PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL); PR_fprintf(err, "Client connecting to "); (void)PrintAddress(server_address); do { xport = PR_Socket(domain, PR_SOCK_STREAM, protocol); if (NULL == xport) { PL_FPrintError(err, "PR_Socket"); return; } if (xport_buffer != -1) { PRSocketOptionData data; data.option = PR_SockOpt_RecvBufferSize; data.value.recv_buffer_size = (PRSize)xport_buffer; rv = PR_SetSocketOption(xport, &data); if (PR_FAILURE == rv) PL_FPrintError(err, "PR_SetSocketOption - ignored"); data.option = PR_SockOpt_SendBufferSize; data.value.send_buffer_size = (PRSize)xport_buffer; rv = PR_SetSocketOption(xport, &data); if (PR_FAILURE == rv) PL_FPrintError(err, "PR_SetSocketOption - ignored"); } rv = PR_Connect(xport, server_address, connect_timeout); if (PR_FAILURE == rv) { PL_FPrintError(err, "PR_Connect"); if (PR_IO_TIMEOUT_ERROR != PR_GetError()) PR_Sleep(connect_timeout); PR_Close(xport); /* delete it and start over */ } } while (PR_FAILURE == rv); do { bytes = PR_Recv( xport, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT); PR_Lock(shared->ml); now = PR_IntervalNow(); shared->sampled += bytes; interval = now - shared->timein; if (interval > sampling_interval) { sampled = shared->sampled; shared->timein = now; shared->sampled = 0; do_display = PR_TRUE; } PR_Unlock(shared->ml); if (do_display) { PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval); PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate); do_display = PR_FALSE; } } while (bytes > 0); } /* Clientel */
static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server) { PRStatus drv, rv; char buffer[1024]; PRFileDesc *file = NULL; PRThread * me = PR_GetCurrentThread(); PRInt32 bytes, descbytes, netbytes, filebytes = 0; CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t); PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_SERVER_TIMEOUT); TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\tProcessRequest(0x%p): receiving desciptor\n", me)); bytes = PR_Recv( fd, descriptor, sizeof(*descriptor), RECV_FLAGS, timeout); if (-1 == bytes) { rv = PR_FAILURE; if (Aborted(rv)) goto exit; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\tProcessRequest(0x%p): receive timeout\n", me)); } goto exit; } if (0 == bytes) { rv = PR_FAILURE; TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\tProcessRequest(0x%p): unexpected end of file\n", me)); goto exit; } descbytes = PR_ntohl(descriptor->size); TEST_ASSERT(sizeof(*descriptor) == bytes); TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n", me, descbytes, descriptor->filename)); file = PR_Open( descriptor->filename, (PR_CREATE_FILE | PR_WRONLY), 0666); if (NULL == file) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\tProcessRequest(0x%p): open file timeout\n", me)); goto aborted; } } TEST_ASSERT(NULL != file); filebytes = 0; while (filebytes < descbytes) { netbytes = sizeof(buffer); if ((descbytes - filebytes) < netbytes) netbytes = descbytes - filebytes; TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes)); bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout); if (-1 == bytes) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): receive data timeout\n", me)); goto aborted; } /* * XXX: I got (PR_CONNECT_RESET_ERROR, ERROR_NETNAME_DELETED) * on NT here. This is equivalent to ECONNRESET on Unix. * -wtc */ TEST_LOG( cltsrv_log_file, TEST_LOG_WARNING, ("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n", me, PR_GetError(), PR_GetOSError())); goto aborted; } if(0 == bytes) { TEST_LOG( cltsrv_log_file, TEST_LOG_WARNING, ("\t\tProcessRequest(0x%p): unexpected end of stream\n", me)); rv = PR_FAILURE; goto aborted; } filebytes += bytes; netbytes = bytes; /* The byte count for PR_Write should be positive */ MY_ASSERT(netbytes > 0); TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes)); bytes = PR_Write(file, buffer, netbytes); if (netbytes != bytes) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): write file timeout\n", me)); goto aborted; } } TEST_ASSERT(bytes > 0); } PR_Lock(server->ml); server->operations += 1; server->bytesTransferred += filebytes; PR_Unlock(server->ml); rv = PR_Close(file); if (Aborted(rv)) goto aborted; TEST_ASSERT(PR_SUCCESS == rv); file = NULL; TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->filename)); file = PR_Open(descriptor->filename, PR_RDONLY, 0); if (NULL == file) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): open file timeout\n", PR_GetCurrentThread())); goto aborted; } TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n", me, PR_GetError(), PR_GetOSError())); goto aborted; } TEST_ASSERT(NULL != file); netbytes = 0; while (netbytes < descbytes) { filebytes = sizeof(buffer); if ((descbytes - netbytes) < filebytes) filebytes = descbytes - netbytes; TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes)); bytes = PR_Read(file, buffer, filebytes); if (filebytes != bytes) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): read file timeout\n", me)); else TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): other file error (%d, %d)\n", me, PR_GetError(), PR_GetOSError())); goto aborted; } TEST_ASSERT(bytes > 0); netbytes += bytes; filebytes = bytes; TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes)); bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout); if (filebytes != bytes) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): send data timeout\n", me)); goto aborted; } break; } TEST_ASSERT(bytes > 0); } PR_Lock(server->ml); server->bytesTransferred += filebytes; PR_Unlock(server->ml); rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH); if (Aborted(rv)) goto aborted; rv = PR_Close(file); if (Aborted(rv)) goto aborted; TEST_ASSERT(PR_SUCCESS == rv); file = NULL; aborted: PR_ClearInterrupt(); if (NULL != file) PR_Close(file); drv = PR_Delete(descriptor->filename); TEST_ASSERT(PR_SUCCESS == drv); exit: TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\t\tProcessRequest(0x%p): Finished\n", me)); PR_DELETE(descriptor); #if defined(WIN95) PR_Sleep(PR_MillisecondsToInterval(200)); /* lth. see note [1] */ #endif return rv; } /* ProcessRequest */
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; }