diff --git a/.github/workflows/composite/unit-integration-test-runner/run-integration-tests.sh b/.github/workflows/composite/unit-integration-test-runner/run-integration-tests.sh index a89779a3..b0f8fac8 100755 --- a/.github/workflows/composite/unit-integration-test-runner/run-integration-tests.sh +++ b/.github/workflows/composite/unit-integration-test-runner/run-integration-tests.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -e INFO_BG="\033[0m\033[48;2;5;49;70m" INFO_FG="\033[38;2;19;181;255m" diff --git a/.github/workflows/composite/unit-integration-test-runner/run-unit-tests.sh b/.github/workflows/composite/unit-integration-test-runner/run-unit-tests.sh index 0da15bf5..88027bb1 100755 --- a/.github/workflows/composite/unit-integration-test-runner/run-unit-tests.sh +++ b/.github/workflows/composite/unit-integration-test-runner/run-unit-tests.sh @@ -1,4 +1,10 @@ #!/bin/bash +set -e + +if [ -d "/usr/lib/x86_64-linux-gnu/" ]; then +export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH +fi + echo "::group::Run unit tests ('$1' $CC / $CXX)" cd "$GITHUB_WORKSPACE/core" diff --git a/.github/workflows/composite/unit-test-framework/action.yaml b/.github/workflows/composite/unit-test-framework/action.yaml index e0114ddc..70b3fd18 100644 --- a/.github/workflows/composite/unit-test-framework/action.yaml +++ b/.github/workflows/composite/unit-test-framework/action.yaml @@ -18,7 +18,7 @@ runs: steps: - name: Build and Cache Unit Test framework ('${{ inputs.os }}' ${{ inputs.compilers }}) id: unit-test-framework - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | cgreen @@ -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@v3 + uses: actions/checkout@v4 with: repository: cgreen-devs/cgreen ref: ${{ matrix.cgreen }} diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 66fe81d8..0c70fab6 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -25,11 +25,11 @@ jobs: # group: organization/macos-gh steps: - name: Checkout project - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: token: ${{ secrets.GH_TOKEN }} - name: Checkout actions - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: pubnub/client-engineering-deployment-tools ref: v1 diff --git a/.pubnub.yml b/.pubnub.yml index 76c5b55c..343bfd48 100644 --- a/.pubnub.yml +++ b/.pubnub.yml @@ -1,8 +1,17 @@ name: c-core schema: 1 -version: "4.14.1" +version: "4.15.0" scm: github.com/pubnub/c-core changelog: + - date: 2024-11-25 + version: v4.15.0 + changes: + - type: feature + text: "Add custom message type support for the following APIs: publish, signal, share file, subscribe and history." + - type: feature + text: "Add `pubnub_set_ipv4_connectivity` and `pubnub_set_ipv6_connectivity` to `pubnub_coreapi` to switch preferred connectivity protocol." + - type: bug + text: "Make sure that in case of connection close (including because of error) proxy context object will be reset." - date: 2024-10-24 version: v4.14.1 changes: @@ -875,7 +884,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.14.1 + location: https://github.com/pubnub/c-core/releases/tag/v4.15.0 requires: - name: "miniz" @@ -941,7 +950,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.14.1 + location: https://github.com/pubnub/c-core/releases/tag/v4.15.0 requires: - name: "miniz" @@ -1007,7 +1016,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.14.1 + location: https://github.com/pubnub/c-core/releases/tag/v4.15.0 requires: - name: "miniz" @@ -1069,7 +1078,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.14.1 + location: https://github.com/pubnub/c-core/releases/tag/v4.15.0 requires: - name: "miniz" @@ -1130,7 +1139,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.14.1 + location: https://github.com/pubnub/c-core/releases/tag/v4.15.0 requires: - name: "miniz" @@ -1186,7 +1195,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.14.1 + location: https://github.com/pubnub/c-core/releases/tag/v4.15.0 requires: - name: "miniz" @@ -1239,7 +1248,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.14.1 + location: https://github.com/pubnub/c-core/releases/tag/v4.15.0 requires: - name: "miniz" diff --git a/CHANGELOG.md b/CHANGELOG.md index a266a427..2d05815a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## v4.15.0 +November 25 2024 + +#### Added +- Add custom message type support for the following APIs: publish, signal, share file, subscribe and history. +- Add `pubnub_set_ipv4_connectivity` and `pubnub_set_ipv6_connectivity` to `pubnub_coreapi` to switch preferred connectivity protocol. + +#### Fixed +- Make sure that in case of connection close (including because of error) proxy context object will be reset. + ## v4.14.1 October 24 2024 diff --git a/Dockerfile b/Dockerfile index 3364296f..125ccbf5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -37,11 +37,11 @@ RUN apt-get install -y cmake g++ ruby ruby-dev git ninja-build libboost-all-dev RUN git clone https://github.com/cgreen-devs/cgreen.git RUN cd cgreen && git checkout 1.4.1 && make -FROM ubuntu:20.04 +FROM ubuntu:20.04 ARG DEBIAN_FRONTEND=noninteractive WORKDIR /home -ENV GMOCK_VER=1.7.0 +ENV GMOCK_VER=1.7.0 ENV CMAKE_CXX_COMPILER=/usr/bin/g++ RUN apt-get update @@ -83,7 +83,7 @@ RUN if [ -z "$MOCK_SERVER_DOCKER" ]; then \ -Icucumber-cpp/include -Icucumber-cpp/build/src/ -Iposix -Icore -I. -Icpp \ -D PUBNUB_CRYPTO_API=1 -D PUBNUB_USE_SSL=0 -D MOCK_SERVER_DOCKER; \ fi - + RUN g++ -o steps BoostSteps.o cpp/pubnub_sync.a cucumber-cpp/build/src/libcucumber-cpp.a \ -Lboost -lboost_unit_test_framework -lpthread -lboost_regex \ diff --git a/core/Makefile b/core/Makefile index 79de3513..3727ea07 100644 --- a/core/Makefile +++ b/core/Makefile @@ -66,7 +66,7 @@ pubnub_timer_list_unittest: pubnub_timer_list.c pubnub_timer_list_unit_test.c #$(GCOVR) -r . --html --html-details -o coverage.html -PROXY_PROJECT_SOURCEFILES = pubnub_proxy_core.c pubnub_proxy.c pbhttp_digest.c pbntlm_core.c pbntlm_packer_std.c pubnub_generate_uuid_v4_random_std.c ../lib/pubnub_parse_ipv4_addr.c ../lib/pubnub_parse_ipv6_addr.c ../lib/md5/md5.c +PROXY_PROJECT_SOURCEFILES = pubnub_proxy_core.c pubnub_proxy.c pbhttp_digest.c pbntlm_core.c pbntlm_packer_std.c pubnub_generate_uuid_v4_random_std.c pubnub_dns_servers.c ../lib/pubnub_parse_ipv4_addr.c ../lib/pubnub_parse_ipv6_addr.c ../lib/md5/md5.c pubnub_proxy_unittest: $(PROJECT_SOURCEFILES) $(PROXY_PROJECT_SOURCEFILES) pubnub_proxy_unit_test.c gcc -o pubnub_proxy_unit_test.so -shared $(CFLAGS) $(LDFLAGS) -D PUBNUB_CALLBACK_API -D PUBNUB_PROXY_API=1 -Wall $(COVERAGE_FLAGS) -fPIC $(PROJECT_SOURCEFILES) $(PROXY_PROJECT_SOURCEFILES) pubnub_proxy_unit_test.c -lcgreen -lm @@ -87,17 +87,47 @@ CRYPTO_INCLUDES += -I ../openssl/. CRYPTO_LIBS += -lssl -lcrypto CRYPTO_SOURCEFILES += pubnub_crypto.c pbcc_crypto.c pbcc_crypto_aes_cbc.c pbcc_crypto_legacy.c ../openssl/pbaes256.c + +OS := $(shell uname) +ifeq ($(OS),Darwin) + # Ensure OpenSSL paths are set. + OPENSSL_CFLAGS := $(shell pkg-config --cflags openssl 2>/dev/null) + OPENSSL_LIBS := $(shell pkg-config --libs openssl 2>/dev/null) + ifneq ($(OPENSSL_CFLAGS),) + CRYPTO_INCLUDES += $(OPENSSL_CFLAGS) + endif + ifneq ($(OPENSSL_LIBS),) + CRYPTO_LIBS += $(OPENSSL_LIBS) + endif +else + ifeq ($(shell test -d "/usr/local/opt/openssl" && echo yes || echo no),yes) + CRYPTO_INCLUDES += -I/usr/local/opt/openssl/include + else + # Path on GitHub Action Runner (ubuntu-latest image) + ifeq ($(shell test -d "/usr/include/openssl" && echo yes || echo no),yes) + CRYPTO_INCLUDES += -I/usr/include + endif + endif + # Path on GitHub Action Runner (ubuntu-latest image) + ifeq ($(shell test -d "/usr/lib/x86_64-linux-gnu" && echo yes || echo no),yes) + CRYPTO_LIBS += -L/usr/lib/x86_64-linux-gnu -Wl,-Bdynamic + endif +endif + + pbcc_crypto_unittest: $(PROJECT_SOURCEFILES) $(CRYPTO_SOURCEFILES) pbcc_crypto_unit_tests.c - gcc -o pbcc_crypto_unit_test.so -shared $(CFLAGS) $(LDFLAGS) $(CRYPTO_INCLUDES) $(CRYPTO_LIBS) -D PUBNUB_CRYPTO_API=1 -Wall $(COVERAGE_FLAGS) -fPIC $(PROJECT_SOURCEFILES) $(CRYPTO_SOURCEFILES) test/pubnub_test_mocks.c pbcc_crypto_unit_tests.c -lcgreen -lm + gcc -o pbcc_crypto_unit_test.so -shared $(CFLAGS) $(LDFLAGS) $(CRYPTO_INCLUDES) -D PUBNUB_CRYPTO_API=1 -Wall $(COVERAGE_FLAGS) -fPIC $(PROJECT_SOURCEFILES) $(CRYPTO_SOURCEFILES) test/pubnub_test_mocks.c pbcc_crypto_unit_tests.c $(CRYPTO_LIBS) -lcgreen -lm # gcc -o pubnub_core_unit_testo $(CFLAGS) -Wall $(COVERAGE_FLAGS) $(PROJECT_SOURCEFILES) pbcc_crypto_unit_tests.c -lcgreen -lm + #ldd pbcc_crypto_unit_test.so $(CGREEN_RUNNER) ./pbcc_crypto_unit_test.so #$(GCOVR) -r . --html --html-details -o coverage.html SUBSCRIBE_V2_SOURCEFILES += pubnub_subscribe_v2.c pbcc_subscribe_v2.c pubnub_crypto_unittest: $(PROJECT_SOURCEFILES) $(CRYPTO_SOURCEFILES) $(SUBSCRIBE_V2_SOURCEFILES) pubnub_crypto_unit_tests.c - gcc -o pubnub_crypto_unit_test.so -shared $(CFLAGS) $(LDFLAGS) $(CRYPTO_INCLUDES) $(CRYPTO_LIBS) -D PUBNUB_CRYPTO_API=1 -D PUBNUB_USE_SUBSCRIBE_V2=1 -Wall $(COVERAGE_FLAGS) -fPIC $(PROJECT_SOURCEFILES) $(CRYPTO_SOURCEFILES) $(SUBSCRIBE_V2_SOURCEFILES) test/pubnub_test_mocks.c pubnub_crypto_unit_tests.c -lcgreen -lm + gcc -o pubnub_crypto_unit_test.so -shared $(CFLAGS) $(LDFLAGS) $(CRYPTO_INCLUDES) -D PUBNUB_CRYPTO_API=1 -D PUBNUB_USE_SUBSCRIBE_V2=1 -Wall $(COVERAGE_FLAGS) -fPIC $(PROJECT_SOURCEFILES) $(CRYPTO_SOURCEFILES) $(SUBSCRIBE_V2_SOURCEFILES) test/pubnub_test_mocks.c pubnub_crypto_unit_tests.c $(CRYPTO_LIBS) -lcgreen -lm # gcc -o pubnub_core_unit_testo $(CFLAGS) -Wall $(COVERAGE_FLAGS) $(PROJECT_SOURCEFILES) pubnub_crypto_unit_tests.c -lcgreen -lm + #ldd pubnub_crypto_unit_test.so $(CGREEN_RUNNER) ./pubnub_crypto_unit_test.so diff --git a/core/pbcc_fetch_history.c b/core/pbcc_fetch_history.c index 24b45a65..20d417d6 100644 --- a/core/pbcc_fetch_history.c +++ b/core/pbcc_fetch_history.c @@ -21,6 +21,7 @@ enum pubnub_res pbcc_fetch_history_prep(struct pbcc_context* pb, const char* channel, unsigned int max_per_channel, enum pubnub_tribool include_meta, + enum pubnub_tribool include_custom_message_type, enum pubnub_tribool include_message_type, enum pubnub_tribool include_user_id, enum pubnub_tribool include_message_actions, @@ -59,7 +60,8 @@ enum pubnub_res pbcc_fetch_history_prep(struct pbcc_context* pb, if (max_per_channel) { ADD_URL_PARAM(qparam, max, max_per_ch_cnt_buf); } if (include_meta != pbccNotSet) { ADD_URL_PARAM(qparam, include_meta, include_meta == pbccTrue ? "true" : "false"); } - if (include_message_type != pbccNotSet) { ADD_URL_PARAM(qparam, include_message_type, include_meta == pbccTrue ? "true" : "false"); } + if (include_custom_message_type != pbccNotSet) { ADD_URL_PARAM(qparam, include_custom_message_type, include_custom_message_type == pbccTrue ? "true" : "false"); } + if (include_message_type != pbccNotSet) { ADD_URL_PARAM(qparam, include_message_type, include_message_type == pbccTrue ? "true" : "false"); } if (include_user_id != pbccNotSet) { ADD_URL_PARAM(qparam, include_uuid, include_user_id == pbccTrue ? "true" : "false"); } #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } diff --git a/core/pbcc_fetch_history.h b/core/pbcc_fetch_history.h index c16739e4..d2072e77 100644 --- a/core/pbcc_fetch_history.h +++ b/core/pbcc_fetch_history.h @@ -10,6 +10,7 @@ enum pubnub_res pbcc_fetch_history_prep(struct pbcc_context* pb, const char* channel, unsigned int max_per_channel, enum pubnub_tribool include_meta, + enum pubnub_tribool include_custom_message_type, enum pubnub_tribool include_message_type, enum pubnub_tribool include_user_id, enum pubnub_tribool include_message_actions, diff --git a/core/pbcc_subscribe_v2.c b/core/pbcc_subscribe_v2.c index e1c50650..4ed2e13c 100644 --- a/core/pbcc_subscribe_v2.c +++ b/core/pbcc_subscribe_v2.c @@ -27,7 +27,7 @@ enum pubnub_res pbcc_subscribe_v2_prep(struct pbcc_context* p, char const* channel, char const* channel_group, - unsigned* heartbeat, + const unsigned* heartbeat, char const* filter_expr) { char region_str[20]; @@ -254,6 +254,9 @@ struct pubnub_v2_message pbcc_get_msg_v2(struct pbcc_context* p) found.end - found.start, &rslt.payload.size ); + } else { + rslt.payload.ptr = (char*)found.start; + rslt.payload.size = found.end - found.start; } #else rslt.payload.ptr = (char*)found.start; @@ -303,6 +306,11 @@ struct pubnub_v2_message pbcc_get_msg_v2(struct pbcc_context* p) rslt.message_type = pbsbPublished; } + if (jonmpOK == pbjson_get_object_value(&el, "cmt", &found)) { + rslt.custom_message_type.ptr = (char*)found.start + 1; + rslt.custom_message_type.size = found.end - found.start - 2; + } + jpresult = pbjson_get_object_value(&el, "p", &found); if (jonmpOK == jpresult) { struct pbjson_elem titel; diff --git a/core/pbcc_subscribe_v2.h b/core/pbcc_subscribe_v2.h index 642f969a..cce9c340 100644 --- a/core/pbcc_subscribe_v2.h +++ b/core/pbcc_subscribe_v2.h @@ -15,7 +15,7 @@ struct pbcc_context; enum pubnub_res pbcc_subscribe_v2_prep(struct pbcc_context* p, char const* channel, char const* channel_group, - unsigned* heartbeat, + const unsigned* heartbeat, char const* filter_expr); diff --git a/core/pubnub_ccore_pubsub.c b/core/pubnub_ccore_pubsub.c index 6822467e..db886ce9 100644 --- a/core/pubnub_ccore_pubsub.c +++ b/core/pubnub_ccore_pubsub.c @@ -525,6 +525,7 @@ enum pubnub_res pbcc_append_url_param_encoded(struct pbcc_context* pb, enum pubnub_res pbcc_publish_prep(struct pbcc_context* pb, const char* channel, const char* message, + const char* custom_message_type, bool store_in_history, bool norep, char const* meta, @@ -596,7 +597,7 @@ enum pubnub_res pbcc_publish_prep(struct pbcc_context* pb, URL_PARAMS_INIT(qparam, PUBNUB_MAX_URL_PARAMS); if (uname) { ADD_URL_PARAM(qparam, pnsdk, uname); } ADD_URL_PARAM(qparam, uuid, user_id); - if (ttl != SIZE_MAX) { ADD_URL_PARAM_SIZET(qparam, ttl, ttl); } + if (ttl != 0 && ttl != SIZE_MAX) { ADD_URL_PARAM_SIZET(qparam, ttl, ttl); } #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } ADD_TS_TO_URL_PARAM(); @@ -606,6 +607,9 @@ enum pubnub_res pbcc_publish_prep(struct pbcc_context* pb, if (!store_in_history) { ADD_URL_PARAM(qparam, store, "0"); } if (norep) { ADD_URL_PARAM(qparam, norep, "true"); } if (meta) { ADD_URL_PARAM(qparam, meta, meta); } + if (custom_message_type) { + ADD_URL_PARAM(qparam, custom_message_type, custom_message_type); + } #if PUBNUB_CRYPTO_API SORT_URL_PARAMETERS(qparam); @@ -667,7 +671,8 @@ enum pubnub_res pbcc_sign_url(struct pbcc_context* pc, const char* msg, enum pub enum pubnub_res pbcc_signal_prep(struct pbcc_context* pb, const char* channel, - const char* message) + const char* message, + const char* custom_message_type) { enum pubnub_res rslt = PNR_OK; char const* const uname = pubnub_uname(); @@ -689,6 +694,9 @@ enum pubnub_res pbcc_signal_prep(struct pbcc_context* pb, URL_PARAMS_INIT(qparam, PUBNUB_MAX_URL_PARAMS); if (uname) { ADD_URL_PARAM(qparam, pnsdk, uname); } if (user_id) { ADD_URL_PARAM(qparam, uuid, user_id); } + if (custom_message_type) { + ADD_URL_PARAM(qparam, custom_message_type, custom_message_type); + } #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } ADD_TS_TO_URL_PARAM(); @@ -716,7 +724,7 @@ enum pubnub_res pbcc_signal_prep(struct pbcc_context* pb, enum pubnub_res pbcc_subscribe_prep(struct pbcc_context* p, char const* channel, char const* channel_group, - unsigned* heartbeat) + const unsigned* heartbeat) { char const* user_id = pbcc_user_id_get(p); char const* const uname = pubnub_uname(); diff --git a/core/pubnub_ccore_pubsub.h b/core/pubnub_ccore_pubsub.h index 1e03e6a8..737cbfed 100644 --- a/core/pubnub_ccore_pubsub.h +++ b/core/pubnub_ccore_pubsub.h @@ -477,6 +477,7 @@ void pbcc_via_post_headers(struct pbcc_context* p, char* header, size_t max_leng enum pubnub_res pbcc_publish_prep(struct pbcc_context* pb, const char* channel, const char* message, + const char* custom_message_type, bool store_in_history, bool norep, char const* meta, @@ -488,7 +489,8 @@ enum pubnub_res pbcc_publish_prep(struct pbcc_context* pb, */ enum pubnub_res pbcc_signal_prep(struct pbcc_context* pb, const char* channel, - const char* message); + const char* message, + const char* custom_message_type); /** Prepares the Subscribe operation (transaction), mostly by formatting the URI of the HTTP request. @@ -496,7 +498,7 @@ enum pubnub_res pbcc_signal_prep(struct pbcc_context* pb, enum pubnub_res pbcc_subscribe_prep(struct pbcc_context* p, char const* channel, char const* channel_group, - unsigned* heartbeat); + const unsigned* heartbeat); /** Split @p buf string containing a JSON array (with arbitrary diff --git a/core/pubnub_coreapi.c b/core/pubnub_coreapi.c index 5eec3c42..da82efdb 100644 --- a/core/pubnub_coreapi.c +++ b/core/pubnub_coreapi.c @@ -471,3 +471,20 @@ int pubnub_last_http_response_body(pubnub_t* pb, pubnub_chamebl_t* o_msg) pubnub_mutex_unlock(pb->monitor); return 0; } + +#if PUBNUB_USE_IPV6 +void pubnub_set_ipv4_connectivity(pubnub_t *p) +{ + pubnub_mutex_lock(p->monitor); + p->options.ipv6_connectivity = false; + pubnub_mutex_unlock(p->monitor); +} + +void pubnub_set_ipv6_connectivity(pubnub_t *p) +{ + pubnub_mutex_lock(p->monitor); + p->options.ipv6_connectivity = true; + pubnub_mutex_unlock(p->monitor); +} +#endif /* PUBNUB_USE_IPV6 */ + diff --git a/core/pubnub_coreapi.h b/core/pubnub_coreapi.h index e803c828..99656480 100644 --- a/core/pubnub_coreapi.h +++ b/core/pubnub_coreapi.h @@ -439,4 +439,14 @@ PUBNUB_EXTERN int pubnub_get_error_message(pubnub_t* pb, pubnub_chamebl_t* o_msg */ PUBNUB_EXTERN int pubnub_last_http_response_body(pubnub_t* pb, pubnub_chamebl_t* o_msg); +#if PUBNUB_USE_IPV6 +/** IPv4 connectivity type for @p. + Use IPv4 addresses to establish connection with remote origin. */ +PUBNUB_EXTERN void pubnub_set_ipv4_connectivity(pubnub_t *p); + +/** IPv6 connectivity type for @p. + Use IPv6 addresses to establish connection with remote origin. */ +PUBNUB_EXTERN void pubnub_set_ipv6_connectivity(pubnub_t *p); +#endif + #endif /* defined INC_PUBNUB_COREAPI */ diff --git a/core/pubnub_coreapi_ex.c b/core/pubnub_coreapi_ex.c index 119a28c7..30fdfa66 100644 --- a/core/pubnub_coreapi_ex.c +++ b/core/pubnub_coreapi_ex.c @@ -27,12 +27,13 @@ struct pubnub_publish_options pubnub_publish_defopts(void) { struct pubnub_publish_options result; - result.store = true; - result.cipher_key = NULL; - result.replicate = true; - result.meta = NULL; - result.method = pubnubSendViaGET; - result.ttl = SIZE_MAX; + result.store = true; + result.cipher_key = NULL; + result.replicate = true; + result.meta = NULL; + result.method = pubnubSendViaGET; + result.ttl = 0; + result.custom_message_type = NULL; return result; } @@ -85,6 +86,7 @@ enum pubnub_res pubnub_publish_ex(pubnub_t* pb, rslt = pbcc_publish_prep(&pb->core, channel, message, + opts.custom_message_type, opts.store, !opts.replicate, opts.meta, @@ -102,6 +104,40 @@ enum pubnub_res pubnub_publish_ex(pubnub_t* pb, return rslt; } +struct pubnub_signal_options pubnub_signal_defopts(void) +{ + struct pubnub_signal_options result; + result.custom_message_type = NULL; + return result; +} + +enum pubnub_res pubnub_signal_ex( + pubnub_t* pb, + const char* channel, + const char* message, + struct pubnub_signal_options opts) +{ + enum pubnub_res rslt; + + PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); + + pubnub_mutex_lock(pb->monitor); + if (!pbnc_can_start_transaction(pb)) { + pubnub_mutex_unlock(pb->monitor); + return PNR_IN_PROGRESS; + } + + rslt = pbcc_signal_prep(&pb->core, channel, message, opts.custom_message_type); + if (PNR_STARTED == rslt) { + pb->trans = PBTT_SIGNAL; + pb->core.last_result = PNR_STARTED; + pbnc_fsm(pb); + rslt = pb->core.last_result; + } + pubnub_mutex_unlock(pb->monitor); + + return rslt; +} struct pubnub_subscribe_options pubnub_subscribe_defopts(void) { diff --git a/core/pubnub_coreapi_ex.h b/core/pubnub_coreapi_ex.h index 79a88b30..f48eec6a 100644 --- a/core/pubnub_coreapi_ex.h +++ b/core/pubnub_coreapi_ex.h @@ -65,11 +65,17 @@ struct pubnub_publish_options { API. */ size_t ttl; + /** User-specified message type. + Important: String limited by **3**-**50** case-sensitive alphanumeric + characters with only `-` and `_` special characters allowed. + */ + char const* custom_message_type; }; /** This returns the default options for publish V1 transactions. Will set `store = true`, `cipher_key = NULL`, `replicate = true`, - `meta = NULL` and `method = pubnubPublishViaGet` + `meta = NULL`, `method = pubnubPublishViaGet`, `ttl=0`, and + `custom_message_type=NULL`. */ PUBNUB_EXTERN struct pubnub_publish_options pubnub_publish_defopts(void); @@ -85,7 +91,7 @@ PUBNUB_EXTERN struct pubnub_publish_options pubnub_publish_defopts(void); @param p The Pubnub context. Can't be NULL. @param channel The string with the channel name to publish to. Can't be NULL. - @param opt Publish V1 options + @param opts Publish V1 options @return #PNR_STARTED on success, an error otherwise */ PUBNUB_EXTERN enum pubnub_res pubnub_publish_ex(pubnub_t* p, @@ -94,6 +100,41 @@ PUBNUB_EXTERN enum pubnub_res pubnub_publish_ex(pubnub_t* p, struct pubnub_publish_options opts); +/** Options for "extended" signal V1. */ +struct pubnub_signal_options { + /** User-specified message type. + Important: String limited by **3**-**50** case-sensitive alphanumeric + characters with only `-` and `_` special characters allowed. + */ + char const* custom_message_type; +}; + +/** This returns the default options for signal V1 transactions. + Will set `custom_message_type=NULL`. */ +PUBNUB_EXTERN struct pubnub_signal_options pubnub_signal_defopts(void); + +/** The extended signal V1. Basically the same as pubnub_signal(), + but with added optional parameters in @p opts. + + Basic usage: + + struct pubnub_signal_options opt = pubnub_signal_defopts(); + opt.custom_message_type = "test-message-type"; + pbresult = pubnub_signal_ex(pn, "my_channel", "status:active", opt); + + @param pb The pubnub context. Can't be NULL + @param channel The string with the channel to signal to. + @param message The signal message to send, expected to be in JSON format + @param opts Signal V1 options + @return #PNR_STARTED on success, an error otherwise +*/ +PUBNUB_EXTERN enum pubnub_res pubnub_signal_ex( + pubnub_t* pb, + const char* channel, + const char* message, + struct pubnub_signal_options opts); + + /** Options for "extended" subscribe. */ struct pubnub_subscribe_options { /** Channel group (a comma-delimited list of channel group names). diff --git a/core/pubnub_dns_servers.c b/core/pubnub_dns_servers.c index 5a8eb32c..57a63d33 100644 --- a/core/pubnub_dns_servers.c +++ b/core/pubnub_dns_servers.c @@ -33,7 +33,6 @@ void pubnub_dns_servers_deinit(void) pubnub_mutex_destroy(m_lock); } - int pubnub_dns_set_primary_server_ipv4(struct pubnub_ipv4_address ipv4_address) { uint8_t* ipv4 = ipv4_address.ipv4; diff --git a/core/pubnub_dns_servers.h b/core/pubnub_dns_servers.h index 4a742990..2a77f411 100644 --- a/core/pubnub_dns_servers.h +++ b/core/pubnub_dns_servers.h @@ -2,6 +2,7 @@ #if !defined INC_PUBNUB_DNS_SERVERS #define INC_PUBNUB_DNS_SERVERS +#include "core/pubnub_api_types.h" #include /** IPv4 Address, in binary format. diff --git a/core/pubnub_fetch_history.c b/core/pubnub_fetch_history.c index c4626190..85e729fa 100644 --- a/core/pubnub_fetch_history.c +++ b/core/pubnub_fetch_history.c @@ -23,6 +23,7 @@ struct pubnub_fetch_history_options pubnub_fetch_history_defopts(void) rslt.include_message_type = false; rslt.include_user_id = false; rslt.include_message_actions = false; + rslt.include_custom_message_type = false; return rslt; } @@ -45,6 +46,7 @@ enum pubnub_res pubnub_fetch_history(pubnub_t* pb, channel, opt.max_per_channel, opt.include_meta ? pbccTrue : pbccFalse, + opt.include_custom_message_type ? pbccTrue : pbccFalse, opt.include_message_type ? pbccTrue : pbccFalse, opt.include_user_id ? pbccTrue : pbccFalse, opt.include_message_actions ? pbccTrue : pbccFalse, diff --git a/core/pubnub_fetch_history.h b/core/pubnub_fetch_history.h index 45e92c42..2379a3d2 100644 --- a/core/pubnub_fetch_history.h +++ b/core/pubnub_fetch_history.h @@ -55,6 +55,10 @@ struct pubnub_fetch_history_options { * false. */ bool include_message_actions; + /** Include messages' custom type flag. + Message / signal and file messages may contain user-provided type. + */ + bool include_custom_message_type; }; /** This returns the default options for fetch history transactions. diff --git a/core/pubnub_internal_common.h b/core/pubnub_internal_common.h index ba6a733e..f30cdc82 100644 --- a/core/pubnub_internal_common.h +++ b/core/pubnub_internal_common.h @@ -206,7 +206,7 @@ struct pubnub_options { */ bool use_http_keep_alive : 1; -#if PUBNUB_USE_IPV6 && defined(PUBNUB_CALLBACK_API) +#if PUBNUB_USE_IPV6 /* Connectivity type(true-Ipv6/false-Ipv4) chosen on a given context */ bool ipv6_connectivity : 1; #endif diff --git a/core/pubnub_netcore.c b/core/pubnub_netcore.c index 62bad26b..227faabb 100644 --- a/core/pubnub_netcore.c +++ b/core/pubnub_netcore.c @@ -186,6 +186,10 @@ static bool should_keep_alive(struct pubnub_* pb, enum pubnub_res rslt) static void close_connection(struct pubnub_* pb) { +#if PUBNUB_PROXY_API + pbproxy_handle_connection_close(pb); +#endif /* PUBNUB_PROXY_API */ + if (pbpal_close(pb) <= 0) { #if PUBNUB_NEED_RETRY_AFTER_CLOSE PUBNUB_LOG_TRACE("close_connection(): pb->flags.retry_after_close=%d\n", @@ -588,7 +592,7 @@ int pbnc_fsm(struct pubnub_* pb) if (0 == i) { goto next_state; } - else if (i < 0) { + if (i < 0) { pb->core.last_result = PNR_CONNECT_FAILED; #if PUBNUB_ADNS_RETRY_AFTER_CLOSE if (pb->flags.retry_after_close) { diff --git a/core/pubnub_proxy_core.c b/core/pubnub_proxy_core.c index b40a4a7e..dcbe9221 100644 --- a/core/pubnub_proxy_core.c +++ b/core/pubnub_proxy_core.c @@ -122,6 +122,15 @@ static int process_digest_header_line(pubnub_t* p, char const* header) return 0; } +void pbproxy_handle_connection_close(pubnub_t *pb) +{ + /* Invalidate current NTLM proxy context state. */ + if (pbhtauNTLM == pb->proxy_auth_scheme && + (pb->ntlm_context.state != pbntlmSendNegotiate && + pb->ntlm_context.state != pbntlmDone)) { + pbntlm_core_deinit(pb); + } +} int pbproxy_handle_http_header(pubnub_t* p, char const* header) { @@ -211,6 +220,7 @@ int pbproxy_handle_http_header(pubnub_t* p, char const* header) } else if ((0 == strncmp(contents, scheme_NTLM, sizeof scheme_NTLM - 1)) && (auth_sheme_priority(p->proxy_auth_scheme) <= auth_sheme_priority(pbhtauNTLM))) { + PUBNUB_LOG_TRACE("pbproxy_handle_http_header() NTLM authentication\n"); if (pbhtauNTLM != p->proxy_auth_scheme) { pbntlm_core_init(p); p->proxy_auth_scheme = pbhtauNTLM; diff --git a/core/pubnub_proxy_core.h b/core/pubnub_proxy_core.h index e73c2772..6669192c 100644 --- a/core/pubnub_proxy_core.h +++ b/core/pubnub_proxy_core.h @@ -19,12 +19,15 @@ #if PUBNUB_PROXY_API +/** Handle PubNub context connection close. */ +void pbproxy_handle_connection_close(pubnub_t *pb); /** Processes a proxy related HTTP @p header on the Pubnub context @p p. @return 0 expected, -1 unexpected proxy authentication header */ int pbproxy_handle_http_header(pubnub_t *p, char const* header); #else +#define pbproxy_handle_connection_close(p, header) #define pbproxy_handle_http_header(p, header) 0 #endif diff --git a/core/pubnub_pubsubapi.c b/core/pubnub_pubsubapi.c index ac9b027d..a8953a97 100644 --- a/core/pubnub_pubsubapi.c +++ b/core/pubnub_pubsubapi.c @@ -52,10 +52,8 @@ 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; -#if PUBNUB_USE_IPV6 && defined(PUBNUB_CALLBACK_API) - /* Connectivity type(true-Ipv6/false-Ipv4) chosen on given contex. - Ipv4 by default. - */ +#if PUBNUB_USE_IPV6 + /* IPv4 connectivity type by default. */ p->options.ipv6_connectivity = false; #endif p->flags.started_while_kept_alive = false; @@ -110,7 +108,7 @@ enum pubnub_res pubnub_publish(pubnub_t* pb, const char* channel, const char* me } rslt = pbcc_publish_prep( - &pb->core, channel, message, true, false, NULL, SIZE_MAX, pubnubSendViaGET); + &pb->core, channel, message, NULL, true, false, NULL, SIZE_MAX, pubnubSendViaGET); if (PNR_STARTED == rslt) { pb->trans = PBTT_PUBLISH; pb->core.last_result = PNR_STARTED; @@ -137,7 +135,7 @@ enum pubnub_res pubnub_signal(pubnub_t* pb, return PNR_IN_PROGRESS; } - rslt = pbcc_signal_prep(&pb->core, channel, message); + rslt = pbcc_signal_prep(&pb->core, channel, message, NULL); if (PNR_STARTED == rslt) { pb->trans = PBTT_SIGNAL; pb->core.last_result = PNR_STARTED; diff --git a/core/pubnub_subscribe_v2_message.h b/core/pubnub_subscribe_v2_message.h index bd02cbfb..4c712418 100644 --- a/core/pubnub_subscribe_v2_message.h +++ b/core/pubnub_subscribe_v2_message.h @@ -54,6 +54,8 @@ struct pubnub_v2_message { enum pubnub_message_type message_type; /** The message information about publisher */ struct pubnub_char_mem_block publisher; + /** User-provided message type. */ + struct pubnub_char_mem_block custom_message_type; }; diff --git a/core/pubnub_subscribe_v2_unit_test.c b/core/pubnub_subscribe_v2_unit_test.c index eb89c06e..fad553bb 100644 --- a/core/pubnub_subscribe_v2_unit_test.c +++ b/core/pubnub_subscribe_v2_unit_test.c @@ -53,7 +53,7 @@ Ensure(subscribe_v2, should_parse_response_correctly) { assert_that(pubnub_auth_get(pbp), is_equal_to_string(NULL)); expect_have_dns_for_pubnub_origin_on_ctx(pbp); expect_outgoing_with_url_on_ctx(pbp, - "/v2/subscribe/sub_key/my-channel/0?pnsdk=unit-test-0.1&tt=0&tr=0&uuid=test_id&heartbeat=270"); + "/v2/subscribe/sub_key/my-channel/0?pnsdk=unit-test-0.1&tt=0&uuid=test_id&heartbeat=300"); incoming("HTTP/1.1 200\r\nContent-Length: " "44\r\n\r\n{\"t\":{\"t\":\"15628652479932717\",\"r\":4},\"m\":[]}", NULL); @@ -71,9 +71,9 @@ Ensure(subscribe_v2, should_parse_response_correctly) { expect(pbntf_got_socket, when(pb, is_equal_to(pbp)), will_return(0)); expect_outgoing_with_url_on_ctx(pbp, - "/v2/subscribe/sub_key/my-channel/0?pnsdk=unit-test-0.1&tt=15628652479932717&tr=4&uuid=test_id&heartbeat=270"); + "/v2/subscribe/sub_key/my-channel/0?pnsdk=unit-test-0.1&tt=15628652479932717&tr=4&uuid=test_id&heartbeat=300"); incoming("HTTP/1.1 220\r\nContent-Length: " - "183\r\n\r\n{\"t\":{\"t\":\"15628652479932717\",\"r\":4},\"m\":[{\"a\":\"1\",\"f\":514,\"i\":\"publisher_id\",\"s\":1,\"p\":{\"t\":\"15628652479933927\",\"r\":4},\"k\":\"demo\",\"c\":\"my-channel\",\"d\":\"mymessage\",\"b\":\"my-channel\"}]}", + "209\r\n\r\n{\"t\":{\"t\":\"15628652479932717\",\"r\":4},\"m\":[{\"a\":\"1\",\"f\":514,\"cmt\":\"test-message-type\",\"i\":\"publisher_id\",\"s\":1,\"p\":{\"t\":\"15628652479933927\",\"r\":4},\"k\":\"demo\",\"c\":\"my-channel\",\"d\":\"mymessage\",\"b\":\"my-channel\"}]}", NULL); expect(pbntf_lost_socket, when(pb, is_equal_to(pbp))); @@ -88,6 +88,7 @@ Ensure(subscribe_v2, should_parse_response_correctly) { assert_char_mem_block(msg.channel, "my-channel"); assert_char_mem_block(msg.payload, "\"mymessage\""); assert_char_mem_block(msg.publisher, "publisher_id"); + assert_char_mem_block(msg.custom_message_type, "test-message-type"); assert_that(msg.region, is_equal_to(4)); assert_that(msg.flags, is_equal_to(514)); diff --git a/core/pubnub_version_internal.h b/core/pubnub_version_internal.h index ecd52c95..2512985b 100644 --- a/core/pubnub_version_internal.h +++ b/core/pubnub_version_internal.h @@ -3,7 +3,7 @@ #define INC_PUBNUB_VERSION_INTERNAL -#define PUBNUB_SDK_VERSION "4.14.1" +#define PUBNUB_SDK_VERSION "4.15.0" #endif /* !defined INC_PUBNUB_VERSION_INTERNAL */ diff --git a/core/samples/publish_queue_callback_subloop.c b/core/samples/publish_queue_callback_subloop.c index 927f41f8..cc8afec5 100644 --- a/core/samples/publish_queue_callback_subloop.c +++ b/core/samples/publish_queue_callback_subloop.c @@ -2,6 +2,7 @@ #include "pubnub_callback.h" #include "core/pubnub_callback_subscribe_loop.h" +#include "core/pubnub_coreapi.h" #include "core/pubnub_timers.h" #include "core/pubnub_helper.h" #include "core/pubnub_log.h" @@ -158,6 +159,11 @@ int main() time_t start = time(NULL); unsigned i = 0; + char* my_env_ipv6_connectivity = getenv("PUBNUB_USE_IPV6_CONNECTIVITY"); + char* my_env_origin = getenv("PUBNUB_ORIGIN"); + if (NULL == my_env_origin) { my_env_origin = "ps.pndsn.com"; } + if (NULL == my_env_ipv6_connectivity) { my_env_ipv6_connectivity = "0"; } + if ((NULL == pbp) || (NULL == pbp_2)) { printf("Failed to allocate Pubnub context(1 or 2)!\n"); return -1; @@ -168,6 +174,17 @@ int main() pubnub_set_user_id(pbp, "demo"); pubnub_set_user_id(pbp_2, "demo_2"); + pubnub_origin_set(pbp, my_env_origin); + pubnub_origin_set(pbp_2, my_env_origin); + +#if PUBNUB_USE_IPV6 + // Enable IPv6 connectivity. + if (0 == strcmp(my_env_ipv6_connectivity, "1")) { + pubnub_set_ipv6_connectivity(pbp); + pubnub_set_ipv6_connectivity(pbp_2); + } +#endif + pubnub_register_callback(pbp_2, publish_callback, (void*)chan); pubnub_mutex_init_static(m_lock); diff --git a/core/samples/pubnub_fetch_history_sample.c b/core/samples/pubnub_fetch_history_sample.c index 03e19fd3..8cfb62b4 100644 --- a/core/samples/pubnub_fetch_history_sample.c +++ b/core/samples/pubnub_fetch_history_sample.c @@ -4,6 +4,7 @@ #if PUBNUB_USE_FETCH_HISTORY #include "core/pubnub_fetch_history.c" #endif +#include "core/pubnub_coreapi_ex.h" #include "core/pubnub_helper.h" #include "core/pubnub_timers.h" @@ -58,9 +59,13 @@ static void publish_on_channels(pubnub_t* pbp) enum pubnub_res res; char msg[100]; sprintf(msg,"\"Hello world from fetch history sample %d !\"", i); - res = pubnub_publish(pbp, + struct pubnub_publish_options opts = pubnub_publish_defopts(); + opts.custom_message_type = "test-message-type"; + + res = pubnub_publish_ex(pbp, m_channel1, - msg); + msg, + opts); if (res == PNR_STARTED) { puts("Await publish"); res = pubnub_await(pbp); @@ -139,6 +144,7 @@ int main(int argc, char* argv[]) m_channel2); struct pubnub_fetch_history_options opt = pubnub_fetch_history_defopts(); + opt.include_custom_message_type = true; opt.include_message_type = true; opt.include_meta = true; res = pubnub_fetch_history(pbp, string_channels, opt); @@ -162,6 +168,10 @@ int main(int argc, char* argv[]) printf("\"meta\" is missing in response."); return 1; } + if (NULL == strstr(response.ptr, "\"custom_message_type\"")) { + printf("\"custom_message_type\" is missing in response."); + return 1; + } } else{ printf("pubnub_fetch_history() failed with code: %d('%s')\n", diff --git a/core/samples/pubnub_publish_via_post_sample.c b/core/samples/pubnub_publish_via_post_sample.c index 4c60bd3d..2ba85c48 100644 --- a/core/samples/pubnub_publish_via_post_sample.c +++ b/core/samples/pubnub_publish_via_post_sample.c @@ -2,6 +2,7 @@ #include "pubnub_sync.h" #include "core/pubnub_coreapi_ex.h" +#include "core/pubnub_coreapi.h" #include "core/pubnub_helper.h" #include "core/pubnub_timers.h" @@ -89,14 +90,25 @@ int main() char* my_env_publish_key = getenv("PUBNUB_PUBLISH_KEY"); char* my_env_subscribe_key = getenv("PUBNUB_SUBSCRIBE_KEY"); char* my_env_secret_key = getenv("PUBNUB_SECRET_KEY"); + char* my_env_ipv6_connectivity = getenv("PUBNUB_USE_IPV6_CONNECTIVITY"); + char* my_env_origin = getenv("PUBNUB_ORIGIN"); if (NULL == my_env_publish_key) { my_env_publish_key = "demo"; } if (NULL == my_env_subscribe_key) { my_env_subscribe_key = "demo"; } if (NULL == my_env_secret_key) { my_env_secret_key = "demo"; } + if (NULL == my_env_origin) { my_env_origin = "ps.pndsn.com"; } + if (NULL == my_env_ipv6_connectivity) { my_env_ipv6_connectivity = "0"; } printf("%s\n%s\n%s\n",my_env_publish_key,my_env_subscribe_key,my_env_secret_key); pubnub_init(pbp, my_env_publish_key, my_env_subscribe_key); pubnub_set_user_id(pbp, user_id); + pubnub_origin_set(pbp, my_env_origin); +#if PUBNUB_USE_IPV6 + // Enable IPv6 connectivity. + if (0 == strcmp(my_env_ipv6_connectivity, "1")) { + pubnub_set_ipv6_connectivity(pbp); + } +#endif pubnub_set_transaction_timeout(pbp, PUBNUB_DEFAULT_NON_SUBSCRIBE_TIMEOUT); diff --git a/cpp/posix_openssl.mk b/cpp/posix_openssl.mk index 12bb230e..5fa51c7e 100644 --- a/cpp/posix_openssl.mk +++ b/cpp/posix_openssl.mk @@ -118,14 +118,36 @@ CFLAGS =-g -I .. -I . -I ../openssl -I ../lib/base64 -Wall -D PUBNUB_THREADSAFE OS := $(shell uname) ifeq ($(OS),Darwin) -SOURCEFILES += ../posix/monotonic_clock_get_time_darwin.c -OBJFILES += monotonic_clock_get_time_darwin.o -LDLIBS=-lpthread -lssl -lcrypto -L/usr/local/opt/openssl/lib -CFLAGS += -I/usr/local/opt/openssl/include + SOURCEFILES += ../posix/monotonic_clock_get_time_darwin.c + OBJFILES += monotonic_clock_get_time_darwin.o + LDLIBS=-lpthread -lssl -lcrypto + + # Ensure OpenSSL paths are set. + OPENSSL_CFLAGS := $(shell pkg-config --cflags openssl 2>/dev/null) + OPENSSL_LIBS := $(shell pkg-config --libs openssl 2>/dev/null) + ifneq ($(OPENSSL_CFLAGS),) + CFLAGS += $(OPENSSL_CFLAGS) + endif + ifneq ($(OPENSSL_LIBS),) + LDLIBS += $(OPENSSL_LIBS) + endif else -SOURCEFILES += ../posix/monotonic_clock_get_time_posix.c -OBJFILES += monotonic_clock_get_time_posix.o -LDLIBS=-lrt -lpthread -lssl -lcrypto + SOURCEFILES += ../posix/monotonic_clock_get_time_posix.c + OBJFILES += monotonic_clock_get_time_posix.o + LDLIBS=-lrt -lpthread -lssl -lcrypto + + ifeq ($(shell test -d "/usr/local/opt/openssl" && echo yes || echo no),yes) + CFLAGS += -I/usr/local/opt/openssl/include + else + # Path on GitHub Action Runner (ubuntu-latest image) + ifeq ($(shell test -d "/usr/include/openssl" && echo yes || echo no),yes) + CFLAGS += -I/usr/include + endif + endif + # Path on GitHub Action Runner (ubuntu-latest image) + ifeq ($(shell test -d "/usr/lib/x86_64-linux-gnu" && echo yes || echo no),yes) + LDLIBS += -L/usr/lib/x86_64-linux-gnu + endif endif diff --git a/lib/sockets/pbpal_resolv_and_connect_sockets.c b/lib/sockets/pbpal_resolv_and_connect_sockets.c index f89e8580..ad4b0517 100644 --- a/lib/sockets/pbpal_resolv_and_connect_sockets.c +++ b/lib/sockets/pbpal_resolv_and_connect_sockets.c @@ -149,6 +149,7 @@ static void get_dns_ip(struct sockaddr* addr) get_default_dns_ip((struct pubnub_ipv4_address*)p); #endif /* PUBNUB_USE_IPV6 */ } +#if PUBNUB_USE_IPV6 if (AF_INET6 == addr->sa_family) { if ((pubnub_get_dns_primary_server_ipv6((struct pubnub_ipv6_address*)pv6) == -1) @@ -158,6 +159,7 @@ static void get_dns_ip(struct sockaddr* addr) get_default_dns_ip((struct pubnub_ipv4_address*)p); } } +#endif } #endif /* PUBNUB_CHANGE_DNS_SERVERS */ #else @@ -295,7 +297,11 @@ try_TCP_connect_spare_address(pb_socket_t* skt, enum pbpal_resolv_n_connect_result rslt = pbpal_resolv_resource_failure; time_t tt = time(NULL); - if (spare_addresses->ipv4_index < spare_addresses->n_ipv4) { + if (spare_addresses->ipv4_index < spare_addresses->n_ipv4 +#if PUBNUB_USE_IPV6 + && !options->ipv6_connectivity +#endif /* PUBNUB_USE_IPV6 */ + ) { PUBNUB_LOG_TRACE( "spare_addresses->ipv4_index = %d, spare_addresses->n_ipv4 = %d.\n", spare_addresses->ipv4_index, @@ -408,10 +414,18 @@ enum pbpal_resolv_n_connect_result pbpal_resolv_and_connect(pubnub_t* pb) #ifdef PUBNUB_CALLBACK_API sockaddr_inX_t dest = { 0 }; +#if PUBNUB_USE_IPV6 + const bool has_ipv6_proxy = 0 != pb->proxy_ipv6_address.ipv6[0] + || 0 != pb->proxy_ipv6_address.ipv6[1]; +#endif /* PUBNUB_USE_IPV6 */ prepare_port_and_hostname(pb, &port, &origin); #if PUBNUB_PROXY_API - if (0 != pb->proxy_ipv4_address.ipv4[0]) { + if (0 != pb->proxy_ipv4_address.ipv4[0] +#if PUBNUB_USE_IPV6 + && (!pb->options.ipv6_connectivity || !has_ipv6_proxy) +#endif /* PUBNUB_USE_IPV6 */ + ) { struct sockaddr_in dest = { 0 }; PUBNUB_LOG_TRACE("(0 != pb->proxy_ipv4_address.ipv4[0]) - "); memcpy(&(dest.sin_addr.s_addr), @@ -422,8 +436,7 @@ enum pbpal_resolv_n_connect_result pbpal_resolv_and_connect(pubnub_t* pb) &pb->pal.socket, &pb->options, (struct sockaddr*)&dest, port); } #if PUBNUB_USE_IPV6 - else if ((0 != pb->proxy_ipv6_address.ipv6[0]) - || (0 != pb->proxy_ipv6_address.ipv6[1])) { + if (has_ipv6_proxy) { struct sockaddr_in6 dest = { 0 }; PUBNUB_LOG_TRACE("(0 != pb->proxy_ipv6_address.ipv6[0]) ||" " (0 != pb->proxy_ipv6_address.ipv6[1]) - "); @@ -469,7 +482,7 @@ enum pbpal_resolv_n_connect_result pbpal_resolv_and_connect(pubnub_t* pb) #endif return pbpal_resolv_failed_send; } - else if (error > 0) { + if (error > 0) { return pbpal_resolv_send_wouldblock; } pb->flags.sent_queries++; @@ -495,28 +508,41 @@ enum pbpal_resolv_n_connect_result pbpal_resolv_and_connect(pubnub_t* pb) if (error != 0) { return pbpal_resolv_failed_processing; } +#if PUBNUB_USE_IPV6 + for (int pass = 0; pass < 2; ++pass) { + bool prioritize_ipv6 = pass == 0 && pb->options.ipv6_connectivity; +#endif /* PUBNUB_USE_IPV6 */ - for (it = result; it != NULL; it = it->ai_next) { - pb->pal.socket = socket(it->ai_family, it->ai_socktype, it->ai_protocol); - if (pb->pal.socket == SOCKET_INVALID) { - continue; - } - pbpal_set_blocking_io(pb); - if (connect(pb->pal.socket, it->ai_addr, it->ai_addrlen) == SOCKET_ERROR) { - if (socket_would_block()) { - error = 1; - break; - } - else { - PUBNUB_LOG_WARNING("socket connect() failed, will try another " - "IP address, if available\n"); - socket_close(pb->pal.socket); - pb->pal.socket = SOCKET_INVALID; + for (it = result; it != NULL; it = it->ai_next) { +#if PUBNUB_USE_IPV6 + if (prioritize_ipv6 && it->ai_family != AF_INET6) { continue; } + if (!prioritize_ipv6 && it->ai_family != AF_INET) { continue; } +#endif /* PUBNUB_USE_IPV6 */ + + pb->pal.socket = + socket(it->ai_family, it->ai_socktype, it->ai_protocol); + if (pb->pal.socket == SOCKET_INVALID) { continue; } + pbpal_set_blocking_io(pb); + if (connect(pb->pal.socket, it->ai_addr, it->ai_addrlen) == SOCKET_ERROR) { + if (socket_would_block()) { + error = 1; + break; + } + else { + PUBNUB_LOG_WARNING("socket connect() failed, will try " + "another IP address, if available\n"); + socket_close(pb->pal.socket); + pb->pal.socket = SOCKET_INVALID; + continue; + } + } + break; } - break; +#if PUBNUB_USE_IPV6 } +#endif /* PUBNUB_USE_IPV6 */ freeaddrinfo(result); if (NULL == it) { diff --git a/microchip_harmony/pbpal_resolv_and_connect_harmony_tcp.c b/microchip_harmony/pbpal_resolv_and_connect_harmony_tcp.c index b5f26af8..c754cb92 100644 --- a/microchip_harmony/pbpal_resolv_and_connect_harmony_tcp.c +++ b/microchip_harmony/pbpal_resolv_and_connect_harmony_tcp.c @@ -13,7 +13,13 @@ enum pbpal_resolv_n_connect_result pbpal_resolv_and_connect(pubnub_t *pb) { char const* origin = PUBNUB_ORIGIN_SETTABLE ? pb->origin : PUBNUB_ORIGIN; - TCPIP_DNS_RESULT dns_result = TCPIP_DNS_Resolve(origin, TCPIP_DNS_TYPE_A); +#if PUBNUB_USE_IPV6 + TCPIP_DNS_RESOLVE_TYPE query_type = + pb->options.ipv6_connectivity ? TCPIP_DNS_TYPE_AAAA : TCPIP_DNS_TYPE_A; +#else + TCPIP_DNS_RESOLVE_TYPE query_type = TCPIP_DNS_TYPE_A; +#endif + TCPIP_DNS_RESULT dns_result = TCPIP_DNS_Resolve(origin, query_type); PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); PUBNUB_ASSERT((pb->state == PBS_IDLE) || (pb->state == PBS_WAIT_DNS_SEND) || (pb->state == PBS_WAIT_DNS_RCV)); @@ -41,8 +47,14 @@ enum pbpal_resolv_n_connect_result pbpal_resolv_and_connect(pubnub_t *pb) enum pbpal_resolv_n_connect_result pbpal_check_resolv_and_connect(pubnub_t *pb) { char const* origin = PUBNUB_ORIGIN_SETTABLE ? pb->origin : PUBNUB_ORIGIN; +#if PUBNUB_USE_IPV6 + IP_ADDRESS_TYPE address_type = + pb->options.ipv6_connectivity ? IP_ADDRESS_TYPE_IPV6 : IP_ADDRESS_TYPE_IPV4; +#else + IP_ADDRESS_TYPE address_type = IP_ADDRESS_TYPE_IPV4; +#endif IP_MULTI_ADDRESS ip_addr; - TCPIP_DNS_RESULT dns_result = TCPIP_DNS_IsResolved(origin, &ip_addr, IP_ADDRESS_TYPE_IPV4); + TCPIP_DNS_RESULT dns_result = TCPIP_DNS_IsResolved(origin, &ip_addr, address_type); PUBNUB_ASSERT_OPT(pb != NULL); switch (dns_result) { case TCPIP_DNS_RES_OK: @@ -51,12 +63,12 @@ enum pbpal_resolv_n_connect_result pbpal_check_resolv_and_connect(pubnub_t *pb) pb->pal.socket = NET_PRES_SocketOpen( 0, pb->options.useSSL ? NET_PRES_SKT_ENCRYPTED_STREAM_CLIENT : NET_PRES_SKT_UNENCRYPTED_STREAM_CLIENT, - IP_ADDRESS_TYPE_IPV4, + address_type, HTTPS_PORT, (NET_PRES_ADDRESS*)&ip_addr, NULL ); #else - pb->pal.socket = TCPIP_TCP_ClientOpen(IP_ADDRESS_TYPE_IPV4, HTTP_PORT, &ip_addr); + pb->pal.socket = TCPIP_TCP_ClientOpen(address_type, HTTP_PORT, &ip_addr); #endif } if (SOCKET_INVALID == pb->pal.socket) { diff --git a/openssl/posix.mk b/openssl/posix.mk index 445d083b..5f96541f 100644 --- a/openssl/posix.mk +++ b/openssl/posix.mk @@ -58,6 +58,14 @@ ifndef USE_CRYPTO_API USE_CRYPTO_API = 1 endif +ifndef USE_IPV6 +USE_IPV6 = 1 +endif + +ifndef USE_DNS_SERVERS +USE_DNS_SERVERS = 1 +endif + ifeq ($(USE_PROXY), 1) SOURCEFILES += ../core/pubnub_proxy.c ../core/pubnub_proxy_core.c ../core/pbhttp_digest.c ../core/pbntlm_core.c ../core/pbntlm_packer_std.c OBJFILES += pubnub_proxy.o pubnub_proxy_core.o pbhttp_digest.o pbntlm_core.o pbntlm_packer_std.o @@ -125,43 +133,61 @@ CFLAGS = -g -D PUBNUB_THREADSAFE -D PUBNUB_LOG_LEVEL=PUBNUB_LOG_LEVEL_WARNING -W OS := $(shell uname) ifeq ($(OS),Darwin) -SOURCEFILES += ../posix/monotonic_clock_get_time_darwin.c -OBJFILES += monotonic_clock_get_time_darwin.o -LDLIBS = -lpthread -lssl -lcrypto -L/usr/local/opt/openssl/lib -CFLAGS += -I/usr/local/opt/openssl/include + SOURCEFILES += ../posix/monotonic_clock_get_time_darwin.c + OBJFILES += monotonic_clock_get_time_darwin.o + LDLIBS = -lpthread -lssl -lcrypto + + # Ensure OpenSSL paths are set. + OPENSSL_CFLAGS := $(shell pkg-config --cflags openssl 2>/dev/null) + OPENSSL_LIBS := $(shell pkg-config --libs openssl 2>/dev/null) + ifneq ($(OPENSSL_CFLAGS),) + CFLAGS += $(OPENSSL_CFLAGS) + endif + ifneq ($(OPENSSL_LIBS),) + LDLIBS += $(OPENSSL_LIBS) + endif else -SOURCEFILES += ../posix/monotonic_clock_get_time_posix.c -OBJFILES += monotonic_clock_get_time_posix.o -LDLIBS=-lrt -lpthread -lssl -lcrypto + SOURCEFILES += ../posix/monotonic_clock_get_time_posix.c + OBJFILES += monotonic_clock_get_time_posix.o + LDLIBS=-lrt -lpthread -lssl -lcrypto + + ifeq ($(shell test -d "/usr/local/opt/openssl" && echo yes || echo no),yes) + CFLAGS += -I/usr/local/opt/openssl/include + else + # Path on GitHub Action Runner (ubuntu-latest image) + ifeq ($(shell test -d "/usr/include/openssl" && echo yes || echo no),yes) + CFLAGS += -I/usr/include + endif + endif + # Path on GitHub Action Runner (ubuntu-latest image) + ifeq ($(shell test -d "/usr/lib/x86_64-linux-gnu" && echo yes || echo no),yes) + LDLIBS += -L/usr/lib/x86_64-linux-gnu + endif endif - INCLUDES=-I .. -I . -I ../lib/base64/ - all: pubnub_sync_sample pubnub_sync_grant_token_sample pubnub_sync_revoke_token_sample pubnub_objects_secretkey_sample metadata cancel_subscribe_sync_sample pubnub_sync_subloop_sample pubnub_publish_via_post_sample pubnub_publish_via_post_secretkey_sample pubnub_advanced_history_sample pubnub_fetch_history_sample pubnub_callback_sample subscribe_publish_callback_sample pubnub_callback_subloop_sample pubnub_fntest pubnub_console_sync pubnub_console_callback pubnub_crypto_sync_sample subscribe_publish_from_callback publish_callback_subloop_sample publish_queue_callback_subloop pubnub_crypto_module_sample SYNC_INTF_SOURCEFILES=../core/pubnub_ntf_sync.c ../core/pubnub_sync_subscribe_loop.c ../core/srand_from_pubnub_time.c SYNC_INTF_OBJFILES=pubnub_ntf_sync.o pubnub_sync_subscribe_loop.o srand_from_pubnub_time.o +ifeq ($(USE_IPV6), 1) +SYNC_INTF_SOURCEFILES += ../lib/pubnub_parse_ipv6_addr.c +SYNC_INTF_OBJFILES += pubnub_parse_ipv6_addr.o +endif + pubnub_sync.a : $(SOURCEFILES) $(SYNC_INTF_SOURCEFILES) $(REVOKE_TOKEN_SOURCEFILES) $(GRANT_TOKEN_SOURCEFILES) - $(CC) -c $(CFLAGS) -D PUBNUB_RAND_INIT_VECTOR=0 $(INCLUDES) $(SOURCEFILES) $(SYNC_INTF_SOURCEFILES) $(REVOKE_TOKEN_SOURCEFILES) $(GRANT_TOKEN_SOURCEFILES) + $(CC) -c $(CFLAGS) -D PUBNUB_USE_IPV6=$(USE_IPV6) -D PUBNUB_RAND_INIT_VECTOR=0 $(INCLUDES) $(SOURCEFILES) $(SYNC_INTF_SOURCEFILES) $(REVOKE_TOKEN_SOURCEFILES) $(GRANT_TOKEN_SOURCEFILES) ar rcs pubnub_sync.a $(OBJFILES) $(SYNC_INTF_OBJFILES) $(REVOKE_TOKEN_OBJFILES) $(GRANT_TOKEN_OBJFILES) pubnub_sync_dynamiciv.a : $(SOURCEFILES) $(SYNC_INTF_SOURCEFILES) $(REVOKE_TOKEN_SOURCEFILES) $(GRANT_TOKEN_SOURCEFILES) - $(CC) -c $(CFLAGS) -D PUBNUB_RAND_INIT_VECTOR=1 $(INCLUDES) $(SOURCEFILES) $(SYNC_INTF_SOURCEFILES) $(REVOKE_TOKEN_SOURCEFILES) $(GRANT_TOKEN_SOURCEFILES) + $(CC) -c $(CFLAGS) -D PUBNUB_USE_IPV6=$(USE_IPV6) -D PUBNUB_RAND_INIT_VECTOR=1 $(INCLUDES) $(SOURCEFILES) $(SYNC_INTF_SOURCEFILES) $(REVOKE_TOKEN_SOURCEFILES) $(GRANT_TOKEN_SOURCEFILES) ar rcs pubnub_sync_dynamiciv.a $(OBJFILES) $(SYNC_INTF_OBJFILES) $(REVOKE_TOKEN_OBJFILES) $(GRANT_TOKEN_OBJFILES) CALLBACK_INTF_SOURCEFILES=pubnub_ntf_callback_posix.c pubnub_get_native_socket.c ../core/pubnub_timer_list.c ../lib/sockets/pbpal_ntf_callback_poller_poll.c ../lib/sockets/pbpal_adns_sockets.c ../lib/pubnub_dns_codec.c ../core/pbpal_ntf_callback_queue.c ../core/pbpal_ntf_callback_admin.c ../core/pbpal_ntf_callback_handle_timer_list.c ../core/pubnub_callback_subscribe_loop.c CALLBACK_INTF_OBJFILES=pubnub_ntf_callback_posix.o pubnub_get_native_socket.o pubnub_timer_list.o pbpal_ntf_callback_poller_poll.o pbpal_adns_sockets.o pubnub_dns_codec.o pbpal_ntf_callback_queue.o pbpal_ntf_callback_admin.o pbpal_ntf_callback_handle_timer_list.o pubnub_callback_subscribe_loop.o -ifndef USE_DNS_SERVERS -USE_DNS_SERVERS = 1 -endif - -ifndef USE_IPV6 -USE_IPV6 = 1 -endif ifeq ($(USE_DNS_SERVERS), 1) CALLBACK_INTF_SOURCEFILES += ../core/pubnub_dns_servers.c ../posix/pubnub_dns_system_servers.c ../lib/pubnub_parse_ipv4_addr.c @@ -216,7 +242,7 @@ pubnub_sync_subloop_sample: ../core/samples/pubnub_sync_subloop_sample.c pubnub_ $(CC) -o $@ $(CFLAGS) $(INCLUDES) ../core/samples/pubnub_sync_subloop_sample.c pubnub_sync.a $(LDLIBS) pubnub_publish_via_post_sample: ../core/samples/pubnub_publish_via_post_sample.c pubnub_sync.a - $(CC) -o $@ $(CFLAGS) $(INCLUDES) ../core/samples/pubnub_publish_via_post_sample.c pubnub_sync.a $(LDLIBS) + $(CC) -o $@ $(CFLAGS) -D PUBNUB_USE_IPV6=$(USE_IPV6) $(INCLUDES) ../core/samples/pubnub_publish_via_post_sample.c pubnub_sync.a $(LDLIBS) pubnub_publish_via_post_secretkey_sample: ../core/samples/pubnub_publish_via_post_secretkey_sample.c pubnub_sync.a $(CC) -o $@ $(CFLAGS) $(INCLUDES) ../core/samples/pubnub_publish_via_post_secretkey_sample.c pubnub_sync.a $(LDLIBS) @@ -243,7 +269,7 @@ publish_callback_subloop_sample: ../core/samples/publish_callback_subloop_sample $(CC) -o $@ -D PUBNUB_CALLBACK_API $(CFLAGS) $(CFLAGS_CALLBACK) $(INCLUDES) ../core/samples/publish_callback_subloop_sample.c pubnub_callback.a $(LDLIBS) publish_queue_callback_subloop: ../core/samples/publish_queue_callback_subloop.c pubnub_callback.a - $(CC) -o $@ -D PUBNUB_CALLBACK_API $(CFLAGS) $(CFLAGS_CALLBACK) $(INCLUDES) ../core/samples/publish_queue_callback_subloop.c pubnub_callback.a $(LDLIBS) + $(CC) -o $@ -D PUBNUB_CALLBACK_API $(CFLAGS) -D PUBNUB_USE_IPV6=$(USE_IPV6) $(CFLAGS_CALLBACK) $(INCLUDES) ../core/samples/publish_queue_callback_subloop.c pubnub_callback.a $(LDLIBS) pubnub_crypto_module_sample: ../core/samples/pubnub_crypto_module_sample.c pubnub_sync.a $(CC) -o $@ $(CFLAGS) $(INCLUDES) -I ../core/ ../core/samples/pubnub_crypto_module_sample.c pubnub_sync.a $(LDLIBS) diff --git a/posix/posix.mk b/posix/posix.mk index 80cc008a..0a1cab5f 100644 --- a/posix/posix.mk +++ b/posix/posix.mk @@ -58,6 +58,14 @@ ifndef USE_FETCH_HISTORY USE_FETCH_HISTORY = 1 endif +ifndef USE_IPV6 +USE_IPV6 = 1 +endif + +ifndef USE_DNS_SERVERS +USE_DNS_SERVERS = 1 +endif + ifeq ($(USE_PROXY), 1) SOURCEFILES += ../core/pubnub_proxy.c ../core/pubnub_proxy_core.c ../core/pbhttp_digest.c ../core/pbntlm_core.c ../core/pbntlm_packer_std.c OBJFILES += pubnub_proxy.o pubnub_proxy_core.o pbhttp_digest.o pbntlm_core.o pbntlm_packer_std.o @@ -136,20 +144,18 @@ all: pubnub_sync_sample metadata cancel_subscribe_sync_sample pubnub_advanced_hi SYNC_INTF_SOURCEFILES=../core/pubnub_ntf_sync.c ../core/pubnub_sync_subscribe_loop.c ../core/srand_from_pubnub_time.c SYNC_INTF_OBJFILES=pubnub_ntf_sync.o pubnub_sync_subscribe_loop.o srand_from_pubnub_time.o +ifeq ($(USE_IPV6), 1) +SYNC_INTF_SOURCEFILES += ../lib/pubnub_parse_ipv6_addr.c +SYNC_INTF_OBJFILES += pubnub_parse_ipv6_addr.o +endif + pubnub_sync.a : $(SOURCEFILES) $(SYNC_INTF_SOURCEFILES) - $(CC) -c $(CFLAGS) $(INCLUDES) $(SOURCEFILES) $(SYNC_INTF_SOURCEFILES) + $(CC) -c $(CFLAGS) -D PUBNUB_USE_IPV6=$(USE_IPV6) $(INCLUDES) $(SOURCEFILES) $(SYNC_INTF_SOURCEFILES) ar rcs pubnub_sync.a $(OBJFILES) $(SYNC_INTF_OBJFILES) CALLBACK_INTF_SOURCEFILES=pubnub_ntf_callback_posix.c pubnub_get_native_socket.c ../core/pubnub_timer_list.c ../lib/sockets/pbpal_ntf_callback_poller_poll.c ../lib/sockets/pbpal_adns_sockets.c ../lib/pubnub_dns_codec.c ../core/pbpal_ntf_callback_queue.c ../core/pbpal_ntf_callback_admin.c ../core/pbpal_ntf_callback_handle_timer_list.c ../core/pubnub_callback_subscribe_loop.c CALLBACK_INTF_OBJFILES=pubnub_ntf_callback_posix.o pubnub_get_native_socket.o pubnub_timer_list.o pbpal_ntf_callback_poller_poll.o pbpal_adns_sockets.o pubnub_dns_codec.o pbpal_ntf_callback_queue.o pbpal_ntf_callback_admin.o pbpal_ntf_callback_handle_timer_list.o pubnub_callback_subscribe_loop.o -ifndef USE_DNS_SERVERS -USE_DNS_SERVERS = 1 -endif - -ifndef USE_IPV6 -USE_IPV6 = 1 -endif ifeq ($(USE_DNS_SERVERS), 1) CALLBACK_INTF_SOURCEFILES += ../core/pubnub_dns_servers.c ../posix/pubnub_dns_system_servers.c ../lib/pubnub_parse_ipv4_addr.c @@ -183,7 +189,7 @@ pubnub_sync_publish_retry: ../core/samples/pubnub_sync_publish_retry.c pubnub_sy $(CC) -o $@ $(CFLAGS) $(INCLUDES) ../core/samples/pubnub_sync_publish_retry.c pubnub_sync.a $(LDLIBS) pubnub_publish_via_post_sample: ../core/samples/pubnub_publish_via_post_sample.c pubnub_sync.a - $(CC) -o $@ $(CFLAGS) $(INCLUDES) ../core/samples/pubnub_publish_via_post_sample.c pubnub_sync.a $(LDLIBS) + $(CC) -o $@ $(CFLAGS) -D PUBNUB_USE_IPV6=$(USE_IPV6) $(INCLUDES) ../core/samples/pubnub_publish_via_post_sample.c pubnub_sync.a $(LDLIBS) pubnub_advanced_history_sample: ../core/samples/pubnub_advanced_history_sample.c pubnub_sync.a $(CC) -o $@ $(CFLAGS) $(INCLUDES) ../core/samples/pubnub_advanced_history_sample.c pubnub_sync.a $(LDLIBS) @@ -214,7 +220,7 @@ publish_callback_subloop_sample: ../core/samples/publish_callback_subloop_sample $(CC) -o $@ -D PUBNUB_CALLBACK_API $(CFLAGS) $(CFLAGS_CALLBACK) $(INCLUDES) ../core/samples/publish_callback_subloop_sample.c pubnub_callback.a $(LDLIBS) publish_queue_callback_subloop: ../core/samples/publish_queue_callback_subloop.c pubnub_callback.a - $(CC) -o $@ -D PUBNUB_CALLBACK_API $(CFLAGS) $(CFLAGS_CALLBACK) $(INCLUDES) ../core/samples/publish_queue_callback_subloop.c pubnub_callback.a $(LDLIBS) + $(CC) -o $@ -D PUBNUB_CALLBACK_API $(CFLAGS) -D PUBNUB_USE_IPV6=$(USE_IPV6) $(CFLAGS_CALLBACK) $(INCLUDES) ../core/samples/publish_queue_callback_subloop.c pubnub_callback.a $(LDLIBS) pubnub_fntest: ../core/fntest/pubnub_fntest.c ../core/fntest/pubnub_fntest_basic.c ../core/fntest/pubnub_fntest_medium.c fntest/pubnub_fntest_posix.c fntest/pubnub_fntest_runner.c pubnub_sync.a $(CC) -o $@ $(CFLAGS) $(INCLUDES) ../core/fntest/pubnub_fntest.c ../core/fntest/pubnub_fntest_basic.c ../core/fntest/pubnub_fntest_medium.c fntest/pubnub_fntest_posix.c fntest/pubnub_fntest_runner.c pubnub_sync.a $(LDLIBS) -lpthread