aboutsummaryrefslogtreecommitdiff
path: root/src/cljs/gnunet_web/service.cljs
blob: 0eea5a2c392c7a77a3b16b0adedef749fad9a804 (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
;; service.cljs - service manager for gnunet-web website
;; Copyright (C) 2013-2018  David Barksdale <amatus@amat.us>
;;
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program 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 General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

(ns gnunet-web.service
  (:require [cognitect.transit :as t]
            [gnunet-web.webrtc :refer [peer-connect]]))

(def private-key
  ;; XXX This has no synchronization!
  (let [d (.getItem js/localStorage "private-key")]
    (if (nil? d)
      (let [d (js/Uint8Array. 32)
            _ (js/window.crypto.getRandomValues d)
            d (vec (.apply js/Array (array) d))]
        (.setItem js/localStorage "private-key" (t/write (t/writer :json) d))
        d)
      (t/read (t/reader :json) d))))

(def services (atom {}))

(defn add-service
  [service-name port]
  (swap! services assoc service-name port))

(def client-connect)

(defn start-worker
  [worker-name uri]
  (let [worker (js/SharedWorker. uri)
        port (.-port worker)
        random-bytes (js/Uint8Array. 4080)
        _ (js/window.crypto.getRandomValues random-bytes)]
    (set! (.-onerror worker)
          (fn [event]
            (.error js/console
                    worker-name
                    (.-filename event)
                    (.-lineno event)
                    (.-message event))))
    (set! (.-onmessage port)
          (try
            (fn [event]
              (let [data (.-data event)]
                (condp = (.-type data)
                  "init" (do
                           (set! (.-onmessage (aget data "stdout"))
                                 (fn [event]
                                   (.debug js/console
                                           worker-name
                                           (.-data event))))
                           (set! (.-onmessage (aget data "stderr"))
                                 (fn [event]
                                   (.debug js/console
                                           worker-name
                                           (.-data event)))))
                  "client_connect" (client-connect (aget data "service_name")
                                                   (aget data "client_name")
                                                   (aget data "message_port"))
                  "peer_connect" (peer-connect (aget data "message_port") (aget data "offer"))
                  (.warn js/console worker-name data))))
          (catch :default e
            (js/console.error "REKT" e))))
    (.start port)
    (.postMessage port (js-obj "type" "init"
                               "private-key" (to-array private-key)
                               "random-bytes" random-bytes))
    worker))

(defn ^:export client-connect
  [service-name client-name message-port]
  (js/console.debug "client" client-name "wants to connect to" service-name)
  (let [service (get @services service-name)]
    (if (nil? service)
      (let [worker (start-worker service-name
                                 (str "js/gnunet-service-" service-name ".js"))
            port (.-port worker)]
        (add-service service-name port)
        (recur service-name client-name message-port))
      (.postMessage service (js-obj "type" "connect"
                                    "client-name" client-name
                                    "port" message-port)
                    (array message-port)))))