Data Structures | Defines | Enumerations | Functions

sofia-sip/sip_util.h File Reference

SIP utility functions. More...

#include <sofia-sip/sip.h>
#include <sofia-sip/string0.h>
#include <sofia-sip/msg_header.h>
Include dependency graph for sip_util.h:

Go to the source code of this file.

Data Structures

union  sip_pref
 Possible values for SIP media tags. More...
struct  sip_pref::sp_literal
 Literal (tag="foo"). More...
struct  sip_pref::sp_string
 String (tag="&lt;foo&gt;"). More...
struct  sip_pref::sp_range
 Numeric value or range (tag="#=1"; tag="#<=3"; tag="#>=-2"; tag="#1:6"). More...

Defines

#define SIP_UTIL_H
 Defined when <sofia-sip/sip_util.h> has been included.
#define SIP_STRLOG(prefix, s)
 Add optional prefix and string to argument list if s is non-NULL.

Enumerations

enum  sp_type
 

Type of the SIP media tag.


Functions

sip_contact_tsip_contact_create_from_via_with_transport (su_home_t *home, sip_via_t const *v, char const *user, char const *transport)
 Convert a Via header to Contact header.
sip_contact_tsip_contact_create_from_via (su_home_t *, sip_via_t const *, char const *user)
 Convert a Via header to Contact header.
char * sip_contact_string_from_via (su_home_t *home, sip_via_t const *v, char const *user, char const *transport)
 Convert a Via header to Contact URL string.
int sip_transport_has_tls (char const *transport_name)
 Check if tranport name refers to TLS.
int sip_response_terminates_dialog (int response_code, sip_method_t method, int *return_graceful_terminate)
 Checks if the response with given response code terminates dialog or dialog usage.
int sip_sanity_check (sip_t const *sip)
 Perform sanity check on a SIP message.
unsigned sip_q_value (char const *q)
 Calculate Q value.
url_tsip_url_dup (su_home_t *sh, url_t const *o)
 Duplicate a url or make a url out of string.
int sip_addr_match (sip_addr_t const *a, sip_addr_t const *b)
 Compare two SIP addresses ( From or To headers).
int sip_route_is_loose (sip_route_t const *r)
 Check if route header has lr param.
sip_route_tsip_route_remove (msg_t *msg, sip_t *sip)
 Get first route header and remove it from its fragment chain.
sip_route_tsip_route_pop (msg_t *msg, sip_t *sip)
 Get last route header and remove it from its fragment chain.
sip_route_tsip_route_follow (msg_t *msg, sip_t *sip)
 Get first route header and rewrite the RequestURI.
sip_route_tsip_route_reverse (su_home_t *, sip_route_t const *)
 Reverse a Route header.
sip_route_tsip_route_fixdup (su_home_t *, sip_route_t const *)
 Fix and duplicate a Route header.
sip_route_tsip_route_fix (sip_route_t *route)
 Fix Route header.
sip_route_tsip_route_fixdup_as (su_home_t *, msg_hclass_t *, sip_route_t const *)
 Fix and duplicate a route header (Route, Record-Route, Path, Service-Route).
sip_route_tsip_route_reverse_as (su_home_t *, msg_hclass_t *, sip_route_t const *)
 Reverse a route header (Route, Record-Route, Path, Service-Route).
sip_via_tsip_via_remove (msg_t *msg, sip_t *sip)
 Get first via header and remove it from its fragment chain.
int sip_prefs_matching (char const *pvalue, char const *nvalue, int *return_parse_error)
 Check callerprefs.
int sip_is_callerpref (char const *param)
 Check if the parameter is a valid feature tag.
int sip_prefs_parse (union sip_pref *sp, char const **in_out_s, int *return_negation)
 Parse a single preference.
int sip_prefs_match (union sip_pref const *, union sip_pref const *)
 Match preferences.
int sip_contact_is_immune (sip_contact_t const *m)
 Check if Contact is immune to callerprefs.
sip_contact_tsip_contact_immunize (su_home_t *home, sip_contact_t const *m)
 Immunize Contact to callerprefs.
int sip_contact_reject (sip_contact_t const *m, sip_reject_contact_t const *rc)
 Check if Contact is rejected by Reject-Contact.
