Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/commands-handler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ jobs:
run: echo -e "\033[38;2;19;181;255mThis is regular commit which should be ignored.\033[0m"
- name: Checkout repository
if: steps.user-check.outputs.expected-user == 'true'
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
token: ${{ secrets.GH_TOKEN }}
- name: Checkout release actions
if: steps.user-check.outputs.expected-user == 'true'
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
repository: pubnub/client-engineering-deployment-tools
ref: v1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ runs:
${{ inputs.os }}-cgreen-${{ inputs.version }}-
- name: Checkout Unit Test framework
if: steps.unit-test-framework.outputs.cache-hit != 'true'
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
repository: cgreen-devs/cgreen
ref: ${{ matrix.cgreen }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
release: ${{ steps.check.outputs.ready }}
steps:
- name: Checkout actions
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
repository: pubnub/client-engineering-deployment-tools
ref: v1
Expand All @@ -34,13 +34,13 @@ jobs:
group: organization/Default
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
# This should be the same as the one specified for on.pull_request.branches
ref: master
token: ${{ secrets.GH_TOKEN }}
- name: Checkout actions
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
repository: pubnub/client-engineering-deployment-tools
ref: v1
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ jobs:
# group: organization/macos-gh
steps:
- name: Checkout project
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
token: ${{ secrets.GH_TOKEN }}
- name: Checkout actions
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
repository: pubnub/client-engineering-deployment-tools
ref: v1
Expand Down Expand Up @@ -59,11 +59,11 @@ jobs:
sudo apt-get install -y ninja-build libboost-all-dev libssl-dev libgtest-dev nlohmann-json3-dev libasio-dev libtclap-dev g++ cmake
sudo gem install cucumber
- name: Checkout project
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
token: ${{ secrets.GH_TOKEN }}
- name: Checkout mock-server action
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
repository: pubnub/client-engineering-deployment-tools
ref: v1
Expand All @@ -84,7 +84,7 @@ jobs:
${{ runner.os }}-cucumber-cpp-
- name: Checkout Cucumber
if: steps.cucumber-cpp.outputs.cache-hit != 'true'
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
repository: cucumber/cucumber-cpp
ref: c79100eb70fbb34f6ea10030cec051c2cc9f7961
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/run-validations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ jobs:
group: organization/Default
steps:
- name: Checkout project
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Checkout validator action
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
repository: pubnub/client-engineering-deployment-tools
ref: v1
Expand Down
25 changes: 17 additions & 8 deletions .pubnub.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
name: c-core
schema: 1
version: "5.3.2"
version: "5.4.0"
scm: github.com/pubnub/c-core
changelog:
- date: 2025-10-21
version: v5.4.0
changes:
- type: feature
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."
- type: bug
text: "Replace the Windows API, which in a multithreaded environment became a reason for crashes during the DNS resolution process."
- type: bug
text: "Fix the issue because of which client created a secondary connection when built with `PUBNUB_USE_IPV6` support."
- date: 2025-09-23
version: v5.3.2
changes:
Expand Down Expand Up @@ -1036,7 +1045,7 @@ sdks:
distribution-type: source code
distribution-repository: GitHub release
package-name: C-Core
location: https://github.com/pubnub/c-core/releases/tag/v5.3.2
location: https://github.com/pubnub/c-core/releases/tag/v5.4.0
requires:
-
name: "miniz"
Expand Down Expand Up @@ -1102,7 +1111,7 @@ sdks:
distribution-type: source code
distribution-repository: GitHub release
package-name: C-Core
location: https://github.com/pubnub/c-core/releases/tag/v5.3.2
location: https://github.com/pubnub/c-core/releases/tag/v5.4.0
requires:
-
name: "miniz"
Expand Down Expand Up @@ -1168,7 +1177,7 @@ sdks:
distribution-type: source code
distribution-repository: GitHub release
package-name: C-Core
location: https://github.com/pubnub/c-core/releases/tag/v5.3.2
location: https://github.com/pubnub/c-core/releases/tag/v5.4.0
requires:
-
name: "miniz"
Expand Down Expand Up @@ -1230,7 +1239,7 @@ sdks:
distribution-type: source code
distribution-repository: GitHub release
package-name: C-Core
location: https://github.com/pubnub/c-core/releases/tag/v5.3.2
location: https://github.com/pubnub/c-core/releases/tag/v5.4.0
requires:
-
name: "miniz"
Expand Down Expand Up @@ -1291,7 +1300,7 @@ sdks:
distribution-type: source code
distribution-repository: GitHub release
package-name: C-Core
location: https://github.com/pubnub/c-core/releases/tag/v5.3.2
location: https://github.com/pubnub/c-core/releases/tag/v5.4.0
requires:
-
name: "miniz"
Expand Down Expand Up @@ -1347,7 +1356,7 @@ sdks:
distribution-type: source code
distribution-repository: GitHub release
package-name: C-Core
location: https://github.com/pubnub/c-core/releases/tag/v5.3.2
location: https://github.com/pubnub/c-core/releases/tag/v5.4.0
requires:
-
name: "miniz"
Expand Down Expand Up @@ -1400,7 +1409,7 @@ sdks:
distribution-type: source code
distribution-repository: GitHub release
package-name: C-Core
location: https://github.com/pubnub/c-core/releases/tag/v5.3.2
location: https://github.com/pubnub/c-core/releases/tag/v5.4.0
requires:
-
name: "miniz"
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## v5.4.0
October 21 2025

#### Added
- 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.

#### Fixed
- Replace the Windows API, which in a multithreaded environment became a reason for crashes during the DNS resolution process.
- Fix the issue because of which client created a secondary connection when built with `PUBNUB_USE_IPV6` support.

## v5.3.2
September 23 2025

Expand Down
20 changes: 20 additions & 0 deletions core/pbauto_heartbeat.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ static int copy_context_settings(pubnub_t* pb_clone, pubnub_t const* pb)
pb_clone->origin = pb->origin;
}
pb_clone->options.use_http_keep_alive = pb->options.use_http_keep_alive;
pb_clone->options.tcp_keepalive.enabled = pb->options.tcp_keepalive.enabled;
pb_clone->options.tcp_keepalive.time = pb->options.tcp_keepalive.time;
pb_clone->options.tcp_keepalive.interval = pb->options.tcp_keepalive.interval;
pb_clone->options.tcp_keepalive.probes = pb->options.tcp_keepalive.probes;
#if PUBNUB_USE_IPV6 && defined(PUBNUB_CALLBACK_API)
pb_clone->options.ipv6_connectivity = pb->options.ipv6_connectivity;
#endif
Expand Down Expand Up @@ -252,6 +256,14 @@ static void auto_heartbeat_callback(pubnub_t* heartbeat_pb,
if (pubsub_keys_changed(heartbeat_pb, pb)) {
pubnub_init(
heartbeat_pb, pb->core.publish_key, pb->core.subscribe_key);
if (pbccTrue == pb->options.tcp_keepalive.enabled) {
pubnub_use_tcp_keep_alive(
heartbeat_pb,
pb->options.tcp_keepalive.time,
pb->options.tcp_keepalive.interval,
pb->options.tcp_keepalive.probes);
} else if (pbccFalse == pb->options.tcp_keepalive.enabled)
pubnub_dont_use_tcp_keep_alive(heartbeat_pb);

heartbeat_thump(pb, heartbeat_pb);
}
Expand All @@ -275,6 +287,14 @@ static pubnub_t* init_new_thumper_pb(pubnub_t* pb, unsigned i)
}
pubnub_mutex_lock(pb->monitor);
pubnub_init(pb_new, pb->core.publish_key, pb->core.subscribe_key);
if (pbccTrue == pb->options.tcp_keepalive.enabled) {
pubnub_use_tcp_keep_alive(
pb_new,
pb->options.tcp_keepalive.time,
pb->options.tcp_keepalive.interval,
pb->options.tcp_keepalive.probes);
} else if (pbccFalse == pb->options.tcp_keepalive.enabled)
pubnub_dont_use_tcp_keep_alive(pb_new);
pubnub_mutex_unlock(pb->monitor);

