diff options
author | joe <joe@jerkface.net> | 2017-10-12 05:41:09 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2017-10-12 05:41:09 -0400 |
commit | 37a7fa4978f89072d9231bcc9bd0848bb52c676c (patch) | |
tree | 48a2a934e5da1c6754915d5ad27417f604cbfd04 /src/Network/Tox/Onion/Transport.hs | |
parent | 3024b35b05d7f520666af20ced8d1f3080837bb2 (diff) |
WIP Onion routing.
Diffstat (limited to 'src/Network/Tox/Onion/Transport.hs')
-rw-r--r-- | src/Network/Tox/Onion/Transport.hs | 61 |
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 | ||
40 | import Network.Address (fromSockAddr,toSockAddr,setPort,either4or6,sockAddrPort) | 42 | import Network.Address (fromSockAddr,toSockAddr,setPort,either4or6,sockAddrPort) |
@@ -42,10 +44,11 @@ import Network.QueryResponse | |||
42 | import Crypto.Tox hiding (encrypt,decrypt) | 44 | import Crypto.Tox hiding (encrypt,decrypt) |
43 | import Network.Tox.NodeId | 45 | import Network.Tox.NodeId |
44 | import qualified Crypto.Tox as ToxCrypto | 46 | import qualified Crypto.Tox as ToxCrypto |
45 | import Network.Tox.DHT.Transport (NodeInfo(..),NodeId(..),SendNodes,nodeInfo,DHTPublicKey,asymNodeInfo) | 47 | import Network.Tox.DHT.Transport (NodeInfo(..),NodeId(..),SendNodes(..),nodeInfo,DHTPublicKey,asymNodeInfo) |
46 | 48 | ||
47 | import Debug.Trace | 49 | import Debug.Trace |
48 | import Control.Arrow | 50 | import Control.Arrow |
51 | import Control.Applicative | ||
49 | import Control.Concurrent.STM | 52 | import Control.Concurrent.STM |
50 | import Control.Monad | 53 | import Control.Monad |
51 | import qualified Data.ByteString as B | 54 | import 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 | ||
94 | msgNonce :: OnionMessage f -> Nonce24 | ||
95 | msgNonce (OnionAnnounce a) = assymNonce a | ||
96 | msgNonce (OnionAnnounceResponse _ n24 _) = n24 | ||
97 | msgNonce (OnionToRoute _ a) = assymNonce a | ||
98 | msgNonce (OnionToRouteResponse a) = assymNonce a | ||
99 | |||
91 | data OnionDestination r | 100 | data 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 | ||
105 | onionNodeInfo :: OnionDestination r -> NodeInfo | ||
106 | onionNodeInfo (OnionToOwner ni _) = ni | ||
107 | onionNodeInfo (OnionDestination ni _) = ni | ||
108 | |||
96 | onionKey :: OnionDestination r -> Maybe PublicKey | 109 | onionKey :: OnionDestination r -> Maybe PublicKey |
97 | onionKey (OnionToOwner ni _) = Just $ id2key (nodeId ni) | 110 | onionKey od = Just $ id2key . nodeId $ onionNodeInfo od |
98 | onionKey (OnionDestination ni _) = Just $ id2key (nodeId ni) | ||
99 | 111 | ||
100 | instance Sized (OnionMessage Encrypted) where | 112 | instance Sized (OnionMessage Encrypted) where |
101 | size = VarSize $ \case | 113 | size = VarSize $ \case |
@@ -176,11 +188,19 @@ encodeOnionAddr :: (NodeInfo -> r -> IO (Maybe OnionRoute)) | |||
176 | encodeOnionAddr _ (msg,OnionToOwner ni p) = | 188 | encodeOnionAddr _ (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 ) |
179 | encodeOnionAddr _ (msg,OnionDestination _ Nothing ) = return Nothing | 191 | encodeOnionAddr _ (msg,OnionDestination _ Nothing ) = do |
192 | hPutStrLn stderr $ "ONION encode missing routeid" | ||
193 | return Nothing | ||
180 | encodeOnionAddr getRoute (msg,OnionDestination ni (Just rid)) = do | 194 | encodeOnionAddr 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 | ||
186 | forwardOnions :: TransportCrypto -> UDPTransport -> UDPTransport | 206 | forwardOnions :: TransportCrypto -> UDPTransport -> UDPTransport |
@@ -239,16 +259,19 @@ deriving instance ( Show (Forwarding (ThreeMinus n) (OnionMessage Encrypted)) | |||
239 | instance ( Serialize (Forwarding (ThreeMinus n) (OnionMessage Encrypted)) | 259 | instance ( 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 |
406 | handleOnionRequest proxy crypto saddr udp kont (OnionRequest nonce msg rpath) = do | 430 | handleOnionRequest 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 | ||
475 | putRequest :: (KnownPeanoNat n, Serialize (OnionRequest n)) => OnionRequest n -> Put | 499 | putRequest :: ( KnownPeanoNat n |
500 | , Serialize (OnionRequest n) | ||
501 | , Typeable n | ||
502 | ) => OnionRequest n -> Put | ||
476 | putRequest req = do | 503 | putRequest 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 | ||
480 | putResponse :: (KnownPeanoNat n, Serialize (OnionResponse n)) => OnionResponse n -> Put | 508 | putResponse :: (KnownPeanoNat n, Serialize (OnionResponse n)) => OnionResponse n -> Put |
@@ -513,9 +541,14 @@ data AnnounceResponse = AnnounceResponse | |||
513 | instance Sized AnnounceResponse where | 541 | instance Sized AnnounceResponse where |
514 | size = contramap is_stored size <> contramap announceNodes size | 542 | size = contramap is_stored size <> contramap announceNodes size |
515 | 543 | ||
544 | getNodeList :: S.Get [NodeInfo] | ||
545 | getNodeList = do | ||
546 | n <- S.get | ||
547 | (:) n <$> (getNodeList <|> pure []) | ||
548 | |||
516 | instance S.Serialize AnnounceResponse where | 549 | instance 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 | ||
520 | data DataToRoute = DataToRoute | 553 | data DataToRoute = DataToRoute |
521 | { dataFromKey :: PublicKey -- Real public key of sender | 554 | { dataFromKey :: PublicKey -- Real public key of sender |