@@ -416,7 +416,12 @@ static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr *pkt_header, u_ch
416416 /*
417417 * 'fp->rmt_sockdata' has always to be set before calling the select(),
418418 * since it is cleared by the select()
419+ *
420+ * While not strictly necessary, it's best to include the control socket.
421+ * It allows us to check for a connection drop as the data socket may use UDP
422+ * and as such, is without any mean to report back any error to the client.
419423 */
424+ FD_SET (pr -> rmt_sockctrl , & rfds );
420425 FD_SET (pr -> rmt_sockdata , & rfds );
421426
422427#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
@@ -439,8 +444,22 @@ static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr *pkt_header, u_ch
439444 }
440445 }
441446
447+ /*
448+ * In the rpcap protocol, once the capture starts, the control socket isn't
449+ * used anymore until the capture ends.
450+ * However, it's the only way to check for connection errors
451+ * as the data socket may uses UDP.
452+ */
453+ if (FD_ISSET (pr -> rmt_sockctrl , & rfds )) {
454+ uint8 byte ;
455+ const int nread = sock_recv (pr -> rmt_sockctrl , pr -> ctrl_ssl , & byte , sizeof (byte ),
456+ SOCK_MSG_PEEK | SOCK_EOF_IS_ERROR , p -> errbuf , PCAP_ERRBUF_SIZE );
457+ if (nread == -1 )
458+ return -1 ;
459+ }
460+
442461 /* There is no data waiting, so return '0' */
443- if (retval == 0 )
462+ if (! FD_ISSET ( pr -> rmt_sockdata , & rfds ) )
444463 return 0 ;
445464
446465 /*
0 commit comments