#ifdef LIBUS_USE_QUIC
#define _GNU_SOURCE
#include <unistd.h>
#include <stdlib.h>
#include <libusockets.h>
#include "quic.h"
us_quic_socket_context_t *context;
int responses = 0;
#include <stdio.h>
unsigned long long requests = 0;
struct us_loop_t *loop;
void on_wakeup(struct us_loop_t *loop) {}
void on_pre(struct us_loop_t *loop) {}
void on_post(struct us_loop_t *loop) {}
int per_socket_requests[100];
us_quic_socket_t *sockets[100];
int num_sockets = 0;
void on_print(struct us_timer_t *t) {
printf("Responses per second: %d\n", responses);
responses = 0;
for (int i = 0; i < num_sockets; i++) {
if (per_socket_requests[i] == 0) {
printf("One socket had no responses, closing!\n");
exit(0);
}
printf("Responses per second for socket %d: %d\n", i, per_socket_requests[i]);
per_socket_requests[i] = 0;
}
}
void print_current_headers() {
for (int i = 0, more = 1; more; i++) {
char *name, *value;
int name_length, value_length;
if (more = us_quic_socket_context_get_header(context, i, &name, &name_length, &value, &value_length)) {
printf("header %.*s = %.*s\n", name_length, name, value_length, value);
}
}
}
void on_stream_headers(us_quic_stream_t *s) {
for (int i = 0; i < num_sockets; i++) {
if (sockets[i] == us_quic_stream_socket(s)) {
per_socket_requests[i]++;
break;
}
if (i == num_sockets - 1) {
printf("Got response from socket we do not even have open!\n");
exit(0);
}
}
responses++;
us_quic_socket_create_stream(us_quic_stream_socket(s));
}
void on_stream_data(us_quic_stream_t *s, char *data, int length) {
}
void on_stream_writable(us_quic_stream_t *s) {
}
void on_stream_close(us_quic_stream_t *s) {
}
int ignore = 0;
void on_start(struct us_timer_t *t) {
if (num_sockets < 10) {
us_quic_socket_t *connect_socket = us_quic_socket_context_connect(context, "::1", 9004);
} else {
if (!ignore) {
struct us_timer_t *delayTimer = us_create_timer(loop, 0, 0);
us_timer_set(delayTimer, on_print, 1000, 1000);
ignore = 1;
printf("Starting now\n");
for (int i = 0; i < num_sockets; i++) {
for (int j = 0; j < 32; j++) {
us_quic_socket_create_stream(sockets[i]);
}
}
}
}
}
void on_open(us_quic_socket_t *s, int is_client) {
printf("New QUIC connection! Is client: %d\n", is_client);
if (is_client) {
sockets[num_sockets++] = s;
} else {
printf("yololooo\n");
exit(0);
}
}
void on_stream_open(us_quic_stream_t *s, int is_client) {
if (is_client) {
us_quic_socket_context_set_header(NULL, 0, ":method", 7, "GET", 3);
us_quic_socket_context_send_headers(NULL, s, 1, 0);
us_quic_stream_shutdown(s);
}
}
void on_close(us_quic_socket_t *s) {
printf("QUIC connection closed!\n");
}
int main() {
loop = us_create_loop(0, on_wakeup, on_pre, on_post, 0);
us_quic_socket_context_options_t options = {
.cert_file_name = "",
.key_file_name = ""
};
context = us_create_quic_socket_context(loop, options);
us_quic_socket_context_on_stream_data(context, on_stream_data);
us_quic_socket_context_on_stream_open(context, on_stream_open);
us_quic_socket_context_on_stream_close(context, on_stream_close);
us_quic_socket_context_on_stream_writable(context, on_stream_writable);
us_quic_socket_context_on_stream_headers(context, on_stream_headers);
us_quic_socket_context_on_open(context, on_open);
us_quic_socket_context_on_close(context, on_close);
struct us_timer_t *startTimer = us_create_timer(loop, 0, 0);
us_timer_set(startTimer, on_start, 100, 100);
us_loop_run(loop);
printf("Falling through!\n");
}
#else
#include <stdio.h>
int main() {
printf("Compile with WITH_QUIC=1 make examples in order to build this example\n");
}
#endif