[PACKET_IO]fix coredump for large packets

This commit is contained in:
liuwentan
2022-08-12 17:23:27 +08:00
parent 5c7c2a4052
commit 90542cec2d
6 changed files with 91 additions and 41 deletions

View File

@@ -9,13 +9,20 @@
#include <pthread.h>
#include <unistd.h>
#include <netinet/ether.h>
#include <netinet/ip.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "global_var.h"
#include "logger.h"
#include "packet_io.h"
#include "packet_io_util.h"
#include "session_manager.h"
#include "plugin_manager.h"
#include "http.h"
#include "util_errors.h"
struct worker_thread_ctx
{
@@ -41,7 +48,6 @@ void *worker_thread_cycle(void *arg)
plugin_manager_dispatch(thread_arg->plugin_mgr, session, thread_arg->thread_id);
session = session_manager_fetch_session(thread_arg->session_mgr, session, thread_arg->thread_id);
}
// clean session_manager event queue
packet_io_device_tx(thread_arg->dev, thread_arg->thread_id, &rx_pkt, 1);
}
@@ -52,6 +58,7 @@ void *worker_thread_cycle(void *arg)
// dispatch to trigger polling event
}
#endif
}
return nullptr;
}

View File

@@ -28,6 +28,18 @@ int packet_copy_data(uint8_t *ptr, const uint8_t *pkt_data, uint32_t pkt_len)
return packet_copy_data_offset(ptr, 0, pkt_data, pkt_len);
}
void pio_packet_queue_init(struct pio_packet_queue *q)
{
if (nullptr == q) {
return;
}
q->bot = nullptr;
q->top = nullptr;
q->len = 0;
pthread_mutex_init(&q->mutex_q, nullptr);
}
void pio_packet_enqueue(struct pio_packet_queue *q, struct pio_packet *p)
{
if (nullptr == p)
@@ -104,7 +116,6 @@ int strncpy_safe(char *dst, const char *src, size_t dst_size)
dst[dst_size - 1] = '\0';
} else {
strcpy(dst, src);
dst[slen - 1] = '\0';
}
return 0;

View File

@@ -35,7 +35,8 @@ extern "C"
#define DEFAULT_MTU 1500
#define DEFAULT_PACKET_SIZE (CUSTOM_ZONE_LEN + DEFAULT_MTU + ETHERNET_HEADER_LEN)
#define SIZE_OF_PIO_PACKET (DEFAULT_PACKET_SIZE + sizeof(struct pio_packet))
#define COMMON_SIZE_OF_PIO_PACKET (DEFAULT_PACKET_SIZE + sizeof(struct pio_packet))
#define MAX_SIZE_OF_PIO_PACKET (65535 + sizeof(struct pio_packet))
/**
* @brief pcap_live/pcap_file mode packet structure
@@ -92,6 +93,8 @@ int packet_copy_data(uint8_t *ptr, const uint8_t *pkt_data, uint32_t pkt_len);
*/
uint64_t pio_packet_hash(struct pio_packet *p);
void pio_packet_queue_init(struct pio_packet_queue *);
void pio_packet_enqueue(struct pio_packet_queue *, struct pio_packet *);
struct pio_packet *pio_packet_dequeue(struct pio_packet_queue *);

View File

@@ -106,7 +106,7 @@ static int init_pcap_file(struct pcap_plain_file_info *pfile_info)
if (pcap_setfilter(pfile_info->pcap_handle, &pfile_info->filter) < 0) {
log_error(ST_ERR_BPF, "could not set bpf filter %s for %s",
pcap_geterr(pfile_info->pcap_handle, pfile_info->file_name));
pcap_geterr(pfile_info->pcap_handle), pfile_info->file_name);
pcap_freecode(&pfile_info->filter);
return -1;
}
@@ -205,10 +205,9 @@ static int pcap_file_shared_init(struct pio_pcap_file_device_context *pfile_dev_
pfile_dev_ctx->shared.should_delete = g_engine_instance.config.packet_io.should_delete;
/* init pcap file device packet queue */
memset(pfile_dev_ctx->pkt_queues, 0, sizeof(pfile_dev_ctx->pkt_queues));
for (uint32_t i = 0; i < PKT_QUEUE_MAX_NUM; i++) {
pthread_mutex_init(&pfile_dev_ctx->pkt_queues[i].mutex_q, nullptr);
pio_packet_queue_init(&pfile_dev_ctx->pkt_queues[i]);
}
return 0;
@@ -317,15 +316,25 @@ int pio_pcap_file_device_close(struct packet_io_device *pdev)
void pcap_file_pkt_callback_oneshot(char *user, struct pcap_pkthdr *pkt_hdr, u_char *pkt)
{
struct pio_pcap_file_device_context *pfile_dev_ctx = (struct pio_pcap_file_device_context *)user;
struct pio_packet *p = (struct pio_packet *)malloc(SIZE_OF_PIO_PACKET);
uint32_t p_len = 0;
if (pkt_hdr->caplen < DEFAULT_MTU) {
p_len = COMMON_SIZE_OF_PIO_PACKET;
} else {
p_len = MAX_SIZE_OF_PIO_PACKET;
}
struct pio_packet *p = (struct pio_packet *)malloc(p_len);
if (nullptr == p) {
return;
}
memset(p, 0, SIZE_OF_PIO_PACKET);
memset(p, 0, p_len);
p->pkt_hdr = p;
p->pkt_payload = (uint8_t *)p + CUSTOM_ZONE_LEN;
p->pkt_len = pkt_hdr->caplen;
p->data_link = pfile_dev_ctx->entity.file->data_link;
if (packet_copy_data((uint8_t *)p->pkt_payload, (uint8_t *)pkt, pkt_hdr->caplen)) {
FREE(p);
return;

View File

@@ -17,87 +17,92 @@
#include "util_errors.h"
#include "pio_pcap_live.h"
#include "packet_io.h"
#include "packet_io_util.h"
#define DEFAULT_MAX_PACKET_SIZE 65535
#define TIMEOUT_MS 500
static int pcap_live_init(struct pio_pcap_live_device_context *pcap_live_dev_ctx, const char *dev_name)
static int pcap_live_init(struct pio_pcap_live_device_context *plive_dev_ctx, const char *dev_name)
{
if (nullptr == pcap_live_dev_ctx) {
if (nullptr == plive_dev_ctx) {
return -1;
}
char errbuf[PCAP_ERRBUF_SIZE];
pcap_live_dev_ctx->pcap_handle = pcap_create(dev_name, errbuf);
if (nullptr == pcap_live_dev_ctx->pcap_handle) {
plive_dev_ctx->pcap_handle = pcap_create(dev_name, errbuf);
if (nullptr == plive_dev_ctx->pcap_handle) {
log_error(ST_ERR_PIO_PCAP_LIVE_DEVICE, "could not create pcap handle for %s, error %s",
dev_name, errbuf);
return -1;
}
if (g_engine_instance.config.packet_io.snaplen == 0) {
pcap_live_dev_ctx->pcap_snaplen = DEFAULT_MAX_PACKET_SIZE;
plive_dev_ctx->pcap_snaplen = DEFAULT_MAX_PACKET_SIZE;
} else {
pcap_live_dev_ctx->pcap_snaplen = g_engine_instance.config.packet_io.snaplen;
plive_dev_ctx->pcap_snaplen = g_engine_instance.config.packet_io.snaplen;
}
/* set snaplen */
int res = pcap_set_snaplen(pcap_live_dev_ctx->pcap_handle, pcap_live_dev_ctx->pcap_snaplen);
int res = pcap_set_snaplen(plive_dev_ctx->pcap_handle, plive_dev_ctx->pcap_snaplen);
if (res != 0) {
log_error(ST_ERR_PCAP_SET_SNAPLEN, "could not set snaplen, error:%s",
pcap_geterr(pcap_live_dev_ctx->pcap_handle));
pcap_geterr(plive_dev_ctx->pcap_handle));
return -1;
}
log_info("set snaplen to %d for %s", pcap_live_dev_ctx->pcap_snaplen, dev_name);
log_info("set snaplen to %d for %s", plive_dev_ctx->pcap_snaplen, dev_name);
/* set promisc */
res = pcap_set_promisc(pcap_live_dev_ctx->pcap_handle, g_engine_instance.config.packet_io.promisc);
res = pcap_set_promisc(plive_dev_ctx->pcap_handle, g_engine_instance.config.packet_io.promisc);
if (res != 0) {
log_error(ST_ERR_PCAP_SET_PROMISC, "could not set promisc mode, error:%s",
pcap_geterr(pcap_live_dev_ctx->pcap_handle));
pcap_geterr(plive_dev_ctx->pcap_handle));
return -1;
}
/* set timeout */
res = pcap_set_timeout(pcap_live_dev_ctx->pcap_handle, TIMEOUT_MS);
res = pcap_set_timeout(plive_dev_ctx->pcap_handle, TIMEOUT_MS);
if (res != 0) {
log_error(ST_ERR_PCAP_SET_TIMEOUT, "could not set timeout, error:%s",
pcap_geterr(pcap_live_dev_ctx->pcap_handle));
pcap_geterr(plive_dev_ctx->pcap_handle));
return -1;
}
res = pcap_activate(pcap_live_dev_ctx->pcap_handle);
res = pcap_activate(plive_dev_ctx->pcap_handle);
if (res != 0) {
log_error(ST_ERR_PCAP_ACTIVATE_HANDLE, "could not activate the pcap handle, error:%s",
pcap_geterr(pcap_live_dev_ctx->pcap_handle));
pcap_geterr(plive_dev_ctx->pcap_handle));
return -1;
}
pcap_live_dev_ctx->pcap_state = PCAP_STATE_UP;
plive_dev_ctx->pcap_state = PCAP_STATE_UP;
/* set bpf filter */
if (strlen(g_engine_instance.config.packet_io.bpf_string) != 0) {
res = strncpy_safe(pcap_live_dev_ctx->bpf_string, g_engine_instance.config.packet_io.bpf_string,
sizeof(pcap_live_dev_ctx->bpf_string));
res = strncpy_safe(plive_dev_ctx->bpf_string, g_engine_instance.config.packet_io.bpf_string,
sizeof(plive_dev_ctx->bpf_string));
if (res < 0) {
log_error(ST_ERR_STR_COPY, "pcap_live_dev_ctx bpf string copy failed.");
log_error(ST_ERR_STR_COPY, "plive_dev_ctx bpf string copy failed.");
return -1;
}
if (pcap_compile(pcap_live_dev_ctx->pcap_handle, &pcap_live_dev_ctx->filter,
pcap_live_dev_ctx->bpf_string, 1, 0) < 0) {
if (pcap_compile(plive_dev_ctx->pcap_handle, &plive_dev_ctx->filter,
plive_dev_ctx->bpf_string, 1, 0) < 0) {
log_error(ST_ERR_BPF, "bpf compliation error %s",
pcap_geterr(pcap_live_dev_ctx->pcap_handle));
pcap_geterr(plive_dev_ctx->pcap_handle));
return -1;
}
if (pcap_setfilter(pcap_live_dev_ctx->pcap_handle, &pcap_live_dev_ctx->filter) < 0) {
if (pcap_setfilter(plive_dev_ctx->pcap_handle, &plive_dev_ctx->filter) < 0) {
log_error(ST_ERR_BPF, "could not set bpf filter %s",
pcap_geterr(pcap_live_dev_ctx->pcap_handle));
pcap_geterr(plive_dev_ctx->pcap_handle));
return -1;
}
}
pcap_live_dev_ctx->data_link = pcap_datalink(pcap_live_dev_ctx->pcap_handle);
plive_dev_ctx->data_link = pcap_datalink(plive_dev_ctx->pcap_handle);
for (uint32_t i = 0; i < PKT_QUEUE_MAX_NUM; i++) {
pio_packet_queue_init(&plive_dev_ctx->pkt_queues[i]);
}
return res;
}
@@ -152,15 +157,25 @@ int pio_pcap_live_device_close(struct packet_io_device *pdev)
static void pcap_live_pkt_callback_oneshot(char *user, struct pcap_pkthdr *pkt_hdr, u_char *pkt)
{
struct pio_pcap_live_device_context *plive_dev_ctx = (struct pio_pcap_live_device_context *)user;
struct pio_packet *p = (struct pio_packet *)malloc(SIZE_OF_PIO_PACKET);
uint32_t p_len = 0;
if (pkt_hdr->caplen < DEFAULT_MTU) {
p_len = COMMON_SIZE_OF_PIO_PACKET;
} else {
p_len = MAX_SIZE_OF_PIO_PACKET;
}
struct pio_packet *p = (struct pio_packet *)malloc(p_len);
if (nullptr == p) {
return;
}
memset(p, 0, sizeof(SIZE_OF_PIO_PACKET));
memset(p, 0, p_len);
p->pkt_hdr = p;
p->pkt_payload = (uint8_t *)p + CUSTOM_ZONE_LEN;
p->pkt_len = pkt_hdr->caplen;
p->data_link = plive_dev_ctx->data_link;
if (packet_copy_data((uint8_t *)p->pkt_payload, (uint8_t *)pkt, pkt_hdr->caplen)) {
FREE(p);
return;
@@ -199,16 +214,19 @@ int pio_pcap_live_device_receive(struct packet_io_device *pdev, uint16_t rxq_id,
} else {
struct pio_packet *p = nullptr;
int i = 0;
uint32_t q_len = 0;
pthread_mutex_lock(&plive_dev_ctx->pkt_queues[rxq_id].mutex_q);
do {
p = pio_packet_dequeue(&plive_dev_ctx->pkt_queues[rxq_id]);
q_len = plive_dev_ctx->pkt_queues[rxq_id].len;
pkts[i] = (struct stellar_packet *)p;
printf("rxq_id:%d, i:%d, pkts[i]:%p\n", rxq_id, i, pkts[i]);
i++;
} while (p != nullptr && (i < nr_pkts));
} while ((q_len != 0) && (i < nr_pkts));
pthread_mutex_unlock(&plive_dev_ctx->pkt_queues[rxq_id].mutex_q);
if (nullptr == p) {
res = i - 1;
if (q_len == 0) {
res = i;
} else {
res = nr_pkts;
}
@@ -240,9 +258,11 @@ int pio_pcap_live_device_send(struct packet_io_device *pdev, uint16_t txq_id, st
void pio_pcap_live_device_pkt_free(__unused struct packet_io_device *pdev, __unused uint16_t qid, struct stellar_packet **pkts, int nr_pkts)
{
void **pptr_pkts = (void **)pkts;
for (int i = 0; i < nr_pkts; i++) {
struct pio_packet *p = (struct pio_packet *)pkts[i];
FREE(p);
printf("before free pptr_pkts[%d]:%p\n", i, pptr_pkts[i]);
FREE(pptr_pkts[i]);
printf("after free pptr_pkts[%d]:%p\n", i, pptr_pkts[i]);
}
}

View File

@@ -30,7 +30,7 @@ struct pio_pcap_live_instance_context {
};
/**
* @brief pio_pcap_file_device_context - pcap file device context
* @brief pio_pcap_live_device_context - pcap live device context
*/
struct pio_pcap_live_device_context {
pcap_t *pcap_handle;