create local server socket

This commit is contained in:
Trolli Schmittlauch 2020-05-12 21:24:56 +02:00
parent 906cdc67c3
commit 0682bf4bad
4 changed files with 64 additions and 26 deletions

View file

@ -46,7 +46,7 @@ category: Network
extra-source-files: CHANGELOG.md
common deps
build-depends: base ^>=4.12.0.0, containers ^>=0.6.0.1, bytestring, utf8-string ^>=1.0.1.1, network ^>=2.8.0.1, time ^>=1.8.0.2, cmdargs ^>= 0.10, cryptonite ^>= 0.25, memory, async, asn1-encoding, asn1-types, asn1-parse, publicsuffix, network-byte-order, safe
build-depends: base ^>=4.12.0.0, containers ^>=0.6.0.1, bytestring, utf8-string ^>=1.0.1.1, network ^>=2.8.0.1, time ^>=1.8.0.2, cmdargs ^>= 0.10, cryptonite ^>= 0.25, memory, async, asn1-encoding, asn1-types, asn1-parse, publicsuffix, network-byte-order, safe, iproute
ghc-options: -Wall
@ -74,7 +74,7 @@ executable Hash2Pub
import: deps
-- adding the library as a dependency
build-depends: Hash2Pub, iproute
build-depends: Hash2Pub
-- .hs or .lhs file containing the Main module.
main-is: Main.hs

View file

@ -19,6 +19,8 @@ import Data.Maybe (maybe, fromMaybe)
import qualified Data.Set as Set
import qualified Data.Map as Map
import Data.Time.Clock.POSIX
import Network.Socket hiding (send, sendTo, recv, recvFrom)
import Network.Socket.ByteString
import Hash2Pub.FediChord
( NodeID
@ -187,4 +189,3 @@ deleteCacheEntry = Map.update modifier
modifier (ProxyEntry idPointer _) = Just (ProxyEntry idPointer Nothing)
modifier NodeEntry {} = Nothing

View file

@ -38,6 +38,8 @@ module Hash2Pub.FediChord (
, bsAsIpAddr
, FediChordConf(..)
, fediChordInit
, mkServerSocket
, resolve
) where
import qualified Data.Map.Strict as Map
@ -53,6 +55,7 @@ import qualified Data.ByteString as BS
import qualified Data.ByteString.UTF8 as BSU
import qualified Data.ByteArray as BA
import qualified Network.ByteOrder as NetworkBytes
import Data.IP (IPv6, fromHostAddress6, toHostAddress6)
import Hash2Pub.Utils
@ -392,7 +395,6 @@ checkCacheSlices state = case getNodeCache state of
-- Todo: DHT backend can learn potential initial bootstrapping points through the instances mentioned in the received AP-relay messages
-- needs to know its own domain anyways for ID generation
-- persist them on disk so they can be used for all following bootstraps
-- | configuration values used for initialising the FediChord DHT
@ -402,27 +404,61 @@ data FediChordConf = FediChordConf {
, confDhtPort :: Int
} deriving (Show, Eq)
-- | initialise data structures, compute own IDs.
-- | initialise data structures, compute own IDs and bind to listening socket
-- ToDo: load persisted state, thus this function already operates in IO
fediChordInit :: FediChordConf -> IO NodeState
fediChordInit conf = return $ NodeState {
domain = confDomain conf
, ipAddr = confIP conf
, nid = genNodeID (confIP conf) (confDomain conf) 0
, dhtPort = toEnum $ confDhtPort conf
, apPort = Nothing
, vServerID = 0
, internals = Just internalsInit
}
where
internalsInit = InternalNodeState {
nodeCache = initCache
, successors = []
, predecessors = []
, kNeighbours = 3
, lNumBestNodes = 3
, pNumParallelQueries = 2
, jEntriesPerSlice = 2
}
fediChordInit :: FediChordConf -> IO (Socket, NodeState)
fediChordInit conf = do
let
initialState = NodeState {
domain = confDomain conf
, ipAddr = confIP conf
, nid = genNodeID (confIP conf) (confDomain conf) 0
, dhtPort = toEnum $ confDhtPort conf
, apPort = Nothing
, vServerID = 0
, internals = Just internalsInit
}
internalsInit = InternalNodeState {
nodeCache = initCache
, successors = []
, predecessors = []
, kNeighbours = 3
, lNumBestNodes = 3
, pNumParallelQueries = 2
, jEntriesPerSlice = 2
}
serverSock <- mkServerSocket (ipAddr initialState) (dhtPort initialState)
return (serverSock, initialState)
--fediChordJoin :: NodeState -- ^ the local 'NodeState'
-- -> (String, PortNumber) -- ^ domain and port of a bootstrapping node
-- -> IO Either String NodeState -- ^ the joined 'NodeState' after a successful
-- -- join, otherwise an error message
--fediChordJoin
-- ====== network socket operations ======
-- | resolve a specified host and return the 'AddrInfo' for it.
-- If no hostname or IP is specified, the 'AddrInfo' can be used to bind to all
-- addresses;
-- if no port is specified an arbitrary free port is selected.
resolve :: Maybe String -- ^ hostname or IP address to be resolved
-> Maybe PortNumber -- ^ port number of either local bind or remote
-> IO AddrInfo
resolve host port = let
hints = defaultHints { addrFamily = AF_INET6, addrSocketType = Datagram
, addrFlags = [AI_PASSIVE] }
in
head <$> getAddrInfo (Just hints) host (show <$> port)
-- | create an unconnected UDP Datagram 'Socket' bound to the specified address
mkServerSocket :: HostAddress6 -> PortNumber -> IO Socket
mkServerSocket ip port = do
sockAddr <- addrAddress <$> resolve (Just $ show . fromHostAddress6 $ ip) (Just port)
sock <- socket AF_INET6 Datagram defaultProtocol
setSocketOption sock IPv6Only 1
bind sock sockAddr
return sock

View file

@ -11,8 +11,9 @@ main = do
-- probably use `tomland` for that
conf <- readConfig
-- ToDo: load persisted caches, bootstrapping nodes …
thisNode <- fediChordInit conf
(serverSock, thisNode) <- fediChordInit conf
print thisNode
print serverSock
return ()
readConfig :: IO FediChordConf