UDP::payload

Description

Returns the content (or length in octets) of the payload in the just-received UDP datagram. You may also replace some or all of the payload before the datagram is processed further. This command is valid in CLIENT_DATA and SERVER_DATA, and also in CLIENT_ACCEPTED.
The LTM UDP Profile option “Datagram LB” controls whether UDP flows are created for traffic through a UDP virtual server. By default “Datagram LB” is disabled so UDP flows are created. That improves performance with protocols such as RTP or DTLS which send many related datagrams between a particular client and server. When “Datagram LB” is enabled, flows are not created, thereby saving BIG-IP resources when processing largely unrelated UDP datagrams such as DNS queries.
Though CLIENT_ACCEPTED only fires for the first datagram in a UDP flow, it fires for every datagram when no flow is created.
Unlike with TCP::payload you do not need to invoke any collect or release commands. By default the current datagram is processed normally (load-balanced) after the current iRule event completes. If the virtual server has no pool (and you do not invoke pool or node) then a client-supplied datagram cannot be processed further, so the BIG-IP will discard it and send an ICMP Unreachable message to the client. To avoid that, when you deal with a UDP datagram in an iRule and do not want it to be processed further, invoke UDP::drop to discard it quietly (avoid plain drop and reject because they delete any existing flow record and it is costly to create a new one when the next datagram arrives).
This command returns a binary (octet) string . To process non-textual data use the binary scan command to extract data of interest. As soon as you pass the result of UDP::payload to a text-oriented command such as regexp the iRules TCL interpreter will coerce the data to text. If the payload was not originally ASCII or ISO-8859-1 that conversion will produce garbage.

Syntax

UDP::payload [<size>]
UDP::payload replace <offset> <length> <data>
UDP::payload length

UDP::payload [<size>]

  • Returns the content of the current UDP payload. If <size> is specified, and more than <size> bytes are available, only the first <size> bytes of collected data are returned.

UDP::payload replace <offset> <length> <data>

  • Replaces <length> bytes of the collected payload data starting at <offset> with the given <data>. Note that the <data> does not need to be exactly <length> bytes in length.

UDP::payload length

  • Returns the length, in bytes, of the current UDP payload.

Examples

when CLIENT_DATA {
  # empty payload entirely so there is no packet to send to the server
  UDP::payload replace 0 [UDP::payload length] ""

  # craft a string to hold our  packet data, 0x01 0x00 0x00 0x00 0x02 0x00 0x00 0x00 0x03 0x00 0x00 0x00
  set packetdata [binary format i1i1i1 1 2 3 ]

  # then fill payload with our own data from arbitrary length string called packetdata to send to the server
  # this actually inserts it at the start of the packet, but because we emptied the packet above it becomes the new packet
  UDP::payload replace 0 0 $packetdata

  # Unlike TCP, UDP has no "collect" or "release"
}

Workaround

In at least BIG-IP 9.3.0 you can’t use UDP::payload replace 0 0 $packetdata after emptying the payload entirely
A workaround is to insert your data at the start of the packet, then empty the old data from the end
when CLIENT_DATA {
  # remember how big the incoming packet was
  set oldlength [UDP::payload length]

  # craft a string to hold our  packet data, 0x01 0x00 0x00 0x00 0x02 0x00 0x00 0x00 0x03 0x00 0x00 0x00
  set packetdata [binary format i1i1i1 1 2 3 ]

  # then fill payload with our own data from arbitrary length string called packetdata to send to the server
  # this actually inserts it at the start of the packet, but because we emptied the packet above it becomes the new packet
  UDP::payload replace 0 0 $packetdata

  # now empty the old packet off the end
  UDP::payload replace [string length $packetdata] [expr [UDP::payload length] - [string length $packetdata]] ""
}