mirror of
https://github.com/bol-van/zapret.git
synced 2025-01-03 23:10:35 +05:00
nfqws: extend conntrack
This commit is contained in:
parent
5e1adaa348
commit
5ddc0aa01b
@ -98,6 +98,7 @@ t_conntrack6 *ConntrackPoolSearch6(t_conntrack6 *p, const t_conn6 *c)
|
||||
static void ConntrackInitTrack(t_ctrack *t)
|
||||
{
|
||||
memset(t,0,sizeof(*t));
|
||||
t->scale_orig = t->scale_reply = SCALE_NONE;
|
||||
time(&t->t_start);
|
||||
}
|
||||
|
||||
@ -122,6 +123,7 @@ static t_conntrack6 *ConntrackNew6(t_conntrack6 **pp, const t_conn6 *c)
|
||||
|
||||
static void ConntrackFeedPacket(t_ctrack *t, bool bReverse, const struct tcphdr *tcphdr, uint32_t len_payload)
|
||||
{
|
||||
uint8_t scale;
|
||||
if (tcp_syn_segment(tcphdr))
|
||||
{
|
||||
if (t->state==FIN) ConntrackInitTrack(t); // erase current entry
|
||||
@ -148,17 +150,23 @@ static void ConntrackFeedPacket(t_ctrack *t, bool bReverse, const struct tcphdr
|
||||
if (!bReverse && !t->ack0) t->ack0 = htonl(tcphdr->th_ack)-1;
|
||||
}
|
||||
}
|
||||
scale = tcp_find_scale_factor(tcphdr);
|
||||
if (bReverse)
|
||||
{
|
||||
t->seq_last = htonl(tcphdr->th_ack);
|
||||
t->ack_last = htonl(tcphdr->th_seq) + len_payload;
|
||||
t->pcounter_reply++;
|
||||
t->winsize_reply = htons(tcphdr->th_win);
|
||||
if (scale!=SCALE_NONE) t->scale_reply = scale;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
t->seq_last = htonl(tcphdr->th_seq) + len_payload;
|
||||
t->ack_last = htonl(tcphdr->th_ack);
|
||||
t->pcounter_orig++;
|
||||
t->winsize_orig = htons(tcphdr->th_win);
|
||||
if (scale!=SCALE_NONE) t->scale_orig = scale;
|
||||
}
|
||||
time(&t->t_last);
|
||||
}
|
||||
@ -271,13 +279,15 @@ void ConntrackPoolPurge(t_conntrack *p)
|
||||
HASH_ITER(hh, p, t, tmp) { \
|
||||
*sa1=0; inet_ntop(AF_INET##f, &t->conn.e1.adr, sa1, sizeof(sa1)); \
|
||||
*sa2=0; inet_ntop(AF_INET##f, &t->conn.e2.adr, sa2, sizeof(sa2)); \
|
||||
printf("[%s]:%u => [%s]:%u : %s : t0=%lld last=t0+%lld now=last+%lld cutoff=%u packets_orig=%llu packets_reply=%llu seq0=%u rseq=%u ack0=%u rack=%u\n", \
|
||||
printf("[%s]:%u => [%s]:%u : %s : t0=%lld last=t0+%lld now=last+%lld cutoff=%u packets_orig=%llu packets_reply=%llu seq0=%u rseq=%u ack0=%u rack=%u wsize_orig=%u:%d wsize_reply=%u:%d\n", \
|
||||
sa1, t->conn.e1.port, sa2, t->conn.e2.port, \
|
||||
connstate_s[t->track.state], \
|
||||
(unsigned long long)t->track.t_start, (unsigned long long)(t->track.t_last - t->track.t_start), (unsigned long long)(tnow - t->track.t_last), \
|
||||
t->track.b_cutoff, \
|
||||
(unsigned long long)t->track.pcounter_orig, (unsigned long long)t->track.pcounter_reply, \
|
||||
t->track.seq0, t->track.seq_last - t->track.seq0, t->track.ack0, t->track.ack_last - t->track.ack0); \
|
||||
t->track.seq0, t->track.seq_last - t->track.seq0, t->track.ack0, t->track.ack_last - t->track.ack0, \
|
||||
t->track.winsize_orig, t->track.scale_orig==SCALE_NONE ? -1 : t->track.scale_orig, \
|
||||
t->track.winsize_reply, t->track.scale_reply==SCALE_NONE ? -1 : t->track.scale_reply ); \
|
||||
};
|
||||
void ConntrackPoolDump4(t_conntrack4 *p)
|
||||
{
|
||||
|
@ -51,6 +51,8 @@ typedef struct
|
||||
uint32_t seq0, ack0; // starting seq and ack
|
||||
uint32_t seq_last, ack_last; // current seq and ack
|
||||
uint64_t pcounter_orig, pcounter_reply; // packet counter
|
||||
uint16_t winsize_orig, winsize_reply; // last seen window size
|
||||
uint8_t scale_orig, scale_reply; // last seen window scale factor. SCALE_NONE if none
|
||||
|
||||
bool b_cutoff; // mark for deletion
|
||||
} t_ctrack;
|
||||
|
@ -46,8 +46,14 @@ uint32_t *tcp_find_timestamps(struct tcphdr *tcp)
|
||||
uint8_t *t = tcp_find_option(tcp,8);
|
||||
return (t && t[1]==10) ? (uint32_t*)(t+2) : NULL;
|
||||
}
|
||||
uint8_t tcp_find_scale_factor(const struct tcphdr *tcp)
|
||||
{
|
||||
uint8_t *scale = tcp_find_option((struct tcphdr*)tcp,3); // tcp option 3 - scale factor
|
||||
if (scale && scale[1]==3) return scale[2];
|
||||
return SCALE_NONE;
|
||||
}
|
||||
|
||||
static void fill_tcphdr(struct tcphdr *tcp, uint8_t tcp_flags, uint32_t seq, uint32_t ack_seq, uint8_t fooling, uint16_t nsport, uint16_t ndport, uint16_t nwsize, uint32_t *timestamps)
|
||||
static void fill_tcphdr(struct tcphdr *tcp, uint8_t tcp_flags, uint32_t seq, uint32_t ack_seq, uint8_t fooling, uint16_t nsport, uint16_t ndport, uint16_t nwsize, uint8_t scale_factor, uint32_t *timestamps)
|
||||
{
|
||||
char *tcpopt = (char*)(tcp+1);
|
||||
uint8_t t=0;
|
||||
@ -87,14 +93,21 @@ static void fill_tcphdr(struct tcphdr *tcp, uint8_t tcp_flags, uint32_t seq, uin
|
||||
*(uint32_t*)(tcpopt+t+6) = (timestamps && !(fooling & TCP_FOOL_TS)) ? timestamps[1] : -1;
|
||||
t+=10;
|
||||
}
|
||||
if (scale_factor!=SCALE_NONE)
|
||||
{
|
||||
tcpopt[t++]=3;
|
||||
tcpopt[t++]=3;
|
||||
tcpopt[t++]=scale_factor;
|
||||
}
|
||||
while (t&3) tcpopt[t++]=1; // noop
|
||||
tcp->th_off += t>>2;
|
||||
}
|
||||
static uint16_t tcpopt_len(uint8_t fooling, uint32_t *timestamps)
|
||||
static uint16_t tcpopt_len(uint8_t fooling, uint32_t *timestamps, uint8_t scale_factor)
|
||||
{
|
||||
uint16_t t=0;
|
||||
if (fooling & TCP_FOOL_MD5SIG) t=18;
|
||||
if ((fooling & TCP_FOOL_TS) || timestamps) t+=10;
|
||||
if (scale_factor!=SCALE_NONE) t+=3;
|
||||
return (t+3)&~3;
|
||||
}
|
||||
|
||||
@ -253,6 +266,7 @@ bool rawsend(const struct sockaddr* dst,uint32_t fwmark,const void *data,size_t
|
||||
{
|
||||
int sock=rawsend_socket(dst->sa_family,fwmark);
|
||||
if (sock==-1) return false;
|
||||
|
||||
int salen = dst->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
|
||||
struct sockaddr_storage dst2;
|
||||
memcpy(&dst2,dst,salen);
|
||||
@ -323,13 +337,14 @@ bool prepare_tcp_segment4(
|
||||
uint8_t tcp_flags,
|
||||
uint32_t seq, uint32_t ack_seq,
|
||||
uint16_t wsize,
|
||||
uint8_t scale_factor,
|
||||
uint32_t *timestamps,
|
||||
uint8_t ttl,
|
||||
uint8_t fooling,
|
||||
const void *data, uint16_t len,
|
||||
uint8_t *buf, size_t *buflen)
|
||||
{
|
||||
uint16_t tcpoptlen = tcpopt_len(fooling,timestamps);
|
||||
uint16_t tcpoptlen = tcpopt_len(fooling,timestamps, scale_factor);
|
||||
uint16_t pktlen = sizeof(struct ip) + sizeof(struct tcphdr) + tcpoptlen + len;
|
||||
if (pktlen>*buflen)
|
||||
{
|
||||
@ -350,7 +365,7 @@ bool prepare_tcp_segment4(
|
||||
ip->ip_src = src->sin_addr;
|
||||
ip->ip_dst = dst->sin_addr;
|
||||
|
||||
fill_tcphdr(tcp,tcp_flags,seq,ack_seq,fooling,src->sin_port,dst->sin_port,wsize,timestamps);
|
||||
fill_tcphdr(tcp,tcp_flags,seq,ack_seq,fooling,src->sin_port,dst->sin_port,wsize,scale_factor,timestamps);
|
||||
|
||||
memcpy((char*)tcp+sizeof(struct tcphdr)+tcpoptlen,data,len);
|
||||
tcp4_fix_checksum(tcp,sizeof(struct tcphdr)+tcpoptlen+len,&ip->ip_src,&ip->ip_dst);
|
||||
@ -366,13 +381,14 @@ bool prepare_tcp_segment6(
|
||||
uint8_t tcp_flags,
|
||||
uint32_t seq, uint32_t ack_seq,
|
||||
uint16_t wsize,
|
||||
uint8_t scale_factor,
|
||||
uint32_t *timestamps,
|
||||
uint8_t ttl,
|
||||
uint8_t fooling,
|
||||
const void *data, uint16_t len,
|
||||
uint8_t *buf, size_t *buflen)
|
||||
{
|
||||
uint16_t tcpoptlen = tcpopt_len(fooling,timestamps);
|
||||
uint16_t tcpoptlen = tcpopt_len(fooling,timestamps, scale_factor);
|
||||
uint16_t payloadlen = sizeof(struct tcphdr) + tcpoptlen + len;
|
||||
uint16_t pktlen = sizeof(struct ip6_hdr) + payloadlen;
|
||||
if (pktlen>*buflen)
|
||||
@ -391,7 +407,7 @@ bool prepare_tcp_segment6(
|
||||
ip6->ip6_src = src->sin6_addr;
|
||||
ip6->ip6_dst = dst->sin6_addr;
|
||||
|
||||
fill_tcphdr(tcp,tcp_flags,seq,ack_seq,fooling,src->sin6_port,dst->sin6_port,wsize,timestamps);
|
||||
fill_tcphdr(tcp,tcp_flags,seq,ack_seq,fooling,src->sin6_port,dst->sin6_port,wsize,scale_factor,timestamps);
|
||||
|
||||
memcpy((char*)tcp+sizeof(struct tcphdr)+tcpoptlen,data,len);
|
||||
tcp6_fix_checksum(tcp,sizeof(struct tcphdr)+tcpoptlen+len,&ip6->ip6_src,&ip6->ip6_dst);
|
||||
@ -406,6 +422,7 @@ bool prepare_tcp_segment(
|
||||
uint8_t tcp_flags,
|
||||
uint32_t seq, uint32_t ack_seq,
|
||||
uint16_t wsize,
|
||||
uint8_t scale_factor,
|
||||
uint32_t *timestamps,
|
||||
uint8_t ttl,
|
||||
uint8_t fooling,
|
||||
@ -413,9 +430,9 @@ bool prepare_tcp_segment(
|
||||
uint8_t *buf, size_t *buflen)
|
||||
{
|
||||
return (src->sa_family==AF_INET && dst->sa_family==AF_INET) ?
|
||||
prepare_tcp_segment4((struct sockaddr_in *)src,(struct sockaddr_in *)dst,tcp_flags,seq,ack_seq,wsize,timestamps,ttl,fooling,data,len,buf,buflen) :
|
||||
prepare_tcp_segment4((struct sockaddr_in *)src,(struct sockaddr_in *)dst,tcp_flags,seq,ack_seq,wsize,scale_factor,timestamps,ttl,fooling,data,len,buf,buflen) :
|
||||
(src->sa_family==AF_INET6 && dst->sa_family==AF_INET6) ?
|
||||
prepare_tcp_segment6((struct sockaddr_in6 *)src,(struct sockaddr_in6 *)dst,tcp_flags,seq,ack_seq,wsize,timestamps,ttl,fooling,data,len,buf,buflen) :
|
||||
prepare_tcp_segment6((struct sockaddr_in6 *)src,(struct sockaddr_in6 *)dst,tcp_flags,seq,ack_seq,wsize,scale_factor,timestamps,ttl,fooling,data,len,buf,buflen) :
|
||||
false;
|
||||
}
|
||||
|
||||
@ -663,7 +680,7 @@ void tcp_rewrite_wscale(struct tcphdr *tcp, uint8_t scale_factor)
|
||||
{
|
||||
uint8_t *scale,scale_factor_old;
|
||||
|
||||
if (scale_factor!=(uint8_t)-1)
|
||||
if (scale_factor!=SCALE_NONE)
|
||||
{
|
||||
scale = tcp_find_option(tcp,3); // tcp option 3 - scale factor
|
||||
if (scale && scale[1]==3) // length should be 3
|
||||
@ -680,7 +697,7 @@ void tcp_rewrite_wscale(struct tcphdr *tcp, uint8_t scale_factor)
|
||||
}
|
||||
}
|
||||
}
|
||||
// scale_factor=-1 - do not change
|
||||
// scale_factor=SCALE_NONE - do not change
|
||||
void tcp_rewrite_winsize(struct tcphdr *tcp, uint16_t winsize, uint8_t scale_factor)
|
||||
{
|
||||
uint16_t winsize_old;
|
||||
|
@ -19,12 +19,15 @@ uint32_t net32_add(uint32_t netorder_value, uint32_t cpuorder_increment);
|
||||
#define TCP_FOOL_TS 4
|
||||
#define TCP_FOOL_BADSEQ 8
|
||||
|
||||
#define SCALE_NONE ((uint8_t)-1)
|
||||
|
||||
// seq and wsize have network byte order
|
||||
bool prepare_tcp_segment4(
|
||||
const struct sockaddr_in *src, const struct sockaddr_in *dst,
|
||||
uint8_t tcp_flags,
|
||||
uint32_t seq, uint32_t ack_seq,
|
||||
uint16_t wsize,
|
||||
uint8_t scale_factor,
|
||||
uint32_t *timestamps,
|
||||
uint8_t ttl,
|
||||
uint8_t fooling,
|
||||
@ -35,6 +38,7 @@ bool prepare_tcp_segment6(
|
||||
uint8_t tcp_flags,
|
||||
uint32_t seq, uint32_t ack_seq,
|
||||
uint16_t wsize,
|
||||
uint8_t scale_factor,
|
||||
uint32_t *timestamps,
|
||||
uint8_t ttl,
|
||||
uint8_t fooling,
|
||||
@ -45,6 +49,7 @@ bool prepare_tcp_segment(
|
||||
uint8_t tcp_flags,
|
||||
uint32_t seq, uint32_t ack_seq,
|
||||
uint16_t wsize,
|
||||
uint8_t scale_factor,
|
||||
uint32_t *timestamps,
|
||||
uint8_t ttl,
|
||||
uint8_t fooling,
|
||||
@ -54,6 +59,7 @@ bool prepare_tcp_segment(
|
||||
void extract_endpoints(const struct ip *ip,const struct ip6_hdr *ip6hdr,const struct tcphdr *tcphdr, struct sockaddr_storage *src, struct sockaddr_storage *dst);
|
||||
uint8_t *tcp_find_option(struct tcphdr *tcp, uint8_t kind);
|
||||
uint32_t *tcp_find_timestamps(struct tcphdr *tcp);
|
||||
uint8_t tcp_find_scale_factor(const struct tcphdr *tcp);
|
||||
|
||||
// auto creates internal socket and uses it for subsequent calls
|
||||
bool rawsend(const struct sockaddr* dst,uint32_t fwmark,const void *data,size_t len);
|
||||
@ -77,6 +83,6 @@ void proto_skip_ipv6(uint8_t **data, size_t *len, uint8_t *proto_type);
|
||||
bool tcp_synack_segment(const struct tcphdr *tcphdr);
|
||||
bool tcp_syn_segment(const struct tcphdr *tcphdr);
|
||||
bool tcp_ack_segment(const struct tcphdr *tcphdr);
|
||||
// scale_factor=-1 - do not change
|
||||
// scale_factor=SCALE_NONE - do not change
|
||||
void tcp_rewrite_wscale(struct tcphdr *tcp, uint8_t scale_factor);
|
||||
void tcp_rewrite_winsize(struct tcphdr *tcp, uint16_t winsize, uint8_t scale_factor);
|
||||
|
17
nfq/desync.c
17
nfq/desync.c
@ -240,6 +240,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
uint8_t flags_orig = *((uint8_t*)tcphdr+13);
|
||||
uint32_t *timestamps = tcp_find_timestamps(tcphdr);
|
||||
enum dpi_desync_mode desync_mode = params.desync_mode;
|
||||
uint8_t scale_factor = tcp_find_scale_factor(tcphdr);
|
||||
bool b;
|
||||
|
||||
newlen = sizeof(newdata);
|
||||
@ -247,7 +248,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
switch(desync_mode)
|
||||
{
|
||||
case DESYNC_FAKE:
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, timestamps,
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
|
||||
ttl_fake,params.desync_tcp_fooling_mode,
|
||||
fake, fake_size, newdata, &newlen))
|
||||
{
|
||||
@ -259,7 +260,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
break;
|
||||
case DESYNC_RST:
|
||||
case DESYNC_RSTACK:
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, TH_RST | (desync_mode==DESYNC_RSTACK ? TH_ACK:0), tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, timestamps,
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, TH_RST | (desync_mode==DESYNC_RSTACK ? TH_ACK:0), tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
|
||||
ttl_fake,params.desync_tcp_fooling_mode,
|
||||
NULL, 0, newdata, &newlen))
|
||||
{
|
||||
@ -311,7 +312,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
|
||||
if (split_pos<len_payload)
|
||||
{
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(tcphdr->th_seq,split_pos), tcphdr->th_ack, tcphdr->th_win, timestamps,
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(tcphdr->th_seq,split_pos), tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
|
||||
ttl_orig,TCP_FOOL_NONE,
|
||||
data_payload+split_pos, len_payload-split_pos, newdata, &newlen))
|
||||
return res;
|
||||
@ -325,7 +326,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (desync_mode==DESYNC_DISORDER)
|
||||
{
|
||||
fakeseg_len = sizeof(fakeseg);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, timestamps,
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
|
||||
ttl_fake,params.desync_tcp_fooling_mode,
|
||||
zeropkt, split_pos, fakeseg, &fakeseg_len))
|
||||
return res;
|
||||
@ -337,7 +338,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
|
||||
|
||||
newlen = sizeof(newdata);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, timestamps,
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
|
||||
ttl_orig,TCP_FOOL_NONE,
|
||||
data_payload, split_pos, newdata, &newlen))
|
||||
return res;
|
||||
@ -367,7 +368,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (desync_mode==DESYNC_SPLIT)
|
||||
{
|
||||
fakeseg_len = sizeof(fakeseg);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, timestamps,
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
|
||||
ttl_fake,params.desync_tcp_fooling_mode,
|
||||
zeropkt, split_pos, fakeseg, &fakeseg_len))
|
||||
return res;
|
||||
@ -378,7 +379,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
}
|
||||
|
||||
newlen = sizeof(newdata);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, timestamps,
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
|
||||
ttl_orig,TCP_FOOL_NONE,
|
||||
data_payload, split_pos, newdata, &newlen))
|
||||
return res;
|
||||
@ -398,7 +399,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (split_pos<len_payload)
|
||||
{
|
||||
newlen = sizeof(newdata);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(tcphdr->th_seq,split_pos), tcphdr->th_ack, tcphdr->th_win, timestamps,
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(tcphdr->th_seq,split_pos), tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
|
||||
ttl_orig,TCP_FOOL_NONE,
|
||||
data_payload+split_pos, len_payload-split_pos, newdata, &newlen))
|
||||
return res;
|
||||
|
Loading…
Reference in New Issue
Block a user