mirror of
https://github.com/Zxilly/UA2F.git
synced 2026-01-06 02:25:08 +00:00
fix: add fail fallback for no conntrack environment
This commit is contained in:
parent
8aeec0a2b3
commit
e8b193f0c2
14
src/cli.c
14
src/cli.c
@ -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);
|
||||
}
|
||||
}
|
||||
@ -21,4 +21,6 @@
|
||||
|
||||
void try_print_info(int argc, char *argv[]);
|
||||
|
||||
void require_root();
|
||||
|
||||
#endif // UA2F_CLI_H
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
26
src/ua2f.c
26
src/ua2f.c
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user