cwist
Modern C web framework with libttak runtime
Loading...
Searching...
No Matches
lwip.h File Reference

Serve a CWIST app over lwIP's raw TCP API (issue #447 Phase 3). More...

#include <cwist/sys/app/app.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
Include dependency graph for lwip.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  cwist_lwip_config
 Listener settings; start from cwist_lwip_config_init(). More...
 

Typedefs

typedef struct cwist_lwip_config cwist_lwip_config
 Listener settings; start from cwist_lwip_config_init().
 
typedef struct cwist_lwip_tls cwist_lwip_tls
 Opaque TLS server context: certificate chain, key, DRBG and mbedTLS config.
 
typedef struct cwist_lwip_server cwist_lwip_server
 Opaque listener handle returned by cwist_lwip_listen().
 

Functions

void cwist_lwip_config_init (cwist_lwip_config *cfg)
 Fill cfg with the defaults documented on cwist_lwip_config.
 
cwist_lwip_server * cwist_lwip_listen (cwist_app *app, const cwist_lwip_config *cfg)
 Bind a listening tcp_pcb on cfg->port (any address) and serve app on it.
 
void cwist_lwip_close (cwist_lwip_server *srv)
 Stop listening and abort every open connection, then free srv.
 
size_t cwist_lwip_active_connections (const cwist_lwip_server *srv)
 Number of connections the server currently holds open.
 
cwist_lwip_tls * cwist_lwip_tls_create (const unsigned char *cert, size_t cert_len, const unsigned char *key, size_t key_len)
 Create a TLS server context from a certificate chain and private key.
 
void cwist_lwip_tls_destroy (cwist_lwip_tls *tls)
 Free a TLS context. Close every server using it first.
 

Detailed Description

Serve a CWIST app over lwIP's raw TCP API (issue #447 Phase 3).

For targets without BSD sockets (bare metal, or an RTOS running lwIP in NO_SYS / tcpip-thread mode): the adapter owns a listening tcp_pcb, frames HTTP/1.1 requests out of the received pbufs, runs them through the app's router and middleware (cwist_app_dispatch), and streams the serialized response back with tcp_write/tcp_sent back-pressure.

Build: compile src/sys/port/lwip.c into the firmware next to lwIP, with the firmware's lwipopts.h on the include path (the adapter depends on its TCP options). It needs LWIP_TCP and LWIP_CALLBACK_API, and uses only the raw API, so it works under NO_SYS=1. With SO_REUSE=1 the listener sets SOF_REUSEADDR, so it can be re-created while closed connections sit in TIME_WAIT.

Context: every call here, and every callback the adapter installs, runs in lwIP's core context: the main loop for NO_SYS=1, the tcpip thread otherwise (wrap calls in tcpip_callback()). Handlers therefore run there too; keep them short.

Behaviour:

  • Request bodies are framed by Content-Length. Transfer-Encoding is answered with 501, Content-Length together with Transfer-Encoding or an invalid/conflicting Content-Length with 400, an oversized header block with 431 and an oversized body with 413; the connection then closes.
  • Expect: 100-continue gets an interim 100 before the body is read.
  • Keep-alive follows the request and the response (as on the socket path); pipelined requests are answered in order, one at a time.
  • Responses are sent zero-copy from the serialized buffer, which is released once the peer has acknowledged it.
  • Received data beyond the request limits is refused back to lwIP while a response is in flight, so the TCP window throttles the peer.
  • Connections idle longer than idle_timeout_ms, or beyond max_conns at accept time, are closed (the latter aborted).
  • Deferred (cwist_async) and upgraded (WebSocket) responses are not supported here.

