1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeOperators #-}
module Network.Tox.Transport (toxTransport, RouteId) where
import Network.QueryResponse
import Crypto.Tox
import Data.Tox.Relay as TCP
import qualified Data.Tox.DHT.Multi as Multi
import Network.Tox.DHT.Transport as UDP
import Network.Tox.TCP (ViaRelay)
import Network.Tox.Onion.Transport
import Network.Tox.Crypto.Transport
import Network.Tox.Onion.Routes
import Control.Concurrent.STM
import qualified Data.ByteString as B
import qualified Data.Dependent.Map as DMap
import Data.Dependent.Sum
import Data.Functor.Identity
import Network.Socket
pendingCookiesUDP :: TransportCrypto -> STM [(SockAddr, (Int, PublicKey))]
pendingCookiesUDP crypto = readTVar $ pendingCookies crypto
pendingCookiesTCP :: TransportCrypto -> STM [(ViaRelay, (Int, PublicKey))]
pendingCookiesTCP crypto = return [] -- TODO
toxTransport ::
TransportCrypto
-> OnionRouter
-> (PublicKey -> IO (Maybe UDP.NodeInfo))
-> SockAddr -- ^ UDP bind-address
-> UDPTransport
-> Transport String ViaRelay B.ByteString
-> (TCP.NodeInfo -> RelayPacket -> IO ()) -- ^ TCP server-bound callback.
-> (Int -> OnionMessage Encrypted -> IO ()) -- ^ TCP client-bound callback.
-> IO ( Transport String Multi.SessionAddress (CryptoPacket Encrypted)
, Transport String Multi.NodeInfo (DHTMessage Encrypted8)
, Transport String (OnionDestination RouteId) (OnionMessage Encrypted)
, Transport String AnnouncedRendezvous (PublicKey,OnionData)
, Transport String Multi.SessionAddress (Handshake Encrypted))
toxTransport crypto orouter closeLookup addr udp relaynet tcp2server tcp2client = do
(netcrypto, udp0) <- partitionTransport parseCrypto encodeCrypto udp
(dhtUDP,udp1) <- partitionTransportM (parseDHTAddr (pendingCookiesUDP crypto) nodeInfo)
(fmap Just . encodeDHTAddr nodeAddr)
$ forwardOnions crypto addr udp0 tcp2client
-- rlynet0 = layerTransportM (DHT.decrypt crypto Multi.relayNodeId) (DHT.encrypt crypto Multi.relayNodeId) relaynet
(dhtTCP,relaynet0) <- partitionTransportM
(parseDHTAddr (pendingCookiesTCP crypto) (\nid viarelay -> Right viarelay))
(fmap Just . encodeDHTAddr id)
relaynet
let _ = dhtTCP :: Transport String ViaRelay (DHTMessage Encrypted8)
dht <- mergeTransports $ DMap.fromList
[ Multi.UDP :=> ByAddress dhtUDP
, Multi.TCP :=> ByAddress dhtTCP
]
(onion1,udp2) <- partitionAndForkTransport tcp2server
(parseOnionAddr $ lookupSender orouter)
(encodeOnionAddr crypto $ lookupRoute orouter)
udp1
(dta,onion) <- partitionTransportM (parseDataToRoute crypto) (encodeDataToRoute crypto) onion1
let handshakes = layerTransport parseHandshakes encodeHandshakes udp2
promoteUDP :: TransportA err SockAddr x y -> TransportA err Multi.SessionAddress x y
promoteUDP net = layerTransport (\msg saddr -> Right (msg,Multi.SessionUDP ==> saddr))
(\msg (Multi.SessionUDP :=> Identity saddr) -> (msg,saddr))
net
-- TODO: Enable sessions over TCP
multi_netcrypto = promoteUDP netcrypto
multi_handshakes = promoteUDP handshakes
return ( multi_netcrypto
, forwardDHTRequests crypto (fmap (fmap (Multi.UDP ==>)) . closeLookup) dht
, onion
, dta
, multi_handshakes
)
-- instance (Sized a, Sized b) => Sized (a,b) where size = _todo
-- Byte value Packet Kind Return address
-- :----------- :--------------------
-- `0x00` Ping Request DHTNode
-- `0x01` Ping Response -
-- `0x02` Nodes Request DHTNode
-- `0x04` Nodes Response -
-- `0x18` Cookie Request DHTNode, but without sending pubkey in response
-- `0x19` Cookie Response - (no pubkey)
--
-- `0x21` LAN Discovery DHTNode (No reply, port 33445, trigger Nodes Request/Response)
--
-- `0x20` DHT Request DHTNode/-forward
--
-- `0x1a` Crypto Handshake CookieAddress
--
-- `0x1b` Crypto Data SessionAddress
--
-- `0x83` Announce Request OnionToOwner
-- `0x84` Announce Response -
-- `0x85` Onion Data Request OnionToOwner
-- `0x86` Onion Data Response -
--
-- `0xf0` Bootstrap Info SockAddr?
--
-- `0x80` Onion Request 0 -forward
-- `0x81` Onion Request 1 -forward
-- `0x82` Onion Request 2 -forward
-- `0x8c` Onion Response 3 -return
-- `0x8d` Onion Response 2 -return
-- `0x8e` Onion Response 1 -return
|