int sip_contact_accept (sip_contact_t const *m, sip_accept_contact_t const *cp, unsigned *return_S, unsigned *return_N, int *return_error)
 Check if Contact matches by Accept-Contact.
int sip_contact_score (sip_contact_t const *m, sip_accept_contact_t const *ac, sip_reject_contact_t const *rc)
 Calculate score for contact.
int sip_aor_strip (url_t *url)
 Remove extra parameters from an AOR URL.
sip_security_client_t const * sip_security_client_select (sip_security_client_t const *client, sip_security_server_t const *server)
 Select best mechanism from Security-Client header.

Detailed Description

SIP utility functions.

Author:
Pekka Pessi <Pekka.Pessi@nokia-email.address.hidden>.
Date:
Created: Thu Jun 8 19:28:55 2000 ppessi

Define Documentation

#define SIP_UTIL_H

Defined when <sofia-sip/sip_util.h> has been included.


Function Documentation

int sip_addr_match ( sip_addr_t const *  a,
sip_addr_t const *  b 
)

Compare two SIP addresses ( From or To headers).

Return values:
nonzero if matching.
zero if not matching.
int sip_aor_strip ( url_t url  ) 

Remove extra parameters from an AOR URL.

The extra parameters listed in the RFC 3261 table 1 include port number, method, maddr, ttl, transport, lr and headers.

Note:
The funtion modifies the url and the strings attached to it.
Return values:
0 when successful
-1 upon an error
int sip_contact_accept ( sip_contact_t const *  m,
sip_accept_contact_t const *  cp,
unsigned *  return_S,
unsigned *  return_N,
int *  return_error 
)

Check if Contact matches by Accept-Contact.

Matching Accept-Contact and Contact headers is done as explained in RFC 3841 section 7.2.4. The caller score can be calculated from the returned S and N values.

Matching
The Accept-Contact header contains number of feature tag parameters. The count of feature tags is returned in return_N. For each feature tag in Accept-Contact, the feature tag with same name is searched from the Contact header. If both headers contain the feature tag with same name, their values are compared. If the value in Accept-Contact does not match with the value in Contact, there is mismatch and 0 is returned. If they match, S is increased by 1.
Parameters:
m pointer to Contact header structure
cp pointer to Accept-Contact header structure
return_N return-value parameter for number of feature tags in Accept-Contact
return_S return-value parameter for number of matching feature tags
return_error return-value parameter for parsing error

For example,

 if (sip_contact_accept(contact, accept_contact, &S, &N, &error)) {
   if (N == 0)
     score == 1.0;
   else
     score = (double)S / (double)N;
   if (accept_contact->cp_explicit) {
     if (accept_contact->cp_require)
       goto drop;
     else
       score = 0.0;
   }
 }
 else if (!error) {
   score = 0.0;
 }
Return values:
1 if Contact matches
Returns:
return_S contains number of matching feature tags
return_N contains number of feature tags in Accept-Contact
Return values:
0 if Contact does not match
Returns:
return_error contains -1 if feature tag value was malformed
See also:
RFC 3841 section 7.2.4, sip_contact_score(), sip_contact_reject(), sip_contact_is_immune(), sip_contact_immunize(), sip_is_callerpref(), sip_prefs_matching().
sip_contact_t* sip_contact_create_from_via ( su_home_t home,
sip_via_t const *  v,
char const *  user 
)

Convert a Via header to Contact header.

The Contact URI will contain the port number if needed. If transport protocol name starts with "TLS", "SIPS:" URI schema is used. Transport parameter is included in the URI unless the transport protocol is UDP.

Parameters:
home memory home
v Via header field structure (with <sent-protocol> and <sent-by> parameters)
user username for Contact URI (may be NULL)
Return values:
contact header structure
NULL upon an error
See also:
sip_contact_create_from_via_with_transport(), sip_contact_string_from_via()
sip_contact_t* sip_contact_create_from_via_with_transport ( su_home_t home,
sip_via_t const *  v,
char const *  user,
char const *  transport 
)

Convert a Via header to Contact header.

The Contact URI will contain the port number and transport parameters if needed. If transport protocol name starts with "TLS", "SIPS:" URI schema is used.

