From 51953ac760b7f04c3cac05b04cf42b8d5658a4d6 Mon Sep 17 00:00:00 2001 From: Leif Hedstrom Date: Thu, 27 Feb 2020 16:37:32 -0700 Subject: [PATCH 1/7] First refactoring, eliminates many of the lookup APIs --- example/plugins/c-api/remap/remap.cc | 2 +- .../plugins/c-api/vconn_args/vconn_args.cc | 4 +- include/ts/apidefs.h.in | 8 +++ include/ts/ts.h | 35 ++++++------ plugins/authproxy/authproxy.cc | 6 ++- plugins/esi/combo_handler.cc | 2 +- .../ja3_fingerprint/ja3_fingerprint.cc | 4 +- .../experimental/remap_stats/remap_stats.cc | 2 +- .../experimental/traffic_dump/traffic_dump.cc | 2 +- plugins/xdebug/Cleanup.h | 2 +- proxy/InkAPIInternal.h | 2 +- src/traffic_server/InkAPI.cc | 53 +++++++++---------- src/tscpp/api/utils_internal.cc | 2 +- 13 files changed, 67 insertions(+), 57 deletions(-) diff --git a/example/plugins/c-api/remap/remap.cc b/example/plugins/c-api/remap/remap.cc index 2f437407b56..d23c5ef721d 100644 --- a/example/plugins/c-api/remap/remap.cc +++ b/example/plugins/c-api/remap/remap.cc @@ -267,7 +267,7 @@ TSRemapDoRemap(void *ih, TSHttpTxn rh, TSRemapRequestInfo *rri) } // How to store plugin private arguments inside Traffic Server request processing block. - if (TSHttpTxnArgIndexReserve("remap_example", "Example remap plugin", &arg_index) == TS_SUCCESS) { + if (TSUserArgIndexReserve(TSUserArgType::TXN, "remap_example", "Example remap plugin", &arg_index) == TS_SUCCESS) { TSDebug(PLUGIN_NAME, "Save processing counter %" PRIu64 " inside request processing block\n", _processing_counter); TSHttpTxnArgSet(rh, arg_index, (void *)_processing_counter); // save counter } diff --git a/example/plugins/c-api/vconn_args/vconn_args.cc b/example/plugins/c-api/vconn_args/vconn_args.cc index 2185dbe1f01..217f2070b74 100644 --- a/example/plugins/c-api/vconn_args/vconn_args.cc +++ b/example/plugins/c-api/vconn_args/vconn_args.cc @@ -37,7 +37,7 @@ vconn_arg_handler(TSCont contp, TSEvent event, void *edata) case TS_EVENT_VCONN_START: { // Testing set argument int idx = 0; - while (TSVConnArgIndexReserve(PLUGIN_NAME, "test", &idx) == TS_SUCCESS) { + while (TSUserArgIndexReserve(TSUserArgType::VCONN, PLUGIN_NAME, "test", &idx) == TS_SUCCESS) { char *buf = static_cast(TSmalloc(64)); snprintf(buf, 64, "Test Arg Idx %d", idx); TSVConnArgSet(ssl_vc, idx, (void *)buf); @@ -52,7 +52,7 @@ vconn_arg_handler(TSCont contp, TSEvent event, void *edata) while (idx <= last_arg) { const char *name = nullptr; const char *desc = nullptr; - if (TSVConnArgIndexLookup(idx, &name, &desc) == TS_SUCCESS) { + if (TSUserArgIndexLookup(TSUserArgType::VCONN, idx, &name, &desc) == TS_SUCCESS) { TSDebug(PLUGIN_NAME, "Successful lookup for arg #%d: [%s] [%s]", idx, name, desc); } else { TSDebug(PLUGIN_NAME, "Failed lookup for arg #%d", idx); diff --git a/include/ts/apidefs.h.in b/include/ts/apidefs.h.in index e71bd0bd8b6..2efdf2deb81 100644 --- a/include/ts/apidefs.h.in +++ b/include/ts/apidefs.h.in @@ -878,6 +878,14 @@ typedef enum { TS_MGMT_SOURCE_ENV ///< Process environment variable. } TSMgmtSource; +/// The User Arg type, used for Txn/Ssn/VConn user argument slots +typedef enum { + TXN, ///< Transaction based. + SSN, ///< Session based + VCONN, ///< VConnection based + COUNT ///< Fake enum, # of valid entries. +} TSUserArgType; + typedef struct tsapi_file *TSFile; typedef struct tsapi_mloc *TSMLoc; diff --git a/include/ts/ts.h b/include/ts/ts.h index 983abf2112b..b10467385a5 100644 --- a/include/ts/ts.h +++ b/include/ts/ts.h @@ -1548,6 +1548,13 @@ tsapi void TSHttpTxnTransformedRespCache(TSHttpTxn txnp, int on); tsapi void TSHttpTxnReenable(TSHttpTxn txnp, TSEvent event); tsapi TSReturnCode TSHttpCacheReenable(TSCacheTxn txnp, const TSEvent event, const void *data, const uint64_t size); +/* The reserve API should only be use in TSAPI plugins, during plugin initialization! + The lookup methods can be used anytime, but are best used during initialization as well, + or at least "cache" the results for best performance. */ +tsapi TSReturnCode TSUserArgIndexReserve(TSUserArgType type, const char *name, const char *description, int *arg_idx); +tsapi TSReturnCode TSUserArgIndexNameLookup(TSUserArgType type, const char *name, int *arg_idx, const char **description); +tsapi TSReturnCode TSUserArgIndexLookup(TSUserArgType type, int arg_idx, const char **name, const char **description); + tsapi void TSHttpTxnArgSet(TSHttpTxn txnp, int arg_idx, void *arg); tsapi void *TSHttpTxnArgGet(TSHttpTxn txnp, int arg_idx); tsapi void TSHttpSsnArgSet(TSHttpSsn ssnp, int arg_idx, void *arg); @@ -1555,18 +1562,16 @@ tsapi void *TSHttpSsnArgGet(TSHttpSsn ssnp, int arg_idx); tsapi void TSVConnArgSet(TSVConn connp, int arg_idx, void *arg); tsapi void *TSVConnArgGet(TSVConn connp, int arg_idx); -/* The reserve API should only be use in TSAPI plugins, during plugin initialization! */ -/* The lookup methods can be used anytime, but are best used during initialization as well, - or at least "cache" the results for best performance. */ -tsapi TSReturnCode TSHttpTxnArgIndexReserve(const char *name, const char *description, int *arg_idx); -tsapi TSReturnCode TSHttpTxnArgIndexNameLookup(const char *name, int *arg_idx, const char **description); -tsapi TSReturnCode TSHttpTxnArgIndexLookup(int arg_idx, const char **name, const char **description); -tsapi TSReturnCode TSHttpSsnArgIndexReserve(const char *name, const char *description, int *arg_idx); -tsapi TSReturnCode TSHttpSsnArgIndexNameLookup(const char *name, int *arg_idx, const char **description); -tsapi TSReturnCode TSHttpSsnArgIndexLookup(int arg_idx, const char **name, const char **description); -tsapi TSReturnCode TSVConnArgIndexReserve(const char *name, const char *description, int *arg_idx); -tsapi TSReturnCode TSVConnArgIndexNameLookup(const char *name, int *arg_idx, const char **description); -tsapi TSReturnCode TSVConnArgIndexLookup(int arg_idx, const char **name, const char **description); +/* These are deprecated as of v9.0.0, and will be removed in v10.0.0 */ +tsapi TS_DEPRECATED TSReturnCode TSHttpTxnArgIndexReserve(const char *name, const char *description, int *arg_idx); +tsapi TS_DEPRECATED TSReturnCode TSHttpTxnArgIndexNameLookup(const char *name, int *arg_idx, const char **description); +tsapi TS_DEPRECATED TSReturnCode TSHttpTxnArgIndexLookup(int arg_idx, const char **name, const char **description); +tsapi TS_DEPRECATED TSReturnCode TSHttpSsnArgIndexReserve(const char *name, const char *description, int *arg_idx); +tsapi TS_DEPRECATED TSReturnCode TSHttpSsnArgIndexNameLookup(const char *name, int *arg_idx, const char **description); +tsapi TS_DEPRECATED TSReturnCode TSHttpSsnArgIndexLookup(int arg_idx, const char **name, const char **description); +tsapi TS_DEPRECATED TSReturnCode TSVConnArgIndexReserve(const char *name, const char *description, int *arg_idx); +tsapi TS_DEPRECATED TSReturnCode TSVConnArgIndexNameLookup(const char *name, int *arg_idx, const char **description); +tsapi TS_DEPRECATED TSReturnCode TSVConnArgIndexLookup(int arg_idx, const char **name, const char **description); tsapi void TSHttpTxnStatusSet(TSHttpTxn txnp, TSHttpStatus status); tsapi TSHttpStatus TSHttpTxnStatusGet(TSHttpTxn txnp); @@ -2504,9 +2509,9 @@ tsapi const char *TSHttpSsnClientProtocolStackContains(TSHttpSsn ssnp, char cons tsapi const char *TSNormalizedProtocolTag(char const *tag); tsapi const char *TSRegisterProtocolTag(char const *tag); -// If, for the given transaction, the URL has been remapped, this function puts the memory location of the "from" URL object in the -// variable pointed to by urlLocp, and returns TS_SUCCESS. (The URL object will be within memory allocated to the transaction -// object.) Otherwise, the function returns TS_ERROR. +// If, for the given transaction, the URL has been remapped, this function puts the memory location of the "from" URL object in +// the variable pointed to by urlLocp, and returns TS_SUCCESS. (The URL object will be within memory allocated to the +// transaction object.) Otherwise, the function returns TS_ERROR. // tsapi TSReturnCode TSRemapFromUrlGet(TSHttpTxn txnp, TSMLoc *urlLocp); diff --git a/plugins/authproxy/authproxy.cc b/plugins/authproxy/authproxy.cc index b3d2d2c45db..e5d7291a111 100644 --- a/plugins/authproxy/authproxy.cc +++ b/plugins/authproxy/authproxy.cc @@ -736,7 +736,8 @@ TSPluginInit(int argc, const char *argv[]) AuthLogError("plugin registration failed"); } - TSReleaseAssert(TSHttpTxnArgIndexReserve("AuthProxy", "AuthProxy authorization tag", &AuthTaggedRequestArg) == TS_SUCCESS); + TSReleaseAssert(TSUserArgIndexReserve(TSUserArgType::TXN, "AuthProxy", "AuthProxy authorization tag", &AuthTaggedRequestArg) == + TS_SUCCESS); AuthOsDnsContinuation = TSContCreate(AuthProxyGlobalHook, nullptr); AuthGlobalOptions = AuthParseOptions(argc, argv); @@ -749,7 +750,8 @@ TSPluginInit(int argc, const char *argv[]) TSReturnCode TSRemapInit(TSRemapInterface * /* api ATS_UNUSED */, char * /* err ATS_UNUSED */, int /* errsz ATS_UNUSED */) { - TSReleaseAssert(TSHttpTxnArgIndexReserve("AuthProxy", "AuthProxy authorization tag", &AuthTaggedRequestArg) == TS_SUCCESS); + TSReleaseAssert(TSUserArgIndexReserve(TSUserArgType::TXN, "AuthProxy", "AuthProxy authorization tag", &AuthTaggedRequestArg) == + TS_SUCCESS); AuthOsDnsContinuation = TSContCreate(AuthProxyGlobalHook, nullptr); return TS_SUCCESS; diff --git a/plugins/esi/combo_handler.cc b/plugins/esi/combo_handler.cc index 6aae5c78926..0705a035513 100644 --- a/plugins/esi/combo_handler.cc +++ b/plugins/esi/combo_handler.cc @@ -438,7 +438,7 @@ TSPluginInit(int argc, const char *argv[]) TSHttpHookAdd(TS_HTTP_OS_DNS_HOOK, rrh_contp); - if (TSHttpTxnArgIndexReserve(DEBUG_TAG, "will save plugin-enable flag here", &arg_idx) != TS_SUCCESS) { + if (TSUserArgIndexReserve(TSUserArgType::TXN, DEBUG_TAG, "will save plugin-enable flag here", &arg_idx) != TS_SUCCESS) { LOG_ERROR("failed to reserve private data slot"); return; } else { diff --git a/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc b/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc index dc0486a504c..d598124d0bf 100644 --- a/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc +++ b/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc @@ -444,7 +444,7 @@ TSPluginInit(int argc, const char *argv[]) } // SNI handler TSCont ja3_cont = TSContCreate(client_hello_ja3_handler, nullptr); - TSVConnArgIndexReserve(PLUGIN_NAME, "used to pass ja3", &ja3_idx); + TSUserArgIndexReserve(TSUserArgType::VCONN, PLUGIN_NAME, "used to pass ja3", &ja3_idx); #if OPENSSL_VERSION_NUMBER < 0x10100000L TSHttpHookAdd(TS_SSL_SERVERNAME_HOOK, ja3_cont); #elif OPENSSL_VERSION_NUMBER >= 0x10101000L @@ -473,7 +473,7 @@ TSRemapInit(TSRemapInterface *api_info, char *errbuf, int errbuf_size) // Set up SNI handler for all TLS connections TSCont ja3_cont = TSContCreate(client_hello_ja3_handler, nullptr); - TSVConnArgIndexReserve(PLUGIN_NAME, "Used to pass ja3", &ja3_idx); + TSUserArgIndexReserve(TSUserArgType::VCONN, PLUGIN_NAME, "Used to pass ja3", &ja3_idx); #if OPENSSL_VERSION_NUMBER < 0x10100000L TSHttpHookAdd(TS_SSL_SERVERNAME_HOOK, ja3_cont); #elif OPENSSL_VERSION_NUMBER >= 0x10101000L diff --git a/plugins/experimental/remap_stats/remap_stats.cc b/plugins/experimental/remap_stats/remap_stats.cc index df252d372e2..f3ba3b03985 100644 --- a/plugins/experimental/remap_stats/remap_stats.cc +++ b/plugins/experimental/remap_stats/remap_stats.cc @@ -273,7 +273,7 @@ TSPluginInit(int argc, const char *argv[]) } } - TSHttpTxnArgIndexReserve(PLUGIN_NAME, "txn data", &(config->txn_slot)); + TSUserArgIndexReserve(TSUserArgType::TXN, PLUGIN_NAME, "txn data", &(config->txn_slot)); if (!config->post_remap_host) { pre_remap_cont = TSContCreate(handle_read_req_hdr, nullptr); diff --git a/plugins/experimental/traffic_dump/traffic_dump.cc b/plugins/experimental/traffic_dump/traffic_dump.cc index f915ce54679..66ef9592b89 100644 --- a/plugins/experimental/traffic_dump/traffic_dump.cc +++ b/plugins/experimental/traffic_dump/traffic_dump.cc @@ -645,7 +645,7 @@ TSPluginInit(int argc, const char *argv[]) if (TS_SUCCESS != TSPluginRegister(&info)) { TSError("[%s] Unable to initialize plugin (disabled). Failed to register plugin.", PLUGIN_NAME); - } else if (TS_SUCCESS != TSHttpSsnArgIndexReserve(PLUGIN_NAME, "Track log related data", &s_arg_idx)) { + } else if (TS_SUCCESS != TSUserArgIndexReserve(TSUserArgType::SSN, PLUGIN_NAME, "Track log related data", &s_arg_idx)) { TSError("[%s] Unable to initialize plugin (disabled). Failed to reserve ssn arg.", PLUGIN_NAME); } else { /// Add global hooks diff --git a/plugins/xdebug/Cleanup.h b/plugins/xdebug/Cleanup.h index 453903c1c2b..5a758032e35 100644 --- a/plugins/xdebug/Cleanup.h +++ b/plugins/xdebug/Cleanup.h @@ -145,7 +145,7 @@ template class TxnAuxDataMgr : private return; } - TSReleaseAssert(TSHttpTxnArgIndexReserve(arg_name, arg_desc, &md.txnArgIndex) == TS_SUCCESS); + TSReleaseAssert(TSUserArgIndexReserve(TSUserArgType::TXN, arg_name, arg_desc, &md.txnArgIndex) == TS_SUCCESS); TSReleaseAssert(md.txnCloseContp = TSContCreate(_deleteAuxData, nullptr)); } diff --git a/proxy/InkAPIInternal.h b/proxy/InkAPIInternal.h index 4a90f3518ef..d6870968939 100644 --- a/proxy/InkAPIInternal.h +++ b/proxy/InkAPIInternal.h @@ -40,7 +40,7 @@ /* Some defines that might be candidates for configurable settings later. */ -#define TS_HTTP_MAX_USER_ARG 16 /* max number of user arguments for Transactions and Sessions */ +static constexpr int TS_HTTP_MAX_USER_ARG = 16; /* max number of user arguments for Transactions and Sessions */ typedef int8_t TSMgmtByte; // Not for external use diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index b91712e4478..ce49504d85f 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -102,22 +102,16 @@ static RecRawStatBlock *api_rsb; /** Reservation for a user arg. */ struct UserArg { - /// Types of user args. - enum Type { - TXN, ///< Transaction based. - SSN, ///< Session based - VCONN, ///< VConnection based - COUNT ///< Fake enum, # of valid entries. - }; - + TSUserArgType type; std::string name; ///< Name of reserving plugin. std::string description; ///< Description of use for this arg. }; /// Table of reservations, indexed by type and then index. -UserArg UserArgTable[UserArg::Type::COUNT][TS_HTTP_MAX_USER_ARG]; +UserArg UserArgTable[TSUserArgType::COUNT][std::max(TS_HTTP_MAX_USER_ARG, TS_VCONN_MAX_USER_ARG)]; + /// Table of next reserved index. -std::atomic UserArgIdx[UserArg::Type::COUNT]; +std::atomic UserArgIdx[TSUserArgType::COUNT]; /* URL schemes */ tsapi const char *TS_URL_SCHEME_FILE; @@ -6103,29 +6097,30 @@ TSHttpTxnReenable(TSHttpTxn txnp, TSEvent event) eventProcessor.schedule_imm(cb, ET_NET); } -TSReturnCode TSHttpArgIndexNameLookup(UserArg::Type type, const char *name, int *arg_idx, const char **description); +TSReturnCode TSUserArgIndexNameLookup(TSUserArgType type, const char *name, int *arg_idx, const char **description); TSReturnCode -TSHttpArgIndexReserve(UserArg::Type type, const char *name, const char *description, int *ptr_idx) +TSUserArgIndexReserve(TSUserArgType type, const char *name, const char *description, int *ptr_idx) { sdk_assert(sdk_sanity_check_null_ptr(ptr_idx) == TS_SUCCESS); sdk_assert(sdk_sanity_check_null_ptr(name) == TS_SUCCESS); - sdk_assert(0 <= type && type < UserArg::Type::COUNT); + sdk_assert(0 <= type && type < TSUserArgType::COUNT); int idx; /* Since this function is meant to be called during plugin initialization we could end up "leaking" indices during plugins reload. - * Make sure we allocate 1 index per name, also current TSHttpArgIndexNameLookup() implementation assumes 1-1 relationship as + * Make sure we allocate 1 index per name, also current TSUserArgIndexNameLookup() implementation assumes 1-1 relationship as * well. */ const char *desc; - if (TS_SUCCESS == TSHttpArgIndexNameLookup(type, name, &idx, &desc)) { + + if (TS_SUCCESS == TSUserArgIndexNameLookup(type, name, &idx, &desc)) { // Found existing index. *ptr_idx = idx; return TS_SUCCESS; } idx = UserArgIdx[type]++; - int limit = (type == UserArg::Type::VCONN) ? TS_VCONN_MAX_USER_ARG : TS_HTTP_MAX_USER_ARG; + int limit = (type == TSUserArgType::VCONN) ? TS_VCONN_MAX_USER_ARG : TS_HTTP_MAX_USER_ARG; if (idx < limit) { UserArg &arg(UserArgTable[type][idx]); @@ -6141,9 +6136,9 @@ TSHttpArgIndexReserve(UserArg::Type type, const char *name, const char *descript } TSReturnCode -TSHttpArgIndexLookup(UserArg::Type type, int idx, const char **name, const char **description) +TSUserArgIndexLookup(TSUserArgType type, int idx, const char **name, const char **description) { - sdk_assert(0 <= type && type < UserArg::Type::COUNT); + sdk_assert(0 <= type && type < TSUserArgType::COUNT); if (sdk_sanity_check_null_ptr(name) == TS_SUCCESS) { if (idx < UserArgIdx[type]) { UserArg &arg(UserArgTable[type][idx]); @@ -6159,10 +6154,10 @@ TSHttpArgIndexLookup(UserArg::Type type, int idx, const char **name, const char // Not particularly efficient, but good enough for now. TSReturnCode -TSHttpArgIndexNameLookup(UserArg::Type type, const char *name, int *arg_idx, const char **description) +TSUserArgIndexNameLookup(TSUserArgType type, const char *name, int *arg_idx, const char **description) { sdk_assert(sdk_sanity_check_null_ptr(arg_idx) == TS_SUCCESS); - sdk_assert(0 <= type && type < UserArg::Type::COUNT); + sdk_assert(0 <= type && type < TSUserArgType::COUNT); std::string_view n{name}; @@ -6182,55 +6177,55 @@ TSHttpArgIndexNameLookup(UserArg::Type type, const char *name, int *arg_idx, con TSReturnCode TSHttpTxnArgIndexReserve(const char *name, const char *description, int *arg_idx) { - return TSHttpArgIndexReserve(UserArg::TXN, name, description, arg_idx); + return TSUserArgIndexReserve(TSUserArgType::TXN, name, description, arg_idx); } TSReturnCode TSHttpTxnArgIndexLookup(int arg_idx, const char **name, const char **description) { - return TSHttpArgIndexLookup(UserArg::TXN, arg_idx, name, description); + return TSUserArgIndexLookup(TSUserArgType::TXN, arg_idx, name, description); } TSReturnCode TSHttpTxnArgIndexNameLookup(const char *name, int *arg_idx, const char **description) { - return TSHttpArgIndexNameLookup(UserArg::TXN, name, arg_idx, description); + return TSUserArgIndexNameLookup(TSUserArgType::TXN, name, arg_idx, description); } TSReturnCode TSHttpSsnArgIndexReserve(const char *name, const char *description, int *arg_idx) { - return TSHttpArgIndexReserve(UserArg::SSN, name, description, arg_idx); + return TSUserArgIndexReserve(TSUserArgType::SSN, name, description, arg_idx); } TSReturnCode TSHttpSsnArgIndexLookup(int arg_idx, const char **name, const char **description) { - return TSHttpArgIndexLookup(UserArg::SSN, arg_idx, name, description); + return TSUserArgIndexLookup(TSUserArgType::SSN, arg_idx, name, description); } TSReturnCode TSHttpSsnArgIndexNameLookup(const char *name, int *arg_idx, const char **description) { - return TSHttpArgIndexNameLookup(UserArg::SSN, name, arg_idx, description); + return TSUserArgIndexNameLookup(TSUserArgType::SSN, name, arg_idx, description); } TSReturnCode TSVConnArgIndexReserve(const char *name, const char *description, int *arg_idx) { - return TSHttpArgIndexReserve(UserArg::VCONN, name, description, arg_idx); + return TSUserArgIndexReserve(TSUserArgType::VCONN, name, description, arg_idx); } TSReturnCode TSVConnArgIndexLookup(int arg_idx, const char **name, const char **description) { - return TSHttpArgIndexLookup(UserArg::VCONN, arg_idx, name, description); + return TSUserArgIndexLookup(TSUserArgType::VCONN, arg_idx, name, description); } TSReturnCode TSVConnArgIndexNameLookup(const char *name, int *arg_idx, const char **description) { - return TSHttpArgIndexNameLookup(UserArg::VCONN, name, arg_idx, description); + return TSUserArgIndexNameLookup(TSUserArgType::VCONN, name, arg_idx, description); } void diff --git a/src/tscpp/api/utils_internal.cc b/src/tscpp/api/utils_internal.cc index 923c48d961a..39a80ec711d 100644 --- a/src/tscpp/api/utils_internal.cc +++ b/src/tscpp/api/utils_internal.cc @@ -99,7 +99,7 @@ void setupTransactionManagement() { // Reserve a transaction slot - TSAssert(TS_SUCCESS == TSHttpTxnArgIndexReserve("atscppapi", "ATS CPP API", &TRANSACTION_STORAGE_INDEX)); + TSAssert(TS_SUCCESS == TSUserArgIndexReserve(TSUserArgType::TXN, "atscppapi", "ATS CPP API", &TRANSACTION_STORAGE_INDEX)); // We must always have a cleanup handler available TSMutex mutex = nullptr; TSCont cont = TSContCreate(handleTransactionEvents, mutex); From 374af4443ceecf3b74f2353fe91b80a638083e1b Mon Sep 17 00:00:00 2001 From: Leif Hedstrom Date: Fri, 28 Feb 2020 14:14:58 -0700 Subject: [PATCH 2/7] Refactor all User Args, deprecating all old APIs for Get() / Set(). --- example/plugins/c-api/remap/remap.cc | 4 +- .../plugins/c-api/vconn_args/vconn_args.cc | 4 +- include/ts/ts.h | 16 +++-- include/tscore/PluginUserArgs.h | 70 +++++++++++++++++++ iocore/eventsystem/I_VConnection.h | 42 ++--------- iocore/net/I_NetVConnection.h | 4 +- plugins/authproxy/authproxy.cc | 6 +- plugins/esi/combo_handler.cc | 6 +- .../ja3_fingerprint/ja3_fingerprint.cc | 8 +-- .../experimental/remap_stats/remap_stats.cc | 10 +-- .../experimental/traffic_dump/traffic_dump.cc | 6 +- plugins/xdebug/Cleanup.h | 6 +- proxy/InkAPIInternal.h | 2 - proxy/ProxySession.cc | 5 +- proxy/ProxySession.h | 36 +++++----- proxy/http/HttpSM.h | 2 +- proxy/http/HttpTransact.h | 3 - src/traffic_server/InkAPI.cc | 54 ++++++++++---- src/tscpp/api/utils_internal.cc | 4 +- 19 files changed, 171 insertions(+), 117 deletions(-) create mode 100644 include/tscore/PluginUserArgs.h diff --git a/example/plugins/c-api/remap/remap.cc b/example/plugins/c-api/remap/remap.cc index d23c5ef721d..7a3b3190fcc 100644 --- a/example/plugins/c-api/remap/remap.cc +++ b/example/plugins/c-api/remap/remap.cc @@ -269,7 +269,7 @@ TSRemapDoRemap(void *ih, TSHttpTxn rh, TSRemapRequestInfo *rri) // How to store plugin private arguments inside Traffic Server request processing block. if (TSUserArgIndexReserve(TSUserArgType::TXN, "remap_example", "Example remap plugin", &arg_index) == TS_SUCCESS) { TSDebug(PLUGIN_NAME, "Save processing counter %" PRIu64 " inside request processing block\n", _processing_counter); - TSHttpTxnArgSet(rh, arg_index, (void *)_processing_counter); // save counter + TSUserArgSet(rh, arg_index, (void *)_processing_counter); // save counter } // How to cancel request processing and return error message to the client // We will do it every other request @@ -321,7 +321,7 @@ TSRemapDoRemap(void *ih, TSHttpTxn rh, TSRemapRequestInfo *rri) void TSRemapOSResponse(void *ih ATS_UNUSED, TSHttpTxn rh, int os_response_type) { - void *data = TSHttpTxnArgGet(rh, arg_index); // read counter (we store it in TSRemapDoRemap function call) + void *data = TSUserArgGet(rh, arg_index); // read counter (we store it in TSRemapDoRemap function call) int request_id = data ? static_cast(data)[0] : -1; TSDebug(PLUGIN_NAME, "Read processing counter %d from request processing block\n", request_id); diff --git a/example/plugins/c-api/vconn_args/vconn_args.cc b/example/plugins/c-api/vconn_args/vconn_args.cc index 217f2070b74..6f9f0fbb428 100644 --- a/example/plugins/c-api/vconn_args/vconn_args.cc +++ b/example/plugins/c-api/vconn_args/vconn_args.cc @@ -40,7 +40,7 @@ vconn_arg_handler(TSCont contp, TSEvent event, void *edata) while (TSUserArgIndexReserve(TSUserArgType::VCONN, PLUGIN_NAME, "test", &idx) == TS_SUCCESS) { char *buf = static_cast(TSmalloc(64)); snprintf(buf, 64, "Test Arg Idx %d", idx); - TSVConnArgSet(ssl_vc, idx, (void *)buf); + TSUserArgSet(ssl_vc, idx, (void *)buf); TSDebug(PLUGIN_NAME, "Successfully reserve and set arg #%d", idx); } last_arg = idx; @@ -65,7 +65,7 @@ vconn_arg_handler(TSCont contp, TSEvent event, void *edata) // Testing argget and delete int idx = 0; while (idx <= last_arg) { - char *buf = static_cast(TSVConnArgGet(ssl_vc, idx)); + char *buf = static_cast(TSUserArgGet(ssl_vc, idx)); if (buf) { TSDebug(PLUGIN_NAME, "Successfully retrieve vconn arg #%d: %s", idx, buf); TSfree(buf); diff --git a/include/ts/ts.h b/include/ts/ts.h index b10467385a5..b18ce03bb87 100644 --- a/include/ts/ts.h +++ b/include/ts/ts.h @@ -1554,15 +1554,17 @@ tsapi TSReturnCode TSHttpCacheReenable(TSCacheTxn txnp, const TSEvent event, con tsapi TSReturnCode TSUserArgIndexReserve(TSUserArgType type, const char *name, const char *description, int *arg_idx); tsapi TSReturnCode TSUserArgIndexNameLookup(TSUserArgType type, const char *name, int *arg_idx, const char **description); tsapi TSReturnCode TSUserArgIndexLookup(TSUserArgType type, int arg_idx, const char **name, const char **description); - -tsapi void TSHttpTxnArgSet(TSHttpTxn txnp, int arg_idx, void *arg); -tsapi void *TSHttpTxnArgGet(TSHttpTxn txnp, int arg_idx); -tsapi void TSHttpSsnArgSet(TSHttpSsn ssnp, int arg_idx, void *arg); -tsapi void *TSHttpSsnArgGet(TSHttpSsn ssnp, int arg_idx); -tsapi void TSVConnArgSet(TSVConn connp, int arg_idx, void *arg); -tsapi void *TSVConnArgGet(TSVConn connp, int arg_idx); +tsapi void TSUserArgSet(void *data, int arg_idx, void *arg); +tsapi void *TSUserArgGet(void *data, int arg_idx); /* These are deprecated as of v9.0.0, and will be removed in v10.0.0 */ +tsapi TS_DEPRECATED void TSHttpTxnArgSet(TSHttpTxn txnp, int arg_idx, void *arg); +tsapi TS_DEPRECATED void *TSHttpTxnArgGet(TSHttpTxn txnp, int arg_idx); +tsapi TS_DEPRECATED void TSHttpSsnArgSet(TSHttpSsn ssnp, int arg_idx, void *arg); +tsapi TS_DEPRECATED void *TSHttpSsnArgGet(TSHttpSsn ssnp, int arg_idx); +tsapi TS_DEPRECATED void TSVConnArgSet(TSVConn connp, int arg_idx, void *arg); +tsapi TS_DEPRECATED void *TSVConnArgGet(TSVConn connp, int arg_idx); + tsapi TS_DEPRECATED TSReturnCode TSHttpTxnArgIndexReserve(const char *name, const char *description, int *arg_idx); tsapi TS_DEPRECATED TSReturnCode TSHttpTxnArgIndexNameLookup(const char *name, int *arg_idx, const char **description); tsapi TS_DEPRECATED TSReturnCode TSHttpTxnArgIndexLookup(int arg_idx, const char **name, const char **description); diff --git a/include/tscore/PluginUserArgs.h b/include/tscore/PluginUserArgs.h new file mode 100644 index 00000000000..3df8fd1b635 --- /dev/null +++ b/include/tscore/PluginUserArgs.h @@ -0,0 +1,70 @@ +/** @file + + Base class and implementation details for the User Args features. + + @section license License + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#pragma once + +#include +#include "tscore/ink_assert.h" + +static constexpr int MAX_USER_ARGS_TXN = 16; /* max number of user arguments for Transactions */ +static constexpr int MAX_USER_ARGS_SSN = 8; /* max number of user arguments for Sessions (for now) */ +static constexpr int MAX_USER_ARGS_VCONN = 4; /* max number of VConnection user arguments */ +// static constexpr int MAX_USER_ARGS_GLB = 128; /* max number of user arguments, globally */ + +/** + This is a mixin class (sort of), implementing the appropriate APIs and data storage for + a particular user arg table. Used by VConn / Ssn / Txn user arg data. +*/ +class PluginUserArgsMixin +{ +public: + virtual void *get_user_arg(unsigned ix) const = 0; + virtual void set_user_arg(unsigned ix, void *arg) = 0; +}; + +template class PluginUserArgs : public virtual PluginUserArgsMixin +{ +public: + void * + get_user_arg(unsigned ix) const + { + ink_assert(ix < user_args.size()); + return this->user_args[ix]; + }; + + void + set_user_arg(unsigned ix, void *arg) + { + ink_assert(ix < user_args.size()); + user_args[ix] = arg; + }; + + void + clear() + { + user_args.fill(nullptr); + } + +private: + std::array user_args{{nullptr}}; +}; diff --git a/iocore/eventsystem/I_VConnection.h b/iocore/eventsystem/I_VConnection.h index 80a7218f08e..674191a08ce 100644 --- a/iocore/eventsystem/I_VConnection.h +++ b/iocore/eventsystem/I_VConnection.h @@ -25,16 +25,13 @@ #pragma once #include "tscore/ink_platform.h" +#include "tscore/PluginUserArgs.h" #include "I_EventSystem.h" #if !defined(I_VIO_h) #error "include I_VIO.h" #endif -#include - -static constexpr int TS_VCONN_MAX_USER_ARG = 4; - // // Data Types // @@ -149,7 +146,7 @@ typedef struct tsapi_vio *TSVIO; It is also a Continuation that is called back from processors. */ -class VConnection : public Continuation +class VConnection : public Continuation, public PluginUserArgs { public: ~VConnection() override; @@ -378,38 +375,7 @@ class VConnection : public Continuation int lerrno; }; -/** - Subclass of VConnection to provide support for user arguments - - Inherited by DummyVConnection (down to INKContInternal) and NetVConnection -*/ -class AnnotatedVConnection : public VConnection -{ - using self_type = AnnotatedVConnection; - using super_type = VConnection; - -public: - explicit AnnotatedVConnection(ProxyMutex *aMutex) : super_type(aMutex){}; - explicit AnnotatedVConnection(Ptr &aMutex) : super_type(aMutex){}; - - void * - get_user_arg(unsigned ix) const - { - ink_assert(ix < user_args.size()); - return this->user_args[ix]; - }; - void - set_user_arg(unsigned ix, void *arg) - { - ink_assert(ix < user_args.size()); - user_args[ix] = arg; - }; - -protected: - std::array user_args{{nullptr}}; -}; - -struct DummyVConnection : public AnnotatedVConnection { +struct DummyVConnection : public VConnection { VIO * do_io_write(Continuation * /* c ATS_UNUSED */, int64_t /* nbytes ATS_UNUSED */, IOBufferReader * /* buf ATS_UNUSED */, bool /* owner ATS_UNUSED */) override @@ -440,5 +406,5 @@ struct DummyVConnection : public AnnotatedVConnection { "cannot use default implementation"); } - explicit DummyVConnection(ProxyMutex *m) : AnnotatedVConnection(m) {} + explicit DummyVConnection(ProxyMutex *m) : VConnection(m) {} }; diff --git a/iocore/net/I_NetVConnection.h b/iocore/net/I_NetVConnection.h index 1e3feba14c0..0ce385cecb1 100644 --- a/iocore/net/I_NetVConnection.h +++ b/iocore/net/I_NetVConnection.h @@ -332,7 +332,7 @@ struct NetVCOptions { stream IO to be done based on a single read or write call. */ -class NetVConnection : public AnnotatedVConnection +class NetVConnection : public VConnection { public: // How many bytes have been queued to the OS for sending by haven't been sent yet @@ -888,7 +888,7 @@ class NetVConnection : public AnnotatedVConnection NetVConnectionContext_t netvc_context = NET_VCONNECTION_UNSET; }; -inline NetVConnection::NetVConnection() : AnnotatedVConnection(nullptr) +inline NetVConnection::NetVConnection() : VConnection(nullptr) { ink_zero(local_addr); diff --git a/plugins/authproxy/authproxy.cc b/plugins/authproxy/authproxy.cc index e5d7291a111..e5d364c3054 100644 --- a/plugins/authproxy/authproxy.cc +++ b/plugins/authproxy/authproxy.cc @@ -170,7 +170,7 @@ struct AuthRequestContext { { AuthOptions *opt; - opt = static_cast(TSHttpTxnArgGet(this->txn, AuthTaggedRequestArg)); + opt = static_cast(TSUserArgGet(this->txn, AuthTaggedRequestArg)); return opt ? opt : AuthGlobalOptions; } @@ -621,7 +621,7 @@ StateAuthorized(AuthRequestContext *auth, void *) static bool AuthRequestIsTagged(TSHttpTxn txn) { - return AuthTaggedRequestArg != -1 && TSHttpTxnArgGet(txn, AuthTaggedRequestArg) != nullptr; + return AuthTaggedRequestArg != -1 && TSUserArgGet(txn, AuthTaggedRequestArg) != nullptr; } static int @@ -787,7 +787,7 @@ TSRemapDoRemap(void *instance, TSHttpTxn txn, TSRemapRequestInfo * /* rri ATS_UN { AuthOptions *options = static_cast(instance); - TSHttpTxnArgSet(txn, AuthTaggedRequestArg, options); + TSUserArgSet(txn, AuthTaggedRequestArg, options); TSHttpTxnHookAdd(txn, TS_HTTP_POST_REMAP_HOOK, AuthOsDnsContinuation); return TSREMAP_NO_REMAP; diff --git a/plugins/esi/combo_handler.cc b/plugins/esi/combo_handler.cc index 0705a035513..00649c10eae 100644 --- a/plugins/esi/combo_handler.cc +++ b/plugins/esi/combo_handler.cc @@ -469,7 +469,7 @@ handleReadRequestHeader(TSCont /* contp ATS_UNUSED */, TSEvent event, void *edat return 0; } - if (1 != reinterpret_cast(TSHttpTxnArgGet(txnp, arg_idx))) { + if (1 != reinterpret_cast(TSUserArgGet(txnp, arg_idx))) { LOG_DEBUG("combo is disabled for this channel"); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; @@ -1228,8 +1228,8 @@ writeErrorResponse(InterceptData &int_data, int &n_bytes_written) TSRemapStatus TSRemapDoRemap(void *ih, TSHttpTxn rh, TSRemapRequestInfo *rri) { - TSHttpTxnArgSet(rh, arg_idx, (void *)1); /* Save for later hooks */ - return TSREMAP_NO_REMAP; /* Continue with next remap plugin in chain */ + TSUserArgSet(rh, arg_idx, (void *)1); /* Save for later hooks */ + return TSREMAP_NO_REMAP; /* Continue with next remap plugin in chain */ } /* diff --git a/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc b/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc index d598124d0bf..0fcfe2b3cd0 100644 --- a/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc +++ b/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc @@ -311,7 +311,7 @@ client_hello_ja3_handler(TSCont contp, TSEvent event, void *edata) data->ja3_string.append(custom_get_ja3(ssl)); getIP(TSNetVConnRemoteAddrGet(ssl_vc), data->ip_addr); - TSVConnArgSet(ssl_vc, ja3_idx, static_cast(data)); + TSUserArgSet(ssl_vc, ja3_idx, static_cast(data)); TSDebug(PLUGIN_NAME, "client_hello_ja3_handler(): JA3: %s", data->ja3_string.c_str()); // MD5 hash @@ -326,14 +326,14 @@ client_hello_ja3_handler(TSCont contp, TSEvent event, void *edata) } case TS_EVENT_VCONN_CLOSE: { // Clean up - ja3_data *data = static_cast(TSVConnArgGet(ssl_vc, ja3_idx)); + ja3_data *data = static_cast(TSUserArgGet(ssl_vc, ja3_idx)); if (data == nullptr) { TSDebug(PLUGIN_NAME, "client_hello_ja3_handler(): Failed to retrieve ja3 data at VCONN_CLOSE."); return TS_ERROR; } - TSVConnArgSet(ssl_vc, ja3_idx, nullptr); + TSUserArgSet(ssl_vc, ja3_idx, nullptr); delete data; break; @@ -361,7 +361,7 @@ req_hdr_ja3_handler(TSCont contp, TSEvent event, void *edata) } // Retrieve ja3_data from vconn args - ja3_data *data = static_cast(TSVConnArgGet(vconn, ja3_idx)); + ja3_data *data = static_cast(TSUserArgGet(vconn, ja3_idx)); if (data) { // Decide global or remap ja3_remap_info *info = static_cast(TSContDataGet(contp)); diff --git a/plugins/experimental/remap_stats/remap_stats.cc b/plugins/experimental/remap_stats/remap_stats.cc index f3ba3b03985..24e06e299ee 100644 --- a/plugins/experimental/remap_stats/remap_stats.cc +++ b/plugins/experimental/remap_stats/remap_stats.cc @@ -116,7 +116,7 @@ handle_read_req_hdr(TSCont cont, TSEvent event ATS_UNUSED, void *edata) config = static_cast(TSContDataGet(cont)); txnd = (void *)get_effective_host(txn); // low bit left 0 because we do not know that remap succeeded yet - TSHttpTxnArgSet(txn, config->txn_slot, txnd); + TSUserArgSet(txn, config->txn_slot, txnd); TSHttpTxnReenable(txn, TS_EVENT_HTTP_CONTINUE); TSDebug(DEBUG_TAG, "Read Req Handler Finished"); @@ -133,10 +133,10 @@ handle_post_remap(TSCont cont, TSEvent event ATS_UNUSED, void *edata) config = static_cast(TSContDataGet(cont)); if (config->post_remap_host) { - TSHttpTxnArgSet(txn, config->txn_slot, txnd); + TSUserArgSet(txn, config->txn_slot, txnd); } else { - txnd = (void *)((uintptr_t)txnd | (uintptr_t)TSHttpTxnArgGet(txn, config->txn_slot)); // We need the hostname pre-remap - TSHttpTxnArgSet(txn, config->txn_slot, txnd); + txnd = (void *)((uintptr_t)txnd | (uintptr_t)TSUserArgGet(txn, config->txn_slot)); // We need the hostname pre-remap + TSUserArgSet(txn, config->txn_slot, txnd); } TSHttpTxnReenable(txn, TS_EVENT_HTTP_CONTINUE); @@ -163,7 +163,7 @@ handle_txn_close(TSCont cont, TSEvent event ATS_UNUSED, void *edata) static char const *const unknown = "unknown"; config_t const *const config = static_cast(TSContDataGet(cont)); - void const *const txnd = TSHttpTxnArgGet(txn, config->txn_slot); + void const *const txnd = TSUserArgGet(txn, config->txn_slot); hostname = reinterpret_cast(reinterpret_cast(txnd) & ~0x01); // Get hostname diff --git a/plugins/experimental/traffic_dump/traffic_dump.cc b/plugins/experimental/traffic_dump/traffic_dump.cc index 66ef9592b89..3e330a3171c 100644 --- a/plugins/experimental/traffic_dump/traffic_dump.cc +++ b/plugins/experimental/traffic_dump/traffic_dump.cc @@ -360,7 +360,7 @@ session_txn_handler(TSCont contp, TSEvent event, void *edata) // Retrieve SsnData TSHttpSsn ssnp = TSHttpTxnSsnGet(txnp); - SsnData *ssnData = static_cast(TSHttpSsnArgGet(ssnp, s_arg_idx)); + SsnData *ssnData = static_cast(TSUserArgGet(ssnp, s_arg_idx)); // If no valid ssnData, continue transaction as if nothing happened if (!ssnData) { @@ -499,7 +499,7 @@ global_ssn_handler(TSCont contp, TSEvent event, void *edata) // Create new per session data SsnData *ssnData = new SsnData; - TSHttpSsnArgSet(ssnp, s_arg_idx, ssnData); + TSUserArgSet(ssnp, s_arg_idx, ssnData); TSContDataSet(ssnData->aio_cont, ssnData); @@ -573,7 +573,7 @@ global_ssn_handler(TSCont contp, TSEvent event, void *edata) int64_t id = TSHttpSsnIdGet(ssnp); TSDebug(PLUGIN_NAME, "global_ssn_handler(): Closing session %" PRId64 "...", id); // Retrieve SsnData - SsnData *ssnData = static_cast(TSHttpSsnArgGet(ssnp, s_arg_idx)); + SsnData *ssnData = static_cast(TSUserArgGet(ssnp, s_arg_idx)); // If no valid ssnData, continue transaction as if nothing happened if (!ssnData) { TSDebug(PLUGIN_NAME, "global_ssn_handler(): [TS_EVENT_HTTP_SSN_CLOSE] No ssnData found. Abort."); diff --git a/plugins/xdebug/Cleanup.h b/plugins/xdebug/Cleanup.h index 5a758032e35..cd09a7c1ca9 100644 --- a/plugins/xdebug/Cleanup.h +++ b/plugins/xdebug/Cleanup.h @@ -158,11 +158,11 @@ template class TxnAuxDataMgr : private TSAssert(md.txnArgIndex >= 0); - auto d = static_cast(TSHttpTxnArgGet(txn, md.txnArgIndex)); + auto d = static_cast(TSUserArgGet(txn, md.txnArgIndex)); if (!d) { d = new TxnAuxData; - TSHttpTxnArgSet(txn, md.txnArgIndex, d); + TSUserArgSet(txn, md.txnArgIndex, d); TSHttpTxnHookAdd(txn, TS_HTTP_TXN_CLOSE_HOOK, md.txnCloseContp); } @@ -176,7 +176,7 @@ template class TxnAuxDataMgr : private MgrData_ &md = access(MDRef); auto txn = static_cast(edata); - auto data = static_cast(TSHttpTxnArgGet(txn, md.txnArgIndex)); + auto data = static_cast(TSUserArgGet(txn, md.txnArgIndex)); delete data; TSHttpTxnReenable(txn, TS_EVENT_HTTP_CONTINUE); return 0; diff --git a/proxy/InkAPIInternal.h b/proxy/InkAPIInternal.h index d6870968939..5d79c9accc0 100644 --- a/proxy/InkAPIInternal.h +++ b/proxy/InkAPIInternal.h @@ -40,8 +40,6 @@ /* Some defines that might be candidates for configurable settings later. */ -static constexpr int TS_HTTP_MAX_USER_ARG = 16; /* max number of user arguments for Transactions and Sessions */ - typedef int8_t TSMgmtByte; // Not for external use /* ****** Cache Structure ********* */ diff --git a/proxy/ProxySession.cc b/proxy/ProxySession.cc index e64e7b94d21..ef910eadd50 100644 --- a/proxy/ProxySession.cc +++ b/proxy/ProxySession.cc @@ -26,10 +26,7 @@ #include "ProxySession.h" #include "P_SSLNetVConnection.h" -ProxySession::ProxySession() : VConnection(nullptr) -{ - ink_zero(this->user_args); -} +ProxySession::ProxySession() : VConnection(nullptr) {} void ProxySession::set_session_active() diff --git a/proxy/ProxySession.h b/proxy/ProxySession.h index e3003944eb0..ce511014770 100644 --- a/proxy/ProxySession.h +++ b/proxy/ProxySession.h @@ -74,8 +74,10 @@ struct ProxyError { }; /// Abstract class for HttpSM to interface with any session -class ProxySession : public VConnection +class ProxySession : public VConnection, public PluginUserArgs { + using pua_type = PluginUserArgs; + public: ProxySession(); @@ -126,10 +128,6 @@ class ProxySession : public VConnection // Non-Virtual Methods int do_api_callout(TSHttpHookID id); - // Non-Virtual Accessors - void *get_user_arg(unsigned ix) const; - void set_user_arg(unsigned ix, void *arg); - void set_debug(bool flag); bool debug() const; @@ -161,6 +159,19 @@ class ProxySession : public VConnection ink_hrtime ssn_start_time = 0; ink_hrtime ssn_last_txn_time = 0; + // Necessary, because, C++. Thanks Alan! + void * + get_user_arg(unsigned ix) const override + { + return this->pua_type::get_user_arg(ix); + } + + void + set_user_arg(unsigned ix, void *arg) override + { + return this->pua_type::set_user_arg(ix, arg); + } + protected: // Hook dispatching state HttpHookState hook_state; @@ -185,7 +196,6 @@ class ProxySession : public VConnection APIHook const *cur_hook = nullptr; HttpAPIHooks api_hooks; - void *user_args[TS_HTTP_MAX_USER_ARG]; // for DI. An active connection is one that a request has // been successfully parsed (PARSE_DONE) and it remains to @@ -207,20 +217,6 @@ ProxySession::next_connection_id() return ink_atomic_increment(&next_cs_id, 1); } -inline void * -ProxySession::get_user_arg(unsigned ix) const -{ - ink_assert(ix < countof(user_args)); - return this->user_args[ix]; -} - -inline void -ProxySession::set_user_arg(unsigned ix, void *arg) -{ - ink_assert(ix < countof(user_args)); - user_args[ix] = arg; -} - inline void ProxySession::set_debug(bool flag) { diff --git a/proxy/http/HttpSM.h b/proxy/http/HttpSM.h index c33acf4bd89..8855620fcb9 100644 --- a/proxy/http/HttpSM.h +++ b/proxy/http/HttpSM.h @@ -199,7 +199,7 @@ class PostDataBuffers ~PostDataBuffers(); }; -class HttpSM : public Continuation +class HttpSM : public Continuation, public PluginUserArgs { friend class HttpPagesHandler; friend class CoreUtils; diff --git a/proxy/http/HttpTransact.h b/proxy/http/HttpTransact.h index b031a6c56da..ca4009795fe 100644 --- a/proxy/http/HttpTransact.h +++ b/proxy/http/HttpTransact.h @@ -759,8 +759,6 @@ class HttpTransact // for authenticated content caching CacheAuth_t www_auth_content = CACHE_AUTH_NONE; - // INK API/Remap API plugin interface - void *user_args[TS_HTTP_MAX_USER_ARG]; RemapPluginInst *os_response_plugin_inst = nullptr; HTTPStatus http_return_code = HTTP_STATUS_NONE; @@ -855,7 +853,6 @@ class HttpTransact via_string[VIA_DETAIL_SERVER_DESCRIPTOR] = VIA_DETAIL_SERVER_DESCRIPTOR_STRING; via_string[MAX_VIA_INDICES] = '\0'; - memset(user_args, 0, sizeof(user_args)); memset((void *)&host_db_info, 0, sizeof(host_db_info)); } diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index ce49504d85f..337141e89fa 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -30,6 +30,7 @@ #include "tscore/ink_platform.h" #include "tscore/ink_base64.h" +#include "tscore/PluginUserArgs.h" #include "tscore/I_Layout.h" #include "tscore/I_Version.h" @@ -108,7 +109,7 @@ struct UserArg { }; /// Table of reservations, indexed by type and then index. -UserArg UserArgTable[TSUserArgType::COUNT][std::max(TS_HTTP_MAX_USER_ARG, TS_VCONN_MAX_USER_ARG)]; +UserArg UserArgTable[TSUserArgType::COUNT][std::max(MAX_USER_ARGS_TXN, MAX_USER_ARGS_VCONN)]; /// Table of next reserved index. std::atomic UserArgIdx[TSUserArgType::COUNT]; @@ -6120,7 +6121,7 @@ TSUserArgIndexReserve(TSUserArgType type, const char *name, const char *descript } idx = UserArgIdx[type]++; - int limit = (type == TSUserArgType::VCONN) ? TS_VCONN_MAX_USER_ARG : TS_HTTP_MAX_USER_ARG; + int limit = (type == TSUserArgType::VCONN) ? MAX_USER_ARGS_VCONN : MAX_USER_ARGS_TXN; if (idx < limit) { UserArg &arg(UserArgTable[type][idx]); @@ -6173,6 +6174,32 @@ TSUserArgIndexNameLookup(TSUserArgType type, const char *name, int *arg_idx, con return TS_ERROR; } +// ------------- +void +TSUserArgSet(void *data, int arg_idx, void *arg) +{ + if (nullptr != data) { + PluginUserArgsMixin *user_args = dynamic_cast(static_cast(data)); + + user_args->set_user_arg(arg_idx, arg); + } else { + // This will be a special case later for the GLB + } +} + +void * +TSUserArgGet(void *data, int arg_idx) +{ + if (nullptr != data) { + PluginUserArgsMixin *user_args = dynamic_cast(static_cast(data)); + + return user_args->get_user_arg(arg_idx); + } else { + // This will be a special case later for the GLB + return nullptr; + } +} + // ------------- TSReturnCode TSHttpTxnArgIndexReserve(const char *name, const char *description, int *arg_idx) @@ -6232,27 +6259,28 @@ void TSHttpTxnArgSet(TSHttpTxn txnp, int arg_idx, void *arg) { sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS); - sdk_assert(arg_idx >= 0 && arg_idx < TS_HTTP_MAX_USER_ARG); + sdk_assert(arg_idx >= 0 && arg_idx < MAX_USER_ARGS_TXN); + + HttpSM *sm = reinterpret_cast(txnp); - HttpSM *sm = reinterpret_cast(txnp); - sm->t_state.user_args[arg_idx] = arg; + sm->set_user_arg(arg_idx, arg); } void * TSHttpTxnArgGet(TSHttpTxn txnp, int arg_idx) { sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS); - sdk_assert(arg_idx >= 0 && arg_idx < TS_HTTP_MAX_USER_ARG); + sdk_assert(arg_idx >= 0 && arg_idx < MAX_USER_ARGS_TXN); HttpSM *sm = reinterpret_cast(txnp); - return sm->t_state.user_args[arg_idx]; + return sm->get_user_arg(arg_idx); } void TSHttpSsnArgSet(TSHttpSsn ssnp, int arg_idx, void *arg) { sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS); - sdk_assert(arg_idx >= 0 && arg_idx < TS_HTTP_MAX_USER_ARG); + sdk_assert(arg_idx >= 0 && arg_idx < MAX_USER_ARGS_SSN); ProxySession *cs = reinterpret_cast(ssnp); @@ -6263,7 +6291,7 @@ void * TSHttpSsnArgGet(TSHttpSsn ssnp, int arg_idx) { sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS); - sdk_assert(arg_idx >= 0 && arg_idx < TS_HTTP_MAX_USER_ARG); + sdk_assert(arg_idx >= 0 && arg_idx < MAX_USER_ARGS_SSN); ProxySession *cs = reinterpret_cast(ssnp); return cs->get_user_arg(arg_idx); @@ -6273,8 +6301,8 @@ void TSVConnArgSet(TSVConn connp, int arg_idx, void *arg) { sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS); - sdk_assert(arg_idx >= 0 && arg_idx < TS_VCONN_MAX_USER_ARG); - AnnotatedVConnection *avc = reinterpret_cast(connp); + sdk_assert(arg_idx >= 0 && arg_idx < MAX_USER_ARGS_VCONN); + VConnection *avc = reinterpret_cast(connp); avc->set_user_arg(arg_idx, arg); } @@ -6282,9 +6310,9 @@ void * TSVConnArgGet(TSVConn connp, int arg_idx) { sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS); - sdk_assert(arg_idx >= 0 && arg_idx < TS_VCONN_MAX_USER_ARG); + sdk_assert(arg_idx >= 0 && arg_idx < MAX_USER_ARGS_VCONN); - AnnotatedVConnection *avc = reinterpret_cast(connp); + VConnection *avc = reinterpret_cast(connp); return avc->get_user_arg(arg_idx); } diff --git a/src/tscpp/api/utils_internal.cc b/src/tscpp/api/utils_internal.cc index 39a80ec711d..364599b9f87 100644 --- a/src/tscpp/api/utils_internal.cc +++ b/src/tscpp/api/utils_internal.cc @@ -153,11 +153,11 @@ void inline invokePluginForEvent(Plugin *plugin, TSHttpTxn ats_txn_handle, TSEve Transaction & utils::internal::getTransaction(TSHttpTxn ats_txn_handle) { - Transaction *transaction = static_cast(TSHttpTxnArgGet(ats_txn_handle, TRANSACTION_STORAGE_INDEX)); + Transaction *transaction = static_cast(TSUserArgGet(ats_txn_handle, TRANSACTION_STORAGE_INDEX)); if (!transaction) { transaction = new Transaction(static_cast(ats_txn_handle)); LOG_DEBUG("Created new transaction object at %p for ats pointer %p", transaction, ats_txn_handle); - TSHttpTxnArgSet(ats_txn_handle, TRANSACTION_STORAGE_INDEX, transaction); + TSUserArgSet(ats_txn_handle, TRANSACTION_STORAGE_INDEX, transaction); } return *transaction; } From 1897deb08b1859ce73124e4dc30b55bc4e0ea6d7 Mon Sep 17 00:00:00 2001 From: Leif Hedstrom Date: Sat, 29 Feb 2020 14:59:48 -0700 Subject: [PATCH 3/7] Adds the global / GLB type of user args --- include/ts/apidefs.h.in | 9 +++++---- include/tscore/PluginUserArgs.h | 8 ++++---- src/traffic_server/InkAPI.cc | 14 ++++++-------- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/include/ts/apidefs.h.in b/include/ts/apidefs.h.in index 2efdf2deb81..428b3cc30c1 100644 --- a/include/ts/apidefs.h.in +++ b/include/ts/apidefs.h.in @@ -880,10 +880,11 @@ typedef enum { /// The User Arg type, used for Txn/Ssn/VConn user argument slots typedef enum { - TXN, ///< Transaction based. - SSN, ///< Session based - VCONN, ///< VConnection based - COUNT ///< Fake enum, # of valid entries. + TXN, ///< Transaction based. + SSN, ///< Session based + VCONN, ///< VConnection based + TS_USER_ARGS_GLB, ///< Global based + COUNT ///< Fake enum, # of valid entries. } TSUserArgType; typedef struct tsapi_file *TSFile; diff --git a/include/tscore/PluginUserArgs.h b/include/tscore/PluginUserArgs.h index 3df8fd1b635..1d53dfbe62e 100644 --- a/include/tscore/PluginUserArgs.h +++ b/include/tscore/PluginUserArgs.h @@ -26,10 +26,10 @@ #include #include "tscore/ink_assert.h" -static constexpr int MAX_USER_ARGS_TXN = 16; /* max number of user arguments for Transactions */ -static constexpr int MAX_USER_ARGS_SSN = 8; /* max number of user arguments for Sessions (for now) */ -static constexpr int MAX_USER_ARGS_VCONN = 4; /* max number of VConnection user arguments */ -// static constexpr int MAX_USER_ARGS_GLB = 128; /* max number of user arguments, globally */ +static constexpr int MAX_USER_ARGS_TXN = 16; /* max number of user arguments for Transactions */ +static constexpr int MAX_USER_ARGS_SSN = 8; /* max number of user arguments for Sessions (for now) */ +static constexpr int MAX_USER_ARGS_VCONN = 4; /* max number of VConnection user arguments */ +static constexpr int MAX_USER_ARGS_GLB = 128; /* max number of user arguments, globally */ /** This is a mixin class (sort of), implementing the appropriate APIs and data storage for diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index 337141e89fa..ee2f0dd833d 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -108,11 +108,10 @@ struct UserArg { std::string description; ///< Description of use for this arg. }; -/// Table of reservations, indexed by type and then index. -UserArg UserArgTable[TSUserArgType::COUNT][std::max(MAX_USER_ARGS_TXN, MAX_USER_ARGS_VCONN)]; - -/// Table of next reserved index. -std::atomic UserArgIdx[TSUserArgType::COUNT]; +// Managing the user args tables, and the global storage (which is assumed to be the biggest, by far). +UserArg UserArgTable[TSUserArgType::COUNT][MAX_USER_ARGS_GLB]; +static PluginUserArgs global_user_args; +std::atomic UserArgIdx[TSUserArgType::COUNT]; // Table of next reserved index. /* URL schemes */ tsapi const char *TS_URL_SCHEME_FILE; @@ -6183,7 +6182,7 @@ TSUserArgSet(void *data, int arg_idx, void *arg) user_args->set_user_arg(arg_idx, arg); } else { - // This will be a special case later for the GLB + global_user_args.set_user_arg(arg_idx, arg); } } @@ -6195,8 +6194,7 @@ TSUserArgGet(void *data, int arg_idx) return user_args->get_user_arg(arg_idx); } else { - // This will be a special case later for the GLB - return nullptr; + return global_user_args.get_user_arg(arg_idx); } } From 54f2fb5bf6d0474c4fc9fa98c74efefab53a7be9 Mon Sep 17 00:00:00 2001 From: Leif Hedstrom Date: Mon, 2 Mar 2020 08:52:32 -0700 Subject: [PATCH 4/7] Adds a plugin for testing the APIs, can maybe be used by autest --- tests/tools/plugins/user_args.cc | 230 +++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 tests/tools/plugins/user_args.cc diff --git a/tests/tools/plugins/user_args.cc b/tests/tools/plugins/user_args.cc new file mode 100644 index 00000000000..854655a6d6d --- /dev/null +++ b/tests/tools/plugins/user_args.cc @@ -0,0 +1,230 @@ +/** @file + + Test and verify all the user args APIs. + + @section license License + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#include +#include +#include +#include + +#define NEW_APIS 1 + +typedef struct { + int TXN, SSN, VCONN, GLB; + TSCont contp; +} ArgIndexes; + +const char *PLUGIN_NAME = "user_args_test"; +ArgIndexes gIX; + +bool +set_header(TSMBuffer bufp, TSMLoc hdr_loc, const char *header, const char *val) +{ + if (!bufp || !hdr_loc || !header || !val) { + return false; + } + + bool ret = false; + TSMLoc field_loc = TSMimeHdrFieldFind(bufp, hdr_loc, header, strlen(header)); + + TSReleaseAssert(!field_loc); // The headers are for testing, should never exist + if (TS_SUCCESS == TSMimeHdrFieldCreateNamed(bufp, hdr_loc, header, strlen(header), &field_loc)) { + if (TS_SUCCESS == TSMimeHdrFieldValueStringSet(bufp, hdr_loc, field_loc, -1, val, strlen(val))) { + TSMimeHdrFieldAppend(bufp, hdr_loc, field_loc); + ret = true; + } + TSHandleMLocRelease(bufp, hdr_loc, field_loc); + } + + return ret; +} + +static int +cont_global(TSCont contp, TSEvent event, void *edata) +{ + TSHttpTxn txnp = static_cast(edata); + TSHttpSsn ssnp = TSHttpTxnSsnGet(txnp); + TSVConn vconnp = TSHttpSsnClientVConnGet(ssnp); + + TSUserArgSet(txnp, gIX.TXN, (void *)"Transaction Data"); + TSUserArgSet(ssnp, gIX.SSN, (void *)"Session Data"); + TSUserArgSet(vconnp, gIX.VCONN, (void *)"VConn Data"); + + TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); + + return 0; +} + +static int +cont_remap(TSCont contp, TSEvent event, void *edata) +{ + TSMBuffer bufp; + TSMLoc hdrs; + ArgIndexes *ix = static_cast(TSContDataGet(contp)); + TSHttpTxn txnp = static_cast(edata); + TSHttpSsn ssnp = TSHttpTxnSsnGet(txnp); + TSVConn vconnp = TSHttpSsnClientVConnGet(ssnp); + + if (TS_SUCCESS == TSHttpTxnClientRespGet(txnp, &bufp, &hdrs)) { +#if NEW_APIS + set_header(bufp, hdrs, "X-Arg-GLB", static_cast(TSUserArgGet(nullptr, ix->GLB))); + set_header(bufp, hdrs, "X-Arg-TXN", static_cast(TSUserArgGet(txnp, ix->TXN))); + set_header(bufp, hdrs, "X-Arg-SSN", static_cast(TSUserArgGet(ssnp, ix->SSN))); + set_header(bufp, hdrs, "X-Arg-VCONN", static_cast(TSUserArgGet(vconnp, ix->VCONN))); +#else + set_header(bufp, hdrs, "X-Arg-TXN", static_cast(TSHttpTxnArgGet(txnp, ix->TXN))); + set_header(bufp, hdrs, "X-Arg-SSN", static_cast(TSHttpSsnArgGet(ssnp, ix->SSN))); + set_header(bufp, hdrs, "X-Arg-VCONN", static_cast(TSVConnArgGet(vconnp, ix->VCONN))); +#endif + } + + TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); + + return 0; +} + +// Called by ATS as our initialization point +void +TSPluginInit(int argc, const char *argv[]) +{ + TSPluginRegistrationInfo info; + info.plugin_name = const_cast("user_args"); + info.vendor_name = const_cast("apache"); + info.support_email = const_cast("dev@trafficserver.apache.org"); + if (TSPluginRegister(&info) != TS_SUCCESS) { + TSError("[%s] Plugin registration failed", PLUGIN_NAME); + } + +#if NEW_APIS + if (TS_SUCCESS != TSUserArgIndexReserve(TSUserArgType::TXN, PLUGIN_NAME, "User args tests TXN", &gIX.TXN)) { + TSError("[%s] Unable to initialize plugin (disabled). Failed to reserve TXN arg.", PLUGIN_NAME); + return; + } else if (TS_SUCCESS != TSUserArgIndexReserve(TSUserArgType::SSN, PLUGIN_NAME, "User args tests SSN", &gIX.SSN)) { + TSError("[%s] Unable to initialize plugin (disabled). Failed to reserve SSN arg.", PLUGIN_NAME); + return; + } else if (TS_SUCCESS != TSUserArgIndexReserve(TSUserArgType::VCONN, PLUGIN_NAME, "User args tests VCONN", &gIX.VCONN)) { + TSError("[%s] Unable to initialize plugin (disabled). Failed to reserve VCONN arg.", PLUGIN_NAME); + return; + } else if (TS_SUCCESS != TSUserArgIndexReserve(TSUserArgType::GLB, PLUGIN_NAME, "User args tests GLB", &gIX.GLB)) { + TSError("[%s] Unable to initialize plugin (disabled). Failed to reserve GLB arg.", PLUGIN_NAME); + return; + } +#else + if (TS_SUCCESS != TSHttpTxnArgIndexReserve(PLUGIN_NAME, "User args tests TXN", &gIX.TXN)) { + TSError("[%s] Unable to initialize plugin (disabled). Failed to reserve TXN arg.", PLUGIN_NAME); + return; + } else if (TS_SUCCESS != TSHttpSsnArgIndexReserve(PLUGIN_NAME, "User args tests SSN", &gIX.SSN)) { + TSError("[%s] Unable to initialize plugin (disabled). Failed to reserve SSN arg.", PLUGIN_NAME); + return; + } else if (TS_SUCCESS != TSVConnArgIndexReserve(PLUGIN_NAME, "User args tests VCONN", &gIX.VCONN)) { + TSError("[%s] Unable to initialize plugin (disabled). Failed to reserve VCONN arg.", PLUGIN_NAME); + return; + } +#endif + + // Setup the global slot value + TSUserArgSet(nullptr, gIX.GLB, (void *)"Global Data"); + + gIX.contp = TSContCreate(cont_global, nullptr); + TSHttpHookAdd(TS_HTTP_READ_REQUEST_HDR_HOOK, gIX.contp); +} + +TSReturnCode +TSRemapInit(TSRemapInterface *api_info, char *errbuf, int errbuf_size) +{ + if (!api_info) { + strncpy(errbuf, "[TSRemapInit] - Invalid TSRemapInterface argument", errbuf_size - 1); + return TS_ERROR; + } + + if (api_info->size < sizeof(TSRemapInterface)) { + strncpy(errbuf, "[TSRemapInit] - Incorrect size of TSRemapInterface structure", errbuf_size - 1); + return TS_ERROR; + } + + if (api_info->tsremap_version < TSREMAP_VERSION) { + snprintf(errbuf, errbuf_size, "[TSRemapInit] - Incorrect API version %ld.%ld", api_info->tsremap_version >> 16, + (api_info->tsremap_version & 0xffff)); + return TS_ERROR; + } + + return TS_SUCCESS; +} + +TSReturnCode +TSRemapNewInstance(int argc, char *argv[], void **ih, char * /* errbuf ATS_UNUSED */, int /* errbuf_size ATS_UNUSED */) +{ + ArgIndexes *ix = new ArgIndexes; + + ix->contp = TSContCreate(cont_remap, nullptr); + TSContDataSet(ix->contp, static_cast(ix)); + +#if NEW_APIS + if (TS_SUCCESS != TSUserArgIndexNameLookup(TSUserArgType::TXN, PLUGIN_NAME, &ix->TXN, nullptr)) { + TSError("[%s] Failed to lookup TXN arg.", PLUGIN_NAME); + return TS_ERROR; + } else if (TS_SUCCESS != TSUserArgIndexNameLookup(TSUserArgType::SSN, PLUGIN_NAME, &ix->SSN, nullptr)) { + TSError("[%s] Failed to lookup SSN arg.", PLUGIN_NAME); + return TS_ERROR; + } else if (TS_SUCCESS != TSUserArgIndexNameLookup(TSUserArgType::VCONN, PLUGIN_NAME, &ix->VCONN, nullptr)) { + TSError("[%s] Failed to lookup VCONN arg.", PLUGIN_NAME); + return TS_ERROR; + } else if (TS_SUCCESS != TSUserArgIndexNameLookup(TSUserArgType::GLB, PLUGIN_NAME, &ix->GLB, nullptr)) { + TSError("[%s] Failed to lookup GLB arg.", PLUGIN_NAME); + return TS_ERROR; + } +#else + if (TS_SUCCESS != TSHttpTxnArgIndexNameLookup(PLUGIN_NAME, &ix->TXN, nullptr)) { + TSError("[%s] Failed to lookup TXN arg.", PLUGIN_NAME); + return TS_ERROR; + } else if (TS_SUCCESS != TSHttpSsnArgIndexNameLookup(PLUGIN_NAME, &ix->SSN, nullptr)) { + TSError("[%s] Failed to lookup SSN arg.", PLUGIN_NAME); + return TS_ERROR; + } else if (TS_SUCCESS != TSVConnArgIndexNameLookup(PLUGIN_NAME, &ix->VCONN, nullptr)) { + TSError("[%s] Failed to lookup VCONN arg.", PLUGIN_NAME); + return TS_ERROR; + } +#endif + + *ih = static_cast(ix); + return TS_SUCCESS; +} + +void +TSRemapDeleteInstance(void *ih) +{ + ArgIndexes *ix = static_cast(ih); + + TSContDestroy(ix->contp); + delete ix; +} + +TSRemapStatus +TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri) +{ + ArgIndexes *ix = static_cast(ih); + + TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, ix->contp); + TSHttpTxnStatusSet(txnp, TS_HTTP_STATUS_MOVED_TEMPORARILY); + + return TSREMAP_DID_REMAP; +} From e8e031d4b6365887468d27234ff2e9ebc8712df8 Mon Sep 17 00:00:00 2001 From: Leif Hedstrom Date: Wed, 4 Mar 2020 10:01:35 -0700 Subject: [PATCH 5/7] Makes the proper enum name prefixes for the new constants --- example/plugins/c-api/remap/remap.cc | 2 +- .../plugins/c-api/vconn_args/vconn_args.cc | 4 +-- include/ts/apidefs.h.in | 10 +++---- plugins/authproxy/authproxy.cc | 4 +-- plugins/esi/combo_handler.cc | 2 +- .../ja3_fingerprint/ja3_fingerprint.cc | 4 +-- .../experimental/remap_stats/remap_stats.cc | 2 +- .../experimental/traffic_dump/traffic_dump.cc | 2 +- plugins/xdebug/Cleanup.h | 2 +- src/traffic_server/InkAPI.cc | 30 +++++++++---------- src/tscpp/api/utils_internal.cc | 2 +- tests/tools/plugins/user_args.cc | 16 +++++----- 12 files changed, 40 insertions(+), 40 deletions(-) diff --git a/example/plugins/c-api/remap/remap.cc b/example/plugins/c-api/remap/remap.cc index 7a3b3190fcc..f46991eda49 100644 --- a/example/plugins/c-api/remap/remap.cc +++ b/example/plugins/c-api/remap/remap.cc @@ -267,7 +267,7 @@ TSRemapDoRemap(void *ih, TSHttpTxn rh, TSRemapRequestInfo *rri) } // How to store plugin private arguments inside Traffic Server request processing block. - if (TSUserArgIndexReserve(TSUserArgType::TXN, "remap_example", "Example remap plugin", &arg_index) == TS_SUCCESS) { + if (TSUserArgIndexReserve(TS_USER_ARGS_TXN, "remap_example", "Example remap plugin", &arg_index) == TS_SUCCESS) { TSDebug(PLUGIN_NAME, "Save processing counter %" PRIu64 " inside request processing block\n", _processing_counter); TSUserArgSet(rh, arg_index, (void *)_processing_counter); // save counter } diff --git a/example/plugins/c-api/vconn_args/vconn_args.cc b/example/plugins/c-api/vconn_args/vconn_args.cc index 6f9f0fbb428..18620ac8a8c 100644 --- a/example/plugins/c-api/vconn_args/vconn_args.cc +++ b/example/plugins/c-api/vconn_args/vconn_args.cc @@ -37,7 +37,7 @@ vconn_arg_handler(TSCont contp, TSEvent event, void *edata) case TS_EVENT_VCONN_START: { // Testing set argument int idx = 0; - while (TSUserArgIndexReserve(TSUserArgType::VCONN, PLUGIN_NAME, "test", &idx) == TS_SUCCESS) { + while (TSUserArgIndexReserve(TS_USER_ARGS_VCONN, PLUGIN_NAME, "test", &idx) == TS_SUCCESS) { char *buf = static_cast(TSmalloc(64)); snprintf(buf, 64, "Test Arg Idx %d", idx); TSUserArgSet(ssl_vc, idx, (void *)buf); @@ -52,7 +52,7 @@ vconn_arg_handler(TSCont contp, TSEvent event, void *edata) while (idx <= last_arg) { const char *name = nullptr; const char *desc = nullptr; - if (TSUserArgIndexLookup(TSUserArgType::VCONN, idx, &name, &desc) == TS_SUCCESS) { + if (TSUserArgIndexLookup(TS_USER_ARGS_VCONN, idx, &name, &desc) == TS_SUCCESS) { TSDebug(PLUGIN_NAME, "Successful lookup for arg #%d: [%s] [%s]", idx, name, desc); } else { TSDebug(PLUGIN_NAME, "Failed lookup for arg #%d", idx); diff --git a/include/ts/apidefs.h.in b/include/ts/apidefs.h.in index 428b3cc30c1..c728b0116cf 100644 --- a/include/ts/apidefs.h.in +++ b/include/ts/apidefs.h.in @@ -880,11 +880,11 @@ typedef enum { /// The User Arg type, used for Txn/Ssn/VConn user argument slots typedef enum { - TXN, ///< Transaction based. - SSN, ///< Session based - VCONN, ///< VConnection based - TS_USER_ARGS_GLB, ///< Global based - COUNT ///< Fake enum, # of valid entries. + TS_USER_ARGS_TXN, ///< Transaction based. + TS_USER_ARGS_SSN, ///< Session based + TS_USER_ARGS_VCONN, ///< VConnection based + TS_USER_ARGS_GLB, ///< Global based + TS_USER_ARGS_COUNT ///< Fake enum, # of valid entries. } TSUserArgType; typedef struct tsapi_file *TSFile; diff --git a/plugins/authproxy/authproxy.cc b/plugins/authproxy/authproxy.cc index e5d364c3054..88dadd09c6a 100644 --- a/plugins/authproxy/authproxy.cc +++ b/plugins/authproxy/authproxy.cc @@ -736,7 +736,7 @@ TSPluginInit(int argc, const char *argv[]) AuthLogError("plugin registration failed"); } - TSReleaseAssert(TSUserArgIndexReserve(TSUserArgType::TXN, "AuthProxy", "AuthProxy authorization tag", &AuthTaggedRequestArg) == + TSReleaseAssert(TSUserArgIndexReserve(TS_USER_ARGS_TXN, "AuthProxy", "AuthProxy authorization tag", &AuthTaggedRequestArg) == TS_SUCCESS); AuthOsDnsContinuation = TSContCreate(AuthProxyGlobalHook, nullptr); @@ -750,7 +750,7 @@ TSPluginInit(int argc, const char *argv[]) TSReturnCode TSRemapInit(TSRemapInterface * /* api ATS_UNUSED */, char * /* err ATS_UNUSED */, int /* errsz ATS_UNUSED */) { - TSReleaseAssert(TSUserArgIndexReserve(TSUserArgType::TXN, "AuthProxy", "AuthProxy authorization tag", &AuthTaggedRequestArg) == + TSReleaseAssert(TSUserArgIndexReserve(TS_USER_ARGS_TXN, "AuthProxy", "AuthProxy authorization tag", &AuthTaggedRequestArg) == TS_SUCCESS); AuthOsDnsContinuation = TSContCreate(AuthProxyGlobalHook, nullptr); diff --git a/plugins/esi/combo_handler.cc b/plugins/esi/combo_handler.cc index 00649c10eae..e031be784be 100644 --- a/plugins/esi/combo_handler.cc +++ b/plugins/esi/combo_handler.cc @@ -438,7 +438,7 @@ TSPluginInit(int argc, const char *argv[]) TSHttpHookAdd(TS_HTTP_OS_DNS_HOOK, rrh_contp); - if (TSUserArgIndexReserve(TSUserArgType::TXN, DEBUG_TAG, "will save plugin-enable flag here", &arg_idx) != TS_SUCCESS) { + if (TSUserArgIndexReserve(TS_USER_ARGS_TXN, DEBUG_TAG, "will save plugin-enable flag here", &arg_idx) != TS_SUCCESS) { LOG_ERROR("failed to reserve private data slot"); return; } else { diff --git a/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc b/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc index 0fcfe2b3cd0..fe3a33e8705 100644 --- a/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc +++ b/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc @@ -444,7 +444,7 @@ TSPluginInit(int argc, const char *argv[]) } // SNI handler TSCont ja3_cont = TSContCreate(client_hello_ja3_handler, nullptr); - TSUserArgIndexReserve(TSUserArgType::VCONN, PLUGIN_NAME, "used to pass ja3", &ja3_idx); + TSUserArgIndexReserve(TS_USER_ARGS_VCONN, PLUGIN_NAME, "used to pass ja3", &ja3_idx); #if OPENSSL_VERSION_NUMBER < 0x10100000L TSHttpHookAdd(TS_SSL_SERVERNAME_HOOK, ja3_cont); #elif OPENSSL_VERSION_NUMBER >= 0x10101000L @@ -473,7 +473,7 @@ TSRemapInit(TSRemapInterface *api_info, char *errbuf, int errbuf_size) // Set up SNI handler for all TLS connections TSCont ja3_cont = TSContCreate(client_hello_ja3_handler, nullptr); - TSUserArgIndexReserve(TSUserArgType::VCONN, PLUGIN_NAME, "Used to pass ja3", &ja3_idx); + TSUserArgIndexReserve(TS_USER_ARGS_VCONN, PLUGIN_NAME, "Used to pass ja3", &ja3_idx); #if OPENSSL_VERSION_NUMBER < 0x10100000L TSHttpHookAdd(TS_SSL_SERVERNAME_HOOK, ja3_cont); #elif OPENSSL_VERSION_NUMBER >= 0x10101000L diff --git a/plugins/experimental/remap_stats/remap_stats.cc b/plugins/experimental/remap_stats/remap_stats.cc index 24e06e299ee..31809bb33b8 100644 --- a/plugins/experimental/remap_stats/remap_stats.cc +++ b/plugins/experimental/remap_stats/remap_stats.cc @@ -273,7 +273,7 @@ TSPluginInit(int argc, const char *argv[]) } } - TSUserArgIndexReserve(TSUserArgType::TXN, PLUGIN_NAME, "txn data", &(config->txn_slot)); + TSUserArgIndexReserve(TS_USER_ARGS_TXN, PLUGIN_NAME, "txn data", &(config->txn_slot)); if (!config->post_remap_host) { pre_remap_cont = TSContCreate(handle_read_req_hdr, nullptr); diff --git a/plugins/experimental/traffic_dump/traffic_dump.cc b/plugins/experimental/traffic_dump/traffic_dump.cc index 3e330a3171c..458afd5e7c4 100644 --- a/plugins/experimental/traffic_dump/traffic_dump.cc +++ b/plugins/experimental/traffic_dump/traffic_dump.cc @@ -645,7 +645,7 @@ TSPluginInit(int argc, const char *argv[]) if (TS_SUCCESS != TSPluginRegister(&info)) { TSError("[%s] Unable to initialize plugin (disabled). Failed to register plugin.", PLUGIN_NAME); - } else if (TS_SUCCESS != TSUserArgIndexReserve(TSUserArgType::SSN, PLUGIN_NAME, "Track log related data", &s_arg_idx)) { + } else if (TS_SUCCESS != TSUserArgIndexReserve(TS_USER_ARGS_SSN, PLUGIN_NAME, "Track log related data", &s_arg_idx)) { TSError("[%s] Unable to initialize plugin (disabled). Failed to reserve ssn arg.", PLUGIN_NAME); } else { /// Add global hooks diff --git a/plugins/xdebug/Cleanup.h b/plugins/xdebug/Cleanup.h index cd09a7c1ca9..7a1c5b3351f 100644 --- a/plugins/xdebug/Cleanup.h +++ b/plugins/xdebug/Cleanup.h @@ -145,7 +145,7 @@ template class TxnAuxDataMgr : private return; } - TSReleaseAssert(TSUserArgIndexReserve(TSUserArgType::TXN, arg_name, arg_desc, &md.txnArgIndex) == TS_SUCCESS); + TSReleaseAssert(TSUserArgIndexReserve(TS_USER_ARGS_TXN, arg_name, arg_desc, &md.txnArgIndex) == TS_SUCCESS); TSReleaseAssert(md.txnCloseContp = TSContCreate(_deleteAuxData, nullptr)); } diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index ee2f0dd833d..26a7722e1ba 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -109,9 +109,9 @@ struct UserArg { }; // Managing the user args tables, and the global storage (which is assumed to be the biggest, by far). -UserArg UserArgTable[TSUserArgType::COUNT][MAX_USER_ARGS_GLB]; +UserArg UserArgTable[TS_USER_ARGS_COUNT][MAX_USER_ARGS_GLB]; static PluginUserArgs global_user_args; -std::atomic UserArgIdx[TSUserArgType::COUNT]; // Table of next reserved index. +std::atomic UserArgIdx[TS_USER_ARGS_COUNT]; // Table of next reserved index. /* URL schemes */ tsapi const char *TS_URL_SCHEME_FILE; @@ -6104,7 +6104,7 @@ TSUserArgIndexReserve(TSUserArgType type, const char *name, const char *descript { sdk_assert(sdk_sanity_check_null_ptr(ptr_idx) == TS_SUCCESS); sdk_assert(sdk_sanity_check_null_ptr(name) == TS_SUCCESS); - sdk_assert(0 <= type && type < TSUserArgType::COUNT); + sdk_assert(0 <= type && type < TS_USER_ARGS_COUNT); int idx; @@ -6120,7 +6120,7 @@ TSUserArgIndexReserve(TSUserArgType type, const char *name, const char *descript } idx = UserArgIdx[type]++; - int limit = (type == TSUserArgType::VCONN) ? MAX_USER_ARGS_VCONN : MAX_USER_ARGS_TXN; + int limit = (type == TS_USER_ARGS_VCONN) ? MAX_USER_ARGS_VCONN : MAX_USER_ARGS_TXN; if (idx < limit) { UserArg &arg(UserArgTable[type][idx]); @@ -6138,7 +6138,7 @@ TSUserArgIndexReserve(TSUserArgType type, const char *name, const char *descript TSReturnCode TSUserArgIndexLookup(TSUserArgType type, int idx, const char **name, const char **description) { - sdk_assert(0 <= type && type < TSUserArgType::COUNT); + sdk_assert(0 <= type && type < TS_USER_ARGS_COUNT); if (sdk_sanity_check_null_ptr(name) == TS_SUCCESS) { if (idx < UserArgIdx[type]) { UserArg &arg(UserArgTable[type][idx]); @@ -6157,7 +6157,7 @@ TSReturnCode TSUserArgIndexNameLookup(TSUserArgType type, const char *name, int *arg_idx, const char **description) { sdk_assert(sdk_sanity_check_null_ptr(arg_idx) == TS_SUCCESS); - sdk_assert(0 <= type && type < TSUserArgType::COUNT); + sdk_assert(0 <= type && type < TS_USER_ARGS_COUNT); std::string_view n{name}; @@ -6202,55 +6202,55 @@ TSUserArgGet(void *data, int arg_idx) TSReturnCode TSHttpTxnArgIndexReserve(const char *name, const char *description, int *arg_idx) { - return TSUserArgIndexReserve(TSUserArgType::TXN, name, description, arg_idx); + return TSUserArgIndexReserve(TS_USER_ARGS_TXN, name, description, arg_idx); } TSReturnCode TSHttpTxnArgIndexLookup(int arg_idx, const char **name, const char **description) { - return TSUserArgIndexLookup(TSUserArgType::TXN, arg_idx, name, description); + return TSUserArgIndexLookup(TS_USER_ARGS_TXN, arg_idx, name, description); } TSReturnCode TSHttpTxnArgIndexNameLookup(const char *name, int *arg_idx, const char **description) { - return TSUserArgIndexNameLookup(TSUserArgType::TXN, name, arg_idx, description); + return TSUserArgIndexNameLookup(TS_USER_ARGS_TXN, name, arg_idx, description); } TSReturnCode TSHttpSsnArgIndexReserve(const char *name, const char *description, int *arg_idx) { - return TSUserArgIndexReserve(TSUserArgType::SSN, name, description, arg_idx); + return TSUserArgIndexReserve(TS_USER_ARGS_SSN, name, description, arg_idx); } TSReturnCode TSHttpSsnArgIndexLookup(int arg_idx, const char **name, const char **description) { - return TSUserArgIndexLookup(TSUserArgType::SSN, arg_idx, name, description); + return TSUserArgIndexLookup(TS_USER_ARGS_SSN, arg_idx, name, description); } TSReturnCode TSHttpSsnArgIndexNameLookup(const char *name, int *arg_idx, const char **description) { - return TSUserArgIndexNameLookup(TSUserArgType::SSN, name, arg_idx, description); + return TSUserArgIndexNameLookup(TS_USER_ARGS_SSN, name, arg_idx, description); } TSReturnCode TSVConnArgIndexReserve(const char *name, const char *description, int *arg_idx) { - return TSUserArgIndexReserve(TSUserArgType::VCONN, name, description, arg_idx); + return TSUserArgIndexReserve(TS_USER_ARGS_VCONN, name, description, arg_idx); } TSReturnCode TSVConnArgIndexLookup(int arg_idx, const char **name, const char **description) { - return TSUserArgIndexLookup(TSUserArgType::VCONN, arg_idx, name, description); + return TSUserArgIndexLookup(TS_USER_ARGS_VCONN, arg_idx, name, description); } TSReturnCode TSVConnArgIndexNameLookup(const char *name, int *arg_idx, const char **description) { - return TSUserArgIndexNameLookup(TSUserArgType::VCONN, name, arg_idx, description); + return TSUserArgIndexNameLookup(TS_USER_ARGS_VCONN, name, arg_idx, description); } void diff --git a/src/tscpp/api/utils_internal.cc b/src/tscpp/api/utils_internal.cc index 364599b9f87..ae9f79f2ebf 100644 --- a/src/tscpp/api/utils_internal.cc +++ b/src/tscpp/api/utils_internal.cc @@ -99,7 +99,7 @@ void setupTransactionManagement() { // Reserve a transaction slot - TSAssert(TS_SUCCESS == TSUserArgIndexReserve(TSUserArgType::TXN, "atscppapi", "ATS CPP API", &TRANSACTION_STORAGE_INDEX)); + TSAssert(TS_SUCCESS == TSUserArgIndexReserve(TS_USER_ARGS_TXN, "atscppapi", "ATS CPP API", &TRANSACTION_STORAGE_INDEX)); // We must always have a cleanup handler available TSMutex mutex = nullptr; TSCont cont = TSContCreate(handleTransactionEvents, mutex); diff --git a/tests/tools/plugins/user_args.cc b/tests/tools/plugins/user_args.cc index 854655a6d6d..c478762c80b 100644 --- a/tests/tools/plugins/user_args.cc +++ b/tests/tools/plugins/user_args.cc @@ -115,16 +115,16 @@ TSPluginInit(int argc, const char *argv[]) } #if NEW_APIS - if (TS_SUCCESS != TSUserArgIndexReserve(TSUserArgType::TXN, PLUGIN_NAME, "User args tests TXN", &gIX.TXN)) { + if (TS_SUCCESS != TSUserArgIndexReserve(TS_USER_ARGS_TXN, PLUGIN_NAME, "User args tests TXN", &gIX.TXN)) { TSError("[%s] Unable to initialize plugin (disabled). Failed to reserve TXN arg.", PLUGIN_NAME); return; - } else if (TS_SUCCESS != TSUserArgIndexReserve(TSUserArgType::SSN, PLUGIN_NAME, "User args tests SSN", &gIX.SSN)) { + } else if (TS_SUCCESS != TSUserArgIndexReserve(TS_USER_ARGS_SSN, PLUGIN_NAME, "User args tests SSN", &gIX.SSN)) { TSError("[%s] Unable to initialize plugin (disabled). Failed to reserve SSN arg.", PLUGIN_NAME); return; - } else if (TS_SUCCESS != TSUserArgIndexReserve(TSUserArgType::VCONN, PLUGIN_NAME, "User args tests VCONN", &gIX.VCONN)) { + } else if (TS_SUCCESS != TSUserArgIndexReserve(TS_USER_ARGS_VCONN, PLUGIN_NAME, "User args tests VCONN", &gIX.VCONN)) { TSError("[%s] Unable to initialize plugin (disabled). Failed to reserve VCONN arg.", PLUGIN_NAME); return; - } else if (TS_SUCCESS != TSUserArgIndexReserve(TSUserArgType::GLB, PLUGIN_NAME, "User args tests GLB", &gIX.GLB)) { + } else if (TS_SUCCESS != TSUserArgIndexReserve(TS_USER_ARGS_GLB, PLUGIN_NAME, "User args tests GLB", &gIX.GLB)) { TSError("[%s] Unable to initialize plugin (disabled). Failed to reserve GLB arg.", PLUGIN_NAME); return; } @@ -179,16 +179,16 @@ TSRemapNewInstance(int argc, char *argv[], void **ih, char * /* errbuf ATS_UNUSE TSContDataSet(ix->contp, static_cast(ix)); #if NEW_APIS - if (TS_SUCCESS != TSUserArgIndexNameLookup(TSUserArgType::TXN, PLUGIN_NAME, &ix->TXN, nullptr)) { + if (TS_SUCCESS != TSUserArgIndexNameLookup(TS_USER_ARGS_TXN, PLUGIN_NAME, &ix->TXN, nullptr)) { TSError("[%s] Failed to lookup TXN arg.", PLUGIN_NAME); return TS_ERROR; - } else if (TS_SUCCESS != TSUserArgIndexNameLookup(TSUserArgType::SSN, PLUGIN_NAME, &ix->SSN, nullptr)) { + } else if (TS_SUCCESS != TSUserArgIndexNameLookup(TS_USER_ARGS_SSN, PLUGIN_NAME, &ix->SSN, nullptr)) { TSError("[%s] Failed to lookup SSN arg.", PLUGIN_NAME); return TS_ERROR; - } else if (TS_SUCCESS != TSUserArgIndexNameLookup(TSUserArgType::VCONN, PLUGIN_NAME, &ix->VCONN, nullptr)) { + } else if (TS_SUCCESS != TSUserArgIndexNameLookup(TS_USER_ARGS_VCONN, PLUGIN_NAME, &ix->VCONN, nullptr)) { TSError("[%s] Failed to lookup VCONN arg.", PLUGIN_NAME); return TS_ERROR; - } else if (TS_SUCCESS != TSUserArgIndexNameLookup(TSUserArgType::GLB, PLUGIN_NAME, &ix->GLB, nullptr)) { + } else if (TS_SUCCESS != TSUserArgIndexNameLookup(TS_USER_ARGS_GLB, PLUGIN_NAME, &ix->GLB, nullptr)) { TSError("[%s] Failed to lookup GLB arg.", PLUGIN_NAME); return TS_ERROR; } From 88709336353be53ca526582694a6d2d7864558de Mon Sep 17 00:00:00 2001 From: Leif Hedstrom Date: Wed, 4 Mar 2020 10:29:03 -0700 Subject: [PATCH 6/7] Changes the max defines to an array --- include/tscore/PluginUserArgs.h | 24 +++++++++++++---------- iocore/eventsystem/I_VConnection.h | 4 ++-- iocore/net/I_NetVConnection.h | 2 +- proxy/ProxySession.h | 17 +--------------- proxy/http/HttpSM.h | 2 +- src/traffic_server/InkAPI.cc | 31 +++++++++++++++++------------- 6 files changed, 37 insertions(+), 43 deletions(-) diff --git a/include/tscore/PluginUserArgs.h b/include/tscore/PluginUserArgs.h index 1d53dfbe62e..a8921fa6531 100644 --- a/include/tscore/PluginUserArgs.h +++ b/include/tscore/PluginUserArgs.h @@ -24,12 +24,16 @@ #pragma once #include +#include "ts/apidefs.h" #include "tscore/ink_assert.h" +#include "tscore/PluginUserArgs.h" -static constexpr int MAX_USER_ARGS_TXN = 16; /* max number of user arguments for Transactions */ -static constexpr int MAX_USER_ARGS_SSN = 8; /* max number of user arguments for Sessions (for now) */ -static constexpr int MAX_USER_ARGS_VCONN = 4; /* max number of VConnection user arguments */ -static constexpr int MAX_USER_ARGS_GLB = 128; /* max number of user arguments, globally */ +static constexpr std::array MAX_USER_ARGS = { + 16, /* max number of user arguments for TXN */ + 8, /* max number of user arguments for SSN */ + 4, /* max number of user arguments for VCONN */ + 128 /* max number of user arguments for GLB */ +}; /** This is a mixin class (sort of), implementing the appropriate APIs and data storage for @@ -38,22 +42,22 @@ static constexpr int MAX_USER_ARGS_GLB = 128; /* max number of user arguments, class PluginUserArgsMixin { public: - virtual void *get_user_arg(unsigned ix) const = 0; - virtual void set_user_arg(unsigned ix, void *arg) = 0; + virtual void *get_user_arg(size_t ix) const = 0; + virtual void set_user_arg(size_t ix, void *arg) = 0; }; -template class PluginUserArgs : public virtual PluginUserArgsMixin +template class PluginUserArgs : public virtual PluginUserArgsMixin { public: void * - get_user_arg(unsigned ix) const + get_user_arg(size_t ix) const { ink_assert(ix < user_args.size()); return this->user_args[ix]; }; void - set_user_arg(unsigned ix, void *arg) + set_user_arg(size_t ix, void *arg) { ink_assert(ix < user_args.size()); user_args[ix] = arg; @@ -66,5 +70,5 @@ template class PluginUserArgs : public virtual PluginUserArgsMixin } private: - std::array user_args{{nullptr}}; + std::array user_args{{nullptr}}; }; diff --git a/iocore/eventsystem/I_VConnection.h b/iocore/eventsystem/I_VConnection.h index 674191a08ce..e739fc6039d 100644 --- a/iocore/eventsystem/I_VConnection.h +++ b/iocore/eventsystem/I_VConnection.h @@ -146,7 +146,7 @@ typedef struct tsapi_vio *TSVIO; It is also a Continuation that is called back from processors. */ -class VConnection : public Continuation, public PluginUserArgs +class VConnection : public Continuation { public: ~VConnection() override; @@ -375,7 +375,7 @@ class VConnection : public Continuation, public PluginUserArgs { VIO * do_io_write(Continuation * /* c ATS_UNUSED */, int64_t /* nbytes ATS_UNUSED */, IOBufferReader * /* buf ATS_UNUSED */, bool /* owner ATS_UNUSED */) override diff --git a/iocore/net/I_NetVConnection.h b/iocore/net/I_NetVConnection.h index 0ce385cecb1..f3bb310e705 100644 --- a/iocore/net/I_NetVConnection.h +++ b/iocore/net/I_NetVConnection.h @@ -332,7 +332,7 @@ struct NetVCOptions { stream IO to be done based on a single read or write call. */ -class NetVConnection : public VConnection +class NetVConnection : public VConnection, public PluginUserArgs { public: // How many bytes have been queued to the OS for sending by haven't been sent yet diff --git a/proxy/ProxySession.h b/proxy/ProxySession.h index ce511014770..62804107eaf 100644 --- a/proxy/ProxySession.h +++ b/proxy/ProxySession.h @@ -74,10 +74,8 @@ struct ProxyError { }; /// Abstract class for HttpSM to interface with any session -class ProxySession : public VConnection, public PluginUserArgs +class ProxySession : public VConnection, public PluginUserArgs { - using pua_type = PluginUserArgs; - public: ProxySession(); @@ -159,19 +157,6 @@ class ProxySession : public VConnection, public PluginUserArgspua_type::get_user_arg(ix); - } - - void - set_user_arg(unsigned ix, void *arg) override - { - return this->pua_type::set_user_arg(ix, arg); - } - protected: // Hook dispatching state HttpHookState hook_state; diff --git a/proxy/http/HttpSM.h b/proxy/http/HttpSM.h index 8855620fcb9..6f1663bbfce 100644 --- a/proxy/http/HttpSM.h +++ b/proxy/http/HttpSM.h @@ -199,7 +199,7 @@ class PostDataBuffers ~PostDataBuffers(); }; -class HttpSM : public Continuation, public PluginUserArgs +class HttpSM : public Continuation, public PluginUserArgs { friend class HttpPagesHandler; friend class CoreUtils; diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index 26a7722e1ba..f6e8636bbbd 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -109,8 +109,8 @@ struct UserArg { }; // Managing the user args tables, and the global storage (which is assumed to be the biggest, by far). -UserArg UserArgTable[TS_USER_ARGS_COUNT][MAX_USER_ARGS_GLB]; -static PluginUserArgs global_user_args; +UserArg UserArgTable[TS_USER_ARGS_COUNT][MAX_USER_ARGS[TS_USER_ARGS_GLB]]; +static PluginUserArgs global_user_args; std::atomic UserArgIdx[TS_USER_ARGS_COUNT]; // Table of next reserved index. /* URL schemes */ @@ -6120,7 +6120,7 @@ TSUserArgIndexReserve(TSUserArgType type, const char *name, const char *descript } idx = UserArgIdx[type]++; - int limit = (type == TS_USER_ARGS_VCONN) ? MAX_USER_ARGS_VCONN : MAX_USER_ARGS_TXN; + int limit = MAX_USER_ARGS[type]; if (idx < limit) { UserArg &arg(UserArgTable[type][idx]); @@ -6179,6 +6179,7 @@ TSUserArgSet(void *data, int arg_idx, void *arg) { if (nullptr != data) { PluginUserArgsMixin *user_args = dynamic_cast(static_cast(data)); + sdk_assert(user_args); user_args->set_user_arg(arg_idx, arg); } else { @@ -6191,6 +6192,7 @@ TSUserArgGet(void *data, int arg_idx) { if (nullptr != data) { PluginUserArgsMixin *user_args = dynamic_cast(static_cast(data)); + sdk_assert(user_args); return user_args->get_user_arg(arg_idx); } else { @@ -6257,7 +6259,7 @@ void TSHttpTxnArgSet(TSHttpTxn txnp, int arg_idx, void *arg) { sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS); - sdk_assert(arg_idx >= 0 && arg_idx < MAX_USER_ARGS_TXN); + sdk_assert(arg_idx >= 0 && static_cast(arg_idx) < MAX_USER_ARGS[TS_USER_ARGS_TXN]); HttpSM *sm = reinterpret_cast(txnp); @@ -6268,7 +6270,7 @@ void * TSHttpTxnArgGet(TSHttpTxn txnp, int arg_idx) { sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS); - sdk_assert(arg_idx >= 0 && arg_idx < MAX_USER_ARGS_TXN); + sdk_assert(arg_idx >= 0 && static_cast(arg_idx) < MAX_USER_ARGS[TS_USER_ARGS_TXN]); HttpSM *sm = reinterpret_cast(txnp); return sm->get_user_arg(arg_idx); @@ -6278,7 +6280,7 @@ void TSHttpSsnArgSet(TSHttpSsn ssnp, int arg_idx, void *arg) { sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS); - sdk_assert(arg_idx >= 0 && arg_idx < MAX_USER_ARGS_SSN); + sdk_assert(arg_idx >= 0 && static_cast(arg_idx) < MAX_USER_ARGS[TS_USER_ARGS_SSN]); ProxySession *cs = reinterpret_cast(ssnp); @@ -6289,7 +6291,7 @@ void * TSHttpSsnArgGet(TSHttpSsn ssnp, int arg_idx) { sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS); - sdk_assert(arg_idx >= 0 && arg_idx < MAX_USER_ARGS_SSN); + sdk_assert(arg_idx >= 0 && static_cast(arg_idx) < MAX_USER_ARGS[TS_USER_ARGS_SSN]); ProxySession *cs = reinterpret_cast(ssnp); return cs->get_user_arg(arg_idx); @@ -6299,19 +6301,22 @@ void TSVConnArgSet(TSVConn connp, int arg_idx, void *arg) { sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS); - sdk_assert(arg_idx >= 0 && arg_idx < MAX_USER_ARGS_VCONN); - VConnection *avc = reinterpret_cast(connp); - avc->set_user_arg(arg_idx, arg); + sdk_assert(arg_idx >= 0 && static_cast(arg_idx) < MAX_USER_ARGS[TS_USER_ARGS_VCONN]); + PluginUserArgsMixin *user_args = dynamic_cast(reinterpret_cast(connp)); + sdk_assert(user_args); + + user_args->set_user_arg(arg_idx, arg); } void * TSVConnArgGet(TSVConn connp, int arg_idx) { sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS); - sdk_assert(arg_idx >= 0 && arg_idx < MAX_USER_ARGS_VCONN); + sdk_assert(arg_idx >= 0 && static_cast(arg_idx) < MAX_USER_ARGS[TS_USER_ARGS_VCONN]); + PluginUserArgsMixin *user_args = dynamic_cast(reinterpret_cast(connp)); + sdk_assert(user_args); - VConnection *avc = reinterpret_cast(connp); - return avc->get_user_arg(arg_idx); + return user_args->get_user_arg(arg_idx); } void From 11ac50d6bda66feff54e37b2f853041ccb7373c1 Mon Sep 17 00:00:00 2001 From: Leif Hedstrom Date: Tue, 10 Mar 2020 15:41:09 -0600 Subject: [PATCH 7/7] Updated Docs with these changes --- .../api/functions/TSHttpArgs.en.rst | 11 +- .../api/functions/TSTypes.en.rst | 4 + .../api/functions/TSUserArgs.en.rst | 112 ++++++++++++++++++ .../api/functions/TSVConnArgs.en.rst | 8 +- .../design-documents/reloading-plugins.en.rst | 16 +-- tests/tools/plugins/user_args.cc | 6 + 6 files changed, 145 insertions(+), 12 deletions(-) create mode 100644 doc/developer-guide/api/functions/TSUserArgs.en.rst diff --git a/doc/developer-guide/api/functions/TSHttpArgs.en.rst b/doc/developer-guide/api/functions/TSHttpArgs.en.rst index fec1dd00f86..a564eb2d4f9 100644 --- a/doc/developer-guide/api/functions/TSHttpArgs.en.rst +++ b/doc/developer-guide/api/functions/TSHttpArgs.en.rst @@ -17,12 +17,19 @@ .. include:: ../../../common.defs .. default-domain:: c + TSHttpArgs ********** Synopsis ======== +.. note:: + + This set of API is obsoleted as of ATS v9.0.0, and will be removed with ATS v10.0.0! + For details of the new APIs, see :ref:`tsuserargs`. + + .. code-block:: cpp #include @@ -35,8 +42,8 @@ Synopsis .. function:: TSReturnCode TSHttpSsnArgIndexLookup(int arg_idx, const char ** name, const char ** description) .. function:: void TSHttpTxnArgSet(TSHttpTxn txnp, int arg_idx, void * arg) .. function:: void * TSHttpTxnArgGet(TSHttpTxn txnp, int arg_idx) -.. function:: void TSHttpSsnArgSet(TSHttpTxn txnp, int arg_idx, void * arg) -.. function:: void * TSHttpSsnArgGet(TSHttpTxn txnp, int arg_idx) +.. function:: void TSHttpSsnArgSet(TSHttpSsn ssnp, int arg_idx, void * arg) +.. function:: void * TSHttpSsnArgGet(TSHttpSsn ssnp, int arg_idx) Description =========== diff --git a/doc/developer-guide/api/functions/TSTypes.en.rst b/doc/developer-guide/api/functions/TSTypes.en.rst index e158c97ee62..a63c5fbf7a0 100644 --- a/doc/developer-guide/api/functions/TSTypes.en.rst +++ b/doc/developer-guide/api/functions/TSTypes.en.rst @@ -217,6 +217,10 @@ more widely. Those are described on this page. .. type:: TSThreadFunc +.. type:: TSUserArgType + + An enum for the supported types of user arguments. + .. type:: TSUuidVersion A version value for at :type:`TSUuid`. diff --git a/doc/developer-guide/api/functions/TSUserArgs.en.rst b/doc/developer-guide/api/functions/TSUserArgs.en.rst new file mode 100644 index 00000000000..5dc020885ca --- /dev/null +++ b/doc/developer-guide/api/functions/TSUserArgs.en.rst @@ -0,0 +1,112 @@ +.. Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright + ownership. The ASF licenses this file to you under the Apache + License, Version 2.0 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + +.. include:: ../../../common.defs +.. default-domain:: c + +.. _tsuserargs: + +TSUserArgs +********** + +Synopsis +======== + +.. code-block:: cpp + + #include + + typedef enum { + TS_USER_ARGS_TXN, ///< Transaction based. + TS_USER_ARGS_SSN, ///< Session based + TS_USER_ARGS_VCONN, ///< VConnection based + TS_USER_ARGS_GLB, ///< Global based + TS_USER_ARGS_COUNT ///< Fake enum, # of valid entries. + } TSUserArgType; + +.. function:: TSReturnCode TSUserArgIndexReserve(TSUserArgType type, const char *name, const char *description, int *arg_idx) +.. function:: TSReturnCode TSUserArgIndexNameLookup(TSUserArgType type, const char *name, int *arg_idx, const char **description) +.. function:: TSReturnCode TSUserArgIndexLookup(TSUserArgType type, int arg_idx, const char **name, const char **description) +.. function:: void TSUserArgSet(void *data, int arg_idx, void *arg) +.. function:: void *TSUserArgGet(void *data, int arg_idx) + +Description +=========== + +|TS| sessions, transactions, virtual connections and globally provide a fixed array of void pointers +that can be used by plugins to store information. This can be used to avoid creating a per session or +transaction continuations to hold data, or to communicate between plugins as the values in the array +are visible to any plugin which can access the session or transaction. The array values are opaque +to |TS| and it will not dereference nor release them. Plugins are responsible for cleaning up any +resources pointed to by the values or, if the values are simply values, there is no need for the plugin +to remove them after the session or transaction has completed. + +To avoid collisions between plugins a plugin should first *reserve* an index in the array. A +plugin can reserve a slot of a particular type by calling :func:`TSUserArgIndexReserve`. The arguments are: + +:arg:`type` + The type for which the plugin intend to reserve a slot. See :code:`TSUserArgType` above. + +:arg:`name` + An identifying name for the plugin that reserved the index. Required. + +:arg:`description` + An optional description of the use of the arg. This can be :code:`nullptr`. + +:arg:`arg_idx` + A pointer to an :code:`int`. If an index is successfully reserved, the :code:`int` pointed at by this is + set to the reserved index. It is not modified if the call is unsuccessful. + +The functions return :code:`TS_SUCCESS` if an index was reserved, +:code:`TS_ERROR` if not (most likely because all of the indices have already been reserved). +Generally this will be a file or library scope global which is set at plugin initialization. This +function is used in the example remap plugin :ts:git:`example/plugins/c-api/remap/remap.cc`. The index is stored +in the plugin global :code:`arg_index`. Transaction and session plugin argument indices are reserved +independently. + +To look up the owner of a reserved index use :func:`TSUserArgIndexNameLookup`, with the appropriate type. +If :arg:`name` is found as an owner, the function returns :code:`TS_SUCCESS` and :arg:`arg_index` is +updated with the index reserved under that name. If :arg:`description` is not :code:`NULL` then +the character pointer to which it points will be updated to point at the description for that +reserved index. This enables communication between plugins where plugin "A" reserves an index under +a well known name and plugin "B" locates the index by looking it up under that name. + +The owner of a reserved index can be found with :func:`TSUserArgIndexLookup`. If +:arg:`arg_index` is reserved then the function returns :code:`TS_SUCCESS` and the pointers referred +to by :arg:`name` and :arg:`description` are updated. :arg:`name` must point at a valid character +pointer but :arg:`description` can be :code:`NULL` in which case it is ignored. + +Manipulating the array is simple. :func:`TSUserArgSet` sets the array slot at :arg:`arg_idx`, for the +particular type based on the provide data pointer. The values can be retrieved with the value from +:func:`TSUserArgGet`. Values that have not been set are :code:`NULL`. Note that both the setter and the getter are +context sensitive, based on the type (or value) of the data pointer: + + ============== ======================================================================= + data type Semantics + ============== ======================================================================= + ``TSHttpTxn`` The implicit context is for a transaction (``TS_USER_ARGS_TXN``) + ``TSHttpSsn`` The implicit context is for a transaction (``TS_USER_ARGS_SSN``) + ``TSVConn`` The implicit context is for a transaction (``TS_USER_ARGS_VCONN``) + ``nullptr`` The implicit context is global (``TS_USER_ARGS_GLB``) + ============== ======================================================================= + +Note that neither :func:`TSUserArgSet` nor :func:`TSUserArgGet` has any type safety on the :arg:`data` +parameters, being a ``void*`` pointer. + + +.. note:: Session arguments persist for the entire session, which means potentially across all transactions in that session. + +.. note:: Following arg index reservations is conventional, it is not enforced. diff --git a/doc/developer-guide/api/functions/TSVConnArgs.en.rst b/doc/developer-guide/api/functions/TSVConnArgs.en.rst index d6e7febad4f..be575296b9d 100644 --- a/doc/developer-guide/api/functions/TSVConnArgs.en.rst +++ b/doc/developer-guide/api/functions/TSVConnArgs.en.rst @@ -17,14 +17,18 @@ .. include:: ../../../common.defs .. default-domain:: c -.. _TSVConnArgs: - TSVConnArgs ************ Synopsis ======== +.. note:: + + This set of API is obsoleted as of ATS v9.0.0, and will be removed with ATS v10.0.0! + For details of the new APIs, see :ref:`tsuserargs`. + + .. code-block:: cpp #include diff --git a/doc/developer-guide/design-documents/reloading-plugins.en.rst b/doc/developer-guide/design-documents/reloading-plugins.en.rst index fb0d2ffee9b..14e7aec95ae 100644 --- a/doc/developer-guide/design-documents/reloading-plugins.en.rst +++ b/doc/developer-guide/design-documents/reloading-plugins.en.rst @@ -128,17 +128,17 @@ The continuations created by the plugin will have a context member added to them reference counting, when continuations are destroyed, and to handle events. -TSHttpArgs +TSUserArgs ---------- -|TS| sessions and transactions provide a fixed array of void pointers that can be used by plugins -to store information. To avoid collisions between plugins a plugin should first *reserve* an index in the array. +|TS| sessions, transactions, virtual connections and globally provide a fixed array of void pointers that +can be used by plugins to store information. To avoid collisions between plugins a plugin should first +*reserve* an index in the array. -Since :c:func:`TSHttpTxnArgIndexReserve` and :c:func:`TSHttpSsnArgIndexReserve` are meant to be called during plugin -initialization we could end up "leaking" indices during plugin reload. -Hence it is necessary to make sure only one index is allocated per "plugin identifying name", current -:c:func:`TSHttpTxnArgIndexNameLookup` and :c:func:`TSHttpTxnArgIndexNameLookup` implementation assumes 1-1 -index-to-name relationship as well. +Since :c:func:`TSUserArgIndexReserve` is meant to be called during plugin initialization we could end up +"leaking" indices during plugin reload. Hence it is necessary to make sure only one index is allocated per +"plugin identifying name", current :c:func:`TSUserArgIndexNameLookup` and +:c:func:`TSUserArgIndexLookup` implementation assumes 1-1 index-to-name relationship as well. PluginFactory diff --git a/tests/tools/plugins/user_args.cc b/tests/tools/plugins/user_args.cc index c478762c80b..71f1956aa6a 100644 --- a/tests/tools/plugins/user_args.cc +++ b/tests/tools/plugins/user_args.cc @@ -65,9 +65,15 @@ cont_global(TSCont contp, TSEvent event, void *edata) TSHttpSsn ssnp = TSHttpTxnSsnGet(txnp); TSVConn vconnp = TSHttpSsnClientVConnGet(ssnp); +#if NEW_APIS TSUserArgSet(txnp, gIX.TXN, (void *)"Transaction Data"); TSUserArgSet(ssnp, gIX.SSN, (void *)"Session Data"); TSUserArgSet(vconnp, gIX.VCONN, (void *)"VConn Data"); +#else + TSHttpTxnArgSet(txnp, gIX.TXN, (void *)"Transaction Data"); + TSHttpSsnArgSet(ssnp, gIX.SSN, (void *)"Session Data"); + TSVConnArgSet(vconnp, gIX.VCONN, (void *)"VConn Data"); +#endif TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);