Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
Sichere ProgrammierungRefreshed repository pull requests page generally available(22.09.2026 um 03:25 Uhr)
Sichere ProgrammierungThe Joy of Learning the Basics Again(22.09.2026 um 03:28 Uhr)
Sichere ProgrammierungZero-Code OpenTelemetry Tracing for Dagster(22.09.2026 um 03:39 Uhr)
Linux Tipps & Hardening`prime-all`(22.09.2026 um 02:28 Uhr)
IT Security Toolsopensoho v0.15.2(22.09.2026 um 03:33 Uhr)
IT Security NachrichtenUS Proposes AI Incident Alert System in Talks With China, Bessent Says(22.09.2026 um 04:01 Uhr)
Sichere ProgrammierungRefreshed repository pull requests page generally available(22.09.2026 um 03:25 Uhr)
Sichere ProgrammierungThe Joy of Learning the Basics Again(22.09.2026 um 03:28 Uhr)
Sichere ProgrammierungZero-Code OpenTelemetry Tracing for Dagster(22.09.2026 um 03:39 Uhr)
Linux Tipps & Hardening`prime-all`(22.09.2026 um 02:28 Uhr)
IT Security Toolsopensoho v0.15.2(22.09.2026 um 03:33 Uhr)
IT Security NachrichtenUS Proposes AI Incident Alert System in Talks With China, Bessent Says(22.09.2026 um 04:01 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Building a UDP-based API

In my last post I introduced the concept of treating UDP network packets as a serverless event source. In this post I explore building a UDP-based application programming interfaces (APIs) with a request-response model. …

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

In my last post I introduced the concept of treating UDP network packets as a serverless event source. In this post I explore building a UDP-based application programming interfaces (APIs) with a request-response model.






Background



The modern web is brim-full of HTTP APIs, and we have excellent tooling to simplify and de-risk building them.



The simplicity means we don't need to write network stacks, web servers or parsers: we get them as part of the library or platform. Writing an HTTP server is as simple as:




from http.server import HTTPServer, BaseHTTPRequestHandler

class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b"OK")

HTTPServer(("", 8080), Handler).serve_forever()






If we want to get even simpler, we can use API Gateway and write a Lambda function to avoid paying for an idle container or instance to run our server. In that case the handler may be something like:




def handler(event, context):
return {
"statusCode": 200,
"body": "OK"
}






With this approach we have no costs for reserved capacity and no infrastructure to manage. This is what I mean by de-risking: We can build such APIs all day long and pay only when (if) they're actually used. Use rate limiting and WAF for abuse protection and reduce the risk even further.



What about UDP then?






A UDP API



A server for a UDP API is very similar. We're going to write it to listen for incoming packets on any port to keep with the example from the previous article.



In this case we want to support responses as an API should. We can't use EventBridge since it has a write-only API (responses relate to the success of the write; nothing custom).



So we're going to use Lambda instead and send what it returns as the response:




import socket
import struct
import boto3
import json
import base64

raw_sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
lambda_client = boto3.client("lambda")
reply_socks = {}

while True:
data, addr = raw_sock.recvfrom(65535)

ip_header_len = (data[0] & 0x0F) * 4
src_port, dst_port = struct.unpack('!HH', data[ip_header_len:ip_header_len + 4])
payload = data[ip_header_len + 8:]
src_ip = addr[0]

response = lambda_client.invoke(
FunctionName="my-function",
Payload=json.dumps({
"Port": dst_port,
"Data": base64.b64encode(payload).decode()
}),
)
reply = json.loads(response["Payload"].read())

if reply:
if dst_port not in reply_socks:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("", dst_port))
reply_socks[dst_port] = s

reply_socks[dst_port].sendto(reply.encode(), (src_ip, src_port))






Note that we're keeping a map of reply sockets to ensure that our replies appear to be "from" the same port the incoming packet has as the destination (the bind() call locks the socket to sending from a single port). If we didn't do this our replies would probably be ignored (or blocked by a firewall) since the client expects to have a two-way conversation with the given server port.



Now we can implement my-function however we'd like, including port-specific handling:




import json

def handler(event, context):
if event.get("Port") == 4321:
return "OK"






But we really want a more "API Gateway like" experience, and we can get there. The Constrained Application Protocol (CoAP) is the UDP-based cousin of HTTP. It has paths, methods, etc. and the basis for good general purpose UDP APIs.



So let's add support for CoAP to the server:




import socket
import struct
import boto3
import json
import base64
from aiocoap import Message, ACK, CONTENT

raw_sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
lambda_client = boto3.client("lambda")
reply_socks = {}

ROUTES = {
4321: {"function": "my-function", "protocol": "raw"},
5678: {"function": "coap-function", "protocol": "coap"},
}

def parse_coap(data):
msg = Message.decode(data)
return {
"code": str(msg.code),
"message_id": msg.mid,
"token": base64.b64encode(msg.token).decode(),
"path": "/" + "/".join(msg.opt.uri_path),
"payload": base64.b64encode(msg.payload).decode(),
}

def build_coap_ack(coap, body):
return Message(
mtype=ACK,
code=CONTENT,
mid=coap["message_id"],
token=base64.b64decode(coap["token"]),
payload=body.encode()
).encode()

while True:
data, addr = raw_sock.recvfrom(65535)
ip_header_len = (data[0] & 0x0F) * 4
src_port, dst_port = struct.unpack('!HH', data[ip_header_len:ip_header_len + 4])
payload = data[ip_header_len + 8:]
src_ip = addr[0]

route = ROUTES.get(dst_port)
if not route:
continue

if route["protocol"] == "coap":
coap = parse_coap(payload)
lambda_payload = json.dumps(coap)
else:
lambda_payload = json.dumps({"Port": dst_port, "Data": base64.b64encode(payload).decode()})

response = lambda_client.invoke(FunctionName=route["function"], Payload=lambda_payload)
reply = json.loads(response["Payload"].read())

if reply:
if dst_port not in reply_socks:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("", dst_port))
reply_socks[dst_port] = s

packet = build_coap_ack(coap, reply) if route["protocol"] == "coap" else reply.encode()
reply_socks[dst_port].sendto(packet, (src_ip, src_port))






In reality the configuration would be external to the server, but we're keeping things simple here. To add a new CoAP API endpoint we can just add to the configuration. To implement a CoAP handler, we build a simple Lambda that just processes the JSON object payload.



For example, here is a Lambda implementing a "time" service:




import datetime

def handler(event, context):
if event.get("path") == "/time":
return datetime.datetime.now().isoformat()






Adding more paths and methods to the Lambda will feel very much like building an HTTP handler.






Summary



This is the start of an interesting architecture that decouples network listening and replies from handling the packet data:




  • We can add new paths and methods to the CoAP Lambda without touching the server at all.

  • We can add new ports and custom protocols to the server in a clean, configuration driven way.

  • Using CoAP, we're within sight of the simplicity of the tooling for HTTP but lack the ease of configuration and features.

  • We're running a server, and hence haven't really de-risked as much as we'd like.



To that last point, we can't quite match API Gateway approach (there is no AWS service that supports UDP in this way, but Proxylity does).

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Building a UDP-based API

Thematisch verwandte Begriffe: Building, UDPbased · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-49449 | Joplin is an open source note-taking and to-do application that organise…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick