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)
initTimers tcp
queueTcp :: TcpHandle -> IP4Header -> S.ByteString -> IO ()
queueTcp tcp !hdr !bs = send tcp (handleIncomingTcp hdr bs)
isnRate :: POSIXTime
isnRate = 128000
stepTcp :: Tcp () -> Tcp ()
stepTcp body = do
now <- time
lastUpdate <- getLastUpdate
let diff = now lastUpdate
inc = round (isnRate * diff)
when (inc > 0) $
modifyHost_ $ \ host ->
host { hostLastUpdate = now
, hostInitialSeqNum = hostInitialSeqNum host + inc
}
body