1
0
mirror of https://github.com/stefanocasazza/ULib.git synced 2025-09-28 19:05:55 +08:00
This commit is contained in:
stefanocasazza 2020-08-29 21:24:47 +02:00
parent 02c70bcd83
commit 8af911bc81
16 changed files with 887 additions and 700 deletions

View File

@ -115,6 +115,7 @@ vClientImage = new client_type[UNotifier::max_connection]; } }
#endif
class UQuic;
class UHTTP;
class UHTTP2;
class UHTTP3;
@ -1458,6 +1459,7 @@ private:
U_DISALLOW_COPY_AND_ASSIGN(UServer_Base)
friend class UQuic;
friend class UHTTP;
friend class UHTTP2;
friend class UHTTP3;

View File

@ -59,6 +59,7 @@
* they use class UIPAddress instances and port numbers rather than sockaddr structures
*/
class UQuic;
class UFile;
class UHTTP;
class UHTTP2;
@ -906,6 +907,7 @@ protected:
private:
U_DISALLOW_COPY_AND_ASSIGN(USocket)
friend class UQuic;
friend class UFile;
friend class UHTTP;
friend class UHTTP2;

View File

@ -1267,7 +1267,7 @@ public:
// ORM SQLITE
static const UString* str_sqlite_name;
static const UString* str_dbdir;
#ifndef U_HTTP2_DISABLE
#if !defined(U_HTTP2_DISABLE) || !defined(U_HTTP3_DISABLE)
static const UString* str_authority;
static const UString* str_method;
static const UString* str_method_get;

View File

@ -31,6 +31,7 @@
#define HTTP2_CONNECTION_PREFACE "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" // (24 bytes)
class UHTTP;
class UHTTP3;
class UClientImage_Base;
class U_EXPORT UHTTP2 {
@ -282,6 +283,7 @@ protected:
static void sendPing();
static void readFrame();
static void setStream();
static void buildTable();
static void manageData();
static bool initRequest();
static void writeResponse();
@ -490,7 +492,7 @@ protected:
U_RETURN(false);
}
static bool eraseHeaders(UStringRep* key, void* elem) // callWithDeleteForAllEntry()...
{
U_TRACE(0, "UHTTP2::eraseHeaders(%V,%p)", key, elem)
@ -849,6 +851,7 @@ private:
U_DISALLOW_COPY_AND_ASSIGN(UHTTP2)
friend class UHTTP;
friend class UHTTP3;
friend class Application;
friend class UClientImage_Base;
};

View File

