summaryrefslogtreecommitdiff
path: root/examples/dhtd.hs
diff options
context:
space:
mode:
authorjim@bo <jim@bo>2018-06-23 02:51:56 -0400
committerjim@bo <jim@bo>2018-06-23 05:56:39 -0400
commit8f541d5e4f81ad7766986c48e4296e4d4ec5788b (patch)
treec41657c1326771b17c8cd4968f56e83e6d765c43 /examples/dhtd.hs
parent5c42256bb4bbd97b6d179e992eb762625a8dc2b4 (diff)
OutGoing hooks so SessionView is updated etc
Diffstat (limited to 'examples/dhtd.hs')
-rw-r--r--examples/dhtd.hs114
1 files changed, 108 insertions, 6 deletions
diff --git a/examples/dhtd.hs b/examples/dhtd.hs
index 1821cb1c..8e34d4fe 100644
--- a/examples/dhtd.hs
+++ b/examples/dhtd.hs
@@ -62,7 +62,9 @@ import qualified Data.HashMap.Strict as HashMap
62import qualified Data.Text as T 62import qualified Data.Text as T
63import qualified Data.Text.Encoding as T 63import qualified Data.Text.Encoding as T
64import System.Posix.Signals 64import System.Posix.Signals
65 65import qualified Data.Array
66import qualified Data.Array.Unboxed as U
67import qualified Data.Conduit as Conduit
66 68
67import Announcer 69import Announcer
68import Announcer.Tox 70import Announcer.Tox
@@ -103,6 +105,13 @@ import OnionRouter
103import PingMachine 105import PingMachine
104import Data.PacketQueue 106import Data.PacketQueue
105import qualified Data.Word64Map as W64 107import qualified Data.Word64Map as W64
108import System.FilePath
109import System.Process
110import System.Posix.IO
111import Data.Word64RangeMap
112import Network.Tox.Crypto.Transport
113import Data.Conduit.Cereal
114import qualified Data.Conduit.Binary as Conduit
106 115
107-- Presence imports. 116-- Presence imports.
108import ConsoleWriter 117import ConsoleWriter
@@ -932,7 +941,9 @@ clientSession s@Session{..} sock cnum h = do
932 941
933 -- necrypto <FRIEND-TOXID> 942 -- necrypto <FRIEND-TOXID>
934 -- establish a netcrypto session with specified person 943 -- establish a netcrypto session with specified person
935 ("netcrypto", s) -> cmd0 $ netcrypto (Map.lookup netname dhts) selectedKey h roster mbTox (strp s) 944 ("netcrypto", s) -> cmd0 $ do
945 let exes = Map.fromList [("atox",("/usr/bin/tmux -c","atox"))]
946 netcrypto (Map.lookup netname dhts) selectedKey h roster mbTox exes (strp s)
936 ("g", s) | Just DHT{..} <- Map.lookup netname dhts 947 ("g", s) | Just DHT{..} <- Map.lookup netname dhts
937 -> cmd0 $ do 948 -> cmd0 $ do
938 -- arguments: method 949 -- arguments: method
@@ -1282,11 +1293,12 @@ netcrypto
1282 -> ClientHandle 1293 -> ClientHandle
1283 -> ContactInfo extra1 1294 -> ContactInfo extra1
1284 -> Maybe (Tox.Tox extra2) 1295 -> Maybe (Tox.Tox extra2)
1296 -> Map.Map String (String,String) -- profile name to (multiplexer,exe name) for supported child executables
1285 -> String 1297 -> String
1286 -> IO () 1298 -> IO ()
1287netcrypto _ _ h _ Nothing _ = hPutClient h "Requires Tox enabled." 1299netcrypto _ _ h _ Nothing _ _ = hPutClient h "Requires Tox enabled."
1288netcrypto _ Nothing h _ _ _ = hPutClient h "No key is selected, see k command." 1300netcrypto _ Nothing h _ _ _ _ = hPutClient h "No key is selected, see k command."
1289netcrypto (Just (DHT {..})) (Just mypubkey) h roster (Just tox) keystr = 1301netcrypto (Just (DHT {..})) (Just mypubkey) h roster (Just tox) exes paramStr =
1290 either 1302 either
1291 (const $ 1303 (const $
1292 either 1304 either
@@ -1297,6 +1309,25 @@ netcrypto (Just (DHT {..})) (Just mypubkey) h roster (Just tox) keystr =
1297 (goPubkey . Tox.id2key) $ 1309 (goPubkey . Tox.id2key) $
1298 readEither keystr -- attempt read as NodeId type 1310 readEither keystr -- attempt read as NodeId type
1299 where 1311 where
1312 params = words paramStr
1313 keystr = bool (head params) "" (null params)
1314 -- TODO:
1315 -- execProfiles:
1316 -- atox@24-25,48-51,64-45 gnome-tox-notifier@24-25,49,50
1317 -- ^-- word64 type values that should be forwarded to this process
1318 execParams=drop 1 params
1319 parseExecParam :: String -> (String,[(Maybe Word64,Maybe Word64)])
1320 parseExecParam param = let (name,drop 1 -> rangesCombined) = span (/='@') param
1321 wordsBy x str = groupBy (const (/=x)) str
1322 rangesUnparsed = wordsBy ',' rangesCombined
1323 parseRange :: String -> (Maybe Word64,Maybe Word64)
1324 parseRange "all" = (Nothing,Nothing)
1325 parseRange x = let (low,drop 1 -> high) = break (==',') x
1326 in (readMaybe low,readMaybe high)
1327 in (name,map parseRange rangesUnparsed)
1328 execs = map parseExecParam execParams
1329
1330
1300 goNodeInfo userkey_nodeinfo = do 1331 goNodeInfo userkey_nodeinfo = do
1301 msec <- 1332 msec <-
1302 atomically $ do 1333 atomically $ do
@@ -1314,7 +1345,78 @@ netcrypto (Just (DHT {..})) (Just mypubkey) h roster (Just tox) keystr =
1314 Just account -> do 1345 Just account -> do
1315 now <- getPOSIXTime 1346 now <- getPOSIXTime
1316 atomically $ setContactAddr now their_pub their_addr account 1347 atomically $ setContactAddr now their_pub their_addr account
1317 Tox.netCrypto tox sec their_pub 1348 sessions <- Tox.netCrypto tox sec their_pub
1349 exeDir <- takeDirectory <$> getExecutablePath
1350 forM_ sessions $ \session -> do
1351 forM_ execs $ \(exekey,ranges) -> do
1352 case Map.lookup exekey exes of
1353 Nothing -> return ()
1354 Just (multiplexer,exename) -> do
1355 let exepath = exeDir </> exename
1356 (myReadFd,myWriteFd) <- System.Posix.IO.createPipe
1357 myRead <- fdToHandle myReadFd
1358 myWrite <- fdToHandle myWriteFd
1359 whoAmI <- atomically $ newTVar mypubkey
1360 whoAreThey <- atomically $ newTVar their_pub
1361 let fdArgs = [show myWriteFd,show myReadFd]
1362 if null multiplexer
1363 then callProcess exepath fdArgs
1364 else do
1365 let (multiplexer_exe,multiplexer_args) = splitAt 1 (words multiplexer)
1366 callProcess multiplexer (multiplexer_args ++ [intercalate " " (exepath:fdArgs)])
1367 -- tell subprocess who is talking to who
1368 B.hPutStr myWrite ("\NUL\NUL" `B.append` S.encode (Tox.key2id mypubkey))
1369 B.hPutStr myWrite ("\NUL\SOH" `B.append` S.encode (Tox.key2id their_pub))
1370 -- add hooks so subprocess is updated on incoming
1371 let makeHook session typ
1372 = \session msg
1373 -> do -- if (getMessageType msg == typ)
1374 me <- atomically $ readTVar whoAmI
1375 when (me /= mypubkey) $ do
1376 atomically $ writeTVar whoAmI mypubkey
1377 B.hPutStr myWrite ("\NUL\NUL" `B.append` S.encode (Tox.key2id mypubkey))
1378 them <- atomically $ readTVar whoAreThey
1379 when (them /= their_pub) $ do
1380 atomically $ writeTVar whoAreThey their_pub
1381 B.hPutStr myWrite ("\NUL\SOH" `B.append` S.encode (Tox.key2id their_pub))
1382 B.hPutStr myWrite (S.encode msg)
1383 return (Just id)
1384 addHooks currentHooks typs = forM_ typs $ \typ -> modifyTVar (Tox.ncHooks session) (Map.insert typ (currentHooks typ ++ [makeHook session typ]))
1385 case ranges of
1386 [(Nothing,Nothing)] -> atomically $ do
1387 typs <- map fromWord64 . filter (/=0) . U.elems <$> readTVar (Tox.ncIncomingTypeArray session)
1388 addHooks (const []) typs
1389 _ -> atomically . forM_ ranges $ \range -> do
1390 case range of
1391 (Just first,Just last) -> do
1392 let typs = map fromWord64 [first .. last]
1393 hooks <- readTVar (Tox.ncHooks session)
1394 let currentHooks typ = fromMaybe [] (Map.lookup typ hooks)
1395 addHooks currentHooks typs
1396 -- forward messages from subprocess
1397 forwardThread <- forkIO $ do
1398 tid <- myThreadId
1399 let sidStr = printf "(%x)" (Tox.ncSessionId session)
1400 labelThread tid (exekey ++ ".forward" ++ sidStr)
1401 let myconduit = Conduit.sourceHandle myRead .| conduitGet2 S.get -- :: ConduitT i CryptoMessage IO ()
1402 Conduit.runConduit (myconduit .| awaitForever (\msg -> do
1403 let typ = toWord64 (getMessageType msg)
1404 mbSendIt <- liftIO $ atomically (lookupInRangeMap typ (Tox.ncOutHooks session))
1405 case mbSendIt of
1406 Just sendit -> liftIO . void $ sendit (Tox.toxCryptoKeys tox) session msg
1407 Nothing -> return () -- do
1408 -- uncomment to let unhooked pass thru:
1409 -- if lossyness (msgId msg) == Lossless
1410 -- then sendLossless (Tox.toxCryptoKeys tox) session msg
1411 -- else sendLossy (Tox.toxCryptoKeys tox) session msg
1412 ))
1413 -- add hook to killThread on kill packet
1414 atomically $ do
1415 hooks <- readTVar (Tox.ncHooks session)
1416 let currentHooks = fromMaybe [] $ Map.lookup (Msg KillPacket) hooks
1417 let myhook :: Tox.NetCryptoSession -> CryptoMessage -> IO (Maybe (CryptoMessage -> CryptoMessage))
1418 myhook _ _ = killThread forwardThread >> return (Just id)
1419 modifyTVar' (Tox.ncHooks session) (Map.insert (Msg KillPacket) (currentHooks ++ [myhook]))
1318 hPutClient h "Handshake sent" 1420 hPutClient h "Handshake sent"
1319 goPubkey their_pub = do 1421 goPubkey their_pub = do
1320 msec <- 1422 msec <-