diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/org/gnu/clojure/gnunet/hello.clj | 24 | ||||
-rw-r--r-- | src/org/gnu/clojure/gnunet/peer.clj | 13 | ||||
-rw-r--r-- | src/org/gnu/clojure/gnunet/transport.clj | 106 | ||||
-rw-r--r-- | src/org/gnu/clojure/gnunet/udp.clj | 34 |
4 files changed, 101 insertions, 76 deletions
diff --git a/src/org/gnu/clojure/gnunet/hello.clj b/src/org/gnu/clojure/gnunet/hello.clj index d25659e..6ad2b45 100644 --- a/src/org/gnu/clojure/gnunet/hello.clj +++ b/src/org/gnu/clojure/gnunet/hello.clj @@ -4,20 +4,20 @@ (def message-type-hello 16) -(defn encode-transport - [transport] +(defn encode-transport-address + [address] (concat - (encode-utf8 (:name transport)) - (encode-int16 (count (:encoded-address transport))) - (encode-date (:expiration transport)) - (:encoded-address transport))) + (encode-utf8 (:transport address)) + (encode-int16 (count (:encoded-address address))) + (encode-date (:expiration address)) + (:encoded-address address))) -(def parse-transport - (domonad parser-m [name- parse-utf8 +(def parse-transport-address + (domonad parser-m [transport parse-utf8 address-length parse-uint16 expiration parse-date encoded-address (items address-length)] - {:name name- + {:transport transport :expiration expiration :encoded-address encoded-address})) @@ -27,12 +27,12 @@ (concat (encode-int32 0) (encode-rsa-public-key (:public-key hello)) - (mapcat encode-transport (:transports hello)))) + (mapcat encode-transport-address (:transport-addresses hello)))) (def parse-hello (domonad parser-m [padding parse-uint32 :when (== padding 0) public-key parse-rsa-public-key - transports (none-or-more parse-transport)] + addresses (none-or-more parse-transport-address)] {:public-key public-key - :transports transports})) + :transport-addresses addresses})) diff --git a/src/org/gnu/clojure/gnunet/peer.clj b/src/org/gnu/clojure/gnunet/peer.clj index e9f3b06..1424206 100644 --- a/src/org/gnu/clojure/gnunet/peer.clj +++ b/src/org/gnu/clojure/gnunet/peer.clj @@ -11,7 +11,7 @@ ;; agent of a map associating transport names (strings) to maps associating ;; transport addresses (byte vector) to maps containing {:expiration ;; (java.util.Date) :latency (int, if ever connected)} - :transports-agent + :transport-addresses-agent ;; agent of ?? :connection-agent) @@ -23,7 +23,11 @@ :private-key ;; agent of a map of peer IDs to struct remote-peer - :remote-peers-agent)))) + :remote-peers-agent + + ;; agent of a map of transport names (String) to maps of {:connect! + ;; :emit-message!} + :transports-agent)))) (defstruct peer-options :keypair) @@ -39,6 +43,7 @@ (struct-map peer :public-key (.getPublic (:keypair options)) :id (generate-id (.getPublic (:keypair options))) - :transports-agent (agent {}) + :transport-addresses-agent (agent {}) :private-key (.getPrivate (:keypair options)) - :remote-peers-agent (agent {}))) + :remote-peers-agent (agent {}) + :transports-agent (agent nil))) diff --git a/src/org/gnu/clojure/gnunet/transport.clj b/src/org/gnu/clojure/gnunet/transport.clj index 7baeb67..c35bcaa 100644 --- a/src/org/gnu/clojure/gnunet/transport.clj +++ b/src/org/gnu/clojure/gnunet/transport.clj @@ -13,16 +13,16 @@ [& coll] (last (sort (filter #(not (nil? %)) coll)))) -(defn list-transports +(defn list-transport-addresses "Generate a list of transport descriptions." - [transport-map] - (for [transport transport-map + [addresses-map] + (for [transport addresses-map address (val transport)] (conj - {:name (key transport) :encoded-address (key address)} + {:transport (key transport) :encoded-address (key address)} (val address)))) -(defn merge-addresses +(defn merge-address-info "Merge two address-info maps." [a b] (let [expiration (my-max (:expiration a) (:expiration b)) @@ -31,47 +31,49 @@ {:expiration expiration :latency latency} {:expiration expiration}))) -(defn merge-transports +(defn merge-transport-addresses "Merge a list of transport descriptions into a transports-agent map. The input list is generated from parse-hello or list-transports. The input map is described in peer.clj." - [transport-map transport-list] - (reduce (fn [transport-map transport] - (if-let [addresses (transport-map (:name transport))] - (if-let [address (addresses (:encoded-address transport))] - (assoc transport-map (:name transport) - (assoc addresses (:encoded-address transport) - (merge-addresses address transport))) - (assoc transport-map (:name transport) - (assoc addresses (:encoded-address transport) - (dissoc transport :name :encoded-address)))) - (assoc transport-map (:name transport) - {(:encoded-address transport) - (dissoc transport :name :encoded-address)}))) - transport-map - transport-list)) + [address-map address-list] + (reduce (fn [address-map new-address] + (if-let [transport (address-map (:transport new-address))] + (if-let [address-info (transport (:encoded-address new-address))] + (assoc address-map (:transport new-address) + (assoc transport (:encoded-address new-address) + (merge-address-info address-info new-address))) + (assoc address-map (:transport new-address) + (assoc transport (:encoded-address new-address) + (dissoc new-address :transport :encoded-address)))) + (assoc address-map (:transport new-address) + {(:encoded-address new-address) + (dissoc new-address :transport :encoded-address)}))) + address-map + address-list)) -(defn expire-transports - [min-expiration transport-list] - (filter #(>= 0 (compare min-expiration (:expiration %))) transport-list)) +(defn expire-transport-addresses + [min-expiration addresses-list] + (filter #(>= 0 (compare min-expiration (:expiration %))) addresses-list)) (defn new-remote-peer-from-hello [hello] (struct-map remote-peer :public-key (:public-key hello) :id (generate-id (:public-key hello)) - :transports-agent (agent (merge-transports {} (:transports hello))))) + :transport-addresses-agent (agent (merge-transport-addresses {} + (:transport-addresses hello))) + :connection-agent (agent nil))) ;; Event - Peer receives a HELLO message (defn admit-hello! "Updates the remote-peers map with new information contained in a hello and expires old addresses." [peer hello] - (letfn [(update-transports - [transports new-transports] - (merge-transports {} - (expire-transports (Date.) (concat (list-transports transports) - new-transports)))) + (letfn [(update-transport-addresses + [addresses new-addresses] + (merge-transport-addresses {} + (expire-transport-addresses (Date.) + (concat (list-transport-addresses addresses) new-addresses)))) (update-remote-peers [remote-peers hello] (let [id (vec (generate-id (:public-key hello))) @@ -79,9 +81,9 @@ (if remote-peer (do (send - (:transports-agent remote-peer) - update-transports - (:transports hello)) + (:transport-addresses-agent remote-peer) + update-transport-addresses + (:transport-addresses hello)) remote-peers) (assoc remote-peers id (new-remote-peer-from-hello hello)))))] (send (:remote-peers-agent peer) update-remote-peers hello))) @@ -100,21 +102,27 @@ {:challenge challenge :peer-id peer-id})) (defn best-transport - [remote-peer] - (let [transports (deref (:transports-agent remote-peer)) - current-transports (expire-transports (Date.) (list-transports - transports)) - usable-transports (filter #(contains? my-transports (key %)) - current-transports) - best (first usable-transports)] - [(my-transports (key best)) (val best)])) - -(defn send-message! - "Sends message to remote-peer." - [remote-peer message] - (let [[transport-send! addresses] (best-transport remote-peer)] - (transport-send! remote-peer addresses message))) + [peer remote-peer] + (let [addresses (deref (:transport-addressess-agent remote-peer)) + current-addresses (expire-transport-addresses (Date.) + (list-transport-addresses addresses)) + transports (deref (:transports-agent peer)) + usable-addresses (filter #(contains? transports (:transport %)) + current-addresses) + sorted-addresses (sort-by #(if-let [latency (:latency %)] latency 0) + usable-addresses) + best (first sorted-addresses)] + {:address best + :transport (transports (:transport best))})) (defn connect-to-peer! - [remote-peer] - ) + [peer remote-peer] + (send (:connection-agent remote-peer) + (fn [connection] + (if (nil? connection) + (let [{transport :transport address :address} (best-transport peer + remote-peer)] + (do + ((:connect! transport) peer remote-peer address) + {:transport transport + :transport-name (:transport address)})))))) diff --git a/src/org/gnu/clojure/gnunet/udp.clj b/src/org/gnu/clojure/gnunet/udp.clj index 10d4f9e..fc58e3a 100644 --- a/src/org/gnu/clojure/gnunet/udp.clj +++ b/src/org/gnu/clojure/gnunet/udp.clj @@ -5,19 +5,19 @@ (defn configure-udp-addresses! "Adds new addresses for the udp transport to peer's transports-agent expiring - in 30 days and removes expired addresses." - [peer addresses port] - (send (:transports-agent peer) - (fn [transports] - (merge-transports {} - (expire-transports (Date.) - (concat (list-transports transports) - (for [address addresses] - {:name "udp" + in 12 hours and removes expired addresses." + [peer local-addresses port] + (send (:transport-addresses-agent peer) + (fn [addresses] + (merge-transport-addresses {} + (expire-transport-addresses (Date.) + (concat (list-transport-addresses addresses) + (for [address local-addresses] + {:transport "udp" :encoded-address (encode-address (InetSocketAddress. address port)) :expiration (.getTime (doto (Calendar/getInstance) - (.add Calendar/DAY_OF_MONTH 30)))}))))))) + (.add Calendar/HOUR_OF_DAY 12)))}))))))) (defn pick-address [addresses] @@ -26,7 +26,7 @@ parsed-addresses)] (first usable-addresses))) -(defn udp-send! +(defn emit-message-udp! [remote-peer addresses encoded-message] (let [address (pick-address addresses)] )) @@ -35,3 +35,15 @@ (domonad parser-m [peer-id (parse-uint id-size) messages (none-or-more parse-message)] {:peer-id peer-id :messages messages})) + +(defn connect-udp! + [peer remote-peer address] + ) + +(defn activate-udp! + [peer] + (send (:transports-agent peer) + (fn [transports] + (assoc transports "udp" + {:connect! connect-udp! + :emit-message! emit-message-udp!})))) |