diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2016-08-16 17:01:37 +0100 |
---|---|---|
committer | Patrik Flykt <patrik.flykt@linux.intel.com> | 2016-08-19 10:10:29 +0300 |
commit | f7227339b6515c44d2d84facd425ea6f71c5b206 (patch) | |
tree | 5ff3d4388a2b006420a7145495e17e12ac3738f6 | |
parent | b57f740b6e876fed5d9de26098bb4115601f5437 (diff) | |
download | pacrunner-f7227339b6515c44d2d84facd425ea6f71c5b206.tar.gz |
Add duktape support
-rw-r--r-- | Makefile.am | 13 | ||||
-rw-r--r-- | configure.ac | 5 | ||||
-rw-r--r-- | plugins/duktape.c | 231 |
3 files changed, 248 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am index d637baf..f504e60 100644 --- a/Makefile.am +++ b/Makefile.am @@ -41,6 +41,15 @@ builtin_sources += plugins/v8.cc builtin_libadd += @V8_LIBS@ endif +if DUKTAPE +js_sources = src/js_funcs.c +builtin_modules += duktape +builtin_sources += plugins/duktape.c \ + duktape/duk_config.h \ + duktape/duktape.h \ + duktape/duktape.c +endif + sbin_PROGRAMS = src/pacrunner src_pacrunner_SOURCES = $(gdbus_sources) $(builtin_sources) $(js_sources) \ @@ -126,11 +135,13 @@ unit_test_mozjs_LDADD = @MOZJS_LIBS@ @GLIB_LIBS@ @PTHREAD_LIBS@ endif if V8 - unit_test_pacrunner_SOURCES += plugins/v8.cc unit_test_pacrunner_LDADD += @V8_LIBS@ +endif +if DUKTAPE +unit_test_pacrunner_SOURCES += plugins/duktape.c duktape/duktape.c endif endif #UNIT diff --git a/configure.ac b/configure.ac index c788c7f..d31cdcc 100644 --- a/configure.ac +++ b/configure.ac @@ -69,6 +69,11 @@ AC_ARG_ENABLE(pie, AC_HELP_STRING([--enable-pie], fi ]) +AC_ARG_ENABLE(duktape, AC_HELP_STRING([--enable-duktape], + [enable Duktape Javascript plugin support])) + +AM_CONDITIONAL(DUKTAPE, test "${enable_duktape}" = "yes") + AC_ARG_ENABLE(mozjs, AC_HELP_STRING([--enable-mozjs], [enable Mozilla Javascript plugin support])) if (test "${enable_mozjs}" = "yes"); then diff --git a/plugins/duktape.c b/plugins/duktape.c new file mode 100644 index 0000000..a8a93bc --- /dev/null +++ b/plugins/duktape.c @@ -0,0 +1,231 @@ +/* + * PACrunner - Proxy configuration daemon + * + * Copyright © 2013-2016 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify + * it under the terms and conditions of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <sys/ioctl.h> + +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> +#include <ctype.h> + +#include <netdb.h> + +#include "pacrunner.h" +#include "js.h" + +#include "duktape/duktape.h" + +struct pacrunner_duktape { + struct pacrunner_proxy *proxy; + pthread_mutex_t lock; + duk_context *dctx; +}; + +static duk_ret_t myipaddress(duk_context *dkctx) +{ + struct pacrunner_duktape *ctx; + duk_memory_functions fns; + char address[NI_MAXHOST]; + + duk_get_memory_functions(dkctx, &fns); + ctx = fns.udata; + + if (__pacrunner_js_getipaddr(ctx->proxy, address, sizeof(address)) < 0) + duk_push_string(dkctx, NULL); + else + duk_push_string(dkctx, address); + + DBG("address %s", address); + + return 1; +} + +static duk_ret_t dnsresolve(duk_context *dkctx) +{ + struct pacrunner_duktape *ctx; + const char *host = duk_require_string(dkctx, 0); + duk_memory_functions fns; + char address[NI_MAXHOST]; + + DBG("host %s", host); + + duk_get_memory_functions(dkctx, &fns); + ctx = fns.udata; + + address[0] = 0; + if (__pacrunner_js_resolve(ctx->proxy, host, address, + sizeof(address)) < 0) + duk_push_string(dkctx, NULL); + else + duk_push_string(dkctx, address); + + DBG("address %s", address); + + return 1; +} + +static int create_object(struct pacrunner_proxy *proxy) +{ + struct pacrunner_duktape *ctx; + const char *script; + + script = (char *) pacrunner_proxy_get_script(proxy); + if (!script) { + pacrunner_error("no script\n"); + return 0; + } + + ctx = g_malloc0(sizeof(struct pacrunner_duktape)); + + ctx->proxy = proxy; + ctx->dctx = duk_create_heap(NULL, NULL, NULL, ctx, NULL); + if (!ctx->dctx) { + pacrunner_error("no headp\n"); + g_free(ctx); + return -ENOMEM; + } + duk_push_global_object(ctx->dctx); + + /* Register the C functions so the script can use them */ + duk_push_c_function(ctx->dctx, myipaddress, 0); + duk_put_prop_string(ctx->dctx, -2, "myIpAddress"); + + duk_push_c_function(ctx->dctx, dnsresolve, 1); + duk_put_prop_string(ctx->dctx, -2, "dnsResolve"); + + if (duk_peval_string_noresult(ctx->dctx, + __pacrunner_js_routines) != 0 || + duk_peval_string_noresult(ctx->dctx, script) != 0) { + pacrunner_error("Error: %s\n", + duk_safe_to_string(ctx->dctx, -1)); + duk_destroy_heap(ctx->dctx); + g_free(ctx); + return -EINVAL; + } + + if (pthread_mutex_init(&ctx->lock, NULL) != 0) { + pacrunner_error("Failed to init mutex lock\n"); + duk_destroy_heap(ctx->dctx); + g_free(ctx); + return -EIO; + } + + __pacrunner_proxy_set_jsctx(proxy, ctx); + pacrunner_error("done %p\n", ctx); + return 0; +} + +static int duktape_clear_proxy(struct pacrunner_proxy *proxy) +{ + struct pacrunner_duktape *ctx = __pacrunner_proxy_get_jsctx(proxy); + + DBG("proxy %p ctx %p", proxy, ctx); + + if (!ctx) + return -EINVAL; + + duk_destroy_heap(ctx->dctx); + pthread_mutex_destroy(&ctx->lock); + + __pacrunner_proxy_set_jsctx(proxy, NULL); + return 0; +} + +static int duktape_set_proxy(struct pacrunner_proxy *proxy) +{ + DBG("proxy %p", proxy); + + if (!proxy) + return 0; + + duktape_clear_proxy(proxy); + + return create_object(proxy); +} + +static char *duktape_execute(struct pacrunner_proxy *proxy, + const char *url, const char *host) +{ + struct pacrunner_duktape *ctx = __pacrunner_proxy_get_jsctx(proxy); + char *result; + + DBG("proxy %p ctx %p url %s host %s", proxy, ctx, url, host); + + if (!ctx) + return NULL; + + pthread_mutex_lock(&ctx->lock); + + duk_get_prop_string(ctx->dctx, -1 /*index*/, "FindProxyForURL"); + + duk_push_string(ctx->dctx, url); + duk_push_string(ctx->dctx, host); + if (duk_pcall(ctx->dctx, 2 /*nargs*/) != 0) { + pacrunner_error("Error: %s\n", + duk_safe_to_string(ctx->dctx, -1)); + result = NULL; + } else { + result = strdup(duk_safe_to_string(ctx->dctx, -1)); + } + duk_pop(ctx->dctx); /* pop result/error */ + + if (result) { + DBG("the return string is: %s\n", result); + } + + pthread_mutex_unlock(&ctx->lock); + + return result; +} + + +static struct pacrunner_js_driver duktape_driver = { + .name = "duktape", + .priority = PACRUNNER_JS_PRIORITY_HIGH, + .set_proxy = duktape_set_proxy, + .clear_proxy = duktape_clear_proxy, + .execute = duktape_execute, +}; + +static int duktape_init(void) +{ + DBG(""); + + return pacrunner_js_driver_register(&duktape_driver); +} + + +static void duktape_exit(void) +{ + DBG(""); + + pacrunner_js_driver_unregister(&duktape_driver); + + duktape_set_proxy(NULL); +} + +PACRUNNER_PLUGIN_DEFINE(duktape, duktape_init, duktape_exit) |