/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Netscape Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* A test for nonblocking connect. Functions tested include PR_Connect,
* PR_Poll, and PR_GetConnectStatus.
*
* The test should be invoked with a host name, for example:
* nbconn www.netscape.com
* It will do a nonblocking connect to port 80 (HTTP) on that host,
* and when connected, issue the "GET /" HTTP command.
*
* You should run this test in three ways:
* 1. To a known web site, such as www.netscape.com. The HTML of the
* top-level page at the web site should be printed.
* 2. To a machine not running a web server at port 80. This test should
* fail. Ideally the error code should be PR_CONNECT_REFUSED_ERROR.
* But it is possible to return PR_UNKNOWN_ERROR on certain platforms.
* 3. To an unreachable machine, for example, a machine that is off line.
* The test should fail after the connect times out. Ideally the
* error code should be PR_IO_TIMEOUT_ERROR, but it is possible to
* return PR_UNKNOWN_ERROR on certain platforms.
*/
#include "nspr.h"
#include "plgetopt.h"
#include <stdio.h>
#ifdef XP_MAC
extern void SetupMacPrintfLog(char *logFile);
#endif
typedef struct Server_Param {
} Server_Param;
int _debug_on;
static PRIntn connection_success_test();
static PRIntn connection_failure_test();
{
#ifdef XP_MAC
int index;
#endif
/*
* -d debug mode
*/
{
if (PL_OPT_BAD == os) continue;
{
case 0: /* debug mode */
break;
case 'd': /* debug mode */
_debug_on = 1;
break;
default:
break;
}
}
#ifdef XP_MAC
SetupMacPrintfLog("nbconn.log");
if (index == 3)
#endif
#ifndef XP_MAC
if (hostname)
default_case = 0;
else
default_case = 1;
#endif
if (default_case) {
/*
* In the default case the following tests are executed:
* 1. successful connection: a server thread accepts a connection
* from the main thread
* 2. unsuccessful connection: the main thread tries to connect to a
* non-existent port and expects to get an error
*/
if (rv == 0)
return rv;
} else {
exit(1);
} else {
}
sock = PR_NewTCPSocket();
printf( "Connect in progress\n");
}
#ifndef XP_MAC
#else
#endif
if (n == -1) {
printf( "PR_Poll failed\n");
exit(1);
}
printf( "PR_Poll returns %d\n", n);
printf( "PR_POLL_READ\n");
}
printf( "PR_POLL_WRITE\n");
}
printf( "PR_POLL_EXCEPT\n");
}
printf( "PR_POLL_ERR\n");
}
printf( "PR_POLL_NVAL\n");
}
printf("PR_GetConnectStatus: connect succeeded\n");
/* Mac and Win16 have trouble printing to the console. */
while (1) {
printf( "poll returns %d\n", n);
printf( "read returns %d\n", n);
if (n <= 0) {
break;
}
}
#endif
} else {
if (PR_GetError() == PR_IN_PROGRESS_ERROR) {
printf( "PR_GetConnectStatus: connect still in progress\n");
exit(1);
}
printf( "PR_GetConnectStatus: connect failed: (%ld, %ld)\n",
PR_GetError(), PR_GetOSError());
}
#ifdef XP_MAC
} /* end of for loop */
#endif
printf( "PASS\n");
return 0;
}
}
/*
* TCP Server
* Server Thread
* Accept a connection from the client and write some data
*/
static void PR_CALLBACK
{
PR_INTERVAL_NO_TIMEOUT)) == NULL) {
PR_GetError(), PR_GetOSError());
return;
}
bytes_read = 0;
while (bytes_read != DATA_BUF_SIZE) {
if (rv < 0) {
PR_GetError(), PR_GetOSError());
return;
}
bytes_read += rv;
}
if (rv < 0) {
PR_GetError(), PR_GetOSError());
return;
}
}
/*
* test for successful connection using a non-blocking socket
*/
static PRIntn
{
/*
* Create a tcp socket
*/
goto def_exit;
}
/*
* try a few times to bind server's address, if addresses are in
* use
*/
i = 0;
if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
if (i++ < SERVER_MAX_BIND_COUNT)
continue;
}
PR_GetError(), PR_GetOSError());
goto def_exit;
}
PR_GetError(), PR_GetOSError());
goto def_exit;
}
PR_GetError(), PR_GetOSError());
goto def_exit;
}
goto def_exit;
}
if (rv == PR_FAILURE) {
if (PR_GetError() == PR_IN_PROGRESS_ERROR) {
DPRINTF(("Connect in progress\n"));
} else {
PR_GetError(), PR_GetOSError());
goto def_exit;
}
}
/*
* Now create a thread to accept a connection
*/
PR_GetError(), PR_GetOSError());
goto def_exit;
}
#ifndef XP_MAC
#else
#endif
if (n == -1) {
PR_GetError(), PR_GetOSError());
goto def_exit;
}
DPRINTF(("Connection successful\n"));
/*
* Write some data, read it back and check data integrity to
* make sure the connection is good
*/
bytes_sent = 0;
while (bytes_sent != DATA_BUF_SIZE) {
if (rv < 0) {
PR_GetError(), PR_GetOSError());
goto def_exit;
}
if (rv < 0) {
PR_GetError(), PR_GetOSError());
goto def_exit;
}
bytes_sent += rv;
}
bytes_read = 0;
while (bytes_read != DATA_BUF_SIZE) {
if (rv < 0) {
PR_GetError(), PR_GetOSError());
goto def_exit;
}
if (rv < 0) {
PR_GetError(), PR_GetOSError());
goto def_exit;
}
bytes_read += rv;
}
/*
* verify the data read
*/
goto def_exit;
}
DPRINTF(("Data integrity verified\n"));
} else {
PR_GetError(), PR_GetOSError());
failed_already = 1;
goto def_exit;
}
if (thr) {
}
if (sockfd) {
}
if (conn_fd) {
}
if (failed_already)
return 1;
else
return 0;
}
/*
* test for connection to a non-existent port using a non-blocking socket
*/
static PRIntn
{
/*
* Create a tcp socket
*/
goto def_exit;
}
/*
* try a few times to bind server's address, if addresses are in
* use
*/
i = 0;
if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
if (i++ < SERVER_MAX_BIND_COUNT)
continue;
}
PR_GetError(), PR_GetOSError());
goto def_exit;
}
PR_GetError(), PR_GetOSError());
goto def_exit;
}
#ifdef AIX
/*
*/
#endif
goto def_exit;
}
if (rv == PR_FAILURE) {
DPRINTF(("PR_Connect to a non-listen port failed: (%d, %d)\n",
PR_GetError(), PR_GetOSError()));
} else {
goto def_exit;
}
#ifndef XP_MAC
#else
#endif
if (n == -1) {
PR_GetError(), PR_GetOSError());
goto def_exit;
}
failed_already = 1;
goto def_exit;
}
rv = PR_GetError();
if (sockfd) {
}
if (conn_fd) {
}
if (failed_already)
return 1;
else
return 0;
}