| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Hmssql.Tds.Packet
Description
TDS packet framing.
Synopsis
- data PacketType
- packetTypeWord :: PacketType -> Word8
- packetTypeFromWord :: Word8 -> PacketType
- newtype PacketStatus = PacketStatus Word8
- statusEndOfMessage :: PacketStatus
- statusIgnore :: PacketStatus
- statusResetConnection :: PacketStatus
- data Header = Header {
- headerType :: !PacketType
- headerStatus :: !PacketStatus
- headerPacketLength :: !Word16
- headerSpid :: !Word16
- headerPacketId :: !Word8
- headerWindow :: !Word8
- headerLength :: Int
- readHeader :: ByteString -> Header
- getHeader :: Get Header
- putHeader :: Header -> Put
- pokePacketHeader :: Ptr Word8 -> PacketType -> PacketStatus -> Int -> Word8 -> IO ()
- packetPayloadSize :: TdsContext -> Int
- splitIntoPackets :: TdsContext -> PacketType -> PacketStatus -> ByteString -> [ByteString]
- frameSegments :: Int -> TdsContext -> PacketType -> PacketStatus -> ByteString -> [ByteString]
- pokeFramedPacket :: Ptr Word8 -> PacketType -> PacketStatus -> Bool -> Word8 -> Bool -> Int -> [ByteString] -> IO [ByteString]
- packetCount :: TdsContext -> ByteString -> Int
- maxSqlBatchPackets :: Int
Documentation
data PacketType Source #
The type byte of a packet header.
Constructors
| PTSqlBatch | 0x01 |
| PTRpc | 0x03 |
| PTTabularResult | 0x04 |
| PTAttention | 0x06 |
| PTBulkLoad | 0x07 |
| PTTransactionManager | 0x0E |
| PTLogin7 | 0x10 |
| PTSspi | 0x11 |
| PTPrelogin | 0x12, also carries TLS handshake records for non-strict encryption |
| PTOther !Word8 |
Instances
| Show PacketType Source # | |
Defined in Hmssql.Tds.Packet Methods showsPrec :: Int -> PacketType -> ShowS # show :: PacketType -> String # showList :: [PacketType] -> ShowS # | |
| Eq PacketType Source # | |
Defined in Hmssql.Tds.Packet | |
packetTypeWord :: PacketType -> Word8 Source #
packetTypeFromWord :: Word8 -> PacketType Source #
newtype PacketStatus Source #
The status byte of a packet header; statusEndOfMessage, statusIgnore
and statusResetConnection are its bits.
Constructors
| PacketStatus Word8 |
Instances
A packet header.
Constructors
| Header | |
Fields
| |
headerLength :: Int Source #
The fixed size of a TDS packet header, in bytes. The total packet
length is the separate headerPacketLength field.
readHeader :: ByteString -> Header Source #
The header at the start of a buffer of at least headerLength bytes,
read in place: one per packet received (error on a shorter buffer).
pokePacketHeader :: Ptr Word8 -> PacketType -> PacketStatus -> Int -> Word8 -> IO () Source #
Write a packet header at the pointer: the type, the status (as given;
the caller sets statusEndOfMessage on the last packet), the total
length (header included, at most maxPacketSize) and the packet ID.
For a message framed packet by packet as it is produced
(Hmssql.Tds.PacketWriter); frameSegments frames a complete body.
packetPayloadSize :: TdsContext -> Int Source #
The body bytes each packet of splitIntoPackets carries: the
negotiated packet size less the header (clamped as frameSegments
clamps it).
splitIntoPackets :: TdsContext -> PacketType -> PacketStatus -> ByteString -> [ByteString] Source #
Frame a complete message body into packets of the negotiated size, one
strict chunk per packet. (frameSegments with one packet per segment.)
The extra status bits go on every packet, except statusResetConnection,
which goes on the first packet only (MS-TDS 2.2.3.1.2), and EOM, which is
set on the last packet here.
Body lengths and the framed allocation sizes must fit in Int.
A packet size outside what the header can describe is clamped: to at
least one byte of payload, so the split always makes progress, and to at
most maxPacketSize, so the 16-bit length field never truncates. (The
connection never negotiates such a size; the clamp prevents a zero-size
split or a truncated packet header.)
frameSegments :: Int -> TdsContext -> PacketType -> PacketStatus -> ByteString -> [ByteString] Source #
Frame a complete message body as splitIntoPackets does, into strict
chunks of as many whole packets as fit in the given number of bytes (at
least one packet each). The message is the chunks concatenated. Body
lengths and framed allocation sizes must fit in Int. No uninitialized
prefix is reserved by this entry point.
Each byte of the body is copied once, into a chunk of exactly its size; the chunks are produced lazily, so a message sent as it is framed needs the body and one chunk at a time. The connection sends a chunk at a time, sized to fill a TLS record, or a larger socket write.
pokeFramedPacket :: Ptr Word8 -> PacketType -> PacketStatus -> Bool -> Word8 -> Bool -> Int -> [ByteString] -> IO [ByteString] Source #
Write a whole packet of a message body at the pointer: its header
(with EOM if it is the last, and the extra status bits as
splitIntoPackets describes them) and size bytes of payload from the
front of the chunks; the chunks left.
packetCount :: TdsContext -> ByteString -> Int Source #
How many packets splitIntoPackets frames a message body into.
maxSqlBatchPackets :: Int Source #
The most packets SQL Server accepts in one SQLBatch message: it closes the connection, without an error message, on a longer one. (Hence the documented batch size limit of "65,536 * network packet size"; SQL Server 2025 accepts exactly 65535 full packets, at every packet size and TDS version. RPC messages have no such limit.)