Skip to content

Commit d6415a0

Browse files
committed
Support both: 0.1.0 and 0.2.0 versions of the Proxy-Wasm ABI.
Signed-off-by: Piotr Sikora <[email protected]>
1 parent 68a319b commit d6415a0

File tree

10 files changed

+122
-17
lines changed

10 files changed

+122
-17
lines changed

include/proxy-wasm/context.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,10 @@ class ContextBase : public RootInterface,
238238
t += tpe.tv_nsec;
239239
return t;
240240
}
241+
std::string_view getConfiguration() override {
242+
unimplemented();
243+
return "";
244+
}
241245
std::pair<uint32_t, std::string_view> getStatus() override {
242246
unimplemented();
243247
return std::make_pair(1, "unimplmemented");
@@ -316,6 +320,7 @@ class ContextBase : public RootInterface,
316320
std::string_view /* details */) override {
317321
return unimplemented();
318322
}
323+
void clearRouteCache() override { unimplemented(); }
319324
void failStream(WasmStreamType stream_type) override { closeStream(stream_type); }
320325

321326
// Shared Data

include/proxy-wasm/context_interface.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,9 @@ struct HttpInterface {
234234
Pairs additional_headers, uint32_t grpc_status,
235235
std::string_view details) = 0;
236236

237+
// Clears the route cache for the current request.
238+
virtual void clearRouteCache() = 0;
239+
237240
// Call when the stream closes. See RootInterface.
238241
virtual bool onDone() = 0;
239242

