NFQ 增加 tfe_hexdump2file() 将格式无效的 payload dump 到 stderr

This commit is contained in:
luwenpeng
2021-04-25 14:44:34 +08:00
parent 7ff44ea6f0
commit b667408617

View File

@@ -6,6 +6,7 @@
#include <linux/netfilter.h> // for NF_ACCEPT
#include <libnetfilter_queue/libnetfilter_queue.h>
#include <tfe_utils.h>
#include <tfe_cmsg.h>
#include <proxy.h>
#include <tfe_pkt_util.h>
@@ -65,20 +66,20 @@ static int tcp_restore_info_parse_from_cmsg(const char *data, unsigned int datal
if (header->__magic__[0] != 0x4d || header->__magic__[1] != 0x5a)
{
TFE_LOG_ERROR(g_default_logger, "failed at parser TCP options from cmsg, wrong magic");
TFE_LOG_ERROR(g_default_logger, "Failed at parser TCP options from cmsg, wrong magic");
goto invalid_format;
}
nr_tlvs = ntohs(header->nr_tlvs);
if (nr_tlvs >= 256)
{
TFE_LOG_ERROR(g_default_logger, "failed at parser TCP options from cmsg, numbers of tlvs is larger than 256");
TFE_LOG_ERROR(g_default_logger, "Failed at parser TCP options from cmsg, numbers of tlvs is larger than 256");
goto invalid_format;
}
if (datalen < sizeof(struct tcp_restore_info_header))
{
TFE_LOG_ERROR(g_default_logger, "failed at parser TCP options from cmsg, length is shorter than tlv header");
TFE_LOG_ERROR(g_default_logger, "Failed at parser TCP options from cmsg, length is shorter than tlv header");
goto invalid_format;
}
@@ -97,14 +98,14 @@ static int tcp_restore_info_parse_from_cmsg(const char *data, unsigned int datal
unsigned int __length = tlv_length;
if (datalen < __length)
{
TFE_LOG_ERROR(g_default_logger, "failed at parser TCP options from cmsg, left space is smaller than tlv's length, "
TFE_LOG_ERROR(g_default_logger, "Failed at parser TCP options from cmsg, left space is smaller than tlv's length, "
"datalen is %u, tlv's length is %u", datalen, __length);
goto invalid_format;
}
if (tlv_length < sizeof(uint16_t) * 2)
{
TFE_LOG_ERROR(g_default_logger, "failed at parser TCP options from cmsg, invalid tlv length, should larger than sizeof(type) + sizeof(length)");
TFE_LOG_ERROR(g_default_logger, "Failed at parser TCP options from cmsg, invalid tlv length, should larger than sizeof(type) + sizeof(length)");
goto invalid_format;
}
@@ -115,7 +116,7 @@ static int tcp_restore_info_parse_from_cmsg(const char *data, unsigned int datal
{ \
if (x != tlv_length) \
{ \
TFE_LOG_ERROR(g_default_logger, "failed at parser TCP options from cmsg, invalid tlv length, should be %u, actually is %u", \
TFE_LOG_ERROR(g_default_logger, "Failed at parser TCP options from cmsg, invalid tlv length, should be %u, actually is %u", \
(unsigned int)x, (unsigned int)tlv_length); \
goto invalid_format; \
} \
@@ -304,7 +305,7 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s
struct nfqnl_msg_packet_hdr *ph = nfq_get_msg_packet_hdr(nfa);
if (ph == NULL)
{
TFE_LOG_ERROR(g_default_logger, "failed at nfq_get_msg_packet_hdr(), result is NULL");
TFE_LOG_ERROR(g_default_logger, "Failed at nfq_get_msg_packet_hdr(), result is NULL");
goto end;
}
id = ntohl(ph->packet_id);
@@ -312,7 +313,8 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s
raw_payload_len = nfq_get_payload(nfa, &raw_payload);
if ((unsigned int)raw_payload_len <= (MIN(sizeof(struct iphdr), sizeof(struct ip6_hdr)) + sizeof(struct tcphdr)))
{
TFE_LOG_ERROR(g_default_logger, "failed at nfq_get_payload(), paylod len is %d", raw_payload_len);
TFE_LOG_ERROR(g_default_logger, "Failed at nfq_get_payload(), paylod len %d too small, less than %d", raw_payload_len, (MIN(sizeof(struct iphdr), sizeof(struct ip6_hdr)) + sizeof(struct tcphdr)));
tfe_hexdump2file(stderr, "Failed at parsing payload, payload len too small", raw_payload, (unsigned int)raw_payload_len);
goto end;
}
@@ -325,7 +327,8 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s
}
else
{
TFE_LOG_ERROR(g_default_logger, "failed at parse IPv4 header, sub protocol not tcp");
TFE_LOG_ERROR(g_default_logger, "Failed at parse IPv4 header, sub protocol not tcp");
tfe_hexdump2file(stderr, "Failed at parsing IPv4 header, TCP no found", raw_payload, (unsigned int)raw_payload_len);
goto end;
}
}
@@ -334,21 +337,24 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s
tfe_pkt_parse_ipv6_header(raw_payload, &pktinfo);
if (pktinfo.parse_failed)
{
TFE_LOG_ERROR(g_default_logger, "failed at parse IPv6 header, sub protocol not tcp");
TFE_LOG_ERROR(g_default_logger, "Failed at parse IPv6 header, sub protocol not tcp");
tfe_hexdump2file(stderr, "Failed at parsing IPv6 header, TCP no found", raw_payload, (unsigned int)raw_payload_len);
goto end;
}
}
if (pktinfo.ip_totlen > raw_payload_len)
{
TFE_LOG_ERROR(g_default_logger, "failed at parser IP header, invalid ip header totlen");
TFE_LOG_ERROR(g_default_logger, "Failed at parser IP header, invalid ip header totlen");
tfe_hexdump2file(stderr, "Failed at parsing IP header, IP totlen too small", raw_payload, (unsigned int)raw_payload_len);
goto end;
}
// check if there is a tcp options
if (pktinfo.tcphdr_len <= sizeof(struct tcphdr))
{
TFE_LOG_ERROR(g_default_logger, "failed at parser TCP header, tcp header len too small");
TFE_LOG_ERROR(g_default_logger, "Failed at parser TCP header, TCP header len %d too small, less than %d", pktinfo.tcphdr_len, sizeof(struct tcphdr));
tfe_hexdump2file(stderr, "Failed at parsing TCP header, TCP header len too small", raw_payload, (unsigned int)raw_payload_len);
goto end;
}
@@ -357,7 +363,8 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s
&restore_opt_len, (char *)&cmsg_offset, sizeof(cmsg_offset));
if (!hit_tcpopt || restore_opt_len != 2)
{
TFE_LOG_ERROR(g_default_logger, "failed at parser TCP options, tcp option hit:%d, opt len:%d", hit_tcpopt, restore_opt_len);
TFE_LOG_ERROR(g_default_logger, "Failed at parser TCP options, tcp option hit:%d, opt len:%d", hit_tcpopt, restore_opt_len);
tfe_hexdump2file(stderr, "Failed at parsing TCP options, TCP options no found", raw_payload, (unsigned int)raw_payload_len);
goto end;
}
@@ -369,7 +376,7 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s
ret = tcp_restore_info_parse_from_cmsg(cmsg_payload, cmsg_payload_len, &restore_info);
if (ret < 0)
{
TFE_LOG_ERROR(g_default_logger, "failed at parser TCP options from cmsg");
TFE_LOG_ERROR(g_default_logger, "Failed at parser TCP options from cmsg");
goto end;
}
@@ -400,7 +407,7 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s
fd_upstream = tfe_tcp_restore_fd_create(&(restore_info.client), &(restore_info.server));
if (fd_upstream < 0)
{
TFE_LOG_ERROR(g_default_logger, "failed at tcp_restore_fd_create(UPSTREAM)");
TFE_LOG_ERROR(g_default_logger, "Failed at tcp_restore_fd_create(UPSTREAM)");
goto end;
}
@@ -408,19 +415,19 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s
fd_downstream = tfe_tcp_restore_fd_create(&(restore_info.server), &(restore_info.client));
if (fd_downstream < 0)
{
TFE_LOG_ERROR(g_default_logger, "failed at tcp_restore_fd_create(DOWNSTREAM)");
TFE_LOG_ERROR(g_default_logger, "Failed at tcp_restore_fd_create(DOWNSTREAM)");
goto end;
}
if (tfe_cmsg_deserialize((const unsigned char *)restore_info.cmsg, restore_info.cmsg_len, &cmsg) < 0)
{
TFE_LOG_ERROR(g_default_logger, "failed at tfe_cmsg_deserialize()");
TFE_LOG_ERROR(g_default_logger, "Failed at tfe_cmsg_deserialize()");
goto end;
}
if (tfe_proxy_fds_accept(__ctx->proxy, fd_downstream, fd_upstream, cmsg) < 0)
{
TFE_LOG_ERROR(g_default_logger, "failed at tfe_proxy_fds_accept()");
TFE_LOG_ERROR(g_default_logger, "Failed at tfe_proxy_fds_accept()");
goto end;
}
TFE_PROXY_STAT_INCREASE(STAT_FD_OPEN_BY_KNI_ACCEPT, 2);
@@ -489,7 +496,7 @@ void acceptor_kni_v3_event(evutil_socket_t fd, short what, void *user)
TFE_LOG_ERROR(g_default_logger, "nfqueue losing packets!");
}
TFE_LOG_ERROR(g_default_logger, "failed at recv() data from nfqueue, %d: %s", errno, strerror(errno));
TFE_LOG_ERROR(g_default_logger, "Failed at recv() data from nfqueue, %d: %s", errno, strerror(errno));
}
}
@@ -557,35 +564,35 @@ struct acceptor_kni_v3 *acceptor_kni_v3_create(struct tfe_proxy *proxy, const ch
__ctx->h = nfq_open();
if (!__ctx->h)
{
TFE_LOG_ERROR(g_default_logger, "failed at nfq_open(), %d: %s", errno, strerror(errno));
TFE_LOG_ERROR(g_default_logger, "Failed at nfq_open(), %d: %s", errno, strerror(errno));
errno = 0;
goto __errout;
}
if (nfq_unbind_pf(__ctx->h, AF_INET) < 0)
{
TFE_LOG_ERROR(g_default_logger, "failed at nfq_unbind_pf(AF_INET), %d: %s", errno, strerror(errno));
TFE_LOG_ERROR(g_default_logger, "Failed at nfq_unbind_pf(AF_INET), %d: %s", errno, strerror(errno));
errno = 0;
goto __errout;
}
if (nfq_unbind_pf(__ctx->h, AF_INET6) < 0)
{
TFE_LOG_ERROR(g_default_logger, "failed at nfq_unbind_pf(AF_INET6), %d: %s", errno, strerror(errno));
TFE_LOG_ERROR(g_default_logger, "Failed at nfq_unbind_pf(AF_INET6), %d: %s", errno, strerror(errno));
errno = 0;
goto __errout;
}
if (nfq_bind_pf(__ctx->h, AF_INET) < 0)
{
TFE_LOG_ERROR(g_default_logger, "failed at nfq_bind_pf(AF_INET), %d: %s", errno, strerror(errno));
TFE_LOG_ERROR(g_default_logger, "Failed at nfq_bind_pf(AF_INET), %d: %s", errno, strerror(errno));
errno = 0;
goto __errout;
}
if (nfq_bind_pf(__ctx->h, AF_INET6) < 0)
{
TFE_LOG_ERROR(g_default_logger, "failed at nfq_bind_pf(AF_INET6), %d: %s", errno, strerror(errno));
TFE_LOG_ERROR(g_default_logger, "Failed at nfq_bind_pf(AF_INET6), %d: %s", errno, strerror(errno));
errno = 0;
goto __errout;
}
@@ -593,7 +600,7 @@ struct acceptor_kni_v3 *acceptor_kni_v3_create(struct tfe_proxy *proxy, const ch
__ctx->qh = nfq_create_queue(__ctx->h, __ctx->queue_id, &payload_handler_cb, __ctx);
if (!__ctx->qh)
{
TFE_LOG_ERROR(g_default_logger, "failed at nfq_create_queue(), %d: %s", errno, strerror(errno));
TFE_LOG_ERROR(g_default_logger, "Failed at nfq_create_queue(), %d: %s", errno, strerror(errno));
errno = 0;
goto __errout;
}
@@ -605,14 +612,14 @@ struct acceptor_kni_v3 *acceptor_kni_v3_create(struct tfe_proxy *proxy, const ch
*/
if (nfq_set_mode(__ctx->qh, NFQNL_COPY_PACKET, 0xffff) < 0)
{
TFE_LOG_ERROR(g_default_logger, "failed at nfq_set_mode(NFQNL_COPY_PACKET), %d: %s", errno, strerror(errno));
TFE_LOG_ERROR(g_default_logger, "Failed at nfq_set_mode(NFQNL_COPY_PACKET), %d: %s", errno, strerror(errno));
errno = 0;
goto __errout;
}
if (nfq_set_queue_maxlen(__ctx->qh, __ctx->queue_maxlen) < 0)
{
TFE_LOG_ERROR(g_default_logger, "failed at nfq_set_queue_maxlen(%d), %d: %s", __ctx->queue_maxlen, errno, strerror(errno));
TFE_LOG_ERROR(g_default_logger, "Failed at nfq_set_queue_maxlen(%d), %d: %s", __ctx->queue_maxlen, errno, strerror(errno));
errno = 0;
goto __errout;
}
@@ -629,7 +636,7 @@ struct acceptor_kni_v3 *acceptor_kni_v3_create(struct tfe_proxy *proxy, const ch
{
if (setsockopt(__ctx->fd_nfq_socket, SOL_NETLINK, NETLINK_NO_ENOBUFS, &__ctx->queue_no_enobufs, sizeof(__ctx->queue_no_enobufs)) == -1)
{
TFE_LOG_ERROR(g_default_logger, "failed at setsockopt(NETLINK_NO_ENOBUFS) for nfq fd, %d: %s", errno, strerror(errno));
TFE_LOG_ERROR(g_default_logger, "Failed at setsockopt(NETLINK_NO_ENOBUFS) for nfq fd, %d: %s", errno, strerror(errno));
errno = 0;
goto __errout;
}
@@ -640,28 +647,28 @@ struct acceptor_kni_v3 *acceptor_kni_v3_create(struct tfe_proxy *proxy, const ch
__ctx->ev_base = event_base_new();
if (unlikely(__ctx->ev_base == NULL))
{
TFE_LOG_ERROR(g_default_logger, "failed at event_base_new()");
TFE_LOG_ERROR(g_default_logger, "Failed at event_base_new()");
goto __errout;
}
__ctx->ev_nfq_socket = event_new(__ctx->ev_base, __ctx->fd_nfq_socket, EV_READ | EV_PERSIST, acceptor_kni_v3_event, __ctx);
if (unlikely(__ctx->ev_nfq_socket == NULL))
{
TFE_LOG_ERROR(g_default_logger, "failed at setup READ event for nfqueue socket");
TFE_LOG_ERROR(g_default_logger, "Failed at setup READ event for nfqueue socket");
goto __errout;
}
ret = event_add(__ctx->ev_nfq_socket, NULL);
if (unlikely(ret < 0))
{
TFE_LOG_ERROR(g_default_logger, "failed at adding nfqueue socket event to evbase");
TFE_LOG_ERROR(g_default_logger, "Failed at adding nfqueue socket event to evbase");
goto __errout;
}
ret = pthread_create(&__ctx->thread, NULL, acceptor_kni_v3_event_thread_entry, (void *) __ctx);
if (unlikely(ret < 0))
{
TFE_LOG_ERROR(g_default_logger, "failed at creating event thread: %s", strerror(errno));
TFE_LOG_ERROR(g_default_logger, "Failed at creating event thread: %s", strerror(errno));
errno = 0;
goto __errout;
}