mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-16 04:20:32 +01:00
601 lines
20 KiB
C
601 lines
20 KiB
C
|
/*
|
||
|
* test_socket.c
|
||
|
*
|
||
|
* Test Socket Type
|
||
|
*
|
||
|
* Copyright 2004-2005 Sun Microsystems, Inc. All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions are met:
|
||
|
*
|
||
|
* 1. Redistribution of source code must retain the above copyright notice,
|
||
|
* this list of conditions and the following disclaimer.
|
||
|
*
|
||
|
* 2. Redistribution in binary form must reproduce the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer in the
|
||
|
* documentation and/or other materials provided with the distribution.
|
||
|
*
|
||
|
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
|
||
|
* be used to endorse or promote products derived from this software without
|
||
|
* specific prior written permission.
|
||
|
*
|
||
|
* This software is provided "AS IS," without a warranty of any kind. ALL
|
||
|
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
|
||
|
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
|
||
|
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
|
||
|
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
|
||
|
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
|
||
|
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
|
||
|
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
|
||
|
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
|
||
|
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
|
||
|
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||
|
*
|
||
|
* You acknowledge that this software is not designed or intended for use in
|
||
|
* the design, construction, operation or maintenance of any nuclear facility.
|
||
|
*/
|
||
|
|
||
|
#include "testutil.h"
|
||
|
#include "testutil_nss.h"
|
||
|
#include "pkix_pl_common.h"
|
||
|
|
||
|
#define LDAP_PORT 389
|
||
|
|
||
|
static void *plContext = NULL;
|
||
|
|
||
|
typedef enum {
|
||
|
SERVER_LISTENING,
|
||
|
SERVER_RECV1,
|
||
|
SERVER_POLL1,
|
||
|
SERVER_SEND2,
|
||
|
SERVER_POLL2,
|
||
|
SERVER_RECV3,
|
||
|
SERVER_POLL3,
|
||
|
SERVER_SEND4,
|
||
|
SERVER_POLL4,
|
||
|
SERVER_DONE,
|
||
|
SERVER_FAILED
|
||
|
} SERVER_STATE;
|
||
|
|
||
|
typedef enum {
|
||
|
CLIENT_WAITFORCONNECT,
|
||
|
CLIENT_SEND1,
|
||
|
CLIENT_POLL1,
|
||
|
CLIENT_RECV2,
|
||
|
CLIENT_POLL2,
|
||
|
CLIENT_SEND3,
|
||
|
CLIENT_POLL3,
|
||
|
CLIENT_RECV4,
|
||
|
CLIENT_POLL4,
|
||
|
CLIENT_DONE,
|
||
|
CLIENT_FAILED
|
||
|
} CLIENT_STATE;
|
||
|
|
||
|
SERVER_STATE serverState;
|
||
|
CLIENT_STATE clientState;
|
||
|
PKIX_PL_Socket *sSock = NULL;
|
||
|
PKIX_PL_Socket *cSock = NULL;
|
||
|
PKIX_PL_Socket *rendezvousSock = NULL;
|
||
|
PKIX_PL_Socket_Callback *sCallbackList;
|
||
|
PKIX_PL_Socket_Callback *cCallbackList;
|
||
|
PKIX_PL_Socket_Callback *rvCallbackList;
|
||
|
PRNetAddr serverNetAddr;
|
||
|
PRNetAddr clientNetAddr;
|
||
|
PRIntn backlog = 0;
|
||
|
PRIntervalTime timeout = 0;
|
||
|
char *sendBuf1 = "Hello, world!";
|
||
|
char *sendBuf2 = "Ack";
|
||
|
char *sendBuf3 = "What do you mean, \"Ack\"?";
|
||
|
char *sendBuf4 = "What do you mean, \"What do you mean, \'Ack\'?\"?";
|
||
|
char rcvBuf1[100];
|
||
|
char rcvBuf2[100];
|
||
|
|
||
|
static
|
||
|
void printUsage(char *testname)
|
||
|
{
|
||
|
char *fmt = "USAGE: %s [-arenas] server:port\n";
|
||
|
printf(fmt, testname);
|
||
|
}
|
||
|
|
||
|
/* Functional tests for Socket public functions */
|
||
|
static
|
||
|
void do_other_work(void)
|
||
|
{ /* while waiting for nonblocking I/O to complete */
|
||
|
(void) PR_Sleep(2*60);
|
||
|
}
|
||
|
|
||
|
static
|
||
|
PKIX_Boolean server()
|
||
|
{
|
||
|
PKIX_Int32 bytesRead = 0;
|
||
|
PKIX_Int32 bytesWritten = 0;
|
||
|
PKIX_Boolean keepGoing = PKIX_FALSE;
|
||
|
|
||
|
PKIX_TEST_STD_VARS();
|
||
|
|
||
|
switch (serverState) {
|
||
|
case SERVER_LISTENING:
|
||
|
subTest("SERVER_LISTENING");
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(sCallbackList->acceptCallback
|
||
|
(sSock, &rendezvousSock, plContext));
|
||
|
if (rendezvousSock) {
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_GetCallbackList
|
||
|
(rendezvousSock, &rvCallbackList, plContext));
|
||
|
|
||
|
serverState = SERVER_RECV1;
|
||
|
}
|
||
|
break;
|
||
|
case SERVER_RECV1:
|
||
|
subTest("SERVER_RECV1");
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->recvCallback
|
||
|
(rendezvousSock,
|
||
|
rcvBuf1,
|
||
|
sizeof(rcvBuf1),
|
||
|
&bytesRead,
|
||
|
plContext));
|
||
|
|
||
|
if (bytesRead > 0) {
|
||
|
/* confirm that rcvBuf1 = sendBuf1 */
|
||
|
if ((bytesRead != (PRInt32)PL_strlen(sendBuf1) + 1) ||
|
||
|
(strncmp(sendBuf1, rcvBuf1, bytesRead) != 0)) {
|
||
|
testError("Receive buffer mismatch\n");
|
||
|
}
|
||
|
|
||
|
serverState = SERVER_SEND2;
|
||
|
keepGoing = PKIX_TRUE;
|
||
|
} else {
|
||
|
serverState = SERVER_POLL1;
|
||
|
}
|
||
|
break;
|
||
|
case SERVER_POLL1:
|
||
|
subTest("SERVER_POLL1");
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->pollCallback
|
||
|
(rendezvousSock, NULL, &bytesRead, plContext));
|
||
|
|
||
|
if (bytesRead > 0) {
|
||
|
/* confirm that rcvBuf1 = sendBuf1 */
|
||
|
if ((bytesRead != (PRInt32)PL_strlen(sendBuf1) + 1) ||
|
||
|
(strncmp(sendBuf1, rcvBuf1, bytesRead) != 0)) {
|
||
|
testError("Receive buffer mismatch\n");
|
||
|
}
|
||
|
|
||
|
serverState = SERVER_SEND2;
|
||
|
keepGoing = PKIX_TRUE;
|
||
|
}
|
||
|
break;
|
||
|
case SERVER_SEND2:
|
||
|
subTest("SERVER_SEND2");
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->sendCallback
|
||
|
(rendezvousSock,
|
||
|
sendBuf2,
|
||
|
strlen(sendBuf2) + 1,
|
||
|
&bytesWritten,
|
||
|
plContext));
|
||
|
if (bytesWritten > 0) {
|
||
|
serverState = SERVER_RECV3;
|
||
|
} else {
|
||
|
serverState = SERVER_POLL2;
|
||
|
}
|
||
|
break;
|
||
|
case SERVER_POLL2:
|
||
|
subTest("SERVER_POLL2");
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->pollCallback
|
||
|
(rendezvousSock, &bytesWritten, NULL, plContext));
|
||
|
if (bytesWritten > 0) {
|
||
|
serverState = SERVER_RECV3;
|
||
|
}
|
||
|
break;
|
||
|
case SERVER_RECV3:
|
||
|
subTest("SERVER_RECV3");
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->recvCallback
|
||
|
(rendezvousSock,
|
||
|
rcvBuf1,
|
||
|
sizeof(rcvBuf1),
|
||
|
&bytesRead,
|
||
|
plContext));
|
||
|
|
||
|
if (bytesRead > 0) {
|
||
|
serverState = SERVER_SEND4;
|
||
|
keepGoing = PKIX_TRUE;
|
||
|
} else {
|
||
|
serverState = SERVER_POLL3;
|
||
|
}
|
||
|
break;
|
||
|
case SERVER_POLL3:
|
||
|
subTest("SERVER_POLL3");
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->pollCallback
|
||
|
(rendezvousSock, NULL, &bytesRead, plContext));
|
||
|
if (bytesRead > 0) {
|
||
|
serverState = SERVER_SEND4;
|
||
|
keepGoing = PKIX_TRUE;
|
||
|
}
|
||
|
break;
|
||
|
case SERVER_SEND4:
|
||
|
subTest("SERVER_SEND4");
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->sendCallback
|
||
|
(rendezvousSock,
|
||
|
sendBuf4,
|
||
|
strlen(sendBuf4) + 1,
|
||
|
&bytesWritten,
|
||
|
plContext));
|
||
|
|
||
|
if (bytesWritten > 0) {
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->shutdownCallback
|
||
|
(rendezvousSock, plContext));
|
||
|
PKIX_TEST_DECREF_BC(sSock);
|
||
|
PKIX_TEST_DECREF_BC(rendezvousSock);
|
||
|
serverState = SERVER_DONE;
|
||
|
} else {
|
||
|
serverState = SERVER_POLL4;
|
||
|
}
|
||
|
break;
|
||
|
case SERVER_POLL4:
|
||
|
subTest("SERVER_POLL4");
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->pollCallback
|
||
|
(rendezvousSock, &bytesWritten, NULL, plContext));
|
||
|
if (bytesWritten > 0) {
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->shutdownCallback
|
||
|
(rendezvousSock, plContext));
|
||
|
PKIX_TEST_DECREF_BC(sSock);
|
||
|
PKIX_TEST_DECREF_BC(rendezvousSock);
|
||
|
serverState = SERVER_DONE;
|
||
|
}
|
||
|
break;
|
||
|
case SERVER_DONE:
|
||
|
default:
|
||
|
subTest("SERVER_DONE");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
cleanup:
|
||
|
|
||
|
PKIX_TEST_RETURN();
|
||
|
|
||
|
return (keepGoing);
|
||
|
}
|
||
|
|
||
|
static
|
||
|
PKIX_Boolean client()
|
||
|
{
|
||
|
PKIX_Boolean keepGoing = PKIX_FALSE;
|
||
|
PKIX_Int32 bytesRead = 0;
|
||
|
PKIX_Int32 bytesWritten = 0;
|
||
|
PRErrorCode cStat = 0;
|
||
|
|
||
|
/* At 2 seconds each cycle, this should suffice! */
|
||
|
PKIX_UInt32 giveUpCount = 10;
|
||
|
|
||
|
PKIX_TEST_STD_VARS();
|
||
|
|
||
|
switch (clientState) {
|
||
|
case CLIENT_WAITFORCONNECT:
|
||
|
subTest("CLIENT_WAITFORCONNECT");
|
||
|
clientState = CLIENT_FAILED;
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->connectcontinueCallback
|
||
|
(cSock, &cStat, plContext));
|
||
|
if (cStat == 0) {
|
||
|
clientState = CLIENT_SEND1;
|
||
|
keepGoing = PKIX_TRUE;
|
||
|
} else {
|
||
|
clientState = CLIENT_WAITFORCONNECT;
|
||
|
if (--giveUpCount == 0) {
|
||
|
testError("Client unable to connect");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case CLIENT_SEND1:
|
||
|
subTest("CLIENT_SEND1");
|
||
|
clientState = CLIENT_FAILED;
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->sendCallback
|
||
|
(cSock,
|
||
|
sendBuf1,
|
||
|
strlen(sendBuf1) + 1,
|
||
|
&bytesWritten,
|
||
|
plContext));
|
||
|
if (bytesWritten > 0) {
|
||
|
clientState = CLIENT_RECV2;
|
||
|
} else {
|
||
|
clientState = CLIENT_POLL1;
|
||
|
}
|
||
|
break;
|
||
|
case CLIENT_POLL1:
|
||
|
subTest("CLIENT_POLL1");
|
||
|
clientState = CLIENT_FAILED;
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->pollCallback
|
||
|
(cSock, &bytesWritten, NULL, plContext));
|
||
|
if (bytesWritten > 0) {
|
||
|
clientState = CLIENT_RECV2;
|
||
|
} else {
|
||
|
clientState = CLIENT_POLL1;
|
||
|
}
|
||
|
break;
|
||
|
case CLIENT_RECV2:
|
||
|
subTest("CLIENT_RECV2");
|
||
|
clientState = CLIENT_FAILED;
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->recvCallback
|
||
|
(cSock,
|
||
|
rcvBuf2,
|
||
|
sizeof(rcvBuf2),
|
||
|
&bytesRead,
|
||
|
plContext));
|
||
|
|
||
|
if (bytesRead > 0) {
|
||
|
/* confirm that rcvBuf2 = sendBuf2 */
|
||
|
if ((bytesRead != (PRInt32)PL_strlen(sendBuf2) + 1) ||
|
||
|
(strncmp(sendBuf2, rcvBuf2, bytesRead) != 0)) {
|
||
|
testError("Receive buffer mismatch\n");
|
||
|
}
|
||
|
clientState = CLIENT_SEND3;
|
||
|
keepGoing = PKIX_TRUE;
|
||
|
} else {
|
||
|
clientState = CLIENT_POLL2;
|
||
|
}
|
||
|
break;
|
||
|
case CLIENT_POLL2:
|
||
|
subTest("CLIENT_POLL2");
|
||
|
clientState = CLIENT_FAILED;
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->pollCallback
|
||
|
(cSock, NULL, &bytesRead, plContext));
|
||
|
if (bytesRead > 0) {
|
||
|
/* confirm that rcvBuf2 = sendBuf2 */
|
||
|
if ((bytesRead != (PRInt32)PL_strlen(sendBuf2) + 1) ||
|
||
|
(strncmp(sendBuf2, rcvBuf2, bytesRead) != 0)) {
|
||
|
testError("Receive buffer mismatch\n");
|
||
|
}
|
||
|
clientState = CLIENT_SEND3;
|
||
|
} else {
|
||
|
clientState = CLIENT_POLL2;
|
||
|
}
|
||
|
break;
|
||
|
case CLIENT_SEND3:
|
||
|
subTest("CLIENT_SEND3");
|
||
|
clientState = CLIENT_FAILED;
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->sendCallback
|
||
|
(cSock,
|
||
|
sendBuf3,
|
||
|
strlen(sendBuf3) + 1,
|
||
|
&bytesWritten,
|
||
|
plContext));
|
||
|
|
||
|
if (bytesWritten > 0) {
|
||
|
clientState = CLIENT_RECV4;
|
||
|
} else {
|
||
|
clientState = CLIENT_POLL3;
|
||
|
}
|
||
|
break;
|
||
|
case CLIENT_POLL3:
|
||
|
subTest("CLIENT_POLL3");
|
||
|
clientState = CLIENT_FAILED;
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->pollCallback
|
||
|
(cSock, &bytesWritten, NULL, plContext));
|
||
|
if (bytesWritten > 0) {
|
||
|
clientState = CLIENT_RECV4;
|
||
|
} else {
|
||
|
clientState = CLIENT_POLL3;
|
||
|
}
|
||
|
break;
|
||
|
case CLIENT_RECV4:
|
||
|
subTest("CLIENT_RECV4");
|
||
|
clientState = CLIENT_FAILED;
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->recvCallback
|
||
|
(cSock,
|
||
|
rcvBuf2,
|
||
|
sizeof(rcvBuf2),
|
||
|
&bytesRead,
|
||
|
plContext));
|
||
|
|
||
|
if (bytesRead > 0) {
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->shutdownCallback
|
||
|
(cSock, plContext));
|
||
|
PKIX_TEST_DECREF_BC(cSock);
|
||
|
clientState = CLIENT_DONE;
|
||
|
} else {
|
||
|
clientState = CLIENT_POLL4;
|
||
|
}
|
||
|
break;
|
||
|
case CLIENT_POLL4:
|
||
|
subTest("CLIENT_POLL4");
|
||
|
clientState = CLIENT_FAILED;
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->pollCallback
|
||
|
(cSock, NULL, &bytesRead, plContext));
|
||
|
if (bytesRead > 0) {
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->shutdownCallback
|
||
|
(cSock, plContext));
|
||
|
PKIX_TEST_DECREF_BC(cSock);
|
||
|
clientState = CLIENT_DONE;
|
||
|
} else {
|
||
|
clientState = CLIENT_POLL4;
|
||
|
}
|
||
|
break;
|
||
|
case CLIENT_DONE:
|
||
|
default:
|
||
|
subTest("CLIENT_DONE");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
cleanup:
|
||
|
|
||
|
PKIX_TEST_RETURN();
|
||
|
|
||
|
return (keepGoing);
|
||
|
}
|
||
|
|
||
|
static
|
||
|
void dispatcher()
|
||
|
{
|
||
|
PKIX_Boolean keepGoing = PKIX_FALSE;
|
||
|
|
||
|
PKIX_TEST_STD_VARS();
|
||
|
|
||
|
do {
|
||
|
if (serverState < SERVER_DONE) {
|
||
|
do {
|
||
|
keepGoing = server();
|
||
|
} while (keepGoing == PKIX_TRUE);
|
||
|
}
|
||
|
if (clientState < CLIENT_DONE) {
|
||
|
do {
|
||
|
keepGoing = client();
|
||
|
} while (keepGoing == PKIX_TRUE);
|
||
|
}
|
||
|
do_other_work();
|
||
|
|
||
|
} while ((serverState < SERVER_DONE) || (clientState < CLIENT_DONE));
|
||
|
|
||
|
PKIX_TEST_RETURN();
|
||
|
}
|
||
|
|
||
|
int test_socket(int argc, char *argv[])
|
||
|
{
|
||
|
|
||
|
int j = 0;
|
||
|
PKIX_UInt32 actualMinorVersion;
|
||
|
char buf[PR_NETDB_BUF_SIZE];
|
||
|
char *serverName = NULL;
|
||
|
char *sepPtr = NULL;
|
||
|
PRHostEnt hostent;
|
||
|
PRUint16 portNum = 0;
|
||
|
PRStatus prstatus = PR_FAILURE;
|
||
|
PRErrorCode cStat = 0;
|
||
|
void *ipaddr = NULL;
|
||
|
PKIX_Error *bindError = NULL;
|
||
|
PRIntn hostenum;
|
||
|
|
||
|
PKIX_TEST_STD_VARS();
|
||
|
|
||
|
startTests("Socket");
|
||
|
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(
|
||
|
PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
|
||
|
|
||
|
if (argc != (j + 2)) {
|
||
|
printUsage(argv[0]);
|
||
|
pkixTestErrorMsg = "Missing command line argument.";
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
serverName = argv[j + 1];
|
||
|
|
||
|
subTest("Using pkix_pl_Socket_CreateByName");
|
||
|
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_CreateByName
|
||
|
(PKIX_TRUE, timeout, serverName, &cStat, &sSock, plContext));
|
||
|
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_GetCallbackList
|
||
|
(sSock, &sCallbackList, plContext));
|
||
|
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(sCallbackList->listenCallback
|
||
|
(sSock, backlog, plContext));
|
||
|
|
||
|
serverState = SERVER_LISTENING;
|
||
|
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_CreateByName
|
||
|
(PKIX_FALSE, timeout, serverName, &cStat, &cSock, plContext));
|
||
|
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_GetCallbackList
|
||
|
(cSock, &cCallbackList, plContext));
|
||
|
|
||
|
if ((timeout == 0) && (cStat == PR_IN_PROGRESS_ERROR)) {
|
||
|
clientState = CLIENT_WAITFORCONNECT;
|
||
|
} else {
|
||
|
clientState = CLIENT_SEND1;
|
||
|
}
|
||
|
|
||
|
dispatcher();
|
||
|
|
||
|
subTest("Using pkix_pl_Socket_Create");
|
||
|
|
||
|
sepPtr = strchr(serverName, ':');
|
||
|
/* First strip off the portnum, if present, from the end of the name */
|
||
|
if (sepPtr) {
|
||
|
*sepPtr++ = '\0';
|
||
|
portNum = (PRUint16)atoi(sepPtr);
|
||
|
} else {
|
||
|
portNum = (PRUint16)LDAP_PORT;
|
||
|
}
|
||
|
/*
|
||
|
* The hostname may be a fully-qualified name. Just
|
||
|
* use the leftmost component in our lookup.
|
||
|
*/
|
||
|
sepPtr = strchr(serverName, '.');
|
||
|
if (sepPtr) {
|
||
|
*sepPtr++ = '\0';
|
||
|
}
|
||
|
prstatus = PR_GetHostByName(serverName, buf, sizeof(buf), &hostent);
|
||
|
|
||
|
if ((prstatus != PR_SUCCESS) || (hostent.h_length != 4)) {
|
||
|
printUsage(argv[0]);
|
||
|
pkixTestErrorMsg =
|
||
|
"PR_GetHostByName rejects command line argument.";
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
serverNetAddr.inet.family = PR_AF_INET;
|
||
|
serverNetAddr.inet.port = PR_htons(portNum);
|
||
|
serverNetAddr.inet.ip = PR_INADDR_ANY;
|
||
|
|
||
|
hostenum = PR_EnumerateHostEnt(0, &hostent, portNum, &clientNetAddr);
|
||
|
if (hostenum == -1) {
|
||
|
pkixTestErrorMsg =
|
||
|
"PR_EnumerateHostEnt failed.";
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
backlog = 5;
|
||
|
|
||
|
/* timeout = PR_INTERVAL_NO_TIMEOUT; */
|
||
|
/* timeout = 0; nonblocking */
|
||
|
timeout = 0;
|
||
|
|
||
|
bindError = pkix_pl_Socket_Create
|
||
|
(PKIX_TRUE, timeout, &serverNetAddr, &cStat, &sSock, plContext);
|
||
|
|
||
|
/* If PR_Bind can't handle INADDR_ANY, try it with the real name */
|
||
|
if (bindError) {
|
||
|
PKIX_TEST_DECREF_BC(bindError);
|
||
|
serverNetAddr.inet.ip = PR_htonl(*(PRUint32 *)ipaddr);
|
||
|
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_Create
|
||
|
(PKIX_TRUE,
|
||
|
timeout,
|
||
|
&serverNetAddr,
|
||
|
&cStat,
|
||
|
&sSock,
|
||
|
plContext));
|
||
|
}
|
||
|
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_GetCallbackList
|
||
|
(sSock, &sCallbackList, plContext));
|
||
|
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(sCallbackList->listenCallback
|
||
|
(sSock, backlog, plContext));
|
||
|
|
||
|
serverState = SERVER_LISTENING;
|
||
|
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_Create
|
||
|
(PKIX_FALSE, timeout, &clientNetAddr, &cStat, &cSock, plContext));
|
||
|
|
||
|
PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_GetCallbackList
|
||
|
(cSock, &cCallbackList, plContext));
|
||
|
|
||
|
if ((timeout == 0) && (cStat == PR_IN_PROGRESS_ERROR)) {
|
||
|
clientState = CLIENT_WAITFORCONNECT;
|
||
|
} else {
|
||
|
clientState = CLIENT_SEND1;
|
||
|
}
|
||
|
|
||
|
dispatcher();
|
||
|
|
||
|
cleanup:
|
||
|
|
||
|
PKIX_TEST_DECREF_AC(sSock);
|
||
|
PKIX_TEST_DECREF_AC(cSock);
|
||
|
PKIX_TEST_DECREF_AC(rendezvousSock);
|
||
|
|
||
|
PKIX_TEST_RETURN();
|
||
|
|
||
|
endTests("Socket");
|
||
|
|
||
|
return (0);
|
||
|
}
|