@@ -550,6 +553,9 @@ struct GeneralInterface {
550553
// Provides the current time in nanoseconds since the Unix epoch.
551554
virtual uint64_t getCurrentTimeNanoseconds() = 0;
552555

556+
// Returns plugin configuration.
557+
virtual string_view getConfiguration() = 0;
558+
553559
/**
554560
* Provides the status of the last call into the VM or out of the VM, similar to errno.
555561
* @return the status code and a descriptive string.

include/proxy-wasm/exports.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,22 @@ namespace exports {
2929

3030
// ABI functions exported from envoy to wasm.
3131

32+
Word get_configuration(void *raw_context, Word address, Word size);
3233
Word get_status(void *raw_context, Word status_code, Word address, Word size);
3334
Word log(void *raw_context, Word level, Word address, Word size);
3435
Word get_log_level(void *raw_context, Word result_level_uint32_ptr);
3536
Word get_property(void *raw_context, Word path_ptr, Word path_size, Word value_ptr_ptr,
3637
Word value_size_ptr);
3738
Word set_property(void *raw_context, Word key_ptr, Word key_size, Word value_ptr, Word value_size);
39+
Word continue_request(void *raw_context);
40+
Word continue_response(void *raw_context);
3841
Word continue_stream(void *raw_context, Word stream_type);
3942
Word close_stream(void *raw_context, Word stream_type);
4043
Word send_local_response(void *raw_context, Word response_code, Word response_code_details_ptr,
4144
Word response_code_details_size, Word body_ptr, Word body_size,
4245
Word additional_response_header_pairs_ptr,
4346
Word additional_response_header_pairs_size, Word grpc_status);
47+
Word clear_route_cache(void *raw_context);
4448
Word get_shared_data(void *raw_context, Word key_ptr, Word key_size, Word value_ptr_ptr,
4549
Word value_size_ptr, Word cas_ptr);
4650
Word set_shared_data(void *raw_context, Word key_ptr, Word key_size, Word value_ptr,

include/proxy-wasm/null_plugin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ namespace proxy_wasm {
3737
*/
3838
struct NullPluginRegistry {
3939
void (*proxy_abi_version_0_1_0_)() = nullptr;
40+
void (*proxy_abi_version_0_2_0_)() = nullptr;
4041
void (*proxy_on_log_)(uint32_t context_id) = nullptr;
4142
uint32_t (*proxy_validate_configuration_)(uint32_t root_context_id,
4243
uint32_t plugin_configuration_size) = nullptr;

include/proxy-wasm/wasm.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> {
185185
std::unordered_set<ContextBase *> pending_done_; // Root contexts not done during shutdown.
186186

187187
WasmCallVoid<0> abi_version_0_1_0_;
188+
WasmCallVoid<0> abi_version_0_2_0_;
188189

189190
WasmCallVoid<0> _start_; /* Emscripten v1.39.0+ */
190191
WasmCallVoid<0> __wasm_call_ctors_;
@@ -205,12 +206,14 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> {
205206
WasmCallVoid<2> on_downstream_connection_close_;
206207
WasmCallVoid<2> on_upstream_connection_close_;
207208

208-
WasmCallWord<3> on_request_headers_;
209+
WasmCallWord<2> on_request_headers_abi_01_;
210+
WasmCallWord<3> on_request_headers_abi_02_;
209211
WasmCallWord<3> on_request_body_;
210212
WasmCallWord<2> on_request_trailers_;
211213
WasmCallWord<2> on_request_metadata_;
212214

213-
WasmCallWord<3> on_response_headers_;
215+
WasmCallWord<2> on_response_headers_abi_01_;
216+
WasmCallWord<3> on_response_headers_abi_02_;
214217
WasmCallWord<3> on_response_body_;
215218
WasmCallWord<2> on_response_trailers_;
216219
WasmCallWord<2> on_response_metadata_;

include/proxy-wasm/wasm_api_impl.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ namespace null_plugin {
2323

2424
inline WasmResult wordToWasmResult(Word w) { return static_cast<WasmResult>(w.u64_); }
2525

26+
// Configuration and Status
27+
inline WasmResult proxy_get_configuration(const char **configuration_ptr,
28+
size_t *configuration_size) {
29+
return wordToWasmResult(
30+
exports::get_configuration(current_context_, WR(configuration_ptr), WR(configuration_size)));
31+
}
32+
2633
inline WasmResult proxy_get_status(uint32_t *code_ptr, const char **ptr, size_t *size) {
2734
return wordToWasmResult(exports::get_status(current_context_, WR(code_ptr), WR(ptr), WR(size)));
2835
}
@@ -55,6 +62,12 @@ inline WasmResult proxy_set_property(const char *key_ptr, size_t key_size, const
5562
}
5663

5764
// Continue
65+
inline WasmResult proxy_continue_request() {
66+
return wordToWasmResult(exports::continue_request(current_context_));
67+
}
68+
inline WasmResult proxy_continue_response() {
69+
return wordToWasmResult(exports::continue_response(current_context_));
70+
}
5871
inline WasmResult proxy_continue_stream(WasmStreamType stream_type) {
5972
return wordToWasmResult(exports::continue_stream(current_context_, WS(stream_type)));
6073
}
@@ -73,6 +86,10 @@ proxy_send_local_response(uint32_t response_code, const char *response_code_deta
7386
WS(grpc_status)));
7487
}
7588

89+
inline WasmResult proxy_clear_route_cache() {
90+
return wordToWasmResult(exports::clear_route_cache(current_context_));
91+
}
92+
7693
// SharedData
7794
inline WasmResult proxy_get_shared_data(const char *key_ptr, size_t key_size,
7895
const char **value_ptr, size_t *value_size, uint32_t *cas) {

src/context.cc

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,24 @@
3737
} \
3838
}
3939

40+
#define CHECK_FAIL2(_call1, _call2, _stream_type, _return_open, _return_closed) \
41+
if (isFailed()) { \
42+
if (plugin_->fail_open_) { \
43+
return _return_open; \
44+
} else { \
45+
failStream(_stream_type); \
46+
return _return_closed; \
47+
} \
48+
} else { \
49+
if (!wasm_->_call1 && !wasm_->_call2) { \
50+
return _return_open; \
51+
} \
52+
}
53+
4054
#define CHECK_HTTP(_call, _return_open, _return_closed) \
4155
CHECK_FAIL(_call, WasmStreamType::Request, _return_open, _return_closed)
56+
#define CHECK_HTTP2(_call1, _call2, _return_open, _return_closed) \
57+
CHECK_FAIL2(_call1, _call2, WasmStreamType::Request, _return_open, _return_closed)
4258
#define CHECK_NET(_call, _return_open, _return_closed) \
4359
CHECK_FAIL(_call, WasmStreamType::Downstream, _return_open, _return_closed)
4460

@@ -443,11 +459,15 @@ void ContextBase::onUpstreamConnectionClose(CloseType close_type) {
443459
template <typename P> static uint32_t headerSize(const P &p) { return p ? p->size() : 0; }
444460

445461
FilterHeadersStatus ContextBase::onRequestHeaders(uint32_t headers, bool end_of_stream) {
446-
CHECK_HTTP(on_request_headers_, FilterHeadersStatus::Continue,
447-
FilterHeadersStatus::StopIteration);
462+
CHECK_HTTP2(on_request_headers_abi_01_, on_request_headers_abi_02_, FilterHeadersStatus::Continue,
463+
FilterHeadersStatus::StopIteration);
448464
DeferAfterCallActions actions(this);
449-
auto result =
450-
wasm_->on_request_headers_(this, id_, headers, static_cast<uint32_t>(end_of_stream)).u64_;
465+
auto result = wasm_->on_request_headers_abi_01_
466+
? wasm_->on_request_headers_abi_01_(this, id_, headers).u64_
467+
: wasm_
468+
->on_request_headers_abi_02_(this, id_, headers,
469+
static_cast<uint32_t>(end_of_stream))
470+
.u64_;
451471
if (result > static_cast<uint64_t>(FilterHeadersStatus::StopAllIterationAndWatermark))
452472
return FilterHeadersStatus::StopAllIterationAndWatermark;
453473
return static_cast<FilterHeadersStatus>(result);
@@ -485,11 +505,15 @@ FilterMetadataStatus ContextBase::onRequestMetadata(uint32_t elements) {
485505
}
486506

487507
FilterHeadersStatus ContextBase::onResponseHeaders(uint32_t headers, bool end_of_stream) {
488-
CHECK_HTTP(on_response_headers_, FilterHeadersStatus::Continue,
489-
FilterHeadersStatus::StopIteration);
508+
CHECK_HTTP2(on_response_headers_abi_01_, on_response_headers_abi_02_,
509+
FilterHeadersStatus::Continue, FilterHeadersStatus::StopIteration);
490510
DeferAfterCallActions actions(this);
491-
auto result =
492-
wasm_->on_response_headers_(this, id_, headers, static_cast<uint32_t>(end_of_stream)).u64_;
511+
auto result = wasm_->on_response_headers_abi_01_
512+
? wasm_->on_response_headers_abi_01_(this, id_, headers).u64_
513+
: wasm_
514+
->on_response_headers_abi_02_(this, id_, headers,
515+
static_cast<uint32_t>(end_of_stream))
516+
.u64_;
493517
if (result > static_cast<uint64_t>(FilterHeadersStatus::StopAllIterationAndWatermark))
494518
return FilterHeadersStatus::StopAllIterationAndWatermark;
495519
return static_cast<FilterHeadersStatus>(result);

src/exports.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,15 @@ Word get_property(void *raw_context, Word path_ptr, Word path_size, Word value_p
148148
return WasmResult::Ok;
149149
}
150150

151+
Word get_configuration(void *raw_context, Word value_ptr_ptr, Word value_size_ptr) {
152+
auto context = WASM_CONTEXT(raw_context);
153+
auto value = context->getConfiguration();
154+
if (!context->wasm()->copyToPointerSize(value, value_ptr_ptr, value_size_ptr)) {
155+
return WasmResult::InvalidMemoryAccess;
156+
}
157+
return WasmResult::Ok;
158+
}
159+
151160
Word get_status(void *raw_context, Word code_ptr, Word value_ptr_ptr, Word value_size_ptr) {
152161
auto context = WASM_CONTEXT(raw_context);
153162
auto status = context->getStatus();
@@ -163,6 +172,16 @@ Word get_status(void *raw_context, Word code_ptr, Word value_ptr_ptr, Word value
163172
// HTTP
164173

165174
// Continue/Reply/Route
175+
Word continue_request(void *raw_context) {
176+
auto context = WASM_CONTEXT(raw_context);
177+
return context->continueStream(WasmStreamType::Request);
178+
}
179+
180+
Word continue_response(void *raw_context) {
181+
auto context = WASM_CONTEXT(raw_context);
182+
return context->continueStream(WasmStreamType::Response);
183+
}
184+
166185
Word continue_stream(void *raw_context, Word type) {
167186
auto context = WASM_CONTEXT(raw_context);
168187
if (type > static_cast<uint64_t>(WasmStreamType::MAX)) {
@@ -198,6 +217,12 @@ Word send_local_response(void *raw_context, Word response_code, Word response_co
198217
return WasmResult::Ok;
199218
}
200219

220+
Word clear_route_cache(void *raw_context) {
221+
auto context = WASM_CONTEXT(raw_context);
222+
context->clearRouteCache();
223+
return WasmResult::Ok;
224+
}
225+
201226
Word set_effective_context(void *raw_context, Word context_id) {
202227
auto context = WASM_CONTEXT(raw_context);
203228
uint32_t cid = static_cast<uint32_t>(context_id);

src/null/null_plugin.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
namespace proxy_wasm {
3434

3535
void NullPlugin::getFunction(std::string_view function_name, WasmCallVoid<0> *f) {
36-
if (function_name == "proxy_abi_version_0_1_0") {
36+
if (function_name == "proxy_abi_version_0_2_0") {
3737
*f = [](ContextBase *) { /* dummy function */ };
3838
} else if (function_name == "_start") {
3939
*f = nullptr;

src/wasm.cc

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,18 @@ void WasmBase::registerCallbacks() {
143143
_REGISTER_PROXY(log);
144144
_REGISTER_PROXY(get_log_level);
145145

146+
_REGISTER_PROXY(get_configuration);
146147
_REGISTER_PROXY(get_status);
147148

148149
_REGISTER_PROXY(set_property);
149150
_REGISTER_PROXY(get_property);
150151

152+
_REGISTER_PROXY(continue_request);
153+
_REGISTER_PROXY(continue_response);
151154
_REGISTER_PROXY(continue_stream);
152155
_REGISTER_PROXY(close_stream);
153156
_REGISTER_PROXY(send_local_response);
157+
_REGISTER_PROXY(clear_route_cache);
154158

155159
_REGISTER_PROXY(get_shared_data);
156160
_REGISTER_PROXY(set_shared_data);
@@ -200,9 +204,23 @@ void WasmBase::getFunctions() {
200204
_GET(__wasm_call_ctors);
201205

202206
_GET(malloc);
207+
if (!malloc_) {
208+
fail(FailState::MissingFunction, "Wasm module is missing malloc function.");
209+
}
203210
#undef _GET
204211

205212
#define _GET_PROXY(_fn) wasm_vm_->getFunction("proxy_" #_fn, &_fn##_);
213+
#define _GET_PROXY_ABI(_fn, _abi) wasm_vm_->getFunction("proxy_" #_fn, &_fn##_abi##_);
214+
_GET_PROXY(abi_version_0_1_0);
215+
_GET_PROXY(abi_version_0_2_0);
216+
if (!abi_version_0_1_0_ && !abi_version_0_2_0_) {
217+
fail(FailState::MissingFunction,
218+
"Wasm module is missing the Proxy-Wasm ABI version or requires an unsupported version.");
219+
} else if (abi_version_0_1_0_ && abi_version_0_2_0_) {
220+
fail(FailState::MissingFunction,
221+
"Wasm multiple versions of the Proxy-Wasm ABI are declared by the module.");
222+
}
223+
206224
_GET_PROXY(validate_configuration);
207225
_GET_PROXY(on_vm_start);
208226
_GET_PROXY(on_configure);
@@ -217,11 +235,16 @@ void WasmBase::getFunctions() {
217235
_GET_PROXY(on_downstream_connection_close);
218236
_GET_PROXY(on_upstream_connection_close);
219237

220-
_GET_PROXY(on_request_headers);
238+
if (abi_version_0_1_0_) {
239+
_GET_PROXY_ABI(on_request_headers, _abi_01);
240+
_GET_PROXY_ABI(on_response_headers, _abi_01);
241+
} else if (abi_version_0_2_0_) {
242+
_GET_PROXY_ABI(on_request_headers, _abi_02);
243+
_GET_PROXY_ABI(on_response_headers, _abi_02);
244+
}
221245
_GET_PROXY(on_request_body);
222246
_GET_PROXY(on_request_trailers);
223247
_GET_PROXY(on_request_metadata);
224-
_GET_PROXY(on_response_headers);
225248
_GET_PROXY(on_response_body);
226249
_GET_PROXY(on_response_trailers);
227250
_GET_PROXY(on_response_metadata);
@@ -234,11 +257,8 @@ void WasmBase::getFunctions() {
234257
_GET_PROXY(on_done);
235258
_GET_PROXY(on_log);
236259
_GET_PROXY(on_delete);
260+
#undef _GET_PROXY_ABI
237261
#undef _GET_PROXY
238-
239-
if (!malloc_) {
240-
fail(FailState::MissingFunction, "Wasm missing malloc");
241-
}
242262
}
243263

244264
WasmBase::WasmBase(const std::shared_ptr<WasmHandleBase> &base_wasm_handle, WasmVmFactory factory)

0 commit comments

Comments
 (0)