add testsuites

Change-Id: Ice1193d1ae7f2e0d12a2a38a306a6399407f5037
This commit is contained in:
lnlan
2021-04-25 12:37:35 +08:00
parent dc90400456
commit 778c5e17c3
2720 changed files with 335022 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions 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.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import("//build/lite/config/test.gni")
import("../../config.gni")
config("net_local_config") {
if (LOSCFG_USER_TEST_NET_SOCKET == true) {
cflags = [ "-DLOSCFG_USER_TEST_NET_SOCKET" ]
cflags_cc = cflags
}
}
unittest("liteos_a_net_socket_unittest") {
output_extension = "bin"
output_dir = "$root_out_dir/test/unittest/kernel"
include_dirs = [
"../../common/include",
"../../net/socket",
]
sources = [
"../../common/osTest.cpp",
"net_socket_test.cpp",
"smoke/net_socket_test_001.cpp",
"smoke/net_socket_test_002.cpp",
"smoke/net_socket_test_003.cpp",
"smoke/net_socket_test_004.cpp",
"smoke/net_socket_test_005.cpp",
"smoke/net_socket_test_006.cpp",
"smoke/net_socket_test_007.cpp",
"smoke/net_socket_test_008.cpp",
"smoke/net_socket_test_009.cpp",
"smoke/net_socket_test_010.cpp",
"smoke/net_socket_test_011.cpp",
"smoke/net_socket_test_012.cpp",
"smoke/net_socket_test_013.cpp",
]
deps = [ "//third_party/bounds_checking_function:libsec_shared" ]
configs = [
"../../:public_config",
":net_local_config",
]
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions 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.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NET_SOCKET_LT_NET_SOCKET_H_
#define NET_SOCKET_LT_NET_SOCKET_H_
#include <osTest.h>
#include <sys/socket.h>
void NetSocketTest001(void);
void NetSocketTest002(void);
void NetSocketTest003(void);
void NetSocketTest004(void);
void NetSocketTest005(void);
void NetSocketTest006(void);
void NetSocketTest007(void);
void NetSocketTest008(void);
void NetSocketTest009(void);
void NetSocketTest010(void);
void NetSocketTest011(void);
void NetSocketTest012(void);
void NetSocketTest013(void);
#endif /* NET_SOCKET_LT_NET_SOCKET_H_ */

View File

@@ -0,0 +1,204 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions 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.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "stdio.h"
#include <climits>
#include <gtest/gtest.h>
#include "lt_net_socket.h"
using namespace testing::ext;
namespace OHOS {
class NetSocketTest : public testing::Test {
public:
static void SetUpTestCase(void)
{
struct sched_param param = { 0 };
int currThreadPolicy, ret;
ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, &param);
ICUNIT_ASSERT_EQUAL_VOID(ret, 0, -ret);
param.sched_priority = TASK_PRIO_TEST;
ret = pthread_setschedparam(pthread_self(), SCHED_RR, &param);
ICUNIT_ASSERT_EQUAL_VOID(ret, 0, -ret);
}
static void TearDownTestCase(void) {}
};
#if defined(LOSCFG_USER_TEST_SMOKE) && defined(LOSCFG_USER_TEST_NET_SOCKET)
/* *
* @tc.name: NetSocketTest001
* @tc.desc: function for NetSocketTest
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
HWTEST_F(NetSocketTest, NetSocketTest001, TestSize.Level0)
{
NetSocketTest001();
}
/* *
* @tc.name: NetSocketTest002
* @tc.desc: function for NetSocketTest
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
HWTEST_F(NetSocketTest, NetSocketTest002, TestSize.Level0)
{
NetSocketTest002();
}
#if TEST_ON_LINUX
/* *
* @tc.name: NetSocketTest003
* @tc.desc: function for NetSocketTest
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
HWTEST_F(NetSocketTest, NetSocketTest003, TestSize.Level0)
{
NetSocketTest003(); // getifaddrs need PF_NETLINK which was not supported by lwip currently
}
#endif
/* *
* @tc.name: NetSocketTest004
* @tc.desc: function for NetSocketTest
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
HWTEST_F(NetSocketTest, NetSocketTest004, TestSize.Level0)
{
NetSocketTest004();
}
/* *
* @tc.name: NetSocketTest005
* @tc.desc: function for NetSocketTest
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
HWTEST_F(NetSocketTest, NetSocketTest005, TestSize.Level0)
{
NetSocketTest005();
}
/* *
* @tc.name: NetSocketTest006
* @tc.desc: function for NetSocketTest
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
HWTEST_F(NetSocketTest, NetSocketTest006, TestSize.Level0)
{
NetSocketTest006();
}
#if TEST_ON_LINUX
/* *
* @tc.name: NetSocketTest007
* @tc.desc: function for NetSocketTest
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
HWTEST_F(NetSocketTest, NetSocketTest007, TestSize.Level0)
{
NetSocketTest007();
}
#endif
/* *
* @tc.name: NetSocketTest008
* @tc.desc: function for NetSocketTest
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
HWTEST_F(NetSocketTest, NetSocketTest008, TestSize.Level0)
{
NetSocketTest008();
}
/* *
* @tc.name: NetSocketTest009
* @tc.desc: function for NetSocketTest
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
HWTEST_F(NetSocketTest, NetSocketTest009, TestSize.Level0)
{
NetSocketTest009();
}
/* *
* @tc.name: NetSocketTest010
* @tc.desc: function for NetSocketTest
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
HWTEST_F(NetSocketTest, NetSocketTest010, TestSize.Level0)
{
NetSocketTest010();
}
/* *
* @tc.name: NetSocketTest011
* @tc.desc: function for NetSocketTest
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
HWTEST_F(NetSocketTest, NetSocketTest011, TestSize.Level0)
{
NetSocketTest011();
}
/* *
* @tc.name: NetSocketTest012
* @tc.desc: function for NetSocketTest
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
HWTEST_F(NetSocketTest, NetSocketTest012, TestSize.Level0)
{
NetSocketTest012();
}
/* *
* @tc.name: NetSocketTest013
* @tc.desc: function for NetSocketTest
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
/*
HWTEST_F(NetSocketTest, NetSocketTest013, TestSize.Level0)
{
//NetSocketTest013(); // broadcast to self to be supported.
}
*/
#endif
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions 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.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/socket.h>
#include <osTest.h>
static int SocketTest(void)
{
int fd = socket(0, 0, 0);
ICUNIT_ASSERT_EQUAL(fd, -1, fd);
return ICUNIT_SUCCESS;
}
void NetSocketTest001(void)
{
TEST_ADD_CASE(__FUNCTION__, SocketTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}

View File

@@ -0,0 +1,131 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions 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.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <osTest.h>
#define localhost "127.0.0.1"
#define STACK_IP localhost
#define STACK_PORT 2277
#define PEER_PORT STACK_PORT
#define PEER_IP localhost
#define MSG "Hi, I am UDP"
#define BUF_SIZE (1024 * 8)
static char g_buf[BUF_SIZE + 1] = { 0 };
static int UdpTest(void)
{
int sfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
int ret = 0, i = 0;
struct msghdr msg = { 0 };
struct iovec iov[2] = { };
/* socket creation */
sfd = socket(AF_INET, SOCK_DGRAM, 0);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, sfd);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(STACK_PORT);
ret = bind(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
/* send */
clnAddr.sin_family = AF_INET;
clnAddr.sin_addr.s_addr = inet_addr(PEER_IP);
clnAddr.sin_port = htons(PEER_PORT);
ret = memset_s(g_buf, BUF_SIZE, 0, BUF_SIZE);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = strcpy_s(g_buf, BUF_SIZE, MSG);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = sendto(sfd, g_buf, strlen(MSG), 0, (struct sockaddr*)&clnAddr,
(socklen_t)sizeof(clnAddr));
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret);
/* recv */
ret = memset_s(g_buf, BUF_SIZE, 0, BUF_SIZE);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = recvfrom(sfd, g_buf, sizeof(g_buf), 0, (struct sockaddr*)&clnAddr,
&clnAddrLen);
ICUNIT_ASSERT_EQUAL(ret, strlen(MSG), ret);
/* sendmsg */
clnAddr.sin_family = AF_INET;
clnAddr.sin_addr.s_addr = inet_addr(PEER_IP);
clnAddr.sin_port = htons(PEER_PORT);
ret = memset_s(g_buf, BUF_SIZE, 0, BUF_SIZE);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = strcpy_s(g_buf, BUF_SIZE, MSG);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = 2;
iov[0].iov_base = g_buf;
iov[0].iov_len = strlen(MSG);
iov[1].iov_base = g_buf;
iov[1].iov_len = strlen(MSG);
ret = sendmsg(sfd, &msg, 0);
ICUNIT_ASSERT_EQUAL(ret, 2 * strlen(MSG), ret);
/* recvmsg */
ret = memset_s(g_buf, BUF_SIZE, 0, BUF_SIZE);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = memset_s(&msg, sizeof(msg), 0, sizeof(msg));
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
iov[0].iov_base = g_buf;
iov[0].iov_len = sizeof(g_buf);
ret = recvmsg(sfd, &msg, 0);
ICUNIT_ASSERT_EQUAL(ret, 2 * strlen(MSG), ret);
/* close socket */
ret = close(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, ret);
return 0;
}
void NetSocketTest002(void)
{
TEST_ADD_CASE(__FUNCTION__, UdpTest, TEST_POSIX, TEST_UDP, TEST_LEVEL0, TEST_FUNCTION);
}

View File

@@ -0,0 +1,321 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions 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.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <osTest.h>
#define localhost "127.0.0.1"
#define STACK_IP localhost
#define STACK_PORT 2277
#define PEER_PORT STACK_PORT
#define PEER_IP localhost
#define BUF_SIZE (1024 * 8)
#define SRV_MSG "Hi, I am TCP server"
#define CLI_MSG "Hi, I am TCP client"
static pthread_barrier_t gBarrier;
#define Wait() pthread_barrier_wait(&gBarrier)
static int SampleTcpServer()
{
static char gBuf[BUF_SIZE + 1] = { 0 };
int sfd = -1, lsfd = -1;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
struct msghdr msg = { 0 };
struct iovec iov[2] = { };
int ret = 0, i = 0;
/* tcp server */
lsfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create listen socket inet stream: %d", lsfd);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, lsfd);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(STACK_PORT);
ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("bind socket %d to %s:%d: %d", lsfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, Wait() + ret);
ret = listen(lsfd, 0);
LogPrintln("listen socket %d: %d", lsfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
Wait();
sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen);
LogPrintln("accept socket %d: %d <%s:%d>", lsfd, sfd, inet_ntoa(clnAddr.sin_addr), ntohs(clnAddr.sin_port));
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, sfd);
/* send */
ret = memset_s(gBuf, BUF_SIZE - 1, 0, BUF_SIZE - 1);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
gBuf[BUF_SIZE - 1] = '\0';
ret = strcpy_s(gBuf, BUF_SIZE - 1, SRV_MSG);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
gBuf[BUF_SIZE - 1] = '\0';
ret = send(sfd, gBuf, strlen(SRV_MSG), 0);
LogPrintln("send on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), ret);
/* recv */
ret = memset_s(gBuf, BUF_SIZE - 1, 0, BUF_SIZE - 1);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
gBuf[BUF_SIZE - 1] = '\0';
ret = recv(sfd, gBuf, sizeof(gBuf), 0);
LogPrintln("recv on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, strlen(CLI_MSG), ret);
Wait();
/* sendmsg */
clnAddr.sin_family = AF_INET;
clnAddr.sin_addr.s_addr = inet_addr(PEER_IP);
clnAddr.sin_port = htons(PEER_PORT);
ret = memset_s(gBuf, BUF_SIZE - 1, 0, BUF_SIZE - 1);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
gBuf[BUF_SIZE - 1] = '\0';
ret = strcpy_s(gBuf, BUF_SIZE - 1, SRV_MSG);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
gBuf[BUF_SIZE - 1] = '\0';
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = 2;
iov[0].iov_base = gBuf;
iov[0].iov_len = strlen(SRV_MSG);
iov[1].iov_base = gBuf;
iov[1].iov_len = strlen(SRV_MSG);
ret = sendmsg(sfd, &msg, 0);
LogPrintln("sendmsg on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 2 * strlen(SRV_MSG), ret);
Wait();
/* recvmsg */
ret = memset_s(gBuf, BUF_SIZE - 1, 0, BUF_SIZE - 1);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
gBuf[BUF_SIZE - 1] = '\0';
ret = memset_s(&msg, sizeof(msg), 0, sizeof(msg));
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
iov[0].iov_base = gBuf;
iov[0].iov_len = sizeof(gBuf);
ret = recvmsg(sfd, &msg, 0);
LogPrintln("recvmsg on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 2 * strlen(CLI_MSG), ret);
ret = shutdown(sfd, SHUT_RDWR);
LogPrintln("shutdown socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
close(sfd);
close(lsfd);
return 0;
}
static int SampleTcpClient()
{
static char gBuf[BUF_SIZE + 1] = { 0 };
int sfd = -1;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
int ret = 0, i = 0;
struct msghdr msg = { 0 };
struct iovec iov[2] = { };
struct sockaddr addr;
socklen_t addrLen = sizeof(addr);
/* tcp client connection */
sfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create client socket inet stream: %d", sfd);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, sfd);
Wait();
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(PEER_IP);
srvAddr.sin_port = htons(PEER_PORT);
ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("connect socket %d to %s:%d: %d", sfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
/* test getpeername */
ret = getpeername(sfd, &addr, &addrLen);
LogPrintln("getpeername %d %s:%d: %d", sfd, inet_ntoa(((struct sockaddr_in*)&addr)->sin_addr), ntohs(((struct sockaddr_in*)&addr)->sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(addrLen, sizeof(struct sockaddr_in), addrLen);
ICUNIT_ASSERT_EQUAL(((struct sockaddr_in*)&addr)->sin_addr.s_addr,
inet_addr(PEER_IP), ((struct sockaddr_in*)&addr)->sin_addr.s_addr);
/* test getsockname */
ret = getsockname(sfd, &addr, &addrLen);
LogPrintln("getsockname %d %s:%d: %d", sfd, inet_ntoa(((struct sockaddr_in*)&addr)->sin_addr), ntohs(((struct sockaddr_in*)&addr)->sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(addrLen, sizeof(struct sockaddr_in), addrLen);
ICUNIT_ASSERT_EQUAL(((struct sockaddr_in*)&addr)->sin_addr.s_addr,
inet_addr(STACK_IP), ((struct sockaddr_in*)&addr)->sin_addr.s_addr);
/* send */
ret = memset_s(gBuf, BUF_SIZE - 1, 0, BUF_SIZE - 1);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
gBuf[BUF_SIZE - 1] = '\0';
ret = strcpy_s(gBuf, BUF_SIZE - 1, CLI_MSG);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
gBuf[BUF_SIZE - 1] = '\0';
ret = send(sfd, gBuf, strlen(CLI_MSG), 0);
LogPrintln("send on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, strlen(CLI_MSG), ret);
/* recv */
ret = memset_s(gBuf, BUF_SIZE - 1, 0, BUF_SIZE - 1);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
gBuf[BUF_SIZE - 1] = '\0';
ret = recv(sfd, gBuf, sizeof(gBuf), 0);
LogPrintln("recv on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), ret);
Wait();
/* sendmsg */
clnAddr.sin_family = AF_INET;
clnAddr.sin_addr.s_addr = inet_addr(PEER_IP);
clnAddr.sin_port = htons(PEER_PORT);
ret = memset_s(gBuf, BUF_SIZE - 1, 0, BUF_SIZE - 1);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
gBuf[BUF_SIZE - 1] = '\0';
ret = strcpy_s(gBuf, BUF_SIZE - 1, CLI_MSG);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
gBuf[BUF_SIZE - 1] = '\0';
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = 2;
iov[0].iov_base = gBuf;
iov[0].iov_len = strlen(CLI_MSG);
iov[1].iov_base = gBuf;
iov[1].iov_len = strlen(CLI_MSG);
ret = sendmsg(sfd, &msg, 0);
LogPrintln("sendmsg on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 2 * strlen(CLI_MSG), ret);
Wait();
/* recvmsg */
ret = memset_s(gBuf, BUF_SIZE - 1, 0, BUF_SIZE - 1);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
gBuf[BUF_SIZE - 1] = '\0';
ret = memset_s(&msg, sizeof(msg), 0, sizeof(msg));
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
iov[0].iov_base = gBuf;
iov[0].iov_len = sizeof(gBuf);
ret = recvmsg(sfd, &msg, 0);
LogPrintln("recvmsg on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 2 * strlen(SRV_MSG), ret);
ret = shutdown(sfd, SHUT_RDWR);
LogPrintln("shutdown socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
close(sfd);
return 0;
}
static void* TcpServerRoutine(void *p)
{
int ret = SampleTcpServer();
return (void*)(intptr_t)ret;
}
static void* TcpClientRoutine(void *p)
{
int ret = SampleTcpClient();
return (void*)(intptr_t)ret;
}
static int TcpTest()
{
int ret;
void *sret = NULL;
void *cret = NULL;
pthread_t srv, cli;
pthread_attr_t attr;
ret = pthread_barrier_init(&gBarrier, 0, 2);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_attr_init(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_create(&srv, &attr, TcpServerRoutine, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_create(&cli, &attr, TcpClientRoutine, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_join(cli, &cret);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
LogPrintln("client finish");
ret = pthread_join(srv, &sret);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
LogPrintln("server finish");
ret = pthread_attr_destroy(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_barrier_destroy(&gBarrier);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
return (int)(intptr_t)(sret) + (int)(intptr_t)(cret);
}
void NetSocketTest003(void)
{
TEST_ADD_CASE(__FUNCTION__, TcpTest, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions 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.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <osTest.h>
static int SockOptTest(void)
{
int ret, error, flag;
struct timeval timeout;
socklen_t len;
int fd = socket(AF_INET, SOCK_STREAM, 0);
ICUNIT_ASSERT_NOT_EQUAL(fd, -1, fd);
error = -1;
len = sizeof(error);
ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len);
LogPrintln("getsockopt(%d, SOL_SOCKET, SO_ERROR, &error, &len)=%d, error=%d, len=%d, errno=%d", fd, ret, error, len, errno);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(error, 0, error);
len = sizeof(timeout);
ret = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, &len);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
timeout.tv_sec = 1000;
len = sizeof(timeout);
ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, len);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = memset_s(&timeout, len, 0, len);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, &len);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(timeout.tv_sec, 1000, ret);
error = -1;
len = sizeof(error);
ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len);
LogPrintln("getsockopt(%d, SOL_SOCKET, SO_ERROR, &error, &len)=%d, error=%d, len=%d, errno=%d", fd, ret, error, len, errno);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(error, 0, error);
flag=1;
ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
LogPrintln("setsockopt(TCP_NODELAY) ret=%d", ret);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = close(fd);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
return ICUNIT_SUCCESS;
}
void NetSocketTest004(void)
{
TEST_ADD_CASE(__FUNCTION__, SockOptTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions 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.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/socket.h>
#include <arpa/inet.h>
#include <osTest.h>
static int ByteOrderTest(void)
{
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
uint32_t hl = ntohl(0x12345678);
ICUNIT_ASSERT_EQUAL(hl, 0x78563412, hl);
uint32_t nl = htonl(0x12345678);
ICUNIT_ASSERT_EQUAL(nl, 0x78563412, nl);
uint16_t hs = ntohs(0x1234);
ICUNIT_ASSERT_EQUAL(hs, 0x3412, hs);
uint16_t ns = htons(0x1234);
ICUNIT_ASSERT_EQUAL(ns, 0x3412, ns);
#else
uint32_t hl = ntohl(0x12345678);
ICUNIT_ASSERT_EQUAL(hl, 0x12345678, hl);
uint32_t nl = htonl(0x12345678);
ICUNIT_ASSERT_EQUAL(nl, 0x12345678, nl);
uint16_t hs = ntohs(0x1234);
ICUNIT_ASSERT_EQUAL(hs, 0x1234, hs);
uint16_t ns = htons(0x1234);
ICUNIT_ASSERT_EQUAL(ns, 0x1234, ns);
#endif
return ICUNIT_SUCCESS;
}
void NetSocketTest005(void)
{
TEST_ADD_CASE(__FUNCTION__, ByteOrderTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions 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.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <osTest.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
static int InetTest(void)
{
struct in_addr in;
int ret = inet_pton(AF_INET, "300.10.10.10", &in);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = inet_pton(AF_INET, "10.11.12.13", &in);
ICUNIT_ASSERT_EQUAL(ret, 1, ret);
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
ICUNIT_ASSERT_EQUAL(in.s_addr, 0x0d0c0b0a, in.s_addr);
#else
ICUNIT_ASSERT_EQUAL(in.s_addr, 0x0a0b0c0d, in.s_addr);
#endif
// host order
in_addr_t lna = inet_lnaof(in);
ICUNIT_ASSERT_EQUAL(lna, 0x000b0c0d, lna);
// host order
in_addr_t net = inet_netof(in);
ICUNIT_ASSERT_EQUAL(net, 0x0000000a, net);
in = inet_makeaddr(net, lna);
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
ICUNIT_ASSERT_EQUAL(in.s_addr, 0x0d0c0b0a, in.s_addr);
#else
ICUNIT_ASSERT_EQUAL(in.s_addr, 0x0a0b0c0d, in.s_addr);
#endif
net = inet_network("300.10.10.10");
ICUNIT_ASSERT_EQUAL(net, -1, net);
// host order
net = inet_network("10.11.12.13");
ICUNIT_ASSERT_EQUAL(net, 0x0a0b0c0d, net);
const char *p = inet_ntoa(in);
ICUNIT_ASSERT_EQUAL(strcmp(p, "10.11.12.13"), 0, -1);
char buf[32];
p = inet_ntop(AF_INET, &in, buf, sizeof(buf));
ICUNIT_ASSERT_EQUAL(p, buf, -1);
ICUNIT_ASSERT_EQUAL(strcmp(p, "10.11.12.13"), 0, -1);
return ICUNIT_SUCCESS;
}
void NetSocketTest006(void)
{
TEST_ADD_CASE(__FUNCTION__, InetTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}

View File

@@ -0,0 +1,156 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions 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.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <arpa/inet.h>
#include <osTest.h>
#define SRV_MSG "Hi, I am TCP server"
#define INVALID_USER_ADDR 0X1200000
#define INVALID_KERNEL_ADDR 0x48000000
static int TcpTest()
{
int ret;
int lsfd = -1;
struct msghdr msg = { 0 };
lsfd = socket(AF_INET, SOCK_STREAM, 0);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, lsfd);
ret = bind(lsfd, (const struct sockaddr *)INVALID_USER_ADDR, sizeof(struct sockaddr_in));
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = bind(lsfd, (const struct sockaddr *)INVALID_KERNEL_ADDR, sizeof(struct sockaddr_in));
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = connect(lsfd, (struct sockaddr*)INVALID_USER_ADDR, sizeof(struct sockaddr_in));
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = connect(lsfd, (struct sockaddr*)INVALID_KERNEL_ADDR, sizeof(struct sockaddr_in));
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = accept(lsfd, (struct sockaddr*)INVALID_USER_ADDR, (socklen_t *)INVALID_USER_ADDR);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = accept(lsfd, (struct sockaddr*)INVALID_KERNEL_ADDR, (socklen_t *)INVALID_KERNEL_ADDR);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = getsockname(lsfd, (struct sockaddr*)INVALID_USER_ADDR, (socklen_t *)INVALID_USER_ADDR);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = getsockname(lsfd, (struct sockaddr*)INVALID_KERNEL_ADDR, (socklen_t *)INVALID_KERNEL_ADDR);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = getpeername(lsfd, (struct sockaddr*)INVALID_USER_ADDR, (socklen_t *)INVALID_USER_ADDR);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = getpeername(lsfd, (struct sockaddr*)INVALID_KERNEL_ADDR, (socklen_t *)INVALID_KERNEL_ADDR);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = send(lsfd, (char *)INVALID_USER_ADDR, strlen(SRV_MSG), 0);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = send(lsfd, (char *)INVALID_KERNEL_ADDR, strlen(SRV_MSG), 0);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = sendto(lsfd, (char *)INVALID_USER_ADDR, strlen(SRV_MSG), 0, (struct sockaddr*)INVALID_USER_ADDR,
(socklen_t)sizeof(struct sockaddr_in));
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = sendto(lsfd, (char *)INVALID_KERNEL_ADDR, strlen(SRV_MSG), 0, (struct sockaddr*)INVALID_KERNEL_ADDR,
(socklen_t)sizeof(struct sockaddr_in));
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = recv(lsfd, (char *)INVALID_USER_ADDR, sizeof(SRV_MSG), 0);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = recv(lsfd, (char *)INVALID_KERNEL_ADDR, sizeof(SRV_MSG), 0);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = recvfrom(lsfd, (char *)INVALID_USER_ADDR, sizeof(SRV_MSG), 0, (struct sockaddr*)INVALID_USER_ADDR,
(socklen_t *)INVALID_USER_ADDR);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = recvfrom(lsfd, (char *)INVALID_KERNEL_ADDR, sizeof(SRV_MSG), 0, (struct sockaddr*)INVALID_KERNEL_ADDR,
(socklen_t *)INVALID_KERNEL_ADDR);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = setsockopt(lsfd, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *)INVALID_USER_ADDR, (socklen_t)sizeof(struct timeval));
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = setsockopt(lsfd, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *)INVALID_KERNEL_ADDR, (socklen_t)sizeof(struct timeval));
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = getsockopt(lsfd, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *)INVALID_USER_ADDR, (socklen_t*)sizeof(struct timeval));
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = getsockopt(lsfd, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *)INVALID_KERNEL_ADDR, (socklen_t*)sizeof(struct timeval));
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = sendmsg(lsfd, (struct msghdr *)INVALID_USER_ADDR, 0);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = sendmsg(lsfd, (struct msghdr *)INVALID_KERNEL_ADDR, 0);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
msg.msg_name = (char *)INVALID_USER_ADDR;
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_iov = (struct iovec *)INVALID_KERNEL_ADDR;
msg.msg_iovlen = 2;
ret = recvmsg(lsfd, (struct msghdr *)&msg, 0);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
ret = recvmsg(lsfd, (struct msghdr *)&msg, 0);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
#ifdef TEST_BIG_MEM
const int bufSiz = 0x1400000; // 20M
void *buf = malloc(bufSiz);
if (!buf) {
printf("malloc 20M fail\n");
} else {
printf("malloc 20M success\n");
ret = memset_s(buf, bufSiz, 0, bufSiz);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = send(lsfd, buf, bufSiz, 0);
printf("send ret = %d, errno :%d\n", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
}
#endif
close(lsfd);
return 0;
}
void NetSocketTest007(void)
{
TEST_ADD_CASE(__FUNCTION__, TcpTest, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
}

View File

@@ -0,0 +1,282 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions 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.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <osTest.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SERVER_PORT 6666
#define INVALID_SOCKET -1
#define CLIENT_NUM 50
#define BACKLOG CLIENT_NUM
static int gFds[FD_SETSIZE];
static int gBye;
static void InitFds()
{
for (int i = 0; i < FD_SETSIZE; ++i) {
gFds[i] = INVALID_SOCKET;
}
}
static void GetReadfds(fd_set *fds, int *nfd)
{
for (int i = 0; i < FD_SETSIZE; i++) {
if (gFds[i] == INVALID_SOCKET) {
continue;
}
FD_SET(gFds[i], fds);
if (*nfd < gFds[i]) {
*nfd = gFds[i];
}
}
}
static int AddFd(int fd)
{
for (int i = 0; i < FD_SETSIZE; ++i) {
if (gFds[i] == INVALID_SOCKET) {
gFds[i] = fd;
return 0;
}
}
return -1;
}
static void DelFd(int fd)
{
for (int i = 0; i < FD_SETSIZE; ++i) {
if (gFds[i] == fd) {
gFds[i] = INVALID_SOCKET;
}
}
(void)close(fd);
}
static int CloseAllFd(void)
{
for (int i = 0; i < FD_SETSIZE; ++i) {
if (gFds[i] != INVALID_SOCKET) {
(void)close(gFds[i]);
gFds[i] = INVALID_SOCKET;
}
}
return 0;
}
static int HandleRecv(int fd)
{
char buf[256];
int ret = recv(fd, buf, sizeof(buf)-1, 0);
if (ret < 0) {
LogPrintln("[%d]Error: %s", fd, strerror(errno));
DelFd(fd);
} else if (ret == 0) {
LogPrintln("[%d]Closed", fd);
DelFd(fd);
} else {
buf[ret] = 0;
LogPrintln("[%d]Received: %s", fd, buf);
if (strstr(buf, "Bye") != NULL) {
DelFd(fd);
gBye++;
}
}
return -(ret < 0);
}
static int HandleAccept(int lsfd)
{
struct sockaddr_in sa;
int saLen = sizeof(sa);
int fd = accept(lsfd, (struct sockaddr *)&sa, (socklen_t *)&saLen);
if (fd == INVALID_SOCKET) {
perror("accept");
return -1;
}
if (AddFd(fd) == -1) {
LogPrintln("Too many clients, refuse %s:%d", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port));
close(fd);
return -1;
}
LogPrintln("New client %d: %s:%d", fd, inet_ntoa(sa.sin_addr), ntohs(sa.sin_port));
return 0;
}
static int HandleReadfds(fd_set *fds, int lsfd)
{
int ret = 0;
for (int i = 0; i < FD_SETSIZE; ++i) {
if (gFds[i] == INVALID_SOCKET || !FD_ISSET(gFds[i], fds)) {
continue;
}
if (gFds[i] == lsfd) {
ret += HandleAccept(lsfd);
} else {
ret += HandleRecv(gFds[i]);
}
}
return ret;
}
static void *ClientsThread(void *param)
{
int fd;
int thrNo = (int)(intptr_t)param;
LogPrintln("<%d>socket client thread started", thrNo);
fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (fd == INVALID_SOCKET) {
perror("socket");
return NULL;
}
struct sockaddr_in sa;
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
sa.sin_port = htons(SERVER_PORT);
if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
perror("connect");
return NULL;
}
LogPrintln("[%d]<%d>connected to %s:%d successful", fd, thrNo, inet_ntoa(sa.sin_addr), SERVER_PORT);
const char *msg[] = {
"hello, ",
"ohos, ",
"my name is net_socket_test_008, ",
"see u next time, ",
"Bye!"
};
for (int i = 0; i < sizeof(msg) / sizeof(msg[0]); ++i) {
if (send(fd, msg[i], strlen(msg[i]), 0) < 0) {
LogPrintln("[%d]<%d>send msg [%s] fail", fd, thrNo, msg[i]);
}
}
(void)shutdown(fd, SHUT_RDWR);
(void)close(fd);
return param;
}
static int StartClients(pthread_t *cli, int cliNum)
{
int ret;
pthread_attr_t attr;
for (int i = 0; i < cliNum; ++i) {
ret = pthread_attr_init(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_create(&cli[i], &attr, ClientsThread, (void *)(intptr_t)i);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_attr_destroy(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
}
return 0;
}
static int SelectTest(void)
{
struct sockaddr_in sa = {0};
int lsfd;
int ret;
lsfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, errno);
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl(INADDR_ANY);
sa.sin_port = htons(SERVER_PORT);
ret = bind(lsfd, (struct sockaddr *)&sa, sizeof(sa));
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, errno + CloseAllFd());
ret = listen(lsfd, BACKLOG);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, errno + CloseAllFd());
InitFds();
AddFd(lsfd);
LogPrintln("[%d]Waiting for client to connect on port %d", lsfd, SERVER_PORT);
pthread_t clients[CLIENT_NUM];
ret = StartClients(clients, CLIENT_NUM);
ICUNIT_ASSERT_EQUAL(ret, 0, ret + CloseAllFd());
for ( ; ; ) {
int nfd;
fd_set readfds;
struct timeval timeout;
timeout.tv_sec = 3;
timeout.tv_usec = 0;
nfd = 0;
FD_ZERO(&readfds);
GetReadfds(&readfds, &nfd);
ret = select(nfd + 1, &readfds, NULL, NULL, &timeout);
LogPrintln("select %d", ret);
if (ret == -1) {
perror("select");
break; // error occurred
} else if (ret == 0) {
break; // timed out
}
if (HandleReadfds(&readfds, lsfd) < 0) {
break;
}
}
for (int i = 0; i < CLIENT_NUM; ++i) {
ret = pthread_join(clients[i], NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret + CloseAllFd());
}
ICUNIT_ASSERT_EQUAL(gBye, CLIENT_NUM, gBye + CloseAllFd());
(void)CloseAllFd();
return ICUNIT_SUCCESS;
}
void NetSocketTest008(void)
{
TEST_ADD_CASE(__FUNCTION__, SelectTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}

View File

@@ -0,0 +1,278 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions 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.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <osTest.h>
#include <sys/socket.h>
#include <poll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SERVER_PORT 8888
#define INVALID_SOCKET -1
#define CLIENT_NUM 50
#define BACKLOG CLIENT_NUM
static int gFds[FD_SETSIZE];
static int gBye;
static void InitFds()
{
for (int i = 0; i < FD_SETSIZE; ++i) {
gFds[i] = INVALID_SOCKET;
}
}
static void GetReadfds(struct pollfd *fds, int *nfd)
{
for (int i = 0; i < FD_SETSIZE; i++) {
if (gFds[i] == INVALID_SOCKET) {
continue;
}
fds[*nfd].fd = gFds[i];
fds[*nfd].events = POLLIN;
(*nfd)++;
}
}
static int AddFd(int fd)
{
for (int i = 0; i < FD_SETSIZE; ++i) {
if (gFds[i] == INVALID_SOCKET) {
gFds[i] = fd;
return 0;
}
}
return -1;
}
static void DelFd(int fd)
{
for (int i = 0; i < FD_SETSIZE; ++i) {
if (gFds[i] == fd) {
gFds[i] = INVALID_SOCKET;
}
}
(void)close(fd);
}
static int CloseAllFd(void)
{
for (int i = 0; i < FD_SETSIZE; ++i) {
if (gFds[i] != INVALID_SOCKET) {
(void)close(gFds[i]);
gFds[i] = INVALID_SOCKET;
}
}
return 0;
}
static int HandleRecv(int fd)
{
char buf[256];
int ret = recv(fd, buf, sizeof(buf)-1, 0);
if (ret < 0) {
LogPrintln("[%d]Error: %s", fd, strerror(errno));
DelFd(fd);
} else if (ret == 0) {
LogPrintln("[%d]Closed", fd);
DelFd(fd);
} else {
buf[ret] = 0;
LogPrintln("[%d]Received: %s", fd, buf);
if (strstr(buf, "Bye") != NULL) {
DelFd(fd);
gBye++;
}
}
return -(ret < 0);
}
static int HandleAccept(int lsfd)
{
struct sockaddr_in sa;
int saLen = sizeof(sa);
int fd = accept(lsfd, (struct sockaddr *)&sa, (socklen_t *)&saLen);
if (fd == INVALID_SOCKET) {
perror("accept");
return -1;
}
if (AddFd(fd) == -1) {
LogPrintln("Too many clients, refuse %s:%d", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port));
close(fd);
return -1;
}
LogPrintln("New client %d: %s:%d", fd, inet_ntoa(sa.sin_addr), ntohs(sa.sin_port));
return 0;
}
static int HandleReadfds(struct pollfd *fds, int nfds, int lsfd)
{
int ret = 0;
for (int i = 0; i < nfds; ++i) {
if (fds[i].revents == 0) {
continue;
}
LogPrintln("[%d]revents: %04hx", fds[i].fd, fds[i].revents);
if (fds[i].fd == lsfd) {
ret += HandleAccept(lsfd);
} else {
ret += HandleRecv(fds[i].fd);
}
}
return ret;
}
static void *ClientsThread(void *param)
{
int fd;
int thrNo = (int)(intptr_t)param;
LogPrintln("<%d>socket client thread started", thrNo);
fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (fd == INVALID_SOCKET) {
perror("socket");
return NULL;
}
struct sockaddr_in sa;
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
sa.sin_port = htons(SERVER_PORT);
if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
perror("connect");
return NULL;
}
LogPrintln("[%d]<%d>connected to %s:%d successful", fd, thrNo, inet_ntoa(sa.sin_addr), SERVER_PORT);
const char *msg[] = {
"hello, ",
"ohos, ",
"my name is net_socket_test_009, ",
"see u next time, ",
"Bye!"
};
for (int i = 0; i < sizeof(msg) / sizeof(msg[0]); ++i) {
if (send(fd, msg[i], strlen(msg[i]), 0) < 0) {
LogPrintln("[%d]<%d>send msg [%s] fail", fd, thrNo, msg[i]);
}
}
(void)shutdown(fd, SHUT_RDWR);
(void)close(fd);
return param;
}
static int StartClients(pthread_t *cli, int cliNum)
{
int ret;
pthread_attr_t attr;
for (int i = 0; i < cliNum; ++i) {
ret = pthread_attr_init(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_create(&cli[i], &attr, ClientsThread, (void *)(intptr_t)i);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_attr_destroy(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
}
return 0;
}
static int PollTest(void)
{
struct sockaddr_in sa = {0};
int lsfd;
int ret;
lsfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, errno);
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl(INADDR_ANY);
sa.sin_port = htons(SERVER_PORT);
ret = bind(lsfd, (struct sockaddr *)&sa, sizeof(sa));
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, errno + CloseAllFd());
ret = listen(lsfd, BACKLOG);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, errno + CloseAllFd());
InitFds();
AddFd(lsfd);
LogPrintln("[%d]Waiting for client to connect on port %d", lsfd, SERVER_PORT);
pthread_t clients[CLIENT_NUM];
ret = StartClients(clients, CLIENT_NUM);
ICUNIT_ASSERT_EQUAL(ret, 0, ret + CloseAllFd());
for ( ; ; ) {
int nfd;
struct pollfd readfds[FD_SETSIZE];
int timeoutMs;
timeoutMs = 3000;
nfd = 0;
GetReadfds(readfds, &nfd);
ret = poll(readfds, nfd, timeoutMs);
LogPrintln("poll %d", ret);
if (ret == -1) {
perror("poll");
break; // error occurred
} else if (ret == 0) {
break; // timed out
}
if (HandleReadfds(readfds, nfd, lsfd) < 0) {
break;
}
}
for (int i = 0; i < CLIENT_NUM; ++i) {
ret = pthread_join(clients[i], NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret + CloseAllFd());
}
ICUNIT_ASSERT_EQUAL(gBye, CLIENT_NUM, gBye + CloseAllFd());
(void)CloseAllFd();
return ICUNIT_SUCCESS;
}
void NetSocketTest009(void)
{
TEST_ADD_CASE(__FUNCTION__, PollTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}

View File

@@ -0,0 +1,191 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions 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.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <osTest.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <fcntl.h>
static char gDefaultNetif[IFNAMSIZ] = "eth0";
static void InitIfreq(struct ifreq *ifr)
{
*ifr = (struct ifreq){{0}};
(void)strncpy_s(ifr->ifr_name, sizeof(ifr->ifr_name) - 1, gDefaultNetif, sizeof(ifr->ifr_name) - 1);
ifr->ifr_name[sizeof(ifr->ifr_name) - 1] = '\0';
}
static char *IfIndex2Name(int fd, unsigned index, char *name)
{
#if SUPPORT_IF_INDEX_TO_NAME
return if_indextoname(index, name);
#else
struct ifreq ifr;
int ret;
ifr.ifr_ifindex = index;
ret = ioctl(fd, SIOCGIFNAME, &ifr);
if (ret < 0) {
return NULL;
}
ret = strncpy_s(name, IF_NAMESIZE - 1, ifr.ifr_name, IF_NAMESIZE - 1);
if (ret < 0) {
return NULL;
}
name[IF_NAMESIZE - 1] = '\0';
return name;
#endif
}
static unsigned IfName2Index(int fd, const char *name)
{
#if SUPPORT_IF_NAME_TO_INDEX
return if_nametoindex(name);
#else
struct ifreq ifr;
int ret;
(void)strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name) - 1, name, sizeof(ifr.ifr_name) - 1);
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
ret = ioctl(fd, SIOCGIFINDEX, &ifr);
return ret < 0 ? 0 : ifr.ifr_ifindex;
#endif
}
static int IoctlTestInternal(int sfd)
{
struct ifreq ifr = {{0}};
char ifName[IFNAMSIZ] = {0}, *p = NULL;
unsigned int loIndex = 0;
unsigned int lanIndex = 0;
int maxIndex = 256;
int ret;
for (int i = 0; i < maxIndex; ++i) {
p = IfIndex2Name(sfd, i, ifName);
if (p) {
if (strcmp(p, "lo") == 0) {
loIndex = i;
} else {
lanIndex = i;
}
}
}
LogPrintln("ifindex of lo: %u, ifindex of lan: %u", loIndex, lanIndex);
ICUNIT_ASSERT_NOT_EQUAL(loIndex, 0, errno);
ICUNIT_ASSERT_NOT_EQUAL(lanIndex, 0, errno);
p = IfIndex2Name(sfd, loIndex, ifName);
LogPrintln("ifindex %u: %s", loIndex, p);
ICUNIT_ASSERT_NOT_EQUAL(p, NULL, errno);
p = IfIndex2Name(sfd, lanIndex, ifName);
LogPrintln("ifindex %u: %s", lanIndex, p);
ICUNIT_ASSERT_NOT_EQUAL(p, NULL, errno);
ret = strncpy_s(gDefaultNetif, sizeof(gDefaultNetif) -1, p, sizeof(gDefaultNetif) - 1);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
gDefaultNetif[sizeof(gDefaultNetif) - 1] = '\0';
ret = (int)IfName2Index(sfd, p);
LogPrintln("index of %s: %d", p, ret);
ICUNIT_ASSERT_NOT_EQUAL(ret, 0, errno);
ifr.ifr_ifindex = lanIndex;
ret = ioctl(sfd, SIOCGIFNAME, &ifr);
ICUNIT_ASSERT_EQUAL(ret, 0, errno);
LogPrintln("name of ifindex %u: %s", lanIndex, ifr.ifr_name);
InitIfreq(&ifr);
ret = ioctl(sfd, SIOCGIFINDEX, &ifr);
ICUNIT_ASSERT_EQUAL(ret, 0, errno);
LogPrintln("index of ifname %s: %d", ifr.ifr_name, ifr.ifr_ifindex);
InitIfreq(&ifr);
ret = ioctl(sfd, SIOCGIFHWADDR, &ifr);
ICUNIT_ASSERT_EQUAL(ret, 0, errno);
LogPrintln("hwaddr: %02hhX:%02hhX:%02hhX:XX:XX:XX", ifr.ifr_hwaddr.sa_data[0], ifr.ifr_hwaddr.sa_data[1], ifr.ifr_hwaddr.sa_data[2]);
InitIfreq(&ifr);
ret = ioctl(sfd, SIOCGIFFLAGS, &ifr);
ICUNIT_ASSERT_EQUAL(ret, 0, errno);
LogPrintln("FLAGS of ifname %s: %#x, IFF_PROMISC: %d", ifr.ifr_name, ifr.ifr_flags, !!(ifr.ifr_flags & IFF_PROMISC));
if (ifr.ifr_flags & IFF_PROMISC) {
ifr.ifr_flags &= ~(IFF_PROMISC);
} else {
ifr.ifr_flags |= IFF_PROMISC;
}
LogPrintln("SIOCSIFFLAGS FLAGS: %#x", ifr.ifr_flags);
ret = ioctl(sfd, SIOCSIFFLAGS, &ifr);
if (ret == -1) {
ICUNIT_ASSERT_EQUAL(errno, EPERM, errno);
} else {
ICUNIT_ASSERT_EQUAL(ret, 0, errno);
}
InitIfreq(&ifr);
ret = ioctl(sfd, SIOCGIFFLAGS, &ifr);
ICUNIT_ASSERT_EQUAL(ret, 0, errno);
LogPrintln("FLAGS of ifname %s: %#x, IFF_PROMISC: %d", ifr.ifr_name, ifr.ifr_flags, !!(ifr.ifr_flags & IFF_PROMISC));
ret = fcntl(sfd, F_GETFL, 0);
ICUNIT_ASSERT_EQUAL(ret < 0, 0, errno);
ret = fcntl(sfd, F_SETFL, ret | O_NONBLOCK);
ICUNIT_ASSERT_EQUAL(ret < 0, 0, errno);
return ICUNIT_SUCCESS;
}
static int IoctlTest(void)
{
int sfd;
sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
LogPrintln("socket(PF_INET, SOCK_STREAM, IPPROTO_TCP): %d", sfd);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, errno);
(void)IoctlTestInternal(sfd);
(void)close(sfd);
return ICUNIT_SUCCESS;
}
void NetSocketTest010(void)
{
TEST_ADD_CASE(__FUNCTION__, IoctlTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}

View File

@@ -0,0 +1,254 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions 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.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <osTest.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SERVER_PORT 7777
#define INVALID_SOCKET -1
#define CLIENT_NUM 50
static int gFds[FD_SETSIZE];
static int gBye;
static void InitFds()
{
for (int i = 0; i < FD_SETSIZE; ++i) {
gFds[i] = INVALID_SOCKET;
}
}
static void GetReadfds(fd_set *fds, int *nfd)
{
for (int i = 0; i < FD_SETSIZE; i++) {
if (gFds[i] == INVALID_SOCKET) {
continue;
}
FD_SET(gFds[i], fds);
if (*nfd < gFds[i]) {
*nfd = gFds[i];
}
}
}
static int AddFd(int fd)
{
for (int i = 0; i < FD_SETSIZE; ++i) {
if (gFds[i] == INVALID_SOCKET) {
gFds[i] = fd;
return 0;
}
}
return -1;
}
static void DelFd(int fd)
{
for (int i = 0; i < FD_SETSIZE; ++i) {
if (gFds[i] == fd) {
gFds[i] = INVALID_SOCKET;
}
}
(void)close(fd);
}
static int CloseAllFd(void)
{
for (int i = 0; i < FD_SETSIZE; ++i) {
if (gFds[i] != INVALID_SOCKET) {
(void)close(gFds[i]);
gFds[i] = INVALID_SOCKET;
}
}
return 0;
}
static int HandleRecv(int fd)
{
char buf[256];
int ret = recv(fd, buf, sizeof(buf)-1, 0);
if (ret < 0) {
LogPrintln("[%d]Error: %s", fd, strerror(errno));
DelFd(fd);
} else if (ret == 0) {
LogPrintln("[%d]Closed", fd);
DelFd(fd);
} else {
buf[ret] = 0;
LogPrintln("[%d]Received: %s", fd, buf);
if (strstr(buf, "Bye") != NULL) {
gBye++;
}
}
return -(ret < 0);
}
static int HandleReadfds(fd_set *fds, int lsfd)
{
int ret = 0;
for (int i = 0; i < FD_SETSIZE; ++i) {
if (gFds[i] == INVALID_SOCKET || !FD_ISSET(gFds[i], fds)) {
continue;
}
ret += HandleRecv(gFds[i]);
}
return ret;
}
static void *ClientsThread(void *param)
{
int fd;
int thrNo = (int)(intptr_t)param;
LogPrintln("<%d>socket client thread started", thrNo);
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (fd == INVALID_SOCKET) {
perror("socket");
return NULL;
}
struct sockaddr_in sa;
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
sa.sin_port = htons(SERVER_PORT);
if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
perror("connect");
return NULL;
}
LogPrintln("[%d]<%d>connected to udp://%s:%d successful", fd, thrNo, inet_ntoa(sa.sin_addr), SERVER_PORT);
const char *msg[] = {
"hello, ",
"ohos, ",
"my name is net_socket_test_011, ",
"see u next time, ",
"Bye!"
};
for (int i = 0; i < sizeof(msg) / sizeof(msg[0]); ++i) {
if (send(fd, msg[i], strlen(msg[i]), 0) < 0) {
LogPrintln("[%d]<%d>send msg [%s] fail", fd, thrNo, msg[i]);
}
}
(void)shutdown(fd, SHUT_RDWR);
(void)close(fd);
return param;
}
static int StartClients(pthread_t *cli, int cliNum)
{
int ret;
pthread_attr_t attr;
for (int i = 0; i < cliNum; ++i) {
ret = pthread_attr_init(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_create(&cli[i], &attr, ClientsThread, (void *)(intptr_t)i);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_attr_destroy(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
}
return 0;
}
static int UdpSelectTest(void)
{
struct sockaddr_in sa = {0};
int lsfd;
int ret;
lsfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, errno);
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl(INADDR_ANY);
sa.sin_port = htons(SERVER_PORT);
ret = bind(lsfd, (struct sockaddr *)&sa, sizeof(sa));
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, errno + CloseAllFd());
InitFds();
AddFd(lsfd);
LogPrintln("[%d]Waiting for client to connect on UDP port %d", lsfd, SERVER_PORT);
pthread_t clients[CLIENT_NUM];
ret = StartClients(clients, CLIENT_NUM);
ICUNIT_ASSERT_EQUAL(ret, 0, ret + CloseAllFd());
for ( ; ; ) {
int nfd;
fd_set readfds;
struct timeval timeout;
timeout.tv_sec = 3;
timeout.tv_usec = 0;
nfd = 0;
FD_ZERO(&readfds);
GetReadfds(&readfds, &nfd);
ret = select(nfd + 1, &readfds, NULL, NULL, &timeout);
LogPrintln("select %d", ret);
if (ret == -1) {
perror("select");
break; // error occurred
} else if (ret == 0) {
break; // timed out
}
if (HandleReadfds(&readfds, lsfd) < 0) {
break;
}
}
for (int i = 0; i < CLIENT_NUM; ++i) {
ret = pthread_join(clients[i], NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret + CloseAllFd());
}
ICUNIT_ASSERT_EQUAL(gBye, CLIENT_NUM, gBye + CloseAllFd());
(void)CloseAllFd();
return ICUNIT_SUCCESS;
}
void NetSocketTest011(void)
{
TEST_ADD_CASE(__FUNCTION__, UdpSelectTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}

View File

@@ -0,0 +1,451 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions 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.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <osTest.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <fcntl.h>
#include <signal.h>
static struct iovec gIov[IOV_MAX + 1];
static int SocketNullTestInternal(int sfd)
{
int ret;
struct sockaddr addr = {0};
struct sockaddr *bad = (struct sockaddr *)0xbad;
socklen_t addrlen = sizeof(addr);
socklen_t zero = 0;
struct msghdr message = {0};
void *badUserAddr = (void*)0x3effffff;
/**
* accept
*/
ret = accept(sfd, NULL, NULL);
LogPrintln("accept: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = accept(sfd, NULL, &addrlen);
LogPrintln("accept: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = accept(sfd, bad, &zero);
LogPrintln("accept: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = accept(sfd, &addr, NULL);
LogPrintln("accept: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
/**
* bind
*/
ret = bind(sfd, NULL, addrlen);
LogPrintln("bind: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = bind(sfd, bad, 0);
LogPrintln("bind: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
/**
* getpeername
*/
ret = getpeername(sfd, NULL, NULL);
LogPrintln("getpeername: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = getpeername(sfd, NULL, &addrlen);
LogPrintln("getpeername: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = getpeername(sfd, &addr, NULL);
LogPrintln("getpeername: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
zero = 0;
ret = getpeername(sfd, bad, &zero);
LogPrintln("getpeername: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ICUNIT_ASSERT_EQUAL(errno, ENOTCONN, errno);
/**
* getsockname
*/
ret = getsockname(sfd, NULL, NULL);
LogPrintln("getsockname: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = getsockname(sfd, NULL, &addrlen);
LogPrintln("getsockname: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = getsockname(sfd, &addr, NULL);
LogPrintln("getsockname: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
zero = 0;
ret = getsockname(sfd, bad, &zero);
LogPrintln("getsockname: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
/**
* getsockopt
*/
ret = getsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, NULL, NULL);
LogPrintln("getsockopt: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = getsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, NULL, &addrlen);
LogPrintln("getsockopt: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = getsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, &addr, NULL);
LogPrintln("getsockopt: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
zero = 0;
ret = getsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, bad, &zero);
LogPrintln("getsockopt: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
/**
* setsockopt
*/
ret = setsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, NULL, addrlen);
LogPrintln("setsockopt: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = setsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, bad, 0);
LogPrintln("setsockopt: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = setsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, bad, addrlen);
LogPrintln("setsockopt: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
/**
* connect
*/
ret = connect(sfd, NULL, addrlen);
LogPrintln("connect: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = connect(sfd, bad, 0);
LogPrintln("connect: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = connect(sfd, bad, addrlen);
LogPrintln("connect: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
/**
* recv
*/
ret = recv(sfd, NULL, 1, MSG_DONTWAIT);
LogPrintln("recv: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
/**
* recvfrom
*/
ret = recvfrom(sfd, NULL, 1, MSG_DONTWAIT, NULL, NULL);
LogPrintln("recvfrom: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = recvfrom(sfd, NULL, 1, MSG_DONTWAIT, NULL, &addrlen);
LogPrintln("recvfrom: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = recvfrom(sfd, NULL, 1, MSG_DONTWAIT, &addr, NULL);
LogPrintln("recvfrom: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
zero = 0;
ret = recvfrom(sfd, NULL, 1, MSG_DONTWAIT, bad, &zero);
LogPrintln("recvfrom: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
/**
* recvmsg
*/
ret = recvmsg(sfd, NULL, MSG_DONTWAIT);
LogPrintln("recvmsg: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
message.msg_iov = NULL;
message.msg_iovlen = 1;
ret = recvmsg(sfd, &message, MSG_DONTWAIT);
LogPrintln("recvmsg: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
message.msg_iov = gIov;
message.msg_iovlen = 1 + IOV_MAX;
ret = recvmsg(sfd, &message, MSG_DONTWAIT);
LogPrintln("recvmsg: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
message.msg_iov = (struct iovec *)((void *)0xbad);
message.msg_iovlen = 1;
ret = recvmsg(sfd, &message, MSG_DONTWAIT);
LogPrintln("recvmsg: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
message.msg_iov = (struct iovec *)((void *)0xbad);
message.msg_iovlen = 0;
ret = recvmsg(sfd, &message, MSG_DONTWAIT);
LogPrintln("recvmsg: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
/**
* send
*/
ret = send(sfd, NULL, 1, MSG_NOSIGNAL);
LogPrintln("send: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = send(sfd, bad, 0, MSG_NOSIGNAL);
LogPrintln("send: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
/**
* sendmsg
*/
ret = sendmsg(sfd, NULL, MSG_NOSIGNAL);
LogPrintln("sendmsg: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
message.msg_iov = NULL;
message.msg_iovlen = 1;
ret = sendmsg(sfd, &message, MSG_NOSIGNAL);
LogPrintln("sendmsg: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
message.msg_iov = gIov;
message.msg_iovlen = IOV_MAX + 1;
ret = sendmsg(sfd, &message, MSG_NOSIGNAL);
LogPrintln("sendmsg: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
message.msg_iov = gIov;
message.msg_iovlen = (~0UL / sizeof(struct iovec)) + 2; // Test overflow
ret = sendmsg(sfd, &message, MSG_NOSIGNAL);
LogPrintln("sendmsg: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
message.msg_iov = (struct iovec *)0xbad;
message.msg_iovlen = 1;
ret = sendmsg(sfd, &message, MSG_NOSIGNAL);
LogPrintln("sendmsg: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
message.msg_iov = (struct iovec *)0xbad;
message.msg_iovlen = 0;
ret = sendmsg(sfd, &message, MSG_NOSIGNAL);
LogPrintln("sendmsg: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
/**
* sendto
*/
ret = sendto(sfd, NULL, 1, MSG_NOSIGNAL, NULL, addrlen);
LogPrintln("sendto: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = sendto(sfd, NULL, 1, MSG_NOSIGNAL, &addr, addrlen);
LogPrintln("sendto: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = sendto(sfd, bad, 0, MSG_NOSIGNAL, &addr, addrlen);
LogPrintln("sendto: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
ret = sendto(sfd, "NULL", 4, MSG_NOSIGNAL, NULL, addrlen);
LogPrintln("sendto: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = sendto(sfd, "NULL", 4, MSG_NOSIGNAL, bad, 0);
LogPrintln("sendto: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = sendto(sfd, "NULL", 4, MSG_NOSIGNAL, bad, addrlen);
LogPrintln("sendto: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
/**
* read/readv
*/
ret = read(sfd, NULL, 1);
LogPrintln("read: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = read(sfd, NULL, 0);
LogPrintln("read: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, 0, errno);
ret = read(sfd, bad, 1);
LogPrintln("read: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = read(sfd, badUserAddr, 1);
LogPrintln("read: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = read(sfd, bad, 0);
LogPrintln("read: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
ret = readv(sfd, (struct iovec *)bad, 0);
LogPrintln("readv: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
ret = readv(sfd, (struct iovec *)bad, 1);
LogPrintln("readv: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = readv(sfd, gIov, 0);
LogPrintln("readv: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
ret = readv(sfd, gIov, IOV_MAX + 1);
LogPrintln("readv: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
gIov[0].iov_base = bad;
gIov[0].iov_len = 1;
ret = readv(sfd, gIov, 1);
LogPrintln("readv: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
gIov[0].iov_base = bad;
gIov[0].iov_len = 0;
ret = readv(sfd, gIov, 1);
LogPrintln("readv: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
/**
* write/writev
*/
ret = write(sfd, NULL, 1);
LogPrintln("write: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = write(sfd, NULL, 0);
LogPrintln("write: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
ret = write(sfd, bad, 1);
LogPrintln("write: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = write(sfd, badUserAddr, 1);
LogPrintln("write: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = write(sfd, bad, 0);
LogPrintln("write: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
ret = writev(sfd, (struct iovec *)bad, 0);
LogPrintln("writev: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
ret = writev(sfd, (struct iovec *)bad, 1);
LogPrintln("writev: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
ret = writev(sfd, gIov, 0);
LogPrintln("writev: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
ret = writev(sfd, gIov, IOV_MAX + 1);
LogPrintln("writev: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
gIov[0].iov_base = bad;
gIov[0].iov_len = 1;
ret = writev(sfd, gIov, 1);
LogPrintln("writev: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL(ret, -1, errno);
gIov[0].iov_base = bad;
gIov[0].iov_len = 0;
ret = writev(sfd, gIov, 1);
LogPrintln("writev: %d, errno=%d", ret, errno);
ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
return ICUNIT_SUCCESS;
}
static int SocketSetNonBlock(int sfd)
{
int ret = fcntl(sfd, F_GETFL, 0);
ICUNIT_ASSERT_EQUAL(ret < 0, 0, errno);
ret = fcntl(sfd, F_SETFL, ret | O_NONBLOCK);
ICUNIT_ASSERT_EQUAL(ret < 0, 0, errno);
return ICUNIT_SUCCESS;
}
static int SocketNullTest(void)
{
int sfd;
sighandler_t oldHdl = signal(SIGPIPE, SIG_IGN);
sfd = socket(PF_INET, SOCK_DGRAM, 0);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, errno);
LogPrintln("UDP socket: %d", sfd);
(void)SocketSetNonBlock(sfd);
(void)SocketNullTestInternal(sfd);
(void)close(sfd);
sfd = socket(PF_INET, SOCK_STREAM, 0);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, errno);
LogPrintln("TCP socket: %d", sfd);
(void)SocketSetNonBlock(sfd);
(void)SocketNullTestInternal(sfd);
(void)close(sfd);
(void)signal(SIGPIPE, oldHdl);
return ICUNIT_SUCCESS;
}
void NetSocketTest012(void)
{
TEST_ADD_CASE(__FUNCTION__, SocketNullTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}

View File

@@ -0,0 +1,336 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions 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.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <osTest.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <sys/ioctl.h>
#define SERVER_PORT 9999
#define INVALID_SOCKET -1
#define CLIENT_NUM 1
static int gFds[FD_SETSIZE];
static int gBye;
static void InitFds()
{
for (int i = 0; i < FD_SETSIZE; ++i) {
gFds[i] = INVALID_SOCKET;
}
}
static void GetReadfds(fd_set *fds, int *nfd)
{
for (int i = 0; i < FD_SETSIZE; i++) {
if (gFds[i] == INVALID_SOCKET) {
continue;
}
FD_SET(gFds[i], fds);
if (*nfd < gFds[i]) {
*nfd = gFds[i];
}
}
}
static int AddFd(int fd)
{
for (int i = 0; i < FD_SETSIZE; ++i) {
if (gFds[i] == INVALID_SOCKET) {
gFds[i] = fd;
return 0;
}
}
return -1;
}
static void DelFd(int fd)
{
for (int i = 0; i < FD_SETSIZE; ++i) {
if (gFds[i] == fd) {
gFds[i] = INVALID_SOCKET;
}
}
(void)close(fd);
}
static int CloseAllFd(void)
{
for (int i = 0; i < FD_SETSIZE; ++i) {
if (gFds[i] != INVALID_SOCKET) {
(void)close(gFds[i]);
gFds[i] = INVALID_SOCKET;
}
}
return 0;
}
static int HandleRecv(int fd)
{
char buf[256];
int ret = recv(fd, buf, sizeof(buf)-1, 0);
if (ret < 0) {
LogPrintln("[%d]Error: %s", fd, strerror(errno));
DelFd(fd);
} else if (ret == 0) {
LogPrintln("[%d]Closed", fd);
DelFd(fd);
} else {
buf[ret] = 0;
LogPrintln("[%d]Received: %s", fd, buf);
if (strstr(buf, "Bye") != NULL) {
gBye++;
}
}
return -(ret < 0);
}
static int HandleReadfds(fd_set *fds, int lsfd)
{
int ret = 0;
for (int i = 0; i < FD_SETSIZE; ++i) {
if (gFds[i] == INVALID_SOCKET || !FD_ISSET(gFds[i], fds)) {
continue;
}
ret += HandleRecv(gFds[i]);
}
return ret;
}
static unsigned int GetIp(int sfd, const char *ifname)
{
struct ifreq ifr;
unsigned int ip = 0;
int ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name) - 1, ifname, sizeof(ifr.ifr_name) - 1);
if (ret < 0) {
return 0;
}
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
ret = ioctl(sfd, SIOCGIFADDR, &ifr);
if (ret == 0) {
ip = ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr.s_addr;
}
return ip;
}
static unsigned int GetNetmask(int sfd, const char *ifname)
{
struct ifreq ifr;
unsigned int msk = 0;
int ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name) - 1, ifname, sizeof(ifr.ifr_name) - 1);
if (ret < 0) {
return 0;
}
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
ret = ioctl(sfd, SIOCGIFNETMASK, &ifr);
if (ret == 0) {
msk = ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr.s_addr;
}
return msk;
}
static char *MyInetNtoa(unsigned int ip)
{
struct in_addr in = {ip};
return inet_ntoa(in);
}
static void *ClientsThread(void *param)
{
int fd;
int thrNo = (int)(intptr_t)param;
int ret;
const char *ifname[] = {"eth0", "wlan0", "et1", "wl1", "enp4s0f0"};
unsigned int ip, msk, brdcast;
LogPrintln("<%d>socket client thread started", thrNo);
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (fd == INVALID_SOCKET) {
perror("socket");
return NULL;
}
int broadcast = 1;
ret = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
if (ret != 0) {
LogPrintln("[%d]<%d> set broadcast option fail", fd, thrNo);
close(fd);
return NULL;
}
for (int j = 0; j < sizeof(ifname) / sizeof(ifname[0]); ++j) {
ip = GetIp(fd, ifname[j]);
msk = GetNetmask(fd, ifname[j]);
if (ip != 0) {
LogPrintln("[%d]<%d>%s: ip %s", fd, thrNo, ifname[j], MyInetNtoa(ip));
LogPrintln("[%d]<%d>%s: netmask %s", fd, thrNo, ifname[j], MyInetNtoa(msk));
break;
}
}
brdcast = ip | ~msk;
LogPrintln("[%d]<%d>broadcast address %s", fd, thrNo, MyInetNtoa(brdcast));
struct sockaddr_in sa;
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = brdcast;
sa.sin_port = htons(SERVER_PORT);
if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
perror("connect");
return NULL;
}
LogPrintln("[%d]<%d>connected to udp://%s:%d successful", fd, thrNo, inet_ntoa(sa.sin_addr), SERVER_PORT);
const char *msg[] = {
"hello, ",
"ohos, ",
"my name is net_socket_test_013, ",
"see u next time, ",
"Bye!"
};
for (int i = 0; i < sizeof(msg) / sizeof(msg[0]); ++i) {
if (send(fd, msg[i], strlen(msg[i]), 0) < 0) {
LogPrintln("[%d]<%d>send msg [%s] fail: errno %d", fd, thrNo, msg[i], errno);
}
}
(void)shutdown(fd, SHUT_RDWR);
(void)close(fd);
return param;
}
static int StartClients(pthread_t *cli, int cliNum)
{
int ret;
pthread_attr_t attr;
for (int i = 0; i < cliNum; ++i) {
ret = pthread_attr_init(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_create(&cli[i], &attr, ClientsThread, (void *)(intptr_t)i);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_attr_destroy(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
}
return 0;
}
static int UdpBrdcastSelectTest(void)
{
struct sockaddr_in sa = {0};
int lsfd;
int ret;
lsfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, errno);
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl(INADDR_ANY);
sa.sin_port = htons(SERVER_PORT);
ret = bind(lsfd, (struct sockaddr *)&sa, sizeof(sa));
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, errno + CloseAllFd());
int broadcast = 1;
ret = setsockopt(lsfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
ICUNIT_ASSERT_EQUAL(ret, 0, errno + CloseAllFd());
int loop = 0;
socklen_t len = sizeof(loop);
ret = getsockopt(lsfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, &len);
ICUNIT_ASSERT_EQUAL(ret, 0, errno + CloseAllFd());
LogPrintln("IP_MULTICAST_LOOP default: %d", loop);
loop = 0;
ret = setsockopt(lsfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
ICUNIT_ASSERT_EQUAL(ret, 0, errno + CloseAllFd());
ret = getsockopt(lsfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, &len);
ICUNIT_ASSERT_EQUAL(ret, 0, errno + CloseAllFd());
LogPrintln("IP_MULTICAST_LOOP changed to: %d", loop);
InitFds();
AddFd(lsfd);
LogPrintln("[%d]Waiting for client to connect on UDP port %d", lsfd, SERVER_PORT);
pthread_t clients[CLIENT_NUM];
ret = StartClients(clients, CLIENT_NUM);
ICUNIT_ASSERT_EQUAL(ret, 0, ret + CloseAllFd());
for ( ; ; ) {
int nfd;
fd_set readfds;
struct timeval timeout;
timeout.tv_sec = 3;
timeout.tv_usec = 0;
nfd = 0;
FD_ZERO(&readfds);
GetReadfds(&readfds, &nfd);
ret = select(nfd + 1, &readfds, NULL, NULL, &timeout);
LogPrintln("select %d", ret);
if (ret == -1) {
perror("select");
break; // error occurred
} else if (ret == 0) {
break; // timed out
}
if (HandleReadfds(&readfds, lsfd) < 0) {
break;
}
}
for (int i = 0; i < CLIENT_NUM; ++i) {
ret = pthread_join(clients[i], NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret + CloseAllFd());
}
ICUNIT_ASSERT_EQUAL(gBye, CLIENT_NUM, gBye + CloseAllFd());
(void)CloseAllFd();
return ICUNIT_SUCCESS;
}
void NetSocketTest013(void)
{
TEST_ADD_CASE(__FUNCTION__, UdpBrdcastSelectTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}