/* -*- 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
 * http://www.mozilla.org/MPL/
 *
 * 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>
#include <string.h>

#define SERVER_MAX_BIND_COUNT        100
#define DATA_BUF_SIZE        		 256
#define TCP_SERVER_PORT            10000
#define TCP_UNUSED_PORT            211

typedef struct Server_Param {
    PRFileDesc *sp_fd;		/* server port */
} Server_Param;
static void PR_CALLBACK TCP_Server(void *arg);

int _debug_on;
#define DPRINTF(arg) if (_debug_on) printf arg

static PRIntn connection_success_test();
static PRIntn connection_failure_test();

int main(int argc, char **argv)
{
    PRHostEnt he;
    char buf[1024];
    PRNetAddr addr;
    PRPollDesc pd;
    PRStatus rv;
    PRSocketOptionData optData;
	const char *hostname = NULL;
    PRIntn default_case, n, bytes_read, bytes_sent;
	PRInt32 failed_already = 0;

    /*
     * -d           debug mode
     */

    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 0:  /* debug mode */
            hostname = opt->value;
            break;
        case 'd':  /* debug mode */
            _debug_on = 1;
            break;
        default:
            break;
        }
    }
    PL_DestroyOptState(opt);

    PR_STDIO_INIT();
    if (hostname)
		default_case = 0;
	else
		default_case = 1;

	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
		 *	   nonexistent port and expects to get an error
		 */
		rv = connection_success_test();
		if (rv == 0)
			rv = connection_failure_test();
		return rv;
	} else {
    	PRFileDesc *sock;

		if (PR_GetHostByName(argv[1], buf, sizeof(buf), &he) == PR_FAILURE) {
			printf( "Unknown host: %s\n", argv[1]);
			exit(1);
		} else {
			printf( "host: %s\n", buf);
		}
		PR_EnumerateHostEnt(0, &he, 80, &addr);

		sock = PR_NewTCPSocket();
		optData.option = PR_SockOpt_Nonblocking;
		optData.value.non_blocking = PR_TRUE;
		PR_SetSocketOption(sock, &optData);
		rv = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
		if (rv == PR_FAILURE && PR_GetError() == PR_IN_PROGRESS_ERROR) {
			printf( "Connect in progress\n");
		}

		pd.fd = sock;
		pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
		n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
		if (n == -1) {
			printf( "PR_Poll failed\n");
			exit(1);
		}
		printf( "PR_Poll returns %d\n", n);
		if (pd.out_flags & PR_POLL_READ) {
			printf( "PR_POLL_READ\n");
		}
		if (pd.out_flags & PR_POLL_WRITE) {
			printf( "PR_POLL_WRITE\n");
		}
		if (pd.out_flags & PR_POLL_EXCEPT) {
			printf( "PR_POLL_EXCEPT\n");
		}
		if (pd.out_flags & PR_POLL_ERR) {
			printf( "PR_POLL_ERR\n");
		}
		if (pd.out_flags & PR_POLL_NVAL) {
			printf( "PR_POLL_NVAL\n");
		}

		if (PR_GetConnectStatus(&pd) == PR_SUCCESS) {
			printf("PR_GetConnectStatus: connect succeeded\n");
			PR_Write(sock, "GET /\r\n\r\n", 9);
			PR_Shutdown(sock, PR_SHUTDOWN_SEND);
			pd.in_flags = PR_POLL_READ;
			while (1) {
				n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
				printf( "poll returns %d\n", n);
				n = PR_Read(sock, buf, sizeof(buf));
				printf( "read returns %d\n", n);
				if (n <= 0) {
					break;
				}
				PR_Write(PR_STDOUT, buf, n);
			}
		} 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());
		}
		PR_Close(sock);
    	printf( "PASS\n");
    	return 0;

	}
}


/*
 * TCP Server
 *    Server Thread
 *    Accept a connection from the client and write some data
 */
static void PR_CALLBACK
TCP_Server(void *arg)
{
    Server_Param *sp = (Server_Param *) arg;
    PRFileDesc *sockfd, *newsockfd;
	char data_buf[DATA_BUF_SIZE];
    PRIntn rv, bytes_read;

	sockfd = sp->sp_fd;
	if ((newsockfd = PR_Accept(sockfd, NULL,
		PR_INTERVAL_NO_TIMEOUT)) == NULL) {
		fprintf(stderr,"ERROR - PR_Accept failed: (%d,%d)\n",
										PR_GetError(), PR_GetOSError());
		return;
	}
	bytes_read = 0;
	while (bytes_read != DATA_BUF_SIZE) {
		rv = PR_Read(newsockfd, data_buf + bytes_read ,
									DATA_BUF_SIZE - bytes_read);
		if (rv < 0) {
			fprintf(stderr,"Error - PR_Read failed: (%d, %d)\n",
							PR_GetError(), PR_GetOSError());
			PR_Close(newsockfd);
			return;
		}
		PR_ASSERT(rv != 0);
		bytes_read += rv;
	}
	DPRINTF(("Bytes read from client - %d\n",bytes_read));
	rv = PR_Write(newsockfd, data_buf,DATA_BUF_SIZE);
	if (rv < 0) {
		fprintf(stderr,"Error - PR_Write failed: (%d, %d)\n",
						PR_GetError(), PR_GetOSError());
		PR_Close(newsockfd);
		return;
	}
	PR_ASSERT(rv == DATA_BUF_SIZE);
	DPRINTF(("Bytes written to client - %d\n",rv));
	PR_Close(newsockfd);
}


