/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * (C) 2013 Guido Günther */ Components.utils.import("resource://gre/modules/ctypes.jsm"); const GError = ctypes.StructType("GError"); const GCancellable = ctypes.StructType("GCancellable"); const GResolver = ctypes.StructType("GResolver"); const GSrvTarget = ctypes.StructType("GSrvTarget"); const gpointer = ctypes.void_t.ptr; var gioExist = false; try { var glib = ctypes.open("libglib-2.0.so.0"); var gobject = ctypes.open("libgobject-2.0.so.0"); var gio = ctypes.open("libgio-2.0.so.0"); gioExist = true; } catch (ex) { Components.utils.reportError("Failed to load gio: " + ex); } if (gioExist) { caDNSResolver = function() { this.gpointer = ctypes.void_t.ptr; this._GList = new ctypes.StructType("_GList"); this._GList.define([{data: this.gpointer}, {next: this._GList.ptr}, {prev: this._GList.ptr}]); this.GList = this._GList; this.g_resolver_lookup_service = gio.declare( "g_resolver_lookup_service", ctypes.default_abi, this.GList.ptr, // return type: GList GResolver.ptr, // in: the resolver to use ctypes.char.ptr, // in: the service of look for ctypes.char.ptr, // in: the protocol the service should use ctypes.char.ptr, // in: the domain the service is offerd in GCancellable.ptr, // in: the cancellable GError.ptr.ptr // out: error ); this.g_srv_target_get_hostname = gio.declare( "g_srv_target_get_hostname", ctypes.default_abi, ctypes.char.ptr, // return type: string GSrvTarget.ptr // in: Record to parse ); this.g_resolver_get_default = gio.declare( "g_resolver_get_default", ctypes.default_abi, GResolver.ptr // return type: GResolver ); this.g_resolver_free_targets = gio.declare( "g_resolver_free_targets", ctypes.default_abi, ctypes.void_t, this.GList.ptr // in: List of GSrvTargets ); this._resolver = this.g_resolver_get_default(); this.get_srv_records = function (service, proto, domain) { var ret = []; var records = this.g_resolver_lookup_service(this._resolver, service, proto, domain, null, null); if (records.isNull()) { Components.utils.reportError("Failed to lookup: " + service); return []; } else { Components.utils.reportError("records: " + records); // For PoC just look at the first record // and ignore weight and prio var tmp = records.contents.data; var rec = ctypes.cast(tmp, GSrvTarget.ptr); var val = this.g_srv_target_get_hostname (rec); ret[0] = val.readString(); Components.utils.reportError("ret: " + ret); this.g_resolver_free_targets(records); } return ret; }; }; } else { caDNSResolver = function() { this.get_srv_records = function (service, proto, domain) { return null; }; }; }