pubnub_mutex_lock(pb_new->monitor);
Expand Down
3 changes: 3 additions & 0 deletions core/pbpal.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,9 @@ int pbpal_close(pubnub_t *pb);
/** Sets blocking I/O option on the context for the communication */
int pbpal_set_blocking_io(pubnub_t *pb);

/** Sets user-provided TCP Keep-Alive configuration for active connection. */
void pbpal_set_tcp_keepalive(const pubnub_t *pb);

/** Frees-up any resources allocated by the PAL for the given
context. After this call, context is not safe for use by PAL any
more (it is assumed it will be freed-up by the caller).
Expand Down
24 changes: 24 additions & 0 deletions core/pubnub_internal_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,27 @@ struct pbntlm_context {

typedef struct pbntlm_context pbntlm_ctx_t;

/** TCP Keep-Alive configuration object. */
typedef struct pubnub_tcp_keepalive_ {
/** Whether TCP Keep-Alive should be used or not. */
enum pubnub_tribool enabled;

/** The time in seconds a socket needs to be @c idle before the first
keep-alive probe is sent.
*/
uint8_t time;

/** The number of seconds that should pass between sends of
keep-alive probes if the last one wasn't acknowledged.
*/
uint8_t interval;

/** The number of times a probe will be sent and not acknowledged
before the connection is deemed broken.
*/
uint8_t probes;
} pubnub_tcp_keepalive;

