Sync to current darcs tree:

Mon Sep 17 14:50:04 EDT 2007  Pekka.Pessi@nokia.com
  * sofia-sip/sip_util.h: updated documentation

Mon Sep 17 14:50:18 EDT 2007  Pekka.Pessi@nokia.com
  * sofia-sip/tport_tag.h: updated documentation

Mon Sep 17 14:50:28 EDT 2007  Pekka.Pessi@nokia.com
  * soa_tag.c: updated documentation

Wed Sep 19 12:50:01 EDT 2007  Pekka.Pessi@nokia.com
  * msg: updated documentation

Wed Sep 19 13:29:50 EDT 2007  Pekka.Pessi@nokia.com
  * url: updated documentation

Wed Sep 19 13:32:14 EDT 2007  Pekka.Pessi@nokia.com
  * nth: updated documentation

Wed Sep 19 13:32:27 EDT 2007  Pekka.Pessi@nokia.com
  * nea: updated documentation

Wed Sep 19 13:33:36 EDT 2007  Pekka.Pessi@nokia.com
  * http: updated documentation

Wed Sep 19 13:36:58 EDT 2007  Pekka.Pessi@nokia.com
  * bnf: updated documentation

Wed Sep 19 13:38:58 EDT 2007  Pekka.Pessi@nokia.com
  * nua: updated nua_stack_init_handle() prototype

Wed Sep 19 18:45:56 EDT 2007  Pekka.Pessi@nokia.com
  * sip: added sip_name_addr_xtra(), sip_name_addr_dup()

Wed Sep 19 19:00:19 EDT 2007  Pekka.Pessi@nokia.com
  * sip_basic.c: cleaned old crud

Thu Sep 20 13:34:04 EDT 2007  Pekka.Pessi@nokia.com
  * iptsec: updated documentation

Thu Sep 20 13:36:22 EDT 2007  Pekka.Pessi@nokia.com
  * tport: updated documentation

Thu Sep 20 13:36:56 EDT 2007  Pekka.Pessi@nokia.com
  * su: updated documentation
  Removed internal files from doxygen-generated documentation.

Thu Sep 20 13:38:29 EDT 2007  Pekka.Pessi@nokia.com
  * soa: fixed documentation

Thu Sep 20 13:39:56 EDT 2007  Pekka.Pessi@nokia.com
  * sdp: updated documentation

Thu Sep 20 13:40:16 EDT 2007  Pekka.Pessi@nokia.com
  * ipt: updated documentation

Thu Sep 20 14:24:20 EDT 2007  Pekka.Pessi@nokia.com
  * nta: updated documentation

Thu Sep 20 14:41:04 EDT 2007  Pekka.Pessi@nokia.com
  * nua: updated documentation

  Updated tag documentation.

  Moved doxygen doc entries from sofia-sip/nua_tag.h to nua_tag.c.

  Removed internal datatypes and files from the generated documents.

Wed Sep 19 13:34:20 EDT 2007  Pekka.Pessi@nokia.com
  * docs: updated the generation of documentation. Updated links to header files.

Thu Sep 20 08:45:32 EDT 2007  Pekka.Pessi@nokia.com
  * sip/Makefile.am: added tags to <sofia-sip/sip_extra.h>

  Added check for extra tags in torture_sip.c.

Thu Sep 20 14:45:22 EDT 2007  Pekka.Pessi@nokia.com
  * stun: updated documentation

Wed Jul  4 18:55:20 EDT 2007  Pekka.Pessi@nokia.com
  * torture_heap.c: added tests for ##sort() and su_smoothsort()

Wed Jul  4 18:56:59 EDT 2007  Pekka.Pessi@nokia.com
  * Makefile.am: added smoothsort.c

Fri Jul 13 12:38:44 EDT 2007  Pekka.Pessi@nokia.com
  * sofia-sip/heap.h: heap_remove() now set()s index to 0 on removed item

Mon Jul 23 11:14:22 EDT 2007  Pekka.Pessi@nokia.com
  * sofia-sip/heap.h: fixed bug in heap##remove()

  If left kid was in heap but right was not, left kid was ignored.

Wed Jul  4 18:51:08 EDT 2007  Pekka.Pessi@nokia.com
  * smoothsort.c: added

Wed Jul  4 18:51:34 EDT 2007  Pekka.Pessi@nokia.com
  * heap.h: using su_smoothsort()

Fri Jul  6 10:20:27 EDT 2007  Pekka.Pessi@nokia.com
  * smoothsort.c: added

Wed Sep 19 17:40:30 EDT 2007  Pekka.Pessi@nokia.com
  * msg_parser.awk: generate two parser tables, default and extended

Wed Sep 19 18:39:45 EDT 2007  Pekka.Pessi@nokia.com
  * msg_parser.awk: just generate list of extra headers

  Allocate extended parser dynamically.

Wed Sep 19 18:59:59 EDT 2007  Pekka.Pessi@nokia.com
  * sip: added Remote-Party-ID, P-Asserted-Identity, P-Preferred-Identity

  Added functions sip_update_default_mclass() and sip_extend_mclass()
  for handling the extended parser. Note that Reply-To and Alert-Info are only
  available with the extended parser.

Wed Sep 19 19:05:44 EDT 2007  Pekka.Pessi@nokia.com
  * RELEASE: updated

Thu Sep 20 13:38:59 EDT 2007  Pekka.Pessi@nokia.com
  * sip: updated documentation

Thu Sep 20 14:17:28 EDT 2007  Pekka.Pessi@nokia.com
  * docs/conformance.docs: updated

Mon Oct  1 10:11:14 EDT 2007  Pekka.Pessi@nokia.com
  * tport_tag.c: re-enabled tptag_trusted

Thu Oct  4 09:21:07 EDT 2007  Pekka.Pessi@nokia.com
  * su_osx_runloop.c: moved virtual function table after struct definition

  Preparing for su_port_vtable_t refactoring.

Thu Oct  4 10:22:03 EDT 2007  Pekka.Pessi@nokia.com
  * su_source.c: refactored initialization/deinitialization

Fri Oct  5 04:58:18 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * sip_extra.c: fixed prototypes with isize_t

Fri Oct  5 04:58:45 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * test_nta_api.c: removed warnings about signedness

Fri Oct  5 04:59:02 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * test_nua_params.c: removed warnings about constness

Fri Oct  5 07:20:26 EDT 2007  Pekka Pessi <first.lastname@nokia.com>
  * su_port.h, su_root.c: cleaned argument checking

  The su_root_*() and su_port_*() functions now check their arguments once
  and do not assert() with NULL arguments. The sur_task->sut_port should
  always be valid while su_root_t is alive.

Fri Oct  5 07:22:09 EDT 2007  Pekka Pessi <first.lastname@nokia.com>
  * su: added su_root_obtain(), su_root_release() and su_root_has_thread()

  When root is created with su_root_create() or cloned with su_clone_start(),
  the resulting root is obtained by the calling or created thread,
  respectively.

  The root can be released with su_root_release() and another thread can
  obtain it.

  The function su_root_has_thread() can be used to check if a thread has
  obtained or released the root.

  Implementation upgraded the su_port_own_thread() method as su_port_thread().

Fri Oct  5 07:28:10 EDT 2007  Pekka Pessi <first.lastname@nokia.com>
  * su_port.h: removed su_port_threadsafe() and su_port_yield() methods

  su_port_wait_events() replaces su_port_yield().

Fri Oct  5 13:26:04 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * msg_parser.awk: not extending header structure unless needed.

  Removed gawk-ish /* comments */.

Fri Oct  5 14:32:25 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * run_test_su: removed GNUisms

Fri Oct  5 14:32:47 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * Makefile.am: removed implicit check target test_urlmap

Fri Oct  5 14:22:32 EDT 2007  Pekka Pessi <first.lastname@nokia.com>
  * torture_sresolv.c: use CLOCK_REALTIME if no CLOCK_PROCESS_CPUTIME_ID available

  Casting timespec tv_sec to unsigned long.

Fri Oct * nua_s added handling nua_prack()

  Thanks to Fabio Margarido for the patch.

Mon Oct  8 10:24:35 EDT 2007  Pekka.Pessi@nokia.com
  * test_nua: added test for sf.net bug #1803686

Mon Oct  8 08:15:23 EDT 2007  Pekka.Pessi@nokia.com
  * RELEASE: updated.

Mon Oct  8 09:30:36 EDT 2007  Pekka.Pessi@nokia.com
  * nua_stack: added handling nua_prack()

  Thanks to Fabio Margarido for the patch.

Mon Oct  8 10:24:35 EDT 2007  Pekka.Pessi@nokia.com
  * test_nua: added test for sf.net bug #1803686

