diff options
Diffstat (limited to 'thirdparty/apps/testapp/te')
-rw-r--r-- | thirdparty/apps/testapp/te/te.c | 782 |
1 files changed, 782 insertions, 0 deletions
diff --git a/thirdparty/apps/testapp/te/te.c b/thirdparty/apps/testapp/te/te.c new file mode 100644 index 0000000..4f17d29 --- /dev/null +++ b/thirdparty/apps/testapp/te/te.c @@ -0,0 +1,782 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "lb.h" + +#define TEST_ASSERT(cond) do { if(!(cond)) err("%s\n", #cond); } while(0) + +int +test_v6_udp (int argc, const char *argv[]) +{ + int fd, ret; + struct sockaddr_in6 addr = { 0 }; + struct sockaddr_in6 out = { 0 }; + socklen_t len = sizeof (out); + const char *ip = argv[1]; + + fd = _socket (AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + ERR_RETURN (fd < 0, -1, "socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)=%d:%d\n", + fd, errno); + + ret = inet_pton (AF_INET6, ip, &addr.sin6_addr); + ERR_GOTO (ret != 1, CLEAN, "inet_pton(AF_INET6, %s)=%d:%d\n", ip, ret, + errno); + + addr.sin6_family = AF_INET6; + addr.sin6_port = htons (54321); + ret = _bind (fd, (struct sockaddr *) &addr, sizeof (addr)); + ERR_GOTO (ret < 0, CLEAN, "bind(%d, %s, %ld)=%d:%d\n", fd, + f_in6addr (&addr), sizeof (addr), ret, errno); + + ret = _getsockname (fd, (struct sockaddr *) &out, &len); + ERR_GOTO (ret < 0, CLEAN, "getsockname(%d, %s, %d)=%d:%d\n", fd, + f_in6addr (&out), len, ret, errno); + TEST_ASSERT (out.sin6_family == AF_INET6); + TEST_ASSERT (out.sin6_addr.s6_addr32[0] == addr.sin6_addr.s6_addr32[0]); + TEST_ASSERT (out.sin6_addr.s6_addr32[1] == addr.sin6_addr.s6_addr32[1]); + TEST_ASSERT (out.sin6_addr.s6_addr32[2] == addr.sin6_addr.s6_addr32[2]); + TEST_ASSERT (out.sin6_addr.s6_addr32[3] == addr.sin6_addr.s6_addr32[3]); + TEST_ASSERT (out.sin6_port == addr.sin6_port); + + ret = _close (fd); + if (ret) + err ("close(%d)=%d:%d\n", fd, ret, errno); + + return ret; + +CLEAN: + (void) _close (fd); + return -1; +} + +int +test_v4_udp (int argc, const char *argv[]) +{ + int fd, ret; + struct sockaddr_in addr = { 0 }; + struct sockaddr_in out = { 0 }; + socklen_t len = sizeof (out); + const char *ip = argv[1]; + + fd = _socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); + ERR_RETURN (fd < 0, fd, "socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)=%d:%d\n", + fd, errno); + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr (ip); + addr.sin_port = htons (12345); + ret = _bind (fd, (struct sockaddr *) &addr, sizeof (addr)); + ERR_GOTO (ret < 0, CLEAN, "bind(%d, %s, %ld)=%d:%d\n", fd, f_inaddr (&addr), + sizeof (addr), ret, errno); + + ret = _getsockname (fd, (struct sockaddr *) &out, &len); + ERR_GOTO (ret < 0, CLEAN, "getsockname(%d, %s, %d)=%d:%d\n", fd, + f_inaddr (&out), len, ret, errno); + TEST_ASSERT (out.sin_family == AF_INET); + TEST_ASSERT (out.sin_addr.s_addr == addr.sin_addr.s_addr); + TEST_ASSERT (out.sin_port == addr.sin_port); + + ret = _close (fd); + if (ret) + err ("close(%d)=%d:%d\n", fd, ret, errno); + + return ret; + +CLEAN: + (void) _close (fd); + return -1; +} + +int +test_v4_tcp (int argc, const char *argv[]) +{ + int sfd, cfd, afd, ret; + struct sockaddr_in saddr = { 0 }, caddr = + { + 0}, aaddr = + { + 0}, out = + { + 0}; + socklen_t len; + const char *ip = argv[1]; + + sfd = _socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + ERR_RETURN (sfd < 0, sfd, + "sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)=%d:%d\n", sfd, + errno); + + saddr.sin_family = AF_INET; + saddr.sin_addr.s_addr = inet_addr (ip); + saddr.sin_port = htons (23456); + ret = _bind (sfd, (struct sockaddr *) &saddr, sizeof (saddr)); + ERR_GOTO (ret < 0, CLEAN_S, "bind(%d, %s, %ld)=%d:%d\n", sfd, + f_inaddr (&saddr), sizeof (saddr), ret, errno); + + ret = _listen (sfd, 100); + ERR_GOTO (ret < 0, CLEAN_S, "listen(%d, 100)=%d:%d\n", sfd, ret, errno); + + cfd = _socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + ERR_GOTO (cfd < 0, CLEAN_S, + "cfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)=%d:%d\n", cfd, + errno); + + ret = _connect (cfd, (struct sockaddr *) &saddr, sizeof (saddr)); + ERR_GOTO (ret < 0, CLEAN_C, "connect(%d, %s, %ld)=%d:%d\n", cfd, + f_inaddr (&saddr), sizeof (saddr), ret, errno); + + len = sizeof (caddr); + ret = _getsockname (cfd, (struct sockaddr *) &caddr, &len); + TEST_ASSERT (ret == 0); + TEST_ASSERT (len == sizeof (caddr)); + + len = sizeof (aaddr); + afd = _accept (sfd, (struct sockaddr *) &aaddr, &len); + ERR_GOTO (ret < 0, CLEAN_C, "accept(%d, %s, %d)=%d:%d\n", sfd, + f_inaddr (&aaddr), len, ret, errno); + TEST_ASSERT (len == sizeof (caddr)); + + len = sizeof (out); + ret = _getsockname (afd, (struct sockaddr *) &out, &len); + TEST_ASSERT (ret == 0); + TEST_ASSERT (len == sizeof (out)); + TEST_ASSERT (out.sin_family == AF_INET); + TEST_ASSERT (out.sin_addr.s_addr == saddr.sin_addr.s_addr); + TEST_ASSERT (out.sin_port == saddr.sin_port); + + len = sizeof (out); + ret = _getpeername (afd, (struct sockaddr *) &out, &len); + TEST_ASSERT (ret == 0); + TEST_ASSERT (len == sizeof (out)); + TEST_ASSERT (out.sin_family == AF_INET); + TEST_ASSERT (out.sin_addr.s_addr == caddr.sin_addr.s_addr); + TEST_ASSERT (out.sin_port == caddr.sin_port); + + ret = _close (afd); + TEST_ASSERT (ret == 0); + + ret = _close (cfd); + TEST_ASSERT (ret == 0); + + ret = _close (sfd); + TEST_ASSERT (ret == 0); + + return ret; + +CLEAN: + (void) _close (afd); +CLEAN_C: + (void) _close (cfd); +CLEAN_S: + (void) _close (sfd); + return -1; +} + +int +v6_udp_close_select (int argc, const char *argv[]) +{ + int fd, ret; + struct sockaddr_in6 addr = { 0 }; + struct sockaddr_in6 out = { 0 }; + socklen_t len = sizeof (out); + const char *ip = argv[1]; + const char *port = argv[2]; + + fd = _socket (AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + ERR_RETURN (fd < 0, -1, "socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)=%d:%d\n", + fd, errno); + + ret = inet_pton (AF_INET6, ip, &addr.sin6_addr); + ERR_GOTO (ret != 1, CLEAN, "inet_pton(AF_INET6, %s)=%d:%d\n", ip, ret, + errno); + + addr.sin6_family = AF_INET6; + addr.sin6_port = htons (atoi (port)); + ret = _bind (fd, (struct sockaddr *) &addr, sizeof (addr)); + ERR_GOTO (ret < 0, CLEAN, "bind(%d, %s, %ld)=%d:%d\n", fd, + f_in6addr (&addr), sizeof (addr), ret, errno); + + ret = _close (fd); + if (ret) + err ("close(%d)=%d:%d\n", fd, ret, errno); + + { + fd_set rfds, wfds, efds; + int nfds = fd + 1; + FD_ZERO (&rfds); + FD_SET (fd, &rfds); + FD_ZERO (&wfds); + FD_SET (fd, &wfds); + FD_ZERO (&efds); + FD_SET (fd, &efds); + ret = select (nfds, &rfds, &wfds, &efds, NULL); + int err = errno; + TEST_ASSERT (ret == -1); + TEST_ASSERT (err == EBADF); + } + + return 0; + +CLEAN: + (void) _close (fd); + return -1; +} + +int +v6_tcp_server_listen (int argc, const char *argv[]) +{ + return -1; +} + +int +v6_tcp_server_shutdown_rd (int argc, const char *argv[]) +{ + int sfd = -1, afd = -1, ret; + struct sockaddr_in6 saddr = { 0 }, aaddr = + { + 0}; + socklen_t len; + const char *ip = argv[1]; + const char *port = argv[2]; + + sfd = _socket (PF_INET6, SOCK_STREAM, IPPROTO_TCP); + ERR_RETURN (sfd < 0, sfd, + "socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)=%d:%d\n", sfd, + errno); + + saddr.sin6_family = AF_INET6; + ret = inet_pton (AF_INET6, ip, &saddr.sin6_addr); + ERR_GOTO (ret != 1, CLEAN_S, + "inet_pton(AF_INET6, ip=\"%s\", &saddr.sin6_addr)=%d:%d\n", ip, + ret, errno); + saddr.sin6_port = htons (atoi (port)); + + ret = _bind (sfd, (struct sockaddr *) &saddr, sizeof (saddr)); + ERR_GOTO (ret < 0, CLEAN_S, "bind(%d, %s, %ld)=%d:%d\n", sfd, + f_in6addr (&saddr), sizeof (saddr), ret, errno); + + ret = _listen (sfd, 100); + ERR_GOTO (ret < 0, CLEAN_S, "listen(%d, 100)=%d:%d\n", sfd, ret, errno); + + len = sizeof (aaddr); + afd = _accept (sfd, (struct sockaddr *) &aaddr, &len); + ERR_GOTO (ret < 0, CLEAN_S, "accept(%d, %s, %d)=%d:%d\n", sfd, + f_in6addr (&aaddr), len, ret, errno); + + out ("accept(sfd=%d, addr=%s, len=%d)=%d\n", sfd, f_in6addr (&aaddr), len, + afd); + + ret = _shutdown (afd, SHUT_RD); + ERR_GOTO (ret != 0, CLEAN, "shutdown(afd=%d, SHUT_RD)=%d:%d\n", afd, ret, + errno); + + out ("shutdown(afd=%d, SHUT_RD) ok --> sleep(10)\n", afd); + sleep (10); + + out ("closing\n"); + + ret = _close (afd); + TEST_ASSERT (ret == 0); + + ret = _close (sfd); + TEST_ASSERT (ret == 0); + + return ret; + +CLEAN: + (void) _close (afd); +CLEAN_S: + (void) _close (sfd); + return -1; +} + +int +v6_tcp_server_shutdown_wr (int argc, const char *argv[]) +{ + int sfd = -1, afd = -1, ret; + struct sockaddr_in6 saddr = { 0 }, aaddr = + { + 0}; + socklen_t len; + const char *ip = argv[1]; + const char *port = argv[2]; + + sfd = _socket (PF_INET6, SOCK_STREAM, IPPROTO_TCP); + ERR_RETURN (sfd < 0, sfd, + "socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)=%d:%d\n", sfd, + errno); + + saddr.sin6_family = AF_INET6; + ret = inet_pton (AF_INET6, ip, &saddr.sin6_addr); + ERR_GOTO (ret != 1, CLEAN_S, + "inet_pton(AF_INET6, ip=\"%s\", &saddr.sin6_addr)=%d:%d\n", ip, + ret, errno); + saddr.sin6_port = htons (atoi (port)); + + ret = _bind (sfd, (struct sockaddr *) &saddr, sizeof (saddr)); + ERR_GOTO (ret < 0, CLEAN_S, "bind(%d, %s, %ld)=%d:%d\n", sfd, + f_in6addr (&saddr), sizeof (saddr), ret, errno); + + ret = _listen (sfd, 100); + ERR_GOTO (ret < 0, CLEAN_S, "listen(%d, 100)=%d:%d\n", sfd, ret, errno); + + len = sizeof (aaddr); + afd = _accept (sfd, (struct sockaddr *) &aaddr, &len); + ERR_GOTO (ret < 0, CLEAN_S, "accept(%d, %s, %d)=%d:%d\n", sfd, + f_in6addr (&aaddr), len, ret, errno); + + out ("accept(sfd=%d, addr=%s, len=%d)=%d\n", sfd, f_in6addr (&aaddr), len, + afd); + + ret = _shutdown (afd, SHUT_WR); + ERR_GOTO (ret != 0, CLEAN, "shutdown(afd=%d, SHUT_WR)=%d:%d\n", afd, ret, + errno); + + out ("shutdown(afd=%d, SHUT_WR) ok --> sleep(10)\n", afd); + sleep (10); + + out ("closing\n"); + + ret = _close (afd); + TEST_ASSERT (ret == 0); + + ret = _close (sfd); + TEST_ASSERT (ret == 0); + + return ret; + +CLEAN: + (void) _close (afd); +CLEAN_S: + (void) _close (sfd); + return -1; +} + +int +v6_tcp_server_shutdown_rdwr (int argc, const char *argv[]) +{ + int sfd = -1, afd = -1, ret; + struct sockaddr_in6 saddr = { 0 }, aaddr = + { + 0}; + socklen_t len; + const char *ip = argv[1]; + const char *port = argv[2]; + + sfd = _socket (PF_INET6, SOCK_STREAM, IPPROTO_TCP); + ERR_RETURN (sfd < 0, sfd, + "socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)=%d:%d\n", sfd, + errno); + + saddr.sin6_family = AF_INET6; + ret = inet_pton (AF_INET6, ip, &saddr.sin6_addr); + ERR_GOTO (ret != 1, CLEAN_S, + "inet_pton(AF_INET6, ip=\"%s\", &saddr.sin6_addr)=%d:%d\n", ip, + ret, errno); + saddr.sin6_port = htons (atoi (port)); + + ret = _bind (sfd, (struct sockaddr *) &saddr, sizeof (saddr)); + ERR_GOTO (ret < 0, CLEAN_S, "bind(%d, %s, %ld)=%d:%d\n", sfd, + f_in6addr (&saddr), sizeof (saddr), ret, errno); + + ret = _listen (sfd, 100); + ERR_GOTO (ret < 0, CLEAN_S, "listen(%d, 100)=%d:%d\n", sfd, ret, errno); + + len = sizeof (aaddr); + afd = _accept (sfd, (struct sockaddr *) &aaddr, &len); + ERR_GOTO (ret < 0, CLEAN_S, "accept(%d, %s, %d)=%d:%d\n", sfd, + f_in6addr (&aaddr), len, ret, errno); + + out ("accept(sfd=%d, addr=%s, len=%d)=%d\n", sfd, f_in6addr (&aaddr), len, + afd); + + ret = _shutdown (afd, SHUT_RDWR); + ERR_GOTO (ret != 0, CLEAN, "shutdown(afd=%d, SHUT_RDWR)=%d:%d\n", afd, ret, + errno); + + out ("shutdown(afd=%d, SHUT_WR) ok --> sleep(10)\n", afd); + sleep (10); + + out ("closing\n"); + + ret = _close (afd); + TEST_ASSERT (ret == 0); + + ret = _close (sfd); + TEST_ASSERT (ret == 0); + + return ret; + +CLEAN: + (void) _close (afd); +CLEAN_S: + (void) _close (sfd); + return -1; +} + +int +v6_tcp_client_s (int argc, const char *argv[]) +{ + int cfd = -1, ret; + struct sockaddr_in6 saddr = { 0 }; + socklen_t len; + char buf[10] = { 'X', 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + const char *ip = argv[1]; + const char *port = argv[2]; + + cfd = _socket (PF_INET6, SOCK_STREAM, IPPROTO_TCP); + ERR_RETURN (cfd < 0, cfd, + "socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)=%d:%d\n", cfd, + errno); + + saddr.sin6_family = AF_INET6; + ret = inet_pton (AF_INET6, ip, &saddr.sin6_addr); + ERR_GOTO (ret != 1, CLEAN, + "inet_pton(AF_INET6, ip=\"%s\", &saddr.sin6_addr)=%d:%d\n", ip, + ret, errno); + saddr.sin6_port = htons (atoi (port)); + + ret = _connect (cfd, (struct sockaddr *) &saddr, sizeof (saddr)); + ERR_GOTO (ret < 0, CLEAN, "connect(%d, %s, %d)=%d:%d\n", cfd, + f_in6addr (&saddr), len, ret, errno); + out ("connect ok --> sleep(5)\n"); + sleep (5); + + ret = _send (cfd, buf, 10, 0); + out ("send()=%d:%d --> sleep(5)\n", ret, errno); + sleep (5); + + ret = _close (cfd); + TEST_ASSERT (ret == 0); + + return ret; + +CLEAN: + (void) _close (cfd); + return -1; +} + +int +v4_tcp_server_shutdown_rd (int argc, const char *argv[]) +{ + int sfd = -1, afd = -1, ret; + struct sockaddr_in saddr = { 0 }, aaddr = + { + 0}; + socklen_t len; + const char *ip = argv[1]; + const char *port = argv[2]; + + sfd = _socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); + ERR_RETURN (sfd < 0, sfd, + "socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)=%d:%d\n", sfd, + errno); + + saddr.sin_family = AF_INET; + ret = inet_pton (AF_INET, ip, &saddr.sin_addr); + ERR_GOTO (ret != 1, CLEAN_S, + "inet_pton(AF_INET, ip=\"%s\", &saddr.sin_addr)=%d:%d\n", ip, ret, + errno); + saddr.sin_port = htons (atoi (port)); + + ret = _bind (sfd, (struct sockaddr *) &saddr, sizeof (saddr)); + ERR_GOTO (ret < 0, CLEAN_S, "bind(%d, %s, %ld)=%d:%d\n", sfd, + f_inaddr (&saddr), sizeof (saddr), ret, errno); + + ret = _listen (sfd, 100); + ERR_GOTO (ret < 0, CLEAN_S, "listen(%d, 100)=%d:%d\n", sfd, ret, errno); + + len = sizeof (aaddr); + afd = _accept (sfd, (struct sockaddr *) &aaddr, &len); + ERR_GOTO (ret < 0, CLEAN_S, "accept(%d, %s, %d)=%d:%d\n", sfd, + f_inaddr (&aaddr), len, ret, errno); + + out ("accept(sfd=%d, addr=%s, len=%d)=%d\n", sfd, f_inaddr (&aaddr), len, + afd); + sleep (2); + + ret = _shutdown (afd, SHUT_RD); + ERR_GOTO (ret != 0, CLEAN, "shutdown(afd=%d, SHUT_RD)=%d:%d\n", afd, ret, + errno); + + out ("shutdown(afd=%d, SHUT_RD) ok --> sleep(10)\n", afd); + sleep (10); + + out ("closing\n"); + + ret = _close (afd); + TEST_ASSERT (ret == 0); + + ret = _close (sfd); + TEST_ASSERT (ret == 0); + + return ret; + +CLEAN: + (void) _close (afd); +CLEAN_S: + (void) _close (sfd); + return -1; +} + +int +v4_tcp_server_shutdown_wr (int argc, const char *argv[]) +{ + int sfd = -1, afd = -1, ret; + struct sockaddr_in saddr = { 0 }, aaddr = + { + 0}; + socklen_t len; + const char *ip = argv[1]; + const char *port = argv[2]; + + sfd = _socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); + ERR_RETURN (sfd < 0, sfd, + "socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)=%d:%d\n", sfd, + errno); + + saddr.sin_family = AF_INET; + ret = inet_pton (AF_INET, ip, &saddr.sin_addr); + ERR_GOTO (ret != 1, CLEAN_S, + "inet_pton(AF_INET, ip=\"%s\", &saddr.sin_addr)=%d:%d\n", ip, ret, + errno); + saddr.sin_port = htons (atoi (port)); + + ret = _bind (sfd, (struct sockaddr *) &saddr, sizeof (saddr)); + ERR_GOTO (ret < 0, CLEAN_S, "bind(%d, %s, %ld)=%d:%d\n", sfd, + f_inaddr (&saddr), sizeof (saddr), ret, errno); + + ret = _listen (sfd, 100); + ERR_GOTO (ret < 0, CLEAN_S, "listen(%d, 100)=%d:%d\n", sfd, ret, errno); + + len = sizeof (aaddr); + afd = _accept (sfd, (struct sockaddr *) &aaddr, &len); + ERR_GOTO (ret < 0, CLEAN_S, "accept(%d, %s, %d)=%d:%d\n", sfd, + f_inaddr (&aaddr), len, ret, errno); + out ("accept(sfd=%d, addr=%s, len=%d)=%d\n", sfd, f_inaddr (&aaddr), len, + afd); + + ret = _shutdown (afd, SHUT_WR); + ERR_GOTO (ret != 0, CLEAN, "shutdown(afd=%d, SHUT_RD)=%d:%d\n", afd, ret, + errno); + out ("shutdown(afd=%d, SHUT_WR) ok --> sleep(10)\n", afd); + sleep (10); + + out ("closing\n"); + + ret = _close (afd); + TEST_ASSERT (ret == 0); + + ret = _close (sfd); + TEST_ASSERT (ret == 0); + + return ret; + +CLEAN: + (void) _close (afd); +CLEAN_S: + (void) _close (sfd); + return -1; +} + +int +v4_tcp_client_s (int argc, const char *argv[]) +{ + int cfd = -1, ret; + struct sockaddr_in saddr = { 0 }; + socklen_t len; + char buf[10] = { 'X', 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + const char *ip = argv[1]; + const char *port = argv[2]; + + cfd = _socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); + ERR_RETURN (cfd < 0, cfd, + "socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)=%d:%d\n", cfd, + errno); + + saddr.sin_family = AF_INET; + ret = inet_pton (AF_INET, ip, &saddr.sin_addr); + ERR_GOTO (ret != 1, CLEAN, + "inet_pton(AF_INET, ip=\"%s\", &saddr.sin_addr)=%d:%d\n", ip, ret, + errno); + saddr.sin_port = htons (atoi (port)); + + ret = _connect (cfd, (struct sockaddr *) &saddr, sizeof (saddr)); + ERR_GOTO (ret < 0, CLEAN, "connect(%d, %s, %d)=%d:%d\n", cfd, + f_inaddr (&saddr), len, ret, errno); + out ("connect ok --> sleep(5)\n"); + sleep (5); + + ret = _send (cfd, buf, 10, 0); + out ("send()=%d:%d --> sleep(5)\n", ret, errno); + sleep (5); + + ret = _close (cfd); + TEST_ASSERT (ret == 0); + + return ret; + +CLEAN: + (void) _close (cfd); + return -1; +} + +int +v6_tcp_server_close_select (int argc, const char *argv[]) +{ + int sfd = -1, afd = -1, ret; + struct sockaddr_in6 saddr = { 0 }, aaddr = + { + 0}; + socklen_t len; + const char *ip = argv[1]; + const char *port = argv[2]; + + sfd = _socket (PF_INET6, SOCK_STREAM, IPPROTO_TCP); + ERR_RETURN (sfd < 0, sfd, + "socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)=%d:%d\n", sfd, + errno); + + saddr.sin6_family = AF_INET6; + ret = inet_pton (AF_INET6, ip, &saddr.sin6_addr); + ERR_GOTO (ret != 1, CLEAN_S, + "inet_pton(AF_INET6, ip=\"%s\", &saddr.sin6_addr)=%d:%d\n", ip, + ret, errno); + saddr.sin6_port = htons (atoi (port)); + + ret = _bind (sfd, (struct sockaddr *) &saddr, sizeof (saddr)); + ERR_GOTO (ret < 0, CLEAN_S, "bind(%d, %s, %ld)=%d:%d\n", sfd, + f_in6addr (&saddr), sizeof (saddr), ret, errno); + + ret = _listen (sfd, 100); + ERR_GOTO (ret < 0, CLEAN_S, "listen(%d, 100)=%d:%d\n", sfd, ret, errno); + + len = sizeof (aaddr); + afd = _accept (sfd, (struct sockaddr *) &aaddr, &len); + ERR_GOTO (ret < 0, CLEAN_S, "accept(%d, %s, %d)=%d:%d\n", sfd, + f_in6addr (&aaddr), len, ret, errno); + + out ("accept(sfd=%d, addr=%s, len=%d)=%d\n", sfd, f_in6addr (&aaddr), len, + afd); + + ret = _close (afd); + ERR_GOTO (ret != 0, CLEAN_S, "close(afd=%d)=%d:%d\n", afd, ret, errno); + out ("close(afd=%d) ok --> sleep(2)\n", afd); + sleep (2); + + { + fd_set rfds, wfds, efds; + int nfds = afd + 1; + FD_ZERO (&rfds); + FD_SET (afd, &rfds); + FD_ZERO (&wfds); + FD_SET (afd, &wfds); + FD_ZERO (&efds); + FD_SET (afd, &efds); + ret = select (nfds, &rfds, &wfds, &efds, NULL); + int err = errno; + TEST_ASSERT (ret == -1); + TEST_ASSERT (err == EBADF); + } + + ret = _close (sfd); + TEST_ASSERT (ret == 0); + + return ret; + +CLEAN: + (void) _close (afd); +CLEAN_S: + (void) _close (sfd); + return -1; +} + +struct config +{ + char opt; + const char *name; + const char *help; + int (*proc) (int argc, const char *argv[]); +}; + +struct config list[] = { + {'l', "v6_tcp_server_listen", "X::X PORT", v6_tcp_server_listen}, + {'L', "v6_tcp_server_listen", "X::X PORT", v6_tcp_server_listen}, + {'-', NULL, NULL, NULL}, + {'c', "v6_tcp_client_s", "X::X PORT", v6_tcp_client_s}, + {'s', "v6_tcp_server_shutdown_rd", "X::X PORT", v6_tcp_server_shutdown_rd}, + {'d', "v6_tcp_server_shutdown_wr", "X::X PORT", v6_tcp_server_shutdown_wr}, + {'f', "v6_tcp_server_shutdown_rdwr", "X::X PORT", + v6_tcp_server_shutdown_rdwr}, + {'-', NULL, NULL, NULL}, + {'1', "v4_tcp_client_s", "X.X.X.X PORT", v4_tcp_client_s}, + {'2', "v4_tcp_server_shutdown_rd", "X.X.X.X PORT", + v4_tcp_server_shutdown_rd}, + {'3', "v4_tcp_server_shutdown_wr", "X.X.X.X PORT", + v4_tcp_server_shutdown_wr}, + {'-', NULL, NULL, NULL}, + {'U', "test_v6_udp", "X::X", test_v6_udp}, + {'u', "test_v4_udp", "X.X.X.X", test_v4_udp}, + {'t', "test_v4_tcp", "X.X.X.X", test_v4_tcp}, + {'-', NULL, NULL, NULL}, + {'b', "v6_udp_close_select", "X::X PORT", v6_udp_close_select}, +}; + +int +usage () +{ + int i; + for (i = 0; i < sizeof (list) / sizeof (list[0]); ++i) + { + if (list[i].opt == '-') + out ("\n"); + else + out ("%c : %s ( %s )\n", list[i].opt, list[i].name, list[i].help); + } + return 0; +} + +int +main (int argc, const char *argv[]) +{ + int i, ret; + + argc--; + argv++; + + if (argc <= 0) + return usage (); + + for (i = 0; i < sizeof (list) / sizeof (list[0]); ++i) + { + if (list[i].opt == '-') + continue; + if (argv[0][0] != list[i].opt) + continue; + + out ("Test %s%s%s begin\n", CH, list[i].name, CC); + ret = list[i].proc (argc, argv); + if (ret) + out ("%sFAILED%s: %s\n", FR__, CC, list[i].name); + else + out ("OK: %s\n", list[i].name); + + out ("\n <<<< over <<<<\n"); + return 0; + } + + return usage (); +} |