summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Network/BitTorrent/MainlineDHT.hs4
-rw-r--r--src/Network/QueryResponse.hs21
-rw-r--r--src/Network/Tox.hs10
-rw-r--r--src/Network/Tox/DHT/Handlers.hs36
-rw-r--r--src/Network/Tox/DHT/Transport.hs31
-rw-r--r--src/Network/Tox/Onion/Handlers.hs2
6 files changed, 70 insertions, 34 deletions
diff --git a/src/Network/BitTorrent/MainlineDHT.hs b/src/Network/BitTorrent/MainlineDHT.hs
index a7359bda..c0413322 100644
--- a/src/Network/BitTorrent/MainlineDHT.hs
+++ b/src/Network/BitTorrent/MainlineDHT.hs
@@ -444,7 +444,7 @@ encodePacket :: Message BValue -> NodeInfo -> (ByteString, SockAddr)
444encodePacket msg ni = ( toStrict $ BE.encode msg 444encodePacket msg ni = ( toStrict $ BE.encode msg
445 , nodeAddr ni ) 445 , nodeAddr ni )
446 446
447classify :: Message BValue -> MessageClass String Method TransactionId 447classify :: Message BValue -> MessageClass String Method TransactionId NodeInfo (Message BValue)
448classify (Q { msgID = tid, qryMethod = meth }) = IsQuery meth tid 448classify (Q { msgID = tid, qryMethod = meth }) = IsQuery meth tid
449classify (R { msgID = tid }) = IsResponse tid 449classify (R { msgID = tid }) = IsResponse tid
450 450
@@ -566,7 +566,7 @@ newClient swarms addr = do
566 outgoingClient = client { clientNet = net { awaitMessage = ($ Nothing) } } 566 outgoingClient = client { clientNet = net { awaitMessage = ($ Nothing) } }
567 567
568 dispatch = DispatchMethods 568 dispatch = DispatchMethods
569 { classifyInbound = classify -- :: x -> MessageClass err meth tid 569 { classifyInbound = classify -- :: x -> MessageClass err meth tid addr x
570 , lookupHandler = handlers -- :: meth -> Maybe (MethodHandler err tid addr x) 570 , lookupHandler = handlers -- :: meth -> Maybe (MethodHandler err tid addr x)
571 , tableMethods = mapT -- :: TransactionMethods tbl tid x 571 , tableMethods = mapT -- :: TransactionMethods tbl tid x
572 } 572 }
diff --git a/src/Network/QueryResponse.hs b/src/Network/QueryResponse.hs
index fca6d5cc..492b7bb4 100644
--- a/src/Network/QueryResponse.hs
+++ b/src/Network/QueryResponse.hs
@@ -226,11 +226,15 @@ data Client err meth tid addr x = forall tbl. Client
226 } 226 }
227 227
228-- | An incoming message can be classified into three cases. 228-- | An incoming message can be classified into three cases.
229data MessageClass err meth tid 229data MessageClass err meth tid addr x
230 = IsQuery meth tid -- ^ An unsolicited query is handled based on it's /meth/ value. Any response 230 = IsQuery meth tid -- ^ An unsolicited query is handled based on it's /meth/ value. Any response
231 -- should include the provided /tid/ value. 231 -- should include the provided /tid/ value.
232 | IsResponse tid -- ^ A response to a outgoing query we associated with a /tid/ value. 232 | IsResponse tid -- ^ A response to a outgoing query we associated with a /tid/ value.
233 | IsUnknown err -- ^ None of the above. 233 | IsUnsolicited (addr -> addr -> IO (Maybe (x -> x))) -- ^ Transactionless informative packet. The io action will be invoked
234 -- with the source and destination address of a message. If it handles the
235 -- message, it should return Nothing. Otherwise, it should return a transform
236 -- (usually /id/) to apply before the next handler examines it.
237 | IsUnknown err -- ^ None of the above.
234 238
235-- | Handler for an inbound query of type /x/ from an address of type _addr_. 239-- | Handler for an inbound query of type /x/ from an address of type _addr_.
236data MethodHandler err tid addr x = forall a b. MethodHandler 240data MethodHandler err tid addr x = forall a b. MethodHandler
@@ -243,6 +247,7 @@ data MethodHandler err tid addr x = forall a b. MethodHandler
243 -- address of the query is provided to the handler. 247 -- address of the query is provided to the handler.
244 , methodAction :: addr -> a -> IO b 248 , methodAction :: addr -> a -> IO b
245 } 249 }
250 -- | See also 'IsUnsolicited' which likely makes this constructor unnecessary.
246 | forall a. NoReply 251 | forall a. NoReply
247 { -- | Parse the query into a more specific type for this method. 252 { -- | Parse the query into a more specific type for this method.
248 methodParse :: x -> Either err a 253 methodParse :: x -> Either err a
@@ -377,7 +382,7 @@ transactionMethods (TableMethods insert delete lookup) generate = TransactionMet
377-- | A set of methods necessary for dispatching incoming packets. 382-- | A set of methods necessary for dispatching incoming packets.
378data DispatchMethods tbl err meth tid addr x = DispatchMethods 383data DispatchMethods tbl err meth tid addr x = DispatchMethods
379 { -- | Classify an inbound packet as a query or response. 384 { -- | Classify an inbound packet as a query or response.
380 classifyInbound :: x -> MessageClass err meth tid 385 classifyInbound :: x -> MessageClass err meth tid addr x
381 -- | Lookup the handler for a inbound query. 386 -- | Lookup the handler for a inbound query.
382 , lookupHandler :: meth -> Maybe (MethodHandler err tid addr x) 387 , lookupHandler :: meth -> Maybe (MethodHandler err tid addr x)
383 -- | Methods for handling incoming responses. 388 -- | Methods for handling incoming responses.
@@ -459,6 +464,10 @@ handleMessage (Client net d err pending whoami responseID) addr plain = do
459 (>>= \m -> do mapM_ (sendMessage net addr) m 464 (>>= \m -> do mapM_ (sendMessage net addr) m
460 return $! Nothing) 465 return $! Nothing)
461 (dispatchQuery m tid' self plain addr) 466 (dispatchQuery m tid' self plain addr)
467 IsUnsolicited action -> do
468 self <- whoami (Just addr)
469 action self addr
470 return Nothing
462 IsResponse tid -> do 471 IsResponse tid -> do
463 action <- atomically $ do 472 action <- atomically $ do
464 ts0 <- readTVar pending 473 ts0 <- readTVar pending
diff --git a/src/Network/Tox.hs b/src/Network/Tox.hs
index d434360f..d5db6979 100644
--- a/src/Network/Tox.hs
+++ b/src/Network/Tox.hs
@@ -174,7 +174,7 @@ myAddr routing maddr = atomically $ do
174 174
175newClient :: (DRG g, Show addr, Show meth) => 175newClient :: (DRG g, Show addr, Show meth) =>
176 g -> Transport String addr x 176 g -> Transport String addr x
177 -> (x -> MessageClass String meth DHT.TransactionId) 177 -> (Client String meth DHT.TransactionId addr x -> x -> MessageClass String meth DHT.TransactionId addr x)
178 -> (Maybe addr -> IO addr) 178 -> (Maybe addr -> IO addr)
179 -> (meth -> Maybe (MethodHandler String DHT.TransactionId addr x)) 179 -> (meth -> Maybe (MethodHandler String DHT.TransactionId addr x))
180 -> (forall d. TransactionMethods d DHT.TransactionId addr x -> TransactionMethods d DHT.TransactionId addr x) 180 -> (forall d. TransactionMethods d DHT.TransactionId addr x -> TransactionMethods d DHT.TransactionId addr x)
@@ -195,8 +195,8 @@ newClient drg net classify selfAddr handlers modifytbl modifynet = do
195 let word64mapT = transactionMethods (contramap w64Key w64MapMethods) gen 195 let word64mapT = transactionMethods (contramap w64Key w64MapMethods) gen
196 map_var <- atomically $ newTVar (drg, Data.Word64Map.empty) 196 map_var <- atomically $ newTVar (drg, Data.Word64Map.empty)
197 return $ Left (word64mapT,map_var) 197 return $ Left (word64mapT,map_var)
198 let dispatch tbl var handlers = DispatchMethods 198 let dispatch tbl var handlers client = DispatchMethods
199 { classifyInbound = classify 199 { classifyInbound = classify client
200 , lookupHandler = handlers -- var 200 , lookupHandler = handlers -- var
201 , tableMethods = modifytbl tbl 201 , tableMethods = modifytbl tbl
202 } 202 }
@@ -204,7 +204,7 @@ newClient drg net classify selfAddr handlers modifytbl modifynet = do
204 mkclient (tbl,var) handlers = 204 mkclient (tbl,var) handlers =
205 let client = Client 205 let client = Client
206 { clientNet = addHandler eprinter (handleMessage client) $ modifynet client net 206 { clientNet = addHandler eprinter (handleMessage client) $ modifynet client net
207 , clientDispatcher = dispatch tbl var handlers 207 , clientDispatcher = dispatch tbl var handlers client
208 , clientErrorReporter = eprinter { reportTimeout = reportTimeout ignoreErrors } 208 , clientErrorReporter = eprinter { reportTimeout = reportTimeout ignoreErrors }
209 , clientPending = var 209 , clientPending = var
210 , clientAddress = selfAddr 210 , clientAddress = selfAddr
@@ -301,7 +301,7 @@ newTox keydb addr = do
301 atomically $ newTVar nil { maxInterval = 20 } -- 20 second timeout on announce ping-ids. 301 atomically $ newTVar nil { maxInterval = 20 } -- 20 second timeout on announce ping-ids.
302 oniondrg <- drgNew 302 oniondrg <- drgNew
303 let onionnet = layerTransportM (Onion.decrypt crypto) (Onion.encrypt crypto) onioncrypt 303 let onionnet = layerTransportM (Onion.decrypt crypto) (Onion.encrypt crypto) onioncrypt
304 onionclient <- newClient oniondrg onionnet Onion.classify 304 onionclient <- newClient oniondrg onionnet (const Onion.classify)
305 (getOnionAlias crypto $ R.thisNode <$> readTVar (DHT.routing4 routing)) 305 (getOnionAlias crypto $ R.thisNode <$> readTVar (DHT.routing4 routing))
306 (Onion.handlers onionnet routing toks keydb) 306 (Onion.handlers onionnet routing toks keydb)
307 (hookQueries orouter DHT.transactionKey) 307 (hookQueries orouter DHT.transactionKey)
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
22import qualified Data.ByteString.Base16 as Base16 22import qualified Data.ByteString.Base16 as Base16
23import Control.Arrow 23import Control.Arrow
24import Control.Monad 24import Control.Monad
25import Control.Concurrent.Lifted.Instrument
25import Control.Concurrent.STM 26import Control.Concurrent.STM
26import Data.Time.Clock.POSIX (POSIXTime, getPOSIXTime) 27import Data.Time.Clock.POSIX (POSIXTime, getPOSIXTime)
27import Network.Socket 28import 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 91msgType :: ( Serialize (f DHTRequest)
91classify :: Message -> MessageClass String PacketKind TransactionId 92 , Serialize (f Cookie), Serialize (f CookieRequest)
92classify 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
96msgType msg = PacketKind $ fst $ dhtMessageType msg
97
98classify :: Client -> Message -> MessageClass String PacketKind TransactionId NodeInfo Message
99classify client (DHTLanDiscovery {}) = IsUnsolicited (lanDiscoveryH client)
100classify 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
214lanDiscoveryH :: Client -> NodeInfo -> NodeInfo -> IO (Maybe (Message -> Message))
215lanDiscoveryH client _ ni = do
216 forkIO $ do
217 myThreadId >>= flip labelThread "lan-discover-ping"
218 ping client ni
219 return ()
220 return Nothing
205 221
206type Message = DHTMessage ((,) Nonce8) 222type 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
297updateRouting :: Client -> Routing -> OnionRouter -> NodeInfo -> Message -> IO () 313updateRouting :: Client -> Routing -> OnionRouter -> NodeInfo -> Message -> IO ()
298updateRouting client routing orouter naddr msg = do 314updateRouting 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
367handlers :: TransportCrypto -> Routing -> PacketKind -> Maybe Handler 381handlers :: TransportCrypto -> Routing -> PacketKind -> Maybe Handler
368handlers _ routing PingType = Just $ MethodHandler (isPing snd) mkPong pingH 382handlers _ routing PingType = Just $ MethodHandler (isPing snd) mkPong $ pingH
369handlers _ routing GetNodesType = Just $ MethodHandler (isGetNodes snd) mkSendNodes $ getNodesH routing 383handlers _ routing GetNodesType = Just $ MethodHandler (isGetNodes snd) mkSendNodes $ getNodesH routing
370handlers crypto _ CookieRequestType = Just $ MethodHandler (isCookieRequest snd) mkCookie $ cookieRequestH crypto 384handlers crypto _ CookieRequestType = Just $ MethodHandler (isCookieRequest snd) mkCookie $ cookieRequestH crypto
371handlers _ _ _ = error "TODO handlers" 385handlers _ _ _ = error "TODO handlers"
372 386
373nodeSearch :: Client -> Search NodeId (IP,PortNumber) () NodeInfo NodeInfo 387nodeSearch :: Client -> Search NodeId (IP,PortNumber) () NodeInfo NodeInfo
374nodeSearch client = Search 388nodeSearch 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
72deriving instance ( Show (f Cookie) 73deriving 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
81mapMessage :: forall f b. (forall a. Nonce24 -> f a -> b) -> DHTMessage f -> b 82mapMessage :: forall f b. (forall a. Nonce24 -> f a -> b) -> DHTMessage f -> Maybe b
82mapMessage f (DHTPing a) = f (asymmNonce a) (asymmData a) 83mapMessage f (DHTPing a) = Just $ f (asymmNonce a) (asymmData a)
83mapMessage f (DHTPong a) = f (asymmNonce a) (asymmData a) 84mapMessage f (DHTPong a) = Just $ f (asymmNonce a) (asymmData a)
84mapMessage f (DHTGetNodes a) = f (asymmNonce a) (asymmData a) 85mapMessage f (DHTGetNodes a) = Just $ f (asymmNonce a) (asymmData a)
85mapMessage f (DHTSendNodes a) = f (asymmNonce a) (asymmData a) 86mapMessage f (DHTSendNodes a) = Just $ f (asymmNonce a) (asymmData a)
86mapMessage f (DHTCookieRequest a) = f (asymmNonce a) (asymmData a) 87mapMessage f (DHTCookieRequest a) = Just $ f (asymmNonce a) (asymmData a)
87mapMessage f (DHTDHTRequest _ a) = f (asymmNonce a) (asymmData a) 88mapMessage f (DHTDHTRequest _ a) = Just $ f (asymmNonce a) (asymmData a)
88mapMessage f (DHTCookie nonce fcookie) = f nonce fcookie 89mapMessage f (DHTCookie nonce fcookie) = Just $ f nonce fcookie
90mapMessage f (DHTLanDiscovery nid) = Nothing
89 91
90 92
91instance Sized Ping where size = ConstSize 1 93instance 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
114encodeDHTAddr :: (DHTMessage Encrypted8,NodeInfo) -> IO (ByteString, SockAddr) 120encodeDHTAddr :: (DHTMessage Encrypted8,NodeInfo) -> IO (ByteString, SockAddr)
115encodeDHTAddr (msg,ni) = return (runPut $ putMessage msg, nodeAddr ni) 121encodeDHTAddr (msg,ni) = return (runPut $ putMessage msg, nodeAddr ni)
116 122
117dhtMessageType :: DHTMessage Encrypted8 -> ( Word8, Put ) 123dhtMessageType :: ( 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)
118dhtMessageType (DHTPing a) = (0x00, putAsymm a) 128dhtMessageType (DHTPing a) = (0x00, putAsymm a)
119dhtMessageType (DHTPong a) = (0x01, putAsymm a) 129dhtMessageType (DHTPong a) = (0x01, putAsymm a)
120dhtMessageType (DHTGetNodes a) = (0x02, putAsymm a) 130dhtMessageType (DHTGetNodes a) = (0x02, putAsymm a)
@@ -122,6 +132,7 @@ dhtMessageType (DHTSendNodes a) = (0x04, putAsymm a)
122dhtMessageType (DHTCookieRequest a) = (0x18, putAsymm a) 132dhtMessageType (DHTCookieRequest a) = (0x18, putAsymm a)
123dhtMessageType (DHTCookie n x) = (0x19, put n >> put x) 133dhtMessageType (DHTCookie n x) = (0x19, put n >> put x)
124dhtMessageType (DHTDHTRequest k a) = (0x20, putPublicKey k >> putAsymm a) 134dhtMessageType (DHTDHTRequest k a) = (0x20, putPublicKey k >> putAsymm a)
135dhtMessageType (DHTLanDiscovery nid) = (0x21, put nid)
125 136
126putMessage :: DHTMessage Encrypted8 -> Put 137putMessage :: DHTMessage Encrypted8 -> Put
127putMessage msg = case dhtMessageType msg of (typ,p) -> put typ >> p 138putMessage msg = case dhtMessageType msg of (typ,p) -> put typ >> p
@@ -452,6 +463,7 @@ sequenceMessage (DHTSendNodes asym) = fmap DHTSendNodes $ sequenceA
452sequenceMessage (DHTCookieRequest asym) = fmap DHTCookieRequest $ sequenceA $ fmap uncomposed asym 463sequenceMessage (DHTCookieRequest asym) = fmap DHTCookieRequest $ sequenceA $ fmap uncomposed asym
453sequenceMessage (DHTCookie n dta) = fmap (DHTCookie n) $ uncomposed dta 464sequenceMessage (DHTCookie n dta) = fmap (DHTCookie n) $ uncomposed dta
454sequenceMessage (DHTDHTRequest pubkey asym) = fmap (DHTDHTRequest pubkey) $ sequenceA $ fmap uncomposed asym 465sequenceMessage (DHTDHTRequest pubkey asym) = fmap (DHTDHTRequest pubkey) $ sequenceA $ fmap uncomposed asym
466sequenceMessage (DHTLanDiscovery nid) = pure $ DHTLanDiscovery nid
455 467
456transcode :: forall f g. (forall a. Serialize a => Nonce24 -> Either (f a) (Asymm (f a)) -> g a) -> DHTMessage f -> DHTMessage g 468transcode :: forall f g. (forall a. Serialize a => Nonce24 -> Either (f a) (Asymm (f a)) -> g a) -> DHTMessage f -> DHTMessage g
457transcode f (DHTPing asym) = DHTPing $ asym { asymmData = f (asymmNonce asym) (Right asym) } 469transcode f (DHTPing asym) = DHTPing $ asym { asymmData = f (asymmNonce asym) (Right asym) }
@@ -461,3 +473,4 @@ transcode f (DHTSendNodes asym) = DHTSendNodes $ asym { asymmDat
461transcode f (DHTCookieRequest asym) = DHTCookieRequest $ asym { asymmData = f (asymmNonce asym) (Right asym) } 473transcode f (DHTCookieRequest asym) = DHTCookieRequest $ asym { asymmData = f (asymmNonce asym) (Right asym) }
462transcode f (DHTCookie n dta) = DHTCookie n $ f n $ Left dta 474transcode f (DHTCookie n dta) = DHTCookie n $ f n $ Left dta
463transcode f (DHTDHTRequest pubkey asym) = DHTDHTRequest pubkey $ asym { asymmData = f (asymmNonce asym) (Right asym) } 475transcode f (DHTDHTRequest pubkey asym) = DHTDHTRequest pubkey $ asym { asymmData = f (asymmNonce asym) (Right asym) }
476transcode f (DHTLanDiscovery nid) = DHTLanDiscovery nid
diff --git a/src/Network/Tox/Onion/Handlers.hs b/src/Network/Tox/Onion/Handlers.hs
index 76908df8..b06fc2af 100644
--- a/src/Network/Tox/Onion/Handlers.hs
+++ b/src/Network/Tox/Onion/Handlers.hs
@@ -42,7 +42,7 @@ import Data.Functor.Identity
42type Client r = QR.Client String PacketKind TransactionId (OnionDestination r) Message 42type Client r = QR.Client String PacketKind TransactionId (OnionDestination r) Message
43type Message = OnionMessage Identity 43type Message = OnionMessage Identity
44 44
45classify :: Message -> MessageClass String PacketKind TransactionId 45classify :: Message -> MessageClass String PacketKind TransactionId (OnionDestination r) Message
46classify msg = go msg 46classify msg = go msg
47 where 47 where
48 go (OnionAnnounce announce) = IsQuery AnnounceType 48 go (OnionAnnounce announce) = IsQuery AnnounceType