Skip to content

Commit c5756f8

Browse files
Add ability to configure TCP keepalive (#232)
feat(tcp-keepalive): add ability to configure TCP keepalive Provide interfaces (`pubnub_use_tcp_keep_alive`, `pubnub_dont_use_tcp_keep_alive`, `use_tcp_keep_alive`, and `dont_use_tcp_keep_alive`) to set up active TCP connection keep-alive packet sending. fix(dns): fix crash on Windows system DNS Replace the Windows API, which in a multithreaded environment became a reason for crashes during the DNS resolution process. --------- Co-authored-by: Kamil Gronek <[email protected]>
1 parent 00d33f4 commit c5756f8

20 files changed

+402
-76
lines changed

.github/workflows/commands-handler.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ jobs:
2424
run: echo -e "\033[38;2;19;181;255mThis is regular commit which should be ignored.\033[0m"
2525
- name: Checkout repository
2626
if: steps.user-check.outputs.expected-user == 'true'
27-
uses: actions/checkout@v4
27+
uses: actions/checkout@v5
2828
with:
2929
token: ${{ secrets.GH_TOKEN }}
3030
- name: Checkout release actions
3131
if: steps.user-check.outputs.expected-user == 'true'
32-
uses: actions/checkout@v4
32+
uses: actions/checkout@v5
3333
with:
3434
repository: pubnub/client-engineering-deployment-tools
3535
ref: v1

.github/workflows/composite/unit-test-framework/action.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ runs:
2727
${{ inputs.os }}-cgreen-${{ inputs.version }}-
2828
- name: Checkout Unit Test framework
2929
if: steps.unit-test-framework.outputs.cache-hit != 'true'
30-
uses: actions/checkout@v4
30+
uses: actions/checkout@v5
3131
with:
3232
repository: cgreen-devs/cgreen
3333
ref: ${{ matrix.cgreen }}

.github/workflows/release.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
release: ${{ steps.check.outputs.ready }}
1616
steps:
1717
- name: Checkout actions
18-
uses: actions/checkout@v4
18+
uses: actions/checkout@v5
1919
with:
2020
repository: pubnub/client-engineering-deployment-tools
2121
ref: v1
@@ -34,13 +34,13 @@ jobs:
3434
group: organization/Default
3535
steps:
3636
- name: Checkout repository
37-
uses: actions/checkout@v4
37+
uses: actions/checkout@v5
3838
with:
3939
# This should be the same as the one specified for on.pull_request.branches
4040
ref: master
4141
token: ${{ secrets.GH_TOKEN }}
4242
- name: Checkout actions
43-
uses: actions/checkout@v4
43+
uses: actions/checkout@v5
4444
with:
4545
repository: pubnub/client-engineering-deployment-tools
4646
ref: v1

.github/workflows/run-tests.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ jobs:
2525
# group: organization/macos-gh
2626
steps:
2727
- name: Checkout project
28-
uses: actions/checkout@v4
28+
uses: actions/checkout@v5
2929
with:
3030
token: ${{ secrets.GH_TOKEN }}
3131
- name: Checkout actions
32-
uses: actions/checkout@v4
32+
uses: actions/checkout@v5
3333
with:
3434
repository: pubnub/client-engineering-deployment-tools
3535
ref: v1
@@ -59,11 +59,11 @@ jobs:
5959
sudo apt-get install -y ninja-build libboost-all-dev libssl-dev libgtest-dev nlohmann-json3-dev libasio-dev libtclap-dev g++ cmake
6060
sudo gem install cucumber
6161
- name: Checkout project
62-
uses: actions/checkout@v4
62+
uses: actions/checkout@v5
6363
with:
6464
token: ${{ secrets.GH_TOKEN }}
6565
- name: Checkout mock-server action
66-
uses: actions/checkout@v4
66+
uses: actions/checkout@v5
6767
with:
6868
repository: pubnub/client-engineering-deployment-tools
6969
ref: v1
@@ -84,7 +84,7 @@ jobs:
8484
${{ runner.os }}-cucumber-cpp-
8585
- name: Checkout Cucumber
8686
if: steps.cucumber-cpp.outputs.cache-hit != 'true'
87-
uses: actions/checkout@v4
87+
uses: actions/checkout@v5
8888
with:
8989
repository: cucumber/cucumber-cpp
9090
ref: c79100eb70fbb34f6ea10030cec051c2cc9f7961

.github/workflows/run-validations.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ jobs:
99
group: organization/Default
1010
steps:
1111
- name: Checkout project
12-
uses: actions/checkout@v4
12+
uses: actions/checkout@v5
1313
- name: Checkout validator action
14-
uses: actions/checkout@v4
14+
uses: actions/checkout@v5
1515
with:
1616
repository: pubnub/client-engineering-deployment-tools
1717
ref: v1

.pubnub.yml

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
11
name: c-core
22
schema: 1
3-
version: "5.3.2"
3+
version: "5.4.0"
44
scm: github.com/pubnub/c-core
55
changelog:
6+
- date: 2025-10-21
7+
version: v5.4.0
8+
changes:
9+
- type: feature
10+
text: "Provide interfaces (`pubnub_use_tcp_keep_alive`, `pubnub_dont_use_tcp_keep_alive`, `use_tcp_keep_alive`, and `dont_use_tcp_keep_alive`) to set up active TCP connection keep-alive packet sending."
11+
- type: bug
12+
text: "Replace the Windows API, which in a multithreaded environment became a reason for crashes during the DNS resolution process."
13+
- type: bug
14+
text: "Fix the issue because of which client created a secondary connection when built with `PUBNUB_USE_IPV6` support."
615
- date: 2025-09-23
716
version: v5.3.2
817
changes:
@@ -1036,7 +1045,7 @@ sdks:
10361045
distribution-type: source code
10371046
distribution-repository: GitHub release
10381047
package-name: C-Core
1039-
location: https://github.com/pubnub/c-core/releases/tag/v5.3.2
1048+
location: https://github.com/pubnub/c-core/releases/tag/v5.4.0
10401049
requires:
10411050
-
10421051
name: "miniz"
@@ -1102,7 +1111,7 @@ sdks:
11021111
distribution-type: source code
11031112
distribution-repository: GitHub release
11041113
package-name: C-Core
1105-
location: https://github.com/pubnub/c-core/releases/tag/v5.3.2
1114+
location: https://github.com/pubnub/c-core/releases/tag/v5.4.0
11061115
requires:
11071116
-
11081117
name: "miniz"
@@ -1168,7 +1177,7 @@ sdks:
11681177
distribution-type: source code
11691178
distribution-repository: GitHub release
11701179
package-name: C-Core
1171-
location: https://github.com/pubnub/c-core/releases/tag/v5.3.2
1180+
location: https://github.com/pubnub/c-core/releases/tag/v5.4.0
11721181
requires:
11731182
-
11741183
name: "miniz"
@@ -1230,7 +1239,7 @@ sdks:
12301239
distribution-type: source code
12311240
distribution-repository: GitHub release
12321241
package-name: C-Core
1233-
location: https://github.com/pubnub/c-core/releases/tag/v5.3.2
1242+
location: https://github.com/pubnub/c-core/releases/tag/v5.4.0
12341243
requires:
12351244
-
12361245
name: "miniz"
@@ -1291,7 +1300,7 @@ sdks:
12911300
distribution-type: source code
12921301
distribution-repository: GitHub release
12931302
package-name: C-Core
1294-
location: https://github.com/pubnub/c-core/releases/tag/v5.3.2
1303+
location: https://github.com/pubnub/c-core/releases/tag/v5.4.0
12951304
requires:
12961305
-
12971306
name: "miniz"
@@ -1347,7 +1356,7 @@ sdks:
13471356
distribution-type: source code
13481357
distribution-repository: GitHub release
13491358
package-name: C-Core
1350-
location: https://github.com/pubnub/c-core/releases/tag/v5.3.2
1359+
location: https://github.com/pubnub/c-core/releases/tag/v5.4.0
13511360
requires:
13521361
-
13531362
name: "miniz"
@@ -1400,7 +1409,7 @@ sdks:
14001409
distribution-type: source code
14011410
distribution-repository: GitHub release
14021411
package-name: C-Core
1403-
location: https://github.com/pubnub/c-core/releases/tag/v5.3.2
1412+
location: https://github.com/pubnub/c-core/releases/tag/v5.4.0
14041413
requires:
14051414
-
14061415
name: "miniz"

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## v5.4.0
2+
October 21 2025
3+
4+
#### Added
5+
- Provide interfaces (`pubnub_use_tcp_keep_alive`, `pubnub_dont_use_tcp_keep_alive`, `use_tcp_keep_alive`, and `dont_use_tcp_keep_alive`) to set up active TCP connection keep-alive packet sending.
6+
7+
#### Fixed
8+
- Replace the Windows API, which in a multithreaded environment became a reason for crashes during the DNS resolution process.
9+
- Fix the issue because of which client created a secondary connection when built with `PUBNUB_USE_IPV6` support.
10+
111
## v5.3.2
212
September 23 2025
313

core/pbauto_heartbeat.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ static int copy_context_settings(pubnub_t* pb_clone, pubnub_t const* pb)
9898
pb_clone->origin = pb->origin;
9999
}
100100
pb_clone->options.use_http_keep_alive = pb->options.use_http_keep_alive;
101+
pb_clone->options.tcp_keepalive.enabled = pb->options.tcp_keepalive.enabled;
102+
pb_clone->options.tcp_keepalive.time = pb->options.tcp_keepalive.time;
103+
pb_clone->options.tcp_keepalive.interval = pb->options.tcp_keepalive.interval;
104+
pb_clone->options.tcp_keepalive.probes = pb->options.tcp_keepalive.probes;
101105
#if PUBNUB_USE_IPV6 && defined(PUBNUB_CALLBACK_API)
102106
pb_clone->options.ipv6_connectivity = pb->options.ipv6_connectivity;
103107
#endif
@@ -252,6 +256,14 @@ static void auto_heartbeat_callback(pubnub_t* heartbeat_pb,
252256
if (pubsub_keys_changed(heartbeat_pb, pb)) {
253257
pubnub_init(
254258
heartbeat_pb, pb->core.publish_key, pb->core.subscribe_key);
259+
if (pbccTrue == pb->options.tcp_keepalive.enabled) {
260+
pubnub_use_tcp_keep_alive(
261+
heartbeat_pb,
262+
pb->options.tcp_keepalive.time,
263+
pb->options.tcp_keepalive.interval,
264+
pb->options.tcp_keepalive.probes);
265+
} else if (pbccFalse == pb->options.tcp_keepalive.enabled)
266+
pubnub_dont_use_tcp_keep_alive(heartbeat_pb);
255267

256268
heartbeat_thump(pb, heartbeat_pb);
257269
}
@@ -275,6 +287,14 @@ static pubnub_t* init_new_thumper_pb(pubnub_t* pb, unsigned i)
275287
}
276288
pubnub_mutex_lock(pb->monitor);
277289
pubnub_init(pb_new, pb->core.publish_key, pb->core.subscribe_key);
290+
if (pbccTrue == pb->options.tcp_keepalive.enabled) {
291+
pubnub_use_tcp_keep_alive(
292+
pb_new,
293+
pb->options.tcp_keepalive.time,
294+
pb->options.tcp_keepalive.interval,
295+
pb->options.tcp_keepalive.probes);
296+
} else if (pbccFalse == pb->options.tcp_keepalive.enabled)
297+
pubnub_dont_use_tcp_keep_alive(pb_new);
278298
pubnub_mutex_unlock(pb->monitor);
279299

