#include "config.h"
#include <sofia-sip/su_alloc.h>
#include <sofia-sip/su_strlst.h>
#include <sofia-sip/string0.h>
#include "sofia-sip/sip_parser.h"
#include <sofia-sip/sip_header.h>
#include <sofia-sip/sip_util.h>
#include <sofia-sip/sip_status.h>
#include <sofia-sip/bnf.h>
#include <sofia-sip/hostdomain.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <float.h>
#include <limits.h>
#include <ctype.h>
Include dependency graph for sip_util.c:
Functions | |
int | sip_addr_match (sip_addr_t const *a, sip_addr_t const *b) |
Compare two SIP addresses (From or To headers). | |
sip_contact_t * | sip_contact_create (su_home_t *home, url_string_t const *url, char const *p,...) |
Create a Contact header object. | |
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. | |
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. | |
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_sanity_check (sip_t const *sip) |
Perform sanity check on a SIP message. | |
int | sip_header_field_d (su_home_t *home, sip_header_t *h, char *s, int slen) |
Decode the string containing header field. | |
int | sip_header_field_e (char *b, int bsiz, sip_header_t const *h, int flags) |
Encode a SIP header contents. | |
char * | sip_header_as_string (su_home_t *home, sip_header_t *h) |
Convert the header h to a string allocated from home. | |
int | sip_header_size (sip_header_t const *h) |
Calculate the size of a SIP header and associated memory areas. | |
url_t * | sip_url_dup (su_home_t *home, url_t const *o) |
Duplicate a url or make a url out of string. | |
unsigned | sip_q_value (char const *q) |
Calculate Q value. | |
sip_route_t * | sip_route_remove (msg_t *msg, sip_t *sip) |
Get first route header and remove it from its fragment chain. | |
sip_route_t * | sip_route_pop (msg_t *msg, sip_t *sip) |
Get last route header and remove it from its fragment chain. | |
sip_route_t * | sip_route_follow (msg_t *msg, sip_t *sip) |
Get first route header and rewrite the RequestURI. | |
int | sip_route_is_loose (sip_route_t const *r) |
Check if route header has lr param. | |
sip_route_t * | sip_route_reverse_as (su_home_t *home, msg_hclass_t const *hc, sip_route_t const *route) |
Reverse a route header (Route, Record-Route, Path, Service-Route). | |
sip_route_t * | sip_route_reverse (su_home_t *home, sip_route_t const *route) |
Reverse a Route header. | |
sip_route_t * | sip_route_fixdup_as (su_home_t *home, msg_hclass_t const *hc, sip_route_t const *route) |
Fix and duplicate a route header (Route, Record-Route, Path, Service-Route). | |
sip_route_t * | sip_route_fixdup (su_home_t *home, sip_route_t const *route) |
Fix and duplicate a Route header. | |
sip_route_t * | sip_route_fix (sip_route_t *route) |
Fix Route header. | |
sip_via_t * | sip_via_remove (msg_t *msg, sip_t *sip) |
Get first via header and remove it from its fragment chain. | |
unsigned long | sip_payload_serialize (msg_t *msg, sip_payload_t *pl) |
Serialize payload. | |
int | sip_aor_strip (url_t *url) |
Remove extra parameters from an AOR URL. | |
int | sip_security_verify_compare (sip_security_server_t const *s, sip_security_verify_t const *v, msg_param_t *return_d_ver) |
Compare Security-Verify header with Security-Server header. | |
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. | |
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. |
int sip_addr_match | ( | sip_addr_t const * | a, | |
sip_addr_t const * | b | |||
) |
Compare two SIP addresses (From or To headers).
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.
0 | when successful | |
-1 | upon an error |
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.
home | memory home | |
v | Via header field structure (with <sent-protocol> and <sent-by> parameters) | |
user | username for Contact URI (may be NULL) |
contact | header structure | |
NULL | upon an error |
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.
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) |
contact | header structure | |
NULL | upon an error |
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.
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) |
string | containing Contact URI with angle brackets | |
NULL | upon an error |
int sip_header_field_d | ( | su_home_t * | home, | |
sip_header_t * | h, | |||
char * | s, | |||
int | slen | |||
) |
Decode the string containing header field.
The header object is initialized with the contents of the string. The string is modified when parsing. The home is used to allocate extra memory required when parsing, e.g., for parameter list or when there string contains multiple header fields.
0 | when successful | |
-1 | upon an error. |
int sip_header_field_e | ( | char * | b, | |
int | bsiz, | |||
sip_header_t const * | h, | |||
int | flags | |||
) |
unsigned long sip_payload_serialize | ( | msg_t * | msg, | |
sip_payload_t * | pl | |||
) |
Serialize payload.
The sip_payload_serialize() adds missing headers to MIME multiparty payload, encodes them and orders them in header chain. It also calculates the total length of the payload.
unsigned sip_q_value | ( | char const * | q | ) |
Calculate Q value.
The function sip_q_value() converts q-value string q to numeric value in range (0..1000). Q values are used, for instance, to describe relative priorities of registered contacts.
q | q-value string ("1" | "." 1,3DIGIT) |
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.
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.
OPEN ISSUE: There has been some list discussion indicating a need for a response code that only terminates the usage, but not the dialog (Motivation: being able to destroy a subscription by refusing a NOTIFY without destroying the dialog that that subscription exists in, particularly when the susbcription exists because of an in-dialog REFER).
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.
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.
sip | SIP message to be checked |
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.