#ifndef SLEEP_UTP_H #define SLEEP_UTP_H #include #include #include "dat_socket.h" #define SLEEP_UTP_MTU 1200u #define SLEEP_UTP_WINDOW 64u enum sleep_utp_state { SLEEP_UTP_CLOSED, SLEEP_UTP_SYN_SENT, SLEEP_UTP_SYN_RECV, SLEEP_UTP_CONNECTED, SLEEP_UTP_FIN_SENT, SLEEP_UTP_RESET }; enum sleep_utp_packet_type { SLEEP_UTP_DATA, SLEEP_UTP_FIN, SLEEP_UTP_STATE, SLEEP_UTP_RESET_PACKET, SLEEP_UTP_SYN }; typedef struct sleep_utp_packet { uint8_t type, version; uint16_t connection_id; uint32_t timestamp, timestamp_diff, window_size; uint16_t sequence, acknowledgement; uint32_t selective_ack; int has_selective_ack; const uint8_t *payload; size_t payload_len; } sleep_utp_packet_t; typedef struct sleep_utp_slot { uint16_t sequence; uint8_t data[SLEEP_UTP_MTU]; size_t length; uint64_t sent_at; unsigned retries; int used; } sleep_utp_slot_t; typedef struct sleep_utp { dat_socket_t socket; struct sockaddr_storage remote; socklen_t remote_len; uint16_t send_id, receive_id, sequence, acknowledgement; uint32_t receive_window, send_window; enum sleep_utp_state state; uint64_t retransmit_at; unsigned syn_retries; uint32_t congestion_window, slow_start_threshold; uint32_t round_trip_time, round_trip_variance; size_t bytes_in_flight; sleep_utp_slot_t unacked[SLEEP_UTP_WINDOW]; sleep_utp_slot_t reorder[SLEEP_UTP_WINDOW]; void *context; void (*on_data)(struct sleep_utp *, const uint8_t *, size_t); } sleep_utp_t; int sleep_utp_init(sleep_utp_t *utp, dat_socket_t udp_socket); int sleep_utp_connect(sleep_utp_t *utp, const struct sockaddr *remote, socklen_t remote_len); int sleep_utp_accept(sleep_utp_t *utp, const sleep_utp_packet_t *syn, const struct sockaddr *remote, socklen_t remote_len); int sleep_utp_packet_encode(const sleep_utp_packet_t *packet, uint8_t *out, size_t capacity, size_t *written); int sleep_utp_packet_decode(sleep_utp_packet_t *packet, const uint8_t *input, size_t input_len); int sleep_utp_input(sleep_utp_t *utp, const uint8_t *packet, size_t packet_len); int sleep_utp_send(sleep_utp_t *utp, const uint8_t *data, size_t length); int sleep_utp_tick(sleep_utp_t *utp, uint64_t now_ms); int sleep_utp_close(sleep_utp_t *utp); #endif