diff options
author | Yacan Liu <liuyacan@corp.netease.com> | 2022-09-20 14:19:19 +0800 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2022-09-20 16:56:40 +0000 |
commit | f5e0a17c9cca09822296a0ed3196fde36c1ca5f8 (patch) | |
tree | b71e6578c70a82cb5af4e0d9e8f6e76c30d7ff95 | |
parent | c872cec3f0b31f7baf36dd50d75c285f0d0f4bec (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
-rw-r--r-- | src/vcl/vppcom.c | 14 |
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: |