Parameters:
home memory home
v Via header field structure (with <sent-by> parameter containing host and port)
user username for Contact URI (may be NULL)
transport transport name for Contact URI (may be NULL)
Return values:
contact header structure
NULL upon an error
See also:
sip_contact_create_from_via(), sip_contact_string_from_via()
sip_contact_t* sip_contact_immunize ( su_home_t home,
sip_contact_t const *  m 
)

Immunize Contact to callerprefs.

Make a copy of Contact header m and remove all parameters which affect caller preferences.

Parameters:
home home object used when allocating copy
m pointer to Contact header structure to immunize
Return values:
pointer to immunized copy if successful
NULL upon an error
See also:
RFC 3841, sip_is_callerpref(), sip_contact_score(), sip_contact_accept(), sip_contact_reject(), Contact
int sip_contact_is_immune ( sip_contact_t const *  m  ) 

Check if Contact is immune to callerprefs.

int sip_contact_reject ( sip_contact_t const *  m,
sip_reject_contact_t const *  reject 
)

Check if Contact is rejected by Reject-Contact.

Parameters:
m pointer to Contact header
reject pointer to Reject-Contact header
Return values:
1 when rejecting
0 when Contact does not match with Reject-Contact
See also:
sip_contact_score(), sip_contact_accept(), sip_contact_immunize(), sip_contact_is_immune(), RFC 3841, Reject-Contact, Contact
int sip_contact_score ( sip_contact_t const *  m,
sip_accept_contact_t const *  ac,
sip_reject_contact_t const *  rc 
)

Calculate score for contact.

The caller preference score is an integer in range of 0 to 1000.

Return values:
-1 if the contact is rejected
1000 if contact is immune to caller preferences
0..1000 reflecting RFC 3841 score in 0.000 - 1.000.
See also:
sip_q_value(), sip_contact_accept(), sip_contact_reject(), sip_contact_is_immune(), sip_contact_immunize(), sip_is_callerpref(), sip_prefs_matching(), RFC 3841, Accept-Contact, Reject-Contact, Contact
char* sip_contact_string_from_via ( su_home_t home,
sip_via_t const *  v,
char const *  user,
char const *  transport 
)

Convert a Via header to Contact URL string.

The Contact URI will contain the port number and transport parameters if needed. If transport protocol name starts with "TLS", "SIPS:" URI schema is used.

The contact URI string returned will always have angle brackets ("<" and ">") around it.

Parameters:
home memory home
v Via header field structure (with <sent-by> parameter containing host and port)
user username for Contact URI (may be NULL)
transport transport name for Contact URI (may be NULL)
Return values:
string containing Contact URI with angle brackets
NULL upon an error
int sip_is_callerpref ( char const *  param  ) 

Check if the parameter is a valid feature tag.

A feature tag is a parameter starting with a single plus, or a well-known feature tag listed in RFC 3841: "audio", "automata", "application", "class", "control", "duplex", "data", "description", "events", "isfocus", "language", "mobility", "methods", "priority", "schemes", "type", or "video". However, well-known feature tag can not start with plus. So, "+alarm" or "audio" is a feature tag, "alarm", "++alarm", or "+audio" are not.

Return values:
1 if string is a feature tag parameter
0 otherwise
int sip_prefs_matching ( char const *  pvalue,
char const *  nvalue,
int *  return_parse_error 
)

Check callerprefs.

Check callerprefs.

Check if the given feature values match with each other.

Parameters:
pvalue first feature parameter
nvalue second feature parameter
return_parse_error return-value parameter for error (may be NULL)
Return values:
1 if given feature parameters match
0 if there is no match or a parse or type error occurred.

If there is a parsing or type error, 0 is returned and *return_parse_error is set to -1.

See also:
sip_prefs_parse(), sip_prefs_match(), union sip_pref.
unsigned sip_q_value ( char const *  q  ) 

Calculate Q value.

Convert q-value string q to numeric value in range (0..1000). Q values are used, for instance, to describe relative priorities of registered contacts.

Parameters:
q q-value string ("1" | "." 1,3DIGIT)
Returns:
An integer in range 0 .. 1000.
int sip_response_terminates_dialog ( int  response_code,
sip_method_t  method,
int *  return_graceful_terminate_usage 
)

Checks if the response with given response code terminates dialog or dialog usage.

