mirror of
https://github.com/stefanocasazza/ULib.git
synced 2025-09-28 19:05:55 +08:00
sync
This commit is contained in:
parent
02c70bcd83
commit
8af911bc81
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
151
include/ulib/utility/uquic.h
Normal file
151
include/ulib/utility/uquic.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
463
src/ulib/utility/uquic.cpp
Normal 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);
|
||||
}
|
|
@ -1 +1 @@
|
|||
0A20
|
||||
0A2E
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user