/*
 * test for successful connection using a non-blocking socket
 */
static PRIntn
connection_success_test()
{
	PRFileDesc *sockfd = NULL, *conn_fd = NULL;
	PRNetAddr netaddr;
	PRInt32 i, rv;
    PRPollDesc pd;
    PRSocketOptionData optData;
	PRThread *thr = NULL;
	Server_Param sp;
	char send_buf[DATA_BUF_SIZE], recv_buf[DATA_BUF_SIZE];
    PRIntn default_case, n, bytes_read, bytes_sent;
    PRIntn failed_already = 0;

	/*
	 * Create a tcp socket
	 */
	if ((sockfd = PR_NewTCPSocket()) == NULL) {
		fprintf(stderr,"Error - PR_NewTCPSocket failed\n");
		failed_already=1;
		goto def_exit;
	}
	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,"ERROR - PR_Bind failed: (%d,%d)\n",
									PR_GetError(), PR_GetOSError());
		failed_already=1;
		goto def_exit;
	}

	if (PR_Listen(sockfd, 32) < 0) {
		fprintf(stderr,"ERROR - PR_Listen failed: (%d,%d)\n",
									PR_GetError(), PR_GetOSError());
		failed_already=1;
		goto def_exit;
	}

	if (PR_GetSockName(sockfd, &netaddr) < 0) {
		fprintf(stderr,"ERROR - PR_GetSockName failed: (%d,%d)\n",
									PR_GetError(), PR_GetOSError());
		failed_already=1;
		goto def_exit;
	}
	if ((conn_fd = PR_NewTCPSocket()) == NULL) {
		fprintf(stderr,"Error - PR_NewTCPSocket failed\n");
		failed_already=1;
		goto def_exit;
	}
	optData.option = PR_SockOpt_Nonblocking;
	optData.value.non_blocking = PR_TRUE;
	PR_SetSocketOption(conn_fd, &optData);
	rv = PR_Connect(conn_fd, &netaddr, PR_INTERVAL_NO_TIMEOUT);
	if (rv == PR_FAILURE) {
		if (PR_GetError() == PR_IN_PROGRESS_ERROR) {
			DPRINTF(("Connect in progress\n"));
		} else  {
			fprintf(stderr,"Error - PR_Connect failed: (%d, %d)\n",
									PR_GetError(), PR_GetOSError());
			failed_already=1;
			goto def_exit;
		}
	}
	/*
	 * Now create a thread to accept a connection
	 */
	sp.sp_fd = sockfd;
	thr = PR_CreateThread(PR_USER_THREAD, TCP_Server, (void *)&sp, 
			PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
	if (thr == NULL) {
		fprintf(stderr,"Error - PR_CreateThread failed: (%d,%d)\n",
									PR_GetError(), PR_GetOSError());
		failed_already=1;
		goto def_exit;
	}
	DPRINTF(("Created TCP_Server thread [0x%x]\n",thr));
	pd.fd = conn_fd;
	pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
	n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
	if (n == -1) {
		fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n",
									PR_GetError(), PR_GetOSError());
		failed_already=1;
		goto def_exit;
	}
	if (PR_GetConnectStatus(&pd) == PR_SUCCESS) {
		PRInt32 rv;

		DPRINTF(("Connection successful\n"));

		/*
		 * Write some data, read it back and check data integrity to
		 * make sure the connection is good
		 */
		pd.in_flags = PR_POLL_WRITE;
		bytes_sent = 0;
		memset(send_buf, 'a', DATA_BUF_SIZE);
		while (bytes_sent != DATA_BUF_SIZE) {
			rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
			if (rv < 0) {
				fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n",
								PR_GetError(), PR_GetOSError());
				failed_already=1;
				goto def_exit;
			}
			PR_ASSERT((rv == 1) && (pd.out_flags == PR_POLL_WRITE));
			rv = PR_Write(conn_fd, send_buf + bytes_sent,
										DATA_BUF_SIZE - bytes_sent);
			if (rv < 0) {
				fprintf(stderr,"Error - PR_Write failed: (%d, %d)\n",
								PR_GetError(), PR_GetOSError());
				failed_already=1;
				goto def_exit;
			}
			PR_ASSERT(rv > 0);
			bytes_sent += rv;
		}
		DPRINTF(("Bytes written to server - %d\n",bytes_sent));
		PR_Shutdown(conn_fd, PR_SHUTDOWN_SEND);
		pd.in_flags = PR_POLL_READ;
		bytes_read = 0;
		memset(recv_buf, 0, DATA_BUF_SIZE);
		while (bytes_read != DATA_BUF_SIZE) {
			rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
			if (rv < 0) {
				fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n",
								PR_GetError(), PR_GetOSError());
				failed_already=1;
				goto def_exit;
			}
			PR_ASSERT((rv == 1) && (pd.out_flags == PR_POLL_READ));
			rv = PR_Read(conn_fd, recv_buf + bytes_read ,
										DATA_BUF_SIZE - bytes_read);
			if (rv < 0) {
				fprintf(stderr,"Error - PR_Read failed: (%d, %d)\n",
								PR_GetError(), PR_GetOSError());
				failed_already=1;
				goto def_exit;
			}
			PR_ASSERT(rv != 0);
			bytes_read += rv;
		}
		DPRINTF(("Bytes read from server - %d\n",bytes_read));
		/*
		 * verify the data read
		 */
		if (memcmp(send_buf, recv_buf, DATA_BUF_SIZE) != 0) {
			fprintf(stderr,"ERROR - data corruption\n");
			failed_already=1;
			goto def_exit;
		}
		DPRINTF(("Data integrity verified\n"));
	} else {
		fprintf(stderr,"PR_GetConnectStatus: connect failed: (%ld, %ld)\n",
				PR_GetError(), PR_GetOSError());
		failed_already = 1;
		goto def_exit;
	}
