summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYacan Liu <liuyacan@corp.netease.com>2022-09-20 14:19:19 +0800
committerFlorin Coras <florin.coras@gmail.com>2022-09-20 16:56:40 +0000
commitf5e0a17c9cca09822296a0ed3196fde36c1ca5f8 (patch)
treeb71e6578c70a82cb5af4e0d9e8f6e76c30d7ff95 /src
parentc872cec3f0b31f7baf36dd50d75c285f0d0f4bec (diff)
vcl: align the RST behaviour with kernel
When ESTABLISHED TCP connection is terminated by an RST packet, EPOLLHUP + EPOLLRDHUP would be updeliever by VCL. If not using VPP, app would receive EPOLLHUP + EPOLLERR + EPOLLIN(if requested) + EPOLLRDHUP(if requested). libevent will interpret the two cases as different EV combinations. Below is the code snippet for libevent v2.12: if (what & EPOLLERR) { ev = EV_READ | EV_WRITE; } else if ((what & EPOLLHUP) && !(what & EPOLLRDHUP)) { ev = EV_READ | EV_WRITE; } else { if (what & EPOLLIN) ev |= EV_READ; if (what & EPOLLOUT) ev |= EV_WRITE; if (what & EPOLLRDHUP) ev |= EV_CLOSED; } Type: fix Signed-off-by: Yacan Liu <liuyacan@corp.netease.com> Change-Id: Ice3d2861183b6ea499f66b727bbe175eeae5cb05
Diffstat (limited to 'src')
-rw-r--r--src/vcl/vppcom.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c
index 05b84d4674b..9644973ce72 100644
--- a/src/vcl/vppcom.c
+++ b/src/vcl/vppcom.c
@@ -516,6 +516,8 @@ vcl_session_reset_handler (vcl_worker_t * wrk,
if (session->session_state != VCL_STATE_CLOSED)
session->session_state = VCL_STATE_DISCONNECT;
+
+ session->flags |= (VCL_SESSION_F_RD_SHUTDOWN | VCL_SESSION_F_WR_SHUTDOWN);
VDBG (0, "session %u [0x%llx]: reset", sid, reset_msg->handle);
return sid;
}
@@ -1067,6 +1069,7 @@ vcl_handle_mq_event (vcl_worker_t * wrk, session_event_t * e)
{
s->flags |= VCL_SESSION_F_PENDING_DISCONNECT;
s->session_state = VCL_STATE_DISCONNECT;
+ s->flags |= (VCL_SESSION_F_RD_SHUTDOWN | VCL_SESSION_F_WR_SHUTDOWN);
vec_add2 (wrk->unhandled_evts_vector, ecpy, 1);
*ecpy = *e;
ecpy->postponed = 1;
@@ -3118,7 +3121,16 @@ vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
}
session_events = s->vep.ev.events;
add_event = 1;
- events[*num_ev].events = EPOLLHUP | EPOLLRDHUP;
+ events[*num_ev].events = EPOLLERR | EPOLLHUP;
+ if ((EPOLLRDHUP & session_events) &&
+ (s->flags & VCL_SESSION_F_RD_SHUTDOWN))
+ {
+ events[*num_ev].events = EPOLLRDHUP;
+ }
+ if ((EPOLLIN & session_events) && (s->flags & VCL_SESSION_F_RD_SHUTDOWN))
+ {
+ events[*num_ev].events |= EPOLLIN;
+ }
session_evt_data = s->vep.ev.data.u64;
break;
case SESSION_CTRL_EVT_UNLISTEN_REPLY: