Module for kernel works now on local machine.

SEG2_DELAY is not implemented yet.
This commit is contained in:
Vadim Vetrov 2024-08-04 15:55:07 +03:00
parent 62a5627c50
commit 8bb2bb28d2
No known key found for this signature in database
GPG Key ID: E8A308689D7A73A5
7 changed files with 168 additions and 139 deletions

2
Kbuild
View File

@ -1,3 +1,3 @@
obj-m := ipt_YTUNBLOCK.o obj-m := ipt_YTUNBLOCK.o
ipt_YTUNBLOCK-objs := iptk_YTUNBLOCK.o mangle.o ipt_YTUNBLOCK-objs := iptk_YTUNBLOCK.o mangle.o
ccflags-y := -std=gnu11 -Wno-unused-variable -DKERNEL_SPACE ccflags-y := -std=gnu11 -Wno-unused-variable -DKERNEL_SPACE -DDEBUG

View File

@ -23,6 +23,7 @@
#elif FRAGMENTATION_STRATEGY == FRAG_STRAT_IP #elif FRAGMENTATION_STRATEGY == FRAG_STRAT_IP
#define USE_IP_FRAGMENTATION #define USE_IP_FRAGMENTATION
#elif FRAGMENTATION_STRATEGY == FRAG_STRAT_NONE #elif FRAGMENTATION_STRATEGY == FRAG_STRAT_NONE
#define USE_NO_FRAGMENTATION
#endif #endif
#define RAWSOCKET_MARK (1 << 15) #define RAWSOCKET_MARK (1 << 15)
@ -35,6 +36,7 @@
#define FAKE_SNI #define FAKE_SNI
#endif #endif
#ifndef SILENT #if !defined(SILENT) && !defined(KERNEL_SPACE)
#define DEBUG #define DEBUG
#endif #endif

View File

@ -1,4 +1,3 @@
//
// Kernel module for youtubeUnblock. // Kernel module for youtubeUnblock.
// Make with make kmake && sudo iptables -t mangle -D OUTPUT 1 && sudo make kreload && sudo iptables -t mangle -I OUTPUT -p tcp -j YTUNBLOCK // Make with make kmake && sudo iptables -t mangle -D OUTPUT 1 && sudo make kreload && sudo iptables -t mangle -I OUTPUT -p tcp -j YTUNBLOCK
#include <linux/module.h> #include <linux/module.h>
@ -9,15 +8,16 @@
#include <linux/net.h> #include <linux/net.h>
#include <linux/netfilter/x_tables.h> #include <linux/netfilter/x_tables.h>
#include "ipt_YTUNBLOCK.h" #include "ipt_YTUNBLOCK.h"
#include "mangle.h" #include "mangle.h"
#include "config.h"
#include "raw_replacements.h"
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_VERSION("0.1"); MODULE_VERSION("0.1");
MODULE_AUTHOR("Vadim Vetrov <vetrovvd@gmail.com>"); MODULE_AUTHOR("Vadim Vetrov <vetrovvd@gmail.com>");
MODULE_DESCRIPTION("Linux kernel module for youtube unblock"); MODULE_DESCRIPTION("Linux kernel module for youtube unblock");
#define USE_TCP_SEGMENTATION
static int rsfd; static int rsfd;
static struct socket *rawsocket; static struct socket *rawsocket;
DEFINE_MUTEX(rslock); DEFINE_MUTEX(rslock);
@ -63,16 +63,13 @@ static void close_raw_socket(void) {
static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) { static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
if (pktlen > AVAILABLE_MTU) { if (pktlen > AVAILABLE_MTU) {
pr_alert("The packet is too big!"); pr_warn("The packet is too big and may cause issues!");
#ifdef DEBUG
printf("Split packet!\n");
#endif
__u32 buff1_size = pktlen; __u32 buff1_size = pktlen;
__u32 buff2_size = pktlen; __u32 buff2_size = pktlen;
__u8 *buff1 = kmalloc(pktlen, GFP_KERNEL); __u8 *buff1 = kmalloc(pktlen, GFP_ATOMIC);
if (buff1 == NULL) return -1; if (buff1 == NULL) return -1;
__u8 *buff2 = kmalloc(pktlen, GFP_KERNEL); __u8 *buff2 = kmalloc(pktlen, GFP_ATOMIC);
if (buff2 == NULL) { if (buff2 == NULL) {
kfree(buff1); kfree(buff1);
return -1; return -1;
@ -80,15 +77,19 @@ static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
int ret; int ret;
#ifdef USE_TCP_SEGMENTATION #if defined(USE_TCP_SEGMENTATION) || defined(RAWSOCK_TCP_FSTRAT)
if ((ret = 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 ret; return ret;
#else #elif defined(USE_IP_FRAGMENTATION) || defined(RAWSOCK_IP_FSTRAT)
if ((ret = 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 ret; return ret;
#else
pr_warn("send_raw_socket: Packet is too big but fragmentation is disabled! "
"Pass -DRAWSOCK_TCP_FSTRAT or -DRAWSOCK_IP_FSTRAT as CFLAGS "
"To enable it only for raw socket\n");
return -EINVAL;
#endif #endif
int sent = 0; int sent = 0;
@ -147,100 +148,147 @@ static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
ret = kernel_sendmsg(rawsocket, &msg, &iov, 1, pktlen); ret = kernel_sendmsg(rawsocket, &msg, &iov, 1, pktlen);
mutex_unlock(&rslock); mutex_unlock(&rslock);
pr_info("%d\n", ret);
return ret; return ret;
} }
static unsigned int ykb_tg(struct sk_buff *skb, const struct xt_action_param *par) static unsigned int ykb_tg(struct sk_buff *skb, const struct xt_action_param *par)
{ {
if ((skb->mark & RAWSOCKET_MARK) == RAWSOCKET_MARK)
return XT_CONTINUE;
if (skb->head == NULL) return XT_CONTINUE; if (skb->head == NULL) return XT_CONTINUE;
struct iphdr *iph = ip_hdr(skb);
if (iph == NULL) {
pr_alert("iph is NULL!\n");
goto accept;
}
__u32 iph_len = iph->ihl * 4;
struct tcphdr *tcph = tcp_hdr(skb); // TODO: Mallocs are bad!
if (tcph == NULL) { uint32_t buflen = skb->len;
pr_alert("tcph is NULL!\n"); __u8 *buf = kmalloc(skb->len, GFP_ATOMIC);
goto accept;
}
__u32 tcph_len = tcp_hdrlen(skb);
// Mallocs are bad!
__u8 *buf = kmalloc(skb->len, GFP_KERNEL);
if (buf == NULL) { if (buf == NULL) {
pr_alert("Cannot alloc enough buffer"); pr_err("Cannot alloc enough buffer space");
goto accept; goto accept;
} }
if (skb_copy_bits(skb, 0, buf, skb->len) < 0) { if (skb_copy_bits(skb, 0, buf, skb->len) < 0) {
pr_alert("Unable copy bits\n"); pr_err("Unable copy bits\n");
goto ac_fkb; goto ac_fkb;
} }
struct iphdr *iph;
uint32_t iph_len;
struct tcphdr *tcph;
uint32_t tcph_len;
__u8 *payload;
uint32_t plen;
const __u8 *payload = buf + iph_len + tcph_len; int ret = tcp4_payload_split(buf, buflen, &iph, &iph_len,
__u32 plen = skb->len - iph_len - tcph_len; &tcph, &tcph_len, &payload, &plen);
if (ret < 0)
goto ac_fkb;
struct verdict vrd = analyze_tls_data(payload, plen); struct verdict vrd = analyze_tls_data(payload, plen);
if (vrd.gvideo_hello) { if (vrd.gvideo_hello) {
pr_alert("Googlevideo detected!\n"); int ret;
pr_info("Googlevideo detected\n");
ip4_set_checksum(iph);
tcp4_set_checksum(tcph, iph);
uint32_t f1len = skb->len; uint32_t f1len = skb->len;
uint32_t f2len = skb->len; uint32_t f2len = skb->len;
__u8 *frag1 = kmalloc(f1len, GFP_KERNEL); __u8 *frag1 = kmalloc(f1len, GFP_ATOMIC);
__u8 *frag2 = kmalloc(f2len, GFP_KERNEL); if (!frag1) {
pr_err("Cannot alloc enough gv frag1 buffer space");
goto ac_fkb;
}
__u8 *frag2 = kmalloc(f2len, GFP_ATOMIC);
if (!frag2) {
pr_err("Cannot alloc enough gv frag1 buffer space");
kfree(frag1);
goto ac_fkb;
}
#ifdef USE_TCP_SEGMENTATION
#ifdef FAKE_SNI
uint32_t fksn_len = FAKE_SNI_MAXLEN;
__u8 *fksn_buf = kmalloc(fksn_len, GFP_ATOMIC);
if (!fksn_buf) {
pr_err("Cannot alloc enough gksn buffer space");
goto fallback;
}
ret = gen_fake_sni(iph, tcph, fksn_buf, &fksn_len);
if (ret < 0) {
pr_err("Cannot alloc enough gksn buffer space");
goto fksn_fb;
}
#endif
#if defined(USE_TCP_SEGMENTATION)
size_t ipd_offset = vrd.sni_offset; size_t ipd_offset = vrd.sni_offset;
size_t mid_offset = ipd_offset + vrd.sni_len / 2; size_t mid_offset = ipd_offset + vrd.sni_len / 2;
int ret;
if ((ret = tcp4_frag(buf, skb->len, if ((ret = tcp4_frag(buf, skb->len,
mid_offset, frag1, &f1len, frag2, &f2len)) < 0) { mid_offset, frag1, &f1len, frag2, &f2len)) < 0) {
pr_err("tcp4_frag"); pr_err("tcp4_frag: %d", ret);
goto fksn_fb;
} }
#elif defined(USE_IP_FRAGMENTATION)
if ((ret = send_raw_socket(frag2, f2len) < 0) || size_t ipd_offset = tcph_len + vrd.sni_offset;
(ret = send_raw_socket(frag1, f1len) < 0)) {
pr_err("raw frags send");
goto fallback;
}
#else
// TODO: Implement ip fragmentation
/*
// TODO: Implement compute of tcp checksum
// GSO may turn kernel to not compute the tcp checksum.
// Also it will never be meaningless to ensure the
// checksum is right.
// nfq_tcp_compute_checksum_ipv4(tcph, ip_header);
size_t ipd_offset = ((char *)data - (char *)tcph) + vrd.sni_offset;
size_t mid_offset = ipd_offset + vrd.sni_len / 2; size_t mid_offset = ipd_offset + vrd.sni_len / 2;
mid_offset += 8 - mid_offset % 8; mid_offset += 8 - mid_offset % 8;
if ((errno = ip4_frag(raw_payload, raw_payload_len, if ((ret = ip4_frag(buf, skb->len,
mid_offset, frag1, &f1len, frag2, &f2len)) < 0) { mid_offset, frag1, &f1len, frag2, &f2len)) < 0) {
errno *= -1; pr_err("ip4_frag: %d", ret);
perror("ip4_frag"); goto fksn_fb;
goto fallback;
} }
if ((send_raw_socket(frag2, f2len) < 0) ||
(send_raw_socket(frag1, f1len) < 0)) {
perror("raw frags send");
}
*/
#endif #endif
#ifdef FAKE_SNI
ret = send_raw_socket(fksn_buf, fksn_len);
if (ret < 0) {
pr_err("fksn_send: %d", ret);
goto fksn_fb;
}
#endif
#if defined(USE_NO_FRAGMENTATION)
#ifdef SEG2_DELAY
#error "SEG2_DELAY is incompatible with NO FRAGMENTATION"
#endif
ret = send_raw_socket(buf, buflen);
if (ret < 0) {
pr_err("nofrag_send: %d", ret);
}
goto fksn_fb;
#endif
ret = send_raw_socket(frag2, f2len);
if (ret < 0) {
pr_err("raw frag2 send: %d", ret);
goto fksn_fb;
}
#ifdef SEG2_DELAY
#error "Seg2 delay is unsupported yet for kmod"
#else
ret = send_raw_socket(frag1, f1len);
if (ret < 0) {
pr_err("raw frag1 send: %d", ret);
goto fksn_fb;
}
#endif
fksn_fb:
#ifdef FAKE_SNI
kfree(fksn_buf);
#endif
fallback: fallback:
#ifndef SEG2_DELAY
kfree(frag1); kfree(frag1);
#endif
kfree(frag2); kfree(frag2);
kfree(buf); kfree(buf);
return XT_CONTINUE; kfree_skb(skb);
// return NF_DROP; return NF_STOLEN;
} }
ac_fkb: ac_fkb:
kfree(buf); kfree(buf);

View File

@ -1,61 +1,10 @@
#include "mangle.h" #include "mangle.h"
#include "raw_replacements.h" #include "raw_replacements.h"
#include "config.h"
#ifdef KERNEL_SPACE #ifdef KERNEL_SPACE
#include <linux/printk.h> #include <linux/printk.h>
#include <linux/ip.h>
static __u16 nfq_checksum(__u32 sum, __u16 *buf, int size)
{
while (size > 1) {
sum += *buf++;
size -= sizeof(__u16);
}
if (size) {
#ifdef __LITTLE_ENDIAN
sum += (uint16_t)*(uint8_t *)buf << 8;
#else
sum += (__u16)*(__u8 *)buf;
#endif
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return (__u16)(~sum);
}
static __u16 nfq_checksum_tcpudp_ipv4(struct iphdr *iph, __u16 protonum)
{
__u32 sum = 0;
__u32 iph_len = iph->ihl*4;
__u32 len = ntohs(iph->tot_len) - iph_len;
__u8 *payload = (__u8 *)iph + iph_len;
sum += (iph->saddr >> 16) & 0xFFFF;
sum += (iph->saddr) & 0xFFFF;
sum += (iph->daddr >> 16) & 0xFFFF;
sum += (iph->daddr) & 0xFFFF;
sum += htons(protonum);
sum += htons(len);
return nfq_checksum(sum, (__u16 *)payload, len);
}
static void nfq_ip_set_checksum(struct iphdr *iph)
{
__u32 iph_len = iph->ihl * 4;
iph->check = 0;
iph->check = nfq_checksum(0, (__u16 *)iph, iph_len);
}
static void
nfq_tcp_compute_checksum_ipv4(struct tcphdr *tcph, struct iphdr *iph)
{
/* checksum field in header needs to be zero for calculation. */
tcph->check = 0;
tcph->check = nfq_checksum_tcpudp_ipv4(iph, IPPROTO_TCP);
}
#define printf pr_info #define printf pr_info
#define perror pr_err #define perror pr_err
@ -69,9 +18,33 @@ 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);}) #define lgerror(msg, ret) __extension__ ({errno = -ret; perror(msg);})
#endif #endif
void tcp4_set_checksum(struct tcphdr *tcph, struct iphdr *iph)
{
#ifdef KERNEL_SPACE
uint32_t tcp_packet_len = ntohs(iph->tot_len) - (iph->ihl << 2);
tcph->check = 0;
tcph->check = csum_tcpudp_magic(
iph->saddr, iph->daddr, tcp_packet_len,
IPPROTO_TCP,
csum_partial(tcph, tcp_packet_len, 0));
#else
nfq_tcp_compute_checksum_ipv4(tcph, iph);
#endif
}
void ip4_set_checksum(struct iphdr *iph)
{
#ifdef KERNEL_SPACE
iph->check = 0;
iph->check = ip_fast_csum(iph, iph->ihl);
#else
nfq_ip_set_checksum(iph);
#endif
}
int ip4_payload_split(__u8 *pkt, __u32 buflen, int ip4_payload_split(__u8 *pkt, __u32 buflen,
struct iphdr **iph, __u32 *iph_len, struct iphdr **iph, __u32 *iph_len,
@ -219,8 +192,8 @@ int ip4_frag(const __u8 *pkt, __u32 buflen, __u32 payload_offset,
printf("Packet split in portion %u %u\n", f1_plen, f2_plen); printf("Packet split in portion %u %u\n", f1_plen, f2_plen);
#endif #endif
nfq_ip_set_checksum(f1_hdr); ip4_set_checksum(f1_hdr);
nfq_ip_set_checksum(f2_hdr); ip4_set_checksum(f2_hdr);
return 0; return 0;
} }
@ -297,8 +270,9 @@ int tcp4_frag(const __u8 *pkt, __u32 buflen, __u32 payload_offset,
printf("Packet split in portion %u %u\n", s1_plen, s2_plen); printf("Packet split in portion %u %u\n", s1_plen, s2_plen);
#endif #endif
nfq_tcp_compute_checksum_ipv4(s1_tcph, s1_hdr); tcp4_set_checksum(s1_tcph, s1_hdr);
nfq_tcp_compute_checksum_ipv4(s2_tcph, s2_hdr); tcp4_set_checksum(s2_tcph, s2_hdr);
return 0; return 0;
} }
@ -481,8 +455,8 @@ int gen_fake_sni(const struct iphdr *iph, const struct tcphdr *tcph,
ntcph->th_sport = tcph->th_sport; ntcph->th_sport = tcph->th_sport;
#endif #endif
nfq_ip_set_checksum(niph); ip4_set_checksum(niph);
nfq_tcp_compute_checksum_ipv4(ntcph, niph); tcp4_set_checksum(ntcph, niph);
return 0; return 0;
} }

View File

@ -59,6 +59,9 @@ int tcp4_payload_split(uint8_t *pkt, uint32_t buflen,
struct tcphdr **tcph, uint32_t *tcph_len, struct tcphdr **tcph, uint32_t *tcph_len,
uint8_t **payload, uint32_t *plen); uint8_t **payload, uint32_t *plen);
void tcp4_set_checksum(struct tcphdr *tcph, struct iphdr *iph);
void ip4_set_checksum(struct iphdr *iph);
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);
#endif /* YU_MANGLE_H */ #endif /* YU_MANGLE_H */

View File

@ -1,6 +1,8 @@
#ifndef RAW_REPLACEMENTS_H #ifndef RAW_REPLACEMENTS_H
#define RAW_REPLACEMENTS_H #define RAW_REPLACEMENTS_H
const char fake_sni[] = "\276(\001\273\366\234|\335\213\222\023\330\200\030\001\366\350e\000\000\001\001\b\n}\355\267Hm/\217\347\026\003\001\004\316\001\000\004\312\003\003K+\272\314\340\306\374>dw%\f\223\346\225\270\270~\335\027\f\264\341H\267\357\303\216T\322[\371 \245\320\212V6\374\3706\232\0216B\325\273P\b\300>\0332>\362\323\033\322\301\204\022f8\223\214\000\"\023\001\023\003\023\002\300+\300/\314\251\314\250\300,\3000\300\n\300\t\300\023\300\024\000\234\000\235\000/\0005\001\000\004_\000\000\000\023\000\021\000\000\016www.google.com\000\027\000\000\377\001\000\001\000\000\n\000\016\000\f\000\035\000\027\000\030\000\031\001\000\001\001\000\v\000\002\001\000\000\020\000\v\000\t\bhttp/1.1\000\005\000\005\001\000\000\000\000\000\"\000\n\000\b\004\003\005\003\006\003\002\003\0003\000k\000i\000\035\000 \333C\212\234-\t\237#\202\\\231\311\022]\333\341t(\t\276U\373u\234\316J~,^|*Z\000\027\000A\004k\n\255\254\376X\226t\001;n~\033\034.\245\027\024\3762_\352$\374\346^f\fF,\201\275\263\336O\231\001\032\200\357dI\266y\031\323\311vR\232\004\r\366FT\004\335\326\356\256\230B\t\313\000*\000\000\000+\000\005\004\003\004\003\003\000\r\000\030\000\026\004\003\005\003\006\003\b\004\b\005\b\006\004\001\005\001\006\001\002\003\002\001\000-\000\002\001\001\000\034\000\002@\001\376\r\0029\000\000\001\000\003\344\000 \337\306\243\332Y\033\a\252\352\025\365Z\035\223\226\304\255\363\215G\356g\344%}7\217\033n\211^\201\002\017g\267\334\326OD}\336\341ZC\230\226'\225\313\357\211\\\242\273\030k\216\377U\315\206\2410\200\203\332Z\223\005\370\b\304\370f\017\200\023\241\223~?\270{\037b\312\001\270\227\366\356\352\002\314\351\006\237\241q\226\300\314\321o\247{\201\317\230}B\005T\3660\335\320\332r?S\217\tq\036\031\326I|\237]\311 c\f\024r\031\310W\373\257\314q)q\030\237\261\227\217Kd?\257'G\320\020\340\256ND\247\005\341\324\024OP>\370\350\270b\311wAj\t\311\213\365i\203\230x\207\354\245<\274\202\230c\v0Y\263\364\022\303a\200\022\031\314\271rl=\327\336\001\327\264\267\342\353\352=\354[u\224\260\257\034\004\232\023\226}\227\030e\221\"\350\207\027dId\324\305\362N:\035\307`\204\337\201;\221\320\266b\362hrH\345e\206\246%\006\020a4\3430\036\225\215\274\275\360Q&\271\237)\222uK\362\017o\220\226W\357\267#\357\v\023\354\213\2629\331\ad\005/~6k\000[\247\301\270\310qJ\004\303|m5\363\376Y\002\243}6\251x\024\331)GH\335\205rI\032\f\210\a\212\347]\271\030\347.\021\213\365\026\030\340/Ny\r\332\3577\3203\026iX}>\2507\327&XRXU!\017\270I\313\352\350^?\352Uss\017\266pF\222NI\245\307_\305#\361\352\243+-\266\317Q\036s\243\277\355{S&\023>\275\360\215\032V\237XOY\345u>\002\305\252T\354\035\327v{P\352M\233\366\221\270\377\251\261f+rF\201wL2W\266X\252\242X\2536I\337c\205uZ\254Fe\305h\t\371\376\216r\336Y\327h\347*\331\257-ZQ{(\336\226\206\017\037\036\021\341\027z\033\254\235\252\227\224\004?p\243\351\\\263\352\205\327#W\345\255\256\375\267bP\3047\363!*K\003t\212(\306\214P\215\3506j\025\375\213e\254s\000)\001\034\000\367\000\361\002\276W%\232?\326\223\277\211v\017\a\361\347\312N\226\024L\260v\210\271j\324[|\270\344\3773\321-\313b>~\310\253XIR\324)&;\033{g;)\344\255\226\370\347I\\y\020\324\360\211vC\310\226s\267|\273$\341\332\2045qh\245w\2255\214\316\030\255\301\326C\343\304=\245\231h`yd\000#s\002\370\374Z\0336\245\361\226\222\306\032k\2457\016h\314(R;\326T~EHH\352\307\023^\247\363\321`V\340\253Z\233\357\227I\373\337z\177\nv\261\252\371\017\226\223\345\005\315y4\b\236N0\2630\017\215c\305&L\260\346J\237\203Q(\335W\027|>\3553\275j\307?W5\3463kc\350\262C\361 \037w!\371}\214\"I\377|\331@a;\342\3566\312\272Z\327u7\204'\215YBLL\235\236\242\345\215\245T\211a\312\263\342\000! \221\202X$\302\317\203\246\207c{\231\330\264\324\\k\271\272\336\356\002|\261O\207\030+\367P\317\356"; #define FAKE_SNI_MAXLEN 1500
#define fake_sni "\276(\001\273\366\234|\335\213\222\023\330\200\030\001\366\350e\000\000\001\001\b\n}\355\267Hm/\217\347\026\003\001\004\316\001\000\004\312\003\003K+\272\314\340\306\374>dw%\f\223\346\225\270\270~\335\027\f\264\341H\267\357\303\216T\322[\371 \245\320\212V6\374\3706\232\0216B\325\273P\b\300>\0332>\362\323\033\322\301\204\022f8\223\214\000\"\023\001\023\003\023\002\300+\300/\314\251\314\250\300,\3000\300\n\300\t\300\023\300\024\000\234\000\235\000/\0005\001\000\004_\000\000\000\023\000\021\000\000\016www.google.com\000\027\000\000\377\001\000\001\000\000\n\000\016\000\f\000\035\000\027\000\030\000\031\001\000\001\001\000\v\000\002\001\000\000\020\000\v\000\t\bhttp/1.1\000\005\000\005\001\000\000\000\000\000\"\000\n\000\b\004\003\005\003\006\003\002\003\0003\000k\000i\000\035\000 \333C\212\234-\t\237#\202\\\231\311\022]\333\341t(\t\276U\373u\234\316J~,^|*Z\000\027\000A\004k\n\255\254\376X\226t\001;n~\033\034.\245\027\024\3762_\352$\374\346^f\fF,\201\275\263\336O\231\001\032\200\357dI\266y\031\323\311vR\232\004\r\366FT\004\335\326\356\256\230B\t\313\000*\000\000\000+\000\005\004\003\004\003\003\000\r\000\030\000\026\004\003\005\003\006\003\b\004\b\005\b\006\004\001\005\001\006\001\002\003\002\001\000-\000\002\001\001\000\034\000\002@\001\376\r\0029\000\000\001\000\003\344\000 \337\306\243\332Y\033\a\252\352\025\365Z\035\223\226\304\255\363\215G\356g\344%}7\217\033n\211^\201\002\017g\267\334\326OD}\336\341ZC\230\226'\225\313\357\211\\\242\273\030k\216\377U\315\206\2410\200\203\332Z\223\005\370\b\304\370f\017\200\023\241\223~?\270{\037b\312\001\270\227\366\356\352\002\314\351\006\237\241q\226\300\314\321o\247{\201\317\230}B\005T\3660\335\320\332r?S\217\tq\036\031\326I|\237]\311 c\f\024r\031\310W\373\257\314q)q\030\237\261\227\217Kd?\257'G\320\020\340\256ND\247\005\341\324\024OP>\370\350\270b\311wAj\t\311\213\365i\203\230x\207\354\245<\274\202\230c\v0Y\263\364\022\303a\200\022\031\314\271rl=\327\336\001\327\264\267\342\353\352=\354[u\224\260\257\034\004\232\023\226}\227\030e\221\"\350\207\027dId\324\305\362N:\035\307`\204\337\201;\221\320\266b\362hrH\345e\206\246%\006\020a4\3430\036\225\215\274\275\360Q&\271\237)\222uK\362\017o\220\226W\357\267#\357\v\023\354\213\2629\331\ad\005/~6k\000[\247\301\270\310qJ\004\303|m5\363\376Y\002\243}6\251x\024\331)GH\335\205rI\032\f\210\a\212\347]\271\030\347.\021\213\365\026\030\340/Ny\r\332\3577\3203\026iX}>\2507\327&XRXU!\017\270I\313\352\350^?\352Uss\017\266pF\222NI\245\307_\305#\361\352\243+-\266\317Q\036s\243\277\355{S&\023>\275\360\215\032V\237XOY\345u>\002\305\252T\354\035\327v{P\352M\233\366\221\270\377\251\261f+rF\201wL2W\266X\252\242X\2536I\337c\205uZ\254Fe\305h\t\371\376\216r\336Y\327h\347*\331\257-ZQ{(\336\226\206\017\037\036\021\341\027z\033\254\235\252\227\224\004?p\243\351\\\263\352\205\327#W\345\255\256\375\267bP\3047\363!*K\003t\212(\306\214P\215\3506j\025\375\213e\254s\000)\001\034\000\367\000\361\002\276W%\232?\326\223\277\211v\017\a\361\347\312N\226\024L\260v\210\271j\324[|\270\344\3773\321-\313b>~\310\253XIR\324)&;\033{g;)\344\255\226\370\347I\\y\020\324\360\211vC\310\226s\267|\273$\341\332\2045qh\245w\2255\214\316\030\255\301\326C\343\304=\245\231h`yd\000#s\002\370\374Z\0336\245\361\226\222\306\032k\2457\016h\314(R;\326T~EHH\352\307\023^\247\363\321`V\340\253Z\233\357\227I\373\337z\177\nv\261\252\371\017\226\223\345\005\315y4\b\236N0\2630\017\215c\305&L\260\346J\237\203Q(\335W\027|>\3553\275j\307?W5\3463kc\350\262C\361 \037w!\371}\214\"I\377|\331@a;\342\3566\312\272Z\327u7\204'\215YBLL\235\236\242\345\215\245T\211a\312\263\342\000! \221\202X$\302\317\203\246\207c{\231\330\264\324\\k\271\272\336\356\002|\261O\207\030+\367P\317\356"
#endif /*RAW_REPLACEMENTS_H*/ #endif /*RAW_REPLACEMENTS_H*/

View File

@ -110,13 +110,13 @@ static int open_raw_socket(void) {
return -1; return -1;
} }
int one = 1; // int one = 1;
const int *val = &one; // const int *val = &one;
if (setsockopt(config.rawsocket, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0) // if (setsockopt(config.rawsocket, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0)
{ // {
fprintf(stderr, "setsockopt(IP_HDRINCL, 1) failed\n"); // fprintf(stderr, "setsockopt(IP_HDRINCL, 1) failed\n");
return -1; // return -1;
} // }
int mark = RAWSOCKET_MARK; int mark = RAWSOCKET_MARK;
if (setsockopt(config.rawsocket, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0) if (setsockopt(config.rawsocket, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0)