def_exit:
	if (thr) {
		PR_JoinThread(thr);
		thr = NULL;
	}
	if (sockfd) {
		PR_Close(sockfd);
		sockfd = NULL;
	}
	if (conn_fd) {
		PR_Close(conn_fd);
		conn_fd = NULL;
	}
	if (failed_already)
		return 1;
	else
		return 0;

}

/*
 * test for connection to a nonexistent port using a non-blocking socket
 */
static PRIntn
connection_failure_test()
{
	PRFileDesc *sockfd = NULL, *conn_fd = NULL;
	PRNetAddr netaddr;
	PRInt32 i, rv;
    PRPollDesc pd;
    PRSocketOptionData optData;
    PRIntn n, failed_already = 0;

	/*
	 * Create a tcp socket
	 */
	if ((sockfd = PR_NewTCPSocket()) == NULL) {
		fprintf(stderr,"Error - PR_NewTCPSocket failed\n");
		failed_already=1;
		goto def_exit;
	}
	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,"ERROR - PR_Bind failed: (%d,%d)\n",
									PR_GetError(), PR_GetOSError());
		failed_already=1;
		goto def_exit;
	}

	if (PR_GetSockName(sockfd, &netaddr) < 0) {
		fprintf(stderr,"ERROR - PR_GetSockName failed: (%d,%d)\n",
									PR_GetError(), PR_GetOSError());
		failed_already=1;
		goto def_exit;
	}
#ifdef AIX
	/*
	 * On AIX, set to unused/reserved port
	 */
	netaddr.inet.port = PR_htons(TCP_UNUSED_PORT);
#endif
	if ((conn_fd = PR_NewTCPSocket()) == NULL) {
		fprintf(stderr,"Error - PR_NewTCPSocket failed\n");
		failed_already=1;
		goto def_exit;
	}
	optData.option = PR_SockOpt_Nonblocking;
	optData.value.non_blocking = PR_TRUE;
	PR_SetSocketOption(conn_fd, &optData);
	rv = PR_Connect(conn_fd, &netaddr, PR_INTERVAL_NO_TIMEOUT);
	if (rv == PR_FAILURE) {
		DPRINTF(("PR_Connect to a non-listen port failed: (%d, %d)\n",
									PR_GetError(), PR_GetOSError()));
	} else {
		PR_ASSERT(rv == PR_SUCCESS);
		fprintf(stderr,"Error - PR_Connect succeeded, expected to fail\n");
		failed_already=1;
		goto def_exit;
	}
	pd.fd = conn_fd;
	pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
	n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
	if (n == -1) {
		fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n",
									PR_GetError(), PR_GetOSError());
		failed_already=1;
		goto def_exit;
	}
	if (PR_GetConnectStatus(&pd) == PR_SUCCESS) {
		PRInt32 rv;
		fprintf(stderr,"PR_GetConnectStatus succeeded, expected to fail\n");
		failed_already = 1;
		goto def_exit;
	}
	rv = PR_GetError();
	DPRINTF(("Connection failed, successfully with PR_Error %d\n",rv));
def_exit:
	if (sockfd) {
		PR_Close(sockfd);
		sockfd = NULL;
	}
	if (conn_fd) {
		PR_Close(conn_fd);
		conn_fd = NULL;
	}
	if (failed_already)
		return 1;
	else
		return 0;

}