Returns:
-1 if the response with given code terminates whole dialog.
1 if the response terminates the dialog usage.
0 if the response does not terminate dialog or dialog usage.
The *return_graceful_terminate_usage is set to 1, if application should gracefully terminate its dialog usage. It is set to 0, if no graceful terminate is required. If it is up to application policy to decide whether to gracefully terminate or not, the *return_graceful_terminate_usage is left unmodified.

RFC 5057

400 and unrecognized 4xx responses

These responses affect only the NOTIFY transaction, not the subscription, the dialog it resides in (beyond affecting the local CSeq), or any other usage of that dialog. In general, the response is a complaint about this transaction, not the usage or dialog the transaction occurs in.

401 Unauthorized and 407 Proxy Authentication Required

This request, not the subscription or dialog, is being challenged. The usages and dialog are not terminated.

402 Payment Required

This is a reserved response code. If encountered, it should be treated as an unrecognized 4xx.

403 Forbidden

This response terminates the subscription, but has no effect on any other usages of the dialog. In our example scenario, the invite usage continues to exist. Similarly, if the 403 came in response to a re-INVITE, the invite usage would be terminated, but not the subscription.

404 Not Found

This response destroys the dialog and all usages sharing it. The Request-URI that is being 404ed is the remote target set by the Contact provided by the peer. Getting this response means something has gone fundamentally wrong with the dialog state.

405 Method Not Allowed

In our example scenario, this response destroys the subscription, but not the invite usage or the dialog. It's an aberrant case for NOTIFYs to receive a 405 since they only come as a result to something that creates subscription. In general, a 405 within a given usage affects only that usage, but does not affect other usages of the dialog.

406 Not Acceptable

These responses concern details of the message in the transaction. Subsequent requests in this same usage may succeed. Neither the usage nor dialog is terminated, other usages sharing this dialog are unaffected.

408 Request Timeout

Receiving a 408 will have the same effect on usages and dialogs as a real transaction timeout as described in Section 3.2.

410 Gone

This response destroys the dialog and all usages sharing it. The Request-URI that is being rejected is the remote target set by the Contact provided by the peer. Similar to 404, getting this response means something has gone fundamentally wrong with the dialog state, its slightly less aberrant in that the other endpoint recognizes that this was once a valid URI that it isn't willing to respond to anymore.

412, 413, 414 and 415

These responses concern details of the message in the transaction. Subsequent requests in this same usage may succeed. Neither the usage nor dialog is terminated, other usages sharing this dialog are unaffected.

416 Unsupported URI Scheme

Similar to 404 and 410, this response came to a request whose Request-URI was provided by the peer in a Contact header field. Something has gone fundamentally wrong, and the dialog and all of its usages are destroyed.

417 Uknown Resource-Priority
The effect of this response on usages and dialogs is analgous to that for 420 and 488. The usage is not affected. The dialog is only affected by a change in its local CSeq. No other usages of the dialog are affected.
420 Bad Extension and 421 Extension Required

These responses are objecting to the request, not the usage. The usage is not affected. The dialog is only affected by a change in its local CSeq. No other usages of the dialog are affected.

422 Session Interval Too Small

This response will not be returned to a NOTIFY in our example scenario. This response is non-sensical for any mid-usage request. If it is received, an element in the path of the request is violating protocol, and the recipient should treat this as it would an unknown 4xx response. If the response came to a request that was attempting to establish a new usage in an existing dialog, no new usage is created and existing usages are unaffected.

423 Interval Too Brief

This response won't happen in our example scenario, but if it came in response to a re-SUBSCRIBE, the subscribe usage is not destroyed (or otherwise affected). No other usages of the dialog are affected.

428 Use Identity Header

This response objects to the request, not the usage. The usage is not affected. The dialog is only affected by a change in its local CSeq. No other usages of the dialog are affected.

429 Provide Referrer Identity

This response won't be returned to a NOTIFY as in our example scenario, but when it is returned to a REFER, it is objecting to the REFER request itself, not any usage the REFER occurs within. The usage is unaffected. Any other usages sharing this dialog are unaffected. The dialog is only affected by a change in its local CSeq.

436 Bad Identity-Info, 437 Unsupported Certificate, 438 Invalid \
Identity Header

These responses object to the request, not the usage. The usage is not affected. The dialog is only affected by a change in its local CSeq. No other usages of the dialog are affected.

480 Temporarily Unavailable

