Python / RPC
Out-of-process campaign control over a Unix-domain socket — live steering without recompilation.
The scripting surface exposes a control plane so an operator or Python client can inject seeds, swap protocol models, attach a live is_interesting oracle, change integrity/encryptor strategies, and push mutator dictionary extras — all while the campaign is running.
src/scripting/ — RpcServer, bridges (protocol / integrity / encryptor / mutator / oracle), pure-stdlib JSON. Activated via -Y / NEXSIZ_RPC_SOCK.
Activation
nexsiz -h 127.0.0.1 -p 21 -m ftp -Y /tmp/nexsiz.sock -v
# or
export NEXSIZ_RPC_SOCK=/tmp/nexsiz.sock
nexsiz -h 127.0.0.1 -p 21 -m ftp -v
Unix only. On non-Unix platforms RpcServer::start returns an explicit error; the rest of the fuzzer remains fully usable.
Capabilities
| Bridge | What you can push |
|---|---|
| Protocol | Live ProtocolModel store (JSON model or name) |
| Integrity | Strategy name → repairer factory |
| Encryptor | Name + key → encryptor factory |
| Mutator | Extra dictionary tokens + generation counter |
| Oracle | Register as live Python oracle (reverse-RPC is_interesting) |
| Seeds | Structured JSON seed → TestCase |
Transport & concurrency
- Line-delimited JSON over a Unix-domain socket.
- One accept thread (
nexsiz-rpc) + one short-lived client thread per connection. - Non-blocking accept, 50 ms poll, read/write timeouts prevent a stalled client from blocking the surface.
- Hot path (mutate → repair → encrypt → send) never performs reverse-RPC except the optional oracle query (bounded timeout).
- All plugin injection is push-style; workers re-resolve on the next cycle via generation or name comparison.
Oracle mode (reverse-RPC)
After a successful register_oracle the connection leaves the normal request/response path:
- Engine pushes
is_interestingrequests to the Python client. - Python answers with a boolean (or structured result).
- On disconnect / timeout / stop flag the bridge unregisters and the default oracle is restored.
Design invariants
- Zero behaviour change when the RPC socket is not configured.
- The server never owns campaign logic — pure transport + mode switcher that delegates to
RpcContextand the bridges. - Socket path is removed on
Drop; cooperative shutdown shares the sameAtomicBoolused by workers and the Engine.
Reference client: python/nexsiz_client.py (shipped with the source tree). Use it as the starting point for custom steering scripts.