Quickstart
This page lets you activate a paid destination and confirm end-to-end UDP delivery on a Linux server.
Before you start
- Have a shredstream.sh purchase for one destination.
- Control a server with a stable public IP address or a stable one-to-one UDP port mapping.
- Have Python 3 and sudo access on the receiving Linux server.
- Choose an unused UDP port and substitute it consistently for 9000 in this procedure.
- Have access to the shredstream.sh dashboard for the paid destination.
Set the destination values
This procedure uses UDP port 9000 as a runnable example. Keep that value when it is free, or replace every occurrence with one port you control. Register the server's public IP address, not a private address, unless a public NAT address forwards the same UDP port to the receiver.
Every verification and stream datagram originates from ${SOURCE_IP}. Permit inbound UDP from that exact address. This rule is required even when a cloud firewall, host firewall, or network ACL already permits other traffic. Forgetting this source rule is the most common activation failure.
Open the host firewall
Use this ufw command when ufw manages the host firewall:
bash
sudo ufw allow proto udp from 64.130.40.90 to any port 9000
sudo ufw status numberedUse the matching command from Firewall configuration when the host uses iptables or nftables. Add the same source CIDR, ${SOURCE_IP}/32, to the cloud firewall or security group when the server runs behind one. Do not replace the narrow source with 0.0.0.0/0.
Start a receiver
Run this command in a terminal on the destination server. It binds all local IPv4 interfaces on UDP port 9000, prints the verification payload as text, and reports aggregate stream counters once per second.
bash
python3 - <<'PY'
import socket
import time
HOST = "0.0.0.0"
PORT = 9000
SOURCE_IP = "64.130.40.90"
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 8 * 1024 * 1024)
sock.bind((HOST, PORT))
print(f"listening on udp://{HOST}:{PORT}", flush=True)
stream_packets = 0
stream_bytes = 0
last_report = time.monotonic()
while True:
data, peer = sock.recvfrom(65535)
if not peer[0] == SOURCE_IP:
print(f"ignored source={peer[0]}:{peer[1]} bytes={len(data)}", flush=True)
continue
if data.startswith(b"SHRED-FANOUT-VERIFY/1"):
print(data.decode("utf-8", errors="replace"), flush=True)
continue
stream_packets += 1
stream_bytes += len(data)
now = time.monotonic()
if now - last_report >= 1.0:
print(
f"source={peer[0]} stream_packets={stream_packets} "
f"stream_bytes={stream_bytes}",
flush=True,
)
stream_packets = 0
stream_bytes = 0
last_report = now
PYLeave this terminal running. The receive buffer setting asks the kernel for 8 MiB. The kernel may cap the effective buffer according to host policy. Changing that cap is an operating-system task and is not required to read the one verification datagram.
Register and verify the destination
- Open the paid destination in the dashboard.
- Enter the server's public IP address.
- Enter UDP port
9000. - Save the destination.
- Request the verification challenge.
- Read the line beginning with
${CHALLENGE_PREFIX}in the receiver terminal. - Copy the token from that datagram.
- Paste the token into the dashboard.
- Submit the token before ${CHALLENGE_TTL_SECONDS} seconds elapse.
- Keep the receiver running.
The datagram begins with the literal prefix ${CHALLENGE_PREFIX}, followed by the destination ID and token. The delimiter and exact field encoding after the prefix are not currently specified. Read the complete printable payload instead of using a parser that assumes spaces, colons, JSON, or line breaks.
The service sends one challenge datagram per request. UDP does not retransmit it. Request a resend in the dashboard when the receiver does not print the challenge or when the ${CHALLENGE_TTL_SECONDS} second window expires. Do not submit a token from an earlier request.
Confirm the stream
After the dashboard accepts the token, watch the existing receiver terminal. Stream datagrams from ${SOURCE_IP} should replace the single verification message. The exact activation delay is not currently specified.
Open a second terminal and observe counters without decoding payloads:
bash
sudo tcpdump -n -i any -c 20 'src host 64.130.40.90 and udp dst port 9000'The command exits after 20 matching datagrams. A healthy feed is measured at ${FEED.mbps} Mbps and ${FEED.packetsPerSecond.toLocaleString("en-US")} packets per second, with a ${FEED.meanPacketBytes} byte mean packet size. These are measured feed characteristics, not an ordering or delivery promise. Individual service datagrams can be as large as ${WIRE.maxPacketBytes} bytes.
Confirm that the Python stream counter reports ${SOURCE_IP} for accepted traffic. The UDP source port is not currently specified, so do not filter it. Filter the source IP, protocol, and your destination port.
Preserve the working configuration
The example ufw rule is managed by ufw. Persistence for iptables and nftables depends on the Linux distribution and is not currently specified by the product. Store the chosen rule through the host's normal firewall configuration after confirming delivery.
Keep the public IP and port stable. Changing either field counts as a destination address change and requires a new verification challenge. A destination permits three address changes per day.
Monitor receive errors, kernel UDP drops, process restarts, and firewall changes. Raw UDP supplies no retransmission, ordering, or backpressure. A slow or stopped receiver cannot ask the sender to replay missed packets. Plan sustained capacity for the published ${FEED.mbps} Mbps and ${FEED.packetsPerSecond.toLocaleString("en-US")} packets per second, plus environment-specific headroom. A required headroom percentage is not currently specified.
If no packet arrives
Run the tcpdump command while requesting a new challenge. If tcpdump sees nothing, check the public IP, cloud rule, host rule, NAT mapping, and dashboard port. If tcpdump sees the challenge but Python does not, another process may own the port or the receiver may be bound to a different interface. Use sudo ss -ulnp | grep ':9000 ' to inspect the binding.
Do not debug the shred decoder until the network path works. First prove that one datagram from ${SOURCE_IP} reaches the configured UDP socket. Then complete verification. Then count stream datagrams. Decode payloads only after those three checks pass.
Parameters
When it goes wrong
No challenge appears before the dashboard window closes. Example error: `verification timed out`.
Cause. UDP from 64.130.40.90 is blocked, the public IP or port is wrong, NAT does not forward the port, or no socket is bound.
Fix. Start the receiver, allow 64.130.40.90/32 through every firewall, confirm the mapping, and request a resend.
The receiver exits immediately. Example error: `OSError: [Errno 98] Address already in use`.
Cause. Another process already owns UDP port 9000 on the selected bind address.
Fix. Stop the conflicting process or choose a free UDP port, then update the receiver, firewall, NAT mapping, and dashboard together.
The token is rejected. Example error: `challenge expired`.
Cause. The token was submitted after 600 seconds or came from an earlier challenge.
Fix. Request a new challenge, copy its token from the current datagram, and submit it within the active window.
Verification completes but no stream packets appear. Example error: `receiver idle: 0 datagrams`.
Cause. The receiver, host firewall, or cloud rule no longer matches the verified destination port.
Fix. Compare the dashboard destination with the socket binding and every firewall rule, then restore the exact verified IP and port.
Questions
- Which address must the firewall allow?
- Allow inbound UDP from ${SOURCE_IP} to the exact destination port registered in the dashboard. The verification challenge and every stream datagram use that source IP. Do not filter on a source UDP port because the source port is not currently specified. Apply the rule at both cloud and host layers when both exist.
- What should I do when the challenge is lost?
- Keep the receiver bound, confirm that ${SOURCE_IP} is allowed, and request a resend from the dashboard. The service sends one challenge datagram per request, and UDP provides no retransmission. Submit the token from the new packet within ${CHALLENGE_TTL_SECONDS} seconds. Do not reuse a token from an expired request.
- How do I know the stream is reaching the server?
- Run tcpdump with a filter for source ${SOURCE_IP}, UDP, and the registered destination port. Then confirm the receiver's datagram counter advances. This separates network delivery from payload decoding. The measured feed is ${FEED.packetsPerSecond.toLocaleString("en-US")} packets per second, but an exact activation delay and peak rate are not currently specified.