mirror of
https://github.com/hufrea/byedpi.git
synced 2024-11-26 00:35:32 +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->index = pool->count;
|
||||||
val->type = type;
|
val->type = type;
|
||||||
val->pair = 0;
|
val->pair = 0;
|
||||||
val->send_count = 0;
|
val->tmpbuf = 0;
|
||||||
|
val->size = 0;
|
||||||
|
val->offset = 0;
|
||||||
val->flag = 0;
|
val->flag = 0;
|
||||||
|
|
||||||
#ifndef NOEPOLL
|
#ifndef NOEPOLL
|
||||||
|
@ -80,6 +82,10 @@ void del_event(struct poolhd *pool, struct eval *val)
|
||||||
if (!val->fd) {
|
if (!val->fd) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (val->tmpbuf) {
|
||||||
|
free(val->tmpbuf);
|
||||||
|
val->tmpbuf = 0;
|
||||||
|
}
|
||||||
close(val->fd);
|
close(val->fd);
|
||||||
val->fd = 0;
|
val->fd = 0;
|
||||||
pool->count--;
|
pool->count--;
|
||||||
|
@ -106,7 +112,13 @@ void destroy_pool(struct poolhd *pool)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < pool->count; x++) {
|
for (int x = 0; x < pool->count; x++) {
|
||||||
struct eval *val = pool->links[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) {
|
if (pool->items) {
|
||||||
free(pool->items);
|
free(pool->items);
|
||||||
|
|
4
conev.h
4
conev.h
|
@ -48,7 +48,9 @@ struct eval {
|
||||||
int index;
|
int index;
|
||||||
enum eid type;
|
enum eid type;
|
||||||
struct eval *pair;
|
struct eval *pair;
|
||||||
size_t send_count;
|
char *tmpbuf;
|
||||||
|
ssize_t size;
|
||||||
|
int offset;
|
||||||
int flag;
|
int flag;
|
||||||
#ifndef NOEPOLL
|
#ifndef NOEPOLL
|
||||||
uint32_t events;
|
uint32_t events;
|
||||||
|
|
57
desync.c
57
desync.c
|
@ -10,9 +10,10 @@
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <sys/sendfile.h>
|
#include <sys/sendfile.h>
|
||||||
|
#define _sendfile(outfd, infd, start, len) sendfile(outfd, infd, start, len)
|
||||||
#else
|
#else
|
||||||
#include <sys/uio.h>
|
#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
|
#endif
|
||||||
|
|
||||||
#ifdef MFD_CLOEXEC
|
#ifdef MFD_CLOEXEC
|
||||||
|
@ -26,7 +27,25 @@
|
||||||
#include <packets.h>
|
#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;
|
struct packet pkt = cnt != IS_HTTP ? fake_tls : fake_http;
|
||||||
size_t psz = pkt.size;
|
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);
|
memcpy(p, pkt.data, psz < pos ? psz : pos);
|
||||||
|
|
||||||
if (setsockopt(sfd, IPPROTO_IP, IP_TTL,
|
if (setttl(sfd, params.ttl, fa) < 0) {
|
||||||
¶ms.ttl, sizeof(params.ttl)) < 0) {
|
|
||||||
perror("setsockopt IP_TTL");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (sendfile(sfd, ffd, 0, pos) < 0) {
|
if (_sendfile(sfd, ffd, 0, pos) < 0) {
|
||||||
perror("sendfile");
|
perror("sendfile");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -66,9 +83,7 @@ int fake_attack(int sfd, char *buffer, ssize_t n, int cnt, int pos)
|
||||||
nanosleep(&delay, 0);
|
nanosleep(&delay, 0);
|
||||||
memcpy(p, buffer, pos);
|
memcpy(p, buffer, pos);
|
||||||
|
|
||||||
if (setsockopt(sfd, IPPROTO_IP, IP_TTL,
|
if (setttl(sfd, params.def_ttl, fa) < 0) {
|
||||||
¶ms.def_ttl, sizeof(int)) < 0) {
|
|
||||||
perror("setsockopt IP_TTL");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (send(sfd, buffer + pos, n - pos, 0) < 0) {
|
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;
|
int bttl = 1;
|
||||||
if (setsockopt(sfd, IPPROTO_IP, IP_TTL,
|
if (setttl(sfd, bttl, fa) < 0) {
|
||||||
(char *)&bttl, sizeof(bttl)) < 0) {
|
|
||||||
perror("setsockopt IP_TTL");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (send(sfd, buffer, pos, 0) < 0) {
|
if (send(sfd, buffer, pos, 0) < 0) {
|
||||||
perror("send");
|
perror("send");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (setsockopt(sfd, IPPROTO_IP, IP_TTL,
|
if (setttl(sfd, params.def_ttl, fa) < 0) {
|
||||||
(char *)¶ms.def_ttl, sizeof(int)) < 0) {
|
|
||||||
perror("setsockopt IP_TTL");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (send(sfd, buffer + pos, n - pos, 0) < 0) {
|
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;
|
char *host = 0;
|
||||||
int len = 0, type = 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))) {
|
if ((len = parse_tls(buffer, n, &host))) {
|
||||||
type = IS_HTTPS;
|
type = IS_HTTPS;
|
||||||
}
|
}
|
||||||
|
@ -146,10 +166,11 @@ int desync(int sfd, char *buffer, ssize_t n)
|
||||||
}
|
}
|
||||||
else switch (params.attack) {
|
else switch (params.attack) {
|
||||||
case DESYNC_FAKE:
|
case DESYNC_FAKE:
|
||||||
return fake_attack(sfd, buffer, n, type, pos);
|
return fake_attack(sfd, buffer, n, type, pos, fa);
|
||||||
|
|
||||||
case DESYNC_DISORDER:
|
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:
|
case DESYNC_SPLIT:
|
||||||
default:
|
default:
|
||||||
|
|
3
main.c
3
main.c
|
@ -40,7 +40,6 @@ struct params params = {
|
||||||
|
|
||||||
.bfsize = 16384,
|
.bfsize = 16384,
|
||||||
.send_bfsz = 65536,
|
.send_bfsz = 65536,
|
||||||
.nack_max = 65536 * 2 - 16384,
|
|
||||||
.debug = 0
|
.debug = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -369,8 +368,6 @@ int main(int argc, char **argv)
|
||||||
if (params.send_bfsz * 2 <= params.bfsize) {
|
if (params.send_bfsz * 2 <= params.bfsize) {
|
||||||
fprintf(stderr, "send buffer too small\n");
|
fprintf(stderr, "send buffer too small\n");
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
|
||||||
params.nack_max = val * 2 - params.bfsize;
|
|
||||||
}
|
}
|
||||||
FILE *file;
|
FILE *file;
|
||||||
if (pidfile) {
|
if (pidfile) {
|
||||||
|
|
1
params.h
1
params.h
|
@ -30,7 +30,6 @@ struct params {
|
||||||
|
|
||||||
int debug;
|
int debug;
|
||||||
size_t bfsize;
|
size_t bfsize;
|
||||||
size_t nack_max;
|
|
||||||
int send_bfsz;
|
int send_bfsz;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
86
proxy.c
86
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,
|
static inline int create_conn(struct poolhd *pool, struct eval *val,
|
||||||
enum eid nxt, struct sockaddr_ina *dst)
|
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)
|
char *buffer, size_t bfsize, int out)
|
||||||
{
|
{
|
||||||
ssize_t n = 0;
|
ssize_t n = 0;
|
||||||
int peek = 0;
|
char *rb = buffer;
|
||||||
struct eval *pair = val->pair;
|
struct eval *pair = val->pair;
|
||||||
|
|
||||||
if (val->flag & FLAG_NOSEND && out) {
|
if (pair->tmpbuf && out) {
|
||||||
val->flag &= ~FLAG_NOSEND;
|
|
||||||
|
|
||||||
mod_etype(pool, val, POLLOUT, 0);
|
mod_etype(pool, val, POLLOUT, 0);
|
||||||
mod_etype(pool, val->pair, POLLIN, 1);
|
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;
|
val = val->pair;
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
if (pair->send_count >= params.nack_max) {
|
if (val->tmpbuf) {
|
||||||
int wn = 0;
|
n = val->size - val->offset;
|
||||||
if (nsendc(pair->fd, &wn)) {
|
rb = val->tmpbuf + val->offset;
|
||||||
return -1;
|
} else {
|
||||||
}
|
n = recv(val->fd, buffer, bfsize, 0);
|
||||||
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);
|
|
||||||
|
|
||||||
if (n < 0 && errno == EAGAIN)
|
if (n < 0 && errno == EAGAIN)
|
||||||
break;
|
break;
|
||||||
if (n < 1) {
|
if (n < 1) {
|
||||||
if (n) perror("recv server");
|
if (n) perror("recv server");
|
||||||
return -1;
|
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;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
ssize_t sn = send(pair->fd, rb, n, 0);
|
||||||
|
if (sn != n) {
|
||||||
|
if (sn < 0 && errno != EAGAIN) {
|
||||||
perror("send");
|
perror("send");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (peek) {
|
LOG(LOG_S, "EAGAIN, set POLLOUT (fd: %d)\n", pair->fd);
|
||||||
if (recv(val->fd, buffer, n, 0) != n) {
|
mod_etype(pool, val, POLLIN, 0);
|
||||||
perror("recv");
|
mod_etype(pool, pair, POLLOUT, 1);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pair->send_count += n;
|
|
||||||
|
|
||||||
|
if (val->tmpbuf) {
|
||||||
|
LOG(LOG_S, "EAGAIN, AGAIN ! (fd: %d)\n", pair->fd);
|
||||||
|
if (sn > 0)
|
||||||
|
val->offset += sn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
val->size = sn > 0 ? n - sn : n;
|
||||||
|
val->tmpbuf = malloc(val->size);
|
||||||
|
memcpy(val->tmpbuf, buffer + (sn > 0 ? sn : 0), val->size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (val->tmpbuf) {
|
||||||
|
free(val->tmpbuf);
|
||||||
|
val->tmpbuf = 0;
|
||||||
|
rb = buffer;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
} while (n == bfsize);
|
} while (n == bfsize);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -624,8 +601,7 @@ int big_loop(int srvfd)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case EV_TUNNEL:
|
case EV_TUNNEL:
|
||||||
if ((etype & POLLHUP) ||
|
if (on_tunnel(pool, val, buffer, bfsize, etype & POLLOUT))
|
||||||
on_tunnel(pool, val, buffer, bfsize, etype & POLLOUT))
|
|
||||||
del_event(pool, val);
|
del_event(pool, val);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue