FreeBSD Bugzilla – Attachment 192208 Details for
Bug 227259
accept()/poll() and shutdown()/close() - not work as in FreeBSD10, may broke many apps
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
test tool
acc_test.c (text/plain), 13.46 KB, created by
Ivan Rozhuk
on 2018-04-04 12:44:53 UTC
(
hide
)
Description:
test tool
Filename:
MIME Type:
Creator:
Ivan Rozhuk
Created:
2018-04-04 12:44:53 UTC
Size:
13.46 KB
patch
obsolete
>/*- > * Copyright (c) 2018 Rozhuk Ivan <rozhuk.im@gmail.com> > * 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. > * > * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. > * > * Author: Rozhuk Ivan <rozhuk.im@gmail.com> > * > */ > > >/* cc acc_test.c -O0 -DDEBUG -pthread -o acc_test */ > >#include <sys/param.h> >#include <sys/types.h> >#include <sys/socket.h> >#include <netinet/in.h> >#include <netinet/tcp.h> >#include <arpa/inet.h> >#include <sys/select.h> >#include <sys/event.h> >#include <poll.h> > >#include <inttypes.h> >#include <stdlib.h> /* malloc, exit */ >#include <stdio.h> /* snprintf, fprintf */ >#include <unistd.h> /* close, write, sysconf */ >#include <string.h> /* bcopy, bzero, memcpy, memmove, memset, strerror... */ >#include <time.h> >#include <errno.h> >#include <err.h> >#include <fcntl.h> >#include <pthread.h> >#include <pthread_np.h> > > >#define LOG_ERR(error, descr) \ > if (0 != error) \ > fprintf(stderr, "%s , line: %i, error: %i - %s - %s\n", \ > __FUNCTION__, __LINE__, (error), strerror((error)), (descr)) >#define LOG_EV(descr) \ > fprintf(stdout, "%s , line: %i: %s\n", \ > __FUNCTION__, __LINE__, (descr)) >#define LOG_INFO(descr) \ > fprintf(stdout, "%s\n", (descr)) >#define LOG_ERR_FMT(error, fmt, args...) \ > if (0 != error) \ > fprintf(stderr, "%s , line: %i, error: %i - %s" fmt "\n", \ > __FUNCTION__, __LINE__, (error), strerror((error)), ##args) >#define LOG_EV_FMT(fmt, args...) \ > fprintf(stdout, "%s , line: %i: " fmt "\n", \ > __FUNCTION__, __LINE__, ##args) >#define LOG_INFO_FMT(fmt, args...) \ > fprintf(stdout, fmt"\n", ##args) >#define LOG_ADD(descr) \ > fprintf(stdout, "%s", (descr)); fflush(stdout) > > >typedef enum wait_type_e { > WAIT_ACCEPT, > WAIT_RECV, > WAIT_SELECT, > WAIT_POLL, > WAIT_KQUEUE >} wait_type_t; > >typedef enum event_source_e { > EVS_SHUTDOWN, > EVS_CLOSE >} event_src_t; > >typedef enum socket_create_e { > SC_LOCAL, > SC_REMOTE >} skt_create_t; > >typedef enum event_gegerate_time_e { > EVGT_AFTER_WAIT, > EVGT_BEFORE_WAIT >} ev_gent_t; > >typedef struct test_params_s { > skt_create_t remote_skt; /* Create socket in thread where wait it. */ > int so_family; /* AF_INET */ > int non_block; > ev_gent_t event_gen_time; > wait_type_t wait; > event_src_t ev_src; >} test_prm_t, *test_prm_p; > >typedef struct test_data_s { > size_t port_add; > int skt; > test_prm_p tprm; > volatile int result; >} test_d_t, *test_d_p; > > >static test_prm_t test_prm[] = { > { SC_LOCAL, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_ACCEPT, EVS_SHUTDOWN }, > { SC_REMOTE, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_ACCEPT, EVS_SHUTDOWN }, > //{ SC_LOCAL, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_RECV, EVS_SHUTDOWN }, > //{ SC_REMOTE, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_RECV, EVS_SHUTDOWN }, > { SC_LOCAL, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_SELECT, EVS_SHUTDOWN }, > { SC_REMOTE, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_SELECT, EVS_SHUTDOWN }, > { SC_LOCAL, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_POLL, EVS_SHUTDOWN }, > { SC_REMOTE, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_POLL, EVS_SHUTDOWN }, > { SC_LOCAL, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_KQUEUE, EVS_SHUTDOWN }, > { SC_REMOTE, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_KQUEUE, EVS_SHUTDOWN }, > { SC_LOCAL, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_ACCEPT, EVS_CLOSE }, > { SC_REMOTE, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_ACCEPT, EVS_CLOSE }, > //{ SC_LOCAL, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_RECV, EVS_CLOSE }, > //{ SC_REMOTE, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_RECV, EVS_CLOSE }, > { SC_LOCAL, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_SELECT, EVS_CLOSE }, > { SC_REMOTE, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_SELECT, EVS_CLOSE }, > { SC_LOCAL, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_POLL, EVS_CLOSE }, > { SC_REMOTE, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_POLL, EVS_CLOSE }, > { SC_LOCAL, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_KQUEUE, EVS_CLOSE }, > { SC_REMOTE, AF_INET, 0, EVGT_AFTER_WAIT, WAIT_KQUEUE, EVS_CLOSE }, > > { SC_LOCAL, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_ACCEPT, EVS_SHUTDOWN }, > { SC_REMOTE, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_ACCEPT, EVS_SHUTDOWN }, > //{ SC_LOCAL, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_RECV, EVS_SHUTDOWN }, > //{ SC_REMOTE, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_RECV, EVS_SHUTDOWN }, > { SC_LOCAL, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_SELECT, EVS_SHUTDOWN }, > { SC_REMOTE, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_SELECT, EVS_SHUTDOWN }, > { SC_LOCAL, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_POLL, EVS_SHUTDOWN }, > { SC_REMOTE, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_POLL, EVS_SHUTDOWN }, > { SC_LOCAL, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_KQUEUE, EVS_SHUTDOWN }, > { SC_REMOTE, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_KQUEUE, EVS_SHUTDOWN }, > { SC_LOCAL, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_ACCEPT, EVS_CLOSE }, > { SC_REMOTE, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_ACCEPT, EVS_CLOSE }, > //{ SC_LOCAL, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_RECV, EVS_CLOSE }, > //{ SC_REMOTE, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_RECV, EVS_CLOSE }, > { SC_LOCAL, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_SELECT, EVS_CLOSE }, > { SC_REMOTE, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_SELECT, EVS_CLOSE }, > { SC_LOCAL, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_POLL, EVS_CLOSE }, > { SC_REMOTE, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_POLL, EVS_CLOSE }, > { SC_LOCAL, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_KQUEUE, EVS_CLOSE },//*/ > { SC_REMOTE, AF_INET, 0, EVGT_BEFORE_WAIT, WAIT_KQUEUE, EVS_CLOSE },//*/ > > { SC_LOCAL, AF_INET, 1, EVGT_AFTER_WAIT, WAIT_ACCEPT, EVS_SHUTDOWN }, > { SC_REMOTE, AF_INET, 1, EVGT_AFTER_WAIT, WAIT_ACCEPT, EVS_SHUTDOWN }, > //{ SC_LOCAL, AF_INET, 1, EVGT_AFTER_WAIT, WAIT_RECV, EVS_SHUTDOWN }, > //{ SC_REMOTE, AF_INET, 1, EVGT_AFTER_WAIT, WAIT_RECV, EVS_SHUTDOWN }, > { SC_LOCAL, AF_INET, 1, EVGT_AFTER_WAIT, WAIT_SELECT, EVS_SHUTDOWN }, > { SC_REMOTE, AF_INET, 1, EVGT_AFTER_WAIT, WAIT_SELECT, EVS_SHUTDOWN }, > { SC_LOCAL, AF_INET, 1, EVGT_AFTER_WAIT, WAIT_POLL, EVS_SHUTDOWN }, > { SC_REMOTE, AF_INET, 1, EVGT_AFTER_WAIT, WAIT_POLL, EVS_SHUTDOWN }, > { SC_LOCAL, AF_INET, 1, EVGT_AFTER_WAIT, WAIT_KQUEUE, EVS_SHUTDOWN }, > { SC_REMOTE, AF_INET, 1, EVGT_AFTER_WAIT, WAIT_KQUEUE, EVS_SHUTDOWN }, > > { SC_LOCAL, AF_INET, 1, EVGT_BEFORE_WAIT, WAIT_ACCEPT, EVS_SHUTDOWN }, > //{ SC_LOCAL, AF_INET, 1, EVGT_BEFORE_WAIT, WAIT_RECV, EVS_SHUTDOWN }, > { SC_LOCAL, AF_INET, 1, EVGT_BEFORE_WAIT, WAIT_SELECT, EVS_SHUTDOWN }, > { SC_LOCAL, AF_INET, 1, EVGT_BEFORE_WAIT, WAIT_POLL, EVS_SHUTDOWN }, > { SC_LOCAL, AF_INET, 1, EVGT_BEFORE_WAIT, WAIT_KQUEUE, EVS_SHUTDOWN }, > > { SC_LOCAL, 0, 0, 0, 0, 0 } >}; > >/* Set file/socket to non blocking mode */ >static int >fd_set_nonblocking(int fd, int nonblocked) { > int opts; > > if (-1 == fd) > return (EINVAL); > > opts = fcntl(fd, F_GETFL); /* Read current options. */ > if (-1 == opts) > return (errno); > if (0 == nonblocked) { > if (0 == (opts & O_NONBLOCK)) > return (0); /* Allready set. */ > opts &= ~O_NONBLOCK; > } else { > if (0 != (opts & O_NONBLOCK)) > return (0); /* Allready set. */ > opts |= O_NONBLOCK; > } > if (-1 == fcntl(fd, F_SETFL, opts)) /* Update options. */ > return (errno); > > return (0); >} > >static int >socket_create_listen(int family, int type, int proto, int non_block, uint16_t port, int *skt_ret) { > int error = 0, on = 1, skt; > socklen_t addrlen = 0; > struct sockaddr_storage addr; > > if (NULL == skt_ret) > return (EINVAL); > > skt = socket(family, type, proto); > if (-1 == skt) { > error = errno; > goto err_out; > } > /* Tune socket. */ > setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int)); >#ifdef SO_REUSEPORT > setsockopt(skt, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(int)); >#endif > if (0 != fd_set_nonblocking(skt, non_block)) { > error = errno; > goto err_out; > } > /* Prepare socket. */ > memset(&addr, 0x00, sizeof(struct sockaddr_storage)); > switch (family) { > case AF_INET: > addrlen = sizeof(struct sockaddr_in); > ((struct sockaddr_in*)&addr)->sin_len = addrlen; > ((struct sockaddr_in*)&addr)->sin_family = AF_INET; > ((struct sockaddr_in*)&addr)->sin_port = htons(port); > break; > case AF_INET6: > addrlen = sizeof(struct sockaddr_in6); > ((struct sockaddr_in6*)&addr)->sin6_len = addrlen; > ((struct sockaddr_in6*)&addr)->sin6_family = AF_INET6; > ((struct sockaddr_in6*)&addr)->sin6_port = htons(port); > break; > } > if (-1 == bind(skt, (struct sockaddr*)&addr, addrlen)) { > error = errno; > goto err_out; > } > if (-1 == listen(skt, -1)) { > error = errno; > goto err_out; > } > >err_out: > if (0 != error) { > close(skt); > skt = -1; > } > (*skt_ret) = skt; > > return (error); >} > >static void * >thread_wait_proc(void *data) { > test_d_p td = (test_d_p)data; > int error = 0, skt_new, kq_fd; > struct sockaddr_storage addr; > socklen_t addrlen; > fd_set sfds; > struct pollfd pfds; > struct kevent kev; > > td->result = -1; > > if (SC_REMOTE == td->tprm->remote_skt) { > /* Create socket. */ > LOG_ADD(" rskt "); > error = socket_create_listen(td->tprm->so_family, > SOCK_STREAM, IPPROTO_TCP, td->tprm->non_block, > (55556 + td->port_add), &td->skt); > if (0 != error) > goto err_out; > } > > switch (td->tprm->wait) { > case WAIT_ACCEPT: > LOG_ADD(" accept "); > addrlen = sizeof(struct sockaddr_storage); > skt_new = accept(td->skt, (struct sockaddr*)&addr, &addrlen); > error = errno; > break; > case WAIT_RECV: > LOG_ADD(" recv "); > addrlen = sizeof(struct sockaddr_storage); > if (-1 == recv(td->skt, &addr, addrlen, 0)) { > error = errno; > } > break; > case WAIT_SELECT: > LOG_ADD(" select "); > FD_ZERO(&sfds); > FD_SET(td->skt, &sfds); > if (-1 == select(1, &sfds, &sfds, &sfds, NULL)) { > error = errno; > } > break; > case WAIT_POLL: > LOG_ADD(" poll "); > pfds.fd = td->skt; > pfds.events = (POLLIN | POLLPRI | POLLRDNORM | POLLWRNORM | POLLRDBAND | POLLWRBAND); > pfds.revents = 0; > if (-1 == poll(&pfds, 1, INFTIM) || > 0 != pfds.revents) { > error = errno; > } > break; > case WAIT_KQUEUE: > LOG_ADD(" kqueue "); > kq_fd = kqueue(); > if (-1 == kq_fd) { > error = errno; > break; > } > EV_SET(&kev, td->skt, EVFILT_READ, EV_ADD, 0, 0, NULL); > if (-1 == kevent(kq_fd, &kev, 1, NULL, 0, NULL)) { > error = errno; > } else { > if (EV_ERROR & kev.flags) { > error = (int)kev.data; > } else if (-1 == kevent(kq_fd, NULL, 0, &kev, 1, NULL)) { > error = errno; > } > } > close(kq_fd); > break; > } > >err_out: > if (0 > error) { > error = 0; /* Silence some errors, neg codes recerved for int use. */ > } > td->result = error; > > return (NULL); >} > > >int >main(int argc __unused, char *argv[] __unused) { > int error = 0; > size_t i; > pthread_t tid = NULL; > test_d_p td; > struct timespec abstime; > > > abstime.tv_sec = 1; > abstime.tv_nsec = 0; > for (i = 0; 0 != test_prm[i].so_family; i ++) { > if (EVGT_BEFORE_WAIT == test_prm[i].event_gen_time && > SC_REMOTE == test_prm[i].remote_skt) > continue; /* Skip, always fail. */ > if (EVGT_BEFORE_WAIT == test_prm[i].event_gen_time && > EVS_CLOSE == test_prm[i].ev_src) > continue; /* Skip, always fail. */ > if (0 != test_prm[i].non_block && > WAIT_ACCEPT == test_prm[i].wait) > continue; /* Skip, always OK, by design. */ > fprintf(stdout, "%zu: socket(%s, %s) ...", > i, ((AF_INET == test_prm[i].so_family) ? "AF_INET" : "AF_INET6"), > ((0 != test_prm[i].non_block) ? "nblock" : "block")); > fflush(stdout); > > td = calloc(1, sizeof(test_d_t)); > if (NULL == td) { > error = errno; > LOG_ERR(error, "calloc()"); > continue; > } > td->port_add = i; > td->result = -2; > td->tprm = &test_prm[i]; > > if (SC_LOCAL == test_prm[i].remote_skt) { > /* Create socket. */ > LOG_ADD(" lskt "); > error = socket_create_listen(td->tprm->so_family, > SOCK_STREAM, IPPROTO_TCP, td->tprm->non_block, > (45556 + td->port_add), &td->skt); > if (0 != error) { > LOG_ERR(error, "socket_create_listen()"); > continue; > } > } > > if (EVGT_AFTER_WAIT == test_prm[i].event_gen_time) { > usleep(100000); > if (0 != pthread_create(&tid, NULL, thread_wait_proc, (void*)td)) { > error = errno; > LOG_ERR(error, "pthread_create()"); > continue; > } > usleep(100000); > } > switch (test_prm[i].ev_src) { > case EVS_SHUTDOWN: > LOG_ADD(" shutdown "); > shutdown(td->skt, SHUT_RDWR); > break; > case EVS_CLOSE: > LOG_ADD(" close "); > close(td->skt); > break; > } > if (EVGT_BEFORE_WAIT == test_prm[i].event_gen_time) { > if (0 != pthread_create(&tid, NULL, thread_wait_proc, (void*)td)) { > error = errno; > LOG_ERR(error, "pthread_create()"); > continue; > } > } > > usleep(100000); > LOG_ADD(" chk "); > if (0 != pthread_timedjoin_np(tid, NULL, &abstime)) { > pthread_cancel(tid); > } > if (0 == td->result) { > LOG_INFO("OK"); > } else if (0 < td->result) { > LOG_INFO_FMT("OK, ret code: %i - %s", > td->result, strerror(td->result)); > } else { > LOG_INFO_FMT("FAIL, ret code: %i ", > td->result); > } > } > > return (0); >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 227259
:
192171
|
192208
|
192260