hans-2.4.0.1: src/Hans/Layer/Tcp.hs
{-# LANGUAGE BangPatterns #-}
module Hans.Layer.Tcp (
TcpHandle
, runTcpLayer
, queueTcp
) where
import Hans.Channel
import Hans.Layer
import Hans.Layer.IP4
import Hans.Layer.Tcp.Handlers
import Hans.Layer.Tcp.Monad
import Hans.Layer.Tcp.Timers
import Hans.Layer.Tcp.Types
import Hans.Message.Ip4
import Hans.Message.Tcp
import Hans.Utils
import Control.Concurrent (forkIO)
import Control.Monad (when)
import Data.Time.Clock.POSIX (getPOSIXTime,POSIXTime)
import qualified Data.ByteString as S
runTcpLayer :: TcpHandle -> IP4Handle -> IO ()
runTcpLayer tcp ip4 = do
start <- getPOSIXTime
let s0 = emptyTcpState tcp ip4 start
void (forkIO (loopLayer "tcp" s0 (receive tcp) stepTcp))
addIP4Handler ip4 tcpProtocol (queueTcp tcp)
-- initialize the timers
initTimers tcp
-- | Queue a tcp packet.
queueTcp :: TcpHandle -> IP4Header -> S.ByteString -> IO ()
queueTcp tcp !hdr !bs = send tcp (handleIncomingTcp hdr bs)
-- | Rate of ISN increase, in Hz.
isnRate :: POSIXTime
isnRate = 128000
-- | Run the tcp action, after updating any internal state.
stepTcp :: Tcp () -> Tcp ()
stepTcp body = do
now <- time
lastUpdate <- getLastUpdate
let diff = now - lastUpdate
-- increment the ISN at 128KHz
inc = round (isnRate * diff)
when (inc > 0) $
modifyHost_ $ \ host ->
host { hostLastUpdate = now
, hostInitialSeqNum = hostInitialSeqNum host + inc
}
body