struct pubnub_options {
#if PUBNUB_BLOCKING_IO_SETTABLE
/** Indicates whether to use blocking I/O. Not implemented if
Expand All @@ -214,6 +235,9 @@ struct pubnub_options {
*/
bool use_http_keep_alive : 1;

/** Per-context (because of one request per-context) TCP Keep-Alive
configuration. */
pubnub_tcp_keepalive tcp_keepalive;
#if PUBNUB_USE_IPV6
/* Connectivity type(true-Ipv6/false-Ipv4) chosen on a given context */
bool ipv6_connectivity : 1;
Expand Down
5 changes: 1 addition & 4 deletions core/pubnub_netcore.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,7 @@ static enum pubnub_state close_kept_alive_connection(struct pubnub_* pb)
pbpal_forget(pb);
return PBS_IDLE;
}
else {
return PBS_KEEP_ALIVE_WAIT_CLOSE;
}
return PBS_KEEP_ALIVE_WAIT_CLOSE;
}


Expand Down Expand Up @@ -1085,7 +1083,6 @@ int pbnc_fsm(struct pubnub_* pb)
pb->state = PBS_RX_HEADERS;
goto next_state;
case PNR_CONNECTION_TIMEOUT:
case PNR_TIMEOUT:
case PNR_IO_ERROR:
if (pb->flags.started_while_kept_alive) {
pb->state = close_kept_alive_connection(pb);
Expand Down
23 changes: 23 additions & 0 deletions core/pubnub_pubsubapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ pubnub_t* pubnub_init(pubnub_t* p, const char* publish_key, const char* subscrib
p->state = PBS_IDLE;
p->trans = PBTT_NONE;
p->options.use_http_keep_alive = true;

// Setting default TCP keep-alive options.
p->options.tcp_keepalive.enabled = pbccTrue;
p->options.tcp_keepalive.time = 60;
p->options.tcp_keepalive.interval = 20;
p->options.tcp_keepalive.probes = 3;
#if !defined(PUBNUB_CALLBACK_API) || defined(PUBNUB_NTF_RUNTIME_SELECTION)
p->should_stop_await = false;
#endif
Expand Down Expand Up @@ -540,3 +546,20 @@ void pubnub_dont_use_http_keep_alive(pubnub_t* p)
{
p->options.use_http_keep_alive = 0;
}

void pubnub_use_tcp_keep_alive(
pubnub_t* pb,
const uint8_t time,
const uint8_t interval,
const uint8_t probes)
{
pb->options.tcp_keepalive.enabled = pbccTrue;
pb->options.tcp_keepalive.time = time;
pb->options.tcp_keepalive.interval = interval;
pb->options.tcp_keepalive.probes = probes;
}

void pubnub_dont_use_tcp_keep_alive(pubnub_t* pb)
{
pb->options.tcp_keepalive.enabled = pbccFalse;
}
34 changes: 34 additions & 0 deletions core/pubnub_pubsubapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,5 +394,39 @@ PUBNUB_EXTERN void pubnub_use_http_keep_alive(pubnub_t* p);
*/
PUBNUB_EXTERN void pubnub_dont_use_http_keep_alive(pubnub_t* p);

/** Enable the use of TCP Keep-Alive ("probes") on the context @p pb .
*
* @b Defaults:
* - @c time: @b 60 seconds
* - @c interval: @b 20 seconds
* - @c probes: @b 3
*
* @b Important: this option works well @b only together with HTTP Keep-Alive, which
* is managed by @c pubnub_use_http_keep_alive and
* @c pubnub_dont_use_http_keep_alive.
*
* @param pb Pointer to the PubNub context which TCP KA should be enabled.
* @param time The time in seconds a socket needs to be @c idle before the
* first keep-alive probe is sent.
* @param interval The number of seconds that should pass between sends of
* keep-alive probes if the last one wasn't acknowledged.
* @param probes The number of times a probe will be sent and not acknowledged
* before the connection is deemed broken.
*/
PUBNUB_EXTERN void pubnub_use_tcp_keep_alive(
pubnub_t* pb,
uint8_t time,
uint8_t interval,
uint8_t probes);

/** Disables the use of TCP Keep-Alive ("probes") on the context @p pb .
*
* @b Important: this option works @b only together with HTTP Keep-Alive, which
* is managed by @c pubnub_use_http_keep_alive and
* @c pubnub_dont_use_http_keep_alive.
*
* @param pb Pointer to the PubNub context which TCP KA should be disabled.
*/
PUBNUB_EXTERN void pubnub_dont_use_tcp_keep_alive(pubnub_t* pb);

#endif /* !defined INC_PUBNUB_PUBSUBAPI */
2 changes: 1 addition & 1 deletion core/pubnub_version_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#define INC_PUBNUB_VERSION_INTERNAL


#define PUBNUB_SDK_VERSION "5.3.2"
#define PUBNUB_SDK_VERSION "5.4.0"


#endif /* !defined INC_PUBNUB_VERSION_INTERNAL */
Loading
Loading