hmssql
Safe HaskellNone
LanguageHaskell2010

Hmssql.Tds.Packet

Description

TDS packet framing.

MS-TDS 2.2.3 Packets

Synopsis

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

Instances details
Show PacketType Source # 
Instance details

Defined in Hmssql.Tds.Packet

Eq PacketType Source # 
Instance details

Defined in Hmssql.Tds.Packet

newtype PacketStatus Source #

The status byte of a packet header; statusEndOfMessage, statusIgnore and statusResetConnection are its bits.

Constructors

PacketStatus Word8 

data Header Source #

A packet header.

Constructors

Header 

Fields

Instances

Instances details
Show Header Source # 
Instance details

Defined in Hmssql.Tds.Packet

Eq Header Source # 
Instance details

Defined in Hmssql.Tds.Packet

Methods

(==) :: Header -> Header -> Bool #

(/=) :: Header -> Header -> Bool #

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).

getHeader :: Get Header Source #

readHeader as a Get (the tests' mock server).

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.)