Skip to content

Commit ff382f5

Browse files
committed
refinements + ignore HTTP requests from disconnected clients
1 parent 0c115a4 commit ff382f5

File tree

7 files changed

+176
-110
lines changed

7 files changed

+176
-110
lines changed

fio-stl.h

Lines changed: 88 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -7365,8 +7365,8 @@ Random - Implementation
73657365
#include <sys/time.h>
73667366
#endif
73677367

7368-
static volatile uint64_t fio___rand_state[4]; /* random state */
7369-
static volatile size_t fio___rand_counter; /* seed counter */
7368+
static volatile uint64_t fio___rand_state[4] = {0}; /* random state */
7369+
static volatile size_t fio___rand_counter = 0; /* seed counter */
73707370
/* feeds random data to the algorithm through this 256 bit feed. */
73717371
static volatile uint64_t fio___rand_buffer[4] = {0x9c65875be1fce7b9ULL,
73727372
0x7cc568e838f6a40d,
@@ -7429,14 +7429,14 @@ SFUNC uint64_t fio_rand64(void) {
74297429
/* modeled after xoroshiro128+, by David Blackman and Sebastiano Vigna */
74307430
uint64_t r = 0;
74317431
if (!((fio___rand_counter++) & (((size_t)1 << 12) - 1))) {
7432-
/* re-seed state every 524,288 requests / 2^19-1 attempts */
7432+
/* re-seed state every 4095 requests / 2^12-1 attempts */
74337433
fio_rand_reseed();
74347434
}
74357435
const uint64_t s0[] = {fio___rand_state[0],
74367436
fio___rand_state[1],
74377437
fio___rand_state[2],
74387438
fio___rand_state[3]}; /* load to registers */
7439-
uint64_t s1[4];
7439+
uint64_t s1[4] = {0};
74407440
{
74417441
const uint64_t mulp[] = {0x37701261ED6C16C7ULL,
74427442
0x764DBBB75F3B3E0DULL,
@@ -10859,6 +10859,8 @@ SFUNC size_t fio_sock_maximize_limits(size_t maximum_limit);
1085910859
/**
1086010860
* Returns 0 on timeout, -1 on error or the events that are valid.
1086110861
*
10862+
* A zero timeout returns immediately.
10863+
*
1086210864
* Possible events are POLLIN | POLLOUT
1086310865
*/
1086410866
SFUNC short fio_sock_wait_io(int fd, short events, int timeout);
@@ -10873,6 +10875,16 @@ SFUNC short fio_sock_wait_io(int fd, short events, int timeout);
1087310875
/** A helper macro that waits on a single IO with no callbacks (0 = no event) */
1087410876
#define FIO_SOCK_WAIT_W(fd, timeout_) fio_sock_wait_io(fd, POLLOUT, timeout_)
1087510877

10878+
#ifdef POLLRDHUP
10879+
/** A helper macro that tests if a socket was closed. */
10880+
#define FIO_SOCK_IS_OPEN(fd) \
10881+
(!(fio_sock_wait_io(fd, (POLLOUT | POLLRDHUP), 0) & \
10882+
(POLLRDHUP | POLLHUP | POLLNVAL)))
10883+
#else
10884+
#define FIO_SOCK_IS_OPEN(fd) \
10885+
(!(fio_sock_wait_io(fd, POLLOUT, 0) & (POLLHUP | POLLNVAL)))
10886+
#endif
10887+
1087610888
/* *****************************************************************************
1087710889
IO Poll - Implementation (always static / inlined)
1087810890
***************************************************************************** */
@@ -35286,6 +35298,13 @@ Copyright and License: see header file (000 copyright.h) or top of file
3528635298
/** I would love to use fio_time_mono, but using time_real enables logging. */
3528735299
#define FIO___IO_GET_TIME_MILLI() fio_time2milli(fio_time_real())
3528835300

35301+
/** Sets a flag in io->flag */
35302+
#define FIO___IO_FLAG_SET(io, flag_to_set) \
35303+
fio_atomic_or(&(io)->flags, flag_to_set)
35304+
/** unsets a flag in io->flag */
35305+
#define FIO___IO_FLAG_UNSET(io, flag_to_unset) \
35306+
fio_atomic_and(&(io)->flags, ~(flag_to_unset))
35307+
3528935308
/* *****************************************************************************
3529035309
IO environment support (`env`)
3529135310
***************************************************************************** */
@@ -35531,8 +35550,9 @@ FIO_IFUNC void fio___io_init_protocol_test(fio_io_protocol_s *pr,
3553135550
IO Reactor State Machine
3553235551
***************************************************************************** */
3553335552

35534-
#define FIO___IO_FLAG_WAKEUP (1U)
35535-
#define FIO___IO_FLAG_CYCLING (2U)
35553+
#define FIO___IO_FLAG_WAKEUP (1U)
35554+
#define FIO___IO_FLAG_CYCLING (2U)
35555+
#define FIO___IO_FLAG_TICK_SET (4U)
3553635556

3553735557
typedef struct {
3553835558
FIO_LIST_NODE node;
@@ -35570,6 +35590,32 @@ static struct FIO___IO_S {
3557035590
.shutdown_timeout = FIO_IO_SHUTDOWN_TIMEOUT,
3557135591
};
3557235592

35593+
FIO_IFUNC void fio___io_defer_no_wakeup(void (*task)(void *, void *),
35594+
void *udata1,
35595+
void *udata2) {
35596+
fio_queue_push(&FIO___IO.queue, task, udata1, udata2);
35597+
}
35598+
35599+
FIO_SFUNC void fio___io_wakeup(void);
35600+
void fio_io_defer___(void);
35601+
/** Schedules a task for delayed execution. This function is thread-safe. */
35602+
SFUNC void fio_io_defer FIO_NOOP(void (*task)(void *, void *),
35603+
void *udata1,
35604+
void *udata2) {
35605+
fio_queue_push(&FIO___IO.queue, task, udata1, udata2);
35606+
fio___io_wakeup();
35607+
}
35608+
35609+
void fio_io_run_every___(void);
35610+
/** Schedules a timer bound task, see `fio_timer_schedule`. */
35611+
SFUNC void fio_io_run_every FIO_NOOP(fio_timer_schedule_args_s args) {
35612+
args.start_at = FIO___IO.tick;
35613+
fio_timer_schedule FIO_NOOP(&FIO___IO.timer, args);
35614+
}
35615+
35616+
/** Returns a pointer for the IO reactor's queue. */
35617+
SFUNC fio_queue_s *fio_io_queue(void) { return &FIO___IO.queue; }
35618+
3557335619
/** Stopping the IO reactor. */
3557435620
SFUNC void fio_io_stop(void) { fio_atomic_or_fetch(&FIO___IO.stop, 1); }
3557535621

@@ -35588,40 +35634,25 @@ SFUNC int fio_io_is_master(void) { return FIO___IO.root_pid == FIO___IO.pid; }
3558835634
/** Returns true if the current process is a worker process. */
3558935635
SFUNC int fio_io_is_worker(void) { return FIO___IO.is_worker; }
3559035636

35637+
FIO_SFUNC void fio___io_last_tick_update(void *ignr_1, void *ignr_2) {
35638+
FIO___IO_FLAG_UNSET(&FIO___IO, FIO___IO_FLAG_TICK_SET);
35639+
FIO___IO.tick = FIO___IO_GET_TIME_MILLI();
35640+
(void)ignr_1, (void)ignr_2;
35641+
}
35642+
3559135643
/** Returns the last millisecond when the polled for IO events. */
35592-
SFUNC int64_t fio_io_last_tick(void) { return FIO___IO.tick; }
35644+
SFUNC int64_t fio_io_last_tick(void) {
35645+
if (!(FIO___IO_FLAG_SET(&FIO___IO, FIO___IO_FLAG_TICK_SET) &
35646+
FIO___IO_FLAG_TICK_SET))
35647+
fio___io_defer_no_wakeup(fio___io_last_tick_update, NULL, NULL);
35648+
return FIO___IO.tick;
35649+
}
3559335650

3559435651
/** Sets a signal to listen to for a hot restart (see `fio_io_restart`). */
3559535652
SFUNC void fio_io_restart_on_signal(int signal) {
3559635653
FIO___IO.restart_signal = signal;
3559735654
}
3559835655

35599-
FIO_SFUNC void fio___io_wakeup(void);
35600-
void fio_io_defer___(void);
35601-
/** Schedules a task for delayed execution. This function is thread-safe. */
35602-
SFUNC void fio_io_defer FIO_NOOP(void (*task)(void *, void *),
35603-
void *udata1,
35604-
void *udata2) {
35605-
fio_queue_push(&FIO___IO.queue, task, udata1, udata2);
35606-
fio___io_wakeup();
35607-
}
35608-
35609-
FIO_IFUNC void fio___io_defer_no_wakeup(void (*task)(void *, void *),
35610-
void *udata1,
35611-
void *udata2) {
35612-
fio_queue_push(&FIO___IO.queue, task, udata1, udata2);
35613-
}
35614-
35615-
void fio_io_run_every___(void);
35616-
/** Schedules a timer bound task, see `fio_timer_schedule`. */
35617-
SFUNC void fio_io_run_every FIO_NOOP(fio_timer_schedule_args_s args) {
35618-
args.start_at = FIO___IO.tick;
35619-
fio_timer_schedule FIO_NOOP(&FIO___IO.timer, args);
35620-
}
35621-
35622-
/** Returns a pointer for the IO reactor's queue. */
35623-
SFUNC fio_queue_s *fio_io_queue(void) { return &FIO___IO.queue; }
35624-
3562535656
/** Returns the shutdown timeout for the reactor. */
3562635657
SFUNC size_t fio_io_shutdown_timsout(void) { return FIO___IO.shutdown_timeout; }
3562735658

@@ -35653,11 +35684,6 @@ IO Type
3565335684
#define FIO___IO_FLAG_POLL_SET \
3565435685
(FIO___IO_FLAG_POLLIN_SET | FIO___IO_FLAG_POLLOUT_SET)
3565535686

35656-
#define FIO___IO_FLAG_SET(io, flag_to_set) \
35657-
fio_atomic_or(&(io)->flags, flag_to_set)
35658-
#define FIO___IO_FLAG_UNSET(io, flag_to_unset) \
35659-
fio_atomic_and(&(io)->flags, ~(flag_to_unset))
35660-
3566135687
static void fio___io_poll_on_data_schd(void *io);
3566235688
static void fio___io_poll_on_ready_schd(void *io);
3566335689
static void fio___io_poll_on_close_schd(void *io);
@@ -37790,6 +37816,9 @@ SFUNC fio_io_s *fio_io_connect FIO_NOOP(fio_io_connect_args_s args) {
3779037816
/* *****************************************************************************
3779137817
IO Reactor Finish
3779237818
***************************************************************************** */
37819+
#undef FIO___IO_FLAG_SET
37820+
#undef FIO___IO_FLAG_UNSET
37821+
#undef FIO___IO_GET_TIME_MILLI
3779337822
#endif /* FIO_IO */
3779437823
/* ************************************************************************* */
3779537824
#if !defined(FIO_INCLUDE_FILE) /* Dev test - ignore line */
@@ -42676,7 +42705,8 @@ int fio_http_cookie_set___(void); /* IDE Marker */
4267642705
SFUNC int fio_http_cookie_set FIO_NOOP(fio_http_s *h,
4267742706
fio_http_cookie_args_s cookie) {
4267842707
FIO_ASSERT_DEBUG(h, "Can't set cookie for NULL HTTP handler!");
42679-
if (!h || (h->state & (FIO_HTTP_STATE_FINISHED | FIO_HTTP_STATE_STREAMING)))
42708+
if (!h || ((h->state & (FIO_HTTP_STATE_FINISHED | FIO_HTTP_STATE_STREAMING)) |
42709+
(h->writer != fio____http_write_start)))
4268042710
return -1;
4268142711
/* promises that some warnings print only once. */
4268242712
static unsigned int warn_illegal = 0;
@@ -46021,7 +46051,8 @@ FIO_SFUNC void fio___http_perform_user_callback(void *cb_, void *h_) {
4602146051
} cb = {.ptr = cb_};
4602246052
fio_http_s *h = (fio_http_s *)h_;
4602346053
fio___http_connection_s *c = (fio___http_connection_s *)fio_http_cdata(h);
46024-
if (FIO_LIKELY(fio_io_is_open(c->io)))
46054+
46055+
if (FIO_LIKELY(FIO_SOCK_IS_OPEN(fio_io_fd(c->io))))
4602546056
cb.fn(h);
4602646057
fio_http_free(h);
4602746058
}
@@ -46035,7 +46066,7 @@ FIO_SFUNC void fio___http_perform_user_upgrade_callback_websocket(void *cb_,
4603546066
fio_http_s *h = (fio_http_s *)h_;
4603646067
fio___http_connection_s *c = (fio___http_connection_s *)fio_http_cdata(h);
4603746068
struct fio___http_connection_http_s old = c->state.http;
46038-
if (cb.fn(h))
46069+
if (!FIO_LIKELY(fio_io_is_open(c->io)) || cb.fn(h))
4603946070
goto refuse_upgrade;
4604046071
if (c->h) /* request after WebSocket Upgrade? an attack vector? */
4604146072
goto refuse_upgrade;
@@ -46101,7 +46132,7 @@ FIO_SFUNC void fio___http_perform_user_upgrade_callback_sse(void *cb_,
4610146132
} cb = {.ptr = cb_};
4610246133
fio_http_s *h = (fio_http_s *)h_;
4610346134
fio___http_connection_s *c = (fio___http_connection_s *)fio_http_cdata(h);
46104-
if (cb.fn(h))
46135+
if (!FIO_LIKELY(fio_io_is_open(c->io)) || cb.fn(h))
4610546136
goto refuse_upgrade;
4610646137
if (c->h) /* request after eventsource? an attack vector? */
4610746138
goto refuse_upgrade;
@@ -46702,19 +46733,21 @@ HTTP/1.1 Protocol
4670246733

4670346734
FIO_SFUNC int fio___http1_process_data(fio_io_s *io,
4670446735
fio___http_connection_s *c) {
46705-
(void)io, (void)c;
46706-
size_t consumed = fio_http1_parse(&c->state.http.parser,
46707-
FIO_BUF_INFO2(c->buf, c->len),
46708-
(void *)c);
46709-
if (!consumed)
46710-
goto nothing_consumed;
46711-
if (consumed == FIO_HTTP1_PARSER_ERROR)
46712-
goto http1_error;
46713-
c->len -= consumed;
46714-
if (c->len)
46715-
FIO_MEMMOVE(c->buf, c->buf + consumed, c->len);
46716-
if (c->suspend)
46717-
return -1;
46736+
(void)io;
46737+
for (;;) {
46738+
size_t consumed = fio_http1_parse(&c->state.http.parser,
46739+
FIO_BUF_INFO2(c->buf, c->len),
46740+
(void *)c);
46741+
if (!consumed)
46742+
goto nothing_consumed;
46743+
if (consumed == FIO_HTTP1_PARSER_ERROR)
46744+
goto http1_error;
46745+
c->len -= consumed;
46746+
if (c->len)
46747+
FIO_MEMMOVE(c->buf, c->buf + consumed, c->len);
46748+
if (c->suspend)
46749+
return -1;
46750+
}
4671846751
return 0;
4671946752

4672046753
nothing_consumed:

fio-stl/002 random.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,8 @@ Random - Implementation
263263
#include <sys/time.h>
264264
#endif
265265

266-
static volatile uint64_t fio___rand_state[4]; /* random state */
267-
static volatile size_t fio___rand_counter; /* seed counter */
266+
static volatile uint64_t fio___rand_state[4] = {0}; /* random state */
267+
static volatile size_t fio___rand_counter = 0; /* seed counter */
268268
/* feeds random data to the algorithm through this 256 bit feed. */
269269
static volatile uint64_t fio___rand_buffer[4] = {0x9c65875be1fce7b9ULL,
270270
0x7cc568e838f6a40d,
@@ -327,14 +327,14 @@ SFUNC uint64_t fio_rand64(void) {
327327
/* modeled after xoroshiro128+, by David Blackman and Sebastiano Vigna */
328328
uint64_t r = 0;
329329
if (!((fio___rand_counter++) & (((size_t)1 << 12) - 1))) {
330-
/* re-seed state every 524,288 requests / 2^19-1 attempts */
330+
/* re-seed state every 4095 requests / 2^12-1 attempts */
331331
fio_rand_reseed();
332332
}
333333
const uint64_t s0[] = {fio___rand_state[0],
334334
fio___rand_state[1],
335335
fio___rand_state[2],
336336
fio___rand_state[3]}; /* load to registers */
337-
uint64_t s1[4];
337+
uint64_t s1[4] = {0};
338338
{
339339
const uint64_t mulp[] = {0x37701261ED6C16C7ULL,
340340
0x764DBBB75F3B3E0DULL,

fio-stl/004 sock.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ SFUNC size_t fio_sock_maximize_limits(size_t maximum_limit);
195195
/**
196196
* Returns 0 on timeout, -1 on error or the events that are valid.
197197
*
198+
* A zero timeout returns immediately.
199+
*
198200
* Possible events are POLLIN | POLLOUT
199201
*/
200202
SFUNC short fio_sock_wait_io(int fd, short events, int timeout);
@@ -209,6 +211,16 @@ SFUNC short fio_sock_wait_io(int fd, short events, int timeout);
209211
/** A helper macro that waits on a single IO with no callbacks (0 = no event) */
210212
#define FIO_SOCK_WAIT_W(fd, timeout_) fio_sock_wait_io(fd, POLLOUT, timeout_)
211213

214+
#ifdef POLLRDHUP
215+
/** A helper macro that tests if a socket was closed. */
216+
#define FIO_SOCK_IS_OPEN(fd) \
217+
(!(fio_sock_wait_io(fd, (POLLOUT | POLLRDHUP), 0) & \
218+
(POLLRDHUP | POLLHUP | POLLNVAL)))
219+
#else
220+
#define FIO_SOCK_IS_OPEN(fd) \
221+
(!(fio_sock_wait_io(fd, POLLOUT, 0) & (POLLHUP | POLLNVAL)))
222+
#endif
223+
212224
/* *****************************************************************************
213225
IO Poll - Implementation (always static / inlined)
214226
***************************************************************************** */

0 commit comments

Comments
 (0)