Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package belle-sip for openSUSE:Factory checked in at 2023-01-04 17:53:27 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/belle-sip (Old) and /work/SRC/openSUSE:Factory/.belle-sip.new.1563 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "belle-sip" Wed Jan 4 17:53:27 2023 rev:32 rq:1055795 version:5.2.6 Changes: -------- --- /work/SRC/openSUSE:Factory/belle-sip/belle-sip.changes 2022-12-05 18:02:20.308953182 +0100 +++ /work/SRC/openSUSE:Factory/.belle-sip.new.1563/belle-sip.changes 2023-01-04 17:53:40.074558310 +0100 @@ -1,0 +2,9 @@ +Wed Jan 4 11:26:35 UTC 2023 - Paolo Stivanin <i...@paolostivanin.com> + +- Update to 5.2.6: + * Support for authentication headers with multiple challenges. + * Fixed various weaknesses within multipart decoding process. + * Fixed endless UDP transaction in a specific scenario. + * Fixed various crashes. + +------------------------------------------------------------------- Old: ---- belle-sip-5.1.72.tar.bz2 New: ---- belle-sip-5.2.6.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ belle-sip.spec ++++++ --- /var/tmp/diff_new_pack.ElkTgR/_old 2023-01-04 17:53:40.786562506 +0100 +++ /var/tmp/diff_new_pack.ElkTgR/_new 2023-01-04 17:53:40.790562529 +0100 @@ -1,7 +1,7 @@ # # spec file for package belle-sip # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # Copyright (c) 2014 Mariusz Fik <fi...@opensuse.org>. # # All modifications and additions to the file contributed by third parties @@ -20,7 +20,7 @@ %define soname libbellesip %define sover 1 Name: belle-sip -Version: 5.1.72 +Version: 5.2.6 Release: 0 Summary: C object-oriented SIP Stack License: GPL-3.0-or-later @@ -33,7 +33,7 @@ BuildRequires: cmake BuildRequires: gcc-c++ BuildRequires: pkgconfig -BuildRequires: pkgconfig(bctoolbox) >= 5.0.0 +BuildRequires: pkgconfig(bctoolbox) >= 5.2.0 BuildRequires: pkgconfig(zlib) %description ++++++ belle-sip-5.1.72.tar.bz2 -> belle-sip-5.2.6.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/.github/ISSUE_TEMPLATE/bug_report.yml new/belle-sip-5.2.6/.github/ISSUE_TEMPLATE/bug_report.yml --- old/belle-sip-5.1.72/.github/ISSUE_TEMPLATE/bug_report.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/belle-sip-5.2.6/.github/ISSUE_TEMPLATE/bug_report.yml 2022-11-04 17:46:39.000000000 +0100 @@ -0,0 +1,131 @@ +--- +name: Bug report +description: File a bug/issue +title: "[Bug]: " +labels: ["bug"] + +body: +- type: markdown + attributes: + value: '# Reminder' +- type: markdown + attributes: + value: | + The responses are provided by the **community** and, on a **best effort** basis, by some Belledonne Communications SARL engineers working on Linphone and its related projects. + The community means any people all around the world simply willing to participate to the discussions. + + Belledonne Communications SARL **disclaims any WARRANTY** that the content posted on github issues or mailing lists is technically correct. + Responses from Belledonne Communications SARL engineers shall be considered as individual contributions and shall not be seen as Belledonne Communications's official point of view or commitment. + + The Github issue tracker must be seen as a place for **collaboration**. Issues submitted should be of general interest, in the goal of improving the software. Consider that a **well documented** issue (with precise reproduction procedure, logs, stack trace if relevant, possibly a corrective patch) has a higher chance to receive interest and feedback from community members and Belledonne Communications' engineers. + + __Issues poorly documented, with no facts, or asking for debugging assistance for a custom app using Linphone's libraries, or for a modified version of Linphone are unlikely to receive any kind of response.__ + + People using Linphone or its related projects within the scope of their company job are invited to contact [Belledonne Communications](https://linphone.org/contact#content-bottom3) in order to obtain commercial support. + +- type: markdown + attributes: + value: | + # Well ordered issues are treated issues + **In our apps, the [Linphone-SDK](https://github.com/BelledonneCommunications/linphone-sdk) is used.** + Please report your issue here **ONLY** if you are sure that the origin of the error is in this module. + Otherwise, open an issue in the repository of the app you are using or in the Linphone-SDK, and we will move it to the related module. + +- type: markdown + attributes: + value: | + # Useful links + [Linphone.org](https://linphone.org) + [Linphone commercial contact](https://linphone.org/contact#content-bottom3) + Linphone Vulnerability/Security contact: vulnerabilit...@linphone.org + [Contributor agreement (to sign and to return to sa...@belledonne-communications.com for a pull request)](https://linphone.org/sites/default/files/bc-contributor-agreement_0.pdf) + +- type: textarea + attributes: + label: | + Context + description: | + - For which purpose do you use the project ? + - With which software/hardware it is integrated ? + - Did you use sip.linphone.org or a different SIP service (in this case specify which one and which version) ? + value: | + I use this project in a custom app running on Linux with the sip.linphone.org service for my company. I want to do a simple call between an Android phone and a Linux client. There is an error with a method of this project and I'm sure that I followed the documentation and double checked before posting. + validations: + required: true + +- type: textarea + attributes: + label: General information + description: | + Complete it multiple time if there are multiple devices involved. + Please note that the issue has more chances to be read if you report a bug seen in the latest version of the module. + + Ex: + - Device: [e.g. Samsung Note 20 Ultra] + - OS: [e.g. Android 11] + - Version of the App [e.g. 4.3.1] + - Version of the SDK [e.g 4.4.16] + value: | + - Device: + - OS: + - Version of the App: + - Version of the SDK: + validations: + required: true + +- type: textarea + attributes: + label: Expected behaviour + description: "A clear and concise description of what you expected to happen." + value: | + I wanted to do a simple call with the Linux client calling the Android phone. However, the phone doesn't ring when it is asleep. + validations: + required: true + +- type: textarea + attributes: + label: To Reproduce + description: "Steps to reproduce the behavior:" + value: | + 1. Go to '...' + 2. Click on '....' + 3. Scroll down to '....' + 4. See error + validations: + required: true + +- type: textarea + attributes: + label: 'Additional context' + value: Add any other context about the problem here. + +- type: markdown + attributes: + value: | + # Logs + ## Module logs + Enable debug logs in advanced section of the settings, restart the app, reproduce the issue and then go to About page, click on "Send logs" and copy/paste the link here. + If you doesn't have such an option, just provide the logs in attachments. + +- type: input + attributes: + label: 'SDK logs URL' + +- type: markdown + attributes: + value: | + ## Module crash logs + In case of a crash related to this module, please also provide the backtrace of the crash in attachments using adb logcat (Android) or the device console (iOS). + For desktop versions, you can get the backtrace from a core dump. + +- type: markdown + attributes: + value: | + # Screenshots + Please add screenshots in attachments to help us to understand your problem. + +- type: markdown + attributes: + value: | + # Pcap file + If this is a network issue, join a pcap file of your attempt in attachments (done with Wireshark or TCPDump, for example) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/CHANGELOG.md new/belle-sip-5.2.6/CHANGELOG.md --- old/belle-sip-5.1.72/CHANGELOG.md 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/CHANGELOG.md 2022-11-04 17:46:39.000000000 +0100 @@ -6,6 +6,18 @@ ## [Unreleased] +## [5.2.0] - 2022-11-07 + +## Added +- Support for authentication headers with multiple challenges. + +## Fixed +- various weaknesses within multipart decoding process. +- endless UDP transaction in a specific scenario. +- crash on iOS 16 because of kCFStreamNetworkServiceTypeVoIP that no longer works. +- crashes. + + ## [5.1.0] - 2022-02-14 ### Fixed diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/CMakeLists.txt new/belle-sip-5.2.6/CMakeLists.txt --- old/belle-sip-5.1.72/CMakeLists.txt 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/CMakeLists.txt 2022-11-04 17:46:39.000000000 +0100 @@ -28,7 +28,7 @@ cmake_policy(SET CMP0077 NEW) endif() -project(belle-sip VERSION 5.1.0 LANGUAGES C CXX) +project(belle-sip VERSION 5.2.0 LANGUAGES C CXX) set(PACKAGE "${PROJECT_NAME}") set(PACKAGE_NAME "${PROJECT_NAME}") @@ -201,7 +201,7 @@ endif() if(ENABLE_STRICT) list(APPEND STRICT_OPTIONS_CPP "-Werror" "-Wextra" "-Wno-unused-parameter" "-Wno-error=unknown-pragmas" "-Wuninitialized" "-fno-strict-aliasing") - list(APPEND STRICT_OPTIONS_C " -Wno-missing-field-initializers" "-Wno-error=unused-result" ) + list(APPEND STRICT_OPTIONS_C " -Wno-missing-field-initializers" "-Wno-error=unused-result" "-Wno-cast-function-type") endif() # this warning is generated by antlr so ignore it for now list(APPEND STRICT_OPTIONS_C "-Wno-error=sign-compare") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/include/belle-sip/belle-sdp.h new/belle-sip-5.2.6/include/belle-sip/belle-sdp.h --- old/belle-sip-5.1.72/include/belle-sip/belle-sdp.h 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/include/belle-sip/belle-sdp.h 2022-11-04 17:46:39.000000000 +0100 @@ -453,10 +453,10 @@ BELLESIP_EXPORT belle_sdp_time_t* belle_sdp_time_new(void); BELLESIP_EXPORT belle_sdp_time_t* belle_sdp_time_parse (const char* time); -BELLESIP_EXPORT int belle_sdp_time_get_start(const belle_sdp_time_t* time); -BELLESIP_EXPORT int belle_sdp_time_get_stop(const belle_sdp_time_t* time); -BELLESIP_EXPORT void belle_sdp_time_set_start(belle_sdp_time_t* time, int value); -BELLESIP_EXPORT void belle_sdp_time_set_stop(belle_sdp_time_t* time, int value); +BELLESIP_EXPORT long long belle_sdp_time_get_start(const belle_sdp_time_t* time); +BELLESIP_EXPORT long long belle_sdp_time_get_stop(const belle_sdp_time_t* time); +BELLESIP_EXPORT void belle_sdp_time_set_start(belle_sdp_time_t* time, long long value); +BELLESIP_EXPORT void belle_sdp_time_set_stop(belle_sdp_time_t* time, long long value); #define BELLE_SDP_TIME(t) BELLE_SDP_CAST(t,belle_sdp_time_t) /*************************************************************************************** @@ -466,7 +466,7 @@ typedef struct _belle_sdp_time_description belle_sdp_time_description_t; BELLESIP_EXPORT belle_sdp_time_description_t* belle_sdp_time_description_new(void); BELLESIP_EXPORT belle_sdp_time_description_t* belle_sdp_time_description_parse (const char* time_description); -BELLESIP_EXPORT belle_sdp_time_description_t* belle_sdp_time_description_create (int start, int stop); +BELLESIP_EXPORT belle_sdp_time_description_t* belle_sdp_time_description_create (long long start, long long stop); BELLESIP_EXPORT belle_sip_list_t* belle_sdp_time_description_get_repeate_times(const belle_sdp_time_description_t* time_description); BELLESIP_EXPORT belle_sdp_time_t* belle_sdp_time_description_get_time(const belle_sdp_time_description_t* time_description); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/include/belle-sip/dialog.h new/belle-sip-5.2.6/include/belle-sip/dialog.h --- old/belle-sip-5.1.72/include/belle-sip/dialog.h 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/include/belle-sip/dialog.h 2022-11-04 17:46:39.000000000 +0100 @@ -29,16 +29,30 @@ typedef enum belle_sip_dialog_state belle_sip_dialog_state_t; +enum belle_sip_dialog_termination_cause{ + BELLE_SIP_DIALOG_TERMINATION_CAUSE_NORMAL, + BELLE_SIP_DIALOG_TERMINATION_CAUSE_ABORT_NO_ACK +}; + +typedef enum belle_sip_dialog_termination_cause belle_sip_dialog_termination_cause_t; + BELLE_SIP_BEGIN_DECLS BELLESIP_EXPORT const char* belle_sip_dialog_state_to_string(const belle_sip_dialog_state_t state); BELLESIP_EXPORT belle_sip_request_t *belle_sip_dialog_create_ack(belle_sip_dialog_t *dialog, unsigned int cseq); +BELLESIP_EXPORT bool_t belle_sip_dialog_can_create_asynchronous_request(belle_sip_dialog_t *obj, const char *method); + +BELLESIP_EXPORT bool_t belle_sip_dialog_can_create_synchronous_request(belle_sip_dialog_t *obj, const char *method); + /** * Create a request part of this dialog. + * @param dialog dialog associated to the request + * @param method method of the request **/ BELLESIP_EXPORT belle_sip_request_t *belle_sip_dialog_create_request(belle_sip_dialog_t *dialog, const char *method); + /** * Create a request within a dialog keeping non system header from an initial request. This function is very useful to resend request after expiration or chalenge. * @param obj dialog associated to the request @@ -50,6 +64,8 @@ /** * Create a new request part of this dialog. If dialog is busy (pending transaction), the request can be created anyway and will be sent by the transaction * when the dialog becomes available. + * @param obj dialog associated to the request + * @param method method of the request **/ BELLESIP_EXPORT belle_sip_request_t * belle_sip_dialog_create_queued_request(belle_sip_dialog_t *obj, const char *method); @@ -90,7 +106,7 @@ BELLESIP_EXPORT belle_sip_dialog_state_t belle_sip_dialog_get_state(const belle_sip_dialog_t *dialog); /** - * return the dialog state before last transition. Can be useful to detect early avorted dialogs + * return the dialog state before last transition. Can be useful to detect early aborted dialogs * @param dialog * @returns state **/ @@ -113,11 +129,18 @@ BELLESIP_EXPORT int belle_sip_dialog_request_pending(const belle_sip_dialog_t *dialog); +BELLESIP_EXPORT int belle_sip_dialog_expired(const belle_sip_dialog_t *dialog); + +BELLESIP_EXPORT int belle_sip_dialog_get_request_retry_timeout(const belle_sip_dialog_t *dialog); + /*for debugging purpose only, allow to disable checking for pending transaction*/ BELLESIP_EXPORT int belle_sip_dialog_pending_trans_checking_enabled( const belle_sip_dialog_t *dialog) ; BELLESIP_EXPORT int belle_sip_dialog_enable_pending_trans_checking(belle_sip_dialog_t *dialog, int value) ; -BELLESIP_EXPORT int belle_sip_dialog_expired(const belle_sip_dialog_t *dialog); +BELLESIP_EXPORT belle_sip_dialog_termination_cause_t belle_sip_dialog_get_termination_cause(const belle_sip_dialog_t *dialog); + +/*for testing purposes only*/ +BELLESIP_EXPORT void belle_sip_dialog_set_simulate_lost_ack_enabled(belle_sip_dialog_t *dialog, int enable); BELLE_SIP_END_DECLS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/include/belle-sip/sip-uri.h new/belle-sip-5.2.6/include/belle-sip/sip-uri.h --- old/belle-sip-5.1.72/include/belle-sip/sip-uri.h 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/include/belle-sip/sip-uri.h 2022-11-04 17:46:39.000000000 +0100 @@ -281,21 +281,14 @@ return h; } }; -} - -#include <functional> -namespace bellesip { - -struct UriComparator : public std::binary_function<belle_sip_uri_t*, belle_sip_uri_t*, bool> { - bool operator()(const belle_sip_uri_t* lhs, const belle_sip_uri_t* rhs) const { - return belle_sip_uri_equals(lhs,rhs); - } -}; + template <> struct equal_to<const belle_sip_uri_t*> { + bool operator()(const belle_sip_uri_t* lhs, const belle_sip_uri_t* rhs) const { + return belle_sip_uri_equals(lhs,rhs); + } + }; } - - #endif #endif /*BELLE_SIP_URI_H_*/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/include/belle-sip/utils.h new/belle-sip-5.2.6/include/belle-sip/utils.h --- old/belle-sip-5.1.72/include/belle-sip/utils.h 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/include/belle-sip/utils.h 2022-11-04 17:46:39.000000000 +0100 @@ -156,14 +156,6 @@ BELLESIP_EXPORT unsigned long belle_sip_begin_background_task(const char *name, belle_sip_background_task_end_callback_t cb, void *data); BELLESIP_EXPORT void belle_sip_end_background_task(unsigned long id); -/** - * create a directory if it doesn't already exists - * - * @param[in] path The directory to be created - * @return 0 in case of succes, -1 otherwise, note it returns -1 if the directory already exists - */ -BELLESIP_EXPORT int belle_sip_mkdir(const char *path); - BELLESIP_EXPORT char* belle_sip_uri_to_escaped_username(const char* buff); BELLESIP_EXPORT char* belle_sip_username_unescape_unnecessary_characters(const char* buff); BELLESIP_EXPORT char* belle_sip_to_unescaped_string(const char* buff); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/src/belle_sdp_impl.cc new/belle-sip-5.2.6/src/belle_sdp_impl.cc --- old/belle-sip-5.1.72/src/belle_sdp_impl.cc 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/src/belle_sdp_impl.cc 2022-11-04 17:46:39.000000000 +0100 @@ -1969,8 +1969,8 @@ ***********************/ struct _belle_sdp_time { belle_sip_object_t base; - int start; - int stop; + long long start; + long long stop; }; void belle_sdp_time_destroy(belle_sdp_time_t* time) { @@ -1982,12 +1982,12 @@ } belle_sip_error_code belle_sdp_time_marshal(belle_sdp_time_t* time, char* buff, size_t buff_size, size_t *offset) { - return belle_sip_snprintf(buff,buff_size,offset,"%i %i",time->start,time->stop); + return belle_sip_snprintf(buff,buff_size,offset,"%lld %lld",time->start,time->stop); } BELLE_SDP_NEW(time,belle_sip_object) -GET_SET_INT(belle_sdp_time,start,int); -GET_SET_INT(belle_sdp_time,stop,int); +GET_SET_INT(belle_sdp_time,start,long long); +GET_SET_INT(belle_sdp_time,stop,long long); /************************ * time description @@ -2012,7 +2012,7 @@ BELLE_SDP_NEW(time_description,belle_sip_object) -belle_sdp_time_description_t* belle_sdp_time_description_create (int start,int stop) { +belle_sdp_time_description_t* belle_sdp_time_description_create (long long start,long long stop) { belle_sdp_time_description_t* time_desc= belle_sdp_time_description_new(); belle_sdp_time_t* time = belle_sdp_time_new(); belle_sdp_time_set_start(time,start); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/src/belle_sip_internal.h new/belle-sip-5.2.6/src/belle_sip_internal.h --- old/belle-sip-5.1.72/src/belle_sip_internal.h 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/src/belle_sip_internal.h 2022-11-04 17:46:39.000000000 +0100 @@ -878,6 +878,7 @@ belle_sip_list_t *route_set; belle_sip_header_address_t *remote_target; belle_sip_source_t *expiration_timer; + belle_sip_dialog_termination_cause_t termination_cause; char *local_tag; char *remote_tag; unsigned int local_cseq; @@ -893,6 +894,7 @@ unsigned char is_expired; unsigned char pending_trans_checking_enabled; /*use to disabled pending transaction check at request creation (testing)*/ unsigned char is_internal; /*Internal dialogs are those created by refreshers. */ + unsigned char simulate_lost_ack; /*used by testers*/ }; belle_sip_dialog_t *belle_sip_dialog_new(belle_sip_transaction_t *t); @@ -1128,20 +1130,10 @@ BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_multipart_body_handler_t,belle_sip_body_handler_t) BELLE_SIP_DECLARE_CUSTOM_VPTR_END -void belle_sip_multipart_body_handler_progress_cb(belle_sip_body_handler_t *obj, belle_sip_message_t *msg, void *user_data, size_t transfered, size_t expected_total); /** * file manipulation */ -/** - * Parse a directory and return all files in it. - * - * @param[in] path The directory to be parsed - * @param[in] file_type if not NULL return only the file with the given extension, must include the '.', ex:".pem" - * @return a belle_sip list containing all found file or NULL if no file were found or directory doesn't exist. List must be destroyed using belle_sip_list_free_with_data(<ret_list>, belle_sip_free) - */ -belle_sip_list_t *belle_sip_parse_directory(const char *path, const char *file_type); - typedef struct authorization_context authorization_context_t; typedef authorization_context_t belle_sip_authorization_t; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/src/belle_sip_resolver.c new/belle-sip-5.2.6/src/belle_sip_resolver.c --- old/belle-sip-5.1.72/src/belle_sip_resolver.c 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/src/belle_sip_resolver.c 2022-11-04 17:46:39.000000000 +0100 @@ -1661,7 +1661,7 @@ * Start a global timer in order to workaround buggy home routers that don't respond to SRV requests. * If A fallback response arrived, SRV shall not take a lot longer. */ - belle_sip_message("resolver[%p]: starting SRV timeout since A/AAAA fallback response is received.", ctx); + belle_sip_message("resolver[%p]: starting SRV timer since A/AAAA fallback response is received.", ctx); belle_sip_socket_source_init((belle_sip_source_t*)ctx, (belle_sip_source_func_t)combined_resolver_srv_timeout, ctx, -1 , BELLE_SIP_EVENT_TIMEOUT, belle_sip_srv_timeout_after_a_received); belle_sip_main_loop_add_source(ctx->base.stack->ml, (belle_sip_source_t*)ctx); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/src/belle_sip_utils.c new/belle-sip-5.2.6/src/belle_sip_utils.c --- old/belle-sip-5.1.72/src/belle_sip_utils.c 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/src/belle_sip_utils.c 2022-11-04 17:46:39.000000000 +0100 @@ -548,88 +548,3 @@ output_buff[out_buff_index]='\0'; return belle_sip_strdup(output_buff); } - -belle_sip_list_t *belle_sip_parse_directory(const char *path, const char *file_type) { - belle_sip_list_t* file_list = NULL; -#ifdef _WIN32 - WIN32_FIND_DATA FileData; - HANDLE hSearch; - BOOL fFinished = FALSE; - char szDirPath[1024]; -#ifdef UNICODE - wchar_t wszDirPath[1024]; -#endif - - if (file_type == NULL) { - file_type = ".*"; - } - snprintf(szDirPath, sizeof(szDirPath), "%s\\*%s", path, file_type); -#ifdef UNICODE - mbstowcs(wszDirPath, szDirPath, sizeof(wszDirPath)); - hSearch = FindFirstFileExW(wszDirPath, FindExInfoStandard, &FileData, FindExSearchNameMatch, NULL, 0); -#else - hSearch = FindFirstFileExA(szDirPath, FindExInfoStandard, &FileData, FindExSearchNameMatch, NULL, 0); -#endif - if (hSearch == INVALID_HANDLE_VALUE) { - belle_sip_message("No file (*%s) found in [%s] [%d].", file_type, szDirPath, (int)GetLastError()); - return NULL; - } - snprintf(szDirPath, sizeof(szDirPath), "%s", path); - while (!fFinished) { - char szFilePath[1024]; -#ifdef UNICODE - char filename[512]; - wcstombs(filename, FileData.cFileName, sizeof(filename)); - snprintf(szFilePath, sizeof(szFilePath), "%s\\%s", szDirPath, filename); -#else - snprintf(szFilePath, sizeof(szFilePath), "%s\\%s", szDirPath, FileData.cFileName); -#endif - file_list = belle_sip_list_append(file_list, belle_sip_strdup(szFilePath)); - if (!FindNextFile(hSearch, &FileData)) { - if (GetLastError() == ERROR_NO_MORE_FILES) { - fFinished = TRUE; - } - else { - belle_sip_error("Couldn't find next (*%s) file.", file_type); - fFinished = TRUE; - } - } - } - /* Close the search handle. */ - FindClose(hSearch); -#else - DIR *dir; - struct dirent *ent; - - if ((dir = opendir(path)) == NULL) { - belle_sip_error("Could't open [%s] directory.", path); - return NULL; - } - - /* loop on all directory files */ - errno = 0; - ent = readdir(dir); - while (ent != NULL) { - /* filter on file type if given */ - if (file_type==NULL - || (strncmp(ent->d_name+strlen(ent->d_name)-strlen(file_type), file_type, strlen(file_type))==0) ) { - char *name_with_path=belle_sip_strdup_printf("%s/%s",path,ent->d_name); - file_list = belle_sip_list_append(file_list, name_with_path); - } - ent = readdir(dir); - } - if (errno != 0) { - belle_sip_error("Error while reading the [%s] directory: %s.", path, strerror(errno)); - } - closedir(dir); -#endif - return file_list; -} - -int belle_sip_mkdir(const char *path) { -#ifdef _WIN32 - return _mkdir(path); -#else - return mkdir(path, 0700); -#endif -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/src/bodyhandler.c new/belle-sip-5.2.6/src/bodyhandler.c --- old/belle-sip-5.1.72/src/bodyhandler.c 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/src/bodyhandler.c 2022-11-04 17:46:39.000000000 +0100 @@ -864,6 +864,9 @@ * TODO **/ + +static void belle_sip_multipart_body_handler_parse_final(belle_sip_multipart_body_handler_t *obj); + struct belle_sip_multipart_body_handler{ belle_sip_body_handler_t base; belle_sip_list_t *parts; @@ -880,8 +883,8 @@ if (obj->boundary != NULL) belle_sip_free(obj->boundary); } -static void belle_sip_multipart_body_handler_clone(belle_sip_multipart_body_handler_t *obj){ - obj->parts=belle_sip_list_copy_with_data(obj->parts,(void *(*)(void*))belle_sip_object_clone_and_ref); +static void belle_sip_multipart_body_handler_clone(belle_sip_multipart_body_handler_t *obj, const belle_sip_multipart_body_handler_t*other){ + belle_sip_fatal("belle_sip_multipart_body_handler_clone() not implemenented."); } static void belle_sip_multipart_body_handler_begin_recv_transfer(belle_sip_body_handler_t *obj) { @@ -907,11 +910,17 @@ static void belle_sip_multipart_body_handler_end_transfer(belle_sip_body_handler_t *obj) { const belle_sip_list_t *it; belle_sip_multipart_body_handler_t *obj_multipart = (belle_sip_multipart_body_handler_t *)obj; - for (it = obj_multipart->parts; it != NULL; it = it->next) { - belle_sip_body_handler_t *bh = BELLE_SIP_BODY_HANDLER(it->data); - belle_sip_body_handler_end_transfer(bh); + + if (obj_multipart->parts == NULL){ + /* this was a receive transfer */ + belle_sip_multipart_body_handler_parse_final(obj_multipart); + }else{ + for (it = obj_multipart->parts; it != NULL; it = it->next) { + belle_sip_body_handler_t *bh = BELLE_SIP_BODY_HANDLER(it->data); + belle_sip_body_handler_end_transfer(bh); + } + obj_multipart->transfer_current_part = NULL; } - obj_multipart->transfer_current_part = NULL; } static void belle_sip_multipart_body_handler_recv_chunk(belle_sip_body_handler_t *obj, belle_sip_message_t *msg, off_t offset, @@ -927,7 +936,7 @@ uint8_t *buffer, size_t *size){ belle_sip_multipart_body_handler_t *obj_multipart=(belle_sip_multipart_body_handler_t*)obj; - if (obj_multipart->transfer_current_part->data) { /* we have a part, get its content from handler */ + if (obj_multipart->transfer_current_part && obj_multipart->transfer_current_part->data) { /* we have a part, get its content from handler */ int retval = BELLE_SIP_STOP; size_t offsetSize = 0; /* used to store size of data added by this function and not given by the body handler of current part */ size_t boundary_len = strlen(obj_multipart->boundary); @@ -1039,7 +1048,7 @@ belle_sip_multipart_body_handler_t *belle_sip_multipart_body_handler_new_from_buffer(const void *buffer, size_t bufsize, const char *boundary) { belle_sip_multipart_body_handler_t *obj_multipart = belle_sip_object_new(belle_sip_multipart_body_handler_t); belle_sip_body_handler_t *obj = (belle_sip_body_handler_t *)obj_multipart; - belle_sip_body_handler_init((belle_sip_body_handler_t *)obj, belle_sip_multipart_body_handler_progress_cb, NULL); + belle_sip_body_handler_init((belle_sip_body_handler_t *)obj, NULL, NULL); belle_sip_multipart_body_handler_set_boundary(obj_multipart, boundary); obj_multipart->base.expected_size = bufsize; belle_sip_body_handler_begin_recv_transfer(obj); @@ -1085,71 +1094,68 @@ return obj->parts; } -void belle_sip_multipart_body_handler_progress_cb(belle_sip_body_handler_t *obj, belle_sip_message_t *msg, void *user_data, size_t transfered, size_t expected_total) { - if (transfered == expected_total) { - /* The full multipart body has been received, we can now parse it and split the different parts, - * creating a belle_sip_memory_body_handler for each part and adding them to the belle_sip_multipart_body_handler - * parts list. */ - belle_sip_multipart_body_handler_t *obj_multipart = (belle_sip_multipart_body_handler_t *)obj; - belle_sip_memory_body_handler_t *memorypart; - belle_sip_header_t *header; - uint8_t *end_part_cursor; - uint8_t *end_headers_cursor; - uint8_t *end_header_cursor; - uint8_t *cursor = obj_multipart->buffer; - char *dash_boundary = belle_sip_strdup_printf("--%s", obj_multipart->boundary); - size_t expected_size = obj_multipart->base.expected_size; /* Save expected size. Indeed add_parts() plays with it - * for the composing process. For parsing process we actually don't need this, so the correct size will be restored at the end.*/ - - if (strncmp((char *)cursor, dash_boundary, strlen(dash_boundary))) { - belle_sip_warning("belle_sip_multipart_body_handler [%p]: body not starting by specified boundary '%s'", obj_multipart, obj_multipart->boundary); +static void belle_sip_multipart_body_handler_parse_final(belle_sip_multipart_body_handler_t *obj_multipart){ + /* The full multipart body has been received, we can now parse it and split the different parts, + * creating a belle_sip_memory_body_handler for each part and adding them to the belle_sip_multipart_body_handler + * parts list. */ + belle_sip_memory_body_handler_t *memorypart; + belle_sip_header_t *header; + uint8_t *end_part_cursor; + uint8_t *end_headers_cursor; + uint8_t *end_header_cursor; + uint8_t *cursor = obj_multipart->buffer; + char *dash_boundary = belle_sip_strdup_printf("--%s", obj_multipart->boundary); + size_t expected_size = obj_multipart->base.expected_size; /* Save expected size. Indeed add_parts() plays with it + * for the composing process. For parsing process we actually don't need this, so the correct size will be restored at the end.*/ + + if (strncmp((char *)cursor, dash_boundary, strlen(dash_boundary))) { + belle_sip_warning("belle_sip_multipart_body_handler [%p]: body not starting by specified boundary '%s'", obj_multipart, obj_multipart->boundary); + belle_sip_free(dash_boundary); + return; + } + cursor += strlen(dash_boundary); + + do { + bool_t delimiter_contains_crlf = FALSE; + if (strncmp((char *)cursor, "\r\n", 2)) { + belle_sip_warning("belle_sip_multipart_body_handler [%p]: no new-line after boundary", obj_multipart); belle_sip_free(dash_boundary); return; } - cursor += strlen(dash_boundary); - - do { - bool_t delimiter_contains_crlf = FALSE; - if (strncmp((char *)cursor, "\r\n", 2)) { - belle_sip_warning("belle_sip_multipart_body_handler [%p]: no new-line after boundary", obj_multipart); - belle_sip_free(dash_boundary); - return; + cursor += 2; + end_part_cursor = (uint8_t *)strstr((char *)cursor, dash_boundary); + if (end_part_cursor == NULL) { + belle_sip_error("belle_sip_multipart_body_handler [%p]: cannot find next boundary", obj_multipart); + belle_sip_free(dash_boundary); + return; + } else { + if (*(end_part_cursor-1) == '\n' && *(end_part_cursor-2) == '\r') { + end_part_cursor-=2; /* delimiter is well formed: delimiter := CRLF dash-boundary */ + delimiter_contains_crlf = TRUE; } - cursor += 2; - end_part_cursor = (uint8_t *)strstr((char *)cursor, dash_boundary); - if (end_part_cursor == NULL) { - belle_sip_warning("belle_sip_multipart_body_handler [%p]: cannot find next boundary", obj_multipart); - belle_sip_free(dash_boundary); - return; + *end_part_cursor = 0; + end_headers_cursor = (uint8_t *)strstr((char *)cursor, "\r\n\r\n"); + if (end_headers_cursor == NULL) { + memorypart = belle_sip_memory_body_handler_new_copy_from_buffer(cursor, strlen((char *)cursor), NULL, NULL); } else { - if (*(end_part_cursor-1) == '\n' && *(end_part_cursor-2) == '\r') { - end_part_cursor-=2; /* delimiter is well formed: delimiter := CRLF dash-boundary */ - delimiter_contains_crlf = TRUE; - } - *end_part_cursor = 0; - end_headers_cursor = (uint8_t *)strstr((char *)cursor, "\r\n\r\n"); - if (end_headers_cursor == NULL) { - memorypart = belle_sip_memory_body_handler_new_copy_from_buffer(cursor, strlen((char *)cursor), NULL, NULL); - } else { - uint8_t *begin_body_cursor = end_headers_cursor + 4; - memorypart = belle_sip_memory_body_handler_new_copy_from_buffer(begin_body_cursor, strlen((char *)begin_body_cursor), NULL, NULL); - do { - end_header_cursor = (uint8_t *)strstr((char *)cursor, "\r\n"); - *end_header_cursor = 0; - header = belle_sip_header_parse((char *)cursor); - if (header != NULL) { - belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(memorypart), header); - } - cursor = end_header_cursor + 2; - } while (end_header_cursor != end_headers_cursor); - } - belle_sip_multipart_body_handler_add_part(obj_multipart, BELLE_SIP_BODY_HANDLER(memorypart)); - cursor = end_part_cursor + strlen(dash_boundary); - if (delimiter_contains_crlf) - cursor += 2; + uint8_t *begin_body_cursor = end_headers_cursor + 4; + memorypart = belle_sip_memory_body_handler_new_copy_from_buffer(begin_body_cursor, strlen((char *)begin_body_cursor), NULL, NULL); + do { + end_header_cursor = (uint8_t *)strstr((char *)cursor, "\r\n"); + *end_header_cursor = 0; + header = belle_sip_header_parse((char *)cursor); + if (header != NULL) { + belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(memorypart), header); + } + cursor = end_header_cursor + 2; + } while (end_header_cursor != end_headers_cursor); } - } while (strcmp((char *)cursor, "--\r\n")); - belle_sip_free(dash_boundary); - obj_multipart->base.expected_size = expected_size; - } + belle_sip_multipart_body_handler_add_part(obj_multipart, BELLE_SIP_BODY_HANDLER(memorypart)); + cursor = end_part_cursor + strlen(dash_boundary); + if (delimiter_contains_crlf) + cursor += 2; + } + } while (strncmp((char *)cursor, "--\r\n", 4)); + belle_sip_free(dash_boundary); + obj_multipart->base.expected_size = expected_size; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/src/channel.c new/belle-sip-5.2.6/src/channel.c --- old/belle-sip-5.1.72/src/channel.c 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/src/channel.c 2022-11-04 17:46:39.000000000 +0100 @@ -336,10 +336,7 @@ belle_sip_header_content_length_set_content_length(content_length, belle_sip_body_handler_get_size(BELLE_SIP_BODY_HANDLER(mbh))); belle_sip_message_remove_header_from_ptr(msg, ceh); if (content_type && (strcmp(belle_sip_header_content_type_get_type(content_type), "multipart") == 0)) { - const char *unparsed_value = belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(content_type)); - const char *boundary = strstr(unparsed_value, ";boundary="); - if (boundary != NULL) boundary += 10; - if (boundary[0] == '\0') boundary = NULL; + const char *boundary = belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type), "boundary"); bh = (belle_sip_body_handler_t *)belle_sip_multipart_body_handler_new_from_buffer( belle_sip_memory_body_handler_get_buffer(mbh), belle_sip_body_handler_get_size((belle_sip_body_handler_t *)mbh), boundary); belle_sip_message_set_body_handler(msg, bh); @@ -410,11 +407,8 @@ bh = (belle_sip_body_handler_t *)belle_sip_memory_body_handler_new(NULL, NULL); belle_sip_body_handler_add_header(bh, content_encoding); } else if (content_type && (strcmp(belle_sip_header_content_type_get_type(content_type), "multipart") == 0)) { - const char *unparsed_value = belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(content_type)); - const char *boundary = strstr(unparsed_value, ";boundary="); - if (boundary) boundary += 10; - if (boundary[0] == '\0') boundary = NULL; - bh = (belle_sip_body_handler_t *)belle_sip_multipart_body_handler_new(belle_sip_multipart_body_handler_progress_cb, NULL, NULL, boundary); + const char *boundary = belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type), "boundary"); + bh = (belle_sip_body_handler_t *)belle_sip_multipart_body_handler_new(NULL, NULL, NULL, boundary); } else { bh = (belle_sip_body_handler_t *)belle_sip_memory_body_handler_new(NULL, NULL); } @@ -1173,9 +1167,11 @@ ret=belle_sip_channel_send(obj,buffer,size); }else if (obj->stack->send_error<0){ /*for testing purpose only */ + belle_sip_message("channel[%p]: simulating socket error [%i].", obj, (int) obj->stack->send_error); ret=obj->stack->send_error; } else { ret=(int)size; /*to silently discard message*/ + belle_sip_message("channel[%p]: %i bytes are silently discarded, to simulate loss of data.", obj, (int) size); } if (ret<0){ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/src/dialog.c new/belle-sip-5.2.6/src/dialog.c --- old/belle-sip-5.1.72/src/dialog.c 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/src/dialog.c 2022-11-04 17:46:39.000000000 +0100 @@ -341,10 +341,32 @@ static int dialog_on_200Ok_end(belle_sip_dialog_t *dialog){ belle_sip_request_t *bye; belle_sip_client_transaction_t *trn; + belle_sip_header_reason_t *reason; + belle_sip_dialog_stop_200Ok_retrans(dialog); - belle_sip_error("Dialog [%p] was not ACK'd within T1*64 seconds, it is going to be terminated.",dialog); + + belle_sip_error("Dialog [%p] was not ACK'd within T1*64 seconds.", dialog); + + if (dialog->last_transaction){ + /* Check if a BYE is not already in progress, no need to send a second one.*/ + const char * request = belle_sip_request_get_method(belle_sip_transaction_get_request(dialog->last_transaction)); + if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(dialog->last_transaction,belle_sip_client_transaction_t) && strcmp(request, "BYE") == 0){ + return BELLE_SIP_STOP; + } + } + + belle_sip_error("Dialog [%p] it is going to be terminated automatically.",dialog); dialog->state=BELLE_SIP_DIALOG_CONFIRMED; + bye=belle_sip_dialog_create_request(dialog,"BYE"); + reason=belle_sip_header_reason_new(); + belle_sip_header_reason_set_protocol(reason,"SIP"); + belle_sip_header_reason_set_cause(reason,408); + belle_sip_header_reason_set_text(reason,"no ACK received"); + belle_sip_message_add_header(BELLE_SIP_MESSAGE(bye), BELLE_SIP_HEADER(reason)); + + dialog->termination_cause = BELLE_SIP_DIALOG_TERMINATION_CAUSE_ABORT_NO_ACK; + trn=belle_sip_provider_create_client_transaction(dialog->provider,bye); BELLE_SIP_TRANSACTION(trn)->is_internal=1; /*don't bother user with this transaction*/ belle_sip_client_transaction_send_request(trn); @@ -535,23 +557,29 @@ int is_retransmition=FALSE; int delete_dialog=FALSE; belle_sip_request_t *req=belle_sip_transaction_get_request(transaction); + belle_sip_header_cseq_t* current_cseq=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_cseq_t); + unsigned int current_transaction_cseq = belle_sip_header_cseq_get_seq_number(current_cseq); belle_sip_response_t *resp=belle_sip_transaction_get_response(transaction); int code=0; int ret = 0; int is_invite = strcmp(belle_sip_request_get_method(req),"INVITE")==0; int is_subscribe = strcmp(belle_sip_request_get_method(req),"SUBSCRIBE")==0; int is_notify = strcmp(belle_sip_request_get_method(req),"NOTIFY")==0; + belle_sip_transaction_t *previous_transaction = NULL; belle_sip_message("Dialog [%p]: now updated by transaction [%p].",obj, transaction); if (resp) code=belle_sip_response_get_status_code(resp); - if (as_uas && code == 491) { /**/ + bool_t do_not_update_last_transaction = (as_uas && (code == 491)); + if (do_not_update_last_transaction) { /**/ belle_sip_message("Dialog [%p]: don't update last transaction by transaction [%p].",obj, transaction); } else { belle_sip_object_ref(transaction); - if (obj->last_transaction) belle_sip_object_unref(obj->last_transaction); + if (obj->last_transaction) { + previous_transaction = obj->last_transaction; + } obj->last_transaction=transaction; } if (!as_uas){ @@ -559,16 +587,24 @@ SET_OBJECT_PROPERTY(obj,privacy,privacy_header); } - /*first update local/remote cseq*/ + /* + first update local/remote cseq + Do not update remote and remote invite CSeq if it is lower than the current one as it may be a retransmission and the next transaction may already be executing + */ if (as_uas) { - belle_sip_header_cseq_t* cseq=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_cseq_t); - obj->remote_cseq=belle_sip_header_cseq_get_seq_number(cseq); - if (is_invite && code>=200 && code<300) - obj->remote_invite_cseq = belle_sip_header_cseq_get_seq_number(cseq); - /*else ACK is handled by transaction, not dialog*/ + bool_t update_remote_invite_cseq = (obj->remote_invite_cseq < current_transaction_cseq); + bool_t update_cseq = (obj->remote_cseq < current_transaction_cseq); + if ((is_invite && (code>=200) && (code<300) && !update_remote_invite_cseq) || (!update_cseq && !do_not_update_last_transaction)) { + obj->last_transaction=previous_transaction; + } + if (update_cseq) { + obj->remote_cseq=current_transaction_cseq; + } + if (is_invite && (code>=200) && (code<300) && update_remote_invite_cseq) { + obj->remote_invite_cseq = current_transaction_cseq; + } /*else ACK is handled by transaction, not dialog*/ } - switch (obj->state){ case BELLE_SIP_DIALOG_NULL: /*always establish a dialog*/ @@ -648,7 +684,9 @@ if (code>=200 && code<300){ /*handle possible retransmission of 200Ok */ if (!as_uas && (is_retransmition=(belle_sip_dialog_handle_200Ok(obj,resp)==0))) { - return is_retransmition; + obj->last_transaction=previous_transaction; + ret = 1; + goto end; } else { if (as_uas) belle_sip_dialog_init_200Ok_retrans(obj,resp); @@ -677,6 +715,15 @@ if (code>=200 || (code==0 && belle_sip_transaction_get_state(transaction)==BELLE_SIP_TRANSACTION_TERMINATED)){ obj->needs_ack=FALSE; /*no longuer need ACK*/ if (obj->terminate_on_bye) delete_dialog=TRUE; + }else if (!as_uas && code == 0){ + /* A client BYE transaction is being started */ + if (previous_transaction && belle_sip_transaction_get_state(previous_transaction) != BELLE_SIP_TRANSACTION_TERMINATED){ + belle_sip_warning("Forcibly terminating previous transaction as BYE is being sent."); + /* Detach the dialog from the transaction, so that the dialog does not get updated for nothing + * by the killed transaction. */ + belle_sip_transaction_set_dialog(previous_transaction, NULL); + belle_sip_transaction_terminate(previous_transaction); + } } }else if (is_subscribe){ if (belle_sip_dialog_schedule_expiration(obj, (belle_sip_message_t*)req) == BELLE_SIP_STOP @@ -701,6 +748,13 @@ } end: + if (!do_not_update_last_transaction) { + if (obj->last_transaction && (obj->last_transaction == transaction)) { + if (previous_transaction) belle_sip_object_unref(previous_transaction); + } else { + if (transaction) belle_sip_object_unref(transaction); + } + } if (delete_dialog) belle_sip_dialog_delete(obj); else { belle_sip_dialog_process_queue(obj); @@ -775,6 +829,7 @@ obj->pending_trans_checking_enabled=1; obj->call_id=(belle_sip_header_call_id_t*)belle_sip_object_ref(call_id); obj->type=type; + obj->termination_cause=BELLE_SIP_DIALOG_TERMINATION_CAUSE_NORMAL; belle_sip_object_ref(t); obj->last_transaction=t; @@ -905,15 +960,21 @@ return TRUE; } -belle_sip_request_t * belle_sip_dialog_create_queued_request(belle_sip_dialog_t *obj, const char *method){ - belle_sip_request_t *req; - - if (!dialog_can_create_request(obj, method)) return NULL; +bool_t belle_sip_dialog_can_create_asynchronous_request(belle_sip_dialog_t *obj, const char *method){ + if (!dialog_can_create_request(obj, method)) return FALSE; if (strcmp(method,"INVITE")==0 || strcmp(method,"SUBSCRIBE")==0){ /*we don't allow requests that can update the dialog's state to be sent asynchronously*/ - belle_sip_error("belle_sip_dialog_create_queued_request([%p]): [%s] requests are forbidden using this method.",obj,method); - return NULL; + belle_sip_error("%s([%p]): [%s] requests are forbidden using this method.",__func__,obj,method); + return FALSE; } + return TRUE; +} + +belle_sip_request_t * belle_sip_dialog_create_queued_request(belle_sip_dialog_t *obj, const char *method){ + belle_sip_request_t *req; + + if (!belle_sip_dialog_can_create_asynchronous_request(obj, method)) return NULL; + req=create_request(obj,method,FALSE); if (req){ req->dialog_queued=TRUE; @@ -921,21 +982,27 @@ return req; } -belle_sip_request_t *belle_sip_dialog_create_request(belle_sip_dialog_t *obj, const char *method){ - belle_sip_request_t *req; - - if (!dialog_can_create_request(obj, method)) return NULL; +bool_t belle_sip_dialog_can_create_synchronous_request(belle_sip_dialog_t *obj, const char *method){ + if (!dialog_can_create_request(obj, method)) return FALSE; /*don't prevent to send a BYE in any case */ - if ( obj->pending_trans_checking_enabled + if (obj->pending_trans_checking_enabled && strcmp(method,"BYE")!=0 && obj->last_transaction && belle_sip_transaction_state_is_transient(belle_sip_transaction_get_state(obj->last_transaction))){ if (obj->state != BELLE_SIP_DIALOG_EARLY && strcmp(method,"UPDATE")!=0 && strcmp(method,"NOTIFY")!=0) { - belle_sip_error("belle_sip_dialog_create_request(): cannot create [%s] request from dialog [%p] while pending [%s] transaction in state [%s]",method,obj,belle_sip_transaction_get_method(obj->last_transaction), belle_sip_transaction_state_to_string(belle_sip_transaction_get_state(obj->last_transaction))); - return NULL; - } /*else UPDATE transaction can be send in // */ + belle_sip_error("%s(): cannot create [%s] request from dialog [%p] while pending [%s] transaction in state [%s]",__func__,method,obj,belle_sip_transaction_get_method(obj->last_transaction), belle_sip_transaction_state_to_string(belle_sip_transaction_get_state(obj->last_transaction))); + return FALSE; + } /*else UPDATE transaction can be sent in // */ } + return TRUE; +} + +belle_sip_request_t *belle_sip_dialog_create_request(belle_sip_dialog_t *obj, const char *method){ + belle_sip_request_t *req; + + if (!belle_sip_dialog_can_create_synchronous_request(obj, method)) return NULL; + belle_sip_dialog_update_local_cseq(obj,method); req=create_request(obj,method,TRUE); @@ -1126,6 +1193,11 @@ belle_sip_error("Your listener did not ACK'd the 200Ok for your INVITE request. The dialog will be terminated."); req=belle_sip_dialog_create_request(obj,"BYE"); if (req){ + belle_sip_header_reason_t *reason=belle_sip_header_reason_new(); + belle_sip_header_reason_set_protocol(reason,"SIP"); + belle_sip_header_reason_set_cause(reason,500); + belle_sip_header_reason_set_text(reason,"Internal Error"); + belle_sip_message_add_header(BELLE_SIP_MESSAGE(req), BELLE_SIP_HEADER(reason)); client_trans=belle_sip_provider_create_client_transaction(obj->provider,req); BELLE_SIP_TRANSACTION(client_trans)->is_internal=TRUE; /*internal transaction, don't bother user with 200ok*/ belle_sip_client_transaction_send_request(client_trans); @@ -1156,6 +1228,10 @@ } int belle_sip_dialog_handle_ack(belle_sip_dialog_t *obj, belle_sip_request_t *ack){ + if (obj->simulate_lost_ack) { + belle_sip_message("Simulating lost ACK for dialog %p", obj); + return -1; + } belle_sip_header_cseq_t *cseq=belle_sip_message_get_header_by_type(ack,belle_sip_header_cseq_t); if (obj->needs_ack && belle_sip_header_cseq_get_seq_number(cseq)==obj->remote_invite_cseq){ belle_sip_message("Incoming INVITE has ACK, dialog is happy"); @@ -1164,7 +1240,7 @@ belle_sip_dialog_process_queue(obj); return 0; } - belle_sip_message("Dialog ignoring incoming ACK (surely a retransmission)"); + belle_sip_message("Dialog ignoring incoming ACK (surely a retransmission) to dialog %p with CSeq %0d", obj, belle_sip_header_cseq_get_seq_number(cseq)); return -1; } @@ -1176,6 +1252,16 @@ return dialog->needs_ack || (dialog->last_transaction ? belle_sip_transaction_state_is_transient(belle_sip_transaction_get_state(dialog->last_transaction)) : FALSE); } +int belle_sip_dialog_get_request_retry_timeout(const belle_sip_dialog_t *dialog){ + /* According to RFC3261 - 14.1 */ + if (!dialog->is_server){ + return 2100 + 10 * (((belle_sip_random() % (4000 - 2100))) / 10 ); + }else{ + return 10 * ((belle_sip_random() % 2000) / 10 ); + } +} + + /* for notify exception As per RFC 3265; 3.3.4. Dialog creation and termination @@ -1227,9 +1313,7 @@ static void _belle_sip_dialog_process_queue(belle_sip_dialog_t* dialog){ belle_sip_client_transaction_t *tr=NULL; - if (dialog->state==BELLE_SIP_DIALOG_TERMINATED || belle_sip_dialog_request_pending(dialog)) goto end; - dialog->queued_ct=belle_sip_list_pop_front(dialog->queued_ct,(void**)&tr); if (tr){ belle_sip_message("Dialog [%p]: sending queued request [%p].",dialog,tr); @@ -1268,3 +1352,11 @@ dialog->pending_trans_checking_enabled = value; return 0; } + +belle_sip_dialog_termination_cause_t belle_sip_dialog_get_termination_cause(const belle_sip_dialog_t *dialog) { + return dialog->termination_cause; +} + +void belle_sip_dialog_set_simulate_lost_ack_enabled(belle_sip_dialog_t *dialog, int enable) { + dialog->simulate_lost_ack = (unsigned char) enable; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/src/dns/dns.c new/belle-sip-5.2.6/src/dns/dns.c --- old/belle-sip-5.1.72/src/dns/dns.c 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/src/dns/dns.c 2022-11-04 17:46:39.000000000 +0100 @@ -7259,11 +7259,12 @@ static void dns_res_frame_init(struct dns_resolver *R, struct dns_res_frame *frame) { memset(frame, '\0', sizeof *frame); - - if (!R->resconf->options.recurse) - frame->qflags |= DNS_Q_RD; - if (R->resconf->options.edns0) - frame->qflags |= DNS_Q_EDNS0; + if (R != NULL && R->resconf != NULL) { + if (!R->resconf->options.recurse) + frame->qflags |= DNS_Q_RD; + if (R->resconf->options.edns0) + frame->qflags |= DNS_Q_EDNS0; + } } /* dns_res_frame_init() */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/src/grammars/belle_sdp.g new/belle-sip-5.2.6/src/grammars/belle_sdp.g --- old/belle-sip-5.1.72/src/grammars/belle_sdp.g 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/src/grammars/belle_sdp.g 2022-11-04 17:46:39.000000000 +0100 @@ -202,8 +202,8 @@ stop_time {belle_sdp_time_description_t* time_description =belle_sdp_time_description_new(); belle_sdp_time_t* time_value =belle_sdp_time_new(); belle_sip_list_t* time_description_list; - belle_sdp_time_set_start(time_value,atoi((const char*)$start_time.text->chars)); - belle_sdp_time_set_stop(time_value,atoi((const char*)$stop_time.text->chars)); + belle_sdp_time_set_start(time_value,atoll((const char*)$start_time.text->chars)); + belle_sdp_time_set_stop(time_value,atoll((const char*)$stop_time.text->chars)); belle_sdp_time_description_set_time(time_description,time_value); time_description_list = belle_sip_list_append(NULL,time_description); belle_sdp_session_description_set_time_descriptions($session_description::current,time_description_list);}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/src/http-provider.c new/belle-sip-5.2.6/src/http-provider.c --- old/belle-sip-5.1.72/src/http-provider.c 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/src/http-provider.c 2022-11-04 17:46:39.000000000 +0100 @@ -347,6 +347,9 @@ * decides to close the connection because of inactivity timeout. Handle this case by re-submitting the pending request(s). */ http_channel_context_handle_disconnection(ctx, chan); provider_remove_channel(ctx->provider,chan); + } else { + /*In case of force close, manage DISCONNECTED as an io error in order to notify potential pending requests*/ + http_channel_context_handle_io_error(ctx, chan); } break; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/src/transaction.c new/belle-sip-5.2.6/src/transaction.c --- old/belle-sip-5.1.72/src/transaction.c 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/src/transaction.c 2022-11-04 17:46:39.000000000 +0100 @@ -288,7 +288,7 @@ } void belle_sip_transaction_notify_timeout(belle_sip_transaction_t *t){ - /* Report the channel as possibly dead. If an alternate IP can be tryied, the channel will notify us with the RETRY state. + /* Report the channel as possibly dead. If an alternate IP can be tried, the channel will notify us with the RETRY state. * Otherwise it will report the error. * We limit this dead channel reporting to REGISTER transactions, who are unlikely to be unresponded. **/ @@ -512,7 +512,6 @@ } if (t->base.sent_by_dialog_queue){ - /*it can be sent immediately, so update the request with latest cseq and route_set */ /*update route and contact just in case they changed*/ belle_sip_dialog_update_request(dialog,req); @@ -538,7 +537,7 @@ } if (dialog){ - belle_sip_dialog_update(dialog,(belle_sip_transaction_t*)t,BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_server_transaction_t)); + belle_sip_dialog_update(dialog, (belle_sip_transaction_t*)t, FALSE); } if (!t->next_hop) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/src/transports/tls_channel.c new/belle-sip-5.2.6/src/transports/tls_channel.c --- old/belle-sip-5.1.72/src/transports/tls_channel.c 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/src/transports/tls_channel.c 2022-11-04 17:46:39.000000000 +0100 @@ -199,7 +199,7 @@ */ int belle_sip_get_certificate_and_pkey_in_dir(const char *path, const char *subject, belle_sip_certificates_chain_t **certificate, belle_sip_signing_key_t **pkey, belle_sip_certificate_raw_format_t format) { /* get all *.pem file from given path */ - belle_sip_list_t *file_list = belle_sip_parse_directory(path, ".pem"); + belle_sip_list_t *file_list = bctbx_parse_directory(path, ".pem"); char *filename = NULL; file_list = belle_sip_list_pop_front(file_list, (void **)&filename); @@ -276,7 +276,7 @@ memcpy(name_with_path+path_length+strlen(subject), ".pem", 5); /* check if directory exists and if not, create it */ - belle_sip_mkdir(path); + bctbx_mkdir(path); if ( (fd = fopen(name_with_path, "w") ) == NULL) { belle_sip_error("Certificate generation can't open/create file %s", name_with_path); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/tester/auth_helper_tester.c new/belle-sip-5.2.6/tester/auth_helper_tester.c --- old/belle-sip-5.1.72/tester/auth_helper_tester.c 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/tester/auth_helper_tester.c 2022-11-04 17:46:39.000000000 +0100 @@ -63,6 +63,52 @@ belle_sip_object_unref(authorization); } +/* test patterns from RFC7616 section 3.9.1 */ +static void test_authentication_sha256_rfc7616(void) { + const char *l_raw_header = "WWW-Authenticate: Digest " + "algorithm=SHA-256, realm=\"http-a...@example.org\", opaque=\"FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS\"," + " qop=\"auth,auth-int\", nonce=\"7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v\""; + char ha1[65]; + size_t size = sizeof(ha1) / sizeof(char); + belle_sip_header_www_authenticate_t *www_authenticate = belle_sip_header_www_authenticate_parse(l_raw_header); + belle_http_header_authorization_t *authorization = belle_http_auth_helper_create_authorization(www_authenticate); + belle_http_header_authorization_set_uri(authorization, belle_generic_uri_parse("/dir/index.html")); + belle_sip_header_authorization_set_nonce_count(BELLE_SIP_HEADER_AUTHORIZATION(authorization), 1); + belle_sip_header_authorization_set_qop(BELLE_SIP_HEADER_AUTHORIZATION(authorization), "auth"); + belle_sip_header_authorization_set_cnonce(BELLE_SIP_HEADER_AUTHORIZATION(authorization), "f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ"); + const char *algo = belle_sip_header_authorization_get_algorithm(BELLE_SIP_HEADER_AUTHORIZATION(authorization)); + BC_ASSERT_EQUAL(0, belle_sip_auth_helper_compute_ha1_for_algorithm("Mufasa", "http-a...@example.org", "Circle of Life", ha1, size, algo), int, "%d"); + BC_ASSERT_EQUAL(0, belle_sip_auth_helper_fill_authorization(BELLE_SIP_HEADER_AUTHORIZATION(authorization), "GET", ha1), int, "%d"); + BC_ASSERT_STRING_EQUAL(belle_sip_header_authorization_get_qop(BELLE_SIP_HEADER_AUTHORIZATION(authorization)), "auth"); + BC_ASSERT_STRING_EQUAL(belle_sip_header_authorization_get_response(BELLE_SIP_HEADER_AUTHORIZATION(authorization)), "753927fa0e85d155564e2e272a28d1802ca10daf4496794697cf8db5856cb6c1"); + BC_ASSERT_EQUAL(belle_sip_header_authorization_get_nonce_count(BELLE_SIP_HEADER_AUTHORIZATION(authorization)), 1, int, "%d"); + belle_sip_object_unref(www_authenticate); + belle_sip_object_unref(authorization); +} + +static void test_authentication_md5_rfc7616(void) { + const char *l_raw_header = "WWW-Authenticate: Digest " + "algorithm=MD5, realm=\"http-a...@example.org\", opaque=\"FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS\"," + " qop=\"auth,auth-int\", nonce=\"7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v\""; + char ha1[33]; + size_t size = sizeof(ha1) / sizeof(char); + belle_sip_header_www_authenticate_t *www_authenticate = belle_sip_header_www_authenticate_parse(l_raw_header); + belle_http_header_authorization_t *authorization = belle_http_auth_helper_create_authorization(www_authenticate); + belle_http_header_authorization_set_uri(authorization, belle_generic_uri_parse("/dir/index.html")); + belle_sip_header_authorization_set_nonce_count(BELLE_SIP_HEADER_AUTHORIZATION(authorization), 1); + belle_sip_header_authorization_set_qop(BELLE_SIP_HEADER_AUTHORIZATION(authorization), "auth"); + belle_sip_header_authorization_set_cnonce(BELLE_SIP_HEADER_AUTHORIZATION(authorization), "f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ"); + const char *algo = belle_sip_header_authorization_get_algorithm(BELLE_SIP_HEADER_AUTHORIZATION(authorization)); + BC_ASSERT_EQUAL(0, belle_sip_auth_helper_compute_ha1_for_algorithm("Mufasa", "http-a...@example.org", "Circle of Life", ha1, size, algo), int, "%d"); + BC_ASSERT_EQUAL(0, belle_sip_auth_helper_fill_authorization(BELLE_SIP_HEADER_AUTHORIZATION(authorization), "GET", ha1), int, "%d"); + BC_ASSERT_STRING_EQUAL(belle_sip_header_authorization_get_qop(BELLE_SIP_HEADER_AUTHORIZATION(authorization)), "auth"); + BC_ASSERT_STRING_EQUAL(belle_sip_header_authorization_get_response(BELLE_SIP_HEADER_AUTHORIZATION(authorization)), "8ca523f5e9506fed4657c9700eebdbec"); + BC_ASSERT_EQUAL(belle_sip_header_authorization_get_nonce_count(BELLE_SIP_HEADER_AUTHORIZATION(authorization)), 1, int, "%d"); + belle_sip_object_unref(www_authenticate); + belle_sip_object_unref(authorization); +} + + static void test_authentication_qop_auth(void) { const char* l_raw_header = "WWW-Authenticate: Digest " @@ -221,6 +267,8 @@ TEST_NO_TAG("Proxy-Authenticate", test_proxy_authentication), TEST_NO_TAG("WWW-Authenticate", test_authentication), TEST_NO_TAG("WWW-Authenticate-sha", test_authentication_sha256), + TEST_NO_TAG("WWW-Authenticate-sha256 RFC7616 patterns", test_authentication_sha256_rfc7616), + TEST_NO_TAG("WWW-Authenticate-MD5 RFC7616 patterns", test_authentication_md5_rfc7616), TEST_NO_TAG("WWW-Authenticate (with qop)", test_authentication_qop_auth), TEST_NO_TAG("generate and parse self signed certificates", test_generate_and_parse_certificates), TEST_NO_TAG("generate certificate fingerprint", test_certificate_fingerprint) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/belle-sip-5.1.72/tester/belle_sdp_tester.c new/belle-sip-5.2.6/tester/belle_sdp_tester.c --- old/belle-sip-5.1.72/tester/belle_sdp_tester.c 2022-10-03 17:23:12.000000000 +0200 +++ new/belle-sip-5.2.6/tester/belle_sdp_tester.c 2022-11-04 17:46:39.000000000 +0100 @@ -747,8 +747,8 @@ BC_ASSERT_PTR_NOT_NULL(belle_sdp_session_description_get_connection(l_session_description)); BC_ASSERT_PTR_NOT_NULL(belle_sdp_session_description_get_time_descriptions(l_session_description)); - BC_ASSERT_EQUAL(belle_sdp_time_get_start(belle_sdp_time_description_get_time((belle_sdp_time_description_t*)(belle_sdp_session_description_get_time_descriptions(l_session_description)->data))),0, int, "%d"); - BC_ASSERT_EQUAL(belle_sdp_time_get_stop(belle_sdp_time_description_get_time((belle_sdp_time_description_t*)(belle_sdp_session_description_get_time_descriptions(l_session_description)->data))),0, int, "%d"); + BC_ASSERT_EQUAL(belle_sdp_time_get_start(belle_sdp_time_description_get_time((belle_sdp_time_description_t*)(belle_sdp_session_description_get_time_descriptions(l_session_description)->data))),0, long long, "%lld"); + BC_ASSERT_EQUAL(belle_sdp_time_get_stop(belle_sdp_time_description_get_time((belle_sdp_time_description_t*)(belle_sdp_session_description_get_time_descriptions(l_session_description)->data))),0, long long, "%lld"); media_descriptions = belle_sdp_session_description_get_media_descriptions(l_session_description); BC_ASSERT_PTR_NOT_NULL(media_descriptions); @@ -831,8 +831,8 @@ BC_ASSERT_PTR_NOT_NULL(belle_sdp_session_description_get_connection(l_session_description)); BC_ASSERT_PTR_NOT_NULL(belle_sdp_session_description_get_time_descriptions(l_session_description)); - BC_ASSERT_EQUAL(belle_sdp_time_get_start(belle_sdp_time_description_get_time((belle_sdp_time_description_t*)(belle_sdp_session_description_get_time_descriptions(l_session_description)->data))),0, int, "%d"); - BC_ASSERT_EQUAL(belle_sdp_time_get_stop(belle_sdp_time_description_get_time((belle_sdp_time_description_t*)(belle_sdp_session_description_get_time_descriptions(l_session_description)->data))),0, int, "%d"); + BC_ASSERT_EQUAL(belle_sdp_time_get_start(belle_sdp_time_description_get_time((belle_sdp_time_description_t*)(belle_sdp_session_description_get_time_descriptions(l_session_description)->data))),0, long long, "%lld"); + BC_ASSERT_EQUAL(belle_sdp_time_get_stop(belle_sdp_time_description_get_time((belle_sdp_time_description_t*)(belle_sdp_session_description_get_time_descriptions(l_session_description)->data))),0, long long, "%lld"); media_descriptions = belle_sdp_session_description_get_media_descriptions(l_session_description); BC_ASSERT_PTR_NOT_NULL(media_descriptions); @@ -936,8 +936,8 @@ BC_ASSERT_EQUAL(belle_sdp_session_description_get_bandwidth(l_session_description,"AS"), 380, int, "%d"); BC_ASSERT_PTR_NOT_NULL(belle_sdp_session_description_get_time_descriptions(l_session_description)); - BC_ASSERT_EQUAL(belle_sdp_time_get_start(belle_sdp_time_description_get_time((belle_sdp_time_description_t*)(belle_sdp_session_description_get_time_descriptions(l_session_description)->data))),0, int, "%d"); - BC_ASSERT_EQUAL(belle_sdp_time_get_stop(belle_sdp_time_description_get_time((belle_sdp_time_description_t*)(belle_sdp_session_description_get_time_descriptions(l_session_description)->data))),0, int, "%d"); + BC_ASSERT_EQUAL(belle_sdp_time_get_start(belle_sdp_time_description_get_time((belle_sdp_time_description_t*)(belle_sdp_session_description_get_time_descriptions(l_session_description)->data))),0, long long, "%lld"); + BC_ASSERT_EQUAL(belle_sdp_time_get_stop(belle_sdp_time_description_get_time((belle_sdp_time_description_t*)(belle_sdp_session_description_get_time_descriptions(l_session_description)->data))),0, long long, "%lld"); media_descriptions = belle_sdp_session_description_get_media_descriptions(l_session_description); BC_ASSERT_PTR_NOT_NULL(media_descriptions);