Skip to content

Commit

Permalink
Merge pull request #5066 from caohaley/connectaccept
Browse files Browse the repository at this point in the history
  • Loading branch information
rwy7 authored May 26, 2020
2 parents 957228c + 0f47287 commit f50097e
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 26 deletions.
118 changes: 108 additions & 10 deletions fvtest/porttest/omrsockTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,18 @@
* @return 0 on success, return an error otherwise.
*/
int32_t
start_server(struct OMRPortLibrary *portLibrary, const char *addrStr, const char *port, int32_t family, omrsock_socket_t *serverSocket, omrsock_sockaddr_t serverAddr)
start_server(struct OMRPortLibrary *portLibrary, int32_t family, int32_t socktype, omrsock_socket_t *serverSocket, omrsock_sockaddr_t serverSockAddr)
{
return OMRPORT_ERROR_NOTEXIST;
OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());

EXPECT_EQ(OMRPORTLIB->sock_socket(OMRPORTLIB, serverSocket, family, socktype, OMRSOCK_IPPROTO_DEFAULT), 0);
EXPECT_EQ(OMRPORTLIB->sock_bind(OMRPORTLIB, *serverSocket, serverSockAddr), 0);

if (OMRSOCK_STREAM == socktype) {
EXPECT_EQ(OMRPORTLIB->sock_listen(OMRPORTLIB, *serverSocket, 10), 0);
}

return 0;
}

/**
Expand All @@ -59,9 +68,37 @@ start_server(struct OMRPortLibrary *portLibrary, const char *addrStr, const char
* @return 0 on success, return an error otherwise.
*/
int32_t
connect_client_to_server(struct OMRPortLibrary *portLibrary, const char *addrStr, const char *port, int32_t family, omrsock_socket_t *sessionClientSocket, omrsock_sockaddr_t sessionClientAddr)
connect_client_to_server(struct OMRPortLibrary *portLibrary, const char *addrStr, const char *port, int32_t family, int32_t socktype, omrsock_socket_t *clientSocket, omrsock_sockaddr_t clientSockAddr, omrsock_sockaddr_t serverSockAddr)
{
return OMRPORT_ERROR_NOTEXIST;
OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());

omrsock_addrinfo_t hints = NULL;
OMRAddrInfoNode result;
uint32_t length = 0;
int32_t resultFamily;
int32_t resultSocktype;
int32_t resultProtocol;

EXPECT_EQ(OMRPORTLIB->sock_getaddrinfo_create_hints(OMRPORTLIB, &hints, family, socktype, OMRSOCK_IPPROTO_DEFAULT, 0), 0);
EXPECT_EQ(OMRPORTLIB->sock_getaddrinfo(OMRPORTLIB, addrStr, port, hints, &result), 0);
EXPECT_EQ(OMRPORTLIB->sock_addrinfo_length(OMRPORTLIB, &result, &length), 0);
EXPECT_NE(length, 0);

/* Create a socket with results. */
for (uint32_t i = 0; i < length; i++) {
EXPECT_EQ(OMRPORTLIB->sock_addrinfo_family(OMRPORTLIB, &result, i, &resultFamily), 0);
EXPECT_EQ(OMRPORTLIB->sock_addrinfo_socktype(OMRPORTLIB, &result, i, &resultSocktype), 0);
EXPECT_EQ(OMRPORTLIB->sock_addrinfo_protocol(OMRPORTLIB, &result, i, &resultProtocol), 0);

if(0 == OMRPORTLIB->sock_socket(OMRPORTLIB, clientSocket, resultFamily, resultSocktype, resultProtocol)) {
EXPECT_NE(clientSocket, (void *)NULL);
EXPECT_EQ(OMRPORTLIB->sock_addrinfo_address(OMRPORTLIB, &result, i, clientSockAddr), 0);
break;
}
}
EXPECT_EQ(OMRPORTLIB->sock_connect(OMRPORTLIB, *clientSocket, serverSockAddr), 0);

return 0;
}