RFC 3261 is unclear on what this response means for mid-usage requests. Clarifications will be made to show that this response affects only the usage in which the request occurs. No other usages are affected. If the response included a Retry-After header field, further requests in that usage should not be sent until the indicated time has past. Requests in other usages may still be sent at any time.

481 Call/Transaction Does Not Exist

This response indicates that the peer has lost its copy of the dialog state. The dialog and any usages sharing it are destroyed.

The dialog itself should not be destroyed unless this was the last usage. The effects of a 481 on a dialog and its usages are the most ambiguous of any final response. There are implementations that have chosen the meaning recommended here, and others that destroy the entire dialog without regard to the number of outstanding usages. Going forward with this clarification will allow those deployed implementations that assumed only the usage was destroyed to work with a wider number of implementations. Those that made the other choice will continue to function as they do now, suffering at most the same extra messages needed for a peer to discover that that other usages have gone away that they currently do. However, the necessary clarification to RFC 3261 needs to make it very clear that the ability to terminate usages independently from the overall dialog using a 481 is not justification for designing new applications that count on multiple usages in a dialog.

482 Loop Detected

This response is aberrant mid-dialog. It will only occur if the Record-Route header field was improperly constructed by the proxies involved in setting up the dialog's initial usage, or if a mid-dialog request forks and merges (which should never happen). Future requests using this dialog state will also fail. The dialog and any usages sharing it are destroyed.

483 Too Many Hops

Similar to 482, receiving this mid-dialog is aberrant. Unlike 482, recovery may be possible by increasing Max-Forwards (assuming that the requester did something strange like using a smaller value for Max-Forwards in mid-dialog requests than it used for an initial request). If the request isn't tried with an increased Max-Forwards, then the agent should attempt to gracefully terminate this usage and all other usages that share its dialog.

484 Address Incomplete and 485 Ambiguous

Similar to 404 and 410, these responses came to a request whose Request-URI was provided by the peer in a Contact header field. Something has gone fundamentally wrong, and the dialog and all of its usages are destroyed.

Asterisk (v 1.2.7.1) does response with 484 if a client does send a refer with a Refer-To header to an unknown number. This is therefore not fundamentally wrong and the dialog should not be destroyed!

486 Busy Here

This response is non-sensical in our example scenario, or in any scenario where this response comes inside an established usage. If it occurs in that context, it should be treated as an unknown 4xx response. The usage, and any other usages sharing its dialog are unaffected. The dialog is only affected by the change in its local CSeq. If this response is to a request that is attempting to establish a new usage within an existing dialog (such as an INVITE sent within a dialog established by a subscription), the request fails, no new usage is created, and no other usages are affected.

487 Request Terminated

This response speaks to the disposition of a particular request (transaction). The usage in which that request occurs is not affected by this response (it may be affected by another associated request within that usage). No other usages sharing this dialog are affected.

488 Not Acceptable Here

This response is objecting to the request, not the usage. The usage is not affected. The dialog is only affected by a change in its local CSeq. No other usages of the dialog are affected.

489 Bad Event

In our example scenario, RFC 3265 declares that the subscription usage in which the NOTIFY is sent is terminated. The invite usage is unaffected and the dialog continues to exist. This response is only valid in the context of SUBSCRIBE and NOTIFY. UAC behavior for receiving this response to other methods is not specified, but treating it as an unknown 4xx is a reasonable practice.

491 Request Pending

This response addresses in-dialog request glare. Its affect is scoped to the request. The usage in which the request occurs is not affected. The dialog is only affected by the change in its local CSeq. No other usages sharing this dialog are affected.

493 Undecipherable

This response objects to the request, not the usage. The usage is not affected. The dialog is only affected by a change in its local CSeq. No other usages of the dialog are affected.

494 Security Agreement Required

This response is objecting to the request, not the usage. The usage is not affected. The dialog is only affected by a change in its local CSeq. No other usages of the dialog are affected.

500 and 5xx unrecognized responses

These responses are complaints against the request (transaction), not the usage. If the response contains a Retry-After header field value, the server thinks the condition is temporary and the request can be retried after the indicated interval. This usage, and any other usages sharing the dialog are unaffected. If the response does not contain a Retry-After header field value, the UA may decide to retry after an interval of its choosing or attempt to gracefully terminate the usage. Whether or not to terminate other usages depends on the application. If the UA receives a 500 (or unrecognized 5xx) in response to an attempt to gracefully terminate this usage, it can treat this usage as terminated. If this is the last usage sharing the dialog, the dialog is also terminated.

