mirror of
https://github.com/Waujito/youtubeUnblock.git
synced 2026-01-01 06:08:49 +03:00
Update userspace interactions
This commit is contained in:
42
mangle.c
42
mangle.c
@@ -59,6 +59,7 @@ nfq_tcp_compute_checksum_ipv4(struct tcphdr *tcph, struct iphdr *iph)
|
|||||||
|
|
||||||
#define printf pr_info
|
#define printf pr_info
|
||||||
#define perror pr_err
|
#define perror pr_err
|
||||||
|
#define lgerror(msg, ret) (pr_err(msg ": %d\n", ret))
|
||||||
#else
|
#else
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <libnetfilter_queue/libnetfilter_queue_ipv4.h>
|
#include <libnetfilter_queue/libnetfilter_queue_ipv4.h>
|
||||||
@@ -67,6 +68,8 @@ nfq_tcp_compute_checksum_ipv4(struct tcphdr *tcph, struct iphdr *iph)
|
|||||||
typedef uint8_t __u8;
|
typedef uint8_t __u8;
|
||||||
typedef uint32_t __u32;
|
typedef uint32_t __u32;
|
||||||
typedef uint16_t __u16;
|
typedef uint16_t __u16;
|
||||||
|
|
||||||
|
#define lgerror(msg, ret) ({errno = -ret; perror(msg);})
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -116,7 +119,6 @@ int tcp4_payload_split(__u8 *pkt, __u32 buflen,
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
hdr->protocol != IPPROTO_TCP ||
|
hdr->protocol != IPPROTO_TCP ||
|
||||||
!(ntohs(hdr->frag_off) & IP_DF) ||
|
|
||||||
tcph_plen < sizeof(struct tcphdr)) {
|
tcph_plen < sizeof(struct tcphdr)) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -148,10 +150,15 @@ int ip4_frag(const __u8 *pkt, __u32 buflen, __u32 payload_offset,
|
|||||||
const __u8 *payload;
|
const __u8 *payload;
|
||||||
__u32 plen;
|
__u32 plen;
|
||||||
__u32 hdr_len;
|
__u32 hdr_len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (ip4_payload_split(
|
if (!frag1 || !f1len || !frag2 || !f2len)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if ((ret = ip4_payload_split(
|
||||||
(__u8 *)pkt, buflen,
|
(__u8 *)pkt, buflen,
|
||||||
&hdr, &hdr_len, (__u8 **)&payload, &plen)) {
|
&hdr, &hdr_len, (__u8 **)&payload, &plen)) < 0) {
|
||||||
|
lgerror("ipv4_frag: TCP Header extract error", ret);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,10 +167,7 @@ int ip4_frag(const __u8 *pkt, __u32 buflen, __u32 payload_offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (payload_offset & ((1 << 3) - 1)) {
|
if (payload_offset & ((1 << 3) - 1)) {
|
||||||
#ifdef USER_SPACE
|
lgerror("ipv4_frag: Payload offset MUST be a multiply of 8!", -EINVAL);
|
||||||
errno = EINVAL;
|
|
||||||
#endif
|
|
||||||
perror("Payload offset MUST be a multiply of 8!");
|
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -232,11 +236,23 @@ int tcp4_frag(const __u8 *pkt, __u32 buflen, __u32 payload_offset,
|
|||||||
__u32 tcph_len;
|
__u32 tcph_len;
|
||||||
__u32 plen;
|
__u32 plen;
|
||||||
const __u8 *payload;
|
const __u8 *payload;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (tcp4_payload_split((__u8 *)pkt, buflen,
|
if (!seg1 || !s1len || !seg2 || !s2len)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if ((ret = tcp4_payload_split((__u8 *)pkt, buflen,
|
||||||
&hdr, &hdr_len,
|
&hdr, &hdr_len,
|
||||||
&tcph, &tcph_len,
|
&tcph, &tcph_len,
|
||||||
(__u8 **)&payload, &plen)) {
|
(__u8 **)&payload, &plen)) < 0) {
|
||||||
|
lgerror("tcp4_frag: tcp4_payload_split", ret);
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!(ntohs(hdr->frag_off) & IP_DF)) {
|
||||||
|
lgerror("tcp4_frag: ip fragmentation is set", -EINVAL);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,7 +267,8 @@ int tcp4_frag(const __u8 *pkt, __u32 buflen, __u32 payload_offset,
|
|||||||
__u32 s2_plen = plen - payload_offset;
|
__u32 s2_plen = plen - payload_offset;
|
||||||
__u32 s2_dlen = s2_plen + hdr_len + tcph_len;
|
__u32 s2_dlen = s2_plen + hdr_len + tcph_len;
|
||||||
|
|
||||||
if (*s1len < s1_dlen || *s2len < s2_dlen) return -ENOMEM;
|
if (*s1len < s1_dlen || *s2len < s2_dlen)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
*s1len = s1_dlen;
|
*s1len = s1_dlen;
|
||||||
*s2len = s2_dlen;
|
*s2len = s2_dlen;
|
||||||
@@ -434,7 +451,7 @@ nextMessage:
|
|||||||
int gen_fake_sni(const struct iphdr *iph, const struct tcphdr *tcph,
|
int gen_fake_sni(const struct iphdr *iph, const struct tcphdr *tcph,
|
||||||
uint8_t *buf, uint32_t *buflen) {
|
uint8_t *buf, uint32_t *buflen) {
|
||||||
|
|
||||||
if (iph == NULL || tcph == NULL || buf == NULL || buflen == NULL)
|
if (!iph || !tcph || !buf || !buflen)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
int ip_len = iph->ihl * 4;
|
int ip_len = iph->ihl * 4;
|
||||||
@@ -444,6 +461,7 @@ int gen_fake_sni(const struct iphdr *iph, const struct tcphdr *tcph,
|
|||||||
|
|
||||||
if (*buflen < dlen)
|
if (*buflen < dlen)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
*buflen = dlen;
|
||||||
|
|
||||||
memcpy(buf, iph, ip_len);
|
memcpy(buf, iph, ip_len);
|
||||||
memcpy(buf + ip_len, fake_sni, data_len);
|
memcpy(buf + ip_len, fake_sni, data_len);
|
||||||
@@ -466,7 +484,5 @@ int gen_fake_sni(const struct iphdr *iph, const struct tcphdr *tcph,
|
|||||||
nfq_ip_set_checksum(niph);
|
nfq_ip_set_checksum(niph);
|
||||||
nfq_tcp_compute_checksum_ipv4(ntcph, niph);
|
nfq_tcp_compute_checksum_ipv4(ntcph, niph);
|
||||||
|
|
||||||
*buflen = dlen;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,9 +68,9 @@ $(APP): $(OBJS) $(LIBNETFILTER_QUEUE) $(LIBMNL)
|
|||||||
@echo 'CCLD $(APP)'
|
@echo 'CCLD $(APP)'
|
||||||
@$(CCLD) $(OBJS) -o $(APP) -L$(DEPSDIR)/lib -lmnl -lnetfilter_queue
|
@$(CCLD) $(OBJS) -o $(APP) -L$(DEPSDIR)/lib -lmnl -lnetfilter_queue
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: %.c $(LIBNETFILTER_QUEUE) $(LIBMNL)
|
$(BUILD_DIR)/%.o: %.c $(LIBNETFILTER_QUEUE) $(LIBMNL) config.h
|
||||||
@echo 'CC $@'
|
@echo 'CC $@'
|
||||||
@$(CC) -c $(CFLAGS) $^ -o $@
|
@$(CC) -c $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
install -d $(PREFIX)/bin/
|
install -d $(PREFIX)/bin/
|
||||||
|
|||||||
@@ -21,22 +21,22 @@
|
|||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <netinet/udp.h>
|
#include <netinet/udp.h>
|
||||||
|
|
||||||
#include <linux/netfilter.h>
|
|
||||||
#include <linux/if_ether.h>
|
#include <linux/if_ether.h>
|
||||||
#include <sys/socket.h>
|
#include <linux/netfilter.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#include "mangle.h"
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "mangle.h"
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
uint32_t queue_start_num;
|
uint32_t queue_start_num;
|
||||||
int rawsocket;
|
int rawsocket;
|
||||||
pthread_mutex_t rawsocket_lock;
|
pthread_mutex_t rawsocket_lock;
|
||||||
int threads;
|
int threads;
|
||||||
} config = {
|
} config = {
|
||||||
.rawsocket = -2,
|
.rawsocket = -2,
|
||||||
.threads=THREADS_NUM
|
.threads = THREADS_NUM
|
||||||
};
|
};
|
||||||
|
|
||||||
static int parse_args(int argc, const char *argv[]) {
|
static int parse_args(int argc, const char *argv[]) {
|
||||||
@@ -160,6 +160,8 @@ static int close_raw_socket(void) {
|
|||||||
#define AVAILABLE_MTU 1384
|
#define AVAILABLE_MTU 1384
|
||||||
|
|
||||||
static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
|
static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (pktlen > AVAILABLE_MTU) {
|
if (pktlen > AVAILABLE_MTU) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Split packet!\n");
|
printf("Split packet!\n");
|
||||||
@@ -171,19 +173,25 @@ static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
|
|||||||
uint32_t buff2_size = MNL_SOCKET_BUFFER_SIZE;
|
uint32_t buff2_size = MNL_SOCKET_BUFFER_SIZE;
|
||||||
|
|
||||||
#if defined(USE_TCP_SEGMENTATION) || defined(RAWSOCK_TCP_FSTRAT)
|
#if defined(USE_TCP_SEGMENTATION) || defined(RAWSOCK_TCP_FSTRAT)
|
||||||
if ((errno = tcp4_frag(pkt, pktlen, AVAILABLE_MTU-128,
|
if ((ret = tcp4_frag(pkt, pktlen, AVAILABLE_MTU-128,
|
||||||
buff1, &buff1_size, buff2, &buff2_size)) < 0)
|
buff1, &buff1_size, buff2, &buff2_size)) < 0) {
|
||||||
return -1;
|
|
||||||
|
errno = -ret;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
#elif defined(USE_IP_FRAGMENTATION) || defined(RAWSOCK_IP_FSTRAT)
|
#elif defined(USE_IP_FRAGMENTATION) || defined(RAWSOCK_IP_FSTRAT)
|
||||||
if ((errno = ip4_frag(pkt, pktlen, AVAILABLE_MTU-128,
|
if ((ret = ip4_frag(pkt, pktlen, AVAILABLE_MTU-128,
|
||||||
buff1, &buff1_size, buff2, &buff2_size)) < 0)
|
buff1, &buff1_size, buff2, &buff2_size)) < 0) {
|
||||||
return -1;
|
|
||||||
|
errno = -ret;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
printf("send_raw_socket: Packet is too big but fragmentation is disabled! "
|
printf("send_raw_socket: Packet is too big but fragmentation is disabled! "
|
||||||
"Pass -DRAWSOCK_TCP_FSTRAT or -DRAWSOCK_IP_FSTRAT as CFLAGS "
|
"Pass -DRAWSOCK_TCP_FSTRAT or -DRAWSOCK_IP_FSTRAT as CFLAGS "
|
||||||
"To enable it only for raw socket\n");
|
"To enable it only for raw socket\n");
|
||||||
return -1;
|
return -EINVAL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int sent = 0;
|
int sent = 0;
|
||||||
@@ -206,22 +214,16 @@ static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
|
|||||||
|
|
||||||
struct iphdr *iph;
|
struct iphdr *iph;
|
||||||
|
|
||||||
if ((errno = ip4_payload_split(
|
if ((ret = ip4_payload_split(
|
||||||
(uint8_t *)pkt, pktlen, &iph, NULL, NULL, NULL)) < 0) {
|
(uint8_t *)pkt, pktlen, &iph, NULL, NULL, NULL)) < 0) {
|
||||||
errno *= -1;
|
errno = -ret;
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int sin_port = 0;
|
|
||||||
|
|
||||||
struct tcphdr *tcph;
|
|
||||||
if (tcp4_payload_split((uint8_t *)pkt, pktlen, NULL, NULL, &tcph, NULL, NULL, NULL) == 0)
|
|
||||||
sin_port = tcph->dest;
|
|
||||||
|
|
||||||
struct sockaddr_in daddr = {
|
struct sockaddr_in daddr = {
|
||||||
.sin_family = AF_INET,
|
.sin_family = AF_INET,
|
||||||
.sin_port = sin_port,
|
/* Always 0 for raw socket */
|
||||||
|
.sin_port = 0,
|
||||||
.sin_addr = {
|
.sin_addr = {
|
||||||
.s_addr = iph->daddr
|
.s_addr = iph->daddr
|
||||||
}
|
}
|
||||||
@@ -235,6 +237,9 @@ static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
|
|||||||
|
|
||||||
pthread_mutex_unlock(&config.rawsocket_lock);
|
pthread_mutex_unlock(&config.rawsocket_lock);
|
||||||
|
|
||||||
|
/* The function will return -errno on error as well as errno value set itself */
|
||||||
|
if (sent < 0) sent = -errno;
|
||||||
|
|
||||||
return sent;
|
return sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,7 +292,11 @@ void *delay_packet_send(void *data) {
|
|||||||
uint32_t pktlen = dpdt->pktlen;
|
uint32_t pktlen = dpdt->pktlen;
|
||||||
|
|
||||||
usleep(dpdt->timer * 1000);
|
usleep(dpdt->timer * 1000);
|
||||||
send_raw_socket(pkt, pktlen);
|
int ret = send_raw_socket(pkt, pktlen);
|
||||||
|
if (ret < 0) {
|
||||||
|
errno = -ret;
|
||||||
|
perror("send delayed raw packet");
|
||||||
|
}
|
||||||
|
|
||||||
free(pkt);
|
free(pkt);
|
||||||
free(dpdt);
|
free(dpdt);
|
||||||
@@ -425,6 +434,8 @@ static int process_packet(const struct packet_data packet, struct queue_data qda
|
|||||||
#ifdef SEG2_DELAY
|
#ifdef SEG2_DELAY
|
||||||
struct dps_t *dpdt = malloc(sizeof(struct dps_t));
|
struct dps_t *dpdt = malloc(sizeof(struct dps_t));
|
||||||
dpdt->pkt = malloc(f1len);
|
dpdt->pkt = malloc(f1len);
|
||||||
|
memcpy(dpdt->pkt, frag1, f1len);
|
||||||
|
dpdt->pktlen = f1len;
|
||||||
dpdt->timer = SEG2_DELAY;
|
dpdt->timer = SEG2_DELAY;
|
||||||
pthread_t thr;
|
pthread_t thr;
|
||||||
pthread_create(&thr, NULL, delay_packet_send, dpdt);
|
pthread_create(&thr, NULL, delay_packet_send, dpdt);
|
||||||
|
|||||||
Reference in New Issue
Block a user