/**
Expand Down Expand Up @@ -358,7 +395,6 @@ TEST(PortSockTest, create_dotted_decimal_IPv4_socket_address)
EXPECT_EQ(OMRPORTLIB->sock_bind(OMRPORTLIB, socket, &sockAddr), 0);
EXPECT_EQ(OMRPORTLIB->sock_listen(OMRPORTLIB, socket, 10), 0);
EXPECT_EQ(OMRPORTLIB->sock_close(OMRPORTLIB, &socket), 0);

}

/**
Expand Down Expand Up @@ -437,21 +473,83 @@ TEST(PortSockTest, create_IPv4_mapped_IPv6_Socket_Address)
}

/**
* Test functions to set up a connection by using two sockets, which talk to each other.
* Test functions to set up a stream connection by using two sockets, which talk to each other.
*
* First, the server starts and listens for connections. Then, the
* client starts and sends a request to connect to the server. The messages are
* sent both ways, and it is checked if they were sent correctly.
*
* Address families tested include IPv4 and IPv6 (if supported). Socket types
* tested include stream and datagram.
* Address families tested include IPv4 and socket types tested is stream.
*
* @note Errors such as failed function calls, failure to create server and/or client, wrong
* message sent/received, will be reported.
*/
TEST(PortSockTest, two_socket_communication)
TEST(PortSockTest, two_socket_stream_communication)
{
/* Unimplemented. */
OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());

OMRSockAddrStorage serverStreamSockAddr;
omrsock_socket_t serverStreamSocket = NULL;
uint16_t port = 4930;
uint8_t serverAddr[4];

/* To Create a Server Socket and Address */
uint32_t inaddrAny = OMRPORTLIB->sock_htonl(OMRPORTLIB, OMRSOCK_INADDR_ANY);
memcpy(serverAddr, &inaddrAny, 4);
EXPECT_EQ(OMRPORTLIB->sock_sockaddr_init(OMRPORTLIB, &serverStreamSockAddr, OMRSOCK_AF_INET, serverAddr, OMRPORTLIB->sock_htons(OMRPORTLIB, port)), 0);
EXPECT_EQ(start_server(OMRPORTLIB, OMRSOCK_AF_INET, OMRSOCK_STREAM, &serverStreamSocket, &serverStreamSockAddr), 0);

/* To Create a Client Socket and Address */
OMRSockAddrStorage clientStreamSockAddr;
omrsock_socket_t clientStreamSocket = NULL;
EXPECT_EQ(connect_client_to_server(OMRPORTLIB, (char *)"localhost", NULL, OMRSOCK_AF_INET, OMRSOCK_STREAM, &clientStreamSocket, &clientStreamSockAddr, &serverStreamSockAddr), 0);

/* Accept Connection */
OMRSockAddrStorage connectedClientStreamSockAddr;
omrsock_socket_t connectedClientStreamSocket = NULL;
EXPECT_EQ(OMRPORTLIB->sock_accept(OMRPORTLIB, serverStreamSocket, &connectedClientStreamSockAddr, &connectedClientStreamSocket), 0);

EXPECT_EQ(OMRPORTLIB->sock_close(OMRPORTLIB, &connectedClientStreamSocket), 0);
EXPECT_EQ(OMRPORTLIB->sock_close(OMRPORTLIB, &clientStreamSocket), 0);
EXPECT_EQ(OMRPORTLIB->sock_close(OMRPORTLIB, &serverStreamSocket), 0);
}

/**
* Test functions to set up a datagram connection by using two sockets, which talk to each other.
*
* First, the server is set up, and then, the client is set up sends a request to
* connect to the server (this is optional). The messages are sent both ways, and
* it is checked if they were sent correctly.
*
* Address families tested include IPv4 in this test case. Socket types
* tested is datagram.
*
* @note Errors such as failed function calls, failure to create server and/or client, wrong
* message sent/received, will be reported.
*/
TEST(PortSockTest, two_socket_datagram_communication)
{
OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());

OMRSockAddrStorage serverSockAddr;
omrsock_socket_t serverSocket = NULL;
uint16_t port = 4930;
uint8_t serverAddr[4];

