summaryrefslogtreecommitdiff
path: root/content/caDNSResolver.js
blob: f6b029fa3040f19cf1c113a81edcdbaf38694666 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/* 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 <agx@sigxcpu.org>
 */

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;
        };
    };
}