A couple of minor changes to make Coverity a bit happier - initialize hmac arrays to 0's - Random - change LoadLibrary to GetModuleHandle to avoid leaking single hLib handle
sip5060.net / en es
A couple of minor changes to make Coverity a bit happier - initialize hmac arrays to 0's - Random - change LoadLibrary to GetModuleHandle to avoid leaking single hLib handle
Fix POSIX build error: strerror_r has two incompatible signatures depending on feature-test macros and the platform's libc. The GNU variant returns char* (the message, which may not be 'buf'); the XSI/POSIX variant returns int (0 on success) and writes the message into 'buf'. Let overload resolution pick the right one.
Update README with C++11 version requirement Added a note in the README.md file to specify that the minimum required C++ version for the reSIProcate repository is currently C++11. This ensures developers are aware of the version requirement when working with the repository.
Merge pull request #471 from portsip/fix/invite-2xx-ack-correlation resip/dum: correlate the 2xx ACK to mInvite200 (fix endless 200 OK re…
Fix: Remove [[nodiscard]] from isAckForCurrent200 for C++11/C++14 compatibility fix: Remove [[nodiscard]] from isAckForCurrent200 for C++11/C++14 compatibility
resip/dum: correlate the 2xx ACK to mInvite200 (fix endless 200 OK retransmission on overlapping/glare re-INVITE) Summary InviteSession decided whether an inbound ACK should stop retransmission of an outstanding 200 OK to an INVITE/re-INVITE by comparing mLastRemoteSessionModification's CSeq against the ACK's CSeq. The previous logic was effectively: lastRemote.CSeq > ack.CSeq means drop as stale. That is the wrong correlator. The response being retransmitted is held in mInvite200, and RFC 3261 sections 13.2.2.4 and 17.1.1.3 require the ACK for a 2xx INVITE response to carry the same CSeq sequence number as the INVITE/2xx it acknowledges. This PR correlates the ACK against mInvite200, applies the same key to the Retransmit200 and WaitForAck timers, and adds two defensive checks. Symptoms * A UAS-sent 200 OK to a re-INVITE retransmits forever, using T1, 2*T1, and then capped at T2, even though the peer's ACK is received and routed to the dialog. * No onAckReceived callback is triggered; the log shows either no clear, or dropped stale ACK. * After about 32 seconds, Timer H or the ACK wait timer expires and the call is torn down. * This was observed in production against an SBC that hairpins a B2BUA call and emits bidirectional session-timer refresh re-INVITEs, causing re-INVITE glare. Root cause The clear-on-ACK logic in dispatchConnected, dispatchSentReinvite, dispatchReceivedReinviteSentOffer, dispatchWaitingToHangup, dispatchOthers, and the WaitForAck timer were keyed on mLastRemoteSessionModification. That value can diverge from mInvite200 whenever: 1. Re-INVITE glare occurs. We sent our own re-INVITE, so the state is now SentReinvite or a glare-related state, while we are still waiting for the ACK to a 2xx response we sent for the remote's re-INVITE. 2. Overlapping remote session-modification traffic occurs. For example, the remote sends re-INVITE B with CSeq N+1 before the ACK for our 200 OK to re-INVITE A with CSeq N arrives. dispatchConnected overwrites mLastRemoteSessionModification with B. When A's ACK with CSeq N arrives, the old guard evaluates N+1 > N as true, treats the ACK as stale, logs dropped stale ACK, and the retransmission never stops. The WaitForAck failsafe is armed with sequence N but is compared against CSeq N+1, so it also fails to fire. 3. A peer reuses, or does not strictly increase, the in-dialog CSeq. Minimal reproducible sequence: Remote sends INVITE with CSeq N: re-INVITE A DUM sends 200 OK with CSeq N: starts Retransmit200 and WaitForAck with seq N mInvite200 is 200(A) Remote sends INVITE with CSeq N+1: re-INVITE B mLastRemoteSessionModification is updated to B DUM sends 200 OK with CSeq N+1. Remote sends ACK with CSeq N: ACK for A The old logic evaluates N+1 > N as true, treats the ACK as stale, and 200(A) retransmits until Timer H. The call then fails. Fix Add a new helper: InviteSession::isAckForCurrent200(const SipMessage&) const The helper returns true only if all of the following are true: 1. The message is an ACK request. 2. A 2xx retransmission is outstanding. 3. mCurrentRetransmit200 is non-zero. 4. mInvite200 is valid. 5. The ACK's CSeq sequence number equals mInvite200's CSeq sequence number. Replace the stale guard with !isAckForCurrent200(msg) at all relevant ACK sites. Each branch keeps its existing side effects, including clearing the retransmission state, calling onAckReceived, delivering answer-in-ACK, or sending BYE. dispatchOthers is the universal fallback for re-INVITE and glare states, so this also covers states that do not special-case OnAck. Key the timers off mInvite200. WaitForAck and startRetransmit200Timer now use mInvite200's CSeq instead of mLastRemoteSessionModification's CSeq. This ensures the timers identify the specific 2xx response and continue to work even if mLastRemoteSessionModification is overwritten by later remote session-modification traffic. Suppress stale Retransmit200 timer events. The Retransmit200 branch now retransmits only when timeout.seq() still matches the current mInvite200's CSeq. This prevents a leftover timer for a superseded mInvite200 from retransmitting a replaced response. The benign post-ACK case, where mCurrentRetransmit200 is zero, stays silent as before. Only genuine stale-chain suppression is logged. The stale ACK log message is updated to: dropped stale or duplicate ACK Why this is safe mInvite200 is constructor-initialised with new SipMessage, and all startRetransmit200Timer callers populate it via makeResponse(*mInvite200, ...) immediately before arming the timer. There is no null dereference. Every mInvite200 mutation is paired with startRetransmit200Timer, so the live retransmit chain always matches and is never suppressed. States whose ACK branch does more than clear are reached only with mCurrentRetransmit200 != 0. WaitingToHangup and UAS_WaitingToHangup are entered only inside if(mCurrentRetransmit200), so BYE and termination still fire. ReceivedReinviteSentOffer is entered through provideOffer(), which sends mInvite200 and starts the timer, so answer-in-ACK delivery still fires. ServerInviteSession::dispatchAccepted, ServerInviteSession::dispatchWaitingToOffer, and ServerInviteSession::dispatchWaitingToHangup clear mCurrentRetransmit200 unconditionally. They do not use the fragile correlator and are not touched. The UAS initial-INVITE and queued-offer paths are unchanged. This PR does not alter the main InviteSession state transitions. The behavioral delta is limited to: 1. The ACK correlation bug fix. 2. Duplicate or stale ACKs no longer re-fire onAckReceived for the outstanding 2xx response. 3. Stale Retransmit200 timer events can no longer retransmit a replaced mInvite200. Files changed * resip/dum/InviteSession.cxx * resip/dum/InviteSession.hxx Testing Verified by source audit of every ACK dispatch path and the Retransmit200 / WaitForAck timers. The new helper and timer guards compile clean under -std=c++20 -Wall -Wextra -Werror. Recommended tests: 1. Run the existing DUM test suite under resip/dum/test. 2. Add a regression test for interleaved or glare re-INVITE. The test should cover this sequence: DUM sends 200 OK to re-INVITE A and starts Retransmit200 / WaitForAck. mLastRemoteSessionModification advances because of re-INVITE B before ACK A arrives. ACK A is received. Assert that mCurrentRetransmit200 is cleared, onAckReceived is called once, and no further 200 OK is sent. 3. Add a stale Retransmit200 test. The test should deliver a Retransmit200 timeout where timeout.seq() no longer matches the current mInvite200 CSeq. Assert that no retransmission is sent.
reTurn: implement real HMAC when USE_SSL isn't defined, add MESSAGE-INTEGRITY-SHA256 (RFC 8489)
- computeHmac(): replace the "hmac-not-implemented" placeholder used in
non-USE_SSL builds with a real HMAC-SHA1 (RFC 2104) built on the bundled
Sha1 class; OpenSSL is still used when USE_SSL is defined. Previously STUN
MESSAGE-INTEGRITY was non-functional without OpenSSL.
- checkMessageIntegrity(): use a constant-time comparison instead of memcmp
so the expected HMAC can't be recovered via a timing side channel.
- Add MESSAGE-INTEGRITY-SHA256 (attribute 0x001C) for the short-term
credential mechanism (USE_SSL only; no SHA-256 is available otherwise):
- parse and store the attribute (full 32-byte value), encode it after
MESSAGE-INTEGRITY and before FINGERPRINT, and verify it
(checkMessageIntegritySha256, constant-time, fail-closed without OpenSSL).
- rewrite the header length field per integrity attribute when computing
each HMAC, so MESSAGE-INTEGRITY covers up to itself and
MESSAGE-INTEGRITY-SHA256 covers up to itself (RFC 8489 sec 14.5-14.7).
- computeHmacSha256() via HMAC(EVP_sha256()).
Enabling SHA256 on outgoing messages (setting mHasMessageIntegritySha256)
and any ICE/long-term algorithm negotiation are left to callers / follow-up.
Misc
- fix typo in DialogUsageManager logging for content validationUse CSPRNG for security-sensitive SIP/STUN/TURN tokens (CWE-338) Random::initialize() seeded random()/rand() solely from time+PID via getSimpleSeed(); the /dev/urandom bytes that were read got passed only to RAND_add() and never reached srandom(), leaving the random() stream predictable to an attacker who can approximate process start time and PID. - Random.cxx: read /dev/urandom before seeding and XOR its entropy into the srandom()/initstate_r() seed. For the RESIP_RANDOM_THREAD_LOCAL build, capture that entropy process-wide and mix it into each thread's seed. - Random.hxx: enable RESIP_RANDOM_WIN32_RTL by default so getRandom() uses RtlGenRandom (XP+) instead of srand()/rand(), with automatic fallback. - Stun.cxx: generate the STUN transaction ID (stunBuildReqSimple) and the username nonce (stunCreateUserName) with Random::getCryptoRandom() instead of the weak stunRand() (also compounds the CWE-345 STUN work). - ChannelManager.cxx: pick the initial TURN channel number with getCryptoRandom(). Completes the migration started for SIP tags/Call-IDs/branches/GRUU salt (Helper.cxx) and Via branch transaction IDs (BranchParameter.cxx).
Merge pull request #431 from Lastique/feature/increase_tid_quality Improve transaction ID uniqueness
Merge pull request #432 from Lastique/feature/increase_ids_quality Use crypto RNG to generate various IDs that are supposed to be unique
Authenticate STUN Binding responses (CWE-345) UdpTransport's STUN client accepted any datagram beginning 0x01 0x01 as a Binding Success and stored its mapped address as the authoritative public address, without checking the transaction id or the source. An on-path or blind attacker could inject a spoofed response during a discovery cycle and redirect the stack to an attacker-controlled address. resip/stack/UdpTransport: - Store the request's transaction id and the queried server address in stunSendTest(), and in processRxParse() reject responses that are unsolicited, come from an unexpected source, or whose transaction id does not match (RFC 5389 sec 10.1). A mismatch leaves the result unchanged so a genuine response can still be accepted; success consumes the request. - Documented the single-outstanding-request restriction and that Short-term credentials and MESSAGE-INTEGRITY are intentionally not added to this SIP signaling transport (that belongs to ICE on the media path) Misc changes (fix STUN MESSAGE-INTEGRITY in Stun.cxx/hxx): - Implement computeHmac() as real HMAC-SHA1: OpenSSL when USE_SSL, otherwise the bundled Sha1 class via the RFC 2104 construction (previously it wrote a "hmac-not-implemented" placeholder in non-SSL builds). - Fix MESSAGE-INTEGRITY encoding to be RFC 5389 sec 15.4 compliant (drop the bogus 64-byte zero padding from the HMAC input). - Record the MESSAGE-INTEGRITY attribute offset during parsing and add stunVerifyMessageIntegrity(), which verifies the HMAC with a constant-time comparison. - Fix server-side verification (even though it implements a deprecated authentication mechanism) . In stunServerProcessMsg(): it compared the wrong bytes, read an uninitialized buffer in non-SSL builds, and only ever recognized a hard-coded "test"/"1234" credential while silently accepting any other username. It now derives the password via stunCreatePassword(), verifies with stunVerifyMessageIntegrity(), and rejects failures with 431.
Helper::getResponseCodeReason: Add SIP response code reason's for RFC8224 defined responses
HttpProvider abstract base class expanded with get request timeout options: - ConnectTimeoutSeconds - RequestTimeoutSeconds
- basicClient sample app CMake update to include header files in IDE's
Ensure reason-text complies with RFC 3326 formatting Updated multiple methods to set the `reason-text` parameter as a quoted-string in compliance with RFC 3326. This includes changes to `ResponseContext::processResponse`, `ResponseContext::forwardBestResponse`, `DialogSet::addEndReasonToMessage`, and `InviteSession::sendBye` to ensure proper formatting of SIP headers.
- stack: output multiple Identity headers as individual headers (not comma delimited) - repro: don't strip PAssertedIdentityHeaders in IsTrustedNode processor if proxy had PAsstertedIdentityProcessing disabled
- minor: remove non-ascii characters
Add getByIndex method to ParserContainer - added `getByIndex` to `ParserContainer` for retrieving header field values by index with both const and non-const overloads. - added tests in `testSipMessage.cxx` to validate `getByIndex` functionality, including in-range and out-of-range scenarios.
-add support for rtcp-mux attribute to sdpcontainer -add support for SDP transport protocol: PROTOCOL_TYPE_UDP_TLS_RTP_SAVPF
Misc fixes - move recon sdpTests to media/sdpcontainer/test/testSdpContainer - fix issue in SipXRemoteParticipant that was discovered due to recent operator= change - SdpHelper: modify multiple fingerprint handling to prefer SHA-256 - add unit test for multiple fingerprints
Add SdpHelper unit tests and fix some issues with SDP capability negotiation handling - improved SdpHelper to merge medium and session-level attributes for a=tcap and a=acap attributes (uses new method SdpContents::getMergedValues) - process all potential configurations, not just the first one - fix parsing when '|' symbol is used in pcfg - fix SdpMediaLine assignment operator missing copy of potential media views/strings - added support for RTP/AVPF protocol - enhanced SDP parsing logic for capability negotiation scenarios
Add RFC7714 crypto suites (WebRTC DTLS-SRTP) to SdpCryptoSuiteType
Add SIP Diversion header (RFC 5806) support Implemented full support for the SIP Diversion header as specified in RFC 5806. This includes: - Registration of Diversion as a multi-header in all relevant header and parsing files. - Addition of Diversion header parameters: reason, counter, limit, privacy, and screen, with correct types and RFC references. - New unit tests to verify Diversion header parsing and parameter access.
Add REST API for SIP stack statistics (/api/v1/stats) Introduces /api/v1/stats endpoint for retrieving and resetting SIP stack statistics in JSON format. Implements async stats delivery using condition variables and mutexes, with timeout and HTTP 504 support. Updates WebAdmin and ReproRunner to handle and dispatch statistics messages. Adds helpers for compact JSON serialization of stats. Updates documentation and method signatures accordingly.
Allow user/domain change with password on update Enhance RestAdmin user update logic to permit changing username and domain, but require a new password if either field is modified, since the password hash is bound to user+realm. Update error handling, record fetching, and user-facing messages to reflect this requirement. Update API documentation accordingly. Add validation of this logic on the HTML WebAdmin side as well.
-fix linux build issue
Add REST API alongside existing HTML WebAdmin interface
Adds a JSON/REST interface under /api/v1/ that shares the same HTTP
listener, authentication (Basic auth against users.txt), and process as
the existing HTML admin. No new ports or config required.
New class RestAdmin handles dispatch and JSON encoding using cajun.
WebAdmin::buildPage detects the /api/v1/ prefix after authentication
and delegates to RestAdmin.
Endpoints:
GET /api/v1/registrations
GET /api/v1/publications
GET /api/v1/domains
POST /api/v1/domains?uri=...&tlsPort=...
DELETE /api/v1/domains/{uri}
GET /api/v1/users
POST /api/v1/users?user=...&domain=...&password=...&name=...&email=...
GET /api/v1/users/{user@domain}
PUT /api/v1/users/{user@domain}?password=...&name=...&email=...
DELETE /api/v1/users/{user@domain}
GET /api/v1/acls
POST /api/v1/acls?hostOrIp=...&port=...&transport=...
DELETE /api/v1/acls/{key}
GET /api/v1/routes
POST /api/v1/routes?uri=...&destination=...&method=...&event=...&order=...
PUT /api/v1/routes/{key}?...
DELETE /api/v1/routes/{key}
GET /api/v1/filters
GET /api/v1/settings
GET /api/v1/stats
GET /api/v1/congestion
GET /api/v1/loglevel
PUT /api/v1/loglevel?level=...
GET /api/v1/dnscache
DELETE /api/v1/dnscache
POST /api/v1/dnscache/reload
POST /api/v1/restart
POST /api/v1/certs/reload
Write operations use query parameters rather than request bodies to
avoid parsing inbound HTTP bodies. Filter add/edit/delete are not
exposed via REST due to the field count and regex escaping concerns;
use the HTML interface for those. Registration delete removes all
contacts for an AOR. PUT on users and routes has partial-update
semantics (omitted fields are left unchanged).
Response envelopes:
{"data": ...} on success
{"status": "ok"} on action success with no payload
{"error": {"code": N, "message":...}} on error
Required plumbing changes:
- HttpBase::buildPage virtual now takes the HTTP method as its first
parameter; HttpConnection::tryParse captures it from the request
line and passes it through.
- HttpConnection::setPage handles status codes 400, 405, 501, and 503
(previously 200/301/401/404/500 only), and preserves the caller's
body for application/json responses rather than substituting a
canned HTML page on 401/404.
- WebAdmin owns a std::unique_ptr<RestAdmin>, declares RestAdmin as a
friend so it can reach shared state (store, registration/
publication DBs, proxy, DNS cache machinery), and exposes
setApiResponse() as a JSON-aware wrapper around setPage().
Authentication is identical to the HTML admin: HTTP Basic against the
existing users.txt file. The DisableHttpAuth config flag applies to
REST calls as well.Refactor SIP capability handling in InviteSession - update stored peer capabilties with mid-dialog INVITEs or UPDATEs - UPDATE messaging only updates stored peer UserAgent and P-Asserted-Identities, and a new mPeerSupportSessionTimers boolean - fixes issue where initially a peer doesn't support Session Timers, then later in the session advertised support for it
Extend HttpGetMessage with status, headers, userData Added support for HTTP status codes, user data, and response headers to HttpGetMessage, including new constructor, accessors, and encode methods. Introduced case-insensitive header lookup. Updated clone to use new fields. Extended HttpProvider with a backward-compatible get overload.
Handle OPTIONS separately in session timer logic OPTIONS requests no longer trigger session timer refreshes when both sides support session timers. This ensures only INVITE and UPDATE methods affect session timer state. OPTIONS requests no longer update peer P-Asserted-Identity
Add IdentityCategory header tests Added comprehensive tests for IdentityCategory header parsing, parameter extraction, encoding, and copy construction in testParserCategories.cxx
Add Tuple::isSpecialPurposeAddress() per RFC 6890 Implement detection of special-purpose IP addresses (RFC 6890) in Tuple, covering private, loopback, link-local, multicast, and reserved ranges for both IPv4 and IPv6. Add static Tuple instances for these ranges and declare the new method in Tuple.hxx. Add unit tests to verify correct identification of special-purpose addresses.
recon: fix race condition crash - don't store reference to RemoteParticipantDialogSet in MediaStreamEvents since it might go away before being processed - instead pass ParticipantHandle so that it can be safely looked up and discarded if call has gone away
- add missing files to fixed visual studio 2022 project - fixup FlowManagerSipXSocket for windows (broken from recent changes)
Merge branch 'master' of https://github.com/resiprocate/resiprocate
-reTurn: do not respond to responses
- try again
- fix recent build error
- fix up some lingering build issues from last commit
Resolve /w3 and SDL compilation errors/warnings on Visual Studio builds - Part2
Resolve /w3 and SDL compilation errors/warnings on Visual Studio builds - Part1
Merge branch 'master' of https://github.com/resiprocate/resiprocate
- improve reTurn nonce generation - use crypto random for private part of nonce - incorporate senders protocol, IP and port into nonce, so nonce is unique per sender
Merge pull request #466 from mykhailopopivniak/param-name-log resip/stack: downgrade duplicate parameter-name log to INFO level
- change IdentityHeader to use new parser
- Security.hxx - add missing X509_free call to checkAndSetIdentity
- DialogUsageManager.hxx - remove unused members
- Data class - add prefixNoCase and postfixNoCase methods - add unit tests to testData.cxx
resip/stack: downgrade duplicate parameter-name log to INFO level Duplicate parameters are a protocol violation per RFC 3261 ยง7.3.1 and ยง19.1.1, but the stack already handles them gracefully by silently skipping the duplicate. Using WarningLog implies operator attention is needed, which is not the case here. Downgrade to InfoLog to avoid noise in production environments where non-compliant peers may frequently send duplicate parameters.
Cleanup SecurityAttributes - add copy constructor - cleanup code formatting - optimize operator<< - modify SipMessage copy logic to use SecurityAttributes copy constructor - add unit test for SecurityAttributes copy in SipMessage assignment - repro/HttpConnection.cxx - fix typo in 404 responses
Add new parameters and parsing for RFC8224 Identity headers - Identity header parsing remains as StringCategory for now, until RFC8224 can be fully implemented
Update windows CMake builds from OpenSSL 1.1.1q (zero-c nuget package) to OpenSSL 3.5.5 (openssl-native nuget package) - moved linux install of config.h from /usr/include to /usr/include/resip
Make sure new transport flag: RESIP_TRANSPORT_FLAG_SYMMETRIC_CONNECTIONS uses SO_RESUSEPORT on linux - fix testTransportSelector issues on linux, but using new transport flag to allow multiple test transports to bind to the same port
Fix failure ACK routing over TLS when stack has multiple TLS transports - ACK could use different transport than INVITE - issue introduced in PR https://github.com/resiprocate/resiprocate/pull/367 - TransportSelector, if port is specified in source make sure we select the correct TLS transport - Tuple: add new isEqual method to Tuple to allow comparison without checking the port - testTransportSelector - added TLS transport based tests for source searches using port 0 and transports bound to INADDR_ANY, corrected other tests - Misc: fix some spelling errors
Improve Session Timer Support when Refresher - if DUM is the refresher and sends a reINITE or UPDATE to refresh the session timer and we receive an error response that doesn't tear down the INVITE session, then we need to make sure we timeout the session when it eventaully expires - start a 2nd timer on the refresher side to ensure we timeout the session if refresh attempts fail - also retry the refresh at half the duration of the previous attempt if it failed to get a success response - add better logging of timers
Merge pull request #462 from mykhailopopivniak/rinstance_uri_param
resip/stack: consider known parameters when comparing URIs Previously, URI comparison logic treated URIs with different known parameter values as equal. Per RFC 3261 ยง19.1.4, parameters present in both URIs must match. Add related unit tests. Relates to #385.
- expose Helper::getSdpRecurse for use cases where modifying the SdpContents is needed
Merge pull request #461 from Anjali515/Avtec_Symm_Conn Symmetric Connection
Remove closesocket() Socket close not needed as the socket failed to open.