/* To Create a Server Socket and Address */
uint32_t inaddrAny = OMRPORTLIB->sock_htonl(OMRPORTLIB, OMRSOCK_INADDR_ANY);
memcpy(serverAddr, &inaddrAny, 4);
EXPECT_EQ(OMRPORTLIB->sock_sockaddr_init(OMRPORTLIB, &serverSockAddr, OMRSOCK_AF_INET, serverAddr, OMRPORTLIB->sock_htons(OMRPORTLIB, port)), 0);
/* Datagram server sockets does not need to listen and accept */
EXPECT_EQ(start_server(OMRPORTLIB, OMRSOCK_AF_INET, OMRSOCK_DGRAM, &serverSocket, &serverSockAddr), 0);

OMRSockAddrStorage clientSockAddr;
omrsock_socket_t clientSocket = NULL;
/* Connect is optional for datagram clients */
EXPECT_EQ(connect_client_to_server(OMRPORTLIB, (char *)"localhost", NULL, OMRSOCK_AF_INET, OMRSOCK_DGRAM, &clientSocket, &clientSockAddr, &serverSockAddr), 0);

EXPECT_EQ(OMRPORTLIB->sock_close(OMRPORTLIB, &clientSocket), 0);
EXPECT_EQ(OMRPORTLIB->sock_close(OMRPORTLIB, &serverSocket), 0);
}