501 Not Implemented

This would be a degenerate response in our example scenario since the NOTIFY is being sent as part of an established subscribe usage. In this case, the UA knows the condition is unrecoverable and should stop attempting to send NOTIFYs on this usage. (It may or may not destroy the usage. If it remembers the bad behavior, it can reject any refresh subscription). In general, this response may or may not affect the usage (a 501 to an unknown method or an INFO will not end an invite usage). It will never affect other usages sharing this usage's dialog.

502 Bad Gateway

This response is aberrant mid-dialog. It will only occur if the Record-Route header field was improperly constructed by the proxies involved in setting up the dialog's initial usage. Future requests using this dialog state will also fail. The dialog and any usages sharing it are destroyed.

503 Service Unavailable

As per RFC 3263, the logic handling locating SIP servers for transactions may handle 503 requests (effectively sequentially forking at the endpoint based on DNS results). If this process does not yield a better response, a 503 may be returned to the transaction user. Like a 500 response, the error is a complaint about this transaction, not the usage. Because this response occurred in the context of an established usage (hence an existing dialog), the route-set has already been formed and any opportunity to try alternate servers (as recommended in RFC 3261) has been exhausted by the RFC 3263 logic. The response should be handled as described for 500 earlier in this memo.

504 Server Time-out

It is not obvious under what circumstances this response would be returned to a request in an existing dialog. If it occurs it should have the same affect on the dialog and its usages as described for unknown 5xx responses.

505 Version Not Supported and 513 Message Too Large

These responses are objecting to the request, not the usage. The usage is not affected. The dialog is only affected by a change in its local CSeq. No other usages of the dialog are affected.

580 Precondition Failure

This response is objecting to the request, not the usage. The usage is not affected. The dialog is only affected by a change in its local CSeq. No other usages of the dialog are affected.

600 and 6xx unrecognized responses

Unlike 400 Bad Request, a 600 response code says something about the recipient user, not the request that was made. This end user is stating an unwillingness to communicate.

If the response contains a Retry-After header field value, the user is indicating willingness to communicate later and the request can be retried after the indicated interval. This usage, and any other usages sharing the dialog are unaffected. If the response does not contain a Retry-After header field value, the UA may decide to retry after an interval of its choosing or attempt to gracefully terminate the usage. Whether or not to terminate other usages depends on the application. If the UA receives a 600 (or unrecognized 6xx) in response to an attempt to gracefully terminate this usage, it can treat this usage as terminated. If this is the last usage sharing the dialog, the dialog is also terminated.

603 Decline

This response declines the action indicated by the associated request. It can be used, for example, to decline a hold or transfer attempt. Receiving this response does NOT terminate the usage it occurs in. Other usages sharing the dialog are unaffected.

604 Does Not Exist Anywhere

Like 404, this response destroys the dialog and all usages sharing it. The Request-URI that is being 604ed is the remote target set by the Contact provided by the peer. Getting this response means something has gone fundamentally wrong with the dialog state.

606 Not Acceptable

This response is objecting to aspects of the associated request, not the usage the request appears in. The usage is unaffected. Any other usages sharing the dialog are unaffected. The only affect on the dialog is the change in the local CSeq.

int sip_sanity_check ( sip_t const *  sip  ) 

Perform sanity check on a SIP message.

Check that the SIP message has all the mandatory fields.

Parameters:
sip SIP message to be checked
Returns:
When the SIP message fulfills the minimum requirements, return zero, otherwise a negative status code.
sip_security_client_t const* sip_security_client_select ( sip_security_client_t const *  client,
sip_security_server_t const *  server 
)

Select best mechanism from Security-Client header.

Note:
We assume that Security-Server header in s is sorted by preference.
url_t* sip_url_dup ( su_home_t home,
url_t const *  o 
)

Duplicate a url or make a url out of string.

Deprecated:
Use url_hdup() instead.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Sofia-SIP 1.12.11 - Copyright (C) 2006 Nokia Corporation. All rights reserved. Licensed under the terms of the GNU Lesser General Public License.