summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Barksdale <amatus.amongus@gmail.com>2010-11-03 20:46:42 -0700
committerDavid Barksdale <amatus.amongus@gmail.com>2010-11-03 20:46:42 -0700
commitd65ae1590d3de1aa605fa70a2b75a050c3889f85 (patch)
tree09fd624ff10ee6e9a8bafc1ea8007424e2b4b3c1 /src
parentfe33193b9e34492d6eb38b067e3686bc9afdf2c8 (diff)
Added new exception-m monad. Added :when-let and :when-not to domonad.
Replaced conditional with m-when. Embraced parser.clj with with-monad. Discovered str function is useful for formatting strings.
Diffstat (limited to 'src')
-rw-r--r--src/org/gnu/clojure/gnunet/core.clj336
-rw-r--r--src/org/gnu/clojure/gnunet/exception.clj17
-rw-r--r--src/org/gnu/clojure/gnunet/filesharing.clj24
-rw-r--r--src/org/gnu/clojure/gnunet/parser.clj33
-rw-r--r--src/org/gnu/clojure/gnunet/transport.clj105
5 files changed, 231 insertions, 284 deletions
diff --git a/src/org/gnu/clojure/gnunet/core.clj b/src/org/gnu/clojure/gnunet/core.clj
index f13ec9f..0c6442d 100644
--- a/src/org/gnu/clojure/gnunet/core.clj
+++ b/src/org/gnu/clojure/gnunet/core.clj
@@ -1,5 +1,5 @@
(ns org.gnu.clojure.gnunet.core
- (:use (org.gnu.clojure.gnunet parser message peer crypto)
+ (:use (org.gnu.clojure.gnunet crypto exception message parser peer)
clojure.contrib.monads)
(:import (java.util Date Calendar)))
@@ -161,146 +161,110 @@
(defn emit-messages!
[peer remote-peer messages]
- (send (:state-agent remote-peer)
- (fn [state]
- (if (:is-connected state)
- (let [transport (:connected-transport state)
- encoded-address (:connected-address state)]
- ((:emit-messages! transport) transport remote-peer
- encoded-address nil messages)))
- state)))
+ (send-do-exception-m! (:state-agent remote-peer)
+ [is-connected (fetch-val :is-connected)
+ :when is-connected
+ transport (fetch-val :connected-transport)
+ encoded-address (fetch-val :connected-address)]
+ ((:emit-messages! transport) transport remote-peer encoded-address nil
+ messages)))
(defn send-key!
[peer remote-peer]
- (send (:state-agent remote-peer)
- (fn [state]
- (if-let [public-key (deref (:public-key-atom remote-peer))]
- (if (:is-connected state)
- (let [state (if (= peer-status-down (:status state))
- (assoc state :status peer-status-key-sent)
- state)
- set-key {:sender-status (:status state)
- :creation-time (:encrypt-key-created state)
- :peer-id (:id remote-peer)
- :encrypted-key (rsa-encrypt!
- public-key
- (encode-aes-key (:encrypt-key state))
- (:random peer))}
- signed-material (encode-set-key-signed-material set-key)
- signature (rsa-sign (:private-key peer) signed-material)
- set-key (assoc set-key :signature signature)
- encoded-set-key (encode-set-key set-key signed-material)
- iv-seed (.nextInt (:random peer))
- ping {:iv-seed iv-seed
- :challenge (:ping-challenge state)
- :peer-id (:id remote-peer)}
- encoded-ping (encode-core-ping ping
- (:encrypt-key state)
- (:id remote-peer))]
- (emit-messages! peer remote-peer
- [{:message-type message-type-core-set-key
- :bytes encoded-set-key}
- {:message-type message-type-core-ping
- :bytes encoded-ping}])
- state)
- state)
- state))))
-
-(defn verify-set-key
- [peer remote-peer state message]
- (when-let [public-key (deref (:public-key-atom remote-peer))]
- (when-let [set-key (first (parse-set-key (:bytes message)))]
- (let [status (:status state)
- decrypt-key-created (:decrypt-key-created state)]
- (cond
- (not (= (:peer-id set-key) (seq (:id peer)))) nil
- (not (rsa-verify public-key
- (:signed-material set-key) (:signature set-key))) nil
- (and
- (or (= status peer-status-key-received)
- (= status peer-status-key-confirmed))
- (< 0 (.compareTo decrypt-key-created (:creation-time set-key)))) nil
- :else (when-let [decrypted-key (rsa-decrypt (:private-key peer)
- (:encrypted-key set-key))]
- ;; XXX: For some reason we end up with an extra 0 byte at the
- ;; beginning of the decrypted-key when the MSB is 1.
- (let [decrypted-key (drop (- (count decrypted-key)
- aes-key-size 4)
- decrypted-key)]
- (when-let [decrypt-key (first
- (parse-aes-key decrypted-key))]
- (assoc set-key :decrypt-key decrypt-key)))))))))
+ (send-do-exception-m! (:state-agent remote-peer)
+ [:when-let [public-key (deref (:public-key-atom remote-peer))]
+ is-connected (fetch-val :is-connected)
+ :when is-connected
+ _ (update-val :status #(if (= % peer-status-down) peer-status-key-sent %))
+ sender-status (fetch-val :status)
+ creation-time (fetch-val :encrypt-key-created)
+ encrypt-key (fetch-val :encrypt-key)
+ challenge (fetch-val :ping-challenge)]
+ (let [set-key {:sender-status sender-status
+ :creation-time creation-time
+ :peer-id (:id remote-peer)
+ :encrypted-key (rsa-encrypt! public-key
+ (encode-aes-key encrypt-key)
+ (:random peer))}
+ signed-material (encode-set-key-signed-material set-key)
+ signature (rsa-sign (:private-key peer) signed-material)
+ set-key (assoc set-key :signature signature)
+ encoded-set-key (encode-set-key set-key signed-material)
+ iv-seed (.nextInt (:random peer))
+ ping {:iv-seed iv-seed
+ :challenge challenge
+ :peer-id (:id remote-peer)}
+ encoded-ping (encode-core-ping ping encrypt-key (:id remote-peer))]
+ (emit-messages! peer remote-peer
+ [{:message-type message-type-core-set-key :bytes encoded-set-key}
+ {:message-type message-type-core-ping :bytes encoded-ping}]))))
(defn handle-set-key!
[peer remote-peer message]
- (send (:state-agent remote-peer)
- (fn [state]
- (if-let [set-key (verify-set-key peer remote-peer state message)]
- (let [decrypt-key (:decrypt-key set-key)
- state (assoc state :decrypt-key decrypt-key)
- decrypt-key-created (:decrypt-key-created state)
- creation-time (:creation-time set-key)
- state (if (= decrypt-key-created creation-time)
- state
- (conj state {:last-sequence-number-received 0
- :last-packets-bitmap (int 0)
- :decrypt-key-created creation-time}))
- status (:status state)
- sender-status (:sender-status set-key)]
- (condp contains? status
- #{peer-status-down}
- (do (send-key! peer remote-peer)
- (assoc state :status peer-status-key-received))
- #{peer-status-key-sent
- peer-status-key-received}
- (do (if (and (not (= sender-status peer-status-key-received))
- (not (= sender-status peer-status-key-confirmed)))
- (send-key! peer remote-peer))
- (assoc state :status peer-status-key-received))
- #{peer-status-key-confirmed}
- (do (if (and (not (= sender-status peer-status-key-received))
- (not (= sender-status peer-status-key-confirmed)))
- (send-key! peer remote-peer))
- state)
- state))
- state))))
+ (send-do-exception-m! (:state-agent remote-peer)
+ [:when-let [public-key (deref (:public-key-atom remote-peer))]
+ :when-let [set-key (first (parse-set-key (:bytes message)))]
+ :when (= (:peer-id set-key) (:id peer))
+ :when (rsa-verify public-key
+ (:signed-material set-key) (:signature set-key))
+ status (fetch-val :status)
+ decrypt-key-created (fetch-val :decrypt-key-created)
+ :when-not (and
+ (or (= status peer-status-key-received)
+ (= status peer-status-key-confirmed))
+ (.after decrypt-key-created (:creation-time set-key)))
+ :when-let [decrypted-key (rsa-decrypt (:private-key peer)
+ (:encrypted-key set-key))]
+ ;; XXX: For some reason we end up with an extra 0 byte at the
+ ;; beginning of the decrypted-key when the MSB is 1.
+ :let [decrypted-key (drop (- (count decrypted-key) aes-key-size 4)
+ decrypted-key)]
+ :when-let [decrypt-key (first (parse-aes-key decrypted-key))]
+ _ (set-val :decrypt-key decrypt-key)
+ :let [creation-time (:creation-time set-key)]
+ _ (update-state #(if (= decrypt-key-created creation-time)
+ %
+ (conj % {:last-sequence-number-received 0
+ :last-packets-bitmap (int 0)
+ :decrypt-key-created creation-time})))
+ :let [sender-status (:sender-status set-key)]
+ _ (update-val :status
+ #(if (= % peer-status-key-confirmed) % peer-status-key-received))]
+ (when (or (= status peer-status-down)
+ (and (not (= sender-status peer-status-key-received))
+ (not (= sender-status peer-status-key-confirmed))))
+ (send-key! peer remote-peer))))
(defn handle-core-ping!
[peer remote-peer message]
- (send (:state-agent remote-peer)
- (fn [state]
- (when-let [decrypt-key (:decrypt-key state)]
- (when-let [ping (first ((parse-core-ping decrypt-key (:id peer))
- (:bytes message)))]
- (when (= (:peer-id ping) (:id peer))
- (let [iv-seed (.nextInt (:random peer))
- pong {:iv-seed iv-seed
- :challenge (:challenge ping)
- :inbound-bw-limit (:bw-in state)
- :peer-id (:id peer)}
- encoded-pong (encode-core-pong pong
- (:encrypt-key state) (:id remote-peer))]
- (emit-messages! peer remote-peer
- [{:message-type message-type-core-pong
- :bytes encoded-pong}])))))
- state)))
+ (send-do-exception-m! (:state-agent remote-peer)
+ [decrypt-key (fetch-val :decrypt-key)
+ :when decrypt-key
+ :when-let [ping (first ((parse-core-ping decrypt-key (:id peer))
+ (:bytes message)))]
+ bw-in (fetch-val :bw-in)
+ encrypt-key (fetch-val :encrypt-key)]
+ (let [iv-seed (.nextInt (:random peer))
+ pong {:iv-seed iv-seed
+ :challenge (:challenge ping)
+ :inbound-bw-limit bw-in
+ :peer-id (:id peer)}
+ encoded-pong (encode-core-pong pong encrypt-key (:id remote-peer))]
+ (emit-messages! peer remote-peer
+ [{:message-type message-type-core-pong :bytes encoded-pong}]))))
(defn handle-core-pong!
[peer remote-peer message]
- (send (:state-agent remote-peer)
- (fn [state]
- (if-let [decrypt-key (:decrypt-key state)]
- (if-let [pong (first ((parse-core-pong decrypt-key
- (:ping-challenge state) (:id peer))
- (:bytes message)))]
- (if (= (:peer-id pong) (:id remote-peer))
- (condp = (:status state)
- peer-status-key-received (assoc state :status
- peer-status-key-confirmed)
- state)
- state)
- state)
- state))))
+ (send-do-exception-m! (:state-agent remote-peer)
+ [decrypt-key (fetch-val :decrypt-key)
+ :when decrypt-key
+ challenge (fetch-val :ping-challenge)
+ :when-let [pong (first ((parse-core-pong decrypt-key
+ challenge (:id peer)) (:bytes message)))]
+ :when (= (:peer-id pong) (:id remote-peer))
+ status (fetch-val :status)
+ :when (= status peer-status-key-received)
+ _ (set-val :status peer-status-key-confirmed)] nil))
(defn admit-core-message!
[peer remote-peer message]
@@ -308,75 +272,57 @@
(:message-type message))]
(doseq [dispatcher! dispatchers]
(dispatcher! peer remote-peer message))
- (do
- (.write *out* "No dispatcher for message type ")
- (.write *out* (.toString (:message-type message)))
- (.write *out* "\n"))))
+ (.write *out* (str "No dispatcher for message type "
+ (:message-type message) "\n"))))
(defn handle-core-encrypted-message!
[peer remote-peer message]
- (send (:state-agent remote-peer)
- (fn [state]
- (if-let [decrypt-key (:decrypt-key state)]
- (if-let [message (first ((parse-core-encrypted-message decrypt-key
- (:decrypt-key-created state) (:id peer))
- (:bytes message)))]
- (let [last-seqnum-received (:last-sequence-number-received state)
- seqnum (:sequence-number message)]
- (cond
- (.before (:timestamp message) (message-expiration))
- state
- (== last-seqnum-received seqnum)
- state
- (> last-seqnum-received (+ 32 seqnum))
- state
- (> last-seqnum-received seqnum)
- (let [bit (bit-set 0 (- last-seqnum-received seqnum 1))
- bitmap (:last-packets-bitmap state)]
- (if (bit-test bitmap bit)
- state
- (do
- ;; TODO: update bandwidth tracking
- (doseq [message (:messages message)]
- (admit-core-message! peer remote-peer message))
- (assoc state :last-packets-bitmap (bit-or bitmap bit)))))
- (< last-seqnum-received seqnum)
- (let [bitmap (.intValue
- (bit-shift-left
- (bigint (:last-packets-bitmap state))
- (- seqnum last-seqnum-received)))]
- ;; TODO: update bandwidth tracking
- (doseq [message (:messages message)]
- (admit-core-message! peer remote-peer message))
- (conj state {:last-packets-bitmap bitmap
- :last-sequence-number-received seqnum}))
- :else state))
- state)
- state))))
-
-(defn initialize-remote-peer-state
- [peer state]
- (conj state
- {:status peer-status-down
- :decrypt-key-created (Date. (long 0))
- :encrypt-key (generate-aes-key! (:random peer))
- :encrypt-key-created (Date.)
- :ping-challenge (.nextInt (:random peer))
- ;; TODO: Make this a real number
- :bw-in 20000}))
+ (send-do-exception-m! (:state-agent remote-peer)
+ [decrypt-key (fetch-val :decrypt-key)
+ :when decrypt-key
+ decrypt-key-created (fetch-val :decrypt-key-created)
+ :when-let [message (first
+ ((parse-core-encrypted-message decrypt-key
+ decrypt-key-created (:id peer)) (:bytes message)))]
+ last-seqnum (fetch-val :last-sequence-number-received)
+ :let [seqnum (:sequence-number message)]
+ :when-not (== last-seqnum seqnum)
+ :when-not (> last-seqnum (+ 32 seqnum))
+ bitmap (fetch-val :last-packets-bitmap)
+ :let [bit (- last-seqnum seqnum 1)]
+ :when-not (and (> last-seqnum seqnum) (bit-test bitmap bit))
+ _ (update-state
+ #(if (> last-seqnum seqnum)
+ (assoc % :last-packets-bitmap (bit-set bitmap bit))
+ (conj %
+ {:last-sequence-number-received seqnum
+ :last-packets-bitmap (.intValue
+ (bit-shift-left (bigint bitmap)
+ (- seqnum last-seqnum)))})))
+ :when-not (.before (:timestamp message) (message-expiration))
+ ;; TODO: update bandwidth tracking
+ ]
+ (doseq [message (:messages message)]
+ (admit-core-message! peer remote-peer message))))
(defn handle-receive!
[peer remote-peer message]
- (send (:state-agent remote-peer)
- (fn [state]
- (let [state (if (contains? state :status)
- state
- (initialize-remote-peer-state peer state))]
- (condp = (:message-type message)
- message-type-core-set-key (handle-set-key! peer remote-peer message)
- message-type-core-encrypted-message (handle-core-encrypted-message!
- peer remote-peer message)
- message-type-core-ping (handle-core-ping! peer remote-peer message)
- message-type-core-pong (handle-core-pong! peer remote-peer message)
- nil)
- state))))
+ (send-do-exception-m! (:state-agent remote-peer)
+ [_ (update-state
+ #(if (contains? % :status)
+ %
+ (conj %
+ {:status peer-status-down
+ :decrypt-key-created (Date. (long 0))
+ :encrypt-key (generate-aes-key! (:random peer))
+ :encrypt-key-created (Date.)
+ :ping-challenge (.nextInt (:random peer))
+ ;; TODO: Make this a real number
+ :bw-in 20000})))]
+ (condp = (:message-type message)
+ message-type-core-set-key (handle-set-key! peer remote-peer message)
+ message-type-core-encrypted-message (handle-core-encrypted-message!
+ peer remote-peer message)
+ message-type-core-ping (handle-core-ping! peer remote-peer message)
+ message-type-core-pong (handle-core-pong! peer remote-peer message)
+ nil)))
diff --git a/src/org/gnu/clojure/gnunet/exception.clj b/src/org/gnu/clojure/gnunet/exception.clj
new file mode 100644
index 0000000..456bc05
--- /dev/null
+++ b/src/org/gnu/clojure/gnunet/exception.clj
@@ -0,0 +1,17 @@
+(ns org.gnu.clojure.gnunet.exception
+ (:use clojure.contrib.monads))
+
+(def exception-m (maybe-t state-m :exception))
+
+(with-monad exception-m
+
+(def nop (m-result nil))
+
+(def break m-zero)
+)
+
+(defmacro send-do-exception-m!
+ [target-agent steps expr]
+ `(send ~target-agent
+ (fn [state#]
+ (second ((domonad exception-m ~steps ~expr) state#)))))
diff --git a/src/org/gnu/clojure/gnunet/filesharing.clj b/src/org/gnu/clojure/gnunet/filesharing.clj
index 16c22b4..b253219 100644
--- a/src/org/gnu/clojure/gnunet/filesharing.clj
+++ b/src/org/gnu/clojure/gnunet/filesharing.clj
@@ -18,11 +18,11 @@
filter-mutator parse-int32
hash-bitmap parse-int32
query (items hash-size)
- return-to (conditional (bit-test hash-bitmap bit-return-to)
+ return-to (m-when (bit-test hash-bitmap bit-return-to)
(items id-size))
- sks-namespace (conditional (bit-test hash-bitmap bit-sks-namespace)
+ sks-namespace (m-when (bit-test hash-bitmap bit-sks-namespace)
(items hash-size))
- transmit-to (conditional (bit-test hash-bitmap bit-transmit-to)
+ transmit-to (m-when (bit-test hash-bitmap bit-transmit-to)
(items id-size))
bloomfilter (optional (parse-bloomfilter bloomfilter-k))]
{:block-type block-type
@@ -35,23 +35,15 @@
:transmit-to transmit-to
:bloomfilter bloomfilter}))
-(defn bound-priority
- [priority remote-peer]
- )
-
(defn admit-get!
[peer remote-peer message]
(when-let [get-message (first (parse-get-message (:bytes message)))]
- (.write *out* (.toString get-message))
- (.write *out* "\n")
- )
- (when-let [return-to (if (:return-to message)
- ((deref (:remote-peers-agent peer))
- (:return-to message))
- remote-peer)]
- (when-let [priority (bound-priority (:priority message) remote-peer)]
+ (.write *out* (str get-message "\n"))
+ (when-let [return-to (if (:return-to get-message)
+ ((deref (:remote-peers-agent peer))
+ (:return-to get-message))
+ remote-peer)]
)))
-
(defn admit-put!
[peer remote-peer message])
diff --git a/src/org/gnu/clojure/gnunet/parser.clj b/src/org/gnu/clojure/gnunet/parser.clj
index c96b293..e931e90 100644
--- a/src/org/gnu/clojure/gnunet/parser.clj
+++ b/src/org/gnu/clojure/gnunet/parser.clj
@@ -3,6 +3,8 @@
(def parser-m (state-t maybe-m))
+(with-monad parser-m
+
(defn parser-m-until
"An optimized implementation of m-until for the parser monad that
replaces recursion by a loop."
@@ -22,28 +24,20 @@
(defn satisfy
"Produces a parser that matches an item which satisfies the given predicate."
[p]
- (domonad parser-m [x item
- :when (p x)]
+ (domonad
+ [x item
+ :when (p x)]
x))
(defn match-one
"Match the first in a list of parsers."
[& mvs]
- (with-monad parser-m
- (apply m-plus mvs)))
+ (apply m-plus mvs))
(defn optional
"Makes a parser optional."
[mv]
- (with-monad parser-m
- (m-plus mv (m-result nil))))
-
-(defn conditional
- "Returns the parser on a condition, otherwise a parser that returns nil."
- [condition mv]
- (if condition
- mv
- (with-monad parser-m (m-result nil))))
+ (match-one mv (m-result nil)))
(defn none-or-more
"Makes a parser repeat none or more times."
@@ -61,8 +55,9 @@
(defn one-or-more
"Makes a parser repeat one or more times."
[mv]
- (domonad parser-m [x mv
- xs (none-or-more mv)]
+ (domonad
+ [x mv
+ xs (none-or-more mv)]
(cons x xs)))
(defn n-times
@@ -78,6 +73,8 @@
[0 []]) s)]
[(second (first xs)) (second xs)])))
-(def
- #^{:doc "Produces a parser that matches a number of items."}
- items (partial n-times item))
+(defn items
+ "Produces a parser that matches a number of items."
+ [n]
+ (n-times item n))
+)
diff --git a/src/org/gnu/clojure/gnunet/transport.clj b/src/org/gnu/clojure/gnunet/transport.clj
index 6eca59a..1ad910f 100644
--- a/src/org/gnu/clojure/gnunet/transport.clj
+++ b/src/org/gnu/clojure/gnunet/transport.clj
@@ -1,5 +1,6 @@
(ns org.gnu.clojure.gnunet.transport
- (:use (org.gnu.clojure.gnunet parser message hello peer util crypto core)
+ (:use (org.gnu.clojure.gnunet core crypto exception hello message parser peer
+ util)
clojure.contrib.monads)
(:import (java.util Date Calendar)))
@@ -32,10 +33,11 @@
(:encoded-address ping)))))
(def parse-ping
- (domonad parser-m [challenge parse-uint32
- peer-id (items id-size)
- transport (optional parse-utf8)
- encoded-address (none-or-more item)]
+ (domonad parser-m
+ [challenge parse-uint32
+ peer-id (items id-size)
+ transport (optional parse-utf8)
+ encoded-address (none-or-more item)]
{:challenge challenge
:peer-id peer-id
:transport transport
@@ -173,20 +175,22 @@
(defn verify-transport-address
[peer remote-peer address]
- (if (or (contains? address :latency)
- (contains? address :send-time))
- address
- (if-let [transport ((deref (:transports-agent peer))
- (:transport address))]
- (let [challenge (.nextInt (:random peer))]
- ((:emit-messages! transport) transport remote-peer
- (:encoded-address address) nil
- [(hello-for-peer-message peer)
- (ping-message remote-peer address challenge)])
- (conj address
- {:send-time (Date.) ;; TODO: Now is not the actual send time.
- :challenge challenge}))
- address)))
+ (second
+ ((domonad exception-m
+ [address (fetch-state)
+ :when (not (or (contains? address :latency)
+ (contains? address :send-time)))
+ :when-let [transport ((deref (:transports-agent peer))
+ (:transport address))]
+ :let [challenge (.nextInt (:random peer))]
+ _ (set-state
+ (conj address
+ {:send-time (Date.) ;; TODO: Now is not the actual send time.
+ :challenge challenge}))]
+ ((:emit-messages! transport) transport remote-peer
+ (:encoded-address address) nil
+ [(hello-for-peer-message peer)
+ (ping-message remote-peer address challenge)])) address)))
(defn verify-transport-addresses
[addresses peer remote-peer]
@@ -217,11 +221,11 @@
(defn send-pong-own!
[peer remote-peer ping]
- (if-let [transport-addresses ((deref (:transport-addresses-agent peer))
- (:transport ping))]
+ (when-let [transport-addresses ((deref (:transport-addresses-agent peer))
+ (:transport ping))]
;; XXX: Here we're looking for an exact match, gnunet allows transport
;; plugins to do inexact matches.
- (if (contains? transport-addresses (:encoded-address ping))
+ (when (contains? transport-addresses (:encoded-address ping))
(let [pong {:challenge (:challenge ping)
:signature-purpose signature-purpose-pong-own
:expiration (pong-expiration)
@@ -237,8 +241,8 @@
(doseq [transport-addresses (deref
(:transport-addresses-agent remote-peer))
address (val transport-addresses)]
- (if-let [transport ((deref (:transports-agent peer))
- (key transport-addresses))]
+ (when-let [transport ((deref (:transports-agent peer))
+ (key transport-addresses))]
((:emit-messages! transport) transport remote-peer (key address) nil
[{:message-type message-type-pong :bytes encoded-pong}])))))))
@@ -255,39 +259,30 @@
(:transport ping) (send-pong-own! peer remote-peer ping)
:else (send-pong-using! peer remote-peer ping))))
-(defn check-pending-validation
- [addresses remote-peer pong]
- (if-let [public-key (deref (:public-key-atom remote-peer))]
- (if-let [transport (addresses (:transport pong))]
- (if-let [address (transport (:encoded-address pong))]
- (cond
- (not (= (:challenge address) (:challenge pong))) addresses
- (= signature-purpose-pong-own (:signature-purpose pong))
- (if (rsa-verify public-key
- (:signed-material pong)
- (:signature pong))
- (assoc addresses (:transport pong)
- (assoc transport (:encoded-address pong)
- {:expiration (hello-address-expiration)
- :latency (- (.getTime (Date.))
- (.getTime (:send-time address)))}))
- addresses)
- (= signature-purpose-pong-using (:signature-purpose pong))
- ;; TODO - fill in this case
- addresses
- :else addresses)
- addresses)
- addresses)
- addresses))
-
(defn handle-pong!
[peer message]
- (when-let [pong (first (parse-pong (:bytes message)))]
- (if (not (.after (Date.) (:expiration pong)))
- (when-let [remote-peer ((deref (:remote-peers-agent peer))
- (:peer-id pong))]
- (send (:transport-addresses-agent remote-peer) check-pending-validation
- remote-peer pong)))))
+ (domonad maybe-m
+ [pong (first (parse-pong (:bytes message)))
+ :when (not (.after (Date.) (:expiration pong)))
+ remote-peer ((deref (:remote-peers-agent peer)) (:peer-id pong))
+ public-key (deref (:public-key-atom remote-peer))]
+ (send-do-exception-m! (:transport-addresses-agent remote-peer)
+ [address (with-state-field (:transport pong)
+ (fetch-val (:encoded-address pong)))
+ :when (= (:challenge address) (:challenge pong))
+ _ (cond
+ (= signature-purpose-pong-own (:signature-purpose pong))
+ (if (rsa-verify public-key (:signed-material pong) (:signature pong))
+ (with-state-field (:transport pong)
+ (set-val (:encoded-address pong)
+ {:expiration (hello-address-expiration)
+ :latency (- (.getTime (Date.))
+ (.getTime (:send-time address)))}))
+ break)
+ (= signature-purpose-pong-using (:signature-purpose pong))
+ ;; TODO - fill in this case
+ break
+ :else break)] nil)))
(defn emit-continuation!
[peer transport remote-peer encoded-address result]