/src/trafficserver/include/tscore/PluginUserArgs.h
Line | Count | Source |
1 | | /** @file |
2 | | |
3 | | Base class and implementation details for the User Args features. |
4 | | |
5 | | @section license License |
6 | | |
7 | | Licensed to the Apache Software Foundation (ASF) under one |
8 | | or more contributor license agreements. See the NOTICE file |
9 | | distributed with this work for additional information |
10 | | regarding copyright ownership. The ASF licenses this file |
11 | | to you under the Apache License, Version 2.0 (the |
12 | | "License"); you may not use this file except in compliance |
13 | | with the License. You may obtain a copy of the License at |
14 | | |
15 | | http://www.apache.org/licenses/LICENSE-2.0 |
16 | | |
17 | | Unless required by applicable law or agreed to in writing, software |
18 | | distributed under the License is distributed on an "AS IS" BASIS, |
19 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
20 | | See the License for the specific language governing permissions and |
21 | | limitations under the License. |
22 | | */ |
23 | | |
24 | | #pragma once |
25 | | |
26 | | #include <array> |
27 | | #include "ts/apidefs.h" |
28 | | #include "tscore/ink_assert.h" |
29 | | #include "tscore/PluginUserArgs.h" |
30 | | |
31 | | static constexpr std::array<size_t, TS_USER_ARGS_COUNT> MAX_USER_ARGS = { |
32 | | { |
33 | | 16, /* max number of user arguments for TXN */ |
34 | | 8, /* max number of user arguments for SSN */ |
35 | | 4, /* max number of user arguments for VCONN */ |
36 | | 128 /* max number of user arguments for GLB */ |
37 | | } |
38 | | }; |
39 | | |
40 | | /** Stagger each user argument value so we can detect mismatched |
41 | | * indices. |
42 | | * |
43 | | * For example, say a plugin associates data with both sessions and |
44 | | * transactions and that its session index is 2 and its transaction index is 4. |
45 | | * In this case, we'll hand back to the plugin 2002 for its session index and |
46 | | * 1004 for its transaction index. If it then accidentally uses its session |
47 | | * index to reference its transaction index, it will pass back 2002 instead of |
48 | | * 1004, which we will identify as belonging to the wrong user argument type |
49 | | * because it is in the 2000 session block rather than the expected 1000 |
50 | | * transaction block. |
51 | | * |
52 | | * Note that these higher value 1000 block indices are only used when |
53 | | * interfacing with the plugin. Internally the lower valued index is used. |
54 | | * That is, for a transaction, expect internally a value of 3 instead of 1003. |
55 | | */ |
56 | | static constexpr size_t |
57 | | get_user_arg_offset(TSUserArgType type) |
58 | 0 | { |
59 | | // TS_USER_ARGS_TXN indices begin at 1000, TS_USER_ARGS_SSN begin at 2000, |
60 | | // etc. |
61 | 0 | return (static_cast<size_t>(type) + 1) * 1000; |
62 | 0 | } Unexecuted instantiation: fuzz_http3frame.cc:get_user_arg_offset(TSUserArgType) Unexecuted instantiation: Http3Frame.cc:get_user_arg_offset(TSUserArgType) Unexecuted instantiation: EventSystem.cc:get_user_arg_offset(TSUserArgType) |
63 | | |
64 | | /** Verify that the user passed in an index whose value corresponds with the |
65 | | * type. See the comment above the declaration of get_user_arg_offset for the |
66 | | * intention behind this. |
67 | | */ |
68 | | static constexpr inline bool |
69 | | SanityCheckUserIndex(TSUserArgType type, int idx) |
70 | 0 | { |
71 | 0 | int const block_start = get_user_arg_offset(type); |
72 | 0 | return idx >= block_start && idx < block_start + 1000; |
73 | 0 | } Unexecuted instantiation: fuzz_http3frame.cc:SanityCheckUserIndex(TSUserArgType, int) Unexecuted instantiation: Http3Frame.cc:SanityCheckUserIndex(TSUserArgType, int) Unexecuted instantiation: EventSystem.cc:SanityCheckUserIndex(TSUserArgType, int) |
74 | | |
75 | | /** |
76 | | This is a mixin class (sort of), implementing the appropriate APIs and data storage for |
77 | | a particular user arg table. Used by VConn / Ssn / Txn user arg data. |
78 | | */ |
79 | | class PluginUserArgsMixin |
80 | | { |
81 | | public: |
82 | 0 | virtual ~PluginUserArgsMixin() = default; |
83 | | virtual void *get_user_arg(size_t ix) const = 0; |
84 | | virtual void set_user_arg(size_t ix, void *arg) = 0; |
85 | | }; |
86 | | |
87 | | template <TSUserArgType I> class PluginUserArgs : public virtual PluginUserArgsMixin |
88 | | { |
89 | | public: |
90 | | void * |
91 | | get_user_arg(size_t ix) const override |
92 | 0 | { |
93 | 0 | ink_release_assert(SanityCheckUserIndex(I, ix)); |
94 | 0 | ix -= get_user_arg_offset(I); |
95 | 0 | ink_release_assert(ix < user_args.size()); |
96 | 0 | return this->user_args[ix]; |
97 | 0 | }; |
98 | | |
99 | | void |
100 | | set_user_arg(size_t ix, void *arg) override |
101 | 0 | { |
102 | 0 | ink_release_assert(SanityCheckUserIndex(I, ix)); |
103 | 0 | ix -= get_user_arg_offset(I); |
104 | 0 | ink_release_assert(ix < user_args.size()); |
105 | 0 | user_args[ix] = arg; |
106 | 0 | }; |
107 | | |
108 | | void |
109 | | clear() |
110 | | { |
111 | | user_args.fill(nullptr); |
112 | | } |
113 | | |
114 | | private: |
115 | | std::array<void *, MAX_USER_ARGS[I]> user_args{{nullptr}}; |
116 | | }; |