From 831d4199fa39c3facda931d0280f2032761a9c70 Mon Sep 17 00:00:00 2001 From: stefanocasazza Date: Sat, 11 Jul 2020 18:27:06 +0200 Subject: [PATCH] sync --- configure | 2 +- configure.ac | 2 +- examples/WiAuth/v2/wi_auth_declaration2.h | 4 +- include/ulib/net/client/redis.h | 385 ++-- include/ulib/net/server/client_image.h | 79 +- include/ulib/net/server/server.h | 81 +- include/ulib/net/socket.h | 34 +- include/ulib/string.h | 32 +- include/ulib/utility/http3.h | 43 +- include/ulib/utility/socket_ext.h | 17 +- src/ulib/net/client/redis.cpp | 43 +- src/ulib/net/server/client_image.cpp | 61 +- src/ulib/net/server/server.cpp | 1280 +++++++------ src/ulib/net/socket.cpp | 14 +- src/ulib/utility/http3.cpp | 535 +++--- src/ulib/utility/uhttp.cpp | 6 +- test-driver | 23 +- tests/.function | 1 + tests/examples/CSP/CSP/DB_CA/openssl.cnf.tmpl | 13 +- tests/examples/TSA/tsaserial | 2 +- tests/examples/csp_rpc.test | 9 +- tests/examples/inp/openssl.cnf | 13 +- tests/examples/ok/web_server_rng.ok | 1657 +++++++++++++++-- tests/examples/tsa_ssoap.test | 4 +- tests/examples/udp_server.sh | 4 +- tests/examples/web_server.test | 4 +- tests/examples/web_server_multiclient.test | 14 +- tests/examples/web_server_rng.test | 6 +- .../examples/web_server_rng_multiclient.test | 5 +- tests/ulib/ioring.test | 10 +- 30 files changed, 3113 insertions(+), 1270 deletions(-) diff --git a/configure b/configure index 5ca9cee0..43161103 100755 --- a/configure +++ b/configure @@ -33126,7 +33126,7 @@ else fi -if test "x$use_userver_udp" != "xno" -a "$enable_http3" = "yes" -a "$USE_LIBQUICHE" = "yes"; then +if test "x$use_userver_udp" != "xno" -a "$enable_http3" = "yes" -a "$USE_LIBQUICHE" = "yes" -a "$USE_LIBURING" = "yes"; then if true; then HTTP3_TRUE= HTTP3_FALSE='#' diff --git a/configure.ac b/configure.ac index f845ddf6..e858e1da 100644 --- a/configure.ac +++ b/configure.ac @@ -2558,7 +2558,7 @@ fi AM_CONDITIONAL(HTTP3, false) AM_CONDITIONAL(USERVER_UDP, false) -if test "x$use_userver_udp" != "xno" -a "$enable_http3" = "yes" -a "$USE_LIBQUICHE" = "yes"; then +if test "x$use_userver_udp" != "xno" -a "$enable_http3" = "yes" -a "$USE_LIBQUICHE" = "yes" -a "$USE_LIBURING" = "yes"; then AM_CONDITIONAL(HTTP3, true) AM_CONDITIONAL(USERVER_UDP, true) AC_DEFINE(USERVER_UDP, 1, [Define if use userver_udp]) diff --git a/examples/WiAuth/v2/wi_auth_declaration2.h b/examples/WiAuth/v2/wi_auth_declaration2.h index effbd2e2..6dafc357 100644 --- a/examples/WiAuth/v2/wi_auth_declaration2.h +++ b/examples/WiAuth/v2/wi_auth_declaration2.h @@ -592,10 +592,12 @@ static void setSessionPolicy() } else { + U_LOGGER("*** AP:id:%v NOT FOUND ***", ap_label->rep); + ap_consume = true; ap_notify = 0; // notify - (void) rc->hmset(U_CONSTANT_TO_PARAM("AP:id:%v consume 1 notify 3"), ap_label->rep); + // (void) rc->hmset(U_CONSTANT_TO_PARAM("AP:id:%v consume 1 notify 3"), ap_label->rep); } U_INTERNAL_DUMP("ap_consume = %b ap_notify = %u", ap_consume, ap_notify) diff --git a/include/ulib/net/client/redis.h b/include/ulib/net/client/redis.h index 8dadf6fd..94523f2f 100644 --- a/include/ulib/net/client/redis.h +++ b/include/ulib/net/client/redis.h @@ -192,45 +192,6 @@ public: bool connect(const char* host = U_NULLPTR, unsigned int _port = 6379); - // by Victor Stewart - - UString single(const UString& pipeline) - { - U_TRACE(0, "UREDISClient_Base::single(%V)", pipeline.rep) - - (void) processRequest(U_RC_MULTIBULK, U_STRING_TO_PARAM(pipeline)); - - return vitem[0]; - } - - bool silencedSingle(UString& pipeline) - { - U_TRACE(0, "UREDISClient_Base::silencedSingle(%V)", pipeline.rep) - - return sendRequest(U_CONSTANT_TO_PARAM("CLIENT REPLY SKIP \r\n"), pipeline); - } - - const UVector& multi(const UString& pipeline) - { - U_TRACE(0, "UREDISClient_Base::multi(%V)", pipeline.rep) - - (void) processRequest(U_RC_MULTIBULK, U_STRING_TO_PARAM(pipeline)); - - return vitem; - } - - bool silencedMulti(UString& pipeline) - { - U_TRACE(0, "UREDISClient_Base::silencedMulti(%V)", pipeline.rep) - - bool result = sendRequest(U_CONSTANT_TO_PARAM("CLIENT REPLY OFF \r\n"), pipeline + "CLIENT REPLY ON \r\n"); - - // CLIENT REPLY ON responds with "+OK\r\n" and no way to silence it - UClient_Base::readResponse(); - - return result; - } - // STRING (@see http://redis.io/commands#string) bool get(const char* key, uint32_t keylen) // Get the value of a key @@ -807,7 +768,7 @@ protected: void init(); - static void parseResponse(UString& response, UVector& parsed, size_t index, size_t terminalIndex) + static void parseResponse(UString& response, UVector& parsed, size_t index, size_t terminalIndex, ssize_t depth = 0) { U_TRACE(0, "UREDISClient_Base::parseResponse(index = %lu, terminalIndex = %lu)", index, terminalIndex); @@ -815,9 +776,12 @@ protected: ptr1 = (ptr2 = response.c_pointer(index)); - while (ptr2 < pend) + while (ptr2 < pend && depth > 0) { - while (*ptr2 != '\r') ++ptr2; + while (*ptr2 != '\r') + { + ++ptr2; + } switch (*ptr1++) { @@ -838,6 +802,7 @@ protected: else { size_t length = u_strtoul(ptr1, ptr2); + parsed.push_back(response.substr((ptr2 += U_CONSTANT_SIZE(U_CRLF)), length)); ptr2 += length; } @@ -846,15 +811,17 @@ protected: } // *2\r\n$10\r\n1439822796\r\n$6\r\n311090\r\n case U_RC_MULTIBULK: - // never - default: - break; + { + depth += u_strtoul(ptr1, ptr2); + break; + } + default: break; // never } + --depth; + ptr1 = (ptr2 += U_CONSTANT_SIZE(U_CRLF)); } - - //U_DUMP_CONTAINER(parsed); } void processResponse() @@ -865,19 +832,13 @@ protected: bool processRequest(char recvtype); -#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) -#endif { U_TRACE_NO_PARAM(0, "UREDISClient_Base::sendRequest()"); UClient_Base::iov[0].iov_base = (caddr_t)pipeline.data(); UClient_Base::iov[0].iov_len = pipeline.size(); - UClient_Base::iov[1].iov_base = (caddr_t)U_CRLF; - UClient_Base::iov[1].iov_len = - UClient_Base::iovcnt = 2; + UClient_Base::iovcnt = 1; return UClient_Base::sendRequest(false); } @@ -1037,7 +998,40 @@ private: // by Victor Stewart -#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) && GCC_VERSION_NUM < 100100 +#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) + +enum class RedisOptions : uint8_t { + + one = 0b0000'0001, // return one item, of type const UString& + many = 0b0000'0010, // return all items, of type const UVector& + + // for cluster mode these are "psuedo-silenced", aka we wait on responses to ensure no cluster errors, but don't waste resources processing the responses + silenced = 0b0000'0100, // void + reorderable = 0b0000'1000, // only in cluster mode + + copy = 0b0001'0000, // if data needs to persist through subsequent Redis calls, at the cost of copy operation + asynchronous = 0b0010'0000 +}; + +constexpr RedisOptions operator |(RedisOptions lhs, RedisOptions rhs) +{ + using underlying = typename std::underlying_type::type; + return static_cast + ( + static_cast(lhs) | + static_cast(rhs) + ); +} + +constexpr bool operator &(RedisOptions lhs, RedisOptions rhs) +{ + using underlying = typename std::underlying_type::type; + return static_cast + ( + static_cast(lhs) & + static_cast(rhs) + ); +} class UCompileTimeRESPEncoder : public UCompileTimeStringFormatter { private: @@ -1179,39 +1173,231 @@ public: } }; -enum class RedisOptions : uint8_t { +class RedisSubscriber : public UEventFd { +private: + + UString subscriptionString; + USocket *subscriptionSocket; + UHashMap* pchannelCallbackMap; + +public: + + virtual int handlerRead() U_DECL_FINAL; + + void subscribe(const UString& channel, vPFcscs callback) + { + subscriptionString.setEmpty(); + UCompileTimeRESPEncoder::encode<"SUBSCRIBE {}"_ctv>(subscriptionString, channel); + USocketExt::write(subscriptionSocket, U_STRING_TO_PARAM(subscriptionString), 500); + + UString channelCopy(U_STRING_TO_PARAM(channel)); + pchannelCallbackMap->insert(channelCopy, (const void*)callback); + } + + void unsubscribe(const UString& channel) + { + subscriptionString.setEmpty(); + UCompileTimeRESPEncoder::encode<"UNSUBSCRIBE {}"_ctv>(subscriptionString, channel); + USocketExt::write(subscriptionSocket, U_STRING_TO_PARAM(subscriptionString), 500); + (void)pchannelCallbackMap->erase(channel); + } + + void connectForSubscriptions(const UString& host, uint16_t port) + { + subscriptionSocket->connectServer(host, port, 500); + + U_NEW(UHashMap, pchannelCallbackMap, UHashMap()); + + this->UEventFd::fd = subscriptionSocket->getFd(); + this->UEventFd::op_mask |= EPOLLET; + UServer_Base::addHandlerEvent(this); + } + + RedisSubscriber() + { + U_NEW(USocket, subscriptionSocket, USocket); + } - one = 0b0000'0001, // const UString& - many = 0b0000'0010, // const UVector& - - //these are "psuedo-silenced", aka we wait on responses to ensure no cluster errors, but don't waste resources processing the responses - silenced = 0b0000'0100, // void - reorderable = 0b0000'1000, - - copy = 0b0001'0000 // if data needs to persist through subsequent Redis calls, at the cost of copy operation + ~RedisSubscriber() + { + U_DELETE(subscriptionSocket); + if (pchannelCallbackMap) U_DELETE(pchannelCallbackMap); + } }; -constexpr RedisOptions operator |(RedisOptions lhs, RedisOptions rhs) -{ - using underlying = typename std::underlying_type::type; - return static_cast - ( - static_cast(lhs) | - static_cast(rhs) - ); -} +class URedisClient2 : public UEventFd { +private: -constexpr bool operator &(RedisOptions lhs, RedisOptions rhs) -{ - using underlying = typename std::underlying_type::type; - return static_cast - ( - static_cast(lhs) & - static_cast(rhs) - ); -} + RedisSubscriber subscriber; + USocket *socket; -static uint16_t hashslotForKey(UStringType&& hashableKey) + UString workingString; + UVector vitem; + uint8_t pendingSilencedWrites; + + virtual int handlerRead() U_DECL_FINAL + { + // currently if you want to read responses asynchronsouly, you must do so by explicitly calling read() before your USP returns, otherwise the response was assumed to have been silenced, and thus we read until empty then discard. + + workingString.setEmpty(); + USocketExt::read(socket, workingString, U_SINGLE_READ, 100); + + // every silenced response is +OK/r/n and we assume we only receive whole responses.. aka not chopped in the middle into differing TCP packets. + // thus each response is 5 bytes + pendingSilencedWrites -= (workingString.size() / 5); + + return U_NOTIFIER_OK; + } + +public: + + // only explicitly call this to read asynchronously + template + const decltype(auto) read(size_t commandCount) + { + vitem.clear(); + workingString.setEmpty(); + + const char *pointer1, *pointer2, *pend; + pointer1 = pointer2 = pend = workingString.data(); + + auto readAndRevalidatePointers = [&] (void) -> void { + + size_t index1 = pointer1 - workingString.data(); + size_t index2 = pointer2 - workingString.data(); + USocketExt::read(socket, workingString, U_SINGLE_READ, 500); + pointer1 = workingString.c_pointer(index1); + pointer2 = workingString.c_pointer(index2); + pend = workingString.pend(); + }; + + uint8_t depth = commandCount; + + do + { + if (pointer1 >= pend) readAndRevalidatePointers(); + + while (*pointer2 != '\r') + { + // no knowing where the TCP packets might have been sliced + if (UNLIKELY(++pointer2 == pend)) readAndRevalidatePointers(); + } + + switch (*pointer1++) + { + // :0\r\n + case U_RC_INT: + // +OK\r\n + case U_RC_INLINE: + // -Error message\r\n + case U_RC_ERROR: // only errors here are your fault + { + if (LIKELY(pendingSilencedWrites == 0)) vitem.push_back(workingString.substr(pointer1, pointer2 - pointer1)); + else + { + depth++; // to counterbalance the decrement after the switch + pendingSilencedWrites--; + } + + break; + } + // $-1\r\n + // $15\r\nmy-value-tester\r\n + case U_RC_BULK: + { + if (pointer1[0] == '-') vitem.push_back(UString::getStringNull()); + else + { + size_t length = u_strtoul(pointer1, pointer2); + + if ((pointer2 + U_CONSTANT_SIZE(U_CRLF) + length + U_CONSTANT_SIZE(U_CRLF)) > pend) readAndRevalidatePointers(); + + vitem.push_back(workingString.substr((pointer2 += U_CONSTANT_SIZE(U_CRLF)), length)); + + pointer2 += length; + } + + break; + } + // *2\r\n$10\r\n1439822796\r\n$6\r\n311090\r\n + case U_RC_MULTIBULK: + { + depth += u_strtoul(pointer1, pointer2); + break; + } + + default: break; + } + + --depth; + + pointer1 = (pointer2 += U_CONSTANT_SIZE(U_CRLF)); + + } while (depth > 0); + + if constexpr (options & RedisOptions::one) + { + if (vitem.size()) + { + if constexpr (options & RedisOptions::copy) return vitem[0].copy(); + else return vitem[0]; + } + else return UString::getStringNull().copy(); + } + else if constexpr (options & RedisOptions::many) + { + if constexpr (options & RedisOptions::copy) return UVector(vitem); + else return (vitem); + } + } + + // single refers to the targeting of a single Redis node (versus multi as in multiple nodes in a Cluster config) + + template + const decltype(auto) single(A&& pipeline, ssize_t commandCount = -1) + { + // this guarantees that no matter how many commands were pipelined, the only response will be +OK/r/n + // which decomplicates scenarios where you push multiple silenced writes, then issue a read where we + // would have to read out those silenced replies first before getting to the read in question. + if constexpr (options & RedisOptions::silenced) + { + pendingSilencedWrites++; + pipeline.insert(0, UCompileTimeRESPEncoder::CLIENTREPLYOFF); + pipeline.append(UCompileTimeRESPEncoder::CLIENTREPLYON); + } + + USocketExt::write(socket, U_STRING_TO_PARAM(pipeline), 500); + + if constexpr (options & RedisOptions::asynchronous || options & RedisOptions::silenced) return commandCount; + else return read(commandCount); + } + + template + const decltype(auto) single(Ts&&... ts) + { + return single(workingString, UCompileTimeRESPEncoder::encode(workingString, std::forward(ts)...)); + } + + void subscribe(const UString& channel, vPFcscs callback) { subscriber.subscribe(channel, callback); } + void unsubscribe(const UString& channel) { subscriber.unsubscribe(channel); } + + URedisClient2(const UString& host, uint16_t port) + { + U_NEW(USocket, socket, USocket); + socket->connectServer(host, port, 500); + subscriber.connectForSubscriptions(host, port); + } + + ~URedisClient2() + { + U_DELETE(socket); + } +}; + + +///// CLUSTER ///// + +static uint16_t hashslotForKey(UStringType auto&& hashableKey) { return u_crc16(U_STRING_TO_PARAM(hashableKey)) % 16384; } @@ -1238,9 +1424,10 @@ public: pipeline.setEmpty(); } - void setHashslot(UStringType&& hashableKey) + template + void setHashslot(T&& hashableKey) { - hashslot = hashslotForKey(std::forward(hashableKey)); + hashslot = hashslotForKey(std::forward(hashableKey)); } void append(const UString& command, uint8_t count) @@ -1329,7 +1516,7 @@ public: RedisClusterMultiPipeline() : pipeline(300U) {} }; -class U_EXPORT UREDISClusterMaster : public UEventFd { +class U_EXPORT UREDISClusterMaster : public RedisSubscriber { private: struct RedisClusterNode { @@ -1345,7 +1532,7 @@ private: RedisClusterNode(const UString& _ipAddress, uint16_t _port, uint16_t _lowHashSlot, uint16_t _highHashSlot) : ipAddress(_ipAddress), port(_port), lowHashSlot(_lowHashSlot), highHashSlot(_highHashSlot) { U_NEW(USocket, socket, USocket); - socket->connectServer(ipAddress, port, 1000); + socket->connectServer(ipAddress, port, 500); } #if defined(DEBUG) @@ -1355,17 +1542,13 @@ private: friend class RedisClusterMultiPipeline; - UString workingString, subscriptionString; + UString workingString; UVector parsed; - USocket *subscriptionSocket; USocket *managementSocket; UHashMap *clusterNodes; // speed at the cost of memory, worth it std::unordered_map hashslotToSocket; - UHashMap* pchannelCallbackMap; - - virtual int handlerRead() U_DECL_FINAL; template USocket* socketForHashableKey(A&& hashableKey) const { return hashslotToSocket[hashslotForKey(std::forward(hashableKey))]; } @@ -1388,7 +1571,7 @@ private: size_t index1 = pointer1 - workingString.data(); size_t index2 = pointer2 - workingString.data(); - USocketExt::read(socket, workingString, U_SINGLE_READ, 1000); + USocketExt::read(socket, workingString, U_SINGLE_READ, 500); pointer1 = workingString.c_pointer(index1); pointer2 = workingString.c_pointer(index2); pend = workingString.pend(); @@ -1482,12 +1665,12 @@ private: } while (depth > 0); - report.end = pointer2 - workingString.data();; + report.end = pointer2 - workingString.data(); return report; } - bool handleErrors(RedisReadReport& report, uint16_t hashslot, UStringType&& pipeline, size_t commandCount, bool skipRecloning = false) + bool handleErrors(RedisReadReport& report, uint16_t hashslot, UStringType auto&& pipeline, size_t commandCount, bool skipRecloning = false) { bool recloned = skipRecloning; @@ -1509,7 +1692,7 @@ private: case RedisClusterError::ask: case RedisClusterError::tryagain: { - USocketExt::write(report.socketAfterError, U_STRING_TO_PARAM(pipeline), 1000); + USocketExt::write(report.socketAfterError, U_STRING_TO_PARAM(pipeline), 500); } default: break; @@ -1536,7 +1719,7 @@ private: size_t pipelineLength = (pipeline.data() == workingString.data()) ? pipeline.size() : 0; // U_DUMP("pipelineLength = %lu", pipelineLength); - USocketExt::write(workingSocket, U_STRING_TO_PARAM(pipeline), 1000); + USocketExt::write(workingSocket, U_STRING_TO_PARAM(pipeline), 500); RedisReadReport report = read(workingSocket, workingString.size(), commandCount); @@ -1679,7 +1862,7 @@ public: } while (++it != pipeline.spans.end() && workingSocket == hashslotToSocket[it->hashslot]); - USocketExt::write(workingSocket, U_STRING_TO_PARAM(workingString), 1000); + USocketExt::write(workingSocket, U_STRING_TO_PARAM(workingString), 500); workingString.setEmpty(); } while (it != pipeline.spans.end()); @@ -1751,22 +1934,16 @@ public: return handleReturn(); } - void clusterUnsubscribe(const UString& channel); - void clusterSubscribe( const UString& channel, vPFcscs callback); - UREDISClusterMaster() { clusterNodes = U_NULLPTR; U_NEW(USocket, managementSocket, USocket); - U_NEW(USocket, subscriptionSocket, USocket); } ~UREDISClusterMaster() { - U_DELETE(subscriptionSocket); U_DELETE(managementSocket); if (clusterNodes) U_DELETE(clusterNodes); - if (pchannelCallbackMap) U_DELETE(pchannelCallbackMap); } #if defined(DEBUG) diff --git a/include/ulib/net/server/client_image.h b/include/ulib/net/server/client_image.h index cd0813d0..3dfc4a93 100644 --- a/include/ulib/net/server/client_image.h +++ b/include/ulib/net/server/client_image.h @@ -24,12 +24,6 @@ # include #endif -#ifdef USE_LIBURING -# ifndef U_IO_BUFFER_SIZE -# define U_IO_BUFFER_SIZE U_1M // 1 MB in bytes -# endif -#endif - /** * @class UClientImage * @@ -54,9 +48,9 @@ template class UHashMap; #define U_ClientImage_request_is_cached UClientImage_Base::cbuffer[0] #define U_ClientImage_status(obj) (obj)->UClientImage_Base::flag.c[0] -#define U_ClientImage_op_pending(obj) (obj)->UClientImage_Base::flag.c[1] -#define U_ClientImage_write_pending(obj) (obj)->UClientImage_Base::flag.c[2] -#define U_ClientImage_user_value(obj) (obj)->UClientImage_Base::flag.c[3] +#define U_ClientImage_user_value(obj) (obj)->UClientImage_Base::flag.c[1] +#define U_ClientImage_op_pending(obj) (obj)->UClientImage_Base::flag.c[2] +#define U_ClientImage_write_pending(obj) (obj)->UClientImage_Base::flag.c[3] class U_EXPORT UClientImage_Base : public UEventFd { public: @@ -311,10 +305,10 @@ public: _ACCEPT = 0x02, _READ = 0x04, _WRITE = 0x08, - _WRITEV = 0x10, - _CLOSE = 0x20, - _CANCEL = 0x40, - _UPDATE = 0x80, + _CLOSE = 0x10, + _CANCEL = 0x20, + _UPDATE = 0x40, + _RECVMSG = 0x80, _CONNECT = _READ | _ACCEPT }; @@ -325,25 +319,18 @@ public: op == _ACCEPT ? "_ACCEPT" : op == _READ ? "_READ" : op == _WRITE ? "_WRITE" : - op == _WRITEV ? "_WRITEV" : op == _CLOSE ? "_CLOSE" : op == _CANCEL ? "_CANCEL" : op == _UPDATE ? "_UPDATE" : + op == _RECVMSG ? "_RECVMSG" : op == _CONNECT ? "_CONNECT" : "???"); } const char* getPendingOperationDescription() { return getPendingOperationDescription( U_ClientImage_op_pending(this)); } - void resetPendingOperation() + bool isPendingOperation() { - U_TRACE_NO_PARAM(0, "UClientImage_Base::resetPendingOperation()") - - U_ClientImage_op_pending(this) = 0; - } - - bool isFlagPendingOperation() - { - U_TRACE_NO_PARAM(0, "UClientImage_Base::isFlagPendingOperation()") + U_TRACE_NO_PARAM(0, "UClientImage_Base::isPendingOperation()") if (U_ClientImage_op_pending(this) != 0) U_RETURN(true); @@ -377,9 +364,19 @@ public: U_RETURN(false); } - bool isPendingOperationRead() { return isPendingOperationRead( U_ClientImage_op_pending(this)); } - bool isPendingOperationWrite() { return isPendingOperationWrite(U_ClientImage_op_pending(this)); } - bool isPendingOperationClose() { return isPendingOperationClose(U_ClientImage_op_pending(this)); } + static bool isPendingOperationCancel(char op) + { + U_TRACE(0, "UClientImage_Base::isPendingOperationCancel(%u %B)", op, op) + + if ((op & _CANCEL) != 0) U_RETURN(true); + + U_RETURN(false); + } + + bool isPendingOperationRead() { return isPendingOperationRead( U_ClientImage_op_pending(this)); } + bool isPendingOperationWrite() { return isPendingOperationWrite(U_ClientImage_op_pending(this)); } + bool isPendingOperationClose() { return isPendingOperationClose(U_ClientImage_op_pending(this)); } + bool isPendingOperationCancel() { return isPendingOperationCancel(U_ClientImage_op_pending(this)); } void setPendingOperationRead() { @@ -420,7 +417,7 @@ public: { U_ClientImage_op_pending(this) &= ~_WRITE; - if (isPendingOperationClose()) U_RETURN(true); + U_RETURN(true); } U_RETURN(false); @@ -444,6 +441,31 @@ public: U_ClientImage_op_pending(this) &= ~_CLOSE; } + void setPendingOperationCancel() + { + U_TRACE_NO_PARAM(0, "UClientImage_Base::setPendingOperationCancel()") + + U_ASSERT_EQUALS(isPendingOperationCancel(), false) + + U_ClientImage_op_pending(this) |= _CANCEL; + } + + void resetPendingOperationCancel() + { + U_TRACE_NO_PARAM(0, "UClientImage_Base::resetPendingOperationCancel()") + + U_DUMP("isPendingOperationCancel() = %b", isPendingOperationCancel()) + + U_ClientImage_op_pending(this) &= ~_CANCEL; + } + + void resetPendingOperation() + { + U_TRACE_NO_PARAM(0, "UClientImage_Base::resetPendingOperation()") + + U_ClientImage_op_pending(this) = 0; + } + // flag status processing enum FlagStatusType { @@ -707,9 +729,10 @@ protected: int sfd; uucflag flag; long last_event; - // HTTP3 +#ifdef USE_LIBURING void* conn; void* http3; +#endif bool isCallHandlerFailed(); diff --git a/include/ulib/net/server/server.h b/include/ulib/net/server/server.h index 42dd52ba..ac5ee7ea 100644 --- a/include/ulib/net/server/server.h +++ b/include/ulib/net/server/server.h @@ -28,6 +28,7 @@ #ifdef USE_LIBURING # include +//#define U_FILES_UPDATE_ASYNC_WORK #endif #ifndef SIGWINCH @@ -294,6 +295,8 @@ public: handler_other->push_back(item); } + static void addHandlerEventPoll(UEventFd* handler); + static int loadPlugins(UString& plugin_dir, const UString& plugin_list); // load plugin modules and call server-wide hooks handlerConfig()... // --------------------------------- @@ -1101,12 +1104,27 @@ protected: static int fds[1]; static int* socketfds; static UString* rBuffers; + static struct msghdr rmsg; static UStringRep* rbuffer; + static struct in_pktinfo* pi; static uint32_t rbuffer_size; static struct io_uring_sqe* sqe; static struct io_uring_cqe* cqe; static struct io_uring* io_uring; + static struct iovec vrwBuffers[3]; + static struct io_uring_probe* probe; static UVector* handler_poll; + static char cmbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; + + static void checkIfOpcodeSupported(int op, const char* descr) + { + U_TRACE(1, "UServer_Base::checkIfOpcodeSupported(%d,%S)", op, descr) + + if (U_SYSCALL(io_uring_opcode_supported, "%p,%u", probe, op) == false) + { + U_ERROR("%s not supported, kernel(%u)", descr, LINUX_VERSION_CODE) + } + } static void get_sqe() { @@ -1152,22 +1170,25 @@ protected: U_SYSCALL_VOID(io_uring_sqe_set_data, "%p,%p", sqe, (void*)(((long)nClientIndex << 32) + op)); } - static int wait_cqe() + static bool wait_cqe() { U_TRACE_NO_PARAM(1, "UServer_Base::wait_cqe()") - int ret = U_SYSCALL(io_uring_wait_cqe, "%p,%p", io_uring, &cqe); + int ret = U_SYSCALL(io_uring_submit_and_wait, "%p,%u", io_uring, 1); - if (ret) + if (ret < 0) { - if (ret == -EINTR) UInterrupt::checkForEventSignalPending(); - else + if (ret == -EINTR) { - U_ERROR("io_uring_wait_cqe() failed: %d%R", ret, 0); // NB: the last argument (0) is necessary... + UInterrupt::checkForEventSignalPending(); + + U_RETURN(false); } + + U_ERROR("io_uring_submit_and_wait() failed: %d%R", ret, 0); // NB: the last argument (0) is necessary... } - U_RETURN(ret); + U_RETURN(true); } static void register_files_update() @@ -1188,19 +1209,46 @@ protected: } } - static void prepareForAccept() + static void reset() { - U_TRACE_NO_PARAM(1, "UServer_Base::prepareForAccept()") + U_TRACE_NO_PARAM(0, "UServer_Base::reset()") - U_INTERNAL_DUMP("UNotifier::num_connection = %u UNotifier::max_connection = %u", UNotifier::num_connection, UNotifier::max_connection) + pClientImage->fd = -1; + pClientImage->flag.hi = 0; - U_INTERNAL_ASSERT_MINOR(UNotifier::num_connection, UNotifier::max_connection) + register_files_update(); + } - USocket::resetPeerAddr(); + static void prepareForCancelRead() + { + U_TRACE_NO_PARAM(1, "UServer_Base::prepareForCancelRead()") - U_SYSCALL_VOID(io_uring_prep_accept, "%p,%u,%p,%p,%u", sqe, 0, (struct sockaddr*)&USocket::peer_addr, &USocket::peer_addr_len, SOCK_CLOEXEC); + pClientImage->setPendingOperationCancel(); - nClientIndex = 0; + get_sqe(); + + U_SYSCALL_VOID(io_uring_prep_cancel, "%p,%p,%u", sqe, (void*)(((long)nClientIndex << 32) + (long)UClientImage_Base::_READ), 0); + + U_SYSCALL_VOID(io_uring_sqe_set_data, "%p,%p", sqe, (void*)(((long)nClientIndex << 32) + (long)UClientImage_Base::_CANCEL)); + + submit(); + } + + static void prepareFilesUpdate() + { + U_TRACE_NO_PARAM(1, "UServer_Base::prepareFilesUpdate()") + +# ifndef U_FILES_UPDATE_ASYNC_WORK + register_files_update(); +# else + get_sqe(); + + U_SYSCALL_VOID(io_uring_prep_files_update, "%p,%p,%u,%u", sqe, &(fds[0] = pClientImage->fd), 1, 1+nClientIndex); + + U_SYSCALL_VOID(io_uring_sqe_set_flags, "%p,%u", sqe, IOSQE_IO_LINK); // That next SQE will not be started before this one completes + + U_SYSCALL_VOID(io_uring_sqe_set_data, "%p,%p", sqe, (void*)(((long)nClientIndex << 32) + UClientImage_Base::_UPDATE)); +# endif } static void epoll_ctl_batch(UEventFd* handler) @@ -1220,8 +1268,9 @@ protected: U_SYSCALL_VOID(io_uring_prep_epoll_ctl, "%p,%d,%d,%u,%p", sqe, UNotifier::epollfd, handler->fd, EPOLL_CTL_ADD, &ev); } - static void submit(int op, ...); - static void findNextClientImage(); + static void logNewClient(); + static void findClientImage(); + static void prepareOperation(int op, ...); static void waitForEvent(UEventTime* ptimeout); static void epoll_ctl_batch(uint32_t ctl_cmd_cnt); #endif diff --git a/include/ulib/net/socket.h b/include/ulib/net/socket.h index deeab6ee..81eaef37 100644 --- a/include/ulib/net/socket.h +++ b/include/ulib/net/socket.h @@ -621,6 +621,15 @@ public: U_RETURN(false); } + void setPktInfo() + { + U_TRACE_NO_PARAM(0, "USocket::setPktInfo()") + +# ifdef IP_PKTINFO + (void) setSockOpt(IPPROTO_IP, IP_PKTINFO, (const int[]){ 1 }); +# endif + } + /** * The recvfrom() function is called with the proper parameters, params is placed for obtaining * the source address information. The number of bytes read is returned @@ -856,7 +865,30 @@ protected: peer_addr_len = sizeof(peer_addr); - (void) U_SYSCALL(memset, "%p,%d,%u", &peer_addr, 0, U_SIZE_SOCKADDR); + (void) U_SYSCALL(memset, "%p,%u,%u", &peer_addr, 0, U_SIZE_SOCKADDR); + } + + void resetPeerAddrFromLocal() + { + U_TRACE_NO_PARAM(0, "USocket::resetPeerAddrFromLocal()") + + resetPeerAddr(); + + uint32_t iAddressLength; + +# ifdef ENABLE_IPV6 + if (U_socket_IPv6(this)) iAddressLength = sizeof(in6_addr); + else +# endif + { + iAddressLength = sizeof(in_addr); + } + + char* ptr = (char*)&peer_addr; + + u_put_unalignedp16(ptr, cLocalAddress.getAddressFamily()); + + U_MEMCPY(ptr+sizeof(short), (const void*)&(cLocalAddress.pcAddress.p), iAddressLength); } /** diff --git a/include/ulib/string.h b/include/ulib/string.h index e6eaeaae..96c6b818 100644 --- a/include/ulib/string.h +++ b/include/ulib/string.h @@ -104,7 +104,6 @@ class UValue; class UString; class UBase64; class UEscape; -class UIORing; class UHexDump; class UOptions; class UTimeDate; @@ -2811,7 +2810,6 @@ private: } friend class UHTTP; - friend class UIORing; friend class USSEThread; friend class UServer_Base; friend class URDBClient_Base; @@ -2899,17 +2897,16 @@ template <> inline uint32_t UObject2String(UString& object, char* pbuff // by Victor Stewart -#if defined(U_STDCPP_ENABLE) -# if defined(HAVE_CXX11) +#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX11) namespace std { template<> struct hash { std::size_t operator()(const UString& str) const noexcept { return str.hash(); } }; } -# endif +#endif -#if defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) -# include // std::index_sequence +#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) +# include // std::index_sequence template class UCompileTimeStringView { private: @@ -3208,24 +3205,19 @@ public: } }; -# if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) && GCC_VERSION_NUM < 100100 +# if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) template -concept bool UCompileTimeStringType = requires(T string) { - is_ctv_v; -}; +concept UCompileTimeStringType = is_ctv_v; template -concept bool UStringType = requires(T string) -{ - (std::is_same_v || is_ctv_v); -}; +concept UStringType = (std::is_same_v, UString> || is_ctv_v); -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); } +inline bool operator==(const UString& lhs, const UCompileTimeStringType auto& rhs){ return lhs.equal(rhs.string); } +inline bool operator==(const UCompileTimeStringType auto& lhs, const UString& rhs){ return rhs.equal(lhs.string); } + +inline bool operator!=(const UString& lhs, const UCompileTimeStringType auto& rhs){ return !lhs.equal(rhs.string); } +inline bool operator!=(const UCompileTimeStringType auto& lhs, const UString& rhs){ return !rhs.equal(lhs.string); } -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 diff --git a/include/ulib/utility/http3.h b/include/ulib/utility/http3.h index abed15e0..0777b9c3 100644 --- a/include/ulib/utility/http3.h +++ b/include/ulib/utility/http3.h @@ -15,14 +15,20 @@ #define ULIB_HTTP3_H 1 #include -#include +#include #include +#define U_MAX_TOKEN_LEN \ + sizeof("quiche")-1 + \ + sizeof(struct sockaddr_storage) + \ + QUICHE_MAX_CONN_ID_LEN + #define U_LOCAL_CONN_ID_LEN 16 class UHTTP; class UHttpPlugIn; +class UServer_Base; class UClientImage_Base; /** @@ -54,20 +60,19 @@ public: quiche_h3_conn* http3; } conn_io; - static bool handlerRead(); - static bool handlerAccept(); static int loadConfigParam(); + static bool handlerNewConnection(); protected: static conn_io conn; - static size_t conn_id_len; + static uint8_t pkt_type; static quiche_config* qconfig; static quiche_h3_config* http3_config; static struct sockaddr_storage peer_addr; - static uint8_t conn_id[QUICHE_MAX_CONN_ID_LEN]; - static uint32_t quiche_max_packet_size, peer_addr_len; - static UHashMap* peers; + static size_t conn_id_len, scid_len, token_len; + static uint32_t pkt_version, quiche_max_packet_size, peer_addr_len; + static uint8_t token[U_MAX_TOKEN_LEN], scid[QUICHE_MAX_CONN_ID_LEN], conn_id[QUICHE_MAX_CONN_ID_LEN]; // SERVICES @@ -90,6 +95,29 @@ protected: if (http3_config) U_SYSCALL_VOID(quiche_h3_config_free, "%p", http3_config); } + static bool parseHeader(const char* data, uint32_t iBytesRead); + + // 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 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) @@ -114,6 +142,7 @@ private: friend class UHTTP; friend class Application; friend class UHttpPlugIn; + friend class UServer_Base; friend class UClientImage_Base; }; #endif diff --git a/include/ulib/utility/socket_ext.h b/include/ulib/utility/socket_ext.h index 202777a9..dbdc98e1 100644 --- a/include/ulib/utility/socket_ext.h +++ b/include/ulib/utility/socket_ext.h @@ -155,10 +155,14 @@ public: static void startResolv(const char* name, int family = AF_INET); // AF_INET6 #endif + // write data + + static uint32_t write(USocket* sk, const UString& buffer, int timeoutMS) { return write(sk, U_STRING_TO_PARAM(buffer), timeoutMS); } + static uint32_t write(USocket* sk, const char* ptr, uint32_t count, int timeoutMS); + + static bool read(USocket* sk, UString& buffer, uint32_t count = U_SINGLE_READ, int timeoutMS = -1, uint32_t time_limit = 0); // read while not received almost count data + private: - - friend class UREDISClusterMaster; - #ifdef USE_C_ARES static int resolv_status; static char resolv_hostname[INET6_ADDRSTRLEN]; @@ -178,8 +182,6 @@ private: static uint32_t byte_read, start_read; - static bool read(USocket* sk, UString& buffer, uint32_t count = U_SINGLE_READ, int timeoutMS = -1, uint32_t time_limit = 0); // read while not received almost count data - // read while received data static void readEOF(USocket* sk, UString& buffer) @@ -193,11 +195,6 @@ private: static uint32_t readWhileNotToken(USocket* sk, UString& buffer, const char* token, uint32_t token_len, int timeoutMS = -1); - // write data - - static uint32_t write(USocket* sk, const UString& buffer, int timeoutMS) { return write(sk, U_STRING_TO_PARAM(buffer), timeoutMS); } - static uint32_t write(USocket* sk, const char* ptr, uint32_t count, int timeoutMS); - // write data from multiple buffers static uint32_t iov_resize(struct iovec* liov, const struct iovec* iov, int iovcnt, uint32_t byte_written); diff --git a/src/ulib/net/client/redis.cpp b/src/ulib/net/client/redis.cpp index a9c90698..dab5104d 100644 --- a/src/ulib/net/client/redis.cpp +++ b/src/ulib/net/client/redis.cpp @@ -66,7 +66,7 @@ bool UREDISClient_Base::connect(const char* phost, unsigned int _port) UClient_Base::connect()) { init(); - + U_RETURN(true); } @@ -352,13 +352,13 @@ 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__) && GCC_VERSION_NUM < 100100 +#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX20) && defined(U_LINUX) && !defined(__clang__) -int UREDISClusterMaster::handlerRead() +int RedisSubscriber::handlerRead() { // BytesRead(100) = "*3\r\n$7\r\nmessage\r\n$19\r\n{ABC}.trafficSignal\r\n$1\r\n1\r\n*3\r\n$7\r\nmessage\r\n$19\r\n{DEF}.trafficSignal\r\n$1\r\n1\r\n" - U_TRACE_NO_PARAM(0, "UREDISClusterMaster::handlerRead()") + U_TRACE_NO_PARAM(0, "RedisSubscriber::handlerRead()") if (subscriptionString.size()) subscriptionString.setEmpty(); USocketExt::read(subscriptionSocket, subscriptionString, U_SINGLE_READ, 1000); @@ -399,28 +399,6 @@ int UREDISClusterMaster::handlerRead() U_RETURN(U_NOTIFIER_OK); } -void UREDISClusterMaster::clusterUnsubscribe(const UString& channel) // unregister the callback for messages published to the given channels -{ - U_TRACE(0, "UREDISClusterMaster::clusterUnsubscribe(%V)", channel.rep) - - if (subscriptionString.size()) subscriptionString.setEmpty(); - UCompileTimeRESPEncoder::encode<"UNSUBSCRIBE {}"_ctv>(subscriptionString, channel); - USocketExt::write(subscriptionSocket, U_STRING_TO_PARAM(subscriptionString), 1000); - (void)pchannelCallbackMap->erase(channel); -} - -void UREDISClusterMaster::clusterSubscribe(const UString& channel, vPFcscs callback) // register the callback for messages published to the given channels -{ - U_TRACE(0, "UREDISClusterMaster::clusterSubscribe(%V,%p)", channel.rep, callback) - - if (subscriptionString.size()) subscriptionString.setEmpty(); - UCompileTimeRESPEncoder::encode<"SUBSCRIBE {}"_ctv>(subscriptionString, channel); - USocketExt::write(subscriptionSocket, U_STRING_TO_PARAM(subscriptionString), 1000); - - UString channelCopy(U_STRING_TO_PARAM(channel)); - pchannelCallbackMap->insert(channelCopy, (const void*)callback); -} - void UREDISClusterMaster::cloneClusterTopology() { U_TRACE_NO_PARAM(0, "UREDISClusterMaster::cloneClusterTopology()") @@ -535,24 +513,15 @@ bool UREDISClusterMaster::connect(const UString& host, uint16_t port) { U_TRACE(0, "UREDISClusterMaster::connect(%v,%hhu)", host.rep, port) - // const UString& singleTest = single() - if (managementSocket->connectServer(host, port, 1000)) { cloneClusterTopology(); RedisClusterNode *randomNode = clusterNodes->randomElement(); - if (randomNode) + if (randomNode) { - subscriptionSocket->connectServer(randomNode->ipAddress, randomNode->port, 1000); - - U_NEW(UHashMap, pchannelCallbackMap, UHashMap()); - - this->UEventFd::fd = subscriptionSocket->getFd(); - this->UEventFd::op_mask |= EPOLLET; - UServer_Base::addHandlerEvent(this); - + RedisSubscriber::connectForSubscriptions(randomNode->ipAddress, randomNode->port); U_RETURN(true); } } diff --git a/src/ulib/net/server/client_image.cpp b/src/ulib/net/server/client_image.cpp index 13a2add5..3a548940 100644 --- a/src/ulib/net/server/client_image.cpp +++ b/src/ulib/net/server/client_image.cpp @@ -139,8 +139,10 @@ UClientImage_Base::UClientImage_Base() flag.u = 0; last_event = u_now->tv_sec; - conn = U_NULLPTR; +#ifdef USE_LIBURING + conn = http3 = U_NULLPTR; +#endif // NB: array are not pointers (virtual table can shift the address of 'this')... @@ -182,8 +184,16 @@ void UClientImage_Base::set() socket->cLocalAddress.set(UServer_Base::socket->cLocalAddress); } - socket->flags |= O_CLOEXEC; + socket->flags |= O_CLOEXEC; + +#ifdef USE_LIBURING + if (UServer_Base::brng == false) +#endif + { +#ifdef HAVE_ACCEPT4 if (USocket::accept4_flags & SOCK_NONBLOCK) socket->flags |= O_NONBLOCK; +#endif + } #ifdef DEBUG U_CHECK_MEMORY @@ -283,20 +293,15 @@ void UClientImage_Base::init() U_INTERNAL_ASSERT_EQUALS(chronometer, U_NULLPTR) #ifdef USE_LIBURING - if (UServer_Base::brng) + if (UServer_Base::brng || + UServer_Base::budp) { U_NEW_STRING(rbuffer, UString(UServer_Base::rbuffer)); } else #endif { - uint32_t sz = 8192; - -#ifdef USERVER_UDP - if (UServer_Base::budp) sz = 65535; -#endif - - U_NEW_STRING(rbuffer, UString(sz)); + U_NEW_STRING(rbuffer, UString(8192)); } U_NEW_STRING(body, UString); @@ -608,12 +613,7 @@ void UClientImage_Base::handlerDelete() if (data_pending) { -# ifdef USE_LIBURING - if (UServer_Base::brng == false) -# endif - { U_DELETE(data_pending) - } data_pending = U_NULLPTR; } @@ -642,15 +642,29 @@ void UClientImage_Base::handlerDelete() reset(); } +#ifdef USE_LIBURING + if (UServer_Base::brng) + { + flag.lo = 0; + + resetPendingOperationClose(); + } + else +#endif + { flag.u = 0; UEventFd::fd = -1; +#ifdef HAVE_ACCEPT4 + U_INTERNAL_ASSERT_EQUALS(((USocket::accept4_flags & SOCK_NONBLOCK) != 0),((socket->flags & O_NONBLOCK) != 0)) +#endif + } + U_INTERNAL_ASSERT_EQUALS(data_pending, U_NULLPTR) U_INTERNAL_ASSERT_EQUALS(UEventFd::op_mask, EPOLLIN | EPOLLRDHUP | EPOLLET) #ifdef HAVE_ACCEPT4 - U_INTERNAL_ASSERT_EQUALS(((USocket::accept4_flags & SOCK_CLOEXEC) != 0),((socket->flags & O_CLOEXEC) != 0)) - U_INTERNAL_ASSERT_EQUALS(((USocket::accept4_flags & SOCK_NONBLOCK) != 0),((socket->flags & O_NONBLOCK) != 0)) + U_INTERNAL_ASSERT_EQUALS(((USocket::accept4_flags & SOCK_CLOEXEC) != 0),((socket->flags & O_CLOEXEC) != 0)) #endif #ifdef USE_LIBEVENT @@ -1156,7 +1170,9 @@ bool UClientImage_Base::genericRead() #endif #ifdef USE_LIBURING - if (UServer_Base::brng == false) + if (UServer_Base::brng == false || + (U_ClientImage_request == 0 && + U_ClientImage_parallelization == U_PARALLELIZATION_CHILD)) #endif { // NB: rbuffer string can be referenced more than one (often if U_SUBSTR_INC_REF is defined)... @@ -1236,7 +1252,7 @@ uint32_t UClientImage_Base::writev(struct iovec* iov, int iovcnt, uint32_t _coun { U_DUMP_IOVEC(iov,iovcnt) - UServer_Base::submit(_WRITEV, iov, iovcnt, 0); // this queues a writev() + UServer_Base::prepareOperation(_WRITE, iov, iovcnt, 0); U_RETURN(_count); } @@ -1280,8 +1296,6 @@ start: if (genericRead() == false) { - U_INTERNAL_ASSERT_EQUALS(UServer_Base::brng, false) - if (U_ClientImage_state == U_PLUGIN_HANDLER_AGAIN && U_ClientImage_parallelization != U_PARALLELIZATION_CHILD) { @@ -2056,7 +2070,10 @@ void UClientImage_Base::abortive_close() if (U_ClientImage_pipeline) resetPipeline(); - if (UServer_Base::csocket->isOpen()) UServer_Base::csocket->abortive_close(); + if (UServer_Base::csocket->isOpen()) + { + UServer_Base::csocket->abortive_close(); + } } void UClientImage_Base::resetPipeline() diff --git a/src/ulib/net/server/server.cpp b/src/ulib/net/server/server.cpp index 64a81e88..7a7b865f 100644 --- a/src/ulib/net/server/server.cpp +++ b/src/ulib/net/server/server.cpp @@ -213,19 +213,26 @@ UVector* UServer_Base::vallow_IP_prv; # ifndef IOSQE_BUFFER_SELECT # define IOSQE_BUFFER_SELECT (1U << 5) // select buffer from sqe->buf_group # endif +# ifndef IORING_FEAT_FAST_POLL +# define IORING_FEAT_FAST_POLL (1U << 5) +# endif //#define U_FILES_UPDATE_ASYNC_WORK - # include -int UServer_Base::fds[1]; +int UServer_Base::fds[1] = { -1 }; int* UServer_Base::socketfds; +char UServer_Base::cmbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; uint32_t UServer_Base::rbuffer_size = 65535; UString* UServer_Base::rBuffers; UStringRep* UServer_Base::rbuffer; +struct iovec UServer_Base::vrwBuffers[3]; +struct msghdr UServer_Base::rmsg; struct io_uring* UServer_Base::io_uring; +struct in_pktinfo* UServer_Base::pi; UVector* UServer_Base::handler_poll; struct io_uring_sqe* UServer_Base::sqe; struct io_uring_cqe* UServer_Base::cqe; +struct io_uring_probe* UServer_Base::probe; #endif //#define U_MAX_CONNECTIONS_ACCEPTED_SIMULTANEOUSLY 1 @@ -363,16 +370,16 @@ public: { UServer_Base::pClientImage = UServer_Base::vClientImage; - for (uint32_t num_close = 0; UServer_Base::pClientImage < UServer_Base::eClientImage; ++UServer_Base::pClientImage) + for (uint32_t num_close = 0, num_connection = UNotifier::num_connection; UServer_Base::pClientImage < UServer_Base::eClientImage; ++UServer_Base::pClientImage) { if (UServer_Base::pClientImage->UEventFd::fd != -1 && UServer_Base::isReqTimeout(UServer_Base::pClientImage)) { (void) UServer_Base::handlerTimeoutConnection(UServer_Base::pClientImage); - U_INTERNAL_DUMP("num_close = %u", num_close+1) + U_INTERNAL_DUMP("num_close = %u num_connection = %u", num_close+1, num_connection) - if (++num_close == UNotifier::num_connection) break; + if (++num_close == num_connection) break; } } } @@ -1623,7 +1630,7 @@ public: { // int rfd = fd; - fd = (U_FF_SYSCALL(recvmsg, "%u,%p,%u", UServer_Base::sse_socketpair[0], &UServer_Base::msg, 0) == 1 ? UServer_Base::cmsg.cmsg_data : -1); + fd = (U_FF_SYSCALL(recvmsg, "%u,%p,%u", UServer_Base::sse_socketpair[0], &UServer_Base::msg, MSG_CMSG_CLOEXEC) == 1 ? UServer_Base::cmsg.cmsg_data : -1); U_INTERNAL_DUMP("fd = %d", fd) @@ -1921,6 +1928,27 @@ UServer_Base::~UServer_Base() UClientImage_Base::clear(); #ifdef USERVER_RNG + if (io_uring) + { + U_SYSCALL_VOID(io_uring_queue_exit, "%p", io_uring); + + U_FREE_TYPE(io_uring, struct io_uring); + + U_SYSCALL_VOID(free, "%p", probe); + + if (brng || + budp) + { + U_DELETE(rBuffers); + + handler_poll->_length = 0; + + U_DELETE(handler_poll); + } + + if (socketfds) UMemoryPool::_free(socketfds, 1+UNotifier::max_connection, sizeof(int)); + } + if (rbuffer) { U_ASSERT_EQUALS(rbuffer->capacity(), rbuffer_size) @@ -1930,24 +1958,6 @@ UServer_Base::~UServer_Base() rbuffer->_release(); } - - if (io_uring) - { - U_SYSCALL_VOID(io_uring_queue_exit, "%p", io_uring); - - U_FREE_TYPE(io_uring, struct io_uring); - - if (socketfds) - { - U_DELETE(rBuffers); - - handler_poll->_length = 0; - - U_DELETE(handler_poll); - - UMemoryPool::_free(socketfds, 1+UNotifier::max_connection, sizeof(int)); - } - } #endif U_INTERNAL_ASSERT_POINTER(socket) @@ -2400,7 +2410,8 @@ void UServer_Base::loadConfigParam() preforked_num_kids = 2; # elif defined(USERVER_RNG) - if (brng) + if (brng || + budp) { U_WARNING("Sorry, I was compiled with io_uring support so I can't accept PREFORK_CHILD = 1"); @@ -2594,12 +2605,12 @@ void UServer_Base::loadConfigParam() U_DEBUG("We have %s the PID_FILE %V with content: %P", (old_pid > 0 ? "updated" : "created"), x.rep); } -#if defined(USE_LOAD_BALANCE) && !defined(U_DISABLE_WATCH_THREAD) -# if defined(USERVER_UDP) || defined(USERVER_IPC) +#if defined(USERVER_UDP) || defined(USERVER_IPC) if (budp == false && bipc == false) -# endif +#endif { +#if defined(USE_LOAD_BALANCE) && !defined(U_DISABLE_WATCH_THREAD) x = pcfg->at(U_CONSTANT_TO_PARAM("LOAD_BALANCE_DEVICE_NETWORK")); if (x) @@ -2630,15 +2641,15 @@ void UServer_Base::loadConfigParam() vallow_cluster = U_NULLPTR; } } - } #endif + } -#if defined(U_EVASIVE_SUPPORT) && !defined(U_DISABLE_WATCH_THREAD) -# if defined(USERVER_UDP) || defined(USERVER_IPC) +#if defined(USERVER_UDP) || defined(USERVER_IPC) if (budp == false && bipc == false) -# endif +#endif { +#if defined(U_EVASIVE_SUPPORT) && !defined(U_DISABLE_WATCH_THREAD) /** * This is the threshold for the number of requests for the same page (or URI) per page interval. * Once the threshold for that interval has been exceeded (defaults to 2), the IP address of the client will be added to the blocking list @@ -2737,8 +2748,8 @@ void UServer_Base::loadConfigParam() U_NEW(UFile, dos_LOG, UFile(x)); } - } #endif + } // load ORM driver modules... @@ -3412,7 +3423,8 @@ next: UTimer::init(UTimer::NOSIGNAL); #ifdef USERVER_RNG - if (UServer_Base::brng) + if (brng || + budp) { U_NEW(UStringRep, rbuffer, UStringRep(rbuffer_size, U_NULLPTR)); } @@ -3597,9 +3609,10 @@ next: isClassic() == false) { # ifdef USERVER_RNG - U_INTERNAL_DUMP("brng = %b socket_flags = %u %B", brng, socket_flags, socket_flags) + U_INTERNAL_DUMP("brng = %b budp = %b socket_flags = %u %B", brng, budp, socket_flags, socket_flags) - if (brng) + if (brng || + budp) { U_INTERNAL_ASSERT_EQUALS(socket_flags & O_NONBLOCK, 0) } @@ -3631,7 +3644,8 @@ next: } #ifdef USERVER_RNG - if (brng == false) + if (brng == false && + budp == false) #endif { if (handler_inotify) @@ -3676,27 +3690,27 @@ next: U_ERROR("System date not updated"); } -#ifdef U_THROTTLING_SUPPORT -# ifdef USERVER_UDP +#ifdef USERVER_UDP if (budp == false) -# endif +#endif +#if defined(U_THROTTLING_SUPPORT) && !defined(U_DISABLE_WATCH_THREAD) if (throttling_mask) initThrottlingServer(); #endif -#if defined(U_EVASIVE_SUPPORT) && !defined(U_DISABLE_WATCH_THREAD) -# if defined(USERVER_UDP) || defined(USERVER_IPC) +#if defined(USERVER_UDP) || defined(USERVER_IPC) if (budp == false && bipc == false) -# endif +#endif +#if defined(U_EVASIVE_SUPPORT) && !defined(U_DISABLE_WATCH_THREAD) initEvasive(); #endif -#if defined(U_SSE_ENABLE) && !defined(U_DISABLE_WATCH_THREAD) // SERVER SENT EVENTS (SSE) -# if defined(USERVER_UDP) || defined(USERVER_IPC) +#if defined(USERVER_UDP) || defined(USERVER_IPC) if (budp == false && bipc == false) -# endif +#endif { +#if defined(U_SSE_ENABLE) && !defined(U_DISABLE_WATCH_THREAD) // SERVER SENT EVENTS (SSE) sse_fifo_pos = u__snprintf(sse_fifo_name, 256, U_CONSTANT_TO_PARAM("%s/SSE_%s_EVENT"), u_tmpdir, bssl ? "SSL" : "TCP") - U_CONSTANT_SIZE("EVENT"); (void) UFile::mkfifo(sse_fifo_name, PERM_FILE); @@ -3724,8 +3738,8 @@ next: (void) U_SYSCALL(socketpair, "%d,%d,%d,%p", AF_UNIX, SOCK_STREAM, 0, sse_socketpair); U_INTERNAL_DUMP("sse_socketpair[0] = %u sse_socketpair[1] = %u", sse_socketpair[0], sse_socketpair[1]) - } #endif + } if (pcfg) pcfg->clear(); @@ -4159,21 +4173,6 @@ int UServer_Base::handlerRead() uint32_t ctl_cmd_cnt = 0; #endif -#ifndef U_HTTP3_DISABLE - if (budp) - { -hretry: - if (UHTTP3::handlerRead() == false) U_RETURN(U_NOTIFIER_OK); - - if (pClientImage) - { - U_INTERNAL_DUMP("pClientImage->conn = %p pClientImage->http3", pClientImage->conn, pClientImage->http3) - - goto try_accept; - } - } -#endif - // This loops until the accept() fails, trying to start new connections as fast as possible so we don't overrun the listen queue U_INTERNAL_DUMP("pClientImage = %p vClientImage = %p nClientIndex = %u", pClientImage, vClientImage, nClientIndex) @@ -4285,19 +4284,6 @@ try_next: try_accept: U_INTERNAL_ASSERT_DIFFERS(U_ClientImage_parallelization, U_PARALLELIZATION_CHILD) -#ifndef U_HTTP3_DISABLE - if (budp) - { - if (UHTTP3::handlerAccept() == false) goto hretry; - - U_INTERNAL_DUMP("pClientImage->conn = %p pClientImage->http3", pClientImage->conn, pClientImage->http3) - - U_INTERNAL_ASSERT_POINTER(pClientImage->conn) - - // goto hnext; - } -#endif - U_INTERNAL_ASSERT(CSOCKET->isClosed()) if (socket->acceptClient(CSOCKET) == false) @@ -4568,7 +4554,7 @@ bool UServer_Base::handlerTimeoutConnection(void* cimg) U_INTERNAL_ASSERT_MINOR(nClientIndex, UNotifier::max_connection) - submit(UClientImage_Base::_CLOSE); // this queues a close() + prepareOperation(UClientImage_Base::_CLOSE); logReqTimeout(cimg, last_event); @@ -4602,25 +4588,21 @@ void UServer_Base::epoll_ctl_batch(uint32_t ctl_cmd_cnt) U_INTERNAL_ASSERT_MAJOR(ctl_cmd_cnt, 0) - uint32_t head, count = 0; - int ret = U_SYSCALL(io_uring_submit_and_wait, "%p,%u", io_uring, ctl_cmd_cnt); + (void) U_SYSCALL(io_uring_submit_and_wait, "%p,%u", io_uring, ctl_cmd_cnt); - if (ret == -1) - { - U_ERROR("io_uring_submit_and_wait() failed: %d%R", ret, 0); // NB: the last argument (0) is necessary... - } + uint32_t head, count = 0; do { io_uring_for_each_cqe(io_uring, head, cqe) { + ++count; + if (UNLIKELY(cqe->res < 0)) { u_errno = -cqe->res; U_WARNING("epoll_ctl got %d%R", cqe->res, 0); // NB: the last argument (0) is necessary... } - - ++count; } U_INTERNAL_ASSERT(count <= ctl_cmd_cnt) @@ -4630,18 +4612,60 @@ void UServer_Base::epoll_ctl_batch(uint32_t ctl_cmd_cnt) while (count != ctl_cmd_cnt); } -void UServer_Base::submit(int op, ...) +void UServer_Base::prepareOperation(int op, ...) { - U_TRACE(1, "UServer_Base::submit(%d)", op) + U_TRACE(1, "UServer_Base::prepareOperation(%d)", op) - int flags = 0; + U_INTERNAL_DUMP("op = %s", UClientImage_Base::getPendingOperationDescription(op)) - va_list argp; - va_start(argp, op); - - if (op == UClientImage_Base::_POLL) + if (op == UClientImage_Base::_ACCEPT) { - UEventFd* handler = va_arg(argp, UEventFd*); +accept: + U_INTERNAL_DUMP("UNotifier::num_connection = %u UNotifier::max_connection = %u", UNotifier::num_connection, UNotifier::max_connection) + + U_INTERNAL_ASSERT_MINOR(UNotifier::num_connection, UNotifier::max_connection) + + USocket::resetPeerAddr(); + + get_sqe(); + + U_SYSCALL_VOID(io_uring_prep_accept, "%p,%u,%p,%p,%u", sqe, 0, (struct sockaddr*)&USocket::peer_addr, &USocket::peer_addr_len, SOCK_CLOEXEC); + + // IOSQE_FIXED_FILE -> signals that we pass an index into socketfds rather than a file descriptor + + U_SYSCALL_VOID(io_uring_sqe_set_flags, "%p,%u", sqe, IOSQE_ASYNC | IOSQE_FIXED_FILE); + + U_SYSCALL_VOID(io_uring_sqe_set_data, "%p,%p", sqe, (void*)UClientImage_Base::_ACCEPT); + } + else if (op == UClientImage_Base::_RECVMSG) + { + USocket::resetPeerAddr(); + + rmsg.msg_namelen = USocket::peer_addr_len; + + U_INTERNAL_ASSERT_EQUALS(rmsg.msg_flags, 0) + U_INTERNAL_ASSERT_EQUALS(rmsg.msg_name, &USocket::peer_addr) + + get_sqe(); + + U_SYSCALL_VOID(io_uring_prep_recvmsg, "%p,%u,%p,%u", sqe, 0, &rmsg, 0); + + // IOSQE_FIXED_FILE -> signals that we pass an index into socketfds rather than a file descriptor + + U_SYSCALL_VOID(io_uring_sqe_set_flags, "%p,%u", sqe, IOSQE_ASYNC | IOSQE_FIXED_FILE); + + U_SYSCALL_VOID(io_uring_sqe_set_data, "%p,%p", sqe, (void*)UClientImage_Base::_RECVMSG); + } + else if (op == UClientImage_Base::_POLL) + { + UEventFd* handler; + + va_list argp; + va_start(argp, op); + + handler = va_arg(argp, UEventFd*); + + U_INTERNAL_ASSERT_POINTER(handler) uint32_t nHandlerIndex = handler_poll->size(); @@ -4653,198 +4677,158 @@ void UServer_Base::submit(int op, ...) U_SYSCALL_VOID(io_uring_sqe_set_data, "%p,%p", sqe, (void*)(((long)nHandlerIndex << 32) + (long)UClientImage_Base::_POLL)); - goto submit; + va_end(argp); } - - if (op == UClientImage_Base::_ACCEPT) + else { - get_sqe(); + // ...fd member is the index of the file in the file descriptor array - prepareForAccept(); + U_INTERNAL_DUMP("socketfds[%u] = %d pClientImage->fd = %d", 1+nClientIndex, socketfds[1+nClientIndex], pClientImage->fd) - goto set; - } + U_INTERNAL_ASSERT_EQUALS(pClientImage, vClientImage+nClientIndex) - // ...fd member is the index of the file in the file descriptor array + char* ptr; + uint32_t sz; - U_INTERNAL_DUMP("op = %s socketfds[%u] = %d pClientImage->fd = %d", UClientImage_Base::getPendingOperationDescription(op), 1+nClientIndex, socketfds[1+nClientIndex], pClientImage->fd) + if (pClientImage->isPendingOperationClose()) return; - U_INTERNAL_ASSERT_EQUALS(pClientImage, vClientImage+nClientIndex) - - if (pClientImage->isPendingOperationClose()) goto end; - - if (op == UClientImage_Base::_CLOSE) - { - pClientImage->setPendingOperationClose(); - - if (pClientImage->isPendingOperationWrite() == false) + if (op == UClientImage_Base::_READ) { + pClientImage->setPendingOperationRead(); + + uint32_t start; + + sz = (long)pClientImage->data_pending; + ptr = rBuffers->c_pointer(start = nClientIndex * rbuffer_size); + get_sqe(); - U_SYSCALL_VOID(io_uring_prep_close, "%p,%u", sqe, pClientImage->fd); + if (sz == 0) + { + U_SYSCALL_VOID(io_uring_prep_read_fixed, "%p,%u,%p,%u,%u,%u", sqe, 1+nClientIndex, ptr, rbuffer_size, 0, 0); + } + else + { + U_INTERNAL_DUMP("pClientImage->data_pending(%u) = %V", sz, UClientImage_Base::rbuffer->rep) - U_SYSCALL_VOID(io_uring_sqe_set_data, "%p,%p", sqe, (void*)(((long)nClientIndex << 32) + (long)UClientImage_Base::_CLOSE)); + if (UClientImage_Base::rbuffer->same(rbuffer) == false) + { + U_MEMCPY(ptr, UClientImage_Base::rbuffer->data(), sz); - if (pClientImage->isPendingOperationRead()) + UClientImage_Base::resetReadBuffer(rbuffer); + + U_ASSERT_EQUALS(UClientImage_Base::rbuffer->capacity(), rbuffer_size) + } + + U_SYSCALL_VOID(io_uring_prep_read_fixed, "%p,%u,%p,%u,%u,%u", sqe, 1+nClientIndex, ptr + sz, rbuffer_size - sz, 0, 0); + } + + setOperation(UClientImage_Base::_READ); + } + else if (op == UClientImage_Base::_WRITE) + { + pClientImage->setPendingOperationWrite(); + + uint32_t buf; + int flags = 0; + + va_list argp; + va_start(argp, op); + + ptr = va_arg(argp, char*); + sz = va_arg(argp, uint32_t); + buf = va_arg(argp, uint32_t); + + get_sqe(); + + U_SYSCALL_VOID(io_uring_prep_writev, "%p,%u,%p,%u,%u", sqe, 1+nClientIndex, (const iovec*)ptr, sz, 0); + + if (buf) + { + flags = IOSQE_BUFFER_SELECT; + sqe->buf_group = buf; + } + + U_INTERNAL_DUMP("U_ClientImage_close = %b U_ClientImage_pipeline = %b", U_ClientImage_close, U_ClientImage_pipeline) + + if (U_ClientImage_close && + U_ClientImage_pipeline == false) + { + U_DUMP("UServer_Base::isParallelizationChild() = %b", UServer_Base::isParallelizationChild()) + + U_INTERNAL_ASSERT_DIFFERS(U_ClientImage_parallelization, U_PARALLELIZATION_CHILD) + + setOperation(UClientImage_Base::_WRITE, flags | IOSQE_IO_LINK); // That next SQE (CLOSE) will not be started before this one completes + + pClientImage->setPendingOperationClose(); + + get_sqe(); + + U_SYSCALL_VOID(io_uring_prep_close, "%p,%u", sqe, pClientImage->fd); + + U_SYSCALL_VOID(io_uring_sqe_set_data, "%p,%p", sqe, (void*)(((long)nClientIndex << 32) + (long)UClientImage_Base::_CLOSE)); + } + else + { + setOperation(UClientImage_Base::_WRITE, flags); + } + + va_end(argp); + + if (U_ClientImage_pipeline) submit(); + } + else if (op == UClientImage_Base::_CLOSE) + { + pClientImage->setPendingOperationClose(); + + if (pClientImage->isPendingOperationWrite() == false) { get_sqe(); - U_SYSCALL_VOID(io_uring_prep_cancel, "%p,%p,%u", sqe, (void*)(((long)nClientIndex << 32) + (long)UClientImage_Base::_READ), 0); + U_SYSCALL_VOID(io_uring_prep_close, "%p,%u", sqe, pClientImage->fd); - U_SYSCALL_VOID(io_uring_sqe_set_data, "%p,%p", sqe, (void*)(((long)nClientIndex << 32) + (long)UClientImage_Base::_CANCEL)); + U_SYSCALL_VOID(io_uring_sqe_set_data, "%p,%p", sqe, (void*)(((long)nClientIndex << 32) + (long)UClientImage_Base::_CLOSE)); + + if (pClientImage->isPendingOperationRead()) prepareForCancelRead(); } - - goto submit; - } - - goto end; - } - - if (op == UClientImage_Base::_READ) - { - pClientImage->setPendingOperationRead(); - - uint32_t start, sz = (long)pClientImage->data_pending; - char* ptr = rBuffers->c_pointer(start = nClientIndex * rbuffer_size); - - get_sqe(); - - if (sz == 0) - { - U_SYSCALL_VOID(io_uring_prep_read_fixed, "%p,%u,%p,%u,%u,%u", sqe, 1+nClientIndex, ptr, rbuffer_size, 0, 0); } else { - U_INTERNAL_DUMP("pClientImage->data_pending(%u) = %V", sz, UClientImage_Base::rbuffer->rep) + U_INTERNAL_ASSERT_EQUALS(op, UClientImage_Base::_CONNECT) - if (UClientImage_Base::rbuffer->same(rbuffer) == false) +# ifndef U_LOG_DISABLE + logNewClient(pClientImage->fd); +# endif + + prepareFilesUpdate(); + +# ifdef U_WELCOME_SUPPORT + if (msg_welcome) { - U_MEMCPY(ptr, UClientImage_Base::rbuffer->data(), sz); + pClientImage->setPendingOperationWrite(); - UClientImage_Base::resetReadBuffer(rbuffer); + get_sqe(); - U_ASSERT_EQUALS(UClientImage_Base::rbuffer->capacity(), rbuffer_size) + U_SYSCALL_VOID(io_uring_prep_write_fixed, "%p,%u,%p,%u,%u,%u", sqe, 1+nClientIndex, U_STRING_TO_PARAM(*msg_welcome), 0, 1); + + setOperation(UClientImage_Base::_WRITE); } - - U_SYSCALL_VOID(io_uring_prep_read_fixed, "%p,%u,%p,%u,%u,%u", sqe, 1+nClientIndex, ptr + sz, rbuffer_size - sz, 0, 0); - } - - goto set; - } - - if (op != UClientImage_Base::_CONNECT) - { - void* ptr = va_arg(argp, void*); - uint32_t sz = va_arg(argp, uint32_t), - buf = va_arg(argp, uint32_t); - - pClientImage->setPendingOperationWrite(); - - get_sqe(); - - if (op == UClientImage_Base::_WRITE) - { - U_SYSCALL_VOID(io_uring_prep_write_fixed, "%p,%u,%p,%u,%u,%u", sqe, 1+nClientIndex, ptr, sz, 0, buf); - - goto set; - } - - U_INTERNAL_ASSERT_EQUALS(op, UClientImage_Base::_WRITEV) - - U_SYSCALL_VOID(io_uring_prep_writev, "%p,%u,%p,%u,%u", sqe, 1+nClientIndex, (const iovec*)ptr, sz, 0); - - if (buf) - { - flags = IOSQE_BUFFER_SELECT; - sqe->buf_group = buf; - } - - U_INTERNAL_DUMP("U_ClientImage_close = %b U_ClientImage_pipeline = %b", U_ClientImage_close, U_ClientImage_pipeline) - - if (U_ClientImage_close && - U_ClientImage_pipeline == false) - { - U_DUMP("UServer_Base::isParallelizationChild() = %b", UServer_Base::isParallelizationChild()) - - U_INTERNAL_ASSERT_DIFFERS(U_ClientImage_parallelization, U_PARALLELIZATION_CHILD) - - setOperation(UClientImage_Base::_WRITEV, flags | IOSQE_IO_LINK); // That next SQE (CLOSE) will not be started before this one completes - - pClientImage->setPendingOperationClose(); +# endif get_sqe(); - U_SYSCALL_VOID(io_uring_prep_close, "%p,%u", sqe, pClientImage->fd); + U_SYSCALL_VOID(io_uring_prep_read_fixed, "%p,%u,%p,%u,%u,%u", sqe, 1+nClientIndex, rBuffers->c_pointer(nClientIndex * rbuffer_size), rbuffer_size, 0, 0); - U_SYSCALL_VOID(io_uring_sqe_set_data, "%p,%p", sqe, (void*)(((long)nClientIndex << 32) + (long)UClientImage_Base::_CLOSE)); + setOperation(UClientImage_Base::_READ); - goto submit; + if (UNotifier::num_connection < UNotifier::max_connection) goto accept; } - - goto set; } - - U_INTERNAL_ASSERT_EQUALS(op, UClientImage_Base::_CONNECT) - -#ifndef U_LOG_DISABLE - logNewClient(pClientImage->fd); -#endif - -#ifndef U_FILES_UPDATE_ASYNC_WORK - register_files_update(); -#else - get_sqe(); - - U_SYSCALL_VOID(io_uring_prep_files_update, "%p,%p,%u,%u", sqe, &(fds[0] = pClientImage->fd), 1, 1+nClientIndex); - - U_SYSCALL_VOID(io_uring_sqe_set_flags, "%p,%u", sqe, IOSQE_IO_LINK); // That next SQE will not be started before this one completes - - U_SYSCALL_VOID(io_uring_sqe_set_data, "%p,%p", sqe, (void*)(((long)nClientIndex << 32) + UClientImage_Base::_UPDATE)); -#endif - -#ifdef U_WELCOME_SUPPORT - if (msg_welcome) - { - pClientImage->setPendingOperationWrite(); - - get_sqe(); - - U_SYSCALL_VOID(io_uring_prep_write_fixed, "%p,%u,%p,%u,%u,%u", sqe, 1+nClientIndex, U_STRING_TO_PARAM(*msg_welcome), 0, 1); - - setOperation(UClientImage_Base::_WRITE); - } -#endif - - get_sqe(); - - U_SYSCALL_VOID(io_uring_prep_read_fixed, "%p,%u,%p,%u,%u,%u", sqe, 1+nClientIndex, rBuffers->c_pointer(nClientIndex * rbuffer_size), rbuffer_size, 0, 0); - - setOperation(UClientImage_Base::_READ); - - if (UNotifier::num_connection < UNotifier::max_connection) - { - get_sqe(); - - prepareForAccept(); - - setOperation(UClientImage_Base::_ACCEPT); - } - - goto submit; - -set: - setOperation(op, flags); - -submit: - submit(); - -end: - va_end(argp); } -void UServer_Base::findNextClientImage() +void UServer_Base::findClientImage() { - U_TRACE_NO_PARAM(0, "UServer_Base::findNextClientImage()") + U_TRACE_NO_PARAM(0, "UServer_Base::findClientImage()") pClientImage = vClientImage + UNotifier::num_connection; @@ -4914,7 +4898,92 @@ void UServer_Base::waitForEvent(UEventTime* ptimeout) U_ERROR("io_uring_wait_cqe_timeout() failed: %d%R", ret, 0); // NB: the last argument (0) is necessary... } } + +void UServer_Base::logNewClient() +{ + U_TRACE_NO_PARAM(0, "UServer_Base::logNewClient()") + + U_INTERNAL_DUMP("rmsg.msg_namelen = %u rmsg.msg_flags = %u %B", rmsg.msg_namelen, rmsg.msg_flags, rmsg.msg_flags) + + if ((rmsg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) != 0) + { + U_WARNING("recvmsg() truncated data"); + + rmsg.msg_flags = 0; + } + + U_INTERNAL_ASSERT_EQUALS(rmsg.msg_name, &USocket::peer_addr) + + /** + for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&rmsg); cmsg; cmsg = CMSG_NXTHDR(&rmsg, cmsg)) // iterate through all the control headers + { + // ignore the control headers that don't match what we want + if (cmsg->cmsg_level != IPPROTO_IP || + cmsg->cmsg_type != IP_PKTINFO) + { + continue; + } + + // struct in_pktinfo { + // unsigned int ipi_ifindex; // Interface index + // struct in_addr ipi_spec_dst; // Local address + // struct in_addr ipi_addr; // Header Destination address + // }; + + pi = (struct in_pktinfo*) CMSG_DATA(cmsg); + + // pi->ipi_spec_dst is the destination in_addr + // pi->ipi_addr is the receiving interface in_addr + + ((struct sockaddr_in*)&USocket::peer_addr)->sin_addr = pi->ipi_addr; + } + */ + + USocket::peer_addr_len = rmsg.msg_namelen; + + (csocket = socket)->setRemoteAddressAndPort(); + + setClientAddress(); + + U_DUMP("UHTTP3::conn_id = %M", UHTTP3::conn_id, UHTTP3::conn_id_len) + +#ifndef U_LOG_DISABLE + if (isLog()) + { + char buffer[32]; + uint32_t len = setNumConnection(buffer), + sz = u__snprintf(u_buffer, U_BUFFER_SIZE, U_CONSTANT_TO_PARAM("'%s:%u'"), csocket->cRemoteAddress.pcStrAddress, csocket->iRemotePort); + + log->log(U_CONSTANT_TO_PARAM("New client connected from %.*s, %.*s clients currently connected"), sz, u_buffer, len, buffer); + } #endif +} +#endif + +void UServer_Base::addHandlerEventPoll(UEventFd* handler) +{ + U_TRACE(0, "UServer_Base::addHandlerEventPoll(%p)", handler) + +#ifndef U_SERVER_CAPTIVE_PORTAL + if (handler) + { + U_INTERNAL_DUMP("handler->UEventFd::fd = %d", handler->UEventFd::fd) + + U_INTERNAL_ASSERT_DIFFERS(handler->UEventFd::fd, -1) + +# ifdef USERVER_RNG + if (brng) prepareOperation(UClientImage_Base::_POLL, handler); + else +# endif + { + UNotifier::min_connection++; + + handler->UEventFd::op_mask |= EPOLLET; + handler->UEventFd::op_mask &= ~EPOLLRDHUP; + } + } +#endif +} void UServer_Base::runLoop(const char* user) { @@ -4973,6 +5042,12 @@ void UServer_Base::runLoop(const char* user) # endif } + /* +#ifdef DEBUG + socket->dumpProperties(); +#endif + */ + # ifdef USE_LIBURING int ret; struct io_uring_params params; @@ -4985,29 +5060,37 @@ void UServer_Base::runLoop(const char* user) * * as soon as we stop generating submission queue entries, a timer starts that will put the kernel side polling thread to sleep, as long as we keep driving IO, the kernel * thread will always stay active... otherwise it will set IORING_SQ_NEED_WAKEUP bit in the flags field of the struct io_sq_ring and you have to call enter to wake it up - -# if LINUX_VERSION_CODE <= KERNEL_VERSION(5,10,0) // maybe... ??? - if (brng == false) -# endif - { - if (UServices::isSetuidRoot()) - { - params.flags = IORING_SETUP_SQPOLL; - params.sq_thread_idle = SQ_THREAD_IDLE; // UINT32_MAX tell the kernel to never stop polling - - if (baffinity) // Pin kernel submission polling thread to same CPU - { - params.flags |= IORING_SETUP_SQ_AFF; - params.sq_thread_cpu = rkids % u_num_cpu; - } - } - } */ - io_uring = U_MALLOC_TYPE(struct io_uring); + if (budp) + { + // socket->setPktInfo(); + + fds[0] = socket->iSockDesc; + + rmsg.msg_name = &USocket::peer_addr; + rmsg.msg_iov = vrwBuffers; + rmsg.msg_iovlen = 1; + // rmsg.msg_control = cmbuf; + // rmsg.msg_controllen = sizeof(cmbuf); + + if (UServices::isSetuidRoot()) + { + params.flags = IORING_SETUP_SQPOLL; + params.sq_thread_idle = SQ_THREAD_IDLE; // UINT32_MAX tell the kernel to never stop polling + + if (baffinity) // Pin kernel submission polling thread to same CPU + { + params.flags |= IORING_SETUP_SQ_AFF; + params.sq_thread_cpu = rkids % u_num_cpu; + } + } + } U_INTERNAL_DUMP("params.sq_thread_cpu = %u params.flags = %u %B", params.sq_thread_cpu, params.flags, params.flags) + io_uring = U_MALLOC_TYPE(struct io_uring); + ret = U_SYSCALL(io_uring_queue_init_params, "%u,%p,%p", UNotifier::max_connection * 3, io_uring, ¶ms); if (ret) @@ -5015,53 +5098,146 @@ void UServer_Base::runLoop(const char* user) U_ERROR("io_uring_queue_init_params() failed: %d%R", ret, 0); // NB: the last argument (0) is necessary... } - if (brng) + probe = (struct io_uring_probe*) U_SYSCALL(io_uring_get_probe_ring, "%p", io_uring); + + if (probe == U_NULLPTR) { + U_ERROR("Failed getting probe data, kernel(%u)", LINUX_VERSION_CODE) + } + + /** check a few ops that must be supported + * + * IORING_OP_SPLICE + * IORING_OP_READV + * IORING_OP_READ_FIXED + * IORING_OP_WRITEV + * IORING_OP_WRITE_FIXED + * IORING_OP_RECVMSG + * IORING_OP_SENDMSG + * IORING_OP_POLL_ADD + * IORING_OP_POLL_REMOVE + * IORING_OP_FSYNC + * IORING_OP_NOP + * IORING_OP_TIMEOUT + * IORING_OP_TIMEOUT_REMOVE + * IORING_OP_ACCEPT + * IORING_OP_ASYNC_CANCEL + * IORING_OP_LINK_TIMEOUT + * IORING_OP_CONNECT + * IORING_OP_FILES_UPDATE + * IORING_OP_FALLOCATE + * IORING_OP_OPENAT + * IORING_OP_CLOSE + * IORING_OP_READ + * IORING_OP_WRITE + * IORING_OP_STATX + * IORING_OP_FADVISE + * IORING_OP_MADVISE + * IORING_OP_SEND + * IORING_OP_RECV + * IORING_OP_OPENAT2 + * IORING_OP_EPOLL_CTL + * IORING_OP_PROVIDE_BUFFERS + * IORING_OP_REMOVE_BUFFERS + */ + + if (brng == false && + budp == false) + { + checkIfOpcodeSupported(IORING_OP_EPOLL_CTL, "IORING_OP_EPOLL_CTL"); + } + else + { + checkIfOpcodeSupported(IORING_OP_POLL_ADD, "IORING_OP_POLL_ADD"); + + if (brng) + { + checkIfOpcodeSupported(IORING_OP_CLOSE, "IORING_OP_CLOSE"); + checkIfOpcodeSupported(IORING_OP_ACCEPT, "IORING_OP_ACCEPT"); + checkIfOpcodeSupported(IORING_OP_WRITEV, "IORING_OP_WRITEV"); + checkIfOpcodeSupported(IORING_OP_READ_FIXED, "IORING_OP_READ_FIXED"); + checkIfOpcodeSupported(IORING_OP_WRITE_FIXED, "IORING_OP_WRITE_FIXED"); + checkIfOpcodeSupported(IORING_OP_ASYNC_CANCEL, "IORING_OP_ASYNC_CANCEL"); +# ifdef U_FILES_UPDATE_ASYNC_WORK + checkIfOpcodeSupported(IORING_OP_FILES_UPDATE, "IORING_OP_FILES_UPDATE"); +# endif + } + else + { + U_INTERNAL_ASSERT(budp) + + checkIfOpcodeSupported(IORING_OP_RECVMSG, "IORING_OP_RECVMSG"); + } + + // check if IORING_FEAT_FAST_POLL is supported + if (!(params.features & IORING_FEAT_FAST_POLL)) + { + U_WARNING("IORING_FEAT_FAST_POLL not available in the kernel(%u)", LINUX_VERSION_CODE) + } + + // check if buffer selection is supported + if (U_SYSCALL(io_uring_opcode_supported, "%p,%u", probe, IORING_OP_PROVIDE_BUFFERS) == false) + { + U_WARNING("Buffer select not supported, kernel(%u)", LINUX_VERSION_CODE) + } + + U_ASSERT(socket->isBlocking()) + U_INTERNAL_ASSERT_EQUALS(nClientIndex, 0) U_INTERNAL_ASSERT_EQUALS(rBuffers, U_NULLPTR) U_INTERNAL_ASSERT_EQUALS(socketfds, U_NULLPTR) U_INTERNAL_ASSERT_EQUALS(handler_poll, U_NULLPTR) + uint32_t num_iovec = 1, sz = rbuffer_size, fdn = 1; + U_NEW_STRING(rBuffers, UString); U_NEW(UVector, handler_poll, UVector); - socketfds = (int*) UMemoryPool::cmalloc(1+UNotifier::max_connection, sizeof(int)); + if (brng) + { + socketfds = (int*) UMemoryPool::cmalloc(1+UNotifier::max_connection, sizeof(int)); - (void) U_SYSCALL(memset, "%p,%u,%u", socketfds, 0xff, (1+UNotifier::max_connection) * sizeof(int)); // make sparse with -1 + socketfds[0] = socket->iSockDesc; + + (void) U_SYSCALL(memset, "%p,%u,%u", socketfds+1, 0xff, UNotifier::max_connection * sizeof(int)); // make sparse with -1 + + sz *= UNotifier::max_connection; + fdn += UNotifier::max_connection; + + U_INTERNAL_DUMP("UClientImage_Base::iov_vec[1](%u) = %.*S", 17+6+29+2+12+2+17+2, 17+6+29+2+12+2+17+2, UClientImage_Base::iov_vec[1].iov_base) + + U_INTERNAL_ASSERT_POINTER(ptr_shared_data) + + // vrwBuffers[1] = { ptr_shared_data, map_size }; -> EOPNOTSUPP + +# ifdef U_WELCOME_SUPPORT + if (msg_welcome) + { + ++num_iovec; + + vrwBuffers[1] = { U_STRING_TO_PARAM(*msg_welcome) }; + } +# endif + } // Register an array large enough to contain all possible file descriptors for io. // To make use of the registered files, the IOSQE_FIXED_FILE flag must be set in the flags member // of the struct io_uring_sqe, and the fd member is set to the index of the file in the file descriptor array - ret = U_SYSCALL(io_uring_register_files, "%p,%p,%p", io_uring, socketfds, 1+UNotifier::max_connection); + ret = U_SYSCALL(io_uring_register_files, "%p,%p,%p", io_uring, (fdn > 1 ? socketfds : fds), fdn); if (ret) { U_ERROR("io_uring_register_files() failed: %d%R", ret, 0); // NB: the last argument (0) is necessary... } - uint32_t sz = rbuffer_size * UNotifier::max_connection; - rBuffers->setConstant(sz); rBuffers->checkConstant(sz); - U_INTERNAL_DUMP("UClientImage_Base::iov_vec[1](%u) = %.*S", 17+6+29+2+12+2+17+2, 17+6+29+2+12+2+17+2, UClientImage_Base::iov_vec[1].iov_base) + char* ptr = rBuffers->data(); - U_INTERNAL_ASSERT_POINTER(ptr_shared_data) + rbuffer->set(0, ptr); - uint32_t num_iovec = 1; - struct iovec vrwBuffers[3] = { - rBuffers->data(), sz, - // ptr_shared_data, map_size -> EOPNOTSUPP - }; - -# ifdef U_WELCOME_SUPPORT - if (msg_welcome) - { - ++num_iovec; - - vrwBuffers[1] = { U_STRING_TO_PARAM(*msg_welcome) }; - } -# endif + vrwBuffers[0] = { ptr, sz }; ret = U_SYSCALL(io_uring_register_buffers, "%p,%p,%p", io_uring, vrwBuffers, num_iovec); @@ -5070,26 +5246,10 @@ void UServer_Base::runLoop(const char* user) U_ERROR("io_uring_register_buffers() failed: %d%R", ret, 0); // NB: the last argument (0) is necessary... } - // ...fd member is the index of the file in the file descriptor array + prepareOperation(brng ? UClientImage_Base::_ACCEPT + : UClientImage_Base::_RECVMSG); - ret = U_SYSCALL(io_uring_register_files_update, "%p,%u,%p,%u", io_uring, 0, &(socketfds[0] = socket->iSockDesc), 1); - - if (ret != 1) - { - U_ERROR("io_uring_register_files_update() failed: %d%R", ret, 0); // NB: the last argument (0) is necessary... - } - - if (handler_inotify) submit(UClientImage_Base::_POLL, handler_inotify); // this queues an poll() - - /* - U_INTERNAL_ASSERT_EQUALS(fcntl(pthis->fd,F_GETFL,0), O_RDWR | O_CLOEXEC) - - socket->setFlags(O_RDWR | O_CLOEXEC); - */ - - U_ASSERT(socket->isBlocking()) - - submit(UClientImage_Base::_ACCEPT); // this queues an accept() + if (handler_inotify) prepareOperation(UClientImage_Base::_POLL, handler_inotify); } # endif @@ -5110,63 +5270,14 @@ void UServer_Base::runLoop(const char* user) pthis->UEventFd::fd = socket->iSockDesc; -# ifndef U_SERVER_CAPTIVE_PORTAL - if (handler_db1) - { -# ifdef USERVER_RNG - if (brng) submit(UClientImage_Base::_POLL, handler_db1); // this queues an poll() - else -# endif - { - UNotifier::min_connection++; + addHandlerEventPoll(handler_db1); + addHandlerEventPoll(handler_db2); - handler_db1->UEventFd::op_mask |= EPOLLET; - handler_db1->UEventFd::op_mask &= ~EPOLLRDHUP; - } - } - - if (handler_db2) - { -# ifdef USERVER_RNG - if (brng) submit(UClientImage_Base::_POLL, handler_db2); // this queues an poll() - else -# endif - { - UNotifier::min_connection++; - - handler_db2->UEventFd::op_mask |= EPOLLET; - handler_db2->UEventFd::op_mask &= ~EPOLLRDHUP; - } - } -# endif - - if (handler_other) - { - uint32_t n = handler_other->size(); - - U_INTERNAL_DUMP("handler_other->size() = %u", n) - - for (uint32_t i = 0; i < n; ++i) - { - U_INTERNAL_DUMP("(*handler_other)[%u]->UEventFd::fd = %d", i, (*handler_other)[i]->UEventFd::fd) - - U_INTERNAL_ASSERT_DIFFERS((*handler_other)[i]->UEventFd::fd, -1) - -# ifdef USERVER_RNG - if (brng) submit(UClientImage_Base::_POLL, handler_other+i); // this queues an poll() - else -# endif - (*handler_other)[i]->UEventFd::op_mask &= ~EPOLLRDHUP; - } - -# ifdef USERVER_RNG - if (brng == false) -# endif - UNotifier::min_connection += n; - } + if (handler_other) for (uint32_t i = 0, n = handler_other->size(); i < n; ++i) addHandlerEventPoll(handler_other->at(i)); #ifdef USERVER_RNG - if (brng == false) + if (brng == false && + budp == false) #endif { UNotifier::max_connection += (UNotifier::num_connection = UNotifier::min_connection); @@ -5261,208 +5372,288 @@ void UServer_Base::runLoop(const char* user) U_INTERNAL_DUMP("UNotifier::num_connection = %u UNotifier::min_connection = %u", UNotifier::num_connection, UNotifier::min_connection) # ifdef USERVER_RNG - if (brng) + if (brng || + budp) { if (ptime == U_NULLPTR) // NB: we can go directly on wait_cqe() and block on it... { - if (wait_cqe()) continue; + if (wait_cqe() == false) continue; } else { + submit(); + UNotifier::nfd_ready = 0; UNotifier::waitForEvent((vPFpv)UServer_Base::waitForEvent); } - void* data = (void*) U_SYSCALL(io_uring_cqe_get_data, "%p", cqe); + void* data; + int op, result; + uint32_t head, count = 0; - U_SYSCALL_VOID(io_uring_cqe_seen, "%p,%p", io_uring, cqe); // signal that we consumed one - - int op = ((uint32_t)(long)data), - result = cqe->res; - - U_INTERNAL_DUMP("op = %u %s result = %d", op, UClientImage_Base::getPendingOperationDescription(op), result) - - if (op == UClientImage_Base::_POLL) + io_uring_for_each_cqe(io_uring, head, cqe) { - uint32_t nHandlerIndex = (uint32_t)((long)data>>32); - UEventFd* pHandlerIndex = handler_poll->at(nHandlerIndex); + data = (void*) U_SYSCALL(io_uring_cqe_get_data, "%p", cqe); + op = ((uint32_t)(long)data), + result = cqe->res; - U_INTERNAL_DUMP("nHandlerIndex = %u pHandlerIndex->fd = %d result = %d", nHandlerIndex, pHandlerIndex->fd, result) + U_INTERNAL_DUMP("op = %u %s result = %d count = %u", op, UClientImage_Base::getPendingOperationDescription(op), result, count) - U_INTERNAL_ASSERT_DIFFERS(pHandlerIndex->fd, -1) + if ((unsigned long)data == 0xffffffffffffffff) break; - if (UNLIKELY(result < 0)) + ++count; + + if (op == UClientImage_Base::_ACCEPT) { - u_errno = -result; + U_INTERNAL_DUMP("socketfds[0] = %u", socketfds[0]) - U_WARNING("poll fd %d got %d%R", pHandlerIndex->fd, result, 0); // NB: the last argument (0) is necessary... - } - else - { - pHandlerIndex->handlerRead(); - - submit(UClientImage_Base::_POLL, pHandlerIndex); // this queues an poll() - It's a one-shot operation that must be resubmitted after it completes - } - - continue; - } - - if (op == UClientImage_Base::_ACCEPT) - { - U_INTERNAL_DUMP("socketfds[0] = %u", socketfds[0]) - - if (UNLIKELY(result < 0)) // standard accept errors -> ENETDOWN, EPROTO, ENOPROTOOPT, EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP, ENETUNREACH - { - u_errno = -result; - - U_WARNING("accept got %d%R", result, 0); // NB: the last argument (0) is necessary... - } - else - { - findNextClientImage(); - - (csocket = pClientImage->socket)->setFd(pClientImage->fd = result); - -# if !defined(U_SERVER_CAPTIVE_PORTAL) || !defined(ENABLE_THREAD) - csocket->setRemoteAddressAndPort(); - - setClientAddress(); -# endif - - submit(pthis->handlerAccept(pClientImage->fd) ? UClientImage_Base::_CONNECT - : UClientImage_Base::_CLOSE); - } - - continue; - } - - pClientImage = vClientImage + (nClientIndex = (uint32_t)((long)data>>32)); - - U_INTERNAL_ASSERT_RANGE(0L, nClientIndex, UNotifier::max_connection-1) - - U_INTERNAL_DUMP("socketfds[%u] = %d pClientImage->fd = %d", 1+nClientIndex, socketfds[1+nClientIndex], pClientImage->fd) - - if (result < 0) - { - u_errno = -result; - - U_WARNING("operation %s on fd %d got %d%R", UClientImage_Base::getPendingOperationDescription(op), pClientImage->fd, result, 0); // NB: the last argument (0) is necessary... - - if (pClientImage->fd != -1) - { - if (result != -9) (void) U_FF_SYSCALL(close, "%d", pClientImage->fd); // 9 -> EBADF - - U_ClientImage_state = U_NOTIFY_DELETE; - - goto next; - } - - continue; - } - - if (op == UClientImage_Base::_CLOSE) - { - if (socketfds[1+nClientIndex] == -1) pClientImage->resetPendingOperationClose(); - else - { -next: pClientImage->socket->setFd(-1); - - pClientImage->UClientImage_Base::handlerDelete(); - - U_INTERNAL_ASSERT_EQUALS(pClientImage->fd, -1) - U_ASSERT_EQUALS(pClientImage->isPendingOperationClose(), false) - - register_files_update(); - } - - continue; - } - - if (op == UClientImage_Base::_READ) - { - pClientImage->resetPendingOperationRead(); - - U_INTERNAL_DUMP("read fd(%d) = %d", pClientImage->fd, result); - - if (pClientImage->fd == -1 || - pClientImage->isPendingOperationClose()) - { - continue; - } - - if (result == 0) - { - U_ClientImage_state = U_NOTIFY_DELETE; - - submit(UClientImage_Base::_CLOSE); // this queues a close() - - continue; - } - - uint32_t start = nClientIndex * rbuffer_size, - sz = (long)pClientImage->data_pending; - - U_INTERNAL_DUMP("BytesRead(%u) = %#.*S", result, result, rBuffers->c_pointer(start+sz)) - - if (UClientImage_Base::rbuffer->same(rbuffer) == false) - { - U_INTERNAL_ASSERT_EQUALS(sz, 0) - - UClientImage_Base::resetReadBuffer(rbuffer); - } - - U_INTERNAL_ASSERT_MINOR((uint32_t)result, rbuffer_size) - U_INTERNAL_ASSERT(UClientImage_Base::rbuffer->same(rbuffer)) - U_ASSERT_EQUALS(UClientImage_Base::rbuffer->capacity(), rbuffer_size) - - rbuffer->set(sz+result, rBuffers->c_pointer(start)); - - if (sz) - { - if (UClientImage_Base::callerIsValidRequestExt(U_STRING_TO_PARAM(*UClientImage_Base::rbuffer)) == false) // partial valid (not complete) + if (UNLIKELY(result < 0)) // standard accept errors -> ENETDOWN, EPROTO, ENOPROTOOPT, EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP, ENETUNREACH { - U_INTERNAL_DUMP("pClientImage->data_pending = %u", sz) + u_errno = -result; - pClientImage->data_pending = (UString*)((long)sz + (long)result); + U_WARNING("accept got %d%R", result, 0); // NB: the last argument (0) is necessary... + } + else + { + findClientImage(); - U_ClientImage_state = U_PLUGIN_HANDLER_AGAIN; + (csocket = pClientImage->socket)->setFd(pClientImage->fd = result); - submit(UClientImage_Base::_READ); +# if !defined(U_SERVER_CAPTIVE_PORTAL) || !defined(ENABLE_THREAD) + csocket->setRemoteAddressAndPort(); - continue; + setClientAddress(); +# endif + + prepareOperation(pthis->handlerAccept(pClientImage->fd) ? UClientImage_Base::_CONNECT + : UClientImage_Base::_CLOSE); + } + } +# ifndef U_HTTP3_DISABLE + else if (op == UClientImage_Base::_RECVMSG) + { + U_INTERNAL_ASSERT(budp) + + if (result < 0) + { + u_errno = -result; + + U_WARNING("recvmsg on fd %d got %d%R", fds[0], result, 0); // NB: the last argument (0) is necessary... + + // result = U_SYSCALL(recvmsg, "%u,%p,%u", fds[0], &rmsg, 0); + } + else + { + char* ptr = rbuffer->data(); + + U_INTERNAL_DUMP("BytesRead(%u) = %#.*S", result, result, ptr) + + U_INTERNAL_ASSERT_EQUALS(ptr, rBuffers->data()) + U_INTERNAL_ASSERT(UClientImage_Base::rbuffer->same(rbuffer)) + U_ASSERT_EQUALS(UClientImage_Base::rbuffer->capacity(), rbuffer_size) + + if (UHTTP3::parseHeader(ptr, result)) + { + rbuffer->size_adjust_force(result); + + if (UHTTP3::lookup()) + { + // TODO + } + else + { + logNewClient(); + + if (UHTTP3::handlerNewConnection()) + { + if (pthis->handlerAccept(-1)) + { + // TODO + } + } + } + } + } + } +# endif + else if (op == UClientImage_Base::_POLL) + { + uint32_t nHandlerIndex = (uint32_t)((long)data>>32); + UEventFd* pHandlerIndex = handler_poll->at(nHandlerIndex); + + U_INTERNAL_ASSERT_POINTER(pHandlerIndex) + + U_INTERNAL_DUMP("nHandlerIndex = %u pHandlerIndex->fd = %d result = %d", nHandlerIndex, pHandlerIndex->fd, result) + + U_INTERNAL_ASSERT_DIFFERS(pHandlerIndex->fd, -1) + + if (UNLIKELY(result < 0)) + { + u_errno = -result; + + U_WARNING("poll fd %d got %d%R", pHandlerIndex->fd, result, 0); // NB: the last argument (0) is necessary... + } + else + { + pHandlerIndex->handlerRead(); + + prepareOperation(UClientImage_Base::_POLL, pHandlerIndex); // It's a one-shot operation that must be resubmitted after it completes + } + } + else + { + pClientImage = vClientImage + (nClientIndex = (uint32_t)((long)data>>32)); + + U_INTERNAL_ASSERT_RANGE(0L, nClientIndex, UNotifier::max_connection-1) + + U_INTERNAL_DUMP("socketfds[%u] = %d pClientImage->fd = %d", 1+nClientIndex, socketfds[1+nClientIndex], pClientImage->fd) + + if (result < 0) + { + u_errno = -result; + + U_WARNING("operation %s on fd %d got %d%R", UClientImage_Base::getPendingOperationDescription(op), + (pClientImage->fd != -1 ? pClientImage->fd : socketfds[1+nClientIndex]), result, 0); // NB: the last argument (0) is necessary + + if (pClientImage->fd != -1 && + pClientImage->isPendingOperationCancel() == false) + { + if (result != -EBADF) + { + if (result == -EINTR) continue; + + (void) U_FF_SYSCALL(close, "%d", pClientImage->fd); + } + + U_ClientImage_state = U_NOTIFY_DELETE; + + if (op == UClientImage_Base::_READ) pClientImage->resetPendingOperationRead(); + + goto close; + } } - pClientImage->data_pending = U_NULLPTR; + if (op == UClientImage_Base::_READ) + { + pClientImage->resetPendingOperationRead(); + + U_INTERNAL_DUMP("read fd(%d) = %d", pClientImage->fd, result); + + if (pClientImage->fd == -1 || + pClientImage->isPendingOperationClose()) + { + } + else if (result == 0) + { + U_ClientImage_state = U_NOTIFY_DELETE; + + prepareOperation(UClientImage_Base::_CLOSE); + } + else + { + uint32_t start = nClientIndex * rbuffer_size, + sz = (long)pClientImage->data_pending; + + U_INTERNAL_DUMP("BytesRead(%u) = %#.*S", result, result, rBuffers->c_pointer(start+sz)) + + if (UClientImage_Base::rbuffer->same(rbuffer) == false) + { + U_INTERNAL_ASSERT_EQUALS(sz, 0) + + UClientImage_Base::resetReadBuffer(rbuffer); + } + + U_INTERNAL_ASSERT_MINOR((uint32_t)result, rbuffer_size) + U_INTERNAL_ASSERT(UClientImage_Base::rbuffer->same(rbuffer)) + U_ASSERT_EQUALS(UClientImage_Base::rbuffer->capacity(), rbuffer_size) + + rbuffer->set(sz+result, rBuffers->c_pointer(start)); + + if (sz) + { + if (UClientImage_Base::callerIsValidRequestExt(U_STRING_TO_PARAM(*UClientImage_Base::rbuffer)) == false) // partial valid (not complete) + { + U_INTERNAL_DUMP("pClientImage->data_pending = %u", sz) + + pClientImage->data_pending = (UString*)((long)sz + (long)result); + + U_ClientImage_state = U_PLUGIN_HANDLER_AGAIN; + + prepareOperation(UClientImage_Base::_READ); + + continue; + } + + pClientImage->data_pending = U_NULLPTR; + } + + csocket = pClientImage->socket; + + result = pClientImage->handlerRead(); + + U_DUMP("result = %d csocket->isClosed() = %b U_ClientImage_close = %b", result, csocket->isClosed(), U_ClientImage_close) + + if (result != U_NOTIFIER_DELETE && + U_ClientImage_close == false) + { + prepareOperation(UClientImage_Base::_READ); + } + else + { + if (csocket->isClosed()) reset(); + else prepareOperation(UClientImage_Base::_CLOSE); + } + } + } + else if (op == UClientImage_Base::_WRITE) + { + if (pClientImage->resetPendingOperationWrite()) + { + if (pClientImage->isPendingOperationClose()) prepareOperation(UClientImage_Base::_CLOSE); + else if (pClientImage->isPendingOperationCancel()) + { + pClientImage->resetPendingOperationCancel(); + + reset(); + } + } + } + else if (op == UClientImage_Base::_CLOSE) + { +close: U_INTERNAL_ASSERT_DIFFERS(socketfds[1+nClientIndex], -1) + + pClientImage->socket->setFd(-1); + + if (pClientImage->data_pending) pClientImage->data_pending = U_NULLPTR; + + pClientImage->UClientImage_Base::handlerDelete(); + + U_ASSERT_EQUALS(pClientImage->isPendingOperationClose(), false) + + if (pClientImage->isPendingOperationRead() == false) reset(); + else if (pClientImage->isPendingOperationCancel() == false) prepareForCancelRead(); + } + else if (op == UClientImage_Base::_CANCEL) + { + pClientImage->resetPendingOperationCancel(); + + reset(); + } +# ifdef U_FILES_UPDATE_ASYNC_WORK + else + { + U_INTERNAL_ASSERT(op == UClientImage_Base::_UPDATE) + + U_INTERNAL_ASSERT_EQUALS(fds[0], pClientImage->fd) + + socketfds[1+nClientIndex] = fds[0]; + } +# endif } - - csocket = pClientImage->socket; - - result = pClientImage->handlerRead(); - - U_DUMP("result = %u csocket->isClosed() = %b", result, csocket->isClosed()) - - if (result != U_NOTIFIER_DELETE) submit(UClientImage_Base::_READ); - else if (csocket->isClosed() == false) submit(UClientImage_Base::_CLOSE); - - continue; } -# ifdef U_FILES_UPDATE_ASYNC_WORK - if (op == UClientImage_Base::_UPDATE) - { - U_INTERNAL_ASSERT_EQUALS(fds[0], pClientImage->fd) - - socketfds[1+nClientIndex] = fds[0]; - - continue; - } -# endif - - U_INTERNAL_ASSERT(op == UClientImage_Base::_WRITE || - op == UClientImage_Base::_WRITEV) - - if (pClientImage->resetPendingOperationWrite()) submit(UClientImage_Base::_CLOSE); + U_SYSCALL_VOID(io_uring_cq_advance, "%p,%u", io_uring, count); continue; } @@ -5532,7 +5723,9 @@ void UServer_Base::handlerStop() if (pthread_sse) sse_vclient->clear(); #endif +#ifdef DEBUG pthis->deallocate(); +#endif } void UServer_Base::run() @@ -5904,6 +6097,21 @@ bool UServer_Base::startParallelization(uint32_t nclient) csocket->close(); +# ifdef USERVER_RNG + if (brng) + { + --UNotifier::num_connection; + + U_INTERNAL_DUMP("UNotifier::num_connection = %u", UNotifier::num_connection) + +# if !defined(U_LOG_DISABLE) && defined(U_LINUX) && defined(ENABLE_THREAD) + ULock::atomicDecrement(U_SRV_TOT_CONNECTION); + + U_INTERNAL_DUMP("U_SRV_TOT_CONNECTION = %u", U_SRV_TOT_CONNECTION) +# endif + } +# endif + UClientImage_Base::resetPipelineAndSetCloseConnection(); U_ClientImage_parallelization = U_PARALLELIZATION_PARENT; diff --git a/src/ulib/net/socket.cpp b/src/ulib/net/socket.cpp index ce6b042d..54a011bb 100644 --- a/src/ulib/net/socket.cpp +++ b/src/ulib/net/socket.cpp @@ -240,12 +240,10 @@ void USocket::setRemoteAddressAndPort() { U_TRACE_NO_PARAM(0, "USocket::setRemoteAddressAndPort()") - U_INTERNAL_DUMP("peer_addr_len = %u sizeOf() = %u", peer_addr_len, ((SocketAddress*)&peer_addr)->sizeOf()) + U_INTERNAL_DUMP("peer_addr_len = %u sizeOf() = %u SocketAddress = %#.*S", peer_addr_len, ((SocketAddress*)&peer_addr)->sizeOf(), peer_addr_len, &peer_addr) U_INTERNAL_ASSERT_EQUALS(peer_addr_len, ((SocketAddress*)&peer_addr)->sizeOf()) - U_INTERNAL_DUMP("SocketAddress = %#.*S", peer_addr_len, &peer_addr) - iRemotePort = ((SocketAddress*)&peer_addr)->getPortNumber(); ((SocketAddress*)&peer_addr)->getIPAddress(cRemoteAddress); @@ -931,12 +929,14 @@ void USocket::close_socket() #if defined(HAVE_EPOLL_WAIT) && !defined(USE_LIBEVENT) U_INTERNAL_DUMP("U_ClientImage_parallelization = %d", U_ClientImage_parallelization) - if (U_ClientImage_parallelization != U_PARALLELIZATION_CHILD && - UNotifier::isHandler(iSockDesc)) + if (U_ClientImage_parallelization != U_PARALLELIZATION_CHILD) { - (void) U_FF_SYSCALL(epoll_ctl, "%d,%d,%d,%p", UNotifier::epollfd, EPOLL_CTL_DEL, iSockDesc, (struct epoll_event*)1); + if (UNotifier::isHandler(iSockDesc)) + { + (void) U_FF_SYSCALL(epoll_ctl, "%d,%d,%d,%p", UNotifier::epollfd, EPOLL_CTL_DEL, iSockDesc, (struct epoll_event*)1); - UNotifier::handlerDelete(iSockDesc, EPOLLIN | EPOLLRDHUP); + UNotifier::handlerDelete(iSockDesc, EPOLLIN | EPOLLRDHUP); + } } #endif diff --git a/src/ulib/utility/http3.cpp b/src/ulib/utility/http3.cpp index 3cd1a256..48bc4714 100644 --- a/src/ulib/utility/http3.cpp +++ b/src/ulib/utility/http3.cpp @@ -21,8 +21,14 @@ #define U_MAX_DATAGRAM_SIZE 1350 +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::peer_addr_len; uint32_t UHTTP3::quiche_max_packet_size = U_MAX_DATAGRAM_SIZE; quiche_config* UHTTP3::qconfig; @@ -177,352 +183,267 @@ int UHTTP3::loadConfigParam() U_RETURN(U_PLUGIN_HANDLER_OK); } -bool UHTTP3::handlerRead() +bool UHTTP3::parseHeader(const char* data, uint32_t iBytesRead) { - U_TRACE_NO_PARAM(0, "UHTTP3::handlerRead()") + U_TRACE(0, "UHTTP3::parseHeader(%.*S,%u)", iBytesRead, data, iBytesRead) + + 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*)data, iBytesRead, 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::parseHeader(): failed to parse header: %d", rc); + + U_RETURN(false); + } + + U_INTERNAL_DUMP("\n" + " scid(%u) = %#.*S\n" + " token(%u) = %#.*S\n" + "conn_id(%u) = %#.*S\n" + "pkt_version = %u 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::handlerNewConnection() +{ + U_TRACE_NO_PARAM(0, "UHTTP3::handlerNewConnection()") U_INTERNAL_ASSERT_POINTER(peers) U_INTERNAL_ASSERT(UServer_Base::budp) - int rc; - void* pconn; - uint8_t pkt_type; - uint32_t pkt_version; - size_t scid_len, token_len; - ssize_t done, written, sent; - char* data = UClientImage_Base::rbuffer->data(); - int iBytesRead, fd = UServer_Base::socket->getFd(); - uint8_t token[U_MAX_TOKEN_LEN], scid[QUICHE_MAX_CONN_ID_LEN], out[U_MAX_DATAGRAM_SIZE]; + ssize_t written, sent; + const char* pkt = "vneg"; + uint8_t out[U_MAX_DATAGRAM_SIZE]; - while (true) + if (pkt_type != Initial) { - USocket::resetPeerAddr(); + U_DEBUG("UHTTP3::handlerNewConnection(): packet is NOT initial: %u", pkt_type); - iBytesRead = U_SYSCALL(recvfrom, "%d,%p,%u,%u,%p,%p", fd, data, 65535, 0, (struct sockaddr*)&peer_addr, &peer_addr_len); + U_RETURN(false); + } - if (iBytesRead <= 0) + // 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("UHTTP3::handlerNewConnection(): 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 (errno != EAGAIN) - { - U_DEBUG("UHTTP3::handlerRead(): failed to receive"); - - U_RETURN(false); - } - - break; - } - - U_INTERNAL_DUMP("BytesRead(%u) = %#.*S", iBytesRead, iBytesRead, data) - - u__memcpy(&USocket::peer_addr, &peer_addr, USocket::peer_addr_len = peer_addr_len, __PRETTY_FUNCTION__); - - 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 - rc = U_SYSCALL(quiche_header_info, "%p,%u,%u,%p,%p,%p,%p,%p,%p,%p,%p", (const uint8_t*)data, iBytesRead, 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_DEBUG("UHTTP3::handlerNewConnection(): failed to create %S packet: %d", pkt, written); U_RETURN(false); } - U_INTERNAL_DUMP("\n" - " scid(%u) = %#.*S\n" - " token(%u) = %#.*S\n" - "conn_id(%u) = %#.*S\n" - "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) + 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); - // 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)); - - U_INTERNAL_DUMP("pconn = %p", pconn) - - if (pconn == U_NULLPTR) + if (sent == written) { - const char* pkt = "vneg"; - - if (pkt_type != Initial) - { - U_DEBUG("UHTTP3::handlerRead(): packet is NOT initial: %d", pkt_type); - - 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); + U_DEBUG("UHTTP3::handlerNewConnection(): sent %u bytes", sent); } - - // Processes QUIC packets received from the peer - done = U_SYSCALL(quiche_conn_recv, "%p,%p,%u", conn.conn, (uint8_t*)data, iBytesRead); - - if (done == QUICHE_ERR_DONE) + else { - U_DEBUG("UHTTP3::handlerRead(): done reading"); - - U_RETURN(true); - } - - if (done < 0) - { - U_DEBUG("UHTTP3::handlerRead(): failed to process packet: %d", done); + U_DEBUG("UHTTP3::handlerNewConnection(): failed to send"); U_RETURN(false); } - - U_DEBUG("UHTTP3::handlerRead(): recv %d bytes", done); - - 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(conn.http3, U_NULLPTR) - - // Creates a new HTTP/3 connection using the provided QUIC connection - conn.http3 = (quiche_h3_conn*) U_SYSCALL(quiche_h3_conn_new_with_transport, "%p,%p", conn.conn, http3_config); - - if (conn.http3 == U_NULLPTR) - { - U_DEBUG("UHTTP3::handlerAccept(): failed to create HTTP/3 connection"); - - U_RETURN(false); - } - - quiche_h3_event* ev; - - while (true) - { - // Processes HTTP/3 data received from the peer - done = U_SYSCALL(quiche_h3_conn_poll, "%p,%p,%p", conn.http3, conn.conn, &ev); - - if (done < 0) break; - - switch (quiche_h3_event_type(ev)) - { - case QUICHE_H3_EVENT_HEADERS: - { - // 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, NULL); - - if (rc != 0) - { - U_DEBUG("UHTTP3::handlerRead(): failed to process headers"); - } - - /* - quiche_h3_header headers[] = { - { - .name = (const uint8_t *) ":status", - .name_len = sizeof(":status") - 1, - - .value = (const uint8_t *) "200", - .value_len = sizeof("200") - 1, - }, - - { - .name = (const uint8_t *) "server", - .name_len = sizeof("server") - 1, - - .value = (const uint8_t *) "quiche", - .value_len = sizeof("quiche") - 1, - }, - - { - .name = (const uint8_t *) "content-length", - .name_len = sizeof("content-length") - 1, - - .value = (const uint8_t *) "5", - .value_len = sizeof("5") - 1, - }, - }; - - quiche_h3_send_response(conn_io->http3, conn_io->conn, s, headers, 3, true); - - quiche_h3_send_body(conn_io->http3, conn_io->conn, s, (uint8_t *) "byez\n", 5, true); - */ - break; - } - - case QUICHE_H3_EVENT_DATA: - { - U_DEBUG("UHTTP3::handlerRead(): got HTTP data"); - - break; - } - - case QUICHE_H3_EVENT_FINISHED: - break; - } - - U_SYSCALL_VOID(quiche_h3_event_free, "%p", ev); - } - } } - while (true) + if (token_len == 0) { - written = U_SYSCALL(quiche_conn_send, "%p,%p,%u", conn.conn, out, sizeof(out)); + uint8_t odcid[QUICHE_MAX_CONN_ID_LEN]; - if (written == QUICHE_ERR_DONE) - { - U_DEBUG("UHTTP3::handlerRead(): done writing"); + // 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_RETURN(false); - } + U_DEBUG("UHTTP3::handlerNewConnection(): stateless retry"); - if (written < 0) - { - U_DEBUG("UHTTP3::handlerRead(): failed to create packet: %d", written); + (void) memcpy(token, U_CONSTANT_TO_PARAM("quiche")); + (void) memcpy(token + U_CONSTANT_SIZE("quiche"), &USocket::peer_addr, USocket::peer_addr_len); + (void) memcpy(token + U_CONSTANT_SIZE("quiche") + USocket::peer_addr_len, conn_id, conn_id_len); - U_RETURN(false); - } + token_len = U_CONSTANT_SIZE("quiche") + USocket::peer_addr_len + conn_id_len; - sent = U_SYSCALL(sendto, "%d,%p,%u,%u,%p,%d", fd, out, written, 0, (struct sockaddr*)&USocket::peer_addr, USocket::peer_addr_len); + u__memcpy(odcid, conn_id, conn_id_len, __PRETTY_FUNCTION__); - if (sent != written) - { - U_DEBUG("UHTTP3::handlerRead(): failed to send"); + // 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)); - U_RETURN(false); - } + pkt = "retry"; - U_DEBUG("UHTTP3::handlerRead(): sent %u bytes", sent); + goto pkt; } -// UClientImage_Base::rbuffer->size_adjust(iBytesRead); + // 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::handlerNewConnection(): 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::handlerNewConnection(): 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::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.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::handlerNewConnection(): failed to create connection"); + + U_RETURN(false); + } U_RETURN(true); -} -bool UHTTP3::handlerAccept() -{ - U_TRACE_NO_PARAM(0, "UHTTP3::handlerAccept()") + /* + { + peers->insert((const char*)conn_id, conn_id_len, (const UClientImage_Base*)&conn); - 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) + // Processes QUIC packets received from the peer + ssize_t done = U_SYSCALL(quiche_conn_recv, "%p,%p,%u", conn.conn, (uint8_t*)data, iBytesRead); - UServer_Base::pClientImage->conn = conn.conn; - UServer_Base::pClientImage->http3 = conn.http3; - - conn.conn = U_NULLPTR; - conn.http3 = U_NULLPTR; - - UServer_Base::pClientImage->socket->setRemoteAddressAndPort(); - - peers->replace((const char*)conn_id, conn_id_len, UServer_Base::pClientImage); + if (done == QUICHE_ERR_DONE) + { + U_DEBUG("UHTTP3::handlerRead(): done reading"); U_RETURN(true); + } + + if (done < 0) + { + U_DEBUG("UHTTP3::handlerRead(): failed to process packet: %d", done); + + U_RETURN(false); + } + + U_DEBUG("UHTTP3::handlerRead(): recv %d bytes", done); + + 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(conn.http3, U_NULLPTR) + + // Creates a new HTTP/3 connection using the provided QUIC connection + conn.http3 = (quiche_h3_conn*) U_SYSCALL(quiche_h3_conn_new_with_transport, "%p,%p", conn.conn, http3_config); + + if (conn.http3 == U_NULLPTR) + { + U_DEBUG("UHTTP3::handlerAccept(): failed to create HTTP/3 connection"); + + U_RETURN(false); + } + + quiche_h3_event* ev; + + while (true) + { + // Processes HTTP/3 data received from the peer + done = U_SYSCALL(quiche_h3_conn_poll, "%p,%p,%p", conn.http3, conn.conn, &ev); + + if (done < 0) break; + + switch (quiche_h3_event_type(ev)) + { + case QUICHE_H3_EVENT_HEADERS: + { + // 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, NULL); + + if (rc != 0) + { + U_DEBUG("UHTTP3::handlerRead(): failed to process headers"); + } + + break; + } + + case QUICHE_H3_EVENT_DATA: + { + U_DEBUG("UHTTP3::handlerRead(): got HTTP data"); + + break; + } + + case QUICHE_H3_EVENT_FINISHED: + break; + } + + U_SYSCALL_VOID(quiche_h3_event_free, "%p", ev); + } + } + + while (true) + { + written = U_SYSCALL(quiche_conn_send, "%p,%p,%u", conn.conn, out, sizeof(out)); + + if (written == QUICHE_ERR_DONE) + { + U_DEBUG("UHTTP3::handlerRead(): done writing"); + + U_RETURN(false); + } + + if (written < 0) + { + U_DEBUG("UHTTP3::handlerRead(): failed to create packet: %d", written); + + U_RETURN(false); + } + + sent = U_SYSCALL(sendto, "%d,%p,%u,%u,%p,%d", fd, out, written, 0, (struct sockaddr*)&USocket::peer_addr, USocket::peer_addr_len); + + if (sent != written) + { + U_DEBUG("UHTTP3::handlerRead(): failed to send"); + + U_RETURN(false); + } + + U_DEBUG("UHTTP3::handlerRead(): sent %u bytes", sent); + } + } + */ } diff --git a/src/ulib/utility/uhttp.cpp b/src/ulib/utility/uhttp.cpp index 7570a530..8b29b54d 100644 --- a/src/ulib/utility/uhttp.cpp +++ b/src/ulib/utility/uhttp.cpp @@ -824,7 +824,11 @@ U_NO_EXPORT void UHTTP::loadStaticLinkedServlet(const char* name, uint32_t len, file_data->mime_index = U_usp; - U_NEW(UHTTP::UServletPage, file_data->ptr, UHTTP::UServletPage(name, len, U_NULLPTR, 0, runDynamicPage, runDynamicPageParam)); + UHTTP::UServletPage* page; + + U_NEW(UHTTP::UServletPage, page, UHTTP::UServletPage(name, len, U_NULLPTR, 0, runDynamicPage, runDynamicPageParam)); + + file_data->ptr = page; U_INTERNAL_ASSERT_POINTER(vusp) diff --git a/test-driver b/test-driver index d3060566..b8521a48 100755 --- a/test-driver +++ b/test-driver @@ -1,9 +1,9 @@ #! /bin/sh # test-driver - basic testsuite driver script. -scriptversion=2013-07-13.22; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 2011-2013 Free Software Foundation, Inc. +# Copyright (C) 2011-2018 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ scriptversion=2013-07-13.22; # UTC # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -106,11 +106,14 @@ trap "st=143; $do_exit" 15 # Test script is run here. "$@" >$log_file 2>&1 estatus=$? + if test $enable_hard_errors = no && test $estatus -eq 99; then - estatus=1 + tweaked_estatus=1 +else + tweaked_estatus=$estatus fi -case $estatus:$expect_failure in +case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; @@ -119,6 +122,12 @@ case $estatus:$expect_failure in *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac +# Report the test outcome and exit status in the logs, so that one can +# know whether the test passed or failed simply by looking at the '.log' +# file, without the need of also peaking into the corresponding '.trs' +# file (automake bug#11814). +echo "$res $test_name (exit status: $estatus)" >>$log_file + # Report outcome to console. echo "${col}${res}${std}: $test_name" @@ -131,9 +140,9 @@ echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff --git a/tests/.function b/tests/.function index 3de5e0f3..ea6c5ab9 100644 --- a/tests/.function +++ b/tests/.function @@ -473,6 +473,7 @@ wait_server_ready() { if [ $? -eq 0 ]; then break fi + $SLEEP done } diff --git a/tests/examples/CSP/CSP/DB_CA/openssl.cnf.tmpl b/tests/examples/CSP/CSP/DB_CA/openssl.cnf.tmpl index 2d29118c..5758ede8 100644 --- a/tests/examples/CSP/CSP/DB_CA/openssl.cnf.tmpl +++ b/tests/examples/CSP/CSP/DB_CA/openssl.cnf.tmpl @@ -1,13 +1,14 @@ RANDFILE = $ENV::HOME/.rnd -oid_file = /etc/openssl/.oid +#oid_file = /etc/openssl/.oid oid_section = new_oids [ new_oids ] -dnQualifier = 2.5.4.46 -surName = 2.5.4.4 -givenName = 2.5.4.42 -initials = 2.5.4.43 -generationQualifier = 2.5.4.44 + +# dnQualifier = 2.5.4.46 +# surName = 2.5.4.4 +# givenName = 2.5.4.42 +# initials = 2.5.4.43 +# generationQualifier = 2.5.4.44 [ req ] default_bits = 4096 diff --git a/tests/examples/TSA/tsaserial b/tests/examples/TSA/tsaserial index e42a0403..f5c0ed5c 100644 --- a/tests/examples/TSA/tsaserial +++ b/tests/examples/TSA/tsaserial @@ -1 +1 @@ -09A2 +09DA diff --git a/tests/examples/csp_rpc.test b/tests/examples/csp_rpc.test index 77e3a4f7..bda998ff 100755 --- a/tests/examples/csp_rpc.test +++ b/tests/examples/csp_rpc.test @@ -6,12 +6,12 @@ start_msg cspclient_rpc -#UTRACE="0 5M -1" +#UTRACE="0 5M 0" #UOBJDUMP="0 100k 10" #USIMERR="error.sim" export UTRACE UOBJDUMP USIMERR -rm -rf CSP/cspserver_rpc.log CSP/CSP/DB_CA/log CSP/CSP/DB_CA/CA* \ +rm -rf /tmp/cspserver_rpc.log CSP/cspserver_rpc.log CSP/CSP/DB_CA/log CSP/CSP/DB_CA/CA* \ out/userver_ssl.out err/userver_ssl.err \ CSP/trace.*userver_ssl*.[0-9]* CSP/object.*userver_ssl*.[0-9]* CSP/stack.*userver_ssl*.[0-9]* CSP/mempool.*userver_ssl*.[0-9]* @@ -52,7 +52,7 @@ rm -rf CSP/cspserver_rpc.log CSP/CSP/DB_CA/log CSP/CSP/DB_CA/CA* \ cat <inp/webserver.cfg userver { - LOG_FILE cspserver_rpc.log + LOG_FILE /tmp/cspserver_rpc.log LOG_FILE_SZ 1M DOCUMENT_ROOT CSP PLUGIN rpc @@ -76,7 +76,8 @@ EOF DIR_CMD="../../examples/userver" start_prg_background userver_ssl -c inp/webserver.cfg -$SLEEP + +wait_server_ready localhost 443 ## ./CSP/request/run.sh > out/cspclient_rpc.out diff --git a/tests/examples/inp/openssl.cnf b/tests/examples/inp/openssl.cnf index 2d29118c..5758ede8 100644 --- a/tests/examples/inp/openssl.cnf +++ b/tests/examples/inp/openssl.cnf @@ -1,13 +1,14 @@ RANDFILE = $ENV::HOME/.rnd -oid_file = /etc/openssl/.oid +#oid_file = /etc/openssl/.oid oid_section = new_oids [ new_oids ] -dnQualifier = 2.5.4.46 -surName = 2.5.4.4 -givenName = 2.5.4.42 -initials = 2.5.4.43 -generationQualifier = 2.5.4.44 + +# dnQualifier = 2.5.4.46 +# surName = 2.5.4.4 +# givenName = 2.5.4.42 +# initials = 2.5.4.43 +# generationQualifier = 2.5.4.44 [ req ] default_bits = 4096 diff --git a/tests/examples/ok/web_server_rng.ok b/tests/examples/ok/web_server_rng.ok index cb6a075c..456c0a49 100644 --- a/tests/examples/ok/web_server_rng.ok +++ b/tests/examples/ok/web_server_rng.ok @@ -1,11 +1,11 @@ HTTP/1.1 505 HTTP Version Not Supported -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Length: 0 HTTP/1.1 501 Not Implemented -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 @@ -21,7 +21,7 @@ Content-Length: 256
ULib Server
HTTP/1.1 400 Bad Request -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 @@ -37,7 +37,7 @@ Content-Length: 263
ULib Server
HTTP/1.1 400 Bad Request -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 @@ -53,7 +53,7 @@ Content-Length: 263
ULib Server
HTTP/1.1 400 Bad Request -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 @@ -69,7 +69,7 @@ Content-Length: 263
ULib Server
HTTP/1.1 411 Length Required -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 @@ -85,7 +85,7 @@ Content-Length: 273
ULib Server
HTTP/1.1 413 Request Entity Too Large -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 @@ -101,7 +101,7 @@ Content-Length: 266
ULib Server
HTTP/1.1 400 Bad Request -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 @@ -117,7 +117,7 @@ Content-Length: 263
ULib Server
HTTP/1.1 400 Bad Request -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 @@ -133,7 +133,7 @@ Content-Length: 263
ULib Server
HTTP/1.1 400 Bad Request -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 @@ -149,7 +149,7 @@ Content-Length: 263
ULib Server
HTTP/1.1 400 Bad Request -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 @@ -165,7 +165,7 @@ Content-Length: 263
ULib Server
HTTP/1.1 400 Bad Request -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 @@ -181,7 +181,7 @@ Content-Length: 263
ULib Server
HTTP/1.1 400 Bad Request -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 @@ -197,14 +197,14 @@ Content-Length: 263
ULib Server
HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Allow: GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE, CONNECT, COPY, MOVE, LOCK, UNLOCK, MKCOL, PROPFIND, PATCH, PURGE, MERGE, REPORT, CHECKOUT, MKACTIVITY, NOTIFY, MSEARCH, SUBSCRIBE, UNSUBSCRIBE Content-Length: 0 HTTP/1.1 401 Authorization Required -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 @@ -221,13 +221,13 @@ Content-Length: 444
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 257 HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 344 @@ -242,7 +242,7 @@ Content-Length: 344
ULib Server
HTTP/1.1 403 Forbidden -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 304 @@ -257,7 +257,7 @@ Content-Length: 304
ULib Server
HTTP/1.1 500 Internal Server Error -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 548 @@ -272,7 +272,7 @@ Content-Length: 548
ULib Server
HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/plain; charset=UTF-8 Cache-Control: max-age=0, no-cache, no-store, must-revalidate @@ -282,7 +282,7 @@ Content-Length: 21 pippo pluto paperino HTTP/1.1 401 Authorization Required -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 WWW-Authenticate: Basic realm="Protected Area" @@ -298,20 +298,20 @@ Content-Length: 444
ULib Server
HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 -Expires: Sat, 19 Jun 2021 14:36:51 GMT +Expires: Tue, 06 Jul 2021 14:39:58 GMT Last-Modified: Fri, 20 Feb 2009 14:50:49 GMT Content-Length: 63 this is the web_server testsuite inp/http/data/index.html file HTTP/1.1 206 Partial Content -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Range: bytes 0-63/64 Content-Type: application/octet-stream; charset=binary -Expires: Sat, 19 Jun 2021 14:36:52 GMT +Expires: Tue, 06 Jul 2021 14:39:59 GMT Last-Modified: Sun, 24 Sep 2017 17:11:42 GMT Content-Length: 64 @@ -320,89 +320,89 @@ Content-Length: 64 34567892345678 012345670123456 HTTP/1.1 206 Partial Content -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Range: bytes 0-31/64 Content-Type: application/octet-stream; charset=binary -Expires: Sat, 19 Jun 2021 14:36:52 GMT +Expires: Tue, 06 Jul 2021 14:39:59 GMT Last-Modified: Sun, 24 Sep 2017 17:11:42 GMT Content-Length: 32 123456781234567 345678903456789 HTTP/1.1 206 Partial Content -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Range: bytes 32-63/64 Content-Type: application/octet-stream; charset=binary -Expires: Sat, 19 Jun 2021 14:36:52 GMT +Expires: Tue, 06 Jul 2021 14:39:59 GMT Last-Modified: Sun, 24 Sep 2017 17:11:42 GMT Content-Length: 32 34567892345678 012345670123456 HTTP/1.1 206 Partial Content -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Range: bytes 32-63/64 Content-Type: text/plain; charset=us-ascii -Expires: Sat, 19 Jun 2021 14:36:52 GMT +Expires: Tue, 06 Jul 2021 14:39:59 GMT Last-Modified: Sun, 24 Sep 2017 17:11:42 GMT Content-Length: 32 234567892345678 012345670123456 HTTP/1.1 206 Partial Content -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib -Content-Length: 227 -Content-Type: multipart/byteranges; boundary="=_5476481467314131684" +Content-Length: 230 +Content-Type: multipart/byteranges; boundary="=_16141005521278189674" ---=_5476481467314131684 +--=_16141005521278189674 Content-Range: bytes 0-0/64 Content-Type: text/html; charset=UTF-8 1 ---=_5476481467314131684 +--=_16141005521278189674 Content-Range: bytes 63-63/64 Content-Type: text/html; charset=UTF-8 ---=_5476481467314131684--HTTP/1.1 206 Partial Content -Date: Fri, 19 Jun 2020 14:36:52 GMT +--=_16141005521278189674--HTTP/1.1 206 Partial Content +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Range: bytes 50-63/64 Content-Type: text/plain; charset=us-ascii -Expires: Sat, 19 Jun 2021 14:36:52 GMT +Expires: Tue, 06 Jul 2021 14:39:59 GMT Last-Modified: Sun, 24 Sep 2017 17:11:42 GMT Content-Length: 14 2345670123456 HTTP/1.1 206 Partial Content -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib -Content-Length: 247 -Content-Type: multipart/byteranges; boundary="=_5476481467314131685" +Content-Length: 250 +Content-Type: multipart/byteranges; boundary="=_16141005521278189675" ---=_5476481467314131685 +--=_16141005521278189675 Content-Range: bytes 10-19/64 Content-Type: text/html; charset=UTF-8 34567 3456 ---=_5476481467314131685 +--=_16141005521278189675 Content-Range: bytes 50-59/64 Content-Type: text/html; charset=UTF-8 2345670123 ---=_5476481467314131685--HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:36:52 GMT +--=_16141005521278189675--HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/plain; charset=us-ascii -Expires: Sat, 19 Jun 2021 14:36:52 GMT +Expires: Tue, 06 Jul 2021 14:39:59 GMT Last-Modified: Sun, 24 Sep 2017 17:11:42 GMT Content-Length: 64 @@ -411,37 +411,37 @@ Content-Length: 64 234567892345678 012345670123456 HTTP/1.1 204 No Content -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Length: 0 HTTP/1.1 204 No Content -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Length: 0 HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Encoding: gzip Content-Type: text/html; charset=UTF-8 -Last-Modified: Wed, 29 Apr 2020 14:37:14 GMT -Content-Length: 292 +Last-Modified: Sat, 04 Jul 2020 18:19:56 GMT +Content-Length: 291 HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 -Last-Modified: Wed, 29 Apr 2020 14:37:14 GMT +Last-Modified: Sat, 04 Jul 2020 18:19:56 GMT Content-Length: 558 -Index of tmp

Index of directory: tmp


Up one level
c 4 Bytes19/06/2020 14:36:51

ULib Server
HTTP/1.1 304 Not Modified -Date: Fri, 19 Jun 2020 14:36:52 GMT +Index of tmp

Index of directory: tmp


Up one level
c 4 Bytes06/07/2020 14:39:58

ULib Server
HTTP/1.1 304 Not Modified +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Length: 0 HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 1669 @@ -488,13 +488,13 @@ Content-Length: 1669 HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Cache-Control: max-age=0, no-cache, no-store, must-revalidate Pragma: no-cache Expires: Sat, 1 Jan 2000 00:00:00 GMT -Content-Length: 1882 +Content-Length: 1881
 ssi_begin
@@ -521,9 +521,9 @@ Document name: ssi1.shtml
 
 Document URI: /SSI/ssi1.shtml
 
-It's now: Friday, 19-Jun-2020 14:36:52 GMT
+It's now: Monday, 06-Jul-2020 14:39:59 GMT
 
-It's now: Friday, 19-Jun-2020 16:36:52 CEST
+It's now: Monday, 06-Jul-2020 16:39:59 CEST
 
 This page is:     179 Bytes
 
@@ -545,13 +545,13 @@ SERVER_NAME=stefano
 SERVER_PORT=8080
 HTTP_HOST=10.30.1.131
 SERVER_PROTOCOL=HTTP/1.1
-SERVER_ADDR=192.168.42.158
+SERVER_ADDR=192.168.42.40
 DOCUMENT_ROOT=/mnt/data/storage/ulib/ULib-2.4.2/tests/examples/docroot
 SERVER_SOFTWARE=ULib/2.4.2
-REMOTE_PORT=49382
+REMOTE_PORT=60112
 REMOTE_ADDR=
 SESSION_ID=:0
-REQUEST_ID=:49382:0
+REQUEST_ID=:60112:0
 PWD=/mnt/data/storage/ulib/ULib-2.4.2/tests/examples/docroot
 PATH=/usr/local/bin:/usr/bin:/bin
 HTTP_X_SENDFILE=puppamelo
@@ -563,7 +563,7 @@ start LS
 --------------
 total 32
 drwxrwxrwx 3 nobody nobody 4096 Apr  2  2019 .
-drwxrwxrwx 7 nobody nobody 4096 Jun 19 16:36 ..
+drwxrwxrwx 7 nobody nobody 4096 Jul  6 16:39 ..
 drwxrwxrwx 3 nobody nobody 4096 Aug 25  2014 earth
 -rw-r--r-- 1 nobody nobody  179 Apr  2  2019 embed.c
 -rw-rw-rw- 1 nobody nobody  160 Mar 28  2011 index.shtml
@@ -599,12 +599,12 @@ SSI_END
 ssi_end
 
HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Length: 115 X-Real-IP: 10.30.1.131 -Set-Cookie: ulib.s1=; expires=Thu, 18 Jun 2020 14:36:52 GMT -Set-Cookie: ulib.s0=5374657665204a6f686e736f6e26313539323636333831322694c9dfc8242ee973319dac58becc0523; expires=Sat, 20 Jun 2020 14:36:52 GMT +Set-Cookie: ulib.s1=; expires=Sun, 05 Jul 2020 14:39:59 GMT +Set-Cookie: ulib.s0=5374657665204a6f686e736f6e263135393431333237393926a9cf16ac42d98da4e67b05d89a9ab699; expires=Tue, 07 Jul 2020 14:39:59 GMT Set-Cookie: TestCookie=pippo Content-Type: text/html; charset=iso-8859-1 @@ -612,7 +612,7 @@ UID = Steve Johnson HTTP_COOKIE = name1=value1, name2=value2; name3=value3, name4=value4 ULIB_SESSION = HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Encoding: gzip Content-Type: text/html; charset=UTF-8 @@ -621,13 +621,13 @@ Content-Length: 709 UW,W+SWlߛrēHL n oMZR@"Ip% f NHzQjūI'8dS>a5l2ڠYS-k9\d9JitE?r-+rM%>|_&$Rp?Bs x4勵dLȽ]z9YM<.#9wv4ӊϣ&"P?L/vc6>Oؿ[F-Rf:_BFp͐ 鐁/e2I[H*4\49I cmJJLLd/U=S1DW|jm siל,SYՍ>`sŭAФtf ԍ1)?)%?(~Kynm ?2Tz~oz+nw;eg`R}Fc*|"]G00VlS]3=CS^.'q=&+%θjrx_QğpDj\eu:p0+>V?w( /Uz&q]8WKA?jۺxfӹ-~(Aj%L0½ ֮8\ҮYXf幺gdkΘԃx)msw.MB[w{*HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Length: 72 Content-Type: application/jsonrequest {"user":"doctoravatar@penzance.com","t":"vlIj","forecast":7,"zip":94089}HTTP/1.1 302 Moved Temporarily -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 @@ -646,7 +646,7 @@ Content-Length: 365
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 253 @@ -661,7 +661,7 @@ Content-Length: 253
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -676,7 +676,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -691,7 +691,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -706,7 +706,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -721,7 +721,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -736,7 +736,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -751,7 +751,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -766,7 +766,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -781,7 +781,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -796,7 +796,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:52 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -811,7 +811,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:56 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 253 @@ -826,7 +826,7 @@ Content-Length: 253
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:56 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 253 @@ -841,7 +841,7 @@ Content-Length: 253
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:56 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -856,7 +856,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:56 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -871,7 +871,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:56 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -886,7 +886,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:56 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -901,7 +901,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:56 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -916,7 +916,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:56 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -931,7 +931,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:56 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -946,7 +946,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:56 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -961,7 +961,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:56 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -976,7 +976,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:36:56 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -991,7 +991,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 400 Bad Request -Date: Fri, 19 Jun 2020 14:36:56 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 @@ -1007,7 +1007,7 @@ Content-Length: 272
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -1022,7 +1022,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: image/x-icon; charset=binary Expires: Tue, 15 Apr 2050 14:40:40 GMT @@ -1030,7 +1030,7 @@ Last-Modified: Mon, 15 Apr 2017 14:36:13 GMT Content-Length: 318 (( Fi " " " " " 33333HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 253 @@ -1045,7 +1045,7 @@ Content-Length: 253
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 273 @@ -1060,7 +1060,7 @@ Content-Length: 273
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 267 @@ -1075,7 +1075,7 @@ Content-Length: 267
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 280 @@ -1090,7 +1090,7 @@ Content-Length: 280
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 269 @@ -1105,7 +1105,7 @@ Content-Length: 269
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 271 @@ -1120,7 +1120,7 @@ Content-Length: 271
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 269 @@ -1135,7 +1135,7 @@ Content-Length: 269
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 271 @@ -1150,7 +1150,7 @@ Content-Length: 271
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 276 @@ -1165,7 +1165,7 @@ Content-Length: 276
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -1180,7 +1180,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 253 @@ -1195,7 +1195,7 @@ Content-Length: 253
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 249 @@ -1210,7 +1210,7 @@ Content-Length: 249
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 245 @@ -1225,10 +1225,10 @@ Content-Length: 245
ULib Server
HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 -Expires: Sat, 19 Jun 2021 14:36:51 GMT +Expires: Tue, 06 Jul 2021 14:39:59 GMT Last-Modified: Wed, 06 Jul 2011 16:28:46 GMT Content-Length: 1669 @@ -1274,7 +1274,7 @@ Content-Length: 1669 HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:00 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 253 @@ -1289,7 +1289,7 @@ Content-Length: 253
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:04 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 252 @@ -1304,7 +1304,7 @@ Content-Length: 252
ULib Server
HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:04 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Type: text/html; charset=UTF-8 Content-Length: 254 @@ -1319,37 +1319,37 @@ Content-Length: 254
ULib Server
HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:37:08 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Length: 13 Content-Type: text/plain Hello, World!HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:37:08 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Length: 13 Content-Type: text/plain Hello, World!HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:37:08 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Length: 13 Content-Type: text/plain Hello, World!HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:37:08 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Length: 13 Content-Type: text/plain Hello, World!HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:37:08 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Content-Length: 13 Content-Type: text/plain Hello, World!HTTP/1.1 404 Not Found -Date: Fri, 19 Jun 2020 14:37:08 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 @@ -1365,10 +1365,1421 @@ Content-Length: 255
ULib Server
HTTP/1.1 200 OK -Date: Fri, 19 Jun 2020 14:37:08 GMT +Date: Mon, 06 Jul 2020 14:39:58 GMT Server: ULib Connection: close -Set-Cookie: ulib.s0=5374657665204a6f686e736f6e2631353932363633383238262ac2a1b144695197ed86b565777986a6; expires=Sat, 20 Jun 2020 14:37:08 GMT +Set-Cookie: ulib.s0=5374657665204a6f686e736f6e2631353934313332383136265c3eb18662dfd38e4856703ee459541d; expires=Tue, 07 Jul 2020 14:40:16 GMT +Content-Length: 0 + + + + + + + + + + + + + +
Your file have been uploaded!

+ File #1: /uploads/vuoto.txt
+
+
+ Go Back
+ + + + + + + + + + + + + + +
Your file have been uploaded!

+ File #1: /uploads/operazione.xml
+
+
+ Go Back
+ + +HTTP/1.1 505 HTTP Version Not Supported +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Length: 0 + +HTTP/1.1 501 Not Implemented +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Type: text/html; charset=UTF-8 +Content-Length: 256 + + + +501 Not Implemented + +

Not Implemented

+

Sorry, the method you requested is not implemented

+
+
ULib Server
+ +HTTP/1.1 400 Bad Request +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Type: text/html; charset=UTF-8 +Content-Length: 263 + + + +400 Bad Request + +

Bad Request

+

Your browser sent a request that this server could not understand

+
+
ULib Server
+ +HTTP/1.1 400 Bad Request +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Type: text/html; charset=UTF-8 +Content-Length: 263 + + + +400 Bad Request + +

Bad Request

+

Your browser sent a request that this server could not understand

+
+
ULib Server
+ +HTTP/1.1 400 Bad Request +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Type: text/html; charset=UTF-8 +Content-Length: 263 + + + +400 Bad Request + +

Bad Request

+

Your browser sent a request that this server could not understand

+
+
ULib Server
+ +HTTP/1.1 411 Length Required +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Type: text/html; charset=UTF-8 +Content-Length: 273 + + + +411 Length Required + +

Length Required

+

Sorry, you must give the length of your data in your header request

+
+
ULib Server
+ +HTTP/1.1 413 Request Entity Too Large +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Type: text/html; charset=UTF-8 +Content-Length: 266 + + + +413 Request Entity Too Large + +

Request Entity Too Large

+

Sorry, the data you requested is too large

+
+
ULib Server
+ +HTTP/1.1 400 Bad Request +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Type: text/html; charset=UTF-8 +Content-Length: 263 + + + +400 Bad Request + +

Bad Request

+

Your browser sent a request that this server could not understand

+
+
ULib Server
+ +HTTP/1.1 400 Bad Request +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Type: text/html; charset=UTF-8 +Content-Length: 263 + + + +400 Bad Request + +

Bad Request

+

Your browser sent a request that this server could not understand

+
+
ULib Server
+ +HTTP/1.1 400 Bad Request +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Type: text/html; charset=UTF-8 +Content-Length: 263 + + + +400 Bad Request + +

Bad Request

+

Your browser sent a request that this server could not understand

+
+
ULib Server
+ +HTTP/1.1 400 Bad Request +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Type: text/html; charset=UTF-8 +Content-Length: 263 + + + +400 Bad Request + +

Bad Request

+

Your browser sent a request that this server could not understand

+
+
ULib Server
+ +HTTP/1.1 400 Bad Request +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Type: text/html; charset=UTF-8 +Content-Length: 263 + + + +400 Bad Request + +

Bad Request

+

Your browser sent a request that this server could not understand

+
+
ULib Server
+ +HTTP/1.1 400 Bad Request +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Type: text/html; charset=UTF-8 +Content-Length: 263 + + + +400 Bad Request + +

Bad Request

+

Your browser sent a request that this server could not understand

+
+
ULib Server
+ +HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Allow: GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE, CONNECT, COPY, MOVE, LOCK, UNLOCK, MKCOL, PROPFIND, PATCH, PURGE, MERGE, REPORT, CHECKOUT, MKACTIVITY, NOTIFY, MSEARCH, SUBSCRIBE, UNSUBSCRIBE +Content-Length: 0 + +HTTP/1.1 401 Authorization Required +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Type: text/html; charset=UTF-8 +WWW-Authenticate: Basic realm="Protected Area" +Content-Length: 444 + + + +401 Authorization Required + +

Authorization Required

+

This server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 257 + +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 344 + + + +404 Not Found + +

Not Found

+

Your requested URL "/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 403 Forbidden +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 304 + + + +403 Forbidden + +

Forbidden

+

You don't have permission to access "/../../../../linux/include/generated/uapi/linux/version.h" on this server

+
+
ULib Server
+ +HTTP/1.1 500 Internal Server Error +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 548 + + + +500 Internal Server Error + +

Internal Server Error

+

The server encountered an internal error or misconfiguration and was unable to complete your request. Please contact the server administrator, and inform them of the time the error occurred, and anything you might have done that may have caused the error. More information about this error may be available in the server error log

+
+
ULib Server
+ +HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/plain; charset=UTF-8 +Cache-Control: max-age=0, no-cache, no-store, must-revalidate +Pragma: no-cache +Expires: Sat, 1 Jan 2000 00:00:00 GMT +Content-Length: 21 + +pippo pluto paperino +HTTP/1.1 401 Authorization Required +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +WWW-Authenticate: Basic realm="Protected Area" +Content-Length: 444 + + + +401 Authorization Required + +

Authorization Required

+

This server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required

+
+
ULib Server
+ +HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Expires: Tue, 06 Jul 2021 14:40:19 GMT +Last-Modified: Fri, 20 Feb 2009 14:50:49 GMT +Content-Length: 63 + +this is the web_server testsuite inp/http/data/index.html file +HTTP/1.1 206 Partial Content +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Range: bytes 0-63/64 +Content-Type: application/octet-stream; charset=binary +Expires: Tue, 06 Jul 2021 14:40:20 GMT +Last-Modified: Sun, 24 Sep 2017 17:11:42 GMT +Content-Length: 64 + +123456781234567 +345678903456789 +34567892345678 +012345670123456 +HTTP/1.1 206 Partial Content +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Range: bytes 0-31/64 +Content-Type: application/octet-stream; charset=binary +Expires: Tue, 06 Jul 2021 14:40:20 GMT +Last-Modified: Sun, 24 Sep 2017 17:11:42 GMT +Content-Length: 32 + +123456781234567 +345678903456789 +HTTP/1.1 206 Partial Content +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Range: bytes 32-63/64 +Content-Type: application/octet-stream; charset=binary +Expires: Tue, 06 Jul 2021 14:40:20 GMT +Last-Modified: Sun, 24 Sep 2017 17:11:42 GMT +Content-Length: 32 + +34567892345678 +012345670123456 +HTTP/1.1 206 Partial Content +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Range: bytes 32-63/64 +Content-Type: text/plain; charset=us-ascii +Expires: Tue, 06 Jul 2021 14:40:20 GMT +Last-Modified: Sun, 24 Sep 2017 17:11:42 GMT +Content-Length: 32 + +234567892345678 +012345670123456 +HTTP/1.1 206 Partial Content +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Length: 227 +Content-Type: multipart/byteranges; boundary="=_6052942353682697120" + + +--=_6052942353682697120 +Content-Range: bytes 0-0/64 +Content-Type: text/html; charset=UTF-8 + +1 +--=_6052942353682697120 +Content-Range: bytes 63-63/64 +Content-Type: text/html; charset=UTF-8 + + + +--=_6052942353682697120--HTTP/1.1 206 Partial Content +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Range: bytes 50-63/64 +Content-Type: text/plain; charset=us-ascii +Expires: Tue, 06 Jul 2021 14:40:20 GMT +Last-Modified: Sun, 24 Sep 2017 17:11:42 GMT +Content-Length: 14 + +2345670123456 +HTTP/1.1 206 Partial Content +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Length: 247 +Content-Type: multipart/byteranges; boundary="=_6052942353682697121" + + +--=_6052942353682697121 +Content-Range: bytes 10-19/64 +Content-Type: text/html; charset=UTF-8 + +34567 +3456 +--=_6052942353682697121 +Content-Range: bytes 50-59/64 +Content-Type: text/html; charset=UTF-8 + +2345670123 +--=_6052942353682697121--HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/plain; charset=us-ascii +Expires: Tue, 06 Jul 2021 14:40:20 GMT +Last-Modified: Sun, 24 Sep 2017 17:11:42 GMT +Content-Length: 64 + +123456781234567 +345678903456789 +234567892345678 +012345670123456 +HTTP/1.1 204 No Content +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Length: 0 + +HTTP/1.1 204 No Content +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Length: 0 + +HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Encoding: gzip +Content-Type: text/html; charset=UTF-8 +Last-Modified: Sat, 04 Jul 2020 18:19:56 GMT +Content-Length: 291 + +HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Last-Modified: Sat, 04 Jul 2020 18:19:56 GMT +Content-Length: 558 + +Index of tmp

Index of directory: tmp


Up one level
c 4 Bytes06/07/2020 14:39:58

ULib Server
HTTP/1.1 304 Not Modified +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Length: 0 + +HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 1669 + + + + Welcome to ULib Web Server! + + + + +
+

Welcome to ULib Web Server!

+
+ + +
+ + + + + + +
+ + +HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Cache-Control: max-age=0, no-cache, no-store, must-revalidate +Pragma: no-cache +Expires: Sat, 1 Jan 2000 00:00:00 GMT +Content-Length: 1881 + +
+ssi_begin
+This page last updated: Friday, 30-Oct-2015 15:20:57 GMT
+
+ +1: ok + + +2: ok + + +3: ok + + +4: ok + + +
+SSI_BEGIN
+Name of user: nobody
+
+Document name: ssi1.shtml
+
+Document URI: /SSI/ssi1.shtml
+
+It's now: Monday, 06-Jul-2020 14:40:20 GMT
+
+It's now: Monday, 06-Jul-2020 16:40:20 CEST
+
+This page is:     179 Bytes
+
+This file last modified: April 02, 2019
+
+You're using: 
+
+$HTTP_X_SENDFILE: 
+
+
+start PRINTENV
+--------------
+QUERY_STRING=
+REQUEST_URI=/SSI/ssi1.shtml
+CONTENT_LENGTH=0
+REQUEST_METHOD=GET
+SCRIPT_NAME=/SSI/ssi1.shtml
+SERVER_NAME=stefano
+SERVER_PORT=8080
+HTTP_HOST=10.30.1.131
+SERVER_PROTOCOL=HTTP/1.1
+SERVER_ADDR=192.168.42.40
+DOCUMENT_ROOT=/mnt/data/storage/ulib/ULib-2.4.2/tests/examples/docroot
+SERVER_SOFTWARE=ULib/2.4.2
+REMOTE_PORT=60170
+REMOTE_ADDR=
+SESSION_ID=:0
+REQUEST_ID=:60170:0
+PWD=/mnt/data/storage/ulib/ULib-2.4.2/tests/examples/docroot
+PATH=/usr/local/bin:/usr/bin:/bin
+HTTP_X_SENDFILE=puppamelo
+--------------
+end   PRINTENV
+ 
+
+start LS
+--------------
+total 32
+drwxrwxrwx 3 nobody nobody 4096 Apr  2  2019 .
+drwxrwxrwx 7 nobody nobody 4096 Jul  6 16:39 ..
+drwxrwxrwx 3 nobody nobody 4096 Aug 25  2014 earth
+-rw-r--r-- 1 nobody nobody  179 Apr  2  2019 embed.c
+-rw-rw-rw- 1 nobody nobody  160 Mar 28  2011 index.shtml
+-rw-rw-rw- 1 nobody nobody  352 Nov  8  2011 menu.shtml
+-rw-rw-rw- 1 nobody nobody  917 Oct 30  2015 ssi1.shtml
+-rw-rw-rw- 1 nobody nobody 1190 Aug 25  2014 ssi2.shtml
+--------------
+end   LS
+
+start CGI
+--------------
+Content-Type: text/html
+
+You're not using Microsoft® Internet Explorer® 5.0
+--------------
+end   CGI
+SSI include failed!
+SSI include failed!
+/*int main(void) {
+  struct mg_context* ctx;
+  const char *options[] = {"listening_ports", LISTENING_PORT, NULL};
+
+  ctx = mg_start(callback, options);
+  pause();
+  return 0;
+}*/
+
+SSI_END
+
+ + +
+ssi_end
+
+HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Length: 115 +X-Real-IP: 10.30.1.131 +Set-Cookie: ulib.s1=; expires=Sun, 05 Jul 2020 14:40:20 GMT +Set-Cookie: ulib.s0=5374657665204a6f686e736f6e263135393431333238323026733a6a322a3bb89d35786c81a9c65f52; expires=Tue, 07 Jul 2020 14:40:20 GMT +Set-Cookie: TestCookie=pippo +Content-Type: text/html; charset=iso-8859-1 + +UID = Steve Johnson +HTTP_COOKIE = name1=value1, name2=value2; name3=value3, name4=value4 +ULIB_SESSION = +HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Encoding: gzip +Content-Type: text/html; charset=UTF-8 +Content-Length: 709 + +UW,W+SWlߛrēHL n +oMZR@"Ip% f NHzQjūI'8dS>a5l2ڠYS-k9\d9JitE?r-+rM%>|_&$Rp?Bs +x4勵dLȽ]z9YM<.#9wv4ӊϣ&"P?L/vc6>Oؿ[F-Rf:_BFp͐ 鐁/e2I[H*4\49I cmJJLLd/U=S1DW|jm siל,SYՍ>`sŭAФtf ԍ1)?)%?(~Kynm ?2Tz~oz+nw;eg`R}Fc*|"]G00VlS]3=CS^.'q=&+%θjrx_QğpDj\eu:p0+>V?w( /Uz&q]8WKA?jۺxfӹ-~(Aj%L0½ ֮8\ҮYXf幺gdkΘԃx)msw.MB[w{*HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Length: 72 +Content-Type: application/jsonrequest + +{"user":"doctoravatar@penzance.com","t":"vlIj","forecast":7,"zip":94089}HTTP/1.1 302 Moved Temporarily +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Type: text/html; charset=UTF-8 +Location: http://10.30.1.131/?ticket=U2FsdGVkX1+/AYaicDGB1EReb1+EErzD/ar1Wrv8wrXpYEj9RoN3RlzFWK5ykUyRMg4AicmBMNQsUQDWZENgiQ +X-Powered-By: PHP/5.2.6-pl7-gentoo +X-Powered-By: PHP/5.2.6-pl7-gentoo +Content-Length: 365 + + + +302 Moved Temporarily + +

Moved Temporarily

+

The document has moved here

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 253 + + + +404 Not Found + +

Not Found

+

Your requested URL "/uploader" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 253 + + + +404 Not Found + +

Not Found

+

Your requested URL "/uploader" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 253 + + + +404 Not Found + +

Not Found

+

Your requested URL "/uploader" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/info" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 400 Bad Request +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Type: text/html; charset=UTF-8 +Content-Length: 272 + + + +400 Bad Request + +

Bad Request

+

Your requested URL "/" was a request that this server could not understand

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/test" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: image/x-icon; charset=binary +Expires: Tue, 15 Apr 2050 14:40:40 GMT +Last-Modified: Mon, 15 Apr 2017 14:36:13 GMT +Content-Length: 318 + +(( Fi " " " " " 33333HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 253 + + + +404 Not Found + +

Not Found

+

Your requested URL "/dumbfuck" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 273 + + + +404 Not Found + +

Not Found

+

Your requested URL "/get_no_headers_no_body/world" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 267 + + + +404 Not Found + +

Not Found

+

Your requested URL "/get_one_header_no_body" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 280 + + + +404 Not Found + +

Not Found

+

Your requested URL "/get_funky_content_length_body_hello" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 269 + + + +404 Not Found + +

Not Found

+

Your requested URL "/post_identity_body_world" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 271 + + + +404 Not Found + +

Not Found

+

Your requested URL "/post_chunked_all_your_base" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 269 + + + +404 Not Found + +

Not Found

+

Your requested URL "/two_chunks_mult_zero_end" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 271 + + + +404 Not Found + +

Not Found

+

Your requested URL "/chunked_w_trailing_headers" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 276 + + + +404 Not Found + +

Not Found

+

Your requested URL "/chunked_w_bullshit_after_length" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/test" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 253 + + + +404 Not Found + +

Not Found

+

Your requested URL "/test.cgi" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 249 + + + +404 Not Found + +

Not Found

+

Your requested URL "/test" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 245 + + + +404 Not Found + +

Not Found

+

Your requested URL "*" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Expires: Tue, 06 Jul 2021 14:40:19 GMT +Last-Modified: Wed, 06 Jul 2011 16:28:46 GMT +Content-Length: 1669 + + + + Welcome to ULib Web Server! + + + + +
+

Welcome to ULib Web Server!

+
+ + +
+ + + + + + +
+ + +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 253 + + + +404 Not Found + +

Not Found

+

Your requested URL "/file.txt" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 252 + + + +404 Not Found + +

Not Found

+

Your requested URL "/bag.xml" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Type: text/html; charset=UTF-8 +Content-Length: 254 + + + +404 Not Found + +

Not Found

+

Your requested URL "/help.html" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Length: 13 +Content-Type: text/plain + +Hello, World!HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Length: 13 +Content-Type: text/plain + +Hello, World!HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Length: 13 +Content-Type: text/plain + +Hello, World!HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Length: 13 +Content-Type: text/plain + +Hello, World!HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Content-Length: 13 +Content-Type: text/plain + +Hello, World!HTTP/1.1 404 Not Found +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Content-Type: text/html; charset=UTF-8 +Content-Length: 255 + + + +404 Not Found + +

Not Found

+

Your requested URL "/plaintext1" was not found on this server

+
+
ULib Server
+ +HTTP/1.1 200 OK +Date: Mon, 06 Jul 2020 14:40:19 GMT +Server: ULib +Connection: close +Set-Cookie: ulib.s0=5374657665204a6f686e736f6e2631353934313332383336265758697b8cd13b6fb358b387b133575f; expires=Tue, 07 Jul 2020 14:40:36 GMT Content-Length: 0 diff --git a/tests/examples/tsa_ssoap.test b/tests/examples/tsa_ssoap.test index 0366b08b..dabeb81f 100755 --- a/tests/examples/tsa_ssoap.test +++ b/tests/examples/tsa_ssoap.test @@ -13,7 +13,7 @@ start_msg tsa_ssoap DOC_ROOT=TSA -rm -rf $DOC_ROOT/*log \ +rm -rf $DOC_ROOT/*log /tmp/*log \ out/userver_ssl.out err/userver_ssl.err \ trace.*userver_*.[0-9]* object.*userver_*.[0-9]* stack.*userver_*.[0-9]* mempool.*userver_*.[0-9]* \ $DOC_ROOT/trace.*userver_*.[0-9]* $DOC_ROOT/object.*userver_*.[0-9]* $DOC_ROOT/stack.*userver_*.[0-9]* $DOC_ROOT/mempool.*userver_*.[0-9]* @@ -64,7 +64,7 @@ cat <inp/webserver.cfg userver { REQ_TIMEOUT 5 MAX_KEEP_ALIVE 256 - LOG_FILE tsa_ssoap.log + LOG_FILE /tmp/tsa_ssoap.log LOG_FILE_SZ 1M DOCUMENT_ROOT TSA PLUGIN "soap http" diff --git a/tests/examples/udp_server.sh b/tests/examples/udp_server.sh index 29913309..784c1abc 100755 --- a/tests/examples/udp_server.sh +++ b/tests/examples/udp_server.sh @@ -11,7 +11,7 @@ rm -f tmp/usp_compile.sh.err /tmp/*.hpack.* \ /tmp/trace.*userver_*.[0-9]* /tmp/object.*userver_*.[0-9]* /tmp/stack.*userver_*.[0-9]* /tmp/mempool.*userver_*.[0-9]* \ $DOC_ROOT/trace.*userver_*.[0-9]* $DOC_ROOT/object.*userver_*.[0-9]* $DOC_ROOT/stack.*userver_*.[0-9]* $DOC_ROOT/mempool.*userver_*.[0-9]* - UTRACE="0 50M -1" + UTRACE="0 20M 0" UTRACE_SIGNAL="0 50M 0" UTRACE_FOLDER=/tmp #UOBJDUMP="0 10M 100" @@ -70,11 +70,9 @@ wait_server_ready localhost 4433 sync echo "PID = `cat /var/run/userver_udp.pid`" -$SLEEP $SLEEP curl -vvvv --http3 https://localhost:4433 & $SLEEP -$SLEEP killall userver_udp $SLEEP pkill userver_udp 2>/dev/null diff --git a/tests/examples/web_server.test b/tests/examples/web_server.test index d332954f..fdb10c28 100755 --- a/tests/examples/web_server.test +++ b/tests/examples/web_server.test @@ -16,7 +16,7 @@ start_msg web_server DOC_ROOT=docroot rm -f db/session.ssl* /tmp/ssl_session.txt /tmp/byterange* /tmp/soap.res /tmp/*.memusage.* /tmp/*.hpack.* \ - $DOC_ROOT/webserver*.log* $DOC_ROOT/uploads/* /var/log/httpd/access_log \ + /tmp/$DOC_ROOT/webserver*.log* $DOC_ROOT/webserver*.log* $DOC_ROOT/uploads/* /var/log/httpd/access_log \ out/userver_tcp.out err/userver_tcp.err web_server.err \ trace.*userver_*.[0-9]* object.*userver_*.[0-9]* stack.*userver_*.[0-9]* mempool.*userver_*.[0-9]* \ $DOC_ROOT/trace.*userver_*.[0-9]* $DOC_ROOT/object.*userver_*.[0-9]* $DOC_ROOT/stack.*userver_*.[0-9]* $DOC_ROOT/mempool.*userver_*.[0-9]* @@ -125,7 +125,7 @@ userver { #MIN_SIZE_FOR_SENDFILE 1k REQ_TIMEOUT 5 DOS_WHITE_LIST 127.0.0.1,10.30.0.0/16 - LOG_FILE webserver$1.log + LOG_FILE /tmp/webserver$1.log LOG_FILE_SZ 1M LOG_MSG_SIZE -1 DOCUMENT_ROOT $DOC_ROOT diff --git a/tests/examples/web_server_multiclient.test b/tests/examples/web_server_multiclient.test index 7634aa50..f7140f18 100755 --- a/tests/examples/web_server_multiclient.test +++ b/tests/examples/web_server_multiclient.test @@ -11,7 +11,7 @@ start_msg web_server_multiclient DOC_ROOT=benchmark/docroot -rm -f $DOC_ROOT/web_server_multiclient.log* \ +rm -f $DOC_ROOT/web_server_multiclient.log* /tmp/web_server_multiclient.log* \ out/userver_tcp.out err/userver_tcp.err err/web_server_multiclient.err \ trace.*userver_*.[0-9]* object.*userver_*.[0-9]* stack.*userver_*.[0-9]* mempool.*userver_*.[0-9]* \ $DOC_ROOT/trace.*userver_*.[0-9]* $DOC_ROOT/object.*userver_*.[0-9]* $DOC_ROOT/stack.*userver_*.[0-9]* $DOC_ROOT/mempool.*userver_*.[0-9]* @@ -31,10 +31,10 @@ userver { PORT 8080 RUN_AS_USER apache DOS_WHITE_LIST 127.0.0.1,10.30.0.0/16 - LOG_FILE web_server_multiclient.log + LOG_FILE /tmp/web_server_multiclient.log LOG_FILE_SZ 1M LOG_MSG_SIZE -1 -#REQ_TIMEOUT 5 + REQ_TIMEOUT 5 #MAX_KEEP_ALIVE 3 PID_FILE /var/run/userver_tcp.pid DOCUMENT_ROOT benchmark/docroot @@ -68,18 +68,20 @@ compile_usp #VALGRIND='valgrind --leak-check=yes --track-origins=yes' start_prg_background userver_tcp -c inp/webserver.cfg -wait_server_ready localhost 8080 +wait_server_ready 127.0.0.1 8080 + +#netstat -tulap > /tmp/netstat.out 2>&1 +#$CURL -v http://127.0.0.1:8080/1000.html > /tmp/curl.out 2>&1 #ab -k -n 2 -c 2 "http://$ADDRESS:8080/servlet/benchmarking?name=stefano" >/dev/null 2>&1 ab -k -n 100 -c 2 'http://127.0.0.1:8080/servlet/benchmarking?name=stefano' >/tmp/ab.out 2>&1 #ab -k -n 100000 -c 1000 'http://127.0.0.1:8080/servlet/benchmarking?name=stefano' >/tmp/ab.txt 2>&1 $SLEEP -$SLEEP kill_server userver_tcp mv err/userver_tcp.err err/web_server_multiclient.err -cat $DOC_ROOT/web_server_multiclient.log > out/web_server_multiclient.out +cp /tmp/web_server_multiclient.log out/web_server_multiclient.out # Test against expected output test_output_wc l web_server_multiclient diff --git a/tests/examples/web_server_rng.test b/tests/examples/web_server_rng.test index 4057a2a4..30302184 100755 --- a/tests/examples/web_server_rng.test +++ b/tests/examples/web_server_rng.test @@ -23,7 +23,7 @@ rm -f db/session.ssl* /tmp/ssl_session.txt /tmp/byterange* /tmp/soap.res /tmp/*. #chmod 666 /proc/sys/net/ipv4/tcp_fin_timeout /proc/sys/net/core/somaxconn /proc/sys/net/ipv4/tcp_max_syn_backlog - UTRACE="0 20M 0" +#UTRACE="0 20M 0" UTRACE_SIGNAL="0 50M -1" UTRACE_FOLDER=/tmp TMPDIR=/tmp @@ -198,8 +198,8 @@ export UMEMPOOL="136,0,60,100,250,-22,-17,-23,60" #creat_config 1 #start_test $NCAT localhost # webserver2 -#creat_config 2 -#start_test $NCAT localhost + creat_config 2 + start_test $NCAT localhost # webserverN #creat_config N 2 #start_test $NCAT localhost diff --git a/tests/examples/web_server_rng_multiclient.test b/tests/examples/web_server_rng_multiclient.test index 273556b0..5e436a46 100755 --- a/tests/examples/web_server_rng_multiclient.test +++ b/tests/examples/web_server_rng_multiclient.test @@ -44,7 +44,7 @@ userver { #PLUGIN "nocat ssi http" PLUGIN_DIR ../../../../src/ulib/net/server/plugin/.libs ORM_DRIVER_DIR ../../../../src/ulib/orm/driver/.libs - PREFORK_CHILD 0 + PREFORK_CHILD 2 } http { ALIAS "[ / /index.php ]" @@ -79,12 +79,11 @@ wait_server_ready localhost 8080 ab -k -n 100 -c 2 'http://127.0.0.1:8080/servlet/benchmarking?name=stefano' >/tmp/ab.out 2>&1 #ab -k -n 100000 -c 1000 'http://127.0.0.1:8080/servlet/benchmarking?name=stefano' >/tmp/ab.txt 2>&1 $SLEEP -$SLEEP kill_server userver_rng mv err/userver_rng.err err/web_server_rng_multiclient.err -cat /tmp/web_server_rng_multiclient.log > out/web_server_rng_multiclient.out +cp /tmp/web_server_rng_multiclient.log out/web_server_rng_multiclient.out # Test against expected output test_output_wc l web_server_rng_multiclient diff --git a/tests/ulib/ioring.test b/tests/ulib/ioring.test index 366ce1bd..9b4a4f5f 100755 --- a/tests/ulib/ioring.test +++ b/tests/ulib/ioring.test @@ -6,7 +6,7 @@ start_msg ioring -rm -rf err/ioring.err /tmp/ioring.log \ +rm -rf err/ioring.err out/ioring.out /tmp/ioring.log \ trace.*ioring*.[0-9]* object.*ioring*.[0-9]* stack.*ioring*.[0-9]* mempool.*ioring*.[0-9]* \ /tmp/trace.*ioring*.[0-9]* /tmp/object.*ioring*.[0-9]* /tmp/stack.*ioring*.[0-9]* /tmp/mempool.*ioring*.[0-9]* @@ -28,7 +28,7 @@ userver { PORT 8080 RUN_AS_USER nobody #MIN_SIZE_FOR_SENDFILE 1k -#REQ_TIMEOUT 5 + REQ_TIMEOUT 5 WELCOME_MSG "220 david.unirel.intranet LCSP server (Version 1.1.0) ready.\n" DOS_WHITE_LIST 127.0.0.1,10.30.0.0/16 LOG_FILE /tmp/ioring.log @@ -44,8 +44,8 @@ userver { } http { CACHE_FILE_MASK _off_ -#ENABLE_INOTIFY yes -#REQUEST_READ_TIMEOUT 30 + ENABLE_INOTIFY yes + REQUEST_READ_TIMEOUT 30 APACHE_LIKE_LOG /var/log/httpd/access_log } EOF @@ -57,7 +57,7 @@ start_prg_background ioring ../examples/inp/webserver.cfg wait_server_ready localhost 8080 #../examples/sendbytes.pl -#$SLEEP +$SLEEP send_req $NCAT localhost 8080 inp/http/form_enctype.http ioring 5 kill #ln -s ../examples/benchmark/docroot/servlet