vtinf ("(fd %d): TX (%d bytes) - '%s'", conn->fd, tx_bytes, conn->rxbuf);
}
+static vcl_test_session_t *
+vts_accept_ctrl (vcl_test_server_worker_t *wrk, int listen_fd)
+{
+ vcl_test_server_main_t *vsm = &vcl_server_main;
+ const vcl_test_proto_vft_t *tp;
+ vcl_test_session_t *conn;
+ struct epoll_event ev;
+ int rv;
+
+ conn = conn_pool_alloc (wrk);
+ if (!conn)
+ {
+ vtwrn ("No free connections!");
+ return 0;
+ }
+
+ if (vsm->ctrl)
+ conn->cfg = vsm->ctrl->cfg;
+ vcl_test_session_buf_alloc (conn);
+ clock_gettime (CLOCK_REALTIME, &conn->old_stats.stop);
+
+ tp = vcl_test_main.protos[VPPCOM_PROTO_TCP];
+ if (tp->accept (listen_fd, conn))
+ return 0;
+
+ vtinf ("CTRL accepted fd = %d (0x%08x) on listener fd = %d (0x%08x)",
+ conn->fd, conn->fd, listen_fd, listen_fd);
+
+ ev.events = EPOLLET | EPOLLIN;
+ ev.data.u64 = conn - wrk->conn_pool;
+ rv = vppcom_epoll_ctl (wrk->epfd, EPOLL_CTL_ADD, conn->fd, &ev);
+ if (rv < 0)
+ {
+ vterr ("vppcom_epoll_ctl()", rv);
+ return 0;
+ }
+
+ wrk->nfds++;
+
+ return conn;
+}
+
static vcl_test_session_t *
vts_accept_client (vcl_test_server_worker_t *wrk, int listen_fd)
{
vtinf ("Got a connection -- fd = %d (0x%08x) on listener fd = %d (0x%08x)",
conn->fd, conn->fd, listen_fd, listen_fd);
- ev.events = EPOLLIN;
+ ev.events = EPOLLET | EPOLLIN;
ev.data.u64 = conn - wrk->conn_pool;
rv = vppcom_epoll_ctl (wrk->epfd, EPOLL_CTL_ADD, conn->fd, &ev);
if (rv < 0)
print_usage_and_exit ();
}
- if (argc < (optind + 1))
+ if (argc > (optind + 1))
{
- fprintf (stderr, "SERVER: ERROR: Insufficient number of arguments!\n");
+ fprintf (stderr, "Incorrect number of arguments!\n");
print_usage_and_exit ();
}
-
- if (sscanf (argv[optind], "%d", &v) == 1)
- vsm->server_cfg.port = (uint16_t) v;
- else
+ else if (argc > 1 && argc == (optind + 1))
{
- fprintf (stderr, "SERVER: ERROR: Invalid port (%s)!\n", argv[optind]);
- print_usage_and_exit ();
+ if (sscanf (argv[optind], "%d", &v) == 1)
+ vsm->server_cfg.port = (uint16_t) v;
+ else
+ {
+ fprintf (stderr, "Invalid port (%s)!\n", argv[optind]);
+ print_usage_and_exit ();
+ }
}
vcl_test_init_endpoint_addr (vsm);
wrk->nfds--;
if (wrk->nfds)
vts_wrk_cleanup_all (wrk);
+ vcl_server_main.ctrl = 0;
break;
default:
vtfail ("vppcom_epoll_create()", wrk->epfd);
}
- listen_ev.events = EPOLLIN;
+ listen_ev.events = EPOLLET | EPOLLIN;
listen_ev.data.u32 = VCL_TEST_DATA_LISTENER;
rv =
vppcom_epoll_ctl (wrk->epfd, EPOLL_CTL_ADD, wrk->listener.fd, &listen_ev);
*/
if (ep_evts[i].events & (EPOLLHUP | EPOLLRDHUP))
{
- vts_session_cleanup (conn);
- wrk->nfds--;
- if (!wrk->nfds)
+ if (conn == vsm->ctrl)
{
- vtinf ("All client connections closed\n");
- goto done;
+ vtinf ("ctrl session went away");
+ vsm->ctrl = 0;
}
+ vts_session_cleanup (conn);
+ wrk->nfds--;
continue;
}
vtwrn ("ctrl already exists");
continue;
}
- vsm->ctrl = vts_accept_client (wrk, vsm->ctrl_listen_fd);
+ vsm->ctrl = vts_accept_ctrl (wrk, vsm->ctrl_listen_fd);
continue;
}
+
+ /* at this point ctrl session must be valid */
+ ASSERT (vsm->ctrl);
+
if (ep_evts[i].data.u32 == VCL_TEST_DATA_LISTENER)
{
conn = vts_accept_client (wrk, wrk->listener.fd);
if (wrk->epfd < 0)
vtfail ("vppcom_epoll_create()", wrk->epfd);
- listen_ev.events = EPOLLIN;
+ listen_ev.events = EPOLLET | EPOLLIN;
listen_ev.data.u32 = VCL_TEST_CTRL_LISTENER;
rv = vppcom_epoll_ctl (wrk->epfd, EPOLL_CTL_ADD, vsm->ctrl_listen_fd,
&listen_ev);