forked from cory/tildefriends
221 lines
8.0 KiB
C
221 lines
8.0 KiB
C
|
/*
|
||
|
* Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
|
||
|
*
|
||
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||
|
* this file except in compliance with the License. You can obtain a copy
|
||
|
* in the file LICENSE in the source distribution or at
|
||
|
* https://www.openssl.org/source/license.html
|
||
|
*/
|
||
|
|
||
|
#ifndef OSSL_QUIC_TSERVER_H
|
||
|
# define OSSL_QUIC_TSERVER_H
|
||
|
|
||
|
# include <openssl/ssl.h>
|
||
|
# include <openssl/bio.h>
|
||
|
# include "internal/quic_stream.h"
|
||
|
# include "internal/quic_channel.h"
|
||
|
# include "internal/statem.h"
|
||
|
# include "internal/time.h"
|
||
|
|
||
|
# ifndef OPENSSL_NO_QUIC
|
||
|
|
||
|
/*
|
||
|
* QUIC Test Server Module
|
||
|
* =======================
|
||
|
*
|
||
|
* This implements a QUIC test server. Since full QUIC server support is not yet
|
||
|
* implemented this server is limited in features and scope. It exists to
|
||
|
* provide a target for our QUIC client to talk to for testing purposes.
|
||
|
*
|
||
|
* A given QUIC test server instance supports only one client at a time.
|
||
|
*
|
||
|
* Note that this test server is not suitable for production use because it does
|
||
|
* not implement address verification, anti-amplification or retry logic.
|
||
|
*/
|
||
|
typedef struct quic_tserver_st QUIC_TSERVER;
|
||
|
|
||
|
typedef struct quic_tserver_args_st {
|
||
|
OSSL_LIB_CTX *libctx;
|
||
|
const char *propq;
|
||
|
SSL_CTX *ctx;
|
||
|
BIO *net_rbio, *net_wbio;
|
||
|
OSSL_TIME (*now_cb)(void *arg);
|
||
|
void *now_cb_arg;
|
||
|
const unsigned char *alpn;
|
||
|
size_t alpnlen;
|
||
|
} QUIC_TSERVER_ARGS;
|
||
|
|
||
|
QUIC_TSERVER *ossl_quic_tserver_new(const QUIC_TSERVER_ARGS *args,
|
||
|
const char *certfile, const char *keyfile);
|
||
|
|
||
|
void ossl_quic_tserver_free(QUIC_TSERVER *srv);
|
||
|
|
||
|
/* Set mutator callbacks for test framework support */
|
||
|
int ossl_quic_tserver_set_plain_packet_mutator(QUIC_TSERVER *srv,
|
||
|
ossl_mutate_packet_cb mutatecb,
|
||
|
ossl_finish_mutate_cb finishmutatecb,
|
||
|
void *mutatearg);
|
||
|
|
||
|
int ossl_quic_tserver_set_handshake_mutator(QUIC_TSERVER *srv,
|
||
|
ossl_statem_mutate_handshake_cb mutate_handshake_cb,
|
||
|
ossl_statem_finish_mutate_handshake_cb finish_mutate_handshake_cb,
|
||
|
void *mutatearg);
|
||
|
|
||
|
/* Advances the state machine. */
|
||
|
int ossl_quic_tserver_tick(QUIC_TSERVER *srv);
|
||
|
|
||
|
/* Returns 1 if we have a (non-terminated) client. */
|
||
|
int ossl_quic_tserver_is_connected(QUIC_TSERVER *srv);
|
||
|
|
||
|
/*
|
||
|
* Returns 1 if we have finished the TLS handshake
|
||
|
*/
|
||
|
int ossl_quic_tserver_is_handshake_confirmed(const QUIC_TSERVER *srv);
|
||
|
|
||
|
/* Returns 1 if the server is in any terminating or terminated state */
|
||
|
int ossl_quic_tserver_is_term_any(const QUIC_TSERVER *srv);
|
||
|
|
||
|
const QUIC_TERMINATE_CAUSE *
|
||
|
ossl_quic_tserver_get_terminate_cause(const QUIC_TSERVER *srv);
|
||
|
|
||
|
/* Returns 1 if the server is in a terminated state */
|
||
|
int ossl_quic_tserver_is_terminated(const QUIC_TSERVER *srv);
|
||
|
|
||
|
/*
|
||
|
* Attempts to read from stream 0. Writes the number of bytes read to
|
||
|
* *bytes_read and returns 1 on success. If no bytes are available, 0 is written
|
||
|
* to *bytes_read and 1 is returned (this is considered a success case).
|
||
|
*
|
||
|
* Returns 0 if connection is not currently active. If the receive part of
|
||
|
* the stream has reached the end of stream condition, returns 0; call
|
||
|
* ossl_quic_tserver_has_read_ended() to identify this condition.
|
||
|
*/
|
||
|
int ossl_quic_tserver_read(QUIC_TSERVER *srv,
|
||
|
uint64_t stream_id,
|
||
|
unsigned char *buf,
|
||
|
size_t buf_len,
|
||
|
size_t *bytes_read);
|
||
|
|
||
|
/*
|
||
|
* Returns 1 if the read part of the stream has ended normally.
|
||
|
*/
|
||
|
int ossl_quic_tserver_has_read_ended(QUIC_TSERVER *srv, uint64_t stream_id);
|
||
|
|
||
|
/*
|
||
|
* Attempts to write to the given stream. Writes the number of bytes consumed to
|
||
|
* *bytes_written and returns 1 on success. If there is no space currently
|
||
|
* available to write any bytes, 0 is written to *consumed and 1 is returned
|
||
|
* (this is considered a success case).
|
||
|
*
|
||
|
* Note that unlike libssl public APIs, this API always works in a 'partial
|
||
|
* write' mode.
|
||
|
*
|
||
|
* Returns 0 if connection is not currently active.
|
||
|
*/
|
||
|
int ossl_quic_tserver_write(QUIC_TSERVER *srv,
|
||
|
uint64_t stream_id,
|
||
|
const unsigned char *buf,
|
||
|
size_t buf_len,
|
||
|
size_t *bytes_written);
|
||
|
|
||
|
/*
|
||
|
* Signals normal end of the stream.
|
||
|
*/
|
||
|
int ossl_quic_tserver_conclude(QUIC_TSERVER *srv, uint64_t stream_id);
|
||
|
|
||
|
/*
|
||
|
* Create a server-initiated stream. The stream ID of the newly
|
||
|
* created stream is written to *stream_id.
|
||
|
*/
|
||
|
int ossl_quic_tserver_stream_new(QUIC_TSERVER *srv,
|
||
|
int is_uni,
|
||
|
uint64_t *stream_id);
|
||
|
|
||
|
BIO *ossl_quic_tserver_get0_rbio(QUIC_TSERVER *srv);
|
||
|
|
||
|
SSL_CTX *ossl_quic_tserver_get0_ssl_ctx(QUIC_TSERVER *srv);
|
||
|
|
||
|
/*
|
||
|
* Returns 1 if the peer has sent a STOP_SENDING frame for a stream.
|
||
|
* app_error_code is written if this returns 1.
|
||
|
*/
|
||
|
int ossl_quic_tserver_stream_has_peer_stop_sending(QUIC_TSERVER *srv,
|
||
|
uint64_t stream_id,
|
||
|
uint64_t *app_error_code);
|
||
|
|
||
|
/*
|
||
|
* Returns 1 if the peer has sent a RESET_STREAM frame for a stream.
|
||
|
* app_error_code is written if this returns 1.
|
||
|
*/
|
||
|
int ossl_quic_tserver_stream_has_peer_reset_stream(QUIC_TSERVER *srv,
|
||
|
uint64_t stream_id,
|
||
|
uint64_t *app_error_code);
|
||
|
|
||
|
/*
|
||
|
* Replaces existing local connection ID in the underlying QUIC_CHANNEL.
|
||
|
*/
|
||
|
int ossl_quic_tserver_set_new_local_cid(QUIC_TSERVER *srv,
|
||
|
const QUIC_CONN_ID *conn_id);
|
||
|
|
||
|
/*
|
||
|
* Returns the stream ID of the next incoming stream, or UINT64_MAX if there
|
||
|
* currently is none.
|
||
|
*/
|
||
|
uint64_t ossl_quic_tserver_pop_incoming_stream(QUIC_TSERVER *srv);
|
||
|
|
||
|
/*
|
||
|
* Returns 1 if all data sent on the given stream_id has been acked by the peer.
|
||
|
*/
|
||
|
int ossl_quic_tserver_is_stream_totally_acked(QUIC_TSERVER *srv,
|
||
|
uint64_t stream_id);
|
||
|
|
||
|
/* Returns 1 if we are currently interested in reading data from the network */
|
||
|
int ossl_quic_tserver_get_net_read_desired(QUIC_TSERVER *srv);
|
||
|
|
||
|
/* Returns 1 if we are currently interested in writing data to the network */
|
||
|
int ossl_quic_tserver_get_net_write_desired(QUIC_TSERVER *srv);
|
||
|
|
||
|
/* Returns the next event deadline */
|
||
|
OSSL_TIME ossl_quic_tserver_get_deadline(QUIC_TSERVER *srv);
|
||
|
|
||
|
/*
|
||
|
* Shutdown the QUIC connection. Returns 1 if the connection is terminated and
|
||
|
* 0 otherwise.
|
||
|
*/
|
||
|
int ossl_quic_tserver_shutdown(QUIC_TSERVER *srv, uint64_t app_error_code);
|
||
|
|
||
|
/* Force generation of an ACK-eliciting packet. */
|
||
|
int ossl_quic_tserver_ping(QUIC_TSERVER *srv);
|
||
|
|
||
|
/* Set tracing callback on channel. */
|
||
|
void ossl_quic_tserver_set_msg_callback(QUIC_TSERVER *srv,
|
||
|
void (*f)(int write_p, int version,
|
||
|
int content_type,
|
||
|
const void *buf, size_t len,
|
||
|
SSL *ssl, void *arg),
|
||
|
void *arg);
|
||
|
|
||
|
/*
|
||
|
* This is similar to ossl_quic_conn_get_channel; it should be used for test
|
||
|
* instrumentation only and not to bypass QUIC_TSERVER for 'normal' operations.
|
||
|
*/
|
||
|
QUIC_CHANNEL *ossl_quic_tserver_get_channel(QUIC_TSERVER *srv);
|
||
|
|
||
|
/* Send a TLS new session ticket */
|
||
|
int ossl_quic_tserver_new_ticket(QUIC_TSERVER *srv);
|
||
|
|
||
|
/*
|
||
|
* Set the max_early_data value to be sent in NewSessionTickets. Only the
|
||
|
* values 0 and 0xffffffff are valid for use in QUIC.
|
||
|
*/
|
||
|
int ossl_quic_tserver_set_max_early_data(QUIC_TSERVER *srv,
|
||
|
uint32_t max_early_data);
|
||
|
|
||
|
/* Set the find session callback for getting a server PSK */
|
||
|
void ossl_quic_tserver_set_psk_find_session_cb(QUIC_TSERVER *srv,
|
||
|
SSL_psk_find_session_cb_func cb);
|
||
|
|
||
|
# endif
|
||
|
|
||
|
#endif
|