Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/proxy-wasm/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ class ContextBase : public RootInterface,
t += tpe.tv_nsec;
return t;
}
string_view getConfiguration() override {
unimplemented();
return "";
}
std::pair<uint32_t, string_view> getStatus() override {
unimplemented();
return std::make_pair(1, "unimplmemented");
Expand Down Expand Up @@ -312,6 +316,7 @@ class ContextBase : public RootInterface,
string_view /* details */) override {
return unimplemented();
}
void clearRouteCache() override { unimplemented(); }
void failStream(WasmStreamType stream_type) override { closeStream(stream_type); }

// Shared Data
Expand Down
6 changes: 6 additions & 0 deletions include/proxy-wasm/context_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ struct HttpInterface {
Pairs additional_headers, uint32_t grpc_status,
string_view details) = 0;

// Clears the route cache for the current request.
virtual void clearRouteCache() = 0;

// Call when the stream closes. See RootInterface.
virtual bool onDone() = 0;

Expand Down Expand Up @@ -545,6 +548,9 @@ struct GeneralInterface {
// Provides the current time in nanoseconds since the Unix epoch.
virtual uint64_t getCurrentTimeNanoseconds() = 0;

// Returns plugin configuration.
virtual string_view getConfiguration() = 0;

/**
* Provides the status of the last call into the VM or out of the VM, similar to errno.
* @return the status code and a descriptive string.
Expand Down
4 changes: 4 additions & 0 deletions include/proxy-wasm/exports.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,21 @@ namespace exports {

// ABI functions exported from envoy to wasm.

Word get_configuration(void *raw_context, Word address, Word size);
Word get_status(void *raw_context, Word status_code, Word address, Word size);
Word log(void *raw_context, Word level, Word address, Word size);
Word get_property(void *raw_context, Word path_ptr, Word path_size, Word value_ptr_ptr,
Word value_size_ptr);
Word set_property(void *raw_context, Word key_ptr, Word key_size, Word value_ptr, Word value_size);
Word continue_request(void *raw_context);
Word continue_response(void *raw_context);
Word continue_stream(void *raw_context, Word stream_type);
Word close_stream(void *raw_context, Word stream_type);
Word send_local_response(void *raw_context, Word response_code, Word response_code_details_ptr,
Word response_code_details_size, Word body_ptr, Word body_size,
Word additional_response_header_pairs_ptr,
Word additional_response_header_pairs_size, Word grpc_status);
Word clear_route_cache(void *raw_context);
Word get_shared_data(void *raw_context, Word key_ptr, Word key_size, Word value_ptr_ptr,
Word value_size_ptr, Word cas_ptr);
Word set_shared_data(void *raw_context, Word key_ptr, Word key_size, Word value_ptr,
Expand Down
1 change: 1 addition & 0 deletions include/proxy-wasm/null_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ namespace proxy_wasm {
*/
struct NullPluginRegistry {
void (*proxy_abi_version_0_1_0_)() = nullptr;
void (*proxy_abi_version_0_2_0_)() = nullptr;
void (*proxy_on_log_)(uint32_t context_id) = nullptr;
uint32_t (*proxy_validate_configuration_)(uint32_t root_context_id,
uint32_t plugin_configuration_size) = nullptr;
Expand Down
7 changes: 5 additions & 2 deletions include/proxy-wasm/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> {
std::unordered_set<ContextBase *> pending_done_; // Root contexts not done during shutdown.

WasmCallVoid<0> abi_version_0_1_0_;
WasmCallVoid<0> abi_version_0_2_0_;

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

WasmCallWord<3> on_request_headers_;
WasmCallWord<2> on_request_headers_abi_01_;
WasmCallWord<3> on_request_headers_abi_02_;
WasmCallWord<3> on_request_body_;
WasmCallWord<2> on_request_trailers_;
WasmCallWord<2> on_request_metadata_;

WasmCallWord<3> on_response_headers_;
WasmCallWord<2> on_response_headers_abi_01_;
WasmCallWord<3> on_response_headers_abi_02_;
WasmCallWord<3> on_response_body_;
WasmCallWord<2> on_response_trailers_;
WasmCallWord<2> on_response_metadata_;
Expand Down
17 changes: 17 additions & 0 deletions include/proxy-wasm/wasm_api_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ namespace null_plugin {

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

// Configuration and Status
inline WasmResult proxy_get_configuration(const char **configuration_ptr,
size_t *configuration_size) {
return wordToWasmResult(
exports::get_configuration(current_context_, WR(configuration_ptr), WR(configuration_size)));
}

inline WasmResult proxy_get_status(uint32_t *code_ptr, const char **ptr, size_t *size) {
return wordToWasmResult(exports::get_status(current_context_, WR(code_ptr), WR(ptr), WR(size)));
}
Expand Down Expand Up @@ -57,6 +64,12 @@ inline WasmResult proxy_set_property(const char *key_ptr, size_t key_size, const
}

// Continue
inline WasmResult proxy_continue_request() {
return wordToWasmResult(exports::continue_request(current_context_));
}
inline WasmResult proxy_continue_response() {
return wordToWasmResult(exports::continue_response(current_context_));
}
inline WasmResult proxy_continue_stream(WasmStreamType stream_type) {
return wordToWasmResult(exports::continue_stream(current_context_, WS(stream_type)));
}
Expand All @@ -75,6 +88,10 @@ proxy_send_local_response(uint32_t response_code, const char *response_code_deta
WS(grpc_status)));
}

inline WasmResult proxy_clear_route_cache() {
return wordToWasmResult(exports::clear_route_cache(current_context_));
}

// SharedData
inline WasmResult proxy_get_shared_data(const char *key_ptr, size_t key_size,
const char **value_ptr, size_t *value_size, uint32_t *cas) {
Expand Down
40 changes: 32 additions & 8 deletions src/context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,24 @@
} \
}

#define CHECK_FAIL2(_call1, _call2, _stream_type, _return_open, _return_closed) \
if (isFailed()) { \
if (plugin_->fail_open_) { \
return _return_open; \
} else { \
failStream(_stream_type); \
return _return_closed; \
} \
} else { \
if (!wasm_->_call1 && !wasm_->_call2) { \
return _return_open; \
} \
}

#define CHECK_HTTP(_call, _return_open, _return_closed) \
CHECK_FAIL(_call, WasmStreamType::Request, _return_open, _return_closed)
#define CHECK_HTTP2(_call1, _call2, _return_open, _return_closed) \
CHECK_FAIL2(_call1, _call2, WasmStreamType::Request, _return_open, _return_closed)
#define CHECK_NET(_call, _return_open, _return_closed) \
CHECK_FAIL(_call, WasmStreamType::Downstream, _return_open, _return_closed)

Expand Down Expand Up @@ -429,11 +445,15 @@ void ContextBase::onUpstreamConnectionClose(CloseType close_type) {
template <typename P> static uint32_t headerSize(const P &p) { return p ? p->size() : 0; }

FilterHeadersStatus ContextBase::onRequestHeaders(uint32_t headers, bool end_of_stream) {
CHECK_HTTP(on_request_headers_, FilterHeadersStatus::Continue,
FilterHeadersStatus::StopIteration);
CHECK_HTTP2(on_request_headers_abi_01_, on_request_headers_abi_02_, FilterHeadersStatus::Continue,
FilterHeadersStatus::StopIteration);
DeferAfterCallActions actions(this);
auto result =
wasm_->on_request_headers_(this, id_, headers, static_cast<uint32_t>(end_of_stream)).u64_;
auto result = wasm_->on_request_headers_abi_01_
? wasm_->on_request_headers_abi_01_(this, id_, headers).u64_
: wasm_
->on_request_headers_abi_02_(this, id_, headers,
static_cast<uint32_t>(end_of_stream))
.u64_;
if (result > static_cast<uint64_t>(FilterHeadersStatus::StopAllIterationAndWatermark))
return FilterHeadersStatus::StopAllIterationAndWatermark;
return static_cast<FilterHeadersStatus>(result);
Expand Down Expand Up @@ -471,11 +491,15 @@ FilterMetadataStatus ContextBase::onRequestMetadata(uint32_t elements) {
}

FilterHeadersStatus ContextBase::onResponseHeaders(uint32_t headers, bool end_of_stream) {
CHECK_HTTP(on_response_headers_, FilterHeadersStatus::Continue,
FilterHeadersStatus::StopIteration);
CHECK_HTTP2(on_response_headers_abi_01_, on_response_headers_abi_02_,
FilterHeadersStatus::Continue, FilterHeadersStatus::StopIteration);
DeferAfterCallActions actions(this);
auto result =
wasm_->on_response_headers_(this, id_, headers, static_cast<uint32_t>(end_of_stream)).u64_;
auto result = wasm_->on_response_headers_abi_01_
? wasm_->on_response_headers_abi_01_(this, id_, headers).u64_
: wasm_
->on_response_headers_abi_02_(this, id_, headers,
static_cast<uint32_t>(end_of_stream))
.u64_;
if (result > static_cast<uint64_t>(FilterHeadersStatus::StopAllIterationAndWatermark))
return FilterHeadersStatus::StopAllIterationAndWatermark;
return static_cast<FilterHeadersStatus>(result);
Expand Down
25 changes: 25 additions & 0 deletions src/exports.cc
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,15 @@ Word get_property(void *raw_context, Word path_ptr, Word path_size, Word value_p
return WasmResult::Ok;
}

Word get_configuration(void *raw_context, Word value_ptr_ptr, Word value_size_ptr) {
auto context = WASM_CONTEXT(raw_context);
auto value = context->getConfiguration();
if (!context->wasm()->copyToPointerSize(value, value_ptr_ptr, value_size_ptr)) {
return WasmResult::InvalidMemoryAccess;
}
return WasmResult::Ok;
}

Word get_status(void *raw_context, Word code_ptr, Word value_ptr_ptr, Word value_size_ptr) {
auto context = WASM_CONTEXT(raw_context);
auto status = context->getStatus();
Expand All @@ -163,6 +172,16 @@ Word get_status(void *raw_context, Word code_ptr, Word value_ptr_ptr, Word value
// HTTP

// Continue/Reply/Route
Word continue_request(void *raw_context) {
auto context = WASM_CONTEXT(raw_context);
return context->continueStream(WasmStreamType::Request);
}

Word continue_response(void *raw_context) {
auto context = WASM_CONTEXT(raw_context);
return context->continueStream(WasmStreamType::Response);
}

Word continue_stream(void *raw_context, Word type) {
auto context = WASM_CONTEXT(raw_context);
if (type > static_cast<uint64_t>(WasmStreamType::MAX)) {
Expand Down Expand Up @@ -198,6 +217,12 @@ Word send_local_response(void *raw_context, Word response_code, Word response_co
return WasmResult::Ok;
}

Word clear_route_cache(void *raw_context) {
auto context = WASM_CONTEXT(raw_context);
context->clearRouteCache();
return WasmResult::Ok;
}

Word set_effective_context(void *raw_context, Word context_id) {
auto context = WASM_CONTEXT(raw_context);
uint32_t cid = static_cast<uint32_t>(context_id);
Expand Down
2 changes: 1 addition & 1 deletion src/null/null_plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
namespace proxy_wasm {

void NullPlugin::getFunction(string_view function_name, WasmCallVoid<0> *f) {
if (function_name == "proxy_abi_version_0_1_0") {
if (function_name == "proxy_abi_version_0_2_0") {
*f = [](ContextBase *) { /* dummy function */ };
} else if (function_name == "_start") {
*f = nullptr;
Expand Down
30 changes: 24 additions & 6 deletions src/wasm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,18 @@ void WasmBase::registerCallbacks() {
exports::_fn>::convertFunctionWordToUint32);
_REGISTER_PROXY(log);

_REGISTER_PROXY(get_configuration);
_REGISTER_PROXY(get_status);

_REGISTER_PROXY(set_property);
_REGISTER_PROXY(get_property);

_REGISTER_PROXY(continue_request);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't these be conditional based on the version?

Copy link
Copy Markdown
Member Author

@PiotrSikora PiotrSikora Aug 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See envoyproxy/envoy-wasm#596 (comment):

Note, that because we register/expose host functions before linking, we don't know the exported ABI version marker at that point, so we expose host functions for both 0.1.0 and 0.2.0 version of the ABI (since they are not conflicting), and the switching is only happening for the callbacks.

We could expose host functions only for the requested ABI version, but that would require some invasive rewrites to the code that I'm not willing to make just before the release.

_REGISTER_PROXY(continue_response);
_REGISTER_PROXY(continue_stream);
_REGISTER_PROXY(close_stream);
_REGISTER_PROXY(send_local_response);
_REGISTER_PROXY(clear_route_cache);

_REGISTER_PROXY(get_shared_data);
_REGISTER_PROXY(set_shared_data);
Expand Down Expand Up @@ -198,9 +202,21 @@ void WasmBase::getFunctions() {
_GET(__wasm_call_ctors);

_GET(malloc);
if (!malloc_) {
fail("Wasm module is missing malloc function.");
}
#undef _GET

#define _GET_PROXY(_fn) wasm_vm_->getFunction("proxy_" #_fn, &_fn##_);
#define _GET_PROXY_ABI(_fn, _abi) wasm_vm_->getFunction("proxy_" #_fn, &_fn##_abi##_);
_GET_PROXY(abi_version_0_1_0);
_GET_PROXY(abi_version_0_2_0);
if (!abi_version_0_1_0_ && !abi_version_0_2_0_) {
fail("Wasm module is missing the Proxy-Wasm ABI version or requires an unsupported version.");
} else if (abi_version_0_1_0_ && abi_version_0_2_0_) {
fail("Wasm multiple versions of the Proxy-Wasm ABI are declared by the module.");
}

_GET_PROXY(validate_configuration);
_GET_PROXY(on_vm_start);
_GET_PROXY(on_configure);
Expand All @@ -215,11 +231,16 @@ void WasmBase::getFunctions() {
_GET_PROXY(on_downstream_connection_close);
_GET_PROXY(on_upstream_connection_close);

_GET_PROXY(on_request_headers);
if (abi_version_0_1_0_) {
_GET_PROXY_ABI(on_request_headers, _abi_01);
_GET_PROXY_ABI(on_response_headers, _abi_01);
} else if (abi_version_0_2_0_) {
_GET_PROXY_ABI(on_request_headers, _abi_02);
_GET_PROXY_ABI(on_response_headers, _abi_02);
}
_GET_PROXY(on_request_body);
_GET_PROXY(on_request_trailers);
_GET_PROXY(on_request_metadata);
_GET_PROXY(on_response_headers);
_GET_PROXY(on_response_body);
_GET_PROXY(on_response_trailers);
_GET_PROXY(on_response_metadata);
Expand All @@ -232,11 +253,8 @@ void WasmBase::getFunctions() {
_GET_PROXY(on_done);
_GET_PROXY(on_log);
_GET_PROXY(on_delete);
#undef _GET_PROXY_ABI
#undef _GET_PROXY

if (!malloc_) {
fail("Wasm missing malloc");
}
}

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