# udpcheck

Source: https://www.pingtower.com/docs/addons/udpcheck/

Send one datagram to a UDP port and wait for the reply, retrying when one is lost. Runs on your own agents only.

UDP has no handshake, so an open port proves nothing. The only sign a UDP service is alive is a reply to something it understands. You supply that something as the payload, and optionally what the reply must contain. A datagram can be lost without anyone at fault, so a silent attempt is retried before the target is called down.

`udpcheck` runs on your own agents only. Datagrams of any content sent from Pingtower's shared addresses would put those addresses' reputation at risk, so a check that names a Pingtower region is refused with a `422` under the rule `agent_only`. See [Hosted checks](/docs/service/checks/#what-runs-where).

## Parameters

| Parameter | Default | Meaning |
| --- | --- | --- |
| `address`<span class="req">REQUIRED</span> | | `host:port`. There is no default port. |
| `payload` | | The datagram to send, as text. Exactly one of `payload` and `payload_hex` is required. 1 to 1,024 bytes. |
| `payload_hex` | | The datagram, hex-encoded, for binary protocols. |
| `expect` | | Text the reply must contain. Unset, any reply passes. |
| `expect_hex` | | Bytes the reply must contain, hex-encoded. At most one of `expect` and `expect_hex`. |
| `attempts` | `3` | Sends before a silent target is **down**, 1 to 5. |
| `max_rtt` | | Round trip above this is **degraded**. |

The check's timeout is split evenly across the attempts still to make, so a lost first datagram can't use up the time the retries need.

## Status

A reply that contains `expect` is **up**: `replied in 3ms`. Over `max_rtt` it is **degraded**.

It is **down** when:

- the host does not resolve;
- the target answers with ICMP port unreachable: `port unreachable`;
- every attempt goes unanswered: `no reply after 3 attempts`;
- a reply arrives that does not contain `expect`. That is an answer, not a loss, so it is not retried.

## Measurements

| Key | Meaning |
| --- | --- |
| `dns_ms` | Resolution time, when `address` names a host rather than an IP |
| `attempts` | Datagrams sent |
| `rtt_ms` | Round trip of the attempt that was answered |
| `total_ms` | The whole run |
| `port` | Label: the target port |

The check needs addons agent 0.4.0 or later; an older agent reports it as an unknown addon.

## Example

A DNS server answering a query for `example.com`, sent as raw bytes:

```yaml
- id: resolver-udp
  addon: udpcheck
  interval: 30s
  with:
    address: 10.0.0.53:53
    payload_hex: "abcd01000001000000000000076578616d706c6503636f6d0000010001"
    expect_hex: "abcd"
    attempts: 3
    max_rtt: 50ms
```

## A rule for it

```json
{"name":"udp-down","match":{"tags":["addon:udpcheck"],"min_level":400}}
```
