Fix tunneling after many EAGAIN, remove ip-opt on Windows

This commit is contained in:
ruti 2024-05-14 05:07:01 +03:00
parent 13d0a9e4ed
commit 1052a85d2c
3 changed files with 19 additions and 27 deletions

View File

@ -233,7 +233,7 @@ ssize_t send_fake(int sfd, char *buffer,
}
size_t psz = pkt.size;
char path[MAX_PATH], temp[MAX_PATH];
char path[MAX_PATH], temp[MAX_PATH + 1];
int ps = GetTempPath(sizeof(temp), temp);
if (!ps) {
uniperror("GetTempPath");
@ -246,13 +246,12 @@ ssize_t send_fake(int sfd, char *buffer,
LOG(LOG_L, "temp file: %s\n", path);
HANDLE hfile = CreateFileA(path, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
if (hfile == INVALID_HANDLE_VALUE) {
uniperror("CreateFileA");
return -1;
}
OVERLAPPED ov = {};
ssize_t len = -1;
@ -262,7 +261,6 @@ ssize_t send_fake(int sfd, char *buffer,
uniperror("CreateEvent");
break;
}
if (!WriteFile(hfile, pkt.data, psz < pos ? psz : pos, 0, 0)) {
uniperror("WriteFile");
break;
@ -284,12 +282,6 @@ ssize_t send_fake(int sfd, char *buffer,
if (setttl(sfd, opt->ttl ? opt->ttl : 8, fa) < 0) {
break;
}
if (opt->ip_options && fa == AF_INET
&& setsockopt(sfd, IPPROTO_IP, IP_OPTIONS,
opt->ip_options, opt->ip_options_len) < 0) {
uniperror("setsockopt IP_OPTIONS");
break;
}
if (!TransmitFile(sfd, hfile, pos, pos, &ov,
NULL, TF_USE_KERNEL_APC | TF_WRITE_BEHIND)) {
if ((GetLastError() != ERROR_IO_PENDING)
@ -311,20 +303,13 @@ ssize_t send_fake(int sfd, char *buffer,
if (setttl(sfd, params.def_ttl, fa) < 0) {
break;
}
if (opt->ip_options && fa == AF_INET
&& setsockopt(sfd, IPPROTO_IP, IP_OPTIONS,
opt->ip_options, 0) < 0) {
uniperror("setsockopt IP_OPTIONS");
break;
}
len = pos;
break;
}
if (!CloseHandle(hfile)) {
uniperror("CloseHandle hfile");
}
if (ov.hEvent && !CloseHandle(ov.hEvent)) {
uniperror("CloseHandle hEvent");
if (!CloseHandle(hfile)
|| (ov.hEvent && !CloseHandle(ov.hEvent))) {
uniperror("CloseHandle");
return -1;
}
return len;
}
@ -480,8 +465,6 @@ ssize_t desync(int sfd, char *buffer, size_t bfsize,
break;
}
// send part
LOG(LOG_S, "split: pos=%ld-%ld, m: %s\n", lp, pos, demode_str[part.m]);
ssize_t s = 0;
switch (part.m) {
#ifdef FAKE_SUPPORT
@ -502,10 +485,14 @@ ssize_t desync(int sfd, char *buffer, size_t bfsize,
break;
case DESYNC_SPLIT:
default:
s = send(sfd, buffer + lp, pos - lp, 0);
wait_send_if_support(sfd);
default:
return -1;
}
LOG(LOG_S, "split: pos=%ld-%ld (%ld), m: %s\n", lp, pos, s, demode_str[part.m]);
if (s < 0) {
if (get_e() == EAGAIN) {
return lp;

4
main.c
View File

@ -92,8 +92,8 @@ const char help_text[] = {
#ifdef FAKE_SUPPORT
" -f, --fake <n[+s]> Split and send fake packet\n"
" -t, --ttl <num> TTL of fake packets, default 8\n"
" -k, --ip-opt[=f|:str] IP options of fake packets\n"
#ifdef __linux__
" -k, --ip-opt[=f|:str] IP options of fake packets\n"
" -S, --md5sig Add MD5 Signature option for fake packets\n"
#endif
" -l, --fake-data <f|:str> Set custom fake packet\n"
@ -136,8 +136,8 @@ const struct option options[] = {
#ifdef FAKE_SUPPORT
{"fake", 1, 0, 'f'},
{"ttl", 1, 0, 't'},
{"ip-opt", 2, 0, 'k'},
#ifdef __linux__
{"ip-opt", 2, 0, 'k'},
{"md5sig", 0, 0, 'S'},
#endif
{"fake-data", 1, 0, 'l'},

View File

@ -6,6 +6,7 @@
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <assert.h>
#include "proxy.h"
#include "params.h"
@ -559,6 +560,7 @@ int on_tunnel(struct poolhd *pool, struct eval *val,
free(val->buff.data);
val->buff.data = 0;
val->buff.size = 0;
val->buff.offset = 0;
if (mod_etype(pool, val, POLLIN) ||
mod_etype(pool, pair, POLLIN)) {
@ -586,6 +588,7 @@ int on_tunnel(struct poolhd *pool, struct eval *val,
sn = 0;
}
LOG(LOG_S, "EAGAIN, set POLLOUT (fd: %d)\n", pair->fd);
assert(!(val->buff.data || val->buff.offset));
val->buff.size = n - sn;
if (!(val->buff.data = malloc(val->buff.size))) {
@ -811,6 +814,8 @@ int event_loop(int srvfd)
uniperror("(e)poll");
break;
}
assert(val->type >= 0
&& val->type < sizeof(eid_name)/sizeof(*eid_name));
LOG(LOG_L, "new event: fd: %d, evt: %s, mod_iter: %d\n", val->fd, eid_name[val->type], val->mod_iter);
switch (val->type) {