[PACKET_IO]fix coredump for large packets
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user