summaryrefslogtreecommitdiff
path: root/src/Network/Tox/Onion/Transport.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2017-10-12 05:41:09 -0400
committerjoe <joe@jerkface.net>2017-10-12 05:41:09 -0400
commit37a7fa4978f89072d9231bcc9bd0848bb52c676c (patch)
tree48a2a934e5da1c6754915d5ad27417f604cbfd04 /src/Network/Tox/Onion/Transport.hs
parent3024b35b05d7f520666af20ced8d1f3080837bb2 (diff)
WIP Onion routing.
Diffstat (limited to 'src/Network/Tox/Onion/Transport.hs')
-rw-r--r--src/Network/Tox/Onion/Transport.hs61
1 files changed, 47 insertions, 14 deletions
diff --git a/src/Network/Tox/Onion/Transport.hs b/src/Network/Tox/Onion/Transport.hs
index a3c1950f..b5ac748a 100644
--- a/src/Network/Tox/Onion/Transport.hs
+++ b/src/Network/Tox/Onion/Transport.hs
@@ -35,6 +35,8 @@ module Network.Tox.Onion.Transport
35 , peelSymmetric 35 , peelSymmetric
36 , OnionRoute(..) 36 , OnionRoute(..)
37 , N3 37 , N3
38 , onionKey
39 , onionNodeInfo
38 ) where 40 ) where
39 41
40import Network.Address (fromSockAddr,toSockAddr,setPort,either4or6,sockAddrPort) 42import Network.Address (fromSockAddr,toSockAddr,setPort,either4or6,sockAddrPort)
@@ -42,10 +44,11 @@ import Network.QueryResponse
42import Crypto.Tox hiding (encrypt,decrypt) 44import Crypto.Tox hiding (encrypt,decrypt)
43import Network.Tox.NodeId 45import Network.Tox.NodeId
44import qualified Crypto.Tox as ToxCrypto 46import qualified Crypto.Tox as ToxCrypto
45import Network.Tox.DHT.Transport (NodeInfo(..),NodeId(..),SendNodes,nodeInfo,DHTPublicKey,asymNodeInfo) 47import Network.Tox.DHT.Transport (NodeInfo(..),NodeId(..),SendNodes(..),nodeInfo,DHTPublicKey,asymNodeInfo)
46 48
47import Debug.Trace 49import Debug.Trace
48import Control.Arrow 50import Control.Arrow
51import Control.Applicative
49import Control.Concurrent.STM 52import Control.Concurrent.STM
50import Control.Monad 53import Control.Monad
51import qualified Data.ByteString as B 54import qualified Data.ByteString as B
@@ -88,14 +91,23 @@ deriving instance ( Show (f (AnnounceRequest, Nonce8))
88 , Show (f DataToRoute) 91 , Show (f DataToRoute)
89 ) => Show (OnionMessage f) 92 ) => Show (OnionMessage f)
90 93
94msgNonce :: OnionMessage f -> Nonce24
95msgNonce (OnionAnnounce a) = assymNonce a
96msgNonce (OnionAnnounceResponse _ n24 _) = n24
97msgNonce (OnionToRoute _ a) = assymNonce a
98msgNonce (OnionToRouteResponse a) = assymNonce a
99
91data OnionDestination r 100data OnionDestination r
92 = OnionToOwner NodeInfo (ReturnPath N3) -- ^ Somebody else's path to us. 101 = OnionToOwner NodeInfo (ReturnPath N3) -- ^ Somebody else's path to us.
93 | OnionDestination NodeInfo (Maybe r) -- ^ Our own onion-path. 102 | OnionDestination NodeInfo (Maybe r) -- ^ Our own onion-path.
94 deriving Show 103 deriving Show
95 104
105onionNodeInfo :: OnionDestination r -> NodeInfo
106onionNodeInfo (OnionToOwner ni _) = ni
107onionNodeInfo (OnionDestination ni _) = ni
108
96onionKey :: OnionDestination r -> Maybe PublicKey 109onionKey :: OnionDestination r -> Maybe PublicKey
97onionKey (OnionToOwner ni _) = Just $ id2key (nodeId ni) 110onionKey od = Just $ id2key . nodeId $ onionNodeInfo od
98onionKey (OnionDestination ni _) = Just $ id2key (nodeId ni)
99 111
100instance Sized (OnionMessage Encrypted) where 112instance Sized (OnionMessage Encrypted) where
101 size = VarSize $ \case 113 size = VarSize $ \case
@@ -176,11 +188,19 @@ encodeOnionAddr :: (NodeInfo -> r -> IO (Maybe OnionRoute))
176encodeOnionAddr _ (msg,OnionToOwner ni p) = 188encodeOnionAddr _ (msg,OnionToOwner ni p) =
177 return $ Just ( runPut $ putResponse (OnionResponse p msg) 189 return $ Just ( runPut $ putResponse (OnionResponse p msg)
178 , nodeAddr ni ) 190 , nodeAddr ni )
179encodeOnionAddr _ (msg,OnionDestination _ Nothing ) = return Nothing 191encodeOnionAddr _ (msg,OnionDestination _ Nothing ) = do
192 hPutStrLn stderr $ "ONION encode missing routeid"
193 return Nothing
180encodeOnionAddr getRoute (msg,OnionDestination ni (Just rid)) = do 194encodeOnionAddr getRoute (msg,OnionDestination ni (Just rid)) = do
181 let go route = do 195 let go route0 = do
182 return (runPut $ putRequest $ wrapForRoute msg ni route, nodeAddr ni) 196 let route = route0 { routeNonce = msgNonce msg } -- TODO: This necessary?
183 getRoute ni rid >>= mapM go 197 return ( runPut $ putRequest $ wrapForRoute msg ni route
198 , nodeAddr $ routeNodeA route)
199 mapM' f x = do
200 hPutStrLn stderr $ "ONION encode sending to " ++ show ni
201 hPutStrLn stderr $ "ONION encode getRoute -> " ++ show (mapM (\y -> map ($ y) [routeNodeA,routeNodeB,routeNodeC]) x)
202 mapM f x
203 getRoute ni rid >>= mapM' go
184 204
185 205
186forwardOnions :: TransportCrypto -> UDPTransport -> UDPTransport 206forwardOnions :: TransportCrypto -> UDPTransport -> UDPTransport
@@ -239,16 +259,19 @@ deriving instance ( Show (Forwarding (ThreeMinus n) (OnionMessage Encrypted))
239instance ( Serialize (Forwarding (ThreeMinus n) (OnionMessage Encrypted)) 259instance ( Serialize (Forwarding (ThreeMinus n) (OnionMessage Encrypted))
240 , Sized (ReturnPath n) 260 , Sized (ReturnPath n)
241 , Serialize (ReturnPath n) 261 , Serialize (ReturnPath n)
262 , Typeable n
242 ) => Serialize (OnionRequest n) where 263 ) => Serialize (OnionRequest n) where
243 get = do 264 get = do
244 -- TODO share code with 'getOnionRequest' 265 -- TODO share code with 'getOnionRequest'
245 n24 <- get 266 n24 <- case eqT :: Maybe (n :~: N3) of
267 Just Refl -> return $ Nonce24 zeros24
268 Nothing -> get
246 cnt <- remaining 269 cnt <- remaining
247 let fwdsize = case size :: Size (ReturnPath n) of ConstSize n -> cnt - n 270 let fwdsize = case size :: Size (ReturnPath n) of ConstSize n -> cnt - n
248 fwd <- isolate fwdsize get 271 fwd <- isolate fwdsize get
249 rpath <- get 272 rpath <- get
250 return $ OnionRequest n24 fwd rpath 273 return $ OnionRequest n24 fwd rpath
251 put (OnionRequest n f p) = put n >> put f >> put p 274 put (OnionRequest n f p) = maybe (put n) (\Refl -> return ()) (eqT :: Maybe (n :~: N3)) >> put f >> put p
252 275
253-- getRequest :: _ 276-- getRequest :: _
254-- getRequest = OnionRequest <$> get <*> get <*> get 277-- getRequest = OnionRequest <$> get <*> get <*> get
@@ -402,6 +425,7 @@ handleOnionRequest :: forall a proxy n.
402 ( LessThanThree n 425 ( LessThanThree n
403 , KnownPeanoNat n 426 , KnownPeanoNat n
404 , Sized (ReturnPath n) 427 , Sized (ReturnPath n)
428 , Typeable n
405 ) => proxy n -> TransportCrypto -> SockAddr -> UDPTransport -> IO a -> OnionRequest n -> IO a 429 ) => proxy n -> TransportCrypto -> SockAddr -> UDPTransport -> IO a -> OnionRequest n -> IO a
406handleOnionRequest proxy crypto saddr udp kont (OnionRequest nonce msg rpath) = do 430handleOnionRequest proxy crypto saddr udp kont (OnionRequest nonce msg rpath) = do
407 let n = peanoVal rpath 431 let n = peanoVal rpath
@@ -414,7 +438,7 @@ handleOnionRequest proxy crypto saddr udp kont (OnionRequest nonce msg rpath) =
414 hPutStrLn stderr $ unwords [ "peelOnion:", show n, either show show (either4or6 saddr), e] 438 hPutStrLn stderr $ unwords [ "peelOnion:", show n, either show show (either4or6 saddr), e]
415 kont 439 kont
416 Right (Addressed dst msg') -> do 440 Right (Addressed dst msg') -> do
417 hPutStrLn stderr $ unwords [ "peelOnion:", show n, either show show (either4or6 saddr), "SUCCESS"] 441 hPutStrLn stderr $ unwords [ "peelOnion:", show n, either show show (either4or6 saddr), "-->", either show show (either4or6 dst), "SUCCESS"]
418 sendMessage udp dst (runPut $ putRequest $ OnionRequest nonce msg' $ wrapSymmetric sym snonce saddr rpath) 442 sendMessage udp dst (runPut $ putRequest $ OnionRequest nonce msg' $ wrapSymmetric sym snonce saddr rpath)
419 kont 443 kont
420 444
@@ -472,9 +496,13 @@ getOnionRequest = do
472 path <- get 496 path <- get
473 return (a,path) 497 return (a,path)
474 498
475putRequest :: (KnownPeanoNat n, Serialize (OnionRequest n)) => OnionRequest n -> Put 499putRequest :: ( KnownPeanoNat n
500 , Serialize (OnionRequest n)
501 , Typeable n
502 ) => OnionRequest n -> Put
476putRequest req = do 503putRequest req = do
477 putWord8 $ 0x80 + fromIntegral (peanoVal req) 504 let tag = 0x80 + fromIntegral (peanoVal req)
505 when (tag <= 0x82) (putWord8 tag)
478 put req 506 put req
479 507
480putResponse :: (KnownPeanoNat n, Serialize (OnionResponse n)) => OnionResponse n -> Put 508putResponse :: (KnownPeanoNat n, Serialize (OnionResponse n)) => OnionResponse n -> Put
@@ -513,9 +541,14 @@ data AnnounceResponse = AnnounceResponse
513instance Sized AnnounceResponse where 541instance Sized AnnounceResponse where
514 size = contramap is_stored size <> contramap announceNodes size 542 size = contramap is_stored size <> contramap announceNodes size
515 543
544getNodeList :: S.Get [NodeInfo]
545getNodeList = do
546 n <- S.get
547 (:) n <$> (getNodeList <|> pure [])
548
516instance S.Serialize AnnounceResponse where 549instance S.Serialize AnnounceResponse where
517 get = AnnounceResponse <$> S.get <*> S.get 550 get = AnnounceResponse <$> S.get <*> (SendNodes <$> getNodeList)
518 put (AnnounceResponse st ns) = S.put st >> S.put ns 551 put (AnnounceResponse st (SendNodes ns)) = S.put st >> mapM_ S.put ns
519 552
520data DataToRoute = DataToRoute 553data DataToRoute = DataToRoute
521 { dataFromKey :: PublicKey -- Real public key of sender 554 { dataFromKey :: PublicKey -- Real public key of sender