diff --git a/libsofia-sip-ua/tport/tport.c b/libsofia-sip-ua/tport/tport.c index 339d8e38..06ce0852 100644 --- a/libsofia-sip-ua/tport/tport.c +++ b/libsofia-sip-ua/tport/tport.c @@ -102,6 +102,11 @@ static char const __func__[] = "tport"; #define TP_STACK tp_master->mr_stack +/* Upper bound on how much of a received message is reassembled for HEP + * capture. Large or heavily fragmented messages may be captured truncated; + * raise this if that happens. */ +#define TPORT_CAPT_IOVMAX 80 + /* Define macros for rbtree implementation */ #define TP_LEFT(tp) ((tp)->tp_left) #define TP_RIGHT(tp) ((tp)->tp_right) @@ -2743,8 +2748,17 @@ msg_t *tport_msg_alloc(tport_t const *self, usize_t size) { if (self) { tport_master_t *mr = self->tp_master; - msg_t *msg = mr->mr_tpac->tpac_alloc(mr->mr_stack, mr->mr_log, - NULL, size, self, NULL); + int flags = mr->mr_log; + msg_t *msg; + + /* Capture rebuilds the payload via msg_iovec(), which needs the + * header wire image that only MSG_DO_EXTRACT_COPY preserves. */ + if (mr->mr_capt_sock) { + flags |= MSG_DO_EXTRACT_COPY; + } + + msg = mr->mr_tpac->tpac_alloc(mr->mr_stack, flags, + NULL, size, self, NULL); if (msg) { su_addrinfo_t *mai = msg_addrinfo(msg); su_addrinfo_t const *tai = self->tp_addrinfo; @@ -3056,6 +3070,8 @@ static void tport_parse(tport_t *self, int complete, su_time_t now) if (self->tp_rlogged != msg) self->tp_rlogged = NULL; + if (self->tp_rcaptured != msg) + self->tp_rcaptured = NULL; self->tp_msg = msg; } @@ -3115,6 +3131,26 @@ void tport_deliver(tport_t *self, self->tp_rlogged = msg; } + /* Capture needs the wire image MSG_FLG_EXTRACT_COPY preserves; messages + * allocated before capture was enabled lack it, so skip them. */ + if (!error && self->tp_master->mr_capt_sock && msg != self->tp_rcaptured + && msg_get_flags(msg, MSG_FLG_EXTRACT_COPY)) { + msg_iovec_t iov[TPORT_CAPT_IOVMAX]; + size_t i, iovlen = msg_iovec(msg, iov, TPORT_CAPT_IOVMAX); + size_t bytes = 0; + + for (i = 0; i < iovlen && i < TPORT_CAPT_IOVMAX; i++) { + bytes += iov[i].mv_len; + } + + if (bytes > 0) { + tport_capt_msg(self, msg, bytes, iov, + iovlen < TPORT_CAPT_IOVMAX ? iovlen : TPORT_CAPT_IOVMAX, + "recv"); + } + self->tp_rcaptured = msg; + } + SU_DEBUG_7(("%s(%p): %smsg %p ("MOD_ZU" bytes)" " from " TPN_FORMAT " next=%p\n", __func__, (void *)self, error ? "bad " : "", diff --git a/libsofia-sip-ua/tport/tport_internal.h b/libsofia-sip-ua/tport/tport_internal.h index e77d175d..b24430c0 100644 --- a/libsofia-sip-ua/tport/tport_internal.h +++ b/libsofia-sip-ua/tport/tport_internal.h @@ -212,6 +212,7 @@ struct tport_s { msg_t *tp_msg; /**< Message being received */ msg_t const *tp_rlogged; /**< Last logged when receiving */ + msg_t const *tp_rcaptured; /**< Last HEP-captured when receiving */ su_time_t tp_rtime; /**< Last time received data */ unsigned short tp_ping; /**< Whitespace ping being received */ diff --git a/libsofia-sip-ua/tport/tport_type_sctp.c b/libsofia-sip-ua/tport/tport_type_sctp.c index fba193c9..470178fd 100644 --- a/libsofia-sip-ua/tport/tport_type_sctp.c +++ b/libsofia-sip-ua/tport/tport_type_sctp.c @@ -260,9 +260,6 @@ int tport_recv_sctp(tport_t *self) if (self->tp_master->mr_dump_file) tport_dump_iovec(self, msg, N, iovec, veclen, "recv", "from"); - if (self->tp_master->mr_capt_sock) - tport_capt_msg(self, msg, N, iovec, veclen, "recv"); - msg_recv_commit(msg, N, 0); /* Mark buffer as used */ return 2; diff --git a/libsofia-sip-ua/tport/tport_type_tcp.c b/libsofia-sip-ua/tport/tport_type_tcp.c index db3a76ac..d4af27c0 100644 --- a/libsofia-sip-ua/tport/tport_type_tcp.c +++ b/libsofia-sip-ua/tport/tport_type_tcp.c @@ -353,10 +353,6 @@ int tport_recv_stream(tport_t *self) /* Write the received data to the message dump file */ if (self->tp_master->mr_dump_file) tport_dump_iovec(self, msg, n, iovec, veclen, "recv", "from"); - - if (self->tp_master->mr_capt_sock) - tport_capt_msg(self, msg, n, iovec, veclen, "recv"); - /* Mark buffer as used */ msg_recv_commit(msg, n, n == 0); diff --git a/libsofia-sip-ua/tport/tport_type_tls.c b/libsofia-sip-ua/tport/tport_type_tls.c index 2418e87c..2f3643a4 100644 --- a/libsofia-sip-ua/tport/tport_type_tls.c +++ b/libsofia-sip-ua/tport/tport_type_tls.c @@ -468,9 +468,6 @@ int tport_tls_recv(tport_t *self) if (self->tp_master->mr_dump_file) tport_dump_iovec(self, msg, n, iovec, veclen, "recv", "from"); - if (self->tp_master->mr_capt_sock) - tport_capt_msg(self, msg, n, iovec, veclen, "recv"); - /* Mark buffer as used */ msg_recv_commit(msg, N, 0); diff --git a/libsofia-sip-ua/tport/tport_type_udp.c b/libsofia-sip-ua/tport/tport_type_udp.c index 5a1715b3..8d0f2de7 100644 --- a/libsofia-sip-ua/tport/tport_type_udp.c +++ b/libsofia-sip-ua/tport/tport_type_udp.c @@ -362,9 +362,6 @@ int tport_recv_dgram(tport_t *self) if (self->tp_master->mr_dump_file) tport_dump_iovec(self, msg, n, iovec, veclen, "recv", "from"); - - if (self->tp_master->mr_capt_sock) - tport_capt_msg(self, msg, n, iovec, veclen, "recv"); *sample = *((uint8_t *)iovec[0].mv_base); diff --git a/libsofia-sip-ua/tport/tport_type_ws.c b/libsofia-sip-ua/tport/tport_type_ws.c index a62ec228..0d690663 100644 --- a/libsofia-sip-ua/tport/tport_type_ws.c +++ b/libsofia-sip-ua/tport/tport_type_ws.c @@ -253,9 +253,6 @@ int tport_recv_stream_ws(tport_t *self) if (self->tp_master->mr_dump_file) tport_dump_iovec(self, msg, n, iovec, veclen, "recv", "from"); - if (self->tp_master->mr_capt_sock) - tport_capt_msg(self, msg, n, iovec, veclen, "recv"); - /* Mark buffer as used */ msg_recv_commit(msg, N, 0);