diff options
Diffstat (limited to 'src/Network/Tox/DHT')
-rw-r--r-- | src/Network/Tox/DHT/Handlers.hs | 36 | ||||
-rw-r--r-- | src/Network/Tox/DHT/Transport.hs | 31 |
2 files changed, 47 insertions, 20 deletions
diff --git a/src/Network/Tox/DHT/Handlers.hs b/src/Network/Tox/DHT/Handlers.hs index 6bbcfb43..d010f36d 100644 --- a/src/Network/Tox/DHT/Handlers.hs +++ b/src/Network/Tox/DHT/Handlers.hs | |||
@@ -22,6 +22,7 @@ import qualified Data.ByteString.Char8 as C8 | |||
22 | import qualified Data.ByteString.Base16 as Base16 | 22 | import qualified Data.ByteString.Base16 as Base16 |
23 | import Control.Arrow | 23 | import Control.Arrow |
24 | import Control.Monad | 24 | import Control.Monad |
25 | import Control.Concurrent.Lifted.Instrument | ||
25 | import Control.Concurrent.STM | 26 | import Control.Concurrent.STM |
26 | import Data.Time.Clock.POSIX (POSIXTime, getPOSIXTime) | 27 | import Data.Time.Clock.POSIX (POSIXTime, getPOSIXTime) |
27 | import Network.Socket | 28 | import Network.Socket |
@@ -87,9 +88,17 @@ instance Show PacketKind where | |||
87 | showsPrec d CookieResponseType = mappend "CookieResponseType" | 88 | showsPrec d CookieResponseType = mappend "CookieResponseType" |
88 | showsPrec d (PacketKind x) = mappend "PacketKind " . showsPrec (d+1) x | 89 | showsPrec d (PacketKind x) = mappend "PacketKind " . showsPrec (d+1) x |
89 | 90 | ||
90 | 91 | msgType :: ( Serialize (f DHTRequest) | |
91 | classify :: Message -> MessageClass String PacketKind TransactionId | 92 | , Serialize (f Cookie), Serialize (f CookieRequest) |
92 | classify msg = mapMessage (\nonce24 (nonce8,_) -> go msg (TransactionId nonce8 nonce24)) msg | 93 | , Serialize (f SendNodes), Serialize (f GetNodes) |
94 | , Serialize (f Pong), Serialize (f Ping) | ||
95 | ) => DHTMessage f -> PacketKind | ||
96 | msgType msg = PacketKind $ fst $ dhtMessageType msg | ||
97 | |||
98 | classify :: Client -> Message -> MessageClass String PacketKind TransactionId NodeInfo Message | ||
99 | classify client (DHTLanDiscovery {}) = IsUnsolicited (lanDiscoveryH client) | ||
100 | classify client msg = fromMaybe (IsUnknown "unknown") | ||
101 | $ mapMessage (\nonce24 (nonce8,_) -> go msg (TransactionId nonce8 nonce24)) msg | ||
93 | where | 102 | where |
94 | go (DHTPing {}) = IsQuery PingType | 103 | go (DHTPing {}) = IsQuery PingType |
95 | go (DHTGetNodes {}) = IsQuery GetNodesType | 104 | go (DHTGetNodes {}) = IsQuery GetNodesType |
@@ -202,6 +211,13 @@ cookieRequestH crypto ni (CookieRequest remoteUserKey) = do | |||
202 | edta = encryptSymmetric sym n24 dta | 211 | edta = encryptSymmetric sym n24 dta |
203 | return $ Cookie n24 edta | 212 | return $ Cookie n24 edta |
204 | 213 | ||
214 | lanDiscoveryH :: Client -> NodeInfo -> NodeInfo -> IO (Maybe (Message -> Message)) | ||
215 | lanDiscoveryH client _ ni = do | ||
216 | forkIO $ do | ||
217 | myThreadId >>= flip labelThread "lan-discover-ping" | ||
218 | ping client ni | ||
219 | return () | ||
220 | return Nothing | ||
205 | 221 | ||
206 | type Message = DHTMessage ((,) Nonce8) | 222 | type Message = DHTMessage ((,) Nonce8) |
207 | 223 | ||
@@ -295,11 +311,9 @@ getNodes client nid addr = do | |||
295 | return $ fmap unwrapNodes $ join reply | 311 | return $ fmap unwrapNodes $ join reply |
296 | 312 | ||
297 | updateRouting :: Client -> Routing -> OnionRouter -> NodeInfo -> Message -> IO () | 313 | updateRouting :: Client -> Routing -> OnionRouter -> NodeInfo -> Message -> IO () |
298 | updateRouting client routing orouter naddr msg = do | 314 | updateRouting client routing orouter naddr msg |
299 | let typ = fst $ dhtMessageType $ fst $ DHTTransport.encrypt (error "updateRouting") msg naddr | 315 | | PacketKind 0x21 <- msgType msg = return () -- ignore lan discovery |
300 | tid = mapMessage (\n24 (n8,_) -> TransactionId n8 n24) msg | 316 | | otherwise = do |
301 | -- hPutStrLn stderr $ "updateRouting "++show (typ,tid) | ||
302 | -- TODO: check msg type | ||
303 | case prefer4or6 naddr Nothing of | 317 | case prefer4or6 naddr Nothing of |
304 | Want_IP4 -> updateTable client naddr orouter (routing4 routing) (committee4 routing) (sched4 routing) | 318 | Want_IP4 -> updateTable client naddr orouter (routing4 routing) (committee4 routing) (sched4 routing) |
305 | Want_IP6 -> updateTable client naddr orouter (routing6 routing) (committee6 routing) (sched6 routing) | 319 | Want_IP6 -> updateTable client naddr orouter (routing6 routing) (committee6 routing) (sched6 routing) |
@@ -365,10 +379,10 @@ mkCookie (TransactionId n8 n24) src dst cookie = DHTCookie n24 (n8,cookie) | |||
365 | 379 | ||
366 | 380 | ||
367 | handlers :: TransportCrypto -> Routing -> PacketKind -> Maybe Handler | 381 | handlers :: TransportCrypto -> Routing -> PacketKind -> Maybe Handler |
368 | handlers _ routing PingType = Just $ MethodHandler (isPing snd) mkPong pingH | 382 | handlers _ routing PingType = Just $ MethodHandler (isPing snd) mkPong $ pingH |
369 | handlers _ routing GetNodesType = Just $ MethodHandler (isGetNodes snd) mkSendNodes $ getNodesH routing | 383 | handlers _ routing GetNodesType = Just $ MethodHandler (isGetNodes snd) mkSendNodes $ getNodesH routing |
370 | handlers crypto _ CookieRequestType = Just $ MethodHandler (isCookieRequest snd) mkCookie $ cookieRequestH crypto | 384 | handlers crypto _ CookieRequestType = Just $ MethodHandler (isCookieRequest snd) mkCookie $ cookieRequestH crypto |
371 | handlers _ _ _ = error "TODO handlers" | 385 | handlers _ _ _ = error "TODO handlers" |
372 | 386 | ||
373 | nodeSearch :: Client -> Search NodeId (IP,PortNumber) () NodeInfo NodeInfo | 387 | nodeSearch :: Client -> Search NodeId (IP,PortNumber) () NodeInfo NodeInfo |
374 | nodeSearch client = Search | 388 | nodeSearch client = Search |
diff --git a/src/Network/Tox/DHT/Transport.hs b/src/Network/Tox/DHT/Transport.hs index dd2838f2..736e84d1 100644 --- a/src/Network/Tox/DHT/Transport.hs +++ b/src/Network/Tox/DHT/Transport.hs | |||
@@ -68,6 +68,7 @@ data DHTMessage (f :: * -> *) | |||
68 | | DHTCookieRequest (Asymm (f CookieRequest)) | 68 | | DHTCookieRequest (Asymm (f CookieRequest)) |
69 | | DHTCookie Nonce24 (f Cookie) | 69 | | DHTCookie Nonce24 (f Cookie) |
70 | | DHTDHTRequest PublicKey (Asymm (f DHTRequest)) | 70 | | DHTDHTRequest PublicKey (Asymm (f DHTRequest)) |
71 | | DHTLanDiscovery NodeId | ||
71 | 72 | ||
72 | deriving instance ( Show (f Cookie) | 73 | deriving instance ( Show (f Cookie) |
73 | , Show (Asymm (f Ping)) | 74 | , Show (Asymm (f Ping)) |
@@ -78,14 +79,15 @@ deriving instance ( Show (f Cookie) | |||
78 | , Show (Asymm (f DHTRequest)) | 79 | , Show (Asymm (f DHTRequest)) |
79 | ) => Show (DHTMessage f) | 80 | ) => Show (DHTMessage f) |
80 | 81 | ||
81 | mapMessage :: forall f b. (forall a. Nonce24 -> f a -> b) -> DHTMessage f -> b | 82 | mapMessage :: forall f b. (forall a. Nonce24 -> f a -> b) -> DHTMessage f -> Maybe b |
82 | mapMessage f (DHTPing a) = f (asymmNonce a) (asymmData a) | 83 | mapMessage f (DHTPing a) = Just $ f (asymmNonce a) (asymmData a) |
83 | mapMessage f (DHTPong a) = f (asymmNonce a) (asymmData a) | 84 | mapMessage f (DHTPong a) = Just $ f (asymmNonce a) (asymmData a) |
84 | mapMessage f (DHTGetNodes a) = f (asymmNonce a) (asymmData a) | 85 | mapMessage f (DHTGetNodes a) = Just $ f (asymmNonce a) (asymmData a) |
85 | mapMessage f (DHTSendNodes a) = f (asymmNonce a) (asymmData a) | 86 | mapMessage f (DHTSendNodes a) = Just $ f (asymmNonce a) (asymmData a) |
86 | mapMessage f (DHTCookieRequest a) = f (asymmNonce a) (asymmData a) | 87 | mapMessage f (DHTCookieRequest a) = Just $ f (asymmNonce a) (asymmData a) |
87 | mapMessage f (DHTDHTRequest _ a) = f (asymmNonce a) (asymmData a) | 88 | mapMessage f (DHTDHTRequest _ a) = Just $ f (asymmNonce a) (asymmData a) |
88 | mapMessage f (DHTCookie nonce fcookie) = f nonce fcookie | 89 | mapMessage f (DHTCookie nonce fcookie) = Just $ f nonce fcookie |
90 | mapMessage f (DHTLanDiscovery nid) = Nothing | ||
89 | 91 | ||
90 | 92 | ||
91 | instance Sized Ping where size = ConstSize 1 | 93 | instance Sized Ping where size = ConstSize 1 |
@@ -109,12 +111,20 @@ parseDHTAddr crypto (msg,saddr) | |||
109 | either (const Nothing) Just $ nodeInfo (key2id key) saddr | 111 | either (const Nothing) Just $ nodeInfo (key2id key) saddr |
110 | left $ fanGet bs getCookie (uncurry DHTCookie) (const $ ni) | 112 | left $ fanGet bs getCookie (uncurry DHTCookie) (const $ ni) |
111 | 0x20 -> left $ fanGet bs getDHTReqest (uncurry DHTDHTRequest) (asymNodeInfo saddr . snd) | 113 | 0x20 -> left $ fanGet bs getDHTReqest (uncurry DHTDHTRequest) (asymNodeInfo saddr . snd) |
114 | 0x21 -> left $ do | ||
115 | nid <- runGet get bs | ||
116 | ni <- nodeInfo nid saddr | ||
117 | return (DHTLanDiscovery nid, ni) | ||
112 | _ -> right | 118 | _ -> right |
113 | 119 | ||
114 | encodeDHTAddr :: (DHTMessage Encrypted8,NodeInfo) -> IO (ByteString, SockAddr) | 120 | encodeDHTAddr :: (DHTMessage Encrypted8,NodeInfo) -> IO (ByteString, SockAddr) |
115 | encodeDHTAddr (msg,ni) = return (runPut $ putMessage msg, nodeAddr ni) | 121 | encodeDHTAddr (msg,ni) = return (runPut $ putMessage msg, nodeAddr ni) |
116 | 122 | ||
117 | dhtMessageType :: DHTMessage Encrypted8 -> ( Word8, Put ) | 123 | dhtMessageType :: ( Serialize (f DHTRequest) |
124 | , Serialize (f Cookie), Serialize (f CookieRequest) | ||
125 | , Serialize (f SendNodes), Serialize (f GetNodes) | ||
126 | , Serialize (f Pong), Serialize (f Ping) | ||
127 | ) => DHTMessage f -> (Word8, Put) | ||
118 | dhtMessageType (DHTPing a) = (0x00, putAsymm a) | 128 | dhtMessageType (DHTPing a) = (0x00, putAsymm a) |
119 | dhtMessageType (DHTPong a) = (0x01, putAsymm a) | 129 | dhtMessageType (DHTPong a) = (0x01, putAsymm a) |
120 | dhtMessageType (DHTGetNodes a) = (0x02, putAsymm a) | 130 | dhtMessageType (DHTGetNodes a) = (0x02, putAsymm a) |
@@ -122,6 +132,7 @@ dhtMessageType (DHTSendNodes a) = (0x04, putAsymm a) | |||
122 | dhtMessageType (DHTCookieRequest a) = (0x18, putAsymm a) | 132 | dhtMessageType (DHTCookieRequest a) = (0x18, putAsymm a) |
123 | dhtMessageType (DHTCookie n x) = (0x19, put n >> put x) | 133 | dhtMessageType (DHTCookie n x) = (0x19, put n >> put x) |
124 | dhtMessageType (DHTDHTRequest k a) = (0x20, putPublicKey k >> putAsymm a) | 134 | dhtMessageType (DHTDHTRequest k a) = (0x20, putPublicKey k >> putAsymm a) |
135 | dhtMessageType (DHTLanDiscovery nid) = (0x21, put nid) | ||
125 | 136 | ||
126 | putMessage :: DHTMessage Encrypted8 -> Put | 137 | putMessage :: DHTMessage Encrypted8 -> Put |
127 | putMessage msg = case dhtMessageType msg of (typ,p) -> put typ >> p | 138 | putMessage msg = case dhtMessageType msg of (typ,p) -> put typ >> p |
@@ -452,6 +463,7 @@ sequenceMessage (DHTSendNodes asym) = fmap DHTSendNodes $ sequenceA | |||
452 | sequenceMessage (DHTCookieRequest asym) = fmap DHTCookieRequest $ sequenceA $ fmap uncomposed asym | 463 | sequenceMessage (DHTCookieRequest asym) = fmap DHTCookieRequest $ sequenceA $ fmap uncomposed asym |
453 | sequenceMessage (DHTCookie n dta) = fmap (DHTCookie n) $ uncomposed dta | 464 | sequenceMessage (DHTCookie n dta) = fmap (DHTCookie n) $ uncomposed dta |
454 | sequenceMessage (DHTDHTRequest pubkey asym) = fmap (DHTDHTRequest pubkey) $ sequenceA $ fmap uncomposed asym | 465 | sequenceMessage (DHTDHTRequest pubkey asym) = fmap (DHTDHTRequest pubkey) $ sequenceA $ fmap uncomposed asym |
466 | sequenceMessage (DHTLanDiscovery nid) = pure $ DHTLanDiscovery nid | ||
455 | 467 | ||
456 | transcode :: forall f g. (forall a. Serialize a => Nonce24 -> Either (f a) (Asymm (f a)) -> g a) -> DHTMessage f -> DHTMessage g | 468 | transcode :: forall f g. (forall a. Serialize a => Nonce24 -> Either (f a) (Asymm (f a)) -> g a) -> DHTMessage f -> DHTMessage g |
457 | transcode f (DHTPing asym) = DHTPing $ asym { asymmData = f (asymmNonce asym) (Right asym) } | 469 | transcode f (DHTPing asym) = DHTPing $ asym { asymmData = f (asymmNonce asym) (Right asym) } |
@@ -461,3 +473,4 @@ transcode f (DHTSendNodes asym) = DHTSendNodes $ asym { asymmDat | |||
461 | transcode f (DHTCookieRequest asym) = DHTCookieRequest $ asym { asymmData = f (asymmNonce asym) (Right asym) } | 473 | transcode f (DHTCookieRequest asym) = DHTCookieRequest $ asym { asymmData = f (asymmNonce asym) (Right asym) } |
462 | transcode f (DHTCookie n dta) = DHTCookie n $ f n $ Left dta | 474 | transcode f (DHTCookie n dta) = DHTCookie n $ f n $ Left dta |
463 | transcode f (DHTDHTRequest pubkey asym) = DHTDHTRequest pubkey $ asym { asymmData = f (asymmNonce asym) (Right asym) } | 475 | transcode f (DHTDHTRequest pubkey asym) = DHTDHTRequest pubkey $ asym { asymmData = f (asymmNonce asym) (Right asym) } |
476 | transcode f (DHTLanDiscovery nid) = DHTLanDiscovery nid | ||