Mon Oct  8 10:26:31 EDT 2007  Pekka.Pessi@nokia.com
  * nua: added test for nua_prack() (sf.net bug #1804248)

  Avoid sending nua_i_state after nua_prack() if no SDP O/A is happening, too.

Mon Oct  8 10:32:04 EDT 2007  Mikhail Zabaluev <mikhail.zabaluev@nokia.com>
  * su_source.c: don t leak the wait arrays

Mon Oct  8 10:37:11 EDT 2007  Pekka.Pessi@nokia.com
  * RELEASE: updated

Wed Oct 10 11:55:21 EDT 2007  Pekka.Pessi@nokia.com
  * sip_parser.c: silenced warning about extra const in sip_extend_mclass()

Wed Oct 10 11:57:08 EDT 2007  Pekka.Pessi@nokia.com
  * nta_tag.c: updated tag documentation

Wed Oct 10 13:16:40 EDT 2007  Pekka.Pessi@nokia.com
  * nua: fix logging crash if outbound used with application contact

  Silenced warnings.

Wed Oct 10 13:30:45 EDT 2007  Pekka.Pessi@nokia.com
  * msg_parser.awk: removed extra "const"

Wed Oct 10 13:31:45 EDT 2007  Pekka.Pessi@nokia.com
  * Makefile.am's: fixed distclean of documentation



git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5840 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Michael Jerris committed 2007-10-11 14:16:59 +00:00
1 parent 24ff890bbb
commit 5e81b98eba
153 files changed
+7633 -4401

No files matched your search

+4 -2
View File
@@ -6,8 +6,10 @@
*
* The Sofia @b bnf module contains macros and functions for parsing
* text-based formats, for example, for SIP. The interface is described in
* <bnf.h>, the <bnf.c> contains a #_bnf_table table used to classify
* characters.
* <sofia-sip/bnf.h>.
*
* The interface used for validating hostnames and IP addresses is in
* <sofia-sip/hostdomain.h>.
*
* @CONTACT Pekka Pessi <Pekka.Pessi@nokia.com>
*
@@ -28,7 +28,7 @@ ALIASES = \
"TAG=\par \n" \
"EVENTS=\par Events:\n" \
"RESPONSES=\par Related Response Codes:\n" \
"CFILE=\file" \
"CFILE=\internal \file" \
"IFILE=\file" \
"HI=\hideinitializer " \
"HIDE=\hideinitializer " \
@@ -23,6 +23,7 @@ COLLABORATION_GRAPH = YES
GROUP_GRAPHS = NO
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
VERBATIM_HEADERS = YES
HIDE_UNDOC_RELATIONS = YES
HIDE_UNDOC_MEMBERS = YES
HIDE_UNDOC_CLASSES = YES
@@ -7,6 +7,7 @@ INPUT = @srcdir@/mainpage.docs @srcdir@/docguide.docs @srcdir@/conformanc
@INCLUDE_PATH = . @srcdir@
@INCLUDE = ../docs/Doxyfile.conf
@INCLUDE = ../sip/sip.doxyaliases
GENERATE_TAGFILE = docs.doxytags
@@ -28,4 +29,6 @@ TAGFILES += nea.doxytags=nea
TAGFILES += nua.doxytags=nua
TAGFILES += features.doxytags=features
EXAMPLE_PATH = @srcdir@/../sip
@@ -40,7 +40,10 @@ Doxyfile.rfc:
from=700 to=4800 \
/dev/null > $@
CLEANFILES = Doxyfile.rfc
CLEANFILES = Doxyfile.rfc *.doxytags
distclean-local:
-rm -rf html
# ----------------------------------------------------------------------
# Sofia specific rules
@@ -20,32 +20,37 @@ below.
<a href="#3313">RFC 3313</a> <br>
<a href="#3323">RFC 3323</a> <br>
<a href="#3326">RFC 3326</a> <br>
</td><td>
<a href="#3325">RFC 3325</a> <br>
<a href="#3327">RFC 3327</a> <br>
</td><td>
<a href="#3329">RFC 3329</a> <br>
<a href="#3361">RFC 3361</a> <br>
<a href="#3420">RFC 3420</a> <br>
<a href="#3428">RFC 3428</a> <br>
<a href="#3486">RFC 3486</a> <br>
<a href="#3515">RFC 3515</a> <br>
<a href="#3581">RFC 3581</a> <br>
<a href="#3608">RFC 3608</a> <br>
<a href="#3680">RFC 3680</a> <br>
<a href="#3824">RFC 3824</a> <br>
</td><td>
<a href="#3840">RFC 3840</a> <br>
<a href="#3841">RFC 3841</a> <br>
<a href="#3842">RFC 3842</a> <br>
</td><td>
<a href="#3856">RFC 3856</a> <br>
<a href="#3857">RFC 3857</a> <br>
<a href="#3858">RFC 3858</a> <br>
<a href="#3859">RFC 3859</a> <br>
<a href="#3860">RFC 3860</a> <br>
<a href="#3891">RFC 3891</a> <br>
<a href="#3892">RFC 3892</a> <br>
<a href="#3903">RFC 3903</a> <br>
<a href="#4028">RFC 4028</a> <br>
<a href="#4168">RFC 4168</a> <br>
<a href="#4320">RFC 4320</a> <br>
<a href="#4566">RFC 4566</a> <br>
<a href="#4488">RFC 4488</a> <br>
</td><td>
<a href="#4566">RFC 4566</a> <br>
<a href="#2327">RFC 2327</a> <br>
<a href="#3264">RFC 3264</a> <br>
<a href="#3266">RFC 3266</a> <br>
@@ -53,6 +58,7 @@ below.
<a href="#3388">RFC 3388</a> <br>
<a href="#3407">RFC 3407</a> <br>
<a href="#3524">RFC 3524</a> <br>
<a href="#3551">RFC 3551</a> <br>
<a href="#3556">RFC 3556</a> <br>
<a href="#3605">RFC 3605</a> <br>
<a href="#3890">RFC 3890</a> <br>
@@ -98,7 +104,7 @@ below.
</td>
<td>
The supported @RFC3261 methods are: @b REGISTER, @b OPTIONS, @b
INVITE, @b ACK, @b CANCEL, @b BYE, as well as methods
INVITE, @b ACK, @b CANCEL, @b BYE, as well as extension methods
<a href="#2976"><b>INFO</b></a>,
<a href="#3262"><b>PRACK</b></a>,
<a href="#3265"><b>SUBSCRIBE</b></a>,
@@ -116,7 +122,7 @@ below.
@ref sip_accept "Accept",
@ref sip_accept_encoding "Accept-Encoding",
@ref sip_accept_language "Accept-Language",
@ref sip_alert_info "Alert-Info" (@VERSION_1_12_7),
@ref sip_alert_info "Alert-Info" (extension in @VERSION_1_12_7),
@ref sip_allow "Allow",
@ref sip_authentication_info "Authentication-Info",
@ref sip_authorization "Authorization",
@@ -138,12 +144,18 @@ below.
@ref sip_min_expires "Min-Expires",
@ref sip_mime_version "MIME-Version",
@ref sip_organization "Organization",
@ref sip_p_asserted_identity "P-Asserted-Identity"
(extension in @VERSION_1_12_7),
@ref sip_p_preferred_identity "P-Preferred-Identity"
(extension in @VERSION_1_12_7),
@ref sip_priority "Priority",
@ref sip_proxy_authenticate "Proxy-Authenticate",
@ref sip_proxy_authorization "Proxy-Authorization",
@ref sip_proxy_require "Proxy-Require",
@ref sip_record_route "Record-Route",
@ref sip_reply_to "Reply-To" (@VERSION_1_12_7),
@ref sip_refer_sub "Refer-Sub" (@VERSION_1_12_5),
@ref sip_remote_party_id "Remote-Party-ID" (extension in @VERSION_1_12_7),
@ref sip_reply_to "Reply-To" (extension in @VERSION_1_12_7),
@ref sip_require "Require",
@ref sip_retry_after "Retry-After",
@ref sip_route "Route",
@@ -167,7 +179,7 @@ below.
<td>
- Automatic escaping of reserved characters has not been
implemented.
- Using NUL (zero byte) in doublequoted strings has not been implemented
- Using NUL (zero byte) in double-quoted strings has not been implemented
</td>
</tr>
@@ -196,7 +208,7 @@ below.
Only one SIP message is accepted per UDP message, as per @RFC3261.
</td>
<td>
There is experimental support for SCTP, too.
There is <a href="#4168">experimental support for SCTP</a>, too.
</td>
</tr>
@@ -212,8 +224,12 @@ below.
User-Agent and Proxy modes.
Default values for SIP timers are those specified by @RFC3261. The
defaults for T1, T1x64, T2 and T4 can be changed via
values for T1, T1x64, T2 and T4 can be changed via
configuration tags defined in <sofia-sip/nta_tag.h>.
The SIP timer C is implemented from @VERSION_1_12_7. Also, its value
can be changed via configuration tag NTATAG_TIMER_C() defined in
<sofia-sip/nta_tag.h>.
</td>
<td>
&nbsp;
@@ -462,10 +478,13 @@ below.
@RFC3325: Asserted Identity
</th>
<td>
Sofia-SIP provides <a href="#3261.19">generic support</a> for
extension headers and parameters. P-Asserted-Identity and
P-Preferred-Identity are supported as supported as @ref
sip_unknown "extension headers".
Sofia-SIP supports
@ref sip_p_asserted_identity "P-Asserted-Identity" and
@ref sip_p_preferred_identity "P-Preferred-Identity" headers
(generating, parsing and syntax checking). Also the non-standard
header @ref sip_remote_party_id "Remote-Party-ID" is supported.
@NEW_1_12_7.
</td>
<td>
Not implemented:
@@ -733,10 +752,11 @@ below.
</td>
</tr>
<a name="3856"></a>
<a name="3856"></a><a name="3859"></a>
<tr valign=top>
<th align="left">
@RFC3856: Presence
@RFC3856: Presence <br />
@RFC3859: Common Profile for Presence
</th>
<td>
Sofia-SIP supports <a href="#3265">generic SIP event support</a> for
@@ -778,7 +798,22 @@ below.
- Including correct @ref sip_event "Event" and
@ref sip_accept "Accept" headers in the request (if needed)
- Processing notifications for winfo events:
- Processing watcherxinfo XML documents
- Processing watcherinfo XML documents
</td>
</tr>
<a name="3860"></a>
<tr valign=top>
<th align="left">
@RFC3860: Common Profile for IM
</th>
<td>
Sofia-SIP supports handling of any URI type. Sofia-SIP parses "im:"
URIs.
</td>
<td>
Application must take care of:
- resolving the "im:" URI
</td>
</tr>
@@ -834,7 +869,7 @@ below.
<td>
Application must take care of:
- Including correct @ref sip_event "Event" in the request
- Permanently storing SIP-ETag
- Permanently storing @SIPETag
</td>
</tr>
@@ -864,6 +899,26 @@ below.
</td>
</tr>
<a name="4168"></a>
<tr valign=top>
<th align="left">
@RFC4168: SCTP as Transport for SIP
</th>
<td>
The transport=sctp URI parameter is supported. The SCTP transport
protocol is supported as experimental. It is enabled with
configure script argument --enable-sctp.
The framing of SIP messages over SCTP is not specified clearly in
@RFC4168. It is possible to send SIP messages smaller than 64K over
SCTP.
</td>
<td>
&nbsp;
</td>
</tr>
<a name="4320"></a>
<tr valign=top>
<th align="left">
@@ -886,6 +941,28 @@ below.
</td>
</tr>
<a name="4488"></a>
<tr valign=top>
<th align="left">
@RFC4488: Suppression of REFER Implicit Subscription
</th>
<td>
Sofia-SIP supports @ref sip_refer_sub "Refer-Sub" header
(generating, parsing and syntax checking).
The implicit subscription is suppressed by @nua, if the @ReferSub:
true header is included in the REFER
request (@ref nua_refer "on server side") or
response (@ref nua_i_refer "on client side").
@NEW_1_12_5
</td>
<td>
The REFER client application must include SIPTAG_REFER_SUB_STR("true")
in the nua_refer() tags.
</td>
</tr>
</table>
<table border=1 cellpadding=4 cellspacing=0>
@@ -922,7 +999,7 @@ below.
"a=inactive", @ref sdp_rtpmap_s "a=rtpmap", and "a=fmtp" are parsed.
The implementation partially implements @RFC4566. Note that
definiton of 'token' was updated in @RFC4566 and the parser has not
definition of 'token' was updated in @RFC4566 and the parser has not
been updated yet.
</td>
<td>
@@ -1023,6 +1100,23 @@ below.
</td>
</tr>
<a name="3551"></a>
<tr valign=top>
<th align="left">
@RFC3551: RTP/AVP
</th>
<td>
Sofia-SIP recognizes the RTP payload types for well-known audio and
video codecs defined in @RFC3551.
</td>
<td>
Application must take care of:
- Audio or video processing
- Generating a=rtpmap or a=fmtp lines when needed
</td>
</tr>
<a name="3556"></a>
<tr valign=top>
<th align="left">
@@ -260,7 +260,7 @@ C 99 standard defines the following fixed length data types:
- int8_t
- uint8_t
To use these data types you must include the <su_types.h> header, which
To use these data types you must include the <sofia-sip/su_types.h> header, which
takes care of including correct file. If @b su includes are not available,
you must include the following code segment to each file where you plan to
use them:
@@ -298,7 +298,7 @@ network byte order to host byte order.
The ntohs() function converts the unsigned short integer netshort
from network byte order to host byte order.
You need to include <netinet/in.h> or <su.h> to use these functions.
You need to include <netinet/in.h> or <sofia-sip/su.h> to use these functions.
@subsection port_struct Packing structures
@@ -467,7 +467,7 @@ reference. This simplifies application logic because application code does
not need to keep track of the allocated memory and free every allocated block
separately.
See documentation of <su_alloc.h> and @ref su_alloc "memory managment tutorial"
See documentation of <sofia-sip/su_alloc.h> and @ref su_alloc "memory managment tutorial"
for more information of memory management services.
@subsection contextdata Memory management of context data
@@ -532,7 +532,7 @@ controlled by upper level memory management.
@section testing Testing Your Code
See <tstdef.h> for example of how to write module tests with macros provided
See <sofia-sip/tstdef.h> for example of how to write module tests with macros provided
by Sofia.
Here are some ideas of what you should test:
@@ -15,7 +15,7 @@
*
* @section http_overview Overview
*
* Each HTTP header has a structure defined for it in <http.h>. All the
* Each HTTP header has a structure defined for it in <sofia-sip/http.h>. All the
* variables, objects and functions related to a particular HTTP header are
* documented in a <a href="modules.html">submodule</a> for the header. In
* addition to the header structure, there is defined a @em header @em class
@@ -30,7 +30,7 @@
*
*/
/**@file http_tag.c HTTP Tag classes
/**@internal @file http_tag.c HTTP Tag classes
*
* This file is autogenerated from <http_tag.c.in>.
*
@@ -1,7 +1,9 @@
PROJECT_NAME = "ipt"
OUTPUT_DIRECTORY = ../docs/html/ips
OUTPUT_DIRECTORY = ../docs/html/ipt
INPUT = @srcdir@/ipt.docs @srcdir@/sofia-sip @srcdir@ .
INPUT = @srcdir@/ipt.docs
INPUT += @srcdir@/sofia-sip/base64.h @srcdir@/base64.c
INPUT += @srcdir@/sofia-sip/token64.h @srcdir@/token64.c
@INCLUDE_PATH = . @srcdir@
@INCLUDE = ../docs/Doxyfile.conf
+2 -2
View File
@@ -15,6 +15,6 @@
* @section ipt_overview Overview
*
* This module contain some routines useful for IPT applications, like
* - <sofia-sip/base64.h> BASE64 encoding/decoding,
* - <sofia-sip/token64.h> encoding/decoding binary as SIP/HTTP token,
* - <sofia-sip/base64.h> BASE64 encoding/decoding, and
* - <sofia-sip/token64.h> encoding/decoding binary as SIP/HTTP token.
*/
@@ -57,7 +57,7 @@ SOFIAPUBFUN isize_t base64_e(char buf[], isize_t bsiz, void *data, isize_t dsiz)
/** Calculate size of n bytes encoded in base64 */
#define BASE64_SIZE(n) ((((n) + 2) / 3) * 4)
/** Calculate size of n bytes encoded in base64 sans trailing =. @NEW_1_12_5 */
/** Calculate size of n bytes encoded in base64 sans trailing =. @NEW_1_12_5. */
#define BASE64_MINSIZE(n) ((n * 4 + 2) / 3)
SOFIA_END_DECLS
+2 -2
View File
@@ -22,7 +22,7 @@
*
*/
/**@CFILE token64.c
/**@internal @file token64.c
*
* Token encoding.
*
@@ -41,7 +41,7 @@
static const char code[65] =
"0123456789-abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ";
/** Encode data as an http token.
/** Encode data as a SIP/HTTP token.
*
* @note
* A token is case-independent, so this is really not a good idea.
@@ -20,7 +20,7 @@ TAGFILES += ../docs/nta.doxytags=../nta
GENERATE_TAGFILE = ../docs/iptsec.doxytags
ALIASES +=
ALIASES += "iptsec=@ref index \"iptsec\""
PREDEFINED += SOFIA_EXTEND_AUTH_CLIENT=1
@@ -205,15 +205,17 @@ int ca_challenge(auth_client_t *ca,
* processed.
*
* @bug
* The result can be quite unexpected if there are more than one
* authenticator with the given type (specified by @a crcl). In principle,
* SIP allows more than one challenge for a single request.
* In principle, SIP allows more than one challenge for a single request.
* For example, there can be multiple proxies that each challenge the
* client. The result of storing authentication info can be quite unexpected
* if there are more than one authenticator with the given type (specified
* by @a credential_class).
*
* @retval number of challenges to updated
* @retval 0 when there was no challenge to update
* @retval -1 upon an error
*
* @NEW_1_12_5
* @NEW_1_12_5.
*/
int auc_info(auth_client_t **auc_list,
msg_auth_info_t const *info,
@@ -525,7 +527,7 @@ int ca_clear_credentials(auth_client_t *ca)
* @retval 1 when authorization can proceed
* @retval 0 when there is not enough credentials
*
* @NEW_1_12_5
* @NEW_1_12_5.
*/
int auc_has_authorization(auth_client_t **auc_list)
{
@@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file auth_module_http.c
* @brief Authenticate HTTP request
*
@@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file auth_module_sip.c
* @brief Authenticate SIP request
*
@@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file auth_plugin.c
* @brief Plugin interface for authentication verification modules.
*
@@ -22,7 +22,7 @@
*
*/
/**@file iptsec_debug.c
/**@internal @file iptsec_debug.c
* @brief Debug log for IPTSEC module.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
@@ -36,25 +36,34 @@
#include "iptsec_debug.h"
/**@var IPTSEC_DEBUG
#if DOXYGEN_ONLY
/** @defgroup iptsec_env Environment Variables Used by iptsec Module
*
* Environment variable determining the debug log level for @b iptsec
* @brief Environment variables used by @iptsec module are listed here.
*
* The #IPTSEC_DEBUG variable sets the debug level.
*/
/**@ingroup iptsec_env
*
* Environment variable determining the debug log level for @iptsec
* module.
*
* The IPTSEC_DEBUG environment variable is used to determine the debug
* logging level for @b iptsec module. The default level is 3.
* logging level for @iptsec module. The default level is 3.
*
* @sa <sofia-sip/su_debug.h>, iptsec_log, SOFIA_DEBUG
* @sa <sofia-sip/su_debug.h>, #iptsec_log, #SOFIA_DEBUG
*/
extern char const IPTSEC_DEBUG[];
extern IPTSEC_DEBUG;
#endif
#ifndef SU_DEBUG
#define SU_DEBUG 3
#endif
/**Debug log for @b iptsec module.
/** Common log for client and server components.
*
* The iptsec_log is the log object used by @b iptsec module. The level of
* The iptsec_log is the log object used by @iptsec module. The level of
* #iptsec_log is set using #IPTSEC_DEBUG environment variable.
*/
su_log_t iptsec_log[] = { SU_LOG_INIT("iptsec", "IPTSEC_DEBUG", SU_DEBUG) };
@@ -26,7 +26,8 @@
/** Defined when <iptsec_debug.h> has been included. */
#define IPTSEC_DEBUG_H
/**@file iptsec_debug.h
/**@internal
* @file iptsec_debug.h
* @brief Debug log for IPTSEC module.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
@@ -38,7 +39,7 @@
SOFIA_BEGIN_DECLS
/** Common log for application and srvlib components. */
/** Common log for client and server components. */
SOFIAPUBVAR su_log_t iptsec_log[];
SOFIA_END_DECLS
@@ -91,12 +91,12 @@ struct auth_client_plugin
int (*auc_info)(auth_client_t *ca, msg_auth_info_t const *ai);
#if SOFIA_EXTEND_AUTH_CLIENT
/** Clear credentials (user/pass). @NEW_1_12_6 */
/** Clear credentials (user/pass). @NEW_1_12_6. */
int (*auc_clear)(auth_client_t *ca);
#endif
};
/** Check if authentication client has been extended. @NEW_1_12_6 */
/** Check if authentication client has been extended. @NEW_1_12_6. */
#define AUTH_CLIENT_IS_EXTENDED(ca) \
((ca)->ca_auc->auc_plugin_size > \
(int)offsetof(auth_client_plugin_t, auc_clear) \
@@ -7,6 +7,8 @@ INPUT = @srcdir@/msg.docs @srcdir@/sofia-sip sofia-sip @srcdir@ .
@INCLUDE = ../docs/Doxyfile.conf
@INCLUDE = ../sip/sip.doxyaliases
EXCLUDE_PATTERNS += msg_test*.h msg_test*.c
TAGFILES += ../docs/ipt.doxytags=../ipt \
../docs/su.doxytags=../su \
../docs/sip.doxytags=../sip \
+1 -1
View File
@@ -22,7 +22,7 @@
*
*/
/**@file msg.c Message object implementation.
/**@internal @file msg.c Message object implementation.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
+2 -2
View File
@@ -142,7 +142,7 @@ separator and the message body are all in their own fragment structure. The
fragments form a dual-linked list known as @e fragment @e chain as shown in
the above figure. The memory buffers for the message, the fragment chain,
and a whole lot of other stuff is held by the generic message type, #msg_t,
defined in <msg.h>. The internal structure of #msg_t is known only within @b
defined in <sofia-sip/msg.h>. The internal structure of #msg_t is known only within @b
msg module and it is opaque to other modules.
The @b msg parser engine also drives the reverse process, invoking the
@@ -262,7 +262,7 @@ header members that are also found in the beginning of a header
structure. The @e sip_size indicates the size of the structure - the
application can extend the parser and #sip_t structure beyond the
original size. The @e sip_flags contains various flags used during the
parsing and printing process. They are documented in the <msg.h>. These
parsing and printing process. They are documented in the <sofia-sip/msg.h>. These
boilerplate members are followed by the pointers to various message
elements and headers.
@@ -22,7 +22,8 @@
*
*/
/**@ingroup msg_parser
/**@internal
* @ingroup msg_parser
* @file msg_generic.c
* @brief Functions for generic headers
*
@@ -67,36 +67,6 @@ size_t memcspn(const void *mem, size_t memlen,
/** Protocol version of MIME */
char const msg_mime_version_1_0[] = "MIME/1.0";
/* Internally used version of msg_header_t */
union msg_mime_u
{
msg_common_t sh_common[1];
struct {
msg_common_t shn_common;
msg_header_t *shn_next;
} sh_header_next[1];
msg_multipart_t sh_multipart[1];
msg_accept_t sh_accept[1];
msg_accept_any_t sh_accept_any[1];
msg_accept_charset_t sh_accept_charset[1];
msg_accept_encoding_t sh_accept_encoding[1];
msg_accept_language_t sh_accept_language[1];
msg_content_disposition_t sh_content_disposition[1];
msg_content_encoding_t sh_content_encoding[1];
msg_content_id_t sh_content_id[1];
msg_content_language_t sh_content_language[1];
msg_content_length_t sh_content_length[1];
msg_content_location_t sh_content_location[1];
msg_content_type_t sh_content_type[1];
msg_mime_version_t sh_mime_version[1];
msg_warning_t sh_warning[1];
msg_unknown_t sh_unknown[1];
msg_separator_t sh_separator[1];
msg_payload_t sh_payload[1];
};
#include <sofia-sip/msg_parser.h>
#include <sofia-sip/msg_mime_protos.h>
+182 -102
View File
@@ -54,25 +54,26 @@ BEGIN {
split("", NAMES);
split("", Comments);
split("", COMMENTS);
split("", experimental);
# indexed by the C name of the header
split("", Since); # Non-NUL if extra
split("", Extra); # Offset in extra headers
total = 0;
ordinary = 0;
basic = 0;
extra = 0;
without_experimental = 0;
template="";
template1="";
template2="";
template3="";
prefix="";
tprefix="";
extra=0;
failed=0;
success=0;
extra_struct = "msg_pub_extra";
ERRNO="error";
}
@@ -159,7 +160,6 @@ function protos (name, comment, hash, since)
symbols[name] = comment;
if (since) {
Since[name] = since;
Extra[name] = extra++;
}
expr = (without_experimental > 0 && do_hash);
@@ -210,7 +210,7 @@ function replace (p, hash, name, NAME, comment, Comment, COMMENT, since)
#
# Repeat each line in the footer containing the magic replacement
# pattern with a instance of all headers
# pattern with an instance of all headers
#
function process_footer (text)
{
@@ -368,9 +368,14 @@ function templates ()
}
/^#### EXTRA HEADER LIST STARTS HERE ####$/ { HLIST=1; templates(); }
HLIST && /^#### DEFAULT HEADER LIST ENDS HERE ####$/ { basic=total; }
HLIST && /^#### EXPERIMENTAL HEADER LIST STARTS HERE ####$/ {
without_experimental=total; }
HLIST && /^[a-z]/ { protos($1, $0, 0, $2); headers[total++] = $1; }
without_experimental = total; }
HLIST && /^[a-z]/ { protos($1, $0, 0, $2);
headers[total++] = $1;
Extra[$1] = extra++;
}
/^#### EXTRA HEADER LIST ENDS HERE ####$/ { HLIST=0; }
/^ *\/\* === Headers start here \*\// { in_header_list=1; templates(); }
@@ -396,15 +401,117 @@ in_header_list && /^ (sip|rtsp|http|msg|mp)_[a-z_0-9]+_t/ {
if (!NO_MIDDLE)
protos(n, $0, 0);
headers[total++] = n;
headers[total] = n; total++; ordinary++;
}
function print_parser_table(struct, scope, name, N, N_EXPERIMENTAL)
{
if (PT) {
if (N > ordinary) {
printf("/* Ordinary %u, extra %u, experimental %u */\n",
ordinary, N - ordinary, N_EXPERIMENTAL - N) > PT;
printf("struct %s {\n", struct) > PT;
printf(" %s_t base;\n", module) > PT;
printf(" msg_header_t *extra[%u];\n", N - ordinary) > PT;
if (N != N_EXPERIMENTAL) {
print "#if SU_HAVE_EXPERIMENTAL" > PT;
printf(" msg_header_t *extra[%u];\n", N_EXPERIMENTAL - N) > PT;
print "#endif" > PT;
}
printf("};\n\n") > PT;
}
printf("%s\n", scope) > PT;
printf("msg_mclass_t const %s[1] = \n{{\n", name) > PT;
printf("# if defined (%s_HCLASS)\n", toupper(module)) > PT;
printf(" %s_HCLASS,\n", toupper(module)) > PT;
printf("#else\n") > PT;
printf(" {{ 0 }},\n") > PT;
printf("#endif\n") > PT;
printf(" %s_VERSION_CURRENT,\n", toupper(module)) > PT;
printf(" %s_PROTOCOL_TAG,\n", toupper(module)) > PT;
printf("#if defined (%s_PARSER_FLAGS)\n", toupper(module)) > PT;
printf(" %s_PARSER_FLAGS,\n", toupper(module)) > PT;
printf("#else\n") > PT;
printf(" 0,\n") > PT;
printf("#endif\n") > PT;
if (N > ordinary) {
printf(" sizeof (struct %s),\n", struct) > PT;
}
else {
printf(" sizeof (%s_t),\n", module) > PT;
}
printf(" %s_extract_body,\n", module) > PT;
len = split("request status separator payload unknown error", unnamed, " ");
for (i = 1; i <= len; i++) {
printf(" {{ %s_%s_class, msg_offsetof(%s_t, %s_%s) }},\n",
tprefix, unnamed[i], module, prefix, unnamed[i]) > PT;
}
if (multipart) {
printf(" {{ %s_class, msg_offsetof(%s_t, %s_multipart) }},\n",
multipart, module, prefix) > PT;
} else {
printf(" {{ NULL, 0 }},\n") > PT;
}
if (MC_SHORT_SIZE) {
printf(" %s_short_forms, \n", module) > PT;
}
else {
printf(" NULL, \n") > PT;
}
printf(" %d, \n", MC_HASH_SIZE) > PT;
if (N != N_EXPERIMENTAL) {
print "#if SU_HAVE_EXPERIMENTAL" > PT;
printf(" %d,\n", N_EXPERIMENTAL) > PT;
print "#else" > PT;
}
printf(" %d,\n", N) > PT;
if (N != N_EXPERIMENTAL) {
print "#endif" > PT;
}
printf(" {\n") > PT;
for (j = 0; j < MC_HASH_SIZE; j++) {
c = (j + 1 == MC_HASH_SIZE) ? "" : ",";
if (j in header_hash) {
n = header_hash[j];
i = index_hash[j];
flags = header_flags[n]; if (flags) flags = ",\n " flags;
if (i >= N) {
print "#if SU_HAVE_EXPERIMENTAL" > PT;
}
if (i >= ordinary) {
printf(" { %s_%s_class,\n" \
" msg_offsetof(struct %s, extra[%u])%s }%s\n",
tprefix, n, struct, Extra[n], flags, c) > PT;
}
else {
printf(" { %s_%s_class, msg_offsetof(%s_t, %s_%s)%s }%s\n",
tprefix, n, module, prefix, n, flags, c) > PT;
}
if (i >= N) {
printf("#else\n { NULL, 0 }%s\n#endif\n", c) > PT;
}
}
else {
printf(" { NULL, 0 }%s\n", c) > PT;
}
}
printf(" }\n}};\n\n") > PT;
}
}
END {
if (failed) { exit };
if (without_experimental == 0)
without_experimental = total;
if (!NO_LAST) {
protos("unknown", "/**< Unknown headers */", -3);
protos("error", "/**< Erroneous headers */", -4);
@@ -429,8 +536,6 @@ END {
getline footer < TEMPLATE;
RS=RS0;
module_struct = module "_t";
sub(/.*[\/]/, "", TEMPLATE);
gsub(/#AUTO#/, auto, header);
gsub(/#DATE#/, "@date Generated: " date, header);
@@ -451,9 +556,9 @@ END {
n = shorts[i];
flags = header_flags[n]; if (flags) flags = ",\n " flags;
printf(" { /* %s */ %s_%s_class, msg_offsetof(%s_t, %s_%s)%s }%s\n",
substr(lower_case, i, 1),
tprefix, n, module, prefix, n, flags, c) \
printf(" { /* %s */ %s_%s_class, msg_offsetof(%s_t, %s_%s)%s }%s\n",
substr(lower_case, i, 1),
tprefix, n, module, prefix, n, flags, c) \
> PT;
}
else {
@@ -466,67 +571,13 @@ END {
# printf("extern msg_hclass_t msg_multipart_class[];\n\n") > PT;
if (extra > 0) {
printf("struct %s {\n", extra_struct) > PT;
printf(" %s base;\n", module_struct) > PT;
if (total - without_experimental < extra) {
printf(" msg_header_t *extra[%u];\n",
extra - (total - without_experimental)) > PT;
}
if (total - without_experimental > 0) {
print "#if SU_HAVE_EXPERIMENTAL" > PT;
printf(" msg_header_t *experimental[%u];\n",
total - without_experimental) > PT;
print "#endif" > PT;
}
printf("};\n\n") > PT;
module_struct = "struct " extra_struct;
}
if (basic == 0) basic = total;
if (without_experimental == 0) without_experimental = total;
printf("msg_mclass_t const %s_mclass[1] = \n{{\n", module) > PT;
printf("# if defined (%s_HCLASS)\n", toupper(module)) > PT;
printf(" %s_HCLASS,\n", toupper(module)) > PT;
printf("#else\n") > PT;
printf(" {{ 0 }},\n") > PT;
printf("#endif\n") > PT;
printf(" %s_VERSION_CURRENT,\n", toupper(module)) > PT;
printf(" %s_PROTOCOL_TAG,\n", toupper(module)) > PT;
printf("#if defined (%s_PARSER_FLAGS)\n", toupper(module)) > PT;
printf(" %s_PARSER_FLAGS,\n", toupper(module)) > PT;
printf("#else\n") > PT;
printf(" 0,\n") > PT;
printf("#endif\n") > PT;
printf(" sizeof (%s),\n", module_struct) > PT;
printf(" %s_extract_body,\n", module) > PT;
split("", header_hash);
split("", index_hash);
len = split("request status separator payload unknown error", unnamed, " ");
for (i = 1; i <= len; i++) {
printf(" {{ %s_%s_class, msg_offsetof(%s_t, %s_%s) }},\n",
tprefix, unnamed[i], module, prefix, unnamed[i]) > PT;
}
if (multipart) {
printf(" {{ %s_class, msg_offsetof(%s_t, %s_multipart) }},\n",
multipart, module, prefix) > PT;
} else {
printf(" {{ NULL, 0 }},\n") > PT;
}
if (MC_SHORT_SIZE) {
printf(" %s_short_forms, \n", module) > PT;
}
else {
printf(" NULL, \n") > PT;
}
printf(" %d, \n", MC_HASH_SIZE) > PT;
printf ("#if SU_HAVE_EXPERIMENTAL\n" \
" %d,\n" \
"#else\n" \
" %d,\n" \
"#endif\n", \
total, without_experimental) > PT;
printf(" {\n") > PT;
for (i = 0; i < total; i++) {
for (i = 0; i < basic; i++) {
n = headers[i];
h = hashed[n];
@@ -542,38 +593,67 @@ END {
}
header_hash[j] = n;
experimental2[j] = (i >= without_experimental);
index_hash[j] = i;
}
for (i = 0; i < MC_HASH_SIZE; i++) {
c = (i + 1 == MC_HASH_SIZE) ? "" : ",";
if (i in header_hash) {
n = header_hash[i];
flags = header_flags[n]; if (flags) flags = ",\n " flags;
m = module "_mclass";
s = "_d_" module "_t";
if (experimental2[i]) {
# Add basic headers
if (ordinary == basic) {
print_parser_table(s, "", m, basic, basic);
}
else if (basic < without_experimental) {
print_parser_table(s, "", m, basic, basic);
}
else {
print_parser_table(s, "", m, without_experimental, basic);
}
if (0) {
# Hash extra headers
for (i = basic; i < total; i++) {
n = headers[i];
h = hashed[n];
if (h < 0)
continue;
j = h % MC_HASH_SIZE; if (j == -0) j = 0;
for (; j in header_hash;) {
if (++j == MC_HASH_SIZE) {
j = 0;
}
}
header_hash[j] = n;
index_hash[j] = i;
}
if (basic < total) {
m = module "_ext_mclass";
s = "_e_" module "_s";
print_parser_table(s, "static", m, without_experimental, total);
}
printf("msg_mclass_t const * %s_extended_mclass = %s;\n\n", module, m) > PT;
}
if (basic < total) {
printf("msg_hclass_t * const %s_extensions[] = {\n", module) > PT;
for (i = basic; i < total; i++) {
if (i == without_experimental) {
print "#if SU_HAVE_EXPERIMENTAL" > PT;
}
if (Since[n]) {
printf(" { %s_%s_class,\n" \
" msg_offsetof(struct %s, extra[%u])%s }%s\n",
tprefix, n, extra_struct, Extra[n], flags, c) > PT;
}
else {
printf(" { %s_%s_class, msg_offsetof(%s_t, %s_%s)%s }%s\n",
tprefix, n, module, prefix, n, flags, c) > PT;
}
if (experimental2[i]) {
printf("#else\n { NULL, 0 }%s\n#endif\n", c) > PT;
}
}
else {
printf(" { NULL, 0 }%s\n", c) > PT;
}
printf(" %s_%s_class,\n", module, headers[i]) > PT;
}
if (total != without_experimental)
print "#endif" > PT;
print " NULL\n};\n\n" > PT;
}
printf(" }\n}};\n\n") > PT;
}
exit success;
@@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file nea_event.c
* @brief Default MIME type for certain events.
*
@@ -22,7 +22,7 @@
*
*/
/**@file nea_server.c
/**@internal @file nea_server.c
* @brief Nokia Event API - event notifier implementation.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
@@ -65,7 +65,7 @@
/** Number of primary views (with different MIME type or content) */
#define NEA_VIEW_MAX (8)
/** Server object, created for every notifier.
/** @internal Server object, created for every notifier.
*/
struct nea_server_s {
su_home_t nes_home[1];
@@ -112,7 +112,7 @@ struct nea_server_s {
};
/** Supported events and their subscribers */
/** @internal Supported events and their subscribers */
struct nea_event_s {
nea_event_t *ev_next;
nea_event_t **ev_prev;
@@ -141,7 +141,7 @@ struct nea_event_s {
typedef struct nea_event_queue_s nea_event_queue_t;
/** Object representing particular view of event */
/** @internal Object representing particular view of event */
struct nea_event_view_s
{
nea_event_view_t *evv_next;
@@ -156,7 +156,7 @@ struct nea_event_view_s
unsigned evv_reliable:1; /**< Keep all notifications */
unsigned:0;
/** Queued notification */
/** @internal Queued notification */
struct nea_event_queue_s
{
nea_event_queue_t *evq_next;
@@ -173,7 +173,7 @@ struct nea_event_view_s
#define evv_payload evv_head->evq_payload
/** Subscription object
/** @internal Subscription object.
*/
struct nea_sub_s {
nea_sub_t *s_next;
+8 -3
View File
@@ -4538,7 +4538,7 @@ nta_incoming_t *incoming_create(nta_agent_t *agent,
irq->irq_home = home = msg_home(msg_ref_create(msg));
irq->irq_agent = agent;
irq->irq_received = agent_now(agent);
irq->irq_received = agent_now(agent); /* Timestamp originally from tport */
irq->irq_method = method;
irq->irq_rq = sip_request_copy(home, sip->sip_request);
@@ -5129,7 +5129,12 @@ nta_incoming_magic_t *nta_incoming_magic(nta_incoming_t *irq,
return irq && irq->irq_callback == callback ? irq->irq_magic : NULL;
}
/** When received */
/** When received.
*
* Return timestamp from the reception of the initial request.
*
* @NEW_1_12_7.
*/
sip_time_t nta_incoming_received(nta_incoming_t *irq,
su_nanotime_t *return_nano)
{
@@ -6768,7 +6773,7 @@ unsigned nta_outgoing_delay(nta_outgoing_t const *orq)
return orq != NULL && orq != NONE ? orq->orq_delay : UINT_MAX;
}
/** Get the branch parameter. @NEW_1_12_7 */
/** Get the branch parameter. @NEW_1_12_7. */
char const *nta_outgoing_branch(nta_outgoing_t const *orq)
{
return orq != NULL && orq != NONE && orq->orq_branch
@@ -26,7 +26,8 @@
/** Defined when <nta_internal.h> has been included. */
#define NTA_INTERNAL_H
/**@IFILE nta_internal.h
/**@internal @file nta_internal.h
*
* @brief Internals of NTA objects.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
File diff suppressed because it is too large. Load diff
@@ -22,8 +22,8 @@
*
*/
/**@file portbind.c
* @brief bind a socket to an UDP/TCP port and return the port number
/**@internal @file portbind.c
* @brief Bind a socket to an UDP/TCP port and return the port number
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
@@ -63,25 +63,25 @@ typedef struct nta_incoming_s nta_incoming_t;
#ifndef NTA_AGENT_MAGIC_T
/** Default type of application context for NTA agents.
* Application may define this to appropriate type before including
* <nta.h>. */
* <sofia-sip/nta.h>. */
#define NTA_AGENT_MAGIC_T struct nta_agent_magic_s
#endif
#ifndef NTA_LEG_MAGIC_T
/** Default type of application context for NTA call legs.
* Application may define this to appropriate type before including
* <nta.h>. */
* <sofia-sip/nta.h>. */
#define NTA_LEG_MAGIC_T struct nta_leg_magic_s
#endif
#ifndef NTA_OUTGOING_MAGIC_T
/** Default type of application context for outgoing NTA requests.
* Application may define this to appropriate type before including
* <nta.h>. */
* <sofia-sip/nta.h>. */
#define NTA_OUTGOING_MAGIC_T struct nta_outgoing_magic_s
#endif
#ifndef NTA_INCOMING_MAGIC_T
/** Default type of application context for incoming NTA requests.
* Application may define this to appropriate type before including
* <nta.h>. */
* <sofia-sip/nta.h>. */
#define NTA_INCOMING_MAGIC_T struct nta_incoming_magic_s
#endif
@@ -439,13 +439,13 @@ SOFIAPUBFUN int nta_outgoing_setrseq(nta_outgoing_t *orq, uint32_t rseq);
typedef struct nta_reliable_s nta_reliable_t;
#ifndef NTA_RELIABLE_MAGIC_T
/** Default type of application context for reliable NTA responses.
/** Default type of application context for reliable preliminary responses.
* Application may define this to appropriate type before including
* <nta.h>. */
* <sofia-sip/nta.h>. */
#define NTA_RELIABLE_MAGIC_T struct nta_reliable_magic_s
#endif
/** Application context for reliable NTA requests */
/** Application context for reliable preliminary responses. */
typedef NTA_RELIABLE_MAGIC_T nta_reliable_magic_t;
typedef int nta_prack_f(nta_reliable_magic_t *rmagic,
File diff suppressed because it is too large. Load diff
@@ -534,11 +534,11 @@ int api_test_params(agent_t *ag)
TEST_1(default_proxy == NULL);
TEST_1(smime == NULL);
TEST_1(blacklist != -1);
TEST_1(blacklist != (unsigned)-1);
TEST(debug_drop_prob, 0);
TEST_1(max_forwards >= 20);
TEST_1(maxsize >= 65536);
TEST_1(preload != -1);
TEST_1(preload != (unsigned)-1);
TEST_1(progress <= 60 * 1000);
TEST(sip_t1, NTA_SIP_T1);
TEST(sip_t2, NTA_SIP_T2);
@@ -22,7 +22,7 @@
*
*/
/**@file nth_server.c
/**@internal @file nth_server.c
* @brief HTTP server.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
@@ -50,7 +50,7 @@ typedef struct nth_request_s nth_request_t;
#ifndef NTH_CLIENT_MAGIC_T
/** Default type of application context for client NTH requests.
* Application may define this to appropriate type before including
* <nth.h>. */
* <sofia-sip/nth.h>. */
#define NTH_CLIENT_MAGIC_T struct nth_client_magic_s
#endif
@@ -60,7 +60,7 @@ typedef NTH_CLIENT_MAGIC_T nth_client_magic_t;
#ifndef NTH_SITE_MAGIC_T
/** Default type of application context for NTH servers.
* Application may define this to appropriate type before including
* <nth.h>. */
* <sofia-sip/nth.h>. */
#define NTH_SITE_MAGIC_T struct nth_site_magic_s
#endif
@@ -32,7 +32,7 @@ ALIASES += NUA_EVENT="@var nua_event_e::"
ALIASES += END_NUA_EVENT="@par &nbsp;"
ALIASES += \
NUA_HPARAM_CALLS="nua_invite(), nua_respond(), nua_ack(), nua_prack(), nua_update(), nua_info(), nua_bye(), nua_options(), nua_message(), nua_register(), nua_publish(), nua_refer(),nua_subscribe(), nua_notify(), nua_refer(), nua_notifier()"
NUA_HPARAM_CALLS="nua_method(), nua_respond(), nua_invite(), nua_ack(), nua_cancel(), nua_prack(), nua_update(), nua_info(), nua_bye(), nua_options(), nua_message(), nua_register(), nua_unregister(), nua_publish(), nua_refer(), nua_subscribe(), nua_unsubscribe(), nua_notify(), nua_notifier()"
VERBATIM_HEADERS = NO
+70 -41
View File
@@ -22,7 +22,7 @@
*
*/
/**@file nua.c High-Level User Agent Library - "nua" Implementation.
/**@internal @file nua.c High-Level User Agent Library - "nua" Implementation.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
* @author Kai Vehmanen <Kai.Vehmanen@nokia.com>
@@ -93,19 +93,28 @@ su_log_t nua_log[] = { SU_LOG_INIT("nua", "NUA_DEBUG", SU_DEBUG) };
* @param magic Pointer to callback context
* @param tag, value, ... List of tagged parameters
*
* @retval !=NULL a pointer to a @nua stack object \n
* @retval !=NULL a pointer to a @nua stack object
* @retval NULL upon an error
*
* @par Related tags:
* NUTAG_PROXY() \n
* NUTAG_URL() \n
* NUTAG_SIPS_URL() \n
* NUTAG_SIP_PARSER() \n
* NUTAG_CERTIFICATE_DIR() \n
* all tags listed in nua_set_params(), \n
* all NTATAG_* are passed to NTA listed in <sofia-sip/nta_tag.h> \n
* all tport tags listed in <sofia-sip/tport_tag.h> \n
* STUNTAG_DOMAIN(), STUNTAG_SERVER() \n
* - NUTAG_PROXY(), giving the URI of the outbound proxy
* (but see also NUTAG_INITIAL_ROUTE()).
* - NUTAG_URL() (and NUTAG_SIPS_URL(), listing URIs describing
* transports)
* - NUTAG_CERTIFICATE_DIR(), specifying the location of the
* root and client/server certificate files
* - NUTAG_SIP_PARSER(), providing customized parser used to
* parse received SIP messages
* - All parameter tags, listed with nua_set_params()
* - All NTATAG_* are passed to NTA documented in <sofia-sip/nta_tag.h>:
* see NTATAG_EXTRA_100(),
* - All tport tags are passed to tport.
* They are documented in <sofia-sip/tport_tag.h>
* - All SOATAG_* are passed to the default SOA (media session) object which
* is created by nua_create() unless NUTAG_MEDIA_ENABLE(0) is included in
* the tag list
* - STUN tags STUNTAG_DOMAIN(), STUNTAG_SERVER().
* STUN is deprecated, however.
*
* @note
* From the @VERSION_1_12_2 all the nua_set_params() tags are processed.
@@ -186,6 +195,13 @@ void nua_shutdown(nua_t *nua)
nua_signal(nua, NULL, NULL, 1, nua_r_shutdown, 0, NULL, TAG_END());
}
/** @internal Linked stack frames from nua event callback */
struct nua_event_frame_s {
nua_event_frame_t *nf_next;
nua_t *nf_nua;
nua_saved_event_t nf_saved[1];
};
/** Destroy the @nua stack.
*
* Before calling nua_destroy() the application
@@ -211,6 +227,8 @@ void nua_destroy(nua_t *nua)
enter;
if (nua) {
nua_event_frame_t *nf;
if (!nua->nua_shutdown_final) {
SU_DEBUG_0(("nua_destroy(%p): FATAL: nua_shutdown not completed\n",
(void *)nua));
@@ -218,6 +236,13 @@ void nua_destroy(nua_t *nua)
return;
}
nua->nua_callback = NULL;
for (nf = nua->nua_current; nf; nf = nf->nf_next) {
nf->nf_nua = NULL;
}
nua->nua_current = NULL;
su_task_deinit(nua->nua_server);
su_task_deinit(nua->nua_client);
@@ -975,9 +1000,10 @@ void nua_event(nua_t *root_magic, su_msg_r sumsg, event_t *e)
{
nua_t *nua;
nua_handle_t *nh = e->e_nh;
enter;
e->e_nh = NULL;
if (nh) {
if (!nh->nh_ref_by_user && nh->nh_valid) {
nh->nh_ref_by_user = 1;
@@ -1004,40 +1030,40 @@ void nua_event(nua_t *root_magic, su_msg_r sumsg, event_t *e)
nua = nh->nh_nua; assert(nua);
if (e->e_event == nua_r_shutdown && e->e_status >= 200)
nua->nua_shutdown_final = 1;
if (!nua->nua_callback)
return;
if (NH_IS_DEFAULT(nh))
nh = NULL;
su_msg_save(nua->nua_current, sumsg);
if (e->e_event == nua_r_shutdown && e->e_status >= 200)
nua->nua_shutdown_final = 1;
e->e_nh = NULL;
if (nua->nua_callback) {
nua_event_frame_t frame[1];
su_msg_remove_refs(sumsg); /* Remove references to tasks */
su_msg_save(frame->nf_saved, sumsg);
frame->nf_nua = nua;
frame->nf_next = nua->nua_current, nua->nua_current = frame;
nua->nua_callback(e->e_event, e->e_status, e->e_phrase,
nua, nua->nua_magic,
nh, nh ? nh->nh_magic : NULL,
e->e_msg ? sip_object(e->e_msg) : NULL,
e->e_tags);
nua->nua_callback(e->e_event, e->e_status, e->e_phrase,
nua, nua->nua_magic,
nh, nh ? nh->nh_magic : NULL,
e->e_msg ? sip_object(e->e_msg) : NULL,
e->e_tags);
if (nh && !NH_IS_DEFAULT(nh) && nua_handle_unref(nh)) {
su_msg_destroy(frame->nf_saved);
if (frame->nf_nua == NULL)
return;
nua->nua_current = frame->nf_next;
}
if (nh && nua_handle_unref(nh)) {
#if HAVE_NUA_HANDLE_DEBUG
SU_DEBUG_0(("nua(%p): freed by application\n", (void *)nh));
#else
SU_DEBUG_9(("nua(%p): freed by application\n", (void *)nh));
#endif
}
if (!su_msg_is_non_null(nua->nua_current))
return;
if (e->e_msg)
msg_destroy(e->e_msg), e->e_msg = NULL;
su_msg_destroy(nua->nua_current);
}
/** Get current request message. @NEW_1_12_4.
@@ -1048,7 +1074,9 @@ void nua_event(nua_t *root_magic, su_msg_r sumsg, event_t *e)
*/
msg_t *nua_current_request(nua_t const *nua)
{
return nua && nua->nua_current ? su_msg_data(nua->nua_current)->e_msg : NULL;
if (nua && nua->nua_current && su_msg_is_non_null(nua->nua_current->nf_saved))
return su_msg_data(nua->nua_current->nf_saved)->e_msg;
return NULL;
}
/** Get request message from saved nua event. @NEW_1_12_4.
@@ -1066,14 +1094,15 @@ msg_t *nua_saved_event_request(nua_saved_event_t const *saved)
*/
int nua_save_event(nua_t *nua, nua_saved_event_t return_saved[1])
{
if (nua && return_saved) {
su_msg_save(return_saved, nua->nua_current);
if (su_msg_is_non_null(return_saved)) {
/* Remove references to tasks */
su_msg_remove_refs(return_saved);
return 1;
if (return_saved) {
if (nua && nua->nua_current) {
su_msg_save(return_saved, nua->nua_current->nf_saved);
return su_msg_is_non_null(return_saved);
}
else
*return_saved = NULL;
}
return 0;
}
@@ -238,7 +238,7 @@ char const *nua_generate_instance_identifier(su_home_t *home)
*
* @sa nua_respond(), #nua_event_e, #nua_event_t, nua_event_name()
*
* @NEW_1_12_6
* @NEW_1_12_6.
*/
int nua_event_is_incoming_request(nua_event_t event)
{
@@ -80,7 +80,7 @@ typedef struct {
} nua_server_methods_t;
/** Server side transaction */
/* Server side transaction */
struct nua_server_request {
struct nua_server_request *sr_next, **sr_prev;
@@ -147,7 +147,7 @@ int sr_status(nua_server_request_t *sr, int status, char const *phrase)
return (void)(sr->sr_phrase = phrase), (sr->sr_status = status);
}
/** Methods for client request */
/* Methods for client request. @internal */
typedef struct {
sip_method_t crm_method;
char const *crm_method_name;
@@ -367,7 +367,7 @@ struct nua_dialog_state
} ds_remote_ua[1];
};
/** Virtual function pointer table for dialog usage. */
/* Virtual function pointer table for dialog usage. */
typedef struct {
unsigned usage_size, usage_class_size;
int (*usage_add)(nua_owner_t *,
@@ -387,7 +387,7 @@ typedef struct {
} nua_usage_class;
/** Base structure for dialog usage. */
/* Base structure for dialog usage. */
struct nua_dialog_usage {
nua_dialog_usage_t *du_next;
nua_usage_class const *du_class;
@@ -79,7 +79,7 @@ nua_stack_notifier(nua_t *nua, nua_handle_t *nh, nua_event_t e, tagi_t const *ta
int status = 900;
char const *phrase = nua_internal_error;
nua_stack_init_handle(nua, nh, TAG_NEXT(tags));
nua_stack_init_handle(nua, nh, tags);
tl_gets(tags,
NUTAG_URL_REF(url),
@@ -35,7 +35,7 @@
* @date Created: Wed Mar 8 11:38:18 EET 2006 ppessi
*/
/** NUA preferences.
/**@internal @brief NUA preferences.
*
* This structure contains values for various preferences and a separate
* bitmap (nhp_set) for each preference. Preferences are set using
@@ -116,7 +116,7 @@ static int nua_register_usage_shutdown(nua_handle_t *,
nua_dialog_state_t *,
nua_dialog_usage_t *);
/** REGISTER usage, aka nua_registration_t */
/** @internal @brief REGISTER usage, aka nua_registration_t. */
struct register_usage {
nua_registration_t *nr_next, **nr_prev, **nr_list; /* Doubly linked list and its head */
sip_from_t *nr_aor; /**< AoR for this registration, NULL if none */
@@ -293,7 +293,7 @@ outbound_owner_vtable nua_stack_outbound_callbacks = {
* @par Related tags:
* NUTAG_REGISTRAR(), NUTAG_INSTANCE(), NUTAG_OUTBOUND(),
* NUTAG_KEEPALIVE(), NUTAG_KEEPALIVE_STREAM(), NUTAG_M_USERNAME(),
* NUTAG_M_DISPLAY(), NUTAG_M_PARAMS(), NUTAG_M_FEATURES(),
* NUTAG_M_DISPLAY(), NUTAG_M_PARAMS(), NUTAG_M_FEATURES()
*
* @par Events:
* #nua_r_register, #nua_i_outbound
@@ -57,9 +57,15 @@
* Incoming REGISTER request.
*
* In order to receive #nua_i_register events, the application must enable
* the REGISTER method with NUTAG_ALLOW() tag.
* the REGISTER method with NUTAG_ALLOW() tag, e.g.,
* @verbatim
* nua_set_params(nua;
* NUTAG_APPL_METHOD("REGISTER"),
* NUTAG_ALLOW("REGISTER"),
* TAG_END());
* @endverbatim
*
* The nua_response() call responding to a REGISTER request must have
* The nua_response() call responding to a REGISTER request must include
* NUTAG_WITH() (or NUTAG_WITH_THIS()/NUTAG_WITH_SAVED()) tag. Note that
* a successful response to REGISTER @b MUST include the @Contact header
* bound to the the AoR URI (in @To header).
@@ -137,7 +137,7 @@ sip_response_terminates_dialog().
/* ---------------------------------------------------------------------- */
/* Session event usage */
/** Session-related state */
/** @internal @brief Session-related state. */
typedef struct nua_session_usage
{
enum nua_callstate ss_state; /**< Session status (enum nua_callstate) */
@@ -1591,7 +1591,11 @@ static int nua_prack_client_request(nua_client_request_t *cr,
else if (answer_sent)
ss->ss_oa_sent = Answer;
if (!cr->cr_restarting) /* Restart logic calls nua_prack_client_report */
if (cr->cr_restarting)
/* Restart logic calls nua_prack_client_report */;
else if (!cr->cr_auto && (!offer_sent || !answer_sent))
/* Suppose application know it called nua_prack() */;
else
signal_call_state_change(nh, ss, status, phrase, ss->ss_state);
}
+10 -11
View File
@@ -414,6 +414,9 @@ void nua_stack_signal(nua_t *nua, su_msg_r msg, nua_event_data_t *e)
case nua_r_info:
error = nua_stack_info(nua, nh, event, tags);
break;
case nua_r_prack:
error = nua_stack_prack(nua, nh, event, tags);
break;
case nua_r_update:
error = nua_stack_update(nua, nh, event, tags);
break;
@@ -754,10 +757,8 @@ void nh_destroy(nua_t *nua, nua_handle_t *nh)
* @retval -1 upon an error
* @retval 0 when successful
*/
int nua_stack_init_handle(nua_t *nua, nua_handle_t *nh,
tag_type_t tag, tag_value_t value, ...)
int nua_stack_init_handle(nua_t *nua, nua_handle_t *nh, tagi_t const *tags)
{
ta_list ta;
int retval = 0;
if (nh == NULL)
@@ -765,13 +766,9 @@ int nua_stack_init_handle(nua_t *nua, nua_handle_t *nh,
assert(nh != nua->nua_dhandle);
ta_start(ta, tag, value);
if (nua_stack_set_params(nua, nh, nua_i_error, ta_args(ta)) < 0)
if (nua_stack_set_params(nua, nh, nua_i_error, tags) < 0)
retval = -1;
ta_end(ta);
if (retval || nh->nh_init) /* Already initialized? */
return retval;
@@ -814,7 +811,7 @@ nua_handle_t *nua_stack_incoming_handle(nua_t *nua,
SIPTAG_FROM(from), /* Remote AoR */
TAG_END());
if (nua_stack_init_handle(nh->nh_nua, nh, TAG_END()) < 0)
if (nua_stack_init_handle(nh->nh_nua, nh, NULL) < 0)
nh_destroy(nua, nh), nh = NULL;
if (nh && create_dialog) {
@@ -1672,7 +1669,9 @@ int nua_base_server_report(nua_server_request_t *sr, tagi_t const *tags)
/* ---------------------------------------------------------------------- */
/** @class nua_client_request
/**@internal
*
* @class nua_client_request
*
* Each handle has a queue of client-side requests; if a request is pending,
* a new request from API is added to the queue. After the request is
@@ -1944,7 +1943,7 @@ int nua_client_init_request(nua_client_request_t *cr)
cr->cr_offer_recv = 0, cr->cr_answer_sent = 0;
cr->cr_terminated = 0, cr->cr_graceful = 0;
nua_stack_init_handle(nua, nh, TAG_NEXT(cr->cr_tags));
nua_stack_init_handle(nua, nh, cr->cr_tags);
if (cr->cr_method == sip_method_cancel) {
if (cr->cr_methods->crm_init) {
@@ -129,7 +129,7 @@ su_inline int nua_handle_unref_by(nua_handle_t *nh, char const *by)
#endif
/** NUA handle.
/** @internal @brief NUA handle.
*
*/
struct nua_handle_s
@@ -197,6 +197,8 @@ int nh_is_special(nua_handle_t *nh)
return nh == NULL || nh->nh_special;
}
typedef struct nua_event_frame_s nua_event_frame_t;
extern char const nua_internal_error[];
#define NUA_INTERNAL_ERROR 900, nua_internal_error
@@ -214,7 +216,7 @@ struct nua_s {
nua_callback_f nua_callback;
nua_magic_t *nua_magic;
nua_saved_event_t nua_current[1];
nua_event_frame_t *nua_current;
nua_saved_event_t nua_signal[1];
/* Engine state flags */
@@ -307,7 +309,8 @@ nua_stack_signal_handler
nua_stack_set_params, nua_stack_get_params,
nua_stack_register,
nua_stack_invite, nua_stack_ack, nua_stack_cancel,
nua_stack_bye, nua_stack_info, nua_stack_update,
nua_stack_bye, nua_stack_info, nua_stack_update,
nua_stack_prack,
nua_stack_options, nua_stack_publish, nua_stack_message,
nua_stack_subscribe, nua_stack_notify, nua_stack_refer,
nua_stack_method;
@@ -336,8 +339,7 @@ nua_handle_t *nua_stack_incoming_handle(nua_t *nua,
sip_t const *sip,
int create_dialog);
int nua_stack_init_handle(nua_t *nua, nua_handle_t *nh,
tag_type_t tag, tag_value_t value, ...);
int nua_stack_init_handle(nua_t *nua, nua_handle_t *nh, tagi_t const *tags);
enum nh_kind {
nh_has_nothing,
@@ -737,7 +737,10 @@ int nua_notify_server_report(nua_server_request_t *sr, tagi_t const *tags)
* #nua_i_notify
*
* @sa #nua_r_refer, NUTAG_SUBSTATE(), NUTAG_REFER_EVENT(),#nua_i_refer,
* @RFC3515, @ReferTo, @RFC3892, @ReferredBy
* @RFC3515, @ReferTo, SIPTAG_REFER_TO(), SIPTAG_REFER_TO_STR(),
* @RFC3892, @ReferredBy, SIPTAG_REFERRED_BY(), SIPTAG_REFERRED_BY_STR(),
* @RFC3891, @Replaces, SIPTAG_REPLACES(), SIPTAG_REPLACES_STR(),
* @RFC4488, @ReferSub, SIPTAG_REFER_SUB(), SIPTAG_REFER_SUB_STR()
*/
/**@NUA_EVENT nua_r_refer
@@ -758,7 +761,7 @@ int nua_notify_server_report(nua_server_request_t *sr, tagi_t const *tags)
* NUTAG_SUBSTATE()
*
* @sa nua_refer(), NUTAG_SUBSTATE(), #nua_i_refer,
* @RFC3515, @ReferTo, @RFC3892, @ReferredBy
* @RFC3515, @RFC4488, @ReferSub
*
* @END_NUA_EVENT
*/
File diff suppressed because it is too large. Load diff
+16 -5
View File
@@ -863,11 +863,20 @@ static int response_to_keepalive_options(outbound_t *ob,
loglevel = 1; /* XXX ... for now */
if (loglevel >= SU_LOG->log_level) {
su_llog(SU_LOG, loglevel,
"outbound(%p): %s <" URL_PRINT_FORMAT ">\n",
(void *)ob->ob_owner,
failed ? "FAILED to validate" : "validated",
URL_PRINT_ARGS(ob->ob_rcontact->m_url));
sip_contact_t const *m = ob->ob_rcontact;
if (m)
su_llog(SU_LOG, loglevel,
"outbound(%p): %s <" URL_PRINT_FORMAT ">\n",
(void *)ob->ob_owner,
failed ? "FAILED to validate" : "validated",
URL_PRINT_ARGS(m->m_url));
else
su_llog(SU_LOG, loglevel,
"outbound(%p): %s registration\n",
(void *)ob->ob_owner,
failed ? "FAILED to validate" : "validated");
if (failed)
su_llog(SU_LOG, loglevel, "outbound(%p): FAILED with %u %s\n",
(void *)ob->ob_owner, status, phrase);
@@ -1101,6 +1110,8 @@ int outbound_set_contact(outbound_t *ob,
previous = ob->ob_rcontact;
}
else if (application_contact) {
rcontact = sip_contact_dup(home, application_contact);
if (!ob->ob_rcontact ||
url_cmp_all(ob->ob_rcontact->m_url, application_contact->m_url)) {
contact_uri_changed = 1;
File diff suppressed because it is too large. Load diff
@@ -550,6 +550,7 @@ int ringing_pracked(CONDITION_PARAMS)
}
int respond_483_to_prack(CONDITION_PARAMS);
static int prack_100rel(CONDITION_PARAMS);
int test_183rel(struct context *ctx)
{
@@ -681,13 +682,14 @@ int test_183rel(struct context *ctx)
if (print_headings)
printf("TEST NUA-10.2.2: graceful termination because PRACK fails\n");
nua_set_hparams(a_call->nh, NUTAG_APPL_METHOD("PRACK"), TAG_END());
nua_set_hparams(b_call->nh, NUTAG_APPL_METHOD("PRACK"),
NUTAG_AUTOANSWER(0), TAG_END());
run_b_until(ctx, nua_r_set_params, NULL);
run_ab_until(ctx, nua_r_set_params, NULL, nua_r_set_params, NULL);
INVITE(a, a_call, a_call->nh, TAG_END());
run_ab_until(ctx, -1, until_terminated, -1, respond_483_to_prack);
run_ab_until(ctx, -1, prack_100rel, -1, respond_483_to_prack);
/* Client transitions:
INIT -(C1)-> CALLING: nua_invite(), nua_i_state
@@ -790,6 +792,29 @@ int test_183rel(struct context *ctx)
END();
}
static int prack_100rel(CONDITION_PARAMS)
{
if (!check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR))
return 0;
save_event_in_list(ctx, event, ep, call);
if (event == nua_r_invite && 100 < status && status < 200 &&
sip_has_feature(sip->sip_require, "100rel")) {
sip_rack_t rack[1];
sip_rack_init(rack);
rack->ra_response = sip->sip_rseq->rs_response;
rack->ra_cseq = sip->sip_cseq->cs_seq;
rack->ra_method = sip->sip_cseq->cs_method;
rack->ra_method_name = sip->sip_cseq->cs_method_name;
nua_prack(nh, SIPTAG_RACK(rack), TAG_END());
}
return event == nua_i_state && callstate(tags) == nua_callstate_terminated;
}
int respond_483_to_prack(CONDITION_PARAMS)
{
if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
@@ -338,6 +338,8 @@ int main(int argc, char *argv[])
retval |= test_nua_params(ctx); SINGLE_FAILURE_CHECK();
retval |= test_nua_destroy(ctx); SINGLE_FAILURE_CHECK();
retval |= test_nua_init(ctx, o_iproxy, o_proxy, o_inat,
TESTNATTAG_SYMMETRIC(o_inat_symmetric),
TESTNATTAG_LOGGING(o_inat_logging),
@@ -327,6 +327,7 @@ int test_nua_init(struct context *ctx,
int test_deinit(struct context *ctx);
int test_nua_api_errors(struct context *ctx);
int test_nua_destroy(struct context *ctx);
int test_stack_errors(struct context *ctx);
int test_tag_filter(void);
int test_nua_params(struct context *ctx);
@@ -34,6 +34,7 @@
#include "config.h"
#include "test_nua.h"
#include "sofia-sip/tport_tag.h"
#if HAVE_FUNC
#elif HAVE_FUNCTION
@@ -71,9 +72,9 @@ int test_nua_api_errors(struct context *ctx)
TEST(status, 200); TEST_S(phrase, sip_200_OK);
su_log_init(nua_log);
level = nua_log->log_level;
if (!(tstflags & tst_verbatim))
su_log_set_level(nua_log, 0); /* Log at level 0 by default */
level = nua_log->log_level;
TEST_1(!nua_create(NULL, NULL, NULL, TAG_END()));
TEST_VOID(nua_shutdown(NULL));
@@ -142,6 +143,61 @@ int test_nua_api_errors(struct context *ctx)
/* ======================================================================== */
void destroy_callback(nua_event_t event,
int status, char const *phrase,
nua_t *nua, struct context *ctx,
nua_handle_t *nh, struct call *call,
sip_t const *sip,
tagi_t tags[])
{
if (status >= 200) {
nua_destroy(ctx->a.nua), ctx->a.nua = NULL;
su_root_break(ctx->root);
}
}
/* Test different nua_destroy() corner cases */
int test_nua_destroy(struct context *ctx)
{
BEGIN();
struct endpoint *a = &ctx->a;
TEST_1(ctx->root = su_root_create(NULL));
#if 0
a->nua = nua_create(ctx->root, destroy_callback, ctx,
NUTAG_URL("sip:0.0.0.0:*"),
TAG_IF(ctx->a.logging, TPTAG_LOG(1)),
TAG_END());
TEST_1(a->nua);
nua_get_params(a->nua, TAG_ANY(), TAG_END());
su_root_run(ctx->root);
TEST_1(a->nua == NULL);
#endif
a->nua = nua_create(ctx->root, destroy_callback, ctx,
NUTAG_URL("sip:0.0.0.0:*"),
TAG_IF(ctx->a.logging, TPTAG_LOG(1)),
TAG_END());
TEST_1(a->nua);
nua_shutdown(a->nua);
su_root_run(ctx->root);
TEST_1(a->nua == NULL);
su_root_destroy(ctx->root), ctx->root = NULL;
END();
}
/* ======================================================================== */
int test_stack_errors(struct context *ctx)
{
BEGIN();
@@ -299,7 +299,7 @@ int test_nua_params(struct context *ctx)
sip_organization_t const *organization = NONE;
char const *organization_str = "NONE";
sip_route_t *initial_route = NONE;
sip_route_t const *initial_route = NONE;
char const *initial_route_str = NONE;
char const *outbound = "NONE";
+1 -1
View File
@@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file sdp_tag.c
* @brief SDP Tags
*
@@ -230,7 +230,7 @@ typedef enum
sdp_media_control, /**< Additional conference control */
sdp_media_message, /**< Messaging sessions*/
sdp_media_image, /**< Image browsing sessions for JPIP, and T.38 */
sdp_media_red /**< Redundancy. @NEW_1_12_4 */
sdp_media_red /**< Redundancy. @NEW_1_12_4. */
} sdp_media_e;
/** Media transport protocol. */
@@ -241,7 +241,7 @@ typedef enum
sdp_proto_udp = 17, /**< Plain UDP */
sdp_proto_rtp = 256, /**< RTP/AVP */
sdp_proto_srtp = 257, /**< RTP/SAVP */
sdp_proto_udptl = 258, /**< UDPTL. @NEW_1_12_4 */
sdp_proto_udptl = 258, /**< UDPTL. @NEW_1_12_4. */
sdp_proto_tls = 511, /**< TLS over TCP */
sdp_proto_any = 512 /**< * wildcard */
} sdp_proto_e;
+28 -28
View File
@@ -1,13 +1,11 @@
Description of Adding a SIP Header to Sofia SIP
===============================================
Adding a SIP Header to Sofia SIP
================================
by Pekka Pessi (2002-08-16, updated 2006-10-03)
by Pekka Pessi (2002-08-16, last updated 2007-09-19)
There are three ways to extend the Sofia SIP parser, including a standard
header in sip_t structure, including a standard header in extra headers or
putting the extension headers into a separate library.
Probalem with extending #sip_t is that it breaks binary compatibility.
There are two recommended ways to extend the Sofia SIP parser, including a
standard header in extra headers or putting the extension headers into a
separate library.
In the text below, we use "Example" header as our example with following
ABNF:
@@ -18,30 +16,18 @@ ABNF:
IF YOUR HEADER IS A STANDARD ONE
--------------------------------
* In <sip.h>, add:
* In <sofia-sip/sip_extra.h>, add:
- Add typedef to the header structure.
The typedefs to ordinary headers are in more or less alphabetic
order after typedef of sip_unknown_t. You should add a typedef line
like this:
You should add a typedef line like this:
typedef struct sip_example_s sip_example_t;
Note that the typedefs are documented together with the
implementation in the .c file.
- Add field to the sip_t structure (struct sip_s)
- Remember to add a comment containing the header name
after field for benefit of the AWK script autmatically generating
boilerplate functions and macros:
sip_example_t *sip_example; /**< Example */
- The AWK script msg_parser.awk automatically creates the default
prototypes and tags for the newly created header when the entry in
sip_t structure is formatted like to the example above.
It will complain about mismatches between header name and field name.
* Add the actual header structure:
- Add the actual header structure:
The header structure would look like below. The first field MUST be a
sip_common_t structure, second field MUST be a pointer to next header
@@ -61,6 +47,21 @@ IF YOUR HEADER IS A STANDARD ONE
unsigned long ex_value; /**< Value of example. */
};
* Add entry to sip_extra_headers.txt:
- In this case:
example @NEW_2_0 /* Example header */
- The first is the base C name used for functions and types related to
the type. The AWK script msg_parser.awk automatically creates the
default prototypes and tags for the newly created header. It will
complain about mismatches between header name and the base name.
- If the entry is before #### DEFAULT HEADER LIST ENDS HERE ####
the new header is added to the default parser
- If after, the new header is added only to the extended parser.
- The extended parser will be used after call to
sip_update_default_mclass(NULL)
* Write parsing tests for your new headers in torture_sip.c:
Add all relevant parsing/processing cases you can think of
@@ -86,8 +87,10 @@ IF YOUR HEADER IS A STANDARD ONE
* Run "make check" after you are ready. Really.
IF YOUR HEADERS ARE NON-STANDARD
--------------------------------
IF YOUR HEADERS ARE COMPLETELY NON-STANDARD
-------------------------------------------
* Add a separate library package for them
- There is an example package sofia-sip-2543.tar.gz, available from
sofia-sip.sourceforge.net
@@ -147,6 +150,3 @@ struct sip_example_dummy_structure {
#endif /** !defined(SIP_EXAMPLE_H) */
--->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---
@@ -148,4 +148,5 @@ sofia-sip/sip_extra.h: ${srcdir}/sofia-sip/sip_extra.h.in ${EXTRA}
PACKAGE_VERSION="${PACKAGE_VERSION}" \
TEMPLATE1=${srcdir}/sofia-sip/sip_hclasses.h.in \
TEMPLATE2=${srcdir}/sofia-sip/sip_protos.h.in \
TEMPLATE3=${srcdir}/sofia-sip/sip_tag.h.in \
TEMPLATE=${srcdir}/sofia-sip/sip_extra.h.in ${EXTRA}
@@ -69,4 +69,6 @@ ALIASES += \
"ReplyTo=@ref sip_reply_to \"Reply-To\"" \
"SuppressBodyIfMatch=@ref sip_suppress_body_if_match \"Suppress-Body-If-Match\"" \
"SuppressNotifyIfMatch=@ref sip_suppress_notify_if_match \"Suppress-Notify-If-Match\"" \
"RemotePartyID=@ref sip_remote_party_id \"Remote-Party-ID\"" \
"PAssertedIdentity=@ref sip_p_asserted_identity \"P-Asserted-Identity\"" \
"PPreferredIdentity=@ref sip_p_preferred_identity \"P-Preferred-Identity\"" \
+153 -108
View File
@@ -123,7 +123,7 @@ SIP_HEADER_CLASS(request, NULL, "", rq_common, single_critical, request);
/**Parse @ref sip_request "request line" from a a SIP message. */
issize_t sip_request_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
{
sip_request_t *rq = h->sh_request;
sip_request_t *rq = (sip_request_t *)h;
char *uri, *version;
if (msg_firstline_d(s, &uri, &version) < 0 || !uri || !version ||
@@ -138,7 +138,7 @@ issize_t sip_request_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
/**Encode @ref sip_request "request line" of a a SIP message. */
issize_t sip_request_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
{
sip_request_t const *rq = h->sh_request;
sip_request_t const *rq = (sip_request_t *)h;
return snprintf(b, bsiz, "%s " URL_FORMAT_STRING " %s" CRLF,
rq->rq_method_name,
@@ -148,7 +148,7 @@ issize_t sip_request_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
isize_t sip_request_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_request_t const *rq = h->sh_request;
sip_request_t const *rq = (sip_request_t *)h;
offset += url_xtra(rq->rq_url);
if (!rq->rq_method)
@@ -162,8 +162,8 @@ isize_t sip_request_dup_xtra(sip_header_t const *h, isize_t offset)
char *sip_request_dup_one(sip_header_t *dst, sip_header_t const *src,
char *b, isize_t xtra)
{
sip_request_t *rq = dst->sh_request;
sip_request_t const *o = src->sh_request;
sip_request_t *rq = (sip_request_t *)dst;
sip_request_t const *o = (sip_request_t *)src;
char *end = b + xtra;
URL_DUP(b, end, rq->rq_url, o->rq_url);
@@ -224,7 +224,7 @@ sip_request_t *sip_request_create(su_home_t *home,
xtra = url_xtra(uri->us_url) + (method ? 0 : strlen(name) + 1);
rq = sip_header_alloc(home, sip_request_class, xtra)->sh_request;
rq = (sip_request_t *)sip_header_alloc(home, sip_request_class, xtra);
if (rq) {
char *b = (char *)(rq + 1), *end = b + xtra;
@@ -298,7 +298,7 @@ SIP_HEADER_CLASS(status, NULL, "", st_common, single_critical, status);
/** Parse status line */
issize_t sip_status_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
{
sip_status_t *st = h->sh_status;
sip_status_t *st = (sip_status_t *)h;
char *status, *phrase;
unsigned long code;
@@ -315,25 +315,26 @@ issize_t sip_status_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
issize_t sip_status_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
{
sip_status_t const *st = (sip_status_t *)h;
int status;
assert(sip_is_status(h));
status = h->sh_status->st_status;
status = st->st_status;
if (status > 999 || status < 100)
status = 0;
return snprintf(b, bsiz, "%s %03u %s" CRLF,
h->sh_status->st_version,
st->st_version,
status,
h->sh_status->st_phrase);
st->st_phrase);
}
/** Extra size of a #sip_status_t object. */
isize_t sip_status_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_status_t const *st = h->sh_status;
sip_status_t const *st = (sip_status_t *)h;
offset += sip_version_xtra(st->st_version);
offset += MSG_STRING_SIZE(st->st_phrase);
return offset;
@@ -343,8 +344,8 @@ isize_t sip_status_dup_xtra(sip_header_t const *h, isize_t offset)
char *sip_status_dup_one(sip_header_t *dst, sip_header_t const *src,
char *b, isize_t xtra)
{
sip_status_t *st = dst->sh_status;
sip_status_t const *o = src->sh_status;
sip_status_t *st = (sip_status_t *)dst;
sip_status_t const *o = (sip_status_t *)src;
char *end = b + xtra;
sip_version_dup(&b, &st->st_version, o->st_version);
@@ -386,7 +387,7 @@ sip_status_t *sip_status_create(su_home_t *home,
if (phrase == NULL && (phrase = sip_status_phrase(status)) == NULL)
phrase = "";
if ((st = sip_header_alloc(home, sip_status_class, 0)->sh_status)) {
if ((st = (sip_status_t *)sip_header_alloc(home, sip_status_class, 0))) {
st->st_status = status;
st->st_phrase = phrase;
st->st_version = version ? version : SIP_VERSION_CURRENT;
@@ -452,7 +453,7 @@ sip_payload_t *sip_payload_create(su_home_t *home, void const *data, isize_t len
{
msg_hclass_t *hc = sip_payload_class;
sip_header_t *h = sip_header_alloc(home, hc, len + 1);
sip_payload_t *pl = h->sh_payload;
sip_payload_t *pl = (sip_payload_t *)h;
if (pl) {
char *b = sip_header_data(h);
@@ -512,8 +513,8 @@ SIP_HEADER_CLASS(separator, NULL, "", sep_common, single, any);
*/
sip_separator_t *sip_separator_create(su_home_t *home)
{
sip_separator_t *sep =
sip_header_alloc(home, sip_separator_class, 0)->sh_separator;
sip_separator_t *sep = (sip_separator_t *)
sip_header_alloc(home, sip_separator_class, 0);
if (sep)
strcpy(sep->sep_data, CRLF);
@@ -764,7 +765,7 @@ issize_t sip_name_addr_e(char b[], isize_t bsiz,
int flags,
char const *display,
int brackets, url_t const url[],
msg_param_t const params[],
msg_param_t const params[],
char const *comment)
{
int const compact = MSG_IS_COMPACT(flags);
@@ -801,6 +802,63 @@ issize_t sip_name_addr_e(char b[], isize_t bsiz,
return b - b0;
}
/** Calculate the extra size needed to duplicate a name-addr-params construct.
*
* @param display display name (may be NULL)
* @param addr pointer to URL structure
* @param params pointer to parameter list (may be NULL)
* @param offset base offset
*
* @retval Size of duplicated name-addr-params construct, including base offset.
*
* @NEW_1_12_7.
*/
isize_t sip_name_addr_xtra(char const *display, url_t const *addr,
msg_param_t const params[],
isize_t offset)
{
SIP_PARAMS_SIZE(offset, params);
offset += SIP_STRING_SIZE(display);
offset += url_xtra(addr);
return offset;
}
/**Duplicate a name-addr-params construct.
*
* @param d_display value-result parameter for copied @e name (may be NULL)
* @param display display name (may be NULL)
* @param d_addr value-result parameter for copied @e address
* @param addr pointer to URL address structure
* @param d_params value-result parameter for copied parameters (may be NULL)
* @param params pointer to parameter list (may be NULL)
* @param b pointer to memory pool
* @param xtra size of the memory pool
*
* @retval End of the memory area used.
*
* @NEW_1_12_7.
*/
char *sip_name_addr_dup(char const **d_display, char const *display,
url_t *d_addr, url_t const *addr,
msg_param_t const **d_params, msg_param_t const params[],
char *b, isize_t xtra)
{
char *end = b + xtra;
if (d_params)
b = msg_params_dup(d_params, params, b, xtra);
URL_DUP(b, end, d_addr, addr);
if (d_display)
MSG_STRING_DUP(b, *d_display, display);
assert(b <= end);
return b;
}
/** Parse @To or @From headers */
static issize_t sip_addr_d(su_home_t *home,
sip_header_t *h,
@@ -851,10 +909,11 @@ isize_t sip_addr_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_addr_t const *a = (sip_addr_t const *)h;
MSG_PARAMS_SIZE(offset, a->a_params);
offset += MSG_STRING_SIZE(a->a_display);
offset += url_xtra(a->a_url);
return sip_name_addr_xtra(a->a_display,
a->a_url,
a->a_params,
offset);
return offset;
}
@@ -866,15 +925,11 @@ static char *sip_addr_dup_one(sip_header_t *dst, sip_header_t const *src,
{
sip_addr_t *a = (sip_addr_t *)dst;
sip_addr_t const *o = (sip_addr_t *)src;
char *end = b + xtra;
b = msg_params_dup(&a->a_params, o->a_params, b, xtra);
MSG_STRING_DUP(b, a->a_display, o->a_display);
URL_DUP(b, end, a->a_url, o->a_url);
assert(b <= end);
return b;
return sip_name_addr_dup(&a->a_display, o->a_display,
a->a_url, o->a_url,
&a->a_params, o->a_params,
b, xtra);
}
/** Update parameters in sip_addr_t object */
@@ -905,7 +960,7 @@ sip_addr_make_url(su_home_t *home, msg_hclass_t *hc, url_string_t const *us)
h = sip_header_alloc(home, hc, n);
if (h) {
sip_addr_t *a = h->sh_to;
sip_addr_t *a = (sip_to_t *)h;
char *s2 = sip_header_data(h);
if ((size_t)url_dup(s2, n, a->a_url, us->us_url) == n)
@@ -997,7 +1052,7 @@ issize_t sip_call_id_d(su_home_t *home,
char *s,
isize_t slen)
{
sip_call_id_t *i = h->sh_call_id;
sip_call_id_t *i = (sip_call_id_t *)h;
i->i_id = s; /* XXX - why not sip_word_at_word_d(&s); */
i->i_hash = msg_hash_string(s);
@@ -1008,10 +1063,11 @@ issize_t sip_call_id_d(su_home_t *home,
issize_t sip_call_id_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
{
size_t n = strlen(h->sh_call_id->i_id);
sip_call_id_t const *i = (sip_call_id_t *)h;
size_t n = strlen(i->i_id);
if (bsiz > n)
strcpy(b, h->sh_call_id->i_id);
strcpy(b, i->i_id);
return (issize_t)n;
}
@@ -1019,7 +1075,7 @@ issize_t sip_call_id_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
/** Extra size of a #sip_call_id_t object. */
isize_t sip_call_id_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_call_id_t const *i = h->sh_call_id;
sip_call_id_t const *i = (sip_call_id_t *)h;
return offset + MSG_STRING_SIZE(i->i_id);
}
@@ -1038,8 +1094,8 @@ isize_t sip_call_id_dup_xtra(sip_header_t const *h, isize_t offset)
char *sip_call_id_dup_one(sip_header_t *dst, sip_header_t const *src,
char *b, isize_t xtra)
{
sip_call_id_t *i = dst->sh_call_id;
sip_call_id_t const *o = src->sh_call_id;
sip_call_id_t *i = (sip_call_id_t *)dst;
sip_call_id_t const *o = (sip_call_id_t *)src;
char *end = b + xtra;
MSG_STRING_DUP(b, i->i_id, o->i_id);
@@ -1072,7 +1128,7 @@ sip_call_id_t *sip_call_id_create(su_home_t *home, char const *domain)
sip_call_id_t *i;
size_t xtra = su_guid_strlen + 1 + (domain ? strlen(domain) + 1 : 0);
i = sip_header_alloc(home, sip_call_id_class, xtra)->sh_call_id;
i = (sip_call_id_t *)sip_header_alloc(home, sip_call_id_class, xtra);
if (i) {
char *b;
@@ -1149,7 +1205,7 @@ issize_t sip_cseq_d(su_home_t *home,
char *s,
isize_t slen)
{
sip_cseq_t *cs = h->sh_cseq;
sip_cseq_t *cs = (sip_cseq_t *)h;
if (msg_uint32_d(&s, &cs->cs_seq) < 0)
return -1;
@@ -1165,17 +1221,16 @@ issize_t sip_cseq_d(su_home_t *home,
issize_t sip_cseq_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
{
sip_cseq_t const *cs = (sip_cseq_t *)h;
assert(sip_is_cseq(h));
return snprintf(b, bsiz,
"%u %s",
h->sh_cseq->cs_seq,
h->sh_cseq->cs_method_name);
return snprintf(b, bsiz, "%u %s", cs->cs_seq, cs->cs_method_name);
}
isize_t sip_cseq_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_cseq_t const *cs = h->sh_cseq;
sip_cseq_t const *cs = (sip_cseq_t *)h;
if (!cs->cs_method)
return offset + MSG_STRING_SIZE(cs->cs_method_name);
else
@@ -1185,8 +1240,8 @@ isize_t sip_cseq_dup_xtra(sip_header_t const *h, isize_t offset)
char *sip_cseq_dup_one(sip_header_t *dst, sip_header_t const *src,
char *b, isize_t xtra)
{
sip_cseq_t *cs = dst->sh_cseq;
sip_cseq_t const *o = src->sh_cseq;
sip_cseq_t *cs = (sip_cseq_t *)dst;
sip_cseq_t const *o = (sip_cseq_t *)src;
char *end = b + xtra;
if (!(cs->cs_method = o->cs_method))
@@ -1241,7 +1296,7 @@ sip_cseq_t *sip_cseq_create(su_home_t *home,
xtra = (method ? 0 : (strlen(method_name) + 1));
cs = sip_header_alloc(home, sip_cseq_class, xtra)->sh_cseq;
cs = (sip_cseq_t *)sip_header_alloc(home, sip_cseq_class, xtra);
if (cs) {
cs->cs_seq = seq;
@@ -1355,7 +1410,7 @@ issize_t sip_contact_d(su_home_t *home,
issize_t sip_contact_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
{
sip_contact_t const *m = h->sh_contact;
sip_contact_t const *m = (sip_contact_t *)h;
int always_lt_gt = MSG_IS_CANONIC(flags) && m->m_url->url_type != url_any;
assert(sip_is_contact(h));
@@ -1369,30 +1424,26 @@ issize_t sip_contact_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
isize_t sip_contact_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_contact_t const *m = h->sh_contact;
sip_contact_t const *m = (sip_contact_t *)h;
MSG_PARAMS_SIZE(offset, m->m_params);
offset += MSG_STRING_SIZE(m->m_display);
offset += url_xtra(m->m_url);
offset += MSG_STRING_SIZE(m->m_comment);
return offset;
return sip_name_addr_xtra(m->m_display,
m->m_url,
m->m_params,
offset)
+ MSG_STRING_SIZE(m->m_comment);
}
char *sip_contact_dup_one(sip_header_t *dst, sip_header_t const *src,
char *b, isize_t xtra)
{
char *end = b + xtra;
sip_contact_t *m = dst->sh_contact;
sip_contact_t const *o = src->sh_contact;
sip_contact_t *m = (sip_contact_t *)dst;
sip_contact_t const *o = (sip_contact_t *)src;
b = msg_params_dup(&m->m_params, o->m_params, b, xtra);
MSG_STRING_DUP(b, m->m_display, o->m_display);
URL_DUP(b, end, m->m_url, o->m_url);
b = sip_name_addr_dup(&m->m_display, o->m_display,
m->m_url, o->m_url,
&m->m_params, o->m_params,
b, xtra);
MSG_STRING_DUP(b, m->m_comment, o->m_comment);
assert(b <= end);
return b;
}
@@ -1515,8 +1566,8 @@ issize_t sip_content_length_e(char b[], isize_t bsiz, sip_header_t const *h, int
*/
sip_content_length_t *sip_content_length_create(su_home_t *home, uint32_t n)
{
sip_content_length_t *l =
sip_header_alloc(home, sip_content_length_class, 0)->sh_content_length;
sip_content_length_t *l = (sip_content_length_t *)
sip_header_alloc(home, sip_content_length_class, 0);
if (l)
l->l_length = n;
@@ -1570,7 +1621,7 @@ SIP_HEADER_CLASS(date, "Date", "", d_common, single, any);
issize_t sip_date_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
{
sip_date_t *date = h->sh_date;
sip_date_t *date = (sip_date_t *)h;
if (msg_date_d((char const **)&s, &date->d_time) < 0 || *s)
return -1;
@@ -1580,7 +1631,7 @@ issize_t sip_date_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
issize_t sip_date_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
{
sip_date_t const *date = h->sh_date;
sip_date_t const *date = (sip_date_t *)h;
return msg_date_e(b, bsiz, date->d_time);
}
@@ -1601,15 +1652,15 @@ issize_t sip_date_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
*/
sip_date_t *sip_date_create(su_home_t *home, sip_time_t date)
{
sip_header_t *h = sip_header_alloc(home, sip_date_class, 0);
sip_date_t *d = (sip_date_t *)sip_header_alloc(home, sip_date_class, 0);
if (h) {
if (d) {
if (date == 0)
date = sip_now();
h->sh_date->d_time = date;
d->d_time = date;
}
return h->sh_date;
return d;
}
/* ====================================================================== */
@@ -1651,7 +1702,7 @@ SIP_HEADER_CLASS(expires, "Expires", "", ex_common, single, any);
issize_t sip_expires_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
{
sip_expires_t *expires = h->sh_expires;
sip_expires_t *expires = (sip_expires_t *)h;
if (msg_date_delta_d((char const **)&s,
&expires->ex_date,
@@ -1663,7 +1714,7 @@ issize_t sip_expires_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
issize_t sip_expires_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
{
sip_expires_t const *expires = h->sh_expires;
sip_expires_t const *expires = (sip_expires_t *)h;
if (expires->ex_date)
return msg_date_e(b, bsiz, expires->ex_date + expires->ex_delta);
@@ -1685,12 +1736,13 @@ issize_t sip_expires_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
*/
sip_expires_t *sip_expires_create(su_home_t *home, sip_time_t delta)
{
sip_header_t *h = sip_header_alloc(home, sip_expires_class, 0);
sip_expires_t *ex = (sip_expires_t *)
sip_header_alloc(home, sip_expires_class, 0);
if (h)
h->sh_expires->ex_delta = delta;
if (ex)
ex->ex_delta = delta;
return h->sh_expires;
return ex;
}
/* ====================================================================== */
@@ -1955,7 +2007,7 @@ SIP_HEADER_CLASS(retry_after, "Retry-After", "", af_params, single,
issize_t sip_retry_after_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
{
sip_retry_after_t *af = h->sh_retry_after;
sip_retry_after_t *af = (sip_retry_after_t *)h;
if ((msg_delta_d((char const **)&s, &af->af_delta) < 0) ||
(*s == '(' && msg_comment_d(&s, &af->af_comment) == -1) ||
@@ -1974,7 +2026,7 @@ issize_t sip_retry_after_d(su_home_t *home, sip_header_t *h, char *s, isize_t sl
issize_t sip_retry_after_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
{
sip_retry_after_t const *af = h->sh_retry_after;
sip_retry_after_t const *af = (sip_retry_after_t *)h;
int const compact = MSG_IS_COMPACT(f);
char *b0 = b, *end = b + bsiz;
@@ -2000,7 +2052,7 @@ issize_t sip_retry_after_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
isize_t sip_retry_after_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_retry_after_t const *af = h->sh_retry_after;
sip_retry_after_t const *af = (sip_retry_after_t *)h;
MSG_PARAMS_SIZE(offset, af->af_params);
offset += MSG_STRING_SIZE(af->af_comment);
@@ -2013,8 +2065,8 @@ char *sip_retry_after_dup_one(sip_header_t *dst,
char *b,
isize_t xtra)
{
sip_retry_after_t *af = dst->sh_retry_after;
sip_retry_after_t const *o = src->sh_retry_after;
sip_retry_after_t *af = (sip_retry_after_t *)dst;
sip_retry_after_t const *o = (sip_retry_after_t *)src;
char *end = b + xtra;
b = msg_params_dup(&af->af_params, o->af_params, b, xtra);
@@ -2072,7 +2124,7 @@ issize_t sip_any_route_d(su_home_t *home,
issize_t sip_any_route_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
{
sip_route_t const *r = h->sh_route;
sip_route_t const *r = (sip_route_t *)h;
return sip_name_addr_e(b, bsiz, flags,
r->r_display, 1, r->r_url, r->r_params, NULL);
@@ -2080,30 +2132,23 @@ issize_t sip_any_route_e(char b[], isize_t bsiz, sip_header_t const *h, int flag
isize_t sip_any_route_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_route_t const *r = h->sh_route;
MSG_PARAMS_SIZE(offset, r->r_params);
offset += MSG_STRING_SIZE(r->r_display);
offset += url_xtra(r->r_url);
return offset;
sip_route_t const *r = (sip_route_t *)h;
return sip_name_addr_xtra(r->r_display,
r->r_url,
r->r_params,
offset);
}
char *sip_any_route_dup_one(sip_header_t *dst, sip_header_t const *src,
char *b,
isize_t xtra)
{
sip_route_t *r = dst->sh_route;
sip_route_t const *o = src->sh_route;
char *end = b + xtra;
b = msg_params_dup(&r->r_params, o->r_params, b, xtra);
MSG_STRING_DUP(b, r->r_display, o->r_display);
URL_DUP(b, end, r->r_url, o->r_url);
assert(b <= end);
return b;
sip_route_t *r = (sip_route_t *)dst;
sip_route_t const *o = (sip_route_t *)src;
return sip_name_addr_dup(&r->r_display, o->r_display,
r->r_url, o->r_url,
&r->r_params, o->r_params,
b, xtra);
}
#define sip_any_route_update NULL
@@ -2149,7 +2194,7 @@ sip_route_t *sip_any_route_create(su_home_t *home,
xtra = n_url + n_params + n_addr + (n_params || n_addr);
h = sip_header_alloc(home, hc, xtra);
if ((rr = h->sh_record_route)) {
if ((rr = (sip_record_route_t *)h)) {
b = sip_header_data(h);
n = url_dup(b, n_url, rr->r_url, url);
assert(n == n_url);
@@ -2519,7 +2564,7 @@ issize_t sip_via_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
issize_t sip_via_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
{
char *b0 = b, *end = b + bsiz;
sip_via_t const *v = h->sh_via;
sip_via_t const *v = (sip_via_t *)h;
assert(sip_is_via(h));
@@ -2548,7 +2593,7 @@ issize_t sip_via_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
isize_t sip_via_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_via_t const *v = h->sh_via;
sip_via_t const *v = (sip_via_t *)h;
MSG_PARAMS_SIZE(offset, v->v_params);
offset += sip_transport_xtra(v->v_protocol);
@@ -2563,8 +2608,8 @@ isize_t sip_via_dup_xtra(sip_header_t const *h, isize_t offset)
char *sip_via_dup_one(sip_header_t *dst, sip_header_t const *src,
char *b, isize_t xtra)
{
sip_via_t *v = dst->sh_via;
sip_via_t const *o = src->sh_via;
sip_via_t *v = (sip_via_t *)dst;
sip_via_t const *o = (sip_via_t *)src;
char *end = b + xtra;
b = msg_params_dup(&v->v_params, o->v_params, b, xtra);
@@ -2679,7 +2724,7 @@ sip_via_t *sip_via_create(su_home_t *home,
via->v_host = host;
via->v_port = port;
v = msg_header_dup_as(home, sip_via_class, (sip_header_t *)via)->sh_via;
v = (sip_via_t *)msg_header_dup_as(home, sip_via_class, (sip_header_t *)via);
if (v) {
char const *param;
+342 -26
View File
@@ -219,7 +219,9 @@ issize_t sip_error_info_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
*
* The parsed Alert-Info header is stored in #sip_alert_info_t structure.
*
* @NEW_1_12_7
* @NEW_1_12_7. In order to use @b Alert-Info header,
* initialize the SIP parser with, e.g.,
* sip_update_default_mclass(sip_extend_mclass(NULL))
*/
/**@ingroup sip_alert_info
@@ -239,7 +241,7 @@ issize_t sip_error_info_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
* };
* @endcode
*
* @NEW_1_12_7
* @NEW_1_12_7.
*/
msg_hclass_t sip_alert_info_class[] =
@@ -276,6 +278,12 @@ issize_t sip_alert_info_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
* @endcode
*
* The parsed Reply-To header is stored in #sip_reply_to_t structure.
*
* @sa sip_update_default_mclass()
*
* @NEW_1_12_7. In order to use @b Reply-To header,
* initialize the SIP parser with, e.g.,
* sip_update_default_mclass(sip_extend_mclass(NULL)).
*/
/**@ingroup sip_reply_to
@@ -336,11 +344,10 @@ static isize_t sip_reply_to_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_reply_to_t const *rplyto = (sip_reply_to_t const *)h;
MSG_PARAMS_SIZE(offset, rplyto->rplyto_params);
offset += MSG_STRING_SIZE(rplyto->rplyto_display);
offset += url_xtra(rplyto->rplyto_url);
return offset;
return sip_name_addr_xtra(rplyto->rplyto_display,
rplyto->rplyto_url,
rplyto->rplyto_params,
offset);
}
/**@internal Duplicate one sip_reply_to_t object. */
@@ -349,15 +356,11 @@ static char *sip_reply_to_dup_one(sip_header_t *dst, sip_header_t const *src,
{
sip_reply_to_t *rplyto = (sip_reply_to_t *)dst;
sip_reply_to_t const *o = (sip_reply_to_t *)src;
char *end = b + xtra;
b = msg_params_dup(&rplyto->rplyto_params, o->rplyto_params, b, xtra);
MSG_STRING_DUP(b, rplyto->rplyto_display, o->rplyto_display);
URL_DUP(b, end, rplyto->rplyto_url, o->rplyto_url);
assert(b <= end);
return b;
return sip_name_addr_dup(&rplyto->rplyto_display, o->rplyto_display,
rplyto->rplyto_url, o->rplyto_url,
&rplyto->rplyto_params, o->rplyto_params,
b, xtra);
}
/* ====================================================================== */
@@ -889,10 +892,10 @@ isize_t sip_info_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_call_info_t const *ci = h->sh_call_info;
MSG_PARAMS_SIZE(offset, ci->ci_params);
offset += url_xtra(ci->ci_url);
return offset;
return sip_name_addr_xtra(NULL,
ci->ci_url,
ci->ci_params,
offset);
}
char *sip_info_dup_one(sip_header_t *dst,
@@ -902,14 +905,11 @@ char *sip_info_dup_one(sip_header_t *dst,
{
sip_call_info_t *ci = dst->sh_call_info;
sip_call_info_t const *o = src->sh_call_info;
char *end = b + xtra;
b = msg_params_dup(&ci->ci_params, o->ci_params, b, xtra);
URL_DUP(b, end, ci->ci_url, o->ci_url);
assert(b <= end);
return b;
return sip_name_addr_dup(NULL, NULL,
ci->ci_url, o->ci_url,
&ci->ci_params, o->ci_params,
b, xtra);
}
/* ====================================================================== */
@@ -1047,3 +1047,319 @@ issize_t sip_suppress_notify_if_match_e(char b[], isize_t bsiz,
}
#endif
#if SIP_HAVE_REMOTE_PARTY_ID
/**@SIP_HEADER sip_remote_party_id Remote-Party-ID Header
*
* The syntax of the Remote-Party-ID header is described as follows:
* @code
* Remote-Party-ID = "Remote-Party-ID" HCOLON rpid *(COMMA rpid)
*
* rpid = [display-name] LAQUOT addr-spec RAQUOT
* *(SEMI rpi-token)
*
* rpi-token = rpi-screen / rpi-pty-type /
* rpi-id-type / rpi-privacy / other-rpi-token
*
* rpi-screen = "screen" EQUAL ("no" / "yes")
*
* rpi-pty-type = "party" EQUAL ("calling" / "called" / token)
*
* rpi-id-type = "id-type" EQUAL ("subscriber" / "user" /
* "term" / token)
*
* rpi-privacy = "privacy" EQUAL
* ( rpi-priv-element
* / (LDQUOT rpi-priv-element
* *(COMMA rpi-priv-element) RDQUOT) )
*
* rpi-priv-element = ("full" / "name" / "uri" / "off" / token)
* ["-" ( "network" / token )]
*
* other-rpi-token = ["-"] token [EQUAL (token / quoted-string)]
*
* @endcode
*
* @sa sip_update_default_mclass(), draft-ietf-sip-privacy-04.txt, @RFC3325
*
* @NEW_1_12_7. In order to use @b Remote-Party-ID header,
* initialize the SIP parser with, e.g.,
* sip_update_default_mclass(sip_extend_mclass(NULL)).
*/
/**@ingroup sip_remote_party_id
* @typedef typedef struct sip_remote_party_id_s sip_remote_party_id_t;
*
* The structure #sip_remote_party_id_t contains representation of SIP
* @RemotePartyID header.
*
* The #sip_remote_party_id_t is defined as follows:
* @code
* typedef struct sip_remote_party_id_s {
* sip_common_t rpid_common[1]; // Common fragment info
* sip_remote_party_id_t *rpid_next; // Link to next
* char const *rpid_display; // Display name
* url_t rpid_url[1]; // URL
* sip_param_t const *rpid_params; // Parameters
* // Shortcuts to screen, party, id-type and privacy parameters
* char const *rpid_screen, *rpid_party, *rpid_id_type, *rpid_privacy;
* } sip_remote_party_id_t;
* @endcode
*/
extern msg_xtra_f sip_remote_party_id_dup_xtra;
extern msg_dup_f sip_remote_party_id_dup_one;
static msg_update_f sip_remote_party_id_update;
msg_hclass_t sip_remote_party_id_class[] =
SIP_HEADER_CLASS(remote_party_id, "Remote-Party-ID", "",
rpid_params, append, remote_party_id);
issize_t sip_remote_party_id_d(su_home_t *home, sip_header_t *h,
char *s, isize_t slen)
{
sip_remote_party_id_t *rpid = (sip_remote_party_id_t *)h;
while (*s == ',') /* Ignore empty entries (comma-whitespace) */
*s = '\0', s += span_lws(s + 1) + 1;
if (sip_name_addr_d(home, &s,
&rpid->rpid_display,
rpid->rpid_url,
&rpid->rpid_params, NULL) == -1)
return -1;
return msg_parse_next_field(home, h, s, slen);
}
issize_t sip_remote_party_id_e(char b[], isize_t bsiz,
sip_header_t const *h, int f)
{
sip_remote_party_id_t const *rpid = (sip_remote_party_id_t *)h;
return sip_name_addr_e(b, bsiz, f,
rpid->rpid_display, 1,
rpid->rpid_url,
rpid->rpid_params,
NULL);
}
/** Calculate size of extra data required for duplicating one
* sip_remote_party_id_t header.
*/
isize_t sip_remote_party_id_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_remote_party_id_t const *rpid = (sip_remote_party_id_t *)h;
return sip_name_addr_xtra(rpid->rpid_display,
rpid->rpid_url,
rpid->rpid_params,
offset);
}
/** Duplicate one sip_remote_party_id_t object */
char *sip_remote_party_id_dup_one(sip_header_t *dst,
sip_header_t const *src,
char *b, isize_t xtra)
{
sip_remote_party_id_t *rpid = (sip_remote_party_id_t *)dst;
sip_remote_party_id_t const *o = (sip_remote_party_id_t const *)src;
return sip_name_addr_dup(&rpid->rpid_display, o->rpid_display,
rpid->rpid_url, o->rpid_url,
&rpid->rpid_params, o->rpid_params,
b, xtra);
}
static int sip_remote_party_id_update(msg_common_t *h,
char const *name, isize_t namelen,
char const *value)
{
sip_remote_party_id_t *rpid = (sip_remote_party_id_t *)h;
if (name == NULL) {
rpid->rpid_screen = NULL;
rpid->rpid_party = NULL;
rpid->rpid_id_type = NULL;
rpid->rpid_privacy = NULL;
}
#define MATCH(s) (namelen == strlen(#s) && !strncasecmp(name, #s, strlen(#s)))
else if (MATCH(screen))
rpid->rpid_screen = value;
else if (MATCH(party))
rpid->rpid_party = value;
else if (MATCH(id-type))
rpid->rpid_id_type = value;
else if (MATCH(privacy))
rpid->rpid_privacy = value;
#undef MATCH
return 0;
}
#endif
#if SIP_HAVE_P_ASSERTED_IDENTITY
/**@SIP_HEADER sip_p_asserted_identity P-Asserted-Identity Header
*
* The P-Asserted-Identity header is used used among trusted SIP entities
* (typically intermediaries) to carry the identity of the user sending a
* SIP message as it was verified by authentication. It is "defined" in
* @RFC3325 section 9.1 as follows:
*
* @code
* PAssertedID = "P-Asserted-Identity" HCOLON PAssertedID-value
* *(COMMA PAssertedID-value)
* PAssertedID-value = name-addr / addr-spec
* @endcode
*
* @sa @RFC3325, @PPreferredIdentity
*
* @NEW_1_12_7. In order to use @b P-Asserted-Identity header,
* initialize the SIP parser with, e.g.,
* sip_update_default_mclass(sip_extend_mclass(NULL)).
*/
/**@ingroup sip_p_asserted_identity
* @typedef typedef struct sip_p_asserted_identity_s sip_p_asserted_identity_t;
*
* The structure #sip_p_asserted_identity_t contains representation of SIP
* @PAssertedIdentity header.
*
* The #sip_p_asserted_identity_t is defined as follows:
* @code
* typedef struct sip_p_asserted_identity_s {
* sip_common_t paid_common[1]; // Common fragment info
* sip_p_asserted_identity_t *paid_next; // Link to next
* char const *paid_display; // Display name
* url_t paid_url[1]; // URL
* } sip_p_asserted_identity_t;
* @endcode
*/
static msg_xtra_f sip_p_asserted_identity_dup_xtra;
static msg_dup_f sip_p_asserted_identity_dup_one;
#define sip_p_asserted_identity_update NULL
msg_hclass_t sip_p_asserted_identity_class[] =
SIP_HEADER_CLASS(p_asserted_identity, "P-Asserted-Identity", "",
paid_common, append, p_asserted_identity);
issize_t sip_p_asserted_identity_d(su_home_t *home, sip_header_t *h,
char *s, isize_t slen)
{
sip_p_asserted_identity_t *paid = (sip_p_asserted_identity_t *)h;
while (*s == ',') /* Ignore empty entries (comma-whitespace) */
*s = '\0', s += span_lws(s + 1) + 1;
if (sip_name_addr_d(home, &s,
&paid->paid_display,
paid->paid_url,
NULL, NULL) == -1)
return -1;
return msg_parse_next_field(home, h, s, slen);
}
issize_t sip_p_asserted_identity_e(char b[], isize_t bsiz,
sip_header_t const *h, int f)
{
sip_p_asserted_identity_t const *paid = (sip_p_asserted_identity_t *)h;
return sip_name_addr_e(b, bsiz, f,
paid->paid_display, MSG_IS_CANONIC(f),
paid->paid_url,
NULL,
NULL);
}
isize_t sip_p_asserted_identity_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_p_asserted_identity_t const *paid = (sip_p_asserted_identity_t *)h;
return sip_name_addr_xtra(paid->paid_display,
paid->paid_url,
NULL,
offset);
}
/** Duplicate one sip_p_asserted_identity_t object */
char *sip_p_asserted_identity_dup_one(sip_header_t *dst,
sip_header_t const *src,
char *b, isize_t xtra)
{
sip_p_asserted_identity_t *paid = (sip_p_asserted_identity_t *)dst;
sip_p_asserted_identity_t const *o = (sip_p_asserted_identity_t *)src;
return sip_name_addr_dup(&paid->paid_display, o->paid_display,
paid->paid_url, o->paid_url,
NULL, NULL,
b, xtra);
}
#endif
#if SIP_HAVE_P_PREFERRED_IDENTITY
/**@SIP_HEADER sip_p_preferred_identity P-Preferred-Identity Header
*
* The P-Preferred-Identity header is used used among trusted SIP entities
* (typically intermediaries) to carry the identity of the user sending a
* SIP message as it was verified by authentication. It is "defined" in
* @RFC3325 section 9.1 as follows:
*
* @code
* PPreferredID = "P-Preferred-Identity" HCOLON PPreferredID-value
* *(COMMA PPreferredID-value)
* PPreferredID-value = name-addr / addr-spec
* @endcode
*
* @sa @RFC3325, @PAssertedIdentity
*
* @NEW_1_12_7. In order to use @b P-Preferred-Identity header,
* initialize the SIP parser with, e.g.,
* sip_update_default_mclass(sip_extend_mclass(NULL)).
*/
/**@ingroup sip_p_preferred_identity
* @typedef typedef struct sip_p_preferred_identity_s sip_p_preferred_identity_t;
*
* The structure #sip_p_preferred_identity_t contains representation of SIP
* @PPreferredIdentity header.
*
* The #sip_p_preferred_identity_t is defined as follows:
* @code
* typedef struct sip_p_preferred_identity_s {
* sip_common_t ppid_common[1]; // Common fragment info
* sip_p_preferred_identity_t *ppid_next; // Link to next
* char const *ppid_display; // Display name
* url_t ppid_url[1]; // URL
* } sip_p_preferred_identity_t;
* @endcode
*/
msg_hclass_t sip_p_preferred_identity_class[] =
SIP_HEADER_CLASS(p_preferred_identity, "P-Preferred-Identity", "",
ppid_common, append, p_asserted_identity);
issize_t sip_p_preferred_identity_d(su_home_t *home, sip_header_t *h,
char *s, isize_t slen)
{
return sip_p_asserted_identity_d(home, h, s, slen);
}
issize_t sip_p_preferred_identity_e(char b[], isize_t bsiz,
sip_header_t const *h, int f)
{
return sip_p_asserted_identity_e(b, bsiz, h, f);
}
#endif
@@ -1,6 +1,9 @@
#
# This file specifies extra SIP headers not included in sip_t structure
#
# The parsed headers are accessed with function (or macro) like sip_refer_sub()
# e.g., sip_refer_sub_t *rsub = sip_refer_sub(sip);
#
# The line format is:
# C-name @SINCE sip_t-like-comment
#
@@ -9,8 +12,19 @@
#### EXTRA HEADER LIST STARTS HERE ####
refer_sub @NEW_1_12_5 /**< Refer-Sub header */
#### DEFAULT HEADER LIST ENDS HERE ####
#
# These headers are added to the extended parser, installed
# as default with sip_update_default_mclass(NULL)
#
alert_info @NEW_1_12_7 /**< Alert-Info header */
reply_to @NEW_1_12_7 /**< Reply-To header */
remote_party_id @NEW_1_12_7 /**< Remote-Party-ID header */
p_asserted_identity @NEW_1_12_7 /**<P-Asserted-Identity*/
p_preferred_identity @NEW_1_12_7 /**<P-Preferred-Identity*/
#### EXPERIMENTAL HEADER LIST STARTS HERE ####
@@ -60,11 +60,84 @@ char const sip_parser_version[] = VERSION;
char const sip_version_2_0[] = "SIP/2.0";
/** Default message class */
extern msg_mclass_t const sip_mclass[];
extern msg_mclass_t sip_mclass[];
static msg_mclass_t const *_default = sip_mclass;
/** Return a built-in SIP parser object. */
msg_mclass_t const *sip_default_mclass(void)
{
return sip_mclass;
return _default;
}
/** Update the default SIP parser.
*
* Use the extended SIP parser as default one.
*
* If the applications want to use headers added after @VERSION_1_12_5,
* they should call this function before doing any other initialization, e.g.,
* @code
* su_init();
* if (sip_update_default_mclass(sip_extend_mclass(NULL)) < 0) {
* su_deinit();
* exit(2);
* }
* @endcode
*
* The default parser is not extended because it may break the old
* applications looking for extension headers from sip_unknown list.
*
* @retval 0 when successful
* @retval -1 upon an error
*
* @NEW_1_12_7.
*/
int sip_update_default_mclass(msg_mclass_t const *mclass)
{
if (mclass == NULL)
return -1;
_default = mclass;
return 0;
}
/**Extend SIP parser class with extension headers.
*
* Extend given SIP parser class with extension headers. If the given parser
* class is the default one or NULL, make a clone of it before extending it.
*
* @param input pointer to a SIP message class (may be NULL)
*
* @return Pointer to extended mclass, or NULL upon an error.
*
* @NEW_1_12_7.
*/
msg_mclass_t *sip_extend_mclass(msg_mclass_t *input)
{
msg_mclass_t *mclass;
if (input == NULL || input == _default)
mclass = msg_mclass_clone(_default, 0, 0);
else
mclass = input;
if (mclass) {
extern msg_hclass_t * const sip_extensions[];
int i;
for (i = 0; sip_extensions[i]; i++) {
msg_hclass_t *hclass = sip_extensions[i];
if (mclass->mc_unknown != msg_find_hclass(mclass, hclass->hc_name, NULL))
continue;
if (msg_mclass_insert_header(mclass, hclass, 0) < 0) {
if (input != mclass)
free(mclass);
return mclass = NULL;
}
}
}
return mclass;
}
/** Extract the SIP message body, including separator line.
@@ -56,7 +56,7 @@
*/
#ifndef SIP_H
#include <sip.h>
#include <sofia-sip/sip.h>
#endif
/**@ingroup sip_also
@@ -543,12 +543,12 @@ sip_contact_t *sip_contact_immunize(su_home_t *home, sip_contact_t const *m)
*
* @retval -1 if the contact is rejected
* @retval 1000 if contact is immune to caller preferences
* @retval 0..1000 reflecting @RFC3481 score in 0.000 - 1.000.
* @retval 0..1000 reflecting @RFC3841 score in 0.000 - 1.000.
*
* @sa sip_q_value(),
* sip_contact_accept(), sip_contact_reject(), sip_contact_is_immune(),
* sip_contact_immunize(), sip_is_callerpref(), sip_prefs_matching(),
* @RFC3481, @AcceptContact, @RejectContact, @Contact
* @RFC3841, @AcceptContact, @RejectContact, @Contact
*/
int sip_contact_score(sip_contact_t const *m,
sip_accept_contact_t const *ac,
@@ -1421,3 +1421,4 @@ int sip_response_terminates_dialog(int response_code,
return 0;
}
@@ -107,7 +107,7 @@ typedef msg_time_t sip_time_t;
/** Latest time that can be expressed with #sip_time_t. @HIDE */
#define SIP_TIME_MAX ((sip_time_t)MSG_TIME_MAX)
/** SIP message object. */
/** Structure for accessing parsed SIP headers. */
typedef struct sip_s sip_t;
/** Any SIP header - union of all possible SIP headers. */
@@ -409,7 +409,7 @@ struct sip_accept_s
/**@ingroup sip_allow
* @brief Structure for @Allow header field.
*
* @NEW_1_12_5 (before used struct msg_list_s with @Allow).
* @NEW_1_12_5. (Before used struct msg_list_s with @Allow).
*/
struct sip_allow_s
{
@@ -417,7 +417,7 @@ struct sip_allow_s
msg_list_t *k_next; /**< Link to next */
msg_param_t *k_items; /**< List of allowed items */
uint32_t k_bitmap; /**< Bitmap of allowed methods.
@NEW_1_12_5 */
@NEW_1_12_5. */
};
/**@ingroup sip_authentication_info
@@ -573,7 +573,7 @@ struct sip_min_expires_s
};
/**@ingroup sip_rack
* @brief Structure for @b Rack header.
* @brief Structure for @RAck header.
*/
struct sip_rack_s
{
@@ -1,4 +1,4 @@
/**@file sofia-sip/sip_extra.h.in
`/**@file sofia-sip/sip_extra.h.in
* -*- C -*-
* Template for <sofia-sip/sip_extra.h>.
*
@@ -117,6 +117,55 @@ struct sip_suppress_notify_if_match_s
char const *snim_tag; /**< Entity-tag */
};
typedef struct sip_p_asserted_identity_s sip_p_asserted_identity_t;
/**@ingroup sip_p_asserted_identity
* @brief Structure for @PAssertedIdentity header.
*/
struct sip_p_asserted_identity_s
{
sip_common_t paid_common[1];/**< Common fragment info */
sip_p_asserted_identity_t
*paid_next; /**< Link to next identity */
char const *paid_display; /**< Display name */
url_t paid_url[1]; /**< SIP, SIPS or TEL URL */
};
typedef struct sip_p_preferred_identity_s sip_p_preferred_identity_t;
/**@ingroup sip_p_preferred_identity
* @brief Structure for @PPreferredIdentity header.
*/
struct sip_p_preferred_identity_s
{
sip_common_t ppid_common[1];/**< Common fragment info */
sip_p_preferred_identity_t
*ppid_next; /**< Link to next identity */
char const *ppid_display; /**< Display name */
url_t ppid_url[1]; /**< SIP, SIPS or TEL URL */
};
int sip_p_initialize_remote_party_id_headers(msg_mclass_t *mclass);
typedef struct sip_remote_party_id_s sip_remote_party_id_t;
/**@ingroup sip_remote_party_id
* @brief Structure for @RemotePartyID header.
*/
struct sip_remote_party_id_s
{
sip_common_t rpid_common[1];/**< Common fragment info */
sip_remote_party_id_t
*rpid_next; /**< Link to next identity */
char const *rpid_display; /**< Display name */
url_t rpid_url[1]; /**< URL */
sip_param_t const *rpid_params; /**< Parameters */
/** Shortcuts to screen, party, id-type and privacy parameters */
char const *rpid_screen, *rpid_party, *rpid_id_type, *rpid_privacy;
};
/** Defined as 1 if the @ref sip_#xxxxxx# "#xxxxxxx_xxxxxxx#" is supported */
#define SIP_HAVE_#XXXXXX# 1
@@ -57,13 +57,16 @@
SOFIA_BEGIN_DECLS
/** Return built-in SIP parser object. */
/** Return a built-in SIP parser object. */
SOFIAPUBFUN msg_mclass_t const *sip_default_mclass(void);
/** Check that sip_t is a SIP structure (not RTSP or HTTP). @HIDE */
SOFIAPUBFUN int sip_update_default_mclass(msg_mclass_t const *mclass);
SOFIAPUBFUN msg_mclass_t *sip_extend_mclass(msg_mclass_t *input);
/** Check that sip_t is a SIP header structure (not MIME or HTTP). @HIDE */
#define sip_is_sip(sip) ((sip) && (sip)->sip_ident == SIP_PROTOCOL_TAG)
/** Initializer for a SIP header object. @HIDE */
/** Initializer for a SIP header structure. @HIDE */
#define SIP_HDR_INIT(name) {{{ 0, 0, sip_##name##_class }}}
/** Initialize a SIP header structure. @HIDE */
@@ -349,7 +352,7 @@ int sip_has_feature(msg_list_t const *supported, char const *feature);
SOFIAPUBFUN int sip_is_allowed(sip_allow_t const *allow,
sip_method_t method, char const *name);
/** Check if the well-known method is listed in @Allow header. @NEW_1_12_6 */
/** Check if the well-known method is listed in @Allow header. @NEW_1_12_6. */
#define SIP_IS_ALLOWED(allow, method) \
(sip_method_unknown < (method) && (method) < 32 && \
(allow) && ((allow)->k_bitmap & (1 << (method))) != 0)
@@ -447,7 +450,7 @@ enum sip_bad_mask {
/** Bit marking essential headers for PUBLISH servers and clients.
*
* @SIPEtag, and @SIPIfMatch.
* @SIPETag, and @SIPIfMatch.
*
* @sa @RFC3903.
*/
@@ -137,6 +137,17 @@ SOFIAPUBFUN issize_t sip_name_addr_e(char b[], isize_t bsiz,
msg_param_t const params[],
char const *comment);
SOFIAPUBFUN isize_t sip_name_addr_xtra(char const *display, url_t const *addr,
msg_param_t const params[],
isize_t offset);
SOFIAPUBFUN char *sip_name_addr_dup(char const **d_display, char const *display,
url_t *d_addr, url_t const *addr,
msg_param_t const **d_params,
msg_param_t const params[],
char *b, isize_t xtra);
/* ---------------------------------------------------------------------------
* 3) Compatibility macros and functions
*/
@@ -153,7 +153,7 @@ siptag_header_vr(sip_header_t const **vp)
* Macro is used to include a tag item containing an unknown extension
* header in the tag list, e.g.,
* @code
* SIPTAG_HEADER_STR("Remote-Party-ID: +358718008000")
* SIPTAG_HEADER_STR("P-Alternative-URL: <+358718008000>")
* @endcode
*
* It is also possible to include multiple headers at once
@@ -138,7 +138,7 @@ union sip_pref
usize_t spl_length;
} sp_literal;
/** String (tag="&lt;foo&gt;"). */
/** String (tag="&lt;foo&gt;"). */ /* (tag="<foo>") */
struct sp_string {
enum sp_type sps_type;
char const *sps_value;
@@ -74,6 +74,135 @@ msg_mclass_t *test_mclass = NULL;
static msg_t *read_message(int flags, char const string[]);
static int test_identity(void)
{
su_home_t *home;
sip_p_asserted_identity_t *paid;
sip_p_preferred_identity_t *ppid;
msg_t *msg;
sip_t *sip;
BEGIN();
msg_href_t const *href;
msg_mclass_t const *def0, *def1, *ext;
def0 = sip_default_mclass();
/* Check that Refer-Sub has been added to our parser */
TEST_1(href = msg_find_hclass(def0, "Refer-Sub", NULL));
TEST_P(href->hr_class, sip_refer_sub_class);
/* Check that Reply-To is not there */
TEST_P(msg_find_hclass(def0, "Reply-To", NULL), def0->mc_unknown);
TEST_1(ext = sip_extend_mclass(NULL));
/* Update default parser */
TEST_1(sip_update_default_mclass(ext) == 0);
def1 = sip_default_mclass();
TEST_1(def0 != def1);
TEST_1(ext == def1);
TEST_1(href = msg_find_hclass(def1, "Reply-To", NULL));
TEST_P(href->hr_class, sip_reply_to_class);
TEST_1(test_mclass = msg_mclass_clone(def0, 0, 0));
msg = read_message(MSG_DO_EXTRACT_COPY,
"BYE sip:foo@bar SIP/2.0\r\n"
"To: <sip:foo@bar>;tag=deadbeef\r\n"
"From: <sip:bar@foo>;\r\n"
"Call-ID: 0ha0isndaksdj@10.1.2.3\r\n"
"CSeq: 8 SUBSCRIBE\r\n"
"Via: SIP/2.0/UDP 135.180.130.133\r\n"
"P-Asserted-Identity: <sip:test@test.domain.com>\r\n"
"P-Preferred-Identity: <sip:test@test.domain.com>, <tel:+358708008000>\r\n"
"Content-Length: 0\r\n"
"\r\n");
sip = sip_object(msg);
TEST_1(!sip_p_asserted_identity(sip));
TEST_1(!sip_p_preferred_identity(sip));
msg_destroy(msg);
TEST_1(msg_mclass_insert_header(test_mclass,
sip_p_asserted_identity_class, 0) > 0);
TEST_1(msg_mclass_insert_header(test_mclass,
sip_p_preferred_identity_class, 0) > 0);
msg = read_message(MSG_DO_EXTRACT_COPY,
"BYE sip:foo@bar SIP/2.0\r\n"
"To: <sip:foo@bar>;tag=deadbeef\r\n"
"From: <sip:bar@foo>;\r\n"
"Call-ID: 0ha0isndaksdj@10.1.2.3\r\n"
"CSeq: 8 SUBSCRIBE\r\n"
"Via: SIP/2.0/UDP 135.180.130.133\r\n"
"P-Asserted-Identity: <sip:test@test.domain.com>\r\n"
"P-Preferred-Identity: <sip:test@test.domain.com>, <tel:+358708008000>\r\n"
"Content-Length: 0\r\n"
"\r\n");
sip = sip_object(msg);
TEST_1(home = msg_home(msg));
TEST_1((paid = sip_p_asserted_identity_make(home, "sip:joe@example.com")));
TEST_1((paid = sip_p_asserted_identity_make
(home, "Jaska <sip:joe@example.com>, Helmi <tel:+3587808000>")));
TEST_1(paid->paid_next);
TEST_1((ppid = sip_p_preferred_identity_make(home, "sip:joe@example.com")));
TEST_1((ppid = sip_p_preferred_identity_make
(home, "Jaska <sip:joe@example.com>, Helmi <tel:+3587808000>")));
msg_destroy(msg);
/* Now with extensions */
TEST_1(test_mclass = msg_mclass_clone(def1, 0, 0));
{
su_home_t *home = su_home_clone(NULL, sizeof *home);
char *s;
char const canonic[] =
"\"Jaska Jokunen\" <sip:jaska.jokunen@example.com>;"
"screen=yes;party=called;id-type=user;privacy=\"name,uri-network\"";
char const canonic2[] =
"Jaska Jokunen <sip:jaska.jokunen@example.com>;"
"screen=yes;party=called;id-type=user;privacy=\"name,uri-network\"";
sip_remote_party_id_t *rpid, *d;
TEST_1(rpid = sip_remote_party_id_make(home, canonic));
TEST_S(rpid->rpid_display, "\"Jaska Jokunen\"");
TEST_S(rpid->rpid_url->url_user, "jaska.jokunen");
TEST_S(rpid->rpid_params[0], "screen=yes");
TEST_S(rpid->rpid_screen, "yes");
TEST_S(rpid->rpid_party, "called");
TEST_S(rpid->rpid_id_type, "user");
TEST_S(rpid->rpid_privacy, "\"name,uri-network\"");
TEST_1(s = sip_header_as_string(home, (void*)rpid));
TEST_S(s, canonic);
TEST_1(d = sip_remote_party_id_dup(home, rpid));
TEST_S(d->rpid_display, rpid->rpid_display);
TEST_S(d->rpid_params[0], rpid->rpid_params[0]);
TEST_1(rpid = sip_remote_party_id_make(home, canonic2));
TEST_S(rpid->rpid_display, "Jaska Jokunen");
TEST_1(s = sip_header_as_string(home, (void*)rpid));
TEST_S(s, canonic2);
TEST_1(d = sip_remote_party_id_dup(home, rpid));
TEST_S(d->rpid_display, rpid->rpid_display);
su_home_check(home);
su_home_zap(home);
}
END();
}
int test_url_headers(void)
{
BEGIN();
@@ -84,16 +213,20 @@ int test_url_headers(void)
sip_from_t const *f;
sip_accept_t const *ac;
sip_payload_t const *body;
sip_refer_sub_t rs[1];
TEST_1(home = su_home_new(sizeof *home));
sip_refer_sub_init(rs)->rs_value = "false";
s = sip_headers_as_url_query
(home,
SIPTAG_SUBJECT_STR(";"),
SIPTAG_SUBJECT_STR("kuik"),
SIPTAG_REFER_SUB(rs),
TAG_END());
TEST_1(s);
TEST_S(s, "subject=;");
TEST_S(s, "subject=kuik&refer-sub=false");
s = sip_headers_as_url_query
(home,
@@ -2189,7 +2322,7 @@ int test_refer(void)
TEST_1(home = su_home_create());
/* Check that Refer-Sub has already been added to our parser */
/* Check that Refer-Sub has now been added to our parser */
TEST_1(msg_mclass_insert_with_mask(test_mclass, sip_refer_sub_class,
0, 0) == -1);
@@ -3334,9 +3467,13 @@ int main(int argc, char *argv[])
tstflags |= tst_verbatim;
#endif
if (!test_mclass)
retval |= test_identity(); fflush(stdout);
if (test_mclass == NULL)
test_mclass = msg_mclass_clone(sip_default_mclass(), 0, 0);
retval |= parser_test(); fflush(stdout);
retval |= test_url_headers(); fflush(stdout);
retval |= test_manipulation(); fflush(stdout);
retval |= test_methods(); fflush(stdout);
@@ -3348,7 +3485,7 @@ int main(int argc, char *argv[])
retval |= tag_test(); fflush(stdout);
retval |= parser_tag_test(); fflush(stdout);
retval |= response_phrase_test(); fflush(stdout);
retval |= parser_test(); fflush(stdout);
retval |= sip_header_test(); fflush(stdout);
retval |= test_bad_packet(); fflush(stdout);
retval |= test_sip_list_header(); fflush(stdout);
@@ -22,9 +22,10 @@
*
*/
/**@IFILE validator.c
/**@internal @IFILE validator.c
*
* SIP parser tester. This uses output
* SIP parser tester. This uses output from tport dump where messages are
* separated with Control-K ('\v') from each other.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>.
*
+11 -11
View File
@@ -824,7 +824,7 @@ int soa_get_warning(soa_session_t *ss, char const **return_text)
* nua_options(), #nua_i_options
*/
int soa_get_capability_sdp(soa_session_t const *ss,
sdp_session_t const **return_sdp,
struct sdp_session_s const **return_sdp,
char const **return_sdp_str,
isize_t *return_len)
{
@@ -874,7 +874,7 @@ int soa_get_capability_sdp(soa_session_t const *ss,
* nua_options(), #nua_i_options
*/
int soa_set_capability_sdp(soa_session_t *ss,
sdp_session_t const *sdp,
struct sdp_session_s const *sdp,
char const *str, issize_t len)
{
SU_DEBUG_9(("soa_set_capability_sdp(%s::%p, %p, %p, "MOD_ZD") called\n",
@@ -956,7 +956,7 @@ soa_base_set_capability_sdp(soa_session_t *ss,
* soa_get_capability_sdp()
*/
int soa_get_user_sdp(soa_session_t const *ss,
sdp_session_t const **return_sdp,
struct sdp_session_s const **return_sdp,
char const **return_sdp_str,
isize_t *return_len)
{
@@ -1032,7 +1032,7 @@ int soa_get_user_version(soa_session_t const *ss)
* soa_set_remote_sdp()
*/
int soa_set_user_sdp(soa_session_t *ss,
sdp_session_t const *sdp,
struct sdp_session_s const *sdp,
char const *str, issize_t len)
{
SU_DEBUG_9(("soa_set_user_sdp(%s::%p, %p, %p, "MOD_ZD") called\n",
@@ -1073,7 +1073,7 @@ int soa_base_set_user_sdp(soa_session_t *ss,
* soa_get_local_sdp(), soa_get_user_sdp(), soa_get_capability_sdp().
*/
int soa_get_remote_sdp(soa_session_t const *ss,
sdp_session_t const **return_sdp,
struct sdp_session_s const **return_sdp,
char const **return_sdp_str,
isize_t *return_len)
{
@@ -1151,7 +1151,7 @@ int soa_get_remote_version(soa_session_t const *ss)
* soa_set_user_sdp(), soa_set_capability_sdp().
*/
int soa_set_remote_sdp(soa_session_t *ss,
sdp_session_t const *sdp,
struct sdp_session_s const *sdp,
char const *str, issize_t len)
{
SU_DEBUG_9(("soa_set_remote_sdp(%s::%p, %p, %p, "MOD_ZD") called\n",
@@ -1245,7 +1245,7 @@ int soa_has_received_sdp(soa_session_t const *ss)
* soa_get_user_sdp(), soa_get_remote_sdp(), soa_get_capability_sdp().
*/
int soa_get_local_sdp(soa_session_t const *ss,
sdp_session_t const **return_sdp,
struct sdp_session_s const **return_sdp,
char const **return_sdp_str,
isize_t *return_len)
{
@@ -1412,7 +1412,7 @@ int soa_generate_offer(soa_session_t *ss,
if (ss == NULL)
return su_seterrno(EFAULT), -1;
/** @ERROR An operation is already in progress */
/** @ERROR EALREADY An operation is already in progress */
if (ss->ss_in_progress)
return su_seterrno(EALREADY), -1;
@@ -1500,7 +1500,7 @@ int soa_generate_answer(soa_session_t *ss,
if (ss == NULL)
return su_seterrno(EFAULT), -1;
/** @ERROR An operation is already in progress. */
/** @ERROR EALREADY An operation is already in progress. */
if (ss->ss_in_progress)
return su_seterrno(EALREADY), -1;
@@ -1580,7 +1580,7 @@ int soa_process_answer(soa_session_t *ss,
if (ss == NULL)
return su_seterrno(EFAULT), -1;
/** @ERROR An operation is already in progress. */
/** @ERROR EALREADY An operation is already in progress. */
if (ss->ss_in_progress)
return su_seterrno(EALREADY), -1;
@@ -1661,7 +1661,7 @@ int soa_process_reject(soa_session_t *ss,
if (ss == NULL)
return su_seterrno(EFAULT), -1;
/** @ERROR An operation is already in progress. */
/** @ERROR EALREADY An operation is already in progress. */
if (ss->ss_in_progress)
return su_seterrno(EALREADY), -1;
+1 -1
View File
@@ -3,7 +3,7 @@
@section soa_meta Module Information
The Sofia SIP @b soa module consists of an asynchronous SDP Offer/Answer engine
library. The interface to library is defined in <soa.h>.
library. The interface to library is defined in <sofia-sip/soa.h>.
@CONTACT Pekka Pessi <Pekka.Pessi@nokia.com>
@@ -631,6 +631,8 @@ tag_typedef_t soatag_hold = STRTAG_TYPEDEF(hold);
* Corresponding tag taking a reference parameter is SOATAG_RTP_SELECT_REF().
*
* @sa @RFC3264 section 8.3.3, T.38
*
* @NEW_1_12_7.
*/
tag_typedef_t soatag_ordered_user = BOOLTAG_TYPEDEF(ordered_user);
@@ -30,14 +30,14 @@
# Author(s): Pekka Pessi <Pekka.Pessi@nokia.com>.
#
s=${0%/*}
test x$s = x$0 && s=`pwd`
s=`dirname $0`
test x$s = x. && s=`pwd`
PATH=/usr/sbin:/usr/local/sbin:/sbin:$PATH
export PATH
# Test for support for IPv6 on Linux. This probably fails on everything else.
ipv6='sysctl net.ipv6.conf.default.mtu >& /dev/null'
ipv6='sysctl net.ipv6.conf.default.mtu >/dev/null 2>&1'
# Bind not working with IPv6 on RHEL 4:
# client.c:1325: unexpected error: failed to get request's destination: failure
#ipv6=false
@@ -46,18 +46,18 @@ port=`expr $$ % \( 65536 - 1024 \) + 1024`
# Try to find a free port
if netstat --ip >/dev/null 2>&1 ; then
while netstat --ip -n -a | fgrep -q ":$port "
while netstat --ip -n -a | fgrep ":$port " > /dev/null
do
port=$(($port + 1))
if [$port = 65536] ; then
port=`expr $port + 1`
if test $port = 65536 ; then
port=1024
fi
done
fi
# No BIND 9, no fun
{ type -p named >/dev/null &&
named -v | grep -q BIND.*9
{ type named >/dev/null &&
named -v | grep BIND.*9 > /dev/null
} || {
echo test_sresolv: there is no BIND 9 named in you path, skipping
exit 77
@@ -66,10 +66,10 @@ exit 77
if eval $ipv6
then
# Figure out nice IPv6 address for us
ns=$(ip addr ls | awk '
ns=`ip addr ls | awk '
/^[0-9]:/ { up = ($3 ~ /UP/) && ($3 !~ /LOOPBACK/); }
/inet6 fe80::/ { next; } # no link-local
up && $1 ~ /inet6/ { sub(/\/.*$/, "", $2); print $2; exit 0; }')
up && $1 ~ /inet6/ { sub(/\/.*$/, "", $2); print $2; exit 0; }'`
# Nothing found, use localnode ::1
if test -z "$ns"; then ns=::1 ; fi
@@ -113,9 +113,11 @@ search example.com
port $port
EOF
absolute=`cd $s; pwd`
cat > $t/named.conf <<EOF
options {
directory "$(cd $s; pwd)";
directory "$absolute";
pid-file "$t/named.pid";
notify no;
$listen4
@@ -164,16 +166,16 @@ done
test -r $t/named.pid || {
echo $0: cannot start named >&2 ;
if fgrep -q -i -e SELINUX=enforcing /etc/selinux/config 2>&/dev/null ; then
if fgrep -i -e SELINUX=enforcing /etc/selinux/config >/dev/null 2>&1 ; then
echo $0: perhaps you have to disable SELinux protection for named
fi
exit 77
}
function kill_named
kill_named ()
{
kill `cat $t/named.pid`
rm $t/named.conf $t/resolv.conf $t/error.conf $t/named.pid
rm $t/named.conf $t/resolv.conf $t/error.conf $t/named.pid 2>/dev/null
rmdir $t
}
trap kill_named EXIT
@@ -224,6 +224,10 @@ int test_api_errors(void)
extern void sres_cache_clean(sres_cache_t *cache, time_t now);
#ifndef CLOCK_PROCESS_CPUTIME_ID
#define CLOCK_PROCESS_CPUTIME_ID CLOCK_REALTIME
#endif
static
int test_cache(void)
{
@@ -282,7 +286,7 @@ int test_cache(void)
if (t1.tv_nsec < t0.tv_nsec)
t2.tv_sec--, t2.tv_nsec += 1000000000;
printf("sres_cache: stored %u entries: %lu.%09lu sec\n",
N, t2.tv_sec, t2.tv_nsec);
N, (long unsigned)t2.tv_sec, t2.tv_nsec);
}
for (i = 0, N; i < N; i++)
@@ -299,7 +303,7 @@ int test_cache(void)
if (t1.tv_nsec < t0.tv_nsec)
t2.tv_sec--, t2.tv_nsec += 1000000000;
printf("sres_cache: cleaned %u entries: %lu.%09lu sec\n",
N, t2.tv_sec, t2.tv_nsec);
N, (long unsigned)t2.tv_sec, t2.tv_nsec);
}
for (i = 0, N; i < N; i++)
@@ -321,7 +325,7 @@ int test_cache(void)
if (t1.tv_nsec < t0.tv_nsec)
t2.tv_sec--, t2.tv_nsec += 1000000000;
printf("sres_cache: stored %u entries: %lu.%09lu sec\n",
N, t2.tv_sec, t2.tv_nsec);
N, (long unsigned)t2.tv_sec, t2.tv_nsec);
}
for (i = 0, N; i < N; i++)
@@ -339,7 +343,7 @@ int test_cache(void)
if (t1.tv_nsec < t0.tv_nsec)
t2.tv_sec--, t2.tv_nsec += 1000000000;
printf("sres_cache: cleaned %u entries: %lu.%09lu sec\n",
N, t2.tv_sec, t2.tv_nsec);
N, (long unsigned)t2.tv_sec, t2.tv_nsec);
}
for (i = 0, N; i < N; i++) {
@@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file lookup_stun_server.c
* @brief Test app for STUN DNS-SRV lookups.
*
+1 -1
View File
@@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file stun.c STUN client module
*
* See RFC 3489/3489bis for further information.
@@ -14,9 +14,9 @@ client library.
@section stun_contents Contents of stun Module
The stun module contains the public header files as follows:
- <stun.h> the public API of the module
- <stun_common.h> low-level functions for parsing and encoding STUN messages
- <stun_tag.h> defines the su tags used by stun
- <sofia-sip/stun.h> the public API of the module
- <sofia-sip/stun_common.h> low-level functions for parsing and encoding STUN messages
- <sofia-sip/stun_tag.h> defines the su tags used by stun
@section stun_usage Using Sofia STUN Library
@@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file stun_common.c
* @brief
*
@@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file stun_dns.c
* @brief Functins to discover STUN server address using DNS-SRV.
*
@@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file stun_mini.c
* @brief Minimal stun server
*
@@ -22,7 +22,7 @@
*
*/
/**@CFILE stun_tag.c Tags and tag lists for Offer/Answer Engine
/**@internal @CFILE stun_tag.c Tags and tag lists for Offer/Answer Engine
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
* @author Martti Mela <Martti.Mela@nokia.com>
@@ -73,7 +73,7 @@ libsu_la_SOURCES = \
su_os_nw.c \
su_taglist.c su_tag.c su_tag_io.c \
su_log.c su_global_log.c su_default_log.c su_module_debug.h \
su_md5.c su_uniqueid.c su_bm.c string0.c $(OSXSOURCES)
su_md5.c su_uniqueid.c su_bm.c smoothsort.c string0.c $(OSXSOURCES)
EXTRA_libsu_la_SOURCES = \
+265
View File
@@ -0,0 +1,265 @@
/*
* This file is part of the Sofia-SIP package
*
* Copyright (C) 2005 Nokia Corporation.
*
* Contact: Pekka Pessi <pekka.pessi@nokia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**@file smoothsort.c
* @brief Smoothsort implementation
*
* Smoothsort is a in-place sorting algorithm with performance of O(NlogN)
* in worst case and O(n) in best case.
*
* @sa <a href="http://www.enterag.ch/hartwig/order/smoothsort.pdf">
* "Smoothsort, an alternative for sorting in-situ", E.D. Dijkstra, EWD796a</a>,
* &lt;http://www.enterag.ch/hartwig/order/smoothsort.pdf&gt;.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*/
#include "config.h"
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
/** Description of current stretch */
typedef struct {
size_t b, c; /**< Leonardo numbers */
unsigned longlong p; /**< Concatenation codification */
} stretch;
/** Description of array */
typedef struct
{
void *m;
int (*less)(void *m, size_t a, size_t b);
void (*swap)(void *m, size_t a, size_t b);
} array;
static inline size_t stretch_up(stretch s[1])
{
size_t next;
s->p >>= 1;
next = s->b + s->c + 1, s->c = s->b, s->b = next;
return next;
}
static inline size_t stretch_down(stretch s[1], unsigned bit)
{
size_t next;
s->p <<= 1, s->p |= bit;
next = s->c, s->c = s->b - s->c - 1, s->b = next;
return next;
}
#if DEBUG_SMOOTHSORT
static char const *binary(unsigned long long p)
{
static char binary[65];
int i;
if (p == 0)
return "0";
binary[64] = 0;
for (i = 64; p; p >>= 1)
binary[--i] = "01"[p & 1];
return binary + i;
}
#else
#define DEBUG(x) ((void)0)
#endif
/**
* Sift the root of the stretch.
*
* The low values are sifted up (towards index 0) from root.
*
* @param array description of array to sort
* @param r root of the stretch
* @param s description of current stretch
*/
static void sift(array const *array, size_t r, stretch s)
{
while (s.b >= 3) {
size_t r2 = r - s.b + s.c;
if (!array->less(array->m, r - 1, r2)) {
r2 = r - 1;
stretch_down(&s, 0);
}
if (array->less(array->m, r2, r))
break;
DEBUG(("\tswap(%p @%zu <=> @%zu)\n", array, r, r2));
array->swap(array->m, r, r2); r = r2;
stretch_down(&s, 0);
}
}
/** Trinkle the roots of the given stretches
*
* @param array description of array to sort
* @param r root of the stretch
* @param s description of stretches to concatenate
*/
static void trinkle(array const *array, size_t r, stretch s)
{
DEBUG(("trinkle(%p, %zu, (%u, %s))\n", array, r, s.b, binary(s.p)));
while (s.p != 0) {
size_t r2, r3;
while ((s.p & 1) == 0)
stretch_up(&s);
if (s.p == 1)
break;
r3 = r - s.b;
if (array->less(array->m, r3, r))
break;
s.p--;
if (s.b < 3) {
DEBUG(("\tswap(%p @%zu <=> @%zu b=%u)\n", array, r, r3, s.b));
array->swap(array->m, r, r3); r = r3;
continue;
}
r2 = r - s.b + s.c;
if (array->less(array->m, r2, r - 1)) {
r2 = r - 1;
stretch_down(&s, 0);
}
if (array->less(array->m, r2, r3)) {
DEBUG(("swap(%p [%zu]=[%zu])\n", array, r, r3));
array->swap(array->m, r, r3); r = r3;
continue;
}
DEBUG(("\tswap(%p @%zu <=> @%zu b=%u)\n", array, r, r2, s.b));
array->swap(array->m, r, r2); r = r2;
stretch_down(&s, 0);
break;
}
sift(array, r, s);
}
/** Trinkles the stretches when the adjacent stretches are already trusty.
*
* @param array description of array to sort
* @param r root of the stretch
* @param stretch description of stretches to trinkle
*/
static void semitrinkle(array const *array, size_t r, stretch s)
{
size_t r1 = r - s.c;
DEBUG(("semitrinkle(%p, %zu, (%u, %s))\n", array, r, s.b, binary(s.p)));
if (array->less(array->m, r, r1)) {
DEBUG(("\tswap(%p @%zu <=> @%zu b=%u)\n", array, r, r1, s.b));
array->swap(array->m, r, r1);
trinkle(array, r1, s);
}
}
/** Sort array using smoothsort.
*
* Sort @a N elements from array @a base starting with index @a r with smoothsort.
*
* @param base pointer to array
* @param r lowest index to sort
* @param N number of elements to sort
* @param less comparison function returning nonzero if m[a] < m[b]
* @param swap swapper function exchanging elements m[a] and m[b]
*/
void su_smoothsort(void *base, size_t r, size_t N,
int (*less)(void *m, size_t a, size_t b),
void (*swap)(void *m, size_t a, size_t b))
{
stretch s = { 1, 1, 1 };
size_t q;
array const array[1] = {{ base, less, swap }};
assert(less && swap);
if (base == NULL || N <= 1 || less == NULL || swap == NULL)
return;
DEBUG(("\nsmoothsort(%p, %zu)\n", array, nmemb));
for (q = 1; q != N; q++, r++, s.p++) {
DEBUG(("loop0 q=%zu, b=%u, p=%s \n", q, s.b, binary(s.p)));
if ((s.p & 7) == 3) {
sift(array, r, s), stretch_up(&s), stretch_up(&s);
}
else /* if ((s.p & 3) == 1) */ { assert((s.p & 3) == 1);
if (q + s.c < N)
sift(array, r, s);
else
trinkle(array, r, s);
while (stretch_down(&s, 0) > 1)
;
}
}
trinkle(array, r, s);
for (; q > 1; q--) {
s.p--;
DEBUG(("loop1 q=%zu: b=%u p=%s\n", q, s.b, binary(s.p)));
if (s.b <= 1) {
while ((s.p & 1) == 0)
stretch_up(&s);
--r;
}
else /* if b >= 3 */ {
if (s.p) semitrinkle(array, r - (s.b - s.c), s);
stretch_down(&s, 1);
semitrinkle(array, --r, s);
stretch_down(&s, 1);
}
}
}
+1 -1
View File
@@ -22,7 +22,7 @@
*
*/
/**@file memccpy.c
/**@internal @file memccpy.c
* @brief The memccpy() replacement function.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
+1 -1
View File
@@ -22,7 +22,7 @@
*
*/
/**@file memcspn.c
/**@internal @file memcspn.c
* @brief The memcspn() replacement function.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
+2 -1
View File
@@ -22,7 +22,8 @@
*
*/
/**@file memmem.c
/**@internal @file memmem.c
*
* @brief Backup implementation of memmem()
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
+2 -1
View File
@@ -22,7 +22,8 @@
*
*/
/**@file memspn.c
/**@internal @file memspn.c
*
* The memspn() replacement function.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
@@ -8,7 +8,7 @@ for SU_PORT in select kqueue devpoll epoll poll ; do
export SU_PORT
egrep -q -i '^#define have_(sys_)?'$SU_PORT ../../config.h ||
egrep -i '^#define have_(sys_)?'$SU_PORT ../../config.h >/dev/null ||
continue
run=yes
@@ -0,0 +1,265 @@
/*
* This file is part of the Sofia-SIP package
*
* Copyright (C) 2005 Nokia Corporation.
*
* Contact: Pekka Pessi <pekka.pessi@nokia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**@file smoothsort.c
* @brief Smoothsort implementation
*
* Smoothsort is a in-place sorting algorithm with performance of O(NlogN)
* in worst case and O(n) in best case.
*
* @sa <a href="http://www.enterag.ch/hartwig/order/smoothsort.pdf">
* "Smoothsort, an alternative for sorting in-situ", E.D. Dijkstra, EWD796a</a>,
* &lt;http://www.enterag.ch/hartwig/order/smoothsort.pdf&gt;.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*/
#include "config.h"
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
/** Description of current stretch */
typedef struct {
size_t b, c; /**< Leonardo numbers */
unsigned longlong p; /**< Concatenation codification */
} stretch;
/** Description of array */
typedef struct
{
void *m;
int (*less)(void *m, size_t a, size_t b);
void (*swap)(void *m, size_t a, size_t b);
} array;
static inline size_t stretch_up(stretch s[1])
{
size_t next;
s->p >>= 1;
next = s->b + s->c + 1, s->c = s->b, s->b = next;
return next;
}
static inline size_t stretch_down(stretch s[1], unsigned bit)
{
size_t next;
s->p <<= 1, s->p |= bit;
next = s->c, s->c = s->b - s->c - 1, s->b = next;
return next;
}
#if DEBUG_SMOOTHSORT
static char const *binary(unsigned long long p)
{
static char binary[65];
int i;
if (p == 0)
return "0";
binary[64] = 0;
for (i = 64; p; p >>= 1)
binary[--i] = "01"[p & 1];
return binary + i;
}
#else
#define DEBUG(x) ((void)0)
#endif
/**
* Sift the root of the stretch.
*
* The low values are sifted up (towards index 0) from root.
*
* @param array description of array to sort
* @param r root of the stretch
* @param s description of current stretch
*/
static void sift(array const *array, size_t r, stretch s)
{
while (s.b >= 3) {
size_t r2 = r - s.b + s.c;
if (!array->less(array->m, r - 1, r2)) {
r2 = r - 1;
stretch_down(&s, 0);
}
if (array->less(array->m, r2, r))
break;
DEBUG(("\tswap(%p @%zu <=> @%zu)\n", array, r, r2));
array->swap(array->m, r, r2); r = r2;
stretch_down(&s, 0);
}
}
/** Trinkle the roots of the given stretches
*
* @param array description of array to sort
* @param r root of the stretch
* @param s description of stretches to concatenate
*/
static void trinkle(array const *array, size_t r, stretch s)
{
DEBUG(("trinkle(%p, %zu, (%u, %s))\n", array, r, s.b, binary(s.p)));
while (s.p != 0) {
size_t r2, r3;
while ((s.p & 1) == 0)
stretch_up(&s);
if (s.p == 1)
break;
r3 = r - s.b;
if (array->less(array->m, r3, r))
break;
s.p--;
if (s.b < 3) {
DEBUG(("\tswap(%p @%zu <=> @%zu b=%u)\n", array, r, r3, s.b));
array->swap(array->m, r, r3); r = r3;
continue;
}
r2 = r - s.b + s.c;
if (array->less(array->m, r2, r - 1)) {
r2 = r - 1;
stretch_down(&s, 0);
}
if (array->less(array->m, r2, r3)) {
DEBUG(("swap(%p [%zu]=[%zu])\n", array, r, r3));
array->swap(array->m, r, r3); r = r3;
continue;
}
DEBUG(("\tswap(%p @%zu <=> @%zu b=%u)\n", array, r, r2, s.b));
array->swap(array->m, r, r2); r = r2;
stretch_down(&s, 0);
break;
}
sift(array, r, s);
}
/** Trinkles the stretches when the adjacent stretches are already trusty.
*
* @param array description of array to sort
* @param r root of the stretch
* @param stretch description of stretches to trinkle
*/
static void semitrinkle(array const *array, size_t r, stretch s)
{
size_t r1 = r - s.c;
DEBUG(("semitrinkle(%p, %zu, (%u, %s))\n", array, r, s.b, binary(s.p)));
if (array->less(array->m, r, r1)) {
DEBUG(("\tswap(%p @%zu <=> @%zu b=%u)\n", array, r, r1, s.b));
array->swap(array->m, r, r1);
trinkle(array, r1, s);
}
}
/** Sort array using smoothsort.
*
* Sort @a N elements from array @a base starting with index @a r with smoothsort.
*
* @param base pointer to array
* @param r lowest index to sort
* @param N number of elements to sort
* @param less comparison function returning nonzero if m[a] < m[b]
* @param swap swapper function exchanging elements m[a] and m[b]
*/
void su_smoothsort(void *base, size_t r, size_t N,
int (*less)(void *m, size_t a, size_t b),
void (*swap)(void *m, size_t a, size_t b))
{
stretch s = { 1, 1, 1 };
size_t q;
array const array[1] = {{ base, less, swap }};
assert(less && swap);
if (base == NULL || N <= 1 || less == NULL || swap == NULL)
return;
DEBUG(("\nsmoothsort(%p, %zu)\n", array, nmemb));
for (q = 1; q != N; q++, r++, s.p++) {
DEBUG(("loop0 q=%zu, b=%u, p=%s \n", q, s.b, binary(s.p)));
if ((s.p & 7) == 3) {
sift(array, r, s), stretch_up(&s), stretch_up(&s);
}
else /* if ((s.p & 3) == 1) */ { assert((s.p & 3) == 1);
if (q + s.c < N)
sift(array, r, s);
else
trinkle(array, r, s);
while (stretch_down(&s, 0) > 1)
;
}
}
trinkle(array, r, s);
for (; q > 1; q--) {
s.p--;
DEBUG(("loop1 q=%zu: b=%u p=%s\n", q, s.b, binary(s.p)));
if (s.b <= 1) {
while ((s.p & 1) == 0)
stretch_up(&s);
--r;
}
else /* if b >= 3 */ {
if (s.p) semitrinkle(array, r - (s.b - s.c), s);
stretch_down(&s, 1);
semitrinkle(array, --r, s);
stretch_down(&s, 1);
}
}
}
@@ -114,6 +114,7 @@ scope int prefix##free(void *, heaptype *); \
scope int prefix##is_full(heaptype const); \
scope size_t prefix##size(heaptype const); \
scope size_t prefix##used(heaptype const); \
scope void prefix##sort(heaptype); \
scope int prefix##add(heaptype, type); \
scope type prefix##remove(heaptype, size_t); \
scope type prefix##get(heaptype, size_t)
@@ -126,6 +127,7 @@ scope type prefix##get(heaptype, size_t)
* - prefix ## is_full(heap)
* - prefix ## size(heap)
* - prefix ## used(heap)
* - prefix ## sort(heap)
* - prefix ## add(heap, entry)
* - prefix ## remove(heap, index)
* - prefix ## get(heap, index)
@@ -240,35 +242,32 @@ scope type prefix##remove(heaptype h, size_t index) \
struct prefix##priv { size_t _size, _used; type _heap[1];}; \
struct prefix##priv *_priv = *(void **)&h; \
type *heap = _priv->_heap - 1; \
type retval; \
type retval[1]; \
type e; \
\
size_t top, left, right, move; \
\
move = _priv->_used; \
\
if (index - 1 >= _priv->_used) \
return (null); \
\
move = _priv->_used--; \
retval = heap[top = index]; \
set(retval, 0, heap[index]); \
\
for (;;) { \
for (top = index;;index = top) { \
left = 2 * top; \
right = 2 * top + 1; \
\
if (right >= move) \
if (left >= move) \
break; \
if (less(heap[right], heap[left])) \
if (right < move && less(heap[right], heap[left])) \
top = right; \
else \
top = left; \
set(heap, index, heap[top]); \
index = top; \
} \
\
if (index == move) \
return retval; \
return *retval; \
\
e = heap[move]; \
for (; index > 1; index = top) { \
@@ -280,7 +279,7 @@ scope type prefix##remove(heaptype h, size_t index) \
\
set(heap, index, e); \
\
return retval; \
return *retval; \
} \
\
scope \
@@ -310,6 +309,25 @@ size_t prefix##used(heaptype const h) \
struct prefix##priv *_priv = *(void **)&h; \
return _priv ? _priv->_used : 0; \
} \
scope int prefix##_less(void *h, size_t a, size_t b) \
{ \
type *_heap = h; return less(_heap[a], _heap[b]); \
} \
scope void prefix##_swap(void *h, size_t a, size_t b) \
{ \
type *_heap = h; type _swap = _heap[a]; \
set(_heap, a, _heap[b]); set(_heap, b, _swap); \
} \
void su_smoothsort(void *base, size_t r0, size_t N, \
int (*less)(void *base, size_t a, size_t b), \
void (*swap)(void *base, size_t a, size_t b)); \
scope void prefix##sort(heaptype h) \
{ \
struct prefix##priv { size_t _size, _used; type _heap[1];}; \
struct prefix##priv *_priv = *(void **)&h; \
if (_priv) \
su_smoothsort(_priv->_heap - 1, 1, _priv->_used, prefix##_less, prefix##_swap); \
} \
extern int const prefix##dummy_heap
#endif /** !defined(SOFIA_SIP_HEAP_H) */
@@ -31,7 +31,7 @@
* Hash tables templates, take 2.
*
* Note: this version can handle structures as entries, and it can be used
* without <su_alloc.h>.
* without <sofia-sip/su_alloc.h>.
*
* This file contain a hash table template for C. The hash tables are
* resizeable, and they usually contain pointers to entries. The
Loaded 100 of 153 files, more files were not shown because too many files have changed in this diff. Show more