fix: add fail fallback for no conntrack environment

This commit is contained in:
Zxilly 2024-07-01 04:10:46 +08:00
parent 8aeec0a2b3
commit e8b193f0c2
No known key found for this signature in database
GPG Key ID: 47AB1DEC841BC6A2
7 changed files with 50 additions and 13 deletions

View File

@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "cli.h"
#include "config.h"
@ -31,19 +32,26 @@ void try_print_info(const int argc, char *argv[]) {
#else
printf("UCI support disabled\n");
#endif
exit(0);
exit(EXIT_SUCCESS);
}
if (strcmp(argv[1], "--help") == 0) {
printf("Usage: ua2f\n");
printf(" --version\n");
printf(" --help\n");
exit(0);
exit(EXIT_SUCCESS);
}
printf("Unknown option: %s\n", argv[1]);
printf("Usage: ua2f\n");
printf(" --version\n");
printf(" --help\n");
exit(1);
exit(EXIT_FAILURE);
}
void require_root() {
if (geteuid() != 0) {
fprintf(stderr, "This program must be run as root\n");
exit(EXIT_FAILURE);
}
}

View File

@ -21,4 +21,6 @@
void try_print_info(int argc, char *argv[]);
void require_root();
#endif // UA2F_CLI_H

View File

@ -68,7 +68,7 @@ static void send_verdict(const struct nf_queue *queue, const struct nf_packet *p
syslog(LOG_ERR, "failed to put nfqueue header");
goto end;
}
nfq_nlmsg_verdict_put(nlh, (int)pkt->packet_id, NF_ACCEPT);
nfq_nlmsg_verdict_put(nlh, pkt->packet_id, NF_ACCEPT);
if (mark.should_set) {
struct nlattr *nest = mnl_attr_nest_start_check(nlh, SEND_BUF_LEN, NFQA_CT);
@ -98,7 +98,7 @@ end:
}
}
static bool conntrack_info_available = true;
bool conntrack_info_available = true;
static bool cache_initialized = false;
static void add_to_cache(const struct nf_packet *pkt) {

View File

@ -3,6 +3,8 @@
#include "third/nfqueue-mnl.h"
extern bool conntrack_info_available;
void init_handler();
void handle_packet(const struct nf_queue *queue, const struct nf_packet *pkt);

View File

@ -80,7 +80,8 @@ struct nlmsghdr *nfqueue_put_header(int queue_num, int msg_type) {
void *buf = malloc(SEND_BUF_LEN);
ASSERT(buf != NULL);
struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
ASSERT(nlh == buf);
ASSERT(nlh != NULL); // fixme: workaround CLion bug
nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | msg_type;
nlh->nlmsg_flags = NLM_F_REQUEST;
@ -566,7 +567,7 @@ nfqueue_receive() while packet object is being processed by another thread.
// Return false on failure
// If queue_len is zero, use default value
bool nfqueue_open(struct nf_queue *q, int queue_num, uint32_t queue_len) {
bool nfqueue_open(struct nf_queue *q, int queue_num, uint32_t queue_len, bool skip_conntrack) {
memset(q, 0, sizeof(*q));
q->queue_num = queue_num;
@ -596,9 +597,11 @@ bool nfqueue_open(struct nf_queue *q, int queue_num, uint32_t queue_len) {
In kernel 4.15 modprobe-only method is not sufficient, rule containing -m conntrack must be used.
Otherwise, conntrack info is not passed by kernel (both NFQA_CT and NFQA_CT_INFO attributes are missing).
*/
if (nfqueue_set_params(q->nl_socket, queue_num, NFQNL_COPY_PACKET, 0xFFFF, queue_len, NFQA_CFG_F_CONNTRACK) < 0) {
LOG_SYSERR("nfqueue_set_params");
return false;
if (!skip_conntrack) {
if (nfqueue_set_params(q->nl_socket, queue_num, NFQNL_COPY_PACKET, 0xFFFF, queue_len, NFQA_CFG_F_CONNTRACK) < 0) {
LOG_SYSERR("nfqueue_set_params");
return false;
}
}
ssize_t sockopt = 1;

View File

@ -240,7 +240,7 @@ nfqueue_receive() while packet object is being processed by another thread.
// Return false on failure
// If queue_len is zero, use default value
bool nfqueue_open(struct nf_queue *q, int queue_num, uint32_t queue_len);
bool nfqueue_open(struct nf_queue *q, int queue_num, uint32_t queue_len, bool skip_conntrack);
void nfqueue_close(struct nf_queue *q);

View File

@ -50,12 +50,32 @@ int read_buffer(struct nf_queue *queue, struct nf_buffer *buf) {
}
}
bool retry_disable_conntrack(struct nf_queue *queue) {
nfqueue_close(queue);
syslog(LOG_INFO, "Retrying to disable conntrack");
const __auto_type ret = nfqueue_open(queue, QUEUE_NUM, 0, true);
if (!ret) {
syslog(LOG_ERR, "Failed to open nfqueue with conntrack disabled");
return false;
}
return true;
}
void main_loop(struct nf_queue *queue) {
struct nf_buffer buf[1] = {0};
bool retried = false;
while (!should_exit) {
if (read_buffer(queue, buf) == IO_ERROR) {
break;
if (!retried) {
retried = true;
if (!retry_disable_conntrack(queue)) {
break;
}
} else {
break;
}
}
}
@ -73,6 +93,8 @@ int main(const int argc, char *argv[]) {
try_print_info(argc, argv);
require_root();
init_statistics();
init_handler();
@ -84,7 +106,7 @@ int main(const int argc, char *argv[]) {
struct nf_queue queue[1] = {0};
const __auto_type ret = nfqueue_open(queue, QUEUE_NUM, 0);
const __auto_type ret = nfqueue_open(queue, QUEUE_NUM, 0, false);
if (!ret) {
syslog(LOG_ERR, "Failed to open nfqueue");
return EXIT_FAILURE;