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 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)
send tcp initTimers
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
modifyHost $ \ host ->
let diff = now hostLastUpdate host
inc = round (isnRate * diff)
in if inc > 0
then host
{ hostLastUpdate = now
, hostInitialSeqNum = hostInitialSeqNum host + inc
}
else host
body