#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. | |
issize_t | sip_header_field_d (su_home_t *home, sip_header_t *h, char *s, isize_t slen) |
Decode the string containing header field. | |
issize_t | sip_header_field_e (char *b, isize_t 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 const *h) |
Convert the header h to a string allocated from home. | |
isize_t | 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 *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 *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 | |||
) |
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 |
char* sip_header_as_string | ( | su_home_t * | home, | |
sip_header_t const * | h | |||
) |
Convert the header h to a string allocated from home.
issize_t sip_header_field_d | ( | su_home_t * | home, | |
sip_header_t * | h, | |||
char * | s, | |||
isize_t | 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. |
issize_t sip_header_field_e | ( | char * | b, | |
isize_t | bsiz, | |||
sip_header_t const * | h, | |||
int | flags | |||
) |
isize_t sip_header_size | ( | sip_header_t const * | h | ) |
Calculate the size of a SIP header and associated memory areas.
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.
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.
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.
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.
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.
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.