diff options
author | jim@bo <jim@bo> | 2018-06-23 02:51:56 -0400 |
---|---|---|
committer | jim@bo <jim@bo> | 2018-06-23 05:56:39 -0400 |
commit | 8f541d5e4f81ad7766986c48e4296e4d4ec5788b (patch) | |
tree | c41657c1326771b17c8cd4968f56e83e6d765c43 /examples/dhtd.hs | |
parent | 5c42256bb4bbd97b6d179e992eb762625a8dc2b4 (diff) |
OutGoing hooks so SessionView is updated etc
Diffstat (limited to 'examples/dhtd.hs')
-rw-r--r-- | examples/dhtd.hs | 114 |
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 | |||
62 | import qualified Data.Text as T | 62 | import qualified Data.Text as T |
63 | import qualified Data.Text.Encoding as T | 63 | import qualified Data.Text.Encoding as T |
64 | import System.Posix.Signals | 64 | import System.Posix.Signals |
65 | 65 | import qualified Data.Array | |
66 | import qualified Data.Array.Unboxed as U | ||
67 | import qualified Data.Conduit as Conduit | ||
66 | 68 | ||
67 | import Announcer | 69 | import Announcer |
68 | import Announcer.Tox | 70 | import Announcer.Tox |
@@ -103,6 +105,13 @@ import OnionRouter | |||
103 | import PingMachine | 105 | import PingMachine |
104 | import Data.PacketQueue | 106 | import Data.PacketQueue |
105 | import qualified Data.Word64Map as W64 | 107 | import qualified Data.Word64Map as W64 |
108 | import System.FilePath | ||
109 | import System.Process | ||
110 | import System.Posix.IO | ||
111 | import Data.Word64RangeMap | ||
112 | import Network.Tox.Crypto.Transport | ||
113 | import Data.Conduit.Cereal | ||
114 | import qualified Data.Conduit.Binary as Conduit | ||
106 | 115 | ||
107 | -- Presence imports. | 116 | -- Presence imports. |
108 | import ConsoleWriter | 117 | import 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 () |
1287 | netcrypto _ _ h _ Nothing _ = hPutClient h "Requires Tox enabled." | 1299 | netcrypto _ _ h _ Nothing _ _ = hPutClient h "Requires Tox enabled." |
1288 | netcrypto _ Nothing h _ _ _ = hPutClient h "No key is selected, see k command." | 1300 | netcrypto _ Nothing h _ _ _ _ = hPutClient h "No key is selected, see k command." |
1289 | netcrypto (Just (DHT {..})) (Just mypubkey) h roster (Just tox) keystr = | 1301 | netcrypto (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 <- |