Skip to content

Freestyle probe

The Freestyle probe opens a plain TCP or UDP socket and lets you drive it yourself. You write the bytes to send, say how much to read back, and check what came in. Nothing parses the conversation for you, so it is how you reach a protocol VirtuProbe has no dedicated probe for, a proprietary service on an internal port, or a device that answers in binary and nothing else.

It is also the probe to reach for when a purpose-built one would get in the way. A dedicated probe knows the grammar of its protocol and will politely correct you. Freestyle sends what you typed.

FieldDescription
HostHostname or IP of the service
PortTarget port
TransportTCP or UDP
TLSWrap the connection in TLS. TCP only; the toggle is disabled for UDP.
Trust self-signedSkip certificate validation, for lab targets and appliances with their own CA
Connect timeout (ms)How long to wait for the connection itself
Read timeout (ms)How long to wait for bytes once connected

A probe is a list of exchanges, run in order down one connection. Each exchange sends a payload, reads a reply, or does one without the other. That is what makes Freestyle usable for anything with a handshake: a banner arrives before you say anything, you greet, it answers, and you carry on.

FieldDescription
LabelA name for this exchange. Extractors address exchanges by label, so it is worth setting.
PayloadThe bytes to send
Payload asHow the payload text is interpreted: Text, Hex or Base64
Receive onlySend nothing and just read, for a server that speaks first
Response must containFail the exchange unless the reply contains this text
Expected outcomeHow this exchange should end. It passes when the exchange ends that way, and any other outcome fails it.

In Text mode the escapes \r \n \t \0 \\ and \xNN are understood, so a line-oriented protocol reads naturally: EHLO probe\r\n. Use Hex when the protocol is binary and Base64 when you already have the bytes in that form.

Each exchange can be switched off without deleting it, which is how you bisect a handshake that stopped working.

Knowing when a reply has finished is the hard part of talking to a socket directly, so the read strategy is explicit per exchange.

StrategyReads untilSettings
Nothing, send onlyDoes not read at all
The peer goes quietNo further bytes arrive for a whileQuiet for (ms)
A delimiter appearsA byte sequence shows up in the streamDelimiter, Delimiter as
A byte count is reachedExactly this many bytes have arrivedBytes
A length prefix says soThe reply’s own length field says the body is completePrefix width, Big endian, Length includes the prefix

Ceiling (bytes) caps any strategy, so a talkative or misbehaving peer cannot run the read forever.

The length-prefix strategy is the one that makes binary protocols practical. A great many of them put a two or four byte length in front of each message, and once you tell the probe how wide that field is and which way round it reads, the whole reply arrives as one unit.

Every exchange ends with an outcome, shown as a chip beside it. A failure that is really a refused connection and a failure that is really a timeout are different findings, and the outcome is what tells them apart.

OutcomeShown asMeaning
OKOKThe exchange completed
EOFPeer closedThe peer closed the connection
RSTConnection resetThe peer reset the connection
TIMEOUTTimed outNo reply within the read timeout
PARTIALIncompleteSome bytes arrived, but the strategy was never satisfied
CONNECT_REFUSEDConnection refusedNothing accepted the connection
CONNECT_TIMEOUTConnect timed outThe connection itself never came up
RESOLVE_FAILEDHost not foundThe hostname did not resolve

Setting Expected outcome on an exchange turns this column into an assertion. The exchange then passes when it ends the way you named, whichever way that is. A timeout you asked for is a pass, and so is a reset.

Leave it blank and the exchange has to complete normally, so a timeout or a reset counts as a failure. That is the useful default, because most of the time you wanted bytes back and did not get them.

A port that should be closed is a passing test, and it is written the same way. The one thing to know is that a refused connection happens before any exchange gets to run, so the expectation is read from the first exchange in the list:

FieldValue
HostThe host you are checking
PortThe port that should be closed
PayloadAnything, since nothing is sent when the connection is refused
Expected outcomeCONNECT_REFUSED

That probe is green for as long as the port stays closed, and red the day something starts answering on it. CONNECT_TIMEOUT and RESOLVE_FAILED work the same way, which covers a host that should be firewalled off and a name that should not resolve.

The response panel shows each exchange with what was Sent and what was Received, the byte counts, and how long it took. Bytes are shown as a hex dump alongside their printable form, so a reply that is mostly binary with a readable string in it is legible either way. A long reply is truncated in the view; the full bytes are still what extractors see.

Freestyle steps expose their result to the rest of a chain through these extractors. Where an expression takes a label, leaving it blank means the last exchange.

ExtractorExpressionReturns
FREESTYLE_SUCCESSnoneWhether the probe succeeded
FREESTYLE_TEXTexchange labelThe reply as text
FREESTYLE_HEXexchange labelThe reply as hex, in the form a later Hex payload can use directly
FREESTYLE_HEX_SLICElabel|offset:lengthBytes at a known position, as hex. A slice running past the end is clamped rather than refused.
FREESTYLE_REGEXlabel|regexThe first capture group, or the whole match when the pattern has none
FREESTYLE_BYTE_COUNTexchange labelHow many bytes came back
FREESTYLE_OUTCOMEexchange labelThe outcome, so a chain can branch on how the exchange ended

FREESTYLE_HEX and FREESTYLE_HEX_SLICE are what let one exchange feed the next: pull a session token out of a binary reply by offset, and send it back in the following request.

A Freestyle probe works as a chain step like any other protocol, so it composes with the rest. An HTTP call can trigger work, a Freestyle step can confirm the service behind it answered on its own port, and an assert step can decide the verdict.