You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/draft/timeout.md
+27-53Lines changed: 27 additions & 53 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@
4
4
5
5
The timeout feature uses a callback-based abstraction (similar to the lock feature) that allows platform-specific timer implementations without introducing OS dependencies in core wolfHSM code. A platform port provides a callback table implementing the timer operations, and the core timeout module delegates to these callbacks.
6
6
7
-
When creating a client, you provide a `whTimeoutConfig`specifying the platform callbacks, platform context, and an optional application-level expired callback:
7
+
The timeout lives in the comm layer. When creating a client, you provide a `whTimeoutConfig`in the `whCommClientConfig`:
During `wh_Client_Init`, the config is used to initialize an embedded `whTimeout respTimeout` inside the client context via `wh_Timeout_Init()`. This calls the platform `init` callback to set up timer resources but doesn't start any timer yet.
29
-
If `respTimeoutConfig` is NULL (or `cb` is NULL), the timeout is disabled and all operations become no-ops (timeout never expires).
34
+
During `wh_CommClient_Init`, the timeout is initialized via `wh_Timeout_Init()`. This calls the platform `init` callback to set up timer resources but doesn't start any timer yet.
35
+
If `respTimeoutConfig` is NULL (or `cb` is NULL), the timeout enters no-op mode and never expires.
30
36
31
-
## 2. What Happens During a Crypto Call
37
+
## 2. How the Timeout Works
32
38
33
-
Before the timeout feature, every crypto function in `wh_client_crypto.c` had this pattern after sending a request:
34
-
```c
35
-
/* Old pattern -- infinite busy-wait */
36
-
do {
37
-
ret = wh_Client_RecvResponse(ctx, &group, &action, &res_len, dataPtr);
38
-
} while (ret == WH_ERROR_NOTREADY);
39
-
```
39
+
The timeout is handled transparently in the comm layer:
40
40
41
-
If the server never responded, the client would spin forever.
42
-
This is replaced with a single helper `_recvCryptoResponse()` (`src/wh_client_crypto.c`):
ret = wh_Client_RecvResponseBlockingWithTimeout(ctx, group, action,
51
-
size, data);
52
-
#else
53
-
do {
54
-
ret = wh_Client_RecvResponse(ctx, group, action, size, data);
55
-
} while (ret == WH_ERROR_NOTREADY);
56
-
#endif
57
-
return ret;
58
-
}
59
-
```
41
+
1. **`wh_CommClient_SendRequest`**: After a successful send, starts the response timer via `wh_Timeout_Start()`.
42
+
2. **`wh_CommClient_RecvResponse`**: When the transport returns `WH_ERROR_NOTREADY`, checks `wh_Timeout_Expired()`. If expired, returns `WH_ERROR_TIMEOUT`. On successful receive, stops the timer via `wh_Timeout_Stop()`.
43
+
44
+
This means every `do { ... } while (ret == WH_ERROR_NOTREADY)` loop in the codebase automatically gets timeout support -- crypto, NVM, keystore, cert, SHE, keywrap, and all other client operations.
60
45
61
-
When timeout is enabled, it delegates to `wh_Client_RecvResponseBlockingWithTimeout`. When disabled, the old infinite-loop behavior is preserved.
62
-
63
-
## 3. The Timeout Receive Loop
64
-
`wh_Client_RecvResponseBlockingWithTimeout` (`src/wh_client.c`) does this:
65
-
1. **Starts the timer** -- calls `wh_Timeout_Start()` which delegates to the platform `start` callback (e.g. captures the current time).
66
-
2. **Polls for a response** -- calls `wh_Client_RecvResponse()` in a loop.
67
-
3. **On each `WH_ERROR_NOTREADY`**, checks `wh_Timeout_Expired()`:
68
-
- Delegates to the platform `expired` callback to check elapsed time
69
-
- If expired: invokes the application `expiredCb` (if set), then returns `WH_ERROR_TIMEOUT`
70
-
- If not expired: loops again
71
-
4. **On any other return value** (success or error), returns immediately.
From the application's perspective, the crypto APIs (`wh_Client_AesCbc`, `wh_Client_RsaFunction`, `wh_Client_EccSign`, etc.) now return `WH_ERROR_TIMEOUT` (-2010) instead of hanging indefinitely. The application can then decide how to handle it -- retry, log, fail gracefully, etc.
63
+
## 3. What the Client Sees
64
+
65
+
From the application's perspective, any client API that waits for a server response can now return `WH_ERROR_TIMEOUT` (-2010) instead of hanging indefinitely. The application can then decide how to handle it -- retry, log, fail gracefully, etc.
91
66
The `expiredCb` fires *before* the error is returned, so you can use it for logging or cleanup without needing to check the return code first.
92
67
93
-
## 5. Overriding Expiration via the Callback
68
+
## 4. Overriding Expiration via the Callback
94
69
95
70
The application expired callback receives a pointer to the `isExpired` flag and can override it by setting `*isExpired = 0`. This suppresses the expiration for the current check, allowing the polling loop to continue. A common use case is to extend the timeout deadline: clear the flag, then call `wh_Timeout_Start()` to restart the timer.
-**Only crypto responses are covered.** Non-crypto client calls (key management, NVM operations, comm init) still use the old infinite-wait pattern. The timeout is specifically wired into `_recvCryptoResponse`.
135
-
-**The timeout is per-client, not per-call.** All crypto operations for a given client share the same `respTimeout` context with the same duration. You can call `wh_Timeout_Set()` to change the duration between calls, but there's no per-operation override.
107
+
## 5. Design Notes
108
+
-**The timeout is per-comm-client, not per-call.** All operations for a given client share the same `respTimeout` context with the same duration. You can call `wh_Timeout_Set()` to change the duration between calls, but there's no per-operation override.
109
+
-**Timer starts on send, checks on receive.** The timer window begins when a request is successfully sent, measuring the full round-trip wait.
0 commit comments