Skip to content

Commit 7333682

Browse files
authored
Capture HEP messages after parsing instead of per recv (#324)
HEP capture fired in each transport's recv hook, on the raw recv buffer. For a datagram that buffer is a whole message, but on a stream (TCP/TLS/WS/SCTP) one `recv` returns an arbitrary slice of the byte stream, so capture emitted byte fragments that did not align with SIP message boundaries: several HEP packets per message, each starting mid-message. Move capture into `tport_deliver()`, which runs once per fully parsed message, and rebuild the wire image with `msg_iovec()`. The five per-transport capture calls are removed. Now every transport produces exactly one HEP packet per SIP message, starting at the request or status line. For `msg_iovec()` to reproduce the header bytes the parser must keep the wire image, so `tport_msg_alloc()` sets `MSG_DO_EXTRACT_COPY` while the capture socket is open; a `tp_rcaptured` marker dedupes the per-message delivery, mirroring `tp_rlogged`.
1 parent 704c49d commit 7333682

7 files changed

Lines changed: 39 additions & 18 deletions

File tree

‎libsofia-sip-ua/tport/tport.c‎

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ static char const __func__[] = "tport";
102102

103103
#define TP_STACK tp_master->mr_stack
104104

105+
/* Upper bound on how much of a received message is reassembled for HEP
106+
* capture. Large or heavily fragmented messages may be captured truncated;
107+
* raise this if that happens. */
108+
#define TPORT_CAPT_IOVMAX 80
109+
105110
/* Define macros for rbtree implementation */
106111
#define TP_LEFT(tp) ((tp)->tp_left)
107112
#define TP_RIGHT(tp) ((tp)->tp_right)
@@ -2743,8 +2748,17 @@ msg_t *tport_msg_alloc(tport_t const *self, usize_t size)
27432748
{
27442749
if (self) {
27452750
tport_master_t *mr = self->tp_master;
2746-
msg_t *msg = mr->mr_tpac->tpac_alloc(mr->mr_stack, mr->mr_log,
2747-
NULL, size, self, NULL);
2751+
int flags = mr->mr_log;
2752+
msg_t *msg;
2753+
2754+
/* Capture rebuilds the payload via msg_iovec(), which needs the
2755+
* header wire image that only MSG_DO_EXTRACT_COPY preserves. */
2756+
if (mr->mr_capt_sock) {
2757+
flags |= MSG_DO_EXTRACT_COPY;
2758+
}
2759+
2760+
msg = mr->mr_tpac->tpac_alloc(mr->mr_stack, flags,
2761+
NULL, size, self, NULL);
27482762
if (msg) {
27492763
su_addrinfo_t *mai = msg_addrinfo(msg);
27502764
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)
30563070

30573071
if (self->tp_rlogged != msg)
30583072
self->tp_rlogged = NULL;
3073+
if (self->tp_rcaptured != msg)
3074+
self->tp_rcaptured = NULL;
30593075

30603076
self->tp_msg = msg;
30613077
}
@@ -3115,6 +3131,26 @@ void tport_deliver(tport_t *self,
31153131
self->tp_rlogged = msg;
31163132
}
31173133

3134+
/* Capture needs the wire image MSG_FLG_EXTRACT_COPY preserves; messages
3135+
* allocated before capture was enabled lack it, so skip them. */
3136+
if (!error && self->tp_master->mr_capt_sock && msg != self->tp_rcaptured
3137+
&& msg_get_flags(msg, MSG_FLG_EXTRACT_COPY)) {
3138+
msg_iovec_t iov[TPORT_CAPT_IOVMAX];
3139+
size_t i, iovlen = msg_iovec(msg, iov, TPORT_CAPT_IOVMAX);
3140+
size_t bytes = 0;
3141+
3142+
for (i = 0; i < iovlen && i < TPORT_CAPT_IOVMAX; i++) {
3143+
bytes += iov[i].mv_len;
3144+
}
3145+
3146+
if (bytes > 0) {
3147+
tport_capt_msg(self, msg, bytes, iov,
3148+
iovlen < TPORT_CAPT_IOVMAX ? iovlen : TPORT_CAPT_IOVMAX,
3149+
"recv");
3150+
}
3151+
self->tp_rcaptured = msg;
3152+
}
3153+
31183154
SU_DEBUG_7(("%s(%p): %smsg %p ("MOD_ZU" bytes)"
31193155
" from " TPN_FORMAT " next=%p\n",
31203156
__func__, (void *)self, error ? "bad " : "",

‎libsofia-sip-ua/tport/tport_internal.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ struct tport_s {
212212

213213
msg_t *tp_msg; /**< Message being received */
214214
msg_t const *tp_rlogged; /**< Last logged when receiving */
215+
msg_t const *tp_rcaptured; /**< Last HEP-captured when receiving */
215216
su_time_t tp_rtime; /**< Last time received data */
216217
unsigned short tp_ping; /**< Whitespace ping being received */
217218

‎libsofia-sip-ua/tport/tport_type_sctp.c‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,6 @@ int tport_recv_sctp(tport_t *self)
260260
if (self->tp_master->mr_dump_file)
261261
tport_dump_iovec(self, msg, N, iovec, veclen, "recv", "from");
262262

263-
if (self->tp_master->mr_capt_sock)
264-
tport_capt_msg(self, msg, N, iovec, veclen, "recv");
265-
266263
msg_recv_commit(msg, N, 0); /* Mark buffer as used */
267264

268265
return 2;

‎libsofia-sip-ua/tport/tport_type_tcp.c‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,10 +353,6 @@ int tport_recv_stream(tport_t *self)
353353
/* Write the received data to the message dump file */
354354
if (self->tp_master->mr_dump_file)
355355
tport_dump_iovec(self, msg, n, iovec, veclen, "recv", "from");
356-
357-
if (self->tp_master->mr_capt_sock)
358-
tport_capt_msg(self, msg, n, iovec, veclen, "recv");
359-
360356

361357
/* Mark buffer as used */
362358
msg_recv_commit(msg, n, n == 0);

‎libsofia-sip-ua/tport/tport_type_tls.c‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -468,9 +468,6 @@ int tport_tls_recv(tport_t *self)
468468
if (self->tp_master->mr_dump_file)
469469
tport_dump_iovec(self, msg, n, iovec, veclen, "recv", "from");
470470

471-
if (self->tp_master->mr_capt_sock)
472-
tport_capt_msg(self, msg, n, iovec, veclen, "recv");
473-
474471
/* Mark buffer as used */
475472
msg_recv_commit(msg, N, 0);
476473

‎libsofia-sip-ua/tport/tport_type_udp.c‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,6 @@ int tport_recv_dgram(tport_t *self)
362362

363363
if (self->tp_master->mr_dump_file)
364364
tport_dump_iovec(self, msg, n, iovec, veclen, "recv", "from");
365-
366-
if (self->tp_master->mr_capt_sock)
367-
tport_capt_msg(self, msg, n, iovec, veclen, "recv");
368365

369366
*sample = *((uint8_t *)iovec[0].mv_base);
370367

‎libsofia-sip-ua/tport/tport_type_ws.c‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,6 @@ int tport_recv_stream_ws(tport_t *self)
253253
if (self->tp_master->mr_dump_file)
254254
tport_dump_iovec(self, msg, n, iovec, veclen, "recv", "from");
255255

256-
if (self->tp_master->mr_capt_sock)
257-
tport_capt_msg(self, msg, n, iovec, veclen, "recv");
258-
259256
/* Mark buffer as used */
260257
msg_recv_commit(msg, N, 0);
261258

0 commit comments

Comments
 (0)