diff options
-rw-r--r-- | src/Network/DatagramServer.hs | 36 | ||||
-rw-r--r-- | src/Network/KRPC/Method.hs | 5 |
2 files changed, 30 insertions, 11 deletions
diff --git a/src/Network/DatagramServer.hs b/src/Network/DatagramServer.hs index d478d667..e004eef3 100644 --- a/src/Network/DatagramServer.hs +++ b/src/Network/DatagramServer.hs | |||
@@ -127,6 +127,7 @@ import Network.Socket hiding (listen) | |||
127 | import Network.Socket.ByteString as BS | 127 | import Network.Socket.ByteString as BS |
128 | import System.IO.Error | 128 | import System.IO.Error |
129 | import System.Timeout | 129 | import System.Timeout |
130 | import Network.KRPC.Method | ||
130 | 131 | ||
131 | 132 | ||
132 | {----------------------------------------------------------------------- | 133 | {----------------------------------------------------------------------- |
@@ -320,7 +321,15 @@ sendQuery sock addr q = handle sockError $ sendMessage sock addr q | |||
320 | -- This function should throw 'QueryFailure' exception if quered node | 321 | -- This function should throw 'QueryFailure' exception if quered node |
321 | -- respond with @error@ message or the query timeout expires. | 322 | -- respond with @error@ message or the query timeout expires. |
322 | -- | 323 | -- |
323 | query :: forall h a b raw msg. (SerializableTo raw b, Show (QueryMethod msg), Ord (TransactionID msg), Serialize (TransactionID msg), SerializableTo raw a, WireFormat raw msg) => Manager raw msg -> QueryMethod msg -> SockAddr -> a -> IO b | 324 | query :: forall h a b raw msg. |
325 | ( SerializableTo raw b | ||
326 | , Show (QueryMethod msg) | ||
327 | , Ord (TransactionID msg) | ||
328 | , Serialize (TransactionID msg) | ||
329 | , SerializableTo raw a | ||
330 | , WireFormat raw msg | ||
331 | , KRPC msg a b | ||
332 | ) => Manager raw msg -> QueryMethod msg -> SockAddr -> a -> IO b | ||
324 | query mgr meth addr params = queryK mgr meth addr params (\_ x _ -> x) | 333 | query mgr meth addr params = queryK mgr meth addr params (\_ x _ -> x) |
325 | 334 | ||
326 | -- | Like 'query' but possibly returns your externally routable IP address. | 335 | -- | Like 'query' but possibly returns your externally routable IP address. |
@@ -330,6 +339,7 @@ query' :: forall h a b raw msg. | |||
330 | , Ord (TransactionID msg) | 339 | , Ord (TransactionID msg) |
331 | , Serialize (TransactionID msg) | 340 | , Serialize (TransactionID msg) |
332 | , SerializableTo raw a , WireFormat raw msg | 341 | , SerializableTo raw a , WireFormat raw msg |
342 | , KRPC msg a b | ||
333 | ) => Manager raw msg -> QueryMethod msg -> SockAddr -> a -> IO (b , Maybe ReflectedIP) | 343 | ) => Manager raw msg -> QueryMethod msg -> SockAddr -> a -> IO (b , Maybe ReflectedIP) |
334 | query' mgr meth addr params = queryK mgr meth addr params (const (,)) | 344 | query' mgr meth addr params = queryK mgr meth addr params (const (,)) |
335 | 345 | ||
@@ -343,6 +353,7 @@ queryRaw :: forall h a b raw msg. | |||
343 | , Serialize (TransactionID msg) | 353 | , Serialize (TransactionID msg) |
344 | , SerializableTo raw a | 354 | , SerializableTo raw a |
345 | , WireFormat raw msg | 355 | , WireFormat raw msg |
356 | , KRPC msg a b | ||
346 | ) => Manager raw msg -> QueryMethod msg -> SockAddr -> a -> IO (b , raw) | 357 | ) => Manager raw msg -> QueryMethod msg -> SockAddr -> a -> IO (b , raw) |
347 | queryRaw mgr meth addr params = queryK mgr meth addr params (\raw x _ -> (x,raw)) | 358 | queryRaw mgr meth addr params = queryK mgr meth addr params (\raw x _ -> (x,raw)) |
348 | 359 | ||
@@ -353,6 +364,7 @@ queryK :: forall h a b x raw msg. | |||
353 | , Show (QueryMethod msg) | 364 | , Show (QueryMethod msg) |
354 | , Ord (TransactionID msg) | 365 | , Ord (TransactionID msg) |
355 | , Serialize (TransactionID msg) | 366 | , Serialize (TransactionID msg) |
367 | , KRPC msg a b | ||
356 | ) => | 368 | ) => |
357 | Manager raw msg -> QueryMethod msg -> SockAddr -> a -> (raw -> b -> Maybe ReflectedIP -> x) -> IO x | 369 | Manager raw msg -> QueryMethod msg -> SockAddr -> a -> (raw -> b -> Maybe ReflectedIP -> x) -> IO x |
358 | queryK mgr@Manager{..} meth addr params kont = do | 370 | queryK mgr@Manager{..} meth addr params kont = do |
@@ -373,16 +385,18 @@ queryK mgr@Manager{..} meth addr params kont = do | |||
373 | `onException` unregisterQuery (tid, addr) pendingCalls | 385 | `onException` unregisterQuery (tid, addr) pendingCalls |
374 | 386 | ||
375 | timeout (optQueryTimeout options * 10 ^ (6 :: Int)) $ do | 387 | timeout (optQueryTimeout options * 10 ^ (6 :: Int)) $ do |
376 | -- TODO: Loop with polymorphic sanity-check (to handle Tox's nonces). | 388 | fix $ \loop -> do |
377 | (raw,res) <- readMVar ares -- MVar (KQueryArgs, KResult) | 389 | (raw,res) <- readMVar ares -- MVar (KQueryArgs, KResult) |
378 | case res of | 390 | case res of |
379 | Left (KError c m _) -> throwIO $ QueryFailed c (T.decodeUtf8 m) | 391 | Left (KError c m _) -> throwIO $ QueryFailed c (T.decodeUtf8 m) |
380 | Right m -> case decodePayload m of | 392 | Right m -> case decodePayload m of |
381 | Right r -> case envelopeClass (r :: msg b) of | 393 | Right r -> case envelopeClass (r :: msg b) of |
382 | Response reflectedAddr -> pure $ kont raw (envelopePayload r) reflectedAddr | 394 | Response reflectedAddr |
383 | Error (KError c m _) -> throwIO $ QueryFailed c (T.decodeUtf8 m) -- XXX neccessary? | 395 | | validateExchange q r -> return $ kont raw (envelopePayload r) reflectedAddr |
384 | Query _ -> throwIO $ QueryFailed ProtocolError "BUG!! UNREACHABLE" | 396 | | otherwise -> loop |
385 | Left e -> throwIO $ QueryFailed ProtocolError (T.pack e) | 397 | Error (KError c m _) -> throwIO $ QueryFailed c (T.decodeUtf8 m) -- XXX neccessary? |
398 | Query _ -> throwIO $ QueryFailed ProtocolError "BUG!! UNREACHABLE" | ||
399 | Left e -> throwIO $ QueryFailed ProtocolError (T.pack e) | ||
386 | 400 | ||
387 | case mres of | 401 | case mres of |
388 | Just res -> do | 402 | Just res -> do |
diff --git a/src/Network/KRPC/Method.hs b/src/Network/KRPC/Method.hs index 84c7fe4c..2033f808 100644 --- a/src/Network/KRPC/Method.hs +++ b/src/Network/KRPC/Method.hs | |||
@@ -100,3 +100,8 @@ class ( Typeable req, Typeable resp) | |||
100 | method = Method $ fromString $ L.map toLower $ show $ typeOf hole | 100 | method = Method $ fromString $ L.map toLower $ show $ typeOf hole |
101 | where | 101 | where |
102 | hole = error "krpc.method: impossible" :: req | 102 | hole = error "krpc.method: impossible" :: req |
103 | |||
104 | |||
105 | validateExchange :: dht req -> dht resp -> Bool | ||
106 | validateExchange _ _ = True | ||
107 | |||