mirror of
https://github.com/stefanocasazza/ULib.git
synced 2025-10-05 19:18:01 +08:00
add mimalloc
This commit is contained in:
parent
35fa262ab4
commit
6eaac44aa2
82
configure
vendored
82
configure
vendored
|
@ -1093,6 +1093,7 @@ enable_zip
|
|||
with_libzopfli
|
||||
with_libbrotli
|
||||
with_libquiche
|
||||
with_libmimalloc
|
||||
with_magic
|
||||
enable_ssl_staticlib_deps
|
||||
with_ssl
|
||||
|
@ -1863,6 +1864,7 @@ Optional Packages:
|
|||
--with-libzopfli use system zopfli library - [will check /usr /usr/local] [default=use if present]
|
||||
--with-libbrotli use system brotli library - [will check /usr /usr/local] [default=use if present]
|
||||
--with-libquiche use system quiche library - [will check /usr /usr/local] [default=use if present]
|
||||
--with-libmimalloc use system mimalloc library - [will check /usr /usr/local] [default=use if present]
|
||||
--with-magic use system libmagic library - [will check /usr /usr/local] [default=use if present]
|
||||
--with-ssl use system SSL library - [will check /usr /usr/local] [default=use if present]
|
||||
--with-pcre use system PCRE library - [will check /usr /usr/local] [default=use if present]
|
||||
|
@ -26219,6 +26221,7 @@ $as_echo "${T_MD}C++ stuff:${T_ME}" >&6; }
|
|||
ulib_libzopfli_msg="no (--with-libzopfli)"
|
||||
ulib_libbrotli_msg="no (--with-libbrotli)"
|
||||
ulib_libquiche_msg="no (--with-libquiche)"
|
||||
ulib_mimalloc_msg="no (--with-libmimalloc)"
|
||||
ulib_libtdb_msg="no (--with-libtdb)"
|
||||
ulib_curl_msg="no (--with-curl)"
|
||||
ulib_expat_msg="no (--with-expat)"
|
||||
|
@ -27446,6 +27449,7 @@ libz_version="unknow"
|
|||
libzopfli_version="unknown"
|
||||
libbrotli_version="unknown"
|
||||
libquiche_version="unknown"
|
||||
mimalloc_version="unknown"
|
||||
libtdb_version="unknown"
|
||||
pcre_version="unknown"
|
||||
ldap_version="unknown"
|
||||
|
@ -27748,6 +27752,73 @@ $as_echo "no" >&6; }
|
|||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if mimalloc library is wanted" >&5
|
||||
$as_echo_n "checking if mimalloc library is wanted... " >&6; }
|
||||
wanted=1;
|
||||
if test -z "$with_libmimalloc" ; then
|
||||
wanted=0;
|
||||
if test -n "$CROSS_ENVIRONMENT" -o "$USP_FLAGS" = "-DAS_cpoll_cppsp_DO" -o "$enable_shared" = "no"; then
|
||||
with_libmimalloc="no";
|
||||
else
|
||||
with_libmimalloc="${CROSS_ENVIRONMENT}/usr";
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check whether --with-libmimalloc was given.
|
||||
if test "${with_libmimalloc+set}" = set; then :
|
||||
withval=$with_libmimalloc;
|
||||
if test "$withval" = "no"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
for dir in $withval ${CROSS_ENVIRONMENT}/ ${CROSS_ENVIRONMENT}/usr ${CROSS_ENVIRONMENT}/usr/local; do
|
||||
libmimallocdir="$dir"
|
||||
if test -f "$dir/include/mimalloc.h"; then
|
||||
found_libmimalloc="yes";
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libmimalloc != x_yes; then
|
||||
msg="Cannot find libmimalloc library";
|
||||
if test $wanted = 1; then
|
||||
as_fn_error $? "$msg" "$LINENO" 5
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $msg" >&5
|
||||
$as_echo "$msg" >&6; }
|
||||
fi
|
||||
else
|
||||
echo "${T_MD}libmimalloc found in $libmimallocdir${T_ME}"
|
||||
USE_LIBMIMALLOC=yes
|
||||
|
||||
$as_echo "#define USE_LIBMIMALLOC 1" >>confdefs.h
|
||||
|
||||
|
||||
if test -z "$CROSS_ENVIRONMENT" -a x_$PKG_CONFIG != x_no; then
|
||||
libmimalloc_version=$(pkg-config --modversion mimalloc 2>/dev/null)
|
||||
fi
|
||||
if test -z "${libmimalloc}"; then
|
||||
libmimalloc_version=$(ls $libmimallocdir/lib*/libmimalloc.so.*.* 2>/dev/null | head -n 1 | awk -F'.so.' '{n=2; print $n}' 2>/dev/null)
|
||||
fi
|
||||
if test -z "${libmimalloc_version}"; then
|
||||
libmimalloc_version="unknown"
|
||||
fi
|
||||
ULIB_LIBS="$ULIB_LIBS -lmimalloc";
|
||||
if test $libmimallocdir != "${CROSS_ENVIRONMENT}/" -a $libmimallocdir != "${CROSS_ENVIRONMENT}/usr" -a $libmimallocdir != "${CROSS_ENVIRONMENT}/usr/local"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$libmimallocdir/include"
|
||||
LDFLAGS="$LDFLAGS -L$libmimallocdir/lib -Wl,-R$libmimallocdir/lib";
|
||||
PRG_LDFLAGS="$PRG_LDFLAGS -L$libmimallocdir/lib";
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if MAGIC library is wanted" >&5
|
||||
$as_echo_n "checking if MAGIC library is wanted... " >&6; }
|
||||
wanted=1;
|
||||
|
@ -29288,6 +29359,10 @@ if test "$USE_LIBQUICHE" = "yes"; then
|
|||
ulib_libquiche_msg="yes ( $libquiche_version )"
|
||||
fi
|
||||
|
||||
if test "$USE_LIBMIMALLOC" = "yes"; then
|
||||
ulib_mimalloc_msg="yes ( $libmimalloc_version )"
|
||||
fi
|
||||
|
||||
if test "$USE_LIBTDB" = "yes"; then
|
||||
ulib_libtdb_msg="yes ( $libtdb_version )"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tdb_traverse_read in -ltdb" >&5
|
||||
|
@ -30885,6 +30960,11 @@ cat >>confdefs.h <<_ACEOF
|
|||
_ACEOF
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define _LIBMIMALLOC_VERSION "$libmimalloc_version"
|
||||
_ACEOF
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define _LIBTDB_VERSION "$libtdb_version"
|
||||
_ACEOF
|
||||
|
@ -34294,6 +34374,7 @@ ULIB_SYSCONFDIR="$u_sysconfdir"
|
|||
LIBZOPFLI support: ${ulib_libzopfli_msg}
|
||||
LIBBROTLI support: ${ulib_libbrotli_msg}
|
||||
LIBQUICHE support: ${ulib_libquiche_msg}
|
||||
MIMALLOC support: ${ulib_mimalloc_msg}
|
||||
LIBTDB support: ${ulib_libtdb_msg}
|
||||
PCRE support: ${ulib_pcre_msg}
|
||||
SSL support: ${ulib_ssl_msg}
|
||||
|
@ -34358,6 +34439,7 @@ $as_echo "$as_me: Configured to build src/ulib/lib${ULIB}:
|
|||
LIBZOPFLI support: ${ulib_libzopfli_msg}
|
||||
LIBBROTLI support: ${ulib_libbrotli_msg}
|
||||
LIBQUICHE support: ${ulib_libquiche_msg}
|
||||
MIMALLOC support: ${ulib_mimalloc_msg}
|
||||
LIBTDB support: ${ulib_libtdb_msg}
|
||||
PCRE support: ${ulib_pcre_msg}
|
||||
SSL support: ${ulib_ssl_msg}
|
||||
|
|
|
@ -1309,6 +1309,7 @@ dnl initialize all the info variables to 'no'
|
|||
ulib_libzopfli_msg="no (--with-libzopfli)"
|
||||
ulib_libbrotli_msg="no (--with-libbrotli)"
|
||||
ulib_libquiche_msg="no (--with-libquiche)"
|
||||
ulib_mimalloc_msg="no (--with-libmimalloc)"
|
||||
ulib_libtdb_msg="no (--with-libtdb)"
|
||||
ulib_curl_msg="no (--with-curl)"
|
||||
ulib_expat_msg="no (--with-expat)"
|
||||
|
@ -1447,6 +1448,7 @@ libz_version="unknow"
|
|||
libzopfli_version="unknown"
|
||||
libbrotli_version="unknown"
|
||||
libquiche_version="unknown"
|
||||
mimalloc_version="unknown"
|
||||
libtdb_version="unknown"
|
||||
pcre_version="unknown"
|
||||
ldap_version="unknown"
|
||||
|
@ -1538,6 +1540,10 @@ if test "$USE_LIBQUICHE" = "yes"; then
|
|||
ulib_libquiche_msg="yes ( $libquiche_version )"
|
||||
fi
|
||||
|
||||
if test "$USE_LIBMIMALLOC" = "yes"; then
|
||||
ulib_mimalloc_msg="yes ( $libmimalloc_version )"
|
||||
fi
|
||||
|
||||
if test "$USE_LIBTDB" = "yes"; then
|
||||
ulib_libtdb_msg="yes ( $libtdb_version )"
|
||||
AC_CHECK_LIB(tdb,tdb_traverse_read)
|
||||
|
@ -2034,6 +2040,7 @@ AC_DEFINE_UNQUOTED(_LIBZ_VERSION, "$libz_version", [libz - general purpose c
|
|||
AC_DEFINE_UNQUOTED(_LIBZOPFLI_VERSION, "$libzopfli_version", [libzopfli - google compression library version])
|
||||
AC_DEFINE_UNQUOTED(_LIBBROTLI_VERSION, "$libbrotli_version", [libbrotli - google compression library version])
|
||||
AC_DEFINE_UNQUOTED(_LIBQUICHE_VERSION, "$libquiche_version", [libquiche - library version of implementation of the QUIC transport protocol and HTTP/3])
|
||||
AC_DEFINE_UNQUOTED(_LIBMIMALLOC_VERSION,"$libmimalloc_version",[libmimalloc - library version of implementation of the QUIC transport protocol and HTTP/3])
|
||||
AC_DEFINE_UNQUOTED(_LIBTDB_VERSION, "$libtdb_version", [libtdb - samba Trivial DB library version])
|
||||
AC_DEFINE_UNQUOTED(_LIBSSH_VERSION, "$libssh_version", [libSSH version])
|
||||
AC_DEFINE_UNQUOTED(_SSL_VERSION, "$ssl_version", [SSL version])
|
||||
|
@ -3126,6 +3133,7 @@ AC_MSG_NOTICE([Configured to build src/ulib/lib${ULIB}:
|
|||
LIBZOPFLI support: ${ulib_libzopfli_msg}
|
||||
LIBBROTLI support: ${ulib_libbrotli_msg}
|
||||
LIBQUICHE support: ${ulib_libquiche_msg}
|
||||
MIMALLOC support: ${ulib_mimalloc_msg}
|
||||
LIBTDB support: ${ulib_libtdb_msg}
|
||||
PCRE support: ${ulib_pcre_msg}
|
||||
SSL support: ${ulib_ssl_msg}
|
||||
|
|
|
@ -285,6 +285,17 @@ public:
|
|||
|
||||
void insert(const UString& k, const void* e) { return insert(k.rep, e); }
|
||||
|
||||
void replace(const char* k, uint32_t klen, const void* e)
|
||||
{
|
||||
U_TRACE(0, "UHashMap<void*>::replace(%#.*S,%u,%p)", klen, k, klen, e)
|
||||
|
||||
setKey(k, klen);
|
||||
|
||||
lookup();
|
||||
|
||||
replaceAfterFind(e);
|
||||
}
|
||||
|
||||
void* erase(const char* k, uint32_t klen)
|
||||
{
|
||||
U_TRACE(0, "UHashMap<void*>::erase(%#.*S,%u)", klen, k, klen)
|
||||
|
@ -987,6 +998,17 @@ public:
|
|||
|
||||
void insert(const UString& k, const T* e) { return insert(k.rep, e); }
|
||||
|
||||
void replace(const char* k, uint32_t klen, const T* e)
|
||||
{
|
||||
U_TRACE(0, "UHashMap<T*>::replace(%#.*S,%u,%p)", klen, k, klen, e)
|
||||
|
||||
setKey(k, klen);
|
||||
|
||||
lookup();
|
||||
|
||||
replaceAfterFind(e);
|
||||
}
|
||||
|
||||
// find a elem in the array with key
|
||||
|
||||
T* at(const UString& k) { return (T*) UHashMap<void*>::at(k.rep); }
|
||||
|
|
|
@ -88,6 +88,7 @@ public:
|
|||
|
||||
// method VIRTUAL to define
|
||||
|
||||
virtual int handlerConnect() { return U_NOTIFIER_DELETE; }
|
||||
virtual int handlerRead() { return U_NOTIFIER_DELETE; }
|
||||
virtual int handlerWrite() { return U_NOTIFIER_DELETE; }
|
||||
virtual int handlerTimeout() { return U_NOTIFIER_DELETE; }
|
||||
|
|
|
@ -747,6 +747,9 @@
|
|||
/* Define if enable libmagic support */
|
||||
#undef USE_LIBMAGIC
|
||||
|
||||
/* Define if enable libmimalloc support */
|
||||
#undef USE_LIBMIMALLOC
|
||||
|
||||
/* Define if enable libpcre support */
|
||||
#undef USE_LIBPCRE
|
||||
|
||||
|
@ -1010,6 +1013,10 @@
|
|||
/* libevent - event notification library version */
|
||||
#undef _LIBEVENT_VERSION
|
||||
|
||||
/* libmimalloc - library version of implementation of the QUIC transport
|
||||
protocol and HTTP/3 */
|
||||
#undef _LIBMIMALLOC_VERSION
|
||||
|
||||
/* libquiche - library version of implementation of the QUIC transport
|
||||
protocol and HTTP/3 */
|
||||
#undef _LIBQUICHE_VERSION
|
||||
|
|
|
@ -16,6 +16,12 @@
|
|||
|
||||
#include <ulib/internal/common.h>
|
||||
|
||||
#ifdef USE_LIBMIMALLOC
|
||||
# include <mimalloc.h> // mimalloc-new-delete.h
|
||||
# define malloc(x) mi_malloc(x)
|
||||
# define free(x) mi_free(x)
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
// U_STACK_TYPE_[0-9] 'type' stack for which the request is serviced with preallocation
|
||||
|
||||
|
@ -524,7 +530,7 @@ public:
|
|||
|
||||
#endif
|
||||
|
||||
static void* malloc(uint32_t num, uint32_t type_size = sizeof(char), bool bzero = false);
|
||||
static void* u_malloc(uint32_t num, uint32_t type_size = sizeof(char), bool bzero = false);
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char* obj_class;
|
||||
|
@ -602,7 +608,7 @@ template <class T> bool u_check_memory_vector(T* _vec, uint32_t n)
|
|||
|
||||
# define U_MEMORY_ALLOCATOR \
|
||||
void* operator new( size_t sz) { U_INTERNAL_ASSERT(sz <= U_MAX_SIZE_PREALLOCATE); return UMemoryPool::pop(U_SIZE_TO_STACK_INDEX(sz)); } \
|
||||
void* operator new[](size_t sz) { return UMemoryPool::malloc(sz); }
|
||||
void* operator new[](size_t sz) { return UMemoryPool::u_malloc(sz); }
|
||||
# define U_MEMORY_DEALLOCATOR \
|
||||
void operator delete( void* _ptr, size_t sz) { U_INTERNAL_ASSERT(sz <= U_MAX_SIZE_PREALLOCATE); UMemoryPool::push( _ptr, U_SIZE_TO_STACK_INDEX(sz)); } \
|
||||
void operator delete[](void* _ptr, size_t sz) { UMemoryPool::_free(_ptr, sz); }
|
||||
|
|
|
@ -865,7 +865,7 @@ protected:
|
|||
|
||||
bool processRequest(char recvtype);
|
||||
|
||||
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__)
|
||||
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) && GCC_VERSION_NUM < 100100
|
||||
bool sendRequest(UStringType&& pipeline)
|
||||
#else
|
||||
bool sendRequest(const UString& pipeline)
|
||||
|
@ -1037,7 +1037,7 @@ private:
|
|||
|
||||
// by Victor Stewart
|
||||
|
||||
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__)
|
||||
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) && GCC_VERSION_NUM < 100100
|
||||
|
||||
class UCompileTimeRESPEncoder : public UCompileTimeStringFormatter {
|
||||
private:
|
||||
|
|
|
@ -674,6 +674,12 @@ public:
|
|||
|
||||
virtual bool connectServer(const UString& server, unsigned int iServPort, int timeoutMS = 0);
|
||||
|
||||
#ifdef HAVE_EPOLL_WAIT
|
||||
// this method initiates an asynchronous connection that you must later wait on with UNotifier::waitOnAsynchronousConnects
|
||||
virtual bool beginAsynchronousConnect(const UString& server, unsigned int iServPort);
|
||||
virtual bool finishAsynchronousConnect();
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This method is called to receive a block of data on the connected socket.
|
||||
* The parameters signify the payload receiving buffer and its size.
|
||||
|
|
|
@ -186,6 +186,11 @@ public:
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EPOLL_WAIT
|
||||
// this timeout does not include time spent in event handlers, only time waiting on epoll
|
||||
static bool waitOnAsynchronousBatch(const UVector<UEventFd *>& waiting, int op, int timeoutMS = -1);
|
||||
#endif
|
||||
|
||||
// READ - WRITE
|
||||
|
||||
// param timeoutMS specified the timeout value, in milliseconds.
|
||||
|
|
|
@ -3172,6 +3172,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
# if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) && GCC_VERSION_NUM < 100100
|
||||
template<typename T>
|
||||
concept bool UCompileTimeStringType = requires(T string) {
|
||||
is_ctv_v<T>;
|
||||
|
@ -3188,7 +3189,7 @@ inline bool operator==(const UCompileTimeStringType& lhs, const UString& rhs){ r
|
|||
|
||||
inline bool operator!=(const UString& lhs, const UCompileTimeStringType& rhs){ return !lhs.equal(rhs.string); }
|
||||
inline bool operator!=(const UCompileTimeStringType& lhs, const UString& rhs){ return !rhs.equal(lhs.string); }
|
||||
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -49,14 +49,18 @@ public:
|
|||
Short = 0x006
|
||||
};
|
||||
|
||||
typedef struct conn_io {
|
||||
quiche_conn* conn;
|
||||
quiche_h3_conn* http3;
|
||||
} conn_io;
|
||||
|
||||
static bool handlerRead();
|
||||
static bool handlerAccept();
|
||||
static int loadConfigParam();
|
||||
|
||||
protected:
|
||||
static quiche_conn* conn;
|
||||
static conn_io conn;
|
||||
static size_t conn_id_len;
|
||||
static quiche_h3_conn* http3;
|
||||
static quiche_config* qconfig;
|
||||
static quiche_h3_config* http3_config;
|
||||
static struct sockaddr_storage peer_addr;
|
||||
|
|
|
@ -214,6 +214,59 @@ AC_DEFUN([AC_CHECK_PACKAGE],[
|
|||
fi
|
||||
], [AC_MSG_RESULT(no)])
|
||||
|
||||
AC_MSG_CHECKING(if mimalloc library is wanted)
|
||||
wanted=1;
|
||||
if test -z "$with_libmimalloc" ; then
|
||||
wanted=0;
|
||||
if test -n "$CROSS_ENVIRONMENT" -o "$USP_FLAGS" = "-DAS_cpoll_cppsp_DO" -o "$enable_shared" = "no"; then
|
||||
with_libmimalloc="no";
|
||||
else
|
||||
with_libmimalloc="${CROSS_ENVIRONMENT}/usr";
|
||||
fi
|
||||
fi
|
||||
AC_ARG_WITH(libmimalloc, [ --with-libmimalloc use system mimalloc library - [[will check /usr /usr/local]] [[default=use if present]]], [
|
||||
if test "$withval" = "no"; then
|
||||
AC_MSG_RESULT(no)
|
||||
else
|
||||
AC_MSG_RESULT(yes)
|
||||
for dir in $withval ${CROSS_ENVIRONMENT}/ ${CROSS_ENVIRONMENT}/usr ${CROSS_ENVIRONMENT}/usr/local; do
|
||||
libmimallocdir="$dir"
|
||||
if test -f "$dir/include/mimalloc.h"; then
|
||||
found_libmimalloc="yes";
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libmimalloc != x_yes; then
|
||||
msg="Cannot find libmimalloc library";
|
||||
if test $wanted = 1; then
|
||||
AC_MSG_ERROR($msg)
|
||||
else
|
||||
AC_MSG_RESULT($msg)
|
||||
fi
|
||||
else
|
||||
echo "${T_MD}libmimalloc found in $libmimallocdir${T_ME}"
|
||||
USE_LIBMIMALLOC=yes
|
||||
AC_DEFINE(USE_LIBMIMALLOC, 1, [Define if enable libmimalloc support])
|
||||
|
||||
if test -z "$CROSS_ENVIRONMENT" -a x_$PKG_CONFIG != x_no; then
|
||||
libmimalloc_version=$(pkg-config --modversion mimalloc 2>/dev/null)
|
||||
fi
|
||||
if test -z "${libmimalloc}"; then
|
||||
libmimalloc_version=$(ls $libmimallocdir/lib*/libmimalloc.so.*.* 2>/dev/null | head -n 1 | awk -F'.so.' '{n=2; print $n}' 2>/dev/null)
|
||||
fi
|
||||
if test -z "${libmimalloc_version}"; then
|
||||
libmimalloc_version="unknown"
|
||||
fi
|
||||
ULIB_LIBS="$ULIB_LIBS -lmimalloc";
|
||||
if test $libmimallocdir != "${CROSS_ENVIRONMENT}/" -a $libmimallocdir != "${CROSS_ENVIRONMENT}/usr" -a $libmimallocdir != "${CROSS_ENVIRONMENT}/usr/local"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$libmimallocdir/include"
|
||||
LDFLAGS="$LDFLAGS -L$libmimallocdir/lib -Wl,-R$libmimallocdir/lib";
|
||||
PRG_LDFLAGS="$PRG_LDFLAGS -L$libmimallocdir/lib";
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
], [AC_MSG_RESULT(no)])
|
||||
|
||||
AC_MSG_CHECKING(if MAGIC library is wanted)
|
||||
wanted=1;
|
||||
if test -z "$with_magic" ; then
|
||||
|
|
|
@ -111,7 +111,7 @@ bool UCache::open(const UString& path, const UString& dir, const UString* enviro
|
|||
|
||||
if (( _x.size() == 0 ||
|
||||
(_x.fstat(), _x.st_mtime < _y.st_mtime)) &&
|
||||
(UDirWalk::setFollowLinks(true), n = dirwalk.walk(vec1)))
|
||||
(UDirWalk::setFollowLinks(true), (n = dirwalk.walk(vec1))))
|
||||
{
|
||||
exist = false;
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ void UCommand::setCommand()
|
|||
|
||||
uint32_t n = 1+ncmd+1;
|
||||
|
||||
argv_exec = (char**) UMemoryPool::malloc(n + U_ADD_ARGS, sizeof(char*)); // U_ADD_ARGS => space for addArgument()...
|
||||
argv_exec = (char**) UMemoryPool::u_malloc(n + U_ADD_ARGS, sizeof(char*)); // U_ADD_ARGS => space for addArgument()...
|
||||
|
||||
U_MEMCPY(argv_exec, argv, n * sizeof(char*)); // NB: copy also null terminator...
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ uint32_t UCommand::setEnvironment(const UString& env, char**& _envp)
|
|||
|
||||
uint32_t n = _nenv + 1; // NB: consider also null terminator...
|
||||
|
||||
_envp = (char**) UMemoryPool::malloc(n, sizeof(char*)); // NB: consider also null terminator...
|
||||
_envp = (char**) UMemoryPool::u_malloc(n, sizeof(char*)); // NB: consider also null terminator...
|
||||
|
||||
U_MEMCPY(_envp, argp, n * sizeof(char*)); // NB: copy also null terminator...
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ void UHashMap<void*>::_allocate(uint32_t n)
|
|||
|
||||
U_INTERNAL_ASSERT_EQUALS(n & (n-1), 0)
|
||||
|
||||
info = (uint8_t*) U_SYSCALL(malloc, "%u", n*(1+UHashMapNode::size())); // UMemoryPool::malloc(n, 1+UHashMapNode::size(), false);
|
||||
info = (uint8_t*) U_SYSCALL(malloc, "%u", n*(1+UHashMapNode::size())); // UMemoryPool::u_malloc(n, 1+UHashMapNode::size(), false);
|
||||
table = (char*) (info + n);
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER_MSG(info, "cannot allocate memory, exiting...")
|
||||
|
|
|
@ -301,7 +301,7 @@ uint32_t UCDB::makeFinish(bool _reset)
|
|||
uint32_t index;
|
||||
};
|
||||
|
||||
cdb_tmp* tmp = (cdb_tmp*) UMemoryPool::malloc(nrecord, sizeof(cdb_tmp));
|
||||
cdb_tmp* tmp = (cdb_tmp*) UMemoryPool::u_malloc(nrecord, sizeof(cdb_tmp));
|
||||
cdb_tmp* ptmp = tmp;
|
||||
|
||||
cdb_hash_table_slot* pslot;
|
||||
|
|
|
@ -1843,7 +1843,7 @@ URDBObjectHandler<UDataStorage*>::URDBObjectHandler(const UString& pathdb, int _
|
|||
{
|
||||
uint32_t sz = pDataStorage->size();
|
||||
|
||||
if (sz) pDataStorage->recdata = (char*) UMemoryPool::malloc(sz);
|
||||
if (sz) pDataStorage->recdata = (char*) UMemoryPool::u_malloc(sz);
|
||||
|
||||
U_INTERNAL_DUMP("pDataStorage->recdata(%u) = %p", sz, pDataStorage->recdata)
|
||||
}
|
||||
|
|
|
@ -451,9 +451,9 @@ bool UMemoryPool::check(void* ptr)
|
|||
# endif
|
||||
#endif
|
||||
|
||||
void* UMemoryPool::malloc(uint32_t num, uint32_t type_size, bool bzero)
|
||||
void* UMemoryPool::u_malloc(uint32_t num, uint32_t type_size, bool bzero)
|
||||
{
|
||||
U_TRACE(0, "UMemoryPool::malloc(%u,%u,%b)", num, type_size, bzero)
|
||||
U_TRACE(0, "UMemoryPool::u_malloc(%u,%u,%b)", num, type_size, bzero)
|
||||
|
||||
U_INTERNAL_ASSERT_MAJOR(num, 0)
|
||||
U_INTERNAL_ASSERT_MAJOR(type_size, 0)
|
||||
|
|
|
@ -28,8 +28,8 @@ ULDAPEntry::ULDAPEntry(int num_names, const char** names, int num_entry)
|
|||
n_entry = num_entry;
|
||||
attr_name = names;
|
||||
|
||||
dn = (char**) UMemoryPool::malloc(num_entry, sizeof(char*), true);
|
||||
attr_val = (UString**) UMemoryPool::malloc(num_entry * num_names, sizeof(UString*), true);
|
||||
dn = (char**) UMemoryPool::u_malloc(num_entry, sizeof(char*), true);
|
||||
attr_val = (UString**) UMemoryPool::u_malloc(num_entry * num_names, sizeof(UString*), true);
|
||||
}
|
||||
|
||||
ULDAPEntry::~ULDAPEntry()
|
||||
|
|
|
@ -352,7 +352,7 @@ bool UREDISClient_Base::deleteKeys(const char* pattern, uint32_t len) // Delete
|
|||
|
||||
// by Victor Stewart
|
||||
|
||||
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__)
|
||||
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) && GCC_VERSION_NUM < 100100
|
||||
|
||||
int UREDISClusterMaster::handlerRead()
|
||||
{
|
||||
|
|
|
@ -87,8 +87,8 @@ UIptAccount::UIptAccount(bool bSocketIsIPv6) : USocket(bSocketIsIPv6)
|
|||
|
||||
// 4096 bytes default buffer should save us from reallocations as it fits 200 concurrent active clients
|
||||
|
||||
data = UMemoryPool::malloc(IPT_ACCOUNT_MIN_BUFSIZE);
|
||||
data_size = IPT_ACCOUNT_MIN_BUFSIZE;
|
||||
data = UMemoryPool::u_malloc(IPT_ACCOUNT_MIN_BUFSIZE);
|
||||
data_size = IPT_ACCOUNT_MIN_BUFSIZE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,7 @@ bool UIptAccount::readEntries(const char* table, bool bflush)
|
|||
|
||||
UMemoryPool::_free(data, data_size);
|
||||
|
||||
data = UMemoryPool::malloc(new_size);
|
||||
data = UMemoryPool::u_malloc(new_size);
|
||||
|
||||
data_size = new_size;
|
||||
}
|
||||
|
|
|
@ -2175,7 +2175,7 @@ int UNoCatPlugIn::handlerInit()
|
|||
U_INTERNAL_ASSERT_EQUALS(UPing::addrmask, U_NULLPTR)
|
||||
|
||||
// UPing::addrmask = (fd_set*) UServer_Base::getOffsetToDataShare(sizeof(fd_set) + sizeof(uint32_t));
|
||||
UPing::addrmask = (fd_set*) UMemoryPool::malloc(1, sizeof(fd_set) + sizeof(uint32_t));
|
||||
UPing::addrmask = (fd_set*) UMemoryPool::u_malloc(1, sizeof(fd_set) + sizeof(uint32_t));
|
||||
|
||||
// crypto cmd
|
||||
|
||||
|
@ -2280,8 +2280,8 @@ int UNoCatPlugIn::handlerFork()
|
|||
|
||||
U_INTERNAL_DUMP("num_radio = %u", num_radio)
|
||||
|
||||
// sockp = (UPing**) UMemoryPool::malloc(num_radio, sizeof(UPing*));
|
||||
vaddr = (UVector<UIPAddress*>**) UMemoryPool::malloc(num_radio, sizeof(UVector<UIPAddress*>*));
|
||||
// sockp = (UPing**) UMemoryPool::u_malloc(num_radio, sizeof(UPing*));
|
||||
vaddr = (UVector<UIPAddress*>**) UMemoryPool::u_malloc(num_radio, sizeof(UVector<UIPAddress*>*));
|
||||
|
||||
// UPing::addrmask = (fd_set*) UServer_Base::getPointerToDataShare(UPing::addrmask);
|
||||
|
||||
|
|
|
@ -1173,6 +1173,66 @@ ok: setLocal();
|
|||
U_RETURN(false);
|
||||
}
|
||||
|
||||
#ifdef HAVE_EPOLL_WAIT
|
||||
bool USocket::beginAsynchronousConnect(const UString& server, unsigned int iServPort)
|
||||
{
|
||||
U_TRACE(1, "USocket::beginAsynchronousConnect(%V,%u)", server.rep, iServPort)
|
||||
|
||||
U_CHECK_MEMORY
|
||||
|
||||
U_INTERNAL_ASSERT(server.isNullTerminated())
|
||||
|
||||
if (isOpen() == false) _socket();
|
||||
|
||||
if (cRemoteAddress.setHostName(server, U_socket_IPv6(this)))
|
||||
{
|
||||
setNonBlocking(); // we assume all sockets are blocking, so we will set nonBlocking for connect then unset back to blocking
|
||||
|
||||
SocketAddress cServer(iRemotePort = iServPort, cRemoteAddress);
|
||||
|
||||
/*
|
||||
Yes, a non-blocking connect() can return 0 (which means success), although this is not likely to happen with TCP. "Immediately" means that the kernel does not have to wait to determine the status. Situations where you could see this include
|
||||
|
||||
1) UDP sockets, where connect() is basically advisory, allowing send() to be used later, rather than sendto().
|
||||
|
||||
2) Streaming UNIX domain sockets, where the peer is in the same kernel and thus could be scrutinized immediately.
|
||||
|
||||
3) A TCP connection to 127.0.0.1 (localhost).
|
||||
*/
|
||||
|
||||
int result = U_FF_SYSCALL(connect, "%d,%p,%d", getFd(), (sockaddr*)cServer, cServer.sizeOf());
|
||||
|
||||
if ( (result == -1 && errno == EINPROGRESS) || (result == 0 && finishAsynchronousConnect()) ) U_RETURN(true);
|
||||
|
||||
_close_socket();
|
||||
}
|
||||
|
||||
U_RETURN(false);
|
||||
}
|
||||
|
||||
bool USocket::finishAsynchronousConnect()
|
||||
{
|
||||
U_TRACE_NO_PARAM(0, "USocket::finishAsynchronousConnect()")
|
||||
|
||||
setBlocking();
|
||||
|
||||
uint32_t error = U_NOT_FOUND, tmp = sizeof(uint32_t);
|
||||
|
||||
(void) getSockOpt(SOL_SOCKET, SO_ERROR, (void*)&error, tmp);
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
iState = CONNECT;
|
||||
|
||||
U_RETURN(true);
|
||||
}
|
||||
|
||||
iState = -(errno = error);
|
||||
|
||||
U_RETURN(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
int USocket::send(const char* pData, uint32_t iDataLen)
|
||||
{
|
||||
U_TRACE(1, "USocket::send(%p,%u)", pData, iDataLen)
|
||||
|
|
|
@ -279,8 +279,8 @@ next:
|
|||
U_INTERNAL_ASSERT_EQUALS(kqevents, 0)
|
||||
U_INTERNAL_ASSERT_EQUALS(kqrevents, 0)
|
||||
|
||||
kqevents = (struct kevent*) UMemoryPool::malloc(max_connection, sizeof(struct kevent), true);
|
||||
kqrevents = (struct kevent*) UMemoryPool::malloc(max_connection, sizeof(struct kevent), true);
|
||||
kqevents = (struct kevent*) UMemoryPool::u_malloc(max_connection, sizeof(struct kevent), true);
|
||||
kqrevents = (struct kevent*) UMemoryPool::u_malloc(max_connection, sizeof(struct kevent), true);
|
||||
|
||||
// Check for Mac OS X kqueue bug. If kqueue works, then kevent will succeed, and it will stick an error in events[0].
|
||||
// If kqueue is broken, then kevent will fail (This detects an old bug in Mac OS X 10.4, fixed in 10.5)
|
||||
|
@ -303,7 +303,7 @@ next:
|
|||
U_INTERNAL_ASSERT_EQUALS(events, U_NULLPTR)
|
||||
|
||||
events =
|
||||
pevents = (struct epoll_event*) UMemoryPool::malloc(max_connection+1, sizeof(struct epoll_event), true);
|
||||
pevents = (struct epoll_event*) UMemoryPool::u_malloc(max_connection+1, sizeof(struct epoll_event), true);
|
||||
|
||||
# ifdef HAVE_EPOLL_CTL_BATCH
|
||||
for (int i = 0; i < U_EPOLL_CTL_CMD_SIZE; ++i)
|
||||
|
@ -1362,6 +1362,79 @@ int UNotifier::waitForRead(int fd, int timeoutMS)
|
|||
U_RETURN(ret);
|
||||
}
|
||||
|
||||
#ifdef HAVE_EPOLL_WAIT
|
||||
bool UNotifier::waitOnAsynchronousBatch(const UVector<UEventFd*>& waiting, int op, int timeoutMS)
|
||||
{
|
||||
U_TRACE_NO_PARAM(0, "UNotifier::waitOnAsynchronousBatch()");
|
||||
|
||||
uint32_t waitingOnN = waiting.size();
|
||||
|
||||
int epollfd = U_SYSCALL(epoll_create1, "%d", 0);
|
||||
|
||||
struct epoll_event* events;
|
||||
struct epoll_event* pevents;
|
||||
|
||||
events =
|
||||
pevents = (struct epoll_event*) UMemoryPool::u_malloc(waitingOnN + 1, sizeof(struct epoll_event), true);
|
||||
|
||||
for (uint32_t i = 0; i < waitingOnN; ++i)
|
||||
{
|
||||
UEventFd* waiter = waiting.at(i);
|
||||
struct epoll_event _events = { (uint32_t)op, { waiter } };
|
||||
|
||||
(void) U_FF_SYSCALL(epoll_ctl, "%d,%d,%d,%p", epollfd, EPOLL_CTL_ADD, waiter->UEventFd::fd, &_events);
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
UTimeVal* timer = U_NULLPTR;
|
||||
|
||||
if (timeoutMS > 0) U_NEW(UTimeVal, timer, UTimeVal);
|
||||
|
||||
do {
|
||||
if (timer) timer->start();
|
||||
|
||||
int nfd_ready = U_FF_SYSCALL(epoll_wait, "%d,%p,%u,%d", epollfd, events, waitingOnN, timeoutMS);
|
||||
|
||||
if (nfd_ready <= 0) // either timed out or failed
|
||||
{
|
||||
result = false;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// if it had timed out it would have returned 0, so we still have some time left
|
||||
if (timer) timeoutMS -= timer->stop();
|
||||
|
||||
waitingOnN -= nfd_ready;
|
||||
|
||||
pevents = events;
|
||||
|
||||
do {
|
||||
UEventFd* waiter = (UEventFd*)events->data.ptr;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case POLLIN: waiter->handlerRead(); break;
|
||||
case POLLOUT: waiter->handlerConnect(); break; // it's the responsibility of the wrapper to check if the connect completed succesfully or not
|
||||
default: break;
|
||||
}
|
||||
|
||||
pevents++;
|
||||
}
|
||||
while (--nfd_ready > 0);
|
||||
}
|
||||
while (waitingOnN > 0);
|
||||
|
||||
if (timer) U_DELETE(timer);
|
||||
|
||||
UMemoryPool::_free(events, waiting.size() + 1, sizeof(struct epoll_event));
|
||||
|
||||
(void) U_FF_SYSCALL(close, "%d", epollfd);
|
||||
|
||||
U_RETURN(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
int UNotifier::waitForWrite(int fd, int timeoutMS)
|
||||
{
|
||||
U_TRACE(0, "UNotifier::waitForWrite(%d,%d)", fd, timeoutMS)
|
||||
|
|
|
@ -67,6 +67,11 @@
|
|||
#else
|
||||
# define LIBQUICHE_ENABLE "no"
|
||||
#endif
|
||||
#ifdef USE_LIBMIMALLOC
|
||||
# define LIBMIMALLOC_ENABLE "yes ( " _LIBMIMALLOC_VERSION " )"
|
||||
#else
|
||||
# define LIBMIMALLOC_ENABLE "no"
|
||||
#endif
|
||||
#ifdef USE_LIBTDB
|
||||
# define LIBTDB_ENABLE "yes ( " _LIBTDB_VERSION " )"
|
||||
#else
|
||||
|
@ -727,6 +732,7 @@ PYTHON language support: yes ( 2.7 )
|
|||
"LIBZOPFLI support......:%W " LIBZOPFLI_ENABLE "%W\n" \
|
||||
"LIBBROTLI support......:%W " LIBBROTLI_ENABLE "%W\n" \
|
||||
"LIBQUICHE support......:%W " LIBQUICHE_ENABLE "%W\n" \
|
||||
"MIMALLOC support.......:%W " LIBMIMALLOC_ENABLE "%W\n" \
|
||||
"LIBTDB support.........:%W " LIBTDB_ENABLE "%W\n" \
|
||||
"PCRE support...........:%W " LIBPCRE_ENABLE "%W\n" \
|
||||
"SSL support............:%W " LIBSSL_ENABLE "%W\n" \
|
||||
|
@ -806,6 +812,7 @@ PYTHON language support: yes ( 2.7 )
|
|||
BRIGHTYELLOW, RESET,
|
||||
BRIGHTYELLOW, RESET,
|
||||
BRIGHTYELLOW, RESET,
|
||||
BRIGHTYELLOW, RESET,
|
||||
// parser
|
||||
BRIGHTYELLOW, RESET,
|
||||
BRIGHTYELLOW, RESET);
|
||||
|
|
|
@ -363,7 +363,7 @@ bool UMySqlStatement::setBindParam(UOrmDriver* pdrv)
|
|||
{
|
||||
USqlStatementBindParam* param;
|
||||
|
||||
mysql_vparam = (MYSQL_BIND*) UMemoryPool::malloc(num_bind_param, sizeof(MYSQL_BIND), true);
|
||||
mysql_vparam = (MYSQL_BIND*) UMemoryPool::u_malloc(num_bind_param, sizeof(MYSQL_BIND), true);
|
||||
|
||||
for (uint32_t i = 0; i < num_bind_param; ++i)
|
||||
{
|
||||
|
@ -494,7 +494,7 @@ bool UMySqlStatement::setBindResult(UOrmDriver* pdrv)
|
|||
{
|
||||
USqlStatementBindResult* result;
|
||||
|
||||
mysql_vresult = (MYSQL_BIND*) UMemoryPool::malloc(num_bind_result, sizeof(MYSQL_BIND), true);
|
||||
mysql_vresult = (MYSQL_BIND*) UMemoryPool::u_malloc(num_bind_result, sizeof(MYSQL_BIND), true);
|
||||
|
||||
for (uint32_t i = 0; i < num_bind_result; ++i)
|
||||
{
|
||||
|
|
|
@ -192,7 +192,7 @@ UPgSqlStatement::UPgSqlStatement(const char* s, uint32_t n) : USqlStatement(U_NU
|
|||
{
|
||||
vparam.reserve(num_bind_param);
|
||||
|
||||
paramTypes = (Oid*) UMemoryPool::malloc(num_bind_param * 3, sizeof(int), false);
|
||||
paramTypes = (Oid*) UMemoryPool::u_malloc(num_bind_param * 3, sizeof(int), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -417,7 +417,7 @@ bool UPgSqlStatement::setBindParam(UOrmDriver* pdrv)
|
|||
{
|
||||
if (paramValues == U_NULLPTR)
|
||||
{
|
||||
paramValues = (const char**) UMemoryPool::malloc(num_bind_param, sizeof(const char*), false);
|
||||
paramValues = (const char**) UMemoryPool::u_malloc(num_bind_param, sizeof(const char*), false);
|
||||
|
||||
U_INTERNAL_ASSERT_EQUALS(paramLengths, U_NULLPTR)
|
||||
|
||||
|
|
|
@ -911,8 +911,8 @@ void UQueryParser::startEvaluate(bPFpr func)
|
|||
|
||||
uint32_t sz = termRoots->size();
|
||||
|
||||
negatives = (UVector<UString>**) UMemoryPool::malloc(sz, sizeof(void*));
|
||||
positives = (UVector<UString>**) UMemoryPool::malloc(sz, sizeof(void*));
|
||||
negatives = (UVector<UString>**) UMemoryPool::u_malloc(sz, sizeof(void*));
|
||||
positives = (UVector<UString>**) UMemoryPool::u_malloc(sz, sizeof(void*));
|
||||
|
||||
for (uint32_t i = 0; i < sz; ++i)
|
||||
{
|
||||
|
|
|
@ -25,9 +25,8 @@ size_t UHTTP3::conn_id_len;
|
|||
uint8_t UHTTP3::conn_id[QUICHE_MAX_CONN_ID_LEN];
|
||||
uint32_t UHTTP3::peer_addr_len;
|
||||
uint32_t UHTTP3::quiche_max_packet_size = U_MAX_DATAGRAM_SIZE;
|
||||
quiche_conn* UHTTP3::conn;
|
||||
quiche_config* UHTTP3::qconfig;
|
||||
quiche_h3_conn* UHTTP3::http3;
|
||||
UHTTP3::conn_io UHTTP3::conn;
|
||||
quiche_h3_config* UHTTP3::http3_config;
|
||||
|
||||
struct sockaddr_storage UHTTP3::peer_addr;
|
||||
|
@ -186,6 +185,7 @@ bool UHTTP3::handlerRead()
|
|||
U_INTERNAL_ASSERT(UServer_Base::budp)
|
||||
|
||||
int rc;
|
||||
void* pconn;
|
||||
uint8_t pkt_type;
|
||||
uint32_t pkt_version;
|
||||
size_t scid_len, token_len;
|
||||
|
@ -240,123 +240,132 @@ bool UHTTP3::handlerRead()
|
|||
"pkt_version = %d pkt_type = %d",
|
||||
scid_len, scid_len, scid, token_len, token_len, token, conn_id_len, conn_id_len, conn_id, pkt_version, pkt_type)
|
||||
|
||||
U_INTERNAL_DUMP("conn = %p", conn)
|
||||
// Lookup a connection based on the packet's connection ID. If there is no connection matching, create a new one
|
||||
pconn = (peers->empty() ? U_NULLPTR : peers->at((const char*)conn_id, conn_id_len));
|
||||
|
||||
if (conn == U_NULLPTR)
|
||||
U_INTERNAL_DUMP("pconn = %p", pconn)
|
||||
|
||||
if (pconn == U_NULLPTR)
|
||||
{
|
||||
// Lookup a connection based on the packet's connection ID. If there is no connection matching, create a new one
|
||||
UServer_Base::pClientImage = (peers->empty() ? U_NULLPTR : peers->at((const char*)conn_id, conn_id_len));
|
||||
const char* pkt = "vneg";
|
||||
|
||||
if (UServer_Base::pClientImage == U_NULLPTR)
|
||||
if (pkt_type != Initial)
|
||||
{
|
||||
const char* pkt = "vneg";
|
||||
U_DEBUG("UHTTP3::handlerRead(): packet is NOT initial: %d", pkt_type);
|
||||
|
||||
if (pkt_type != Initial)
|
||||
{
|
||||
U_DEBUG("UHTTP3::handlerRead(): packet is NOT initial: %d", pkt_type);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Returns true if the given protocol version is supported
|
||||
if (U_SYSCALL(quiche_version_is_supported, "%u", pkt_version) == false)
|
||||
{
|
||||
U_DEBUG("UHTTP3::handlerRead(): 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("UHTTP3::handlerRead(): failed to create %s packet: %d", pkt, written);
|
||||
|
||||
U_RETURN(false);
|
||||
}
|
||||
|
||||
sent = U_SYSCALL(sendto, "%d,%p,%u,%u,%p,%d", fd, out, written, 0, (struct sockaddr*)&peer_addr, peer_addr_len);
|
||||
|
||||
if (sent == written)
|
||||
{
|
||||
U_DEBUG("UHTTP3::handlerRead(): sent %u bytes", sent);
|
||||
}
|
||||
else
|
||||
{
|
||||
U_DEBUG("UHTTP3::handlerRead(): failed to send");
|
||||
}
|
||||
|
||||
U_RETURN(false);
|
||||
}
|
||||
|
||||
if (token_len == 0)
|
||||
{
|
||||
uint8_t odcid[QUICHE_MAX_CONN_ID_LEN];
|
||||
|
||||
// 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("UHTTP3::handlerRead(): stateless retry");
|
||||
|
||||
(void) memcpy(token, U_CONSTANT_TO_PARAM("quiche"));
|
||||
(void) memcpy(token + U_CONSTANT_SIZE("quiche"), &peer_addr, peer_addr_len);
|
||||
(void) memcpy(token + U_CONSTANT_SIZE("quiche") + peer_addr_len, conn_id, conn_id_len);
|
||||
|
||||
token_len = U_CONSTANT_SIZE("quiche") + peer_addr_len + conn_id_len;
|
||||
|
||||
u__memcpy(odcid, conn_id, conn_id_len, __PRETTY_FUNCTION__);
|
||||
|
||||
// Writes a retry packet
|
||||
written = U_SYSCALL(quiche_retry, "%p,%u,%p,%u,%p,%u,%p,%u,%p,%u", scid, scid_len, conn_id, conn_id_len, odcid, conn_id_len, token, token_len, out, sizeof(out));
|
||||
|
||||
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 < U_CONSTANT_SIZE("quiche") ||
|
||||
memcmp(token, U_CONSTANT_TO_PARAM("quiche")))
|
||||
{
|
||||
U_DEBUG("UHTTP3::handlerRead(): invalid address validation token");
|
||||
|
||||
U_RETURN(false);
|
||||
}
|
||||
|
||||
token_len -= U_CONSTANT_SIZE("quiche");
|
||||
|
||||
const char* ptr = (const char*)&token[0] + U_CONSTANT_SIZE("quiche");
|
||||
|
||||
if (token_len < peer_addr_len ||
|
||||
memcmp(ptr, &peer_addr, peer_addr_len))
|
||||
{
|
||||
U_DEBUG("UHTTP3::handlerRead(): invalid address validation token");
|
||||
|
||||
U_RETURN(false);
|
||||
}
|
||||
|
||||
ptr += peer_addr_len;
|
||||
token_len -= 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::handlerRead(): 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::handlerRead(): failed to create connection");
|
||||
|
||||
U_RETURN(false);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Client Initial packets must be at least 1200 bytes
|
||||
if (iBytesRead < QUICHE_MIN_CLIENT_INITIAL_LEN)
|
||||
{
|
||||
U_DEBUG("UHTTP3::handlerRead(): quic initial packet is too short: %d", iBytesRead);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Returns true if the given protocol version is supported
|
||||
if (U_SYSCALL(quiche_version_is_supported, "%u", pkt_version) == false)
|
||||
{
|
||||
U_DEBUG("UHTTP3::handlerRead(): 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("UHTTP3::handlerRead(): failed to create %s packet: %d", pkt, written);
|
||||
|
||||
U_RETURN(false);
|
||||
}
|
||||
|
||||
sent = U_SYSCALL(sendto, "%d,%p,%u,%u,%p,%d", fd, out, written, 0, (struct sockaddr*)&peer_addr, peer_addr_len);
|
||||
|
||||
if (sent == written)
|
||||
{
|
||||
U_DEBUG("UHTTP3::handlerRead(): sent %u bytes", sent);
|
||||
}
|
||||
else
|
||||
{
|
||||
U_DEBUG("UHTTP3::handlerRead(): failed to send");
|
||||
}
|
||||
|
||||
U_RETURN(false);
|
||||
}
|
||||
|
||||
if (token_len == 0)
|
||||
{
|
||||
uint8_t odcid[QUICHE_MAX_CONN_ID_LEN];
|
||||
|
||||
// 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("UHTTP3::handlerRead(): stateless retry");
|
||||
|
||||
(void) memcpy(token, U_CONSTANT_TO_PARAM("quiche"));
|
||||
(void) memcpy(token + U_CONSTANT_SIZE("quiche"), &peer_addr, peer_addr_len);
|
||||
(void) memcpy(token + U_CONSTANT_SIZE("quiche") + peer_addr_len, conn_id, conn_id_len);
|
||||
|
||||
token_len = U_CONSTANT_SIZE("quiche") + peer_addr_len + conn_id_len;
|
||||
|
||||
u__memcpy(odcid, conn_id, conn_id_len, __PRETTY_FUNCTION__);
|
||||
|
||||
// Writes a retry packet
|
||||
written = U_SYSCALL(quiche_retry, "%p,%u,%p,%u,%p,%u,%p,%u,%p,%u", scid, scid_len, conn_id, conn_id_len, odcid, conn_id_len, token, token_len, out, sizeof(out));
|
||||
|
||||
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 < U_CONSTANT_SIZE("quiche") ||
|
||||
memcmp(token, U_CONSTANT_TO_PARAM("quiche")))
|
||||
{
|
||||
U_DEBUG("UHTTP3::handlerRead(): invalid address validation token");
|
||||
|
||||
U_RETURN(false);
|
||||
}
|
||||
|
||||
token_len -= U_CONSTANT_SIZE("quiche");
|
||||
|
||||
const char* ptr = (const char*)&token[0] + U_CONSTANT_SIZE("quiche");
|
||||
|
||||
if (token_len < peer_addr_len ||
|
||||
memcmp(ptr, &peer_addr, peer_addr_len))
|
||||
{
|
||||
U_DEBUG("UHTTP3::handlerRead(): invalid address validation token");
|
||||
|
||||
U_RETURN(false);
|
||||
}
|
||||
|
||||
ptr += peer_addr_len;
|
||||
token_len -= 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::handlerRead(): invalid address validation token");
|
||||
|
||||
U_RETURN(false);
|
||||
}
|
||||
|
||||
U_INTERNAL_ASSERT_EQUALS(conn.conn, U_NULLPTR)
|
||||
|
||||
// Reuse the source connection ID we sent in the Retry packet, instead of changing it again. Creates a new server-side connection
|
||||
conn.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.conn == U_NULLPTR)
|
||||
{
|
||||
U_DEBUG("UHTTP3::handlerRead(): failed to create connection");
|
||||
|
||||
U_RETURN(false);
|
||||
}
|
||||
|
||||
peers->insert((const char*)conn_id, conn_id_len, (const UClientImage_Base*)&conn);
|
||||
}
|
||||
|
||||
// Processes QUIC packets received from the peer
|
||||
done = U_SYSCALL(quiche_conn_recv, "%p,%p,%u", conn, (uint8_t*)data, iBytesRead);
|
||||
done = U_SYSCALL(quiche_conn_recv, "%p,%p,%u", conn.conn, (uint8_t*)data, iBytesRead);
|
||||
|
||||
if (done == QUICHE_ERR_DONE)
|
||||
{
|
||||
|
@ -374,17 +383,17 @@ pkt: if (written < 0)
|
|||
|
||||
U_DEBUG("UHTTP3::handlerRead(): recv %d bytes", done);
|
||||
|
||||
if (U_SYSCALL(quiche_conn_is_in_early_data, "%p", conn) || // the connection has a pending handshake that has progressed
|
||||
U_SYSCALL(quiche_conn_is_established, "%p", conn)) // the connection handshake is complete
|
||||
if (U_SYSCALL(quiche_conn_is_in_early_data, "%p", conn.conn) || // the connection has a pending handshake that has progressed
|
||||
U_SYSCALL(quiche_conn_is_established, "%p", conn.conn)) // the connection handshake is complete
|
||||
{
|
||||
U_DEBUG("UHTTP3::handlerRead(): connection handshake is complete");
|
||||
|
||||
U_INTERNAL_ASSERT_EQUALS(http3, U_NULLPTR)
|
||||
U_INTERNAL_ASSERT_EQUALS(conn.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);
|
||||
conn.http3 = (quiche_h3_conn*) U_SYSCALL(quiche_h3_conn_new_with_transport, "%p,%p", conn.conn, http3_config);
|
||||
|
||||
if (http3 == U_NULLPTR)
|
||||
if (conn.http3 == U_NULLPTR)
|
||||
{
|
||||
U_DEBUG("UHTTP3::handlerAccept(): failed to create HTTP/3 connection");
|
||||
|
||||
|
@ -396,7 +405,7 @@ pkt: if (written < 0)
|
|||
while (true)
|
||||
{
|
||||
// Processes HTTP/3 data received from the peer
|
||||
done = U_SYSCALL(quiche_h3_conn_poll, "%p,%p,%p", http3, conn, &ev);
|
||||
done = U_SYSCALL(quiche_h3_conn_poll, "%p,%p,%p", conn.http3, conn.conn, &ev);
|
||||
|
||||
if (done < 0) break;
|
||||
|
||||
|
@ -465,7 +474,7 @@ pkt: if (written < 0)
|
|||
|
||||
while (true)
|
||||
{
|
||||
written = U_SYSCALL(quiche_conn_send, "%p,%p,%u", conn, out, sizeof(out));
|
||||
written = U_SYSCALL(quiche_conn_send, "%p,%p,%u", conn.conn, out, sizeof(out));
|
||||
|
||||
if (written == QUICHE_ERR_DONE)
|
||||
{
|
||||
|
@ -502,20 +511,20 @@ bool UHTTP3::handlerAccept()
|
|||
{
|
||||
U_TRACE_NO_PARAM(0, "UHTTP3::handlerAccept()")
|
||||
|
||||
U_INTERNAL_ASSERT_POINTER(conn)
|
||||
U_INTERNAL_ASSERT_POINTER(http3)
|
||||
U_INTERNAL_ASSERT_POINTER(conn.conn)
|
||||
U_INTERNAL_ASSERT_POINTER(conn.http3)
|
||||
U_INTERNAL_ASSERT(UServer_Base::budp)
|
||||
U_INTERNAL_ASSERT_POINTER(UServer_Base::pClientImage)
|
||||
|
||||
UServer_Base::pClientImage->conn = conn;
|
||||
UServer_Base::pClientImage->http3 = http3;
|
||||
UServer_Base::pClientImage->conn = conn.conn;
|
||||
UServer_Base::pClientImage->http3 = conn.http3;
|
||||
|
||||
conn = U_NULLPTR;
|
||||
http3 = U_NULLPTR;
|
||||
conn.conn = U_NULLPTR;
|
||||
conn.http3 = U_NULLPTR;
|
||||
|
||||
UServer_Base::pClientImage->socket->setRemoteAddressAndPort();
|
||||
|
||||
peers->insert((const char*)conn_id, conn_id_len, UServer_Base::pClientImage);
|
||||
peers->replace((const char*)conn_id, conn_id_len, UServer_Base::pClientImage);
|
||||
|
||||
U_RETURN(true);
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
07F4
|
||||
0800
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1504,7 +1504,7 @@ U_EXPORT main(int argc, char* argv[])
|
|||
|
||||
U_ASSERT( byte_count == U_STRING_FROM_CONSTANT("4.0 GiB") )
|
||||
|
||||
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX)
|
||||
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) && GCC_VERSION_NUM < 100100
|
||||
UString token = U_STRING_FROM_CONSTANT("a"),
|
||||
firstname = U_STRING_FROM_CONSTANT("Victor"),
|
||||
lastname = U_STRING_FROM_CONSTANT("Stewart"),
|
||||
|
|
Loading…
Reference in New Issue
Block a user