TLS (issue #447 Phase 4): build lwip.c with -DCWIST_LWIP_TLS and link mbedTLS 3.6 (TLS 1.2 server, X.509, PK parse, CTR_DRBG), then set cfg.tls to a context from cwist_lwip_tls_create(). The adapter drives mbedTLS itself over the pcb (lwIP's altcp_tls_mbedtls only supports mbedTLS 2.x). The DRBG is seeded from cwist_port_entropy(); a failing hook makes cwist_lwip_tls_create() fail rather than run unseeded. Ciphertext goes out with TCP_WRITE_FLAG_COPY. Each TLS connection costs one mbedtls_ssl_context plus MBEDTLS_SSL_IN_CONTENT_LEN and MBEDTLS_SSL_OUT_CONTENT_LEN record buffers. A failed handshake aborts the connection. Without CWIST_LWIP_TLS, cwist_lwip_tls_create() returns NULL and the adapter serves plaintext only.

Definition in file lwip.h.

Typedef Documentation

◆ cwist_lwip_config

◆ cwist_lwip_server

typedef struct cwist_lwip_server cwist_lwip_server

Opaque listener handle returned by cwist_lwip_listen().

Definition at line 81 of file lwip.h.

◆ cwist_lwip_tls

Opaque TLS server context: certificate chain, key, DRBG and mbedTLS config.

Definition at line 78 of file lwip.h.

Function Documentation

◆ cwist_lwip_active_connections()

size_t cwist_lwip_active_connections ( const cwist_lwip_server *  srv)

Number of connections the server currently holds open.

Parameters
srvServer handle.
Returns
Open connection count (0 for NULL).

Definition at line 791 of file lwip.c.

◆ cwist_lwip_close()

void cwist_lwip_close ( cwist_lwip_server *  srv)

Stop listening and abort every open connection, then free srv.

Parameters
srvServer returned by cwist_lwip_listen(); NULL is a no-op.

Stop listening and abort every open connection, then free srv.

Parameters
srvServer returned by cwist_lwip_listen(); NULL is a no-op.

Definition at line 774 of file lwip.c.

References cap, and cwist_free().

◆ cwist_lwip_config_init()

void cwist_lwip_config_init ( cwist_lwip_config *  cfg)

◆ cwist_lwip_listen()

cwist_lwip_server * cwist_lwip_listen ( cwist_app *  app,
const cwist_lwip_config *  cfg 
)

Bind a listening tcp_pcb on cfg->port (any address) and serve app on it.

Parameters
appApplication to dispatch to; must outlive the server.
cfgSettings, copied; NULL means the defaults.
Returns
Server handle, or NULL when the pcb cannot be created, bound or put into the listen state, or on allocation failure.

Bind a listening tcp_pcb on cfg->port (any address) and serve app on it.

Parameters
appApplication to dispatch to; must outlive the server.
cfgSettings, copied; NULL means the defaults.
Returns
Server handle, or NULL on pcb or allocation failure.

Definition at line 729 of file lwip.c.

References cap, cwist_alloc(), cwist_free(), and cwist_lwip_config_init().

◆ cwist_lwip_tls_create()

cwist_lwip_tls * cwist_lwip_tls_create ( const unsigned char *  cert,
size_t  cert_len,
const unsigned char *  key,
size_t  key_len 
)

Create a TLS server context from a certificate chain and private key.

PEM input must be NUL-terminated and cert_len / key_len must count the NUL (mbedTLS's PEM rule: pass sizeof() of a string literal); DER input is passed as is. The context may be shared by several servers and must outlive every server that uses it.

Parameters
certCertificate chain, leaf first (PEM or DER).
cert_lenLength of cert.
keyPrivate key matching the leaf certificate (PEM or DER, unencrypted).
key_lenLength of key.
Returns
Context, or NULL when parsing fails, the key does not match the certificate, cwist_port_entropy() fails while seeding the DRBG, memory runs out, or lwip.c was built without CWIST_LWIP_TLS.
Parameters
certCertificate chain, leaf first (PEM with its NUL counted, or DER).
cert_lenLength of cert.
keyMatching private key (PEM with its NUL counted, or DER).
key_lenLength of key.
Returns
Context, or NULL on parse/pairing/seeding/allocation failure or when built without CWIST_LWIP_TLS.

Definition at line 804 of file lwip.c.

References cap, cwist_alloc(), and cwist_lwip_tls_destroy().

◆ cwist_lwip_tls_destroy()

void cwist_lwip_tls_destroy ( cwist_lwip_tls *  tls)

Free a TLS context. Close every server using it first.

Parameters
tlsContext from cwist_lwip_tls_create(); NULL is a no-op.

Free a TLS context. Close every server using it first.

Parameters
tlsContext from cwist_lwip_tls_create(); NULL is a no-op.

Definition at line 841 of file lwip.c.

References cap, and cwist_free().

Referenced by cwist_lwip_tls_create().