280300
pubnub_mutex_lock(pb_new->monitor);

core/pbpal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,9 @@ int pbpal_close(pubnub_t *pb);
251251
/** Sets blocking I/O option on the context for the communication */
252252
int pbpal_set_blocking_io(pubnub_t *pb);
253253

254+
/** Sets user-provided TCP Keep-Alive configuration for active connection. */
255+
void pbpal_set_tcp_keepalive(const pubnub_t *pb);
256+
254257
/** Frees-up any resources allocated by the PAL for the given
255258
context. After this call, context is not safe for use by PAL any
256259
more (it is assumed it will be freed-up by the caller).

core/pubnub_internal_common.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,27 @@ struct pbntlm_context {
197197

198198
typedef struct pbntlm_context pbntlm_ctx_t;
199199

200+
/** TCP Keep-Alive configuration object. */
201+
typedef struct pubnub_tcp_keepalive_ {
202+
/** Whether TCP Keep-Alive should be used or not. */
203+
enum pubnub_tribool enabled;
204+
205+
/** The time in seconds a socket needs to be @c idle before the first
206+
keep-alive probe is sent.
207+
*/
208+
uint8_t time;
209+
210+
/** The number of seconds that should pass between sends of
211+
keep-alive probes if the last one wasn't acknowledged.
212+
*/
213+
uint8_t interval;
214+
215+
/** The number of times a probe will be sent and not acknowledged
216+
before the connection is deemed broken.
217+
*/
218+
uint8_t probes;
219+
} pubnub_tcp_keepalive;
220+
200221
struct pubnub_options {
201222
#if PUBNUB_BLOCKING_IO_SETTABLE
202223
/** Indicates whether to use blocking I/O. Not implemented if
@@ -214,6 +235,9 @@ struct pubnub_options {
214235
*/
215236
bool use_http_keep_alive : 1;
216237

238+
/** Per-context (because of one request per-context) TCP Keep-Alive
239+
configuration. */
240+
pubnub_tcp_keepalive tcp_keepalive;
217241
#if PUBNUB_USE_IPV6
218242
/* Connectivity type(true-Ipv6/false-Ipv4) chosen on a given context */
219243
bool ipv6_connectivity : 1;

0 commit comments

Comments
 (0)