From 0ff432fcc6e34e62fe0a37ea1cb400471b78cd2c Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Tue, 30 Dec 2014 15:30:59 +0100 Subject: [PATCH] handle read error correctly and remove the WTP --- src/capwap-mitm.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/capwap-mitm.c b/src/capwap-mitm.c index 6644675..f265baa 100644 --- a/src/capwap-mitm.c +++ b/src/capwap-mitm.c @@ -272,6 +272,17 @@ static void capwap_dump(struct sockaddr *src, struct sockaddr *dst, const unsign } +static void remove_wtp(EV_P_ struct wtp *wtp) +{ + ev_timer_stop (EV_A_ &wtp->timeout); + ev_io_stop (EV_A_ &wtp->client_ev); + if (wtp->server.fd) + close(wtp->server.fd); + + RB_REMOVE(wtp_tree, &wtp_tree, wtp); + free(wtp); +} + static void capwap_server_in(EV_P_ struct capwap_port *capwap_port, unsigned char *buffer, ssize_t len, struct sockaddr *addr, socklen_t addrlen); static void capwap_fwd(struct wtp *wtp, unsigned char *buffer, ssize_t len); @@ -288,12 +299,17 @@ static void capwap_server_cb(EV_P_ ev_io *ev, int revents) do { r = recvfrom(ev->fd, buffer, sizeof(buffer), MSG_DONTWAIT, (struct sockaddr *)&addr, &addrlen); if (r < 0) { + struct wtp *wtp; + if (errno == EAGAIN) break; else if (errno == EINTR) continue; debug("capwap read error: %m"); + if ((wtp = RB_FIND(wtp_tree, &wtp_tree, (struct wtp *)&addr))) + remove_wtp(EV_A_ wtp); + return; } else capwap_server_in(EV_A_ capwap_port, buffer, r, (struct sockaddr *)&addr, addrlen); @@ -305,14 +321,7 @@ static void wtp_timeout_cb(EV_P_ ev_timer *w, int revents) struct wtp *wtp = container_of(w, struct wtp, timeout); debug("got timeout for WTP at %p", wtp); - - ev_timer_stop (EV_A_ w); - ev_io_stop (EV_A_ &wtp->client_ev); - if (wtp->server.fd) - close(wtp->server.fd); - - RB_REMOVE(wtp_tree, &wtp_tree, wtp); - free(wtp); + remove_wtp(EV_A_ wtp); } static void capwap_client_cb(EV_P_ ev_io *ev, int revents)