Skip to content

Commit 5c3d71d

Browse files
committed
rpcap: set keepalives on rpcap's control socket
Signed-off-by: Kevin Boulain <[email protected]> Signed-off-by: Gabriel Ganne <[email protected]>
1 parent a0a049c commit 5c3d71d

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

pcap-rpcap.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
#include <stdarg.h> /* for functions with variable number of arguments */
4444
#include <errno.h> /* for the errno variable */
4545
#include <limits.h> /* for INT_MAX */
46+
47+
#ifndef _WIN32
48+
#include <netinet/tcp.h> /* for TCP_KEEP* */
49+
#endif
50+
4651
#include "sockutils.h"
4752
#include "pcap-int.h"
4853
#include "rpcap-protocol.h"
@@ -3536,3 +3541,46 @@ static int rpcap_read_packet_msg(struct pcap_rpcap const *rp, pcap_t *p, size_t
35363541
p->cc = cc;
35373542
return 0;
35383543
}
3544+
3545+
/*
3546+
* Set the keepalives parameters on the control socket.
3547+
* An rpcap-based application may detect more rapidly a network error.
3548+
*
3549+
* It may not be necessary to set them on the data socket as it may use UDP.
3550+
* See pcap_read_nocb_remote for the select logic that will take into
3551+
* account the error on the control socket.
3552+
*/
3553+
int
3554+
pcap_set_control_keepalive(pcap_t *p, int enable, int keepcnt, int keepidle, int keepintvl)
3555+
{
3556+
struct pcap_rpcap *pr = p->priv; /* structure used when doing a remote live capture */
3557+
3558+
if (setsockopt(pr->rmt_sockctrl, SOL_SOCKET, SO_KEEPALIVE, (char *)&enable, sizeof(enable)) < 0)
3559+
{
3560+
sock_geterror("setsockopt(): ", p->errbuf, PCAP_ERRBUF_SIZE);
3561+
return -1;
3562+
}
3563+
3564+
/* when SO_KEEPALIVE isn't active, the following options aren't used */
3565+
if (!enable)
3566+
return 0;
3567+
3568+
#if defined(TCP_KEEPCNT) && defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL)
3569+
if (setsockopt(pr->rmt_sockctrl, IPPROTO_TCP, TCP_KEEPCNT, (char *)&keepcnt, sizeof(keepcnt)) < 0 ||
3570+
setsockopt(pr->rmt_sockctrl, IPPROTO_TCP, TCP_KEEPIDLE, (char *)&keepidle, sizeof(keepidle)) < 0 ||
3571+
setsockopt(pr->rmt_sockctrl, IPPROTO_TCP, TCP_KEEPINTVL, (char *)&keepintvl, sizeof(keepintvl)) < 0)
3572+
{
3573+
sock_geterror("setsockopt(): ", p->errbuf, PCAP_ERRBUF_SIZE);
3574+
return -1;
3575+
}
3576+
#else
3577+
if (keepcnt || keepidle || keepintvl)
3578+
{
3579+
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
3580+
"TCP_KEEPCNT, TCP_KEEPIDLE or TCP_KEEPINTVL not supported on this platform");
3581+
return -1;
3582+
}
3583+
#endif
3584+
3585+
return 0;
3586+
}

pcap/pcap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ PCAP_API int pcap_get_tstamp_precision(pcap_t *);
432432

433433
PCAP_AVAILABLE_1_0
434434
PCAP_API int pcap_activate(pcap_t *);
435+
PCAP_API int pcap_set_control_keepalive(pcap_t *, int, int, int, int);
435436

436437
PCAP_AVAILABLE_1_2
437438
PCAP_API int pcap_list_tstamp_types(pcap_t *, int **);

0 commit comments

Comments
 (0)