#endif /* defined(OMR_PORT_SOCKET_SUPPORT) */
4 changes: 2 additions & 2 deletions include_core/omrport.h
Original file line number Diff line number Diff line change
Expand Up @@ -2159,7 +2159,7 @@ typedef struct OMRPortLibrary {
/** see @ref omrsock.c::omrsock_htonl "omrsock_htonl"*/
uint32_t (*sock_htonl)(struct OMRPortLibrary *portLibrary, uint32_t val) ;
/** see @ref omrsock.c::omrsock_inet_pton "omrsock_inet_pton"*/
int32_t (*sock_inet_pton)(struct OMRPortLibrary *portLibrary, int32_t addrFamily, const char *addr, uint8_t *addrNetworkOrder) ;
int32_t (*sock_inet_pton)(struct OMRPortLibrary *portLibrary, int32_t addrFamily, const char *addr, uint8_t *result) ;
#endif /* defined(OMR_PORT_SOCKET_SUPPORT) */
#if defined(OMR_OPT_CUDA)
/** CUDA configuration data */
Expand Down Expand Up @@ -2630,7 +2630,7 @@ extern J9_CFUNC int32_t omrport_getVersion(struct OMRPortLibrary *portLibrary);
#define omrsock_shutdown() privateOmrPortLibrary->sock_shutdown(privateOmrPortLibrary)
#define omrsock_htons(param1) privateOmrPortLibrary->sock_htons(privateOmrPortLibrary, (param1))
#define omrsock_htonl(param1) privateOmrPortLibrary->sock_htonl(privateOmrPortLibrary, (param1))
#define omrsock_inet_pton(param1) privateOmrPortLibrary->sock_inet_pton(privateOmrPortLibrary, (param1))
#define omrsock_inet_pton(param1,param2,param3) privateOmrPortLibrary->sock_inet_pton(privateOmrPortLibrary, (param1), (param2), (param3))
#endif /* defined(OMR_PORT_SOCKET_SUPPORT) */

#if defined(OMR_OPT_CUDA)
Expand Down
9 changes: 6 additions & 3 deletions include_core/omrporterror.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,9 +327,12 @@
#define OMRPORT_ERROR_SOCK_ADDRINFO_FAILED (OMRPORT_ERROR_SOCK_BASE - 2)
#define OMRPORT_ERROR_SOCK_SOCKET_CREATION_FAILED (OMRPORT_ERROR_SOCK_BASE - 3)
#define OMRPORT_ERROR_SOCK_SOCKET_CLOSE_FAILED (OMRPORT_ERROR_SOCK_BASE - 4)
#define OMRPORT_ERROR_SOCK_INET_PTON_FAILED (OMRPORT_ERROR_SOCK_BASE - 5)
#define OMRPORT_ERROR_SOCK_BIND_FAILED (OMRPORT_ERROR_SOCK_BASE - 6)
#define OMRPORT_ERROR_SOCK_LISTEN_FAILED (OMRPORT_ERROR_SOCK_BASE - 7)
#define OMRPORT_ERROR_SOCK_INVALID_ADDRESS (OMRPORT_ERROR_SOCK_BASE - 5)
#define OMRPORT_ERROR_SOCK_UNSUPPORTED_AF (OMRPORT_ERROR_SOCK_BASE - 6)
#define OMRPORT_ERROR_SOCK_BIND_FAILED (OMRPORT_ERROR_SOCK_BASE - 7)
#define OMRPORT_ERROR_SOCK_LISTEN_FAILED (OMRPORT_ERROR_SOCK_BASE - 8)
#define OMRPORT_ERROR_SOCK_CONNECT_FAILED (OMRPORT_ERROR_SOCK_BASE - 9)
#define OMRPORT_ERROR_SOCK_ACCEPT_FAILED (OMRPORT_ERROR_SOCK_BASE - 10)
/**
* @}
*/
Expand Down
4 changes: 2 additions & 2 deletions port/common/omrsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -507,12 +507,12 @@ omrsock_htonl(struct OMRPortLibrary *portLibrary, uint32_t val)
* @param[in] portLibrary The port library.
* @param[in] addrFamily The address family.
* @param[in] addr The address string to be converted.
* @param[out] addrNetworkOrder The address in network order.
* @param[out] result The address in network order.
*
* @return 0, if no errors occurred, otherwise return an error.
*/
int32_t
omrsock_inet_pton(struct OMRPortLibrary *portLibrary, int32_t addrFamily, const char *addr, uint8_t *addrNetworkOrder)
omrsock_inet_pton(struct OMRPortLibrary *portLibrary, int32_t addrFamily, const char *addr, uint8_t *result)
{
return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM;
}
Expand Down
2 changes: 1 addition & 1 deletion port/omrportpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ omrsock_htons(struct OMRPortLibrary *portLibrary, uint16_t val);
extern J9_CFUNC uint32_t
omrsock_htonl(struct OMRPortLibrary *portLibrary, uint32_t val);
extern J9_CFUNC int32_t
omrsock_inet_pton(struct OMRPortLibrary *portLibrary, int32_t addrFamily, const char *addr, uint8_t *addrNetworkOrder);
omrsock_inet_pton(struct OMRPortLibrary *portLibrary, int32_t addrFamily, const char *addr, uint8_t *result);
#endif /* defined(OMR_PORT_SOCKET_SUPPORT) */

/* J9SourceJ9Str*/
Expand Down
78 changes: 71 additions & 7 deletions port/unix/omrsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
#include "omrporterror.h"
#include "omrsockptb.h"

#if defined(J9ZOS390) && !defined(OMR_EBCDIC)
#include "atoe.h"
#endif /* defined(J9ZOS390) && !defined(OMR_EBCDIC) */

/* Internal: OMRSOCK user interface constants TO OS dependent constants mapping. */

/**
Expand Down Expand Up @@ -490,13 +494,57 @@ omrsock_listen(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, int32_
int32_t
omrsock_connect(struct OMRPortLibrary *portLibrary, omrsock_socket_t sock, omrsock_sockaddr_t addr)
{
return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM;
socklen_t addrLength;

if (NULL == addr || NULL == sock) {
return OMRPORT_ERROR_INVALID_ARGUMENTS;
}

if (OS_SOCK_AF_INET == addr->data.ss_family) {
addrLength = sizeof(omr_os_sockaddr_in);
}
else {
addrLength = sizeof(omr_os_sockaddr_in6);
}

if (connect(sock->data, (omr_os_sockaddr *)&addr->data, addrLength) < 0) {
portLibrary->error_set_last_error(portLibrary, errno, OMRPORT_ERROR_SOCK_CONNECT_FAILED);
return OMRPORT_ERROR_SOCK_CONNECT_FAILED;
}
return 0;
}

int32_t
omrsock_accept(struct OMRPortLibrary *portLibrary, omrsock_socket_t serverSock, omrsock_sockaddr_t addrHandle, omrsock_socket_t *sockHandle)
{
return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM;
int32_t connSocketDescriptor;

#if defined(OMR_OS_ZOS)
int32_t addrLength = sizeof(omr_os_sockaddr_storage);
#else
socklen_t addrLength = sizeof(omr_os_sockaddr_storage);
#endif

if (NULL == serverSock || NULL == addrHandle) {
return OMRPORT_ERROR_INVALID_ARGUMENTS;
}

*sockHandle = NULL;

connSocketDescriptor = accept(serverSock->data, (omr_os_sockaddr *)&addrHandle->data, &addrLength);
if (connSocketDescriptor < 0) {
portLibrary->error_set_last_error(portLibrary, errno, OMRPORT_ERROR_SOCK_ACCEPT_FAILED);
return OMRPORT_ERROR_SOCK_ACCEPT_FAILED;
}

*sockHandle = (omrsock_socket_t)portLibrary->mem_allocate_memory(portLibrary, sizeof(struct OMRSocket), OMR_GET_CALLSITE(), OMRMEM_CATEGORY_PORT_LIBRARY);
if (*sockHandle == NULL) {
close(connSocketDescriptor);
return OMRPORT_ERROR_SOCK_SYSTEM_FULL;
}

(*sockHandle)->data = connSocketDescriptor;
return 0;
}

int32_t
Expand Down Expand Up @@ -558,16 +606,32 @@ omrsock_htonl(struct OMRPortLibrary *portLibrary, uint32_t val)
}

int32_t
omrsock_inet_pton(struct OMRPortLibrary *portLibrary, int32_t addrFamily, const char *addr, uint8_t *addrNetworkOrder)
omrsock_inet_pton(struct OMRPortLibrary *portLibrary, int32_t addrFamily, const char *addr, uint8_t *result)
{
if (NULL == addrNetworkOrder) {
int32_t rc;
#if defined(J9ZOS390) && !defined(OMR_EBCDIC)
char *addrA2e;
#endif /* defined(J9ZOS390) && !defined(OMR_EBCDIC) */

if (NULL == result) {
return OMRPORT_ERROR_INVALID_ARGUMENTS;
}

if (1 != inet_pton(get_os_family(addrFamily), addr, addrNetworkOrder)) {
return OMRPORT_ERROR_SOCK_INET_PTON_FAILED;
}
#if defined(J9ZOS390) && !defined(OMR_EBCDIC)
addrA2e = a2e(addr, strlen(addr));
rc = inet_pton(get_os_family(addrFamily), addrA2e, (void *)result);
free(addrA2e);
#else /* defined(J9ZOS390) && !defined(OMR_EBCDIC) */
rc = inet_pton(get_os_family(addrFamily), addr, (void *)result);
#endif /* defined(J9ZOS390) && !defined(OMR_EBCDIC) */

if (rc == 0) {
portLibrary->error_set_last_error(portLibrary, 0, OMRPORT_ERROR_SOCK_INVALID_ADDRESS);
return OMRPORT_ERROR_SOCK_INVALID_ADDRESS;
} else if (rc == -1) {
portLibrary->error_set_last_error(portLibrary, errno, OMRPORT_ERROR_SOCK_UNSUPPORTED_AF);
return OMRPORT_ERROR_SOCK_UNSUPPORTED_AF;
}
return 0;
}

Expand Down
5 changes: 5 additions & 0 deletions port/unix_include/omrsock.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
#define _OE_SOCKETS
#endif

/* This exposes some definitions needed by the socket api */
#if defined(OMR_OS_ZOS) && !defined(_OPEN_SYS_SOCK_IPV6)
#define _OPEN_SYS_SOCK_IPV6
#endif

#include <sys/types.h> /* Some historical implementations need this file, POSIX.1-2001 does not. */
#include <sys/socket.h>

Expand Down
2 changes: 1 addition & 1 deletion port/win32/omrsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ omrsock_htonl(struct OMRPortLibrary *portLibrary, uint32_t val)
}

int32_t
omrsock_inet_pton(struct OMRPortLibrary *portLibrary, int32_t addrFamily, const char *addr, uint8_t *addrNetworkOrder)
omrsock_inet_pton(struct OMRPortLibrary *portLibrary, int32_t addrFamily, const char *addr, uint8_t *result)
{
return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM;
}
Expand Down

0 comments on commit f50097e

Please sign in to comment.