mirror of
https://github.com/hufrea/byedpi.git
synced 2024-11-22 15:05:20 +03:00
set ttl and EAGAIN handler
This commit is contained in:
parent
a542ede01a
commit
c4dc80498b
6 changed files with 91 additions and 84 deletions
16
conev.c
16
conev.c
|
@ -51,7 +51,9 @@ struct eval *add_event(struct poolhd *pool, enum eid type,
|
|||
val->index = pool->count;
|
||||
val->type = type;
|
||||
val->pair = 0;
|
||||
val->send_count = 0;
|
||||
val->tmpbuf = 0;
|
||||
val->size = 0;
|
||||
val->offset = 0;
|
||||
val->flag = 0;
|
||||
|
||||
#ifndef NOEPOLL
|
||||
|
@ -80,6 +82,10 @@ void del_event(struct poolhd *pool, struct eval *val)
|
|||
if (!val->fd) {
|
||||
return;
|
||||
}
|
||||
if (val->tmpbuf) {
|
||||
free(val->tmpbuf);
|
||||
val->tmpbuf = 0;
|
||||
}
|
||||
close(val->fd);
|
||||
val->fd = 0;
|
||||
pool->count--;
|
||||
|
@ -106,7 +112,13 @@ void destroy_pool(struct poolhd *pool)
|
|||
{
|
||||
for (int x = 0; x < pool->count; x++) {
|
||||
struct eval *val = pool->links[x];
|
||||
if (val->fd) close(val->fd);
|
||||
if (val->fd) {
|
||||
close(val->fd);
|
||||
}
|
||||
if (val->tmpbuf) {
|
||||
free(val->tmpbuf);
|
||||
val->tmpbuf = 0;
|
||||
}
|
||||
}
|
||||
if (pool->items) {
|
||||
free(pool->items);
|
||||
|
|
4
conev.h
4
conev.h
|
@ -48,7 +48,9 @@ struct eval {
|
|||
int index;
|
||||
enum eid type;
|
||||
struct eval *pair;
|
||||
size_t send_count;
|
||||
char *tmpbuf;
|
||||
ssize_t size;
|
||||
int offset;
|
||||
int flag;
|
||||
#ifndef NOEPOLL
|
||||
uint32_t events;
|
||||
|
|
57
desync.c
57
desync.c
|
@ -10,9 +10,10 @@
|
|||
|
||||
#ifdef __linux__
|
||||
#include <sys/sendfile.h>
|
||||
#define _sendfile(outfd, infd, start, len) sendfile(outfd, infd, start, len)
|
||||
#else
|
||||
#include <sys/uio.h>
|
||||
#define sendfile(outfd, infd, start, len) sendfile(infd, outfd, start, len, 0, 0)
|
||||
#define _sendfile(outfd, infd, start, len) sendfile(infd, outfd, start, len, 0, 0)
|
||||
#endif
|
||||
|
||||
#ifdef MFD_CLOEXEC
|
||||
|
@ -26,7 +27,25 @@
|
|||
#include <packets.h>
|
||||
|
||||
|
||||
int fake_attack(int sfd, char *buffer, ssize_t n, int cnt, int pos)
|
||||
int setttl(int fd, int ttl, int family) {
|
||||
int _ttl = ttl;
|
||||
if (family == AF_INET) {
|
||||
if (setsockopt(fd, IPPROTO_IP, IP_TTL,
|
||||
&_ttl, sizeof(_ttl)) < 0) {
|
||||
perror("setsockopt IP_TTL");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
|
||||
&_ttl, sizeof(_ttl)) < 0) {
|
||||
perror("setsockopt IPV6_UNICAST_HOPS");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int fake_attack(int sfd, char *buffer, ssize_t n, int cnt, int pos, int fa)
|
||||
{
|
||||
struct packet pkt = cnt != IS_HTTP ? fake_tls : fake_http;
|
||||
size_t psz = pkt.size;
|
||||
|
@ -51,12 +70,10 @@ int fake_attack(int sfd, char *buffer, ssize_t n, int cnt, int pos)
|
|||
}
|
||||
memcpy(p, pkt.data, psz < pos ? psz : pos);
|
||||
|
||||
if (setsockopt(sfd, IPPROTO_IP, IP_TTL,
|
||||
¶ms.ttl, sizeof(params.ttl)) < 0) {
|
||||
perror("setsockopt IP_TTL");
|
||||
if (setttl(sfd, params.ttl, fa) < 0) {
|
||||
break;
|
||||
}
|
||||
if (sendfile(sfd, ffd, 0, pos) < 0) {
|
||||
if (_sendfile(sfd, ffd, 0, pos) < 0) {
|
||||
perror("sendfile");
|
||||
break;
|
||||
}
|
||||
|
@ -66,9 +83,7 @@ int fake_attack(int sfd, char *buffer, ssize_t n, int cnt, int pos)
|
|||
nanosleep(&delay, 0);
|
||||
memcpy(p, buffer, pos);
|
||||
|
||||
if (setsockopt(sfd, IPPROTO_IP, IP_TTL,
|
||||
¶ms.def_ttl, sizeof(int)) < 0) {
|
||||
perror("setsockopt IP_TTL");
|
||||
if (setttl(sfd, params.def_ttl, fa) < 0) {
|
||||
break;
|
||||
}
|
||||
if (send(sfd, buffer + pos, n - pos, 0) < 0) {
|
||||
|
@ -83,21 +98,17 @@ int fake_attack(int sfd, char *buffer, ssize_t n, int cnt, int pos)
|
|||
}
|
||||
|
||||
|
||||
int disorder_attack(int sfd, char *buffer, ssize_t n, int pos)
|
||||
int disorder_attack(int sfd, char *buffer, ssize_t n, int pos, int fa)
|
||||
{
|
||||
int bttl = 1;
|
||||
if (setsockopt(sfd, IPPROTO_IP, IP_TTL,
|
||||
(char *)&bttl, sizeof(bttl)) < 0) {
|
||||
perror("setsockopt IP_TTL");
|
||||
if (setttl(sfd, bttl, fa) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (send(sfd, buffer, pos, 0) < 0) {
|
||||
perror("send");
|
||||
return -1;
|
||||
}
|
||||
if (setsockopt(sfd, IPPROTO_IP, IP_TTL,
|
||||
(char *)¶ms.def_ttl, sizeof(int)) < 0) {
|
||||
perror("setsockopt IP_TTL");
|
||||
if (setttl(sfd, params.def_ttl, fa) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (send(sfd, buffer + pos, n - pos, 0) < 0) {
|
||||
|
@ -114,6 +125,15 @@ int desync(int sfd, char *buffer, ssize_t n)
|
|||
char *host = 0;
|
||||
int len = 0, type = 0;
|
||||
|
||||
struct sockaddr sa;
|
||||
socklen_t alen = sizeof(sa);
|
||||
|
||||
if (getsockname(sfd, &sa, &alen)) {
|
||||
perror("getsockname");
|
||||
return -1;
|
||||
}
|
||||
int fa = sa.sa_family;
|
||||
|
||||
if ((len = parse_tls(buffer, n, &host))) {
|
||||
type = IS_HTTPS;
|
||||
}
|
||||
|
@ -146,10 +166,11 @@ int desync(int sfd, char *buffer, ssize_t n)
|
|||
}
|
||||
else switch (params.attack) {
|
||||
case DESYNC_FAKE:
|
||||
return fake_attack(sfd, buffer, n, type, pos);
|
||||
return fake_attack(sfd, buffer, n, type, pos, fa);
|
||||
|
||||
case DESYNC_DISORDER:
|
||||
return disorder_attack(sfd, buffer, n, pos);
|
||||
printf("disorder attack\n");
|
||||
return disorder_attack(sfd, buffer, n, pos, fa);
|
||||
|
||||
case DESYNC_SPLIT:
|
||||
default:
|
||||
|
|
3
main.c
3
main.c
|
@ -40,7 +40,6 @@ struct params params = {
|
|||
|
||||
.bfsize = 16384,
|
||||
.send_bfsz = 65536,
|
||||
.nack_max = 65536 * 2 - 16384,
|
||||
.debug = 0
|
||||
};
|
||||
|
||||
|
@ -369,8 +368,6 @@ int main(int argc, char **argv)
|
|||
if (params.send_bfsz * 2 <= params.bfsize) {
|
||||
fprintf(stderr, "send buffer too small\n");
|
||||
return -1;
|
||||
} else {
|
||||
params.nack_max = val * 2 - params.bfsize;
|
||||
}
|
||||
FILE *file;
|
||||
if (pidfile) {
|
||||
|
|
1
params.h
1
params.h
|
@ -30,7 +30,6 @@ struct params {
|
|||
|
||||
int debug;
|
||||
size_t bfsize;
|
||||
size_t nack_max;
|
||||
int send_bfsz;
|
||||
};
|
||||
|
||||
|
|
92
proxy.c
92
proxy.c
|
@ -283,24 +283,6 @@ int handle_http(int fd, char *buffer,
|
|||
}
|
||||
|
||||
|
||||
int nsendc(int fd, int *wn)
|
||||
{
|
||||
#ifdef SO_NWRITE
|
||||
socklen_t len = sizeof(*wn);
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_NWRITE, wn, &len) < 0) {
|
||||
perror("getsockopt SO_NWRITE");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (ioctl(fd, TIOCOUTQ, wn) < 0 ) {
|
||||
perror("ioctl");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline int create_conn(struct poolhd *pool, struct eval *val,
|
||||
enum eid nxt, struct sockaddr_ina *dst)
|
||||
{
|
||||
|
@ -519,12 +501,10 @@ static inline int on_tunnel(struct poolhd *pool, struct eval *val,
|
|||
char *buffer, size_t bfsize, int out)
|
||||
{
|
||||
ssize_t n = 0;
|
||||
int peek = 0;
|
||||
char *rb = buffer;
|
||||
struct eval *pair = val->pair;
|
||||
|
||||
if (val->flag & FLAG_NOSEND && out) {
|
||||
val->flag &= ~FLAG_NOSEND;
|
||||
|
||||
if (pair->tmpbuf && out) {
|
||||
mod_etype(pool, val, POLLOUT, 0);
|
||||
mod_etype(pool, val->pair, POLLIN, 1);
|
||||
|
||||
|
@ -532,48 +512,45 @@ static inline int on_tunnel(struct poolhd *pool, struct eval *val,
|
|||
val = val->pair;
|
||||
}
|
||||
do {
|
||||
if (pair->send_count >= params.nack_max) {
|
||||
int wn = 0;
|
||||
if (nsendc(pair->fd, &wn)) {
|
||||
if (val->tmpbuf) {
|
||||
n = val->size - val->offset;
|
||||
rb = val->tmpbuf + val->offset;
|
||||
} else {
|
||||
n = recv(val->fd, buffer, bfsize, 0);
|
||||
if (n < 0 && errno == EAGAIN)
|
||||
break;
|
||||
if (n < 1) {
|
||||
if (n) perror("recv server");
|
||||
return -1;
|
||||
}
|
||||
pair->send_count = wn;
|
||||
if (wn) {
|
||||
LOG(LOG_S, "not ack: %d (fd: %d)\n", wn, pair->fd);
|
||||
}
|
||||
if (wn >= params.nack_max) {
|
||||
peek = MSG_PEEK;
|
||||
}
|
||||
}
|
||||
n = recv(val->fd, buffer, bfsize, peek);
|
||||
ssize_t sn = send(pair->fd, rb, n, 0);
|
||||
if (sn != n) {
|
||||
if (sn < 0 && errno != EAGAIN) {
|
||||
perror("send");
|
||||
return -1;
|
||||
}
|
||||
LOG(LOG_S, "EAGAIN, set POLLOUT (fd: %d)\n", pair->fd);
|
||||
mod_etype(pool, val, POLLIN, 0);
|
||||
mod_etype(pool, pair, POLLOUT, 1);
|
||||
|
||||
if (n < 0 && errno == EAGAIN)
|
||||
break;
|
||||
if (n < 1) {
|
||||
if (n) perror("recv server");
|
||||
return -1;
|
||||
}
|
||||
if (send(pair->fd, buffer, n, 0) < 0) {
|
||||
if (errno == EAGAIN && peek) {
|
||||
LOG(LOG_S, "EAGAIN, set POLLOUT (fd: %d)\n", pair->fd);
|
||||
|
||||
mod_etype(pool, val, POLLIN, 0);
|
||||
mod_etype(pool, pair, POLLOUT, 1);
|
||||
|
||||
pair->flag |= FLAG_NOSEND;
|
||||
if (val->tmpbuf) {
|
||||
LOG(LOG_S, "EAGAIN, AGAIN ! (fd: %d)\n", pair->fd);
|
||||
if (sn > 0)
|
||||
val->offset += sn;
|
||||
break;
|
||||
}
|
||||
perror("send");
|
||||
return -1;
|
||||
val->size = sn > 0 ? n - sn : n;
|
||||
val->tmpbuf = malloc(val->size);
|
||||
memcpy(val->tmpbuf, buffer + (sn > 0 ? sn : 0), val->size);
|
||||
break;
|
||||
}
|
||||
if (peek) {
|
||||
if (recv(val->fd, buffer, n, 0) != n) {
|
||||
perror("recv");
|
||||
return -1;
|
||||
}
|
||||
else if (val->tmpbuf) {
|
||||
free(val->tmpbuf);
|
||||
val->tmpbuf = 0;
|
||||
rb = buffer;
|
||||
continue;
|
||||
}
|
||||
pair->send_count += n;
|
||||
|
||||
} while (n == bfsize);
|
||||
return 0;
|
||||
}
|
||||
|
@ -624,8 +601,7 @@ int big_loop(int srvfd)
|
|||
continue;
|
||||
|
||||
case EV_TUNNEL:
|
||||
if ((etype & POLLHUP) ||
|
||||
on_tunnel(pool, val, buffer, bfsize, etype & POLLOUT))
|
||||
if (on_tunnel(pool, val, buffer, bfsize, etype & POLLOUT))
|
||||
del_event(pool, val);
|
||||
continue;
|
||||
|
||||
|
|
Loading…
Reference in a new issue