Check not sent bytes, --ip-opt

This commit is contained in:
ruti 2024-03-21 01:01:36 +03:00
parent ca03b1d311
commit 56a9043dd6
5 changed files with 96 additions and 16 deletions

View File

@ -76,9 +76,46 @@ static inline void delay(long ms)
#define delay(ms) Sleep(ms) #define delay(ms) Sleep(ms)
#endif #endif
#ifdef __linux__
void wait_send(int sfd)
{
for (int i = 0; params.wait_send; i++) {
struct {
uint8_t state;
uint8_t r[3];
uint32_t rr[35];
uint32_t notsent_bytes;
} tcpi = {};
socklen_t ts = sizeof(tcpi);
if (getsockopt(sfd, IPPROTO_TCP,
TCP_INFO, (char *)&tcpi, &ts) < 0) {
perror("getsockopt TCP_INFO");
break;
}
if (ts < sizeof(tcpi)) {
LOG(LOG_E, "tcpi_notsent_bytes not provided\n");
params.wait_send = 0;
break;
}
if (tcpi.state != 1) {
LOG(LOG_E, "state: %d\n", tcpi.state);
return;
}
if (tcpi.notsent_bytes == 0) {
return;
}
LOG(LOG_S, "not sent after %d ms\n", i);
delay(1);
}
delay(params.sfdelay);
}
#else
#define wait_send(sfd) delay(params.sfdelay)
#endif
#ifdef __linux__ #ifdef __linux__
int send_fake(int sfd, char *buffer, int send_fake(int sfd, char *buffer,
int cnt, long pos, int fa, int ttl) int cnt, long pos, int fa, struct desync_params *opt)
{ {
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;
@ -104,19 +141,31 @@ int send_fake(int sfd, char *buffer,
} }
memcpy(p, pkt.data, psz < pos ? psz : pos); memcpy(p, pkt.data, psz < pos ? psz : pos);
if (setttl(sfd, ttl, fa) < 0) { if (setttl(sfd, opt->ttl ? opt->ttl : 8, fa) < 0) {
break;
}
if (opt->ip_options
&& setsockopt(sfd, IPPROTO_IP, IP_OPTIONS,
opt->ip_options, opt->ip_options_len) < 0) {
perror("setsockopt IP_OPTIONS");
break; break;
} }
if (sendfile(sfd, ffd, 0, pos) < 0) { if (sendfile(sfd, ffd, 0, pos) < 0) {
uniperror("sendfile"); uniperror("sendfile");
break; break;
} }
delay(params.sfdelay); wait_send(sfd);
memcpy(p, buffer, pos); memcpy(p, buffer, pos);
if (setttl(sfd, params.def_ttl, fa) < 0) { if (setttl(sfd, params.def_ttl, fa) < 0) {
break; break;
} }
if (opt->ip_options
&& setsockopt(sfd, IPPROTO_IP,
IP_OPTIONS, opt->ip_options, 0) < 0) {
perror("setsockopt IP_OPTIONS");
break;
}
status = 0; status = 0;
} }
if (p) munmap(p, pos); if (p) munmap(p, pos);
@ -127,7 +176,7 @@ int send_fake(int sfd, char *buffer,
#ifdef _WIN32 #ifdef _WIN32
int send_fake(int sfd, char *buffer, int send_fake(int sfd, char *buffer,
int cnt, long pos, int fa, int ttl) int cnt, long pos, int fa, struct desync_params *opt)
{ {
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;
@ -180,7 +229,13 @@ int send_fake(int sfd, char *buffer,
uniperror("SetFilePointer"); uniperror("SetFilePointer");
break; break;
} }
if (setttl(sfd, ttl, fa) < 0) { if (setttl(sfd, opt->ttl ? opt->ttl : 8, fa) < 0) {
break;
}
if (opt->ip_options
&& setsockopt(sfd, IPPROTO_IP, IP_OPTIONS,
opt->ip_options, opt->ip_options_len) < 0) {
perror("setsockopt IP_OPTIONS");
break; break;
} }
if (!TransmitFile(sfd, hfile, pos, pos, &ov, if (!TransmitFile(sfd, hfile, pos, pos, &ov,
@ -204,6 +259,12 @@ int send_fake(int sfd, char *buffer,
if (setttl(sfd, params.def_ttl, fa) < 0) { if (setttl(sfd, params.def_ttl, fa) < 0) {
break; break;
} }
if (opt->ip_options
&& setsockopt(sfd, IPPROTO_IP, IP_OPTIONS,
opt->ip_options, 0) < 0) {
perror("setsockopt IP_OPTIONS");
break;
}
status = 0; status = 0;
} }
if (!CloseHandle(hfile)) { if (!CloseHandle(hfile)) {
@ -231,17 +292,14 @@ int send_oob(int sfd, char *buffer,
return -1; return -1;
} }
buffer[pos] = rchar; buffer[pos] = rchar;
if (size) { wait_send(sfd);
delay(params.sfdelay);
}
for (long i = 0; i < size; i++) { for (long i = 0; i < size; i++) {
if (send(sfd, data + i, 1, MSG_OOB) < 0) { if (send(sfd, data + i, 1, MSG_OOB) < 0) {
uniperror("send"); uniperror("send");
return -1; return -1;
} }
if (size != 1) { wait_send(sfd);
delay(params.sfdelay);
}
} }
return 0; return 0;
} }
@ -267,7 +325,7 @@ int send_disorder(int sfd,
} }
int desync(int sfd, char *buffer, size_t bfsize, ssize_t desync(int sfd, char *buffer, size_t bfsize,
ssize_t n, ssize_t offset, struct sockaddr *dst, int dp_c) ssize_t n, ssize_t offset, struct sockaddr *dst, int dp_c)
{ {
struct desync_params dp = params.dp[dp_c]; struct desync_params dp = params.dp[dp_c];
@ -364,7 +422,7 @@ int desync(int sfd, char *buffer, size_t bfsize,
#ifdef FAKE_SUPPORT #ifdef FAKE_SUPPORT
case DESYNC_FAKE: case DESYNC_FAKE:
s = send_fake(sfd, s = send_fake(sfd,
buffer + lp, type, pos - lp, fa, dp.ttl ? dp.ttl : 8); buffer + lp, type, pos - lp, fa, &dp);
break; break;
#endif #endif
case DESYNC_DISORDER: case DESYNC_DISORDER:

View File

@ -1 +1 @@
int desync(int sfd, char *buffer, size_t bfsize, ssize_t n, ssize_t offset, struct sockaddr *dst, int dp_c); ssize_t desync(int sfd, char *buffer, size_t bfsize, ssize_t n, ssize_t offset, struct sockaddr *dst, int dp_c);

16
main.c
View File

@ -39,6 +39,7 @@ oob_data = {
struct params params = { struct params params = {
.sfdelay = 3, .sfdelay = 3,
.wait_send = 1,
.def_ttl = 0, .def_ttl = 0,
.custom_ttl = 0, .custom_ttl = 0,
.de_known = 0, .de_known = 0,
@ -85,6 +86,7 @@ const char help_text[] = {
#ifdef FAKE_SUPPORT #ifdef FAKE_SUPPORT
" -f, --fake <n[+s]> Split and send fake packet\n" " -f, --fake <n[+s]> Split and send fake packet\n"
" -t, --ttl <num> TTL of fake packets, default 8\n" " -t, --ttl <num> TTL of fake packets, default 8\n"
" -k, --ip-opt <f|:str> IP options of fake packets\n"
" -l, --fake-tls <f|:str>\n" " -l, --fake-tls <f|:str>\n"
" -j, --fake-http <f|:str> Set custom fake packet\n" " -j, --fake-http <f|:str> Set custom fake packet\n"
" -n, --tls-sni <str> Change SNI in fake ClientHello\n" " -n, --tls-sni <str> Change SNI in fake ClientHello\n"
@ -123,6 +125,7 @@ const struct option options[] = {
#ifdef FAKE_SUPPORT #ifdef FAKE_SUPPORT
{"fake", 1, 0, 'f'}, {"fake", 1, 0, 'f'},
{"ttl", 1, 0, 't'}, {"ttl", 1, 0, 't'},
{"ip-opt", 1, 0, 'k'},
{"fake-tls", 1, 0, 'l'}, {"fake-tls", 1, 0, 'l'},
{"fake-http", 1, 0, 'j'}, {"fake-http", 1, 0, 'j'},
{"tls-sni", 1, 0, 'n'}, {"tls-sni", 1, 0, 'n'},
@ -132,6 +135,7 @@ const struct option options[] = {
{"tlsrec", 1, 0, 'r'}, {"tlsrec", 1, 0, 'r'},
{"def-ttl", 1, 0, 'g'}, {"def-ttl", 1, 0, 'g'},
{"delay", 1, 0, 'w'}, // {"delay", 1, 0, 'w'}, //
{"not-wait-send", 1, 0, 'W'}, //
{0} {0}
}; };
@ -484,6 +488,14 @@ int main(int argc, char **argv)
dp->ttl = val; dp->ttl = val;
break; break;
case 'k':
dp->ip_options = ftob(optarg, &dp->ip_options_len);
if (!dp->ip_options) {
uniperror("read/parse");
return -1;
}
break;
case 'n': case 'n':
if (change_tls_sni(optarg, fake_tls.data, fake_tls.size)) { if (change_tls_sni(optarg, fake_tls.data, fake_tls.size)) {
fprintf(stderr, "error chsni\n"); fprintf(stderr, "error chsni\n");
@ -568,6 +580,10 @@ int main(int argc, char **argv)
invalid = 1; invalid = 1;
break; break;
case 'W':
params.wait_send = 0;
break;
case 0: case 0:
break; break;

View File

@ -31,6 +31,8 @@ struct part {
struct desync_params { struct desync_params {
int ttl; int ttl;
char *ip_options;
ssize_t ip_options_len;
int parts_n; int parts_n;
struct part *parts; struct part *parts;
int mod_http; int mod_http;
@ -43,6 +45,7 @@ struct params {
int dp_count; int dp_count;
struct desync_params *dp; struct desync_params *dp;
long sfdelay; long sfdelay;
char wait_send;
int def_ttl; int def_ttl;
char custom_ttl; char custom_ttl;

View File

@ -350,6 +350,9 @@ int create_conn(struct poolhd *pool,
return -1; return -1;
} }
int status = connect(sfd, &addr.sa, sizeof(addr)); int status = connect(sfd, &addr.sa, sizeof(addr));
if (status == 0 && params.tfo) {
LOG(LOG_S, "TFO supported!\n");
}
if (status < 0 && if (status < 0 &&
get_e() != EINPROGRESS && get_e() != EAGAIN) { get_e() != EINPROGRESS && get_e() != EAGAIN) {
uniperror("connect"); uniperror("connect");
@ -733,7 +736,7 @@ int on_desync(struct poolhd *pool, struct eval *val,
if (sn < 0) { if (sn < 0) {
return -1; return -1;
} }
if (sn != n) { if (sn < n) {
val->buff.offset = sn; val->buff.offset = sn;
if (mod_etype(pool, val->pair, POLLOUT, 1)) { if (mod_etype(pool, val->pair, POLLOUT, 1)) {
uniperror("mod_etype"); uniperror("mod_etype");