@ -7,23 +7,15 @@
// http3.h - HTTP/3 utility
//
// = AUTHOR
// Stefano Casazza
// Stefano Casazza + Victor Stewart
//
// ============================================================================
#ifndef ULIB_HTTP3_H
#define ULIB_HTTP3_H 1
#include <ulib/db/rdb.h>
#include <ulib/net/server/server.h>
#define U_MAX_TOKEN_LEN \
sizeof("quiche")-1 + \
sizeof(struct sockaddr_storage) + \
QUICHE_MAX_CONN_ID_LEN
#define U_LOCAL_CONN_ID_LEN 16
#define U_MAX_DATAGRAM_SIZE 1350
#include <ulib/utility/uquic.h>
#include <ulib/utility/http2.h>
/**
* HTTP3 connection Information
@ -31,38 +23,17 @@
* This class contains data about an HTTP3 connection
*/
// override the default...
template <> inline void u_destroy( const UClientImage_Base* ptr) { U_TRACE(0,"u_destroy<UClientImage_Base*>(%p)", ptr) }
template <> inline void u_destroy( const UClientImage_Base** ptr, uint32_t n) { U_TRACE(0,"u_destroy<UClientImage_Base*>(%p,%u)", ptr, n) }
template <> inline void u_construct(const UClientImage_Base** ptr, bool b) { U_TRACE(0,"u_construct<UClientImage_Base*>(%p,%b)", ptr, b) }
class U_EXPORT UHTTP3 {
public:
// QUIC packet type
enum Type {
Initial = 1,
Retry = 2,
Handshake = 3,
ZeroRTT = 4,
Short = 5,
VersionNegotiation = 6
};
static int loadConfigParam();
protected:
static uint8_t pkt_type;
static quiche_conn* conn;
static uint32_t headers_len;
static quiche_h3_conn* http3;
static quiche_config* qconfig;
static quiche_h3_header* headers;
static UHashMap<UString>* itable; // headers request
static quiche_h3_config* http3_config;
static struct sockaddr_storage peer_addr;
static UHashMap<UClientImage_Base*>* peers;
static size_t conn_id_len, scid_len, token_len;
static uint32_t pkt_version, peer_addr_len, headers_len;
static uint8_t token[U_MAX_TOKEN_LEN], scid[QUICHE_MAX_CONN_ID_LEN], conn_id[QUICHE_MAX_CONN_ID_LEN];
// SERVICES
@ -70,90 +41,27 @@ protected:
{
U_TRACE_NO_PARAM(0, "UHTTP3::ctor()")
U_INTERNAL_ASSERT_EQUALS(peers, U_NULLPTR)
# ifdef U_HTTP2_DISABLE
UHTTP2::buildTable();
# endif
U_NEW(UHashMap<UClientImage_Base*>, peers, UHashMap<UClientImage_Base*>(UNotifier::max_connection));
U_NEW(UHashMap<UString>, itable, UHashMap<UString>(64, UHTTP2::setIndexStaticTable));
}
static void dtor()
{
U_TRACE_NO_PARAM(0, "UHTTP3::dtor()")
if (peers) U_DELETE(peers)
if (itable) U_DELETE(itable)
if (qconfig) U_SYSCALL_VOID(quiche_config_free, "%p", qconfig);
if (http3_config) U_SYSCALL_VOID(quiche_h3_config_free, "%p", http3_config);
}
static bool parseHeader();
static bool handlerNewConnection();
static void handlerRequest(quiche_conn* lconn, quiche_h3_conn* lh3);
static bool handlerRead(quiche_conn* lconn = U_NULLPTR, bool bwait_for_data = false);
// Lookup a connection based on the packet's connection ID
static bool lookup()
{
U_TRACE_NO_PARAM(0, "UHTTP3::lookup()")
if (peers->empty() == false &&
((UServer_Base::pClientImage = peers->at((const char*)conn_id, conn_id_len))))
{
UServer_Base::nClientIndex = UServer_Base::pClientImage - UServer_Base::vClientImage;
U_INTERNAL_DUMP("UServer_Base::nClientIndex = %u", UServer_Base::nClientIndex)
U_INTERNAL_ASSERT_MINOR(UServer_Base::nClientIndex, UNotifier::max_connection)
U_RETURN(true);
}
U_RETURN(false);
}
static void insert()
{
U_TRACE_NO_PARAM(0, "UHTTP3::insert()")
peers->insert((const char*)conn_id, conn_id_len, UServer_Base::pClientImage);
}
static bool processesPackets(quiche_conn* lconn)
{
U_TRACE(0, "UHTTP3::processesPackets(%p)", lconn)
U_INTERNAL_ASSERT_POINTER(lconn)
// Processes QUIC packets received from the peer
ssize_t done = U_SYSCALL(quiche_conn_recv, "%p,%p,%u", lconn, (uint8_t*)U_STRING_TO_PARAM(*UServer_Base::rbuffer));
if (done < 0)
{
U_DEBUG("UHTTP3::processesPackets(): failed to process packet: %d", done)
U_RETURN(false);
}
U_DEBUG("quiche: recv %d bytes", done)
U_RETURN(true);
}
static int for_each_header(uint8_t* name, size_t name_len, uint8_t* value, size_t value_len, void* argp)
{
U_TRACE(0, "UHTTP3::for_each_header(%.*S,%u,%.*S,%u,%p)", name_len, name, name_len, value_len, value, value_len, argp)
U_DEBUG("quiche: got HTTP header: %.*S(%u)=%.*S(%u)", name_len, name, name_len, value_len, value, value_len)
U_RETURN(0);
}
#ifdef DEBUG
static void quiche_debug_log(const char* line, void* argp)
{
U_DEBUG("%s\n", line)
}
#endif
static int for_each_header(uint8_t* name, size_t name_len, uint8_t* value, size_t value_len, void* argp);
private:
U_DISALLOW_COPY_AND_ASSIGN(UHTTP3)

View File

@ -0,0 +1,151 @@
// ============================================================================
//
// = LIBRARY
// ULib - c++ library
//
// = FILENAME
// uquic.h - Quic utility
//
// = AUTHOR
// Stefano Casazza + Victor Stewart
//
// ============================================================================
#ifndef U_QUIC_H
#define U_QUIC_H 1
#include <ulib/db/rdb.h>
#include <ulib/net/server/server.h>
#define U_MAX_TOKEN_LEN \
sizeof("quiche")-1 + \
sizeof(struct sockaddr_storage) + \
QUICHE_MAX_CONN_ID_LEN
#define U_LOCAL_CONN_ID_LEN 16
#define U_MAX_DATAGRAM_SIZE 1350
// override the default...
template <> inline void u_destroy( const UClientImage_Base* ptr) { U_TRACE(0,"u_destroy<UClientImage_Base*>(%p)", ptr) }
template <> inline void u_destroy( const UClientImage_Base** ptr, uint32_t n) { U_TRACE(0,"u_destroy<UClientImage_Base*>(%p,%u)", ptr, n) }
template <> inline void u_construct(const UClientImage_Base** ptr, bool b) { U_TRACE(0,"u_construct<UClientImage_Base*>(%p,%b)", ptr, b) }
class UHTTP3;
class U_EXPORT UQuic {
public:
// QUIC packet type
enum Type {
Initial = 1,
Retry = 2,
Handshake = 3,
ZeroRTT = 4,
Short = 5,
VersionNegotiation = 6
};
static int loadConfigParam();
protected:
static uint8_t pkt_type;
static quiche_conn* conn;
static quiche_config* qconfig;
static struct sockaddr_storage peer_addr;
static UHashMap<UClientImage_Base*>* peers;
static uint32_t pkt_version, peer_addr_len;
static size_t conn_id_len, scid_len, token_len;
static uint8_t token[U_MAX_TOKEN_LEN], scid[QUICHE_MAX_CONN_ID_LEN], conn_id[QUICHE_MAX_CONN_ID_LEN];
// SERVICES
static void ctor()
{
U_TRACE_NO_PARAM(0, "UQuic::ctor()")
U_INTERNAL_ASSERT_EQUALS(peers, U_NULLPTR)
U_NEW(UHashMap<UClientImage_Base*>, peers, UHashMap<UClientImage_Base*>(UNotifier::max_connection));
}
static void dtor()
{
U_TRACE_NO_PARAM(0, "UQuic::dtor()")
if (peers) U_DELETE(peers)
if (qconfig) U_SYSCALL_VOID(quiche_config_free, "%p", qconfig);
}
static bool parseHeader();
static bool handlerNewConnection();
static void handlerRequest(quiche_conn* lconn, quiche_h3_conn* lh3);
static bool handlerRead(quiche_conn* lconn = U_NULLPTR, bool bwait_for_data = false);
// Lookup a connection based on the packet's connection ID
static bool lookup()
{
U_TRACE_NO_PARAM(0, "UQuic::lookup()")
if (peers->empty() == false &&
((UServer_Base::pClientImage = peers->at((const char*)conn_id, conn_id_len))))
{
UServer_Base::nClientIndex = UServer_Base::pClientImage - UServer_Base::vClientImage;
U_INTERNAL_DUMP("UServer_Base::nClientIndex = %u", UServer_Base::nClientIndex)
U_INTERNAL_ASSERT_MINOR(UServer_Base::nClientIndex, UNotifier::max_connection)
U_RETURN(true);
}
U_RETURN(false);
}
static void insert()
{
U_TRACE_NO_PARAM(0, "UQuic::insert()")
peers->insert((const char*)conn_id, conn_id_len, UServer_Base::pClientImage);
}
static bool processesPackets(quiche_conn* lconn)
{
U_TRACE(0, "UQuic::processesPackets(%p)", lconn)
U_INTERNAL_ASSERT_POINTER(lconn)
// Processes QUIC packets received from the peer
ssize_t done = U_SYSCALL(quiche_conn_recv, "%p,%p,%u", lconn, (uint8_t*)U_STRING_TO_PARAM(*UServer_Base::rbuffer));
if (done < 0)
{
U_DEBUG("UQuic::processesPackets(): failed to process packet: %d", done)
U_RETURN(false);
}
U_DEBUG("quiche: recv %d bytes", done)
U_RETURN(true);
}
#ifdef DEBUG
static void quiche_debug_log(const char* line, void* argp)
{
U_DEBUG("%s\n", line)
}
#endif
private:
U_DISALLOW_COPY_AND_ASSIGN(UQuic)
friend class UHTTP;
friend class UHTTP3;
friend class Application;
friend class UHttpPlugIn;
friend class UServer_Base;
friend class UClientImage_Base;
};
#endif

View File

@ -61,7 +61,10 @@ if HTTP2
SRC_CPP += utility/http2.cpp
endif
if HTTP3
SRC_CPP += utility/http3.cpp
SRC_CPP += utility/http3.cpp utility/uquic.cpp
if !HTTP2
SRC_CPP += utility/http2.cpp
endif
endif
if STDCPP

View File

@ -93,81 +93,82 @@ target_triplet = @target@
@LIBTDB_TRUE@am__append_1 = db/tdb.cpp
@MONGODB_TRUE@am__append_2 = net/client/mongodb.cpp
@HTTP2_TRUE@am__append_3 = utility/http2.cpp
@HTTP3_TRUE@am__append_4 = utility/http3.cpp
@STDCPP_TRUE@am__append_5 = internal/objectIO.cpp
@PTHREAD_TRUE@am__append_6 = thread.cpp
@DEBUG_TRUE@am__append_7 = base/base_trace.c
@DEBUG_TRUE@am__append_8 = debug/debug_common.cpp debug/trace.cpp debug/error_memory.cpp debug/error_simulation.cpp
@DEBUG_TRUE@@STDCPP_TRUE@am__append_9 = debug/objectDB.cpp
@GETOPT_LONG_FALSE@am__append_10 = replace/getopt_long.c
@MREMAP_FALSE@am__append_11 = replace/mremap.c
@NANOSLEEP_FALSE@am__append_12 = replace/nanosleep.c
@SENDFILE_FALSE@am__append_13 = replace/sendfile.c
@STRNDUP_FALSE@am__append_14 = replace/strndup.c
@SEMAPHORE_FALSE@am__append_15 = replace/sem.c
@SEMAPHORE_TRUE@@SEM_TIMEDWAIT_FALSE@am__append_16 = replace/sem_timedwait.c
@STRPTIME_FALSE@am__append_17 = replace/strptime.c
@MKDTEMP_FALSE@am__append_18 = replace/mkdtemp.c
@MEMMEM_FALSE@am__append_19 = replace/memmem.c
@MEMRCHR_FALSE@am__append_20 = replace/memrchr.c
@GMTIME_R_FALSE@am__append_21 = replace/gmtime.c
@TIMEGM_FALSE@am__append_22 = replace/timegm.c
@FNMATCH_FALSE@am__append_23 = replace/fnmatch.c
@FALLOCATE_FALSE@am__append_24 = replace/fallocate.c
@FALLOCATE64_FALSE@am__append_25 = replace/fallocate64.c
@PREAD_FALSE@am__append_26 = replace/pread.c
@ASSERT_FALSE@am__append_27 = replace/assert.c
@APEXMEM_TRUE@am__append_28 = base/apex/apex_memmove.c
@SCHED_GETCPU_FALSE@am__append_29 = replace/sched_getcpu.c
@ZIP_TRUE@am__append_30 = base/zip/inflate.c base/zip/dostime.c base/zip/pushback.c base/zip/ziptool.c
@ZIP_TRUE@am__append_31 = zip/zip.cpp
@LIBZ_TRUE@am__append_32 = base/coder/cgzio.c
@USE_PARSER_TRUE@am__append_33 = flex/flexer.cpp flex/bison.cpp
@PCRE_TRUE@am__append_34 = pcre/pcre.cpp
@SSL_TRUE@am__append_35 = base/ssl/cdes3.c base/ssl/dgst.c
@SSL_TRUE@am__append_36 = ssl/certificate.cpp ssl/pkcs7.cpp ssl/crl.cpp ssl/pkcs10.cpp net/client/twilio.cpp net/client/uwebsocket.cpp \
@HTTP3_TRUE@am__append_4 = utility/http3.cpp utility/uquic.cpp
@HTTP2_FALSE@@HTTP3_TRUE@am__append_5 = utility/http2.cpp
@STDCPP_TRUE@am__append_6 = internal/objectIO.cpp
@PTHREAD_TRUE@am__append_7 = thread.cpp
@DEBUG_TRUE@am__append_8 = base/base_trace.c
@DEBUG_TRUE@am__append_9 = debug/debug_common.cpp debug/trace.cpp debug/error_memory.cpp debug/error_simulation.cpp
@DEBUG_TRUE@@STDCPP_TRUE@am__append_10 = debug/objectDB.cpp
@GETOPT_LONG_FALSE@am__append_11 = replace/getopt_long.c
@MREMAP_FALSE@am__append_12 = replace/mremap.c
@NANOSLEEP_FALSE@am__append_13 = replace/nanosleep.c
@SENDFILE_FALSE@am__append_14 = replace/sendfile.c
@STRNDUP_FALSE@am__append_15 = replace/strndup.c
@SEMAPHORE_FALSE@am__append_16 = replace/sem.c
@SEMAPHORE_TRUE@@SEM_TIMEDWAIT_FALSE@am__append_17 = replace/sem_timedwait.c
@STRPTIME_FALSE@am__append_18 = replace/strptime.c
@MKDTEMP_FALSE@am__append_19 = replace/mkdtemp.c
@MEMMEM_FALSE@am__append_20 = replace/memmem.c
@MEMRCHR_FALSE@am__append_21 = replace/memrchr.c
@GMTIME_R_FALSE@am__append_22 = replace/gmtime.c
@TIMEGM_FALSE@am__append_23 = replace/timegm.c
@FNMATCH_FALSE@am__append_24 = replace/fnmatch.c
@FALLOCATE_FALSE@am__append_25 = replace/fallocate.c
@FALLOCATE64_FALSE@am__append_26 = replace/fallocate64.c
@PREAD_FALSE@am__append_27 = replace/pread.c
@ASSERT_FALSE@am__append_28 = replace/assert.c
@APEXMEM_TRUE@am__append_29 = base/apex/apex_memmove.c
@SCHED_GETCPU_FALSE@am__append_30 = replace/sched_getcpu.c
@ZIP_TRUE@am__append_31 = base/zip/inflate.c base/zip/dostime.c base/zip/pushback.c base/zip/ziptool.c
@ZIP_TRUE@am__append_32 = zip/zip.cpp
@LIBZ_TRUE@am__append_33 = base/coder/cgzio.c
@USE_PARSER_TRUE@am__append_34 = flex/flexer.cpp flex/bison.cpp
@PCRE_TRUE@am__append_35 = pcre/pcre.cpp
@SSL_TRUE@am__append_36 = base/ssl/cdes3.c base/ssl/dgst.c
@SSL_TRUE@am__append_37 = ssl/certificate.cpp ssl/pkcs7.cpp ssl/crl.cpp ssl/pkcs10.cpp net/client/twilio.cpp net/client/uwebsocket.cpp \
@SSL_TRUE@ ssl/mime/mime_pkcs7.cpp ssl/net/sslsocket.cpp ssl/net/ssl_session.cpp utility/des3.cpp
@SSL_TRUE@@SSL_TS_TRUE@am__append_37 = ssl/timestamp.cpp
@SSH_TRUE@am__append_38 = ssh/net/sshsocket.cpp
@LDAP_TRUE@am__append_39 = ldap/ldap.cpp
@CURL_TRUE@am__append_40 = curl/curl.cpp
@EXPAT_TRUE@am__append_41 = xml/expat/attribute.cpp xml/expat/element.cpp xml/expat/xml_parser.cpp xml/expat/xml2txt.cpp \
@SSL_TRUE@@SSL_TS_TRUE@am__append_38 = ssl/timestamp.cpp
@SSH_TRUE@am__append_39 = ssh/net/sshsocket.cpp
@LDAP_TRUE@am__append_40 = ldap/ldap.cpp
@CURL_TRUE@am__append_41 = curl/curl.cpp
@EXPAT_TRUE@am__append_42 = xml/expat/attribute.cpp xml/expat/element.cpp xml/expat/xml_parser.cpp xml/expat/xml2txt.cpp \
@EXPAT_TRUE@ xml/soap/soap_fault.cpp xml/soap/soap_gen_method.cpp xml/soap/soap_parser.cpp xml/soap/soap_encoder.cpp xml/soap/soap_client.cpp
@LIBXML2_TRUE@am__append_42 = xml/libxml2/node.cpp xml/libxml2/document.cpp xml/libxml2/schema.cpp
@MAGIC_TRUE@am__append_43 = magic/magic.cpp
@DBI_TRUE@am__append_44 = dbi/dbi.cpp
@LIBEVENT_TRUE@am__append_45 = libevent/event.cpp
@MINGW_TRUE@am__append_46 = base/win32/mingw32.c
@MINGW_FALSE@am__append_47 = net/unixsocket.cpp
@LIBXML2_TRUE@am__append_43 = xml/libxml2/node.cpp xml/libxml2/document.cpp xml/libxml2/schema.cpp
@MAGIC_TRUE@am__append_44 = magic/magic.cpp
@DBI_TRUE@am__append_45 = dbi/dbi.cpp
@LIBEVENT_TRUE@am__append_46 = libevent/event.cpp
@MINGW_TRUE@am__append_47 = base/win32/mingw32.c
@MINGW_FALSE@am__append_48 = net/unixsocket.cpp
# Handler static plugin
@STATIC_HANDLER_RPC_TRUE@am__append_48 = net/server/plugin/mod_rpc.cpp
@MOD_SHIB_TRUE@@STATIC_HANDLER_SHIB_TRUE@am__append_49 = net/server/plugin/mod_shib/mod_shib.cpp
@STATIC_HANDLER_STREAM_TRUE@am__append_50 = net/server/plugin/mod_stream.cpp
@STATIC_HANDLER_NOCAT_TRUE@am__append_51 = net/server/plugin/mod_nocat.cpp
@STATIC_HANDLER_NODOG_TRUE@am__append_52 = net/server/plugin/mod_nodog.cpp
@STATIC_HANDLER_SOCKET_TRUE@am__append_53 = net/server/plugin/mod_socket.cpp
@STATIC_HANDLER_SCGI_TRUE@am__append_54 = net/server/plugin/mod_scgi.cpp
@STATIC_HANDLER_FCGI_TRUE@am__append_55 = net/server/plugin/mod_fcgi.cpp
@GEOIP_TRUE@@STATIC_HANDLER_GEOIP_TRUE@am__append_56 = net/server/plugin/mod_geoip/mod_geoip.cpp
@PCRE_TRUE@@STATIC_HANDLER_PROXY_TRUE@am__append_57 = net/server/plugin/mod_proxy.cpp
@EXPAT_TRUE@@STATIC_HANDLER_SOAP_TRUE@am__append_58 = net/server/plugin/mod_soap.cpp
@STATIC_HANDLER_SSI_TRUE@am__append_59 = net/server/plugin/mod_ssi.cpp
@STATIC_HANDLER_TSA_TRUE@am__append_60 = net/server/plugin/mod_tsa.cpp
@STATIC_HANDLER_HTTP_TRUE@am__append_61 = net/server/plugin/mod_http.cpp
@STATIC_HANDLER_ECHO_TRUE@am__append_62 = net/server/plugin/mod_echo.cpp
@STATIC_HANDLER_RPC_TRUE@am__append_49 = net/server/plugin/mod_rpc.cpp
@MOD_SHIB_TRUE@@STATIC_HANDLER_SHIB_TRUE@am__append_50 = net/server/plugin/mod_shib/mod_shib.cpp
@STATIC_HANDLER_STREAM_TRUE@am__append_51 = net/server/plugin/mod_stream.cpp
@STATIC_HANDLER_NOCAT_TRUE@am__append_52 = net/server/plugin/mod_nocat.cpp
@STATIC_HANDLER_NODOG_TRUE@am__append_53 = net/server/plugin/mod_nodog.cpp
@STATIC_HANDLER_SOCKET_TRUE@am__append_54 = net/server/plugin/mod_socket.cpp
@STATIC_HANDLER_SCGI_TRUE@am__append_55 = net/server/plugin/mod_scgi.cpp
@STATIC_HANDLER_FCGI_TRUE@am__append_56 = net/server/plugin/mod_fcgi.cpp
@GEOIP_TRUE@@STATIC_HANDLER_GEOIP_TRUE@am__append_57 = net/server/plugin/mod_geoip/mod_geoip.cpp
@PCRE_TRUE@@STATIC_HANDLER_PROXY_TRUE@am__append_58 = net/server/plugin/mod_proxy.cpp
@EXPAT_TRUE@@STATIC_HANDLER_SOAP_TRUE@am__append_59 = net/server/plugin/mod_soap.cpp
@STATIC_HANDLER_SSI_TRUE@am__append_60 = net/server/plugin/mod_ssi.cpp
@STATIC_HANDLER_TSA_TRUE@am__append_61 = net/server/plugin/mod_tsa.cpp
@STATIC_HANDLER_HTTP_TRUE@am__append_62 = net/server/plugin/mod_http.cpp
@STATIC_HANDLER_ECHO_TRUE@am__append_63 = net/server/plugin/mod_echo.cpp
# Handler static orm driver
@STATIC_ORM_DRIVER_SQLITE_TRUE@am__append_63 = orm/driver/orm_driver_sqlite.cpp
@STATIC_ORM_DRIVER_MYSQL_TRUE@am__append_64 = orm/driver/orm_driver_mysql.cpp
@STATIC_ORM_DRIVER_PGSQL_TRUE@am__append_65 = orm/driver/orm_driver_pgsql.cpp
@STATIC_ORM_DRIVER_PGSQL_TRUE@am__append_66 = $(top_builddir)/src/ulib/orm/driver/libpq/libpq.la
@MINGW_TRUE@am__append_67 = -export-symbols $(srcdir)/@ULIB@.def -no-undefined -Wl,ULib-win32-res.o
@STATIC_ORM_DRIVER_SQLITE_TRUE@am__append_64 = orm/driver/orm_driver_sqlite.cpp
@STATIC_ORM_DRIVER_MYSQL_TRUE@am__append_65 = orm/driver/orm_driver_mysql.cpp
@STATIC_ORM_DRIVER_PGSQL_TRUE@am__append_66 = orm/driver/orm_driver_pgsql.cpp
@STATIC_ORM_DRIVER_PGSQL_TRUE@am__append_67 = $(top_builddir)/src/ulib/orm/driver/libpq/libpq.la
@MINGW_TRUE@am__append_68 = -export-symbols $(srcdir)/@ULIB@.def -no-undefined -Wl,ULib-win32-res.o
# Handler static http servlet
@STATIC_ONLY_TRUE@@STATIC_SERVLET_TRUE@am__append_68 = net/server/plugin/usp/loader.autoconf.inc
@STATIC_ONLY_TRUE@@STATIC_SERVLET_TRUE@am__append_69 = net/server/plugin/usp/loader.autoconf.inc
subdir = src/ulib
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_package.m4 \
@ -269,12 +270,13 @@ am__lib@ULIB@_la_SOURCES_DIST = base/base.c base/base_error.c \
process.cpp file_config.cpp log.cpp options.cpp \
application.cpp cache.cpp date.cpp url.cpp tokenizer.cpp \
command.cpp db/tdb.cpp net/client/mongodb.cpp \
utility/http2.cpp utility/http3.cpp internal/objectIO.cpp \
thread.cpp debug/debug_common.cpp debug/trace.cpp \
debug/error_memory.cpp debug/error_simulation.cpp \
debug/objectDB.cpp zip/zip.cpp flex/flexer.cpp flex/bison.cpp \
pcre/pcre.cpp ssl/certificate.cpp ssl/pkcs7.cpp ssl/crl.cpp \
ssl/pkcs10.cpp net/client/twilio.cpp net/client/uwebsocket.cpp \
utility/http2.cpp utility/http3.cpp utility/uquic.cpp \
internal/objectIO.cpp thread.cpp debug/debug_common.cpp \
debug/trace.cpp debug/error_memory.cpp \
debug/error_simulation.cpp debug/objectDB.cpp zip/zip.cpp \
flex/flexer.cpp flex/bison.cpp pcre/pcre.cpp \
ssl/certificate.cpp ssl/pkcs7.cpp ssl/crl.cpp ssl/pkcs10.cpp \
net/client/twilio.cpp net/client/uwebsocket.cpp \
ssl/mime/mime_pkcs7.cpp ssl/net/sslsocket.cpp \
ssl/net/ssl_session.cpp utility/des3.cpp ssl/timestamp.cpp \
ssh/net/sshsocket.cpp ldap/ldap.cpp curl/curl.cpp \
@ -344,69 +346,70 @@ am__objects_26 = base/base.lo base/base_error.lo base/hash.lo \
@LIBTDB_TRUE@am__objects_27 = db/tdb.lo
@MONGODB_TRUE@am__objects_28 = net/client/mongodb.lo
@HTTP2_TRUE@am__objects_29 = utility/http2.lo
@HTTP3_TRUE@am__objects_30 = utility/http3.lo
@STDCPP_TRUE@am__objects_31 = internal/objectIO.lo
@PTHREAD_TRUE@am__objects_32 = thread.lo
@DEBUG_TRUE@am__objects_33 = debug/debug_common.lo debug/trace.lo \
@HTTP3_TRUE@am__objects_30 = utility/http3.lo utility/uquic.lo
@HTTP2_FALSE@@HTTP3_TRUE@am__objects_31 = utility/http2.lo
@STDCPP_TRUE@am__objects_32 = internal/objectIO.lo
@PTHREAD_TRUE@am__objects_33 = thread.lo
@DEBUG_TRUE@am__objects_34 = debug/debug_common.lo debug/trace.lo \
@DEBUG_TRUE@ debug/error_memory.lo debug/error_simulation.lo
@DEBUG_TRUE@@STDCPP_TRUE@am__objects_34 = debug/objectDB.lo
@ZIP_TRUE@am__objects_35 = zip/zip.lo
@USE_PARSER_TRUE@am__objects_36 = flex/flexer.lo flex/bison.lo
@PCRE_TRUE@am__objects_37 = pcre/pcre.lo
@SSL_TRUE@am__objects_38 = ssl/certificate.lo ssl/pkcs7.lo ssl/crl.lo \
@DEBUG_TRUE@@STDCPP_TRUE@am__objects_35 = debug/objectDB.lo
@ZIP_TRUE@am__objects_36 = zip/zip.lo
@USE_PARSER_TRUE@am__objects_37 = flex/flexer.lo flex/bison.lo
@PCRE_TRUE@am__objects_38 = pcre/pcre.lo
@SSL_TRUE@am__objects_39 = ssl/certificate.lo ssl/pkcs7.lo ssl/crl.lo \
@SSL_TRUE@ ssl/pkcs10.lo net/client/twilio.lo \
@SSL_TRUE@ net/client/uwebsocket.lo ssl/mime/mime_pkcs7.lo \
@SSL_TRUE@ ssl/net/sslsocket.lo ssl/net/ssl_session.lo \
@SSL_TRUE@ utility/des3.lo
@SSL_TRUE@@SSL_TS_TRUE@am__objects_39 = ssl/timestamp.lo
@SSH_TRUE@am__objects_40 = ssh/net/sshsocket.lo
@LDAP_TRUE@am__objects_41 = ldap/ldap.lo
@CURL_TRUE@am__objects_42 = curl/curl.lo
@EXPAT_TRUE@am__objects_43 = xml/expat/attribute.lo \
@SSL_TRUE@@SSL_TS_TRUE@am__objects_40 = ssl/timestamp.lo
@SSH_TRUE@am__objects_41 = ssh/net/sshsocket.lo
@LDAP_TRUE@am__objects_42 = ldap/ldap.lo
@CURL_TRUE@am__objects_43 = curl/curl.lo
@EXPAT_TRUE@am__objects_44 = xml/expat/attribute.lo \
@EXPAT_TRUE@ xml/expat/element.lo xml/expat/xml_parser.lo \
@EXPAT_TRUE@ xml/expat/xml2txt.lo xml/soap/soap_fault.lo \
@EXPAT_TRUE@ xml/soap/soap_gen_method.lo \
@EXPAT_TRUE@ xml/soap/soap_parser.lo xml/soap/soap_encoder.lo \
@EXPAT_TRUE@ xml/soap/soap_client.lo
@LIBXML2_TRUE@am__objects_44 = xml/libxml2/node.lo \
@LIBXML2_TRUE@am__objects_45 = xml/libxml2/node.lo \
@LIBXML2_TRUE@ xml/libxml2/document.lo xml/libxml2/schema.lo
@MAGIC_TRUE@am__objects_45 = magic/magic.lo
@DBI_TRUE@am__objects_46 = dbi/dbi.lo
@LIBEVENT_TRUE@am__objects_47 = libevent/event.lo
@MINGW_FALSE@am__objects_48 = net/unixsocket.lo
@STATIC_HANDLER_RPC_TRUE@am__objects_49 = \
@MAGIC_TRUE@am__objects_46 = magic/magic.lo
@DBI_TRUE@am__objects_47 = dbi/dbi.lo
@LIBEVENT_TRUE@am__objects_48 = libevent/event.lo
@MINGW_FALSE@am__objects_49 = net/unixsocket.lo
@STATIC_HANDLER_RPC_TRUE@am__objects_50 = \
@STATIC_HANDLER_RPC_TRUE@ net/server/plugin/mod_rpc.lo
@MOD_SHIB_TRUE@@STATIC_HANDLER_SHIB_TRUE@am__objects_50 = net/server/plugin/mod_shib/mod_shib.lo
@STATIC_HANDLER_STREAM_TRUE@am__objects_51 = \
@MOD_SHIB_TRUE@@STATIC_HANDLER_SHIB_TRUE@am__objects_51 = net/server/plugin/mod_shib/mod_shib.lo
@STATIC_HANDLER_STREAM_TRUE@am__objects_52 = \
@STATIC_HANDLER_STREAM_TRUE@ net/server/plugin/mod_stream.lo
@STATIC_HANDLER_NOCAT_TRUE@am__objects_52 = \
@STATIC_HANDLER_NOCAT_TRUE@am__objects_53 = \
@STATIC_HANDLER_NOCAT_TRUE@ net/server/plugin/mod_nocat.lo
@STATIC_HANDLER_NODOG_TRUE@am__objects_53 = \
@STATIC_HANDLER_NODOG_TRUE@am__objects_54 = \
@STATIC_HANDLER_NODOG_TRUE@ net/server/plugin/mod_nodog.lo
@STATIC_HANDLER_SOCKET_TRUE@am__objects_54 = \
@STATIC_HANDLER_SOCKET_TRUE@am__objects_55 = \
@STATIC_HANDLER_SOCKET_TRUE@ net/server/plugin/mod_socket.lo
@STATIC_HANDLER_SCGI_TRUE@am__objects_55 = \
@STATIC_HANDLER_SCGI_TRUE@am__objects_56 = \
@STATIC_HANDLER_SCGI_TRUE@ net/server/plugin/mod_scgi.lo
@STATIC_HANDLER_FCGI_TRUE@am__objects_56 = \
@STATIC_HANDLER_FCGI_TRUE@am__objects_57 = \
@STATIC_HANDLER_FCGI_TRUE@ net/server/plugin/mod_fcgi.lo
@GEOIP_TRUE@@STATIC_HANDLER_GEOIP_TRUE@am__objects_57 = net/server/plugin/mod_geoip/mod_geoip.lo
@PCRE_TRUE@@STATIC_HANDLER_PROXY_TRUE@am__objects_58 = net/server/plugin/mod_proxy.lo
@EXPAT_TRUE@@STATIC_HANDLER_SOAP_TRUE@am__objects_59 = net/server/plugin/mod_soap.lo
@STATIC_HANDLER_SSI_TRUE@am__objects_60 = \
@GEOIP_TRUE@@STATIC_HANDLER_GEOIP_TRUE@am__objects_58 = net/server/plugin/mod_geoip/mod_geoip.lo
@PCRE_TRUE@@STATIC_HANDLER_PROXY_TRUE@am__objects_59 = net/server/plugin/mod_proxy.lo
@EXPAT_TRUE@@STATIC_HANDLER_SOAP_TRUE@am__objects_60 = net/server/plugin/mod_soap.lo
@STATIC_HANDLER_SSI_TRUE@am__objects_61 = \
@STATIC_HANDLER_SSI_TRUE@ net/server/plugin/mod_ssi.lo
@STATIC_HANDLER_TSA_TRUE@am__objects_61 = \
@STATIC_HANDLER_TSA_TRUE@am__objects_62 = \
@STATIC_HANDLER_TSA_TRUE@ net/server/plugin/mod_tsa.lo
@STATIC_HANDLER_HTTP_TRUE@am__objects_62 = \
@STATIC_HANDLER_HTTP_TRUE@am__objects_63 = \
@STATIC_HANDLER_HTTP_TRUE@ net/server/plugin/mod_http.lo
@STATIC_HANDLER_ECHO_TRUE@am__objects_63 = \
@STATIC_HANDLER_ECHO_TRUE@am__objects_64 = \
@STATIC_HANDLER_ECHO_TRUE@ net/server/plugin/mod_echo.lo
@STATIC_ORM_DRIVER_SQLITE_TRUE@am__objects_64 = orm/driver/orm_driver_sqlite.lo
@STATIC_ORM_DRIVER_MYSQL_TRUE@am__objects_65 = \
@STATIC_ORM_DRIVER_SQLITE_TRUE@am__objects_65 = orm/driver/orm_driver_sqlite.lo
@STATIC_ORM_DRIVER_MYSQL_TRUE@am__objects_66 = \
@STATIC_ORM_DRIVER_MYSQL_TRUE@ orm/driver/orm_driver_mysql.lo
@STATIC_ORM_DRIVER_PGSQL_TRUE@am__objects_66 = \
@STATIC_ORM_DRIVER_PGSQL_TRUE@am__objects_67 = \
@STATIC_ORM_DRIVER_PGSQL_TRUE@ orm/driver/orm_driver_pgsql.lo
am__objects_67 =
am__objects_68 = internal/common.lo internal/error.lo \
am__objects_68 =
am__objects_69 = internal/common.lo internal/error.lo \
internal/memory_pool.lo ui/dialog.lo db/cdb.lo db/rdb.lo \
dynamic/dynamic.lo dynamic/plugin.lo mime/header.lo \
mime/entity.lo mime/multipart.lo container/vector.lo \
@ -445,9 +448,10 @@ am__objects_68 = internal/common.lo internal/error.lo \
$(am__objects_56) $(am__objects_57) $(am__objects_58) \
$(am__objects_59) $(am__objects_60) $(am__objects_61) \
$(am__objects_62) $(am__objects_63) $(am__objects_64) \
$(am__objects_65) $(am__objects_66) $(am__objects_67)
$(am__objects_65) $(am__objects_66) $(am__objects_67) \
$(am__objects_68)
@FINAL_FALSE@am_lib@ULIB@_la_OBJECTS = $(am__objects_26) \
@FINAL_FALSE@ $(am__objects_68)
@FINAL_FALSE@ $(am__objects_69)
@FINAL_TRUE@am_lib@ULIB@_la_OBJECTS = all_c.lo all_cpp.lo
lib@ULIB@_la_OBJECTS = $(am_lib@ULIB@_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
@ -581,7 +585,7 @@ am__depfiles_remade = ./$(DEPDIR)/all_c.Plo ./$(DEPDIR)/all_cpp.Plo \
utility/$(DEPDIR)/semaphore.Plo utility/$(DEPDIR)/services.Plo \
utility/$(DEPDIR)/socket_ext.Plo \
utility/$(DEPDIR)/string_ext.Plo utility/$(DEPDIR)/uhttp.Plo \
utility/$(DEPDIR)/websocket.Plo \
utility/$(DEPDIR)/uquic.Plo utility/$(DEPDIR)/websocket.Plo \
xml/expat/$(DEPDIR)/attribute.Plo \
xml/expat/$(DEPDIR)/element.Plo \
xml/expat/$(DEPDIR)/xml2txt.Plo \
@ -918,15 +922,15 @@ SRC_C = base/base.c base/base_error.c base/hash.c base/utility.c \
base/miniz/miniz.c base/coder/cbase64.c \
base/coder/cquoted_printable.c base/coder/curl_coder.c \
base/coder/cxml_coder.c base/coder/cescape.c \
base/coder/chexdump.c $(am__append_7) $(am__append_10) \
$(am__append_11) $(am__append_12) $(am__append_13) \
$(am__append_14) $(am__append_15) $(am__append_16) \
$(am__append_17) $(am__append_18) $(am__append_19) \
$(am__append_20) $(am__append_21) $(am__append_22) \
$(am__append_23) $(am__append_24) $(am__append_25) \
$(am__append_26) $(am__append_27) $(am__append_28) \
$(am__append_29) $(am__append_30) $(am__append_32) \
$(am__append_35) $(am__append_46)
base/coder/chexdump.c $(am__append_8) $(am__append_11) \
$(am__append_12) $(am__append_13) $(am__append_14) \
$(am__append_15) $(am__append_16) $(am__append_17) \
$(am__append_18) $(am__append_19) $(am__append_20) \
$(am__append_21) $(am__append_22) $(am__append_23) \
$(am__append_24) $(am__append_25) $(am__append_26) \
$(am__append_27) $(am__append_28) $(am__append_29) \
$(am__append_30) $(am__append_31) $(am__append_33) \
$(am__append_36) $(am__append_47)
SRC_CPP = internal/common.cpp internal/error.cpp \
internal/memory_pool.cpp ui/dialog.cpp db/cdb.cpp db/rdb.cpp \
dynamic/dynamic.cpp dynamic/plugin.cpp mime/header.cpp \
@ -958,20 +962,20 @@ SRC_CPP = internal/common.cpp internal/error.cpp \
application.cpp cache.cpp date.cpp url.cpp tokenizer.cpp \
command.cpp $(am__append_1) $(am__append_2) $(am__append_3) \
$(am__append_4) $(am__append_5) $(am__append_6) \
$(am__append_8) $(am__append_9) $(am__append_31) \
$(am__append_33) $(am__append_34) $(am__append_36) \
$(am__append_7) $(am__append_9) $(am__append_10) \
$(am__append_32) $(am__append_34) $(am__append_35) \
$(am__append_37) $(am__append_38) $(am__append_39) \
$(am__append_40) $(am__append_41) $(am__append_42) \
$(am__append_43) $(am__append_44) $(am__append_45) \
$(am__append_47) $(am__append_48) $(am__append_49) \
$(am__append_46) $(am__append_48) $(am__append_49) \
$(am__append_50) $(am__append_51) $(am__append_52) \
$(am__append_53) $(am__append_54) $(am__append_55) \
$(am__append_56) $(am__append_57) $(am__append_58) \
$(am__append_59) $(am__append_60) $(am__append_61) \
$(am__append_62) $(am__append_63) $(am__append_64) \
$(am__append_65) $(am__append_68)
lib@ULIB@_la_LDFLAGS = @ULIB_LIBS@ $(am__append_66) -version-info \
1:0:0 -release @ULIB_VERSION@ $(am__append_67)
$(am__append_65) $(am__append_66) $(am__append_69)
lib@ULIB@_la_LDFLAGS = @ULIB_LIBS@ $(am__append_67) -version-info \
1:0:0 -release @ULIB_VERSION@ $(am__append_68)
@MINGW_TRUE@lib@ULIB@_la_DEPENDENCIES = ULib-win32-res.o
@FINAL_FALSE@lib@ULIB@_la_SOURCES = $(SRC_C) $(SRC_CPP)
@FINAL_TRUE@lib@ULIB@_la_SOURCES = all_c.c all_cpp.cpp
@ -1402,6 +1406,8 @@ utility/http2.lo: utility/$(am__dirstamp) \
utility/$(DEPDIR)/$(am__dirstamp)
utility/http3.lo: utility/$(am__dirstamp) \
utility/$(DEPDIR)/$(am__dirstamp)
utility/uquic.lo: utility/$(am__dirstamp) \
utility/$(DEPDIR)/$(am__dirstamp)
internal/objectIO.lo: internal/$(am__dirstamp) \
internal/$(DEPDIR)/$(am__dirstamp)
debug/$(am__dirstamp):
@ -1887,6 +1893,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@utility/$(DEPDIR)/socket_ext.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@utility/$(DEPDIR)/string_ext.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@utility/$(DEPDIR)/uhttp.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@utility/$(DEPDIR)/uquic.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@utility/$(DEPDIR)/websocket.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@xml/expat/$(DEPDIR)/attribute.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@xml/expat/$(DEPDIR)/element.Plo@am__quote@ # am--include-marker
@ -2491,6 +2498,7 @@ distclean: distclean-recursive
-rm -f utility/$(DEPDIR)/socket_ext.Plo
-rm -f utility/$(DEPDIR)/string_ext.Plo
-rm -f utility/$(DEPDIR)/uhttp.Plo
-rm -f utility/$(DEPDIR)/uquic.Plo
-rm -f utility/$(DEPDIR)/websocket.Plo
-rm -f xml/expat/$(DEPDIR)/attribute.Plo
-rm -f xml/expat/$(DEPDIR)/element.Plo
@ -2718,6 +2726,7 @@ maintainer-clean: maintainer-clean-recursive
-rm -f utility/$(DEPDIR)/socket_ext.Plo
-rm -f utility/$(DEPDIR)/string_ext.Plo
-rm -f utility/$(DEPDIR)/uhttp.Plo
-rm -f utility/$(DEPDIR)/uquic.Plo
-rm -f utility/$(DEPDIR)/websocket.Plo
-rm -f xml/expat/$(DEPDIR)/attribute.Plo
-rm -f xml/expat/$(DEPDIR)/element.Plo

View File

@ -112,6 +112,7 @@
# include "utility/http2.cpp"
# endif
# ifndef U_HTTP3_DISABLE
# include "utility/uquic.cpp"
# include "utility/http3.cpp"
# endif
# ifdef ENABLE_ZIP

View File

@ -4945,7 +4945,7 @@ void UServer_Base::logNewClient()
setClientAddress();
#ifndef U_HTTP3_DISABLE
U_INTERNAL_DUMP("UHTTP3::conn_id = %M", UHTTP3::conn_id, UHTTP3::conn_id_len)
U_INTERNAL_DUMP("UQuic::conn_id = %M", UQuic::conn_id, UQuic::conn_id_len)
#endif
#ifndef U_LOG_DISABLE
@ -5456,9 +5456,9 @@ void UServer_Base::runLoop(const char* user)
rbuffer->size_adjust_force(result);
if (UHTTP3::parseHeader() == false) goto next;
if (UQuic::parseHeader() == false) goto next;
if ((blookup = UHTTP3::lookup()) == false)
if ((blookup = UQuic::lookup()) == false)
{
logNewClient();
@ -5468,7 +5468,7 @@ void UServer_Base::runLoop(const char* user)
if (pthis->handlerAccept(-1) == false) goto next;
pClientImage->conn = UHTTP3::conn;
pClientImage->conn = UQuic::conn;
pClientImage->http3 = UHTTP3::http3;
pClientImage->socket->setFd(pClientImage->fd = fds[0]);
@ -5482,7 +5482,7 @@ void UServer_Base::runLoop(const char* user)
U_DUMP("result = %d csocket->isClosed() = %b U_ClientImage_close = %b", result, csocket->isClosed(), U_ClientImage_close)
// if (blookup == false) UHTTP3::insert();
// if (blookup == false) UQuic::insert();
}
next: prepareOperation(UClientImage_Base::_RECVMSG);

View File

@ -114,7 +114,7 @@ const UString* UString::str_pgsql_name;
const UString* UString::str_sqlite_name;
const UString* UString::str_dbdir;
const UString* UString::str_memory;
#ifndef U_HTTP2_DISABLE
#if !defined(U_HTTP2_DISABLE) || !defined(U_HTTP3_DISABLE)
const UString* UString::str_authority;
const UString* UString::str_method;
const UString* UString::str_method_get;
@ -181,10 +181,10 @@ const UString* UString::str_www_authenticate;
const UString* UString::str_ULib;
#endif
#ifdef U_HTTP2_DISABLE
static ustringrep stringrep_storage[75] = {
#else
#if !defined(U_HTTP2_DISABLE) || !defined(U_HTTP3_DISABLE)
static ustringrep stringrep_storage[139] = {
#else
static ustringrep stringrep_storage[75] = {
#endif
{ U_STRINGREP_FROM_CONSTANT("host") },
{ U_STRINGREP_FROM_CONSTANT("chunked") },
@ -270,7 +270,7 @@ static ustringrep stringrep_storage[139] = {
{ U_STRINGREP_FROM_CONSTANT("auto-reconnect") },
// ORM PGSQL
{ U_STRINGREP_FROM_CONSTANT("pgsql") },
#ifndef U_HTTP2_DISABLE
#if !defined(U_HTTP2_DISABLE) || !defined(U_HTTP3_DISABLE)
{ U_STRINGREP_FROM_CONSTANT(":authority") },
{ U_STRINGREP_FROM_CONSTANT(":method") },
{ U_STRINGREP_FROM_CONSTANT("GET") },
@ -530,7 +530,7 @@ void UString::str_allocate(int which)
U_NEW_ULIB_STRING(str_auto_reconnect, UString(stringrep_storage+STR_ALLOCATE_INDEX_ORM+13));
U_NEW_ULIB_STRING(str_pgsql_name, UString(stringrep_storage+STR_ALLOCATE_INDEX_ORM+14));
}
#ifndef U_HTTP2_DISABLE
#if !defined(U_HTTP2_DISABLE) || !defined(U_HTTP3_DISABLE)
else if ((which & STR_ALLOCATE_HTTP2) != 0)
{
U_INTERNAL_ASSERT_EQUALS(str_authority, U_NULLPTR)

View File

@ -160,9 +160,9 @@ UHTTP2::Connection::Connection() : itable(64, setIndexStaticTable)
hpack_error[i].desc = d
#endif
void UHTTP2::ctor()
void UHTTP2::buildTable()
{
U_TRACE_NO_PARAM(0+256, "UHTTP2::ctor()")
U_TRACE_NO_PARAM(0+256, "UHTTP2::buildTable()")
UString::str_allocate(STR_ALLOCATE_HTTP2);
@ -293,6 +293,13 @@ void UHTTP2::ctor()
hash_static_table[59] = UString::str_via->hashIgnoreCase();
hpack_static_table[60].name = UString::str_www_authenticate->rep;
hash_static_table[60] = UString::str_www_authenticate->hashIgnoreCase();
}
void UHTTP2::ctor()
{
U_TRACE_NO_PARAM(0+256, "UHTTP2::ctor()")
buildTable();
#ifdef DEBUG
if (btest)
@ -3084,7 +3091,8 @@ void UHTTP2::downgradeRequest()
if (sz)
{
if (U_http_content_type_len) UClientImage_Base::request->snprintf_add(U_CONSTANT_TO_PARAM("Content-Type: %.*s\r\n"), U_HTTP_CTYPE_TO_TRACE);
UClientImage_Base::request->snprintf_add(U_CONSTANT_TO_PARAM("Content-Length: %u\r\n"), sz);
UClientImage_Base::request->snprintf_add(U_CONSTANT_TO_PARAM("Content-Length: %u\r\n"), sz);
}
pConnection->itable.callForAllEntry(copyHeaders);
@ -3583,7 +3591,7 @@ process_request:
U_SRV_LOG_WITH_ADDR("send response (HTTP2,id:%u,bytes:%u) %#.*S to", pStream->id, sz0, sz0, ptr0);
if (USocketExt::write(UServer_Base::csocket, ptr0, sz0, 0) != (int)sz0) nerror = CONNECT_ERROR;
if (USocketExt::write(UServer_Base::csocket, ptr0, sz0, 0) != sz0) nerror = CONNECT_ERROR;
# ifdef DEBUG
// (void) UFile::writeToTmp(ptr0, sz0, O_RDWR | O_TRUNC, U_CONSTANT_TO_PARAM("load_balance_response.%P"), 0);

View File

@ -7,330 +7,90 @@
// http3.cpp - HTTP/3 utility
//
// = AUTHOR
// Stefano Casazza
// Stefano Casazza + Victor Stewart
//
// ============================================================================
#include <ulib/utility/uhttp.h>
#include <ulib/utility/http3.h>
size_t UHTTP3::scid_len;
size_t UHTTP3::token_len;
size_t UHTTP3::conn_id_len;
uint8_t UHTTP3::pkt_type;
uint8_t UHTTP3::token[U_MAX_TOKEN_LEN];
uint8_t UHTTP3::scid[QUICHE_MAX_CONN_ID_LEN];
uint8_t UHTTP3::conn_id[QUICHE_MAX_CONN_ID_LEN];
uint32_t UHTTP3::pkt_version;
uint32_t UHTTP3::headers_len;
uint32_t UHTTP3::peer_addr_len;
quiche_conn* UHTTP3::conn;
quiche_config* UHTTP3::qconfig;
quiche_h3_conn* UHTTP3::http3;
quiche_h3_header* UHTTP3::headers;
quiche_h3_config* UHTTP3::http3_config;
struct sockaddr_storage UHTTP3::peer_addr;
UHashMap<UClientImage_Base*>* UHTTP3::peers;
uint32_t UHTTP3::headers_len;
quiche_h3_conn* UHTTP3::http3;
quiche_h3_header* UHTTP3::headers;
quiche_h3_config* UHTTP3::http3_config;
UHashMap<UString>* UHTTP3::itable; // headers request
int UHTTP3::loadConfigParam()
{
U_TRACE_NO_PARAM(0, "UHTTP3::loadConfigParam()")
U_INTERNAL_ASSERT(UServer_Base::budp)
U_INTERNAL_ASSERT_POINTER(UServer_Base::pcfg)
#ifndef USE_LIBQUICHE
U_ERROR("Sorry, I was compiled without libquiche so there isn't HTTP/3 support");
#endif
if (UServer_Base::key_file->empty() ||
UServer_Base::cert_file->empty())
if (UQuic::loadConfigParam() == U_PLUGIN_HANDLER_OK)
{
U_ERROR("You need to specify in configuration file the property KEY_FILE and CERT_FILE");
}
// Stores configuration shared between multiple connections
http3_config = (quiche_h3_config*) U_SYSCALL_NO_PARAM(quiche_h3_config_new); // Creates an HTTP/3 config object with default settings values
#ifdef DEBUG
// (void) U_SYSCALL(quiche_enable_debug_logging, "%p,%p", quiche_debug_log, U_NULLPTR);
#endif
// Stores configuration shared between multiple connections
qconfig = (quiche_config*) U_SYSCALL(quiche_config_new, "%u", QUICHE_PROTOCOL_VERSION);
http3_config = (quiche_h3_config*) U_SYSCALL_NO_PARAM(quiche_h3_config_new); // Creates an HTTP/3 config object with default settings values
if (qconfig == U_NULLPTR ||
http3_config == U_NULLPTR)
{
U_ERROR("Failed to create quiche/HTTP3 config");
}
// Configures the given certificate chain
(void) U_SYSCALL(quiche_config_load_cert_chain_from_pem_file, "%p,%S", qconfig, UServer_Base::cert_file->data());
// Configures the given private key
(void) U_SYSCALL(quiche_config_load_priv_key_from_pem_file, "%p,%S", qconfig, UServer_Base::key_file->data());
// Configures the list of supported application protocols
(void) U_SYSCALL(quiche_config_set_application_protos, "%p,%p,%u", qconfig, (uint8_t*)U_CONSTANT_TO_PARAM(QUICHE_H3_APPLICATION_PROTOCOL));
if (UServer_Base::pcfg->searchForObjectStream(U_CONSTANT_TO_PARAM("http3")))
{
UServer_Base::pcfg->table.clear();
if (UServer_Base::pcfg->loadTable())
if (http3_config == U_NULLPTR)
{
// --------------------------------------------------------------------------------------------------------------------------------------
// userver_udp - http3 configuration parameters
// --------------------------------------------------------------------------------------------------------------------------------------
// QUICHE_GREASE Whether to send GREASE
// QUICHE_LOG_KEYS Enables logging of secrets
// QUICHE_VERIFY_PEER Whether to verify the peer's certificate
// QUICHE_CC_ALGORITHM Sets the congestion control algorithm used
// QUICHE_MAX_ACK_DELAY Sets the `max_ack_delay` transport parameter
// QUICHE_MAX_PACKET_SIZE Sets the max_packet_size transport parameter
// QUICHE_MAX_IDLE_TIMEOUT Sets the `max_idle_timeout` transport parameter
// QUICHE_INITIAL_MAX_DATA Sets the `initial_max_data` transport parameter
// QUICHE_ENABLE_EARLY_DATA Enables sending or receiving early data
// QUICHE_ACK_DELAY_EXPONENT Sets the `ack_delay_exponent` transport parameter
// QUICHE_MAX_UDP_PAYLOAD_SIZE Sets the `max_udp_payload_size` transport parameter
// QUICHE_INITIAL_MAX_STREAM_UNI Sets the `initial_max_streams_uni` transport parameter
// QUICHE_DISABLE_ACTIVE_MIGRATION Sets the `disable_active_migration` transport parameter
// QUICHE_INITIAL_MAX_STREAMS_BIDI Sets the `initial_max_streams_bidi` transport parameter
// QUICHE_INITIAL_MAX_STREAM_DATA_UNI Sets the `initial_max_stream_data_uni` transport parameter
// QUICHE_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL Sets the `initial_max_stream_data_bidi_local` transport parameter
// QUICHE_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE Sets the `initial_max_stream_data_bidi_remote` transport parameter
//
// QUICHE_H3_MAX_HEADER_LIST_SIZE Sets the `SETTINGS_MAX_HEADER_LIST_SIZE` setting
// QUICHE_H3_QPACK_BLOCKED_STREAMS Sets the `SETTINGS_QPACK_BLOCKED_STREAMS` setting
// QUICHE_H3_QPACK_MAX_TABLE_CAPACITY Sets the `SETTINGS_QPACK_BLOCKED_STREAMS` setting
// --------------------------------------------------------------------------------------------------------------------------------------
U_ERROR("Failed to create HTTP3 config");
}
long param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_MAX_IDLE_TIMEOUT"), 180000);
bool param1 = UServer_Base::pcfg->readBoolean(U_CONSTANT_TO_PARAM("QUICHE_DISABLE_ACTIVE_MIGRATION"), true);
// Configures the list of supported application protocols
(void) U_SYSCALL(quiche_config_set_application_protos, "%p,%p,%u", UQuic::qconfig, (uint8_t*)U_CONSTANT_TO_PARAM(QUICHE_H3_APPLICATION_PROTOCOL));
U_SYSCALL_VOID(quiche_config_set_max_idle_timeout, "%p,%lu", qconfig, param0);
U_SYSCALL_VOID(quiche_config_set_disable_active_migration, "%p,%b", qconfig, param1);
if (UServer_Base::pcfg->searchForObjectStream(U_CONSTANT_TO_PARAM("http3")))
{
UServer_Base::pcfg->table.clear();
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_CC_ALGORITHM"), 0); // QUICHE_CC_RENO = 0
if (UServer_Base::pcfg->loadTable())
{
// --------------------------------------------------------------------------------------------------------------------------------------
// userver_udp - http3 configuration parameters
// --------------------------------------------------------------------------------------------------------------------------------------
// QUICHE_H3_MAX_HEADER_LIST_SIZE Sets the `SETTINGS_MAX_HEADER_LIST_SIZE` setting
// QUICHE_H3_QPACK_BLOCKED_STREAMS Sets the `SETTINGS_QPACK_BLOCKED_STREAMS` setting
// QUICHE_H3_QPACK_MAX_TABLE_CAPACITY Sets the `SETTINGS_QPACK_BLOCKED_STREAMS` setting
// --------------------------------------------------------------------------------------------------------------------------------------
U_SYSCALL_VOID(quiche_config_set_cc_algorithm, "%p,%lu", qconfig, (quiche_cc_algorithm)param0);
/*
long param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_H3_MAX_HEADER_LIST_SIZE"), 16384);
# ifdef LIBQUICHE_AT_LEAST_0_5
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_MAX_UDP_PAYLOAD_SIZE"), U_MAX_DATAGRAM_SIZE);
U_SYSCALL_VOID(quiche_h3_config_set_max_header_list_size, "%p,%lu", http3_config, param0);
*/
U_SYSCALL_VOID(quiche_config_set_max_udp_payload_size, "%p,%lu", qconfig, param0);
# else
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_MAX_PACKET_SIZE"), U_MAX_DATAGRAM_SIZE);
/** TODO
U_SYSCALL_VOID(quiche_config_set_max_packet_size, "%p,%lu", qconfig, param0);
# endif
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_H3_QPACK_BLOCKED_STREAMS"), ???);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_INITIAL_MAX_DATA"), 10485760);
U_SYSCALL_VOID(quiche_h3_config_set_qpack_blocked_streams, "%p,%lu", http3_config, param0);
U_SYSCALL_VOID(quiche_config_set_initial_max_data, "%p,%lu", qconfig, param0);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_H3_QPACK_MAX_TABLE_CAPACITY"), ???);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_INITIAL_MAX_STREAM_UNI"), 3); // For HTTP/3 we only need 3 unidirectional streams
U_SYSCALL_VOID(quiche_h3_config_set_qpack_max_table_capacity, "%p,%lu", http3_config, param0);
*/
U_SYSCALL_VOID(quiche_config_set_initial_max_streams_uni, "%p,%lu", qconfig, param0);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_INITIAL_MAX_STREAMS_BIDI"), 128);
U_SYSCALL_VOID(quiche_config_set_initial_max_streams_bidi, "%p,%lu", qconfig, param0);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_INITIAL_MAX_STREAM_DATA_UNI"), 1048576);
U_SYSCALL_VOID(quiche_config_set_initial_max_stream_data_uni, "%p,%lu", qconfig, param0);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL"), 1000000);
U_SYSCALL_VOID(quiche_config_set_initial_max_stream_data_bidi_local, "%p,%lu", qconfig, param0);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE"), 1048576);
U_SYSCALL_VOID(quiche_config_set_initial_max_stream_data_bidi_remote, "%p,%lu", qconfig, param0);
/*
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_MAX_ACK_DELAY"), 25);
U_SYSCALL_VOID(quiche_config_set_max_ack_delay, "%p,%lu", qconfig, param0);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_ACK_DELAY_EXPONENT"), 3);
U_SYSCALL_VOID(quiche_config_set_ack_delay_exponent, "%p,%lu", qconfig, param0);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_H3_MAX_HEADER_LIST_SIZE"), 16384);
U_SYSCALL_VOID(quiche_h3_config_set_max_header_list_size, "%p,%lu", http3_config, param0);
*/
if (UServer_Base::pcfg->readBoolean(U_CONSTANT_TO_PARAM("QUICHE_ENABLE_EARLY_DATA"), false)) U_SYSCALL_VOID(quiche_config_enable_early_data, "%p", qconfig);
/** TODO
void quiche_config_log_keys(quiche_config *config);
void quiche_config_grease(quiche_config *config, bool v);
void quiche_config_verify_peer(quiche_config *config, bool v);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_H3_QPACK_BLOCKED_STREAMS"), ???);
U_SYSCALL_VOID(quiche_h3_config_set_qpack_blocked_streams, "%p,%lu", http3_config, param0);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_H3_QPACK_MAX_TABLE_CAPACITY"), ???);
U_SYSCALL_VOID(quiche_h3_config_set_qpack_max_table_capacity, "%p,%lu", http3_config, param0);
*/
UServer_Base::pcfg->reset();
UServer_Base::pcfg->reset();
}
}
}
U_RETURN(U_PLUGIN_HANDLER_OK);
}
bool UHTTP3::parseHeader()
int UHTTP3::for_each_header(uint8_t* name, size_t name_len, uint8_t* value, size_t value_len, void* argp)
{
U_TRACE_NO_PARAM(0, "UHTTP3::parseHeader()")
U_TRACE(0, "UHTTP3::for_each_header(%.*S,%u,%.*S,%u,%p)", name_len, name, name_len, value_len, value, value_len, argp)
// Parse the QUIC packet's header
/*
* quiche: got HTTP header: ":method"(7)="GET"(3)
* quiche: got HTTP header: ":scheme"(7)="https"(5)
* quiche: got HTTP header: ":authority"(10)="127.0.0.1"(9)
* quiche: got HTTP header: ":path"(5)="/"(1)
* quiche: got HTTP header: "user-agent"(10)="quiche"(6)
*/
scid_len =
conn_id_len = QUICHE_MAX_CONN_ID_LEN;
token_len = U_MAX_TOKEN_LEN;
U_INTERNAL_DUMP("quiche: got HTTP header: %.*S(%u)=%.*S(%u)", name_len, name, name_len, value_len, value, value_len)
// Extracts version, type, source / destination connection ID and address verification token from the packet in buffer
int rc = U_SYSCALL(quiche_header_info, "%p,%u,%u,%p,%p,%p,%p,%p,%p,%p,%p", (const uint8_t*)U_STRING_TO_PARAM(*UServer_Base::rbuffer), U_LOCAL_CONN_ID_LEN,
&pkt_version, &pkt_type, scid, &scid_len, conn_id, &conn_id_len, token, &token_len);
if (rc < 0)
{
U_DEBUG("UHTTP3::handlerRead(): failed to parse header: %d", rc)
U_RETURN(false);
}
U_INTERNAL_DUMP("scid(%u) = %#.*S token(%u) = %#.*S conn_id(%u) = %#.*S pkt_version = %p pkt_type = %u",
scid_len, scid_len, scid, token_len, token_len, token, conn_id_len, conn_id_len, conn_id, pkt_version, pkt_type)
U_RETURN(true);
}
bool UHTTP3::handlerRead(quiche_conn* lconn, bool bwait_for_data)
{
U_TRACE(0, "UHTTP3::handlerRead(%p,%b)", lconn, bwait_for_data)
U_ASSERT_EQUALS(UClientImage_Base::rbuffer->capacity(), UServer_Base::rbuffer_size)
int iBytesRead;
char* ptr = UServer_Base::rbuffer->data();
// Read incoming UDP packets from the socket and feed them to quiche, until there are no more packets to read
loop:
peer_addr_len = sizeof(peer_addr);
(void) U_SYSCALL(memset, "%p,%u,%u", &peer_addr, 0, U_SIZE_SOCKADDR);
iBytesRead = U_SYSCALL(recvfrom, "%d,%p,%u,%u,%p,%p", UServer_Base::fds[0], ptr, UServer_Base::rbuffer_size, (bwait_for_data ? 0 : MSG_DONTWAIT),
(struct sockaddr*)&peer_addr, &peer_addr_len);
if (iBytesRead <= 0)
{
if (errno == EAGAIN)
{
U_DEBUG("quiche: recvfrom would block")
U_INTERNAL_ASSERT_EQUALS(bwait_for_data, false)
if (lconn) // reported no read packets, we will then proceed with the send loop
{
uint8_t out[65536];
ssize_t written, sent;
uint32_t start = 0, remain = sizeof(out);
while (true)
{
written = U_SYSCALL(quiche_conn_send, "%p,%p,%u", lconn, &out[start], remain);
if (written == QUICHE_ERR_DONE)
{
U_DEBUG("quiche: done writing")
break;
}
if (written < 0)
{
U_DEBUG("UHTTP3::handlerRead(): failed to create packet: %d", written)
break;
}
start += written;
remain -= written;
U_INTERNAL_ASSERT_MINOR(start, sizeof(out))
U_DEBUG("quiche: sent %u bytes", written)
}
sent = U_SYSCALL(sendto, "%d,%p,%u,%u,%p,%d", UServer_Base::fds[0], out, start, 0, (struct sockaddr*)&USocket::peer_addr, USocket::peer_addr_len);
if (sent != start)
{
U_DEBUG("UHTTP3::handlerRead(): failed to send")
U_RETURN(false);
}
if (U_SYSCALL(quiche_conn_is_closed, "%p", lconn))
{
quiche_stats stats;
U_SYSCALL_VOID(quiche_conn_stats, "%p,%p", lconn, &stats);
U_DEBUG("quiche: connection closed, recv=%u sent=%u lost=%u rtt=%u cwnd=%u", stats.recv, stats.sent, stats.lost, stats.rtt, stats.cwnd)
U_SYSCALL_VOID(quiche_conn_free, "%p", lconn);
U_RETURN(false);
}
}
bwait_for_data = true;
goto loop;
}
U_WARNING("recvfrom on fd %d got %d%R", UServer_Base::fds[0], iBytesRead, 0); // NB: the last argument (0) is necessary...
if (errno == EINTR) UInterrupt::checkForEventSignalPending();
U_RETURN(false);
}
U_INTERNAL_DUMP("peer_addr_len = %u BytesRead(%u) = %#.*S", peer_addr_len, iBytesRead, iBytesRead, ptr)
U_INTERNAL_ASSERT_MAJOR(peer_addr_len, 0)
UServer_Base::rbuffer->size_adjust_force(iBytesRead);
if (memcmp(&peer_addr, &USocket::peer_addr, peer_addr_len) != 0)
{
// TODO
U_WARNING("recvfrom() different address");
/* Lookup a connection based on the packet's connection ID. If there is no connection matching, create a new one
if (lookup())
{
}
*/
}
if (lconn || parseHeader()) U_RETURN(true);
U_RETURN(false);
U_RETURN(0);
}
void UHTTP3::handlerRequest(quiche_conn* lconn, quiche_h3_conn* lh3)
@ -351,8 +111,8 @@ void UHTTP3::handlerRequest(quiche_conn* lconn, quiche_h3_conn* lh3)
if (s < 0)
{
if (handlerRead(lconn, true) &&
processesPackets(lconn))
if (UQuic::handlerRead(lconn, true) &&
UQuic::processesPackets(lconn))
{
continue;
}
@ -360,12 +120,22 @@ void UHTTP3::handlerRequest(quiche_conn* lconn, quiche_h3_conn* lh3)
break;
}
U_INTERNAL_DUMP("quiche_h3_event_type(ev) = %d", quiche_h3_event_type(ev))
switch (quiche_h3_event_type(ev))
{
case QUICHE_H3_EVENT_HEADERS:
{
if (itable->empty() == false)
{
U_DUMP_CONTAINER(*itable)
itable->clear();
}
// Iterates over the headers in the event. The `cb` callback will be called for each header in `ev`. `cb` should check the validity of
// pseudo-headers and headers. If `cb` returns any value other than `0`, processing will be interrupted and the value is returned to the caller
rc = U_SYSCALL(quiche_h3_event_for_each_header, "%p,%p,%p", ev, for_each_header, 0);
if (rc != 0)
@ -373,11 +143,14 @@ void UHTTP3::handlerRequest(quiche_conn* lconn, quiche_h3_conn* lh3)
U_DEBUG("UHTTP3::handlerRequest(): failed to process headers: %d", rc)
}
// Sends an HTTP/3 response on the specified stream
(void) U_SYSCALL(quiche_h3_send_response, "%p,%p,%lu,%p,%p,%b", lh3, lconn, s, headers, headers_len, false);
// Sends an HTTP/3 body chunk on the given stream.
(void) U_SYSCALL(quiche_h3_send_body, "%p,%p,%lu,%p,%p", lh3, lconn, s, (uint8_t*)U_STRING_TO_PARAM(*UHTTP::body), true);
U_INTERNAL_DUMP("Host = %.*S", U_HTTP_HOST_TO_TRACE)
U_INTERNAL_DUMP("Range = %.*S", U_HTTP_RANGE_TO_TRACE)
U_INTERNAL_DUMP("Accept = %.*S", U_HTTP_ACCEPT_TO_TRACE)
U_INTERNAL_DUMP("Cookie = %.*S", U_HTTP_COOKIE_TO_TRACE)
U_INTERNAL_DUMP("Referer = %.*S", U_HTTP_REFERER_TO_TRACE)
U_INTERNAL_DUMP("User-Agent = %.*S", U_HTTP_USER_AGENT_TO_TRACE)
U_INTERNAL_DUMP("Content-Type = %.*S", U_HTTP_CTYPE_TO_TRACE)
U_INTERNAL_DUMP("Accept-Language = %.*S", U_HTTP_ACCEPT_LANGUAGE_TO_TRACE)
break;
}
@ -390,7 +163,16 @@ void UHTTP3::handlerRequest(quiche_conn* lconn, quiche_h3_conn* lh3)
}
case QUICHE_H3_EVENT_FINISHED:
break;
{
/* Sends an HTTP/3 response on the specified stream
(void) U_SYSCALL(quiche_h3_send_response, "%p,%p,%lu,%p,%p,%b", lh3, lconn, s, headers, headers_len, false);
// Sends an HTTP/3 body chunk on the given stream.
(void) U_SYSCALL(quiche_h3_send_body, "%p,%p,%lu,%p,%p", lh3, lconn, s, (uint8_t*)U_STRING_TO_PARAM(*UHTTP::body), true);
*/
break;
}
}
U_SYSCALL_VOID(quiche_h3_event_free, "%p", ev);
@ -401,166 +183,21 @@ bool UHTTP3::handlerNewConnection()
{
U_TRACE_NO_PARAM(0, "UHTTP3::handlerNewConnection()")
U_INTERNAL_ASSERT_POINTER(peers)
U_INTERNAL_ASSERT(UServer_Base::budp)
const char* ptr;
ssize_t written, sent;
const char* pkt = "vneg";
uint8_t out[U_MAX_DATAGRAM_SIZE];
conn = U_NULLPTR;
http3 = U_NULLPTR;
loop:
if (pkt_type != Initial)
if (UQuic::handlerNewConnection())
{
U_DEBUG("UHTTP3::handlerNewConnection(): packet is NOT initial: %u", pkt_type)
// Creates a new HTTP/3 connection using the provided QUIC connection
http3 = (quiche_h3_conn*) U_SYSCALL(quiche_h3_conn_new_with_transport, "%p,%p", UQuic::conn, http3_config);
U_RETURN(false);
}
// Client Initial packets must be at least 1200 bytes
if (UServer_Base::rbuffer->size() < QUICHE_MIN_CLIENT_INITIAL_LEN)
{
U_DEBUG("UHTTP3::handlerNewConnection(): quic initial packet is too short: %u", UServer_Base::rbuffer->size())
U_RETURN(false);
}
// Returns true if the given protocol version is supported
if (U_SYSCALL(quiche_version_is_supported, "%u", pkt_version) == false)
{
U_DEBUG("quiche: version negotiation")
// Writes a version negotiation packet
written = U_SYSCALL(quiche_negotiate_version, "%p,%u,%p,%u,%p,%u", scid, scid_len, conn_id, conn_id_len, out, sizeof(out));
pkt: if (written < 0)
if (http3 == U_NULLPTR)
{
U_DEBUG("UHTTP3::handlerNewConnection(): failed to create %S packet: %d", pkt, written)
U_DEBUG("UHTTP3::handlerNewConnection(): failed to create HTTP/3 connection")
U_RETURN(false);
}
sent = U_SYSCALL(sendto, "%u,%p,%u,%u,%p,%d", UServer_Base::fds[0], out, written, 0, (struct sockaddr*)&USocket::peer_addr, USocket::peer_addr_len);
if (sent == written)
{
U_DEBUG("quiche: sent %u bytes", sent)
}
else
{
U_DEBUG("UHTTP3::handlerNewConnection(): failed to send")
U_RETURN(false);
}
if (handlerRead()) goto loop;
U_RETURN(false);
}
if (token_len == 0)
{
// Generate a stateless retry token. The token includes the static string "quiche" followed
// by the IP address of the client and by the original destination connection ID generated by the client
U_DEBUG("quiche: stateless retry")
U_INTERNAL_DUMP("USocket::peer_addr_len = %u", USocket::peer_addr_len)
U_INTERNAL_ASSERT_MAJOR(conn_id_len, 0)
U_INTERNAL_ASSERT_MAJOR(USocket::peer_addr_len, 0)
// 6 -> U_CONSTANT_SIZE("quiche")
U_MEMCPY(token, "quiche", 6);
U_MEMCPY(token + 6, &USocket::peer_addr, USocket::peer_addr_len);
U_MEMCPY(token + 6 + USocket::peer_addr_len, conn_id, conn_id_len);
token_len = 6 + USocket::peer_addr_len + conn_id_len;
U_INTERNAL_DUMP("scid(%u) = %.*S conn_id(%u) = %.*S token(%u) = %.*S pkt_version = %p",
scid_len, scid_len, scid, conn_id_len, conn_id_len, conn_id, token_len, token_len, token, pkt_version)
// Writes a retry packet
# ifdef LIBQUICHE_AT_LEAST_0_5
written = U_SYSCALL(quiche_retry, "%p,%u,%p,%u,%p,%u,%p,%u,%u,%p,%u", scid, scid_len, conn_id, conn_id_len, conn_id, conn_id_len, token, token_len, pkt_version, out, sizeof(out));
# else
written = U_SYSCALL(quiche_retry, "%p,%u,%p,%u,%p,%u,%p,%u, %p,%u", scid, scid_len, conn_id, conn_id_len, conn_id, conn_id_len, token, token_len, out, sizeof(out));
# endif
pkt = "retry";
goto pkt;
}
// Validates a stateless retry token. This checks that the ticket includes the `"quiche"` static string, and that the client IP address matches the address stored in the ticket
if (token_len < 6 ||
memcmp(token, U_CONSTANT_TO_PARAM("quiche")))
{
U_DEBUG("UHTTP3::handlerNewConnection(): invalid address validation token")
U_RETURN(false);
}
token_len -= 6;
ptr = (const char*)&token[0] + 6;
if (token_len < USocket::peer_addr_len ||
memcmp(ptr, &USocket::peer_addr, USocket::peer_addr_len))
{
U_DEBUG("UHTTP3::handlerNewConnection(): invalid address validation token")
U_RETURN(false);
}
ptr += USocket::peer_addr_len;
token_len -= USocket::peer_addr_len;
if (conn_id_len != token_len) // The token was not valid, meaning the retry failed, so drop the packet
{
U_DEBUG("UHTTP3::handlerNewConnection(): invalid address validation token")
U_RETURN(false);
}
// Reuse the source connection ID we sent in the Retry packet, instead of changing it again. Creates a new server-side connection
conn = (quiche_conn*) U_SYSCALL(quiche_accept, "%p,%u,%p,%u,%p", conn_id, conn_id_len, (const uint8_t*)ptr, token_len, qconfig);
if (conn == U_NULLPTR)
{
U_DEBUG("UHTTP3::handlerNewConnection(): failed to create connection")
U_RETURN(false);
}
U_DEBUG("quiche: new connection")
while (processesPackets(conn))
{
if (U_SYSCALL(quiche_conn_is_established, "%p", conn))
{
U_DEBUG("UHTTP3::handlerNewConnection(): connection handshake is complete")
if (http3 == U_NULLPTR)
{
// Creates a new HTTP/3 connection using the provided QUIC connection
http3 = (quiche_h3_conn*) U_SYSCALL(quiche_h3_conn_new_with_transport, "%p,%p", conn, http3_config);
if (http3 == U_NULLPTR)
{
U_DEBUG("UHTTP3::handlerNewConnection(): failed to create HTTP/3 connection")
U_RETURN(false);
}
}
U_RETURN(true);
}
if (handlerRead(conn) == false) U_RETURN(false);
U_RETURN(true);
}
U_RETURN(false);

463
src/ulib/utility/uquic.cpp Normal file
View File

@ -0,0 +1,463 @@
// ============================================================================
//
// = LIBRARY
// ULib - c++ library
//
// = FILENAME
// uquic.cpp - Quic utility
//
// = AUTHOR
// Stefano Casazza + Victor Stewart
//
// ============================================================================
#include <ulib/utility/http3.h>
size_t UQuic::scid_len;
size_t UQuic::token_len;
size_t UQuic::conn_id_len;
uint8_t UQuic::pkt_type;
uint8_t UQuic::token[U_MAX_TOKEN_LEN];
uint8_t UQuic::scid[QUICHE_MAX_CONN_ID_LEN];
uint8_t UQuic::conn_id[QUICHE_MAX_CONN_ID_LEN];
uint32_t UQuic::pkt_version;
uint32_t UQuic::peer_addr_len;
quiche_conn* UQuic::conn;
quiche_config* UQuic::qconfig;
struct sockaddr_storage UQuic::peer_addr;
UHashMap<UClientImage_Base*>* UQuic::peers;
int UQuic::loadConfigParam()
{
U_TRACE_NO_PARAM(0, "UQuic::loadConfigParam()")
U_INTERNAL_ASSERT(UServer_Base::budp)
U_INTERNAL_ASSERT_POINTER(UServer_Base::pcfg)
#ifndef USE_LIBQUICHE
U_ERROR("Sorry, I was compiled without libquiche so there isn't HTTP/3 support");
#endif
if (UServer_Base::key_file->empty() ||
UServer_Base::cert_file->empty())
{
U_ERROR("You need to specify in configuration file the property KEY_FILE and CERT_FILE");
}
#ifdef DEBUG
// (void) U_SYSCALL(quiche_enable_debug_logging, "%p,%p", quiche_debug_log, U_NULLPTR);
#endif
// Stores configuration shared between multiple connections
qconfig = (quiche_config*) U_SYSCALL(quiche_config_new, "%u", QUICHE_PROTOCOL_VERSION);
if (qconfig == U_NULLPTR)
{
U_ERROR("Failed to create quiche config");
}
// Configures the given certificate chain
(void) U_SYSCALL(quiche_config_load_cert_chain_from_pem_file, "%p,%S", qconfig, UServer_Base::cert_file->data());
// Configures the given private key
(void) U_SYSCALL(quiche_config_load_priv_key_from_pem_file, "%p,%S", qconfig, UServer_Base::key_file->data());
if (UServer_Base::pcfg->searchForObjectStream(U_CONSTANT_TO_PARAM("quic")))
{
UServer_Base::pcfg->table.clear();
if (UServer_Base::pcfg->loadTable())
{
// --------------------------------------------------------------------------------------------------------------------------------------
// userver_udp - quic configuration parameters
// --------------------------------------------------------------------------------------------------------------------------------------
// QUICHE_GREASE Whether to send GREASE
// QUICHE_LOG_KEYS Enables logging of secrets
// QUICHE_VERIFY_PEER Whether to verify the peer's certificate
// QUICHE_CC_ALGORITHM Sets the congestion control algorithm used
// QUICHE_MAX_ACK_DELAY Sets the `max_ack_delay` transport parameter
// QUICHE_MAX_PACKET_SIZE Sets the max_packet_size transport parameter
// QUICHE_MAX_IDLE_TIMEOUT Sets the `max_idle_timeout` transport parameter
// QUICHE_INITIAL_MAX_DATA Sets the `initial_max_data` transport parameter
// QUICHE_ENABLE_EARLY_DATA Enables sending or receiving early data
// QUICHE_ACK_DELAY_EXPONENT Sets the `ack_delay_exponent` transport parameter
// QUICHE_MAX_UDP_PAYLOAD_SIZE Sets the `max_udp_payload_size` transport parameter
// QUICHE_INITIAL_MAX_STREAM_UNI Sets the `initial_max_streams_uni` transport parameter
// QUICHE_DISABLE_ACTIVE_MIGRATION Sets the `disable_active_migration` transport parameter
// QUICHE_INITIAL_MAX_STREAMS_BIDI Sets the `initial_max_streams_bidi` transport parameter
// QUICHE_INITIAL_MAX_STREAM_DATA_UNI Sets the `initial_max_stream_data_uni` transport parameter
// QUICHE_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL Sets the `initial_max_stream_data_bidi_local` transport parameter
// QUICHE_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE Sets the `initial_max_stream_data_bidi_remote` transport parameter
// --------------------------------------------------------------------------------------------------------------------------------------
long param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_MAX_IDLE_TIMEOUT"), 180000);
bool param1 = UServer_Base::pcfg->readBoolean(U_CONSTANT_TO_PARAM("QUICHE_DISABLE_ACTIVE_MIGRATION"), true);
U_SYSCALL_VOID(quiche_config_set_max_idle_timeout, "%p,%lu", qconfig, param0);
U_SYSCALL_VOID(quiche_config_set_disable_active_migration, "%p,%b", qconfig, param1);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_CC_ALGORITHM"), 0); // QUICHE_CC_RENO = 0
U_SYSCALL_VOID(quiche_config_set_cc_algorithm, "%p,%lu", qconfig, (quiche_cc_algorithm)param0);
# ifdef LIBQUICHE_AT_LEAST_0_5
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_MAX_UDP_PAYLOAD_SIZE"), U_MAX_DATAGRAM_SIZE);
U_SYSCALL_VOID(quiche_config_set_max_udp_payload_size, "%p,%lu", qconfig, param0);
# else
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_MAX_PACKET_SIZE"), U_MAX_DATAGRAM_SIZE);
U_SYSCALL_VOID(quiche_config_set_max_packet_size, "%p,%lu", qconfig, param0);
# endif
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_INITIAL_MAX_DATA"), 10485760);
U_SYSCALL_VOID(quiche_config_set_initial_max_data, "%p,%lu", qconfig, param0);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_INITIAL_MAX_STREAM_UNI"), 3); // For HTTP/3 we only need 3 unidirectional streams
U_SYSCALL_VOID(quiche_config_set_initial_max_streams_uni, "%p,%lu", qconfig, param0);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_INITIAL_MAX_STREAMS_BIDI"), 128);
U_SYSCALL_VOID(quiche_config_set_initial_max_streams_bidi, "%p,%lu", qconfig, param0);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_INITIAL_MAX_STREAM_DATA_UNI"), 1048576);
U_SYSCALL_VOID(quiche_config_set_initial_max_stream_data_uni, "%p,%lu", qconfig, param0);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL"), 1000000);
U_SYSCALL_VOID(quiche_config_set_initial_max_stream_data_bidi_local, "%p,%lu", qconfig, param0);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE"), 1048576);
U_SYSCALL_VOID(quiche_config_set_initial_max_stream_data_bidi_remote, "%p,%lu", qconfig, param0);
/*
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_MAX_ACK_DELAY"), 25);
U_SYSCALL_VOID(quiche_config_set_max_ack_delay, "%p,%lu", qconfig, param0);
param0 = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("QUICHE_ACK_DELAY_EXPONENT"), 3);
U_SYSCALL_VOID(quiche_config_set_ack_delay_exponent, "%p,%lu", qconfig, param0);
*/
if (UServer_Base::pcfg->readBoolean(U_CONSTANT_TO_PARAM("QUICHE_ENABLE_EARLY_DATA"), false)) U_SYSCALL_VOID(quiche_config_enable_early_data, "%p", qconfig);
/** TODO
void quiche_config_log_keys(quiche_config *config);
void quiche_config_grease(quiche_config *config, bool v);
void quiche_config_verify_peer(quiche_config *config, bool v);
*/
UServer_Base::pcfg->reset();
}
}
U_RETURN(U_PLUGIN_HANDLER_OK);
}
bool UQuic::parseHeader()
{
U_TRACE_NO_PARAM(0, "UQuic::parseHeader()")
// Parse the QUIC packet's header
scid_len =
conn_id_len = QUICHE_MAX_CONN_ID_LEN;
token_len = U_MAX_TOKEN_LEN;
// Extracts version, type, source / destination connection ID and address verification token from the packet in buffer
int rc = U_SYSCALL(quiche_header_info, "%p,%u,%u,%p,%p,%p,%p,%p,%p,%p,%p", (const uint8_t*)U_STRING_TO_PARAM(*UServer_Base::rbuffer), U_LOCAL_CONN_ID_LEN,
&pkt_version, &pkt_type, scid, &scid_len, conn_id, &conn_id_len, token, &token_len);
if (rc < 0)
{
U_DEBUG("UQuic::handlerRead(): failed to parse header: %d", rc)
U_RETURN(false);
}
U_INTERNAL_DUMP("scid(%u) = %#.*S token(%u) = %#.*S conn_id(%u) = %#.*S pkt_version = %p pkt_type = %u",
scid_len, scid_len, scid, token_len, token_len, token, conn_id_len, conn_id_len, conn_id, pkt_version, pkt_type)
U_RETURN(true);
}
bool UQuic::handlerRead(quiche_conn* lconn, bool bwait_for_data)
{
U_TRACE(0, "UQuic::handlerRead(%p,%b)", lconn, bwait_for_data)
U_ASSERT_EQUALS(UClientImage_Base::rbuffer->capacity(), UServer_Base::rbuffer_size)
int iBytesRead;
char* ptr = UServer_Base::rbuffer->data();
// Read incoming UDP packets from the socket and feed them to quiche, until there are no more packets to read
loop:
peer_addr_len = sizeof(peer_addr);
(void) U_SYSCALL(memset, "%p,%u,%u", &peer_addr, 0, U_SIZE_SOCKADDR);
iBytesRead = U_SYSCALL(recvfrom, "%d,%p,%u,%u,%p,%p", UServer_Base::fds[0], ptr, UServer_Base::rbuffer_size, (bwait_for_data ? 0 : MSG_DONTWAIT),
(struct sockaddr*)&peer_addr, &peer_addr_len);
if (iBytesRead <= 0)
{
if (errno == EAGAIN)
{
U_DEBUG("quiche: recvfrom would block")
U_INTERNAL_ASSERT_EQUALS(bwait_for_data, false)
if (lconn) // reported no read packets, we will then proceed with the send loop
{
uint8_t out[65536];
ssize_t written, sent;
uint32_t start = 0, remain = sizeof(out);
while (true)
{
written = U_SYSCALL(quiche_conn_send, "%p,%p,%u", lconn, &out[start], remain);
if (written == QUICHE_ERR_DONE)
{
U_DEBUG("quiche: done writing")
break;
}
if (written < 0)
{
U_DEBUG("UQuic::handlerRead(): failed to create packet: %d", written)
break;
}
start += written;
remain -= written;
U_INTERNAL_ASSERT_MINOR(start, sizeof(out))
U_DEBUG("quiche: sent %u bytes", written)
}
sent = U_SYSCALL(sendto, "%d,%p,%u,%u,%p,%d", UServer_Base::fds[0], out, start, 0, (struct sockaddr*)&USocket::peer_addr, USocket::peer_addr_len);
if (sent != start)
{
U_DEBUG("UQuic::handlerRead(): failed to send")
U_RETURN(false);
}
if (U_SYSCALL(quiche_conn_is_closed, "%p", lconn))
{
quiche_stats stats;
U_SYSCALL_VOID(quiche_conn_stats, "%p,%p", lconn, &stats);
U_DEBUG("quiche: connection closed, recv=%u sent=%u lost=%u rtt=%u cwnd=%u", stats.recv, stats.sent, stats.lost, stats.rtt, stats.cwnd)
U_SYSCALL_VOID(quiche_conn_free, "%p", lconn);
U_RETURN(false);
}
}
bwait_for_data = true;
goto loop;
}
U_WARNING("recvfrom on fd %d got %d%R", UServer_Base::fds[0], iBytesRead, 0); // NB: the last argument (0) is necessary...
if (errno == EINTR) UInterrupt::checkForEventSignalPending();
U_RETURN(false);
}
U_INTERNAL_DUMP("peer_addr_len = %u BytesRead(%u) = %#.*S", peer_addr_len, iBytesRead, iBytesRead, ptr)
U_INTERNAL_ASSERT_MAJOR(peer_addr_len, 0)
UServer_Base::rbuffer->size_adjust_force(iBytesRead);
if (memcmp(&peer_addr, &USocket::peer_addr, peer_addr_len) != 0)
{
// TODO
U_WARNING("recvfrom() different address");
/* Lookup a connection based on the packet's connection ID. If there is no connection matching, create a new one
if (lookup())
{
}
*/
}
if (lconn || parseHeader()) U_RETURN(true);
U_RETURN(false);
}
bool UQuic::handlerNewConnection()
{
U_TRACE_NO_PARAM(0, "UQuic::handlerNewConnection()")
U_INTERNAL_ASSERT_POINTER(peers)
U_INTERNAL_ASSERT(UServer_Base::budp)
const char* ptr;
ssize_t written, sent;
const char* pkt = "vneg";
uint8_t out[U_MAX_DATAGRAM_SIZE];
conn = U_NULLPTR;
loop:
if (pkt_type != Initial)
{
U_DEBUG("UQuic::handlerNewConnection(): packet is NOT initial: %u", pkt_type)
U_RETURN(false);
}
// Client Initial packets must be at least 1200 bytes
if (UServer_Base::rbuffer->size() < QUICHE_MIN_CLIENT_INITIAL_LEN)
{
U_DEBUG("UQuic::handlerNewConnection(): quic initial packet is too short: %u", UServer_Base::rbuffer->size())
U_RETURN(false);
}
// Returns true if the given protocol version is supported
if (U_SYSCALL(quiche_version_is_supported, "%u", pkt_version) == false)
{
U_DEBUG("quiche: version negotiation")
// Writes a version negotiation packet
written = U_SYSCALL(quiche_negotiate_version, "%p,%u,%p,%u,%p,%u", scid, scid_len, conn_id, conn_id_len, out, sizeof(out));
pkt: if (written < 0)
{
U_DEBUG("UQuic::handlerNewConnection(): failed to create %S packet: %d", pkt, written)
U_RETURN(false);
}
sent = U_SYSCALL(sendto, "%u,%p,%u,%u,%p,%d", UServer_Base::fds[0], out, written, 0, (struct sockaddr*)&USocket::peer_addr, USocket::peer_addr_len);
if (sent == written)
{
U_DEBUG("quiche: sent %u bytes", sent)
}
else
{
U_DEBUG("UQuic::handlerNewConnection(): failed to send")
U_RETURN(false);
}
if (handlerRead()) goto loop;
U_RETURN(false);
}
if (token_len == 0)
{
// Generate a stateless retry token. The token includes the static string "quiche" followed
// by the IP address of the client and by the original destination connection ID generated by the client
U_DEBUG("quiche: stateless retry")
U_INTERNAL_DUMP("USocket::peer_addr_len = %u", USocket::peer_addr_len)
U_INTERNAL_ASSERT_MAJOR(conn_id_len, 0)
U_INTERNAL_ASSERT_MAJOR(USocket::peer_addr_len, 0)
// 6 -> U_CONSTANT_SIZE("quiche")
U_MEMCPY(token, "quiche", 6);
U_MEMCPY(token + 6, &USocket::peer_addr, USocket::peer_addr_len);
U_MEMCPY(token + 6 + USocket::peer_addr_len, conn_id, conn_id_len);
token_len = 6 + USocket::peer_addr_len + conn_id_len;
U_INTERNAL_DUMP("scid(%u) = %.*S conn_id(%u) = %.*S token(%u) = %.*S pkt_version = %p",
scid_len, scid_len, scid, conn_id_len, conn_id_len, conn_id, token_len, token_len, token, pkt_version)
// Writes a retry packet
# ifdef LIBQUICHE_AT_LEAST_0_5
written = U_SYSCALL(quiche_retry, "%p,%u,%p,%u,%p,%u,%p,%u,%u,%p,%u", scid, scid_len, conn_id, conn_id_len, conn_id, conn_id_len, token, token_len, pkt_version, out, sizeof(out));
# else
written = U_SYSCALL(quiche_retry, "%p,%u,%p,%u,%p,%u,%p,%u, %p,%u", scid, scid_len, conn_id, conn_id_len, conn_id, conn_id_len, token, token_len, out, sizeof(out));
# endif
pkt = "retry";
goto pkt;
}
// Validates a stateless retry token. This checks that the ticket includes the `"quiche"` static string, and that the client IP address matches the address stored in the ticket
if (token_len < 6 ||
memcmp(token, U_CONSTANT_TO_PARAM("quiche")))
{
U_DEBUG("UQuic::handlerNewConnection(): invalid address validation token")
U_RETURN(false);
}
token_len -= 6;
ptr = (const char*)&token[0] + 6;
if (token_len < USocket::peer_addr_len ||
memcmp(ptr, &USocket::peer_addr, USocket::peer_addr_len))
{
U_DEBUG("UQuic::handlerNewConnection(): invalid address validation token")
U_RETURN(false);
}
ptr += USocket::peer_addr_len;
token_len -= USocket::peer_addr_len;
if (conn_id_len != token_len) // The token was not valid, meaning the retry failed, so drop the packet
{
U_DEBUG("UQuic::handlerNewConnection(): invalid address validation token")
U_RETURN(false);
}
// Reuse the source connection ID we sent in the Retry packet, instead of changing it again. Creates a new server-side connection
conn = (quiche_conn*) U_SYSCALL(quiche_accept, "%p,%u,%p,%u,%p", conn_id, conn_id_len, (const uint8_t*)ptr, token_len, qconfig);
if (conn == U_NULLPTR)
{
U_DEBUG("UQuic::handlerNewConnection(): failed to create connection")
U_RETURN(false);
}
U_DEBUG("quiche: new connection")
while (processesPackets(conn))
{
if (U_SYSCALL(quiche_conn_is_established, "%p", conn))
{
U_DEBUG("UQuic::handlerNewConnection(): connection handshake is complete")
U_RETURN(true);
}
if (handlerRead(conn) == false) U_RETURN(false);
}
U_RETURN(false);
}

View File

@ -1 +1 @@
0A20
0A2E

View File

@ -7,8 +7,8 @@ Debian 8.11 was released Saturday, 23rd June 2018.
Debian 9.13, or stretch. Access this release through dists/oldstable
Debian 9.13 was released Saturday, 18th July 2020.
Debian 10.4, or buster. Access this release through dists/stable
Debian 10.4 was released Saturday, 9th May 2020.
Debian 10.5, or buster. Access this release through dists/stable
Debian 10.5 was released Saturday, 1st August 2020.
Testing, or bullseye. Access this release through dists/testing. The
current tested development snapshot is named bullseye. Packages which