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 extra-source-files: CHANGELOG.md
common deps 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 ghc-options: -Wall
@ -74,7 +74,7 @@ executable Hash2Pub
import: deps import: deps
-- adding the library as a dependency -- adding the library as a dependency
build-depends: Hash2Pub, iproute build-depends: Hash2Pub
-- .hs or .lhs file containing the Main module. -- .hs or .lhs file containing the Main module.
main-is: Main.hs main-is: Main.hs

View file

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

View file

@ -38,6 +38,8 @@ module Hash2Pub.FediChord (
, bsAsIpAddr , bsAsIpAddr
, FediChordConf(..) , FediChordConf(..)
, fediChordInit , fediChordInit
, mkServerSocket
, resolve
) where ) where
import qualified Data.Map.Strict as Map 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.ByteString.UTF8 as BSU
import qualified Data.ByteArray as BA import qualified Data.ByteArray as BA
import qualified Network.ByteOrder as NetworkBytes import qualified Network.ByteOrder as NetworkBytes
import Data.IP (IPv6, fromHostAddress6, toHostAddress6)
import Hash2Pub.Utils 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 -- 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 -- persist them on disk so they can be used for all following bootstraps
-- | configuration values used for initialising the FediChord DHT -- | configuration values used for initialising the FediChord DHT
@ -402,27 +404,61 @@ data FediChordConf = FediChordConf {
, confDhtPort :: Int , confDhtPort :: Int
} deriving (Show, Eq) } 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 -- ToDo: load persisted state, thus this function already operates in IO
fediChordInit :: FediChordConf -> IO NodeState fediChordInit :: FediChordConf -> IO (Socket, NodeState)
fediChordInit conf = return $ NodeState { fediChordInit conf = do
domain = confDomain conf let
, ipAddr = confIP conf initialState = NodeState {
, nid = genNodeID (confIP conf) (confDomain conf) 0 domain = confDomain conf
, dhtPort = toEnum $ confDhtPort conf , ipAddr = confIP conf
, apPort = Nothing , nid = genNodeID (confIP conf) (confDomain conf) 0
, vServerID = 0 , dhtPort = toEnum $ confDhtPort conf
, internals = Just internalsInit , apPort = Nothing
} , vServerID = 0
where , internals = Just internalsInit
internalsInit = InternalNodeState { }
nodeCache = initCache internalsInit = InternalNodeState {
, successors = [] nodeCache = initCache
, predecessors = [] , successors = []
, kNeighbours = 3 , predecessors = []
, lNumBestNodes = 3 , kNeighbours = 3
, pNumParallelQueries = 2 , lNumBestNodes = 3
, jEntriesPerSlice = 2 , 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 -- probably use `tomland` for that
conf <- readConfig conf <- readConfig
-- ToDo: load persisted caches, bootstrapping nodes … -- ToDo: load persisted caches, bootstrapping nodes …
thisNode <- fediChordInit conf (serverSock, thisNode) <- fediChordInit conf
print thisNode print thisNode
print serverSock
return () return ()
readConfig :: IO FediChordConf readConfig :: IO FediChordConf