blob: 2eac9785c7e7cacbf53047ad51f5e86a5866d812 (
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
100
|
(ns org.gnu.clojure.gnunet.peer
(:use (org.gnu.clojure.gnunet crypto message util))
(:import java.nio.channels.Selector
java.util.concurrent.ConcurrentLinkedQueue
java.security.SecureRandom))
(defstruct remote-peer-struct
;; atom of java.security.PublicKey
:public-key-atom
;; 64 byte (512-bit) vector
:id
;; agent of a map associating transport names (String) to maps associating
;; transport addresses (byte vector) to maps containing {:expiration
;; (java.util.Date) :latency (int, if validated)}
:transport-addresses-agent
;; agent of a map of state (nil for local peer?)
;; { (shared between layers)
;; :is-connected (boolean)
;; :connected-transport (value from peer-struct:transports-agent)
;; :connected-address (byte vector)
;; (core layer)
;; :status peer-status-down (int)
;; :decrypt-key-created (java.util.Date)
;; :encrypt-key (java.security.Key)
;; :encrypt-key-created (java.util.Date)
;; :ping-challenge (int)
;; :bw-in (int)
;; (filesharing layer)
;; :trust (int)
;; :average-priority (float)}
:state-agent)
(def peer-struct (apply create-struct (concat
(keys (struct-map remote-peer-struct))
(list
;; java.security.PrivateKey
:private-key
;; agent of a map of peer IDs to struct remote-peer
:remote-peers-agent
;; agent of a map of transport names (String) to maps of {:emit-message!}
:transports-agent
;; agent of a map of message types to sets of dispatch handlers
:dispatch-agent
;; java.nio.channels.Selector
:selector
;; Thread which selects on :selector
:selector-thread
;; java.util.concurrent.ConcurrentLinkedQueue of continuations, in order to
;; access the selector while the selector-thread is running add a
;; continuation to this queue and call .wakeup on the selector
:selector-continuations-queue
;; java.security.SecureRandom
:random))))
(defstruct peer-options
:keypair)
(defn generate-id
"Generate the SHA-512 digest of the encoded public key."
[public-key]
(vec (sha-512 (encode-rsa-public-key public-key))))
(def id-size hash-size)
(defn selector-loop!
[selector continuations]
(doseq [continuation (queue-seq! continuations)]
(continuation))
(.select selector)
(let [selected-keys (.selectedKeys selector)]
(doseq [selection-key selected-keys]
((.attachment selection-key) selection-key))
(.clear selected-keys))
(recur selector continuations))
(defn new-peer [options]
(let [selector (Selector/open)
continuations (ConcurrentLinkedQueue.)]
(struct-map peer-struct
:public-key-atom (atom (.getPublic (:keypair options)))
:id (generate-id (.getPublic (:keypair options)))
:transport-addresses-agent (agent {})
:private-key (.getPrivate (:keypair options))
:remote-peers-agent (agent {})
:transports-agent (agent {})
:dispatch-agent (agent {})
:selector selector
:selector-thread (Thread. (partial selector-loop! selector continuations))
:selector-continuations-queue continuations
:random (:random options))))
|